summaryrefslogtreecommitdiffstats
path: root/sys/legacy/dev
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2009-05-27 16:16:56 +0000
committerthompsa <thompsa@FreeBSD.org>2009-05-27 16:16:56 +0000
commit14ea3ee2bb371575697cd652ca2064877b187983 (patch)
tree723b0aed327f79b20884592648d5b64748a24f12 /sys/legacy/dev
parent3f72bbde95ea9eee2e163b14ffdca8533a85e6c1 (diff)
downloadFreeBSD-src-14ea3ee2bb371575697cd652ca2064877b187983.zip
FreeBSD-src-14ea3ee2bb371575697cd652ca2064877b187983.tar.gz
Delete the old USB stack. The new stack has settled in and has all the
drivers/functionality and then some.
Diffstat (limited to 'sys/legacy/dev')
-rw-r--r--sys/legacy/dev/ata/ata-usb.c970
-rw-r--r--sys/legacy/dev/sound/usb/uaudio.c4662
-rw-r--r--sys/legacy/dev/sound/usb/uaudio.h56
-rw-r--r--sys/legacy/dev/sound/usb/uaudio_pcm.c481
-rw-r--r--sys/legacy/dev/sound/usb/uaudioreg.h404
-rw-r--r--sys/legacy/dev/usb/FILES52
-rw-r--r--sys/legacy/dev/usb/dsbr100io.h39
-rw-r--r--sys/legacy/dev/usb/ehci.c3932
-rw-r--r--sys/legacy/dev/usb/ehci_ddb.c255
-rw-r--r--sys/legacy/dev/usb/ehci_ixp4xx.c360
-rw-r--r--sys/legacy/dev/usb/ehci_mbus.c396
-rw-r--r--sys/legacy/dev/usb/ehci_pci.c635
-rw-r--r--sys/legacy/dev/usb/ehcireg.h344
-rw-r--r--sys/legacy/dev/usb/ehcivar.h278
-rw-r--r--sys/legacy/dev/usb/hid.c469
-rw-r--r--sys/legacy/dev/usb/hid.h91
-rw-r--r--sys/legacy/dev/usb/if_urtw.c3324
-rw-r--r--sys/legacy/dev/usb/if_urtwreg.h256
-rw-r--r--sys/legacy/dev/usb/if_urtwvar.h151
-rw-r--r--sys/legacy/dev/usb/ohci.c3638
-rw-r--r--sys/legacy/dev/usb/ohci_pci.c410
-rw-r--r--sys/legacy/dev/usb/ohcireg.h250
-rw-r--r--sys/legacy/dev/usb/ohcivar.h164
-rw-r--r--sys/legacy/dev/usb/rio500_usb.h48
-rw-r--r--sys/legacy/dev/usb/rt2573_ucode.h213
-rw-r--r--sys/legacy/dev/usb/sl811hs.c1654
-rw-r--r--sys/legacy/dev/usb/sl811hsreg.h126
-rw-r--r--sys/legacy/dev/usb/sl811hsvar.h107
-rw-r--r--sys/legacy/dev/usb/slhci_pccard.c206
-rw-r--r--sys/legacy/dev/usb/u3g.c799
-rw-r--r--sys/legacy/dev/usb/uark.c339
-rw-r--r--sys/legacy/dev/usb/ubsa.c742
-rw-r--r--sys/legacy/dev/usb/ubser.c882
-rw-r--r--sys/legacy/dev/usb/ubser.h43
-rw-r--r--sys/legacy/dev/usb/uchcom.c1036
-rw-r--r--sys/legacy/dev/usb/ucom.c829
-rw-r--r--sys/legacy/dev/usb/ucomvar.h169
-rw-r--r--sys/legacy/dev/usb/ucycom.c543
-rw-r--r--sys/legacy/dev/usb/udbp.c860
-rw-r--r--sys/legacy/dev/usb/udbp.h80
-rw-r--r--sys/legacy/dev/usb/ufm.c376
-rw-r--r--sys/legacy/dev/usb/ufoma.c1192
-rw-r--r--sys/legacy/dev/usb/uftdi.c793
-rw-r--r--sys/legacy/dev/usb/uftdireg.h338
-rw-r--r--sys/legacy/dev/usb/ugen.c1590
-rw-r--r--sys/legacy/dev/usb/ugraphire_rdesc.h176
-rw-r--r--sys/legacy/dev/usb/uhci.c3704
-rw-r--r--sys/legacy/dev/usb/uhci_pci.c523
-rw-r--r--sys/legacy/dev/usb/uhcireg.h193
-rw-r--r--sys/legacy/dev/usb/uhcivar.h206
-rw-r--r--sys/legacy/dev/usb/uhid.c755
-rw-r--r--sys/legacy/dev/usb/uhub.c703
-rw-r--r--sys/legacy/dev/usb/uipaq.c822
-rw-r--r--sys/legacy/dev/usb/ukbd.c1538
-rw-r--r--sys/legacy/dev/usb/ulpt.c815
-rw-r--r--sys/legacy/dev/usb/umass.c3611
-rw-r--r--sys/legacy/dev/usb/umct.c511
-rw-r--r--sys/legacy/dev/usb/umodem.c821
-rw-r--r--sys/legacy/dev/usb/ums.c972
-rw-r--r--sys/legacy/dev/usb/uplcom.c990
-rw-r--r--sys/legacy/dev/usb/urio.c518
-rw-r--r--sys/legacy/dev/usb/usb.c939
-rw-r--r--sys/legacy/dev/usb/usb.h708
-rw-r--r--sys/legacy/dev/usb/usb_if.m42
-rw-r--r--sys/legacy/dev/usb/usb_mem.c297
-rw-r--r--sys/legacy/dev/usb/usb_mem.h58
-rw-r--r--sys/legacy/dev/usb/usb_port.h200
-rw-r--r--sys/legacy/dev/usb/usb_quirks.c153
-rw-r--r--sys/legacy/dev/usb/usb_quirks.h64
-rw-r--r--sys/legacy/dev/usb/usb_subr.c1388
-rw-r--r--sys/legacy/dev/usb/usbcdc.h188
-rw-r--r--sys/legacy/dev/usb/usbdi.c1383
-rw-r--r--sys/legacy/dev/usb/usbdi.h289
-rw-r--r--sys/legacy/dev/usb/usbdi_util.c539
-rw-r--r--sys/legacy/dev/usb/usbdi_util.h98
-rw-r--r--sys/legacy/dev/usb/usbdivar.h322
-rw-r--r--sys/legacy/dev/usb/usbhid.h185
-rw-r--r--sys/legacy/dev/usb/uscanner.c723
-rw-r--r--sys/legacy/dev/usb/uslcom.c419
-rw-r--r--sys/legacy/dev/usb/uvisor.c639
-rw-r--r--sys/legacy/dev/usb/uvscom.c906
-rw-r--r--sys/legacy/dev/usb/uxb360gp_rdesc.h124
82 files changed, 0 insertions, 61104 deletions
diff --git a/sys/legacy/dev/ata/ata-usb.c b/sys/legacy/dev/ata/ata-usb.c
deleted file mode 100644
index 5c868b2..0000000
--- a/sys/legacy/dev/ata/ata-usb.c
+++ /dev/null
@@ -1,970 +0,0 @@
-/*-
- * Copyright (c) 2006 - 2008 Søren Schmidt <sos@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer,
- * without modification, immediately at the beginning of the file.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_ata.h"
-#include <sys/param.h>
-#include <sys/conf.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/mutex.h>
-#include <sys/ata.h>
-#include <sys/bus.h>
-#include <sys/endian.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/sema.h>
-#include <sys/taskqueue.h>
-#include <vm/uma.h>
-#include <machine/resource.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <dev/usb/usb_port.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/ata/ata-all.h>
-#include <ata_if.h>
-
-/* Command Block Wrapper */
-struct bbb_cbw {
- u_int8_t signature[4];
-#define CBWSIGNATURE 0x43425355
-
- u_int8_t tag[4];
- u_int8_t transfer_length[4];
- u_int8_t flags;
-#define CBWFLAGS_OUT 0x00
-#define CBWFLAGS_IN 0x80
-
- u_int8_t lun;
- u_int8_t length;
-#define CBWCDBLENGTH 16
-
- u_int8_t cdb[CBWCDBLENGTH];
-};
-
-/* Command Status Wrapper */
-struct bbb_csw {
- u_int8_t signature[4];
-#define CSWSIGNATURE 0x53425355
-
- u_int8_t tag[4];
- u_int8_t residue[4];
- u_int8_t status;
-#define CSWSTATUS_GOOD 0x0
-#define CSWSTATUS_FAILED 0x1
-#define CSWSTATUS_PHASE 0x2
-};
-
-/* USB-ATA 'controller' softc */
-struct atausb_softc {
- device_t dev; /* base device */
- usbd_interface_handle iface; /* interface */
- int ifaceno; /* interface number */
- u_int8_t bulkin; /* endpoint address's */
- u_int8_t bulkout;
- u_int8_t bulkirq;
- usbd_pipe_handle bulkin_pipe; /* pipe handle's */
- usbd_pipe_handle bulkout_pipe;
- usbd_pipe_handle bulkirq_pipe;
- int maxlun;
- int timeout;
- struct ata_request *ata_request;
- usb_device_request_t usb_request;
- struct bbb_cbw cbw;
- struct bbb_csw csw;
-
-#define ATAUSB_T_BBB_CBW 0
-#define ATAUSB_T_BBB_DATA 1
-#define ATAUSB_T_BBB_DCLEAR 2
-#define ATAUSB_T_BBB_CSW1 3
-#define ATAUSB_T_BBB_CSW2 4
-#define ATAUSB_T_BBB_SCLEAR 5
-#define ATAUSB_T_BBB_RESET1 6
-#define ATAUSB_T_BBB_RESET2 7
-#define ATAUSB_T_BBB_RESET3 8
-#define ATAUSB_T_MAX 9
- usbd_xfer_handle transfer[ATAUSB_T_MAX];
-
- int state;
-#define ATAUSB_S_ATTACH 0
-#define ATAUSB_S_IDLE 1
-#define ATAUSB_S_BBB_COMMAND 2
-#define ATAUSB_S_BBB_DATA 3
-#define ATAUSB_S_BBB_DCLEAR 4
-#define ATAUSB_S_BBB_STATUS1 5
-#define ATAUSB_S_BBB_SCLEAR 6
-#define ATAUSB_S_BBB_STATUS2 7
-#define ATAUSB_S_BBB_RESET1 8
-#define ATAUSB_S_BBB_RESET2 9
-#define ATAUSB_S_BBB_RESET3 10
-#define ATAUSB_S_DETACH 11
-
- struct mtx locked_mtx;
- struct ata_channel *locked_ch;
- struct ata_channel *restart_ch;
-};
-
-static int atausbdebug = 0;
-
-/* prototypes*/
-static usbd_status atausb_start(struct atausb_softc *sc, usbd_pipe_handle pipe, void *buffer, int buflen, int flags, usbd_xfer_handle xfer);
-static usbd_status atausb_ctl_start(struct atausb_softc *sc, usbd_device_handle udev, usb_device_request_t *req, void *buffer, int buflen, int flags, usbd_xfer_handle xfer);
-static void atausb_clear_stall(struct atausb_softc *sc, u_int8_t endpt, usbd_pipe_handle pipe, int state, usbd_xfer_handle xfer);
-static void atausb_bbb_reset(struct atausb_softc *sc);
-static int atausb_bbb_start(struct ata_request *request);
-static void atausb_bbb_finish(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status err);
-int ata_usbchannel_begin_transaction(struct ata_request *request);
-int ata_usbchannel_end_transaction(struct ata_request *request);
-
-
-/*
- * USB frontend part
- */
-USB_DECLARE_DRIVER(atausb);
-DRIVER_MODULE(atausb, uhub, atausb_driver, atausb_devclass, 0, 0);
-MODULE_VERSION(atausb, 1);
-
-static int
-atausb_match(device_t dev)
-{
- struct usb_attach_arg *uaa = device_get_ivars(dev);
- usb_interface_descriptor_t *id;
-
- if (uaa->iface == NULL)
- return UMATCH_NONE;
-
- id = usbd_get_interface_descriptor(uaa->iface);
- if (!id || id->bInterfaceClass != UICLASS_MASS)
- return UMATCH_NONE;
-
- switch (id->bInterfaceSubClass) {
- case UISUBCLASS_QIC157:
- case UISUBCLASS_RBC:
- case UISUBCLASS_SCSI:
- case UISUBCLASS_SFF8020I:
- case UISUBCLASS_SFF8070I:
- case UISUBCLASS_UFI:
- switch (id->bInterfaceProtocol) {
- case UIPROTO_MASS_CBI:
- case UIPROTO_MASS_CBI_I:
- case UIPROTO_MASS_BBB:
- case UIPROTO_MASS_BBB_OLD:
- return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO;
- default:
- return UMATCH_IFACECLASS_IFACESUBCLASS;
- }
- break;
- default:
- return UMATCH_IFACECLASS;
- }
-}
-
-static int
-atausb_attach(device_t dev)
-{
- struct atausb_softc *sc = device_get_softc(dev);
- struct usb_attach_arg *uaa = device_get_ivars(dev);
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_device_handle udev;
- usb_device_request_t request;
- device_t child;
- char devinfo[1024], *proto, *subclass;
- u_int8_t maxlun;
- int err, i;
-
- sc->dev = dev;
- usbd_devinfo(uaa->device, 0, devinfo);
- device_set_desc_copy(dev, devinfo);
- sc->bulkin = sc->bulkout = sc->bulkirq = -1;
- sc->bulkin_pipe = sc->bulkout_pipe= sc->bulkirq_pipe = NULL;
- sc->iface = uaa->iface;
- sc->ifaceno = uaa->ifaceno;
- sc->maxlun = 0;
- sc->timeout = 5000;
- sc->locked_ch = NULL;
- sc->restart_ch = NULL;
- mtx_init(&sc->locked_mtx, "ATAUSB lock", NULL, MTX_DEF);
-
- id = usbd_get_interface_descriptor(sc->iface);
- switch (id->bInterfaceProtocol) {
- case UIPROTO_MASS_BBB:
- case UIPROTO_MASS_BBB_OLD:
- proto = "Bulk-Only";
- break;
- case UIPROTO_MASS_CBI:
- proto = "CBI";
- break;
- case UIPROTO_MASS_CBI_I:
- proto = "CBI with CCI";
- break;
- default:
- proto = "Unknown";
- }
- switch (id->bInterfaceSubClass) {
- case UISUBCLASS_RBC:
- subclass = "RBC";
- break;
- case UISUBCLASS_QIC157:
- case UISUBCLASS_SFF8020I:
- case UISUBCLASS_SFF8070I:
- subclass = "ATAPI";
- break;
- case UISUBCLASS_SCSI:
- subclass = "SCSI";
- break;
- case UISUBCLASS_UFI:
- subclass = "UFI";
- break;
- default:
- subclass = "Unknown";
- }
- device_printf(dev, "using %s over %s\n", subclass, proto);
- if (strcmp(proto, "Bulk-Only") ||
- (strcmp(subclass, "ATAPI") && strcmp(subclass, "SCSI")))
- return ENXIO;
-
- for (i = 0 ; i < id->bNumEndpoints ; i++) {
- if (!(ed = usbd_interface2endpoint_descriptor(sc->iface, i))) {
- device_printf(sc->dev, "could not read endpoint descriptor\n");
- return ENXIO;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- sc->bulkin = ed->bEndpointAddress;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- sc->bulkout = ed->bEndpointAddress;
- }
- if (id->bInterfaceProtocol == UIPROTO_MASS_CBI_I &&
- UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
- sc->bulkirq = ed->bEndpointAddress;
- }
- }
-
- /* check whether we found at least the endpoints we need */
- if (!sc->bulkin || !sc->bulkout) {
- device_printf(sc->dev, "needed endpoints not found (%d,%d)\n",
- sc->bulkin, sc->bulkout);
- atausb_detach(dev);
- return ENXIO;
- }
-
- /* open the pipes */
- if (usbd_open_pipe(sc->iface, sc->bulkout,
- USBD_EXCLUSIVE_USE, &sc->bulkout_pipe)) {
- device_printf(sc->dev, "cannot open bulkout pipe (%d)\n", sc->bulkout);
- atausb_detach(dev);
- return ENXIO;
- }
- if (usbd_open_pipe(sc->iface, sc->bulkin,
- USBD_EXCLUSIVE_USE, &sc->bulkin_pipe)) {
- device_printf(sc->dev, "cannot open bulkin pipe (%d)\n", sc->bulkin);
- atausb_detach(dev);
- return ENXIO;
- }
- if (id->bInterfaceProtocol == UIPROTO_MASS_CBI_I) {
- if (usbd_open_pipe(sc->iface, sc->bulkirq,
- USBD_EXCLUSIVE_USE, &sc->bulkirq_pipe)) {
- device_printf(sc->dev, "cannot open bulkirq pipe (%d)\n",
- sc->bulkirq);
- atausb_detach(dev);
- return ENXIO;
- }
- }
- sc->state = ATAUSB_S_ATTACH;
-
- /* alloc needed number of transfer handles */
- for (i = 0; i < ATAUSB_T_MAX; i++) {
- sc->transfer[i] = usbd_alloc_xfer(uaa->device);
- if (!sc->transfer[i]) {
- device_printf(sc->dev, "out of memory\n");
- atausb_detach(dev);
- return ENXIO;
- }
- }
-
- /* driver is ready to process requests here */
- sc->state = ATAUSB_S_IDLE;
-
- /* get number of devices so we can add matching channels */
- usbd_interface2device_handle(sc->iface, &udev);
- request.bmRequestType = UT_READ_CLASS_INTERFACE;
- request.bRequest = 0xfe; //GET_MAX_LUN;
- USETW(request.wValue, 0);
- USETW(request.wIndex, sc->ifaceno);
- USETW(request.wLength, sizeof(maxlun));
- switch ((err = usbd_do_request(udev, &request, &maxlun))) {
- case USBD_NORMAL_COMPLETION:
- if (bootverbose)
- device_printf(sc->dev, "maxlun=%d\n", maxlun);
- sc->maxlun = maxlun;
- break;
- default:
- if (bootverbose)
- device_printf(sc->dev, "get maxlun not supported %s\n",
- usbd_errstr(err));
- }
-
- /* ata channels are children to this USB control device */
- for (i = 0; i <= sc->maxlun; i++) {
- if ((child = device_add_child(sc->dev, "ata",
- devclass_find_free_unit(ata_devclass, 2))) == NULL) {
- device_printf(sc->dev, "failed to add ata child device\n");
- } else
- device_set_ivars(child, (void *)(intptr_t)i);
- }
- bus_generic_attach(sc->dev);
- return 0;
-}
-
-static int
-atausb_detach(device_t dev)
-{
- struct atausb_softc *sc = device_get_softc(dev);
- usbd_device_handle udev;
- device_t *children;
- int nchildren, i;
-
- /* signal that device is going away */
- sc->state = ATAUSB_S_DETACH;
-
- /* abort all the pipes in case there are active transfers */
- usbd_interface2device_handle(sc->iface, &udev);
- usbd_abort_default_pipe(udev);
- if (sc->bulkout_pipe)
- usbd_abort_pipe(sc->bulkout_pipe);
- if (sc->bulkin_pipe)
- usbd_abort_pipe(sc->bulkin_pipe);
- if (sc->bulkirq_pipe)
- usbd_abort_pipe(sc->bulkirq_pipe);
-
- /* detach & delete all children */
- if (!device_get_children(dev, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++)
- device_delete_child(dev, children[i]);
- free(children, M_TEMP);
- }
-
- /* free the transfers */
- for (i = 0; i < ATAUSB_T_MAX; i++)
- if (sc->transfer[i])
- usbd_free_xfer(sc->transfer[i]);
-
- /* remove all the pipes */
- if (sc->bulkout_pipe)
- usbd_close_pipe(sc->bulkout_pipe);
- if (sc->bulkin_pipe)
- usbd_close_pipe(sc->bulkin_pipe);
- if (sc->bulkirq_pipe)
- usbd_close_pipe(sc->bulkirq_pipe);
-
- mtx_destroy(&sc->locked_mtx);
- return 0;
-}
-
-
-/*
- * Generic USB transfer routines
- */
-static usbd_status
-atausb_start(struct atausb_softc *sc, usbd_pipe_handle pipe,
- void *buffer, int buflen, int flags, usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- if (sc->state == ATAUSB_S_DETACH)
- return USBD_NOT_STARTED;
-
- usbd_setup_xfer(xfer, pipe, (void *)sc, buffer, buflen, flags,
- sc->timeout, atausb_bbb_finish);
- err = usbd_transfer(xfer);
- if (err && (err != USBD_IN_PROGRESS)) {
- if (atausbdebug)
- device_printf(sc->dev, "failed to setup transfer, %s\n",
- usbd_errstr(err));
- return err;
- }
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-atausb_ctl_start(struct atausb_softc *sc, usbd_device_handle udev,
- usb_device_request_t *req, void *buffer, int buflen, int flags,
- usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- if (sc->state == ATAUSB_S_DETACH)
- return USBD_NOT_STARTED;
-
- usbd_setup_default_xfer(xfer, udev, (void *)sc, sc->timeout, req,
- buffer, buflen, flags, atausb_bbb_finish);
- err = usbd_transfer(xfer);
- if (err && (err != USBD_IN_PROGRESS)) {
- if (atausbdebug)
- device_printf(sc->dev, "failed to setup ctl transfer, %s\n",
- usbd_errstr(err));
- return err;
- }
- return USBD_NORMAL_COMPLETION;
-}
-
-static void
-atausb_clear_stall(struct atausb_softc *sc, u_int8_t endpt,
- usbd_pipe_handle pipe, int state, usbd_xfer_handle xfer)
-{
- usbd_device_handle udev;
-
- if (atausbdebug)
- device_printf(sc->dev, "clear endpoint 0x%02x stall\n", endpt);
- usbd_interface2device_handle(sc->iface, &udev);
- sc->state = state;
- usbd_clear_endpoint_toggle(pipe);
- sc->usb_request.bmRequestType = UT_WRITE_ENDPOINT;
- sc->usb_request.bRequest = UR_CLEAR_FEATURE;
- USETW(sc->usb_request.wValue, UF_ENDPOINT_HALT);
- USETW(sc->usb_request.wIndex, endpt);
- USETW(sc->usb_request.wLength, 0);
- atausb_ctl_start(sc, udev, &sc->usb_request, NULL, 0, 0, xfer);
-}
-
-
-/*
- * Bulk-Only transport part
- */
-static void
-atausb_bbb_reset(struct atausb_softc *sc)
-{
- usbd_device_handle udev;
-
- if (atausbdebug)
- device_printf(sc->dev, "Bulk Reset\n");
- sc->timeout = 5000;
- sc->state = ATAUSB_S_BBB_RESET1;
- usbd_interface2device_handle(sc->iface, &udev);
- sc->usb_request.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- sc->usb_request.bRequest = 0xff; /* bulk-only reset */
- USETW(sc->usb_request.wValue, 0);
- USETW(sc->usb_request.wIndex, sc->ifaceno);
- USETW(sc->usb_request.wLength, 0);
- atausb_ctl_start(sc, udev, &sc->usb_request, NULL,
- 0, 0, sc->transfer[ATAUSB_T_BBB_RESET1]);
-}
-
-static int
-atausb_bbb_start(struct ata_request *request)
-{
- struct atausb_softc *sc =
- device_get_softc(device_get_parent(request->parent));
- struct ata_channel *ch = device_get_softc(request->parent);
-
- sc->timeout = (request->timeout * 1000) + 5000;
- USETDW(sc->cbw.signature, CBWSIGNATURE);
- USETDW(sc->cbw.tag, UGETDW(sc->cbw.tag) + 1);
- USETDW(sc->cbw.transfer_length, request->bytecount);
- sc->cbw.flags = (request->flags & ATA_R_READ) ? CBWFLAGS_IN : CBWFLAGS_OUT;
- sc->cbw.lun = ch->unit;
- sc->cbw.length = 16;
- bzero(sc->cbw.cdb, 16);
- bcopy(request->u.atapi.ccb, sc->cbw.cdb, 12); /* XXX SOS */
- sc->state = ATAUSB_S_BBB_COMMAND;
- if (atausb_start(sc, sc->bulkout_pipe, &sc->cbw, sizeof(struct bbb_cbw),
- 0, sc->transfer[ATAUSB_T_BBB_CBW])) {
- request->result = EIO;
- if (atausbdebug)
- device_printf(request->dev, "cannot setup USB transfer\n");
- atausb_bbb_reset(sc);
- return ATA_OP_FINISHED;
- }
- return ATA_OP_CONTINUES;
-}
-
-static void
-atausb_bbb_finish(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status err)
-{
- struct atausb_softc *sc = (struct atausb_softc *)priv;
- struct ata_request *request = sc->ata_request;
- usbd_xfer_handle next_xfer;
-
- //device_printf(sc->dev, "BBB state %d: %s\n", sc->state, usbd_errstr(err));
-
- if (sc->state == ATAUSB_S_DETACH) {
- device_printf(sc->dev, "WARNING - device has been removed\n");
- return;
- }
-
- switch (sc->state) {
- case ATAUSB_S_BBB_COMMAND: /* command transport phase */
- if (err) {
- if (atausbdebug)
- device_printf(sc->dev, "failed to send CBW\n");
- request->result = EIO;
- atausb_bbb_reset(sc);
- return;
- }
-
- /* next is data transport phase, setup transfer */
- sc->state = ATAUSB_S_BBB_DATA;
- if (request->flags & ATA_R_READ) {
- if (atausb_start(sc, sc->bulkin_pipe,
- request->data, request->bytecount,
- USBD_SHORT_XFER_OK,
- sc->transfer[ATAUSB_T_BBB_DATA])) {
- request->result = EIO;
- atausb_bbb_reset(sc);
- }
- return;
- }
- if (request->flags & ATA_R_WRITE) {
- if (atausb_start(sc, sc->bulkout_pipe,
- request->data, request->bytecount,
- 0, sc->transfer[ATAUSB_T_BBB_DATA])) {
- request->result = EIO;
- atausb_bbb_reset(sc);
- }
- return;
- }
- /* FALLTHROUGH */
-
- case ATAUSB_S_BBB_DATA: /* data transport phase */
- if (request->flags & (ATA_R_READ | ATA_R_WRITE)) {
- usbd_get_xfer_status(xfer, NULL, NULL, &request->donecount, NULL);
- if (err) {
- if (atausbdebug)
- device_printf(sc->dev, "data %s count %d failed: %s\n",
- (request->flags & ATA_R_READ?"read":"write"),
- request->bytecount, usbd_errstr(err));
- if (err == USBD_STALLED) {
- atausb_clear_stall(sc,
- (request->flags & ATA_R_READ ?
- sc->bulkin : sc->bulkout),
- (request->flags & ATA_R_READ ?
- sc->bulkin_pipe : sc->bulkout_pipe),
- ATAUSB_S_BBB_DCLEAR,
- sc->transfer[ATAUSB_T_BBB_DCLEAR]);
- }
- else {
- request->result = EIO;
- atausb_bbb_reset(sc);
- }
- return;
- }
- }
- /* FALLTHROUGH */
-
- case ATAUSB_S_BBB_DCLEAR: /* stall clear after data phase */
- case ATAUSB_S_BBB_SCLEAR: /* stall clear after status phase */
- if (err) {
- if (atausbdebug)
- device_printf(sc->dev, "bulk%s stall clear failed %s\n",
- (request->flags & ATA_R_READ ? "in" : "out"),
- usbd_errstr(err));
- request->result = EIO;
- atausb_bbb_reset(sc);
- return;
- }
-
- if (sc->state == ATAUSB_S_BBB_COMMAND ||
- sc->state == ATAUSB_S_BBB_DATA ||
- sc->state == ATAUSB_S_BBB_DCLEAR) {
- /* first attempt on status transport phase setup transfer */
- sc->state = ATAUSB_S_BBB_STATUS1;
- next_xfer = sc->transfer[ATAUSB_T_BBB_CSW1];
- }
- else {
- /* second attempt of fetching status */
- sc->state = ATAUSB_S_BBB_STATUS2;
- next_xfer = sc->transfer[ATAUSB_T_BBB_CSW2];
- }
- if (atausb_start(sc, sc->bulkin_pipe, &sc->csw, sizeof(struct bbb_csw),
- USBD_SHORT_XFER_OK, next_xfer)) {
- request->result = EIO;
- atausb_bbb_reset(sc);
- }
- return;
-
- case ATAUSB_S_BBB_STATUS1: /* status transfer first attempt */
- case ATAUSB_S_BBB_STATUS2: /* status transfer second attempt */
- if (err) {
- if (atausbdebug)
- device_printf(sc->dev, "cannot get CSW, %s%s\n",
- usbd_errstr(err),
- sc->state == ATAUSB_S_BBB_STATUS1 ? ", retry":"");
- if (sc->state == ATAUSB_S_BBB_STATUS1) {
- atausb_clear_stall(sc, sc->bulkin, sc->bulkin_pipe,
- ATAUSB_S_BBB_SCLEAR,
- sc->transfer[ATAUSB_T_BBB_SCLEAR]);
- }
- else {
- request->result = EIO;
- atausb_bbb_reset(sc);
- }
- return;
- }
-
- int residue = UGETDW(sc->csw.residue);
-
- if (!residue &&
- (request->bytecount - request->donecount))
- residue = request->bytecount - request->donecount;
-
- /* check CSW and handle eventual error */
- if (UGETDW(sc->csw.signature) != CSWSIGNATURE) {
- if (atausbdebug)
- device_printf(sc->dev, "bad CSW signature 0x%08x != 0x%08x\n",
- UGETDW(sc->csw.signature), CSWSIGNATURE);
- request->result = EIO;
- atausb_bbb_reset(sc);
- return;
- }
- else if (UGETDW(sc->csw.tag) != UGETDW(sc->cbw.tag)) {
- if (atausbdebug)
- device_printf(sc->dev, "bad CSW tag %d != %d\n",
- UGETDW(sc->csw.tag), UGETDW(sc->cbw.tag));
- request->result = EIO;
- atausb_bbb_reset(sc);
- return;
- }
- else if (sc->csw.status > CSWSTATUS_PHASE) {
- if (atausbdebug)
- device_printf(sc->dev, "bad CSW status %d > %d\n",
- sc->csw.status, CSWSTATUS_PHASE);
- request->result = EIO;
- atausb_bbb_reset(sc);
- return;
- }
- else if (sc->csw.status == CSWSTATUS_PHASE) {
- if (atausbdebug)
- device_printf(sc->dev, "phase error residue = %d\n", residue);
- request->result = EIO;
- atausb_bbb_reset(sc);
- return;
- }
- else if (request->donecount > request->bytecount) {
- if (atausbdebug)
- device_printf(sc->dev, "buffer overrun %d > %d",
- request->donecount, request->bytecount);
- request->result = EIO;
- atausb_bbb_reset(sc);
- return;
- }
- else if (sc->csw.status == CSWSTATUS_FAILED) {
- if (atausbdebug)
- device_printf(sc->dev, "CSWSTATUS_FAILED\n");
- request->error = ATA_E_ATAPI_SENSE_MASK ;
- sc->state = ATAUSB_S_IDLE;
- ata_interrupt(device_get_softc(request->parent));
- return;
- }
- else {
- sc->state = ATAUSB_S_IDLE;
- ata_interrupt(device_get_softc(request->parent));
- return;
- }
- /* NOT REACHED */
-
- case ATAUSB_S_BBB_RESET1:
- if (err)
- if (atausbdebug)
- device_printf(sc->dev,
- "BBB reset failure: %s\n", usbd_errstr(err));
- atausb_clear_stall(sc, sc->bulkin, sc->bulkin_pipe,
- ATAUSB_S_BBB_RESET2,
- sc->transfer[ATAUSB_T_BBB_RESET2]);
- return;
-
- case ATAUSB_S_BBB_RESET2:
- if (err)
- if (atausbdebug)
- device_printf(sc->dev, "BBB bulkin clear stall failure: %s\n",
- usbd_errstr(err));
- atausb_clear_stall(sc, sc->bulkout, sc->bulkout_pipe,
- ATAUSB_S_BBB_RESET3,
- sc->transfer[ATAUSB_T_BBB_RESET3]);
- return;
-
- case ATAUSB_S_BBB_RESET3:
- if (err)
- if (atausbdebug)
- device_printf(sc->dev, "BBB bulk-out clear stall failure: %s\n",
- usbd_errstr(err));
- sc->state = ATAUSB_S_IDLE;
- if (request) {
- if (err)
- request->result = ENXIO;
- else
- request->result = EIO;
- ata_interrupt(device_get_softc(request->parent));
- }
- return;
-
- default:
- if (atausbdebug)
- device_printf(sc->dev, "unknown state %d", sc->state);
- }
-}
-
-
-/*
- * ATA backend part
- */
-struct atapi_inquiry {
- u_int8_t device_type;
- u_int8_t device_modifier;
- u_int8_t version;
- u_int8_t response_format;
- u_int8_t length;
- u_int8_t reserved[2];
- u_int8_t flags;
- u_int8_t vendor[8];
- u_int8_t product[16];
- u_int8_t revision[4];
- //u_int8_t crap[60];
-};
-
-int
-ata_usbchannel_begin_transaction(struct ata_request *request)
-{
- struct atausb_softc *sc =
- device_get_softc(device_get_parent(request->parent));
-
- if (atausbdebug > 1)
- device_printf(request->dev, "begin_transaction %s\n",
- ata_cmd2str(request));
-
- /* sanity just in case */
- if (sc->state != ATAUSB_S_IDLE) {
- printf("begin is busy (%d)\n", sc->state);
- request->result = EBUSY;
- return ATA_OP_FINISHED;
- }
-
- /* XXX SOS convert the request into the format used, only BBB for now*/
- sc->ata_request = request;
-
- /* ATA/ATAPI IDENTIFY needs special treatment */
- if (!(request->flags & ATA_R_ATAPI)) {
- if (request->u.ata.command != ATA_ATAPI_IDENTIFY) {
- device_printf(request->dev,"%s unsupported\n",ata_cmd2str(request));
- request->result = EIO;
- return ATA_OP_FINISHED;
- }
- request->flags |= ATA_R_ATAPI;
- bzero(request->u.atapi.ccb, 16);
- request->u.atapi.ccb[0] = ATAPI_INQUIRY;
- request->u.atapi.ccb[4] = 255; //sizeof(struct atapi_inquiry);
- request->data += 256; /* arbitrary offset into ata_param */
- request->bytecount = 255; //sizeof(struct atapi_inquiry);
- }
- return atausb_bbb_start(request);
-}
-
-int
-ata_usbchannel_end_transaction(struct ata_request *request)
-{
- if (atausbdebug > 1)
- device_printf(request->dev, "end_transaction %s\n",
- ata_cmd2str(request));
-
- /* XXX SOS convert the request from the format used, only BBB for now*/
-
- /* ATA/ATAPI IDENTIFY needs special treatment */
- if ((request->flags & ATA_R_ATAPI) &&
- (request->u.atapi.ccb[0] == ATAPI_INQUIRY)) {
- struct ata_device *atadev = device_get_softc(request->dev);
- struct atapi_inquiry *inquiry = (struct atapi_inquiry *)request->data;
- u_int16_t *ptr;
-
- /* convert inquiry data into simple ata_param like format */
- atadev->param.config = ATA_PROTO_ATAPI | ATA_PROTO_ATAPI_12;
- atadev->param.config |= (inquiry->device_type & 0x1f) << 8;
- bzero(atadev->param.model, sizeof(atadev->param.model));
- strncpy(atadev->param.model, inquiry->vendor, 8);
- strcpy(atadev->param.model, " ");
- strncpy(atadev->param.model, inquiry->product, 16);
- ptr = (u_int16_t*)(atadev->param.model + sizeof(atadev->param.model));
- while (--ptr >= (u_int16_t*)atadev->param.model)
- *ptr = ntohs(*ptr);
- strncpy(atadev->param.revision, inquiry->revision, 4);
- ptr=(u_int16_t*)(atadev->param.revision+sizeof(atadev->param.revision));
- while (--ptr >= (u_int16_t*)atadev->param.revision)
- *ptr = ntohs(*ptr);
- request->result = 0;
- }
- return ATA_OP_FINISHED;
-}
-
-static int
-ata_usbchannel_probe(device_t dev)
-{
- char buffer[32];
-
- sprintf(buffer, "USB lun %d", (int)(intptr_t)device_get_ivars(dev));
- device_set_desc_copy(dev, buffer);
-
- return 0;
-}
-
-static int
-ata_usbchannel_attach(device_t dev)
-{
- struct ata_channel *ch = device_get_softc(dev);
-
- if (ch->attached)
- return (0);
- ch->attached = 1;
-
- /* initialize the softc basics */
- ch->dev = dev;
- ch->unit = (intptr_t)device_get_ivars(dev);
- ch->state = ATA_IDLE;
- ch->hw.begin_transaction = ata_usbchannel_begin_transaction;
- ch->hw.end_transaction = ata_usbchannel_end_transaction;
- ch->hw.status = NULL;
- ch->hw.command = NULL;
- bzero(&ch->state_mtx, sizeof(struct mtx));
- mtx_init(&ch->state_mtx, "ATA state lock", NULL, MTX_DEF);
- bzero(&ch->queue_mtx, sizeof(struct mtx));
- mtx_init(&ch->queue_mtx, "ATA queue lock", NULL, MTX_DEF);
- TAILQ_INIT(&ch->ata_queue);
-
- /* XXX SOS reset the controller HW, the channel and device(s) */
- //ATA_RESET(dev);
-
- /* probe and attach device on this channel */
- ch->devices = ATA_ATAPI_MASTER;
- if (!ata_delayed_attach)
- ata_identify(dev);
- return 0;
-}
-
-static int
-ata_usbchannel_detach(device_t dev)
-{
- struct ata_channel *ch = device_get_softc(dev);
- device_t *children;
- int nchildren, i;
-
- if (!ch->attached)
- return (0);
- ch->attached = 0;
-
- /* detach & delete all children */
- if (!device_get_children(dev, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++)
- if (children[i])
- device_delete_child(dev, children[i]);
- free(children, M_TEMP);
- }
- mtx_destroy(&ch->state_mtx);
- mtx_destroy(&ch->queue_mtx);
- return 0;
-}
-
-static void
-ata_usbchannel_setmode(device_t parent, device_t dev)
-{
- struct atausb_softc *sc = device_get_softc(GRANDPARENT(dev));
- struct ata_device *atadev = device_get_softc(dev);
- usbd_device_handle udev;
-
- usbd_interface2device_handle(sc->iface, &udev);
- if (usbd_get_speed(udev) == USB_SPEED_HIGH)
- atadev->mode = ATA_USB2;
- else
- atadev->mode = ATA_USB1;
-}
-
-static int
-ata_usbchannel_locking(device_t dev, int flags)
-{
- struct atausb_softc *sc = device_get_softc(device_get_parent(dev));
- struct ata_channel *ch = device_get_softc(dev);
- int res = -1;
-
-
- mtx_lock(&sc->locked_mtx);
- switch (flags) {
- case ATA_LF_LOCK:
- if (sc->locked_ch == NULL)
- sc->locked_ch = ch;
- if (sc->locked_ch != ch)
- sc->restart_ch = ch;
- break;
-
- case ATA_LF_UNLOCK:
- if (sc->locked_ch == ch) {
- sc->locked_ch = NULL;
- if (sc->restart_ch) {
- ch = sc->restart_ch;
- sc->restart_ch = NULL;
- mtx_unlock(&sc->locked_mtx);
- ata_start(ch->dev);
- return res;
- }
- }
- break;
-
- case ATA_LF_WHICH:
- break;
- }
- if (sc->locked_ch)
- res = sc->locked_ch->unit;
- mtx_unlock(&sc->locked_mtx);
- return res;
-}
-
-static device_method_t ata_usbchannel_methods[] = {
- /* device interface */
- DEVMETHOD(device_probe, ata_usbchannel_probe),
- DEVMETHOD(device_attach, ata_usbchannel_attach),
- DEVMETHOD(device_detach, ata_usbchannel_detach),
-
- /* ATA methods */
- DEVMETHOD(ata_setmode, ata_usbchannel_setmode),
- DEVMETHOD(ata_locking, ata_usbchannel_locking),
- //DEVMETHOD(ata_reset, ata_usbchannel_reset),
-
- { 0, 0 }
-};
-
-static driver_t ata_usbchannel_driver = {
- "ata",
- ata_usbchannel_methods,
- sizeof(struct ata_channel),
-};
-
-DRIVER_MODULE(ata, atausb, ata_usbchannel_driver, ata_devclass, 0, 0);
-MODULE_DEPEND(atausb, ata, 1, 1, 1);
diff --git a/sys/legacy/dev/sound/usb/uaudio.c b/sys/legacy/dev/sound/usb/uaudio.c
deleted file mode 100644
index 758d6cd..0000000
--- a/sys/legacy/dev/sound/usb/uaudio.c
+++ /dev/null
@@ -1,4662 +0,0 @@
-/* $NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1999 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
- * http://www.usb.org/developers/devclass_docs/frmts10.pdf
- * http://www.usb.org/developers/devclass_docs/termt10.pdf
- */
-
-#include <sys/cdefs.h>
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $");
-#endif
-
-/*
- * Also merged:
- * $NetBSD: uaudio.c,v 1.94 2005/01/15 15:19:53 kent Exp $
- * $NetBSD: uaudio.c,v 1.95 2005/01/16 06:02:19 dsainty Exp $
- * $NetBSD: uaudio.c,v 1.96 2005/01/16 12:46:00 kent Exp $
- * $NetBSD: uaudio.c,v 1.97 2005/02/24 08:19:38 martin Exp $
- * $NetBSD: uaudio.c,v 1.102 2006/04/14 17:00:55 christos Exp $
- * $NetBSD: uaudio.c,v 1.103 2006/05/11 19:09:25 mrg Exp $
- * $NetBSD: uaudio.c,v 1.105 2006/10/04 16:00:15 christos Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-#include <sys/device.h>
-#include <sys/ioctl.h>
-#endif
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/reboot.h> /* for bootverbose */
-#include <sys/select.h>
-#include <sys/proc.h>
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-#include <sys/device.h>
-#elif defined(__FreeBSD__)
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#endif
-#include <sys/poll.h>
-#if defined(__FreeBSD__)
-#include <sys/sysctl.h>
-#include <sys/sbuf.h>
-#endif
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-#include <sys/audioio.h>
-#include <dev/audio_if.h>
-#include <dev/audiovar.h>
-#include <dev/mulaw.h>
-#include <dev/auconv.h>
-#elif defined(__FreeBSD__)
-#include <dev/sound/pcm/sound.h> /* XXXXX */
-#include <dev/sound/chip.h>
-#include "feeder_if.h"
-#endif
-
-#include <dev/usb/usb_port.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_quirks.h>
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-#include <dev/usb/uaudioreg.h>
-#elif defined(__FreeBSD__)
-#include <dev/sound/usb/uaudioreg.h>
-#include <dev/sound/usb/uaudio.h>
-#endif
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-/* #define UAUDIO_DEBUG */
-#else
-/* #define USB_DEBUG */
-#endif
-/* #define UAUDIO_MULTIPLE_ENDPOINTS */
-#ifdef USB_DEBUG
-#define DPRINTF(x) do { if (uaudiodebug) printf x; } while (0)
-#define DPRINTFN(n,x) do { if (uaudiodebug>(n)) printf x; } while (0)
-int uaudiodebug = 0;
-#if defined(__FreeBSD__)
-SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
-SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, debug, CTLFLAG_RW,
- &uaudiodebug, 0, "uaudio debug level");
-#endif
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UAUDIO_NCHANBUFS 6 /* number of outstanding request */
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-#define UAUDIO_NFRAMES 10 /* ms of sound in each request */
-#elif defined(__FreeBSD__)
-#define UAUDIO_NFRAMES 20 /* ms of sound in each request */
-#endif
-
-
-#define MIX_MAX_CHAN 8
-struct mixerctl {
- uint16_t wValue[MIX_MAX_CHAN]; /* using nchan */
- uint16_t wIndex;
- uint8_t nchan;
- uint8_t type;
-#define MIX_ON_OFF 1
-#define MIX_SIGNED_16 2
-#define MIX_UNSIGNED_16 3
-#define MIX_SIGNED_8 4
-#define MIX_SELECTOR 5
-#define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
-#define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
- int minval, maxval;
- u_int delta;
- u_int mul;
-#if defined(__FreeBSD__) /* XXXXX */
- unsigned ctl;
-#define MAX_SELECTOR_INPUT_PIN 256
- uint8_t slctrtype[MAX_SELECTOR_INPUT_PIN];
-#endif
- uint8_t class;
-#if !defined(__FreeBSD__)
- char ctlname[MAX_AUDIO_DEV_LEN];
- char *ctlunit;
-#endif
-};
-#define MAKE(h,l) (((h) << 8) | (l))
-
-struct as_info {
- uint8_t alt;
- uint8_t encoding;
- uint8_t attributes; /* Copy of bmAttributes of
- * usb_audio_streaming_endpoint_descriptor
- */
- usbd_interface_handle ifaceh;
- const usb_interface_descriptor_t *idesc;
- const usb_endpoint_descriptor_audio_t *edesc;
- const usb_endpoint_descriptor_audio_t *edesc1;
- const struct usb_audio_streaming_type1_descriptor *asf1desc;
- int sc_busy; /* currently used */
-};
-
-struct chan {
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- void (*intr)(void *); /* DMA completion intr handler */
- void *arg; /* arg for intr() */
-#else
- struct pcm_channel *pcm_ch;
-#endif
- usbd_pipe_handle pipe;
- usbd_pipe_handle sync_pipe;
-
- u_int sample_size;
- u_int sample_rate;
- u_int bytes_per_frame;
- u_int fraction; /* fraction/1000 is the extra samples/frame */
- u_int residue; /* accumulates the fractional samples */
-
- u_char *start; /* upper layer buffer start */
- u_char *end; /* upper layer buffer end */
- u_char *cur; /* current position in upper layer buffer */
- int blksize; /* chunk size to report up */
- int transferred; /* transferred bytes not reported up */
-
- int altidx; /* currently used altidx */
-
- int curchanbuf;
- struct chanbuf {
- struct chan *chan;
- usbd_xfer_handle xfer;
- u_char *buffer;
- u_int16_t sizes[UAUDIO_NFRAMES];
- u_int16_t offsets[UAUDIO_NFRAMES];
- u_int16_t size;
- } chanbufs[UAUDIO_NCHANBUFS];
-
- struct uaudio_softc *sc; /* our softc */
-#if defined(__FreeBSD__)
- u_int32_t format;
- int precision;
- int channels;
-#endif
-};
-
-struct uaudio_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev; /* USB device */
- int sc_ac_iface; /* Audio Control interface */
- usbd_interface_handle sc_ac_ifaceh;
- struct chan sc_playchan; /* play channel */
- struct chan sc_recchan; /* record channel */
- int sc_nullalt;
- int sc_audio_rev;
- struct as_info *sc_alts; /* alternate settings */
- int sc_nalts; /* # of alternate settings */
- int sc_altflags;
-#define HAS_8 0x01
-#define HAS_16 0x02
-#define HAS_8U 0x04
-#define HAS_ALAW 0x08
-#define HAS_MULAW 0x10
-#define UA_NOFRAC 0x20 /* don't do sample rate adjustment */
-#define HAS_24 0x40
-#define HAS_32 0x80
- int sc_mode; /* play/record capability */
- struct mixerctl *sc_ctls; /* mixer controls */
- int sc_nctls; /* # of mixer controls */
- device_t sc_audiodev;
- char sc_dying;
-#if defined(__FreeBSD__)
- struct sbuf uaudio_sndstat;
- int uaudio_sndstat_flag;
- int async;
-#endif
- int sc_vendor;
- int sc_product;
- int sc_release;
-};
-
-struct terminal_list {
- int size;
- uint16_t terminals[1];
-};
-#define TERMINAL_LIST_SIZE(N) (offsetof(struct terminal_list, terminals) \
- + sizeof(uint16_t) * (N))
-
-struct io_terminal {
- union {
- const usb_descriptor_t *desc;
- const struct usb_audio_input_terminal *it;
- const struct usb_audio_output_terminal *ot;
- const struct usb_audio_mixer_unit *mu;
- const struct usb_audio_selector_unit *su;
- const struct usb_audio_feature_unit *fu;
- const struct usb_audio_processing_unit *pu;
- const struct usb_audio_extension_unit *eu;
- } d;
- int inputs_size;
- struct terminal_list **inputs; /* list of source input terminals */
- struct terminal_list *output; /* list of destination output terminals */
- int direct; /* directly connected to an output terminal */
-};
-
-#define UAC_OUTPUT 0
-#define UAC_INPUT 1
-#define UAC_EQUAL 2
-#define UAC_RECORD 3
-#define UAC_NCLASSES 4
-#ifdef USB_DEBUG
-#if defined(__FreeBSD__)
-#define AudioCinputs "inputs"
-#define AudioCoutputs "outputs"
-#define AudioCrecord "record"
-#define AudioCequalization "equalization"
-#endif
-static const char *uac_names[] = {
- AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord,
-};
-#endif
-
-static usbd_status uaudio_identify_ac
- (struct uaudio_softc *, const usb_config_descriptor_t *);
-static usbd_status uaudio_identify_as
- (struct uaudio_softc *, const usb_config_descriptor_t *);
-static usbd_status uaudio_process_as
- (struct uaudio_softc *, const char *, int *, int,
- const usb_interface_descriptor_t *);
-
-static void uaudio_add_alt(struct uaudio_softc *, const struct as_info *);
-
-static const usb_interface_descriptor_t *uaudio_find_iface
- (const char *, int, int *, int);
-
-static void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static char *uaudio_id_name
- (struct uaudio_softc *, const struct io_terminal *, int);
-#endif
-
-#ifdef USB_DEBUG
-static void uaudio_dump_cluster(const struct usb_audio_cluster *);
-#endif
-static struct usb_audio_cluster uaudio_get_cluster
- (int, const struct io_terminal *);
-static void uaudio_add_input
- (struct uaudio_softc *, const struct io_terminal *, int);
-static void uaudio_add_output
- (struct uaudio_softc *, const struct io_terminal *, int);
-static void uaudio_add_mixer
- (struct uaudio_softc *, const struct io_terminal *, int);
-static void uaudio_add_selector
- (struct uaudio_softc *, const struct io_terminal *, int);
-#ifdef USB_DEBUG
-static const char *uaudio_get_terminal_name(int);
-#endif
-static int uaudio_determine_class
- (const struct io_terminal *, struct mixerctl *);
-#if defined(__FreeBSD__)
-static int uaudio_feature_name(const struct io_terminal *,
- struct mixerctl *);
-#else
-static const char *uaudio_feature_name
- (const struct io_terminal *, struct mixerctl *);
-#endif
-static void uaudio_add_feature
- (struct uaudio_softc *, const struct io_terminal *, int);
-static void uaudio_add_processing_updown
- (struct uaudio_softc *, const struct io_terminal *, int);
-static void uaudio_add_processing
- (struct uaudio_softc *, const struct io_terminal *, int);
-static void uaudio_add_extension
- (struct uaudio_softc *, const struct io_terminal *, int);
-static struct terminal_list *uaudio_merge_terminal_list
- (const struct io_terminal *);
-static struct terminal_list *uaudio_io_terminaltype
- (int, struct io_terminal *, int);
-static usbd_status uaudio_identify
- (struct uaudio_softc *, const usb_config_descriptor_t *);
-
-static int uaudio_signext(int, int);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static int uaudio_value2bsd(struct mixerctl *, int);
-#endif
-static int uaudio_bsd2value(struct mixerctl *, int);
-static int uaudio_get(struct uaudio_softc *, int, int, int, int, int);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static int uaudio_ctl_get
- (struct uaudio_softc *, int, struct mixerctl *, int);
-#endif
-static void uaudio_set
- (struct uaudio_softc *, int, int, int, int, int, int);
-static void uaudio_ctl_set
- (struct uaudio_softc *, int, struct mixerctl *, int, int);
-
-static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int);
-
-static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *);
-static void uaudio_chan_close(struct uaudio_softc *, struct chan *);
-static usbd_status uaudio_chan_alloc_buffers
- (struct uaudio_softc *, struct chan *);
-static void uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static void uaudio_chan_init
- (struct chan *, int, const struct audio_params *, int);
-static void uaudio_chan_set_param(struct chan *, u_char *, u_char *, int);
-#endif
-
-static void uaudio_chan_ptransfer(struct chan *);
-static void uaudio_chan_pintr
- (usbd_xfer_handle, usbd_private_handle, usbd_status);
-
-static void uaudio_chan_rtransfer(struct chan *);
-static void uaudio_chan_rintr
- (usbd_xfer_handle, usbd_private_handle, usbd_status);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static int uaudio_open(void *, int);
-static void uaudio_close(void *);
-static int uaudio_drain(void *);
-static int uaudio_query_encoding(void *, struct audio_encoding *);
-static void uaudio_get_minmax_rates
- (int, const struct as_info *, const struct audio_params *,
- int, u_long *, u_long *);
-static int uaudio_match_alt_sub
- (int, const struct as_info *, const struct audio_params *, int, u_long);
-static int uaudio_match_alt_chan
- (int, const struct as_info *, struct audio_params *, int);
-static int uaudio_match_alt
- (int, const struct as_info *, struct audio_params *, int);
-static int uaudio_set_params
- (void *, int, int, struct audio_params *, struct audio_params *);
-static int uaudio_round_blocksize(void *, int);
-static int uaudio_trigger_output
- (void *, void *, void *, int, void (*)(void *), void *,
- struct audio_params *);
-static int uaudio_trigger_input
- (void *, void *, void *, int, void (*)(void *), void *,
- struct audio_params *);
-static int uaudio_halt_in_dma(void *);
-static int uaudio_halt_out_dma(void *);
-static int uaudio_getdev(void *, struct audio_device *);
-static int uaudio_mixer_set_port(void *, mixer_ctrl_t *);
-static int uaudio_mixer_get_port(void *, mixer_ctrl_t *);
-static int uaudio_query_devinfo(void *, mixer_devinfo_t *);
-static int uaudio_get_props(void *);
-
-static const struct audio_hw_if uaudio_hw_if = {
- uaudio_open,
- uaudio_close,
- uaudio_drain,
- uaudio_query_encoding,
- uaudio_set_params,
- uaudio_round_blocksize,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- uaudio_halt_out_dma,
- uaudio_halt_in_dma,
- NULL,
- uaudio_getdev,
- NULL,
- uaudio_mixer_set_port,
- uaudio_mixer_get_port,
- uaudio_query_devinfo,
- NULL,
- NULL,
- NULL,
- NULL,
- uaudio_get_props,
- uaudio_trigger_output,
- uaudio_trigger_input,
- NULL,
-};
-
-static struct audio_device uaudio_device = {
- "USB audio",
- "",
- "uaudio"
-};
-
-#elif defined(__FreeBSD__)
-static int audio_attach_mi(device_t);
-static int uaudio_init_params(struct uaudio_softc * sc, struct chan *ch, int mode);
-static int uaudio_sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose);
-
-/* for NetBSD compatibirity */
-#define AUMODE_PLAY 0x01
-#define AUMODE_RECORD 0x02
-
-#define AUDIO_PROP_FULLDUPLEX 0x01
-
-#define AUDIO_ENCODING_ULAW 1
-#define AUDIO_ENCODING_ALAW 2
-#define AUDIO_ENCODING_SLINEAR_LE 6
-#define AUDIO_ENCODING_SLINEAR_BE 7
-#define AUDIO_ENCODING_ULINEAR_LE 8
-#define AUDIO_ENCODING_ULINEAR_BE 9
-
-#endif /* FreeBSD */
-
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-
-USB_DECLARE_DRIVER(uaudio);
-
-#elif defined(__FreeBSD__)
-
-USB_DECLARE_DRIVER_INIT(uaudio,
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(bus_print_child, bus_generic_print_child)
- );
-#endif
-
-
-USB_MATCH(uaudio)
-{
- USB_MATCH_START(uaudio, uaa);
- usb_interface_descriptor_t *id;
-
- if (uaa->iface == NULL)
- return UMATCH_NONE;
-
- id = usbd_get_interface_descriptor(uaa->iface);
- /* Trigger on the control interface. */
- if (id == NULL ||
- id->bInterfaceClass != UICLASS_AUDIO ||
- id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL ||
- (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
- return UMATCH_NONE;
-
- return UMATCH_IFACECLASS_IFACESUBCLASS;
-}
-
-USB_ATTACH(uaudio)
-{
- USB_ATTACH_START(uaudio, sc, uaa);
- usb_interface_descriptor_t *id;
- usb_config_descriptor_t *cdesc;
-#if !defined(__FreeBSD__)
- char devinfo[1024];
-#endif
- usbd_status err;
- int i, j, found;
-
-#if defined(__FreeBSD__)
- sc->sc_dev = self;
-#else
- usbd_devinfo(uaa->device, 0, devinfo, sizeof(devinfo));
- printf(": %s\n", devinfo);
-#endif
-
- sc->sc_udev = uaa->device;
- sc->sc_vendor = uaa->vendor;
- sc->sc_product = uaa->product;
- sc->sc_release = uaa->release;
-#if defined(__FreeBSD__)
- if (resource_int_value(device_get_name(sc->sc_dev),
- device_get_unit(sc->sc_dev), "async", &i) == 0 && i != 0)
- sc->async = 1;
- else
- sc->async = 0;
-#endif
-
- cdesc = usbd_get_config_descriptor(sc->sc_udev);
- if (cdesc == NULL) {
- printf("%s: failed to get configuration descriptor\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-
- err = uaudio_identify(sc, cdesc);
- if (err) {
- printf("%s: audio descriptors make no sense, error=%d\n",
- device_get_nameunit(sc->sc_dev), err);
- return ENXIO;
- }
-
- sc->sc_ac_ifaceh = uaa->iface;
- /* Pick up the AS interface. */
- for (i = 0; i < uaa->nifaces; i++) {
- if (uaa->ifaces[i] == NULL)
- continue;
- id = usbd_get_interface_descriptor(uaa->ifaces[i]);
- if (id == NULL)
- continue;
- found = 0;
- for (j = 0; j < sc->sc_nalts; j++) {
- if (id->bInterfaceNumber ==
- sc->sc_alts[j].idesc->bInterfaceNumber) {
- sc->sc_alts[j].ifaceh = uaa->ifaces[i];
- found = 1;
- }
- }
- if (found)
- uaa->ifaces[i] = NULL;
- }
-
- for (j = 0; j < sc->sc_nalts; j++) {
- if (sc->sc_alts[j].ifaceh == NULL) {
- printf("%s: alt %d missing AS interface(s)\n",
- device_get_nameunit(sc->sc_dev), j);
- return ENXIO;
- }
- }
-
- printf("%s: audio rev %d.%02x\n", device_get_nameunit(sc->sc_dev),
- sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
-
- sc->sc_playchan.sc = sc->sc_recchan.sc = sc;
- sc->sc_playchan.altidx = -1;
- sc->sc_recchan.altidx = -1;
-
- if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
- sc->sc_altflags |= UA_NOFRAC;
-
-#ifndef USB_DEBUG
- if (bootverbose)
-#endif
- printf("%s: %d mixer controls\n", device_get_nameunit(sc->sc_dev),
- sc->sc_nctls);
-
-#if !defined(__FreeBSD__)
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-#endif
-
- DPRINTF(("uaudio_attach: doing audio_attach_mi\n"));
-#if defined(__OpenBSD__)
- audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
-#elif defined(__NetBSD__)
- sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
-#elif defined(__FreeBSD__)
- sc->sc_dying = 0;
- if (audio_attach_mi(sc->sc_dev)) {
- printf("audio_attach_mi failed\n");
- return ENXIO;
- }
-#endif
-
-#if defined(__FreeBSD__)
- SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->sc_dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)),
- OID_AUTO, "async", CTLFLAG_RW, &sc->async, 0,
- "Asynchronous USB request");
-#endif
- return 0;
-}
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-int
-uaudio_activate(device_t self, enum devact act)
-{
- struct uaudio_softc *sc;
- int rv;
-
- sc = (struct uaudio_softc *)self;
- rv = 0;
- switch (act) {
- case DVACT_ACTIVATE:
- return EOPNOTSUPP;
-
- case DVACT_DEACTIVATE:
- if (sc->sc_audiodev != NULL)
- rv = config_deactivate(sc->sc_audiodev);
- sc->sc_dying = 1;
- break;
- }
- return rv;
-}
-#endif
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-int
-uaudio_detach(device_t self, int flags)
-{
- struct uaudio_softc *sc;
- int rv;
-
- sc = (struct uaudio_softc *)self;
- rv = 0;
- /* Wait for outstanding requests to complete. */
- usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
-
- if (sc->sc_audiodev != NULL)
- rv = config_detach(sc->sc_audiodev, flags);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
- return rv;
-}
-#elif defined(__FreeBSD__)
-
-USB_DETACH(uaudio)
-{
- struct sndcard_func *func;
- device_t *devlist = NULL;
- int err, i, devcount;
-
- USB_DETACH_START(uaudio, sc);
-
- sbuf_delete(&(sc->uaudio_sndstat));
- sc->uaudio_sndstat_flag = 0;
-
- sc->sc_dying = 1;
-
-#if 0 /* XXX */
- /* Wait for outstanding requests to complete. */
- usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
-#endif
-
- err = bus_generic_detach(sc->sc_dev);
-
- if (err == 0 &&
- device_get_children(sc->sc_dev, &devlist, &devcount) == 0) {
- for (i = 0; devlist != NULL && i < devcount; i++) {
- func = device_get_ivars(devlist[i]);
- if (func != NULL && func->func == SCF_PCM &&
- func->varinfo == NULL) {
- device_set_ivars(devlist[i], NULL);
- free(func, M_DEVBUF);
- device_delete_child(sc->sc_dev, devlist[i]);
- }
- }
- free(devlist, M_TEMP);
- }
-
- return err;
-}
-#endif
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static int
-uaudio_query_encoding(void *addr, struct audio_encoding *fp)
-{
- struct uaudio_softc *sc;
- int flags;
- int idx;
-
- sc = addr;
- flags = sc->sc_altflags;
- if (sc->sc_dying)
- return EIO;
-
- if (sc->sc_nalts == 0 || flags == 0)
- return ENXIO;
-
- idx = fp->index;
- switch (idx) {
- case 0:
- strlcpy(fp->name, AudioEulinear, sizeof(fp->name));
- fp->encoding = AUDIO_ENCODING_ULINEAR;
- fp->precision = 8;
- fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
- return (0);
- case 1:
- strlcpy(fp->name, AudioEmulaw, sizeof(fp->name));
- fp->encoding = AUDIO_ENCODING_ULAW;
- fp->precision = 8;
- fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
- return (0);
- case 2:
- strlcpy(fp->name, AudioEalaw, sizeof(fp->name));
- fp->encoding = AUDIO_ENCODING_ALAW;
- fp->precision = 8;
- fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
- return (0);
- case 3:
- strlcpy(fp->name, AudioEslinear, sizeof(fp->name));
- fp->encoding = AUDIO_ENCODING_SLINEAR;
- fp->precision = 8;
- fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
- return (0);
- case 4:
- strlcpy(fp->name, AudioEslinear_le, sizeof(fp->name));
- fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
- fp->precision = 16;
- fp->flags = 0;
- return (0);
- case 5:
- strlcpy(fp->name, AudioEulinear_le, sizeof(fp->name));
- fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
- fp->precision = 16;
- fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
- return (0);
- case 6:
- strlcpy(fp->name, AudioEslinear_be, sizeof(fp->name));
- fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
- fp->precision = 16;
- fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
- return (0);
- case 7:
- strlcpy(fp->name, AudioEulinear_be, sizeof(fp->name));
- fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
- fp->precision = 16;
- fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
- return (0);
- default:
- return (EINVAL);
- }
-}
-#endif
-
-static const usb_interface_descriptor_t *
-uaudio_find_iface(const char *buf, int size, int *offsp, int subtype)
-{
- const usb_interface_descriptor_t *d;
-
- while (*offsp < size) {
- d = (const void *)(buf + *offsp);
- *offsp += d->bLength;
- if (d->bDescriptorType == UDESC_INTERFACE &&
- d->bInterfaceClass == UICLASS_AUDIO &&
- d->bInterfaceSubClass == subtype)
- return d;
- }
- return NULL;
-}
-
-static void
-uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
-{
- int res;
- size_t len;
- struct mixerctl *nmc;
-
-#if defined(__FreeBSD__)
- if (mc->class < UAC_NCLASSES) {
- DPRINTF(("%s: adding %s.%d\n",
- __func__, uac_names[mc->class], mc->ctl));
- } else {
- DPRINTF(("%s: adding %d\n", __func__, mc->ctl));
- }
-#else
- if (mc->class < UAC_NCLASSES) {
- DPRINTF(("%s: adding %s.%s\n",
- __func__, uac_names[mc->class], mc->ctlname));
- } else {
- DPRINTF(("%s: adding %s\n", __func__, mc->ctlname));
- }
-#endif
- len = sizeof(*mc) * (sc->sc_nctls + 1);
- nmc = malloc(len, M_USBDEV, M_NOWAIT);
- if (nmc == NULL) {
- printf("uaudio_mixer_add_ctl: no memory\n");
- return;
- }
- /* Copy old data, if there was any */
- if (sc->sc_nctls != 0) {
- memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls));
- free(sc->sc_ctls, M_USBDEV);
- }
- sc->sc_ctls = nmc;
-
- mc->delta = 0;
- if (mc->type == MIX_ON_OFF) {
- mc->minval = 0;
- mc->maxval = 1;
- } else if (mc->type == MIX_SELECTOR) {
- ;
- } else {
- /* Determine min and max values. */
- mc->minval = uaudio_signext(mc->type,
- uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
- mc->wValue[0], mc->wIndex,
- MIX_SIZE(mc->type)));
- mc->maxval = 1 + uaudio_signext(mc->type,
- uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
- mc->wValue[0], mc->wIndex,
- MIX_SIZE(mc->type)));
- mc->mul = mc->maxval - mc->minval;
- if (mc->mul == 0)
- mc->mul = 1;
- res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
- mc->wValue[0], mc->wIndex,
- MIX_SIZE(mc->type));
- if (res > 0)
- mc->delta = (res * 255 + mc->mul/2) / mc->mul;
- }
-
- sc->sc_ctls[sc->sc_nctls++] = *mc;
-
-#ifdef USB_DEBUG
- if (uaudiodebug > 2) {
- int i;
- DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0]));
- for (i = 1; i < mc->nchan; i++)
- DPRINTF((",%04x", mc->wValue[i]));
-#if defined(__FreeBSD__)
- DPRINTF((" wIndex=%04x type=%d ctl='%d' "
- "min=%d max=%d\n",
- mc->wIndex, mc->type, mc->ctl,
- mc->minval, mc->maxval));
-#else
- DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' "
- "min=%d max=%d\n",
- mc->wIndex, mc->type, mc->ctlname, mc->ctlunit,
- mc->minval, mc->maxval));
-#endif
- }
-#endif
-}
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static char *
-uaudio_id_name(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
-{
- static char buf[32];
-
- snprintf(buf, sizeof(buf), "i%d", id);
- return buf;
-}
-#endif
-
-#ifdef USB_DEBUG
-static void
-uaudio_dump_cluster(const struct usb_audio_cluster *cl)
-{
- static const char *channel_names[16] = {
- "LEFT", "RIGHT", "CENTER", "LFE",
- "LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER",
- "SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP",
- "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15",
- };
- int cc, i, first;
-
- cc = UGETW(cl->wChannelConfig);
- printf("cluster: bNrChannels=%u wChannelConfig=0x%.4x",
- cl->bNrChannels, cc);
- first = TRUE;
- for (i = 0; cc != 0; i++) {
- if (cc & 1) {
- printf("%c%s", first ? '<' : ',', channel_names[i]);
- first = FALSE;
- }
- cc = cc >> 1;
- }
- printf("> iChannelNames=%u", cl->iChannelNames);
-}
-#endif
-
-static struct usb_audio_cluster
-uaudio_get_cluster(int id, const struct io_terminal *iot)
-{
- struct usb_audio_cluster r;
- const usb_descriptor_t *dp;
- int i;
-
- for (i = 0; i < 25; i++) { /* avoid infinite loops */
- dp = iot[id].d.desc;
- if (dp == 0)
- goto bad;
- switch (dp->bDescriptorSubtype) {
- case UDESCSUB_AC_INPUT:
- r.bNrChannels = iot[id].d.it->bNrChannels;
- USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig));
- r.iChannelNames = iot[id].d.it->iChannelNames;
- return r;
- case UDESCSUB_AC_OUTPUT:
- id = iot[id].d.ot->bSourceId;
- break;
- case UDESCSUB_AC_MIXER:
- r = *(const struct usb_audio_cluster *)
- &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins];
- return r;
- case UDESCSUB_AC_SELECTOR:
- /* XXX This is not really right */
- id = iot[id].d.su->baSourceId[0];
- break;
- case UDESCSUB_AC_FEATURE:
- id = iot[id].d.fu->bSourceId;
- break;
- case UDESCSUB_AC_PROCESSING:
- r = *(const struct usb_audio_cluster *)
- &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins];
- return r;
- case UDESCSUB_AC_EXTENSION:
- r = *(const struct usb_audio_cluster *)
- &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins];
- return r;
- default:
- goto bad;
- }
- }
- bad:
- printf("uaudio_get_cluster: bad data\n");
- memset(&r, 0, sizeof r);
- return r;
-
-}
-
-static void
-uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
-{
-#ifdef USB_DEBUG
- const struct usb_audio_input_terminal *d = iot[id].d.it;
-
- DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x "
- "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
- "iChannelNames=%d iTerminal=%d\n",
- d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
- d->bNrChannels, UGETW(d->wChannelConfig),
- d->iChannelNames, d->iTerminal));
-#endif
-}
-
-static void
-uaudio_add_output(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
-{
-#ifdef USB_DEBUG
- const struct usb_audio_output_terminal *d;
-
- d = iot[id].d.ot;
- DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x "
- "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
- d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
- d->bSourceId, d->iTerminal));
-#endif
-}
-
-static void
-uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
-{
- const struct usb_audio_mixer_unit *d = iot[id].d.mu;
- const struct usb_audio_mixer_unit_1 *d1;
- int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
- const uByte *bm;
- struct mixerctl mix;
-
- DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n",
- d->bUnitId, d->bNrInPins));
-
- /* Compute the number of input channels */
- ichs = 0;
- for (i = 0; i < d->bNrInPins; i++)
- ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
-
- /* and the number of output channels */
- d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
- ochs = d1->bNrChannels;
- DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs));
-
- bm = d1->bmControls;
- mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
- uaudio_determine_class(&iot[id], &mix);
- mix.type = MIX_SIGNED_16;
-#if !defined(__FreeBSD__) /* XXXXX */
- mix.ctlunit = AudioNvolume;
-#endif
-
-#define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
- for (p = i = 0; i < d->bNrInPins; i++) {
- chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
- mc = 0;
- for (c = 0; c < chs; c++) {
- mo = 0;
- for (o = 0; o < ochs; o++) {
- bno = (p + c) * ochs + o;
- if (BIT(bno))
- mo++;
- }
- if (mo == 1)
- mc++;
- }
- if (mc == chs && chs <= MIX_MAX_CHAN) {
- k = 0;
- for (c = 0; c < chs; c++)
- for (o = 0; o < ochs; o++) {
- bno = (p + c) * ochs + o;
- if (BIT(bno))
- mix.wValue[k++] =
- MAKE(p+c+1, o+1);
- }
-#if !defined(__FreeBSD__)
- snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s",
- d->bUnitId, uaudio_id_name(sc, iot,
- d->baSourceId[i]));
-#endif
- mix.nchan = chs;
- uaudio_mixer_add_ctl(sc, &mix);
- } else {
- /* XXX */
- }
-#undef BIT
- p += chs;
- }
-
-}
-
-static void
-uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
-{
- const struct usb_audio_selector_unit *d;
- struct mixerctl mix;
-#if !defined(__FreeBSD__)
- int i, wp;
-#else
- int i;
- struct mixerctl dummy;
-#endif
-
- d = iot[id].d.su;
- DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
- d->bUnitId, d->bNrInPins));
- mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
- mix.wValue[0] = MAKE(0, 0);
- uaudio_determine_class(&iot[id], &mix);
- mix.nchan = 1;
- mix.type = MIX_SELECTOR;
-#if defined(__FreeBSD__)
- mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
- mix.minval = 1;
- mix.maxval = d->bNrInPins;
- mix.mul = mix.maxval - mix.minval;
- for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) {
- mix.slctrtype[i] = SOUND_MIXER_NRDEVICES;
- }
- for (i = mix.minval; i <= mix.maxval; i++) {
- mix.slctrtype[i - 1] = uaudio_feature_name(&iot[d->baSourceId[i - 1]], &dummy);
- }
-#else
- mix.ctlunit = "";
- mix.minval = 1;
- mix.maxval = d->bNrInPins;
- mix.mul = mix.maxval - mix.minval;
- wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId);
- for (i = 1; i <= d->bNrInPins; i++) {
- wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp,
- "i%d", d->baSourceId[i - 1]);
- if (wp > MAX_AUDIO_DEV_LEN - 1)
- break;
- }
-#endif
- uaudio_mixer_add_ctl(sc, &mix);
-}
-
-#ifdef USB_DEBUG
-static const char *
-uaudio_get_terminal_name(int terminal_type)
-{
- static char buf[100];
-
- switch (terminal_type) {
- /* USB terminal types */
- case UAT_UNDEFINED: return "UAT_UNDEFINED";
- case UAT_STREAM: return "UAT_STREAM";
- case UAT_VENDOR: return "UAT_VENDOR";
- /* input terminal types */
- case UATI_UNDEFINED: return "UATI_UNDEFINED";
- case UATI_MICROPHONE: return "UATI_MICROPHONE";
- case UATI_DESKMICROPHONE: return "UATI_DESKMICROPHONE";
- case UATI_PERSONALMICROPHONE: return "UATI_PERSONALMICROPHONE";
- case UATI_OMNIMICROPHONE: return "UATI_OMNIMICROPHONE";
- case UATI_MICROPHONEARRAY: return "UATI_MICROPHONEARRAY";
- case UATI_PROCMICROPHONEARR: return "UATI_PROCMICROPHONEARR";
- /* output terminal types */
- case UATO_UNDEFINED: return "UATO_UNDEFINED";
- case UATO_SPEAKER: return "UATO_SPEAKER";
- case UATO_HEADPHONES: return "UATO_HEADPHONES";
- case UATO_DISPLAYAUDIO: return "UATO_DISPLAYAUDIO";
- case UATO_DESKTOPSPEAKER: return "UATO_DESKTOPSPEAKER";
- case UATO_ROOMSPEAKER: return "UATO_ROOMSPEAKER";
- case UATO_COMMSPEAKER: return "UATO_COMMSPEAKER";
- case UATO_SUBWOOFER: return "UATO_SUBWOOFER";
- /* bidir terminal types */
- case UATB_UNDEFINED: return "UATB_UNDEFINED";
- case UATB_HANDSET: return "UATB_HANDSET";
- case UATB_HEADSET: return "UATB_HEADSET";
- case UATB_SPEAKERPHONE: return "UATB_SPEAKERPHONE";
- case UATB_SPEAKERPHONEESUP: return "UATB_SPEAKERPHONEESUP";
- case UATB_SPEAKERPHONEECANC: return "UATB_SPEAKERPHONEECANC";
- /* telephony terminal types */
- case UATT_UNDEFINED: return "UATT_UNDEFINED";
- case UATT_PHONELINE: return "UATT_PHONELINE";
- case UATT_TELEPHONE: return "UATT_TELEPHONE";
- case UATT_DOWNLINEPHONE: return "UATT_DOWNLINEPHONE";
- /* external terminal types */
- case UATE_UNDEFINED: return "UATE_UNDEFINED";
- case UATE_ANALOGCONN: return "UATE_ANALOGCONN";
- case UATE_LINECONN: return "UATE_LINECONN";
- case UATE_LEGACYCONN: return "UATE_LEGACYCONN";
- case UATE_DIGITALAUIFC: return "UATE_DIGITALAUIFC";
- case UATE_SPDIF: return "UATE_SPDIF";
- case UATE_1394DA: return "UATE_1394DA";
- case UATE_1394DV: return "UATE_1394DV";
- /* embedded function terminal types */
- case UATF_UNDEFINED: return "UATF_UNDEFINED";
- case UATF_CALIBNOISE: return "UATF_CALIBNOISE";
- case UATF_EQUNOISE: return "UATF_EQUNOISE";
- case UATF_CDPLAYER: return "UATF_CDPLAYER";
- case UATF_DAT: return "UATF_DAT";
- case UATF_DCC: return "UATF_DCC";
- case UATF_MINIDISK: return "UATF_MINIDISK";
- case UATF_ANALOGTAPE: return "UATF_ANALOGTAPE";
- case UATF_PHONOGRAPH: return "UATF_PHONOGRAPH";
- case UATF_VCRAUDIO: return "UATF_VCRAUDIO";
- case UATF_VIDEODISCAUDIO: return "UATF_VIDEODISCAUDIO";
- case UATF_DVDAUDIO: return "UATF_DVDAUDIO";
- case UATF_TVTUNERAUDIO: return "UATF_TVTUNERAUDIO";
- case UATF_SATELLITE: return "UATF_SATELLITE";
- case UATF_CABLETUNER: return "UATF_CABLETUNER";
- case UATF_DSS: return "UATF_DSS";
- case UATF_RADIORECV: return "UATF_RADIORECV";
- case UATF_RADIOXMIT: return "UATF_RADIOXMIT";
- case UATF_MULTITRACK: return "UATF_MULTITRACK";
- case UATF_SYNTHESIZER: return "UATF_SYNTHESIZER";
- default:
- snprintf(buf, sizeof(buf), "unknown type (0x%.4x)", terminal_type);
- return buf;
- }
-}
-#endif
-
-static int
-uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix)
-{
- int terminal_type;
-
- if (iot == NULL || iot->output == NULL) {
- mix->class = UAC_OUTPUT;
- return 0;
- }
- terminal_type = 0;
- if (iot->output->size == 1)
- terminal_type = iot->output->terminals[0];
- /*
- * If the only output terminal is USB,
- * the class is UAC_RECORD.
- */
- if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
- mix->class = UAC_RECORD;
- if (iot->inputs_size == 1
- && iot->inputs[0] != NULL
- && iot->inputs[0]->size == 1)
- return iot->inputs[0]->terminals[0];
- else
- return 0;
- }
- /*
- * If the ultimate destination of the unit is just one output
- * terminal and the unit is connected to the output terminal
- * directly, the class is UAC_OUTPUT.
- */
- if (terminal_type != 0 && iot->direct) {
- mix->class = UAC_OUTPUT;
- return terminal_type;
- }
- /*
- * If the unit is connected to just one input terminal,
- * the class is UAC_INPUT.
- */
- if (iot->inputs_size == 1 && iot->inputs[0] != NULL
- && iot->inputs[0]->size == 1) {
- mix->class = UAC_INPUT;
- return iot->inputs[0]->terminals[0];
- }
- /*
- * Otherwise, the class is UAC_OUTPUT.
- */
- mix->class = UAC_OUTPUT;
- return terminal_type;
-}
-
-#if defined(__FreeBSD__)
-static int
-uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
-{
- int terminal_type;
-
- terminal_type = uaudio_determine_class(iot, mix);
- if (mix->class == UAC_RECORD && terminal_type == 0)
- return SOUND_MIXER_IMIX;
- DPRINTF(("%s: terminal_type=%s\n", __func__,
- uaudio_get_terminal_name(terminal_type)));
- switch (terminal_type) {
- case UAT_STREAM:
- return SOUND_MIXER_PCM;
-
- case UATI_MICROPHONE:
- case UATI_DESKMICROPHONE:
- case UATI_PERSONALMICROPHONE:
- case UATI_OMNIMICROPHONE:
- case UATI_MICROPHONEARRAY:
- case UATI_PROCMICROPHONEARR:
- return SOUND_MIXER_MIC;
-
- case UATO_SPEAKER:
- case UATO_DESKTOPSPEAKER:
- case UATO_ROOMSPEAKER:
- case UATO_COMMSPEAKER:
- return SOUND_MIXER_SPEAKER;
-
- case UATE_ANALOGCONN:
- case UATE_LINECONN:
- case UATE_LEGACYCONN:
- return SOUND_MIXER_LINE;
-
- case UATE_DIGITALAUIFC:
- case UATE_SPDIF:
- case UATE_1394DA:
- case UATE_1394DV:
- return SOUND_MIXER_ALTPCM;
-
- case UATF_CDPLAYER:
- return SOUND_MIXER_CD;
-
- case UATF_SYNTHESIZER:
- return SOUND_MIXER_SYNTH;
-
- case UATF_VIDEODISCAUDIO:
- case UATF_DVDAUDIO:
- case UATF_TVTUNERAUDIO:
- return SOUND_MIXER_VIDEO;
-
-/* telephony terminal types */
- case UATT_UNDEFINED:
- case UATT_PHONELINE:
- case UATT_TELEPHONE:
- case UATT_DOWNLINEPHONE:
- return SOUND_MIXER_PHONEIN;
-/* return SOUND_MIXER_PHONEOUT;*/
-
- case UATF_RADIORECV:
- case UATF_RADIOXMIT:
- return SOUND_MIXER_RADIO;
-
- case UAT_UNDEFINED:
- case UAT_VENDOR:
- case UATI_UNDEFINED:
-/* output terminal types */
- case UATO_UNDEFINED:
- case UATO_DISPLAYAUDIO:
- case UATO_SUBWOOFER:
- case UATO_HEADPHONES:
-/* bidir terminal types */
- case UATB_UNDEFINED:
- case UATB_HANDSET:
- case UATB_HEADSET:
- case UATB_SPEAKERPHONE:
- case UATB_SPEAKERPHONEESUP:
- case UATB_SPEAKERPHONEECANC:
-/* external terminal types */
- case UATE_UNDEFINED:
-/* embedded function terminal types */
- case UATF_UNDEFINED:
- case UATF_CALIBNOISE:
- case UATF_EQUNOISE:
- case UATF_DAT:
- case UATF_DCC:
- case UATF_MINIDISK:
- case UATF_ANALOGTAPE:
- case UATF_PHONOGRAPH:
- case UATF_VCRAUDIO:
- case UATF_SATELLITE:
- case UATF_CABLETUNER:
- case UATF_DSS:
- case UATF_MULTITRACK:
- case 0xffff:
- default:
- DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
- return SOUND_MIXER_VOLUME;
- }
- return SOUND_MIXER_VOLUME;
-}
-#else
-static const char *
-uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
-{
- int terminal_type;
-
- terminal_type = uaudio_determine_class(iot, mix);
- if (mix->class == UAC_RECORD && terminal_type == 0)
- return AudioNmixerout;
- DPRINTF(("%s: terminal_type=%s\n", __func__,
- uaudio_get_terminal_name(terminal_type)));
- switch (terminal_type) {
- case UAT_STREAM:
- return AudioNdac;
-
- case UATI_MICROPHONE:
- case UATI_DESKMICROPHONE:
- case UATI_PERSONALMICROPHONE:
- case UATI_OMNIMICROPHONE:
- case UATI_MICROPHONEARRAY:
- case UATI_PROCMICROPHONEARR:
- return AudioNmicrophone;
-
- case UATO_SPEAKER:
- case UATO_DESKTOPSPEAKER:
- case UATO_ROOMSPEAKER:
- case UATO_COMMSPEAKER:
- return AudioNspeaker;
-
- case UATO_HEADPHONES:
- return AudioNheadphone;
-
- case UATO_SUBWOOFER:
- return AudioNlfe;
-
- /* telephony terminal types */
- case UATT_UNDEFINED:
- case UATT_PHONELINE:
- case UATT_TELEPHONE:
- case UATT_DOWNLINEPHONE:
- return "phone";
-
- case UATE_ANALOGCONN:
- case UATE_LINECONN:
- case UATE_LEGACYCONN:
- return AudioNline;
-
- case UATE_DIGITALAUIFC:
- case UATE_SPDIF:
- case UATE_1394DA:
- case UATE_1394DV:
- return AudioNaux;
-
- case UATF_CDPLAYER:
- return AudioNcd;
-
- case UATF_SYNTHESIZER:
- return AudioNfmsynth;
-
- case UATF_VIDEODISCAUDIO:
- case UATF_DVDAUDIO:
- case UATF_TVTUNERAUDIO:
- return AudioNvideo;
-
- case UAT_UNDEFINED:
- case UAT_VENDOR:
- case UATI_UNDEFINED:
-/* output terminal types */
- case UATO_UNDEFINED:
- case UATO_DISPLAYAUDIO:
-/* bidir terminal types */
- case UATB_UNDEFINED:
- case UATB_HANDSET:
- case UATB_HEADSET:
- case UATB_SPEAKERPHONE:
- case UATB_SPEAKERPHONEESUP:
- case UATB_SPEAKERPHONEECANC:
-/* external terminal types */
- case UATE_UNDEFINED:
-/* embedded function terminal types */
- case UATF_UNDEFINED:
- case UATF_CALIBNOISE:
- case UATF_EQUNOISE:
- case UATF_DAT:
- case UATF_DCC:
- case UATF_MINIDISK:
- case UATF_ANALOGTAPE:
- case UATF_PHONOGRAPH:
- case UATF_VCRAUDIO:
- case UATF_SATELLITE:
- case UATF_CABLETUNER:
- case UATF_DSS:
- case UATF_RADIORECV:
- case UATF_RADIOXMIT:
- case UATF_MULTITRACK:
- case 0xffff:
- default:
- DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
- return AudioNmaster;
- }
- return AudioNmaster;
-}
-#endif
-
-static void
-uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
-{
- const struct usb_audio_feature_unit *d;
- const uByte *ctls;
- int ctlsize;
- int nchan;
- u_int fumask, mmask, cmask;
- struct mixerctl mix;
- int chan, ctl, i, unit;
-#if defined(__FreeBSD__)
- int mixernumber;
-#else
- const char *mixername;
-#endif
-
-#define GET(i) (ctls[(i)*ctlsize] | \
- (ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0))
- d = iot[id].d.fu;
- ctls = d->bmaControls;
- ctlsize = d->bControlSize;
- nchan = (d->bLength - 7) / ctlsize;
- mmask = GET(0);
- /* Figure out what we can control */
- for (cmask = 0, chan = 1; chan < nchan; chan++) {
- DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n",
- chan, GET(chan)));
- cmask |= GET(chan);
- }
-
-#if !defined(__FreeBSD__)
- DPRINTFN(1,("uaudio_add_feature: bUnitId=%d, "
- "%d channels, mmask=0x%04x, cmask=0x%04x\n",
- d->bUnitId, nchan, mmask, cmask));
-#endif
-
- if (nchan > MIX_MAX_CHAN)
- nchan = MIX_MAX_CHAN;
- unit = d->bUnitId;
- mix.wIndex = MAKE(unit, sc->sc_ac_iface);
- for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) {
- fumask = FU_MASK(ctl);
- DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n",
- ctl, fumask));
- if (mmask & fumask) {
- mix.nchan = 1;
- mix.wValue[0] = MAKE(ctl, 0);
- } else if (cmask & fumask) {
- mix.nchan = nchan - 1;
- for (i = 1; i < nchan; i++) {
- if (GET(i) & fumask)
- mix.wValue[i-1] = MAKE(ctl, i);
- else
- mix.wValue[i-1] = -1;
- }
- } else {
- continue;
- }
-#undef GET
-
-#if defined(__FreeBSD__)
- mixernumber = uaudio_feature_name(&iot[id], &mix);
-#else
- mixername = uaudio_feature_name(&iot[id], &mix);
-#endif
- switch (ctl) {
- case MUTE_CONTROL:
- mix.type = MIX_ON_OFF;
-#if defined(__FreeBSD__)
- mix.ctl = SOUND_MIXER_NRDEVICES;
-#else
- mix.ctlunit = "";
- snprintf(mix.ctlname, sizeof(mix.ctlname),
- "%s.%s", mixername, AudioNmute);
-#endif
- break;
- case VOLUME_CONTROL:
- mix.type = MIX_SIGNED_16;
-#if defined(__FreeBSD__)
- mix.ctl = mixernumber;
-#else
- mix.ctlunit = AudioNvolume;
- strlcpy(mix.ctlname, mixername, sizeof(mix.ctlname));
-#endif
- break;
- case BASS_CONTROL:
- mix.type = MIX_SIGNED_8;
-#if defined(__FreeBSD__)
- mix.ctl = SOUND_MIXER_BASS;
-#else
- mix.ctlunit = AudioNbass;
- snprintf(mix.ctlname, sizeof(mix.ctlname),
- "%s.%s", mixername, AudioNbass);
-#endif
- break;
- case MID_CONTROL:
- mix.type = MIX_SIGNED_8;
-#if defined(__FreeBSD__)
- mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
-#else
- mix.ctlunit = AudioNmid;
- snprintf(mix.ctlname, sizeof(mix.ctlname),
- "%s.%s", mixername, AudioNmid);
-#endif
- break;
- case TREBLE_CONTROL:
- mix.type = MIX_SIGNED_8;
-#if defined(__FreeBSD__)
- mix.ctl = SOUND_MIXER_TREBLE;
-#else
- mix.ctlunit = AudioNtreble;
- snprintf(mix.ctlname, sizeof(mix.ctlname),
- "%s.%s", mixername, AudioNtreble);
-#endif
- break;
- case GRAPHIC_EQUALIZER_CONTROL:
- continue; /* XXX don't add anything */
- break;
- case AGC_CONTROL:
- mix.type = MIX_ON_OFF;
-#if defined(__FreeBSD__)
- mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
-#else
- mix.ctlunit = "";
- snprintf(mix.ctlname, sizeof(mix.ctlname), "%s.%s",
- mixername, AudioNagc);
-#endif
- break;
- case DELAY_CONTROL:
- mix.type = MIX_UNSIGNED_16;
-#if defined(__FreeBSD__)
- mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
-#else
- mix.ctlunit = "4 ms";
- snprintf(mix.ctlname, sizeof(mix.ctlname),
- "%s.%s", mixername, AudioNdelay);
-#endif
- break;
- case BASS_BOOST_CONTROL:
- mix.type = MIX_ON_OFF;
-#if defined(__FreeBSD__)
- mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
-#else
- mix.ctlunit = "";
- snprintf(mix.ctlname, sizeof(mix.ctlname),
- "%s.%s", mixername, AudioNbassboost);
-#endif
- break;
- case LOUDNESS_CONTROL:
- mix.type = MIX_ON_OFF;
-#if defined(__FreeBSD__)
- mix.ctl = SOUND_MIXER_LOUD; /* Is this correct ? */
-#else
- mix.ctlunit = "";
- snprintf(mix.ctlname, sizeof(mix.ctlname),
- "%s.%s", mixername, AudioNloudness);
-#endif
- break;
- }
- uaudio_mixer_add_ctl(sc, &mix);
- }
-}
-
-static void
-uaudio_add_processing_updown(struct uaudio_softc *sc,
- const struct io_terminal *iot, int id)
-{
- const struct usb_audio_processing_unit *d;
- const struct usb_audio_processing_unit_1 *d1;
- const struct usb_audio_processing_unit_updown *ud;
- struct mixerctl mix;
- int i;
-
- d = iot[id].d.pu;
- d1 = (const struct usb_audio_processing_unit_1 *)
- &d->baSourceId[d->bNrInPins];
- ud = (const struct usb_audio_processing_unit_updown *)
- &d1->bmControls[d1->bControlSize];
- DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n",
- d->bUnitId, ud->bNrModes));
-
- if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
- DPRINTF(("uaudio_add_processing_updown: no mode select\n"));
- return;
- }
-
- mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
- mix.nchan = 1;
- mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
- uaudio_determine_class(&iot[id], &mix);
- mix.type = MIX_ON_OFF; /* XXX */
-#if !defined(__FreeBSD__)
- mix.ctlunit = "";
- snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitId);
-#endif
-
- for (i = 0; i < ud->bNrModes; i++) {
- DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n",
- i, UGETW(ud->waModes[i])));
- /* XXX */
- }
- uaudio_mixer_add_ctl(sc, &mix);
-}
-
-static void
-uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
-{
- const struct usb_audio_processing_unit *d;
- const struct usb_audio_processing_unit_1 *d1;
- int ptype;
- struct mixerctl mix;
-
- d = iot[id].d.pu;
- d1 = (const struct usb_audio_processing_unit_1 *)
- &d->baSourceId[d->bNrInPins];
- ptype = UGETW(d->wProcessType);
- DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d "
- "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins));
-
- if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
- mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
- mix.nchan = 1;
- mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
- uaudio_determine_class(&iot[id], &mix);
- mix.type = MIX_ON_OFF;
-#if !defined(__FreeBSD__)
- mix.ctlunit = "";
- snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d.%d-enable",
- d->bUnitId, ptype);
-#endif
- uaudio_mixer_add_ctl(sc, &mix);
- }
-
- switch(ptype) {
- case UPDOWNMIX_PROCESS:
- uaudio_add_processing_updown(sc, iot, id);
- break;
- case DOLBY_PROLOGIC_PROCESS:
- case P3D_STEREO_EXTENDER_PROCESS:
- case REVERBATION_PROCESS:
- case CHORUS_PROCESS:
- case DYN_RANGE_COMP_PROCESS:
- default:
-#ifdef USB_DEBUG
- printf("uaudio_add_processing: unit %d, type=%d not impl.\n",
- d->bUnitId, ptype);
-#endif
- break;
- }
-}
-
-static void
-uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
-{
- const struct usb_audio_extension_unit *d;
- const struct usb_audio_extension_unit_1 *d1;
- struct mixerctl mix;
-
- d = iot[id].d.eu;
- d1 = (const struct usb_audio_extension_unit_1 *)
- &d->baSourceId[d->bNrInPins];
- DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
- d->bUnitId, d->bNrInPins));
-
- if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU)
- return;
-
- if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
- mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
- mix.nchan = 1;
- mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
- uaudio_determine_class(&iot[id], &mix);
- mix.type = MIX_ON_OFF;
-#if !defined(__FreeBSD__)
- mix.ctlunit = "";
- snprintf(mix.ctlname, sizeof(mix.ctlname), "ext%d-enable",
- d->bUnitId);
-#endif
- uaudio_mixer_add_ctl(sc, &mix);
- }
-}
-
-static struct terminal_list*
-uaudio_merge_terminal_list(const struct io_terminal *iot)
-{
- struct terminal_list *tml;
- uint16_t *ptm;
- int i, len;
-
- len = 0;
- if (iot->inputs == NULL)
- return NULL;
- for (i = 0; i < iot->inputs_size; i++) {
- if (iot->inputs[i] != NULL)
- len += iot->inputs[i]->size;
- }
- tml = malloc(TERMINAL_LIST_SIZE(len), M_TEMP, M_NOWAIT);
- if (tml == NULL) {
- printf("uaudio_merge_terminal_list: no memory\n");
- return NULL;
- }
- tml->size = 0;
- ptm = tml->terminals;
- for (i = 0; i < iot->inputs_size; i++) {
- if (iot->inputs[i] == NULL)
- continue;
- if (iot->inputs[i]->size > len)
- break;
- memcpy(ptm, iot->inputs[i]->terminals,
- iot->inputs[i]->size * sizeof(uint16_t));
- tml->size += iot->inputs[i]->size;
- ptm += iot->inputs[i]->size;
- len -= iot->inputs[i]->size;
- }
- return tml;
-}
-
-static struct terminal_list *
-uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id)
-{
- struct terminal_list *tml;
- struct io_terminal *it;
- int src_id, i;
-
- it = &iot[id];
- if (it->output != NULL) {
- /* already has outtype? */
- for (i = 0; i < it->output->size; i++)
- if (it->output->terminals[i] == outtype)
- return uaudio_merge_terminal_list(it);
- tml = malloc(TERMINAL_LIST_SIZE(it->output->size + 1),
- M_TEMP, M_NOWAIT);
- if (tml == NULL) {
- printf("uaudio_io_terminaltype: no memory\n");
- return uaudio_merge_terminal_list(it);
- }
- memcpy(tml, it->output, TERMINAL_LIST_SIZE(it->output->size));
- tml->terminals[it->output->size] = outtype;
- tml->size++;
- free(it->output, M_TEMP);
- it->output = tml;
- if (it->inputs != NULL) {
- for (i = 0; i < it->inputs_size; i++)
- if (it->inputs[i] != NULL)
- free(it->inputs[i], M_TEMP);
- free(it->inputs, M_TEMP);
- }
- it->inputs_size = 0;
- it->inputs = NULL;
- } else { /* end `iot[id] != NULL' */
- it->inputs_size = 0;
- it->inputs = NULL;
- it->output = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
- if (it->output == NULL) {
- printf("uaudio_io_terminaltype: no memory\n");
- return NULL;
- }
- it->output->terminals[0] = outtype;
- it->output->size = 1;
- it->direct = FALSE;
- }
-
- switch (it->d.desc->bDescriptorSubtype) {
- case UDESCSUB_AC_INPUT:
- it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
- if (it->inputs == NULL) {
- printf("uaudio_io_terminaltype: no memory\n");
- return NULL;
- }
- tml = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
- if (tml == NULL) {
- printf("uaudio_io_terminaltype: no memory\n");
- free(it->inputs, M_TEMP);
- it->inputs = NULL;
- return NULL;
- }
- it->inputs[0] = tml;
- tml->terminals[0] = UGETW(it->d.it->wTerminalType);
- tml->size = 1;
- it->inputs_size = 1;
- return uaudio_merge_terminal_list(it);
- case UDESCSUB_AC_FEATURE:
- src_id = it->d.fu->bSourceId;
- it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
- if (it->inputs == NULL) {
- printf("uaudio_io_terminaltype: no memory\n");
- return uaudio_io_terminaltype(outtype, iot, src_id);
- }
- it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
- it->inputs_size = 1;
- return uaudio_merge_terminal_list(it);
- case UDESCSUB_AC_OUTPUT:
- it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
- if (it->inputs == NULL) {
- printf("uaudio_io_terminaltype: no memory\n");
- return NULL;
- }
- src_id = it->d.ot->bSourceId;
- it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
- it->inputs_size = 1;
- iot[src_id].direct = TRUE;
- return NULL;
- case UDESCSUB_AC_MIXER:
- it->inputs_size = 0;
- it->inputs = malloc(sizeof(struct terminal_list *)
- * it->d.mu->bNrInPins, M_TEMP, M_NOWAIT);
- if (it->inputs == NULL) {
- printf("uaudio_io_terminaltype: no memory\n");
- return NULL;
- }
- for (i = 0; i < it->d.mu->bNrInPins; i++) {
- src_id = it->d.mu->baSourceId[i];
- it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
- src_id);
- it->inputs_size++;
- }
- return uaudio_merge_terminal_list(it);
- case UDESCSUB_AC_SELECTOR:
- it->inputs_size = 0;
- it->inputs = malloc(sizeof(struct terminal_list *)
- * it->d.su->bNrInPins, M_TEMP, M_NOWAIT);
- if (it->inputs == NULL) {
- printf("uaudio_io_terminaltype: no memory\n");
- return NULL;
- }
- for (i = 0; i < it->d.su->bNrInPins; i++) {
- src_id = it->d.su->baSourceId[i];
- it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
- src_id);
- it->inputs_size++;
- }
- return uaudio_merge_terminal_list(it);
- case UDESCSUB_AC_PROCESSING:
- it->inputs_size = 0;
- it->inputs = malloc(sizeof(struct terminal_list *)
- * it->d.pu->bNrInPins, M_TEMP, M_NOWAIT);
- if (it->inputs == NULL) {
- printf("uaudio_io_terminaltype: no memory\n");
- return NULL;
- }
- for (i = 0; i < it->d.pu->bNrInPins; i++) {
- src_id = it->d.pu->baSourceId[i];
- it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
- src_id);
- it->inputs_size++;
- }
- return uaudio_merge_terminal_list(it);
- case UDESCSUB_AC_EXTENSION:
- it->inputs_size = 0;
- it->inputs = malloc(sizeof(struct terminal_list *)
- * it->d.eu->bNrInPins, M_TEMP, M_NOWAIT);
- if (it->inputs == NULL) {
- printf("uaudio_io_terminaltype: no memory\n");
- return NULL;
- }
- for (i = 0; i < it->d.eu->bNrInPins; i++) {
- src_id = it->d.eu->baSourceId[i];
- it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
- src_id);
- it->inputs_size++;
- }
- return uaudio_merge_terminal_list(it);
- case UDESCSUB_AC_HEADER:
- default:
- return NULL;
- }
-}
-
-static usbd_status
-uaudio_identify(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
-{
- usbd_status err;
-
- err = uaudio_identify_ac(sc, cdesc);
- if (err)
- return err;
- return uaudio_identify_as(sc, cdesc);
-}
-
-static void
-uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai)
-{
- size_t len;
- struct as_info *nai;
-
- len = sizeof(*ai) * (sc->sc_nalts + 1);
- nai = malloc(len, M_USBDEV, M_NOWAIT);
- if (nai == NULL) {
- printf("uaudio_add_alt: no memory\n");
- return;
- }
- /* Copy old data, if there was any */
- if (sc->sc_nalts != 0) {
- memcpy(nai, sc->sc_alts, sizeof(*ai) * (sc->sc_nalts));
- free(sc->sc_alts, M_USBDEV);
- }
- sc->sc_alts = nai;
- DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",
- ai->alt, ai->encoding));
- sc->sc_alts[sc->sc_nalts++] = *ai;
-}
-
-static usbd_status
-uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
- int size, const usb_interface_descriptor_t *id)
-#define offs (*offsp)
-{
- const struct usb_audio_streaming_interface_descriptor *asid;
- const struct usb_audio_streaming_type1_descriptor *asf1d;
- const usb_endpoint_descriptor_audio_t *ed;
- const usb_endpoint_descriptor_audio_t *epdesc1;
- const struct usb_audio_streaming_endpoint_descriptor *sed;
- int format, chan, prec, enc;
- int dir, type, sync;
- struct as_info ai;
- const char *format_str;
-
- asid = (const void *)(buf + offs);
-
- if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
- asid->bDescriptorSubtype != AS_GENERAL)
- return USBD_INVAL;
- DPRINTF(("uaudio_process_as: asid: bTerminakLink=%d wFormatTag=%d\n",
- asid->bTerminalLink, UGETW(asid->wFormatTag)));
- offs += asid->bLength;
- if (offs > size)
- return USBD_INVAL;
-
- asf1d = (const void *)(buf + offs);
- if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
- asf1d->bDescriptorSubtype != FORMAT_TYPE)
- return USBD_INVAL;
- offs += asf1d->bLength;
- if (offs > size)
- return USBD_INVAL;
-
- if (asf1d->bFormatType != FORMAT_TYPE_I) {
- printf("%s: ignored setting with type %d format\n",
- device_get_nameunit(sc->sc_dev), UGETW(asid->wFormatTag));
- return USBD_NORMAL_COMPLETION;
- }
-
- ed = (const void *)(buf + offs);
- if (ed->bDescriptorType != UDESC_ENDPOINT)
- return USBD_INVAL;
- DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d "
- "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
- "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
- ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
- ed->bmAttributes, UGETW(ed->wMaxPacketSize),
- ed->bInterval, ed->bRefresh, ed->bSynchAddress));
- offs += ed->bLength;
- if (offs > size)
- return USBD_INVAL;
- if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
- return USBD_INVAL;
-
- dir = UE_GET_DIR(ed->bEndpointAddress);
- type = UE_GET_ISO_TYPE(ed->bmAttributes);
- if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) &&
- dir == UE_DIR_IN && type == UE_ISO_ADAPT)
- type = UE_ISO_ASYNC;
-
- /* We can't handle endpoints that need a sync pipe yet. */
- sync = FALSE;
- if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
- sync = TRUE;
-#ifndef UAUDIO_MULTIPLE_ENDPOINTS
- printf("%s: ignored input endpoint of type adaptive\n",
- device_get_nameunit(sc->sc_dev));
- return USBD_NORMAL_COMPLETION;
-#endif
- }
- if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
- sync = TRUE;
-#ifndef UAUDIO_MULTIPLE_ENDPOINTS
- printf("%s: ignored output endpoint of type async\n",
- device_get_nameunit(sc->sc_dev));
- return USBD_NORMAL_COMPLETION;
-#endif
- }
-
- sed = (const void *)(buf + offs);
- if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
- sed->bDescriptorSubtype != AS_GENERAL)
- return USBD_INVAL;
- DPRINTF((" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength));
- offs += sed->bLength;
- if (offs > size)
- return USBD_INVAL;
-
-#ifdef UAUDIO_MULTIPLE_ENDPOINTS
- if (sync && id->bNumEndpoints <= 1) {
- printf("%s: a sync-pipe endpoint but no other endpoint\n",
- device_get_nameunit(sc->sc_dev));
- return USBD_INVAL;
- }
-#endif
- if (!sync && id->bNumEndpoints > 1) {
- printf("%s: non sync-pipe endpoint but multiple endpoints\n",
- device_get_nameunit(sc->sc_dev));
- return USBD_INVAL;
- }
- epdesc1 = NULL;
- if (id->bNumEndpoints > 1) {
- epdesc1 = (const void*)(buf + offs);
- if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
- return USBD_INVAL;
- DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d "
- "bDescriptorType=%d bEndpointAddress=%d "
- "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d "
- "bRefresh=%d bSynchAddress=%d\n",
- epdesc1->bLength, epdesc1->bDescriptorType,
- epdesc1->bEndpointAddress, epdesc1->bmAttributes,
- UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
- epdesc1->bRefresh, epdesc1->bSynchAddress));
- offs += epdesc1->bLength;
- if (offs > size)
- return USBD_INVAL;
- if (epdesc1->bSynchAddress != 0) {
- printf("%s: invalid endpoint: bSynchAddress=0\n",
- device_get_nameunit(sc->sc_dev));
- return USBD_INVAL;
- }
- if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) {
- printf("%s: invalid endpoint: bmAttributes=0x%x\n",
- device_get_nameunit(sc->sc_dev), epdesc1->bmAttributes);
- return USBD_INVAL;
- }
- if (epdesc1->bEndpointAddress != ed->bSynchAddress) {
- printf("%s: invalid endpoint addresses: "
- "ep[0]->bSynchAddress=0x%x "
- "ep[1]->bEndpointAddress=0x%x\n",
- device_get_nameunit(sc->sc_dev), ed->bSynchAddress,
- epdesc1->bEndpointAddress);
- return USBD_INVAL;
- }
- /* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
- }
-
- format = UGETW(asid->wFormatTag);
- chan = asf1d->bNrChannels;
- prec = asf1d->bBitResolution;
- if (prec != 8 && prec != 16 && prec != 24 && prec != 32) {
- printf("%s: ignored setting with precision %d\n",
- device_get_nameunit(sc->sc_dev), prec);
- return USBD_NORMAL_COMPLETION;
- }
- switch (format) {
- case UA_FMT_PCM:
- if (prec == 8) {
- sc->sc_altflags |= HAS_8;
- } else if (prec == 16) {
- sc->sc_altflags |= HAS_16;
- } else if (prec == 24) {
- sc->sc_altflags |= HAS_24;
- } else if (prec == 32) {
- sc->sc_altflags |= HAS_32;
- }
- enc = AUDIO_ENCODING_SLINEAR_LE;
- format_str = "pcm";
- break;
- case UA_FMT_PCM8:
- enc = AUDIO_ENCODING_ULINEAR_LE;
- sc->sc_altflags |= HAS_8U;
- format_str = "pcm8";
- break;
- case UA_FMT_ALAW:
- enc = AUDIO_ENCODING_ALAW;
- sc->sc_altflags |= HAS_ALAW;
- format_str = "alaw";
- break;
- case UA_FMT_MULAW:
- enc = AUDIO_ENCODING_ULAW;
- sc->sc_altflags |= HAS_MULAW;
- format_str = "mulaw";
- break;
- case UA_FMT_IEEE_FLOAT:
- default:
- printf("%s: ignored setting with format %d\n",
- device_get_nameunit(sc->sc_dev), format);
- return USBD_NORMAL_COMPLETION;
- }
-#ifdef USB_DEBUG
- printf("%s: %s: %dch, %d/%dbit, %s,", device_get_nameunit(sc->sc_dev),
- dir == UE_DIR_IN ? "recording" : "playback",
- chan, prec, asf1d->bSubFrameSize * 8, format_str);
- if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
- printf(" %d-%dHz\n", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
- } else {
- int r;
- printf(" %d", UA_GETSAMP(asf1d, 0));
- for (r = 1; r < asf1d->bSamFreqType; r++)
- printf(",%d", UA_GETSAMP(asf1d, r));
- printf("Hz\n");
- }
-#endif
-#if defined(__FreeBSD__)
- if (sc->uaudio_sndstat_flag != 0) {
- sbuf_printf(&(sc->uaudio_sndstat), "\n\t");
- sbuf_printf(&(sc->uaudio_sndstat),
- "mode %d:(%s) %dch, %d/%dbit, %s,",
- id->bAlternateSetting,
- dir == UE_DIR_IN ? "input" : "output",
- chan, prec, asf1d->bSubFrameSize * 8, format_str);
- if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
- sbuf_printf(&(sc->uaudio_sndstat), " %d-%dHz",
- UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
- } else {
- int r;
- sbuf_printf(&(sc->uaudio_sndstat),
- " %d", UA_GETSAMP(asf1d, 0));
- for (r = 1; r < asf1d->bSamFreqType; r++)
- sbuf_printf(&(sc->uaudio_sndstat),
- ",%d", UA_GETSAMP(asf1d, r));
- sbuf_printf(&(sc->uaudio_sndstat), "Hz");
- }
- }
-#endif
- ai.alt = id->bAlternateSetting;
- ai.encoding = enc;
- ai.attributes = sed->bmAttributes;
- ai.idesc = id;
- ai.edesc = ed;
- ai.edesc1 = epdesc1;
- ai.asf1desc = asf1d;
- ai.sc_busy = 0;
- ai.ifaceh = NULL;
- uaudio_add_alt(sc, &ai);
-#ifdef USB_DEBUG
- if (ai.attributes & UA_SED_FREQ_CONTROL)
- DPRINTFN(1, ("uaudio_process_as: FREQ_CONTROL\n"));
- if (ai.attributes & UA_SED_PITCH_CONTROL)
- DPRINTFN(1, ("uaudio_process_as: PITCH_CONTROL\n"));
-#endif
- sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD;
-
- return USBD_NORMAL_COMPLETION;
-}
-#undef offs
-
-static usbd_status
-uaudio_identify_as(struct uaudio_softc *sc,
- const usb_config_descriptor_t *cdesc)
-{
- const usb_interface_descriptor_t *id;
- const char *buf;
- int size, offs;
-
- size = UGETW(cdesc->wTotalLength);
- buf = (const char *)cdesc;
-
- /* Locate the AudioStreaming interface descriptor. */
- offs = 0;
- id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM);
- if (id == NULL)
- return USBD_INVAL;
-
-#if defined(__FreeBSD__)
- sc->uaudio_sndstat_flag = 0;
- if (sbuf_new(&(sc->uaudio_sndstat), NULL, 4096, SBUF_AUTOEXTEND) != NULL)
- sc->uaudio_sndstat_flag = 1;
-#endif
- /* Loop through all the alternate settings. */
- while (offs <= size) {
- DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n",
- id->bInterfaceNumber, offs));
- switch (id->bNumEndpoints) {
- case 0:
- DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
- id->bAlternateSetting));
- sc->sc_nullalt = id->bAlternateSetting;
- break;
- case 1:
-#ifdef UAUDIO_MULTIPLE_ENDPOINTS
- case 2:
-#endif
- uaudio_process_as(sc, buf, &offs, size, id);
- break;
- default:
- printf("%s: ignored audio interface with %d "
- "endpoints\n",
- device_get_nameunit(sc->sc_dev), id->bNumEndpoints);
- break;
- }
- id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM);
- if (id == NULL)
- break;
- }
-#if defined(__FreeBSD__)
- sbuf_finish(&(sc->uaudio_sndstat));
-#endif
- if (offs > size)
- return USBD_INVAL;
- DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts));
-
- if (sc->sc_mode == 0) {
- printf("%s: no usable endpoint found\n",
- device_get_nameunit(sc->sc_dev));
- return USBD_INVAL;
- }
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
-{
- struct io_terminal* iot;
- const usb_interface_descriptor_t *id;
- const struct usb_audio_control_descriptor *acdp;
- const usb_descriptor_t *dp;
- const struct usb_audio_output_terminal *pot;
- struct terminal_list *tml;
- const char *buf, *ibuf, *ibufend;
- int size, offs, aclen, ndps, i, j;
-
- size = UGETW(cdesc->wTotalLength);
- buf = (const char *)cdesc;
-
- /* Locate the AudioControl interface descriptor. */
- offs = 0;
- id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL);
- if (id == NULL)
- return USBD_INVAL;
- if (offs + sizeof *acdp > size)
- return USBD_INVAL;
- sc->sc_ac_iface = id->bInterfaceNumber;
- DPRINTFN(2,("uaudio_identify_ac: AC interface is %d\n", sc->sc_ac_iface));
-
- /* A class-specific AC interface header should follow. */
- ibuf = buf + offs;
- acdp = (const struct usb_audio_control_descriptor *)ibuf;
- if (acdp->bDescriptorType != UDESC_CS_INTERFACE ||
- acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)
- return USBD_INVAL;
- aclen = UGETW(acdp->wTotalLength);
- if (offs + aclen > size)
- return USBD_INVAL;
-
- if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
- UGETW(acdp->bcdADC) != UAUDIO_VERSION)
- return USBD_INVAL;
-
- sc->sc_audio_rev = UGETW(acdp->bcdADC);
- DPRINTFN(2,("uaudio_identify_ac: found AC header, vers=%03x, len=%d\n",
- sc->sc_audio_rev, aclen));
-
- sc->sc_nullalt = -1;
-
- /* Scan through all the AC specific descriptors */
- ibufend = ibuf + aclen;
- dp = (const usb_descriptor_t *)ibuf;
- ndps = 0;
- iot = malloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT | M_ZERO);
- if (iot == NULL) {
- printf("%s: no memory\n", __func__);
- return USBD_NOMEM;
- }
- for (;;) {
- ibuf += dp->bLength;
- if (ibuf >= ibufend)
- break;
- dp = (const usb_descriptor_t *)ibuf;
- if (ibuf + dp->bLength > ibufend) {
- free(iot, M_TEMP);
- return USBD_INVAL;
- }
- if (dp->bDescriptorType != UDESC_CS_INTERFACE) {
- printf("uaudio_identify_ac: skip desc type=0x%02x\n",
- dp->bDescriptorType);
- continue;
- }
- i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId;
- iot[i].d.desc = dp;
- if (i > ndps)
- ndps = i;
- }
- ndps++;
-
- /* construct io_terminal */
- for (i = 0; i < ndps; i++) {
- dp = iot[i].d.desc;
- if (dp == NULL)
- continue;
- if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT)
- continue;
- pot = iot[i].d.ot;
- tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i);
- if (tml != NULL)
- free(tml, M_TEMP);
- }
-
-#ifdef USB_DEBUG
- for (i = 0; i < 256; i++) {
- struct usb_audio_cluster cluster;
-
- if (iot[i].d.desc == NULL)
- continue;
- printf("id %d:\t", i);
- switch (iot[i].d.desc->bDescriptorSubtype) {
- case UDESCSUB_AC_INPUT:
- printf("AC_INPUT type=%s\n", uaudio_get_terminal_name
- (UGETW(iot[i].d.it->wTerminalType)));
- printf("\t");
- cluster = uaudio_get_cluster(i, iot);
- uaudio_dump_cluster(&cluster);
- printf("\n");
- break;
- case UDESCSUB_AC_OUTPUT:
- printf("AC_OUTPUT type=%s ", uaudio_get_terminal_name
- (UGETW(iot[i].d.ot->wTerminalType)));
- printf("src=%d\n", iot[i].d.ot->bSourceId);
- break;
- case UDESCSUB_AC_MIXER:
- printf("AC_MIXER src=");
- for (j = 0; j < iot[i].d.mu->bNrInPins; j++)
- printf("%d ", iot[i].d.mu->baSourceId[j]);
- printf("\n\t");
- cluster = uaudio_get_cluster(i, iot);
- uaudio_dump_cluster(&cluster);
- printf("\n");
- break;
- case UDESCSUB_AC_SELECTOR:
- printf("AC_SELECTOR src=");
- for (j = 0; j < iot[i].d.su->bNrInPins; j++)
- printf("%d ", iot[i].d.su->baSourceId[j]);
- printf("\n");
- break;
- case UDESCSUB_AC_FEATURE:
- printf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId);
- break;
- case UDESCSUB_AC_PROCESSING:
- printf("AC_PROCESSING src=");
- for (j = 0; j < iot[i].d.pu->bNrInPins; j++)
- printf("%d ", iot[i].d.pu->baSourceId[j]);
- printf("\n\t");
- cluster = uaudio_get_cluster(i, iot);
- uaudio_dump_cluster(&cluster);
- printf("\n");
- break;
- case UDESCSUB_AC_EXTENSION:
- printf("AC_EXTENSION src=");
- for (j = 0; j < iot[i].d.eu->bNrInPins; j++)
- printf("%d ", iot[i].d.eu->baSourceId[j]);
- printf("\n\t");
- cluster = uaudio_get_cluster(i, iot);
- uaudio_dump_cluster(&cluster);
- printf("\n");
- break;
- default:
- printf("unknown audio control (subtype=%d)\n",
- iot[i].d.desc->bDescriptorSubtype);
- }
- for (j = 0; j < iot[i].inputs_size; j++) {
- int k;
- printf("\tinput%d: ", j);
- tml = iot[i].inputs[j];
- if (tml == NULL) {
- printf("NULL\n");
- continue;
- }
- for (k = 0; k < tml->size; k++)
- printf("%s ", uaudio_get_terminal_name
- (tml->terminals[k]));
- printf("\n");
- }
- printf("\toutput: ");
- tml = iot[i].output;
- for (j = 0; j < tml->size; j++)
- printf("%s ", uaudio_get_terminal_name(tml->terminals[j]));
- printf("\n");
- }
-#endif
-
- for (i = 0; i < ndps; i++) {
- dp = iot[i].d.desc;
- if (dp == NULL)
- continue;
- DPRINTF(("uaudio_identify_ac: id=%d subtype=%d\n",
- i, dp->bDescriptorSubtype));
- switch (dp->bDescriptorSubtype) {
- case UDESCSUB_AC_HEADER:
- printf("uaudio_identify_ac: unexpected AC header\n");
- break;
- case UDESCSUB_AC_INPUT:
- uaudio_add_input(sc, iot, i);
- break;
- case UDESCSUB_AC_OUTPUT:
- uaudio_add_output(sc, iot, i);
- break;
- case UDESCSUB_AC_MIXER:
- uaudio_add_mixer(sc, iot, i);
- break;
- case UDESCSUB_AC_SELECTOR:
- uaudio_add_selector(sc, iot, i);
- break;
- case UDESCSUB_AC_FEATURE:
- uaudio_add_feature(sc, iot, i);
- break;
- case UDESCSUB_AC_PROCESSING:
- uaudio_add_processing(sc, iot, i);
- break;
- case UDESCSUB_AC_EXTENSION:
- uaudio_add_extension(sc, iot, i);
- break;
- default:
- printf("uaudio_identify_ac: bad AC desc subtype=0x%02x\n",
- dp->bDescriptorSubtype);
- break;
- }
- }
-
- /* delete io_terminal */
- for (i = 0; i < 256; i++) {
- if (iot[i].d.desc == NULL)
- continue;
- if (iot[i].inputs != NULL) {
- for (j = 0; j < iot[i].inputs_size; j++) {
- if (iot[i].inputs[j] != NULL)
- free(iot[i].inputs[j], M_TEMP);
- }
- free(iot[i].inputs, M_TEMP);
- }
- if (iot[i].output != NULL)
- free(iot[i].output, M_TEMP);
- iot[i].d.desc = NULL;
- }
- free(iot, M_TEMP);
-
- return USBD_NORMAL_COMPLETION;
-}
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static int
-uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi)
-{
- struct uaudio_softc *sc;
- struct mixerctl *mc;
- int n, nctls, i;
-
- sc = addr;
- DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index));
- if (sc->sc_dying)
- return EIO;
-
- n = mi->index;
- nctls = sc->sc_nctls;
-
- switch (n) {
- case UAC_OUTPUT:
- mi->type = AUDIO_MIXER_CLASS;
- mi->mixer_class = UAC_OUTPUT;
- mi->next = mi->prev = AUDIO_MIXER_LAST;
- strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name));
- return 0;
- case UAC_INPUT:
- mi->type = AUDIO_MIXER_CLASS;
- mi->mixer_class = UAC_INPUT;
- mi->next = mi->prev = AUDIO_MIXER_LAST;
- strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name));
- return 0;
- case UAC_EQUAL:
- mi->type = AUDIO_MIXER_CLASS;
- mi->mixer_class = UAC_EQUAL;
- mi->next = mi->prev = AUDIO_MIXER_LAST;
- strlcpy(mi->label.name, AudioCequalization,
- sizeof(mi->label.name));
- return 0;
- case UAC_RECORD:
- mi->type = AUDIO_MIXER_CLASS;
- mi->mixer_class = UAC_RECORD;
- mi->next = mi->prev = AUDIO_MIXER_LAST;
- strlcpy(mi->label.name, AudioCrecord, sizeof(mi->label.name));
- return 0;
- default:
- break;
- }
-
- n -= UAC_NCLASSES;
- if (n < 0 || n >= nctls)
- return ENXIO;
-
- mc = &sc->sc_ctls[n];
- strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name));
- mi->mixer_class = mc->class;
- mi->next = mi->prev = AUDIO_MIXER_LAST; /* XXX */
- switch (mc->type) {
- case MIX_ON_OFF:
- mi->type = AUDIO_MIXER_ENUM;
- mi->un.e.num_mem = 2;
- strlcpy(mi->un.e.member[0].label.name, AudioNoff,
- sizeof(mi->un.e.member[0].label.name));
- mi->un.e.member[0].ord = 0;
- strlcpy(mi->un.e.member[1].label.name, AudioNon,
- sizeof(mi->un.e.member[1].label.name));
- mi->un.e.member[1].ord = 1;
- break;
- case MIX_SELECTOR:
- mi->type = AUDIO_MIXER_ENUM;
- mi->un.e.num_mem = mc->maxval - mc->minval + 1;
- for (i = 0; i <= mc->maxval - mc->minval; i++) {
- snprintf(mi->un.e.member[i].label.name,
- sizeof(mi->un.e.member[i].label.name),
- "%d", i + mc->minval);
- mi->un.e.member[i].ord = i + mc->minval;
- }
- break;
- default:
- mi->type = AUDIO_MIXER_VALUE;
- strlcpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN);
- mi->un.v.num_channels = mc->nchan;
- mi->un.v.delta = mc->delta;
- break;
- }
- return 0;
-}
-
-static int
-uaudio_open(void *addr, int flags)
-{
- struct uaudio_softc *sc;
-
- sc = addr;
- DPRINTF(("uaudio_open: sc=%p\n", sc));
- if (sc->sc_dying)
- return EIO;
-
- if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY))
- return EACCES;
- if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD))
- return EACCES;
-
- return 0;
-}
-
-/*
- * Close function is called at splaudio().
- */
-static void
-uaudio_close(void *addr)
-{
-}
-
-static int
-uaudio_drain(void *addr)
-{
- struct uaudio_softc *sc;
-
- sc = addr;
- usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
-
- return 0;
-}
-
-static int
-uaudio_halt_out_dma(void *addr)
-{
- struct uaudio_softc *sc;
-
- sc = addr;
- if (sc->sc_dying)
- return EIO;
-
- DPRINTF(("uaudio_halt_out_dma: enter\n"));
- if (sc->sc_playchan.pipe != NULL) {
- uaudio_chan_close(sc, &sc->sc_playchan);
- sc->sc_playchan.pipe = NULL;
- uaudio_chan_free_buffers(sc, &sc->sc_playchan);
- sc->sc_playchan.intr = NULL;
- }
- return 0;
-}
-
-static int
-uaudio_halt_in_dma(void *addr)
-{
- struct uaudio_softc *sc;
-
- DPRINTF(("uaudio_halt_in_dma: enter\n"));
- sc = addr;
- if (sc->sc_recchan.pipe != NULL) {
- uaudio_chan_close(sc, &sc->sc_recchan);
- sc->sc_recchan.pipe = NULL;
- uaudio_chan_free_buffers(sc, &sc->sc_recchan);
- sc->sc_recchan.intr = NULL;
- }
- return 0;
-}
-
-static int
-uaudio_getdev(void *addr, struct audio_device *retp)
-{
- struct uaudio_softc *sc;
-
- DPRINTF(("uaudio_mixer_getdev:\n"));
- sc = addr;
- if (sc->sc_dying)
- return EIO;
-
- *retp = uaudio_device;
- return 0;
-}
-
-/*
- * Make sure the block size is large enough to hold all outstanding transfers.
- */
-static int
-uaudio_round_blocksize(void *addr, int blk)
-{
- struct uaudio_softc *sc;
- int b;
-
- sc = addr;
- DPRINTF(("uaudio_round_blocksize: blk=%d mode=%s\n", blk,
- mode == AUMODE_PLAY ? "AUMODE_PLAY" : "AUMODE_RECORD"));
-
- /* chan.bytes_per_frame can be 0. */
- if (mode == AUMODE_PLAY || sc->sc_recchan.bytes_per_frame <= 0) {
- b = param->sample_rate * UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
-
- /*
- * This does not make accurate value in the case
- * of b % USB_FRAMES_PER_SECOND != 0
- */
- b /= USB_FRAMES_PER_SECOND;
-
- b *= param->precision / 8 * param->channels;
- } else {
- /*
- * use wMaxPacketSize in bytes_per_frame.
- * See uaudio_set_params() and uaudio_chan_init()
- */
- b = sc->sc_recchan.bytes_per_frame
- * UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
- }
-
- if (b <= 0)
- b = 1;
- blk = blk <= b ? b : blk / b * b;
-
-#ifdef DIAGNOSTIC
- if (blk <= 0) {
- printf("uaudio_round_blocksize: blk=%d\n", blk);
- blk = 512;
- }
-#endif
-
- DPRINTF(("uaudio_round_blocksize: resultant blk=%d\n", blk));
- return blk;
-}
-
-static int
-uaudio_get_props(void *addr)
-{
- return AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT;
-
-}
-#endif /* NetBSD or OpenBSD */
-
-static int
-uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue,
- int wIndex, int len)
-{
- usb_device_request_t req;
- uint8_t data[4];
- usbd_status err;
- int val;
-
-#if defined(__FreeBSD__)
- if (sc->sc_dying)
- return EIO;
-#endif
-
- if (wValue == -1)
- return 0;
-
- req.bmRequestType = type;
- req.bRequest = which;
- USETW(req.wValue, wValue);
- USETW(req.wIndex, wIndex);
- USETW(req.wLength, len);
- DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x "
- "wIndex=0x%04x len=%d\n",
- type, which, wValue, wIndex, len));
-#if defined(__FreeBSD__)
- if (sc->async != 0)
- err = usbd_do_request_async(sc->sc_udev, &req, data);
- else
-#endif
- err = usbd_do_request(sc->sc_udev, &req, data);
- if (err) {
- DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err)));
- return -1;
- }
- switch (len) {
- case 1:
- val = data[0];
- break;
- case 2:
- val = data[0] | (data[1] << 8);
- break;
- default:
- DPRINTF(("uaudio_get: bad length=%d\n", len));
- return -1;
- }
- DPRINTFN(2,("uaudio_get: val=%d\n", val));
- return val;
-}
-
-static void
-uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue,
- int wIndex, int len, int val)
-{
- usb_device_request_t req;
- uint8_t data[4];
- usbd_status err;
-
-#if defined(__FreeBSD__)
- if (sc->sc_dying)
- return;
-#endif
-
- if (wValue == -1)
- return;
-
- req.bmRequestType = type;
- req.bRequest = which;
- USETW(req.wValue, wValue);
- USETW(req.wIndex, wIndex);
- USETW(req.wLength, len);
- switch (len) {
- case 1:
- data[0] = val;
- break;
- case 2:
- data[0] = val;
- data[1] = val >> 8;
- break;
- default:
- return;
- }
- DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x "
- "wIndex=0x%04x len=%d, val=%d\n",
- type, which, wValue, wIndex, len, val & 0xffff));
-#if defined(__FreeBSD__)
- if (sc->async != 0)
- err = usbd_do_request_async(sc->sc_udev, &req, data);
- else
-#endif
- err = usbd_do_request(sc->sc_udev, &req, data);
-#ifdef USB_DEBUG
- if (err)
- DPRINTF(("uaudio_set: err=%d\n", err));
-#endif
-}
-
-static int
-uaudio_signext(int type, int val)
-{
- if (!MIX_UNSIGNED(type)) {
- if (MIX_SIZE(type) == 2)
- val = (int16_t)val;
- else
- val = (int8_t)val;
- }
- return val;
-}
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static int
-uaudio_value2bsd(struct mixerctl *mc, int val)
-{
- DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ",
- mc->type, val, mc->minval, mc->maxval));
- if (mc->type == MIX_ON_OFF) {
- val = (val != 0);
- } else if (mc->type == MIX_SELECTOR) {
- if (val < mc->minval || val > mc->maxval)
- val = mc->minval;
- } else
- val = ((uaudio_signext(mc->type, val) - mc->minval) * 255
- + mc->mul/2) / mc->mul;
- DPRINTFN(5, ("val'=%d\n", val));
- return val;
-}
-#endif
-
-int
-uaudio_bsd2value(struct mixerctl *mc, int val)
-{
- DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ",
- mc->type, val, mc->minval, mc->maxval));
- if (mc->type == MIX_ON_OFF) {
- val = (val != 0);
- } else if (mc->type == MIX_SELECTOR) {
- if (val < mc->minval || val > mc->maxval)
- val = mc->minval;
- } else
- val = (val + mc->delta/2) * mc->mul / 255 + mc->minval;
- DPRINTFN(5, ("val'=%d\n", val));
- return val;
-}
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static int
-uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc,
- int chan)
-{
- int val;
-
- DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan));
- val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan],
- mc->wIndex, MIX_SIZE(mc->type));
- return uaudio_value2bsd(mc, val);
-}
-#endif
-
-static void
-uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc,
- int chan, int val)
-{
- val = uaudio_bsd2value(mc, val);
- uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
- mc->wIndex, MIX_SIZE(mc->type), val);
-}
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static int
-uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp)
-{
- struct uaudio_softc *sc;
- struct mixerctl *mc;
- int i, n, vals[MIX_MAX_CHAN], val;
-
- DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev));
- sc = addr;
- if (sc->sc_dying)
- return EIO;
-
- n = cp->dev - UAC_NCLASSES;
- if (n < 0 || n >= sc->sc_nctls)
- return ENXIO;
- mc = &sc->sc_ctls[n];
-
- if (mc->type == MIX_ON_OFF) {
- if (cp->type != AUDIO_MIXER_ENUM)
- return EINVAL;
- cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
- } else if (mc->type == MIX_SELECTOR) {
- if (cp->type != AUDIO_MIXER_ENUM)
- return EINVAL;
- cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
- } else {
- if (cp->type != AUDIO_MIXER_VALUE)
- return (EINVAL);
- if (cp->un.value.num_channels != 1 &&
- cp->un.value.num_channels != mc->nchan)
- return EINVAL;
- for (i = 0; i < mc->nchan; i++)
- vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i);
- if (cp->un.value.num_channels == 1 && mc->nchan != 1) {
- for (val = 0, i = 0; i < mc->nchan; i++)
- val += vals[i];
- vals[0] = val / mc->nchan;
- }
- for (i = 0; i < cp->un.value.num_channels; i++)
- cp->un.value.level[i] = vals[i];
- }
-
- return 0;
-}
-
-static int
-uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp)
-{
- struct uaudio_softc *sc;
- struct mixerctl *mc;
- int i, n, vals[MIX_MAX_CHAN];
-
- DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev));
- sc = addr;
- if (sc->sc_dying)
- return EIO;
-
- n = cp->dev - UAC_NCLASSES;
- if (n < 0 || n >= sc->sc_nctls)
- return ENXIO;
- mc = &sc->sc_ctls[n];
-
- if (mc->type == MIX_ON_OFF) {
- if (cp->type != AUDIO_MIXER_ENUM)
- return EINVAL;
- uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
- } else if (mc->type == MIX_SELECTOR) {
- if (cp->type != AUDIO_MIXER_ENUM)
- return EINVAL;
- uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
- } else {
- if (cp->type != AUDIO_MIXER_VALUE)
- return EINVAL;
- if (cp->un.value.num_channels == 1)
- for (i = 0; i < mc->nchan; i++)
- vals[i] = cp->un.value.level[0];
- else if (cp->un.value.num_channels == mc->nchan)
- for (i = 0; i < mc->nchan; i++)
- vals[i] = cp->un.value.level[i];
- else
- return EINVAL;
- for (i = 0; i < mc->nchan; i++)
- uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]);
- }
- return 0;
-}
-
-static int
-uaudio_trigger_input(void *addr, void *start, void *end, int blksize,
- void (*intr)(void *), void *arg,
- struct audio_params *param)
-{
- struct uaudio_softc *sc;
- struct chan *ch;
- usbd_status err;
- int i, s;
-
- sc = addr;
- if (sc->sc_dying)
- return EIO;
-
- DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p "
- "blksize=%d\n", sc, start, end, blksize));
- ch = &sc->sc_recchan;
- uaudio_chan_set_param(ch, start, end, blksize);
- DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d "
- "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
- ch->fraction));
-
- err = uaudio_chan_alloc_buffers(sc, ch);
- if (err)
- return EIO;
-
- err = uaudio_chan_open(sc, ch);
- if (err) {
- uaudio_chan_free_buffers(sc, ch);
- return EIO;
- }
-
- ch->intr = intr;
- ch->arg = arg;
-
- s = splusb();
- for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
- uaudio_chan_rtransfer(ch);
- splx(s);
-
- return 0;
-}
-
-static int
-uaudio_trigger_output(void *addr, void *start, void *end, int blksize,
- void (*intr)(void *), void *arg,
- struct audio_params *param)
-{
- struct uaudio_softc *sc;
- struct chan *ch;
- usbd_status err;
- int i, s;
-
- sc = addr;
- if (sc->sc_dying)
- return EIO;
-
- DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p "
- "blksize=%d\n", sc, start, end, blksize));
- ch = &sc->sc_playchan;
- uaudio_chan_set_param(ch, start, end, blksize);
- DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d "
- "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
- ch->fraction));
-
- err = uaudio_chan_alloc_buffers(sc, ch);
- if (err)
- return EIO;
-
- err = uaudio_chan_open(sc, ch);
- if (err) {
- uaudio_chan_free_buffers(sc, ch);
- return EIO;
- }
-
- ch->intr = intr;
- ch->arg = arg;
-
- s = splusb();
- for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
- uaudio_chan_ptransfer(ch);
- splx(s);
-
- return 0;
-}
-#endif /* NetBSD or OpenBSD */
-
-/* Set up a pipe for a channel. */
-static usbd_status
-uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch)
-{
- struct as_info *as;
- int endpt;
-#if defined(__FreeBSD__)
- int locked;
-#endif
- usbd_status err;
-
-#if defined(__FreeBSD__)
- if (sc->sc_dying)
- return EIO;
-#endif
-
- as = &sc->sc_alts[ch->altidx];
- endpt = as->edesc->bEndpointAddress;
- DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n",
- endpt, ch->sample_rate, as->alt));
-
-#if defined(__FreeBSD__)
- locked = (ch->pcm_ch != NULL && mtx_owned(ch->pcm_ch->lock)) ? 1 : 0;
- if (locked)
- CHN_UNLOCK(ch->pcm_ch);
-#endif
- /* Set alternate interface corresponding to the mode. */
- err = usbd_set_interface(as->ifaceh, as->alt);
-#if defined(__FreeBSD__)
- if (locked)
- CHN_LOCK(ch->pcm_ch);
-#endif
- if (err)
- return err;
-
- /*
- * If just one sampling rate is supported,
- * no need to call uaudio_set_speed().
- * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request.
- */
- if (as->asf1desc->bSamFreqType != 1) {
- err = uaudio_set_speed(sc, endpt, ch->sample_rate);
- if (err) {
- DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n",
- usbd_errstr(err)));
- }
- }
-
- ch->pipe = 0;
- ch->sync_pipe = 0;
- DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt));
- err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe);
- if (err)
- return err;
- if (as->edesc1 != NULL) {
- endpt = as->edesc1->bEndpointAddress;
- DPRINTF(("uaudio_chan_open: create sync-pipe to 0x%02x\n", endpt));
- err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->sync_pipe);
- }
- return err;
-}
-
-static void
-uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch)
-{
- struct as_info *as;
-#if defined(__FreeBSD__)
- int locked;
-
- if (sc->sc_dying)
- return ;
-#endif
-
- as = &sc->sc_alts[ch->altidx];
- as->sc_busy = 0;
-#if defined(__FreeBSD__)
- locked = (ch->pcm_ch != NULL && mtx_owned(ch->pcm_ch->lock)) ? 1 : 0;
- if (locked)
- CHN_UNLOCK(ch->pcm_ch);
-#endif
- if (sc->sc_nullalt >= 0) {
- DPRINTF(("uaudio_chan_close: set null alt=%d\n",
- sc->sc_nullalt));
- /*
- * The interface will be initialized later again, so an
- * error does not hurt.
- */
- (void)usbd_set_interface(as->ifaceh, sc->sc_nullalt);
- }
- if (ch->pipe) {
- usbd_abort_pipe(ch->pipe);
- usbd_close_pipe(ch->pipe);
- }
- if (ch->sync_pipe) {
- usbd_abort_pipe(ch->sync_pipe);
- usbd_close_pipe(ch->sync_pipe);
- }
-#if defined(__FreeBSD__)
- if (locked)
- CHN_LOCK(ch->pcm_ch);
-#endif
-}
-
-static usbd_status
-uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch)
-{
- usbd_xfer_handle xfer;
- void *buf;
- int i, size;
-
- size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES;
- for (i = 0; i < UAUDIO_NCHANBUFS; i++) {
- xfer = usbd_alloc_xfer(sc->sc_udev);
- if (xfer == 0)
- goto bad;
- ch->chanbufs[i].xfer = xfer;
- buf = usbd_alloc_buffer(xfer, size);
- if (buf == 0) {
- i++;
- goto bad;
- }
- ch->chanbufs[i].buffer = buf;
- ch->chanbufs[i].chan = ch;
- }
-
- return USBD_NORMAL_COMPLETION;
-
-bad:
- while (--i >= 0)
- /* implicit buffer free */
- usbd_free_xfer(ch->chanbufs[i].xfer);
- return USBD_NOMEM;
-}
-
-static void
-uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch)
-{
- int i;
-
- for (i = 0; i < UAUDIO_NCHANBUFS; i++)
- usbd_free_xfer(ch->chanbufs[i].xfer);
-}
-
-/* Called at splusb() */
-static void
-uaudio_chan_ptransfer(struct chan *ch)
-{
- struct chanbuf *cb;
- int i, n, size, residue, total;
-
- if (ch->sc->sc_dying)
- return;
-
- /* Pick the next channel buffer. */
- cb = &ch->chanbufs[ch->curchanbuf];
- if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
- ch->curchanbuf = 0;
-
- /* Compute the size of each frame in the next transfer. */
- residue = ch->residue;
- total = 0;
- for (i = 0; i < UAUDIO_NFRAMES; i++) {
- size = ch->bytes_per_frame;
- residue += ch->fraction;
- if (residue >= USB_FRAMES_PER_SECOND) {
- if ((ch->sc->sc_altflags & UA_NOFRAC) == 0)
- size += ch->sample_size;
- residue -= USB_FRAMES_PER_SECOND;
- }
- cb->sizes[i] = size;
- total += size;
- }
- ch->residue = residue;
- cb->size = total;
-
- /*
- * Transfer data from upper layer buffer to channel buffer, taking
- * care of wrapping the upper layer buffer.
- */
- n = min(total, ch->end - ch->cur);
- memcpy(cb->buffer, ch->cur, n);
- ch->cur += n;
- if (ch->cur >= ch->end)
- ch->cur = ch->start;
- if (total > n) {
- total -= n;
- memcpy(cb->buffer + n, ch->cur, total);
- ch->cur += total;
- }
-
-#ifdef USB_DEBUG
- if (uaudiodebug > 8) {
- DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n",
- cb->buffer, ch->residue));
- for (i = 0; i < UAUDIO_NFRAMES; i++) {
- DPRINTF((" [%d] length %d\n", i, cb->sizes[i]));
- }
- }
-#endif
-
- DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer));
- /* Fill the request */
- usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
- UAUDIO_NFRAMES, USBD_NO_COPY,
- uaudio_chan_pintr);
-
- (void)usbd_transfer(cb->xfer);
-}
-
-static void
-uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- struct chanbuf *cb;
- struct chan *ch;
- u_int32_t count;
- int s;
-
- cb = priv;
- ch = cb->chan;
- /* Return if we are aborting. */
- if (status == USBD_CANCELLED)
- return;
-
- usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
- DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n",
- count, ch->transferred));
-#ifdef DIAGNOSTIC
- if (count != cb->size) {
- printf("uaudio_chan_pintr: count(%d) != size(%d)\n",
- count, cb->size);
- }
-#endif
-
- ch->transferred += cb->size;
-#if defined(__FreeBSD__)
- /* s = spltty(); */
- s = splhigh();
- chn_intr(ch->pcm_ch);
- splx(s);
-#else
- s = splaudio();
- /* Call back to upper layer */
- while (ch->transferred >= ch->blksize) {
- ch->transferred -= ch->blksize;
- DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n",
- ch->intr, ch->arg));
- ch->intr(ch->arg);
- }
- splx(s);
-#endif
-
- /* start next transfer */
- uaudio_chan_ptransfer(ch);
-}
-
-/* Called at splusb() */
-static void
-uaudio_chan_rtransfer(struct chan *ch)
-{
- struct chanbuf *cb;
- int i, size, residue, total;
-
- if (ch->sc->sc_dying)
- return;
-
- /* Pick the next channel buffer. */
- cb = &ch->chanbufs[ch->curchanbuf];
- if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
- ch->curchanbuf = 0;
-
- /* Compute the size of each frame in the next transfer. */
- residue = ch->residue;
- total = 0;
- for (i = 0; i < UAUDIO_NFRAMES; i++) {
- size = ch->bytes_per_frame;
- cb->sizes[i] = size;
- cb->offsets[i] = total;
- total += size;
- }
- ch->residue = residue;
- cb->size = total;
-
-#ifdef USB_DEBUG
- if (uaudiodebug > 8) {
- DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n",
- cb->buffer, ch->residue));
- for (i = 0; i < UAUDIO_NFRAMES; i++) {
- DPRINTF((" [%d] length %d\n", i, cb->sizes[i]));
- }
- }
-#endif
-
- DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer));
- /* Fill the request */
- usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
- UAUDIO_NFRAMES, USBD_NO_COPY,
- uaudio_chan_rintr);
-
- (void)usbd_transfer(cb->xfer);
-}
-
-static void
-uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- struct chanbuf *cb = priv;
- struct chan *ch = cb->chan;
- u_int32_t count;
- int s, i, n, frsize;
-
- /* Return if we are aborting. */
- if (status == USBD_CANCELLED)
- return;
-
- usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
- DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n",
- count, ch->transferred));
-
- /* count < cb->size is normal for asynchronous source */
-#ifdef DIAGNOSTIC
- if (count > cb->size) {
- printf("uaudio_chan_rintr: count(%d) > size(%d)\n",
- count, cb->size);
- }
-#endif
-
- /*
- * Transfer data from channel buffer to upper layer buffer, taking
- * care of wrapping the upper layer buffer.
- */
- for(i = 0; i < UAUDIO_NFRAMES; i++) {
- frsize = cb->sizes[i];
- n = min(frsize, ch->end - ch->cur);
- memcpy(ch->cur, cb->buffer + cb->offsets[i], n);
- ch->cur += n;
- if (ch->cur >= ch->end)
- ch->cur = ch->start;
- if (frsize > n) {
- memcpy(ch->cur, cb->buffer + cb->offsets[i] + n,
- frsize - n);
- ch->cur += frsize - n;
- }
- }
-
- /* Call back to upper layer */
- ch->transferred += count;
-#if defined(__FreeBSD__)
- s = spltty();
- chn_intr(ch->pcm_ch);
- splx(s);
-#else
- s = splaudio();
- while (ch->transferred >= ch->blksize) {
- ch->transferred -= ch->blksize;
- DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n",
- ch->intr, ch->arg));
- ch->intr(ch->arg);
- }
- splx(s);
-#endif
-
- /* start next transfer */
- uaudio_chan_rtransfer(ch);
-}
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static void
-uaudio_chan_init(struct chan *ch, int altidx, const struct audio_params *param,
- int maxpktsize)
-{
- int samples_per_frame, sample_size;
-
- ch->altidx = altidx;
- sample_size = param->precision * param->factor * param->hw_channels / 8;
- samples_per_frame = param->hw_sample_rate / USB_FRAMES_PER_SECOND;
- ch->sample_size = sample_size;
- ch->sample_rate = param->hw_sample_rate;
- if (maxpktsize == 0) {
- ch->fraction = param->hw_sample_rate % USB_FRAMES_PER_SECOND;
- ch->bytes_per_frame = samples_per_frame * sample_size;
- } else {
- ch->fraction = 0;
- ch->bytes_per_frame = maxpktsize;
- }
- ch->residue = 0;
-}
-
-static void
-uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize)
-{
- ch->start = start;
- ch->end = end;
- ch->cur = start;
- ch->blksize = blksize;
- ch->transferred = 0;
- ch->curchanbuf = 0;
-}
-
-static void
-uaudio_get_minmax_rates(int nalts, const struct as_info *alts,
- const struct audio_params *p, int mode,
- u_long *min, u_long *max)
-{
- const struct usb_audio_streaming_type1_descriptor *a1d;
- int i, j;
-
- *min = ULONG_MAX;
- *max = 0;
- for (i = 0; i < nalts; i++) {
- a1d = alts[i].asf1desc;
- if (alts[i].sc_busy)
- continue;
- if (p->hw_channels != a1d->bNrChannels)
- continue;
- if (p->hw_precision != a1d->bBitResolution)
- continue;
- if (p->hw_encoding != alts[i].encoding)
- continue;
- if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
- continue;
- if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
- DPRINTFN(2,("uaudio_get_minmax_rates: cont %d-%d\n",
- UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
- if (UA_SAMP_LO(a1d) < *min)
- *min = UA_SAMP_LO(a1d);
- if (UA_SAMP_HI(a1d) > *max)
- *max = UA_SAMP_HI(a1d);
- } else {
- for (j = 0; j < a1d->bSamFreqType; j++) {
- DPRINTFN(2,("uaudio_get_minmax_rates: disc #%d: %d\n",
- j, UA_GETSAMP(a1d, j)));
- if (UA_GETSAMP(a1d, j) < *min)
- *min = UA_GETSAMP(a1d, j);
- if (UA_GETSAMP(a1d, j) > *max)
- *max = UA_GETSAMP(a1d, j);
- }
- }
- }
-}
-
-static int
-uaudio_match_alt_sub(int nalts, const struct as_info *alts,
- const struct audio_params *p, int mode, u_long rate)
-{
- const struct usb_audio_streaming_type1_descriptor *a1d;
- int i, j;
-
- DPRINTF(("uaudio_match_alt_sub: search for %luHz %dch\n",
- rate, p->hw_channels));
- for (i = 0; i < nalts; i++) {
- a1d = alts[i].asf1desc;
- if (alts[i].sc_busy)
- continue;
- if (p->hw_channels != a1d->bNrChannels)
- continue;
- if (p->hw_precision != a1d->bBitResolution)
- continue;
- if (p->hw_encoding != alts[i].encoding)
- continue;
- if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
- continue;
- if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
- DPRINTFN(3,("uaudio_match_alt_sub: cont %d-%d\n",
- UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
- if (UA_SAMP_LO(a1d) <= rate && rate <= UA_SAMP_HI(a1d))
- return i;
- } else {
- for (j = 0; j < a1d->bSamFreqType; j++) {
- DPRINTFN(3,("uaudio_match_alt_sub: disc #%d: %d\n",
- j, UA_GETSAMP(a1d, j)));
- /* XXX allow for some slack */
- if (UA_GETSAMP(a1d, j) == rate)
- return i;
- }
- }
- }
- return -1;
-}
-
-static int
-uaudio_match_alt_chan(int nalts, const struct as_info *alts,
- struct audio_params *p, int mode)
-{
- int i, n;
- u_long min, max;
- u_long rate;
-
- /* Exact match */
- DPRINTF(("uaudio_match_alt_chan: examine %ldHz %dch %dbit.\n",
- p->sample_rate, p->hw_channels, p->hw_precision));
- i = uaudio_match_alt_sub(nalts, alts, p, mode, p->sample_rate);
- if (i >= 0)
- return i;
-
- uaudio_get_minmax_rates(nalts, alts, p, mode, &min, &max);
- DPRINTF(("uaudio_match_alt_chan: min=%lu max=%lu\n", min, max));
- if (max <= 0)
- return -1;
- /* Search for biggers */
- n = 2;
- while ((rate = p->sample_rate * n++) <= max) {
- i = uaudio_match_alt_sub(nalts, alts, p, mode, rate);
- if (i >= 0) {
- p->hw_sample_rate = rate;
- return i;
- }
- }
- if (p->sample_rate >= min) {
- i = uaudio_match_alt_sub(nalts, alts, p, mode, max);
- if (i >= 0) {
- p->hw_sample_rate = max;
- return i;
- }
- } else {
- i = uaudio_match_alt_sub(nalts, alts, p, mode, min);
- if (i >= 0) {
- p->hw_sample_rate = min;
- return i;
- }
- }
- return -1;
-}
-
-static int
-uaudio_match_alt(int nalts, const struct as_info *alts,
- struct audio_params *p, int mode)
-{
- int i, n;
-
- mode = mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN;
- i = uaudio_match_alt_chan(nalts, alts, p, mode);
- if (i >= 0)
- return i;
-
- for (n = p->channels + 1; n <= AUDIO_MAX_CHANNELS; n++) {
- p->hw_channels = n;
- i = uaudio_match_alt_chan(nalts, alts, p, mode);
- if (i >= 0)
- return i;
- }
-
- if (p->channels != 2)
- return -1;
- p->hw_channels = 1;
- return uaudio_match_alt_chan(nalts, alts, p, mode);
-}
-
-static int
-uaudio_set_params(void *addr, int setmode, int usemode,
- struct audio_params *play, struct audio_params *rec)
-{
- struct uaudio_softc *sc;
- int flags;
- int factor;
- int enc, i;
- int paltidx, raltidx;
- void (*swcode)(void *, u_char *buf, int cnt);
- struct audio_params *p;
- int mode;
-
- sc = addr;
- flags = sc->sc_altflags;
- paltidx = -1;
- raltidx = -1;
- if (sc->sc_dying)
- return EIO;
-
- if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) ||
- ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL))
- return EBUSY;
-
- if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
- sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0;
- if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
- sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0;
-
- /* Some uaudio devices are unidirectional. Don't try to find a
- matching mode for the unsupported direction. */
- setmode &= sc->sc_mode;
-
- for (mode = AUMODE_RECORD; mode != -1;
- mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
- if ((setmode & mode) == 0)
- continue;
-
- p = (mode == AUMODE_PLAY) ? play : rec;
-
- factor = 1;
- swcode = 0;
- enc = p->encoding;
- switch (enc) {
- case AUDIO_ENCODING_SLINEAR_BE:
- /* FALLTHROUGH */
- case AUDIO_ENCODING_SLINEAR_LE:
- if (enc == AUDIO_ENCODING_SLINEAR_BE
- && p->precision == 16 && (flags & HAS_16)) {
- swcode = swap_bytes;
- enc = AUDIO_ENCODING_SLINEAR_LE;
- } else if (p->precision == 8) {
- if (flags & HAS_8) {
- /* No conversion */
- } else if (flags & HAS_8U) {
- swcode = change_sign8;
- enc = AUDIO_ENCODING_ULINEAR_LE;
- } else if (flags & HAS_16) {
- factor = 2;
- p->hw_precision = 16;
- if (mode == AUMODE_PLAY)
- swcode = linear8_to_linear16_le;
- else
- swcode = linear16_to_linear8_le;
- }
- }
- break;
- case AUDIO_ENCODING_ULINEAR_BE:
- /* FALLTHROUGH */
- case AUDIO_ENCODING_ULINEAR_LE:
- if (p->precision == 16) {
- if (enc == AUDIO_ENCODING_ULINEAR_LE)
- swcode = change_sign16_le;
- else if (mode == AUMODE_PLAY)
- swcode = swap_bytes_change_sign16_le;
- else
- swcode = change_sign16_swap_bytes_le;
- enc = AUDIO_ENCODING_SLINEAR_LE;
- } else if (p->precision == 8) {
- if (flags & HAS_8U) {
- /* No conversion */
- } else if (flags & HAS_8) {
- swcode = change_sign8;
- enc = AUDIO_ENCODING_SLINEAR_LE;
- } else if (flags & HAS_16) {
- factor = 2;
- p->hw_precision = 16;
- enc = AUDIO_ENCODING_SLINEAR_LE;
- if (mode == AUMODE_PLAY)
- swcode = ulinear8_to_slinear16_le;
- else
- swcode = slinear16_to_ulinear8_le;
- }
- }
- break;
- case AUDIO_ENCODING_ULAW:
- if (flags & HAS_MULAW)
- break;
- if (flags & HAS_16) {
- if (mode == AUMODE_PLAY)
- swcode = mulaw_to_slinear16_le;
- else
- swcode = slinear16_to_mulaw_le;
- factor = 2;
- enc = AUDIO_ENCODING_SLINEAR_LE;
- p->hw_precision = 16;
- } else if (flags & HAS_8U) {
- if (mode == AUMODE_PLAY)
- swcode = mulaw_to_ulinear8;
- else
- swcode = ulinear8_to_mulaw;
- enc = AUDIO_ENCODING_ULINEAR_LE;
- } else if (flags & HAS_8) {
- if (mode == AUMODE_PLAY)
- swcode = mulaw_to_slinear8;
- else
- swcode = slinear8_to_mulaw;
- enc = AUDIO_ENCODING_SLINEAR_LE;
- } else
- return (EINVAL);
- break;
- case AUDIO_ENCODING_ALAW:
- if (flags & HAS_ALAW)
- break;
- if (mode == AUMODE_PLAY && (flags & HAS_16)) {
- swcode = alaw_to_slinear16_le;
- factor = 2;
- enc = AUDIO_ENCODING_SLINEAR_LE;
- p->hw_precision = 16;
- } else if (flags & HAS_8U) {
- if (mode == AUMODE_PLAY)
- swcode = alaw_to_ulinear8;
- else
- swcode = ulinear8_to_alaw;
- enc = AUDIO_ENCODING_ULINEAR_LE;
- } else if (flags & HAS_8) {
- if (mode == AUMODE_PLAY)
- swcode = alaw_to_slinear8;
- else
- swcode = slinear8_to_alaw;
- enc = AUDIO_ENCODING_SLINEAR_LE;
- } else
- return (EINVAL);
- break;
- default:
- return (EINVAL);
- }
- /* XXX do some other conversions... */
-
- DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n",
- p->channels, p->hw_precision, enc, p->sample_rate));
-
- p->hw_encoding = enc;
- i = uaudio_match_alt(sc->sc_nalts, sc->sc_alts, p, mode);
- if (i < 0)
- return (EINVAL);
-
- p->sw_code = swcode;
- p->factor = factor;
-
- if (mode == AUMODE_PLAY)
- paltidx = i;
- else
- raltidx = i;
- }
-
- if ((setmode & AUMODE_PLAY)) {
- /* XXX abort transfer if currently happening? */
- uaudio_chan_init(&sc->sc_playchan, paltidx, play, 0);
- }
- if ((setmode & AUMODE_RECORD)) {
- /* XXX abort transfer if currently happening? */
- uaudio_chan_init(&sc->sc_recchan, raltidx, rec,
- UGETW(sc->sc_alts[raltidx].edesc->wMaxPacketSize));
- }
-
- if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
- sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1;
- if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
- sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1;
-
- DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n",
- sc->sc_playchan.altidx, sc->sc_recchan.altidx,
- (sc->sc_playchan.altidx >= 0)
- ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting
- : -1,
- (sc->sc_recchan.altidx >= 0)
- ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting
- : -1));
-
- return 0;
-}
-#endif /* NetBSD or OpenBSD */
-
-static usbd_status
-uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed)
-{
- usb_device_request_t req;
- uint8_t data[3];
-
- DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed));
- req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
- req.bRequest = SET_CUR;
- USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
- USETW(req.wIndex, endpt);
- USETW(req.wLength, 3);
- data[0] = speed;
- data[1] = speed >> 8;
- data[2] = speed >> 16;
-
-#if defined(__FreeBSD__)
- if (sc->async != 0)
- return usbd_do_request_async(sc->sc_udev, &req, data);
-#endif
- return usbd_do_request(sc->sc_udev, &req, data);
-}
-
-
-#if defined(__FreeBSD__)
-/************************************************************/
-int
-uaudio_init_params(struct uaudio_softc *sc, struct chan *ch, int mode)
-{
- int i, j, enc;
- int samples_per_frame, sample_size;
-
- if ((sc->sc_playchan.pipe != NULL) || (sc->sc_recchan.pipe != NULL))
- return (-1);
-
- switch(ch->format & 0x000FFFFF) {
- case AFMT_U8:
- enc = AUDIO_ENCODING_ULINEAR_LE;
- ch->precision = 8;
- break;
- case AFMT_S8:
- enc = AUDIO_ENCODING_SLINEAR_LE;
- ch->precision = 8;
- break;
- case AFMT_A_LAW: /* ? */
- enc = AUDIO_ENCODING_ALAW;
- ch->precision = 8;
- break;
- case AFMT_MU_LAW: /* ? */
- enc = AUDIO_ENCODING_ULAW;
- ch->precision = 8;
- break;
- case AFMT_S16_LE:
- enc = AUDIO_ENCODING_SLINEAR_LE;
- ch->precision = 16;
- break;
- case AFMT_S16_BE:
- enc = AUDIO_ENCODING_SLINEAR_BE;
- ch->precision = 16;
- break;
- case AFMT_U16_LE:
- enc = AUDIO_ENCODING_ULINEAR_LE;
- ch->precision = 16;
- break;
- case AFMT_U16_BE:
- enc = AUDIO_ENCODING_ULINEAR_BE;
- ch->precision = 16;
- break;
- case AFMT_S24_LE:
- enc = AUDIO_ENCODING_SLINEAR_LE;
- ch->precision = 24;
- break;
- case AFMT_S24_BE:
- enc = AUDIO_ENCODING_SLINEAR_BE;
- ch->precision = 24;
- break;
- case AFMT_U24_LE:
- enc = AUDIO_ENCODING_ULINEAR_LE;
- ch->precision = 24;
- break;
- case AFMT_U24_BE:
- enc = AUDIO_ENCODING_ULINEAR_BE;
- ch->precision = 24;
- break;
- case AFMT_S32_LE:
- enc = AUDIO_ENCODING_SLINEAR_LE;
- ch->precision = 32;
- break;
- case AFMT_S32_BE:
- enc = AUDIO_ENCODING_SLINEAR_BE;
- ch->precision = 32;
- break;
- case AFMT_U32_LE:
- enc = AUDIO_ENCODING_ULINEAR_LE;
- ch->precision = 32;
- break;
- case AFMT_U32_BE:
- enc = AUDIO_ENCODING_ULINEAR_BE;
- ch->precision = 32;
- break;
- default:
- enc = 0;
- ch->precision = 16;
- printf("Unknown format %x\n", ch->format);
- }
-
- if (ch->format & AFMT_STEREO) {
- ch->channels = 2;
- } else {
- ch->channels = 1;
- }
-
-/* for (mode = ...... */
- for (i = 0; i < sc->sc_nalts; i++) {
- const struct usb_audio_streaming_type1_descriptor *a1d =
- sc->sc_alts[i].asf1desc;
- if (ch->channels == a1d->bNrChannels &&
- ch->precision == a1d->bBitResolution &&
-#if 0
- enc == sc->sc_alts[i].encoding) {
-#else
- enc == sc->sc_alts[i].encoding &&
- (mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN) ==
- UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress)) {
-#endif
- if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
- DPRINTFN(2,("uaudio_set_params: cont %d-%d\n",
- UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
- if (UA_SAMP_LO(a1d) <= ch->sample_rate &&
- ch->sample_rate <= UA_SAMP_HI(a1d)) {
- if (mode == AUMODE_PLAY)
- sc->sc_playchan.altidx = i;
- else
- sc->sc_recchan.altidx = i;
- goto found;
- }
- } else {
- for (j = 0; j < a1d->bSamFreqType; j++) {
- DPRINTFN(2,("uaudio_set_params: disc #"
- "%d: %d\n", j, UA_GETSAMP(a1d, j)));
- /* XXX allow for some slack */
- if (UA_GETSAMP(a1d, j) ==
- ch->sample_rate) {
- if (mode == AUMODE_PLAY)
- sc->sc_playchan.altidx = i;
- else
- sc->sc_recchan.altidx = i;
- goto found;
- }
- }
- }
- }
- }
- /* return (EINVAL); */
- if (mode == AUMODE_PLAY)
- printf("uaudio: This device can't play in rate=%d.\n", ch->sample_rate);
- else
- printf("uaudio: This device can't record in rate=%d.\n", ch->sample_rate);
- return (-1);
-
- found:
-#if 0 /* XXX */
- p->sw_code = swcode;
- p->factor = factor;
- if (usemode == mode)
- sc->sc_curaltidx = i;
-#endif
-/* } */
-
- sample_size = ch->precision * ch->channels / 8;
- samples_per_frame = ch->sample_rate / USB_FRAMES_PER_SECOND;
- ch->fraction = ch->sample_rate % USB_FRAMES_PER_SECOND;
- ch->sample_size = sample_size;
- ch->bytes_per_frame = samples_per_frame * sample_size;
- ch->residue = 0;
-
- ch->cur = ch->start;
- ch->transferred = 0;
- ch->curchanbuf = 0;
- return (0);
-}
-
-struct uaudio_conversion {
- uint8_t uaudio_fmt;
- uint8_t uaudio_prec;
- uint32_t freebsd_fmt;
-};
-
-const struct uaudio_conversion const accepted_conversion[] = {
- {AUDIO_ENCODING_ULINEAR_LE, 8, AFMT_U8},
- {AUDIO_ENCODING_ULINEAR_LE, 16, AFMT_U16_LE},
- {AUDIO_ENCODING_ULINEAR_LE, 24, AFMT_U24_LE},
- {AUDIO_ENCODING_ULINEAR_LE, 32, AFMT_U32_LE},
- {AUDIO_ENCODING_ULINEAR_BE, 16, AFMT_U16_BE},
- {AUDIO_ENCODING_ULINEAR_BE, 24, AFMT_U24_BE},
- {AUDIO_ENCODING_ULINEAR_BE, 32, AFMT_U32_BE},
- {AUDIO_ENCODING_SLINEAR_LE, 8, AFMT_S8},
- {AUDIO_ENCODING_SLINEAR_LE, 16, AFMT_S16_LE},
- {AUDIO_ENCODING_SLINEAR_LE, 24, AFMT_S24_LE},
- {AUDIO_ENCODING_SLINEAR_LE, 32, AFMT_S32_LE},
- {AUDIO_ENCODING_SLINEAR_BE, 16, AFMT_S16_BE},
- {AUDIO_ENCODING_SLINEAR_BE, 24, AFMT_S24_BE},
- {AUDIO_ENCODING_SLINEAR_BE, 32, AFMT_S32_BE},
- {AUDIO_ENCODING_ALAW, 8, AFMT_A_LAW},
- {AUDIO_ENCODING_ULAW, 8, AFMT_MU_LAW},
- {0,0,0}
-};
-
-unsigned
-uaudio_query_formats(device_t dev, int reqdir, unsigned maxfmt, struct pcmchan_caps *cap)
-{
- struct uaudio_softc *sc;
- const struct usb_audio_streaming_type1_descriptor *asf1d;
- const struct uaudio_conversion *iterator;
- unsigned fmtcount, foundcount;
- u_int32_t fmt;
- uint8_t format, numchan, subframesize, prec, dir, iscontinuous;
- int freq, freq_min, freq_max;
- char *numchannel_descr;
- char freq_descr[64];
- int i,r;
-
- sc = device_get_softc(dev);
- if (sc == NULL)
- return 0;
-
- cap->minspeed = cap->maxspeed = 0;
- foundcount = fmtcount = 0;
-
- for (i = 0; i < sc->sc_nalts; i++) {
- dir = UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress);
-
- if ((dir == UE_DIR_OUT) != (reqdir == PCMDIR_PLAY))
- continue;
-
- asf1d = sc->sc_alts[i].asf1desc;
- format = sc->sc_alts[i].encoding;
-
- numchan = asf1d->bNrChannels;
- subframesize = asf1d->bSubFrameSize;
- prec = asf1d->bBitResolution; /* precision */
- iscontinuous = asf1d->bSamFreqType == UA_SAMP_CONTNUOUS;
-
- if (iscontinuous)
- snprintf(freq_descr, sizeof(freq_descr), "continous min %d max %d", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
- else
- snprintf(freq_descr, sizeof(freq_descr), "fixed frequency (%d listed formats)", asf1d->bSamFreqType);
-
- if (numchan == 1)
- numchannel_descr = " (mono)";
- else if (numchan == 2)
- numchannel_descr = " (stereo)";
- else
- numchannel_descr = "";
-
- if (bootverbose) {
- device_printf(dev, "uaudio_query_formats: found a native %s channel%s %s %dbit %dbytes/subframe X %d channels = %d bytes per sample\n",
- (dir==UE_DIR_OUT)?"playback":"record",
- numchannel_descr, freq_descr,
- prec, subframesize, numchan, subframesize*numchan);
- }
- /*
- * Now start rejecting the ones that don't map to FreeBSD
- */
-
- if (numchan != 1 && numchan != 2)
- continue;
-
- for (iterator = accepted_conversion ; iterator->uaudio_fmt != 0 ; iterator++)
- if (iterator->uaudio_fmt == format && iterator->uaudio_prec == prec)
- break;
-
- if (iterator->uaudio_fmt == 0)
- continue;
-
- fmt = iterator->freebsd_fmt;
-
- if (numchan == 2)
- fmt |= AFMT_STEREO;
-
- foundcount++;
-
- if (fmtcount >= maxfmt)
- continue;
-
- cap->fmtlist[fmtcount++] = fmt;
-
- if (iscontinuous) {
- freq_min = UA_SAMP_LO(asf1d);
- freq_max = UA_SAMP_HI(asf1d);
-
- if (cap->minspeed == 0 || freq_min < cap->minspeed)
- cap->minspeed = freq_min;
- if (cap->maxspeed == 0)
- cap->maxspeed = cap->minspeed;
- if (freq_max > cap->maxspeed)
- cap->maxspeed = freq_max;
- } else {
- for (r = 0; r < asf1d->bSamFreqType; r++) {
- freq = UA_GETSAMP(asf1d, r);
- if (cap->minspeed == 0 || freq < cap->minspeed)
- cap->minspeed = freq;
- if (cap->maxspeed == 0)
- cap->maxspeed = cap->minspeed;
- if (freq > cap->maxspeed)
- cap->maxspeed = freq;
- }
- }
- }
- cap->fmtlist[fmtcount] = 0;
- return foundcount;
-}
-
-void
-uaudio_chan_set_param_pcm_dma_buff(device_t dev, u_char *start, u_char *end,
- struct pcm_channel *pc, int dir)
-{
- struct uaudio_softc *sc;
- struct chan *ch;
-
- sc = device_get_softc(dev);
-#ifndef NO_RECORDING
- if (dir == PCMDIR_PLAY)
- ch = &sc->sc_playchan;
- else
- ch = &sc->sc_recchan;
-#else
- ch = &sc->sc_playchan;
-#endif
-
- ch->start = start;
- ch->end = end;
-
- ch->pcm_ch = pc;
-
- return;
-}
-
-void
-uaudio_chan_set_param_blocksize(device_t dev, u_int32_t blocksize, int dir)
-{
- struct uaudio_softc *sc;
- struct chan *ch;
-
- sc = device_get_softc(dev);
-#ifndef NO_RECORDING
- if (dir == PCMDIR_PLAY)
- ch = &sc->sc_playchan;
- else
- ch = &sc->sc_recchan;
-#else
- ch = &sc->sc_playchan;
-#endif
-
- ch->blksize = blocksize;
-
- return;
-}
-
-int
-uaudio_chan_set_param_speed(device_t dev, u_int32_t speed, int reqdir)
-{
- const struct uaudio_conversion *iterator;
- struct uaudio_softc *sc;
- struct chan *ch;
- int i, r, score, hiscore, bestspeed;
-
- sc = device_get_softc(dev);
-#ifndef NO_RECORDING
- if (reqdir == PCMDIR_PLAY)
- ch = &sc->sc_playchan;
- else
- ch = &sc->sc_recchan;
-#else
- ch = &sc->sc_playchan;
-#endif
- /*
- * We are successful if we find an endpoint that matches our selected format and it
- * supports the requested speed.
- */
- hiscore = 0;
- bestspeed = 1;
- for (i = 0; i < sc->sc_nalts; i++) {
- int dir = UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress);
- int format = sc->sc_alts[i].encoding;
- const struct usb_audio_streaming_type1_descriptor *asf1d = sc->sc_alts[i].asf1desc;
- int iscontinuous = asf1d->bSamFreqType == UA_SAMP_CONTNUOUS;
-
- if ((dir == UE_DIR_OUT) != (reqdir == PCMDIR_PLAY))
- continue;
-
- for (iterator = accepted_conversion ; iterator->uaudio_fmt != 0 ; iterator++)
- if (iterator->uaudio_fmt != format || iterator->freebsd_fmt != (ch->format&0xfffffff))
- continue;
- if (iscontinuous) {
- if (speed >= UA_SAMP_LO(asf1d) && speed <= UA_SAMP_HI(asf1d)) {
- ch->sample_rate = speed;
- return speed;
- } else if (speed < UA_SAMP_LO(asf1d)) {
- score = 0xfff * speed / UA_SAMP_LO(asf1d);
- if (score > hiscore) {
- bestspeed = UA_SAMP_LO(asf1d);
- hiscore = score;
- }
- } else if (speed > UA_SAMP_HI(asf1d)) {
- score = 0xfff * UA_SAMP_HI(asf1d) / speed;
- if (score > hiscore) {
- bestspeed = UA_SAMP_HI(asf1d);
- hiscore = score;
- }
- }
- continue;
- }
- for (r = 0; r < asf1d->bSamFreqType; r++) {
- if (speed == UA_GETSAMP(asf1d, r)) {
- ch->sample_rate = speed;
- return speed;
- }
- if (speed > UA_GETSAMP(asf1d, r))
- score = 0xfff * UA_GETSAMP(asf1d, r) / speed;
- else
- score = 0xfff * speed / UA_GETSAMP(asf1d, r);
- if (score > hiscore) {
- bestspeed = UA_GETSAMP(asf1d, r);
- hiscore = score;
- }
- }
- }
- if (bestspeed != 1) {
- ch->sample_rate = bestspeed;
- return bestspeed;
- }
-
- return 0;
-}
-
-int
-uaudio_chan_getptr(device_t dev, int dir)
-{
- struct uaudio_softc *sc;
- struct chan *ch;
- int ptr;
-
- sc = device_get_softc(dev);
-#ifndef NO_RECORDING
- if (dir == PCMDIR_PLAY)
- ch = &sc->sc_playchan;
- else
- ch = &sc->sc_recchan;
-#else
- ch = &sc->sc_playchan;
-#endif
-
- ptr = ch->cur - ch->start;
-
- return ptr;
-}
-
-void
-uaudio_chan_set_param_format(device_t dev, u_int32_t format, int dir)
-{
- struct uaudio_softc *sc;
- struct chan *ch;
-
- sc = device_get_softc(dev);
-#ifndef NO_RECORDING
- if (dir == PCMDIR_PLAY)
- ch = &sc->sc_playchan;
- else
- ch = &sc->sc_recchan;
-#else
- ch = &sc->sc_playchan;
-#endif
-
- ch->format = format;
-
- return;
-}
-
-int
-uaudio_halt_out_dma(device_t dev)
-{
- struct uaudio_softc *sc;
-
- sc = device_get_softc(dev);
-
- DPRINTF(("uaudio_halt_out_dma: enter\n"));
- if (sc->sc_playchan.pipe != NULL) {
- uaudio_chan_close(sc, &sc->sc_playchan);
- sc->sc_playchan.pipe = 0;
- uaudio_chan_free_buffers(sc, &sc->sc_playchan);
- }
- return (0);
-}
-
-int
-uaudio_halt_in_dma(device_t dev)
-{
- struct uaudio_softc *sc;
-
- sc = device_get_softc(dev);
-
- if (sc->sc_dying)
- return (EIO);
-
- DPRINTF(("uaudio_halt_in_dma: enter\n"));
- if (sc->sc_recchan.pipe != NULL) {
- uaudio_chan_close(sc, &sc->sc_recchan);
- sc->sc_recchan.pipe = NULL;
- uaudio_chan_free_buffers(sc, &sc->sc_recchan);
-/* sc->sc_recchan.intr = NULL; */
- }
- return (0);
-}
-
-int
-uaudio_trigger_input(device_t dev)
-{
- struct uaudio_softc *sc;
- struct chan *ch;
- usbd_status err;
- int i, s;
-
- sc = device_get_softc(dev);
- ch = &sc->sc_recchan;
-
- if (sc->sc_dying)
- return (EIO);
-
-/* uaudio_chan_set_param(ch, start, end, blksize) */
- if (uaudio_init_params(sc, ch, AUMODE_RECORD))
- return (EIO);
-
- err = uaudio_chan_alloc_buffers(sc, ch);
- if (err)
- return (EIO);
-
- err = uaudio_chan_open(sc, ch);
- if (err) {
- uaudio_chan_free_buffers(sc, ch);
- return (EIO);
- }
-
-/* ch->intr = intr;
- ch->arg = arg; */
-
- s = splusb();
- for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
- uaudio_chan_rtransfer(ch);
- splx(s);
-
- return (0);
-}
-
-int
-uaudio_trigger_output(device_t dev)
-{
- struct uaudio_softc *sc;
- struct chan *ch;
- usbd_status err;
- int i, s;
-
- sc = device_get_softc(dev);
- ch = &sc->sc_playchan;
-
- if (sc->sc_dying)
- return (EIO);
-
- if (uaudio_init_params(sc, ch, AUMODE_PLAY))
- return (EIO);
-
- err = uaudio_chan_alloc_buffers(sc, ch);
- if (err)
- return (EIO);
-
- err = uaudio_chan_open(sc, ch);
- if (err) {
- uaudio_chan_free_buffers(sc, ch);
- return (EIO);
- }
-
- s = splusb();
- for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
- uaudio_chan_ptransfer(ch);
- splx(s);
-
- return (0);
-}
-
-u_int32_t
-uaudio_query_mix_info(device_t dev)
-{
- int i;
- u_int32_t mask = 0;
- struct uaudio_softc *sc;
- struct mixerctl *mc;
-
- sc = device_get_softc(dev);
- for (i=0; i < sc->sc_nctls; i++) {
- mc = &sc->sc_ctls[i];
- if (mc->ctl != SOUND_MIXER_NRDEVICES) {
- /* Set device mask bits.
- See /usr/include/machine/soundcard.h */
- mask |= (1 << mc->ctl);
- }
- }
- return mask;
-}
-
-u_int32_t
-uaudio_query_recsrc_info(device_t dev)
-{
- int i, rec_selector_id;
- u_int32_t mask = 0;
- struct uaudio_softc *sc;
- struct mixerctl *mc;
-
- sc = device_get_softc(dev);
- rec_selector_id = -1;
- for (i=0; i < sc->sc_nctls; i++) {
- mc = &sc->sc_ctls[i];
- if (mc->ctl == SOUND_MIXER_NRDEVICES &&
- mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
- if (rec_selector_id == -1) {
- rec_selector_id = i;
- } else {
- printf("There are many selectors. Can't recognize which selector is a record source selector.\n");
- return mask;
- }
- }
- }
- if (rec_selector_id == -1)
- return mask;
- mc = &sc->sc_ctls[rec_selector_id];
- for (i = mc->minval; i <= mc->maxval; i++) {
- if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES)
- continue;
- mask |= 1 << mc->slctrtype[i - 1];
- }
- return mask;
-}
-
-void
-uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right)
-{
- int i;
- struct uaudio_softc *sc;
- struct mixerctl *mc;
-
- sc = device_get_softc(dev);
- for (i=0; i < sc->sc_nctls; i++) {
- mc = &sc->sc_ctls[i];
- if (mc->ctl == type) {
- if (mc->nchan == 2) {
- /* set Right */
- uaudio_ctl_set(sc, SET_CUR, mc, 1, (int)(right*255)/100);
- }
- /* set Left or Mono */
- uaudio_ctl_set(sc, SET_CUR, mc, 0, (int)(left*255)/100);
- }
- }
- return;
-}
-
-u_int32_t
-uaudio_mixer_setrecsrc(device_t dev, u_int32_t src)
-{
- int i, rec_selector_id;
- struct uaudio_softc *sc;
- struct mixerctl *mc;
-
- sc = device_get_softc(dev);
- rec_selector_id = -1;
- for (i=0; i < sc->sc_nctls; i++) {
- mc = &sc->sc_ctls[i];
- if (mc->ctl == SOUND_MIXER_NRDEVICES &&
- mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
- if (rec_selector_id == -1) {
- rec_selector_id = i;
- } else {
- return src; /* Can't recognize which selector is record source selector */
- }
- }
- }
- if (rec_selector_id == -1)
- return src;
- mc = &sc->sc_ctls[rec_selector_id];
- for (i = mc->minval; i <= mc->maxval; i++) {
- if (src != (1 << mc->slctrtype[i - 1]))
- continue;
- uaudio_ctl_set(sc, SET_CUR, mc, 0, i);
- return (1 << mc->slctrtype[i - 1]);
- }
- uaudio_ctl_set(sc, SET_CUR, mc, 0, mc->minval);
- return (1 << mc->slctrtype[mc->minval - 1]);
-}
-
-static int
-uaudio_sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
-{
- struct snddev_info *d;
- struct pcm_channel *c;
- struct pcm_feeder *f;
- device_t pa_dev = device_get_parent(dev);
- struct uaudio_softc *sc = device_get_softc(pa_dev);
-
- if (verbose < 1)
- return 0;
-
- d = device_get_softc(dev);
- if (!d)
- return ENXIO;
-
- PCM_BUSYASSERT(d);
-
- if (CHN_EMPTY(d, channels.pcm)) {
- sbuf_printf(s, " (mixer only)");
- return 0;
- }
-
- sbuf_printf(s, " (%dp:%dv/%dr:%dv channels%s%s)",
- d->playcount, d->pvchancount,
- d->reccount, d->rvchancount,
- (d->flags & SD_F_SIMPLEX)? "" : " duplex",
-#ifdef USING_DEVFS
- (device_get_unit(dev) == snd_unit)? " default" : ""
-#else
- ""
-#endif
- );
-
- if (sc->uaudio_sndstat_flag != 0) {
- sbuf_cat(s, sbuf_data(&(sc->uaudio_sndstat)));
- }
-
- if (verbose <= 1)
- return 0;
-
- CHN_FOREACH(c, d, channels.pcm) {
-
- KASSERT(c->bufhard != NULL && c->bufsoft != NULL,
- ("hosed pcm channel setup"));
-
- sbuf_printf(s, "\n\t");
-
- /* it would be better to indent child channels */
- sbuf_printf(s, "%s[%s]: ", c->parentchannel? c->parentchannel->name : "", c->name);
- sbuf_printf(s, "spd %d", c->speed);
- if (c->speed != sndbuf_getspd(c->bufhard))
- sbuf_printf(s, "/%d", sndbuf_getspd(c->bufhard));
- sbuf_printf(s, ", fmt 0x%08x", c->format);
- if (c->format != sndbuf_getfmt(c->bufhard))
- sbuf_printf(s, "/0x%08x", sndbuf_getfmt(c->bufhard));
- sbuf_printf(s, ", flags 0x%08x, 0x%08x", c->flags, c->feederflags);
- if (c->pid != -1)
- sbuf_printf(s, ", pid %d", c->pid);
- sbuf_printf(s, "\n\t");
-
- sbuf_printf(s, "interrupts %d, ", c->interrupts);
- if (c->direction == PCMDIR_REC)
- sbuf_printf(s, "overruns %d, feed %u, hfree %d, sfree %d [b:%d/%d/%d|bs:%d/%d/%d]",
- c->xruns, c->feedcount, sndbuf_getfree(c->bufhard), sndbuf_getfree(c->bufsoft),
- sndbuf_getsize(c->bufhard), sndbuf_getblksz(c->bufhard),
- sndbuf_getblkcnt(c->bufhard),
- sndbuf_getsize(c->bufsoft), sndbuf_getblksz(c->bufsoft),
- sndbuf_getblkcnt(c->bufsoft));
- else
- sbuf_printf(s, "underruns %d, feed %u, ready %d [b:%d/%d/%d|bs:%d/%d/%d]",
- c->xruns, c->feedcount, sndbuf_getready(c->bufsoft),
- sndbuf_getsize(c->bufhard), sndbuf_getblksz(c->bufhard),
- sndbuf_getblkcnt(c->bufhard),
- sndbuf_getsize(c->bufsoft), sndbuf_getblksz(c->bufsoft),
- sndbuf_getblkcnt(c->bufsoft));
- sbuf_printf(s, "\n\t");
-
- sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC)? "hardware" : "userland");
- sbuf_printf(s, " -> ");
- f = c->feeder;
- while (f->source != NULL)
- f = f->source;
- while (f != NULL) {
- sbuf_printf(s, "%s", f->class->name);
- if (f->desc->type == FEEDER_FMT)
- sbuf_printf(s, "(0x%08x -> 0x%08x)", f->desc->in, f->desc->out);
- if (f->desc->type == FEEDER_RATE)
- sbuf_printf(s, "(%d -> %d)", FEEDER_GET(f, FEEDRATE_SRC), FEEDER_GET(f, FEEDRATE_DST));
- if (f->desc->type == FEEDER_ROOT || f->desc->type == FEEDER_MIXER ||
- f->desc->type == FEEDER_VOLUME)
- sbuf_printf(s, "(0x%08x)", f->desc->out);
- sbuf_printf(s, " -> ");
- f = f->parent;
- }
- sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC)? "userland" : "hardware");
- }
-
- return 0;
-}
-
-void
-uaudio_sndstat_register(device_t dev)
-{
- struct snddev_info *d = device_get_softc(dev);
- sndstat_register(dev, d->status, uaudio_sndstat_prepare_pcm);
-}
-
-int
-uaudio_get_vendor(device_t dev)
-{
- struct uaudio_softc *sc = device_get_softc(dev);
-
- if (sc == NULL)
- return 0;
-
- return sc->sc_vendor;
-}
-
-int
-uaudio_get_product(device_t dev)
-{
- struct uaudio_softc *sc = device_get_softc(dev);
-
- if (sc == NULL)
- return 0;
-
- return sc->sc_product;
-}
-
-int
-uaudio_get_release(device_t dev)
-{
- struct uaudio_softc *sc = device_get_softc(dev);
-
- if (sc == NULL)
- return 0;
-
- return sc->sc_release;
-}
-
-static int
-audio_attach_mi(device_t dev)
-{
- device_t child;
- struct sndcard_func *func;
-
- /* Attach the children. */
- /* PCM Audio */
- func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (func == NULL)
- return (ENOMEM);
- func->func = SCF_PCM;
- child = device_add_child(dev, "pcm", -1);
- device_set_ivars(child, func);
-
- bus_generic_attach(dev);
-
- return 0; /* XXXXX */
-}
-
-DRIVER_MODULE(uaudio, uhub, uaudio_driver, uaudio_devclass, usbd_driver_load, 0);
-MODULE_VERSION(uaudio, 1);
-
-#endif
diff --git a/sys/legacy/dev/sound/usb/uaudio.h b/sys/legacy/dev/sound/usb/uaudio.h
deleted file mode 100644
index b73f7a5..0000000
--- a/sys/legacy/dev/sound/usb/uaudio.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2000-2002 Hiroyuki Aizu <aizu@navi.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.
- *
- * 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.
- */
-
-#if 0
-#define NO_RECORDING /* XXX: some routines missing from uaudio.c */
-#endif
-
-/* Defined in uaudio.c, used in uaudio_pcm,c */
-
-void uaudio_chan_set_param_pcm_dma_buff(device_t dev, u_char *start,
- u_char *end, struct pcm_channel *pc, int dir);
-int uaudio_trigger_output(device_t dev);
-int uaudio_halt_out_dma(device_t dev);
-#ifndef NO_RECORDING
-int uaudio_trigger_input(device_t dev);
-int uaudio_halt_in_dma(device_t dev);
-#endif
-void uaudio_chan_set_param(device_t, u_char *, u_char *);
-void uaudio_chan_set_param_blocksize(device_t dev, u_int32_t blocksize, int dir);
-int uaudio_chan_set_param_speed(device_t dev, u_int32_t speed, int reqdir);
-void uaudio_chan_set_param_format(device_t dev, u_int32_t format,int dir);
-int uaudio_chan_getptr(device_t dev, int);
-void uaudio_mixer_set(device_t dev, unsigned type, unsigned left,
- unsigned right);
-u_int32_t uaudio_mixer_setrecsrc(device_t dev, u_int32_t src);
-u_int32_t uaudio_query_mix_info(device_t dev);
-u_int32_t uaudio_query_recsrc_info(device_t dev);
-unsigned uaudio_query_formats(device_t dev, int dir, unsigned maxfmt, struct pcmchan_caps *fmt);
-void uaudio_sndstat_register(device_t dev);
-int uaudio_get_vendor(device_t dev);
-int uaudio_get_product(device_t dev);
-int uaudio_get_release(device_t dev);
diff --git a/sys/legacy/dev/sound/usb/uaudio_pcm.c b/sys/legacy/dev/sound/usb/uaudio_pcm.c
deleted file mode 100644
index 618a0ed..0000000
--- a/sys/legacy/dev/sound/usb/uaudio_pcm.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2000-2002 Hiroyuki Aizu <aizu@navi.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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-
-#include <sys/soundcard.h>
-#include <dev/sound/pcm/sound.h>
-#include <dev/sound/chip.h>
-
-#include <dev/sound/usb/uaudio.h>
-
-#include "mixer_if.h"
-
-struct ua_info;
-
-struct ua_chinfo {
- struct ua_info *parent;
- struct pcm_channel *channel;
- struct snd_dbuf *buffer;
- u_char *buf;
- int dir, hwch;
- u_int32_t fmt, spd, blksz; /* XXXXX */
-};
-
-struct ua_info {
- device_t sc_dev;
- u_int32_t bufsz;
- struct ua_chinfo pch, rch;
-#define FORMAT_NUM 32
- u_int32_t ua_playfmt[FORMAT_NUM*2+1]; /* FORMAT_NUM format * (stereo or mono) + endptr */
- u_int32_t ua_recfmt[FORMAT_NUM*2+1]; /* FORMAT_NUM format * (stereo or mono) + endptr */
- struct pcmchan_caps ua_playcaps;
- struct pcmchan_caps ua_reccaps;
- int vendor, product, release;
-};
-
-#define UAUDIO_DEFAULT_BUFSZ 16*1024
-
-static const struct {
- int vendor;
- int product;
- int release;
- uint32_t dflags;
-} ua_quirks[] = {
- { 0x1130, 0xf211, 0x0101, SD_F_PSWAPLR },
-};
-
-/************************************************************/
-static void *
-ua_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
-{
- device_t pa_dev;
-
- struct ua_info *sc = devinfo;
- struct ua_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch;
-
- ch->parent = sc;
- ch->channel = c;
- ch->buffer = b;
- ch->dir = dir;
-
- pa_dev = device_get_parent(sc->sc_dev);
-
- ch->buf = malloc(sc->bufsz, M_DEVBUF, M_NOWAIT);
- if (ch->buf == NULL)
- return NULL;
- if (sndbuf_setup(b, ch->buf, sc->bufsz) != 0) {
- free(ch->buf, M_DEVBUF);
- return NULL;
- }
- uaudio_chan_set_param_pcm_dma_buff(pa_dev, ch->buf, ch->buf+sc->bufsz, ch->channel, dir);
- if (bootverbose)
- device_printf(pa_dev, "%s buf %p\n", (dir == PCMDIR_PLAY)?
- "play" : "rec", sndbuf_getbuf(ch->buffer));
-
- ch->dir = dir;
-#ifndef NO_RECORDING
- ch->hwch = 1;
- if (dir == PCMDIR_PLAY)
- ch->hwch = 2;
-#else
- ch->hwch = 2;
-#endif
-
- return ch;
-}
-
-static int
-ua_chan_free(kobj_t obj, void *data)
-{
- struct ua_chinfo *ua = data;
-
- if (ua->buf != NULL)
- free(ua->buf, M_DEVBUF);
- return 0;
-}
-
-static int
-ua_chan_setformat(kobj_t obj, void *data, u_int32_t format)
-{
- device_t pa_dev;
- struct ua_info *ua;
-
- struct ua_chinfo *ch = data;
-
- /*
- * At this point, no need to query as we shouldn't select an unsorted format
- */
- ua = ch->parent;
- pa_dev = device_get_parent(ua->sc_dev);
- uaudio_chan_set_param_format(pa_dev, format, ch->dir);
-
- ch->fmt = format;
- return 0;
-}
-
-static int
-ua_chan_setspeed(kobj_t obj, void *data, u_int32_t speed)
-{
- struct ua_chinfo *ch;
- device_t pa_dev;
- int bestspeed;
-
- ch = data;
- pa_dev = device_get_parent(ch->parent->sc_dev);
-
- if ((bestspeed = uaudio_chan_set_param_speed(pa_dev, speed, ch->dir)))
- ch->spd = bestspeed;
-
- return ch->spd;
-}
-
-static int
-ua_chan_setfragments(kobj_t obj, void *data, u_int32_t blksz, u_int32_t blkcnt)
-{
- device_t pa_dev;
- struct ua_chinfo *ch = data;
- struct ua_info *ua = ch->parent;
-
- RANGE(blksz, 128, sndbuf_getmaxsize(ch->buffer) / 2);
- RANGE(blkcnt, 2, 512);
-
- while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) {
- if ((blkcnt >> 1) >= 2)
- blkcnt >>= 1;
- else if ((blksz >> 1) >= 128)
- blksz >>= 1;
- else
- break;
- }
-
- if ((sndbuf_getblksz(ch->buffer) != blksz ||
- sndbuf_getblkcnt(ch->buffer) != blkcnt) &&
- sndbuf_resize(ch->buffer, blkcnt, blksz) != 0)
- device_printf(ua->sc_dev, "%s: failed blksz=%u blkcnt=%u\n",
- __func__, blksz, blkcnt);
-
- ch->blksz = sndbuf_getblksz(ch->buffer);
-
- pa_dev = device_get_parent(ua->sc_dev);
- uaudio_chan_set_param_pcm_dma_buff(pa_dev, ch->buf,
- ch->buf + sndbuf_getsize(ch->buffer), ch->channel, ch->dir);
- uaudio_chan_set_param_blocksize(pa_dev, ch->blksz, ch->dir);
-
- return 1;
-}
-
-static int
-ua_chan_setblocksize(kobj_t obj, void *data, u_int32_t blksz)
-{
- struct ua_chinfo *ch = data;
-
- ua_chan_setfragments(obj, data, blksz,
- sndbuf_getmaxsize(ch->buffer) / blksz);
-
- return ch->blksz;
-}
-
-static int
-ua_chan_trigger(kobj_t obj, void *data, int go)
-{
- device_t pa_dev;
- struct ua_info *ua;
- struct ua_chinfo *ch = data;
-
- if (!PCMTRIG_COMMON(go))
- return 0;
-
- ua = ch->parent;
- pa_dev = device_get_parent(ua->sc_dev);
-
- /* XXXXX */
- if (ch->dir == PCMDIR_PLAY) {
- if (go == PCMTRIG_START) {
- uaudio_trigger_output(pa_dev);
- } else {
- uaudio_halt_out_dma(pa_dev);
- }
- } else {
-#ifndef NO_RECORDING
- if (go == PCMTRIG_START)
- uaudio_trigger_input(pa_dev);
- else
- uaudio_halt_in_dma(pa_dev);
-#endif
- }
-
- return 0;
-}
-
-static int
-ua_chan_getptr(kobj_t obj, void *data)
-{
- device_t pa_dev;
- struct ua_info *ua;
- struct ua_chinfo *ch = data;
-
- ua = ch->parent;
- pa_dev = device_get_parent(ua->sc_dev);
-
- return uaudio_chan_getptr(pa_dev, ch->dir);
-}
-
-static struct pcmchan_caps *
-ua_chan_getcaps(kobj_t obj, void *data)
-{
- struct ua_chinfo *ch;
-
- ch = data;
- return (ch->dir == PCMDIR_PLAY) ? &(ch->parent->ua_playcaps) : &(ch->parent->ua_reccaps);
-}
-
-static kobj_method_t ua_chan_methods[] = {
- KOBJMETHOD(channel_init, ua_chan_init),
- KOBJMETHOD(channel_free, ua_chan_free),
- KOBJMETHOD(channel_setformat, ua_chan_setformat),
- KOBJMETHOD(channel_setspeed, ua_chan_setspeed),
- KOBJMETHOD(channel_setblocksize, ua_chan_setblocksize),
- KOBJMETHOD(channel_setfragments, ua_chan_setfragments),
- KOBJMETHOD(channel_trigger, ua_chan_trigger),
- KOBJMETHOD(channel_getptr, ua_chan_getptr),
- KOBJMETHOD(channel_getcaps, ua_chan_getcaps),
- { 0, 0 }
-};
-
-CHANNEL_DECLARE(ua_chan);
-
-/************************************************************/
-static int
-ua_mixer_init(struct snd_mixer *m)
-{
- u_int32_t mask;
- device_t pa_dev;
- struct ua_info *ua = mix_getdevinfo(m);
-
- pa_dev = device_get_parent(ua->sc_dev);
-
- mask = uaudio_query_mix_info(pa_dev);
- if (!(mask & SOUND_MASK_PCM)) {
- /*
- * Emulate missing pcm mixer controller
- * through FEEDER_VOLUME
- */
- pcm_setflags(ua->sc_dev, pcm_getflags(ua->sc_dev) |
- SD_F_SOFTPCMVOL);
- }
- if (!(mask & SOUND_MASK_VOLUME)) {
- mix_setparentchild(m, SOUND_MIXER_VOLUME, SOUND_MASK_PCM);
- mix_setrealdev(m, SOUND_MIXER_VOLUME, SOUND_MIXER_NONE);
- }
- mix_setdevs(m, mask);
-
- mask = uaudio_query_recsrc_info(pa_dev);
- mix_setrecdevs(m, mask);
-
- return 0;
-}
-
-static int
-ua_mixer_set(struct snd_mixer *m, unsigned type, unsigned left, unsigned right)
-{
- device_t pa_dev;
- struct ua_info *ua = mix_getdevinfo(m);
-
- pa_dev = device_get_parent(ua->sc_dev);
- uaudio_mixer_set(pa_dev, type, left, right);
-
- return left | (right << 8);
-}
-
-static int
-ua_mixer_setrecsrc(struct snd_mixer *m, u_int32_t src)
-{
- device_t pa_dev;
- struct ua_info *ua = mix_getdevinfo(m);
-
- pa_dev = device_get_parent(ua->sc_dev);
- return uaudio_mixer_setrecsrc(pa_dev, src);
-}
-
-static kobj_method_t ua_mixer_methods[] = {
- KOBJMETHOD(mixer_init, ua_mixer_init),
- KOBJMETHOD(mixer_set, ua_mixer_set),
- KOBJMETHOD(mixer_setrecsrc, ua_mixer_setrecsrc),
-
- { 0, 0 }
-};
-MIXER_DECLARE(ua_mixer);
-/************************************************************/
-
-
-static int
-ua_probe(device_t dev)
-{
- char *s;
- struct sndcard_func *func;
-
- /* The parent device has already been probed. */
-
- func = device_get_ivars(dev);
- if (func == NULL || func->func != SCF_PCM)
- return (ENXIO);
-
- s = "USB Audio";
-
- device_set_desc(dev, s);
- return BUS_PROBE_DEFAULT;
-}
-
-static int
-ua_attach(device_t dev)
-{
- struct ua_info *ua;
- struct sndcard_func *func;
- char status[SND_STATUSLEN];
- device_t pa_dev;
- u_int32_t nplay, nrec, flags;
- int i;
-
- ua = malloc(sizeof(*ua), M_DEVBUF, M_WAITOK | M_ZERO);
- ua->sc_dev = dev;
-
- /* Mark for existence */
- func = device_get_ivars(dev);
- if (func != NULL)
- func->varinfo = (void *)ua;
-
- pa_dev = device_get_parent(dev);
- ua->vendor = uaudio_get_vendor(pa_dev);
- ua->product = uaudio_get_product(pa_dev);
- ua->release = uaudio_get_release(pa_dev);
-
- if (bootverbose)
- device_printf(dev,
- "USB Audio: "
- "vendor=0x%04x, product=0x%04x, release=0x%04x\n",
- ua->vendor, ua->product, ua->release);
-
- ua->bufsz = pcm_getbuffersize(dev, 4096, UAUDIO_DEFAULT_BUFSZ, 65536);
- if (bootverbose)
- device_printf(dev, "using a default buffer size of %jd\n", (intmax_t)ua->bufsz);
-
- if (mixer_init(dev, &ua_mixer_class, ua)) {
- goto bad;
- }
-
- snprintf(status, SND_STATUSLEN, "at ? %s", PCM_KLDSTRING(snd_uaudio));
-
- ua->ua_playcaps.fmtlist = ua->ua_playfmt;
- ua->ua_reccaps.fmtlist = ua->ua_recfmt;
- nplay = uaudio_query_formats(pa_dev, PCMDIR_PLAY, FORMAT_NUM * 2, &ua->ua_playcaps);
- nrec = uaudio_query_formats(pa_dev, PCMDIR_REC, FORMAT_NUM * 2, &ua->ua_reccaps);
-
- if (nplay > 1)
- nplay = 1;
- if (nrec > 1)
- nrec = 1;
-
- flags = pcm_getflags(dev);
- for (i = 0; i < (sizeof(ua_quirks) / sizeof(ua_quirks[0])); i++) {
- if (ua->vendor == ua_quirks[i].vendor &&
- ua->product == ua_quirks[i].product &&
- ua->release == ua_quirks[i].release)
- flags |= ua_quirks[i].dflags;
- }
- pcm_setflags(dev, flags);
-
-#ifndef NO_RECORDING
- if (pcm_register(dev, ua, nplay, nrec)) {
-#else
- if (pcm_register(dev, ua, nplay, 0)) {
-#endif
- goto bad;
- }
-
- sndstat_unregister(dev);
- uaudio_sndstat_register(dev);
-
- for (i = 0; i < nplay; i++) {
- pcm_addchan(dev, PCMDIR_PLAY, &ua_chan_class, ua);
- }
-#ifndef NO_RECORDING
- for (i = 0; i < nrec; i++) {
- pcm_addchan(dev, PCMDIR_REC, &ua_chan_class, ua);
- }
-#endif
- pcm_setstatus(dev, status);
-
- return 0;
-
-bad: free(ua, M_DEVBUF);
- return ENXIO;
-}
-
-static int
-ua_detach(device_t dev)
-{
- struct ua_info *sc;
- struct sndcard_func *func;
- int r;
-
- r = pcm_unregister(dev);
- if (r)
- return r;
-
- sc = pcm_getdevinfo(dev);
- free(sc, M_DEVBUF);
-
- /* Mark for deletion */
- func = device_get_ivars(dev);
- if (func != NULL)
- func->varinfo = NULL;
-
- return 0;
-}
-
-/************************************************************/
-
-static device_method_t ua_pcm_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ua_probe),
- DEVMETHOD(device_attach, ua_attach),
- DEVMETHOD(device_detach, ua_detach),
-
- { 0, 0 }
-};
-
-static driver_t ua_pcm_driver = {
- "pcm",
- ua_pcm_methods,
- PCM_SOFTC_SIZE,
-};
-
-
-DRIVER_MODULE(ua_pcm, uaudio, ua_pcm_driver, pcm_devclass, 0, 0);
-MODULE_DEPEND(ua_pcm, uaudio, 1, 1, 1);
-MODULE_DEPEND(ua_pcm, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
-MODULE_VERSION(ua_pcm, 1);
diff --git a/sys/legacy/dev/sound/usb/uaudioreg.h b/sys/legacy/dev/sound/usb/uaudioreg.h
deleted file mode 100644
index 3cc09ba..0000000
--- a/sys/legacy/dev/sound/usb/uaudioreg.h
+++ /dev/null
@@ -1,404 +0,0 @@
-/* $NetBSD: uaudioreg.h,v 1.12 2004/11/05 19:08:29 kent Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1999 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define UAUDIO_VERSION 0x100
-
-#define UDESC_CS_CONFIG 0x22
-#define UDESC_CS_STRING 0x23
-#define UDESC_CS_INTERFACE 0x24
-#define UDESC_CS_ENDPOINT 0x25
-
-#define UDESCSUB_AC_HEADER 1
-#define UDESCSUB_AC_INPUT 2
-#define UDESCSUB_AC_OUTPUT 3
-#define UDESCSUB_AC_MIXER 4
-#define UDESCSUB_AC_SELECTOR 5
-#define UDESCSUB_AC_FEATURE 6
-#define UDESCSUB_AC_PROCESSING 7
-#define UDESCSUB_AC_EXTENSION 8
-
-/* The first fields are identical to usb_endpoint_descriptor_t */
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bEndpointAddress;
- uByte bmAttributes;
- uWord wMaxPacketSize;
- uByte bInterval;
- /*
- * The following two entries are only used by the Audio Class.
- * And according to the specs the Audio Class is the only one
- * allowed to extend the endpoint descriptor.
- * Who knows what goes on in the minds of the people in the USB
- * standardization? :-(
- */
- uByte bRefresh;
- uByte bSynchAddress;
-} UPACKED usb_endpoint_descriptor_audio_t;
-
-struct usb_audio_control_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uWord bcdADC;
- uWord wTotalLength;
- uByte bInCollection;
- uByte baInterfaceNr[1];
-} UPACKED;
-
-struct usb_audio_streaming_interface_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bTerminalLink;
- uByte bDelay;
- uWord wFormatTag;
-} UPACKED;
-
-struct usb_audio_streaming_endpoint_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bmAttributes;
-#define UA_SED_FREQ_CONTROL 0x01
-#define UA_SED_PITCH_CONTROL 0x02
-#define UA_SED_MAXPACKETSONLY 0x80
- uByte bLockDelayUnits;
- uWord wLockDelay;
-} UPACKED;
-
-struct usb_audio_streaming_type1_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bFormatType;
- uByte bNrChannels;
- uByte bSubFrameSize;
- uByte bBitResolution;
- uByte bSamFreqType;
-#define UA_SAMP_CONTNUOUS 0
- uByte tSamFreq[3*2]; /* room for low and high */
-#define UA_GETSAMP(p, n) ((p)->tSamFreq[(n)*3+0] | ((p)->tSamFreq[(n)*3+1] << 8) | ((p)->tSamFreq[(n)*3+2] << 16))
-#define UA_SAMP_LO(p) UA_GETSAMP(p, 0)
-#define UA_SAMP_HI(p) UA_GETSAMP(p, 1)
-} UPACKED;
-
-struct usb_audio_cluster {
- uByte bNrChannels;
- uWord wChannelConfig;
-#define UA_CHANNEL_LEFT 0x0001
-#define UA_CHANNEL_RIGHT 0x0002
-#define UA_CHANNEL_CENTER 0x0004
-#define UA_CHANNEL_LFE 0x0008
-#define UA_CHANNEL_L_SURROUND 0x0010
-#define UA_CHANNEL_R_SURROUND 0x0020
-#define UA_CHANNEL_L_CENTER 0x0040
-#define UA_CHANNEL_R_CENTER 0x0080
-#define UA_CHANNEL_SURROUND 0x0100
-#define UA_CHANNEL_L_SIDE 0x0200
-#define UA_CHANNEL_R_SIDE 0x0400
-#define UA_CHANNEL_TOP 0x0800
- uByte iChannelNames;
-} UPACKED;
-
-/* Shared by all units and terminals */
-struct usb_audio_unit {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
-};
-
-/* UDESCSUB_AC_INPUT */
-struct usb_audio_input_terminal {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bTerminalId;
- uWord wTerminalType;
- uByte bAssocTerminal;
- uByte bNrChannels;
- uWord wChannelConfig;
- uByte iChannelNames;
- uByte iTerminal;
-} UPACKED;
-
-/* UDESCSUB_AC_OUTPUT */
-struct usb_audio_output_terminal {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bTerminalId;
- uWord wTerminalType;
- uByte bAssocTerminal;
- uByte bSourceId;
- uByte iTerminal;
-} UPACKED;
-
-/* UDESCSUB_AC_MIXER */
-struct usb_audio_mixer_unit {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
- uByte bNrInPins;
- uByte baSourceId[255]; /* [bNrInPins] */
- /* struct usb_audio_mixer_unit_1 */
-} UPACKED;
-struct usb_audio_mixer_unit_1 {
- uByte bNrChannels;
- uWord wChannelConfig;
- uByte iChannelNames;
- uByte bmControls[255]; /* [bNrChannels] */
- /*uByte iMixer;*/
-} UPACKED;
-
-/* UDESCSUB_AC_SELECTOR */
-struct usb_audio_selector_unit {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
- uByte bNrInPins;
- uByte baSourceId[255]; /* [bNrInPins] */
- /* uByte iSelector; */
-} UPACKED;
-
-/* UDESCSUB_AC_FEATURE */
-struct usb_audio_feature_unit {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
- uByte bSourceId;
- uByte bControlSize;
- uByte bmaControls[255]; /* size for more than enough */
- /* uByte iFeature; */
-} UPACKED;
-
-/* UDESCSUB_AC_PROCESSING */
-struct usb_audio_processing_unit {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
- uWord wProcessType;
- uByte bNrInPins;
- uByte baSourceId[255]; /* [bNrInPins] */
- /* struct usb_audio_processing_unit_1 */
-} UPACKED;
-struct usb_audio_processing_unit_1{
- uByte bNrChannels;
- uWord wChannelConfig;
- uByte iChannelNames;
- uByte bControlSize;
- uByte bmControls[255]; /* [bControlSize] */
-#define UA_PROC_ENABLE_MASK 1
-} UPACKED;
-
-struct usb_audio_processing_unit_updown {
- uByte iProcessing;
- uByte bNrModes;
- uWord waModes[255]; /* [bNrModes] */
-} UPACKED;
-
-/* UDESCSUB_AC_EXTENSION */
-struct usb_audio_extension_unit {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
- uWord wExtensionCode;
- uByte bNrInPins;
- uByte baSourceId[255]; /* [bNrInPins] */
- /* struct usb_audio_extension_unit_1 */
-} UPACKED;
-struct usb_audio_extension_unit_1 {
- uByte bNrChannels;
- uWord wChannelConfig;
- uByte iChannelNames;
- uByte bControlSize;
- uByte bmControls[255]; /* [bControlSize] */
-#define UA_EXT_ENABLE_MASK 1
-#define UA_EXT_ENABLE 1
- /*uByte iExtension;*/
-} UPACKED;
-
-/* USB terminal types */
-#define UAT_UNDEFINED 0x0100
-#define UAT_STREAM 0x0101
-#define UAT_VENDOR 0x01ff
-/* input terminal types */
-#define UATI_UNDEFINED 0x0200
-#define UATI_MICROPHONE 0x0201
-#define UATI_DESKMICROPHONE 0x0202
-#define UATI_PERSONALMICROPHONE 0x0203
-#define UATI_OMNIMICROPHONE 0x0204
-#define UATI_MICROPHONEARRAY 0x0205
-#define UATI_PROCMICROPHONEARR 0x0206
-/* output terminal types */
-#define UATO_UNDEFINED 0x0300
-#define UATO_SPEAKER 0x0301
-#define UATO_HEADPHONES 0x0302
-#define UATO_DISPLAYAUDIO 0x0303
-#define UATO_DESKTOPSPEAKER 0x0304
-#define UATO_ROOMSPEAKER 0x0305
-#define UATO_COMMSPEAKER 0x0306
-#define UATO_SUBWOOFER 0x0307
-/* bidir terminal types */
-#define UATB_UNDEFINED 0x0400
-#define UATB_HANDSET 0x0401
-#define UATB_HEADSET 0x0402
-#define UATB_SPEAKERPHONE 0x0403
-#define UATB_SPEAKERPHONEESUP 0x0404
-#define UATB_SPEAKERPHONEECANC 0x0405
-/* telephony terminal types */
-#define UATT_UNDEFINED 0x0500
-#define UATT_PHONELINE 0x0501
-#define UATT_TELEPHONE 0x0502
-#define UATT_DOWNLINEPHONE 0x0503
-/* external terminal types */
-#define UATE_UNDEFINED 0x0600
-#define UATE_ANALOGCONN 0x0601
-#define UATE_DIGITALAUIFC 0x0602
-#define UATE_LINECONN 0x0603
-#define UATE_LEGACYCONN 0x0604
-#define UATE_SPDIF 0x0605
-#define UATE_1394DA 0x0606
-#define UATE_1394DV 0x0607
-/* embedded function terminal types */
-#define UATF_UNDEFINED 0x0700
-#define UATF_CALIBNOISE 0x0701
-#define UATF_EQUNOISE 0x0702
-#define UATF_CDPLAYER 0x0703
-#define UATF_DAT 0x0704
-#define UATF_DCC 0x0705
-#define UATF_MINIDISK 0x0706
-#define UATF_ANALOGTAPE 0x0707
-#define UATF_PHONOGRAPH 0x0708
-#define UATF_VCRAUDIO 0x0709
-#define UATF_VIDEODISCAUDIO 0x070a
-#define UATF_DVDAUDIO 0x070b
-#define UATF_TVTUNERAUDIO 0x070c
-#define UATF_SATELLITE 0x070d
-#define UATF_CABLETUNER 0x070e
-#define UATF_DSS 0x070f
-#define UATF_RADIORECV 0x0710
-#define UATF_RADIOXMIT 0x0711
-#define UATF_MULTITRACK 0x0712
-#define UATF_SYNTHESIZER 0x0713
-
-
-#define SET_CUR 0x01
-#define GET_CUR 0x81
-#define SET_MIN 0x02
-#define GET_MIN 0x82
-#define SET_MAX 0x03
-#define GET_MAX 0x83
-#define SET_RES 0x04
-#define GET_RES 0x84
-#define SET_MEM 0x05
-#define GET_MEM 0x85
-#define GET_STAT 0xff
-
-#define MUTE_CONTROL 0x01
-#define VOLUME_CONTROL 0x02
-#define BASS_CONTROL 0x03
-#define MID_CONTROL 0x04
-#define TREBLE_CONTROL 0x05
-#define GRAPHIC_EQUALIZER_CONTROL 0x06
-#define AGC_CONTROL 0x07
-#define DELAY_CONTROL 0x08
-#define BASS_BOOST_CONTROL 0x09
-#define LOUDNESS_CONTROL 0x0a
-
-#define FU_MASK(u) (1 << ((u)-1))
-
-#define MASTER_CHAN 0
-
-#define AS_GENERAL 1
-#define FORMAT_TYPE 2
-#define FORMAT_SPECIFIC 3
-
-#define UA_FMT_PCM 1
-#define UA_FMT_PCM8 2
-#define UA_FMT_IEEE_FLOAT 3
-#define UA_FMT_ALAW 4
-#define UA_FMT_MULAW 5
-#define UA_FMT_MPEG 0x1001
-#define UA_FMT_AC3 0x1002
-
-#define SAMPLING_FREQ_CONTROL 0x01
-#define PITCH_CONTROL 0x02
-
-#define FORMAT_TYPE_UNDEFINED 0
-#define FORMAT_TYPE_I 1
-#define FORMAT_TYPE_II 2
-#define FORMAT_TYPE_III 3
-
-#define UA_PROC_MASK(n) (1<< ((n)-1))
-#define PROCESS_UNDEFINED 0
-#define XX_ENABLE_CONTROL 1
-#define UPDOWNMIX_PROCESS 1
-#define UD_ENABLE_CONTROL 1
-#define UD_MODE_SELECT_CONTROL 2
-#define DOLBY_PROLOGIC_PROCESS 2
-#define DP_ENABLE_CONTROL 1
-#define DP_MODE_SELECT_CONTROL 2
-#define P3D_STEREO_EXTENDER_PROCESS 3
-#define P3D_ENABLE_CONTROL 1
-#define P3D_SPACIOUSNESS_CONTROL 2
-#define REVERBATION_PROCESS 4
-#define RV_ENABLE_CONTROL 1
-#define RV_LEVEL_CONTROL 2
-#define RV_TIME_CONTROL 3
-#define RV_FEEDBACK_CONTROL 4
-#define CHORUS_PROCESS 5
-#define CH_ENABLE_CONTROL 1
-#define CH_LEVEL_CONTROL 2
-#define CH_RATE_CONTROL 3
-#define CH_DEPTH_CONTROL 4
-#define DYN_RANGE_COMP_PROCESS 6
-#define DR_ENABLE_CONTROL 1
-#define DR_COMPRESSION_RATE_CONTROL 2
-#define DR_MAXAMPL_CONTROL 3
-#define DR_THRESHOLD_CONTROL 4
-#define DR_ATTACK_TIME_CONTROL 5
-#define DR_RELEASE_TIME_CONTROL 6
diff --git a/sys/legacy/dev/usb/FILES b/sys/legacy/dev/usb/FILES
deleted file mode 100644
index 5a77cbd..0000000
--- a/sys/legacy/dev/usb/FILES
+++ /dev/null
@@ -1,52 +0,0 @@
-$FreeBSD$
-
-A small roadmap of the USB files:
-
-FILES this file
-dsbr100io.h API for ufm.c
-ehci.c Host controller driver for EHCI
-ehcireg.h Hardware definitions for EHCI
-ehcivar.h API for ehci.c
-hid.c subroutines to parse and access HID data
-hid.h API for hid.c
-if_aue.c USB Pegasus Ethernet driver
-if_auereg.h and definitions for it
-if_axe.c USB ASIX Electronics Ethernet driver
-if_axereg.h and definitions for it
-if_cue.c USB CATC Ethernet driver
-if_cuereg.h and definitions for it
-if_kue.c USB Kawasaki Ethernet driver
-if_kuereg.h and definitions for it
-ohci.c Host controller driver for OHCI
-ohcireg.h Hardware definitions for OHCI
-ohcivar.h API for ohci.c
-ufm.c USB fm radio driver
-[Merged] ugen.c generic driver that can handle access to any USB device
-uhci.c Host controller driver for UHCI
-uhcireg.h Hardware definitions for UHCI
-uhcivar.h API for uhci.c
-uhid.c USB HID class driver
-uhub.c USB hub driver
-ukbd.c USB keyboard driver
-ulpt.c USB printer class driver
-umass.c USB mass storage driver
-umodem.c USB modem (CDC ACM) driver
-ums.c USB mouse driver
-urio.c USB Diamond Rio500 driver
-usb.c usb (bus) device driver
-usb.h general USB defines
-usb_mem.c memory allocation for DMAable memory
-usb_mem.h API for usb_mem.c
-usb_port.h compatibility defines for different OSs
-usb_quirks.c table of non-conforming USB devices and their problems
-usb_quirks.h API for usb_quirks.c
-usb_subr.c various subroutines used by USB code
-usbcdc.h USB CDC class definitions
-usbdevs data base of known device
-usbdi.c implementation of the USBDI API, which all drivers use
-usbdi.h API for usbdi.c
-usbdi_util.c utilities built on top of usbdi.h
-usbdi_util.h API for usbdi_util.c
-usbdivar.h internal defines and structures for usbdi.c
-uscanner.c minimal USB scanner driver
-usbhid.h USB HID class definitions
diff --git a/sys/legacy/dev/usb/dsbr100io.h b/sys/legacy/dev/usb/dsbr100io.h
deleted file mode 100644
index f1c8a97..0000000
--- a/sys/legacy/dev/usb/dsbr100io.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * Copyright (c) 2001 M. Warner Losh
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This code is based on ugen.c and ulpt.c developed by Lennart Augustsson.
- * This code includes software developed by the NetBSD Foundation, Inc. and
- * its contributors.
- */
-
-/* $FreeBSD$ */
-
-#include <sys/ioccom.h>
-
-#define FM_SET_FREQ _IOWR('U', 200, int)
-#define FM_GET_FREQ _IOWR('U', 201, int)
-#define FM_START _IOWR('U', 202, int)
-#define FM_STOP _IOWR('U', 203, int)
-#define FM_GET_STAT _IOWR('U', 204, int)
diff --git a/sys/legacy/dev/usb/ehci.c b/sys/legacy/dev/usb/ehci.c
deleted file mode 100644
index c159600..0000000
--- a/sys/legacy/dev/usb/ehci.c
+++ /dev/null
@@ -1,3932 +0,0 @@
-/* $NetBSD: ehci.c,v 1.91 2005/02/27 00:27:51 perry Exp $ */
-
-/*-
- * Copyright (c) 2004 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) and by Charles M. Hannum.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
- *
- * The EHCI 1.0 spec can be found at
- * http://developer.intel.com/technology/usb/download/ehci-r10.pdf
- * and the USB 2.0 spec at
- * http://www.usb.org/developers/docs/usb_20.zip
- *
- */
-
-/*
- * TODO:
- * 1) The EHCI driver lacks support for isochronous transfers, so
- * devices using them don't work.
- *
- * 2) Interrupt transfer scheduling does not manage the time available
- * in each frame, so it is possible for the transfers to overrun
- * the end of the frame.
- *
- * 3) Command failures are not recovered correctly.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/endian.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/lock.h>
-#include <sys/lockmgr.h>
-#if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
-#include <machine/cpu.h>
-#endif
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-#include <machine/endian.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ehcireg.h>
-#include <dev/usb/ehcivar.h>
-
-#define delay(d) DELAY(d)
-
-#ifdef USB_DEBUG
-#define EHCI_DEBUG USB_DEBUG
-#define DPRINTF(x) do { if (ehcidebug) printf x; } while (0)
-#define DPRINTFN(n,x) do { if (ehcidebug>(n)) printf x; } while (0)
-int ehcidebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci");
-SYSCTL_INT(_hw_usb_ehci, OID_AUTO, debug, CTLFLAG_RW,
- &ehcidebug, 0, "ehci debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct ehci_pipe {
- struct usbd_pipe pipe;
-
- ehci_soft_qh_t *sqh;
- union {
- ehci_soft_qtd_t *qtd;
- /* ehci_soft_itd_t *itd; */
- } tail;
- union {
- /* Control pipe */
- struct {
- usb_dma_t reqdma;
- u_int length;
- /*ehci_soft_qtd_t *setup, *data, *stat;*/
- } ctl;
- /* Interrupt pipe */
- struct {
- u_int length;
- } intr;
- /* Bulk pipe */
- struct {
- u_int length;
- } bulk;
- /* Iso pipe */
- struct {
- u_int next_frame;
- u_int cur_xfers;
- } isoc;
- } u;
-};
-
-static usbd_status ehci_open(usbd_pipe_handle);
-static void ehci_poll(struct usbd_bus *);
-static void ehci_softintr(void *);
-static int ehci_intr1(ehci_softc_t *);
-static void ehci_waitintr(ehci_softc_t *, usbd_xfer_handle);
-static void ehci_check_intr(ehci_softc_t *, struct ehci_xfer *);
-static void ehci_check_qh_intr(ehci_softc_t *, struct ehci_xfer *);
-static void ehci_check_itd_intr(ehci_softc_t *, struct ehci_xfer *);
-static void ehci_idone(struct ehci_xfer *);
-static void ehci_timeout(void *);
-static void ehci_timeout_task(void *);
-static void ehci_intrlist_timeout(void *);
-
-static usbd_status ehci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
-static void ehci_freem(struct usbd_bus *, usb_dma_t *);
-
-static usbd_xfer_handle ehci_allocx(struct usbd_bus *);
-static void ehci_freex(struct usbd_bus *, usbd_xfer_handle);
-
-static usbd_status ehci_root_ctrl_transfer(usbd_xfer_handle);
-static usbd_status ehci_root_ctrl_start(usbd_xfer_handle);
-static void ehci_root_ctrl_abort(usbd_xfer_handle);
-static void ehci_root_ctrl_close(usbd_pipe_handle);
-static void ehci_root_ctrl_done(usbd_xfer_handle);
-
-static usbd_status ehci_root_intr_transfer(usbd_xfer_handle);
-static usbd_status ehci_root_intr_start(usbd_xfer_handle);
-static void ehci_root_intr_abort(usbd_xfer_handle);
-static void ehci_root_intr_close(usbd_pipe_handle);
-static void ehci_root_intr_done(usbd_xfer_handle);
-
-static usbd_status ehci_device_ctrl_transfer(usbd_xfer_handle);
-static usbd_status ehci_device_ctrl_start(usbd_xfer_handle);
-static void ehci_device_ctrl_abort(usbd_xfer_handle);
-static void ehci_device_ctrl_close(usbd_pipe_handle);
-static void ehci_device_ctrl_done(usbd_xfer_handle);
-
-static usbd_status ehci_device_bulk_transfer(usbd_xfer_handle);
-static usbd_status ehci_device_bulk_start(usbd_xfer_handle);
-static void ehci_device_bulk_abort(usbd_xfer_handle);
-static void ehci_device_bulk_close(usbd_pipe_handle);
-static void ehci_device_bulk_done(usbd_xfer_handle);
-
-static usbd_status ehci_device_intr_transfer(usbd_xfer_handle);
-static usbd_status ehci_device_intr_start(usbd_xfer_handle);
-static void ehci_device_intr_abort(usbd_xfer_handle);
-static void ehci_device_intr_close(usbd_pipe_handle);
-static void ehci_device_intr_done(usbd_xfer_handle);
-
-static usbd_status ehci_device_isoc_transfer(usbd_xfer_handle);
-static usbd_status ehci_device_isoc_start(usbd_xfer_handle);
-static void ehci_device_isoc_abort(usbd_xfer_handle);
-static void ehci_device_isoc_close(usbd_pipe_handle);
-static void ehci_device_isoc_done(usbd_xfer_handle);
-
-static void ehci_device_clear_toggle(usbd_pipe_handle pipe);
-static void ehci_noop(usbd_pipe_handle pipe);
-
-static int ehci_str(usb_string_descriptor_t *, int, char *);
-static void ehci_pcd(ehci_softc_t *, usbd_xfer_handle);
-static void ehci_disown(ehci_softc_t *, int, int);
-
-static ehci_soft_qh_t *ehci_alloc_sqh(ehci_softc_t *);
-static void ehci_free_sqh(ehci_softc_t *, ehci_soft_qh_t *);
-
-static ehci_soft_qtd_t *ehci_alloc_sqtd(ehci_softc_t *);
-static void ehci_free_sqtd(ehci_softc_t *, ehci_soft_qtd_t *);
-static usbd_status ehci_alloc_sqtd_chain(struct ehci_pipe *,
- ehci_softc_t *, int, int, usbd_xfer_handle,
- ehci_soft_qtd_t *, ehci_soft_qtd_t *,
- ehci_soft_qtd_t **, ehci_soft_qtd_t **);
-static void ehci_free_sqtd_chain(ehci_softc_t *, ehci_soft_qh_t *,
- ehci_soft_qtd_t *, ehci_soft_qtd_t *);
-
-static ehci_soft_itd_t *ehci_alloc_itd(ehci_softc_t *);
-static void ehci_free_itd(ehci_softc_t *, ehci_soft_itd_t *);
-static void ehci_rem_free_itd_chain(ehci_softc_t *,
- struct ehci_xfer *);
-static void ehci_abort_isoc_xfer(usbd_xfer_handle, usbd_status);
-
-static usbd_status ehci_device_request(usbd_xfer_handle xfer);
-
-static usbd_status ehci_device_setintr(ehci_softc_t *, ehci_soft_qh_t *,
- int ival);
-
-static void ehci_add_qh(ehci_softc_t *, ehci_soft_qh_t *,
- ehci_soft_qh_t *);
-static void ehci_rem_qh(ehci_softc_t *, ehci_soft_qh_t *,
- ehci_soft_qh_t *);
-static void ehci_activate_qh(ehci_softc_t *sc, ehci_soft_qh_t *,
- ehci_soft_qtd_t *);
-static void ehci_sync_hc(ehci_softc_t *);
-
-static void ehci_close_pipe(usbd_pipe_handle, ehci_soft_qh_t *);
-static void ehci_abort_xfer(usbd_xfer_handle, usbd_status);
-
-ehci_softc_t *theehci;
-
-#define EHCI_NULL(sc) htohc32(sc, EHCI_LINK_TERMINATE)
-
-#define EHCI_INTR_ENDPT 1
-
-#define ehci_add_intr_list(sc, ex) \
- LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ex), inext);
-#define ehci_del_intr_list(ex) \
- do { \
- LIST_REMOVE((ex), inext); \
- (ex)->inext.le_prev = NULL; \
- } while (0)
-#define ehci_active_intr_list(ex) ((ex)->inext.le_prev != NULL)
-
-static struct usbd_bus_methods ehci_bus_methods = {
- ehci_open,
- ehci_softintr,
- ehci_poll,
- ehci_allocm,
- ehci_freem,
- ehci_allocx,
- ehci_freex,
-};
-
-static struct usbd_pipe_methods ehci_root_ctrl_methods = {
- ehci_root_ctrl_transfer,
- ehci_root_ctrl_start,
- ehci_root_ctrl_abort,
- ehci_root_ctrl_close,
- ehci_noop,
- ehci_root_ctrl_done,
-};
-
-static struct usbd_pipe_methods ehci_root_intr_methods = {
- ehci_root_intr_transfer,
- ehci_root_intr_start,
- ehci_root_intr_abort,
- ehci_root_intr_close,
- ehci_noop,
- ehci_root_intr_done,
-};
-
-static struct usbd_pipe_methods ehci_device_ctrl_methods = {
- ehci_device_ctrl_transfer,
- ehci_device_ctrl_start,
- ehci_device_ctrl_abort,
- ehci_device_ctrl_close,
- ehci_noop,
- ehci_device_ctrl_done,
-};
-
-static struct usbd_pipe_methods ehci_device_intr_methods = {
- ehci_device_intr_transfer,
- ehci_device_intr_start,
- ehci_device_intr_abort,
- ehci_device_intr_close,
- ehci_device_clear_toggle,
- ehci_device_intr_done,
-};
-
-static struct usbd_pipe_methods ehci_device_bulk_methods = {
- ehci_device_bulk_transfer,
- ehci_device_bulk_start,
- ehci_device_bulk_abort,
- ehci_device_bulk_close,
- ehci_device_clear_toggle,
- ehci_device_bulk_done,
-};
-
-static struct usbd_pipe_methods ehci_device_isoc_methods = {
- ehci_device_isoc_transfer,
- ehci_device_isoc_start,
- ehci_device_isoc_abort,
- ehci_device_isoc_close,
- ehci_noop,
- ehci_device_isoc_done,
-};
-
-usbd_status
-ehci_reset(ehci_softc_t *sc)
-{
- u_int32_t hcr;
- u_int i;
-
- EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
- for (i = 0; i < 100; i++) {
- usb_delay_ms(&sc->sc_bus, 1);
- hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET;
- if (!hcr) {
- if (sc->sc_flags & (EHCI_SCFLG_SETMODE | EHCI_SCFLG_BIGEMMIO)) {
- /*
- * Force USBMODE as requested. Controllers
- * may have multiple operating modes.
- */
- uint32_t usbmode = EOREAD4(sc, EHCI_USBMODE);
- if (sc->sc_flags & EHCI_SCFLG_SETMODE) {
- usbmode = (usbmode &~ EHCI_UM_CM) | EHCI_UM_CM_HOST;
- device_printf(sc->sc_bus.bdev,
- "set host controller mode\n");
- }
- if (sc->sc_flags & EHCI_SCFLG_BIGEMMIO) {
- usbmode = (usbmode &~ EHCI_UM_ES) | EHCI_UM_ES_BE;
- device_printf(sc->sc_bus.bdev,
- "set big-endian mode\n");
- }
- EOWRITE4(sc, EHCI_USBMODE, usbmode);
- }
- return (USBD_NORMAL_COMPLETION);
- }
- }
- printf("%s: reset timeout\n", device_get_nameunit(sc->sc_bus.bdev));
- return (USBD_IOERROR);
-}
-
-static usbd_status
-ehci_hcreset(ehci_softc_t *sc)
-{
- u_int32_t hcr;
- u_int i;
-
- EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */
- for (i = 0; i < 100; i++) {
- usb_delay_ms(&sc->sc_bus, 1);
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (hcr)
- break;
- }
- if (!hcr)
- /*
- * Fall through and try reset anyway even though
- * Table 2-9 in the EHCI spec says this will result
- * in undefined behavior.
- */
- device_printf(sc->sc_bus.bdev, "stop timeout\n");
-
- return ehci_reset(sc);
-}
-
-usbd_status
-ehci_init(ehci_softc_t *sc)
-{
- u_int32_t version, sparams, cparams, hcr;
- u_int i;
- usbd_status err;
- ehci_soft_qh_t *sqh;
- u_int ncomp;
- int lev;
-
- DPRINTF(("ehci_init: start\n"));
-#ifdef EHCI_DEBUG
- theehci = sc;
-#endif
-
- /* NB: must handle byte-order manually before ehci_hcreset */
-
- sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
-
- version = EREAD2(sc, EHCI_HCIVERSION);
- device_printf(sc->sc_bus.bdev, "EHCI version %x.%x\n",
- version >> 8, version & 0xff);
-
- sparams = EREAD4(sc, EHCI_HCSPARAMS);
- DPRINTF(("ehci_init: sparams=0x%x\n", sparams));
- sc->sc_npcomp = EHCI_HCS_N_PCC(sparams);
- ncomp = EHCI_HCS_N_CC(sparams);
- if (ncomp != sc->sc_ncomp) {
- printf("%s: wrong number of companions (%d != %d)\n",
- device_get_nameunit(sc->sc_bus.bdev),
- ncomp, sc->sc_ncomp);
- if (ncomp < sc->sc_ncomp)
- sc->sc_ncomp = ncomp;
- }
- if (sc->sc_ncomp > 0) {
- printf("%s: companion controller%s, %d port%s each:",
- device_get_nameunit(sc->sc_bus.bdev), sc->sc_ncomp!=1 ? "s" : "",
- EHCI_HCS_N_PCC(sparams),
- EHCI_HCS_N_PCC(sparams)!=1 ? "s" : "");
- for (i = 0; i < sc->sc_ncomp; i++)
- printf(" %s", device_get_nameunit(sc->sc_comps[i]->bdev));
- printf("\n");
- }
- sc->sc_noport = EHCI_HCS_N_PORTS(sparams);
- cparams = EREAD4(sc, EHCI_HCCPARAMS);
- DPRINTF(("ehci_init: cparams=0x%x\n", cparams));
-
- if (EHCI_HCC_64BIT(cparams)) {
- /* MUST clear segment register if 64 bit capable. */
- EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
- }
-
- sc->sc_bus.usbrev = USBREV_2_0;
-
- /* Reset the controller */
- DPRINTF(("%s: resetting\n", device_get_nameunit(sc->sc_bus.bdev)));
- err = ehci_hcreset(sc);
- if (err != USBD_NORMAL_COMPLETION)
- return (err);
-
- /* frame list size at default, read back what we got and use that */
- switch (EHCI_CMD_FLS(EOREAD4(sc, EHCI_USBCMD))) {
- case 0: sc->sc_flsize = 1024; break;
- case 1: sc->sc_flsize = 512; break;
- case 2: sc->sc_flsize = 256; break;
- case 3: return (USBD_IOERROR);
- }
- err = usb_allocmem(&sc->sc_bus, sc->sc_flsize * sizeof(ehci_link_t),
- EHCI_FLALIGN_ALIGN, &sc->sc_fldma);
- if (err)
- return (err);
- DPRINTF(("%s: flsize=%d\n", device_get_nameunit(sc->sc_bus.bdev),sc->sc_flsize));
- sc->sc_flist = KERNADDR(&sc->sc_fldma, 0);
-
- for (i = 0; i < sc->sc_flsize; i++) {
- sc->sc_flist[i] = EHCI_NULL(sc);
- }
-
- EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
-
- sc->sc_softitds = malloc(sc->sc_flsize * sizeof(ehci_soft_itd_t *),
- M_USB, M_NOWAIT | M_ZERO);
- if (sc->sc_softitds == NULL)
- return (ENOMEM);
- LIST_INIT(&sc->sc_freeitds);
-
- /* Set up the bus struct. */
- sc->sc_bus.methods = &ehci_bus_methods;
- sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
-
- sc->sc_eintrs = EHCI_NORMAL_INTRS;
-
- /*
- * Allocate the interrupt dummy QHs. These are arranged to give
- * poll intervals that are powers of 2 times 1ms.
- */
- for (i = 0; i < EHCI_INTRQHS; i++) {
- sqh = ehci_alloc_sqh(sc);
- if (sqh == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- sc->sc_islots[i].sqh = sqh;
- }
- lev = 0;
- for (i = 0; i < EHCI_INTRQHS; i++) {
- if (i == EHCI_IQHIDX(lev + 1, 0))
- lev++;
- sqh = sc->sc_islots[i].sqh;
- if (i == 0) {
- /* The last (1ms) QH terminates. */
- sqh->qh.qh_link = EHCI_NULL(sc);
- sqh->next = NULL;
- } else {
- /* Otherwise the next QH has half the poll interval */
- sqh->next =
- sc->sc_islots[EHCI_IQHIDX(lev - 1, i + 1)].sqh;
- sqh->qh.qh_link = htohc32(sc, sqh->next->physaddr |
- EHCI_LINK_QH);
- }
- sqh->qh.qh_endp = htohc32(sc, EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH));
- sqh->qh.qh_endphub = htohc32(sc, EHCI_QH_SET_MULT(1));
- sqh->qh.qh_curqtd = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_next = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_status = htohc32(sc, EHCI_QTD_HALTED);
- }
- /* Point the frame list at the last level (128ms). */
- for (i = 0; i < sc->sc_flsize; i++) {
- sc->sc_flist[i] = htohc32(sc, EHCI_LINK_QH |
- sc->sc_islots[EHCI_IQHIDX(EHCI_IPOLLRATES - 1, i)].sqh->physaddr);
- }
-
- /* Allocate dummy QH that starts the async list. */
- sqh = ehci_alloc_sqh(sc);
- if (sqh == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- /* Fill the QH */
- sqh->qh.qh_endp =
- htohc32(sc, EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL);
- sqh->qh.qh_link =
- htohc32(sc, sqh->physaddr | EHCI_LINK_QH);
- sqh->qh.qh_curqtd = EHCI_NULL(sc);
- sqh->prev = sqh; /*It's a circular list.. */
- sqh->next = sqh;
- /* Fill the overlay qTD */
- sqh->qh.qh_qtd.qtd_next = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_status = htohc32(sc, 0);
-#ifdef EHCI_DEBUG
- if (ehcidebug) {
- ehci_dump_sqh(sc, sqh);
- }
-#endif
-
- /* Point to async list */
- sc->sc_async_head = sqh;
- EOWRITE4(sc, EHCI_ASYNCLISTADDR, sqh->physaddr | EHCI_LINK_QH);
-
- callout_init(&sc->sc_tmo_intrlist, 0);
-
- lockinit(&sc->sc_doorbell_lock, PZERO, "ehcidb", 0, 0);
-
- /* Enable interrupts */
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
-
- /* Turn on controller */
- EOWRITE4(sc, EHCI_USBCMD,
- EHCI_CMD_ITC_2 | /* 2 microframes interrupt delay */
- (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |
- EHCI_CMD_ASE |
- EHCI_CMD_PSE |
- EHCI_CMD_RS);
-
- /* Take over port ownership */
- EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
-
- for (i = 0; i < 100; i++) {
- usb_delay_ms(&sc->sc_bus, 1);
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (!hcr)
- break;
- }
- if (hcr) {
- printf("%s: run timeout\n", device_get_nameunit(sc->sc_bus.bdev));
- return (USBD_IOERROR);
- }
-
- return (USBD_NORMAL_COMPLETION);
-
-#if 0
- bad2:
- ehci_free_sqh(sc, sc->sc_async_head);
-#endif
- bad1:
- usb_freemem(&sc->sc_bus, &sc->sc_fldma);
- return (err);
-}
-
-int
-ehci_intr(void *v)
-{
- ehci_softc_t *sc = v;
-
- if (sc == NULL || sc->sc_dying)
- return (0);
-
- /* If we get an interrupt while polling, then just ignore it. */
- if (sc->sc_bus.use_polling) {
- u_int32_t intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
-
- if (intrs)
- EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */
-#ifdef DIAGNOSTIC
- DPRINTFN(16, ("ehci_intr: ignored interrupt while polling\n"));
-#endif
- return (0);
- }
-
- return (ehci_intr1(sc));
-}
-
-static int
-ehci_intr1(ehci_softc_t *sc)
-{
- u_int32_t intrs, eintrs;
-
- DPRINTFN(20,("ehci_intr1: enter\n"));
-
- /* In case the interrupt occurs before initialization has completed. */
- if (sc == NULL) {
-#ifdef DIAGNOSTIC
- printf("ehci_intr1: sc == NULL\n");
-#endif
- return (0);
- }
-
- intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
- if (!intrs)
- return (0);
-
- eintrs = intrs & sc->sc_eintrs;
- DPRINTFN(7, ("ehci_intr1: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n",
- sc, (u_int)intrs, EOREAD4(sc, EHCI_USBSTS),
- (u_int)eintrs));
- if (!eintrs)
- return (0);
-
- EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */
- sc->sc_bus.intr_context++;
- sc->sc_bus.no_intrs++;
- if (eintrs & EHCI_STS_IAA) {
- DPRINTF(("ehci_intr1: door bell\n"));
- wakeup(&sc->sc_async_head);
- eintrs &= ~EHCI_STS_IAA;
- }
- if (eintrs & (EHCI_STS_INT | EHCI_STS_ERRINT)) {
- DPRINTFN(5,("ehci_intr1: %s %s\n",
- eintrs & EHCI_STS_INT ? "INT" : "",
- eintrs & EHCI_STS_ERRINT ? "ERRINT" : ""));
- usb_schedsoftintr(&sc->sc_bus);
- eintrs &= ~(EHCI_STS_INT | EHCI_STS_ERRINT);
- }
- if (eintrs & EHCI_STS_HSE) {
- printf("%s: unrecoverable error, controller halted\n",
- device_get_nameunit(sc->sc_bus.bdev));
- /* XXX what else */
- }
- if (eintrs & EHCI_STS_PCD) {
- ehci_pcd(sc, sc->sc_intrxfer);
- eintrs &= ~EHCI_STS_PCD;
- }
-
- sc->sc_bus.intr_context--;
-
- if (eintrs != 0) {
- /* Block unprocessed interrupts. */
- sc->sc_eintrs &= ~eintrs;
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
- printf("%s: blocking intrs 0x%x\n",
- device_get_nameunit(sc->sc_bus.bdev), eintrs);
- }
-
- return (1);
-}
-
-/*
- * XXX write back xfer data for architectures with a write-back
- * data cache; this is a hack because usb is mis-architected
- * in blindly mixing bus_dma w/ PIO.
- */
-static __inline void
-hacksync(usbd_xfer_handle xfer)
-{
- bus_dma_tag_t tag;
- struct usb_dma_mapping *dmap;
-
- if (xfer->length == 0)
- return;
- tag = xfer->pipe->device->bus->buffer_dmatag;
- dmap = &xfer->dmamap;
- bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREWRITE);
-}
-
-void
-ehci_pcd(ehci_softc_t *sc, usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe;
- u_char *p;
- int i, m;
-
- if (xfer == NULL) {
- /* Just ignore the change. */
- return;
- }
-
- pipe = xfer->pipe;
-
- p = xfer->buffer;
- m = min(sc->sc_noport, xfer->length * 8 - 1);
- memset(p, 0, xfer->length);
- for (i = 1; i <= m; i++) {
- /* Pick out CHANGE bits from the status reg. */
- if (EOREAD4(sc, EHCI_PORTSC(i)) & EHCI_PS_CLEAR)
- p[i/8] |= 1 << (i%8);
- }
- DPRINTF(("ehci_pcd: change=0x%02x\n", *p));
- xfer->actlen = xfer->length;
- xfer->status = USBD_NORMAL_COMPLETION;
-
- hacksync(xfer); /* XXX to compensate for usb_transfer_complete */
- usb_transfer_complete(xfer);
-}
-
-void
-ehci_softintr(void *v)
-{
- ehci_softc_t *sc = v;
- struct ehci_xfer *ex, *nextex;
-
- DPRINTFN(10,("%s: ehci_softintr (%d)\n", device_get_nameunit(sc->sc_bus.bdev),
- sc->sc_bus.intr_context));
-
- sc->sc_bus.intr_context++;
-
- /*
- * The only explanation I can think of for why EHCI is as brain dead
- * as UHCI interrupt-wise is that Intel was involved in both.
- * An interrupt just tells us that something is done, we have no
- * clue what, so we need to scan through all active transfers. :-(
- */
- for (ex = LIST_FIRST(&sc->sc_intrhead); ex; ex = nextex) {
- nextex = LIST_NEXT(ex, inext);
- ehci_check_intr(sc, ex);
- }
-
- /* Schedule a callout to catch any dropped transactions. */
- if ((sc->sc_flags & EHCI_SCFLG_LOSTINTRBUG) &&
- !LIST_EMPTY(&sc->sc_intrhead))
- callout_reset(&sc->sc_tmo_intrlist, hz / 5,
- ehci_intrlist_timeout, sc);
-
-#ifdef USB_USE_SOFTINTR
- if (sc->sc_softwake) {
- sc->sc_softwake = 0;
- wakeup(&sc->sc_softwake);
- }
-#endif /* USB_USE_SOFTINTR */
-
- sc->sc_bus.intr_context--;
-}
-
-/* Check for an interrupt. */
-void
-ehci_check_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
-{
- int attr;
-
- DPRINTFN(/*15*/2, ("ehci_check_intr: ex=%p\n", ex));
-
- attr = ex->xfer.pipe->endpoint->edesc->bmAttributes;
- if (UE_GET_XFERTYPE(attr) == UE_ISOCHRONOUS)
- ehci_check_itd_intr(sc, ex);
- else
- ehci_check_qh_intr(sc, ex);
-}
-
-void
-ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
-{
- ehci_soft_qtd_t *sqtd, *lsqtd;
- u_int32_t status;
-
- if (ex->sqtdstart == NULL) {
- printf("ehci_check_qh_intr: not valid sqtd\n");
- return;
- }
- lsqtd = ex->sqtdend;
-#ifdef DIAGNOSTIC
- if (lsqtd == NULL) {
- printf("ehci_check_qh_intr: lsqtd==0\n");
- return;
- }
-#endif
- /*
- * If the last TD is still active we need to check whether there
- * is a an error somewhere in the middle, or whether there was a
- * short packet (SPD and not ACTIVE).
- */
- if (hc32toh(sc, lsqtd->qtd.qtd_status) & EHCI_QTD_ACTIVE) {
- DPRINTFN(12, ("ehci_check_intr: active ex=%p\n", ex));
- for (sqtd = ex->sqtdstart; sqtd != lsqtd; sqtd=sqtd->nextqtd) {
- status = hc32toh(sc, sqtd->qtd.qtd_status);
- /* If there's an active QTD the xfer isn't done. */
- if (status & EHCI_QTD_ACTIVE)
- break;
- /* Any kind of error makes the xfer done. */
- if (status & EHCI_QTD_HALTED)
- goto done;
- /* We want short packets, and it is short: it's done */
- if (EHCI_QTD_GET_BYTES(status) != 0)
- goto done;
- }
- DPRINTFN(12, ("ehci_check_intr: ex=%p std=%p still active\n",
- ex, ex->sqtdstart));
- return;
- }
- done:
- DPRINTFN(12, ("ehci_check_intr: ex=%p done\n", ex));
- callout_stop(&ex->xfer.timeout_handle);
- usb_rem_task(ex->xfer.pipe->device, &ex->abort_task);
- ehci_idone(ex);
-}
-
-void
-ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
-{
- ehci_soft_itd_t *itd;
- int i;
-
- if (ex->itdstart == NULL) {
- printf("ehci_check_itd_intr: not valid itd\n");
- return;
- }
-
- itd = ex->itdend;
-#ifdef DIAGNOSTIC
- if (itd == NULL) {
- printf("ehci_check_itd_intr: itdend == 0\n");
- return;
- }
-#endif
-
- /*
- * Step 1, check no active transfers in last itd, meaning we're finished
- */
- for (i = 0; i < 8; i++) {
- if (hc32toh(sc, itd->itd.itd_ctl[i]) & EHCI_ITD_ACTIVE)
- break;
- }
-
- if (i == 8) {
- goto done; /* All 8 descriptors inactive, it's done */
- }
-
- /*
- * Step 2, check for errors in status bits, throughout chain...
- */
-
- DPRINTFN(12, ("ehci_check_itd_intr: active ex=%p\n", ex));
-
- for (itd = ex->itdstart; itd != ex->itdend; itd = itd->xfer_next) {
- for (i = 0; i < 8; i++) {
- if (hc32toh(sc, itd->itd.itd_ctl[i]) & (EHCI_ITD_BUF_ERR |
- EHCI_ITD_BABBLE | EHCI_ITD_ERROR))
- break;
- }
- if (i != 8) { /* Error in one of the itds */
- goto done;
- }
- } /* itd search loop */
-
- DPRINTFN(12, ("ehci_check_itd_intr: ex %p itd %p still active\n", ex,
- ex->itdstart));
- return;
-done:
- DPRINTFN(12, ("ehci_check_itd_intr: ex=%p done\n", ex));
- callout_stop(&ex->xfer.timeout_handle);
- usb_rem_task(ex->xfer.pipe->device, &ex->abort_task);
- ehci_idone(ex);
-}
-
-void
-ehci_idone(struct ehci_xfer *ex)
-{
- usbd_xfer_handle xfer = &ex->xfer;
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
- ehci_soft_qtd_t *sqtd, *lsqtd;
- u_int32_t status = 0, nstatus = 0;
- ehci_physaddr_t nextphys, altnextphys;
- int actlen, cerr;
-
- DPRINTFN(/*12*/2, ("ehci_idone: ex=%p\n", ex));
-#ifdef DIAGNOSTIC
- {
- int s = splhigh();
- if (ex->isdone) {
- splx(s);
-#ifdef EHCI_DEBUG
- printf("ehci_idone: ex is done!\n ");
- ehci_dump_exfer(ex);
-#else
- printf("ehci_idone: ex=%p is done!\n", ex);
-#endif
- return;
- }
- ex->isdone = 1;
- splx(s);
- }
-#endif
-
- if (xfer->status == USBD_CANCELLED ||
- xfer->status == USBD_TIMEOUT) {
- DPRINTF(("ehci_idone: aborted xfer=%p\n", xfer));
- return;
- }
-
-#ifdef EHCI_DEBUG
- DPRINTFN(/*10*/2, ("ehci_idone: xfer=%p, pipe=%p ready\n", xfer, epipe));
- if (ehcidebug > 10)
- ehci_dump_sqtds(sc, ex->sqtdstart);
-#endif
-
- /*
- * Make sure that the QH overlay qTD does not reference any
- * of the qTDs we are about to free. This is probably only
- * necessary if the transfer is marked as HALTED.
- */
- nextphys = EHCI_LINK_ADDR(hc32toh(sc, epipe->sqh->qh.qh_qtd.qtd_next));
- altnextphys =
- EHCI_LINK_ADDR(hc32toh(sc, epipe->sqh->qh.qh_qtd.qtd_altnext));
- for (sqtd = ex->sqtdstart; sqtd != ex->sqtdend->nextqtd;
- sqtd = sqtd->nextqtd) {
- if (sqtd->physaddr == nextphys) {
- epipe->sqh->qh.qh_qtd.qtd_next =
- htohc32(sc, ex->sqtdend->nextqtd->physaddr);
- DPRINTFN(4, ("ehci_idone: updated overlay next ptr\n"));
-
- }
- if (sqtd->physaddr == altnextphys) {
- DPRINTFN(4,
- ("ehci_idone: updated overlay altnext ptr\n"));
- epipe->sqh->qh.qh_qtd.qtd_altnext =
- htohc32(sc, ex->sqtdend->nextqtd->physaddr);
- }
- }
-
- /* The transfer is done, compute actual length and status. */
- if (UE_GET_XFERTYPE(xfer->pipe->endpoint->edesc->bmAttributes)
- == UE_ISOCHRONOUS) {
- /* Isoc transfer */
- struct ehci_soft_itd *itd;
- int i, nframes, len, uframes;
-
- nframes = 0;
- actlen = 0;
-
- switch (xfer->pipe->endpoint->edesc->bInterval) {
- case 0:
- panic("ehci: isoc xfer suddenly has 0 bInterval, "
- "invalid\n");
- case 1:
- uframes = 1;
- break;
- case 2:
- uframes = 2;
- break;
- case 3:
- uframes = 4;
- break;
- default:
- uframes = 8;
- break;
- }
-
- for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) {
- for (i = 0; i < 8; i += uframes) {
- /* XXX - driver didn't fill in the frame full
- * of uframes. This leads to scheduling
- * inefficiencies, but working around
- * this doubles complexity of tracking
- * an xfer.
- */
- if (nframes >= xfer->nframes)
- break;
-
- status = hc32toh(sc, itd->itd.itd_ctl[i]);
- len = EHCI_ITD_GET_LEN(status);
- xfer->frlengths[nframes++] = len;
- actlen += len;
- }
- if (nframes >= xfer->nframes)
- break;
- }
- xfer->actlen = actlen;
- xfer->status = USBD_NORMAL_COMPLETION;
-
- goto end;
- }
-
- /* Continue processing xfers using queue heads */
-
- lsqtd = ex->sqtdend;
- actlen = 0;
- for (sqtd = ex->sqtdstart; sqtd != lsqtd->nextqtd;
- sqtd =sqtd->nextqtd) {
- nstatus = hc32toh(sc, sqtd->qtd.qtd_status);
- if (nstatus & EHCI_QTD_ACTIVE)
- break;
-
- status = nstatus;
- /* halt is ok if descriptor is last, and complete */
- if (sqtd == lsqtd && EHCI_QTD_GET_BYTES(status) == 0)
- status &= ~EHCI_QTD_HALTED;
- if (EHCI_QTD_GET_PID(status) != EHCI_QTD_PID_SETUP)
- actlen += sqtd->len - EHCI_QTD_GET_BYTES(status);
- }
-
- cerr = EHCI_QTD_GET_CERR(status);
- DPRINTFN(/*10*/2, ("ehci_idone: len=%d, actlen=%d, cerr=%d, "
- "status=0x%x\n", xfer->length, actlen, cerr, status));
- xfer->actlen = actlen;
- if ((status & EHCI_QTD_HALTED) != 0) {
- DPRINTFN(2,
- ("ehci_idone: error, addr=%d, endpt=0x%02x, status %b\n",
- xfer->pipe->device->address,
- xfer->pipe->endpoint->edesc->bEndpointAddress,
- status, EHCI_QTD_STATUS_BITS));
- if ((status & EHCI_QTD_BABBLE) == 0 && cerr > 0)
- xfer->status = USBD_STALLED;
- else
- xfer->status = USBD_IOERROR; /* more info XXX */
- } else {
- xfer->status = USBD_NORMAL_COMPLETION;
- }
-#ifdef EHCI_DEBUG
- if (ehcidebug > 2) {
- ehci_dump_sqh(sc, epipe->sqh);
- ehci_dump_sqtds(sc, ex->sqtdstart);
- }
-#endif
-end:
- /* XXX transfer_complete memcpys out transfer data (for in endpoints)
- * during this call, before methods->done is called: dma sync required
- * beforehand?
- */
- usb_transfer_complete(xfer);
- DPRINTFN(/*12*/2, ("ehci_idone: ex=%p done\n", ex));
-}
-
-/*
- * Wait here until controller claims to have an interrupt.
- * Then call ehci_intr and return. Use timeout to avoid waiting
- * too long.
- */
-void
-ehci_waitintr(ehci_softc_t *sc, usbd_xfer_handle xfer)
-{
- int timo = xfer->timeout;
- int usecs;
- u_int32_t intrs;
-
- xfer->status = USBD_IN_PROGRESS;
- for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) {
- usb_delay_ms(&sc->sc_bus, 1);
- if (sc->sc_dying)
- break;
- intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS)) &
- sc->sc_eintrs;
- DPRINTFN(15,("ehci_waitintr: 0x%04x\n", intrs));
-#ifdef EHCI_DEBUG
- if (ehcidebug > 15)
- ehci_dump_regs(sc);
-#endif
- if (intrs) {
- ehci_intr1(sc);
- if (xfer->status != USBD_IN_PROGRESS)
- return;
- }
- }
-
- /* Timeout */
- DPRINTF(("ehci_waitintr: timeout\n"));
- xfer->status = USBD_TIMEOUT;
- usb_transfer_complete(xfer);
- /* XXX should free TD */
-}
-
-void
-ehci_poll(struct usbd_bus *bus)
-{
- ehci_softc_t *sc = (ehci_softc_t *)bus;
-#ifdef EHCI_DEBUG
- static int last;
- int new;
- new = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
- if (new != last) {
- DPRINTFN(10,("ehci_poll: intrs=0x%04x\n", new));
- last = new;
- }
-#endif
-
- if (EOREAD4(sc, EHCI_USBSTS) & sc->sc_eintrs)
- ehci_intr1(sc);
-}
-
-int
-ehci_detach(struct ehci_softc *sc, int flags)
-{
- int rv = 0;
-
- sc->sc_dying = 1;
-
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
- (void) ehci_hcreset(sc);
- callout_stop(&sc->sc_tmo_intrlist);
-
- usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
-
- usb_freemem(&sc->sc_bus, &sc->sc_fldma);
- /* XXX free other data structures XXX */
-
- return (rv);
-}
-
-/*
- * Handle suspend/resume.
- *
- * We need to switch to polling mode here, because this routine is
- * called from an interrupt context. This is all right since we
- * are almost suspended anyway.
- */
-void
-ehci_power(int why, void *v)
-{
- ehci_softc_t *sc = v;
- u_int32_t cmd, hcr;
- int s, i;
-
-#ifdef EHCI_DEBUG
- DPRINTF(("ehci_power: sc=%p, why=%d\n", sc, why));
- if (ehcidebug > 0)
- ehci_dump_regs(sc);
-#endif
-
- s = splhardusb();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- sc->sc_bus.use_polling++;
-
- for (i = 1; i <= sc->sc_noport; i++) {
- cmd = EOREAD4(sc, EHCI_PORTSC(i));
- if ((cmd & EHCI_PS_PO) == 0 &&
- (cmd & EHCI_PS_PE) == EHCI_PS_PE)
- EOWRITE4(sc, EHCI_PORTSC(i),
- cmd | EHCI_PS_SUSP);
- }
-
- sc->sc_cmd = EOREAD4(sc, EHCI_USBCMD);
-
- cmd = sc->sc_cmd & ~(EHCI_CMD_ASE | EHCI_CMD_PSE);
- EOWRITE4(sc, EHCI_USBCMD, cmd);
-
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) &
- (EHCI_STS_ASS | EHCI_STS_PSS);
- if (hcr == 0)
- break;
-
- usb_delay_ms(&sc->sc_bus, 1);
- }
- if (hcr != 0) {
- printf("%s: reset timeout\n",
- device_get_nameunit(sc->sc_bus.bdev));
- }
-
- cmd &= ~EHCI_CMD_RS;
- EOWRITE4(sc, EHCI_USBCMD, cmd);
-
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (hcr == EHCI_STS_HCH)
- break;
-
- usb_delay_ms(&sc->sc_bus, 1);
- }
- if (hcr != EHCI_STS_HCH) {
- printf("%s: config timeout\n",
- device_get_nameunit(sc->sc_bus.bdev));
- }
-
- sc->sc_bus.use_polling--;
- break;
-
- case PWR_RESUME:
- sc->sc_bus.use_polling++;
-
- /* restore things in case the bios sucks */
- EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
- EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
- EOWRITE4(sc, EHCI_ASYNCLISTADDR,
- sc->sc_async_head->physaddr | EHCI_LINK_QH);
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
-
- hcr = 0;
- for (i = 1; i <= sc->sc_noport; i++) {
- cmd = EOREAD4(sc, EHCI_PORTSC(i));
- if ((cmd & EHCI_PS_PO) == 0 &&
- (cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP) {
- EOWRITE4(sc, EHCI_PORTSC(i),
- cmd | EHCI_PS_FPR);
- hcr = 1;
- }
- }
-
- if (hcr) {
- usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
-
- for (i = 1; i <= sc->sc_noport; i++) {
- cmd = EOREAD4(sc, EHCI_PORTSC(i));
- if ((cmd & EHCI_PS_PO) == 0 &&
- (cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP)
- EOWRITE4(sc, EHCI_PORTSC(i),
- cmd & ~EHCI_PS_FPR);
- }
- }
-
- EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);
-
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (hcr != EHCI_STS_HCH)
- break;
-
- usb_delay_ms(&sc->sc_bus, 1);
- }
- if (hcr == EHCI_STS_HCH) {
- printf("%s: config timeout\n",
- device_get_nameunit(sc->sc_bus.bdev));
- }
-
- usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
-
- sc->sc_bus.use_polling--;
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
- splx(s);
-
-#ifdef EHCI_DEBUG
- DPRINTF(("ehci_power: sc=%p\n", sc));
- if (ehcidebug > 0)
- ehci_dump_regs(sc);
-#endif
-}
-
-/*
- * Shut down the controller when the system is going down.
- */
-void
-ehci_shutdown(void *v)
-{
- ehci_softc_t *sc = v;
-
- DPRINTF(("ehci_shutdown: stopping the HC\n"));
- (void) ehci_hcreset(sc);
-}
-
-usbd_status
-ehci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
-{
- usbd_status err;
-
- err = usb_allocmem(bus, size, 0, dma);
-#ifdef EHCI_DEBUG
- if (err)
- printf("ehci_allocm: usb_allocmem()=%d\n", err);
-#endif
- return (err);
-}
-
-void
-ehci_freem(struct usbd_bus *bus, usb_dma_t *dma)
-{
- usb_freemem(bus, dma);
-}
-
-usbd_xfer_handle
-ehci_allocx(struct usbd_bus *bus)
-{
- struct ehci_softc *sc = (struct ehci_softc *)bus;
- usbd_xfer_handle xfer;
-
- xfer = STAILQ_FIRST(&sc->sc_free_xfers);
- if (xfer != NULL) {
- STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_FREE) {
- printf("ehci_allocx: xfer=%p not free, 0x%08x\n", xfer,
- xfer->busy_free);
- }
-#endif
- } else {
- xfer = malloc(sizeof(struct ehci_xfer), M_USB, M_NOWAIT);
- }
- if (xfer != NULL) {
- memset(xfer, 0, sizeof(struct ehci_xfer));
- usb_init_task(&EXFER(xfer)->abort_task, ehci_timeout_task,
- xfer);
- EXFER(xfer)->ehci_xfer_flags = 0;
-#ifdef DIAGNOSTIC
- EXFER(xfer)->isdone = 1;
- xfer->busy_free = XFER_BUSY;
-#endif
- }
- return (xfer);
-}
-
-void
-ehci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
-{
- struct ehci_softc *sc = (struct ehci_softc *)bus;
-
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_BUSY) {
- printf("ehci_freex: xfer=%p not busy, 0x%08x\n", xfer,
- xfer->busy_free);
- return;
- }
- xfer->busy_free = XFER_FREE;
- if (!EXFER(xfer)->isdone) {
- printf("ehci_freex: !isdone\n");
- return;
- }
-#endif
- STAILQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
-}
-
-static void
-ehci_device_clear_toggle(usbd_pipe_handle pipe)
-{
- struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
- ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
-
- DPRINTF(("ehci_device_clear_toggle: epipe=%p status=0x%x\n",
- epipe, epipe->sqh->qh.qh_qtd.qtd_status));
-#ifdef USB_DEBUG
- if (ehcidebug)
- usbd_dump_pipe(pipe);
-#endif
- KASSERT((epipe->sqh->qh.qh_qtd.qtd_status &
- htohc32(sc, EHCI_QTD_ACTIVE)) == 0,
- ("ehci_device_clear_toggle: queue active"));
- epipe->sqh->qh.qh_qtd.qtd_status &= htohc32(sc, ~EHCI_QTD_TOGGLE_MASK);
-}
-
-static void
-ehci_noop(usbd_pipe_handle pipe)
-{
-}
-
-usbd_status
-ehci_open(usbd_pipe_handle pipe)
-{
- usbd_device_handle dev = pipe->device;
- ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
- usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
- u_int8_t addr = dev->address;
- u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
- struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
- ehci_soft_qh_t *sqh;
- usbd_status err;
- int s;
- int ival, speed, naks;
- int hshubaddr, hshubport;
-
- DPRINTFN(1, ("ehci_open: pipe=%p, xfertype=%d, addr=%d, endpt=%d (%d)\n",
- pipe, addr, ed->bEndpointAddress, sc->sc_addr, xfertype));
-
- if (dev->myhsport) {
- hshubaddr = dev->myhsport->parent->address;
- hshubport = dev->myhsport->portno;
- } else {
- hshubaddr = 0;
- hshubport = 0;
- }
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- if (addr == sc->sc_addr) {
- switch (ed->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &ehci_root_ctrl_methods;
- break;
- case UE_DIR_IN | EHCI_INTR_ENDPT:
- pipe->methods = &ehci_root_intr_methods;
- break;
- default:
- DPRINTF(("ehci_open: bad bEndpointAddress 0x%02x\n",
- ed->bEndpointAddress));
- return (USBD_INVAL);
- }
- return (USBD_NORMAL_COMPLETION);
- }
-
- /* XXX All this stuff is only valid for async. */
- switch (dev->speed) {
- case USB_SPEED_LOW: speed = EHCI_QH_SPEED_LOW; break;
- case USB_SPEED_FULL: speed = EHCI_QH_SPEED_FULL; break;
- case USB_SPEED_HIGH: speed = EHCI_QH_SPEED_HIGH; break;
- default: panic("ehci_open: bad device speed %d", dev->speed);
- }
- if (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_ISOCHRONOUS) {
- printf("%s: *** Error: opening low/full speed isoc device on"
- "ehci, this does not work yet. Feel free to implement\n",
- device_get_nameunit(sc->sc_bus.bdev));
- DPRINTFN(1,("ehci_open: hshubaddr=%d hshubport=%d\n",
- hshubaddr, hshubport));
- return USBD_INVAL;
- }
-
- naks = 8; /* XXX */
- /* Allocate sqh for everything, save isoc xfers */
- if (xfertype != UE_ISOCHRONOUS) {
- sqh = ehci_alloc_sqh(sc);
- if (sqh == NULL)
- goto bad0;
- /* qh_link filled when the QH is added */
- sqh->qh.qh_endp = htohc32(sc,
- EHCI_QH_SET_ADDR(addr) |
- EHCI_QH_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress)) |
- EHCI_QH_SET_EPS(speed) |
- (xfertype == UE_CONTROL ? EHCI_QH_DTC : 0) |
- EHCI_QH_SET_MPL(UGETW(ed->wMaxPacketSize)) |
- (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_CONTROL ?
- EHCI_QH_CTL : 0) |
- EHCI_QH_SET_NRL(naks)
- );
- sqh->qh.qh_endphub = htohc32(sc,
- EHCI_QH_SET_MULT(1) |
- EHCI_QH_SET_HUBA(hshubaddr) |
- EHCI_QH_SET_PORT(hshubport) |
- EHCI_QH_SET_CMASK(0x1c) |
- EHCI_QH_SET_SMASK(xfertype == UE_INTERRUPT ? 0x01 : 0)
- );
- sqh->qh.qh_curqtd = EHCI_NULL(sc);
- /* The overlay qTD was already set up by ehci_alloc_sqh(). */
- sqh->qh.qh_qtd.qtd_status =
- htohc32(sc, EHCI_QTD_SET_TOGGLE(pipe->endpoint->savedtoggle));
- epipe->sqh = sqh;
- } else {
- sqh = NULL;
- }
-
- switch (xfertype) {
- case UE_CONTROL:
- err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t),
- 0, &epipe->u.ctl.reqdma);
-#ifdef EHCI_DEBUG
- if (err)
- printf("ehci_open: usb_allocmem()=%d\n", err);
-#endif
- if (err)
- goto bad1;
- pipe->methods = &ehci_device_ctrl_methods;
- s = splusb();
- ehci_add_qh(sc, sqh, sc->sc_async_head);
- splx(s);
- break;
- case UE_BULK:
- pipe->methods = &ehci_device_bulk_methods;
- s = splusb();
- ehci_add_qh(sc, sqh, sc->sc_async_head);
- splx(s);
- break;
- case UE_INTERRUPT:
- pipe->methods = &ehci_device_intr_methods;
- ival = pipe->interval;
- if (ival == USBD_DEFAULT_INTERVAL)
- ival = ed->bInterval;
- return (ehci_device_setintr(sc, sqh, ival));
- case UE_ISOCHRONOUS:
- pipe->methods = &ehci_device_isoc_methods;
- if (ed->bInterval == 0 || ed->bInterval > 16) {
- printf("ehci: opening pipe with invalid bInterval\n");
- err = USBD_INVAL;
- goto bad1;
- }
- if (UGETW(ed->wMaxPacketSize) == 0) {
- printf("ehci: zero length endpoint open request\n");
- err = USBD_INVAL;
- goto bad1;
- }
- epipe->u.isoc.next_frame = 0;
- epipe->u.isoc.cur_xfers = 0;
- break;
- default:
- DPRINTF(("ehci: bad xfer type %d\n", xfertype));
- return (USBD_INVAL);
- }
- return (USBD_NORMAL_COMPLETION);
-
- bad1:
- if (sqh != NULL)
- ehci_free_sqh(sc, sqh);
- return (err);
- bad0:
- return (USBD_NOMEM);
-}
-
-/*
- * Add an ED to the schedule. Called at splusb().
- * If in the async schedule, it will always have a next.
- * If in the intr schedule it may not.
- */
-void
-ehci_add_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
-{
- SPLUSBCHECK;
-
- sqh->next = head->next;
- sqh->prev = head;
- sqh->qh.qh_link = head->qh.qh_link;
- head->next = sqh;
- if (sqh->next)
- sqh->next->prev = sqh;
- head->qh.qh_link = htohc32(sc, sqh->physaddr | EHCI_LINK_QH);
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 5) {
- printf("ehci_add_qh:\n");
- ehci_dump_sqh(sc, sqh);
- }
-#endif
-}
-
-/*
- * Remove an ED from the schedule. Called at splusb().
- * Will always have a 'next' if it's in the async list as it's circular.
- */
-void
-ehci_rem_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
-{
- SPLUSBCHECK;
- /* XXX */
- sqh->prev->qh.qh_link = sqh->qh.qh_link;
- sqh->prev->next = sqh->next;
- if (sqh->next)
- sqh->next->prev = sqh->prev;
- ehci_sync_hc(sc);
-}
-
-/* Restart a QH following the addition of a qTD. */
-void
-ehci_activate_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd)
-{
- KASSERT((sqtd->qtd.qtd_status & htohc32(sc, EHCI_QTD_ACTIVE)) == 0,
- ("ehci_activate_qh: already active"));
-
- /*
- * When a QH is idle, the overlay qTD should be marked as not
- * halted and not active. This causes the host controller to
- * retrieve the real qTD on each pass (rather than just examinig
- * the overlay), so it will notice when we activate the qTD.
- */
- if (sqtd == sqh->sqtd) {
- /* Check that the hardware is in the state we expect. */
- if (EHCI_LINK_ADDR(hc32toh(sc, sqh->qh.qh_qtd.qtd_next)) !=
- sqtd->physaddr) {
-#ifdef EHCI_DEBUG
- printf("ehci_activate_qh: unexpected next ptr\n");
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, sqh->sqtd);
-#endif
- sqh->qh.qh_qtd.qtd_next = htohc32(sc, sqtd->physaddr);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
- }
- /* Ensure the flags are correct. */
- sqh->qh.qh_qtd.qtd_status &= htohc32(sc, EHCI_QTD_PINGSTATE |
- EHCI_QTD_TOGGLE_MASK);
- }
-
- /* Now activate the qTD. */
- sqtd->qtd.qtd_status |= htohc32(sc, EHCI_QTD_ACTIVE);
-}
-
-/*
- * Ensure that the HC has released all references to the QH. We do this
- * by asking for a Async Advance Doorbell interrupt and then we wait for
- * the interrupt.
- * To make this easier we first obtain exclusive use of the doorbell.
- */
-void
-ehci_sync_hc(ehci_softc_t *sc)
-{
- int s, error;
-
- if (sc->sc_dying) {
- DPRINTFN(2,("ehci_sync_hc: dying\n"));
- return;
- }
- DPRINTFN(2,("ehci_sync_hc: enter\n"));
- /* get doorbell */
- lockmgr(&sc->sc_doorbell_lock, LK_EXCLUSIVE, NULL);
- s = splhardusb();
- /* ask for doorbell */
- EOWRITE4(sc, EHCI_USBCMD, EOREAD4(sc, EHCI_USBCMD) | EHCI_CMD_IAAD);
- DPRINTFN(1,("ehci_sync_hc: cmd=0x%08x sts=0x%08x\n",
- EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS)));
- error = tsleep(&sc->sc_async_head, PZERO, "ehcidi", hz); /* bell wait */
- DPRINTFN(1,("ehci_sync_hc: cmd=0x%08x sts=0x%08x\n",
- EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS)));
- splx(s);
- /* release doorbell */
- lockmgr(&sc->sc_doorbell_lock, LK_RELEASE, NULL);
-#ifdef DIAGNOSTIC
- if (error)
- printf("ehci_sync_hc: tsleep() = %d\n", error);
-#endif
- DPRINTFN(2,("ehci_sync_hc: exit\n"));
-}
-
-/*Call at splusb*/
-void
-ehci_rem_free_itd_chain(ehci_softc_t *sc, struct ehci_xfer *exfer)
-{
- struct ehci_soft_itd *itd, *prev;
-
- prev = NULL;
-
- if (exfer->itdstart == NULL || exfer->itdend == NULL)
- panic("ehci isoc xfer being freed, but with no itd chain\n");
-
- for (itd = exfer->itdstart; itd != NULL; itd = itd->xfer_next) {
- prev = itd->u.frame_list.prev;
- /* Unlink itd from hardware chain, or frame array */
- if (prev == NULL) { /* We're at the table head */
- sc->sc_softitds[itd->slot] = itd->u.frame_list.next;
- sc->sc_flist[itd->slot] = itd->itd.itd_next;
-
- if (itd->u.frame_list.next != NULL)
- itd->u.frame_list.next->u.frame_list.prev =
- NULL;
- } else {
- /* XXX this part is untested... */
- prev->itd.itd_next = itd->itd.itd_next;
- prev->u.frame_list.next = itd->u.frame_list.next;
- if (itd->u.frame_list.next != NULL)
- itd->u.frame_list.next->u.frame_list.prev =
- prev;
- }
- }
-
- prev = NULL;
- for (itd = exfer->itdstart; itd != NULL; itd = itd->xfer_next) {
- if (prev != NULL)
- ehci_free_itd(sc, prev);
- prev = itd;
- }
- if (prev)
- ehci_free_itd(sc, prev);
- exfer->itdstart = NULL;
- exfer->itdend = NULL;
-}
-
-/***********/
-
-/*
- * Data structures and routines to emulate the root hub.
- */
-static usb_device_descriptor_t ehci_devd = {
- USB_DEVICE_DESCRIPTOR_SIZE,
- UDESC_DEVICE, /* type */
- {0x00, 0x02}, /* USB version */
- UDCLASS_HUB, /* class */
- UDSUBCLASS_HUB, /* subclass */
- UDPROTO_HSHUBSTT, /* protocol */
- 64, /* max packet */
- {0},{0},{0x00,0x01}, /* device id */
- 1,2,0, /* string indicies */
- 1 /* # of configurations */
-};
-
-static usb_device_qualifier_t ehci_odevd = {
- USB_DEVICE_DESCRIPTOR_SIZE,
- UDESC_DEVICE_QUALIFIER, /* type */
- {0x00, 0x02}, /* USB version */
- UDCLASS_HUB, /* class */
- UDSUBCLASS_HUB, /* subclass */
- UDPROTO_FSHUB, /* protocol */
- 64, /* max packet */
- 1, /* # of configurations */
- 0
-};
-
-static usb_config_descriptor_t ehci_confd = {
- USB_CONFIG_DESCRIPTOR_SIZE,
- UDESC_CONFIG,
- {USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE},
- 1,
- 1,
- 0,
- UC_SELF_POWERED,
- 0 /* max power */
-};
-
-static usb_interface_descriptor_t ehci_ifcd = {
- USB_INTERFACE_DESCRIPTOR_SIZE,
- UDESC_INTERFACE,
- 0,
- 0,
- 1,
- UICLASS_HUB,
- UISUBCLASS_HUB,
- UIPROTO_HSHUBSTT,
- 0
-};
-
-static usb_endpoint_descriptor_t ehci_endpd = {
- USB_ENDPOINT_DESCRIPTOR_SIZE,
- UDESC_ENDPOINT,
- UE_DIR_IN | EHCI_INTR_ENDPT,
- UE_INTERRUPT,
- {8, 0}, /* max packet */
- 255
-};
-
-static usb_hub_descriptor_t ehci_hubd = {
- USB_HUB_DESCRIPTOR_SIZE,
- UDESC_HUB,
- 0,
- {0,0},
- 0,
- 0,
- {0},
-};
-
-static int
-ehci_str(usb_string_descriptor_t *p, int l, char *s)
-{
- int i;
-
- if (l == 0)
- return (0);
- p->bLength = 2 * strlen(s) + 2;
- if (l == 1)
- return (1);
- p->bDescriptorType = UDESC_STRING;
- l -= 2;
- for (i = 0; s[i] && l > 1; i++, l -= 2)
- USETW2(p->bString[i], 0, s[i]);
- return (2*i+2);
-}
-
-/*
- * Simulate a hardware hub by handling all the necessary requests.
- */
-static usbd_status
-ehci_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ehci_root_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ehci_root_ctrl_start(usbd_xfer_handle xfer)
-{
- ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
- usb_device_request_t *req;
- void *buf = NULL;
- int port, i;
- int s, len, value, index, l, totlen = 0;
- usb_port_status_t ps;
- usb_hub_descriptor_t hubd;
- usbd_status err;
- u_int32_t v;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST))
- /* XXX panic */
- return (USBD_INVAL);
-#endif
- req = &xfer->request;
-
- DPRINTFN(4,("ehci_root_ctrl_start: type=0x%02x request=%02x\n",
- req->bmRequestType, req->bRequest));
-
- len = UGETW(req->wLength);
- value = UGETW(req->wValue);
- index = UGETW(req->wIndex);
-
- if (len != 0)
- buf = xfer->buffer;
-
-#define C(x,y) ((x) | ((y) << 8))
- switch(C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- if (len > 0) {
- *(u_int8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- DPRINTFN(8,("ehci_root_ctrl_start: wValue=0x%04x\n", value));
- switch(value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- USETW(ehci_devd.idVendor, sc->sc_id_vendor);
- memcpy(buf, &ehci_devd, l);
- break;
- /*
- * We can't really operate at another speed, but the spec says
- * we need this descriptor.
- */
- case UDESC_DEVICE_QUALIFIER:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- memcpy(buf, &ehci_odevd, l);
- break;
- /*
- * We can't really operate at another speed, but the spec says
- * we need this descriptor.
- */
- case UDESC_OTHER_SPEED_CONFIGURATION:
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &ehci_confd, l);
- ((usb_config_descriptor_t *)buf)->bDescriptorType =
- value >> 8;
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ehci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ehci_endpd, l);
- break;
- case UDESC_STRING:
- if (len == 0)
- break;
- *(u_int8_t *)buf = 0;
- totlen = 1;
- switch (value & 0xff) {
- case 0: /* Language table */
- totlen = ehci_str(buf, len, "\001");
- break;
- case 1: /* Vendor */
- totlen = ehci_str(buf, len, sc->sc_vendor);
- break;
- case 2: /* Product */
- totlen = ehci_str(buf, len, "EHCI root hub");
- break;
- }
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *(u_int8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- if (value >= USB_MAX_DEVICES) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- if (value != 0 && value != 1) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- break;
- /* Hub requests */
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
- DPRINTFN(8, ("ehci_root_ctrl_start: UR_CLEAR_PORT_FEATURE "
- "port=%d feature=%d\n",
- index, value));
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- port = EHCI_PORTSC(index);
- v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
- switch(value) {
- case UHF_PORT_ENABLE:
- EOWRITE4(sc, port, v &~ EHCI_PS_PE);
- break;
- case UHF_PORT_SUSPEND:
- EOWRITE4(sc, port, v &~ EHCI_PS_SUSP);
- break;
- case UHF_PORT_POWER:
- EOWRITE4(sc, port, v &~ EHCI_PS_PP);
- break;
- case UHF_PORT_TEST:
- DPRINTFN(2,("ehci_root_ctrl_start: clear port test "
- "%d\n", index));
- break;
- case UHF_PORT_INDICATOR:
- DPRINTFN(2,("ehci_root_ctrl_start: clear port ind "
- "%d\n", index));
- EOWRITE4(sc, port, v &~ EHCI_PS_PIC);
- break;
- case UHF_C_PORT_CONNECTION:
- EOWRITE4(sc, port, v | EHCI_PS_CSC);
- break;
- case UHF_C_PORT_ENABLE:
- EOWRITE4(sc, port, v | EHCI_PS_PEC);
- break;
- case UHF_C_PORT_SUSPEND:
- /* how? */
- break;
- case UHF_C_PORT_OVER_CURRENT:
- EOWRITE4(sc, port, v | EHCI_PS_OCC);
- break;
- case UHF_C_PORT_RESET:
- sc->sc_isreset = 0;
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- hubd = ehci_hubd;
- hubd.bNbrPorts = sc->sc_noport;
- v = EOREAD4(sc, EHCI_HCSPARAMS);
- USETW(hubd.wHubCharacteristics,
- EHCI_HCS_PPC(v) ? UHD_PWR_INDIVIDUAL : UHD_PWR_NO_SWITCH |
- EHCI_HCS_P_INDICATOR(EREAD4(sc, EHCI_HCSPARAMS))
- ? UHD_PORT_IND : 0);
- hubd.bPwrOn2PwrGood = 200; /* XXX can't find out? */
- for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
- hubd.DeviceRemovable[i++] = 0; /* XXX can't find out? */
- hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
- l = min(len, hubd.bDescLength);
- totlen = l;
- memcpy(buf, &hubd, l);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- memset(buf, 0, len); /* ? XXX */
- totlen = len;
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- DPRINTFN(8,("ehci_root_ctrl_start: get port status i=%d\n",
- index));
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- v = EOREAD4(sc, EHCI_PORTSC(index));
- DPRINTFN(8,("ehci_root_ctrl_start: port status=0x%04x\n",
- v));
-
- i = UPS_HIGH_SPEED;
-
- if (sc->sc_flags & (EHCI_SCFLG_FORCESPEED | EHCI_SCFLG_TT)) {
- if ((v & 0xc000000) == 0x8000000)
- i = UPS_HIGH_SPEED;
- else if ((v & 0xc000000) == 0x4000000)
- i = UPS_LOW_SPEED;
- else
- i = 0;
- }
-
- if (v & EHCI_PS_CS) i |= UPS_CURRENT_CONNECT_STATUS;
- if (v & EHCI_PS_PE) i |= UPS_PORT_ENABLED;
- if (v & EHCI_PS_SUSP) i |= UPS_SUSPEND;
- if (v & EHCI_PS_OCA) i |= UPS_OVERCURRENT_INDICATOR;
- if (v & EHCI_PS_PR) i |= UPS_RESET;
- if (v & EHCI_PS_PP) i |= UPS_PORT_POWER;
- USETW(ps.wPortStatus, i);
- i = 0;
- if (v & EHCI_PS_CSC) i |= UPS_C_CONNECT_STATUS;
- if (v & EHCI_PS_PEC) i |= UPS_C_PORT_ENABLED;
- if (v & EHCI_PS_OCC) i |= UPS_C_OVERCURRENT_INDICATOR;
- if (sc->sc_isreset) i |= UPS_C_PORT_RESET;
- USETW(ps.wPortChange, i);
- l = min(len, sizeof ps);
- memcpy(buf, &ps, l);
- totlen = l;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- port = EHCI_PORTSC(index);
- v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
- switch(value) {
- case UHF_PORT_ENABLE:
- EOWRITE4(sc, port, v | EHCI_PS_PE);
- break;
- case UHF_PORT_SUSPEND:
- EOWRITE4(sc, port, v | EHCI_PS_SUSP);
- break;
- case UHF_PORT_RESET:
- DPRINTFN(5,("ehci_root_ctrl_start: reset port %d\n",
- index));
- if (EHCI_PS_IS_LOWSPEED(v) &&
- (sc->sc_flags & EHCI_SCFLG_TT) == 0) {
- /* Low speed device, give up ownership. */
- ehci_disown(sc, index, 1);
- break;
- }
- /* Start reset sequence. */
- v &= ~ (EHCI_PS_PE | EHCI_PS_PR);
- EOWRITE4(sc, port, v | EHCI_PS_PR);
- /* Wait for reset to complete. */
- usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
- if (sc->sc_dying) {
- err = USBD_IOERROR;
- goto ret;
- }
- /* Terminate reset sequence. */
- if (sc->sc_flags & EHCI_SCFLG_NORESTERM)
- ;
- else
- EOWRITE4(sc, port, v);
-
- /* Wait for HC to complete reset. */
- usb_delay_ms(&sc->sc_bus, EHCI_PORT_RESET_COMPLETE);
- if (sc->sc_dying) {
- err = USBD_IOERROR;
- goto ret;
- }
- v = EOREAD4(sc, port);
- DPRINTF(("ehci after reset, status=0x%08x\n", v));
- if (v & EHCI_PS_PR) {
- printf("%s: port reset timeout\n",
- device_get_nameunit(sc->sc_bus.bdev));
- return (USBD_TIMEOUT);
- }
- if (!(v & EHCI_PS_PE) &&
- (sc->sc_flags & EHCI_SCFLG_TT) == 0) {
- /* Not a high speed device, give up ownership.*/
- ehci_disown(sc, index, 0);
- break;
- }
- sc->sc_isreset = 1;
- DPRINTF(("ehci port %d reset, status = 0x%08x\n",
- index, v));
- break;
- case UHF_PORT_POWER:
- DPRINTFN(2,("ehci_root_ctrl_start: set port power "
- "%d\n", index));
- EOWRITE4(sc, port, v | EHCI_PS_PP);
- break;
- case UHF_PORT_TEST:
- DPRINTFN(2,("ehci_root_ctrl_start: set port test "
- "%d\n", index));
- break;
- case UHF_PORT_INDICATOR:
- DPRINTFN(2,("ehci_root_ctrl_start: set port ind "
- "%d\n", index));
- EOWRITE4(sc, port, v | EHCI_PS_PIC);
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER):
- case C(UR_RESET_TT, UT_WRITE_CLASS_OTHER):
- case C(UR_GET_TT_STATE, UT_READ_CLASS_OTHER):
- case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER):
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- xfer->actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
- ret:
- xfer->status = err;
- s = splusb();
- hacksync(xfer); /* XXX to compensate for usb_transfer_complete */
- usb_transfer_complete(xfer);
- splx(s);
- return (USBD_IN_PROGRESS);
-}
-
-void
-ehci_disown(ehci_softc_t *sc, int index, int lowspeed)
-{
- int port;
- u_int32_t v;
-
- DPRINTF(("ehci_disown: index=%d lowspeed=%d\n", index, lowspeed));
-#ifdef DIAGNOSTIC
- if (sc->sc_npcomp != 0) {
- int i = (index-1) / sc->sc_npcomp;
- if (i >= sc->sc_ncomp)
- printf("%s: strange port\n",
- device_get_nameunit(sc->sc_bus.bdev));
- else
- printf("%s: handing over %s speed device on "
- "port %d to %s\n",
- device_get_nameunit(sc->sc_bus.bdev),
- lowspeed ? "low" : "full",
- index, device_get_nameunit(sc->sc_comps[i]->bdev));
- } else {
- printf("%s: npcomp == 0\n", device_get_nameunit(sc->sc_bus.bdev));
- }
-#endif
- port = EHCI_PORTSC(index);
- v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
- EOWRITE4(sc, port, v | EHCI_PS_PO);
-}
-
-/* Abort a root control request. */
-static void
-ehci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- /* Nothing to do, all transfers are synchronous. */
-}
-
-/* Close the root pipe. */
-static void
-ehci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(("ehci_root_ctrl_close\n"));
- /* Nothing to do. */
-}
-
-void
-ehci_root_intr_done(usbd_xfer_handle xfer)
-{
-}
-
-static usbd_status
-ehci_root_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ehci_root_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ehci_root_intr_start(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- sc->sc_intrxfer = xfer;
-
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a root interrupt request. */
-static void
-ehci_root_intr_abort(usbd_xfer_handle xfer)
-{
- int s;
-
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTF(("ehci_root_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
- xfer->status = USBD_CANCELLED;
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
-}
-
-/* Close the root pipe. */
-static void
-ehci_root_intr_close(usbd_pipe_handle pipe)
-{
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
-
- DPRINTF(("ehci_root_intr_close\n"));
-
- sc->sc_intrxfer = NULL;
-}
-
-void
-ehci_root_ctrl_done(usbd_xfer_handle xfer)
-{
-}
-
-/************************/
-
-ehci_soft_qh_t *
-ehci_alloc_sqh(ehci_softc_t *sc)
-{
- ehci_soft_qh_t *sqh;
- ehci_soft_qtd_t *sqtd;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
-
- if (sc->sc_freeqhs == NULL) {
- DPRINTFN(2, ("ehci_alloc_sqh: allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, EHCI_SQH_SIZE * EHCI_SQH_CHUNK,
- EHCI_PAGE_SIZE, &dma);
-#ifdef EHCI_DEBUG
- if (err)
- printf("ehci_alloc_sqh: usb_allocmem()=%d\n", err);
-#endif
- if (err)
- return (NULL);
- for(i = 0; i < EHCI_SQH_CHUNK; i++) {
- offs = i * EHCI_SQH_SIZE;
- sqh = KERNADDR(&dma, offs);
- sqh->physaddr = DMAADDR(&dma, offs);
- sqh->next = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh;
- }
- }
- /* Allocate the initial inactive sqtd. */
- sqtd = ehci_alloc_sqtd(sc);
- if (sqtd == NULL)
- return (NULL);
- sqtd->qtd.qtd_status = htohc32(sc, 0);
- sqtd->qtd.qtd_next = EHCI_NULL(sc);
- sqtd->qtd.qtd_altnext = EHCI_NULL(sc);
-
- sqh = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh->next;
-
- /* The overlay QTD should begin zeroed. */
- sqh->qh.qh_qtd.qtd_next = htohc32(sc, sqtd->physaddr);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_status = 0;
- for (i = 0; i < EHCI_QTD_NBUFFERS; i++) {
- sqh->qh.qh_qtd.qtd_buffer[i] = 0;
- sqh->qh.qh_qtd.qtd_buffer_hi[i] = 0;
- }
- sqh->next = NULL;
- sqh->prev = NULL;
- sqh->sqtd = sqtd;
- sqh->inactivesqtd = sqtd;
- return (sqh);
-}
-
-void
-ehci_free_sqh(ehci_softc_t *sc, ehci_soft_qh_t *sqh)
-{
- ehci_free_sqtd(sc, sqh->inactivesqtd);
- sqh->next = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh;
-}
-
-ehci_soft_qtd_t *
-ehci_alloc_sqtd(ehci_softc_t *sc)
-{
- ehci_soft_qtd_t *sqtd;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
- int s;
-
- if (sc->sc_freeqtds == NULL) {
- DPRINTFN(2, ("ehci_alloc_sqtd: allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, EHCI_SQTD_SIZE*EHCI_SQTD_CHUNK,
- EHCI_PAGE_SIZE, &dma);
-#ifdef EHCI_DEBUG
- if (err)
- printf("ehci_alloc_sqtd: usb_allocmem()=%d\n", err);
-#endif
- if (err)
- return (NULL);
- s = splusb();
- for(i = 0; i < EHCI_SQTD_CHUNK; i++) {
- offs = i * EHCI_SQTD_SIZE;
- sqtd = KERNADDR(&dma, offs);
- sqtd->physaddr = DMAADDR(&dma, offs);
- sqtd->nextqtd = sc->sc_freeqtds;
- sc->sc_freeqtds = sqtd;
- }
- splx(s);
- }
-
- s = splusb();
- sqtd = sc->sc_freeqtds;
- sc->sc_freeqtds = sqtd->nextqtd;
- sqtd->qtd.qtd_next = EHCI_NULL(sc);
- sqtd->qtd.qtd_altnext = EHCI_NULL(sc);
- sqtd->qtd.qtd_status = 0;
- for (i = 0; i < EHCI_QTD_NBUFFERS; i++) {
- sqtd->qtd.qtd_buffer[i] = 0;
- sqtd->qtd.qtd_buffer_hi[i] = 0;
- }
- sqtd->nextqtd = NULL;
- sqtd->xfer = NULL;
- splx(s);
-
- return (sqtd);
-}
-
-void
-ehci_free_sqtd(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd)
-{
- int s;
-
- s = splusb();
- sqtd->nextqtd = sc->sc_freeqtds;
- sc->sc_freeqtds = sqtd;
- splx(s);
-}
-
-usbd_status
-ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc,
- int alen, int rd, usbd_xfer_handle xfer, ehci_soft_qtd_t *start,
- ehci_soft_qtd_t *newinactive, ehci_soft_qtd_t **sp, ehci_soft_qtd_t **ep)
-{
- ehci_soft_qtd_t *next, *cur;
- ehci_physaddr_t dataphys, nextphys;
- u_int32_t qtdstatus;
- int adj, len, curlen, mps, offset, pagelen, seg, segoff;
- int i, iscontrol, forceshort;
- struct usb_dma_mapping *dma = &xfer->dmamap;
-
- DPRINTFN(alen<4*4096,("ehci_alloc_sqtd_chain: start len=%d\n", alen));
-
- offset = 0;
- len = alen;
- iscontrol = (epipe->pipe.endpoint->edesc->bmAttributes & UE_XFERTYPE) ==
- UE_CONTROL;
- qtdstatus = EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(rd ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT) |
- EHCI_QTD_SET_CERR(3)
- /* IOC set below */
- /* BYTES set below */
- ;
- mps = UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize);
- forceshort = ((xfer->flags & USBD_FORCE_SHORT_XFER) || len == 0) &&
- len % mps == 0;
- /*
- * The control transfer data stage always starts with a toggle of 1.
- * For other transfers we let the hardware track the toggle state.
- */
- if (iscontrol)
- qtdstatus |= EHCI_QTD_SET_TOGGLE(1);
-
- if (start != NULL) {
- /*
- * If we are given a starting qTD, assume it is linked into
- * an active QH so be careful not to mark it active.
- */
- cur = start;
- *sp = cur;
- qtdstatus &= ~EHCI_QTD_ACTIVE;
- } else {
- cur = ehci_alloc_sqtd(sc);
- *sp = cur;
- if (cur == NULL)
- goto nomem;
- }
- seg = 0;
- segoff = 0;
- for (;;) {
- curlen = 0;
-
- /* The EHCI hardware can handle at most 5 pages. */
- for (i = 0; i < EHCI_QTD_NBUFFERS && curlen < len; i++) {
- KASSERT(seg < dma->nsegs,
- ("ehci_alloc_sqtd_chain: overrun"));
- dataphys = dma->segs[seg].ds_addr + segoff;
- pagelen = dma->segs[seg].ds_len - segoff;
- if (pagelen > len - curlen)
- pagelen = len - curlen;
- if (pagelen > EHCI_PAGE_SIZE -
- EHCI_PAGE_OFFSET(dataphys))
- pagelen = EHCI_PAGE_SIZE -
- EHCI_PAGE_OFFSET(dataphys);
- segoff += pagelen;
- if (segoff >= dma->segs[seg].ds_len) {
- KASSERT(segoff == dma->segs[seg].ds_len,
- ("ehci_alloc_sqtd_chain: overlap"));
- seg++;
- segoff = 0;
- }
-
- cur->qtd.qtd_buffer[i] = htohc32(sc, dataphys);
- cur->qtd.qtd_buffer_hi[i] = 0;
- curlen += pagelen;
-
- /*
- * Must stop if there is any gap before or after
- * the page boundary.
- */
- if (EHCI_PAGE_OFFSET(dataphys + pagelen) != 0)
- break;
- if (seg < dma->nsegs && EHCI_PAGE_OFFSET(segoff +
- dma->segs[seg].ds_addr) != 0)
- break;
- }
- /* Adjust down to a multiple of mps if not at the end. */
- if (curlen < len && curlen % mps != 0) {
- adj = curlen % mps;
- curlen -= adj;
- KASSERT(curlen > 0,
- ("ehci_alloc_sqtd_chain: need to copy"));
- segoff -= adj;
- if (segoff < 0) {
- seg--;
- segoff += dma->segs[seg].ds_len;
- }
- KASSERT(seg >= 0 && segoff >= 0,
- ("ehci_alloc_sqtd_chain: adjust to mps"));
- }
-
- len -= curlen;
-
- if (len != 0 || forceshort) {
- next = ehci_alloc_sqtd(sc);
- if (next == NULL)
- goto nomem;
- nextphys = htohc32(sc, next->physaddr);
- } else {
- next = NULL;
- nextphys = EHCI_NULL(sc);
- }
-
- cur->nextqtd = next;
- cur->qtd.qtd_next = nextphys;
- /* Make sure to stop after a short transfer. */
- cur->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- cur->qtd.qtd_status =
- htohc32(sc, qtdstatus | EHCI_QTD_SET_BYTES(curlen));
- cur->xfer = xfer;
- cur->len = curlen;
- DPRINTFN(10,("ehci_alloc_sqtd_chain: curlen=%d\n", curlen));
- if (iscontrol) {
- /*
- * adjust the toggle based on the number of packets
- * in this qtd
- */
- if ((((curlen + mps - 1) / mps) & 1) || curlen == 0)
- qtdstatus ^= EHCI_QTD_TOGGLE_MASK;
- }
- qtdstatus |= EHCI_QTD_ACTIVE;
- if (len == 0) {
- if (!forceshort)
- break;
- forceshort = 0;
- }
- DPRINTFN(10,("ehci_alloc_sqtd_chain: extend chain\n"));
- offset += curlen;
- cur = next;
- }
- cur->qtd.qtd_status |= htohc32(sc, EHCI_QTD_IOC);
- *ep = cur;
-
- DPRINTFN(10,("ehci_alloc_sqtd_chain: return sqtd=%p sqtdend=%p\n",
- *sp, *ep));
-
- return (USBD_NORMAL_COMPLETION);
-
- nomem:
- /* XXX free chain */
- DPRINTFN(-1,("ehci_alloc_sqtd_chain: no memory\n"));
- return (USBD_NOMEM);
-}
-
-/* Free the chain starting at sqtd and end at the qTD before sqtdend */
-static void
-ehci_free_sqtd_chain(ehci_softc_t *sc, ehci_soft_qh_t *sqh,
- ehci_soft_qtd_t *sqtd, ehci_soft_qtd_t *sqtdend)
-{
- ehci_soft_qtd_t *p, **prevp;
- int i;
-
- DPRINTFN(10,("ehci_free_sqtd_chain: sqtd=%p sqtdend=%p\n",
- sqtd, sqtdend));
-
- /* First unlink the chain from the QH's software qTD list. */
- prevp = &sqh->sqtd;
- for (p = sqh->sqtd; p != NULL; p = p->nextqtd) {
- if (p == sqtd) {
- *prevp = sqtdend;
- break;
- }
- prevp = &p->nextqtd;
- }
- KASSERT(p != NULL, ("ehci_free_sqtd_chain: chain not found"));
- for (i = 0; sqtd != sqtdend; sqtd = p, i++) {
- p = sqtd->nextqtd;
- ehci_free_sqtd(sc, sqtd);
- }
-}
-
-ehci_soft_itd_t *
-ehci_alloc_itd(ehci_softc_t *sc)
-{
- struct ehci_soft_itd *itd, *freeitd;
- usbd_status err;
- int i, s, offs, frindex, previndex;
- usb_dma_t dma;
-
- s = splusb();
-
- /* Find an itd that wasn't freed this frame or last frame. This can
- * discard itds that were freed before frindex wrapped around
- * XXX - can this lead to thrashing? Could fix by enabling wrap-around
- * interrupt and fiddling with list when that happens */
- frindex = (EOREAD4(sc, EHCI_FRINDEX) + 1) >> 3;
- previndex = (frindex != 0) ? frindex - 1 : sc->sc_flsize;
-
- freeitd = NULL;
- LIST_FOREACH(itd, &sc->sc_freeitds, u.free_list) {
- if (itd == NULL)
- break;
- if (itd->slot != frindex && itd->slot != previndex) {
- freeitd = itd;
- break;
- }
- }
-
- if (freeitd == NULL) {
- DPRINTFN(2, ("ehci_alloc_itd allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, EHCI_ITD_SIZE * EHCI_ITD_CHUNK,
- EHCI_PAGE_SIZE, &dma);
-
- if (err) {
- DPRINTF(("ehci_alloc_itd, alloc returned %d\n", err));
- return NULL;
- }
-
- for (i = 0; i < EHCI_ITD_CHUNK; i++) {
- offs = i * EHCI_ITD_SIZE;
- itd = KERNADDR(&dma, offs);
- itd->physaddr = DMAADDR(&dma, offs);
- itd->dma = dma;
- itd->offs = offs;
- LIST_INSERT_HEAD(&sc->sc_freeitds, itd, u.free_list);
- }
- freeitd = LIST_FIRST(&sc->sc_freeitds);
- }
-
- itd = freeitd;
- LIST_REMOVE(itd, u.free_list);
- memset(&itd->itd, 0, sizeof(ehci_itd_t));
- itd->u.frame_list.next = NULL;
- itd->u.frame_list.prev = NULL;
- itd->xfer_next = NULL;
- itd->slot = 0;
- splx(s);
-
- return (itd);
-}
-
-void
-ehci_free_itd(ehci_softc_t *sc, ehci_soft_itd_t *itd)
-{
- int s;
-
- s = splusb();
- LIST_INSERT_AFTER(LIST_FIRST(&sc->sc_freeitds), itd, u.free_list);
- splx(s);
-}
-
-/****************/
-
-/*
- * Close a reqular pipe.
- * Assumes that there are no pending transactions.
- */
-void
-ehci_close_pipe(usbd_pipe_handle pipe, ehci_soft_qh_t *head)
-{
- struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
- ehci_soft_qh_t *sqh = epipe->sqh;
- int s;
-
- s = splusb();
- ehci_rem_qh(sc, sqh, head);
- splx(s);
- pipe->endpoint->savedtoggle =
- EHCI_QTD_GET_TOGGLE(hc32toh(sc, sqh->qh.qh_qtd.qtd_status));
- ehci_free_sqh(sc, epipe->sqh);
-}
-
-/*
- * Abort a device request.
- * If this routine is called at splusb() it guarantees that the request
- * will be removed from the hardware scheduling and that the callback
- * for it will be called with USBD_CANCELLED status.
- * It's impossible to guarantee that the requested transfer will not
- * have happened since the hardware runs concurrently.
- * If the transaction has already happened we rely on the ordinary
- * interrupt processing to process it.
- */
-void
-ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
-{
-#define exfer EXFER(xfer)
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
- ehci_soft_qh_t *sqh = epipe->sqh;
- ehci_soft_qtd_t *sqtd, *snext;
- ehci_physaddr_t cur, us, next;
- int s;
- int hit, i;
- /* int count = 0; */
- ehci_soft_qh_t *psqh;
-
- DPRINTF(("ehci_abort_xfer: xfer=%p pipe=%p\n", xfer, epipe));
-
- if (sc->sc_dying) {
- /* If we're dying, just do the software part. */
- s = splusb();
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(epipe->pipe.device, &exfer->abort_task);
- usb_transfer_complete(xfer);
- splx(s);
- return;
- }
-
- if (xfer->device->bus->intr_context)
- panic("ehci_abort_xfer: not in process context");
-
- /*
- * If an abort is already in progress then just wait for it to
- * complete and return.
- */
- if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING) {
- DPRINTFN(2, ("ehci_abort_xfer: already aborting\n"));
- /* No need to wait if we're aborting from a timeout. */
- if (status == USBD_TIMEOUT)
- return;
- /* Override the status which might be USBD_TIMEOUT. */
- xfer->status = status;
- DPRINTFN(2, ("ehci_abort_xfer: waiting for abort to finish\n"));
- exfer->ehci_xfer_flags |= EHCI_XFER_ABORTWAIT;
- while (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING)
- tsleep(&exfer->ehci_xfer_flags, PZERO, "ehciaw", 0);
- return;
- }
-
- /*
- * Step 1: Make interrupt routine and timeouts ignore xfer.
- */
- s = splusb();
- exfer->ehci_xfer_flags |= EHCI_XFER_ABORTING;
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(epipe->pipe.device, &exfer->abort_task);
- splx(s);
-
- /*
- * Step 2: Wait until we know hardware has finished any possible
- * use of the xfer. We do this by removing the entire
- * queue from the async schedule and waiting for the doorbell.
- * Nothing else should be touching the queue now.
- */
- psqh = sqh->prev;
- ehci_rem_qh(sc, sqh, psqh);
-
- /*
- * Step 3: make sure the soft interrupt routine
- * has run. This should remove any completed items off the queue.
- * The hardware has no reference to completed items (TDs).
- * It's safe to remove them at any time.
- */
- s = splusb();
-#ifdef USB_USE_SOFTINTR
- sc->sc_softwake = 1;
-#endif /* USB_USE_SOFTINTR */
- usb_schedsoftintr(&sc->sc_bus);
-#ifdef USB_USE_SOFTINTR
- tsleep(&sc->sc_softwake, PZERO, "ehciab", 0);
-#endif /* USB_USE_SOFTINTR */
-
- /*
- * Step 4: Remove any vestiges of the xfer from the hardware.
- * The complication here is that the hardware may have executed
- * into or even beyond the xfer we're trying to abort.
- * So as we're scanning the TDs of this xfer we check if
- * the hardware points to any of them.
- *
- * first we need to see if there are any transfers
- * on this queue before the xfer we are aborting.. we need
- * to update any pointers that point to us to point past
- * the aborting xfer. (If there is something past us).
- * Hardware and software.
- */
- cur = EHCI_LINK_ADDR(hc32toh(sc, sqh->qh.qh_curqtd));
- hit = 0;
-
- /* If they initially point here. */
- us = exfer->sqtdstart->physaddr;
-
- /* We will change them to point here */
- snext = exfer->sqtdend->nextqtd;
- next = (snext != NULL) ? htohc32(sc, snext->physaddr) : EHCI_NULL(sc);
-
- /*
- * Now loop through any qTDs before us and keep track of the pointer
- * that points to us for the end.
- */
- sqtd = sqh->sqtd;
- while (sqtd && sqtd != exfer->sqtdstart) {
- hit |= (cur == sqtd->physaddr);
- if (EHCI_LINK_ADDR(hc32toh(sc, sqtd->qtd.qtd_next)) == us)
- sqtd->qtd.qtd_next = next;
- if (EHCI_LINK_ADDR(hc32toh(sc, sqtd->qtd.qtd_altnext)) == us)
- sqtd->qtd.qtd_altnext = next;
- sqtd = sqtd->nextqtd;
- }
-
- /*
- * If we already saw the active one then we are pretty much done.
- * We've done all the relinking we need to do.
- */
- if (!hit) {
-
- /*
- * Now reinitialise the QH to point to the next qTD
- * (if there is one). We only need to do this if
- * it was previously pointing to us.
- */
- for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) {
- if (cur == sqtd->physaddr) {
- hit++;
- }
- if (sqtd == exfer->sqtdend)
- break;
- }
- sqtd = sqtd->nextqtd;
- /*
- * Only need to alter the QH if it was pointing at a qTD
- * that we are removing.
- */
- if (hit) {
- sqh->qh.qh_qtd.qtd_next = htohc32(sc, snext->physaddr);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_status &=
- htohc32(sc, EHCI_QTD_TOGGLE_MASK);
- for (i = 0; i < EHCI_QTD_NBUFFERS; i++) {
- sqh->qh.qh_qtd.qtd_buffer[i] = 0;
- sqh->qh.qh_qtd.qtd_buffer_hi[i] = 0;
- }
- }
- }
- ehci_add_qh(sc, sqh, psqh);
- /*
- * Step 5: Execute callback.
- */
-#ifdef DIAGNOSTIC
- exfer->isdone = 1;
-#endif
- /* Do the wakeup first to avoid touching the xfer after the callback. */
- exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTING;
- if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTWAIT) {
- exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTWAIT;
- wakeup(&exfer->ehci_xfer_flags);
- }
- usb_transfer_complete(xfer);
-
- /* printf("%s: %d TDs aborted\n", __func__, count); */
- splx(s);
-#undef exfer
-}
-
-void
-ehci_timeout(void *addr)
-{
- struct ehci_xfer *exfer = addr;
- struct ehci_pipe *epipe = (struct ehci_pipe *)exfer->xfer.pipe;
- ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
-
- DPRINTF(("ehci_timeout: exfer=%p\n", exfer));
-#ifdef USB_DEBUG
- if (ehcidebug > 1)
- usbd_dump_pipe(exfer->xfer.pipe);
-#endif
-
- if (sc->sc_dying) {
- ehci_abort_xfer(&exfer->xfer, USBD_TIMEOUT);
- return;
- }
-
- /* Execute the abort in a process context. */
- usb_add_task(exfer->xfer.pipe->device, &exfer->abort_task,
- USB_TASKQ_HC);
-}
-
-void
-ehci_abort_isoc_xfer(usbd_xfer_handle xfer, usbd_status status)
-{
- ehci_isoc_trans_t trans_status;
- struct ehci_pipe *epipe;
- struct ehci_xfer *exfer;
- ehci_softc_t *sc;
- struct ehci_soft_itd *itd;
- int s, i;
-
- epipe = (struct ehci_pipe *) xfer->pipe;
- exfer = EXFER(xfer);
- sc = (ehci_softc_t *)epipe->pipe.device->bus;
-
- DPRINTF(("ehci_abort_isoc_xfer: xfer %p pipe %p\n", xfer, epipe));
-
- if (sc->sc_dying) {
- s = splusb();
- xfer->status = status;
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(epipe->pipe.device, &exfer->abort_task);
- usb_transfer_complete(xfer);
- splx(s);
- return;
- }
-
- if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING) {
- DPRINTFN(2, ("ehci_abort_isoc_xfer: already aborting\n"));
-
-#ifdef DIAGNOSTIC
- if (status == USBD_TIMEOUT)
- printf("ehci_abort_xfer: TIMEOUT while aborting\n");
-#endif
-
- xfer->status = status;
- DPRINTFN(2, ("ehci_abort_xfer: waiting for abort to finish\n"));
- exfer->ehci_xfer_flags |= EHCI_XFER_ABORTWAIT;
- while (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING)
- tsleep(&exfer->ehci_xfer_flags, PZERO, "ehciaw", 0);
- return;
- }
- exfer->ehci_xfer_flags |= EHCI_XFER_ABORTING;
-
- xfer->status = status;
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(epipe->pipe.device, &exfer->abort_task);
-
- s = splusb();
- for (itd = exfer->itdstart; itd != NULL; itd = itd->xfer_next) {
-
- for (i = 0; i < 8; i++) {
- trans_status = hc32toh(sc, itd->itd.itd_ctl[i]);
- trans_status &= ~EHCI_ITD_ACTIVE;
- itd->itd.itd_ctl[i] = htohc32(sc, trans_status);
- }
-
- }
- splx(s);
-
- s = splusb();
-#ifdef USB_USE_SOFTINTR
- sc->sc_softwake = 1;
-#endif /* USB_USE_SOFTINTR */
- usb_schedsoftintr(&sc->sc_bus);
-#ifdef USB_USE_SOFTINTR
- tsleep(&sc->sc_softwake, PZERO, "ehciab", 0);
-#endif /* USB_USE_SOFTINTR */
- splx(s);
-
-#ifdef DIAGNOSTIC
- exfer->isdone = 1;
-#endif
- exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTING;
- if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTWAIT) {
- exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTWAIT;
- wakeup(&exfer->ehci_xfer_flags);
- }
- usb_transfer_complete(xfer);
-}
-
-void
-ehci_timeout_task(void *addr)
-{
- usbd_xfer_handle xfer = addr;
- int s;
-
- DPRINTF(("ehci_timeout_task: xfer=%p\n", xfer));
-
- s = splusb();
- ehci_abort_xfer(xfer, USBD_TIMEOUT);
- splx(s);
-}
-
-/*
- * Some EHCI chips from VIA / ATI seem to trigger interrupts before writing
- * back the qTD status, or miss signalling occasionally under heavy load.
- * If the host machine is too fast, we can miss transaction completion - when
- * we scan the active list the transaction still seems to be active. This
- * generally exhibits itself as a umass stall that never recovers.
- *
- * We work around this behaviour by setting up this callback after any softintr
- * that completes with transactions still pending, giving us another chance to
- * check for completion after the writeback has taken place.
- */
-void
-ehci_intrlist_timeout(void *arg)
-{
- ehci_softc_t *sc = arg;
- int s = splusb();
-
- DPRINTFN(3, ("ehci_intrlist_timeout\n"));
- usb_schedsoftintr(&sc->sc_bus);
-
- splx(s);
-}
-
-/************************/
-
-static usbd_status
-ehci_device_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ehci_device_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ehci_device_ctrl_start(usbd_xfer_handle xfer)
-{
- ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST)) {
- /* XXX panic */
- printf("ehci_device_ctrl_transfer: not a request\n");
- return (USBD_INVAL);
- }
-#endif
-
- err = ehci_device_request(xfer);
- if (err)
- return (err);
-
- if (sc->sc_bus.use_polling)
- ehci_waitintr(sc, xfer);
- return (USBD_IN_PROGRESS);
-}
-
-void
-ehci_device_ctrl_done(usbd_xfer_handle xfer)
-{
- struct ehci_xfer *ex = EXFER(xfer);
- ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
-
- DPRINTFN(10,("ehci_ctrl_done: xfer=%p\n", xfer));
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST)) {
- panic("ehci_ctrl_done: not a request");
- }
-#endif
-
- if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
- ehci_del_intr_list(ex); /* remove from active list */
- ehci_free_sqtd_chain(sc, epipe->sqh, ex->sqtdstart,
- ex->sqtdend->nextqtd);
- }
-
- DPRINTFN(5, ("ehci_ctrl_done: length=%d\n", xfer->actlen));
-}
-
-/* Abort a device control request. */
-static void
-ehci_device_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("ehci_device_ctrl_abort: xfer=%p\n", xfer));
- ehci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/* Close a device control pipe. */
-static void
-ehci_device_ctrl_close(usbd_pipe_handle pipe)
-{
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
- /*struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;*/
-
- DPRINTF(("ehci_device_ctrl_close: pipe=%p\n", pipe));
- ehci_close_pipe(pipe, sc->sc_async_head);
-}
-
-usbd_status
-ehci_device_request(usbd_xfer_handle xfer)
-{
-#define exfer EXFER(xfer)
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- usb_device_request_t *req = &xfer->request;
- usbd_device_handle dev = epipe->pipe.device;
- ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
- ehci_soft_qtd_t *newinactive, *setup, *stat, *next;
- ehci_soft_qh_t *sqh;
- int isread;
- int len;
- usbd_status err;
- int s;
-
- isread = req->bmRequestType & UT_READ;
- len = UGETW(req->wLength);
-
- DPRINTFN(3,("ehci_device_request: type=0x%02x, request=0x%02x, "
- "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
- req->bmRequestType, req->bRequest, UGETW(req->wValue),
- UGETW(req->wIndex), len, dev->address,
- epipe->pipe.endpoint->edesc->bEndpointAddress));
-
- newinactive = ehci_alloc_sqtd(sc);
- if (newinactive == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- newinactive->qtd.qtd_status = htohc32(sc, 0);
- newinactive->qtd.qtd_next = EHCI_NULL(sc);
- newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
-
- stat = ehci_alloc_sqtd(sc);
- if (stat == NULL) {
- err = USBD_NOMEM;
- goto bad2;
- }
-
- sqh = epipe->sqh;
- setup = sqh->inactivesqtd;
- sqh->inactivesqtd = newinactive;
- epipe->u.ctl.length = len;
-
- /* Set up data transaction */
- if (len != 0) {
- ehci_soft_qtd_t *end;
-
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
- NULL, newinactive, &next, &end);
- if (err)
- goto bad3;
- end->qtd.qtd_status &= htohc32(sc, ~EHCI_QTD_IOC);
- end->nextqtd = stat;
- end->qtd.qtd_next = htohc32(sc, stat->physaddr);
- end->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- } else {
- next = stat;
- }
-
- memcpy(KERNADDR(&epipe->u.ctl.reqdma, 0), req, sizeof *req);
-
- /* Clear toggle, and do not activate until complete */
- setup->qtd.qtd_status = htohc32(sc,
- EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) |
- EHCI_QTD_SET_CERR(3) |
- EHCI_QTD_SET_TOGGLE(0) |
- EHCI_QTD_SET_BYTES(sizeof *req)
- );
- setup->qtd.qtd_buffer[0] = htohc32(sc, DMAADDR(&epipe->u.ctl.reqdma, 0));
- setup->qtd.qtd_buffer_hi[0] = 0;
- setup->nextqtd = next;
- setup->qtd.qtd_next = htohc32(sc, next->physaddr);
- setup->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- setup->xfer = xfer;
- setup->len = sizeof *req;
-
- stat->qtd.qtd_status = htohc32(sc,
- EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) |
- EHCI_QTD_SET_CERR(3) |
- EHCI_QTD_SET_TOGGLE(1) |
- EHCI_QTD_IOC
- );
- stat->qtd.qtd_buffer[0] = 0; /* XXX not needed? */
- stat->qtd.qtd_buffer_hi[0] = 0; /* XXX not needed? */
- stat->nextqtd = newinactive;
- stat->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
- stat->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- stat->xfer = xfer;
- stat->len = 0;
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 5) {
- DPRINTF(("ehci_device_request:\n"));
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, setup);
- }
-#endif
-
- exfer->sqtdstart = setup;
- exfer->sqtdend = stat;
-#ifdef DIAGNOSTIC
- if (!exfer->isdone) {
- printf("ehci_device_request: not done, exfer=%p\n", exfer);
- }
- exfer->isdone = 0;
-#endif
-
- /* Activate the new qTD in the QH list. */
- s = splusb();
- ehci_activate_qh(sc, sqh, setup);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ehci_timeout, xfer);
- }
- ehci_add_intr_list(sc, exfer);
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 10) {
- DPRINTF(("ehci_device_request: status=%x\n",
- EOREAD4(sc, EHCI_USBSTS)));
- delay(10000);
- ehci_dump_regs(sc);
- ehci_dump_sqh(sc, sc->sc_async_head);
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, setup);
- }
-#endif
-
- return (USBD_NORMAL_COMPLETION);
-
- bad3:
- sqh->inactivesqtd = setup;
- ehci_free_sqtd(sc, stat);
- bad2:
- ehci_free_sqtd(sc, newinactive);
- bad1:
- DPRINTFN(-1,("ehci_device_request: no memory\n"));
- xfer->status = err;
- usb_transfer_complete(xfer);
- return (err);
-#undef exfer
-}
-
-/************************/
-
-static usbd_status
-ehci_device_bulk_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ehci_device_bulk_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-usbd_status
-ehci_device_bulk_start(usbd_xfer_handle xfer)
-{
-#define exfer EXFER(xfer)
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- usbd_device_handle dev = epipe->pipe.device;
- ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
- ehci_soft_qtd_t *data, *dataend, *newinactive;
- ehci_soft_qh_t *sqh;
- usbd_status err;
- int len, isread, endpt;
- int s;
-
- DPRINTFN(2, ("ehci_device_bulk_start: xfer=%p len=%d flags=%d\n",
- xfer, xfer->length, xfer->flags));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("ehci_device_bulk_start: a request");
-#endif
-
- len = xfer->length;
- endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- sqh = epipe->sqh;
-
- epipe->u.bulk.length = len;
-
- newinactive = ehci_alloc_sqtd(sc);
- if (newinactive == NULL) {
- DPRINTFN(-1,("ehci_device_bulk_start: no sqtd memory\n"));
- err = USBD_NOMEM;
- xfer->status = err;
- usb_transfer_complete(xfer);
- return (err);
- }
- newinactive->qtd.qtd_status = htohc32(sc, 0);
- newinactive->qtd.qtd_next = EHCI_NULL(sc);
- newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
- sqh->inactivesqtd, newinactive, &data, &dataend);
- if (err) {
- DPRINTFN(-1,("ehci_device_bulk_start: no memory\n"));
- ehci_free_sqtd(sc, newinactive);
- xfer->status = err;
- usb_transfer_complete(xfer);
- return (err);
- }
- dataend->nextqtd = newinactive;
- dataend->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
- dataend->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- sqh->inactivesqtd = newinactive;
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 5) {
- DPRINTF(("ehci_device_bulk_start: data(1)\n"));
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, data);
- }
-#endif
-
- /* Set up interrupt info. */
- exfer->sqtdstart = data;
- exfer->sqtdend = dataend;
-#ifdef DIAGNOSTIC
- if (!exfer->isdone) {
- printf("ehci_device_bulk_start: not done, ex=%p\n", exfer);
- }
- exfer->isdone = 0;
-#endif
-
- s = splusb();
- ehci_activate_qh(sc, sqh, data);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ehci_timeout, xfer);
- }
- ehci_add_intr_list(sc, exfer);
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 10) {
- DPRINTF(("ehci_device_bulk_start: data(2)\n"));
- delay(10000);
- DPRINTF(("ehci_device_bulk_start: data(3)\n"));
- ehci_dump_regs(sc);
-#if 0
- printf("async_head:\n");
- ehci_dump_sqh(sc->sc_async_head);
-#endif
- printf("sqh:\n");
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, data);
- }
-#endif
-
- if (sc->sc_bus.use_polling)
- ehci_waitintr(sc, xfer);
-
- return (USBD_IN_PROGRESS);
-#undef exfer
-}
-
-static void
-ehci_device_bulk_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("ehci_device_bulk_abort: xfer=%p\n", xfer));
- ehci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/*
- * Close a device bulk pipe.
- */
-static void
-ehci_device_bulk_close(usbd_pipe_handle pipe)
-{
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
-
- DPRINTF(("ehci_device_bulk_close: pipe=%p\n", pipe));
- ehci_close_pipe(pipe, sc->sc_async_head);
-}
-
-void
-ehci_device_bulk_done(usbd_xfer_handle xfer)
-{
- struct ehci_xfer *ex = EXFER(xfer);
- ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
-
- DPRINTFN(10,("ehci_bulk_done: xfer=%p, actlen=%d\n",
- xfer, xfer->actlen));
-
- if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
- ehci_del_intr_list(ex); /* remove from active list */
- ehci_free_sqtd_chain(sc, epipe->sqh, ex->sqtdstart,
- ex->sqtdend->nextqtd);
- }
-
- DPRINTFN(5, ("ehci_bulk_done: length=%d\n", xfer->actlen));
-}
-
-/************************/
-
-static usbd_status
-ehci_device_setintr(ehci_softc_t *sc, ehci_soft_qh_t *sqh, int ival)
-{
- struct ehci_soft_islot *isp;
- int islot, lev;
-
- /* Find a poll rate that is large enough. */
- for (lev = EHCI_IPOLLRATES - 1; lev > 0; lev--)
- if (EHCI_ILEV_IVAL(lev) <= ival)
- break;
-
- /* Pick an interrupt slot at the right level. */
- /* XXX could do better than picking at random. */
- islot = EHCI_IQHIDX(lev, arc4random());
-
- sqh->islot = islot;
- isp = &sc->sc_islots[islot];
- ehci_add_qh(sc, sqh, isp->sqh);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-ehci_device_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (ehci_device_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ehci_device_intr_start(usbd_xfer_handle xfer)
-{
-#define exfer EXFER(xfer)
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- usbd_device_handle dev = xfer->pipe->device;
- ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
- ehci_soft_qtd_t *data, *dataend, *newinactive;
- ehci_soft_qh_t *sqh;
- usbd_status err;
- int len, isread, endpt;
- int s;
-
- DPRINTFN(2, ("ehci_device_intr_start: xfer=%p len=%d flags=%d\n",
- xfer, xfer->length, xfer->flags));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("ehci_device_intr_start: a request");
-#endif
-
- len = xfer->length;
- endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- sqh = epipe->sqh;
-
- epipe->u.intr.length = len;
-
- newinactive = ehci_alloc_sqtd(sc);
- if (newinactive == NULL) {
- DPRINTFN(-1,("ehci_device_intr_start: no sqtd memory\n"));
- err = USBD_NOMEM;
- xfer->status = err;
- usb_transfer_complete(xfer);
- return (err);
- }
- newinactive->qtd.qtd_status = htohc32(sc, 0);
- newinactive->qtd.qtd_next = EHCI_NULL(sc);
- newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
- sqh->inactivesqtd, newinactive, &data, &dataend);
- if (err) {
- DPRINTFN(-1, ("ehci_device_intr_start: no memory\n"));
- xfer->status = err;
- usb_transfer_complete(xfer);
- return (err);
- }
- dataend->nextqtd = newinactive;
- dataend->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
- dataend->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- sqh->inactivesqtd = newinactive;
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 5) {
- DPRINTF(("ehci_device_intr_start: data(1)\n"));
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, data);
- }
-#endif
-
- /* Set up interrupt info. */
- exfer->sqtdstart = data;
- exfer->sqtdend = dataend;
-#ifdef DIAGNOSTIC
- if (!exfer->isdone) {
- printf("ehci_device_intr_start: not done, ex=%p\n", exfer);
- }
- exfer->isdone = 0;
-#endif
-
- s = splusb();
- ehci_activate_qh(sc, sqh, data);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ehci_timeout, xfer);
- }
- ehci_add_intr_list(sc, exfer);
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 10) {
- DPRINTF(("ehci_device_intr_start: data(2)\n"));
- delay(10000);
- DPRINTF(("ehci_device_intr_start: data(3)\n"));
- ehci_dump_regs(sc);
- printf("sqh:\n");
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, data);
- }
-#endif
-
- if (sc->sc_bus.use_polling)
- ehci_waitintr(sc, xfer);
-
- return (USBD_IN_PROGRESS);
-#undef exfer
-}
-
-static void
-ehci_device_intr_abort(usbd_xfer_handle xfer)
-{
- DPRINTFN(1, ("ehci_device_intr_abort: xfer=%p\n", xfer));
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTFN(1, ("ehci_device_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
- /*
- * XXX - abort_xfer uses ehci_sync_hc, which syncs via the advance
- * async doorbell. That's dependant on the async list, wheras
- * intr xfers are periodic, should not use this?
- */
- ehci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-static void
-ehci_device_intr_close(usbd_pipe_handle pipe)
-{
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
- struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
- struct ehci_soft_islot *isp;
-
- isp = &sc->sc_islots[epipe->sqh->islot];
- ehci_close_pipe(pipe, isp->sqh);
-}
-
-static void
-ehci_device_intr_done(usbd_xfer_handle xfer)
-{
-#define exfer EXFER(xfer)
- struct ehci_xfer *ex = EXFER(xfer);
- ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- ehci_soft_qtd_t *data, *dataend, *newinactive;
- ehci_soft_qh_t *sqh;
- usbd_status err;
- int len, isread, endpt, s;
-
- DPRINTFN(10, ("ehci_device_intr_done: xfer=%p, actlen=%d\n",
- xfer, xfer->actlen));
-
- sqh = epipe->sqh;
- if (xfer->pipe->repeat) {
- ehci_free_sqtd_chain(sc, sqh, ex->sqtdstart,
- ex->sqtdend->nextqtd);
-
- len = epipe->u.intr.length;
- xfer->length = len;
- endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
-
- newinactive = ehci_alloc_sqtd(sc);
- if (newinactive == NULL) {
- DPRINTFN(-1,
- ("ehci_device_intr_done: no sqtd memory\n"));
- err = USBD_NOMEM;
- xfer->status = err;
- return;
- }
- newinactive->qtd.qtd_status = htohc32(sc, 0);
- newinactive->qtd.qtd_next = EHCI_NULL(sc);
- newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
- sqh->inactivesqtd, newinactive, &data, &dataend);
- if (err) {
- DPRINTFN(-1, ("ehci_device_intr_done: no memory\n"));
- xfer->status = err;
- return;
- }
- dataend->nextqtd = newinactive;
- dataend->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
- dataend->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- sqh->inactivesqtd = newinactive;
-
- /* Set up interrupt info. */
- exfer->sqtdstart = data;
- exfer->sqtdend = dataend;
-#ifdef DIAGNOSTIC
- if (!exfer->isdone) {
- printf("ehci_device_intr_done: not done, ex=%p\n",
- exfer);
- }
- exfer->isdone = 0;
-#endif
-
- s = splusb();
- ehci_activate_qh(sc, sqh, data);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle,
- MS_TO_TICKS(xfer->timeout), ehci_timeout, xfer);
- }
- splx(s);
-
- xfer->status = USBD_IN_PROGRESS;
- } else if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
- ehci_del_intr_list(ex); /* remove from active list */
- ehci_free_sqtd_chain(sc, sqh, ex->sqtdstart,
- ex->sqtdend->nextqtd);
- }
-#undef exfer
-}
-
-/************************/
-
-static usbd_status
-ehci_device_isoc_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- err = usb_insert_transfer(xfer);
- if (err && err != USBD_IN_PROGRESS)
- return (err);
-
- return (ehci_device_isoc_start(xfer));
-}
-
-static usbd_status
-ehci_device_isoc_start(usbd_xfer_handle xfer)
-{
- struct ehci_pipe *epipe;
- usbd_device_handle dev;
- ehci_softc_t *sc;
- struct ehci_xfer *exfer;
- ehci_soft_itd_t *itd, *prev, *start, *stop;
- usb_dma_t *dma_buf;
- int i, j, k, frames, uframes, ufrperframe;
- int s, trans_count, offs, total_length;
- int frindex;
-
- start = NULL;
- prev = NULL;
- itd = NULL;
- trans_count = 0;
- total_length = 0;
- exfer = (struct ehci_xfer *) xfer;
- sc = (ehci_softc_t *)xfer->pipe->device->bus;
- dev = xfer->pipe->device;
- epipe = (struct ehci_pipe *)xfer->pipe;
-
- /*
- * To allow continuous transfers, above we start all transfers
- * immediately. However, we're still going to get usbd_start_next call
- * this when another xfer completes. So, check if this is already
- * in progress or not
- */
-
- if (exfer->itdstart != NULL)
- return (USBD_IN_PROGRESS);
-
- DPRINTFN(2, ("ehci_device_isoc_start: xfer %p len %d flags %d\n",
- xfer, xfer->length, xfer->flags));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- /*
- * To avoid complication, don't allow a request right now that'll span
- * the entire frame table. To within 4 frames, to allow some leeway
- * on either side of where the hc currently is.
- */
- if ((1 << (epipe->pipe.endpoint->edesc->bInterval)) *
- xfer->nframes >= (sc->sc_flsize - 4) * 8) {
- printf("ehci: isoc descriptor requested that spans the entire"
- " frametable, too many frames\n");
- return (USBD_INVAL);
- }
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("ehci_device_isoc_start: request\n");
-
- if (!exfer->isdone)
- printf("ehci_device_isoc_start: not done, ex = %p\n", exfer);
- exfer->isdone = 0;
-#endif
-
- /*
- * Step 1: Allocate and initialize itds, how many do we need?
- * One per transfer if interval >= 8 microframes, fewer if we use
- * multiple microframes per frame.
- */
-
- i = epipe->pipe.endpoint->edesc->bInterval;
- if (i > 16 || i == 0) {
- /* Spec page 271 says intervals > 16 are invalid */
- DPRINTF(("ehci_device_isoc_start: bInvertal %d invalid\n", i));
- return (USBD_INVAL);
- }
-
- switch (i) {
- case 1:
- ufrperframe = 8;
- break;
- case 2:
- ufrperframe = 4;
- break;
- case 3:
- ufrperframe = 2;
- break;
- default:
- ufrperframe = 1;
- break;
- }
- frames = (xfer->nframes + (ufrperframe - 1)) / ufrperframe;
- uframes = 8 / ufrperframe;
-
- if (frames == 0) {
- DPRINTF(("ehci_device_isoc_start: frames == 0\n"));
- return (USBD_INVAL);
- }
-
- dma_buf = xfer->buffer;
- offs = 0;
-
- for (i = 0; i < frames; i++) {
- int froffs = offs;
- itd = ehci_alloc_itd(sc);
-
- if (prev != NULL) {
- prev->itd.itd_next =
- htohc32(sc, itd->physaddr | EHCI_LINK_ITD);
- prev->xfer_next = itd;
- } else {
- start = itd;
- }
-
- /*
- * Step 1.5, initialize uframes
- */
- for (j = 0; j < 8; j += uframes) {
- /* Calculate which page in the list this starts in */
- int addr = DMAADDR(dma_buf, froffs);
- addr = EHCI_PAGE_OFFSET(addr);
- addr += (offs - froffs);
- addr = EHCI_PAGE(addr);
- addr /= EHCI_PAGE_SIZE;
-
- /* This gets the initial offset into the first page,
- * looks how far further along the current uframe
- * offset is. Works out how many pages that is.
- */
-
- itd->itd.itd_ctl[j] = htohc32(sc, EHCI_ITD_ACTIVE |
- EHCI_ITD_SET_LEN(xfer->frlengths[trans_count]) |
- EHCI_ITD_SET_PG(addr) |
- EHCI_ITD_SET_OFFS(EHCI_PAGE_OFFSET(DMAADDR(dma_buf,
- offs))));
-
- total_length += xfer->frlengths[trans_count];
- offs += xfer->frlengths[trans_count];
- trans_count++;
-
- if (trans_count >= xfer->nframes) { /*Set IOC*/
- itd->itd.itd_ctl[j] |= htohc32(sc, EHCI_ITD_IOC);
- }
- }
-
- /* Step 1.75, set buffer pointers. To simplify matters, all
- * pointers are filled out for the next 7 hardware pages in
- * the dma block, so no need to worry what pages to cover
- * and what to not.
- */
-
- for (j=0; j < 7; j++) {
- /*
- * Don't try to lookup a page that's past the end
- * of buffer
- */
- int page_offs = EHCI_PAGE(froffs +
- (EHCI_PAGE_SIZE * j));
- if (page_offs >= dma_buf->block->size)
- break;
-
- int page = DMAADDR(dma_buf, page_offs);
- page = EHCI_PAGE(page);
- itd->itd.itd_bufr[j] =
- htohc32(sc, EHCI_ITD_SET_BPTR(page) | EHCI_LINK_ITD);
- }
-
- /*
- * Other special values
- */
-
- k = epipe->pipe.endpoint->edesc->bEndpointAddress;
- itd->itd.itd_bufr[0] |= htohc32(sc,
- EHCI_ITD_SET_EP(UE_GET_ADDR(k)) |
- EHCI_ITD_SET_DADDR(epipe->pipe.device->address));
-
- k = (UE_GET_DIR(epipe->pipe.endpoint->edesc->bEndpointAddress))
- ? 1 : 0;
- j = UE_GET_SIZE(
- UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize));
- itd->itd.itd_bufr[1] |= htohc32(sc, EHCI_ITD_SET_DIR(k) |
- EHCI_ITD_SET_MAXPKT(UE_GET_SIZE(j)));
-
- /* FIXME: handle invalid trans */
- itd->itd.itd_bufr[2] |=
- htohc32(sc, EHCI_ITD_SET_MULTI(UE_GET_TRANS(j)+1));
- prev = itd;
- } /* End of frame */
-
- stop = itd;
- stop->xfer_next = NULL;
- exfer->isoc_len = total_length;
-
- /*
- * Part 2: Transfer descriptors have now been set up, now they must
- * be scheduled into the period frame list. Erk. Not wanting to
- * complicate matters, transfer is denied if the transfer spans
- * more than the period frame list.
- */
-
- s = splusb();
-
- /* Start inserting frames */
- if (epipe->u.isoc.cur_xfers > 0) {
- frindex = epipe->u.isoc.next_frame;
- } else {
- frindex = EOREAD4(sc, EHCI_FRINDEX);
- frindex = frindex >> 3; /* Erase microframe index */
- frindex += 2;
- }
-
- if (frindex >= sc->sc_flsize)
- frindex &= (sc->sc_flsize - 1);
-
- /* Whats the frame interval? */
- i = (1 << epipe->pipe.endpoint->edesc->bInterval);
- if (i / 8 == 0)
- i = 1;
- else
- i /= 8;
-
- itd = start;
- for (j = 0; j < frames; j++) {
- if (itd == NULL)
- panic("ehci: unexpectedly ran out of isoc itds,"
- "isoc_start\n");
-
- itd->itd.itd_next = sc->sc_flist[frindex];
- if (itd->itd.itd_next == 0)
- /* FIXME: frindex table gets initialized to NULL
- * or EHCI_NULL? */
- itd->itd.itd_next = EHCI_NULL(sc);
-
- sc->sc_flist[frindex] = htohc32(sc, EHCI_LINK_ITD | itd->physaddr);
-
- itd->u.frame_list.next = sc->sc_softitds[frindex];
- sc->sc_softitds[frindex] = itd;
- if (itd->u.frame_list.next != NULL)
- itd->u.frame_list.next->u.frame_list.prev = itd;
- itd->slot = frindex;
- itd->u.frame_list.prev = NULL;
-
- frindex += i;
- if (frindex >= sc->sc_flsize)
- frindex -= sc->sc_flsize;
-
- itd = itd->xfer_next;
- }
-
- epipe->u.isoc.cur_xfers++;
- epipe->u.isoc.next_frame = frindex;
-
- exfer->itdstart = start;
- exfer->itdend = stop;
- exfer->sqtdstart = NULL;
- exfer->sqtdstart = NULL;
-
- ehci_add_intr_list(sc, exfer);
- xfer->status = USBD_IN_PROGRESS;
- xfer->done = 0;
- splx(s);
-
- if (sc->sc_bus.use_polling) {
- printf("Starting ehci isoc xfer with polling. Bad idea?\n");
- ehci_waitintr(sc, xfer);
- }
-
- return (USBD_IN_PROGRESS);
-}
-
-static void
-ehci_device_isoc_abort(usbd_xfer_handle xfer)
-{
- DPRINTFN(1, ("ehci_device_isoc_abort: xfer = %p\n", xfer));
- ehci_abort_isoc_xfer(xfer, USBD_CANCELLED);
-}
-
-static void
-ehci_device_isoc_close(usbd_pipe_handle pipe)
-{
- printf("ehci_device_isoc_close: nothing in the pipe to free?\n");
-}
-
-static void
-ehci_device_isoc_done(usbd_xfer_handle xfer)
-{
- struct ehci_xfer *exfer;
- ehci_softc_t *sc;
- struct ehci_pipe *epipe;
- int s;
-
- exfer = EXFER(xfer);
- sc = (ehci_softc_t *)xfer->pipe->device->bus;
- epipe = (struct ehci_pipe *) xfer->pipe;
-
- s = splusb();
- epipe->u.isoc.cur_xfers--;
- if (xfer->status != USBD_NOMEM && ehci_active_intr_list(exfer)) {
- ehci_del_intr_list(exfer);
- ehci_rem_free_itd_chain(sc, exfer);
- }
- splx(s);
-}
diff --git a/sys/legacy/dev/usb/ehci_ddb.c b/sys/legacy/dev/usb/ehci_ddb.c
deleted file mode 100644
index 3ebd130..0000000
--- a/sys/legacy/dev/usb/ehci_ddb.c
+++ /dev/null
@@ -1,255 +0,0 @@
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_ddb.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/endian.h>
-#include <sys/bus.h>
-#include <sys/lock.h>
-#include <sys/lockmgr.h>
-
-#include <machine/bus.h>
-#include <machine/endian.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-
-#include <dev/usb/ehcireg.h>
-#include <dev/usb/ehcivar.h>
-
-#ifdef DDB
-#include <ddb/ddb.h>
-#include <ddb/db_sym.h>
-#else
-#define db_printf printf
-#endif
-
-extern ehci_softc_t *theehci; /* XXX */
-
-void
-ehci_dump_regs(ehci_softc_t *sc)
-{
- int i;
- db_printf("cmd=0x%08x, sts=0x%08x, ien=0x%08x\n",
- EOREAD4(sc, EHCI_USBCMD),
- EOREAD4(sc, EHCI_USBSTS),
- EOREAD4(sc, EHCI_USBINTR));
- db_printf("frindex=0x%08x ctrdsegm=0x%08x periodic=0x%08x async=0x%08x\n",
- EOREAD4(sc, EHCI_FRINDEX),
- EOREAD4(sc, EHCI_CTRLDSSEGMENT),
- EOREAD4(sc, EHCI_PERIODICLISTBASE),
- EOREAD4(sc, EHCI_ASYNCLISTADDR));
- for (i = 1; i <= sc->sc_noport; i++)
- db_printf("port %d status=0x%08x\n", i,
- EOREAD4(sc, EHCI_PORTSC(i)));
-}
-
-static void
-ehci_dump_link(ehci_softc_t *sc, ehci_link_t link, int type)
-{
- link = hc32toh(sc, link);
- db_printf("0x%08x", link);
- if (link & EHCI_LINK_TERMINATE)
- db_printf("<T>");
- else {
- db_printf("<");
- if (type) {
- switch (EHCI_LINK_TYPE(link)) {
- case EHCI_LINK_ITD: db_printf("ITD"); break;
- case EHCI_LINK_QH: db_printf("QH"); break;
- case EHCI_LINK_SITD: db_printf("SITD"); break;
- case EHCI_LINK_FSTN: db_printf("FSTN"); break;
- }
- }
- db_printf(">");
- }
-}
-
-void
-ehci_dump_sqtds(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd)
-{
- int i;
- u_int32_t stop;
-
- stop = 0;
- for (i = 0; sqtd && i < 20 && !stop; sqtd = sqtd->nextqtd, i++) {
- ehci_dump_sqtd(sc, sqtd);
- stop = sqtd->qtd.qtd_next & htohc32(sc, EHCI_LINK_TERMINATE);
- }
- if (sqtd)
- db_printf("dump aborted, too many TDs\n");
-}
-
-void
-ehci_dump_qtd(ehci_softc_t *sc, ehci_qtd_t *qtd)
-{
- u_int32_t s;
-
- db_printf(" next="); ehci_dump_link(sc, qtd->qtd_next, 0);
- db_printf(" altnext="); ehci_dump_link(sc, qtd->qtd_altnext, 0);
- db_printf("\n");
- s = hc32toh(sc, qtd->qtd_status);
- db_printf(" status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
- s, EHCI_QTD_GET_TOGGLE(s), EHCI_QTD_GET_BYTES(s),
- EHCI_QTD_GET_IOC(s), EHCI_QTD_GET_C_PAGE(s));
- db_printf(" cerr=%d pid=%d stat=%b\n", EHCI_QTD_GET_CERR(s),
- EHCI_QTD_GET_PID(s),
- EHCI_QTD_GET_STATUS(s), EHCI_QTD_STATUS_BITS);
- for (s = 0; s < 5; s++)
- db_printf(" buffer[%d]=0x%08x\n", s, hc32toh(sc, qtd->qtd_buffer[s]));
-}
-
-void
-ehci_dump_sqtd(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd)
-{
- db_printf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
- ehci_dump_qtd(sc, &sqtd->qtd);
-}
-
-void
-ehci_dump_sqh(ehci_softc_t *sc, ehci_soft_qh_t *sqh)
-{
- ehci_qh_t *qh = &sqh->qh;
- u_int32_t endp, endphub;
-
- db_printf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
- db_printf(" sqtd=%p inactivesqtd=%p\n", sqh->sqtd, sqh->inactivesqtd);
- db_printf(" link="); ehci_dump_link(sc, qh->qh_link, 1); db_printf("\n");
- endp = hc32toh(sc, qh->qh_endp);
- db_printf(" endp=0x%08x\n", endp);
- db_printf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
- EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp),
- EHCI_QH_GET_ENDPT(endp), EHCI_QH_GET_EPS(endp),
- EHCI_QH_GET_DTC(endp), EHCI_QH_GET_HRECL(endp));
- db_printf(" mpl=0x%x ctl=%d nrl=%d\n",
- EHCI_QH_GET_MPL(endp), EHCI_QH_GET_CTL(endp),
- EHCI_QH_GET_NRL(endp));
- endphub = hc32toh(sc, qh->qh_endphub);
- db_printf(" endphub=0x%08x\n", endphub);
- db_printf(" smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
- EHCI_QH_GET_SMASK(endphub), EHCI_QH_GET_CMASK(endphub),
- EHCI_QH_GET_HUBA(endphub), EHCI_QH_GET_PORT(endphub),
- EHCI_QH_GET_MULT(endphub));
- db_printf(" curqtd="); ehci_dump_link(sc, qh->qh_curqtd, 0); db_printf("\n");
- db_printf("Overlay qTD:\n");
- ehci_dump_qtd(sc, &qh->qh_qtd);
-}
-
-void
-ehci_dump_itd(ehci_softc_t *sc, struct ehci_soft_itd *itd)
-{
- ehci_isoc_trans_t t;
- ehci_isoc_bufr_ptr_t b, b2, b3;
- int i;
-
- db_printf("ITD: next phys=%X\n", itd->itd.itd_next);
-
- for (i = 0; i < 8;i++) {
- t = hc32toh(sc, itd->itd.itd_ctl[i]);
- db_printf("ITDctl %d: stat=%X len=%X ioc=%X pg=%X offs=%X\n", i,
- EHCI_ITD_GET_STATUS(t), EHCI_ITD_GET_LEN(t),
- EHCI_ITD_GET_IOC(t), EHCI_ITD_GET_PG(t),
- EHCI_ITD_GET_OFFS(t));
- }
- db_printf("ITDbufr: ");
- for (i = 0; i < 7; i++)
- db_printf("%X,", EHCI_ITD_GET_BPTR(hc32toh(sc, itd->itd.itd_bufr[i])));
-
- b = hc32toh(sc, itd->itd.itd_bufr[0]);
- b2 = hc32toh(sc, itd->itd.itd_bufr[1]);
- b3 = hc32toh(sc, itd->itd.itd_bufr[2]);
- db_printf("\nep=%X daddr=%X dir=%d maxpkt=%X multi=%X\n",
- EHCI_ITD_GET_EP(b), EHCI_ITD_GET_DADDR(b), EHCI_ITD_GET_DIR(b2),
- EHCI_ITD_GET_MAXPKT(b2), EHCI_ITD_GET_MULTI(b3));
-}
-
-void
-ehci_dump_sitd(ehci_softc_t *sc, struct ehci_soft_itd *itd)
-{
- db_printf("SITD %p next=%p prev=%p xfernext=%p physaddr=%X slot=%d\n",
- itd, itd->u.frame_list.next, itd->u.frame_list.prev,
- itd->xfer_next, itd->physaddr, itd->slot);
-}
-
-void
-ehci_dump_exfer(struct ehci_xfer *ex)
-{
-#ifdef DIAGNOSTIC
- db_printf("%p: sqtdstart %p end %p itdstart %p end %p isdone %d\n",
- ex, ex->sqtdstart, ex->sqtdend, ex->itdstart,
- ex->itdend, ex->isdone);
-#else
- db_printf("%p: sqtdstart %p end %p itdstart %p end %p\n",
- ex, ex->sqtdstart, ex->sqtdend, ex->itdstart, ex->itdend);
-#endif
-}
-
-#ifdef DDB
-DB_SHOW_COMMAND(ehci, db_show_ehci)
-{
- if (!have_addr) {
- db_printf("usage: show ehci <addr>\n");
- return;
- }
- ehci_dump_regs((ehci_softc_t *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_sqtds, db_show_ehci_sqtds)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_sqtds <addr>\n");
- return;
- }
- ehci_dump_sqtds(theehci, (ehci_soft_qtd_t *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_qtd, db_show_ehci_qtd)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_qtd <addr>\n");
- return;
- }
- ehci_dump_qtd(theehci, (ehci_qtd_t *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_sqh, db_show_ehci_sqh)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_sqh <addr>\n");
- return;
- }
- ehci_dump_sqh(theehci, (ehci_soft_qh_t *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_itd, db_show_ehci_itd)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_itd <addr>\n");
- return;
- }
- ehci_dump_itd(theehci, (struct ehci_soft_itd *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_sitd, db_show_ehci_sitd)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_sitd <addr>\n");
- return;
- }
- ehci_dump_itd(theehci, (struct ehci_soft_itd *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_xfer, db_show_ehci_xfer)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_xfer <addr>\n");
- return;
- }
- ehci_dump_exfer((struct ehci_xfer *) addr);
-}
-#endif /* DDB */
diff --git a/sys/legacy/dev/usb/ehci_ixp4xx.c b/sys/legacy/dev/usb/ehci_ixp4xx.c
deleted file mode 100644
index bc800d3..0000000
--- a/sys/legacy/dev/usb/ehci_ixp4xx.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*-
- * Copyright (c) 2008 Sam Leffler. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * IXP435 attachment driver for the USB Enhanced Host Controller.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_bus.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/endian.h>
-#include <sys/queue.h>
-#include <sys/lockmgr.h>
-#include <sys/rman.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-
-#include <dev/usb/ehcireg.h>
-#include <dev/usb/ehcivar.h>
-
-#include <arm/xscale/ixp425/ixp425reg.h>
-#include <arm/xscale/ixp425/ixp425var.h>
-
-#define EHCI_VENDORID_IXP4XX 0x42fa05
-#define EHCI_HC_DEVSTR "IXP4XX Integrated USB 2.0 controller"
-
-struct ixp_ehci_softc {
- ehci_softc_t base; /* storage for EHCI code */
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
- struct bus_space tag; /* tag for private bus space ops */
-};
-
-static int ehci_ixp_detach(device_t self);
-
-static uint8_t ehci_bs_r_1(void *, bus_space_handle_t, bus_size_t);
-static void ehci_bs_w_1(void *, bus_space_handle_t, bus_size_t, u_int8_t);
-static uint16_t ehci_bs_r_2(void *, bus_space_handle_t, bus_size_t);
-static void ehci_bs_w_2(void *, bus_space_handle_t, bus_size_t, uint16_t);
-static uint32_t ehci_bs_r_4(void *, bus_space_handle_t, bus_size_t);
-static void ehci_bs_w_4(void *, bus_space_handle_t, bus_size_t, uint32_t);
-
-static int
-ehci_ixp_suspend(device_t self)
-{
- ehci_softc_t *sc;
- int err;
-
- err = bus_generic_suspend(self);
- if (err == 0) {
- sc = device_get_softc(self);
- ehci_power(PWR_SUSPEND, sc);
- }
- return err;
-}
-
-static int
-ehci_ixp_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_power(PWR_RESUME, sc);
- bus_generic_resume(self);
- return 0;
-}
-
-static int
-ehci_ixp_shutdown(device_t self)
-{
- ehci_softc_t *sc;
- int err;
-
- err = bus_generic_shutdown(self);
- if (err == 0) {
- sc = device_get_softc(self);
- ehci_shutdown(sc);
- }
- return err;
-}
-
-static int
-ehci_ixp_probe(device_t self)
-{
- device_set_desc(self, EHCI_HC_DEVSTR);
- return BUS_PROBE_DEFAULT;
-}
-
-static int
-ehci_ixp_attach(device_t self)
-{
- struct ixp_ehci_softc *isc = device_get_softc(self);
- ehci_softc_t *sc = &isc->base;
- int err, rid;
-
- sc->sc_bus.usbrev = USBREV_2_0;
-
- /* NB: hints fix the memory location and irq */
-
- rid = 0;
- sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY,
- &rid, RF_ACTIVE);
- if (sc->io_res == NULL) {
- device_printf(self, "Could not map memory\n");
- return ENXIO;
- }
-
- /*
- * Craft special resource for bus space ops that handle
- * byte-alignment of non-word addresses. Also, since
- * we're already intercepting bus space ops we handle
- * the register window offset that could otherwise be
- * done with bus_space_subregion.
- */
- isc->iot = rman_get_bustag(sc->io_res);
- isc->tag.bs_cookie = isc->iot;
- /* read single */
- isc->tag.bs_r_1 = ehci_bs_r_1,
- isc->tag.bs_r_2 = ehci_bs_r_2,
- isc->tag.bs_r_4 = ehci_bs_r_4,
- /* write (single) */
- isc->tag.bs_w_1 = ehci_bs_w_1,
- isc->tag.bs_w_2 = ehci_bs_w_2,
- isc->tag.bs_w_4 = ehci_bs_w_4,
-
- sc->iot = &isc->tag;
- sc->ioh = rman_get_bushandle(sc->io_res);
- sc->sc_size = IXP435_USB1_SIZE - 0x100;
-
- rid = 0;
- sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ,
- &rid, RF_ACTIVE);
- if (sc->irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- ehci_ixp_detach(self);
- return ENXIO;
- }
- sc->sc_bus.bdev = device_add_child(self, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- ehci_ixp_detach(self);
- return ENOMEM;
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-
- sprintf(sc->sc_vendor, "Intel");
- sc->sc_id_vendor = EHCI_VENDORID_IXP4XX;
-
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
- NULL, (driver_intr_t*)ehci_intr, sc, &sc->ih);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->ih = NULL;
- ehci_ixp_detach(self);
- return ENXIO;
- }
-
- /* There are no companion USB controllers */
- sc->sc_ncomp = 0;
-
- /* Allocate a parent dma tag for DMA maps */
- err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- NULL, NULL, &sc->sc_bus.parent_dmatag);
- if (err) {
- device_printf(self, "Could not allocate parent DMA tag (%d)\n",
- err);
- ehci_ixp_detach(self);
- return ENXIO;
- }
-
- /* Allocate a dma tag for transfer buffers */
- err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
- if (err) {
- device_printf(self, "Could not allocate buffer DMA tag (%d)\n",
- err);
- ehci_ixp_detach(self);
- return ENXIO;
- }
-
- /*
- * Arrange to force Host mode, select big-endian byte alignment,
- * and arrange to not terminate reset operations (the adapter
- * will ignore it if we do but might as well save a reg write).
- * Also, the controller has an embedded Transaction Translator
- * which means port speed must be read from the Port Status
- * register following a port enable.
- */
- sc->sc_flags |= EHCI_SCFLG_TT
- | EHCI_SCFLG_SETMODE
- | EHCI_SCFLG_BIGEDESC
- | EHCI_SCFLG_BIGEMMIO
- | EHCI_SCFLG_NORESTERM
- ;
- (void) ehci_reset(sc);
-
- err = ehci_init(sc);
- if (!err) {
- sc->sc_flags |= EHCI_SCFLG_DONEINIT;
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
-
- if (err) {
- device_printf(self, "USB init failed err=%d\n", err);
- ehci_ixp_detach(self);
- return EIO;
- }
- return 0;
-}
-
-static int
-ehci_ixp_detach(device_t self)
-{
- struct ixp_ehci_softc *isc = device_get_softc(self);
- ehci_softc_t *sc = &isc->base;
- int err;
-
- if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
- ehci_detach(sc, 0);
- sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
- }
-
- /*
- * Disable interrupts that might have been switched on in ehci_init()
- */
- if (sc->iot && sc->ioh)
- bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0);
- if (sc->sc_bus.parent_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
- if (sc->sc_bus.buffer_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
-
- if (sc->irq_res && sc->ih) {
- err = bus_teardown_intr(self, sc->irq_res, sc->ih);
-
- if (err)
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->ih = NULL;
- }
- if (sc->sc_bus.bdev != NULL) {
- device_delete_child(self, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
- }
- if (sc->irq_res != NULL) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
- sc->irq_res = NULL;
- }
- if (sc->io_res != NULL) {
- bus_release_resource(self, SYS_RES_MEMORY, 0, sc->io_res);
- sc->io_res = NULL;
- }
- sc->iot = 0;
- sc->ioh = 0;
- return 0;
-}
-
-/*
- * Bus space accessors for PIO operations.
- */
-
-static uint8_t
-ehci_bs_r_1(void *t, bus_space_handle_t h, bus_size_t o)
-{
- return bus_space_read_1((bus_space_tag_t) t, h,
- 0x100 + (o &~ 3) + (3 - (o & 3)));
-}
-
-static void
-ehci_bs_w_1(void *t, bus_space_handle_t h, bus_size_t o, u_int8_t v)
-{
- panic("%s", __func__);
-}
-
-static uint16_t
-ehci_bs_r_2(void *t, bus_space_handle_t h, bus_size_t o)
-{
- return bus_space_read_2((bus_space_tag_t) t, h,
- 0x100 + (o &~ 3) + (2 - (o & 3)));
-}
-
-static void
-ehci_bs_w_2(void *t, bus_space_handle_t h, bus_size_t o, uint16_t v)
-{
- panic("%s", __func__);
-}
-
-static uint32_t
-ehci_bs_r_4(void *t, bus_space_handle_t h, bus_size_t o)
-{
- return bus_space_read_4((bus_space_tag_t) t, h, 0x100 + o);
-}
-
-static void
-ehci_bs_w_4(void *t, bus_space_handle_t h, bus_size_t o, uint32_t v)
-{
- bus_space_write_4((bus_space_tag_t) t, h, 0x100 + o, v);
-}
-
-static device_method_t ehci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ehci_ixp_probe),
- DEVMETHOD(device_attach, ehci_ixp_attach),
- DEVMETHOD(device_detach, ehci_ixp_detach),
- DEVMETHOD(device_suspend, ehci_ixp_suspend),
- DEVMETHOD(device_resume, ehci_ixp_resume),
- DEVMETHOD(device_shutdown, ehci_ixp_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t ehci_driver = {
- "ehci",
- ehci_methods,
- sizeof(struct ixp_ehci_softc),
-};
-static devclass_t ehci_devclass;
-DRIVER_MODULE(ehci, ixp, ehci_driver, ehci_devclass, 0, 0);
diff --git a/sys/legacy/dev/usb/ehci_mbus.c b/sys/legacy/dev/usb/ehci_mbus.c
deleted file mode 100644
index 792c89d..0000000
--- a/sys/legacy/dev/usb/ehci_mbus.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*-
- * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
- * All rights reserved.
- *
- * Developed by Semihalf.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of MARVELL nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * MBus attachment driver for the USB Enhanced Host Controller.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_bus.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/queue.h>
-#include <sys/lockmgr.h>
-#include <sys/rman.h>
-#include <sys/endian.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-
-#include <dev/usb/ehcireg.h>
-#include <dev/usb/ehcivar.h>
-
-#include <arm/mv/mvreg.h>
-#include <arm/mv/mvvar.h>
-
-#define EHCI_VENDORID_MRVL 0x1286
-#define EHCI_HC_DEVSTR "Marvell Integrated USB 2.0 controller"
-
-static device_attach_t ehci_mbus_attach;
-static device_detach_t ehci_mbus_detach;
-static device_shutdown_t ehci_mbus_shutdown;
-static device_suspend_t ehci_mbus_suspend;
-static device_resume_t ehci_mbus_resume;
-
-static int err_intr(void *arg);
-
-struct resource *irq_err;
-void *ih_err;
-
-#define USB_BRIDGE_INTR_CAUSE 0x210
-#define USB_BRIDGE_INTR_MASK 0x214
-
-#define MV_USB_ADDR_DECODE_ERR (1 << 0)
-#define MV_USB_HOST_UNDERFLOW (1 << 1)
-#define MV_USB_HOST_OVERFLOW (1 << 2)
-#define MV_USB_DEVICE_UNDERFLOW (1 << 3)
-
-static int
-ehci_mbus_suspend(device_t self)
-{
- ehci_softc_t *sc;
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
-
- sc = device_get_softc(self);
- ehci_power(PWR_SUSPEND, sc);
-
- return (0);
-}
-
-static int
-ehci_mbus_resume(device_t self)
-{
- ehci_softc_t *sc;
-
- sc = device_get_softc(self);
-
- ehci_power(PWR_RESUME, sc);
- bus_generic_resume(self);
-
- return (0);
-}
-
-static int
-ehci_mbus_shutdown(device_t self)
-{
- ehci_softc_t *sc;
- int err;
-
- err = bus_generic_shutdown(self);
- if (err)
- return (err);
-
- sc = device_get_softc(self);
- ehci_shutdown(sc);
-
- return (0);
-}
-
-static int
-ehci_mbus_probe(device_t self)
-{
-
- device_set_desc(self, EHCI_HC_DEVSTR);
-
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-ehci_mbus_attach(device_t self)
-{
- ehci_softc_t *sc;
- bus_space_handle_t bsh;
- int err, rid;
-
- sc = device_get_softc(self);
- sc->sc_bus.usbrev = USBREV_2_0;
-
- rid = 0;
- sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!sc->io_res) {
- device_printf(self, "Could not map memory\n");
- return (ENXIO);
- }
- sc->iot = rman_get_bustag(sc->io_res);
- bsh = rman_get_bushandle(sc->io_res);
-
- /*
- * Marvell EHCI host controller registers start at certain offset within
- * the whole USB registers range, so create a subregion for the host
- * mode configuration purposes.
- */
- if (bus_space_subregion(sc->iot, bsh, MV_USB_HOST_OFST,
- MV_USB_SIZE - MV_USB_HOST_OFST, &sc->ioh) != 0)
- panic("%s: unable to subregion USB host registers",
- device_get_name(self));
- sc->sc_size = MV_USB_SIZE - MV_USB_HOST_OFST;
-
- rid = 0;
- irq_err = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (irq_err == NULL) {
- device_printf(self, "Could not allocate error irq\n");
- ehci_mbus_detach(self);
- return (ENXIO);
- }
-
- /*
- * Notice: Marvell EHCI controller has TWO interrupt lines, so make sure to
- * use the correct rid for the main one (controller interrupt) --
- * refer to obio_devices[] for the right resource number to use here.
- */
- rid = 1;
- sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- ehci_mbus_detach(self);
- return (ENXIO);
- }
- sc->sc_bus.bdev = device_add_child(self, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- ehci_mbus_detach(self);
- return (ENOMEM);
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-
- sprintf(sc->sc_vendor, "Marvell");
- sc->sc_id_vendor = EHCI_VENDORID_MRVL;
-
- err = bus_setup_intr(self, irq_err, INTR_FAST | INTR_TYPE_BIO,
- err_intr, NULL, sc, &ih_err);
- if (err) {
- device_printf(self, "Could not setup error irq, %d\n", err);
- ih_err = NULL;
- ehci_mbus_detach(self);
- return (ENXIO);
- }
-
- EWRITE4(sc, USB_BRIDGE_INTR_MASK, MV_USB_ADDR_DECODE_ERR |
- MV_USB_HOST_UNDERFLOW | MV_USB_HOST_OVERFLOW |
- MV_USB_DEVICE_UNDERFLOW);
-
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
- NULL, (driver_intr_t*)ehci_intr, sc, &sc->ih);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->ih = NULL;
- ehci_mbus_detach(self);
- return (ENXIO);
- }
-
- /* There are no companion USB controllers */
- sc->sc_ncomp = 0;
-
- /* Allocate a parent dma tag for DMA maps */
- err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- NULL, NULL, &sc->sc_bus.parent_dmatag);
- if (err) {
- device_printf(self, "Could not allocate parent DMA tag (%d)\n",
- err);
- ehci_mbus_detach(self);
- return (ENXIO);
- }
-
- /* Allocate a dma tag for transfer buffers */
- err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
- if (err) {
- device_printf(self, "Could not allocate buffer DMA tag (%d)\n",
- err);
- ehci_mbus_detach(self);
- return (ENXIO);
- }
-
- /*
- * Workaround for Marvell integrated EHCI controller: reset of
- * the EHCI core clears the USBMODE register, which sets the core in
- * an undefined state (neither host nor agent), so it needs to be set
- * again for proper operation.
- *
- * Refer to errata document MV-S500832-00D.pdf (p. 5.24 GL USB-2) for
- * details.
- */
- sc->sc_flags |= EHCI_SCFLG_SETMODE;
- if (bootverbose)
- device_printf(self, "5.24 GL USB-2 workaround enabled\n");
-
- /* XXX all MV chips need it? */
- sc->sc_flags |= EHCI_SCFLG_FORCESPEED | EHCI_SCFLG_NORESTERM;
-
- err = ehci_init(sc);
- if (!err) {
- sc->sc_flags |= EHCI_SCFLG_DONEINIT;
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
-
- if (err) {
- device_printf(self, "USB init failed err=%d\n", err);
- ehci_mbus_detach(self);
- return (EIO);
- }
- return (0);
-}
-
-static int
-ehci_mbus_detach(device_t self)
-{
- ehci_softc_t *sc;
- int err;
-
- sc = device_get_softc(self);
- if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
- ehci_detach(sc, 0);
- sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
- }
-
- /*
- * Disable interrupts that might have been switched on in ehci_init()
- */
- if (sc->iot && sc->ioh)
- bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0);
- if (sc->sc_bus.parent_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
- if (sc->sc_bus.buffer_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
-
- if (sc->irq_res && sc->ih) {
- err = bus_teardown_intr(self, sc->irq_res, sc->ih);
-
- if (err)
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->ih = NULL;
- }
- EWRITE4(sc, USB_BRIDGE_INTR_MASK, 0);
-
- if (irq_err && ih_err) {
- err = bus_teardown_intr(self, irq_err, ih_err);
-
- if (err)
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- ih_err = NULL;
- }
-
- if (sc->sc_bus.bdev) {
- device_delete_child(self, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
- }
- if (sc->irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
- sc->irq_res = NULL;
- }
- if (irq_err) {
- bus_release_resource(self, SYS_RES_IRQ, 1, irq_err);
- irq_err = NULL;
- }
- if (sc->io_res) {
- bus_release_resource(self, SYS_RES_MEMORY, 0, sc->io_res);
- sc->io_res = NULL;
- sc->iot = 0;
- sc->ioh = 0;
- }
- return (0);
-}
-
-static int
-err_intr(void *arg)
-{
- ehci_softc_t *sc = arg;
- unsigned int cause;
-
- cause = EREAD4(sc, USB_BRIDGE_INTR_CAUSE);
- if (cause) {
- printf("IRQ ERR: cause: 0x%08x\n", cause);
- if (cause & MV_USB_ADDR_DECODE_ERR)
- printf("IRQ ERR: Address decoding error\n");
- if (cause & MV_USB_HOST_UNDERFLOW)
- printf("IRQ ERR: USB Host Underflow\n");
- if (cause & MV_USB_HOST_OVERFLOW)
- printf("IRQ ERR: USB Host Overflow\n");
- if (cause & MV_USB_DEVICE_UNDERFLOW)
- printf("IRQ ERR: USB Device Underflow\n");
- if (cause & ~(MV_USB_ADDR_DECODE_ERR | MV_USB_HOST_UNDERFLOW |
- MV_USB_HOST_OVERFLOW | MV_USB_DEVICE_UNDERFLOW))
- printf("IRQ ERR: Unknown error\n");
-
- EWRITE4(sc, USB_BRIDGE_INTR_CAUSE, 0);
- }
- return (FILTER_HANDLED);
-}
-
-static device_method_t ehci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ehci_mbus_probe),
- DEVMETHOD(device_attach, ehci_mbus_attach),
- DEVMETHOD(device_detach, ehci_mbus_detach),
- DEVMETHOD(device_suspend, ehci_mbus_suspend),
- DEVMETHOD(device_resume, ehci_mbus_resume),
- DEVMETHOD(device_shutdown, ehci_mbus_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t ehci_driver = {
- "ehci",
- ehci_methods,
- sizeof(ehci_softc_t),
-};
-
-static devclass_t ehci_devclass;
-
-DRIVER_MODULE(ehci, mbus, ehci_driver, ehci_devclass, 0, 0);
diff --git a/sys/legacy/dev/usb/ehci_pci.c b/sys/legacy/dev/usb/ehci_pci.c
deleted file mode 100644
index 1e2243b..0000000
--- a/sys/legacy/dev/usb/ehci_pci.c
+++ /dev/null
@@ -1,635 +0,0 @@
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (augustss@carlstedt.se) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
- *
- * The EHCI 1.0 spec can be found at
- * http://developer.intel.com/technology/usb/download/ehci-r10.pdf
- * and the USB 2.0 spec at
- * http://www.usb.org/developers/docs/usb_20.zip
- */
-
-/* The low level controller code for EHCI has been split into
- * PCI probes and EHCI specific code. This was done to facilitate the
- * sharing of code between *BSD's
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/queue.h>
-#include <sys/lockmgr.h>
-#include <sys/rman.h>
-#include <sys/endian.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcireg.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-
-#include <dev/usb/ehcireg.h>
-#include <dev/usb/ehcivar.h>
-
-#define PCI_EHCI_VENDORID_ACERLABS 0x10b9
-#define PCI_EHCI_VENDORID_AMD 0x1022
-#define PCI_EHCI_VENDORID_APPLE 0x106b
-#define PCI_EHCI_VENDORID_ATI 0x1002
-#define PCI_EHCI_VENDORID_CMDTECH 0x1095
-#define PCI_EHCI_VENDORID_INTEL 0x8086
-#define PCI_EHCI_VENDORID_NEC 0x1033
-#define PCI_EHCI_VENDORID_OPTI 0x1045
-#define PCI_EHCI_VENDORID_PHILIPS 0x1131
-#define PCI_EHCI_VENDORID_SIS 0x1039
-#define PCI_EHCI_VENDORID_NVIDIA 0x12D2
-#define PCI_EHCI_VENDORID_NVIDIA2 0x10DE
-#define PCI_EHCI_VENDORID_VIA 0x1106
-
-/* AcerLabs/ALi */
-#define PCI_EHCI_DEVICEID_M5239 0x523910b9
-static const char *ehci_device_m5239 = "ALi M5239 USB 2.0 controller";
-
-/* AMD */
-#define PCI_EHCI_DEVICEID_8111 0x10227463
-static const char *ehci_device_8111 = "AMD 8111 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_CS5536 0x20951022
-static const char *ehci_device_cs5536 = "AMD CS5536 (Geode) USB 2.0 controller";
-
-/* ATI */
-#define PCI_EHCI_DEVICEID_SB200 0x43451002
-static const char *ehci_device_sb200 = "ATI SB200 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_SB400 0x43731002
-static const char *ehci_device_sb400 = "ATI SB400 USB 2.0 controller";
-
-/* Intel */
-#define PCI_EHCI_DEVICEID_6300 0x25ad8086
-static const char *ehci_device_6300 = "Intel 6300ESB USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_ICH4 0x24cd8086
-static const char *ehci_device_ich4 = "Intel 82801DB/L/M (ICH4) USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_ICH5 0x24dd8086
-static const char *ehci_device_ich5 = "Intel 82801EB/R (ICH5) USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_ICH6 0x265c8086
-static const char *ehci_device_ich6 = "Intel 82801FB (ICH6) USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_ICH7 0x27cc8086
-static const char *ehci_device_ich7 = "Intel 82801GB/R (ICH7) USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_ICH8_A 0x28368086
-static const char *ehci_device_ich8_a = "Intel 82801H (ICH8) USB 2.0 controller USB2-A";
-#define PCI_EHCI_DEVICEID_ICH8_B 0x283a8086
-static const char *ehci_device_ich8_b = "Intel 82801H (ICH8) USB 2.0 controller USB2-B";
-#define PCI_EHCI_DEVICEID_ICH9_A 0x293a8086
-#define PCI_EHCI_DEVICEID_ICH9_B 0x293c8086
-static const char *ehci_device_ich9 = "Intel 82801I (ICH9) USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_63XX 0x268c8086
-static const char *ehci_device_63XX = "Intel 63XXESB USB 2.0 controller";
-
-/* NEC */
-#define PCI_EHCI_DEVICEID_NEC 0x00e01033
-static const char *ehci_device_nec = "NEC uPD 720100 USB 2.0 controller";
-
-/* NVIDIA */
-#define PCI_EHCI_DEVICEID_NF2 0x006810de
-static const char *ehci_device_nf2 = "NVIDIA nForce2 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_NF2_400 0x008810de
-static const char *ehci_device_nf2_400 = "NVIDIA nForce2 Ultra 400 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_NF3 0x00d810de
-static const char *ehci_device_nf3 = "NVIDIA nForce3 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_NF3_250 0x00e810de
-static const char *ehci_device_nf3_250 = "NVIDIA nForce3 250 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_NF4 0x005b10de
-static const char *ehci_device_nf4 = "NVIDIA nForce4 USB 2.0 controller";
-
-/* Philips */
-#define PCI_EHCI_DEVICEID_ISP156X 0x15621131
-static const char *ehci_device_isp156x = "Philips ISP156x USB 2.0 controller";
-
-#define PCI_EHCI_DEVICEID_VIA 0x31041106
-static const char *ehci_device_via = "VIA VT6202 USB 2.0 controller";
-
-static const char *ehci_device_generic = "EHCI (generic) USB 2.0 controller";
-
-#define PCI_EHCI_BASE_REG 0x10
-
-#ifdef USB_DEBUG
-#define EHCI_DEBUG USB_DEBUG
-#define DPRINTF(x) do { if (ehcidebug) printf x; } while (0)
-extern int ehcidebug;
-#else
-#define DPRINTF(x)
-#endif
-
-static device_attach_t ehci_pci_attach;
-static device_detach_t ehci_pci_detach;
-static device_shutdown_t ehci_pci_shutdown;
-static device_suspend_t ehci_pci_suspend;
-static device_resume_t ehci_pci_resume;
-static void ehci_pci_givecontroller(device_t self);
-static void ehci_pci_takecontroller(device_t self);
-
-static int
-ehci_pci_suspend(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
- ehci_power(PWR_SUSPEND, sc);
-
- return 0;
-}
-
-static int
-ehci_pci_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_pci_takecontroller(self);
- ehci_power(PWR_RESUME, sc);
- bus_generic_resume(self);
-
- return 0;
-}
-
-static int
-ehci_pci_shutdown(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_shutdown(self);
- if (err)
- return (err);
- ehci_shutdown(sc);
- ehci_pci_givecontroller(self);
-
- return 0;
-}
-
-static const char *
-ehci_pci_match(device_t self)
-{
- u_int32_t device_id = pci_get_devid(self);
-
- switch (device_id) {
- case PCI_EHCI_DEVICEID_M5239:
- return (ehci_device_m5239);
- case PCI_EHCI_DEVICEID_8111:
- return (ehci_device_8111);
- case PCI_EHCI_DEVICEID_CS5536:
- return (ehci_device_cs5536);
- case PCI_EHCI_DEVICEID_SB200:
- return (ehci_device_sb200);
- case PCI_EHCI_DEVICEID_SB400:
- return (ehci_device_sb400);
- case PCI_EHCI_DEVICEID_6300:
- return (ehci_device_6300);
- case PCI_EHCI_DEVICEID_63XX:
- return (ehci_device_63XX);
- case PCI_EHCI_DEVICEID_ICH4:
- return (ehci_device_ich4);
- case PCI_EHCI_DEVICEID_ICH5:
- return (ehci_device_ich5);
- case PCI_EHCI_DEVICEID_ICH6:
- return (ehci_device_ich6);
- case PCI_EHCI_DEVICEID_ICH7:
- return (ehci_device_ich7);
- case PCI_EHCI_DEVICEID_ICH8_A:
- return (ehci_device_ich8_a);
- case PCI_EHCI_DEVICEID_ICH8_B:
- return (ehci_device_ich8_b);
- case PCI_EHCI_DEVICEID_ICH9_A:
- case PCI_EHCI_DEVICEID_ICH9_B:
- return (ehci_device_ich9);
- case PCI_EHCI_DEVICEID_NEC:
- return (ehci_device_nec);
- case PCI_EHCI_DEVICEID_NF2:
- return (ehci_device_nf2);
- case PCI_EHCI_DEVICEID_NF2_400:
- return (ehci_device_nf2_400);
- case PCI_EHCI_DEVICEID_NF3:
- return (ehci_device_nf3);
- case PCI_EHCI_DEVICEID_NF3_250:
- return (ehci_device_nf3_250);
- case PCI_EHCI_DEVICEID_NF4:
- return (ehci_device_nf4);
- case PCI_EHCI_DEVICEID_ISP156X:
- return (ehci_device_isp156x);
- case PCI_EHCI_DEVICEID_VIA:
- return (ehci_device_via);
- default:
- if (pci_get_class(self) == PCIC_SERIALBUS
- && pci_get_subclass(self) == PCIS_SERIALBUS_USB
- && pci_get_progif(self) == PCI_INTERFACE_EHCI) {
- return (ehci_device_generic);
- }
- }
-
- return NULL; /* dunno */
-}
-
-static int
-ehci_pci_probe(device_t self)
-{
- const char *desc = ehci_pci_match(self);
-
- if (desc) {
- device_set_desc(self, desc);
- return BUS_PROBE_DEFAULT;
- } else {
- return ENXIO;
- }
-}
-
-static int
-ehci_pci_attach(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- devclass_t dc;
- device_t parent;
- device_t *neighbors;
- device_t *nbus;
- struct usbd_bus *bsc;
- int err;
- int rid;
- int ncomp;
- int count, buscount;
- int slot, function;
- int res;
- int i;
-
- switch(pci_read_config(self, PCI_USBREV, 1) & PCI_USBREV_MASK) {
- case PCI_USBREV_PRE_1_0:
- case PCI_USBREV_1_0:
- case PCI_USBREV_1_1:
- device_printf(self, "pre-2.0 USB rev\n");
- if (pci_get_devid(self) == PCI_EHCI_DEVICEID_CS5536) {
- sc->sc_bus.usbrev = USBREV_2_0;
- device_printf(self, "Quirk for CS5536 USB 2.0 enabled\n");
- break;
- }
-
- /*
- * Quirk for Parallels Desktop 4.0.
- */
- if (pci_get_devid(self) == PCI_EHCI_DEVICEID_ICH6) {
- sc->sc_bus.usbrev = USBREV_2_0;
- break;
- }
- sc->sc_bus.usbrev = USBREV_UNKNOWN;
- return ENXIO;
- case PCI_USBREV_2_0:
- sc->sc_bus.usbrev = USBREV_2_0;
- break;
- default:
- sc->sc_bus.usbrev = USBREV_UNKNOWN;
- break;
- }
-
- pci_enable_busmaster(self);
-
- rid = PCI_CBMEM;
- sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
- if (!sc->io_res) {
- device_printf(self, "Could not map memory\n");
- return ENXIO;
- }
- sc->iot = rman_get_bustag(sc->io_res);
- sc->ioh = rman_get_bushandle(sc->io_res);
-
- rid = 0;
- sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- ehci_pci_detach(self);
- return ENXIO;
- }
- sc->sc_bus.bdev = device_add_child(self, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- ehci_pci_detach(self);
- return ENOMEM;
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-
- /* ehci_pci_match will never return NULL if ehci_pci_probe succeeded */
- device_set_desc(sc->sc_bus.bdev, ehci_pci_match(self));
- switch (pci_get_vendor(self)) {
- case PCI_EHCI_VENDORID_ACERLABS:
- sprintf(sc->sc_vendor, "AcerLabs");
- break;
- case PCI_EHCI_VENDORID_AMD:
- sprintf(sc->sc_vendor, "AMD");
- break;
- case PCI_EHCI_VENDORID_APPLE:
- sprintf(sc->sc_vendor, "Apple");
- break;
- case PCI_EHCI_VENDORID_ATI:
- sprintf(sc->sc_vendor, "ATI");
- break;
- case PCI_EHCI_VENDORID_CMDTECH:
- sprintf(sc->sc_vendor, "CMDTECH");
- break;
- case PCI_EHCI_VENDORID_INTEL:
- sprintf(sc->sc_vendor, "Intel");
- break;
- case PCI_EHCI_VENDORID_NEC:
- sprintf(sc->sc_vendor, "NEC");
- break;
- case PCI_EHCI_VENDORID_OPTI:
- sprintf(sc->sc_vendor, "OPTi");
- break;
- case PCI_EHCI_VENDORID_SIS:
- sprintf(sc->sc_vendor, "SiS");
- break;
- case PCI_EHCI_VENDORID_NVIDIA:
- case PCI_EHCI_VENDORID_NVIDIA2:
- sprintf(sc->sc_vendor, "nVidia");
- break;
- case PCI_EHCI_VENDORID_VIA:
- sprintf(sc->sc_vendor, "VIA");
- break;
- default:
- if (bootverbose)
- device_printf(self, "(New EHCI DeviceId=0x%08x)\n",
- pci_get_devid(self));
- sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
- }
-
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
- NULL, (driver_intr_t *)ehci_intr, sc, &sc->ih);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->ih = NULL;
- ehci_pci_detach(self);
- return ENXIO;
- }
-
- /* Enable workaround for dropped interrupts as required */
- switch (pci_get_vendor(self)) {
- case PCI_EHCI_VENDORID_ATI:
- case PCI_EHCI_VENDORID_VIA:
- sc->sc_flags |= EHCI_SCFLG_LOSTINTRBUG;
- if (bootverbose)
- device_printf(self,
- "Dropped interrupts workaround enabled\n");
- break;
- default:
- break;
- }
-
- /*
- * Find companion controllers. According to the spec they always
- * have lower function numbers so they should be enumerated already.
- */
- parent = device_get_parent(self);
- res = device_get_children(parent, &neighbors, &count);
- if (res != 0) {
- device_printf(self, "Error finding companion busses\n");
- ehci_pci_detach(self);
- return ENXIO;
- }
- ncomp = 0;
- dc = devclass_find("usb");
- slot = pci_get_slot(self);
- function = pci_get_function(self);
- for (i = 0; i < count; i++) {
- if (pci_get_slot(neighbors[i]) == slot && \
- pci_get_function(neighbors[i]) < function) {
- res = device_get_children(neighbors[i],
- &nbus, &buscount);
- if (res != 0)
- continue;
- if (buscount != 1) {
- free(nbus, M_TEMP);
- continue;
- }
- if (device_get_devclass(nbus[0]) != dc) {
- free(nbus, M_TEMP);
- continue;
- }
- bsc = device_get_softc(nbus[0]);
- free(nbus, M_TEMP);
- DPRINTF(("ehci_pci_attach: companion %s\n",
- device_get_nameunit(bsc->bdev)));
- sc->sc_comps[ncomp++] = bsc;
- if (ncomp >= EHCI_COMPANION_MAX)
- break;
- }
- }
- sc->sc_ncomp = ncomp;
-
- /* Allocate a parent dma tag for DMA maps */
- err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- NULL, NULL, &sc->sc_bus.parent_dmatag);
- if (err) {
- device_printf(self, "Could not allocate parent DMA tag (%d)\n",
- err);
- ehci_pci_detach(self);
- return ENXIO;
- }
-
- /* Allocate a dma tag for transfer buffers */
- err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
- if (err) {
- device_printf(self, "Could not allocate buffer DMA tag (%d)\n",
- err);
- ehci_pci_detach(self);
- return ENXIO;
- }
-
- ehci_pci_takecontroller(self);
- err = ehci_init(sc);
- if (!err) {
- sc->sc_flags |= EHCI_SCFLG_DONEINIT;
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
-
- if (err) {
- device_printf(self, "USB init failed err=%d\n", err);
- ehci_pci_detach(self);
- return EIO;
- }
- return 0;
-}
-
-static int
-ehci_pci_detach(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
- ehci_detach(sc, 0);
- sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
- }
-
- /*
- * disable interrupts that might have been switched on in ehci_init
- */
- if (sc->iot && sc->ioh)
- bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0);
- if (sc->sc_bus.parent_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
- if (sc->sc_bus.buffer_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
-
- if (sc->irq_res && sc->ih) {
- int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
-
- if (err)
- /* XXX or should we panic? */
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->ih = NULL;
- }
- if (sc->sc_bus.bdev) {
- device_delete_child(self, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
- }
- if (sc->irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
- sc->irq_res = NULL;
- }
- if (sc->io_res) {
- bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM, sc->io_res);
- sc->io_res = NULL;
- sc->iot = 0;
- sc->ioh = 0;
- }
- return 0;
-}
-
-static void
-ehci_pci_takecontroller(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- u_int32_t cparams, eec;
- uint8_t bios_sem;
- int eecp, i;
-
- cparams = EREAD4(sc, EHCI_HCCPARAMS);
-
- /* Synchronise with the BIOS if it owns the controller. */
- for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
- eecp = EHCI_EECP_NEXT(eec)) {
- eec = pci_read_config(self, eecp, 4);
- if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP)
- continue;
- bios_sem = pci_read_config(self, eecp + EHCI_LEGSUP_BIOS_SEM,
- 1);
- if (bios_sem) {
- pci_write_config(self, eecp + EHCI_LEGSUP_OS_SEM, 1, 1);
- printf("%s: waiting for BIOS to give up control\n",
- device_get_nameunit(sc->sc_bus.bdev));
- for (i = 0; i < 5000; i++) {
- bios_sem = pci_read_config(self, eecp +
- EHCI_LEGSUP_BIOS_SEM, 1);
- if (bios_sem == 0)
- break;
- DELAY(1000);
- }
- if (bios_sem)
- printf("%s: timed out waiting for BIOS\n",
- device_get_nameunit(sc->sc_bus.bdev));
- }
- }
-}
-
-static void
-ehci_pci_givecontroller(device_t self)
-{
-#if 0
- ehci_softc_t *sc = device_get_softc(self);
- u_int32_t cparams, eec;
- int eecp;
-
- cparams = EREAD4(sc, EHCI_HCCPARAMS);
- for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
- eecp = EHCI_EECP_NEXT(eec)) {
- eec = pci_read_config(self, eecp, 4);
- if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP)
- continue;
- pci_write_config(self, eecp + EHCI_LEGSUP_OS_SEM, 0, 1);
- }
-#endif
-}
-
-static device_method_t ehci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ehci_pci_probe),
- DEVMETHOD(device_attach, ehci_pci_attach),
- DEVMETHOD(device_detach, ehci_pci_detach),
- DEVMETHOD(device_suspend, ehci_pci_suspend),
- DEVMETHOD(device_resume, ehci_pci_resume),
- DEVMETHOD(device_shutdown, ehci_pci_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t ehci_driver = {
- "ehci",
- ehci_methods,
- sizeof(ehci_softc_t),
-};
-
-static devclass_t ehci_devclass;
-
-DRIVER_MODULE(ehci, pci, ehci_driver, ehci_devclass, 0, 0);
-MODULE_DEPEND(ehci, usb, 1, 1, 1);
diff --git a/sys/legacy/dev/usb/ehcireg.h b/sys/legacy/dev/usb/ehcireg.h
deleted file mode 100644
index 3c0f5e7..0000000
--- a/sys/legacy/dev/usb/ehcireg.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/* $NetBSD: ehcireg.h,v 1.18 2004/10/22 10:38:17 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * The EHCI 0.96 spec can be found at
- * http://developer.intel.com/technology/usb/download/ehci-r096.pdf
- * and the USB 2.0 spec at
- * http://www.usb.org/developers/data/usb_20.zip
- */
-
-#ifndef _DEV_PCI_EHCIREG_H_
-#define _DEV_PCI_EHCIREG_H_
-
-/*** PCI config registers ***/
-
-#define PCI_CBMEM 0x10 /* configuration base MEM */
-
-#define PCI_INTERFACE_EHCI 0x20
-
-#define PCI_USBREV 0x60 /* RO USB protocol revision */
-#define PCI_USBREV_MASK 0xff
-#define PCI_USBREV_PRE_1_0 0x00
-#define PCI_USBREV_1_0 0x10
-#define PCI_USBREV_1_1 0x11
-#define PCI_USBREV_2_0 0x20
-
-#define PCI_EHCI_FLADJ 0x61 /*RW Frame len adj, SOF=59488+6*fladj */
-
-#define PCI_EHCI_PORTWAKECAP 0x62 /* RW Port wake caps (opt) */
-
-/* EHCI Extended Capabilities */
-#define EHCI_EC_LEGSUP 0x01
-
-#define EHCI_EECP_NEXT(x) (((x) >> 8) & 0xff)
-#define EHCI_EECP_ID(x) ((x) & 0xff)
-
-/* Legacy support extended capability */
-#define EHCI_LEGSUP_OS_SEM 0x03 /* OS owned semaphore */
-#define EHCI_LEGSUP_BIOS_SEM 0x02 /* BIOS owned semaphore */
-#define EHCI_LEGSUP_USBLEGCTLSTS 0x04
-
-/*** EHCI capability registers ***/
-
-#define EHCI_CAPLENGTH 0x00 /*RO Capability register length field */
-/* reserved 0x01 */
-#define EHCI_HCIVERSION 0x02 /* RO Interface version number */
-
-#define EHCI_HCSPARAMS 0x04 /* RO Structural parameters */
-#define EHCI_HCS_DEBUGPORT(x) (((x) >> 20) & 0xf)
-#define EHCI_HCS_P_INDICATOR(x) ((x) & 0x10000)
-#define EHCI_HCS_N_CC(x) (((x) >> 12) & 0xf) /* # of companion ctlrs */
-#define EHCI_HCS_N_PCC(x) (((x) >> 8) & 0xf) /* # of ports per comp. */
-#define EHCI_HCS_PPC(x) ((x) & 0x10) /* port power control */
-#define EHCI_HCS_N_PORTS(x) ((x) & 0xf) /* # of ports */
-
-#define EHCI_HCCPARAMS 0x08 /* RO Capability parameters */
-#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */
-#define EHCI_HCC_IST(x) (((x) >> 4) & 0xf) /* isoc sched threshold */
-#define EHCI_HCC_ASPC(x) ((x) & 0x4) /* async sched park cap */
-#define EHCI_HCC_PFLF(x) ((x) & 0x2) /* prog frame list flag */
-#define EHCI_HCC_64BIT(x) ((x) & 0x1) /* 64 bit address cap */
-
-#define EHCI_HCSP_PORTROUTE 0x0c /*RO Companion port route description */
-
-/* EHCI operational registers. Offset given by EHCI_CAPLENGTH register */
-#define EHCI_USBCMD 0x00 /* RO, RW, WO Command register */
-#define EHCI_CMD_ITC_M 0x00ff0000 /* RW interrupt threshold ctrl */
-#define EHCI_CMD_ITC_1 0x00010000
-#define EHCI_CMD_ITC_2 0x00020000
-#define EHCI_CMD_ITC_4 0x00040000
-#define EHCI_CMD_ITC_8 0x00080000
-#define EHCI_CMD_ITC_16 0x00100000
-#define EHCI_CMD_ITC_32 0x00200000
-#define EHCI_CMD_ITC_64 0x00400000
-#define EHCI_CMD_ASPME 0x00000800 /* RW/RO async park enable */
-#define EHCI_CMD_ASPMC 0x00000300 /* RW/RO async park count */
-#define EHCI_CMD_LHCR 0x00000080 /* RW light host ctrl reset */
-#define EHCI_CMD_IAAD 0x00000040 /* RW intr on async adv door bell */
-#define EHCI_CMD_ASE 0x00000020 /* RW async sched enable */
-#define EHCI_CMD_PSE 0x00000010 /* RW periodic sched enable */
-#define EHCI_CMD_FLS_M 0x0000000c /* RW/RO frame list size */
-#define EHCI_CMD_FLS(x) (((x) >> 2) & 3) /* RW/RO frame list size */
-#define EHCI_CMD_HCRESET 0x00000002 /* RW reset */
-#define EHCI_CMD_RS 0x00000001 /* RW run/stop */
-
-#define EHCI_USBSTS 0x04 /* RO, RW, RWC Status register */
-#define EHCI_STS_ASS 0x00008000 /* RO async sched status */
-#define EHCI_STS_PSS 0x00004000 /* RO periodic sched status */
-#define EHCI_STS_REC 0x00002000 /* RO reclamation */
-#define EHCI_STS_HCH 0x00001000 /* RO host controller halted */
-#define EHCI_STS_IAA 0x00000020 /* RWC interrupt on async adv */
-#define EHCI_STS_HSE 0x00000010 /* RWC host system error */
-#define EHCI_STS_FLR 0x00000008 /* RWC frame list rollover */
-#define EHCI_STS_PCD 0x00000004 /* RWC port change detect */
-#define EHCI_STS_ERRINT 0x00000002 /* RWC error interrupt */
-#define EHCI_STS_INT 0x00000001 /* RWC interrupt */
-#define EHCI_STS_INTRS(x) ((x) & 0x3f)
-
-#define EHCI_NORMAL_INTRS (EHCI_STS_IAA | EHCI_STS_HSE | EHCI_STS_PCD | EHCI_STS_ERRINT | EHCI_STS_INT)
-
-#define EHCI_USBINTR 0x08 /* RW Interrupt register */
-#define EHCI_INTR_IAAE 0x00000020 /* interrupt on async advance ena */
-#define EHCI_INTR_HSEE 0x00000010 /* host system error ena */
-#define EHCI_INTR_FLRE 0x00000008 /* frame list rollover ena */
-#define EHCI_INTR_PCIE 0x00000004 /* port change ena */
-#define EHCI_INTR_UEIE 0x00000002 /* USB error intr ena */
-#define EHCI_INTR_UIE 0x00000001 /* USB intr ena */
-
-#define EHCI_FRINDEX 0x0c /* RW Frame Index register */
-
-#define EHCI_CTRLDSSEGMENT 0x10 /* RW Control Data Structure Segment */
-
-#define EHCI_PERIODICLISTBASE 0x14 /* RW Periodic List Base */
-#define EHCI_ASYNCLISTADDR 0x18 /* RW Async List Base */
-
-#define EHCI_CONFIGFLAG 0x40 /* RW Configure Flag register */
-#define EHCI_CONF_CF 0x00000001 /* RW configure flag */
-
-#define EHCI_PORTSC(n) (0x40+4*(n)) /* RO, RW, RWC Port Status reg */
-#define EHCI_PS_WKOC_E 0x00400000 /* RW wake on over current ena */
-#define EHCI_PS_WKDSCNNT_E 0x00200000 /* RW wake on disconnect ena */
-#define EHCI_PS_WKCNNT_E 0x00100000 /* RW wake on connect ena */
-#define EHCI_PS_PTC 0x000f0000 /* RW port test control */
-#define EHCI_PS_PIC 0x0000c000 /* RW port indicator control */
-#define EHCI_PS_PO 0x00002000 /* RW port owner */
-#define EHCI_PS_PP 0x00001000 /* RW,RO port power */
-#define EHCI_PS_LS 0x00000c00 /* RO line status */
-#define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == 0x00000400)
-#define EHCI_PS_PR 0x00000100 /* RW port reset */
-#define EHCI_PS_SUSP 0x00000080 /* RW suspend */
-#define EHCI_PS_FPR 0x00000040 /* RW force port resume */
-#define EHCI_PS_OCC 0x00000020 /* RWC over current change */
-#define EHCI_PS_OCA 0x00000010 /* RO over current active */
-#define EHCI_PS_PEC 0x00000008 /* RWC port enable change */
-#define EHCI_PS_PE 0x00000004 /* RW port enable */
-#define EHCI_PS_CSC 0x00000002 /* RWC connect status change */
-#define EHCI_PS_CS 0x00000001 /* RO connect status */
-#define EHCI_PS_CLEAR (EHCI_PS_OCC|EHCI_PS_PEC|EHCI_PS_CSC)
-
-#define EHCI_USBMODE 0x68 /* RW USB Device mode register */
-#define EHCI_UM_CM 0x00000003 /* R/WO Controller Mode */
-#define EHCI_UM_CM_IDLE 0x0 /* Idle */
-#define EHCI_UM_CM_HOST 0x3 /* Host Controller */
-#define EHCI_UM_ES 0x00000004 /* R/WO Endian Select */
-#define EHCI_UM_ES_LE 0x0 /* Little-endian byte alignment */
-#define EHCI_UM_ES_BE 0x4 /* Big-endian byte alignment */
-#define EHCI_UM_SDIS 0x00000010 /* R/WO Stream Disable Mode */
-
-#define EHCI_PORT_RESET_COMPLETE 2 /* ms */
-
-#define EHCI_FLALIGN_ALIGN 0x1000
-
-/* No data structure may cross a page boundary. */
-#define EHCI_PAGE_SIZE 0x1000
-#define EHCI_PAGE(x) ((x) &~ 0xfff)
-#define EHCI_PAGE_OFFSET(x) ((x) & 0xfff)
-#if defined(__FreeBSD__)
-#define EHCI_PAGE_MASK(x) ((x) & 0xfff)
-#endif
-
-typedef u_int32_t ehci_link_t;
-#define EHCI_LINK_TERMINATE 0x00000001
-#define EHCI_LINK_TYPE(x) ((x) & 0x00000006)
-#define EHCI_LINK_ITD 0x0
-#define EHCI_LINK_QH 0x2
-#define EHCI_LINK_SITD 0x4
-#define EHCI_LINK_FSTN 0x6
-#define EHCI_LINK_ADDR(x) ((x) &~ 0x1f)
-
-typedef u_int32_t ehci_physaddr_t;
-
-typedef u_int32_t ehci_isoc_trans_t;
-typedef u_int32_t ehci_isoc_bufr_ptr_t;
-
-/* Isochronous Transfer Descriptor */
-typedef struct {
- ehci_link_t itd_next;
- ehci_isoc_trans_t itd_ctl[8];
-#define EHCI_ITD_GET_STATUS(x) (((x) >> 28) & 0xf)
-#define EHCI_ITD_SET_STATUS(x) (((x) & 0xf) << 28)
-#define EHCI_ITD_ACTIVE 0x80000000
-#define EHCI_ITD_BUF_ERR 0x40000000
-#define EHCI_ITD_BABBLE 0x20000000
-#define EHCI_ITD_ERROR 0x10000000
-#define EHCI_ITD_GET_LEN(x) (((x) >> 16) & 0xfff)
-#define EHCI_ITD_SET_LEN(x) (((x) & 0xfff) << 16)
-#define EHCI_ITD_IOC 0x8000
-#define EHCI_ITD_GET_IOC(x) (((x) >> 15) & 1)
-#define EHCI_ITD_SET_IOC(x) (((x) << 15) & EHCI_ITD_IOC)
-#define EHCI_ITD_GET_PG(x) (((x) >> 12) & 0xf)
-#define EHCI_ITD_SET_PG(x) (((x) & 0xf) << 12)
-#define EHCI_ITD_GET_OFFS(x) (((x) >> 0) & 0xfff)
-#define EHCI_ITD_SET_OFFS(x) (((x) & 0xfff) << 0)
- ehci_isoc_bufr_ptr_t itd_bufr[7];
-#define EHCI_ITD_GET_BPTR(x) ((x) & 0xfffff000)
-#define EHCI_ITD_SET_BPTR(x) ((x) & 0xfffff000)
-#define EHCI_ITD_GET_EP(x) (((x) >> 8) & 0xf)
-#define EHCI_ITD_SET_EP(x) (((x) & 0xf) << 8)
-#define EHCI_ITD_GET_DADDR(x) ((x) & 0x7f)
-#define EHCI_ITD_SET_DADDR(x) ((x) & 0x7f)
-#define EHCI_ITD_GET_DIR(x) (((x) >> 11) & 1)
-#define EHCI_ITD_SET_DIR(x) (((x) & 1) << 11)
-#define EHCI_ITD_GET_MAXPKT(x) ((x) & 0x7ff)
-#define EHCI_ITD_SET_MAXPKT(x) ((x) & 0x7ff)
-#define EHCI_ITD_GET_MULTI(x) ((x) & 0x3)
-#define EHCI_ITD_SET_MULTI(x) ((x) & 0x3)
-} ehci_itd_t;
-#define EHCI_ITD_ALIGN 32
-
-/* Split Transaction Isochronous Transfer Descriptor */
-typedef struct {
- ehci_link_t sitd_next;
- /* XXX many more */
-} ehci_sitd_t;
-#define EHCI_SITD_ALIGN 32
-
-/* Queue Element Transfer Descriptor */
-#define EHCI_QTD_NBUFFERS 5
-typedef struct {
- ehci_link_t qtd_next;
- ehci_link_t qtd_altnext;
- u_int32_t qtd_status;
-#define EHCI_QTD_GET_STATUS(x) (((x) >> 0) & 0xff)
-#define EHCI_QTD_SET_STATUS(x) ((x) << 0)
-#define EHCI_QTD_ACTIVE 0x80
-#define EHCI_QTD_HALTED 0x40
-#define EHCI_QTD_BUFERR 0x20
-#define EHCI_QTD_BABBLE 0x10
-#define EHCI_QTD_XACTERR 0x08
-#define EHCI_QTD_MISSEDMICRO 0x04
-#define EHCI_QTD_SPLITXSTATE 0x02
-#define EHCI_QTD_PINGSTATE 0x01
-#define EHCI_QTD_STATERRS 0x7c
-#define EHCI_QTD_GET_PID(x) (((x) >> 8) & 0x3)
-#define EHCI_QTD_SET_PID(x) ((x) << 8)
-#define EHCI_QTD_PID_OUT 0x0
-#define EHCI_QTD_PID_IN 0x1
-#define EHCI_QTD_PID_SETUP 0x2
-#define EHCI_QTD_GET_CERR(x) (((x) >> 10) & 0x3)
-#define EHCI_QTD_SET_CERR(x) ((x) << 10)
-#define EHCI_QTD_GET_C_PAGE(x) (((x) >> 12) & 0x7)
-#define EHCI_QTD_SET_C_PAGE(x) ((x) << 12)
-#define EHCI_QTD_GET_IOC(x) (((x) >> 15) & 0x1)
-#define EHCI_QTD_IOC 0x00008000
-#define EHCI_QTD_GET_BYTES(x) (((x) >> 16) & 0x7fff)
-#define EHCI_QTD_SET_BYTES(x) ((x) << 16)
-#define EHCI_QTD_GET_TOGGLE(x) (((x) >> 31) & 0x1)
-#define EHCI_QTD_SET_TOGGLE(x) ((x) << 31)
-#define EHCI_QTD_TOGGLE_MASK 0x80000000
- ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS];
- ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
-} ehci_qtd_t;
-#define EHCI_QTD_ALIGN 32
-
-#define EHCI_QTD_STATUS_BITS \
- "\20\10ACTIVE\7HALTED\6BUFERR\5BABBLE\4XACTERR\3MISSED\2SPLIT\1PING"
-
-/* Queue Head */
-typedef struct {
- ehci_link_t qh_link;
- u_int32_t qh_endp;
-#define EHCI_QH_GET_ADDR(x) (((x) >> 0) & 0x7f) /* endpoint addr */
-#define EHCI_QH_SET_ADDR(x) (x)
-#define EHCI_QH_ADDRMASK 0x0000007f
-#define EHCI_QH_GET_INACT(x) (((x) >> 7) & 0x01) /* inactivate on next */
-#define EHCI_QH_INACT 0x00000080
-#define EHCI_QH_GET_ENDPT(x) (((x) >> 8) & 0x0f) /* endpoint no */
-#define EHCI_QH_SET_ENDPT(x) ((x) << 8)
-#define EHCI_QH_GET_EPS(x) (((x) >> 12) & 0x03) /* endpoint speed */
-#define EHCI_QH_SET_EPS(x) ((x) << 12)
-#define EHCI_QH_SPEED_FULL 0x0
-#define EHCI_QH_SPEED_LOW 0x1
-#define EHCI_QH_SPEED_HIGH 0x2
-#define EHCI_QH_GET_DTC(x) (((x) >> 14) & 0x01) /* data toggle control */
-#define EHCI_QH_DTC 0x00004000
-#define EHCI_QH_GET_HRECL(x) (((x) >> 15) & 0x01) /* head of reclamation */
-#define EHCI_QH_HRECL 0x00008000
-#define EHCI_QH_GET_MPL(x) (((x) >> 16) & 0x7ff) /* max packet len */
-#define EHCI_QH_SET_MPL(x) ((x) << 16)
-#define EHCI_QH_MPLMASK 0x07ff0000
-#define EHCI_QH_GET_CTL(x) (((x) >> 27) & 0x01) /* control endpoint */
-#define EHCI_QH_CTL 0x08000000
-#define EHCI_QH_GET_NRL(x) (((x) >> 28) & 0x0f) /* NAK reload */
-#define EHCI_QH_SET_NRL(x) ((x) << 28)
- u_int32_t qh_endphub;
-#define EHCI_QH_GET_SMASK(x) (((x) >> 0) & 0xff) /* intr sched mask */
-#define EHCI_QH_SET_SMASK(x) ((x) << 0)
-#define EHCI_QH_GET_CMASK(x) (((x) >> 8) & 0xff) /* split completion mask */
-#define EHCI_QH_SET_CMASK(x) ((x) << 8)
-#define EHCI_QH_GET_HUBA(x) (((x) >> 16) & 0x7f) /* hub address */
-#define EHCI_QH_SET_HUBA(x) ((x) << 16)
-#define EHCI_QH_GET_PORT(x) (((x) >> 23) & 0x7f) /* hub port */
-#define EHCI_QH_SET_PORT(x) ((x) << 23)
-#define EHCI_QH_GET_MULT(x) (((x) >> 30) & 0x03) /* pipe multiplier */
-#define EHCI_QH_SET_MULT(x) ((x) << 30)
- ehci_link_t qh_curqtd;
- ehci_qtd_t qh_qtd;
-} ehci_qh_t;
-#define EHCI_QH_ALIGN 32
-
-/* Periodic Frame Span Traversal Node */
-typedef struct {
- ehci_link_t fstn_link;
- ehci_link_t fstn_back;
-} ehci_fstn_t;
-#define EHCI_FSTN_ALIGN 32
-
-#endif /* _DEV_PCI_EHCIREG_H_ */
diff --git a/sys/legacy/dev/usb/ehcivar.h b/sys/legacy/dev/usb/ehcivar.h
deleted file mode 100644
index fdd19ba..0000000
--- a/sys/legacy/dev/usb/ehcivar.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/* $NetBSD: ehcivar.h,v 1.19 2005/04/29 15:04:29 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-typedef struct ehci_soft_qtd {
- ehci_qtd_t qtd;
- struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */
- ehci_physaddr_t physaddr;
- usbd_xfer_handle xfer;
- LIST_ENTRY(ehci_soft_qtd) hnext;
- u_int16_t len;
-} ehci_soft_qtd_t;
-#define EHCI_SQTD_SIZE ((sizeof (struct ehci_soft_qtd) + EHCI_QTD_ALIGN - 1) / EHCI_QTD_ALIGN * EHCI_QTD_ALIGN)
-#define EHCI_SQTD_CHUNK (EHCI_PAGE_SIZE / EHCI_SQTD_SIZE)
-
-typedef struct ehci_soft_qh {
- ehci_qh_t qh;
- struct ehci_soft_qh *next;
- struct ehci_soft_qh *prev;
- struct ehci_soft_qtd *sqtd;
- struct ehci_soft_qtd *inactivesqtd;
- ehci_physaddr_t physaddr;
- int islot; /* Interrupt list slot. */
-} ehci_soft_qh_t;
-#define EHCI_SQH_SIZE ((sizeof (struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN)
-#define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE)
-
-typedef struct ehci_soft_itd {
- ehci_itd_t itd;
- union {
- struct {
- /* soft_itds links in a periodic frame*/
- struct ehci_soft_itd *next;
- struct ehci_soft_itd *prev;
- } frame_list;
- /* circular list of free itds */
- LIST_ENTRY(ehci_soft_itd) free_list;
- } u;
- struct ehci_soft_itd *xfer_next; /* Next soft_itd in xfer */
- ehci_physaddr_t physaddr;
- usb_dma_t dma;
- int offs;
- int slot;
- struct timeval t; /* store free time */
-} ehci_soft_itd_t;
-#define EHCI_ITD_SIZE ((sizeof(struct ehci_soft_itd) + EHCI_QH_ALIGN - 1) / EHCI_ITD_ALIGN * EHCI_ITD_ALIGN)
-#define EHCI_ITD_CHUNK (EHCI_PAGE_SIZE / EHCI_ITD_SIZE)
-
-struct ehci_xfer {
- struct usbd_xfer xfer;
- struct usb_task abort_task;
- LIST_ENTRY(ehci_xfer) inext; /* list of active xfers */
- ehci_soft_qtd_t *sqtdstart;
- ehci_soft_qtd_t *sqtdend;
- ehci_soft_itd_t *itdstart;
- ehci_soft_itd_t *itdend;
- u_int isoc_len;
- u_int32_t ehci_xfer_flags;
-#ifdef DIAGNOSTIC
- int isdone;
-#endif
-};
-#define EHCI_XFER_ABORTING 0x0001 /* xfer is aborting. */
-#define EHCI_XFER_ABORTWAIT 0x0002 /* abort completion is being awaited. */
-
-#define EXFER(xfer) ((struct ehci_xfer *)(xfer))
-
-/*
- * Information about an entry in the interrupt list.
- */
-struct ehci_soft_islot {
- ehci_soft_qh_t *sqh; /* Queue Head. */
-};
-
-#define EHCI_FRAMELIST_MAXCOUNT 1024
-#define EHCI_IPOLLRATES 8 /* Poll rates (1ms, 2, 4, 8 ... 128) */
-#define EHCI_INTRQHS ((1 << EHCI_IPOLLRATES) - 1)
-#define EHCI_MAX_POLLRATE (1 << (EHCI_IPOLLRATES - 1))
-#define EHCI_IQHIDX(lev, pos) \
- ((((pos) & ((1 << (lev)) - 1)) | (1 << (lev))) - 1)
-#define EHCI_ILEV_IVAL(lev) (1 << (lev))
-
-#define EHCI_HASH_SIZE 128
-#define EHCI_COMPANION_MAX 8
-
-#define EHCI_FREE_LIST_INTERVAL 100
-
-#define EHCI_SCFLG_DONEINIT 0x0001 /* ehci_init() has been called. */
-#define EHCI_SCFLG_LOSTINTRBUG 0x0002 /* workaround for VIA / ATI chipsets */
-#define EHCI_SCFLG_SETMODE 0x0004 /* set bridge mode again after init (Marvell) */
-#define EHCI_SCFLG_FORCESPEED 0x0008 /* force speed (Marvell) */
-#define EHCI_SCFLG_NORESTERM 0x0010 /* don't terminate reset sequence (Marvell) */
-#define EHCI_SCFLG_BIGEDESC 0x0020 /* big-endian byte order descriptors */
-#define EHCI_SCFLG_BIGEMMIO 0x0040 /* big-endian byte order MMIO */
-#define EHCI_SCFLG_TT 0x0080 /* transaction translator present */
-
-typedef struct ehci_softc {
- struct usbd_bus sc_bus; /* base device */
- int sc_flags;
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
- bus_size_t sc_size;
- void *ih;
-
- struct resource *io_res;
- struct resource *irq_res;
- u_int sc_offs; /* offset to operational regs */
-
- char sc_vendor[32]; /* vendor string for root hub */
- int sc_id_vendor; /* vendor ID for root hub */
-
- u_int32_t sc_cmd; /* shadow of cmd reg during suspend */
-
- u_int sc_ncomp;
- u_int sc_npcomp;
- struct usbd_bus *sc_comps[EHCI_COMPANION_MAX];
-
- usb_dma_t sc_fldma;
- ehci_link_t *sc_flist;
- u_int sc_flsize;
-
- struct ehci_soft_islot sc_islots[EHCI_INTRQHS];
-
- /* jcmm - an array matching sc_flist, but with software pointers,
- * not hardware address pointers
- */
- struct ehci_soft_itd **sc_softitds;
-
- LIST_HEAD(, ehci_xfer) sc_intrhead;
-
- ehci_soft_qh_t *sc_freeqhs;
- ehci_soft_qtd_t *sc_freeqtds;
- LIST_HEAD(sc_freeitds, ehci_soft_itd) sc_freeitds;
-
- int sc_noport;
- u_int8_t sc_addr; /* device address */
- u_int8_t sc_conf; /* device configuration */
- usbd_xfer_handle sc_intrxfer;
- char sc_isreset;
-#ifdef USB_USE_SOFTINTR
- char sc_softwake;
-#endif /* USB_USE_SOFTINTR */
-
- u_int32_t sc_eintrs;
- ehci_soft_qh_t *sc_async_head;
-
- STAILQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
-
- struct lock sc_doorbell_lock;
-
- struct callout sc_tmo_intrlist;
-
- char sc_dying;
-} ehci_softc_t;
-
-#define EREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a))
-#define EREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a))
-#define EREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a))
-#define EWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x))
-#define EWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x))
-#define EWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x))
-#define EOREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
-#define EOREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
-#define EOREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
-#define EOWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
-#define EOWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
-#define EOWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
-
-#ifdef USB_EHCI_BIG_ENDIAN_DESC
-/*
- * Handle byte order conversion between host and ``host controller''.
- * Typically the latter is little-endian but some controllers require
- * big-endian in which case we may need to manually swap.
- */
-static __inline uint32_t
-htohc32(const struct ehci_softc *sc, const uint32_t v)
-{
- return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? htobe32(v) : htole32(v);
-}
-
-static __inline uint16_t
-htohc16(const struct ehci_softc *sc, const uint16_t v)
-{
- return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? htobe16(v) : htole16(v);
-}
-
-static __inline uint32_t
-hc32toh(const struct ehci_softc *sc, const uint32_t v)
-{
- return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? be32toh(v) : le32toh(v);
-}
-
-static __inline uint16_t
-hc16toh(const struct ehci_softc *sc, const uint16_t v)
-{
- return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? be16toh(v) : le16toh(v);
-}
-#else
-/*
- * Normal little-endian only conversion routines.
- */
-static __inline uint32_t
-htohc32(const struct ehci_softc *sc, const uint32_t v)
-{
- return htole32(v);
-}
-
-static __inline uint16_t
-htohc16(const struct ehci_softc *sc, const uint16_t v)
-{
- return htole16(v);
-}
-
-static __inline uint32_t
-hc32toh(const struct ehci_softc *sc, const uint32_t v)
-{
- return le32toh(v);
-}
-
-static __inline uint16_t
-hc16toh(const struct ehci_softc *sc, const uint16_t v)
-{
- return le16toh(v);
-}
-#endif
-
-usbd_status ehci_reset(ehci_softc_t *);
-usbd_status ehci_init(ehci_softc_t *);
-int ehci_intr(void *);
-int ehci_detach(ehci_softc_t *, int);
-void ehci_power(int state, void *priv);
-void ehci_shutdown(void *v);
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-void ehci_dump_regs(ehci_softc_t *);
-void ehci_dump_sqtds(ehci_softc_t *, ehci_soft_qtd_t *);
-void ehci_dump_qtd(ehci_softc_t *, ehci_qtd_t *);
-void ehci_dump_sqtd(ehci_softc_t *, ehci_soft_qtd_t *);
-void ehci_dump_sqh(ehci_softc_t *, ehci_soft_qh_t *);
-void ehci_dump_itd(ehci_softc_t *, struct ehci_soft_itd *);
-void ehci_dump_sitd(ehci_softc_t *, struct ehci_soft_itd *);
-void ehci_dump_exfer(struct ehci_xfer *);
diff --git a/sys/legacy/dev/usb/hid.c b/sys/legacy/dev/usb/hid.c
deleted file mode 100644
index 70facb6..0000000
--- a/sys/legacy/dev/usb/hid.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/* $NetBSD: hid.c,v 1.17 2001/11/13 06:24:53 lukem Exp $ */
-
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/hid.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-extern int usbdebug;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-static void hid_clear_local(struct hid_item *);
-
-#define MAXUSAGE 100
-struct hid_data {
- u_char *start;
- u_char *end;
- u_char *p;
- struct hid_item cur;
- int32_t usages[MAXUSAGE];
- int nu;
- int minset;
- int multi;
- int multimax;
- int kindset;
-};
-
-static void
-hid_clear_local(struct hid_item *c)
-{
-
- c->usage = 0;
- c->usage_minimum = 0;
- c->usage_maximum = 0;
- c->designator_index = 0;
- c->designator_minimum = 0;
- c->designator_maximum = 0;
- c->string_index = 0;
- c->string_minimum = 0;
- c->string_maximum = 0;
- c->set_delimiter = 0;
-}
-
-struct hid_data *
-hid_start_parse(void *d, int len, int kindset)
-{
- struct hid_data *s;
-
- s = malloc(sizeof *s, M_TEMP, M_WAITOK|M_ZERO);
- s->start = s->p = d;
- s->end = (char *)d + len;
- s->kindset = kindset;
- return (s);
-}
-
-void
-hid_end_parse(struct hid_data *s)
-{
-
- while (s->cur.next != NULL) {
- struct hid_item *hi = s->cur.next->next;
- free(s->cur.next, M_TEMP);
- s->cur.next = hi;
- }
- free(s, M_TEMP);
-}
-
-int
-hid_get_item(struct hid_data *s, struct hid_item *h)
-{
- struct hid_item *c = &s->cur;
- unsigned int bTag, bType, bSize;
- u_int32_t oldpos;
- u_char *data;
- int32_t dval;
- u_char *p;
- struct hid_item *hi;
- int i;
-
- top:
- if (s->multimax != 0) {
- if (s->multi < s->multimax) {
- c->usage = s->usages[min(s->multi, s->nu-1)];
- s->multi++;
- *h = *c;
- c->loc.pos += c->loc.size;
- h->next = 0;
- return (1);
- } else {
- c->loc.count = s->multimax;
- s->multimax = 0;
- s->nu = 0;
- hid_clear_local(c);
- }
- }
- for (;;) {
- p = s->p;
- if (p >= s->end)
- return (0);
-
- bSize = *p++;
- if (bSize == 0xfe) {
- /* long item */
- bSize = *p++;
- bSize |= *p++ << 8;
- bTag = *p++;
- data = p;
- p += bSize;
- bType = 0xff; /* XXX what should it be */
- } else {
- /* short item */
- bTag = bSize >> 4;
- bType = (bSize >> 2) & 3;
- bSize &= 3;
- if (bSize == 3) bSize = 4;
- data = p;
- p += bSize;
- }
- s->p = p;
- switch(bSize) {
- case 0:
- dval = 0;
- break;
- case 1:
- dval = (int8_t)*data++;
- break;
- case 2:
- dval = *data++;
- dval |= *data++ << 8;
- dval = (int16_t)dval;
- break;
- case 4:
- dval = *data++;
- dval |= *data++ << 8;
- dval |= *data++ << 16;
- dval |= *data++ << 24;
- break;
- default:
- printf("BAD LENGTH %d\n", bSize);
- continue;
- }
-
- switch (bType) {
- case 0: /* Main */
- switch (bTag) {
- case 8: /* Input */
- if (!(s->kindset & (1 << hid_input))) {
- if (s->nu > 0)
- s->nu--;
- continue;
- }
- c->kind = hid_input;
- c->flags = dval;
- ret:
- if (c->flags & HIO_VARIABLE) {
- s->multimax = c->loc.count;
- s->multi = 0;
- c->loc.count = 1;
- if (s->minset) {
- for (i = c->usage_minimum;
- i <= c->usage_maximum;
- i++) {
- s->usages[s->nu] = i;
- if (s->nu < MAXUSAGE-1)
- s->nu++;
- }
- s->minset = 0;
- }
- goto top;
- } else {
- *h = *c;
- h->next = 0;
- c->loc.pos +=
- c->loc.size * c->loc.count;
- hid_clear_local(c);
- s->minset = 0;
- return (1);
- }
- case 9: /* Output */
- if (!(s->kindset & (1 << hid_output))) {
- if (s->nu > 0)
- s->nu--;
- continue;
- }
- c->kind = hid_output;
- c->flags = dval;
- goto ret;
- case 10: /* Collection */
- c->kind = hid_collection;
- c->collection = dval;
- c->collevel++;
- *h = *c;
- hid_clear_local(c);
- s->nu = 0;
- return (1);
- case 11: /* Feature */
- if (!(s->kindset & (1 << hid_feature))) {
- if (s->nu > 0)
- s->nu--;
- continue;
- }
- c->kind = hid_feature;
- c->flags = dval;
- goto ret;
- case 12: /* End collection */
- c->kind = hid_endcollection;
- c->collevel--;
- *h = *c;
- hid_clear_local(c);
- s->nu = 0;
- return (1);
- default:
- printf("Main bTag=%d\n", bTag);
- break;
- }
- break;
- case 1: /* Global */
- switch (bTag) {
- case 0:
- c->_usage_page = dval << 16;
- break;
- case 1:
- c->logical_minimum = dval;
- break;
- case 2:
- c->logical_maximum = dval;
- break;
- case 3:
- c->physical_minimum = dval;
- break;
- case 4:
- c->physical_maximum = dval;
- break;
- case 5:
- c->unit_exponent = dval;
- break;
- case 6:
- c->unit = dval;
- break;
- case 7:
- c->loc.size = dval;
- break;
- case 8:
- c->report_ID = dval;
- break;
- case 9:
- c->loc.count = dval;
- break;
- case 10: /* Push */
- hi = malloc(sizeof *hi, M_TEMP, M_WAITOK);
- *hi = s->cur;
- c->next = hi;
- break;
- case 11: /* Pop */
- hi = c->next;
- oldpos = c->loc.pos;
- s->cur = *hi;
- c->loc.pos = oldpos;
- free(hi, M_TEMP);
- break;
- default:
- printf("Global bTag=%d\n", bTag);
- break;
- }
- break;
- case 2: /* Local */
- switch (bTag) {
- case 0:
- if (bSize == 1)
- dval = c->_usage_page | (dval&0xff);
- else if (bSize == 2)
- dval = c->_usage_page | (dval&0xffff);
- c->usage = dval;
- if (s->nu < MAXUSAGE)
- s->usages[s->nu++] = dval;
- /* else XXX */
- break;
- case 1:
- s->minset = 1;
- if (bSize == 1)
- dval = c->_usage_page | (dval&0xff);
- else if (bSize == 2)
- dval = c->_usage_page | (dval&0xffff);
- c->usage_minimum = dval;
- break;
- case 2:
- if (bSize == 1)
- dval = c->_usage_page | (dval&0xff);
- else if (bSize == 2)
- dval = c->_usage_page | (dval&0xffff);
- c->usage_maximum = dval;
- break;
- case 3:
- c->designator_index = dval;
- break;
- case 4:
- c->designator_minimum = dval;
- break;
- case 5:
- c->designator_maximum = dval;
- break;
- case 7:
- c->string_index = dval;
- break;
- case 8:
- c->string_minimum = dval;
- break;
- case 9:
- c->string_maximum = dval;
- break;
- case 10:
- c->set_delimiter = dval;
- break;
- default:
- printf("Local bTag=%d\n", bTag);
- break;
- }
- break;
- default:
- printf("default bType=%d\n", bType);
- break;
- }
- }
-}
-
-int
-hid_report_size(void *buf, int len, enum hid_kind k, u_int8_t *idp)
-{
- struct hid_data *d;
- struct hid_item h;
- int hi, lo, size, id;
-
- id = 0;
- hi = lo = -1;
- for (d = hid_start_parse(buf, len, 1<<k); hid_get_item(d, &h); )
- if (h.kind == k) {
- if (h.report_ID != 0 && !id)
- id = h.report_ID;
- if (h.report_ID == id) {
- if (lo < 0)
- lo = h.loc.pos;
- hi = h.loc.pos + h.loc.size * h.loc.count;
- }
- }
- hid_end_parse(d);
- size = hi - lo;
- if (id != 0) {
- size += 8;
- *idp = id; /* XXX wrong */
- } else
- *idp = 0;
- return ((size + 7) / 8);
-}
-
-int
-hid_locate(void *desc, int size, u_int32_t u, enum hid_kind k,
- struct hid_location *loc, u_int32_t *flags)
-{
- struct hid_data *d;
- struct hid_item h;
-
- for (d = hid_start_parse(desc, size, 1<<k); hid_get_item(d, &h); ) {
- if (h.kind == k && !(h.flags & HIO_CONST) && h.usage == u) {
- if (loc != NULL)
- *loc = h.loc;
- if (flags != NULL)
- *flags = h.flags;
- hid_end_parse(d);
- return (1);
- }
- }
- hid_end_parse(d);
- loc->size = 0;
- return (0);
-}
-
-u_long
-hid_get_data(u_char *buf, struct hid_location *loc)
-{
- u_int hpos = loc->pos;
- u_int hsize = loc->size;
- u_int32_t data;
- int i, s;
-
- DPRINTFN(10, ("hid_get_data: loc %d/%d\n", hpos, hsize));
-
- if (hsize == 0)
- return (0);
-
- data = 0;
- s = hpos / 8;
- for (i = hpos; i < hpos+hsize; i += 8)
- data |= buf[i / 8] << ((i / 8 - s) * 8);
- data >>= hpos % 8;
- data &= (1 << hsize) - 1;
- hsize = 32 - hsize;
- /* Sign extend */
- data = ((int32_t)data << hsize) >> hsize;
- DPRINTFN(10,("hid_get_data: loc %d/%d = %lu\n",
- loc->pos, loc->size, (long)data));
- return (data);
-}
-
-int
-hid_is_collection(void *desc, int size, u_int32_t usage)
-{
- struct hid_data *hd;
- struct hid_item hi;
- int err;
-
- hd = hid_start_parse(desc, size, hid_input);
- if (hd == NULL)
- return (0);
-
- err = hid_get_item(hd, &hi) &&
- hi.kind == hid_collection &&
- hi.usage == usage;
- hid_end_parse(hd);
- return (err);
-}
diff --git a/sys/legacy/dev/usb/hid.h b/sys/legacy/dev/usb/hid.h
deleted file mode 100644
index a4ab7d2..0000000
--- a/sys/legacy/dev/usb/hid.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* $NetBSD: hid.h,v 1.6 2000/06/01 14:28:57 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-enum hid_kind {
- hid_input, hid_output, hid_feature, hid_collection, hid_endcollection
-};
-
-struct hid_location {
- u_int32_t size;
- u_int32_t count;
- u_int32_t pos;
-};
-
-struct hid_item {
- /* Global */
- int32_t _usage_page;
- int32_t logical_minimum;
- int32_t logical_maximum;
- int32_t physical_minimum;
- int32_t physical_maximum;
- int32_t unit_exponent;
- int32_t unit;
- int32_t report_ID;
- /* Local */
- int32_t usage;
- int32_t usage_minimum;
- int32_t usage_maximum;
- int32_t designator_index;
- int32_t designator_minimum;
- int32_t designator_maximum;
- int32_t string_index;
- int32_t string_minimum;
- int32_t string_maximum;
- int32_t set_delimiter;
- /* Misc */
- int32_t collection;
- int collevel;
- enum hid_kind kind;
- u_int32_t flags;
- /* Location */
- struct hid_location loc;
- /* */
- struct hid_item *next;
-};
-
-struct hid_data *hid_start_parse(void *d, int len, int kindset);
-void hid_end_parse(struct hid_data *s);
-int hid_get_item(struct hid_data *s, struct hid_item *h);
-int hid_report_size(void *buf, int len, enum hid_kind k, u_int8_t *id);
-int hid_locate(void *desc, int size, u_int32_t usage,
- enum hid_kind kind, struct hid_location *loc,
- u_int32_t *flags);
-u_long hid_get_data(u_char *buf, struct hid_location *loc);
-int hid_is_collection(void *desc, int size, u_int32_t usage);
diff --git a/sys/legacy/dev/usb/if_urtw.c b/sys/legacy/dev/usb/if_urtw.c
deleted file mode 100644
index d1a3a84..0000000
--- a/sys/legacy/dev/usb/if_urtw.c
+++ /dev/null
@@ -1,3324 +0,0 @@
-/*-
- * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#include <sys/param.h>
-#include <sys/sockio.h>
-#include <sys/sysctl.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/endian.h>
-#include <sys/kdb.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/if_ether.h>
-#include <netinet/ip.h>
-#endif
-
-#include <net80211/ieee80211_var.h>
-#include <net80211/ieee80211_regdomain.h>
-#include <net80211/ieee80211_radiotap.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/if_urtwreg.h>
-#include <dev/usb/if_urtwvar.h>
-
-SYSCTL_NODE(_hw_usb, OID_AUTO, urtw, CTLFLAG_RW, 0, "USB Realtek 8187L");
-#ifdef URTW_DEBUG
-int urtw_debug = 0;
-SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RW, &urtw_debug, 0,
- "control debugging printfs");
-TUNABLE_INT("hw.usb.urtw.debug", &urtw_debug);
-enum {
- URTW_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
- URTW_DEBUG_RECV = 0x00000002, /* basic recv operation */
- URTW_DEBUG_RESET = 0x00000004, /* reset processing */
- URTW_DEBUG_TX_PROC = 0x00000008, /* tx ISR proc */
- URTW_DEBUG_RX_PROC = 0x00000010, /* rx ISR proc */
- URTW_DEBUG_STATE = 0x00000020, /* 802.11 state transitions */
- URTW_DEBUG_STAT = 0x00000040, /* statistic */
- URTW_DEBUG_ANY = 0xffffffff
-};
-#define DPRINTF(sc, m, fmt, ...) do { \
- if (sc->sc_debug & (m)) \
- printf(fmt, __VA_ARGS__); \
-} while (0)
-#else
-#define DPRINTF(sc, m, fmt, ...) do { \
- (void) sc; \
-} while (0)
-#endif
-int urtw_preamble_mode = URTW_PREAMBLE_MODE_LONG;
-SYSCTL_INT(_hw_usb_urtw, OID_AUTO, preamble_mode, CTLFLAG_RW,
- &urtw_preamble_mode, 0, "set the preable mode (long or short)");
-TUNABLE_INT("hw.usb.urtw.preamble_mode", &urtw_preamble_mode);
-
-/* recognized device vendors/products */
-static const struct usb_devno urtw_devs[] = {
-#define URTW_DEV(v,p) { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }
- URTW_DEV(REALTEK, RTL8187),
- URTW_DEV(NETGEAR, WG111V2)
-#undef URTW_DEV
-};
-
-#define urtw_read8_m(sc, val, data) do { \
- error = urtw_read8_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_write8_m(sc, val, data) do { \
- error = urtw_write8_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_read16_m(sc, val, data) do { \
- error = urtw_read16_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_write16_m(sc, val, data) do { \
- error = urtw_write16_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_read32_m(sc, val, data) do { \
- error = urtw_read32_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_write32_m(sc, val, data) do { \
- error = urtw_write32_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_8187_write_phy_ofdm(sc, val, data) do { \
- error = urtw_8187_write_phy_ofdm_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_8187_write_phy_cck(sc, val, data) do { \
- error = urtw_8187_write_phy_cck_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_8225_write(sc, val, data) do { \
- error = urtw_8225_write_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-
-struct urtw_pair {
- uint32_t reg;
- uint32_t val;
-};
-
-static uint8_t urtw_8225_agc[] = {
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
- 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
- 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
- 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
- 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
- 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
- 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
- 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
- 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
-};
-
-static uint32_t urtw_8225_channel[] = {
- 0x0000, /* dummy channel 0 */
- 0x085c, /* 1 */
- 0x08dc, /* 2 */
- 0x095c, /* 3 */
- 0x09dc, /* 4 */
- 0x0a5c, /* 5 */
- 0x0adc, /* 6 */
- 0x0b5c, /* 7 */
- 0x0bdc, /* 8 */
- 0x0c5c, /* 9 */
- 0x0cdc, /* 10 */
- 0x0d5c, /* 11 */
- 0x0ddc, /* 12 */
- 0x0e5c, /* 13 */
- 0x0f72, /* 14 */
-};
-
-static uint8_t urtw_8225_gain[] = {
- 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
- 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
- 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
- 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
- 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
- 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
- 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
-};
-
-static struct urtw_pair urtw_8225_rf_part1[] = {
- { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
- { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
- { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
- { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
-};
-
-static struct urtw_pair urtw_8225_rf_part2[] = {
- { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
- { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
- { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
- { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
- { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
- { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
- { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
- { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
- { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
- { 0x27, 0x88 }
-};
-
-static struct urtw_pair urtw_8225_rf_part3[] = {
- { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
- { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
- { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
- { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
- { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
- { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
- { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
-};
-
-static uint16_t urtw_8225_rxgain[] = {
- 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
- 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
- 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
- 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
- 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
- 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
- 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
- 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
- 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
- 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
- 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
- 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
-};
-
-static uint8_t urtw_8225_threshold[] = {
- 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
-};
-
-static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
- 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
-};
-
-static uint8_t urtw_8225_txpwr_cck[] = {
- 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
- 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
- 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
- 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
- 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
- 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
-};
-
-static uint8_t urtw_8225_txpwr_cck_ch14[] = {
- 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
- 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
- 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
- 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
-};
-
-static uint8_t urtw_8225_txpwr_ofdm[]={
- 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
-};
-
-static uint8_t urtw_8225v2_gain_bg[]={
- 0x23, 0x15, 0xa5, /* -82-1dbm */
- 0x23, 0x15, 0xb5, /* -82-2dbm */
- 0x23, 0x15, 0xc5, /* -82-3dbm */
- 0x33, 0x15, 0xc5, /* -78dbm */
- 0x43, 0x15, 0xc5, /* -74dbm */
- 0x53, 0x15, 0xc5, /* -70dbm */
- 0x63, 0x15, 0xc5, /* -66dbm */
-};
-
-static struct urtw_pair urtw_8225v2_rf_part1[] = {
- { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
- { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
- { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
- { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
-};
-
-static struct urtw_pair urtw_8225v2_rf_part2[] = {
- { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
- { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
- { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
- { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
- { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
- { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
- { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
- { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
- { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
- { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
-};
-
-static struct urtw_pair urtw_8225v2_rf_part3[] = {
- { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
- { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
- { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
- { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
- { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
- { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
- { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
- { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
-};
-
-static uint16_t urtw_8225v2_rxgain[] = {
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
- 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
- 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
- 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
- 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
- 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
- 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
- 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
- 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
- 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
- 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
- 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
-};
-
-static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
- 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
- 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
- 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
- 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
-};
-
-static uint8_t urtw_8225v2_txpwr_cck[] = {
- 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
-};
-
-static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
- 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
-};
-
-static struct urtw_pair urtw_ratetable[] = {
- { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
- { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
- { 96, 10 }, { 108, 11 }
-};
-
-static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
- const char name[IFNAMSIZ], int unit, int opmode,
- int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void urtw_vap_delete(struct ieee80211vap *);
-static void urtw_init(void *);
-static void urtw_stop(struct ifnet *, int);
-static int urtw_ioctl(struct ifnet *, u_long, caddr_t);
-static void urtw_start(struct ifnet *);
-static int urtw_alloc_rx_data_list(struct urtw_softc *);
-static int urtw_alloc_tx_data_list(struct urtw_softc *);
-static void urtw_free_data_list(struct urtw_softc *,
- usbd_pipe_handle, usbd_pipe_handle,
- struct urtw_data data[], int);
-static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
- const struct ieee80211_bpf_params *);
-static void urtw_scan_start(struct ieee80211com *);
-static void urtw_scan_end(struct ieee80211com *);
-static void urtw_set_channel(struct ieee80211com *);
-static void urtw_update_mcast(struct ifnet *);
-static void urtw_rxeof(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-static int urtw_tx_start(struct urtw_softc *,
- struct ieee80211_node *, struct mbuf *, int);
-static void urtw_txeof_low(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-static void urtw_txeof_normal(usbd_xfer_handle,
- usbd_private_handle, usbd_status);
-static int urtw_newstate(struct ieee80211vap *,
- enum ieee80211_state, int);
-static void urtw_ledtask(void *);
-static void urtw_ledusbtask(void *);
-static void urtw_ctxtask(void *);
-static void urtw_task(void *);
-static void urtw_watchdog(void *);
-static void urtw_set_multi(void *);
-static int urtw_isbmode(uint16_t);
-static uint16_t urtw_rate2rtl(int);
-static uint16_t urtw_rtl2rate(int);
-static usbd_status urtw_set_rate(struct urtw_softc *);
-static usbd_status urtw_update_msr(struct urtw_softc *);
-static usbd_status urtw_read8_c(struct urtw_softc *, int, uint8_t *);
-static usbd_status urtw_read16_c(struct urtw_softc *, int, uint16_t *);
-static usbd_status urtw_read32_c(struct urtw_softc *, int, uint32_t *);
-static usbd_status urtw_write8_c(struct urtw_softc *, int, uint8_t);
-static usbd_status urtw_write16_c(struct urtw_softc *, int, uint16_t);
-static usbd_status urtw_write32_c(struct urtw_softc *, int, uint32_t);
-static usbd_status urtw_eprom_cs(struct urtw_softc *, int);
-static usbd_status urtw_eprom_ck(struct urtw_softc *);
-static usbd_status urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
- int);
-static usbd_status urtw_eprom_read32(struct urtw_softc *, uint32_t,
- uint32_t *);
-static usbd_status urtw_eprom_readbit(struct urtw_softc *, int16_t *);
-static usbd_status urtw_eprom_writebit(struct urtw_softc *, int16_t);
-static usbd_status urtw_get_macaddr(struct urtw_softc *);
-static usbd_status urtw_get_txpwr(struct urtw_softc *);
-static usbd_status urtw_get_rfchip(struct urtw_softc *);
-static usbd_status urtw_led_init(struct urtw_softc *);
-static usbd_status urtw_8185_rf_pins_enable(struct urtw_softc *);
-static usbd_status urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
-static usbd_status urtw_8187_write_phy(struct urtw_softc *, uint8_t,
- uint32_t);
-static usbd_status urtw_8187_write_phy_ofdm_c(struct urtw_softc *,
- uint8_t, uint32_t);
-static usbd_status urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
- uint32_t);
-static usbd_status urtw_8225_setgain(struct urtw_softc *, int16_t);
-static usbd_status urtw_8225_usb_init(struct urtw_softc *);
-static usbd_status urtw_8225_write_c(struct urtw_softc *, uint8_t,
- uint16_t);
-static usbd_status urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
- uint16_t *);
-static usbd_status urtw_8225_read(struct urtw_softc *, uint8_t,
- uint32_t *);
-static usbd_status urtw_8225_rf_init(struct urtw_softc *);
-static usbd_status urtw_8225_rf_set_chan(struct urtw_softc *, int);
-static usbd_status urtw_8225_rf_set_sens(struct urtw_softc *, int);
-static usbd_status urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
-static usbd_status urtw_8225v2_rf_init(struct urtw_softc *);
-static usbd_status urtw_8225v2_rf_set_chan(struct urtw_softc *, int);
-static usbd_status urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
-static usbd_status urtw_8225v2_setgain(struct urtw_softc *, int16_t);
-static usbd_status urtw_8225_isv2(struct urtw_softc *, int *);
-static usbd_status urtw_read8e(struct urtw_softc *, int, uint8_t *);
-static usbd_status urtw_write8e(struct urtw_softc *, int, uint8_t);
-static usbd_status urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
-static usbd_status urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
-static usbd_status urtw_open_pipes(struct urtw_softc *);
-static usbd_status urtw_close_pipes(struct urtw_softc *);
-static usbd_status urtw_intr_enable(struct urtw_softc *);
-static usbd_status urtw_intr_disable(struct urtw_softc *);
-static usbd_status urtw_reset(struct urtw_softc *);
-static usbd_status urtw_led_on(struct urtw_softc *, int);
-static usbd_status urtw_led_ctl(struct urtw_softc *, int);
-static usbd_status urtw_led_blink(struct urtw_softc *);
-static usbd_status urtw_led_mode0(struct urtw_softc *, int);
-static usbd_status urtw_led_mode1(struct urtw_softc *, int);
-static usbd_status urtw_led_mode2(struct urtw_softc *, int);
-static usbd_status urtw_led_mode3(struct urtw_softc *, int);
-static usbd_status urtw_rx_setconf(struct urtw_softc *);
-static usbd_status urtw_rx_enable(struct urtw_softc *);
-static usbd_status urtw_tx_enable(struct urtw_softc *sc);
-
-static int
-urtw_match(device_t dev)
-{
- struct usb_attach_arg *uaa = device_get_ivars(dev);
- const struct usb_devno *ud;
-
- if (uaa->iface != NULL)
- return UMATCH_NONE;
- ud = usb_lookup(urtw_devs, uaa->vendor, uaa->product);
-
- return (ud != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-static int
-urtw_attach(device_t dev)
-{
- int ret = 0;
- struct urtw_softc *sc = device_get_softc(dev);
- struct usb_attach_arg *uaa = device_get_ivars(dev);
- struct ieee80211com *ic;
- struct ifnet *ifp;
- uint8_t bands;
- uint32_t data;
- usbd_status error;
-
- sc->sc_dev = dev;
- sc->sc_udev = uaa->device;
-#ifdef URTW_DEBUG
- sc->sc_debug = urtw_debug;
-#endif
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
- MTX_DEF);
- callout_init(&sc->sc_led_ch, 0);
- callout_init(&sc->sc_watchdog_ch, 0);
- usb_init_task(&sc->sc_ledtask, urtw_ledusbtask, sc);
- usb_init_task(&sc->sc_ctxtask, urtw_ctxtask, sc);
- usb_init_task(&sc->sc_task, urtw_task, sc);
-
- urtw_read32_m(sc, URTW_RX, &data);
- sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
- URTW_EEPROM_93C46;
-
- error = urtw_get_rfchip(sc);
- if (error != 0)
- goto fail;
- error = urtw_get_macaddr(sc);
- if (error != 0)
- goto fail;
- error = urtw_get_txpwr(sc);
- if (error != 0)
- goto fail;
- error = urtw_led_init(sc);
- if (error != 0)
- goto fail;
-
- sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
- sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
- sc->sc_currate = 3;
- sc->sc_preamble_mode = urtw_preamble_mode;
-
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not allocate ifnet\n");
- ret = ENXIO;
- goto fail;
- }
-
- ifp->if_softc = sc;
- if_initname(ifp, "urtw", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT; /* USB stack is still under Giant lock */
- ifp->if_init = urtw_init;
- ifp->if_ioctl = urtw_ioctl;
- ifp->if_start = urtw_start;
- /* XXX URTW_TX_DATA_LIST_COUNT */
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
- ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
- ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
-
- /* set device capabilities */
- ic->ic_caps =
- IEEE80211_C_STA | /* station mode */
- IEEE80211_C_MONITOR | /* monitor mode supported */
- IEEE80211_C_TXPMGT | /* tx power management */
- IEEE80211_C_SHPREAMBLE | /* short preamble supported */
- IEEE80211_C_SHSLOT | /* short slot time supported */
- IEEE80211_C_BGSCAN | /* capable of bg scanning */
- IEEE80211_C_WPA; /* 802.11i */
-
- IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
-
- bands = 0;
- setbit(&bands, IEEE80211_MODE_11B);
- setbit(&bands, IEEE80211_MODE_11G);
- ieee80211_init_channels(ic, NULL, &bands);
-
- ieee80211_ifattach(ic);
- ic->ic_raw_xmit = urtw_raw_xmit;
- ic->ic_scan_start = urtw_scan_start;
- ic->ic_scan_end = urtw_scan_end;
- ic->ic_set_channel = urtw_set_channel;
-
- ic->ic_vap_create = urtw_vap_create;
- ic->ic_vap_delete = urtw_vap_delete;
- ic->ic_update_mcast = urtw_update_mcast;
-
- bpfattach(ifp, DLT_IEEE802_11_RADIO,
- sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
-
- sc->sc_rxtap_len = sizeof sc->sc_rxtap;
- sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
- sc->sc_rxtap.wr_ihdr.it_present = htole32(URTW_RX_RADIOTAP_PRESENT);
-
- sc->sc_txtap_len = sizeof sc->sc_txtap;
- sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
- sc->sc_txtap.wt_ihdr.it_present = htole32(URTW_TX_RADIOTAP_PRESENT);
-
- if (bootverbose)
- ieee80211_announce(ic);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
-fail:
- return (ret);
-}
-
-static usbd_status
-urtw_open_pipes(struct urtw_softc *sc)
-{
- usbd_status error;
-
- /*
- * NB: there is no way to distinguish each pipes so we need to hardcode
- * pipe numbers
- */
-
- /* tx pipe - low priority packets */
- error = usbd_open_pipe(sc->sc_iface, 0x2, USBD_EXCLUSIVE_USE,
- &sc->sc_txpipe_low);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not open Tx low pipe: %s\n",
- usbd_errstr(error));
- goto fail;
- }
- /* tx pipe - normal priority packets */
- error = usbd_open_pipe(sc->sc_iface, 0x3, USBD_EXCLUSIVE_USE,
- &sc->sc_txpipe_normal);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not open Tx normal pipe: %s\n",
- usbd_errstr(error));
- goto fail;
- }
- /* rx pipe */
- error = usbd_open_pipe(sc->sc_iface, 0x81, USBD_EXCLUSIVE_USE,
- &sc->sc_rxpipe);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not open Rx pipe: %s\n",
- usbd_errstr(error));
- goto fail;
- }
-
- return (0);
-fail:
- (void)urtw_close_pipes(sc);
- return (error);
-}
-
-static usbd_status
-urtw_close_pipes(struct urtw_softc *sc)
-{
- usbd_status error = 0;
-
- if (sc->sc_rxpipe != NULL) {
- error = usbd_close_pipe(sc->sc_rxpipe);
- if (error != 0)
- goto fail;
- sc->sc_rxpipe = NULL;
- }
- if (sc->sc_txpipe_low != NULL) {
- error = usbd_close_pipe(sc->sc_txpipe_low);
- if (error != 0)
- goto fail;
- sc->sc_txpipe_low = NULL;
- }
- if (sc->sc_txpipe_normal != NULL) {
- error = usbd_close_pipe(sc->sc_txpipe_normal);
- if (error != 0)
- goto fail;
- sc->sc_txpipe_normal = NULL;
- }
-fail:
- return (error);
-}
-
-static int
-urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
- int ndata, int maxsz, int fillmbuf)
-{
- int i, error;
-
- for (i = 0; i < ndata; i++) {
- struct urtw_data *dp = &data[i];
-
- dp->sc = sc;
- dp->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (dp->xfer == NULL) {
- device_printf(sc->sc_dev, "could not allocate xfer\n");
- error = ENOMEM;
- goto fail;
- }
- if (fillmbuf) {
- dp->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (dp->m == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate rx mbuf\n");
- error = ENOMEM;
- goto fail;
- }
- dp->buf = mtod(dp->m, uint8_t *);
- } else {
- dp->m = NULL;
- dp->buf = usbd_alloc_buffer(dp->xfer, maxsz);
- if (dp->buf == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate buffer\n");
- error = ENOMEM;
- goto fail;
- }
- if (((unsigned long)dp->buf) % 4)
- device_printf(sc->sc_dev,
- "warn: unaligned buffer %p\n", dp->buf);
- }
- dp->ni = NULL;
- }
-
- return 0;
-
-fail: urtw_free_data_list(sc, NULL, NULL, data, ndata);
- return error;
-}
-
-static void
-urtw_free_data_list(struct urtw_softc *sc, usbd_pipe_handle pipe1,
- usbd_pipe_handle pipe2, struct urtw_data data[], int ndata)
-{
- int i;
-
- /* make sure no transfers are pending */
- if (pipe1 != NULL)
- usbd_abort_pipe(pipe1);
- if (pipe2 != NULL)
- usbd_abort_pipe(pipe2);
-
- for (i = 0; i < ndata; i++) {
- struct urtw_data *dp = &data[i];
-
- if (dp->xfer != NULL) {
- usbd_free_xfer(dp->xfer);
- dp->xfer = NULL;
- }
- if (dp->m != NULL) {
- m_freem(dp->m);
- dp->m = NULL;
- }
- if (dp->ni != NULL) {
- ieee80211_free_node(dp->ni);
- dp->ni = NULL;
- }
- }
-}
-
-static int
-urtw_alloc_rx_data_list(struct urtw_softc *sc)
-{
-
- return urtw_alloc_data_list(sc,
- sc->sc_rxdata, URTW_RX_DATA_LIST_COUNT, MCLBYTES, 1 /* mbufs */);
-}
-
-static void
-urtw_free_rx_data_list(struct urtw_softc *sc)
-{
-
- urtw_free_data_list(sc, sc->sc_rxpipe, NULL, sc->sc_rxdata,
- URTW_RX_DATA_LIST_COUNT);
-}
-
-static int
-urtw_alloc_tx_data_list(struct urtw_softc *sc)
-{
-
- return urtw_alloc_data_list(sc,
- sc->sc_txdata, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE,
- 0 /* no mbufs */);
-}
-
-static void
-urtw_free_tx_data_list(struct urtw_softc *sc)
-{
-
- urtw_free_data_list(sc, sc->sc_txpipe_low, sc->sc_txpipe_normal,
- sc->sc_txdata, URTW_TX_DATA_LIST_COUNT);
-}
-
-static usbd_status
-urtw_led_init(struct urtw_softc *sc)
-{
- uint32_t rev;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
- error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
- if (error != 0)
- goto fail;
-
- switch (rev & URTW_EPROM_CID_MASK) {
- case URTW_EPROM_CID_ALPHA0:
- sc->sc_strategy = URTW_SW_LED_MODE1;
- break;
- case URTW_EPROM_CID_SERCOMM_PS:
- sc->sc_strategy = URTW_SW_LED_MODE3;
- break;
- case URTW_EPROM_CID_HW_LED:
- sc->sc_strategy = URTW_HW_LED;
- break;
- case URTW_EPROM_CID_RSVD0:
- case URTW_EPROM_CID_RSVD1:
- default:
- sc->sc_strategy = URTW_SW_LED_MODE0;
- break;
- }
-
- sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
-
-fail:
- return (error);
-}
-
-/* XXX why we should allocalte memory buffer instead of using memory stack? */
-static usbd_status
-urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
- uint16_t *data)
-{
- uint8_t *buf;
- uint16_t data16;
- usb_device_request_t *req;
- usbd_status error = 0;
-
- data16 = *data;
- req = (usb_device_request_t *)malloc(sizeof(usb_device_request_t),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (req == NULL) {
- device_printf(sc->sc_dev, "could not allocate a memory\n");
- goto fail0;
- }
- buf = (uint8_t *)malloc(2, M_80211_VAP, M_NOWAIT | M_ZERO);
- if (req == NULL) {
- device_printf(sc->sc_dev, "could not allocate a memory\n");
- goto fail1;
- }
-
- req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req->bRequest = URTW_8187_SETREGS_REQ;
- USETW(req->wValue, addr);
- USETW(req->wIndex, index);
- USETW(req->wLength, sizeof(uint16_t));
- buf[0] = (data16 & 0x00ff);
- buf[1] = (data16 & 0xff00) >> 8;
-
- error = usbd_do_request(sc->sc_udev, req, buf);
-
- free(buf, M_80211_VAP);
-fail1: free(req, M_80211_VAP);
-fail0: return (error);
-}
-
-static usbd_status
-urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
-{
- int i;
- int16_t bit;
- uint8_t rlen = 12, wlen = 6;
- uint16_t o1, o2, o3, tmp;
- uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
- uint32_t mask = 0x80000000, value = 0;
- usbd_status error;
-
- urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
- urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
- urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
- o1 &= ~URTW_RF_PINS_MAGIC4;
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
- DELAY(5);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
- DELAY(5);
-
- for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
- bit = ((d2w & mask) != 0) ? 1 : 0;
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
- URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
- URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- mask = mask >> 1;
- if (i == 2)
- break;
- bit = ((d2w & mask) != 0) ? 1 : 0;
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
- URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
- URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
- DELAY(1);
- }
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
- URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
- DELAY(2);
-
- mask = 0x800;
- for (i = 0; i < rlen; i++, mask = mask >> 1) {
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
- o1 | URTW_BB_HOST_BANG_RW);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
- o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
- o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
- o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
- DELAY(2);
-
- urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
- value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
- o1 | URTW_BB_HOST_BANG_RW);
- DELAY(2);
- }
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
- URTW_BB_HOST_BANG_RW);
- DELAY(2);
-
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_OUTPUT_MAGIC1);
-
- if (data != NULL)
- *data = value;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
-{
- uint16_t d80, d82, d84;
- usbd_status error;
-
- urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
- d80 &= URTW_RF_PINS_MAGIC1;
- urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
- urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
- d84 &= URTW_RF_PINS_MAGIC2;
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | URTW_RF_PINS_MAGIC3);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | URTW_RF_PINS_MAGIC3);
- DELAY(10);
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
- DELAY(10);
-
- error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
- if (error != 0)
- goto fail;
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
- DELAY(10);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
- usbd_delay_ms(sc->sc_udev, 2);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225_isv2(struct urtw_softc *sc, int *ret)
-{
- uint32_t data;
- usbd_status error;
-
- *ret = 1;
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_MAGIC5);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, URTW_RF_PINS_MAGIC5);
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, URTW_RF_PINS_MAGIC5);
- usbd_delay_ms(sc->sc_udev, 500);
-
- urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
- URTW_8225_ADDR_0_DATA_MAGIC1);
-
- error = urtw_8225_read(sc, URTW_8225_ADDR_8_MAGIC, &data);
- if (error != 0)
- goto fail;
- if (data != URTW_8225_ADDR_8_DATA_MAGIC1)
- *ret = 0;
- else {
- error = urtw_8225_read(sc, URTW_8225_ADDR_9_MAGIC, &data);
- if (error != 0)
- goto fail;
- if (data != URTW_8225_ADDR_9_DATA_MAGIC1)
- *ret = 0;
- }
-
- urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
- URTW_8225_ADDR_0_DATA_MAGIC2);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_get_rfchip(struct urtw_softc *sc)
-{
- int ret;
- uint32_t data;
- usbd_status error;
-
- error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
- if (error != 0)
- goto fail;
- switch (data & 0xff) {
- case URTW_EPROM_RFCHIPID_RTL8225U:
- error = urtw_8225_isv2(sc, &ret);
- if (error != 0)
- goto fail;
- if (ret == 0) {
- sc->sc_rf_init = urtw_8225_rf_init;
- sc->sc_rf_set_sens = urtw_8225_rf_set_sens;
- sc->sc_rf_set_chan = urtw_8225_rf_set_chan;
- } else {
- sc->sc_rf_init = urtw_8225v2_rf_init;
- sc->sc_rf_set_chan = urtw_8225v2_rf_set_chan;
- }
- sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
- sc->sc_sens = URTW_8225_RF_DEF_SENS;
- break;
- default:
- panic("unsupported RF chip %d\n", data & 0xff);
- /* never reach */
- }
-
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_get_txpwr(struct urtw_softc *sc)
-{
- int i, j;
- uint32_t data;
- usbd_status error;
-
- error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
- if (error != 0)
- goto fail;
- sc->sc_txpwr_cck_base = data & 0xf;
- sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
-
- for (i = 1, j = 0; i < 6; i += 2, j++) {
- error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
- if (error != 0)
- goto fail;
- sc->sc_txpwr_cck[i] = data & 0xf;
- sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
- sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
- sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
- }
- for (i = 1, j = 0; i < 4; i += 2, j++) {
- error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
- if (error != 0)
- goto fail;
- sc->sc_txpwr_cck[i + 6] = data & 0xf;
- sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
- sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
- sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
- }
- for (i = 1, j = 0; i < 4; i += 2, j++) {
- error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j, &data);
- if (error != 0)
- goto fail;
- sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
- sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
- sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
- sc->sc_txpwr_ofdm[i + 6 + 4 + 1] = (data & 0xf000) >> 12;
- }
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_get_macaddr(struct urtw_softc *sc)
-{
- uint32_t data;
- usbd_status error;
-
- error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
- if (error != 0)
- goto fail;
- sc->sc_bssid[0] = data & 0xff;
- sc->sc_bssid[1] = (data & 0xff00) >> 8;
- error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
- if (error != 0)
- goto fail;
- sc->sc_bssid[2] = data & 0xff;
- sc->sc_bssid[3] = (data & 0xff00) >> 8;
- error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
- if (error != 0)
- goto fail;
- sc->sc_bssid[4] = data & 0xff;
- sc->sc_bssid[5] = (data & 0xff00) >> 8;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
-{
-#define URTW_READCMD_LEN 3
- int addrlen, i;
- int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
- usbd_status error;
-
- /* NB: make sure the buffer is initialized */
- *data = 0;
-
- /* enable EPROM programming */
- urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
- DELAY(URTW_EPROM_DELAY);
-
- error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
- if (error != 0)
- goto fail;
- error = urtw_eprom_ck(sc);
- if (error != 0)
- goto fail;
- error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
- if (error != 0)
- goto fail;
- if (sc->sc_epromtype == URTW_EEPROM_93C56) {
- addrlen = 8;
- addrstr[0] = addr & (1 << 7);
- addrstr[1] = addr & (1 << 6);
- addrstr[2] = addr & (1 << 5);
- addrstr[3] = addr & (1 << 4);
- addrstr[4] = addr & (1 << 3);
- addrstr[5] = addr & (1 << 2);
- addrstr[6] = addr & (1 << 1);
- addrstr[7] = addr & (1 << 0);
- } else {
- addrlen=6;
- addrstr[0] = addr & (1 << 5);
- addrstr[1] = addr & (1 << 4);
- addrstr[2] = addr & (1 << 3);
- addrstr[3] = addr & (1 << 2);
- addrstr[4] = addr & (1 << 1);
- addrstr[5] = addr & (1 << 0);
- }
- error = urtw_eprom_sendbits(sc, addrstr, addrlen);
- if (error != 0)
- goto fail;
-
- error = urtw_eprom_writebit(sc, 0);
- if (error != 0)
- goto fail;
-
- for (i = 0; i < 16; i++) {
- error = urtw_eprom_ck(sc);
- if (error != 0)
- goto fail;
- error = urtw_eprom_readbit(sc, &data16);
- if (error != 0)
- goto fail;
-
- (*data) |= (data16 << (15 - i));
- }
-
- error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
- if (error != 0)
- goto fail;
- error = urtw_eprom_ck(sc);
- if (error != 0)
- goto fail;
-
- /* now disable EPROM programming */
- urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
-fail:
- return (error);
-#undef URTW_READCMD_LEN
-}
-
-static usbd_status
-urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
-{
- uint8_t data8;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
- *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
- DELAY(URTW_EPROM_DELAY);
-
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
-{
- int i = 0;
- usbd_status error = 0;
-
- for (i = 0; i < buflen; i++) {
- error = urtw_eprom_writebit(sc, buf[i]);
- if (error != 0)
- goto fail;
- error = urtw_eprom_ck(sc);
- if (error != 0)
- goto fail;
- }
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
-{
- uint8_t data;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_EPROM_CMD, &data);
- if (bit != 0)
- urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
- else
- urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
- DELAY(URTW_EPROM_DELAY);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_eprom_ck(struct urtw_softc *sc)
-{
- uint8_t data;
- usbd_status error;
-
- /* masking */
- urtw_read8_m(sc, URTW_EPROM_CMD, &data);
- urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
- DELAY(URTW_EPROM_DELAY);
- /* unmasking */
- urtw_read8_m(sc, URTW_EPROM_CMD, &data);
- urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
- DELAY(URTW_EPROM_DELAY);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_eprom_cs(struct urtw_softc *sc, int able)
-{
- uint8_t data;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_EPROM_CMD, &data);
- if (able == URTW_EPROM_ENABLE)
- urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
- else
- urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
- DELAY(URTW_EPROM_DELAY);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = URTW_8187_GETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint8_t));
-
- error = usbd_do_request(sc->sc_udev, &req, data);
- return (error);
-}
-
-static usbd_status
-urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = URTW_8187_GETREGS_REQ;
- USETW(req.wValue, val | 0xfe00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint8_t));
-
- error = usbd_do_request(sc->sc_udev, &req, data);
- return (error);
-}
-
-static usbd_status
-urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = URTW_8187_GETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint16_t));
-
- error = usbd_do_request(sc->sc_udev, &req, data);
- return (error);
-}
-
-static usbd_status
-urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = URTW_8187_GETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint32_t));
-
- error = usbd_do_request(sc->sc_udev, &req, data);
- return (error);
-}
-
-static usbd_status
-urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = URTW_8187_SETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint8_t));
-
- return (usbd_do_request(sc->sc_udev, &req, &data));
-}
-
-static usbd_status
-urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = URTW_8187_SETREGS_REQ;
- USETW(req.wValue, val | 0xfe00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint8_t));
-
- return (usbd_do_request(sc->sc_udev, &req, &data));
-}
-
-static usbd_status
-urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = URTW_8187_SETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint16_t));
-
- return (usbd_do_request(sc->sc_udev, &req, &data));
-}
-
-static usbd_status
-urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = URTW_8187_SETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint32_t));
-
- return (usbd_do_request(sc->sc_udev, &req, &data));
-}
-
-static int
-urtw_detach(device_t dev)
-{
- struct urtw_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- if (!device_is_attached(dev))
- return 0;
-
- urtw_stop(ifp, 1);
-
- callout_drain(&sc->sc_led_ch);
- callout_drain(&sc->sc_watchdog_ch);
- usb_rem_task(sc->sc_udev, &sc->sc_ledtask);
- usb_rem_task(sc->sc_udev, &sc->sc_ctxtask);
- usb_rem_task(sc->sc_udev, &sc->sc_task);
-
- /* abort and free xfers */
- urtw_free_tx_data_list(sc);
- urtw_free_rx_data_list(sc);
- urtw_close_pipes(sc);
-
- bpfdetach(ifp);
- ieee80211_ifdetach(ic);
- if_free(ifp);
- mtx_destroy(&sc->sc_mtx);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
-
- return (0);
-}
-
-static struct ieee80211vap *
-urtw_vap_create(struct ieee80211com *ic,
- const char name[IFNAMSIZ], int unit, int opmode, int flags,
- const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct urtw_vap *uvp;
- struct ieee80211vap *vap;
-
- if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
- return (NULL);
- uvp = (struct urtw_vap *) malloc(sizeof(struct urtw_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return (NULL);
- vap = &uvp->vap;
- /* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
-
- /* override state transition machine */
- uvp->newstate = vap->iv_newstate;
- vap->iv_newstate = urtw_newstate;
-
- /* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
- ic->ic_opmode = opmode;
- return (vap);
-}
-
-static void
-urtw_vap_delete(struct ieee80211vap *vap)
-{
- struct urtw_vap *uvp = URTW_VAP(vap);
-
- ieee80211_vap_detach(vap);
- free(uvp, M_80211_VAP);
-}
-
-static usbd_status
-urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
-{
- uint8_t data;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_EPROM_CMD, &data);
- data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
- data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
- urtw_write8_m(sc, URTW_EPROM_CMD, data);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
-{
- uint8_t data;
- usbd_status error;
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
- if (error)
- goto fail;
-
- urtw_read8_m(sc, URTW_CONFIG3, &data);
- urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
- urtw_write32_m(sc, URTW_ANAPARAM, val);
- urtw_read8_m(sc, URTW_CONFIG3, &data);
- urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
- if (error)
- goto fail;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
-{
- uint8_t data;
- usbd_status error;
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
- if (error)
- goto fail;
-
- urtw_read8_m(sc, URTW_CONFIG3, &data);
- urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
- urtw_write32_m(sc, URTW_ANAPARAM2, val);
- urtw_read8_m(sc, URTW_CONFIG3, &data);
- urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
- if (error)
- goto fail;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_intr_disable(struct urtw_softc *sc)
-{
- usbd_status error;
-
- urtw_write16_m(sc, URTW_INTR_MASK, 0);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_reset(struct urtw_softc *sc)
-{
- uint8_t data;
- usbd_status error;
-
- error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
- if (error)
- goto fail;
- error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
- if (error)
- goto fail;
-
- error = urtw_intr_disable(sc);
- if (error)
- goto fail;
- usbd_delay_ms(sc->sc_udev, 100);
-
- error = urtw_write8e(sc, 0x18, 0x10);
- if (error != 0)
- goto fail;
- error = urtw_write8e(sc, 0x18, 0x11);
- if (error != 0)
- goto fail;
- error = urtw_write8e(sc, 0x18, 0x00);
- if (error != 0)
- goto fail;
- usbd_delay_ms(sc->sc_udev, 100);
-
- urtw_read8_m(sc, URTW_CMD, &data);
- data = (data & 0x2) | URTW_CMD_RST;
- urtw_write8_m(sc, URTW_CMD, data);
- usbd_delay_ms(sc->sc_udev, 100);
-
- urtw_read8_m(sc, URTW_CMD, &data);
- if (data & URTW_CMD_RST) {
- device_printf(sc->sc_dev, "reset timeout\n");
- goto fail;
- }
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
- if (error)
- goto fail;
- usbd_delay_ms(sc->sc_udev, 100);
-
- error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
- if (error)
- goto fail;
- error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
- if (error)
- goto fail;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_led_on(struct urtw_softc *sc, int type)
-{
- usbd_status error;
-
- if (type == URTW_LED_GPIO) {
- switch (sc->sc_gpio_ledpin) {
- case URTW_LED_PIN_GPIO0:
- urtw_write8_m(sc, URTW_GPIO, 0x01);
- urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
- break;
- default:
- panic("unsupported LED PIN type 0x%x",
- sc->sc_gpio_ledpin);
- /* never reach */
- }
- } else {
- panic("unsupported LED type 0x%x", type);
- /* never reach */
- }
-
- sc->sc_gpio_ledon = 1;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_led_off(struct urtw_softc *sc, int type)
-{
- usbd_status error;
-
- if (type == URTW_LED_GPIO) {
- switch (sc->sc_gpio_ledpin) {
- case URTW_LED_PIN_GPIO0:
- urtw_write8_m(sc, URTW_GPIO, URTW_GPIO_DATA_MAGIC1);
- urtw_write8_m(sc,
- URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
- break;
- default:
- panic("unsupported LED PIN type 0x%x",
- sc->sc_gpio_ledpin);
- /* never reach */
- }
- } else {
- panic("unsupported LED type 0x%x", type);
- /* never reach */
- }
-
- sc->sc_gpio_ledon = 0;
-
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_led_mode0(struct urtw_softc *sc, int mode)
-{
-
- switch (mode) {
- case URTW_LED_CTL_POWER_ON:
- sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
- break;
- case URTW_LED_CTL_TX:
- if (sc->sc_gpio_ledinprogress == 1)
- return (0);
-
- sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
- sc->sc_gpio_blinktime = 2;
- break;
- case URTW_LED_CTL_LINK:
- sc->sc_gpio_ledstate = URTW_LED_ON;
- break;
- default:
- panic("unsupported LED mode 0x%x", mode);
- /* never reach */
- }
-
- switch (sc->sc_gpio_ledstate) {
- case URTW_LED_ON:
- if (sc->sc_gpio_ledinprogress != 0)
- break;
- urtw_led_on(sc, URTW_LED_GPIO);
- break;
- case URTW_LED_BLINK_NORMAL:
- if (sc->sc_gpio_ledinprogress != 0)
- break;
- sc->sc_gpio_ledinprogress = 1;
- sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
- URTW_LED_OFF : URTW_LED_ON;
- callout_reset(&sc->sc_led_ch, hz, urtw_ledtask, sc);
- break;
- case URTW_LED_POWER_ON_BLINK:
- urtw_led_on(sc, URTW_LED_GPIO);
- usbd_delay_ms(sc->sc_udev, 100);
- urtw_led_off(sc, URTW_LED_GPIO);
- break;
- default:
- panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
- /* never reach */
- }
- return (0);
-}
-
-static usbd_status
-urtw_led_mode1(struct urtw_softc *sc, int mode)
-{
-
- return (USBD_INVAL);
-}
-
-static usbd_status
-urtw_led_mode2(struct urtw_softc *sc, int mode)
-{
-
- return (USBD_INVAL);
-}
-
-static usbd_status
-urtw_led_mode3(struct urtw_softc *sc, int mode)
-{
-
- return (USBD_INVAL);
-}
-
-static usbd_status
-urtw_led_blink(struct urtw_softc *sc)
-{
- uint8_t ing = 0;
- usbd_status error;
-
- if (sc->sc_gpio_blinkstate == URTW_LED_ON)
- error = urtw_led_on(sc, URTW_LED_GPIO);
- else
- error = urtw_led_off(sc, URTW_LED_GPIO);
- sc->sc_gpio_blinktime--;
- if (sc->sc_gpio_blinktime == 0)
- ing = 1;
- else {
- if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
- sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
- sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
- ing = 1;
- }
- if (ing == 1) {
- if (sc->sc_gpio_ledstate == URTW_LED_ON &&
- sc->sc_gpio_ledon == 0)
- error = urtw_led_on(sc, URTW_LED_GPIO);
- else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
- sc->sc_gpio_ledon == 1)
- error = urtw_led_off(sc, URTW_LED_GPIO);
-
- sc->sc_gpio_blinktime = 0;
- sc->sc_gpio_ledinprogress = 0;
- return (0);
- }
-
- sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
- URTW_LED_ON : URTW_LED_OFF;
-
- switch (sc->sc_gpio_ledstate) {
- case URTW_LED_BLINK_NORMAL:
- callout_reset(&sc->sc_led_ch, hz, urtw_ledtask, sc);
- break;
- default:
- panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
- /* never reach */
- }
- return (0);
-}
-
-static void
-urtw_ledusbtask(void *arg)
-{
- struct urtw_softc *sc = arg;
-
- if (sc->sc_strategy != URTW_SW_LED_MODE0)
- panic("could not process a LED strategy 0x%x", sc->sc_strategy);
-
- urtw_led_blink(sc);
-}
-
-static void
-urtw_ledtask(void *arg)
-{
- struct urtw_softc *sc = arg;
-
- /*
- * NB: to change a status of the led we need at least a sleep so we
- * can't do it here
- */
- usb_add_task(sc->sc_udev, &sc->sc_ledtask, USB_TASKQ_DRIVER);
-}
-
-static usbd_status
-urtw_led_ctl(struct urtw_softc *sc, int mode)
-{
- usbd_status error = 0;
-
- switch (sc->sc_strategy) {
- case URTW_SW_LED_MODE0:
- error = urtw_led_mode0(sc, mode);
- break;
- case URTW_SW_LED_MODE1:
- error = urtw_led_mode1(sc, mode);
- break;
- case URTW_SW_LED_MODE2:
- error = urtw_led_mode2(sc, mode);
- break;
- case URTW_SW_LED_MODE3:
- error = urtw_led_mode3(sc, mode);
- break;
- default:
- panic("unsupported LED mode %d\n", sc->sc_strategy);
- /* never reach */
- }
-
- return (error);
-}
-
-static usbd_status
-urtw_update_msr(struct urtw_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint8_t data;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_MSR, &data);
- data &= ~URTW_MSR_LINK_MASK;
-
- if (sc->sc_state == IEEE80211_S_RUN) {
- switch (ic->ic_opmode) {
- case IEEE80211_M_STA:
- case IEEE80211_M_MONITOR:
- data |= URTW_MSR_LINK_STA;
- break;
- case IEEE80211_M_IBSS:
- data |= URTW_MSR_LINK_ADHOC;
- break;
- case IEEE80211_M_HOSTAP:
- data |= URTW_MSR_LINK_HOSTAP;
- break;
- default:
- panic("unsupported operation mode 0x%x\n",
- ic->ic_opmode);
- /* never reach */
- }
- } else
- data |= URTW_MSR_LINK_NONE;
-
- urtw_write8_m(sc, URTW_MSR, data);
-fail:
- return (error);
-}
-
-static uint16_t
-urtw_rate2rtl(int rate)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int i;
-
- for (i = 0; i < N(urtw_ratetable); i++) {
- if (rate == urtw_ratetable[i].reg)
- return urtw_ratetable[i].val;
- }
-
- return (3);
-#undef N
-}
-
-static uint16_t
-urtw_rtl2rate(int rate)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int i;
-
- for (i = 0; i < N(urtw_ratetable); i++) {
- if (rate == urtw_ratetable[i].val)
- return urtw_ratetable[i].reg;
- }
-
- return (0);
-#undef N
-}
-
-static usbd_status
-urtw_set_rate(struct urtw_softc *sc)
-{
- int i, basic_rate, min_rr_rate, max_rr_rate;
- uint16_t data;
- usbd_status error;
-
- basic_rate = urtw_rate2rtl(48);
- min_rr_rate = urtw_rate2rtl(12);
- max_rr_rate = urtw_rate2rtl(48);
-
- urtw_write8_m(sc, URTW_RESP_RATE,
- max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
- min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
-
- urtw_read16_m(sc, URTW_BRSR, &data);
- data &= ~URTW_BRSR_MBR_8185;
-
- for (i = 0; i <= basic_rate; i++)
- data |= (1 << i);
-
- urtw_write16_m(sc, URTW_BRSR, data);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_intr_enable(struct urtw_softc *sc)
-{
- usbd_status error;
-
- urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_adapter_start(struct urtw_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- usbd_status error;
-
- error = urtw_reset(sc);
- if (error)
- goto fail;
-
- urtw_write8_m(sc, URTW_ADDR_MAGIC1, 0);
- urtw_write8_m(sc, URTW_GPIO, 0);
-
- /* for led */
- urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
- error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
- if (error != 0)
- goto fail;
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
- if (error)
- goto fail;
- /* applying MAC address again. */
- urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_myaddr)[0]);
- urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_myaddr)[1] & 0xffff);
- error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
- if (error)
- goto fail;
-
- error = urtw_update_msr(sc);
- if (error)
- goto fail;
-
- urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
- urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
- urtw_write8_m(sc, URTW_RATE_FALLBACK, 0x81);
- error = urtw_set_rate(sc);
- if (error != 0)
- goto fail;
-
- error = sc->sc_rf_init(sc);
- if (error != 0)
- goto fail;
- if (sc->sc_rf_set_sens != NULL)
- sc->sc_rf_set_sens(sc, sc->sc_sens);
-
- /* XXX correct? to call write16 */
- urtw_write16_m(sc, URTW_PSR, 1);
- urtw_write16_m(sc, URTW_ADDR_MAGIC2, 0x10);
- urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
- urtw_write8_m(sc, URTW_ADDR_MAGIC3, 0x60);
- /* XXX correct? to call write16 */
- urtw_write16_m(sc, URTW_PSR, 0);
- urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
-
- error = urtw_intr_enable(sc);
- if (error != 0)
- goto fail;
-
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_rx_setconf(struct urtw_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t data;
- usbd_status error;
-
- urtw_read32_m(sc, URTW_RX, &data);
- data = data &~ URTW_RX_FILTER_MASK;
-#if 0
- data = data | URTW_RX_FILTER_CTL;
-#endif
- data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
- data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
-
- if (ic->ic_opmode == IEEE80211_M_MONITOR) {
- data = data | URTW_RX_FILTER_ICVERR;
- data = data | URTW_RX_FILTER_PWR;
- }
- if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
- data = data | URTW_RX_FILTER_CRCERR;
-
- if (ic->ic_opmode == IEEE80211_M_MONITOR ||
- (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
- data = data | URTW_RX_FILTER_ALLMAC;
- } else {
- data = data | URTW_RX_FILTER_NICMAC;
- data = data | URTW_RX_CHECK_BSSID;
- }
-
- data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
- data = data | URTW_RX_FIFO_THRESHOLD_NONE | URTW_RX_AUTORESETPHY;
- data = data &~ URTW_MAX_RX_DMA_MASK;
- data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
-
- urtw_write32_m(sc, URTW_RX, data);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_rx_enable(struct urtw_softc *sc)
-{
- int i;
- struct urtw_data *rxdata;
- uint8_t data;
- usbd_status error;
-
- /*
- * Start up the receive pipe.
- */
- for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) {
- rxdata = &sc->sc_rxdata[i];
-
- usbd_setup_xfer(rxdata->xfer, sc->sc_rxpipe, rxdata,
- rxdata->buf, MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
- urtw_rxeof);
- error = usbd_transfer(rxdata->xfer);
- if (error != USBD_IN_PROGRESS && error != 0) {
- device_printf(sc->sc_dev,
- "could not queue Rx transfer\n");
- goto fail;
- }
- }
-
- error = urtw_rx_setconf(sc);
- if (error != 0)
- goto fail;
-
- urtw_read8_m(sc, URTW_CMD, &data);
- urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_tx_enable(struct urtw_softc *sc)
-{
- uint8_t data8;
- uint32_t data;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_CW_CONF, &data8);
- data8 &= ~(URTW_CW_CONF_PERPACKET_CW | URTW_CW_CONF_PERPACKET_RETRY);
- urtw_write8_m(sc, URTW_CW_CONF, data8);
-
- urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
- data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
- data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
- data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
- urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
-
- urtw_read32_m(sc, URTW_TX_CONF, &data);
- data &= ~URTW_TX_LOOPBACK_MASK;
- data |= URTW_TX_LOOPBACK_NONE;
- data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
- data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
- data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
- data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
- data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
- data &= ~URTW_TX_SWPLCPLEN;
- data |= URTW_TX_NOICV;
- urtw_write32_m(sc, URTW_TX_CONF, data);
-
- urtw_read8_m(sc, URTW_CMD, &data8);
- urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
-fail:
- return (error);
-}
-
-static void
-urtw_init(void *arg)
-{
- int ret;
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- usbd_status error;
-
- urtw_stop(ifp, 0);
-
- error = urtw_adapter_start(sc);
- if (error != 0)
- goto fail;
-
- /* reset softc variables */
- sc->sc_txidx = sc->sc_tx_low_queued = sc->sc_tx_normal_queued = 0;
- sc->sc_txtimer = 0;
-
- if (!(sc->sc_flags & URTW_INIT_ONCE)) {
- error = usbd_set_config_no(sc->sc_udev, URTW_CONFIG_NO, 0);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "could not set configuration no\n");
- goto fail;
- }
- /* get the first interface handle */
- error = usbd_device2interface_handle(sc->sc_udev,
- URTW_IFACE_INDEX, &sc->sc_iface);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "could not get interface handle\n");
- goto fail;
- }
- error = urtw_open_pipes(sc);
- if (error != 0)
- goto fail;
- ret = urtw_alloc_rx_data_list(sc);
- if (error != 0)
- goto fail;
- ret = urtw_alloc_tx_data_list(sc);
- if (error != 0)
- goto fail;
- sc->sc_flags |= URTW_INIT_ONCE;
- }
-
- error = urtw_rx_enable(sc);
- if (error != 0)
- goto fail;
- error = urtw_tx_enable(sc);
- if (error != 0)
- goto fail;
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
-
- callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
-fail:
- return;
-}
-
-static void
-urtw_set_multi(void *arg)
-{
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
-
- if (!(ifp->if_flags & IFF_UP))
- return;
-
- /*
- * XXX don't know how to set a device. Lack of docs. Just try to set
- * IFF_ALLMULTI flag here.
- */
- IF_ADDR_LOCK(ifp);
- ifp->if_flags |= IFF_ALLMULTI;
- IF_ADDR_UNLOCK(ifp);
-}
-
-static int
-urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct urtw_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- mtx_lock(&Giant);
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if ((ifp->if_flags ^ sc->sc_if_flags) &
- (IFF_ALLMULTI | IFF_PROMISC))
- urtw_set_multi(sc);
- } else {
- urtw_init(ifp->if_softc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- urtw_stop(ifp, 1);
- }
- sc->sc_if_flags = ifp->if_flags;
- mtx_unlock(&Giant);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-static void
-urtw_start(struct ifnet *ifp)
-{
- struct urtw_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
- URTW_LOCK(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->sc_tx_low_queued >= URTW_TX_DATA_LIST_COUNT ||
- sc->sc_tx_normal_queued >= URTW_TX_DATA_LIST_COUNT) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
-
- ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
- m->m_pkthdr.rcvif = NULL;
- m = ieee80211_encap(ni, m);
- if (m == NULL) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- continue;
- }
-
- if (urtw_tx_start(sc, ni, m, URTW_PRIORITY_NORMAL) != 0) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- break;
- }
-
- sc->sc_txtimer = 5;
- }
- URTW_UNLOCK(sc);
-}
-
-static void
-urtw_txeof_low(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- struct urtw_data *data = priv;
- struct urtw_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- device_printf(sc->sc_dev, "could not transmit buffer: %s\n",
- usbd_errstr(status));
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_txpipe_low);
-
- ifp->if_oerrors++;
- return;
- }
-
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
- m = data->m;
- if (m != NULL && m->m_flags & M_TXCB) {
- ieee80211_process_callback(data->ni, m, 0); /* XXX status? */
- m_freem(m);
- data->m = NULL;
- }
-
- ieee80211_free_node(data->ni);
- data->ni = NULL;
-
- sc->sc_txtimer = 0;
- ifp->if_opackets++;
-
- URTW_LOCK(sc);
- sc->sc_tx_low_queued--;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- URTW_UNLOCK(sc);
-
- urtw_start(ifp);
-}
-
-static void
-urtw_txeof_normal(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- struct urtw_data *data = priv;
- struct urtw_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- device_printf(sc->sc_dev, "could not transmit buffer: %s\n",
- usbd_errstr(status));
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_txpipe_normal);
-
- ifp->if_oerrors++;
- return;
- }
-
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
- m = data->m;
- if (m != NULL && m->m_flags & M_TXCB) {
- ieee80211_process_callback(data->ni, m, 0); /* XXX status? */
- m_freem(m);
- data->m = NULL;
- }
-
- ieee80211_free_node(data->ni);
- data->ni = NULL;
-
- sc->sc_txtimer = 0;
- ifp->if_opackets++;
-
- URTW_LOCK(sc);
- sc->sc_tx_normal_queued--;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- URTW_UNLOCK(sc);
-
- urtw_start(ifp);
-}
-
-static int
-urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
- int prior)
-{
- int xferlen;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
- struct ieee80211_key *k;
- const struct ieee80211_txparam *tp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = ni->ni_vap;
- struct urtw_data *data;
- usbd_status error;
-
- URTW_ASSERT_LOCKED(sc);
-
- /*
- * Software crypto.
- */
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- device_printf(sc->sc_dev,
- "ieee80211_crypto_encap returns NULL.\n");
- /* XXX we don't expect the fragmented frames */
- m_freem(m0);
- return (ENOBUFS);
- }
-
- /* in case packet header moved, reset pointer */
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
-
- /* XXX Are variables correct? */
- tap->wt_flags = 0;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
- }
-
- xferlen = m0->m_pkthdr.len + 4 * 3;
- if((0 == xferlen % 64) || (0 == xferlen % 512))
- xferlen += 1;
-
- data = &sc->sc_txdata[sc->sc_txidx];
- sc->sc_txidx = (sc->sc_txidx + 1) % URTW_TX_DATA_LIST_COUNT;
-
- bzero(data->buf, URTW_TX_MAXSIZE);
- data->buf[0] = m0->m_pkthdr.len & 0xff;
- data->buf[1] = (m0->m_pkthdr.len & 0x0f00) >> 8;
- data->buf[1] |= (1 << 7);
-
- if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
- (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
- (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) &&
- (sc->sc_currate != 0))
- data->buf[2] |= 1;
- if ((m0->m_pkthdr.len > vap->iv_rtsthreshold) &&
- prior == URTW_PRIORITY_LOW)
- panic("TODO tx.");
- if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
- data->buf[2] |= (1 << 1);
- /* RTS rate - 10 means we use a basic rate. */
- data->buf[2] |= (urtw_rate2rtl(2) << 3);
- /*
- * XXX currently TX rate control depends on the rate value of
- * RX descriptor because I don't know how to we can control TX rate
- * in more smart way. Please fix me you find a thing.
- */
- data->buf[3] = sc->sc_currate;
- if (prior == URTW_PRIORITY_NORMAL) {
- tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
- if (IEEE80211_IS_MULTICAST(wh->i_addr1))
- data->buf[3] = urtw_rate2rtl(tp->mcastrate);
- else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
- data->buf[3] = urtw_rate2rtl(tp->ucastrate);
- }
- data->buf[8] = 3; /* CW minimum */
- data->buf[8] |= (7 << 4); /* CW maximum */
- data->buf[9] |= 11; /* retry limitation */
-
- m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)&data->buf[12]);
- data->ni = ni;
- data->m = m0;
-
- usbd_setup_xfer(data->xfer,
- (prior == URTW_PRIORITY_LOW) ? sc->sc_txpipe_low :
- sc->sc_txpipe_normal, data, data->buf, xferlen,
- USBD_FORCE_SHORT_XFER | USBD_NO_COPY, URTW_DATA_TIMEOUT,
- (prior == URTW_PRIORITY_LOW) ? urtw_txeof_low : urtw_txeof_normal);
- error = usbd_transfer(data->xfer);
- if (error != USBD_IN_PROGRESS && error != USBD_NORMAL_COMPLETION) {
- device_printf(sc->sc_dev, "could not send frame: %s\n",
- usbd_errstr(error));
- return EIO;
- }
-
- error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
- if (error != 0)
- device_printf(sc->sc_dev, "could not control LED (%d)\n", error);
-
- if (prior == URTW_PRIORITY_LOW)
- sc->sc_tx_low_queued++;
- else
- sc->sc_tx_normal_queued++;
-
- return (0);
-}
-
-static int
-urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
- const struct ieee80211_bpf_params *params)
-{
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct urtw_softc *sc = ifp->if_softc;
-
- /* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- m_freem(m);
- ieee80211_free_node(ni);
- return ENETDOWN;
- }
- URTW_LOCK(sc);
- if (sc->sc_tx_low_queued >= URTW_TX_DATA_LIST_COUNT ||
- sc->sc_tx_normal_queued >= URTW_TX_DATA_LIST_COUNT) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- m_freem(m);
- ieee80211_free_node(ni);
- URTW_UNLOCK(sc);
- return (ENOBUFS); /* XXX */
- }
-
- ifp->if_opackets++;
- if (urtw_tx_start(sc, ni, m, URTW_PRIORITY_LOW) != 0) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- URTW_UNLOCK(sc);
- return (EIO);
- }
-
- sc->sc_txtimer = 5;
- URTW_UNLOCK(sc);
- return (0);
-}
-
-static void
-urtw_scan_start(struct ieee80211com *ic)
-{
-
- /* XXX do nothing? */
-}
-
-static void
-urtw_scan_end(struct ieee80211com *ic)
-{
-
- /* XXX do nothing? */
-}
-
-static void
-urtw_set_channel(struct ieee80211com *ic)
-{
- struct urtw_softc *sc = ic->ic_ifp->if_softc;
- struct ifnet *ifp = sc->sc_ifp;
-
- /*
- * if the user set a channel explicitly using ifconfig(8) this function
- * can be called earlier than we're expected that in some cases the
- * initialization would be failed if setting a channel is called before
- * the init have done.
- */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- return;
-
- sc->sc_ctxarg = URTW_SET_CHANNEL;
- usb_add_task(sc->sc_udev, &sc->sc_ctxtask, USB_TASKQ_DRIVER);
-}
-
-static void
-urtw_update_mcast(struct ifnet *ifp)
-{
-
- /* XXX do nothing? */
-}
-
-static usbd_status
-urtw_8225_usb_init(struct urtw_softc *sc)
-{
- uint8_t data;
- usbd_status error;
-
- urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
- urtw_write8_m(sc, URTW_GPIO, 0);
- error = urtw_read8e(sc, 0x53, &data);
- if (error)
- goto fail;
- error = urtw_write8e(sc, 0x53, data | (1 << 7));
- if (error)
- goto fail;
- urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
- urtw_write8_m(sc, URTW_GPIO, 0x20);
- urtw_write8_m(sc, URTW_GP_ENABLE, 0);
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
-
- usbd_delay_ms(sc->sc_udev, 500);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8185_rf_pins_enable(struct urtw_softc *sc)
-{
- usbd_status error = 0;
-
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
-{
- uint32_t phyw;
- usbd_status error;
-
- phyw = ((data << 8) | (addr | 0x80));
- urtw_write8_m(sc, URTW_PHY_MAGIC4, ((phyw & 0xff000000) >> 24));
- urtw_write8_m(sc, URTW_PHY_MAGIC3, ((phyw & 0x00ff0000) >> 16));
- urtw_write8_m(sc, URTW_PHY_MAGIC2, ((phyw & 0x0000ff00) >> 8));
- urtw_write8_m(sc, URTW_PHY_MAGIC1, ((phyw & 0x000000ff)));
- usbd_delay_ms(sc->sc_udev, 1);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
-{
-
- data = data & 0xff;
- return urtw_8187_write_phy(sc, addr, data);
-}
-
-static usbd_status
-urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
-{
-
- data = data & 0xff;
- return urtw_8187_write_phy(sc, addr, data | 0x10000);
-}
-
-static usbd_status
-urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
-{
- usbd_status error;
-
- urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
- urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
- urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
- urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
-{
- int i, idx, set;
- uint8_t *cck_pwltable;
- uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
- uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
- uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
- usbd_status error;
-
- cck_pwrlvl_max = 11;
- ofdm_pwrlvl_max = 25; /* 12 -> 25 */
- ofdm_pwrlvl_min = 10;
-
- /* CCK power setting */
- cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
- idx = cck_pwrlvl % 6;
- set = cck_pwrlvl / 6;
- cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
- urtw_8225_txpwr_cck;
-
- urtw_write8_m(sc, URTW_TX_GAIN_CCK,
- urtw_8225_tx_gain_cck_ofdm[set] >> 1);
- for (i = 0; i < 8; i++) {
- urtw_8187_write_phy_cck(sc, 0x44 + i,
- cck_pwltable[idx * 8 + i]);
- }
- usbd_delay_ms(sc->sc_udev, 1);
-
- /* OFDM power setting */
- ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
- ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
- ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
-
- idx = ofdm_pwrlvl % 6;
- set = ofdm_pwrlvl / 6;
-
- error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
- if (error)
- goto fail;
- urtw_8187_write_phy_ofdm(sc, 2, 0x42);
- urtw_8187_write_phy_ofdm(sc, 6, 0);
- urtw_8187_write_phy_ofdm(sc, 8, 0);
-
- urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
- urtw_8225_tx_gain_cck_ofdm[set] >> 1);
- urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
- urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
- usbd_delay_ms(sc->sc_udev, 1);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
-{
- usbd_status error;
-
- urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
- usbd_delay_ms(sc->sc_udev, 1);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225_rf_init(struct urtw_softc *sc)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int i;
- uint16_t data;
- usbd_status error;
-
- error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
- if (error)
- goto fail;
-
- error = urtw_8225_usb_init(sc);
- if (error)
- goto fail;
-
- urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
- urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
- urtw_write16_m(sc, URTW_BRSR, 0xffff);
- urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
- if (error)
- goto fail;
- urtw_write8_m(sc, URTW_CONFIG3, 0x44);
- error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
- if (error)
- goto fail;
-
- error = urtw_8185_rf_pins_enable(sc);
- if (error)
- goto fail;
- usbd_delay_ms(sc->sc_udev, 1000);
-
- for (i = 0; i < N(urtw_8225_rf_part1); i++) {
- urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
- urtw_8225_rf_part1[i].val);
- usbd_delay_ms(sc->sc_udev, 1);
- }
- usbd_delay_ms(sc->sc_udev, 100);
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
- usbd_delay_ms(sc->sc_udev, 200);
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
- usbd_delay_ms(sc->sc_udev, 200);
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC3);
-
- for (i = 0; i < 95; i++) {
- urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
- urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225_rxgain[i]);
- }
-
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC4);
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC5);
-
- for (i = 0; i < 128; i++) {
- urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
- usbd_delay_ms(sc->sc_udev, 1);
- urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
- usbd_delay_ms(sc->sc_udev, 1);
- }
-
- for (i = 0; i < N(urtw_8225_rf_part2); i++) {
- urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
- urtw_8225_rf_part2[i].val);
- usbd_delay_ms(sc->sc_udev, 1);
- }
-
- error = urtw_8225_setgain(sc, 4);
- if (error)
- goto fail;
-
- for (i = 0; i < N(urtw_8225_rf_part3); i++) {
- urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
- urtw_8225_rf_part3[i].val);
- usbd_delay_ms(sc->sc_udev, 1);
- }
-
- urtw_write8_m(sc, URTW_ADDR_MAGIC4, 0x0d);
-
- error = urtw_8225_set_txpwrlvl(sc, 1);
- if (error)
- goto fail;
-
- urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
- usbd_delay_ms(sc->sc_udev, 1);
- urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
- usbd_delay_ms(sc->sc_udev, 1);
-
- /* TX ant A, 0x0 for B */
- error = urtw_8185_tx_antenna(sc, 0x3);
- if (error)
- goto fail;
- urtw_write32_m(sc, URTW_ADDR_MAGIC5, 0x3dc00002);
-
- error = urtw_8225_rf_set_chan(sc, 1);
-fail:
- return (error);
-#undef N
-}
-
-static usbd_status
-urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan)
-{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
- struct ieee80211_channel *c = ic->ic_curchan;
- usbd_status error;
-
- error = urtw_8225_set_txpwrlvl(sc, chan);
- if (error)
- goto fail;
- urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
- usbd_delay_ms(sc->sc_udev, 10);
-
- urtw_write8_m(sc, URTW_SIFS, 0x22);
-
- if (sc->sc_state == IEEE80211_S_ASSOC &&
- ic->ic_flags & IEEE80211_F_SHSLOT)
- urtw_write8_m(sc, URTW_SLOT, 0x9);
- else
- urtw_write8_m(sc, URTW_SLOT, 0x14);
-
- if (IEEE80211_IS_CHAN_G(c)) {
- /* for G */
- urtw_write8_m(sc, URTW_DIFS, 0x14);
- urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
- urtw_write8_m(sc, URTW_CW_VAL, 0x73);
- } else {
- /* for B */
- urtw_write8_m(sc, URTW_DIFS, 0x24);
- urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
- urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
- }
-
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225_rf_set_sens(struct urtw_softc *sc, int sens)
-{
- usbd_status error;
-
- if (sens < 0 || sens > 6)
- return -1;
-
- if (sens > 4)
- urtw_8225_write(sc,
- URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC1);
- else
- urtw_8225_write(sc,
- URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC2);
-
- sens = 6 - sens;
- error = urtw_8225_setgain(sc, sens);
- if (error)
- goto fail;
-
- urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[sens]);
-
-fail:
- return (error);
-}
-
-static void
-urtw_stop(struct ifnet *ifp, int disable)
-{
- struct urtw_softc *sc = ifp->if_softc;
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- callout_stop(&sc->sc_led_ch);
- callout_stop(&sc->sc_watchdog_ch);
-
- if (sc->sc_rxpipe != NULL)
- usbd_abort_pipe(sc->sc_rxpipe);
- if (sc->sc_txpipe_low != NULL)
- usbd_abort_pipe(sc->sc_txpipe_low);
- if (sc->sc_txpipe_normal != NULL)
- usbd_abort_pipe(sc->sc_txpipe_normal);
-}
-
-static int
-urtw_isbmode(uint16_t rate)
-{
-
- rate = urtw_rtl2rate(rate);
-
- return ((rate <= 22 && rate != 12 && rate != 18) ||
- rate == 44) ? (1) : (0);
-}
-
-static void
-urtw_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- int actlen, flen, len, nf, rssi;
- struct ieee80211_frame *wh;
- struct ieee80211_node *ni;
- struct mbuf *m, *mnew;
- struct urtw_data *data = priv;
- struct urtw_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint8_t *desc, quality, rate;
- usbd_status error;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_rxpipe);
- ifp->if_ierrors++;
- goto skip;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &actlen, NULL);
- if (actlen < URTW_MIN_RXBUFSZ) {
- ifp->if_ierrors++;
- goto skip;
- }
-
- /* 4 dword and 4 byte CRC */
- len = actlen - (4 * 4);
- desc = data->buf + len;
- flen = ((desc[1] & 0x0f) << 8) + (desc[0] & 0xff);
- if (flen > actlen) {
- ifp->if_ierrors++;
- goto skip;
- }
-
- rate = (desc[2] & 0xf0) >> 4;
- quality = desc[4] & 0xff;
- /* XXX correct? */
- rssi = (desc[6] & 0xfe) >> 1;
- if (!urtw_isbmode(rate)) {
- rssi = (rssi > 90) ? 90 : ((rssi < 25) ? 25 : rssi);
- rssi = ((90 - rssi) * 100) / 65;
- } else {
- rssi = (rssi > 90) ? 95 : ((rssi < 30) ? 30 : rssi);
- rssi = ((95 - rssi) * 100) / 65;
- }
-
- mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (mnew == NULL) {
- ifp->if_ierrors++;
- goto skip;
- }
-
- m = data->m;
- data->m = mnew;
- data->buf = mtod(mnew, uint8_t *);
-
- /* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = flen - 4;
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
-
- /* XXX Are variables correct? */
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wr_dbm_antsignal = (int8_t)rssi;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
- }
-
- wh = mtod(m, struct ieee80211_frame *);
- if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
- sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
- ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
- /* XXX correct? */
- nf = (quality > 64) ? 0 : ((64 - quality) * 100) / 64;
- /* send the frame to the 802.11 layer */
- if (ni != NULL) {
- (void) ieee80211_input(ni, m, rssi, -nf, 0);
- /* node is no longer needed */
- ieee80211_free_node(ni);
- } else
- (void) ieee80211_input_all(ic, m, rssi, -nf, 0);
-
-skip: /* setup a new transfer */
- usbd_setup_xfer(xfer, sc->sc_rxpipe, data, data->buf, MCLBYTES,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtw_rxeof);
- error = usbd_transfer(xfer);
- if (error != USBD_IN_PROGRESS && error != 0)
- device_printf(sc->sc_dev, "could not queue Rx transfer\n");
-}
-
-static int
-urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
-{
- struct urtw_vap *rvp = URTW_VAP(vap);
- struct ieee80211com *ic = vap->iv_ic;
- struct urtw_softc *sc = ic->ic_ifp->if_softc;
-
- DPRINTF(sc, URTW_DEBUG_STATE, "%s: %s -> %s\n", __func__,
- ieee80211_state_name[vap->iv_state],
- ieee80211_state_name[nstate]);
-
- /* do it in a process context */
- sc->sc_state = nstate;
- sc->sc_arg = arg;
-
- if (nstate == IEEE80211_S_INIT) {
- rvp->newstate(vap, nstate, arg);
- return (0);
- } else {
- usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
- return (EINPROGRESS);
- }
-}
-
-static usbd_status
-urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
-{
- uint8_t *gainp;
- usbd_status error;
-
- /* XXX for A? */
- gainp = urtw_8225v2_gain_bg;
- urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
- usbd_delay_ms(sc->sc_udev, 1);
- urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
- usbd_delay_ms(sc->sc_udev, 1);
- urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
- usbd_delay_ms(sc->sc_udev, 1);
- urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
- usbd_delay_ms(sc->sc_udev, 1);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
-{
- int i;
- uint8_t *cck_pwrtable;
- uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
- uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
- uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
- usbd_status error;
-
- /* CCK power setting */
- cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
- cck_pwrlvl += sc->sc_txpwr_cck_base;
- cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
- cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
- urtw_8225v2_txpwr_cck;
-
- for (i = 0; i < 8; i++)
- urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
-
- urtw_write8_m(sc, URTW_TX_GAIN_CCK,
- urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
- usbd_delay_ms(sc->sc_udev, 1);
-
- /* OFDM power setting */
- ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
- ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
- ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
- ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
-
- error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
- if (error)
- goto fail;
-
- urtw_8187_write_phy_ofdm(sc, 2, 0x42);
- urtw_8187_write_phy_ofdm(sc, 5, 0x0);
- urtw_8187_write_phy_ofdm(sc, 6, 0x40);
- urtw_8187_write_phy_ofdm(sc, 7, 0x0);
- urtw_8187_write_phy_ofdm(sc, 8, 0x40);
-
- urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
- urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
- usbd_delay_ms(sc->sc_udev, 1);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225v2_rf_init(struct urtw_softc *sc)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int i;
- uint16_t data;
- uint32_t data32;
- usbd_status error;
-
- error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
- if (error)
- goto fail;
-
- error = urtw_8225_usb_init(sc);
- if (error)
- goto fail;
-
- urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
- urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
- urtw_write16_m(sc, URTW_BRSR, 0xffff);
- urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
- if (error)
- goto fail;
- urtw_write8_m(sc, URTW_CONFIG3, 0x44);
- error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
- if (error)
- goto fail;
-
- error = urtw_8185_rf_pins_enable(sc);
- if (error)
- goto fail;
-
- usbd_delay_ms(sc->sc_udev, 500);
-
- for (i = 0; i < N(urtw_8225v2_rf_part1); i++) {
- urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
- urtw_8225v2_rf_part1[i].val);
- }
- usbd_delay_ms(sc->sc_udev, 50);
-
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1);
-
- for (i = 0; i < 95; i++) {
- urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
- urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
- urtw_8225v2_rxgain[i]);
- }
-
- urtw_8225_write(sc,
- URTW_8225_ADDR_3_MAGIC, URTW_8225_ADDR_3_DATA_MAGIC1);
- urtw_8225_write(sc,
- URTW_8225_ADDR_5_MAGIC, URTW_8225_ADDR_5_DATA_MAGIC1);
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC2);
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
- usbd_delay_ms(sc->sc_udev, 100);
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
- usbd_delay_ms(sc->sc_udev, 100);
-
- error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
- if (error != 0)
- goto fail;
- if (data32 != URTW_8225_ADDR_6_DATA_MAGIC1)
- device_printf(sc->sc_dev, "expect 0xe6!! (0x%x)\n", data32);
- if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2)) {
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
- usbd_delay_ms(sc->sc_udev, 100);
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
- usbd_delay_ms(sc->sc_udev, 50);
- error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
- if (error != 0)
- goto fail;
- if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2))
- device_printf(sc->sc_dev, "RF calibration failed\n");
- }
- usbd_delay_ms(sc->sc_udev, 100);
-
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC6);
- for (i = 0; i < 128; i++) {
- urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
- urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
- }
-
- for (i = 0; i < N(urtw_8225v2_rf_part2); i++) {
- urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
- urtw_8225v2_rf_part2[i].val);
- }
-
- error = urtw_8225v2_setgain(sc, 4);
- if (error)
- goto fail;
-
- for (i = 0; i < N(urtw_8225v2_rf_part3); i++) {
- urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
- urtw_8225v2_rf_part3[i].val);
- }
-
- urtw_write8_m(sc, URTW_ADDR_MAGIC4, 0x0d);
-
- error = urtw_8225v2_set_txpwrlvl(sc, 1);
- if (error)
- goto fail;
-
- urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
- urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
-
- /* TX ant A, 0x0 for B */
- error = urtw_8185_tx_antenna(sc, 0x3);
- if (error)
- goto fail;
- urtw_write32_m(sc, URTW_ADDR_MAGIC5, 0x3dc00002);
-
- error = urtw_8225_rf_set_chan(sc, 1);
-fail:
- return (error);
-#undef N
-}
-
-static usbd_status
-urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan)
-{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
- struct ieee80211_channel *c = ic->ic_curchan;
- usbd_status error;
-
- error = urtw_8225v2_set_txpwrlvl(sc, chan);
- if (error)
- goto fail;
-
- urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
- usbd_delay_ms(sc->sc_udev, 10);
-
- urtw_write8_m(sc, URTW_SIFS, 0x22);
-
- if(sc->sc_state == IEEE80211_S_ASSOC &&
- ic->ic_flags & IEEE80211_F_SHSLOT)
- urtw_write8_m(sc, URTW_SLOT, 0x9);
- else
- urtw_write8_m(sc, URTW_SLOT, 0x14);
-
- if (IEEE80211_IS_CHAN_G(c)) {
- /* for G */
- urtw_write8_m(sc, URTW_DIFS, 0x14);
- urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
- urtw_write8_m(sc, URTW_CW_VAL, 0x73);
- } else {
- /* for B */
- urtw_write8_m(sc, URTW_DIFS, 0x24);
- urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
- urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
- }
-
-fail:
- return (error);
-}
-
-static void
-urtw_ctxtask(void *arg)
-{
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t data;
- usbd_status error;
-
- switch (sc->sc_ctxarg) {
- case URTW_SET_CHANNEL:
- /*
- * during changing th channel we need to temporarily be disable
- * TX.
- */
- urtw_read32_m(sc, URTW_TX_CONF, &data);
- data &= ~URTW_TX_LOOPBACK_MASK;
- urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
- error = sc->sc_rf_set_chan(sc,
- ieee80211_chan2ieee(ic, ic->ic_curchan));
- if (error != 0)
- goto fail;
- usbd_delay_ms(sc->sc_udev, 10);
- urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_NONE);
- break;
- default:
- panic("unknown argument.\n");
- }
-
-fail:
- if (error != 0)
- device_printf(sc->sc_dev, "could not change the channel\n");
- return;
-}
-
-static void
-urtw_task(void *arg)
-{
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ieee80211_node *ni = vap->iv_bss;
- struct urtw_vap *uvp = URTW_VAP(vap);
- usbd_status error = 0;
-
- switch (sc->sc_state) {
- case IEEE80211_S_RUN:
- /* setting bssid. */
- urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
- urtw_write16_m(sc, URTW_BSSID + 4,
- ((uint16_t *)ni->ni_bssid)[2]);
- urtw_update_msr(sc);
- /* XXX maybe the below would be incorrect. */
- urtw_write16_m(sc, URTW_ATIM_WND, 2);
- urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
- urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
- urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
- error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
- if (error != 0)
- device_printf(sc->sc_dev,
- "could not control LED (%d)\n", error);
- break;
- default:
- break;
- }
-
-fail:
- if (error != 0)
- printf("error duing processing RUN state.");
-
- IEEE80211_LOCK(ic);
- uvp->newstate(vap, sc->sc_state, sc->sc_arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
- IEEE80211_UNLOCK(ic);
-}
-
-static void
-urtw_watchdog(void *arg)
-{
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
-
- if (sc->sc_txtimer > 0) {
- if (--sc->sc_txtimer == 0) {
- device_printf(sc->sc_dev, "device timeout\n");
- ifp->if_oerrors++;
- return;
- }
- callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
- }
-}
-
-static device_method_t urtw_methods[] = {
- DEVMETHOD(device_probe, urtw_match),
- DEVMETHOD(device_attach, urtw_attach),
- DEVMETHOD(device_detach, urtw_detach),
- { 0, 0 }
-};
-static driver_t urtw_driver = {
- "urtw",
- urtw_methods,
- sizeof(struct urtw_softc)
-};
-static devclass_t urtw_devclass;
-
-DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(urtw, wlan, 1, 1, 1);
-MODULE_DEPEND(urtw, usb, 1, 1, 1);
diff --git a/sys/legacy/dev/usb/if_urtwreg.h b/sys/legacy/dev/usb/if_urtwreg.h
deleted file mode 100644
index 7a9baa3..0000000
--- a/sys/legacy/dev/usb/if_urtwreg.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define URTW_CONFIG_NO 1
-#define URTW_IFACE_INDEX 0
-
-/* for 8187 */
-#define URTW_MAC0 0x0000 /* 1 byte */
-#define URTW_MAC1 0x0001 /* 1 byte */
-#define URTW_MAC2 0x0002 /* 1 byte */
-#define URTW_MAC3 0x0003 /* 1 byte */
-#define URTW_MAC4 0x0004 /* 1 byte */
-#define URTW_MAC5 0x0005 /* 1 byte */
-#define URTW_BRSR 0x002c /* 2 byte */
-#define URTW_BRSR_MBR_8185 (0x0fff)
-#define URTW_BSSID 0x002e /* 6 byte */
-#define URTW_RESP_RATE 0x0034 /* 1 byte */
-#define URTW_RESP_MAX_RATE_SHIFT (4)
-#define URTW_RESP_MIN_RATE_SHIFT (0)
-#define URTW_EIFS 0x0035 /* 1 byte */
-#define URTW_INTR_MASK 0x003c /* 2 byte */
-#define URTW_CMD 0x0037 /* 1 byte */
-#define URTW_CMD_TX_ENABLE (0x4)
-#define URTW_CMD_RX_ENABLE (0x8)
-#define URTW_CMD_RST (0x10)
-#define URTW_TX_CONF 0x0040 /* 4 byte */
-#define URTW_TX_LOOPBACK_SHIFT (17)
-#define URTW_TX_LOOPBACK_NONE (0 << URTW_TX_LOOPBACK_SHIFT)
-#define URTW_TX_LOOPBACK_MAC (1 << URTW_TX_LOOPBACK_SHIFT)
-#define URTW_TX_LOOPBACK_BASEBAND (2 << URTW_TX_LOOPBACK_SHIFT)
-#define URTW_TX_LOOPBACK_CONTINUE (3 << URTW_TX_LOOPBACK_SHIFT)
-#define URTW_TX_LOOPBACK_MASK (0x60000)
-#define URTW_TX_DPRETRY_MASK (0xff00)
-#define URTW_TX_RTSRETRY_MASK (0xff)
-#define URTW_TX_DPRETRY_SHIFT (0)
-#define URTW_TX_RTSRETRY_SHIFT (8)
-#define URTW_TX_NOCRC (0x10000)
-#define URTW_TX_MXDMA_MASK (0xe00000)
-#define URTW_TX_MXDMA_1024 (6 << URTW_TX_MXDMA_SHIFT)
-#define URTW_TX_MXDMA_2048 (7 << URTW_TX_MXDMA_SHIFT)
-#define URTW_TX_MXDMA_SHIFT (21)
-#define URTW_TX_CWMIN (1 << 31)
-#define URTW_TX_DISCW (1 << 20)
-#define URTW_TX_SWPLCPLEN (1 << 24)
-#define URTW_TX_NOICV (0x80000)
-#define URTW_RX 0x0044 /* 4 byte */
-#define URTW_RX_9356SEL (1 << 6)
-#define URTW_RX_FILTER_MASK \
- (URTW_RX_FILTER_ALLMAC | URTW_RX_FILTER_NICMAC | URTW_RX_FILTER_MCAST | \
- URTW_RX_FILTER_BCAST | URTW_RX_FILTER_CRCERR | URTW_RX_FILTER_ICVERR | \
- URTW_RX_FILTER_DATA | URTW_RX_FILTER_CTL | URTW_RX_FILTER_MNG | \
- (1 << 21) | \
- URTW_RX_FILTER_PWR | URTW_RX_CHECK_BSSID)
-#define URTW_RX_FILTER_ALLMAC (0x00000001)
-#define URTW_RX_FILTER_NICMAC (0x00000002)
-#define URTW_RX_FILTER_MCAST (0x00000004)
-#define URTW_RX_FILTER_BCAST (0x00000008)
-#define URTW_RX_FILTER_CRCERR (0x00000020)
-#define URTW_RX_FILTER_ICVERR (0x00001000)
-#define URTW_RX_FILTER_DATA (0x00040000)
-#define URTW_RX_FILTER_CTL (0x00080000)
-#define URTW_RX_FILTER_MNG (0x00100000)
-#define URTW_RX_FILTER_PWR (0x00400000)
-#define URTW_RX_CHECK_BSSID (0x00800000)
-#define URTW_RX_FIFO_THRESHOLD_MASK ((1 << 13) | (1 << 14) | (1 << 15))
-#define URTW_RX_FIFO_THRESHOLD_SHIFT (13)
-#define URTW_RX_FIFO_THRESHOLD_128 (3)
-#define URTW_RX_FIFO_THRESHOLD_256 (4)
-#define URTW_RX_FIFO_THRESHOLD_512 (5)
-#define URTW_RX_FIFO_THRESHOLD_1024 (6)
-#define URTW_RX_FIFO_THRESHOLD_NONE (7 << URTW_RX_FIFO_THRESHOLD_SHIFT)
-#define URTW_RX_AUTORESETPHY (1 << URTW_RX_AUTORESETPHY_SHIFT)
-#define URTW_RX_AUTORESETPHY_SHIFT (28)
-#define URTW_MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
-#define URTW_MAX_RX_DMA_2048 (7 << URTW_MAX_RX_DMA_SHIFT)
-#define URTW_MAX_RX_DMA_1024 (6)
-#define URTW_MAX_RX_DMA_SHIFT (10)
-#define URTW_RCR_ONLYERLPKT (1 << 31)
-#define URTW_INT_TIMEOUT 0x0048 /* 4 byte */
-#define URTW_EPROM_CMD 0x0050 /* 1 byte */
-#define URTW_EPROM_CMD_NORMAL (0x0)
-#define URTW_EPROM_CMD_NORMAL_MODE \
- (URTW_EPROM_CMD_NORMAL << URTW_EPROM_CMD_SHIFT)
-#define URTW_EPROM_CMD_LOAD (0x1)
-#define URTW_EPROM_CMD_PROGRAM (0x2)
-#define URTW_EPROM_CMD_PROGRAM_MODE \
- (URTW_EPROM_CMD_PROGRAM << URTW_EPROM_CMD_SHIFT)
-#define URTW_EPROM_CMD_CONFIG (0x3)
-#define URTW_EPROM_CMD_SHIFT (6)
-#define URTW_EPROM_CMD_MASK ((1 << 7) | (1 << 6))
-#define URTW_EPROM_READBIT (0x1)
-#define URTW_EPROM_WRITEBIT (0x2)
-#define URTW_EPROM_CK (0x4)
-#define URTW_EPROM_CS (0x8)
-#define URTW_CONFIG2 0x0053
-#define URTW_ANAPARAM 0x0054 /* 4 byte */
-#define URTW_8225_ANAPARAM_ON (0xa0000a59)
-#define URTW_MSR 0x0058 /* 1 byte */
-#define URTW_MSR_LINK_MASK ((1 << 2) | (1 << 3))
-#define URTW_MSR_LINK_SHIFT (2)
-#define URTW_MSR_LINK_NONE (0 << URTW_MSR_LINK_SHIFT)
-#define URTW_MSR_LINK_ADHOC (1 << URTW_MSR_LINK_SHIFT)
-#define URTW_MSR_LINK_STA (2 << URTW_MSR_LINK_SHIFT)
-#define URTW_MSR_LINK_HOSTAP (3 << URTW_MSR_LINK_SHIFT)
-#define URTW_CONFIG3 0x0059 /* 1 byte */
-#define URTW_CONFIG3_ANAPARAM_WRITE (0x40)
-#define URTW_CONFIG3_ANAPARAM_W_SHIFT (6)
-#define URTW_ADDR_MAGIC4 0x005b /* 1 byte */
-#define URTW_PSR 0x005e /* 1 byte */
-#define URTW_ANAPARAM2 0x0060 /* 4 byte */
-#define URTW_8225_ANAPARAM2_ON (0x860c7312)
-#define URTW_BEACON_INTERVAL 0x0070 /* 2 byte */
-#define URTW_ATIM_WND 0x0072 /* 2 byte */
-#define URTW_BEACON_INTERVAL_TIME 0x0074 /* 2 byte */
-#define URTW_ATIM_TR_ITV 0x0076 /* 2 byte */
-#define URTW_PHY_MAGIC1 0x007c /* 1 byte */
-#define URTW_PHY_MAGIC2 0x007d /* 1 byte */
-#define URTW_PHY_MAGIC3 0x007e /* 1 byte */
-#define URTW_PHY_MAGIC4 0x007f /* 1 byte */
-#define URTW_RF_PINS_OUTPUT 0x0080 /* 2 byte */
-#define URTW_RF_PINS_OUTPUT_MAGIC1 (0x3a0)
-#define URTW_BB_HOST_BANG_CLK (1 << 1)
-#define URTW_BB_HOST_BANG_EN (1 << 2)
-#define URTW_BB_HOST_BANG_RW (1 << 3)
-#define URTW_RF_PINS_ENABLE 0x0082 /* 2 byte */
-#define URTW_RF_PINS_SELECT 0x0084 /* 2 byte */
-#define URTW_ADDR_MAGIC1 0x0085 /* broken? */
-#define URTW_RF_PINS_INPUT 0x0086 /* 2 byte */
-#define URTW_RF_PINS_MAGIC1 (0xfff3)
-#define URTW_RF_PINS_MAGIC2 (0xfff0)
-#define URTW_RF_PINS_MAGIC3 (0x0007)
-#define URTW_RF_PINS_MAGIC4 (0xf)
-#define URTW_RF_PINS_MAGIC5 (0x0080)
-#define URTW_RF_PARA 0x0088 /* 4 byte */
-#define URTW_RF_TIMING 0x008c /* 4 byte */
-#define URTW_GP_ENABLE 0x0090 /* 1 byte */
-#define URTW_GP_ENABLE_DATA_MAGIC1 (0x1)
-#define URTW_GPIO 0x0091 /* 1 byte */
-#define URTW_GPIO_DATA_MAGIC1 (0x1)
-#define URTW_ADDR_MAGIC5 0x0094 /* 4 byte */
-#define URTW_TX_AGC_CTL 0x009c /* 1 byte */
-#define URTW_TX_AGC_CTL_PERPACKET_GAIN (0x1)
-#define URTW_TX_AGC_CTL_PERPACKET_ANTSEL (0x2)
-#define URTW_TX_AGC_CTL_FEEDBACK_ANT (0x4)
-#define URTW_TX_GAIN_CCK 0x009d /* 1 byte */
-#define URTW_TX_GAIN_OFDM 0x009e /* 1 byte */
-#define URTW_TX_ANTENNA 0x009f /* 1 byte */
-#define URTW_WPA_CONFIG 0x00b0 /* 1 byte */
-#define URTW_SIFS 0x00b4 /* 1 byte */
-#define URTW_DIFS 0x00b5 /* 1 byte */
-#define URTW_SLOT 0x00b6 /* 1 byte */
-#define URTW_CW_CONF 0x00bc /* 1 byte */
-#define URTW_CW_CONF_PERPACKET_RETRY (0x2)
-#define URTW_CW_CONF_PERPACKET_CW (0x1)
-#define URTW_CW_VAL 0x00bd /* 1 byte */
-#define URTW_RATE_FALLBACK 0x00be /* 1 byte */
-#define URTW_TALLY_SEL 0x00fc /* 1 byte */
-#define URTW_ADDR_MAGIC2 0x00fe /* 2 byte */
-#define URTW_ADDR_MAGIC3 0x00ff /* 1 byte */
-
-/* for 8225 */
-#define URTW_8225_ADDR_0_MAGIC 0x0
-#define URTW_8225_ADDR_0_DATA_MAGIC1 (0x1b7)
-#define URTW_8225_ADDR_0_DATA_MAGIC2 (0x0b7)
-#define URTW_8225_ADDR_0_DATA_MAGIC3 (0x127)
-#define URTW_8225_ADDR_0_DATA_MAGIC4 (0x027)
-#define URTW_8225_ADDR_0_DATA_MAGIC5 (0x22f)
-#define URTW_8225_ADDR_0_DATA_MAGIC6 (0x2bf)
-#define URTW_8225_ADDR_1_MAGIC 0x1
-#define URTW_8225_ADDR_2_MAGIC 0x2
-#define URTW_8225_ADDR_2_DATA_MAGIC1 (0xc4d)
-#define URTW_8225_ADDR_2_DATA_MAGIC2 (0x44d)
-#define URTW_8225_ADDR_3_MAGIC 0x3
-#define URTW_8225_ADDR_3_DATA_MAGIC1 (0x2)
-#define URTW_8225_ADDR_5_MAGIC 0x5
-#define URTW_8225_ADDR_5_DATA_MAGIC1 (0x4)
-#define URTW_8225_ADDR_6_MAGIC 0x6
-#define URTW_8225_ADDR_6_DATA_MAGIC1 (0xe6)
-#define URTW_8225_ADDR_6_DATA_MAGIC2 (0x80)
-#define URTW_8225_ADDR_7_MAGIC 0x7
-#define URTW_8225_ADDR_8_MAGIC 0x8
-#define URTW_8225_ADDR_8_DATA_MAGIC1 (0x588)
-#define URTW_8225_ADDR_9_MAGIC 0x9
-#define URTW_8225_ADDR_9_DATA_MAGIC1 (0x700)
-#define URTW_8225_ADDR_C_MAGIC 0xc
-#define URTW_8225_ADDR_C_DATA_MAGIC1 (0x850)
-#define URTW_8225_ADDR_C_DATA_MAGIC2 (0x050)
-
-/* for EEPROM */
-#define URTW_EPROM_TXPW_BASE 0x05
-#define URTW_EPROM_RFCHIPID 0x06
-#define URTW_EPROM_RFCHIPID_RTL8225U (5)
-#define URTW_EPROM_MACADDR 0x07
-#define URTW_EPROM_TXPW0 0x16
-#define URTW_EPROM_TXPW2 0x1b
-#define URTW_EPROM_TXPW1 0x3d
-#define URTW_EPROM_SWREV 0x3f
-#define URTW_EPROM_CID_MASK (0xff)
-#define URTW_EPROM_CID_RSVD0 (0x00)
-#define URTW_EPROM_CID_RSVD1 (0xff)
-#define URTW_EPROM_CID_ALPHA0 (0x01)
-#define URTW_EPROM_CID_SERCOMM_PS (0x02)
-#define URTW_EPROM_CID_HW_LED (0x03)
-
-/* LED */
-#define URTW_CID_DEFAULT 0
-#define URTW_CID_8187_ALPHA0 1
-#define URTW_CID_8187_SERCOMM_PS 2
-#define URTW_CID_8187_HW_LED 3
-#define URTW_SW_LED_MODE0 0
-#define URTW_SW_LED_MODE1 1
-#define URTW_SW_LED_MODE2 2
-#define URTW_SW_LED_MODE3 3
-#define URTW_HW_LED 4
-#define URTW_LED_CTL_POWER_ON 0
-#define URTW_LED_CTL_LINK 2
-#define URTW_LED_CTL_TX 4
-#define URTW_LED_PIN_GPIO0 0
-#define URTW_LED_PIN_LED0 1
-#define URTW_LED_PIN_LED1 2
-#define URTW_LED_UNKNOWN 0
-#define URTW_LED_ON 1
-#define URTW_LED_OFF 2
-#define URTW_LED_BLINK_NORMAL 3
-#define URTW_LED_BLINK_SLOWLY 4
-#define URTW_LED_POWER_ON_BLINK 5
-#define URTW_LED_SCAN_BLINK 6
-#define URTW_LED_NO_LINK_BLINK 7
-#define URTW_LED_BLINK_CM3 8
-
-/* for extra area */
-#define URTW_EPROM_DISABLE 0
-#define URTW_EPROM_ENABLE 1
-#define URTW_EPROM_DELAY 10
-#define URTW_8187_GETREGS_REQ 5
-#define URTW_8187_SETREGS_REQ 5
-#define URTW_8225_RF_MAX_SENS 6
-#define URTW_8225_RF_DEF_SENS 4
-#define URTW_DEFAULT_RTS_RETRY 7
-#define URTW_DEFAULT_TX_RETRY 7
-#define URTW_DEFAULT_RTS_THRESHOLD 2342U
diff --git a/sys/legacy/dev/usb/if_urtwvar.h b/sys/legacy/dev/usb/if_urtwvar.h
deleted file mode 100644
index 77c09ef..0000000
--- a/sys/legacy/dev/usb/if_urtwvar.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* XXX no definition at net80211? */
-#define URTW_MAX_CHANNELS 15
-
-struct urtw_data {
- struct urtw_softc *sc;
- usbd_xfer_handle xfer;
- uint8_t *buf;
- struct mbuf *m;
- struct ieee80211_node *ni; /* NB: tx only */
-};
-
-/* XXX not correct.. */
-#define URTW_MIN_RXBUFSZ \
- (sizeof(struct ieee80211_frame_min))
-
-#define URTW_RX_DATA_LIST_COUNT 1
-#define URTW_TX_DATA_LIST_COUNT 16
-#define URTW_RX_MAXSIZE 0x9c4
-#define URTW_TX_MAXSIZE 0x9c4
-
-struct urtw_rx_radiotap_header {
- struct ieee80211_radiotap_header wr_ihdr;
- uint8_t wr_flags;
- uint16_t wr_chan_freq;
- uint16_t wr_chan_flags;
- int8_t wr_dbm_antsignal;
-} __packed;
-
-#define URTW_RX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL))
-
-struct urtw_tx_radiotap_header {
- struct ieee80211_radiotap_header wt_ihdr;
- uint8_t wt_flags;
- uint16_t wt_chan_freq;
- uint16_t wt_chan_flags;
-} __packed;
-
-#define URTW_TX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL))
-
-struct urtw_vap {
- struct ieee80211vap vap;
- int (*newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
-};
-#define URTW_VAP(vap) ((struct urtw_vap *)(vap))
-
-struct urtw_softc {
- struct ifnet *sc_ifp;
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
- struct mtx sc_mtx;
-
- int sc_debug;
- int sc_if_flags;
- int sc_flags;
-#define URTW_INIT_ONCE (1 << 1)
- struct usb_task sc_task;
- struct usb_task sc_ctxtask;
- int sc_ctxarg;
-#define URTW_SET_CHANNEL 1
- enum ieee80211_state sc_state;
- int sc_arg;
- int (*sc_newstate)(struct ieee80211com *,
- enum ieee80211_state, int);
-
- int sc_epromtype;
-#define URTW_EEPROM_93C46 0
-#define URTW_EEPROM_93C56 1
- uint8_t sc_crcmon;
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
-
- /* for RF */
- usbd_status (*sc_rf_init)(struct urtw_softc *);
- usbd_status (*sc_rf_set_chan)(struct urtw_softc *,
- int);
- usbd_status (*sc_rf_set_sens)(struct urtw_softc *,
- int);
- uint8_t sc_rfchip;
- uint32_t sc_max_sens;
- uint32_t sc_sens;
- /* for LED */
- struct callout sc_led_ch;
- struct usb_task sc_ledtask;
- uint8_t sc_psr;
- uint8_t sc_strategy;
-#define URTW_LED_GPIO 1
- uint8_t sc_gpio_ledon;
- uint8_t sc_gpio_ledinprogress;
- uint8_t sc_gpio_ledstate;
- uint8_t sc_gpio_ledpin;
- uint8_t sc_gpio_blinktime;
- uint8_t sc_gpio_blinkstate;
- /* RX/TX */
- usbd_pipe_handle sc_rxpipe;
- usbd_pipe_handle sc_txpipe_low;
- usbd_pipe_handle sc_txpipe_normal;
-#define URTW_PRIORITY_LOW 0
-#define URTW_PRIORITY_NORMAL 1
-#define URTW_DATA_TIMEOUT 10000 /* 10 sec */
- struct urtw_data sc_rxdata[URTW_RX_DATA_LIST_COUNT];
- struct urtw_data sc_txdata[URTW_TX_DATA_LIST_COUNT];
- uint32_t sc_tx_low_queued;
- uint32_t sc_tx_normal_queued;
- uint32_t sc_txidx;
- uint8_t sc_rts_retry;
- uint8_t sc_tx_retry;
- uint8_t sc_preamble_mode;
-#define URTW_PREAMBLE_MODE_SHORT 1
-#define URTW_PREAMBLE_MODE_LONG 2
- struct callout sc_watchdog_ch;
- int sc_txtimer;
- int sc_currate;
- /* TX power */
- uint8_t sc_txpwr_cck[URTW_MAX_CHANNELS];
- uint8_t sc_txpwr_cck_base;
- uint8_t sc_txpwr_ofdm[URTW_MAX_CHANNELS];
- uint8_t sc_txpwr_ofdm_base;
-
- struct urtw_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
- struct urtw_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
-};
-
-#define URTW_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
-#define URTW_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
-#define URTW_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
diff --git a/sys/legacy/dev/usb/ohci.c b/sys/legacy/dev/usb/ohci.c
deleted file mode 100644
index efa6e7e..0000000
--- a/sys/legacy/dev/usb/ohci.c
+++ /dev/null
@@ -1,3638 +0,0 @@
-/* $NetBSD: ohci.c,v 1.138 2003/02/08 03:32:50 ichiro Exp $ */
-
-/* Also, already ported:
- * $NetBSD: ohci.c,v 1.140 2003/05/13 04:42:00 gson Exp $
- * $NetBSD: ohci.c,v 1.141 2003/09/10 20:08:29 mycroft Exp $
- * $NetBSD: ohci.c,v 1.142 2003/10/11 03:04:26 toshii Exp $
- * $NetBSD: ohci.c,v 1.143 2003/10/18 04:50:35 simonb Exp $
- * $NetBSD: ohci.c,v 1.144 2003/11/23 19:18:06 augustss Exp $
- * $NetBSD: ohci.c,v 1.145 2003/11/23 19:20:25 augustss Exp $
- * $NetBSD: ohci.c,v 1.146 2003/12/29 08:17:10 toshii Exp $
- * $NetBSD: ohci.c,v 1.147 2004/06/22 07:20:35 mycroft Exp $
- * $NetBSD: ohci.c,v 1.148 2004/06/22 18:27:46 mycroft Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * USB Open Host Controller driver.
- *
- * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html
- * USB spec: http://www.usb.org/developers/docs/usbspec.zip
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/endian.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
-#include <machine/cpu.h>
-#endif
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-#include <machine/endian.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ohcireg.h>
-#include <dev/usb/ohcivar.h>
-
-#define delay(d) DELAY(d)
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (ohcidebug) printf x
-#define DPRINTFN(n,x) if (ohcidebug>(n)) printf x
-int ohcidebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ohci, CTLFLAG_RW, 0, "USB ohci");
-SYSCTL_INT(_hw_usb_ohci, OID_AUTO, debug, CTLFLAG_RW,
- &ohcidebug, 0, "ohci debug level");
-#define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct ohci_pipe;
-
-static ohci_soft_ed_t *ohci_alloc_sed(ohci_softc_t *);
-static void ohci_free_sed(ohci_softc_t *, ohci_soft_ed_t *);
-
-static ohci_soft_td_t *ohci_alloc_std(ohci_softc_t *);
-static void ohci_free_std(ohci_softc_t *, ohci_soft_td_t *);
-
-static ohci_soft_itd_t *ohci_alloc_sitd(ohci_softc_t *);
-static void ohci_free_sitd(ohci_softc_t *,ohci_soft_itd_t *);
-
-#if 0
-static void ohci_free_std_chain(ohci_softc_t *, ohci_soft_td_t *,
- ohci_soft_td_t *);
-#endif
-static usbd_status ohci_alloc_std_chain(struct ohci_pipe *,
- ohci_softc_t *, int, int, usbd_xfer_handle,
- ohci_soft_td_t *, ohci_soft_td_t **);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static void ohci_shutdown(void *v);
-static void ohci_power(int, void *);
-#endif
-static usbd_status ohci_open(usbd_pipe_handle);
-static void ohci_poll(struct usbd_bus *);
-static void ohci_softintr(void *);
-static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle);
-static void ohci_add_done(ohci_softc_t *, ohci_physaddr_t);
-static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle);
-
-static usbd_status ohci_device_request(usbd_xfer_handle xfer);
-static void ohci_add_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
-static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
-static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *);
-static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *);
-static ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t);
-static void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *);
-static void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *);
-static ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t);
-
-static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe);
-static void ohci_device_isoc_enter(usbd_xfer_handle);
-
-static usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
-static void ohci_freem(struct usbd_bus *, usb_dma_t *);
-
-static usbd_xfer_handle ohci_allocx(struct usbd_bus *);
-static void ohci_freex(struct usbd_bus *, usbd_xfer_handle);
-
-static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle);
-static usbd_status ohci_root_ctrl_start(usbd_xfer_handle);
-static void ohci_root_ctrl_abort(usbd_xfer_handle);
-static void ohci_root_ctrl_close(usbd_pipe_handle);
-static void ohci_root_ctrl_done(usbd_xfer_handle);
-
-static usbd_status ohci_root_intr_transfer(usbd_xfer_handle);
-static usbd_status ohci_root_intr_start(usbd_xfer_handle);
-static void ohci_root_intr_abort(usbd_xfer_handle);
-static void ohci_root_intr_close(usbd_pipe_handle);
-static void ohci_root_intr_done(usbd_xfer_handle);
-
-static usbd_status ohci_device_ctrl_transfer(usbd_xfer_handle);
-static usbd_status ohci_device_ctrl_start(usbd_xfer_handle);
-static void ohci_device_ctrl_abort(usbd_xfer_handle);
-static void ohci_device_ctrl_close(usbd_pipe_handle);
-static void ohci_device_ctrl_done(usbd_xfer_handle);
-
-static usbd_status ohci_device_bulk_transfer(usbd_xfer_handle);
-static usbd_status ohci_device_bulk_start(usbd_xfer_handle);
-static void ohci_device_bulk_abort(usbd_xfer_handle);
-static void ohci_device_bulk_close(usbd_pipe_handle);
-static void ohci_device_bulk_done(usbd_xfer_handle);
-
-static usbd_status ohci_device_intr_transfer(usbd_xfer_handle);
-static usbd_status ohci_device_intr_start(usbd_xfer_handle);
-static void ohci_device_intr_abort(usbd_xfer_handle);
-static void ohci_device_intr_close(usbd_pipe_handle);
-static void ohci_device_intr_done(usbd_xfer_handle);
-
-static usbd_status ohci_device_isoc_transfer(usbd_xfer_handle);
-static usbd_status ohci_device_isoc_start(usbd_xfer_handle);
-static void ohci_device_isoc_abort(usbd_xfer_handle);
-static void ohci_device_isoc_close(usbd_pipe_handle);
-static void ohci_device_isoc_done(usbd_xfer_handle);
-
-static usbd_status ohci_device_setintr(ohci_softc_t *sc,
- struct ohci_pipe *pipe, int ival);
-static usbd_status ohci_device_intr_insert(ohci_softc_t *sc,
- usbd_xfer_handle xfer);
-
-static int ohci_str(usb_string_descriptor_t *, int, const char *);
-
-static void ohci_timeout(void *);
-static void ohci_timeout_task(void *);
-static void ohci_rhsc_able(ohci_softc_t *, int);
-static void ohci_rhsc_enable(void *);
-
-static void ohci_close_pipe(usbd_pipe_handle, ohci_soft_ed_t *);
-static void ohci_abort_xfer(usbd_xfer_handle, usbd_status);
-
-static void ohci_device_clear_toggle(usbd_pipe_handle pipe);
-static void ohci_noop(usbd_pipe_handle pipe);
-
-static usbd_status ohci_controller_init(ohci_softc_t *sc);
-
-#ifdef USB_DEBUG
-static void ohci_dumpregs(ohci_softc_t *);
-static void ohci_dump_tds(ohci_soft_td_t *);
-static void ohci_dump_td(ohci_soft_td_t *);
-static void ohci_dump_ed(ohci_soft_ed_t *);
-static void ohci_dump_itd(ohci_soft_itd_t *);
-static void ohci_dump_itds(ohci_soft_itd_t *);
-#endif
-
-#define OBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
- BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
-#define OWRITE1(sc, r, x) \
- do { OBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
-#define OWRITE2(sc, r, x) \
- do { OBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
-#define OWRITE4(sc, r, x) \
- do { OBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
-#define OREAD1(sc, r) (OBARR(sc), bus_space_read_1((sc)->iot, (sc)->ioh, (r)))
-#define OREAD2(sc, r) (OBARR(sc), bus_space_read_2((sc)->iot, (sc)->ioh, (r)))
-#define OREAD4(sc, r) (OBARR(sc), bus_space_read_4((sc)->iot, (sc)->ioh, (r)))
-
-/* Reverse the bits in a value 0 .. 31 */
-static u_int8_t revbits[OHCI_NO_INTRS] =
- { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c,
- 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e,
- 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d,
- 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f };
-
-struct ohci_pipe {
- struct usbd_pipe pipe;
- ohci_soft_ed_t *sed;
- u_int32_t aborting;
- union {
- ohci_soft_td_t *td;
- ohci_soft_itd_t *itd;
- } tail;
- /* Info needed for different pipe kinds. */
- union {
- /* Control pipe */
- struct {
- usb_dma_t reqdma;
- u_int length;
- ohci_soft_td_t *setup, *data, *stat;
- } ctl;
- /* Interrupt pipe */
- struct {
- int nslots;
- int pos;
- } intr;
- /* Bulk pipe */
- struct {
- u_int length;
- int isread;
- } bulk;
- /* Iso pipe */
- struct iso {
- int next, inuse;
- } iso;
- } u;
-};
-
-#define OHCI_INTR_ENDPT 1
-
-static struct usbd_bus_methods ohci_bus_methods = {
- ohci_open,
- ohci_softintr,
- ohci_poll,
- ohci_allocm,
- ohci_freem,
- ohci_allocx,
- ohci_freex,
-};
-
-static struct usbd_pipe_methods ohci_root_ctrl_methods = {
- ohci_root_ctrl_transfer,
- ohci_root_ctrl_start,
- ohci_root_ctrl_abort,
- ohci_root_ctrl_close,
- ohci_noop,
- ohci_root_ctrl_done,
-};
-
-static struct usbd_pipe_methods ohci_root_intr_methods = {
- ohci_root_intr_transfer,
- ohci_root_intr_start,
- ohci_root_intr_abort,
- ohci_root_intr_close,
- ohci_noop,
- ohci_root_intr_done,
-};
-
-static struct usbd_pipe_methods ohci_device_ctrl_methods = {
- ohci_device_ctrl_transfer,
- ohci_device_ctrl_start,
- ohci_device_ctrl_abort,
- ohci_device_ctrl_close,
- ohci_noop,
- ohci_device_ctrl_done,
-};
-
-static struct usbd_pipe_methods ohci_device_intr_methods = {
- ohci_device_intr_transfer,
- ohci_device_intr_start,
- ohci_device_intr_abort,
- ohci_device_intr_close,
- ohci_device_clear_toggle,
- ohci_device_intr_done,
-};
-
-static struct usbd_pipe_methods ohci_device_bulk_methods = {
- ohci_device_bulk_transfer,
- ohci_device_bulk_start,
- ohci_device_bulk_abort,
- ohci_device_bulk_close,
- ohci_device_clear_toggle,
- ohci_device_bulk_done,
-};
-
-static struct usbd_pipe_methods ohci_device_isoc_methods = {
- ohci_device_isoc_transfer,
- ohci_device_isoc_start,
- ohci_device_isoc_abort,
- ohci_device_isoc_close,
- ohci_noop,
- ohci_device_isoc_done,
-};
-
-int
-ohci_detach(struct ohci_softc *sc, int flags)
-{
- int i, rv = 0;
-
- sc->sc_dying = 1;
- callout_stop(&sc->sc_tmo_rhsc);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- powerhook_disestablish(sc->sc_powerhook);
- shutdownhook_disestablish(sc->sc_shutdownhook);
-#endif
-
- OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
-
- usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
-
- for (i = 0; i < OHCI_NO_EDS; i++)
- ohci_free_sed(sc, sc->sc_eds[i]);
- ohci_free_sed(sc, sc->sc_isoc_head);
- ohci_free_sed(sc, sc->sc_bulk_head);
- ohci_free_sed(sc, sc->sc_ctrl_head);
- usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
-
- return (rv);
-}
-
-ohci_soft_ed_t *
-ohci_alloc_sed(ohci_softc_t *sc)
-{
- ohci_soft_ed_t *sed;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
-
- if (sc->sc_freeeds == NULL) {
- DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK,
- OHCI_ED_ALIGN, &dma);
- if (err)
- return (NULL);
- for(i = 0; i < OHCI_SED_CHUNK; i++) {
- offs = i * OHCI_SED_SIZE;
- sed = KERNADDR(&dma, offs);
- sed->physaddr = DMAADDR(&dma, offs);
- sed->next = sc->sc_freeeds;
- sc->sc_freeeds = sed;
- }
- }
- sed = sc->sc_freeeds;
- sc->sc_freeeds = sed->next;
- memset(&sed->ed, 0, sizeof(ohci_ed_t));
- sed->next = 0;
- return (sed);
-}
-
-void
-ohci_free_sed(ohci_softc_t *sc, ohci_soft_ed_t *sed)
-{
- sed->next = sc->sc_freeeds;
- sc->sc_freeeds = sed;
-}
-
-ohci_soft_td_t *
-ohci_alloc_std(ohci_softc_t *sc)
-{
- ohci_soft_td_t *std;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
- int s;
-
- if (sc->sc_freetds == NULL) {
- DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK,
- OHCI_TD_ALIGN, &dma);
- if (err)
- return (NULL);
- s = splusb();
- for(i = 0; i < OHCI_STD_CHUNK; i++) {
- offs = i * OHCI_STD_SIZE;
- std = KERNADDR(&dma, offs);
- std->physaddr = DMAADDR(&dma, offs);
- std->nexttd = sc->sc_freetds;
- sc->sc_freetds = std;
- }
- splx(s);
- }
-
- s = splusb();
- std = sc->sc_freetds;
- sc->sc_freetds = std->nexttd;
- memset(&std->td, 0, sizeof(ohci_td_t));
- std->nexttd = NULL;
- std->xfer = NULL;
- ohci_hash_add_td(sc, std);
- splx(s);
-
- return (std);
-}
-
-void
-ohci_free_std(ohci_softc_t *sc, ohci_soft_td_t *std)
-{
- int s;
-
- s = splusb();
- ohci_hash_rem_td(sc, std);
- std->nexttd = sc->sc_freetds;
- sc->sc_freetds = std;
- splx(s);
-}
-
-usbd_status
-ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc,
- int alen, int rd, usbd_xfer_handle xfer,
- ohci_soft_td_t *sp, ohci_soft_td_t **ep)
-{
- ohci_soft_td_t *next, *cur, *end;
- ohci_physaddr_t dataphys, physend;
- u_int32_t tdflags;
- int offset = 0;
- int len, maxp, curlen, curlen2, seg, segoff;
- struct usb_dma_mapping *dma = &xfer->dmamap;
- u_int16_t flags = xfer->flags;
-
- DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen));
-
- len = alen;
- cur = sp;
- end = NULL;
-
- maxp = UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize);
- tdflags = htole32(
- (rd ? OHCI_TD_IN : OHCI_TD_OUT) |
- (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) |
- OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_SET_DI(6));
-
- seg = 0;
- segoff = 0;
- while (len > 0) {
- next = ohci_alloc_std(sc);
- if (next == NULL)
- goto nomem;
-
- /*
- * The OHCI hardware can handle at most one 4k crossing.
- * The OHCI spec says: If during the data transfer the buffer
- * address contained in the HC's working copy of
- * CurrentBufferPointer crosses a 4K boundary, the upper 20
- * bits of Buffer End are copied to the working value of
- * CurrentBufferPointer causing the next buffer address to
- * be the 0th byte in the same 4K page that contains the
- * last byte of the buffer (the 4K boundary crossing may
- * occur within a data packet transfer.)
- */
- KASSERT(seg < dma->nsegs, ("ohci_alloc_std_chain: overrun"));
- dataphys = dma->segs[seg].ds_addr + segoff;
- curlen = dma->segs[seg].ds_len - segoff;
- if (curlen > len)
- curlen = len;
- physend = dataphys + curlen - 1;
- if (OHCI_PAGE(dataphys) != OHCI_PAGE(physend)) {
- /* Truncate to two OHCI pages if there are more. */
- if (curlen > 2 * OHCI_PAGE_SIZE -
- OHCI_PAGE_OFFSET(dataphys))
- curlen = 2 * OHCI_PAGE_SIZE -
- OHCI_PAGE_OFFSET(dataphys);
- if (curlen < len)
- curlen -= curlen % maxp;
- physend = dataphys + curlen - 1;
- } else if (OHCI_PAGE_OFFSET(physend + 1) == 0 && curlen < len &&
- curlen + segoff == dma->segs[seg].ds_len) {
- /* We can possibly include another segment. */
- KASSERT(seg + 1 < dma->nsegs,
- ("ohci_alloc_std_chain: overrun2"));
- seg++;
-
- /* Determine how much of the second segment to use. */
- curlen2 = dma->segs[seg].ds_len;
- if (curlen + curlen2 > len)
- curlen2 = len - curlen;
- if (OHCI_PAGE(dma->segs[seg].ds_addr) !=
- OHCI_PAGE(dma->segs[seg].ds_addr + curlen2 - 1))
- curlen2 = OHCI_PAGE_SIZE -
- OHCI_PAGE_OFFSET(dma->segs[seg].ds_addr);
- if (curlen + curlen2 < len)
- curlen2 -= (curlen + curlen2) % maxp;
-
- if (curlen2 > 0) {
- /* We can include a second segment */
- segoff = curlen2;
- physend = dma->segs[seg].ds_addr + curlen2 - 1;
- curlen += curlen2;
- } else {
- /* Second segment not usable now. */
- seg--;
- segoff += curlen;
- }
- } else {
- /* Simple case where there is just one OHCI page. */
- segoff += curlen;
- }
- if (curlen == 0 && len != 0) {
- /*
- * A maxp length packet would need to be split.
- * This shouldn't be possible if PAGE_SIZE >= 4k
- * and the buffer is contiguous in virtual memory.
- */
- panic("ohci_alloc_std_chain: XXX need to copy");
- }
- if (segoff >= dma->segs[seg].ds_len) {
- KASSERT(segoff == dma->segs[seg].ds_len,
- ("ohci_alloc_std_chain: overlap"));
- seg++;
- segoff = 0;
- }
- DPRINTFN(4,("ohci_alloc_std_chain: dataphys=0x%08x "
- "len=%d curlen=%d\n",
- dataphys, len, curlen));
- len -= curlen;
-
- cur->td.td_flags = tdflags;
- cur->td.td_cbp = htole32(dataphys);
- cur->nexttd = next;
- cur->td.td_nexttd = htole32(next->physaddr);
- cur->td.td_be = htole32(physend);
- cur->len = curlen;
- cur->flags = OHCI_ADD_LEN;
- cur->xfer = xfer;
- DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n",
- dataphys, dataphys + curlen - 1));
- if (len < 0)
- panic("Length went negative: %d curlen %d dma %p offset %08x", len, curlen, dma, (int)0);
-
- DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n"));
- offset += curlen;
- end = cur;
- cur = next;
- }
- if (((flags & USBD_FORCE_SHORT_XFER) || alen == 0) &&
- alen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize) == 0) {
- /* Force a 0 length transfer at the end. */
- next = ohci_alloc_std(sc);
- if (next == NULL)
- goto nomem;
-
- cur->td.td_flags = tdflags;
- cur->td.td_cbp = 0; /* indicate 0 length packet */
- cur->nexttd = next;
- cur->td.td_nexttd = htole32(next->physaddr);
- cur->td.td_be = ~0;
- cur->len = 0;
- cur->flags = 0;
- cur->xfer = xfer;
- DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n"));
- end = cur;
- }
- *ep = end;
-
- return (USBD_NORMAL_COMPLETION);
-
- nomem:
- /* XXX free chain */
- return (USBD_NOMEM);
-}
-
-#if 0
-static void
-ohci_free_std_chain(ohci_softc_t *sc, ohci_soft_td_t *std,
- ohci_soft_td_t *stdend)
-{
- ohci_soft_td_t *p;
-
- for (; std != stdend; std = p) {
- p = std->nexttd;
- ohci_free_std(sc, std);
- }
-}
-#endif
-
-ohci_soft_itd_t *
-ohci_alloc_sitd(ohci_softc_t *sc)
-{
- ohci_soft_itd_t *sitd;
- usbd_status err;
- int i, s, offs;
- usb_dma_t dma;
-
- if (sc->sc_freeitds == NULL) {
- DPRINTFN(2, ("ohci_alloc_sitd: allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * OHCI_SITD_CHUNK,
- OHCI_ITD_ALIGN, &dma);
- if (err)
- return (NULL);
- s = splusb();
- for(i = 0; i < OHCI_SITD_CHUNK; i++) {
- offs = i * OHCI_SITD_SIZE;
- sitd = KERNADDR(&dma, offs);
- sitd->physaddr = DMAADDR(&dma, offs);
- sitd->nextitd = sc->sc_freeitds;
- sc->sc_freeitds = sitd;
- }
- splx(s);
- }
-
- s = splusb();
- sitd = sc->sc_freeitds;
- sc->sc_freeitds = sitd->nextitd;
- memset(&sitd->itd, 0, sizeof(ohci_itd_t));
- sitd->nextitd = NULL;
- sitd->xfer = NULL;
- ohci_hash_add_itd(sc, sitd);
- splx(s);
-
-#ifdef DIAGNOSTIC
- sitd->isdone = 0;
-#endif
-
- return (sitd);
-}
-
-void
-ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
-{
- int s;
-
- DPRINTFN(10,("ohci_free_sitd: sitd=%p\n", sitd));
-
-#ifdef DIAGNOSTIC
- if (!sitd->isdone) {
- panic("ohci_free_sitd: sitd=%p not done", sitd);
- return;
- }
- /* Warn double free */
- sitd->isdone = 0;
-#endif
-
- s = splusb();
- ohci_hash_rem_itd(sc, sitd);
- sitd->nextitd = sc->sc_freeitds;
- sc->sc_freeitds = sitd;
- splx(s);
-}
-
-usbd_status
-ohci_init(ohci_softc_t *sc)
-{
- ohci_soft_ed_t *sed, *psed;
- usbd_status err;
- int i;
- u_int32_t rev;
-
- DPRINTF(("ohci_init: start\n"));
- printf("%s:", device_get_nameunit(sc->sc_bus.bdev));
- rev = OREAD4(sc, OHCI_REVISION);
- printf(" OHCI version %d.%d%s\n", OHCI_REV_HI(rev), OHCI_REV_LO(rev),
- OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
-
- if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) {
- printf("%s: unsupported OHCI revision\n",
- device_get_nameunit(sc->sc_bus.bdev));
- sc->sc_bus.usbrev = USBREV_UNKNOWN;
- return (USBD_INVAL);
- }
- sc->sc_bus.usbrev = USBREV_1_0;
-
- for (i = 0; i < OHCI_HASH_SIZE; i++)
- LIST_INIT(&sc->sc_hash_tds[i]);
- for (i = 0; i < OHCI_HASH_SIZE; i++)
- LIST_INIT(&sc->sc_hash_itds[i]);
-
- STAILQ_INIT(&sc->sc_free_xfers);
-
- /* XXX determine alignment by R/W */
- /* Allocate the HCCA area. */
- err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
- OHCI_HCCA_ALIGN, &sc->sc_hccadma);
- if (err)
- return (err);
- sc->sc_hcca = KERNADDR(&sc->sc_hccadma, 0);
- memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE);
-
- sc->sc_eintrs = OHCI_NORMAL_INTRS;
-
- /* Allocate dummy ED that starts the control list. */
- sc->sc_ctrl_head = ohci_alloc_sed(sc);
- if (sc->sc_ctrl_head == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- sc->sc_ctrl_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
-
- /* Allocate dummy ED that starts the bulk list. */
- sc->sc_bulk_head = ohci_alloc_sed(sc);
- if (sc->sc_bulk_head == NULL) {
- err = USBD_NOMEM;
- goto bad2;
- }
- sc->sc_bulk_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
-
- /* Allocate dummy ED that starts the isochronous list. */
- sc->sc_isoc_head = ohci_alloc_sed(sc);
- if (sc->sc_isoc_head == NULL) {
- err = USBD_NOMEM;
- goto bad3;
- }
- sc->sc_isoc_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
-
- /* Allocate all the dummy EDs that make up the interrupt tree. */
- for (i = 0; i < OHCI_NO_EDS; i++) {
- sed = ohci_alloc_sed(sc);
- if (sed == NULL) {
- while (--i >= 0)
- ohci_free_sed(sc, sc->sc_eds[i]);
- err = USBD_NOMEM;
- goto bad4;
- }
- /* All ED fields are set to 0. */
- sc->sc_eds[i] = sed;
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
- if (i != 0)
- psed = sc->sc_eds[(i-1) / 2];
- else
- psed= sc->sc_isoc_head;
- sed->next = psed;
- sed->ed.ed_nexted = htole32(psed->physaddr);
- }
- /*
- * Fill HCCA interrupt table. The bit reversal is to get
- * the tree set up properly to spread the interrupts.
- */
- for (i = 0; i < OHCI_NO_INTRS; i++)
- sc->sc_hcca->hcca_interrupt_table[revbits[i]] =
- htole32(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr);
-
-#ifdef USB_DEBUG
- if (ohcidebug > 15) {
- for (i = 0; i < OHCI_NO_EDS; i++) {
- printf("ed#%d ", i);
- ohci_dump_ed(sc->sc_eds[i]);
- }
- printf("iso ");
- ohci_dump_ed(sc->sc_isoc_head);
- }
-#endif
-
- err = ohci_controller_init(sc);
- if (err != USBD_NORMAL_COMPLETION)
- goto bad5;
-
- /* Set up the bus struct. */
- sc->sc_bus.methods = &ohci_bus_methods;
- sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- sc->sc_powerhook = powerhook_establish(ohci_power, sc);
- sc->sc_shutdownhook = shutdownhook_establish(ohci_shutdown, sc);
-#endif
-
- callout_init(&sc->sc_tmo_rhsc, 0);
-
- return (USBD_NORMAL_COMPLETION);
-
- bad5:
- for (i = 0; i < OHCI_NO_EDS; i++)
- ohci_free_sed(sc, sc->sc_eds[i]);
- bad4:
- ohci_free_sed(sc, sc->sc_isoc_head);
- bad3:
- ohci_free_sed(sc, sc->sc_bulk_head);
- bad2:
- ohci_free_sed(sc, sc->sc_ctrl_head);
- bad1:
- usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
- return (err);
-}
-
-static usbd_status
-ohci_controller_init(ohci_softc_t *sc)
-{
- int i;
- u_int32_t ctl, ival, hcr, fm, per, desca;
-
- /* Determine in what context we are running. */
- ctl = OREAD4(sc, OHCI_CONTROL);
- if (ctl & OHCI_IR) {
- /* SMM active, request change */
- DPRINTF(("ohci_init: SMM active, request owner change\n"));
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_OCR);
- for (i = 0; i < 100 && (ctl & OHCI_IR); i++) {
- usb_delay_ms(&sc->sc_bus, 1);
- ctl = OREAD4(sc, OHCI_CONTROL);
- }
- if (ctl & OHCI_IR) {
- printf("%s: SMM does not respond, resetting\n",
- device_get_nameunit(sc->sc_bus.bdev));
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
- goto reset;
- }
-#if 0
-/* Don't bother trying to reuse the BIOS init, we'll reset it anyway. */
- } else if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_RESET) {
- /* BIOS started controller. */
- DPRINTF(("ohci_init: BIOS active\n"));
- if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_OPERATIONAL) {
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_OPERATIONAL);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
- }
-#endif
- } else {
- DPRINTF(("ohci_init: cold started\n"));
- reset:
- /* Controller was cold started. */
- usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
- }
-
- /*
- * This reset should not be necessary according to the OHCI spec, but
- * without it some controllers do not start.
- */
- DPRINTF(("%s: resetting\n", device_get_nameunit(sc->sc_bus.bdev)));
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
- usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
-
- /* We now own the host controller and the bus has been reset. */
- ival = OHCI_GET_IVAL(OREAD4(sc, OHCI_FM_INTERVAL));
-
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_HCR); /* Reset HC */
- /* Nominal time for a reset is 10 us. */
- for (i = 0; i < 10; i++) {
- delay(10);
- hcr = OREAD4(sc, OHCI_COMMAND_STATUS) & OHCI_HCR;
- if (!hcr)
- break;
- }
- if (hcr) {
- printf("%s: reset timeout\n", device_get_nameunit(sc->sc_bus.bdev));
- return (USBD_IOERROR);
- }
-#ifdef USB_DEBUG
- if (ohcidebug > 15)
- ohci_dumpregs(sc);
-#endif
-
- /* The controller is now in SUSPEND state, we have 2ms to finish. */
-
- /* Set up HC registers. */
- OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
- OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
- OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
- /* disable all interrupts and then switch on all desired interrupts */
- OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
- OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
- /* switch on desired functional features */
- ctl = OREAD4(sc, OHCI_CONTROL);
- ctl &= ~(OHCI_CBSR_MASK | OHCI_LES | OHCI_HCFS_MASK | OHCI_IR);
- ctl |= OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE |
- OHCI_RATIO_1_4 | OHCI_HCFS_OPERATIONAL;
- /* And finally start it! */
- OWRITE4(sc, OHCI_CONTROL, ctl);
-
- /*
- * The controller is now OPERATIONAL. Set a some final
- * registers that should be set earlier, but that the
- * controller ignores when in the SUSPEND state.
- */
- fm = (OREAD4(sc, OHCI_FM_INTERVAL) & OHCI_FIT) ^ OHCI_FIT;
- fm |= OHCI_FSMPS(ival) | ival;
- OWRITE4(sc, OHCI_FM_INTERVAL, fm);
- per = OHCI_PERIODIC(ival); /* 90% periodic */
- OWRITE4(sc, OHCI_PERIODIC_START, per);
-
- /* Fiddle the No OverCurrent Protection bit to avoid chip bug. */
- desca = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
- OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca | OHCI_NOCP);
- OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */
- usb_delay_ms(&sc->sc_bus, OHCI_ENABLE_POWER_DELAY);
- OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca);
-
- /*
- * The AMD756 requires a delay before re-reading the register,
- * otherwise it will occasionally report 0 ports.
- */
- sc->sc_noport = 0;
- for (i = 0; i < 10 && sc->sc_noport == 0; i++) {
- usb_delay_ms(&sc->sc_bus, OHCI_READ_DESC_DELAY);
- sc->sc_noport = OHCI_GET_NDP(OREAD4(sc, OHCI_RH_DESCRIPTOR_A));
- }
-
-#ifdef USB_DEBUG
- if (ohcidebug > 5)
- ohci_dumpregs(sc);
-#endif
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-ohci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
-{
- return (usb_allocmem(bus, size, 0, dma));
-}
-
-void
-ohci_freem(struct usbd_bus *bus, usb_dma_t *dma)
-{
- usb_freemem(bus, dma);
-}
-
-usbd_xfer_handle
-ohci_allocx(struct usbd_bus *bus)
-{
- struct ohci_softc *sc = (struct ohci_softc *)bus;
- usbd_xfer_handle xfer;
-
- xfer = STAILQ_FIRST(&sc->sc_free_xfers);
- if (xfer != NULL) {
- STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_FREE) {
- printf("ohci_allocx: xfer=%p not free, 0x%08x\n", xfer,
- xfer->busy_free);
- }
-#endif
- } else {
- xfer = malloc(sizeof(struct ohci_xfer), M_USB, M_NOWAIT);
- }
- if (xfer != NULL) {
- memset(xfer, 0, sizeof (struct ohci_xfer));
- usb_init_task(&OXFER(xfer)->abort_task, ohci_timeout_task,
- xfer);
- OXFER(xfer)->ohci_xfer_flags = 0;
-#ifdef DIAGNOSTIC
- xfer->busy_free = XFER_BUSY;
-#endif
- }
- return (xfer);
-}
-
-void
-ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
-{
- struct ohci_softc *sc = (struct ohci_softc *)bus;
-
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_BUSY) {
- printf("ohci_freex: xfer=%p not busy, 0x%08x\n", xfer,
- xfer->busy_free);
- return;
- }
- xfer->busy_free = XFER_FREE;
-#endif
- STAILQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
-}
-
-/*
- * Shut down the controller when the system is going down.
- */
-void
-ohci_shutdown(void *v)
-{
- ohci_softc_t *sc = v;
-
- DPRINTF(("ohci_shutdown: stopping the HC\n"));
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
-}
-
-/*
- * Handle suspend/resume.
- *
- * We need to switch to polling mode here, because this routine is
- * called from an intterupt context. This is all right since we
- * are almost suspended anyway.
- */
-void
-ohci_power(int why, void *v)
-{
- ohci_softc_t *sc = v;
- u_int32_t ctl;
- int s;
-
-#ifdef USB_DEBUG
- DPRINTF(("ohci_power: sc=%p, why=%d\n", sc, why));
- ohci_dumpregs(sc);
-#endif
-
- s = splhardusb();
- if (why != PWR_RESUME) {
- sc->sc_bus.use_polling++;
- ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
- if (sc->sc_control == 0) {
- /*
- * Preserve register values, in case that APM BIOS
- * does not recover them.
- */
- sc->sc_control = ctl;
- sc->sc_intre = OREAD4(sc, OHCI_INTERRUPT_ENABLE);
- }
- ctl |= OHCI_HCFS_SUSPEND;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
- sc->sc_bus.use_polling--;
- } else {
- sc->sc_bus.use_polling++;
-
- /* Some broken BIOSes never initialize Controller chip */
- ohci_controller_init(sc);
-
- if (sc->sc_intre)
- OWRITE4(sc, OHCI_INTERRUPT_ENABLE,
- sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE));
- if (sc->sc_control)
- ctl = sc->sc_control;
- else
- ctl = OREAD4(sc, OHCI_CONTROL);
- ctl |= OHCI_HCFS_RESUME;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
- ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
- sc->sc_control = sc->sc_intre = 0;
- sc->sc_bus.use_polling--;
- }
- splx(s);
-}
-
-#ifdef USB_DEBUG
-void
-ohci_dumpregs(ohci_softc_t *sc)
-{
- DPRINTF(("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n",
- OREAD4(sc, OHCI_REVISION),
- OREAD4(sc, OHCI_CONTROL),
- OREAD4(sc, OHCI_COMMAND_STATUS)));
- DPRINTF((" intrstat=0x%08x intre=0x%08x intrd=0x%08x\n",
- OREAD4(sc, OHCI_INTERRUPT_STATUS),
- OREAD4(sc, OHCI_INTERRUPT_ENABLE),
- OREAD4(sc, OHCI_INTERRUPT_DISABLE)));
- DPRINTF((" hcca=0x%08x percur=0x%08x ctrlhd=0x%08x\n",
- OREAD4(sc, OHCI_HCCA),
- OREAD4(sc, OHCI_PERIOD_CURRENT_ED),
- OREAD4(sc, OHCI_CONTROL_HEAD_ED)));
- DPRINTF((" ctrlcur=0x%08x bulkhd=0x%08x bulkcur=0x%08x\n",
- OREAD4(sc, OHCI_CONTROL_CURRENT_ED),
- OREAD4(sc, OHCI_BULK_HEAD_ED),
- OREAD4(sc, OHCI_BULK_CURRENT_ED)));
- DPRINTF((" done=0x%08x fmival=0x%08x fmrem=0x%08x\n",
- OREAD4(sc, OHCI_DONE_HEAD),
- OREAD4(sc, OHCI_FM_INTERVAL),
- OREAD4(sc, OHCI_FM_REMAINING)));
- DPRINTF((" fmnum=0x%08x perst=0x%08x lsthrs=0x%08x\n",
- OREAD4(sc, OHCI_FM_NUMBER),
- OREAD4(sc, OHCI_PERIODIC_START),
- OREAD4(sc, OHCI_LS_THRESHOLD)));
- DPRINTF((" desca=0x%08x descb=0x%08x stat=0x%08x\n",
- OREAD4(sc, OHCI_RH_DESCRIPTOR_A),
- OREAD4(sc, OHCI_RH_DESCRIPTOR_B),
- OREAD4(sc, OHCI_RH_STATUS)));
- DPRINTF((" port1=0x%08x port2=0x%08x\n",
- OREAD4(sc, OHCI_RH_PORT_STATUS(1)),
- OREAD4(sc, OHCI_RH_PORT_STATUS(2))));
- DPRINTF((" HCCA: frame_number=0x%04x done_head=0x%08x\n",
- le32toh(sc->sc_hcca->hcca_frame_number),
- le32toh(sc->sc_hcca->hcca_done_head)));
-}
-#endif
-
-static int ohci_intr1(ohci_softc_t *);
-
-void
-ohci_intr(void *p)
-{
- ohci_softc_t *sc = p;
-
- if (sc == NULL || sc->sc_dying)
- return;
-
- /* If we get an interrupt while polling, then just ignore it. */
- if (sc->sc_bus.use_polling) {
-#ifdef DIAGNOSTIC
- printf("ohci_intr: ignored interrupt while polling\n");
-#endif
- return;
- }
-
- ohci_intr1(sc);
-}
-
-static int
-ohci_intr1(ohci_softc_t *sc)
-{
- u_int32_t intrs, eintrs;
- ohci_physaddr_t done;
-
- DPRINTFN(14,("ohci_intr1: enter\n"));
-
- /* In case the interrupt occurs before initialization has completed. */
- if (sc == NULL || sc->sc_hcca == NULL) {
-#ifdef DIAGNOSTIC
- printf("ohci_intr: sc->sc_hcca == NULL\n");
-#endif
- return (0);
- }
-
- intrs = 0;
- done = le32toh(sc->sc_hcca->hcca_done_head);
-
- /* The LSb of done is used to inform the HC Driver that an interrupt
- * condition exists for both the Done list and for another event
- * recorded in HcInterruptStatus. On an interrupt from the HC, the HC
- * Driver checks the HccaDoneHead Value. If this value is 0, then the
- * interrupt was caused by other than the HccaDoneHead update and the
- * HcInterruptStatus register needs to be accessed to determine that
- * exact interrupt cause. If HccaDoneHead is nonzero, then a Done list
- * update interrupt is indicated and if the LSb of done is nonzero,
- * then an additional interrupt event is indicated and
- * HcInterruptStatus should be checked to determine its cause.
- */
- if (done != 0) {
- if (done & ~OHCI_DONE_INTRS)
- intrs = OHCI_WDH;
- if (done & OHCI_DONE_INTRS) {
- intrs |= OREAD4(sc, OHCI_INTERRUPT_STATUS);
- done &= ~OHCI_DONE_INTRS;
- }
- sc->sc_hcca->hcca_done_head = 0;
- } else
- intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & ~OHCI_WDH;
-
- if (intrs == 0) /* nothing to be done (PCI shared interrupt) */
- return (0);
-
- intrs &= ~OHCI_MIE;
- OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs); /* Acknowledge */
- eintrs = intrs & sc->sc_eintrs;
- if (!eintrs)
- return (0);
-
- sc->sc_bus.intr_context++;
- sc->sc_bus.no_intrs++;
- DPRINTFN(7, ("ohci_intr: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n",
- sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS),
- (u_int)eintrs));
-
- if (eintrs & OHCI_SO) {
- sc->sc_overrun_cnt++;
- if (usbd_ratecheck(&sc->sc_overrun_ntc)) {
- printf("%s: %u scheduling overruns\n",
- device_get_nameunit(sc->sc_bus.bdev), sc->sc_overrun_cnt);
- sc->sc_overrun_cnt = 0;
- }
- /* XXX do what */
- eintrs &= ~OHCI_SO;
- }
- if (eintrs & OHCI_WDH) {
- ohci_add_done(sc, done &~ OHCI_DONE_INTRS);
- usb_schedsoftintr(&sc->sc_bus);
- eintrs &= ~OHCI_WDH;
- }
- if (eintrs & OHCI_RD) {
- printf("%s: resume detect\n", device_get_nameunit(sc->sc_bus.bdev));
- /* XXX process resume detect */
- }
- if (eintrs & OHCI_UE) {
- printf("%s: unrecoverable error, controller halted\n",
- device_get_nameunit(sc->sc_bus.bdev));
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
- /* XXX what else */
- }
- if (eintrs & OHCI_RHSC) {
- ohci_rhsc(sc, sc->sc_intrxfer);
- /*
- * Disable RHSC interrupt for now, because it will be
- * on until the port has been reset.
- */
- ohci_rhsc_able(sc, 0);
- /* Do not allow RHSC interrupts > 1 per second */
- callout_reset(&sc->sc_tmo_rhsc, hz, ohci_rhsc_enable, sc);
- eintrs &= ~OHCI_RHSC;
- }
-
- sc->sc_bus.intr_context--;
-
- if (eintrs != 0) {
- /* Block unprocessed interrupts. XXX */
- OWRITE4(sc, OHCI_INTERRUPT_DISABLE, eintrs);
- sc->sc_eintrs &= ~eintrs;
- printf("%s: blocking intrs 0x%x\n",
- device_get_nameunit(sc->sc_bus.bdev), eintrs);
- }
-
- return (1);
-}
-
-void
-ohci_rhsc_able(ohci_softc_t *sc, int on)
-{
- DPRINTFN(4, ("ohci_rhsc_able: on=%d\n", on));
- if (on) {
- sc->sc_eintrs |= OHCI_RHSC;
- OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC);
- } else {
- sc->sc_eintrs &= ~OHCI_RHSC;
- OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_RHSC);
- }
-}
-
-void
-ohci_rhsc_enable(void *v_sc)
-{
- ohci_softc_t *sc = v_sc;
- int s;
-
- s = splhardusb();
- ohci_rhsc_able(sc, 1);
- splx(s);
-}
-
-#ifdef USB_DEBUG
-char *ohci_cc_strs[] = {
- "NO_ERROR",
- "CRC",
- "BIT_STUFFING",
- "DATA_TOGGLE_MISMATCH",
- "STALL",
- "DEVICE_NOT_RESPONDING",
- "PID_CHECK_FAILURE",
- "UNEXPECTED_PID",
- "DATA_OVERRUN",
- "DATA_UNDERRUN",
- "BUFFER_OVERRUN",
- "BUFFER_UNDERRUN",
- "reserved",
- "reserved",
- "NOT_ACCESSED",
- "NOT_ACCESSED"
-};
-#endif
-
-void
-ohci_add_done(ohci_softc_t *sc, ohci_physaddr_t done)
-{
- ohci_soft_itd_t *sitd, *sidone, **ip;
- ohci_soft_td_t *std, *sdone, **p;
-
- /* Reverse the done list. */
- for (sdone = NULL, sidone = NULL; done != 0; ) {
- std = ohci_hash_find_td(sc, done);
- if (std != NULL) {
- std->dnext = sdone;
- done = le32toh(std->td.td_nexttd);
- sdone = std;
- DPRINTFN(10,("add TD %p\n", std));
- continue;
- }
- sitd = ohci_hash_find_itd(sc, done);
- if (sitd != NULL) {
- sitd->dnext = sidone;
- done = le32toh(sitd->itd.itd_nextitd);
- sidone = sitd;
- DPRINTFN(5,("add ITD %p\n", sitd));
- continue;
- }
- panic("ohci_add_done: addr 0x%08lx not found", (u_long)done);
- }
-
- /* sdone & sidone now hold the done lists. */
- /* Put them on the already processed lists. */
- for (p = &sc->sc_sdone; *p != NULL; p = &(*p)->dnext)
- ;
- *p = sdone;
- for (ip = &sc->sc_sidone; *ip != NULL; ip = &(*ip)->dnext)
- ;
- *ip = sidone;
-}
-
-void
-ohci_softintr(void *v)
-{
- ohci_softc_t *sc = v;
- ohci_soft_itd_t *sitd, *sidone, *sitdnext;
- ohci_soft_td_t *std, *sdone, *stdnext, *p, *n;
- usbd_xfer_handle xfer;
- struct ohci_pipe *opipe;
- int len, cc, s;
- int i, j, iframes;
-
- DPRINTFN(10,("ohci_softintr: enter\n"));
-
- sc->sc_bus.intr_context++;
-
- s = splhardusb();
- sdone = sc->sc_sdone;
- sc->sc_sdone = NULL;
- sidone = sc->sc_sidone;
- sc->sc_sidone = NULL;
- splx(s);
-
- DPRINTFN(10,("ohci_softintr: sdone=%p sidone=%p\n", sdone, sidone));
-
-#ifdef USB_DEBUG
- if (ohcidebug > 10) {
- DPRINTF(("ohci_process_done: TD done:\n"));
- ohci_dump_tds(sdone);
- }
-#endif
-
- for (std = sdone; std; std = stdnext) {
- xfer = std->xfer;
- stdnext = std->dnext;
- DPRINTFN(10, ("ohci_process_done: std=%p xfer=%p hcpriv=%p\n",
- std, xfer, (xfer ? xfer->hcpriv : NULL)));
- if (xfer == NULL) {
- /*
- * xfer == NULL: There seems to be no xfer associated
- * with this TD. It is tailp that happened to end up on
- * the done queue.
- */
- continue;
- }
- if (xfer->status == USBD_CANCELLED ||
- xfer->status == USBD_TIMEOUT) {
- DPRINTF(("ohci_process_done: cancel/timeout %p\n",
- xfer));
- /* Handled by abort routine. */
- continue;
- }
-
- len = std->len;
- if (std->td.td_cbp != 0)
- len -= le32toh(std->td.td_be) -
- le32toh(std->td.td_cbp) + 1;
- DPRINTFN(10, ("ohci_process_done: len=%d, flags=0x%x\n", len,
- std->flags));
- if (std->flags & OHCI_ADD_LEN)
- xfer->actlen += len;
-
- cc = OHCI_TD_GET_CC(le32toh(std->td.td_flags));
- if (cc != OHCI_CC_NO_ERROR) {
- /*
- * Endpoint is halted. First unlink all the TDs
- * belonging to the failed transfer, and then restart
- * the endpoint.
- */
- opipe = (struct ohci_pipe *)xfer->pipe;
-
- DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n",
- OHCI_TD_GET_CC(le32toh(std->td.td_flags)),
- ohci_cc_strs[OHCI_TD_GET_CC(le32toh(std->td.td_flags))]));
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(OXFER(xfer)->xfer.pipe->device,
- &OXFER(xfer)->abort_task);
-
- /* Remove all this xfer's TDs from the done queue. */
- for (p = std; p->dnext != NULL; p = p->dnext) {
- if (p->dnext->xfer != xfer)
- continue;
- p->dnext = p->dnext->dnext;
- }
- /* The next TD may have been removed. */
- stdnext = std->dnext;
-
- /* Remove all TDs belonging to this xfer. */
- for (p = xfer->hcpriv; p->xfer == xfer; p = n) {
- n = p->nexttd;
- ohci_free_std(sc, p);
- }
-
- /* clear halt */
- opipe->sed->ed.ed_headp = htole32(p->physaddr);
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
-
- if (cc == OHCI_CC_STALL)
- xfer->status = USBD_STALLED;
- else
- xfer->status = USBD_IOERROR;
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
- continue;
- }
- /*
- * Skip intermediate TDs. They remain linked from
- * xfer->hcpriv and we free them when the transfer completes.
- */
- if ((std->flags & OHCI_CALL_DONE) == 0)
- continue;
-
- /* Normal transfer completion */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(OXFER(xfer)->xfer.pipe->device,
- &OXFER(xfer)->abort_task);
- for (p = xfer->hcpriv; p->xfer == xfer; p = n) {
- n = p->nexttd;
- ohci_free_std(sc, p);
- }
- xfer->status = USBD_NORMAL_COMPLETION;
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
- }
-
-#ifdef USB_DEBUG
- if (ohcidebug > 10) {
- DPRINTF(("ohci_softintr: ITD done:\n"));
- ohci_dump_itds(sidone);
- }
-#endif
-
- for (sitd = sidone; sitd != NULL; sitd = sitdnext) {
- xfer = sitd->xfer;
- sitdnext = sitd->dnext;
- sitd->flags |= OHCI_ITD_INTFIN;
- DPRINTFN(1, ("ohci_process_done: sitd=%p xfer=%p hcpriv=%p\n",
- sitd, xfer, xfer ? xfer->hcpriv : 0));
- if (xfer == NULL)
- continue;
- if (xfer->status == USBD_CANCELLED ||
- xfer->status == USBD_TIMEOUT) {
- DPRINTF(("ohci_process_done: cancel/timeout %p\n",
- xfer));
- /* Handled by abort routine. */
- continue;
- }
- if (xfer->pipe)
- if (xfer->pipe->aborting)
- continue; /*Ignore.*/
-#ifdef DIAGNOSTIC
- if (sitd->isdone)
- printf("ohci_softintr: sitd=%p is done\n", sitd);
- sitd->isdone = 1;
-#endif
- opipe = (struct ohci_pipe *)xfer->pipe;
- if (opipe->aborting)
- continue;
-
- if (sitd->flags & OHCI_CALL_DONE) {
- ohci_soft_itd_t *next;
-
- opipe->u.iso.inuse -= xfer->nframes;
- xfer->status = USBD_NORMAL_COMPLETION;
- for (i = 0, sitd = xfer->hcpriv;;sitd = next) {
- next = sitd->nextitd;
- if (OHCI_ITD_GET_CC(sitd->itd.itd_flags) != OHCI_CC_NO_ERROR)
- xfer->status = USBD_IOERROR;
-
- if (xfer->status == USBD_NORMAL_COMPLETION) {
- iframes = OHCI_ITD_GET_FC(sitd->itd.itd_flags);
- for (j = 0; j < iframes; i++, j++) {
- len = le16toh(sitd->itd.itd_offset[j]);
- len =
- (OHCI_ITD_PSW_GET_CC(len) ==
- OHCI_CC_NOT_ACCESSED) ? 0 :
- OHCI_ITD_PSW_LENGTH(len);
- xfer->frlengths[i] = len;
- }
- }
- if (sitd->flags & OHCI_CALL_DONE)
- break;
- }
- for (sitd = xfer->hcpriv; sitd->xfer == xfer;
- sitd = next) {
- next = sitd->nextitd;
- ohci_free_sitd(sc, sitd);
- }
-
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
- }
- }
-
-#ifdef USB_USE_SOFTINTR
- if (sc->sc_softwake) {
- sc->sc_softwake = 0;
- wakeup(&sc->sc_softwake);
- }
-#endif /* USB_USE_SOFTINTR */
-
- sc->sc_bus.intr_context--;
- DPRINTFN(10,("ohci_softintr: done:\n"));
-}
-
-void
-ohci_device_ctrl_done(usbd_xfer_handle xfer)
-{
- DPRINTFN(10,("ohci_device_ctrl_done: xfer=%p\n", xfer));
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST)) {
- panic("ohci_device_ctrl_done: not a request");
- }
-#endif
- xfer->hcpriv = NULL;
-}
-
-void
-ohci_device_intr_done(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
- usbd_status err;
-
- DPRINTFN(10,("ohci_device_intr_done: xfer=%p, actlen=%d\n",
- xfer, xfer->actlen));
-
- xfer->hcpriv = NULL;
- if (xfer->pipe->repeat) {
- err = ohci_device_intr_insert(sc, xfer);
- if (err) {
- xfer->status = err;
- return;
- }
- }
-}
-
-void
-ohci_device_bulk_done(usbd_xfer_handle xfer)
-{
- DPRINTFN(10,("ohci_device_bulk_done: xfer=%p, actlen=%d\n",
- xfer, xfer->actlen));
-
- xfer->hcpriv = NULL;
-}
-
-/*
- * XXX write back xfer data for architectures with a write-back
- * data cache; this is a hack because usb is mis-architected
- * in blindly mixing bus_dma w/ PIO.
- */
-static __inline void
-hacksync(usbd_xfer_handle xfer)
-{
- bus_dma_tag_t tag;
- struct usb_dma_mapping *dmap;
-
- if (xfer->length == 0)
- return;
- tag = xfer->pipe->device->bus->buffer_dmatag;
- dmap = &xfer->dmamap;
- bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREWRITE);
-}
-
-void
-ohci_rhsc(ohci_softc_t *sc, usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe;
- u_char *p;
- int i, m;
- int hstatus;
-
- hstatus = OREAD4(sc, OHCI_RH_STATUS);
- DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n",
- sc, xfer, hstatus));
-
- if (xfer == NULL) {
- /* Just ignore the change. */
- return;
- }
-
- pipe = xfer->pipe;
-
- p = xfer->buffer;
- m = min(sc->sc_noport, xfer->length * 8 - 1);
- memset(p, 0, xfer->length);
- for (i = 1; i <= m; i++) {
- /* Pick out CHANGE bits from the status reg. */
- if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16)
- p[i/8] |= 1 << (i%8);
- }
- DPRINTF(("ohci_rhsc: change=0x%02x\n", *p));
- xfer->actlen = xfer->length;
- xfer->status = USBD_NORMAL_COMPLETION;
-
- hacksync(xfer); /* XXX to compensate for usb_transfer_complete */
- usb_transfer_complete(xfer);
-}
-
-void
-ohci_root_intr_done(usbd_xfer_handle xfer)
-{
- xfer->hcpriv = NULL;
-}
-
-void
-ohci_root_ctrl_done(usbd_xfer_handle xfer)
-{
- xfer->hcpriv = NULL;
-}
-
-/*
- * Wait here until controller claims to have an interrupt.
- * Then call ohci_intr and return. Use timeout to avoid waiting
- * too long.
- */
-void
-ohci_waitintr(ohci_softc_t *sc, usbd_xfer_handle xfer)
-{
- int timo = xfer->timeout;
- int usecs;
- u_int32_t intrs;
-
- xfer->status = USBD_IN_PROGRESS;
- for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) {
- usb_delay_ms(&sc->sc_bus, 1);
- if (sc->sc_dying)
- break;
- intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs;
- DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs));
-#ifdef USB_DEBUG
- if (ohcidebug > 15)
- ohci_dumpregs(sc);
-#endif
- if (intrs) {
- ohci_intr1(sc);
- if (xfer->status != USBD_IN_PROGRESS)
- return;
- }
- }
-
- /* Timeout */
- DPRINTF(("ohci_waitintr: timeout\n"));
- xfer->status = USBD_TIMEOUT;
- usb_transfer_complete(xfer);
- /* XXX should free TD */
-}
-
-void
-ohci_poll(struct usbd_bus *bus)
-{
- ohci_softc_t *sc = (ohci_softc_t *)bus;
-#ifdef USB_DEBUG
- static int last;
- int new;
- new = OREAD4(sc, OHCI_INTERRUPT_STATUS);
- if (new != last) {
- DPRINTFN(10,("ohci_poll: intrs=0x%04x\n", new));
- last = new;
- }
-#endif
-
- if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs)
- ohci_intr1(sc);
-}
-
-usbd_status
-ohci_device_request(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- usb_device_request_t *req = &xfer->request;
- usbd_device_handle dev = opipe->pipe.device;
- ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
- ohci_soft_td_t *setup, *stat, *next, *tail;
- ohci_soft_ed_t *sed;
- int isread;
- int len;
- usbd_status err;
- int s;
-
- isread = req->bmRequestType & UT_READ;
- len = UGETW(req->wLength);
-
- DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, "
- "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
- req->bmRequestType, req->bRequest, UGETW(req->wValue),
- UGETW(req->wIndex), len, dev->address,
- opipe->pipe.endpoint->edesc->bEndpointAddress));
-
- setup = opipe->tail.td;
- stat = ohci_alloc_std(sc);
- if (stat == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- tail = ohci_alloc_std(sc);
- if (tail == NULL) {
- err = USBD_NOMEM;
- goto bad2;
- }
- tail->xfer = NULL;
-
- sed = opipe->sed;
- opipe->u.ctl.length = len;
- next = stat;
-
- /* Set up data transaction */
- if (len != 0) {
- ohci_soft_td_t *std = stat;
-
- err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer,
- std, &stat);
- stat = stat->nexttd; /* point at free TD */
- if (err)
- goto bad3;
- /* Start toggle at 1 and then use the carried toggle. */
- std->td.td_flags &= htole32(~OHCI_TD_TOGGLE_MASK);
- std->td.td_flags |= htole32(OHCI_TD_TOGGLE_1);
- }
-
- memcpy(KERNADDR(&opipe->u.ctl.reqdma, 0), req, sizeof *req);
-
- setup->td.td_flags = htole32(OHCI_TD_SETUP | OHCI_TD_NOCC |
- OHCI_TD_TOGGLE_0 | OHCI_TD_SET_DI(6));
- setup->td.td_cbp = htole32(DMAADDR(&opipe->u.ctl.reqdma, 0));
- setup->nexttd = next;
- setup->td.td_nexttd = htole32(next->physaddr);
- setup->td.td_be = htole32(le32toh(setup->td.td_cbp) + sizeof *req - 1);
- setup->len = 0;
- setup->xfer = xfer;
- setup->flags = 0;
- xfer->hcpriv = setup;
-
- stat->td.td_flags = htole32(
- (isread ? OHCI_TD_OUT : OHCI_TD_IN) |
- OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1));
- stat->td.td_cbp = 0;
- stat->nexttd = tail;
- stat->td.td_nexttd = htole32(tail->physaddr);
- stat->td.td_be = 0;
- stat->flags = OHCI_CALL_DONE;
- stat->len = 0;
- stat->xfer = xfer;
-
-#ifdef USB_DEBUG
- if (ohcidebug > 5) {
- DPRINTF(("ohci_device_request:\n"));
- ohci_dump_ed(sed);
- ohci_dump_tds(setup);
- }
-#endif
-
- /* Insert ED in schedule */
- s = splusb();
- sed->ed.ed_tailp = htole32(tail->physaddr);
- opipe->tail.td = tail;
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ohci_timeout, xfer);
- }
- splx(s);
-
-#ifdef USB_DEBUG
- if (ohcidebug > 20) {
- delay(10000);
- DPRINTF(("ohci_device_request: status=%x\n",
- OREAD4(sc, OHCI_COMMAND_STATUS)));
- ohci_dumpregs(sc);
- printf("ctrl head:\n");
- ohci_dump_ed(sc->sc_ctrl_head);
- printf("sed:\n");
- ohci_dump_ed(sed);
- ohci_dump_tds(setup);
- }
-#endif
-
- return (USBD_NORMAL_COMPLETION);
-
- bad3:
- ohci_free_std(sc, tail);
- bad2:
- ohci_free_std(sc, stat);
- bad1:
- return (err);
-}
-
-/*
- * Add an ED to the schedule. Called at splusb().
- */
-void
-ohci_add_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
-{
- DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head));
-
- SPLUSBCHECK;
- sed->next = head->next;
- sed->ed.ed_nexted = head->ed.ed_nexted;
- head->next = sed;
- head->ed.ed_nexted = htole32(sed->physaddr);
-}
-
-/*
- * Remove an ED from the schedule. Called at splusb().
- */
-void
-ohci_rem_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
-{
- ohci_soft_ed_t *p;
-
- SPLUSBCHECK;
-
- /* XXX */
- for (p = head; p != NULL && p->next != sed; p = p->next)
- ;
- if (p == NULL)
- panic("ohci_rem_ed: ED not found");
- p->next = sed->next;
- p->ed.ed_nexted = sed->ed.ed_nexted;
-}
-
-/*
- * When a transfer is completed the TD is added to the done queue by
- * the host controller. This queue is the processed by software.
- * Unfortunately the queue contains the physical address of the TD
- * and we have no simple way to translate this back to a kernel address.
- * To make the translation possible (and fast) we use a hash table of
- * TDs currently in the schedule. The physical address is used as the
- * hash value.
- */
-
-#define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE)
-/* Called at splusb() */
-void
-ohci_hash_add_td(ohci_softc_t *sc, ohci_soft_td_t *std)
-{
- int h = HASH(std->physaddr);
-
- SPLUSBCHECK;
-
- LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
-}
-
-/* Called at splusb() */
-void
-ohci_hash_rem_td(ohci_softc_t *sc, ohci_soft_td_t *std)
-{
- SPLUSBCHECK;
-
- LIST_REMOVE(std, hnext);
-}
-
-ohci_soft_td_t *
-ohci_hash_find_td(ohci_softc_t *sc, ohci_physaddr_t a)
-{
- int h = HASH(a);
- ohci_soft_td_t *std;
-
- /* if these are present they should be masked out at an earlier
- * stage.
- */
- KASSERT((a&~OHCI_HEADMASK) == 0, ("%s: 0x%b has lower bits set\n",
- device_get_nameunit(sc->sc_bus.bdev),
- (int) a, "\20\1HALT\2TOGGLE"));
-
- for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
- std != NULL;
- std = LIST_NEXT(std, hnext))
- if (std->physaddr == a)
- return (std);
-
- DPRINTF(("%s: ohci_hash_find_td: addr 0x%08lx not found\n",
- device_get_nameunit(sc->sc_bus.bdev), (u_long) a));
- return (NULL);
-}
-
-/* Called at splusb() */
-void
-ohci_hash_add_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
-{
- int h = HASH(sitd->physaddr);
-
- SPLUSBCHECK;
-
- DPRINTFN(10,("ohci_hash_add_itd: sitd=%p physaddr=0x%08lx\n",
- sitd, (u_long)sitd->physaddr));
-
- LIST_INSERT_HEAD(&sc->sc_hash_itds[h], sitd, hnext);
-}
-
-/* Called at splusb() */
-void
-ohci_hash_rem_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
-{
- SPLUSBCHECK;
-
- DPRINTFN(10,("ohci_hash_rem_itd: sitd=%p physaddr=0x%08lx\n",
- sitd, (u_long)sitd->physaddr));
-
- LIST_REMOVE(sitd, hnext);
-}
-
-ohci_soft_itd_t *
-ohci_hash_find_itd(ohci_softc_t *sc, ohci_physaddr_t a)
-{
- int h = HASH(a);
- ohci_soft_itd_t *sitd;
-
- for (sitd = LIST_FIRST(&sc->sc_hash_itds[h]);
- sitd != NULL;
- sitd = LIST_NEXT(sitd, hnext))
- if (sitd->physaddr == a)
- return (sitd);
- return (NULL);
-}
-
-void
-ohci_timeout(void *addr)
-{
- struct ohci_xfer *oxfer = addr;
- struct ohci_pipe *opipe = (struct ohci_pipe *)oxfer->xfer.pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
-
- DPRINTF(("ohci_timeout: oxfer=%p\n", oxfer));
-
- if (sc->sc_dying) {
- ohci_abort_xfer(&oxfer->xfer, USBD_TIMEOUT);
- return;
- }
-
- /* Execute the abort in a process context. */
- usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task,
- USB_TASKQ_HC);
-}
-
-void
-ohci_timeout_task(void *addr)
-{
- usbd_xfer_handle xfer = addr;
- int s;
-
- DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer));
-
- s = splusb();
- ohci_abort_xfer(xfer, USBD_TIMEOUT);
- splx(s);
-}
-
-#ifdef USB_DEBUG
-void
-ohci_dump_tds(ohci_soft_td_t *std)
-{
- for (; std; std = std->nexttd)
- ohci_dump_td(std);
-}
-
-void
-ohci_dump_td(ohci_soft_td_t *std)
-{
- char sbuf[128];
-
- bitmask_snprintf((u_int32_t)le32toh(std->td.td_flags),
- "\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE",
- sbuf, sizeof(sbuf));
-
- printf("TD(%p) at %08lx: %s delay=%d ec=%d cc=%d\ncbp=0x%08lx "
- "nexttd=0x%08lx be=0x%08lx\n",
- std, (u_long)std->physaddr, sbuf,
- OHCI_TD_GET_DI(le32toh(std->td.td_flags)),
- OHCI_TD_GET_EC(le32toh(std->td.td_flags)),
- OHCI_TD_GET_CC(le32toh(std->td.td_flags)),
- (u_long)le32toh(std->td.td_cbp),
- (u_long)le32toh(std->td.td_nexttd),
- (u_long)le32toh(std->td.td_be));
-}
-
-void
-ohci_dump_itd(ohci_soft_itd_t *sitd)
-{
- int i;
-
- printf("ITD(%p) at %08lx: sf=%d di=%d fc=%d cc=%d\n"
- "bp0=0x%08lx next=0x%08lx be=0x%08lx\n",
- sitd, (u_long)sitd->physaddr,
- OHCI_ITD_GET_SF(le32toh(sitd->itd.itd_flags)),
- OHCI_ITD_GET_DI(le32toh(sitd->itd.itd_flags)),
- OHCI_ITD_GET_FC(le32toh(sitd->itd.itd_flags)),
- OHCI_ITD_GET_CC(le32toh(sitd->itd.itd_flags)),
- (u_long)le32toh(sitd->itd.itd_bp0),
- (u_long)le32toh(sitd->itd.itd_nextitd),
- (u_long)le32toh(sitd->itd.itd_be));
- for (i = 0; i < OHCI_ITD_NOFFSET; i++)
- printf("offs[%d]=0x%04x ", i,
- (u_int)le16toh(sitd->itd.itd_offset[i]));
- printf("\n");
-}
-
-void
-ohci_dump_itds(ohci_soft_itd_t *sitd)
-{
- for (; sitd; sitd = sitd->nextitd)
- ohci_dump_itd(sitd);
-}
-
-void
-ohci_dump_ed(ohci_soft_ed_t *sed)
-{
- char sbuf[128], sbuf2[128];
-
- bitmask_snprintf((u_int32_t)le32toh(sed->ed.ed_flags),
- "\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO",
- sbuf, sizeof(sbuf));
- bitmask_snprintf((u_int32_t)le32toh(sed->ed.ed_headp),
- "\20\1HALT\2CARRY", sbuf2, sizeof(sbuf2));
-
- printf("ED(%p) at 0x%08lx: addr=%d endpt=%d maxp=%d flags=%s\ntailp=0x%08lx "
- "headflags=%s headp=0x%08lx nexted=0x%08lx\n",
- sed, (u_long)sed->physaddr,
- OHCI_ED_GET_FA(le32toh(sed->ed.ed_flags)),
- OHCI_ED_GET_EN(le32toh(sed->ed.ed_flags)),
- OHCI_ED_GET_MAXP(le32toh(sed->ed.ed_flags)), sbuf,
- (u_long)le32toh(sed->ed.ed_tailp), sbuf2,
- (u_long)le32toh(sed->ed.ed_headp),
- (u_long)le32toh(sed->ed.ed_nexted));
-}
-#endif
-
-usbd_status
-ohci_open(usbd_pipe_handle pipe)
-{
- usbd_device_handle dev = pipe->device;
- ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
- usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- u_int8_t addr = dev->address;
- u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
- ohci_soft_ed_t *sed;
- ohci_soft_td_t *std;
- ohci_soft_itd_t *sitd;
- ohci_physaddr_t tdphys;
- u_int32_t fmt;
- usbd_status err;
- int s;
- int ival;
-
- DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
- pipe, addr, ed->bEndpointAddress, sc->sc_addr));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- std = NULL;
- sed = NULL;
-
- if (addr == sc->sc_addr) {
- switch (ed->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &ohci_root_ctrl_methods;
- break;
- case UE_DIR_IN | OHCI_INTR_ENDPT:
- pipe->methods = &ohci_root_intr_methods;
- break;
- default:
- return (USBD_INVAL);
- }
- } else {
- sed = ohci_alloc_sed(sc);
- if (sed == NULL)
- goto bad0;
- opipe->sed = sed;
- if (xfertype == UE_ISOCHRONOUS) {
- sitd = ohci_alloc_sitd(sc);
- if (sitd == NULL)
- goto bad1;
- opipe->tail.itd = sitd;
- opipe->aborting = 0;
- tdphys = sitd->physaddr;
- fmt = OHCI_ED_FORMAT_ISO;
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
- fmt |= OHCI_ED_DIR_IN;
- else
- fmt |= OHCI_ED_DIR_OUT;
- } else {
- std = ohci_alloc_std(sc);
- if (std == NULL)
- goto bad1;
- opipe->tail.td = std;
- tdphys = std->physaddr;
- fmt = OHCI_ED_FORMAT_GEN | OHCI_ED_DIR_TD;
- }
- sed->ed.ed_flags = htole32(
- OHCI_ED_SET_FA(addr) |
- OHCI_ED_SET_EN(UE_GET_ADDR(ed->bEndpointAddress)) |
- (dev->speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) |
- fmt |
- OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize)));
- sed->ed.ed_headp = htole32(tdphys |
- (pipe->endpoint->savedtoggle ? OHCI_TOGGLECARRY : 0));
- sed->ed.ed_tailp = htole32(tdphys);
-
- switch (xfertype) {
- case UE_CONTROL:
- pipe->methods = &ohci_device_ctrl_methods;
- err = usb_allocmem(&sc->sc_bus,
- sizeof(usb_device_request_t),
- 0, &opipe->u.ctl.reqdma);
- if (err)
- goto bad;
- s = splusb();
- ohci_add_ed(sed, sc->sc_ctrl_head);
- splx(s);
- break;
- case UE_INTERRUPT:
- pipe->methods = &ohci_device_intr_methods;
- ival = pipe->interval;
- if (ival == USBD_DEFAULT_INTERVAL)
- ival = ed->bInterval;
- return (ohci_device_setintr(sc, opipe, ival));
- case UE_ISOCHRONOUS:
- pipe->methods = &ohci_device_isoc_methods;
- return (ohci_setup_isoc(pipe));
- case UE_BULK:
- pipe->methods = &ohci_device_bulk_methods;
- s = splusb();
- ohci_add_ed(sed, sc->sc_bulk_head);
- splx(s);
- break;
- }
- }
- return (USBD_NORMAL_COMPLETION);
-
- bad:
- if (std != NULL)
- ohci_free_std(sc, std);
- bad1:
- if (sed != NULL)
- ohci_free_sed(sc, sed);
- bad0:
- return (USBD_NOMEM);
-
-}
-
-/*
- * Close a reqular pipe.
- * Assumes that there are no pending transactions.
- */
-void
-ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
- ohci_soft_ed_t *sed = opipe->sed;
- int s;
-
- s = splusb();
-#ifdef DIAGNOSTIC
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
- if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
- (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK)) {
- ohci_soft_td_t *std;
- std = ohci_hash_find_td(sc, le32toh(sed->ed.ed_headp));
- printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x "
- "tl=0x%x pipe=%p, std=%p\n", sed,
- (int)le32toh(sed->ed.ed_headp),
- (int)le32toh(sed->ed.ed_tailp),
- pipe, std);
-#ifdef USB_DEBUG
- usbd_dump_pipe(&opipe->pipe);
-#endif
-#ifdef USB_DEBUG
- ohci_dump_ed(sed);
- if (std)
- ohci_dump_td(std);
-#endif
- usb_delay_ms(&sc->sc_bus, 2);
- if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
- (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK))
- printf("ohci_close_pipe: pipe still not empty\n");
- }
-#endif
- ohci_rem_ed(sed, head);
- /* Make sure the host controller is not touching this ED */
- usb_delay_ms(&sc->sc_bus, 1);
- splx(s);
- pipe->endpoint->savedtoggle =
- (le32toh(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0;
- ohci_free_sed(sc, opipe->sed);
-}
-
-/*
- * Abort a device request.
- * If this routine is called at splusb() it guarantees that the request
- * will be removed from the hardware scheduling and that the callback
- * for it will be called with USBD_CANCELLED status.
- * It's impossible to guarantee that the requested transfer will not
- * have happened since the hardware runs concurrently.
- * If the transaction has already happened we rely on the ordinary
- * interrupt processing to process it.
- */
-void
-ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
-{
- struct ohci_xfer *oxfer = OXFER(xfer);
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
- ohci_soft_ed_t *sed = opipe->sed;
- ohci_soft_td_t *p, *n;
- ohci_physaddr_t headp;
- int s, hit;
-
- DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,sed));
-
- if (sc->sc_dying) {
- /* If we're dying, just do the software part. */
- s = splusb();
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(xfer->pipe->device, &OXFER(xfer)->abort_task);
- usb_transfer_complete(xfer);
- splx(s);
- return;
- }
-
- if (xfer->device->bus->intr_context || !curproc)
- panic("ohci_abort_xfer: not in process context");
-
- /*
- * If an abort is already in progress then just wait for it to
- * complete and return.
- */
- if (oxfer->ohci_xfer_flags & OHCI_XFER_ABORTING) {
- DPRINTFN(2, ("ohci_abort_xfer: already aborting\n"));
- /* No need to wait if we're aborting from a timeout. */
- if (status == USBD_TIMEOUT)
- return;
- /* Override the status which might be USBD_TIMEOUT. */
- xfer->status = status;
- DPRINTFN(2, ("ohci_abort_xfer: waiting for abort to finish\n"));
- oxfer->ohci_xfer_flags |= OHCI_XFER_ABORTWAIT;
- while (oxfer->ohci_xfer_flags & OHCI_XFER_ABORTING)
- tsleep(&oxfer->ohci_xfer_flags, PZERO, "ohciaw", 0);
- return;
- }
-
- /*
- * Step 1: Make interrupt routine and hardware ignore xfer.
- */
- s = splusb();
- oxfer->ohci_xfer_flags |= OHCI_XFER_ABORTING;
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(xfer->pipe->device, &OXFER(xfer)->abort_task);
- splx(s);
- DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */
-
- /*
- * Step 2: Wait until we know hardware has finished any possible
- * use of the xfer. Also make sure the soft interrupt routine
- * has run.
- */
- usb_delay_ms(opipe->pipe.device->bus, 20); /* Hardware finishes in 1ms */
- s = splusb();
-#ifdef USB_USE_SOFTINTR
- sc->sc_softwake = 1;
-#endif /* USB_USE_SOFTINTR */
- usb_schedsoftintr(&sc->sc_bus);
-#ifdef USB_USE_SOFTINTR
- tsleep(&sc->sc_softwake, PZERO, "ohciab", 0);
-#endif /* USB_USE_SOFTINTR */
- splx(s);
-
- /*
- * Step 3: Remove any vestiges of the xfer from the hardware.
- * The complication here is that the hardware may have executed
- * beyond the xfer we're trying to abort. So as we're scanning
- * the TDs of this xfer we check if the hardware points to
- * any of them.
- */
- s = splusb(); /* XXX why? */
- p = xfer->hcpriv;
-#ifdef DIAGNOSTIC
- if (p == NULL) {
- oxfer->ohci_xfer_flags &= ~OHCI_XFER_ABORTING; /* XXX */
- splx(s);
- printf("ohci_abort_xfer: hcpriv is NULL\n");
- return;
- }
-#endif
-#ifdef USB_DEBUG
- if (ohcidebug > 1) {
- DPRINTF(("ohci_abort_xfer: sed=\n"));
- ohci_dump_ed(sed);
- ohci_dump_tds(p);
- }
-#endif
- headp = le32toh(sed->ed.ed_headp) & OHCI_HEADMASK;
- hit = 0;
- for (; p->xfer == xfer; p = n) {
- hit |= headp == p->physaddr;
- n = p->nexttd;
- ohci_free_std(sc, p);
- }
- /* Zap headp register if hardware pointed inside the xfer. */
- if (hit) {
- DPRINTFN(1,("ohci_abort_xfer: set hd=0x08%x, tl=0x%08x\n",
- (int)p->physaddr, (int)le32toh(sed->ed.ed_tailp)));
- sed->ed.ed_headp = htole32(p->physaddr); /* unlink TDs */
- } else {
- DPRINTFN(1,("ohci_abort_xfer: no hit\n"));
- }
-
- /*
- * Step 4: Turn on hardware again.
- */
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */
-
- /*
- * Step 5: Execute callback.
- */
- /* Do the wakeup first to avoid touching the xfer after the callback. */
- oxfer->ohci_xfer_flags &= ~OHCI_XFER_ABORTING;
- if (oxfer->ohci_xfer_flags & OHCI_XFER_ABORTWAIT) {
- oxfer->ohci_xfer_flags &= ~OHCI_XFER_ABORTWAIT;
- wakeup(&oxfer->ohci_xfer_flags);
- }
- usb_transfer_complete(xfer);
-
- splx(s);
-}
-
-/*
- * Data structures and routines to emulate the root hub.
- */
-static usb_device_descriptor_t ohci_devd = {
- USB_DEVICE_DESCRIPTOR_SIZE,
- UDESC_DEVICE, /* type */
- {0x00, 0x01}, /* USB version */
- UDCLASS_HUB, /* class */
- UDSUBCLASS_HUB, /* subclass */
- UDPROTO_FSHUB, /* protocol */
- 64, /* max packet */
- {0},{0},{0x00,0x01}, /* device id */
- 1,2,0, /* string indicies */
- 1 /* # of configurations */
-};
-
-static usb_config_descriptor_t ohci_confd = {
- USB_CONFIG_DESCRIPTOR_SIZE,
- UDESC_CONFIG,
- {USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE},
- 1,
- 1,
- 0,
- UC_SELF_POWERED,
- 0 /* max power */
-};
-
-static usb_interface_descriptor_t ohci_ifcd = {
- USB_INTERFACE_DESCRIPTOR_SIZE,
- UDESC_INTERFACE,
- 0,
- 0,
- 1,
- UICLASS_HUB,
- UISUBCLASS_HUB,
- UIPROTO_FSHUB,
- 0
-};
-
-static usb_endpoint_descriptor_t ohci_endpd = {
- USB_ENDPOINT_DESCRIPTOR_SIZE,
- UDESC_ENDPOINT,
- UE_DIR_IN | OHCI_INTR_ENDPT,
- UE_INTERRUPT,
- {8, 0}, /* max packet */
- 255
-};
-
-static usb_hub_descriptor_t ohci_hubd = {
- USB_HUB_DESCRIPTOR_SIZE,
- UDESC_HUB,
- 0,
- {0,0},
- 0,
- 0,
- {0},
-};
-
-static int
-ohci_str(usb_string_descriptor_t *p, int l, const char *s)
-{
- int i;
-
- if (l == 0)
- return (0);
- p->bLength = 2 * strlen(s) + 2;
- if (l == 1)
- return (1);
- p->bDescriptorType = UDESC_STRING;
- l -= 2;
- for (i = 0; s[i] && l > 1; i++, l -= 2)
- USETW2(p->bString[i], 0, s[i]);
- return (2*i+2);
-}
-
-/*
- * Simulate a hardware hub by handling all the necessary requests.
- */
-static usbd_status
-ohci_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ohci_root_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ohci_root_ctrl_start(usbd_xfer_handle xfer)
-{
- ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
- usb_device_request_t *req;
- void *buf = NULL;
- int port, i;
- int s, len, value, index, l, totlen = 0;
- usb_port_status_t ps;
- usb_hub_descriptor_t hubd;
- usbd_status err;
- u_int32_t v;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST))
- /* XXX panic */
- return (USBD_INVAL);
-#endif
- req = &xfer->request;
-
- DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n",
- req->bmRequestType, req->bRequest));
-
- len = UGETW(req->wLength);
- value = UGETW(req->wValue);
- index = UGETW(req->wIndex);
-
- if (len != 0)
- buf = xfer->buffer;
-
-#define C(x,y) ((x) | ((y) << 8))
- switch(C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- if (len > 0) {
- *(u_int8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value));
- switch(value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- USETW(ohci_devd.idVendor, sc->sc_id_vendor);
- memcpy(buf, &ohci_devd, l);
- break;
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &ohci_confd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ohci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ohci_endpd, l);
- break;
- case UDESC_STRING:
- if (len == 0)
- break;
- *(u_int8_t *)buf = 0;
- totlen = 1;
- switch (value & 0xff) {
- case 1: /* Vendor */
- totlen = ohci_str(buf, len, sc->sc_vendor);
- break;
- case 2: /* Product */
- totlen = ohci_str(buf, len, "OHCI root hub");
- break;
- }
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *(u_int8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- if (value >= USB_MAX_DEVICES) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- if (value != 0 && value != 1) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- break;
- /* Hub requests */
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
- DPRINTFN(8, ("ohci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
- "port=%d feature=%d\n",
- index, value));
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- port = OHCI_RH_PORT_STATUS(index);
- switch(value) {
- case UHF_PORT_ENABLE:
- OWRITE4(sc, port, UPS_CURRENT_CONNECT_STATUS);
- break;
- case UHF_PORT_SUSPEND:
- OWRITE4(sc, port, UPS_OVERCURRENT_INDICATOR);
- break;
- case UHF_PORT_POWER:
- /* Yes, writing to the LOW_SPEED bit clears power. */
- OWRITE4(sc, port, UPS_LOW_SPEED);
- break;
- case UHF_C_PORT_CONNECTION:
- OWRITE4(sc, port, UPS_C_CONNECT_STATUS << 16);
- break;
- case UHF_C_PORT_ENABLE:
- OWRITE4(sc, port, UPS_C_PORT_ENABLED << 16);
- break;
- case UHF_C_PORT_SUSPEND:
- OWRITE4(sc, port, UPS_C_SUSPEND << 16);
- break;
- case UHF_C_PORT_OVER_CURRENT:
- OWRITE4(sc, port, UPS_C_OVERCURRENT_INDICATOR << 16);
- break;
- case UHF_C_PORT_RESET:
- OWRITE4(sc, port, UPS_C_PORT_RESET << 16);
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- switch(value) {
- case UHF_C_PORT_CONNECTION:
- case UHF_C_PORT_ENABLE:
- case UHF_C_PORT_SUSPEND:
- case UHF_C_PORT_OVER_CURRENT:
- case UHF_C_PORT_RESET:
- /* Enable RHSC interrupt if condition is cleared. */
- if ((OREAD4(sc, port) >> 16) == 0)
- ohci_rhsc_able(sc, 1);
- break;
- default:
- break;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
- hubd = ohci_hubd;
- hubd.bNbrPorts = sc->sc_noport;
- USETW(hubd.wHubCharacteristics,
- (v & OHCI_NPS ? UHD_PWR_NO_SWITCH :
- v & OHCI_PSM ? UHD_PWR_GANGED : UHD_PWR_INDIVIDUAL)
- /* XXX overcurrent */
- );
- hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v);
- v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
- for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
- hubd.DeviceRemovable[i++] = (u_int8_t)v;
- hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
- l = min(len, hubd.bDescLength);
- totlen = l;
- memcpy(buf, &hubd, l);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- memset(buf, 0, len); /* ? XXX */
- totlen = len;
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n",
- index));
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
- DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n",
- v));
- USETW(ps.wPortStatus, v);
- USETW(ps.wPortChange, v >> 16);
- l = min(len, sizeof ps);
- memcpy(buf, &ps, l);
- totlen = l;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- port = OHCI_RH_PORT_STATUS(index);
- switch(value) {
- case UHF_PORT_ENABLE:
- OWRITE4(sc, port, UPS_PORT_ENABLED);
- break;
- case UHF_PORT_SUSPEND:
- OWRITE4(sc, port, UPS_SUSPEND);
- break;
- case UHF_PORT_RESET:
- DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n",
- index));
- OWRITE4(sc, port, UPS_RESET);
- for (i = 0; i < 5; i++) {
- usb_delay_ms(&sc->sc_bus,
- USB_PORT_ROOT_RESET_DELAY);
- if (sc->sc_dying) {
- err = USBD_IOERROR;
- goto ret;
- }
- if ((OREAD4(sc, port) & UPS_RESET) == 0)
- break;
- }
- DPRINTFN(8,("ohci port %d reset, status = 0x%04x\n",
- index, OREAD4(sc, port)));
- break;
- case UHF_PORT_POWER:
- DPRINTFN(2,("ohci_root_ctrl_transfer: set port power "
- "%d\n", index));
- OWRITE4(sc, port, UPS_PORT_POWER);
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- xfer->actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
- ret:
- xfer->status = err;
- s = splusb();
- hacksync(xfer); /* XXX to compensate for usb_transfer_complete */
- usb_transfer_complete(xfer);
- splx(s);
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a root control request. */
-static void
-ohci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- /* Nothing to do, all transfers are synchronous. */
-}
-
-/* Close the root pipe. */
-static void
-ohci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(("ohci_root_ctrl_close\n"));
- /* Nothing to do. */
-}
-
-static usbd_status
-ohci_root_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ohci_root_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ohci_root_intr_start(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- sc->sc_intrxfer = xfer;
-
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a root interrupt request. */
-static void
-ohci_root_intr_abort(usbd_xfer_handle xfer)
-{
- int s;
-
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTF(("ohci_root_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
- xfer->status = USBD_CANCELLED;
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
-}
-
-/* Close the root pipe. */
-static void
-ohci_root_intr_close(usbd_pipe_handle pipe)
-{
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
-
- DPRINTF(("ohci_root_intr_close\n"));
-
- sc->sc_intrxfer = NULL;
-}
-
-/************************/
-
-static usbd_status
-ohci_device_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ohci_device_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ohci_device_ctrl_start(usbd_xfer_handle xfer)
-{
- ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST)) {
- /* XXX panic */
- printf("ohci_device_ctrl_transfer: not a request\n");
- return (USBD_INVAL);
- }
-#endif
-
- err = ohci_device_request(xfer);
- if (err)
- return (err);
-
- if (sc->sc_bus.use_polling)
- ohci_waitintr(sc, xfer);
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a device control request. */
-static void
-ohci_device_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer));
- ohci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/* Close a device control pipe. */
-static void
-ohci_device_ctrl_close(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
-
- DPRINTF(("ohci_device_ctrl_close: pipe=%p\n", pipe));
- ohci_close_pipe(pipe, sc->sc_ctrl_head);
- ohci_free_std(sc, opipe->tail.td);
-}
-
-/************************/
-
-static void
-ohci_device_clear_toggle(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
-
- opipe->sed->ed.ed_headp &= htole32(~OHCI_TOGGLECARRY);
-}
-
-static void
-ohci_noop(usbd_pipe_handle pipe)
-{
-}
-
-static usbd_status
-ohci_device_bulk_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ohci_device_bulk_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ohci_device_bulk_start(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- usbd_device_handle dev = opipe->pipe.device;
- ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
- int addr = dev->address;
- ohci_soft_td_t *data, *tail, *tdp;
- ohci_soft_ed_t *sed;
- int s, len, isread, endpt;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST) {
- /* XXX panic */
- printf("ohci_device_bulk_start: a request\n");
- return (USBD_INVAL);
- }
-#endif
-
- len = xfer->length;
- endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- sed = opipe->sed;
-
- DPRINTFN(4,("ohci_device_bulk_start: xfer=%p len=%d isread=%d "
- "flags=%d endpt=%d\n", xfer, len, isread, xfer->flags,
- endpt));
-
- opipe->u.bulk.isread = isread;
- opipe->u.bulk.length = len;
-
- /* Update device address */
- sed->ed.ed_flags = htole32(
- (le32toh(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) |
- OHCI_ED_SET_FA(addr));
-
- /* Allocate a chain of new TDs (including a new tail). */
- data = opipe->tail.td;
- err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer,
- data, &tail);
- /* We want interrupt at the end of the transfer. */
- tail->td.td_flags &= htole32(~OHCI_TD_INTR_MASK);
- tail->td.td_flags |= htole32(OHCI_TD_SET_DI(1));
- tail->flags |= OHCI_CALL_DONE;
- tail = tail->nexttd; /* point at sentinel */
- if (err)
- return (err);
-
- tail->xfer = NULL;
- xfer->hcpriv = data;
-
- DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x "
- "td_cbp=0x%08x td_be=0x%08x\n",
- (int)le32toh(sed->ed.ed_flags),
- (int)le32toh(data->td.td_flags),
- (int)le32toh(data->td.td_cbp),
- (int)le32toh(data->td.td_be)));
-
-#ifdef USB_DEBUG
- if (ohcidebug > 5) {
- ohci_dump_ed(sed);
- ohci_dump_tds(data);
- }
-#endif
-
- /* Insert ED in schedule */
- s = splusb();
- for (tdp = data; tdp != tail; tdp = tdp->nexttd) {
- tdp->xfer = xfer;
- }
- sed->ed.ed_tailp = htole32(tail->physaddr);
- opipe->tail.td = tail;
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ohci_timeout, xfer);
- }
-
-#if 0
-/* This goes wrong if we are too slow. */
- if (ohcidebug > 10) {
- delay(10000);
- DPRINTF(("ohci_device_intr_transfer: status=%x\n",
- OREAD4(sc, OHCI_COMMAND_STATUS)));
- ohci_dump_ed(sed);
- ohci_dump_tds(data);
- }
-#endif
-
- splx(s);
-
- if (sc->sc_bus.use_polling)
- ohci_waitintr(sc, xfer);
-
- return (USBD_IN_PROGRESS);
-}
-
-static void
-ohci_device_bulk_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer));
- ohci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/*
- * Close a device bulk pipe.
- */
-static void
-ohci_device_bulk_close(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
-
- DPRINTF(("ohci_device_bulk_close: pipe=%p\n", pipe));
- ohci_close_pipe(pipe, sc->sc_bulk_head);
- ohci_free_std(sc, opipe->tail.td);
-}
-
-/************************/
-
-static usbd_status
-ohci_device_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ohci_device_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ohci_device_intr_start(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
- ohci_soft_ed_t *sed = opipe->sed;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- DPRINTFN(3, ("ohci_device_intr_start: xfer=%p len=%d "
- "flags=%d priv=%p\n",
- xfer, xfer->length, xfer->flags, xfer->priv));
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("ohci_device_intr_start: a request");
-#endif
-
- err = ohci_device_intr_insert(sc, xfer);
- if (err)
- return (err);
-
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
-
- return (USBD_IN_PROGRESS);
-}
-
-/*
- * Insert an interrupt transfer into an endpoint descriptor list
- */
-static usbd_status
-ohci_device_intr_insert(ohci_softc_t *sc, usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_soft_ed_t *sed = opipe->sed;
- ohci_soft_td_t *data, *tail;
- ohci_physaddr_t dataphys, physend;
- int s;
-
- DPRINTFN(4, ("ohci_device_intr_insert: xfer=%p", xfer));
-
- data = opipe->tail.td;
- tail = ohci_alloc_std(sc);
- if (tail == NULL)
- return (USBD_NOMEM);
- tail->xfer = NULL;
-
- data->td.td_flags = htole32(
- OHCI_TD_IN | OHCI_TD_NOCC |
- OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
- if (xfer->flags & USBD_SHORT_XFER_OK)
- data->td.td_flags |= htole32(OHCI_TD_R);
- /*
- * Assume a short mapping with no complications, which
- * should always be true for <= 4k buffers in contiguous
- * virtual memory. The data can take the following forms:
- * 1 segment in 1 OHCI page
- * 1 segment in 2 OHCI pages
- * 2 segments in 2 OHCI pages
- * (see comment in ohci_alloc_std_chain() for details)
- */
- KASSERT(xfer->length > 0 && xfer->length <= OHCI_PAGE_SIZE,
- ("ohci_device_intr_insert: bad length %d", xfer->length));
- dataphys = xfer->dmamap.segs[0].ds_addr;
- physend = dataphys + xfer->length - 1;
- if (xfer->dmamap.nsegs == 2) {
- KASSERT(OHCI_PAGE_OFFSET(dataphys +
- xfer->dmamap.segs[0].ds_len) == 0,
- ("ohci_device_intr_insert: bad seg 0 termination"));
- physend = xfer->dmamap.segs[1].ds_addr + xfer->length -
- xfer->dmamap.segs[0].ds_len - 1;
- } else {
- KASSERT(xfer->dmamap.nsegs == 1,
- ("ohci_device_intr_insert: bad seg count %d",
- (u_int)xfer->dmamap.nsegs));
- }
- data->td.td_cbp = htole32(dataphys);
- data->nexttd = tail;
- data->td.td_nexttd = htole32(tail->physaddr);
- data->td.td_be = htole32(physend);
- data->len = xfer->length;
- data->xfer = xfer;
- data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
- xfer->hcpriv = data;
- xfer->actlen = 0;
-
-#ifdef USB_DEBUG
- if (ohcidebug > 5) {
- DPRINTF(("ohci_device_intr_insert:\n"));
- ohci_dump_ed(sed);
- ohci_dump_tds(data);
- }
-#endif
-
- /* Insert ED in schedule */
- s = splusb();
- sed->ed.ed_tailp = htole32(tail->physaddr);
- opipe->tail.td = tail;
- splx(s);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-/* Abort a device control request. */
-static void
-ohci_device_intr_abort(usbd_xfer_handle xfer)
-{
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTF(("ohci_device_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
- ohci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/* Close a device interrupt pipe. */
-static void
-ohci_device_intr_close(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
- int nslots = opipe->u.intr.nslots;
- int pos = opipe->u.intr.pos;
- int j;
- ohci_soft_ed_t *p, *sed = opipe->sed;
- int s;
-
- DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n",
- pipe, nslots, pos));
- s = splusb();
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
- if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
- (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK))
- usb_delay_ms(&sc->sc_bus, 2);
-#ifdef DIAGNOSTIC
- if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
- (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK))
- panic("%s: Intr pipe %p still has TDs queued",
- device_get_nameunit(sc->sc_bus.bdev), pipe);
-#endif
-
- for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
- ;
-#ifdef DIAGNOSTIC
- if (p == NULL)
- panic("ohci_device_intr_close: ED not found");
-#endif
- p->next = sed->next;
- p->ed.ed_nexted = sed->ed.ed_nexted;
- splx(s);
-
- for (j = 0; j < nslots; j++)
- --sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS];
-
- ohci_free_std(sc, opipe->tail.td);
- ohci_free_sed(sc, opipe->sed);
-}
-
-static usbd_status
-ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival)
-{
- int i, j, s, best;
- u_int npoll, slow, shigh, nslots;
- u_int bestbw, bw;
- ohci_soft_ed_t *hsed, *sed = opipe->sed;
-
- DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe));
- if (ival == 0) {
- printf("ohci_setintr: 0 interval\n");
- return (USBD_INVAL);
- }
-
- npoll = OHCI_NO_INTRS;
- while (npoll > ival)
- npoll /= 2;
- DPRINTFN(2, ("ohci_setintr: ival=%d npoll=%d\n", ival, npoll));
-
- /*
- * We now know which level in the tree the ED must go into.
- * Figure out which slot has most bandwidth left over.
- * Slots to examine:
- * npoll
- * 1 0
- * 2 1 2
- * 4 3 4 5 6
- * 8 7 8 9 10 11 12 13 14
- * N (N-1) .. (N-1+N-1)
- */
- slow = npoll-1;
- shigh = slow + npoll;
- nslots = OHCI_NO_INTRS / npoll;
- for (best = i = slow, bestbw = ~0; i < shigh; i++) {
- bw = 0;
- for (j = 0; j < nslots; j++)
- bw += sc->sc_bws[(i * nslots + j) % OHCI_NO_INTRS];
- if (bw < bestbw) {
- best = i;
- bestbw = bw;
- }
- }
- DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n",
- best, slow, shigh, bestbw));
-
- s = splusb();
- hsed = sc->sc_eds[best];
- sed->next = hsed->next;
- sed->ed.ed_nexted = hsed->ed.ed_nexted;
- hsed->next = sed;
- hsed->ed.ed_nexted = htole32(sed->physaddr);
- splx(s);
-
- for (j = 0; j < nslots; j++)
- ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS];
- opipe->u.intr.nslots = nslots;
- opipe->u.intr.pos = best;
-
- DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe));
- return (USBD_NORMAL_COMPLETION);
-}
-
-/***********************/
-
-usbd_status
-ohci_device_isoc_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- DPRINTFN(5,("ohci_device_isoc_transfer: xfer=%p\n", xfer));
-
- /* Put it on our queue, */
- err = usb_insert_transfer(xfer);
-
- /* bail out on error, */
- if (err && err != USBD_IN_PROGRESS)
- return (err);
-
- /* XXX should check inuse here */
-
- /* insert into schedule, */
- ohci_device_isoc_enter(xfer);
-
- /* and start if the pipe wasn't running */
- if (!err)
- ohci_device_isoc_start(STAILQ_FIRST(&xfer->pipe->queue));
-
- return (err);
-}
-
-void
-ohci_device_isoc_enter(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- usbd_device_handle dev = opipe->pipe.device;
- ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
- ohci_soft_ed_t *sed = opipe->sed;
- struct iso *iso = &opipe->u.iso;
- struct usb_dma_mapping *dma = &xfer->dmamap;
- ohci_soft_itd_t *sitd, *nsitd;
- ohci_physaddr_t dataphys, bp0, physend, prevpage;
- int curlen, i, len, ncur, nframes, npages, seg, segoff;
- int s;
-
- DPRINTFN(1,("ohci_device_isoc_enter: used=%d next=%d xfer=%p "
- "nframes=%d\n",
- iso->inuse, iso->next, xfer, xfer->nframes));
-
- if (sc->sc_dying)
- return;
-
- if (iso->next == -1) {
- /* Not in use yet, schedule it a few frames ahead. */
- iso->next = le32toh(sc->sc_hcca->hcca_frame_number) + 5;
- DPRINTFN(2,("ohci_device_isoc_enter: start next=%d\n",
- iso->next));
- }
-
- sitd = opipe->tail.itd;
- nframes = xfer->nframes;
- xfer->hcpriv = sitd;
- seg = 0;
- segoff = 0;
- i = 0;
- while (i < nframes) {
- /*
- * Fill in as many ITD frames as possible.
- */
- KASSERT(seg < dma->nsegs, ("ohci_device_isoc_enter: overrun"));
- bp0 = dma->segs[seg].ds_addr + segoff;
- sitd->itd.itd_bp0 = htole32(bp0);
- prevpage = OHCI_PAGE(bp0);
- npages = 1;
-
- ncur = 0;
- while (ncur < OHCI_ITD_NOFFSET && i < nframes) {
- /* Find the frame start and end physical addresses. */
- len = xfer->frlengths[i];
- dataphys = dma->segs[seg].ds_addr + segoff;
- curlen = dma->segs[seg].ds_len - segoff;
- if (len > curlen) {
- KASSERT(seg + 1 < dma->nsegs,
- ("ohci_device_isoc_enter: overrun2"));
- seg++;
- segoff = len - curlen;
- } else {
- segoff += len;
- }
- KASSERT(segoff <= dma->segs[seg].ds_len,
- ("ohci_device_isoc_enter: overrun3"));
- physend = dma->segs[seg].ds_addr + segoff - 1;
-
- /* Check if there would be more than 2 pages . */
- if (OHCI_PAGE(dataphys) != prevpage) {
- prevpage = OHCI_PAGE(dataphys);
- npages++;
- }
- if (OHCI_PAGE(physend) != prevpage) {
- prevpage = OHCI_PAGE(physend);
- npages++;
- }
- if (npages > 2) {
- /* We cannot fit this frame now. */
- segoff -= len;
- if (segoff < 0) {
- seg--;
- segoff += dma->segs[seg].ds_len;
- }
- break;
- }
-
- sitd->itd.itd_be = htole32(physend);
- sitd->itd.itd_offset[ncur] =
- htole16(OHCI_ITD_MK_OFFS(OHCI_PAGE(dataphys) ==
- OHCI_PAGE(bp0) ? 0 : 1, dataphys));
- i++;
- ncur++;
- }
- if (segoff >= dma->segs[seg].ds_len) {
- KASSERT(segoff == dma->segs[seg].ds_len,
- ("ohci_device_isoc_enter: overlap"));
- seg++;
- segoff = 0;
- }
-
- /* Allocate next ITD */
- nsitd = ohci_alloc_sitd(sc);
- if (nsitd == NULL) {
- /* XXX what now? */
- printf("%s: isoc TD alloc failed\n",
- device_get_nameunit(sc->sc_bus.bdev));
- return;
- }
-
- /* Fill out remaining fields of current ITD */
- sitd->nextitd = nsitd;
- sitd->itd.itd_nextitd = htole32(nsitd->physaddr);
- sitd->xfer = xfer;
- if (i < nframes) {
- sitd->itd.itd_flags = htole32(
- OHCI_ITD_NOCC |
- OHCI_ITD_SET_SF(iso->next) |
- OHCI_ITD_SET_DI(6) | /* delay intr a little */
- OHCI_ITD_SET_FC(ncur));
- sitd->flags = OHCI_ITD_ACTIVE;
- } else {
- sitd->itd.itd_flags = htole32(
- OHCI_ITD_NOCC |
- OHCI_ITD_SET_SF(iso->next) |
- OHCI_ITD_SET_DI(0) |
- OHCI_ITD_SET_FC(ncur));
- sitd->flags = OHCI_CALL_DONE | OHCI_ITD_ACTIVE;
- }
- iso->next += ncur;
-
- sitd = nsitd;
- }
-
- iso->inuse += nframes;
-
- /* XXX pretend we did it all */
- xfer->actlen = 0;
- for (i = 0; i < nframes; i++)
- xfer->actlen += xfer->frlengths[i];
-
- xfer->status = USBD_IN_PROGRESS;
-
-#ifdef USB_DEBUG
- if (ohcidebug > 5) {
- DPRINTF(("ohci_device_isoc_enter: frame=%d\n",
- le32toh(sc->sc_hcca->hcca_frame_number)));
- ohci_dump_itds(xfer->hcpriv);
- ohci_dump_ed(sed);
- }
-#endif
-
- s = splusb();
- opipe->tail.itd = sitd;
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
- sed->ed.ed_tailp = htole32(sitd->physaddr);
- splx(s);
-
-#ifdef USB_DEBUG
- if (ohcidebug > 5) {
- delay(150000);
- DPRINTF(("ohci_device_isoc_enter: after frame=%d\n",
- le32toh(sc->sc_hcca->hcca_frame_number)));
- ohci_dump_itds(xfer->hcpriv);
- ohci_dump_ed(sed);
- }
-#endif
-}
-
-usbd_status
-ohci_device_isoc_start(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
- ohci_soft_ed_t *sed;
- int s;
-
- DPRINTFN(5,("ohci_device_isoc_start: xfer=%p\n", xfer));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (xfer->status != USBD_IN_PROGRESS)
- printf("ohci_device_isoc_start: not in progress %p\n", xfer);
-#endif
-
- /* XXX anything to do? */
-
- s = splusb();
- sed = opipe->sed; /* Turn off ED skip-bit to start processing */
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* ED's ITD list.*/
- splx(s);
-
- return (USBD_IN_PROGRESS);
-}
-
-void
-ohci_device_isoc_abort(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
- ohci_soft_ed_t *sed;
- ohci_soft_itd_t *sitd, *sitdnext, *tmp_sitd;
- int s,undone,num_sitds;
-
- s = splusb();
- opipe->aborting = 1;
-
- DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer));
-
- /* Transfer is already done. */
- if (xfer->status != USBD_NOT_STARTED &&
- xfer->status != USBD_IN_PROGRESS) {
- splx(s);
- printf("ohci_device_isoc_abort: early return\n");
- return;
- }
-
- /* Give xfer the requested abort code. */
- xfer->status = USBD_CANCELLED;
-
- sed = opipe->sed;
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */
-
- num_sitds = 0;
- sitd = xfer->hcpriv;
-#ifdef DIAGNOSTIC
- if (sitd == NULL) {
- splx(s);
- printf("ohci_device_isoc_abort: hcpriv==0\n");
- return;
- }
-#endif
- for (; sitd != NULL && sitd->xfer == xfer; sitd = sitd->nextitd) {
- num_sitds++;
-#ifdef DIAGNOSTIC
- DPRINTFN(1,("abort sets done sitd=%p\n", sitd));
- sitd->isdone = 1;
-#endif
- }
-
- splx(s);
-
- /*
- * Each sitd has up to OHCI_ITD_NOFFSET transfers, each can
- * take a usb 1ms cycle. Conservatively wait for it to drain.
- * Even with DMA done, it can take awhile for the "batch"
- * delivery of completion interrupts to occur thru the controller.
- */
-
- do {
- usb_delay_ms(&sc->sc_bus, 2*(num_sitds*OHCI_ITD_NOFFSET));
-
- undone = 0;
- tmp_sitd = xfer->hcpriv;
- for (; tmp_sitd != NULL && tmp_sitd->xfer == xfer;
- tmp_sitd = tmp_sitd->nextitd) {
- if (OHCI_CC_NO_ERROR ==
- OHCI_ITD_GET_CC(le32toh(tmp_sitd->itd.itd_flags)) &&
- tmp_sitd->flags & OHCI_ITD_ACTIVE &&
- (tmp_sitd->flags & OHCI_ITD_INTFIN) == 0)
- undone++;
- }
- } while( undone != 0 );
-
- /* Free the sitds */
- for (sitd = xfer->hcpriv; sitd->xfer == xfer;
- sitd = sitdnext) {
- sitdnext = sitd->nextitd;
- ohci_free_sitd(sc, sitd);
- }
-
- s = splusb();
-
- /* Run callback. */
- usb_transfer_complete(xfer);
-
- /* There is always a `next' sitd so link it up. */
- sed->ed.ed_headp = htole32(sitd->physaddr);
-
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */
-
- splx(s);
-}
-
-void
-ohci_device_isoc_done(usbd_xfer_handle xfer)
-{
- /* This null routine corresponds to non-isoc "done()" routines
- * that free the stds associated with an xfer after a completed
- * xfer interrupt. However, in the case of isoc transfers, the
- * sitds associated with the transfer have already been processed
- * and reallocated for the next iteration by
- * "ohci_device_isoc_transfer()".
- *
- * Routine "usb_transfer_complete()" is called at the end of every
- * relevant usb interrupt. "usb_transfer_complete()" indirectly
- * calls 1) "ohci_device_isoc_transfer()" (which keeps pumping the
- * pipeline by setting up the next transfer iteration) and 2) then
- * calls "ohci_device_isoc_done()". Isoc transfers have not been
- * working for the ohci usb because this routine was trashing the
- * xfer set up for the next iteration (thus, only the first
- * UGEN_NISOREQS xfers outstanding on an open would work). Perhaps
- * this could all be re-factored, but that's another pass...
- */
-}
-
-usbd_status
-ohci_setup_isoc(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
- struct iso *iso = &opipe->u.iso;
- int s;
-
- iso->next = -1;
- iso->inuse = 0;
-
- s = splusb();
- ohci_add_ed(opipe->sed, sc->sc_isoc_head);
- splx(s);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-void
-ohci_device_isoc_close(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
- ohci_soft_ed_t *sed;
-
- DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe));
-
- sed = opipe->sed;
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* Stop device. */
-
- ohci_close_pipe(pipe, sc->sc_isoc_head); /* Stop isoc list, free ED.*/
-
- /* up to NISOREQs xfers still outstanding. */
-
-#ifdef DIAGNOSTIC
- opipe->tail.itd->isdone = 1;
-#endif
- ohci_free_sitd(sc, opipe->tail.itd); /* Next `avail free' sitd.*/
-}
diff --git a/sys/legacy/dev/usb/ohci_pci.c b/sys/legacy/dev/usb/ohci_pci.c
deleted file mode 100644
index efba469..0000000
--- a/sys/legacy/dev/usb/ohci_pci.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (augustss@carlstedt.se) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * USB Open Host Controller driver.
- *
- * OHCI spec: http://www.intel.com/design/usb/ohci11d.pdf
- */
-
-/* The low level controller code for OHCI has been split into
- * PCI probes and OHCI specific code. This was done to facilitate the
- * sharing of code between *BSD's
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/queue.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <machine/resource.h>
-
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcireg.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-
-#include <dev/usb/ohcireg.h>
-#include <dev/usb/ohcivar.h>
-
-#define PCI_OHCI_VENDORID_ACERLABS 0x10b9
-#define PCI_OHCI_VENDORID_AMD 0x1022
-#define PCI_OHCI_VENDORID_APPLE 0x106b
-#define PCI_OHCI_VENDORID_ATI 0x1002
-#define PCI_OHCI_VENDORID_CMDTECH 0x1095
-#define PCI_OHCI_VENDORID_NEC 0x1033
-#define PCI_OHCI_VENDORID_NVIDIA 0x12D2
-#define PCI_OHCI_VENDORID_NVIDIA2 0x10DE
-#define PCI_OHCI_VENDORID_OPTI 0x1045
-#define PCI_OHCI_VENDORID_SIS 0x1039
-#define PCI_OHCI_VENDORID_SUN 0x108e
-
-#define PCI_OHCI_DEVICEID_ALADDIN_V 0x523710b9
-static const char *ohci_device_aladdin_v = "AcerLabs M5237 (Aladdin-V) USB controller";
-
-#define PCI_OHCI_DEVICEID_AMD756 0x740c1022
-static const char *ohci_device_amd756 = "AMD-756 USB Controller";
-
-#define PCI_OHCI_DEVICEID_AMD766 0x74141022
-static const char *ohci_device_amd766 = "AMD-766 USB Controller";
-
-#define PCI_OHCI_DEVICEID_SB400_1 0x43741002
-#define PCI_OHCI_DEVICEID_SB400_2 0x43751002
-static const char *ohci_device_sb400 = "ATI SB400 USB Controller";
-
-#define PCI_OHCI_DEVICEID_FIRELINK 0xc8611045
-static const char *ohci_device_firelink = "OPTi 82C861 (FireLink) USB controller";
-
-#define PCI_OHCI_DEVICEID_NEC 0x00351033
-static const char *ohci_device_nec = "NEC uPD 9210 USB controller";
-
-#define PCI_OHCI_DEVICEID_NFORCE3 0x00d710de
-static const char *ohci_device_nforce3 = "nVidia nForce3 USB Controller";
-
-#define PCI_OHCI_DEVICEID_USB0670 0x06701095
-static const char *ohci_device_usb0670 = "CMD Tech 670 (USB0670) USB controller";
-
-#define PCI_OHCI_DEVICEID_USB0673 0x06731095
-static const char *ohci_device_usb0673 = "CMD Tech 673 (USB0673) USB controller";
-
-#define PCI_OHCI_DEVICEID_SIS5571 0x70011039
-static const char *ohci_device_sis5571 = "SiS 5571 USB controller";
-
-#define PCI_OHCI_DEVICEID_KEYLARGO 0x0019106b
-static const char *ohci_device_keylargo = "Apple KeyLargo USB controller";
-
-#define PCI_OHCI_DEVICEID_PCIO2USB 0x1103108e
-static const char *ohci_device_pcio2usb = "Sun PCIO-2 USB controller";
-
-static const char *ohci_device_generic = "OHCI (generic) USB controller";
-
-#define PCI_OHCI_BASE_REG 0x10
-
-
-static device_attach_t ohci_pci_attach;
-static device_detach_t ohci_pci_detach;
-static device_suspend_t ohci_pci_suspend;
-static device_resume_t ohci_pci_resume;
-
-static int
-ohci_pci_suspend(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return err;
- ohci_power(PWR_SUSPEND, sc);
-
- return 0;
-}
-
-static int
-ohci_pci_resume(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
-
- ohci_power(PWR_RESUME, sc);
- bus_generic_resume(self);
-
- return 0;
-}
-
-static const char *
-ohci_pci_match(device_t self)
-{
- u_int32_t device_id = pci_get_devid(self);
-
- switch (device_id) {
- case PCI_OHCI_DEVICEID_ALADDIN_V:
- return (ohci_device_aladdin_v);
- case PCI_OHCI_DEVICEID_AMD756:
- return (ohci_device_amd756);
- case PCI_OHCI_DEVICEID_AMD766:
- return (ohci_device_amd766);
- case PCI_OHCI_DEVICEID_SB400_1:
- case PCI_OHCI_DEVICEID_SB400_2:
- return (ohci_device_sb400);
- case PCI_OHCI_DEVICEID_USB0670:
- return (ohci_device_usb0670);
- case PCI_OHCI_DEVICEID_USB0673:
- return (ohci_device_usb0673);
- case PCI_OHCI_DEVICEID_FIRELINK:
- return (ohci_device_firelink);
- case PCI_OHCI_DEVICEID_NEC:
- return (ohci_device_nec);
- case PCI_OHCI_DEVICEID_NFORCE3:
- return (ohci_device_nforce3);
- case PCI_OHCI_DEVICEID_SIS5571:
- return (ohci_device_sis5571);
- case PCI_OHCI_DEVICEID_KEYLARGO:
- return (ohci_device_keylargo);
- case PCI_OHCI_DEVICEID_PCIO2USB:
- return (ohci_device_pcio2usb);
- default:
- if (pci_get_class(self) == PCIC_SERIALBUS
- && pci_get_subclass(self) == PCIS_SERIALBUS_USB
- && pci_get_progif(self) == PCI_INTERFACE_OHCI) {
- return (ohci_device_generic);
- }
- }
-
- return NULL; /* dunno */
-}
-
-static int
-ohci_pci_probe(device_t self)
-{
- const char *desc = ohci_pci_match(self);
-
- if (desc) {
- device_set_desc(self, desc);
- return BUS_PROBE_DEFAULT;
- } else {
- return ENXIO;
- }
-}
-
-static int
-ohci_pci_attach(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
- int err;
- int rid;
-
- /* XXX where does it say so in the spec? */
- sc->sc_bus.usbrev = USBREV_1_0;
-
- pci_enable_busmaster(self);
-
- /*
- * Some Sun PCIO-2 USB controllers have their intpin register
- * bogusly set to 0, although it should be 4. Correct that.
- */
- if (pci_get_devid(self) == PCI_OHCI_DEVICEID_PCIO2USB &&
- pci_get_intpin(self) == 0)
- pci_set_intpin(self, 4);
-
- rid = PCI_CBMEM;
- sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
- if (!sc->io_res) {
- device_printf(self, "Could not map memory\n");
- return ENXIO;
- }
- sc->iot = rman_get_bustag(sc->io_res);
- sc->ioh = rman_get_bushandle(sc->io_res);
-
- rid = 0;
- sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- ohci_pci_detach(self);
- return ENXIO;
- }
- sc->sc_bus.bdev = device_add_child(self, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- ohci_pci_detach(self);
- return ENOMEM;
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-
- /* ohci_pci_match will never return NULL if ohci_pci_probe succeeded */
- device_set_desc(sc->sc_bus.bdev, ohci_pci_match(self));
- switch (pci_get_vendor(self)) {
- case PCI_OHCI_VENDORID_ACERLABS:
- sprintf(sc->sc_vendor, "AcerLabs");
- break;
- case PCI_OHCI_VENDORID_AMD:
- sprintf(sc->sc_vendor, "AMD");
- break;
- case PCI_OHCI_VENDORID_APPLE:
- sprintf(sc->sc_vendor, "Apple");
- break;
- case PCI_OHCI_VENDORID_ATI:
- sprintf(sc->sc_vendor, "ATI");
- break;
- case PCI_OHCI_VENDORID_CMDTECH:
- sprintf(sc->sc_vendor, "CMDTECH");
- break;
- case PCI_OHCI_VENDORID_NEC:
- sprintf(sc->sc_vendor, "NEC");
- break;
- case PCI_OHCI_VENDORID_NVIDIA:
- case PCI_OHCI_VENDORID_NVIDIA2:
- sprintf(sc->sc_vendor, "nVidia");
- break;
- case PCI_OHCI_VENDORID_OPTI:
- sprintf(sc->sc_vendor, "OPTi");
- break;
- case PCI_OHCI_VENDORID_SIS:
- sprintf(sc->sc_vendor, "SiS");
- break;
- default:
- if (bootverbose)
- device_printf(self, "(New OHCI DeviceId=0x%08x)\n",
- pci_get_devid(self));
- sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
- }
-
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO, NULL, ohci_intr,
- sc, &sc->ih);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->ih = NULL;
- ohci_pci_detach(self);
- return ENXIO;
- }
-
- /* Allocate a parent dma tag for DMA maps */
- err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- NULL, NULL, &sc->sc_bus.parent_dmatag);
- if (err) {
- device_printf(self, "Could not allocate parent DMA tag (%d)\n",
- err);
- ohci_pci_detach(self);
- return ENXIO;
- }
- /* Allocate a dma tag for transfer buffers */
- err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
- if (err) {
- device_printf(self, "Could not allocate transfer tag (%d)\n",
- err);
- ohci_pci_detach(self);
- return ENXIO;
- }
-
- err = ohci_init(sc);
- if (!err) {
- sc->sc_flags |= OHCI_SCFLG_DONEINIT;
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
-
- if (err) {
- device_printf(self, "USB init failed\n");
- ohci_pci_detach(self);
- return EIO;
- }
- return 0;
-}
-
-static int
-ohci_pci_detach(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
-
- if (sc->sc_flags & OHCI_SCFLG_DONEINIT) {
- ohci_detach(sc, 0);
- sc->sc_flags &= ~OHCI_SCFLG_DONEINIT;
- }
-
- if (sc->sc_bus.parent_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
- if (sc->sc_bus.buffer_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
-
- if (sc->irq_res && sc->ih) {
- int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
-
- if (err)
- /* XXX or should we panic? */
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->ih = NULL;
- }
- if (sc->sc_bus.bdev) {
- device_delete_child(self, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
- }
- if (sc->irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
- sc->irq_res = NULL;
- }
- if (sc->io_res) {
- bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM,
- sc->io_res);
- sc->io_res = NULL;
- sc->iot = 0;
- sc->ioh = 0;
- }
- return 0;
-}
-
-static device_method_t ohci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ohci_pci_probe),
- DEVMETHOD(device_attach, ohci_pci_attach),
- DEVMETHOD(device_detach, ohci_pci_detach),
- DEVMETHOD(device_suspend, ohci_pci_suspend),
- DEVMETHOD(device_resume, ohci_pci_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t ohci_driver = {
- "ohci",
- ohci_methods,
- sizeof(ohci_softc_t),
-};
-
-static devclass_t ohci_devclass;
-
-DRIVER_MODULE(ohci, pci, ohci_driver, ohci_devclass, 0, 0);
-MODULE_DEPEND(ohci, usb, 1, 1, 1);
diff --git a/sys/legacy/dev/usb/ohcireg.h b/sys/legacy/dev/usb/ohcireg.h
deleted file mode 100644
index 429beb8..0000000
--- a/sys/legacy/dev/usb/ohcireg.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/* $NetBSD: ohcireg.h,v 1.17 2000/04/01 09:27:35 augustss Exp $ */
-/* $FreeBSD$ */
-
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DEV_PCI_OHCIREG_H_
-#define _DEV_PCI_OHCIREG_H_
-
-/*** PCI config registers ***/
-
-#define PCI_CBMEM 0x10 /* configuration base memory */
-
-#define PCI_INTERFACE_OHCI 0x10
-
-/*** OHCI registers */
-
-#define OHCI_REVISION 0x00 /* OHCI revision # */
-#define OHCI_REV_LO(rev) ((rev)&0xf)
-#define OHCI_REV_HI(rev) (((rev)>>4)&0xf)
-#define OHCI_REV_LEGACY(rev) ((rev) & 0x100)
-
-#define OHCI_CONTROL 0x04
-#define OHCI_CBSR_MASK 0x00000003 /* Control/Bulk Service Ratio */
-#define OHCI_RATIO_1_1 0x00000000
-#define OHCI_RATIO_1_2 0x00000001
-#define OHCI_RATIO_1_3 0x00000002
-#define OHCI_RATIO_1_4 0x00000003
-#define OHCI_PLE 0x00000004 /* Periodic List Enable */
-#define OHCI_IE 0x00000008 /* Isochronous Enable */
-#define OHCI_CLE 0x00000010 /* Control List Enable */
-#define OHCI_BLE 0x00000020 /* Bulk List Enable */
-#define OHCI_HCFS_MASK 0x000000c0 /* HostControllerFunctionalState */
-#define OHCI_HCFS_RESET 0x00000000
-#define OHCI_HCFS_RESUME 0x00000040
-#define OHCI_HCFS_OPERATIONAL 0x00000080
-#define OHCI_HCFS_SUSPEND 0x000000c0
-#define OHCI_IR 0x00000100 /* Interrupt Routing */
-#define OHCI_RWC 0x00000200 /* Remote Wakeup Connected */
-#define OHCI_RWE 0x00000400 /* Remote Wakeup Enabled */
-#define OHCI_COMMAND_STATUS 0x08
-#define OHCI_HCR 0x00000001 /* Host Controller Reset */
-#define OHCI_CLF 0x00000002 /* Control List Filled */
-#define OHCI_BLF 0x00000004 /* Bulk List Filled */
-#define OHCI_OCR 0x00000008 /* Ownership Change Request */
-#define OHCI_SOC_MASK 0x00030000 /* Scheduling Overrun Count */
-#define OHCI_INTERRUPT_STATUS 0x0c
-#define OHCI_SO 0x00000001 /* Scheduling Overrun */
-#define OHCI_WDH 0x00000002 /* Writeback Done Head */
-#define OHCI_SF 0x00000004 /* Start of Frame */
-#define OHCI_RD 0x00000008 /* Resume Detected */
-#define OHCI_UE 0x00000010 /* Unrecoverable Error */
-#define OHCI_FNO 0x00000020 /* Frame Number Overflow */
-#define OHCI_RHSC 0x00000040 /* Root Hub Status Change */
-#define OHCI_OC 0x40000000 /* Ownership Change */
-#define OHCI_MIE 0x80000000 /* Master Interrupt Enable */
-#define OHCI_INTERRUPT_ENABLE 0x10
-#define OHCI_INTERRUPT_DISABLE 0x14
-#define OHCI_HCCA 0x18
-#define OHCI_PERIOD_CURRENT_ED 0x1c
-#define OHCI_CONTROL_HEAD_ED 0x20
-#define OHCI_CONTROL_CURRENT_ED 0x24
-#define OHCI_BULK_HEAD_ED 0x28
-#define OHCI_BULK_CURRENT_ED 0x2c
-#define OHCI_DONE_HEAD 0x30
-#define OHCI_FM_INTERVAL 0x34
-#define OHCI_GET_IVAL(s) ((s) & 0x3fff)
-#define OHCI_GET_FSMPS(s) (((s) >> 16) & 0x7fff)
-#define OHCI_FIT 0x80000000
-#define OHCI_FM_REMAINING 0x38
-#define OHCI_FM_NUMBER 0x3c
-#define OHCI_PERIODIC_START 0x40
-#define OHCI_LS_THRESHOLD 0x44
-#define OHCI_RH_DESCRIPTOR_A 0x48
-#define OHCI_GET_NDP(s) ((s) & 0xff)
-#define OHCI_PSM 0x0100 /* Power Switching Mode */
-#define OHCI_NPS 0x0200 /* No Power Switching */
-#define OHCI_DT 0x0400 /* Device Type */
-#define OHCI_OCPM 0x0800 /* Overcurrent Protection Mode */
-#define OHCI_NOCP 0x1000 /* No Overcurrent Protection */
-#define OHCI_GET_POTPGT(s) ((s) >> 24)
-#define OHCI_RH_DESCRIPTOR_B 0x4c
-#define OHCI_RH_STATUS 0x50
-#define OHCI_LPS 0x00000001 /* Local Power Status */
-#define OHCI_OCI 0x00000002 /* OverCurrent Indicator */
-#define OHCI_DRWE 0x00008000 /* Device Remote Wakeup Enable */
-#define OHCI_LPSC 0x00010000 /* Local Power Status Change */
-#define OHCI_CCIC 0x00020000 /* OverCurrent Indicator Change */
-#define OHCI_CRWE 0x80000000 /* Clear Remote Wakeup Enable */
-#define OHCI_RH_PORT_STATUS(n) (0x50 + (n)*4) /* 1 based indexing */
-
-#define OHCI_LES (OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE)
-#define OHCI_ALL_INTRS (OHCI_SO | OHCI_WDH | OHCI_SF | OHCI_RD | OHCI_UE | \
- OHCI_FNO | OHCI_RHSC | OHCI_OC)
-#define OHCI_NORMAL_INTRS (OHCI_WDH | OHCI_RD | OHCI_UE | OHCI_RHSC)
-
-#define OHCI_FSMPS(i) (((i-210)*6/7) << 16)
-#define OHCI_PERIODIC(i) ((i)*9/10)
-
-typedef u_int32_t ohci_physaddr_t;
-
-#define OHCI_NO_INTRS 32
-struct ohci_hcca {
- ohci_physaddr_t hcca_interrupt_table[OHCI_NO_INTRS];
- u_int32_t hcca_frame_number;
- ohci_physaddr_t hcca_done_head;
-#define OHCI_DONE_INTRS 1
-};
-#define OHCI_HCCA_SIZE 256
-#define OHCI_HCCA_ALIGN 256
-
-#define OHCI_PAGE_SIZE 0x1000
-#define OHCI_PAGE(x) ((x) &~ 0xfff)
-#define OHCI_PAGE_OFFSET(x) ((x) & 0xfff)
-#define OHCI_PAGE_MASK(x) ((x) & 0xfff)
-
-typedef struct {
- u_int32_t ed_flags;
-#define OHCI_ED_GET_FA(s) ((s) & 0x7f)
-#define OHCI_ED_ADDRMASK 0x0000007f
-#define OHCI_ED_SET_FA(s) (s)
-#define OHCI_ED_GET_EN(s) (((s) >> 7) & 0xf)
-#define OHCI_ED_SET_EN(s) ((s) << 7)
-#define OHCI_ED_DIR_MASK 0x00001800
-#define OHCI_ED_DIR_TD 0x00000000
-#define OHCI_ED_DIR_OUT 0x00000800
-#define OHCI_ED_DIR_IN 0x00001000
-#define OHCI_ED_SPEED 0x00002000
-#define OHCI_ED_SKIP 0x00004000
-#define OHCI_ED_FORMAT_GEN 0x00000000
-#define OHCI_ED_FORMAT_ISO 0x00008000
-#define OHCI_ED_GET_MAXP(s) (((s) >> 16) & 0x07ff)
-#define OHCI_ED_SET_MAXP(s) ((s) << 16)
-#define OHCI_ED_MAXPMASK (0x7ff << 16)
- ohci_physaddr_t ed_tailp;
- ohci_physaddr_t ed_headp;
-#define OHCI_HALTED 0x00000001
-#define OHCI_TOGGLECARRY 0x00000002
-#define OHCI_HEADMASK 0xfffffffc
- ohci_physaddr_t ed_nexted;
-} ohci_ed_t;
-/* #define OHCI_ED_SIZE 16 */
-#define OHCI_ED_ALIGN 16
-
-typedef struct {
- u_int32_t td_flags;
-#define OHCI_TD_R 0x00040000 /* Buffer Rounding */
-#define OHCI_TD_DP_MASK 0x00180000 /* Direction / PID */
-#define OHCI_TD_SETUP 0x00000000
-#define OHCI_TD_OUT 0x00080000
-#define OHCI_TD_IN 0x00100000
-#define OHCI_TD_GET_DI(x) (((x) >> 21) & 7) /* Delay Interrupt */
-#define OHCI_TD_SET_DI(x) ((x) << 21)
-#define OHCI_TD_NOINTR 0x00e00000
-#define OHCI_TD_INTR_MASK 0x00e00000
-#define OHCI_TD_TOGGLE_CARRY 0x00000000
-#define OHCI_TD_TOGGLE_0 0x02000000
-#define OHCI_TD_TOGGLE_1 0x03000000
-#define OHCI_TD_TOGGLE_MASK 0x03000000
-#define OHCI_TD_GET_EC(x) (((x) >> 26) & 3) /* Error Count */
-#define OHCI_TD_GET_CC(x) ((x) >> 28) /* Condition Code */
-#define OHCI_TD_NOCC 0xf0000000
- ohci_physaddr_t td_cbp; /* Current Buffer Pointer */
- ohci_physaddr_t td_nexttd; /* Next TD */
- ohci_physaddr_t td_be; /* Buffer End */
-} ohci_td_t;
-/* #define OHCI_TD_SIZE 16 */
-#define OHCI_TD_ALIGN 16
-
-#define OHCI_ITD_NOFFSET 8
-typedef struct {
- u_int32_t itd_flags;
-#define OHCI_ITD_GET_SF(x) ((x) & 0x0000ffff)
-#define OHCI_ITD_SET_SF(x) ((x) & 0xffff)
-#define OHCI_ITD_GET_DI(x) (((x) >> 21) & 7) /* Delay Interrupt */
-#define OHCI_ITD_SET_DI(x) ((x) << 21)
-#define OHCI_ITD_NOINTR 0x00e00000
-#define OHCI_ITD_GET_FC(x) ((((x) >> 24) & 7)+1) /* Frame Count */
-#define OHCI_ITD_SET_FC(x) (((x)-1) << 24)
-#define OHCI_ITD_GET_CC(x) ((x) >> 28) /* Condition Code */
-#define OHCI_ITD_NOCC 0xf0000000
- ohci_physaddr_t itd_bp0; /* Buffer Page 0 */
- ohci_physaddr_t itd_nextitd; /* Next ITD */
- ohci_physaddr_t itd_be; /* Buffer End */
- u_int16_t itd_offset[OHCI_ITD_NOFFSET]; /* Buffer offsets */
-#define itd_pswn itd_offset /* Packet Status Word*/
-#define OHCI_ITD_PAGE_SELECT 0x00001000
-#define OHCI_ITD_MK_OFFS(page, off) \
- (0xe000 | ((page) ? OHCI_ITD_PAGE_SELECT : 0) | ((off) & 0xfff))
-#define OHCI_ITD_PSW_LENGTH(x) ((x) & 0xfff) /* Transfer length */
-#define OHCI_ITD_PSW_GET_CC(x) ((x) >> 12) /* Condition Code */
-} ohci_itd_t;
-/* #define OHCI_ITD_SIZE 32 */
-#define OHCI_ITD_ALIGN 32
-
-
-#define OHCI_CC_NO_ERROR 0
-#define OHCI_CC_CRC 1
-#define OHCI_CC_BIT_STUFFING 2
-#define OHCI_CC_DATA_TOGGLE_MISMATCH 3
-#define OHCI_CC_STALL 4
-#define OHCI_CC_DEVICE_NOT_RESPONDING 5
-#define OHCI_CC_PID_CHECK_FAILURE 6
-#define OHCI_CC_UNEXPECTED_PID 7
-#define OHCI_CC_DATA_OVERRUN 8
-#define OHCI_CC_DATA_UNDERRUN 9
-#define OHCI_CC_BUFFER_OVERRUN 12
-#define OHCI_CC_BUFFER_UNDERRUN 13
-#define OHCI_CC_NOT_ACCESSED 15
-
-/* Some delay needed when changing certain registers. */
-#define OHCI_ENABLE_POWER_DELAY 5
-#define OHCI_READ_DESC_DELAY 5
-
-#endif /* _DEV_PCI_OHCIREG_H_ */
diff --git a/sys/legacy/dev/usb/ohcivar.h b/sys/legacy/dev/usb/ohcivar.h
deleted file mode 100644
index 48f99e7..0000000
--- a/sys/legacy/dev/usb/ohcivar.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/* $NetBSD: ohcivar.h,v 1.30 2001/12/31 12:20:35 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-typedef struct ohci_soft_ed {
- ohci_ed_t ed;
- struct ohci_soft_ed *next;
- ohci_physaddr_t physaddr;
-} ohci_soft_ed_t;
-#define OHCI_SED_SIZE ((sizeof (struct ohci_soft_ed) + OHCI_ED_ALIGN - 1) / OHCI_ED_ALIGN * OHCI_ED_ALIGN)
-#define OHCI_SED_CHUNK (PAGE_SIZE / OHCI_SED_SIZE)
-
-typedef struct ohci_soft_td {
- ohci_td_t td;
- struct ohci_soft_td *nexttd; /* mirrors nexttd in TD */
- struct ohci_soft_td *dnext; /* next in done list */
- ohci_physaddr_t physaddr;
- LIST_ENTRY(ohci_soft_td) hnext;
- usbd_xfer_handle xfer;
- u_int16_t len;
- u_int16_t flags;
-#define OHCI_CALL_DONE 0x0001
-#define OHCI_ADD_LEN 0x0002
-} ohci_soft_td_t;
-#define OHCI_STD_SIZE ((sizeof (struct ohci_soft_td) + OHCI_TD_ALIGN - 1) / OHCI_TD_ALIGN * OHCI_TD_ALIGN)
-#define OHCI_STD_CHUNK (PAGE_SIZE / OHCI_STD_SIZE)
-
-typedef struct ohci_soft_itd {
- ohci_itd_t itd;
- struct ohci_soft_itd *nextitd; /* mirrors nexttd in ITD */
- struct ohci_soft_itd *dnext; /* next in done list */
- ohci_physaddr_t physaddr;
- LIST_ENTRY(ohci_soft_itd) hnext;
- usbd_xfer_handle xfer;
- u_int16_t flags;
-#define OHCI_ITD_ACTIVE 0x0010 /* Hardware op in progress */
-#define OHCI_ITD_INTFIN 0x0020 /* Hw completion interrupt seen.*/
-#ifdef DIAGNOSTIC
- char isdone;
-#endif
-} ohci_soft_itd_t;
-#define OHCI_SITD_SIZE ((sizeof (struct ohci_soft_itd) + OHCI_ITD_ALIGN - 1) / OHCI_ITD_ALIGN * OHCI_ITD_ALIGN)
-#define OHCI_SITD_CHUNK (PAGE_SIZE / OHCI_SITD_SIZE)
-
-#define OHCI_NO_EDS (2*OHCI_NO_INTRS-1)
-
-#define OHCI_HASH_SIZE 128
-
-#define OHCI_SCFLG_DONEINIT 0x0001 /* ohci_init() done. */
-
-typedef struct ohci_softc {
- struct usbd_bus sc_bus; /* base device */
- int sc_flags;
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
- bus_size_t sc_size;
-
- void *ih;
-
- struct resource *io_res;
- struct resource *irq_res;
-
- usb_dma_t sc_hccadma;
- struct ohci_hcca *sc_hcca;
- ohci_soft_ed_t *sc_eds[OHCI_NO_EDS];
- u_int sc_bws[OHCI_NO_INTRS];
-
- u_int32_t sc_eintrs; /* enabled interrupts */
-
- ohci_soft_ed_t *sc_isoc_head;
- ohci_soft_ed_t *sc_ctrl_head;
- ohci_soft_ed_t *sc_bulk_head;
-
- LIST_HEAD(, ohci_soft_td) sc_hash_tds[OHCI_HASH_SIZE];
- LIST_HEAD(, ohci_soft_itd) sc_hash_itds[OHCI_HASH_SIZE];
-
- int sc_noport;
- u_int8_t sc_addr; /* device address */
- u_int8_t sc_conf; /* device configuration */
-
-#ifdef USB_USE_SOFTINTR
- char sc_softwake;
-#endif /* USB_USE_SOFTINTR */
-
- ohci_soft_ed_t *sc_freeeds;
- ohci_soft_td_t *sc_freetds;
- ohci_soft_itd_t *sc_freeitds;
-
- STAILQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
-
- usbd_xfer_handle sc_intrxfer;
-
- ohci_soft_itd_t *sc_sidone;
- ohci_soft_td_t *sc_sdone;
-
- char sc_vendor[16];
- int sc_id_vendor;
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- void *sc_powerhook; /* cookie from power hook */
- void *sc_shutdownhook; /* cookie from shutdown hook */
-#endif
- u_int32_t sc_control; /* Preserved during suspend/standby */
- u_int32_t sc_intre;
-
- u_int sc_overrun_cnt;
- struct timeval sc_overrun_ntc;
-
- struct callout sc_tmo_rhsc;
- char sc_dying;
-} ohci_softc_t;
-
-struct ohci_xfer {
- struct usbd_xfer xfer;
- struct usb_task abort_task;
- u_int32_t ohci_xfer_flags;
-};
-#define OHCI_XFER_ABORTING 0x01 /* xfer is aborting. */
-#define OHCI_XFER_ABORTWAIT 0x02 /* abort completion is being awaited. */
-
-#define OXFER(xfer) ((struct ohci_xfer *)(xfer))
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-usbd_status ohci_init(ohci_softc_t *);
-void ohci_intr(void *);
-int ohci_detach(ohci_softc_t *, int);
-void ohci_shutdown(void *v);
-void ohci_power(int state, void *priv);
diff --git a/sys/legacy/dev/usb/rio500_usb.h b/sys/legacy/dev/usb/rio500_usb.h
deleted file mode 100644
index 5b53e2c..0000000
--- a/sys/legacy/dev/usb/rio500_usb.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-
- ----------------------------------------------------------------------
-
- Copyright (C) 2000 Cesar Miquel (miquel@df.uba.ar)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted under any licence of your choise which
- meets the open source licence definiton
- http://www.opensource.org/opd.html such as the GNU licence or the
- BSD licence.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License or the BSD license for more details.
-
- ----------------------------------------------------------------------
-
- Modified for FreeBSD by Iwasa Kazmi <kzmi@ca2.so-net.ne.jp>
-
- ---------------------------------------------------------------------- */
-
-/* $FreeBSD$ */
-
-#include <sys/ioccom.h>
-#ifndef USB_VENDOR_DIAMOND
-#define USB_VENDOR_DIAMOND 0x841
-#endif
-#ifndef USB_PRODUCT_DIAMOND_RIO500USB
-#define USB_PRODUCT_DIAMOND_RIO500USB 0x1
-#endif
-
-struct RioCommand
-{
- uint16_t length;
- int request;
- int requesttype;
- int value;
- int index;
- void *buffer;
- int timeout;
-};
-
-#define RIO_SEND_COMMAND _IOWR('U', 200, struct RioCommand)
-#define RIO_RECV_COMMAND _IOWR('U', 201, struct RioCommand)
-
-#define RIO_DIR_OUT 0x0
-#define RIO_DIR_IN 0x1
diff --git a/sys/legacy/dev/usb/rt2573_ucode.h b/sys/legacy/dev/usb/rt2573_ucode.h
deleted file mode 100644
index f2040f3..0000000
--- a/sys/legacy/dev/usb/rt2573_ucode.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005-2006, Ralink Technology, Corp.
- * Paul Lin <paul_lin@ralinktech.com.tw>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file contains the loadable 8051 microcode for the Ralink RT2573
- * chipset.
- */
-
-static const uint8_t rt2573_ucode[] = {
- 0x02, 0x13, 0x25, 0x12, 0x10, 0xd9, 0x02, 0x12, 0x58, 0x02, 0x13,
- 0x58, 0x02, 0x13, 0x5a, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0x12, 0x13,
- 0x5c, 0xd0, 0xd0, 0x22, 0x02, 0x14, 0x5c, 0x02, 0x14, 0xe7, 0xed,
- 0x4c, 0x70, 0x44, 0x90, 0x01, 0xa8, 0x74, 0x80, 0xf0, 0xef, 0x30,
- 0xe5, 0x07, 0xe4, 0x90, 0x00, 0x0f, 0xf0, 0x80, 0x2c, 0xe5, 0x40,
- 0x24, 0xc0, 0x60, 0x13, 0x24, 0xc0, 0x60, 0x16, 0x24, 0xc0, 0x60,
- 0x19, 0x24, 0xc0, 0x70, 0x1a, 0xe4, 0x90, 0x00, 0x0b, 0xf0, 0x80,
- 0x13, 0xe4, 0x90, 0x00, 0x13, 0xf0, 0x80, 0x0c, 0xe4, 0x90, 0x00,
- 0x1b, 0xf0, 0x80, 0x05, 0xe4, 0x90, 0x00, 0x23, 0xf0, 0xe4, 0x90,
- 0x01, 0xa8, 0xf0, 0xd3, 0x22, 0x90, 0x02, 0x02, 0xed, 0xf0, 0x90,
- 0x02, 0x01, 0xef, 0xf0, 0xd3, 0x22, 0xef, 0x24, 0xc0, 0x60, 0x1f,
- 0x24, 0xc0, 0x60, 0x2e, 0x24, 0xc0, 0x60, 0x3d, 0x24, 0xc0, 0x70,
- 0x53, 0x90, 0x00, 0x0b, 0xe0, 0x30, 0xe1, 0x02, 0xc3, 0x22, 0x90,
- 0x00, 0x09, 0xe0, 0xfe, 0x90, 0x00, 0x08, 0x80, 0x37, 0x90, 0x00,
- 0x13, 0xe0, 0x30, 0xe1, 0x02, 0xc3, 0x22, 0x90, 0x00, 0x11, 0xe0,
- 0xfe, 0x90, 0x00, 0x10, 0x80, 0x24, 0x90, 0x00, 0x1b, 0xe0, 0x30,
- 0xe1, 0x02, 0xc3, 0x22, 0x90, 0x00, 0x19, 0xe0, 0xfe, 0x90, 0x00,
- 0x18, 0x80, 0x11, 0x90, 0x00, 0x23, 0xe0, 0x30, 0xe1, 0x02, 0xc3,
- 0x22, 0x90, 0x00, 0x21, 0xe0, 0xfe, 0x90, 0x00, 0x20, 0xe0, 0xfd,
- 0xee, 0xf5, 0x37, 0xed, 0xf5, 0x38, 0xd3, 0x22, 0x30, 0x09, 0x20,
- 0x20, 0x04, 0x0b, 0x90, 0x02, 0x08, 0xe0, 0x54, 0x0f, 0x70, 0x03,
- 0x02, 0x12, 0x57, 0xc2, 0x09, 0x90, 0x02, 0x00, 0xe0, 0x44, 0x04,
- 0xf0, 0x74, 0x04, 0x12, 0x0c, 0x3a, 0xc2, 0x04, 0xc2, 0x07, 0x90,
- 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80, 0xf6, 0x90, 0x03,
- 0x26, 0xe0, 0x20, 0xe2, 0x03, 0x02, 0x12, 0x57, 0x90, 0x02, 0x08,
- 0xe0, 0x70, 0x1b, 0x20, 0x07, 0x03, 0x02, 0x12, 0x57, 0x90, 0x03,
- 0x12, 0xe0, 0x64, 0x22, 0x60, 0x03, 0x02, 0x12, 0x57, 0xd2, 0x09,
- 0xc2, 0x07, 0x74, 0x02, 0x12, 0x0c, 0x3a, 0x22, 0x90, 0x02, 0x03,
- 0xe0, 0x30, 0xe4, 0x47, 0x20, 0x06, 0x44, 0xe5, 0x3c, 0x60, 0x34,
- 0xe5, 0x40, 0x24, 0xc0, 0x60, 0x14, 0x24, 0xc0, 0x60, 0x18, 0x24,
- 0xc0, 0x60, 0x1c, 0x24, 0xc0, 0x70, 0x22, 0x90, 0x00, 0x0b, 0xe0,
- 0x30, 0xe1, 0x1b, 0x22, 0x90, 0x00, 0x13, 0xe0, 0x30, 0xe1, 0x13,
- 0x22, 0x90, 0x00, 0x1b, 0xe0, 0x30, 0xe1, 0x0b, 0x22, 0x90, 0x00,
- 0x23, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x12, 0x57, 0x90, 0x02, 0x03,
- 0x74, 0x01, 0xf0, 0x00, 0xe0, 0x54, 0xc0, 0xf5, 0x40, 0xe5, 0x40,
- 0x24, 0xc0, 0x60, 0x20, 0x24, 0xc0, 0x60, 0x30, 0x24, 0xc0, 0x60,
- 0x40, 0x24, 0xc0, 0x70, 0x56, 0x90, 0x00, 0x0b, 0xe0, 0x30, 0xe1,
- 0x03, 0x02, 0x12, 0x57, 0x90, 0x00, 0x09, 0xe0, 0xfe, 0x90, 0x00,
- 0x08, 0x80, 0x3a, 0x90, 0x00, 0x13, 0xe0, 0x30, 0xe1, 0x03, 0x02,
- 0x12, 0x57, 0x90, 0x00, 0x11, 0xe0, 0xfe, 0x90, 0x00, 0x10, 0x80,
- 0x26, 0x90, 0x00, 0x1b, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x12, 0x57,
- 0x90, 0x00, 0x19, 0xe0, 0xfe, 0x90, 0x00, 0x18, 0x80, 0x12, 0x90,
- 0x00, 0x23, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x12, 0x57, 0x90, 0x00,
- 0x21, 0xe0, 0xfe, 0x90, 0x00, 0x20, 0xe0, 0xfd, 0xee, 0xf5, 0x37,
- 0xed, 0xf5, 0x38, 0x90, 0x03, 0x27, 0x74, 0x82, 0xf0, 0x90, 0x02,
- 0x01, 0xe5, 0x40, 0xf0, 0x90, 0x02, 0x06, 0xe0, 0xf5, 0x3c, 0xc3,
- 0xe5, 0x38, 0x95, 0x3a, 0xe5, 0x37, 0x95, 0x39, 0x50, 0x21, 0xe5,
- 0x40, 0x44, 0x05, 0xff, 0xe5, 0x37, 0xa2, 0xe7, 0x13, 0xfc, 0xe5,
- 0x38, 0x13, 0xfd, 0x12, 0x10, 0x20, 0xe5, 0x3c, 0x30, 0xe2, 0x04,
- 0xd2, 0x06, 0x80, 0x02, 0xc2, 0x06, 0x53, 0x3c, 0x01, 0x22, 0x30,
- 0x0b, 0x07, 0xe4, 0x90, 0x02, 0x02, 0xf0, 0x80, 0x06, 0x90, 0x02,
- 0x02, 0x74, 0x20, 0xf0, 0xe5, 0x40, 0x44, 0x01, 0x90, 0x02, 0x01,
- 0xf0, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80, 0xf6,
- 0x90, 0x03, 0x27, 0x74, 0x02, 0xf0, 0xaf, 0x40, 0x12, 0x10, 0x74,
- 0x40, 0xa5, 0x00, 0x80, 0xf6, 0x22, 0x90, 0x7f, 0xf8, 0xe0, 0xb4,
- 0x02, 0x03, 0x12, 0x16, 0x38, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0,
- 0x03, 0x00, 0x80, 0xf6, 0x90, 0x03, 0x26, 0xe0, 0x20, 0xe1, 0x07,
- 0xe5, 0x3b, 0x70, 0x03, 0x02, 0x13, 0x24, 0xe5, 0x3b, 0x70, 0x15,
- 0x90, 0x03, 0x24, 0xe0, 0x75, 0xf0, 0x40, 0xa4, 0xf5, 0x36, 0x85,
- 0xf0, 0x35, 0x75, 0x24, 0x83, 0x75, 0x3b, 0x01, 0x80, 0x03, 0x75,
- 0x24, 0x03, 0xd3, 0xe5, 0x36, 0x95, 0x3a, 0xe5, 0x35, 0x95, 0x39,
- 0x40, 0x36, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80,
- 0xf6, 0x90, 0x03, 0x27, 0xe5, 0x24, 0xf0, 0x90, 0x00, 0x0f, 0xe0,
- 0x30, 0xe1, 0x04, 0x30, 0x0e, 0xf6, 0x22, 0x30, 0x0b, 0x07, 0xe4,
- 0x90, 0x02, 0x02, 0xf0, 0x80, 0x06, 0x90, 0x02, 0x02, 0x74, 0x20,
- 0xf0, 0x90, 0x02, 0x01, 0x74, 0x21, 0xf0, 0x75, 0x24, 0x03, 0x80,
- 0x3d, 0xe5, 0x35, 0xa2, 0xe7, 0x13, 0xfe, 0xe5, 0x36, 0x13, 0xfd,
- 0xac, 0x06, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80,
- 0xf6, 0x90, 0x03, 0x27, 0xe5, 0x24, 0xf0, 0x90, 0x00, 0x0f, 0xe0,
- 0x30, 0xe1, 0x04, 0x30, 0x0e, 0xf6, 0x22, 0x7f, 0x25, 0x12, 0x10,
- 0x20, 0xe5, 0x36, 0xb5, 0x3a, 0x08, 0xe5, 0x35, 0xb5, 0x39, 0x03,
- 0x00, 0x80, 0x04, 0xe4, 0xf5, 0x3b, 0x22, 0xc3, 0xe5, 0x36, 0x95,
- 0x3a, 0xf5, 0x36, 0xe5, 0x35, 0x95, 0x39, 0xf5, 0x35, 0x02, 0x12,
- 0x96, 0x22, 0x75, 0xa8, 0x0f, 0x90, 0x03, 0x06, 0x74, 0x01, 0xf0,
- 0x90, 0x03, 0x07, 0xf0, 0x90, 0x03, 0x08, 0x04, 0xf0, 0x90, 0x03,
- 0x09, 0x74, 0x6c, 0xf0, 0x90, 0x03, 0x0a, 0x74, 0xff, 0xf0, 0x90,
- 0x03, 0x02, 0x74, 0x1f, 0xf0, 0x90, 0x03, 0x00, 0x74, 0x04, 0xf0,
- 0x90, 0x03, 0x25, 0x74, 0x31, 0xf0, 0xd2, 0xaf, 0x22, 0x00, 0x22,
- 0x00, 0x22, 0x90, 0x03, 0x05, 0xe0, 0x30, 0xe0, 0x0b, 0xe0, 0x44,
- 0x01, 0xf0, 0x30, 0x09, 0x02, 0xd2, 0x04, 0xc2, 0x07, 0x22, 0x8d,
- 0x24, 0xa9, 0x07, 0x90, 0x7f, 0xfc, 0xe0, 0x75, 0x25, 0x00, 0xf5,
- 0x26, 0xa3, 0xe0, 0x75, 0x27, 0x00, 0xf5, 0x28, 0xa3, 0xe0, 0xff,
- 0xa3, 0xe0, 0xfd, 0xe9, 0x30, 0xe5, 0x14, 0x54, 0xc0, 0x60, 0x05,
- 0x43, 0x05, 0x03, 0x80, 0x03, 0x53, 0x05, 0xfc, 0xef, 0x54, 0x3f,
- 0x44, 0x40, 0xff, 0x80, 0x06, 0x53, 0x07, 0x3f, 0x53, 0x05, 0xf0,
- 0xe5, 0x24, 0x30, 0xe0, 0x05, 0x43, 0x05, 0x10, 0x80, 0x03, 0x53,
- 0x05, 0xef, 0x90, 0x7f, 0xfc, 0xe5, 0x26, 0xf0, 0xa3, 0xe5, 0x28,
- 0xf0, 0xa3, 0xef, 0xf0, 0xa3, 0xed, 0xf0, 0x22, 0x8f, 0x24, 0xa9,
- 0x05, 0x90, 0x7f, 0xfc, 0xe0, 0x75, 0x25, 0x00, 0xf5, 0x26, 0xa3,
- 0xe0, 0x75, 0x27, 0x00, 0xf5, 0x28, 0xa3, 0xe0, 0xff, 0xa3, 0xe0,
- 0xfd, 0xe5, 0x24, 0x30, 0xe5, 0x0b, 0x43, 0x05, 0x0f, 0xef, 0x54,
- 0x3f, 0x44, 0x40, 0xff, 0x80, 0x06, 0x53, 0x05, 0xf0, 0x53, 0x07,
- 0x3f, 0xe9, 0x30, 0xe0, 0x05, 0x43, 0x05, 0x10, 0x80, 0x03, 0x53,
- 0x05, 0xef, 0x90, 0x7f, 0xfc, 0xe5, 0x26, 0xf0, 0xa3, 0xe5, 0x28,
- 0xf0, 0xa3, 0xef, 0xf0, 0xa3, 0xed, 0xf0, 0x22, 0x90, 0x7f, 0xfc,
- 0xe0, 0xf9, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfb,
- 0xef, 0x30, 0xe5, 0x0b, 0x43, 0x03, 0x0f, 0xec, 0x54, 0x3f, 0x44,
- 0x40, 0xfc, 0x80, 0x06, 0x53, 0x03, 0xf0, 0x53, 0x04, 0x3f, 0xed,
- 0x30, 0xe0, 0x07, 0xef, 0x54, 0xc0, 0x60, 0x07, 0x80, 0x0a, 0xef,
- 0x54, 0xc0, 0x60, 0x05, 0x43, 0x03, 0x10, 0x80, 0x03, 0x53, 0x03,
- 0xef, 0x90, 0x7f, 0xfc, 0xe9, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xec,
- 0xf0, 0xa3, 0xeb, 0xf0, 0x22, 0xe5, 0x4b, 0xfd, 0x54, 0x1f, 0x90,
- 0x7f, 0xf8, 0xf0, 0xe5, 0x4a, 0xf5, 0x09, 0x90, 0x30, 0x38, 0xe0,
- 0x90, 0x7f, 0xfc, 0xf0, 0x90, 0x30, 0x39, 0xe0, 0x90, 0x7f, 0xfd,
- 0xf0, 0x90, 0x30, 0x3a, 0xe0, 0x90, 0x7f, 0xfe, 0xf0, 0x90, 0x30,
- 0x3b, 0xe0, 0x90, 0x7f, 0xff, 0xf0, 0xed, 0x30, 0xe5, 0x0c, 0x54,
- 0xc0, 0x60, 0x0d, 0x90, 0x7f, 0xf0, 0xe5, 0x47, 0xf0, 0x80, 0x05,
- 0xe4, 0x90, 0x7f, 0xf0, 0xf0, 0x90, 0x7f, 0xf8, 0xe0, 0x14, 0x60,
- 0x08, 0x24, 0xfe, 0x60, 0x0d, 0x24, 0x03, 0x80, 0x12, 0xaf, 0x05,
- 0xad, 0x09, 0x12, 0x13, 0xc5, 0x80, 0x10, 0xaf, 0x05, 0xad, 0x09,
- 0x12, 0x14, 0x12, 0x80, 0x07, 0xaf, 0x05, 0xad, 0x09, 0x12, 0x13,
- 0x6f, 0x90, 0x7f, 0xfc, 0xe0, 0x90, 0x30, 0x38, 0xf0, 0x90, 0x7f,
- 0xfd, 0xe0, 0x90, 0x30, 0x39, 0xf0, 0x90, 0x7f, 0xfe, 0xe0, 0x90,
- 0x30, 0x3a, 0xf0, 0x90, 0x7f, 0xff, 0xe0, 0x90, 0x30, 0x3b, 0xf0,
- 0x22, 0xe5, 0x4b, 0x64, 0x01, 0x60, 0x03, 0x02, 0x15, 0x71, 0xf5,
- 0x4b, 0xe5, 0x44, 0x45, 0x43, 0x70, 0x03, 0x02, 0x15, 0xa0, 0x12,
- 0x0c, 0x14, 0x12, 0x0b, 0x86, 0x50, 0xfb, 0x90, 0x00, 0x00, 0xe0,
- 0xf5, 0x25, 0x12, 0x15, 0xb4, 0xc2, 0x92, 0xe4, 0xf5, 0x24, 0xe5,
- 0x24, 0xc3, 0x95, 0x25, 0x50, 0x49, 0x7e, 0x00, 0x7f, 0x4c, 0x74,
- 0x40, 0x25, 0x24, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xad, 0x82, 0xfc,
- 0x75, 0x2b, 0x02, 0x7b, 0x10, 0x12, 0x07, 0x1e, 0xc2, 0x93, 0x12,
- 0x15, 0xa1, 0x7d, 0xa0, 0x12, 0x15, 0xd0, 0xe5, 0x24, 0x54, 0x0f,
- 0x24, 0x4c, 0xf8, 0xe6, 0xfd, 0xaf, 0x4b, 0xae, 0x4a, 0x12, 0x15,
- 0xd8, 0x05, 0x4b, 0xe5, 0x4b, 0x70, 0x02, 0x05, 0x4a, 0x12, 0x0a,
- 0x5f, 0x05, 0x24, 0xe5, 0x24, 0x54, 0x0f, 0x70, 0xd5, 0xd2, 0x93,
- 0x80, 0xb0, 0xc3, 0xe5, 0x44, 0x95, 0x25, 0xf5, 0x44, 0xe5, 0x43,
- 0x94, 0x00, 0xf5, 0x43, 0x02, 0x14, 0xf2, 0x12, 0x15, 0xb4, 0xc2,
- 0x93, 0xc2, 0x92, 0x12, 0x15, 0xa1, 0x7d, 0x80, 0x12, 0x15, 0xd0,
- 0x7d, 0xaa, 0x74, 0x55, 0xff, 0xfe, 0x12, 0x15, 0xd8, 0x7d, 0x55,
- 0x7f, 0xaa, 0x7e, 0x2a, 0x12, 0x15, 0xd8, 0x7d, 0x30, 0xaf, 0x4b,
- 0xae, 0x4a, 0x12, 0x15, 0xd8, 0x12, 0x0a, 0x5f, 0xd2, 0x93, 0x22,
- 0x7d, 0xaa, 0x74, 0x55, 0xff, 0xfe, 0x12, 0x15, 0xd8, 0x7d, 0x55,
- 0x7f, 0xaa, 0x7e, 0x2a, 0x12, 0x15, 0xd8, 0x22, 0xad, 0x47, 0x7f,
- 0x34, 0x7e, 0x30, 0x12, 0x15, 0xd8, 0x7d, 0xff, 0x7f, 0x35, 0x7e,
- 0x30, 0x12, 0x15, 0xd8, 0xe4, 0xfd, 0x7f, 0x37, 0x7e, 0x30, 0x12,
- 0x15, 0xd8, 0x22, 0x74, 0x55, 0xff, 0xfe, 0x12, 0x15, 0xd8, 0x22,
- 0x8f, 0x82, 0x8e, 0x83, 0xed, 0xf0, 0x22, 0xe4, 0xfc, 0x90, 0x7f,
- 0xf0, 0xe0, 0xaf, 0x09, 0x14, 0x60, 0x14, 0x14, 0x60, 0x15, 0x14,
- 0x60, 0x16, 0x14, 0x60, 0x17, 0x14, 0x60, 0x18, 0x24, 0x05, 0x70,
- 0x16, 0xe4, 0xfc, 0x80, 0x12, 0x7c, 0x01, 0x80, 0x0e, 0x7c, 0x03,
- 0x80, 0x0a, 0x7c, 0x07, 0x80, 0x06, 0x7c, 0x0f, 0x80, 0x02, 0x7c,
- 0x1f, 0xec, 0x6f, 0xf4, 0x54, 0x1f, 0xfc, 0x90, 0x30, 0x34, 0xe0,
- 0x54, 0xe0, 0x4c, 0xfd, 0xa3, 0xe0, 0xfc, 0x43, 0x04, 0x1f, 0x7f,
- 0x34, 0x7e, 0x30, 0x12, 0x15, 0xd8, 0xad, 0x04, 0x0f, 0x12, 0x15,
- 0xd8, 0xe4, 0xfd, 0x7f, 0x37, 0x02, 0x15, 0xd8, 0x02, 0x15, 0xdf,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
- 0x29, 0xe9
-};
diff --git a/sys/legacy/dev/usb/sl811hs.c b/sys/legacy/dev/usb/sl811hs.c
deleted file mode 100644
index 3620d5f..0000000
--- a/sys/legacy/dev/usb/sl811hs.c
+++ /dev/null
@@ -1,1654 +0,0 @@
-/* $NetBSD: sl811hs.c,v 1.5 2005/02/27 00:27:02 perry Exp $ */
-
-/*
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Tetsuya Isaki.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/*
- * ScanLogic SL811HS/T USB Host Controller
- */
-/*
- * !! HIGHLY EXPERIMENTAL CODE !!
- */
-
-#include <sys/cdefs.h>
-//_RCSID(0, "$NetBSD: sl811hs.c,v 1.5 2005/02/27 00:27:02 perry Exp $");
-
-#include "opt_slhci.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/malloc.h>
-
-#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <sys/module.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_port.h>
-#include "usbdevs.h"
-
-#include <dev/usb/sl811hsreg.h>
-#include <dev/usb/sl811hsvar.h>
-
-__FBSDID("$FreeBSD$");
-
-static inline u_int8_t sl11read(struct slhci_softc *, int);
-static inline void sl11write(struct slhci_softc *, int, u_int8_t);
-static inline void sl11read_region(struct slhci_softc *, u_char *, int, int);
-static inline void sl11write_region(struct slhci_softc *, int, u_char *, int);
-
-static void sl11_reset(struct slhci_softc *);
-static void sl11_speed(struct slhci_softc *);
-
-static usbd_status slhci_open(usbd_pipe_handle);
-static void slhci_softintr(void *);
-static void slhci_poll(struct usbd_bus *);
-static void slhci_poll_hub(void *);
-static void slhci_poll_device(void *arg);
-static usbd_status slhci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
-static void slhci_freem(struct usbd_bus *, usb_dma_t *);
-static usbd_xfer_handle slhci_allocx(struct usbd_bus *);
-static void slhci_freex(struct usbd_bus *, usbd_xfer_handle);
-
-static int slhci_str(usb_string_descriptor_t *, int, const char *);
-
-static usbd_status slhci_root_ctrl_transfer(usbd_xfer_handle);
-static usbd_status slhci_root_ctrl_start(usbd_xfer_handle);
-static void slhci_root_ctrl_abort(usbd_xfer_handle);
-static void slhci_root_ctrl_close(usbd_pipe_handle);
-static void slhci_root_ctrl_done(usbd_xfer_handle);
-
-static usbd_status slhci_root_intr_transfer(usbd_xfer_handle);
-static usbd_status slhci_root_intr_start(usbd_xfer_handle);
-static void slhci_root_intr_abort(usbd_xfer_handle);
-static void slhci_root_intr_close(usbd_pipe_handle);
-static void slhci_root_intr_done(usbd_xfer_handle);
-
-static usbd_status slhci_device_ctrl_transfer(usbd_xfer_handle);
-static usbd_status slhci_device_ctrl_start(usbd_xfer_handle);
-static void slhci_device_ctrl_abort(usbd_xfer_handle);
-static void slhci_device_ctrl_close(usbd_pipe_handle);
-static void slhci_device_ctrl_done(usbd_xfer_handle);
-
-static usbd_status slhci_device_intr_transfer(usbd_xfer_handle);
-static usbd_status slhci_device_intr_start(usbd_xfer_handle);
-static void slhci_device_intr_abort(usbd_xfer_handle);
-static void slhci_device_intr_close(usbd_pipe_handle);
-static void slhci_device_intr_done(usbd_xfer_handle);
-
-static usbd_status slhci_device_isoc_transfer(usbd_xfer_handle);
-static usbd_status slhci_device_isoc_start(usbd_xfer_handle);
-static void slhci_device_isoc_abort(usbd_xfer_handle);
-static void slhci_device_isoc_close(usbd_pipe_handle);
-static void slhci_device_isoc_done(usbd_xfer_handle);
-
-static usbd_status slhci_device_bulk_transfer(usbd_xfer_handle);
-static usbd_status slhci_device_bulk_start(usbd_xfer_handle);
-static void slhci_device_bulk_abort(usbd_xfer_handle);
-static void slhci_device_bulk_close(usbd_pipe_handle);
-static void slhci_device_bulk_done(usbd_xfer_handle);
-
-static int slhci_transaction(struct slhci_softc *,
- usbd_pipe_handle, u_int8_t, int, u_char *, u_int8_t);
-static void slhci_noop(usbd_pipe_handle);
-static void slhci_abort_xfer(usbd_xfer_handle, usbd_status);
-static void slhci_device_clear_toggle(usbd_pipe_handle);
-
-extern int usbdebug;
-
-/* For root hub */
-#define SLHCI_INTR_ENDPT (1)
-
-#ifdef SLHCI_DEBUG
-#define D_TRACE (0x0001) /* function trace */
-#define D_MSG (0x0002) /* debug messages */
-#define D_XFER (0x0004) /* transfer messages (noisy!) */
-#define D_MEM (0x0008) /* memory allocation */
-
-int slhci_debug = D_MSG | D_XFER;
-#define DPRINTF(z,x) if((slhci_debug&(z))!=0)printf x
-void print_req(usb_device_request_t *);
-void print_req_hub(usb_device_request_t *);
-void print_dumpreg(struct slhci_softc *);
-void print_xfer(usbd_xfer_handle);
-#else
-#define DPRINTF(z,x)
-#endif
-
-
-/* XXX: sync with argument */
-static const char *sltypestr [] = {
- "SL11H/T",
- "SL811HS/T",
-};
-
-
-struct usbd_bus_methods slhci_bus_methods = {
- slhci_open,
- slhci_softintr,
- slhci_poll,
- slhci_allocm,
- slhci_freem,
- slhci_allocx,
- slhci_freex,
-};
-
-struct usbd_pipe_methods slhci_root_ctrl_methods = {
- slhci_root_ctrl_transfer,
- slhci_root_ctrl_start,
- slhci_root_ctrl_abort,
- slhci_root_ctrl_close,
- slhci_noop,
- slhci_root_ctrl_done,
-};
-
-struct usbd_pipe_methods slhci_root_intr_methods = {
- slhci_root_intr_transfer,
- slhci_root_intr_start,
- slhci_root_intr_abort,
- slhci_root_intr_close,
- slhci_noop,
- slhci_root_intr_done,
-};
-
-struct usbd_pipe_methods slhci_device_ctrl_methods = {
- slhci_device_ctrl_transfer,
- slhci_device_ctrl_start,
- slhci_device_ctrl_abort,
- slhci_device_ctrl_close,
- slhci_noop,
- slhci_device_ctrl_done,
-};
-
-struct usbd_pipe_methods slhci_device_intr_methods = {
- slhci_device_intr_transfer,
- slhci_device_intr_start,
- slhci_device_intr_abort,
- slhci_device_intr_close,
- slhci_device_clear_toggle,
- slhci_device_intr_done,
-};
-
-struct usbd_pipe_methods slhci_device_isoc_methods = {
- slhci_device_isoc_transfer,
- slhci_device_isoc_start,
- slhci_device_isoc_abort,
- slhci_device_isoc_close,
- slhci_noop,
- slhci_device_isoc_done,
-};
-
-struct usbd_pipe_methods slhci_device_bulk_methods = {
- slhci_device_bulk_transfer,
- slhci_device_bulk_start,
- slhci_device_bulk_abort,
- slhci_device_bulk_close,
- slhci_noop,
- slhci_device_bulk_done,
-};
-
-struct slhci_pipe {
- struct usbd_pipe pipe;
-};
-
-
-/*
- * SL811HS Register read/write routine
- */
-static inline u_int8_t
-sl11read(struct slhci_softc *sc, int reg)
-{
-#if 1
- int b;
- DELAY(80);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
- b = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA);
- return b;
-#else
- outb(0x4000, reg&0xff);
- return (inb(0x4001)&0xff);
-#endif
-}
-
-static inline void
-sl11write(struct slhci_softc *sc, int reg, u_int8_t data)
-{
-#if 1
- DELAY(80);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA, data);
-#else
- outb(0x4000, reg&0xff);
- outb(0x4000, data&0xff);
-#endif
-}
-
-static inline void
-sl11read_region(struct slhci_softc *sc, u_char *buf, int reg, int len)
-{
- int i;
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
- for (i = 0; i < len; i++)
- buf[i] = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA);
-}
-
-static inline void
-sl11write_region(struct slhci_softc *sc, int reg, u_char *buf, int len)
-{
- int i;
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
- for (i = 0; i < len; i++)
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA, buf[i]);
-}
-
-/*
- * USB bus reset. From sl811hs_appnote.pdf, p22
- */
-static void
-sl11_reset(struct slhci_softc *sc)
-{
- u_int8_t r;
-
- DPRINTF(D_TRACE, ("%s() ", __FUNCTION__));
- // r = sl11read(sc, SL11_CTRL);
- r = 0;
- sl11write(sc, SL11_CTRL, r | SL11_CTRL_RESETENGINE);
- delay_ms(250);
- sl11write(sc, SL11_CTRL, r | SL11_CTRL_JKSTATE | SL11_CTRL_RESETENGINE); delay_ms(150);
- sl11write(sc, SL11_CTRL, r | SL11_CTRL_RESETENGINE);
- delay_ms(10);
- sl11write(sc, SL11_CTRL, r);
-}
-
-/*
- * Detect the speed of attached device.
- */
-static void
-sl11_speed(struct slhci_softc *sc)
-{
- u_int8_t r;
-
- sl11write(sc, SL11_ISR, 0xff);
- r = sl11read(sc, SL11_ISR);
- if ((r & SL11_ISR_RESET)) {
- DPRINTF(D_MSG, ("NC "));
- sl11write(sc, SL11_ISR, SL11_ISR_RESET);
- sc->sc_connect = 0;
- }
-
- if ((sl11read(sc, SL11_ISR) & SL11_ISR_RESET)) {
- sl11write(sc, SL11_ISR, 0xff);
- } else {
- u_int8_t pol = 0, ctrl = 0;
-
- sc->sc_connect = 1;
- if (r & SL11_ISR_DATA) {
- DPRINTF(D_MSG, ("FS "));
- pol = 0;
- ctrl = SL11_CTRL_EOF2;
- sc->sc_fullspeed = 1;
- } else {
- DPRINTF(D_MSG, ("LS "));
- pol = SL811_CSOF_POLARITY;
- ctrl = SL11_CTRL_LOWSPEED;
- sc->sc_fullspeed = 0;
- }
- sl11write(sc, SL811_CSOF, pol | SL811_CSOF_MASTER | 0x2e);
- sl11write(sc, SL11_DATA, 0xe0);
- sl11write(sc, SL11_CTRL, ctrl | SL11_CTRL_ENABLESOF);
- }
-
- sl11write(sc, SL11_E0PID, (SL11_PID_SOF << 4) + 0);
- sl11write(sc, SL11_E0DEV, 0);
- sl11write(sc, SL11_E0CTRL, SL11_EPCTRL_ARM);
- delay_ms(30);
-}
-
-/*
- * If detect some known controller, return the type.
- * If does not, return -1.
- */
-int
-sl811hs_find(struct slhci_softc *sc)
-{
- int rev;
- sc->sc_sltype = -1;
-
- rev = sl11read(sc, SL11_REV) >> 4;
- if (rev >= SLTYPE_SL11H && rev <= SLTYPE_SL811HS_R14)
- sc->sc_sltype = rev;
- return sc->sc_sltype;
-}
-
-/*
- * Attach SL11H/SL811HS. Return 0 if success.
- */
-int
-slhci_attach(struct slhci_softc *sc)
-{
- int rev;
- /* Detect and check the controller type */
-
- rev = sl811hs_find(sc);
- if (rev == -1)
- return -1;
-
- printf("%s: ScanLogic %s USB Host Controller",
- device_get_nameunit(sc->sc_bus.bdev), sltypestr[(rev > 0)]);
- switch (rev) {
- case SLTYPE_SL11H:
- break;
- case SLTYPE_SL811HS_R12:
- printf(" (rev 1.2)");
- break;
- case SLTYPE_SL811HS_R14:
- printf(" (rev 1.4)");
- break;
- default:
- printf(" (unknown revision)");
- break;
- }
- printf("\n");
-
-
- /* Initialize sc */
- sc->sc_bus.usbrev = USBREV_1_1;
- sc->sc_bus.methods = &slhci_bus_methods;
- sc->sc_bus.pipe_size = sizeof(struct slhci_pipe);
- sc->sc_bus.parent_dmatag = NULL; /* XXX */
- sc->sc_bus.buffer_dmatag = NULL; /* XXX */
- STAILQ_INIT(&sc->sc_free_xfers);
-
- usb_callout_init(sc->sc_poll_handle);
-
- /* Disable interrupt, then wait 40msec */
- sl11write(sc, SL11_IER, 0x00);
- delay_ms(40);
-
- /* Initialize controller */
- sl11write(sc, SL811_CSOF, SL811_CSOF_MASTER | 0x2e);
- delay_ms(40);
-
- sl11write(sc, SL11_ISR, 0xff);
-
- /* Disable interrupt, then wait 40msec */
- sl11write(sc, SL11_IER, 0x00);
-
- /* Reset USB engine */
- sl11write(sc, SL11_CTRL, SL11_CTRL_JKSTATE| SL11_CTRL_RESETENGINE);
- delay_ms(40);
- sl11write(sc, SL11_CTRL, 0x00);
- delay_ms(10);
-
- /* USB Bus reset for GET_PORT_STATUS */
- sl11_reset(sc);
- sc->sc_flags = SLF_ATTACHED;
-
- /* Enable interrupt */
- sl11write(sc, SL11_IER, SL11_IER_INSERT);
- /* x68k Nereid USB controller needs it */
- if (sc->sc_enable_intr)
- sc->sc_enable_intr(sc->sc_arg, INTR_ON);
-#ifdef USB_DEBUG
- usbdebug = 0;
-#endif
-
- return 0;
-}
-
-int
-slhci_intr(void *arg)
-{
- struct slhci_softc *sc = arg;
- u_int8_t r;
-#ifdef SLHCI_DEBUG
- char bitbuf[256];
-#endif
-
-
- if((sc->sc_flags & SLF_ATTACHED) == 0)
- return 0;
-
- r = sl11read(sc, SL11_ISR);
-
-
-
- sl11write(sc, SL11_ISR, SL11_ISR_DATA | SL11_ISR_SOFTIMER);
-
- if ((r & SL11_ISR_RESET)) {
- sc->sc_flags |= SLF_RESET;
- sl11write(sc, SL11_ISR, SL11_ISR_RESET);
- }
- if ((r & SL11_ISR_INSERT)) {
- sc->sc_flags |= SLF_INSERT;
- sl11write(sc, SL11_ISR, SL11_ISR_INSERT);
- }
-
-#ifdef SLHCI_DEBUG
- bitmask_snprintf(r,
- (sl11read(sc, SL11_CTRL) & SL11_CTRL_SUSPEND)
- ? "\20\x8""D+\7RESUME\6INSERT\5SOF\4res\3""BABBLE\2USBB\1USBA"
- : "\20\x8""D+\7RESET\6INSERT\5SOF\4res\3""BABBLE\2USBB\1USBA",
- bitbuf, sizeof(bitbuf));
- DPRINTF(D_XFER, ("I=%s ", bitbuf));
-#endif /* SLHCI_DEBUG */
-
- return 0;
-}
-
-usbd_status
-slhci_open(usbd_pipe_handle pipe)
-{
- usbd_device_handle dev = pipe->device;
- struct slhci_softc *sc = (struct slhci_softc *)dev->bus;
- usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
-
- DPRINTF(D_TRACE, ("slhci_open(addr=%d,ep=%d,scaddr=%d)",
- dev->address, ed->bEndpointAddress, sc->sc_addr));
-
- if (dev->address == sc->sc_addr) {
- switch (ed->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &slhci_root_ctrl_methods;
- break;
- case UE_DIR_IN | SLHCI_INTR_ENDPT:
- pipe->methods = &slhci_root_intr_methods;
- break;
- default:
- printf("open:endpointErr!\n");
- return USBD_INVAL;
- }
- } else {
- switch (ed->bmAttributes & UE_XFERTYPE) {
- case UE_CONTROL:
- DPRINTF(D_MSG, ("control "));
- pipe->methods = &slhci_device_ctrl_methods;
- break;
- case UE_INTERRUPT:
- DPRINTF(D_MSG, ("interrupt "));
- pipe->methods = &slhci_device_intr_methods;
- break;
- case UE_ISOCHRONOUS:
- DPRINTF(D_MSG, ("isochronous "));
- pipe->methods = &slhci_device_isoc_methods;
- break;
- case UE_BULK:
- DPRINTF(D_MSG, ("bluk "));
- pipe->methods = &slhci_device_bulk_methods;
- break;
- }
- }
- return USBD_NORMAL_COMPLETION;
-}
-
-void
-slhci_softintr(void *arg)
-{
- DPRINTF(D_TRACE, ("%s()", __FUNCTION__));
-}
-
-void
-slhci_poll(struct usbd_bus *bus)
-{
- DPRINTF(D_TRACE, ("%s()", __FUNCTION__));
-}
-
-/*
- * Emulation of interrupt transfer for status change endpoint
- * of root hub.
- */
-void
-slhci_poll_hub(void *arg)
-{
- usbd_xfer_handle xfer = arg;
- usbd_pipe_handle pipe = xfer->pipe;
- struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
- int s;
- u_char *p;
-
- usb_callout(sc->sc_poll_handle, sc->sc_interval, slhci_poll_hub, xfer);
-
- /* USB spec 11.13.3 (p.260) */
- p = xfer->buffer;
- p[0] = 0;
- if ((sc->sc_flags & (SLF_INSERT | SLF_RESET))) {
- p[0] = 2;
- DPRINTF(D_TRACE, ("!"));
- }
-
- /* no change, return NAK */
- if (p[0] == 0)
- return;
-
- xfer->actlen = 1;
- xfer->status = USBD_NORMAL_COMPLETION;
- s = splusb();
- xfer->device->bus->intr_context++;
- usb_transfer_complete(xfer);
- xfer->device->bus->intr_context--;
- splx(s);
-}
-
-usbd_status
-slhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
-{
- struct slhci_softc *sc = (struct slhci_softc *)bus;
-
- DPRINTF(D_MEM, ("SLallocm"));
- return usb_allocmem(&sc->sc_bus, size, 0, dma);
-}
-
-void
-slhci_freem(struct usbd_bus *bus, usb_dma_t *dma)
-{
- struct slhci_softc *sc = (struct slhci_softc *)bus;
-
- DPRINTF(D_MEM, ("SLfreem"));
- usb_freemem(&sc->sc_bus, dma);
-}
-
-usbd_xfer_handle
-slhci_allocx(struct usbd_bus *bus)
-{
- struct slhci_softc *sc = (struct slhci_softc *)bus;
- usbd_xfer_handle xfer;
-
- DPRINTF(D_MEM, ("SLallocx"));
-
- xfer = STAILQ_FIRST(&sc->sc_free_xfers);
- if (xfer) {
- STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_FREE) {
- printf("slhci_allocx: xfer=%p not free, 0x%08x\n",
- xfer, xfer->busy_free);
- }
-#endif
- } else {
- xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT);
- }
-
- if (xfer) {
- memset(xfer, 0, sizeof(*xfer));
-#ifdef DIAGNOSTIC
- xfer->busy_free = XFER_BUSY;
-#endif
- }
-
- return xfer;
-}
-
-void
-slhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
-{
- struct slhci_softc *sc = (struct slhci_softc *)bus;
-
- DPRINTF(D_MEM, ("SLfreex"));
-
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_BUSY) {
- printf("slhci_freex: xfer=%p not busy, 0x%08x\n",
- xfer, xfer->busy_free);
- return;
- }
- xfer->busy_free = XFER_FREE;
-#endif
- STAILQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
-}
-
-void
-slhci_noop(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("%s()", __FUNCTION__));
-}
-
-/*
- * Data structures and routines to emulate the root hub.
- */
-usb_device_descriptor_t slhci_devd = {
- USB_DEVICE_DESCRIPTOR_SIZE,
- UDESC_DEVICE, /* type */
- {0x01, 0x01}, /* USB version */
- UDCLASS_HUB, /* class */
- UDSUBCLASS_HUB, /* subclass */
- 0, /* protocol */
- 64, /* max packet */
- {USB_VENDOR_SCANLOGIC & 0xff, /* vendor ID (low) */
- USB_VENDOR_SCANLOGIC >> 8 }, /* vendor ID (high) */
- {0} /* ? */, /* product ID */
- {0}, /* device */
- 1, /* index to manufacturer */
- 2, /* index to product */
- 0, /* index to serial number */
- 1 /* number of configurations */
-};
-
-usb_config_descriptor_t slhci_confd = {
- USB_CONFIG_DESCRIPTOR_SIZE,
- UDESC_CONFIG,
- {USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE},
- 1, /* number of interfaces */
- 1, /* configuration value */
- 0, /* index to configuration */
- UC_SELF_POWERED, /* attributes */
- 15 /* max current is 30mA... */
-};
-
-usb_interface_descriptor_t slhci_ifcd = {
- USB_INTERFACE_DESCRIPTOR_SIZE,
- UDESC_INTERFACE,
- 0, /* interface number */
- 0, /* alternate setting */
- 1, /* number of endpoint */
- UICLASS_HUB, /* class */
- UISUBCLASS_HUB, /* subclass */
- 0, /* protocol */
- 0 /* index to interface */
-};
-
-usb_endpoint_descriptor_t slhci_endpd = {
- USB_ENDPOINT_DESCRIPTOR_SIZE,
- UDESC_ENDPOINT,
- UE_DIR_IN | SLHCI_INTR_ENDPT, /* endpoint address */
- UE_INTERRUPT, /* attributes */
- {8}, /* max packet size */
- 255 /* interval */
-};
-
-usb_hub_descriptor_t slhci_hubd = {
- USB_HUB_DESCRIPTOR_SIZE,
- UDESC_HUB,
- 1, /* number of ports */
- {UHD_PWR_INDIVIDUAL | UHD_OC_NONE, 0}, /* hub characteristics */
- 20 /* ? */, /* 5:power on to power good */
- 50, /* 6:maximum current */
- { 0x00 }, /* both ports are removable */
- { 0x00 } /* port power control mask */
-};
-
-static int
-slhci_str(usb_string_descriptor_t *p, int l, const char *s)
-{
- int i;
-
- if (l == 0)
- return 0;
- p->bLength = 2 * strlen(s) + 2;
- if (l == 1)
- return 1;
- p->bDescriptorType = UDESC_STRING;
- l -= 2;
- for (i = 0; s[i] && l > 1; i++, l -= 2)
- USETW2(p->bString[i], 0, s[i]);
- return 2 * i + 2;
-}
-
-usbd_status
-slhci_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status error;
-
- DPRINTF(D_TRACE, ("SLRCtrans "));
-
- /* Insert last in queue */
- error = usb_insert_transfer(xfer);
- if (error) {
- DPRINTF(D_MSG, ("usb_insert_transfer returns err! "));
- return error;
- }
-
- /*
- * Pipe isn't running (otherwise error would be USBD_INPROG),
- * so start it first.
- */
- return slhci_root_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue));
-}
-
-usbd_status
-slhci_root_ctrl_start(usbd_xfer_handle xfer)
-{
- struct slhci_softc *sc = (struct slhci_softc *)xfer->pipe->device->bus;
- usb_device_request_t *req;
- int len, value, index, l, s, status;
- int totlen = 0;
- void *buf = NULL;
- usb_port_status_t ps;
- usbd_status error;
- char slbuf[50];
- u_int8_t r;
-
- DPRINTF(D_TRACE, ("SLRCstart "));
-
- req = &xfer->request;
-
- len = UGETW(req->wLength);
- value = UGETW(req->wValue);
- index = UGETW(req->wIndex);
-
- if (len)
- buf = xfer->buffer;
-
-#ifdef SLHCI_DEBUG
- if ((slhci_debug & D_TRACE))
- print_req_hub(req);
-#endif
-
-#define C(x,y) ((x) | ((y) << 8))
- switch (C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- DPRINTF(D_MSG, ("UR_CLEAR_FEATURE "));
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- DPRINTF(D_MSG, ("UR_GET_CONFIG "));
- if (len > 0) {
- *(u_int8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- switch (value >> 8) {
- case UDESC_DEVICE:
- DPRINTF(D_MSG, ("UDESC_DEVICE "));
- if ((value & 0xff) != 0) {
- error = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- memcpy(buf, &slhci_devd, l);
- break;
- case UDESC_CONFIG:
- DPRINTF(D_MSG, ("UDESC_CONFIG "));
- if ((value & 0xff) != 0) {
- error = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &slhci_confd, l);
- buf = (char *)buf + l;
- len -= l;
-
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &slhci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
-
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &slhci_endpd, l);
- break;
- case UDESC_STRING:
- DPRINTF(D_MSG, ("UDESC_STR "));
- if (len == 0)
- break;
- *(u_int8_t *)buf = 0;
- totlen = 1;
- switch (value & 0xff) {
- case 0:
- break;
- case 1: /* Vendor */
- totlen = slhci_str(buf, len, "ScanLogic");
- break;
- case 2: /* Product */
- snprintf(slbuf, sizeof(slbuf), "%s root hub",
- sltypestr[sc->sc_sltype>0]);
- totlen = slhci_str(buf, len, slbuf);
- break;
- default:
- printf("strerr%d ", value & 0xff);
- break;
- }
- break;
- default:
- printf("unknownGetDescriptor=%x", value);
- error = USBD_IOERROR;
- break;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- /* Get Interface, 9.4.4 */
- if (len > 0) {
- *(u_int8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- /* Get Status from device, 9.4.5 */
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- /* Get Status from interface, endpoint, 9.4.5 */
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- /* Set Address, 9.4.6 */
- DPRINTF(D_MSG, ("UR_SET_ADDRESS "));
- if (value >= USB_MAX_DEVICES) {
- error = USBD_IOERROR;
- goto ret;
- }
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- /* Set Configuration, 9.4.7 */
- DPRINTF(D_MSG, ("UR_SET_CONFIG "));
- if (value != 0 && value != 1) {
- error = USBD_IOERROR;
- goto ret;
- }
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- /* Set Descriptor, 9.4.8, not supported */
- DPRINTF(D_MSG, ("UR_SET_DESCRIPTOR,WRITE_DEVICE not supported\n"));
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- /* Set Feature, 9.4.9, not supported */
- DPRINTF(D_MSG, ("UR_SET_FEATURE not supported\n"));
- error = USBD_IOERROR;
- break;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- /* Set Interface, 9.4.10, not supported */
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- /* Synch Frame, 9.4.11, not supported */
- break;
-
- /*
- * Hub specific requests
- */
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
- /* Clear Hub Feature, 11.16.2.1, not supported */
- DPRINTF(D_MSG, ("ClearHubFeature not supported\n"));
- break;
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
- /* Clear Port Feature, 11.16.2.2 */
- if (index != 1) {
- error = USBD_IOERROR;
- goto ret;
- }
- switch (value) {
- case UHF_PORT_POWER:
- DPRINTF(D_MSG, ("POWER_OFF "));
- sc->sc_powerstat = POWER_OFF;
- /* x68k Nereid USB controller needs it */
- if (sc->sc_enable_power)
- sc->sc_enable_power(sc, sc->sc_powerstat);
- break;
- case UHF_PORT_SUSPEND:
- DPRINTF(D_MSG, ("SUSPEND "));
- sl11write(sc, SL11_CTRL,
- sl11read(sc, SL11_CTRL) & ~SL11_CTRL_SUSPEND);
- break;
- case UHF_C_PORT_CONNECTION:
- sc->sc_change &= ~UPS_C_CONNECT_STATUS;
- break;
- case UHF_C_PORT_RESET:
- sc->sc_change &= ~UPS_C_PORT_RESET;
- break;
- case UHF_PORT_ENABLE:
- break;
- case UHF_C_PORT_SUSPEND:
- case UHF_C_PORT_ENABLE:
- case UHF_C_PORT_OVER_CURRENT:
- default:
- printf("ClrPortFeatERR:value=0x%x ", value);
- error = USBD_IOERROR;
- break;
- }
- //DPRINTF(D_XFER, ("CH=%04x ", sc->sc_change));
- break;
- case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
- /* Get Bus State, 11.16.2.3, not supported */
- /* shall return a STALL... */
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- /* Get Hub Descriptor, 11.16.2.4 */
- if (value != 0) {
- error = USBD_IOERROR;
- goto ret;
- }
- l = min(len, USB_HUB_DESCRIPTOR_SIZE);
- totlen = l;
- memcpy(buf, &slhci_hubd, l);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
- /* Get Hub Status, 11.16.2.5 */
- DPRINTF(D_MSG, ("UR_GET_STATUS RCD"));
- if (len != 4) {
- error = USBD_IOERROR;
- goto ret;
- }
- memset(buf, 0, len);
- totlen = len;
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- /* Get Port Status, 11.16.2.6 */
- if (index != 1 || len != 4) {
- printf("index=%d,len=%d ", index, len);
- error = USBD_IOERROR;
- goto ret;
- }
- /*
- * change
- * o port is always enabled.
- * o cannot detect over current.
- */
- s = splusb();
- sc->sc_change &= ~(UPS_C_CONNECT_STATUS | UPS_C_PORT_RESET);
- if ((sc->sc_flags & SLF_INSERT)) {
- sc->sc_flags &= ~SLF_INSERT;
- sc->sc_change |= UPS_C_CONNECT_STATUS;
- }
- if ((sc->sc_flags & SLF_RESET)) {
- sc->sc_flags &= ~SLF_RESET;
- sc->sc_change |= UPS_C_PORT_RESET;
- }
- splx(s);
- /*
- * XXX It can recognize that device is detached,
- * while there is sl11_speed() here.
- */
- if (sc->sc_change)
- sl11_speed(sc);
- /*
- * status
- * o port is always enabled.
- * o cannot detect over current.
- */
- status = 0;
- if (sc->sc_connect)
- status |= UPS_CURRENT_CONNECT_STATUS | UPS_PORT_ENABLED;
- r = sl11read(sc, SL11_CTRL);
- if (r & SL11_CTRL_SUSPEND)
- status |= UPS_SUSPEND;
- if (sc->sc_powerstat)
- status |= UPS_PORT_POWER;
- if (!sc->sc_fullspeed)
- status |= UPS_LOW_SPEED;
-
- //DPRINTF(D_XFER, ("ST=%04x,CH=%04x ", status, sc->sc_change));
- USETW(ps.wPortStatus, status);
- USETW(ps.wPortChange, sc->sc_change);
- l = min(len, sizeof(ps));
- memcpy(buf, &ps, l);
- totlen = l;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- /* Set Hub Descriptor, 11.16.2.7, not supported */
- /* STALL ? */
- error = USBD_IOERROR;
- break;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
- /* Set Hub Feature, 11.16.2.8, not supported */
- break;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
- /* Set Port Feature, 11.16.2.9 */
- if (index != 1) {
- printf("index=%d ", index);
- error = USBD_IOERROR;
- goto ret;
- }
- switch (value) {
- case UHF_PORT_RESET:
- DPRINTF(D_MSG, ("PORT_RESET "));
- sl11_reset(sc);
- sl11_speed(sc);
- sc->sc_change = 0;
- break;
- case UHF_PORT_POWER:
- DPRINTF(D_MSG, ("PORT_POWER "));
- sc->sc_powerstat = POWER_ON;
- /* x68k Nereid USB controller needs it */
- if (sc->sc_enable_power)
- sc->sc_enable_power(sc, sc->sc_powerstat);
- delay_ms(25);
- break;
- default:
- printf("SetPortFeatERR=0x%x ", value);
- error = USBD_IOERROR;
- break;
- }
- break;
- default:
- DPRINTF(D_MSG, ("ioerr(UR=%02x,UT=%02x) ",
- req->bRequest, req->bmRequestType));
- error = USBD_IOERROR;
- goto ret;
- }
- xfer->actlen = totlen;
- error = USBD_NORMAL_COMPLETION;
- ret:
- xfer->status = error;
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
- return USBD_IN_PROGRESS;
-}
-
-void
-slhci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("SLRCabort "));
-}
-
-void
-slhci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("SLRCclose "));
-}
-
-void
-slhci_root_ctrl_done(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("SLRCdone\n"));
-}
-
-static usbd_status
-slhci_root_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status error;
-
- DPRINTF(D_TRACE, ("SLRItransfer "));
-
- /* Insert last in queue */
- error = usb_insert_transfer(xfer);
- if (error)
- return error;
-
- /*
- * Pipe isn't running (otherwise error would be USBD_INPROG),
- * start first.
- */
- return slhci_root_intr_start(STAILQ_FIRST(&xfer->pipe->queue));
-}
-
-static usbd_status
-slhci_root_intr_start(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
-
- DPRINTF(D_TRACE, ("SLRIstart "));
-
- sc->sc_interval = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval);
- usb_callout(sc->sc_poll_handle, sc->sc_interval, slhci_poll_hub, xfer);
- sc->sc_intr_xfer = xfer;
- return USBD_IN_PROGRESS;
-}
-
-static void
-slhci_root_intr_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("SLRIabort "));
-}
-
-static void
-slhci_root_intr_close(usbd_pipe_handle pipe)
-{
- struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
-
- DPRINTF(D_TRACE, ("SLRIclose "));
-
- usb_uncallout(sc->sc_poll_handle, slhci_poll_hub, sc->sc_intr_xfer);
- sc->sc_intr_xfer = NULL;
-}
-
-static void
-slhci_root_intr_done(usbd_xfer_handle xfer)
-{
- //DPRINTF(D_XFER, ("RIdn "));
-}
-
-static usbd_status
-slhci_device_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status error;
-
- DPRINTF(D_TRACE, ("C"));
-
- error = usb_insert_transfer(xfer);
- if (error)
- return error;
-
- return slhci_device_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue));
-}
-
-static usbd_status
-slhci_device_ctrl_start(usbd_xfer_handle xfer)
-{
- usb_device_request_t *req = &xfer->request;
- usbd_pipe_handle pipe = xfer->pipe;
- struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
- usbd_status status = USBD_NORMAL_COMPLETION;
- u_char *buf;
- int pid = SL11_PID_OUT;
- int len, actlen, size;
- int s;
- u_int8_t toggle = 0;
-
- DPRINTF(D_TRACE, ("st "));
-#ifdef SLHCI_DEBUG
- if ((slhci_debug & D_TRACE))
- print_req_hub(req);
-#endif
-
- /* SETUP transaction */
- if (slhci_transaction(sc, pipe, SL11_PID_SETUP,
- sizeof(*req), (u_char*)req, toggle) == -1) {
- status = USBD_IOERROR;
- goto ret;
- }
- toggle ^= SL11_EPCTRL_DATATOGGLE;
-
- /* DATA transaction */
- actlen = 0;
- len = UGETW(req->wLength);
- if (len) {
- buf = xfer->buffer;
- if (req->bmRequestType & UT_READ)
- pid = SL11_PID_IN;
- for (; actlen < len; ) {
- size = min(len - actlen, 8/* Minimum size */);
- if (slhci_transaction(sc, pipe, pid, size, buf, toggle) == -1)
- break;
- toggle ^= SL11_EPCTRL_DATATOGGLE;
- buf += size;
- actlen += size;
- }
- }
- xfer->actlen = actlen;
-
- /* ACK (status) */
- if (pid == SL11_PID_IN)
- pid = SL11_PID_OUT;
- else
- pid = SL11_PID_IN;
- if (slhci_transaction(sc, pipe, pid, 0, NULL, toggle) == -1)
- status = USBD_IOERROR;
-
- ret:
- xfer->status = status;
-
-#ifdef SLHCI_DEBUG
- if((slhci_debug & D_TRACE) && UGETW(req->wLength) > 0){
- int i;
- for(i=0; i < UGETW(req->wLength); i++)
- printf("%02x", ((unsigned char *)xfer->buffer)[i]);
- printf(" ");
- }
-#endif
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
- return USBD_IN_PROGRESS;
-}
-
-static void
-slhci_device_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Cab "));
- slhci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-static void
-slhci_device_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("Ccl "));
-}
-
-static void
-slhci_device_ctrl_done(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Cdn "));
-}
-
-static usbd_status
-slhci_device_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status error;
-
- DPRINTF(D_TRACE, ("INTRtrans "));
-
- error = usb_insert_transfer(xfer);
- if (error)
- return error;
-
- return slhci_device_intr_start(STAILQ_FIRST(&xfer->pipe->queue));
-}
-
-static usbd_status
-slhci_device_intr_start(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- struct slhci_xfer *sx;
-
- DPRINTF(D_TRACE, ("INTRstart "));
-
- sx = malloc(sizeof(*sx), M_USB, M_NOWAIT);
- if (sx == NULL)
- goto reterr;
- memset(sx, 0, sizeof(*sx));
- sx->sx_xfer = xfer;
- xfer->hcpriv = sx;
-
- /* initialize callout */
- usb_callout_init(sx->sx_callout_t);
- usb_callout(sx->sx_callout_t,
- MS_TO_TICKS(pipe->endpoint->edesc->bInterval),
- slhci_poll_device, sx);
-
- /* ACK */
- return USBD_IN_PROGRESS;
-
- reterr:
- return USBD_IOERROR;
-}
-
-static void
-slhci_poll_device(void *arg)
-{
- struct slhci_xfer *sx = (struct slhci_xfer *)arg;
- usbd_xfer_handle xfer = sx->sx_xfer;
- usbd_pipe_handle pipe = xfer->pipe;
- struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
- void *buf;
- int pid;
- int r;
- int s;
-
- DPRINTF(D_TRACE, ("pldev"));
-
- usb_callout(sx->sx_callout_t,
- MS_TO_TICKS(pipe->endpoint->edesc->bInterval),
- slhci_poll_device, sx);
-
- /* interrupt transfer */
- pid = (UE_GET_DIR(pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN)
- ? SL11_PID_IN : SL11_PID_OUT;
- buf = xfer->buffer;
-
- r = slhci_transaction(sc, pipe, pid, xfer->length, buf, 0/*toggle*/);
- if (r < 0) {
- DPRINTF(D_MSG, ("%s error", __FUNCTION__));
- return;
- }
- /* no change, return NAK */
- if (r == 0)
- return;
-
- xfer->status = USBD_NORMAL_COMPLETION;
- s = splusb();
- xfer->device->bus->intr_context++;
- usb_transfer_complete(xfer);
- xfer->device->bus->intr_context--;
- splx(s);
-}
-
-static void
-slhci_device_intr_abort(usbd_xfer_handle xfer)
-{
- struct slhci_xfer *sx;
-
- DPRINTF(D_TRACE, ("INTRabort "));
-
- sx = xfer->hcpriv;
- if (sx) {
- usb_uncallout(sx->sx_callout_t, slhci_poll_device, sx);
- free(sx, M_USB);
- xfer->hcpriv = NULL;
- } else {
- printf("%s: sx == NULL!\n", __FUNCTION__);
- }
- slhci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-static void
-slhci_device_intr_close(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("INTRclose "));
-}
-
-static void
-slhci_device_intr_done(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("INTRdone "));
-}
-
-static usbd_status
-slhci_device_isoc_transfer(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("S"));
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-slhci_device_isoc_start(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("st "));
- return USBD_NORMAL_COMPLETION;
-}
-
-static void
-slhci_device_isoc_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Sab "));
-}
-
-static void
-slhci_device_isoc_close(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("Scl "));
-}
-
-static void
-slhci_device_isoc_done(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Sdn "));
-}
-
-static usbd_status
-slhci_device_bulk_transfer(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("B"));
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-slhci_device_bulk_start(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("st "));
- return USBD_NORMAL_COMPLETION;
-}
-
-static void
-slhci_device_bulk_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Bab "));
-}
-
-static void
-slhci_device_bulk_close(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("Bcl "));
-}
-
-static void
-slhci_device_bulk_done(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Bdn "));
-}
-
-#define DATA0_RD (0x03)
-#define DATA0_WR (0x07)
-#define SLHCI_TIMEOUT (5000)
-
-/*
- * Do a transaction.
- * return 1 if ACK, 0 if NAK, -1 if error.
- */
-static int
-slhci_transaction(struct slhci_softc *sc, usbd_pipe_handle pipe,
- u_int8_t pid, int len, u_char *buf, u_int8_t toggle)
-{
-#ifdef SLHCI_DEBUG
- char str[64];
- int i;
-#endif
- int timeout;
- int ls_via_hub = 0;
- int pl;
- u_int8_t isr;
- u_int8_t result = 0;
- u_int8_t devaddr = pipe->device->address;
- u_int8_t endpointaddr = pipe->endpoint->edesc->bEndpointAddress;
- u_int8_t endpoint;
- u_int8_t cmd = DATA0_RD;
-
- endpoint = UE_GET_ADDR(endpointaddr);
- DPRINTF(D_XFER, ("\n(%x,%d%s%d,%d) ",
- pid, len, (pid == SL11_PID_IN) ? "<-" : "->", devaddr, endpoint));
-
- /* Set registers */
- sl11write(sc, SL11_E0ADDR, 0x40);
- sl11write(sc, SL11_E0LEN, len);
- sl11write(sc, SL11_E0PID, (pid << 4) + endpoint);
- sl11write(sc, SL11_E0DEV, devaddr);
-
- /* Set buffer unless PID_IN */
- if (pid != SL11_PID_IN) {
- if (len > 0)
- sl11write_region(sc, 0x40, buf, len);
- cmd = DATA0_WR;
- }
-
- /* timing ? */
- pl = (len >> 3) + 3;
-
- /* Low speed device via HUB */
- /* XXX does not work... */
- if ((sc->sc_fullspeed) && pipe->device->speed == USB_SPEED_LOW) {
- pl = len + 16;
- cmd |= SL11_EPCTRL_PREAMBLE;
-
- /*
- * SL811HS/T rev 1.2 has a bug, when it got PID_IN
- * from LowSpeed device via HUB.
- */
- if (sc->sc_sltype == SLTYPE_SL811HS_R12 && pid == SL11_PID_IN) {
- ls_via_hub = 1;
- DPRINTF(D_MSG, ("LSvH "));
- }
- }
-
- /* timing ? */
- if (sl11read(sc, SL811_CSOF) <= (u_int8_t)pl)
- cmd |= SL11_EPCTRL_SOF;
-
- /* Transfer */
- sl11write(sc, SL11_ISR, 0xff);
- sl11write(sc, SL11_E0CTRL, cmd | toggle);
-
- /* Polling */
- for (timeout = SLHCI_TIMEOUT; timeout; timeout--) {
- isr = sl11read(sc, SL11_ISR);
- if ((isr & SL11_ISR_USBA))
- break;
- }
-
- /* Check result status */
- result = sl11read(sc, SL11_E0STAT);
- if (!(result & SL11_EPSTAT_NAK) && ls_via_hub) {
- /* Resend PID_IN within 20usec */
- sl11write(sc, SL11_ISR, 0xff);
- sl11write(sc, SL11_E0CTRL, SL11_EPCTRL_ARM);
- }
-
- sl11write(sc, SL11_ISR, 0xff);
-
- DPRINTF(D_XFER, ("t=%d i=%x ", SLHCI_TIMEOUT - timeout, isr));
-#ifdef SLHCI_DEBUG
- bitmask_snprintf(result,
- "\20\x8STALL\7NAK\6OV\5SETUP\4DATA1\3TIMEOUT\2ERR\1ACK",
- str, sizeof(str));
- DPRINTF(D_XFER, ("STAT=%s ", str));
-#endif
-
- if ((result & SL11_EPSTAT_ERROR))
- return -1;
-
- if ((result & SL11_EPSTAT_NAK))
- return 0;
-
- /* Read buffer if PID_IN */
- if (pid == SL11_PID_IN && len > 0) {
- sl11read_region(sc, buf, 0x40, len);
-#ifdef SLHCI_DEBUG
- for (i = 0; i < len; i++)
- DPRINTF(D_XFER, ("%02X ", buf[i]));
-#endif
- }
-
- return 1;
-}
-
-void
-slhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
-{
- xfer->status = status;
- usb_transfer_complete(xfer);
-}
-
-void
-slhci_device_clear_toggle(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("SLdevice_clear_toggle "));
-}
-
-#ifdef SLHCI_DEBUG
-void
-print_req(usb_device_request_t *r)
-{
- char *xmes[]={
- "GETSTAT",
- "CLRFEAT",
- "res",
- "SETFEAT",
- "res",
- "SETADDR",
- "GETDESC",
- "SETDESC",
- "GETCONF",
- "SETCONF",
- "GETIN/F",
- "SETIN/F",
- "SYNC_FR"
- };
- int req, type, value, index, len;
-
- req = r->bRequest;
- type = r->bmRequestType;
- value = UGETW(r->wValue);
- index = UGETW(r->wIndex);
- len = UGETW(r->wLength);
-
- printf("%x,%s,v=%d,i=%d,l=%d ",
- type, xmes[req], value, index, len);
-}
-
-void
-print_req_hub(usb_device_request_t *r)
-{
- struct {
- int req;
- int type;
- char *str;
- } conf[] = {
- { 1, 0x20, "ClrHubFeat" },
- { 1, 0x23, "ClrPortFeat" },
- { 2, 0xa3, "GetBusState" },
- { 6, 0xa0, "GetHubDesc" },
- { 0, 0xa0, "GetHubStat" },
- { 0, 0xa3, "GetPortStat" },
- { 7, 0x20, "SetHubDesc" },
- { 3, 0x20, "SetHubFeat" },
- { 3, 0x23, "SetPortFeat" },
- {-1, 0, NULL},
- };
- int i;
- int value, index, len;
-
- value = UGETW(r->wValue);
- index = UGETW(r->wIndex);
- len = UGETW(r->wLength);
- for (i = 0; ; i++) {
- if (conf[i].req == -1 )
- return print_req(r);
- if (r->bmRequestType == conf[i].type && r->bRequest == conf[i].req) {
- printf("%s", conf[i].str);
- break;
- }
- }
- printf(",v=%d,i=%d,l=%d ", value, index, len);
-}
-
-void
-print_dumpreg(struct slhci_softc *sc)
-{
- printf("00=%02x,01=%02x,02=%02x,03=%02x,04=%02x,"
- "08=%02x,09=%02x,0A=%02x,0B=%02x,0C=%02x,",
- sl11read(sc, 0), sl11read(sc, 1),
- sl11read(sc, 2), sl11read(sc, 3),
- sl11read(sc, 4), sl11read(sc, 8),
- sl11read(sc, 9), sl11read(sc, 10),
- sl11read(sc, 11), sl11read(sc, 12)
- );
- printf("CR1=%02x,IER=%02x,0D=%02x,0E=%02x,0F=%02x ",
- sl11read(sc, 5), sl11read(sc, 6),
- sl11read(sc, 13), sl11read(sc, 14), sl11read(sc, 15)
- );
-}
-
-void
-print_xfer(usbd_xfer_handle xfer)
-{
- printf("xfer: length=%d, actlen=%d, flags=%x, timeout=%d,",
- xfer->length, xfer->actlen, xfer->flags, xfer->timeout);
- printf("request{ ");
- print_req_hub(&xfer->request);
- printf("} ");
-}
-#endif /* SLHCI_DEBUG */
diff --git a/sys/legacy/dev/usb/sl811hsreg.h b/sys/legacy/dev/usb/sl811hsreg.h
deleted file mode 100644
index f9c0328..0000000
--- a/sys/legacy/dev/usb/sl811hsreg.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* $NetBSD$ */
-/* $FreeBSD$ */
-
-
-/*
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Tetsuya Isaki.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ScanLogic SL811HS/T USB Host Controller
- */
-
-#define SL11_IDX_ADDR (0x00)
-#define SL11_IDX_DATA (0x01)
-#define SL11_PORTSIZE (0x02)
-
-#define SL11_E0BASE (0x00) /* Base of Control0 */
-#define SL11_E0CTRL (0x00) /* Host Control Register */
-#define SL11_E0ADDR (0x01) /* Host Base Address */
-#define SL11_E0LEN (0x02) /* Host Base Length */
-#define SL11_E0STAT (0x03) /* USB Status (Read) */
-#define SL11_E0PID SL11_E0STAT /* Host PID, Device Endpoint (Write) */
-#define SL11_E0CONT (0x04) /* Transfer Count (Read) */
-#define SL11_E0DEV SL11_E0CONT /* Host Device Address (Write) */
-
-#define SL11_E1BASE (0x08) /* Base of Control1 */
-#define SL11_E1CTRL (SL11_E1BASE + SL11_E0CTRL)
-#define SL11_E1ADDR (SL11_E1BASE + SL11_E0ADDR)
-#define SL11_E1LEN (SL11_E1BASE + SL11_E0LEN)
-#define SL11_E1STAT (SL11_E1BASE + SL11_E0STAT)
-#define SL11_E1PID (SL11_E1BASE + SL11_E0PID)
-#define SL11_E1CONT (SL11_E1BASE + SL11_E0CONT)
-#define SL11_E1DEV (SL11_E1BASE + SL11_E0DEV)
-
-#define SL11_CTRL (0x05) /* Control Register1 */
-#define SL11_IER (0x06) /* Interrupt Enable Register */
-#define SL11_ISR (0x0d) /* Interrupt Status Register */
-#define SL11_DATA (0x0e) /* SOF Counter Low (Write) */
-#define SL11_REV SL11_DATA /* HW Revision Register (Read) */
-#define SL811_CSOF (0x0f) /* SOF Counter High(R), Control2(W) */
-#define SL11_MEM (0x10) /* Memory Buffer (0x10 - 0xff) */
-
-#define SL11_EPCTRL_ARM (0x01)
-#define SL11_EPCTRL_ENABLE (0x02)
-#define SL11_EPCTRL_DIRECTION (0x04)
-#define SL11_EPCTRL_ISO (0x10)
-#define SL11_EPCTRL_SOF (0x20)
-#define SL11_EPCTRL_DATATOGGLE (0x40)
-#define SL11_EPCTRL_PREAMBLE (0x80)
-
-#define SL11_EPPID_PIDMASK (0xf0)
-#define SL11_EPPID_EPMASK (0x0f)
-
-#define SL11_EPSTAT_ACK (0x01)
-#define SL11_EPSTAT_ERROR (0x02)
-#define SL11_EPSTAT_TIMEOUT (0x04)
-#define SL11_EPSTAT_SEQUENCE (0x08)
-#define SL11_EPSTAT_SETUP (0x10)
-#define SL11_EPSTAT_OVERFLOW (0x20)
-#define SL11_EPSTAT_NAK (0x40)
-#define SL11_EPSTAT_STALL (0x80)
-
-#define SL11_CTRL_ENABLESOF (0x01)
-#define SL11_CTRL_EOF2 (0x04)
-#define SL11_CTRL_RESETENGINE (0x08)
-#define SL11_CTRL_JKSTATE (0x10)
-#define SL11_CTRL_LOWSPEED (0x20)
-#define SL11_CTRL_SUSPEND (0x40)
-
-#define SL11_IER_USBA (0x01) /* USB-A done */
-#define SL11_IER_USBB (0x02) /* USB-B done */
-#define SL11_IER_BABBLE (0x04) /* Babble detection */
-#define SL11_IER_SOFTIMER (0x10) /* 1ms SOF timer */
-#define SL11_IER_INSERT (0x20) /* Slave Insert/Remove detection */
-#define SL11_IER_RESET (0x40) /* USB Reset/Resume */
-
-#define SL11_ISR_USBA (0x01) /* USB-A done */
-#define SL11_ISR_USBB (0x02) /* USB-B done */
-#define SL11_ISR_BABBLE (0x04) /* Babble detection */
-#define SL11_ISR_SOFTIMER (0x10) /* 1ms SOF timer */
-#define SL11_ISR_INSERT (0x20) /* Slave Insert/Remove detection */
-#define SL11_ISR_RESET (0x40) /* USB Reset/Resume */
-#define SL11_ISR_DATA (0x80) /* Value of the Data+ pin */
-
-#define SL11_REV_USBA (0x01) /* USB-A */
-#define SL11_REV_USBB (0x02) /* USB-B */
-#define SL11_REV_REVMASK (0xf0) /* HW Revision */
-#define SL11_REV_REVSL11H (0x00) /* HW is SL11H */
-#define SL11_REV_REVSL811HS (0x10) /* HW is SL811HS */
-
-#define SL811_CSOF_SOFMASK (0x3f) /* SOF High Counter */
-#define SL811_CSOF_POLARITY (0x40) /* Change polarity */
-#define SL811_CSOF_MASTER (0x80) /* Master/Slave selection */
-
diff --git a/sys/legacy/dev/usb/sl811hsvar.h b/sys/legacy/dev/usb/sl811hsvar.h
deleted file mode 100644
index 6f5e6d6..0000000
--- a/sys/legacy/dev/usb/sl811hsvar.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* $NetBSD$ */
-/* $FreeBSD$ */
-
-/*
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Tetsuya Isaki.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ScanLogic SL811HS/T USB Host Controller
- */
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-#define delay_ms(X) \
- pause("slhci", MS_TO_TICKS(X))
-
-#define SL11_PID_OUT (0x1)
-#define SL11_PID_IN (0x9)
-#define SL11_PID_SOF (0x5)
-#define SL11_PID_SETUP (0xd)
-
-struct slhci_xfer {
- usbd_xfer_handle sx_xfer;
- usb_callout_t sx_callout_t;
-};
-
-struct slhci_softc {
- struct usbd_bus sc_bus;
- bus_space_tag_t sc_iot;
- bus_space_handle_t sc_ioh;
-
-#ifdef __FreeBSD__
- void *ih;
- struct resource *io_res;
- struct resource *irq_res;
-#endif
-
- void (*sc_enable_power)(void *, int);
- void (*sc_enable_intr)(void *, int);
- void *sc_arg;
- int sc_powerstat;
-#define POWER_ON (1)
-#define POWER_OFF (0)
-#define INTR_ON (1)
-#define INTR_OFF (0)
-
- struct device *sc_parent; /* parent device */
- int sc_sltype; /* revision */
-#define SLTYPE_SL11H (0x00)
-#define SLTYPE_SL811HS (0x01)
-#define SLTYPE_SL811HS_R12 SLTYPE_SL811HS
-#define SLTYPE_SL811HS_R14 (0x02)
-
- u_int8_t sc_addr; /* device address of root hub */
- u_int8_t sc_conf;
- STAILQ_HEAD(, usbd_xfer) sc_free_xfers;
-
- /* Information for the root hub interrupt pipe */
- int sc_interval;
- usbd_xfer_handle sc_intr_xfer;
- usb_callout_t sc_poll_handle;
-
- int sc_flags;
-#define SLF_RESET (0x01)
-#define SLF_INSERT (0x02)
-#define SLF_ATTACHED (0x04)
-
- /* Root HUB specific members */
- int sc_fullspeed;
- int sc_connect; /* XXX */
- int sc_change;
-};
-
-int sl811hs_find(struct slhci_softc *);
-int slhci_attach(struct slhci_softc *);
-int slhci_intr(void *);
diff --git a/sys/legacy/dev/usb/slhci_pccard.c b/sys/legacy/dev/usb/slhci_pccard.c
deleted file mode 100644
index 794b81d..0000000
--- a/sys/legacy/dev/usb/slhci_pccard.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*-
- * Copyright (C) 2005 Takanori Watanabe. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/malloc.h>
-#include <sys/sema.h>
-#include <sys/taskqueue.h>
-#include <vm/uma.h>
-#include <machine/stdarg.h>
-#include <machine/resource.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <dev/pccard/pccard_cis.h>
-#include <dev/pccard/pccardreg.h>
-#include <dev/pccard/pccardvar.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_port.h>
-#include <dev/usb/sl811hsvar.h>
-#include "pccarddevs.h"
-
-__FBSDID("$FreeBSD$");
-
-static void slhci_pccard_intr(void *arg);
-
-static const struct pccard_product slhci_pccard_products[] = {
- PCMCIA_CARD(RATOC, REX_CFU1),
- {NULL}
-};
-
-static int
-slhci_pccard_probe(device_t dev)
-{
- const struct pccard_product *pp;
- u_int32_t fcn = PCCARD_FUNCTION_UNSPEC;
- int error = 0;
-
- if ((error = pccard_get_function(dev, &fcn)))
- return error;
-
- /* if it says its a disk we should register it */
- if (fcn == PCCARD_FUNCTION_DISK)
- return 0;
-
- /* match other devices here, primarily cdrom/dvd rom */
- if ((pp = pccard_product_lookup(dev, slhci_pccard_products,
- sizeof(slhci_pccard_products[0]), NULL))) {
- if (pp->pp_name)
- device_set_desc(dev, pp->pp_name);
- return 0;
- }
- return ENXIO;
-}
-
-static int
-slhci_pccard_detach(device_t dev)
-{
- struct slhci_softc *sc = device_get_softc(dev);
- bus_generic_detach(dev);
-
- if (sc->ih)
- bus_teardown_intr(dev, sc->irq_res, sc->ih);
- if (sc->io_res)
- bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->io_res);
- if (sc->irq_res)
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
- if (sc->sc_bus.bdev)
- device_delete_child(dev, sc->sc_bus.bdev);
- return 0;
-}
-
-static int
-slhci_pccard_attach(device_t dev)
-{
- struct slhci_softc *sc = device_get_softc(dev);
- int error = ENXIO;
- int rid = 0;
- if ((sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE)) == NULL) {
- return ENOMEM;
- }
- sc->sc_iot = rman_get_bustag(sc->io_res);
- sc->sc_ioh = rman_get_bushandle(sc->io_res);
-
- if (sl811hs_find(sc) == -1) {
- error = ENXIO;
- goto out;
- }
-
- rid = 0;
- if ((sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
- printf("CANNOT ALLOC IRQ\n");
- error = ENOMEM;
- goto out;
- }
- sc->sc_iot = rman_get_bustag(sc->io_res);
- sc->sc_ioh = rman_get_bushandle(sc->io_res);
- sc->sc_bus.bdev = device_add_child(dev, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(dev, "Could not add USB device\n");
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
- error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO, NULL, slhci_pccard_intr, sc, &sc->ih);
- if (error)
- goto out;
-#if 1
-
- if (slhci_attach(sc) == -1) {
- printf("MI attach NO\n");
- goto out;
- }
-
- error = device_probe_and_attach(sc->sc_bus.bdev);
-
- if (error) {
- printf("Probing USB bus %x\n", error);
- goto out;
- }
-#endif
- printf("ATTACHED\n");
- return 0;
-out:
- slhci_pccard_detach(dev);
- return error;
-}
-
-#if 0
-static void
-slhci_pccard_enable_power(void *arg, int mode)
-{
-#if 0
- struct slhci_softc *sc = arg;
- u_int8_t r;
-#endif
-}
-
-static void
-slhci_pccard_enable_intr(void *arg, int mode)
-{
-#if 0
- struct slhci_softc *sc = arg;
- u_int8_t r;
-#endif
-}
-
-#endif
-static void
-slhci_pccard_intr(void *arg)
-{
-#if 1
- struct slhci_softc *sc = arg;
- sc = sc;
- slhci_intr(sc);
-#endif
-}
-
-static device_method_t slhci_pccard_methods[] = {
- /* device interface */
- DEVMETHOD(device_probe, slhci_pccard_probe),
- DEVMETHOD(device_attach, slhci_pccard_attach),
- DEVMETHOD(device_detach, slhci_pccard_detach),
-
- {0, 0}
-};
-
-static driver_t slhci_pccard_driver = {
- "slhci",
- slhci_pccard_methods,
- sizeof(struct slhci_softc),
-};
-
-devclass_t slhci_devclass;
-
-DRIVER_MODULE(slhci, pccard, slhci_pccard_driver, slhci_devclass, 0, 0);
-MODULE_DEPEND(slhci, usb, 1, 1, 1);
diff --git a/sys/legacy/dev/usb/u3g.c b/sys/legacy/dev/usb/u3g.c
deleted file mode 100644
index 8c6f67e..0000000
--- a/sys/legacy/dev/usb/u3g.c
+++ /dev/null
@@ -1,799 +0,0 @@
-/*
- * Copyright (c) 2008 AnyWi Technologies
- * Author: Andrea Guzzo <aguzzo@anywi.com>
- * * based on uark.c 1.1 2006/08/14 08:30:22 jsg *
- * * parts from ubsa.c 183348 2008-09-25 12:00:56Z phk *
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-/*
- * Notes:
- * - The detour through the tty layer is ridiculously expensive wrt buffering
- * due to the high speeds.
- * We should consider adding a simple r/w device which allows attaching of PPP
- * in a more efficient way.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include <dev/usb/ucomvar.h>
-
-#if __FreeBSD_version >= 800000
-#include "opt_u3g.h"
-#endif
-#include "usbdevs.h"
-
-//#define U3G_DEBUG
-#ifdef U3G_DEBUG
-#define DPRINTF(x...) do { if (u3gdebug) device_printf(sc->sc_dev, ##x); } while (0)
-int u3gdebug = 1;
-#else
-#define DPRINTF(x...) /* nop */
-#endif
-
-#define U3G_MAXPORTS 4
-#define U3G_CONFIG_INDEX 0
-
-struct u3g_softc {
- struct ucom_softc sc_ucom[U3G_MAXPORTS];
- device_t sc_dev;
- usbd_device_handle sc_udev;
- u_int8_t sc_speed;
- u_int8_t sc_flags;
- u_char sc_numports;
-};
-
-static int u3g_open(void *addr, int portno);
-static void u3g_close(void *addr, int portno);
-
-struct ucom_callback u3g_callback = {
- NULL,
- NULL,
- NULL,
- NULL,
- u3g_open,
- u3g_close,
- NULL,
- NULL,
-};
-
-
-struct u3g_speeds_s {
- u_int32_t ispeed;
- u_int32_t ospeed;
-};
-
-static const struct u3g_speeds_s u3g_speeds[] = {
-#define U3GSP_GPRS 0
- {64000, 64000},
-#define U3GSP_EDGE 1
- {384000, 64000},
-#define U3GSP_CDMA 2
- {384000, 64000},
-#define U3GSP_UMTS 3
- {384000, 64000},
-#define U3GSP_HSDPA 4
- {1200000, 384000},
-#define U3GSP_HSUPA 5
- {1200000, 384000},
-#define U3GSP_HSPA 6
- {7200000, 384000},
-};
-
-#define U3GIBUFSIZE 1024
-#define U3GOBUFSIZE 1024
-
-/*
- * Various supported device vendors/products.
- */
-struct u3g_dev_type_s {
- struct usb_devno devno;
- u_int8_t speed;
- u_int8_t flags;
-#define U3GFL_NONE 0x00
-#define U3GFL_HUAWEI_INIT 0x01 // Requires init command (Huawei cards)
-#define U3GFL_SCSI_EJECT 0x02 // Requires SCSI eject command (Novatel)
-#define U3GFL_SIERRA_INIT 0x04 // Requires init command (Sierra cards)
-#define U3GFL_CMOTECH_INIT 0x08 // Requires init command (CMOTECH cards)
-#define U3GFL_STUB_WAIT 0x80 // Device reappears after a short delay
-};
-
-// Note: The entries marked with XXX should be checked for the correct speed
-// indication to set the buffer sizes.
-static const struct u3g_dev_type_s u3g_devs[] = {
- /* OEM: Option */
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3G }, U3GSP_UMTS, U3GFL_NONE },
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD }, U3GSP_UMTS, U3GFL_NONE },
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS }, U3GSP_UMTS, U3GFL_NONE },
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36 }, U3GSP_HSDPA, U3GFL_NONE },
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAXHSUPA }, U3GSP_HSDPA, U3GFL_NONE },
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G }, U3GSP_UMTS, U3GFL_NONE },
- /* OEM: Qualcomm, Inc. */
- {{ USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_STOR }, U3GSP_CDMA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM }, U3GSP_CDMA, U3GFL_SCSI_EJECT },
- /* OEM: Huawei */
- {{ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE }, U3GSP_HSDPA, U3GFL_HUAWEI_INIT },
- {{ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220 }, U3GSP_HSPA, U3GFL_HUAWEI_INIT },
- /* OEM: Novatel */
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_CDMA_MODEM }, U3GSP_CDMA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ES620 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D }, U3GSP_HSUPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U720 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740 }, U3GSP_HSDPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740_2 }, U3GSP_HSDPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U870 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V620 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V640 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V740 }, U3GSP_HSDPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_X950D }, U3GSP_HSUPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_XU870 }, U3GSP_HSDPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD }, U3GSP_HSUPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_DELL, USB_PRODUCT_DELL_U740 }, U3GSP_HSDPA, U3GFL_SCSI_EJECT },
- /* OEM: Merlin */
- {{ USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- /* OEM: Sierra Wireless: */
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD595 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MINI5725 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC875U }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2 }, U3GSP_HSDPA, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_TRUINSTALL }, U3GSP_UMTS, U3GFL_SIERRA_INIT },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_HS2300 }, U3GSP_HSDPA, U3GFL_NONE },
- /* OEM: CMOTECH */
- {{ USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CGU628 }, U3GSP_HSDPA, U3GFL_CMOTECH_INIT },
- {{ USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_DISK }, U3GSP_HSDPA, U3GFL_NONE },
-};
-#define u3g_lookup(v, p) ((const struct u3g_dev_type_s *)usb_lookup(u3g_devs, v, p))
-
-static int
-u3g_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- const struct u3g_dev_type_s *u3g_dev_type;
-
- if (!uaa->iface)
- return UMATCH_NONE;
-
- u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product);
- if (!u3g_dev_type)
- return UMATCH_NONE;
-
- if (u3g_dev_type->flags&U3GFL_HUAWEI_INIT) {
- /* If the interface class of the first interface is no longer
- * mass storage the card has changed to modem (see u3g_attach()
- * below).
- */
- usb_interface_descriptor_t *id;
- id = usbd_get_interface_descriptor(uaa->iface);
- if (!id || id->bInterfaceClass == UICLASS_MASS)
- return UMATCH_NONE;
- }
-
- return UMATCH_VENDOR_PRODUCT_CONF_IFACE;
-}
-
-static int
-u3g_attach(device_t self)
-{
- struct u3g_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- const struct u3g_dev_type_s *u3g_dev_type;
- usbd_device_handle dev = uaa->device;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i, n;
- usb_config_descriptor_t *cd;
- char devnamefmt[32];
-
-#if __FreeBSD_version < 700000
- char *devinfo = malloc(1024, M_USBDEV, M_WAITOK);
- usbd_devinfo(dev, 0, devinfo);
- device_printf(self, "%s\n", devinfo);
- free(devinfo, M_USBDEV);
-#endif
-
- /* get the config descriptor */
- cd = usbd_get_config_descriptor(dev);
- if (cd == NULL) {
- device_printf(self, "failed to get configuration descriptor\n");
- return ENXIO;
- }
-
- sc->sc_dev = self;
- sc->sc_udev = dev;
-
- u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product);
- sc->sc_flags = u3g_dev_type->flags;
- sc->sc_speed = u3g_dev_type->speed;
-
- sprintf(devnamefmt,"U%d.%%d", device_get_unit(self));
- int portno = 0;
- for (i = 0; i < uaa->nifaces && portno < U3G_MAXPORTS; i++) {
- if (uaa->ifaces[i] == NULL)
- continue;
-
- id = usbd_get_interface_descriptor(uaa->ifaces[i]);
- if (id && id->bInterfaceClass == UICLASS_MASS) {
- /* We attach to the interface instead of the device as
- * some devices have a built-in SD card reader.
- * Claim the first umass device (cdX) as it contains
- * only Windows drivers anyway (CD-ROM), hiding it.
- */
-#ifndef U3G_DEBUG
- if (!bootverbose)
- if (uaa->vendor == USB_VENDOR_HUAWEI)
- if (id->bInterfaceNumber == 2)
- uaa->ifaces[i] = NULL;
-#endif
- continue;
- }
-
- int bulkin_no = -1, bulkout_no = -1;
- int claim_iface = 0;
- for (n = 0; n < id->bNumEndpoints && portno < U3G_MAXPORTS; n++) {
- ed = usbd_interface2endpoint_descriptor(uaa->ifaces[i], n);
- if (ed == NULL)
- continue;
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
- && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- bulkin_no = ed->bEndpointAddress;
- else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
- && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- bulkout_no = ed->bEndpointAddress;
-
- /* If we have found a pair of bulk-in/-out endpoints
- * create a serial port for it. Note: We assume that
- * the bulk-in and bulk-out endpoints appear in pairs.
- */
- if (bulkin_no != -1 && bulkout_no != -1) {
- struct ucom_softc *ucom = &sc->sc_ucom[portno];
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->ifaces[i];
- ucom->sc_bulkin_no = bulkin_no;
- ucom->sc_bulkout_no = bulkout_no;
- ucom->sc_ibufsize = U3GIBUFSIZE;
- ucom->sc_ibufsizepad = U3GIBUFSIZE;
- ucom->sc_obufsize = U3GOBUFSIZE;
- ucom->sc_opkthdrlen = 0;
-
- ucom->sc_callback = &u3g_callback;
- ucom->sc_parent = sc;
- ucom->sc_portno = portno;
-
- DPRINTF("port=%d iface=%d in=0x%x out=0x%x\n",
- portno, i,
- ucom->sc_bulkin_no,
- ucom->sc_bulkout_no);
-#if __FreeBSD_version < 700000
- ucom_attach_tty(ucom, MINOR_CALLOUT, devnamefmt, portno);
-#elif __FreeBSD_version < 800000
- ucom_attach_tty(ucom, TS_CALLOUT, devnamefmt, portno);
-#else
- ucom_attach_tty(ucom, devnamefmt, portno);
-#endif
-
- claim_iface = 1;
- portno++;
- bulkin_no = bulkout_no = -1;
- }
- }
- if (claim_iface)
- uaa->ifaces[i] = NULL; // claim the interface
- }
- sc->sc_numports = portno;
-
- device_printf(self, "configured %d serial ports (%s)\n",
- sc->sc_numports, devnamefmt);
- return 0;
-}
-
-static int
-u3g_detach(device_t self)
-{
- struct u3g_softc *sc = device_get_softc(self);
- int rv = 0;
- int i;
-
- for (i = 0; i < sc->sc_numports; i++) {
- sc->sc_ucom[i].sc_dying = 1;
- rv = ucom_detach(&sc->sc_ucom[i]);
- if (rv != 0) {
- device_printf(self, "ucom_detach(U%d.%d\n", device_get_unit(self), i);
- return rv;
- }
- }
-
- return 0;
-}
-
-static int
-u3g_open(void *addr, int portno)
-{
-#if __FreeBSD_version < 800000
- /* Supply generous buffering for these cards to avoid disappointments
- * when setting the speed incorrectly. Only do this for the first port
- * assuming that the rest of the ports are used for diagnostics only
- * anyway.
- * Note: We abuse the fact that ucom sets the speed through
- * ispeed/ospeed, not through ispeedwat/ospeedwat.
- */
- if (portno == 0) {
- struct u3g_softc *sc = addr;
- struct ucom_softc *ucom = &sc->sc_ucom[portno];
- struct tty *tp = ucom->sc_tty;
-
- tp->t_ispeedwat = u3g_speeds[sc->sc_speed].ispeed;
- tp->t_ospeedwat = u3g_speeds[sc->sc_speed].ospeed;
-
- /* Avoid excessive buffer sizes.
- * XXX The values here should be checked. Lower them and see
- * whether 'lost chars' messages appear.
- */
- if (tp->t_ispeedwat > 384000)
- tp->t_ispeedwat = 384000;
- if (tp->t_ospeedwat > 384000)
- tp->t_ospeedwat = 384000;
-
- ttsetwater(tp);
- }
-#endif
-
- return 0;
-}
-
-static void
-u3g_close(void *addr, int portno)
-{
-#if __FreeBSD_version < 800000
- if (portno == 0) { /* see u3g_open() */
- /* Reduce the buffers allocated above again */
- struct u3g_softc *sc = addr;
- struct ucom_softc *ucom = &sc->sc_ucom[portno];
- struct tty *tp = ucom->sc_tty;
-#ifdef U3G_DEBUG
- device_t self = sc->sc_dev;
-#endif
-
- tp->t_ispeedwat = (speed_t)-1;
- tp->t_ospeedwat = (speed_t)-1;
-
- ttsetwater(tp);
- }
-#endif
-}
-
-static device_method_t u3g_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, u3g_match),
- DEVMETHOD(device_attach, u3g_attach),
- DEVMETHOD(device_detach, u3g_detach),
-
- { 0, 0 }
-};
-
-static driver_t u3g_driver = {
- "ucom",
- u3g_methods,
- sizeof (struct u3g_softc)
-};
-
-DRIVER_MODULE(u3g, uhub, u3g_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(u3g, usb, 1, 1, 1);
-MODULE_DEPEND(u3g, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(u3g, 1);
-
-/*******************************************************************
- ****** Stub driver to hide devices that need to reinitialise ******
- *******************************************************************/
-
-struct u3gstub_softc {
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_pipe_handle sc_pipe_out, sc_pipe_in;
- usbd_xfer_handle sc_xfer;
-};
-
-static int
-u3gstub_huawei_init(struct u3gstub_softc *sc, struct usb_attach_arg *uaa)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_SET_FEATURE;
- USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
- USETW(req.wIndex, UHF_PORT_SUSPEND);
- USETW(req.wLength, 0);
-
- (void) usbd_do_request(uaa->device, &req, 0); /* ignore any error */
-
- return 1;
-}
-
-static void
-u3gstub_BBB_cb(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status err)
-{
- struct u3gstub_softc *sc = (struct u3gstub_softc *) priv;
- unsigned char cmd[13];
-
- if (err) {
- device_printf(sc->sc_dev,
- "Failed to send CD eject command to "
- "change to modem mode\n");
- } else {
- usbd_setup_xfer(sc->sc_xfer, sc->sc_pipe_in, NULL, cmd, sizeof(cmd),
- 0, USBD_DEFAULT_TIMEOUT, NULL);
- int err = usbd_transfer(sc->sc_xfer) != USBD_NORMAL_COMPLETION;
- if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS)
- DPRINTF("failed to start transfer (CSW)\n");
- }
-}
-
-static int
-u3gstub_scsi_eject(struct u3gstub_softc *sc, struct usb_attach_arg *uaa)
-{
- /* See definition of umass_bbb_cbw_t in sys/dev/usb/umass.c and struct
- * scsi_start_stop_unit in sys/cam/scsi/scsi_all.h .
- */
- unsigned char cmd[31] = {
- 0x55, 0x53, 0x42, 0x43, /* 0..3: Command Block Wrapper (CBW) signature */
- 0x01, 0x00, 0x00, 0x00, /* 4..7: CBW Tag, unique 32-bit number */
- 0x00, 0x00, 0x00, 0x00, /* 8..11: CBW Transfer Length, no data here */
- 0x00, /* 12: CBW Flag: output */
- 0x00, /* 13: CBW Lun */
- 0x06, /* 14: CBW Length */
-
- 0x1b, /* 15+0: opcode: SCSI START/STOP */
- 0x00, /* 15+1: byte2: Not immediate */
- 0x00, 0x00, /* 15+2..3: reserved */
- 0x02, /* 15+4: Load/Eject command */
- 0x00, /* 15+5: control */
- 0x00, 0x00, 0x00, 0x00, /* 15+6..15: unused */
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
- };
-
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed = NULL;
- int i;
-
-
- /* Find the bulk-out endpoints */
- id = usbd_get_interface_descriptor(uaa->iface);
- for (i = 0 ; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(uaa->iface, i);
- if (ed != NULL
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) {
- if (usbd_open_pipe(uaa->iface,
- ed->bEndpointAddress,
- USBD_EXCLUSIVE_USE,
- &sc->sc_pipe_out)
- != USBD_NORMAL_COMPLETION) {
- DPRINTF("failed to open bulk-out pipe on endpoint %d\n",
- ed->bEndpointAddress);
- return 0;
- }
- } else {
- if (usbd_open_pipe(uaa->iface,
- ed->bEndpointAddress,
- USBD_EXCLUSIVE_USE,
- &sc->sc_pipe_in)
- != USBD_NORMAL_COMPLETION) {
- DPRINTF("failed to open bulk-in pipe on endpoint %d\n",
- ed->bEndpointAddress);
- return 0;
- }
- }
- }
- if (sc->sc_pipe_out && sc->sc_pipe_in)
- break;
- }
-
- if (i == id->bNumEndpoints) {
- DPRINTF("failed to find bulk-out pipe\n");
- return 0;
- }
-
- sc->sc_xfer = usbd_alloc_xfer(uaa->device);
- if (sc->sc_xfer == NULL) {
- DPRINTF("failed to allocate xfer\n");
- return 0;
- }
-
- usbd_setup_xfer(sc->sc_xfer, sc->sc_pipe_out, NULL, cmd, sizeof(cmd),
- 0, USBD_DEFAULT_TIMEOUT, u3gstub_BBB_cb);
- int err = usbd_transfer(sc->sc_xfer) != USBD_NORMAL_COMPLETION;
- if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS) {
- DPRINTF("failed to start transfer (CBW)\n");
- return 0;
- }
-
- return 1;
-}
-
-static int
-u3gstub_cmotech_init(struct u3gstub_softc *sc, struct usb_attach_arg *uaa)
-{
- /* See definition of umass_bbb_cbw_t in sys/dev/usb/umass.c
- * in sys/cam/scsi/scsi_all.h .
- */
- unsigned char cmd[31] = {
- 0x55, 0x53, 0x42, 0x43, /* 0..3: Command Block Wrapper (CBW) signature */
- 0x01, 0x00, 0x00, 0x00, /* 4..7: CBW Tag, unique 32-bit number */
- 0x00, 0x00, 0x00, 0x00, /* 8..11: CBW Transfer Length, no data here */
- 0x80, /* 12: CBW Flag: output, so 0 */
- 0x00, /* 13: CBW Lun */
- 0x08, /* 14: CBW Length */
-
- 0xff, /* 15+0 */
- 0x52, /* 15+1 */
- 0x44, /* 15+2 */
- 0x45, /* 15+2 */
- 0x56, /* 15+4 */
- 0x43, /* 15+5 */
- 0x48, /* 15+5 */
- 0x47, /* 15+5 */
- 0x00, 0x00, 0x00, 0x00, /* 15+8..15: unused */
- 0x00, 0x00, 0x00, 0x00
- };
-
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed = NULL;
- int i;
-
-
- /* Find the bulk-out endpoints */
- id = usbd_get_interface_descriptor(uaa->iface);
- for (i = 0 ; i < id->bNumEndpoints ; i++) {
- ed = usbd_interface2endpoint_descriptor(uaa->iface, i);
- if (ed != NULL
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) {
- if (usbd_open_pipe(uaa->iface,
- ed->bEndpointAddress,
- USBD_EXCLUSIVE_USE,
- &sc->sc_pipe_out)
- != USBD_NORMAL_COMPLETION) {
- DPRINTF("failed to open bulk-out pipe on endpoint %d\n",
- ed->bEndpointAddress);
- return 0;
- }
- } else {
- if (usbd_open_pipe(uaa->iface,
- ed->bEndpointAddress,
- USBD_EXCLUSIVE_USE,
- &sc->sc_pipe_in)
- != USBD_NORMAL_COMPLETION) {
- DPRINTF("failed to open bulk-in pipe on endpoint %d\n",
- ed->bEndpointAddress);
- return 0;
- }
- }
- }
- if (sc->sc_pipe_out && sc->sc_pipe_in)
- break;
- }
-
- if (i == id->bNumEndpoints) {
- DPRINTF("failed to find bulk-out pipe\n");
- return 0;
- }
-
- sc->sc_xfer = usbd_alloc_xfer(uaa->device);
- if (sc->sc_xfer == NULL) {
- DPRINTF("failed to allocate xfer\n");
- return 0;
- }
-
- usbd_setup_xfer(sc->sc_xfer, sc->sc_pipe_out, NULL, cmd, sizeof(cmd),
- 0, USBD_DEFAULT_TIMEOUT, u3gstub_BBB_cb);
- int err = usbd_transfer(sc->sc_xfer) != USBD_NORMAL_COMPLETION;
- if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS) {
- DPRINTF("failed to start transfer (CBW)\n");
- return 0;
- }
-
- return 1;
-}
-
-static int
-u3gstub_sierra_init(struct u3gstub_softc *sc, struct usb_attach_arg *uaa)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_VENDOR;
- req.bRequest = UR_SET_INTERFACE;
- USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
- USETW(req.wIndex, UHF_PORT_CONNECTION);
- USETW(req.wLength, 0);
-
- (void) usbd_do_request(uaa->device, &req, 0); /* ignore any error */
-
- return 1;
-}
-
-static int
-u3gstub_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- const struct u3g_dev_type_s *u3g_dev_type;
- usb_interface_descriptor_t *id;
-
- /* This stub handles 3G modem devices (E220, Mobile, etc.) with
- * auto-install flash disks for Windows/MacOSX on the first interface.
- * After some command or some delay they change appearance to a modem.
- */
-
- if (!uaa->iface)
- return UMATCH_NONE;
-
- u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product);
- if (!u3g_dev_type)
- return UMATCH_NONE;
-
- if (u3g_dev_type->flags&U3GFL_HUAWEI_INIT
- || u3g_dev_type->flags&U3GFL_SCSI_EJECT
- || u3g_dev_type->flags&U3GFL_SIERRA_INIT
- || u3g_dev_type->flags&U3GFL_CMOTECH_INIT
- || u3g_dev_type->flags&U3GFL_STUB_WAIT) {
- /* We assume that if the first interface is still a mass
- * storage device the device has not yet changed appearance.
- */
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id && id->bInterfaceNumber == 0
- && id->bInterfaceClass == UICLASS_MASS) {
-#ifndef U3G_DEBUG
- if (!bootverbose)
- device_quiet(self);
-#endif
-
- return UMATCH_VENDOR_PRODUCT;
- }
- }
-
- return UMATCH_NONE;
-}
-
-static int
-u3gstub_attach(device_t self)
-{
- struct u3gstub_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- const struct u3g_dev_type_s *u3g_dev_type;
- int i;
-
-#ifndef U3G_DEBUG
- if (!bootverbose)
- device_quiet(self);
-#endif
-
- sc->sc_dev = self;
- sc->sc_udev = uaa->device;
-
- for (i = 0; i < uaa->nifaces; i++)
- uaa->ifaces[i] = NULL; // claim all interfaces
-
- u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product);
- if (u3g_dev_type->flags&U3GFL_HUAWEI_INIT) {
- if (bootverbose)
- device_printf(sc->sc_dev,
- "changing Huawei modem to modem mode\n");
- if (!u3gstub_huawei_init(sc, uaa))
- return ENXIO;
- } else if (u3g_dev_type->flags&U3GFL_SCSI_EJECT) {
- if (bootverbose)
- device_printf(sc->sc_dev, "sending CD eject command to "
- "change to modem mode\n");
- if (!u3gstub_scsi_eject(sc, uaa))
- return ENXIO;
- } else if (u3g_dev_type->flags&U3GFL_SIERRA_INIT) {
- if (bootverbose)
- device_printf(sc->sc_dev,
- "changing Sierra modem to modem mode\n");
- if (!u3gstub_sierra_init(sc, uaa))
- return ENXIO;
- } else if (u3g_dev_type->flags&U3GFL_CMOTECH_INIT) {
- if (bootverbose)
- device_printf(sc->sc_dev,
- "changing CMOTECH modem to modem mode\n");
- if (!u3gstub_cmotech_init(sc, uaa))
- return ENXIO;
- } else if (u3g_dev_type->flags&U3GFL_STUB_WAIT) {
- if (bootverbose)
- device_printf(sc->sc_dev, "waiting for modem to change "
- "to modem mode\n");
- /* nop */
- }
-
- return 0;
-}
-
-static int
-u3gstub_detach(device_t self)
-{
- struct u3gstub_softc *sc = device_get_softc(self);
-
- if (sc->sc_xfer)
- usbd_free_xfer(sc->sc_xfer);
-
- if (sc->sc_pipe_in) {
- usbd_abort_pipe(sc->sc_pipe_in);
- usbd_close_pipe(sc->sc_pipe_in);
- }
- if (sc->sc_pipe_out) {
- usbd_abort_pipe(sc->sc_pipe_out);
- usbd_close_pipe(sc->sc_pipe_out);
- }
-
- return 0;
-}
-
-static device_method_t u3gstub_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, u3gstub_match),
- DEVMETHOD(device_attach, u3gstub_attach),
- DEVMETHOD(device_detach, u3gstub_detach),
-
- { 0, 0 }
-};
-
-static driver_t u3gstub_driver = {
- "u3g",
- u3gstub_methods,
- sizeof (struct u3gstub_softc)
-};
-
-DRIVER_MODULE(u3gstub, uhub, u3gstub_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(u3gstub, usb, 1, 1, 1);
diff --git a/sys/legacy/dev/usb/uark.c b/sys/legacy/dev/usb/uark.c
deleted file mode 100644
index af85819..0000000
--- a/sys/legacy/dev/usb/uark.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/* $OpenBSD: uark.c,v 1.1 2006/08/14 08:30:22 jsg Exp $ */
-
-/*
- * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/ucomvar.h>
-
-#ifdef UARK_DEBUG
-#define DPRINTFN(n, x) do { \
- if (uarkdebug > (n)) \
- printf x; \
-} while (0)
-int uarkebug = 0;
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define UARKBUFSZ 256
-#define UARK_CONFIG_NO 0
-#define UARK_IFACE_NO 0
-
-#define UARK_SET_DATA_BITS(x) (x - 5)
-
-#define UARK_PARITY_NONE 0x00
-#define UARK_PARITY_ODD 0x08
-#define UARK_PARITY_EVEN 0x18
-
-#define UARK_STOP_BITS_1 0x00
-#define UARK_STOP_BITS_2 0x04
-
-#define UARK_BAUD_REF 3000000
-
-#define UARK_WRITE 0x40
-#define UARK_READ 0xc0
-
-#define UARK_REQUEST 0xfe
-
-#define UARK_CONFIG_INDEX 0
-#define UARK_IFACE_INDEX 0
-
-struct uark_softc {
- struct ucom_softc sc_ucom;
- usbd_interface_handle sc_iface;
-
- u_char sc_msr;
- u_char sc_lsr;
-};
-
-static void uark_get_status(void *, int portno, u_char *lsr, u_char *msr);
-static void uark_set(void *, int, int, int);
-static int uark_param(void *, int, struct termios *);
-static void uark_break(void *, int, int);
-static int uark_cmd(struct uark_softc *, uint16_t, uint16_t);
-
-struct ucom_callback uark_callback = {
- uark_get_status,
- uark_set,
- uark_param,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
-};
-
-static const struct usb_devno uark_devs[] = {
- { USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116 }
-};
-
-static int
-uark_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- return (usb_lookup(uark_devs, uaa->vendor, uaa->product) != NULL) ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
-}
-
-static int
-uark_attach(device_t self)
-{
- struct uark_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_interface_handle iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_status error;
- int i;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
-
- if (uaa->iface == NULL) {
- /* Move the device into the configured state. */
- error = usbd_set_config_index(dev, UARK_CONFIG_INDEX, 1);
- if (error) {
- device_printf(ucom->sc_dev,
- "failed to set configuration, err=%s\n",
- usbd_errstr(error));
- goto bad;
- }
- error =
- usbd_device2interface_handle(dev, UARK_IFACE_INDEX, &iface);
- if (error) {
- device_printf(ucom->sc_dev,
- "failed to get interface, err=%s\n",
- usbd_errstr(error));
- goto bad;
- }
- } else
- iface = uaa->iface;
-
- id = usbd_get_interface_descriptor(iface);
- ucom->sc_iface = iface;
-
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- device_printf(ucom->sc_dev,
- "could not read endpoint descriptor\n");
- goto bad;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
- if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) {
- device_printf(ucom->sc_dev, "missing endpoint\n");
- goto bad;
- }
- ucom->sc_parent = sc;
- ucom->sc_ibufsize = UARKBUFSZ;
- ucom->sc_obufsize = UARKBUFSZ;
- ucom->sc_ibufsizepad = UARKBUFSZ;
- ucom->sc_opkthdrlen = 0;
-
- ucom->sc_callback = &uark_callback;
-
- DPRINTF(("uark: in=0x%x out=0x%x\n", ucom->sc_bulkin_no, ucom->sc_bulkout_no));
- ucom_attach(&sc->sc_ucom);
- return 0;
-
-bad:
- DPRINTF(("uark_attach: ATTACH ERROR\n"));
- ucom->sc_dying = 1;
- return ENXIO;
-}
-
-static int
-uark_detach(device_t self)
-{
- struct uark_softc *sc = device_get_softc(self);
- int rv = 0;
-
- DPRINTF(("uark_detach: sc=%p\n", sc));
- sc->sc_ucom.sc_dying = 1;
- rv = ucom_detach(&sc->sc_ucom);
-
- return (rv);
-}
-
-static void
-uark_set(void *vsc, int portno, int reg, int onoff)
-{
- struct uark_softc *sc = vsc;
-
- switch (reg) {
- case UCOM_SET_BREAK:
- uark_break(sc, portno, onoff);
- return;
- /* NOTREACHED */
- case UCOM_SET_DTR:
- case UCOM_SET_RTS:
- default:
- return;
- /* NOTREACHED */
- }
-}
-
-static int
-uark_param(void *vsc, int portno, struct termios *t)
-{
- struct uark_softc *sc = (struct uark_softc *)vsc;
- int data, divisor;
- speed_t speed = t->c_ospeed;
-
- if (speed < 300 || speed > 115200)
- return (EINVAL);
- divisor = (UARK_BAUD_REF + speed / 2) / speed;
- /* Check that we're within 3% of the requested rate. */
- if (speed * divisor < UARK_BAUD_REF * 100 / 103 ||
- speed * divisor > UARK_BAUD_REF * 100 / 97)
- return (EINVAL);
- uark_cmd(sc, 3, 0x83);
- uark_cmd(sc, 0, divisor & 0xFF);
- uark_cmd(sc, 1, divisor >> 8);
- uark_cmd(sc, 3, 0x03);
-
- if (ISSET(t->c_cflag, CSTOPB))
- data = UARK_STOP_BITS_2;
- else
- data = UARK_STOP_BITS_1;
-
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- data |= UARK_PARITY_ODD;
- else
- data |= UARK_PARITY_EVEN;
- } else
- data |= UARK_PARITY_NONE;
-
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- data |= UARK_SET_DATA_BITS(5);
- break;
- case CS6:
- data |= UARK_SET_DATA_BITS(6);
- break;
- case CS7:
- data |= UARK_SET_DATA_BITS(7);
- break;
- case CS8:
- data |= UARK_SET_DATA_BITS(8);
- break;
- }
- uark_cmd(sc, 3, 0x00);
- uark_cmd(sc, 3, data);
-
- return (0);
-}
-
-void
-uark_get_status(void *vsc, int portno, u_char *lsr, u_char *msr)
-{
- struct uark_softc *sc = vsc;
-
- if (msr != NULL)
- *msr = sc->sc_msr;
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
-}
-
-void
-uark_break(void *vsc, int portno, int onoff)
-{
-#ifdef UARK_DEBUG
- struct uark_softc *sc = vsc;
-
- device_printf(sc->sc_dev, "%s: break %s!\n", onoff ? "on" : "off");
- if (onoff)
- /* break on */
- uark_cmd(sc, 4, 0x01);
- else
- uark_cmd(sc, 4, 0x00);
-#endif
-}
-
-int
-uark_cmd(struct uark_softc *sc, uint16_t index, uint16_t value)
-{
- usb_device_request_t req;
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- req.bmRequestType = UARK_WRITE;
- req.bRequest = UARK_REQUEST;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, 0);
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
-
- if (err)
- return (EIO);
-
- return (0);
-}
-
-static device_method_t uark_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uark_match),
- DEVMETHOD(device_attach, uark_attach),
- DEVMETHOD(device_detach, uark_detach),
-
- { 0, 0 }
-};
-
-static driver_t uark_driver = {
- "ucom",
- uark_methods,
- sizeof (struct uark_softc)
-};
-
-DRIVER_MODULE(uark, uhub, uark_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uark, usb, 1, 1, 1);
-MODULE_DEPEND(uark, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
diff --git a/sys/legacy/dev/usb/ubsa.c b/sys/legacy/dev/usb/ubsa.c
deleted file mode 100644
index b66cce8..0000000
--- a/sys/legacy/dev/usb/ubsa.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/*-
- * Copyright (c) 2002, Alexander Kabaev <kan.FreeBSD.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Ichiro FUKUHARA (ichiro@ichiro.org).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/taskqueue.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-#ifdef USB_DEBUG
-static int ubsadebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ubsa, CTLFLAG_RW, 0, "USB ubsa");
-SYSCTL_INT(_hw_usb_ubsa, OID_AUTO, debug, CTLFLAG_RW,
- &ubsadebug, 0, "ubsa debug level");
-
-#define DPRINTFN(n, x) do { \
- if (ubsadebug > (n)) \
- printf x; \
- } while (0)
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define UBSA_MODVER 1 /* module version */
-
-#define UBSA_CONFIG_INDEX 1
-#define UBSA_IFACE_INDEX 0
-
-#define UBSA_INTR_INTERVAL 100 /* ms */
-
-#define UBSA_SET_BAUDRATE 0x00
-#define UBSA_SET_STOP_BITS 0x01
-#define UBSA_SET_DATA_BITS 0x02
-#define UBSA_SET_PARITY 0x03
-#define UBSA_SET_DTR 0x0A
-#define UBSA_SET_RTS 0x0B
-#define UBSA_SET_BREAK 0x0C
-#define UBSA_SET_FLOW_CTRL 0x10
-
-#define UBSA_PARITY_NONE 0x00
-#define UBSA_PARITY_EVEN 0x01
-#define UBSA_PARITY_ODD 0x02
-#define UBSA_PARITY_MARK 0x03
-#define UBSA_PARITY_SPACE 0x04
-
-#define UBSA_FLOW_NONE 0x0000
-#define UBSA_FLOW_OCTS 0x0001
-#define UBSA_FLOW_ODSR 0x0002
-#define UBSA_FLOW_IDSR 0x0004
-#define UBSA_FLOW_IDTR 0x0008
-#define UBSA_FLOW_IRTS 0x0010
-#define UBSA_FLOW_ORTS 0x0020
-#define UBSA_FLOW_UNKNOWN 0x0040
-#define UBSA_FLOW_OXON 0x0080
-#define UBSA_FLOW_IXON 0x0100
-
-/* line status register */
-#define UBSA_LSR_TSRE 0x40 /* Transmitter empty: byte sent */
-#define UBSA_LSR_TXRDY 0x20 /* Transmitter buffer empty */
-#define UBSA_LSR_BI 0x10 /* Break detected */
-#define UBSA_LSR_FE 0x08 /* Framing error: bad stop bit */
-#define UBSA_LSR_PE 0x04 /* Parity error */
-#define UBSA_LSR_OE 0x02 /* Overrun, lost incoming byte */
-#define UBSA_LSR_RXRDY 0x01 /* Byte ready in Receive Buffer */
-#define UBSA_LSR_RCV_MASK 0x1f /* Mask for incoming data or error */
-
-/* modem status register */
-/* All deltas are from the last read of the MSR. */
-#define UBSA_MSR_DCD 0x80 /* Current Data Carrier Detect */
-#define UBSA_MSR_RI 0x40 /* Current Ring Indicator */
-#define UBSA_MSR_DSR 0x20 /* Current Data Set Ready */
-#define UBSA_MSR_CTS 0x10 /* Current Clear to Send */
-#define UBSA_MSR_DDCD 0x08 /* DCD has changed state */
-#define UBSA_MSR_TERI 0x04 /* RI has toggled low to high */
-#define UBSA_MSR_DDSR 0x02 /* DSR has changed state */
-#define UBSA_MSR_DCTS 0x01 /* CTS has changed state */
-
-struct ubsa_softc {
- struct ucom_softc sc_ucom;
-
- int sc_iface_number; /* interface number */
-
- usbd_interface_handle sc_intr_iface; /* interrupt interface */
- int sc_intr_number; /* interrupt number */
- usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */
- u_char *sc_intr_buf; /* interrupt buffer */
- int sc_isize;
-
- u_char sc_dtr; /* current DTR state */
- u_char sc_rts; /* current RTS state */
-
- u_char sc_lsr; /* Local status register */
- u_char sc_msr; /* ubsa status register */
- struct task sc_task;
-};
-
-static void ubsa_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void ubsa_notify(void *, int count);
-
-static void ubsa_get_status(void *, int, u_char *, u_char *);
-static void ubsa_set(void *, int, int, int);
-static int ubsa_param(void *, int, struct termios *);
-static int ubsa_open(void *, int);
-static void ubsa_close(void *, int);
-
-static int ubsa_request(struct ubsa_softc *, u_int8_t, u_int16_t);
-static void ubsa_dtr(struct ubsa_softc *, int);
-static void ubsa_rts(struct ubsa_softc *, int);
-static void ubsa_baudrate(struct ubsa_softc *, speed_t);
-static void ubsa_parity(struct ubsa_softc *, tcflag_t);
-static void ubsa_databits(struct ubsa_softc *, tcflag_t);
-static void ubsa_stopbits(struct ubsa_softc *, tcflag_t);
-static void ubsa_flow(struct ubsa_softc *, tcflag_t, tcflag_t);
-
-struct ucom_callback ubsa_callback = {
- ubsa_get_status,
- ubsa_set,
- ubsa_param,
- NULL,
- ubsa_open,
- ubsa_close,
- NULL,
- NULL
-};
-
-static const struct ubsa_product {
- uint16_t vendor;
- uint16_t product;
-} ubsa_products [] = {
- /* AnyData ADU-500A */
- { USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_500A },
- /* AnyData ADU-E100A/H */
- { USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_E100X },
- /* Axesstel MV100H */
- { USB_VENDOR_AXESSTEL, USB_PRODUCT_AXESSTEL_DATAMODEM },
- /* BELKIN F5U103 */
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U103 },
- /* BELKIN F5U120 */
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U120 },
- /* GoHubs GO-COM232 */
- { USB_VENDOR_ETEK, USB_PRODUCT_ETEK_1COM },
- /* GoHubs GO-COM232 */
- { USB_VENDOR_GOHUBS, USB_PRODUCT_GOHUBS_GOCOM232 },
- /* Peracom */
- { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1 },
- { 0, 0 }
-};
-
-static device_probe_t ubsa_match;
-static device_attach_t ubsa_attach;
-static device_detach_t ubsa_detach;
-
-static device_method_t ubsa_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ubsa_match),
- DEVMETHOD(device_attach, ubsa_attach),
- DEVMETHOD(device_detach, ubsa_detach),
- { 0, 0 }
-};
-
-static driver_t ubsa_driver = {
- "ucom",
- ubsa_methods,
- sizeof (struct ubsa_softc)
-};
-
-DRIVER_MODULE(ubsa, uhub, ubsa_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(ubsa, usb, 1, 1, 1);
-MODULE_DEPEND(ubsa, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(ubsa, UBSA_MODVER);
-
-static int
-ubsa_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- int i;
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- for (i = 0; ubsa_products[i].vendor != 0; i++) {
- if (ubsa_products[i].vendor == uaa->vendor &&
- ubsa_products[i].product == uaa->product) {
- return (UMATCH_VENDOR_PRODUCT);
- }
- }
- return (UMATCH_NONE);
-}
-
-static int
-ubsa_attach(device_t self)
-{
- struct ubsa_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev;
- struct ucom_softc *ucom;
- usb_config_descriptor_t *cdesc;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_status err;
- int i;
-
- dev = uaa->device;
- ucom = &sc->sc_ucom;
-
- /*
- * initialize rts, dtr variables to something
- * different from boolean 0, 1
- */
- sc->sc_dtr = -1;
- sc->sc_rts = -1;
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- DPRINTF(("ubsa attach: sc = %p\n", sc));
-
- /* initialize endpoints */
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- sc->sc_intr_number = -1;
- sc->sc_intr_pipe = NULL;
-
- /* Move the device into the configured state. */
- err = usbd_set_config_index(dev, UBSA_CONFIG_INDEX, 1);
- if (err) {
- device_printf(ucom->sc_dev, "failed to set configuration: %s\n",
- usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* get the config descriptor */
- cdesc = usbd_get_config_descriptor(ucom->sc_udev);
-
- if (cdesc == NULL) {
- device_printf(ucom->sc_dev,
- "failed to get configuration descriptor\n");
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* get the first interface */
- err = usbd_device2interface_handle(dev, UBSA_IFACE_INDEX,
- &ucom->sc_iface);
- if (err) {
- device_printf(ucom->sc_dev, "failed to get interface: %s\n",
- usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* Find the endpoints */
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
- sc->sc_iface_number = id->bInterfaceNumber;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- device_printf(ucom->sc_dev,
- "no endpoint descriptor for %d\n", i);
- ucom->sc_dying = 1;
- goto error;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- sc->sc_intr_number = ed->bEndpointAddress;
- sc->sc_isize = UGETW(ed->wMaxPacketSize);
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- ucom->sc_ibufsize = UGETW(ed->wMaxPacketSize);
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- ucom->sc_obufsize = UGETW(ed->wMaxPacketSize);
- }
- }
-
- if (sc->sc_intr_number == -1) {
- device_printf(ucom->sc_dev, "Could not find interrupt in\n");
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* keep interface for interrupt */
- sc->sc_intr_iface = ucom->sc_iface;
-
- if (ucom->sc_bulkin_no == -1) {
- device_printf(ucom->sc_dev, "Could not find data bulk in\n");
- ucom->sc_dying = 1;
- goto error;
- }
-
- if (ucom->sc_bulkout_no == -1) {
- device_printf(ucom->sc_dev, "Could not find data bulk out\n");
- ucom->sc_dying = 1;
- goto error;
- }
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = 1024;
- ucom->sc_obufsize = 1024;
- ucom->sc_ibufsizepad = ucom->sc_ibufsize;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &ubsa_callback;
-
- DPRINTF(("ubsa: in = 0x%x, out = 0x%x, intr = 0x%x\n",
- ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number));
-
- TASK_INIT(&sc->sc_task, 0, ubsa_notify, sc);
- ucom_attach(ucom);
- return 0;
-
-error:
- return ENXIO;
-}
-
-static int
-ubsa_detach(device_t self)
-{
- struct ubsa_softc *sc = device_get_softc(self);
- int rv;
-
- DPRINTF(("ubsa_detach: sc = %p\n", sc));
-
- if (sc->sc_intr_pipe != NULL) {
- usbd_abort_pipe(sc->sc_intr_pipe);
- usbd_close_pipe(sc->sc_intr_pipe);
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-
- sc->sc_ucom.sc_dying = 1;
-#if 0
- taskqueue_drain(taskqueue_swi_giant);
-#endif
- rv = ucom_detach(&sc->sc_ucom);
-
- return (rv);
-}
-
-static int
-ubsa_request(struct ubsa_softc *sc, u_int8_t request, u_int16_t value)
-{
- usb_device_request_t req;
- usbd_status err;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = request;
- USETW(req.wValue, value);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err)
- device_printf(sc->sc_ucom.sc_dev, "ubsa_request(%x, %x): %s\n",
- request, value, usbd_errstr(err));
- return (err);
-}
-
-static void
-ubsa_dtr(struct ubsa_softc *sc, int onoff)
-{
-
- DPRINTF(("ubsa_dtr: onoff = %d\n", onoff));
-
- if (sc->sc_dtr == onoff)
- return;
- sc->sc_dtr = onoff;
-
- ubsa_request(sc, UBSA_SET_DTR, onoff ? 1 : 0);
-}
-
-static void
-ubsa_rts(struct ubsa_softc *sc, int onoff)
-{
-
- DPRINTF(("ubsa_rts: onoff = %d\n", onoff));
-
- if (sc->sc_rts == onoff)
- return;
- sc->sc_rts = onoff;
-
- ubsa_request(sc, UBSA_SET_RTS, onoff ? 1 : 0);
-}
-
-static void
-ubsa_break(struct ubsa_softc *sc, int onoff)
-{
-
- DPRINTF(("ubsa_rts: onoff = %d\n", onoff));
-
- ubsa_request(sc, UBSA_SET_BREAK, onoff ? 1 : 0);
-}
-
-static void
-ubsa_set(void *addr, int portno, int reg, int onoff)
-{
- struct ubsa_softc *sc;
-
- sc = addr;
- switch (reg) {
- case UCOM_SET_DTR:
- ubsa_dtr(sc, onoff);
- break;
- case UCOM_SET_RTS:
- ubsa_rts(sc, onoff);
- break;
- case UCOM_SET_BREAK:
- ubsa_break(sc, onoff);
- break;
- default:
- break;
- }
-}
-
-static void
-ubsa_baudrate(struct ubsa_softc *sc, speed_t speed)
-{
- u_int16_t value = 0;
-
- DPRINTF(("ubsa_baudrate: speed = %d\n", speed));
-
- switch(speed) {
- case B0:
- break;
- case B300:
- case B600:
- case B1200:
- case B2400:
- case B4800:
- case B9600:
- case B19200:
- case B38400:
- case B57600:
- case B115200:
- case B230400:
- value = B230400 / speed;
- break;
- default:
- device_printf(sc->sc_ucom.sc_dev,
- "ubsa_param: unsupported baud, forcing default of 9600\n");
- value = B230400 / B9600;
- break;
- };
-
- if (speed == B0) {
- ubsa_flow(sc, 0, 0);
- ubsa_dtr(sc, 0);
- ubsa_rts(sc, 0);
- } else
- ubsa_request(sc, UBSA_SET_BAUDRATE, value);
-}
-
-static void
-ubsa_parity(struct ubsa_softc *sc, tcflag_t cflag)
-{
- int value;
-
- DPRINTF(("ubsa_parity: cflag = 0x%x\n", cflag));
-
- if (cflag & PARENB)
- value = (cflag & PARODD) ? UBSA_PARITY_ODD : UBSA_PARITY_EVEN;
- else
- value = UBSA_PARITY_NONE;
-
- ubsa_request(sc, UBSA_SET_PARITY, value);
-}
-
-static void
-ubsa_databits(struct ubsa_softc *sc, tcflag_t cflag)
-{
- int value;
-
- DPRINTF(("ubsa_databits: cflag = 0x%x\n", cflag));
-
- switch (cflag & CSIZE) {
- case CS5: value = 0; break;
- case CS6: value = 1; break;
- case CS7: value = 2; break;
- case CS8: value = 3; break;
- default:
- device_printf(sc->sc_ucom.sc_dev,
- "ubsa_param: unsupported databits requested, "
- "forcing default of 8\n");
- value = 3;
- }
-
- ubsa_request(sc, UBSA_SET_DATA_BITS, value);
-}
-
-static void
-ubsa_stopbits(struct ubsa_softc *sc, tcflag_t cflag)
-{
- int value;
-
- DPRINTF(("ubsa_stopbits: cflag = 0x%x\n", cflag));
-
- value = (cflag & CSTOPB) ? 1 : 0;
-
- ubsa_request(sc, UBSA_SET_STOP_BITS, value);
-}
-
-static void
-ubsa_flow(struct ubsa_softc *sc, tcflag_t cflag, tcflag_t iflag)
-{
- int value;
-
- DPRINTF(("ubsa_flow: cflag = 0x%x, iflag = 0x%x\n", cflag, iflag));
-
- value = 0;
- if (cflag & CRTSCTS)
- value |= UBSA_FLOW_OCTS | UBSA_FLOW_IRTS;
- if (iflag & (IXON|IXOFF))
- value |= UBSA_FLOW_OXON | UBSA_FLOW_IXON;
-
- ubsa_request(sc, UBSA_SET_FLOW_CTRL, value);
-}
-
-static int
-ubsa_param(void *addr, int portno, struct termios *ti)
-{
- struct ubsa_softc *sc;
-
- sc = addr;
-
- DPRINTF(("ubsa_param: sc = %p\n", sc));
-
- ubsa_baudrate(sc, ti->c_ospeed);
- ubsa_parity(sc, ti->c_cflag);
- ubsa_databits(sc, ti->c_cflag);
- ubsa_stopbits(sc, ti->c_cflag);
- ubsa_flow(sc, ti->c_cflag, ti->c_iflag);
-
- return (0);
-}
-
-static int
-ubsa_open(void *addr, int portno)
-{
- struct ubsa_softc *sc;
- int err;
-
- sc = addr;
- if (sc->sc_ucom.sc_dying)
- return (ENXIO);
-
- DPRINTF(("ubsa_open: sc = %p\n", sc));
-
- if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
- sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
- err = usbd_open_pipe_intr(sc->sc_intr_iface,
- sc->sc_intr_number,
- USBD_SHORT_XFER_OK,
- &sc->sc_intr_pipe,
- sc,
- sc->sc_intr_buf,
- sc->sc_isize,
- ubsa_intr,
- UBSA_INTR_INTERVAL);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev,
- "cannot open interrupt pipe (addr %d)\n",
- sc->sc_intr_number);
- return (EIO);
- }
- }
-
- return (0);
-}
-
-static void
-ubsa_close(void *addr, int portno)
-{
- struct ubsa_softc *sc;
- int err;
-
- sc = addr;
- if (sc->sc_ucom.sc_dying)
- return;
-
- DPRINTF(("ubsa_close: close\n"));
-
- if (sc->sc_intr_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(sc->sc_ucom.sc_dev,
- "abort interrupt pipe failed: %s\n",
- usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(sc->sc_ucom.sc_dev,
- "close interrupt pipe failed: %s\n",
- usbd_errstr(err));
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-}
-
-static void
-ubsa_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ubsa_softc *sc;
- u_char *buf;
-
- sc = priv;
- buf = sc->sc_intr_buf;
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- DPRINTF(("%s: ubsa_intr: abnormal status: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- usbd_errstr(status)));
- usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
- return;
- }
-
- /* incidentally, Belkin adapter status bits match UART 16550 bits */
- sc->sc_lsr = buf[2];
- sc->sc_msr = buf[3];
-
- DPRINTF(("%s: ubsa lsr = 0x%02x, msr = 0x%02x\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), sc->sc_lsr, sc->sc_msr));
-
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
-}
-
-/* Handle delayed events. */
-static void
-ubsa_notify(void *arg, int count)
-{
- struct ubsa_softc *sc;
-
- sc = arg;
- ucom_status_change(&sc->sc_ucom);
-}
-
-static void
-ubsa_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct ubsa_softc *sc;
-
- DPRINTF(("ubsa_get_status\n"));
-
- sc = addr;
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-}
diff --git a/sys/legacy/dev/usb/ubser.c b/sys/legacy/dev/usb/ubser.c
deleted file mode 100644
index 29994b9..0000000
--- a/sys/legacy/dev/usb/ubser.c
+++ /dev/null
@@ -1,882 +0,0 @@
-/*-
- * Copyright (c) 2004 Bernd Walter <ticso@freebsd.org>
- *
- * $URL: https://devel.bwct.de/svn/projects/ubser/ubser.c $
- * $Date: 2004-02-29 01:53:10 +0100 (Sun, 29 Feb 2004) $
- * $Author: ticso $
- * $Rev: 1127 $
- */
-
-/*-
- * Copyright (c) 2001-2002, Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*-
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * BWCT serial adapter driver
- */
-
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/clist.h>
-#include <sys/file.h>
-
-#include <sys/selinfo.h>
-
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/ubser.h>
-
-#ifdef USB_DEBUG
-static int ubserdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ubser, CTLFLAG_RW, 0, "USB ubser");
-SYSCTL_INT(_hw_usb_ubser, OID_AUTO, debug, CTLFLAG_RW,
- &ubserdebug, 0, "ubser debug level");
-#define DPRINTF(x) do { \
- if (ubserdebug) \
- printf x; \
- } while (0)
-
-#define DPRINTFN(n, x) do { \
- if (ubserdebug > (n)) \
- printf x; \
- } while (0)
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define ISSET(t, f) ((t) & (f))
-#define SET(t, f) (t) |= (f)
-#define CLR(t, f) (t) &= ~((unsigned)(f))
-
-struct ubser_port {
- int p_port;
- struct ubser_softc *p_sc;
- usbd_xfer_handle p_oxfer; /* write request */
- u_char *p_obuf; /* write buffer */
- struct tty *p_tty;
-};
-
-struct ubser_softc {
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface; /* data interface */
- int sc_ifaceno;
-
- int sc_refcnt;
- u_char sc_dying;
- u_char sc_opening;
- int sc_state;
- uint8_t sc_numser;
-
- int sc_bulkin_no; /* bulk in endpoint address */
- usbd_pipe_handle sc_bulkin_pipe; /* bulk in pipe */
- usbd_xfer_handle sc_ixfer; /* read request */
- u_char *sc_ibuf; /* read buffer */
- u_int sc_ibufsize; /* read buffer size */
- u_int sc_ibufsizepad; /* read buffer size padded */
-
- int sc_bulkout_no; /* bulk out endpoint address */
- usbd_pipe_handle sc_bulkout_pipe;/* bulk out pipe */
- u_int sc_obufsize; /* write buffer size */
- u_int sc_opkthdrlen; /* header length of
- output packet */
-
- struct ubser_port *sc_port;
-};
-
-static int ubserparam(struct tty *, struct termios *);
-static void ubserstart(struct tty *);
-static void ubserstop(struct tty *, int);
-static usbd_status ubserstartread(struct ubser_softc *);
-static void ubserreadcb(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void ubserwritecb(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void ubser_cleanup(struct ubser_softc *sc);
-
-static t_break_t ubserbreak;
-static t_open_t ubseropen;
-static t_close_t ubserclose;
-static t_modem_t ubsermodem;
-
-static device_probe_t ubser_match;
-static device_attach_t ubser_attach;
-static device_detach_t ubser_detach;
-
-static device_method_t ubser_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ubser_match),
- DEVMETHOD(device_attach, ubser_attach),
- DEVMETHOD(device_detach, ubser_detach),
-
- { 0, 0 }
-};
-
-static driver_t ubser_driver = {
- "ubser",
- ubser_methods,
- sizeof(struct ubser_softc)
-};
-
-static devclass_t ubser_devclass;
-
-static int
-ubser_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_string_descriptor_t us;
- usb_interface_descriptor_t *id;
- usb_device_descriptor_t *dd;
- int err, size;
-
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
-
- DPRINTFN(20,("ubser: vendor=0x%x, product=0x%x\n",
- uaa->vendor, uaa->product));
-
- dd = usbd_get_device_descriptor(uaa->device);
- if (dd == NULL) {
- printf("ubser: failed to get device descriptor\n");
- return (UMATCH_NONE);
- }
-
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL) {
- printf("ubser: failed to get interface descriptor\n");
- return (UMATCH_NONE);
- }
-
- err = usbd_get_string_desc(uaa->device, dd->iManufacturer, 0, &us,
- &size);
- if (err != 0)
- return (UMATCH_NONE);
-
- /* check if this is a BWCT vendor specific ubser interface */
- if (strcmp((char*)us.bString, "B\0W\0C\0T\0") == 0 &&
- id->bInterfaceClass == 0xff && id->bInterfaceSubClass == 0x00)
- return (UMATCH_VENDOR_IFACESUBCLASS);
-
- return (UMATCH_NONE);
-}
-
-static int
-ubser_attach(device_t self)
-{
- struct ubser_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle udev = uaa->device;
- usb_endpoint_descriptor_t *ed;
- usb_interface_descriptor_t *id;
- usb_device_request_t req;
- struct tty *tp;
- usbd_status err;
- int i;
- int alen;
- uint8_t epcount;
- struct ubser_port *pp;
-
- sc->sc_dev = self;
-
- DPRINTFN(10,("\nubser_attach: sc=%p\n", sc));
-
- sc->sc_udev = udev = uaa->device;
- sc->sc_iface = uaa->iface;
- sc->sc_numser = 0;
- sc->sc_port = NULL;
-
- /* get interface index */
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL) {
- printf("ubser: failed to get interface descriptor\n");
- return (UMATCH_NONE);
- }
- sc->sc_ifaceno = id->bInterfaceNumber;
-
- /* get number of serials */
- req.bmRequestType = UT_READ_VENDOR_INTERFACE;
- req.bRequest = VENDOR_GET_NUMSER;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, 1);
- err = usbd_do_request_flags(udev, &req, &sc->sc_numser,
- USBD_SHORT_XFER_OK, &alen, USBD_DEFAULT_TIMEOUT);
- if (err) {
- device_printf(self, "failed to get number of serials\n");
- goto bad;
- } else if (alen != 1) {
- device_printf(self, "bogus answer on get_numser\n");
- goto bad;
- }
- if (sc->sc_numser > MAX_SER)
- sc->sc_numser = MAX_SER;
- device_printf(self, "found %i serials\n", sc->sc_numser);
-
- sc->sc_port = malloc(sizeof(*sc->sc_port) * sc->sc_numser,
- M_USBDEV, M_WAITOK);
-
- /* find our bulk endpoints */
- epcount = 0;
- (void)usbd_endpoint_count(sc->sc_iface, &epcount);
- sc->sc_bulkin_no = -1;
- sc->sc_bulkout_no = -1;
- for (i = 0; i < epcount; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
- if (ed == NULL) {
- device_printf(self, "couldn't get ep %d\n", i);
- return ENXIO;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->sc_bulkin_no = ed->bEndpointAddress;
- sc->sc_ibufsizepad = UGETW(ed->wMaxPacketSize);
- sc->sc_ibufsizepad = UGETW(ed->wMaxPacketSize) - 1;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->sc_bulkout_no = ed->bEndpointAddress;
- sc->sc_obufsize = UGETW(ed->wMaxPacketSize) - 1;
- sc->sc_opkthdrlen = 1;
- }
- }
- if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1) {
- device_printf(self, "could not find bulk in/out endpoint\n");
- sc->sc_dying = 1;
- goto bad;
- }
-
- /* Open the bulk pipes */
- /* Bulk-in pipe */
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, 0,
- &sc->sc_bulkin_pipe);
- if (err) {
- device_printf(self, "open bulk in error (addr %d): %s\n",
- sc->sc_bulkin_no, usbd_errstr(err));
- goto fail_0;
- }
- /* Bulk-out pipe */
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
- if (err) {
- device_printf(self, "open bulk out error (addr %d): %s\n",
- sc->sc_bulkout_no, usbd_errstr(err));
- goto fail_1;
- }
-
- /* Allocate a request and an input buffer */
- sc->sc_ixfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_ixfer == NULL) {
- goto fail_2;
- }
-
- sc->sc_ibuf = usbd_alloc_buffer(sc->sc_ixfer,
- sc->sc_ibufsizepad);
- if (sc->sc_ibuf == NULL) {
- goto fail_3;
- }
-
- for (i = 0; i < sc->sc_numser; i++) {
- pp = &sc->sc_port[i];
- pp->p_port = i;
- pp->p_sc = sc;
- tp = pp->p_tty = ttyalloc();
- tp->t_sc = pp;
- DPRINTF(("ubser_attach: tty_attach tp = %p\n", tp));
- tp->t_oproc = ubserstart;
- tp->t_param = ubserparam;
- tp->t_stop = ubserstop;
- tp->t_break = ubserbreak;
- tp->t_open = ubseropen;
- tp->t_close = ubserclose;
- tp->t_modem = ubsermodem;
- ttycreate(tp, 0, "y%r%r", device_get_unit(sc->sc_dev), i);
- }
-
-
- for (i = 0; i < sc->sc_numser; i++) {
- sc->sc_port[i].p_oxfer = NULL;
- sc->sc_port[i].p_obuf = NULL;
- }
- for (i = 0; i < sc->sc_numser; i++) {
- sc->sc_port[i].p_oxfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_port[i].p_oxfer == NULL) {
- goto fail_4;
- }
-
- sc->sc_port[i].p_obuf = usbd_alloc_buffer(sc->sc_port[i].p_oxfer,
- sc->sc_obufsize +
- sc->sc_opkthdrlen);
- if (sc->sc_port[i].p_obuf == NULL) {
- goto fail_4;
- }
- }
-
- ubserstartread(sc);
- return 0;
-
-fail_4:
- for (i = 0; i < sc->sc_numser; i++) {
- if (sc->sc_port[i].p_oxfer != NULL) {
- usbd_free_xfer(sc->sc_port[i].p_oxfer);
- sc->sc_port[i].p_oxfer = NULL;
- }
- }
-fail_3:
- usbd_free_xfer(sc->sc_ixfer);
- sc->sc_ixfer = NULL;
-fail_2:
- usbd_close_pipe(sc->sc_bulkout_pipe);
- sc->sc_bulkout_pipe = NULL;
-fail_1:
- usbd_close_pipe(sc->sc_bulkin_pipe);
- sc->sc_bulkin_pipe = NULL;
-fail_0:
- sc->sc_opening = 0;
- wakeup(&sc->sc_opening);
-
-bad:
- ubser_cleanup(sc);
- if (sc->sc_port != NULL) {
- for (i = 0; i < sc->sc_numser; i++) {
- pp = &sc->sc_port[i];
- if (pp->p_tty != NULL)
- ttyfree(pp->p_tty);
- }
- free(sc->sc_port, M_USBDEV);
- sc->sc_port = NULL;
- }
-
- DPRINTF(("ubser_attach: ATTACH ERROR\n"));
- return ENXIO;
-}
-
-static int
-ubser_detach(device_t self)
-{
- struct ubser_softc *sc = device_get_softc(self);
- int i;
- struct ubser_port *pp;
-
- DPRINTF(("ubser_detach: sc=%p\n", sc));
-
- sc->sc_dying = 1;
- for (i = 0; i < sc->sc_numser; i++) {
- pp = &sc->sc_port[i];
- if (pp->p_tty != NULL)
- ttygone(pp->p_tty);
- }
-
- if (sc->sc_bulkin_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- if (sc->sc_bulkout_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkout_pipe);
-
- if (sc->sc_port != NULL) {
- for (i = 0; i < sc->sc_numser; i++) {
- pp = &sc->sc_port[i];
- if (pp->p_tty != NULL)
- ttyfree(pp->p_tty);
- }
- free(sc->sc_port, M_USBDEV);
- sc->sc_port = NULL;
- }
-
- if (--sc->sc_refcnt >= 0) {
- /* Wait for processes to go away. */
- usb_detach_wait(sc->sc_dev);
- }
-
- return (0);
-}
-
-static int
-ubserparam(struct tty *tp, struct termios *t)
-{
- struct ubser_softc *sc;
- struct ubser_port *pp;
-
- pp = tp->t_sc;
- sc = pp->p_sc;
-
- if (sc->sc_dying)
- return (EIO);
-
- DPRINTF(("ubserparam: sc = %p\n", sc));
-
- /*
- * The firmware on our devices can only do 8n1@9600bps
- * without handshake.
- * We refuse to accept other configurations.
- */
-
- /* enshure 9600bps */
- switch (t->c_ospeed) {
- case 9600:
- break;
- default:
- return (EINVAL);
- }
-
- /* 2 stop bits not possible */
- if (ISSET(t->c_cflag, CSTOPB))
- return (EINVAL);
-
- /* XXX parity handling not possible with current firmware */
- if (ISSET(t->c_cflag, PARENB))
- return (EINVAL);
-
- /* we can only do 8 data bits */
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS8:
- break;
- default:
- return (EINVAL);
- }
-
- /* we can't do any kind of hardware handshaking */
- if ((t->c_cflag &
- (CRTS_IFLOW | CDTR_IFLOW |CDSR_OFLOW |CCAR_OFLOW)) != 0)
- return (EINVAL);
-
- /*
- * XXX xon/xoff not supported by the firmware!
- * This is handled within FreeBSD only and may overflow buffers
- * because of delayed reaction due to device buffering.
- */
-
- ttsetwater(tp);
-
- return (0);
-}
-
-static void
-ubserstart(struct tty *tp)
-{
- struct ubser_softc *sc;
- struct ubser_port *pp;
- struct cblock *cbp;
- usbd_status err;
- u_char *data;
- int cnt;
- uint8_t serial;
-
- pp = tp->t_sc;
- sc = pp->p_sc;
- serial = pp->p_port;
- DPRINTF(("ubserstart: sc = %p, tp = %p\n", sc, tp));
-
- if (sc->sc_dying)
- return;
-
- if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) {
- ttwwakeup(tp);
- DPRINTF(("ubserstart: stopped\n"));
- return;
- }
-
- if (tp->t_outq.c_cc <= tp->t_olowat) {
- if (ISSET(tp->t_state, TS_SO_OLOWAT)) {
- CLR(tp->t_state, TS_SO_OLOWAT);
- wakeup(TSA_OLOWAT(tp));
- }
- selwakeuppri(&tp->t_wsel, TTIPRI);
- if (tp->t_outq.c_cc == 0) {
- if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
- TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
- CLR(tp->t_state, TS_SO_OCOMPLETE);
- wakeup(TSA_OCOMPLETE(tp));
- }
- return;
- }
- }
-
- /* Grab the first contiguous region of buffer space. */
- data = tp->t_outq.c_cf;
- cbp = (struct cblock *) ((intptr_t) tp->t_outq.c_cf & ~CROUND);
- cnt = min((char *) (cbp+1) - tp->t_outq.c_cf, tp->t_outq.c_cc);
-
- if (cnt == 0) {
- DPRINTF(("ubserstart: cnt == 0\n"));
- return;
- }
-
- SET(tp->t_state, TS_BUSY);
-
- if (cnt + sc->sc_opkthdrlen > sc->sc_obufsize) {
- DPRINTF(("ubserstart: big buffer %d chars\n", cnt));
- cnt = sc->sc_obufsize;
- }
- sc->sc_port[serial].p_obuf[0] = serial;
- memcpy(sc->sc_port[serial].p_obuf + sc->sc_opkthdrlen, data, cnt);
-
-
- DPRINTF(("ubserstart: %d chars\n", cnt));
- usbd_setup_xfer(sc->sc_port[serial].p_oxfer, sc->sc_bulkout_pipe,
- (usbd_private_handle)tp, sc->sc_port[serial].p_obuf,
- cnt + sc->sc_opkthdrlen,
- USBD_NO_COPY, USBD_NO_TIMEOUT, ubserwritecb);
- /* What can we do on error? */
- err = usbd_transfer(sc->sc_port[serial].p_oxfer);
- if (err != USBD_IN_PROGRESS)
- printf("ubserstart: err=%s\n", usbd_errstr(err));
-
- ttwwakeup(tp);
-}
-
-static void
-ubserstop(struct tty *tp, int flag)
-{
- struct ubser_softc *sc;
-
- sc = tp->t_sc;
-
- DPRINTF(("ubserstop: %d\n", flag));
-
- if (flag & FWRITE) {
- DPRINTF(("ubserstop: write\n"));
- if (ISSET(tp->t_state, TS_BUSY)) {
- /* XXX do what? */
- if (!ISSET(tp->t_state, TS_TTSTOP))
- SET(tp->t_state, TS_FLUSH);
- }
- }
-
- DPRINTF(("ubserstop: done\n"));
-}
-
-static void
-ubserwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
-{
- struct tty *tp;
- struct ubser_softc *sc;
- struct ubser_port *pp;
- u_int32_t cc;
-
- tp = (struct tty *)p;
- pp = tp->t_sc;
- sc = pp->p_sc;
-
- DPRINTF(("ubserwritecb: status = %d\n", status));
-
- if (status == USBD_CANCELLED || sc->sc_dying)
- goto error;
-
- if (status != USBD_NORMAL_COMPLETION) {
- device_printf(sc->sc_dev, "ubserwritecb: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
- /* XXX we should restart after some delay. */
- goto error;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL);
- DPRINTF(("ubserwritecb: cc = %d\n", cc));
- if (cc <= sc->sc_opkthdrlen) {
- device_printf(sc->sc_dev, "sent size too small, cc = %d\n",
- cc);
- goto error;
- }
-
- /* convert from USB bytes to tty bytes */
- cc -= sc->sc_opkthdrlen;
-
- CLR(tp->t_state, TS_BUSY);
- if (ISSET(tp->t_state, TS_FLUSH))
- CLR(tp->t_state, TS_FLUSH);
- else
- ndflush(&tp->t_outq, cc);
- ttyld_start(tp);
-
- return;
-
-error:
- CLR(tp->t_state, TS_BUSY);
- return;
-}
-
-static usbd_status
-ubserstartread(struct ubser_softc *sc)
-{
- usbd_status err;
-
- DPRINTF(("ubserstartread: start\n"));
-
- if (sc->sc_bulkin_pipe == NULL)
- return (USBD_NORMAL_COMPLETION);
-
- usbd_setup_xfer(sc->sc_ixfer, sc->sc_bulkin_pipe,
- (usbd_private_handle)sc,
- sc->sc_ibuf, sc->sc_ibufsizepad,
- USBD_SHORT_XFER_OK | USBD_NO_COPY,
- USBD_NO_TIMEOUT, ubserreadcb);
-
- err = usbd_transfer(sc->sc_ixfer);
- if (err != USBD_IN_PROGRESS) {
- DPRINTF(("ubserstartread: err = %s\n", usbd_errstr(err)));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-ubserreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
-{
- struct ubser_softc *sc = (struct ubser_softc *)p;
- struct tty *tp;
- usbd_status err;
- u_int32_t cc;
- u_char *cp;
- int lostcc;
-
- if (status == USBD_IOERROR) {
- device_printf(sc->sc_dev, "ubserreadcb: %s - restarting\n",
- usbd_errstr(status));
- goto resubmit;
- }
-
- DPRINTF(("ubserreadcb: status = %d\n", status));
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status != USBD_CANCELLED) {
- device_printf(sc->sc_dev, "ubserreadcb: %s\n",
- usbd_errstr(status));
- }
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
- return;
- }
-
- usbd_get_xfer_status(xfer, NULL, (void **)&cp, &cc, NULL);
-
- DPRINTF(("ubserreadcb: got %d bytes from device\n", cc));
- if (cc == 0)
- goto resubmit;
-
- if (cc > sc->sc_ibufsizepad) {
- device_printf(sc->sc_dev, "invalid receive data size, %d chars\n",
- cc);
- goto resubmit;
- }
-
- /* parse header */
- if (cc < 1)
- goto resubmit;
- DPRINTF(("ubserreadcb: got %d chars for serial %d\n", cc - 1, *cp));
- tp = sc->sc_port[*cp].p_tty;
- cp++;
- cc--;
-
- if (cc < 1)
- goto resubmit;
-
- if (!(tp->t_state & TS_ISOPEN)) /* drop data for unused serials */
- goto resubmit;
-
- if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
- if (tp->t_rawq.c_cc + cc > tp->t_ihiwat
- && (tp->t_iflag & IXOFF)
- && !(tp->t_state & TS_TBLOCK))
- ttyblock(tp);
- lostcc = b_to_q((char *)cp, cc, &tp->t_rawq);
- tp->t_rawcc += cc;
- ttwakeup(tp);
- if (tp->t_state & TS_TTSTOP
- && (tp->t_iflag & IXANY
- || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
- tp->t_state &= ~TS_TTSTOP;
- tp->t_lflag &= ~FLUSHO;
- ubserstart(tp);
- }
- if (lostcc > 0)
- device_printf(sc->sc_dev, "lost %d chars\n", lostcc);
- } else {
- /* Give characters to tty layer. */
- while (cc > 0) {
- DPRINTFN(7, ("ubserreadcb: char = 0x%02x\n", *cp));
- if (ttyld_rint(tp, *cp) == -1) {
- /* XXX what should we do? */
- device_printf(sc->sc_dev, "lost %d chars\n",
- cc);
- break;
- }
- cc--;
- cp++;
- }
- }
-
-resubmit:
- err = ubserstartread(sc);
- if (err) {
- device_printf(sc->sc_dev, "read start failed\n");
- /* XXX what should we do now? */
- }
-
-}
-
-static void
-ubser_cleanup(struct ubser_softc *sc)
-{
- int i;
- struct ubser_port *pp;
-
- DPRINTF(("ubser_cleanup: closing pipes\n"));
-
- if (sc->sc_bulkin_pipe != NULL) {
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- usbd_close_pipe(sc->sc_bulkin_pipe);
- sc->sc_bulkin_pipe = NULL;
- }
- if (sc->sc_bulkout_pipe != NULL) {
- usbd_abort_pipe(sc->sc_bulkout_pipe);
- usbd_close_pipe(sc->sc_bulkout_pipe);
- sc->sc_bulkout_pipe = NULL;
- }
- if (sc->sc_ixfer != NULL) {
- usbd_free_xfer(sc->sc_ixfer);
- sc->sc_ixfer = NULL;
- }
- for (i = 0; i < sc->sc_numser; i++) {
- pp = &sc->sc_port[i];
- if (pp->p_oxfer != NULL) {
- usbd_free_xfer(pp->p_oxfer);
- pp->p_oxfer = NULL;
- }
- }
-}
-
-static int
-ubseropen(struct tty *tp, struct cdev *dev)
-{
- struct ubser_softc *sc;
- struct ubser_port *pp;
-
- pp = tp->t_sc;
- sc = pp->p_sc;
-
- sc->sc_refcnt++; /* XXX: wrong refcnt on error later on */
- return (0);
-}
-
-static void
-ubserclose(struct tty *tp)
-{
- struct ubser_softc *sc;
- struct ubser_port *pp;
-
- pp = tp->t_sc;
- sc = pp->p_sc;
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
-}
-
-static void
-ubserbreak(struct tty *tp, int sig)
-{
- usb_device_request_t req;
- struct ubser_softc *sc;
- struct ubser_port *pp;
- int error;
- int alen;
-
- pp = tp->t_sc;
- sc = pp->p_sc;
- if (sig) {
- DPRINTF(("ubser_break: TIOCSBRK\n"));
- req.bmRequestType = UT_READ_VENDOR_INTERFACE;
- req.bRequest = VENDOR_SET_BREAK;
- USETW(req.wValue, pp->p_port);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, 0);
- error = usbd_do_request_flags(sc->sc_udev, &req, &sc->sc_numser,
- USBD_SHORT_XFER_OK, &alen, USBD_DEFAULT_TIMEOUT);
- }
-}
-
-static int
-ubsermodem(struct tty *tp, int sigon, int sigoff)
-{
-
- return (SER_DTR | SER_RTS | SER_DCD);
-}
-
-MODULE_DEPEND(ubser, usb, 1, 1, 1);
-DRIVER_MODULE(ubser, uhub, ubser_driver, ubser_devclass, usbd_driver_load, 0);
diff --git a/sys/legacy/dev/usb/ubser.h b/sys/legacy/dev/usb/ubser.h
deleted file mode 100644
index f256d4a..0000000
--- a/sys/legacy/dev/usb/ubser.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*-
- * Copyright (c) 2003 Bernd Walter <ticso@freebsd.org>
- *
- * $URL: https://devel.bwct.de/svn/projects/ubser/ubser.h $
- * $Date: 2004-02-29 01:53:10 +0100 (Sun, 29 Feb 2004) $
- * $Author: ticso $
- * $Rev: 1127 $
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef UBSER_H
-#define UBSER_H
-
-#define MAX_SER 32
-
-/* Vendor Interface Requests */
-#define VENDOR_GET_NUMSER 0x01
-#define VENDOR_SET_BREAK 0x02
-#define VENDOR_CLEAR_BREAK 0x03
-
-#endif /* UBSER_H */
diff --git a/sys/legacy/dev/usb/uchcom.c b/sys/legacy/dev/usb/uchcom.c
deleted file mode 100644
index 85b2629..0000000
--- a/sys/legacy/dev/usb/uchcom.c
+++ /dev/null
@@ -1,1036 +0,0 @@
-/* $NetBSD: uchcom.c,v 1.1 2007/09/03 17:57:37 tshiozak Exp $ */
-
-/*-
- * Copyright (c) 2007, Takanori Watanabe
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Copyright (c) 2007 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Takuya SHIOZAKI (tshiozak@netbsd.org).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * driver for WinChipHead CH341/340, the worst USB-serial chip in the world.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/select.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/poll.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-#include "usbdevs.h"
-
-#ifdef UCHCOM_DEBUG
-#define DPRINTFN(n, x) if (uchcomdebug > (n)) logprintf x
-int uchcomdebug = 0;
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define UCHCOM_IFACE_INDEX 0
-#define UCHCOM_CONFIG_INDEX 0
-
-#define UCHCOM_REV_CH340 0x0250
-#define UCHCOM_INPUT_BUF_SIZE 8
-
-#define UCHCOM_REQ_GET_VERSION 0x5F
-#define UCHCOM_REQ_READ_REG 0x95
-#define UCHCOM_REQ_WRITE_REG 0x9A
-#define UCHCOM_REQ_RESET 0xA1
-#define UCHCOM_REQ_SET_DTRRTS 0xA4
-
-#define UCHCOM_REG_STAT1 0x06
-#define UCHCOM_REG_STAT2 0x07
-#define UCHCOM_REG_BPS_PRE 0x12
-#define UCHCOM_REG_BPS_DIV 0x13
-#define UCHCOM_REG_BPS_MOD 0x14
-#define UCHCOM_REG_BPS_PAD 0x0F
-#define UCHCOM_REG_BREAK1 0x05
-#define UCHCOM_REG_BREAK2 0x18
-#define UCHCOM_REG_LCR1 0x18
-#define UCHCOM_REG_LCR2 0x25
-
-#define UCHCOM_VER_20 0x20
-
-#define UCHCOM_BASE_UNKNOWN 0
-#define UCHCOM_BPS_MOD_BASE 20000000
-#define UCHCOM_BPS_MOD_BASE_OFS 1100
-
-#define UCHCOM_DTR_MASK 0x20
-#define UCHCOM_RTS_MASK 0x40
-
-#define UCHCOM_BRK1_MASK 0x01
-#define UCHCOM_BRK2_MASK 0x40
-
-#define UCHCOM_LCR1_MASK 0xAF
-#define UCHCOM_LCR2_MASK 0x07
-#define UCHCOM_LCR1_PARENB 0x80
-#define UCHCOM_LCR2_PAREVEN 0x07
-#define UCHCOM_LCR2_PARODD 0x06
-#define UCHCOM_LCR2_PARMARK 0x05
-#define UCHCOM_LCR2_PARSPACE 0x04
-
-#define UCHCOM_INTR_STAT1 0x02
-#define UCHCOM_INTR_STAT2 0x03
-#define UCHCOM_INTR_LEAST 4
-
-#define UCHCOMIBUFSIZE 256
-#define UCHCOMOBUFSIZE 256
-
-struct uchcom_softc
-{
- struct ucom_softc sc_ucom;
-
- /* */
- int sc_intr_endpoint;
- int sc_intr_size;
- usbd_pipe_handle sc_intr_pipe;
- u_char *sc_intr_buf;
- /* */
- uint8_t sc_version;
- int sc_dtr;
- int sc_rts;
- u_char sc_lsr;
- u_char sc_msr;
- int sc_lcr1;
- int sc_lcr2;
-};
-
-struct uchcom_endpoints
-{
- int ep_bulkin;
- int ep_bulkout;
- int ep_intr;
- int ep_intr_size;
-};
-
-struct uchcom_divider
-{
- uint8_t dv_prescaler;
- uint8_t dv_div;
- uint8_t dv_mod;
-};
-
-struct uchcom_divider_record
-{
- uint32_t dvr_high;
- uint32_t dvr_low;
- uint32_t dvr_base_clock;
- struct uchcom_divider dvr_divider;
-};
-
-static const struct uchcom_divider_record dividers[] =
-{
- { 307200, 307200, UCHCOM_BASE_UNKNOWN, { 7, 0xD9, 0 } },
- { 921600, 921600, UCHCOM_BASE_UNKNOWN, { 7, 0xF3, 0 } },
- { 2999999, 23530, 6000000, { 3, 0, 0 } },
- { 23529, 2942, 750000, { 2, 0, 0 } },
- { 2941, 368, 93750, { 1, 0, 0 } },
- { 367, 1, 11719, { 0, 0, 0 } },
-};
-#define NUM_DIVIDERS (sizeof (dividers) / sizeof (dividers[0]))
-
-static const struct usb_devno uchcom_devs[] = {
- { USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341SER },
-};
-#define uchcom_lookup(v, p) usb_lookup(uchcom_devs, v, p)
-
-static void uchcom_get_status(void *, int, u_char *, u_char *);
-static void uchcom_set(void *, int, int, int);
-static int uchcom_param(void *, int, struct termios *);
-static int uchcom_open(void *, int);
-static void uchcom_close(void *, int);
-static void uchcom_intr(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-
-static int set_config(device_t );
-static int find_ifaces(struct uchcom_softc *, usbd_interface_handle *);
-static int find_endpoints(struct uchcom_softc *,
- struct uchcom_endpoints *);
-static void close_intr_pipe(struct uchcom_softc *);
-
-static int uchcom_match(device_t );
-static int uchcom_attach(device_t );
-static int uchcom_detach(device_t );
-
-struct ucom_callback uchcom_callback = {
- .ucom_get_status = uchcom_get_status,
- .ucom_set = uchcom_set,
- .ucom_param = uchcom_param,
- .ucom_ioctl = NULL,
- .ucom_open = uchcom_open,
- .ucom_close = uchcom_close,
- .ucom_read = NULL,
- .ucom_write = NULL,
-};
-
-
-
-
-/* ----------------------------------------------------------------------
- * driver entry points
- */
-
-static int uchcom_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- return (uchcom_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-static int uchcom_attach(device_t self)
-{
- struct uchcom_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
-
- struct uchcom_endpoints endpoints;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
-
- ucom->sc_dying = 0;
- sc->sc_dtr = sc->sc_rts = -1;
- sc->sc_lsr = sc->sc_msr = 0;
-
- DPRINTF(("\n\nuchcom attach: sc=%p\n", sc));
-
- if (set_config(self))
- goto failed;
-
- switch (uaa->release) {
- case UCHCOM_REV_CH340:
- device_printf(self, "CH340 detected\n");
- break;
- default:
- device_printf(self, "CH341 detected\n");
- break;
- }
-
- if (find_ifaces(sc, &ucom->sc_iface))
- goto failed;
-
- if (find_endpoints(sc, &endpoints))
- goto failed;
-
- sc->sc_intr_endpoint = endpoints.ep_intr;
- sc->sc_intr_size = endpoints.ep_intr_size;
-
- /* setup ucom layer */
- ucom->sc_portno = UCOM_UNK_PORTNO;
- ucom->sc_bulkin_no = endpoints.ep_bulkin;
- ucom->sc_bulkout_no = endpoints.ep_bulkout;
- ucom->sc_ibufsize = UCHCOMIBUFSIZE;
- ucom->sc_obufsize = UCHCOMOBUFSIZE;
- ucom->sc_ibufsizepad = UCHCOMIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_parent = sc;
-
- ucom->sc_callback = &uchcom_callback;
-
- ucom_attach(&sc->sc_ucom);
-
- return 0;
-
-failed:
- ucom->sc_dying = 1;
- return ENXIO;
-}
-
-static int uchcom_detach(device_t self)
-{
- struct uchcom_softc *sc = device_get_softc(self);
- struct ucom_softc *ucom = &sc->sc_ucom ;
- int rv = 0;
-
- DPRINTF(("uchcom_detach: sc=%p flags=%d\n", sc, flags));
-
- close_intr_pipe(sc);
-
- ucom->sc_dying = 1;
-
- rv = ucom_detach(ucom);
-
- return rv;
-}
-static int
-set_config(device_t dev)
-{
- struct uchcom_softc *sc = device_get_softc(dev);
- struct ucom_softc *ucom = &sc->sc_ucom;
- usbd_status err;
-
- err = usbd_set_config_index(ucom->sc_udev, UCHCOM_CONFIG_INDEX, 1);
- if (err) {
- device_printf(dev, "failed to set configuration: %s\n",
- usbd_errstr(err));
- return -1;
- }
-
- return 0;
-}
-
-static int
-find_ifaces(struct uchcom_softc *sc, usbd_interface_handle *riface)
-{
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- err = usbd_device2interface_handle(ucom->sc_udev, UCHCOM_IFACE_INDEX,
- riface);
- if (err) {
- device_printf(ucom->sc_dev, "failed to get interface: %s\n",
- usbd_errstr(err));
- return -1;
- }
-
- return 0;
-}
-
-static int
-find_endpoints(struct uchcom_softc *sc, struct uchcom_endpoints *endpoints)
-{
- struct ucom_softc *ucom= &sc->sc_ucom;
- int i, bin=-1, bout=-1, intr=-1, isize=0;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- device_printf(ucom->sc_dev, "no endpoint descriptor for %d\n", i);
- return -1;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- intr = ed->bEndpointAddress;
- isize = UGETW(ed->wMaxPacketSize);
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- bin = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- bout = ed->bEndpointAddress;
- }
- }
-
- if (intr == -1 || bin == -1 || bout == -1) {
- if (intr == -1) {
- device_printf(ucom->sc_dev, "no interrupt end point\n");
- }
- if (bin == -1) {
- device_printf(ucom->sc_dev, "no data bulk in end point\n");
-
- }
- if (bout == -1) {
- device_printf(ucom->sc_dev, "no data bulk out end point\n");
- }
- return -1;
- }
- if (isize < UCHCOM_INTR_LEAST) {
- device_printf(ucom->sc_dev, "intr pipe is too short");
- return -1;
- }
-
- DPRINTF(("%s: bulkin=%d, bulkout=%d, intr=%d, isize=%d\n",
- USBDEVNAME(sc->sc_dev), bin, bout, intr, isize));
-
- endpoints->ep_intr = intr;
- endpoints->ep_intr_size = isize;
- endpoints->ep_bulkin = bin;
- endpoints->ep_bulkout = bout;
-
- return 0;
-}
-
-
-/* ----------------------------------------------------------------------
- * low level i/o
- */
-
-static __inline usbd_status
-generic_control_out(struct uchcom_softc *sc, uint8_t reqno,
- uint16_t value, uint16_t index)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = reqno;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, 0);
-
- return usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
-}
-
-static __inline usbd_status
-generic_control_in(struct uchcom_softc *sc, uint8_t reqno,
- uint16_t value, uint16_t index, void *buf, int buflen,
- int *actlen)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = reqno;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, (uint16_t)buflen);
-
- return usbd_do_request_flags(sc->sc_ucom.sc_udev, &req, buf,
- USBD_SHORT_XFER_OK, actlen,
- USBD_DEFAULT_TIMEOUT);
-}
-
-static __inline usbd_status
-write_reg(struct uchcom_softc *sc,
- uint8_t reg1, uint8_t val1, uint8_t reg2, uint8_t val2)
-{
- DPRINTF(("uchcom: write reg 0x%02X<-0x%02X, 0x%02X<-0x%02X\n",
- (unsigned)reg1, (unsigned)val1,
- (unsigned)reg2, (unsigned)val2));
- return generic_control_out(
- sc, UCHCOM_REQ_WRITE_REG,
- reg1|((uint16_t)reg2<<8), val1|((uint16_t)val2<<8));
-}
-
-static __inline usbd_status
-read_reg(struct uchcom_softc *sc,
- uint8_t reg1, uint8_t *rval1, uint8_t reg2, uint8_t *rval2)
-{
- uint8_t buf[UCHCOM_INPUT_BUF_SIZE];
- usbd_status err;
- int actin;
-
- err = generic_control_in(
- sc, UCHCOM_REQ_READ_REG,
- reg1|((uint16_t)reg2<<8), 0, buf, sizeof buf, &actin);
- if (err)
- return err;
-
- DPRINTF(("uchcom: read reg 0x%02X->0x%02X, 0x%02X->0x%02X\n",
- (unsigned)reg1, (unsigned)buf[0],
- (unsigned)reg2, (unsigned)buf[1]));
-
- if (rval1) *rval1 = buf[0];
- if (rval2) *rval2 = buf[1];
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static __inline usbd_status
-get_version(struct uchcom_softc *sc, uint8_t *rver)
-{
- uint8_t buf[UCHCOM_INPUT_BUF_SIZE];
- usbd_status err;
- int actin;
-
- err = generic_control_in(
- sc, UCHCOM_REQ_GET_VERSION, 0, 0, buf, sizeof buf, &actin);
- if (err)
- return err;
-
- if (rver) *rver = buf[0];
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static __inline usbd_status
-get_status(struct uchcom_softc *sc, uint8_t *rval)
-{
- return read_reg(sc, UCHCOM_REG_STAT1, rval, UCHCOM_REG_STAT2, NULL);
-}
-
-static __inline usbd_status
-set_dtrrts_10(struct uchcom_softc *sc, uint8_t val)
-{
- return write_reg(sc, UCHCOM_REG_STAT1, val, UCHCOM_REG_STAT1, val);
-}
-
-static __inline usbd_status
-set_dtrrts_20(struct uchcom_softc *sc, uint8_t val)
-{
- return generic_control_out(sc, UCHCOM_REQ_SET_DTRRTS, val, 0);
-}
-
-
-/* ----------------------------------------------------------------------
- * middle layer
- */
-
-static int
-update_version(struct uchcom_softc *sc)
-{
- usbd_status err;
-
- err = get_version(sc, &sc->sc_version);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "cannot get version: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- return 0;
-}
-
-static void
-convert_status(struct uchcom_softc *sc, uint8_t cur)
-{
- sc->sc_dtr = !(cur & UCHCOM_DTR_MASK);
- sc->sc_rts = !(cur & UCHCOM_RTS_MASK);
-
- cur = ~cur & 0x0F;
- sc->sc_msr = (cur << 4) | ((sc->sc_msr >> 4) ^ cur);
-}
-
-static int
-update_status(struct uchcom_softc *sc)
-{
- usbd_status err;
- uint8_t cur;
-
- err = get_status(sc, &cur);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev,
- "cannot update status: %s\n",
- usbd_errstr(err));
- return EIO;
- }
- convert_status(sc, cur);
-
- return 0;
-}
-
-
-static int
-set_dtrrts(struct uchcom_softc *sc, int dtr, int rts)
-{
- usbd_status err;
- uint8_t val = 0;
-
- if (dtr) val |= UCHCOM_DTR_MASK;
- if (rts) val |= UCHCOM_RTS_MASK;
-
- if (sc->sc_version < UCHCOM_VER_20)
- err = set_dtrrts_10(sc, ~val);
- else
- err = set_dtrrts_20(sc, ~val);
-
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "cannot set DTR/RTS: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- return 0;
-}
-
-static int
-set_break(struct uchcom_softc *sc, int onoff)
-{
- usbd_status err;
- uint8_t brk1, brk2;
-
- err = read_reg(sc, UCHCOM_REG_BREAK1, &brk1, UCHCOM_REG_BREAK2, &brk2);
- if (err)
- return EIO;
- if (onoff) {
- /* on - clear bits */
- brk1 &= ~UCHCOM_BRK1_MASK;
- brk2 &= ~UCHCOM_BRK2_MASK;
- } else {
- /* off - set bits */
- brk1 |= UCHCOM_BRK1_MASK;
- brk2 |= UCHCOM_BRK2_MASK;
- }
- err = write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_BREAK2, brk2);
- if (err)
- return EIO;
-
- return 0;
-}
-
-static int
-calc_divider_settings(struct uchcom_divider *dp, uint32_t rate)
-{
- int i;
- const struct uchcom_divider_record *rp;
- uint32_t div, rem, mod;
-
- /* find record */
- for (i=0; i<NUM_DIVIDERS; i++) {
- if (dividers[i].dvr_high >= rate &&
- dividers[i].dvr_low <= rate) {
- rp = &dividers[i];
- goto found;
- }
- }
- return -1;
-
-found:
- dp->dv_prescaler = rp->dvr_divider.dv_prescaler;
- if (rp->dvr_base_clock == UCHCOM_BASE_UNKNOWN)
- dp->dv_div = rp->dvr_divider.dv_div;
- else {
- div = rp->dvr_base_clock / rate;
- rem = rp->dvr_base_clock % rate;
- if (div==0 || div>=0xFF)
- return -1;
- if ((rem<<1) >= rate)
- div += 1;
- dp->dv_div = (uint8_t)-div;
- }
-
- mod = UCHCOM_BPS_MOD_BASE/rate + UCHCOM_BPS_MOD_BASE_OFS;
- mod = mod + mod/2;
-
- dp->dv_mod = mod / 0x100;
-
- return 0;
-}
-
-static int
-set_dte_rate(struct uchcom_softc *sc, uint32_t rate)
-{
- usbd_status err;
- struct uchcom_divider dv;
-
- if (calc_divider_settings(&dv, rate))
- return EINVAL;
-
- if ((err = write_reg(sc,
- UCHCOM_REG_BPS_PRE, dv.dv_prescaler,
- UCHCOM_REG_BPS_DIV, dv.dv_div)) ||
- (err = write_reg(sc,
- UCHCOM_REG_BPS_MOD, dv.dv_mod,
- UCHCOM_REG_BPS_PAD, 0))) {
- device_printf(sc->sc_ucom.sc_dev, " cannot set DTE rate: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- return 0;
-}
-
-static int
-set_line_control(struct uchcom_softc *sc, tcflag_t cflag)
-{
- usbd_status err;
- uint8_t lcr1 = 0, lcr2 = 0;
-
- err = read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, " cannot get LCR: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- lcr1 &= ~UCHCOM_LCR1_MASK;
- lcr2 &= ~UCHCOM_LCR2_MASK;
-
- /*
- * XXX: it is difficult to handle the line control appropriately:
- * - CS8, !CSTOPB and any parity mode seems ok, but
- * - the chip doesn't have the function to calculate parity
- * in !CS8 mode.
- * - it is unclear that the chip supports CS5,6 mode.
- * - it is unclear how to handle stop bits.
- */
-
- switch (ISSET(cflag, CSIZE)) {
- case CS5:
- case CS6:
- case CS7:
- return EINVAL;
- case CS8:
- break;
- }
-
- if (ISSET(cflag, PARENB)) {
- lcr1 |= UCHCOM_LCR1_PARENB;
- if (ISSET(cflag, PARODD))
- lcr2 |= UCHCOM_LCR2_PARODD;
- else
- lcr2 |= UCHCOM_LCR2_PAREVEN;
- }
-
- err = write_reg(sc, UCHCOM_REG_LCR1, lcr1, UCHCOM_REG_LCR2, lcr2);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "cannot set LCR: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- return 0;
-}
-
-static int
-clear_chip(struct uchcom_softc *sc)
-{
- usbd_status err;
-
- DPRINTF(("%s: clear\n", USBDEVNAME(sc->sc_dev)));
- err = generic_control_out(sc, UCHCOM_REQ_RESET, 0, 0);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "cannot clear: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- return 0;
-}
-
-static int
-reset_chip(struct uchcom_softc *sc)
-{
- usbd_status err;
- uint8_t lcr1, lcr2, pre, div, mod;
- uint16_t val=0, idx=0;
-
- err = read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2);
- if (err)
- goto failed;
-
- err = read_reg(sc, UCHCOM_REG_BPS_PRE, &pre, UCHCOM_REG_BPS_DIV, &div);
- if (err)
- goto failed;
-
- err = read_reg(sc, UCHCOM_REG_BPS_MOD, &mod, UCHCOM_REG_BPS_PAD, NULL);
- if (err)
- goto failed;
-
- val |= (uint16_t)(lcr1&0xF0) << 8;
- val |= 0x01;
- val |= (uint16_t)(lcr2&0x0F) << 8;
- val |= 0x02;
- idx |= pre & 0x07;
- val |= 0x04;
- idx |= (uint16_t)div << 8;
- val |= 0x08;
- idx |= mod & 0xF8;
- val |= 0x10;
-
- DPRINTF(("%s: reset v=0x%04X, i=0x%04X\n",
- USBDEVNAME(sc->sc_dev), val, idx));
-
- err = generic_control_out(sc, UCHCOM_REQ_RESET, val, idx);
- if (err)
- goto failed;
-
- return 0;
-
-failed:
- device_printf(sc->sc_ucom.sc_dev, "cannot reset: %s\n",
- usbd_errstr(err));
- return EIO;
-}
-
-static int
-setup_comm(struct uchcom_softc *sc)
-{
- int ret;
-
- ret = update_version(sc);
- if (ret)
- return ret;
-
- ret = clear_chip(sc);
- if (ret)
- return ret;
-
- ret = set_dte_rate(sc, TTYDEF_SPEED);
- if (ret)
- return ret;
-
- ret = set_line_control(sc, CS8);
- if (ret)
- return ret;
-
- ret = update_status(sc);
- if (ret)
- return ret;
-
- ret = reset_chip(sc);
- if (ret)
- return ret;
-
- ret = set_dte_rate(sc, TTYDEF_SPEED); /* XXX */
- if (ret)
- return ret;
-
- sc->sc_dtr = sc->sc_rts = 1;
- ret = set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int
-setup_intr_pipe(struct uchcom_softc *sc)
-{
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
- if (sc->sc_intr_endpoint != -1 && sc->sc_intr_pipe == NULL) {
- sc->sc_intr_buf = malloc(sc->sc_intr_size, M_USBDEV, M_WAITOK);
- err = usbd_open_pipe_intr(ucom->sc_iface,
- sc->sc_intr_endpoint,
- USBD_SHORT_XFER_OK,
- &sc->sc_intr_pipe, sc,
- sc->sc_intr_buf,
- sc->sc_intr_size,
- uchcom_intr, USBD_DEFAULT_INTERVAL);
- if (err) {
- device_printf(ucom->sc_dev,
- "cannot open interrupt pipe: %s\n",
- usbd_errstr(err));
- return EIO;
- }
- }
- return 0;
-}
-
-static void
-close_intr_pipe(struct uchcom_softc *sc)
-{
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
- if (ucom->sc_dying)
- return;
-
- if (sc->sc_intr_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(ucom->sc_dev,
- "abort interrupt pipe failed: %s\n",
- usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(ucom->sc_dev,
- " close interrupt pipe failed: %s\n",
- usbd_errstr(err));
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-}
-
-
-/* ----------------------------------------------------------------------
- * methods for ucom
- */
-void
-uchcom_get_status(void *arg, int portno, u_char *rlsr, u_char *rmsr)
-{
- struct uchcom_softc *sc = arg;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- *rlsr = sc->sc_lsr;
- *rmsr = sc->sc_msr;
-}
-
-void
-uchcom_set(void *arg, int portno, int reg, int onoff)
-{
- struct uchcom_softc *sc = arg;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- switch (reg) {
- case UCOM_SET_DTR:
- sc->sc_dtr = !!onoff;
- set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
- break;
- case UCOM_SET_RTS:
- sc->sc_rts = !!onoff;
- set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
- break;
- case UCOM_SET_BREAK:
- set_break(sc, onoff);
- break;
- }
-}
-
-int
-uchcom_param(void *arg, int portno, struct termios *t)
-{
- struct uchcom_softc *sc = arg;
- int ret;
-
- if (sc->sc_ucom.sc_dying)
- return 0;
-
- ret = set_line_control(sc, t->c_cflag);
- if (ret)
- return ret;
-
- ret = set_dte_rate(sc, t->c_ospeed);
- if (ret)
- return ret;
-
- return 0;
-}
-
-int
-uchcom_open(void *arg, int portno)
-{
- int ret;
- struct uchcom_softc *sc = arg;
-
- if (sc->sc_ucom.sc_dying)
- return EIO;
-
- ret = setup_intr_pipe(sc);
- if (ret)
- return ret;
-
- ret = setup_comm(sc);
- if (ret)
- return ret;
-
- return 0;
-}
-
-void
-uchcom_close(void *arg, int portno)
-{
- struct uchcom_softc *sc = arg;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- close_intr_pipe(sc);
-}
-
-
-/* ----------------------------------------------------------------------
- * callback when the modem status is changed.
- */
-void
-uchcom_intr(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- struct uchcom_softc *sc = priv;
- u_char *buf = sc->sc_intr_buf;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- DPRINTF(("%s: abnormal status: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(status)));
- usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
- return;
- }
- DPRINTF(("%s: intr: 0x%02X 0x%02X 0x%02X 0x%02X "
- "0x%02X 0x%02X 0x%02X 0x%02X\n",
- USBDEVNAME(sc->sc_dev),
- (unsigned)buf[0], (unsigned)buf[1],
- (unsigned)buf[2], (unsigned)buf[3],
- (unsigned)buf[4], (unsigned)buf[5],
- (unsigned)buf[6], (unsigned)buf[7]));
-
- convert_status(sc, buf[UCHCOM_INTR_STAT1]);
- ucom_status_change(&sc->sc_ucom);
-}
-
-static device_method_t uchcom_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uchcom_match),
- DEVMETHOD(device_attach, uchcom_attach),
- DEVMETHOD(device_detach, uchcom_detach),
-
- { 0, 0 }
-};
-
-static driver_t uchcom_driver = {
- "ucom",
- uchcom_methods,
- sizeof (struct uchcom_softc)
-};
-
-DRIVER_MODULE(uchcom, uhub, uchcom_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uchcom, usb, 1, 1, 1);
-MODULE_DEPEND(uchcom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
diff --git a/sys/legacy/dev/usb/ucom.c b/sys/legacy/dev/usb/ucom.c
deleted file mode 100644
index ae263a0..0000000
--- a/sys/legacy/dev/usb/ucom.c
+++ /dev/null
@@ -1,829 +0,0 @@
-/* $NetBSD: ucom.c,v 1.40 2001/11/13 06:24:54 lukem Exp $ */
-
-/*-
- * Copyright (c) 2001-2003, 2005, 2008
- * Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-#ifdef USB_DEBUG
-static int ucomdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom");
-SYSCTL_INT(_hw_usb_ucom, OID_AUTO, debug, CTLFLAG_RW,
- &ucomdebug, 0, "ucom debug level");
-#define DPRINTF(x) do { \
- if (ucomdebug) \
- printf x; \
- } while (0)
-
-#define DPRINTFN(n, x) do { \
- if (ucomdebug > (n)) \
- printf x; \
- } while (0)
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n, x)
-#endif
-
-static int ucom_modevent(module_t, int, void *);
-static void ucom_cleanup(struct ucom_softc *);
-static void ucom_shutdown(struct ucom_softc *);
-static void ucom_dtr(struct ucom_softc *, int);
-static void ucom_rts(struct ucom_softc *, int);
-static void ucombreak(struct ucom_softc *, int);
-static usbd_status ucomstartread(struct ucom_softc *);
-static void ucomreadcb(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void ucomwritecb(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void ucomstopread(struct ucom_softc *);
-
-static tsw_open_t ucomtty_open;
-static tsw_close_t ucomtty_close;
-static tsw_outwakeup_t ucomtty_outwakeup;
-static tsw_ioctl_t ucomtty_ioctl;
-static tsw_param_t ucomtty_param;
-static tsw_modem_t ucomtty_modem;
-static tsw_free_t ucomtty_free;
-
-static struct ttydevsw ucomtty_class = {
- .tsw_flags = TF_INITLOCK|TF_CALLOUT,
- .tsw_open = ucomtty_open,
- .tsw_close = ucomtty_close,
- .tsw_outwakeup = ucomtty_outwakeup,
- .tsw_ioctl = ucomtty_ioctl,
- .tsw_param = ucomtty_param,
- .tsw_modem = ucomtty_modem,
- .tsw_free = ucomtty_free,
-};
-
-devclass_t ucom_devclass;
-
-static moduledata_t ucom_mod = {
- "ucom",
- ucom_modevent,
- NULL
-};
-
-DECLARE_MODULE(ucom, ucom_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
-MODULE_DEPEND(ucom, usb, 1, 1, 1);
-MODULE_VERSION(ucom, UCOM_MODVER);
-
-static int
-ucom_modevent(module_t mod, int type, void *data)
-{
- switch (type) {
- case MOD_LOAD:
- case MOD_UNLOAD:
- return (0);
- default:
- return (EOPNOTSUPP);
- }
-}
-
-void
-ucom_attach_tty(struct ucom_softc *sc, char* fmt, int unit)
-{
- struct tty *tp;
-
- sc->sc_tty = tp = tty_alloc(&ucomtty_class, sc, &Giant);
- tty_makedev(tp, NULL, fmt, unit);
-}
-
-int
-ucom_attach(struct ucom_softc *sc)
-{
-
- ucom_attach_tty(sc, "U%d", device_get_unit(sc->sc_dev));
-
- DPRINTF(("ucom_attach: ttycreate: tp = %p, %s\n",
- sc->sc_tty, sc->sc_tty->t_dev->si_name));
-
- return (0);
-}
-
-int
-ucom_detach(struct ucom_softc *sc)
-{
- DPRINTF(("ucom_detach: sc = %p, tp = %p\n", sc, sc->sc_tty));
-
- tty_lock(sc->sc_tty);
- sc->sc_dying = 1;
-
- if (sc->sc_bulkin_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- if (sc->sc_bulkout_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkout_pipe);
-
- tty_rel_gone(sc->sc_tty);
-
- return (0);
-}
-
-static void
-ucom_shutdown(struct ucom_softc *sc)
-{
- struct tty *tp = sc->sc_tty;
-
- DPRINTF(("ucom_shutdown\n"));
- /*
- * Hang up if necessary. Wait a bit, so the other side has time to
- * notice even if we immediately open the port again.
- */
- if (tp->t_termios.c_cflag & HUPCL) {
- (void)ucomtty_modem(tp, 0, SER_DTR);
-#if 0
- (void)tsleep(sc, TTIPRI, "ucomsd", hz);
-#endif
- }
-}
-
-static int
-ucomtty_open(struct tty *tp)
-{
- struct ucom_softc *sc = tty_softc(tp);
- usbd_status err;
- int error;
-
- if (sc->sc_dying)
- return (ENXIO);
-
- DPRINTF(("%s: ucomtty_open: tp = %p\n", device_get_nameunit(sc->sc_dev), tp));
-
- sc->sc_poll = 0;
- sc->sc_lsr = sc->sc_msr = sc->sc_mcr = 0;
-
- (void)ucomtty_modem(tp, SER_DTR | SER_RTS, 0);
-
- /* Device specific open */
- if (sc->sc_callback->ucom_open != NULL) {
- error = sc->sc_callback->ucom_open(sc->sc_parent,
- sc->sc_portno);
- if (error) {
- ucom_cleanup(sc);
- return (error);
- }
- }
-
- DPRINTF(("ucomtty_open: open pipes in = %d out = %d\n",
- sc->sc_bulkin_no, sc->sc_bulkout_no));
-
- /* Open the bulk pipes */
- /* Bulk-in pipe */
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, 0,
- &sc->sc_bulkin_pipe);
- if (err) {
- printf("%s: open bulk in error (addr %d): %s\n",
- device_get_nameunit(sc->sc_dev), sc->sc_bulkin_no,
- usbd_errstr(err));
- error = EIO;
- goto fail;
- }
- /* Bulk-out pipe */
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
- if (err) {
- printf("%s: open bulk out error (addr %d): %s\n",
- device_get_nameunit(sc->sc_dev), sc->sc_bulkout_no,
- usbd_errstr(err));
- error = EIO;
- goto fail;
- }
-
- /* Allocate a request and an input buffer and start reading. */
- sc->sc_ixfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_ixfer == NULL) {
- error = ENOMEM;
- goto fail;
- }
-
- sc->sc_ibuf = usbd_alloc_buffer(sc->sc_ixfer,
- sc->sc_ibufsizepad);
- if (sc->sc_ibuf == NULL) {
- error = ENOMEM;
- goto fail;
- }
-
- sc->sc_oxfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_oxfer == NULL) {
- error = ENOMEM;
- goto fail;
- }
-
- sc->sc_obuf = usbd_alloc_buffer(sc->sc_oxfer,
- sc->sc_obufsize +
- sc->sc_opkthdrlen);
- if (sc->sc_obuf == NULL) {
- error = ENOMEM;
- goto fail;
- }
-
- sc->sc_state |= UCS_RXSTOP;
- ucomstartread(sc);
-
- sc->sc_poll = 1;
-
- return (0);
-
-fail:
- ucom_cleanup(sc);
- return (error);
-}
-
-static void
-ucomtty_close(struct tty *tp)
-{
- struct ucom_softc *sc = tty_softc(tp);
-
- DPRINTF(("%s: ucomtty_close \n", device_get_nameunit(sc->sc_dev)));
-
- ucom_cleanup(sc);
-
- if (sc->sc_callback->ucom_close != NULL)
- sc->sc_callback->ucom_close(sc->sc_parent, sc->sc_portno);
-}
-
-static int
-ucomtty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *p)
-{
- struct ucom_softc *sc = tty_softc(tp);
- int error;
-
- if (sc->sc_dying)
- return (EIO);
-
- DPRINTF(("ucomioctl: cmd = 0x%08lx\n", cmd));
-
- switch (cmd) {
- case TIOCSBRK:
- ucombreak(sc, 1);
- return (0);
- case TIOCCBRK:
- ucombreak(sc, 0);
- return (0);
- }
-
- error = ENOIOCTL;
- if (sc->sc_callback->ucom_ioctl != NULL)
- error = sc->sc_callback->ucom_ioctl(sc->sc_parent,
- sc->sc_portno,
- cmd, data, p);
- return (error);
-}
-
-static int
-ucomtty_modem(struct tty *tp, int sigon, int sigoff)
-{
- struct ucom_softc *sc = tty_softc(tp);
- int mcr;
- int msr;
- int onoff;
-
- if (sigon == 0 && sigoff == 0) {
- mcr = sc->sc_mcr;
- if (ISSET(mcr, SER_DTR))
- sigon |= SER_DTR;
- if (ISSET(mcr, SER_RTS))
- sigon |= SER_RTS;
-
- msr = sc->sc_msr;
- if (ISSET(msr, SER_CTS))
- sigon |= SER_CTS;
- if (ISSET(msr, SER_DCD))
- sigon |= SER_DCD;
- if (ISSET(msr, SER_DSR))
- sigon |= SER_DSR;
- if (ISSET(msr, SER_RI))
- sigon |= SER_RI;
- return (sigon);
- }
-
- mcr = sc->sc_mcr;
- if (ISSET(sigon, SER_DTR))
- mcr |= SER_DTR;
- if (ISSET(sigoff, SER_DTR))
- mcr &= ~SER_DTR;
- if (ISSET(sigon, SER_RTS))
- mcr |= SER_RTS;
- if (ISSET(sigoff, SER_RTS))
- mcr &= ~SER_RTS;
- sc->sc_mcr = mcr;
-
- onoff = ISSET(sc->sc_mcr, SER_DTR) ? 1 : 0;
- ucom_dtr(sc, onoff);
-
- onoff = ISSET(sc->sc_mcr, SER_RTS) ? 1 : 0;
- ucom_rts(sc, onoff);
-
- return (0);
-}
-
-static void
-ucombreak(struct ucom_softc *sc, int onoff)
-{
- DPRINTF(("ucombreak: onoff = %d\n", onoff));
-
- if (sc->sc_callback->ucom_set == NULL)
- return;
- sc->sc_callback->ucom_set(sc->sc_parent, sc->sc_portno,
- UCOM_SET_BREAK, onoff);
-}
-
-static void
-ucom_dtr(struct ucom_softc *sc, int onoff)
-{
- DPRINTF(("ucom_dtr: onoff = %d\n", onoff));
-
- if (sc->sc_callback->ucom_set == NULL)
- return;
- sc->sc_callback->ucom_set(sc->sc_parent, sc->sc_portno,
- UCOM_SET_DTR, onoff);
-}
-
-static void
-ucom_rts(struct ucom_softc *sc, int onoff)
-{
- DPRINTF(("ucom_rts: onoff = %d\n", onoff));
-
- if (sc->sc_callback->ucom_set == NULL)
- return;
- sc->sc_callback->ucom_set(sc->sc_parent, sc->sc_portno,
- UCOM_SET_RTS, onoff);
-}
-
-void
-ucom_status_change(struct ucom_softc *sc)
-{
- struct tty *tp = sc->sc_tty;
- u_char old_msr;
- int onoff;
-
- if (sc->sc_callback->ucom_get_status == NULL) {
- sc->sc_lsr = 0;
- sc->sc_msr = 0;
- return;
- }
-
- old_msr = sc->sc_msr;
- sc->sc_callback->ucom_get_status(sc->sc_parent, sc->sc_portno,
- &sc->sc_lsr, &sc->sc_msr);
- if (ISSET((sc->sc_msr ^ old_msr), SER_DCD)) {
- if (sc->sc_poll == 0)
- return;
- onoff = ISSET(sc->sc_msr, SER_DCD) ? 1 : 0;
- DPRINTF(("ucom_status_change: DCD changed to %d\n", onoff));
- ttydisc_modem(tp, onoff);
- }
-}
-
-static int
-ucomtty_param(struct tty *tp, struct termios *t)
-{
- struct ucom_softc *sc = tty_softc(tp);
- int error;
- usbd_status uerr;
-
- if (sc->sc_dying)
- return (EIO);
-
- DPRINTF(("ucomtty_param: sc = %p\n", sc));
-
- /* Check requested parameters. */
- if (t->c_ospeed < 0) {
- DPRINTF(("ucomtty_param: negative ospeed\n"));
- return (EINVAL);
- }
- if (t->c_ispeed && t->c_ispeed != t->c_ospeed) {
- DPRINTF(("ucomtty_param: mismatch ispeed and ospeed\n"));
- return (EINVAL);
- }
- t->c_ispeed = t->c_ospeed;
-
- if (sc->sc_callback->ucom_param == NULL)
- return (0);
-
- ucomstopread(sc);
-
- error = sc->sc_callback->ucom_param(sc->sc_parent, sc->sc_portno, t);
- if (error) {
- DPRINTF(("ucomtty_param: callback: error = %d\n", error));
- return (error);
- }
-
-#if 0
- ttsetwater(tp);
-#endif
-
- if (t->c_cflag & CRTS_IFLOW) {
- sc->sc_state |= UCS_RTS_IFLOW;
- } else if (sc->sc_state & UCS_RTS_IFLOW) {
- sc->sc_state &= ~UCS_RTS_IFLOW;
- (void)ucomtty_modem(tp, SER_RTS, 0);
- }
-
-#if 0
- ttyldoptim(tp);
-#endif
-
- uerr = ucomstartread(sc);
- if (uerr != USBD_NORMAL_COMPLETION)
- return (EIO);
-
- return (0);
-}
-
-static void
-ucomtty_free(void *sc)
-{
- /*
- * Our softc gets deallocated earlier on.
- * XXX: we should make sure the TTY device name doesn't get
- * recycled before we end up here!
- */
-}
-
-static void
-ucomtty_outwakeup(struct tty *tp)
-{
- struct ucom_softc *sc = tty_softc(tp);
- usbd_status err;
- size_t cnt;
-
- DPRINTF(("ucomtty_outwakeup: sc = %p\n", sc));
-
- if (sc->sc_dying)
- return;
-
- /*
- * If there's no sc_oxfer, then ucomclose has removed it. The buffer
- * has just been flushed in the ttyflush() in ttyclose(). ttyflush()
- * then calls tt_stop(). ucomstop calls ucomstart, so the right thing
- * to do here is just abort if sc_oxfer is NULL, as everything else
- * is cleaned up elsewhere.
- */
- if (sc->sc_oxfer == NULL)
- return;
-
- /* XXX: hardware flow control. We should use inwakeup here. */
-#if 0
- if (tp->t_state & TS_TBLOCK) {
- if (ISSET(sc->sc_mcr, SER_RTS) &&
- ISSET(sc->sc_state, UCS_RTS_IFLOW)) {
- DPRINTF(("ucomtty_outwakeup: clear RTS\n"));
- (void)ucomtty_modem(tp, 0, SER_RTS);
- }
- } else {
- if (!ISSET(sc->sc_mcr, SER_RTS) &&
- tp->t_rawq.c_cc <= tp->t_ilowat &&
- ISSET(sc->sc_state, UCS_RTS_IFLOW)) {
- DPRINTF(("ucomtty_outwakeup: set RTS\n"));
- (void)ucomtty_modem(tp, SER_RTS, 0);
- }
- }
-#endif
-
- if (sc->sc_state & UCS_TXBUSY)
- return;
-
- sc->sc_state |= UCS_TXBUSY;
- if (sc->sc_callback->ucom_write != NULL)
- cnt = sc->sc_callback->ucom_write(sc->sc_parent,
- sc->sc_portno, tp, sc->sc_obuf, sc->sc_obufsize);
- else
- cnt = ttydisc_getc(tp, sc->sc_obuf, sc->sc_obufsize);
-
- if (cnt == 0) {
- DPRINTF(("ucomtty_outwakeup: cnt == 0\n"));
- sc->sc_state &= ~UCS_TXBUSY;
- return;
- }
- sc->sc_obufactive = cnt;
-
- DPRINTF(("ucomtty_outwakeup: %zu chars\n", cnt));
- usbd_setup_xfer(sc->sc_oxfer, sc->sc_bulkout_pipe,
- (usbd_private_handle)sc, sc->sc_obuf, cnt,
- USBD_NO_COPY, USBD_NO_TIMEOUT, ucomwritecb);
- /* What can we do on error? */
- err = usbd_transfer(sc->sc_oxfer);
- if (err != USBD_IN_PROGRESS) {
- printf("ucomtty_outwakeup: err=%s\n", usbd_errstr(err));
- sc->sc_state &= ~UCS_TXBUSY;
- }
-}
-
-#if 0
-static void
-ucomstop(struct tty *tp, int flag)
-{
- struct ucom_softc *sc = tty_softc(tp);
- int s;
-
- DPRINTF(("ucomstop: %d\n", flag));
-
- if ((flag & FREAD) && (sc->sc_state & UCS_RXSTOP) == 0) {
- DPRINTF(("ucomstop: read\n"));
- ucomstopread(sc);
- ucomstartread(sc);
- }
-
- if (flag & FWRITE) {
- DPRINTF(("ucomstop: write\n"));
- if (ISSET(tp->t_state, TS_BUSY)) {
- /* XXX do what? */
- if (!ISSET(tp->t_state, TS_TTSTOP))
- SET(tp->t_state, TS_FLUSH);
- }
- }
-
- ucomtty_outwakeup(tp);
-
- DPRINTF(("ucomstop: done\n"));
-}
-#endif
-
-static void
-ucomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
-{
- struct ucom_softc *sc = (struct ucom_softc *)p;
- struct tty *tp = sc->sc_tty;
- u_int32_t cc;
-
- DPRINTF(("ucomwritecb: status = %d\n", status));
-
- if (status == USBD_CANCELLED || sc->sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- printf("%s: ucomwritecb: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
- /* XXX we should restart after some delay. */
- return;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL);
- DPRINTF(("ucomwritecb: cc = %d\n", cc));
- if (cc <= sc->sc_opkthdrlen) {
- printf("%s: sent size too small, cc = %d\n",
- device_get_nameunit(sc->sc_dev), cc);
- return;
- }
-
- /* convert from USB bytes to tty bytes */
- cc -= sc->sc_opkthdrlen;
- if (cc != sc->sc_obufactive)
- panic("Partial write of %d of %d bytes, not supported\n",
- cc, sc->sc_obufactive);
-
- sc->sc_state &= ~UCS_TXBUSY;
-#if 0
- CLR(tp->t_state, TS_BUSY);
- if (ISSET(tp->t_state, TS_FLUSH))
- CLR(tp->t_state, TS_FLUSH);
- else
- ndflush(&tp->t_outq, cc);
-#endif
- ucomtty_outwakeup(tp);
-}
-
-static usbd_status
-ucomstartread(struct ucom_softc *sc)
-{
- usbd_status err;
-
- DPRINTF(("ucomstartread: start\n"));
-
- if (sc->sc_bulkin_pipe == NULL || (sc->sc_state & UCS_RXSTOP) == 0)
- return (USBD_NORMAL_COMPLETION);
- sc->sc_state &= ~UCS_RXSTOP;
-
- usbd_setup_xfer(sc->sc_ixfer, sc->sc_bulkin_pipe,
- (usbd_private_handle)sc,
- sc->sc_ibuf, sc->sc_ibufsize,
- USBD_SHORT_XFER_OK | USBD_NO_COPY,
- USBD_NO_TIMEOUT, ucomreadcb);
-
- err = usbd_transfer(sc->sc_ixfer);
- if (err && err != USBD_IN_PROGRESS) {
- sc->sc_state |= UCS_RXSTOP;
- DPRINTF(("ucomstartread: err = %s\n", usbd_errstr(err)));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-void
-ucomrxchars(struct ucom_softc *sc, u_char *cp, u_int32_t cc)
-{
- struct tty *tp = sc->sc_tty;
-
- /* Give characters to tty layer. */
- if (ttydisc_can_bypass(tp)) {
- DPRINTFN(7, ("ucomreadcb: buf = %*D\n", cc, cp, ""));
- cc -= ttydisc_rint_bypass(tp, cp, cc);
- } else {
- while (cc > 0) {
- DPRINTFN(7, ("ucomreadcb: char = 0x%02x\n", *cp));
- if (ttydisc_rint(tp, *cp, 0) == -1)
- break;
- cc--;
- cp++;
- }
- }
- if (cc > 0)
- device_printf(sc->sc_dev, "lost %d chars\n", cc);
- ttydisc_rint_done(tp);
-}
-
-static void
-ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
-{
- struct ucom_softc *sc = (struct ucom_softc *)p;
- struct tty *tp = sc->sc_tty;
- usbd_status err;
- u_int32_t cc;
- u_char *cp;
-
- (void)tp; /* Used for debugging */
- DPRINTF(("ucomreadcb: status = %d\n", status));
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (!(sc->sc_state & UCS_RXSTOP))
- printf("%s: ucomreadcb: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(status));
- sc->sc_state |= UCS_RXSTOP;
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
- /* XXX we should restart after some delay. */
- return;
- }
- sc->sc_state |= UCS_RXSTOP;
-
- usbd_get_xfer_status(xfer, NULL, (void **)&cp, &cc, NULL);
- DPRINTF(("ucomreadcb: got %d chars, tp = %p\n", cc, tp));
- if (cc == 0)
- goto resubmit;
-
- if (sc->sc_callback->ucom_read != NULL)
- sc->sc_callback->ucom_read(sc->sc_parent, sc->sc_portno,
- &cp, &cc);
-
- if (cc > sc->sc_ibufsize) {
- printf("%s: invalid receive data size, %d chars\n",
- device_get_nameunit(sc->sc_dev), cc);
- goto resubmit;
- }
- if (cc > 0)
- ucomrxchars(sc, cp, cc);
-
- resubmit:
- err = ucomstartread(sc);
- if (err) {
- printf("%s: read start failed\n", device_get_nameunit(sc->sc_dev));
- /* XXX what should we dow now? */
- }
-
-#if 0
- if ((sc->sc_state & UCS_RTS_IFLOW) && !ISSET(sc->sc_mcr, SER_RTS)
- && !(tp->t_state & TS_TBLOCK))
- ucomtty_modem(tp, SER_RTS, 0);
-#endif
-}
-
-static void
-ucom_cleanup(struct ucom_softc *sc)
-{
- DPRINTF(("ucom_cleanup: closing pipes\n"));
-
- ucom_shutdown(sc);
- if (sc->sc_bulkin_pipe != NULL) {
- sc->sc_state |= UCS_RXSTOP;
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- usbd_close_pipe(sc->sc_bulkin_pipe);
- sc->sc_bulkin_pipe = NULL;
- }
- if (sc->sc_bulkout_pipe != NULL) {
- usbd_abort_pipe(sc->sc_bulkout_pipe);
- usbd_close_pipe(sc->sc_bulkout_pipe);
- sc->sc_bulkout_pipe = NULL;
- }
- if (sc->sc_ixfer != NULL) {
- usbd_free_xfer(sc->sc_ixfer);
- sc->sc_ixfer = NULL;
- }
- if (sc->sc_oxfer != NULL) {
- usbd_free_xfer(sc->sc_oxfer);
- sc->sc_oxfer = NULL;
- }
-}
-
-static void
-ucomstopread(struct ucom_softc *sc)
-{
- usbd_status err;
-
- DPRINTF(("ucomstopread: enter\n"));
-
- if (!(sc->sc_state & UCS_RXSTOP)) {
- sc->sc_state |= UCS_RXSTOP;
- if (sc->sc_bulkin_pipe == NULL) {
- DPRINTF(("ucomstopread: bulkin pipe NULL\n"));
- return;
- }
- err = usbd_abort_pipe(sc->sc_bulkin_pipe);
- if (err) {
- DPRINTF(("ucomstopread: err = %s\n",
- usbd_errstr(err)));
- }
- }
-
- DPRINTF(("ucomstopread: leave\n"));
-}
diff --git a/sys/legacy/dev/usb/ucomvar.h b/sys/legacy/dev/usb/ucomvar.h
deleted file mode 100644
index 4433a1a..0000000
--- a/sys/legacy/dev/usb/ucomvar.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/* $NetBSD: ucomvar.h,v 1.9 2001/01/23 21:56:17 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2001-2002, Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*-
- * Copyright (c) 1999 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* Module interface related macros */
-#define UCOM_MODVER 1
-
-#define UCOM_MINVER 1
-#define UCOM_PREFVER UCOM_MODVER
-#define UCOM_MAXVER 1
-
-/* Macros to clear/set/test flags. */
-#define SET(t, f) (t) |= (f)
-#define CLR(t, f) (t) &= ~((unsigned)(f))
-#define ISSET(t, f) ((t) & (f))
-
-#define UCOM_CALLOUT_MASK 0x80
-
-#define UCOMUNIT_MASK 0x3ff7f
-#define UCOMDIALOUT_MASK 0x80000
-#define UCOMCALLUNIT_MASK 0x40000
-
-#define UCOMUNIT(x) (dev2unit(x) & UCOMUNIT_MASK)
-#define UCOMDIALOUT(x) (dev2unit(x) & UCOMDIALOUT_MASK)
-#define UCOMCALLUNIT(x) (dev2unit(x) & UCOMCALLUNIT_MASK)
-
-#define UCOM_UNK_PORTNO -1 /* XXX */
-
-struct tty;
-struct ucom_softc;
-
-struct ucom_callback {
- void (*ucom_get_status)(void *, int, u_char *, u_char *);
- void (*ucom_set)(void *, int, int, int);
-#define UCOM_SET_DTR 1
-#define UCOM_SET_RTS 2
-#define UCOM_SET_BREAK 3
- int (*ucom_param)(void *, int, struct termios *);
- int (*ucom_ioctl)(void *, int, u_long, caddr_t, struct thread *);
- int (*ucom_open)(void *, int);
- void (*ucom_close)(void *, int);
- void (*ucom_read)(void *, int, u_char **, u_int32_t *);
- size_t (*ucom_write)(void *, int, struct tty *, u_char *, u_int32_t);
-};
-
-/* line status register */
-#define ULSR_RCV_FIFO 0x80
-#define ULSR_TSRE 0x40 /* Transmitter empty: byte sent */
-#define ULSR_TXRDY 0x20 /* Transmitter buffer empty */
-#define ULSR_BI 0x10 /* Break detected */
-#define ULSR_FE 0x08 /* Framing error: bad stop bit */
-#define ULSR_PE 0x04 /* Parity error */
-#define ULSR_OE 0x02 /* Overrun, lost incoming byte */
-#define ULSR_RXRDY 0x01 /* Byte ready in Receive Buffer */
-#define ULSR_RCV_MASK 0x1f /* Mask for incoming data or error */
-
-/* ucom state declarations */
-#define UCS_RXSTOP 0x0001 /* Rx stopped */
-#define UCS_TXBUSY 0x0002 /* Tx busy */
-#define UCS_RTS_IFLOW 0x0008 /* use RTS input flow control */
-
-struct ucom_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev; /* USB device */
- usbd_interface_handle sc_iface; /* data interface */
-
- int sc_bulkin_no; /* bulk in endpoint address */
- usbd_pipe_handle sc_bulkin_pipe; /* bulk in pipe */
- usbd_xfer_handle sc_ixfer; /* read request */
- u_char *sc_ibuf; /* read buffer */
- u_int sc_ibufsize; /* read buffer size */
- u_int sc_ibufsizepad; /* read buffer size padded */
-
- int sc_bulkout_no; /* bulk out endpoint address */
- usbd_pipe_handle sc_bulkout_pipe;/* bulk out pipe */
- usbd_xfer_handle sc_oxfer; /* write request */
- u_char *sc_obuf; /* write buffer */
- u_int sc_obufsize; /* write buffer size */
- u_int sc_opkthdrlen; /* header length of
- output packet */
- u_int sc_obufactive; /* Active bytes in buffer */
-
- struct ucom_callback *sc_callback;
- void *sc_parent;
- int sc_portno;
-
- struct tty *sc_tty; /* our tty */
-
- int sc_state;
-
- int sc_poll;
-
- u_char sc_lsr;
- u_char sc_msr;
- u_char sc_mcr;
-
- u_char sc_dying; /* disconnecting */
-
-};
-
-extern devclass_t ucom_devclass;
-
-void ucom_attach_tty(struct ucom_softc *, char*, int);
-int ucom_attach(struct ucom_softc *);
-int ucom_detach(struct ucom_softc *);
-void ucom_status_change(struct ucom_softc *);
-void ucomrxchars(struct ucom_softc *sc, u_char *cp, u_int32_t cc);
diff --git a/sys/legacy/dev/usb/ucycom.c b/sys/legacy/dev/usb/ucycom.c
deleted file mode 100644
index ecf115f..0000000
--- a/sys/legacy/dev/usb/ucycom.c
+++ /dev/null
@@ -1,543 +0,0 @@
-/*-
- * Copyright (c) 2004 Dag-Erling Coïdan Smørgrav
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
- * in this position and unchanged.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * Device driver for Cypress CY7C637xx and CY7C640/1xx series USB to
- * RS232 bridges.
- *
- * Normally, a driver for a USB-to-serial chip would hang off the ucom(4)
- * driver, but ucom(4) was written under the assumption that all USB-to-
- * serial chips use bulk pipes for I/O, while the Cypress parts use HID
- * reports.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/sysctl.h>
-#include <sys/bus.h>
-#include <sys/tty.h>
-
-#include "usbdevs.h"
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbhid.h>
-#include <dev/usb/hid.h>
-
-#define UCYCOM_EP_INPUT 0
-#define UCYCOM_EP_OUTPUT 1
-
-#define UCYCOM_MAX_IOLEN 32U
-
-struct ucycom_softc {
- device_t sc_dev;
- struct tty *sc_tty;
- int sc_error;
- unsigned long sc_cintr;
- unsigned long sc_cin;
- unsigned long sc_clost;
- unsigned long sc_cout;
-
- /* usb parameters */
- usbd_device_handle sc_usbdev;
- usbd_interface_handle sc_iface;
- usbd_pipe_handle sc_pipe;
- uint8_t sc_iep; /* input endpoint */
- uint8_t sc_fid; /* feature report id*/
- uint8_t sc_iid; /* input report id */
- uint8_t sc_oid; /* output report id */
- size_t sc_flen; /* feature report length */
- size_t sc_ilen; /* input report length */
- size_t sc_olen; /* output report length */
- uint8_t sc_ibuf[UCYCOM_MAX_IOLEN];
-
- /* model and settings */
- uint32_t sc_model;
-#define MODEL_CY7C63743 0x63743
-#define MODEL_CY7C64013 0x64013
- uint32_t sc_baud;
- uint8_t sc_cfg;
-#define UCYCOM_CFG_RESET 0x80
-#define UCYCOM_CFG_PARODD 0x20
-#define UCYCOM_CFG_PAREN 0x10
-#define UCYCOM_CFG_STOPB 0x08
-#define UCYCOM_CFG_DATAB 0x03
- uint8_t sc_ist; /* status flags from last input */
- uint8_t sc_ost; /* status flags for next output */
-
- /* flags */
- char sc_dying;
-};
-
-static device_probe_t ucycom_probe;
-static device_attach_t ucycom_attach;
-static device_detach_t ucycom_detach;
-static t_open_t ucycom_open;
-static t_close_t ucycom_close;
-static void ucycom_start(struct tty *);
-static void ucycom_stop(struct tty *, int);
-static int ucycom_param(struct tty *, struct termios *);
-static int ucycom_configure(struct ucycom_softc *, uint32_t, uint8_t);
-static void ucycom_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-
-static device_method_t ucycom_methods[] = {
- DEVMETHOD(device_probe, ucycom_probe),
- DEVMETHOD(device_attach, ucycom_attach),
- DEVMETHOD(device_detach, ucycom_detach),
- { 0, 0 }
-};
-
-static driver_t ucycom_driver = {
- "ucycom",
- ucycom_methods,
- sizeof(struct ucycom_softc),
-};
-
-static devclass_t ucycom_devclass;
-
-DRIVER_MODULE(ucycom, uhub, ucycom_driver, ucycom_devclass, usbd_driver_load, 0);
-MODULE_VERSION(ucycom, 1);
-MODULE_DEPEND(ucycom, usb, 1, 1, 1);
-
-/*
- * Supported devices
- */
-
-static struct ucycom_device {
- uint16_t vendor;
- uint16_t product;
- uint32_t model;
-} ucycom_devices[] = {
- { USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE, MODEL_CY7C64013 },
- { 0, 0, 0 },
-};
-
-#define UCYCOM_DEFAULT_RATE 4800
-#define UCYCOM_DEFAULT_CFG 0x03 /* N-8-1 */
-
-/*****************************************************************************
- *
- * Driver interface
- *
- */
-
-static int
-ucycom_probe(device_t dev)
-{
- struct usb_attach_arg *uaa;
- struct ucycom_device *ud;
-
- uaa = device_get_ivars(dev);
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
- for (ud = ucycom_devices; ud->model != 0; ++ud)
- if (ud->vendor == uaa->vendor && ud->product == uaa->product)
- return (UMATCH_VENDOR_PRODUCT);
- return (UMATCH_NONE);
-}
-
-static int
-ucycom_attach(device_t dev)
-{
- struct usb_attach_arg *uaa;
- struct ucycom_softc *sc;
- struct ucycom_device *ud;
- usb_endpoint_descriptor_t *ued;
- void *urd;
- int error, urdlen;
-
- /* get arguments and softc */
- uaa = device_get_ivars(dev);
- sc = device_get_softc(dev);
- bzero(sc, sizeof *sc);
- sc->sc_dev = dev;
- sc->sc_usbdev = uaa->device;
-
- /* get chip model */
- for (ud = ucycom_devices; ud->model != 0; ++ud)
- if (ud->vendor == uaa->vendor && ud->product == uaa->product)
- sc->sc_model = ud->model;
- if (sc->sc_model == 0) {
- device_printf(dev, "unsupported device\n");
- return (ENXIO);
- }
- device_printf(dev, "Cypress CY7C%X USB to RS232 bridge\n", sc->sc_model);
-
- /* select configuration */
- error = usbd_set_config_index(sc->sc_usbdev, 0, 1 /* verbose */);
- if (error != 0) {
- device_printf(dev, "failed to select configuration: %s\n",
- usbd_errstr(error));
- return (ENXIO);
- }
-
- /* get first interface handle */
- error = usbd_device2interface_handle(sc->sc_usbdev, 0, &sc->sc_iface);
- if (error != 0) {
- device_printf(dev, "failed to get interface handle: %s\n",
- usbd_errstr(error));
- return (ENXIO);
- }
-
- /* get report descriptor */
- error = usbd_read_report_desc(sc->sc_iface, &urd, &urdlen, M_USBDEV);
- if (error != 0) {
- device_printf(dev, "failed to get report descriptor: %s\n",
- usbd_errstr(error));
- return (ENXIO);
- }
-
- /* get report sizes */
- sc->sc_flen = hid_report_size(urd, urdlen, hid_feature, &sc->sc_fid);
- sc->sc_ilen = hid_report_size(urd, urdlen, hid_input, &sc->sc_iid);
- sc->sc_olen = hid_report_size(urd, urdlen, hid_output, &sc->sc_oid);
-
- if (sc->sc_ilen > UCYCOM_MAX_IOLEN || sc->sc_olen > UCYCOM_MAX_IOLEN) {
- device_printf(dev, "I/O report size too big (%zu, %zu, %u)\n",
- sc->sc_ilen, sc->sc_olen, UCYCOM_MAX_IOLEN);
- return (ENXIO);
- }
-
- /* get and verify input endpoint descriptor */
- ued = usbd_interface2endpoint_descriptor(sc->sc_iface, UCYCOM_EP_INPUT);
- if (ued == NULL) {
- device_printf(dev, "failed to get input endpoint descriptor\n");
- return (ENXIO);
- }
- if (UE_GET_DIR(ued->bEndpointAddress) != UE_DIR_IN) {
- device_printf(dev, "not an input endpoint\n");
- return (ENXIO);
- }
- if ((ued->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
- device_printf(dev, "not an interrupt endpoint\n");
- return (ENXIO);
- }
- sc->sc_iep = ued->bEndpointAddress;
-
- /* set up tty */
- sc->sc_tty = ttyalloc();
- sc->sc_tty->t_sc = sc;
- sc->sc_tty->t_oproc = ucycom_start;
- sc->sc_tty->t_stop = ucycom_stop;
- sc->sc_tty->t_param = ucycom_param;
- sc->sc_tty->t_open = ucycom_open;
- sc->sc_tty->t_close = ucycom_close;
-
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "intr", CTLFLAG_RD, &sc->sc_cintr, 0,
- "interrupt count");
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "in", CTLFLAG_RD, &sc->sc_cin, 0,
- "input bytes read");
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "lost", CTLFLAG_RD, &sc->sc_clost, 0,
- "input bytes lost");
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "out", CTLFLAG_RD, &sc->sc_cout, 0,
- "output bytes");
-
- /* create character device node */
- ttycreate(sc->sc_tty, 0, "y%r", device_get_unit(sc->sc_dev));
-
- return (0);
-}
-
-static int
-ucycom_detach(device_t dev)
-{
- struct ucycom_softc *sc;
-
- sc = device_get_softc(dev);
-
- ttyfree(sc->sc_tty);
-
- return (0);
-}
-
-/*****************************************************************************
- *
- * Device interface
- *
- */
-
-static int
-ucycom_open(struct tty *tp, struct cdev *cdev)
-{
- struct ucycom_softc *sc = tp->t_sc;
- int error;
-
- /* set default configuration */
- ucycom_configure(sc, UCYCOM_DEFAULT_RATE, UCYCOM_DEFAULT_CFG);
-
- /* open interrupt pipe */
- error = usbd_open_pipe_intr(sc->sc_iface, sc->sc_iep, 0,
- &sc->sc_pipe, sc, sc->sc_ibuf, sc->sc_ilen,
- ucycom_intr, USBD_DEFAULT_INTERVAL);
- if (error != 0) {
- device_printf(sc->sc_dev, "failed to open interrupt pipe: %s\n",
- usbd_errstr(error));
- return (ENXIO);
- }
-
- if (bootverbose)
- device_printf(sc->sc_dev, "%s bypass l_rint()\n",
- (sc->sc_tty->t_state & TS_CAN_BYPASS_L_RINT) ?
- "can" : "can't");
-
- /* done! */
- return (0);
-}
-
-static void
-ucycom_close(struct tty *tp)
-{
- struct ucycom_softc *sc = tp->t_sc;
-
- /* stop interrupts and close the interrupt pipe */
- usbd_abort_pipe(sc->sc_pipe);
- usbd_close_pipe(sc->sc_pipe);
- sc->sc_pipe = 0;
-
- return;
-}
-
-/*****************************************************************************
- *
- * TTY interface
- *
- */
-
-static void
-ucycom_start(struct tty *tty)
-{
- struct ucycom_softc *sc = tty->t_sc;
- uint8_t report[sc->sc_olen];
- int error, len;
-
- while (sc->sc_error == 0 && sc->sc_tty->t_outq.c_cc > 0) {
- switch (sc->sc_model) {
- case MODEL_CY7C63743:
- len = q_to_b(&sc->sc_tty->t_outq,
- report + 1, sc->sc_olen - 1);
- sc->sc_cout += len;
- report[0] = len;
- len += 1;
- break;
- case MODEL_CY7C64013:
- len = q_to_b(&sc->sc_tty->t_outq,
- report + 2, sc->sc_olen - 2);
- sc->sc_cout += len;
- report[0] = 0;
- report[1] = len;
- len += 2;
- break;
- default:
- panic("unsupported model (driver error)");
- }
-
- while (len < sc->sc_olen)
- report[len++] = 0;
- error = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
- sc->sc_oid, report, sc->sc_olen);
-#if 0
- if (error != 0) {
- device_printf(sc->sc_dev,
- "failed to set output report: %s\n",
- usbd_errstr(error));
- sc->sc_error = error;
- }
-#endif
- }
-}
-
-static void
-ucycom_stop(struct tty *tty, int flags)
-{
- struct ucycom_softc *sc;
-
- sc = tty->t_sc;
- if (bootverbose)
- device_printf(sc->sc_dev, "%s()\n", __func__);
-}
-
-static int
-ucycom_param(struct tty *tty, struct termios *t)
-{
- struct ucycom_softc *sc;
- uint32_t baud;
- uint8_t cfg;
- int error;
-
- sc = tty->t_sc;
-
- if (t->c_ispeed != t->c_ospeed)
- return (EINVAL);
- baud = t->c_ispeed;
-
- if (t->c_cflag & CIGNORE) {
- cfg = sc->sc_cfg;
- } else {
- cfg = 0;
- switch (t->c_cflag & CSIZE) {
- case CS8:
- ++cfg;
- case CS7:
- ++cfg;
- case CS6:
- ++cfg;
- case CS5:
- break;
- default:
- return (EINVAL);
- }
- if (t->c_cflag & CSTOPB)
- cfg |= UCYCOM_CFG_STOPB;
- if (t->c_cflag & PARENB)
- cfg |= UCYCOM_CFG_PAREN;
- if (t->c_cflag & PARODD)
- cfg |= UCYCOM_CFG_PARODD;
- }
-
- error = ucycom_configure(sc, baud, cfg);
- return (error);
-}
-
-/*****************************************************************************
- *
- * Hardware interface
- *
- */
-
-static int
-ucycom_configure(struct ucycom_softc *sc, uint32_t baud, uint8_t cfg)
-{
- uint8_t report[sc->sc_flen];
- int error;
-
- switch (baud) {
- case 600:
- case 1200:
- case 2400:
- case 4800:
- case 9600:
- case 19200:
- case 38400:
- case 57600:
-#if 0
- /*
- * Stock chips only support standard baud rates in the 600 - 57600
- * range, but higher rates can be achieved using custom firmware.
- */
- case 115200:
- case 153600:
- case 192000:
-#endif
- break;
- default:
- return (EINVAL);
- }
-
- if (bootverbose)
- device_printf(sc->sc_dev, "%d baud, %c-%d-%d\n", baud,
- (cfg & UCYCOM_CFG_PAREN) ?
- ((cfg & UCYCOM_CFG_PARODD) ? 'O' : 'E') : 'N',
- 5 + (cfg & UCYCOM_CFG_DATAB),
- (cfg & UCYCOM_CFG_STOPB) ? 2 : 1);
- report[0] = baud & 0xff;
- report[1] = (baud >> 8) & 0xff;
- report[2] = (baud >> 16) & 0xff;
- report[3] = (baud >> 24) & 0xff;
- report[4] = cfg;
- error = usbd_set_report(sc->sc_iface, UHID_FEATURE_REPORT,
- sc->sc_fid, report, sc->sc_flen);
- if (error != 0) {
- device_printf(sc->sc_dev, "%s\n", usbd_errstr(error));
- return (EIO);
- }
- sc->sc_baud = baud;
- sc->sc_cfg = cfg;
- return (0);
-}
-
-static void
-ucycom_intr(usbd_xfer_handle xfer, usbd_private_handle scp, usbd_status status)
-{
- struct ucycom_softc *sc = scp;
- uint8_t *data;
- int i, len, lost;
-
- sc->sc_cintr++;
-
- switch (sc->sc_model) {
- case MODEL_CY7C63743:
- sc->sc_ist = sc->sc_ibuf[0] & ~0x07;
- len = sc->sc_ibuf[0] & 0x07;
- data = sc->sc_ibuf + 1;
- break;
- case MODEL_CY7C64013:
- sc->sc_ist = sc->sc_ibuf[0] & ~0x07;
- len = sc->sc_ibuf[1];
- data = sc->sc_ibuf + 2;
- break;
- default:
- panic("unsupported model (driver error)");
- }
-
- switch (status) {
- case USBD_NORMAL_COMPLETION:
- break;
- default:
- /* XXX */
- return;
- }
-
- if (sc->sc_tty->t_state & TS_CAN_BYPASS_L_RINT) {
- /* XXX flow control! */
- lost = b_to_q(data, len, &sc->sc_tty->t_rawq);
- sc->sc_tty->t_rawcc += len - lost;
- ttwakeup(sc->sc_tty);
- } else {
- for (i = 0, lost = len; i < len; ++i, --lost)
- if (ttyld_rint(sc->sc_tty, data[i]) != 0)
- break;
- }
- sc->sc_cin += len - lost;
- sc->sc_clost += lost;
-}
diff --git a/sys/legacy/dev/usb/udbp.c b/sys/legacy/dev/usb/udbp.c
deleted file mode 100644
index 523184f..0000000
--- a/sys/legacy/dev/usb/udbp.c
+++ /dev/null
@@ -1,860 +0,0 @@
-/*-
- * Copyright (c) 1996-2000 Whistle Communications, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of author nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY NICK HIBMA AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/* Driver for arbitrary double bulk pipe devices.
- * The driver assumes that there will be the same driver on the other side.
- *
- * XXX Some more information on what the framing of the IP packets looks like.
- *
- * To take full advantage of bulk transmission, packets should be chosen
- * between 1k and 5k in size (1k to make sure the sending side starts
- * straming, and <5k to avoid overflowing the system with small TDs).
- */
-
-
-/* probe/attach/detach:
- * Connect the driver to the hardware and netgraph
- *
- * udbp_setup_out_transfer(sc);
- * Setup an outbound transfer. Only one transmit can be active at the same
- * time.
- * XXX If it is required that the driver is able to queue multiple requests
- * let me know. That is slightly difficult, due to the fact that we
- * cannot call usbd_alloc_xfer in int context.
- *
- * udbp_setup_in_transfer(sc)
- * Prepare an in transfer that will be waiting for data to come in. It
- * is submitted and sits there until data is available.
- * The callback resubmits a new transfer on completion.
- *
- * The reason we submit a bulk in transfer is that USB does not know about
- * interrupts. The bulk transfer continuously polls the device for data.
- * While the device has no data available, the device NAKs the TDs. As soon
- * as there is data, the transfer happens and the data comes flowing in.
- *
- * In case you were wondering, interrupt transfers happen exactly that way.
- * It therefore doesn't make sense to use the interrupt pipe to signal
- * 'data ready' and then schedule a bulk transfer to fetch it. That would
- * incur a 2ms delay at least, without reducing bandwidth requirements.
- *
- */
-
-
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/poll.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/ctype.h>
-#include <sys/errno.h>
-#include <sys/sysctl.h>
-#include <net/if.h>
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usbhid.h>
-
-#include "usbdevs.h"
-
-
-#include <netgraph/ng_message.h>
-#include <netgraph/ng_parse.h>
-#include <dev/usb/udbp.h>
-#include <netgraph/netgraph.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (udbpdebug) printf x
-#define DPRINTFN(n,x) if (udbpdebug>(n)) printf x
-int udbpdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, udbp, CTLFLAG_RW, 0, "USB udbp");
-SYSCTL_INT(_hw_usb_udbp, OID_AUTO, debug, CTLFLAG_RW,
- &udbpdebug, 0, "udbp debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-#define UDBP_TIMEOUT 2000 /* timeout on outbound transfers, in msecs */
-#define UDBP_BUFFERSIZE 2048 /* maximum number of bytes in one transfer */
-
-
-struct udbp_softc {
- device_t sc_dev; /* base device */
- usbd_interface_handle sc_iface;
-
- usbd_pipe_handle sc_bulkin_pipe;
- int sc_bulkin;
- usbd_xfer_handle sc_bulkin_xfer;
- void *sc_bulkin_buffer;
- int sc_bulkin_bufferlen;
- int sc_bulkin_datalen;
-
- usbd_pipe_handle sc_bulkout_pipe;
- int sc_bulkout;
- usbd_xfer_handle sc_bulkout_xfer;
- void *sc_bulkout_buffer;
- int sc_bulkout_bufferlen;
- int sc_bulkout_datalen;
-
- int flags;
-# define DISCONNECTED 0x01
-# define OUT_BUSY 0x02
-# define NETGRAPH_INITIALISED 0x04
- node_p node; /* back pointer to node */
- hook_p hook; /* pointer to the hook */
- u_int packets_in; /* packets in from downstream */
- u_int packets_out; /* packets out towards downstream */
- struct ifqueue xmitq_hipri; /* hi-priority transmit queue */
- struct ifqueue xmitq; /* low-priority transmit queue */
-
-};
-typedef struct udbp_softc *udbp_p;
-
-
-
-static ng_constructor_t ng_udbp_constructor;
-static ng_rcvmsg_t ng_udbp_rcvmsg;
-static ng_shutdown_t ng_udbp_rmnode;
-static ng_newhook_t ng_udbp_newhook;
-static ng_connect_t ng_udbp_connect;
-static ng_rcvdata_t ng_udbp_rcvdata;
-static ng_disconnect_t ng_udbp_disconnect;
-
-/* Parse type for struct ngudbpstat */
-static const struct ng_parse_struct_field
- ng_udbp_stat_type_fields[] = NG_UDBP_STATS_TYPE_INFO;
-static const struct ng_parse_type ng_udbp_stat_type = {
- &ng_parse_struct_type,
- &ng_udbp_stat_type_fields
-};
-
-/* List of commands and how to convert arguments to/from ASCII */
-static const struct ng_cmdlist ng_udbp_cmdlist[] = {
- {
- NGM_UDBP_COOKIE,
- NGM_UDBP_GET_STATUS,
- "getstatus",
- NULL,
- &ng_udbp_stat_type,
- },
- {
- NGM_UDBP_COOKIE,
- NGM_UDBP_SET_FLAG,
- "setflag",
- &ng_parse_int32_type,
- NULL
- },
- { 0 }
-};
-
-/* Netgraph node type descriptor */
-static struct ng_type ng_udbp_typestruct = {
- .version = NG_ABI_VERSION,
- .name = NG_UDBP_NODE_TYPE,
- .constructor = ng_udbp_constructor,
- .rcvmsg = ng_udbp_rcvmsg,
- .shutdown = ng_udbp_rmnode,
- .newhook = ng_udbp_newhook,
- .connect = ng_udbp_connect,
- .rcvdata = ng_udbp_rcvdata,
- .disconnect = ng_udbp_disconnect,
- .cmdlist = ng_udbp_cmdlist,
-};
-
-static int udbp_setup_in_transfer (udbp_p sc);
-static void udbp_in_transfer_cb (usbd_xfer_handle xfer,
- usbd_private_handle priv,
- usbd_status err);
-
-static int udbp_setup_out_transfer (udbp_p sc);
-static void udbp_out_transfer_cb (usbd_xfer_handle xfer,
- usbd_private_handle priv,
- usbd_status err);
-
-static device_probe_t udbp_match;
-static device_attach_t udbp_attach;
-static device_detach_t udbp_detach;
-
-static device_method_t udbp_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, udbp_match),
- DEVMETHOD(device_attach, udbp_attach),
- DEVMETHOD(device_detach, udbp_detach),
-
- { 0, 0 }
-};
-
-static driver_t udbp_driver = {
- "udbp",
- udbp_methods,
- sizeof(struct udbp_softc)
-};
-
-static devclass_t udbp_devclass;
-
-static int
-udbp_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
- if (!uaa->iface)
- return (UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
-
- /* XXX Julian, add the id of the device if you have one to test
- * things with. run 'usbdevs -v' and note the 3 ID's that appear.
- * The Vendor Id and Product Id are in hex and the Revision Id is in
- * bcd. But as usual if the revision is 0x101 then you should compare
- * the revision id in the device descriptor with 0x101
- * Or go search the file usbdevs.h. Maybe the device is already in
- * there.
- */
- if ((uaa->vendor == USB_VENDOR_NETCHIP &&
- uaa->product == USB_PRODUCT_NETCHIP_TURBOCONNECT))
- return (UMATCH_VENDOR_PRODUCT);
-
- if ((uaa->vendor == USB_VENDOR_PROLIFIC &&
- (uaa->product == USB_PRODUCT_PROLIFIC_PL2301 ||
- uaa->product == USB_PRODUCT_PROLIFIC_PL2302)))
- return (UMATCH_VENDOR_PRODUCT);
-
- if ((uaa->vendor == USB_VENDOR_ANCHOR &&
- uaa->product == USB_PRODUCT_ANCHOR_EZLINK))
- return (UMATCH_VENDOR_PRODUCT);
-
- if ((uaa->vendor == USB_VENDOR_GENESYS &&
- uaa->product == USB_PRODUCT_GENESYS_GL620USB))
- return (UMATCH_VENDOR_PRODUCT);
-
- return (UMATCH_NONE);
-}
-
-static int
-udbp_attach(device_t self)
-{
- struct udbp_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed, *ed_bulkin = NULL, *ed_bulkout = NULL;
- usbd_status err;
- int i;
- static int ngudbp_done_init=0;
-
- sc->flags |= DISCONNECTED;
- /* fetch the interface handle for the first interface */
- (void) usbd_device2interface_handle(uaa->device, 0, &iface);
- id = usbd_get_interface_descriptor(iface);
- sc->sc_dev = self;
-
- /* Find the two first bulk endpoints */
- for (i = 0 ; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (!ed) {
- device_printf(self, "could not read endpoint descriptor\n");
- return ENXIO;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ed_bulkin = ed;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ed_bulkout = ed;
- }
-
- if (ed_bulkin && ed_bulkout) /* found all we need */
- break;
- }
-
- /* Verify that we goething sensible */
- if (ed_bulkin == NULL || ed_bulkout == NULL) {
- device_printf(self, "bulk-in and/or bulk-out endpoint not found\n");
- return ENXIO;
- }
-
- if (ed_bulkin->wMaxPacketSize[0] != ed_bulkout->wMaxPacketSize[0] ||
- ed_bulkin->wMaxPacketSize[1] != ed_bulkout->wMaxPacketSize[1]) {
- device_printf(self,
- "bulk-in and bulk-out have different packet sizes %d %d %d %d\n",
- ed_bulkin->wMaxPacketSize[0],
- ed_bulkout->wMaxPacketSize[0],
- ed_bulkin->wMaxPacketSize[1],
- ed_bulkout->wMaxPacketSize[1]);
- return ENXIO;
- }
-
- sc->sc_bulkin = ed_bulkin->bEndpointAddress;
- sc->sc_bulkout = ed_bulkout->bEndpointAddress;
-
- DPRINTF(("%s: Bulk-in: 0x%02x, bulk-out 0x%02x, packet size = %d\n",
- device_get_nameunit(sc->sc_dev), sc->sc_bulkin, sc->sc_bulkout,
- ed_bulkin->wMaxPacketSize[0]));
-
- /* Allocate the in transfer struct */
- sc->sc_bulkin_xfer = usbd_alloc_xfer(uaa->device);
- if (!sc->sc_bulkin_xfer) {
- goto bad;
- }
- sc->sc_bulkout_xfer = usbd_alloc_xfer(uaa->device);
- if (!sc->sc_bulkout_xfer) {
- goto bad;
- }
- sc->sc_bulkin_buffer = malloc(UDBP_BUFFERSIZE, M_USBDEV, M_WAITOK);
- if (!sc->sc_bulkin_buffer) {
- goto bad;
- }
- sc->sc_bulkout_buffer = malloc(UDBP_BUFFERSIZE, M_USBDEV, M_WAITOK);
- if (!sc->sc_bulkout_xfer || !sc->sc_bulkout_buffer) {
- goto bad;
- }
- sc->sc_bulkin_bufferlen = UDBP_BUFFERSIZE;
- sc->sc_bulkout_bufferlen = UDBP_BUFFERSIZE;
-
- /* We have decided on which endpoints to use, now open the pipes */
- err = usbd_open_pipe(iface, sc->sc_bulkin,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
- if (err) {
- device_printf(self, "cannot open bulk-in pipe (addr %d)\n",
- sc->sc_bulkin);
- goto bad;
- }
- err = usbd_open_pipe(iface, sc->sc_bulkout,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
- if (err) {
- device_printf(self, "cannot open bulk-out pipe (addr %d)\n",
- sc->sc_bulkout);
- goto bad;
- }
-
- if (!ngudbp_done_init){
- ngudbp_done_init=1;
- if (ng_newtype(&ng_udbp_typestruct)) {
- printf("ngudbp install failed\n");
- goto bad;
- }
- }
-
- if ((err = ng_make_node_common(&ng_udbp_typestruct, &sc->node)) == 0) {
- char nodename[128];
- sprintf(nodename, "%s", device_get_nameunit(sc->sc_dev));
- if ((err = ng_name_node(sc->node, nodename))) {
- NG_NODE_UNREF(sc->node);
- sc->node = NULL;
- goto bad;
- } else {
- NG_NODE_SET_PRIVATE(sc->node, sc);
- sc->xmitq.ifq_maxlen = IFQ_MAXLEN;
- sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN;
- mtx_init(&sc->xmitq.ifq_mtx, "usb_xmitq", NULL,
- MTX_DEF);
- mtx_init(&sc->xmitq_hipri.ifq_mtx,
- "usb_xmitq_hipri", NULL, MTX_DEF);
- }
- }
- sc->flags = NETGRAPH_INITIALISED;
- /* sc->flags &= ~DISCONNECTED; */ /* XXX */
-
-
- /* the device is now operational */
-
-
- /* schedule the first incoming xfer */
- err = udbp_setup_in_transfer(sc);
- if (err) {
- goto bad;
- }
- return 0;
-bad:
-#if 0 /* probably done in udbp_detach() */
- if (sc->sc_bulkout_buffer) {
- free(sc->sc_bulkout_buffer, M_USBDEV);
- }
- if (sc->sc_bulkin_buffer) {
- free(sc->sc_bulkin_buffer, M_USBDEV);
- }
- if (sc->sc_bulkout_xfer) {
- usbd_free_xfer(sc->sc_bulkout_xfer);
- }
- if (sc->sc_bulkin_xfer) {
- usbd_free_xfer(sc->sc_bulkin_xfer);
- }
-#endif
- udbp_detach(self);
- return ENXIO;
-}
-
-
-static int
-udbp_detach(device_t self)
-{
- struct udbp_softc *sc = device_get_softc(self);
-
- sc->flags |= DISCONNECTED;
-
- DPRINTF(("%s: disconnected\n", device_get_nameunit(self)));
-
- if (sc->sc_bulkin_pipe) {
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- usbd_close_pipe(sc->sc_bulkin_pipe);
- }
- if (sc->sc_bulkout_pipe) {
- usbd_abort_pipe(sc->sc_bulkout_pipe);
- usbd_close_pipe(sc->sc_bulkout_pipe);
- }
-
- if (sc->flags & NETGRAPH_INITIALISED) {
- ng_rmnode_self(sc->node);
- NG_NODE_SET_PRIVATE(sc->node, NULL);
- NG_NODE_UNREF(sc->node);
- sc->node = NULL; /* Paranoid */
- }
-
- if (sc->sc_bulkin_xfer)
- usbd_free_xfer(sc->sc_bulkin_xfer);
- if (sc->sc_bulkout_xfer)
- usbd_free_xfer(sc->sc_bulkout_xfer);
-
- if (sc->sc_bulkin_buffer)
- free(sc->sc_bulkin_buffer, M_USBDEV);
- if (sc->sc_bulkout_buffer)
- free(sc->sc_bulkout_buffer, M_USBDEV);
- return 0;
-}
-
-
-static int
-udbp_setup_in_transfer(udbp_p sc)
-{
- void *priv = sc; /* XXX this should probably be some pointer to
- * struct describing the transfer (mbuf?)
- * See also below.
- */
- usbd_status err;
-
- /* XXX
- * How should we arrange for 2 extra bytes at the start of the
- * packet?
- */
-
- /* Initialise a USB transfer and then schedule it */
-
- (void) usbd_setup_xfer( sc->sc_bulkin_xfer,
- sc->sc_bulkin_pipe,
- priv,
- sc->sc_bulkin_buffer,
- sc->sc_bulkin_bufferlen,
- USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT,
- udbp_in_transfer_cb);
-
- err = usbd_transfer(sc->sc_bulkin_xfer);
- if (err && err != USBD_IN_PROGRESS) {
- DPRINTF(("%s: failed to setup in-transfer, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
- return(err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-udbp_in_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status err)
-{
- udbp_p sc = priv; /* XXX see priv above */
- int s;
- int len;
- struct mbuf *m;
-
- if (err) {
- if (err != USBD_CANCELLED) {
- DPRINTF(("%s: bulk-out transfer failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
- } else {
- /* USBD_CANCELLED happens at unload of the driver */
- return;
- }
-
- /* Transfer has failed, packet is not received */
- } else {
-
- len = xfer->actlen;
-
- s = splimp(); /* block network stuff too */
- if (sc->hook) {
- /* get packet from device and send on */
- m = m_devget(sc->sc_bulkin_buffer, len, 0, NULL, NULL);
- NG_SEND_DATA_ONLY(err, sc->hook, m);
- }
- splx(s);
-
- }
- /* schedule the next in transfer */
- udbp_setup_in_transfer(sc);
-}
-
-
-static int
-udbp_setup_out_transfer(udbp_p sc)
-{
- void *priv = sc; /* XXX this should probably be some pointer to
- * struct describing the transfer (mbuf?)
- * See also below.
- */
- int pktlen;
- usbd_status err;
- int s, s1;
- struct mbuf *m;
-
-
- s = splusb();
- if (sc->flags & OUT_BUSY)
- panic("out transfer already in use, we should add queuing");
- sc->flags |= OUT_BUSY;
- splx(s);
- s1 = splimp(); /* Queueing happens at splnet */
- IF_DEQUEUE(&sc->xmitq_hipri, m);
- if (m == NULL) {
- IF_DEQUEUE(&sc->xmitq, m);
- }
- splx(s1);
-
- if (!m) {
- sc->flags &= ~OUT_BUSY;
- return (USBD_NORMAL_COMPLETION);
- }
-
- pktlen = m->m_pkthdr.len;
- if (pktlen > sc->sc_bulkout_bufferlen) {
- device_printf(sc->sc_dev, "Packet too large, %d > %d\n",
- pktlen, sc->sc_bulkout_bufferlen);
- return (USBD_IOERROR);
- }
-
- m_copydata(m, 0, pktlen, sc->sc_bulkout_buffer);
- m_freem(m);
-
- /* Initialise a USB transfer and then schedule it */
-
- (void) usbd_setup_xfer( sc->sc_bulkout_xfer,
- sc->sc_bulkout_pipe,
- priv,
- sc->sc_bulkout_buffer,
- pktlen,
- USBD_SHORT_XFER_OK,
- UDBP_TIMEOUT,
- udbp_out_transfer_cb);
-
- err = usbd_transfer(sc->sc_bulkout_xfer);
- if (err && err != USBD_IN_PROGRESS) {
- DPRINTF(("%s: failed to setup out-transfer, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
- return(err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-udbp_out_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status err)
-{
- udbp_p sc = priv; /* XXX see priv above */
- int s;
-
- if (err) {
- DPRINTF(("%s: bulk-out transfer failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
- /* Transfer has failed, packet is not transmitted */
- /* XXX Invalidate packet */
- return;
- }
-
- /* packet has been transmitted */
-
- s = splusb(); /* mark the buffer available */
- sc->flags &= ~OUT_BUSY;
- udbp_setup_out_transfer(sc);
- splx(s);
-}
-
-DRIVER_MODULE(udbp, uhub, udbp_driver, udbp_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(udbp, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
-MODULE_DEPEND(udbp, usb, 1, 1, 1);
-
-
-/***********************************************************************
- * Start of Netgraph methods
- **********************************************************************/
-
-/*
- * If this is a device node so this work is done in the attach()
- * routine and the constructor will return EINVAL as you should not be able
- * to create nodes that depend on hardware (unless you can add the hardware :)
- */
-static int
-ng_udbp_constructor(node_p node)
-{
- return (EINVAL);
-}
-
-/*
- * Give our ok for a hook to be added...
- * If we are not running this might kick a device into life.
- * Possibly decode information out of the hook name.
- * Add the hook's private info to the hook structure.
- * (if we had some). In this example, we assume that there is a
- * an array of structs, called 'channel' in the private info,
- * one for each active channel. The private
- * pointer of each hook points to the appropriate UDBP_hookinfo struct
- * so that the source of an input packet is easily identified.
- */
-static int
-ng_udbp_newhook(node_p node, hook_p hook, const char *name)
-{
- const udbp_p sc = NG_NODE_PRIVATE(node);
-
-#if 0
- /* Possibly start up the device if it's not already going */
- if ((sc->flags & SCF_RUNNING) == 0) {
- ng_udbp_start_hardware(sc);
- }
-#endif
-
- if (strcmp(name, NG_UDBP_HOOK_NAME) == 0) {
- sc->hook = hook;
- NG_HOOK_SET_PRIVATE(hook, NULL);
- } else {
- return (EINVAL); /* not a hook we know about */
- }
- return(0);
-}
-
-/*
- * Get a netgraph control message.
- * Check it is one we understand. If needed, send a response.
- * We could save the address for an async action later, but don't here.
- * Always free the message.
- * The response should be in a malloc'd region that the caller can 'free'.
- * A response is not required.
- * Theoretically you could respond defferently to old message types if
- * the cookie in the header didn't match what we consider to be current
- * (so that old userland programs could continue to work).
- */
-static int
-ng_udbp_rcvmsg(node_p node, item_p item, hook_p lasthook)
-{
- const udbp_p sc = NG_NODE_PRIVATE(node);
- struct ng_mesg *resp = NULL;
- int error = 0;
- struct ng_mesg *msg;
-
- NGI_GET_MSG(item, msg);
- /* Deal with message according to cookie and command */
- switch (msg->header.typecookie) {
- case NGM_UDBP_COOKIE:
- switch (msg->header.cmd) {
- case NGM_UDBP_GET_STATUS:
- {
- struct ngudbpstat *stats;
-
- NG_MKRESPONSE(resp, msg, sizeof(*stats), M_NOWAIT);
- if (!resp) {
- error = ENOMEM;
- break;
- }
- stats = (struct ngudbpstat *) resp->data;
- stats->packets_in = sc->packets_in;
- stats->packets_out = sc->packets_out;
- break;
- }
- case NGM_UDBP_SET_FLAG:
- if (msg->header.arglen != sizeof(u_int32_t)) {
- error = EINVAL;
- break;
- }
- sc->flags = *((u_int32_t *) msg->data);
- break;
- default:
- error = EINVAL; /* unknown command */
- break;
- }
- break;
- default:
- error = EINVAL; /* unknown cookie type */
- break;
- }
-
- /* Take care of synchronous response, if any */
- NG_RESPOND_MSG(error, node, item, resp);
- NG_FREE_MSG(msg);
- return(error);
-}
-
-/*
- * Accept data from the hook and queue it for output.
- */
-static int
-ng_udbp_rcvdata(hook_p hook, item_p item)
-{
- const udbp_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- int error;
- struct ifqueue *xmitq_p;
- int s;
- struct mbuf *m;
- struct ng_tag_prio *ptag;
-
- NGI_GET_M(item, m);
- NG_FREE_ITEM(item);
-
- /*
- * Now queue the data for when it can be sent
- */
- if ((ptag = (struct ng_tag_prio *)m_tag_locate(m, NGM_GENERIC_COOKIE,
- NG_TAG_PRIO, NULL)) != NULL && (ptag->priority > NG_PRIO_CUTOFF) )
- xmitq_p = (&sc->xmitq_hipri);
- else
- xmitq_p = (&sc->xmitq);
-
- s = splusb();
- IF_LOCK(xmitq_p);
- if (_IF_QFULL(xmitq_p)) {
- _IF_DROP(xmitq_p);
- IF_UNLOCK(xmitq_p);
- splx(s);
- error = ENOBUFS;
- goto bad;
- }
- _IF_ENQUEUE(xmitq_p, m);
- IF_UNLOCK(xmitq_p);
- if (!(sc->flags & OUT_BUSY))
- udbp_setup_out_transfer(sc);
- splx(s);
- return (0);
-
-bad: /*
- * It was an error case.
- * check if we need to free the mbuf, and then return the error
- */
- NG_FREE_M(m);
- return (error);
-}
-
-/*
- * Do local shutdown processing..
- * We are a persistant device, we refuse to go away, and
- * only remove our links and reset ourself.
- */
-static int
-ng_udbp_rmnode(node_p node)
-{
- const udbp_p sc = NG_NODE_PRIVATE(node);
- int err;
-
- if (sc->flags & DISCONNECTED) {
- /*
- * WE are really going away.. hardware must have gone.
- * Assume that the hardware drive part will clear up the
- * sc, in fact it may already have done so..
- * In which case we may have just segfaulted..XXX
- */
- return (0);
- }
-
- /* stolen from attach routine */
- /* Drain the queues */
- IF_DRAIN(&sc->xmitq_hipri);
- IF_DRAIN(&sc->xmitq);
-
- sc->packets_in = 0; /* reset stats */
- sc->packets_out = 0;
- NG_NODE_UNREF(node); /* forget it ever existed */
-
- if ((err = ng_make_node_common(&ng_udbp_typestruct, &sc->node)) == 0) {
- char nodename[128];
- sprintf(nodename, "%s", device_get_nameunit(sc->sc_dev));
- if ((err = ng_name_node(sc->node, nodename))) {
- NG_NODE_UNREF(sc->node); /* out damned spot! */
- sc->flags &= ~NETGRAPH_INITIALISED;
- sc->node = NULL;
- } else {
- NG_NODE_SET_PRIVATE(sc->node, sc);
- }
- }
- return (err);
-}
-
-/*
- * This is called once we've already connected a new hook to the other node.
- * It gives us a chance to balk at the last minute.
- */
-static int
-ng_udbp_connect(hook_p hook)
-{
- /* probably not at splnet, force outward queueing */
- NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
- /* be really amiable and just say "YUP that's OK by me! " */
- return (0);
-}
-
-/*
- * Dook disconnection
- *
- * For this type, removal of the last link destroys the node
- */
-static int
-ng_udbp_disconnect(hook_p hook)
-{
- const udbp_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- sc->hook = NULL;
-
- if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
- && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))))
- ng_rmnode_self(NG_HOOK_NODE(hook));
- return (0);
-}
-
diff --git a/sys/legacy/dev/usb/udbp.h b/sys/legacy/dev/usb/udbp.h
deleted file mode 100644
index 97ef945..0000000
--- a/sys/legacy/dev/usb/udbp.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-
- * Copyright (c) 1996-2000 Whistle Communications, Inc.
- * All rights reserved.
- *
- * Subject to the following obligations and disclaimer of warranty, use and
- * redistribution of this software, in source or object code forms, with or
- * without modifications are expressly permitted by Whistle Communications;
- * provided, however, that:
- * 1. Any and all reproductions of the source or object code must include the
- * copyright notice above and the following disclaimer of warranties; and
- * 2. No rights are granted, in any manner or form, to use Whistle
- * Communications, Inc. trademarks, including the mark "WHISTLE
- * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
- * such appears in the above copyright notice or in the software.
- *
- * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
- * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
- * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
- * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
- * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
- * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
- * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
- * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
- * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file was derived from src/sys/netgraph/ng_sample.h, revision 1.1
- * written by Julian Elischer, Whistle Communications.
- *
- * $FreeBSD$
- */
-
-#ifndef _NETGRAPH_UDBP_H_
-#define _NETGRAPH_UDBP_H_
-
-/* Node type name. This should be unique among all netgraph node types */
-#define NG_UDBP_NODE_TYPE "udbp"
-
-/* Node type cookie. Should also be unique. This value MUST change whenever
- an incompatible change is made to this header file, to insure consistency.
- The de facto method for generating cookies is to take the output of the
- date command: date -u +'%s' */
-#define NGM_UDBP_COOKIE 944609300
-
-
-#define NG_UDBP_HOOK_NAME "data"
-
-/* Netgraph commands understood by this node type */
-enum {
- NGM_UDBP_SET_FLAG = 1,
- NGM_UDBP_GET_STATUS,
-};
-
-/* This structure is returned by the NGM_UDBP_GET_STATUS command */
-struct ngudbpstat {
- u_int packets_in; /* packets in from downstream */
- u_int packets_out; /* packets out towards downstream */
-};
-
-/*
- * This is used to define the 'parse type' for a struct ngudbpstat, which
- * is bascially a description of how to convert a binary struct ngudbpstat
- * to an ASCII string and back. See ng_parse.h for more info.
- *
- * This needs to be kept in sync with the above structure definition
- */
-#define NG_UDBP_STATS_TYPE_INFO { \
- { "packets_in", &ng_parse_int32_type }, \
- { "packets_out", &ng_parse_int32_type }, \
- { NULL }, \
-}
-
-#endif /* _NETGRAPH_UDBP_H_ */
diff --git a/sys/legacy/dev/usb/ufm.c b/sys/legacy/dev/usb/ufm.c
deleted file mode 100644
index 2635827..0000000
--- a/sys/legacy/dev/usb/ufm.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*-
- * Copyright (c) 2001-2007 M. Warner Losh
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This code is based on ugen.c and ulpt.c developed by Lennart Augustsson.
- * This code includes software developed by the NetBSD Foundation, Inc. and
- * its contributors.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/conf.h>
-#include <sys/uio.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include "usbdevs.h"
-#include <dev/usb/dsbr100io.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (ufmdebug) printf x
-#define DPRINTFN(n,x) if (ufmdebug>(n)) printf x
-int ufmdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ufm, CTLFLAG_RW, 0, "USB ufm");
-SYSCTL_INT(_hw_usb_ufm, OID_AUTO, debug, CTLFLAG_RW,
- &ufmdebug, 0, "ufm debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-d_open_t ufmopen;
-d_close_t ufmclose;
-d_ioctl_t ufmioctl;
-
-static struct cdevsw ufm_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = ufmopen,
- .d_close = ufmclose,
- .d_ioctl = ufmioctl,
- .d_name = "ufm",
-};
-
-#define FM_CMD0 0x00
-#define FM_CMD_SET_FREQ 0x01
-#define FM_CMD2 0x02
-
-struct ufm_softc {
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
-
- int sc_opened;
- int sc_epaddr;
- int sc_freq;
-
- int sc_refcnt;
-};
-
-#define UFMUNIT(n) (dev2unit(n))
-
-static device_probe_t ufm_match;
-static device_attach_t ufm_attach;
-static device_detach_t ufm_detach;
-
-static device_method_t ufm_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ufm_match),
- DEVMETHOD(device_attach, ufm_attach),
- DEVMETHOD(device_detach, ufm_detach),
-
- { 0, 0 }
-};
-
-static driver_t ufm_driver = {
- "ufm",
- ufm_methods,
- sizeof(struct ufm_softc)
-};
-
-static devclass_t ufm_devclass;
-
-static int
-ufm_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_device_descriptor_t *dd;
-
- DPRINTFN(10,("ufm_match\n"));
- if (!uaa->iface)
- return UMATCH_NONE;
-
- dd = usbd_get_device_descriptor(uaa->device);
-
- if (dd &&
- ((UGETW(dd->idVendor) == USB_VENDOR_CYPRESS &&
- UGETW(dd->idProduct) == USB_PRODUCT_CYPRESS_FMRADIO)))
- return UMATCH_VENDOR_PRODUCT;
- else
- return UMATCH_NONE;
-}
-
-static int
-ufm_attach(device_t self)
-{
- struct ufm_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_endpoint_descriptor_t *edesc;
- usbd_device_handle udev;
- usbd_interface_handle iface;
- u_int8_t epcount;
- usbd_status r;
- char * ermsg = "<none>";
-
- DPRINTFN(10,("ufm_attach: sc=%p\n", sc));
- sc->sc_dev = self;
- sc->sc_udev = udev = uaa->device;
-
- if ((!uaa->device) || (!uaa->iface)) {
- ermsg = "device or iface";
- goto nobulk;
- }
- sc->sc_iface = iface = uaa->iface;
- sc->sc_opened = 0;
- sc->sc_refcnt = 0;
-
- r = usbd_endpoint_count(iface, &epcount);
- if (r != USBD_NORMAL_COMPLETION) {
- ermsg = "endpoints";
- goto nobulk;
- }
-
- edesc = usbd_interface2endpoint_descriptor(iface, 0);
- if (!edesc) {
- ermsg = "interface endpoint";
- goto nobulk;
- }
- sc->sc_epaddr = edesc->bEndpointAddress;
-
- /* XXX no error trapping, no storing of struct cdev **/
- (void) make_dev(&ufm_cdevsw, device_get_unit(self),
- UID_ROOT, GID_OPERATOR,
- 0644, "ufm%d", device_get_unit(self));
- DPRINTFN(10, ("ufm_attach: %p\n", sc->sc_udev));
- return 0;
-
- nobulk:
- device_printf(sc->sc_dev, "could not find %s\n", ermsg);
- return ENXIO;
-}
-
-
-int
-ufmopen(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct ufm_softc *sc;
-
- int unit = UFMUNIT(dev);
- sc = devclass_get_softc(ufm_devclass, unit);
- if (sc == NULL)
- return (ENXIO);
-
- DPRINTFN(5, ("ufmopen: flag=%d, mode=%d, unit=%d\n",
- flag, mode, unit));
-
- if (sc->sc_opened)
- return (EBUSY);
-
- if ((flag & (FWRITE|FREAD)) != (FWRITE|FREAD))
- return (EACCES);
-
- sc->sc_opened = 1;
- return (0);
-}
-
-int
-ufmclose(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct ufm_softc *sc;
-
- int unit = UFMUNIT(dev);
- sc = devclass_get_softc(ufm_devclass, unit);
-
- DPRINTFN(5, ("ufmclose: flag=%d, mode=%d, unit=%d\n", flag, mode, unit));
- sc->sc_opened = 0;
- sc->sc_refcnt = 0;
- return 0;
-}
-
-static int
-ufm_do_req(struct ufm_softc *sc, u_int8_t reqtype, u_int8_t request,
- u_int16_t value, u_int16_t index, u_int8_t len, void *retbuf)
-{
- int s;
- usb_device_request_t req;
- usbd_status err;
-
- s = splusb();
- req.bmRequestType = reqtype;
- req.bRequest = request;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, len);
- err = usbd_do_request_flags(sc->sc_udev, &req, retbuf, 0, NULL,
- USBD_DEFAULT_TIMEOUT);
- splx(s);
- if (err)
- return (EIO);
- return (0);
-}
-
-static int
-ufm_set_freq(struct ufm_softc *sc, caddr_t addr)
-{
- int freq = *(int *)addr;
- u_int8_t ret;
-
- /*
- * Freq now is in Hz. We need to convert it to the frequency
- * that the radio wants. This frequency is 10.7MHz above
- * the actual frequency. We then need to convert to
- * units of 12.5kHz. We add one to the IFM to make rounding
- * easier.
- */
- sc->sc_freq = freq;
- freq = (freq + 10700001) / 12500;
- /* This appears to set the frequency */
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD_SET_FREQ, freq >> 8,
- freq, 1, &ret) != 0)
- return (EIO);
- /* Not sure what this does */
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD0, 0x96, 0xb7, 1,
- &ret) != 0)
- return (EIO);
- return (0);
-}
-
-static int
-ufm_get_freq(struct ufm_softc *sc, caddr_t addr)
-{
- int *valp = (int *)addr;
- *valp = sc->sc_freq;
- return (0);
-}
-
-static int
-ufm_start(struct ufm_softc *sc, caddr_t addr)
-{
- u_int8_t ret;
-
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD0, 0x00, 0xc7,
- 1, &ret))
- return (EIO);
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD2, 0x01, 0x00,
- 1, &ret))
- return (EIO);
- if (ret & 0x1)
- return (EIO);
- return (0);
-}
-
-static int
-ufm_stop(struct ufm_softc *sc, caddr_t addr)
-{
- u_int8_t ret;
-
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD0, 0x16, 0x1C,
- 1, &ret))
- return (EIO);
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD2, 0x00, 0x00,
- 1, &ret))
- return (EIO);
- return (0);
-}
-
-static int
-ufm_get_stat(struct ufm_softc *sc, caddr_t addr)
-{
- u_int8_t ret;
-
- /*
- * Note, there's a 240ms settle time before the status
- * will be valid, so tsleep that amount. hz/4 is a good
- * approximation of that. Since this is a short sleep
- * we don't try to catch any signals to keep things
- * simple.
- */
- tsleep(sc, 0, "ufmwait", hz/4);
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD0, 0x00, 0x24,
- 1, &ret))
- return (EIO);
- *(int *)addr = ret;
-
- return (0);
-}
-
-int
-ufmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
-{
- struct ufm_softc *sc;
-
- int unit = UFMUNIT(dev);
- int error = 0;
-
- sc = devclass_get_softc(ufm_devclass, unit);
-
- switch (cmd) {
- case FM_SET_FREQ:
- error = ufm_set_freq(sc, addr);
- break;
- case FM_GET_FREQ:
- error = ufm_get_freq(sc, addr);
- break;
- case FM_START:
- error = ufm_start(sc, addr);
- break;
- case FM_STOP:
- error = ufm_stop(sc, addr);
- break;
- case FM_GET_STAT:
- error = ufm_get_stat(sc, addr);
- break;
- default:
- return ENOTTY;
- break;
- }
- return error;
-}
-
-static int
-ufm_detach(device_t self)
-{
- return 0;
-}
-
-MODULE_DEPEND(ufm, usb, 1, 1, 1);
-DRIVER_MODULE(ufm, uhub, ufm_driver, ufm_devclass, usbd_driver_load, 0);
diff --git a/sys/legacy/dev/usb/ufoma.c b/sys/legacy/dev/usb/ufoma.c
deleted file mode 100644
index e5704a7..0000000
--- a/sys/legacy/dev/usb/ufoma.c
+++ /dev/null
@@ -1,1192 +0,0 @@
-/* $NetBSD: umodem.c,v 1.45 2002/09/23 05:51:23 simonb Exp $ */
-#define UFOMA_HANDSFREE
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2005, Takanori Watanabe
- * Copyright (c) 2003, M. Warner Losh <imp@freebsd.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Comm Class spec: http://www.usb.org/developers/devclass_docs/usbccs10.pdf
- * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf
- */
-
-/*
- * TODO:
- * - Add error recovery in various places; the big problem is what
- * to do in a callback if there is an error.
- * - Implement a Call Device for modems without multiplexed commands.
- *
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/ioccom.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/select.h>
-#include <sys/sysctl.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/sbuf.h>
-#include <sys/poll.h>
-#include <sys/uio.h>
-#include <sys/taskqueue.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-#include "usbdevs.h"
-
-typedef struct ufoma_mobile_acm_descriptor{
- uByte bFunctionLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bType;
- uByte bMode[1];
-}usb_mcpc_acm_descriptor;
-
-#define UISUBCLASS_MCPC 0x88
-
-#define UDESC_VS_INTERFACE 0x44
-#define UDESCSUB_MCPC_ACM 0x11
-
-#define UMCPC_ACM_TYPE_AB1 0x1
-#define UMCPC_ACM_TYPE_AB2 0x2
-#define UMCPC_ACM_TYPE_AB5 0x5
-#define UMCPC_ACM_TYPE_AB6 0x6
-
-#define UMCPC_ACM_MODE_DEACTIVATED 0x0
-#define UMCPC_ACM_MODE_MODEM 0x1
-#define UMCPC_ACM_MODE_ATCOMMAND 0x2
-#define UMCPC_ACM_MODE_OBEX 0x60
-#define UMCPC_ACM_MODE_VENDOR1 0xc0
-#define UMCPC_ACM_MODE_VENDOR2 0xfe
-#define UMCPC_ACM_MODE_UNLINKED 0xff
-
-#define UMCPC_CM_MOBILE_ACM 0x0
-
-#define UMCPC_ACTIVATE_MODE 0x60
-#define UMCPC_GET_MODETABLE 0x61
-#define UMCPC_SET_LINK 0x62
-#define UMCPC_CLEAR_LINK 0x63
-
-#define UMCPC_REQUEST_ACKNOLEDGE 0x31
-
-#define UFOMA_MAX_TIMEOUT 15 /*Standard says 10(sec)*/
-#define UFOMA_CMD_BUF_SIZE 64
-
-#define UMODEMIBUFSIZE 1024
-#define UMODEMOBUFSIZE 1024
-#define DPRINTF(a)
-
-struct ufoma_softc{
- struct ucom_softc sc_ucom;
- int sc_is_ucom;
- int sc_isopen;
-
- struct mtx sc_mtx;
- int sc_ctl_iface_no;
- usbd_interface_handle sc_ctl_iface;
- usbd_interface_handle sc_data_iface;
- int sc_data_iface_no;
- int sc_cm_cap;
- int sc_acm_cap;
- usb_cdc_line_state_t sc_line_state; /* current line state */
- usb_cdc_line_state_t sc_line_state_init; /* pre open line state*/
- u_char sc_dtr; /* current DTR state */
- u_char sc_rts; /* current RTS state */
-
- usbd_pipe_handle sc_notify_pipe;
- usb_cdc_notification_t sc_notify_buf;
- u_char sc_lsr;
- u_char sc_msr;
-
- struct task sc_task;
- uByte *sc_modetable;
- uByte sc_modetoactivate;
- uByte sc_currentmode;
- char sc_resbuffer[UFOMA_CMD_BUF_SIZE+1];
- int sc_cmdbp;
- int sc_nummsg;
- usbd_xfer_handle sc_msgxf;
-};
-static usbd_status
-ufoma_set_line_coding(struct ufoma_softc *sc, usb_cdc_line_state_t *state);
-static device_probe_t ufoma_match;
-static device_attach_t ufoma_attach;
-static device_detach_t ufoma_detach;
-static void *ufoma_get_intconf(usb_config_descriptor_t *cd, usb_interface_descriptor_t *id,int type, int subtype);
-static void ufoma_notify(void * ,int count);
-static void ufoma_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static char *ufoma_mode_to_str(int);
-static int ufoma_str_to_mode(char *);
-
-#ifdef UFOMA_HANDSFREE
-/*Pseudo ucom stuff(for Handsfree interface)*/
-static int ufoma_init_pseudo_ucom(struct ufoma_softc *);
-static tsw_open_t ufoma_open;
-static tsw_close_t ufoma_close;
-static tsw_outwakeup_t ufoma_outwakeup;
-static tsw_free_t ufoma_free;
-#endif
-
-/*umodem like stuff*/
-static int ufoma_init_modem(struct ufoma_softc *, struct usb_attach_arg *);
-static void ufoma_get_status(void *, int portno, u_char *lst, u_char *msr);
-static void ufoma_set(void *, int portno, int reg, int onoff);
-static int ufoma_param(void *, int portno, struct termios *);
-static int ufoma_ucom_open(void *, int portno);
-static void ufoma_ucom_close(void *, int portno);
-static void ufoma_break(struct ufoma_softc *sc, int onoff);
-static void ufoma_dtr(struct ufoma_softc *sc, int onoff);
-static void ufoma_rts(struct ufoma_softc *sc, int onoff);
-
-/*sysctl stuff*/
-static int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS);
-static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS);
-static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS);
-static void ufoma_set_line_state(struct ufoma_softc *sc);
-
-static struct ucom_callback ufoma_callback = {
- .ucom_get_status = ufoma_get_status,
- .ucom_set = ufoma_set,
- .ucom_param = ufoma_param,
- .ucom_open = ufoma_ucom_open,
- .ucom_close = ufoma_ucom_close,
-};
-
-
-static device_method_t ufoma_methods[] = {
- /**/
- DEVMETHOD(device_probe, ufoma_match),
- DEVMETHOD(device_attach, ufoma_attach),
- DEVMETHOD(device_detach, ufoma_detach),
- {0, 0}
-};
-struct umcpc_modetostr_tab{
- int mode;
- char *str;
-}umcpc_modetostr_tab[]={
- {UMCPC_ACM_MODE_DEACTIVATED, "deactivated"},
- {UMCPC_ACM_MODE_MODEM, "modem"},
- {UMCPC_ACM_MODE_ATCOMMAND, "handsfree"},
- {UMCPC_ACM_MODE_OBEX, "obex"},
- {UMCPC_ACM_MODE_VENDOR1, "vendor1"},
- {UMCPC_ACM_MODE_VENDOR2, "vendor2"},
- {UMCPC_ACM_MODE_UNLINKED, "unlinked"},
- {0, NULL}
-};
-
-static driver_t ufoma_driver = {
- "ucom",
- ufoma_methods,
- sizeof(struct ufoma_softc)
-};
-
-
-DRIVER_MODULE(ufoma, uhub, ufoma_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(ufoma, usb, 1, 1, 1);
-MODULE_DEPEND(ufoma, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-
-static int
-ufoma_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
- usb_config_descriptor_t *cd;
- usb_mcpc_acm_descriptor *mad;
- int ret;
-
- ret = UMATCH_NONE;
-
- if(uaa->iface == NULL)
- return(UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
- cd = usbd_get_config_descriptor(uaa->device);
-
- if(id == NULL || cd == NULL)
- return (UMATCH_NONE);
-
- if( id->bInterfaceClass == UICLASS_CDC &&
- id->bInterfaceSubClass == UISUBCLASS_MCPC){
- ret = (UMATCH_IFACECLASS_IFACESUBCLASS);
- }else{
- return UMATCH_NONE;
- }
-
- mad = ufoma_get_intconf(cd, id , UDESC_VS_INTERFACE, UDESCSUB_MCPC_ACM);
- if(mad == NULL){
- return (UMATCH_NONE);
- }
-
-#ifndef UFOMA_HANDSFREE
- if((mad->bType == UMCPC_ACM_TYPE_AB5)||
- (mad->bType == UMCPC_ACM_TYPE_AB6)){
- return UMATCH_NONE;
- }
-#endif
- return ret;
-}
-
-static int
-ufoma_attach(device_t self)
-{
- struct ufoma_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usb_config_descriptor_t *cd;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usb_mcpc_acm_descriptor *mad;
- struct ucom_softc *ucom = &sc->sc_ucom;
- const char *devname,*modename;
- int ctl_notify;
- int i,err;
- int elements;
- uByte *mode;
- struct sysctl_ctx_list *sctx;
- struct sysctl_oid *soid;
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- sc->sc_ctl_iface = uaa->iface;
- mtx_init(&sc->sc_mtx, "ufoma", NULL, MTX_DEF);
-
- cd = usbd_get_config_descriptor(ucom->sc_udev);
- id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
- sc->sc_ctl_iface_no = id->bInterfaceNumber;
-
- devname = device_get_nameunit(self);
- device_printf(self, "iclass %d/%d ifno:%d\n",
- id->bInterfaceClass, id->bInterfaceSubClass, sc->sc_ctl_iface_no);
-
- ctl_notify = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
- if (ed == NULL)
- continue;
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
- ctl_notify = ed->bEndpointAddress;
- }
- }
-
- if(ctl_notify== -1){
- /*NOTIFY is mandatory.*/
- printf("NOTIFY interface not found\n");
- goto error;
- }
-
- err = usbd_open_pipe_intr(sc->sc_ctl_iface, ctl_notify,
- USBD_SHORT_XFER_OK, &sc->sc_notify_pipe, sc, &sc->sc_notify_buf,
- sizeof(sc->sc_notify_buf), ufoma_intr, USBD_DEFAULT_INTERVAL);
- if(err){
- printf("PIPE open error %d\n", err);
- goto error;
- }
- mad = ufoma_get_intconf(cd, id , UDESC_VS_INTERFACE, UDESCSUB_MCPC_ACM);
- if(mad ==NULL){
- goto error;
- }
-
- printf("%s:Supported Mode:", devname);
- for(mode = mad->bMode;
- mode < ((uByte *)mad + mad->bFunctionLength); mode++){
- modename = ufoma_mode_to_str(*mode);
- if(modename){
- printf("%s", ufoma_mode_to_str(*mode));
- }else{
- printf("(%x)", *mode);
- }
- if(mode != ((uByte*)mad + mad->bFunctionLength-1)){
- printf(",");
- }
- }
- printf("\n");
- if((mad->bType == UMCPC_ACM_TYPE_AB5)
- ||(mad->bType == UMCPC_ACM_TYPE_AB6)){
-#ifdef UFOMA_HANDSFREE
- /*These does not have data interface*/
- sc->sc_is_ucom = 0;
- ufoma_init_pseudo_ucom(sc);
-#else
- /*Should not happen*/
- goto error;
-#endif
-
- }else{
- if(ufoma_init_modem(sc, uaa)){
- goto error;
- }
- }
- elements = mad->bFunctionLength - sizeof(*mad)+1;
- sc->sc_msgxf = usbd_alloc_xfer(ucom->sc_udev);
- sc->sc_nummsg = 0;
-
- /*Initialize Mode vars.*/
- sc->sc_modetable = malloc(elements + 1, M_USBDEV, M_WAITOK);
- sc->sc_modetable[0] = elements + 1;
- bcopy(mad->bMode, &sc->sc_modetable[1], elements);
- sc->sc_currentmode = UMCPC_ACM_MODE_UNLINKED;
- sc->sc_modetoactivate = mad->bMode[0];
-
- /*Sysctls*/
- sctx = device_get_sysctl_ctx(self);
- soid = device_get_sysctl_tree(self);
-
- SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "supportmode",
- CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_support,
- "A", "Supporting port role");
-
- SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "currentmode",
- CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_current,
- "A", "Current port role");
-
- SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "openmode",
- CTLFLAG_RW|CTLTYPE_STRING, sc, 0, ufoma_sysctl_open,
- "A", "Mode to transit when port is opened");
-
- return 0;
- error:
- if(sc->sc_modetable)
- free(sc->sc_modetable, M_USBDEV);
- return EIO;
-}
-
-static int
-ufoma_detach(device_t self)
-{
- struct ufoma_softc *sc = device_get_softc(self);
- int rv = 0;
-
- usbd_free_xfer(sc->sc_msgxf);
- sc->sc_ucom.sc_dying = 1;
- usbd_abort_pipe(sc->sc_notify_pipe);
- usbd_close_pipe(sc->sc_notify_pipe);
- if(sc->sc_is_ucom){
- ucom_detach(&sc->sc_ucom);
- }
-#ifdef UFOMA_HANDSFREE
- else{
- tty_lock(sc->sc_ucom.sc_tty);
- tty_rel_gone(sc->sc_ucom.sc_tty);
- }
-
-#endif
- free(sc->sc_modetable, M_USBDEV);
- return rv;
-}
-
-
-static char *ufoma_mode_to_str(int mode)
-{
- int i;
- for(i = 0 ;umcpc_modetostr_tab[i].str != NULL; i++){
- if(umcpc_modetostr_tab[i].mode == mode){
- return umcpc_modetostr_tab[i].str;
- }
- }
- return NULL;
-}
-
-static int ufoma_str_to_mode(char *str)
-{
- int i;
- for(i = 0 ;umcpc_modetostr_tab[i].str != NULL; i++){
- if(strcmp(str, umcpc_modetostr_tab[i].str)==0){
- return umcpc_modetostr_tab[i].mode;
- }
- }
- return -1;
-}
-
-static void *ufoma_get_intconf( usb_config_descriptor_t *cd,
- usb_interface_descriptor_t *id, int type, int subtype)
-{
- uByte *p, *end;
- usb_descriptor_t *ud=NULL;
- int flag=0;
-
-
- for(p = (uByte *)cd,end = p + UGETW(cd->wTotalLength); p < end;
- p += ud->bLength){
- ud = (usb_descriptor_t *)p;
- if(flag && ud->bDescriptorType==UDESC_INTERFACE){
- return NULL;
- }
- /*Read through this interface desc.*/
- if(bcmp(p, id, sizeof(*id))==0){
- flag=1;
- continue;
- }
- if(flag==0)
- continue;
- if(ud->bDescriptorType == type
- && ud->bDescriptorSubtype == subtype){
- break;
- }
- }
- return ud;
-}
-
-
-
-static int ufoma_link_state(struct ufoma_softc *sc)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- int err;
-
- req.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
- req.bRequest = UMCPC_SET_LINK;
- USETW(req.wValue, UMCPC_CM_MOBILE_ACM);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, sc->sc_modetable[0]);
-
- err = usbd_do_request(ucom->sc_udev, &req, sc->sc_modetable);
- if(err){
- printf("SET_LINK:%s\n",usbd_errstr(err));
- return EIO;
- }
- err = tsleep(&sc->sc_currentmode, PZERO|PCATCH, "fmalnk", hz);
- if(err){
- printf("NO response");
- return EIO;
- }
- if(sc->sc_currentmode != UMCPC_ACM_MODE_DEACTIVATED){
- return EIO;
- }
- return 0;
-}
-
-static int ufoma_activate_state(struct ufoma_softc *sc, int state)
-{
- usb_device_request_t req;
- int err;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- req.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
- req.bRequest = UMCPC_ACTIVATE_MODE;
- USETW(req.wValue, state);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if(err){
- printf("%s:ACTIVATE(%x):%s\n",
- device_get_nameunit(ucom->sc_dev), state,
- usbd_errstr(err));
- return EIO;
- }
-
- err = tsleep(&sc->sc_currentmode, PZERO|PCATCH, "fmaact", UFOMA_MAX_TIMEOUT*hz);
- if(err){
- printf("%s:NO response", device_get_nameunit(ucom->sc_dev));
- return EIO;
- }
- if(sc->sc_currentmode != state){
- return EIO;
- }
- return 0;
-}
-
-#ifdef UFOMA_HANDSFREE
-static inline void ufoma_setup_msg_req(struct ufoma_softc *sc, usb_device_request_t *req)
-{
- req->bmRequestType = UT_READ_CLASS_INTERFACE;
- req->bRequest = UCDC_GET_ENCAPSULATED_RESPONSE;
- USETW(req->wIndex, sc->sc_ctl_iface_no);
- USETW(req->wValue, 0);
- USETW(req->wLength, UFOMA_CMD_BUF_SIZE);
-}
-
-
-static void ufoma_msg(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- usb_device_request_t req;
- struct ufoma_softc *sc = priv;
- int actlen,i;
- struct ucom_softc *ucom= &sc->sc_ucom;
- usbd_get_xfer_status(xfer, NULL, NULL, &actlen ,NULL);
- ufoma_setup_msg_req(sc, &req);
- mtx_lock(&sc->sc_mtx);
- for(i = 0;i < actlen; i++){
-
- if(ttydisc_rint(sc->sc_ucom.sc_tty, sc->sc_resbuffer[i], 0)
- == -1){
- break;
- }
- }
-
- ttydisc_rint_done(sc->sc_ucom.sc_tty);
-
- sc->sc_nummsg--;
- if(sc->sc_nummsg){
- usbd_setup_default_xfer(sc->sc_msgxf, ucom->sc_udev,
- priv, USBD_DEFAULT_TIMEOUT, &req,
- sc->sc_resbuffer,
- UFOMA_CMD_BUF_SIZE,
- 0, ufoma_msg);
- usbd_transfer(sc->sc_msgxf);
- }
- mtx_unlock(&sc->sc_mtx);
-
-}
-#endif
-static void ufoma_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ufoma_softc *sc = priv;
- unsigned int a;
- struct ucom_softc *ucom =&sc->sc_ucom;
- u_char mstatus;
-
-#ifdef UFOMA_HANDSFREE
- usb_device_request_t req;
-
- ufoma_setup_msg_req(sc, &req);
-#endif
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
- printf("%s: abnormal status: %s\n", device_get_nameunit(ucom->sc_dev),
- usbd_errstr(status));
- return;
- }
- if((sc->sc_notify_buf.bmRequestType == UT_READ_VENDOR_INTERFACE)&&
- (sc->sc_notify_buf.bNotification == UMCPC_REQUEST_ACKNOLEDGE)){
- a = UGETW(sc->sc_notify_buf.wValue);
- sc->sc_currentmode = a>>8;
- if(!(a&0xff)){
- printf("%s:Mode change Failed\n", device_get_nameunit(ucom->sc_dev));
- }
- wakeup(&sc->sc_currentmode);
- }
- if(sc->sc_notify_buf.bmRequestType != UCDC_NOTIFICATION){
- return;
- }
- switch(sc->sc_notify_buf.bNotification){
-#ifdef UFOMA_HANDSFREE
- case UCDC_N_RESPONSE_AVAILABLE:
- if(sc->sc_is_ucom){
- printf("%s:wrong response request?\n", device_get_nameunit(ucom->sc_dev));
- break;
- }
- mtx_lock(&sc->sc_mtx);
- if(!sc->sc_nummsg){
- usbd_setup_default_xfer(sc->sc_msgxf, ucom->sc_udev,
- priv, USBD_DEFAULT_TIMEOUT, &req, sc->sc_resbuffer,
- UFOMA_CMD_BUF_SIZE,
- 0, ufoma_msg);
- usbd_transfer(sc->sc_msgxf);
- }
- sc->sc_nummsg++;
- mtx_unlock(&sc->sc_mtx);
- break;
-#endif
- case UCDC_N_SERIAL_STATE:
- if(!sc->sc_is_ucom){
- printf("%s:wrong sereal request?\n",device_get_nameunit(ucom->sc_dev));
- break;
- }
-
- /*
- * Set the serial state in ucom driver based on
- * the bits from the notify message
- */
- if (UGETW(sc->sc_notify_buf.wLength) != 2) {
- printf("%s: Invalid notification length! (%d)\n",
- device_get_nameunit(ucom->sc_dev),
- UGETW(sc->sc_notify_buf.wLength));
- break;
- }
- DPRINTF(("%s: notify bytes = %02x%02x\n",
- device_get_nameunit(ucom->sc_dev),
- sc->sc_notify_buf.data[0],
- sc->sc_notify_buf.data[1]));
- /* Currently, lsr is always zero. */
- sc->sc_lsr = sc->sc_msr = 0;
- mstatus = sc->sc_notify_buf.data[0];
-
- if (ISSET(mstatus, UCDC_N_SERIAL_RI))
- sc->sc_msr |= SER_RI;
- if (ISSET(mstatus, UCDC_N_SERIAL_DSR))
- sc->sc_msr |= SER_DSR;
- if (ISSET(mstatus, UCDC_N_SERIAL_DCD))
- sc->sc_msr |= SER_DCD;
- /* Deferred notifying to the ucom layer */
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
- break;
- default:
- break;
- }
-}
-
-#ifdef UFOMA_HANDSFREE
-struct ttydevsw ufomatty_class ={
- .tsw_flags = TF_INITLOCK|TF_CALLOUT,
- .tsw_open = ufoma_open,
- .tsw_close = ufoma_close,
- .tsw_outwakeup = ufoma_outwakeup,
- .tsw_free = ufoma_free
-};
-static void ufoma_free(void *sc)
-{
-
-}
-static int ufoma_init_pseudo_ucom(struct ufoma_softc *sc)
-{
- struct tty *tp;
- struct ucom_softc *ucom = &sc->sc_ucom;
- tp = ucom->sc_tty = tty_alloc(&ufomatty_class, sc, &Giant);
- tty_makedev(tp, NULL, "U%d", device_get_unit(ucom->sc_dev));
-
- return 0;
-}
-
-
-static int ufoma_open(struct tty * tty)
-{
-
- struct ufoma_softc *sc = tty_softc(tty);
-
- if(sc->sc_ucom.sc_dying)
- return (ENXIO);
-
- mtx_lock(&sc->sc_mtx);
- if(sc->sc_isopen){
- mtx_unlock(&sc->sc_mtx);
- return EBUSY;
- }
- mtx_unlock(&sc->sc_mtx);
-
- return ufoma_ucom_open(sc, 0);
-}
-
-static void ufoma_close(struct tty *tty)
-{
- struct ufoma_softc *sc = tty_softc(tty);
-
- ufoma_ucom_close(sc, 0);
-}
-
-static void ufoma_outwakeup(struct tty *tp)
-{
- struct ufoma_softc *sc = tty_softc(tp);
- struct ucom_softc *ucom = &sc->sc_ucom;
- usb_device_request_t req;
- int len,i;
- unsigned char buf[128];
-
- uByte c;
- if(ucom->sc_dying)
- return;
- if(ucom->sc_state &UCS_TXBUSY)
- return;
-
- ucom->sc_state |= UCS_TXBUSY;
- for(;;){
- len = ttydisc_getc(tp, buf, sizeof(buf));
- if(len == 0){
- break;
- }
-
- for(i=0; i < len; i++){
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- c = buf[i];
- req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND;
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wValue, 0);
- USETW(req.wLength, 1);
- usbd_do_request(ucom->sc_udev, &req, &c);
- }
- }
- ucom->sc_state &= ~(UCS_TXBUSY);
-
-}
-#endif
-
-
-static int ufoma_ucom_open(void *p, int portno)
-{
- struct ufoma_softc *sc = p;
- int res;
-
- if(sc->sc_currentmode == UMCPC_ACM_MODE_UNLINKED){
- if((res = ufoma_link_state(sc))){
- return res;
- }
- }
-
- sc->sc_cmdbp = 0;
- if(sc->sc_currentmode == UMCPC_ACM_MODE_DEACTIVATED){
- if((res = ufoma_activate_state(sc, sc->sc_modetoactivate))){
- return res;
- }
- }
- mtx_lock(&sc->sc_mtx);
- sc->sc_isopen = 1;
- mtx_unlock(&sc->sc_mtx);
- /*Now line coding should be set.*/
- if(sc->sc_is_ucom){
- ufoma_set_line_state(sc);
- ufoma_set_line_coding(sc, NULL);
- }
- return 0;
-}
-
-static void ufoma_ucom_close(void *p, int portno)
-{
- struct ufoma_softc *sc = p;
- ufoma_activate_state(sc, UMCPC_ACM_MODE_DEACTIVATED);
- mtx_lock(&sc->sc_mtx);
- sc->sc_isopen = 0;
- mtx_unlock(&sc->sc_mtx);
- return ;
-}
-
-void
-ufoma_break(struct ufoma_softc *sc, int onoff)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- DPRINTF(("ufoma_break: onoff=%d\n", onoff));
-
- if (!(sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK))
- return;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
- USETW(req.wValue, onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, 0);
-
- (void)usbd_do_request(ucom->sc_udev, &req, 0);
-}
-
-void
-ufoma_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct ufoma_softc *sc = addr;
-
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-}
-
-static void ufoma_set(void * addr, int portno, int reg, int onoff)
-{
- struct ufoma_softc *sc = addr;
-
- switch (reg) {
- case UCOM_SET_DTR:
- ufoma_dtr(sc, onoff);
- break;
- case UCOM_SET_RTS:
- ufoma_rts(sc, onoff);
- break;
- case UCOM_SET_BREAK:
- ufoma_break(sc, onoff);
- break;
- default:
- break;
- }
-
-}
-
-static void
-ufoma_set_line_state(struct ufoma_softc *sc)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- int ls;
- int err;
-
- if(!sc->sc_isopen){
- return ; /*Set it later*/
- }
-
- /*Don't send line state emulation request for OBEX port*/
- if(sc->sc_currentmode == UMCPC_ACM_MODE_OBEX){
- return;
- }
-
- ls = (sc->sc_dtr ? UCDC_LINE_DTR : 0) |
- (sc->sc_rts ? UCDC_LINE_RTS : 0);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, ls);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(ucom->sc_udev, &req, 0);
- if(err){
- printf("LINE_STATE:%s\n", usbd_errstr(err));
- }
-
-
-}
-
-void
-ufoma_dtr(struct ufoma_softc *sc, int onoff)
-{
- DPRINTF(("ufoma_foma: onoff=%d\n", onoff));
-
- if (sc->sc_dtr == onoff)
- return;
- sc->sc_dtr = onoff;
-
- ufoma_set_line_state(sc);
-}
-
-void
-ufoma_rts(struct ufoma_softc *sc, int onoff)
-{
- DPRINTF(("ufoma_foma: onoff=%d\n", onoff));
-
- if (sc->sc_rts == onoff)
- return;
- sc->sc_rts = onoff;
-
- ufoma_set_line_state(sc);
-}
-
-usbd_status
-ufoma_set_line_coding(struct ufoma_softc *sc, usb_cdc_line_state_t *state)
-{
-
- usbd_status err;
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- if(!sc->sc_isopen){
- sc->sc_line_state_init = *state;
- return (USBD_NORMAL_COMPLETION);
- }
-
- DPRINTF(("ufoma_set_line_coding: rate=%d fmt=%d parity=%d bits=%d\n",
- UGETDW(state->dwDTERate), state->bCharFormat,
- state->bParityType, state->bDataBits));
- if(state == NULL){
- state = &sc->sc_line_state_init;
- }else if (memcmp(state, &sc->sc_line_state,
- UCDC_LINE_STATE_LENGTH) == 0) {
- DPRINTF(("ufoma_set_line_coding: already set\n"));
- return (USBD_NORMAL_COMPLETION);
- }
-
- /*Don't send line state emulation request for OBEX port*/
- if(sc->sc_currentmode == UMCPC_ACM_MODE_OBEX){
- sc->sc_line_state = *state;
- return (USBD_NORMAL_COMPLETION);
- }
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_LINE_CODING;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, UCDC_LINE_STATE_LENGTH);
-
- err = usbd_do_request(ucom->sc_udev, &req, state);
- if (err) {
- DPRINTF(("ufoma_set_line_coding: failed, err=%s\n",
- usbd_errstr(err)));
- return (err);
- }
-
- sc->sc_line_state = *state;
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static int
-ufoma_param(void *addr, int portno, struct termios *t)
-{
-
- struct ufoma_softc *sc = addr;
- usbd_status err;
- usb_cdc_line_state_t ls;
-
- DPRINTF(("ufoma_param: sc=%p\n", sc));
-
- USETDW(ls.dwDTERate, t->c_ospeed);
- if (ISSET(t->c_cflag, CSTOPB))
- ls.bCharFormat = UCDC_STOP_BIT_2;
- else
- ls.bCharFormat = UCDC_STOP_BIT_1;
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- ls.bParityType = UCDC_PARITY_ODD;
- else
- ls.bParityType = UCDC_PARITY_EVEN;
- } else
- ls.bParityType = UCDC_PARITY_NONE;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- ls.bDataBits = 5;
- break;
- case CS6:
- ls.bDataBits = 6;
- break;
- case CS7:
- ls.bDataBits = 7;
- break;
- case CS8:
- ls.bDataBits = 8;
- break;
- }
-
- err = ufoma_set_line_coding(sc, &ls);
- if (err) {
- DPRINTF(("ufoma_param: err=%s\n", usbd_errstr(err)));
- return (EIO);
- }
-
- return (0);
-}
-
-static int ufoma_init_modem(struct ufoma_softc *sc,struct usb_attach_arg *uaa)
-{
- struct ucom_softc *ucom = &sc->sc_ucom;
- usb_config_descriptor_t *cd;
- usb_cdc_acm_descriptor_t *acm;
- usb_cdc_cm_descriptor_t *cmd;
- usb_endpoint_descriptor_t *ed;
- usb_interface_descriptor_t *id;
- const char *devname = device_get_nameunit(ucom->sc_dev);
- int i;
- cd = usbd_get_config_descriptor(ucom->sc_udev);
- id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
-
- sc->sc_is_ucom = 1;
-
- cmd = ufoma_get_intconf(cd, id, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
- if(cmd == NULL)
- return -1;
- sc->sc_cm_cap = cmd->bmCapabilities;
-
- acm = ufoma_get_intconf(cd, id, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM);
- if(acm == NULL)
- return -1;
- sc->sc_acm_cap = acm->bmCapabilities;
-
- sc->sc_data_iface_no = cmd->bDataInterface;
- printf("%s: data interface %d, has %sCM over data, has %sbreak\n",
- devname, sc->sc_data_iface_no,
- sc->sc_cm_cap & USB_CDC_CM_OVER_DATA ? "" : "no ",
- sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK ? "" : "no ");
-
- for(i = 0; i < uaa->nifaces; i++){
- if(!uaa->ifaces[i])
- continue;
- id = usbd_get_interface_descriptor(uaa->ifaces[i]);
- if(id != NULL &&
- id->bInterfaceNumber == sc->sc_data_iface_no){
- sc->sc_data_iface = uaa->ifaces[i];
- //uaa->ifaces[i] = NULL;
- }
- }
-
- ucom->sc_iface = sc->sc_data_iface;
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- id = usbd_get_interface_descriptor(sc->sc_data_iface);
- for(i = 0 ; i < id->bNumEndpoints; i++){
- ed = usbd_interface2endpoint_descriptor(sc->sc_data_iface, i);
- if(ed == NULL){
- printf("%s: endpoint descriptor for %d\n",
- devname,i);
- return -1;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
- }
-
- if (ucom->sc_bulkin_no == -1) {
- printf("%s: Could not find data bulk in\n", devname);
- return -1;
- }
- if (ucom->sc_bulkout_no == -1) {
- printf("%s: Could not find data bulk out\n", devname);
- return -1;
- }
-
- sc->sc_dtr = -1;
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = UMODEMIBUFSIZE;
- ucom->sc_obufsize = UMODEMOBUFSIZE;
- ucom->sc_ibufsizepad = UMODEMIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &ufoma_callback;
- TASK_INIT(&sc->sc_task, 0, ufoma_notify, sc);
- ucom_attach(&sc->sc_ucom);
-
- return 0;
-}
-
-static void
-ufoma_notify(void *arg, int count)
-{
- struct ufoma_softc *sc;
-
- sc = (struct ufoma_softc *)arg;
- if (sc->sc_ucom.sc_dying)
- return;
- ucom_status_change(&sc->sc_ucom);
-}
-static int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS)
-{
- struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
- struct sbuf sb;
- int i;
- char *mode;
-
- sbuf_new(&sb, NULL, 1, SBUF_AUTOEXTEND);
- for(i = 1; i < sc->sc_modetable[0]; i++){
- mode = ufoma_mode_to_str(sc->sc_modetable[i]);
- if(mode !=NULL){
- sbuf_cat(&sb, mode);
- }else{
- sbuf_printf(&sb, "(%02x)", sc->sc_modetable[i]);
- }
- if(i < (sc->sc_modetable[0]-1))
- sbuf_cat(&sb, ",");
- }
- sbuf_trim(&sb);
- sbuf_finish(&sb);
- sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req);
- sbuf_delete(&sb);
-
- return 0;
-}
-static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS)
-{
- struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
- char *mode;
- char subbuf[]="(XXX)";
- mode = ufoma_mode_to_str(sc->sc_currentmode);
- if(!mode){
- mode = subbuf;
- snprintf(subbuf, sizeof(subbuf), "(%02x)", sc->sc_currentmode);
- }
- sysctl_handle_string(oidp, mode, strlen(mode), req);
-
- return 0;
-
-}
-static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS)
-{
- struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
- char *mode;
- char subbuf[40];
- int newmode;
- int error;
- int i;
-
- mode = ufoma_mode_to_str(sc->sc_modetoactivate);
- if(mode){
- strncpy(subbuf, mode, sizeof(subbuf));
- }else{
- snprintf(subbuf, sizeof(subbuf), "(%02x)", sc->sc_modetoactivate);
- }
- error = sysctl_handle_string(oidp, subbuf, sizeof(subbuf), req);
- if(error != 0 || req->newptr == NULL){
- return error;
- }
-
- if((newmode = ufoma_str_to_mode(subbuf)) == -1){
- return EINVAL;
- }
-
- for(i = 1 ; i < sc->sc_modetable[0] ; i++){
- if(sc->sc_modetable[i] == newmode){
- sc->sc_modetoactivate = newmode;
- return 0;
- }
- }
-
- return EINVAL;
-}
diff --git a/sys/legacy/dev/usb/uftdi.c b/sys/legacy/dev/usb/uftdi.c
deleted file mode 100644
index c652977..0000000
--- a/sys/legacy/dev/usb/uftdi.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/* $NetBSD: uftdi.c,v 1.13 2002/09/23 05:51:23 simonb Exp $ */
-
-/*-
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * FTDI FT8U100AX serial adapter driver
- */
-
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-
-#include <sys/selinfo.h>
-
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/ucomvar.h>
-
-#include <dev/usb/uftdireg.h>
-
-#ifdef USB_DEBUG
-static int uftdidebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uftdi, CTLFLAG_RW, 0, "USB uftdi");
-SYSCTL_INT(_hw_usb_uftdi, OID_AUTO, debug, CTLFLAG_RW,
- &uftdidebug, 0, "uftdi debug level");
-#define DPRINTF(x) do { \
- if (uftdidebug) \
- printf x; \
- } while (0)
-
-#define DPRINTFN(n, x) do { \
- if (uftdidebug > (n)) \
- printf x; \
- } while (0)
-
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UFTDI_CONFIG_INDEX 0
-#define UFTDI_IFACE_INDEX 0
-
-
-/*
- * These are the maximum number of bytes transferred per frame.
- * The output buffer size cannot be increased due to the size encoding.
- */
-#define UFTDIIBUFSIZE 256
-#define UFTDIOBUFSIZE 64
-
-struct uftdi_softc {
- struct ucom_softc sc_ucom;
- usbd_interface_handle sc_iface; /* interface */
- enum uftdi_type sc_type;
- u_int sc_hdrlen;
- u_char sc_msr;
- u_char sc_lsr;
- u_int last_lcr;
-};
-
-static void uftdi_get_status(void *, int portno, u_char *lsr, u_char *msr);
-static void uftdi_set(void *, int, int, int);
-static int uftdi_param(void *, int, struct termios *);
-static int uftdi_open(void *sc, int portno);
-static void uftdi_read(void *sc, int portno, u_char **ptr,u_int32_t *count);
-static size_t uftdi_write(void *sc, int portno, struct tty *,
- u_char *to, u_int32_t count);
-static void uftdi_break(void *sc, int portno, int onoff);
-static int uftdi_8u232am_getrate(speed_t speed, int *rate);
-
-struct ucom_callback uftdi_callback = {
- uftdi_get_status,
- uftdi_set,
- uftdi_param,
- NULL,
- uftdi_open,
- NULL,
- uftdi_read,
- uftdi_write,
-};
-
-static int
-uftdi_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL) {
- if (uaa->vendor == USB_VENDOR_FTDI &&
- (uaa->product == USB_PRODUCT_FTDI_SERIAL_2232C))
- return (UMATCH_VENDOR_IFACESUBCLASS);
- return (UMATCH_NONE);
- }
-
- DPRINTFN(20,("uftdi: vendor=0x%x, product=0x%x\n",
- uaa->vendor, uaa->product));
-
- if (uaa->vendor == USB_VENDOR_FTDI &&
- (uaa->product == USB_PRODUCT_FTDI_SERIAL_8U100AX ||
- uaa->product == USB_PRODUCT_FTDI_SERIAL_8U232AM ||
- uaa->product == USB_PRODUCT_FTDI_SEMC_DSS20 ||
- uaa->product == USB_PRODUCT_FTDI_CFA_631 ||
- uaa->product == USB_PRODUCT_FTDI_CFA_632 ||
- uaa->product == USB_PRODUCT_FTDI_CFA_633 ||
- uaa->product == USB_PRODUCT_FTDI_CFA_634 ||
- uaa->product == USB_PRODUCT_FTDI_CFA_635 ||
- uaa->product == USB_PRODUCT_FTDI_USBSERIAL ||
- uaa->product == USB_PRODUCT_FTDI_MX2_3 ||
- uaa->product == USB_PRODUCT_FTDI_MX4_5 ||
- uaa->product == USB_PRODUCT_FTDI_LK202 ||
- uaa->product == USB_PRODUCT_FTDI_LK204 ||
- uaa->product == USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13M ||
- uaa->product == USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13S ||
- uaa->product == USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13U ||
- uaa->product == USB_PRODUCT_FTDI_EISCOU ||
- uaa->product == USB_PRODUCT_FTDI_UOPTBR ||
- uaa->product == USB_PRODUCT_FTDI_EMCU2D ||
- uaa->product == USB_PRODUCT_FTDI_PCMSFU ||
- uaa->product == USB_PRODUCT_FTDI_EMCU2H ||
- uaa->product == USB_PRODUCT_FTDI_MAXSTREAM ))
- return (UMATCH_VENDOR_PRODUCT);
- if (uaa->vendor == USB_VENDOR_SIIG2 &&
- (uaa->product == USB_PRODUCT_SIIG2_US2308))
- return (UMATCH_VENDOR_PRODUCT);
- if (uaa->vendor == USB_VENDOR_INTREPIDCS &&
- (uaa->product == USB_PRODUCT_INTREPIDCS_VALUECAN ||
- uaa->product == USB_PRODUCT_INTREPIDCS_NEOVI))
- return (UMATCH_VENDOR_PRODUCT);
- if (uaa->vendor == USB_VENDOR_BBELECTRONICS &&
- (uaa->product == USB_PRODUCT_BBELECTRONICS_USOTL4))
- return (UMATCH_VENDOR_PRODUCT);
- if (uaa->vendor == USB_VENDOR_MELCO &&
- (uaa->product == USB_PRODUCT_MELCO_PCOPRS1))
- return (UMATCH_VENDOR_PRODUCT);
- if (uaa->vendor == USB_VENDOR_DRESDENELEKTRONIK &&
- (uaa->product == USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD))
- return (UMATCH_VENDOR_PRODUCT);
-
- return (UMATCH_NONE);
-}
-
-static int
-uftdi_attach(device_t self)
-{
- struct uftdi_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_interface_handle iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
- DPRINTFN(10,("\nuftdi_attach: sc=%p\n", sc));
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
-
- if (uaa->iface == NULL) {
- /* Move the device into the configured state. */
- err = usbd_set_config_index(dev, UFTDI_CONFIG_INDEX, 1);
- if (err) {
- device_printf(ucom->sc_dev,
- "failed to set configuration, err=%s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- err = usbd_device2interface_handle(dev, UFTDI_IFACE_INDEX, &iface);
- if (err) {
- device_printf(ucom->sc_dev,
- "failed to get interface, err=%s\n", usbd_errstr(err));
- goto bad;
- }
- } else {
- iface = uaa->iface;
- }
-
- id = usbd_get_interface_descriptor(iface);
- ucom->sc_iface = iface;
- switch( uaa->vendor ){
- case USB_VENDOR_FTDI:
- switch( uaa->product ){
- case USB_PRODUCT_FTDI_SERIAL_8U100AX:
- sc->sc_type = UFTDI_TYPE_SIO;
- sc->sc_hdrlen = 1;
- break;
- case USB_PRODUCT_FTDI_SEMC_DSS20:
- case USB_PRODUCT_FTDI_SERIAL_8U232AM:
- case USB_PRODUCT_FTDI_SERIAL_2232C:
- case USB_PRODUCT_FTDI_CFA_631:
- case USB_PRODUCT_FTDI_CFA_632:
- case USB_PRODUCT_FTDI_CFA_633:
- case USB_PRODUCT_FTDI_CFA_634:
- case USB_PRODUCT_FTDI_CFA_635:
- case USB_PRODUCT_FTDI_USBSERIAL:
- case USB_PRODUCT_FTDI_MX2_3:
- case USB_PRODUCT_FTDI_MX4_5:
- case USB_PRODUCT_FTDI_LK202:
- case USB_PRODUCT_FTDI_LK204:
- case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13M:
- case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13S:
- case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13U:
- case USB_PRODUCT_FTDI_EISCOU:
- case USB_PRODUCT_FTDI_UOPTBR:
- case USB_PRODUCT_FTDI_EMCU2D:
- case USB_PRODUCT_FTDI_PCMSFU:
- case USB_PRODUCT_FTDI_EMCU2H:
- case USB_PRODUCT_FTDI_MAXSTREAM:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- case USB_VENDOR_INTREPIDCS:
- switch( uaa->product ){
- case USB_PRODUCT_INTREPIDCS_VALUECAN:
- case USB_PRODUCT_INTREPIDCS_NEOVI:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- case USB_VENDOR_SIIG2:
- switch( uaa->product ){
- case USB_PRODUCT_SIIG2_US2308:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- case USB_VENDOR_BBELECTRONICS:
- switch( uaa->product ){
- case USB_PRODUCT_BBELECTRONICS_USOTL4:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- case USB_VENDOR_MELCO:
- switch( uaa->product ){
- case USB_PRODUCT_MELCO_PCOPRS1:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- case USB_VENDOR_DRESDENELEKTRONIK:
- switch( uaa->product ){
- case USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- default: /* Can't happen */
- goto bad;
- }
-
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- int addr, dir, attr;
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- device_printf(ucom->sc_dev,
- "could not read endpoint descriptor\n");
- goto bad;
- }
-
- addr = ed->bEndpointAddress;
- dir = UE_GET_DIR(ed->bEndpointAddress);
- attr = ed->bmAttributes & UE_XFERTYPE;
- if (dir == UE_DIR_IN && attr == UE_BULK)
- ucom->sc_bulkin_no = addr;
- else if (dir == UE_DIR_OUT && attr == UE_BULK)
- ucom->sc_bulkout_no = addr;
- else {
- device_printf(ucom->sc_dev, "unexpected endpoint\n");
- goto bad;
- }
- }
- if (ucom->sc_bulkin_no == -1) {
- device_printf(ucom->sc_dev, "Could not find data bulk in\n");
- goto bad;
- }
- if (ucom->sc_bulkout_no == -1) {
- device_printf(ucom->sc_dev, "Could not find data bulk out\n");
- goto bad;
- }
- ucom->sc_parent = sc;
- if (uaa->iface == NULL)
- ucom->sc_portno = FTDI_PIT_SIOA;
- else
- ucom->sc_portno = FTDI_PIT_SIOA + id->bInterfaceNumber;
- /* bulkin, bulkout set above */
-
- ucom->sc_ibufsize = UFTDIIBUFSIZE;
- ucom->sc_obufsize = UFTDIOBUFSIZE - sc->sc_hdrlen;
- ucom->sc_ibufsizepad = UFTDIIBUFSIZE;
- ucom->sc_opkthdrlen = sc->sc_hdrlen;
-
-
- ucom->sc_callback = &uftdi_callback;
-#if 0
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, ucom->sc_udev,
- ucom->sc_dev);
-#endif
- DPRINTF(("uftdi: in=0x%x out=0x%x\n", ucom->sc_bulkin_no, ucom->sc_bulkout_no));
- ucom_attach(&sc->sc_ucom);
- return 0;
-
-bad:
- DPRINTF(("uftdi_attach: ATTACH ERROR\n"));
- ucom->sc_dying = 1;
- return ENXIO;
-}
-#if 0
-int
-uftdi_activate(device_t self, enum devact act)
-{
- struct uftdi_softc *sc = (struct uftdi_softc *)self;
- int rv = 0;
-
- switch (act) {
- case DVACT_ACTIVATE:
- return (EOPNOTSUPP);
-
- case DVACT_DEACTIVATE:
- if (sc->sc_subdev != NULL)
- rv = config_deactivate(sc->sc_subdev);
- sc->sc_ucom.sc_dying = 1;
- break;
- }
- return (rv);
-}
-#endif
-
-static int
-uftdi_detach(device_t self)
-{
- struct uftdi_softc *sc = device_get_softc(self);
-
- int rv = 0;
-
- DPRINTF(("uftdi_detach: sc=%p\n", sc));
- sc->sc_ucom.sc_dying = 1;
- rv = ucom_detach(&sc->sc_ucom);
-
- return rv;
-}
-
-static int
-uftdi_open(void *vsc, int portno)
-{
- struct uftdi_softc *sc = vsc;
- struct ucom_softc *ucom = &sc->sc_ucom;
- usb_device_request_t req;
- usbd_status err;
- struct termios t;
-
- DPRINTF(("uftdi_open: sc=%p\n", sc));
-
- if (ucom->sc_dying)
- return (EIO);
-
- /* Perform a full reset on the device */
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_RESET;
- USETW(req.wValue, FTDI_SIO_RESET_SIO);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- /* Set 9600 baud, 2 stop bits, no parity, 8 bits */
- t.c_ospeed = 9600;
- t.c_cflag = CSTOPB | CS8;
- (void)uftdi_param(sc, portno, &t);
-
- /* Turn on RTS/CTS flow control */
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_FLOW_CTRL;
- USETW(req.wValue, 0);
- USETW2(req.wIndex, FTDI_SIO_RTS_CTS_HS, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- return (0);
-}
-
-static void
-uftdi_read(void *vsc, int portno, u_char **ptr, u_int32_t *count)
-{
- struct uftdi_softc *sc = vsc;
- u_char msr, lsr;
- unsigned l;
-
- DPRINTFN(15,("uftdi_read: sc=%p, port=%d count=%d\n",
- sc, portno, *count));
- while (*count > 0) {
- l = *count;
- if (l > 64)
- l = 64;
-
- msr = FTDI_GET_MSR(*ptr);
- lsr = FTDI_GET_LSR(*ptr);
-
- if (sc->sc_msr != msr ||
- (sc->sc_lsr & FTDI_LSR_MASK) != (lsr & FTDI_LSR_MASK)) {
- DPRINTF(("uftdi_read: status change msr=0x%02x(0x%02x) "
- "lsr=0x%02x(0x%02x)\n", msr, sc->sc_msr,
- lsr, sc->sc_lsr));
- sc->sc_msr = msr;
- sc->sc_lsr = lsr;
- ucom_status_change(&sc->sc_ucom);
- }
-
- if (l > 2)
- ucomrxchars(&sc->sc_ucom, (*ptr) + 2, l - 2);
- *ptr += l;
- *count -= l;
- }
-}
-
-static size_t
-uftdi_write(void *vsc, int portno, struct tty *tp, u_char *to, u_int32_t count)
-{
- struct uftdi_softc *sc = vsc;
- size_t l;
-
- DPRINTFN(10,("uftdi_write: sc=%p, port=%d tp=%p, count=%u\n",
- vsc, portno, tp, count));
-
- /* Leave space for the length tag. */
- l = ttydisc_getc(tp, to + sc->sc_hdrlen, count - sc->sc_hdrlen);
- if (l == 0)
- return (0);
-
- /* Make length tag. */
- if (sc->sc_hdrlen > 0)
- *to = FTDI_OUT_TAG(l, portno);
-
- return (l + sc->sc_hdrlen);
-}
-
-static void
-uftdi_set(void *vsc, int portno, int reg, int onoff)
-{
- struct uftdi_softc *sc = vsc;
- struct ucom_softc *ucom = vsc;
- usb_device_request_t req;
- int ctl;
-
- DPRINTF(("uftdi_set: sc=%p, port=%d reg=%d onoff=%d\n", vsc, portno,
- reg, onoff));
-
- switch (reg) {
- case UCOM_SET_DTR:
- ctl = onoff ? FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW;
- break;
- case UCOM_SET_RTS:
- ctl = onoff ? FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW;
- break;
- case UCOM_SET_BREAK:
- uftdi_break(sc, portno, onoff);
- return;
- default:
- return;
- }
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_MODEM_CTRL;
- USETW(req.wValue, ctl);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- DPRINTFN(2,("uftdi_set: reqtype=0x%02x req=0x%02x value=0x%04x "
- "index=0x%04x len=%d\n", req.bmRequestType, req.bRequest,
- UGETW(req.wValue), UGETW(req.wIndex), UGETW(req.wLength)));
- (void)usbd_do_request(ucom->sc_udev, &req, NULL);
-}
-
-static int
-uftdi_param(void *vsc, int portno, struct termios *t)
-{
- struct uftdi_softc *sc = vsc;
- struct ucom_softc *ucom = &sc->sc_ucom;
- usb_device_request_t req;
- usbd_status err;
- int rate=0, data, flow;
-
- DPRINTF(("uftdi_param: sc=%p\n", sc));
-
- if (ucom->sc_dying)
- return (EIO);
-
- switch (sc->sc_type) {
- case UFTDI_TYPE_SIO:
- switch (t->c_ospeed) {
- case 300: rate = ftdi_sio_b300; break;
- case 600: rate = ftdi_sio_b600; break;
- case 1200: rate = ftdi_sio_b1200; break;
- case 2400: rate = ftdi_sio_b2400; break;
- case 4800: rate = ftdi_sio_b4800; break;
- case 9600: rate = ftdi_sio_b9600; break;
- case 19200: rate = ftdi_sio_b19200; break;
- case 38400: rate = ftdi_sio_b38400; break;
- case 57600: rate = ftdi_sio_b57600; break;
- case 115200: rate = ftdi_sio_b115200; break;
- default:
- return (EINVAL);
- }
- break;
-
- case UFTDI_TYPE_8U232AM:
- if (uftdi_8u232am_getrate(t->c_ospeed, &rate) == -1)
- return (EINVAL);
- break;
- }
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_BAUD_RATE;
- USETW(req.wValue, rate);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- DPRINTFN(2,("uftdi_param: reqtype=0x%02x req=0x%02x value=0x%04x "
- "index=0x%04x len=%d\n", req.bmRequestType, req.bRequest,
- UGETW(req.wValue), UGETW(req.wIndex), UGETW(req.wLength)));
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- if (ISSET(t->c_cflag, CSTOPB))
- data = FTDI_SIO_SET_DATA_STOP_BITS_2;
- else
- data = FTDI_SIO_SET_DATA_STOP_BITS_1;
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- data |= FTDI_SIO_SET_DATA_PARITY_ODD;
- else
- data |= FTDI_SIO_SET_DATA_PARITY_EVEN;
- } else
- data |= FTDI_SIO_SET_DATA_PARITY_NONE;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- data |= FTDI_SIO_SET_DATA_BITS(5);
- break;
- case CS6:
- data |= FTDI_SIO_SET_DATA_BITS(6);
- break;
- case CS7:
- data |= FTDI_SIO_SET_DATA_BITS(7);
- break;
- case CS8:
- data |= FTDI_SIO_SET_DATA_BITS(8);
- break;
- }
- sc->last_lcr = data;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_DATA;
- USETW(req.wValue, data);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- DPRINTFN(2,("uftdi_param: reqtype=0x%02x req=0x%02x value=0x%04x "
- "index=0x%04x len=%d\n", req.bmRequestType, req.bRequest,
- UGETW(req.wValue), UGETW(req.wIndex), UGETW(req.wLength)));
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- if (ISSET(t->c_cflag, CRTSCTS)) {
- flow = FTDI_SIO_RTS_CTS_HS;
- USETW(req.wValue, 0);
- } else if (ISSET(t->c_iflag, IXON|IXOFF)) {
- flow = FTDI_SIO_XON_XOFF_HS;
- USETW2(req.wValue, t->c_cc[VSTOP], t->c_cc[VSTART]);
- } else {
- flow = FTDI_SIO_DISABLE_FLOW_CTRL;
- USETW(req.wValue, 0);
- }
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_FLOW_CTRL;
- USETW2(req.wIndex, flow, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- return (0);
-}
-
-void
-uftdi_get_status(void *vsc, int portno, u_char *lsr, u_char *msr)
-{
- struct uftdi_softc *sc = vsc;
-
- DPRINTF(("uftdi_status: msr=0x%02x lsr=0x%02x\n",
- sc->sc_msr, sc->sc_lsr));
-
- if (msr != NULL)
- *msr = sc->sc_msr;
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
-}
-
-void
-uftdi_break(void *vsc, int portno, int onoff)
-{
- struct uftdi_softc *sc = vsc;
- struct ucom_softc *ucom = vsc;
-
- usb_device_request_t req;
- int data;
-
- DPRINTF(("uftdi_break: sc=%p, port=%d onoff=%d\n", vsc, portno,
- onoff));
-
- if (onoff) {
- data = sc->last_lcr | FTDI_SIO_SET_BREAK;
- } else {
- data = sc->last_lcr;
- }
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_DATA;
- USETW(req.wValue, data);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- (void)usbd_do_request(ucom->sc_udev, &req, NULL);
-}
-
-static int
-uftdi_8u232am_getrate(speed_t speed, int *rate)
-{
- /* Table of the nearest even powers-of-2 for values 0..15. */
- static const unsigned char roundoff[16] = {
- 0, 2, 2, 4, 4, 4, 8, 8,
- 8, 8, 8, 8, 16, 16, 16, 16,
- };
-
- unsigned int d, freq;
- int result;
-
- if (speed <= 0)
- return (-1);
-
- /* Special cases for 2M and 3M. */
- if (speed >= 3000000 * 100 / 103 &&
- speed <= 3000000 * 100 / 97) {
- result = 0;
- goto done;
- }
- if (speed >= 2000000 * 100 / 103 &&
- speed <= 2000000 * 100 / 97) {
- result = 1;
- goto done;
- }
-
- d = (FTDI_8U232AM_FREQ << 4) / speed;
- d = (d & ~15) + roundoff[d & 15];
-
- if (d < FTDI_8U232AM_MIN_DIV)
- d = FTDI_8U232AM_MIN_DIV;
- else if (d > FTDI_8U232AM_MAX_DIV)
- d = FTDI_8U232AM_MAX_DIV;
-
- /*
- * Calculate the frequency needed for d to exactly divide down
- * to our target speed, and check that the actual frequency is
- * within 3% of this.
- */
- freq = speed * d;
- if (freq < (quad_t)(FTDI_8U232AM_FREQ << 4) * 100 / 103 ||
- freq > (quad_t)(FTDI_8U232AM_FREQ << 4) * 100 / 97)
- return (-1);
-
- /*
- * Pack the divisor into the resultant value. The lower
- * 14-bits hold the integral part, while the upper 2 bits
- * encode the fractional component: either 0, 0.5, 0.25, or
- * 0.125.
- */
- result = d >> 4;
- if (d & 8)
- result |= 0x4000;
- else if (d & 4)
- result |= 0x8000;
- else if (d & 2)
- result |= 0xc000;
-
-done:
- *rate = result;
- return (0);
-}
-
-static device_method_t uftdi_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uftdi_match),
- DEVMETHOD(device_attach, uftdi_attach),
- DEVMETHOD(device_detach, uftdi_detach),
-
- { 0, 0 }
-};
-
-static driver_t uftdi_driver = {
- "ucom",
- uftdi_methods,
- sizeof (struct uftdi_softc)
-};
-
-DRIVER_MODULE(uftdi, uhub, uftdi_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uftdi, usb, 1, 1, 1);
-MODULE_DEPEND(uftdi, ucom,UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
diff --git a/sys/legacy/dev/usb/uftdireg.h b/sys/legacy/dev/usb/uftdireg.h
deleted file mode 100644
index 78c9349..0000000
--- a/sys/legacy/dev/usb/uftdireg.h
+++ /dev/null
@@ -1,338 +0,0 @@
-/* $NetBSD: uftdireg.h,v 1.6 2002/07/11 21:14:28 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*
- * Definitions for the FTDI USB Single Port Serial Converter -
- * known as FTDI_SIO (Serial Input/Output application of the chipset)
- *
- * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side,
- * USB on the other.
- *
- * Thanx to FTDI (http://www.ftdi.co.uk) for so kindly providing details
- * of the protocol required to talk to the device and ongoing assistence
- * during development.
- *
- * Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc. is the original
- * author of this file.
- */
-/* Modified by Lennart Augustsson */
-
-/* Vendor Request Interface */
-#define FTDI_SIO_RESET 0 /* Reset the port */
-#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
-#define FTDI_SIO_SET_FLOW_CTRL 2 /* Set flow control register */
-#define FTDI_SIO_SET_BAUD_RATE 3 /* Set baud rate */
-#define FTDI_SIO_SET_DATA 4 /* Set the data characteristics of the port */
-#define FTDI_SIO_GET_STATUS 5 /* Retrieve current value of status reg */
-#define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */
-#define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */
-
-/* Port Identifier Table */
-#define FTDI_PIT_DEFAULT 0 /* SIOA */
-#define FTDI_PIT_SIOA 1 /* SIOA */
-#define FTDI_PIT_SIOB 2 /* SIOB */
-#define FTDI_PIT_PARALLEL 3 /* Parallel */
-
-enum uftdi_type {
- UFTDI_TYPE_SIO,
- UFTDI_TYPE_8U232AM
-};
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_RESET
- * wValue: Control Value
- * 0 = Reset SIO
- * 1 = Purge RX buffer
- * 2 = Purge TX buffer
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * The Reset SIO command has this effect:
- *
- * Sets flow control set to 'none'
- * Event char = 0x0d
- * Event trigger = disabled
- * Purge RX buffer
- * Purge TX buffer
- * Clear DTR
- * Clear RTS
- * baud and data format not reset
- *
- * The Purge RX and TX buffer commands affect nothing except the buffers
- *
- */
-/* FTDI_SIO_RESET */
-#define FTDI_SIO_RESET_SIO 0
-#define FTDI_SIO_RESET_PURGE_RX 1
-#define FTDI_SIO_RESET_PURGE_TX 2
-
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_SET_BAUDRATE
- * wValue: BaudRate value - see below
- * wIndex: Port
- * wLength: 0
- * Data: None
- */
-/* FTDI_SIO_SET_BAUDRATE */
-enum {
- ftdi_sio_b300 = 0,
- ftdi_sio_b600 = 1,
- ftdi_sio_b1200 = 2,
- ftdi_sio_b2400 = 3,
- ftdi_sio_b4800 = 4,
- ftdi_sio_b9600 = 5,
- ftdi_sio_b19200 = 6,
- ftdi_sio_b38400 = 7,
- ftdi_sio_b57600 = 8,
- ftdi_sio_b115200 = 9
-};
-
-#define FTDI_8U232AM_FREQ 3000000
-
-/* Bounds for normal divisors as 4-bit fixed precision ints. */
-#define FTDI_8U232AM_MIN_DIV 0x20
-#define FTDI_8U232AM_MAX_DIV 0x3fff8
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_SET_DATA
- * wValue: Data characteristics (see below)
- * wIndex: Port
- * wLength: 0
- * Data: No
- *
- * Data characteristics
- *
- * B0..7 Number of data bits
- * B8..10 Parity
- * 0 = None
- * 1 = Odd
- * 2 = Even
- * 3 = Mark
- * 4 = Space
- * B11..13 Stop Bits
- * 0 = 1
- * 1 = 1.5
- * 2 = 2
- * B14..15 Reserved
- *
- */
-/* FTDI_SIO_SET_DATA */
-#define FTDI_SIO_SET_DATA_BITS(n) (n)
-#define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8)
-#define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11)
-#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11)
-#define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11)
-#define FTDI_SIO_SET_BREAK (0x1 << 14)
-
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_MODEM_CTRL
- * wValue: ControlValue (see below)
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * NOTE: If the device is in RTS/CTS flow control, the RTS set by this
- * command will be IGNORED without an error being returned
- * Also - you can not set DTR and RTS with one control message
- *
- * ControlValue
- * B0 DTR state
- * 0 = reset
- * 1 = set
- * B1 RTS state
- * 0 = reset
- * 1 = set
- * B2..7 Reserved
- * B8 DTR state enable
- * 0 = ignore
- * 1 = use DTR state
- * B9 RTS state enable
- * 0 = ignore
- * 1 = use RTS state
- * B10..15 Reserved
- */
-/* FTDI_SIO_MODEM_CTRL */
-#define FTDI_SIO_SET_DTR_MASK 0x1
-#define FTDI_SIO_SET_DTR_HIGH (1 | ( FTDI_SIO_SET_DTR_MASK << 8))
-#define FTDI_SIO_SET_DTR_LOW (0 | ( FTDI_SIO_SET_DTR_MASK << 8))
-#define FTDI_SIO_SET_RTS_MASK 0x2
-#define FTDI_SIO_SET_RTS_HIGH (2 | ( FTDI_SIO_SET_RTS_MASK << 8))
-#define FTDI_SIO_SET_RTS_LOW (0 | ( FTDI_SIO_SET_RTS_MASK << 8))
-
-
-/*
- * BmRequestType: 0100 0000b
- * bRequest: FTDI_SIO_SET_FLOW_CTRL
- * wValue: Xoff/Xon
- * wIndex: Protocol/Port - hIndex is protocl / lIndex is port
- * wLength: 0
- * Data: None
- *
- * hIndex protocol is:
- * B0 Output handshaking using RTS/CTS
- * 0 = disabled
- * 1 = enabled
- * B1 Output handshaking using DTR/DSR
- * 0 = disabled
- * 1 = enabled
- * B2 Xon/Xoff handshaking
- * 0 = disabled
- * 1 = enabled
- *
- * A value of zero in the hIndex field disables handshaking
- *
- * If Xon/Xoff handshaking is specified, the hValue field should contain the
- * XOFF character and the lValue field contains the XON character.
- */
-/* FTDI_SIO_SET_FLOW_CTRL */
-#define FTDI_SIO_DISABLE_FLOW_CTRL 0x0
-#define FTDI_SIO_RTS_CTS_HS 0x1
-#define FTDI_SIO_DTR_DSR_HS 0x2
-#define FTDI_SIO_XON_XOFF_HS 0x4
-
-
-/*
- * BmRequestType: 0100 0000b
- * bRequest: FTDI_SIO_SET_EVENT_CHAR
- * wValue: Event Char
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * wValue:
- * B0..7 Event Character
- * B8 Event Character Processing
- * 0 = disabled
- * 1 = enabled
- * B9..15 Reserved
- *
- * FTDI_SIO_SET_EVENT_CHAR
- *
- * Set the special event character for the specified communications port.
- * If the device sees this character it will immediately return the
- * data read so far - rather than wait 40ms or until 62 bytes are read
- * which is what normally happens.
- */
-
-
-
-/*
- * BmRequestType: 0100 0000b
- * bRequest: FTDI_SIO_SET_ERROR_CHAR
- * wValue: Error Char
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * Error Char
- * B0..7 Error Character
- * B8 Error Character Processing
- * 0 = disabled
- * 1 = enabled
- * B9..15 Reserved
- *
- *
- * FTDI_SIO_SET_ERROR_CHAR
- * Set the parity error replacement character for the specified communications
- * port.
- */
-
-
-/*
- * BmRequestType: 1100 0000b
- * bRequest: FTDI_SIO_GET_MODEM_STATUS
- * wValue: zero
- * wIndex: Port
- * wLength: 1
- * Data: Status
- *
- * One byte of data is returned
- * B0..3 0
- * B4 CTS
- * 0 = inactive
- * 1 = active
- * B5 DSR
- * 0 = inactive
- * 1 = active
- * B6 Ring Indicator (RI)
- * 0 = inactive
- * 1 = active
- * B7 Receive Line Signal Detect (RLSD)
- * 0 = inactive
- * 1 = active
- *
- * FTDI_SIO_GET_MODEM_STATUS
- * Retrieve the current value of the modem status register.
- */
-#define FTDI_SIO_CTS_MASK 0x10
-#define FTDI_SIO_DSR_MASK 0x20
-#define FTDI_SIO_RI_MASK 0x40
-#define FTDI_SIO_RLSD_MASK 0x80
-
-
-
-/*
- *
- * DATA FORMAT
- *
- * IN Endpoint
- *
- * The device reserves the first two bytes of data on this endpoint to contain
- * the current values of the modem and line status registers. In the absence of
- * data, the device generates a message consisting of these two status bytes
- * every 40 ms.
- *
- * Byte 0: Modem Status
- * NOTE: 4 upper bits have same layout as the MSR register in a 16550
- *
- * Offset Description
- * B0..3 Port
- * B4 Clear to Send (CTS)
- * B5 Data Set Ready (DSR)
- * B6 Ring Indicator (RI)
- * B7 Receive Line Signal Detect (RLSD)
- *
- * Byte 1: Line Status
- * NOTE: same layout as the LSR register in a 16550
- *
- * Offset Description
- * B0 Data Ready (DR)
- * B1 Overrun Error (OE)
- * B2 Parity Error (PE)
- * B3 Framing Error (FE)
- * B4 Break Interrupt (BI)
- * B5 Transmitter Holding Register (THRE)
- * B6 Transmitter Empty (TEMT)
- * B7 Error in RCVR FIFO
- *
- *
- * OUT Endpoint
- *
- * This device reserves the first bytes of data on this endpoint contain the
- * length and port identifier of the message. For the FTDI USB Serial converter
- * the port identifier is always 1.
- *
- * Byte 0: Port & length
- *
- * Offset Description
- * B0..1 Port
- * B2..7 Length of message - (not including Byte 0)
- *
- */
-#define FTDI_PORT_MASK 0x0f
-#define FTDI_MSR_MASK 0xf0
-#define FTDI_GET_MSR(p) (((p)[0]) & FTDI_MSR_MASK)
-#define FTDI_GET_LSR(p) ((p)[1])
-#define FTDI_LSR_MASK (~0x60) /* interesting bits */
-#define FTDI_OUT_TAG(len, port) (((len) << 2) | (port))
diff --git a/sys/legacy/dev/usb/ugen.c b/sys/legacy/dev/usb/ugen.c
deleted file mode 100644
index 4f03cfb..0000000
--- a/sys/legacy/dev/usb/ugen.c
+++ /dev/null
@@ -1,1590 +0,0 @@
-/* $NetBSD: ugen.c,v 1.79 2006/03/01 12:38:13 yamt Exp $ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: ugen.c,v 1.61 2002/09/23 05:51:20 simonb Exp $
- * $NetBSD: ugen.c,v 1.64 2003/06/28 14:21:46 darrenr Exp $
- * $NetBSD: ugen.c,v 1.65 2003/06/29 22:30:56 fvdl Exp $
- * $NetBSD: ugen.c,v 1.68 2004/06/23 02:30:52 mycroft Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/clist.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (ugendebug) printf x
-#define DPRINTFN(n,x) if (ugendebug>(n)) printf x
-int ugendebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ugen, CTLFLAG_RW, 0, "USB ugen");
-SYSCTL_INT(_hw_usb_ugen, OID_AUTO, debug, CTLFLAG_RW,
- &ugendebug, 0, "ugen debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UGEN_CHUNK 128 /* chunk size for read */
-#define UGEN_IBSIZE 1020 /* buffer size */
-#define UGEN_BBSIZE 1024
-
-#define UGEN_NISOFRAMES 500 /* 0.5 seconds worth */
-#define UGEN_NISOREQS 6 /* number of outstanding xfer requests */
-#define UGEN_NISORFRMS 4 /* number of frames (miliseconds) per req */
-
-struct ugen_endpoint {
- struct ugen_softc *sc;
- struct cdev *dev;
- usb_endpoint_descriptor_t *edesc;
- usbd_interface_handle iface;
- int state;
-#define UGEN_ASLP 0x02 /* waiting for data */
-#define UGEN_SHORT_OK 0x04 /* short xfers are OK */
- usbd_pipe_handle pipeh;
- struct clist q;
- struct selinfo rsel;
- u_char *ibuf; /* start of buffer (circular for isoc) */
- u_char *fill; /* location for input (isoc) */
- u_char *limit; /* end of circular buffer (isoc) */
- u_char *cur; /* current read location (isoc) */
- u_int32_t timeout;
- struct isoreq {
- struct ugen_endpoint *sce;
- usbd_xfer_handle xfer;
- void *dmabuf;
- u_int16_t sizes[UGEN_NISORFRMS];
- } isoreqs[UGEN_NISOREQS];
-};
-
-struct ugen_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev;
- struct cdev *dev;
-
- char sc_is_open[USB_MAX_ENDPOINTS];
- struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2];
-#define OUT 0
-#define IN 1
-
-#define UGEN_DEV_REF(dev, sc) \
- if ((sc)->sc_dying || dev_refthread(dev) == NULL) \
- return (ENXIO)
-#define UGEN_DEV_RELE(dev, sc) \
- dev_relthread(dev)
-#define UGEN_DEV_OPEN(dev, sc) \
- /* handled by dev layer */
-#define UGEN_DEV_CLOSE(dev, sc) \
- /* handled by dev layer */
- u_char sc_dying;
-};
-
-d_open_t ugenopen;
-d_close_t ugenclose;
-d_read_t ugenread;
-d_write_t ugenwrite;
-d_ioctl_t ugenioctl;
-d_poll_t ugenpoll;
-d_purge_t ugenpurge;
-
-static struct cdevsw ugenctl_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = ugenopen,
- .d_close = ugenclose,
- .d_ioctl = ugenioctl,
- .d_purge = ugenpurge,
- .d_name = "ugenctl",
-};
-
-static struct cdevsw ugen_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = ugenopen,
- .d_close = ugenclose,
- .d_read = ugenread,
- .d_write = ugenwrite,
- .d_ioctl = ugenioctl,
- .d_poll = ugenpoll,
- .d_purge = ugenpurge,
- .d_name = "ugen",
-};
-
-static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr,
- usbd_status status);
-static void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
- usbd_status status);
-static int ugen_do_read(struct ugen_softc *, int, struct uio *, int);
-static int ugen_do_write(struct ugen_softc *, int, struct uio *, int);
-static int ugen_do_ioctl(struct ugen_softc *, int, u_long,
- caddr_t, int, struct thread *);
-static void ugen_make_devnodes(struct ugen_softc *sc);
-static void ugen_destroy_devnodes(struct ugen_softc *sc);
-static int ugen_set_config(struct ugen_softc *sc, int configno);
-static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc,
- int index, int *lenp);
-static usbd_status ugen_set_interface(struct ugen_softc *, int, int);
-static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx);
-
-#define UGENUNIT(n) ((dev2unit(n) >> 4) & 0xf)
-#define UGENENDPOINT(n) (dev2unit(n) & 0xf)
-#define UGENMINOR(u, e) (((u) << 4) | (e))
-
-static device_probe_t ugen_match;
-static device_attach_t ugen_attach;
-static device_detach_t ugen_detach;
-
-static devclass_t ugen_devclass;
-
-static device_method_t ugen_methods[] = {
- DEVMETHOD(device_probe, ugen_match),
- DEVMETHOD(device_attach, ugen_attach),
- DEVMETHOD(device_detach, ugen_detach),
- {0,0},
- {0,0}
-};
-
-static driver_t ugen_driver = {
- "ugen",
- ugen_methods,
- sizeof(struct ugen_softc)
-};
-
-MODULE_DEPEND(ugen, usb, 1, 1, 1);
-
-static int
-ugen_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
-#if 0
- if (uaa->matchlvl)
- return (uaa->matchlvl);
-#endif
- if (uaa->usegeneric)
- return (UMATCH_GENERIC);
- else
- return (UMATCH_NONE);
-}
-
-static int
-ugen_attach(device_t self)
-{
- struct ugen_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle udev;
- usbd_status err;
- int conf;
-
- sc->sc_dev = self;
- sc->sc_udev = udev = uaa->device;
-
- memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
-
- /* First set configuration index 0, the default one for ugen. */
- err = usbd_set_config_index(udev, 0, 0);
- if (err) {
- printf("%s: setting configuration index 0 failed\n",
- device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return (ENXIO);
- }
- conf = usbd_get_config_descriptor(udev)->bConfigurationValue;
-
- /* Set up all the local state for this configuration. */
- err = ugen_set_config(sc, conf);
- if (err) {
- printf("%s: setting configuration %d failed\n",
- device_get_nameunit(sc->sc_dev), conf);
- sc->sc_dying = 1;
- return (ENXIO);
- }
-
- /* the main device, ctrl endpoint */
- sc->dev = make_dev(&ugenctl_cdevsw,
- UGENMINOR(device_get_unit(sc->sc_dev), 0), UID_ROOT, GID_OPERATOR, 0644,
- "%s", device_get_nameunit(sc->sc_dev));
- ugen_make_devnodes(sc);
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
- return (0);
-}
-
-static void
-ugen_make_devnodes(struct ugen_softc *sc)
-{
- int endptno;
- struct cdev *dev;
-
- for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
- if (sc->sc_endpoints[endptno][IN].sc != NULL ||
- sc->sc_endpoints[endptno][OUT].sc != NULL ) {
- /* endpt can be 0x81 and 0x01, representing
- * endpoint address 0x01 and IN/OUT directions.
- * We map both endpts to the same device,
- * IN is reading from it, OUT is writing to it.
- *
- * In the if clause above we check whether one
- * of the structs is populated.
- */
- dev = make_dev(&ugen_cdevsw,
- UGENMINOR(device_get_unit(sc->sc_dev), endptno),
- UID_ROOT, GID_OPERATOR, 0644,
- "%s.%d",
- device_get_nameunit(sc->sc_dev), endptno);
- dev_depends(sc->dev, dev);
- if (sc->sc_endpoints[endptno][IN].sc != NULL)
- sc->sc_endpoints[endptno][IN].dev = dev;
- if (sc->sc_endpoints[endptno][OUT].sc != NULL)
- sc->sc_endpoints[endptno][OUT].dev = dev;
- }
- }
-}
-
-static void
-ugen_destroy_devnodes(struct ugen_softc *sc)
-{
- int endptno, prev_sc_dying;
- struct cdev *dev;
-
- prev_sc_dying = sc->sc_dying;
- sc->sc_dying = 1;
- /* destroy all devices for the other (existing) endpoints as well */
- for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
- if (sc->sc_endpoints[endptno][IN].sc != NULL ||
- sc->sc_endpoints[endptno][OUT].sc != NULL ) {
- /* endpt can be 0x81 and 0x01, representing
- * endpoint address 0x01 and IN/OUT directions.
- * We map both endpoint addresses to the same device,
- * IN is reading from it, OUT is writing to it.
- *
- * In the if clause above we check whether one
- * of the structs is populated.
- */
- if (sc->sc_endpoints[endptno][IN].sc != NULL)
- dev = sc->sc_endpoints[endptno][IN].dev;
- else
- dev = sc->sc_endpoints[endptno][OUT].dev;
-
- KASSERT(dev != NULL,
- ("ugen_destroy_devnodes: NULL dev"));
- if(dev != NULL)
- destroy_dev(dev);
-
- sc->sc_endpoints[endptno][IN].sc = NULL;
- sc->sc_endpoints[endptno][OUT].sc = NULL;
- }
- }
- sc->sc_dying = prev_sc_dying;
-}
-
-static int
-ugen_set_config(struct ugen_softc *sc, int configno)
-{
- usbd_device_handle dev = sc->sc_udev;
- usbd_interface_handle iface;
- usb_endpoint_descriptor_t *ed;
- struct ugen_endpoint *sce, **sce_cache, ***sce_cache_arr;
- u_int8_t niface, niface_cache, nendpt, *nendpt_cache;
- int ifaceno, endptno, endpt;
- usbd_status err;
- int dir;
-
- DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
- device_get_nameunit(sc->sc_dev), configno, sc));
-
- /* We start at 1, not 0, because we don't care whether the
- * control endpoint is open or not. It is always present.
- */
- for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++)
- if (sc->sc_is_open[endptno]) {
- DPRINTFN(1,
- ("ugen_set_config: %s - endpoint %d is open\n",
- device_get_nameunit(sc->sc_dev), endptno));
- return (USBD_IN_USE);
- }
-
- err = usbd_interface_count(dev, &niface);
- if (err)
- return (err);
- /* store an array of endpoint descriptors to clear if the configuration
- * change succeeds - these aren't available afterwards */
- nendpt_cache = malloc(sizeof(u_int8_t) * niface, M_TEMP, M_WAITOK |
- M_ZERO);
- sce_cache_arr = malloc(sizeof(struct ugen_endpoint **) * niface, M_TEMP,
- M_WAITOK | M_ZERO);
- niface_cache = niface;
-
- for (ifaceno = 0; ifaceno < niface; ifaceno++) {
- DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
- err = usbd_device2interface_handle(dev, ifaceno, &iface);
- if (err)
- panic("ugen_set_config: can't obtain interface handle");
- err = usbd_endpoint_count(iface, &nendpt);
- if (err)
- panic("ugen_set_config: endpoint count failed");
-
- /* store endpoint descriptors for each interface */
- nendpt_cache[ifaceno] = nendpt;
- sce_cache = malloc(sizeof(struct ugen_endpoint *) * nendpt, M_TEMP,
- M_WAITOK);
- sce_cache_arr[ifaceno] = sce_cache;
-
- for (endptno = 0; endptno < nendpt; endptno++) {
- ed = usbd_interface2endpoint_descriptor(iface,endptno);
- endpt = ed->bEndpointAddress;
- dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
- sce_cache[endptno] = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
- }
- }
-
- /* Avoid setting the current value. */
- if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
- /* attempt to perform the configuration change */
- err = usbd_set_config_no(dev, configno, 1);
- if (err) {
- for(ifaceno = 0; ifaceno < niface_cache; ifaceno++)
- free(sce_cache_arr[ifaceno], M_TEMP);
- free(sce_cache_arr, M_TEMP);
- free(nendpt_cache, M_TEMP);
- return (err);
- }
- }
-
- ugen_destroy_devnodes(sc);
-
- /* now we can clear the old interface's ugen_endpoints */
- for(ifaceno = 0; ifaceno < niface_cache; ifaceno++) {
- sce_cache = sce_cache_arr[ifaceno];
- for(endptno = 0; endptno < nendpt_cache[ifaceno]; endptno++) {
- sce = sce_cache[endptno];
- sce->sc = 0;
- sce->edesc = 0;
- sce->iface = 0;
- }
- }
-
- /* and free the cache storing them */
- for(ifaceno = 0; ifaceno < niface_cache; ifaceno++)
- free(sce_cache_arr[ifaceno], M_TEMP);
- free(sce_cache_arr, M_TEMP);
- free(nendpt_cache, M_TEMP);
-
- /* no endpoints if the device is in the unconfigured state */
- if (configno != USB_UNCONFIG_NO)
- {
- /* set the new configuration's ugen_endpoints */
- err = usbd_interface_count(dev, &niface);
- if (err)
- panic("ugen_set_config: interface count failed");
-
- memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
- for (ifaceno = 0; ifaceno < niface; ifaceno++) {
- DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
- err = usbd_device2interface_handle(dev, ifaceno, &iface);
- if (err)
- panic("ugen_set_config: can't obtain interface handle");
- err = usbd_endpoint_count(iface, &nendpt);
- if (err)
- panic("ugen_set_config: endpoint count failed");
- for (endptno = 0; endptno < nendpt; endptno++) {
- ed = usbd_interface2endpoint_descriptor(iface,endptno);
- endpt = ed->bEndpointAddress;
- dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
- sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
- DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x"
- "(%d,%d), sce=%p\n",
- endptno, endpt, UE_GET_ADDR(endpt),
- UE_GET_DIR(endpt), sce));
- sce->sc = sc;
- sce->edesc = ed;
- sce->iface = iface;
- }
- }
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-int
-ugenopen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct ugen_softc *sc;
- int unit = UGENUNIT(dev);
- int endpt = UGENENDPOINT(dev);
- usb_endpoint_descriptor_t *edesc;
- struct ugen_endpoint *sce;
- int dir, isize;
- usbd_status err;
- usbd_xfer_handle xfer;
- void *buf;
- int i, j;
-
- sc = devclass_get_softc(ugen_devclass, unit);
- if (sc == NULL)
- return (ENXIO);
-
- DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
- flag, mode, unit, endpt));
-
- if (sc == NULL || sc->sc_dying)
- return (ENXIO);
-
- if (sc->sc_is_open[endpt])
- return (EBUSY);
-
- if (endpt == USB_CONTROL_ENDPOINT) {
- sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
- UGEN_DEV_OPEN(dev, sc);
- return (0);
- }
-
- /* Make sure there are pipes for all directions. */
- for (dir = OUT; dir <= IN; dir++) {
- if (flag & (dir == OUT ? FWRITE : FREAD)) {
- sce = &sc->sc_endpoints[endpt][dir];
- if (sce->edesc == 0)
- return (ENXIO);
- }
- }
-
- /* Actually open the pipes. */
- /* XXX Should back out properly if it fails. */
- for (dir = OUT; dir <= IN; dir++) {
- if (!(flag & (dir == OUT ? FWRITE : FREAD)))
- continue;
- sce = &sc->sc_endpoints[endpt][dir];
- sce->state = 0;
- sce->timeout = USBD_NO_TIMEOUT;
- DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
- sc, endpt, dir, sce));
- edesc = sce->edesc;
- switch (edesc->bmAttributes & UE_XFERTYPE) {
- case UE_INTERRUPT:
- if (dir == OUT) {
- err = usbd_open_pipe(sce->iface,
- edesc->bEndpointAddress, 0, &sce->pipeh);
- if (err)
- return (EIO);
- break;
- }
- isize = UGETW(edesc->wMaxPacketSize);
- if (isize == 0) /* shouldn't happen */
- return (EINVAL);
- sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
- DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
- endpt, isize));
- if ((clist_alloc_cblocks(&sce->q, UGEN_IBSIZE,
- UGEN_IBSIZE), 0) == -1)
- return (ENOMEM);
- err = usbd_open_pipe_intr(sce->iface,
- edesc->bEndpointAddress,
- USBD_SHORT_XFER_OK, &sce->pipeh, sce,
- sce->ibuf, isize, ugenintr,
- USBD_DEFAULT_INTERVAL);
- if (err) {
- free(sce->ibuf, M_USBDEV);
- clist_free_cblocks(&sce->q);
- return (EIO);
- }
- DPRINTFN(5, ("ugenopen: interrupt open done\n"));
- break;
- case UE_BULK:
- err = usbd_open_pipe(sce->iface,
- edesc->bEndpointAddress, 0, &sce->pipeh);
- if (err)
- return (EIO);
- break;
- case UE_ISOCHRONOUS:
- if (dir == OUT)
- return (EINVAL);
- isize = UGETW(edesc->wMaxPacketSize);
- if (isize == 0) /* shouldn't happen */
- return (EINVAL);
- sce->ibuf = malloc(isize * UGEN_NISOFRAMES,
- M_USBDEV, M_WAITOK);
- sce->cur = sce->fill = sce->ibuf;
- sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES;
- DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
- endpt, isize));
- err = usbd_open_pipe(sce->iface,
- edesc->bEndpointAddress, 0, &sce->pipeh);
- if (err) {
- free(sce->ibuf, M_USBDEV);
- return (EIO);
- }
- for(i = 0; i < UGEN_NISOREQS; ++i) {
- sce->isoreqs[i].sce = sce;
- xfer = usbd_alloc_xfer(sc->sc_udev);
- if (xfer == 0)
- goto bad;
- sce->isoreqs[i].xfer = xfer;
- buf = usbd_alloc_buffer
- (xfer, isize * UGEN_NISORFRMS);
- if (buf == 0) {
- i++;
- goto bad;
- }
- sce->isoreqs[i].dmabuf = buf;
- for(j = 0; j < UGEN_NISORFRMS; ++j)
- sce->isoreqs[i].sizes[j] = isize;
- usbd_setup_isoc_xfer
- (xfer, sce->pipeh, &sce->isoreqs[i],
- sce->isoreqs[i].sizes,
- UGEN_NISORFRMS, USBD_NO_COPY,
- ugen_isoc_rintr);
- (void)usbd_transfer(xfer);
- }
- DPRINTFN(5, ("ugenopen: isoc open done\n"));
- break;
- bad:
- while (--i >= 0) /* implicit buffer free */
- usbd_free_xfer(sce->isoreqs[i].xfer);
- return (ENOMEM);
- case UE_CONTROL:
- sce->timeout = USBD_DEFAULT_TIMEOUT;
- return (EINVAL);
- }
- }
- sc->sc_is_open[endpt] = 1;
- UGEN_DEV_OPEN(dev, sc);
- return (0);
-}
-
-int
-ugenclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- int endpt = UGENENDPOINT(dev);
- struct ugen_softc *sc;
- struct ugen_endpoint *sce;
- int dir;
- int i;
-
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
-
- DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
- flag, mode, UGENUNIT(dev), endpt));
-
-#ifdef DIAGNOSTIC
- if (!sc->sc_is_open[endpt]) {
- printf("ugenclose: not open\n");
- return (EINVAL);
- }
-#endif
-
- if (endpt == USB_CONTROL_ENDPOINT) {
- DPRINTFN(5, ("ugenclose: close control\n"));
- sc->sc_is_open[endpt] = 0;
- UGEN_DEV_CLOSE(dev, sc);
- return (0);
- }
-
- for (dir = OUT; dir <= IN; dir++) {
- if (!(flag & (dir == OUT ? FWRITE : FREAD)))
- continue;
- sce = &sc->sc_endpoints[endpt][dir];
- if (sce->pipeh == NULL)
- continue;
- DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
- endpt, dir, sce));
-
- usbd_abort_pipe(sce->pipeh);
- usbd_close_pipe(sce->pipeh);
- sce->pipeh = NULL;
-
- switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
- case UE_INTERRUPT:
- ndflush(&sce->q, sce->q.c_cc);
- clist_free_cblocks(&sce->q);
- break;
- case UE_ISOCHRONOUS:
- for (i = 0; i < UGEN_NISOREQS; ++i)
- usbd_free_xfer(sce->isoreqs[i].xfer);
-
- default:
- break;
- }
-
- if (sce->ibuf != NULL) {
- free(sce->ibuf, M_USBDEV);
- sce->ibuf = NULL;
- clist_free_cblocks(&sce->q);
- }
- }
- sc->sc_is_open[endpt] = 0;
- UGEN_DEV_CLOSE(dev, sc);
-
- return (0);
-}
-
-static int
-ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
-{
- struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
- u_int32_t n, tn;
- char buf[UGEN_BBSIZE];
- usbd_xfer_handle xfer;
- usbd_status err;
- int s;
- int error = 0, doneone = 0;
- u_char buffer[UGEN_CHUNK];
-
- DPRINTFN(5, ("%s: ugenread: %d\n", device_get_nameunit(sc->sc_dev), endpt));
-
- if (sc->sc_dying)
- return (EIO);
-
- if (endpt == USB_CONTROL_ENDPOINT)
- return (ENODEV);
-
-#ifdef DIAGNOSTIC
- if (sce->edesc == NULL) {
- printf("ugenread: no edesc\n");
- return (EIO);
- }
- if (sce->pipeh == NULL) {
- printf("ugenread: no pipe\n");
- return (EIO);
- }
-#endif
-
- switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
- case UE_INTERRUPT:
- /* Block until activity occurred. */
- s = splusb();
- while (sce->q.c_cc == 0) {
- if (flag & O_NONBLOCK) {
- splx(s);
- return (EWOULDBLOCK);
- }
- sce->state |= UGEN_ASLP;
- DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
- error = tsleep(sce, PZERO | PCATCH, "ugenri",
- (sce->timeout * hz + 999) / 1000);
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
- if (sc->sc_dying)
- error = EIO;
- if (error == EAGAIN) {
- error = 0; /* timeout, return 0 bytes */
- break;
- }
- if (error)
- break;
- }
- splx(s);
-
- /* Transfer as many chunks as possible. */
- while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
- n = min(sce->q.c_cc, uio->uio_resid);
- if (n > sizeof(buffer))
- n = sizeof(buffer);
-
- /* Remove a small chunk from the input queue. */
- q_to_b(&sce->q, buffer, n);
- DPRINTFN(5, ("ugenread: got %d chars\n", n));
-
- /* Copy the data to the user process. */
- error = uiomove(buffer, n, uio);
- if (error)
- break;
- }
- break;
- case UE_BULK:
- xfer = usbd_alloc_xfer(sc->sc_udev);
- if (xfer == 0)
- return (ENOMEM);
- while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0 ||
- !doneone) {
- DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
- tn = n;
- doneone = 1;
- err = usbd_bulk_transfer(
- xfer, sce->pipeh,
- sce->state & UGEN_SHORT_OK ?
- USBD_SHORT_XFER_OK : 0,
- sce->timeout, buf, &tn, "ugenrb");
- if (err) {
- if (err == USBD_INTERRUPTED)
- error = EINTR;
- else if (err == USBD_TIMEOUT)
- error = ETIMEDOUT;
- else
- error = EIO;
- break;
- }
- DPRINTFN(1, ("ugenread: got %d bytes\n", tn));
- error = uiomove(buf, tn, uio);
- if (error || tn < n)
- break;
- }
- usbd_free_xfer(xfer);
- break;
- case UE_ISOCHRONOUS:
- s = splusb();
- while (sce->cur == sce->fill) {
- if (flag & O_NONBLOCK) {
- splx(s);
- return (EWOULDBLOCK);
- }
- sce->state |= UGEN_ASLP;
- DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
- error = tsleep(sce, PZERO | PCATCH, "ugenri",
- (sce->timeout * hz + 999) / 1000);
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
- if (sc->sc_dying)
- error = EIO;
- if (error == EAGAIN) {
- error = 0; /* timeout, return 0 bytes */
- break;
- }
- if (error)
- break;
- }
-
- while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) {
- if (sce->fill > sce->cur)
- n = min(sce->fill - sce->cur, uio->uio_resid);
- else
- n = min(sce->limit - sce->cur, uio->uio_resid);
-
- DPRINTFN(5, ("ugenread: isoc got %d chars\n", n));
-
- /* Copy the data to the user process. */
- error = uiomove(sce->cur, n, uio);
- if (error)
- break;
- sce->cur += n;
- if(sce->cur >= sce->limit)
- sce->cur = sce->ibuf;
- }
- splx(s);
- break;
-
-
- default:
- return (ENXIO);
- }
- return (error);
-}
-
-int
-ugenread(struct cdev *dev, struct uio *uio, int flag)
-{
- int endpt = UGENENDPOINT(dev);
- struct ugen_softc *sc;
- int error;
-
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
-
- if (sc->sc_dying)
- return (EIO);
-
- UGEN_DEV_REF(dev, sc);
- error = ugen_do_read(sc, endpt, uio, flag);
- UGEN_DEV_RELE(dev, sc);
- return (error);
-}
-
-static int
-ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
-{
- struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
- u_int32_t n;
- int error = 0, doneone = 0;
- char buf[UGEN_BBSIZE];
- usbd_xfer_handle xfer;
- usbd_status err;
-
- DPRINTFN(5, ("%s: ugenwrite: %d\n", device_get_nameunit(sc->sc_dev), endpt));
-
- if (sc->sc_dying)
- return (EIO);
-
- if (endpt == USB_CONTROL_ENDPOINT)
- return (ENODEV);
-
-#ifdef DIAGNOSTIC
- if (sce->edesc == NULL) {
- printf("ugenwrite: no edesc\n");
- return (EIO);
- }
- if (sce->pipeh == NULL) {
- printf("ugenwrite: no pipe\n");
- return (EIO);
- }
-#endif
-
- switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
- case UE_BULK:
- xfer = usbd_alloc_xfer(sc->sc_udev);
- if (xfer == 0)
- return (EIO);
- while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0 ||
- !doneone) {
- doneone = 1;
- error = uiomove(buf, n, uio);
- if (error)
- break;
- DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
- err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
- sce->timeout, buf, &n,"ugenwb");
- if (err) {
- if (err == USBD_INTERRUPTED)
- error = EINTR;
- else if (err == USBD_TIMEOUT)
- error = ETIMEDOUT;
- else
- error = EIO;
- break;
- }
- }
- usbd_free_xfer(xfer);
- break;
- case UE_INTERRUPT:
- xfer = usbd_alloc_xfer(sc->sc_udev);
- if (xfer == 0)
- return (EIO);
- while ((n = min(UGETW(sce->edesc->wMaxPacketSize),
- uio->uio_resid)) != 0 || !doneone) {
- doneone = 1;
- error = uiomove(buf, n, uio);
- if (error)
- break;
- DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
- err = usbd_intr_transfer(xfer, sce->pipeh, 0,
- sce->timeout, buf, &n, "ugenwi");
- if (err) {
- if (err == USBD_INTERRUPTED)
- error = EINTR;
- else if (err == USBD_TIMEOUT)
- error = ETIMEDOUT;
- else
- error = EIO;
- break;
- }
- }
- usbd_free_xfer(xfer);
- break;
- default:
- return (ENXIO);
- }
- return (error);
-}
-
-int
-ugenwrite(struct cdev *dev, struct uio *uio, int flag)
-{
- int endpt = UGENENDPOINT(dev);
- struct ugen_softc *sc;
- int error;
-
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
-
- if (sc->sc_dying)
- return (EIO);
-
- UGEN_DEV_REF(dev, sc);
- error = ugen_do_write(sc, endpt, uio, flag);
- UGEN_DEV_RELE(dev, sc);
- return (error);
-}
-
-void
-ugenpurge(struct cdev *dev)
-{
- int endpt = UGENENDPOINT(dev);
- struct ugen_endpoint *sce;
- struct ugen_softc *sc;
-
- if (endpt == USB_CONTROL_ENDPOINT)
- return;
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
- sce = &sc->sc_endpoints[endpt][IN];
- if (sce->pipeh)
- usbd_abort_pipe(sce->pipeh);
- if (sce->state & UGEN_ASLP) {
- DPRINTFN(5, ("ugenpurge: waking %p\n", sce));
- wakeup(sce);
- }
- selwakeuppri(&sce->rsel, PZERO);
-
- sce = &sc->sc_endpoints[endpt][OUT];
- if (sce->pipeh)
- usbd_abort_pipe(sce->pipeh);
- if (sce->state & UGEN_ASLP) {
- DPRINTFN(5, ("ugenpurge: waking %p\n", sce));
- wakeup(sce);
- }
- selwakeuppri(&sce->rsel, PZERO);
-}
-
-static int
-ugen_detach(device_t self)
-{
- struct ugen_softc *sc = device_get_softc(self);
- struct ugen_endpoint *sce;
- int i, dir;
-
- DPRINTF(("ugen_detach: sc=%p\n", sc));
-
- sc->sc_dying = 1;
- /* Abort all pipes. Causes processes waiting for transfer to wake. */
- for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
- for (dir = OUT; dir <= IN; dir++) {
- sce = &sc->sc_endpoints[i][dir];
- if (sce->pipeh)
- usbd_abort_pipe(sce->pipeh);
- selwakeuppri(&sce->rsel, PZERO);
- }
- }
-
- /* destroy the device for the control endpoint */
- destroy_dev(sc->dev);
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
- return (0);
-}
-
-static void
-ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
-{
- struct ugen_endpoint *sce = addr;
- /*struct ugen_softc *sc = sce->sc;*/
- u_int32_t count;
- u_char *ibuf;
-
- if (status == USBD_CANCELLED)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF(("ugenintr: status=%d\n", status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sce->pipeh);
- return;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
- ibuf = sce->ibuf;
-
- DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
- xfer, status, count));
- DPRINTFN(5, (" data = %02x %02x %02x\n",
- ibuf[0], ibuf[1], ibuf[2]));
-
- (void)b_to_q(ibuf, count, &sce->q);
-
- if (sce->state & UGEN_ASLP) {
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
- wakeup(sce);
- }
- selwakeuppri(&sce->rsel, PZERO);
-}
-
-static void
-ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
- usbd_status status)
-{
- struct isoreq *req = addr;
- struct ugen_endpoint *sce = req->sce;
- u_int32_t count, n;
- int i, isize;
-
- /* Return if we are aborting. */
- if (status == USBD_CANCELLED)
- return;
-
- usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
- DPRINTFN(5,("ugen_isoc_rintr: xfer %td, count=%d\n", req - sce->isoreqs,
- count));
-
- /* throw away oldest input if the buffer is full */
- if(sce->fill < sce->cur && sce->cur <= sce->fill + count) {
- sce->cur += count;
- if(sce->cur >= sce->limit)
- sce->cur = sce->ibuf + (sce->limit - sce->cur);
- DPRINTF(("ugen_isoc_rintr: throwing away %d bytes\n",
- count));
- }
-
- isize = UGETW(sce->edesc->wMaxPacketSize);
- for (i = 0; i < UGEN_NISORFRMS; i++) {
- u_int32_t actlen = req->sizes[i];
- char const *buf = (char const *)req->dmabuf + isize * i;
-
- /* copy data to buffer */
- while (actlen > 0) {
- n = min(actlen, sce->limit - sce->fill);
- memcpy(sce->fill, buf, n);
-
- buf += n;
- actlen -= n;
- sce->fill += n;
- if(sce->fill == sce->limit)
- sce->fill = sce->ibuf;
- }
-
- /* setup size for next transfer */
- req->sizes[i] = isize;
- }
-
- usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS,
- USBD_NO_COPY, ugen_isoc_rintr);
- (void)usbd_transfer(xfer);
-
- if (sce->state & UGEN_ASLP) {
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce));
- wakeup(sce);
- }
- selwakeuppri(&sce->rsel, PZERO);
-}
-
-static usbd_status
-ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno)
-{
- usbd_interface_handle iface;
- usb_endpoint_descriptor_t *ed;
- usbd_status err;
- struct ugen_endpoint *sce, **sce_cache;
- u_int8_t niface, nendpt, nendpt_cache, endptno, endpt;
- int dir;
-
- DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
-
- err = usbd_interface_count(sc->sc_udev, &niface);
- if (err)
- return (err);
- if (ifaceidx < 0 || ifaceidx >= niface)
- return (USBD_INVAL);
-
- err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
- if (err)
- return (err);
- err = usbd_endpoint_count(iface, &nendpt);
- if (err)
- return (err);
-
- /* store an array of endpoint descriptors to clear if the interface
- * change succeeds - these aren't available afterwards */
- sce_cache = malloc(sizeof(struct ugen_endpoint *) * nendpt, M_TEMP,
- M_WAITOK);
- nendpt_cache = nendpt;
-
- for (endptno = 0; endptno < nendpt; endptno++) {
- ed = usbd_interface2endpoint_descriptor(iface,endptno);
- endpt = ed->bEndpointAddress;
- dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
- sce_cache[endptno] = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
- }
-
- /* change setting */
- err = usbd_set_interface(iface, altno);
- if (err) {
- free(sce_cache, M_TEMP);
- return (err);
- }
- err = usbd_endpoint_count(iface, &nendpt);
- if (err)
- panic("ugen_set_interface: endpoint count failed");
-
- /* destroy the existing devices, we remake the new ones in a moment */
- ugen_destroy_devnodes(sc);
-
- /* now we can clear the old interface's ugen_endpoints */
- for (endptno = 0; endptno < nendpt_cache; endptno++) {
- sce = sce_cache[endptno];
- sce->sc = 0;
- sce->edesc = 0;
- sce->iface = 0;
- }
- free(sce_cache, M_TEMP);
-
- /* set the new interface's ugen_endpoints */
- for (endptno = 0; endptno < nendpt; endptno++) {
- ed = usbd_interface2endpoint_descriptor(iface,endptno);
- endpt = ed->bEndpointAddress;
- dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
- sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
- sce->sc = sc;
- sce->edesc = ed;
- sce->iface = iface;
- }
-
- /* make the new devices */
- ugen_make_devnodes(sc);
-
- return (0);
-}
-
-/* Retrieve a complete descriptor for a certain device and index. */
-static usb_config_descriptor_t *
-ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp)
-{
- usb_config_descriptor_t *cdesc, *tdesc, cdescr;
- int len;
- usbd_status err;
-
- if (index == USB_CURRENT_CONFIG_INDEX) {
- tdesc = usbd_get_config_descriptor(sc->sc_udev);
- len = UGETW(tdesc->wTotalLength);
- if (lenp)
- *lenp = len;
- cdesc = malloc(len, M_TEMP, M_WAITOK);
- memcpy(cdesc, tdesc, len);
- DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
- } else {
- err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
- if (err)
- return (0);
- len = UGETW(cdescr.wTotalLength);
- DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
- if (lenp)
- *lenp = len;
- cdesc = malloc(len, M_TEMP, M_WAITOK);
- err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
- if (err) {
- free(cdesc, M_TEMP);
- return (0);
- }
- }
- return (cdesc);
-}
-
-static int
-ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx)
-{
- usbd_interface_handle iface;
- usbd_status err;
-
- err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
- if (err)
- return (-1);
- return (usbd_get_interface_altindex(iface));
-}
-
-static int
-ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
- caddr_t addr, int flag, struct thread *p)
-{
- struct ugen_endpoint *sce;
- usbd_status err;
- usbd_interface_handle iface;
- struct usb_config_desc *cd;
- usb_config_descriptor_t *cdesc;
- struct usb_interface_desc *id;
- usb_interface_descriptor_t *idesc;
- struct usb_endpoint_desc *ed;
- usb_endpoint_descriptor_t *edesc;
- struct usb_alt_interface *ai;
- struct usb_string_desc *si;
- u_int8_t conf, alt;
-
- DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
- if (sc->sc_dying)
- return (EIO);
-
- switch (cmd) {
- case FIONBIO:
- case FIOASYNC:
- /* All handled in the upper FS layer. */
- return (0);
- case USB_SET_SHORT_XFER:
- if (endpt == USB_CONTROL_ENDPOINT)
- return (EINVAL);
- /* This flag only affects read */
- sce = &sc->sc_endpoints[endpt][IN];
-
- if (sce->pipeh == NULL) {
- printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n");
- return (EIO);
- }
-
- if (*(int *)addr)
- sce->state |= UGEN_SHORT_OK;
- else
- sce->state &= ~UGEN_SHORT_OK;
- return (0);
- case USB_SET_TIMEOUT:
- sce = &sc->sc_endpoints[endpt][IN];
- sce->timeout = *(int *)addr;
- sce = &sc->sc_endpoints[endpt][OUT];
- sce->timeout = *(int *)addr;
- return (0);
- default:
- break;
- }
-
- if (endpt != USB_CONTROL_ENDPOINT)
- return (EINVAL);
-
- switch (cmd) {
-#ifdef USB_DEBUG
- case USB_SETDEBUG:
- ugendebug = *(int *)addr;
- break;
-#endif
- case USB_GET_CONFIG:
- err = usbd_get_config(sc->sc_udev, &conf);
- if (err)
- return (EIO);
- *(int *)addr = conf;
- break;
- case USB_SET_CONFIG:
- if (!(flag & FWRITE))
- return (EPERM);
- err = ugen_set_config(sc, *(int *)addr);
- switch (err) {
- case USBD_NORMAL_COMPLETION:
- ugen_make_devnodes(sc);
- break;
- case USBD_IN_USE:
- return (EBUSY);
- default:
- return (EIO);
- }
- break;
- case USB_GET_ALTINTERFACE:
- ai = (struct usb_alt_interface *)addr;
- err = usbd_device2interface_handle(sc->sc_udev,
- ai->uai_interface_index, &iface);
- if (err)
- return (EINVAL);
- idesc = usbd_get_interface_descriptor(iface);
- if (idesc == NULL)
- return (EIO);
- ai->uai_alt_no = idesc->bAlternateSetting;
- break;
- case USB_SET_ALTINTERFACE:
- if (!(flag & FWRITE))
- return (EPERM);
- ai = (struct usb_alt_interface *)addr;
- err = usbd_device2interface_handle(sc->sc_udev,
- ai->uai_interface_index, &iface);
- if (err)
- return (EINVAL);
- err = ugen_set_interface(sc, ai->uai_interface_index,
- ai->uai_alt_no);
- if (err)
- return (EINVAL);
- break;
- case USB_GET_NO_ALT:
- ai = (struct usb_alt_interface *)addr;
- cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0);
- if (cdesc == NULL)
- return (EINVAL);
- idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0);
- if (idesc == NULL) {
- free(cdesc, M_TEMP);
- return (EINVAL);
- }
- ai->uai_alt_no = usbd_get_no_alts(cdesc,
- idesc->bInterfaceNumber);
- free(cdesc, M_TEMP);
- break;
- case USB_GET_DEVICE_DESC:
- *(usb_device_descriptor_t *)addr =
- *usbd_get_device_descriptor(sc->sc_udev);
- break;
- case USB_GET_CONFIG_DESC:
- cd = (struct usb_config_desc *)addr;
- cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0);
- if (cdesc == NULL)
- return (EINVAL);
- cd->ucd_desc = *cdesc;
- free(cdesc, M_TEMP);
- break;
- case USB_GET_INTERFACE_DESC:
- id = (struct usb_interface_desc *)addr;
- cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0);
- if (cdesc == NULL)
- return (EINVAL);
- if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX &&
- id->uid_alt_index == USB_CURRENT_ALT_INDEX)
- alt = ugen_get_alt_index(sc, id->uid_interface_index);
- else
- alt = id->uid_alt_index;
- idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt);
- if (idesc == NULL) {
- free(cdesc, M_TEMP);
- return (EINVAL);
- }
- id->uid_desc = *idesc;
- free(cdesc, M_TEMP);
- break;
- case USB_GET_ENDPOINT_DESC:
- ed = (struct usb_endpoint_desc *)addr;
- cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0);
- if (cdesc == NULL)
- return (EINVAL);
- if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX &&
- ed->ued_alt_index == USB_CURRENT_ALT_INDEX)
- alt = ugen_get_alt_index(sc, ed->ued_interface_index);
- else
- alt = ed->ued_alt_index;
- edesc = usbd_find_edesc(cdesc, ed->ued_interface_index,
- alt, ed->ued_endpoint_index);
- if (edesc == NULL) {
- free(cdesc, M_TEMP);
- return (EINVAL);
- }
- ed->ued_desc = *edesc;
- free(cdesc, M_TEMP);
- break;
- case USB_GET_FULL_DESC:
- {
- int len;
- struct iovec iov;
- struct uio uio;
- struct usb_full_desc *fd = (struct usb_full_desc *)addr;
- int error;
-
- cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len);
- if (len > fd->ufd_size)
- len = fd->ufd_size;
- iov.iov_base = (caddr_t)fd->ufd_data;
- iov.iov_len = len;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_resid = len;
- uio.uio_offset = 0;
- uio.uio_segflg = UIO_USERSPACE;
- uio.uio_rw = UIO_READ;
- uio.uio_td = p;
- error = uiomove((void *)cdesc, len, &uio);
- free(cdesc, M_TEMP);
- return (error);
- }
- case USB_GET_STRING_DESC: {
- int len;
- si = (struct usb_string_desc *)addr;
- err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
- si->usd_language_id, &si->usd_desc, &len);
- if (err)
- return (EINVAL);
- break;
- }
- case USB_DO_REQUEST:
- {
- struct usb_ctl_request *ur = (void *)addr;
- int len = UGETW(ur->ucr_request.wLength);
- struct iovec iov;
- struct uio uio;
- void *ptr = 0;
- int error = 0;
-
- if (!(flag & FWRITE))
- return (EPERM);
- /* Avoid requests that would damage the bus integrity. */
- if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
- ur->ucr_request.bRequest == UR_SET_ADDRESS) ||
- (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
- ur->ucr_request.bRequest == UR_SET_CONFIG) ||
- (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE &&
- ur->ucr_request.bRequest == UR_SET_INTERFACE))
- return (EINVAL);
-
- if (len < 0 || len > 32767)
- return (EINVAL);
- if (len != 0) {
- iov.iov_base = (caddr_t)ur->ucr_data;
- iov.iov_len = len;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_resid = len;
- uio.uio_offset = 0;
- uio.uio_segflg = UIO_USERSPACE;
- uio.uio_rw =
- ur->ucr_request.bmRequestType & UT_READ ?
- UIO_READ : UIO_WRITE;
- uio.uio_td = p;
- ptr = malloc(len, M_TEMP, M_WAITOK);
- if (uio.uio_rw == UIO_WRITE) {
- error = uiomove(ptr, len, &uio);
- if (error)
- goto ret;
- }
- }
- sce = &sc->sc_endpoints[endpt][IN];
- err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request,
- ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout);
- if (err) {
- error = EIO;
- goto ret;
- }
- if (len != 0) {
- if (uio.uio_rw == UIO_READ) {
- error = uiomove(ptr, len, &uio);
- if (error)
- goto ret;
- }
- }
- ret:
- if (ptr)
- free(ptr, M_TEMP);
- return (error);
- }
- case USB_GET_DEVICEINFO:
- usbd_fill_deviceinfo(sc->sc_udev,
- (struct usb_device_info *)addr, 1);
- break;
- case USB_RESET_DEVICE:
- err = usbd_reset_device(sc->sc_udev);
- if (err)
- return EIO;
- break;
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-int
-ugenioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
- struct thread *p)
-{
- int endpt = UGENENDPOINT(dev);
- struct ugen_softc *sc;
- int error;
-
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
-
- if (sc->sc_dying)
- return (EIO);
-
- UGEN_DEV_REF(dev, sc);
- error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
- UGEN_DEV_RELE(dev, sc);
- return (error);
-}
-
-int
-ugenpoll(struct cdev *dev, int events, struct thread *p)
-{
- struct ugen_softc *sc;
- struct ugen_endpoint *sce_in, *sce_out;
- usb_endpoint_descriptor_t *edesc;
- int revents = 0;
- int s;
-
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
-
- if (sc->sc_dying)
- return ((events & (POLLIN | POLLOUT | POLLRDNORM |
- POLLWRNORM)) | POLLHUP);
- /* Do not allow to poll a control endpoint */
- if (UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT)
- return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
-
- sce_in = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
- sce_out = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT];
- edesc = (sce_in->edesc != NULL) ? sce_in->edesc : sce_out->edesc;
- KASSERT(edesc != NULL, ("ugenpoll: NULL edesc"));
- if (sce_in->edesc == NULL || sce_in->pipeh == NULL)
- sce_in = NULL;
- if (sce_out->edesc == NULL || sce_out->pipeh == NULL)
- sce_out = NULL;
-
- s = splusb();
- switch (edesc->bmAttributes & UE_XFERTYPE) {
- case UE_INTERRUPT:
- if (sce_in != NULL && (events & (POLLIN | POLLRDNORM))) {
- if (sce_in->q.c_cc > 0)
- revents |= events & (POLLIN | POLLRDNORM);
- else
- selrecord(p, &sce_in->rsel);
- }
- if (sce_out != NULL && (events & (POLLOUT | POLLWRNORM))) {
- if (sce_out->q.c_cc > 0)
- revents |= events & (POLLOUT | POLLWRNORM);
- else
- selrecord(p, &sce_out->rsel);
- }
- break;
- case UE_ISOCHRONOUS:
- if (sce_in != NULL && (events & (POLLIN | POLLRDNORM))) {
- if (sce_in->cur != sce_in->fill)
- revents |= events & (POLLIN | POLLRDNORM);
- else
- selrecord(p, &sce_in->rsel);
- }
- if (sce_out != NULL && (events & (POLLOUT | POLLWRNORM))) {
- if (sce_out->cur != sce_out->fill)
- revents |= events & (POLLOUT | POLLWRNORM);
- else
- selrecord(p, &sce_out->rsel);
- }
- break;
- case UE_BULK:
- /*
- * We have no easy way of determining if a read will
- * yield any data or a write will happen.
- * Pretend they will.
- */
- revents |= events &
- (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
- break;
- default:
- break;
- }
- splx(s);
- return (revents);
-}
-
-DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0);
diff --git a/sys/legacy/dev/usb/ugraphire_rdesc.h b/sys/legacy/dev/usb/ugraphire_rdesc.h
deleted file mode 100644
index 9c5a0c1..0000000
--- a/sys/legacy/dev/usb/ugraphire_rdesc.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/* $NetBSD: usb/ugraphire_rdesc.h,v 1.1 2000/12/29 01:47:49 augustss Exp $ */
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2000 Nick Hibma <n_hibma@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-static const uByte uhid_graphire_report_descr[] = {
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x01, /* USAGE (Digitizer) */
- 0xa1, 0x01, /* COLLECTION (Application) */
- 0x85, 0x02, /* REPORT_ID (2) */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x01, /* USAGE (Digitizer) */
- 0xa1, 0x00, /* COLLECTION (Physical) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
- 0x09, 0x33, /* USAGE (Touch) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x44, /* USAGE (Barrel Switch) */
- 0x95, 0x02, /* REPORT_COUNT (2) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x00, /* USAGE (Undefined) */
- 0x95, 0x02, /* REPORT_COUNT (2) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */
- 0x09, 0x3c, /* USAGE (Invert) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x38, /* USAGE (Transducer Index) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x32, /* USAGE (In Range) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
- 0x09, 0x30, /* USAGE (X) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x26, 0xde, 0x27, /* LOGICAL_MAXIMUM (10206) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x31, /* USAGE (Y) */
- 0x26, 0xfe, 0x1c, /* LOGICAL_MAXIMUM (7422) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x30, /* USAGE (Tip Pressure) */
- 0x26, 0xff, 0x01, /* LOGICAL_MAXIMUM (511) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0xc0, /* END_COLLECTION */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x00, /* USAGE (Undefined) */
- 0x85, 0x02, /* REPORT_ID (2) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */
- 0x09, 0x00, /* USAGE (Undefined) */
- 0x85, 0x03, /* REPORT_ID (3) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */
- 0xc0, /* END_COLLECTION */
-};
-
-static const uByte uhid_graphire3_4x5_report_descr[] = {
- 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
- 0x09, 0x02, /* USAGE (Mouse) */
- 0xa1, 0x01, /* COLLECTION (Application) */
- 0x85, 0x01, /* REPORT_ID (1) */
- 0x09, 0x01, /* USAGE (Pointer) */
- 0xa1, 0x00, /* COLLECTION (Physical) */
- 0x05, 0x09, /* USAGE_PAGE (Button) */
- 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
- 0x29, 0x03, /* USAGE_MAXIMUM (Button 3) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
- 0x95, 0x03, /* REPORT_COUNT (3) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x05, /* REPORT_SIZE (5) */
- 0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */
- 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
- 0x09, 0x30, /* USAGE (X) */
- 0x09, 0x31, /* USAGE (Y) */
- 0x09, 0x38, /* USAGE (Wheel) */
- 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */
- 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */
- 0x75, 0x08, /* REPORT_SIZE (8) */
- 0x95, 0x03, /* REPORT_COUNT (3) */
- 0x81, 0x06, /* INPUT (Data,Var,Rel) */
- 0xc0, /* END_COLLECTION */
- 0xc0, /* END_COLLECTION */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x01, /* USAGE (Pointer) */
- 0xa1, 0x01, /* COLLECTION (Applicaption) */
- 0x85, 0x02, /* REPORT_ID (2) */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x01, /* USAGE (Digitizer) */
- 0xa1, 0x00, /* COLLECTION (Physical) */
- 0x09, 0x33, /* USAGE (Touch) */
- 0x09, 0x44, /* USAGE (Barrel Switch) */
- 0x09, 0x44, /* USAGE (Barrel Switch) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x95, 0x03, /* REPORT_COUNT (3) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x95, 0x02, /* REPORT_COUNT (2) */
- 0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */
- 0x09, 0x3c, /* USAGE (Invert) */
- 0x09, 0x38, /* USAGE (Transducer Index) */
- 0x09, 0x32, /* USAGE (In Range) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x95, 0x03, /* REPORT_COUNT (3) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
- 0x09, 0x30, /* USAGE (X) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x26, 0xde, 0x27, /* LOGICAL_MAXIMUM (10206) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x31, /* USAGE (Y) */
- 0x26, 0xfe, 0x1c, /* LOGICAL_MAXIMUM (7422) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x30, /* USAGE (Tip Pressure) */
- 0x26, 0xff, 0x01, /* LOGICAL_MAXIMUM (511) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0xc0, /* END_COLLECTION */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x00, /* USAGE (Undefined) */
- 0x85, 0x02, /* REPORT_ID (2) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */
- 0x09, 0x00, /* USAGE (Undefined) */
- 0x85, 0x03, /* REPORT_ID (3) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */
- 0xc0 /* END_COLLECTION */
-};
diff --git a/sys/legacy/dev/usb/uhci.c b/sys/legacy/dev/usb/uhci.c
deleted file mode 100644
index 4d4c61b..0000000
--- a/sys/legacy/dev/usb/uhci.c
+++ /dev/null
@@ -1,3704 +0,0 @@
-/* $NetBSD: uhci.c,v 1.170 2003/02/19 01:35:04 augustss Exp $ */
-
-/* Also already incorporated from NetBSD:
- * $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $
- * $NetBSD: uhci.c,v 1.173 2003/05/13 04:41:59 gson Exp $
- * $NetBSD: uhci.c,v 1.175 2003/09/12 16:18:08 mycroft Exp $
- * $NetBSD: uhci.c,v 1.176 2003/11/04 19:11:21 mycroft Exp $
- * $NetBSD: uhci.c,v 1.177 2003/12/29 08:17:10 toshii Exp $
- * $NetBSD: uhci.c,v 1.178 2004/03/02 16:32:05 martin Exp $
- * $NetBSD: uhci.c,v 1.180 2004/07/17 20:12:03 mycroft Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * USB Universal Host Controller driver.
- * Handles e.g. PIIX3 and PIIX4.
- *
- * UHCI spec: http://developer.intel.com/design/USB/UHCI11D.htm
- * USB spec: http://www.usb.org/developers/docs/usbspec.zip
- * PIIXn spec: ftp://download.intel.com/design/intarch/datashts/29055002.pdf
- * ftp://download.intel.com/design/intarch/datashts/29056201.pdf
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/endian.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#if defined(DIAGNOSTIC) && defined(__i386__)
-#include <machine/cpu.h>
-#endif
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-#include <machine/endian.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/uhcireg.h>
-#include <dev/usb/uhcivar.h>
-
-/* Use bandwidth reclamation for control transfers. Some devices choke on it. */
-/*#define UHCI_CTL_LOOP */
-
-#define delay(d) DELAY(d)
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-#ifdef USB_DEBUG
-uhci_softc_t *thesc;
-#define DPRINTF(x) if (uhcidebug) printf x
-#define DPRINTFN(n,x) if (uhcidebug>(n)) printf x
-int uhcidebug = 0;
-int uhcinoloop = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uhci, CTLFLAG_RW, 0, "USB uhci");
-SYSCTL_INT(_hw_usb_uhci, OID_AUTO, debug, CTLFLAG_RW,
- &uhcidebug, 0, "uhci debug level");
-SYSCTL_INT(_hw_usb_uhci, OID_AUTO, loop, CTLFLAG_RW,
- &uhcinoloop, 0, "uhci noloop");
-#define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct uhci_pipe {
- struct usbd_pipe pipe;
- int nexttoggle;
-
- u_char aborting;
- usbd_xfer_handle abortstart, abortend;
-
- /* Info needed for different pipe kinds. */
- union {
- /* Control pipe */
- struct {
- uhci_soft_qh_t *sqh;
- usb_dma_t reqdma;
- uhci_soft_td_t *setup, *stat;
- u_int length;
- } ctl;
- /* Interrupt pipe */
- struct {
- int npoll;
- int isread;
- uhci_soft_qh_t **qhs;
- } intr;
- /* Bulk pipe */
- struct {
- uhci_soft_qh_t *sqh;
- u_int length;
- int isread;
- } bulk;
- /* Iso pipe */
- struct iso {
- uhci_soft_td_t **stds;
- int next, inuse;
- } iso;
- } u;
-};
-
-static void uhci_globalreset(uhci_softc_t *);
-static usbd_status uhci_portreset(uhci_softc_t*, int);
-static void uhci_reset(uhci_softc_t *);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static void uhci_shutdown(void *v);
-static void uhci_power(int, void *);
-#endif
-static usbd_status uhci_run(uhci_softc_t *, int run);
-static uhci_soft_td_t *uhci_alloc_std(uhci_softc_t *);
-static void uhci_free_std(uhci_softc_t *, uhci_soft_td_t *);
-static uhci_soft_qh_t *uhci_alloc_sqh(uhci_softc_t *);
-static void uhci_free_sqh(uhci_softc_t *, uhci_soft_qh_t *);
-static usbd_status uhci_aux_dma_alloc(uhci_softc_t *, uhci_soft_td_t *,
- void *data, int len);
-static uhci_physaddr_t uhci_aux_dma_prepare(uhci_soft_td_t *, int);
-static void uhci_aux_dma_complete(uhci_soft_td_t *, int);
-#if 0
-static void uhci_enter_ctl_q(uhci_softc_t *, uhci_soft_qh_t *,
- uhci_intr_info_t *);
-static void uhci_exit_ctl_q(uhci_softc_t *, uhci_soft_qh_t *);
-#endif
-
-static void uhci_free_std_chain(uhci_softc_t *,
- uhci_soft_td_t *, uhci_soft_td_t *);
-static usbd_status uhci_alloc_std_chain(struct uhci_pipe *,
- uhci_softc_t *, int, int, u_int16_t,
- usbd_xfer_handle xfer,
- uhci_soft_td_t **, uhci_soft_td_t **);
-static void uhci_poll_hub(void *);
-static void uhci_waitintr(uhci_softc_t *, usbd_xfer_handle);
-static void uhci_check_intr(uhci_softc_t *, uhci_intr_info_t *);
-static void uhci_idone(uhci_intr_info_t *);
-
-static void uhci_abort_xfer(usbd_xfer_handle, usbd_status status);
-static void uhci_transfer_complete(usbd_xfer_handle xfer);
-
-static void uhci_timeout(void *);
-static void uhci_timeout_task(void *);
-static void uhci_add_ls_ctrl(uhci_softc_t *, uhci_soft_qh_t *);
-static void uhci_add_hs_ctrl(uhci_softc_t *, uhci_soft_qh_t *);
-static void uhci_add_bulk(uhci_softc_t *, uhci_soft_qh_t *);
-static void uhci_remove_ls_ctrl(uhci_softc_t *,uhci_soft_qh_t *);
-static void uhci_remove_hs_ctrl(uhci_softc_t *,uhci_soft_qh_t *);
-static void uhci_remove_bulk(uhci_softc_t *,uhci_soft_qh_t *);
-static int uhci_str(usb_string_descriptor_t *, int, char *);
-static void uhci_add_loop(uhci_softc_t *sc);
-static void uhci_rem_loop(uhci_softc_t *sc);
-
-static usbd_status uhci_setup_isoc(usbd_pipe_handle pipe);
-static void uhci_device_isoc_enter(usbd_xfer_handle);
-
-static usbd_status uhci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
-static void uhci_freem(struct usbd_bus *, usb_dma_t *);
-
-static usbd_xfer_handle uhci_allocx(struct usbd_bus *);
-static void uhci_freex(struct usbd_bus *, usbd_xfer_handle);
-
-static usbd_status uhci_device_ctrl_transfer(usbd_xfer_handle);
-static usbd_status uhci_device_ctrl_start(usbd_xfer_handle);
-static void uhci_device_ctrl_abort(usbd_xfer_handle);
-static void uhci_device_ctrl_close(usbd_pipe_handle);
-static void uhci_device_ctrl_done(usbd_xfer_handle);
-
-static usbd_status uhci_device_intr_transfer(usbd_xfer_handle);
-static usbd_status uhci_device_intr_start(usbd_xfer_handle);
-static void uhci_device_intr_abort(usbd_xfer_handle);
-static void uhci_device_intr_close(usbd_pipe_handle);
-static void uhci_device_intr_done(usbd_xfer_handle);
-
-static usbd_status uhci_device_bulk_transfer(usbd_xfer_handle);
-static usbd_status uhci_device_bulk_start(usbd_xfer_handle);
-static void uhci_device_bulk_abort(usbd_xfer_handle);
-static void uhci_device_bulk_close(usbd_pipe_handle);
-static void uhci_device_bulk_done(usbd_xfer_handle);
-
-static usbd_status uhci_device_isoc_transfer(usbd_xfer_handle);
-static usbd_status uhci_device_isoc_start(usbd_xfer_handle);
-static void uhci_device_isoc_abort(usbd_xfer_handle);
-static void uhci_device_isoc_close(usbd_pipe_handle);
-static void uhci_device_isoc_done(usbd_xfer_handle);
-
-static usbd_status uhci_root_ctrl_transfer(usbd_xfer_handle);
-static usbd_status uhci_root_ctrl_start(usbd_xfer_handle);
-static void uhci_root_ctrl_abort(usbd_xfer_handle);
-static void uhci_root_ctrl_close(usbd_pipe_handle);
-static void uhci_root_ctrl_done(usbd_xfer_handle);
-
-static usbd_status uhci_root_intr_transfer(usbd_xfer_handle);
-static usbd_status uhci_root_intr_start(usbd_xfer_handle);
-static void uhci_root_intr_abort(usbd_xfer_handle);
-static void uhci_root_intr_close(usbd_pipe_handle);
-static void uhci_root_intr_done(usbd_xfer_handle);
-
-static usbd_status uhci_open(usbd_pipe_handle);
-static void uhci_poll(struct usbd_bus *);
-static void uhci_softintr(void *);
-
-static usbd_status uhci_device_request(usbd_xfer_handle xfer);
-
-static void uhci_add_intr(uhci_softc_t *, uhci_soft_qh_t *);
-static void uhci_remove_intr(uhci_softc_t *, uhci_soft_qh_t *);
-static usbd_status uhci_device_setintr(uhci_softc_t *sc,
- struct uhci_pipe *pipe, int ival);
-
-static void uhci_device_clear_toggle(usbd_pipe_handle pipe);
-static void uhci_noop(usbd_pipe_handle pipe);
-
-static __inline uhci_soft_qh_t *uhci_find_prev_qh(uhci_soft_qh_t *,
- uhci_soft_qh_t *);
-
-#ifdef USB_DEBUG
-static void uhci_dump_all(uhci_softc_t *);
-static void uhci_dumpregs(uhci_softc_t *);
-static void uhci_dump_qhs(uhci_soft_qh_t *);
-static void uhci_dump_qh(uhci_soft_qh_t *);
-static void uhci_dump_tds(uhci_soft_td_t *);
-static void uhci_dump_td(uhci_soft_td_t *);
-static void uhci_dump_ii(uhci_intr_info_t *ii);
-void uhci_dump(void);
-#endif
-
-#define UBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
- BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
-#define UWRITE1(sc, r, x) \
- do { UBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); \
- } while (/*CONSTCOND*/0)
-#define UWRITE2(sc, r, x) \
- do { UBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); \
- } while (/*CONSTCOND*/0)
-#define UWRITE4(sc, r, x) \
- do { UBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); \
- } while (/*CONSTCOND*/0)
-#define UREAD1(sc, r) (UBARR(sc), bus_space_read_1((sc)->iot, (sc)->ioh, (r)))
-#define UREAD2(sc, r) (UBARR(sc), bus_space_read_2((sc)->iot, (sc)->ioh, (r)))
-#define UREAD4(sc, r) (UBARR(sc), bus_space_read_4((sc)->iot, (sc)->ioh, (r)))
-
-#define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd)
-#define UHCISTS(sc) UREAD2(sc, UHCI_STS)
-
-#define UHCI_RESET_TIMEOUT 100 /* ms, reset timeout */
-
-#define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK)
-
-#define UHCI_INTR_ENDPT 1
-
-struct usbd_bus_methods uhci_bus_methods = {
- uhci_open,
- uhci_softintr,
- uhci_poll,
- uhci_allocm,
- uhci_freem,
- uhci_allocx,
- uhci_freex,
-};
-
-struct usbd_pipe_methods uhci_root_ctrl_methods = {
- uhci_root_ctrl_transfer,
- uhci_root_ctrl_start,
- uhci_root_ctrl_abort,
- uhci_root_ctrl_close,
- uhci_noop,
- uhci_root_ctrl_done,
-};
-
-struct usbd_pipe_methods uhci_root_intr_methods = {
- uhci_root_intr_transfer,
- uhci_root_intr_start,
- uhci_root_intr_abort,
- uhci_root_intr_close,
- uhci_noop,
- uhci_root_intr_done,
-};
-
-struct usbd_pipe_methods uhci_device_ctrl_methods = {
- uhci_device_ctrl_transfer,
- uhci_device_ctrl_start,
- uhci_device_ctrl_abort,
- uhci_device_ctrl_close,
- uhci_noop,
- uhci_device_ctrl_done,
-};
-
-struct usbd_pipe_methods uhci_device_intr_methods = {
- uhci_device_intr_transfer,
- uhci_device_intr_start,
- uhci_device_intr_abort,
- uhci_device_intr_close,
- uhci_device_clear_toggle,
- uhci_device_intr_done,
-};
-
-struct usbd_pipe_methods uhci_device_bulk_methods = {
- uhci_device_bulk_transfer,
- uhci_device_bulk_start,
- uhci_device_bulk_abort,
- uhci_device_bulk_close,
- uhci_device_clear_toggle,
- uhci_device_bulk_done,
-};
-
-struct usbd_pipe_methods uhci_device_isoc_methods = {
- uhci_device_isoc_transfer,
- uhci_device_isoc_start,
- uhci_device_isoc_abort,
- uhci_device_isoc_close,
- uhci_noop,
- uhci_device_isoc_done,
-};
-
-#define uhci_add_intr_info(sc, ii) \
- LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ii), list)
-#define uhci_del_intr_info(ii) \
- do { \
- LIST_REMOVE((ii), list); \
- (ii)->list.le_prev = NULL; \
- } while (0)
-#define uhci_active_intr_info(ii) ((ii)->list.le_prev != NULL)
-
-static __inline uhci_soft_qh_t *
-uhci_find_prev_qh(uhci_soft_qh_t *pqh, uhci_soft_qh_t *sqh)
-{
- DPRINTFN(15,("uhci_find_prev_qh: pqh=%p sqh=%p\n", pqh, sqh));
-
- for (; pqh->hlink != sqh; pqh = pqh->hlink) {
-#if defined(DIAGNOSTIC) || defined(USB_DEBUG)
- if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) {
- printf("uhci_find_prev_qh: QH not found\n");
- return (NULL);
- }
-#endif
- }
- return (pqh);
-}
-
-void
-uhci_globalreset(uhci_softc_t *sc)
-{
- UHCICMD(sc, UHCI_CMD_GRESET); /* global reset */
- usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); /* wait a little */
- UHCICMD(sc, 0); /* do nothing */
-}
-
-usbd_status
-uhci_init(uhci_softc_t *sc)
-{
- usbd_status err;
- int i, j;
- uhci_soft_qh_t *clsqh, *chsqh, *bsqh, *sqh, *lsqh;
- uhci_soft_td_t *std;
-
- DPRINTFN(1,("uhci_init: start\n"));
-
-#ifdef USB_DEBUG
- thesc = sc;
-
- if (uhcidebug > 2)
- uhci_dumpregs(sc);
-#endif
-
- UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
- uhci_globalreset(sc); /* reset the controller */
- uhci_reset(sc);
-
- /* Allocate and initialize real frame array. */
- err = usb_allocmem(&sc->sc_bus,
- UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
- UHCI_FRAMELIST_ALIGN, &sc->sc_dma);
- if (err)
- return (err);
- sc->sc_pframes = KERNADDR(&sc->sc_dma, 0);
- UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */
- UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0)); /* set frame list*/
-
- /*
- * Allocate a TD, inactive, that hangs from the last QH.
- * This is to avoid a bug in the PIIX that makes it run berserk
- * otherwise.
- */
- std = uhci_alloc_std(sc);
- if (std == NULL)
- return (USBD_NOMEM);
- std->link.std = NULL;
- std->td.td_link = htole32(UHCI_PTR_T);
- std->td.td_status = htole32(0); /* inactive */
- std->td.td_token = htole32(0);
- std->td.td_buffer = htole32(0);
-
- /* Allocate the dummy QH marking the end and used for looping the QHs.*/
- lsqh = uhci_alloc_sqh(sc);
- if (lsqh == NULL)
- return (USBD_NOMEM);
- lsqh->hlink = NULL;
- lsqh->qh.qh_hlink = htole32(UHCI_PTR_T); /* end of QH chain */
- lsqh->elink = std;
- lsqh->qh.qh_elink = htole32(std->physaddr | UHCI_PTR_TD);
- sc->sc_last_qh = lsqh;
-
- /* Allocate the dummy QH where bulk traffic will be queued. */
- bsqh = uhci_alloc_sqh(sc);
- if (bsqh == NULL)
- return (USBD_NOMEM);
- bsqh->hlink = lsqh;
- bsqh->qh.qh_hlink = htole32(lsqh->physaddr | UHCI_PTR_QH);
- bsqh->elink = NULL;
- bsqh->qh.qh_elink = htole32(UHCI_PTR_T);
- sc->sc_bulk_start = sc->sc_bulk_end = bsqh;
-
- /* Allocate dummy QH where high speed control traffic will be queued. */
- chsqh = uhci_alloc_sqh(sc);
- if (chsqh == NULL)
- return (USBD_NOMEM);
- chsqh->hlink = bsqh;
- chsqh->qh.qh_hlink = htole32(bsqh->physaddr | UHCI_PTR_QH);
- chsqh->elink = NULL;
- chsqh->qh.qh_elink = htole32(UHCI_PTR_T);
- sc->sc_hctl_start = sc->sc_hctl_end = chsqh;
-
- /* Allocate dummy QH where control traffic will be queued. */
- clsqh = uhci_alloc_sqh(sc);
- if (clsqh == NULL)
- return (USBD_NOMEM);
- clsqh->hlink = chsqh;
- clsqh->qh.qh_hlink = htole32(chsqh->physaddr | UHCI_PTR_QH);
- clsqh->elink = NULL;
- clsqh->qh.qh_elink = htole32(UHCI_PTR_T);
- sc->sc_lctl_start = sc->sc_lctl_end = clsqh;
-
- /*
- * Make all (virtual) frame list pointers point to the interrupt
- * queue heads and the interrupt queue heads at the control
- * queue head and point the physical frame list to the virtual.
- */
- for(i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
- std = uhci_alloc_std(sc);
- sqh = uhci_alloc_sqh(sc);
- if (std == NULL || sqh == NULL)
- return (USBD_NOMEM);
- std->link.sqh = sqh;
- std->td.td_link = htole32(sqh->physaddr | UHCI_PTR_QH);
- std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */
- std->td.td_token = htole32(0);
- std->td.td_buffer = htole32(0);
- sqh->hlink = clsqh;
- sqh->qh.qh_hlink = htole32(clsqh->physaddr | UHCI_PTR_QH);
- sqh->elink = NULL;
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- sc->sc_vframes[i].htd = std;
- sc->sc_vframes[i].etd = std;
- sc->sc_vframes[i].hqh = sqh;
- sc->sc_vframes[i].eqh = sqh;
- for (j = i;
- j < UHCI_FRAMELIST_COUNT;
- j += UHCI_VFRAMELIST_COUNT)
- sc->sc_pframes[j] = htole32(std->physaddr);
- }
-
- LIST_INIT(&sc->sc_intrhead);
-
- STAILQ_INIT(&sc->sc_free_xfers);
-
- callout_init(&sc->sc_poll_handle, 0);
-
- /* Set up the bus struct. */
- sc->sc_bus.methods = &uhci_bus_methods;
- sc->sc_bus.pipe_size = sizeof(struct uhci_pipe);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- sc->sc_suspend = PWR_RESUME;
- sc->sc_powerhook = powerhook_establish(uhci_power, sc);
- sc->sc_shutdownhook = shutdownhook_establish(uhci_shutdown, sc);
-#endif
-
- DPRINTFN(1,("uhci_init: enabling\n"));
- UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
- UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */
-
- UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */
-
- return (uhci_run(sc, 1)); /* and here we go... */
-}
-
-int
-uhci_detach(struct uhci_softc *sc, int flags)
-{
- usbd_xfer_handle xfer;
- int rv = 0;
-
- sc->sc_dying = 1;
-
- UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
- uhci_run(sc, 0);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- powerhook_disestablish(sc->sc_powerhook);
- shutdownhook_disestablish(sc->sc_shutdownhook);
-#endif
-
- /* Free all xfers associated with this HC. */
- for (;;) {
- xfer = STAILQ_FIRST(&sc->sc_free_xfers);
- if (xfer == NULL)
- break;
- STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
- free(xfer, M_USB);
- }
-
- /* XXX free other data structures XXX */
- usb_freemem(&sc->sc_bus, &sc->sc_dma);
-
- return (rv);
-}
-
-usbd_status
-uhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
-{
- return (usb_allocmem(bus, size, 0, dma));
-}
-
-void
-uhci_freem(struct usbd_bus *bus, usb_dma_t *dma)
-{
- usb_freemem(bus, dma);
-}
-
-usbd_xfer_handle
-uhci_allocx(struct usbd_bus *bus)
-{
- struct uhci_softc *sc = (struct uhci_softc *)bus;
- usbd_xfer_handle xfer;
-
- xfer = STAILQ_FIRST(&sc->sc_free_xfers);
- if (xfer != NULL) {
- STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_FREE) {
- printf("uhci_allocx: xfer=%p not free, 0x%08x\n", xfer,
- xfer->busy_free);
- }
-#endif
- } else {
- xfer = malloc(sizeof(struct uhci_xfer), M_USB, M_NOWAIT);
- }
- if (xfer != NULL) {
- memset(xfer, 0, sizeof (struct uhci_xfer));
- UXFER(xfer)->iinfo.sc = sc;
- usb_init_task(&UXFER(xfer)->abort_task, uhci_timeout_task,
- xfer);
- UXFER(xfer)->uhci_xfer_flags = 0;
-#ifdef DIAGNOSTIC
- UXFER(xfer)->iinfo.isdone = 1;
- xfer->busy_free = XFER_BUSY;
-#endif
- }
- return (xfer);
-}
-
-void
-uhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
-{
- struct uhci_softc *sc = (struct uhci_softc *)bus;
-
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_BUSY) {
- printf("uhci_freex: xfer=%p not busy, 0x%08x\n", xfer,
- xfer->busy_free);
- return;
- }
- xfer->busy_free = XFER_FREE;
- if (!UXFER(xfer)->iinfo.isdone) {
- printf("uhci_freex: !isdone\n");
- return;
- }
-#endif
- STAILQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
-}
-
-/*
- * Shut down the controller when the system is going down.
- */
-void
-uhci_shutdown(void *v)
-{
- uhci_softc_t *sc = v;
-
- DPRINTF(("uhci_shutdown: stopping the HC\n"));
- uhci_run(sc, 0); /* stop the controller */
-}
-
-/*
- * Handle suspend/resume.
- *
- * We need to switch to polling mode here, because this routine is
- * called from an interrupt context. This is all right since we
- * are almost suspended anyway.
- */
-void
-uhci_power(int why, void *v)
-{
- uhci_softc_t *sc = v;
- int cmd;
- int s;
-
- s = splhardusb();
- cmd = UREAD2(sc, UHCI_CMD);
-
- DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n",
- sc, why, sc->sc_suspend, cmd));
-
- if (why != PWR_RESUME) {
-#ifdef USB_DEBUG
- if (uhcidebug > 2)
- uhci_dumpregs(sc);
-#endif
- if (sc->sc_intr_xfer != NULL)
- callout_stop(&sc->sc_poll_handle);
- sc->sc_bus.use_polling++;
- uhci_run(sc, 0); /* stop the controller */
- cmd &= ~UHCI_CMD_RS;
-
- /* save some state if BIOS doesn't */
- sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM);
- sc->sc_saved_sof = UREAD1(sc, UHCI_SOF);
-
- UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */
-
- UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter global suspend */
- usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
- sc->sc_suspend = why;
- sc->sc_bus.use_polling--;
- DPRINTF(("uhci_power: cmd=0x%x\n", UREAD2(sc, UHCI_CMD)));
- } else {
-#ifdef DIAGNOSTIC
- if (sc->sc_suspend == PWR_RESUME)
- printf("uhci_power: weird, resume without suspend.\n");
-#endif
- sc->sc_bus.use_polling++;
- sc->sc_suspend = why;
- UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
- uhci_globalreset(sc); /* reset the controller */
- uhci_reset(sc);
- if (cmd & UHCI_CMD_RS)
- uhci_run(sc, 0); /* in case BIOS has started it */
-
- uhci_globalreset(sc);
- uhci_reset(sc);
-
- /* restore saved state */
- UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0));
- UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum);
- UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
-
- UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force global resume */
- usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
- UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */
- UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
- UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */
- UHCICMD(sc, UHCI_CMD_MAXP);
- uhci_run(sc, 1); /* and start traffic again */
- usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
- sc->sc_bus.use_polling--;
- if (sc->sc_intr_xfer != NULL)
- callout_reset(&sc->sc_poll_handle, sc->sc_ival,
- uhci_poll_hub, sc->sc_intr_xfer);
-#ifdef USB_DEBUG
- if (uhcidebug > 2)
- uhci_dumpregs(sc);
-#endif
- }
- splx(s);
-}
-
-#ifdef USB_DEBUG
-static void
-uhci_dumpregs(uhci_softc_t *sc)
-{
- DPRINTFN(-1,("%s regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, "
- "flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n",
- device_get_nameunit(sc->sc_bus.bdev),
- UREAD2(sc, UHCI_CMD),
- UREAD2(sc, UHCI_STS),
- UREAD2(sc, UHCI_INTR),
- UREAD2(sc, UHCI_FRNUM),
- UREAD4(sc, UHCI_FLBASEADDR),
- UREAD1(sc, UHCI_SOF),
- UREAD2(sc, UHCI_PORTSC1),
- UREAD2(sc, UHCI_PORTSC2)));
-}
-
-void
-uhci_dump_td(uhci_soft_td_t *p)
-{
- char sbuf[128], sbuf2[128];
-
- DPRINTFN(-1,("TD(%p) at %08lx = link=0x%08lx status=0x%08lx "
- "token=0x%08lx buffer=0x%08lx\n",
- p, (long)p->physaddr,
- (long)le32toh(p->td.td_link),
- (long)le32toh(p->td.td_status),
- (long)le32toh(p->td.td_token),
- (long)le32toh(p->td.td_buffer)));
-
- bitmask_snprintf((u_int32_t)le32toh(p->td.td_link), "\20\1T\2Q\3VF",
- sbuf, sizeof(sbuf));
- bitmask_snprintf((u_int32_t)le32toh(p->td.td_status),
- "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27"
- "STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD",
- sbuf2, sizeof(sbuf2));
-
- DPRINTFN(-1,(" %s %s,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d,"
- "D=%d,maxlen=%d\n", sbuf, sbuf2,
- UHCI_TD_GET_ERRCNT(le32toh(p->td.td_status)),
- UHCI_TD_GET_ACTLEN(le32toh(p->td.td_status)),
- UHCI_TD_GET_PID(le32toh(p->td.td_token)),
- UHCI_TD_GET_DEVADDR(le32toh(p->td.td_token)),
- UHCI_TD_GET_ENDPT(le32toh(p->td.td_token)),
- UHCI_TD_GET_DT(le32toh(p->td.td_token)),
- UHCI_TD_GET_MAXLEN(le32toh(p->td.td_token))));
-}
-
-void
-uhci_dump_qh(uhci_soft_qh_t *sqh)
-{
- DPRINTFN(-1,("QH(%p) at %08x: hlink=%08x elink=%08x\n", sqh,
- (int)sqh->physaddr, le32toh(sqh->qh.qh_hlink),
- le32toh(sqh->qh.qh_elink)));
-}
-
-
-#if 1
-void
-uhci_dump(void)
-{
- uhci_dump_all(thesc);
-}
-#endif
-
-void
-uhci_dump_all(uhci_softc_t *sc)
-{
- uhci_dumpregs(sc);
- printf("intrs=%d\n", sc->sc_bus.no_intrs);
- /*printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);*/
- uhci_dump_qh(sc->sc_lctl_start);
-}
-
-
-void
-uhci_dump_qhs(uhci_soft_qh_t *sqh)
-{
- uhci_dump_qh(sqh);
-
- /* uhci_dump_qhs displays all the QHs and TDs from the given QH onwards
- * Traverses sideways first, then down.
- *
- * QH1
- * QH2
- * No QH
- * TD2.1
- * TD2.2
- * TD1.1
- * etc.
- *
- * TD2.x being the TDs queued at QH2 and QH1 being referenced from QH1.
- */
-
-
- if (sqh->hlink != NULL && !(le32toh(sqh->qh.qh_hlink) & UHCI_PTR_T))
- uhci_dump_qhs(sqh->hlink);
- else
- DPRINTF(("No QH\n"));
-
- if (sqh->elink != NULL && !(le32toh(sqh->qh.qh_elink) & UHCI_PTR_T))
- uhci_dump_tds(sqh->elink);
- else
- DPRINTF(("No TD\n"));
-}
-
-void
-uhci_dump_tds(uhci_soft_td_t *std)
-{
- uhci_soft_td_t *td;
-
- for(td = std; td != NULL; td = td->link.std) {
- uhci_dump_td(td);
-
- /* Check whether the link pointer in this TD marks
- * the link pointer as end of queue. This avoids
- * printing the free list in case the queue/TD has
- * already been moved there (seatbelt).
- */
- if (le32toh(td->td.td_link) & UHCI_PTR_T ||
- le32toh(td->td.td_link) == 0)
- break;
- }
-}
-
-static void
-uhci_dump_ii(uhci_intr_info_t *ii)
-{
- usbd_pipe_handle pipe;
- usb_endpoint_descriptor_t *ed;
- usbd_device_handle dev;
-
-#ifdef DIAGNOSTIC
-#define DONE ii->isdone
-#else
-#define DONE 0
-#endif
- if (ii == NULL) {
- printf("ii NULL\n");
- return;
- }
- if (ii->xfer == NULL) {
- printf("ii %p: done=%d xfer=NULL\n",
- ii, DONE);
- return;
- }
- pipe = ii->xfer->pipe;
- if (pipe == NULL) {
- printf("ii %p: done=%d xfer=%p pipe=NULL\n",
- ii, DONE, ii->xfer);
- return;
- }
- if (pipe->endpoint == NULL) {
- printf("ii %p: done=%d xfer=%p pipe=%p pipe->endpoint=NULL\n",
- ii, DONE, ii->xfer, pipe);
- return;
- }
- if (pipe->device == NULL) {
- printf("ii %p: done=%d xfer=%p pipe=%p pipe->device=NULL\n",
- ii, DONE, ii->xfer, pipe);
- return;
- }
- ed = pipe->endpoint->edesc;
- dev = pipe->device;
- printf("ii %p: done=%d xfer=%p dev=%p vid=0x%04x pid=0x%04x addr=%d pipe=%p ep=0x%02x attr=0x%02x\n",
- ii, DONE, ii->xfer, dev,
- UGETW(dev->ddesc.idVendor),
- UGETW(dev->ddesc.idProduct),
- dev->address, pipe,
- ed->bEndpointAddress, ed->bmAttributes);
-#undef DONE
-}
-
-void uhci_dump_iis(struct uhci_softc *sc);
-void
-uhci_dump_iis(struct uhci_softc *sc)
-{
- uhci_intr_info_t *ii;
-
- printf("intr_info list:\n");
- for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list))
- uhci_dump_ii(ii);
-}
-
-void iidump(void);
-void iidump(void) { uhci_dump_iis(thesc); }
-
-#endif
-
-/*
- * This routine is executed periodically and simulates interrupts
- * from the root controller interrupt pipe for port status change.
- */
-void
-uhci_poll_hub(void *addr)
-{
- usbd_xfer_handle xfer = addr;
- usbd_pipe_handle pipe = xfer->pipe;
- usbd_device_handle dev = pipe->device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
- int s;
- u_char *p;
-
- DPRINTFN(20, ("uhci_poll_hub\n"));
-
- callout_reset(&sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer);
-
- p = xfer->buffer;
- p[0] = 0;
- if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
- p[0] |= 1<<1;
- if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
- p[0] |= 1<<2;
- if (p[0] == 0)
- /* No change, try again in a while */
- return;
-
- xfer->actlen = 1;
- xfer->status = USBD_NORMAL_COMPLETION;
- s = splusb();
- dev->bus->intr_context++;
- uhci_transfer_complete(xfer);
- dev->bus->intr_context--;
- splx(s);
-}
-
-void
-uhci_root_intr_done(usbd_xfer_handle xfer)
-{
-}
-
-void
-uhci_root_ctrl_done(usbd_xfer_handle xfer)
-{
-}
-
-/*
- * Let the last QH loop back to the high speed control transfer QH.
- * This is what intel calls "bandwidth reclamation" and improves
- * USB performance a lot for some devices.
- * If we are already looping, just count it.
- */
-void
-uhci_add_loop(uhci_softc_t *sc) {
-#ifdef USB_DEBUG
- if (uhcinoloop)
- return;
-#endif
- if (++sc->sc_loops == 1) {
- DPRINTFN(5,("uhci_start_loop: add\n"));
- /* Note, we don't loop back the soft pointer. */
- sc->sc_last_qh->qh.qh_hlink =
- htole32(sc->sc_hctl_start->physaddr | UHCI_PTR_QH);
- }
-}
-
-void
-uhci_rem_loop(uhci_softc_t *sc) {
-#ifdef USB_DEBUG
- if (uhcinoloop)
- return;
-#endif
- if (--sc->sc_loops == 0) {
- DPRINTFN(5,("uhci_end_loop: remove\n"));
- sc->sc_last_qh->qh.qh_hlink = htole32(UHCI_PTR_T);
- }
-}
-
-/* Add high speed control QH, called at splusb(). */
-void
-uhci_add_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *eqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh));
- eqh = sc->sc_hctl_end;
- sqh->hlink = eqh->hlink;
- sqh->qh.qh_hlink = eqh->qh.qh_hlink;
- eqh->hlink = sqh;
- eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
- sc->sc_hctl_end = sqh;
-#ifdef UHCI_CTL_LOOP
- uhci_add_loop(sc);
-#endif
-}
-
-/* Remove high speed control QH, called at splusb(). */
-void
-uhci_remove_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *pqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_remove_hs_ctrl: sqh=%p\n", sqh));
-#ifdef UHCI_CTL_LOOP
- uhci_rem_loop(sc);
-#endif
- /*
- * The T bit should be set in the elink of the QH so that the HC
- * doesn't follow the pointer. This condition may fail if the
- * the transferred packet was short so that the QH still points
- * at the last used TD.
- * In this case we set the T bit and wait a little for the HC
- * to stop looking at the TD.
- */
- if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- delay(UHCI_QH_REMOVE_DELAY);
- }
-
- pqh = uhci_find_prev_qh(sc->sc_hctl_start, sqh);
- pqh->hlink = sqh->hlink;
- pqh->qh.qh_hlink = sqh->qh.qh_hlink;
- delay(UHCI_QH_REMOVE_DELAY);
- if (sc->sc_hctl_end == sqh)
- sc->sc_hctl_end = pqh;
-}
-
-/* Add low speed control QH, called at splusb(). */
-void
-uhci_add_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *eqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_add_ls_ctrl: sqh=%p\n", sqh));
- eqh = sc->sc_lctl_end;
- sqh->hlink = eqh->hlink;
- sqh->qh.qh_hlink = eqh->qh.qh_hlink;
- eqh->hlink = sqh;
- eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
- sc->sc_lctl_end = sqh;
-}
-
-/* Remove low speed control QH, called at splusb(). */
-void
-uhci_remove_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *pqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_remove_ls_ctrl: sqh=%p\n", sqh));
- /* See comment in uhci_remove_hs_ctrl() */
- if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- delay(UHCI_QH_REMOVE_DELAY);
- }
- pqh = uhci_find_prev_qh(sc->sc_lctl_start, sqh);
- pqh->hlink = sqh->hlink;
- pqh->qh.qh_hlink = sqh->qh.qh_hlink;
- delay(UHCI_QH_REMOVE_DELAY);
- if (sc->sc_lctl_end == sqh)
- sc->sc_lctl_end = pqh;
-}
-
-/* Add bulk QH, called at splusb(). */
-void
-uhci_add_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *eqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
- eqh = sc->sc_bulk_end;
- sqh->hlink = eqh->hlink;
- sqh->qh.qh_hlink = eqh->qh.qh_hlink;
- eqh->hlink = sqh;
- eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
- sc->sc_bulk_end = sqh;
- uhci_add_loop(sc);
-}
-
-/* Remove bulk QH, called at splusb(). */
-void
-uhci_remove_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *pqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh));
- uhci_rem_loop(sc);
- /* See comment in uhci_remove_hs_ctrl() */
- if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- delay(UHCI_QH_REMOVE_DELAY);
- }
- pqh = uhci_find_prev_qh(sc->sc_bulk_start, sqh);
- pqh->hlink = sqh->hlink;
- pqh->qh.qh_hlink = sqh->qh.qh_hlink;
- delay(UHCI_QH_REMOVE_DELAY);
- if (sc->sc_bulk_end == sqh)
- sc->sc_bulk_end = pqh;
-}
-
-static int uhci_intr1(uhci_softc_t *);
-
-int
-uhci_intr(void *arg)
-{
- uhci_softc_t *sc = arg;
-
- if (sc->sc_dying)
- return (0);
-
- DPRINTFN(15,("uhci_intr: real interrupt\n"));
- if (sc->sc_bus.use_polling) {
-#ifdef DIAGNOSTIC
- printf("uhci_intr: ignored interrupt while polling\n");
-#endif
- return (0);
- }
- return (uhci_intr1(sc));
-}
-
-int
-uhci_intr1(uhci_softc_t *sc)
-{
-
- int status;
- int ack;
-
- /*
- * It can happen that an interrupt will be delivered to
- * us before the device has been fully attached and the
- * softc struct has been configured. Usually this happens
- * when kldloading the USB support as a module after the
- * system has been booted. If we detect this condition,
- * we need to squelch the unwanted interrupts until we're
- * ready for them.
- */
- if (sc->sc_bus.bdev == NULL) {
- UWRITE2(sc, UHCI_STS, 0xFFFF); /* ack pending interrupts */
- uhci_run(sc, 0); /* stop the controller */
- UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
- return(0);
- }
-
-#ifdef USB_DEBUG
- if (uhcidebug > 15) {
- DPRINTF(("%s: uhci_intr1\n", device_get_nameunit(sc->sc_bus.bdev)));
- uhci_dumpregs(sc);
- }
-#endif
- status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS;
- if (status == 0) /* The interrupt was not for us. */
- return (0);
-
-#if defined(DIAGNOSTIC) && defined(__NetBSD__)
- if (sc->sc_suspend != PWR_RESUME)
- printf("uhci_intr: suspended sts=0x%x\n", status);
-#endif
-
- if (sc->sc_suspend != PWR_RESUME) {
- printf("%s: interrupt while not operating ignored\n",
- device_get_nameunit(sc->sc_bus.bdev));
- UWRITE2(sc, UHCI_STS, status); /* acknowledge the ints */
- return (0);
- }
-
- ack = 0;
- if (status & UHCI_STS_USBINT)
- ack |= UHCI_STS_USBINT;
- if (status & UHCI_STS_USBEI)
- ack |= UHCI_STS_USBEI;
- if (status & UHCI_STS_RD) {
- ack |= UHCI_STS_RD;
-#ifdef USB_DEBUG
- printf("%s: resume detect\n", device_get_nameunit(sc->sc_bus.bdev));
-#endif
- }
- if (status & UHCI_STS_HSE) {
- ack |= UHCI_STS_HSE;
- printf("%s: host system error\n", device_get_nameunit(sc->sc_bus.bdev));
- }
- if (status & UHCI_STS_HCPE) {
- ack |= UHCI_STS_HCPE;
- printf("%s: host controller process error\n",
- device_get_nameunit(sc->sc_bus.bdev));
- }
- if (status & UHCI_STS_HCH) {
- /* no acknowledge needed */
- if (!sc->sc_dying) {
- printf("%s: host controller halted\n",
- device_get_nameunit(sc->sc_bus.bdev));
-#ifdef USB_DEBUG
- uhci_dump_all(sc);
-#endif
- }
- sc->sc_dying = 1;
- }
-
- if (!ack)
- return (0); /* nothing to acknowledge */
- UWRITE2(sc, UHCI_STS, ack); /* acknowledge the ints */
-
- sc->sc_bus.no_intrs++;
- usb_schedsoftintr(&sc->sc_bus);
-
- DPRINTFN(15, ("%s: uhci_intr: exit\n", device_get_nameunit(sc->sc_bus.bdev)));
-
- return (1);
-}
-
-void
-uhci_softintr(void *v)
-{
- uhci_softc_t *sc = v;
- uhci_intr_info_t *ii, *nextii;
-
- DPRINTFN(10,("%s: uhci_softintr (%d)\n", device_get_nameunit(sc->sc_bus.bdev),
- sc->sc_bus.intr_context));
-
- sc->sc_bus.intr_context++;
-
- /*
- * Interrupts on UHCI really suck. When the host controller
- * interrupts because a transfer is completed there is no
- * way of knowing which transfer it was. You can scan down
- * the TDs and QHs of the previous frame to limit the search,
- * but that assumes that the interrupt was not delayed by more
- * than 1 ms, which may not always be true (e.g. after debug
- * output on a slow console).
- * We scan all interrupt descriptors to see if any have
- * completed.
- */
- LIST_FOREACH_SAFE(ii, &sc->sc_intrhead, list, nextii)
- uhci_check_intr(sc, ii);
-
-#ifdef USB_USE_SOFTINTR
- if (sc->sc_softwake) {
- sc->sc_softwake = 0;
- wakeup(&sc->sc_softwake);
- }
-#endif /* USB_USE_SOFTINTR */
-
- sc->sc_bus.intr_context--;
-}
-
-/* Check for an interrupt. */
-void
-uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii)
-{
- uhci_soft_td_t *std, *lstd;
- u_int32_t status;
-
- DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii));
-#ifdef DIAGNOSTIC
- if (ii == NULL) {
- printf("uhci_check_intr: no ii? %p\n", ii);
- return;
- }
-#endif
- if (ii->xfer->status == USBD_CANCELLED ||
- ii->xfer->status == USBD_TIMEOUT) {
- DPRINTF(("uhci_check_intr: aborted xfer=%p\n", ii->xfer));
- return;
- }
-
- if (ii->stdstart == NULL)
- return;
- lstd = ii->stdend;
-#ifdef DIAGNOSTIC
- if (lstd == NULL) {
- printf("uhci_check_intr: std==0\n");
- return;
- }
-#endif
- /*
- * If the last TD is still active we need to check whether there
- * is an error somewhere in the middle, or whether there was a
- * short packet (SPD and not ACTIVE).
- */
- if (le32toh(lstd->td.td_status) & UHCI_TD_ACTIVE) {
- DPRINTFN(12, ("uhci_check_intr: active ii=%p\n", ii));
- for (std = ii->stdstart; std != lstd; std = std->link.std) {
- status = le32toh(std->td.td_status);
- /* If there's an active TD the xfer isn't done. */
- if (status & UHCI_TD_ACTIVE)
- break;
- /* Any kind of error makes the xfer done. */
- if (status & UHCI_TD_STALLED)
- goto done;
- /* We want short packets, and it is short: it's done */
- if ((status & UHCI_TD_SPD) &&
- UHCI_TD_GET_ACTLEN(status) <
- UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token)))
- goto done;
- }
- DPRINTFN(12, ("uhci_check_intr: ii=%p std=%p still active\n",
- ii, ii->stdstart));
- return;
- }
- done:
- DPRINTFN(12, ("uhci_check_intr: ii=%p done\n", ii));
- callout_stop(&ii->xfer->timeout_handle);
- usb_rem_task(ii->xfer->pipe->device, &UXFER(ii->xfer)->abort_task);
- uhci_idone(ii);
-}
-
-/* Called at splusb() */
-void
-uhci_idone(uhci_intr_info_t *ii)
-{
- usbd_xfer_handle xfer = ii->xfer;
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- uhci_soft_td_t *std;
- u_int32_t status = 0, nstatus;
- int actlen;
-
- DPRINTFN(12, ("uhci_idone: ii=%p\n", ii));
-#ifdef DIAGNOSTIC
- {
- int s = splhigh();
- if (ii->isdone) {
- splx(s);
-#ifdef USB_DEBUG
- printf("uhci_idone: ii is done!\n ");
- uhci_dump_ii(ii);
-#else
- printf("uhci_idone: ii=%p is done!\n", ii);
-#endif
- return;
- }
- ii->isdone = 1;
- splx(s);
- }
-#endif
-
- if (xfer->nframes != 0) {
- /* Isoc transfer, do things differently. */
- uhci_soft_td_t **stds = upipe->u.iso.stds;
- int i, n, nframes, len;
-
- DPRINTFN(5,("uhci_idone: ii=%p isoc ready\n", ii));
-
- nframes = xfer->nframes;
- actlen = 0;
- n = UXFER(xfer)->curframe;
- for (i = 0; i < nframes; i++) {
- std = stds[n];
-#ifdef USB_DEBUG
- if (uhcidebug > 5) {
- DPRINTFN(-1,("uhci_idone: isoc TD %d\n", i));
- uhci_dump_td(std);
- }
-#endif
- if (++n >= UHCI_VFRAMELIST_COUNT)
- n = 0;
- status = le32toh(std->td.td_status);
- len = UHCI_TD_GET_ACTLEN(status);
- xfer->frlengths[i] = len;
- actlen += len;
- }
- upipe->u.iso.inuse -= nframes;
- xfer->actlen = actlen;
- xfer->status = USBD_NORMAL_COMPLETION;
- goto end;
- }
-
-#ifdef USB_DEBUG
- DPRINTFN(10, ("uhci_idone: ii=%p, xfer=%p, pipe=%p ready\n",
- ii, xfer, upipe));
- if (uhcidebug > 10)
- uhci_dump_tds(ii->stdstart);
-#endif
-
- /* The transfer is done, compute actual length and status. */
- actlen = 0;
- for (std = ii->stdstart; std != NULL; std = std->link.std) {
- nstatus = le32toh(std->td.td_status);
- if (nstatus & UHCI_TD_ACTIVE)
- break;
-
- status = nstatus;
- if (UHCI_TD_GET_PID(le32toh(std->td.td_token)) !=
- UHCI_TD_PID_SETUP)
- actlen += UHCI_TD_GET_ACTLEN(status);
- else {
- /*
- * UHCI will report CRCTO in addition to a STALL or NAK
- * for a SETUP transaction. See section 3.2.2, "TD
- * CONTROL AND STATUS".
- */
- if (status & (UHCI_TD_STALLED | UHCI_TD_NAK))
- status &= ~UHCI_TD_CRCTO;
- }
- }
- /* If there are left over TDs we need to update the toggle. */
- if (std != NULL)
- upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token));
-
- status &= UHCI_TD_ERROR;
- DPRINTFN(10, ("uhci_idone: actlen=%d, status=0x%x\n",
- actlen, status));
- xfer->actlen = actlen;
- if (status != 0) {
-#ifdef USB_DEBUG
- char sbuf[128];
-
- bitmask_snprintf((u_int32_t)status,
- "\20\22BITSTUFF\23CRCTO\24NAK\25"
- "BABBLE\26DBUFFER\27STALLED\30ACTIVE",
- sbuf, sizeof(sbuf));
-
- DPRINTFN((status == UHCI_TD_STALLED)*10,
- ("uhci_idone: error, addr=%d, endpt=0x%02x, "
- "status 0x%s\n",
- xfer->pipe->device->address,
- xfer->pipe->endpoint->edesc->bEndpointAddress,
- sbuf));
-#endif
-
- if (status == UHCI_TD_STALLED)
- xfer->status = USBD_STALLED;
- else
- xfer->status = USBD_IOERROR; /* more info XXX */
- } else {
- xfer->status = USBD_NORMAL_COMPLETION;
- }
-
- end:
- uhci_transfer_complete(xfer);
- DPRINTFN(12, ("uhci_idone: ii=%p done\n", ii));
-}
-
-/*
- * Called when a request does not complete.
- */
-void
-uhci_timeout(void *addr)
-{
- uhci_intr_info_t *ii = addr;
- struct uhci_xfer *uxfer = UXFER(ii->xfer);
- struct uhci_pipe *upipe = (struct uhci_pipe *)uxfer->xfer.pipe;
- uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus;
-
- DPRINTF(("uhci_timeout: uxfer=%p\n", uxfer));
-
- if (sc->sc_dying) {
- uhci_abort_xfer(&uxfer->xfer, USBD_TIMEOUT);
- return;
- }
-
- /* Execute the abort in a process context. */
- usb_add_task(uxfer->xfer.pipe->device, &uxfer->abort_task,
- USB_TASKQ_HC);
-}
-
-void
-uhci_timeout_task(void *addr)
-{
- usbd_xfer_handle xfer = addr;
- int s;
-
- DPRINTF(("uhci_timeout_task: xfer=%p\n", xfer));
-
- s = splusb();
- uhci_abort_xfer(xfer, USBD_TIMEOUT);
- splx(s);
-}
-
-/*
- * Wait here until controller claims to have an interrupt.
- * Then call uhci_intr and return. Use timeout to avoid waiting
- * too long.
- * Only used during boot when interrupts are not enabled yet.
- */
-void
-uhci_waitintr(uhci_softc_t *sc, usbd_xfer_handle xfer)
-{
- int timo = xfer->timeout;
- uhci_intr_info_t *ii;
-
- DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo));
-
- xfer->status = USBD_IN_PROGRESS;
- for (; timo >= 0; timo--) {
- usb_delay_ms(&sc->sc_bus, 1);
- DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
- if (UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS)
- uhci_intr1(sc);
- if (xfer->status != USBD_IN_PROGRESS)
- return;
- }
-
- /* Timeout */
- DPRINTF(("uhci_waitintr: timeout\n"));
- for (ii = LIST_FIRST(&sc->sc_intrhead);
- ii != NULL && ii->xfer != xfer;
- ii = LIST_NEXT(ii, list))
- ;
-#ifdef DIAGNOSTIC
- if (ii == NULL)
- panic("uhci_waitintr: lost intr_info");
-#endif
- uhci_idone(ii);
-}
-
-void
-uhci_poll(struct usbd_bus *bus)
-{
- uhci_softc_t *sc = (uhci_softc_t *)bus;
-
- if (UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS)
- uhci_intr1(sc);
-}
-
-void
-uhci_reset(uhci_softc_t *sc)
-{
- int n;
-
- UHCICMD(sc, UHCI_CMD_HCRESET);
- /* The reset bit goes low when the controller is done. */
- for (n = 0; n < UHCI_RESET_TIMEOUT &&
- (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++)
- usb_delay_ms(&sc->sc_bus, 1);
- if (n >= UHCI_RESET_TIMEOUT)
- printf("%s: controller did not reset\n",
- device_get_nameunit(sc->sc_bus.bdev));
-}
-
-usbd_status
-uhci_run(uhci_softc_t *sc, int run)
-{
- int s, n, running;
- u_int16_t cmd;
-
- run = run != 0;
- s = splhardusb();
- DPRINTF(("uhci_run: setting run=%d\n", run));
- cmd = UREAD2(sc, UHCI_CMD);
- if (run)
- cmd |= UHCI_CMD_RS;
- else
- cmd &= ~UHCI_CMD_RS;
- UHCICMD(sc, cmd);
- for(n = 0; n < 10; n++) {
- running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH);
- /* return when we've entered the state we want */
- if (run == running) {
- splx(s);
- DPRINTF(("uhci_run: done cmd=0x%x sts=0x%x\n",
- UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS)));
- return (USBD_NORMAL_COMPLETION);
- }
- usb_delay_ms(&sc->sc_bus, 1);
- }
- splx(s);
- printf("%s: cannot %s\n", device_get_nameunit(sc->sc_bus.bdev),
- run ? "start" : "stop");
- return (USBD_IOERROR);
-}
-
-/*
- * Memory management routines.
- * uhci_alloc_std allocates TDs
- * uhci_alloc_sqh allocates QHs
- * These two routines do their own free list management,
- * partly for speed, partly because allocating DMAable memory
- * has page size granularaity so much memory would be wasted if
- * only one TD/QH (32 bytes) was placed in each allocated chunk.
- */
-
-uhci_soft_td_t *
-uhci_alloc_std(uhci_softc_t *sc)
-{
- uhci_soft_td_t *std;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
-
- if (sc->sc_freetds == NULL) {
- DPRINTFN(2,("uhci_alloc_std: allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK,
- UHCI_TD_ALIGN, &dma);
- if (err)
- return (0);
- for(i = 0; i < UHCI_STD_CHUNK; i++) {
- offs = i * UHCI_STD_SIZE;
- std = KERNADDR(&dma, offs);
- std->physaddr = DMAADDR(&dma, offs);
- std->link.std = sc->sc_freetds;
- std->aux_dma.block = NULL;
- std->aux_data = NULL;
- std->aux_len = 0;
- sc->sc_freetds = std;
- }
- }
- std = sc->sc_freetds;
- sc->sc_freetds = std->link.std;
- memset(&std->td, 0, sizeof(uhci_td_t));
- return std;
-}
-
-void
-uhci_free_std(uhci_softc_t *sc, uhci_soft_td_t *std)
-{
-#ifdef DIAGNOSTIC
-#define TD_IS_FREE 0x12345678
- if (le32toh(std->td.td_token) == TD_IS_FREE) {
- printf("uhci_free_std: freeing free TD %p\n", std);
- return;
- }
- std->td.td_token = htole32(TD_IS_FREE);
-#endif
- if (std->aux_dma.block != NULL) {
- usb_freemem(&sc->sc_bus, &std->aux_dma);
- std->aux_dma.block = NULL;
- std->aux_data = NULL;
- std->aux_len = 0;
- }
- std->link.std = sc->sc_freetds;
- sc->sc_freetds = std;
-}
-
-uhci_soft_qh_t *
-uhci_alloc_sqh(uhci_softc_t *sc)
-{
- uhci_soft_qh_t *sqh;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
-
- if (sc->sc_freeqhs == NULL) {
- DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK,
- UHCI_QH_ALIGN, &dma);
- if (err)
- return (0);
- for(i = 0; i < UHCI_SQH_CHUNK; i++) {
- offs = i * UHCI_SQH_SIZE;
- sqh = KERNADDR(&dma, offs);
- sqh->physaddr = DMAADDR(&dma, offs);
- sqh->hlink = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh;
- }
- }
- sqh = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh->hlink;
- memset(&sqh->qh, 0, sizeof(uhci_qh_t));
- return (sqh);
-}
-
-void
-uhci_free_sqh(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- sqh->hlink = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh;
-}
-
-void
-uhci_free_std_chain(uhci_softc_t *sc, uhci_soft_td_t *std,
- uhci_soft_td_t *stdend)
-{
- uhci_soft_td_t *p;
-
- for (; std != stdend; std = p) {
- p = std->link.std;
- uhci_free_std(sc, std);
- }
-}
-
-usbd_status
-uhci_alloc_std_chain(struct uhci_pipe *upipe, uhci_softc_t *sc, int len,
- int rd, u_int16_t flags, usbd_xfer_handle xfer,
- uhci_soft_td_t **sp, uhci_soft_td_t **ep)
-{
- struct usb_dma_mapping *dma = &xfer->dmamap;
- uhci_soft_td_t *p, *prevp, *startp;
- int err, i, ntd, l, tog, maxp, seg, segoff;
- u_int32_t status;
- int addr = upipe->pipe.device->address;
- int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
-
- DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d speed=%d "
- "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len,
- upipe->pipe.device->speed, flags));
- maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize);
- if (maxp == 0) {
- printf("uhci_alloc_std_chain: maxp=0\n");
- return (USBD_INVAL);
- }
- ntd = (len + maxp - 1) / maxp;
- if (len == 0)
- flags |= USBD_FORCE_SHORT_XFER;
- if ((flags & USBD_FORCE_SHORT_XFER) && len % maxp == 0)
- ntd++;
- DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd));
- KASSERT(ntd > 0, ("uhci_alloc_std_chain: ntd=0"));
- tog = upipe->nexttoggle;
- prevp = NULL;
- startp = NULL;
- status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE);
- if (upipe->pipe.device->speed == USB_SPEED_LOW)
- status |= UHCI_TD_LS;
- if (flags & USBD_SHORT_XFER_OK)
- status |= UHCI_TD_SPD;
- seg = 0;
- segoff = 0;
- for (i = 0; i < ntd; i++) {
- p = uhci_alloc_std(sc);
- if (p == NULL) {
- uhci_free_std_chain(sc, startp, NULL);
- return (USBD_NOMEM);
- }
- p->link.std = NULL;
- if (prevp != NULL) {
- prevp->link.std = p;
- prevp->td.td_link = htole32(p->physaddr | UHCI_PTR_VF |
- UHCI_PTR_TD);
- } else {
- startp = p;
- }
- p->td.td_status = htole32(status);
- if (i == ntd - 1) {
- /* last TD */
- l = len % maxp;
- if (l == 0 && !(flags & USBD_FORCE_SHORT_XFER))
- l = maxp;
- *ep = p;
- } else
- l = maxp;
- p->td.td_token =
- htole32(rd ? UHCI_TD_IN (l, endpt, addr, tog) :
- UHCI_TD_OUT(l, endpt, addr, tog));
-
- KASSERT(seg < dma->nsegs || l == 0,
- ("uhci_alloc_std_chain: too few segments"));
- if (l == 0) {
- p->td.td_buffer = 0;
- } else if (l > dma->segs[seg].ds_len - segoff) {
- /* UHCI can't handle non-contiguous data. */
- err = uhci_aux_dma_alloc(sc, p, (char *)xfer->buffer +
- i * maxp, l);
- if (err) {
- uhci_free_std_chain(sc, startp, NULL);
- return (err);
- }
- p->td.td_buffer = htole32(uhci_aux_dma_prepare(p, rd));
- l -= dma->segs[seg].ds_len - segoff;
- seg++;
- KASSERT(seg < dma->nsegs,
- ("uhci_alloc_std_chain: too few segments 2"));
- segoff = 0;
- } else {
- p->td.td_buffer = htole32(dma->segs[seg].ds_addr +
- segoff);
- }
- segoff += l;
- if (l > 0 && segoff >= dma->segs[seg].ds_len) {
- KASSERT(segoff == dma->segs[seg].ds_len,
- ("uhci_alloc_std_chain: overlap"));
- if (i * maxp + l != len) {
- seg++;
- segoff = 0;
- }
- }
- prevp = p;
- tog ^= 1;
- }
- prevp->td.td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD);
- upipe->nexttoggle = tog;
- *sp = startp;
- DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n",
- upipe->nexttoggle));
- return (USBD_NORMAL_COMPLETION);
-}
-
-/*
- * Allocate a physically contiguous buffer to handle cases where UHCI
- * cannot handle a packet because it is not physically contiguous.
- * If the usb_dma_t was already allocated this just ensures it is
- * large enough for the specified size.
- */
-static usbd_status
-uhci_aux_dma_alloc(uhci_softc_t *sc, uhci_soft_td_t *std, void *data, int len)
-{
- int err, align;
-
- if (std->aux_dma.block == NULL || std->aux_dma.block->size < len) {
- /* Align to avoid crossing a page boundary. */
- if (powerof2(len))
- align = len;
- else
- align = 1 << fls(len);
-
- if (std->aux_dma.block != NULL)
- usb_freemem(&sc->sc_bus, &std->aux_dma);
- std->aux_dma.block = NULL;
- err = usb_allocmem(&sc->sc_bus, len, align, &std->aux_dma);
- if (err)
- return (err);
- }
- std->aux_data = data;
- std->aux_len = len;
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static uhci_physaddr_t
-uhci_aux_dma_prepare(uhci_soft_td_t *std, int isread)
-{
- if (!isread) {
- bcopy(std->aux_data, KERNADDR(&std->aux_dma, 0), std->aux_len);
- bus_dmamap_sync(std->aux_dma.block->tag,
- std->aux_dma.block->map, BUS_DMASYNC_PREWRITE);
- }
-
- return (DMAADDR(&std->aux_dma, 0));
-}
-
-static void
-uhci_aux_dma_complete(uhci_soft_td_t *std, int isread)
-{
- if (isread) {
- bus_dmamap_sync(std->aux_dma.block->tag,
- std->aux_dma.block->map, BUS_DMASYNC_POSTREAD);
- bcopy(KERNADDR(&std->aux_dma, 0), std->aux_data, std->aux_len);
- }
-}
-
-void
-uhci_device_clear_toggle(usbd_pipe_handle pipe)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- upipe->nexttoggle = 0;
-}
-
-void
-uhci_noop(usbd_pipe_handle pipe)
-{
-}
-
-usbd_status
-uhci_device_bulk_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (uhci_device_bulk_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-usbd_status
-uhci_device_bulk_start(usbd_xfer_handle xfer)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- usbd_device_handle dev = upipe->pipe.device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
- uhci_soft_td_t *data, *dataend;
- uhci_soft_qh_t *sqh;
- usbd_status err;
- int len, isread, endpt;
- int s;
-
- DPRINTFN(3, ("uhci_device_bulk_start: xfer=%p len=%d flags=%d ii=%p\n",
- xfer, xfer->length, xfer->flags, ii));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("uhci_device_bulk_transfer: a request");
-#endif
-
- len = xfer->length;
- endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- sqh = upipe->u.bulk.sqh;
-
- upipe->u.bulk.isread = isread;
- upipe->u.bulk.length = len;
-
- err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags, xfer,
- &data, &dataend);
- if (err)
- return (err);
- dataend->td.td_status |= htole32(UHCI_TD_IOC);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 8) {
- DPRINTF(("uhci_device_bulk_transfer: data(1)\n"));
- uhci_dump_tds(data);
- }
-#endif
-
- /* Set up interrupt info. */
- ii->xfer = xfer;
- ii->stdstart = data;
- ii->stdend = dataend;
-#ifdef DIAGNOSTIC
- if (!ii->isdone) {
- printf("uhci_device_bulk_transfer: not done, ii=%p\n", ii);
- }
- ii->isdone = 0;
-#endif
-
- sqh->elink = data;
- sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD);
-
- s = splusb();
- uhci_add_bulk(sc, sqh);
- uhci_add_intr_info(sc, ii);
-
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- uhci_timeout, ii);
- }
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 10) {
- DPRINTF(("uhci_device_bulk_transfer: data(2)\n"));
- uhci_dump_tds(data);
- }
-#endif
-
- if (sc->sc_bus.use_polling)
- uhci_waitintr(sc, xfer);
-
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a device bulk request. */
-void
-uhci_device_bulk_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("uhci_device_bulk_abort:\n"));
- uhci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/*
- * Abort a device request.
- * If this routine is called at splusb() it guarantees that the request
- * will be removed from the hardware scheduling and that the callback
- * for it will be called with USBD_CANCELLED status.
- * It's impossible to guarantee that the requested transfer will not
- * have happened since the hardware runs concurrently.
- * If the transaction has already happened we rely on the ordinary
- * interrupt processing to process it.
- */
-void
-uhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
-{
- struct uhci_xfer *uxfer = UXFER(xfer);
- uhci_intr_info_t *ii = &uxfer->iinfo;
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus;
- uhci_soft_td_t *std;
- int s;
-
- DPRINTFN(1,("uhci_abort_xfer: xfer=%p, status=%d\n", xfer, status));
-
- if (sc->sc_dying) {
- /* If we're dying, just do the software part. */
- s = splusb();
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(xfer->pipe->device, &UXFER(xfer)->abort_task);
- uhci_transfer_complete(xfer);
- splx(s);
- return;
- }
-
- if (xfer->device->bus->intr_context || !curproc)
- panic("uhci_abort_xfer: not in process context");
-
- /*
- * If an abort is already in progress then just wait for it to
- * complete and return.
- */
- if (uxfer->uhci_xfer_flags & UHCI_XFER_ABORTING) {
- DPRINTFN(2, ("uhci_abort_xfer: already aborting\n"));
- /* No need to wait if we're aborting from a timeout. */
- if (status == USBD_TIMEOUT)
- return;
- /* Override the status which might be USBD_TIMEOUT. */
- xfer->status = status;
- DPRINTFN(2, ("uhci_abort_xfer: waiting for abort to finish\n"));
- uxfer->uhci_xfer_flags |= UHCI_XFER_ABORTWAIT;
- while (uxfer->uhci_xfer_flags & UHCI_XFER_ABORTING)
- tsleep(&uxfer->uhci_xfer_flags, PZERO, "uhciaw", 0);
- return;
- }
-
- /*
- * Step 1: Make interrupt routine and hardware ignore xfer.
- */
- s = splusb();
- uxfer->uhci_xfer_flags |= UHCI_XFER_ABORTING;
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(xfer->pipe->device, &UXFER(xfer)->abort_task);
- DPRINTFN(1,("uhci_abort_xfer: stop ii=%p\n", ii));
- for (std = ii->stdstart; std != NULL; std = std->link.std)
- std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
- splx(s);
-
- /*
- * Step 2: Wait until we know hardware has finished any possible
- * use of the xfer. Also make sure the soft interrupt routine
- * has run.
- */
- usb_delay_ms(upipe->pipe.device->bus, 2); /* Hardware finishes in 1ms */
- s = splusb();
-#ifdef USB_USE_SOFTINTR
- sc->sc_softwake = 1;
-#endif /* USB_USE_SOFTINTR */
- usb_schedsoftintr(&sc->sc_bus);
-#ifdef USB_USE_SOFTINTR
- DPRINTFN(1,("uhci_abort_xfer: tsleep\n"));
- tsleep(&sc->sc_softwake, PZERO, "uhciab", 0);
-#endif /* USB_USE_SOFTINTR */
- splx(s);
-
- /*
- * Step 3: Execute callback.
- */
- DPRINTFN(1,("uhci_abort_xfer: callback\n"));
- s = splusb();
-#ifdef DIAGNOSTIC
- ii->isdone = 1;
-#endif
- /* Do the wakeup first to avoid touching the xfer after the callback. */
- uxfer->uhci_xfer_flags &= ~UHCI_XFER_ABORTING;
- if (uxfer->uhci_xfer_flags & UHCI_XFER_ABORTWAIT) {
- uxfer->uhci_xfer_flags &= ~UHCI_XFER_ABORTWAIT;
- wakeup(&uxfer->uhci_xfer_flags);
- }
- uhci_transfer_complete(xfer);
- splx(s);
-}
-
-/*
- * Perform any UHCI-specific transfer completion operations, then
- * call usb_transfer_complete().
- */
-static void
-uhci_transfer_complete(usbd_xfer_handle xfer)
-{
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- uhci_soft_td_t *p;
- int i, isread, n;
-
- /* XXX, must be an easier way to detect reads... */
- isread = ((xfer->rqflags & URQ_REQUEST) &&
- (xfer->request.bmRequestType & UT_READ)) ||
- (xfer->pipe->endpoint->edesc->bEndpointAddress & UE_DIR_IN);
-
- /* Copy back from any auxillary buffers after a read operation. */
- if (xfer->nframes == 0) {
- for (p = ii->stdstart; p != NULL; p = p->link.std) {
- if (p->aux_data != NULL)
- uhci_aux_dma_complete(p, isread);
- }
- } else {
- if (xfer->nframes != 0) {
- /* Isoc transfer, do things differently. */
- n = UXFER(xfer)->curframe;
- for (i = 0; i < xfer->nframes; i++) {
- p = upipe->u.iso.stds[n];
- if (p->aux_data != NULL)
- uhci_aux_dma_complete(p, isread);
- if (++n >= UHCI_VFRAMELIST_COUNT)
- n = 0;
- }
- }
- }
-
- usb_transfer_complete(xfer);
-}
-
-/* Close a device bulk pipe. */
-void
-uhci_device_bulk_close(usbd_pipe_handle pipe)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- usbd_device_handle dev = upipe->pipe.device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
-
- uhci_free_sqh(sc, upipe->u.bulk.sqh);
- pipe->endpoint->savedtoggle = upipe->nexttoggle;
-}
-
-usbd_status
-uhci_device_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (uhci_device_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-usbd_status
-uhci_device_ctrl_start(usbd_xfer_handle xfer)
-{
- uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST))
- panic("uhci_device_ctrl_transfer: not a request");
-#endif
-
- err = uhci_device_request(xfer);
- if (err)
- return (err);
-
- if (sc->sc_bus.use_polling)
- uhci_waitintr(sc, xfer);
- return (USBD_IN_PROGRESS);
-}
-
-usbd_status
-uhci_device_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (uhci_device_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-usbd_status
-uhci_device_intr_start(usbd_xfer_handle xfer)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- usbd_device_handle dev = upipe->pipe.device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
- uhci_soft_td_t *data, *dataend;
- uhci_soft_qh_t *sqh;
- usbd_status err;
- int isread, endpt;
- int i, s;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- DPRINTFN(3,("uhci_device_intr_transfer: xfer=%p len=%d flags=%d\n",
- xfer, xfer->length, xfer->flags));
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("uhci_device_intr_transfer: a request");
-#endif
-
- endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- sqh = upipe->u.bulk.sqh;
-
- upipe->u.intr.isread = isread;
-
- err = uhci_alloc_std_chain(upipe, sc, xfer->length, isread, xfer->flags,
- xfer, &data, &dataend);
- if (err)
- return (err);
- dataend->td.td_status |= htole32(UHCI_TD_IOC);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 10) {
- DPRINTF(("uhci_device_intr_transfer: data(1)\n"));
- uhci_dump_tds(data);
- uhci_dump_qh(upipe->u.intr.qhs[0]);
- }
-#endif
-
- s = splusb();
- /* Set up interrupt info. */
- ii->xfer = xfer;
- ii->stdstart = data;
- ii->stdend = dataend;
-#ifdef DIAGNOSTIC
- if (!ii->isdone) {
- printf("uhci_device_intr_transfer: not done, ii=%p\n", ii);
- }
- ii->isdone = 0;
-#endif
-
- DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n",
- upipe->u.intr.qhs[0]));
- for (i = 0; i < upipe->u.intr.npoll; i++) {
- sqh = upipe->u.intr.qhs[i];
- sqh->elink = data;
- sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD);
- }
- uhci_add_intr_info(sc, ii);
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 10) {
- DPRINTF(("uhci_device_intr_transfer: data(2)\n"));
- uhci_dump_tds(data);
- uhci_dump_qh(upipe->u.intr.qhs[0]);
- }
-#endif
-
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a device control request. */
-void
-uhci_device_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("uhci_device_ctrl_abort:\n"));
- uhci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/* Close a device control pipe. */
-void
-uhci_device_ctrl_close(usbd_pipe_handle pipe)
-{
-}
-
-/* Abort a device interrupt request. */
-void
-uhci_device_intr_abort(usbd_xfer_handle xfer)
-{
- DPRINTFN(1,("uhci_device_intr_abort: xfer=%p\n", xfer));
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTFN(1,("uhci_device_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
- uhci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/* Close a device interrupt pipe. */
-void
-uhci_device_intr_close(usbd_pipe_handle pipe)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
- int i, npoll;
- int s;
-
- /* Unlink descriptors from controller data structures. */
- npoll = upipe->u.intr.npoll;
- s = splusb();
- for (i = 0; i < npoll; i++)
- uhci_remove_intr(sc, upipe->u.intr.qhs[i]);
- splx(s);
-
- /*
- * We now have to wait for any activity on the physical
- * descriptors to stop.
- */
- usb_delay_ms(&sc->sc_bus, 2);
-
- for(i = 0; i < npoll; i++)
- uhci_free_sqh(sc, upipe->u.intr.qhs[i]);
- free(upipe->u.intr.qhs, M_USBHC);
-
- /* XXX free other resources */
-}
-
-usbd_status
-uhci_device_request(usbd_xfer_handle xfer)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- usb_device_request_t *req = &xfer->request;
- usbd_device_handle dev = upipe->pipe.device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
- int addr = dev->address;
- int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
- uhci_soft_td_t *setup, *data, *stat, *next, *dataend;
- uhci_soft_qh_t *sqh;
- int len;
- u_int32_t ls;
- usbd_status err;
- int isread;
- int s;
-
- DPRINTFN(3,("uhci_device_control type=0x%02x, request=0x%02x, "
- "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
- req->bmRequestType, req->bRequest, UGETW(req->wValue),
- UGETW(req->wIndex), UGETW(req->wLength),
- addr, endpt));
-
- ls = dev->speed == USB_SPEED_LOW ? UHCI_TD_LS : 0;
- isread = req->bmRequestType & UT_READ;
- len = UGETW(req->wLength);
-
- setup = upipe->u.ctl.setup;
- stat = upipe->u.ctl.stat;
- sqh = upipe->u.ctl.sqh;
-
- /* Set up data transaction */
- if (len != 0) {
- upipe->nexttoggle = 1;
- err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
- xfer, &data, &dataend);
- if (err)
- return (err);
- next = data;
- dataend->link.std = stat;
- dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_VF | UHCI_PTR_TD);
- } else {
- next = stat;
- }
- upipe->u.ctl.length = len;
-
- memcpy(KERNADDR(&upipe->u.ctl.reqdma, 0), req, sizeof *req);
-
- setup->link.std = next;
- setup->td.td_link = htole32(next->physaddr | UHCI_PTR_VF | UHCI_PTR_TD);
- setup->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls |
- UHCI_TD_ACTIVE);
- setup->td.td_token = htole32(UHCI_TD_SETUP(sizeof *req, endpt, addr));
- setup->td.td_buffer = htole32(DMAADDR(&upipe->u.ctl.reqdma, 0));
-
- stat->link.std = NULL;
- stat->td.td_link = htole32(UHCI_PTR_T);
- stat->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls |
- UHCI_TD_ACTIVE | UHCI_TD_IOC);
- stat->td.td_token =
- htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) :
- UHCI_TD_IN (0, endpt, addr, 1));
- stat->td.td_buffer = htole32(0);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 10) {
- DPRINTF(("uhci_device_request: before transfer\n"));
- uhci_dump_tds(setup);
- }
-#endif
-
- /* Set up interrupt info. */
- ii->xfer = xfer;
- ii->stdstart = setup;
- ii->stdend = stat;
-#ifdef DIAGNOSTIC
- if (!ii->isdone) {
- printf("uhci_device_request: not done, ii=%p\n", ii);
- }
- ii->isdone = 0;
-#endif
-
- sqh->elink = setup;
- sqh->qh.qh_elink = htole32(setup->physaddr | UHCI_PTR_TD);
-
- s = splusb();
- if (dev->speed == USB_SPEED_LOW)
- uhci_add_ls_ctrl(sc, sqh);
- else
- uhci_add_hs_ctrl(sc, sqh);
- uhci_add_intr_info(sc, ii);
-#ifdef USB_DEBUG
- if (uhcidebug > 12) {
- uhci_soft_td_t *std;
- uhci_soft_qh_t *xqh;
- uhci_soft_qh_t *sxqh;
- int maxqh = 0;
- uhci_physaddr_t link;
- DPRINTF(("uhci_enter_ctl_q: follow from [0]\n"));
- for (std = sc->sc_vframes[0].htd, link = 0;
- (link & UHCI_PTR_QH) == 0;
- std = std->link.std) {
- link = le32toh(std->td.td_link);
- uhci_dump_td(std);
- }
- sxqh = (uhci_soft_qh_t *)std;
- uhci_dump_qh(sxqh);
- for (xqh = sxqh;
- xqh != NULL;
- xqh = (maxqh++ == 5 || xqh->hlink == sxqh ||
- xqh->hlink == xqh ? NULL : xqh->hlink)) {
- uhci_dump_qh(xqh);
- }
- DPRINTF(("Enqueued QH:\n"));
- uhci_dump_qh(sqh);
- uhci_dump_tds(sqh->elink);
- }
-#endif
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- uhci_timeout, ii);
- }
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-uhci_device_isoc_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- DPRINTFN(5,("uhci_device_isoc_transfer: xfer=%p\n", xfer));
-
- /* Put it on our queue, */
- err = usb_insert_transfer(xfer);
-
- /* bail out on error, */
- if (err && err != USBD_IN_PROGRESS)
- return (err);
-
- /* XXX should check inuse here */
-
- /* insert into schedule, */
- uhci_device_isoc_enter(xfer);
-
- /* and start if the pipe wasn't running */
- if (!err)
- uhci_device_isoc_start(STAILQ_FIRST(&xfer->pipe->queue));
-
- return (err);
-}
-
-void
-uhci_device_isoc_enter(usbd_xfer_handle xfer)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- usbd_device_handle dev = upipe->pipe.device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
- struct iso *iso = &upipe->u.iso;
- uhci_soft_td_t *std;
- void *dataptr;
- u_int32_t len, status;
- int err, s, i, isread, next, nframes, seg, segoff;
-
- DPRINTFN(5,("uhci_device_isoc_enter: used=%d next=%d xfer=%p "
- "nframes=%d\n",
- iso->inuse, iso->next, xfer, xfer->nframes));
-
- if (sc->sc_dying)
- return;
-
- if (xfer->status == USBD_IN_PROGRESS) {
- /* This request has already been entered into the frame list */
- printf("uhci_device_isoc_enter: xfer=%p in frame list\n", xfer);
- /* XXX */
- }
-
-#ifdef DIAGNOSTIC
- if (iso->inuse >= UHCI_VFRAMELIST_COUNT)
- printf("uhci_device_isoc_enter: overflow!\n");
-#endif
-
- next = iso->next;
- if (next == -1) {
- /* Not in use yet, schedule it a few frames ahead. */
- next = (UREAD2(sc, UHCI_FRNUM) + 3) % UHCI_VFRAMELIST_COUNT;
- DPRINTFN(2,("uhci_device_isoc_enter: start next=%d\n", next));
- }
-
- xfer->status = USBD_IN_PROGRESS;
- UXFER(xfer)->curframe = next;
-
- seg = 0;
- segoff = 0;
- dataptr = xfer->allocbuf; /* Normal buffers not possible for isoc? */
- isread = xfer->pipe->endpoint->edesc->bEndpointAddress & UE_DIR_IN;
- status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) |
- UHCI_TD_ACTIVE |
- UHCI_TD_IOS);
- nframes = xfer->nframes;
- s = splusb();
- for (i = 0; i < nframes; i++) {
- std = iso->stds[next];
- if (++next >= UHCI_VFRAMELIST_COUNT)
- next = 0;
- len = xfer->frlengths[i];
- KASSERT(seg < xfer->dmamap.nsegs,
- ("uhci_device_isoc_enter: too few segments"));
- if (len + segoff > xfer->dmamap.segs[seg].ds_len) {
- /* UHCI can't handle non-contiguous data. */
- err = uhci_aux_dma_alloc(sc, std, dataptr, len);
- /* XXX */
- if (err)
- printf("uhci_device_isoc_enter: aux alloc\n");
- std->td.td_buffer = htole32(uhci_aux_dma_prepare(std,
- isread));
- segoff += len;
- while (segoff >= xfer->dmamap.segs[seg].ds_len) {
- KASSERT(seg < xfer->dmamap.nsegs - 1 ||
- segoff == xfer->dmamap.segs[seg].ds_len,
- ("uhci_device_isoc_enter: overlap2"));
- segoff -= xfer->dmamap.segs[seg].ds_len;
- seg++;
- }
- } else {
- std->td.td_buffer =
- htole32(xfer->dmamap.segs[seg].ds_addr + segoff);
- segoff += len;
- if (segoff >= xfer->dmamap.segs[seg].ds_len) {
- KASSERT(segoff == xfer->dmamap.segs[seg].ds_len,
- ("uhci_device_isoc_enter: overlap"));
- segoff = 0;
- seg++;
- }
- }
- if (i == nframes - 1)
- status |= UHCI_TD_IOC;
- std->td.td_status = htole32(status);
- std->td.td_token &= htole32(~UHCI_TD_MAXLEN_MASK);
- std->td.td_token |= htole32(UHCI_TD_SET_MAXLEN(len));
-#ifdef USB_DEBUG
- if (uhcidebug > 5) {
- DPRINTFN(5,("uhci_device_isoc_enter: TD %d\n", i));
- uhci_dump_td(std);
- }
-#endif
- dataptr = (char *)dataptr + len;
- }
- iso->next = next;
- iso->inuse += xfer->nframes;
-
- splx(s);
-}
-
-usbd_status
-uhci_device_isoc_start(usbd_xfer_handle xfer)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus;
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
- uhci_soft_td_t *end;
- int s, i;
-
- DPRINTFN(5,("uhci_device_isoc_start: xfer=%p\n", xfer));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (xfer->status != USBD_IN_PROGRESS)
- printf("uhci_device_isoc_start: not in progress %p\n", xfer);
-#endif
-
- /* Find the last TD */
- i = UXFER(xfer)->curframe + xfer->nframes;
- if (i >= UHCI_VFRAMELIST_COUNT)
- i -= UHCI_VFRAMELIST_COUNT;
- end = upipe->u.iso.stds[i];
-
-#ifdef DIAGNOSTIC
- if (end == NULL) {
- printf("uhci_device_isoc_start: end == NULL\n");
- return (USBD_INVAL);
- }
-#endif
-
- s = splusb();
-
- /* Set up interrupt info. */
- ii->xfer = xfer;
- ii->stdstart = end;
- ii->stdend = end;
-#ifdef DIAGNOSTIC
- if (!ii->isdone)
- printf("uhci_device_isoc_start: not done, ii=%p\n", ii);
- ii->isdone = 0;
-#endif
- uhci_add_intr_info(sc, ii);
-
- splx(s);
-
- return (USBD_IN_PROGRESS);
-}
-
-void
-uhci_device_isoc_abort(usbd_xfer_handle xfer)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- uhci_soft_td_t **stds = upipe->u.iso.stds;
- uhci_soft_td_t *std;
- int i, n, s, nframes, maxlen, len;
-
- s = splusb();
-
- /* Transfer is already done. */
- if (xfer->status != USBD_NOT_STARTED &&
- xfer->status != USBD_IN_PROGRESS) {
- splx(s);
- return;
- }
-
- /* Give xfer the requested abort code. */
- xfer->status = USBD_CANCELLED;
-
- /* make hardware ignore it, */
- nframes = xfer->nframes;
- n = UXFER(xfer)->curframe;
- maxlen = 0;
- for (i = 0; i < nframes; i++) {
- std = stds[n];
- std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
- len = UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token));
- if (len > maxlen)
- maxlen = len;
- if (++n >= UHCI_VFRAMELIST_COUNT)
- n = 0;
- }
-
- /* and wait until we are sure the hardware has finished. */
- delay(maxlen);
-
-#ifdef DIAGNOSTIC
- UXFER(xfer)->iinfo.isdone = 1;
-#endif
- /* Run callback and remove from interrupt list. */
- uhci_transfer_complete(xfer);
-
- splx(s);
-}
-
-void
-uhci_device_isoc_close(usbd_pipe_handle pipe)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- usbd_device_handle dev = upipe->pipe.device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
- uhci_soft_td_t *std, *vstd;
- struct iso *iso;
- int i, s;
-
- /*
- * Make sure all TDs are marked as inactive.
- * Wait for completion.
- * Unschedule.
- * Deallocate.
- */
- iso = &upipe->u.iso;
-
- for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++)
- iso->stds[i]->td.td_status &= htole32(~UHCI_TD_ACTIVE);
- usb_delay_ms(&sc->sc_bus, 2); /* wait for completion */
-
- s = splusb();
- for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
- std = iso->stds[i];
- for (vstd = sc->sc_vframes[i].htd;
- vstd != NULL && vstd->link.std != std;
- vstd = vstd->link.std)
- ;
- if (vstd == NULL) {
- /*panic*/
- printf("uhci_device_isoc_close: %p not found\n", std);
- splx(s);
- return;
- }
- vstd->link = std->link;
- vstd->td.td_link = std->td.td_link;
- uhci_free_std(sc, std);
- }
- splx(s);
-
- free(iso->stds, M_USBHC);
-}
-
-usbd_status
-uhci_setup_isoc(usbd_pipe_handle pipe)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- usbd_device_handle dev = upipe->pipe.device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
- int addr = upipe->pipe.device->address;
- int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
- int rd = UE_GET_DIR(endpt) == UE_DIR_IN;
- uhci_soft_td_t *std, *vstd;
- u_int32_t token;
- struct iso *iso;
- int i, s;
-
- iso = &upipe->u.iso;
- iso->stds = malloc(UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *),
- M_USBHC, M_WAITOK);
-
- token = rd ? UHCI_TD_IN (0, endpt, addr, 0) :
- UHCI_TD_OUT(0, endpt, addr, 0);
-
- /* Allocate the TDs and mark as inactive; */
- for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
- std = uhci_alloc_std(sc);
- if (std == 0)
- goto bad;
- std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */
- std->td.td_token = htole32(token);
- iso->stds[i] = std;
- }
-
- /* Insert TDs into schedule. */
- s = splusb();
- for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
- std = iso->stds[i];
- vstd = sc->sc_vframes[i].htd;
- std->link = vstd->link;
- std->td.td_link = vstd->td.td_link;
- vstd->link.std = std;
- vstd->td.td_link = htole32(std->physaddr | UHCI_PTR_TD);
- }
- splx(s);
-
- iso->next = -1;
- iso->inuse = 0;
-
- return (USBD_NORMAL_COMPLETION);
-
- bad:
- while (--i >= 0)
- uhci_free_std(sc, iso->stds[i]);
- free(iso->stds, M_USBHC);
- return (USBD_NOMEM);
-}
-
-void
-uhci_device_isoc_done(usbd_xfer_handle xfer)
-{
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
-
- DPRINTFN(4, ("uhci_isoc_done: length=%d\n", xfer->actlen));
-
- if (ii->xfer != xfer)
- /* Not on interrupt list, ignore it. */
- return;
-
- if (!uhci_active_intr_info(ii))
- return;
-
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_BUSY) {
- printf("uhci_device_isoc_done: xfer=%p not busy 0x%08x\n",
- xfer, xfer->busy_free);
- return;
- }
-
- if (ii->stdend == NULL) {
- printf("uhci_device_isoc_done: xfer=%p stdend==NULL\n", xfer);
-#ifdef USB_DEBUG
- uhci_dump_ii(ii);
-#endif
- return;
- }
-#endif
-
- /* Turn off the interrupt since it is active even if the TD is not. */
- ii->stdend->td.td_status &= htole32(~UHCI_TD_IOC);
-
- uhci_del_intr_info(ii); /* remove from active list */
-
-#ifdef DIAGNOSTIC
- if (ii->stdend == NULL) {
- printf("uhci_device_isoc_done: xfer=%p stdend==NULL\n", xfer);
-#ifdef USB_DEBUG
- uhci_dump_ii(ii);
-#endif
- return;
- }
-#endif
- ii->stdstart = NULL;
- ii->stdend = NULL;
-}
-
-void
-uhci_device_intr_done(usbd_xfer_handle xfer)
-{
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
- uhci_softc_t *sc = ii->sc;
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- uhci_soft_qh_t *sqh;
- int i, npoll;
-
- DPRINTFN(5, ("uhci_device_intr_done: length=%d\n", xfer->actlen));
-
- npoll = upipe->u.intr.npoll;
- for(i = 0; i < npoll; i++) {
- sqh = upipe->u.intr.qhs[i];
- sqh->elink = NULL;
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- }
- uhci_free_std_chain(sc, ii->stdstart, NULL);
-
- /* XXX Wasteful. */
- if (xfer->pipe->repeat) {
- uhci_soft_td_t *data, *dataend;
-
- DPRINTFN(5,("uhci_device_intr_done: requeing\n"));
-
- /* This alloc cannot fail since we freed the chain above. */
- uhci_alloc_std_chain(upipe, sc, xfer->length,
- upipe->u.intr.isread, xfer->flags, xfer,
- &data, &dataend);
- dataend->td.td_status |= htole32(UHCI_TD_IOC);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 10) {
- DPRINTF(("uhci_device_intr_done: data(1)\n"));
- uhci_dump_tds(data);
- uhci_dump_qh(upipe->u.intr.qhs[0]);
- }
-#endif
-
- ii->stdstart = data;
- ii->stdend = dataend;
-#ifdef DIAGNOSTIC
- if (!ii->isdone) {
- printf("uhci_device_intr_done: not done, ii=%p\n", ii);
- }
- ii->isdone = 0;
-#endif
- for (i = 0; i < npoll; i++) {
- sqh = upipe->u.intr.qhs[i];
- sqh->elink = data;
- sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD);
- }
- xfer->status = USBD_IN_PROGRESS;
- /* The ii is already on the examined list, just leave it. */
- } else {
- DPRINTFN(5,("uhci_device_intr_done: removing\n"));
- if (uhci_active_intr_info(ii)) {
- uhci_del_intr_info(ii);
- ii->stdstart = NULL;
- ii->stdend = NULL;
- }
- }
-}
-
-/* Deallocate request data structures */
-void
-uhci_device_ctrl_done(usbd_xfer_handle xfer)
-{
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
- uhci_softc_t *sc = ii->sc;
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST))
- panic("uhci_device_ctrl_done: not a request");
-#endif
-
- if (!uhci_active_intr_info(ii))
- return;
-
- uhci_del_intr_info(ii); /* remove from active list */
-
- if (upipe->pipe.device->speed == USB_SPEED_LOW)
- uhci_remove_ls_ctrl(sc, upipe->u.ctl.sqh);
- else
- uhci_remove_hs_ctrl(sc, upipe->u.ctl.sqh);
-
- if (upipe->u.ctl.length != 0)
- uhci_free_std_chain(sc, ii->stdstart->link.std, ii->stdend);
- ii->stdstart = NULL;
- ii->stdend = NULL;
-
- DPRINTFN(5, ("uhci_device_ctrl_done: length=%d\n", xfer->actlen));
-}
-
-/* Deallocate request data structures */
-void
-uhci_device_bulk_done(usbd_xfer_handle xfer)
-{
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
- uhci_softc_t *sc = ii->sc;
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
-
- DPRINTFN(5,("uhci_device_bulk_done: xfer=%p ii=%p sc=%p upipe=%p\n",
- xfer, ii, sc, upipe));
-
- if (!uhci_active_intr_info(ii))
- return;
-
- uhci_del_intr_info(ii); /* remove from active list */
-
- uhci_remove_bulk(sc, upipe->u.bulk.sqh);
-
- uhci_free_std_chain(sc, ii->stdstart, NULL);
- ii->stdstart = NULL;
- ii->stdend = NULL;
-
- DPRINTFN(5, ("uhci_device_bulk_done: length=%d\n", xfer->actlen));
-}
-
-/* Add interrupt QH, called with vflock. */
-void
-uhci_add_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos];
- uhci_soft_qh_t *eqh;
-
- DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", sqh->pos, sqh));
-
- eqh = vf->eqh;
- sqh->hlink = eqh->hlink;
- sqh->qh.qh_hlink = eqh->qh.qh_hlink;
- eqh->hlink = sqh;
- eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
- vf->eqh = sqh;
- vf->bandwidth++;
-}
-
-/* Remove interrupt QH. */
-void
-uhci_remove_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos];
- uhci_soft_qh_t *pqh;
-
- DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", sqh->pos, sqh));
-
- /* See comment in uhci_remove_ctrl() */
- if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- delay(UHCI_QH_REMOVE_DELAY);
- }
-
- pqh = uhci_find_prev_qh(vf->hqh, sqh);
- pqh->hlink = sqh->hlink;
- pqh->qh.qh_hlink = sqh->qh.qh_hlink;
- delay(UHCI_QH_REMOVE_DELAY);
- if (vf->eqh == sqh)
- vf->eqh = pqh;
- vf->bandwidth--;
-}
-
-usbd_status
-uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *upipe, int ival)
-{
- uhci_soft_qh_t *sqh;
- int i, npoll, s;
- u_int bestbw, bw, bestoffs, offs;
-
- DPRINTFN(2, ("uhci_device_setintr: pipe=%p\n", upipe));
- if (ival == 0) {
- printf("uhci_setintr: 0 interval\n");
- return (USBD_INVAL);
- }
-
- if (ival > UHCI_VFRAMELIST_COUNT)
- ival = UHCI_VFRAMELIST_COUNT;
- npoll = (UHCI_VFRAMELIST_COUNT + ival - 1) / ival;
- DPRINTFN(2, ("uhci_device_setintr: ival=%d npoll=%d\n", ival, npoll));
-
- upipe->u.intr.npoll = npoll;
- upipe->u.intr.qhs =
- malloc(npoll * sizeof(uhci_soft_qh_t *), M_USBHC, M_WAITOK);
-
- /*
- * Figure out which offset in the schedule that has most
- * bandwidth left over.
- */
-#define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1))
- for (bestoffs = offs = 0, bestbw = ~0; offs < ival; offs++) {
- for (bw = i = 0; i < npoll; i++)
- bw += sc->sc_vframes[MOD(i * ival + offs)].bandwidth;
- if (bw < bestbw) {
- bestbw = bw;
- bestoffs = offs;
- }
- }
- DPRINTFN(1, ("uhci_device_setintr: bw=%d offs=%d\n", bestbw, bestoffs));
-
- for(i = 0; i < npoll; i++) {
- upipe->u.intr.qhs[i] = sqh = uhci_alloc_sqh(sc);
- sqh->elink = NULL;
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- sqh->pos = MOD(i * ival + bestoffs);
- }
-#undef MOD
-
- s = splusb();
- /* Enter QHs into the controller data structures. */
- for(i = 0; i < npoll; i++)
- uhci_add_intr(sc, upipe->u.intr.qhs[i]);
- splx(s);
-
- DPRINTFN(5, ("uhci_device_setintr: returns %p\n", upipe));
- return (USBD_NORMAL_COMPLETION);
-}
-
-/* Open a new pipe. */
-usbd_status
-uhci_open(usbd_pipe_handle pipe)
-{
- uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
- usbd_status err;
- int ival;
-
- DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
- pipe, pipe->device->address,
- ed->bEndpointAddress, sc->sc_addr));
-
- upipe->aborting = 0;
- upipe->nexttoggle = pipe->endpoint->savedtoggle;
-
- if (pipe->device->address == sc->sc_addr) {
- switch (ed->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &uhci_root_ctrl_methods;
- break;
- case UE_DIR_IN | UHCI_INTR_ENDPT:
- pipe->methods = &uhci_root_intr_methods;
- break;
- default:
- return (USBD_INVAL);
- }
- } else {
- switch (ed->bmAttributes & UE_XFERTYPE) {
- case UE_CONTROL:
- pipe->methods = &uhci_device_ctrl_methods;
- upipe->u.ctl.sqh = uhci_alloc_sqh(sc);
- if (upipe->u.ctl.sqh == NULL)
- goto bad;
- upipe->u.ctl.setup = uhci_alloc_std(sc);
- if (upipe->u.ctl.setup == NULL) {
- uhci_free_sqh(sc, upipe->u.ctl.sqh);
- goto bad;
- }
- upipe->u.ctl.stat = uhci_alloc_std(sc);
- if (upipe->u.ctl.stat == NULL) {
- uhci_free_sqh(sc, upipe->u.ctl.sqh);
- uhci_free_std(sc, upipe->u.ctl.setup);
- goto bad;
- }
- err = usb_allocmem(&sc->sc_bus,
- sizeof(usb_device_request_t),
- 0, &upipe->u.ctl.reqdma);
- if (err) {
- uhci_free_sqh(sc, upipe->u.ctl.sqh);
- uhci_free_std(sc, upipe->u.ctl.setup);
- uhci_free_std(sc, upipe->u.ctl.stat);
- goto bad;
- }
- break;
- case UE_INTERRUPT:
- pipe->methods = &uhci_device_intr_methods;
- ival = pipe->interval;
- if (ival == USBD_DEFAULT_INTERVAL)
- ival = ed->bInterval;
- return (uhci_device_setintr(sc, upipe, ival));
- case UE_ISOCHRONOUS:
- pipe->methods = &uhci_device_isoc_methods;
- return (uhci_setup_isoc(pipe));
- case UE_BULK:
- pipe->methods = &uhci_device_bulk_methods;
- upipe->u.bulk.sqh = uhci_alloc_sqh(sc);
- if (upipe->u.bulk.sqh == NULL)
- goto bad;
- break;
- }
- }
- return (USBD_NORMAL_COMPLETION);
-
- bad:
- return (USBD_NOMEM);
-}
-
-/*
- * Data structures and routines to emulate the root hub.
- */
-usb_device_descriptor_t uhci_devd = {
- USB_DEVICE_DESCRIPTOR_SIZE,
- UDESC_DEVICE, /* type */
- {0x00, 0x01}, /* USB version */
- UDCLASS_HUB, /* class */
- UDSUBCLASS_HUB, /* subclass */
- UDPROTO_FSHUB, /* protocol */
- 64, /* max packet */
- {0},{0},{0x00,0x01}, /* device id */
- 1,2,0, /* string indicies */
- 1 /* # of configurations */
-};
-
-usb_config_descriptor_t uhci_confd = {
- USB_CONFIG_DESCRIPTOR_SIZE,
- UDESC_CONFIG,
- {USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE},
- 1,
- 1,
- 0,
- UC_SELF_POWERED,
- 0 /* max power */
-};
-
-usb_interface_descriptor_t uhci_ifcd = {
- USB_INTERFACE_DESCRIPTOR_SIZE,
- UDESC_INTERFACE,
- 0,
- 0,
- 1,
- UICLASS_HUB,
- UISUBCLASS_HUB,
- UIPROTO_FSHUB,
- 0
-};
-
-usb_endpoint_descriptor_t uhci_endpd = {
- USB_ENDPOINT_DESCRIPTOR_SIZE,
- UDESC_ENDPOINT,
- UE_DIR_IN | UHCI_INTR_ENDPT,
- UE_INTERRUPT,
- {8},
- 255
-};
-
-usb_hub_descriptor_t uhci_hubd_piix = {
- USB_HUB_DESCRIPTOR_SIZE,
- UDESC_HUB,
- 2,
- { UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0 },
- 50, /* power on to power good */
- 0,
- { 0x00 }, /* both ports are removable */
-};
-
-int
-uhci_str(usb_string_descriptor_t *p, int l, char *s)
-{
- int i;
-
- if (l == 0)
- return (0);
- p->bLength = 2 * strlen(s) + 2;
- if (l == 1)
- return (1);
- p->bDescriptorType = UDESC_STRING;
- l -= 2;
- for (i = 0; s[i] && l > 1; i++, l -= 2)
- USETW2(p->bString[i], 0, s[i]);
- return (2*i+2);
-}
-
-/*
- * The USB hub protocol requires that SET_FEATURE(PORT_RESET) also
- * enables the port, and also states that SET_FEATURE(PORT_ENABLE)
- * should not be used by the USB subsystem. As we cannot issue a
- * SET_FEATURE(PORT_ENABLE) externally, we must ensure that the port
- * will be enabled as part of the reset.
- *
- * On the VT83C572, the port cannot be successfully enabled until the
- * outstanding "port enable change" and "connection status change"
- * events have been reset.
- */
-static usbd_status
-uhci_portreset(uhci_softc_t *sc, int index)
-{
- int lim, port, x;
-
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else
- return (USBD_IOERROR);
-
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_PR);
-
- usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
-
- DPRINTFN(3,("uhci port %d reset, status0 = 0x%04x\n",
- index, UREAD2(sc, port)));
-
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
-
- delay(100);
-
- DPRINTFN(3,("uhci port %d reset, status1 = 0x%04x\n",
- index, UREAD2(sc, port)));
-
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_PE);
-
- for (lim = 10; --lim > 0;) {
- usb_delay_ms(&sc->sc_bus, USB_PORT_RESET_DELAY);
-
- x = UREAD2(sc, port);
-
- DPRINTFN(3,("uhci port %d iteration %u, status = 0x%04x\n",
- index, lim, x));
-
- if (!(x & UHCI_PORTSC_CCS)) {
- /*
- * No device is connected (or was disconnected
- * during reset). Consider the port reset.
- * The delay must be long enough to ensure on
- * the initial iteration that the device
- * connection will have been registered. 50ms
- * appears to be sufficient, but 20ms is not.
- */
- DPRINTFN(3,("uhci port %d loop %u, device detached\n",
- index, lim));
- break;
- }
-
- if (x & (UHCI_PORTSC_POEDC | UHCI_PORTSC_CSC)) {
- /*
- * Port enabled changed and/or connection
- * status changed were set. Reset either or
- * both raised flags (by writing a 1 to that
- * bit), and wait again for state to settle.
- */
- UWRITE2(sc, port, URWMASK(x) |
- (x & (UHCI_PORTSC_POEDC | UHCI_PORTSC_CSC)));
- continue;
- }
-
- if (x & UHCI_PORTSC_PE)
- /* Port is enabled */
- break;
-
- UWRITE2(sc, port, URWMASK(x) | UHCI_PORTSC_PE);
- }
-
- DPRINTFN(3,("uhci port %d reset, status2 = 0x%04x\n",
- index, UREAD2(sc, port)));
-
- if (lim <= 0) {
- DPRINTFN(1,("uhci port %d reset timed out\n", index));
- return (USBD_TIMEOUT);
- }
-
- sc->sc_isreset = 1;
- return (USBD_NORMAL_COMPLETION);
-}
-
-/*
- * Simulate a hardware hub by handling all the necessary requests.
- */
-usbd_status
-uhci_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (uhci_root_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-usbd_status
-uhci_root_ctrl_start(usbd_xfer_handle xfer)
-{
- uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
- usb_device_request_t *req;
- void *buf = NULL;
- int port, x;
- int s, len, value, index, status, change, l, totlen = 0;
- usb_port_status_t ps;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST))
- panic("uhci_root_ctrl_transfer: not a request");
-#endif
- req = &xfer->request;
-
- DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n",
- req->bmRequestType, req->bRequest));
-
- len = UGETW(req->wLength);
- value = UGETW(req->wValue);
- index = UGETW(req->wIndex);
-
- if (len != 0)
- buf = xfer->buffer;
-
-#define C(x,y) ((x) | ((y) << 8))
- switch(C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- if (len > 0) {
- *(u_int8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value));
- switch(value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- USETW(uhci_devd.idVendor, sc->sc_id_vendor);
- memcpy(buf, &uhci_devd, l);
- break;
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &uhci_confd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &uhci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &uhci_endpd, l);
- break;
- case UDESC_STRING:
- if (len == 0)
- break;
- *(u_int8_t *)buf = 0;
- totlen = 1;
- switch (value & 0xff) {
- case 1: /* Vendor */
- totlen = uhci_str(buf, len, sc->sc_vendor);
- break;
- case 2: /* Product */
- totlen = uhci_str(buf, len, "UHCI root hub");
- break;
- }
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *(u_int8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- if (value >= USB_MAX_DEVICES) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- if (value != 0 && value != 1) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- break;
- /* Hub requests */
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
- DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
- "port=%d feature=%d\n",
- index, value));
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else {
- err = USBD_IOERROR;
- goto ret;
- }
- switch(value) {
- case UHF_PORT_ENABLE:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x & ~UHCI_PORTSC_PE);
- break;
- case UHF_PORT_SUSPEND:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP);
- break;
- case UHF_PORT_RESET:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
- break;
- case UHF_C_PORT_CONNECTION:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_CSC);
- break;
- case UHF_C_PORT_ENABLE:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_POEDC);
- break;
- case UHF_C_PORT_OVER_CURRENT:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_OCIC);
- break;
- case UHF_C_PORT_RESET:
- sc->sc_isreset = 0;
- err = USBD_NORMAL_COMPLETION;
- goto ret;
- case UHF_PORT_CONNECTION:
- case UHF_PORT_OVER_CURRENT:
- case UHF_PORT_POWER:
- case UHF_PORT_LOW_SPEED:
- case UHF_C_PORT_SUSPEND:
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else {
- err = USBD_IOERROR;
- goto ret;
- }
- if (len > 0) {
- *(u_int8_t *)buf =
- (UREAD2(sc, port) & UHCI_PORTSC_LS) >>
- UHCI_PORTSC_LS_SHIFT;
- totlen = 1;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- l = min(len, USB_HUB_DESCRIPTOR_SIZE);
- totlen = l;
- memcpy(buf, &uhci_hubd_piix, l);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- memset(buf, 0, len);
- totlen = len;
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else {
- err = USBD_IOERROR;
- goto ret;
- }
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- x = UREAD2(sc, port);
- status = change = 0;
- if (x & UHCI_PORTSC_CCS)
- status |= UPS_CURRENT_CONNECT_STATUS;
- if (x & UHCI_PORTSC_CSC)
- change |= UPS_C_CONNECT_STATUS;
- if (x & UHCI_PORTSC_PE)
- status |= UPS_PORT_ENABLED;
- if (x & UHCI_PORTSC_POEDC)
- change |= UPS_C_PORT_ENABLED;
- if (x & UHCI_PORTSC_OCI)
- status |= UPS_OVERCURRENT_INDICATOR;
- if (x & UHCI_PORTSC_OCIC)
- change |= UPS_C_OVERCURRENT_INDICATOR;
- if (x & UHCI_PORTSC_SUSP)
- status |= UPS_SUSPEND;
- if (x & UHCI_PORTSC_LSDA)
- status |= UPS_LOW_SPEED;
- status |= UPS_PORT_POWER;
- if (sc->sc_isreset)
- change |= UPS_C_PORT_RESET;
- USETW(ps.wPortStatus, status);
- USETW(ps.wPortChange, change);
- l = min(len, sizeof ps);
- memcpy(buf, &ps, l);
- totlen = l;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else {
- err = USBD_IOERROR;
- goto ret;
- }
- switch(value) {
- case UHF_PORT_ENABLE:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_PE);
- break;
- case UHF_PORT_SUSPEND:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_SUSP);
- break;
- case UHF_PORT_RESET:
- err = uhci_portreset(sc, index);
- goto ret;
- case UHF_PORT_POWER:
- /* Pretend we turned on power */
- err = USBD_NORMAL_COMPLETION;
- goto ret;
- case UHF_C_PORT_CONNECTION:
- case UHF_C_PORT_ENABLE:
- case UHF_C_PORT_OVER_CURRENT:
- case UHF_PORT_CONNECTION:
- case UHF_PORT_OVER_CURRENT:
- case UHF_PORT_LOW_SPEED:
- case UHF_C_PORT_SUSPEND:
- case UHF_C_PORT_RESET:
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- xfer->actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
- ret:
- xfer->status = err;
- s = splusb();
- uhci_transfer_complete(xfer);
- splx(s);
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a root control request. */
-void
-uhci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- /* Nothing to do, all transfers are synchronous. */
-}
-
-/* Close the root pipe. */
-void
-uhci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(("uhci_root_ctrl_close\n"));
-}
-
-/* Abort a root interrupt request. */
-void
-uhci_root_intr_abort(usbd_xfer_handle xfer)
-{
- uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
-
- callout_stop(&sc->sc_poll_handle);
- sc->sc_intr_xfer = NULL;
-
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTF(("uhci_root_intr_abort: remove\n"));
- xfer->pipe->intrxfer = 0;
- }
- xfer->status = USBD_CANCELLED;
-#ifdef DIAGNOSTIC
- UXFER(xfer)->iinfo.isdone = 1;
-#endif
- uhci_transfer_complete(xfer);
-}
-
-usbd_status
-uhci_root_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (uhci_root_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-/* Start a transfer on the root interrupt pipe */
-usbd_status
-uhci_root_intr_start(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
-
- DPRINTFN(3, ("uhci_root_intr_start: xfer=%p len=%d flags=%d\n",
- xfer, xfer->length, xfer->flags));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- sc->sc_ival = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval);
- callout_reset(&sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer);
- sc->sc_intr_xfer = xfer;
- return (USBD_IN_PROGRESS);
-}
-
-/* Close the root interrupt pipe. */
-void
-uhci_root_intr_close(usbd_pipe_handle pipe)
-{
- uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
-
- callout_stop(&sc->sc_poll_handle);
- sc->sc_intr_xfer = NULL;
- DPRINTF(("uhci_root_intr_close\n"));
-}
diff --git a/sys/legacy/dev/usb/uhci_pci.c b/sys/legacy/dev/usb/uhci_pci.c
deleted file mode 100644
index 6fe015c..0000000
--- a/sys/legacy/dev/usb/uhci_pci.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (augustss@carlstedt.se) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/* Universal Host Controller Interface
- *
- * UHCI spec: http://www.intel.com/
- */
-
-/* The low level controller code for UHCI has been split into
- * PCI probes and UHCI specific code. This was done to facilitate the
- * sharing of code between *BSD's
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/queue.h>
-#include <sys/bus.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcireg.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-
-#include <dev/usb/uhcireg.h>
-#include <dev/usb/uhcivar.h>
-
-#define PCI_UHCI_VENDORID_INTEL 0x8086
-#define PCI_UHCI_VENDORID_VIA 0x1106
-
-#define PCI_UHCI_DEVICEID_PIIX3 0x70208086
-static const char *uhci_device_piix3 = "Intel 82371SB (PIIX3) USB controller";
-
-#define PCI_UHCI_DEVICEID_PIIX4 0x71128086
-#define PCI_UHCI_DEVICEID_PIIX4E 0x71128086 /* no separate stepping */
-static const char *uhci_device_piix4 = "Intel 82371AB/EB (PIIX4) USB controller";
-
-#define PCI_UHCI_DEVICEID_ICH 0x24128086
-static const char *uhci_device_ich = "Intel 82801AA (ICH) USB controller";
-
-#define PCI_UHCI_DEVICEID_ICH0 0x24228086
-static const char *uhci_device_ich0 = "Intel 82801AB (ICH0) USB controller";
-
-#define PCI_UHCI_DEVICEID_ICH2_A 0x24428086
-static const char *uhci_device_ich2_a = "Intel 82801BA/BAM (ICH2) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH2_B 0x24448086
-static const char *uhci_device_ich2_b = "Intel 82801BA/BAM (ICH2) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH3_A 0x24828086
-static const char *uhci_device_ich3_a = "Intel 82801CA/CAM (ICH3) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH3_B 0x24848086
-static const char *uhci_device_ich3_b = "Intel 82801CA/CAM (ICH3) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH3_C 0x24878086
-static const char *uhci_device_ich3_c = "Intel 82801CA/CAM (ICH3) USB controller USB-C";
-
-#define PCI_UHCI_DEVICEID_ICH4_A 0x24c28086
-static const char *uhci_device_ich4_a = "Intel 82801DB (ICH4) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH4_B 0x24c48086
-static const char *uhci_device_ich4_b = "Intel 82801DB (ICH4) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH4_C 0x24c78086
-static const char *uhci_device_ich4_c = "Intel 82801DB (ICH4) USB controller USB-C";
-
-#define PCI_UHCI_DEVICEID_ICH5_A 0x24d28086
-static const char *uhci_device_ich5_a = "Intel 82801EB (ICH5) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH5_B 0x24d48086
-static const char *uhci_device_ich5_b = "Intel 82801EB (ICH5) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH5_C 0x24d78086
-static const char *uhci_device_ich5_c = "Intel 82801EB (ICH5) USB controller USB-C";
-
-#define PCI_UHCI_DEVICEID_ICH5_D 0x24de8086
-static const char *uhci_device_ich5_d = "Intel 82801EB (ICH5) USB controller USB-D";
-
-#define PCI_UHCI_DEVICEID_ICH6_A 0x26588086
-static const char *uhci_device_ich6_a = "Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH6_B 0x26598086
-static const char *uhci_device_ich6_b = "Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH6_C 0x265a8086
-static const char *uhci_device_ich6_c = "Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-C";
-
-#define PCI_UHCI_DEVICEID_ICH6_D 0x265b8086
-static const char *uhci_device_ich6_d = "Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-D";
-
-#define PCI_UHCI_DEVICEID_63XXESB_1 0x26888086
-static const char *uhci_device_esb_1 = "Intel 631XESB/632XESB/3100 USB controller USB-1";
-
-#define PCI_UHCI_DEVICEID_63XXESB_2 0x26898086
-static const char *uhci_device_esb_2 = "Intel 631XESB/632XESB/3100 USB controller USB-2";
-
-#define PCI_UHCI_DEVICEID_63XXESB_3 0x268a8086
-static const char *uhci_device_esb_3 = "Intel 631XESB/632XESB/3100 USB controller USB-3";
-
-#define PCI_UHCI_DEVICEID_63XXESB_4 0x268b8086
-static const char *uhci_device_esb_4 = "Intel 631XESB/632XESB/3100 USB controller USB-4";
-
-#define PCI_UHCI_DEVICEID_ICH8_A 0x28308086
-static const char *uhci_device_ich8_a = "Intel 82801H (ICH8) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH8_B 0x28318086
-static const char *uhci_device_ich8_b = "Intel 82801H (ICH8) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH8_C 0x28328086
-static const char *uhci_device_ich8_c = "Intel 82801H (ICH8) USB controller USB-C";
-
-#define PCI_UHCI_DEVICEID_ICH8_D 0x28348086
-static const char *uhci_device_ich8_d = "Intel 82801H (ICH8) USB controller USB-D";
-
-#define PCI_UHCI_DEVICEID_ICH8_E 0x28358086
-static const char *uhci_device_ich8_e = "Intel 82801H (ICH8) USB controller USB-E";
-
-#define PCI_UHCI_DEVICEID_ICH9_A 0x29348086
-#define PCI_UHCI_DEVICEID_ICH9_B 0x29358086
-#define PCI_UHCI_DEVICEID_ICH9_C 0x29368086
-#define PCI_UHCI_DEVICEID_ICH9_D 0x29378086
-#define PCI_UHCI_DEVICEID_ICH9_E 0x29388086
-#define PCI_UHCI_DEVICEID_ICH9_F 0x29398086
-static const char *uhci_device_ich9 = "Intel 82801I (ICH9) USB controller";
-
-#define PCI_UHCI_DEVICEID_440MX 0x719a8086
-static const char *uhci_device_440mx = "Intel 82443MX USB controller";
-
-#define PCI_UHCI_DEVICEID_460GX 0x76028086
-static const char *uhci_device_460gx = "Intel 82372FB/82468GX USB controller";
-
-#define PCI_UHCI_DEVICEID_VT83C572 0x30381106
-static const char *uhci_device_vt83c572 = "VIA 83C572 USB controller";
-
-static const char *uhci_device_generic = "UHCI (generic) USB controller";
-
-#define PCI_UHCI_BASE_REG 0x20
-
-
-static device_attach_t uhci_pci_attach;
-static device_detach_t uhci_pci_detach;
-static device_suspend_t uhci_pci_suspend;
-static device_resume_t uhci_pci_resume;
-
-static int
-uhci_pci_suspend(device_t self)
-{
- uhci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return err;
- uhci_power(PWR_SUSPEND, sc);
-
- return 0;
-}
-
-static int
-uhci_pci_resume(device_t self)
-{
- uhci_softc_t *sc = device_get_softc(self);
-
- pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);
-
- uhci_power(PWR_RESUME, sc);
- bus_generic_resume(self);
-
- return 0;
-}
-
-static const char *
-uhci_pci_match(device_t self)
-{
- u_int32_t device_id = pci_get_devid(self);
-
- if (device_id == PCI_UHCI_DEVICEID_PIIX3) {
- return (uhci_device_piix3);
- } else if (device_id == PCI_UHCI_DEVICEID_PIIX4) {
- return (uhci_device_piix4);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH) {
- return (uhci_device_ich);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH0) {
- return (uhci_device_ich0);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH2_A) {
- return (uhci_device_ich2_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH2_B) {
- return (uhci_device_ich2_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH3_A) {
- return (uhci_device_ich3_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH3_B) {
- return (uhci_device_ich3_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH3_C) {
- return (uhci_device_ich3_c);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH4_A) {
- return (uhci_device_ich4_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH4_B) {
- return (uhci_device_ich4_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH4_C) {
- return (uhci_device_ich4_c);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH5_A) {
- return (uhci_device_ich5_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH5_B) {
- return (uhci_device_ich5_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH5_C) {
- return (uhci_device_ich5_c);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH5_D) {
- return (uhci_device_ich5_d);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH6_A) {
- return (uhci_device_ich6_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH6_B) {
- return (uhci_device_ich6_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH6_C) {
- return (uhci_device_ich6_c);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH6_D) {
- return (uhci_device_ich6_d);
- } else if (device_id == PCI_UHCI_DEVICEID_63XXESB_1) {
- return (uhci_device_esb_1);
- } else if (device_id == PCI_UHCI_DEVICEID_63XXESB_2) {
- return (uhci_device_esb_2);
- } else if (device_id == PCI_UHCI_DEVICEID_63XXESB_3) {
- return (uhci_device_esb_3);
- } else if (device_id == PCI_UHCI_DEVICEID_63XXESB_4) {
- return (uhci_device_esb_4);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH8_A) {
- return (uhci_device_ich8_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH8_B) {
- return (uhci_device_ich8_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH8_C) {
- return (uhci_device_ich8_c);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH8_D) {
- return (uhci_device_ich8_d);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH8_E) {
- return (uhci_device_ich8_e);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_A) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_B) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_C) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_D) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_E) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_F) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_440MX) {
- return (uhci_device_440mx);
- } else if (device_id == PCI_UHCI_DEVICEID_460GX) {
- return (uhci_device_460gx);
- } else if (device_id == PCI_UHCI_DEVICEID_VT83C572) {
- return (uhci_device_vt83c572);
- } else {
- if (pci_get_class(self) == PCIC_SERIALBUS
- && pci_get_subclass(self) == PCIS_SERIALBUS_USB
- && pci_get_progif(self) == PCI_INTERFACE_UHCI) {
- return (uhci_device_generic);
- }
- }
-
- return NULL; /* dunno... */
-}
-
-static int
-uhci_pci_probe(device_t self)
-{
- const char *desc = uhci_pci_match(self);
-
- if (desc) {
- device_set_desc(self, desc);
- return BUS_PROBE_DEFAULT;
- } else {
- return ENXIO;
- }
-}
-
-static int
-uhci_pci_attach(device_t self)
-{
- uhci_softc_t *sc = device_get_softc(self);
- int rid;
- int err;
-
- pci_enable_busmaster(self);
-
- rid = PCI_UHCI_BASE_REG;
- sc->io_res = bus_alloc_resource_any(self, SYS_RES_IOPORT, &rid,
- RF_ACTIVE);
- if (!sc->io_res) {
- device_printf(self, "Could not map ports\n");
- return ENXIO;
- }
- sc->iot = rman_get_bustag(sc->io_res);
- sc->ioh = rman_get_bushandle(sc->io_res);
-
- /* disable interrupts */
- bus_space_write_2(sc->iot, sc->ioh, UHCI_INTR, 0);
-
- rid = 0;
- sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- uhci_pci_detach(self);
- return ENXIO;
- }
- sc->sc_bus.bdev = device_add_child(self, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- uhci_pci_detach(self);
- return ENOMEM;
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-
- /* uhci_pci_match must never return NULL if uhci_pci_probe succeeded */
- device_set_desc(sc->sc_bus.bdev, uhci_pci_match(self));
- switch (pci_get_vendor(self)) {
- case PCI_UHCI_VENDORID_INTEL:
- sprintf(sc->sc_vendor, "Intel");
- break;
- case PCI_UHCI_VENDORID_VIA:
- sprintf(sc->sc_vendor, "VIA");
- break;
- default:
- if (bootverbose)
- device_printf(self, "(New UHCI DeviceId=0x%08x)\n",
- pci_get_devid(self));
- sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
- }
-
- switch (pci_read_config(self, PCI_USBREV, 1) & PCI_USBREV_MASK) {
- case PCI_USBREV_PRE_1_0:
- sc->sc_bus.usbrev = USBREV_PRE_1_0;
- break;
- case PCI_USBREV_1_0:
- sc->sc_bus.usbrev = USBREV_1_0;
- break;
- default:
- sc->sc_bus.usbrev = USBREV_UNKNOWN;
- break;
- }
-
- /*
- * Quirk for Parallels Desktop 4.0.
- */
- if (pci_get_devid(self) == PCI_UHCI_DEVICEID_ICH6_A)
- sc->sc_bus.usbrev = USBREV_2_0;
-
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
- NULL, (driver_intr_t *) uhci_intr, sc, &sc->ih);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->ih = NULL;
- uhci_pci_detach(self);
- return ENXIO;
- }
- /*
- * Set the PIRQD enable bit and switch off all the others. We don't
- * want legacy support to interfere with us XXX Does this also mean
- * that the BIOS won't touch the keyboard anymore if it is connected
- * to the ports of the root hub?
- */
-#ifdef USB_DEBUG
- if (pci_read_config(self, PCI_LEGSUP, 2) != PCI_LEGSUP_USBPIRQDEN)
- device_printf(self, "LegSup = 0x%04x\n",
- pci_read_config(self, PCI_LEGSUP, 2));
-#endif
- pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);
-
- /* Allocate a parent dma tag for DMA maps */
- err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- NULL, NULL, &sc->sc_bus.parent_dmatag);
- if (err) {
- device_printf(self, "Could not allocate parent DMA tag (%d)\n",
- err);
- uhci_pci_detach(self);
- return ENXIO;
- }
- /* Allocate a dma tag for transfer buffers */
- err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
- if (err) {
- device_printf(self, "Could not allocate transfer tag (%d)\n",
- err);
- uhci_pci_detach(self);
- return ENXIO;
- }
-
- err = uhci_init(sc);
- if (!err) {
- sc->sc_flags |= UHCI_SCFLG_DONEINIT;
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
-
- if (err) {
- device_printf(self, "USB init failed\n");
- uhci_pci_detach(self);
- return EIO;
- }
- return 0; /* success */
-}
-
-int
-uhci_pci_detach(device_t self)
-{
- uhci_softc_t *sc = device_get_softc(self);
-
- if (sc->sc_flags & UHCI_SCFLG_DONEINIT) {
- uhci_detach(sc, 0);
- sc->sc_flags &= ~UHCI_SCFLG_DONEINIT;
- }
-
- if (sc->sc_bus.parent_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
- if (sc->sc_bus.buffer_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
-
- if (sc->irq_res && sc->ih) {
- int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
-
- if (err)
- /* XXX or should we panic? */
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->ih = NULL;
- }
- if (sc->sc_bus.bdev) {
- device_delete_child(self, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
- }
- if (sc->irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
- sc->irq_res = NULL;
- }
- if (sc->io_res) {
- bus_release_resource(self, SYS_RES_IOPORT, PCI_UHCI_BASE_REG,
- sc->io_res);
- sc->io_res = NULL;
- sc->iot = 0;
- sc->ioh = 0;
- }
- return 0;
-}
-
-
-static device_method_t uhci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uhci_pci_probe),
- DEVMETHOD(device_attach, uhci_pci_attach),
- DEVMETHOD(device_detach, uhci_pci_detach),
- DEVMETHOD(device_suspend, uhci_pci_suspend),
- DEVMETHOD(device_resume, uhci_pci_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t uhci_driver = {
- "uhci",
- uhci_methods,
- sizeof(uhci_softc_t),
-};
-
-static devclass_t uhci_devclass;
-
-DRIVER_MODULE(uhci, pci, uhci_driver, uhci_devclass, 0, 0);
-MODULE_DEPEND(uhci, usb, 1, 1, 1);
diff --git a/sys/legacy/dev/usb/uhcireg.h b/sys/legacy/dev/usb/uhcireg.h
deleted file mode 100644
index 512dd2d..0000000
--- a/sys/legacy/dev/usb/uhcireg.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* $NetBSD: uhcireg.h,v 1.15 2002/02/11 11:41:30 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DEV_PCI_UHCIREG_H_
-#define _DEV_PCI_UHCIREG_H_
-
-/*** PCI config registers ***/
-
-#define PCI_USBREV 0x60 /* USB protocol revision */
-#define PCI_USBREV_MASK 0xff
-#define PCI_USBREV_PRE_1_0 0x00
-#define PCI_USBREV_1_0 0x10
-#define PCI_USBREV_1_1 0x11
-
-#define PCI_LEGSUP 0xc0 /* Legacy Support register */
-#define PCI_LEGSUP_USBPIRQDEN 0x2000 /* USB PIRQ D Enable */
-
-#define PCI_CBIO 0x20 /* configuration base IO */
-
-#define PCI_INTERFACE_UHCI 0x00
-
-/*** UHCI registers ***/
-
-#define UHCI_CMD 0x00
-#define UHCI_CMD_RS 0x0001
-#define UHCI_CMD_HCRESET 0x0002
-#define UHCI_CMD_GRESET 0x0004
-#define UHCI_CMD_EGSM 0x0008
-#define UHCI_CMD_FGR 0x0010
-#define UHCI_CMD_SWDBG 0x0020
-#define UHCI_CMD_CF 0x0040
-#define UHCI_CMD_MAXP 0x0080
-
-#define UHCI_STS 0x02
-#define UHCI_STS_USBINT 0x0001
-#define UHCI_STS_USBEI 0x0002
-#define UHCI_STS_RD 0x0004
-#define UHCI_STS_HSE 0x0008
-#define UHCI_STS_HCPE 0x0010
-#define UHCI_STS_HCH 0x0020
-#define UHCI_STS_ALLINTRS 0x003f
-
-#define UHCI_INTR 0x04
-#define UHCI_INTR_TOCRCIE 0x0001
-#define UHCI_INTR_RIE 0x0002
-#define UHCI_INTR_IOCE 0x0004
-#define UHCI_INTR_SPIE 0x0008
-
-#define UHCI_FRNUM 0x06
-#define UHCI_FRNUM_MASK 0x03ff
-
-#define UHCI_FLBASEADDR 0x08
-
-#define UHCI_SOF 0x0c
-#define UHCI_SOF_MASK 0x7f
-
-#define UHCI_PORTSC1 0x010
-#define UHCI_PORTSC2 0x012
-#define UHCI_PORTSC_CCS 0x0001
-#define UHCI_PORTSC_CSC 0x0002
-#define UHCI_PORTSC_PE 0x0004
-#define UHCI_PORTSC_POEDC 0x0008
-#define UHCI_PORTSC_LS 0x0030
-#define UHCI_PORTSC_LS_SHIFT 4
-#define UHCI_PORTSC_RD 0x0040
-#define UHCI_PORTSC_LSDA 0x0100
-#define UHCI_PORTSC_PR 0x0200
-#define UHCI_PORTSC_OCI 0x0400
-#define UHCI_PORTSC_OCIC 0x0800
-#define UHCI_PORTSC_SUSP 0x1000
-
-#define URWMASK(x) \
- ((x) & (UHCI_PORTSC_SUSP | UHCI_PORTSC_PR | UHCI_PORTSC_RD | UHCI_PORTSC_PE))
-
-#define UHCI_FRAMELIST_COUNT 1024
-#define UHCI_FRAMELIST_ALIGN 4096
-
-#define UHCI_TD_ALIGN 16
-#define UHCI_QH_ALIGN 16
-
-typedef u_int32_t uhci_physaddr_t;
-#define UHCI_PTR_T 0x00000001
-#define UHCI_PTR_TD 0x00000000
-#define UHCI_PTR_QH 0x00000002
-#define UHCI_PTR_VF 0x00000004
-
-/*
- * Wait this long after a QH has been removed. This gives that HC a
- * chance to stop looking at it before it's recycled.
- */
-#define UHCI_QH_REMOVE_DELAY 5
-
-/*
- * The Queue Heads and Transfer Descriptors are accessed
- * by both the CPU and the USB controller which run
- * concurrently. This means that they have to be accessed
- * with great care. As long as the data structures are
- * not linked into the controller's frame list they cannot
- * be accessed by it and anything goes. As soon as a
- * TD is accessible by the controller it "owns" the td_status
- * field; it will not be written by the CPU. Similarly
- * the controller "owns" the qh_elink field.
- */
-
-typedef struct {
- uhci_physaddr_t td_link;
- u_int32_t td_status;
-#define UHCI_TD_GET_ACTLEN(s) (((s) + 1) & 0x3ff)
-#define UHCI_TD_ZERO_ACTLEN(t) ((t) | 0x3ff)
-#define UHCI_TD_BITSTUFF 0x00020000
-#define UHCI_TD_CRCTO 0x00040000
-#define UHCI_TD_NAK 0x00080000
-#define UHCI_TD_BABBLE 0x00100000
-#define UHCI_TD_DBUFFER 0x00200000
-#define UHCI_TD_STALLED 0x00400000
-#define UHCI_TD_ACTIVE 0x00800000
-#define UHCI_TD_IOC 0x01000000
-#define UHCI_TD_IOS 0x02000000
-#define UHCI_TD_LS 0x04000000
-#define UHCI_TD_GET_ERRCNT(s) (((s) >> 27) & 3)
-#define UHCI_TD_SET_ERRCNT(n) ((n) << 27)
-#define UHCI_TD_SPD 0x20000000
- u_int32_t td_token;
-#define UHCI_TD_PID_IN 0x00000069
-#define UHCI_TD_PID_OUT 0x000000e1
-#define UHCI_TD_PID_SETUP 0x0000002d
-#define UHCI_TD_GET_PID(s) ((s) & 0xff)
-#define UHCI_TD_SET_DEVADDR(a) ((a) << 8)
-#define UHCI_TD_GET_DEVADDR(s) (((s) >> 8) & 0x7f)
-#define UHCI_TD_SET_ENDPT(e) (((e)&0xf) << 15)
-#define UHCI_TD_GET_ENDPT(s) (((s) >> 15) & 0xf)
-#define UHCI_TD_SET_DT(t) ((t) << 19)
-#define UHCI_TD_GET_DT(s) (((s) >> 19) & 1)
-#define UHCI_TD_SET_MAXLEN(l) (((l)-1) << 21)
-#define UHCI_TD_GET_MAXLEN(s) ((((s) >> 21) + 1) & 0x7ff)
-#define UHCI_TD_MAXLEN_MASK 0xffe00000
- u_int32_t td_buffer;
-} uhci_td_t;
-
-#define UHCI_TD_ERROR (UHCI_TD_BITSTUFF|UHCI_TD_CRCTO|UHCI_TD_BABBLE|UHCI_TD_DBUFFER|UHCI_TD_STALLED)
-
-#define UHCI_TD_SETUP(len, endp, dev) (UHCI_TD_SET_MAXLEN(len) | \
- UHCI_TD_SET_ENDPT(endp) | UHCI_TD_SET_DEVADDR(dev) | UHCI_TD_PID_SETUP)
-#define UHCI_TD_OUT(len, endp, dev, dt) (UHCI_TD_SET_MAXLEN(len) | \
- UHCI_TD_SET_ENDPT(endp) | UHCI_TD_SET_DEVADDR(dev) | \
- UHCI_TD_PID_OUT | UHCI_TD_SET_DT(dt))
-#define UHCI_TD_IN(len, endp, dev, dt) (UHCI_TD_SET_MAXLEN(len) | \
- UHCI_TD_SET_ENDPT(endp) | UHCI_TD_SET_DEVADDR(dev) | UHCI_TD_PID_IN | \
- UHCI_TD_SET_DT(dt))
-
-typedef struct {
- uhci_physaddr_t qh_hlink;
- uhci_physaddr_t qh_elink;
-} uhci_qh_t;
-
-#endif /* _DEV_PCI_UHCIREG_H_ */
diff --git a/sys/legacy/dev/usb/uhcivar.h b/sys/legacy/dev/usb/uhcivar.h
deleted file mode 100644
index 0df23f1..0000000
--- a/sys/legacy/dev/usb/uhcivar.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/* $NetBSD: uhcivar.h,v 1.33 2002/02/11 11:41:30 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * To avoid having 1024 TDs for each isochronous transfer we introduce
- * a virtual frame list. Every UHCI_VFRAMELIST_COUNT entries in the real
- * frame list points to a non-active TD. These, in turn, form the
- * starts of the virtual frame list. This also has the advantage that it
- * simplifies linking in/out of TDs/QHs in the schedule.
- * Furthermore, initially each of the inactive TDs point to an inactive
- * QH that forms the start of the interrupt traffic for that slot.
- * Each of these QHs point to the same QH that is the start of control
- * traffic. This QH points at another QH which is the start of the
- * bulk traffic.
- *
- * UHCI_VFRAMELIST_COUNT should be a power of 2 and <= UHCI_FRAMELIST_COUNT.
- */
-#define UHCI_VFRAMELIST_COUNT 128
-
-typedef struct uhci_soft_qh uhci_soft_qh_t;
-typedef struct uhci_soft_td uhci_soft_td_t;
-
-typedef union {
- struct uhci_soft_qh *sqh;
- struct uhci_soft_td *std;
-} uhci_soft_td_qh_t;
-
-/*
- * An interrupt info struct contains the information needed to
- * execute a requested routine when the controller generates an
- * interrupt. Since we cannot know which transfer generated
- * the interrupt all structs are linked together so they can be
- * searched at interrupt time.
- */
-typedef struct uhci_intr_info {
- struct uhci_softc *sc;
- usbd_xfer_handle xfer;
- uhci_soft_td_t *stdstart;
- uhci_soft_td_t *stdend;
- LIST_ENTRY(uhci_intr_info) list;
-#ifdef DIAGNOSTIC
- int isdone;
-#endif
-} uhci_intr_info_t;
-
-struct uhci_xfer {
- struct usbd_xfer xfer;
- uhci_intr_info_t iinfo;
- struct usb_task abort_task;
- int curframe;
- u_int32_t uhci_xfer_flags;
-};
-
-#define UHCI_XFER_ABORTING 0x0001 /* xfer is aborting. */
-#define UHCI_XFER_ABORTWAIT 0x0002 /* abort completion is being awaited. */
-
-#define UXFER(xfer) ((struct uhci_xfer *)(xfer))
-
-/*
- * Extra information that we need for a TD.
- */
-struct uhci_soft_td {
- uhci_td_t td; /* The real TD, must be first */
- uhci_soft_td_qh_t link; /* soft version of the td_link field */
- uhci_physaddr_t physaddr; /* TD's physical address. */
- usb_dma_t aux_dma; /* Auxillary storage if needed. */
- void *aux_data; /* Original aux data virtual address. */
- int aux_len; /* Auxillary storage size. */
-};
-/*
- * Make the size such that it is a multiple of UHCI_TD_ALIGN. This way
- * we can pack a number of soft TD together and have the real TD well
- * aligned.
- * NOTE: Minimum size is 32 bytes.
- */
-#define UHCI_STD_SIZE ((sizeof (struct uhci_soft_td) + UHCI_TD_ALIGN - 1) / UHCI_TD_ALIGN * UHCI_TD_ALIGN)
-#define UHCI_STD_CHUNK (PAGE_SIZE / UHCI_STD_SIZE)
-
-/*
- * Extra information that we need for a QH.
- */
-struct uhci_soft_qh {
- uhci_qh_t qh; /* The real QH, must be first */
- uhci_soft_qh_t *hlink; /* soft version of qh_hlink */
- uhci_soft_td_t *elink; /* soft version of qh_elink */
- uhci_physaddr_t physaddr; /* QH's physical address. */
- int pos; /* Timeslot position */
-};
-/* See comment about UHCI_STD_SIZE. */
-#define UHCI_SQH_SIZE ((sizeof (struct uhci_soft_qh) + UHCI_QH_ALIGN - 1) / UHCI_QH_ALIGN * UHCI_QH_ALIGN)
-#define UHCI_SQH_CHUNK (PAGE_SIZE / UHCI_SQH_SIZE)
-
-/*
- * Information about an entry in the virtual frame list.
- */
-struct uhci_vframe {
- uhci_soft_td_t *htd; /* pointer to dummy TD */
- uhci_soft_td_t *etd; /* pointer to last TD */
- uhci_soft_qh_t *hqh; /* pointer to dummy QH */
- uhci_soft_qh_t *eqh; /* pointer to last QH */
- u_int bandwidth; /* max bandwidth used by this frame */
-};
-
-#define UHCI_SCFLG_DONEINIT 0x0001 /* uhci_init() done */
-
-typedef struct uhci_softc {
- struct usbd_bus sc_bus; /* base device */
- int sc_flags;
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
- bus_size_t sc_size;
- void *ih;
-
- struct resource *io_res;
- struct resource *irq_res;
- uhci_physaddr_t *sc_pframes;
- usb_dma_t sc_dma;
- struct uhci_vframe sc_vframes[UHCI_VFRAMELIST_COUNT];
-
- uhci_soft_qh_t *sc_lctl_start; /* dummy QH for low speed control */
- uhci_soft_qh_t *sc_lctl_end; /* last control QH */
- uhci_soft_qh_t *sc_hctl_start; /* dummy QH for high speed control */
- uhci_soft_qh_t *sc_hctl_end; /* last control QH */
- uhci_soft_qh_t *sc_bulk_start; /* dummy QH for bulk */
- uhci_soft_qh_t *sc_bulk_end; /* last bulk transfer */
- uhci_soft_qh_t *sc_last_qh; /* dummy QH at the end */
- u_int32_t sc_loops; /* number of QHs that wants looping */
-
- uhci_soft_td_t *sc_freetds; /* TD free list */
- uhci_soft_qh_t *sc_freeqhs; /* QH free list */
-
- STAILQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
-
- u_int8_t sc_addr; /* device address */
- u_int8_t sc_conf; /* device configuration */
-
- u_int8_t sc_saved_sof;
- u_int16_t sc_saved_frnum;
-
-#ifdef USB_USE_SOFTINTR
- char sc_softwake;
-#endif /* USB_USE_SOFTINTR */
-
- char sc_isreset;
- char sc_suspend;
- char sc_dying;
-
- LIST_HEAD(, uhci_intr_info) sc_intrhead;
-
- /* Info for the root hub interrupt channel. */
- int sc_ival; /* time between root hub intrs */
- usbd_xfer_handle sc_intr_xfer; /* root hub interrupt transfer */
- struct callout sc_poll_handle;
-
- char sc_vendor[16]; /* vendor string for root hub */
- int sc_id_vendor; /* vendor ID for root hub */
-
-#if defined(__NetBSD__)
- void *sc_powerhook; /* cookie from power hook */
- void *sc_shutdownhook; /* cookie from shutdown hook */
-#endif
-} uhci_softc_t;
-
-usbd_status uhci_init(uhci_softc_t *);
-int uhci_intr(void *);
-int uhci_detach(uhci_softc_t *, int);
-void uhci_shutdown(void *v);
-void uhci_power(int state, void *priv);
-
diff --git a/sys/legacy/dev/usb/uhid.c b/sys/legacy/dev/usb/uhid.c
deleted file mode 100644
index d821c01..0000000
--- a/sys/legacy/dev/usb/uhid.c
+++ /dev/null
@@ -1,755 +0,0 @@
-/* $NetBSD: uhid.c,v 1.46 2001/11/13 06:24:55 lukem Exp $ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: uhid.c,v 1.54 2002/09/23 05:51:21 simonb Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
- */
-
-/*
- * XXX TODO: Convert this driver to use si_drv[12] rather than the
- * devclass_get_softc junk
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/clist.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/signalvar.h>
-#include <sys/fcntl.h>
-#include <sys/ioccom.h>
-#include <sys/filio.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/conf.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/ttycom.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include "usbdevs.h"
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/hid.h>
-
-/* Replacement report descriptors for devices shipped with broken ones */
-#include <dev/usb/ugraphire_rdesc.h>
-#include <dev/usb/uxb360gp_rdesc.h>
-
-/* For hid blacklist quirk */
-#include <dev/usb/usb_quirks.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (uhiddebug) printf x
-#define DPRINTFN(n,x) if (uhiddebug>(n)) printf x
-int uhiddebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uhid, CTLFLAG_RW, 0, "USB uhid");
-SYSCTL_INT(_hw_usb_uhid, OID_AUTO, debug, CTLFLAG_RW,
- &uhiddebug, 0, "uhid debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct uhid_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface; /* interface */
- usbd_pipe_handle sc_intrpipe; /* interrupt pipe */
- int sc_ep_addr;
-
- int sc_isize;
- int sc_osize;
- int sc_fsize;
- u_int8_t sc_iid;
- u_int8_t sc_oid;
- u_int8_t sc_fid;
-
- u_char *sc_ibuf;
- u_char *sc_obuf;
-
- void *sc_repdesc;
- int sc_repdesc_size;
-
- struct clist sc_q;
- struct selinfo sc_rsel;
- struct proc *sc_async; /* process that wants SIGIO */
- u_char sc_state; /* driver state */
-#define UHID_OPEN 0x01 /* device is open */
-#define UHID_ASLP 0x02 /* waiting for device data */
-#define UHID_NEEDCLEAR 0x04 /* needs clearing endpoint stall */
-#define UHID_IMMED 0x08 /* return read data immediately */
-
- int sc_refcnt;
- u_char sc_dying;
-
- struct cdev *dev;
-};
-
-#define UHIDUNIT(dev) (dev2unit(dev))
-#define UHID_CHUNK 128 /* chunk size for read */
-#define UHID_BSIZE 1020 /* buffer size */
-
-d_open_t uhidopen;
-d_close_t uhidclose;
-d_read_t uhidread;
-d_write_t uhidwrite;
-d_ioctl_t uhidioctl;
-d_poll_t uhidpoll;
-
-
-static struct cdevsw uhid_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = uhidopen,
- .d_close = uhidclose,
- .d_read = uhidread,
- .d_write = uhidwrite,
- .d_ioctl = uhidioctl,
- .d_poll = uhidpoll,
- .d_name = "uhid",
-};
-
-static void uhid_intr(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-
-static int uhid_do_read(struct uhid_softc *, struct uio *uio, int);
-static int uhid_do_write(struct uhid_softc *, struct uio *uio, int);
-static int uhid_do_ioctl(struct uhid_softc *, u_long, caddr_t, int,
- struct thread *);
-
-MODULE_DEPEND(uhid, usb, 1, 1, 1);
-
-static device_probe_t uhid_match;
-static device_attach_t uhid_attach;
-static device_detach_t uhid_detach;
-
-static device_method_t uhid_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uhid_match),
- DEVMETHOD(device_attach, uhid_attach),
- DEVMETHOD(device_detach, uhid_detach),
-
- { 0, 0 }
-};
-
-static driver_t uhid_driver = {
- "uhid",
- uhid_methods,
- sizeof(struct uhid_softc)
-};
-
-static devclass_t uhid_devclass;
-
-DRIVER_MODULE(uhid, uhub, uhid_driver, uhid_devclass, usbd_driver_load, 0);
-
-static int
-uhid_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
-
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL)
- return (UMATCH_NONE);
- if (id->bInterfaceClass != UICLASS_HID) {
- /* The Xbox 360 gamepad doesn't use the HID class. */
- if (id->bInterfaceClass != UICLASS_VENDOR ||
- id->bInterfaceSubClass != UISUBCLASS_XBOX360_CONTROLLER ||
- id->bInterfaceProtocol != UIPROTO_XBOX360_GAMEPAD)
- return (UMATCH_NONE);
- }
- if (usbd_get_quirks(uaa->device)->uq_flags & UQ_HID_IGNORE)
- return (UMATCH_NONE);
-#if 0
- if (uaa->matchlvl)
- return (uaa->matchlvl);
-#endif
-
- return (UMATCH_IFACECLASS_GENERIC);
-}
-
-static int
-uhid_attach(device_t self)
-{
- struct uhid_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int size;
- void *desc;
- const void *descptr;
- usbd_status err;
-
- sc->sc_dev = self;
- sc->sc_udev = uaa->device;
- sc->sc_iface = iface;
- id = usbd_get_interface_descriptor(iface);
-
- ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (ed == NULL) {
- printf("%s: could not read endpoint descriptor\n",
- device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- DPRINTFN(10,("uhid_attach: bLength=%d bDescriptorType=%d "
- "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
- " bInterval=%d\n",
- ed->bLength, ed->bDescriptorType,
- ed->bEndpointAddress & UE_ADDR,
- UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out",
- ed->bmAttributes & UE_XFERTYPE,
- UGETW(ed->wMaxPacketSize), ed->bInterval));
-
- if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
- (ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
- printf("%s: unexpected endpoint\n", device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- sc->sc_ep_addr = ed->bEndpointAddress;
-
- descptr = NULL;
- if (uaa->vendor == USB_VENDOR_WACOM) {
- /* The report descriptor for the Wacom Graphire is broken. */
- if (uaa->product == USB_PRODUCT_WACOM_GRAPHIRE) {
- size = sizeof uhid_graphire_report_descr;
- descptr = uhid_graphire_report_descr;
- } else if (uaa->product == USB_PRODUCT_WACOM_GRAPHIRE3_4X5) {
- static uByte reportbuf[] = {2, 2, 2};
-
- /*
- * The Graphire3 needs 0x0202 to be written to
- * feature report ID 2 before it'll start
- * returning digitizer data.
- */
- usbd_set_report(uaa->iface, UHID_FEATURE_REPORT, 2,
- &reportbuf, sizeof reportbuf);
-
- size = sizeof uhid_graphire3_4x5_report_descr;
- descptr = uhid_graphire3_4x5_report_descr;
- }
- } else if (id->bInterfaceClass == UICLASS_VENDOR &&
- id->bInterfaceSubClass == UISUBCLASS_XBOX360_CONTROLLER &&
- id->bInterfaceProtocol == UIPROTO_XBOX360_GAMEPAD) {
- static uByte reportbuf[] = {1, 3, 0};
-
- /* The LEDs on the gamepad are blinking by default, turn off. */
- usbd_set_report(uaa->iface, UHID_OUTPUT_REPORT, 0,
- &reportbuf, sizeof reportbuf);
-
- /* The Xbox 360 gamepad has no report descriptor. */
- size = sizeof uhid_xb360gp_report_descr;
- descptr = uhid_xb360gp_report_descr;
- }
-
- if (descptr) {
- desc = malloc(size, M_USBDEV, M_NOWAIT);
- if (desc == NULL)
- err = USBD_NOMEM;
- else {
- err = USBD_NORMAL_COMPLETION;
- memcpy(desc, descptr, size);
- }
- } else {
- desc = NULL;
- err = usbd_read_report_desc(uaa->iface, &desc, &size,M_USBDEV);
- }
-
- if (err) {
- printf("%s: no report descriptor\n", device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- (void)usbd_set_idle(iface, 0, 0);
-
- sc->sc_isize = hid_report_size(desc, size, hid_input, &sc->sc_iid);
- sc->sc_osize = hid_report_size(desc, size, hid_output, &sc->sc_oid);
- sc->sc_fsize = hid_report_size(desc, size, hid_feature, &sc->sc_fid);
-
- sc->sc_repdesc = desc;
- sc->sc_repdesc_size = size;
- sc->dev = make_dev(&uhid_cdevsw, device_get_unit(self),
- UID_ROOT, GID_OPERATOR,
- 0644, "uhid%d", device_get_unit(self));
- return 0;
-}
-
-static int
-uhid_detach(device_t self)
-{
- struct uhid_softc *sc = device_get_softc(self);
- int s;
-
- DPRINTF(("uhid_detach: sc=%p\n", sc));
- sc->sc_dying = 1;
- if (sc->sc_intrpipe != NULL)
- usbd_abort_pipe(sc->sc_intrpipe);
-
- if (sc->sc_state & UHID_OPEN) {
- s = splusb();
- if (--sc->sc_refcnt >= 0) {
- /* Wake everyone */
- wakeup(&sc->sc_q);
- /* Wait for processes to go away. */
- usb_detach_wait(sc->sc_dev);
- }
- splx(s);
- }
- destroy_dev(sc->dev);
-
- if (sc->sc_repdesc)
- free(sc->sc_repdesc, M_USBDEV);
-
- return (0);
-}
-
-void
-uhid_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
-{
- struct uhid_softc *sc = addr;
-
-#ifdef USB_DEBUG
- if (uhiddebug > 5) {
- u_int32_t cc, i;
-
- usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL);
- DPRINTF(("uhid_intr: status=%d cc=%d\n", status, cc));
- DPRINTF(("uhid_intr: data ="));
- for (i = 0; i < cc; i++)
- DPRINTF((" %02x", sc->sc_ibuf[i]));
- DPRINTF(("\n"));
- }
-#endif
-
- if (status == USBD_CANCELLED)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF(("uhid_intr: status=%d\n", status));
- if (status == USBD_STALLED)
- sc->sc_state |= UHID_NEEDCLEAR;
- return;
- }
-
- (void) b_to_q(sc->sc_ibuf, sc->sc_isize, &sc->sc_q);
-
- if (sc->sc_state & UHID_ASLP) {
- sc->sc_state &= ~UHID_ASLP;
- DPRINTFN(5, ("uhid_intr: waking %p\n", &sc->sc_q));
- wakeup(&sc->sc_q);
- }
- selwakeuppri(&sc->sc_rsel, PZERO);
- if (sc->sc_async != NULL) {
- DPRINTFN(3, ("uhid_intr: sending SIGIO %p\n", sc->sc_async));
- PROC_LOCK(sc->sc_async);
- psignal(sc->sc_async, SIGIO);
- PROC_UNLOCK(sc->sc_async);
- }
-}
-
-int
-uhidopen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct uhid_softc *sc;
- usbd_status err;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
- if (sc == NULL)
- return (ENXIO);
-
- DPRINTF(("uhidopen: sc=%p\n", sc));
-
- if (sc->sc_dying)
- return (ENXIO);
-
- if (sc->sc_state & UHID_OPEN)
- return (EBUSY);
- sc->sc_state |= UHID_OPEN;
-
- clist_alloc_cblocks(&sc->sc_q, UHID_BSIZE, UHID_BSIZE);
- sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
- sc->sc_obuf = malloc(sc->sc_osize, M_USBDEV, M_WAITOK);
-
- /* Set up interrupt pipe. */
- err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
- USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc, sc->sc_ibuf,
- sc->sc_isize, uhid_intr, USBD_DEFAULT_INTERVAL);
- if (err) {
- DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
- "error=%d\n",err));
- free(sc->sc_ibuf, M_USBDEV);
- free(sc->sc_obuf, M_USBDEV);
- sc->sc_ibuf = sc->sc_obuf = NULL;
-
- sc->sc_state &= ~UHID_OPEN;
- return (EIO);
- }
-
- sc->sc_state &= ~UHID_IMMED;
-
- sc->sc_async = 0;
-
- return (0);
-}
-
-int
-uhidclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct uhid_softc *sc;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
-
- DPRINTF(("uhidclose: sc=%p\n", sc));
-
- /* Disable interrupts. */
- usbd_abort_pipe(sc->sc_intrpipe);
- usbd_close_pipe(sc->sc_intrpipe);
- sc->sc_intrpipe = 0;
-
- ndflush(&sc->sc_q, sc->sc_q.c_cc);
- clist_free_cblocks(&sc->sc_q);
-
- free(sc->sc_ibuf, M_USBDEV);
- free(sc->sc_obuf, M_USBDEV);
- sc->sc_ibuf = sc->sc_obuf = NULL;
-
- sc->sc_state &= ~UHID_OPEN;
-
- sc->sc_async = 0;
-
- return (0);
-}
-
-int
-uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
-{
- int s;
- int error = 0;
- size_t length;
- u_char buffer[UHID_CHUNK];
- usbd_status err;
-
- DPRINTFN(1, ("uhidread\n"));
- if (sc->sc_state & UHID_IMMED) {
- DPRINTFN(1, ("uhidread immed\n"));
-
- err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
- sc->sc_iid, buffer, sc->sc_isize);
- if (err)
- return (EIO);
- return (uiomove(buffer, sc->sc_isize, uio));
- }
-
- s = splusb();
- while (sc->sc_q.c_cc == 0) {
- if (flag & O_NONBLOCK) {
- splx(s);
- return (EWOULDBLOCK);
- }
- sc->sc_state |= UHID_ASLP;
- DPRINTFN(5, ("uhidread: sleep on %p\n", &sc->sc_q));
- error = tsleep(&sc->sc_q, PZERO | PCATCH, "uhidrea", 0);
- DPRINTFN(5, ("uhidread: woke, error=%d\n", error));
- if (sc->sc_dying)
- error = EIO;
- if (error) {
- sc->sc_state &= ~UHID_ASLP;
- break;
- }
- if (sc->sc_state & UHID_NEEDCLEAR) {
- DPRINTFN(-1,("uhidread: clearing stall\n"));
- sc->sc_state &= ~UHID_NEEDCLEAR;
- usbd_clear_endpoint_stall(sc->sc_intrpipe);
- }
- }
- splx(s);
-
- /* Transfer as many chunks as possible. */
- while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0 && !error) {
- length = min(sc->sc_q.c_cc, uio->uio_resid);
- if (length > sizeof(buffer))
- length = sizeof(buffer);
-
- /* Remove a small chunk from the input queue. */
- (void) q_to_b(&sc->sc_q, buffer, length);
- DPRINTFN(5, ("uhidread: got %lu chars\n", (u_long)length));
-
- /* Copy the data to the user process. */
- if ((error = uiomove(buffer, length, uio)) != 0)
- break;
- }
-
- return (error);
-}
-
-int
-uhidread(struct cdev *dev, struct uio *uio, int flag)
-{
- struct uhid_softc *sc;
- int error;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
- sc->sc_refcnt++;
- error = uhid_do_read(sc, uio, flag);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-int
-uhid_do_write(struct uhid_softc *sc, struct uio *uio, int flag)
-{
- int error;
- int size;
- usbd_status err;
-
- DPRINTFN(1, ("uhidwrite\n"));
-
- if (sc->sc_dying)
- return (EIO);
-
- size = sc->sc_osize;
- error = 0;
- if (uio->uio_resid != size)
- return (EINVAL);
- error = uiomove(sc->sc_obuf, size, uio);
- if (!error) {
- if (sc->sc_oid)
- err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
- sc->sc_obuf[0], sc->sc_obuf+1, size-1);
- else
- err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
- 0, sc->sc_obuf, size);
- if (err)
- error = EIO;
- }
-
- return (error);
-}
-
-int
-uhidwrite(struct cdev *dev, struct uio *uio, int flag)
-{
- struct uhid_softc *sc;
- int error;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
- sc->sc_refcnt++;
- error = uhid_do_write(sc, uio, flag);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-int
-uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr, int flag,
- struct thread *p)
-{
- struct usb_ctl_report_desc *rd;
- struct usb_ctl_report *re;
- int size, id;
- usbd_status err;
-
- DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
-
- if (sc->sc_dying)
- return (EIO);
-
- switch (cmd) {
- case FIONBIO:
- /* All handled in the upper FS layer. */
- break;
-
- case FIOASYNC:
- if (*(int *)addr) {
- if (sc->sc_async != NULL)
- return (EBUSY);
- sc->sc_async = p->td_proc;
- DPRINTF(("uhid_do_ioctl: FIOASYNC %p\n", sc->sc_async));
- } else
- sc->sc_async = NULL;
- break;
-
- /* XXX this is not the most general solution. */
- case TIOCSPGRP:
- if (sc->sc_async == NULL)
- return (EINVAL);
- if (*(int *)addr != sc->sc_async->p_pgid)
- return (EPERM);
- break;
-
- case USB_GET_REPORT_DESC:
- rd = (struct usb_ctl_report_desc *)addr;
- size = min(sc->sc_repdesc_size, sizeof rd->ucrd_data);
- rd->ucrd_size = size;
- memcpy(rd->ucrd_data, sc->sc_repdesc, size);
- break;
-
- case USB_SET_IMMED:
- if (*(int *)addr) {
- /* XXX should read into ibuf, but does it matter? */
- err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
- sc->sc_iid, sc->sc_ibuf, sc->sc_isize);
- if (err)
- return (EOPNOTSUPP);
-
- sc->sc_state |= UHID_IMMED;
- } else
- sc->sc_state &= ~UHID_IMMED;
- break;
-
- case USB_GET_REPORT:
- re = (struct usb_ctl_report *)addr;
- switch (re->ucr_report) {
- case UHID_INPUT_REPORT:
- size = sc->sc_isize;
- id = sc->sc_iid;
- break;
- case UHID_OUTPUT_REPORT:
- size = sc->sc_osize;
- id = sc->sc_oid;
- break;
- case UHID_FEATURE_REPORT:
- size = sc->sc_fsize;
- id = sc->sc_fid;
- break;
- default:
- return (EINVAL);
- }
- err = usbd_get_report(sc->sc_iface, re->ucr_report, id, re->ucr_data,
- size);
- if (err)
- return (EIO);
- break;
-
- case USB_SET_REPORT:
- re = (struct usb_ctl_report *)addr;
- switch (re->ucr_report) {
- case UHID_INPUT_REPORT:
- size = sc->sc_isize;
- id = sc->sc_iid;
- break;
- case UHID_OUTPUT_REPORT:
- size = sc->sc_osize;
- id = sc->sc_oid;
- break;
- case UHID_FEATURE_REPORT:
- size = sc->sc_fsize;
- id = sc->sc_fid;
- break;
- default:
- return (EINVAL);
- }
- err = usbd_set_report(sc->sc_iface, re->ucr_report, id, re->ucr_data,
- size);
- if (err)
- return (EIO);
- break;
-
- case USB_GET_REPORT_ID:
- *(int *)addr = 0; /* XXX: we only support reportid 0? */
- break;
-
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-int
-uhidioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *p)
-{
- struct uhid_softc *sc;
- int error;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
- sc->sc_refcnt++;
- error = uhid_do_ioctl(sc, cmd, addr, flag, p);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-int
-uhidpoll(struct cdev *dev, int events, struct thread *p)
-{
- struct uhid_softc *sc;
- int revents = 0;
- int s;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
- if (sc->sc_dying)
- return (EIO);
-
- s = splusb();
- if (events & (POLLOUT | POLLWRNORM))
- revents |= events & (POLLOUT | POLLWRNORM);
- if (events & (POLLIN | POLLRDNORM)) {
- if (sc->sc_q.c_cc > 0)
- revents |= events & (POLLIN | POLLRDNORM);
- else
- selrecord(p, &sc->sc_rsel);
- }
-
- splx(s);
- return (revents);
-}
diff --git a/sys/legacy/dev/usb/uhub.c b/sys/legacy/dev/usb/uhub.c
deleted file mode 100644
index 86fbba2..0000000
--- a/sys/legacy/dev/usb/uhub.c
+++ /dev/null
@@ -1,703 +0,0 @@
-/* $NetBSD: uhub.c,v 1.68 2004/06/29 06:30:05 mycroft Exp $ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * USB spec: http://www.usb.org/developers/docs/usbspec.zip
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-
-#define UHUB_INTR_INTERVAL 255 /* ms */
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (uhubdebug) printf x
-#define DPRINTFN(n,x) if (uhubdebug > (n)) printf x
-#define DEVPRINTF(x) if (uhubdebug) device_printf x
-#define DEVPRINTFN(n, x)if (uhubdebug > (n)) device_printf x
-int uhubdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB uhub");
-SYSCTL_INT(_hw_usb_uhub, OID_AUTO, debug, CTLFLAG_RW,
- &uhubdebug, 0, "uhub debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#define DEVPRINTF(x)
-#define DEVPRINTFN(n,x)
-#endif
-
-struct uhub_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_hub; /* USB device */
- usbd_pipe_handle sc_ipipe; /* interrupt pipe */
- u_int8_t sc_status[32]; /* max 255 ports */
- u_char sc_running;
-};
-#define UHUB_PROTO(sc) ((sc)->sc_hub->ddesc.bDeviceProtocol)
-#define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
-#define UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
-
-static usbd_status uhub_explore(usbd_device_handle hub);
-static void uhub_intr(usbd_xfer_handle, usbd_private_handle,usbd_status);
-
-/*
- * We need two attachment points:
- * hub to usb and hub to hub
- * Every other driver only connects to hubs
- */
-
-static device_probe_t uhub_match;
-static device_attach_t uhub_attach;
-static device_detach_t uhub_detach;
-static bus_child_location_str_t uhub_child_location_str;
-static bus_child_pnpinfo_str_t uhub_child_pnpinfo_str;
-
-static device_method_t uhub_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uhub_match),
- DEVMETHOD(device_attach, uhub_attach),
- DEVMETHOD(device_detach, uhub_detach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str),
- DEVMETHOD(bus_child_location_str, uhub_child_location_str),
- /* XXX driver_added needs special care */
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
- { 0, 0 }
-};
-
-static driver_t uhub_driver = {
- "uhub",
- uhub_methods,
- sizeof(struct uhub_softc)
-};
-
-static devclass_t uhub_devclass;
-
-/* Create the driver instance for the hub connected to usb case. */
-devclass_t uhubroot_devclass;
-
-static device_method_t uhubroot_methods[] = {
- DEVMETHOD(device_probe, uhub_match),
- DEVMETHOD(device_attach, uhub_attach),
- DEVMETHOD(device_detach, uhub_detach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- DEVMETHOD(bus_child_location_str, uhub_child_location_str),
- DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str),
- /* XXX driver_added needs special care */
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
-
- {0,0}
-};
-
-static driver_t uhubroot_driver = {
- "uhub",
- uhubroot_methods,
- sizeof(struct uhub_softc)
-};
-
-static int
-uhub_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_device_descriptor_t *dd = usbd_get_device_descriptor(uaa->device);
-
- DPRINTFN(5,("uhub_match, dd=%p\n", dd));
- /*
- * The subclass for hubs seems to be 0 for some and 1 for others,
- * so we just ignore the subclass.
- */
- if (uaa->iface == NULL && dd->bDeviceClass == UDCLASS_HUB)
- return (UMATCH_DEVCLASS_DEVSUBCLASS);
- return (UMATCH_NONE);
-}
-
-int
-uhub_attach(device_t self)
-{
- struct uhub_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_status err;
- struct usbd_hub *hub = NULL;
- usb_device_request_t req;
- usb_hub_descriptor_t hubdesc;
- int p, port, nports, nremov, pwrdly;
- usbd_interface_handle iface;
- usb_endpoint_descriptor_t *ed;
- struct usbd_tt *tts = NULL;
-
- DPRINTFN(1,("uhub_attach\n"));
- sc->sc_hub = dev;
- sc->sc_dev = self;
-
- if (dev->depth > 0 && UHUB_IS_HIGH_SPEED(sc)) {
- device_printf(sc->sc_dev, "%s transaction translator%s\n",
- UHUB_IS_SINGLE_TT(sc) ? "single" : "multiple",
- UHUB_IS_SINGLE_TT(sc) ? "" : "s");
- }
- err = usbd_set_config_index(dev, 0, 1);
- if (err) {
- DEVPRINTF((sc->sc_dev, "configuration failed, error=%s\n",
- usbd_errstr(err)));
- return (ENXIO);
- }
-
- if (dev->depth > USB_HUB_MAX_DEPTH) {
- device_printf(sc->sc_dev, "hub depth (%d) exceeded, hub ignored\n",
- USB_HUB_MAX_DEPTH);
- return (ENXIO);
- }
-
- /* Get hub descriptor. */
- req.bmRequestType = UT_READ_CLASS_DEVICE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW2(req.wValue, (dev->address > 1 ? UDESC_HUB : 0), 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
- DPRINTFN(1,("usb_init_hub: getting hub descriptor\n"));
- err = usbd_do_request(dev, &req, &hubdesc);
- nports = hubdesc.bNbrPorts;
- if (!err && nports > 7) {
- USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE + (nports+1) / 8);
- err = usbd_do_request(dev, &req, &hubdesc);
- }
- if (err) {
- DEVPRINTF((sc->sc_dev, "getting hub descriptor failed: %s\n",
- usbd_errstr(err)));
- return (ENXIO);
- }
-
- for (nremov = 0, port = 1; port <= nports; port++)
- if (!UHD_NOT_REMOV(&hubdesc, port))
- nremov++;
- device_printf(sc->sc_dev, "%d port%s with %d removable, %s powered\n",
- nports, nports != 1 ? "s" : "", nremov,
- dev->self_powered ? "self" : "bus");
-
- if (nports == 0) {
- device_printf(sc->sc_dev, "no ports, hub ignored\n");
- goto bad;
- }
-
- hub = malloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port),
- M_USBDEV, M_NOWAIT);
- if (hub == NULL) {
- return (ENXIO);
- }
- dev->hub = hub;
- dev->hub->hubsoftc = sc;
- hub->explore = uhub_explore;
- hub->hubdesc = hubdesc;
-
- DPRINTFN(1,("usbhub_init_hub: selfpowered=%d, parent=%p, "
- "parent->selfpowered=%d\n",
- dev->self_powered, dev->powersrc->parent,
- dev->powersrc->parent ?
- dev->powersrc->parent->self_powered : 0));
-
- if (!dev->self_powered && dev->powersrc->parent != NULL &&
- !dev->powersrc->parent->self_powered) {
- device_printf(sc->sc_dev, "bus powered hub connected to bus "
- "powered hub, ignored\n");
- goto bad;
- }
-
- /* Set up interrupt pipe. */
- err = usbd_device2interface_handle(dev, 0, &iface);
- if (err) {
- device_printf(sc->sc_dev, "no interface handle\n");
- goto bad;
- }
- ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (ed == NULL) {
- device_printf(sc->sc_dev, "no endpoint descriptor\n");
- goto bad;
- }
- if ((ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
- device_printf(sc->sc_dev, "bad interrupt endpoint\n");
- goto bad;
- }
-
- err = usbd_open_pipe_intr(iface, ed->bEndpointAddress,
- USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_status,
- (nports + 1 + 7) / 8, uhub_intr, UHUB_INTR_INTERVAL);
- if (err) {
- device_printf(sc->sc_dev, "cannot open interrupt pipe\n");
- goto bad;
- }
-
- /* Wait with power off for a while. */
- usbd_delay_ms(dev, USB_POWER_DOWN_TIME);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, sc->sc_dev);
-
- /*
- * To have the best chance of success we do things in the exact same
- * order as Windoze98. This should not be necessary, but some
- * devices do not follow the USB specs to the letter.
- *
- * These are the events on the bus when a hub is attached:
- * Get device and config descriptors (see attach code)
- * Get hub descriptor (see above)
- * For all ports
- * turn on power
- * wait for power to become stable
- * (all below happens in explore code)
- * For all ports
- * clear C_PORT_CONNECTION
- * For all ports
- * get port status
- * if device connected
- * wait 100 ms
- * turn on reset
- * wait
- * clear C_PORT_RESET
- * get port status
- * proceed with device attachment
- */
-
- if (UHUB_IS_HIGH_SPEED(sc)) {
- tts = malloc((UHUB_IS_SINGLE_TT(sc) ? 1 : nports) *
- sizeof (struct usbd_tt), M_USBDEV, M_NOWAIT);
- if (!tts)
- goto bad;
- }
-
- /* Set up data structures */
- for (p = 0; p < nports; p++) {
- struct usbd_port *up = &hub->ports[p];
- up->device = NULL;
- up->parent = dev;
- up->portno = p+1;
- if (dev->self_powered)
- /* Self powered hub, give ports maximum current. */
- up->power = USB_MAX_POWER;
- else
- up->power = USB_MIN_POWER;
- up->restartcnt = 0;
- if (UHUB_IS_HIGH_SPEED(sc)) {
- up->tt = &tts[UHUB_IS_SINGLE_TT(sc) ? 0 : p];
- up->tt->hub = hub;
- } else {
- up->tt = NULL;
- }
- }
-
- /* XXX should check for none, individual, or ganged power? */
-
- pwrdly = dev->hub->hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR
- + USB_EXTRA_POWER_UP_TIME;
- for (port = 1; port <= nports; port++) {
- /* Turn the power on. */
- err = usbd_set_port_feature(dev, port, UHF_PORT_POWER);
- if (err)
- device_printf(sc->sc_dev,
- "port %d power on failed, %s\n", port,
- usbd_errstr(err));
- DPRINTF(("usb_init_port: turn on port %d power\n", port));
- /* Wait for stable power. */
- usbd_delay_ms(dev, pwrdly);
- }
-
- /* The usual exploration will finish the setup. */
-
- sc->sc_running = 1;
- return (0);
- bad:
- if (hub)
- free(hub, M_USBDEV);
- dev->hub = NULL;
- return (ENXIO);
-}
-
-usbd_status
-uhub_explore(usbd_device_handle dev)
-{
- usb_hub_descriptor_t *hd = &dev->hub->hubdesc;
- struct uhub_softc *sc = dev->hub->hubsoftc;
- struct usbd_port *up;
- usbd_status err;
- int speed;
- int port;
- int change, status;
-
- DPRINTFN(10, ("uhub_explore dev=%p addr=%d\n", dev, dev->address));
-
- if (!sc->sc_running)
- return (USBD_NOT_STARTED);
-
- /* Ignore hubs that are too deep. */
- if (dev->depth > USB_HUB_MAX_DEPTH)
- return (USBD_TOO_DEEP);
-
- for(port = 1; port <= hd->bNbrPorts; port++) {
- up = &dev->hub->ports[port-1];
- err = usbd_get_port_status(dev, port, &up->status);
- if (err) {
- DPRINTF(("uhub_explore: get port status failed, "
- "error=%s\n", usbd_errstr(err)));
- continue;
- }
- status = UGETW(up->status.wPortStatus);
- change = UGETW(up->status.wPortChange);
- DEVPRINTFN(3,(sc->sc_dev,
- "uhub_explore: port %d status 0x%04x 0x%04x\n", port,
- status, change));
- if (change & UPS_C_PORT_ENABLED) {
- DPRINTF(("uhub_explore: C_PORT_ENABLED 0x%x\n", change));
- usbd_clear_port_feature(dev, port, UHF_C_PORT_ENABLE);
- if (change & UPS_C_CONNECT_STATUS) {
- /* Ignore the port error if the device
- vanished. */
- } else if (status & UPS_PORT_ENABLED) {
- device_printf(sc->sc_dev,
- "illegal enable change, port %d\n", port);
- } else {
- /* Port error condition. */
- if (up->restartcnt) /* no message first time */
- device_printf(sc->sc_dev,
- "port error, restarting port %d\n",
- port);
-
- if (up->restartcnt++ < USBD_RESTART_MAX)
- goto disco;
- else
- device_printf(sc->sc_dev,
- "port error, giving up port %d\n",
- port);
- }
- }
- if (!(change & UPS_C_CONNECT_STATUS)) {
- DPRINTFN(3,("uhub_explore: port=%d !C_CONNECT_"
- "STATUS\n", port));
- /* No status change, just do recursive explore. */
- if (up->device != NULL && up->device->hub != NULL)
- up->device->hub->explore(up->device);
-#if 0 && defined(DIAGNOSTIC)
- if (up->device == NULL &&
- (status & UPS_CURRENT_CONNECT_STATUS))
- deivce_printf(sc->sc_dev,
- "connected, no device\n");
-#endif
- continue;
- }
-
- /* We have a connect status change, handle it. */
-
- DPRINTF(("uhub_explore: status change hub=%d port=%d\n",
- dev->address, port));
- usbd_clear_port_feature(dev, port, UHF_C_PORT_CONNECTION);
- /*usbd_clear_port_feature(dev, port, UHF_C_PORT_ENABLE);*/
- /*
- * If there is already a device on the port the change status
- * must mean that is has disconnected. Looking at the
- * current connect status is not enough to figure this out
- * since a new unit may have been connected before we handle
- * the disconnect.
- */
- disco:
- if (up->device != NULL) {
- /* Disconnected */
- DPRINTF(("uhub_explore: device addr=%d disappeared "
- "on port %d\n", up->device->address, port));
- usb_disconnect_port(up, sc->sc_dev);
- usbd_clear_port_feature(dev, port,
- UHF_C_PORT_CONNECTION);
- }
- if (!(status & UPS_CURRENT_CONNECT_STATUS)) {
- /* Nothing connected, just ignore it. */
- DPRINTFN(3,("uhub_explore: port=%d !CURRENT_CONNECT"
- "_STATUS\n", port));
- continue;
- }
-
- /* Connected */
-
- if (!(status & UPS_PORT_POWER))
- device_printf(sc->sc_dev,
- "strange, connected port %d has no power\n", port);
-
- /* Wait for maximum device power up time. */
- usbd_delay_ms(dev, USB_PORT_POWERUP_DELAY);
-
- /* Reset port, which implies enabling it. */
- if (usbd_reset_port(dev, port, &up->status)) {
- device_printf(sc->sc_dev, "port %d reset failed\n",
- port);
- continue;
- }
- /* Get port status again, it might have changed during reset */
- err = usbd_get_port_status(dev, port, &up->status);
- if (err) {
- DPRINTF(("uhub_explore: get port status failed, "
- "error=%s\n", usbd_errstr(err)));
- continue;
- }
- status = UGETW(up->status.wPortStatus);
- change = UGETW(up->status.wPortChange);
- if (!(status & UPS_CURRENT_CONNECT_STATUS)) {
- /* Nothing connected, just ignore it. */
-#ifdef DIAGNOSTIC
- device_printf(sc->sc_dev,
- "port %d, device disappeared after reset\n", port);
-#endif
- continue;
- }
-
-#if 0
- if (UHUB_IS_HIGH_SPEED(sc) && !(status & UPS_HIGH_SPEED)) {
- device_printf(sc->sc_dev,
- "port %d, transaction translation not implemented,"
- " low/full speed device ignored\n", port);
- continue;
- }
-#endif
-
- /* Figure out device speed */
- if (status & UPS_HIGH_SPEED)
- speed = USB_SPEED_HIGH;
- else if (status & UPS_LOW_SPEED)
- speed = USB_SPEED_LOW;
- else
- speed = USB_SPEED_FULL;
- /* Get device info and set its address. */
- err = usbd_new_device(sc->sc_dev, dev->bus,
- dev->depth + 1, speed, port, up);
- /* XXX retry a few times? */
- if (err) {
- DPRINTFN(-1,("uhub_explore: usb_new_device failed, "
- "error=%s\n", usbd_errstr(err)));
- /* Avoid addressing problems by disabling. */
- /* usbd_reset_port(dev, port, &up->status); */
-
- /*
- * The unit refused to accept a new address, or had
- * some other serious problem. Since we cannot leave
- * at 0 we have to disable the port instead.
- */
- device_printf(sc->sc_dev,
- "device problem (%s), disabling port %d\n",
- usbd_errstr(err), port);
- usbd_clear_port_feature(dev, port, UHF_PORT_ENABLE);
- } else {
- /* The port set up succeeded, reset error count. */
- up->restartcnt = 0;
-
- if (up->device->hub)
- up->device->hub->explore(up->device);
- }
- }
- return (USBD_NORMAL_COMPLETION);
-}
-
-/*
- * Called from process context when the hub is gone.
- * Detach all devices on active ports.
- */
-static int
-uhub_detach(device_t self)
-{
- struct uhub_softc *sc = device_get_softc(self);
- struct usbd_hub *hub = sc->sc_hub->hub;
- struct usbd_port *rup;
- int port, nports;
-
- DPRINTF(("uhub_detach: sc=%port\n", sc));
- if (hub == NULL) /* Must be partially working */
- return (0);
-
- usbd_abort_pipe(sc->sc_ipipe);
- usbd_close_pipe(sc->sc_ipipe);
-
- nports = hub->hubdesc.bNbrPorts;
- for(port = 0; port < nports; port++) {
- rup = &hub->ports[port];
- if (rup->device)
- usb_disconnect_port(rup, self);
- }
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_hub, sc->sc_dev);
-
- if (hub->ports[0].tt)
- free(hub->ports[0].tt, M_USBDEV);
- free(hub, M_USBDEV);
- sc->sc_hub->hub = NULL;
-
- return (0);
-}
-
-int
-uhub_child_location_str(device_t cbdev, device_t child, char *buf,
- size_t buflen)
-{
- struct uhub_softc *sc = device_get_softc(cbdev);
- usbd_device_handle devhub = sc->sc_hub;
- usbd_device_handle dev;
- int nports;
- int port;
- int i;
-
- mtx_lock(&Giant);
- nports = devhub->hub->hubdesc.bNbrPorts;
- for (port = 0; port < nports; port++) {
- dev = devhub->hub->ports[port].device;
- if (dev && dev->subdevs) {
- for (i = 0; dev->subdevs[i]; i++) {
- if (dev->subdevs[i] == child) {
- if (dev->ifacenums == NULL) {
- snprintf(buf, buflen,
- "port=%i", port);
- } else {
- snprintf(buf, buflen,
- "port=%i interface=%i",
- port, dev->ifacenums[i]);
- }
- goto found_dev;
- }
- }
- }
- }
- DPRINTFN(0,("uhub_child_location_str: device not on hub\n"));
- buf[0] = '\0';
-found_dev:
- mtx_unlock(&Giant);
- return (0);
-}
-
-int
-uhub_child_pnpinfo_str(device_t cbdev, device_t child, char *buf,
- size_t buflen)
-{
- struct uhub_softc *sc = device_get_softc(cbdev);
- usbd_device_handle devhub = sc->sc_hub;
- usbd_device_handle dev;
- struct usbd_interface *iface;
- char serial[128];
- int nports;
- int port;
- int i;
-
- mtx_lock(&Giant);
- nports = devhub->hub->hubdesc.bNbrPorts;
- for (port = 0; port < nports; port++) {
- dev = devhub->hub->ports[port].device;
- if (dev && dev->subdevs) {
- for (i = 0; dev->subdevs[i]; i++) {
- if (dev->subdevs[i] == child) {
- goto found_dev;
- }
- }
- }
- }
- DPRINTFN(0,("uhub_child_pnpinfo_str: device not on hub\n"));
- buf[0] = '\0';
- mtx_unlock(&Giant);
- return (0);
-
-found_dev:
- /* XXX can sleep */
- (void)usbd_get_string(dev, dev->ddesc.iSerialNumber, serial,
- sizeof(serial));
- if (dev->ifacenums == NULL) {
- snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
- "devclass=0x%02x devsubclass=0x%02x "
- "release=0x%04x sernum=\"%s\"",
- UGETW(dev->ddesc.idVendor), UGETW(dev->ddesc.idProduct),
- dev->ddesc.bDeviceClass, dev->ddesc.bDeviceSubClass,
- UGETW(dev->ddesc.bcdDevice), serial);
- } else {
- iface = &dev->ifaces[dev->ifacenums[i]];
- snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
- "devclass=0x%02x devsubclass=0x%02x "
- "release=0x%04x sernum=\"%s\" "
- "intclass=0x%02x intsubclass=0x%02x",
- UGETW(dev->ddesc.idVendor), UGETW(dev->ddesc.idProduct),
- dev->ddesc.bDeviceClass, dev->ddesc.bDeviceSubClass,
- UGETW(dev->ddesc.bcdDevice), serial,
- iface->idesc->bInterfaceClass,
- iface->idesc->bInterfaceSubClass);
- }
- mtx_unlock(&Giant);
- return (0);
-}
-
-/*
- * Hub interrupt.
- * This an indication that some port has changed status.
- * Notify the bus event handler thread that we need
- * to be explored again.
- */
-void
-uhub_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
-{
- struct uhub_softc *sc = addr;
-
- DPRINTFN(5,("uhub_intr: sc=%p\n", sc));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_ipipe);
- else if (status == USBD_NORMAL_COMPLETION)
- usb_needs_explore(sc->sc_hub);
-}
-
-MODULE_DEPEND(uhub, usb, 1, 1, 1);
-DRIVER_MODULE(uhub, usb, uhubroot_driver, uhubroot_devclass, 0, 0);
-DRIVER_MODULE(uhub, uhub, uhub_driver, uhub_devclass, usbd_driver_load, 0);
diff --git a/sys/legacy/dev/usb/uipaq.c b/sys/legacy/dev/usb/uipaq.c
deleted file mode 100644
index a231a67..0000000
--- a/sys/legacy/dev/usb/uipaq.c
+++ /dev/null
@@ -1,822 +0,0 @@
-/* $NetBSD: uipaq.c,v 1.4 2006/11/16 01:33:27 christos Exp $ */
-/* $OpenBSD: uipaq.c,v 1.1 2005/06/17 23:50:33 deraadt Exp $ */
-
-/*
- * Copyright (c) 2000-2005 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * iPAQ driver
- *
- * 19 July 2003: Incorporated changes suggested by Sam Lawrance from
- * the uppc module
- *
- *
- * Contact isis@cs.umd.edu if you have any questions/comments about this driver
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/module.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbcdc.h> /*UCDC_* stuff */
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/ucomvar.h>
-
-#ifdef UIPAQ_DEBUG
-#define DPRINTF(x) if (uipaqdebug) printf x
-#define DPRINTFN(n,x) if (uipaqdebug>(n)) printf x
-int uipaqdebug = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UIPAQ_CONFIG_NO 1
-#define UIPAQ_IFACE_INDEX 0
-
-#define UIPAQIBUFSIZE 1024
-#define UIPAQOBUFSIZE 1024
-
-struct uipaq_softc {
- struct ucom_softc sc_ucom;
- u_int16_t sc_lcr; /* state for DTR/RTS */
- u_int16_t sc_flags;
-
-};
-
-/* Callback routines */
-static void uipaq_set(void *, int, int, int);
-
-/* Support routines. */
-/* based on uppc module by Sam Lawrance */
-static void uipaq_dtr(struct uipaq_softc *sc, int onoff);
-static void uipaq_rts(struct uipaq_softc *sc, int onoff);
-static void uipaq_break(struct uipaq_softc* sc, int onoff);
-
-int uipaq_detach(device_t self);
-
-struct ucom_callback uipaq_callback = {
- .ucom_set = uipaq_set
-};
-
-struct uipaq_type {
- struct usb_devno uv_dev;
- u_int16_t uv_flags;
-};
-
-/*
- * Much of this list is generated from lists of other drivers that support
- * the same hardware. Numeric values are used where no usbdevs entries
- * exist.
- */
-static const struct uipaq_type uipaq_devs[] = {
- {{ 0x0104, 0x00be }, 0}, /* Socket USB Sync */
- {{ 0x04ad, 0x0301 }, 0}, /* USB Sync 0301 */
- {{ 0x04ad, 0x0302 }, 0}, /* USB Sync 0302 */
- {{ 0x04ad, 0x0303 }, 0}, /* USB Sync 0303 */
- {{ 0x04ad, 0x0306 }, 0}, /* GPS Pocket PC USB Sync */
- {{ 0x0536, 0x01a0 }, 0}, /* HHP PDT */
- {{ 0x067e, 0x1001 }, 0}, /* Intermec Mobile Computer */
- {{ 0x094b, 0x0001 }, 0}, /* Linkup Systems USB Sync */
- {{ 0x0960, 0x0065 }, 0}, /* BCOM USB Sync 0065 */
- {{ 0x0960, 0x0066 }, 0}, /* BCOM USB Sync 0066 */
- {{ 0x0960, 0x0067 }, 0}, /* BCOM USB Sync 0067 */
- {{ 0x0961, 0x0010 }, 0}, /* Portatec USB Sync */
- {{ 0x099e, 0x0052 }, 0}, /* Trimble GeoExplorer */
- {{ 0x099e, 0x4000 }, 0}, /* TDS Data Collector */
- {{ 0x0c44, 0x03a2 }, 0}, /* Motorola iDEN Smartphone */
- {{ 0x0c8e, 0x6000 }, 0}, /* Cesscom Luxian Series */
- {{ 0x0cad, 0x9001 }, 0}, /* Motorola PowerPad Pocket PCDevice */
- {{ 0x0f4e, 0x0200 }, 0}, /* Freedom Scientific USB Sync */
- {{ 0x0f98, 0x0201 }, 0}, /* Cyberbank USB Sync */
- {{ 0x0fb8, 0x3001 }, 0}, /* Wistron USB Sync */
- {{ 0x0fb8, 0x3002 }, 0}, /* Wistron USB Sync */
- {{ 0x0fb8, 0x3003 }, 0}, /* Wistron USB Sync */
- {{ 0x0fb8, 0x4001 }, 0}, /* Wistron USB Sync */
- {{ 0x1066, 0x00ce }, 0}, /* E-TEN USB Sync */
- {{ 0x1066, 0x0300 }, 0}, /* E-TEN P3XX Pocket PC */
- {{ 0x1066, 0x0500 }, 0}, /* E-TEN P5XX Pocket PC */
- {{ 0x1066, 0x0600 }, 0}, /* E-TEN P6XX Pocket PC */
- {{ 0x1066, 0x0700 }, 0}, /* E-TEN P7XX Pocket PC */
- {{ 0x1114, 0x0001 }, 0}, /* Psion Teklogix Sync 753x */
- {{ 0x1114, 0x0004 }, 0}, /* Psion Teklogix Sync netBookPro */
- {{ 0x1114, 0x0006 }, 0}, /* Psion Teklogix Sync 7525 */
- {{ 0x1182, 0x1388 }, 0}, /* VES USB Sync */
- {{ 0x11d9, 0x1002 }, 0}, /* Rugged Pocket PC 2003 */
- {{ 0x11d9, 0x1003 }, 0}, /* Rugged Pocket PC 2003 */
- {{ 0x1231, 0xce01 }, 0}, /* USB Sync 03 */
- {{ 0x1231, 0xce02 }, 0}, /* USB Sync 03 */
- {{ 0x3340, 0x011c }, 0}, /* Mio DigiWalker PPC StrongARM */
- {{ 0x3340, 0x0326 }, 0}, /* Mio DigiWalker 338 */
- {{ 0x3340, 0x0426 }, 0}, /* Mio DigiWalker 338 */
- {{ 0x3340, 0x043a }, 0}, /* Mio DigiWalker USB Sync */
- {{ 0x3340, 0x051c }, 0}, /* MiTAC USB Sync 528 */
- {{ 0x3340, 0x053a }, 0}, /* Mio DigiWalker SmartPhone USB Sync */
- {{ 0x3340, 0x071c }, 0}, /* MiTAC USB Sync */
- {{ 0x3340, 0x0b1c }, 0}, /* Generic PPC StrongARM */
- {{ 0x3340, 0x0e3a }, 0}, /* Generic PPC USB Sync */
- {{ 0x3340, 0x0f1c }, 0}, /* Itautec USB Sync */
- {{ 0x3340, 0x0f3a }, 0}, /* Generic SmartPhone USB Sync */
- {{ 0x3340, 0x1326 }, 0}, /* Itautec USB Sync */
- {{ 0x3340, 0x191c }, 0}, /* YAKUMO USB Sync */
- {{ 0x3340, 0x2326 }, 0}, /* Vobis USB Sync */
- {{ 0x3340, 0x3326 }, 0}, /* MEDION Winodws Moble USB Sync */
- {{ 0x3708, 0x20ce }, 0}, /* Legend USB Sync */
- {{ 0x3708, 0x21ce }, 0}, /* Lenovo USB Sync */
- {{ 0x4113, 0x0210 }, 0}, /* Mobile Media Technology USB Sync */
- {{ 0x4113, 0x0211 }, 0}, /* Mobile Media Technology USB Sync */
- {{ 0x4113, 0x0400 }, 0}, /* Mobile Media Technology USB Sync */
- {{ 0x4113, 0x0410 }, 0}, /* Mobile Media Technology USB Sync */
- {{ 0x4505, 0x0010 }, 0}, /* Smartphone */
- {{ 0x5e04, 0xce00 }, 0}, /* SAGEM Wireless Assistant */
- {{ USB_VENDOR_ACER, 0x1631 }, 0}, /* c10 Series */
- {{ USB_VENDOR_ACER, 0x1632 }, 0}, /* c20 Series */
- {{ USB_VENDOR_ACER, 0x16e1 }, 0}, /* Acer n10 Handheld USB Sync */
- {{ USB_VENDOR_ACER, 0x16e2 }, 0}, /* Acer n20 Handheld USB Sync */
- {{ USB_VENDOR_ACER, 0x16e3 }, 0}, /* Acer n30 Handheld USB Sync */
- {{ USB_VENDOR_ASUS, 0x4200 }, 0}, /* ASUS USB Sync */
- {{ USB_VENDOR_ASUS, 0x4201 }, 0}, /* ASUS USB Sync */
- {{ USB_VENDOR_ASUS, 0x4202 }, 0}, /* ASUS USB Sync */
- {{ USB_VENDOR_ASUS, 0x9200 }, 0}, /* ASUS USB Sync */
- {{ USB_VENDOR_ASUS, 0x9202 }, 0}, /* ASUS USB Sync */
- {{ USB_VENDOR_ASUS, USB_PRODUCT_ASUS_P535 }, 0},
- {{ USB_VENDOR_CASIO, 0x2001 }, 0}, /* CASIO USB Sync 2001 */
- {{ USB_VENDOR_CASIO, 0x2003 }, 0}, /* CASIO USB Sync 2003 */
- {{ USB_VENDOR_CASIO, USB_PRODUCT_CASIO_BE300 } , 0},
- {{ USB_VENDOR_COMPAL, 0x0531 }, 0}, /* MyGuide 7000 XL USB Sync */
- {{ USB_VENDOR_COMPAQ, 0x0032 }, 0}, /* Compaq iPAQ USB Sync */
- {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQPOCKETPC } , 0},
- {{ USB_VENDOR_DELL, 0x4001 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4002 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4003 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4004 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4005 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4006 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4007 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4008 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4009 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_FSC, 0x1001 }, 0}, /* Fujitsu Siemens Computers USB Sync */
- {{ USB_VENDOR_FUJITSU, 0x1058 }, 0}, /* FUJITSU USB Sync */
- {{ USB_VENDOR_FUJITSU, 0x1079 }, 0}, /* FUJITSU USB Sync */
- {{ USB_VENDOR_GIGASET, 0x0601 }, 0}, /* Askey USB Sync */
- {{ USB_VENDOR_HITACHI, 0x0014 }, 0}, /* Hitachi USB Sync */
- {{ USB_VENDOR_HP, 0x1216 }, 0}, /* HP USB Sync 1612 */
- {{ USB_VENDOR_HP, 0x2016 }, 0}, /* HP USB Sync 1620 */
- {{ USB_VENDOR_HP, 0x2116 }, 0}, /* HP USB Sync 1621 */
- {{ USB_VENDOR_HP, 0x2216 }, 0}, /* HP USB Sync 1622 */
- {{ USB_VENDOR_HP, 0x3016 }, 0}, /* HP USB Sync 1630 */
- {{ USB_VENDOR_HP, 0x3116 }, 0}, /* HP USB Sync 1631 */
- {{ USB_VENDOR_HP, 0x3216 }, 0}, /* HP USB Sync 1632 */
- {{ USB_VENDOR_HP, 0x4016 }, 0}, /* HP USB Sync 1640 */
- {{ USB_VENDOR_HP, 0x4116 }, 0}, /* HP USB Sync 1641 */
- {{ USB_VENDOR_HP, 0x4216 }, 0}, /* HP USB Sync 1642 */
- {{ USB_VENDOR_HP, 0x5016 }, 0}, /* HP USB Sync 1650 */
- {{ USB_VENDOR_HP, 0x5116 }, 0}, /* HP USB Sync 1651 */
- {{ USB_VENDOR_HP, 0x5216 }, 0}, /* HP USB Sync 1652 */
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_2215 }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_568J }, 0},
- {{ USB_VENDOR_HTC, 0x00cf }, 0}, /* HTC USB Modem */
- {{ USB_VENDOR_HTC, 0x0a01 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a02 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a03 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a04 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a05 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a06 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a07 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a08 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a09 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0a }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0b }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0c }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0d }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0e }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0f }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a10 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a11 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a12 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a13 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a14 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a15 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a16 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a17 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a18 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a19 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1a }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1b }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1c }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1d }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1e }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1f }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a20 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a21 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a22 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a23 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a24 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a25 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a26 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a27 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a28 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a29 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2a }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2b }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2c }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2d }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2e }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2f }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a30 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a31 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a32 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a33 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a34 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a35 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a36 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a37 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a38 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a39 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3a }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3b }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3c }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3d }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3e }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3f }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a40 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a41 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a42 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a43 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a44 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a45 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a46 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a47 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a48 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a49 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4a }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4b }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4c }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4d }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4e }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4f }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a50 }, 0}, /* HTC SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a52 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a53 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a54 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a55 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a56 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a57 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a58 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a59 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5a }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5b }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5c }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5d }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5e }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5f }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a60 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a61 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a62 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a63 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a64 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a65 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a66 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a67 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a68 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a69 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6a }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6b }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6c }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6d }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6e }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6f }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a70 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a71 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a72 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a73 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a74 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a75 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a76 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a77 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a78 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a79 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7a }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7b }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7c }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7d }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7e }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7f }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a80 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a81 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a82 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a83 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a84 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a85 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a86 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a87 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a88 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a89 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8a }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8b }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8c }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8d }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8e }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8f }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a90 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a91 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a92 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a93 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a94 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a95 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a96 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a97 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a98 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a99 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9a }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9b }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9c }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9d }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9e }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9f }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0bce }, 0}, /* "High Tech Computer Corp" */
- {{ USB_VENDOR_HTC, USB_PRODUCT_HTC_PPC6700MODEM }, 0},
- {{ USB_VENDOR_HTC, USB_PRODUCT_HTC_SMARTPHONE }, 0},
- {{ USB_VENDOR_HTC, USB_PRODUCT_HTC_WINMOBILE }, 0},
- {{ USB_VENDOR_JVC, 0x3011 }, 0}, /* JVC USB Sync */
- {{ USB_VENDOR_JVC, 0x3012 }, 0}, /* JVC USB Sync */
- {{ USB_VENDOR_LG, 0x9c01 }, 0}, /* LGE USB Sync */
- {{ USB_VENDOR_MICROSOFT, 0x00ce }, 0}, /* Microsoft USB Sync */
- {{ USB_VENDOR_MICROSOFT, 0x0400 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0401 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0402 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0403 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0404 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0405 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0406 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0407 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0408 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0409 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040a }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040b }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040c }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040d }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040e }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040f }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0410 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0411 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0412 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0413 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0414 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0415 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0416 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0417 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0432 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0433 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0434 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0435 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0436 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0437 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0438 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0439 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043a }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043b }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043c }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043d }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043e }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043f }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0440 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0441 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0442 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0443 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0444 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0445 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0446 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0447 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0448 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0449 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044a }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044b }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044c }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044d }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044e }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044f }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0450 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0451 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0452 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0453 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0454 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0455 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0456 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0457 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0458 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0459 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045a }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045b }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045c }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045d }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045e }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045f }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0460 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0461 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0462 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0463 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0464 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0465 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0466 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0467 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0468 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0469 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046a }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046b }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046c }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046d }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046e }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046f }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0470 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0471 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0472 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0473 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0474 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0475 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0476 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0477 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0478 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0479 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x047a }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x047b }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04c8 }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04c9 }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04ca }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04cb }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04cc }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04cd }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04ce }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04d7 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04d8 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04d9 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04da }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04db }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04dc }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04dd }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04de }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04df }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e0 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e1 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e2 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e3 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e4 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e5 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e6 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e7 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e8 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e9 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04ea }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MOTOROLA2, 0x4204 }, 0}, /* Motorola MPx200 Smartphone */
- {{ USB_VENDOR_MOTOROLA2, 0x4214 }, 0}, /* Motorola MPc GSM */
- {{ USB_VENDOR_MOTOROLA2, 0x4224 }, 0}, /* Motorola MPx220 Smartphone */
- {{ USB_VENDOR_MOTOROLA2, 0x4234 }, 0}, /* Motorola MPc CDMA */
- {{ USB_VENDOR_MOTOROLA2, 0x4244 }, 0}, /* Motorola MPx100 Smartphone */
- {{ USB_VENDOR_NEC, 0x00d5 }, 0}, /* NEC USB Sync */
- {{ USB_VENDOR_NEC, 0x00d6 }, 0}, /* NEC USB Sync */
- {{ USB_VENDOR_NEC, 0x00d7 }, 0}, /* NEC USB Sync */
- {{ USB_VENDOR_NEC, 0x8024 }, 0}, /* NEC USB Sync */
- {{ USB_VENDOR_NEC, 0x8025 }, 0}, /* NEC USB Sync */
- {{ USB_VENDOR_PANASONIC, 0x2500 }, 0}, /* Panasonic USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x5f00 }, 0}, /* Samsung NEXiO USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x5f01 }, 0}, /* Samsung NEXiO USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x5f02 }, 0}, /* Samsung NEXiO USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x5f03 }, 0}, /* Samsung NEXiO USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x5f04 }, 0}, /* Samsung NEXiO USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6611 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6613 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6615 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6617 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6619 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x661b }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x662e }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6630 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6632 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SHARP, 0x9102 }, 0}, /* SHARP WS003SH USB Modem */
- {{ USB_VENDOR_SHARP, 0x9121 }, 0}, /* SHARP WS004SH USB Modem */
- {{ USB_VENDOR_SHARP, 0x9151 }, 0}, /* SHARP S01SH USB Modem */
- {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_WZERO3ES }, 0},
- {{ USB_VENDOR_SYMBOL, 0x2000 }, 0}, /* Symbol USB Sync */
- {{ USB_VENDOR_SYMBOL, 0x2001 }, 0}, /* Symbol USB Sync 0x2001 */
- {{ USB_VENDOR_SYMBOL, 0x2002 }, 0}, /* Symbol USB Sync 0x2002 */
- {{ USB_VENDOR_SYMBOL, 0x2003 }, 0}, /* Symbol USB Sync 0x2003 */
- {{ USB_VENDOR_SYMBOL, 0x2004 }, 0}, /* Symbol USB Sync 0x2004 */
- {{ USB_VENDOR_SYMBOL, 0x2005 }, 0}, /* Symbol USB Sync 0x2005 */
- {{ USB_VENDOR_SYMBOL, 0x2006 }, 0}, /* Symbol USB Sync 0x2006 */
- {{ USB_VENDOR_SYMBOL, 0x2007 }, 0}, /* Symbol USB Sync 0x2007 */
- {{ USB_VENDOR_SYMBOL, 0x2008 }, 0}, /* Symbol USB Sync 0x2008 */
- {{ USB_VENDOR_SYMBOL, 0x2009 }, 0}, /* Symbol USB Sync 0x2009 */
- {{ USB_VENDOR_SYMBOL, 0x200a }, 0}, /* Symbol USB Sync 0x200a */
- {{ USB_VENDOR_TOSHIBA, 0x0700 }, 0}, /* TOSHIBA USB Sync 0700 */
- {{ USB_VENDOR_TOSHIBA, 0x0705 }, 0}, /* TOSHIBA Pocket PC e310 */
- {{ USB_VENDOR_TOSHIBA, 0x0707 }, 0}, /* TOSHIBA Pocket PC e330 Series */
- {{ USB_VENDOR_TOSHIBA, 0x0708 }, 0}, /* TOSHIBA Pocket PC e350Series */
- {{ USB_VENDOR_TOSHIBA, 0x0709 }, 0}, /* TOSHIBA Pocket PC e750 Series */
- {{ USB_VENDOR_TOSHIBA, 0x070a }, 0}, /* TOSHIBA Pocket PC e400 Series */
- {{ USB_VENDOR_TOSHIBA, 0x070b }, 0}, /* TOSHIBA Pocket PC e800 Series */
- {{ USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_POCKETPC_E740 }, 0}, /* TOSHIBA Pocket PC e740 */
- {{ USB_VENDOR_VIEWSONIC, 0x0ed9 }, 0}, /* ViewSonic Color Pocket PC V35 */
- {{ USB_VENDOR_VIEWSONIC, 0x1527 }, 0}, /* ViewSonic Color Pocket PC V36 */
- {{ USB_VENDOR_VIEWSONIC, 0x1529 }, 0}, /* ViewSonic Color Pocket PC V37 */
- {{ USB_VENDOR_VIEWSONIC, 0x152b }, 0}, /* ViewSonic Color Pocket PC V38 */
- {{ USB_VENDOR_VIEWSONIC, 0x152e }, 0}, /* ViewSonic Pocket PC */
- {{ USB_VENDOR_VIEWSONIC, 0x1921 }, 0}, /* ViewSonic Communicator Pocket PC */
- {{ USB_VENDOR_VIEWSONIC, 0x1922 }, 0}, /* ViewSonic Smartphone */
- {{ USB_VENDOR_VIEWSONIC, 0x1923 }, 0}, /* ViewSonic Pocket PC V30 */
-};
-
-#define uipaq_lookup(v, p) ((const struct uipaq_type *)usb_lookup(uipaq_devs, v, p))
-
-static int
-uipaq_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- DPRINTFN(20,("uipaq: vendor=0x%x, product=0x%x\n",
- uaa->vendor, uaa->product));
-
- return (uipaq_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-static int
-uipaq_attach(device_t self)
-{
- usb_device_request_t req;
- struct uipaq_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_interface_handle iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
-
- DPRINTFN(10,("\nuipaq_attach: sc=%p\n", sc));
-
- /* Move the device into the configured state. */
- err = usbd_set_config_no(dev, UIPAQ_CONFIG_NO, 1);
- if (err) {
- device_printf(ucom->sc_dev,
- "failed to set configuration: %s\n", usbd_errstr(err));
- goto bad;
- }
-
- err = usbd_device2interface_handle(dev, UIPAQ_IFACE_INDEX, &iface);
- if (err) {
- device_printf(ucom->sc_dev, "failed to get interface: %s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- sc->sc_flags = uipaq_lookup(uaa->vendor, uaa->product)->uv_flags;
- id = usbd_get_interface_descriptor(iface);
- ucom->sc_iface = iface;
- ucom->sc_ibufsize = UIPAQIBUFSIZE;
- ucom->sc_obufsize = UIPAQOBUFSIZE;
- ucom->sc_ibufsizepad = UIPAQIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &uipaq_callback;
- ucom->sc_parent = sc;
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- for (i=0; i<id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- device_printf(ucom->sc_dev,
- "no endpoint descriptor for %d\n", i);
- goto bad;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
- }
- if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) {
- device_printf(ucom->sc_dev,
- "no proper endpoints found (%d,%d)\n",
- ucom->sc_bulkin_no, ucom->sc_bulkout_no);
- return (ENXIO);
- }
- /*
- * Send magic bytes, cribbed from Linux ipaq driver that claims
- * to have sniffed them from Win98.
- */
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, UCDC_LINE_DTR);
- USETW(req.wIndex, 0x0);
- USETW(req.wLength, 0);
- for (i = 0; i < 100; i++) {
- err = usbd_do_request_flags(ucom->sc_udev, &req, NULL, 0, NULL, 100);
- if (!err)
- break;
- usbd_delay_ms(dev, 1000);
- }
- ucom_attach(&sc->sc_ucom);
- return (0);
-bad:
- DPRINTF(("uipaq_attach: ATTACH ERROR\n"));
- ucom->sc_dying = 1;
- return (ENXIO);
-}
-
-void
-uipaq_dtr(struct uipaq_softc* sc, int onoff)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- usbd_status err;
- int retries = 3;
-
- DPRINTF(("%s: uipaq_dtr: onoff=%x\n", device_get_nameunit(ucom->sc_dev), onoff));
-
- /* Avoid sending unnecessary requests */
- if (onoff && (sc->sc_lcr & UCDC_LINE_DTR))
- return;
- if (!onoff && !(sc->sc_lcr & UCDC_LINE_DTR))
- return;
-
- /* Other parameters depend on reg */
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- sc->sc_lcr = onoff ? sc->sc_lcr | UCDC_LINE_DTR : sc->sc_lcr & ~UCDC_LINE_DTR;
- USETW(req.wValue, sc->sc_lcr);
- USETW(req.wIndex, 0x0);
- USETW(req.wLength, 0);
-
- /* Fire off the request a few times if necessary */
- while (retries) {
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (!err)
- break;
- retries--;
- }
-}
-
-void
-uipaq_rts(struct uipaq_softc* sc, int onoff)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- usbd_status err;
- int retries = 3;
-
- DPRINTF(("%s: uipaq_rts: onoff=%x\n", device_get_nameunit(ucom->sc_dev), onoff));
-
- /* Avoid sending unnecessary requests */
- if (onoff && (sc->sc_lcr & UCDC_LINE_RTS)) return;
- if (!onoff && !(sc->sc_lcr & UCDC_LINE_RTS)) return;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- sc->sc_lcr = onoff ? sc->sc_lcr | UCDC_LINE_RTS : sc->sc_lcr & ~UCDC_LINE_RTS;
- USETW(req.wValue, sc->sc_lcr);
- USETW(req.wIndex, 0x0);
- USETW(req.wLength, 0);
-
- while (retries) {
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (!err)
- break;
- retries--;
- }
-}
-
-void
-uipaq_break(struct uipaq_softc* sc, int onoff)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- usbd_status err;
- int retries = 3;
-
- DPRINTF(("%s: uipaq_break: onoff=%x\n", device_get_nameunit(ucom->sc_dev), onoff));
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
-
- USETW(req.wValue, onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF);
- USETW(req.wIndex, 0x0);
- USETW(req.wLength, 0);
-
- while (retries) {
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (!err)
- break;
- retries--;
- }
-}
-
-void
-uipaq_set(void *addr, int portno, int reg, int onoff)
-{
- struct uipaq_softc* sc = addr;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- switch (reg) {
- case UCOM_SET_DTR:
- uipaq_dtr(addr, onoff);
- break;
- case UCOM_SET_RTS:
- uipaq_rts(addr, onoff);
- break;
- case UCOM_SET_BREAK:
- uipaq_break(addr, onoff);
- break;
- default:
- printf("%s: unhandled set request: reg=%x onoff=%x\n",
- device_get_nameunit(ucom->sc_dev), reg, onoff);
- return;
- }
-}
-
-int
-uipaq_detach(device_t self)
-{
- struct uipaq_softc *sc = device_get_softc(self);
- struct ucom_softc *ucom = &sc->sc_ucom;
- int rv = 0;
-
- DPRINTF(("uipaq_detach: sc=%p flags=%d\n", sc, flags));
- ucom->sc_dying = 1;
-
- rv = ucom_detach(ucom);
-
- return (rv);
-}
-
-static device_method_t uipaq_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uipaq_match),
- DEVMETHOD(device_attach, uipaq_attach),
- DEVMETHOD(device_detach, uipaq_detach),
-
- { 0, 0 }
-};
-static driver_t uipaq_driver = {
- "ucom",
- uipaq_methods,
- sizeof (struct uipaq_softc)
-};
-
-DRIVER_MODULE(uipaq, uhub, uipaq_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uipaq, usb, 1, 1, 1);
-MODULE_DEPEND(uipaq, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
diff --git a/sys/legacy/dev/usb/ukbd.c b/sys/legacy/dev/usb/ukbd.c
deleted file mode 100644
index 5a7c9fc..0000000
--- a/sys/legacy/dev/usb/ukbd.c
+++ /dev/null
@@ -1,1538 +0,0 @@
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
- */
-
-#include "opt_compat.h"
-#include "opt_kbd.h"
-#include "opt_ukbd.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/ioccom.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/file.h>
-#include <sys/limits.h>
-#include <sys/selinfo.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-#include <dev/usb/hid.h>
-
-#include <sys/kbio.h>
-#include <dev/kbd/kbdreg.h>
-
-#define UKBD_EMULATE_ATSCANCODE 1
-
-#define DRIVER_NAME "ukbd"
-
-#define delay(d) DELAY(d)
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (ukbddebug) printf x
-#define DPRINTFN(n,x) if (ukbddebug>(n)) printf x
-int ukbddebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ukbd, CTLFLAG_RW, 0, "USB ukbd");
-SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, debug, CTLFLAG_RW,
- &ukbddebug, 0, "ukbd debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UPROTO_BOOT_KEYBOARD 1
-
-#define NKEYCODE 6
-
-struct ukbd_data {
- u_int8_t modifiers;
-#define MOD_CONTROL_L 0x01
-#define MOD_CONTROL_R 0x10
-#define MOD_SHIFT_L 0x02
-#define MOD_SHIFT_R 0x20
-#define MOD_ALT_L 0x04
-#define MOD_ALT_R 0x40
-#define MOD_WIN_L 0x08
-#define MOD_WIN_R 0x80
- u_int8_t reserved;
- u_int8_t keycode[NKEYCODE];
-};
-
-#define MAXKEYS (NMOD+2*NKEYCODE)
-
-typedef struct ukbd_softc {
- device_t sc_dev; /* base device */
-} ukbd_softc_t;
-
-#define UKBD_CHUNK 128 /* chunk size for read */
-#define UKBD_BSIZE 1020 /* buffer size */
-
-typedef void usbd_intr_t(usbd_xfer_handle, usbd_private_handle, usbd_status);
-typedef void usbd_disco_t(void *);
-
-static usbd_intr_t ukbd_intr;
-static int ukbd_driver_load(module_t mod, int what, void *arg);
-
-static device_probe_t ukbd_match;
-static device_attach_t ukbd_attach;
-static device_detach_t ukbd_detach;
-static device_resume_t ukbd_resume;
-
-static device_method_t ukbd_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ukbd_match),
- DEVMETHOD(device_attach, ukbd_attach),
- DEVMETHOD(device_detach, ukbd_detach),
- DEVMETHOD(device_resume, ukbd_resume),
-
- { 0, 0 }
-};
-
-static driver_t ukbd_driver = {
- "ukbd",
- ukbd_methods,
- sizeof(struct ukbd_softc)
-};
-
-static devclass_t ukbd_devclass;
-
-MODULE_DEPEND(ukbd, usb, 1, 1, 1);
-DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0);
-
-static int
-ukbd_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- keyboard_switch_t *sw;
- void *arg[2];
- int unit = device_get_unit(self);
-
- sw = kbd_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return (UMATCH_NONE);
-
- arg[0] = (void *)uaa;
- arg[1] = (void *)ukbd_intr;
- if ((*sw->probe)(unit, (void *)arg, 0))
- return (UMATCH_NONE);
-
- if (usbd_get_quirks(uaa->device)->uq_flags & UQ_KBD_IGNORE)
- return (UMATCH_NONE);
-
- return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
-}
-
-static int
-ukbd_attach(device_t self)
-{
- struct ukbd_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
-
- keyboard_switch_t *sw;
- keyboard_t *kbd;
- void *arg[2];
- int unit = device_get_unit(self);
-
- sc->sc_dev = self;
- sw = kbd_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return ENXIO;
-
- id = usbd_get_interface_descriptor(iface);
-
- arg[0] = (void *)uaa;
- arg[1] = (void *)ukbd_intr;
- kbd = NULL;
- if ((*sw->probe)(unit, (void *)arg, 0))
- return ENXIO;
- if ((*sw->init)(unit, &kbd, (void *)arg, 0))
- return ENXIO;
- (*sw->enable)(kbd);
-
-#ifdef KBD_INSTALL_CDEV
- if (kbd_attach(kbd))
- return ENXIO;
-#endif
- if (bootverbose)
- (*sw->diag)(kbd, bootverbose);
-
- return 0;
-}
-
-int
-ukbd_detach(device_t self)
-{
- keyboard_t *kbd;
- int error;
-
- kbd = kbd_get_keyboard(kbd_find_keyboard(DRIVER_NAME,
- device_get_unit(self)));
- if (kbd == NULL) {
- DPRINTF(("%s: keyboard not attached!?\n", device_get_nameunit(self)));
- return ENXIO;
- }
- kbdd_disable(kbd);
-
-#ifdef KBD_INSTALL_CDEV
- error = kbd_detach(kbd);
- if (error)
- return error;
-#endif
- error = kbdd_term(kbd);
- if (error)
- return error;
-
- DPRINTF(("%s: disconnected\n", device_get_nameunit(self)));
-
- return (0);
-}
-
-static int
-ukbd_resume(device_t self)
-{
- keyboard_t *kbd;
-
- kbd = kbd_get_keyboard(kbd_find_keyboard(DRIVER_NAME,
- device_get_unit(self)));
- if (kbd)
- kbdd_clear_state(kbd);
- return (0);
-}
-
-void
-ukbd_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
-{
- keyboard_t *kbd = (keyboard_t *)addr;
-
- kbdd_intr(kbd, (void *)status);
-}
-
-#define UKBD_DEFAULT 0
-
-#define KEY_ERROR 0x01
-
-#define KEY_PRESS 0
-#define KEY_RELEASE 0x400
-#define KEY_INDEX(c) ((c) & ~KEY_RELEASE)
-
-#define SCAN_PRESS 0
-#define SCAN_RELEASE 0x80
-#define SCAN_PREFIX_E0 0x100
-#define SCAN_PREFIX_E1 0x200
-#define SCAN_PREFIX_CTL 0x400
-#define SCAN_PREFIX_SHIFT 0x800
-#define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL \
- | SCAN_PREFIX_SHIFT)
-#define SCAN_CHAR(c) ((c) & 0x7f)
-
-#define NMOD 8
-static struct {
- int mask, key;
-} ukbd_mods[NMOD] = {
- { MOD_CONTROL_L, 0xe0 },
- { MOD_CONTROL_R, 0xe4 },
- { MOD_SHIFT_L, 0xe1 },
- { MOD_SHIFT_R, 0xe5 },
- { MOD_ALT_L, 0xe2 },
- { MOD_ALT_R, 0xe6 },
- { MOD_WIN_L, 0xe3 },
- { MOD_WIN_R, 0xe7 },
-};
-
-#define NN 0 /* no translation */
-/*
- * Translate USB keycodes to AT keyboard scancodes.
- */
-/*
- * FIXME: Mac USB keyboard generates:
- * 0x53: keypad NumLock/Clear
- * 0x66: Power
- * 0x67: keypad =
- * 0x68: F13
- * 0x69: F14
- * 0x6a: F15
- */
-static u_int8_t ukbd_trtab[256] = {
- 0, 0, 0, 0, 30, 48, 46, 32, /* 00 - 07 */
- 18, 33, 34, 35, 23, 36, 37, 38, /* 08 - 0F */
- 50, 49, 24, 25, 16, 19, 31, 20, /* 10 - 17 */
- 22, 47, 17, 45, 21, 44, 2, 3, /* 18 - 1F */
- 4, 5, 6, 7, 8, 9, 10, 11, /* 20 - 27 */
- 28, 1, 14, 15, 57, 12, 13, 26, /* 28 - 2F */
- 27, 43, 43, 39, 40, 41, 51, 52, /* 30 - 37 */
- 53, 58, 59, 60, 61, 62, 63, 64, /* 38 - 3F */
- 65, 66, 67, 68, 87, 88, 92, 70, /* 40 - 47 */
- 104, 102, 94, 96, 103, 99, 101, 98, /* 48 - 4F */
- 97, 100, 95, 69, 91, 55, 74, 78, /* 50 - 57 */
- 89, 79, 80, 81, 75, 76, 77, 71, /* 58 - 5F */
- 72, 73, 82, 83, 86, 107, 122, NN, /* 60 - 67 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 68 - 6F */
- NN, NN, NN, NN, 115, 108, 111, 113, /* 70 - 77 */
- 109, 110, 112, 118, 114, 116, 117, 119, /* 78 - 7F */
- 121, 120, NN, NN, NN, NN, NN, 115, /* 80 - 87 */
- 112, 125, 121, 123, NN, NN, NN, NN, /* 88 - 8F */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 90 - 97 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 98 - 9F */
- NN, NN, NN, NN, NN, NN, NN, NN, /* A0 - A7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* A8 - AF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* B0 - B7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* B8 - BF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* C0 - C7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* C8 - CF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* D0 - D7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* D8 - DF */
- 29, 42, 56, 105, 90, 54, 93, 106, /* E0 - E7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* E8 - EF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* F0 - F7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* F8 - FF */
-};
-
-typedef struct ukbd_state {
- usbd_interface_handle ks_iface; /* interface */
- usbd_pipe_handle ks_intrpipe; /* interrupt pipe */
- struct usb_attach_arg *ks_uaa;
- int ks_ep_addr;
-
- struct ukbd_data ks_ndata;
- struct ukbd_data ks_odata;
- u_long ks_ntime[NKEYCODE];
- u_long ks_otime[NKEYCODE];
-
-#define INPUTBUFSIZE (NMOD + 2*NKEYCODE)
- u_int ks_input[INPUTBUFSIZE]; /* input buffer */
- int ks_inputs;
- int ks_inputhead;
- int ks_inputtail;
-
- int ks_ifstate;
-#define INTRENABLED (1 << 0)
-#define DISCONNECTED (1 << 1)
-
- struct callout ks_timeout_handle;
-
- int ks_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
- int ks_flags; /* flags */
-#define COMPOSE (1 << 0)
- int ks_polling;
- int ks_state; /* shift/lock key state */
- int ks_accents; /* accent key index (> 0) */
- u_int ks_composed_char; /* composed char code (> 0) */
-#ifdef UKBD_EMULATE_ATSCANCODE
- u_int ks_buffered_char[2];
- u_int8_t ks_leds; /* store for async led requests */
-#endif
-} ukbd_state_t;
-
-/* keyboard driver declaration */
-static int ukbd_configure(int flags);
-static kbd_probe_t ukbd_probe;
-static kbd_init_t ukbd_init;
-static kbd_term_t ukbd_term;
-static kbd_intr_t ukbd_interrupt;
-static kbd_test_if_t ukbd_test_if;
-static kbd_enable_t ukbd_enable;
-static kbd_disable_t ukbd_disable;
-static kbd_read_t ukbd_read;
-static kbd_check_t ukbd_check;
-static kbd_read_char_t ukbd_read_char;
-static kbd_check_char_t ukbd_check_char;
-static kbd_ioctl_t ukbd_ioctl;
-static kbd_lock_t ukbd_lock;
-static kbd_clear_state_t ukbd_clear_state;
-static kbd_get_state_t ukbd_get_state;
-static kbd_set_state_t ukbd_set_state;
-static kbd_poll_mode_t ukbd_poll;
-
-keyboard_switch_t ukbdsw = {
- ukbd_probe,
- ukbd_init,
- ukbd_term,
- ukbd_interrupt,
- ukbd_test_if,
- ukbd_enable,
- ukbd_disable,
- ukbd_read,
- ukbd_check,
- ukbd_read_char,
- ukbd_check_char,
- ukbd_ioctl,
- ukbd_lock,
- ukbd_clear_state,
- ukbd_get_state,
- ukbd_set_state,
- genkbd_get_fkeystr,
- ukbd_poll,
- genkbd_diag,
-};
-
-KEYBOARD_DRIVER(ukbd, ukbdsw, ukbd_configure);
-
-/* local functions */
-static int ukbd_enable_intr(keyboard_t *kbd, int on,
- usbd_intr_t *func);
-static void ukbd_timeout(void *arg);
-
-static int ukbd_getc(ukbd_state_t *state, int wait);
-static int probe_keyboard(struct usb_attach_arg *uaa, int flags);
-static int init_keyboard(ukbd_state_t *state, int *type,
- int flags);
-static void set_leds(ukbd_state_t *state, int leds);
-static int set_typematic(keyboard_t *kbd, int code);
-#ifdef UKBD_EMULATE_ATSCANCODE
-static int keycode2scancode(int keycode, int shift, int up);
-#endif
-
-/* local variables */
-
-/* the initial key map, accent map and fkey strings */
-#if defined(UKBD_DFLT_KEYMAP) && !defined(KLD_MODULE)
-#define KBD_DFLT_KEYMAP
-#include "ukbdmap.h"
-#endif
-#include <dev/kbd/kbdtables.h>
-
-/* structures for the default keyboard */
-static keyboard_t default_kbd;
-static ukbd_state_t default_kbd_state;
-static keymap_t default_keymap;
-static accentmap_t default_accentmap;
-static fkeytab_t default_fkeytab[NUM_FKEYS];
-
-/*
- * The back door to the keyboard driver!
- * This function is called by the console driver, via the kbdio module,
- * to tickle keyboard drivers when the low-level console is being initialized.
- * Almost nothing in the kernel has been initialied yet. Try to probe
- * keyboards if possible.
- * NOTE: because of the way the low-level conole is initialized, this routine
- * may be called more than once!!
- */
-static int
-ukbd_configure(int flags)
-{
- return 0;
-
-#if 0 /* not yet */
- keyboard_t *kbd;
- device_t device;
- struct usb_attach_arg *uaa;
- void *arg[2];
-
- device = devclass_get_device(ukbd_devclass, UKBD_DEFAULT);
- if (device == NULL)
- return 0;
- uaa = (struct usb_attach_arg *)device_get_ivars(device);
- if (uaa == NULL)
- return 0;
-
- /* probe the default keyboard */
- arg[0] = (void *)uaa;
- arg[1] = (void *)ukbd_intr;
- kbd = NULL;
- if (ukbd_probe(UKBD_DEFAULT, arg, flags))
- return 0;
- if (ukbd_init(UKBD_DEFAULT, &kbd, arg, flags))
- return 0;
-
- /* return the number of found keyboards */
- return 1;
-#endif
-}
-
-/* low-level functions */
-
-/* detect a keyboard */
-static int
-ukbd_probe(int unit, void *arg, int flags)
-{
- void **data;
- struct usb_attach_arg *uaa;
-
- data = (void **)arg;
- uaa = (struct usb_attach_arg *)data[0];
-
- /* XXX */
- if (unit == UKBD_DEFAULT) {
- if (KBD_IS_PROBED(&default_kbd))
- return 0;
- }
- if (probe_keyboard(uaa, flags))
- return ENXIO;
- return 0;
-}
-
-/* reset and initialize the device */
-static int
-ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
-{
- keyboard_t *kbd;
- ukbd_state_t *state;
- keymap_t *keymap;
- accentmap_t *accmap;
- fkeytab_t *fkeymap;
- int fkeymap_size;
- void **data = (void **)arg;
- struct usb_attach_arg *uaa = (struct usb_attach_arg *)data[0];
-
- /* XXX */
- if (unit == UKBD_DEFAULT) {
- *kbdp = kbd = &default_kbd;
- if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd))
- return 0;
- state = &default_kbd_state;
- keymap = &default_keymap;
- accmap = &default_accentmap;
- fkeymap = default_fkeytab;
- fkeymap_size =
- sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
- } else if (*kbdp == NULL) {
- *kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT);
- if (kbd == NULL)
- return ENOMEM;
- bzero(kbd, sizeof(*kbd));
- state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT);
- keymap = malloc(sizeof(key_map), M_DEVBUF, M_NOWAIT);
- accmap = malloc(sizeof(accent_map), M_DEVBUF, M_NOWAIT);
- fkeymap = malloc(sizeof(fkey_tab), M_DEVBUF, M_NOWAIT);
- fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
- if ((state == NULL) || (keymap == NULL) || (accmap == NULL)
- || (fkeymap == NULL)) {
- if (state != NULL)
- free(state, M_DEVBUF);
- if (keymap != NULL)
- free(keymap, M_DEVBUF);
- if (accmap != NULL)
- free(accmap, M_DEVBUF);
- if (fkeymap != NULL)
- free(fkeymap, M_DEVBUF);
- free(kbd, M_DEVBUF);
- return ENOMEM;
- }
- } else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
- return 0;
- } else {
- kbd = *kbdp;
- state = (ukbd_state_t *)kbd->kb_data;
- keymap = kbd->kb_keymap;
- accmap = kbd->kb_accentmap;
- fkeymap = kbd->kb_fkeytab;
- fkeymap_size = kbd->kb_fkeytab_size;
- }
-
- if (!KBD_IS_PROBED(kbd)) {
- kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, unit, flags, 0, 0);
- bzero(state, sizeof(*state));
- bcopy(&key_map, keymap, sizeof(key_map));
- bcopy(&accent_map, accmap, sizeof(accent_map));
- bcopy(fkey_tab, fkeymap,
- imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
- kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
- kbd->kb_data = (void *)state;
-
- if (probe_keyboard(uaa, flags))
- return ENXIO;
- else
- KBD_FOUND_DEVICE(kbd);
- ukbd_clear_state(kbd);
- state->ks_mode = K_XLATE;
- state->ks_iface = uaa->iface;
- state->ks_uaa = uaa;
- state->ks_ifstate = 0;
- callout_init(&state->ks_timeout_handle, 0);
- /*
- * FIXME: set the initial value for lock keys in ks_state
- * according to the BIOS data?
- */
- KBD_PROBE_DONE(kbd);
- }
- if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
- if (KBD_HAS_DEVICE(kbd)
- && init_keyboard((ukbd_state_t *)kbd->kb_data,
- &kbd->kb_type, kbd->kb_flags)) {
- kbd->kb_flags = 0;
- /* XXX: Missing free()'s */
- return ENXIO;
- }
- ukbd_ioctl(kbd, KDSETLED, (caddr_t)&(state->ks_state));
- KBD_INIT_DONE(kbd);
- }
- if (!KBD_IS_CONFIGURED(kbd)) {
- if (kbd_register(kbd) < 0) {
- kbd->kb_flags = 0;
- /* XXX: Missing free()'s */
- return ENXIO;
- }
- if (ukbd_enable_intr(kbd, TRUE, (usbd_intr_t *)data[1]) == 0)
- ukbd_timeout((void *)kbd);
- KBD_CONFIG_DONE(kbd);
- }
-
- return 0;
-}
-
-static int
-ukbd_enable_intr(keyboard_t *kbd, int on, usbd_intr_t *func)
-{
- ukbd_state_t *state = (ukbd_state_t *)kbd->kb_data;
- usbd_status err;
-
- if (on) {
- /* Set up interrupt pipe. */
- if (state->ks_ifstate & INTRENABLED)
- return EBUSY;
-
- state->ks_ifstate |= INTRENABLED;
- err = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr,
- USBD_SHORT_XFER_OK,
- &state->ks_intrpipe, kbd,
- &state->ks_ndata,
- sizeof(state->ks_ndata), func,
- USBD_DEFAULT_INTERVAL);
- if (err)
- return (EIO);
- } else {
- /* Disable interrupts. */
- usbd_abort_pipe(state->ks_intrpipe);
- usbd_close_pipe(state->ks_intrpipe);
-
- state->ks_ifstate &= ~INTRENABLED;
- }
-
- return (0);
-}
-
-/* finish using this keyboard */
-static int
-ukbd_term(keyboard_t *kbd)
-{
- ukbd_state_t *state;
- int error;
- int s;
-
- s = splusb();
-
- state = (ukbd_state_t *)kbd->kb_data;
- DPRINTF(("ukbd_term: ks_ifstate=0x%x\n", state->ks_ifstate));
-
- callout_stop(&state->ks_timeout_handle);
-
- if (state->ks_ifstate & INTRENABLED)
- ukbd_enable_intr(kbd, FALSE, NULL);
- if (state->ks_ifstate & INTRENABLED) {
- splx(s);
- DPRINTF(("ukbd_term: INTRENABLED!\n"));
- return ENXIO;
- }
-
- error = kbd_unregister(kbd);
- DPRINTF(("ukbd_term: kbd_unregister() %d\n", error));
- if (error == 0) {
- kbd->kb_flags = 0;
- if (kbd != &default_kbd) {
- free(kbd->kb_keymap, M_DEVBUF);
- free(kbd->kb_accentmap, M_DEVBUF);
- free(kbd->kb_fkeytab, M_DEVBUF);
- free(state, M_DEVBUF);
- free(kbd, M_DEVBUF);
- }
- }
-
- splx(s);
- return error;
-}
-
-
-/* keyboard interrupt routine */
-
-static void
-ukbd_timeout(void *arg)
-{
- keyboard_t *kbd;
- ukbd_state_t *state;
- int s;
-
- kbd = (keyboard_t *)arg;
- state = (ukbd_state_t *)kbd->kb_data;
- s = splusb();
- kbdd_intr(kbd, (void *)USBD_NORMAL_COMPLETION);
- callout_reset(&state->ks_timeout_handle, hz / 40, ukbd_timeout, arg);
- splx(s);
-}
-
-static int
-ukbd_interrupt(keyboard_t *kbd, void *arg)
-{
- usbd_status status = (usbd_status)arg;
- ukbd_state_t *state;
- struct ukbd_data *ud;
- struct timeval tv;
- u_long now;
- int mod, omod;
- int key, c;
- int i, j;
-
- DPRINTFN(5, ("ukbd_intr: status=%d\n", status));
- if (status == USBD_CANCELLED)
- return 0;
-
- state = (ukbd_state_t *)kbd->kb_data;
- ud = &state->ks_ndata;
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF(("ukbd_intr: status=%d\n", status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(state->ks_intrpipe);
- return 0;
- }
-
- if (ud->keycode[0] == KEY_ERROR)
- return 0; /* ignore */
-
- getmicrouptime(&tv);
- now = (u_long)tv.tv_sec*1000 + (u_long)tv.tv_usec/1000;
-
-#define ADDKEY1(c) \
- if (state->ks_inputs < INPUTBUFSIZE) { \
- state->ks_input[state->ks_inputtail] = (c); \
- ++state->ks_inputs; \
- state->ks_inputtail = (state->ks_inputtail + 1)%INPUTBUFSIZE; \
- }
-
- mod = ud->modifiers;
- omod = state->ks_odata.modifiers;
- if (mod != omod) {
- for (i = 0; i < NMOD; i++)
- if (( mod & ukbd_mods[i].mask) !=
- (omod & ukbd_mods[i].mask))
- ADDKEY1(ukbd_mods[i].key |
- (mod & ukbd_mods[i].mask
- ? KEY_PRESS : KEY_RELEASE));
- }
-
- /* Check for released keys. */
- for (i = 0; i < NKEYCODE; i++) {
- key = state->ks_odata.keycode[i];
- if (key == 0)
- continue;
- for (j = 0; j < NKEYCODE; j++) {
- if (ud->keycode[j] == 0)
- continue;
- if (key == ud->keycode[j])
- goto rfound;
- }
- ADDKEY1(key | KEY_RELEASE);
- rfound:
- ;
- }
-
- /* Check for pressed keys. */
- for (i = 0; i < NKEYCODE; i++) {
- key = ud->keycode[i];
- if (key == 0)
- continue;
- state->ks_ntime[i] = now + kbd->kb_delay1;
- for (j = 0; j < NKEYCODE; j++) {
- if (state->ks_odata.keycode[j] == 0)
- continue;
- if (key == state->ks_odata.keycode[j]) {
- state->ks_ntime[i] = state->ks_otime[j];
- if (state->ks_otime[j] > now)
- goto pfound;
- state->ks_ntime[i] = now + kbd->kb_delay2;
- break;
- }
- }
- ADDKEY1(key | KEY_PRESS);
- /*
- * If any other key is presently down, force its repeat to be
- * well in the future (100s). This makes the last key to be
- * pressed do the autorepeat.
- */
- for (j = 0; j < NKEYCODE; j++) {
- if (j != i)
- state->ks_ntime[j] = now + 100 * 1000;
- }
- pfound:
- ;
- }
-
- state->ks_odata = *ud;
- bcopy(state->ks_ntime, state->ks_otime, sizeof(state->ks_ntime));
- if (state->ks_inputs <= 0)
- return 0;
-
-#ifdef USB_DEBUG
- for (i = state->ks_inputhead, j = 0; j < state->ks_inputs; ++j,
- i = (i + 1)%INPUTBUFSIZE) {
- c = state->ks_input[i];
- DPRINTF(("0x%x (%d) %s\n", c, c,
- (c & KEY_RELEASE) ? "released":"pressed"));
- }
- if (ud->modifiers)
- DPRINTF(("mod:0x%04x ", ud->modifiers));
- for (i = 0; i < NKEYCODE; i++) {
- if (ud->keycode[i])
- DPRINTF(("%d ", ud->keycode[i]));
- }
- DPRINTF(("\n"));
-#endif /* USB_DEBUG */
-
- if (state->ks_polling)
- return 0;
-
- if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
- /* let the callback function to process the input */
- (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
- kbd->kb_callback.kc_arg);
- } else {
- /* read and discard the input; no one is waiting for it */
- do {
- c = ukbd_read_char(kbd, FALSE);
- } while (c != NOKEY);
- }
-
- return 0;
-}
-
-static int
-ukbd_getc(ukbd_state_t *state, int wait)
-{
- int c;
- int s;
-
- if (state->ks_polling) {
- DPRINTFN(1,("ukbd_getc: polling\n"));
- s = splusb();
- while (state->ks_inputs <= 0) {
- usbd_dopoll(state->ks_iface);
- if (wait == FALSE)
- break;
- }
- splx(s);
- }
- s = splusb();
- if (state->ks_inputs <= 0) {
- c = -1;
- } else {
- c = state->ks_input[state->ks_inputhead];
- --state->ks_inputs;
- state->ks_inputhead = (state->ks_inputhead + 1)%INPUTBUFSIZE;
- }
- splx(s);
- return c;
-}
-
-/* test the interface to the device */
-static int
-ukbd_test_if(keyboard_t *kbd)
-{
- return 0;
-}
-
-/*
- * Enable the access to the device; until this function is called,
- * the client cannot read from the keyboard.
- */
-static int
-ukbd_enable(keyboard_t *kbd)
-{
- int s;
-
- s = splusb();
- KBD_ACTIVATE(kbd);
- splx(s);
- return 0;
-}
-
-/* disallow the access to the device */
-static int
-ukbd_disable(keyboard_t *kbd)
-{
- int s;
-
- s = splusb();
- KBD_DEACTIVATE(kbd);
- splx(s);
- return 0;
-}
-
-/* read one byte from the keyboard if it's allowed */
-static int
-ukbd_read(keyboard_t *kbd, int wait)
-{
- ukbd_state_t *state;
- int usbcode;
-#ifdef UKBD_EMULATE_ATSCANCODE
- int keycode;
- int scancode;
-#endif
-
- state = (ukbd_state_t *)kbd->kb_data;
-#ifdef UKBD_EMULATE_ATSCANCODE
- if (state->ks_buffered_char[0]) {
- scancode = state->ks_buffered_char[0];
- if (scancode & SCAN_PREFIX) {
- state->ks_buffered_char[0] = scancode & ~SCAN_PREFIX;
- return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
- } else {
- state->ks_buffered_char[0] = state->ks_buffered_char[1];
- state->ks_buffered_char[1] = 0;
- return scancode;
- }
- }
-#endif /* UKBD_EMULATE_ATSCANCODE */
-
- /* XXX */
- usbcode = ukbd_getc(state, wait);
- if (!KBD_IS_ACTIVE(kbd) || (usbcode == -1))
- return -1;
- ++kbd->kb_count;
-#ifdef UKBD_EMULATE_ATSCANCODE
- keycode = ukbd_trtab[KEY_INDEX(usbcode)];
- if (keycode == NN)
- return -1;
-
- scancode = keycode2scancode(keycode, state->ks_ndata.modifiers,
- usbcode & KEY_RELEASE);
- if (scancode & SCAN_PREFIX) {
- if (scancode & SCAN_PREFIX_CTL) {
- state->ks_buffered_char[0] =
- 0x1d | (scancode & SCAN_RELEASE); /* Ctrl */
- state->ks_buffered_char[1] = scancode & ~SCAN_PREFIX;
- } else if (scancode & SCAN_PREFIX_SHIFT) {
- state->ks_buffered_char[0] =
- 0x2a | (scancode & SCAN_RELEASE); /* Shift */
- state->ks_buffered_char[1] =
- scancode & ~SCAN_PREFIX_SHIFT;
- } else {
- state->ks_buffered_char[0] = scancode & ~SCAN_PREFIX;
- state->ks_buffered_char[1] = 0;
- }
- return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
- }
- return scancode;
-#else /* !UKBD_EMULATE_ATSCANCODE */
- return usbcode;
-#endif /* UKBD_EMULATE_ATSCANCODE */
-}
-
-/* check if data is waiting */
-static int
-ukbd_check(keyboard_t *kbd)
-{
- if (!KBD_IS_ACTIVE(kbd))
- return FALSE;
-#ifdef UKBD_EMULATE_ATSCANCODE
- if (((ukbd_state_t *)kbd->kb_data)->ks_buffered_char[0])
- return TRUE;
-#endif
- if (((ukbd_state_t *)kbd->kb_data)->ks_inputs > 0)
- return TRUE;
- return FALSE;
-}
-
-/* read char from the keyboard */
-static u_int
-ukbd_read_char(keyboard_t *kbd, int wait)
-{
- ukbd_state_t *state;
- u_int action;
- int usbcode;
- int keycode;
-#ifdef UKBD_EMULATE_ATSCANCODE
- int scancode;
-#endif
-
- state = (ukbd_state_t *)kbd->kb_data;
-next_code:
- /* do we have a composed char to return? */
- if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
- action = state->ks_composed_char;
- state->ks_composed_char = 0;
- if (action > UCHAR_MAX)
- return ERRKEY;
- return action;
- }
-
-#ifdef UKBD_EMULATE_ATSCANCODE
- /* do we have a pending raw scan code? */
- if (state->ks_mode == K_RAW) {
- if (state->ks_buffered_char[0]) {
- scancode = state->ks_buffered_char[0];
- if (scancode & SCAN_PREFIX) {
- state->ks_buffered_char[0] =
- scancode & ~SCAN_PREFIX;
- return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
- } else {
- state->ks_buffered_char[0] =
- state->ks_buffered_char[1];
- state->ks_buffered_char[1] = 0;
- return scancode;
- }
- }
- }
-#endif /* UKBD_EMULATE_ATSCANCODE */
-
- /* see if there is something in the keyboard port */
- /* XXX */
- usbcode = ukbd_getc(state, wait);
- if (usbcode == -1)
- return NOKEY;
- ++kbd->kb_count;
-
-#ifdef UKBD_EMULATE_ATSCANCODE
- /* USB key index -> key code -> AT scan code */
- keycode = ukbd_trtab[KEY_INDEX(usbcode)];
- if (keycode == NN)
- return NOKEY;
-
- /* return an AT scan code for the K_RAW mode */
- if (state->ks_mode == K_RAW) {
- scancode = keycode2scancode(keycode, state->ks_ndata.modifiers,
- usbcode & KEY_RELEASE);
- if (scancode & SCAN_PREFIX) {
- if (scancode & SCAN_PREFIX_CTL) {
- state->ks_buffered_char[0] =
- 0x1d | (scancode & SCAN_RELEASE);
- state->ks_buffered_char[1] =
- scancode & ~SCAN_PREFIX;
- } else if (scancode & SCAN_PREFIX_SHIFT) {
- state->ks_buffered_char[0] =
- 0x2a | (scancode & SCAN_RELEASE);
- state->ks_buffered_char[1] =
- scancode & ~SCAN_PREFIX_SHIFT;
- } else {
- state->ks_buffered_char[0] =
- scancode & ~SCAN_PREFIX;
- state->ks_buffered_char[1] = 0;
- }
- return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
- }
- return scancode;
- }
-#else /* !UKBD_EMULATE_ATSCANCODE */
- /* return the byte as is for the K_RAW mode */
- if (state->ks_mode == K_RAW)
- return usbcode;
-
- /* USB key index -> key code */
- keycode = ukbd_trtab[KEY_INDEX(usbcode)];
- if (keycode == NN)
- return NOKEY;
-#endif /* UKBD_EMULATE_ATSCANCODE */
-
- switch (keycode) {
- case 0x38: /* left alt (compose key) */
- if (usbcode & KEY_RELEASE) {
- if (state->ks_flags & COMPOSE) {
- state->ks_flags &= ~COMPOSE;
- if (state->ks_composed_char > UCHAR_MAX)
- state->ks_composed_char = 0;
- }
- } else {
- if (!(state->ks_flags & COMPOSE)) {
- state->ks_flags |= COMPOSE;
- state->ks_composed_char = 0;
- }
- }
- break;
- /* XXX: I don't like these... */
- case 0x5c: /* print screen */
- if (state->ks_flags & ALTS)
- keycode = 0x54; /* sysrq */
- break;
- case 0x68: /* pause/break */
- if (state->ks_flags & CTLS)
- keycode = 0x6c; /* break */
- break;
- }
-
- /* return the key code in the K_CODE mode */
- if (usbcode & KEY_RELEASE)
- keycode |= SCAN_RELEASE;
- if (state->ks_mode == K_CODE)
- return keycode;
-
- /* compose a character code */
- if (state->ks_flags & COMPOSE) {
- switch (keycode) {
- /* key pressed, process it */
- case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += keycode - 0x40;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += keycode - 0x47;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += keycode - 0x4E;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x52: /* keypad 0 */
- state->ks_composed_char *= 10;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
-
- /* key released, no interest here */
- case SCAN_RELEASE | 0x47:
- case SCAN_RELEASE | 0x48:
- case SCAN_RELEASE | 0x49: /* keypad 7,8,9 */
- case SCAN_RELEASE | 0x4B:
- case SCAN_RELEASE | 0x4C:
- case SCAN_RELEASE | 0x4D: /* keypad 4,5,6 */
- case SCAN_RELEASE | 0x4F:
- case SCAN_RELEASE | 0x50:
- case SCAN_RELEASE | 0x51: /* keypad 1,2,3 */
- case SCAN_RELEASE | 0x52: /* keypad 0 */
- goto next_code;
-
- case 0x38: /* left alt key */
- break;
-
- default:
- if (state->ks_composed_char > 0) {
- state->ks_flags &= ~COMPOSE;
- state->ks_composed_char = 0;
- return ERRKEY;
- }
- break;
- }
- }
-
- /* keycode to key action */
- action = genkbd_keyaction(kbd, SCAN_CHAR(keycode),
- keycode & SCAN_RELEASE, &state->ks_state,
- &state->ks_accents);
- if (action == NOKEY)
- goto next_code;
- else
- return action;
-}
-
-/* check if char is waiting */
-static int
-ukbd_check_char(keyboard_t *kbd)
-{
- ukbd_state_t *state;
-
- if (!KBD_IS_ACTIVE(kbd))
- return FALSE;
- state = (ukbd_state_t *)kbd->kb_data;
- if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0))
- return TRUE;
- return ukbd_check(kbd);
-}
-
-/* some useful control functions */
-static int
-ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
-{
- /* trasnlate LED_XXX bits into the device specific bits */
- static u_char ledmap[8] = {
- 0, 2, 1, 3, 4, 6, 5, 7,
- };
- ukbd_state_t *state = kbd->kb_data;
- int s;
- int i;
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
- int ival;
-#endif
-
- s = splusb();
- switch (cmd) {
-
- case KDGKBMODE: /* get keyboard mode */
- *(int *)arg = state->ks_mode;
- break;
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
- case _IO('K', 7):
- ival = IOCPARM_IVAL(arg);
- arg = (caddr_t)&ival;
- /* FALLTHROUGH */
-#endif
- case KDSKBMODE: /* set keyboard mode */
- switch (*(int *)arg) {
- case K_XLATE:
- if (state->ks_mode != K_XLATE) {
- /* make lock key state and LED state match */
- state->ks_state &= ~LOCK_MASK;
- state->ks_state |= KBD_LED_VAL(kbd);
- }
- /* FALLTHROUGH */
- case K_RAW:
- case K_CODE:
- if (state->ks_mode != *(int *)arg) {
- ukbd_clear_state(kbd);
- state->ks_mode = *(int *)arg;
- }
- break;
- default:
- splx(s);
- return EINVAL;
- }
- break;
-
- case KDGETLED: /* get keyboard LED */
- *(int *)arg = KBD_LED_VAL(kbd);
- break;
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
- case _IO('K', 66):
- ival = IOCPARM_IVAL(arg);
- arg = (caddr_t)&ival;
- /* FALLTHROUGH */
-#endif
- case KDSETLED: /* set keyboard LED */
- /* NOTE: lock key state in ks_state won't be changed */
- if (*(int *)arg & ~LOCK_MASK) {
- splx(s);
- return EINVAL;
- }
- i = *(int *)arg;
- /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
- if (state->ks_mode == K_XLATE &&
- kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
- if (i & ALKED)
- i |= CLKED;
- else
- i &= ~CLKED;
- }
- if (KBD_HAS_DEVICE(kbd)) {
- set_leds(state, ledmap[i & LED_MASK]);
- /* XXX: error check? */
- }
- KBD_LED_VAL(kbd) = *(int *)arg;
- break;
-
- case KDGKBSTATE: /* get lock key state */
- *(int *)arg = state->ks_state & LOCK_MASK;
- break;
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
- case _IO('K', 20):
- ival = IOCPARM_IVAL(arg);
- arg = (caddr_t)&ival;
- /* FALLTHROUGH */
-#endif
- case KDSKBSTATE: /* set lock key state */
- if (*(int *)arg & ~LOCK_MASK) {
- splx(s);
- return EINVAL;
- }
- state->ks_state &= ~LOCK_MASK;
- state->ks_state |= *(int *)arg;
- splx(s);
- /* set LEDs and quit */
- return ukbd_ioctl(kbd, KDSETLED, arg);
-
- case KDSETREPEAT: /* set keyboard repeat rate (new interface) */
- splx(s);
- if (!KBD_HAS_DEVICE(kbd))
- return 0;
- if (((int *)arg)[1] < 0)
- return EINVAL;
- if (((int *)arg)[0] < 0)
- return EINVAL;
- else if (((int *)arg)[0] == 0) /* fastest possible value */
- kbd->kb_delay1 = 200;
- else
- kbd->kb_delay1 = ((int *)arg)[0];
- kbd->kb_delay2 = ((int *)arg)[1];
- return 0;
-
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
- case _IO('K', 67):
- ival = IOCPARM_IVAL(arg);
- arg = (caddr_t)&ival;
- /* FALLTHROUGH */
-#endif
- case KDSETRAD: /* set keyboard repeat rate (old interface) */
- splx(s);
- return set_typematic(kbd, *(int *)arg);
-
- case PIO_KEYMAP: /* set keyboard translation table */
- case PIO_KEYMAPENT: /* set keyboard translation table entry */
- case PIO_DEADKEYMAP: /* set accent key translation table */
- state->ks_accents = 0;
- /* FALLTHROUGH */
- default:
- splx(s);
- return genkbd_commonioctl(kbd, cmd, arg);
-
-#ifdef USB_DEBUG
- case USB_SETDEBUG:
- ukbddebug = *(int *)arg;
- break;
-#endif
- }
-
- splx(s);
- return 0;
-}
-
-/* lock the access to the keyboard */
-static int
-ukbd_lock(keyboard_t *kbd, int lock)
-{
- /* XXX ? */
- return TRUE;
-}
-
-/* clear the internal state of the keyboard */
-static void
-ukbd_clear_state(keyboard_t *kbd)
-{
- ukbd_state_t *state;
-
- state = (ukbd_state_t *)kbd->kb_data;
- state->ks_flags = 0;
- state->ks_polling = 0;
- state->ks_state &= LOCK_MASK; /* preserve locking key state */
- state->ks_accents = 0;
- state->ks_composed_char = 0;
-#ifdef UKBD_EMULATE_ATSCANCODE
- state->ks_buffered_char[0] = 0;
- state->ks_buffered_char[1] = 0;
-#endif
- bzero(&state->ks_ndata, sizeof(state->ks_ndata));
- bzero(&state->ks_odata, sizeof(state->ks_odata));
- bzero(&state->ks_ntime, sizeof(state->ks_ntime));
- bzero(&state->ks_otime, sizeof(state->ks_otime));
-}
-
-/* save the internal state */
-static int
-ukbd_get_state(keyboard_t *kbd, void *buf, size_t len)
-{
- if (len == 0)
- return sizeof(ukbd_state_t);
- if (len < sizeof(ukbd_state_t))
- return -1;
- bcopy(kbd->kb_data, buf, sizeof(ukbd_state_t));
- return 0;
-}
-
-/* set the internal state */
-static int
-ukbd_set_state(keyboard_t *kbd, void *buf, size_t len)
-{
- if (len < sizeof(ukbd_state_t))
- return ENOMEM;
- bcopy(buf, kbd->kb_data, sizeof(ukbd_state_t));
- return 0;
-}
-
-static int
-ukbd_poll(keyboard_t *kbd, int on)
-{
- ukbd_state_t *state;
- usbd_device_handle dev;
- int s;
-
- state = (ukbd_state_t *)kbd->kb_data;
- usbd_interface2device_handle(state->ks_iface, &dev);
-
- s = splusb();
- if (on) {
- ++state->ks_polling;
- if (state->ks_polling == 1)
- usbd_set_polling(dev, on);
- } else {
- --state->ks_polling;
- if (state->ks_polling == 0)
- usbd_set_polling(dev, on);
- }
- splx(s);
- return 0;
-}
-
-/* local functions */
-
-static int
-probe_keyboard(struct usb_attach_arg *uaa, int flags)
-{
- usb_interface_descriptor_t *id;
-
- if (!uaa->iface) /* we attach to ifaces only */
- return EINVAL;
-
- /* Check that this is a keyboard that speaks the boot protocol. */
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id
- && id->bInterfaceClass == UICLASS_HID
- && id->bInterfaceSubClass == UISUBCLASS_BOOT
- && id->bInterfaceProtocol == UPROTO_BOOT_KEYBOARD)
- return 0; /* found it */
-
- return EINVAL;
-}
-
-static int
-init_keyboard(ukbd_state_t *state, int *type, int flags)
-{
- usb_endpoint_descriptor_t *ed;
-
- *type = KB_OTHER;
-
- state->ks_ifstate |= DISCONNECTED;
-
- ed = usbd_interface2endpoint_descriptor(state->ks_iface, 0);
- if (!ed) {
- printf("ukbd: could not read endpoint descriptor\n");
- return EIO;
- }
-
- DPRINTFN(10,("ukbd:init_keyboard: \
-bLength=%d bDescriptorType=%d bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d bInterval=%d\n",
- ed->bLength, ed->bDescriptorType,
- UE_GET_ADDR(ed->bEndpointAddress),
- UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? "in":"out",
- UE_GET_XFERTYPE(ed->bmAttributes),
- UGETW(ed->wMaxPacketSize), ed->bInterval));
-
- if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
- UE_GET_XFERTYPE(ed->bmAttributes) != UE_INTERRUPT) {
- printf("ukbd: unexpected endpoint\n");
- return EINVAL;
- }
-
- /* Ignore if SETIDLE fails since it is not crucial. */
- usbd_set_idle(state->ks_iface, 0, 0);
-
- state->ks_ep_addr = ed->bEndpointAddress;
- state->ks_ifstate &= ~DISCONNECTED;
-
- return 0;
-}
-
-static void
-set_leds(ukbd_state_t *state, int leds)
-{
-
- DPRINTF(("ukbd:set_leds: state=%p leds=%d\n", state, leds));
- state->ks_leds = leds;
- usbd_set_report_async(state->ks_iface, UHID_OUTPUT_REPORT, 0,
- &state->ks_leds, 1);
-}
-
-static int
-set_typematic(keyboard_t *kbd, int code)
-{
- static int delays[] = { 250, 500, 750, 1000 };
- static int rates[] = { 34, 38, 42, 46, 50, 55, 59, 63,
- 68, 76, 84, 92, 100, 110, 118, 126,
- 136, 152, 168, 184, 200, 220, 236, 252,
- 272, 304, 336, 368, 400, 440, 472, 504 };
-
- if (code & ~0x7f)
- return EINVAL;
- kbd->kb_delay1 = delays[(code >> 5) & 3];
- kbd->kb_delay2 = rates[code & 0x1f];
- return 0;
-}
-
-#ifdef UKBD_EMULATE_ATSCANCODE
-static int
-keycode2scancode(int keycode, int shift, int up)
-{
- static int scan[] = {
- 0x1c, 0x1d, 0x35,
- 0x37 | SCAN_PREFIX_SHIFT, /* PrintScreen */
- 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
- 0x50, 0x51, 0x52, 0x53,
- 0x46, /* XXX Pause/Break */
- 0x5b, 0x5c, 0x5d,
- /* SUN TYPE 6 USB KEYBOARD */
- 0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
- 0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
- 0x20,
- };
- int scancode;
-
- scancode = keycode;
- if ((keycode >= 89) && (keycode < 89 + sizeof(scan)/sizeof(scan[0])))
- scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
- /* Pause/Break */
- if ((keycode == 104) && !(shift & (MOD_CONTROL_L | MOD_CONTROL_R)))
- scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
- if (shift & (MOD_SHIFT_L | MOD_SHIFT_R))
- scancode &= ~SCAN_PREFIX_SHIFT;
- return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
-}
-#endif /* UKBD_EMULATE_ATSCANCODE */
-
-static int
-ukbd_driver_load(module_t mod, int what, void *arg)
-{
- switch (what) {
- case MOD_LOAD:
- kbd_add_driver(&ukbd_kbd_driver);
- break;
- case MOD_UNLOAD:
- kbd_delete_driver(&ukbd_kbd_driver);
- break;
- }
- return usbd_driver_load(mod, what, arg);
-}
diff --git a/sys/legacy/dev/usb/ulpt.c b/sys/legacy/dev/usb/ulpt.c
deleted file mode 100644
index 99a1433..0000000
--- a/sys/legacy/dev/usb/ulpt.c
+++ /dev/null
@@ -1,815 +0,0 @@
-/* $NetBSD: ulpt.c,v 1.60 2003/10/04 21:19:50 augustss Exp $ */
-
-/*-
- * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Printer Class spec: http://www.usb.org/developers/data/devclass/usbprint109.PDF
- */
-
-/* XXXimp: need to migrate from devclass_get_softc */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
-#include <sys/fcntl.h>
-#include <sys/ioccom.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/uio.h>
-#include <sys/conf.h>
-#include <sys/syslog.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#define TIMEOUT hz*16 /* wait up to 16 seconds for a ready */
-#define STEP hz/4
-
-#define LPTPRI (PZERO+8)
-#define ULPT_BSIZE PAGE_SIZE
-
-#define ULPT_READS_PER_SEC 5
-#define ULPT_READ_TIMO 10
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (ulptdebug) printf x
-#define DPRINTFN(n,x) if (ulptdebug>(n)) printf x
-int ulptdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ulpt, CTLFLAG_RW, 0, "USB ulpt");
-SYSCTL_INT(_hw_usb_ulpt, OID_AUTO, debug, CTLFLAG_RW,
- &ulptdebug, 0, "ulpt debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UR_GET_DEVICE_ID 0
-#define UR_GET_PORT_STATUS 1
-#define UR_SOFT_RESET 2
-
-#define LPS_NERR 0x08 /* printer no error */
-#define LPS_SELECT 0x10 /* printer selected */
-#define LPS_NOPAPER 0x20 /* printer out of paper */
-#define LPS_INVERT (LPS_SELECT|LPS_NERR)
-#define LPS_MASK (LPS_SELECT|LPS_NERR|LPS_NOPAPER)
-
-struct ulpt_softc {
- device_t sc_dev;
- usbd_device_handle sc_udev; /* device */
- usbd_interface_handle sc_iface; /* interface */
- int sc_ifaceno;
-
- int sc_out;
- usbd_pipe_handle sc_out_pipe; /* bulk out pipe */
- usbd_xfer_handle sc_out_xfer;
- void *sc_out_buf;
-
- int sc_in;
- usbd_pipe_handle sc_in_pipe; /* bulk in pipe */
- usbd_xfer_handle sc_in_xfer;
- void *sc_in_buf;
-
- struct callout sc_read_callout;
- int sc_has_callout;
-
- u_char sc_state;
-#define ULPT_OPEN 0x01 /* device is open */
-#define ULPT_OBUSY 0x02 /* printer is busy doing output */
-#define ULPT_INIT 0x04 /* waiting to initialize for open */
- u_char sc_flags;
-#define ULPT_NOPRIME 0x40 /* don't prime on open */
- u_char sc_laststatus;
-
- int sc_refcnt;
- u_char sc_dying;
-
- struct cdev *dev;
- struct cdev *dev_noprime;
-};
-
-static d_open_t ulptopen;
-static d_close_t ulptclose;
-static d_write_t ulptwrite;
-static d_read_t ulptread;
-static d_ioctl_t ulptioctl;
-
-
-static struct cdevsw ulpt_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = ulptopen,
- .d_close = ulptclose,
- .d_write = ulptwrite,
- .d_read = ulptread,
- .d_ioctl = ulptioctl,
- .d_name = "ulpt",
-};
-
-void ulpt_disco(void *);
-
-int ulpt_do_write(struct ulpt_softc *, struct uio *uio, int);
-int ulpt_do_read(struct ulpt_softc *, struct uio *uio, int);
-int ulpt_status(struct ulpt_softc *);
-void ulpt_reset(struct ulpt_softc *);
-int ulpt_statusmsg(u_char, struct ulpt_softc *);
-void ulpt_read_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status);
-void ulpt_tick(void *xsc);
-
-#if 0
-void ieee1284_print_id(char *);
-#endif
-
-#define ULPTUNIT(s) (dev2unit(s) & 0x1f)
-#define ULPTFLAGS(s) (dev2unit(s) & 0xe0)
-
-static device_probe_t ulpt_match;
-static device_attach_t ulpt_attach;
-static device_detach_t ulpt_detach;
-
-static device_method_t ulpt_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ulpt_match),
- DEVMETHOD(device_attach, ulpt_attach),
- DEVMETHOD(device_detach, ulpt_detach),
-
- { 0, 0 }
-};
-
-static driver_t ulpt_driver = {
- "ulpt",
- ulpt_methods,
- sizeof(struct ulpt_softc)
-};
-
-static devclass_t ulpt_devclass;
-
-MODULE_DEPEND(umass, usb, 1, 1, 1);
-DRIVER_MODULE(ulpt, uhub, ulpt_driver, ulpt_devclass, usbd_driver_load, 0);
-
-static int
-ulpt_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
-
- DPRINTFN(10,("ulpt_match\n"));
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id != NULL &&
- id->bInterfaceClass == UICLASS_PRINTER &&
- id->bInterfaceSubClass == UISUBCLASS_PRINTER &&
- (id->bInterfaceProtocol == UIPROTO_PRINTER_UNI ||
- id->bInterfaceProtocol == UIPROTO_PRINTER_BI ||
- id->bInterfaceProtocol == UIPROTO_PRINTER_1284))
- return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
- return (UMATCH_NONE);
-}
-
-static int
-ulpt_attach(device_t self)
-{
- struct ulpt_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *ifcd = usbd_get_interface_descriptor(iface);
- usb_interface_descriptor_t *id, *iend;
- usb_config_descriptor_t *cdesc;
- usbd_status err;
- usb_endpoint_descriptor_t *ed;
- u_int8_t epcount;
- int i, altno;
-
- DPRINTFN(10,("ulpt_attach: sc=%p\n", sc));
- sc->sc_dev = self;
-
- /* XXX
- * Stepping through the alternate settings needs to be abstracted out.
- */
- cdesc = usbd_get_config_descriptor(dev);
- if (cdesc == NULL) {
- printf("%s: failed to get configuration descriptor\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
- iend = (usb_interface_descriptor_t *)
- ((char *)cdesc + UGETW(cdesc->wTotalLength));
-#ifdef DIAGNOSTIC
- if (ifcd < (usb_interface_descriptor_t *)cdesc ||
- ifcd >= iend)
- panic("ulpt: iface desc out of range");
-#endif
- /* Step through all the descriptors looking for bidir mode */
- for (id = ifcd, altno = 0;
- id < iend;
- id = (void *)((char *)id + id->bLength)) {
- if (id->bDescriptorType == UDESC_INTERFACE &&
- id->bInterfaceNumber == ifcd->bInterfaceNumber) {
- if (id->bInterfaceClass == UICLASS_PRINTER &&
- id->bInterfaceSubClass == UISUBCLASS_PRINTER &&
- (id->bInterfaceProtocol == UIPROTO_PRINTER_BI /* ||
- id->bInterfaceProtocol == UIPROTO_PRINTER_1284 */))
- goto found;
- altno++;
- }
- }
- id = ifcd; /* not found, use original */
- found:
- if (id != ifcd) {
- /* Found a new bidir setting */
- DPRINTF(("ulpt_attach: set altno = %d\n", altno));
- err = usbd_set_interface(iface, altno);
- if (err) {
- printf("%s: setting alternate interface failed\n",
- device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
- }
-
- epcount = 0;
- (void)usbd_endpoint_count(iface, &epcount);
-
- sc->sc_in = -1;
- sc->sc_out = -1;
- for (i = 0; i < epcount; i++) {
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- printf("%s: couldn't get ep %d\n",
- device_get_nameunit(sc->sc_dev), i);
- return ENXIO;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->sc_in = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->sc_out = ed->bEndpointAddress;
- }
- }
- if (sc->sc_out == -1) {
- printf("%s: could not find bulk out endpoint\n",
- device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- if (usbd_get_quirks(dev)->uq_flags & UQ_BROKEN_BIDIR) {
- /* This device doesn't handle reading properly. */
- sc->sc_in = -1;
- }
-
- printf("%s: using %s-directional mode\n", device_get_nameunit(sc->sc_dev),
- sc->sc_in >= 0 ? "bi" : "uni");
-
- DPRINTFN(10, ("ulpt_attach: bulk=%d\n", sc->sc_out));
-
- sc->sc_iface = iface;
- sc->sc_ifaceno = id->bInterfaceNumber;
- sc->sc_udev = dev;
-
-#if 0
-/*
- * This code is disabled because for some mysterious reason it causes
- * printing not to work. But only sometimes, and mostly with
- * UHCI and less often with OHCI. *sigh*
- */
- {
- usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
- usb_device_request_t req;
- int len, alen;
-
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_GET_DEVICE_ID;
- USETW(req.wValue, cd->bConfigurationValue);
- USETW2(req.wIndex, id->bInterfaceNumber, id->bAlternateSetting);
- USETW(req.wLength, sizeof devinfo - 1);
- err = usbd_do_request_flags(dev, &req, devinfo, USBD_SHORT_XFER_OK,
- &alen, USBD_DEFAULT_TIMEOUT);
- if (err) {
- printf("%s: cannot get device id\n", device_get_nameunit(sc->sc_dev));
- } else if (alen <= 2) {
- printf("%s: empty device id, no printer connected?\n",
- device_get_nameunit(sc->sc_dev));
- } else {
- /* devinfo now contains an IEEE-1284 device ID */
- len = ((devinfo[0] & 0xff) << 8) | (devinfo[1] & 0xff);
- if (len > sizeof devinfo - 3)
- len = sizeof devinfo - 3;
- devinfo[len] = 0;
- printf("%s: device id <", device_get_nameunit(sc->sc_dev));
- ieee1284_print_id(devinfo+2);
- printf(">\n");
- }
- }
-#endif
-
- sc->dev = make_dev(&ulpt_cdevsw, device_get_unit(self),
- UID_ROOT, GID_OPERATOR, 0644, "ulpt%d", device_get_unit(self));
- sc->dev_noprime = make_dev(&ulpt_cdevsw,
- device_get_unit(self)|ULPT_NOPRIME,
- UID_ROOT, GID_OPERATOR, 0644, "unlpt%d", device_get_unit(self));
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
-
- return 0;
-}
-
-
-static int
-ulpt_detach(device_t self)
-{
- struct ulpt_softc *sc = device_get_softc(self);
- int s;
-
- DPRINTF(("ulpt_detach: sc=%p\n", sc));
-
- sc->sc_dying = 1;
- if (sc->sc_out_pipe != NULL)
- usbd_abort_pipe(sc->sc_out_pipe);
- if (sc->sc_in_pipe != NULL)
- usbd_abort_pipe(sc->sc_in_pipe);
-
- s = splusb();
- if (--sc->sc_refcnt >= 0) {
- /* There is noone to wake, aborting the pipe is enough */
- /* Wait for processes to go away. */
- usb_detach_wait(sc->sc_dev);
- }
- splx(s);
-
- destroy_dev(sc->dev);
- destroy_dev(sc->dev_noprime);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
-
- return (0);
-}
-
-int
-ulpt_status(struct ulpt_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
- u_char status;
-
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_GET_PORT_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, 1);
- err = usbd_do_request(sc->sc_udev, &req, &status);
- DPRINTFN(1, ("ulpt_status: status=0x%02x err=%d\n", status, err));
- if (!err)
- return (status);
- else
- return (0);
-}
-
-void
-ulpt_reset(struct ulpt_softc *sc)
-{
- usb_device_request_t req;
-
- DPRINTFN(1, ("ulpt_reset\n"));
- req.bRequest = UR_SOFT_RESET;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, 0);
-
- /*
- * There was a mistake in the USB printer 1.0 spec that gave the
- * request type as UT_WRITE_CLASS_OTHER; it should have been
- * UT_WRITE_CLASS_INTERFACE. Many printers use the old one,
- * so we try both.
- */
- req.bmRequestType = UT_WRITE_CLASS_OTHER;
- if (usbd_do_request(sc->sc_udev, &req, 0)) { /* 1.0 */
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- (void)usbd_do_request(sc->sc_udev, &req, 0); /* 1.1 */
- }
-}
-#if 0
-static void
-ulpt_input(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ulpt_softc *sc = priv;
- u_int32_t count;
-
- /* Don't loop on errors or 0-length input. */
- usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
- if (status != USBD_NORMAL_COMPLETION || count == 0)
- return;
-
- DPRINTFN(2,("ulpt_input: got some data\n"));
- /* Do it again. */
- if (xfer == sc->sc_in_xfer1)
- usbd_transfer(sc->sc_in_xfer2);
- else
- usbd_transfer(sc->sc_in_xfer1);
-}
-#endif
-
-int ulptusein = 1;
-
-/*
- * Reset the printer, then wait until it's selected and not busy.
- */
-int
-ulptopen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- u_char flags = ULPTFLAGS(dev);
- struct ulpt_softc *sc;
- usbd_status err;
- int error;
-
- sc = devclass_get_softc(ulpt_devclass, ULPTUNIT(dev));
- if (sc == NULL)
- return (ENXIO);
-
- if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying)
- return (ENXIO);
-
- if (sc->sc_state)
- return (EBUSY);
-
- sc->sc_state = ULPT_INIT;
- sc->sc_flags = flags;
- DPRINTF(("ulptopen: flags=0x%x\n", (unsigned)flags));
-
-#if defined(USB_DEBUG)
- /* Ignoring these flags might not be a good idea */
- if ((flags & ~ULPT_NOPRIME) != 0)
- printf("ulptopen: flags ignored: %b\n", flags,
- "\20\3POS_INIT\4POS_ACK\6PRIME_OPEN\7AUTOLF\10BYPASS");
-#endif
-
-
- error = 0;
- sc->sc_refcnt++;
-
- if ((flags & ULPT_NOPRIME) == 0) {
- ulpt_reset(sc);
- if (sc->sc_dying) {
- error = ENXIO;
- sc->sc_state = 0;
- goto done;
- }
- }
-
- err = usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe);
- if (err) {
- error = EIO;
- goto err0;
- }
- sc->sc_out_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_out_xfer == NULL) {
- error = ENOMEM;
- goto err1;
- }
- sc->sc_out_buf = usbd_alloc_buffer(sc->sc_out_xfer, ULPT_BSIZE);
- if (sc->sc_out_buf == NULL) {
- error = ENOMEM;
- goto err2;
- }
-
- if (ulptusein && sc->sc_in != -1) {
- DPRINTF(("ulpt_open: open input pipe\n"));
- err = usbd_open_pipe(sc->sc_iface, sc->sc_in,0,&sc->sc_in_pipe);
- if (err) {
- error = EIO;
- goto err2;
- }
- sc->sc_in_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_in_xfer == NULL) {
- error = ENOMEM;
- goto err3;
- }
- sc->sc_in_buf = usbd_alloc_buffer(sc->sc_in_xfer, ULPT_BSIZE);
- if (sc->sc_in_buf == NULL) {
- error = ENOMEM;
- goto err4;
- }
-
- /* If it's not opened for read the set up a reader. */
- if (!(flag & FREAD)) {
- DPRINTF(("ulpt_open: start read callout\n"));
- callout_init(&sc->sc_read_callout, 0);
- callout_reset(&sc->sc_read_callout, hz/5, ulpt_tick,
- sc);
- sc->sc_has_callout = 1;
- }
- }
-
- sc->sc_state = ULPT_OPEN;
- goto done;
-
- err4:
- usbd_free_xfer(sc->sc_in_xfer);
- sc->sc_in_xfer = NULL;
- err3:
- usbd_close_pipe(sc->sc_in_pipe);
- sc->sc_in_pipe = NULL;
- err2:
- usbd_free_xfer(sc->sc_out_xfer);
- sc->sc_out_xfer = NULL;
- err1:
- usbd_close_pipe(sc->sc_out_pipe);
- sc->sc_out_pipe = NULL;
- err0:
- sc->sc_state = 0;
-
- done:
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
-
- DPRINTF(("ulptopen: done, error=%d\n", error));
- return (error);
-}
-
-int
-ulpt_statusmsg(u_char status, struct ulpt_softc *sc)
-{
- u_char new;
-
- status = (status ^ LPS_INVERT) & LPS_MASK;
- new = status & ~sc->sc_laststatus;
- sc->sc_laststatus = status;
-
- if (new & LPS_SELECT)
- log(LOG_NOTICE, "%s: offline\n", device_get_nameunit(sc->sc_dev));
- else if (new & LPS_NOPAPER)
- log(LOG_NOTICE, "%s: out of paper\n", device_get_nameunit(sc->sc_dev));
- else if (new & LPS_NERR)
- log(LOG_NOTICE, "%s: output error\n", device_get_nameunit(sc->sc_dev));
-
- return (status);
-}
-
-int
-ulptclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct ulpt_softc *sc;
-
- sc = devclass_get_softc(ulpt_devclass, ULPTUNIT(dev));
-
- if (sc->sc_state != ULPT_OPEN)
- /* We are being forced to close before the open completed. */
- return (0);
-
- if (sc->sc_has_callout) {
- callout_stop(&sc->sc_read_callout);
- sc->sc_has_callout = 0;
- }
-
- if (sc->sc_out_pipe != NULL) {
- usbd_abort_pipe(sc->sc_out_pipe);
- usbd_close_pipe(sc->sc_out_pipe);
- sc->sc_out_pipe = NULL;
- }
- if (sc->sc_out_xfer != NULL) {
- usbd_free_xfer(sc->sc_out_xfer);
- sc->sc_out_xfer = NULL;
- }
-
- if (sc->sc_in_pipe != NULL) {
- usbd_abort_pipe(sc->sc_in_pipe);
- usbd_close_pipe(sc->sc_in_pipe);
- sc->sc_in_pipe = NULL;
- }
- if (sc->sc_in_xfer != NULL) {
- usbd_free_xfer(sc->sc_in_xfer);
- sc->sc_in_xfer = NULL;
- }
-
- sc->sc_state = 0;
-
- DPRINTF(("ulptclose: closed\n"));
- return (0);
-}
-
-int
-ulpt_do_write(struct ulpt_softc *sc, struct uio *uio, int flags)
-{
- u_int32_t n;
- int error = 0;
- void *bufp;
- usbd_xfer_handle xfer;
- usbd_status err;
-
- DPRINTF(("ulptwrite\n"));
- xfer = sc->sc_out_xfer;
- bufp = sc->sc_out_buf;
- while ((n = min(ULPT_BSIZE, uio->uio_resid)) != 0) {
- ulpt_statusmsg(ulpt_status(sc), sc);
- error = uiomove(bufp, n, uio);
- if (error)
- break;
- DPRINTFN(1, ("ulptwrite: transfer %d bytes\n", n));
- err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY,
- USBD_NO_TIMEOUT, bufp, &n, "ulptwr");
- if (err) {
- DPRINTF(("ulptwrite: error=%d\n", err));
- error = EIO;
- break;
- }
- }
-
- return (error);
-}
-
-int
-ulptwrite(struct cdev *dev, struct uio *uio, int flags)
-{
- struct ulpt_softc *sc;
- int error;
-
- sc = devclass_get_softc(ulpt_devclass, ULPTUNIT(dev));
-
- if (sc->sc_dying)
- return (EIO);
-
- sc->sc_refcnt++;
- error = ulpt_do_write(sc, uio, flags);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-int
-ulpt_do_read(struct ulpt_softc *sc, struct uio *uio, int flags)
-{
- u_int32_t n, on;
- int error = 0;
- void *bufp;
- usbd_xfer_handle xfer;
- usbd_status err;
-
- DPRINTF(("ulptread\n"));
-
- if (sc->sc_in_pipe == NULL)
- return 0;
-
- xfer = sc->sc_in_xfer;
- bufp = sc->sc_in_buf;
- while ((n = min(ULPT_BSIZE, uio->uio_resid)) != 0) {
- DPRINTFN(1, ("ulptread: transfer %d bytes\n", n));
- on = n;
- err = usbd_bulk_transfer(xfer, sc->sc_in_pipe,
- USBD_NO_COPY | USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, bufp, &n, "ulptrd");
- if (err) {
- DPRINTF(("ulptread: error=%d\n", err));
- error = EIO;
- break;
- }
- error = uiomove(bufp, n, uio);
- if (error)
- break;
- if (on != n)
- break;
- }
-
- return (error);
-}
-
-int
-ulptread(struct cdev *dev, struct uio *uio, int flags)
-{
- struct ulpt_softc *sc;
- int error;
-
- sc = devclass_get_softc(ulpt_devclass, ULPTUNIT(dev));
-
- if (sc->sc_dying)
- return (EIO);
-
- sc->sc_refcnt++;
- error = ulpt_do_read(sc, uio, flags);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-void
-ulpt_read_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- usbd_status err;
- u_int32_t n;
- usbd_private_handle xsc;
- struct ulpt_softc *sc;
-
- usbd_get_xfer_status(xfer, &xsc, NULL, &n, &err);
- sc = xsc;
-
- DPRINTFN(1,("ulpt_read_cb: start sc=%p, err=%d n=%d\n", sc, err, n));
-
-#ifdef ULPT_DEBUG
- if (!err && n > 0)
- DPRINTF(("ulpt_tick: discarding %d bytes\n", n));
-#endif
- if (!err || err == USBD_TIMEOUT)
- callout_reset(&sc->sc_read_callout, hz / ULPT_READS_PER_SEC,
- ulpt_tick, sc);
-}
-
-void
-ulpt_tick(void *xsc)
-{
- struct ulpt_softc *sc = xsc;
- usbd_status err;
-
- if (sc == NULL || sc->sc_dying)
- return;
-
- DPRINTFN(1,("ulpt_tick: start sc=%p\n", sc));
-
- usbd_setup_xfer(sc->sc_in_xfer, sc->sc_in_pipe, sc, sc->sc_in_buf,
- ULPT_BSIZE, USBD_NO_COPY | USBD_SHORT_XFER_OK,
- ULPT_READ_TIMO, ulpt_read_cb);
- err = usbd_transfer(sc->sc_in_xfer);
- DPRINTFN(1,("ulpt_tick: err=%d\n", err));
-}
-
-int
-ulptioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *p)
-{
- int error = 0;
-
- switch (cmd) {
- default:
- error = ENODEV;
- }
-
- return (error);
-}
-
-#if 0
-/* XXX This does not belong here. */
-/*
- * Print select parts of an IEEE 1284 device ID.
- */
-void
-ieee1284_print_id(char *str)
-{
- char *p, *q;
-
- for (p = str-1; p; p = strchr(p, ';')) {
- p++; /* skip ';' */
- if (strncmp(p, "MFG:", 4) == 0 ||
- strncmp(p, "MANUFACTURER:", 14) == 0 ||
- strncmp(p, "MDL:", 4) == 0 ||
- strncmp(p, "MODEL:", 6) == 0) {
- q = strchr(p, ';');
- if (q)
- printf("%.*s", (int)(q - p + 1), p);
- }
- }
-}
-#endif
diff --git a/sys/legacy/dev/usb/umass.c b/sys/legacy/dev/usb/umass.c
deleted file mode 100644
index b0b73cc..0000000
--- a/sys/legacy/dev/usb/umass.c
+++ /dev/null
@@ -1,3611 +0,0 @@
-/*-
- * Copyright (c) 1999 MAEKAWA Masahide <bishop@rr.iij4u.or.jp>,
- * Nick Hibma <n_hibma@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- * $NetBSD: umass.c,v 1.28 2000/04/02 23:46:53 augustss Exp $
- */
-
-/* Also already merged from NetBSD:
- * $NetBSD: umass.c,v 1.67 2001/11/25 19:05:22 augustss Exp $
- * $NetBSD: umass.c,v 1.90 2002/11/04 19:17:33 pooka Exp $
- * $NetBSD: umass.c,v 1.108 2003/11/07 17:03:25 wiz Exp $
- * $NetBSD: umass.c,v 1.109 2003/12/04 13:57:31 keihan Exp $
- */
-
-/*
- * Universal Serial Bus Mass Storage Class specs:
- * http://www.usb.org/developers/devclass_docs/usb_msc_overview_1.2.pdf
- * http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf
- * http://www.usb.org/developers/devclass_docs/usb_msc_cbi_1.1.pdf
- * http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf
- */
-
-/*
- * Ported to NetBSD by Lennart Augustsson <augustss@NetBSD.org>.
- * Parts of the code written by Jason R. Thorpe <thorpej@shagadelic.org>.
- */
-
-/*
- * The driver handles 3 Wire Protocols
- * - Command/Bulk/Interrupt (CBI)
- * - Command/Bulk/Interrupt with Command Completion Interrupt (CBI with CCI)
- * - Mass Storage Bulk-Only (BBB)
- * (BBB refers Bulk/Bulk/Bulk for Command/Data/Status phases)
- *
- * Over these wire protocols it handles the following command protocols
- * - SCSI
- * - UFI (floppy command set)
- * - 8070i (ATAPI)
- *
- * UFI and 8070i (ATAPI) are transformed versions of the SCSI command set. The
- * sc->transform method is used to convert the commands into the appropriate
- * format (if at all necessary). For example, UFI requires all commands to be
- * 12 bytes in length amongst other things.
- *
- * The source code below is marked and can be split into a number of pieces
- * (in this order):
- *
- * - probe/attach/detach
- * - generic transfer routines
- * - BBB
- * - CBI
- * - CBI_I (in addition to functions from CBI)
- * - CAM (Common Access Method)
- * - SCSI
- * - UFI
- * - 8070i (ATAPI)
- *
- * The protocols are implemented using a state machine, for the transfers as
- * well as for the resets. The state machine is contained in umass_*_state.
- * The state machine is started through either umass_*_transfer or
- * umass_*_reset.
- *
- * The reason for doing this is a) CAM performs a lot better this way and b) it
- * avoids using tsleep from interrupt context (for example after a failed
- * transfer).
- */
-
-/*
- * The SCSI related part of this driver has been derived from the
- * dev/ppbus/vpo.c driver, by Nicolas Souchu (nsouch@freebsd.org).
- *
- * The CAM layer uses so called actions which are messages sent to the host
- * adapter for completion. The actions come in through umass_cam_action. The
- * appropriate block of routines is called depending on the transport protocol
- * in use. When the transfer has finished, these routines call
- * umass_cam_cb again to complete the CAM command.
- */
-
-/*
- * XXX Currently CBI with CCI is not supported because it bombs the system
- * when the device is detached (low frequency interrupts are detached
- * too late.
- */
-#undef CBI_I
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <cam/cam.h>
-#include <cam/cam_ccb.h>
-#include <cam/cam_sim.h>
-#include <cam/cam_xpt_sim.h>
-#include <cam/scsi/scsi_all.h>
-#include <cam/scsi/scsi_da.h>
-
-#include <cam/cam_periph.h>
-
-#ifdef USB_DEBUG
-#define DIF(m, x) if (umassdebug & (m)) do { x ; } while (0)
-#define DPRINTF(m, x) if (umassdebug & (m)) printf x
-#define UDMASS_GEN 0x00010000 /* general */
-#define UDMASS_SCSI 0x00020000 /* scsi */
-#define UDMASS_UFI 0x00040000 /* ufi command set */
-#define UDMASS_ATAPI 0x00080000 /* 8070i command set */
-#define UDMASS_CMD (UDMASS_SCSI|UDMASS_UFI|UDMASS_ATAPI)
-#define UDMASS_USB 0x00100000 /* USB general */
-#define UDMASS_BBB 0x00200000 /* Bulk-Only transfers */
-#define UDMASS_CBI 0x00400000 /* CBI transfers */
-#define UDMASS_WIRE (UDMASS_BBB|UDMASS_CBI)
-#define UDMASS_ALL 0xffff0000 /* all of the above */
-int umassdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, umass, CTLFLAG_RW, 0, "USB umass");
-SYSCTL_INT(_hw_usb_umass, OID_AUTO, debug, CTLFLAG_RW,
- &umassdebug, 0, "umass debug level");
-#else
-#define DIF(m, x) /* nop */
-#define DPRINTF(m, x) /* nop */
-#endif
-
-
-/* Generic definitions */
-
-/* Direction for umass_*_transfer */
-#define DIR_NONE 0
-#define DIR_IN 1
-#define DIR_OUT 2
-
-/* device name */
-#define DEVNAME "umass"
-#define DEVNAME_SIM "umass-sim"
-
-#define UMASS_MAX_TRANSFER_SIZE 65536
-/* Approximate maximum transfer speeds (assumes 33% overhead). */
-#define UMASS_FULL_TRANSFER_SPEED 1000
-#define UMASS_HIGH_TRANSFER_SPEED 40000
-#define UMASS_FLOPPY_TRANSFER_SPEED 20
-
-#define UMASS_TIMEOUT 5000 /* msecs */
-
-/* CAM specific definitions */
-
-#define UMASS_SCSIID_MAX 1 /* maximum number of drives expected */
-#define UMASS_SCSIID_HOST UMASS_SCSIID_MAX
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-
-/* Bulk-Only features */
-
-#define UR_BBB_RESET 0xff /* Bulk-Only reset */
-#define UR_BBB_GET_MAX_LUN 0xfe /* Get maximum lun */
-
-/* Command Block Wrapper */
-typedef struct {
- uDWord dCBWSignature;
-# define CBWSIGNATURE 0x43425355
- uDWord dCBWTag;
- uDWord dCBWDataTransferLength;
- uByte bCBWFlags;
-# define CBWFLAGS_OUT 0x00
-# define CBWFLAGS_IN 0x80
- uByte bCBWLUN;
- uByte bCDBLength;
-# define CBWCDBLENGTH 16
- uByte CBWCDB[CBWCDBLENGTH];
-} __packed umass_bbb_cbw_t;
-#define UMASS_BBB_CBW_SIZE 31
-
-/* Command Status Wrapper */
-typedef struct {
- uDWord dCSWSignature;
-# define CSWSIGNATURE 0x53425355
-# define CSWSIGNATURE_IMAGINATION_DBX1 0x43425355
-# define CSWSIGNATURE_OLYMPUS_C1 0x55425355
- uDWord dCSWTag;
- uDWord dCSWDataResidue;
- uByte bCSWStatus;
-# define CSWSTATUS_GOOD 0x0
-# define CSWSTATUS_FAILED 0x1
-# define CSWSTATUS_PHASE 0x2
-} __packed umass_bbb_csw_t;
-#define UMASS_BBB_CSW_SIZE 13
-
-/* CBI features */
-
-#define UR_CBI_ADSC 0x00
-
-typedef unsigned char umass_cbi_cbl_t[16]; /* Command block */
-
-typedef union {
- struct {
- unsigned char type;
- #define IDB_TYPE_CCI 0x00
- unsigned char value;
- #define IDB_VALUE_PASS 0x00
- #define IDB_VALUE_FAIL 0x01
- #define IDB_VALUE_PHASE 0x02
- #define IDB_VALUE_PERSISTENT 0x03
- #define IDB_VALUE_STATUS_MASK 0x03
- } common;
-
- struct {
- unsigned char asc;
- unsigned char ascq;
- } ufi;
-} umass_cbi_sbl_t;
-
-
-
-struct umass_softc; /* see below */
-
-typedef void (*transfer_cb_f) (struct umass_softc *sc, void *priv,
- int residue, int status);
-#define STATUS_CMD_OK 0 /* everything ok */
-#define STATUS_CMD_UNKNOWN 1 /* will have to fetch sense */
-#define STATUS_CMD_FAILED 2 /* transfer was ok, command failed */
-#define STATUS_WIRE_FAILED 3 /* couldn't even get command across */
-
-typedef void (*wire_reset_f) (struct umass_softc *sc, int status);
-typedef void (*wire_transfer_f) (struct umass_softc *sc, int lun,
- void *cmd, int cmdlen, void *data, int datalen,
- int dir, u_int timeout, transfer_cb_f cb, void *priv);
-typedef void (*wire_state_f) (usbd_xfer_handle xfer,
- usbd_private_handle priv, usbd_status err);
-
-typedef int (*command_transform_f) (struct umass_softc *sc,
- unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen);
-
-
-struct umass_devdescr_t {
- u_int32_t vid;
-# define VID_WILDCARD 0xffffffff
-# define VID_EOT 0xfffffffe
- u_int32_t pid;
-# define PID_WILDCARD 0xffffffff
-# define PID_EOT 0xfffffffe
- u_int32_t rid;
-# define RID_WILDCARD 0xffffffff
-# define RID_EOT 0xfffffffe
-
- /* wire and command protocol */
- u_int16_t proto;
-# define UMASS_PROTO_BBB 0x0001 /* USB wire protocol */
-# define UMASS_PROTO_CBI 0x0002
-# define UMASS_PROTO_CBI_I 0x0004
-# define UMASS_PROTO_WIRE 0x00ff /* USB wire protocol mask */
-# define UMASS_PROTO_SCSI 0x0100 /* command protocol */
-# define UMASS_PROTO_ATAPI 0x0200
-# define UMASS_PROTO_UFI 0x0400
-# define UMASS_PROTO_RBC 0x0800
-# define UMASS_PROTO_COMMAND 0xff00 /* command protocol mask */
-
- /* Device specific quirks */
- u_int16_t quirks;
-# define NO_QUIRKS 0x0000
- /* The drive does not support Test Unit Ready. Convert to Start Unit
- */
-# define NO_TEST_UNIT_READY 0x0001
- /* The drive does not reset the Unit Attention state after REQUEST
- * SENSE has been sent. The INQUIRY command does not reset the UA
- * either, and so CAM runs in circles trying to retrieve the initial
- * INQUIRY data.
- */
-# define RS_NO_CLEAR_UA 0x0002
- /* The drive does not support START STOP. */
-# define NO_START_STOP 0x0004
- /* Don't ask for full inquiry data (255b). */
-# define FORCE_SHORT_INQUIRY 0x0008
- /* Needs to be initialised the Shuttle way */
-# define SHUTTLE_INIT 0x0010
- /* Drive needs to be switched to alternate iface 1 */
-# define ALT_IFACE_1 0x0020
- /* Drive does not do 1Mb/s, but just floppy speeds (20kb/s) */
-# define FLOPPY_SPEED 0x0040
- /* The device can't count and gets the residue of transfers wrong */
-# define IGNORE_RESIDUE 0x0080
- /* No GetMaxLun call */
-# define NO_GETMAXLUN 0x0100
- /* The device uses a weird CSWSIGNATURE. */
-# define WRONG_CSWSIG 0x0200
- /* Device cannot handle INQUIRY so fake a generic response */
-# define NO_INQUIRY 0x0400
- /* Device cannot handle INQUIRY EVPD, return CHECK CONDITION */
-# define NO_INQUIRY_EVPD 0x0800
- /* Pad all RBC requests to 12 bytes. */
-# define RBC_PAD_TO_12 0x1000
- /* Device reports number of sectors from READ_CAPACITY, not max
- * sector number.
- */
-# define READ_CAPACITY_OFFBY1 0x2000
- /* Device cannot handle a SCSI synchronize cache command. Normally
- * this quirk would be handled in the cam layer, but for IDE bridges
- * we need to associate the quirk with the bridge and not the
- * underlying disk device. This is handled by faking a success result.
- */
-# define NO_SYNCHRONIZE_CACHE 0x4000
-};
-
-static struct umass_devdescr_t umass_devdescrs[] = {
- { USB_VENDOR_ADDONICS2, USB_PRODUCT_ADDONICS2_CABLE_205, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_AIPTEK, USB_PRODUCT_AIPTEK_POCKETCAM3M, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_UMCR_9361, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO230, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO330, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_ASAHIOPTICAL, PID_WILDCARD, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- RS_NO_CLEAR_UA
- },
- { USB_VENDOR_ADDON, USB_PRODUCT_ADDON_ATTACHE, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_ADDON, USB_PRODUCT_ADDON_A256MB, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_ADDON, USB_PRODUCT_ADDON_DISKPRO512, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2SCSI, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_CASIO, USB_PRODUCT_CASIO_QV_DIGICAM, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_INQUIRY
- },
- { USB_VENDOR_CCYU, USB_PRODUCT_CCYU_ED1064, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_CENTURY, USB_PRODUCT_CENTURY_EX35QUAT, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_DESKNOTE, USB_PRODUCT_DESKNOTE_UCR_61S2B, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_DMI, USB_PRODUCT_DMI_CFSM_RW, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_875DC, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_INQUIRY
- },
- { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_895, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_FEIYA, USB_PRODUCT_FEIYA_5IN1, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_FREECOM, USB_PRODUCT_FREECOM_DVD, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- RS_NO_CLEAR_UA
- },
- { USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE_2, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB_2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- WRONG_CSWSIG
- },
- { USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FG, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_USB, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- NO_INQUIRY
- },
- { USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_DZ_MV100A, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_HP, USB_PRODUCT_HP_CDW4E, RID_WILDCARD,
- UMASS_PROTO_ATAPI,
- NO_QUIRKS
- },
- { USB_VENDOR_HP, USB_PRODUCT_HP_CDW8200, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- NO_TEST_UNIT_READY | NO_START_STOP
- },
- { USB_VENDOR_IMAGINATION, USB_PRODUCT_IMAGINATION_DBX1, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- WRONG_CSWSIG
- },
- { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_STORAGE_V2, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_TEST_UNIT_READY | NO_START_STOP | ALT_IFACE_1
- },
- { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_IU_CD2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_DVR_UEH8, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100, RID_WILDCARD,
- /* XXX This is not correct as there are Zip drives that use ATAPI.
- */
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_TEST_UNIT_READY
- },
- { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_L3, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S3X, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_INQUIRY
- },
- { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S4, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_INQUIRY
- },
- { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S5, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_LACIE, USB_PRODUCT_LACIE_HD, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_CF_READER, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_JUMPSHOT, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443SU2, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443U2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_TEST_UNIT_READY | NO_START_STOP
- },
- { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIHD50, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_E223, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_F300, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_CDRRW, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_FDD, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_E398, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_INQUIRY_EVPD | NO_GETMAXLUN
- },
- { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE | NO_GETMAXLUN | RS_NO_CLEAR_UA
- },
- { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY | IGNORE_RESIDUE
- },
- { USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY
- },
- { USB_VENDOR_NETAC, USB_PRODUCT_NETAC_CF_CARD, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_NETAC, USB_PRODUCT_NETAC_ONLYDISK, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_CLIK_40, RID_WILDCARD,
- UMASS_PROTO_ATAPI,
- NO_INQUIRY
- },
- { USB_VENDOR_NIKON, USB_PRODUCT_NIKON_D300, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- WRONG_CSWSIG
- },
- { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFMS_RW, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_COMBO, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER2, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN | NO_SYNCHRONIZE_CACHE
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDCFE_B_CF_READER, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDSM_B_READER, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_INQUIRY
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_READER, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_UCF100, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- NO_INQUIRY | NO_GETMAXLUN
- },
- { USB_VENDOR_ONSPEC2, USB_PRODUCT_ONSPEC2_IMAGEMATE_SDDR55, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXL840AN, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB20AN, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB35AN, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_LS120CAM, RID_WILDCARD,
- UMASS_PROTO_UFI,
- NO_QUIRKS
- },
- { USB_VENDOR_PLEXTOR, USB_PRODUCT_PLEXTOR_40_12_40U, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_TEST_UNIT_READY
- },
- { USB_VENDOR_PNY, USB_PRODUCT_PNY_ATTACHE2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE | NO_START_STOP
- },
- { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_YP_U2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- SHUTTLE_INIT | NO_GETMAXLUN
- },
- { USB_VENDOR_SAMSUNG_TECHWIN, USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05A, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR09, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR12, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR31, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- READ_CAPACITY_OFFBY1
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_256, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_128, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_256, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CDRW, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CF, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- NO_TEST_UNIT_READY | NO_START_STOP | SHUTTLE_INIT
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBATAPI, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBCFSM, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_HIFD, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SDDR09, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- SHUTTLE_INIT
- },
- { USB_VENDOR_SIIG, USB_PRODUCT_SIIG_WINTERREADER, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_MD_7425, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_SX_520Z, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, 0x0500,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- RBC_PAD_TO_12
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, 0x0600,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- RBC_PAD_TO_12
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM, 0x0500,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- RBC_PAD_TO_12
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_MSC_U03, RID_WILDCARD,
- UMASS_PROTO_UFI | UMASS_PROTO_CBI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_NW_MS7, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_PEG_N760C, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSACUS1, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_PORTABLE_HDD_V2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_TAUGA, USB_PRODUCT_TAUGA_CAMERAMATE, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB, RID_WILDCARD,
- UMASS_PROTO_UFI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_TREK, USB_PRODUCT_TREK_MEMKEY, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_C3310, RID_WILDCARD,
- UMASS_PROTO_UFI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_MP3, RID_WILDCARD,
- UMASS_PROTO_RBC,
- NO_QUIRKS
- },
- { USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_T33520, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_MDIV, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_VIA, USB_PRODUCT_VIA_USB2IDEBRIDGE, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_SYNCHRONIZE_CACHE
- },
- { USB_VENDOR_VIVITAR, USB_PRODUCT_VIVITAR_35XX, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_COMBO, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_EXTHDD, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYBOOK, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY_EVPD
- },
- { USB_VENDOR_WINMAXGROUP, USB_PRODUCT_WINMAXGROUP_FLASH64MC, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_YANO, USB_PRODUCT_YANO_FW800HD, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- FORCE_SHORT_INQUIRY
- },
- { USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_ZORAN, USB_PRODUCT_ZORAN_EX20DSC, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { VID_EOT, PID_EOT, RID_EOT, 0, 0 }
-};
-
-
-/* the per device structure */
-struct umass_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev; /* USB device */
-
- struct cam_sim *umass_sim; /* SCSI Interface Module */
-
- unsigned char flags; /* various device flags */
-# define UMASS_FLAGS_GONE 0x01 /* devices is no more */
-
- u_int16_t proto; /* wire and cmd protocol */
- u_int16_t quirks; /* they got it almost right */
-
- usbd_interface_handle iface; /* Mass Storage interface */
- int ifaceno; /* MS iface number */
-
- u_int8_t bulkin; /* bulk-in Endpoint Address */
- u_int8_t bulkout; /* bulk-out Endpoint Address */
- u_int8_t intrin; /* intr-in Endp. (CBI) */
- usbd_pipe_handle bulkin_pipe;
- usbd_pipe_handle bulkout_pipe;
- usbd_pipe_handle intrin_pipe;
-
- /* Reset the device in a wire protocol specific way */
- wire_reset_f reset;
-
- /* The start of a wire transfer. It prepares the whole transfer (cmd,
- * data, and status stage) and initiates it. It is up to the state
- * machine (below) to handle the various stages and errors in these
- */
- wire_transfer_f transfer;
-
- /* The state machine, handling the various states during a transfer */
- wire_state_f state;
-
- /* The command transform function is used to conver the SCSI commands
- * into their derivatives, like UFI, ATAPI, and friends.
- */
- command_transform_f transform; /* command transform */
-
- /* Bulk specific variables for transfers in progress */
- umass_bbb_cbw_t cbw; /* command block wrapper */
- umass_bbb_csw_t csw; /* command status wrapper*/
- /* CBI specific variables for transfers in progress */
- umass_cbi_cbl_t cbl; /* command block */
- umass_cbi_sbl_t sbl; /* status block */
-
- /* generic variables for transfers in progress */
- /* ctrl transfer requests */
- usb_device_request_t request;
-
- /* xfer handles
- * Most of our operations are initiated from interrupt context, so
- * we need to avoid using the one that is in use. We want to avoid
- * allocating them in the interrupt context as well.
- */
- /* indices into array below */
-# define XFER_BBB_CBW 0 /* Bulk-Only */
-# define XFER_BBB_DATA 1
-# define XFER_BBB_DCLEAR 2
-# define XFER_BBB_CSW1 3
-# define XFER_BBB_CSW2 4
-# define XFER_BBB_SCLEAR 5
-# define XFER_BBB_RESET1 6
-# define XFER_BBB_RESET2 7
-# define XFER_BBB_RESET3 8
-
-# define XFER_CBI_CB 0 /* CBI */
-# define XFER_CBI_DATA 1
-# define XFER_CBI_STATUS 2
-# define XFER_CBI_DCLEAR 3
-# define XFER_CBI_SCLEAR 4
-# define XFER_CBI_RESET1 5
-# define XFER_CBI_RESET2 6
-# define XFER_CBI_RESET3 7
-
-# define XFER_NR 9 /* maximum number */
-
- usbd_xfer_handle transfer_xfer[XFER_NR]; /* for ctrl xfers */
-
- int transfer_dir; /* data direction */
- void *transfer_data; /* data buffer */
- int transfer_datalen; /* (maximum) length */
- int transfer_actlen; /* actual length */
- transfer_cb_f transfer_cb; /* callback */
- void *transfer_priv; /* for callback */
- int transfer_status;
-
- int transfer_state;
-# define TSTATE_ATTACH 0 /* in attach */
-# define TSTATE_IDLE 1
-# define TSTATE_BBB_COMMAND 2 /* CBW transfer */
-# define TSTATE_BBB_DATA 3 /* Data transfer */
-# define TSTATE_BBB_DCLEAR 4 /* clear endpt stall */
-# define TSTATE_BBB_STATUS1 5 /* clear endpt stall */
-# define TSTATE_BBB_SCLEAR 6 /* clear endpt stall */
-# define TSTATE_BBB_STATUS2 7 /* CSW transfer */
-# define TSTATE_BBB_RESET1 8 /* reset command */
-# define TSTATE_BBB_RESET2 9 /* in clear stall */
-# define TSTATE_BBB_RESET3 10 /* out clear stall */
-# define TSTATE_CBI_COMMAND 11 /* command transfer */
-# define TSTATE_CBI_DATA 12 /* data transfer */
-# define TSTATE_CBI_STATUS 13 /* status transfer */
-# define TSTATE_CBI_DCLEAR 14 /* clear ep stall */
-# define TSTATE_CBI_SCLEAR 15 /* clear ep stall */
-# define TSTATE_CBI_RESET1 16 /* reset command */
-# define TSTATE_CBI_RESET2 17 /* in clear stall */
-# define TSTATE_CBI_RESET3 18 /* out clear stall */
-# define TSTATE_STATES 19 /* # of states above */
-
-
- /* SCSI/CAM specific variables */
- unsigned char cam_scsi_command[CAM_MAX_CDBLEN];
- unsigned char cam_scsi_command2[CAM_MAX_CDBLEN];
- struct scsi_sense cam_scsi_sense;
- struct scsi_sense cam_scsi_test_unit_ready;
- struct callout cam_scsi_rescan_ch;
-
- int timeout; /* in msecs */
-
- int maxlun; /* maximum LUN number */
-};
-
-#ifdef USB_DEBUG
-char *states[TSTATE_STATES+1] = {
- /* should be kept in sync with the list at transfer_state */
- "Attach",
- "Idle",
- "BBB CBW",
- "BBB Data",
- "BBB Data bulk-in/-out clear stall",
- "BBB CSW, 1st attempt",
- "BBB CSW bulk-in clear stall",
- "BBB CSW, 2nd attempt",
- "BBB Reset",
- "BBB bulk-in clear stall",
- "BBB bulk-out clear stall",
- "CBI Command",
- "CBI Data",
- "CBI Status",
- "CBI Data bulk-in/-out clear stall",
- "CBI Status intr-in clear stall",
- "CBI Reset",
- "CBI bulk-in clear stall",
- "CBI bulk-out clear stall",
- NULL
-};
-#endif
-
-/* If device cannot return valid inquiry data, fake it */
-static uint8_t fake_inq_data[SHORT_INQUIRY_LENGTH] = {
- 0, /*removable*/ 0x80, SCSI_REV_2, SCSI_REV_2,
- /*additional_length*/ 31, 0, 0, 0
-};
-
-/* USB device probe/attach/detach functions */
-static device_probe_t umass_match;
-static device_attach_t umass_attach;
-static device_detach_t umass_detach;
-
-static device_method_t umass_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, umass_match),
- DEVMETHOD(device_attach, umass_attach),
- DEVMETHOD(device_detach, umass_detach),
-
- { 0, 0 }
-};
-
-static driver_t umass_driver = {
- "umass",
- umass_methods,
- sizeof(struct umass_softc)
-};
-
-static devclass_t umass_devclass;
-
-static int umass_match_proto (struct umass_softc *sc,
- usbd_interface_handle iface,
- usbd_device_handle udev);
-
-/* quirk functions */
-static void umass_init_shuttle (struct umass_softc *sc);
-
-/* generic transfer functions */
-static usbd_status umass_setup_transfer (struct umass_softc *sc,
- usbd_pipe_handle pipe,
- void *buffer, int buflen, int flags,
- usbd_xfer_handle xfer);
-static usbd_status umass_setup_ctrl_transfer (struct umass_softc *sc,
- usbd_device_handle udev,
- usb_device_request_t *req,
- void *buffer, int buflen, int flags,
- usbd_xfer_handle xfer);
-static void umass_clear_endpoint_stall (struct umass_softc *sc,
- u_int8_t endpt, usbd_pipe_handle pipe,
- int state, usbd_xfer_handle xfer);
-static void umass_reset (struct umass_softc *sc,
- transfer_cb_f cb, void *priv);
-
-/* Bulk-Only related functions */
-static void umass_bbb_reset (struct umass_softc *sc, int status);
-static void umass_bbb_transfer (struct umass_softc *sc, int lun,
- void *cmd, int cmdlen,
- void *data, int datalen, int dir, u_int timeout,
- transfer_cb_f cb, void *priv);
-static void umass_bbb_state (usbd_xfer_handle xfer,
- usbd_private_handle priv,
- usbd_status err);
-static int umass_bbb_get_max_lun
- (struct umass_softc *sc);
-
-/* CBI related functions */
-static int umass_cbi_adsc (struct umass_softc *sc,
- char *buffer, int buflen,
- usbd_xfer_handle xfer);
-static void umass_cbi_reset (struct umass_softc *sc, int status);
-static void umass_cbi_transfer (struct umass_softc *sc, int lun,
- void *cmd, int cmdlen,
- void *data, int datalen, int dir, u_int timeout,
- transfer_cb_f cb, void *priv);
-static void umass_cbi_state (usbd_xfer_handle xfer,
- usbd_private_handle priv, usbd_status err);
-
-/* CAM related functions */
-static void umass_cam_action (struct cam_sim *sim, union ccb *ccb);
-static void umass_cam_poll (struct cam_sim *sim);
-
-static void umass_cam_cb (struct umass_softc *sc, void *priv,
- int residue, int status);
-static void umass_cam_sense_cb (struct umass_softc *sc, void *priv,
- int residue, int status);
-static void umass_cam_quirk_cb (struct umass_softc *sc, void *priv,
- int residue, int status);
-
-static void umass_cam_rescan_callback
- (struct cam_periph *periph,union ccb *ccb);
-static void umass_cam_rescan (void *addr);
-
-static int umass_cam_attach_sim (struct umass_softc *sc);
-static int umass_cam_attach (struct umass_softc *sc);
-static int umass_cam_detach_sim (struct umass_softc *sc);
-
-
-/* SCSI specific functions */
-static int umass_scsi_transform (struct umass_softc *sc,
- unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen);
-
-/* UFI specific functions */
-#define UFI_COMMAND_LENGTH 12 /* UFI commands are always 12 bytes */
-static int umass_ufi_transform (struct umass_softc *sc,
- unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen);
-
-/* ATAPI (8070i) specific functions */
-#define ATAPI_COMMAND_LENGTH 12 /* ATAPI commands are always 12 bytes */
-static int umass_atapi_transform (struct umass_softc *sc,
- unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen);
-
-/* RBC specific functions */
-static int umass_rbc_transform (struct umass_softc *sc,
- unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen);
-
-#ifdef USB_DEBUG
-/* General debugging functions */
-static void umass_bbb_dump_cbw (struct umass_softc *sc, umass_bbb_cbw_t *cbw);
-static void umass_bbb_dump_csw (struct umass_softc *sc, umass_bbb_csw_t *csw);
-static void umass_cbi_dump_cmd (struct umass_softc *sc, void *cmd, int cmdlen);
-static void umass_dump_buffer (struct umass_softc *sc, u_int8_t *buffer,
- int buflen, int printlen);
-#endif
-
-MODULE_DEPEND(umass, cam, 1, 1, 1);
-MODULE_DEPEND(umass, usb, 1, 1, 1);
-
-/*
- * USB device probe/attach/detach
- */
-
-/*
- * Match the device we are seeing with the devices supported. Fill in the
- * description in the softc accordingly. This function is called from both
- * probe and attach.
- */
-
-static int
-umass_match_proto(struct umass_softc *sc, usbd_interface_handle iface,
- usbd_device_handle udev)
-{
- usb_device_descriptor_t *dd;
- usb_interface_descriptor_t *id;
- int i;
- int found = 0;
-
- sc->sc_udev = udev;
- sc->proto = 0;
- sc->quirks = 0;
-
- dd = usbd_get_device_descriptor(udev);
-
- /* An entry specifically for Y-E Data devices as they don't fit in the
- * device description table.
- */
- if (UGETW(dd->idVendor) == USB_VENDOR_YEDATA
- && UGETW(dd->idProduct) == USB_PRODUCT_YEDATA_FLASHBUSTERU) {
-
- /* Revisions < 1.28 do not handle the interrupt endpoint
- * very well.
- */
- if (UGETW(dd->bcdDevice) < 0x128) {
- sc->proto = UMASS_PROTO_UFI | UMASS_PROTO_CBI;
- } else {
- sc->proto = UMASS_PROTO_UFI | UMASS_PROTO_CBI_I;
- }
-
- /*
- * Revisions < 1.28 do not have the TEST UNIT READY command
- * Revisions == 1.28 have a broken TEST UNIT READY
- */
- if (UGETW(dd->bcdDevice) <= 0x128)
- sc->quirks |= NO_TEST_UNIT_READY;
-
- sc->quirks |= RS_NO_CLEAR_UA | FLOPPY_SPEED;
- return(UMATCH_VENDOR_PRODUCT);
- }
-
- /* Check the list of supported devices for a match. While looking,
- * check for wildcarded and fully matched. First match wins.
- */
- for (i = 0; umass_devdescrs[i].vid != VID_EOT && !found; i++) {
- if (umass_devdescrs[i].vid == VID_WILDCARD &&
- umass_devdescrs[i].pid == PID_WILDCARD &&
- umass_devdescrs[i].rid == RID_WILDCARD) {
- printf("umass: ignoring invalid wildcard quirk\n");
- continue;
- }
- if ((umass_devdescrs[i].vid == UGETW(dd->idVendor) ||
- umass_devdescrs[i].vid == VID_WILDCARD)
- && (umass_devdescrs[i].pid == UGETW(dd->idProduct) ||
- umass_devdescrs[i].pid == PID_WILDCARD)) {
- if (umass_devdescrs[i].rid == RID_WILDCARD) {
- sc->proto = umass_devdescrs[i].proto;
- sc->quirks = umass_devdescrs[i].quirks;
- return (UMATCH_VENDOR_PRODUCT);
- } else if (umass_devdescrs[i].rid ==
- UGETW(dd->bcdDevice)) {
- sc->proto = umass_devdescrs[i].proto;
- sc->quirks = umass_devdescrs[i].quirks;
- return (UMATCH_VENDOR_PRODUCT_REV);
- } /* else RID does not match */
- }
- }
-
- /* Check for a standards compliant device */
- id = usbd_get_interface_descriptor(iface);
- if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
- return(UMATCH_NONE);
-
- switch (id->bInterfaceSubClass) {
- case UISUBCLASS_SCSI:
- sc->proto |= UMASS_PROTO_SCSI;
- break;
- case UISUBCLASS_UFI:
- sc->proto |= UMASS_PROTO_UFI;
- break;
- case UISUBCLASS_RBC:
- sc->proto |= UMASS_PROTO_RBC;
- break;
- case UISUBCLASS_SFF8020I:
- case UISUBCLASS_SFF8070I:
- sc->proto |= UMASS_PROTO_ATAPI;
- break;
- default:
- DPRINTF(UDMASS_GEN, ("%s: Unsupported command protocol %d\n",
- device_get_nameunit(sc->sc_dev), id->bInterfaceSubClass));
- return(UMATCH_NONE);
- }
-
- switch (id->bInterfaceProtocol) {
- case UIPROTO_MASS_CBI:
- sc->proto |= UMASS_PROTO_CBI;
- break;
- case UIPROTO_MASS_CBI_I:
- sc->proto |= UMASS_PROTO_CBI_I;
- break;
- case UIPROTO_MASS_BBB_OLD:
- case UIPROTO_MASS_BBB:
- sc->proto |= UMASS_PROTO_BBB;
- break;
- default:
- DPRINTF(UDMASS_GEN, ("%s: Unsupported wire protocol %d\n",
- device_get_nameunit(sc->sc_dev), id->bInterfaceProtocol));
- return(UMATCH_NONE);
- }
-
- return(UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
-}
-
-static int
-umass_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- struct umass_softc *sc = device_get_softc(self);
-
- sc->sc_dev = self;
- if (uaa->iface == NULL)
- return(UMATCH_NONE);
-
- return(umass_match_proto(sc, uaa->iface, uaa->device));
-}
-
-static int
-umass_attach(device_t self)
-{
- struct umass_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
- int err;
-
- /*
- * the softc struct is bzero-ed in device_set_driver. We can safely
- * call umass_detach without specifically initialising the struct.
- */
- sc->sc_dev = self;
- sc->iface = uaa->iface;
- sc->ifaceno = uaa->ifaceno;
- callout_init(&sc->cam_scsi_rescan_ch, 0);
-
- /* initialise the proto and drive values in the umass_softc (again) */
- (void) umass_match_proto(sc, sc->iface, uaa->device);
-
- id = usbd_get_interface_descriptor(sc->iface);
-#ifdef USB_DEBUG
- printf("%s: ", device_get_nameunit(sc->sc_dev));
- switch (sc->proto&UMASS_PROTO_COMMAND) {
- case UMASS_PROTO_SCSI:
- printf("SCSI");
- break;
- case UMASS_PROTO_ATAPI:
- printf("8070i (ATAPI)");
- break;
- case UMASS_PROTO_UFI:
- printf("UFI");
- break;
- case UMASS_PROTO_RBC:
- printf("RBC");
- break;
- default:
- printf("(unknown 0x%02x)", sc->proto&UMASS_PROTO_COMMAND);
- break;
- }
- printf(" over ");
- switch (sc->proto&UMASS_PROTO_WIRE) {
- case UMASS_PROTO_BBB:
- printf("Bulk-Only");
- break;
- case UMASS_PROTO_CBI: /* uses Comand/Bulk pipes */
- printf("CBI");
- break;
- case UMASS_PROTO_CBI_I: /* uses Comand/Bulk/Interrupt pipes */
- printf("CBI with CCI");
-#ifndef CBI_I
- printf(" (using CBI)");
-#endif
- break;
- default:
- printf("(unknown 0x%02x)", sc->proto&UMASS_PROTO_WIRE);
- }
- printf("; quirks = 0x%04x\n", sc->quirks);
-#endif
-
-#ifndef CBI_I
- if (sc->proto & UMASS_PROTO_CBI_I) {
- /* See beginning of file for comment on the use of CBI with CCI */
- sc->proto = (sc->proto & ~UMASS_PROTO_CBI_I) | UMASS_PROTO_CBI;
- }
-#endif
-
- if (sc->quirks & ALT_IFACE_1) {
- err = usbd_set_interface(uaa->iface, 1);
- if (err) {
- DPRINTF(UDMASS_USB, ("%s: could not switch to "
- "Alt Interface %d\n",
- device_get_nameunit(sc->sc_dev), 1));
- umass_detach(self);
- return ENXIO;
- }
- }
-
- /*
- * In addition to the Control endpoint the following endpoints
- * are required:
- * a) bulk-in endpoint.
- * b) bulk-out endpoint.
- * and for Control/Bulk/Interrupt with CCI (CBI_I)
- * c) intr-in
- *
- * The endpoint addresses are not fixed, so we have to read them
- * from the device descriptors of the current interface.
- */
- for (i = 0 ; i < id->bNumEndpoints ; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->iface, i);
- if (!ed) {
- printf("%s: could not read endpoint descriptor\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- sc->bulkin = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- sc->bulkout = ed->bEndpointAddress;
- } else if (sc->proto & UMASS_PROTO_CBI_I
- && UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
- && (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
- sc->intrin = ed->bEndpointAddress;
-#ifdef USB_DEBUG
- if (UGETW(ed->wMaxPacketSize) > 2) {
- DPRINTF(UDMASS_CBI, ("%s: intr size is %d\n",
- device_get_nameunit(sc->sc_dev),
- UGETW(ed->wMaxPacketSize)));
- }
-#endif
- }
- }
-
- /* check whether we found all the endpoints we need */
- if (!sc->bulkin || !sc->bulkout
- || (sc->proto & UMASS_PROTO_CBI_I && !sc->intrin) ) {
- DPRINTF(UDMASS_USB, ("%s: endpoint not found %d/%d/%d\n",
- device_get_nameunit(sc->sc_dev),
- sc->bulkin, sc->bulkout, sc->intrin));
- umass_detach(self);
- return ENXIO;
- }
-
- /* Open the bulk-in and -out pipe */
- err = usbd_open_pipe(sc->iface, sc->bulkout,
- USBD_EXCLUSIVE_USE, &sc->bulkout_pipe);
- if (err) {
- DPRINTF(UDMASS_USB, ("%s: cannot open %d-out pipe (bulk)\n",
- device_get_nameunit(sc->sc_dev), sc->bulkout));
- umass_detach(self);
- return ENXIO;
- }
- err = usbd_open_pipe(sc->iface, sc->bulkin,
- USBD_EXCLUSIVE_USE, &sc->bulkin_pipe);
- if (err) {
- DPRINTF(UDMASS_USB, ("%s: could not open %d-in pipe (bulk)\n",
- device_get_nameunit(sc->sc_dev), sc->bulkin));
- umass_detach(self);
- return ENXIO;
- }
- /* Open the intr-in pipe if the protocol is CBI with CCI.
- * Note: early versions of the Zip drive do have an interrupt pipe, but
- * this pipe is unused.
- *
- * We do not open the interrupt pipe as an interrupt pipe, but as a
- * normal bulk endpoint. We send an IN transfer down the wire at the
- * appropriate time, because we know exactly when to expect data on
- * that endpoint. This saves bandwidth, but more important, makes the
- * code for handling the data on that endpoint simpler. No data
- * arriving concurrently.
- */
- if (sc->proto & UMASS_PROTO_CBI_I) {
- err = usbd_open_pipe(sc->iface, sc->intrin,
- USBD_EXCLUSIVE_USE, &sc->intrin_pipe);
- if (err) {
- DPRINTF(UDMASS_USB, ("%s: couldn't open %d-in (intr)\n",
- device_get_nameunit(sc->sc_dev), sc->intrin));
- umass_detach(self);
- return ENXIO;
- }
- }
-
- /* initialisation of generic part */
- sc->transfer_state = TSTATE_ATTACH;
-
- /* request a sufficient number of xfer handles */
- for (i = 0; i < XFER_NR; i++) {
- sc->transfer_xfer[i] = usbd_alloc_xfer(uaa->device);
- if (!sc->transfer_xfer[i]) {
- DPRINTF(UDMASS_USB, ("%s: Out of memory\n",
- device_get_nameunit(sc->sc_dev)));
- umass_detach(self);
- return ENXIO;
- }
- }
-
- /* Initialise the wire protocol specific methods */
- if (sc->proto & UMASS_PROTO_BBB) {
- sc->reset = umass_bbb_reset;
- sc->transfer = umass_bbb_transfer;
- sc->state = umass_bbb_state;
- } else if (sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I)) {
- sc->reset = umass_cbi_reset;
- sc->transfer = umass_cbi_transfer;
- sc->state = umass_cbi_state;
-#ifdef USB_DEBUG
- } else {
- panic("%s:%d: Unknown proto 0x%02x",
- __FILE__, __LINE__, sc->proto);
-#endif
- }
-
- if (sc->proto & UMASS_PROTO_SCSI)
- sc->transform = umass_scsi_transform;
- else if (sc->proto & UMASS_PROTO_UFI)
- sc->transform = umass_ufi_transform;
- else if (sc->proto & UMASS_PROTO_ATAPI)
- sc->transform = umass_atapi_transform;
- else if (sc->proto & UMASS_PROTO_RBC)
- sc->transform = umass_rbc_transform;
-#ifdef USB_DEBUG
- else
- panic("No transformation defined for command proto 0x%02x",
- sc->proto & UMASS_PROTO_COMMAND);
-#endif
-
- /* From here onwards the device can be used. */
-
- if (sc->quirks & SHUTTLE_INIT)
- umass_init_shuttle(sc);
-
- /* Get the maximum LUN supported by the device.
- */
- if (((sc->proto & UMASS_PROTO_WIRE) == UMASS_PROTO_BBB) &&
- !(sc->quirks & NO_GETMAXLUN))
- sc->maxlun = umass_bbb_get_max_lun(sc);
- else
- sc->maxlun = 0;
-
- if ((sc->proto & UMASS_PROTO_SCSI) ||
- (sc->proto & UMASS_PROTO_ATAPI) ||
- (sc->proto & UMASS_PROTO_UFI) ||
- (sc->proto & UMASS_PROTO_RBC)) {
- /* Prepare the SCSI command block */
- sc->cam_scsi_sense.opcode = REQUEST_SENSE;
- sc->cam_scsi_test_unit_ready.opcode = TEST_UNIT_READY;
-
- /* register the SIM */
- err = umass_cam_attach_sim(sc);
- if (err) {
- umass_detach(self);
- return ENXIO;
- }
- /* scan the new sim */
- err = umass_cam_attach(sc);
- if (err) {
- umass_cam_detach_sim(sc);
- umass_detach(self);
- return ENXIO;
- }
- } else {
- panic("%s:%d: Unknown proto 0x%02x",
- __FILE__, __LINE__, sc->proto);
- }
-
- sc->transfer_state = TSTATE_IDLE;
- DPRINTF(UDMASS_GEN, ("%s: Attach finished\n", device_get_nameunit(sc->sc_dev)));
-
- return 0;
-}
-
-static int
-umass_detach(device_t self)
-{
- struct umass_softc *sc = device_get_softc(self);
- int err = 0;
- int i;
-
- DPRINTF(UDMASS_USB, ("%s: detached\n", device_get_nameunit(sc->sc_dev)));
-
- sc->flags |= UMASS_FLAGS_GONE;
-
- /* abort all the pipes in case there are transfers active. */
- usbd_abort_default_pipe(sc->sc_udev);
- if (sc->bulkout_pipe)
- usbd_abort_pipe(sc->bulkout_pipe);
- if (sc->bulkin_pipe)
- usbd_abort_pipe(sc->bulkin_pipe);
- if (sc->intrin_pipe)
- usbd_abort_pipe(sc->intrin_pipe);
-
- callout_drain(&sc->cam_scsi_rescan_ch);
- if ((sc->proto & UMASS_PROTO_SCSI) ||
- (sc->proto & UMASS_PROTO_ATAPI) ||
- (sc->proto & UMASS_PROTO_UFI) ||
- (sc->proto & UMASS_PROTO_RBC))
- /* detach the SCSI host controller (SIM) */
- err = umass_cam_detach_sim(sc);
-
- for (i = 0; i < XFER_NR; i++)
- if (sc->transfer_xfer[i])
- usbd_free_xfer(sc->transfer_xfer[i]);
-
- /* remove all the pipes */
- if (sc->bulkout_pipe)
- usbd_close_pipe(sc->bulkout_pipe);
- if (sc->bulkin_pipe)
- usbd_close_pipe(sc->bulkin_pipe);
- if (sc->intrin_pipe)
- usbd_close_pipe(sc->intrin_pipe);
-
- return(err);
-}
-
-static void
-umass_init_shuttle(struct umass_softc *sc)
-{
- usb_device_request_t req;
- u_char status[2];
-
- /* The Linux driver does this, but no one can tell us what the
- * command does.
- */
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = 1; /* XXX unknown command */
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->ifaceno);
- USETW(req.wLength, sizeof status);
- (void) usbd_do_request(sc->sc_udev, &req, &status);
-
- DPRINTF(UDMASS_GEN, ("%s: Shuttle init returned 0x%02x%02x\n",
- device_get_nameunit(sc->sc_dev), status[0], status[1]));
-}
-
- /*
- * Generic functions to handle transfers
- */
-
-static usbd_status
-umass_setup_transfer(struct umass_softc *sc, usbd_pipe_handle pipe,
- void *buffer, int buflen, int flags,
- usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Initialise a USB transfer and then schedule it */
-
- (void) usbd_setup_xfer(xfer, pipe, (void *) sc, buffer, buflen, flags,
- sc->timeout, sc->state);
-
- err = usbd_transfer(xfer);
- if (err && err != USBD_IN_PROGRESS) {
- DPRINTF(UDMASS_BBB, ("%s: failed to setup transfer, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
- return(err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-
-static usbd_status
-umass_setup_ctrl_transfer(struct umass_softc *sc, usbd_device_handle udev,
- usb_device_request_t *req,
- void *buffer, int buflen, int flags,
- usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Initialise a USB control transfer and then schedule it */
-
- (void) usbd_setup_default_xfer(xfer, udev, (void *) sc,
- sc->timeout, req, buffer, buflen, flags, sc->state);
-
- err = usbd_transfer(xfer);
- if (err && err != USBD_IN_PROGRESS) {
- DPRINTF(UDMASS_BBB, ("%s: failed to setup ctrl transfer, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
-
- /* do not reset, as this would make us loop */
- return(err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-umass_clear_endpoint_stall(struct umass_softc *sc,
- u_int8_t endpt, usbd_pipe_handle pipe,
- int state, usbd_xfer_handle xfer)
-{
- usbd_device_handle udev;
-
- DPRINTF(UDMASS_BBB, ("%s: Clear endpoint 0x%02x stall\n",
- device_get_nameunit(sc->sc_dev), endpt));
-
- usbd_interface2device_handle(sc->iface, &udev);
-
- sc->transfer_state = state;
-
- usbd_clear_endpoint_toggle(pipe);
-
- sc->request.bmRequestType = UT_WRITE_ENDPOINT;
- sc->request.bRequest = UR_CLEAR_FEATURE;
- USETW(sc->request.wValue, UF_ENDPOINT_HALT);
- USETW(sc->request.wIndex, endpt);
- USETW(sc->request.wLength, 0);
- umass_setup_ctrl_transfer(sc, udev, &sc->request, NULL, 0, 0, xfer);
-}
-
-static void
-umass_reset(struct umass_softc *sc, transfer_cb_f cb, void *priv)
-{
- sc->transfer_cb = cb;
- sc->transfer_priv = priv;
-
- /* The reset is a forced reset, so no error (yet) */
- sc->reset(sc, STATUS_CMD_OK);
-}
-
-/*
- * Bulk protocol specific functions
- */
-
-static void
-umass_bbb_reset(struct umass_softc *sc, int status)
-{
- usbd_device_handle udev;
-
- KASSERT(sc->proto & UMASS_PROTO_BBB,
- ("%s: umass_bbb_reset: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /*
- * Reset recovery (5.3.4 in Universal Serial Bus Mass Storage Class)
- *
- * For Reset Recovery the host shall issue in the following order:
- * a) a Bulk-Only Mass Storage Reset
- * b) a Clear Feature HALT to the Bulk-In endpoint
- * c) a Clear Feature HALT to the Bulk-Out endpoint
- *
- * This is done in 3 steps, states:
- * TSTATE_BBB_RESET1
- * TSTATE_BBB_RESET2
- * TSTATE_BBB_RESET3
- *
- * If the reset doesn't succeed, the device should be port reset.
- */
-
- DPRINTF(UDMASS_BBB, ("%s: Bulk Reset\n",
- device_get_nameunit(sc->sc_dev)));
-
- sc->transfer_state = TSTATE_BBB_RESET1;
- sc->transfer_status = status;
-
- usbd_interface2device_handle(sc->iface, &udev);
-
- /* reset is a class specific interface write */
- sc->request.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- sc->request.bRequest = UR_BBB_RESET;
- USETW(sc->request.wValue, 0);
- USETW(sc->request.wIndex, sc->ifaceno);
- USETW(sc->request.wLength, 0);
- umass_setup_ctrl_transfer(sc, udev, &sc->request, NULL, 0, 0,
- sc->transfer_xfer[XFER_BBB_RESET1]);
-}
-
-static void
-umass_bbb_transfer(struct umass_softc *sc, int lun, void *cmd, int cmdlen,
- void *data, int datalen, int dir, u_int timeout,
- transfer_cb_f cb, void *priv)
-{
- KASSERT(sc->proto & UMASS_PROTO_BBB,
- ("%s: umass_bbb_transfer: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /* Be a little generous. */
- sc->timeout = timeout + UMASS_TIMEOUT;
-
- /*
- * Do a Bulk-Only transfer with cmdlen bytes from cmd, possibly
- * a data phase of datalen bytes from/to the device and finally a
- * csw read phase.
- * If the data direction was inbound a maximum of datalen bytes
- * is stored in the buffer pointed to by data.
- *
- * umass_bbb_transfer initialises the transfer and lets the state
- * machine in umass_bbb_state handle the completion. It uses the
- * following states:
- * TSTATE_BBB_COMMAND
- * -> TSTATE_BBB_DATA
- * -> TSTATE_BBB_STATUS
- * -> TSTATE_BBB_STATUS2
- * -> TSTATE_BBB_IDLE
- *
- * An error in any of those states will invoke
- * umass_bbb_reset.
- */
-
- /* check the given arguments */
- KASSERT(datalen == 0 || data != NULL,
- ("%s: datalen > 0, but no buffer",device_get_nameunit(sc->sc_dev)));
- KASSERT(cmdlen <= CBWCDBLENGTH,
- ("%s: cmdlen exceeds CDB length in CBW (%d > %d)",
- device_get_nameunit(sc->sc_dev), cmdlen, CBWCDBLENGTH));
- KASSERT(dir == DIR_NONE || datalen > 0,
- ("%s: datalen == 0 while direction is not NONE\n",
- device_get_nameunit(sc->sc_dev)));
- KASSERT(datalen == 0 || dir != DIR_NONE,
- ("%s: direction is NONE while datalen is not zero\n",
- device_get_nameunit(sc->sc_dev)));
- KASSERT(sizeof(umass_bbb_cbw_t) == UMASS_BBB_CBW_SIZE,
- ("%s: CBW struct does not have the right size (%ld vs. %d)\n",
- device_get_nameunit(sc->sc_dev),
- (long)sizeof(umass_bbb_cbw_t), UMASS_BBB_CBW_SIZE));
- KASSERT(sizeof(umass_bbb_csw_t) == UMASS_BBB_CSW_SIZE,
- ("%s: CSW struct does not have the right size (%ld vs. %d)\n",
- device_get_nameunit(sc->sc_dev),
- (long)sizeof(umass_bbb_csw_t), UMASS_BBB_CSW_SIZE));
-
- /*
- * Determine the direction of the data transfer and the length.
- *
- * dCBWDataTransferLength (datalen) :
- * This field indicates the number of bytes of data that the host
- * intends to transfer on the IN or OUT Bulk endpoint(as indicated by
- * the Direction bit) during the execution of this command. If this
- * field is set to 0, the device will expect that no data will be
- * transferred IN or OUT during this command, regardless of the value
- * of the Direction bit defined in dCBWFlags.
- *
- * dCBWFlags (dir) :
- * The bits of the Flags field are defined as follows:
- * Bits 0-6 reserved
- * Bit 7 Direction - this bit shall be ignored if the
- * dCBWDataTransferLength field is zero.
- * 0 = data Out from host to device
- * 1 = data In from device to host
- */
-
- /* Fill in the Command Block Wrapper
- * We fill in all the fields, so there is no need to bzero it first.
- */
- USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE);
- /* We don't care about the initial value, as long as the values are unique */
- USETDW(sc->cbw.dCBWTag, UGETDW(sc->cbw.dCBWTag) + 1);
- USETDW(sc->cbw.dCBWDataTransferLength, datalen);
- /* DIR_NONE is treated as DIR_OUT (0x00) */
- sc->cbw.bCBWFlags = (dir == DIR_IN? CBWFLAGS_IN:CBWFLAGS_OUT);
- sc->cbw.bCBWLUN = lun;
- sc->cbw.bCDBLength = cmdlen;
- bcopy(cmd, sc->cbw.CBWCDB, cmdlen);
-
- DIF(UDMASS_BBB, umass_bbb_dump_cbw(sc, &sc->cbw));
-
- /* store the details for the data transfer phase */
- sc->transfer_dir = dir;
- sc->transfer_data = data;
- sc->transfer_datalen = datalen;
- sc->transfer_actlen = 0;
- sc->transfer_cb = cb;
- sc->transfer_priv = priv;
- sc->transfer_status = STATUS_CMD_OK;
-
- /* move from idle to the command state */
- sc->transfer_state = TSTATE_BBB_COMMAND;
-
- /* Send the CBW from host to device via bulk-out endpoint. */
- if (umass_setup_transfer(sc, sc->bulkout_pipe,
- &sc->cbw, UMASS_BBB_CBW_SIZE, 0,
- sc->transfer_xfer[XFER_BBB_CBW])) {
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- }
-}
-
-
-static void
-umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status err)
-{
- struct umass_softc *sc = (struct umass_softc *) priv;
- usbd_xfer_handle next_xfer;
-
- KASSERT(sc->proto & UMASS_PROTO_BBB,
- ("%s: umass_bbb_state: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /*
- * State handling for BBB transfers.
- *
- * The subroutine is rather long. It steps through the states given in
- * Annex A of the Bulk-Only specification.
- * Each state first does the error handling of the previous transfer
- * and then prepares the next transfer.
- * Each transfer is done asynchronously so after the request/transfer
- * has been submitted you will find a 'return;'.
- */
-
- DPRINTF(UDMASS_BBB, ("%s: Handling BBB state %d (%s), xfer=%p, %s\n",
- device_get_nameunit(sc->sc_dev), sc->transfer_state,
- states[sc->transfer_state], xfer, usbd_errstr(err)));
-
- /* Give up if the device has detached. */
- if (sc->flags & UMASS_FLAGS_GONE) {
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv, sc->transfer_datalen,
- STATUS_CMD_FAILED);
- return;
- }
-
- switch (sc->transfer_state) {
-
- /***** Bulk Transfer *****/
- case TSTATE_BBB_COMMAND:
- /* Command transport phase, error handling */
- if (err) {
- DPRINTF(UDMASS_BBB, ("%s: failed to send CBW\n",
- device_get_nameunit(sc->sc_dev)));
- /* If the device detects that the CBW is invalid, then
- * the device may STALL both bulk endpoints and require
- * a Bulk-Reset
- */
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- }
-
- /* Data transport phase, setup transfer */
- sc->transfer_state = TSTATE_BBB_DATA;
- if (sc->transfer_dir == DIR_IN) {
- if (umass_setup_transfer(sc, sc->bulkin_pipe,
- sc->transfer_data, sc->transfer_datalen,
- USBD_SHORT_XFER_OK,
- sc->transfer_xfer[XFER_BBB_DATA]))
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
-
- return;
- } else if (sc->transfer_dir == DIR_OUT) {
- if (umass_setup_transfer(sc, sc->bulkout_pipe,
- sc->transfer_data, sc->transfer_datalen,
- 0, /* fixed length transfer */
- sc->transfer_xfer[XFER_BBB_DATA]))
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
-
- return;
- } else {
- DPRINTF(UDMASS_BBB, ("%s: no data phase\n",
- device_get_nameunit(sc->sc_dev)));
- }
-
- /* FALLTHROUGH if no data phase, err == 0 */
- case TSTATE_BBB_DATA:
- /* Command transport phase, error handling (ignored if no data
- * phase (fallthrough from previous state)) */
- if (sc->transfer_dir != DIR_NONE) {
- /* retrieve the length of the transfer that was done */
- usbd_get_xfer_status(xfer, NULL, NULL,
- &sc->transfer_actlen, NULL);
-
- if (err) {
- DPRINTF(UDMASS_BBB, ("%s: Data-%s %db failed, "
- "%s\n", device_get_nameunit(sc->sc_dev),
- (sc->transfer_dir == DIR_IN?"in":"out"),
- sc->transfer_datalen,usbd_errstr(err)));
-
- if (err == USBD_STALLED) {
- umass_clear_endpoint_stall(sc,
- (sc->transfer_dir == DIR_IN?
- sc->bulkin:sc->bulkout),
- (sc->transfer_dir == DIR_IN?
- sc->bulkin_pipe:sc->bulkout_pipe),
- TSTATE_BBB_DCLEAR,
- sc->transfer_xfer[XFER_BBB_DCLEAR]);
- return;
- } else {
- /* Unless the error is a pipe stall the
- * error is fatal.
- */
- umass_bbb_reset(sc,STATUS_WIRE_FAILED);
- return;
- }
- }
- }
-
- DIF(UDMASS_BBB, if (sc->transfer_dir == DIR_IN)
- umass_dump_buffer(sc, sc->transfer_data,
- sc->transfer_datalen, 48));
-
-
-
- /* FALLTHROUGH, err == 0 (no data phase or successfull) */
- case TSTATE_BBB_DCLEAR: /* stall clear after data phase */
- case TSTATE_BBB_SCLEAR: /* stall clear after status phase */
- /* Reading of CSW after bulk stall condition in data phase
- * (TSTATE_BBB_DATA2) or bulk-in stall condition after
- * reading CSW (TSTATE_BBB_SCLEAR).
- * In the case of no data phase or successfull data phase,
- * err == 0 and the following if block is passed.
- */
- if (err) { /* should not occur */
- /* try the transfer below, even if clear stall failed */
- DPRINTF(UDMASS_BBB, ("%s: bulk-%s stall clear failed"
- ", %s\n", device_get_nameunit(sc->sc_dev),
- (sc->transfer_dir == DIR_IN? "in":"out"),
- usbd_errstr(err)));
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- }
-
- /* Status transport phase, setup transfer */
- if (sc->transfer_state == TSTATE_BBB_COMMAND ||
- sc->transfer_state == TSTATE_BBB_DATA ||
- sc->transfer_state == TSTATE_BBB_DCLEAR) {
- /* After no data phase, successfull data phase and
- * after clearing bulk-in/-out stall condition
- */
- sc->transfer_state = TSTATE_BBB_STATUS1;
- next_xfer = sc->transfer_xfer[XFER_BBB_CSW1];
- } else {
- /* After first attempt of fetching CSW */
- sc->transfer_state = TSTATE_BBB_STATUS2;
- next_xfer = sc->transfer_xfer[XFER_BBB_CSW2];
- }
-
- /* Read the Command Status Wrapper via bulk-in endpoint. */
- if (umass_setup_transfer(sc, sc->bulkin_pipe,
- &sc->csw, UMASS_BBB_CSW_SIZE, 0,
- next_xfer)) {
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- }
-
- return;
- case TSTATE_BBB_STATUS1: /* first attempt */
- case TSTATE_BBB_STATUS2: /* second attempt */
- /* Status transfer, error handling */
- if (err) {
- DPRINTF(UDMASS_BBB, ("%s: Failed to read CSW, %s%s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err),
- (sc->transfer_state == TSTATE_BBB_STATUS1?
- ", retrying":"")));
-
- /* If this was the first attempt at fetching the CSW
- * retry it, otherwise fail.
- */
- if (sc->transfer_state == TSTATE_BBB_STATUS1) {
- umass_clear_endpoint_stall(sc,
- sc->bulkin, sc->bulkin_pipe,
- TSTATE_BBB_SCLEAR,
- sc->transfer_xfer[XFER_BBB_SCLEAR]);
- return;
- } else {
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- }
- }
-
- DIF(UDMASS_BBB, umass_bbb_dump_csw(sc, &sc->csw));
-
- /* Translate weird command-status signatures. */
- if (sc->quirks & WRONG_CSWSIG) {
- u_int32_t dCSWSignature = UGETDW(sc->csw.dCSWSignature);
- if (dCSWSignature == CSWSIGNATURE_OLYMPUS_C1 ||
- dCSWSignature == CSWSIGNATURE_IMAGINATION_DBX1)
- USETDW(sc->csw.dCSWSignature, CSWSIGNATURE);
- }
-
- int Residue;
- Residue = UGETDW(sc->csw.dCSWDataResidue);
- if (Residue == 0 &&
- sc->transfer_datalen - sc->transfer_actlen != 0)
- Residue = sc->transfer_datalen - sc->transfer_actlen;
-
- /* Check CSW and handle any error */
- if (UGETDW(sc->csw.dCSWSignature) != CSWSIGNATURE) {
- /* Invalid CSW: Wrong signature or wrong tag might
- * indicate that the device is confused -> reset it.
- */
- printf("%s: Invalid CSW: sig 0x%08x should be 0x%08x\n",
- device_get_nameunit(sc->sc_dev),
- UGETDW(sc->csw.dCSWSignature),
- CSWSIGNATURE);
-
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- } else if (UGETDW(sc->csw.dCSWTag)
- != UGETDW(sc->cbw.dCBWTag)) {
- printf("%s: Invalid CSW: tag %d should be %d\n",
- device_get_nameunit(sc->sc_dev),
- UGETDW(sc->csw.dCSWTag),
- UGETDW(sc->cbw.dCBWTag));
-
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
-
- /* CSW is valid here */
- } else if (sc->csw.bCSWStatus > CSWSTATUS_PHASE) {
- printf("%s: Invalid CSW: status %d > %d\n",
- device_get_nameunit(sc->sc_dev),
- sc->csw.bCSWStatus,
- CSWSTATUS_PHASE);
-
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- } else if (sc->csw.bCSWStatus == CSWSTATUS_PHASE) {
- printf("%s: Phase Error, residue = %d\n",
- device_get_nameunit(sc->sc_dev), Residue);
-
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
-
- } else if (sc->transfer_actlen > sc->transfer_datalen) {
- /* Buffer overrun! Don't let this go by unnoticed */
- panic("%s: transferred %db instead of %db",
- device_get_nameunit(sc->sc_dev),
- sc->transfer_actlen, sc->transfer_datalen);
-
- } else if (sc->csw.bCSWStatus == CSWSTATUS_FAILED) {
- DPRINTF(UDMASS_BBB, ("%s: Command Failed, res = %d\n",
- device_get_nameunit(sc->sc_dev), Residue));
-
- /* SCSI command failed but transfer was succesful */
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv, Residue,
- STATUS_CMD_FAILED);
- return;
-
- } else { /* success */
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv, Residue,
- STATUS_CMD_OK);
-
- return;
- }
-
- /***** Bulk Reset *****/
- case TSTATE_BBB_RESET1:
- if (err)
- printf("%s: BBB reset failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
-
- umass_clear_endpoint_stall(sc,
- sc->bulkin, sc->bulkin_pipe, TSTATE_BBB_RESET2,
- sc->transfer_xfer[XFER_BBB_RESET2]);
-
- return;
- case TSTATE_BBB_RESET2:
- if (err) /* should not occur */
- printf("%s: BBB bulk-in clear stall failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- /* no error recovery, otherwise we end up in a loop */
-
- umass_clear_endpoint_stall(sc,
- sc->bulkout, sc->bulkout_pipe, TSTATE_BBB_RESET3,
- sc->transfer_xfer[XFER_BBB_RESET3]);
-
- return;
- case TSTATE_BBB_RESET3:
- if (err) /* should not occur */
- printf("%s: BBB bulk-out clear stall failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- /* no error recovery, otherwise we end up in a loop */
-
- sc->transfer_state = TSTATE_IDLE;
- if (sc->transfer_priv) {
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen,
- sc->transfer_status);
- }
-
- return;
-
- /***** Default *****/
- default:
- panic("%s: Unknown state %d",
- device_get_nameunit(sc->sc_dev), sc->transfer_state);
- }
-}
-
-static int
-umass_bbb_get_max_lun(struct umass_softc *sc)
-{
- usbd_device_handle udev;
- usb_device_request_t req;
- usbd_status err;
- usb_interface_descriptor_t *id;
- int maxlun = 0;
- u_int8_t buf = 0;
-
- usbd_interface2device_handle(sc->iface, &udev);
- id = usbd_get_interface_descriptor(sc->iface);
-
- /* The Get Max Lun command is a class-specific request. */
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_BBB_GET_MAX_LUN;
- USETW(req.wValue, 0);
- USETW(req.wIndex, id->bInterfaceNumber);
- USETW(req.wLength, 1);
-
- err = usbd_do_request(udev, &req, &buf);
- switch (err) {
- case USBD_NORMAL_COMPLETION:
- maxlun = buf;
- DPRINTF(UDMASS_BBB, ("%s: Max Lun is %d\n",
- device_get_nameunit(sc->sc_dev), maxlun));
- break;
- case USBD_STALLED:
- case USBD_SHORT_XFER:
- default:
- /* Device doesn't support Get Max Lun request. */
- printf("%s: Get Max Lun not supported (%s)\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- /* XXX Should we port_reset the device? */
- break;
- }
-
- return(maxlun);
-}
-
-/*
- * Command/Bulk/Interrupt (CBI) specific functions
- */
-
-static int
-umass_cbi_adsc(struct umass_softc *sc, char *buffer, int buflen,
- usbd_xfer_handle xfer)
-{
- usbd_device_handle udev;
-
- KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
- ("%s: umass_cbi_adsc: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- usbd_interface2device_handle(sc->iface, &udev);
-
- sc->request.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- sc->request.bRequest = UR_CBI_ADSC;
- USETW(sc->request.wValue, 0);
- USETW(sc->request.wIndex, sc->ifaceno);
- USETW(sc->request.wLength, buflen);
- return umass_setup_ctrl_transfer(sc, udev, &sc->request, buffer,
- buflen, 0, xfer);
-}
-
-
-static void
-umass_cbi_reset(struct umass_softc *sc, int status)
-{
- int i;
-# define SEND_DIAGNOSTIC_CMDLEN 12
-
- KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
- ("%s: umass_cbi_reset: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /*
- * Command Block Reset Protocol
- *
- * First send a reset request to the device. Then clear
- * any possibly stalled bulk endpoints.
- *
- * This is done in 3 steps, states:
- * TSTATE_CBI_RESET1
- * TSTATE_CBI_RESET2
- * TSTATE_CBI_RESET3
- *
- * If the reset doesn't succeed, the device should be port reset.
- */
-
- DPRINTF(UDMASS_CBI, ("%s: CBI Reset\n",
- device_get_nameunit(sc->sc_dev)));
-
- KASSERT(sizeof(sc->cbl) >= SEND_DIAGNOSTIC_CMDLEN,
- ("%s: CBL struct is too small (%ld < %d)\n",
- device_get_nameunit(sc->sc_dev),
- (long)sizeof(sc->cbl), SEND_DIAGNOSTIC_CMDLEN));
-
- sc->transfer_state = TSTATE_CBI_RESET1;
- sc->transfer_status = status;
-
- /* The 0x1d code is the SEND DIAGNOSTIC command. To distinguish between
- * the two the last 10 bytes of the cbl is filled with 0xff (section
- * 2.2 of the CBI spec).
- */
- sc->cbl[0] = 0x1d; /* Command Block Reset */
- sc->cbl[1] = 0x04;
- for (i = 2; i < SEND_DIAGNOSTIC_CMDLEN; i++)
- sc->cbl[i] = 0xff;
-
- umass_cbi_adsc(sc, sc->cbl, SEND_DIAGNOSTIC_CMDLEN,
- sc->transfer_xfer[XFER_CBI_RESET1]);
- /* XXX if the command fails we should reset the port on the hub */
-}
-
-static void
-umass_cbi_transfer(struct umass_softc *sc, int lun,
- void *cmd, int cmdlen, void *data, int datalen, int dir,
- u_int timeout, transfer_cb_f cb, void *priv)
-{
- KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
- ("%s: umass_cbi_transfer: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /* Be a little generous. */
- sc->timeout = timeout + UMASS_TIMEOUT;
-
- /*
- * Do a CBI transfer with cmdlen bytes from cmd, possibly
- * a data phase of datalen bytes from/to the device and finally a
- * csw read phase.
- * If the data direction was inbound a maximum of datalen bytes
- * is stored in the buffer pointed to by data.
- *
- * umass_cbi_transfer initialises the transfer and lets the state
- * machine in umass_cbi_state handle the completion. It uses the
- * following states:
- * TSTATE_CBI_COMMAND
- * -> XXX fill in
- *
- * An error in any of those states will invoke
- * umass_cbi_reset.
- */
-
- /* check the given arguments */
- KASSERT(datalen == 0 || data != NULL,
- ("%s: datalen > 0, but no buffer",device_get_nameunit(sc->sc_dev)));
- KASSERT(datalen == 0 || dir != DIR_NONE,
- ("%s: direction is NONE while datalen is not zero\n",
- device_get_nameunit(sc->sc_dev)));
-
- /* store the details for the data transfer phase */
- sc->transfer_dir = dir;
- sc->transfer_data = data;
- sc->transfer_datalen = datalen;
- sc->transfer_actlen = 0;
- sc->transfer_cb = cb;
- sc->transfer_priv = priv;
- sc->transfer_status = STATUS_CMD_OK;
-
- /* move from idle to the command state */
- sc->transfer_state = TSTATE_CBI_COMMAND;
-
- DIF(UDMASS_CBI, umass_cbi_dump_cmd(sc, cmd, cmdlen));
-
- /* Send the Command Block from host to device via control endpoint. */
- if (umass_cbi_adsc(sc, cmd, cmdlen, sc->transfer_xfer[XFER_CBI_CB]))
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
-}
-
-static void
-umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status err)
-{
- struct umass_softc *sc = (struct umass_softc *) priv;
-
- KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
- ("%s: umass_cbi_state: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /*
- * State handling for CBI transfers.
- */
-
- DPRINTF(UDMASS_CBI, ("%s: Handling CBI state %d (%s), xfer=%p, %s\n",
- device_get_nameunit(sc->sc_dev), sc->transfer_state,
- states[sc->transfer_state], xfer, usbd_errstr(err)));
-
- /* Give up if the device has detached. */
- if (sc->flags & UMASS_FLAGS_GONE) {
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv, sc->transfer_datalen,
- STATUS_CMD_FAILED);
- return;
- }
-
- switch (sc->transfer_state) {
-
- /***** CBI Transfer *****/
- case TSTATE_CBI_COMMAND:
- if (err == USBD_STALLED) {
- DPRINTF(UDMASS_CBI, ("%s: Command Transport failed\n",
- device_get_nameunit(sc->sc_dev)));
- /* Status transport by control pipe (section 2.3.2.1).
- * The command contained in the command block failed.
- *
- * The control pipe has already been unstalled by the
- * USB stack.
- * Section 2.4.3.1.1 states that the bulk in endpoints
- * should not be stalled at this point.
- */
-
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen,
- STATUS_CMD_FAILED);
-
- return;
- } else if (err) {
- DPRINTF(UDMASS_CBI, ("%s: failed to send ADSC\n",
- device_get_nameunit(sc->sc_dev)));
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
-
- return;
- }
-
- sc->transfer_state = TSTATE_CBI_DATA;
- if (sc->transfer_dir == DIR_IN) {
- if (umass_setup_transfer(sc, sc->bulkin_pipe,
- sc->transfer_data, sc->transfer_datalen,
- USBD_SHORT_XFER_OK,
- sc->transfer_xfer[XFER_CBI_DATA]))
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
-
- } else if (sc->transfer_dir == DIR_OUT) {
- if (umass_setup_transfer(sc, sc->bulkout_pipe,
- sc->transfer_data, sc->transfer_datalen,
- 0, /* fixed length transfer */
- sc->transfer_xfer[XFER_CBI_DATA]))
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
-
- } else if (sc->proto & UMASS_PROTO_CBI_I) {
- DPRINTF(UDMASS_CBI, ("%s: no data phase\n",
- device_get_nameunit(sc->sc_dev)));
- sc->transfer_state = TSTATE_CBI_STATUS;
- if (umass_setup_transfer(sc, sc->intrin_pipe,
- &sc->sbl, sizeof(sc->sbl),
- 0, /* fixed length transfer */
- sc->transfer_xfer[XFER_CBI_STATUS])){
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
- }
- } else {
- DPRINTF(UDMASS_CBI, ("%s: no data phase\n",
- device_get_nameunit(sc->sc_dev)));
- /* No command completion interrupt. Request
- * sense data.
- */
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- 0, STATUS_CMD_UNKNOWN);
- }
-
- return;
-
- case TSTATE_CBI_DATA:
- /* retrieve the length of the transfer that was done */
- usbd_get_xfer_status(xfer,NULL,NULL,&sc->transfer_actlen,NULL);
-
- if (err) {
- DPRINTF(UDMASS_CBI, ("%s: Data-%s %db failed, "
- "%s\n", device_get_nameunit(sc->sc_dev),
- (sc->transfer_dir == DIR_IN?"in":"out"),
- sc->transfer_datalen,usbd_errstr(err)));
-
- if (err == USBD_STALLED) {
- umass_clear_endpoint_stall(sc,
- sc->bulkin, sc->bulkin_pipe,
- TSTATE_CBI_DCLEAR,
- sc->transfer_xfer[XFER_CBI_DCLEAR]);
- } else {
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
- }
- return;
- }
-
- DIF(UDMASS_CBI, if (sc->transfer_dir == DIR_IN)
- umass_dump_buffer(sc, sc->transfer_data,
- sc->transfer_actlen, 48));
-
- if (sc->proto & UMASS_PROTO_CBI_I) {
- sc->transfer_state = TSTATE_CBI_STATUS;
- if (umass_setup_transfer(sc, sc->intrin_pipe,
- &sc->sbl, sizeof(sc->sbl),
- 0, /* fixed length transfer */
- sc->transfer_xfer[XFER_CBI_STATUS])){
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
- }
- } else {
- /* No command completion interrupt. Request
- * sense to get status of command.
- */
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen - sc->transfer_actlen,
- STATUS_CMD_UNKNOWN);
- }
- return;
-
- case TSTATE_CBI_STATUS:
- if (err) {
- DPRINTF(UDMASS_CBI, ("%s: Status Transport failed\n",
- device_get_nameunit(sc->sc_dev)));
- /* Status transport by interrupt pipe (section 2.3.2.2).
- */
-
- if (err == USBD_STALLED) {
- umass_clear_endpoint_stall(sc,
- sc->intrin, sc->intrin_pipe,
- TSTATE_CBI_SCLEAR,
- sc->transfer_xfer[XFER_CBI_SCLEAR]);
- } else {
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
- }
- return;
- }
-
- /* Dissect the information in the buffer */
-
- if (sc->proto & UMASS_PROTO_UFI) {
- int status;
-
- /* Section 3.4.3.1.3 specifies that the UFI command
- * protocol returns an ASC and ASCQ in the interrupt
- * data block.
- */
-
- DPRINTF(UDMASS_CBI, ("%s: UFI CCI, ASC = 0x%02x, "
- "ASCQ = 0x%02x\n",
- device_get_nameunit(sc->sc_dev),
- sc->sbl.ufi.asc, sc->sbl.ufi.ascq));
-
- if (sc->sbl.ufi.asc == 0 && sc->sbl.ufi.ascq == 0)
- status = STATUS_CMD_OK;
- else
- status = STATUS_CMD_FAILED;
-
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen - sc->transfer_actlen,
- status);
- } else {
- /* Command Interrupt Data Block */
- DPRINTF(UDMASS_CBI, ("%s: type=0x%02x, value=0x%02x\n",
- device_get_nameunit(sc->sc_dev),
- sc->sbl.common.type, sc->sbl.common.value));
-
- if (sc->sbl.common.type == IDB_TYPE_CCI) {
- int err;
-
- if ((sc->sbl.common.value&IDB_VALUE_STATUS_MASK)
- == IDB_VALUE_PASS) {
- err = STATUS_CMD_OK;
- } else if ((sc->sbl.common.value & IDB_VALUE_STATUS_MASK)
- == IDB_VALUE_FAIL ||
- (sc->sbl.common.value & IDB_VALUE_STATUS_MASK)
- == IDB_VALUE_PERSISTENT) {
- err = STATUS_CMD_FAILED;
- } else {
- err = STATUS_WIRE_FAILED;
- }
-
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen-sc->transfer_actlen,
- err);
- }
- }
- return;
-
- case TSTATE_CBI_DCLEAR:
- if (err) { /* should not occur */
- printf("%s: CBI bulk-in/out stall clear failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
- }
-
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen,
- STATUS_CMD_FAILED);
- return;
-
- case TSTATE_CBI_SCLEAR:
- if (err) /* should not occur */
- printf("%s: CBI intr-in stall clear failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
-
- /* Something really bad is going on. Reset the device */
- umass_cbi_reset(sc, STATUS_CMD_FAILED);
- return;
-
- /***** CBI Reset *****/
- case TSTATE_CBI_RESET1:
- if (err)
- printf("%s: CBI reset failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
-
- umass_clear_endpoint_stall(sc,
- sc->bulkin, sc->bulkin_pipe, TSTATE_CBI_RESET2,
- sc->transfer_xfer[XFER_CBI_RESET2]);
-
- return;
- case TSTATE_CBI_RESET2:
- if (err) /* should not occur */
- printf("%s: CBI bulk-in stall clear failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- /* no error recovery, otherwise we end up in a loop */
-
- umass_clear_endpoint_stall(sc,
- sc->bulkout, sc->bulkout_pipe, TSTATE_CBI_RESET3,
- sc->transfer_xfer[XFER_CBI_RESET3]);
-
- return;
- case TSTATE_CBI_RESET3:
- if (err) /* should not occur */
- printf("%s: CBI bulk-out stall clear failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- /* no error recovery, otherwise we end up in a loop */
-
- sc->transfer_state = TSTATE_IDLE;
- if (sc->transfer_priv) {
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen,
- sc->transfer_status);
- }
-
- return;
-
-
- /***** Default *****/
- default:
- panic("%s: Unknown state %d",
- device_get_nameunit(sc->sc_dev), sc->transfer_state);
- }
-}
-
-
-
-
-/*
- * CAM specific functions (used by SCSI, UFI, 8070i (ATAPI))
- */
-
-static int
-umass_cam_attach_sim(struct umass_softc *sc)
-{
- struct cam_devq *devq; /* Per device Queue */
-
- /* A HBA is attached to the CAM layer.
- *
- * The CAM layer will then after a while start probing for
- * devices on the bus. The number of SIMs is limited to one.
- */
-
- devq = cam_simq_alloc(1 /*maximum openings*/);
- if (devq == NULL)
- return(ENOMEM);
-
- sc->umass_sim = cam_sim_alloc(umass_cam_action, umass_cam_poll,
- DEVNAME_SIM,
- sc /*priv*/,
- device_get_unit(sc->sc_dev) /*unit number*/,
- &Giant,
- 1 /*maximum device openings*/,
- 0 /*maximum tagged device openings*/,
- devq);
- if (sc->umass_sim == NULL) {
- cam_simq_free(devq);
- return(ENOMEM);
- }
-
- if(xpt_bus_register(sc->umass_sim, NULL, device_get_unit(sc->sc_dev)) !=
- CAM_SUCCESS)
- return(ENOMEM);
-
- return(0);
-}
-
-static void
-umass_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
-{
-#ifdef USB_DEBUG
- if (ccb->ccb_h.status != CAM_REQ_CMP) {
- DPRINTF(UDMASS_SCSI, ("%s:%d Rescan failed, 0x%04x\n",
- periph->periph_name, periph->unit_number,
- ccb->ccb_h.status));
- } else {
- DPRINTF(UDMASS_SCSI, ("%s%d: Rescan succeeded\n",
- periph->periph_name, periph->unit_number));
- }
-#endif
-
- xpt_free_path(ccb->ccb_h.path);
- free(ccb, M_USBDEV);
-}
-
-static void
-umass_cam_rescan(void *addr)
-{
- struct umass_softc *sc = (struct umass_softc *) addr;
- struct cam_path *path;
- union ccb *ccb;
-
- DPRINTF(UDMASS_SCSI, ("scbus%d: scanning for %s:%d:%d:%d\n",
- cam_sim_path(sc->umass_sim),
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- device_get_unit(sc->sc_dev), CAM_LUN_WILDCARD));
-
- ccb = malloc(sizeof(union ccb), M_USBDEV, M_NOWAIT | M_ZERO);
- if (ccb == NULL)
- return;
- if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->umass_sim),
- device_get_unit(sc->sc_dev), CAM_LUN_WILDCARD)
- != CAM_REQ_CMP) {
- free(ccb, M_USBDEV);
- return;
- }
-
- xpt_setup_ccb(&ccb->ccb_h, path, 5/*priority (low)*/);
- ccb->ccb_h.func_code = XPT_SCAN_BUS;
- ccb->ccb_h.cbfcnp = umass_cam_rescan_callback;
- ccb->crcn.flags = CAM_FLAG_NONE;
- xpt_action(ccb);
-
- /* The scan is in progress now. */
-}
-
-static int
-umass_cam_attach(struct umass_softc *sc)
-{
-#ifndef USB_DEBUG
- if (bootverbose)
-#endif
- printf("%s:%d:%d:%d: Attached to scbus%d\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- device_get_unit(sc->sc_dev), CAM_LUN_WILDCARD,
- cam_sim_path(sc->umass_sim));
-
- if (!cold) {
- /* Notify CAM of the new device after a short delay. Any
- * failure is benign, as the user can still do it by hand
- * (camcontrol rescan <busno>). Only do this if we are not
- * booting, because CAM does a scan after booting has
- * completed, when interrupts have been enabled.
- */
-
- callout_reset(&sc->cam_scsi_rescan_ch, MS_TO_TICKS(200),
- umass_cam_rescan, sc);
- }
-
- return(0); /* always succesfull */
-}
-
-/* umass_cam_detach
- * detach from the CAM layer
- */
-
-static int
-umass_cam_detach_sim(struct umass_softc *sc)
-{
- if (sc->umass_sim) {
- if (xpt_bus_deregister(cam_sim_path(sc->umass_sim)))
- cam_sim_free(sc->umass_sim, /*free_devq*/TRUE);
- else
- return(EBUSY);
-
- sc->umass_sim = NULL;
- }
-
- return(0);
-}
-
-/* umass_cam_action
- * CAM requests for action come through here
- */
-
-static void
-umass_cam_action(struct cam_sim *sim, union ccb *ccb)
-{
- struct umass_softc *sc = (struct umass_softc *)sim->softc;
-
- /* The softc is still there, but marked as going away. umass_cam_detach
- * has not yet notified CAM of the lost device however.
- */
- if (sc && (sc->flags & UMASS_FLAGS_GONE)) {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
- "Invalid target (gone)\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- ccb->ccb_h.func_code));
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
-
- /* Verify, depending on the operation to perform, that we either got a
- * valid sc, because an existing target was referenced, or otherwise
- * the SIM is addressed.
- *
- * This avoids bombing out at a printf and does give the CAM layer some
- * sensible feedback on errors.
- */
- switch (ccb->ccb_h.func_code) {
- case XPT_SCSI_IO:
- case XPT_RESET_DEV:
- case XPT_GET_TRAN_SETTINGS:
- case XPT_SET_TRAN_SETTINGS:
- case XPT_CALC_GEOMETRY:
- /* the opcodes requiring a target. These should never occur. */
- if (sc == NULL) {
- printf("%s:%d:%d:%d:func_code 0x%04x: "
- "Invalid target (target needed)\n",
- DEVNAME_SIM, cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- ccb->ccb_h.func_code);
-
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
- break;
- case XPT_PATH_INQ:
- case XPT_NOOP:
- /* The opcodes sometimes aimed at a target (sc is valid),
- * sometimes aimed at the SIM (sc is invalid and target is
- * CAM_TARGET_WILDCARD)
- */
- if (sc == NULL && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
- "Invalid target (no wildcard)\n",
- DEVNAME_SIM, cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- ccb->ccb_h.func_code));
-
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
- break;
- default:
- /* XXX Hm, we should check the input parameters */
- break;
- }
-
- /* Perform the requested action */
- switch (ccb->ccb_h.func_code) {
- case XPT_SCSI_IO:
- {
- struct ccb_scsiio *csio = &ccb->csio; /* deref union */
- int dir;
- unsigned char *cmd;
- int cmdlen;
- unsigned char *rcmd;
- int rcmdlen;
-
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SCSI_IO: "
- "cmd: 0x%02x, flags: 0x%02x, "
- "%db cmd/%db data/%db sense\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- csio->cdb_io.cdb_bytes[0],
- ccb->ccb_h.flags & CAM_DIR_MASK,
- csio->cdb_len, csio->dxfer_len,
- csio->sense_len));
-
- /* clear the end of the buffer to make sure we don't send out
- * garbage.
- */
- DIF(UDMASS_SCSI, if ((ccb->ccb_h.flags & CAM_DIR_MASK)
- == CAM_DIR_OUT)
- umass_dump_buffer(sc, csio->data_ptr,
- csio->dxfer_len, 48));
-
- if (sc->transfer_state != TSTATE_IDLE) {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SCSI_IO: "
- "I/O in progress, deferring (state %d, %s)\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- sc->transfer_state,states[sc->transfer_state]));
- ccb->ccb_h.status = CAM_SCSI_BUSY;
- xpt_done(ccb);
- return;
- }
-
- switch(ccb->ccb_h.flags&CAM_DIR_MASK) {
- case CAM_DIR_IN:
- dir = DIR_IN;
- break;
- case CAM_DIR_OUT:
- dir = DIR_OUT;
- break;
- default:
- dir = DIR_NONE;
- }
-
- ccb->ccb_h.status = CAM_REQ_INPROG | CAM_SIM_QUEUED;
-
-
- if (csio->ccb_h.flags & CAM_CDB_POINTER) {
- cmd = (unsigned char *) csio->cdb_io.cdb_ptr;
- } else {
- cmd = (unsigned char *) &csio->cdb_io.cdb_bytes;
- }
- cmdlen = csio->cdb_len;
- rcmd = (unsigned char *) &sc->cam_scsi_command;
- rcmdlen = sizeof(sc->cam_scsi_command);
-
- /* sc->transform will convert the command to the command
- * (format) needed by the specific command set and return
- * the converted command in a buffer pointed to be rcmd.
- * We pass in a buffer, but if the command does not
- * have to be transformed it returns a ptr to the original
- * buffer (see umass_scsi_transform).
- */
-
- switch (sc->transform(sc, cmd, cmdlen, &rcmd, &rcmdlen)) {
- case 1:
- /*
- * Handle EVPD inquiry for broken devices first
- * NO_INQUIRY also implies NO_INQUIRY_EVPD
- */
- if ((sc->quirks & (NO_INQUIRY_EVPD | NO_INQUIRY)) &&
- rcmd[0] == INQUIRY && (rcmd[1] & SI_EVPD)) {
- struct scsi_sense_data *sense;
-
- sense = &ccb->csio.sense_data;
- bzero(sense, sizeof(*sense));
- sense->error_code = SSD_CURRENT_ERROR;
- sense->flags = SSD_KEY_ILLEGAL_REQUEST;
- sense->add_sense_code = 0x24;
- sense->extra_len = 10;
- ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR |
- CAM_AUTOSNS_VALID;
- xpt_done(ccb);
- return;
- }
- /* Return fake inquiry data for broken devices */
- if ((sc->quirks & NO_INQUIRY) && rcmd[0] == INQUIRY) {
- struct ccb_scsiio *csio = &ccb->csio;
-
- memcpy(csio->data_ptr, &fake_inq_data,
- sizeof(fake_inq_data));
- csio->scsi_status = SCSI_STATUS_OK;
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- return;
- }
- if ((sc->quirks & NO_SYNCHRONIZE_CACHE) &&
- rcmd[0] == SYNCHRONIZE_CACHE) {
- struct ccb_scsiio *csio = &ccb->csio;
-
- csio->scsi_status = SCSI_STATUS_OK;
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- return;
- }
- if ((sc->quirks & FORCE_SHORT_INQUIRY) &&
- rcmd[0] == INQUIRY) {
- csio->dxfer_len = SHORT_INQUIRY_LENGTH;
- }
- sc->transfer(sc, ccb->ccb_h.target_lun, rcmd, rcmdlen,
- csio->data_ptr,
- csio->dxfer_len, dir, ccb->ccb_h.timeout,
- umass_cam_cb, (void *) ccb);
- break;
- case 0:
- ccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(ccb);
- break;
- case 2:
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
-
- break;
- }
- case XPT_PATH_INQ:
- {
- struct ccb_pathinq *cpi = &ccb->cpi;
-
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_PATH_INQ:.\n",
- (sc == NULL? DEVNAME_SIM:device_get_nameunit(sc->sc_dev)),
- cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
-
- /* host specific information */
- cpi->version_num = 1;
- cpi->hba_inquiry = 0;
- cpi->target_sprt = 0;
- cpi->hba_misc = PIM_NO_6_BYTE;
- cpi->hba_eng_cnt = 0;
- cpi->max_target = UMASS_SCSIID_MAX; /* one target */
- cpi->initiator_id = UMASS_SCSIID_HOST;
- strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
- strncpy(cpi->hba_vid, "USB SCSI", HBA_IDLEN);
- strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
- cpi->unit_number = cam_sim_unit(sim);
- cpi->bus_id = device_get_unit(sc->sc_dev);
- cpi->protocol = PROTO_SCSI;
- cpi->protocol_version = SCSI_REV_2;
- cpi->transport = XPORT_USB;
- cpi->transport_version = 0;
-
- if (sc == NULL) {
- cpi->base_transfer_speed = 0;
- cpi->max_lun = 0;
- } else {
- if (sc->quirks & FLOPPY_SPEED) {
- cpi->base_transfer_speed =
- UMASS_FLOPPY_TRANSFER_SPEED;
- } else if (usbd_get_speed(sc->sc_udev) ==
- USB_SPEED_HIGH) {
- cpi->base_transfer_speed =
- UMASS_HIGH_TRANSFER_SPEED;
- } else {
- cpi->base_transfer_speed =
- UMASS_FULL_TRANSFER_SPEED;
- }
- cpi->max_lun = sc->maxlun;
- }
-
- cpi->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
- case XPT_RESET_DEV:
- {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_RESET_DEV:.\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
-
- ccb->ccb_h.status = CAM_REQ_INPROG;
- umass_reset(sc, umass_cam_cb, (void *) ccb);
- break;
- }
- case XPT_GET_TRAN_SETTINGS:
- {
- struct ccb_trans_settings *cts = &ccb->cts;
- cts->protocol = PROTO_SCSI;
- cts->protocol_version = SCSI_REV_2;
- cts->transport = XPORT_USB;
- cts->transport_version = 0;
- cts->xport_specific.valid = 0;
-
-
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
- case XPT_SET_TRAN_SETTINGS:
- {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SET_TRAN_SETTINGS:.\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
-
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- xpt_done(ccb);
- break;
- }
- case XPT_CALC_GEOMETRY:
- {
- cam_calc_geometry(&ccb->ccg, /*extended*/1);
- xpt_done(ccb);
- break;
- }
- case XPT_NOOP:
- {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_NOOP:.\n",
- (sc == NULL? DEVNAME_SIM:device_get_nameunit(sc->sc_dev)),
- cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
-
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
- default:
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
- "Not implemented\n",
- (sc == NULL? DEVNAME_SIM:device_get_nameunit(sc->sc_dev)),
- cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- ccb->ccb_h.func_code));
-
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- xpt_done(ccb);
- break;
- }
-}
-
-static void
-umass_cam_poll(struct cam_sim *sim)
-{
- struct umass_softc *sc = (struct umass_softc *) sim->softc;
-
- DPRINTF(UDMASS_SCSI, ("%s: CAM poll\n",
- device_get_nameunit(sc->sc_dev)));
-
- usbd_set_polling(sc->sc_udev, 1);
- usbd_dopoll(sc->iface);
- usbd_set_polling(sc->sc_udev, 0);
-}
-
-
-/* umass_cam_cb
- * finalise a completed CAM command
- */
-
-static void
-umass_cam_cb(struct umass_softc *sc, void *priv, int residue, int status)
-{
- union ccb *ccb = (union ccb *) priv;
- struct ccb_scsiio *csio = &ccb->csio; /* deref union */
-
- /* If the device is gone, just fail the request. */
- if (sc->flags & UMASS_FLAGS_GONE) {
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
-
- csio->resid = residue;
-
- switch (status) {
- case STATUS_CMD_OK:
- ccb->ccb_h.status = CAM_REQ_CMP;
- if ((sc->quirks & READ_CAPACITY_OFFBY1) &&
- (ccb->ccb_h.func_code == XPT_SCSI_IO) &&
- (csio->cdb_io.cdb_bytes[0] == READ_CAPACITY)) {
- struct scsi_read_capacity_data *rcap;
- uint32_t maxsector;
-
- rcap = (struct scsi_read_capacity_data *)csio->data_ptr;
- maxsector = scsi_4btoul(rcap->addr) - 1;
- scsi_ulto4b(maxsector, rcap->addr);
- }
- xpt_done(ccb);
- break;
-
- case STATUS_CMD_UNKNOWN:
- case STATUS_CMD_FAILED:
- switch (ccb->ccb_h.func_code) {
- case XPT_SCSI_IO:
- {
- unsigned char *rcmd;
- int rcmdlen;
-
- /* fetch sense data */
- /* the rest of the command was filled in at attach */
- sc->cam_scsi_sense.length = csio->sense_len;
-
- DPRINTF(UDMASS_SCSI,("%s: Fetching %db sense data\n",
- device_get_nameunit(sc->sc_dev), csio->sense_len));
-
- rcmd = (unsigned char *) &sc->cam_scsi_command;
- rcmdlen = sizeof(sc->cam_scsi_command);
-
- if (sc->transform(sc,
- (unsigned char *) &sc->cam_scsi_sense,
- sizeof(sc->cam_scsi_sense),
- &rcmd, &rcmdlen) == 1) {
- if ((sc->quirks & FORCE_SHORT_INQUIRY) && (rcmd[0] == INQUIRY)) {
- csio->sense_len = SHORT_INQUIRY_LENGTH;
- }
- sc->transfer(sc, ccb->ccb_h.target_lun,
- rcmd, rcmdlen,
- &csio->sense_data,
- csio->sense_len, DIR_IN, ccb->ccb_h.timeout,
- umass_cam_sense_cb, (void *) ccb);
- } else {
- panic("transform(REQUEST_SENSE) failed");
- }
- break;
- }
- case XPT_RESET_DEV: /* Reset failed */
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
- xpt_done(ccb);
- break;
- default:
- panic("umass_cam_cb called for func_code %d",
- ccb->ccb_h.func_code);
- }
- break;
-
- case STATUS_WIRE_FAILED:
- /* the wire protocol failed and will have recovered
- * (hopefully). We return an error to CAM and let CAM retry
- * the command if necessary.
- */
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
- xpt_done(ccb);
- break;
- default:
- panic("%s: Unknown status %d in umass_cam_cb",
- device_get_nameunit(sc->sc_dev), status);
- }
-}
-
-/* Finalise a completed autosense operation
- */
-static void
-umass_cam_sense_cb(struct umass_softc *sc, void *priv, int residue, int status)
-{
- union ccb *ccb = (union ccb *) priv;
- struct ccb_scsiio *csio = &ccb->csio; /* deref union */
- unsigned char *rcmd;
- int rcmdlen;
-
- if (sc->flags & UMASS_FLAGS_GONE) {
- ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
- xpt_done(ccb);
- return;
- }
-
- switch (status) {
- case STATUS_CMD_OK:
- case STATUS_CMD_UNKNOWN:
- case STATUS_CMD_FAILED:
- /* Getting sense data always succeeds (apart from wire
- * failures).
- */
- if ((sc->quirks & RS_NO_CLEAR_UA)
- && csio->cdb_io.cdb_bytes[0] == INQUIRY
- && (csio->sense_data.flags & SSD_KEY)
- == SSD_KEY_UNIT_ATTENTION) {
- /* Ignore unit attention errors in the case where
- * the Unit Attention state is not cleared on
- * REQUEST SENSE. They will appear again at the next
- * command.
- */
- ccb->ccb_h.status = CAM_REQ_CMP;
- } else if ((csio->sense_data.flags & SSD_KEY)
- == SSD_KEY_NO_SENSE) {
- /* No problem after all (in the case of CBI without
- * CCI)
- */
- ccb->ccb_h.status = CAM_REQ_CMP;
- } else if ((sc->quirks & RS_NO_CLEAR_UA) &&
- (csio->cdb_io.cdb_bytes[0] == READ_CAPACITY) &&
- ((csio->sense_data.flags & SSD_KEY)
- == SSD_KEY_UNIT_ATTENTION)) {
- /*
- * Some devices do not clear the unit attention error
- * on request sense. We insert a test unit ready
- * command to make sure we clear the unit attention
- * condition, then allow the retry to proceed as
- * usual.
- */
-
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
- | CAM_AUTOSNS_VALID;
- csio->scsi_status = SCSI_STATUS_CHECK_COND;
-
-#if 0
- DELAY(300000);
-#endif
-
- DPRINTF(UDMASS_SCSI,("%s: Doing a sneaky"
- "TEST_UNIT_READY\n",
- device_get_nameunit(sc->sc_dev)));
-
- /* the rest of the command was filled in at attach */
-
- rcmd = (unsigned char *) &sc->cam_scsi_command2;
- rcmdlen = sizeof(sc->cam_scsi_command2);
-
- if (sc->transform(sc,
- (unsigned char *)
- &sc->cam_scsi_test_unit_ready,
- sizeof(sc->cam_scsi_test_unit_ready),
- &rcmd, &rcmdlen) == 1) {
- sc->transfer(sc, ccb->ccb_h.target_lun,
- rcmd, rcmdlen,
- NULL, 0, DIR_NONE, ccb->ccb_h.timeout,
- umass_cam_quirk_cb, (void *) ccb);
- } else {
- panic("transform(TEST_UNIT_READY) failed");
- }
- break;
- } else {
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
- | CAM_AUTOSNS_VALID;
- csio->scsi_status = SCSI_STATUS_CHECK_COND;
- }
- xpt_done(ccb);
- break;
-
- default:
- DPRINTF(UDMASS_SCSI, ("%s: Autosense failed, status %d\n",
- device_get_nameunit(sc->sc_dev), status));
- ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
- xpt_done(ccb);
- }
-}
-
-/*
- * This completion code just handles the fact that we sent a test-unit-ready
- * after having previously failed a READ CAPACITY with CHECK_COND. Even
- * though this command succeeded, we have to tell CAM to retry.
- */
-static void
-umass_cam_quirk_cb(struct umass_softc *sc, void *priv, int residue, int status)
-{
- union ccb *ccb = (union ccb *) priv;
-
- DPRINTF(UDMASS_SCSI, ("%s: Test unit ready returned status %d\n",
- device_get_nameunit(sc->sc_dev), status));
-
- if (sc->flags & UMASS_FLAGS_GONE) {
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
-#if 0
- ccb->ccb_h.status = CAM_REQ_CMP;
-#endif
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
- | CAM_AUTOSNS_VALID;
- ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
- xpt_done(ccb);
-}
-
-/*
- * SCSI specific functions
- */
-
-static int
-umass_scsi_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen)
-{
- switch (cmd[0]) {
- case TEST_UNIT_READY:
- if (sc->quirks & NO_TEST_UNIT_READY) {
- KASSERT(*rcmdlen >= sizeof(struct scsi_start_stop_unit),
- ("rcmdlen = %d < %ld, buffer too small",
- *rcmdlen,
- (long)sizeof(struct scsi_start_stop_unit)));
- DPRINTF(UDMASS_SCSI, ("%s: Converted TEST_UNIT_READY "
- "to START_UNIT\n", device_get_nameunit(sc->sc_dev)));
- memset(*rcmd, 0, *rcmdlen);
- (*rcmd)[0] = START_STOP_UNIT;
- (*rcmd)[4] = SSS_START;
- return 1;
- }
- /* fallthrough */
- case INQUIRY:
- /* some drives wedge when asked for full inquiry information. */
- if (sc->quirks & FORCE_SHORT_INQUIRY) {
- memcpy(*rcmd, cmd, cmdlen);
- *rcmdlen = cmdlen;
- (*rcmd)[4] = SHORT_INQUIRY_LENGTH;
- return 1;
- }
- /* fallthrough */
- default:
- *rcmd = cmd; /* We don't need to copy it */
- *rcmdlen = cmdlen;
- }
-
- return 1;
-}
-/* RBC specific functions */
-static int
-umass_rbc_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen)
-{
- switch (cmd[0]) {
- /* these commands are defined in RBC: */
- case READ_10:
- case READ_CAPACITY:
- case START_STOP_UNIT:
- case SYNCHRONIZE_CACHE:
- case WRITE_10:
- case 0x2f: /* VERIFY_10 is absent from scsi_all.h??? */
- case INQUIRY:
- case MODE_SELECT_10:
- case MODE_SENSE_10:
- case TEST_UNIT_READY:
- case WRITE_BUFFER:
- /* The following commands are not listed in my copy of the RBC specs.
- * CAM however seems to want those, and at least the Sony DSC device
- * appears to support those as well */
- case REQUEST_SENSE:
- case PREVENT_ALLOW:
- if ((sc->quirks & RBC_PAD_TO_12) && cmdlen < 12) {
- *rcmdlen = 12;
- bcopy(cmd, *rcmd, cmdlen);
- bzero(*rcmd + cmdlen, 12 - cmdlen);
- } else {
- *rcmd = cmd; /* We don't need to copy it */
- *rcmdlen = cmdlen;
- }
- return 1;
- /* All other commands are not legal in RBC */
- default:
- printf("%s: Unsupported RBC command 0x%02x",
- device_get_nameunit(sc->sc_dev), cmd[0]);
- printf("\n");
- return 0; /* failure */
- }
-}
-
-/*
- * UFI specific functions
- */
-static int
-umass_ufi_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen)
-{
- /* A UFI command is always 12 bytes in length */
- KASSERT(*rcmdlen >= UFI_COMMAND_LENGTH,
- ("rcmdlen = %d < %d, buffer too small",
- *rcmdlen, UFI_COMMAND_LENGTH));
-
- *rcmdlen = UFI_COMMAND_LENGTH;
- memset(*rcmd, 0, UFI_COMMAND_LENGTH);
-
- switch (cmd[0]) {
- /* Commands of which the format has been verified. They should work.
- * Copy the command into the (zeroed out) destination buffer.
- */
- case TEST_UNIT_READY:
- if (sc->quirks & NO_TEST_UNIT_READY) {
- /* Some devices do not support this command.
- * Start Stop Unit should give the same results
- */
- DPRINTF(UDMASS_UFI, ("%s: Converted TEST_UNIT_READY "
- "to START_UNIT\n", device_get_nameunit(sc->sc_dev)));
- (*rcmd)[0] = START_STOP_UNIT;
- (*rcmd)[4] = SSS_START;
- } else {
- memcpy(*rcmd, cmd, cmdlen);
- }
- return 1;
-
- case REZERO_UNIT:
- case REQUEST_SENSE:
- case FORMAT_UNIT:
- case INQUIRY:
- case START_STOP_UNIT:
- case SEND_DIAGNOSTIC:
- case PREVENT_ALLOW:
- case READ_CAPACITY:
- case READ_10:
- case WRITE_10:
- case POSITION_TO_ELEMENT: /* SEEK_10 */
- case WRITE_AND_VERIFY:
- case VERIFY:
- case MODE_SELECT_10:
- case MODE_SENSE_10:
- case READ_12:
- case WRITE_12:
- case READ_FORMAT_CAPACITIES:
- memcpy(*rcmd, cmd, cmdlen);
- return 1;
-
- /*
- * SYNCHRONIZE_CACHE isn't supported by UFI, nor should it be
- * required for UFI devices, so it is appropriate to fake
- * success.
- */
- case SYNCHRONIZE_CACHE:
- return 2;
-
- default:
- printf("%s: Unsupported UFI command 0x%02x\n",
- device_get_nameunit(sc->sc_dev), cmd[0]);
- return 0; /* failure */
- }
-}
-
-/*
- * 8070i (ATAPI) specific functions
- */
-static int
-umass_atapi_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen)
-{
- /* An ATAPI command is always 12 bytes in length. */
- KASSERT(*rcmdlen >= ATAPI_COMMAND_LENGTH,
- ("rcmdlen = %d < %d, buffer too small",
- *rcmdlen, ATAPI_COMMAND_LENGTH));
-
- *rcmdlen = ATAPI_COMMAND_LENGTH;
- memset(*rcmd, 0, ATAPI_COMMAND_LENGTH);
-
- switch (cmd[0]) {
- /* Commands of which the format has been verified. They should work.
- * Copy the command into the (zeroed out) destination buffer.
- */
- case INQUIRY:
- memcpy(*rcmd, cmd, cmdlen);
- /* some drives wedge when asked for full inquiry information. */
- if (sc->quirks & FORCE_SHORT_INQUIRY)
- (*rcmd)[4] = SHORT_INQUIRY_LENGTH;
- return 1;
-
- case TEST_UNIT_READY:
- if (sc->quirks & NO_TEST_UNIT_READY) {
- KASSERT(*rcmdlen >= sizeof(struct scsi_start_stop_unit),
- ("rcmdlen = %d < %ld, buffer too small",
- *rcmdlen,
- (long)sizeof(struct scsi_start_stop_unit)));
- DPRINTF(UDMASS_SCSI, ("%s: Converted TEST_UNIT_READY "
- "to START_UNIT\n", device_get_nameunit(sc->sc_dev)));
- memset(*rcmd, 0, *rcmdlen);
- (*rcmd)[0] = START_STOP_UNIT;
- (*rcmd)[4] = SSS_START;
- return 1;
- }
- /* fallthrough */
- case REZERO_UNIT:
- case REQUEST_SENSE:
- case START_STOP_UNIT:
- case SEND_DIAGNOSTIC:
- case PREVENT_ALLOW:
- case READ_CAPACITY:
- case READ_10:
- case WRITE_10:
- case POSITION_TO_ELEMENT: /* SEEK_10 */
- case SYNCHRONIZE_CACHE:
- case MODE_SELECT_10:
- case MODE_SENSE_10:
- case READ_BUFFER:
- case 0x42: /* READ_SUBCHANNEL */
- case 0x43: /* READ_TOC */
- case 0x44: /* READ_HEADER */
- case 0x47: /* PLAY_MSF (Play Minute/Second/Frame) */
- case 0x48: /* PLAY_TRACK */
- case 0x49: /* PLAY_TRACK_REL */
- case 0x4b: /* PAUSE */
- case 0x51: /* READ_DISK_INFO */
- case 0x52: /* READ_TRACK_INFO */
- case 0x54: /* SEND_OPC */
- case 0x59: /* READ_MASTER_CUE */
- case 0x5b: /* CLOSE_TR_SESSION */
- case 0x5c: /* READ_BUFFER_CAP */
- case 0x5d: /* SEND_CUE_SHEET */
- case 0xa1: /* BLANK */
- case 0xa5: /* PLAY_12 */
- case 0xa6: /* EXCHANGE_MEDIUM */
- case 0xad: /* READ_DVD_STRUCTURE */
- case 0xbb: /* SET_CD_SPEED */
- case 0xe5: /* READ_TRACK_INFO_PHILIPS */
- memcpy(*rcmd, cmd, cmdlen);
- return 1;
-
- case READ_12:
- case WRITE_12:
- default:
- printf("%s: Unsupported ATAPI command 0x%02x"
- " - trying anyway\n",
- device_get_nameunit(sc->sc_dev), cmd[0]);
- memcpy(*rcmd, cmd, cmdlen);
- return 1;
- }
-}
-
-
-/* (even the comment is missing) */
-
-DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, usbd_driver_load, 0);
-
-
-
-#ifdef USB_DEBUG
-static void
-umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw)
-{
- int clen = cbw->bCDBLength;
- int dlen = UGETDW(cbw->dCBWDataTransferLength);
- u_int8_t *c = cbw->CBWCDB;
- int tag = UGETDW(cbw->dCBWTag);
- int flags = cbw->bCBWFlags;
-
- DPRINTF(UDMASS_BBB, ("%s: CBW %d: cmd = %db "
- "(0x%02x%02x%02x%02x%02x%02x%s), "
- "data = %db, dir = %s\n",
- device_get_nameunit(sc->sc_dev), tag, clen,
- c[0], c[1], c[2], c[3], c[4], c[5], (clen > 6? "...":""),
- dlen, (flags == CBWFLAGS_IN? "in":
- (flags == CBWFLAGS_OUT? "out":"<invalid>"))));
-}
-
-static void
-umass_bbb_dump_csw(struct umass_softc *sc, umass_bbb_csw_t *csw)
-{
- int sig = UGETDW(csw->dCSWSignature);
- int tag = UGETW(csw->dCSWTag);
- int res = UGETDW(csw->dCSWDataResidue);
- int status = csw->bCSWStatus;
-
- DPRINTF(UDMASS_BBB, ("%s: CSW %d: sig = 0x%08x (%s), tag = %d, "
- "res = %d, status = 0x%02x (%s)\n", device_get_nameunit(sc->sc_dev),
- tag, sig, (sig == CSWSIGNATURE? "valid":"invalid"),
- tag, res,
- status, (status == CSWSTATUS_GOOD? "good":
- (status == CSWSTATUS_FAILED? "failed":
- (status == CSWSTATUS_PHASE? "phase":"<invalid>")))));
-}
-
-static void
-umass_cbi_dump_cmd(struct umass_softc *sc, void *cmd, int cmdlen)
-{
- u_int8_t *c = cmd;
- int dir = sc->transfer_dir;
-
- DPRINTF(UDMASS_BBB, ("%s: cmd = %db "
- "(0x%02x%02x%02x%02x%02x%02x%s), "
- "data = %db, dir = %s\n",
- device_get_nameunit(sc->sc_dev), cmdlen,
- c[0], c[1], c[2], c[3], c[4], c[5], (cmdlen > 6? "...":""),
- sc->transfer_datalen,
- (dir == DIR_IN? "in":
- (dir == DIR_OUT? "out":
- (dir == DIR_NONE? "no data phase": "<invalid>")))));
-}
-
-static void
-umass_dump_buffer(struct umass_softc *sc, u_int8_t *buffer, int buflen,
- int printlen)
-{
- int i, j;
- char s1[40];
- char s2[40];
- char s3[5];
-
- s1[0] = '\0';
- s3[0] = '\0';
-
- sprintf(s2, " buffer=%p, buflen=%d", buffer, buflen);
- for (i = 0; i < buflen && i < printlen; i++) {
- j = i % 16;
- if (j == 0 && i != 0) {
- DPRINTF(UDMASS_GEN, ("%s: 0x %s%s\n",
- device_get_nameunit(sc->sc_dev), s1, s2));
- s2[0] = '\0';
- }
- sprintf(&s1[j*2], "%02x", buffer[i] & 0xff);
- }
- if (buflen > printlen)
- sprintf(s3, " ...");
- DPRINTF(UDMASS_GEN, ("%s: 0x %s%s%s\n",
- device_get_nameunit(sc->sc_dev), s1, s2, s3));
-}
-#endif
diff --git a/sys/legacy/dev/usb/umct.c b/sys/legacy/dev/usb/umct.c
deleted file mode 100644
index 63de146..0000000
--- a/sys/legacy/dev/usb/umct.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/*-
- * Copyright (c) 2003 Scott Long
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Driver for the MCT (Magic Control Technology) USB-RS232 Converter.
- * Based on the superb documentation from the linux mct_u232 driver by
- * Wolfgang Grandeggar <wolfgang@cec.ch>.
- * This device smells a lot like the Belkin F5U103, except that it has
- * suffered some mild brain-damage. This driver is based off of the ubsa.c
- * driver from Alexander Kabaev <kan@freebsd.org>. Merging the two together
- * might be useful, though the subtle differences might lead to lots of
- * #ifdef's.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/tty.h>
-#include <sys/taskqueue.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/ucomvar.h>
-
-/* The UMCT advertises the standard 8250 UART registers */
-#define UMCT_GET_MSR 2 /* Get Modem Status Register */
-#define UMCT_GET_MSR_SIZE 1
-#define UMCT_GET_LCR 6 /* Get Line Control Register */
-#define UMCT_GET_LCR_SIZE 1
-#define UMCT_SET_BAUD 5 /* Set the Baud Rate Divisor */
-#define UMCT_SET_BAUD_SIZE 4
-#define UMCT_SET_LCR 7 /* Set Line Control Register */
-#define UMCT_SET_LCR_SIZE 1
-#define UMCT_SET_MCR 10 /* Set Modem Control Register */
-#define UMCT_SET_MCR_SIZE 1
-
-#define UMCT_INTR_INTERVAL 100
-#define UMCT_IFACE_INDEX 0
-#define UMCT_CONFIG_INDEX 1
-
-struct umct_softc {
- struct ucom_softc sc_ucom;
- int sc_iface_number;
- usbd_interface_handle sc_intr_iface;
- int sc_intr_number;
- usbd_pipe_handle sc_intr_pipe;
- u_char *sc_intr_buf;
- int sc_isize;
- uint8_t sc_lsr;
- uint8_t sc_msr;
- uint8_t sc_lcr;
- uint8_t sc_mcr;
- struct task sc_task;
-};
-
-static void umct_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void umct_get_status(void *, int, u_char *, u_char *);
-static void umct_set(void *, int, int, int);
-static int umct_param(void *, int, struct termios *);
-static int umct_open(void *, int);
-static void umct_close(void *, int);
-static void umct_notify(void *, int count);
-
-static struct ucom_callback umct_callback = {
- umct_get_status, /* ucom_get_status */
- umct_set, /* ucom_set */
- umct_param, /* ucom_param */
- NULL, /* ucom_ioctl */
- umct_open, /* ucom_open */
- umct_close, /* ucom_close */
- NULL, /* ucom_read */
- NULL /* ucom_write */
-};
-
-static const struct umct_product {
- uint16_t vendor;
- uint16_t product;
-} umct_products[] = {
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232 },
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_SITECOM_USB232 },
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_DU_H3SP_USB232 },
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U109 },
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U409 },
- { 0, 0 }
-};
-
-static device_probe_t umct_match;
-static device_attach_t umct_attach;
-static device_detach_t umct_detach;
-
-static device_method_t umct_methods[] = {
- DEVMETHOD(device_probe, umct_match),
- DEVMETHOD(device_attach, umct_attach),
- DEVMETHOD(device_detach, umct_detach),
- { 0, 0 }
-};
-
-static driver_t umct_driver = {
- "ucom",
- umct_methods,
- sizeof(struct umct_softc)
-};
-
-DRIVER_MODULE(umct, uhub, umct_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(umct, usb, 1, 1, 1);
-MODULE_DEPEND(umct, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(umct, 1);
-
-static int
-umct_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- int i;
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- for (i = 0; umct_products[i].vendor != 0; i++) {
- if (umct_products[i].vendor == uaa->vendor &&
- umct_products[i].product == uaa->product) {
- return (UMATCH_VENDOR_PRODUCT);
- }
- }
-
- return (UMATCH_NONE);
-}
-
-static int
-umct_attach(device_t self)
-{
- struct umct_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev;
- struct ucom_softc *ucom;
- usb_config_descriptor_t *cdesc;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- const char *devname;
- usbd_status err;
- int i;
-
- dev = uaa->device;
- bzero(sc, sizeof(struct umct_softc));
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- ucom->sc_bulkout_no = -1;
- ucom->sc_bulkin_no = -1;
- sc->sc_intr_number = -1;
- sc->sc_intr_pipe = NULL;
-
- devname = device_get_nameunit(ucom->sc_dev);
-
- err = usbd_set_config_index(dev, UMCT_CONFIG_INDEX, 1);
- if (err) {
- printf("%s: failed to set configuration: %s\n",
- devname, usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- cdesc = usbd_get_config_descriptor(ucom->sc_udev);
- if (cdesc == NULL) {
- printf("%s: failed to get configuration descriptor\n", devname);
- ucom->sc_dying = 1;
- goto error;
- }
-
- err = usbd_device2interface_handle(dev, UMCT_IFACE_INDEX,
- &ucom->sc_iface);
- if (err) {
- printf("%s: failed to get interface: %s\n", devname,
- usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
- sc->sc_iface_number = id->bInterfaceNumber;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- printf("%s: no endpoint descriptor for %d\n",
- devname, i);
- ucom->sc_dying = 1;
- goto error;
- }
-
- /*
- * The real bulk-in endpoint is also marked as an interrupt.
- * The only way to differentiate it from the real interrupt
- * endpoint is to look at the wMaxPacketSize field.
- */
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) {
- if (UGETW(ed->wMaxPacketSize) == 0x2) {
- sc->sc_intr_number = ed->bEndpointAddress;
- sc->sc_isize = UGETW(ed->wMaxPacketSize);
- } else {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- ucom->sc_ibufsize = UGETW(ed->wMaxPacketSize);
- }
- continue;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- if (uaa->product == USB_PRODUCT_MCT_SITECOM_USB232)
- ucom->sc_obufsize = 16; /* device is broken */
- else
- ucom->sc_obufsize = UGETW(ed->wMaxPacketSize);
- continue;
- }
-
- printf("%s: warning - unsupported endpoint 0x%x\n", devname,
- ed->bEndpointAddress);
- }
-
- if (sc->sc_intr_number == -1) {
- printf("%s: Could not find interrupt in\n", devname);
- ucom->sc_dying = 1;
- goto error;
- }
-
- sc->sc_intr_iface = ucom->sc_iface;
-
- if (ucom->sc_bulkout_no == -1) {
- printf("%s: Could not find data bulk out\n", devname);
- ucom->sc_dying = 1;
- goto error;
- }
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &umct_callback;
- ucom_attach(ucom);
- TASK_INIT(&sc->sc_task, 0, umct_notify, sc);
- return 0;
-
-error:
- return ENXIO;
-}
-
-static int
-umct_detach(device_t self)
-{
- struct umct_softc *sc = device_get_softc(self);
-
- int rv;
-
- if (sc->sc_intr_pipe != NULL) {
- usbd_abort_pipe(sc->sc_intr_pipe);
- usbd_close_pipe(sc->sc_intr_pipe);
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-
- sc->sc_ucom.sc_dying = 1;
-#if 0
- taskqueue_drain(taskqueue_swi_giant);
-#endif
- rv = ucom_detach(&sc->sc_ucom);
- return (rv);
-}
-
-static int
-umct_request(struct umct_softc *sc, uint8_t request, int len, uint32_t value)
-{
- usb_device_request_t req;
- usbd_status err;
- uint8_t oval[4];
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = request;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, len);
- USETDW(oval, value);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, oval);
- if (err)
- printf("%s: umct_request: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- return (err);
-}
-
-static void
-umct_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct umct_softc *sc;
- u_char *buf;
-
- sc = (struct umct_softc *)priv;
- buf = sc->sc_intr_buf;
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
- return;
- }
-
- sc->sc_msr = buf[0];
- sc->sc_lsr = buf[1];
-
- /*
- * Defer notifying the ucom layer as it doesn't like to be bothered
- * from an interrupt context.
- */
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
-}
-
-static void
-umct_notify(void *arg, int count)
-{
- struct umct_softc *sc;
-
- sc = (struct umct_softc *)arg;
- if (sc->sc_ucom.sc_dying == 0)
- ucom_status_change(&sc->sc_ucom);
-}
-
-static void
-umct_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct umct_softc *sc;
-
- sc = addr;
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-
- return;
-}
-
-static void
-umct_set(void *addr, int portno, int reg, int onoff)
-{
- struct umct_softc *sc;
-
- sc = addr;
- switch (reg) {
- case UCOM_SET_BREAK:
- sc->sc_lcr &= ~0x40;
- sc->sc_lcr |= (onoff) ? 0x40 : 0;
- umct_request(sc, UMCT_SET_LCR, UMCT_SET_LCR_SIZE, sc->sc_lcr);
- break;
- case UCOM_SET_DTR:
- sc->sc_mcr &= ~0x01;
- sc->sc_mcr |= (onoff) ? 0x01 : 0;
- umct_request(sc, UMCT_SET_MCR, UMCT_SET_MCR_SIZE, sc->sc_mcr);
- break;
- case UCOM_SET_RTS:
- sc->sc_mcr &= ~0x2;
- sc->sc_mcr |= (onoff) ? 0x02 : 0;
- umct_request(sc, UMCT_SET_MCR, UMCT_SET_MCR_SIZE, sc->sc_mcr);
- break;
- default:
- break;
- }
-}
-
-static int
-umct_calc_baud(u_int baud)
-{
- switch(baud) {
- case B300: return (0x1);
- case B600: return (0x2);
- case B1200: return (0x3);
- case B2400: return (0x4);
- case B4800: return (0x6);
- case B9600: return (0x8);
- case B19200: return (0x9);
- case B38400: return (0xa);
- case B57600: return (0xb);
- case 115200: return (0xc);
- case B0:
- default:
- break;
- }
-
- return (0x0);
-}
-
-static int
-umct_param(void *addr, int portno, struct termios *ti)
-{
- struct umct_softc *sc;
- uint32_t value;
-
- sc = addr;
- value = umct_calc_baud(ti->c_ospeed);
- umct_request(sc, UMCT_SET_BAUD, UMCT_SET_BAUD_SIZE, value);
-
- value = sc->sc_lcr & 0x40;
-
- switch (ti->c_cflag & CSIZE) {
- case CS5: value |= 0x0; break;
- case CS6: value |= 0x1; break;
- case CS7: value |= 0x2; break;
- case CS8: value |= 0x3; break;
- default: value |= 0x0; break;
- }
-
- value |= (ti->c_cflag & CSTOPB) ? 0x4 : 0;
- if (ti->c_cflag & PARENB) {
- value |= 0x8;
- value |= (ti->c_cflag & PARODD) ? 0x0 : 0x10;
- }
-
- /*
- * XXX There doesn't seem to be a way to tell the device to use flow
- * control.
- */
-
- sc->sc_lcr = value;
- umct_request(sc, UMCT_SET_LCR, UMCT_SET_LCR_SIZE, value);
-
- return (0);
-}
-
-static int
-umct_open(void *addr, int portno)
-{
- struct umct_softc *sc;
- int err;
-
- sc = addr;
- if (sc->sc_ucom.sc_dying) {
- return (ENXIO);
- }
-
- if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
- sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
- err = usbd_open_pipe_intr(sc->sc_intr_iface, sc->sc_intr_number,
- USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_intr_buf,
- sc->sc_isize, umct_intr, UMCT_INTR_INTERVAL);
- if (err) {
- printf("%s: cannot open interrupt pipe (addr %d)\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- sc->sc_intr_number);
- free(sc->sc_intr_buf, M_USBDEV);
- return (EIO);
- }
- }
-
- return (0);
-}
-
-static void
-umct_close(void *addr, int portno)
-{
- struct umct_softc *sc;
- int err;
-
- sc = addr;
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (sc->sc_intr_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_intr_pipe);
- if (err)
- printf("%s: abort interrupt pipe failed: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_intr_pipe);
- if (err)
- printf("%s: close interrupt pipe failed: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-}
diff --git a/sys/legacy/dev/usb/umodem.c b/sys/legacy/dev/usb/umodem.c
deleted file mode 100644
index f0cb17c..0000000
--- a/sys/legacy/dev/usb/umodem.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/* $NetBSD: umodem.c,v 1.45 2002/09/23 05:51:23 simonb Exp $ */
-
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-/*-
- * Copyright (c) 2003, M. Warner Losh <imp@freebsd.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Comm Class spec: http://www.usb.org/developers/devclass_docs/usbccs10.pdf
- * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf
- */
-
-/*
- * TODO:
- * - Add error recovery in various places; the big problem is what
- * to do in a callback if there is an error.
- * - Implement a Call Device for modems without multiplexed commands.
- *
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/ioccom.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/select.h>
-#include <sys/sysctl.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/poll.h>
-#include <sys/uio.h>
-#include <sys/taskqueue.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-#include "usbdevs.h"
-
-#ifdef USB_DEBUG
-int umodemdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, umodem, CTLFLAG_RW, 0, "USB umodem");
-SYSCTL_INT(_hw_usb_umodem, OID_AUTO, debug, CTLFLAG_RW,
- &umodemdebug, 0, "umodem debug level");
-#define DPRINTFN(n, x) if (umodemdebug > (n)) printf x
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-static const struct umodem_product {
- u_int16_t vendor;
- u_int16_t product;
- u_int8_t interface;
-} umodem_products[] = {
- /* Kyocera AH-K3001V*/
- { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_AHK3001V, 0 },
- { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, 0 },
- { USB_VENDOR_CURITEL, USB_PRODUCT_CURITEL_PC5740, 0 },
- { 0, 0, 0 },
-};
-
-/*
- * These are the maximum number of bytes transferred per frame.
- * As speeds for umodem deivces increase, these numbers will need to
- * be increased. They should be good for G3 speeds and below.
- */
-#define UMODEMIBUFSIZE 1024
-#define UMODEMOBUFSIZE 1024
-
-#define UMODEM_MODVER 1 /* module version */
-
-struct umodem_softc {
- struct ucom_softc sc_ucom;
-
- device_t sc_dev; /* base device */
-
- usbd_device_handle sc_udev; /* USB device */
-
- int sc_ctl_iface_no;
- usbd_interface_handle sc_ctl_iface; /* control interface */
- int sc_data_iface_no;
- usbd_interface_handle sc_data_iface; /* data interface */
-
- int sc_cm_cap; /* CM capabilities */
- int sc_acm_cap; /* ACM capabilities */
-
- int sc_cm_over_data;
-
- usb_cdc_line_state_t sc_line_state; /* current line state */
- u_char sc_dtr; /* current DTR state */
- u_char sc_rts; /* current RTS state */
-
- u_char sc_opening; /* lock during open */
-
- int sc_ctl_notify; /* Notification endpoint */
- usbd_pipe_handle sc_notify_pipe; /* Notification pipe */
- usb_cdc_notification_t sc_notify_buf; /* Notification structure */
- u_char sc_lsr; /* Local status register */
- u_char sc_msr; /* Modem status register */
-
- struct task sc_task;
-};
-
-static void *umodem_get_desc(usbd_device_handle dev, int type, int subtype);
-static usbd_status umodem_set_comm_feature(struct umodem_softc *sc,
- int feature, int state);
-static usbd_status umodem_set_line_coding(struct umodem_softc *sc,
- usb_cdc_line_state_t *state);
-
-static void umodem_get_caps(usbd_device_handle, int *, int *);
-
-static void umodem_get_status(void *, int portno, u_char *lsr, u_char *msr);
-static void umodem_set(void *, int, int, int);
-static void umodem_dtr(struct umodem_softc *, int);
-static void umodem_rts(struct umodem_softc *, int);
-static void umodem_break(struct umodem_softc *, int);
-static void umodem_set_line_state(struct umodem_softc *);
-static int umodem_param(void *, int, struct termios *);
-static int umodem_ioctl(void *, int, u_long, caddr_t, struct thread *);
-static int umodem_open(void *, int portno);
-static void umodem_close(void *, int portno);
-static void umodem_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void umodem_notify(void *, int);
-
-static struct ucom_callback umodem_callback = {
- .ucom_get_status = umodem_get_status,
- .ucom_set = umodem_set,
- .ucom_param = umodem_param,
- .ucom_ioctl = umodem_ioctl,
- .ucom_open = umodem_open,
- .ucom_close = umodem_close
-};
-
-static device_probe_t umodem_match;
-static device_attach_t umodem_attach;
-static device_detach_t umodem_detach;
-
-static device_method_t umodem_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, umodem_match),
- DEVMETHOD(device_attach, umodem_attach),
- DEVMETHOD(device_detach, umodem_detach),
- { 0, 0 }
-};
-
-static driver_t umodem_driver = {
- "ucom",
- umodem_methods,
- sizeof (struct umodem_softc)
-};
-
-DRIVER_MODULE(umodem, uhub, umodem_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(umodem, usb, 1, 1, 1);
-MODULE_DEPEND(umodem, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(umodem, UMODEM_MODVER);
-
-static int
-umodem_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
- usb_device_descriptor_t *dd;
- int cm, acm, i, ret;
-
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
-
- id = usbd_get_interface_descriptor(uaa->iface);
- dd = usbd_get_device_descriptor(uaa->device);
- if (id == NULL || dd == NULL)
- return (UMATCH_NONE);
-
- ret = UMATCH_NONE;
- for (i = 0; umodem_products[i].vendor != 0; i++) {
- if (umodem_products[i].vendor == UGETW(dd->idVendor) &&
- umodem_products[i].product == UGETW(dd->idProduct) &&
- umodem_products[i].interface == id->bInterfaceNumber) {
- ret = UMATCH_VENDOR_PRODUCT;
- break;
- }
- }
-
- if (ret == UMATCH_NONE &&
- id->bInterfaceClass == UICLASS_CDC &&
- id->bInterfaceSubClass == UISUBCLASS_ABSTRACT_CONTROL_MODEL &&
- id->bInterfaceProtocol == UIPROTO_CDC_AT)
- ret = UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO;
-
- if (ret == UMATCH_NONE)
- return (ret);
-
- umodem_get_caps(uaa->device, &cm, &acm);
- if (!(cm & USB_CDC_CM_DOES_CM) ||
- !(cm & USB_CDC_CM_OVER_DATA) ||
- !(acm & USB_CDC_ACM_HAS_LINE))
- return (UMATCH_NONE);
-
- return ret;
-}
-
-static int
-umodem_attach(device_t self)
-{
- struct umodem_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usb_cdc_cm_descriptor_t *cmd;
- int data_ifcno;
- int i;
- struct ucom_softc *ucom;
-
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- sc->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- sc->sc_udev = dev;
- sc->sc_ctl_iface = uaa->iface;
- id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
- sc->sc_ctl_iface_no = id->bInterfaceNumber;
- device_printf(self, "iclass %d/%d\n", id->bInterfaceClass,
- id->bInterfaceSubClass);
-
- umodem_get_caps(dev, &sc->sc_cm_cap, &sc->sc_acm_cap);
-
- /* Get the data interface no. */
- cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
- if (cmd == NULL) {
- device_printf(sc->sc_dev, "no CM descriptor\n");
- goto bad;
- }
- sc->sc_data_iface_no = data_ifcno = cmd->bDataInterface;
-
- device_printf(sc->sc_dev,
- "data interface %d, has %sCM over data, has %sbreak\n",
- data_ifcno, sc->sc_cm_cap & USB_CDC_CM_OVER_DATA ? "" : "no ",
- sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK ? "" : "no ");
-
- /* Get the data interface too. */
- for (i = 0; i < uaa->nifaces; i++) {
- if (uaa->ifaces[i] != NULL) {
- id = usbd_get_interface_descriptor(uaa->ifaces[i]);
- if (id != NULL && id->bInterfaceNumber == data_ifcno) {
- sc->sc_data_iface = uaa->ifaces[i];
- uaa->ifaces[i] = NULL;
- }
- }
- }
- if (sc->sc_data_iface == NULL) {
- device_printf(sc->sc_dev, "no data interface\n");
- goto bad;
- }
- ucom->sc_iface = sc->sc_data_iface;
-
- /*
- * Find the bulk endpoints.
- * Iterate over all endpoints in the data interface and take note.
- */
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
-
- id = usbd_get_interface_descriptor(sc->sc_data_iface);
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_data_iface, i);
- if (ed == NULL) {
- device_printf(sc->sc_dev,
- "no endpoint descriptor for %d\n", i);
- goto bad;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
- }
-
- if (ucom->sc_bulkin_no == -1) {
- device_printf(sc->sc_dev, "Could not find data bulk in\n");
- goto bad;
- }
- if (ucom->sc_bulkout_no == -1) {
- device_printf(sc->sc_dev, "Could not find data bulk out\n");
- goto bad;
- }
-
- if (sc->sc_cm_cap & USB_CDC_CM_OVER_DATA) {
- if (sc->sc_acm_cap & USB_CDC_ACM_HAS_FEATURE)
- umodem_set_comm_feature(sc, UCDC_ABSTRACT_STATE,
- UCDC_DATA_MULTIPLEXED);
- sc->sc_cm_over_data = 1;
- }
-
- /*
- * The standard allows for notification messages (to indicate things
- * like a modem hangup) to come in via an interrupt endpoint
- * off of the control interface. Iterate over the endpoints on
- * the control interface and see if there are any interrupt
- * endpoints; if there are, then register it.
- */
-
- sc->sc_ctl_notify = -1;
- sc->sc_notify_pipe = NULL;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
- if (ed == NULL)
- continue;
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
- device_printf(sc->sc_dev,
- "status change notification available\n");
- sc->sc_ctl_notify = ed->bEndpointAddress;
- }
- }
-
- sc->sc_dtr = -1;
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = UMODEMIBUFSIZE;
- ucom->sc_obufsize = UMODEMOBUFSIZE;
- ucom->sc_ibufsizepad = UMODEMIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &umodem_callback;
-
- TASK_INIT(&sc->sc_task, 0, umodem_notify, sc);
- ucom_attach(&sc->sc_ucom);
- return 0;
-
- bad:
- ucom->sc_dying = 1;
- return ENXIO;
-}
-
-static int
-umodem_open(void *addr, int portno)
-{
- struct umodem_softc *sc = addr;
- int err;
-
- DPRINTF(("umodem_open: sc=%p\n", sc));
-
- if (sc->sc_ctl_notify != -1 && sc->sc_notify_pipe == NULL) {
- err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_ctl_notify,
- USBD_SHORT_XFER_OK, &sc->sc_notify_pipe, sc,
- &sc->sc_notify_buf, sizeof(sc->sc_notify_buf),
- umodem_intr, USBD_DEFAULT_INTERVAL);
-
- if (err) {
- DPRINTF(("Failed to establish notify pipe: %s\n",
- usbd_errstr(err)));
- return EIO;
- }
- }
-
- return 0;
-}
-
-static void
-umodem_close(void *addr, int portno)
-{
- struct umodem_softc *sc = addr;
- int err;
-
- DPRINTF(("umodem_close: sc=%p\n", sc));
-
- if (sc->sc_notify_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_notify_pipe);
- if (err)
- device_printf(sc->sc_dev,
- "abort notify pipe failed: %s\n",
- usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_notify_pipe);
- if (err)
- device_printf(sc->sc_dev,
- "close notify pipe failed: %s\n",
- usbd_errstr(err));
- sc->sc_notify_pipe = NULL;
- }
-}
-
-static void
-umodem_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct umodem_softc *sc = priv;
- u_char mstatus;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
- device_printf(sc->sc_dev, "abnormal status: %s\n",
- usbd_errstr(status));
- return;
- }
-
- if (sc->sc_notify_buf.bmRequestType != UCDC_NOTIFICATION) {
- DPRINTF(("%s: unknown message type (%02x) on notify pipe\n",
- device_get_nameunit(sc->sc_dev),
- sc->sc_notify_buf.bmRequestType));
- return;
- }
-
- switch (sc->sc_notify_buf.bNotification) {
- case UCDC_N_SERIAL_STATE:
- /*
- * Set the serial state in ucom driver based on
- * the bits from the notify message
- */
- if (UGETW(sc->sc_notify_buf.wLength) != 2) {
- device_printf(sc->sc_dev,
- "Invalid notification length! (%d)\n",
- UGETW(sc->sc_notify_buf.wLength));
- break;
- }
- DPRINTF(("%s: notify bytes = %02x%02x\n",
- device_get_nameunit(sc->sc_dev),
- sc->sc_notify_buf.data[0],
- sc->sc_notify_buf.data[1]));
- /* Currently, lsr is always zero. */
- sc->sc_lsr = sc->sc_msr = 0;
- mstatus = sc->sc_notify_buf.data[0];
-
- if (ISSET(mstatus, UCDC_N_SERIAL_RI))
- sc->sc_msr |= SER_RI;
- if (ISSET(mstatus, UCDC_N_SERIAL_DSR))
- sc->sc_msr |= SER_DSR;
- if (ISSET(mstatus, UCDC_N_SERIAL_DCD))
- sc->sc_msr |= SER_DCD;
- /* Deferred notifying to the ucom layer */
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
- break;
- default:
- DPRINTF(("%s: unknown notify message: %02x\n",
- device_get_nameunit(sc->sc_dev),
- sc->sc_notify_buf.bNotification));
- break;
- }
-}
-
-static void
-umodem_notify(void *arg, int count)
-{
- struct umodem_softc *sc;
-
- sc = (struct umodem_softc *)arg;
- if (sc->sc_ucom.sc_dying)
- return;
- ucom_status_change(&sc->sc_ucom);
-}
-
-void
-umodem_get_caps(usbd_device_handle dev, int *cm, int *acm)
-{
- usb_cdc_cm_descriptor_t *cmd;
- usb_cdc_acm_descriptor_t *cad;
-
- *cm = *acm = 0;
-
- cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
- if (cmd == NULL) {
- DPRINTF(("umodem_get_desc: no CM desc\n"));
- return;
- }
- *cm = cmd->bmCapabilities;
-
- cad = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM);
- if (cad == NULL) {
- DPRINTF(("umodem_get_desc: no ACM desc\n"));
- return;
- }
- *acm = cad->bmCapabilities;
-}
-
-void
-umodem_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct umodem_softc *sc = addr;
-
- DPRINTF(("umodem_get_status:\n"));
-
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-}
-
-int
-umodem_param(void *addr, int portno, struct termios *t)
-{
- struct umodem_softc *sc = addr;
- usbd_status err;
- usb_cdc_line_state_t ls;
-
- DPRINTF(("umodem_param: sc=%p\n", sc));
-
- USETDW(ls.dwDTERate, t->c_ospeed);
- if (ISSET(t->c_cflag, CSTOPB))
- ls.bCharFormat = UCDC_STOP_BIT_2;
- else
- ls.bCharFormat = UCDC_STOP_BIT_1;
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- ls.bParityType = UCDC_PARITY_ODD;
- else
- ls.bParityType = UCDC_PARITY_EVEN;
- } else
- ls.bParityType = UCDC_PARITY_NONE;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- ls.bDataBits = 5;
- break;
- case CS6:
- ls.bDataBits = 6;
- break;
- case CS7:
- ls.bDataBits = 7;
- break;
- case CS8:
- ls.bDataBits = 8;
- break;
- }
-
- err = umodem_set_line_coding(sc, &ls);
- if (err) {
- DPRINTF(("umodem_param: err=%s\n", usbd_errstr(err)));
- return (EIO);
- }
- return (0);
-}
-
-int
-umodem_ioctl(void *addr, int portno, u_long cmd, caddr_t data,
- struct thread *p)
-{
- struct umodem_softc *sc = addr;
- int error = 0;
-
- if (sc->sc_ucom.sc_dying)
- return (EIO);
-
- DPRINTF(("umodemioctl: cmd=0x%08lx\n", cmd));
-
- switch (cmd) {
- case USB_GET_CM_OVER_DATA:
- *(int *)data = sc->sc_cm_over_data;
- break;
-
- case USB_SET_CM_OVER_DATA:
- if (*(int *)data != sc->sc_cm_over_data) {
- /* XXX change it */
- }
- break;
-
- default:
- DPRINTF(("umodemioctl: unknown\n"));
- error = ENOIOCTL;
- break;
- }
-
- return (error);
-}
-
-void
-umodem_dtr(struct umodem_softc *sc, int onoff)
-{
- DPRINTF(("umodem_modem: onoff=%d\n", onoff));
-
- if (sc->sc_dtr == onoff)
- return;
- sc->sc_dtr = onoff;
-
- umodem_set_line_state(sc);
-}
-
-void
-umodem_rts(struct umodem_softc *sc, int onoff)
-{
- DPRINTF(("umodem_modem: onoff=%d\n", onoff));
-
- if (sc->sc_rts == onoff)
- return;
- sc->sc_rts = onoff;
-
- umodem_set_line_state(sc);
-}
-
-void
-umodem_set_line_state(struct umodem_softc *sc)
-{
- usb_device_request_t req;
- int ls;
-
- ls = (sc->sc_dtr ? UCDC_LINE_DTR : 0) |
- (sc->sc_rts ? UCDC_LINE_RTS : 0);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, ls);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, 0);
-
- (void)usbd_do_request(sc->sc_udev, &req, 0);
-
-}
-
-void
-umodem_break(struct umodem_softc *sc, int onoff)
-{
- usb_device_request_t req;
-
- DPRINTF(("umodem_break: onoff=%d\n", onoff));
-
- if (!(sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK))
- return;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
- USETW(req.wValue, onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, 0);
-
- (void)usbd_do_request(sc->sc_udev, &req, 0);
-}
-
-void
-umodem_set(void *addr, int portno, int reg, int onoff)
-{
- struct umodem_softc *sc = addr;
-
- switch (reg) {
- case UCOM_SET_DTR:
- umodem_dtr(sc, onoff);
- break;
- case UCOM_SET_RTS:
- umodem_rts(sc, onoff);
- break;
- case UCOM_SET_BREAK:
- umodem_break(sc, onoff);
- break;
- default:
- break;
- }
-}
-
-usbd_status
-umodem_set_line_coding(struct umodem_softc *sc, usb_cdc_line_state_t *state)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("umodem_set_line_coding: rate=%d fmt=%d parity=%d bits=%d\n",
- UGETDW(state->dwDTERate), state->bCharFormat,
- state->bParityType, state->bDataBits));
-
- if (memcmp(state, &sc->sc_line_state, UCDC_LINE_STATE_LENGTH) == 0) {
- DPRINTF(("umodem_set_line_coding: already set\n"));
- return (USBD_NORMAL_COMPLETION);
- }
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_LINE_CODING;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, UCDC_LINE_STATE_LENGTH);
-
- err = usbd_do_request(sc->sc_udev, &req, state);
- if (err) {
- DPRINTF(("umodem_set_line_coding: failed, err=%s\n",
- usbd_errstr(err)));
- return (err);
- }
-
- sc->sc_line_state = *state;
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-void *
-umodem_get_desc(usbd_device_handle dev, int type, int subtype)
-{
- usb_descriptor_t *desc;
- usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
- uByte *p = (uByte *)cd;
- uByte *end = p + UGETW(cd->wTotalLength);
-
- while (p < end) {
- desc = (usb_descriptor_t *)p;
- if (desc->bDescriptorType == type &&
- desc->bDescriptorSubtype == subtype)
- return (desc);
- p += desc->bLength;
- }
-
- return (0);
-}
-
-usbd_status
-umodem_set_comm_feature(struct umodem_softc *sc, int feature, int state)
-{
- usb_device_request_t req;
- usbd_status err;
- usb_cdc_abstract_state_t ast;
-
- DPRINTF(("umodem_set_comm_feature: feature=%d state=%d\n", feature,
- state));
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_COMM_FEATURE;
- USETW(req.wValue, feature);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, UCDC_ABSTRACT_STATE_LENGTH);
- USETW(ast.wState, state);
-
- err = usbd_do_request(sc->sc_udev, &req, &ast);
- if (err) {
- DPRINTF(("umodem_set_comm_feature: feature=%d, err=%s\n",
- feature, usbd_errstr(err)));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static int
-umodem_detach(device_t self)
-{
- struct umodem_softc *sc = device_get_softc(self);
- int rv = 0;
-
- DPRINTF(("umodem_detach: sc=%p\n", sc));
-
- if (sc->sc_notify_pipe != NULL) {
- usbd_abort_pipe(sc->sc_notify_pipe);
- usbd_close_pipe(sc->sc_notify_pipe);
- sc->sc_notify_pipe = NULL;
- }
-
- sc->sc_ucom.sc_dying = 1;
- rv = ucom_detach(&sc->sc_ucom);
-
- return (rv);
-}
diff --git a/sys/legacy/dev/usb/ums.c b/sys/legacy/dev/usb/ums.c
deleted file mode 100644
index 6484303..0000000
--- a/sys/legacy/dev/usb/ums.c
+++ /dev/null
@@ -1,972 +0,0 @@
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-#include <dev/usb/hid.h>
-
-#include <sys/mouse.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (umsdebug) printf x
-#define DPRINTFN(n,x) if (umsdebug>(n)) printf x
-int umsdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ums, CTLFLAG_RW, 0, "USB ums");
-SYSCTL_INT(_hw_usb_ums, OID_AUTO, debug, CTLFLAG_RW,
- &umsdebug, 0, "ums debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UMSUNIT(s) (dev2unit(s)&0x1f)
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-#define QUEUE_BUFSIZE 400 /* MUST be divisible by 5 _and_ 8 */
-
-struct ums_softc {
- device_t sc_dev; /* base device */
- usbd_interface_handle sc_iface; /* interface */
- usbd_pipe_handle sc_intrpipe; /* interrupt pipe */
- int sc_ep_addr;
-
- u_char *sc_ibuf;
- u_int8_t sc_iid;
- int sc_isize;
- struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_t, sc_loc_w;
- struct hid_location *sc_loc_btn;
-
- struct callout callout_handle; /* for spurious button ups */
-
- int sc_enabled;
- int sc_disconnected; /* device is gone */
-
- int flags; /* device configuration */
-#define UMS_Z 0x01 /* z direction available */
-#define UMS_SPUR_BUT_UP 0x02 /* spurious button up events */
-#define UMS_T 0x04 /* aa direction available (tilt) */
-#define UMS_REVZ 0x08 /* Z-axis is reversed */
- int nbuttons;
-#define MAX_BUTTONS 31 /* chosen because sc_buttons is int */
-
- u_char qbuf[QUEUE_BUFSIZE]; /* must be divisable by 3&4 */
- u_char dummy[100]; /* XXX just for safety and for now */
- int qcount, qhead, qtail;
- mousehw_t hw;
- mousemode_t mode;
- mousestatus_t status;
-
- int state;
-# define UMS_ASLEEP 0x01 /* readFromDevice is waiting */
-# define UMS_SELECT 0x02 /* select is waiting */
- struct selinfo rsel; /* process waiting in select */
-
- struct cdev *dev; /* specfs */
-};
-
-#define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
-#define MOUSE_FLAGS (HIO_RELATIVE)
-
-static void ums_intr(usbd_xfer_handle xfer,
- usbd_private_handle priv, usbd_status status);
-
-static void ums_add_to_queue(struct ums_softc *sc,
- int dx, int dy, int dz, int dt, int buttons);
-static void ums_add_to_queue_timeout(void *priv);
-
-static int ums_enable(void *);
-static void ums_disable(void *);
-
-static d_open_t ums_open;
-static d_close_t ums_close;
-static d_read_t ums_read;
-static d_ioctl_t ums_ioctl;
-static d_poll_t ums_poll;
-
-
-static struct cdevsw ums_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = ums_open,
- .d_close = ums_close,
- .d_read = ums_read,
- .d_ioctl = ums_ioctl,
- .d_poll = ums_poll,
- .d_name = "ums",
-};
-
-static device_probe_t ums_match;
-static device_attach_t ums_attach;
-static device_detach_t ums_detach;
-
-static device_method_t ums_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ums_match),
- DEVMETHOD(device_attach, ums_attach),
- DEVMETHOD(device_detach, ums_detach),
-
- { 0, 0 }
-};
-
-static driver_t ums_driver = {
- "ums",
- ums_methods,
- sizeof(struct ums_softc)
-};
-
-static devclass_t ums_devclass;
-
-static int
-ums_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
- int size, ret;
- void *desc;
- usbd_status err;
-
- if (!uaa->iface)
- return (UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
- if (!id || id->bInterfaceClass != UICLASS_HID)
- return (UMATCH_NONE);
-
- err = usbd_read_report_desc(uaa->iface, &desc, &size, M_TEMP);
- if (err)
- return (UMATCH_NONE);
-
- if (hid_is_collection(desc, size,
- HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
- ret = UMATCH_IFACECLASS;
- else if (id->bInterfaceClass == UICLASS_HID &&
- id->bInterfaceSubClass == UISUBCLASS_BOOT &&
- id->bInterfaceProtocol == UIPROTO_MOUSE)
- ret = UMATCH_IFACECLASS;
- else
- ret = UMATCH_NONE;
-
- free(desc, M_TEMP);
- return (ret);
-}
-
-static int
-ums_attach(device_t self)
-{
- struct ums_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int size;
- void *desc;
- usbd_status err;
- u_int32_t flags;
- int i, wheel;
- struct hid_location loc_btn;
-
- sc->sc_disconnected = 1;
- sc->sc_iface = iface;
- id = usbd_get_interface_descriptor(iface);
- sc->sc_dev = self;
- ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (!ed) {
- printf("%s: could not read endpoint descriptor\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-
- DPRINTFN(10,("ums_attach: bLength=%d bDescriptorType=%d "
- "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
- " bInterval=%d\n",
- ed->bLength, ed->bDescriptorType,
- UE_GET_ADDR(ed->bEndpointAddress),
- UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? "in":"out",
- UE_GET_XFERTYPE(ed->bmAttributes),
- UGETW(ed->wMaxPacketSize), ed->bInterval));
-
- if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
- UE_GET_XFERTYPE(ed->bmAttributes) != UE_INTERRUPT) {
- printf("%s: unexpected endpoint\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-
- err = usbd_read_report_desc(uaa->iface, &desc, &size, M_TEMP);
- if (err)
- return ENXIO;
-
- if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
- hid_input, &sc->sc_loc_x, &flags)) {
- printf("%s: mouse has no X report\n", device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
- if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("%s: X report 0x%04x not supported\n",
- device_get_nameunit(sc->sc_dev), flags);
- return ENXIO;
- }
-
- if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
- hid_input, &sc->sc_loc_y, &flags)) {
- printf("%s: mouse has no Y report\n", device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
- if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("%s: Y report 0x%04x not supported\n",
- device_get_nameunit(sc->sc_dev), flags);
- return ENXIO;
- }
-
- /* Try the wheel first as the Z activator since it's tradition. */
- wheel = hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_WHEEL),
- hid_input, &sc->sc_loc_z, &flags) ||
- hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_TWHEEL),
- hid_input, &sc->sc_loc_z, &flags);
-
- if (wheel) {
- if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("\n%s: Wheel report 0x%04x not supported\n",
- device_get_nameunit(sc->sc_dev), flags);
- sc->sc_loc_z.size = 0; /* Bad Z coord, ignore it */
- } else {
- sc->flags |= UMS_Z;
- if (usbd_get_quirks(uaa->device)->uq_flags &
- UQ_MS_REVZ) {
- /* Some wheels need the Z axis reversed. */
- sc->flags |= UMS_REVZ;
- }
-
- }
- /*
- * We might have both a wheel and Z direction, if so put
- * put the Z on the W coordinate.
- */
- if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_Z),
- hid_input, &sc->sc_loc_w, &flags)) {
- if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("\n%s: Z report 0x%04x not supported\n",
- device_get_nameunit(sc->sc_dev), flags);
- sc->sc_loc_w.size = 0; /* Bad Z, ignore */
- }
- }
- } else if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_Z),
- hid_input, &sc->sc_loc_z, &flags)) {
- if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("\n%s: Z report 0x%04x not supported\n",
- device_get_nameunit(sc->sc_dev), flags);
- sc->sc_loc_z.size = 0; /* Bad Z coord, ignore it */
- } else {
- sc->flags |= UMS_Z;
- }
- }
-
- /*
- * The Microsoft Wireless Intellimouse 2.0 reports it's wheel
- * using 0x0048 (i've called it HUG_TWHEEL) and seems to expect
- * you to know that the byte after the wheel is the tilt axis.
- * There are no other HID axis descriptors other than X,Y and
- * TWHEEL
- */
- if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL),
- hid_input, &sc->sc_loc_t, &flags)) {
- sc->sc_loc_t.pos = sc->sc_loc_t.pos + 8;
- sc->flags |= UMS_T;
- }
-
- /* figure out the number of buttons */
- for (i = 1; i <= MAX_BUTTONS; i++)
- if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
- hid_input, &loc_btn, 0))
- break;
- sc->nbuttons = i - 1;
- sc->sc_loc_btn = malloc(sizeof(struct hid_location)*sc->nbuttons,
- M_USBDEV, M_NOWAIT);
- if (!sc->sc_loc_btn) {
- printf("%s: no memory\n", device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-
- printf("%s: %d buttons%s%s.\n", device_get_nameunit(sc->sc_dev),
- sc->nbuttons, sc->flags & UMS_Z? " and Z dir" : "",
- sc->flags & UMS_T?" and a TILT dir": "");
-
- for (i = 1; i <= sc->nbuttons; i++)
- hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
- hid_input, &sc->sc_loc_btn[i-1], 0);
-
- sc->sc_isize = hid_report_size(desc, size, hid_input, &sc->sc_iid);
-
- /*
- * The Microsoft Wireless Notebook Optical Mouse seems to be in worse
- * shape than the Wireless Intellimouse 2.0, as its X, Y, wheel, and
- * all of its other button positions are all off. It also reports that
- * it has two addional buttons and a tilt wheel.
- */
- if (usbd_get_quirks(uaa->device)->uq_flags & UQ_MS_BAD_CLASS) {
- sc->flags = UMS_Z;
- sc->flags |= UMS_SPUR_BUT_UP;
- sc->nbuttons = 3;
- sc->sc_isize = 5;
- sc->sc_iid = 0;
- /* 1st byte of descriptor report contains garbage */
- sc->sc_loc_x.pos = 16;
- sc->sc_loc_y.pos = 24;
- sc->sc_loc_z.pos = 32;
- sc->sc_loc_btn[0].pos = 8;
- sc->sc_loc_btn[1].pos = 9;
- sc->sc_loc_btn[2].pos = 10;
- }
-
- /*
- * The Microsoft Wireless Notebook Optical Mouse 3000 Model 1049 has
- * five Report IDs: 19 23 24 17 18 (in the order they appear in report
- * descriptor), it seems that report id 17 contains the necessary
- * mouse information(3-buttons,X,Y,wheel) so we specify it manually.
- */
- if (uaa->vendor == USB_VENDOR_MICROSOFT &&
- uaa->product == USB_PRODUCT_MICROSOFT_WLNOTEBOOK3) {
- sc->flags = UMS_Z;
- sc->nbuttons = 3;
- sc->sc_isize = 5;
- sc->sc_iid = 17;
- sc->sc_loc_x.pos = 8;
- sc->sc_loc_y.pos = 16;
- sc->sc_loc_z.pos = 24;
- sc->sc_loc_btn[0].pos = 0;
- sc->sc_loc_btn[1].pos = 1;
- sc->sc_loc_btn[2].pos = 2;
- }
-
- sc->sc_ibuf = malloc(sc->sc_isize, M_USB, M_NOWAIT);
- if (!sc->sc_ibuf) {
- printf("%s: no memory\n", device_get_nameunit(sc->sc_dev));
- free(sc->sc_loc_btn, M_USB);
- return ENXIO;
- }
-
- sc->sc_ep_addr = ed->bEndpointAddress;
- sc->sc_disconnected = 0;
- free(desc, M_TEMP);
-
-#ifdef USB_DEBUG
- DPRINTF(("ums_attach: sc=%p\n", sc));
- DPRINTF(("ums_attach: X\t%d/%d\n",
- sc->sc_loc_x.pos, sc->sc_loc_x.size));
- DPRINTF(("ums_attach: Y\t%d/%d\n",
- sc->sc_loc_y.pos, sc->sc_loc_y.size));
- if (sc->flags & UMS_Z)
- DPRINTF(("ums_attach: Z\t%d/%d\n",
- sc->sc_loc_z.pos, sc->sc_loc_z.size));
- for (i = 1; i <= sc->nbuttons; i++) {
- DPRINTF(("ums_attach: B%d\t%d/%d\n",
- i, sc->sc_loc_btn[i-1].pos,sc->sc_loc_btn[i-1].size));
- }
- DPRINTF(("ums_attach: size=%d, id=%d\n", sc->sc_isize, sc->sc_iid));
-#endif
-
- if (sc->nbuttons > MOUSE_MSC_MAXBUTTON)
- sc->hw.buttons = MOUSE_MSC_MAXBUTTON;
- else
- sc->hw.buttons = sc->nbuttons;
- sc->hw.iftype = MOUSE_IF_USB;
- sc->hw.type = MOUSE_MOUSE;
- sc->hw.model = MOUSE_MODEL_GENERIC;
- sc->hw.hwid = 0;
- sc->mode.protocol = MOUSE_PROTO_MSC;
- sc->mode.rate = -1;
- sc->mode.resolution = MOUSE_RES_UNKNOWN;
- sc->mode.accelfactor = 0;
- sc->mode.level = 0;
- sc->mode.packetsize = MOUSE_MSC_PACKETSIZE;
- sc->mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
- sc->mode.syncmask[1] = MOUSE_MSC_SYNC;
-
- sc->status.flags = 0;
- sc->status.button = sc->status.obutton = 0;
- sc->status.dx = sc->status.dy = sc->status.dz = 0;
-
- sc->dev = make_dev(&ums_cdevsw, device_get_unit(self),
- UID_ROOT, GID_OPERATOR,
- 0644, "ums%d", device_get_unit(self));
-
- callout_init(&sc->callout_handle, 0);
- if (usbd_get_quirks(uaa->device)->uq_flags & UQ_SPUR_BUT_UP) {
- DPRINTF(("%s: Spurious button up events\n",
- device_get_nameunit(sc->sc_dev)));
- sc->flags |= UMS_SPUR_BUT_UP;
- }
-
- return 0;
-}
-
-
-static int
-ums_detach(device_t self)
-{
- struct ums_softc *sc = device_get_softc(self);
-
- if (sc->sc_enabled)
- ums_disable(sc);
-
- DPRINTF(("%s: disconnected\n", device_get_nameunit(self)));
-
- free(sc->sc_loc_btn, M_USB);
- free(sc->sc_ibuf, M_USB);
-
- /* someone waiting for data */
- /*
- * XXX If we wakeup the process here, the device will be gone by
- * the time the process gets a chance to notice. *_close and friends
- * should be fixed to handle this case.
- * Or we should do a delayed detach for this.
- * Does this delay now force tsleep to exit with an error?
- */
- if (sc->state & UMS_ASLEEP) {
- sc->state &= ~UMS_ASLEEP;
- wakeup(sc);
- }
- if (sc->state & UMS_SELECT) {
- sc->state &= ~UMS_SELECT;
- selwakeuppri(&sc->rsel, PZERO);
- }
-
- destroy_dev(sc->dev);
-
- return 0;
-}
-
-void
-ums_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
-{
- struct ums_softc *sc = addr;
- u_char *ibuf;
- int dx, dy, dz, dw, dt;
- int buttons = 0;
- int i;
-
-#define UMS_BUT(i) ((i) < 3 ? (((i) + 2) % 3) : (i))
-
- DPRINTFN(5, ("ums_intr: sc=%p status=%d\n", sc, status));
- DPRINTFN(5, ("ums_intr: data ="));
- for (i = 0; i < sc->sc_isize; i++)
- DPRINTFN(5, (" %02x", sc->sc_ibuf[i]));
- DPRINTFN(5, ("\n"));
-
- if (status == USBD_CANCELLED)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF(("ums_intr: status=%d\n", status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
- if(status != USBD_IOERROR)
- return;
- }
-
- ibuf = sc->sc_ibuf;
- /*
- * The M$ Wireless Intellimouse 2.0 sends 1 extra leading byte of
- * data compared to most USB mice. This byte frequently switches
- * from 0x01 (usual state) to 0x02. I assume it is to allow
- * extra, non-standard, reporting (say battery-life). However
- * at the same time it generates a left-click message on the button
- * byte which causes spurious left-click's where there shouldn't be.
- * This should sort that.
- * Currently it's the only user of UMS_T so use it as an identifier.
- * We probably should switch to some more official quirk.
- *
- * UPDATE: This problem affects the M$ Wireless Notebook Optical Mouse,
- * too. However, the leading byte for this mouse is normally 0x11,
- * and the phantom mouse click occurs when its 0x14.
- */
- if (sc->flags & UMS_T) {
- if (sc->sc_iid) {
- if (*ibuf++ == 0x02)
- return;
- }
- } else if (sc->flags & UMS_SPUR_BUT_UP) {
- DPRINTFN(5, ("ums_intr: #### ibuf[0] =3D %d ####\n", *ibuf));
- if (*ibuf == 0x14 || *ibuf == 0x15)
- return;
- } else {
- if (sc->sc_iid) {
- if (*ibuf++ != sc->sc_iid)
- return;
- }
- }
-
- dx = hid_get_data(ibuf, &sc->sc_loc_x);
- dy = -hid_get_data(ibuf, &sc->sc_loc_y);
- dz = -hid_get_data(ibuf, &sc->sc_loc_z);
- dw = hid_get_data(ibuf, &sc->sc_loc_w);
- if (sc->flags & UMS_REVZ)
- dz = -dz;
- if (sc->flags & UMS_T)
- dt = -hid_get_data(ibuf, &sc->sc_loc_t);
- else
- dt = 0;
- for (i = 0; i < sc->nbuttons; i++)
- if (hid_get_data(ibuf, &sc->sc_loc_btn[i]))
- buttons |= (1 << UMS_BUT(i));
-
- if (dx || dy || dz || dt || dw || (sc->flags & UMS_Z)
- || buttons != sc->status.button) {
- DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d w:%d t:%d buttons:0x%x\n",
- dx, dy, dz, dw, dt, buttons));
-
- sc->status.button = buttons;
- sc->status.dx += dx;
- sc->status.dy += dy;
- sc->status.dz += dz;
- /* sc->status.dt += dt; */ /* no way to export this yet */
- /* sc->status.dw += dw; */ /* idem */
-
- /* Discard data in case of full buffer */
- if (sc->qcount == sizeof(sc->qbuf)) {
- DPRINTF(("Buffer full, discarded packet"));
- return;
- }
-
- /*
- * The Qtronix keyboard has a built in PS/2 port for a mouse.
- * The firmware once in a while posts a spurious button up
- * event. This event we ignore by doing a timeout for 50 msecs.
- * If we receive dx=dy=dz=buttons=0 before we add the event to
- * the queue.
- * In any other case we delete the timeout event.
- */
- if (sc->flags & UMS_SPUR_BUT_UP &&
- dx == 0 && dy == 0 && dz == 0 && dt == 0 && buttons == 0) {
- callout_reset(&sc->callout_handle, MS_TO_TICKS(50),
- ums_add_to_queue_timeout, (void *) sc);
- } else {
- callout_stop(&sc->callout_handle);
- ums_add_to_queue(sc, dx, dy, dz, dt, buttons);
- }
- }
-}
-
-static void
-ums_add_to_queue_timeout(void *priv)
-{
- struct ums_softc *sc = priv;
- int s;
-
- s = splusb();
- ums_add_to_queue(sc, 0, 0, 0, 0, 0);
- splx(s);
-}
-
-static void
-ums_add_to_queue(struct ums_softc *sc, int dx, int dy, int dz, int dt, int buttons)
-{
- /* Discard data in case of full buffer */
- if (sc->qhead+sc->mode.packetsize > sizeof(sc->qbuf)) {
- DPRINTF(("Buffer full, discarded packet"));
- return;
- }
-
- if (dx > 254) dx = 254;
- if (dx < -256) dx = -256;
- if (dy > 254) dy = 254;
- if (dy < -256) dy = -256;
- if (dz > 126) dz = 126;
- if (dz < -128) dz = -128;
- if (dt > 126) dt = 126;
- if (dt < -128) dt = -128;
-
- sc->qbuf[sc->qhead] = sc->mode.syncmask[1];
- sc->qbuf[sc->qhead] |= ~buttons & MOUSE_MSC_BUTTONS;
- sc->qbuf[sc->qhead+1] = dx >> 1;
- sc->qbuf[sc->qhead+2] = dy >> 1;
- sc->qbuf[sc->qhead+3] = dx - (dx >> 1);
- sc->qbuf[sc->qhead+4] = dy - (dy >> 1);
-
- if (sc->mode.level == 1) {
- sc->qbuf[sc->qhead+5] = dz >> 1;
- sc->qbuf[sc->qhead+6] = dz - (dz >> 1);
- sc->qbuf[sc->qhead+7] = ((~buttons >> 3)
- & MOUSE_SYS_EXTBUTTONS);
- }
-
- sc->qhead += sc->mode.packetsize;
- sc->qcount += sc->mode.packetsize;
- /* wrap round at end of buffer */
- if (sc->qhead >= sizeof(sc->qbuf))
- sc->qhead = 0;
-
- /* someone waiting for data */
- if (sc->state & UMS_ASLEEP) {
- sc->state &= ~UMS_ASLEEP;
- wakeup(sc);
- }
- if (sc->state & UMS_SELECT) {
- sc->state &= ~UMS_SELECT;
- selwakeuppri(&sc->rsel, PZERO);
- }
-}
-static int
-ums_enable(v)
- void *v;
-{
- struct ums_softc *sc = v;
-
- usbd_status err;
-
- if (sc->sc_enabled)
- return EBUSY;
-
- sc->sc_enabled = 1;
- sc->qcount = 0;
- sc->qhead = sc->qtail = 0;
- sc->status.flags = 0;
- sc->status.button = sc->status.obutton = 0;
- sc->status.dx = sc->status.dy = sc->status.dz /* = sc->status.dt */ = 0;
-
- callout_handle_init((struct callout_handle *)&sc->callout_handle);
-
- /*
- * Force the report (non-boot) protocol.
- *
- * Mice without boot protocol support may choose not to implement
- * Set_Protocol at all; do not check for error.
- */
- usbd_set_protocol(sc->sc_iface, 1);
-
- /* Set up interrupt pipe. */
- err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
- USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc,
- sc->sc_ibuf, sc->sc_isize, ums_intr,
- USBD_DEFAULT_INTERVAL);
- if (err) {
- DPRINTF(("ums_enable: usbd_open_pipe_intr failed, error=%d\n",
- err));
- sc->sc_enabled = 0;
- return (EIO);
- }
- return (0);
-}
-
-static void
-ums_disable(priv)
- void *priv;
-{
- struct ums_softc *sc = priv;
-
- callout_stop(&sc->callout_handle);
-
- /* Disable interrupts. */
- usbd_abort_pipe(sc->sc_intrpipe);
- usbd_close_pipe(sc->sc_intrpipe);
-
- sc->sc_enabled = 0;
-
- if (sc->qcount != 0)
- DPRINTF(("Discarded %d bytes in queue\n", sc->qcount));
-}
-
-static int
-ums_open(struct cdev *dev, int flag, int fmt, struct thread *p)
-{
- struct ums_softc *sc;
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- if (sc == NULL)
- return (ENXIO);
-
- return ums_enable(sc);
-}
-
-static int
-ums_close(struct cdev *dev, int flag, int fmt, struct thread *p)
-{
- struct ums_softc *sc;
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- if (!sc)
- return 0;
-
- if (sc->sc_enabled)
- ums_disable(sc);
-
- return 0;
-}
-
-static int
-ums_read(struct cdev *dev, struct uio *uio, int flag)
-{
- struct ums_softc *sc;
- int s;
- char buf[sizeof(sc->qbuf)];
- int l = 0;
- int error;
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- s = splusb();
- if (!sc) {
- splx(s);
- return EIO;
- }
-
- while (sc->qcount == 0 ) {
- if (flag & O_NONBLOCK) { /* non-blocking I/O */
- splx(s);
- return EWOULDBLOCK;
- }
-
- sc->state |= UMS_ASLEEP; /* blocking I/O */
- error = tsleep(sc, PZERO | PCATCH, "umsrea", 0);
- if (error) {
- splx(s);
- return error;
- } else if (!sc->sc_enabled) {
- splx(s);
- return EINTR;
- }
- /* check whether the device is still there */
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- if (!sc) {
- splx(s);
- return EIO;
- }
- }
-
- /*
- * XXX we could optimise the use of splx/splusb somewhat. The writer
- * process only extends qcount and qtail. We could copy them and use the copies
- * to do the copying out of the queue.
- */
-
- while ((sc->qcount > 0) && (uio->uio_resid > 0)) {
- l = (sc->qcount < uio->uio_resid? sc->qcount:uio->uio_resid);
- if (l > sizeof(buf))
- l = sizeof(buf);
- if (l > sizeof(sc->qbuf) - sc->qtail) /* transfer till end of buf */
- l = sizeof(sc->qbuf) - sc->qtail;
-
- splx(s);
- uiomove(&sc->qbuf[sc->qtail], l, uio);
- s = splusb();
-
- if ( sc->qcount - l < 0 ) {
- DPRINTF(("qcount below 0, count=%d l=%d\n", sc->qcount, l));
- sc->qcount = l;
- }
- sc->qcount -= l; /* remove the bytes from the buffer */
- sc->qtail = (sc->qtail + l) % sizeof(sc->qbuf);
- }
- splx(s);
-
- return 0;
-}
-
-static int
-ums_poll(struct cdev *dev, int events, struct thread *p)
-{
- struct ums_softc *sc;
- int revents = 0;
- int s;
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- if (!sc)
- return 0;
-
- s = splusb();
- if (events & (POLLIN | POLLRDNORM)) {
- if (sc->qcount) {
- revents = events & (POLLIN | POLLRDNORM);
- } else {
- sc->state |= UMS_SELECT;
- selrecord(p, &sc->rsel);
- }
- }
- splx(s);
-
- return revents;
-}
-
-int
-ums_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *p)
-{
- struct ums_softc *sc;
- int error = 0;
- int s;
- mousemode_t mode;
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- if (!sc)
- return EIO;
-
- switch(cmd) {
- case MOUSE_GETHWINFO:
- *(mousehw_t *)addr = sc->hw;
- break;
- case MOUSE_GETMODE:
- *(mousemode_t *)addr = sc->mode;
- break;
- case MOUSE_SETMODE:
- mode = *(mousemode_t *)addr;
-
- if (mode.level == -1)
- /* don't change the current setting */
- ;
- else if ((mode.level < 0) || (mode.level > 1))
- return (EINVAL);
-
- s = splusb();
- sc->mode.level = mode.level;
-
- if (sc->mode.level == 0) {
- if (sc->nbuttons > MOUSE_MSC_MAXBUTTON)
- sc->hw.buttons = MOUSE_MSC_MAXBUTTON;
- else
- sc->hw.buttons = sc->nbuttons;
- sc->mode.protocol = MOUSE_PROTO_MSC;
- sc->mode.packetsize = MOUSE_MSC_PACKETSIZE;
- sc->mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
- sc->mode.syncmask[1] = MOUSE_MSC_SYNC;
- } else if (sc->mode.level == 1) {
- if (sc->nbuttons > MOUSE_SYS_MAXBUTTON)
- sc->hw.buttons = MOUSE_SYS_MAXBUTTON;
- else
- sc->hw.buttons = sc->nbuttons;
- sc->mode.protocol = MOUSE_PROTO_SYSMOUSE;
- sc->mode.packetsize = MOUSE_SYS_PACKETSIZE;
- sc->mode.syncmask[0] = MOUSE_SYS_SYNCMASK;
- sc->mode.syncmask[1] = MOUSE_SYS_SYNC;
- }
-
- bzero(sc->qbuf, sizeof(sc->qbuf));
- sc->qhead = sc->qtail = sc->qcount = 0;
- splx(s);
-
- break;
- case MOUSE_GETLEVEL:
- *(int *)addr = sc->mode.level;
- break;
- case MOUSE_SETLEVEL:
- if (*(int *)addr < 0 || *(int *)addr > 1)
- return (EINVAL);
-
- s = splusb();
- sc->mode.level = *(int *)addr;
-
- if (sc->mode.level == 0) {
- if (sc->nbuttons > MOUSE_MSC_MAXBUTTON)
- sc->hw.buttons = MOUSE_MSC_MAXBUTTON;
- else
- sc->hw.buttons = sc->nbuttons;
- sc->mode.protocol = MOUSE_PROTO_MSC;
- sc->mode.packetsize = MOUSE_MSC_PACKETSIZE;
- sc->mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
- sc->mode.syncmask[1] = MOUSE_MSC_SYNC;
- } else if (sc->mode.level == 1) {
- if (sc->nbuttons > MOUSE_SYS_MAXBUTTON)
- sc->hw.buttons = MOUSE_SYS_MAXBUTTON;
- else
- sc->hw.buttons = sc->nbuttons;
- sc->mode.protocol = MOUSE_PROTO_SYSMOUSE;
- sc->mode.packetsize = MOUSE_SYS_PACKETSIZE;
- sc->mode.syncmask[0] = MOUSE_SYS_SYNCMASK;
- sc->mode.syncmask[1] = MOUSE_SYS_SYNC;
- }
-
- bzero(sc->qbuf, sizeof(sc->qbuf));
- sc->qhead = sc->qtail = sc->qcount = 0;
- splx(s);
-
- break;
- case MOUSE_GETSTATUS: {
- mousestatus_t *status = (mousestatus_t *) addr;
-
- s = splusb();
- *status = sc->status;
- sc->status.obutton = sc->status.button;
- sc->status.button = 0;
- sc->status.dx = sc->status.dy
- = sc->status.dz = /* sc->status.dt = */ 0;
- splx(s);
-
- if (status->dx || status->dy || status->dz /* || status->dt */)
- status->flags |= MOUSE_POSCHANGED;
- if (status->button != status->obutton)
- status->flags |= MOUSE_BUTTONSCHANGED;
- break;
- }
- default:
- error = ENOTTY;
- }
-
- return error;
-}
-
-MODULE_DEPEND(ums, usb, 1, 1, 1);
-DRIVER_MODULE(ums, uhub, ums_driver, ums_devclass, usbd_driver_load, 0);
diff --git a/sys/legacy/dev/usb/uplcom.c b/sys/legacy/dev/usb/uplcom.c
deleted file mode 100644
index ab5ab93..0000000
--- a/sys/legacy/dev/usb/uplcom.c
+++ /dev/null
@@ -1,990 +0,0 @@
-/* $NetBSD: uplcom.c,v 1.21 2001/11/13 06:24:56 lukem Exp $ */
-
-/*-
- * Copyright (c) 2001-2003, 2005 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Ichiro FUKUHARA (ichiro@ichiro.org).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This driver supports several USB-to-RS232 serial adapters driven by
- * Prolific PL-2303, PL-2303X and probably PL-2303HX USB-to-RS232
- * bridge chip. The adapters are sold under many different brand
- * names.
- *
- * Datasheets are available at Prolific www site at
- * http://www.prolific.com.tw. The datasheets don't contain full
- * programming information for the chip.
- *
- * PL-2303HX is probably programmed the same as PL-2303X.
- *
- * There are several differences between PL-2303 and PL-2303(H)X.
- * PL-2303(H)X can do higher bitrate in bulk mode, has _probably_
- * different command for controlling CRTSCTS and needs special
- * sequence of commands for initialization which aren't also
- * documented in the datasheet.
- */
-
-#include "opt_uplcom.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-#include <sys/taskqueue.h>
-
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-SYSCTL_NODE(_hw_usb, OID_AUTO, uplcom, CTLFLAG_RW, 0, "USB uplcom");
-#ifdef USB_DEBUG
-static int uplcomdebug = 0;
-SYSCTL_INT(_hw_usb_uplcom, OID_AUTO, debug, CTLFLAG_RW,
- &uplcomdebug, 0, "uplcom debug level");
-
-#define DPRINTFN(n, x) do { \
- if (uplcomdebug > (n)) \
- printf x; \
- } while (0)
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define UPLCOM_MODVER 1 /* module version */
-
-#define UPLCOM_CONFIG_INDEX 0
-#define UPLCOM_IFACE_INDEX 0
-#define UPLCOM_SECOND_IFACE_INDEX 1
-
-#ifndef UPLCOM_INTR_INTERVAL
-#define UPLCOM_INTR_INTERVAL 100 /* ms */
-#endif
-
-#define UPLCOM_SET_REQUEST 0x01
-#define UPLCOM_SET_CRTSCTS 0x41
-#define UPLCOM_SET_CRTSCTS_PL2303X 0x61
-#define RSAQ_STATUS_CTS 0x80
-#define RSAQ_STATUS_DSR 0x02
-#define RSAQ_STATUS_DCD 0x01
-
-#define TYPE_PL2303 0
-#define TYPE_PL2303X 1
-
-struct uplcom_softc {
- struct ucom_softc sc_ucom;
-
- int sc_iface_number; /* interface number */
-
- usbd_interface_handle sc_intr_iface; /* interrupt interface */
- int sc_intr_number; /* interrupt number */
- usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */
- u_char *sc_intr_buf; /* interrupt buffer */
- int sc_isize;
-
- usb_cdc_line_state_t sc_line_state; /* current line state */
- u_char sc_dtr; /* current DTR state */
- u_char sc_rts; /* current RTS state */
- u_char sc_status;
-
- u_char sc_lsr; /* Local status register */
- u_char sc_msr; /* uplcom status register */
-
- int sc_chiptype; /* Type of chip */
-
- struct task sc_task;
-};
-
-/*
- * These are the maximum number of bytes transferred per frame.
- * The output buffer size cannot be increased due to the size encoding.
- */
-#define UPLCOMIBUFSIZE 256
-#define UPLCOMOBUFSIZE 256
-
-static usbd_status uplcom_reset(struct uplcom_softc *);
-static usbd_status uplcom_set_line_coding(struct uplcom_softc *,
- usb_cdc_line_state_t *);
-static usbd_status uplcom_set_crtscts(struct uplcom_softc *);
-static void uplcom_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-
-static void uplcom_set(void *, int, int, int);
-static void uplcom_dtr(struct uplcom_softc *, int);
-static void uplcom_rts(struct uplcom_softc *, int);
-static void uplcom_break(struct uplcom_softc *, int);
-static void uplcom_set_line_state(struct uplcom_softc *);
-static void uplcom_get_status(void *, int, u_char *, u_char *);
-static int uplcom_param(void *, int, struct termios *);
-static int uplcom_open(void *, int);
-static void uplcom_close(void *, int);
-static void uplcom_notify(void *, int);
-
-struct ucom_callback uplcom_callback = {
- uplcom_get_status,
- uplcom_set,
- uplcom_param,
- NULL,
- uplcom_open,
- uplcom_close,
- NULL,
- NULL
-};
-
-static const struct uplcom_product {
- uint16_t vendor;
- uint16_t product;
- int32_t release; /* release is a 16bit entity,
- * if -1 is specified we "don't care"
- * This is a floor value. The table
- * must have newer revs before older
- * revs (and -1 last).
- */
- char chiptype;
-} uplcom_products [] = {
- { USB_VENDOR_RADIOSHACK, USB_PRODUCT_RADIOSHACK_USBCABLE, -1, TYPE_PL2303 },
-
- /* I/O DATA USB-RSAQ */
- { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBRSAQ, -1, TYPE_PL2303 },
- /* Prolific Pharos */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PHAROS, -1, TYPE_PL2303 },
- /* I/O DATA USB-RSAQ2 */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ2, -1, TYPE_PL2303 },
- /* I/O DATA USB-RSAQ3 */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ3, -1, TYPE_PL2303X },
- /* Willcom W-SIM*/
- { USB_VENDOR_PROLIFIC2, USB_PRODUCT_PROLIFIC2_WSIM, -1, TYPE_PL2303X},
- /* PLANEX USB-RS232 URS-03 */
- { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC232A, -1, TYPE_PL2303 },
- /* TrendNet TU-S9 */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303,
- 0x400, TYPE_PL2303X },
- /* ST Lab USB-SERIAL-4 */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303,
- 0x300, TYPE_PL2303X },
- /* IOGEAR/ATEN UC-232A (also ST Lab USB-SERIAL-1) */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, -1, TYPE_PL2303 },
- /* TDK USB-PHS Adapter UHA6400 */
- { USB_VENDOR_TDK, USB_PRODUCT_TDK_UHA6400, -1, TYPE_PL2303 },
- /* RATOC REX-USB60 */
- { USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60, -1, TYPE_PL2303 },
- /* ELECOM UC-SGT */
- { USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT, -1, TYPE_PL2303 },
- { USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT0, -1, TYPE_PL2303 },
- /* Sagem USB-Serial Controller */
- { USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_USBSERIAL, -1, TYPE_PL2303X },
- /* Sony Ericsson USB Cable */
- { USB_VENDOR_SONYERICSSON, USB_PRODUCT_SONYERICSSON_DCU10,
- -1,TYPE_PL2303 },
- /* SOURCENEXT KeikaiDenwa 8 */
- { USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8,
- -1, TYPE_PL2303 },
- /* SOURCENEXT KeikaiDenwa 8 with charger */
- { USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG,
- -1, TYPE_PL2303 },
- /* HAL Corporation Crossam2+USB */
- { USB_VENDOR_HAL, USB_PRODUCT_HAL_IMR001, -1, TYPE_PL2303 },
- /* Sitecom USB to Serial */
- { USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_SERIAL, -1, TYPE_PL2303 },
- /* Tripp-Lite U209-000-R */
- { USB_VENDOR_TRIPPLITE, USB_PRODUCT_TRIPPLITE_U209, -1, TYPE_PL2303X },
- /* Belkin F5U257 */
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U257, -1, TYPE_PL2303X },
- { 0, 0 }
-};
-
-static device_probe_t uplcom_match;
-static device_attach_t uplcom_attach;
-static device_detach_t uplcom_detach;
-
-static device_method_t uplcom_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uplcom_match),
- DEVMETHOD(device_attach, uplcom_attach),
- DEVMETHOD(device_detach, uplcom_detach),
- { 0, 0 }
-};
-
-static driver_t uplcom_driver = {
- "ucom",
- uplcom_methods,
- sizeof (struct uplcom_softc)
-};
-
-DRIVER_MODULE(uplcom, uhub, uplcom_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uplcom, usb, 1, 1, 1);
-MODULE_DEPEND(uplcom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(uplcom, UPLCOM_MODVER);
-
-static int uplcominterval = UPLCOM_INTR_INTERVAL;
-
-static int
-sysctl_hw_usb_uplcom_interval(SYSCTL_HANDLER_ARGS)
-{
- int err, val;
-
- val = uplcominterval;
- err = sysctl_handle_int(oidp, &val, 0, req);
- if (err != 0 || req->newptr == NULL)
- return (err);
- if (0 < val && val <= 1000)
- uplcominterval = val;
- else
- err = EINVAL;
-
- return (err);
-}
-
-SYSCTL_PROC(_hw_usb_uplcom, OID_AUTO, interval, CTLTYPE_INT | CTLFLAG_RW,
- 0, sizeof(int), sysctl_hw_usb_uplcom_interval,
- "I", "uplcom interrupt pipe interval");
-
-static int
-uplcom_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- int i;
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- for (i = 0; uplcom_products[i].vendor != 0; i++) {
- if (uplcom_products[i].vendor == uaa->vendor &&
- uplcom_products[i].product == uaa->product &&
- (uplcom_products[i].release <= uaa->release ||
- uplcom_products[i].release == -1)) {
- return (UMATCH_VENDOR_PRODUCT);
- }
- }
- return (UMATCH_NONE);
-}
-
-static int
-uplcom_attach(device_t self)
-{
- struct uplcom_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- struct ucom_softc *ucom;
- usb_config_descriptor_t *cdesc;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- const char *devname;
- usbd_status err;
- int i;
-
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- devname = device_get_nameunit(ucom->sc_dev);
-
- DPRINTF(("uplcom attach: sc = %p\n", sc));
-
- /* determine chip type */
- for (i = 0; uplcom_products[i].vendor != 0; i++) {
- if (uplcom_products[i].vendor == uaa->vendor &&
- uplcom_products[i].product == uaa->product &&
- (uplcom_products[i].release == uaa->release ||
- uplcom_products[i].release == -1)) {
- sc->sc_chiptype = uplcom_products[i].chiptype;
- break;
- }
- }
-
- /*
- * check we found the device - attach should have ensured we
- * don't get here without matching device
- */
- if (uplcom_products[i].vendor == 0) {
- printf("%s: didn't match\n", devname);
- ucom->sc_dying = 1;
- goto error;
- }
-
-#ifdef USB_DEBUG
- /* print the chip type */
- if (sc->sc_chiptype == TYPE_PL2303X) {
- DPRINTF(("uplcom_attach: chiptype 2303X\n"));
- } else {
- DPRINTF(("uplcom_attach: chiptype 2303\n"));
- }
-#endif
-
- /* initialize endpoints */
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- sc->sc_intr_number = -1;
- sc->sc_intr_pipe = NULL;
-
- /* Move the device into the configured state. */
- err = usbd_set_config_index(dev, UPLCOM_CONFIG_INDEX, 1);
- if (err) {
- printf("%s: failed to set configuration: %s\n",
- devname, usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* get the config descriptor */
- cdesc = usbd_get_config_descriptor(ucom->sc_udev);
-
- if (cdesc == NULL) {
- printf("%s: failed to get configuration descriptor\n",
- device_get_nameunit(ucom->sc_dev));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* get the (first/common) interface */
- err = usbd_device2interface_handle(dev, UPLCOM_IFACE_INDEX,
- &ucom->sc_iface);
- if (err) {
- printf("%s: failed to get interface: %s\n",
- devname, usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* Find the interrupt endpoints */
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
- sc->sc_iface_number = id->bInterfaceNumber;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- printf("%s: no endpoint descriptor for %d\n",
- device_get_nameunit(ucom->sc_dev), i);
- ucom->sc_dying = 1;
- goto error;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- sc->sc_intr_number = ed->bEndpointAddress;
- sc->sc_isize = UGETW(ed->wMaxPacketSize);
- }
- }
-
- if (sc->sc_intr_number == -1) {
- printf("%s: Could not find interrupt in\n",
- device_get_nameunit(ucom->sc_dev));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* keep interface for interrupt */
- sc->sc_intr_iface = ucom->sc_iface;
-
- /*
- * USB-RSAQ1 has two interface
- *
- * USB-RSAQ1 | USB-RSAQ2
- * -----------------+-----------------
- * Interface 0 |Interface 0
- * Interrupt(0x81) | Interrupt(0x81)
- * -----------------+ BulkIN(0x02)
- * Interface 1 | BulkOUT(0x83)
- * BulkIN(0x02) |
- * BulkOUT(0x83) |
- */
- if (cdesc->bNumInterface == 2) {
- err = usbd_device2interface_handle(dev,
- UPLCOM_SECOND_IFACE_INDEX,
- &ucom->sc_iface);
- if (err) {
- printf("%s: failed to get second interface: %s\n",
- devname, usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
- }
-
- /* Find the bulk{in,out} endpoints */
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
- sc->sc_iface_number = id->bInterfaceNumber;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- printf("%s: no endpoint descriptor for %d\n",
- device_get_nameunit(ucom->sc_dev), i);
- ucom->sc_dying = 1;
- goto error;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
- }
-
- if (ucom->sc_bulkin_no == -1) {
- printf("%s: Could not find data bulk in\n",
- device_get_nameunit(ucom->sc_dev));
- ucom->sc_dying = 1;
- goto error;
- }
-
- if (ucom->sc_bulkout_no == -1) {
- printf("%s: Could not find data bulk out\n",
- device_get_nameunit(ucom->sc_dev));
- ucom->sc_dying = 1;
- goto error;
- }
-
- sc->sc_dtr = sc->sc_rts = -1;
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = UPLCOMIBUFSIZE;
- ucom->sc_obufsize = UPLCOMOBUFSIZE;
- ucom->sc_ibufsizepad = UPLCOMIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &uplcom_callback;
-
- err = uplcom_reset(sc);
-
- if (err) {
- printf("%s: reset failed: %s\n",
- device_get_nameunit(ucom->sc_dev), usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- DPRINTF(("uplcom: in = 0x%x, out = 0x%x, intr = 0x%x\n",
- ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number));
-
- TASK_INIT(&sc->sc_task, 0, uplcom_notify, sc);
- ucom_attach(&sc->sc_ucom);
- return 0;
-
-error:
- return ENXIO;
-}
-
-static int
-uplcom_detach(device_t self)
-{
- struct uplcom_softc *sc = device_get_softc(self);
- int rv = 0;
-
- DPRINTF(("uplcom_detach: sc = %p\n", sc));
-
- if (sc->sc_intr_pipe != NULL) {
- usbd_abort_pipe(sc->sc_intr_pipe);
- usbd_close_pipe(sc->sc_intr_pipe);
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-
- sc->sc_ucom.sc_dying = 1;
-
- rv = ucom_detach(&sc->sc_ucom);
-
- return (rv);
-}
-
-static usbd_status
-uplcom_reset(struct uplcom_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UPLCOM_SET_REQUEST;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err) {
- printf("%s: uplcom_reset: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- return (EIO);
- }
-
- return (0);
-}
-
-struct pl2303x_init {
- uint8_t req_type;
- uint8_t request;
- uint16_t value;
- uint16_t index;
- uint16_t length;
-};
-
-static const struct pl2303x_init pl2303x[] = {
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8484, 0, 0 },
- { UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x0404, 0, 0 },
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8484, 0, 0 },
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8383, 0, 0 },
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8484, 0, 0 },
- { UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x0404, 1, 0 },
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8484, 0, 0 },
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8383, 0, 0 },
- { UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0, 1, 0 },
- { UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 1, 0, 0 },
- { UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 2, 0x44, 0 }
-};
-#define N_PL2302X_INIT (sizeof(pl2303x)/sizeof(pl2303x[0]))
-
-static usbd_status
-uplcom_pl2303x_init(struct uplcom_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
- int i;
-
- for (i = 0; i < N_PL2302X_INIT; i++) {
- req.bmRequestType = pl2303x[i].req_type;
- req.bRequest = pl2303x[i].request;
- USETW(req.wValue, pl2303x[i].value);
- USETW(req.wIndex, pl2303x[i].index);
- USETW(req.wLength, pl2303x[i].length);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err) {
- printf("%s: uplcom_pl2303x_init: %d: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), i,
- usbd_errstr(err));
- return (EIO);
- }
- }
-
- return (0);
-}
-
-static void
-uplcom_set_line_state(struct uplcom_softc *sc)
-{
- usb_device_request_t req;
- int ls;
- usbd_status err;
-
- ls = (sc->sc_dtr ? UCDC_LINE_DTR : 0) |
- (sc->sc_rts ? UCDC_LINE_RTS : 0);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, ls);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err)
- printf("%s: uplcom_set_line_status: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
-}
-
-static void
-uplcom_set(void *addr, int portno, int reg, int onoff)
-{
- struct uplcom_softc *sc = addr;
-
- switch (reg) {
- case UCOM_SET_DTR:
- uplcom_dtr(sc, onoff);
- break;
- case UCOM_SET_RTS:
- uplcom_rts(sc, onoff);
- break;
- case UCOM_SET_BREAK:
- uplcom_break(sc, onoff);
- break;
- default:
- break;
- }
-}
-
-static void
-uplcom_dtr(struct uplcom_softc *sc, int onoff)
-{
- DPRINTF(("uplcom_dtr: onoff = %d\n", onoff));
-
- if (sc->sc_dtr == onoff)
- return;
- sc->sc_dtr = onoff;
-
- uplcom_set_line_state(sc);
-}
-
-static void
-uplcom_rts(struct uplcom_softc *sc, int onoff)
-{
- DPRINTF(("uplcom_rts: onoff = %d\n", onoff));
-
- if (sc->sc_rts == onoff)
- return;
- sc->sc_rts = onoff;
-
- uplcom_set_line_state(sc);
-}
-
-static void
-uplcom_break(struct uplcom_softc *sc, int onoff)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("uplcom_break: onoff = %d\n", onoff));
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
- USETW(req.wValue, onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err)
- printf("%s: uplcom_break: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
-}
-
-static usbd_status
-uplcom_set_crtscts(struct uplcom_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("uplcom_set_crtscts: on\n"));
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UPLCOM_SET_REQUEST;
- USETW(req.wValue, 0);
- if (sc->sc_chiptype == TYPE_PL2303X)
- USETW(req.wIndex, UPLCOM_SET_CRTSCTS_PL2303X);
- else
- USETW(req.wIndex, UPLCOM_SET_CRTSCTS);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err) {
- printf("%s: uplcom_set_crtscts: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uplcom_set_line_coding(struct uplcom_softc *sc, usb_cdc_line_state_t *state)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF((
-"uplcom_set_line_coding: rate = %d, fmt = %d, parity = %d bits = %d\n",
- UGETDW(state->dwDTERate), state->bCharFormat,
- state->bParityType, state->bDataBits));
-
- if (memcmp(state, &sc->sc_line_state, UCDC_LINE_STATE_LENGTH) == 0) {
- DPRINTF(("uplcom_set_line_coding: already set\n"));
- return (USBD_NORMAL_COMPLETION);
- }
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_LINE_CODING;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, UCDC_LINE_STATE_LENGTH);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, state);
- if (err) {
- printf("%s: uplcom_set_line_coding: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- return (err);
- }
-
- sc->sc_line_state = *state;
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static const int uplcom_rates[] = {
- 75, 150, 300, 600, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 14400,
- 19200, 28800, 38400, 57600, 115200,
- /*
- * Higher speeds are probably possible. PL2303X supports up to
- * 6Mb and can set any rate
- */
- 230400, 460800, 614400, 921600, 1228800
-};
-#define N_UPLCOM_RATES (sizeof(uplcom_rates)/sizeof(uplcom_rates[0]))
-
-static int
-uplcom_param(void *addr, int portno, struct termios *t)
-{
- struct uplcom_softc *sc = addr;
- usbd_status err;
- usb_cdc_line_state_t ls;
- int i;
-
- DPRINTF(("uplcom_param: sc = %p\n", sc));
-
- /* Check requested baud rate */
- for (i = 0; i < N_UPLCOM_RATES; i++)
- if (uplcom_rates[i] == t->c_ospeed)
- break;
- if (i == N_UPLCOM_RATES) {
- DPRINTF(("uplcom_param: bad baud rate (%d)\n", t->c_ospeed));
- return (EIO);
- }
-
- USETDW(ls.dwDTERate, t->c_ospeed);
- if (ISSET(t->c_cflag, CSTOPB))
- ls.bCharFormat = UCDC_STOP_BIT_2;
- else
- ls.bCharFormat = UCDC_STOP_BIT_1;
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- ls.bParityType = UCDC_PARITY_ODD;
- else
- ls.bParityType = UCDC_PARITY_EVEN;
- } else
- ls.bParityType = UCDC_PARITY_NONE;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- ls.bDataBits = 5;
- break;
- case CS6:
- ls.bDataBits = 6;
- break;
- case CS7:
- ls.bDataBits = 7;
- break;
- case CS8:
- ls.bDataBits = 8;
- break;
- }
-
- err = uplcom_set_line_coding(sc, &ls);
- if (err)
- return (EIO);
-
- if (ISSET(t->c_cflag, CRTSCTS)) {
- err = uplcom_set_crtscts(sc);
- if (err)
- return (EIO);
- }
-
- return (0);
-}
-
-static int
-uplcom_open(void *addr, int portno)
-{
- struct uplcom_softc *sc = addr;
- int err;
-
- if (sc->sc_ucom.sc_dying)
- return (ENXIO);
-
- DPRINTF(("uplcom_open: sc = %p\n", sc));
-
- if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
- sc->sc_status = 0; /* clear status bit */
- sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
- err = usbd_open_pipe_intr(sc->sc_intr_iface,
- sc->sc_intr_number,
- USBD_SHORT_XFER_OK,
- &sc->sc_intr_pipe,
- sc,
- sc->sc_intr_buf,
- sc->sc_isize,
- uplcom_intr,
- uplcominterval);
- if (err) {
- printf("%s: cannot open interrupt pipe (addr %d)\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- sc->sc_intr_number);
- return (EIO);
- }
- }
-
- if (sc->sc_chiptype == TYPE_PL2303X)
- return (uplcom_pl2303x_init(sc));
-
- return (0);
-}
-
-static void
-uplcom_close(void *addr, int portno)
-{
- struct uplcom_softc *sc = addr;
- int err;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- DPRINTF(("uplcom_close: close\n"));
-
- if (sc->sc_intr_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_intr_pipe);
- if (err)
- printf("%s: abort interrupt pipe failed: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_intr_pipe);
- if (err)
- printf("%s: close interrupt pipe failed: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- usbd_errstr(err));
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-}
-
-static void
-uplcom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct uplcom_softc *sc = priv;
- u_char *buf = sc->sc_intr_buf;
- u_char pstatus;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- DPRINTF(("%s: uplcom_intr: abnormal status: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- usbd_errstr(status)));
- usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
- return;
- }
-
- DPRINTF(("%s: uplcom status = %02x\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), buf[8]));
-
- sc->sc_lsr = sc->sc_msr = 0;
- pstatus = buf[8];
- if (ISSET(pstatus, RSAQ_STATUS_CTS))
- sc->sc_msr |= SER_CTS;
- else
- sc->sc_msr &= ~SER_CTS;
- if (ISSET(pstatus, RSAQ_STATUS_DSR))
- sc->sc_msr |= SER_DSR;
- else
- sc->sc_msr &= ~SER_DSR;
- if (ISSET(pstatus, RSAQ_STATUS_DCD))
- sc->sc_msr |= SER_DCD;
- else
- sc->sc_msr &= ~SER_DCD;
-
- /* Deferred notifying to the ucom layer */
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
-}
-
-static void
-uplcom_notify(void *arg, int count)
-{
- struct uplcom_softc *sc;
-
- sc = (struct uplcom_softc *)arg;
- if (sc->sc_ucom.sc_dying)
- return;
- ucom_status_change(&sc->sc_ucom);
-}
-
-static void
-uplcom_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct uplcom_softc *sc = addr;
-
- DPRINTF(("uplcom_get_status:\n"));
-
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-}
diff --git a/sys/legacy/dev/usb/urio.c b/sys/legacy/dev/usb/urio.c
deleted file mode 100644
index 5f69918..0000000
--- a/sys/legacy/dev/usb/urio.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/*-
- * Copyright (c) 2000 Iwasa Kazmi
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This code is based on ugen.c and ulpt.c developed by Lennart Augustsson.
- * This code includes software developed by the NetBSD Foundation, Inc. and
- * its contributors.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-
-/*
- * 2000/3/24 added NetBSD/OpenBSD support (from Alex Nemirovsky)
- * 2000/3/07 use two bulk-pipe handles for read and write (Dirk)
- * 2000/3/06 change major number(143), and copyright header
- * some fix for 4.0 (Dirk)
- * 2000/3/05 codes for FreeBSD 4.x - CURRENT (Thanks to Dirk-Willem van Gulik)
- * 2000/3/01 remove retry code from urioioctl()
- * change method of bulk transfer (no interrupt)
- * 2000/2/28 small fixes for new rio_usb.h
- * 2000/2/24 first version.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/conf.h>
-#include <sys/uio.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include "usbdevs.h"
-#include <dev/usb/rio500_usb.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (uriodebug) printf x
-#define DPRINTFN(n,x) if (uriodebug>(n)) printf x
-int uriodebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, urio, CTLFLAG_RW, 0, "USB urio");
-SYSCTL_INT(_hw_usb_urio, OID_AUTO, debug, CTLFLAG_RW,
- &uriodebug, 0, "urio debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-/* difference of usbd interface */
-#define USBDI 1
-
-#define RIO_OUT 0
-#define RIO_IN 1
-#define RIO_NODIR 2
-
-d_open_t urioopen;
-d_close_t urioclose;
-d_read_t urioread;
-d_write_t uriowrite;
-d_ioctl_t urioioctl;
-
-
-static struct cdevsw urio_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = urioopen,
- .d_close = urioclose,
- .d_read = urioread,
- .d_write = uriowrite,
- .d_ioctl = urioioctl,
- .d_name = "urio",
-};
-#define RIO_UE_GET_DIR(p) ((UE_GET_DIR(p) == UE_DIR_IN) ? RIO_IN :\
- ((UE_GET_DIR(p) == UE_DIR_OUT) ? RIO_OUT :\
- RIO_NODIR))
-
-#define URIO_BBSIZE 1024
-
-struct urio_softc {
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
-
- int sc_opened;
- usbd_pipe_handle sc_pipeh_in;
- usbd_pipe_handle sc_pipeh_out;
- int sc_epaddr[2];
-
- int sc_refcnt;
- struct cdev *sc_dev_t;
- u_char sc_dying;
-};
-
-#define URIOUNIT(n) (dev2unit(n))
-
-#define RIO_RW_TIMEOUT 4000 /* ms */
-
-static device_probe_t urio_match;
-static device_attach_t urio_attach;
-static device_detach_t urio_detach;
-
-static device_method_t urio_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, urio_match),
- DEVMETHOD(device_attach, urio_attach),
- DEVMETHOD(device_detach, urio_detach),
-
- { 0, 0 }
-};
-
-static driver_t urio_driver = {
- "urio",
- urio_methods,
- sizeof(struct urio_softc)
-};
-
-static devclass_t urio_devclass;
-
-static int
-urio_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_device_descriptor_t *dd;
-
- DPRINTFN(10,("urio_match\n"));
- if (!uaa->iface)
- return UMATCH_NONE;
-
- dd = usbd_get_device_descriptor(uaa->device);
-
- if (dd &&
- ((UGETW(dd->idVendor) == USB_VENDOR_DIAMOND &&
- UGETW(dd->idProduct) == USB_PRODUCT_DIAMOND_RIO500USB) ||
- (UGETW(dd->idVendor) == USB_VENDOR_DIAMOND2 &&
- (UGETW(dd->idProduct) == USB_PRODUCT_DIAMOND2_RIO600USB ||
- UGETW(dd->idProduct) == USB_PRODUCT_DIAMOND2_RIO800USB))))
- return UMATCH_VENDOR_PRODUCT;
- else
- return UMATCH_NONE;
-}
-
-static int
-urio_attach(device_t self)
-{
- struct urio_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle udev;
- usbd_interface_handle iface;
- u_int8_t epcount;
- usbd_status r;
- char * ermsg = "<none>";
- int i;
-
- DPRINTFN(10,("urio_attach: sc=%p\n", sc));
- sc->sc_dev = self;
- sc->sc_udev = udev = uaa->device;
-
- if ((!uaa->device) || (!uaa->iface)) {
- ermsg = "device or iface";
- goto nobulk;
- }
- sc->sc_iface = iface = uaa->iface;
- sc->sc_opened = 0;
- sc->sc_pipeh_in = 0;
- sc->sc_pipeh_out = 0;
- sc->sc_refcnt = 0;
-
- r = usbd_endpoint_count(iface, &epcount);
- if (r != USBD_NORMAL_COMPLETION) {
- ermsg = "endpoints";
- goto nobulk;
- }
-
- sc->sc_epaddr[RIO_OUT] = 0xff;
- sc->sc_epaddr[RIO_IN] = 0x00;
-
- for (i = 0; i < epcount; i++) {
- usb_endpoint_descriptor_t *edesc =
- usbd_interface2endpoint_descriptor(iface, i);
- int d;
-
- if (!edesc) {
- ermsg = "interface endpoint";
- goto nobulk;
- }
-
- d = RIO_UE_GET_DIR(edesc->bEndpointAddress);
- if (d != RIO_NODIR)
- sc->sc_epaddr[d] = edesc->bEndpointAddress;
- }
- if ( sc->sc_epaddr[RIO_OUT] == 0xff ||
- sc->sc_epaddr[RIO_IN] == 0x00) {
- ermsg = "Rio I&O";
- goto nobulk;
- }
-
- sc->sc_dev_t = make_dev(&urio_cdevsw, device_get_unit(self),
- UID_ROOT, GID_OPERATOR,
- 0644, "urio%d", device_get_unit(self));
- DPRINTFN(10, ("urio_attach: %p\n", sc->sc_udev));
-
- return 0;
-
- nobulk:
- printf("%s: could not find %s\n", device_get_nameunit(sc->sc_dev),ermsg);
- return ENXIO;
-}
-
-
-int
-urioopen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct urio_softc * sc;
- int unit = URIOUNIT(dev);
- sc = devclass_get_softc(urio_devclass, unit);
- if (sc == NULL)
- return (ENXIO);
-
- DPRINTFN(5, ("urioopen: flag=%d, mode=%d, unit=%d\n",
- flag, mode, unit));
-
- if (sc->sc_opened)
- return EBUSY;
-
- if ((flag & (FWRITE|FREAD)) != (FWRITE|FREAD))
- return EACCES;
-
- sc->sc_opened = 1;
- sc->sc_pipeh_in = 0;
- sc->sc_pipeh_out = 0;
- if (usbd_open_pipe(sc->sc_iface,
- sc->sc_epaddr[RIO_IN], 0, &sc->sc_pipeh_in)
- != USBD_NORMAL_COMPLETION)
- {
- sc->sc_pipeh_in = 0;
- return EIO;
- };
- if (usbd_open_pipe(sc->sc_iface,
- sc->sc_epaddr[RIO_OUT], 0, &sc->sc_pipeh_out)
- != USBD_NORMAL_COMPLETION)
- {
- usbd_close_pipe(sc->sc_pipeh_in);
- sc->sc_pipeh_in = 0;
- sc->sc_pipeh_out = 0;
- return EIO;
- };
- return 0;
-}
-
-int
-urioclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct urio_softc * sc;
- int unit = URIOUNIT(dev);
- sc = devclass_get_softc(urio_devclass, unit);
-
- DPRINTFN(5, ("urioclose: flag=%d, mode=%d, unit=%d\n", flag, mode, unit));
- if (sc->sc_pipeh_in)
- usbd_close_pipe(sc->sc_pipeh_in);
-
- if (sc->sc_pipeh_out)
- usbd_close_pipe(sc->sc_pipeh_out);
-
- sc->sc_pipeh_in = 0;
- sc->sc_pipeh_out = 0;
- sc->sc_opened = 0;
- sc->sc_refcnt = 0;
- return 0;
-}
-
-int
-urioread(struct cdev *dev, struct uio *uio, int flag)
-{
- struct urio_softc * sc;
- usbd_xfer_handle reqh;
- int unit = URIOUNIT(dev);
- usbd_status r;
- char buf[URIO_BBSIZE];
- u_int32_t n, tn;
- int error = 0;
-
- sc = devclass_get_softc(urio_devclass, unit);
-
- DPRINTFN(5, ("urioread: %d\n", unit));
- if (!sc->sc_opened)
- return EIO;
-
- sc->sc_refcnt++;
- reqh = usbd_alloc_xfer(sc->sc_udev);
- if (reqh == 0)
- return ENOMEM;
- while ((n = min(URIO_BBSIZE, uio->uio_resid)) != 0) {
- DPRINTFN(1, ("urioread: start transfer %d bytes\n", n));
- tn = n;
- usbd_setup_xfer(reqh, sc->sc_pipeh_in, 0, buf, tn,
- 0, RIO_RW_TIMEOUT, 0);
- r = usbd_sync_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION) {
- DPRINTFN(1, ("urioread: error=%d\n", r));
- usbd_clear_endpoint_stall(sc->sc_pipeh_in);
- tn = 0;
- error = EIO;
- break;
- }
- usbd_get_xfer_status(reqh, 0, 0, &tn, 0);
-
- DPRINTFN(1, ("urioread: got %d bytes\n", tn));
- error = uiomove(buf, tn, uio);
- if (error || tn < n)
- break;
- }
- usbd_free_xfer(reqh);
- return error;
-}
-
-int
-uriowrite(struct cdev *dev, struct uio *uio, int flag)
-{
- struct urio_softc * sc;
- usbd_xfer_handle reqh;
- int unit = URIOUNIT(dev);
- usbd_status r;
- char buf[URIO_BBSIZE];
- u_int32_t n;
- int error = 0;
-
- sc = devclass_get_softc(urio_devclass, unit);
- DPRINTFN(5, ("uriowrite: %d\n", unit));
- if (!sc->sc_opened)
- return EIO;
-
- sc->sc_refcnt++;
- reqh = usbd_alloc_xfer(sc->sc_udev);
- if (reqh == 0)
- return EIO;
- while ((n = min(URIO_BBSIZE, uio->uio_resid)) != 0) {
- error = uiomove(buf, n, uio);
- if (error)
- break;
- DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n));
- usbd_setup_xfer(reqh, sc->sc_pipeh_out, 0, buf, n,
- 0, RIO_RW_TIMEOUT, 0);
- r = usbd_sync_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION) {
- DPRINTFN(1, ("uriowrite: error=%d\n", r));
- usbd_clear_endpoint_stall(sc->sc_pipeh_out);
- error = EIO;
- break;
- }
- usbd_get_xfer_status(reqh, 0, 0, 0, 0);
- }
-
- usbd_free_xfer(reqh);
- return error;
-}
-
-
-int
-urioioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *p)
-{
- struct urio_softc * sc;
- int unit = URIOUNIT(dev);
- struct RioCommand *rio_cmd;
- int requesttype, len;
- struct iovec iov;
- struct uio uio;
- usb_device_request_t req;
- int req_flags = 0, req_actlen = 0;
- void *ptr = 0;
- int error = 0;
- usbd_status r;
-
- sc = devclass_get_softc(urio_devclass, unit);
- switch (cmd) {
- case RIO_RECV_COMMAND:
- if (!(flag & FWRITE))
- return EPERM;
- rio_cmd = (struct RioCommand *)addr;
- if (rio_cmd == NULL)
- return EINVAL;
- len = rio_cmd->length;
-
- requesttype = rio_cmd->requesttype | UT_READ_VENDOR_DEVICE;
- DPRINTFN(1,("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
- requesttype, rio_cmd->request, rio_cmd->value, rio_cmd->index, len));
- break;
-
- case RIO_SEND_COMMAND:
- if (!(flag & FWRITE))
- return EPERM;
- rio_cmd = (struct RioCommand *)addr;
- if (rio_cmd == NULL)
- return EINVAL;
- len = rio_cmd->length;
-
- requesttype = rio_cmd->requesttype | UT_WRITE_VENDOR_DEVICE;
- DPRINTFN(1,("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
- requesttype, rio_cmd->request, rio_cmd->value, rio_cmd->index, len));
- break;
-
- default:
- return EINVAL;
- break;
- }
-
- /* Send rio control message */
- req.bmRequestType = requesttype;
- req.bRequest = rio_cmd->request;
- USETW(req.wValue, rio_cmd->value);
- USETW(req.wIndex, rio_cmd->index);
- USETW(req.wLength, len);
-
- if (len < 0 || len > 32767)
- return EINVAL;
- if (len != 0) {
- iov.iov_base = (caddr_t)rio_cmd->buffer;
- iov.iov_len = len;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_resid = len;
- uio.uio_offset = 0;
- uio.uio_segflg = UIO_USERSPACE;
- uio.uio_rw =
- req.bmRequestType & UT_READ ?
- UIO_READ : UIO_WRITE;
- uio.uio_td = p;
- ptr = malloc(len, M_TEMP, M_WAITOK);
- if (uio.uio_rw == UIO_WRITE) {
- error = uiomove(ptr, len, &uio);
- if (error)
- goto ret;
- }
- }
-
- r = usbd_do_request_flags(sc->sc_udev, &req,
- ptr, req_flags, &req_actlen,
- USBD_DEFAULT_TIMEOUT);
- if (r == USBD_NORMAL_COMPLETION) {
- error = 0;
- if (len != 0) {
- if (uio.uio_rw == UIO_READ) {
- error = uiomove(ptr, len, &uio);
- }
- }
- } else {
- error = EIO;
- }
-
-ret:
- if (ptr)
- free(ptr, M_TEMP);
- return error;
-}
-
-static int
-urio_detach(device_t self)
-{
- struct urio_softc *sc = device_get_softc(self);
- int s;
-
- DPRINTF(("urio_detach: sc=%p\n", sc));
- sc->sc_dying = 1;
- if (sc->sc_pipeh_in)
- usbd_abort_pipe(sc->sc_pipeh_in);
-
- if (sc->sc_pipeh_out)
- usbd_abort_pipe(sc->sc_pipeh_out);
-
- s = splusb();
- if (--sc->sc_refcnt >= 0) {
- /* Wait for processes to go away. */
- usb_detach_wait(sc->sc_dev);
- }
- splx(s);
-
- destroy_dev(sc->sc_dev_t);
- /* XXX not implemented yet */
- device_set_desc(self, NULL);
- return 0;
-}
-
-MODULE_DEPEND(uscanner, usb, 1, 1, 1);
-DRIVER_MODULE(urio, uhub, urio_driver, urio_devclass, usbd_driver_load, 0);
diff --git a/sys/legacy/dev/usb/usb.c b/sys/legacy/dev/usb/usb.c
deleted file mode 100644
index b1b7d44..0000000
--- a/sys/legacy/dev/usb/usb.c
+++ /dev/null
@@ -1,939 +0,0 @@
-/* $NetBSD: usb.c,v 1.68 2002/02/20 20:30:12 christos Exp $ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: usb.c,v 1.70 2002/05/09 21:54:32 augustss Exp $
- * $NetBSD: usb.c,v 1.71 2002/06/01 23:51:04 lukem Exp $
- * $NetBSD: usb.c,v 1.73 2002/09/23 05:51:19 simonb Exp $
- * $NetBSD: usb.c,v 1.80 2003/11/07 17:03:25 wiz Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * USB specifications and other documentation can be found at
- * http://www.usb.org/developers/docs/ and
- * http://www.usb.org/developers/devclass_docs/
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/unistd.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/uio.h>
-#include <sys/kthread.h>
-#include <sys/proc.h>
-#include <sys/conf.h>
-#include <sys/poll.h>
-#include <sys/selinfo.h>
-#include <sys/signalvar.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#define USBUNIT(d) (dev2unit(d)) /* usb_discover device nodes, kthread */
-#define USB_DEV_MINOR 255 /* event queue device */
-
-MALLOC_DEFINE(M_USB, "USB", "USB");
-MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
-MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
-
-#include "usb_if.h"
-
-#include <machine/bus.h>
-
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_quirks.h>
-
-/* Define this unconditionally in case a kernel module is loaded that
- * has been compiled with debugging options.
- */
-SYSCTL_NODE(_hw, OID_AUTO, usb, CTLFLAG_RW, 0, "USB debugging");
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-int usbdebug = 0;
-SYSCTL_INT(_hw_usb, OID_AUTO, debug, CTLFLAG_RW,
- &usbdebug, 0, "usb debug level");
-/*
- * 0 - do usual exploration
- * 1 - do not use timeout exploration
- * >1 - do no exploration
- */
-int usb_noexplore = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct usb_softc {
- device_t sc_dev; /* base device */
- struct cdev *sc_usbdev; /* /dev/usbN device */
- TAILQ_ENTRY(usb_softc) sc_coldexplist; /* cold needs-explore list */
- usbd_bus_handle sc_bus; /* USB controller */
- struct usbd_port sc_port; /* dummy port for root hub */
-
- struct proc *sc_event_thread;
-
- char sc_dying;
-};
-
-struct usb_taskq {
- TAILQ_HEAD(, usb_task) tasks;
- struct proc *task_thread_proc;
- const char *name;
- int taskcreated; /* task thread exists. */
-};
-
-static struct usb_taskq usb_taskq[USB_NUM_TASKQS];
-
-d_open_t usbopen;
-d_close_t usbclose;
-d_read_t usbread;
-d_ioctl_t usbioctl;
-d_poll_t usbpoll;
-
-struct cdevsw usb_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = usbopen,
- .d_close = usbclose,
- .d_read = usbread,
- .d_ioctl = usbioctl,
- .d_poll = usbpoll,
- .d_name = "usb",
-};
-
-static void usb_discover(void *);
-static void usb_create_event_thread(void *);
-static void usb_event_thread(void *);
-static void usb_task_thread(void *);
-
-static struct cdev *usb_dev; /* The /dev/usb device. */
-static int usb_ndevs; /* Number of /dev/usbN devices. */
-/* Busses to explore at the end of boot-time device configuration. */
-static TAILQ_HEAD(, usb_softc) usb_coldexplist =
- TAILQ_HEAD_INITIALIZER(usb_coldexplist);
-
-#define USB_MAX_EVENTS 100
-struct usb_event_q {
- struct usb_event ue;
- TAILQ_ENTRY(usb_event_q) next;
-};
-static TAILQ_HEAD(, usb_event_q) usb_events =
- TAILQ_HEAD_INITIALIZER(usb_events);
-static int usb_nevents = 0;
-static struct selinfo usb_selevent;
-static struct proc *usb_async_proc; /* process that wants USB SIGIO */
-static int usb_dev_open = 0;
-static void usb_add_event(int, struct usb_event *);
-
-static int usb_get_next_event(struct usb_event *);
-
-static const char *usbrev_str[] = USBREV_STR;
-
-static device_probe_t usb_match;
-static device_attach_t usb_attach;
-static device_detach_t usb_detach;
-static bus_child_detached_t usb_child_detached;
-
-static device_method_t usb_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, usb_match),
- DEVMETHOD(device_attach, usb_attach),
- DEVMETHOD(device_detach, usb_detach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_child_detached, usb_child_detached),
-
- { 0, 0 }
-};
-
-static driver_t usb_driver = {
- "usb",
- usb_methods,
- sizeof(struct usb_softc)
-};
-
-static devclass_t usb_devclass;
-
-DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0);
-DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0);
-DRIVER_MODULE(usb, ehci, usb_driver, usb_devclass, 0, 0);
-DRIVER_MODULE(usb, slhci, usb_driver, usb_devclass, 0, 0);
-MODULE_VERSION(usb, 1);
-
-static int
-usb_match(device_t self)
-{
- DPRINTF(("usbd_match\n"));
- return (UMATCH_GENERIC);
-}
-
-static int
-usb_attach(device_t self)
-{
- struct usb_softc *sc = device_get_softc(self);
- void *aux = device_get_ivars(self);
- usbd_device_handle dev;
- usbd_status err;
- int usbrev;
- int speed;
- struct usb_event ue;
-
- sc->sc_dev = self;
-
- DPRINTF(("usbd_attach\n"));
-
- usbd_init();
- sc->sc_bus = aux;
- sc->sc_bus->usbctl = sc;
- sc->sc_port.power = USB_MAX_POWER;
-
- printf("%s", device_get_nameunit(sc->sc_dev));
- usbrev = sc->sc_bus->usbrev;
- printf(": USB revision %s", usbrev_str[usbrev]);
- switch (usbrev) {
- case USBREV_1_0:
- case USBREV_1_1:
- speed = USB_SPEED_FULL;
- break;
- case USBREV_2_0:
- speed = USB_SPEED_HIGH;
- break;
- default:
- printf(", not supported\n");
- sc->sc_dying = 1;
- return ENXIO;
- }
- printf("\n");
-
- /* Make sure not to use tsleep() if we are cold booting. */
- if (cold)
- sc->sc_bus->use_polling++;
-
- ue.u.ue_ctrlr.ue_bus = device_get_unit(sc->sc_dev);
- usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue);
-
-#ifdef USB_USE_SOFTINTR
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
- /* XXX we should have our own level */
- sc->sc_bus->soft = softintr_establish(IPL_SOFTNET,
- sc->sc_bus->methods->soft_intr, sc->sc_bus);
- if (sc->sc_bus->soft == NULL) {
- printf("%s: can't register softintr\n", device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
-#else
- usb_callout_init(sc->sc_bus->softi);
-#endif
-#endif
-
- err = usbd_new_device(sc->sc_dev, sc->sc_bus, 0, speed, 0,
- &sc->sc_port);
- if (!err) {
- dev = sc->sc_port.device;
- if (dev->hub == NULL) {
- sc->sc_dying = 1;
- printf("%s: root device is not a hub\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
- sc->sc_bus->root_hub = dev;
-#if 1
- /*
- * Turning this code off will delay attachment of USB devices
- * until the USB event thread is running, which means that
- * the keyboard will not work until after cold boot.
- */
- if (cold) {
- /* Explore high-speed busses before others. */
- if (speed == USB_SPEED_HIGH)
- dev->hub->explore(sc->sc_bus->root_hub);
- else
- TAILQ_INSERT_TAIL(&usb_coldexplist, sc,
- sc_coldexplist);
- }
-#endif
- } else {
- printf("%s: root hub problem, error=%d\n",
- device_get_nameunit(sc->sc_dev), err);
- sc->sc_dying = 1;
- }
- if (cold)
- sc->sc_bus->use_polling--;
-
- /* XXX really do right config_pending_incr(); */
- usb_create_event_thread(sc);
- /* The per controller devices (used for usb_discover) */
- /* XXX This is redundant now, but old usbd's will want it */
- sc->sc_usbdev = make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT,
- GID_OPERATOR, 0660, "usb%d", device_get_unit(self));
- if (usb_ndevs++ == 0) {
- /* The device spitting out events */
- usb_dev = make_dev(&usb_cdevsw, USB_DEV_MINOR, UID_ROOT,
- GID_OPERATOR, 0660, "usb");
- }
- return 0;
-}
-
-static const char *taskq_names[] = USB_TASKQ_NAMES;
-
-void
-usb_create_event_thread(void *arg)
-{
- struct usb_softc *sc = arg;
- struct usb_taskq *taskq;
- int i;
-
- if (kproc_create(usb_event_thread, sc, &sc->sc_event_thread,
- RFHIGHPID, 0, device_get_nameunit(sc->sc_dev))) {
- printf("%s: unable to create event thread for\n",
- device_get_nameunit(sc->sc_dev));
- panic("usb_create_event_thread");
- }
- for (i = 0; i < USB_NUM_TASKQS; i++) {
- taskq = &usb_taskq[i];
-
- if (taskq->taskcreated == 0) {
- taskq->taskcreated = 1;
- taskq->name = taskq_names[i];
- TAILQ_INIT(&taskq->tasks);
- if (kproc_create(usb_task_thread, taskq,
- &taskq->task_thread_proc, RFHIGHPID, 0,
- taskq->name)) {
- printf("unable to create task thread\n");
- panic("usb_create_event_thread task");
- }
- }
- }
-}
-
-/*
- * Add a task to be performed by the task thread. This function can be
- * called from any context and the task will be executed in a process
- * context ASAP.
- */
-void
-usb_add_task(usbd_device_handle dev, struct usb_task *task, int queue)
-{
- struct usb_taskq *taskq;
- int s;
-
- s = splusb();
- taskq = &usb_taskq[queue];
- if (task->queue == -1) {
- DPRINTFN(2,("usb_add_task: task=%p\n", task));
- TAILQ_INSERT_TAIL(&taskq->tasks, task, next);
- task->queue = queue;
- } else {
- DPRINTFN(3,("usb_add_task: task=%p on q\n", task));
- }
- wakeup(&taskq->tasks);
- splx(s);
-}
-
-void
-usb_rem_task(usbd_device_handle dev, struct usb_task *task)
-{
- struct usb_taskq *taskq;
- int s;
-
- s = splusb();
- if (task->queue != -1) {
- taskq = &usb_taskq[task->queue];
- TAILQ_REMOVE(&taskq->tasks, task, next);
- task->queue = -1;
- }
- splx(s);
-}
-
-void
-usb_event_thread(void *arg)
-{
- static int newthread_wchan;
- struct usb_softc *sc = arg;
-
- mtx_lock(&Giant);
-
- DPRINTF(("usb_event_thread: start\n"));
-
- /*
- * In case this controller is a companion controller to an
- * EHCI controller we need to wait until the EHCI controller
- * has grabbed the port. What we do here is wait until no new
- * USB threads have been created in a while. XXX we actually
- * just want to wait for the PCI slot to be fully scanned.
- *
- * Note that when you `kldload usb' it actually attaches the
- * devices in order that the drivers appear in the kld, not the
- * normal PCI order, since the addition of each driver within
- * usb.ko (ohci, ehci etc.) causes a separate PCI bus re-scan.
- */
- wakeup(&newthread_wchan);
- for (;;) {
- if (tsleep(&newthread_wchan , PWAIT, "usbets", hz * 4) != 0)
- break;
- }
-
- /* Make sure first discover does something. */
- sc->sc_bus->needs_explore = 1;
- usb_discover(sc);
- /* XXX really do right config_pending_decr(); */
-
- while (!sc->sc_dying) {
-#ifdef USB_DEBUG
- if (usb_noexplore < 2)
-#endif
- usb_discover(sc);
-#ifdef USB_DEBUG
- (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
- usb_noexplore ? 0 : hz * 60);
-#else
- (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
- hz * 60);
-#endif
- DPRINTFN(2,("usb_event_thread: woke up\n"));
- }
- sc->sc_event_thread = NULL;
-
- /* In case parent is waiting for us to exit. */
- wakeup(sc);
-
- DPRINTF(("usb_event_thread: exit\n"));
- while (mtx_owned(&Giant))
- mtx_unlock(&Giant);
- kproc_exit(0);
-}
-
-void
-usb_task_thread(void *arg)
-{
- struct usb_task *task;
- struct usb_taskq *taskq;
- int s;
-
- mtx_lock(&Giant);
-
- taskq = arg;
- DPRINTF(("usb_task_thread: start taskq %s\n", taskq->name));
-
- s = splusb();
- while (usb_ndevs > 0) {
- task = TAILQ_FIRST(&taskq->tasks);
- if (task == NULL) {
- tsleep(&taskq->tasks, PWAIT, "usbtsk", 0);
- task = TAILQ_FIRST(&taskq->tasks);
- }
- DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task));
- if (task != NULL) {
- TAILQ_REMOVE(&taskq->tasks, task, next);
- task->queue = -1;
- splx(s);
- task->fun(task->arg);
- s = splusb();
- }
- }
- splx(s);
-
- taskq->taskcreated = 0;
- wakeup(&taskq->taskcreated);
-
- DPRINTF(("usb_event_thread: exit\n"));
- while (mtx_owned(&Giant))
- mtx_unlock(&Giant);
- kproc_exit(0);
-}
-
-int
-usbopen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- int unit = USBUNIT(dev);
- struct usb_softc *sc;
-
- if (unit == USB_DEV_MINOR) {
- if (usb_dev_open)
- return (EBUSY);
- usb_dev_open = 1;
- usb_async_proc = 0;
- return (0);
- }
- sc = devclass_get_softc(usb_devclass, unit);
- if (sc == NULL)
- return (ENXIO);
- if (sc->sc_dying)
- return (EIO);
-
- return (0);
-}
-
-int
-usbread(struct cdev *dev, struct uio *uio, int flag)
-{
- struct usb_event ue;
- int unit = USBUNIT(dev);
- int s, error, n;
-
- if (unit != USB_DEV_MINOR)
- return (ENODEV);
-
- if (uio->uio_resid != sizeof(struct usb_event))
- return (EINVAL);
-
- error = 0;
- s = splusb();
- for (;;) {
- n = usb_get_next_event(&ue);
- if (n != 0)
- break;
- if (flag & O_NONBLOCK) {
- error = EWOULDBLOCK;
- break;
- }
- error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0);
- if (error)
- break;
- }
- splx(s);
- if (!error)
- error = uiomove((void *)&ue, uio->uio_resid, uio);
-
- return (error);
-}
-
-int
-usbclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- int unit = USBUNIT(dev);
-
- if (unit == USB_DEV_MINOR) {
- usb_async_proc = 0;
- usb_dev_open = 0;
- }
-
- return (0);
-}
-
-int
-usbioctl(struct cdev *devt, u_long cmd, caddr_t data, int flag, struct thread *p)
-{
- struct usb_softc *sc;
- int unit = USBUNIT(devt);
-
- if (unit == USB_DEV_MINOR) {
- switch (cmd) {
- case FIONBIO:
- /* All handled in the upper FS layer. */
- return (0);
-
- case FIOASYNC:
- if (*(int *)data)
- usb_async_proc = p->td_proc;
- else
- usb_async_proc = 0;
- return (0);
-
- default:
- return (EINVAL);
- }
- }
- sc = devclass_get_softc(usb_devclass, unit);
- if (sc->sc_dying)
- return (EIO);
-
- switch (cmd) {
- /* This part should be deleted */
- case USB_DISCOVER:
- break;
- case USB_REQUEST:
- {
- struct usb_ctl_request *ur = (void *)data;
- int len = UGETW(ur->ucr_request.wLength);
- struct iovec iov;
- struct uio uio;
- void *ptr = 0;
- int addr = ur->ucr_addr;
- usbd_status err;
- int error = 0;
-
- DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len));
- if (len < 0 || len > 32768)
- return (EINVAL);
- if (addr < 0 || addr >= USB_MAX_DEVICES ||
- sc->sc_bus->devices[addr] == 0)
- return (EINVAL);
- if (len != 0) {
- iov.iov_base = (caddr_t)ur->ucr_data;
- iov.iov_len = len;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_resid = len;
- uio.uio_offset = 0;
- uio.uio_segflg = UIO_USERSPACE;
- uio.uio_rw =
- ur->ucr_request.bmRequestType & UT_READ ?
- UIO_READ : UIO_WRITE;
- uio.uio_td = p;
- ptr = malloc(len, M_TEMP, M_WAITOK);
- if (uio.uio_rw == UIO_WRITE) {
- error = uiomove(ptr, len, &uio);
- if (error)
- goto ret;
- }
- }
- err = usbd_do_request_flags(sc->sc_bus->devices[addr],
- &ur->ucr_request, ptr, ur->ucr_flags, &ur->ucr_actlen,
- USBD_DEFAULT_TIMEOUT);
- if (err) {
- error = EIO;
- goto ret;
- }
- if (len != 0) {
- if (uio.uio_rw == UIO_READ) {
- error = uiomove(ptr, len, &uio);
- if (error)
- goto ret;
- }
- }
- ret:
- if (ptr)
- free(ptr, M_TEMP);
- return (error);
- }
-
- case USB_DEVICEINFO:
- {
- struct usb_device_info *di = (void *)data;
- int addr = di->udi_addr;
- usbd_device_handle dev;
-
- if (addr < 1 || addr >= USB_MAX_DEVICES)
- return (EINVAL);
- dev = sc->sc_bus->devices[addr];
- if (dev == NULL)
- return (ENXIO);
- usbd_fill_deviceinfo(dev, di, 1);
- break;
- }
-
- case USB_DEVICESTATS:
- *(struct usb_device_stats *)data = sc->sc_bus->stats;
- break;
-
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-int
-usbpoll(struct cdev *dev, int events, struct thread *p)
-{
- int revents, mask, s;
- int unit = USBUNIT(dev);
-
- if (unit == USB_DEV_MINOR) {
- revents = 0;
- mask = POLLIN | POLLRDNORM;
-
- s = splusb();
- if (events & mask && usb_nevents > 0)
- revents |= events & mask;
- if (revents == 0 && events & mask)
- selrecord(p, &usb_selevent);
- splx(s);
-
- return (revents);
- } else {
- return (0); /* select/poll never wakes up - back compat */
- }
-}
-
-/* Explore device tree from the root. */
-static void
-usb_discover(void *v)
-{
- struct usb_softc *sc = v;
-
- /* splxxx should be changed to mutexes for preemption safety some day */
- int s;
-
- DPRINTFN(2,("usb_discover\n"));
-#ifdef USB_DEBUG
- if (usb_noexplore > 1)
- return;
-#endif
-
- /*
- * We need mutual exclusion while traversing the device tree,
- * but this is guaranteed since this function is only called
- * from the event thread for the controller.
- */
- s = splusb();
- while (sc->sc_bus->needs_explore && !sc->sc_dying) {
- sc->sc_bus->needs_explore = 0;
- splx(s);
- sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
- s = splusb();
- }
- splx(s);
-}
-
-void
-usb_needs_explore(usbd_device_handle dev)
-{
- DPRINTFN(2,("usb_needs_explore\n"));
- dev->bus->needs_explore = 1;
- wakeup(&dev->bus->needs_explore);
-}
-
-/* Called at splusb() */
-int
-usb_get_next_event(struct usb_event *ue)
-{
- struct usb_event_q *ueq;
-
- if (usb_nevents <= 0)
- return (0);
- ueq = TAILQ_FIRST(&usb_events);
-#ifdef DIAGNOSTIC
- if (ueq == NULL) {
- printf("usb: usb_nevents got out of sync! %d\n", usb_nevents);
- usb_nevents = 0;
- return (0);
- }
-#endif
- *ue = ueq->ue;
- TAILQ_REMOVE(&usb_events, ueq, next);
- free(ueq, M_USBDEV);
- usb_nevents--;
- return (1);
-}
-
-void
-usbd_add_dev_event(int type, usbd_device_handle udev)
-{
- struct usb_event ue;
-
- usbd_fill_deviceinfo(udev, &ue.u.ue_device, USB_EVENT_IS_ATTACH(type));
- usb_add_event(type, &ue);
-}
-
-void
-usbd_add_drv_event(int type, usbd_device_handle udev, device_t dev)
-{
- struct usb_event ue;
-
- ue.u.ue_driver.ue_cookie = udev->cookie;
- strncpy(ue.u.ue_driver.ue_devname, device_get_nameunit(dev),
- sizeof ue.u.ue_driver.ue_devname);
- usb_add_event(type, &ue);
-}
-
-void
-usb_add_event(int type, struct usb_event *uep)
-{
- struct usb_event_q *ueq;
- struct usb_event ue;
- struct timeval thetime;
- int s;
-
- ueq = malloc(sizeof *ueq, M_USBDEV, M_WAITOK);
- ueq->ue = *uep;
- ueq->ue.ue_type = type;
- microtime(&thetime);
- TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
-
- s = splusb();
- if (USB_EVENT_IS_DETACH(type)) {
- struct usb_event_q *ueqi, *ueqi_next;
-
- for (ueqi = TAILQ_FIRST(&usb_events); ueqi; ueqi = ueqi_next) {
- ueqi_next = TAILQ_NEXT(ueqi, next);
- if (ueqi->ue.u.ue_driver.ue_cookie.cookie ==
- uep->u.ue_device.udi_cookie.cookie) {
- TAILQ_REMOVE(&usb_events, ueqi, next);
- free(ueqi, M_USBDEV);
- usb_nevents--;
- ueqi_next = TAILQ_FIRST(&usb_events);
- }
- }
- }
- if (usb_nevents >= USB_MAX_EVENTS) {
- /* Too many queued events, drop an old one. */
- DPRINTF(("usb: event dropped\n"));
- (void)usb_get_next_event(&ue);
- }
- TAILQ_INSERT_TAIL(&usb_events, ueq, next);
- usb_nevents++;
- wakeup(&usb_events);
- selwakeuppri(&usb_selevent, PZERO);
- if (usb_async_proc != NULL) {
- PROC_LOCK(usb_async_proc);
- psignal(usb_async_proc, SIGIO);
- PROC_UNLOCK(usb_async_proc);
- }
- splx(s);
-}
-
-void
-usb_schedsoftintr(usbd_bus_handle bus)
-{
- DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling));
-#ifdef USB_USE_SOFTINTR
- if (bus->use_polling) {
- bus->methods->soft_intr(bus);
- } else {
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
- softintr_schedule(bus->soft);
-#else
- if (!callout_pending(&bus->softi))
- callout_reset(&bus->softi, 0, bus->methods->soft_intr,
- bus);
-#endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
- }
-#else
- bus->methods->soft_intr(bus);
-#endif /* USB_USE_SOFTINTR */
-}
-
-static int
-usb_detach(device_t self)
-{
- struct usb_softc *sc = device_get_softc(self);
- struct usb_event ue;
- struct usb_taskq *taskq;
- int i;
-
- DPRINTF(("usb_detach: start\n"));
-
- sc->sc_dying = 1;
-
- /* Make all devices disconnect. */
- if (sc->sc_port.device != NULL)
- usb_disconnect_port(&sc->sc_port, self);
-
- /* Kill off event thread. */
- if (sc->sc_event_thread != NULL) {
- wakeup(&sc->sc_bus->needs_explore);
- if (tsleep(sc, PWAIT, "usbdet", hz * 60))
- printf("%s: event thread didn't die\n",
- device_get_nameunit(sc->sc_dev));
- DPRINTF(("usb_detach: event thread dead\n"));
- }
-
- destroy_dev(sc->sc_usbdev);
- if (--usb_ndevs == 0) {
- destroy_dev(usb_dev);
- usb_dev = NULL;
- for (i = 0; i < USB_NUM_TASKQS; i++) {
- taskq = &usb_taskq[i];
- wakeup(&taskq->tasks);
- if (tsleep(&taskq->taskcreated, PWAIT, "usbtdt",
- hz * 60)) {
- printf("usb task thread %s didn't die\n",
- taskq->name);
- }
- }
- }
-
- usbd_finish();
-
-#ifdef USB_USE_SOFTINTR
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
- if (sc->sc_bus->soft != NULL) {
- softintr_disestablish(sc->sc_bus->soft);
- sc->sc_bus->soft = NULL;
- }
-#else
- callout_stop(&sc->sc_bus->softi);
-#endif
-#endif
-
- ue.u.ue_ctrlr.ue_bus = device_get_unit(sc->sc_dev);
- usb_add_event(USB_EVENT_CTRLR_DETACH, &ue);
-
- return (0);
-}
-
-static void
-usb_child_detached(device_t self, device_t child)
-{
- struct usb_softc *sc = device_get_softc(self);
-
- /* XXX, should check it is the right device. */
- sc->sc_port.device = NULL;
-}
-
-/* Explore USB busses at the end of device configuration. */
-static void
-usb_cold_explore(void *arg)
-{
- struct usb_softc *sc;
-
- KASSERT(cold || TAILQ_EMPTY(&usb_coldexplist),
- ("usb_cold_explore: busses to explore when !cold"));
- while (!TAILQ_EMPTY(&usb_coldexplist)) {
- sc = TAILQ_FIRST(&usb_coldexplist);
- TAILQ_REMOVE(&usb_coldexplist, sc, sc_coldexplist);
-
- sc->sc_bus->use_polling++;
- sc->sc_port.device->hub->explore(sc->sc_bus->root_hub);
- sc->sc_bus->use_polling--;
- }
-}
-
-SYSINIT(usb_cold_explore, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE,
- usb_cold_explore, NULL);
diff --git a/sys/legacy/dev/usb/usb.h b/sys/legacy/dev/usb/usb.h
deleted file mode 100644
index 7e64cac..0000000
--- a/sys/legacy/dev/usb/usb.h
+++ /dev/null
@@ -1,708 +0,0 @@
-/* $NetBSD: usb.h,v 1.69 2002/09/22 23:20:50 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef _USB_H_
-#define _USB_H_
-
-#include <sys/types.h>
-#include <sys/time.h>
-
-#if defined(_KERNEL)
-#include "opt_usb.h"
-
-#ifdef SYSCTL_DECL
-SYSCTL_DECL(_hw_usb);
-#endif
-
-#include <sys/malloc.h>
-
-MALLOC_DECLARE(M_USB);
-MALLOC_DECLARE(M_USBDEV);
-MALLOC_DECLARE(M_USBHC);
-#endif /* _KERNEL */
-
-#define PWR_RESUME 0
-#define PWR_SUSPEND 1
-#define PWR_STANDBY 2
-#define PWR_SOFTSUSPEND 3
-#define PWR_SOFTSTANDBY 4
-#define PWR_SOFTRESUME 5
-
-/* These two defines are used by usbd to autoload the usb kld */
-#define USB_KLD "usb" /* name of usb module */
-#define USB_UHUB "usb/uhub" /* root hub */
-
-#define USB_STACK_VERSION 2
-
-#define USB_MAX_DEVICES 128
-#define USB_START_ADDR 0
-
-#define USB_CONTROL_ENDPOINT 0
-#define USB_MAX_ENDPOINTS 16
-
-#define USB_FRAMES_PER_SECOND 1000
-
-/*
- * The USB records contain some unaligned little-endian word
- * components. The U[SG]ETW macros take care of both the alignment
- * and endian problem and should always be used to access non-byte
- * values.
- */
-typedef u_int8_t uByte;
-typedef u_int8_t uWord[2];
-typedef u_int8_t uDWord[4];
-
-#define USETW2(w,h,l) ((w)[0] = (u_int8_t)(l), (w)[1] = (u_int8_t)(h))
-
-#if 1
-#define UGETW(w) ((w)[0] | ((w)[1] << 8))
-#define USETW(w,v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8))
-#define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24))
-#define USETDW(w,v) ((w)[0] = (u_int8_t)(v), \
- (w)[1] = (u_int8_t)((v) >> 8), \
- (w)[2] = (u_int8_t)((v) >> 16), \
- (w)[3] = (u_int8_t)((v) >> 24))
-#else
-/*
- * On little-endian machines that can handle unanliged accesses
- * (e.g. i386) these macros can be replaced by the following.
- */
-#define UGETW(w) (*(u_int16_t *)(w))
-#define USETW(w,v) (*(u_int16_t *)(w) = (v))
-#define UGETDW(w) (*(u_int32_t *)(w))
-#define USETDW(w,v) (*(u_int32_t *)(w) = (v))
-#endif
-
-#define UPACKED __packed
-
-typedef struct {
- uByte bmRequestType;
- uByte bRequest;
- uWord wValue;
- uWord wIndex;
- uWord wLength;
-} UPACKED usb_device_request_t;
-
-#define UT_WRITE 0x00
-#define UT_READ 0x80
-#define UT_STANDARD 0x00
-#define UT_CLASS 0x20
-#define UT_VENDOR 0x40
-#define UT_DEVICE 0x00
-#define UT_INTERFACE 0x01
-#define UT_ENDPOINT 0x02
-#define UT_OTHER 0x03
-
-#define UT_READ_DEVICE (UT_READ | UT_STANDARD | UT_DEVICE)
-#define UT_READ_INTERFACE (UT_READ | UT_STANDARD | UT_INTERFACE)
-#define UT_READ_ENDPOINT (UT_READ | UT_STANDARD | UT_ENDPOINT)
-#define UT_WRITE_DEVICE (UT_WRITE | UT_STANDARD | UT_DEVICE)
-#define UT_WRITE_INTERFACE (UT_WRITE | UT_STANDARD | UT_INTERFACE)
-#define UT_WRITE_ENDPOINT (UT_WRITE | UT_STANDARD | UT_ENDPOINT)
-#define UT_READ_CLASS_DEVICE (UT_READ | UT_CLASS | UT_DEVICE)
-#define UT_READ_CLASS_INTERFACE (UT_READ | UT_CLASS | UT_INTERFACE)
-#define UT_READ_CLASS_OTHER (UT_READ | UT_CLASS | UT_OTHER)
-#define UT_READ_CLASS_ENDPOINT (UT_READ | UT_CLASS | UT_ENDPOINT)
-#define UT_WRITE_CLASS_DEVICE (UT_WRITE | UT_CLASS | UT_DEVICE)
-#define UT_WRITE_CLASS_INTERFACE (UT_WRITE | UT_CLASS | UT_INTERFACE)
-#define UT_WRITE_CLASS_OTHER (UT_WRITE | UT_CLASS | UT_OTHER)
-#define UT_WRITE_CLASS_ENDPOINT (UT_WRITE | UT_CLASS | UT_ENDPOINT)
-#define UT_READ_VENDOR_DEVICE (UT_READ | UT_VENDOR | UT_DEVICE)
-#define UT_READ_VENDOR_INTERFACE (UT_READ | UT_VENDOR | UT_INTERFACE)
-#define UT_READ_VENDOR_OTHER (UT_READ | UT_VENDOR | UT_OTHER)
-#define UT_READ_VENDOR_ENDPOINT (UT_READ | UT_VENDOR | UT_ENDPOINT)
-#define UT_WRITE_VENDOR_DEVICE (UT_WRITE | UT_VENDOR | UT_DEVICE)
-#define UT_WRITE_VENDOR_INTERFACE (UT_WRITE | UT_VENDOR | UT_INTERFACE)
-#define UT_WRITE_VENDOR_OTHER (UT_WRITE | UT_VENDOR | UT_OTHER)
-#define UT_WRITE_VENDOR_ENDPOINT (UT_WRITE | UT_VENDOR | UT_ENDPOINT)
-
-/* Requests */
-#define UR_GET_STATUS 0x00
-#define UR_CLEAR_FEATURE 0x01
-#define UR_SET_FEATURE 0x03
-#define UR_SET_ADDRESS 0x05
-#define UR_GET_DESCRIPTOR 0x06
-#define UDESC_DEVICE 0x01
-#define UDESC_CONFIG 0x02
-#define UDESC_STRING 0x03
-#define UDESC_INTERFACE 0x04
-#define UDESC_ENDPOINT 0x05
-#define UDESC_DEVICE_QUALIFIER 0x06
-#define UDESC_OTHER_SPEED_CONFIGURATION 0x07
-#define UDESC_INTERFACE_POWER 0x08
-#define UDESC_OTG 0x09
-#define UDESC_CS_DEVICE 0x21 /* class specific */
-#define UDESC_CS_CONFIG 0x22
-#define UDESC_CS_STRING 0x23
-#define UDESC_CS_INTERFACE 0x24
-#define UDESC_CS_ENDPOINT 0x25
-#define UDESC_HUB 0x29
-#define UR_SET_DESCRIPTOR 0x07
-#define UR_GET_CONFIG 0x08
-#define UR_SET_CONFIG 0x09
-#define UR_GET_INTERFACE 0x0a
-#define UR_SET_INTERFACE 0x0b
-#define UR_SYNCH_FRAME 0x0c
-
-/* Feature numbers */
-#define UF_ENDPOINT_HALT 0
-#define UF_DEVICE_REMOTE_WAKEUP 1
-#define UF_TEST_MODE 2
-
-#define USB_MAX_IPACKET 8 /* maximum size of the initial packet */
-
-#define USB_2_MAX_CTRL_PACKET 64
-#define USB_2_MAX_BULK_PACKET 512
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
-} UPACKED usb_descriptor_t;
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uWord bcdUSB;
-#define UD_USB_2_0 0x0200
-#define UD_IS_USB2(d) (UGETW((d)->bcdUSB) >= UD_USB_2_0)
- uByte bDeviceClass;
- uByte bDeviceSubClass;
- uByte bDeviceProtocol;
- uByte bMaxPacketSize;
- /* The fields below are not part of the initial descriptor. */
- uWord idVendor;
- uWord idProduct;
- uWord bcdDevice;
- uByte iManufacturer;
- uByte iProduct;
- uByte iSerialNumber;
- uByte bNumConfigurations;
-} UPACKED usb_device_descriptor_t;
-#define USB_DEVICE_DESCRIPTOR_SIZE 18
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uWord wTotalLength;
- uByte bNumInterface;
- uByte bConfigurationValue;
- uByte iConfiguration;
- uByte bmAttributes;
-#define UC_BUS_POWERED 0x80
-#define UC_SELF_POWERED 0x40
-#define UC_REMOTE_WAKEUP 0x20
- uByte bMaxPower; /* max current in 2 mA units */
-#define UC_POWER_FACTOR 2
-} UPACKED usb_config_descriptor_t;
-#define USB_CONFIG_DESCRIPTOR_SIZE 9
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bInterfaceNumber;
- uByte bAlternateSetting;
- uByte bNumEndpoints;
- uByte bInterfaceClass;
- uByte bInterfaceSubClass;
- uByte bInterfaceProtocol;
- uByte iInterface;
-} UPACKED usb_interface_descriptor_t;
-#define USB_INTERFACE_DESCRIPTOR_SIZE 9
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bEndpointAddress;
-#define UE_GET_DIR(a) ((a) & 0x80)
-#define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7))
-#define UE_DIR_IN 0x80
-#define UE_DIR_OUT 0x00
-#define UE_ADDR 0x0f
-#define UE_GET_ADDR(a) ((a) & UE_ADDR)
- uByte bmAttributes;
-#define UE_XFERTYPE 0x03
-#define UE_CONTROL 0x00
-#define UE_ISOCHRONOUS 0x01
-#define UE_BULK 0x02
-#define UE_INTERRUPT 0x03
-#define UE_GET_XFERTYPE(a) ((a) & UE_XFERTYPE)
-#define UE_ISO_TYPE 0x0c
-#define UE_ISO_ASYNC 0x04
-#define UE_ISO_ADAPT 0x08
-#define UE_ISO_SYNC 0x0c
-#define UE_GET_ISO_TYPE(a) ((a) & UE_ISO_TYPE)
- uWord wMaxPacketSize;
-#define UE_GET_TRANS(a) (((a) >> 11) & 0x3)
-#define UE_GET_SIZE(a) ((a) & 0x7ff)
- uByte bInterval;
-} UPACKED usb_endpoint_descriptor_t;
-#define USB_ENDPOINT_DESCRIPTOR_SIZE 7
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uWord bString[127];
-} UPACKED usb_string_descriptor_t;
-#define USB_MAX_STRING_LEN 128
-#define USB_LANGUAGE_TABLE 0 /* # of the string language id table */
-
-/* Hub specific request */
-#define UR_GET_BUS_STATE 0x02
-#define UR_CLEAR_TT_BUFFER 0x08
-#define UR_RESET_TT 0x09
-#define UR_GET_TT_STATE 0x0a
-#define UR_STOP_TT 0x0b
-
-/* Hub features */
-#define UHF_C_HUB_LOCAL_POWER 0
-#define UHF_C_HUB_OVER_CURRENT 1
-#define UHF_PORT_CONNECTION 0
-#define UHF_PORT_ENABLE 1
-#define UHF_PORT_SUSPEND 2
-#define UHF_PORT_OVER_CURRENT 3
-#define UHF_PORT_RESET 4
-#define UHF_PORT_POWER 8
-#define UHF_PORT_LOW_SPEED 9
-#define UHF_C_PORT_CONNECTION 16
-#define UHF_C_PORT_ENABLE 17
-#define UHF_C_PORT_SUSPEND 18
-#define UHF_C_PORT_OVER_CURRENT 19
-#define UHF_C_PORT_RESET 20
-#define UHF_PORT_TEST 21
-#define UHF_PORT_INDICATOR 22
-
-typedef struct {
- uByte bDescLength;
- uByte bDescriptorType;
- uByte bNbrPorts;
- uWord wHubCharacteristics;
-#define UHD_PWR 0x0003
-#define UHD_PWR_GANGED 0x0000
-#define UHD_PWR_INDIVIDUAL 0x0001
-#define UHD_PWR_NO_SWITCH 0x0002
-#define UHD_COMPOUND 0x0004
-#define UHD_OC 0x0018
-#define UHD_OC_GLOBAL 0x0000
-#define UHD_OC_INDIVIDUAL 0x0008
-#define UHD_OC_NONE 0x0010
-#define UHD_TT_THINK 0x0060
-#define UHD_TT_THINK_8 0x0000
-#define UHD_TT_THINK_16 0x0020
-#define UHD_TT_THINK_24 0x0040
-#define UHD_TT_THINK_32 0x0060
-#define UHD_PORT_IND 0x0080
- uByte bPwrOn2PwrGood; /* delay in 2 ms units */
-#define UHD_PWRON_FACTOR 2
- uByte bHubContrCurrent;
- uByte DeviceRemovable[32]; /* max 255 ports */
-#define UHD_NOT_REMOV(desc, i) \
- (((desc)->DeviceRemovable[(i)/8] >> ((i) % 8)) & 1)
- /* deprecated */ uByte PortPowerCtrlMask[1];
-} UPACKED usb_hub_descriptor_t;
-#define USB_HUB_DESCRIPTOR_SIZE 9 /* includes deprecated PortPowerCtrlMask */
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uWord bcdUSB;
- uByte bDeviceClass;
- uByte bDeviceSubClass;
- uByte bDeviceProtocol;
- uByte bMaxPacketSize0;
- uByte bNumConfigurations;
- uByte bReserved;
-} UPACKED usb_device_qualifier_t;
-#define USB_DEVICE_QUALIFIER_SIZE 10
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bmAttributes;
-#define UOTG_SRP 0x01
-#define UOTG_HNP 0x02
-} UPACKED usb_otg_descriptor_t;
-
-/* OTG feature selectors */
-#define UOTG_B_HNP_ENABLE 3
-#define UOTG_A_HNP_SUPPORT 4
-#define UOTG_A_ALT_HNP_SUPPORT 5
-
-typedef struct {
- uWord wStatus;
-/* Device status flags */
-#define UDS_SELF_POWERED 0x0001
-#define UDS_REMOTE_WAKEUP 0x0002
-/* Endpoint status flags */
-#define UES_HALT 0x0001
-} UPACKED usb_status_t;
-
-typedef struct {
- uWord wHubStatus;
-#define UHS_LOCAL_POWER 0x0001
-#define UHS_OVER_CURRENT 0x0002
- uWord wHubChange;
-} UPACKED usb_hub_status_t;
-
-typedef struct {
- uWord wPortStatus;
-#define UPS_CURRENT_CONNECT_STATUS 0x0001
-#define UPS_PORT_ENABLED 0x0002
-#define UPS_SUSPEND 0x0004
-#define UPS_OVERCURRENT_INDICATOR 0x0008
-#define UPS_RESET 0x0010
-#define UPS_PORT_POWER 0x0100
-#define UPS_LOW_SPEED 0x0200
-#define UPS_HIGH_SPEED 0x0400
-#define UPS_PORT_TEST 0x0800
-#define UPS_PORT_INDICATOR 0x1000
- uWord wPortChange;
-#define UPS_C_CONNECT_STATUS 0x0001
-#define UPS_C_PORT_ENABLED 0x0002
-#define UPS_C_SUSPEND 0x0004
-#define UPS_C_OVERCURRENT_INDICATOR 0x0008
-#define UPS_C_PORT_RESET 0x0010
-} UPACKED usb_port_status_t;
-
-/* Device class codes */
-#define UDCLASS_IN_INTERFACE 0x00
-#define UDCLASS_COMM 0x02
-#define UDCLASS_HUB 0x09
-#define UDSUBCLASS_HUB 0x00
-#define UDPROTO_FSHUB 0x00
-#define UDPROTO_HSHUBSTT 0x01
-#define UDPROTO_HSHUBMTT 0x02
-#define UDCLASS_DIAGNOSTIC 0xdc
-#define UDCLASS_WIRELESS 0xe0
-#define UDSUBCLASS_RF 0x01
-#define UDPROTO_BLUETOOTH 0x01
-#define UDCLASS_VENDOR 0xff
-
-/* Interface class codes */
-#define UICLASS_UNSPEC 0x00
-
-#define UICLASS_AUDIO 0x01
-#define UISUBCLASS_AUDIOCONTROL 1
-#define UISUBCLASS_AUDIOSTREAM 2
-#define UISUBCLASS_MIDISTREAM 3
-
-#define UICLASS_CDC 0x02 /* communication */
-#define UISUBCLASS_DIRECT_LINE_CONTROL_MODEL 1
-#define UISUBCLASS_ABSTRACT_CONTROL_MODEL 2
-#define UISUBCLASS_TELEPHONE_CONTROL_MODEL 3
-#define UISUBCLASS_MULTICHANNEL_CONTROL_MODEL 4
-#define UISUBCLASS_CAPI_CONTROLMODEL 5
-#define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
-#define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
-#define UIPROTO_CDC_AT 1
-
-#define UICLASS_HID 0x03
-#define UISUBCLASS_BOOT 1
-#define UIPROTO_BOOT_KEYBOARD 1
-#define UIPROTO_MOUSE 2
-
-#define UICLASS_PHYSICAL 0x05
-
-#define UICLASS_IMAGE 0x06
-
-#define UICLASS_PRINTER 0x07
-#define UISUBCLASS_PRINTER 1
-#define UIPROTO_PRINTER_UNI 1
-#define UIPROTO_PRINTER_BI 2
-#define UIPROTO_PRINTER_1284 3
-
-#define UICLASS_MASS 0x08
-#define UISUBCLASS_RBC 1
-#define UISUBCLASS_SFF8020I 2
-#define UISUBCLASS_QIC157 3
-#define UISUBCLASS_UFI 4
-#define UISUBCLASS_SFF8070I 5
-#define UISUBCLASS_SCSI 6
-#define UIPROTO_MASS_CBI_I 0
-#define UIPROTO_MASS_CBI 1
-#define UIPROTO_MASS_BBB_OLD 2 /* Not in the spec anymore */
-#define UIPROTO_MASS_BBB 80 /* 'P' for the Iomega Zip drive */
-
-#define UICLASS_HUB 0x09
-#define UISUBCLASS_HUB 0
-#define UIPROTO_FSHUB 0
-#define UIPROTO_HSHUBSTT 0 /* Yes, same as previous */
-#define UIPROTO_HSHUBMTT 1
-
-#define UICLASS_CDC_DATA 0x0a
-#define UISUBCLASS_DATA 0
-#define UIPROTO_DATA_ISDNBRI 0x30 /* Physical iface */
-#define UIPROTO_DATA_HDLC 0x31 /* HDLC */
-#define UIPROTO_DATA_TRANSPARENT 0x32 /* Transparent */
-#define UIPROTO_DATA_Q921M 0x50 /* Management for Q921 */
-#define UIPROTO_DATA_Q921 0x51 /* Data for Q921 */
-#define UIPROTO_DATA_Q921TM 0x52 /* TEI multiplexer for Q921 */
-#define UIPROTO_DATA_V42BIS 0x90 /* Data compression */
-#define UIPROTO_DATA_Q931 0x91 /* Euro-ISDN */
-#define UIPROTO_DATA_V120 0x92 /* V.24 rate adaption */
-#define UIPROTO_DATA_CAPI 0x93 /* CAPI 2.0 commands */
-#define UIPROTO_DATA_HOST_BASED 0xfd /* Host based driver */
-#define UIPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc.*/
-#define UIPROTO_DATA_VENDOR 0xff /* Vendor specific */
-
-#define UICLASS_SMARTCARD 0x0b
-
-/*#define UICLASS_FIRM_UPD 0x0c*/
-
-#define UICLASS_SECURITY 0x0d
-
-#define UICLASS_DIAGNOSTIC 0xdc
-
-#define UICLASS_WIRELESS 0xe0
-#define UISUBCLASS_RF 0x01
-#define UIPROTO_BLUETOOTH 0x01
-
-#define UICLASS_APPL_SPEC 0xfe
-#define UISUBCLASS_FIRMWARE_DOWNLOAD 1
-#define UISUBCLASS_IRDA 2
-#define UIPROTO_IRDA 0
-
-#define UICLASS_VENDOR 0xff
-#define UISUBCLASS_XBOX360_CONTROLLER 0x5d
-#define UIPROTO_XBOX360_GAMEPAD 0x01
-
-
-#define USB_HUB_MAX_DEPTH 5
-
-/*
- * Minimum time a device needs to be powered down to go through
- * a power cycle. XXX Are these time in the spec?
- */
-#define USB_POWER_DOWN_TIME 200 /* ms */
-#define USB_PORT_POWER_DOWN_TIME 100 /* ms */
-
-#if 0
-/* These are the values from the spec. */
-#define USB_PORT_RESET_DELAY 10 /* ms */
-#define USB_PORT_ROOT_RESET_DELAY 50 /* ms */
-#define USB_PORT_RESET_RECOVERY 10 /* ms */
-#define USB_PORT_POWERUP_DELAY 100 /* ms */
-#define USB_SET_ADDRESS_SETTLE 2 /* ms */
-#define USB_RESUME_DELAY (20*5) /* ms */
-#define USB_RESUME_WAIT 10 /* ms */
-#define USB_RESUME_RECOVERY 10 /* ms */
-#define USB_EXTRA_POWER_UP_TIME 0 /* ms */
-#else
-/* Allow for marginal (i.e. non-conforming) devices. */
-#define USB_PORT_RESET_DELAY 50 /* ms */
-#define USB_PORT_ROOT_RESET_DELAY 250 /* ms */
-#define USB_PORT_RESET_RECOVERY 250 /* ms */
-#define USB_PORT_POWERUP_DELAY 300 /* ms */
-#define USB_SET_ADDRESS_SETTLE 10 /* ms */
-#define USB_RESUME_DELAY (50*5) /* ms */
-#define USB_RESUME_WAIT 50 /* ms */
-#define USB_RESUME_RECOVERY 50 /* ms */
-#define USB_EXTRA_POWER_UP_TIME 20 /* ms */
-#endif
-
-#define USB_MIN_POWER 100 /* mA */
-#define USB_MAX_POWER 500 /* mA */
-
-#define USB_BUS_RESET_DELAY 100 /* ms XXX?*/
-
-
-#define USB_UNCONFIG_NO 0
-#define USB_UNCONFIG_INDEX (-1)
-
-/*** ioctl() related stuff ***/
-
-struct usb_ctl_request {
- int ucr_addr;
- usb_device_request_t ucr_request;
- void *ucr_data;
- int ucr_flags;
-#define USBD_SHORT_XFER_OK 0x04 /* allow short reads */
- int ucr_actlen; /* actual length transferred */
-};
-
-struct usb_alt_interface {
- int uai_config_index;
- int uai_interface_index;
- int uai_alt_no;
-};
-
-#define USB_CURRENT_CONFIG_INDEX (-1)
-#define USB_CURRENT_ALT_INDEX (-1)
-
-struct usb_config_desc {
- int ucd_config_index;
- usb_config_descriptor_t ucd_desc;
-};
-
-struct usb_interface_desc {
- int uid_config_index;
- int uid_interface_index;
- int uid_alt_index;
- usb_interface_descriptor_t uid_desc;
-};
-
-struct usb_endpoint_desc {
- int ued_config_index;
- int ued_interface_index;
- int ued_alt_index;
- int ued_endpoint_index;
- usb_endpoint_descriptor_t ued_desc;
-};
-
-struct usb_full_desc {
- int ufd_config_index;
- u_int ufd_size;
- u_char *ufd_data;
-};
-
-struct usb_string_desc {
- int usd_string_index;
- int usd_language_id;
- usb_string_descriptor_t usd_desc;
-};
-
-struct usb_ctl_report_desc {
- int ucrd_size;
- u_char ucrd_data[1024]; /* filled data size will vary */
-};
-
-typedef struct { u_int32_t cookie; } usb_event_cookie_t;
-
-#define USB_MAX_DEVNAMES 4
-#define USB_MAX_DEVNAMELEN 16
-struct usb_device_info {
- u_int8_t udi_bus;
- u_int8_t udi_addr; /* device address */
- usb_event_cookie_t udi_cookie;
- char udi_product[USB_MAX_STRING_LEN];
- char udi_vendor[USB_MAX_STRING_LEN];
- char udi_release[8];
- u_int16_t udi_productNo;
- u_int16_t udi_vendorNo;
- u_int16_t udi_releaseNo;
- u_int8_t udi_class;
- u_int8_t udi_subclass;
- u_int8_t udi_protocol;
- u_int8_t udi_config;
- u_int8_t udi_speed;
-#define USB_SPEED_LOW 1
-#define USB_SPEED_FULL 2
-#define USB_SPEED_HIGH 3
- int udi_power; /* power consumption in mA, 0 if selfpowered */
- int udi_nports;
- char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN];
- u_int8_t udi_ports[16];/* hub only: addresses of devices on ports */
-#define USB_PORT_ENABLED 0xff
-#define USB_PORT_SUSPENDED 0xfe
-#define USB_PORT_POWERED 0xfd
-#define USB_PORT_DISABLED 0xfc
-};
-
-struct usb_ctl_report {
- int ucr_report;
- u_char ucr_data[1024]; /* filled data size will vary */
-};
-
-struct usb_device_stats {
- u_long uds_requests[4]; /* indexed by transfer type UE_* */
-};
-
-/* Events that can be read from /dev/usb */
-struct usb_event {
- int ue_type;
-#define USB_EVENT_CTRLR_ATTACH 1
-#define USB_EVENT_CTRLR_DETACH 2
-#define USB_EVENT_DEVICE_ATTACH 3
-#define USB_EVENT_DEVICE_DETACH 4
-#define USB_EVENT_DRIVER_ATTACH 5
-#define USB_EVENT_DRIVER_DETACH 6
-#define USB_EVENT_IS_ATTACH(n) ((n) == USB_EVENT_CTRLR_ATTACH || (n) == USB_EVENT_DEVICE_ATTACH || (n) == USB_EVENT_DRIVER_ATTACH)
-#define USB_EVENT_IS_DETACH(n) ((n) == USB_EVENT_CTRLR_DETACH || (n) == USB_EVENT_DEVICE_DETACH || (n) == USB_EVENT_DRIVER_DETACH)
- struct timespec ue_time;
- union {
- struct {
- int ue_bus;
- } ue_ctrlr;
- struct usb_device_info ue_device;
- struct {
- usb_event_cookie_t ue_cookie;
- char ue_devname[16];
- } ue_driver;
- } u;
-};
-
-/* USB controller */
-#define USB_REQUEST _IOWR('U', 1, struct usb_ctl_request)
-#define USB_SETDEBUG _IOW ('U', 2, int)
-#define USB_DISCOVER _IO ('U', 3)
-#define USB_DEVICEINFO _IOWR('U', 4, struct usb_device_info)
-#define USB_DEVICESTATS _IOR ('U', 5, struct usb_device_stats)
-
-/* Generic HID device */
-#define USB_GET_REPORT_DESC _IOR ('U', 21, struct usb_ctl_report_desc)
-#define USB_SET_IMMED _IOW ('U', 22, int)
-#define USB_GET_REPORT _IOWR('U', 23, struct usb_ctl_report)
-#define USB_SET_REPORT _IOW ('U', 24, struct usb_ctl_report)
-#define USB_GET_REPORT_ID _IOR ('U', 25, int)
-
-/* Generic USB device */
-#define USB_GET_CONFIG _IOR ('U', 100, int)
-#define USB_SET_CONFIG _IOW ('U', 101, int)
-#define USB_GET_ALTINTERFACE _IOWR('U', 102, struct usb_alt_interface)
-#define USB_SET_ALTINTERFACE _IOWR('U', 103, struct usb_alt_interface)
-#define USB_GET_NO_ALT _IOWR('U', 104, struct usb_alt_interface)
-#define USB_GET_DEVICE_DESC _IOR ('U', 105, usb_device_descriptor_t)
-#define USB_GET_CONFIG_DESC _IOWR('U', 106, struct usb_config_desc)
-#define USB_GET_INTERFACE_DESC _IOWR('U', 107, struct usb_interface_desc)
-#define USB_GET_ENDPOINT_DESC _IOWR('U', 108, struct usb_endpoint_desc)
-#define USB_GET_FULL_DESC _IOWR('U', 109, struct usb_full_desc)
-#define USB_GET_STRING_DESC _IOWR('U', 110, struct usb_string_desc)
-#define USB_DO_REQUEST _IOWR('U', 111, struct usb_ctl_request)
-#define USB_GET_DEVICEINFO _IOR ('U', 112, struct usb_device_info)
-#define USB_SET_SHORT_XFER _IOW ('U', 113, int)
-#define USB_SET_TIMEOUT _IOW ('U', 114, int)
-#define USB_RESET_DEVICE _IO ('U', 115)
-
-/* Modem device */
-#define USB_GET_CM_OVER_DATA _IOR ('U', 130, int)
-#define USB_SET_CM_OVER_DATA _IOW ('U', 131, int)
-
-#endif /* _USB_H_ */
diff --git a/sys/legacy/dev/usb/usb_if.m b/sys/legacy/dev/usb/usb_if.m
deleted file mode 100644
index b04c8a4..0000000
--- a/sys/legacy/dev/usb/usb_if.m
+++ /dev/null
@@ -1,42 +0,0 @@
-#-
-# Copyright (c) 1992-1998 Nick Hibma <n_hibma@freebsd.org>
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer,
-# without modification, immediately at the beginning of the file.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# 3. The name of the author may not be used to endorse or promote products
-# derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# $FreeBSD$
-#
-
-# USB interface description
-#
-
-#include <sys/bus.h>
-
-INTERFACE usb;
-
-# The device should start probing for new drivers again
-#
-METHOD int reconfigure {
- device_t dev;
-};
diff --git a/sys/legacy/dev/usb/usb_mem.c b/sys/legacy/dev/usb/usb_mem.c
deleted file mode 100644
index bbb0bf6..0000000
--- a/sys/legacy/dev/usb/usb_mem.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/* $NetBSD: usb_mem.c,v 1.26 2003/02/01 06:23:40 thorpej Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * USB DMA memory allocation.
- * We need to allocate a lot of small (many 8 byte, some larger)
- * memory blocks that can be used for DMA. Using the bus_dma
- * routines directly would incur large overheads in space and time.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/endian.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/queue.h>
-
-#include <machine/bus.h>
-#include <machine/endian.h>
-
-#ifdef DIAGNOSTIC
-#include <sys/proc.h>
-#endif
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h> /* just for usb_dma_t */
-#include <dev/usb/usb_mem.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-extern int usbdebug;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define USB_MEM_SMALL 64
-#define USB_MEM_CHUNKS (PAGE_SIZE / USB_MEM_SMALL)
-#define USB_MEM_BLOCK (USB_MEM_SMALL * USB_MEM_CHUNKS)
-
-/* This struct is overlayed on free fragments. */
-struct usb_frag_dma {
- usb_dma_block_t *block;
- u_int offs;
- LIST_ENTRY(usb_frag_dma) next;
-};
-
-static bus_dmamap_callback_t usbmem_callback;
-static usbd_status usb_block_allocmem(bus_dma_tag_t, size_t, size_t,
- usb_dma_block_t **);
-static void usb_block_freemem(usb_dma_block_t *);
-
-static LIST_HEAD(, usb_dma_block) usb_blk_freelist =
- LIST_HEAD_INITIALIZER(usb_blk_freelist);
-static int usb_blk_nfree = 0;
-/* XXX should have different free list for different tags (for speed) */
-static LIST_HEAD(, usb_frag_dma) usb_frag_freelist =
- LIST_HEAD_INITIALIZER(usb_frag_freelist);
-
-static void
-usbmem_callback(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- int i;
- usb_dma_block_t *p = arg;
-
- if (error == EFBIG) {
- printf("usb: mapping to large\n");
- return;
- }
-
- p->nsegs = nseg;
- for (i = 0; i < nseg && i < sizeof p->segs / sizeof *p->segs; i++)
- p->segs[i] = segs[i];
-}
-
-static usbd_status
-usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align,
- usb_dma_block_t **dmap)
-{
- usb_dma_block_t *p;
- int s;
-
- DPRINTFN(5, ("usb_block_allocmem: size=%lu align=%lu\n",
- (u_long)size, (u_long)align));
-
-#ifdef DIAGNOSTIC
- if (!curproc) {
- printf("usb_block_allocmem: in interrupt context, size=%lu\n",
- (unsigned long) size);
- }
-#endif
-
- s = splusb();
- /* First check the free list. */
- for (p = LIST_FIRST(&usb_blk_freelist); p; p = LIST_NEXT(p, next)) {
- if (p->tag == tag && p->size >= size && p->size < size * 2 &&
- p->align >= align) {
- LIST_REMOVE(p, next);
- usb_blk_nfree--;
- splx(s);
- *dmap = p;
- DPRINTFN(6,("usb_block_allocmem: free list size=%lu\n",
- (u_long)p->size));
- return (USBD_NORMAL_COMPLETION);
- }
- }
- splx(s);
-
-#ifdef DIAGNOSTIC
- if (!curproc) {
- printf("usb_block_allocmem: in interrupt context, failed\n");
- return (USBD_NOMEM);
- }
-#endif
-
- DPRINTFN(6, ("usb_block_allocmem: no free\n"));
- p = malloc(sizeof *p, M_USB, M_NOWAIT);
- if (p == NULL)
- return (USBD_NOMEM);
-
- if (bus_dma_tag_create(tag, align, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- size, sizeof(p->segs) / sizeof(p->segs[0]), size,
- 0, NULL, NULL, &p->tag) == ENOMEM)
- {
- goto free;
- }
-
- p->size = size;
- p->align = align;
- if (bus_dmamem_alloc(p->tag, &p->kaddr,
- BUS_DMA_NOWAIT|BUS_DMA_COHERENT, &p->map))
- goto tagfree;
-
- if (bus_dmamap_load(p->tag, p->map, p->kaddr, p->size,
- usbmem_callback, p, 0))
- goto memfree;
-
- /* XXX - override the tag, ok since we never free it */
- p->tag = tag;
- *dmap = p;
- return (USBD_NORMAL_COMPLETION);
-
- /*
- * XXX - do we need to _unload? is the order of _free and _destroy
- * correct?
- */
-memfree:
- bus_dmamem_free(p->tag, p->kaddr, p->map);
-tagfree:
- bus_dma_tag_destroy(p->tag);
-free:
- free(p, M_USB);
- return (USBD_NOMEM);
-}
-
-/*
- * Do not free the memory unconditionally since we might be called
- * from an interrupt context and that is BAD.
- * XXX when should we really free?
- */
-static void
-usb_block_freemem(usb_dma_block_t *p)
-{
- int s;
-
- DPRINTFN(6, ("usb_block_freemem: size=%lu\n", (u_long)p->size));
- s = splusb();
- LIST_INSERT_HEAD(&usb_blk_freelist, p, next);
- usb_blk_nfree++;
- splx(s);
-}
-
-usbd_status
-usb_allocmem(usbd_bus_handle bus, size_t size, size_t align, usb_dma_t *p)
-{
- bus_dma_tag_t tag = bus->parent_dmatag;
- usbd_status err;
- struct usb_frag_dma *f;
- usb_dma_block_t *b;
- int i;
- int s;
-
- /* compat w/ Net/OpenBSD */
- if (align == 0)
- align = 1;
-
- /* If the request is large then just use a full block. */
- if (size > USB_MEM_SMALL || align > USB_MEM_SMALL) {
- DPRINTFN(1, ("usb_allocmem: large alloc %d\n", (int)size));
- size = (size + USB_MEM_BLOCK - 1) & ~(USB_MEM_BLOCK - 1);
- err = usb_block_allocmem(tag, size, align, &p->block);
- if (!err) {
- p->block->fullblock = 1;
- p->offs = 0;
- p->len = size;
- }
- return (err);
- }
-
- s = splusb();
- /* Check for free fragments. */
- for (f = LIST_FIRST(&usb_frag_freelist); f; f = LIST_NEXT(f, next))
- if (f->block->tag == tag)
- break;
- if (f == NULL) {
- DPRINTFN(1, ("usb_allocmem: adding fragments\n"));
- err = usb_block_allocmem(tag, USB_MEM_BLOCK, USB_MEM_SMALL,&b);
- if (err) {
- splx(s);
- return (err);
- }
- b->fullblock = 0;
- /* XXX - override the tag, ok since we never free it */
- b->tag = tag;
- KASSERT(sizeof *f <= USB_MEM_SMALL, ("USB_MEM_SMALL(%d) is too small for struct usb_frag_dma(%zd)\n",
- USB_MEM_SMALL, sizeof *f));
- for (i = 0; i < USB_MEM_BLOCK; i += USB_MEM_SMALL) {
- f = (struct usb_frag_dma *)((char *)b->kaddr + i);
- f->block = b;
- f->offs = i;
- LIST_INSERT_HEAD(&usb_frag_freelist, f, next);
- }
- f = LIST_FIRST(&usb_frag_freelist);
- }
- p->block = f->block;
- p->offs = f->offs;
- p->len = USB_MEM_SMALL;
- LIST_REMOVE(f, next);
- splx(s);
- DPRINTFN(5, ("usb_allocmem: use frag=%p size=%d\n", f, (int)size));
- return (USBD_NORMAL_COMPLETION);
-}
-
-void
-usb_freemem(usbd_bus_handle bus, usb_dma_t *p)
-{
- struct usb_frag_dma *f;
- int s;
-
- if (p->block->fullblock) {
- DPRINTFN(1, ("usb_freemem: large free\n"));
- usb_block_freemem(p->block);
- return;
- }
- f = KERNADDR(p, 0);
- f->block = p->block;
- f->offs = p->offs;
- s = splusb();
- LIST_INSERT_HEAD(&usb_frag_freelist, f, next);
- splx(s);
- DPRINTFN(5, ("usb_freemem: frag=%p\n", f));
-}
diff --git a/sys/legacy/dev/usb/usb_mem.h b/sys/legacy/dev/usb/usb_mem.h
deleted file mode 100644
index b8f0a14..0000000
--- a/sys/legacy/dev/usb/usb_mem.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* $NetBSD: usb_mem.h,v 1.18 2002/05/28 17:45:17 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-typedef struct usb_dma_block {
- bus_dma_tag_t tag;
- bus_dmamap_t map;
- void *kaddr;
- bus_dma_segment_t segs[1];
- int nsegs;
- size_t size;
- size_t align;
- int fullblock;
- LIST_ENTRY(usb_dma_block) next;
-} usb_dma_block_t;
-
-#define DMAADDR(dma, o) ((dma)->block->segs[0].ds_addr + (dma)->offs + (o))
-#define KERNADDR(dma, o) \
- ((void *)((char *)((dma)->block->kaddr) + (dma)->offs + (o)))
-
-usbd_status usb_allocmem(usbd_bus_handle,size_t,size_t, usb_dma_t *);
-void usb_freemem(usbd_bus_handle, usb_dma_t *);
diff --git a/sys/legacy/dev/usb/usb_port.h b/sys/legacy/dev/usb/usb_port.h
deleted file mode 100644
index fd92d7b..0000000
--- a/sys/legacy/dev/usb/usb_port.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* $OpenBSD: usb_port.h,v 1.18 2000/09/06 22:42:10 rahnds Exp $ */
-/* $NetBSD: usb_port.h,v 1.54 2002/03/28 21:49:19 ichiro Exp $ */
-/* $FreeBSD$ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: usb_port.h,v 1.57 2002/09/27 20:42:01 thorpej Exp $
- * $NetBSD: usb_port.h,v 1.58 2002/10/01 01:25:26 thorpej Exp $
- */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _USB_PORT_H
-#define _USB_PORT_H
-
-/*
- * Macro's to cope with the differences between operating systems.
- */
-
-/*
- * FreeBSD
- */
-
-/* We don't use the soft interrupt code in FreeBSD. */
-#if 0
-#define USB_USE_SOFTINTR
-#endif
-
-#define Static static
-
-#define device_ptr_t device_t
-#define USBBASEDEVICE device_t
-#define USBDEV(bdev) (bdev)
-#define USBDEVNAME(bdev) device_get_nameunit(bdev)
-#define USBDEVPTRNAME(bdev) device_get_nameunit(bdev)
-#define USBDEVUNIT(bdev) device_get_unit(bdev)
-#define USBGETSOFTC(bdev) (device_get_softc(bdev))
-
-#define DECLARE_USB_DMA_T \
- struct usb_dma_block; \
- typedef struct { \
- struct usb_dma_block *block; \
- u_int offs; \
- u_int len; \
- } usb_dma_t
-
-typedef struct thread *usb_proc_ptr;
-
-#define uio_procp uio_td
-
-#define usb_kthread_create1(f, s, p, a0, a1) \
- kproc_create((f), (s), (p), RFHIGHPID, 0, (a0), (a1))
-#define usb_kthread_create2(f, s, p, a0) \
- kproc_create((f), (s), (p), RFHIGHPID, 0, (a0))
-#define usb_kthread_create kproc_create
-
-#define config_pending_incr()
-#define config_pending_decr()
-
-typedef struct callout usb_callout_t;
-#define usb_callout_init(h) callout_init(&(h), 0)
-#define usb_callout(h, t, f, d) callout_reset(&(h), (t), (f), (d))
-#define usb_uncallout(h, f, d) callout_stop(&(h))
-#define usb_uncallout_drain(h, f, d) callout_drain(&(h))
-
-#define clalloc(p, s, x) (clist_alloc_cblocks((p), (s), (s)), 0)
-#define clfree(p) clist_free_cblocks((p))
-
-#define config_detach(dev, flag) \
- do { \
- device_detach(dev); \
- free(device_get_ivars(dev), M_USB); \
- device_delete_child(device_get_parent(dev), dev); \
- } while (0);
-
-typedef struct malloc_type *usb_malloc_type;
-
-#define USB_DECLARE_DRIVER_INIT(dname, init...) \
-static device_probe_t __CONCAT(dname,_match); \
-static device_attach_t __CONCAT(dname,_attach); \
-static device_detach_t __CONCAT(dname,_detach); \
-\
-static devclass_t __CONCAT(dname,_devclass); \
-\
-static device_method_t __CONCAT(dname,_methods)[] = { \
- DEVMETHOD(device_probe, __CONCAT(dname,_match)), \
- DEVMETHOD(device_attach, __CONCAT(dname,_attach)), \
- DEVMETHOD(device_detach, __CONCAT(dname,_detach)), \
- init, \
- {0,0} \
-}; \
-\
-static driver_t __CONCAT(dname,_driver) = { \
- #dname, \
- __CONCAT(dname,_methods), \
- sizeof(struct __CONCAT(dname,_softc)) \
-}; \
-MODULE_DEPEND(dname, usb, 1, 1, 1)
-
-
-#define METHODS_NONE {0,0}
-#define USB_DECLARE_DRIVER(dname) USB_DECLARE_DRIVER_INIT(dname, METHODS_NONE)
-
-#define USB_MATCH(dname) \
-static int \
-__CONCAT(dname,_match)(device_t self)
-
-#define USB_MATCH_START(dname, uaa) \
- struct usb_attach_arg *uaa = device_get_ivars(self)
-
-#define USB_MATCH_SETUP \
- sc->sc_dev = self
-
-#define USB_ATTACH(dname) \
-static int \
-__CONCAT(dname,_attach)(device_t self)
-
-#define USB_ATTACH_START(dname, sc, uaa) \
- struct __CONCAT(dname,_softc) *sc = device_get_softc(self); \
- struct usb_attach_arg *uaa = device_get_ivars(self)
-
-/* Returns from attach */
-#define USB_ATTACH_ERROR_RETURN return ENXIO
-#define USB_ATTACH_SUCCESS_RETURN return 0
-
-#define USB_ATTACH_SETUP \
- sc->sc_dev = self; \
-
-#define USB_DETACH(dname) \
-static int \
-__CONCAT(dname,_detach)(device_t self)
-
-#define USB_DETACH_START(dname, sc) \
- struct __CONCAT(dname,_softc) *sc = device_get_softc(self)
-
-#define USB_GET_SC_OPEN(dname, unit, sc) \
- sc = devclass_get_softc(__CONCAT(dname,_devclass), unit); \
- if (sc == NULL) \
- return (ENXIO)
-
-#define USB_GET_SC(dname, unit, sc) \
- sc = devclass_get_softc(__CONCAT(dname,_devclass), unit)
-
-#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
- (device_probe_and_attach((bdev)) == 0 ? (bdev) : 0)
-
-/* conversion from one type of queue to the other */
-#define SIMPLEQ_REMOVE_HEAD STAILQ_REMOVE_HEAD
-#define SIMPLEQ_INSERT_HEAD STAILQ_INSERT_HEAD
-#define SIMPLEQ_INSERT_TAIL STAILQ_INSERT_TAIL
-#define SIMPLEQ_NEXT STAILQ_NEXT
-#define SIMPLEQ_FIRST STAILQ_FIRST
-#define SIMPLEQ_HEAD STAILQ_HEAD
-#define SIMPLEQ_EMPTY STAILQ_EMPTY
-#define SIMPLEQ_FOREACH STAILQ_FOREACH
-#define SIMPLEQ_INIT STAILQ_INIT
-#define SIMPLEQ_HEAD_INITIALIZER STAILQ_HEAD_INITIALIZER
-#define SIMPLEQ_ENTRY STAILQ_ENTRY
-
-#include <sys/syslog.h>
-/*
-#define logprintf(args...) log(LOG_DEBUG, args)
-*/
-#define logprintf printf
-
-#endif /* _USB_PORT_H */
diff --git a/sys/legacy/dev/usb/usb_quirks.c b/sys/legacy/dev/usb/usb_quirks.c
deleted file mode 100644
index 2771bb7..0000000
--- a/sys/legacy/dev/usb/usb_quirks.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* $NetBSD: usb_quirks.c,v 1.50 2004/06/23 02:30:52 mycroft Exp $ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <dev/usb/usb.h>
-
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#ifdef USB_DEBUG
-extern int usbdebug;
-#endif
-
-#define ANY 0xffff
-
-static const struct usbd_quirk_entry {
- u_int16_t idVendor;
- u_int16_t idProduct;
- u_int16_t bcdDevice;
- struct usbd_quirks quirks;
-} usb_quirks[] = {
- { USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4,
- 0x094, { UQ_SWAP_UNICODE}},
- { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, { UQ_BAD_ADC }},
- { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, { UQ_AU_NO_XU }},
- { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, 0x103, { UQ_BAD_ADC }},
- { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495, 0x000, { UQ_BAD_AUDIO }},
- { USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, 0x110, { UQ_SPUR_BUT_UP }},
- { USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB, 0x001, { UQ_SPUR_BUT_UP }},
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100, 0x102, { UQ_BUS_POWERED }},
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, 0x102, { UQ_BUS_POWERED }},
- { USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, 0x110, { UQ_POWER_CLAIM }},
- { USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0x009, { UQ_AU_NO_FRAC }},
- { USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE,
- 0x100, { UQ_AU_INP_ASYNC }},
- { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN53B, ANY, { UQ_NO_STRINGS }},
- /* XXX These should have a revision number, but I don't know what they are. */
- { USB_VENDOR_HP, USB_PRODUCT_HP_895C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_HP, USB_PRODUCT_HP_880C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_HP, USB_PRODUCT_HP_815C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_HP, USB_PRODUCT_HP_810C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_HP, USB_PRODUCT_HP_830C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_HP, USB_PRODUCT_HP_1220C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_XEROX, USB_PRODUCT_XEROX_WCM15, ANY, { UQ_BROKEN_BIDIR }},
- /* MS keyboards do weird things */
- { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK,
- ANY, { UQ_MS_BAD_CLASS | UQ_MS_LEADING_BYTE }},
- { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK2,
- ANY, { UQ_MS_BAD_CLASS | UQ_MS_LEADING_BYTE }},
- { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE,
- ANY, { UQ_MS_LEADING_BYTE }},
- { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_COMFORT3000,
- ANY, { UQ_MS_BAD_CLASS | UQ_MS_LEADING_BYTE }},
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_RF_RECEIVER,
- ANY,{ UQ_MS_BAD_CLASS }},
-
- /* Devices which should be ignored by uhid */
- { USB_VENDOR_APC, USB_PRODUCT_APC_UPS,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_LCM,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_1500CAVRLCD,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD2X20,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G,
- ANY, { UQ_HID_IGNORE }},
-
- /* Devices which should be ignored by both ukbd and uhid */
- { USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_WISPY1A,
- ANY, { UQ_KBD_IGNORE }},
- { USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY1B,
- ANY, { UQ_KBD_IGNORE }},
- { USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24X,
- ANY, { UQ_KBD_IGNORE }},
- { 0, 0, 0, { 0 } }
-};
-
-const struct usbd_quirks usbd_no_quirk = { 0 };
-
-const struct usbd_quirks *
-usbd_find_quirk(usb_device_descriptor_t *d)
-{
- const struct usbd_quirk_entry *t;
- u_int16_t vendor = UGETW(d->idVendor);
- u_int16_t product = UGETW(d->idProduct);
- u_int16_t revision = UGETW(d->bcdDevice);
-
- for (t = usb_quirks; t->idVendor != 0; t++) {
- if (t->idVendor == vendor &&
- t->idProduct == product &&
- (t->bcdDevice == ANY || t->bcdDevice == revision))
- break;
- }
-#ifdef USB_DEBUG
- if (usbdebug && t->quirks.uq_flags)
- printf("usbd_find_quirk 0x%04x/0x%04x/%x: %d\n",
- UGETW(d->idVendor), UGETW(d->idProduct),
- UGETW(d->bcdDevice), t->quirks.uq_flags);
-#endif
- return (&t->quirks);
-}
diff --git a/sys/legacy/dev/usb/usb_quirks.h b/sys/legacy/dev/usb/usb_quirks.h
deleted file mode 100644
index 16e2f3f..0000000
--- a/sys/legacy/dev/usb/usb_quirks.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* $NetBSD: usb_quirks.h,v 1.20 2001/04/15 09:38:01 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-struct usbd_quirks {
- u_int32_t uq_flags; /* Device problems: */
-#define UQ_SWAP_UNICODE 0x00000002 /* has some Unicode strings swapped. */
-#define UQ_MS_REVZ 0x00000004 /* mouse has Z-axis reversed */
-#define UQ_NO_STRINGS 0x00000008 /* string descriptors are broken. */
-#define UQ_BAD_ADC 0x00000010 /* bad audio spec version number. */
-#define UQ_BUS_POWERED 0x00000020 /* device is bus powered, despite claim */
-#define UQ_BAD_AUDIO 0x00000040 /* device claims audio class, but isn't */
-#define UQ_SPUR_BUT_UP 0x00000080 /* spurious mouse button up events */
-#define UQ_AU_NO_XU 0x00000100 /* audio device has broken extension unit */
-#define UQ_POWER_CLAIM 0x00000200 /* hub lies about power status */
-#define UQ_AU_NO_FRAC 0x00000400 /* don't adjust for fractional samples */
-#define UQ_AU_INP_ASYNC 0x00000800 /* input is async despite claim of adaptive */
-#define UQ_BROKEN_BIDIR 0x00002000 /* printer has broken bidir mode */
-#define UQ_OPEN_CLEARSTALL 0x04000 /* device needs clear endpoint stall */
-#define UQ_HID_IGNORE 0x00008000 /* device should be ignored by hid class */
-#define UQ_KBD_IGNORE 0x00018000 /* device should be ignored by both kbd and hid class */
-#define UQ_MS_BAD_CLASS 0x00020000 /* doesn't identify properly */
-#define UQ_MS_LEADING_BYTE 0x40000 /* mouse sends an unknown leading byte. */
-};
-
-extern const struct usbd_quirks usbd_no_quirk;
-
-const struct usbd_quirks *usbd_find_quirk(usb_device_descriptor_t *);
diff --git a/sys/legacy/dev/usb/usb_subr.c b/sys/legacy/dev/usb/usb_subr.c
deleted file mode 100644
index 29d044c..0000000
--- a/sys/legacy/dev/usb/usb_subr.c
+++ /dev/null
@@ -1,1388 +0,0 @@
-/* $NetBSD: usb_subr.c,v 1.99 2002/07/11 21:14:34 augustss Exp $ */
-
-/* Also already have from NetBSD:
- * $NetBSD: usb_subr.c,v 1.102 2003/01/01 16:21:50 augustss Exp $
- * $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $
- * $NetBSD: usb_subr.c,v 1.111 2004/03/15 10:35:04 augustss Exp $
- * $NetBSD: usb_subr.c,v 1.114 2004/06/23 02:30:52 mycroft Exp $
- * $NetBSD: usb_subr.c,v 1.115 2004/06/23 05:23:19 mycroft Exp $
- * $NetBSD: usb_subr.c,v 1.116 2004/06/23 06:27:54 mycroft Exp $
- * $NetBSD: usb_subr.c,v 1.119 2004/10/23 13:26:33 augustss Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opt_usb.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/proc.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#define delay(d) DELAY(d)
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-extern int usbdebug;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-static usbd_status usbd_set_config(usbd_device_handle, int);
-static void usbd_devinfo_vp(usbd_device_handle, char *, char *, int);
-static int usbd_getnewaddr(usbd_bus_handle bus);
-static void usbd_free_iface_data(usbd_device_handle dev, int ifcno);
-static void usbd_kill_pipe(usbd_pipe_handle);
-static usbd_status usbd_probe_and_attach(device_t parent,
- usbd_device_handle dev, int port, int addr);
-
-static u_int32_t usb_cookie_no = 0;
-
-#ifdef USBVERBOSE
-typedef u_int16_t usb_vendor_id_t;
-typedef u_int16_t usb_product_id_t;
-
-/*
- * Descriptions of of known vendors and devices ("products").
- */
-struct usb_knowndev {
- usb_vendor_id_t vendor;
- usb_product_id_t product;
- int flags;
- char *vendorname, *productname;
-};
-#define USB_KNOWNDEV_NOPROD 0x01 /* match on vendor only */
-
-#include "usbdevs_data.h"
-#endif /* USBVERBOSE */
-
-static const char * const usbd_error_strs[] = {
- "NORMAL_COMPLETION",
- "IN_PROGRESS",
- "PENDING_REQUESTS",
- "NOT_STARTED",
- "INVAL",
- "NOMEM",
- "CANCELLED",
- "BAD_ADDRESS",
- "IN_USE",
- "NO_ADDR",
- "SET_ADDR_FAILED",
- "NO_POWER",
- "TOO_DEEP",
- "IOERROR",
- "NOT_CONFIGURED",
- "TIMEOUT",
- "SHORT_XFER",
- "STALLED",
- "INTERRUPTED",
- "XXX",
-};
-
-const char *
-usbd_errstr(usbd_status err)
-{
- static char buffer[5];
-
- if (err < USBD_ERROR_MAX) {
- return usbd_error_strs[err];
- } else {
- snprintf(buffer, sizeof buffer, "%d", err);
- return buffer;
- }
-}
-
-usbd_status
-usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
- usb_string_descriptor_t *sdesc, int *sizep)
-{
- usb_device_request_t req;
- usbd_status err;
- int actlen;
-
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW2(req.wValue, UDESC_STRING, sindex);
- USETW(req.wIndex, langid);
- USETW(req.wLength, 2); /* only size byte first */
- err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
- &actlen, USBD_DEFAULT_TIMEOUT);
- if (err)
- return (err);
-
- if (actlen < 2)
- return (USBD_SHORT_XFER);
-
- USETW(req.wLength, sdesc->bLength); /* the whole string */
- err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
- &actlen, USBD_DEFAULT_TIMEOUT);
- if (err)
- return (err);
-
- if (actlen != sdesc->bLength) {
- DPRINTFN(-1, ("usbd_get_string_desc: expected %d, got %d\n",
- sdesc->bLength, actlen));
- }
-
- *sizep = actlen;
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-usbd_trim_spaces(char *p)
-{
- char *q, *e;
-
- if (p == NULL)
- return;
- q = e = p;
- while (*q == ' ') /* skip leading spaces */
- q++;
- while ((*p = *q++)) /* copy string */
- if (*p++ != ' ') /* remember last non-space */
- e = p;
- *e = 0; /* kill trailing spaces */
-}
-
-static void
-usbd_devinfo_vp(usbd_device_handle dev, char *v, char *p, int usedev)
-{
- usb_device_descriptor_t *udd = &dev->ddesc;
- char *vendor = 0, *product = 0;
-#ifdef USBVERBOSE
- const struct usb_knowndev *kdp;
-#endif
-
- if (dev == NULL) {
- v[0] = p[0] = '\0';
- return;
- }
-
- if (usedev) {
- if (usbd_get_string(dev, udd->iManufacturer, v,
- USB_MAX_STRING_LEN))
- vendor = NULL;
- else
- vendor = v;
- usbd_trim_spaces(vendor);
- if (usbd_get_string(dev, udd->iProduct, p,
- USB_MAX_STRING_LEN))
- product = NULL;
- else
- product = p;
- usbd_trim_spaces(product);
- if (vendor && !*vendor)
- vendor = NULL;
- if (product && !*product)
- product = NULL;
- } else {
- vendor = NULL;
- product = NULL;
- }
-#ifdef USBVERBOSE
- if (vendor == NULL || product == NULL) {
- for(kdp = usb_knowndevs;
- kdp->vendorname != NULL;
- kdp++) {
- if (kdp->vendor == UGETW(udd->idVendor) &&
- (kdp->product == UGETW(udd->idProduct) ||
- (kdp->flags & USB_KNOWNDEV_NOPROD) != 0))
- break;
- }
- if (kdp->vendorname != NULL) {
- if (vendor == NULL)
- vendor = kdp->vendorname;
- if (product == NULL)
- product = (kdp->flags & USB_KNOWNDEV_NOPROD) == 0 ?
- kdp->productname : NULL;
- }
- }
-#endif
- if (vendor != NULL && *vendor)
- strcpy(v, vendor);
- else
- sprintf(v, "vendor 0x%04x", UGETW(udd->idVendor));
- if (product != NULL && *product)
- strcpy(p, product);
- else
- sprintf(p, "product 0x%04x", UGETW(udd->idProduct));
-}
-
-int
-usbd_printBCD(char *cp, int bcd)
-{
- return (sprintf(cp, "%x.%02x", bcd >> 8, bcd & 0xff));
-}
-
-void
-usbd_devinfo(usbd_device_handle dev, int showclass, char *cp)
-{
- usb_device_descriptor_t *udd = &dev->ddesc;
- usbd_interface_handle iface;
- char vendor[USB_MAX_STRING_LEN];
- char product[USB_MAX_STRING_LEN];
- int bcdDevice, bcdUSB;
- usb_interface_descriptor_t *id;
-
- usbd_devinfo_vp(dev, vendor, product, 1);
- cp += sprintf(cp, "%s %s", vendor, product);
- if (showclass & USBD_SHOW_DEVICE_CLASS)
- cp += sprintf(cp, ", class %d/%d",
- udd->bDeviceClass, udd->bDeviceSubClass);
- bcdUSB = UGETW(udd->bcdUSB);
- bcdDevice = UGETW(udd->bcdDevice);
- cp += sprintf(cp, ", rev ");
- cp += usbd_printBCD(cp, bcdUSB);
- *cp++ = '/';
- cp += usbd_printBCD(cp, bcdDevice);
- cp += sprintf(cp, ", addr %d", dev->address);
- if (showclass & USBD_SHOW_INTERFACE_CLASS)
- {
- /* fetch the interface handle for the first interface */
- (void)usbd_device2interface_handle(dev, 0, &iface);
- id = usbd_get_interface_descriptor(iface);
- cp += sprintf(cp, ", iclass %d/%d",
- id->bInterfaceClass, id->bInterfaceSubClass);
- }
- *cp = 0;
-}
-
-/* Delay for a certain number of ms */
-void
-usb_delay_ms(usbd_bus_handle bus, u_int ms)
-{
- /* Wait at least two clock ticks so we know the time has passed. */
- if (bus->use_polling || cold)
- delay((ms+1) * 1000);
- else
- pause("usbdly", (ms*hz+999)/1000 + 1);
-}
-
-/* Delay given a device handle. */
-void
-usbd_delay_ms(usbd_device_handle dev, u_int ms)
-{
- usb_delay_ms(dev->bus, ms);
-}
-
-usbd_status
-usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
-{
- usbd_status err;
- int n;
-
- err = usbd_set_port_feature(dev, port, UHF_PORT_RESET);
- DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
- port, usbd_errstr(err)));
- if (err)
- return (err);
- n = 10;
- do {
- /* Wait for device to recover from reset. */
- usbd_delay_ms(dev, USB_PORT_RESET_DELAY);
- err = usbd_get_port_status(dev, port, ps);
- if (err) {
- DPRINTF(("usbd_reset_port: get status failed %d\n",
- err));
- return (err);
- }
- /* If the device disappeared, just give up. */
- if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS))
- return (USBD_NORMAL_COMPLETION);
- } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
- if (n == 0)
- return (USBD_TIMEOUT);
- err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
-#ifdef USB_DEBUG
- if (err)
- DPRINTF(("usbd_reset_port: clear port feature failed %d\n",
- err));
-#endif
-
- /* Wait for the device to recover from reset. */
- usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY);
- return (err);
-}
-
-usb_interface_descriptor_t *
-usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx)
-{
- char *p = (char *)cd;
- char *end = p + UGETW(cd->wTotalLength);
- usb_interface_descriptor_t *d;
- int curidx, lastidx, curaidx = 0;
-
- for (curidx = lastidx = -1; p < end; ) {
- d = (usb_interface_descriptor_t *)p;
- DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d "
- "type=%d\n",
- ifaceidx, curidx, altidx, curaidx,
- d->bLength, d->bDescriptorType));
- if (d->bLength == 0) /* bad descriptor */
- break;
- p += d->bLength;
- if (p <= end && d->bDescriptorType == UDESC_INTERFACE) {
- if (d->bInterfaceNumber != lastidx) {
- lastidx = d->bInterfaceNumber;
- curidx++;
- curaidx = 0;
- } else
- curaidx++;
- if (ifaceidx == curidx && altidx == curaidx)
- return (d);
- }
- }
- return (NULL);
-}
-
-usb_endpoint_descriptor_t *
-usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx,
- int endptidx)
-{
- char *p = (char *)cd;
- char *end = p + UGETW(cd->wTotalLength);
- usb_interface_descriptor_t *d;
- usb_endpoint_descriptor_t *e;
- int curidx;
-
- d = usbd_find_idesc(cd, ifaceidx, altidx);
- if (d == NULL)
- return (NULL);
- if (endptidx >= d->bNumEndpoints) /* quick exit */
- return (NULL);
-
- curidx = -1;
- for (p = (char *)d + d->bLength; p < end; ) {
- e = (usb_endpoint_descriptor_t *)p;
- if (e->bLength == 0) /* bad descriptor */
- break;
- p += e->bLength;
- if (p <= end && e->bDescriptorType == UDESC_INTERFACE)
- return (NULL);
- if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) {
- curidx++;
- if (curidx == endptidx)
- return (e);
- }
- }
- return (NULL);
-}
-
-usbd_status
-usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
-{
- usbd_interface_handle ifc = &dev->ifaces[ifaceidx];
- usb_interface_descriptor_t *idesc;
- char *p, *end;
- int endpt, nendpt;
-
- DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n",
- ifaceidx, altidx));
- idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx);
- if (idesc == NULL)
- return (USBD_INVAL);
- ifc->device = dev;
- ifc->idesc = idesc;
- ifc->index = ifaceidx;
- ifc->altindex = altidx;
- nendpt = ifc->idesc->bNumEndpoints;
- DPRINTFN(4,("usbd_fill_iface_data: found idesc nendpt=%d\n", nendpt));
- if (nendpt != 0) {
- ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint),
- M_USB, M_NOWAIT);
- if (ifc->endpoints == NULL)
- return (USBD_NOMEM);
- } else
- ifc->endpoints = NULL;
- ifc->priv = NULL;
- p = (char *)ifc->idesc + ifc->idesc->bLength;
- end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength);
-#define ed ((usb_endpoint_descriptor_t *)p)
- for (endpt = 0; endpt < nendpt; endpt++) {
- DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt));
- for (; p < end; p += ed->bLength) {
- DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p "
- "len=%d type=%d\n",
- p, end, ed->bLength, ed->bDescriptorType));
- if (p + ed->bLength <= end && ed->bLength != 0 &&
- ed->bDescriptorType == UDESC_ENDPOINT)
- goto found;
- if (ed->bLength == 0 ||
- ed->bDescriptorType == UDESC_INTERFACE)
- break;
- }
- /* passed end, or bad desc */
- printf("usbd_fill_iface_data: bad descriptor(s): %s\n",
- ed->bLength == 0 ? "0 length" :
- ed->bDescriptorType == UDESC_INTERFACE ? "iface desc":
- "out of data");
- goto bad;
- found:
- ifc->endpoints[endpt].edesc = ed;
- if (dev->speed == USB_SPEED_HIGH) {
- u_int mps;
- /* Control and bulk endpoints have max packet limits. */
- switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
- case UE_CONTROL:
- mps = USB_2_MAX_CTRL_PACKET;
- goto check;
- case UE_BULK:
- mps = USB_2_MAX_BULK_PACKET;
- check:
- if (UGETW(ed->wMaxPacketSize) != mps) {
- USETW(ed->wMaxPacketSize, mps);
-#ifdef DIAGNOSTIC
- printf("usbd_fill_iface_data: bad max "
- "packet size\n");
-#endif
- }
- break;
- default:
- break;
- }
- }
- ifc->endpoints[endpt].refcnt = 0;
- ifc->endpoints[endpt].savedtoggle = 0;
- p += ed->bLength;
- }
-#undef ed
- LIST_INIT(&ifc->pipes);
- return (USBD_NORMAL_COMPLETION);
-
- bad:
- if (ifc->endpoints != NULL) {
- free(ifc->endpoints, M_USB);
- ifc->endpoints = NULL;
- }
- return (USBD_INVAL);
-}
-
-void
-usbd_free_iface_data(usbd_device_handle dev, int ifcno)
-{
- usbd_interface_handle ifc = &dev->ifaces[ifcno];
- if (ifc->endpoints)
- free(ifc->endpoints, M_USB);
-}
-
-static usbd_status
-usbd_set_config(usbd_device_handle dev, int conf)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_SET_CONFIG;
- USETW(req.wValue, conf);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_set_config_no(usbd_device_handle dev, int no, int msg)
-{
- int index;
- usb_config_descriptor_t cd;
- usbd_status err;
-
- if (no == USB_UNCONFIG_NO)
- return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg));
-
- DPRINTFN(5,("usbd_set_config_no: %d\n", no));
- /* Figure out what config index to use. */
- for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
- err = usbd_get_config_desc(dev, index, &cd);
- if (err)
- return (err);
- if (cd.bConfigurationValue == no)
- return (usbd_set_config_index(dev, index, msg));
- }
- return (USBD_INVAL);
-}
-
-usbd_status
-usbd_set_config_index(usbd_device_handle dev, int index, int msg)
-{
- usb_status_t ds;
- usb_config_descriptor_t cd, *cdp;
- usbd_status err;
- int i, ifcidx, nifc, len, selfpowered, power;
-
- DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
-
- if (dev->config != USB_UNCONFIG_NO) {
- nifc = dev->cdesc->bNumInterface;
-
- /* Check that all interfaces are idle */
- for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
- if (LIST_EMPTY(&dev->ifaces[ifcidx].pipes))
- continue;
- DPRINTF(("usbd_set_config_index: open pipes exist\n"));
- return (USBD_IN_USE);
- }
-
- DPRINTF(("usbd_set_config_index: free old config\n"));
- /* Free all configuration data structures. */
- for (ifcidx = 0; ifcidx < nifc; ifcidx++)
- usbd_free_iface_data(dev, ifcidx);
- free(dev->ifaces, M_USB);
- free(dev->cdesc, M_USB);
- dev->ifaces = NULL;
- dev->cdesc = NULL;
- dev->config = USB_UNCONFIG_NO;
- }
-
- if (index == USB_UNCONFIG_INDEX) {
- /* We are unconfiguring the device, so leave unallocated. */
- DPRINTF(("usbd_set_config_index: set config 0\n"));
- err = usbd_set_config(dev, USB_UNCONFIG_NO);
- if (err)
- DPRINTF(("usbd_set_config_index: setting config=0 "
- "failed, error=%s\n", usbd_errstr(err)));
- return (err);
- }
-
- /* Get the short descriptor. */
- err = usbd_get_config_desc(dev, index, &cd);
- if (err)
- return (err);
- len = UGETW(cd.wTotalLength);
- cdp = malloc(len, M_USB, M_NOWAIT);
- if (cdp == NULL)
- return (USBD_NOMEM);
-
- /* Get the full descriptor. Try a few times for slow devices. */
- for (i = 0; i < 3; i++) {
- err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
- if (!err)
- break;
- usbd_delay_ms(dev, 200);
- }
- if (err)
- goto bad;
- if (cdp->bDescriptorType != UDESC_CONFIG) {
- DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
- cdp->bDescriptorType));
- err = USBD_INVAL;
- goto bad;
- }
-
- /* Figure out if the device is self or bus powered. */
- selfpowered = 0;
- if (!(dev->quirks->uq_flags & UQ_BUS_POWERED) &&
- (cdp->bmAttributes & UC_SELF_POWERED)) {
- /* May be self powered. */
- if (cdp->bmAttributes & UC_BUS_POWERED) {
- /* Must ask device. */
- if (dev->quirks->uq_flags & UQ_POWER_CLAIM) {
- /*
- * Hub claims to be self powered, but isn't.
- * It seems that the power status can be
- * determined by the hub characteristics.
- */
- usb_hub_descriptor_t hd;
- usb_device_request_t req;
- req.bmRequestType = UT_READ_CLASS_DEVICE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
- err = usbd_do_request(dev, &req, &hd);
- if (!err &&
- (UGETW(hd.wHubCharacteristics) &
- UHD_PWR_INDIVIDUAL))
- selfpowered = 1;
- DPRINTF(("usbd_set_config_index: charac=0x%04x"
- ", error=%s\n",
- UGETW(hd.wHubCharacteristics),
- usbd_errstr(err)));
- } else {
- err = usbd_get_device_status(dev, &ds);
- if (!err &&
- (UGETW(ds.wStatus) & UDS_SELF_POWERED))
- selfpowered = 1;
- DPRINTF(("usbd_set_config_index: status=0x%04x"
- ", error=%s\n",
- UGETW(ds.wStatus), usbd_errstr(err)));
- }
- } else
- selfpowered = 1;
- }
- DPRINTF(("usbd_set_config_index: (addr %d) cno=%d attr=0x%02x, "
- "selfpowered=%d, power=%d\n",
- cdp->bConfigurationValue, dev->address, cdp->bmAttributes,
- selfpowered, cdp->bMaxPower * 2));
-
- /* Check if we have enough power. */
-#ifdef USB_DEBUG
- if (dev->powersrc == NULL) {
- DPRINTF(("usbd_set_config_index: No power source?\n"));
- return (USBD_IOERROR);
- }
-#endif
- power = cdp->bMaxPower * 2;
- if (power > dev->powersrc->power) {
- DPRINTF(("power exceeded %d %d\n", power,dev->powersrc->power));
- /* XXX print nicer message. */
- if (msg)
- device_printf(dev->bus->bdev,
- "device addr %d (config %d) exceeds "
- "power budget, %d mA > %d mA\n",
- dev->address, cdp->bConfigurationValue,
- power, dev->powersrc->power);
- err = USBD_NO_POWER;
- goto bad;
- }
- dev->power = power;
- dev->self_powered = selfpowered;
-
- /* Set the actual configuration value. */
- DPRINTF(("usbd_set_config_index: set config %d\n",
- cdp->bConfigurationValue));
- err = usbd_set_config(dev, cdp->bConfigurationValue);
- if (err) {
- DPRINTF(("usbd_set_config_index: setting config=%d failed, "
- "error=%s\n",
- cdp->bConfigurationValue, usbd_errstr(err)));
- goto bad;
- }
-
- /* Allocate and fill interface data. */
- nifc = cdp->bNumInterface;
- dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
- M_USB, M_NOWAIT);
- if (dev->ifaces == NULL) {
- err = USBD_NOMEM;
- goto bad;
- }
- DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
- dev->cdesc = cdp;
- dev->config = cdp->bConfigurationValue;
- for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
- err = usbd_fill_iface_data(dev, ifcidx, 0);
- if (err) {
- while (--ifcidx >= 0)
- usbd_free_iface_data(dev, ifcidx);
- goto bad;
- }
- }
-
- return (USBD_NORMAL_COMPLETION);
-
- bad:
- free(cdp, M_USB);
- return (err);
-}
-
-/* XXX add function for alternate settings */
-
-usbd_status
-usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
- struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe)
-{
- usbd_pipe_handle p;
- usbd_status err;
-
- DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
- dev, iface, ep, pipe));
- p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
- if (p == NULL)
- return (USBD_NOMEM);
- p->device = dev;
- p->iface = iface;
- p->endpoint = ep;
- ep->refcnt++;
- p->refcnt = 1;
- p->intrxfer = 0;
- p->running = 0;
- p->aborting = 0;
- p->repeat = 0;
- p->interval = ival;
- STAILQ_INIT(&p->queue);
- err = dev->bus->methods->open_pipe(p);
- if (err) {
- DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
- "%s\n",
- ep->edesc->bEndpointAddress, usbd_errstr(err)));
- free(p, M_USB);
- return (err);
- }
-
- if (dev->quirks->uq_flags & UQ_OPEN_CLEARSTALL) {
- /* Clear any stall and make sure DATA0 toggle will be used next. */
- if (UE_GET_ADDR(ep->edesc->bEndpointAddress) != USB_CONTROL_ENDPOINT) {
- err = usbd_clear_endpoint_stall(p);
- if (err && err != USBD_STALLED && err != USBD_TIMEOUT) {
- printf("usbd_setup_pipe: failed to start "
- "endpoint, %s\n", usbd_errstr(err));
- return (err);
- }
- }
- }
-
- *pipe = p;
- return (USBD_NORMAL_COMPLETION);
-}
-
-/* Abort the device control pipe. */
-void
-usbd_kill_pipe(usbd_pipe_handle pipe)
-{
- usbd_abort_pipe(pipe);
- pipe->methods->close(pipe);
- pipe->endpoint->refcnt--;
- free(pipe, M_USB);
-}
-
-int
-usbd_getnewaddr(usbd_bus_handle bus)
-{
- int addr;
-
- for (addr = 1; addr < USB_MAX_DEVICES; addr++)
- if (bus->devices[addr] == 0)
- return (addr);
- return (-1);
-}
-
-
-usbd_status
-usbd_probe_and_attach(device_t parent, usbd_device_handle dev,
- int port, int addr)
-{
- struct usb_attach_arg uaa;
- usb_device_descriptor_t *dd = &dev->ddesc;
- int found, i, confi, nifaces;
- usbd_status err;
- device_t *tmpdv;
- usbd_interface_handle ifaces[256]; /* 256 is the absolute max */
- char *devinfo;
-
- /* XXX FreeBSD may leak resources on failure cases -- fixme */
- device_t bdev;
- struct usb_attach_arg *uaap;
-
- devinfo = malloc(1024, M_USB, M_NOWAIT);
- if (devinfo == NULL) {
- device_printf(parent, "Can't allocate memory for probe string\n");
- return (USBD_NOMEM);
- }
- bdev = device_add_child(parent, NULL, -1);
- if (!bdev) {
- free(devinfo, M_USB);
- device_printf(parent, "Device creation failed\n");
- return (USBD_INVAL);
- }
- uaap = malloc(sizeof(uaa), M_USB, M_NOWAIT);
- if (uaap == NULL) {
- free(devinfo, M_USB);
- return (USBD_INVAL);
- }
- device_set_ivars(bdev, uaap);
- uaa.device = dev;
- uaa.iface = NULL;
- uaa.ifaces = NULL;
- uaa.nifaces = 0;
- uaa.usegeneric = 0;
- uaa.port = port;
- uaa.configno = UHUB_UNK_CONFIGURATION;
- uaa.ifaceno = UHUB_UNK_INTERFACE;
- uaa.vendor = UGETW(dd->idVendor);
- uaa.product = UGETW(dd->idProduct);
- uaa.release = UGETW(dd->bcdDevice);
- uaa.matchlvl = 0;
-
- /* First try with device specific drivers. */
- DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n"));
-
- dev->ifacenums = NULL;
- dev->subdevs = malloc(2 * sizeof(device_t), M_USB, M_NOWAIT);
- if (dev->subdevs == NULL) {
- free(devinfo, M_USB);
- return (USBD_NOMEM);
- }
- dev->subdevs[0] = bdev;
- dev->subdevs[1] = 0;
- *uaap = uaa;
- usbd_devinfo(dev, 1, devinfo);
- device_set_desc_copy(bdev, devinfo);
- if (device_probe_and_attach(bdev) == 0) {
- free(devinfo, M_USB);
- return (USBD_NORMAL_COMPLETION);
- }
-
- /*
- * Free subdevs so we can reallocate it larger for the number of
- * interfaces
- */
- tmpdv = dev->subdevs;
- dev->subdevs = NULL;
- free(tmpdv, M_USB);
- DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
-
- DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
- dd->bNumConfigurations));
- /* Next try with interface drivers. */
- for (confi = 0; confi < dd->bNumConfigurations; confi++) {
- DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
- confi));
- err = usbd_set_config_index(dev, confi, 1);
- if (err) {
-#ifdef USB_DEBUG
- DPRINTF(("%s: port %d, set config at addr %d failed, "
- "error=%s\n", device_get_nameunit(parent), port,
- addr, usbd_errstr(err)));
-#else
- printf("%s: port %d, set config at addr %d failed\n",
- device_get_nameunit(parent), port, addr);
-#endif
- free(devinfo, M_USB);
- return (err);
- }
- nifaces = dev->cdesc->bNumInterface;
- uaa.configno = dev->cdesc->bConfigurationValue;
- for (i = 0; i < nifaces; i++)
- ifaces[i] = &dev->ifaces[i];
- uaa.ifaces = ifaces;
- uaa.nifaces = nifaces;
- dev->subdevs = malloc((nifaces+1) * sizeof(device_t), M_USB,M_NOWAIT);
- if (dev->subdevs == NULL) {
- free(devinfo, M_USB);
- return (USBD_NOMEM);
- }
- dev->ifacenums = malloc((nifaces) * sizeof(*dev->ifacenums),
- M_USB,M_NOWAIT);
- if (dev->ifacenums == NULL) {
- free(devinfo, M_USB);
- return (USBD_NOMEM);
- }
-
- found = 0;
- for (i = 0; i < nifaces; i++) {
- if (ifaces[i] == NULL)
- continue; /* interface already claimed */
- uaa.iface = ifaces[i];
- uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
- dev->subdevs[found] = bdev;
- dev->subdevs[found + 1] = 0;
- dev->ifacenums[found] = i;
- *uaap = uaa;
- usbd_devinfo(dev, 1, devinfo);
- device_set_desc_copy(bdev, devinfo);
- if (device_probe_and_attach(bdev) == 0) {
- ifaces[i] = NULL; /* consumed */
- found++;
- /* create another child for the next iface */
- bdev = device_add_child(parent, NULL, -1);
- if (!bdev) {
- device_printf(parent,
- "Device add failed\n");
- free(devinfo, M_USB);
- return (USBD_NORMAL_COMPLETION);
- }
- uaap = malloc(sizeof(uaa), M_USB, M_NOWAIT);
- if (uaap == NULL) {
- free(devinfo, M_USB);
- return (USBD_NOMEM);
- }
- device_set_ivars(bdev, uaap);
- } else {
- dev->subdevs[found] = 0;
- }
- }
- if (found != 0) {
- /* remove the last created child. It is unused */
- free(uaap, M_USB);
- free(devinfo, M_USB);
- device_delete_child(parent, bdev);
- /* free(uaap, M_USB); */ /* May be needed? xxx */
- return (USBD_NORMAL_COMPLETION);
- }
- tmpdv = dev->subdevs;
- dev->subdevs = NULL;
- free(tmpdv, M_USB);
- free(dev->ifacenums, M_USB);
- dev->ifacenums = NULL;
- }
- /* No interfaces were attached in any of the configurations. */
-
- if (dd->bNumConfigurations > 1) /* don't change if only 1 config */
- usbd_set_config_index(dev, 0, 0);
-
- DPRINTF(("usbd_probe_and_attach: no interface drivers found\n"));
-
- /* Finally try the generic driver. */
- uaa.iface = NULL;
- uaa.usegeneric = 1;
- uaa.configno = UHUB_UNK_CONFIGURATION;
- uaa.ifaceno = UHUB_UNK_INTERFACE;
- dev->subdevs = malloc(2 * sizeof(device_t), M_USB, M_NOWAIT);
- if (dev->subdevs == 0) {
- free(devinfo, M_USB);
- return (USBD_NOMEM);
- }
- dev->subdevs[0] = bdev;
- dev->subdevs[1] = 0;
- *uaap = uaa;
- usbd_devinfo(dev, 1, devinfo);
- device_set_desc_copy(bdev, devinfo);
- free(devinfo, M_USB);
- if (device_probe_and_attach(bdev) == 0)
- return (USBD_NORMAL_COMPLETION);
-
- /*
- * The generic attach failed, but leave the device as it is.
- * We just did not find any drivers, that's all. The device is
- * fully operational and not harming anyone.
- */
- DPRINTF(("usbd_probe_and_attach: generic attach failed\n"));
- return (USBD_NORMAL_COMPLETION);
-}
-
-
-/*
- * Called when a new device has been put in the powered state,
- * but not yet in the addressed state.
- * Get initial descriptor, set the address, get full descriptor,
- * and attach a driver.
- */
-usbd_status
-usbd_new_device(device_t parent, usbd_bus_handle bus, int depth,
- int speed, int port, struct usbd_port *up)
-{
- usbd_device_handle dev, adev;
- struct usbd_device *hub;
- usb_device_descriptor_t *dd;
- usb_port_status_t ps;
- usbd_status err;
- int addr;
- int i;
- int p;
-
- DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
- bus, port, depth, speed));
- addr = usbd_getnewaddr(bus);
- if (addr < 0) {
- device_printf(bus->bdev, "No free USB addresses\n");
- return (USBD_NO_ADDR);
- }
-
- dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO);
- if (dev == NULL)
- return (USBD_NOMEM);
-
- dev->bus = bus;
-
- /* Set up default endpoint handle. */
- dev->def_ep.edesc = &dev->def_ep_desc;
-
- /* Set up default endpoint descriptor. */
- dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
- dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
- dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
- dev->def_ep_desc.bmAttributes = UE_CONTROL;
- USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET);
- dev->def_ep_desc.bInterval = 0;
-
- dev->quirks = &usbd_no_quirk;
- dev->address = USB_START_ADDR;
- dev->ddesc.bMaxPacketSize = 0;
- dev->depth = depth;
- dev->powersrc = up;
- dev->myhub = up->parent;
-
- up->device = dev;
-
- if (up->parent && speed > up->parent->speed) {
-#ifdef USB_DEBUG
- printf("%s: maxium speed of attached "
- "device, %d, is higher than speed "
- "of parent HUB, %d.\n",
- __FUNCTION__, speed, up->parent->speed);
-#endif
- /*
- * Reduce the speed, otherwise we won't setup the
- * proper transfer methods.
- */
- speed = up->parent->speed;
- }
-
- /* Locate port on upstream high speed hub */
- for (adev = dev, hub = up->parent;
- hub != NULL && hub->speed != USB_SPEED_HIGH;
- adev = hub, hub = hub->myhub)
- ;
- if (hub) {
- for (p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) {
- if (hub->hub->ports[p].device == adev) {
- dev->myhsport = &hub->hub->ports[p];
- goto found;
- }
- }
- panic("usbd_new_device: cannot find HS port\n");
- found:
- DPRINTFN(1,("usbd_new_device: high speed port %d\n", p));
- } else {
- dev->myhsport = NULL;
- }
- dev->speed = speed;
- dev->langid = USBD_NOLANG;
- dev->cookie.cookie = ++usb_cookie_no;
-
- /* Establish the default pipe. */
- err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
- &dev->default_pipe);
- if (err) {
- usbd_remove_device(dev, up);
- return (err);
- }
-
- dd = &dev->ddesc;
- /* Try a few times in case the device is slow (i.e. outside specs.) */
- DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr));
- for (i = 0; i < 15; i++) {
- /* Get the first 8 bytes of the device descriptor. */
- err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
- if (!err)
- break;
- usbd_delay_ms(dev, 200);
- if ((i & 3) == 3) {
- DPRINTFN(-1,("usb_new_device: set address %d "
- "failed - trying a port reset\n", addr));
- usbd_reset_port(up->parent, port, &ps);
- }
-
- }
- if (err) {
- DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
- "failed\n", addr));
- usbd_remove_device(dev, up);
- return (err);
- }
-
- if (speed == USB_SPEED_HIGH) {
- /* Max packet size must be 64 (sec 5.5.3). */
- if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) {
-#ifdef DIAGNOSTIC
- printf("usbd_new_device: addr=%d bad max packet size\n",
- addr);
-#endif
- dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
- }
- }
-
- DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
- "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
- addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
- dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
- dev->speed));
-
- if (dd->bDescriptorType != UDESC_DEVICE) {
- /* Illegal device descriptor */
- DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n",
- dd->bDescriptorType));
- usbd_remove_device(dev, up);
- return (USBD_INVAL);
- }
-
- if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) {
- DPRINTFN(-1,("usbd_new_device: bad length %d\n", dd->bLength));
- usbd_remove_device(dev, up);
- return (USBD_INVAL);
- }
-
- USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
-
- /* Re-establish the default pipe with the new max packet size. */
- usbd_kill_pipe(dev->default_pipe);
- err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
- &dev->default_pipe);
- if (err) {
- usbd_remove_device(dev, up);
- return (err);
- }
-
- err = usbd_reload_device_desc(dev);
- if (err) {
- DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
- "failed\n", addr));
- usbd_remove_device(dev, up);
- return (err);
- }
-
- /* Set the address */
- DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr));
- err = usbd_set_address(dev, addr);
- if (err) {
- DPRINTFN(-1,("usb_new_device: set address %d failed\n", addr));
- err = USBD_SET_ADDR_FAILED;
- usbd_remove_device(dev, up);
- return (err);
- }
-
- /* Allow device time to set new address */
- usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
- dev->address = addr; /* New device address now */
- bus->devices[addr] = dev;
-
- /* Re-establish the default pipe with the new address. */
- usbd_kill_pipe(dev->default_pipe);
- err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
- &dev->default_pipe);
- if (err) {
- usbd_remove_device(dev, up);
- return (err);
- }
-
- /* Assume 100mA bus powered for now. Changed when configured. */
- dev->power = USB_MIN_POWER;
- dev->self_powered = 0;
-
- DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
- addr, dev, parent));
-
- err = usbd_probe_and_attach(parent, dev, port, addr);
- if (err) {
- usbd_remove_device(dev, up);
- return (err);
- }
-
- usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_reload_device_desc(usbd_device_handle dev)
-{
- usbd_status err;
- int i;
-
- /* Get the full device descriptor. */
- for (i = 0; i < 3; ++i) {
- err = usbd_get_device_desc(dev, &dev->ddesc);
- if (!err)
- break;
- usbd_delay_ms(dev, 200);
- }
- if (err)
- return (err);
-
- /* Figure out what's wrong with this device. */
- dev->quirks = usbd_find_quirk(&dev->ddesc);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-void
-usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
-{
- DPRINTF(("usbd_remove_device: %p\n", dev));
-
- if (dev->default_pipe != NULL)
- usbd_kill_pipe(dev->default_pipe);
- up->device = NULL;
- dev->bus->devices[dev->address] = NULL;
-
- free(dev, M_USB);
-}
-
-void
-usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
- int usedev)
-{
- struct usbd_port *p;
- int i, err, s;
-
- di->udi_bus = device_get_unit(dev->bus->bdev);
- di->udi_addr = dev->address;
- di->udi_cookie = dev->cookie;
- usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev);
- usbd_printBCD(di->udi_release, UGETW(dev->ddesc.bcdDevice));
- di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
- di->udi_productNo = UGETW(dev->ddesc.idProduct);
- di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
- di->udi_class = dev->ddesc.bDeviceClass;
- di->udi_subclass = dev->ddesc.bDeviceSubClass;
- di->udi_protocol = dev->ddesc.bDeviceProtocol;
- di->udi_config = dev->config;
- di->udi_power = dev->self_powered ? 0 : dev->power;
- di->udi_speed = dev->speed;
-
- if (dev->subdevs != NULL) {
- for (i = 0; dev->subdevs[i] && i < USB_MAX_DEVNAMES; i++) {
- if (device_is_attached(dev->subdevs[i]))
- strlcpy(di->udi_devnames[i],
- device_get_nameunit(dev->subdevs[i]),
- USB_MAX_DEVNAMELEN);
- else
- di->udi_devnames[i][0] = 0;
- }
- } else {
- i = 0;
- }
- for (/*i is set */; i < USB_MAX_DEVNAMES; i++)
- di->udi_devnames[i][0] = 0; /* empty */
-
- if (dev->hub) {
- for (i = 0;
- i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
- i < dev->hub->hubdesc.bNbrPorts;
- i++) {
- p = &dev->hub->ports[i];
- if (p->device)
- err = p->device->address;
- else {
- s = UGETW(p->status.wPortStatus);
- if (s & UPS_PORT_ENABLED)
- err = USB_PORT_ENABLED;
- else if (s & UPS_SUSPEND)
- err = USB_PORT_SUSPENDED;
- else if (s & UPS_PORT_POWER)
- err = USB_PORT_POWERED;
- else
- err = USB_PORT_DISABLED;
- }
- di->udi_ports[i] = err;
- }
- di->udi_nports = dev->hub->hubdesc.bNbrPorts;
- } else
- di->udi_nports = 0;
-}
-
-void
-usb_free_device(usbd_device_handle dev)
-{
- int ifcidx, nifc;
-
- if (dev->default_pipe != NULL)
- usbd_kill_pipe(dev->default_pipe);
- if (dev->ifaces != NULL) {
- nifc = dev->cdesc->bNumInterface;
- for (ifcidx = 0; ifcidx < nifc; ifcidx++)
- usbd_free_iface_data(dev, ifcidx);
- free(dev->ifaces, M_USB);
- }
- if (dev->cdesc != NULL)
- free(dev->cdesc, M_USB);
- if (dev->subdevs != NULL)
- free(dev->subdevs, M_USB);
- if (dev->ifacenums != NULL)
- free(dev->ifacenums, M_USB);
- free(dev, M_USB);
-}
-
-/*
- * The general mechanism for detaching drivers works as follows: Each
- * driver is responsible for maintaining a reference count on the
- * number of outstanding references to its softc (e.g. from
- * processing hanging in a read or write). The detach method of the
- * driver decrements this counter and flags in the softc that the
- * driver is dying and then wakes any sleepers. It then sleeps on the
- * softc. Each place that can sleep must maintain the reference
- * count. When the reference count drops to -1 (0 is the normal value
- * of the reference count) the a wakeup on the softc is performed
- * signaling to the detach waiter that all references are gone.
- */
-
-/*
- * Called from process context when we discover that a port has
- * been disconnected.
- */
-void
-usb_disconnect_port(struct usbd_port *up, device_t parent)
-{
- usbd_device_handle dev = up->device;
- const char *hubname = device_get_nameunit(parent);
- int i;
-
- DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
- up, dev, up->portno));
-
-#ifdef DIAGNOSTIC
- if (dev == NULL) {
- printf("usb_disconnect_port: no device\n");
- return;
- }
-#endif
-
- if (dev->subdevs != NULL) {
- DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n"));
- for (i = 0; dev->subdevs[i]; i++) {
- if (!device_is_quiet(dev->subdevs[i])) {
- device_printf(dev->subdevs[i],
- "at %s", hubname);
- if (up->portno != 0)
- printf(" port %d", up->portno);
- printf(" (addr %d) disconnected\n", dev->address);
- }
-
- struct usb_attach_arg *uaap =
- device_get_ivars(dev->subdevs[i]);
- device_detach(dev->subdevs[i]);
- free(uaap, M_USB);
- device_delete_child(device_get_parent(dev->subdevs[i]),
- dev->subdevs[i]);
- dev->subdevs[i] = NULL;
- }
- }
-
- usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
- dev->bus->devices[dev->address] = NULL;
- up->device = NULL;
- usb_free_device(dev);
-}
diff --git a/sys/legacy/dev/usb/usbcdc.h b/sys/legacy/dev/usb/usbcdc.h
deleted file mode 100644
index d684108..0000000
--- a/sys/legacy/dev/usb/usbcdc.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/* $NetBSD: usbcdc.h,v 1.9 2004/10/23 13:24:24 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _USBCDC_H_
-#define _USBCDC_H_
-
-#define UDESCSUB_CDC_HEADER 0
-#define UDESCSUB_CDC_CM 1 /* Call Management */
-#define UDESCSUB_CDC_ACM 2 /* Abstract Control Model */
-#define UDESCSUB_CDC_DLM 3 /* Direct Line Management */
-#define UDESCSUB_CDC_TRF 4 /* Telephone Ringer */
-#define UDESCSUB_CDC_TCLSR 5 /* Telephone Call ... */
-#define UDESCSUB_CDC_UNION 6
-#define UDESCSUB_CDC_CS 7 /* Country Selection */
-#define UDESCSUB_CDC_TOM 8 /* Telephone Operational Modes */
-#define UDESCSUB_CDC_USBT 9 /* USB Terminal */
-#define UDESCSUB_CDC_NCT 10
-#define UDESCSUB_CDC_PUF 11
-#define UDESCSUB_CDC_EUF 12
-#define UDESCSUB_CDC_MCMF 13
-#define UDESCSUB_CDC_CCMF 14
-#define UDESCSUB_CDC_ENF 15
-#define UDESCSUB_CDC_ANF 16
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uWord bcdCDC;
-} UPACKED usb_cdc_header_descriptor_t;
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bmCapabilities;
-#define USB_CDC_CM_DOES_CM 0x01
-#define USB_CDC_CM_OVER_DATA 0x02
- uByte bDataInterface;
-} UPACKED usb_cdc_cm_descriptor_t;
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bmCapabilities;
-#define USB_CDC_ACM_HAS_FEATURE 0x01
-#define USB_CDC_ACM_HAS_LINE 0x02
-#define USB_CDC_ACM_HAS_BREAK 0x04
-#define USB_CDC_ACM_HAS_NETWORK_CONN 0x08
-} UPACKED usb_cdc_acm_descriptor_t;
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bMasterInterface;
- uByte bSlaveInterface[1];
-} UPACKED usb_cdc_union_descriptor_t;
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte iMacAddress;
- uDWord bmEthernetStatistics;
- uWord wMaxSegmentSize;
- uWord wNumberMCFikters;
- uByte bNumberPowerFilters;
-} UPACKED usb_cdc_ethernet_descriptor_t;
-
-#define UCDC_SEND_ENCAPSULATED_COMMAND 0x00
-#define UCDC_GET_ENCAPSULATED_RESPONSE 0x01
-#define UCDC_SET_COMM_FEATURE 0x02
-#define UCDC_GET_COMM_FEATURE 0x03
-#define UCDC_ABSTRACT_STATE 0x01
-#define UCDC_COUNTRY_SETTING 0x02
-#define UCDC_CLEAR_COMM_FEATURE 0x04
-#define UCDC_SET_LINE_CODING 0x20
-#define UCDC_GET_LINE_CODING 0x21
-#define UCDC_SET_CONTROL_LINE_STATE 0x22
-#define UCDC_LINE_DTR 0x0001
-#define UCDC_LINE_RTS 0x0002
-#define UCDC_SEND_BREAK 0x23
-#define UCDC_BREAK_ON 0xffff
-#define UCDC_BREAK_OFF 0x0000
-
-typedef struct {
- uWord wState;
-#define UCDC_IDLE_SETTING 0x0001
-#define UCDC_DATA_MULTIPLEXED 0x0002
-} UPACKED usb_cdc_abstract_state_t;
-#define UCDC_ABSTRACT_STATE_LENGTH 2
-
-typedef struct {
- uDWord dwDTERate;
- uByte bCharFormat;
-#define UCDC_STOP_BIT_1 0
-#define UCDC_STOP_BIT_1_5 1
-#define UCDC_STOP_BIT_2 2
- uByte bParityType;
-#define UCDC_PARITY_NONE 0
-#define UCDC_PARITY_ODD 1
-#define UCDC_PARITY_EVEN 2
-#define UCDC_PARITY_MARK 3
-#define UCDC_PARITY_SPACE 4
- uByte bDataBits;
-} UPACKED usb_cdc_line_state_t;
-#define UCDC_LINE_STATE_LENGTH 7
-
-typedef struct {
- uByte bmRequestType;
-#define UCDC_NOTIFICATION 0xa1
- uByte bNotification;
-#define UCDC_N_NETWORK_CONNECTION 0x00
-#define UCDC_N_RESPONSE_AVAILABLE 0x01
-#define UCDC_N_AUX_JACK_HOOK_STATE 0x08
-#define UCDC_N_RING_DETECT 0x09
-#define UCDC_N_SERIAL_STATE 0x20
-#define UCDC_N_CALL_STATE_CHANGED 0x28
-#define UCDC_N_LINE_STATE_CHANGED 0x29
-#define UCDC_N_CONNECTION_SPEED_CHANGE 0x2a
- uWord wValue;
- uWord wIndex;
- uWord wLength;
- uByte data[16];
-} UPACKED usb_cdc_notification_t;
-#define UCDC_NOTIFICATION_LENGTH 8
-
-/*
- * Bits set in the SERIAL STATE notifcation (first byte of data)
- */
-
-#define UCDC_N_SERIAL_OVERRUN 0x40
-#define UCDC_N_SERIAL_PARITY 0x20
-#define UCDC_N_SERIAL_FRAMING 0x10
-#define UCDC_N_SERIAL_RI 0x08
-#define UCDC_N_SERIAL_BREAK 0x04
-#define UCDC_N_SERIAL_DSR 0x02
-#define UCDC_N_SERIAL_DCD 0x01
-
-/* Serial state bit masks */
-#define UCDC_MDM_RXCARRIER 0x01
-#define UCDC_MDM_TXCARRIER 0x02
-#define UCDC_MDM_BREAK 0x04
-#define UCDC_MDM_RING 0x08
-#define UCDC_MDM_FRAMING_ERR 0x10
-#define UCDC_MDM_PARITY_ERR 0x20
-#define UCDC_MDM_OVERRUN_ERR 0x40
-
-#endif /* _USBCDC_H_ */
diff --git a/sys/legacy/dev/usb/usbdi.c b/sys/legacy/dev/usb/usbdi.c
deleted file mode 100644
index a733bbf..0000000
--- a/sys/legacy/dev/usb/usbdi.c
+++ /dev/null
@@ -1,1383 +0,0 @@
-/* $NetBSD: usbdi.c,v 1.106 2004/10/24 12:52:40 augustss Exp $ */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include "usb_if.h"
-#if defined(DIAGNOSTIC) && defined(__i386__)
-#include <machine/cpu.h>
-#endif
-#include <sys/malloc.h>
-#include <sys/proc.h>
-
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_quirks.h>
-
-#include "usb_if.h"
-#define delay(d) DELAY(d)
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-extern int usbdebug;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-static usbd_status usbd_ar_pipe(usbd_pipe_handle pipe);
-static void usbd_do_request_async_cb
- (usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void usbd_start_next(usbd_pipe_handle pipe);
-static usbd_status usbd_open_pipe_ival
- (usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, int);
-static int usbd_xfer_isread(usbd_xfer_handle xfer);
-static void usbd_start_transfer(void *arg, bus_dma_segment_t *segs, int nseg,
- int error);
-static void usbd_alloc_callback(void *arg, bus_dma_segment_t *segs, int nseg,
- int error);
-
-static int usbd_nbuses = 0;
-
-void
-usbd_init(void)
-{
- usbd_nbuses++;
-}
-
-void
-usbd_finish(void)
-{
- --usbd_nbuses;
-}
-
-static __inline int
-usbd_xfer_isread(usbd_xfer_handle xfer)
-{
- if (xfer->rqflags & URQ_REQUEST)
- return (xfer->request.bmRequestType & UT_READ);
- else
- return (xfer->pipe->endpoint->edesc->bEndpointAddress &
- UE_DIR_IN);
-}
-
-#ifdef USB_DEBUG
-void
-usbd_dump_iface(struct usbd_interface *iface)
-{
- printf("usbd_dump_iface: iface=%p\n", iface);
- if (iface == NULL)
- return;
- printf(" device=%p idesc=%p index=%d altindex=%d priv=%p\n",
- iface->device, iface->idesc, iface->index, iface->altindex,
- iface->priv);
-}
-
-void
-usbd_dump_device(struct usbd_device *dev)
-{
- printf("usbd_dump_device: dev=%p\n", dev);
- if (dev == NULL)
- return;
- printf(" bus=%p default_pipe=%p\n", dev->bus, dev->default_pipe);
- printf(" address=%d config=%d depth=%d speed=%d self_powered=%d "
- "power=%d langid=%d\n",
- dev->address, dev->config, dev->depth, dev->speed,
- dev->self_powered, dev->power, dev->langid);
-}
-
-void
-usbd_dump_endpoint(struct usbd_endpoint *endp)
-{
- printf("usbd_dump_endpoint: endp=%p\n", endp);
- if (endp == NULL)
- return;
- printf(" edesc=%p refcnt=%d\n", endp->edesc, endp->refcnt);
- if (endp->edesc)
- printf(" bEndpointAddress=0x%02x\n",
- endp->edesc->bEndpointAddress);
-}
-
-void
-usbd_dump_queue(usbd_pipe_handle pipe)
-{
- usbd_xfer_handle xfer;
-
- printf("usbd_dump_queue: pipe=%p\n", pipe);
- STAILQ_FOREACH(xfer, &pipe->queue, next) {
- printf(" xfer=%p\n", xfer);
- }
-}
-
-void
-usbd_dump_pipe(usbd_pipe_handle pipe)
-{
- printf("usbd_dump_pipe: pipe=%p\n", pipe);
- if (pipe == NULL)
- return;
- usbd_dump_iface(pipe->iface);
- usbd_dump_device(pipe->device);
- usbd_dump_endpoint(pipe->endpoint);
- printf(" (usbd_dump_pipe:)\n refcnt=%d running=%d aborting=%d\n",
- pipe->refcnt, pipe->running, pipe->aborting);
- printf(" intrxfer=%p, repeat=%d, interval=%d\n",
- pipe->intrxfer, pipe->repeat, pipe->interval);
-}
-#endif
-
-usbd_status
-usbd_open_pipe(usbd_interface_handle iface, u_int8_t address,
- u_int8_t flags, usbd_pipe_handle *pipe)
-{
- return (usbd_open_pipe_ival(iface, address, flags, pipe,
- USBD_DEFAULT_INTERVAL));
-}
-
-usbd_status
-usbd_open_pipe_ival(usbd_interface_handle iface, u_int8_t address,
- u_int8_t flags, usbd_pipe_handle *pipe, int ival)
-{
- usbd_pipe_handle p;
- struct usbd_endpoint *ep;
- usbd_status err;
- int i;
-
- DPRINTFN(3,("usbd_open_pipe: iface=%p address=0x%x flags=0x%x\n",
- iface, address, flags));
-
- for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
- ep = &iface->endpoints[i];
- if (ep->edesc == NULL)
- return (USBD_IOERROR);
- if (ep->edesc->bEndpointAddress == address)
- goto found;
- }
- return (USBD_BAD_ADDRESS);
- found:
- if ((flags & USBD_EXCLUSIVE_USE) && ep->refcnt != 0)
- return (USBD_IN_USE);
- err = usbd_setup_pipe(iface->device, iface, ep, ival, &p);
- if (err)
- return (err);
- LIST_INSERT_HEAD(&iface->pipes, p, next);
- *pipe = p;
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address,
- u_int8_t flags, usbd_pipe_handle *pipe,
- usbd_private_handle priv, void *buffer, u_int32_t len,
- usbd_callback cb, int ival)
-{
- usbd_status err;
- usbd_xfer_handle xfer;
- usbd_pipe_handle ipipe;
-
- DPRINTFN(3,("usbd_open_pipe_intr: address=0x%x flags=0x%x len=%d\n",
- address, flags, len));
-
- err = usbd_open_pipe_ival(iface, address, USBD_EXCLUSIVE_USE,
- &ipipe, ival);
- if (err)
- return (err);
- xfer = usbd_alloc_xfer(iface->device);
- if (xfer == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags,
- USBD_NO_TIMEOUT, cb);
- ipipe->intrxfer = xfer;
- ipipe->repeat = 1;
- *pipe = ipipe;
- err = usbd_transfer(xfer);
- if (err != USBD_IN_PROGRESS && err)
- goto bad2;
- return (USBD_NORMAL_COMPLETION);
-
- bad2:
- ipipe->intrxfer = NULL;
- ipipe->repeat = 0;
- usbd_free_xfer(xfer);
- bad1:
- usbd_close_pipe(ipipe);
- return (err);
-}
-
-usbd_status
-usbd_close_pipe(usbd_pipe_handle pipe)
-{
-#ifdef DIAGNOSTIC
- if (pipe == NULL) {
- printf("usbd_close_pipe: pipe==NULL\n");
- return (USBD_NORMAL_COMPLETION);
- }
-#endif
-
- if (--pipe->refcnt != 0)
- return (USBD_NORMAL_COMPLETION);
- if (! STAILQ_EMPTY(&pipe->queue))
- return (USBD_PENDING_REQUESTS);
- LIST_REMOVE(pipe, next);
- pipe->endpoint->refcnt--;
- pipe->methods->close(pipe);
- if (pipe->intrxfer != NULL)
- usbd_free_xfer(pipe->intrxfer);
- free(pipe, M_USB);
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_transfer(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- usbd_status err;
- u_int size;
- int s;
-
- DPRINTFN(5,("%s: xfer=%p, flags=0x%b, rqflags=0x%b, "
- "length=%d, buffer=%p, allocbuf=%p, pipe=%p, running=%d\n",
- __func__, xfer, xfer->flags, USBD_BITS, xfer->rqflags, URQ_BITS,
- xfer->length, xfer->buffer, xfer->allocbuf, pipe, pipe->running));
-#ifdef USB_DEBUG
- if (usbdebug > 5)
- usbd_dump_queue(pipe);
-#endif
- xfer->done = 0;
-
- if (pipe->aborting)
- return (USBD_CANCELLED);
-
- size = xfer->length;
- /* If there is no buffer, allocate one. */
- if (!(xfer->rqflags & URQ_DEV_DMABUF) && size != 0) {
- bus_dma_tag_t tag = pipe->device->bus->buffer_dmatag;
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_AUTO_DMABUF)
- printf("usbd_transfer: has old buffer!\n");
-#endif
- err = bus_dmamap_create(tag, 0, &dmap->map);
- if (err)
- return (USBD_NOMEM);
-
- xfer->rqflags |= URQ_AUTO_DMABUF;
- err = bus_dmamap_load(tag, dmap->map, xfer->buffer, size,
- usbd_start_transfer, xfer, 0);
- if (err != 0 && err != EINPROGRESS) {
- xfer->rqflags &= ~URQ_AUTO_DMABUF;
- bus_dmamap_destroy(tag, dmap->map);
- return (USBD_INVAL);
- }
- } else if (size != 0) {
- usbd_start_transfer(xfer, dmap->segs, dmap->nsegs, 0);
- } else {
- usbd_start_transfer(xfer, NULL, 0, 0);
- }
-
- if (!(xfer->flags & USBD_SYNCHRONOUS))
- return (xfer->done ? USBD_NORMAL_COMPLETION : USBD_IN_PROGRESS);
-
- /* Sync transfer, wait for completion. */
- s = splusb();
- while (!xfer->done) {
- if (pipe->device->bus->use_polling)
- panic("usbd_transfer: not done");
- tsleep(xfer, PRIBIO, "usbsyn", 0);
- }
- splx(s);
- return (xfer->status);
-}
-
-static void
-usbd_start_transfer(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- usbd_xfer_handle xfer = arg;
- usbd_pipe_handle pipe = xfer->pipe;
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- bus_dma_tag_t tag = pipe->device->bus->buffer_dmatag;
- int err, i;
-
- if (error != 0) {
- KASSERT(xfer->rqflags & URQ_AUTO_DMABUF,
- ("usbd_start_transfer: error with non-auto buf"));
- if (nseg > 0)
- bus_dmamap_unload(tag, dmap->map);
- bus_dmamap_destroy(tag, dmap->map);
- /* XXX */
- usb_insert_transfer(xfer);
- xfer->status = USBD_IOERROR;
- usb_transfer_complete(xfer);
- return;
- }
-
- if (segs != dmap->segs) {
- for (i = 0; i < nseg; i++)
- dmap->segs[i] = segs[i];
- }
- dmap->nsegs = nseg;
-
- if (nseg > 0) {
- if (!usbd_xfer_isread(xfer)) {
- /*
- * Copy data if it is not already in the correct
- * buffer.
- */
- if (!(xfer->flags & USBD_NO_COPY) &&
- xfer->allocbuf != NULL &&
- xfer->buffer != xfer->allocbuf)
- memcpy(xfer->allocbuf, xfer->buffer,
- xfer->length);
- bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREWRITE);
- } else if (xfer->rqflags & URQ_REQUEST) {
- /*
- * Even if we have no data portion we still need to
- * sync the dmamap for the request data in the SETUP
- * packet.
- */
- bus_dmamap_sync(tag, dmap->map,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- } else
- bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREREAD);
- }
- err = pipe->methods->transfer(xfer);
- if (err != USBD_IN_PROGRESS && err) {
- if (xfer->rqflags & URQ_AUTO_DMABUF) {
- bus_dmamap_unload(tag, dmap->map);
- bus_dmamap_destroy(tag, dmap->map);
- xfer->rqflags &= ~URQ_AUTO_DMABUF;
- }
- xfer->status = err;
- usb_transfer_complete(xfer);
- return;
- }
-}
-
-/* Like usbd_transfer(), but waits for completion. */
-usbd_status
-usbd_sync_transfer(usbd_xfer_handle xfer)
-{
- xfer->flags |= USBD_SYNCHRONOUS;
- return (usbd_transfer(xfer));
-}
-
-struct usbd_allocstate {
- usbd_xfer_handle xfer;
- int done;
- int error;
- int waiting;
-};
-
-void *
-usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size)
-{
- struct usbd_allocstate allocstate;
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- bus_dma_tag_t tag = xfer->device->bus->buffer_dmatag;
- void *buf;
- usbd_status err;
- int error, s;
-
- KASSERT((xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) == 0,
- ("usbd_alloc_buffer: xfer already has a buffer"));
- err = bus_dmamap_create(tag, 0, &dmap->map);
- if (err)
- return (NULL);
- buf = malloc(size, M_USB, M_WAITOK);
-
- allocstate.xfer = xfer;
- allocstate.done = 0;
- allocstate.error = 0;
- allocstate.waiting = 0;
- error = bus_dmamap_load(tag, dmap->map, buf, size, usbd_alloc_callback,
- &allocstate, 0);
- if (error && error != EINPROGRESS) {
- bus_dmamap_destroy(tag, dmap->map);
- free(buf, M_USB);
- return (NULL);
- }
- if (error == EINPROGRESS) {
- /* Wait for completion. */
- s = splusb();
- allocstate.waiting = 1;
- while (!allocstate.done)
- tsleep(&allocstate, PRIBIO, "usbdab", 0);
- splx(s);
- error = allocstate.error;
- }
- if (error) {
- bus_dmamap_unload(tag, dmap->map);
- bus_dmamap_destroy(tag, dmap->map);
- free(buf, M_USB);
- return (NULL);
- }
-
- xfer->allocbuf = buf;
- xfer->rqflags |= URQ_DEV_DMABUF;
- return (buf);
-}
-
-void
-usbd_free_buffer(usbd_xfer_handle xfer)
-{
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- bus_dma_tag_t tag = xfer->device->bus->buffer_dmatag;
-
- KASSERT((xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) ==
- URQ_DEV_DMABUF, ("usbd_free_buffer: no/auto buffer"));
-
- xfer->rqflags &= ~URQ_DEV_DMABUF;
- bus_dmamap_unload(tag, dmap->map);
- bus_dmamap_destroy(tag, dmap->map);
- free(xfer->allocbuf, M_USB);
- xfer->allocbuf = NULL;
-}
-
-void *
-usbd_get_buffer(usbd_xfer_handle xfer)
-{
- if (!(xfer->rqflags & URQ_DEV_DMABUF))
- return (NULL);
- return (xfer->allocbuf);
-}
-
-static void
-usbd_alloc_callback(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- struct usbd_allocstate *allocstate = arg;
- usbd_xfer_handle xfer = allocstate->xfer;
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- int i;
-
- allocstate->error = error;
- if (error == 0) {
- for (i = 0; i < nseg; i++)
- dmap->segs[i] = segs[i];
- dmap->nsegs = nseg;
- }
- allocstate->done = 1;
- if (allocstate->waiting)
- wakeup(&allocstate);
-}
-
-usbd_xfer_handle
-usbd_alloc_xfer(usbd_device_handle dev)
-{
- usbd_xfer_handle xfer;
-
- xfer = dev->bus->methods->allocx(dev->bus);
- if (xfer == NULL)
- return (NULL);
- xfer->device = dev;
- callout_init(&xfer->timeout_handle, 0);
- DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer));
- return (xfer);
-}
-
-usbd_status
-usbd_free_xfer(usbd_xfer_handle xfer)
-{
- DPRINTFN(5,("usbd_free_xfer: %p\n", xfer));
- if (xfer->rqflags & URQ_DEV_DMABUF)
- usbd_free_buffer(xfer);
-/* XXX Does FreeBSD need to do something similar? */
-#if defined(__NetBSD__) && defined(DIAGNOSTIC)
- if (callout_pending(&xfer->timeout_handle)) {
- callout_stop(&xfer->timeout_handle);
- printf("usbd_free_xfer: timout_handle pending");
- }
-#endif
- xfer->device->bus->methods->freex(xfer->device->bus, xfer);
- return (USBD_NORMAL_COMPLETION);
-}
-
-void
-usbd_setup_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
- usbd_private_handle priv, void *buffer, u_int32_t length,
- u_int16_t flags, u_int32_t timeout,
- usbd_callback callback)
-{
- xfer->pipe = pipe;
- xfer->priv = priv;
- xfer->buffer = buffer;
- xfer->length = length;
- xfer->actlen = 0;
- xfer->flags = flags;
- xfer->timeout = timeout;
- xfer->status = USBD_NOT_STARTED;
- xfer->callback = callback;
- xfer->rqflags &= ~URQ_REQUEST;
- xfer->nframes = 0;
-}
-
-void
-usbd_setup_default_xfer(usbd_xfer_handle xfer, usbd_device_handle dev,
- usbd_private_handle priv, u_int32_t timeout,
- usb_device_request_t *req, void *buffer,
- u_int32_t length, u_int16_t flags,
- usbd_callback callback)
-{
- xfer->pipe = dev->default_pipe;
- xfer->priv = priv;
- xfer->buffer = buffer;
- xfer->length = length;
- xfer->actlen = 0;
- xfer->flags = flags;
- xfer->timeout = timeout;
- xfer->status = USBD_NOT_STARTED;
- xfer->callback = callback;
- xfer->request = *req;
- xfer->rqflags |= URQ_REQUEST;
- xfer->nframes = 0;
-}
-
-void
-usbd_setup_isoc_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
- usbd_private_handle priv, u_int16_t *frlengths,
- u_int32_t nframes, u_int16_t flags, usbd_callback callback)
-{
- int i;
-
- xfer->pipe = pipe;
- xfer->priv = priv;
- xfer->buffer = 0;
- xfer->length = 0;
- for (i = 0; i < nframes; i++)
- xfer->length += frlengths[i];
- xfer->actlen = 0;
- xfer->flags = flags;
- xfer->timeout = USBD_NO_TIMEOUT;
- xfer->status = USBD_NOT_STARTED;
- xfer->callback = callback;
- xfer->rqflags &= ~URQ_REQUEST;
- xfer->frlengths = frlengths;
- xfer->nframes = nframes;
-}
-
-void
-usbd_get_xfer_status(usbd_xfer_handle xfer, usbd_private_handle *priv,
- void **buffer, u_int32_t *count, usbd_status *status)
-{
- if (priv != NULL)
- *priv = xfer->priv;
- if (buffer != NULL)
- *buffer = xfer->buffer;
- if (count != NULL)
- *count = xfer->actlen;
- if (status != NULL)
- *status = xfer->status;
-}
-
-usb_config_descriptor_t *
-usbd_get_config_descriptor(usbd_device_handle dev)
-{
-#ifdef DIAGNOSTIC
- if (dev == NULL) {
- printf("usbd_get_config_descriptor: dev == NULL\n");
- return (NULL);
- }
-#endif
- return (dev->cdesc);
-}
-
-int
-usbd_get_speed(usbd_device_handle dev)
-{
- return (dev->speed);
-}
-
-usb_interface_descriptor_t *
-usbd_get_interface_descriptor(usbd_interface_handle iface)
-{
-#ifdef DIAGNOSTIC
- if (iface == NULL) {
- printf("usbd_get_interface_descriptor: dev == NULL\n");
- return (NULL);
- }
-#endif
- return (iface->idesc);
-}
-
-usb_device_descriptor_t *
-usbd_get_device_descriptor(usbd_device_handle dev)
-{
- return (&dev->ddesc);
-}
-
-usb_endpoint_descriptor_t *
-usbd_interface2endpoint_descriptor(usbd_interface_handle iface, u_int8_t index)
-{
- if (index >= iface->idesc->bNumEndpoints)
- return (0);
- return (iface->endpoints[index].edesc);
-}
-
-usbd_status
-usbd_abort_pipe(usbd_pipe_handle pipe)
-{
- usbd_status err;
- int s;
-
-#ifdef DIAGNOSTIC
- if (pipe == NULL) {
- printf("usbd_close_pipe: pipe==NULL\n");
- return (USBD_NORMAL_COMPLETION);
- }
-#endif
- s = splusb();
- err = usbd_ar_pipe(pipe);
- splx(s);
- return (err);
-}
-
-usbd_status
-usbd_abort_default_pipe(usbd_device_handle dev)
-{
- return (usbd_abort_pipe(dev->default_pipe));
-}
-
-usbd_status
-usbd_clear_endpoint_stall(usbd_pipe_handle pipe)
-{
- usbd_device_handle dev = pipe->device;
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));
-
- /*
- * Clearing en endpoint stall resets the endpoint toggle, so
- * do the same to the HC toggle.
- */
- pipe->methods->cleartoggle(pipe);
-
- req.bmRequestType = UT_WRITE_ENDPOINT;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, UF_ENDPOINT_HALT);
- USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
- USETW(req.wLength, 0);
- err = usbd_do_request(dev, &req, 0);
-#if 0
-XXX should we do this?
- if (!err) {
- pipe->state = USBD_PIPE_ACTIVE;
- /* XXX activate pipe */
- }
-#endif
- return (err);
-}
-
-usbd_status
-usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe)
-{
- usbd_device_handle dev = pipe->device;
- usb_device_request_t req;
- usbd_status err;
-
- pipe->methods->cleartoggle(pipe);
-
- req.bmRequestType = UT_WRITE_ENDPOINT;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, UF_ENDPOINT_HALT);
- USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
- USETW(req.wLength, 0);
- err = usbd_do_request_async(dev, &req, 0);
- return (err);
-}
-
-void
-usbd_clear_endpoint_toggle(usbd_pipe_handle pipe)
-{
- pipe->methods->cleartoggle(pipe);
-}
-
-usbd_status
-usbd_endpoint_count(usbd_interface_handle iface, u_int8_t *count)
-{
-#ifdef DIAGNOSTIC
- if (iface == NULL || iface->idesc == NULL) {
- printf("usbd_endpoint_count: NULL pointer\n");
- return (USBD_INVAL);
- }
-#endif
- *count = iface->idesc->bNumEndpoints;
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_interface_count(usbd_device_handle dev, u_int8_t *count)
-{
- if (dev->cdesc == NULL)
- return (USBD_NOT_CONFIGURED);
- *count = dev->cdesc->bNumInterface;
- return (USBD_NORMAL_COMPLETION);
-}
-
-void
-usbd_interface2device_handle(usbd_interface_handle iface,
- usbd_device_handle *dev)
-{
- *dev = iface->device;
-}
-
-usbd_status
-usbd_device2interface_handle(usbd_device_handle dev,
- u_int8_t ifaceno, usbd_interface_handle *iface)
-{
- if (dev->cdesc == NULL)
- return (USBD_NOT_CONFIGURED);
- if (ifaceno >= dev->cdesc->bNumInterface)
- return (USBD_INVAL);
- *iface = &dev->ifaces[ifaceno];
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_device_handle
-usbd_pipe2device_handle(usbd_pipe_handle pipe)
-{
- return (pipe->device);
-}
-
-/* XXXX use altno */
-usbd_status
-usbd_set_interface(usbd_interface_handle iface, int altidx)
-{
- usb_device_request_t req;
- usbd_status err;
- void *endpoints;
-
- if (LIST_FIRST(&iface->pipes) != 0)
- return (USBD_IN_USE);
-
- endpoints = iface->endpoints;
- err = usbd_fill_iface_data(iface->device, iface->index, altidx);
- if (err)
- return (err);
-
- /* new setting works, we can free old endpoints */
- if (endpoints != NULL)
- free(endpoints, M_USB);
-
-#ifdef DIAGNOSTIC
- if (iface->idesc == NULL) {
- printf("usbd_set_interface: NULL pointer\n");
- return (USBD_INVAL);
- }
-#endif
-
- req.bmRequestType = UT_WRITE_INTERFACE;
- req.bRequest = UR_SET_INTERFACE;
- USETW(req.wValue, iface->idesc->bAlternateSetting);
- USETW(req.wIndex, iface->idesc->bInterfaceNumber);
- USETW(req.wLength, 0);
- return (usbd_do_request(iface->device, &req, 0));
-}
-
-int
-usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno)
-{
- char *p = (char *)cdesc;
- char *end = p + UGETW(cdesc->wTotalLength);
- usb_interface_descriptor_t *d;
- int n;
-
- for (n = 0; p < end; p += d->bLength) {
- d = (usb_interface_descriptor_t *)p;
- if (p + d->bLength <= end &&
- d->bDescriptorType == UDESC_INTERFACE &&
- d->bInterfaceNumber == ifaceno)
- n++;
- }
- return (n);
-}
-
-int
-usbd_get_interface_altindex(usbd_interface_handle iface)
-{
- return (iface->altindex);
-}
-
-usbd_status
-usbd_get_interface(usbd_interface_handle iface, u_int8_t *aiface)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_INTERFACE;
- req.bRequest = UR_GET_INTERFACE;
- USETW(req.wValue, 0);
- USETW(req.wIndex, iface->idesc->bInterfaceNumber);
- USETW(req.wLength, 1);
- return (usbd_do_request(iface->device, &req, aiface));
-}
-
-/*** Internal routines ***/
-
-/* Dequeue all pipe operations, called at splusb(). */
-static usbd_status
-usbd_ar_pipe(usbd_pipe_handle pipe)
-{
- usbd_xfer_handle xfer;
-
- SPLUSBCHECK;
-
- DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe));
-#ifdef USB_DEBUG
- if (usbdebug > 5)
- usbd_dump_queue(pipe);
-#endif
- pipe->repeat = 0;
- pipe->aborting = 1;
- while ((xfer = STAILQ_FIRST(&pipe->queue)) != NULL) {
- DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n",
- pipe, xfer, pipe->methods));
- /* Make the HC abort it (and invoke the callback). */
- pipe->methods->abort(xfer);
- KASSERT(STAILQ_FIRST(&pipe->queue) != xfer, ("usbd_ar_pipe"));
- /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
- }
- pipe->aborting = 0;
- return (USBD_NORMAL_COMPLETION);
-}
-
-/* Called at splusb() */
-void
-usb_transfer_complete(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- bus_dma_tag_t tag = pipe->device->bus->buffer_dmatag;
- int sync = xfer->flags & USBD_SYNCHRONOUS;
- int erred = xfer->status == USBD_CANCELLED ||
- xfer->status == USBD_TIMEOUT;
- int repeat = pipe->repeat;
- int polling;
-
- SPLUSBCHECK;
-
- DPRINTFN(5, ("%s: pipe=%p xfer=%p status=%d actlen=%d\n",
- __func__, pipe, xfer, xfer->status, xfer->actlen));
- DPRINTFN(5,("%s: flags=0x%b, rqflags=0x%b, length=%d, buffer=%p\n",
- __func__, xfer->flags, USBD_BITS, xfer->rqflags, URQ_BITS,
- xfer->length, xfer->buffer));
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_ONQU) {
- printf("usb_transfer_complete: xfer=%p not busy 0x%08x\n",
- xfer, xfer->busy_free);
- return;
- }
-#endif
-
-#ifdef DIAGNOSTIC
- if (pipe == NULL) {
- printf("usbd_transfer_cb: pipe==0, xfer=%p\n", xfer);
- return;
- }
-#endif
- polling = pipe->device->bus->use_polling;
- /* XXXX */
- if (polling)
- pipe->running = 0;
-
- if (xfer->actlen != 0 && usbd_xfer_isread(xfer)) {
- bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_POSTREAD);
- /* Copy data if it is not already in the correct buffer. */
- if (!(xfer->flags & USBD_NO_COPY) && xfer->allocbuf != NULL &&
- xfer->buffer != xfer->allocbuf)
- memcpy(xfer->buffer, xfer->allocbuf, xfer->actlen);
- }
-
- /* if we mapped the buffer in usbd_transfer() we unmap it here. */
- if (xfer->rqflags & URQ_AUTO_DMABUF) {
- if (!repeat) {
- bus_dmamap_unload(tag, dmap->map);
- bus_dmamap_destroy(tag, dmap->map);
- xfer->rqflags &= ~URQ_AUTO_DMABUF;
- }
- }
-
- if (!repeat) {
- /* Remove request from queue. */
-#ifdef DIAGNOSTIC
- xfer->busy_free = XFER_BUSY;
-#endif
- KASSERT(STAILQ_FIRST(&pipe->queue) == xfer,
- ("usb_transfer_complete: bad dequeue"));
- STAILQ_REMOVE_HEAD(&pipe->queue, next);
- }
- DPRINTFN(5,("usb_transfer_complete: repeat=%d new head=%p\n",
- repeat, STAILQ_FIRST(&pipe->queue)));
-
- /* Count completed transfers. */
- ++pipe->device->bus->stats.uds_requests
- [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE];
-
- xfer->done = 1;
- if (!xfer->status && xfer->actlen < xfer->length &&
- !(xfer->flags & USBD_SHORT_XFER_OK)) {
- DPRINTFN(-1,("usbd_transfer_cb: short transfer %d<%d\n",
- xfer->actlen, xfer->length));
- xfer->status = USBD_SHORT_XFER;
- }
-
- /*
- * For repeat operations, call the callback first, as the xfer
- * will not go away and the "done" method may modify it. Otherwise
- * reverse the order in case the callback wants to free or reuse
- * the xfer.
- */
- if (repeat) {
- if (xfer->callback)
- xfer->callback(xfer, xfer->priv, xfer->status);
- pipe->methods->done(xfer);
- } else {
- pipe->methods->done(xfer);
- if (xfer->callback)
- xfer->callback(xfer, xfer->priv, xfer->status);
- }
-
- if (sync && !polling)
- wakeup(xfer);
-
- if (!repeat) {
- /* XXX should we stop the queue on all errors? */
- if (erred && pipe->iface != NULL) /* not control pipe */
- pipe->running = 0;
- else
- usbd_start_next(pipe);
- }
-}
-
-usbd_status
-usb_insert_transfer(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- usbd_status err;
- int s;
-
- DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
- pipe, pipe->running, xfer->timeout));
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_BUSY) {
- printf("usb_insert_transfer: xfer=%p not busy 0x%08x\n",
- xfer, xfer->busy_free);
- return (USBD_INVAL);
- }
- xfer->busy_free = XFER_ONQU;
-#endif
- s = splusb();
- KASSERT(STAILQ_FIRST(&pipe->queue) != xfer, ("usb_insert_transfer"));
- STAILQ_INSERT_TAIL(&pipe->queue, xfer, next);
- if (pipe->running)
- err = USBD_IN_PROGRESS;
- else {
- pipe->running = 1;
- err = USBD_NORMAL_COMPLETION;
- }
- splx(s);
- return (err);
-}
-
-/* Called at splusb() */
-void
-usbd_start_next(usbd_pipe_handle pipe)
-{
- usbd_xfer_handle xfer;
- usbd_status err;
-
- SPLUSBCHECK;
-
-#ifdef DIAGNOSTIC
- if (pipe == NULL) {
- printf("usbd_start_next: pipe == NULL\n");
- return;
- }
- if (pipe->methods == NULL || pipe->methods->start == NULL) {
- printf("usbd_start_next: pipe=%p no start method\n", pipe);
- return;
- }
-#endif
-
- /* Get next request in queue. */
- xfer = STAILQ_FIRST(&pipe->queue);
- DPRINTFN(5, ("usbd_start_next: pipe=%p, xfer=%p\n", pipe, xfer));
- if (xfer == NULL) {
- pipe->running = 0;
- } else {
- err = pipe->methods->start(xfer);
- if (err != USBD_IN_PROGRESS) {
- printf("usbd_start_next: error=%d\n", err);
- pipe->running = 0;
- /* XXX do what? */
- }
- }
-}
-
-usbd_status
-usbd_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data)
-{
- return (usbd_do_request_flags(dev, req, data, 0, 0,
- USBD_DEFAULT_TIMEOUT));
-}
-
-usbd_status
-usbd_do_request_flags(usbd_device_handle dev, usb_device_request_t *req,
- void *data, u_int16_t flags, int *actlen, u_int32_t timo)
-{
- return (usbd_do_request_flags_pipe(dev, dev->default_pipe, req,
- data, flags, actlen, timo));
-}
-
-usbd_status
-usbd_do_request_flags_pipe(usbd_device_handle dev, usbd_pipe_handle pipe,
- usb_device_request_t *req, void *data, u_int16_t flags, int *actlen,
- u_int32_t timeout)
-{
- usbd_xfer_handle xfer;
- usbd_status err;
-
-#ifdef DIAGNOSTIC
-/* XXX amd64 too? */
-#if defined(__i386__)
- KASSERT(curthread->td_intr_nesting_level == 0,
- ("usbd_do_request: in interrupt context"));
-#endif
- if (dev->bus->intr_context) {
- printf("usbd_do_request: not in process context\n");
- return (USBD_INVAL);
- }
-#endif
-
- xfer = usbd_alloc_xfer(dev);
- if (xfer == NULL)
- return (USBD_NOMEM);
- usbd_setup_default_xfer(xfer, dev, 0, timeout, req,
- data, UGETW(req->wLength), flags, 0);
- xfer->pipe = pipe;
- err = usbd_sync_transfer(xfer);
-#if defined(USB_DEBUG) || defined(DIAGNOSTIC)
- if (xfer->actlen > xfer->length)
- DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
- "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
- dev->address, xfer->request.bmRequestType,
- xfer->request.bRequest, UGETW(xfer->request.wValue),
- UGETW(xfer->request.wIndex),
- UGETW(xfer->request.wLength),
- xfer->length, xfer->actlen));
-#endif
- if (actlen != NULL)
- *actlen = xfer->actlen;
- if (err == USBD_STALLED) {
- /*
- * The control endpoint has stalled. Control endpoints
- * should not halt, but some may do so anyway so clear
- * any halt condition.
- */
- usb_device_request_t treq;
- usb_status_t status;
- u_int16_t s;
- usbd_status nerr;
-
- treq.bmRequestType = UT_READ_ENDPOINT;
- treq.bRequest = UR_GET_STATUS;
- USETW(treq.wValue, 0);
- USETW(treq.wIndex, 0);
- USETW(treq.wLength, sizeof(usb_status_t));
- usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
- &treq, &status,sizeof(usb_status_t),
- 0, 0);
- nerr = usbd_sync_transfer(xfer);
- if (nerr)
- goto bad;
- s = UGETW(status.wStatus);
- DPRINTF(("usbd_do_request: status = 0x%04x\n", s));
- if (!(s & UES_HALT))
- goto bad;
- treq.bmRequestType = UT_WRITE_ENDPOINT;
- treq.bRequest = UR_CLEAR_FEATURE;
- USETW(treq.wValue, UF_ENDPOINT_HALT);
- USETW(treq.wIndex, 0);
- USETW(treq.wLength, 0);
- usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
- &treq, &status, 0, 0, 0);
- nerr = usbd_sync_transfer(xfer);
- if (nerr)
- goto bad;
- }
-
- bad:
- usbd_free_xfer(xfer);
- return (err);
-}
-
-void
-usbd_do_request_async_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
-#if defined(USB_DEBUG) || defined(DIAGNOSTIC)
- if (xfer->actlen > xfer->length)
- DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
- "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
- xfer->pipe->device->address,
- xfer->request.bmRequestType,
- xfer->request.bRequest, UGETW(xfer->request.wValue),
- UGETW(xfer->request.wIndex),
- UGETW(xfer->request.wLength),
- xfer->length, xfer->actlen));
-#endif
- usbd_free_xfer(xfer);
-}
-
-/*
- * Execute a request without waiting for completion.
- * Can be used from interrupt context.
- */
-usbd_status
-usbd_do_request_async(usbd_device_handle dev, usb_device_request_t *req,
- void *data)
-{
- usbd_xfer_handle xfer;
- usbd_status err;
-
- xfer = usbd_alloc_xfer(dev);
- if (xfer == NULL)
- return (USBD_NOMEM);
- usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
- data, UGETW(req->wLength), 0, usbd_do_request_async_cb);
- err = usbd_transfer(xfer);
- if (err != USBD_IN_PROGRESS && err) {
- usbd_free_xfer(xfer);
- return (err);
- }
- return (USBD_NORMAL_COMPLETION);
-}
-
-const struct usbd_quirks *
-usbd_get_quirks(usbd_device_handle dev)
-{
-#ifdef DIAGNOSTIC
- if (dev == NULL) {
- printf("usbd_get_quirks: dev == NULL\n");
- return 0;
- }
-#endif
- return (dev->quirks);
-}
-
-/* XXX do periodic free() of free list */
-
-/*
- * Called from keyboard driver when in polling mode.
- */
-void
-usbd_dopoll(usbd_interface_handle iface)
-{
- iface->device->bus->methods->do_poll(iface->device->bus);
-}
-
-void
-usbd_set_polling(usbd_device_handle dev, int on)
-{
- if (on)
- dev->bus->use_polling++;
- else
- dev->bus->use_polling--;
- /* When polling we need to make sure there is nothing pending to do. */
- if (dev->bus->use_polling)
- dev->bus->methods->soft_intr(dev->bus);
-}
-
-usbd_status
-usbd_reset_device(usbd_device_handle dev)
-{
- usbd_device_handle parent = dev->myhub;
- struct usbd_port *up = dev->powersrc;
-
- return usbd_reset_port(parent, up->portno, &up->status);
-}
-
-
-usb_endpoint_descriptor_t *
-usbd_get_endpoint_descriptor(usbd_interface_handle iface, u_int8_t address)
-{
- struct usbd_endpoint *ep;
- int i;
-
- for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
- ep = &iface->endpoints[i];
- if (ep->edesc->bEndpointAddress == address)
- return (iface->endpoints[i].edesc);
- }
- return (0);
-}
-
-/*
- * usbd_ratecheck() can limit the number of error messages that occurs.
- * When a device is unplugged it may take up to 0.25s for the hub driver
- * to notice it. If the driver continuosly tries to do I/O operations
- * this can generate a large number of messages.
- */
-int
-usbd_ratecheck(struct timeval *last)
-{
- if (last->tv_sec == time_second)
- return (0);
- last->tv_sec = time_second;
- return (1);
-}
-
-/*
- * Search for a vendor/product pair in an array. The item size is
- * given as an argument.
- */
-const struct usb_devno *
-usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz,
- u_int16_t vendor, u_int16_t product)
-{
- while (nentries-- > 0) {
- u_int16_t tproduct = tbl->ud_product;
- if (tbl->ud_vendor == vendor &&
- (tproduct == product || tproduct == USB_PRODUCT_ANY))
- return (tbl);
- tbl = (const struct usb_devno *)((const char *)tbl + sz);
- }
- return (NULL);
-}
-
-
-void
-usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter)
-{
- const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
-
- iter->cur = (const uByte *)cd;
- iter->end = (const uByte *)cd + UGETW(cd->wTotalLength);
-}
-
-const usb_descriptor_t *
-usb_desc_iter_next(usbd_desc_iter_t *iter)
-{
- const usb_descriptor_t *desc;
-
- if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) {
- if (iter->cur != iter->end)
- printf("usb_desc_iter_next: bad descriptor\n");
- return NULL;
- }
- desc = (const usb_descriptor_t *)iter->cur;
- if (desc->bLength == 0) {
- printf("usb_desc_iter_next: descriptor length = 0\n");
- return NULL;
- }
- iter->cur += desc->bLength;
- if (iter->cur > iter->end) {
- printf("usb_desc_iter_next: descriptor length too large\n");
- return NULL;
- }
- return desc;
-}
-
-usbd_status
-usbd_get_string(usbd_device_handle dev, int si, char *buf, size_t len)
-{
- int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
- usb_string_descriptor_t us;
- char *s;
- int i, n;
- u_int16_t c;
- usbd_status err;
- int size;
-
- buf[0] = '\0';
- if (len == 0)
- return (USBD_NORMAL_COMPLETION);
- if (si == 0)
- return (USBD_INVAL);
- if (dev->quirks->uq_flags & UQ_NO_STRINGS)
- return (USBD_STALLED);
- if (dev->langid == USBD_NOLANG) {
- /* Set up default language */
- err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us,
- &size);
- if (err || size < 4) {
- DPRINTFN(-1,("usbd_get_string: getting lang failed, using 0\n"));
- dev->langid = 0; /* Well, just pick something then */
- } else {
- /* Pick the first language as the default. */
- dev->langid = UGETW(us.bString[0]);
- }
- }
- err = usbd_get_string_desc(dev, si, dev->langid, &us, &size);
- if (err)
- return (err);
- s = buf;
- n = size / 2 - 1;
- for (i = 0; i < n && i < len - 1; i++) {
- c = UGETW(us.bString[i]);
- /* Convert from Unicode, handle buggy strings. */
- if ((c & 0xff00) == 0)
- *s++ = c;
- else if ((c & 0x00ff) == 0 && swap)
- *s++ = c >> 8;
- else
- *s++ = '?';
- }
- *s++ = 0;
- return (USBD_NORMAL_COMPLETION);
-}
-
-int
-usbd_driver_load(module_t mod, int what, void *arg)
-{
- /* XXX should implement something like a function that removes all generic devices */
-
- return (0);
-}
diff --git a/sys/legacy/dev/usb/usbdi.h b/sys/legacy/dev/usb/usbdi.h
deleted file mode 100644
index ef59039..0000000
--- a/sys/legacy/dev/usb/usbdi.h
+++ /dev/null
@@ -1,289 +0,0 @@
-/* $NetBSD: usbdi.h,v 1.64 2004/10/23 13:26:34 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _USBDI_H_
-#define _USBDI_H_
-
-typedef struct usbd_bus *usbd_bus_handle;
-typedef struct usbd_device *usbd_device_handle;
-typedef struct usbd_interface *usbd_interface_handle;
-typedef struct usbd_pipe *usbd_pipe_handle;
-typedef struct usbd_xfer *usbd_xfer_handle;
-typedef void *usbd_private_handle;
-
-typedef enum { /* keep in sync with usbd_status_msgs */
- USBD_NORMAL_COMPLETION = 0, /* must be 0 */
- USBD_IN_PROGRESS, /* 1 */
- /* errors */
- USBD_PENDING_REQUESTS, /* 2 */
- USBD_NOT_STARTED, /* 3 */
- USBD_INVAL, /* 4 */
- USBD_NOMEM, /* 5 */
- USBD_CANCELLED, /* 6 */
- USBD_BAD_ADDRESS, /* 7 */
- USBD_IN_USE, /* 8 */
- USBD_NO_ADDR, /* 9 */
- USBD_SET_ADDR_FAILED, /* 10 */
- USBD_NO_POWER, /* 11 */
- USBD_TOO_DEEP, /* 12 */
- USBD_IOERROR, /* 13 */
- USBD_NOT_CONFIGURED, /* 14 */
- USBD_TIMEOUT, /* 15 */
- USBD_SHORT_XFER, /* 16 */
- USBD_STALLED, /* 17 */
- USBD_INTERRUPTED, /* 18 */
-
- USBD_ERROR_MAX /* must be last */
-} usbd_status;
-
-typedef void (*usbd_callback)(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-
-/* Open flags */
-#define USBD_EXCLUSIVE_USE 0x01
-
-/* Use default (specified by ep. desc.) interval on interrupt pipe */
-#define USBD_DEFAULT_INTERVAL (-1)
-
-/* Request flags */
-#define USBD_NO_COPY 0x01 /* do not copy data to DMA buffer */
-#define USBD_SYNCHRONOUS 0x02 /* wait for completion */
-/* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */
-#define USBD_FORCE_SHORT_XFER 0x08 /* force last short packet on write */
-
-#define USBD_BITS "\20\1NO_COPY\2SYNCHRONOUS\4FORCE_SHORT_XFER"
-
-#define USBD_NO_TIMEOUT 0
-#define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */
-
-usbd_status usbd_open_pipe(usbd_interface_handle, u_int8_t,
- u_int8_t, usbd_pipe_handle *);
-usbd_status usbd_close_pipe(usbd_pipe_handle);
-usbd_status usbd_transfer(usbd_xfer_handle);
-usbd_xfer_handle usbd_alloc_xfer(usbd_device_handle);
-usbd_status usbd_free_xfer(usbd_xfer_handle);
-void usbd_setup_xfer(usbd_xfer_handle, usbd_pipe_handle,
- usbd_private_handle, void *,
- u_int32_t, u_int16_t, u_int32_t,
- usbd_callback);
-void usbd_setup_default_xfer(usbd_xfer_handle, usbd_device_handle,
- usbd_private_handle, u_int32_t,
- usb_device_request_t *, void *,
- u_int32_t, u_int16_t, usbd_callback);
-void usbd_setup_isoc_xfer(usbd_xfer_handle, usbd_pipe_handle,
- usbd_private_handle, u_int16_t *,
- u_int32_t, u_int16_t, usbd_callback);
-void usbd_get_xfer_status(usbd_xfer_handle, usbd_private_handle *,
- void **, u_int32_t *, usbd_status *);
-usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor
- (usbd_interface_handle, u_int8_t);
-usbd_status usbd_abort_pipe(usbd_pipe_handle);
-usbd_status usbd_abort_default_pipe(usbd_device_handle);
-usbd_status usbd_clear_endpoint_stall(usbd_pipe_handle);
-usbd_status usbd_clear_endpoint_stall_async(usbd_pipe_handle);
-void usbd_clear_endpoint_toggle(usbd_pipe_handle);
-usbd_status usbd_endpoint_count(usbd_interface_handle, u_int8_t *);
-usbd_status usbd_interface_count(usbd_device_handle, u_int8_t *);
-void usbd_interface2device_handle(usbd_interface_handle,
- usbd_device_handle *);
-usbd_status usbd_device2interface_handle(usbd_device_handle,
- u_int8_t, usbd_interface_handle *);
-
-usbd_device_handle usbd_pipe2device_handle(usbd_pipe_handle);
-void *usbd_alloc_buffer(usbd_xfer_handle, u_int32_t);
-void usbd_free_buffer(usbd_xfer_handle);
-void *usbd_get_buffer(usbd_xfer_handle);
-usbd_status usbd_sync_transfer(usbd_xfer_handle);
-usbd_status usbd_open_pipe_intr(usbd_interface_handle, u_int8_t,
- u_int8_t, usbd_pipe_handle *,
- usbd_private_handle, void *,
- u_int32_t, usbd_callback, int);
-usbd_status usbd_do_request(usbd_device_handle, usb_device_request_t *, void *);
-usbd_status usbd_do_request_async(usbd_device_handle,
- usb_device_request_t *, void *);
-usbd_status usbd_do_request_flags(usbd_device_handle, usb_device_request_t *,
- void *, u_int16_t, int*, u_int32_t);
-usbd_status usbd_do_request_flags_pipe(usbd_device_handle, usbd_pipe_handle,
- usb_device_request_t *, void *, u_int16_t, int *, u_int32_t);
-usb_interface_descriptor_t *usbd_get_interface_descriptor
- (usbd_interface_handle);
-usb_config_descriptor_t *usbd_get_config_descriptor(usbd_device_handle);
-usb_device_descriptor_t *usbd_get_device_descriptor(usbd_device_handle);
-int usbd_get_speed(usbd_device_handle);
-usbd_status usbd_set_interface(usbd_interface_handle, int);
-int usbd_get_no_alts(usb_config_descriptor_t *, int);
-usbd_status usbd_get_interface(usbd_interface_handle, u_int8_t *);
-void usbd_fill_deviceinfo(usbd_device_handle, struct usb_device_info *, int);
-int usbd_get_interface_altindex(usbd_interface_handle);
-
-usb_interface_descriptor_t *usbd_find_idesc(usb_config_descriptor_t *,
- int, int);
-usb_endpoint_descriptor_t *usbd_find_edesc(usb_config_descriptor_t *,
- int, int, int);
-
-void usbd_dopoll(usbd_interface_handle);
-void usbd_set_polling(usbd_device_handle, int);
-usbd_status usbd_reset_device(usbd_device_handle);
-
-const char *usbd_errstr(usbd_status);
-
-void usbd_add_dev_event(int, usbd_device_handle);
-void usbd_add_drv_event(int, usbd_device_handle, device_t);
-
-void usbd_devinfo(usbd_device_handle, int, char *);
-const struct usbd_quirks *usbd_get_quirks(usbd_device_handle);
-usb_endpoint_descriptor_t *usbd_get_endpoint_descriptor
- (usbd_interface_handle, u_int8_t);
-
-usbd_status usbd_reload_device_desc(usbd_device_handle);
-
-int usbd_ratecheck(struct timeval *last);
-
-usbd_status usbd_get_string(usbd_device_handle dev, int si, char *buf,
- size_t len);
-
-/* An iterator for descriptors. */
-typedef struct {
- const uByte *cur;
- const uByte *end;
-} usbd_desc_iter_t;
-void usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter);
-const usb_descriptor_t *usb_desc_iter_next(usbd_desc_iter_t *iter);
-
-/*
- * The usb_task structs form a queue of things to run in the USB event
- * thread. Normally this is just device discovery when a connect/disconnect
- * has been detected. But it may also be used by drivers that need to
- * perform (short) tasks that must have a process context.
- */
-struct usb_task {
- TAILQ_ENTRY(usb_task) next;
- void (*fun)(void *);
- void *arg;
- int queue;
-};
-#define USB_TASKQ_HC 0
-#define USB_TASKQ_DRIVER 1
-#define USB_NUM_TASKQS 2
-#define USB_TASKQ_NAMES {"usbtask-hc", "usbtask-dr"}
-
-void usb_add_task(usbd_device_handle, struct usb_task *, int queue);
-void usb_rem_task(usbd_device_handle, struct usb_task *);
-#define usb_init_task(t, f, a) ((t)->fun = (f), (t)->arg = (a), (t)->queue = -1)
-
-struct usb_devno {
- u_int16_t ud_vendor;
- u_int16_t ud_product;
-};
-const struct usb_devno *usb_match_device(const struct usb_devno *,
- u_int, u_int, u_int16_t, u_int16_t);
-#define usb_lookup(tbl, vendor, product) \
- usb_match_device((const struct usb_devno *)(tbl), sizeof (tbl) / sizeof ((tbl)[0]), sizeof ((tbl)[0]), (vendor), (product))
-#define USB_PRODUCT_ANY 0xffff
-
-/* NetBSD attachment information */
-
-/* Attach data */
-struct usb_attach_arg {
- int port;
- int configno;
- int ifaceno;
- int vendor;
- int product;
- int release;
- int matchlvl;
- usbd_device_handle device; /* current device */
- usbd_interface_handle iface; /* current interface */
- int usegeneric;
- usbd_interface_handle *ifaces; /* all interfaces */
- int nifaces; /* number of interfaces */
-};
-
-/* FreeBSD needs values less than zero */
-#define UMATCH_VENDOR_PRODUCT_REV (-10)
-#define UMATCH_VENDOR_PRODUCT (-20)
-#define UMATCH_VENDOR_DEVCLASS_DEVPROTO (-30)
-#define UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO (-40)
-#define UMATCH_DEVCLASS_DEVSUBCLASS (-50)
-#define UMATCH_VENDOR_PRODUCT_REV_CONF_IFACE (-60)
-#define UMATCH_VENDOR_PRODUCT_CONF_IFACE (-70)
-#define UMATCH_VENDOR_IFACESUBCLASS_IFACEPROTO (-80)
-#define UMATCH_VENDOR_IFACESUBCLASS (-90)
-#define UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO (-100)
-#define UMATCH_IFACECLASS_IFACESUBCLASS (-110)
-#define UMATCH_IFACECLASS (-120)
-#define UMATCH_IFACECLASS_GENERIC (-130)
-#define UMATCH_GENERIC (-140)
-#define UMATCH_NONE (ENXIO)
-
-#define USBD_SHOW_DEVICE_CLASS 0x1
-#define USBD_SHOW_INTERFACE_CLASS 0x2
-
-struct module;
-int usbd_driver_load(struct module *mod, int what, void *arg);
-
-static inline int
-usb_get_port(device_t dev)
-{
- struct usb_attach_arg *uap = device_get_ivars(dev);
- return (uap->port);
-}
-
-static inline struct usbd_interface *
-usb_get_iface(device_t dev)
-{
- struct usb_attach_arg *uap = device_get_ivars(dev);
- return (uap->iface);
-}
-
-/* XXX Perhaps USB should have its own levels? */
-#ifdef USB_USE_SOFTINTR
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
-#define splusb splsoftnet
-#else
-#define splusb splsoftclock
-#endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
-#else
-#define splusb splbio
-#endif /* USB_USE_SOFTINTR */
-#define splhardusb splbio
-#define IPL_USB IPL_BIO
-
-#endif /* _USBDI_H_ */
diff --git a/sys/legacy/dev/usb/usbdi_util.c b/sys/legacy/dev/usb/usbdi_util.c
deleted file mode 100644
index 78ea571..0000000
--- a/sys/legacy/dev/usb/usbdi_util.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/* $NetBSD: usbdi_util.c,v 1.42 2004/12/03 08:53:40 augustss Exp $ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-extern int usbdebug;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-usbd_status
-usbd_get_desc(usbd_device_handle dev, int type, int index, int len, void *desc)
-{
- usb_device_request_t req;
-
- DPRINTFN(3,("usbd_get_desc: type=%d, index=%d, len=%d\n",
- type, index, len));
-
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW2(req.wValue, type, index);
- USETW(req.wIndex, 0);
- USETW(req.wLength, len);
- return (usbd_do_request(dev, &req, desc));
-}
-
-usbd_status
-usbd_get_config_desc(usbd_device_handle dev, int confidx,
- usb_config_descriptor_t *d)
-{
- usbd_status err;
-
- DPRINTFN(3,("usbd_get_config_desc: confidx=%d\n", confidx));
- err = usbd_get_desc(dev, UDESC_CONFIG, confidx,
- USB_CONFIG_DESCRIPTOR_SIZE, d);
- if (err)
- return (err);
- if (d->bDescriptorType != UDESC_CONFIG) {
- DPRINTFN(-1,("usbd_get_config_desc: confidx=%d, bad desc "
- "len=%d type=%d\n",
- confidx, d->bLength, d->bDescriptorType));
- return (USBD_INVAL);
- }
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_get_config_desc_full(usbd_device_handle dev, int conf, void *d, int size)
-{
- DPRINTFN(3,("usbd_get_config_desc_full: conf=%d\n", conf));
- return (usbd_get_desc(dev, UDESC_CONFIG, conf, size, d));
-}
-
-usbd_status
-usbd_get_device_desc(usbd_device_handle dev, usb_device_descriptor_t *d)
-{
- DPRINTFN(3,("usbd_get_device_desc:\n"));
- return (usbd_get_desc(dev, UDESC_DEVICE,
- 0, USB_DEVICE_DESCRIPTOR_SIZE, d));
-}
-
-usbd_status
-usbd_get_device_status(usbd_device_handle dev, usb_status_t *st)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(usb_status_t));
- return (usbd_do_request(dev, &req, st));
-}
-
-usbd_status
-usbd_get_hub_status(usbd_device_handle dev, usb_hub_status_t *st)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_CLASS_DEVICE;
- req.bRequest = UR_GET_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(usb_hub_status_t));
- return (usbd_do_request(dev, &req, st));
-}
-
-usbd_status
-usbd_set_address(usbd_device_handle dev, int addr)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_SET_ADDRESS;
- USETW(req.wValue, addr);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- return usbd_do_request(dev, &req, 0);
-}
-
-usbd_status
-usbd_get_port_status(usbd_device_handle dev, int port, usb_port_status_t *ps)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_CLASS_OTHER;
- req.bRequest = UR_GET_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, port);
- USETW(req.wLength, sizeof *ps);
- return (usbd_do_request(dev, &req, ps));
-}
-
-usbd_status
-usbd_clear_hub_feature(usbd_device_handle dev, int sel)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_CLASS_DEVICE;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, sel);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_set_hub_feature(usbd_device_handle dev, int sel)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_CLASS_DEVICE;
- req.bRequest = UR_SET_FEATURE;
- USETW(req.wValue, sel);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_clear_port_feature(usbd_device_handle dev, int port, int sel)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_CLASS_OTHER;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, sel);
- USETW(req.wIndex, port);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_set_port_feature(usbd_device_handle dev, int port, int sel)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_CLASS_OTHER;
- req.bRequest = UR_SET_FEATURE;
- USETW(req.wValue, sel);
- USETW(req.wIndex, port);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_get_protocol(usbd_interface_handle iface, u_int8_t *report)
-{
- usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_get_protocol: iface=%p, endpt=%d\n",
- iface, id->bInterfaceNumber));
- if (id == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_GET_PROTOCOL;
- USETW(req.wValue, 0);
- USETW(req.wIndex, id->bInterfaceNumber);
- USETW(req.wLength, 1);
- return (usbd_do_request(dev, &req, report));
-}
-
-usbd_status
-usbd_set_protocol(usbd_interface_handle iface, int report)
-{
- usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_set_protocol: iface=%p, report=%d, endpt=%d\n",
- iface, report, id->bInterfaceNumber));
- if (id == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_PROTOCOL;
- USETW(req.wValue, report);
- USETW(req.wIndex, id->bInterfaceNumber);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_set_report(usbd_interface_handle iface, int type, int id, void *data,
- int len)
-{
- usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
- if (ifd == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, type, id);
- USETW(req.wIndex, ifd->bInterfaceNumber);
- USETW(req.wLength, len);
- return (usbd_do_request(dev, &req, data));
-}
-
-usbd_status
-usbd_set_report_async(usbd_interface_handle iface, int type, int id, void *data,
- int len)
-{
- usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_set_report_async: len=%d\n", len));
- if (ifd == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, type, id);
- USETW(req.wIndex, ifd->bInterfaceNumber);
- USETW(req.wLength, len);
- return (usbd_do_request_async(dev, &req, data));
-}
-
-usbd_status
-usbd_get_report(usbd_interface_handle iface, int type, int id, void *data,
- int len)
-{
- usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_get_report: len=%d\n", len));
- if (ifd == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_GET_REPORT;
- USETW2(req.wValue, type, id);
- USETW(req.wIndex, ifd->bInterfaceNumber);
- USETW(req.wLength, len);
- return (usbd_do_request(dev, &req, data));
-}
-
-usbd_status
-usbd_set_idle(usbd_interface_handle iface, int duration, int id)
-{
- usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_set_idle: %d %d\n", duration, id));
- if (ifd == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_IDLE;
- USETW2(req.wValue, duration, id);
- USETW(req.wIndex, ifd->bInterfaceNumber);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_get_report_descriptor(usbd_device_handle dev, int ifcno,
- int size, void *d)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_INTERFACE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW2(req.wValue, UDESC_REPORT, 0); /* report id should be 0 */
- USETW(req.wIndex, ifcno);
- USETW(req.wLength, size);
- return (usbd_do_request(dev, &req, d));
-}
-
-usb_hid_descriptor_t *
-usbd_get_hid_descriptor(usbd_interface_handle ifc)
-{
- usb_interface_descriptor_t *idesc = usbd_get_interface_descriptor(ifc);
- usbd_device_handle dev;
- usb_config_descriptor_t *cdesc;
- usb_hid_descriptor_t *hd;
- char *p, *end;
-
- if (idesc == NULL)
- return (NULL);
- usbd_interface2device_handle(ifc, &dev);
- cdesc = usbd_get_config_descriptor(dev);
-
- p = (char *)idesc + idesc->bLength;
- end = (char *)cdesc + UGETW(cdesc->wTotalLength);
-
- for (; p < end; p += hd->bLength) {
- hd = (usb_hid_descriptor_t *)p;
- if (p + hd->bLength <= end && hd->bDescriptorType == UDESC_HID)
- return (hd);
- if (hd->bDescriptorType == UDESC_INTERFACE)
- break;
- }
- return (NULL);
-}
-
-usbd_status
-usbd_read_report_desc(usbd_interface_handle ifc, void **descp, int *sizep,
- struct malloc_type *mem)
-{
- usb_interface_descriptor_t *id;
- usb_hid_descriptor_t *hid;
- usbd_device_handle dev;
- usbd_status err;
-
- usbd_interface2device_handle(ifc, &dev);
- id = usbd_get_interface_descriptor(ifc);
- if (id == NULL)
- return (USBD_INVAL);
- hid = usbd_get_hid_descriptor(ifc);
- if (hid == NULL)
- return (USBD_IOERROR);
- *sizep = UGETW(hid->descrs[0].wDescriptorLength);
- *descp = malloc(*sizep, mem, M_NOWAIT);
- if (*descp == NULL)
- return (USBD_NOMEM);
- err = usbd_get_report_descriptor(dev, id->bInterfaceNumber,
- *sizep, *descp);
- if (err) {
- free(*descp, mem);
- *descp = NULL;
- return (err);
- }
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_get_config(usbd_device_handle dev, u_int8_t *conf)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_CONFIG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 1);
- return (usbd_do_request(dev, &req, conf));
-}
-
-static void usbd_bulk_transfer_cb(usbd_xfer_handle xfer,
- usbd_private_handle priv, usbd_status status);
-static void
-usbd_bulk_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- wakeup(xfer);
-}
-
-usbd_status
-usbd_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
- u_int16_t flags, u_int32_t timeout, void *buf,
- u_int32_t *size, char *lbl)
-{
- usbd_status err;
- int s, error;
-
- usbd_setup_xfer(xfer, pipe, 0, buf, *size,
- flags, timeout, usbd_bulk_transfer_cb);
- DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size));
- s = splusb(); /* don't want callback until tsleep() */
- err = usbd_transfer(xfer);
- if (err != USBD_IN_PROGRESS) {
- splx(s);
- return (err);
- }
- error = tsleep((caddr_t)xfer, PZERO | PCATCH, lbl, 0);
- splx(s);
- if (error) {
- DPRINTF(("usbd_bulk_transfer: tsleep=%d\n", error));
- usbd_abort_pipe(pipe);
- return (USBD_INTERRUPTED);
- }
- usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
- DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size));
- if (err) {
- DPRINTF(("usbd_bulk_transfer: error=%d\n", err));
- usbd_clear_endpoint_stall(pipe);
- }
- return (err);
-}
-
-static void usbd_intr_transfer_cb(usbd_xfer_handle xfer,
- usbd_private_handle priv, usbd_status status);
-static void
-usbd_intr_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- wakeup(xfer);
-}
-
-usbd_status
-usbd_intr_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
- u_int16_t flags, u_int32_t timeout, void *buf,
- u_int32_t *size, char *lbl)
-{
- usbd_status err;
- int s, error;
-
- usbd_setup_xfer(xfer, pipe, 0, buf, *size,
- flags, timeout, usbd_intr_transfer_cb);
- DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size));
- s = splusb(); /* don't want callback until tsleep() */
- err = usbd_transfer(xfer);
- if (err != USBD_IN_PROGRESS) {
- splx(s);
- return (err);
- }
- error = tsleep(xfer, PZERO | PCATCH, lbl, 0);
- splx(s);
- if (error) {
- DPRINTF(("usbd_intr_transfer: tsleep=%d\n", error));
- usbd_abort_pipe(pipe);
- return (USBD_INTERRUPTED);
- }
- usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
- DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size));
- if (err) {
- DPRINTF(("usbd_intr_transfer: error=%d\n", err));
- usbd_clear_endpoint_stall(pipe);
- }
- return (err);
-}
-
-void
-usb_detach_wait(device_t dv)
-{
- DPRINTF(("usb_detach_wait: waiting for %s\n", device_get_nameunit(dv)));
- if (tsleep(dv, PZERO, "usbdet", hz * 60))
- printf("usb_detach_wait: %s didn't detach\n",
- device_get_nameunit(dv));
- DPRINTF(("usb_detach_wait: %s done\n", device_get_nameunit(dv)));
-}
-
-void
-usb_detach_wakeup(device_t dv)
-{
- DPRINTF(("usb_detach_wakeup: for %s\n", device_get_nameunit(dv)));
- wakeup(dv);
-}
-
-const usb_descriptor_t *
-usb_find_desc(usbd_device_handle dev, int type, int subtype)
-{
- usbd_desc_iter_t iter;
- const usb_descriptor_t *desc;
-
- usb_desc_iter_init(dev, &iter);
- for (;;) {
- desc = usb_desc_iter_next(&iter);
- if (!desc || (desc->bDescriptorType == type &&
- (subtype == USBD_SUBTYPE_ANY ||
- subtype == desc->bDescriptorSubtype)))
- break;
- }
- return desc;
-}
diff --git a/sys/legacy/dev/usb/usbdi_util.h b/sys/legacy/dev/usb/usbdi_util.h
deleted file mode 100644
index b535f0c..0000000
--- a/sys/legacy/dev/usb/usbdi_util.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* $NetBSD: usbdi_util.h,v 1.31 2004/12/03 08:53:40 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _USBI_UTIL_H_
-#define _USBI_UTIL_H_
-usbd_status usbd_get_desc(usbd_device_handle dev, int type,
- int index, int len, void *desc);
-usbd_status usbd_get_config_desc(usbd_device_handle, int,
- usb_config_descriptor_t *);
-usbd_status usbd_get_config_desc_full(usbd_device_handle, int, void *, int);
-usbd_status usbd_get_device_desc(usbd_device_handle dev,
- usb_device_descriptor_t *d);
-usbd_status usbd_set_address(usbd_device_handle dev, int addr);
-usbd_status usbd_get_port_status(usbd_device_handle,
- int, usb_port_status_t *);
-usbd_status usbd_set_hub_feature(usbd_device_handle dev, int);
-usbd_status usbd_clear_hub_feature(usbd_device_handle, int);
-usbd_status usbd_set_port_feature(usbd_device_handle dev, int, int);
-usbd_status usbd_clear_port_feature(usbd_device_handle, int, int);
-usbd_status usbd_get_device_status(usbd_device_handle, usb_status_t *);
-usbd_status usbd_get_hub_status(usbd_device_handle, usb_hub_status_t *);
-usbd_status usbd_get_protocol(usbd_interface_handle dev, u_int8_t *report);
-usbd_status usbd_set_protocol(usbd_interface_handle dev, int report);
-usbd_status usbd_get_report_descriptor(usbd_device_handle dev, int ifcno,
- int size, void *d);
-struct usb_hid_descriptor *usbd_get_hid_descriptor(usbd_interface_handle ifc);
-usbd_status usbd_set_report(usbd_interface_handle iface, int type, int id,
- void *data,int len);
-usbd_status usbd_set_report_async(usbd_interface_handle iface, int type,
- int id, void *data, int len);
-usbd_status usbd_get_report(usbd_interface_handle iface, int type, int id,
- void *data, int len);
-usbd_status usbd_set_idle(usbd_interface_handle iface, int duration, int id);
-usbd_status usbd_read_report_desc(usbd_interface_handle ifc, void **descp,
- int *sizep, struct malloc_type *mem);
-usbd_status usbd_get_config(usbd_device_handle dev, u_int8_t *conf);
-usbd_status usbd_get_string_desc(usbd_device_handle dev, int sindex,
- int langid,usb_string_descriptor_t *sdesc,
- int *sizep);
-void usbd_delay_ms(usbd_device_handle, u_int);
-
-
-usbd_status usbd_set_config_no(usbd_device_handle dev, int no, int msg);
-usbd_status usbd_set_config_index(usbd_device_handle dev, int index, int msg);
-
-usbd_status usbd_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
- u_int16_t flags, u_int32_t timeout, void *buf,
- u_int32_t *size, char *lbl);
-
-usbd_status usbd_intr_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
- u_int16_t flags, u_int32_t timeout, void *buf,
- u_int32_t *size, char *lbl);
-
-void usb_detach_wait(device_t);
-void usb_detach_wakeup(device_t);
-
-const usb_descriptor_t *usb_find_desc(usbd_device_handle dev, int type,
- int subtype);
-#define USBD_SUBTYPE_ANY (~0)
-
-#endif /* _USBI_UTIL_H_ */
diff --git a/sys/legacy/dev/usb/usbdivar.h b/sys/legacy/dev/usb/usbdivar.h
deleted file mode 100644
index 603d691..0000000
--- a/sys/legacy/dev/usb/usbdivar.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/* $NetBSD: usbdivar.h,v 1.70 2002/07/11 21:14:36 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* From usb_mem.h */
-struct usb_dma_block;
-typedef struct {
- struct usb_dma_block *block;
- u_int offs;
- u_int len;
-} usb_dma_t;
-
-struct usbd_xfer;
-struct usbd_pipe;
-
-struct usbd_endpoint {
- usb_endpoint_descriptor_t *edesc;
- int refcnt;
- int savedtoggle;
-};
-
-struct usbd_bus_methods {
- usbd_status (*open_pipe)(struct usbd_pipe *pipe);
- void (*soft_intr)(void *);
- void (*do_poll)(struct usbd_bus *);
- usbd_status (*allocm)(struct usbd_bus *, usb_dma_t *,
- u_int32_t bufsize);
- void (*freem)(struct usbd_bus *, usb_dma_t *);
- struct usbd_xfer * (*allocx)(struct usbd_bus *);
- void (*freex)(struct usbd_bus *, struct usbd_xfer *);
-};
-
-struct usbd_pipe_methods {
- usbd_status (*transfer)(usbd_xfer_handle xfer);
- usbd_status (*start)(usbd_xfer_handle xfer);
- void (*abort)(usbd_xfer_handle xfer);
- void (*close)(usbd_pipe_handle pipe);
- void (*cleartoggle)(usbd_pipe_handle pipe);
- void (*done)(usbd_xfer_handle xfer);
-};
-
-struct usbd_tt {
- struct usbd_hub *hub;
-};
-
-struct usbd_port {
- usb_port_status_t status;
- u_int16_t power; /* mA of current on port */
- u_int8_t portno;
- u_int8_t restartcnt;
-#define USBD_RESTART_MAX 5
- struct usbd_device *device; /* Connected device */
- struct usbd_device *parent; /* The ports hub */
- struct usbd_tt *tt; /* Transaction translator (if any) */
-};
-
-struct usbd_hub {
- usbd_status (*explore)(usbd_device_handle hub);
- void *hubsoftc;
- usb_hub_descriptor_t hubdesc;
- struct usbd_port ports[1];
-};
-
-struct usb_softc;
-
-/*****/
-
-struct usbd_bus {
- /* Filled by HC driver */
- device_t bdev; /* base device, host adapter */
- struct usbd_bus_methods *methods;
- u_int32_t pipe_size; /* size of a pipe struct */
- /* Filled by usb driver */
- struct usbd_device *root_hub;
- usbd_device_handle devices[USB_MAX_DEVICES];
- char needs_explore;/* a hub a signalled a change */
- char use_polling;
- struct usb_softc *usbctl;
- struct usb_device_stats stats;
- int intr_context;
- u_int no_intrs;
- int usbrev; /* USB revision */
-#define USBREV_UNKNOWN 0
-#define USBREV_PRE_1_0 1
-#define USBREV_1_0 2
-#define USBREV_1_1 3
-#define USBREV_2_0 4
-#define USBREV_STR { "unknown", "pre 1.0", "1.0", "1.1", "2.0" }
-
-#ifdef USB_USE_SOFTINTR
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
- void *soft; /* soft interrupt cookie */
-#else
- struct callout softi;
-#endif
-#endif
-
- bus_dma_tag_t parent_dmatag; /* Base DMA tag */
- bus_dma_tag_t buffer_dmatag; /* Tag for transfer buffers */
-};
-
-struct usbd_device {
- struct usbd_bus *bus; /* our controller */
- struct usbd_pipe *default_pipe; /* pipe 0 */
- u_int8_t address; /* device addess */
- u_int8_t config; /* current configuration # */
- u_int8_t depth; /* distance from root hub */
- u_int8_t speed; /* low/full/high speed */
- u_int8_t self_powered; /* flag for self powered */
- u_int16_t power; /* mA the device uses */
- int16_t langid; /* language for strings */
-#define USBD_NOLANG (-1)
- usb_event_cookie_t cookie; /* unique connection id */
- struct usbd_port *powersrc; /* upstream hub port, or 0 */
- struct usbd_device *myhub; /* upstream hub */
- struct usbd_port *myhsport; /* closest high speed port */
- struct usbd_endpoint def_ep; /* for pipe 0 */
- usb_endpoint_descriptor_t def_ep_desc; /* for pipe 0 */
- struct usbd_interface *ifaces; /* array of all interfaces */
- usb_device_descriptor_t ddesc; /* device descriptor */
- usb_config_descriptor_t *cdesc; /* full config descr */
- const struct usbd_quirks *quirks; /* device quirks, always set */
- struct usbd_hub *hub; /* only if this is a hub */
- device_t *subdevs; /* sub-devices, 0 terminated */
- uint8_t *ifacenums; /* sub-device interfacenumbers */
-};
-
-struct usbd_interface {
- struct usbd_device *device;
- usb_interface_descriptor_t *idesc;
- int index;
- int altindex;
- struct usbd_endpoint *endpoints;
- void *priv;
- LIST_HEAD(, usbd_pipe) pipes;
-};
-
-struct usbd_pipe {
- struct usbd_interface *iface;
- struct usbd_device *device;
- struct usbd_endpoint *endpoint;
- int refcnt;
- char running;
- char aborting;
- STAILQ_HEAD(, usbd_xfer) queue;
- LIST_ENTRY(usbd_pipe) next;
-
- usbd_xfer_handle intrxfer; /* used for repeating requests */
- char repeat;
- int interval;
-
- /* Filled by HC driver. */
- struct usbd_pipe_methods *methods;
-};
-
-#define USB_DMA_NSEG (btoc(MAXPHYS) + 1)
-
-/* DMA-capable memory buffer. */
-struct usb_dma_mapping {
- bus_dma_segment_t segs[USB_DMA_NSEG]; /* The physical segments. */
- int nsegs; /* Number of segments. */
- bus_dmamap_t map; /* DMA mapping. */
-};
-
-struct usbd_xfer {
- struct usbd_pipe *pipe;
- void *priv;
- void *buffer;
- u_int32_t length;
- u_int32_t actlen;
- u_int16_t flags;
- u_int32_t timeout;
- usbd_status status;
- usbd_callback callback;
- __volatile char done;
-#ifdef DIAGNOSTIC
- u_int32_t busy_free;
-#define XFER_FREE 0x46524545
-#define XFER_BUSY 0x42555359
-#define XFER_ONQU 0x4f4e5155
-#endif
-
- /* For control pipe */
- usb_device_request_t request;
-
- /* For isoc */
- u_int16_t *frlengths;
- int nframes;
-
- /* For memory allocation */
- struct usbd_device *device;
- struct usb_dma_mapping dmamap;
- void *allocbuf;
-
- int rqflags;
-#define URQ_REQUEST 0x01
-#define URQ_AUTO_DMABUF 0x10
-#define URQ_DEV_DMABUF 0x20
-
- STAILQ_ENTRY(usbd_xfer) next;
-
- void *hcpriv; /* private use by the HC driver */
-
- struct callout timeout_handle;
-};
-
-#define URQ_BITS "\20\1REQUEST\5AUTO_DMABUF\6DEV_DMABUF"
-
-void usbd_init(void);
-void usbd_finish(void);
-
-#ifdef USB_DEBUG
-void usbd_dump_iface(struct usbd_interface *iface);
-void usbd_dump_device(struct usbd_device *dev);
-void usbd_dump_endpoint(struct usbd_endpoint *endp);
-void usbd_dump_queue(usbd_pipe_handle pipe);
-void usbd_dump_pipe(usbd_pipe_handle pipe);
-#endif
-
-/* Routines from usb_subr.c */
-int usbctlprint(void *, const char *);
-void usb_delay_ms(usbd_bus_handle, u_int);
-usbd_status usbd_reset_port(usbd_device_handle dev,
- int port, usb_port_status_t *ps);
-usbd_status usbd_setup_pipe(usbd_device_handle dev,
- usbd_interface_handle iface,
- struct usbd_endpoint *, int,
- usbd_pipe_handle *pipe);
-usbd_status usbd_new_device(device_t parent,
- usbd_bus_handle bus, int depth,
- int lowspeed, int port,
- struct usbd_port *);
-void usbd_remove_device(usbd_device_handle, struct usbd_port *);
-int usbd_printBCD(char *cp, int bcd);
-usbd_status usbd_fill_iface_data(usbd_device_handle dev, int i, int a);
-void usb_free_device(usbd_device_handle);
-
-usbd_status usb_insert_transfer(usbd_xfer_handle xfer);
-void usb_transfer_complete(usbd_xfer_handle xfer);
-void usb_disconnect_port(struct usbd_port *up, device_t);
-
-/* Routines from usb.c */
-void usb_needs_explore(usbd_device_handle);
-void usb_schedsoftintr(struct usbd_bus *);
-
-/*
- * XXX This check is extremely bogus. Bad Bad Bad.
- */
-#if defined(DIAGNOSTIC) && 0
-#define SPLUSBCHECK \
- do { int _s = splusb(), _su = splusb(); \
- if (!cold && _s != _su) printf("SPLUSBCHECK failed 0x%x!=0x%x, %s:%d\n", \
- _s, _su, __FILE__, __LINE__); \
- splx(_s); \
- } while (0)
-#else
-#define SPLUSBCHECK
-#endif
-
-/* Locator stuff. */
-
-/* XXX these values are used to statically bind some elements in the USB tree
- * to specific driver instances. This should be somehow emulated in FreeBSD
- * but can be done later on.
- * The values are copied from the files.usb file in the NetBSD sources.
- */
-#define UHUBCF_PORT_DEFAULT -1
-#define UHUBCF_CONFIGURATION_DEFAULT -1
-#define UHUBCF_INTERFACE_DEFAULT -1
-#define UHUBCF_VENDOR_DEFAULT -1
-#define UHUBCF_PRODUCT_DEFAULT -1
-#define UHUBCF_RELEASE_DEFAULT -1
-
-#define uhubcf_port cf_loc[UHUBCF_PORT]
-#define uhubcf_configuration cf_loc[UHUBCF_CONFIGURATION]
-#define uhubcf_interface cf_loc[UHUBCF_INTERFACE]
-#define uhubcf_vendor cf_loc[UHUBCF_VENDOR]
-#define uhubcf_product cf_loc[UHUBCF_PRODUCT]
-#define uhubcf_release cf_loc[UHUBCF_RELEASE]
-#define UHUB_UNK_PORT UHUBCF_PORT_DEFAULT /* wildcarded 'port' */
-#define UHUB_UNK_CONFIGURATION UHUBCF_CONFIGURATION_DEFAULT /* wildcarded 'configuration' */
-#define UHUB_UNK_INTERFACE UHUBCF_INTERFACE_DEFAULT /* wildcarded 'interface' */
-#define UHUB_UNK_VENDOR UHUBCF_VENDOR_DEFAULT /* wildcarded 'vendor' */
-#define UHUB_UNK_PRODUCT UHUBCF_PRODUCT_DEFAULT /* wildcarded 'product' */
-#define UHUB_UNK_RELEASE UHUBCF_RELEASE_DEFAULT /* wildcarded 'release' */
-
diff --git a/sys/legacy/dev/usb/usbhid.h b/sys/legacy/dev/usb/usbhid.h
deleted file mode 100644
index 8e0ecd5..0000000
--- a/sys/legacy/dev/usb/usbhid.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* $NetBSD: usbhid.h,v 1.9 2000/09/03 19:09:14 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef _USBHID_H_
-#define _USBHID_H_
-
-#define UR_GET_HID_DESCRIPTOR 0x06
-#define UDESC_HID 0x21
-#define UDESC_REPORT 0x22
-#define UDESC_PHYSICAL 0x23
-#define UR_SET_HID_DESCRIPTOR 0x07
-#define UR_GET_REPORT 0x01
-#define UR_SET_REPORT 0x09
-#define UR_GET_IDLE 0x02
-#define UR_SET_IDLE 0x0a
-#define UR_GET_PROTOCOL 0x03
-#define UR_SET_PROTOCOL 0x0b
-
-typedef struct usb_hid_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uWord bcdHID;
- uByte bCountryCode;
- uByte bNumDescriptors;
- struct {
- uByte bDescriptorType;
- uWord wDescriptorLength;
- } descrs[1];
-} UPACKED usb_hid_descriptor_t;
-#define USB_HID_DESCRIPTOR_SIZE(n) (9+(n)*3)
-
-/* Usage pages */
-#define HUP_UNDEFINED 0x0000
-#define HUP_GENERIC_DESKTOP 0x0001
-#define HUP_SIMULATION 0x0002
-#define HUP_VR_CONTROLS 0x0003
-#define HUP_SPORTS_CONTROLS 0x0004
-#define HUP_GAMING_CONTROLS 0x0005
-#define HUP_KEYBOARD 0x0007
-#define HUP_LEDS 0x0008
-#define HUP_BUTTON 0x0009
-#define HUP_ORDINALS 0x000a
-#define HUP_TELEPHONY 0x000b
-#define HUP_CONSUMER 0x000c
-#define HUP_DIGITIZERS 0x000d
-#define HUP_PHYSICAL_IFACE 0x000e
-#define HUP_UNICODE 0x0010
-#define HUP_ALPHANUM_DISPLAY 0x0014
-#define HUP_MONITOR 0x0080
-#define HUP_MONITOR_ENUM_VAL 0x0081
-#define HUP_VESA_VC 0x0082
-#define HUP_VESA_CMD 0x0083
-#define HUP_POWER 0x0084
-#define HUP_BATTERY_SYSTEM 0x0085
-#define HUP_BARCODE_SCANNER 0x008b
-#define HUP_SCALE 0x008c
-#define HUP_CAMERA_CONTROL 0x0090
-#define HUP_ARCADE 0x0091
-#define HUP_MICROSOFT 0xff00
-
-/* Usages, generic desktop */
-#define HUG_POINTER 0x0001
-#define HUG_MOUSE 0x0002
-#define HUG_JOYSTICK 0x0004
-#define HUG_GAME_PAD 0x0005
-#define HUG_KEYBOARD 0x0006
-#define HUG_KEYPAD 0x0007
-#define HUG_X 0x0030
-#define HUG_Y 0x0031
-#define HUG_Z 0x0032
-#define HUG_RX 0x0033
-#define HUG_RY 0x0034
-#define HUG_RZ 0x0035
-#define HUG_SLIDER 0x0036
-#define HUG_DIAL 0x0037
-#define HUG_WHEEL 0x0038
-#define HUG_HAT_SWITCH 0x0039
-#define HUG_COUNTED_BUFFER 0x003a
-#define HUG_BYTE_COUNT 0x003b
-#define HUG_MOTION_WAKEUP 0x003c
-#define HUG_VX 0x0040
-#define HUG_VY 0x0041
-#define HUG_VZ 0x0042
-#define HUG_VBRX 0x0043
-#define HUG_VBRY 0x0044
-#define HUG_VBRZ 0x0045
-#define HUG_VNO 0x0046
-#define HUG_TWHEEL 0x0048 // M$ Wireless Intellimouse Wheel
-#define HUG_SYSTEM_CONTROL 0x0080
-#define HUG_SYSTEM_POWER_DOWN 0x0081
-#define HUG_SYSTEM_SLEEP 0x0082
-#define HUG_SYSTEM_WAKEUP 0x0083
-#define HUG_SYSTEM_CONTEXT_MENU 0x0084
-#define HUG_SYSTEM_MAIN_MENU 0x0085
-#define HUG_SYSTEM_APP_MENU 0x0086
-#define HUG_SYSTEM_MENU_HELP 0x0087
-#define HUG_SYSTEM_MENU_EXIT 0x0088
-#define HUG_SYSTEM_MENU_SELECT 0x0089
-#define HUG_SYSTEM_MENU_RIGHT 0x008a
-#define HUG_SYSTEM_MENU_LEFT 0x008b
-#define HUG_SYSTEM_MENU_UP 0x008c
-#define HUG_SYSTEM_MENU_DOWN 0x008d
-
-/* Usages Digitizers */
-#define HUD_UNDEFINED 0x0000
-#define HUD_TIP_PRESSURE 0x0030
-#define HUD_BARREL_PRESSURE 0x0031
-#define HUD_IN_RANGE 0x0032
-#define HUD_TOUCH 0x0033
-#define HUD_UNTOUCH 0x0034
-#define HUD_TAP 0x0035
-#define HUD_QUALITY 0x0036
-#define HUD_DATA_VALID 0x0037
-#define HUD_TRANSDUCER_INDEX 0x0038
-#define HUD_TABLET_FKEYS 0x0039
-#define HUD_PROGRAM_CHANGE_KEYS 0x003a
-#define HUD_BATTERY_STRENGTH 0x003b
-#define HUD_INVERT 0x003c
-#define HUD_X_TILT 0x003d
-#define HUD_Y_TILT 0x003e
-#define HUD_AZIMUTH 0x003f
-#define HUD_ALTITUDE 0x0040
-#define HUD_TWIST 0x0041
-#define HUD_TIP_SWITCH 0x0042
-#define HUD_SEC_TIP_SWITCH 0x0043
-#define HUD_BARREL_SWITCH 0x0044
-#define HUD_ERASER 0x0045
-#define HUD_TABLET_PICK 0x0046
-
-#define HID_USAGE2(p,u) (((p) << 16) | u)
-
-#define UHID_INPUT_REPORT 0x01
-#define UHID_OUTPUT_REPORT 0x02
-#define UHID_FEATURE_REPORT 0x03
-
-/* Bits in the input/output/feature items */
-#define HIO_CONST 0x001
-#define HIO_VARIABLE 0x002
-#define HIO_RELATIVE 0x004
-#define HIO_WRAP 0x008
-#define HIO_NONLINEAR 0x010
-#define HIO_NOPREF 0x020
-#define HIO_NULLSTATE 0x040
-#define HIO_VOLATILE 0x080
-#define HIO_BUFBYTES 0x100
-
-#endif /* _USBHID_H_ */
diff --git a/sys/legacy/dev/usb/uscanner.c b/sys/legacy/dev/usb/uscanner.c
deleted file mode 100644
index bff3a48..0000000
--- a/sys/legacy/dev/usb/uscanner.c
+++ /dev/null
@@ -1,723 +0,0 @@
-/* $NetBSD: uscanner.c,v 1.30 2002/07/11 21:14:36 augustss Exp$ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: uscanner.c,v 1.33 2002/09/23 05:51:24 simonb Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology
- * and Nick Hibma (n_hibma@qubesoft.com).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/conf.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include "usbdevs.h"
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (uscannerdebug) printf x
-#define DPRINTFN(n,x) if (uscannerdebug>(n)) printf x
-int uscannerdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uscanner, CTLFLAG_RW, 0, "USB uscanner");
-SYSCTL_INT(_hw_usb_uscanner, OID_AUTO, debug, CTLFLAG_RW,
- &uscannerdebug, 0, "uscanner debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct uscan_info {
- struct usb_devno devno;
- u_int flags;
-#define USC_KEEP_OPEN 1
-};
-
-/* Table of scanners that may work with this driver. */
-static const struct uscan_info uscanner_devs[] = {
-
- /*
- * These first two entries are duplicates of known-working units,
- * so one can patch them to test support for newer devices
- * without rebuilding the module.
- */
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_6000 }, 0 }, /* duplicate */
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_6000 }, 0 }, /* duplicate */
-
- /* Acer Peripherals */
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_4300U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640BT }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_620U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_1240U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_C310U }, 0 },
-
- /* AGFA */
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1236U }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U2 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANTOUCH }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE40 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE50 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE20 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE25 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE26 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE52 }, 0 },
-
- /* Avision */
- {{ USB_VENDOR_AVISION, USB_PRODUCT_AVISION_1200U }, 0 },
-
- /* Canon */
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N656U }, 0 },
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N676U }, 0 },
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N1220U }, 0 },
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_D660U }, 0 },
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N1240U }, 0 },
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_LIDE25 }, 0 },
-
- /* Kye */
- {{ USB_VENDOR_KYE, USB_PRODUCT_KYE_VIVIDPRO }, 0 },
-
- /* HP */
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_2200C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_3300C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_3400CSE }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_4100C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_4200C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_4300C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_4470C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_4670V }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_S20 }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_5200C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_5300C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_5400C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_6200C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_6300C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_82x0C }, 0 },
-
- /* Microtek */
- {{ USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_336CX }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_X6U }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX2 }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_C6 }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL2 }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6UL }, 0 },
-
- /* Minolta */
- {{ USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_5400 }, 0 },
-
- /* Mustek */
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CU }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200F }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200TA }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600USB }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600CU }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USB }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200UB }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USBPLUS }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CUPLUS }, 0 },
-
- /* National */
- {{ USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW1200 }, 0 },
- {{ USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW2400 }, 0 },
-
- /* Nikon */
- {{ USB_VENDOR_NIKON, USB_PRODUCT_NIKON_LS40 }, 0 },
-
- /* Primax */
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2X300 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E300 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2300 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E3002 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_9600 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_600U }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_6200 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_19200 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_1200U }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G600 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_636I }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2600 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E600 }, 0 },
-
- /* Epson */
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_636 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_610 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1200 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1240 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1250 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1600 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1640 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_640U }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1650 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1660 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1670 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1260 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1270 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_RX425 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_3200 }, USC_KEEP_OPEN },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9700F }, USC_KEEP_OPEN },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9300UF }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_2480 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_3500 }, USC_KEEP_OPEN },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_3590 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4200 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4800 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4990 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_5000 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_6000 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_CX5400 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX7400 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX8400 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_CX5400 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX3800 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX4000 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_NX300 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_SX200 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_SX400 }, 0 },
-
- /* UMAX */
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1220U }, 0 },
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1236U }, 0 },
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2000U }, 0 },
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2100U }, 0 },
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2200U }, 0 },
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA3400 }, 0 },
-
- /* Visioneer */
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_3000 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_5300 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_7600 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6100 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6200 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8100 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8600 }, 0 },
-
- /* Ultima */
- {{ USB_VENDOR_ULTIMA, USB_PRODUCT_ULTIMA_1200UBPLUS }, 0 },
-
-};
-#define uscanner_lookup(v, p) ((const struct uscan_info *)usb_lookup(uscanner_devs, v, p))
-
-#define USCANNER_BUFFERSIZE 1024
-
-struct uscanner_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
- struct cdev *dev;
-
- u_int sc_dev_flags;
-
- usbd_pipe_handle sc_bulkin_pipe;
- int sc_bulkin;
- usbd_xfer_handle sc_bulkin_xfer;
- void *sc_bulkin_buffer;
- int sc_bulkin_bufferlen;
- int sc_bulkin_datalen;
-
- usbd_pipe_handle sc_bulkout_pipe;
- int sc_bulkout;
- usbd_xfer_handle sc_bulkout_xfer;
- void *sc_bulkout_buffer;
- int sc_bulkout_bufferlen;
- int sc_bulkout_datalen;
-
- u_char sc_state;
-#define USCANNER_OPEN 0x01 /* opened */
-
- int sc_refcnt;
- u_char sc_dying;
-};
-
-d_open_t uscanneropen;
-d_close_t uscannerclose;
-d_read_t uscannerread;
-d_write_t uscannerwrite;
-d_poll_t uscannerpoll;
-
-
-static struct cdevsw uscanner_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = uscanneropen,
- .d_close = uscannerclose,
- .d_read = uscannerread,
- .d_write = uscannerwrite,
- .d_poll = uscannerpoll,
- .d_name = "uscanner",
-};
-
-static int uscanner_do_read(struct uscanner_softc *, struct uio *, int);
-static int uscanner_do_write(struct uscanner_softc *, struct uio *, int);
-static void uscanner_do_close(struct uscanner_softc *);
-
-#define USCANNERUNIT(n) (dev2unit(n))
-
-static device_probe_t uscanner_match;
-static device_attach_t uscanner_attach;
-static device_detach_t uscanner_detach;
-
-static device_method_t uscanner_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uscanner_match),
- DEVMETHOD(device_attach, uscanner_attach),
- DEVMETHOD(device_detach, uscanner_detach),
-
- { 0, 0 }
-};
-
-static driver_t uscanner_driver = {
- "uscanner",
- uscanner_methods,
- sizeof(struct uscanner_softc)
-};
-
-static devclass_t uscanner_devclass;
-
-static int
-uscanner_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
-
- if (uaa->iface == NULL)
- return UMATCH_NONE; /* do not grab the entire device */
-
- if (uscanner_lookup(uaa->vendor, uaa->product) == NULL)
- return UMATCH_NONE; /* not in the list of known devices */
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL)
- return UMATCH_NONE;
-
- /*
- * There isn't a specific UICLASS for scanners, many vendors use
- * UICLASS_VENDOR, so detecting the right interface is not so easy.
- * But certainly we can exclude PRINTER and MASS - which some
- * multifunction devices implement.
- */
- if (id->bInterfaceClass == UICLASS_PRINTER ||
- id->bInterfaceClass == UICLASS_MASS)
- return UMATCH_NONE;
-
- return UMATCH_VENDOR_PRODUCT; /* ok we found it */
-}
-
-static int
-uscanner_attach(device_t self)
-{
- struct uscanner_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id = 0;
- usb_endpoint_descriptor_t *ed, *ed_bulkin = NULL, *ed_bulkout = NULL;
- int i;
- usbd_status err;
- int ifnum;
-
- sc->sc_dev = self;
- sc->sc_dev_flags = uscanner_lookup(uaa->vendor, uaa->product)->flags;
- sc->sc_udev = uaa->device;
-
- id = usbd_get_interface_descriptor(uaa->iface);
- ifnum = id->bInterfaceNumber;
-#if 0
- /*
- * This was in the original driver, but we cannot change the
- * configuration of the whole device while attaching only to
- * one of its interfaces. This can kill other already-attached
- * driver, and/or possibly prevent this driver from attaching
- * if an error occurs in set_config_no.
- * If a device need setting the configuration, this must be done
- * before attaching drivers to the various interfaces.
- */
- err = usbd_set_config_no(uaa->device, 1, 1); /* XXX */
- if (err) {
- printf("%s: setting config no failed\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-#endif
- err = usbd_device2interface_handle(sc->sc_udev, ifnum, &sc->sc_iface);
- if (!err && sc->sc_iface)
- id = usbd_get_interface_descriptor(sc->sc_iface);
- if (err || id == 0) {
- printf("%s: could not get interface descriptor, err=%d,id=%p\n",
- device_get_nameunit(sc->sc_dev), err, id);
- return ENXIO;
- }
-
- /* Find the two first bulk endpoints */
- for (i = 0 ; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
- if (ed == 0) {
- printf("%s: could not read endpoint descriptor\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ed_bulkin = ed;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ed_bulkout = ed;
- }
-
- if (ed_bulkin && ed_bulkout) /* found all we need */
- break;
- }
-
- /* Verify that we goething sensible */
- if (ed_bulkin == NULL || ed_bulkout == NULL) {
- printf("%s: bulk-in and/or bulk-out endpoint not found\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-
- sc->sc_bulkin = ed_bulkin->bEndpointAddress;
- sc->sc_bulkout = ed_bulkout->bEndpointAddress;
-
- /* the main device, ctrl endpoint */
- sc->dev = make_dev(&uscanner_cdevsw, device_get_unit(sc->sc_dev),
- UID_ROOT, GID_OPERATOR, 0644, "%s", device_get_nameunit(sc->sc_dev));
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,sc->sc_dev);
-
- return 0;
-}
-
-int
-uscanneropen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct uscanner_softc *sc;
- int unit = USCANNERUNIT(dev);
- usbd_status err;
-
- sc = devclass_get_softc(uscanner_devclass, unit);
- if (sc == NULL)
- return (ENXIO);
-
- DPRINTFN(5, ("uscanneropen: flag=%d, mode=%d, unit=%d\n",
- flag, mode, unit));
-
- if (sc->sc_dying)
- return (ENXIO);
-
- if (sc->sc_state & USCANNER_OPEN)
- return (EBUSY);
-
- sc->sc_state |= USCANNER_OPEN;
-
- sc->sc_bulkin_buffer = malloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK);
- sc->sc_bulkout_buffer = malloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK);
- /* No need to check buffers for NULL since we have WAITOK */
-
- sc->sc_bulkin_bufferlen = USCANNER_BUFFERSIZE;
- sc->sc_bulkout_bufferlen = USCANNER_BUFFERSIZE;
-
- /* We have decided on which endpoints to use, now open the pipes */
- if (sc->sc_bulkin_pipe == NULL) {
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
- if (err) {
- printf("%s: cannot open bulk-in pipe (addr %d)\n",
- device_get_nameunit(sc->sc_dev), sc->sc_bulkin);
- uscanner_do_close(sc);
- return (EIO);
- }
- }
- if (sc->sc_bulkout_pipe == NULL) {
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
- if (err) {
- printf("%s: cannot open bulk-out pipe (addr %d)\n",
- device_get_nameunit(sc->sc_dev), sc->sc_bulkout);
- uscanner_do_close(sc);
- return (EIO);
- }
- }
-
- sc->sc_bulkin_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_bulkin_xfer == NULL) {
- uscanner_do_close(sc);
- return (ENOMEM);
- }
- sc->sc_bulkout_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_bulkout_xfer == NULL) {
- uscanner_do_close(sc);
- return (ENOMEM);
- }
-
- return (0); /* success */
-}
-
-int
-uscannerclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct uscanner_softc *sc;
-
- sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
- DPRINTFN(5, ("uscannerclose: flag=%d, mode=%d, unit=%d\n",
- flag, mode, USCANNERUNIT(dev)));
-
-#ifdef DIAGNOSTIC
- if (!(sc->sc_state & USCANNER_OPEN)) {
- printf("uscannerclose: not open\n");
- return (EINVAL);
- }
-#endif
-
- uscanner_do_close(sc);
-
- return (0);
-}
-
-void
-uscanner_do_close(struct uscanner_softc *sc)
-{
- if (sc->sc_bulkin_xfer) {
- usbd_free_xfer(sc->sc_bulkin_xfer);
- sc->sc_bulkin_xfer = NULL;
- }
- if (sc->sc_bulkout_xfer) {
- usbd_free_xfer(sc->sc_bulkout_xfer);
- sc->sc_bulkout_xfer = NULL;
- }
-
- if (!(sc->sc_dev_flags & USC_KEEP_OPEN)) {
- if (sc->sc_bulkin_pipe != NULL) {
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- usbd_close_pipe(sc->sc_bulkin_pipe);
- sc->sc_bulkin_pipe = NULL;
- }
- if (sc->sc_bulkout_pipe != NULL) {
- usbd_abort_pipe(sc->sc_bulkout_pipe);
- usbd_close_pipe(sc->sc_bulkout_pipe);
- sc->sc_bulkout_pipe = NULL;
- }
- }
-
- if (sc->sc_bulkin_buffer) {
- free(sc->sc_bulkin_buffer, M_USBDEV);
- sc->sc_bulkin_buffer = NULL;
- }
- if (sc->sc_bulkout_buffer) {
- free(sc->sc_bulkout_buffer, M_USBDEV);
- sc->sc_bulkout_buffer = NULL;
- }
-
- sc->sc_state &= ~USCANNER_OPEN;
-}
-
-static int
-uscanner_do_read(struct uscanner_softc *sc, struct uio *uio, int flag)
-{
- u_int32_t n, tn;
- usbd_status err;
- int error = 0;
-
- DPRINTFN(5, ("%s: uscannerread\n", device_get_nameunit(sc->sc_dev)));
-
- if (sc->sc_dying)
- return (EIO);
-
- while ((n = min(sc->sc_bulkin_bufferlen, uio->uio_resid)) != 0) {
- DPRINTFN(1, ("uscannerread: start transfer %d bytes\n",n));
- tn = n;
-
- err = usbd_bulk_transfer(
- sc->sc_bulkin_xfer, sc->sc_bulkin_pipe,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
- sc->sc_bulkin_buffer, &tn,
- "uscnrb");
- if (err) {
- if (err == USBD_INTERRUPTED)
- error = EINTR;
- else if (err == USBD_TIMEOUT)
- error = ETIMEDOUT;
- else
- error = EIO;
- break;
- }
- DPRINTFN(1, ("uscannerread: got %d bytes\n", tn));
- error = uiomove(sc->sc_bulkin_buffer, tn, uio);
- if (error || tn < n)
- break;
- }
-
- return (error);
-}
-
-int
-uscannerread(struct cdev *dev, struct uio *uio, int flag)
-{
- struct uscanner_softc *sc;
- int error;
-
- sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
- sc->sc_refcnt++;
- error = uscanner_do_read(sc, uio, flag);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
-
- return (error);
-}
-
-static int
-uscanner_do_write(struct uscanner_softc *sc, struct uio *uio, int flag)
-{
- u_int32_t n;
- int error = 0;
- usbd_status err;
-
- DPRINTFN(5, ("%s: uscanner_do_write\n", device_get_nameunit(sc->sc_dev)));
-
- if (sc->sc_dying)
- return (EIO);
-
- while ((n = min(sc->sc_bulkout_bufferlen, uio->uio_resid)) != 0) {
- error = uiomove(sc->sc_bulkout_buffer, n, uio);
- if (error)
- break;
- DPRINTFN(1, ("uscanner_do_write: transfer %d bytes\n", n));
- err = usbd_bulk_transfer(
- sc->sc_bulkout_xfer, sc->sc_bulkout_pipe,
- 0, USBD_NO_TIMEOUT,
- sc->sc_bulkout_buffer, &n,
- "uscnwb");
- if (err) {
- if (err == USBD_INTERRUPTED)
- error = EINTR;
- else
- error = EIO;
- break;
- }
- }
-
- return (error);
-}
-
-int
-uscannerwrite(struct cdev *dev, struct uio *uio, int flag)
-{
- struct uscanner_softc *sc;
- int error;
-
- sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
- sc->sc_refcnt++;
- error = uscanner_do_write(sc, uio, flag);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-static int
-uscanner_detach(device_t self)
-{
- struct uscanner_softc *sc = device_get_softc(self);
- int s;
-
- DPRINTF(("uscanner_detach: sc=%p\n", sc));
-
- sc->sc_dying = 1;
- sc->sc_dev_flags = 0; /* make close really close device */
-
- /* Abort all pipes. Causes processes waiting for transfer to wake. */
- if (sc->sc_bulkin_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- if (sc->sc_bulkout_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkout_pipe);
-
- s = splusb();
- if (--sc->sc_refcnt >= 0) {
- /* Wait for processes to go away. */
- usb_detach_wait(sc->sc_dev);
- }
- splx(s);
-
- /* destroy the device for the control endpoint */
- destroy_dev(sc->dev);
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
-
- return (0);
-}
-
-int
-uscannerpoll(struct cdev *dev, int events, struct thread *p)
-{
- struct uscanner_softc *sc;
- int revents = 0;
-
- sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
- if (sc->sc_dying)
- return (EIO);
-
- /*
- * We have no easy way of determining if a read will
- * yield any data or a write will happen.
- * Pretend they will.
- */
- revents |= events &
- (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
-
- return (revents);
-}
-
-MODULE_DEPEND(uscanner, usb, 1, 1, 1);
-DRIVER_MODULE(uscanner, uhub, uscanner_driver, uscanner_devclass, usbd_driver_load, 0);
diff --git a/sys/legacy/dev/usb/uslcom.c b/sys/legacy/dev/usb/uslcom.c
deleted file mode 100644
index edb13c5..0000000
--- a/sys/legacy/dev/usb/uslcom.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/* $FreeBSD$ */
-/* $OpenBSD: uslcom.c,v 1.17 2007/11/24 10:52:12 jsg Exp $ */
-
-/*
- * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/conf.h>
-#include <sys/bus.h>
-#include <sys/tty.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include "usbdevs.h"
-#include <dev/usb/ucomvar.h>
-
-#ifdef USLCOM_DEBUG
-#define DPRINTFN(n, x) do { if (uslcomdebug > (n)) printf x; } while (0)
-int uslcomdebug = 1;
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define USLCOMBUFSZ 256
-#define USLCOM_CONFIG_NO 0
-#define USLCOM_IFACE_NO 0
-
-#define USLCOM_SET_DATA_BITS(x) (x << 8)
-
-#define USLCOM_WRITE 0x41
-#define USLCOM_READ 0xc1
-
-#define USLCOM_UART 0x00
-#define USLCOM_BAUD_RATE 0x01
-#define USLCOM_DATA 0x03
-#define USLCOM_BREAK 0x05
-#define USLCOM_CTRL 0x07
-
-#define USLCOM_UART_DISABLE 0x00
-#define USLCOM_UART_ENABLE 0x01
-
-#define USLCOM_CTRL_DTR_ON 0x0001
-#define USLCOM_CTRL_DTR_SET 0x0100
-#define USLCOM_CTRL_RTS_ON 0x0002
-#define USLCOM_CTRL_RTS_SET 0x0200
-#define USLCOM_CTRL_CTS 0x0010
-#define USLCOM_CTRL_DSR 0x0020
-#define USLCOM_CTRL_DCD 0x0080
-
-
-#define USLCOM_BAUD_REF 0x384000
-
-#define USLCOM_STOP_BITS_1 0x00
-#define USLCOM_STOP_BITS_2 0x02
-
-#define USLCOM_PARITY_NONE 0x00
-#define USLCOM_PARITY_ODD 0x10
-#define USLCOM_PARITY_EVEN 0x20
-
-#define USLCOM_BREAK_OFF 0x00
-#define USLCOM_BREAK_ON 0x01
-
-
-struct uslcom_softc {
- struct ucom_softc sc_ucom;
- device_t sc_dev;
- usbd_device_handle sc_udev;
-
- u_char sc_msr;
- u_char sc_lsr;
-
- u_char sc_dying;
-};
-
-void uslcom_get_status(void *, int portno, u_char *lsr, u_char *msr);
-void uslcom_set(void *, int, int, int);
-int uslcom_param(void *, int, struct termios *);
-int uslcom_open(void *sc, int portno);
-void uslcom_close(void *, int);
-void uslcom_break(void *sc, int portno, int onoff);
-
-struct ucom_callback uslcom_callback = {
- uslcom_get_status,
- uslcom_set,
- uslcom_param,
- NULL,
- uslcom_open,
- uslcom_close,
- NULL,
- NULL,
-};
-
-static const struct usb_devno uslcom_devs[] = {
- { USB_VENDOR_BALTECH, USB_PRODUCT_BALTECH_CARDREADER },
- { USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD },
- { USB_VENDOR_JABLOTRON, USB_PRODUCT_JABLOTRON_PC60B },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ARGUSISP },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CRUMB128 },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_DEGREE },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_BURNSIDE },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_HELICOM },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_HARP },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_JTAG },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_LIN },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_POLOLU },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2102 },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP210X_2 },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_SUUNTO },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_TRAQMATE },
- { USB_VENDOR_SILABS2, USB_PRODUCT_SILABS2_DCU11CLONE },
- { USB_VENDOR_USI, USB_PRODUCT_USI_MC60 }
-};
-
-static device_probe_t uslcom_match;
-static device_attach_t uslcom_attach;
-static device_detach_t uslcom_detach;
-
-static device_method_t uslcom_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uslcom_match),
- DEVMETHOD(device_attach, uslcom_attach),
- DEVMETHOD(device_detach, uslcom_detach),
- { 0, 0 }
-};
-
-static driver_t uslcom_driver = {
- "ucom",
- uslcom_methods,
- sizeof (struct uslcom_softc)
-};
-
-DRIVER_MODULE(uslcom, uhub, uslcom_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uslcom, usb, 1, 1, 1);
-MODULE_DEPEND(uslcom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(uslcom, 1);
-
-static int
-uslcom_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return UMATCH_NONE;
-
- return (usb_lookup(uslcom_devs, uaa->vendor, uaa->product) != NULL) ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
-}
-
-static int
-uslcom_attach(device_t self)
-{
- struct uslcom_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- struct ucom_softc* ucom;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_status error;
- int i;
-
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- sc->sc_dev = self;
- sc->sc_udev = uaa->device;
-
- if (usbd_set_config_index(sc->sc_udev, USLCOM_CONFIG_NO, 1) != 0) {
- device_printf(self, "could not set configuration no\n");
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- /* get the first interface handle */
- error = usbd_device2interface_handle(sc->sc_udev, USLCOM_IFACE_NO,
- &ucom->sc_iface);
- if (error != 0) {
- device_printf(self, "could not get interface handle\n");
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
-
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- device_printf(self, "no endpoint descriptor found for %d\n",
- i);
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
-
- if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) {
- device_printf(self, "missing endpoint\n");
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = USLCOMBUFSZ;
- ucom->sc_obufsize = USLCOMBUFSZ;
- ucom->sc_ibufsizepad = USLCOMBUFSZ;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &uslcom_callback;
-
- DPRINTF(("uslcom: in = 0x%x, out = 0x%x\n",
- ucom->sc_bulkin_no, ucom->sc_bulkout_no));
-
- ucom_attach(&sc->sc_ucom);
- return 0;
-}
-
-static int
-uslcom_detach(device_t self)
-{
- struct uslcom_softc *sc = device_get_softc(self);
-
- sc->sc_dying = 1;
- return ucom_detach(&sc->sc_ucom);
-}
-
-int
-uslcom_open(void *vsc, int portno)
-{
- struct uslcom_softc *sc = vsc;
- usb_device_request_t req;
- usbd_status err;
-
- if (sc->sc_dying)
- return (EIO);
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_UART;
- USETW(req.wValue, USLCOM_UART_ENABLE);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(sc->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- return (0);
-}
-
-void
-uslcom_close(void *vsc, int portno)
-{
- struct uslcom_softc *sc = vsc;
- usb_device_request_t req;
-
- if (sc->sc_dying)
- return;
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_UART;
- USETW(req.wValue, USLCOM_UART_DISABLE);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- usbd_do_request(sc->sc_udev, &req, NULL);
-}
-
-void
-uslcom_set(void *vsc, int portno, int reg, int onoff)
-{
- struct uslcom_softc *sc = vsc;
- usb_device_request_t req;
- int ctl;
-
- switch (reg) {
- case UCOM_SET_DTR:
- ctl = onoff ? USLCOM_CTRL_DTR_ON : 0;
- ctl |= USLCOM_CTRL_DTR_SET;
- break;
- case UCOM_SET_RTS:
- ctl = onoff ? USLCOM_CTRL_RTS_ON : 0;
- ctl |= USLCOM_CTRL_RTS_SET;
- break;
- case UCOM_SET_BREAK:
- uslcom_break(sc, portno, onoff);
- return;
- default:
- return;
- }
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_CTRL;
- USETW(req.wValue, ctl);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- usbd_do_request(sc->sc_udev, &req, NULL);
-}
-
-int
-uslcom_param(void *vsc, int portno, struct termios *t)
-{
- struct uslcom_softc *sc = (struct uslcom_softc *)vsc;
- usbd_status err;
- usb_device_request_t req;
- int data;
-
- if (t->c_ospeed <= 0 || t->c_ospeed > 921600)
- return (EINVAL);
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_BAUD_RATE;
- USETW(req.wValue, USLCOM_BAUD_REF / t->c_ospeed);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(sc->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- if (ISSET(t->c_cflag, CSTOPB))
- data = USLCOM_STOP_BITS_2;
- else
- data = USLCOM_STOP_BITS_1;
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- data |= USLCOM_PARITY_ODD;
- else
- data |= USLCOM_PARITY_EVEN;
- } else
- data |= USLCOM_PARITY_NONE;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- data |= USLCOM_SET_DATA_BITS(5);
- break;
- case CS6:
- data |= USLCOM_SET_DATA_BITS(6);
- break;
- case CS7:
- data |= USLCOM_SET_DATA_BITS(7);
- break;
- case CS8:
- data |= USLCOM_SET_DATA_BITS(8);
- break;
- }
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_DATA;
- USETW(req.wValue, data);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(sc->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
-#if 0
- /* XXX flow control */
- if (ISSET(t->c_cflag, CRTSCTS))
- /* rts/cts flow ctl */
- } else if (ISSET(t->c_iflag, IXON|IXOFF)) {
- /* xon/xoff flow ctl */
- } else {
- /* disable flow ctl */
- }
-#endif
-
- return (0);
-}
-
-void
-uslcom_get_status(void *vsc, int portno, u_char *lsr, u_char *msr)
-{
- struct uslcom_softc *sc = vsc;
-
- if (msr != NULL)
- *msr = sc->sc_msr;
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
-}
-
-void
-uslcom_break(void *vsc, int portno, int onoff)
-{
- struct uslcom_softc *sc = vsc;
- usb_device_request_t req;
- int brk = onoff ? USLCOM_BREAK_ON : USLCOM_BREAK_OFF;
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_BREAK;
- USETW(req.wValue, brk);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- usbd_do_request(sc->sc_udev, &req, NULL);
-}
diff --git a/sys/legacy/dev/usb/uvisor.c b/sys/legacy/dev/usb/uvisor.c
deleted file mode 100644
index 6c4470e..0000000
--- a/sys/legacy/dev/usb/uvisor.c
+++ /dev/null
@@ -1,639 +0,0 @@
-/* $NetBSD: uvisor.c,v 1.9 2001/01/23 14:04:14 augustss Exp $ */
-/* $FreeBSD$ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: uvisor.c,v 1.12 2001/11/13 06:24:57 lukem Exp $
- * $NetBSD: uvisor.c,v 1.13 2002/02/11 15:11:49 augustss Exp $
- * $NetBSD: uvisor.c,v 1.14 2002/02/27 23:00:03 augustss Exp $
- * $NetBSD: uvisor.c,v 1.15 2002/06/16 15:01:31 augustss Exp $
- * $NetBSD: uvisor.c,v 1.16 2002/07/11 21:14:36 augustss Exp $
- * $NetBSD: uvisor.c,v 1.17 2002/08/13 11:38:15 augustss Exp $
- * $NetBSD: uvisor.c,v 1.18 2003/02/05 00:50:14 augustss Exp $
- * $NetBSD: uvisor.c,v 1.19 2003/02/07 18:12:37 augustss Exp $
- * $NetBSD: uvisor.c,v 1.20 2003/04/11 01:30:10 simonb Exp $
- */
-
-
-/*-
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Handspring Visor (Palmpilot compatible PDA) driver
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/ucomvar.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (uvisordebug) printf x
-#define DPRINTFN(n,x) if (uvisordebug>(n)) printf x
-int uvisordebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uvisor, CTLFLAG_RW, 0, "USB uvisor");
-SYSCTL_INT(_hw_usb_uvisor, OID_AUTO, debug, CTLFLAG_RW,
- &uvisordebug, 0, "uvisor debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UVISOR_CONFIG_INDEX 0
-#define UVISOR_IFACE_INDEX 0
-#define UVISOR_MODVER 1
-
-/* From the Linux driver */
-/*
- * UVISOR_REQUEST_BYTES_AVAILABLE asks the visor for the number of bytes that
- * are available to be transfered to the host for the specified endpoint.
- * Currently this is not used, and always returns 0x0001
- */
-#define UVISOR_REQUEST_BYTES_AVAILABLE 0x01
-
-/*
- * UVISOR_CLOSE_NOTIFICATION is set to the device to notify it that the host
- * is now closing the pipe. An empty packet is sent in response.
- */
-#define UVISOR_CLOSE_NOTIFICATION 0x02
-
-/*
- * UVISOR_GET_CONNECTION_INFORMATION is sent by the host during enumeration to
- * get the endpoints used by the connection.
- */
-#define UVISOR_GET_CONNECTION_INFORMATION 0x03
-
-
-/*
- * UVISOR_GET_CONNECTION_INFORMATION returns data in the following format
- */
-#define UVISOR_MAX_CONN 8
-struct uvisor_connection_info {
- uWord num_ports;
- struct {
- uByte port_function_id;
- uByte port;
- } connections[UVISOR_MAX_CONN];
-};
-#define UVISOR_CONNECTION_INFO_SIZE 18
-
-/* struct uvisor_connection_info.connection[x].port defines: */
-#define UVISOR_ENDPOINT_1 0x01
-#define UVISOR_ENDPOINT_2 0x02
-
-/* struct uvisor_connection_info.connection[x].port_function_id defines: */
-#define UVISOR_FUNCTION_GENERIC 0x00
-#define UVISOR_FUNCTION_DEBUGGER 0x01
-#define UVISOR_FUNCTION_HOTSYNC 0x02
-#define UVISOR_FUNCTION_CONSOLE 0x03
-#define UVISOR_FUNCTION_REMOTE_FILE_SYS 0x04
-
-/*
- * Unknown PalmOS stuff.
- */
-#define UVISOR_GET_PALM_INFORMATION 0x04
-#define UVISOR_GET_PALM_INFORMATION_LEN 0x44
-
-struct uvisor_palm_connection_info {
- uByte num_ports;
- uByte endpoint_numbers_different;
- uWord reserved1;
- struct {
- uDWord port_function_id;
- uByte port;
- uByte end_point_info;
- uWord reserved;
- } connections[UVISOR_MAX_CONN];
-};
-
-
-/*
- * Crank down UVISORBUFSIZE from 1024 to 64 to avoid a problem where
- * the Palm device and the USB host controller deadlock. The USB host
- * controller is expecting an early-end-of-transmission packet with 0
- * data, and the Palm doesn't send one because it's already
- * communicated the amount of data it's going to send in a header
- * (which ucom/uvisor are oblivious to). This is the problem that has
- * been known on the pilot-link lists as the "[Free]BSD USB problem",
- * but not understood.
- */
-#define UVISORIBUFSIZE 64
-#define UVISOROBUFSIZE 1024
-
-struct uvisor_softc {
- struct ucom_softc sc_ucom;
- u_int16_t sc_flags;
-};
-
-static usbd_status uvisor_init(struct uvisor_softc *);
-
-/*static usbd_status clie_3_5_init(struct uvisor_softc *);*/
-
-static void uvisor_close(void *, int);
-
-struct ucom_callback uvisor_callback = {
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- uvisor_close,
- NULL,
- NULL,
-};
-
-static device_probe_t uvisor_match;
-static device_attach_t uvisor_attach;
-static device_detach_t uvisor_detach;
-static device_method_t uvisor_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uvisor_match),
- DEVMETHOD(device_attach, uvisor_attach),
- DEVMETHOD(device_detach, uvisor_detach),
- { 0, 0 }
-};
-
-
-static driver_t uvisor_driver = {
- "ucom",
- uvisor_methods,
- sizeof (struct uvisor_softc)
-};
-
-DRIVER_MODULE(uvisor, uhub, uvisor_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uvisor, usb, 1, 1, 1);
-MODULE_DEPEND(uvisor, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(uvisor, UVISOR_MODVER);
-
-struct uvisor_type {
- struct usb_devno uv_dev;
- u_int16_t uv_flags;
-#define PALM4 0x0001
-#define VISOR 0x0002
-#define PALM35 0x0004
-};
-static const struct uvisor_type uvisor_devs[] = {
- {{ USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000 }, PALM4 },
- {{ USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_IQUE_3600 }, PALM4 },
- {{ USB_VENDOR_FOSSIL, USB_PRODUCT_FOSSIL_WRISTPDA }, PALM4 },
- {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR }, VISOR },
- {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO }, PALM4 },
- {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO600 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M500 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M505 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M515 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_I705 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M125 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M130 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE31 }, PALM4 },
- {{ USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_I500 }, PALM4 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40 }, 0 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41 }, PALM4 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360 }, PALM4 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60 }, PALM4 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_35 }, PALM35 },
-/* {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_25 }, PALM4 },*/
-/* {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TH55 }, PALM4 }, */ /* See PR 80935 */
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TJ37 }, PALM4 },
- {{ USB_VENDOR_TAPWAVE, USB_PRODUCT_TAPWAVE_ZODIAC }, PALM4 },
-};
-#define uvisor_lookup(v, p) ((const struct uvisor_type *)usb_lookup(uvisor_devs, v, p))
-
-
-static int
-uvisor_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- DPRINTFN(20,("uvisor: vendor=0x%x, product=0x%x\n",
- uaa->vendor, uaa->product));
-
- return (uvisor_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-static int
-uvisor_attach(device_t self)
-{
- struct uvisor_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_interface_handle iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
- usbd_status err;
- struct ucom_softc *ucom;
-
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- DPRINTFN(10,("\nuvisor_attach: sc=%p\n", sc));
-
- /* Move the device into the configured state. */
- err = usbd_set_config_index(dev, UVISOR_CONFIG_INDEX, 1);
- if (err) {
- device_printf(self, "failed to set configuration, err=%s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- err = usbd_device2interface_handle(dev, UVISOR_IFACE_INDEX, &iface);
- if (err) {
- device_printf(self, "failed to get interface, err=%s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags;
-
- id = usbd_get_interface_descriptor(iface);
-
- ucom->sc_udev = dev;
- ucom->sc_iface = iface;
-
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- int addr, dir, attr;
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- device_printf(self,
- "could not read endpoint descriptor: %s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- addr = ed->bEndpointAddress;
- dir = UE_GET_DIR(ed->bEndpointAddress);
- attr = ed->bmAttributes & UE_XFERTYPE;
- if (dir == UE_DIR_IN && attr == UE_BULK)
- ucom->sc_bulkin_no = addr;
- else if (dir == UE_DIR_OUT && attr == UE_BULK)
- ucom->sc_bulkout_no = addr;
- else {
- device_printf(self, "unexpected endpoint\n");
- goto bad;
- }
- }
- if (ucom->sc_bulkin_no == -1) {
- device_printf(self, "Could not find data bulk in\n");
- goto bad;
- }
- if (ucom->sc_bulkout_no == -1) {
- device_printf(self, "Could not find data bulk out\n");
- goto bad;
- }
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = UVISORIBUFSIZE;
- ucom->sc_obufsize = UVISOROBUFSIZE;
- ucom->sc_ibufsizepad = UVISORIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &uvisor_callback;
-
-#if 0
- if (uaa->vendor == USB_VENDOR_SONY &&
- uaa->product == USB_PRODUCT_SONY_CLIE_35)
- err = clie_3_5_init(sc);
- else
-#endif
- err = uvisor_init(sc);
-
- if (err) {
- device_printf(ucom->sc_dev, "init failed, %s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, ucom->sc_udev,
- ucom->sc_dev);
-
- DPRINTF(("uvisor: in=0x%x out=0x%x\n", ucom->sc_bulkin_no, ucom->sc_bulkout_no));
- ucom_attach(&sc->sc_ucom);
-
- return 0;
-
-bad:
- DPRINTF(("uvisor_attach: ATTACH ERROR\n"));
- ucom->sc_dying = 1;
- return ENXIO;
-}
-
-#if 0
-
-int
-uvisor_activate(device_t self, enum devact act)
-{
- struct uvisor_softc *sc = (struct uvisor_softc *)self;
- int rv = 0;
-
- switch (act) {
- case DVACT_ACTIVATE:
- return (EOPNOTSUPP);
- break;
-
- case DVACT_DEACTIVATE:
- if (sc->sc_subdev != NULL)
- rv = config_deactivate(sc->sc_subdev);
- sc->sc_dying = 1;
- break;
- }
- return (rv);
-}
-
-#endif
-
-static int
-uvisor_detach(device_t self)
-{
- struct uvisor_softc *sc = device_get_softc(self);
- int rv = 0;
-
- DPRINTF(("uvisor_detach: sc=%p\n", sc));
- sc->sc_ucom.sc_dying = 1;
- rv = ucom_detach(&sc->sc_ucom);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_ucom.sc_udev,
- sc->sc_ucom.sc_dev);
-
- return (rv);
-}
-
-usbd_status
-uvisor_init(struct uvisor_softc *sc)
-{
- usbd_status err;
- usb_device_request_t req;
- struct uvisor_connection_info coninfo;
- struct uvisor_palm_connection_info pconinfo;
- int actlen;
- uWord avail;
- char buffer[256];
-
- if (sc->sc_flags & VISOR) {
- DPRINTF(("uvisor_init: getting connection info\n"));
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_GET_CONNECTION_INFORMATION;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
- err = usbd_do_request_flags(sc->sc_ucom.sc_udev, &req, &coninfo,
- USBD_SHORT_XFER_OK, &actlen,
- USBD_DEFAULT_TIMEOUT);
- if (err)
- return (err);
- }
-#ifdef USB_DEBUG
- {
- int i, np;
- char *string;
-
- np = UGETW(coninfo.num_ports);
- device_printf(sc->sc_ucom.sc_dev, "Number of ports: %d\n", np);
- for (i = 0; i < np; ++i) {
- switch (coninfo.connections[i].port_function_id) {
- case UVISOR_FUNCTION_GENERIC:
- string = "Generic";
- break;
- case UVISOR_FUNCTION_DEBUGGER:
- string = "Debugger";
- break;
- case UVISOR_FUNCTION_HOTSYNC:
- string = "HotSync";
- break;
- case UVISOR_FUNCTION_REMOTE_FILE_SYS:
- string = "Remote File System";
- break;
- default:
- string = "unknown";
- break;
- }
- device_printf(sc->sc_ucom.sc_dev,
- "port %d, is for %s\n",
- coninfo.connections[i].port, string);
- }
- }
-#endif
-
- if (sc->sc_flags & PALM4) {
- int port;
- /* Palm OS 4.0 Hack */
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_GET_PALM_INFORMATION;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, UVISOR_GET_PALM_INFORMATION_LEN);
- err = usbd_do_request_flags(sc->sc_ucom.sc_udev, &req, &pconinfo,
- USBD_SHORT_XFER_OK, &actlen,
- USBD_DEFAULT_TIMEOUT);
- if (err)
- return (err);
-
- if (pconinfo.endpoint_numbers_different) {
- port = pconinfo.connections[0].end_point_info;
- sc->sc_ucom.sc_bulkin_no = (port >> 4) | UE_DIR_IN;
- sc->sc_ucom.sc_bulkout_no = (port & 0xf) | UE_DIR_OUT;
- } else {
- port = pconinfo.connections[0].port;
- sc->sc_ucom.sc_bulkin_no = port | UE_DIR_IN;
- sc->sc_ucom.sc_bulkout_no = port | UE_DIR_OUT;
- }
-#if 0
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_GET_PALM_INFORMATION;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, UVISOR_GET_PALM_INFORMATION_LEN);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
- if (err)
- return (err);
-#endif
- }
-
- if (sc->sc_flags & PALM35) {
- /* get the config number */
- DPRINTF(("clie_3_5_init: getting config info\n"));
- req.bmRequestType = UT_READ;
- req.bRequest = UR_GET_CONFIG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 1);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
- if (err)
- return (err);
-
- /* get the interface number */
- DPRINTF(("clie_3_5_init: get the interface number\n"));
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_INTERFACE;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 1);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
- if (err)
- return (err);
- }
-
- DPRINTF(("uvisor_init: getting available bytes\n"));
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_REQUEST_BYTES_AVAILABLE;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 5);
- USETW(req.wLength, sizeof avail);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, &avail);
- if (err)
- return (err);
- DPRINTF(("uvisor_init: avail=%d\n", UGETW(avail)));
-
- DPRINTF(("uvisor_init: done\n"));
- return (err);
-}
-
-#if 0
-usbd_status
-clie_3_5_init(struct uvisor_softc *sc)
-{
- usbd_status err;
- usb_device_request_t req;
- char buffer[256];
-
- /*
- * Note that PEG-300 series devices expect the following two calls.
- */
-
- /* get the config number */
- DPRINTF(("clie_3_5_init: getting config info\n"));
- req.bmRequestType = UT_READ;
- req.bRequest = UR_GET_CONFIG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 1);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
- if (err)
- return (err);
-
- /* get the interface number */
- DPRINTF(("clie_3_5_init: get the interface number\n"));
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_INTERFACE;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 1);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
- if (err)
- return (err);
-
-#ifdef USB_DEBUG
- {
- struct uvisor_connection_info coninfo;
- int i, np;
- char *string;
-
- np = UGETW(coninfo.num_ports);
- DPRINTF(("%s: Number of ports: %d\n", device_get_nameunit(sc->sc_ucom.sc_dev), np));
- for (i = 0; i < np; ++i) {
- switch (coninfo.connections[i].port_function_id) {
- case UVISOR_FUNCTION_GENERIC:
- string = "Generic";
- break;
- case UVISOR_FUNCTION_DEBUGGER:
- string = "Debugger";
- break;
- case UVISOR_FUNCTION_HOTSYNC:
- string = "HotSync";
- break;
- case UVISOR_FUNCTION_REMOTE_FILE_SYS:
- string = "Remote File System";
- break;
- default:
- string = "unknown";
- break;
- }
- DPRINTF(("%s: port %d, is for %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), coninfo.connections[i].port,
- string));
- }
- }
-#endif
-
- DPRINTF(("clie_3_5_init: done\n"));
- return (err);
-}
-#endif
-
-void
-uvisor_close(void *addr, int portno)
-{
- struct uvisor_softc *sc = addr;
- usb_device_request_t req;
- struct uvisor_connection_info coninfo; /* XXX ? */
- int actlen;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT; /* XXX read? */
- req.bRequest = UVISOR_CLOSE_NOTIFICATION;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
- (void)usbd_do_request_flags(sc->sc_ucom.sc_udev, &req, &coninfo,
- USBD_SHORT_XFER_OK, &actlen,
- USBD_DEFAULT_TIMEOUT);
-}
diff --git a/sys/legacy/dev/usb/uvscom.c b/sys/legacy/dev/usb/uvscom.c
deleted file mode 100644
index ac311f7..0000000
--- a/sys/legacy/dev/usb/uvscom.c
+++ /dev/null
@@ -1,906 +0,0 @@
-/* $NetBSD: usb/uvscom.c,v 1.1 2002/03/19 15:08:42 augustss Exp $ */
-/*-
- * Copyright (c) 2001-2003, 2005 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * uvscom: SUNTAC Slipper U VS-10U driver.
- * Slipper U is a PC Card to USB converter for data communication card
- * adapter. It supports DDI Pocket's Air H" C@rd, C@rd H" 64, NTT's P-in,
- * P-in m@ater and various data communication card adapters.
- */
-
-#include "opt_uvscom.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/taskqueue.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-SYSCTL_NODE(_hw_usb, OID_AUTO, uvscom, CTLFLAG_RW, 0, "USB uvscom");
-#ifdef USB_DEBUG
-static int uvscomdebug = 0;
-SYSCTL_INT(_hw_usb_uvscom, OID_AUTO, debug, CTLFLAG_RW,
- &uvscomdebug, 0, "uvscom debug level");
-
-#define DPRINTFN(n, x) do { \
- if (uvscomdebug > (n)) \
- printf x; \
- } while (0)
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define UVSCOM_MODVER 1 /* module version */
-
-#define UVSCOM_CONFIG_INDEX 0
-#define UVSCOM_IFACE_INDEX 0
-
-#ifndef UVSCOM_INTR_INTERVAL
-#define UVSCOM_INTR_INTERVAL 100 /* mS */
-#endif
-
-#define UVSCOM_UNIT_WAIT 5
-
-/* Request */
-#define UVSCOM_SET_SPEED 0x10
-#define UVSCOM_LINE_CTL 0x11
-#define UVSCOM_SET_PARAM 0x12
-#define UVSCOM_READ_STATUS 0xd0
-#define UVSCOM_SHUTDOWN 0xe0
-
-/* UVSCOM_SET_SPEED parameters */
-#define UVSCOM_SPEED_150BPS 0x00
-#define UVSCOM_SPEED_300BPS 0x01
-#define UVSCOM_SPEED_600BPS 0x02
-#define UVSCOM_SPEED_1200BPS 0x03
-#define UVSCOM_SPEED_2400BPS 0x04
-#define UVSCOM_SPEED_4800BPS 0x05
-#define UVSCOM_SPEED_9600BPS 0x06
-#define UVSCOM_SPEED_19200BPS 0x07
-#define UVSCOM_SPEED_38400BPS 0x08
-#define UVSCOM_SPEED_57600BPS 0x09
-#define UVSCOM_SPEED_115200BPS 0x0a
-
-/* UVSCOM_LINE_CTL parameters */
-#define UVSCOM_BREAK 0x40
-#define UVSCOM_RTS 0x02
-#define UVSCOM_DTR 0x01
-#define UVSCOM_LINE_INIT 0x08
-
-/* UVSCOM_SET_PARAM parameters */
-#define UVSCOM_DATA_MASK 0x03
-#define UVSCOM_DATA_BIT_8 0x03
-#define UVSCOM_DATA_BIT_7 0x02
-#define UVSCOM_DATA_BIT_6 0x01
-#define UVSCOM_DATA_BIT_5 0x00
-
-#define UVSCOM_STOP_MASK 0x04
-#define UVSCOM_STOP_BIT_2 0x04
-#define UVSCOM_STOP_BIT_1 0x00
-
-#define UVSCOM_PARITY_MASK 0x18
-#define UVSCOM_PARITY_EVEN 0x18
-#if 0
-#define UVSCOM_PARITY_UNK 0x10
-#endif
-#define UVSCOM_PARITY_ODD 0x08
-#define UVSCOM_PARITY_NONE 0x00
-
-/* Status bits */
-#define UVSCOM_TXRDY 0x04
-#define UVSCOM_RXRDY 0x01
-
-#define UVSCOM_DCD 0x08
-#define UVSCOM_NOCARD 0x04
-#define UVSCOM_DSR 0x02
-#define UVSCOM_CTS 0x01
-#define UVSCOM_USTAT_MASK (UVSCOM_NOCARD | UVSCOM_DSR | UVSCOM_CTS)
-
-struct uvscom_softc {
- struct ucom_softc sc_ucom;
-
- int sc_iface_number;/* interface number */
-
- usbd_interface_handle sc_intr_iface; /* interrupt interface */
- int sc_intr_number; /* interrupt number */
- usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */
- u_char *sc_intr_buf; /* interrupt buffer */
- int sc_isize;
-
- u_char sc_dtr; /* current DTR state */
- u_char sc_rts; /* current RTS state */
-
- u_char sc_lsr; /* Local status register */
- u_char sc_msr; /* uvscom status register */
-
- uint16_t sc_lcr; /* Line control */
- u_char sc_usr; /* unit status */
-
- struct task sc_task;
-};
-
-/*
- * These are the maximum number of bytes transferred per frame.
- * The output buffer size cannot be increased due to the size encoding.
- */
-#define UVSCOMIBUFSIZE 512
-#define UVSCOMOBUFSIZE 64
-
-#ifndef UVSCOM_DEFAULT_OPKTSIZE
-#define UVSCOM_DEFAULT_OPKTSIZE 8
-#endif
-
-static usbd_status uvscom_shutdown(struct uvscom_softc *);
-static usbd_status uvscom_reset(struct uvscom_softc *);
-static usbd_status uvscom_set_line_coding(struct uvscom_softc *,
- uint16_t, uint16_t);
-static usbd_status uvscom_set_line(struct uvscom_softc *, uint16_t);
-static usbd_status uvscom_set_crtscts(struct uvscom_softc *);
-static void uvscom_get_status(void *, int, u_char *, u_char *);
-static void uvscom_dtr(struct uvscom_softc *, int);
-static void uvscom_rts(struct uvscom_softc *, int);
-static void uvscom_break(struct uvscom_softc *, int);
-
-static void uvscom_set(void *, int, int, int);
-static void uvscom_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static int uvscom_param(void *, int, struct termios *);
-static int uvscom_open(void *, int);
-static void uvscom_close(void *, int);
-static void uvscom_notify(void *, int);
-
-struct ucom_callback uvscom_callback = {
- uvscom_get_status,
- uvscom_set,
- uvscom_param,
- NULL,
- uvscom_open,
- uvscom_close,
- NULL,
- NULL
-};
-
-static const struct usb_devno uvscom_devs [] = {
- /* SUNTAC U-Cable type A4 */
- { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS144L4 },
- /* SUNTAC U-Cable type D2 */
- { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_DS96L },
- /* SUNTAC Ir-Trinity */
- { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_IS96U },
- /* SUNTAC U-Cable type P1 */
- { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_PS64P1 },
- /* SUNTAC Slipper U */
- { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_VS10U },
-};
-#define uvscom_lookup(v, p) usb_lookup(uvscom_devs, v, p)
-
-static device_probe_t uvscom_match;
-static device_attach_t uvscom_attach;
-static device_detach_t uvscom_detach;
-
-static device_method_t uvscom_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uvscom_match),
- DEVMETHOD(device_attach, uvscom_attach),
- DEVMETHOD(device_detach, uvscom_detach),
- { 0, 0 }
-};
-
-static driver_t uvscom_driver = {
- "ucom",
- uvscom_methods,
- sizeof (struct uvscom_softc)
-};
-
-DRIVER_MODULE(uvscom, uhub, uvscom_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uvscom, usb, 1, 1, 1);
-MODULE_DEPEND(uvscom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(uvscom, UVSCOM_MODVER);
-
-static int uvscomobufsiz = UVSCOM_DEFAULT_OPKTSIZE;
-static int uvscominterval = UVSCOM_INTR_INTERVAL;
-
-static int
-sysctl_hw_usb_uvscom_opktsize(SYSCTL_HANDLER_ARGS)
-{
- int err, val;
-
- val = uvscomobufsiz;
- err = sysctl_handle_int(oidp, &val, 0, req);
- if (err != 0 || req->newptr == NULL)
- return (err);
- if (0 < val && val <= UVSCOMOBUFSIZE)
- uvscomobufsiz = val;
- else
- err = EINVAL;
-
- return (err);
-}
-
-static int
-sysctl_hw_usb_uvscom_interval(SYSCTL_HANDLER_ARGS)
-{
- int err, val;
-
- val = uvscominterval;
- err = sysctl_handle_int(oidp, &val, 0, req);
- if (err != 0 || req->newptr == NULL)
- return (err);
- if (0 < val && val <= 1000)
- uvscominterval = val;
- else
- err = EINVAL;
-
- return (err);
-}
-
-SYSCTL_PROC(_hw_usb_uvscom, OID_AUTO, opktsize, CTLTYPE_INT | CTLFLAG_RW,
- 0, sizeof(int), sysctl_hw_usb_uvscom_opktsize,
- "I", "uvscom output packet size");
-SYSCTL_PROC(_hw_usb_uvscom, OID_AUTO, interval, CTLTYPE_INT | CTLFLAG_RW,
- 0, sizeof(int), sysctl_hw_usb_uvscom_interval,
- "I", "uvscom interrpt pipe interval");
-
-static int
-uvscom_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- return (uvscom_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-static int
-uvscom_attach(device_t self)
-{
- struct uvscom_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- struct ucom_softc *ucom;
- usb_config_descriptor_t *cdesc;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_status err;
- int i;
-
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- DPRINTF(("uvscom attach: sc = %p\n", sc));
-
- /* initialize endpoints */
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- sc->sc_intr_number = -1;
- sc->sc_intr_pipe = NULL;
-
- /* Move the device into the configured state. */
- err = usbd_set_config_index(dev, UVSCOM_CONFIG_INDEX, 1);
- if (err) {
- device_printf(self, "failed to set configuration, err=%s\n",
- usbd_errstr(err));
- goto error;
- }
-
- /* get the config descriptor */
- cdesc = usbd_get_config_descriptor(ucom->sc_udev);
-
- if (cdesc == NULL) {
- device_printf(self, "failed to get configuration descriptor\n");
- goto error;
- }
-
- /* get the common interface */
- err = usbd_device2interface_handle(dev, UVSCOM_IFACE_INDEX,
- &ucom->sc_iface);
- if (err) {
- device_printf(self, "failed to get interface, err=%s\n",
- usbd_errstr(err));
- goto error;
- }
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
- sc->sc_iface_number = id->bInterfaceNumber;
-
- /* Find endpoints */
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- device_printf(self, "no endpoint descriptor for %d\n",
- i);
- goto error;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- sc->sc_intr_number = ed->bEndpointAddress;
- sc->sc_isize = UGETW(ed->wMaxPacketSize);
- }
- }
-
- if (ucom->sc_bulkin_no == -1) {
- device_printf(self, "Could not find data bulk in\n");
- goto error;
- }
- if (ucom->sc_bulkout_no == -1) {
- device_printf(self, "Could not find data bulk out\n");
- goto error;
- }
- if (sc->sc_intr_number == -1) {
- device_printf(self, "Could not find interrupt in\n");
- goto error;
- }
-
- sc->sc_dtr = sc->sc_rts = 0;
- sc->sc_lcr = UVSCOM_LINE_INIT;
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = UVSCOMIBUFSIZE;
- ucom->sc_obufsize = uvscomobufsiz;
- ucom->sc_ibufsizepad = UVSCOMIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &uvscom_callback;
-
- err = uvscom_reset(sc);
-
- if (err) {
- device_printf(self, "reset failed, %s\n", usbd_errstr(err));
- goto error;
- }
-
- DPRINTF(("uvscom: in = 0x%x out = 0x%x intr = 0x%x\n",
- ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number));
-
- TASK_INIT(&sc->sc_task, 0, uvscom_notify, sc);
- ucom_attach(&sc->sc_ucom);
- return 0;
-
-error:
- ucom->sc_dying = 1;
- return ENXIO;
-}
-
-static int
-uvscom_detach(device_t self)
-{
- struct uvscom_softc *sc = device_get_softc(self);
- int rv = 0;
-
- DPRINTF(("uvscom_detach: sc = %p\n", sc));
-
- sc->sc_ucom.sc_dying = 1;
-
- if (sc->sc_intr_pipe != NULL) {
- usbd_abort_pipe(sc->sc_intr_pipe);
- usbd_close_pipe(sc->sc_intr_pipe);
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-
- rv = ucom_detach(&sc->sc_ucom);
-
- return (rv);
-}
-
-static usbd_status
-uvscom_readstat(struct uvscom_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
- uint16_t r;
-
- DPRINTF(("%s: send readstat\n", device_get_nameunit(sc->sc_ucom.sc_dev)));
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = UVSCOM_READ_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 2);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, &r);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "uvscom_readstat: %s\n",
- usbd_errstr(err));
- return (err);
- }
-
- DPRINTF(("%s: uvscom_readstat: r = %d\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), r));
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uvscom_shutdown(struct uvscom_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("%s: send shutdown\n", device_get_nameunit(sc->sc_ucom.sc_dev)));
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UVSCOM_SHUTDOWN;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "uvscom_shutdown: %s\n",
- usbd_errstr(err));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uvscom_reset(struct uvscom_softc *sc)
-{
- DPRINTF(("%s: uvscom_reset\n", device_get_nameunit(sc->sc_ucom.sc_dev)));
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uvscom_set_crtscts(struct uvscom_softc *sc)
-{
- DPRINTF(("%s: uvscom_set_crtscts\n", device_get_nameunit(sc->sc_ucom.sc_dev)));
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uvscom_set_line(struct uvscom_softc *sc, uint16_t line)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("%s: uvscom_set_line: %04x\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), line));
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UVSCOM_LINE_CTL;
- USETW(req.wValue, line);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "uvscom_set_line: %s\n",
- usbd_errstr(err));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uvscom_set_line_coding(struct uvscom_softc *sc, uint16_t lsp, uint16_t ls)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("%s: uvscom_set_line_coding: %02x %02x\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), lsp, ls));
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UVSCOM_SET_SPEED;
- USETW(req.wValue, lsp);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "uvscom_set_line_coding: %s\n",
- usbd_errstr(err));
- return (err);
- }
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UVSCOM_SET_PARAM;
- USETW(req.wValue, ls);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "uvscom_set_line_coding: %s\n",
- usbd_errstr(err));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-uvscom_dtr(struct uvscom_softc *sc, int onoff)
-{
- DPRINTF(("%s: uvscom_dtr: onoff = %d\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), onoff));
-
- if (sc->sc_dtr == onoff)
- return; /* no change */
-
- sc->sc_dtr = onoff;
-
- if (onoff)
- SET(sc->sc_lcr, UVSCOM_DTR);
- else
- CLR(sc->sc_lcr, UVSCOM_DTR);
-
- uvscom_set_line(sc, sc->sc_lcr);
-}
-
-static void
-uvscom_rts(struct uvscom_softc *sc, int onoff)
-{
- DPRINTF(("%s: uvscom_rts: onoff = %d\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), onoff));
-
- if (sc->sc_rts == onoff)
- return; /* no change */
-
- sc->sc_rts = onoff;
-
- if (onoff)
- SET(sc->sc_lcr, UVSCOM_RTS);
- else
- CLR(sc->sc_lcr, UVSCOM_RTS);
-
- uvscom_set_line(sc, sc->sc_lcr);
-}
-
-static void
-uvscom_break(struct uvscom_softc *sc, int onoff)
-{
- DPRINTF(("%s: uvscom_break: onoff = %d\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), onoff));
-
- if (onoff)
- uvscom_set_line(sc, SET(sc->sc_lcr, UVSCOM_BREAK));
-}
-
-static void
-uvscom_set(void *addr, int portno, int reg, int onoff)
-{
- struct uvscom_softc *sc = addr;
-
- switch (reg) {
- case UCOM_SET_DTR:
- uvscom_dtr(sc, onoff);
- break;
- case UCOM_SET_RTS:
- uvscom_rts(sc, onoff);
- break;
- case UCOM_SET_BREAK:
- uvscom_break(sc, onoff);
- break;
- default:
- break;
- }
-}
-
-static int
-uvscom_param(void *addr, int portno, struct termios *t)
-{
- struct uvscom_softc *sc = addr;
- usbd_status err;
- uint16_t lsp;
- uint16_t ls;
-
- DPRINTF(("%s: uvscom_param: sc = %p\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), sc));
-
- ls = 0;
-
- switch (t->c_ospeed) {
- case B150:
- lsp = UVSCOM_SPEED_150BPS;
- break;
- case B300:
- lsp = UVSCOM_SPEED_300BPS;
- break;
- case B600:
- lsp = UVSCOM_SPEED_600BPS;
- break;
- case B1200:
- lsp = UVSCOM_SPEED_1200BPS;
- break;
- case B2400:
- lsp = UVSCOM_SPEED_2400BPS;
- break;
- case B4800:
- lsp = UVSCOM_SPEED_4800BPS;
- break;
- case B9600:
- lsp = UVSCOM_SPEED_9600BPS;
- break;
- case B19200:
- lsp = UVSCOM_SPEED_19200BPS;
- break;
- case B38400:
- lsp = UVSCOM_SPEED_38400BPS;
- break;
- case B57600:
- lsp = UVSCOM_SPEED_57600BPS;
- break;
- case B115200:
- lsp = UVSCOM_SPEED_115200BPS;
- break;
- default:
- return (EIO);
- }
-
- if (ISSET(t->c_cflag, CSTOPB))
- SET(ls, UVSCOM_STOP_BIT_2);
- else
- SET(ls, UVSCOM_STOP_BIT_1);
-
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- SET(ls, UVSCOM_PARITY_ODD);
- else
- SET(ls, UVSCOM_PARITY_EVEN);
- } else
- SET(ls, UVSCOM_PARITY_NONE);
-
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- SET(ls, UVSCOM_DATA_BIT_5);
- break;
- case CS6:
- SET(ls, UVSCOM_DATA_BIT_6);
- break;
- case CS7:
- SET(ls, UVSCOM_DATA_BIT_7);
- break;
- case CS8:
- SET(ls, UVSCOM_DATA_BIT_8);
- break;
- default:
- return (EIO);
- }
-
- err = uvscom_set_line_coding(sc, lsp, ls);
- if (err)
- return (EIO);
-
- if (ISSET(t->c_cflag, CRTSCTS)) {
- err = uvscom_set_crtscts(sc);
- if (err)
- return (EIO);
- }
-
- return (0);
-}
-
-static int
-uvscom_open(void *addr, int portno)
-{
- struct uvscom_softc *sc = addr;
- int err;
- int i;
-
- if (sc->sc_ucom.sc_dying)
- return (ENXIO);
-
- DPRINTF(("uvscom_open: sc = %p\n", sc));
-
- /* change output packet size */
- sc->sc_ucom.sc_obufsize = uvscomobufsiz;
-
- if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
- DPRINTF(("uvscom_open: open interrupt pipe.\n"));
-
- sc->sc_usr = 0; /* clear unit status */
-
- err = uvscom_readstat(sc);
- if (err) {
- DPRINTF(("%s: uvscom_open: readstat faild\n",
- device_get_nameunit(sc->sc_ucom.sc_dev)));
- return (ENXIO);
- }
-
- sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
- err = usbd_open_pipe_intr(sc->sc_ucom.sc_iface,
- sc->sc_intr_number,
- USBD_SHORT_XFER_OK,
- &sc->sc_intr_pipe,
- sc,
- sc->sc_intr_buf,
- sc->sc_isize,
- uvscom_intr,
- uvscominterval);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev,
- "cannot open interrupt pipe (addr %d)\n",
- sc->sc_intr_number);
- return (ENXIO);
- }
- } else {
- DPRINTF(("uvscom_open: did not open interrupt pipe.\n"));
- }
-
- if ((sc->sc_usr & UVSCOM_USTAT_MASK) == 0) {
- /* unit is not ready */
-
- for (i = UVSCOM_UNIT_WAIT; i > 0; --i) {
- pause("uvsop", hz); /* XXX */
- if (ISSET(sc->sc_usr, UVSCOM_USTAT_MASK))
- break;
- }
- if (i == 0) {
- DPRINTF(("%s: unit is not ready\n",
- device_get_nameunit(sc->sc_ucom.sc_dev)));
- return (ENXIO);
- }
-
- /* check PC Card was inserted */
- if (ISSET(sc->sc_usr, UVSCOM_NOCARD)) {
- DPRINTF(("%s: no card\n",
- device_get_nameunit(sc->sc_ucom.sc_dev)));
- return (ENXIO);
- }
- }
-
- return (0);
-}
-
-static void
-uvscom_close(void *addr, int portno)
-{
- struct uvscom_softc *sc = addr;
- int err;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- DPRINTF(("uvscom_close: close\n"));
-
- uvscom_shutdown(sc);
-
- if (sc->sc_intr_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(sc->sc_ucom.sc_dev,
- "abort interrupt pipe failed: %s\n",
- usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(sc->sc_ucom.sc_dev,
- "close interrupt pipe failed: %s\n",
- usbd_errstr(err));
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-}
-
-static void
-uvscom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct uvscom_softc *sc = priv;
- u_char *buf = sc->sc_intr_buf;
- u_char pstatus;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- device_printf(sc->sc_ucom.sc_dev,
- "uvscom_intr: abnormal status: %s\n",
- usbd_errstr(status));
- usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
- return;
- }
-
- DPRINTFN(2, ("%s: uvscom status = %02x %02x\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), buf[0], buf[1]));
-
- sc->sc_lsr = sc->sc_msr = 0;
- sc->sc_usr = buf[1];
-
- pstatus = buf[0];
- if (ISSET(pstatus, UVSCOM_TXRDY))
- SET(sc->sc_lsr, ULSR_TXRDY);
- if (ISSET(pstatus, UVSCOM_RXRDY))
- SET(sc->sc_lsr, ULSR_RXRDY);
-
- pstatus = buf[1];
- if (ISSET(pstatus, UVSCOM_CTS))
- SET(sc->sc_msr, SER_CTS);
- if (ISSET(pstatus, UVSCOM_DSR))
- SET(sc->sc_msr, SER_DSR);
- if (ISSET(pstatus, UVSCOM_DCD))
- SET(sc->sc_msr, SER_DCD);
-
- /* Deferred notifying to the ucom layer */
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
-}
-
-static void
-uvscom_notify(void *arg, int count)
-{
- struct uvscom_softc *sc;
-
- sc = (struct uvscom_softc *)arg;
- if (sc->sc_ucom.sc_dying)
- return;
- ucom_status_change(&sc->sc_ucom);
-}
-
-static void
-uvscom_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct uvscom_softc *sc = addr;
-
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-}
diff --git a/sys/legacy/dev/usb/uxb360gp_rdesc.h b/sys/legacy/dev/usb/uxb360gp_rdesc.h
deleted file mode 100644
index b5a43f9..0000000
--- a/sys/legacy/dev/usb/uxb360gp_rdesc.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*-
- * Copyright (c) 2005 Ed Schouten <ed@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * The descriptor has no output report format, thus preventing you from
- * controlling the LEDs and the built-in rumblers.
- */
-static const uByte uhid_xb360gp_report_descr[] = {
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x05, /* USAGE (Gamepad) */
- 0xa1, 0x01, /* COLLECTION (Application) */
- /* Unused */
- 0x75, 0x08, /* REPORT SIZE (8) */
- 0x95, 0x01, /* REPORT COUNT (1) */
- 0x81, 0x01, /* INPUT (Constant) */
- /* Byte count */
- 0x75, 0x08, /* REPORT SIZE (8) */
- 0x95, 0x01, /* REPORT COUNT (1) */
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x3b, /* USAGE (Byte Count) */
- 0x81, 0x01, /* INPUT (Constant) */
- /* D-Pad */
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x01, /* USAGE (Pointer) */
- 0xa1, 0x00, /* COLLECTION (Physical) */
- 0x75, 0x01, /* REPORT SIZE (1) */
- 0x15, 0x00, /* LOGICAL MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL MAXIMUM (1) */
- 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
- 0x45, 0x01, /* PHYSICAL MAXIMUM (1) */
- 0x95, 0x04, /* REPORT COUNT (4) */
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x90, /* USAGE (D-Pad Up) */
- 0x09, 0x91, /* USAGE (D-Pad Down) */
- 0x09, 0x93, /* USAGE (D-Pad Left) */
- 0x09, 0x92, /* USAGE (D-Pad Right) */
- 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
- 0xc0, /* END COLLECTION */
- /* Buttons 5-11 */
- 0x75, 0x01, /* REPORT SIZE (1) */
- 0x15, 0x00, /* LOGICAL MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL MAXIMUM (1) */
- 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
- 0x45, 0x01, /* PHYSICAL MAXIMUM (1) */
- 0x95, 0x07, /* REPORT COUNT (7) */
- 0x05, 0x09, /* USAGE PAGE (Button) */
- 0x09, 0x08, /* USAGE (Button 8) */
- 0x09, 0x07, /* USAGE (Button 7) */
- 0x09, 0x09, /* USAGE (Button 9) */
- 0x09, 0x0a, /* USAGE (Button 10) */
- 0x09, 0x05, /* USAGE (Button 5) */
- 0x09, 0x06, /* USAGE (Button 6) */
- 0x09, 0x0b, /* USAGE (Button 11) */
- 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
- /* Unused */
- 0x75, 0x01, /* REPORT SIZE (1) */
- 0x95, 0x01, /* REPORT COUNT (1) */
- 0x81, 0x01, /* INPUT (Constant) */
- /* Buttons 1-4 */
- 0x75, 0x01, /* REPORT SIZE (1) */
- 0x15, 0x00, /* LOGICAL MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL MAXIMUM (1) */
- 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
- 0x45, 0x01, /* PHYSICAL MAXIMUM (1) */
- 0x95, 0x04, /* REPORT COUNT (4) */
- 0x05, 0x09, /* USAGE PAGE (Button) */
- 0x19, 0x01, /* USAGE MINIMUM (Button 1) */
- 0x29, 0x04, /* USAGE MAXIMUM (Button 4) */
- 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
- /* Triggers */
- 0x75, 0x08, /* REPORT SIZE (8) */
- 0x15, 0x00, /* LOGICAL MINIMUM (0) */
- 0x26, 0xff, 0x00, /* LOGICAL MAXIMUM (255) */
- 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
- 0x46, 0xff, 0x00, /* PHYSICAL MAXIMUM (255) */
- 0x95, 0x02, /* REPORT SIZE (2) */
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x32, /* USAGE (Z) */
- 0x09, 0x35, /* USAGE (Rz) */
- 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
- /* Sticks */
- 0x75, 0x10, /* REPORT SIZE (16) */
- 0x16, 0x00, 0x80, /* LOGICAL MINIMUM (-32768) */
- 0x26, 0xff, 0x7f, /* LOGICAL MAXIMUM (32767) */
- 0x36, 0x00, 0x80, /* PHYSICAL MINIMUM (-32768) */
- 0x46, 0xff, 0x7f, /* PHYSICAL MAXIMUM (32767) */
- 0x95, 0x04, /* REPORT COUNT (4) */
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x30, /* USAGE (X) */
- 0x09, 0x31, /* USAGE (Y) */
- 0x09, 0x33, /* USAGE (Rx) */
- 0x09, 0x34, /* USAGE (Ry) */
- 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
- /* Unused */
- 0x75, 0x30, /* REPORT SIZE (48) */
- 0x95, 0x01, /* REPORT COUNT (1) */
- 0x81, 0x01, /* INPUT (Constant) */
- 0xc0, /* END COLLECTION */
-};
OpenPOWER on IntegriCloud