summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb2
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb2')
-rw-r--r--sys/dev/usb2/bluetooth/TODO.TXT18
-rw-r--r--sys/dev/usb2/bluetooth/ng_ubt2.c1720
-rw-r--r--sys/dev/usb2/bluetooth/ng_ubt2_var.h131
-rw-r--r--sys/dev/usb2/bluetooth/ubtbcmfw2.c431
-rw-r--r--sys/dev/usb2/bluetooth/usb2_bluetooth.c31
-rw-r--r--sys/dev/usb2/bluetooth/usb2_bluetooth.h30
-rw-r--r--sys/dev/usb2/controller/at91dci.c2467
-rw-r--r--sys/dev/usb2/controller/at91dci.h245
-rw-r--r--sys/dev/usb2/controller/at91dci_atmelarm.c347
-rw-r--r--sys/dev/usb2/controller/atmegadci.c2327
-rw-r--r--sys/dev/usb2/controller/atmegadci.h273
-rw-r--r--sys/dev/usb2/controller/atmegadci_atmelarm.c27
-rw-r--r--sys/dev/usb2/controller/ehci2.c3965
-rw-r--r--sys/dev/usb2/controller/ehci2.h532
-rw-r--r--sys/dev/usb2/controller/ehci2_ixp4xx.c349
-rw-r--r--sys/dev/usb2/controller/ehci2_mbus.c365
-rw-r--r--sys/dev/usb2/controller/ehci2_pci.c487
-rw-r--r--sys/dev/usb2/controller/musb2_otg.c2875
-rw-r--r--sys/dev/usb2/controller/musb2_otg.h407
-rw-r--r--sys/dev/usb2/controller/musb2_otg_atmelarm.c240
-rw-r--r--sys/dev/usb2/controller/ohci2.c2862
-rw-r--r--sys/dev/usb2/controller/ohci2.h366
-rw-r--r--sys/dev/usb2/controller/ohci2_atmelarm.c224
-rw-r--r--sys/dev/usb2/controller/ohci2_pci.c388
-rw-r--r--sys/dev/usb2/controller/uhci2.c3381
-rw-r--r--sys/dev/usb2/controller/uhci2.h321
-rw-r--r--sys/dev/usb2/controller/uhci2_pci.c444
-rw-r--r--sys/dev/usb2/controller/usb2_bus.h104
-rw-r--r--sys/dev/usb2/controller/usb2_controller.c623
-rw-r--r--sys/dev/usb2/controller/usb2_controller.h199
-rw-r--r--sys/dev/usb2/controller/usb2_pci.h39
-rw-r--r--sys/dev/usb2/controller/uss820dci.c2489
-rw-r--r--sys/dev/usb2/controller/uss820dci.h377
-rw-r--r--sys/dev/usb2/controller/uss820dci_atmelarm.c239
-rw-r--r--sys/dev/usb2/core/README.TXT411
-rw-r--r--sys/dev/usb2/core/usb2_busdma.c1426
-rw-r--r--sys/dev/usb2/core/usb2_busdma.h183
-rw-r--r--sys/dev/usb2/core/usb2_compat_linux.c1653
-rw-r--r--sys/dev/usb2/core/usb2_compat_linux.h472
-rw-r--r--sys/dev/usb2/core/usb2_core.c40
-rw-r--r--sys/dev/usb2/core/usb2_core.h467
-rw-r--r--sys/dev/usb2/core/usb2_debug.c152
-rw-r--r--sys/dev/usb2/core/usb2_debug.h70
-rw-r--r--sys/dev/usb2/core/usb2_dev.c2814
-rw-r--r--sys/dev/usb2/core/usb2_dev.h168
-rw-r--r--sys/dev/usb2/core/usb2_device.c2192
-rw-r--r--sys/dev/usb2/core/usb2_device.h187
-rw-r--r--sys/dev/usb2/core/usb2_dynamic.c155
-rw-r--r--sys/dev/usb2/core/usb2_dynamic.h70
-rw-r--r--sys/dev/usb2/core/usb2_error.c73
-rw-r--r--sys/dev/usb2/core/usb2_generic.c2195
-rw-r--r--sys/dev/usb2/core/usb2_generic.h33
-rw-r--r--sys/dev/usb2/core/usb2_handle_request.c756
-rw-r--r--sys/dev/usb2/core/usb2_handle_request.h30
-rw-r--r--sys/dev/usb2/core/usb2_hid.c582
-rw-r--r--sys/dev/usb2/core/usb2_hid.h95
-rw-r--r--sys/dev/usb2/core/usb2_hub.c1842
-rw-r--r--sys/dev/usb2/core/usb2_hub.h80
-rw-r--r--sys/dev/usb2/core/usb2_if.m52
-rw-r--r--sys/dev/usb2/core/usb2_lookup.c134
-rw-r--r--sys/dev/usb2/core/usb2_lookup.h122
-rw-r--r--sys/dev/usb2/core/usb2_mbuf.c77
-rw-r--r--sys/dev/usb2/core/usb2_mbuf.h102
-rw-r--r--sys/dev/usb2/core/usb2_msctest.c578
-rw-r--r--sys/dev/usb2/core/usb2_msctest.h33
-rw-r--r--sys/dev/usb2/core/usb2_parse.c225
-rw-r--r--sys/dev/usb2/core/usb2_parse.h41
-rw-r--r--sys/dev/usb2/core/usb2_process.c426
-rw-r--r--sys/dev/usb2/core/usb2_process.h88
-rw-r--r--sys/dev/usb2/core/usb2_request.c1486
-rw-r--r--sys/dev/usb2/core/usb2_request.h103
-rw-r--r--sys/dev/usb2/core/usb2_sw_transfer.c170
-rw-r--r--sys/dev/usb2/core/usb2_sw_transfer.h62
-rw-r--r--sys/dev/usb2/core/usb2_transfer.c2826
-rw-r--r--sys/dev/usb2/core/usb2_transfer.h129
-rw-r--r--sys/dev/usb2/core/usb2_util.c346
-rw-r--r--sys/dev/usb2/core/usb2_util.h57
-rw-r--r--sys/dev/usb2/ethernet/if_aue2.c1054
-rw-r--r--sys/dev/usb2/ethernet/if_auereg.h220
-rw-r--r--sys/dev/usb2/ethernet/if_axe2.c1076
-rw-r--r--sys/dev/usb2/ethernet/if_axereg.h196
-rw-r--r--sys/dev/usb2/ethernet/if_cdce2.c771
-rw-r--r--sys/dev/usb2/ethernet/if_cdcereg.h68
-rw-r--r--sys/dev/usb2/ethernet/if_cue2.c645
-rw-r--r--sys/dev/usb2/ethernet/if_cuereg.h132
-rw-r--r--sys/dev/usb2/ethernet/if_kue2.c704
-rw-r--r--sys/dev/usb2/ethernet/if_kuefw.h685
-rw-r--r--sys/dev/usb2/ethernet/if_kuereg.h141
-rw-r--r--sys/dev/usb2/ethernet/if_rue2.c913
-rw-r--r--sys/dev/usb2/ethernet/if_ruereg.h183
-rw-r--r--sys/dev/usb2/ethernet/if_udav2.c856
-rw-r--r--sys/dev/usb2/ethernet/if_udavreg.h166
-rw-r--r--sys/dev/usb2/ethernet/usb2_ethernet.c587
-rw-r--r--sys/dev/usb2/ethernet/usb2_ethernet.h122
-rw-r--r--sys/dev/usb2/image/usb2_image.c31
-rw-r--r--sys/dev/usb2/image/usb2_image.h30
-rw-r--r--sys/dev/usb2/image/uscanner2.c644
-rw-r--r--sys/dev/usb2/include/ufm2_ioctl.h39
-rw-r--r--sys/dev/usb2/include/usb2_cdc.h191
-rw-r--r--sys/dev/usb2/include/usb2_defs.h77
-rw-r--r--sys/dev/usb2/include/usb2_endian.h119
-rw-r--r--sys/dev/usb2/include/usb2_error.h63
-rw-r--r--sys/dev/usb2/include/usb2_hid.h175
-rw-r--r--sys/dev/usb2/include/usb2_ioctl.h292
-rw-r--r--sys/dev/usb2/include/usb2_mfunc.h78
-rw-r--r--sys/dev/usb2/include/usb2_revision.h65
-rw-r--r--sys/dev/usb2/include/usb2_standard.h619
-rw-r--r--sys/dev/usb2/input/uhid2.c791
-rw-r--r--sys/dev/usb2/input/ukbd2.c1492
-rw-r--r--sys/dev/usb2/input/ums2.c904
-rw-r--r--sys/dev/usb2/input/usb2_input.c31
-rw-r--r--sys/dev/usb2/input/usb2_input.h30
-rw-r--r--sys/dev/usb2/input/usb2_rdesc.h276
-rw-r--r--sys/dev/usb2/misc/udbp2.c854
-rw-r--r--sys/dev/usb2/misc/udbp2.h80
-rw-r--r--sys/dev/usb2/misc/ufm2.c330
-rw-r--r--sys/dev/usb2/misc/usb2_misc.c31
-rw-r--r--sys/dev/usb2/misc/usb2_misc.h30
-rw-r--r--sys/dev/usb2/ndis/if_ndis_usb2.c144
-rw-r--r--sys/dev/usb2/ndis/usb2_ndis.c31
-rw-r--r--sys/dev/usb2/ndis/usb2_ndis.h30
-rw-r--r--sys/dev/usb2/quirk/usb2_quirk.c397
-rw-r--r--sys/dev/usb2/quirk/usb2_quirk.h59
-rw-r--r--sys/dev/usb2/serial/u3g2.c583
-rw-r--r--sys/dev/usb2/serial/uark2.c407
-rw-r--r--sys/dev/usb2/serial/ubsa2.c634
-rw-r--r--sys/dev/usb2/serial/ubser2.c518
-rw-r--r--sys/dev/usb2/serial/uchcom2.c883
-rw-r--r--sys/dev/usb2/serial/ucycom2.c564
-rw-r--r--sys/dev/usb2/serial/ufoma2.c1212
-rw-r--r--sys/dev/usb2/serial/uftdi2.c784
-rw-r--r--sys/dev/usb2/serial/uftdi2_reg.h340
-rw-r--r--sys/dev/usb2/serial/ugensa2.c352
-rw-r--r--sys/dev/usb2/serial/uipaq2.c1314
-rw-r--r--sys/dev/usb2/serial/ulpt2.c726
-rw-r--r--sys/dev/usb2/serial/umct2.c579
-rw-r--r--sys/dev/usb2/serial/umodem2.c788
-rw-r--r--sys/dev/usb2/serial/umoscom2.c672
-rw-r--r--sys/dev/usb2/serial/uplcom2.c831
-rw-r--r--sys/dev/usb2/serial/usb2_serial.c1127
-rw-r--r--sys/dev/usb2/serial/usb2_serial.h198
-rw-r--r--sys/dev/usb2/serial/uslcom2.c539
-rw-r--r--sys/dev/usb2/serial/uvisor2.c610
-rw-r--r--sys/dev/usb2/serial/uvscom2.c707
-rw-r--r--sys/dev/usb2/sound/uaudio2.c3751
-rw-r--r--sys/dev/usb2/sound/uaudio2.h63
-rw-r--r--sys/dev/usb2/sound/uaudio2_pcm.c234
-rw-r--r--sys/dev/usb2/sound/uaudio2_reg.h406
-rw-r--r--sys/dev/usb2/sound/usb2_sound.c31
-rw-r--r--sys/dev/usb2/sound/usb2_sound.h30
-rw-r--r--sys/dev/usb2/storage/ata-usb2.c1103
-rw-r--r--sys/dev/usb2/storage/umass2.c3620
-rw-r--r--sys/dev/usb2/storage/urio2.c480
-rw-r--r--sys/dev/usb2/storage/usb2_storage.c31
-rw-r--r--sys/dev/usb2/storage/usb2_storage.h30
-rw-r--r--sys/dev/usb2/storage/ustorage2_fs.c1898
-rw-r--r--sys/dev/usb2/template/usb2_template.c1312
-rw-r--r--sys/dev/usb2/template/usb2_template.h102
-rw-r--r--sys/dev/usb2/template/usb2_template_cdce.c292
-rw-r--r--sys/dev/usb2/template/usb2_template_msc.c199
-rw-r--r--sys/dev/usb2/template/usb2_template_mtp.c262
-rw-r--r--sys/dev/usb2/wlan/if_rum2.c2436
-rw-r--r--sys/dev/usb2/wlan/if_rumfw.h213
-rw-r--r--sys/dev/usb2/wlan/if_rumreg.h235
-rw-r--r--sys/dev/usb2/wlan/if_rumvar.h156
-rw-r--r--sys/dev/usb2/wlan/if_ural2.c2365
-rw-r--r--sys/dev/usb2/wlan/if_uralreg.h211
-rw-r--r--sys/dev/usb2/wlan/if_uralvar.h155
-rw-r--r--sys/dev/usb2/wlan/if_zyd2.c3122
-rw-r--r--sys/dev/usb2/wlan/if_zydfw.h1144
-rw-r--r--sys/dev/usb2/wlan/if_zydreg.h1338
-rw-r--r--sys/dev/usb2/wlan/usb2_wlan.c31
-rw-r--r--sys/dev/usb2/wlan/usb2_wlan.h57
173 files changed, 0 insertions, 108653 deletions
diff --git a/sys/dev/usb2/bluetooth/TODO.TXT b/sys/dev/usb2/bluetooth/TODO.TXT
deleted file mode 100644
index b0d6695..0000000
--- a/sys/dev/usb2/bluetooth/TODO.TXT
+++ /dev/null
@@ -1,18 +0,0 @@
-$Id: TODO,v 1.1 2002/11/24 19:46:56 max Exp $
-$FreeBSD$
-
-1) SMP/Locking
-
- The code makes use of ng_send_fn() whenever possible. Just
- need to verify and make sure i did it right
-
-2) Firmware upgrade
-
- According to Bluetooth spec device may present third interface
- to perform firmware upgrade. 3Com USB Bluetooth dongle has
- such interface. Need to implement set of Netgraph messages.
-
-3) Isochronous USB transfers (SCO data)
-
- Tried to fix isochrounous transfers, which are still disabled
- by default.
diff --git a/sys/dev/usb2/bluetooth/ng_ubt2.c b/sys/dev/usb2/bluetooth/ng_ubt2.c
deleted file mode 100644
index 3b1ba31..0000000
--- a/sys/dev/usb2/bluetooth/ng_ubt2.c
+++ /dev/null
@@ -1,1720 +0,0 @@
-/*
- * ng_ubt.c
- */
-
-/*-
- * Copyright (c) 2001-2009 Maksim Yevmenkin <m_evmenkin@yahoo.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 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.
- *
- * $Id: ng_ubt.c,v 1.16 2003/10/10 19:15:06 max Exp $
- * $FreeBSD$
- */
-
-/*
- * NOTE: ng_ubt2 driver has a split personality. On one side it is
- * a USB device driver and on the other it is a Netgraph node. This
- * driver will *NOT* create traditional /dev/ enties, only Netgraph
- * node.
- *
- * NOTE ON LOCKS USED: ng_ubt2 drives uses 2 locks (mutexes)
- *
- * 1) sc_if_mtx - lock for device's interface #0 and #1. This lock is used
- * by USB for any USB request going over device's interface #0 and #1,
- * i.e. interrupt, control, bulk and isoc. transfers.
- *
- * 2) sc_ng_mtx - this lock is used to protect shared (between USB, Netgraph
- * and Taskqueue) data, such as outgoing mbuf queues, task flags and hook
- * pointer. This lock *SHOULD NOT* be grabbed for a long time. In fact,
- * think of it as a spin lock.
- *
- * NOTE ON LOCKING STRATEGY: ng_ubt2 driver operates in 3 different contexts.
- *
- * 1) USB context. This is where all the USB related stuff happens. All
- * callbacks run in this context. All callbacks are called (by USB) with
- * appropriate interface lock held. It is (generally) allowed to grab
- * any additional locks.
- *
- * 2) Netgraph context. This is where all the Netgraph related stuff happens.
- * Since we mark node as WRITER, the Netgraph node will be "locked" (from
- * Netgraph point of view). Any variable that is only modified from the
- * Netgraph context does not require any additonal locking. It is generally
- * *NOT* allowed to grab *ANY* additional locks. Whatever you do, *DO NOT*
- * grab any lock in the Netgraph context that could cause de-scheduling of
- * the Netgraph thread for significant amount of time. In fact, the only
- * lock that is allowed in the Netgraph context is the sc_ng_mtx lock.
- * Also make sure that any code that is called from the Netgraph context
- * follows the rule above.
- *
- * 3) Taskqueue context. This is where ubt_task runs. Since we are generally
- * NOT allowed to grab any lock that could cause de-scheduling in the
- * Netgraph context, and, USB requires us to grab interface lock before
- * doing things with transfers, it is safer to transition from the Netgraph
- * context to the Taskqueue context before we can call into USB subsystem.
- *
- * So, to put everything together, the rules are as follows.
- * It is OK to call from the USB context or the Taskqueue context into
- * the Netgraph context (i.e. call NG_SEND_xxx functions). In other words
- * it is allowed to call into the Netgraph context with locks held.
- * Is it *NOT* OK to call from the Netgraph context into the USB context,
- * because USB requires us to grab interface locks, and, it is safer to
- * avoid it. So, to make things safer we set task flags to indicate which
- * actions we want to perform and schedule ubt_task which would run in the
- * Taskqueue context.
- * Is is OK to call from the Taskqueue context into the USB context,
- * and, ubt_task does just that (i.e. grabs appropriate interface locks
- * before calling into USB).
- * Access to the outgoing queues, task flags and hook pointer is
- * controlled by the sc_ng_mtx lock. It is an unavoidable evil. Again,
- * sc_ng_mtx should really be a spin lock (and it is very likely to an
- * equivalent of spin lock due to adaptive nature of freebsd mutexes).
- * All USB callbacks accept softc pointer as a private data. USB ensures
- * that this pointer is valid.
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_parse.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_transfer.h>
-
-#include <sys/mbuf.h>
-#include <sys/taskqueue.h>
-
-#include <netgraph/ng_message.h>
-#include <netgraph/netgraph.h>
-#include <netgraph/ng_parse.h>
-#include <netgraph/bluetooth/include/ng_bluetooth.h>
-#include <netgraph/bluetooth/include/ng_hci.h>
-#include <netgraph/bluetooth/include/ng_ubt.h>
-
-#include <dev/usb2/bluetooth/usb2_bluetooth.h>
-#include <dev/usb2/bluetooth/ng_ubt2_var.h>
-
-static int ubt_modevent(module_t, int, void *);
-static device_probe_t ubt_probe;
-static device_attach_t ubt_attach;
-static device_detach_t ubt_detach;
-
-static void ubt_task_schedule(ubt_softc_p, int);
-static task_fn_t ubt_task;
-
-#define ubt_xfer_start(sc, i) usb2_transfer_start((sc)->sc_xfer[(i)])
-
-/* Netgraph methods */
-static ng_constructor_t ng_ubt_constructor;
-static ng_shutdown_t ng_ubt_shutdown;
-static ng_newhook_t ng_ubt_newhook;
-static ng_connect_t ng_ubt_connect;
-static ng_disconnect_t ng_ubt_disconnect;
-static ng_rcvmsg_t ng_ubt_rcvmsg;
-static ng_rcvdata_t ng_ubt_rcvdata;
-
-/* Queue length */
-static const struct ng_parse_struct_field ng_ubt_node_qlen_type_fields[] =
-{
- { "queue", &ng_parse_int32_type, },
- { "qlen", &ng_parse_int32_type, },
- { NULL, }
-};
-static const struct ng_parse_type ng_ubt_node_qlen_type =
-{
- &ng_parse_struct_type,
- &ng_ubt_node_qlen_type_fields
-};
-
-/* Stat info */
-static const struct ng_parse_struct_field ng_ubt_node_stat_type_fields[] =
-{
- { "pckts_recv", &ng_parse_uint32_type, },
- { "bytes_recv", &ng_parse_uint32_type, },
- { "pckts_sent", &ng_parse_uint32_type, },
- { "bytes_sent", &ng_parse_uint32_type, },
- { "oerrors", &ng_parse_uint32_type, },
- { "ierrors", &ng_parse_uint32_type, },
- { NULL, }
-};
-static const struct ng_parse_type ng_ubt_node_stat_type =
-{
- &ng_parse_struct_type,
- &ng_ubt_node_stat_type_fields
-};
-
-/* Netgraph node command list */
-static const struct ng_cmdlist ng_ubt_cmdlist[] =
-{
- {
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_SET_DEBUG,
- "set_debug",
- &ng_parse_uint16_type,
- NULL
- },
- {
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_GET_DEBUG,
- "get_debug",
- NULL,
- &ng_parse_uint16_type
- },
- {
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_SET_QLEN,
- "set_qlen",
- &ng_ubt_node_qlen_type,
- NULL
- },
- {
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_GET_QLEN,
- "get_qlen",
- &ng_ubt_node_qlen_type,
- &ng_ubt_node_qlen_type
- },
- {
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_GET_STAT,
- "get_stat",
- NULL,
- &ng_ubt_node_stat_type
- },
- {
- NGM_UBT_COOKIE,
- NGM_UBT_NODE_RESET_STAT,
- "reset_stat",
- NULL,
- NULL
- },
- { 0, }
-};
-
-/* Netgraph node type */
-static struct ng_type typestruct =
-{
- .version = NG_ABI_VERSION,
- .name = NG_UBT_NODE_TYPE,
- .constructor = ng_ubt_constructor,
- .rcvmsg = ng_ubt_rcvmsg,
- .shutdown = ng_ubt_shutdown,
- .newhook = ng_ubt_newhook,
- .connect = ng_ubt_connect,
- .rcvdata = ng_ubt_rcvdata,
- .disconnect = ng_ubt_disconnect,
- .cmdlist = ng_ubt_cmdlist
-};
-
-/****************************************************************************
- ****************************************************************************
- ** USB specific
- ****************************************************************************
- ****************************************************************************/
-
-/* USB methods */
-static usb2_callback_t ubt_ctrl_write_callback;
-static usb2_callback_t ubt_intr_read_callback;
-static usb2_callback_t ubt_bulk_read_callback;
-static usb2_callback_t ubt_bulk_write_callback;
-static usb2_callback_t ubt_isoc_read_callback;
-static usb2_callback_t ubt_isoc_write_callback;
-
-static int ubt_fwd_mbuf_up(ubt_softc_p, struct mbuf **);
-static int ubt_isoc_read_one_frame(struct usb2_xfer *, int);
-
-/*
- * USB config
- *
- * The following desribes usb transfers that could be submitted on USB device.
- *
- * Interface 0 on the USB device must present the following endpoints
- * 1) Interrupt endpoint to receive HCI events
- * 2) Bulk IN endpoint to receive ACL data
- * 3) Bulk OUT endpoint to send ACL data
- *
- * Interface 1 on the USB device must present the following endpoints
- * 1) Isochronous IN endpoint to receive SCO data
- * 2) Isochronous OUT endpoint to send SCO data
- */
-
-static const struct usb2_config ubt_config[UBT_N_TRANSFER] =
-{
- /*
- * Interface #0
- */
-
- /* Outgoing bulk transfer - ACL packets */
- [UBT_IF_0_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .if_index = 0,
- .mh.bufsize = UBT_BULK_WRITE_BUFFER_SIZE,
- .mh.flags = { .pipe_bof = 1, .force_short_xfer = 1, },
- .mh.callback = &ubt_bulk_write_callback,
- },
- /* Incoming bulk transfer - ACL packets */
- [UBT_IF_0_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .if_index = 0,
- .mh.bufsize = UBT_BULK_READ_BUFFER_SIZE,
- .mh.flags = { .pipe_bof = 1, .short_xfer_ok = 1, },
- .mh.callback = &ubt_bulk_read_callback,
- },
- /* Incoming interrupt transfer - HCI events */
- [UBT_IF_0_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .if_index = 0,
- .mh.flags = { .pipe_bof = 1, .short_xfer_ok = 1, },
- .mh.bufsize = UBT_INTR_BUFFER_SIZE,
- .mh.callback = &ubt_intr_read_callback,
- },
- /* Outgoing control transfer - HCI commands */
- [UBT_IF_0_CTRL_DT_WR] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* control pipe */
- .direction = UE_DIR_ANY,
- .if_index = 0,
- .mh.bufsize = UBT_CTRL_BUFFER_SIZE,
- .mh.callback = &ubt_ctrl_write_callback,
- .mh.timeout = 5000, /* 5 seconds */
- },
-
- /*
- * Interface #1
- */
-
- /* Incoming isochronous transfer #1 - SCO packets */
- [UBT_IF_1_ISOC_DT_RD1] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .if_index = 1,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES,
- .mh.flags = { .short_xfer_ok = 1, },
- .mh.callback = &ubt_isoc_read_callback,
- },
- /* Incoming isochronous transfer #2 - SCO packets */
- [UBT_IF_1_ISOC_DT_RD2] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .if_index = 1,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES,
- .mh.flags = { .short_xfer_ok = 1, },
- .mh.callback = &ubt_isoc_read_callback,
- },
- /* Outgoing isochronous transfer #1 - SCO packets */
- [UBT_IF_1_ISOC_DT_WR1] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .if_index = 1,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES,
- .mh.flags = { .short_xfer_ok = 1, },
- .mh.callback = &ubt_isoc_write_callback,
- },
- /* Outgoing isochronous transfer #2 - SCO packets */
- [UBT_IF_1_ISOC_DT_WR2] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .if_index = 1,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UBT_ISOC_NFRAMES,
- .mh.flags = { .short_xfer_ok = 1, },
- .mh.callback = &ubt_isoc_write_callback,
- },
-};
-
-/*
- * If for some reason device should not be attached then put
- * VendorID/ProductID pair into the list below. The format is
- * as follows:
- *
- * { USB_VPI(VENDOR_ID, PRODUCT_ID, 0) },
- *
- * where VENDOR_ID and PRODUCT_ID are hex numbers.
- */
-
-static const struct usb2_device_id ubt_ignore_devs[] =
-{
- /* AVM USB Bluetooth-Adapter BlueFritz! v1.0 */
- { USB_VPI(USB_VENDOR_AVM, 0x2200, 0) },
-};
-
-/* List of supported bluetooth devices */
-static const struct usb2_device_id ubt_devs[] =
-{
- /* Generic Bluetooth class devices */
- { USB_IFACE_CLASS(UDCLASS_WIRELESS),
- USB_IFACE_SUBCLASS(UDSUBCLASS_RF),
- USB_IFACE_PROTOCOL(UDPROTO_BLUETOOTH) },
-
- /* AVM USB Bluetooth-Adapter BlueFritz! v2.0 */
- { USB_VPI(USB_VENDOR_AVM, 0x3800, 0) },
-};
-
-/*
- * Probe for a USB Bluetooth device.
- * USB context.
- */
-
-static int
-ubt_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
-
- if (uaa->info.bIfaceIndex != 0)
- return (ENXIO);
-
- if (uaa->use_generic == 0)
- return (ENXIO);
-
- if (usb2_lookup_id_by_uaa(ubt_ignore_devs,
- sizeof(ubt_ignore_devs), uaa) == 0)
- return (ENXIO);
-
- return (usb2_lookup_id_by_uaa(ubt_devs, sizeof(ubt_devs), uaa));
-} /* ubt_probe */
-
-/*
- * Attach the device.
- * USB context.
- */
-
-static int
-ubt_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ubt_softc *sc = device_get_softc(dev);
- struct usb2_endpoint_descriptor *ed;
- uint16_t wMaxPacketSize;
- uint8_t alt_index, i, j;
- uint8_t iface_index[2] = { 0, 1 };
-
- device_set_usb2_desc(dev);
-
- sc->sc_dev = dev;
- sc->sc_debug = NG_UBT_WARN_LEVEL;
-
- /*
- * Create Netgraph node
- */
-
- if (ng_make_node_common(&typestruct, &sc->sc_node) != 0) {
- UBT_ALERT(sc, "could not create Netgraph node\n");
- return (ENXIO);
- }
-
- /* Name Netgraph node */
- if (ng_name_node(sc->sc_node, device_get_nameunit(dev)) != 0) {
- UBT_ALERT(sc, "could not name Netgraph node\n");
- NG_NODE_UNREF(sc->sc_node);
- return (ENXIO);
- }
- NG_NODE_SET_PRIVATE(sc->sc_node, sc);
- NG_NODE_FORCE_WRITER(sc->sc_node);
-
- /*
- * Initialize device softc structure
- */
-
- /* initialize locks */
- mtx_init(&sc->sc_ng_mtx, "ubt ng", NULL, MTX_DEF);
- mtx_init(&sc->sc_if_mtx, "ubt if", NULL, MTX_DEF | MTX_RECURSE);
-
- /* initialize packet queues */
- NG_BT_MBUFQ_INIT(&sc->sc_cmdq, UBT_DEFAULT_QLEN);
- NG_BT_MBUFQ_INIT(&sc->sc_aclq, UBT_DEFAULT_QLEN);
- NG_BT_MBUFQ_INIT(&sc->sc_scoq, UBT_DEFAULT_QLEN);
-
- /* initialize glue task */
- TASK_INIT(&sc->sc_task, 0, ubt_task, sc);
-
- /*
- * Configure Bluetooth USB device. Discover all required USB
- * interfaces and endpoints.
- *
- * USB device must present two interfaces:
- * 1) Interface 0 that has 3 endpoints
- * 1) Interrupt endpoint to receive HCI events
- * 2) Bulk IN endpoint to receive ACL data
- * 3) Bulk OUT endpoint to send ACL data
- *
- * 2) Interface 1 then has 2 endpoints
- * 1) Isochronous IN endpoint to receive SCO data
- * 2) Isochronous OUT endpoint to send SCO data
- *
- * Interface 1 (with isochronous endpoints) has several alternate
- * configurations with different packet size.
- */
-
- /*
- * For interface #1 search alternate settings, and find
- * the descriptor with the largest wMaxPacketSize
- */
-
- wMaxPacketSize = 0;
- alt_index = 0;
- i = 0;
- j = 0;
-
- /* Search through all the descriptors looking for bidir mode */
- while (1) {
- uint16_t temp;
-
- ed = usb2_find_edesc(usb2_get_config_descriptor(uaa->device),
- 1, i, j);
- if (ed == NULL) {
- if (j != 0) {
- /* next interface */
- j = 0;
- i ++;
- continue;
- }
-
- break; /* end of interfaces */
- }
-
- temp = UGETW(ed->wMaxPacketSize);
- if (temp > wMaxPacketSize) {
- wMaxPacketSize = temp;
- alt_index = i;
- }
-
- j ++;
- }
-
- /* Set alt configuration on interface #1 only if we found it */
- if (wMaxPacketSize > 0 &&
- usb2_set_alt_interface_index(uaa->device, 1, alt_index)) {
- UBT_ALERT(sc, "could not set alternate setting %d " \
- "for interface 1!\n", alt_index);
- goto detach;
- }
-
- /* Setup transfers for both interfaces */
- if (usb2_transfer_setup(uaa->device, iface_index, sc->sc_xfer,
- ubt_config, UBT_N_TRANSFER, sc, &sc->sc_if_mtx)) {
- UBT_ALERT(sc, "could not allocate transfers\n");
- goto detach;
- }
-
- /* Claim all interfaces on the device */
- for (i = 1; usb2_get_iface(uaa->device, i) != NULL; i ++)
- usb2_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
-
- return (0); /* success */
-
-detach:
- ubt_detach(dev);
-
- return (ENXIO);
-} /* ubt_attach */
-
-/*
- * Detach the device.
- * USB context.
- */
-
-int
-ubt_detach(device_t dev)
-{
- struct ubt_softc *sc = device_get_softc(dev);
- node_p node = sc->sc_node;
-
- /* Destroy Netgraph node */
- if (node != NULL) {
- sc->sc_node = NULL;
- NG_NODE_REALLY_DIE(node);
- ng_rmnode_self(node);
- }
-
- /* Make sure ubt_task in gone */
- taskqueue_drain(taskqueue_swi, &sc->sc_task);
-
- /* Free USB transfers, if any */
- usb2_transfer_unsetup(sc->sc_xfer, UBT_N_TRANSFER);
-
- /* Destroy queues */
- UBT_NG_LOCK(sc);
- NG_BT_MBUFQ_DESTROY(&sc->sc_cmdq);
- NG_BT_MBUFQ_DESTROY(&sc->sc_aclq);
- NG_BT_MBUFQ_DESTROY(&sc->sc_scoq);
- UBT_NG_UNLOCK(sc);
-
- mtx_destroy(&sc->sc_if_mtx);
- mtx_destroy(&sc->sc_ng_mtx);
-
- return (0);
-} /* ubt_detach */
-
-/*
- * Called when outgoing control request (HCI command) has completed, i.e.
- * HCI command was sent to the device.
- * USB context.
- */
-
-static void
-ubt_ctrl_write_callback(struct usb2_xfer *xfer)
-{
- struct ubt_softc *sc = xfer->priv_sc;
- struct usb2_device_request req;
- struct mbuf *m;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- UBT_INFO(sc, "sent %d bytes to control pipe\n", xfer->actlen);
- UBT_STAT_BYTES_SENT(sc, xfer->actlen);
- UBT_STAT_PCKTS_SENT(sc);
- /* FALLTHROUGH */
-
- case USB_ST_SETUP:
-send_next:
- /* Get next command mbuf, if any */
- UBT_NG_LOCK(sc);
- NG_BT_MBUFQ_DEQUEUE(&sc->sc_cmdq, m);
- UBT_NG_UNLOCK(sc);
-
- if (m == NULL) {
- UBT_INFO(sc, "HCI command queue is empty\n");
- break; /* transfer complete */
- }
-
- /* Initialize a USB control request and then schedule it */
- bzero(&req, sizeof(req));
- req.bmRequestType = UBT_HCI_REQUEST;
- USETW(req.wLength, m->m_pkthdr.len);
-
- UBT_INFO(sc, "Sending control request, " \
- "bmRequestType=0x%02x, wLength=%d\n",
- req.bmRequestType, UGETW(req.wLength));
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
- usb2_m_copy_in(xfer->frbuffers + 1, 0, m, 0, m->m_pkthdr.len);
-
- xfer->frlengths[0] = sizeof(req);
- xfer->frlengths[1] = m->m_pkthdr.len;
- xfer->nframes = 2;
-
- NG_FREE_M(m);
-
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- UBT_WARN(sc, "control transfer failed: %s\n",
- usb2_errstr(xfer->error));
-
- UBT_STAT_OERROR(sc);
- goto send_next;
- }
-
- /* transfer cancelled */
- break;
- }
-} /* ubt_ctrl_write_callback */
-
-/*
- * Called when incoming interrupt transfer (HCI event) has completed, i.e.
- * HCI event was received from the device.
- * USB context.
- */
-
-static void
-ubt_intr_read_callback(struct usb2_xfer *xfer)
-{
- struct ubt_softc *sc = xfer->priv_sc;
- struct mbuf *m;
- ng_hci_event_pkt_t *hdr;
-
- m = NULL;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- /* Allocate a new mbuf */
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- UBT_STAT_IERROR(sc);
- goto submit_next;
- }
-
- MCLGET(m, M_DONTWAIT);
- if (!(m->m_flags & M_EXT)) {
- UBT_STAT_IERROR(sc);
- goto submit_next;
- }
-
- /* Add HCI packet type */
- *mtod(m, uint8_t *)= NG_HCI_EVENT_PKT;
- m->m_pkthdr.len = m->m_len = 1;
-
- if (xfer->actlen > MCLBYTES - 1)
- xfer->actlen = MCLBYTES - 1;
-
- usb2_copy_out(xfer->frbuffers, 0, mtod(m, uint8_t *) + 1,
- xfer->actlen);
- m->m_pkthdr.len += xfer->actlen;
- m->m_len += xfer->actlen;
-
- UBT_INFO(sc, "got %d bytes from interrupt pipe\n",
- xfer->actlen);
-
- /* Validate packet and send it up the stack */
- if (m->m_pkthdr.len < sizeof(*hdr)) {
- UBT_INFO(sc, "HCI event packet is too short\n");
-
- UBT_STAT_IERROR(sc);
- goto submit_next;
- }
-
- hdr = mtod(m, ng_hci_event_pkt_t *);
- if (hdr->length != (m->m_pkthdr.len - sizeof(*hdr))) {
- UBT_ERR(sc, "Invalid HCI event packet size, " \
- "length=%d, pktlen=%d\n",
- hdr->length, m->m_pkthdr.len);
-
- UBT_STAT_IERROR(sc);
- goto submit_next;
- }
-
- UBT_INFO(sc, "got complete HCI event frame, pktlen=%d, " \
- "length=%d\n", m->m_pkthdr.len, hdr->length);
-
- UBT_STAT_PCKTS_RECV(sc);
- UBT_STAT_BYTES_RECV(sc, m->m_pkthdr.len);
-
- ubt_fwd_mbuf_up(sc, &m);
- /* m == NULL at this point */
- /* FALLTHROUGH */
-
- case USB_ST_SETUP:
-submit_next:
- NG_FREE_M(m); /* checks for m != NULL */
-
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- UBT_WARN(sc, "interrupt transfer failed: %s\n",
- usb2_errstr(xfer->error));
-
- /* Try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto submit_next;
- }
- /* transfer cancelled */
- break;
- }
-} /* ubt_intr_read_callback */
-
-/*
- * Called when incoming bulk transfer (ACL packet) has completed, i.e.
- * ACL packet was received from the device.
- * USB context.
- */
-
-static void
-ubt_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct ubt_softc *sc = xfer->priv_sc;
- struct mbuf *m;
- ng_hci_acldata_pkt_t *hdr;
- uint16_t len;
-
- m = NULL;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- /* Allocate new mbuf */
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- UBT_STAT_IERROR(sc);
- goto submit_next;
- }
-
- MCLGET(m, M_DONTWAIT);
- if (!(m->m_flags & M_EXT)) {
- UBT_STAT_IERROR(sc);
- goto submit_next;
- }
-
- /* Add HCI packet type */
- *mtod(m, uint8_t *)= NG_HCI_ACL_DATA_PKT;
- m->m_pkthdr.len = m->m_len = 1;
-
- if (xfer->actlen > MCLBYTES - 1)
- xfer->actlen = MCLBYTES - 1;
-
- usb2_copy_out(xfer->frbuffers, 0, mtod(m, uint8_t *) + 1,
- xfer->actlen);
- m->m_pkthdr.len += xfer->actlen;
- m->m_len += xfer->actlen;
-
- UBT_INFO(sc, "got %d bytes from bulk-in pipe\n",
- xfer->actlen);
-
- /* Validate packet and send it up the stack */
- if (m->m_pkthdr.len < sizeof(*hdr)) {
- UBT_INFO(sc, "HCI ACL packet is too short\n");
-
- UBT_STAT_IERROR(sc);
- goto submit_next;
- }
-
- hdr = mtod(m, ng_hci_acldata_pkt_t *);
- len = le16toh(hdr->length);
- if (len != (m->m_pkthdr.len - sizeof(*hdr))) {
- UBT_ERR(sc, "Invalid ACL packet size, length=%d, " \
- "pktlen=%d\n", len, m->m_pkthdr.len);
-
- UBT_STAT_IERROR(sc);
- goto submit_next;
- }
-
- UBT_INFO(sc, "got complete ACL data packet, pktlen=%d, " \
- "length=%d\n", m->m_pkthdr.len, len);
-
- UBT_STAT_PCKTS_RECV(sc);
- UBT_STAT_BYTES_RECV(sc, m->m_pkthdr.len);
-
- ubt_fwd_mbuf_up(sc, &m);
- /* m == NULL at this point */
- /* FALLTHOUGH */
-
- case USB_ST_SETUP:
-submit_next:
- NG_FREE_M(m); /* checks for m != NULL */
-
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- UBT_WARN(sc, "bulk-in transfer failed: %s\n",
- usb2_errstr(xfer->error));
-
- /* Try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto submit_next;
- }
- /* transfer cancelled */
- break;
- }
-} /* ubt_bulk_read_callback */
-
-/*
- * Called when outgoing bulk transfer (ACL packet) has completed, i.e.
- * ACL packet was sent to the device.
- * USB context.
- */
-
-static void
-ubt_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct ubt_softc *sc = xfer->priv_sc;
- struct mbuf *m;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- UBT_INFO(sc, "sent %d bytes to bulk-out pipe\n", xfer->actlen);
- UBT_STAT_BYTES_SENT(sc, xfer->actlen);
- UBT_STAT_PCKTS_SENT(sc);
- /* FALLTHROUGH */
-
- case USB_ST_SETUP:
-send_next:
- /* Get next mbuf, if any */
- UBT_NG_LOCK(sc);
- NG_BT_MBUFQ_DEQUEUE(&sc->sc_aclq, m);
- UBT_NG_UNLOCK(sc);
-
- if (m == NULL) {
- UBT_INFO(sc, "ACL data queue is empty\n");
- break; /* transfer completed */
- }
-
- /*
- * Copy ACL data frame back to a linear USB transfer buffer
- * and schedule transfer
- */
-
- usb2_m_copy_in(xfer->frbuffers, 0, m, 0, m->m_pkthdr.len);
- xfer->frlengths[0] = m->m_pkthdr.len;
-
- UBT_INFO(sc, "bulk-out transfer has been started, len=%d\n",
- m->m_pkthdr.len);
-
- NG_FREE_M(m);
-
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- UBT_WARN(sc, "bulk-out transfer failed: %s\n",
- usb2_errstr(xfer->error));
-
- UBT_STAT_OERROR(sc);
-
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto send_next;
- }
- /* transfer cancelled */
- break;
- }
-} /* ubt_bulk_write_callback */
-
-/*
- * Called when incoming isoc transfer (SCO packet) has completed, i.e.
- * SCO packet was received from the device.
- * USB context.
- */
-
-static void
-ubt_isoc_read_callback(struct usb2_xfer *xfer)
-{
- struct ubt_softc *sc = xfer->priv_sc;
- int n;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- for (n = 0; n < xfer->nframes; n ++)
- if (ubt_isoc_read_one_frame(xfer, n) < 0)
- break;
- /* FALLTHROUGH */
-
- case USB_ST_SETUP:
-read_next:
- for (n = 0; n < xfer->nframes; n ++)
- xfer->frlengths[n] = xfer->max_frame_size;
-
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- UBT_STAT_IERROR(sc);
- goto read_next;
- }
-
- /* transfer cancelled */
- break;
- }
-} /* ubt_isoc_read_callback */
-
-/*
- * Helper function. Called from ubt_isoc_read_callback() to read
- * SCO data from one frame.
- * USB context.
- */
-
-static int
-ubt_isoc_read_one_frame(struct usb2_xfer *xfer, int frame_no)
-{
- struct ubt_softc *sc = xfer->priv_sc;
- struct mbuf *m;
- int len, want, got;
-
- /* Get existing SCO reassembly buffer */
- m = sc->sc_isoc_in_buffer;
- sc->sc_isoc_in_buffer = NULL;
-
- /* While we have data in the frame */
- while ((len = xfer->frlengths[frame_no]) > 0) {
- if (m == NULL) {
- /* Start new reassembly buffer */
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- UBT_STAT_IERROR(sc);
- return (-1); /* XXX out of sync! */
- }
-
- MCLGET(m, M_DONTWAIT);
- if (!(m->m_flags & M_EXT)) {
- UBT_STAT_IERROR(sc);
- NG_FREE_M(m);
- return (-1); /* XXX out of sync! */
- }
-
- /* Expect SCO header */
- *mtod(m, uint8_t *) = NG_HCI_SCO_DATA_PKT;
- m->m_pkthdr.len = m->m_len = got = 1;
- want = sizeof(ng_hci_scodata_pkt_t);
- } else {
- /*
- * Check if we have SCO header and if so
- * adjust amount of data we want
- */
- got = m->m_pkthdr.len;
- want = sizeof(ng_hci_scodata_pkt_t);
-
- if (got >= want)
- want += mtod(m, ng_hci_scodata_pkt_t *)->length;
- }
-
- /* Append frame data to the SCO reassembly buffer */
- if (got + len > want)
- len = want - got;
-
- usb2_copy_out(xfer->frbuffers, frame_no * xfer->max_frame_size,
- mtod(m, uint8_t *) + m->m_pkthdr.len, len);
-
- m->m_pkthdr.len += len;
- m->m_len += len;
- xfer->frlengths[frame_no] -= len;
-
- /* Check if we got everything we wanted, if not - continue */
- if (got != want)
- continue;
-
- /* If we got here then we got complete SCO frame */
- UBT_INFO(sc, "got complete SCO data frame, pktlen=%d, " \
- "length=%d\n", m->m_pkthdr.len,
- mtod(m, ng_hci_scodata_pkt_t *)->length);
-
- UBT_STAT_PCKTS_RECV(sc);
- UBT_STAT_BYTES_RECV(sc, m->m_pkthdr.len);
-
- ubt_fwd_mbuf_up(sc, &m);
- /* m == NULL at this point */
- }
-
- /* Put SCO reassembly buffer back */
- sc->sc_isoc_in_buffer = m;
-
- return (0);
-} /* ubt_isoc_read_one_frame */
-
-/*
- * Called when outgoing isoc transfer (SCO packet) has completed, i.e.
- * SCO packet was sent to the device.
- * USB context.
- */
-
-static void
-ubt_isoc_write_callback(struct usb2_xfer *xfer)
-{
- struct ubt_softc *sc = xfer->priv_sc;
- struct mbuf *m;
- int n, space, offset;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- UBT_INFO(sc, "sent %d bytes to isoc-out pipe\n", xfer->actlen);
- UBT_STAT_BYTES_SENT(sc, xfer->actlen);
- UBT_STAT_PCKTS_SENT(sc);
- /* FALLTHROUGH */
-
- case USB_ST_SETUP:
-send_next:
- offset = 0;
- space = xfer->max_frame_size * xfer->nframes;
- m = NULL;
-
- while (space > 0) {
- if (m == NULL) {
- UBT_NG_LOCK(sc);
- NG_BT_MBUFQ_DEQUEUE(&sc->sc_scoq, m);
- UBT_NG_UNLOCK(sc);
-
- if (m == NULL)
- break;
- }
-
- n = min(space, m->m_pkthdr.len);
- if (n > 0) {
- usb2_m_copy_in(xfer->frbuffers, offset, m,0, n);
- m_adj(m, n);
-
- offset += n;
- space -= n;
- }
-
- if (m->m_pkthdr.len == 0)
- NG_FREE_M(m); /* sets m = NULL */
- }
-
- /* Put whatever is left from mbuf back on queue */
- if (m != NULL) {
- UBT_NG_LOCK(sc);
- NG_BT_MBUFQ_PREPEND(&sc->sc_scoq, m);
- UBT_NG_UNLOCK(sc);
- }
-
- /*
- * Calculate sizes for isoc frames.
- * Note that offset could be 0 at this point (i.e. we have
- * nothing to send). That is fine, as we have isoc. transfers
- * going in both directions all the time. In this case it
- * would be just empty isoc. transfer.
- */
-
- for (n = 0; n < xfer->nframes; n ++) {
- xfer->frlengths[n] = min(offset, xfer->max_frame_size);
- offset -= xfer->frlengths[n];
- }
-
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- UBT_STAT_OERROR(sc);
- goto send_next;
- }
-
- /* transfer cancelled */
- break;
- }
-}
-
-/*
- * Utility function to forward provided mbuf upstream (i.e. up the stack).
- * Modifies value of the mbuf pointer (sets it to NULL).
- * Save to call from any context.
- */
-
-static int
-ubt_fwd_mbuf_up(ubt_softc_p sc, struct mbuf **m)
-{
- hook_p hook;
- int error;
-
- /*
- * Close the race with Netgraph hook newhook/disconnect methods.
- * Save the hook pointer atomically. Two cases are possible:
- *
- * 1) The hook pointer is NULL. It means disconnect method got
- * there first. In this case we are done.
- *
- * 2) The hook pointer is not NULL. It means that hook pointer
- * could be either in valid or invalid (i.e. in the process
- * of disconnect) state. In any case grab an extra reference
- * to protect the hook pointer.
- *
- * It is ok to pass hook in invalid state to NG_SEND_DATA_ONLY() as
- * it checks for it. Drop extra reference after NG_SEND_DATA_ONLY().
- */
-
- UBT_NG_LOCK(sc);
- if ((hook = sc->sc_hook) != NULL)
- NG_HOOK_REF(hook);
- UBT_NG_UNLOCK(sc);
-
- if (hook == NULL) {
- NG_FREE_M(*m);
- return (ENETDOWN);
- }
-
- NG_SEND_DATA_ONLY(error, hook, *m);
- NG_HOOK_UNREF(hook);
-
- if (error != 0)
- UBT_STAT_IERROR(sc);
-
- return (error);
-} /* ubt_fwd_mbuf_up */
-
-/****************************************************************************
- ****************************************************************************
- ** Glue
- ****************************************************************************
- ****************************************************************************/
-
-/*
- * Schedule glue task. Should be called with sc_ng_mtx held.
- * Netgraph context.
- */
-
-static void
-ubt_task_schedule(ubt_softc_p sc, int action)
-{
- mtx_assert(&sc->sc_ng_mtx, MA_OWNED);
-
- /*
- * Try to handle corner case when "start all" and "stop all"
- * actions can both be set before task is executed.
- *
- * The rules are
- *
- * sc_task_flags action new sc_task_flags
- * ------------------------------------------------------
- * 0 start start
- * 0 stop stop
- * start start start
- * start stop stop
- * stop start stop|start
- * stop stop stop
- * stop|start start stop|start
- * stop|start stop stop
- */
-
- if (action != 0) {
- if ((action & UBT_FLAG_T_STOP_ALL) != 0)
- sc->sc_task_flags &= ~UBT_FLAG_T_START_ALL;
-
- sc->sc_task_flags |= action;
- }
-
- if (sc->sc_task_flags & UBT_FLAG_T_PENDING)
- return;
-
- if (taskqueue_enqueue(taskqueue_swi, &sc->sc_task) == 0) {
- sc->sc_task_flags |= UBT_FLAG_T_PENDING;
- return;
- }
-
- /* XXX: i think this should never happen */
-} /* ubt_task_schedule */
-
-/*
- * Glue task. Examines sc_task_flags and does things depending on it.
- * Taskqueue context.
- */
-
-static void
-ubt_task(void *context, int pending)
-{
- ubt_softc_p sc = context;
- int task_flags, i;
-
- UBT_NG_LOCK(sc);
- task_flags = sc->sc_task_flags;
- sc->sc_task_flags = 0;
- UBT_NG_UNLOCK(sc);
-
- /*
- * Stop all USB transfers synchronously.
- * Stop interface #0 and #1 transfers at the same time and in the
- * same loop. usb2_transfer_drain() will do appropriate locking.
- */
-
- if (task_flags & UBT_FLAG_T_STOP_ALL)
- for (i = 0; i < UBT_N_TRANSFER; i ++)
- usb2_transfer_drain(sc->sc_xfer[i]);
-
- /* Start incoming interrupt and bulk, and all isoc. USB transfers */
- if (task_flags & UBT_FLAG_T_START_ALL) {
- /*
- * Interface #0
- */
-
- mtx_lock(&sc->sc_if_mtx);
-
- ubt_xfer_start(sc, UBT_IF_0_INTR_DT_RD);
- ubt_xfer_start(sc, UBT_IF_0_BULK_DT_RD);
-
- /*
- * Interface #1
- * Start both read and write isoc. transfers by default.
- * Get them going all the time even if we have nothing
- * to send to avoid any delays.
- */
-
- ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_RD1);
- ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_RD2);
- ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_WR1);
- ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_WR2);
-
- mtx_unlock(&sc->sc_if_mtx);
- }
-
- /* Start outgoing control transfer */
- if (task_flags & UBT_FLAG_T_START_CTRL) {
- mtx_lock(&sc->sc_if_mtx);
- ubt_xfer_start(sc, UBT_IF_0_CTRL_DT_WR);
- mtx_unlock(&sc->sc_if_mtx);
- }
-
- /* Start outgoing bulk transfer */
- if (task_flags & UBT_FLAG_T_START_BULK) {
- mtx_lock(&sc->sc_if_mtx);
- ubt_xfer_start(sc, UBT_IF_0_BULK_DT_WR);
- mtx_unlock(&sc->sc_if_mtx);
- }
-} /* ubt_task */
-
-/****************************************************************************
- ****************************************************************************
- ** Netgraph specific
- ****************************************************************************
- ****************************************************************************/
-
-/*
- * Netgraph node constructor. Do not allow to create node of this type.
- * Netgraph context.
- */
-
-static int
-ng_ubt_constructor(node_p node)
-{
- return (EINVAL);
-} /* ng_ubt_constructor */
-
-/*
- * Netgraph node destructor. Destroy node only when device has been detached.
- * Netgraph context.
- */
-
-static int
-ng_ubt_shutdown(node_p node)
-{
- if (node->nd_flags & NGF_REALLY_DIE) {
- /*
- * We came here because the USB device is being
- * detached, so stop being persistant.
- */
- NG_NODE_SET_PRIVATE(node, NULL);
- NG_NODE_UNREF(node);
- } else
- NG_NODE_REVIVE(node); /* tell ng_rmnode we are persisant */
-
- return (0);
-} /* ng_ubt_shutdown */
-
-/*
- * Create new hook. There can only be one.
- * Netgraph context.
- */
-
-static int
-ng_ubt_newhook(node_p node, hook_p hook, char const *name)
-{
- struct ubt_softc *sc = NG_NODE_PRIVATE(node);
-
- if (strcmp(name, NG_UBT_HOOK) != 0)
- return (EINVAL);
-
- UBT_NG_LOCK(sc);
- if (sc->sc_hook != NULL) {
- UBT_NG_UNLOCK(sc);
-
- return (EISCONN);
- }
-
- sc->sc_hook = hook;
- UBT_NG_UNLOCK(sc);
-
- return (0);
-} /* ng_ubt_newhook */
-
-/*
- * Connect hook. Start incoming USB transfers.
- * Netgraph context.
- */
-
-static int
-ng_ubt_connect(hook_p hook)
-{
- struct ubt_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
-
- NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
-
- UBT_NG_LOCK(sc);
- ubt_task_schedule(sc, UBT_FLAG_T_START_ALL);
- UBT_NG_UNLOCK(sc);
-
- return (0);
-} /* ng_ubt_connect */
-
-/*
- * Disconnect hook.
- * Netgraph context.
- */
-
-static int
-ng_ubt_disconnect(hook_p hook)
-{
- struct ubt_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
-
- UBT_NG_LOCK(sc);
-
- if (hook != sc->sc_hook) {
- UBT_NG_UNLOCK(sc);
-
- return (EINVAL);
- }
-
- sc->sc_hook = NULL;
-
- /* Kick off task to stop all USB xfers */
- ubt_task_schedule(sc, UBT_FLAG_T_STOP_ALL);
-
- /* Drain queues */
- NG_BT_MBUFQ_DRAIN(&sc->sc_cmdq);
- NG_BT_MBUFQ_DRAIN(&sc->sc_aclq);
- NG_BT_MBUFQ_DRAIN(&sc->sc_scoq);
-
- UBT_NG_UNLOCK(sc);
-
- return (0);
-} /* ng_ubt_disconnect */
-
-/*
- * Process control message.
- * Netgraph context.
- */
-
-static int
-ng_ubt_rcvmsg(node_p node, item_p item, hook_p lasthook)
-{
- struct ubt_softc *sc = NG_NODE_PRIVATE(node);
- struct ng_mesg *msg, *rsp = NULL;
- struct ng_bt_mbufq *q;
- int error = 0, queue, qlen;
-
- NGI_GET_MSG(item, msg);
-
- switch (msg->header.typecookie) {
- case NGM_GENERIC_COOKIE:
- switch (msg->header.cmd) {
- case NGM_TEXT_STATUS:
- NG_MKRESPONSE(rsp, msg, NG_TEXTRESPONSE, M_NOWAIT);
- if (rsp == NULL) {
- error = ENOMEM;
- break;
- }
-
- snprintf(rsp->data, NG_TEXTRESPONSE,
- "Hook: %s\n" \
- "Task flags: %#x\n" \
- "Debug: %d\n" \
- "CMD queue: [have:%d,max:%d]\n" \
- "ACL queue: [have:%d,max:%d]\n" \
- "SCO queue: [have:%d,max:%d]",
- (sc->sc_hook != NULL) ? NG_UBT_HOOK : "",
- sc->sc_task_flags,
- sc->sc_debug,
- sc->sc_cmdq.len,
- sc->sc_cmdq.maxlen,
- sc->sc_aclq.len,
- sc->sc_aclq.maxlen,
- sc->sc_scoq.len,
- sc->sc_scoq.maxlen);
- break;
-
- default:
- error = EINVAL;
- break;
- }
- break;
-
- case NGM_UBT_COOKIE:
- switch (msg->header.cmd) {
- case NGM_UBT_NODE_SET_DEBUG:
- if (msg->header.arglen != sizeof(ng_ubt_node_debug_ep)){
- error = EMSGSIZE;
- break;
- }
-
- sc->sc_debug = *((ng_ubt_node_debug_ep *) (msg->data));
- break;
-
- case NGM_UBT_NODE_GET_DEBUG:
- NG_MKRESPONSE(rsp, msg, sizeof(ng_ubt_node_debug_ep),
- M_NOWAIT);
- if (rsp == NULL) {
- error = ENOMEM;
- break;
- }
-
- *((ng_ubt_node_debug_ep *) (rsp->data)) = sc->sc_debug;
- break;
-
- case NGM_UBT_NODE_SET_QLEN:
- if (msg->header.arglen != sizeof(ng_ubt_node_qlen_ep)) {
- error = EMSGSIZE;
- break;
- }
-
- queue = ((ng_ubt_node_qlen_ep *) (msg->data))->queue;
- qlen = ((ng_ubt_node_qlen_ep *) (msg->data))->qlen;
-
- switch (queue) {
- case NGM_UBT_NODE_QUEUE_CMD:
- q = &sc->sc_cmdq;
- break;
-
- case NGM_UBT_NODE_QUEUE_ACL:
- q = &sc->sc_aclq;
- break;
-
- case NGM_UBT_NODE_QUEUE_SCO:
- q = &sc->sc_scoq;
- break;
-
- default:
- error = EINVAL;
- goto done;
- /* NOT REACHED */
- }
-
- q->maxlen = qlen;
- break;
-
- case NGM_UBT_NODE_GET_QLEN:
- if (msg->header.arglen != sizeof(ng_ubt_node_qlen_ep)) {
- error = EMSGSIZE;
- break;
- }
-
- queue = ((ng_ubt_node_qlen_ep *) (msg->data))->queue;
-
- switch (queue) {
- case NGM_UBT_NODE_QUEUE_CMD:
- q = &sc->sc_cmdq;
- break;
-
- case NGM_UBT_NODE_QUEUE_ACL:
- q = &sc->sc_aclq;
- break;
-
- case NGM_UBT_NODE_QUEUE_SCO:
- q = &sc->sc_scoq;
- break;
-
- default:
- error = EINVAL;
- goto done;
- /* NOT REACHED */
- }
-
- NG_MKRESPONSE(rsp, msg, sizeof(ng_ubt_node_qlen_ep),
- M_NOWAIT);
- if (rsp == NULL) {
- error = ENOMEM;
- break;
- }
-
- ((ng_ubt_node_qlen_ep *) (rsp->data))->queue = queue;
- ((ng_ubt_node_qlen_ep *) (rsp->data))->qlen = q->maxlen;
- break;
-
- case NGM_UBT_NODE_GET_STAT:
- NG_MKRESPONSE(rsp, msg, sizeof(ng_ubt_node_stat_ep),
- M_NOWAIT);
- if (rsp == NULL) {
- error = ENOMEM;
- break;
- }
-
- bcopy(&sc->sc_stat, rsp->data,
- sizeof(ng_ubt_node_stat_ep));
- break;
-
- case NGM_UBT_NODE_RESET_STAT:
- UBT_STAT_RESET(sc);
- break;
-
- default:
- error = EINVAL;
- break;
- }
- break;
-
- default:
- error = EINVAL;
- break;
- }
-done:
- NG_RESPOND_MSG(error, node, item, rsp);
- NG_FREE_MSG(msg);
-
- return (error);
-} /* ng_ubt_rcvmsg */
-
-/*
- * Process data.
- * Netgraph context.
- */
-
-static int
-ng_ubt_rcvdata(hook_p hook, item_p item)
-{
- struct ubt_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- struct mbuf *m;
- struct ng_bt_mbufq *q;
- int action, error = 0;
-
- if (hook != sc->sc_hook) {
- error = EINVAL;
- goto done;
- }
-
- /* Deatch mbuf and get HCI frame type */
- NGI_GET_M(item, m);
-
- /*
- * Minimal size of the HCI frame is 4 bytes: 1 byte frame type,
- * 2 bytes connection handle and at least 1 byte of length.
- * Panic on data frame that has size smaller than 4 bytes (it
- * should not happen)
- */
-
- if (m->m_pkthdr.len < 4)
- panic("HCI frame size is too small! pktlen=%d\n",
- m->m_pkthdr.len);
-
- /* Process HCI frame */
- switch (*mtod(m, uint8_t *)) { /* XXX call m_pullup ? */
- case NG_HCI_CMD_PKT:
- if (m->m_pkthdr.len - 1 > UBT_CTRL_BUFFER_SIZE)
- panic("HCI command frame size is too big! " \
- "buffer size=%zd, packet len=%d\n",
- UBT_CTRL_BUFFER_SIZE, m->m_pkthdr.len);
-
- q = &sc->sc_cmdq;
- action = UBT_FLAG_T_START_CTRL;
- break;
-
- case NG_HCI_ACL_DATA_PKT:
- if (m->m_pkthdr.len - 1 > UBT_BULK_WRITE_BUFFER_SIZE)
- panic("ACL data frame size is too big! " \
- "buffer size=%d, packet len=%d\n",
- UBT_BULK_WRITE_BUFFER_SIZE, m->m_pkthdr.len);
-
- q = &sc->sc_aclq;
- action = UBT_FLAG_T_START_BULK;
- break;
-
- case NG_HCI_SCO_DATA_PKT:
- q = &sc->sc_scoq;
- action = 0;
- break;
-
- default:
- UBT_ERR(sc, "Dropping unsupported HCI frame, type=0x%02x, " \
- "pktlen=%d\n", *mtod(m, uint8_t *), m->m_pkthdr.len);
-
- NG_FREE_M(m);
- error = EINVAL;
- goto done;
- /* NOT REACHED */
- }
-
- UBT_NG_LOCK(sc);
- if (NG_BT_MBUFQ_FULL(q)) {
- NG_BT_MBUFQ_DROP(q);
- UBT_NG_UNLOCK(sc);
-
- UBT_ERR(sc, "Dropping HCI frame 0x%02x, len=%d. Queue full\n",
- *mtod(m, uint8_t *), m->m_pkthdr.len);
-
- NG_FREE_M(m);
- } else {
- /* Loose HCI packet type, enqueue mbuf and kick off task */
- m_adj(m, sizeof(uint8_t));
- NG_BT_MBUFQ_ENQUEUE(q, m);
- ubt_task_schedule(sc, action);
- UBT_NG_UNLOCK(sc);
- }
-done:
- NG_FREE_ITEM(item);
-
- return (error);
-} /* ng_ubt_rcvdata */
-
-/****************************************************************************
- ****************************************************************************
- ** Module
- ****************************************************************************
- ****************************************************************************/
-
-/*
- * Load/Unload the driver module
- */
-
-static int
-ubt_modevent(module_t mod, int event, void *data)
-{
- int error;
-
- switch (event) {
- case MOD_LOAD:
- error = ng_newtype(&typestruct);
- if (error != 0)
- printf("%s: Could not register Netgraph node type, " \
- "error=%d\n", NG_UBT_NODE_TYPE, error);
- break;
-
- case MOD_UNLOAD:
- error = ng_rmtype(&typestruct);
- break;
-
- default:
- error = EOPNOTSUPP;
- break;
- }
-
- return (error);
-} /* ubt_modevent */
-
-static devclass_t ubt_devclass;
-
-static device_method_t ubt_methods[] =
-{
- DEVMETHOD(device_probe, ubt_probe),
- DEVMETHOD(device_attach, ubt_attach),
- DEVMETHOD(device_detach, ubt_detach),
- { 0, 0 }
-};
-
-static driver_t ubt_driver =
-{
- .name = "ubt",
- .methods = ubt_methods,
- .size = sizeof(struct ubt_softc),
-};
-
-DRIVER_MODULE(ng_ubt, ushub, ubt_driver, ubt_devclass, ubt_modevent, 0);
-MODULE_VERSION(ng_ubt, NG_BLUETOOTH_VERSION);
-MODULE_DEPEND(ng_ubt, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
-MODULE_DEPEND(ng_ubt, ng_hci, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
-MODULE_DEPEND(ng_ubt, usb2_bluetooth, 1, 1, 1);
-MODULE_DEPEND(ng_ubt, usb2_core, 1, 1, 1);
-
diff --git a/sys/dev/usb2/bluetooth/ng_ubt2_var.h b/sys/dev/usb2/bluetooth/ng_ubt2_var.h
deleted file mode 100644
index 721e2f1..0000000
--- a/sys/dev/usb2/bluetooth/ng_ubt2_var.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * ng_ubt_var.h
- */
-
-/*-
- * Copyright (c) 2001-2009 Maksim Yevmenkin <m_evmenkin@yahoo.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 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.
- *
- * $Id: ng_ubt_var.h,v 1.2 2003/03/22 23:44:36 max Exp $
- * $FreeBSD$
- */
-
-#ifndef _NG_UBT_VAR_H_
-#define _NG_UBT_VAR_H_ 1
-
-/* Debug printf's */
-#define UBT_DEBUG(level, sc, fmt, ...) \
-do { \
- if ((sc)->sc_debug >= (level)) \
- device_printf((sc)->sc_dev, "%s:%d: " fmt, \
- __FUNCTION__, __LINE__,## __VA_ARGS__); \
-} while (0)
-
-#define UBT_ALERT(...) UBT_DEBUG(NG_UBT_ALERT_LEVEL, __VA_ARGS__)
-#define UBT_ERR(...) UBT_DEBUG(NG_UBT_ERR_LEVEL, __VA_ARGS__)
-#define UBT_WARN(...) UBT_DEBUG(NG_UBT_WARN_LEVEL, __VA_ARGS__)
-#define UBT_INFO(...) UBT_DEBUG(NG_UBT_INFO_LEVEL, __VA_ARGS__)
-
-#define UBT_NG_LOCK(sc) mtx_lock(&(sc)->sc_ng_mtx)
-#define UBT_NG_UNLOCK(sc) mtx_unlock(&(sc)->sc_ng_mtx)
-
-/* Bluetooth USB control request type */
-#define UBT_HCI_REQUEST 0x20
-#define UBT_DEFAULT_QLEN 64
-#define UBT_ISOC_NFRAMES 32 /* should be factor of 8 */
-
-/* Bluetooth USB defines */
-enum {
- /* Interface #0 transfers */
- UBT_IF_0_BULK_DT_WR = 0,
- UBT_IF_0_BULK_DT_RD,
- UBT_IF_0_INTR_DT_RD,
- UBT_IF_0_CTRL_DT_WR,
-
- /* Interface #1 transfers */
- UBT_IF_1_ISOC_DT_RD1,
- UBT_IF_1_ISOC_DT_RD2,
- UBT_IF_1_ISOC_DT_WR1,
- UBT_IF_1_ISOC_DT_WR2,
-
- UBT_N_TRANSFER, /* total number of transfers */
-};
-
-/* USB device softc structure */
-struct ubt_softc {
- device_t sc_dev; /* for debug printf */
-
- /* State */
- ng_ubt_node_debug_ep sc_debug; /* debug level */
-
- ng_ubt_node_stat_ep sc_stat; /* statistic */
-#define UBT_STAT_PCKTS_SENT(sc) (sc)->sc_stat.pckts_sent ++
-#define UBT_STAT_BYTES_SENT(sc, n) (sc)->sc_stat.bytes_sent += (n)
-#define UBT_STAT_PCKTS_RECV(sc) (sc)->sc_stat.pckts_recv ++
-#define UBT_STAT_BYTES_RECV(sc, n) (sc)->sc_stat.bytes_recv += (n)
-#define UBT_STAT_OERROR(sc) (sc)->sc_stat.oerrors ++
-#define UBT_STAT_IERROR(sc) (sc)->sc_stat.ierrors ++
-#define UBT_STAT_RESET(sc) bzero(&(sc)->sc_stat, sizeof((sc)->sc_stat))
-
- /* USB device specific */
- struct mtx sc_if_mtx; /* interfaces lock */
- struct usb2_xfer *sc_xfer[UBT_N_TRANSFER];
-
- struct mtx sc_ng_mtx; /* lock for shared NG data */
-
- /* HCI commands */
- struct ng_bt_mbufq sc_cmdq; /* HCI command queue */
-#define UBT_CTRL_BUFFER_SIZE (sizeof(struct usb2_device_request) + \
- sizeof(ng_hci_cmd_pkt_t) + NG_HCI_CMD_PKT_SIZE)
-#define UBT_INTR_BUFFER_SIZE (MCLBYTES-1) /* reserve 1 byte for ID-tag */
-
- /* ACL data */
- struct ng_bt_mbufq sc_aclq; /* ACL data queue */
-#define UBT_BULK_READ_BUFFER_SIZE (MCLBYTES-1) /* reserve 1 byte for ID-tag */
-#define UBT_BULK_WRITE_BUFFER_SIZE (MCLBYTES)
-
- /* SCO data */
- struct ng_bt_mbufq sc_scoq; /* SCO data queue */
- struct mbuf *sc_isoc_in_buffer; /* SCO reassembly buffer */
-
- /* Netgraph specific */
- node_p sc_node; /* pointer back to node */
- hook_p sc_hook; /* upstream hook */
-
- /* Glue */
- int sc_task_flags; /* task flags */
-#define UBT_FLAG_T_PENDING (1 << 0) /* task pending */
-#define UBT_FLAG_T_STOP_ALL (1 << 1) /* stop all xfers */
-#define UBT_FLAG_T_START_ALL (1 << 2) /* start all read and isoc
- write xfers */
-#define UBT_FLAG_T_START_CTRL (1 << 3) /* start control xfer (write) */
-#define UBT_FLAG_T_START_BULK (1 << 4) /* start bulk xfer (write) */
-
- struct task sc_task;
-};
-typedef struct ubt_softc ubt_softc_t;
-typedef struct ubt_softc * ubt_softc_p;
-
-#endif /* ndef _NG_UBT_VAR_H_ */
-
diff --git a/sys/dev/usb2/bluetooth/ubtbcmfw2.c b/sys/dev/usb2/bluetooth/ubtbcmfw2.c
deleted file mode 100644
index 91735ed..0000000
--- a/sys/dev/usb2/bluetooth/ubtbcmfw2.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * ubtbcmfw.c
- */
-
-/*-
- * Copyright (c) 2003-2009 Maksim Yevmenkin <m_evmenkin@yahoo.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 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.
- *
- * $Id: ubtbcmfw.c,v 1.3 2003/10/10 19:15:08 max Exp $
- * $FreeBSD$
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_parse.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-#include <dev/usb2/core/usb2_dev.h>
-
-/*
- * Download firmware to BCM2033.
- */
-
-#define UBTBCMFW_CONFIG_NO 1 /* Config number */
-#define UBTBCMFW_IFACE_IDX 0 /* Control interface */
-
-#define UBTBCMFW_BSIZE 1024
-#define UBTBCMFW_IFQ_MAXLEN 2
-
-enum {
- UBTBCMFW_BULK_DT_WR = 0,
- UBTBCMFW_INTR_DT_RD,
- UBTBCMFW_N_TRANSFER,
-};
-
-struct ubtbcmfw_softc {
- struct usb2_device *sc_udev;
- struct mtx sc_mtx;
- struct usb2_xfer *sc_xfer[UBTBCMFW_N_TRANSFER];
- struct usb2_fifo_sc sc_fifo;
-};
-
-/*
- * Prototypes
- */
-
-static device_probe_t ubtbcmfw_probe;
-static device_attach_t ubtbcmfw_attach;
-static device_detach_t ubtbcmfw_detach;
-
-static usb2_callback_t ubtbcmfw_write_callback;
-static usb2_callback_t ubtbcmfw_read_callback;
-
-static usb2_fifo_close_t ubtbcmfw_close;
-static usb2_fifo_cmd_t ubtbcmfw_start_read;
-static usb2_fifo_cmd_t ubtbcmfw_start_write;
-static usb2_fifo_cmd_t ubtbcmfw_stop_read;
-static usb2_fifo_cmd_t ubtbcmfw_stop_write;
-static usb2_fifo_ioctl_t ubtbcmfw_ioctl;
-static usb2_fifo_open_t ubtbcmfw_open;
-
-static struct usb2_fifo_methods ubtbcmfw_fifo_methods =
-{
- .f_close = &ubtbcmfw_close,
- .f_ioctl = &ubtbcmfw_ioctl,
- .f_open = &ubtbcmfw_open,
- .f_start_read = &ubtbcmfw_start_read,
- .f_start_write = &ubtbcmfw_start_write,
- .f_stop_read = &ubtbcmfw_stop_read,
- .f_stop_write = &ubtbcmfw_stop_write,
- .basename[0] = "ubtbcmfw",
- .basename[1] = "ubtbcmfw",
- .basename[2] = "ubtbcmfw",
- .postfix[0] = "",
- .postfix[1] = ".1",
- .postfix[2] = ".2",
-};
-
-/*
- * Device's config structure
- */
-
-static const struct usb2_config ubtbcmfw_config[UBTBCMFW_N_TRANSFER] =
-{
- [UBTBCMFW_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = 0x02, /* fixed */
- .direction = UE_DIR_OUT,
- .if_index = UBTBCMFW_IFACE_IDX,
- .mh.bufsize = UBTBCMFW_BSIZE,
- .mh.flags = { .pipe_bof = 1, .force_short_xfer = 1,
- .proxy_buffer = 1, },
- .mh.callback = &ubtbcmfw_write_callback,
- },
-
- [UBTBCMFW_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = 0x01, /* fixed */
- .direction = UE_DIR_IN,
- .if_index = UBTBCMFW_IFACE_IDX,
- .mh.bufsize = UBTBCMFW_BSIZE,
- .mh.flags = { .pipe_bof = 1, .short_xfer_ok = 1,
- .proxy_buffer = 1, },
- .mh.callback = &ubtbcmfw_read_callback,
- },
-};
-
-/*
- * Module
- */
-
-static devclass_t ubtbcmfw_devclass;
-
-static device_method_t ubtbcmfw_methods[] =
-{
- DEVMETHOD(device_probe, ubtbcmfw_probe),
- DEVMETHOD(device_attach, ubtbcmfw_attach),
- DEVMETHOD(device_detach, ubtbcmfw_detach),
- {0, 0}
-};
-
-static driver_t ubtbcmfw_driver =
-{
- .name = "ubtbcmfw",
- .methods = ubtbcmfw_methods,
- .size = sizeof(struct ubtbcmfw_softc),
-};
-
-DRIVER_MODULE(ubtbcmfw, ushub, ubtbcmfw_driver, ubtbcmfw_devclass, NULL, 0);
-MODULE_DEPEND(ubtbcmfw, usb2_bluetooth, 1, 1, 1);
-MODULE_DEPEND(ubtbcmfw, usb2_core, 1, 1, 1);
-
-/*
- * Probe for a USB Bluetooth device
- */
-
-static int
-ubtbcmfw_probe(device_t dev)
-{
- const struct usb2_device_id devs[] = {
- /* Broadcom BCM2033 devices only */
- { USB_VPI(USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033, 0) },
- };
-
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
-
- if (uaa->info.bIfaceIndex != 0)
- return (ENXIO);
-
- return (usb2_lookup_id_by_uaa(devs, sizeof(devs), uaa));
-} /* ubtbcmfw_probe */
-
-/*
- * Attach the device
- */
-
-static int
-ubtbcmfw_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ubtbcmfw_softc *sc = device_get_softc(dev);
- uint8_t iface_index;
- int error;
-
- sc->sc_udev = uaa->device;
-
- device_set_usb2_desc(dev);
-
- mtx_init(&sc->sc_mtx, "ubtbcmfw lock", NULL, MTX_DEF | MTX_RECURSE);
-
- iface_index = UBTBCMFW_IFACE_IDX;
- error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
- ubtbcmfw_config, UBTBCMFW_N_TRANSFER,
- sc, &sc->sc_mtx);
- if (error != 0) {
- device_printf(dev, "allocating USB transfers failed. %s\n",
- usb2_errstr(error));
- goto detach;
- }
-
- /* Set interface permissions */
- usb2_set_iface_perm(uaa->device, uaa->info.bIfaceIndex,
- UID_ROOT, GID_OPERATOR, 0644);
-
- error = usb2_fifo_attach(uaa->device, sc, &sc->sc_mtx,
- &ubtbcmfw_fifo_methods, &sc->sc_fifo,
- device_get_unit(dev), 0 - 1, uaa->info.bIfaceIndex);
- if (error != 0) {
- device_printf(dev, "could not attach fifo. %s\n",
- usb2_errstr(error));
- goto detach;
- }
-
- return (0); /* success */
-
-detach:
- ubtbcmfw_detach(dev);
-
- return (ENXIO); /* failure */
-} /* ubtbcmfw_attach */
-
-/*
- * Detach the device
- */
-
-static int
-ubtbcmfw_detach(device_t dev)
-{
- struct ubtbcmfw_softc *sc = device_get_softc(dev);
-
- usb2_fifo_detach(&sc->sc_fifo);
-
- usb2_transfer_unsetup(sc->sc_xfer, UBTBCMFW_N_TRANSFER);
-
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-} /* ubtbcmfw_detach */
-
-/*
- * USB write callback
- */
-
-static void
-ubtbcmfw_write_callback(struct usb2_xfer *xfer)
-{
- struct ubtbcmfw_softc *sc = xfer->priv_sc;
- struct usb2_fifo *f = sc->sc_fifo.fp[USB_FIFO_TX];
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-setup_next:
- if (usb2_fifo_get_data(f, xfer->frbuffers, 0,
- xfer->max_data_length, &actlen, 0)) {
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto setup_next;
- }
- break;
- }
-} /* ubtbcmfw_write_callback */
-
-/*
- * USB read callback
- */
-
-static void
-ubtbcmfw_read_callback(struct usb2_xfer *xfer)
-{
- struct ubtbcmfw_softc *sc = xfer->priv_sc;
- struct usb2_fifo *fifo = sc->sc_fifo.fp[USB_FIFO_RX];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_fifo_put_data(fifo, xfer->frbuffers, 0, xfer->actlen, 1);
- /* FALLTHROUGH */
-
- case USB_ST_SETUP:
-setup_next:
- if (usb2_fifo_put_bytes_max(fifo) > 0) {
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto setup_next;
- }
- break;
- }
-} /* ubtbcmfw_read_callback */
-
-/*
- * Called when we about to start read()ing from the device
- */
-
-static void
-ubtbcmfw_start_read(struct usb2_fifo *fifo)
-{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_start(sc->sc_xfer[UBTBCMFW_INTR_DT_RD]);
-} /* ubtbcmfw_start_read */
-
-/*
- * Called when we about to stop reading (i.e. closing fifo)
- */
-
-static void
-ubtbcmfw_stop_read(struct usb2_fifo *fifo)
-{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_stop(sc->sc_xfer[UBTBCMFW_INTR_DT_RD]);
-} /* ubtbcmfw_stop_read */
-
-/*
- * Called when we about to start write()ing to the device, poll()ing
- * for write or flushing fifo
- */
-
-static void
-ubtbcmfw_start_write(struct usb2_fifo *fifo)
-{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_start(sc->sc_xfer[UBTBCMFW_BULK_DT_WR]);
-} /* ubtbcmfw_start_write */
-
-/*
- * Called when we about to stop writing (i.e. closing fifo)
- */
-
-static void
-ubtbcmfw_stop_write(struct usb2_fifo *fifo)
-{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_stop(sc->sc_xfer[UBTBCMFW_BULK_DT_WR]);
-} /* ubtbcmfw_stop_write */
-
-/*
- * Called when fifo is open
- */
-
-static int
-ubtbcmfw_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
- struct usb2_xfer *xfer;
-
- /*
- * f_open fifo method can only be called with either FREAD
- * or FWRITE flag set at one time.
- */
-
- if (fflags & FREAD)
- xfer = sc->sc_xfer[UBTBCMFW_INTR_DT_RD];
- else if (fflags & FWRITE)
- xfer = sc->sc_xfer[UBTBCMFW_BULK_DT_WR];
- else
- return (EINVAL); /* should not happen */
-
- if (usb2_fifo_alloc_buffer(fifo, xfer->max_data_length,
- UBTBCMFW_IFQ_MAXLEN) != 0)
- return (ENOMEM);
-
- return (0);
-} /* ubtbcmfw_open */
-
-/*
- * Called when fifo is closed
- */
-
-static void
-ubtbcmfw_close(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- if (fflags & (FREAD | FWRITE))
- usb2_fifo_free_buffer(fifo);
-} /* ubtbcmfw_close */
-
-/*
- * Process ioctl() on USB device
- */
-
-static int
-ubtbcmfw_ioctl(struct usb2_fifo *fifo, u_long cmd, void *data,
- int fflags, struct thread *td)
-{
- struct ubtbcmfw_softc *sc = fifo->priv_sc0;
- int error = 0;
-
- switch (cmd) {
- case USB_GET_DEVICE_DESC:
- memcpy(data, usb2_get_device_descriptor(sc->sc_udev),
- sizeof(struct usb2_device_descriptor));
- break;
-
- default:
- error = EINVAL;
- break;
- }
-
- return (error);
-} /* ubtbcmfw_ioctl */
diff --git a/sys/dev/usb2/bluetooth/usb2_bluetooth.c b/sys/dev/usb2/bluetooth/usb2_bluetooth.c
deleted file mode 100644
index a8c9f54..0000000
--- a/sys/dev/usb2/bluetooth/usb2_bluetooth.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/bluetooth/usb2_bluetooth.h>
-
-MODULE_VERSION(usb2_bluetooth, 1);
-MODULE_DEPEND(usb2_bluetooth, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/bluetooth/usb2_bluetooth.h b/sys/dev/usb2/bluetooth/usb2_bluetooth.h
deleted file mode 100644
index b4b1761..0000000
--- a/sys/dev/usb2/bluetooth/usb2_bluetooth.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_BLUETOOTH_H_
-#define _USB2_BLUETOOTH_H_
-
-#endif /* _USB2_BLUETOOTH_H_ */
diff --git a/sys/dev/usb2/controller/at91dci.c b/sys/dev/usb2/controller/at91dci.c
deleted file mode 100644
index 501d0c0..0000000
--- a/sys/dev/usb2/controller/at91dci.c
+++ /dev/null
@@ -1,2467 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2007-2008 Hans Petter Selasky. 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 file contains the driver for the AT91 series USB Device
- * Controller
- */
-
-/*
- * Thanks to "David Brownell" for helping out regarding the hardware
- * endpoint profiles.
- */
-
-/*
- * NOTE: The "fifo_bank" is not reset in hardware when the endpoint is
- * reset !
- *
- * NOTE: When the chip detects BUS-reset it will also reset the
- * endpoints, Function-address and more.
- */
-
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR at91dcidebug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_hub.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/at91dci.h>
-
-#define AT9100_DCI_BUS2SC(bus) \
- ((struct at91dci_softc *)(((uint8_t *)(bus)) - \
- USB_P2U(&(((struct at91dci_softc *)0)->sc_bus))))
-
-#define AT9100_DCI_PC2SC(pc) \
- AT9100_DCI_BUS2SC((pc)->tag_parent->info->bus)
-
-#if USB_DEBUG
-static int at91dcidebug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, at91dci, CTLFLAG_RW, 0, "USB at91dci");
-SYSCTL_INT(_hw_usb2_at91dci, OID_AUTO, debug, CTLFLAG_RW,
- &at91dcidebug, 0, "at91dci debug level");
-#endif
-
-#define AT9100_DCI_INTR_ENDPT 1
-
-/* prototypes */
-
-struct usb2_bus_methods at91dci_bus_methods;
-struct usb2_pipe_methods at91dci_device_bulk_methods;
-struct usb2_pipe_methods at91dci_device_ctrl_methods;
-struct usb2_pipe_methods at91dci_device_intr_methods;
-struct usb2_pipe_methods at91dci_device_isoc_fs_methods;
-struct usb2_pipe_methods at91dci_root_ctrl_methods;
-struct usb2_pipe_methods at91dci_root_intr_methods;
-
-static at91dci_cmd_t at91dci_setup_rx;
-static at91dci_cmd_t at91dci_data_rx;
-static at91dci_cmd_t at91dci_data_tx;
-static at91dci_cmd_t at91dci_data_tx_sync;
-static void at91dci_device_done(struct usb2_xfer *, usb2_error_t);
-static void at91dci_do_poll(struct usb2_bus *);
-static void at91dci_root_ctrl_poll(struct at91dci_softc *);
-static void at91dci_standard_done(struct usb2_xfer *);
-
-static usb2_sw_transfer_func_t at91dci_root_intr_done;
-static usb2_sw_transfer_func_t at91dci_root_ctrl_done;
-
-/*
- * NOTE: Some of the bits in the CSR register have inverse meaning so
- * we need a helper macro when acknowledging events:
- */
-#define AT91_CSR_ACK(csr, what) do { \
- (csr) &= ~((AT91_UDP_CSR_FORCESTALL| \
- AT91_UDP_CSR_TXPKTRDY| \
- AT91_UDP_CSR_RXBYTECNT) ^ (what));\
- (csr) |= ((AT91_UDP_CSR_RX_DATA_BK0| \
- AT91_UDP_CSR_RX_DATA_BK1| \
- AT91_UDP_CSR_TXCOMP| \
- AT91_UDP_CSR_RXSETUP| \
- AT91_UDP_CSR_STALLSENT) ^ (what)); \
-} while (0)
-
-/*
- * Here is a list of what the chip supports.
- * Probably it supports more than listed here!
- */
-static const struct usb2_hw_ep_profile
- at91dci_ep_profile[AT91_UDP_EP_MAX] = {
-
- [0] = {
- .max_in_frame_size = 8,
- .max_out_frame_size = 8,
- .is_simplex = 1,
- .support_control = 1,
- },
- [1] = {
- .max_in_frame_size = 64,
- .max_out_frame_size = 64,
- .is_simplex = 1,
- .support_multi_buffer = 1,
- .support_bulk = 1,
- .support_interrupt = 1,
- .support_isochronous = 1,
- .support_in = 1,
- .support_out = 1,
- },
- [2] = {
- .max_in_frame_size = 64,
- .max_out_frame_size = 64,
- .is_simplex = 1,
- .support_multi_buffer = 1,
- .support_bulk = 1,
- .support_interrupt = 1,
- .support_isochronous = 1,
- .support_in = 1,
- .support_out = 1,
- },
- [3] = {
- /* can also do BULK */
- .max_in_frame_size = 8,
- .max_out_frame_size = 8,
- .is_simplex = 1,
- .support_interrupt = 1,
- .support_in = 1,
- .support_out = 1,
- },
- [4] = {
- .max_in_frame_size = 256,
- .max_out_frame_size = 256,
- .is_simplex = 1,
- .support_multi_buffer = 1,
- .support_bulk = 1,
- .support_interrupt = 1,
- .support_isochronous = 1,
- .support_in = 1,
- .support_out = 1,
- },
- [5] = {
- .max_in_frame_size = 256,
- .max_out_frame_size = 256,
- .is_simplex = 1,
- .support_multi_buffer = 1,
- .support_bulk = 1,
- .support_interrupt = 1,
- .support_isochronous = 1,
- .support_in = 1,
- .support_out = 1,
- },
-};
-
-static void
-at91dci_get_hw_ep_profile(struct usb2_device *udev,
- const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr)
-{
- if (ep_addr < AT91_UDP_EP_MAX) {
- *ppf = (at91dci_ep_profile + ep_addr);
- } else {
- *ppf = NULL;
- }
-}
-
-static void
-at91dci_clocks_on(struct at91dci_softc *sc)
-{
- if (sc->sc_flags.clocks_off &&
- sc->sc_flags.port_powered) {
-
- DPRINTFN(5, "\n");
-
- if (sc->sc_clocks_on) {
- (sc->sc_clocks_on) (sc->sc_clocks_arg);
- }
- sc->sc_flags.clocks_off = 0;
-
- /* enable Transceiver */
- AT91_UDP_WRITE_4(sc, AT91_UDP_TXVC, 0);
- }
-}
-
-static void
-at91dci_clocks_off(struct at91dci_softc *sc)
-{
- if (!sc->sc_flags.clocks_off) {
-
- DPRINTFN(5, "\n");
-
- /* disable Transceiver */
- AT91_UDP_WRITE_4(sc, AT91_UDP_TXVC, AT91_UDP_TXVC_DIS);
-
- if (sc->sc_clocks_off) {
- (sc->sc_clocks_off) (sc->sc_clocks_arg);
- }
- sc->sc_flags.clocks_off = 1;
- }
-}
-
-static void
-at91dci_pull_up(struct at91dci_softc *sc)
-{
- /* pullup D+, if possible */
-
- if (!sc->sc_flags.d_pulled_up &&
- sc->sc_flags.port_powered) {
- sc->sc_flags.d_pulled_up = 1;
- (sc->sc_pull_up) (sc->sc_pull_arg);
- }
-}
-
-static void
-at91dci_pull_down(struct at91dci_softc *sc)
-{
- /* pulldown D+, if possible */
-
- if (sc->sc_flags.d_pulled_up) {
- sc->sc_flags.d_pulled_up = 0;
- (sc->sc_pull_down) (sc->sc_pull_arg);
- }
-}
-
-static void
-at91dci_wakeup_peer(struct usb2_xfer *xfer)
-{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
- uint8_t use_polling;
-
- if (!(sc->sc_flags.status_suspend)) {
- return;
- }
- use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
-
- AT91_UDP_WRITE_4(sc, AT91_UDP_GSTATE, AT91_UDP_GSTATE_ESR);
-
- /* wait 8 milliseconds */
- if (use_polling) {
- /* polling */
- DELAY(8000);
- } else {
- /* Wait for reset to complete. */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 125);
- }
-
- AT91_UDP_WRITE_4(sc, AT91_UDP_GSTATE, 0);
-}
-
-static void
-at91dci_set_address(struct at91dci_softc *sc, uint8_t addr)
-{
- DPRINTFN(5, "addr=%d\n", addr);
-
- AT91_UDP_WRITE_4(sc, AT91_UDP_FADDR, addr |
- AT91_UDP_FADDR_EN);
-}
-
-static uint8_t
-at91dci_setup_rx(struct at91dci_td *td)
-{
- struct at91dci_softc *sc;
- struct usb2_device_request req;
- uint32_t csr;
- uint32_t temp;
- uint16_t count;
-
- /* read out FIFO status */
- csr = bus_space_read_4(td->io_tag, td->io_hdl,
- td->status_reg);
-
- DPRINTFN(5, "csr=0x%08x rem=%u\n", csr, td->remainder);
-
- temp = csr;
- temp &= (AT91_UDP_CSR_RX_DATA_BK0 |
- AT91_UDP_CSR_RX_DATA_BK1 |
- AT91_UDP_CSR_STALLSENT |
- AT91_UDP_CSR_RXSETUP |
- AT91_UDP_CSR_TXCOMP);
-
- if (!(csr & AT91_UDP_CSR_RXSETUP)) {
- /* abort any ongoing transfer */
- if (!td->did_stall) {
- DPRINTFN(5, "stalling\n");
- temp |= AT91_UDP_CSR_FORCESTALL;
- td->did_stall = 1;
- }
- goto not_complete;
- }
- /* get the packet byte count */
- count = (csr & AT91_UDP_CSR_RXBYTECNT) >> 16;
-
- /* verify data length */
- if (count != td->remainder) {
- DPRINTFN(0, "Invalid SETUP packet "
- "length, %d bytes\n", count);
- goto not_complete;
- }
- if (count != sizeof(req)) {
- DPRINTFN(0, "Unsupported SETUP packet "
- "length, %d bytes\n", count);
- goto not_complete;
- }
- /* receive data */
- bus_space_read_multi_1(td->io_tag, td->io_hdl,
- td->fifo_reg, (void *)&req, sizeof(req));
-
- /* copy data into real buffer */
- usb2_copy_in(td->pc, 0, &req, sizeof(req));
-
- td->offset = sizeof(req);
- td->remainder = 0;
-
- /* get pointer to softc */
- sc = AT9100_DCI_PC2SC(td->pc);
-
- /* sneak peek the set address */
- if ((req.bmRequestType == UT_WRITE_DEVICE) &&
- (req.bRequest == UR_SET_ADDRESS)) {
- sc->sc_dv_addr = req.wValue[0] & 0x7F;
- } else {
- sc->sc_dv_addr = 0xFF;
- }
-
- /* sneak peek the endpoint direction */
- if (req.bmRequestType & UE_DIR_IN) {
- csr |= AT91_UDP_CSR_DIR;
- } else {
- csr &= ~AT91_UDP_CSR_DIR;
- }
-
- /* write the direction of the control transfer */
- AT91_CSR_ACK(csr, temp);
- bus_space_write_4(td->io_tag, td->io_hdl,
- td->status_reg, csr);
- return (0); /* complete */
-
-not_complete:
- /* clear interrupts, if any */
- if (temp) {
- DPRINTFN(5, "clearing 0x%08x\n", temp);
- AT91_CSR_ACK(csr, temp);
- bus_space_write_4(td->io_tag, td->io_hdl,
- td->status_reg, csr);
- }
- return (1); /* not complete */
-
-}
-
-static uint8_t
-at91dci_data_rx(struct at91dci_td *td)
-{
- struct usb2_page_search buf_res;
- uint32_t csr;
- uint32_t temp;
- uint16_t count;
- uint8_t to;
- uint8_t got_short;
-
- to = 2; /* don't loop forever! */
- got_short = 0;
-
- /* check if any of the FIFO banks have data */
-repeat:
- /* read out FIFO status */
- csr = bus_space_read_4(td->io_tag, td->io_hdl,
- td->status_reg);
-
- DPRINTFN(5, "csr=0x%08x rem=%u\n", csr, td->remainder);
-
- if (csr & AT91_UDP_CSR_RXSETUP) {
- if (td->remainder == 0) {
- /*
- * We are actually complete and have
- * received the next SETUP
- */
- DPRINTFN(5, "faking complete\n");
- return (0); /* complete */
- }
- /*
- * USB Host Aborted the transfer.
- */
- td->error = 1;
- return (0); /* complete */
- }
- /* Make sure that "STALLSENT" gets cleared */
- temp = csr;
- temp &= AT91_UDP_CSR_STALLSENT;
-
- /* check status */
- if (!(csr & (AT91_UDP_CSR_RX_DATA_BK0 |
- AT91_UDP_CSR_RX_DATA_BK1))) {
- if (temp) {
- /* write command */
- AT91_CSR_ACK(csr, temp);
- bus_space_write_4(td->io_tag, td->io_hdl,
- td->status_reg, csr);
- }
- return (1); /* not complete */
- }
- /* get the packet byte count */
- count = (csr & AT91_UDP_CSR_RXBYTECNT) >> 16;
-
- /* verify the packet byte count */
- if (count != td->max_packet_size) {
- if (count < td->max_packet_size) {
- /* we have a short packet */
- td->short_pkt = 1;
- got_short = 1;
- } else {
- /* invalid USB packet */
- td->error = 1;
- return (0); /* we are complete */
- }
- }
- /* verify the packet byte count */
- if (count > td->remainder) {
- /* invalid USB packet */
- td->error = 1;
- return (0); /* we are complete */
- }
- while (count > 0) {
- usb2_get_page(td->pc, td->offset, &buf_res);
-
- /* get correct length */
- if (buf_res.length > count) {
- buf_res.length = count;
- }
- /* receive data */
- bus_space_read_multi_1(td->io_tag, td->io_hdl,
- td->fifo_reg, buf_res.buffer, buf_res.length);
-
- /* update counters */
- count -= buf_res.length;
- td->offset += buf_res.length;
- td->remainder -= buf_res.length;
- }
-
- /* clear status bits */
- if (td->support_multi_buffer) {
- if (td->fifo_bank) {
- td->fifo_bank = 0;
- temp |= AT91_UDP_CSR_RX_DATA_BK1;
- } else {
- td->fifo_bank = 1;
- temp |= AT91_UDP_CSR_RX_DATA_BK0;
- }
- } else {
- temp |= (AT91_UDP_CSR_RX_DATA_BK0 |
- AT91_UDP_CSR_RX_DATA_BK1);
- }
-
- /* write command */
- AT91_CSR_ACK(csr, temp);
- bus_space_write_4(td->io_tag, td->io_hdl,
- td->status_reg, csr);
-
- /*
- * NOTE: We may have to delay a little bit before
- * proceeding after clearing the DATA_BK bits.
- */
-
- /* check if we are complete */
- if ((td->remainder == 0) || got_short) {
- if (td->short_pkt) {
- /* we are complete */
- return (0);
- }
- /* else need to receive a zero length packet */
- }
- if (--to) {
- goto repeat;
- }
- return (1); /* not complete */
-}
-
-static uint8_t
-at91dci_data_tx(struct at91dci_td *td)
-{
- struct usb2_page_search buf_res;
- uint32_t csr;
- uint32_t temp;
- uint16_t count;
- uint8_t to;
-
- to = 2; /* don't loop forever! */
-
-repeat:
-
- /* read out FIFO status */
- csr = bus_space_read_4(td->io_tag, td->io_hdl,
- td->status_reg);
-
- DPRINTFN(5, "csr=0x%08x rem=%u\n", csr, td->remainder);
-
- if (csr & AT91_UDP_CSR_RXSETUP) {
- /*
- * The current transfer was aborted
- * by the USB Host
- */
- td->error = 1;
- return (0); /* complete */
- }
- /* Make sure that "STALLSENT" gets cleared */
- temp = csr;
- temp &= AT91_UDP_CSR_STALLSENT;
-
- if (csr & AT91_UDP_CSR_TXPKTRDY) {
- if (temp) {
- /* write command */
- AT91_CSR_ACK(csr, temp);
- bus_space_write_4(td->io_tag, td->io_hdl,
- td->status_reg, csr);
- }
- return (1); /* not complete */
- } else {
- /* clear TXCOMP and set TXPKTRDY */
- temp |= (AT91_UDP_CSR_TXCOMP |
- AT91_UDP_CSR_TXPKTRDY);
- }
-
- count = td->max_packet_size;
- if (td->remainder < count) {
- /* we have a short packet */
- td->short_pkt = 1;
- count = td->remainder;
- }
- while (count > 0) {
-
- usb2_get_page(td->pc, td->offset, &buf_res);
-
- /* get correct length */
- if (buf_res.length > count) {
- buf_res.length = count;
- }
- /* transmit data */
- bus_space_write_multi_1(td->io_tag, td->io_hdl,
- td->fifo_reg, buf_res.buffer, buf_res.length);
-
- /* update counters */
- count -= buf_res.length;
- td->offset += buf_res.length;
- td->remainder -= buf_res.length;
- }
-
- /* write command */
- AT91_CSR_ACK(csr, temp);
- bus_space_write_4(td->io_tag, td->io_hdl,
- td->status_reg, csr);
-
- /* check remainder */
- if (td->remainder == 0) {
- if (td->short_pkt) {
- return (0); /* complete */
- }
- /* else we need to transmit a short packet */
- }
- if (--to) {
- goto repeat;
- }
- return (1); /* not complete */
-}
-
-static uint8_t
-at91dci_data_tx_sync(struct at91dci_td *td)
-{
- struct at91dci_softc *sc;
- uint32_t csr;
- uint32_t temp;
-
-#if 0
-repeat:
-#endif
-
- /* read out FIFO status */
- csr = bus_space_read_4(td->io_tag, td->io_hdl,
- td->status_reg);
-
- DPRINTFN(5, "csr=0x%08x\n", csr);
-
- if (csr & AT91_UDP_CSR_RXSETUP) {
- DPRINTFN(5, "faking complete\n");
- /* Race condition */
- return (0); /* complete */
- }
- temp = csr;
- temp &= (AT91_UDP_CSR_STALLSENT |
- AT91_UDP_CSR_TXCOMP);
-
- /* check status */
- if (csr & AT91_UDP_CSR_TXPKTRDY) {
- goto not_complete;
- }
- if (!(csr & AT91_UDP_CSR_TXCOMP)) {
- goto not_complete;
- }
- sc = AT9100_DCI_PC2SC(td->pc);
- if (sc->sc_dv_addr != 0xFF) {
- /*
- * The AT91 has a special requirement with regard to
- * setting the address and that is to write the new
- * address before clearing TXCOMP:
- */
- at91dci_set_address(sc, sc->sc_dv_addr);
- }
- /* write command */
- AT91_CSR_ACK(csr, temp);
- bus_space_write_4(td->io_tag, td->io_hdl,
- td->status_reg, csr);
-
- return (0); /* complete */
-
-not_complete:
- if (temp) {
- /* write command */
- AT91_CSR_ACK(csr, temp);
- bus_space_write_4(td->io_tag, td->io_hdl,
- td->status_reg, csr);
- }
- return (1); /* not complete */
-}
-
-static uint8_t
-at91dci_xfer_do_fifo(struct usb2_xfer *xfer)
-{
- struct at91dci_softc *sc;
- struct at91dci_td *td;
- uint8_t temp;
-
- DPRINTFN(9, "\n");
-
- td = xfer->td_transfer_cache;
- while (1) {
- if ((td->func) (td)) {
- /* operation in progress */
- break;
- }
- if (((void *)td) == xfer->td_transfer_last) {
- goto done;
- }
- if (td->error) {
- goto done;
- } else if (td->remainder > 0) {
- /*
- * We had a short transfer. If there is no alternate
- * next, stop processing !
- */
- if (!td->alt_next) {
- goto done;
- }
- }
- /*
- * Fetch the next transfer descriptor and transfer
- * some flags to the next transfer descriptor
- */
- temp = 0;
- if (td->fifo_bank)
- temp |= 1;
- td = td->obj_next;
- xfer->td_transfer_cache = td;
- if (temp & 1)
- td->fifo_bank = 1;
- }
- return (1); /* not complete */
-
-done:
- sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
- temp = (xfer->endpoint & UE_ADDR);
-
- /* update FIFO bank flag and multi buffer */
- if (td->fifo_bank) {
- sc->sc_ep_flags[temp].fifo_bank = 1;
- } else {
- sc->sc_ep_flags[temp].fifo_bank = 0;
- }
-
- /* compute all actual lengths */
-
- at91dci_standard_done(xfer);
-
- return (0); /* complete */
-}
-
-static void
-at91dci_interrupt_poll(struct at91dci_softc *sc)
-{
- struct usb2_xfer *xfer;
-
-repeat:
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
- if (!at91dci_xfer_do_fifo(xfer)) {
- /* queue has been modified */
- goto repeat;
- }
- }
-}
-
-void
-at91dci_vbus_interrupt(struct at91dci_softc *sc, uint8_t is_on)
-{
- DPRINTFN(5, "vbus = %u\n", is_on);
-
- USB_BUS_LOCK(&sc->sc_bus);
- if (is_on) {
- if (!sc->sc_flags.status_vbus) {
- sc->sc_flags.status_vbus = 1;
-
- /* complete root HUB interrupt endpoint */
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &at91dci_root_intr_done);
- }
- } else {
- if (sc->sc_flags.status_vbus) {
- sc->sc_flags.status_vbus = 0;
- sc->sc_flags.status_bus_reset = 0;
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 0;
- sc->sc_flags.change_connect = 1;
-
- /* complete root HUB interrupt endpoint */
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &at91dci_root_intr_done);
- }
- }
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-void
-at91dci_interrupt(struct at91dci_softc *sc)
-{
- uint32_t status;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- status = AT91_UDP_READ_4(sc, AT91_UDP_ISR);
- status &= AT91_UDP_INT_DEFAULT;
-
- if (!status) {
- USB_BUS_UNLOCK(&sc->sc_bus);
- return;
- }
- /* acknowledge interrupts */
-
- AT91_UDP_WRITE_4(sc, AT91_UDP_ICR, status);
-
- /* check for any bus state change interrupts */
-
- if (status & AT91_UDP_INT_BUS) {
-
- DPRINTFN(5, "real bus interrupt 0x%08x\n", status);
-
- if (status & AT91_UDP_INT_END_BR) {
-
- /* set correct state */
- sc->sc_flags.status_bus_reset = 1;
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 0;
- sc->sc_flags.change_connect = 1;
-
- /* disable resume interrupt */
- AT91_UDP_WRITE_4(sc, AT91_UDP_IDR,
- AT91_UDP_INT_RXRSM);
- /* enable suspend interrupt */
- AT91_UDP_WRITE_4(sc, AT91_UDP_IER,
- AT91_UDP_INT_RXSUSP);
- }
- /*
- * If RXRSM and RXSUSP is set at the same time we interpret
- * that like RESUME. Resume is set when there is at least 3
- * milliseconds of inactivity on the USB BUS.
- */
- if (status & AT91_UDP_INT_RXRSM) {
- if (sc->sc_flags.status_suspend) {
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 1;
-
- /* disable resume interrupt */
- AT91_UDP_WRITE_4(sc, AT91_UDP_IDR,
- AT91_UDP_INT_RXRSM);
- /* enable suspend interrupt */
- AT91_UDP_WRITE_4(sc, AT91_UDP_IER,
- AT91_UDP_INT_RXSUSP);
- }
- } else if (status & AT91_UDP_INT_RXSUSP) {
- if (!sc->sc_flags.status_suspend) {
- sc->sc_flags.status_suspend = 1;
- sc->sc_flags.change_suspend = 1;
-
- /* disable suspend interrupt */
- AT91_UDP_WRITE_4(sc, AT91_UDP_IDR,
- AT91_UDP_INT_RXSUSP);
-
- /* enable resume interrupt */
- AT91_UDP_WRITE_4(sc, AT91_UDP_IER,
- AT91_UDP_INT_RXRSM);
- }
- }
- /* complete root HUB interrupt endpoint */
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &at91dci_root_intr_done);
- }
- /* check for any endpoint interrupts */
-
- if (status & AT91_UDP_INT_EPS) {
-
- DPRINTFN(5, "real endpoint interrupt 0x%08x\n", status);
-
- at91dci_interrupt_poll(sc);
- }
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-static void
-at91dci_setup_standard_chain_sub(struct at91dci_std_temp *temp)
-{
- struct at91dci_td *td;
-
- /* get current Transfer Descriptor */
- td = temp->td_next;
- temp->td = td;
-
- /* prepare for next TD */
- temp->td_next = td->obj_next;
-
- /* fill out the Transfer Descriptor */
- td->func = temp->func;
- td->pc = temp->pc;
- td->offset = temp->offset;
- td->remainder = temp->len;
- td->fifo_bank = 0;
- td->error = 0;
- td->did_stall = 0;
- td->short_pkt = temp->short_pkt;
- td->alt_next = temp->setup_alt_next;
-}
-
-static void
-at91dci_setup_standard_chain(struct usb2_xfer *xfer)
-{
- struct at91dci_std_temp temp;
- struct at91dci_softc *sc;
- struct at91dci_td *td;
- uint32_t x;
- uint8_t ep_no;
- uint8_t need_sync;
-
- DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
- xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
-
- temp.max_frame_size = xfer->max_frame_size;
-
- td = xfer->td_start[0];
- xfer->td_transfer_first = td;
- xfer->td_transfer_cache = td;
-
- /* setup temp */
-
- temp.td = NULL;
- temp.td_next = xfer->td_start[0];
- temp.setup_alt_next = xfer->flags_int.short_frames_ok;
- temp.offset = 0;
-
- sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
- ep_no = (xfer->endpoint & UE_ADDR);
-
- /* check if we should prepend a setup message */
-
- if (xfer->flags_int.control_xfr) {
- if (xfer->flags_int.control_hdr) {
-
- temp.func = &at91dci_setup_rx;
- temp.len = xfer->frlengths[0];
- temp.pc = xfer->frbuffers + 0;
- temp.short_pkt = temp.len ? 1 : 0;
-
- at91dci_setup_standard_chain_sub(&temp);
- }
- x = 1;
- } else {
- x = 0;
- }
-
- if (x != xfer->nframes) {
- if (xfer->endpoint & UE_DIR_IN) {
- temp.func = &at91dci_data_tx;
- need_sync = 1;
- } else {
- temp.func = &at91dci_data_rx;
- need_sync = 0;
- }
-
- /* setup "pc" pointer */
- temp.pc = xfer->frbuffers + x;
- } else {
- need_sync = 0;
- }
- while (x != xfer->nframes) {
-
- /* DATA0 / DATA1 message */
-
- temp.len = xfer->frlengths[x];
-
- x++;
-
- if (x == xfer->nframes) {
- temp.setup_alt_next = 0;
- }
- if (temp.len == 0) {
-
- /* make sure that we send an USB packet */
-
- temp.short_pkt = 0;
-
- } else {
-
- /* regular data transfer */
-
- temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
- }
-
- at91dci_setup_standard_chain_sub(&temp);
-
- if (xfer->flags_int.isochronous_xfr) {
- temp.offset += temp.len;
- } else {
- /* get next Page Cache pointer */
- temp.pc = xfer->frbuffers + x;
- }
- }
-
- /* always setup a valid "pc" pointer for status and sync */
- temp.pc = xfer->frbuffers + 0;
-
- /* check if we need to sync */
- if (need_sync && xfer->flags_int.control_xfr) {
-
- /* we need a SYNC point after TX */
- temp.func = &at91dci_data_tx_sync;
- temp.len = 0;
- temp.short_pkt = 0;
-
- at91dci_setup_standard_chain_sub(&temp);
- }
- /* check if we should append a status stage */
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- /*
- * Send a DATA1 message and invert the current
- * endpoint direction.
- */
- if (xfer->endpoint & UE_DIR_IN) {
- temp.func = &at91dci_data_rx;
- need_sync = 0;
- } else {
- temp.func = &at91dci_data_tx;
- need_sync = 1;
- }
- temp.len = 0;
- temp.short_pkt = 0;
-
- at91dci_setup_standard_chain_sub(&temp);
- if (need_sync) {
- /* we need a SYNC point after TX */
- temp.func = &at91dci_data_tx_sync;
- temp.len = 0;
- temp.short_pkt = 0;
-
- at91dci_setup_standard_chain_sub(&temp);
- }
- }
- /* must have at least one frame! */
- td = temp.td;
- xfer->td_transfer_last = td;
-
- /* setup the correct fifo bank */
- if (sc->sc_ep_flags[ep_no].fifo_bank) {
- td = xfer->td_transfer_first;
- td->fifo_bank = 1;
- }
-}
-
-static void
-at91dci_timeout(void *arg)
-{
- struct usb2_xfer *xfer = arg;
-
- DPRINTF("xfer=%p\n", xfer);
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- /* transfer is transferred */
- at91dci_device_done(xfer, USB_ERR_TIMEOUT);
-}
-
-static void
-at91dci_start_standard_chain(struct usb2_xfer *xfer)
-{
- DPRINTFN(9, "\n");
-
- /* poll one time */
- if (at91dci_xfer_do_fifo(xfer)) {
-
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
- uint8_t ep_no = xfer->endpoint & UE_ADDR;
-
- /*
- * Only enable the endpoint interrupt when we are actually
- * waiting for data, hence we are dealing with level
- * triggered interrupts !
- */
- AT91_UDP_WRITE_4(sc, AT91_UDP_IER, AT91_UDP_INT_EP(ep_no));
-
- DPRINTFN(15, "enable interrupts on endpoint %d\n", ep_no);
-
- /* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
-
- /* start timeout, if any */
- if (xfer->timeout != 0) {
- usb2_transfer_timeout_ms(xfer,
- &at91dci_timeout, xfer->timeout);
- }
- }
-}
-
-static void
-at91dci_root_intr_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
-
- DPRINTFN(9, "\n");
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_PRE_DATA) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- at91dci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* setup buffer */
- std->ptr = sc->sc_hub_idata;
- std->len = sizeof(sc->sc_hub_idata);
-
- /* set port bit */
- sc->sc_hub_idata[0] = 0x02; /* we only have one port */
-
-done:
- return;
-}
-
-static usb2_error_t
-at91dci_standard_done_sub(struct usb2_xfer *xfer)
-{
- struct at91dci_td *td;
- uint32_t len;
- uint8_t error;
-
- DPRINTFN(9, "\n");
-
- td = xfer->td_transfer_cache;
-
- do {
- len = td->remainder;
-
- if (xfer->aframes != xfer->nframes) {
- /*
- * Verify the length and subtract
- * the remainder from "frlengths[]":
- */
- if (len > xfer->frlengths[xfer->aframes]) {
- td->error = 1;
- } else {
- xfer->frlengths[xfer->aframes] -= len;
- }
- }
- /* Check for transfer error */
- if (td->error) {
- /* the transfer is finished */
- error = 1;
- td = NULL;
- break;
- }
- /* Check for short transfer */
- if (len > 0) {
- if (xfer->flags_int.short_frames_ok) {
- /* follow alt next */
- if (td->alt_next) {
- td = td->obj_next;
- } else {
- td = NULL;
- }
- } else {
- /* the transfer is finished */
- td = NULL;
- }
- error = 0;
- break;
- }
- td = td->obj_next;
-
- /* this USB frame is complete */
- error = 0;
- break;
-
- } while (0);
-
- /* update transfer cache */
-
- xfer->td_transfer_cache = td;
-
- return (error ?
- USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
-}
-
-static void
-at91dci_standard_done(struct usb2_xfer *xfer)
-{
- usb2_error_t err = 0;
-
- DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
- xfer, xfer->pipe);
-
- /* reset scanner */
-
- xfer->td_transfer_cache = xfer->td_transfer_first;
-
- if (xfer->flags_int.control_xfr) {
-
- if (xfer->flags_int.control_hdr) {
-
- err = at91dci_standard_done_sub(xfer);
- }
- xfer->aframes = 1;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
- while (xfer->aframes != xfer->nframes) {
-
- err = at91dci_standard_done_sub(xfer);
- xfer->aframes++;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- err = at91dci_standard_done_sub(xfer);
- }
-done:
- at91dci_device_done(xfer, err);
-}
-
-/*------------------------------------------------------------------------*
- * at91dci_device_done
- *
- * NOTE: this function can be called more than one time on the
- * same USB transfer!
- *------------------------------------------------------------------------*/
-static void
-at91dci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
-{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
- uint8_t ep_no;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
- xfer, xfer->pipe, error);
-
- if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
- ep_no = (xfer->endpoint & UE_ADDR);
-
- /* disable endpoint interrupt */
- AT91_UDP_WRITE_4(sc, AT91_UDP_IDR, AT91_UDP_INT_EP(ep_no));
-
- DPRINTFN(15, "disable interrupts on endpoint %d\n", ep_no);
- }
- /* dequeue transfer and start next transfer */
- usb2_transfer_done(xfer, error);
-}
-
-static void
-at91dci_set_stall(struct usb2_device *udev, struct usb2_xfer *xfer,
- struct usb2_pipe *pipe)
-{
- struct at91dci_softc *sc;
- uint32_t csr_val;
- uint8_t csr_reg;
-
- USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
-
- DPRINTFN(5, "pipe=%p\n", pipe);
-
- if (xfer) {
- /* cancel any ongoing transfers */
- at91dci_device_done(xfer, USB_ERR_STALLED);
- }
- /* set FORCESTALL */
- sc = AT9100_DCI_BUS2SC(udev->bus);
- csr_reg = (pipe->edesc->bEndpointAddress & UE_ADDR);
- csr_reg = AT91_UDP_CSR(csr_reg);
- csr_val = AT91_UDP_READ_4(sc, csr_reg);
- AT91_CSR_ACK(csr_val, AT91_UDP_CSR_FORCESTALL);
- AT91_UDP_WRITE_4(sc, csr_reg, csr_val);
-}
-
-static void
-at91dci_clear_stall_sub(struct at91dci_softc *sc, uint8_t ep_no,
- uint8_t ep_type, uint8_t ep_dir)
-{
- const struct usb2_hw_ep_profile *pf;
- uint32_t csr_val;
- uint32_t temp;
- uint8_t csr_reg;
- uint8_t to;
-
- if (ep_type == UE_CONTROL) {
- /* clearing stall is not needed */
- return;
- }
- /* compute CSR register offset */
- csr_reg = AT91_UDP_CSR(ep_no);
-
- /* compute default CSR value */
- csr_val = 0;
- AT91_CSR_ACK(csr_val, 0);
-
- /* disable endpoint */
- AT91_UDP_WRITE_4(sc, csr_reg, csr_val);
-
- /* get endpoint profile */
- at91dci_get_hw_ep_profile(NULL, &pf, ep_no);
-
- /* reset FIFO */
- AT91_UDP_WRITE_4(sc, AT91_UDP_RST, AT91_UDP_RST_EP(ep_no));
- AT91_UDP_WRITE_4(sc, AT91_UDP_RST, 0);
-
- /*
- * NOTE: One would assume that a FIFO reset would release the
- * FIFO banks aswell, but it doesn't! We have to do this
- * manually!
- */
-
- /* release FIFO banks, if any */
- for (to = 0; to != 2; to++) {
-
- /* get csr value */
- csr_val = AT91_UDP_READ_4(sc, csr_reg);
-
- if (csr_val & (AT91_UDP_CSR_RX_DATA_BK0 |
- AT91_UDP_CSR_RX_DATA_BK1)) {
- /* clear status bits */
- if (pf->support_multi_buffer) {
- if (sc->sc_ep_flags[ep_no].fifo_bank) {
- sc->sc_ep_flags[ep_no].fifo_bank = 0;
- temp = AT91_UDP_CSR_RX_DATA_BK1;
- } else {
- sc->sc_ep_flags[ep_no].fifo_bank = 1;
- temp = AT91_UDP_CSR_RX_DATA_BK0;
- }
- } else {
- temp = (AT91_UDP_CSR_RX_DATA_BK0 |
- AT91_UDP_CSR_RX_DATA_BK1);
- }
- } else {
- temp = 0;
- }
-
- /* clear FORCESTALL */
- temp |= AT91_UDP_CSR_STALLSENT;
-
- AT91_CSR_ACK(csr_val, temp);
- AT91_UDP_WRITE_4(sc, csr_reg, csr_val);
- }
-
- /* compute default CSR value */
- csr_val = 0;
- AT91_CSR_ACK(csr_val, 0);
-
- /* enable endpoint */
- csr_val &= ~AT91_UDP_CSR_ET_MASK;
- csr_val |= AT91_UDP_CSR_EPEDS;
-
- if (ep_type == UE_CONTROL) {
- csr_val |= AT91_UDP_CSR_ET_CTRL;
- } else {
- if (ep_type == UE_BULK) {
- csr_val |= AT91_UDP_CSR_ET_BULK;
- } else if (ep_type == UE_INTERRUPT) {
- csr_val |= AT91_UDP_CSR_ET_INT;
- } else {
- csr_val |= AT91_UDP_CSR_ET_ISO;
- }
- if (ep_dir & UE_DIR_IN) {
- csr_val |= AT91_UDP_CSR_ET_DIR_IN;
- }
- }
-
- /* enable endpoint */
- AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(ep_no), csr_val);
-}
-
-static void
-at91dci_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe)
-{
- struct at91dci_softc *sc;
- struct usb2_endpoint_descriptor *ed;
-
- DPRINTFN(5, "pipe=%p\n", pipe);
-
- USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
-
- /* check mode */
- if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
- /* not supported */
- return;
- }
- /* get softc */
- sc = AT9100_DCI_BUS2SC(udev->bus);
-
- /* get endpoint descriptor */
- ed = pipe->edesc;
-
- /* reset endpoint */
- at91dci_clear_stall_sub(sc,
- (ed->bEndpointAddress & UE_ADDR),
- (ed->bmAttributes & UE_XFERTYPE),
- (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
-}
-
-usb2_error_t
-at91dci_init(struct at91dci_softc *sc)
-{
- uint32_t csr_val;
- uint8_t n;
-
- DPRINTF("start\n");
-
- /* set up the bus structure */
- sc->sc_bus.usbrev = USB_REV_1_1;
- sc->sc_bus.methods = &at91dci_bus_methods;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* turn on clocks */
-
- if (sc->sc_clocks_on) {
- (sc->sc_clocks_on) (sc->sc_clocks_arg);
- }
- /* wait a little for things to stabilise */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
-
- /* disable and clear all interrupts */
-
- AT91_UDP_WRITE_4(sc, AT91_UDP_IDR, 0xFFFFFFFF);
- AT91_UDP_WRITE_4(sc, AT91_UDP_ICR, 0xFFFFFFFF);
-
- /* compute default CSR value */
-
- csr_val = 0;
- AT91_CSR_ACK(csr_val, 0);
-
- /* disable all endpoints */
-
- for (n = 0; n != AT91_UDP_EP_MAX; n++) {
-
- /* disable endpoint */
- AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(n), csr_val);
- }
-
- /* enable the control endpoint */
-
- AT91_CSR_ACK(csr_val, AT91_UDP_CSR_ET_CTRL |
- AT91_UDP_CSR_EPEDS);
-
- /* write to FIFO control register */
-
- AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(0), csr_val);
-
- /* enable the interrupts we want */
-
- AT91_UDP_WRITE_4(sc, AT91_UDP_IER, AT91_UDP_INT_BUS);
-
- /* turn off clocks */
-
- at91dci_clocks_off(sc);
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-
- /* catch any lost interrupts */
-
- at91dci_do_poll(&sc->sc_bus);
-
- return (0); /* success */
-}
-
-void
-at91dci_uninit(struct at91dci_softc *sc)
-{
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* disable and clear all interrupts */
- AT91_UDP_WRITE_4(sc, AT91_UDP_IDR, 0xFFFFFFFF);
- AT91_UDP_WRITE_4(sc, AT91_UDP_ICR, 0xFFFFFFFF);
-
- sc->sc_flags.port_powered = 0;
- sc->sc_flags.status_vbus = 0;
- sc->sc_flags.status_bus_reset = 0;
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 0;
- sc->sc_flags.change_connect = 1;
-
- at91dci_pull_down(sc);
- at91dci_clocks_off(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-void
-at91dci_suspend(struct at91dci_softc *sc)
-{
- return;
-}
-
-void
-at91dci_resume(struct at91dci_softc *sc)
-{
- return;
-}
-
-static void
-at91dci_do_poll(struct usb2_bus *bus)
-{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(bus);
-
- USB_BUS_LOCK(&sc->sc_bus);
- at91dci_interrupt_poll(sc);
- at91dci_root_ctrl_poll(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-/*------------------------------------------------------------------------*
- * at91dci bulk support
- *------------------------------------------------------------------------*/
-static void
-at91dci_device_bulk_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_device_bulk_close(struct usb2_xfer *xfer)
-{
- at91dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-at91dci_device_bulk_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_device_bulk_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- at91dci_setup_standard_chain(xfer);
- at91dci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods at91dci_device_bulk_methods =
-{
- .open = at91dci_device_bulk_open,
- .close = at91dci_device_bulk_close,
- .enter = at91dci_device_bulk_enter,
- .start = at91dci_device_bulk_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci control support
- *------------------------------------------------------------------------*/
-static void
-at91dci_device_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_device_ctrl_close(struct usb2_xfer *xfer)
-{
- at91dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-at91dci_device_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_device_ctrl_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- at91dci_setup_standard_chain(xfer);
- at91dci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods at91dci_device_ctrl_methods =
-{
- .open = at91dci_device_ctrl_open,
- .close = at91dci_device_ctrl_close,
- .enter = at91dci_device_ctrl_enter,
- .start = at91dci_device_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci interrupt support
- *------------------------------------------------------------------------*/
-static void
-at91dci_device_intr_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_device_intr_close(struct usb2_xfer *xfer)
-{
- at91dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-at91dci_device_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_device_intr_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- at91dci_setup_standard_chain(xfer);
- at91dci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods at91dci_device_intr_methods =
-{
- .open = at91dci_device_intr_open,
- .close = at91dci_device_intr_close,
- .enter = at91dci_device_intr_enter,
- .start = at91dci_device_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci full speed isochronous support
- *------------------------------------------------------------------------*/
-static void
-at91dci_device_isoc_fs_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_device_isoc_fs_close(struct usb2_xfer *xfer)
-{
- at91dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-at91dci_device_isoc_fs_enter(struct usb2_xfer *xfer)
-{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
- uint32_t temp;
- uint32_t nframes;
-
- DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
- xfer, xfer->pipe->isoc_next, xfer->nframes);
-
- /* get the current frame index */
-
- nframes = AT91_UDP_READ_4(sc, AT91_UDP_FRM);
-
- /*
- * check if the frame index is within the window where the frames
- * will be inserted
- */
- temp = (nframes - xfer->pipe->isoc_next) & AT91_UDP_FRM_MASK;
-
- if ((xfer->pipe->is_synced == 0) ||
- (temp < xfer->nframes)) {
- /*
- * If there is data underflow or the pipe queue is
- * empty we schedule the transfer a few frames ahead
- * of the current frame position. Else two isochronous
- * transfers might overlap.
- */
- xfer->pipe->isoc_next = (nframes + 3) & AT91_UDP_FRM_MASK;
- xfer->pipe->is_synced = 1;
- DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next);
- }
- /*
- * compute how many milliseconds the insertion is ahead of the
- * current frame position:
- */
- temp = (xfer->pipe->isoc_next - nframes) & AT91_UDP_FRM_MASK;
-
- /*
- * pre-compute when the isochronous transfer will be finished:
- */
- xfer->isoc_time_complete =
- usb2_isoc_time_expand(&sc->sc_bus, nframes) + temp +
- xfer->nframes;
-
- /* compute frame number for next insertion */
- xfer->pipe->isoc_next += xfer->nframes;
-
- /* setup TDs */
- at91dci_setup_standard_chain(xfer);
-}
-
-static void
-at91dci_device_isoc_fs_start(struct usb2_xfer *xfer)
-{
- /* start TD chain */
- at91dci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods at91dci_device_isoc_fs_methods =
-{
- .open = at91dci_device_isoc_fs_open,
- .close = at91dci_device_isoc_fs_close,
- .enter = at91dci_device_isoc_fs_enter,
- .start = at91dci_device_isoc_fs_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci root control support
- *------------------------------------------------------------------------*
- * simulate a hardware HUB by handling
- * all the necessary requests
- *------------------------------------------------------------------------*/
-
-static void
-at91dci_root_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_root_ctrl_close(struct usb2_xfer *xfer)
-{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_ctrl.xfer == xfer) {
- sc->sc_root_ctrl.xfer = NULL;
- }
- at91dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-/*
- * USB descriptors for the virtual Root HUB:
- */
-
-static const struct usb2_device_descriptor at91dci_devd = {
- .bLength = sizeof(struct usb2_device_descriptor),
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_HSHUBSTT,
- .bMaxPacketSize = 64,
- .bcdDevice = {0x00, 0x01},
- .iManufacturer = 1,
- .iProduct = 2,
- .bNumConfigurations = 1,
-};
-
-static const struct usb2_device_qualifier at91dci_odevd = {
- .bLength = sizeof(struct usb2_device_qualifier),
- .bDescriptorType = UDESC_DEVICE_QUALIFIER,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_FSHUB,
- .bMaxPacketSize0 = 0,
- .bNumConfigurations = 0,
-};
-
-static const struct at91dci_config_desc at91dci_confd = {
- .confd = {
- .bLength = sizeof(struct usb2_config_descriptor),
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength[0] = sizeof(at91dci_confd),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_SELF_POWERED,
- .bMaxPower = 0,
- },
- .ifcd = {
- .bLength = sizeof(struct usb2_interface_descriptor),
- .bDescriptorType = UDESC_INTERFACE,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_HSHUBSTT,
- },
-
- .endpd = {
- .bLength = sizeof(struct usb2_endpoint_descriptor),
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = (UE_DIR_IN | AT9100_DCI_INTR_ENDPT),
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize[0] = 8,
- .bInterval = 255,
- },
-};
-
-static const struct usb2_hub_descriptor_min at91dci_hubd = {
- .bDescLength = sizeof(at91dci_hubd),
- .bDescriptorType = UDESC_HUB,
- .bNbrPorts = 1,
- .wHubCharacteristics[0] =
- (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
- .wHubCharacteristics[1] =
- (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 8,
- .bPwrOn2PwrGood = 50,
- .bHubContrCurrent = 0,
- .DeviceRemovable = {0}, /* port is removable */
-};
-
-#define STRING_LANG \
- 0x09, 0x04, /* American English */
-
-#define STRING_VENDOR \
- 'A', 0, 'T', 0, 'M', 0, 'E', 0, 'L', 0
-
-#define STRING_PRODUCT \
- 'D', 0, 'C', 0, 'I', 0, ' ', 0, 'R', 0, \
- 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
- 'U', 0, 'B', 0,
-
-USB_MAKE_STRING_DESC(STRING_LANG, at91dci_langtab);
-USB_MAKE_STRING_DESC(STRING_VENDOR, at91dci_vendor);
-USB_MAKE_STRING_DESC(STRING_PRODUCT, at91dci_product);
-
-static void
-at91dci_root_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_root_ctrl_start(struct usb2_xfer *xfer)
-{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_ctrl.xfer = xfer;
-
- usb2_bus_roothub_exec(xfer->xroot->bus);
-}
-
-static void
-at91dci_root_ctrl_task(struct usb2_bus *bus)
-{
- at91dci_root_ctrl_poll(AT9100_DCI_BUS2SC(bus));
-}
-
-static void
-at91dci_root_ctrl_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
- uint16_t value;
- uint16_t index;
- uint8_t use_polling;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_SETUP) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- at91dci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* buffer reset */
- std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
- std->len = 0;
-
- value = UGETW(std->req.wValue);
- index = UGETW(std->req.wIndex);
-
- use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
-
- /* demultiplex the control request */
-
- switch (std->req.bmRequestType) {
- case UT_READ_DEVICE:
- switch (std->req.bRequest) {
- case UR_GET_DESCRIPTOR:
- goto tr_handle_get_descriptor;
- case UR_GET_CONFIG:
- goto tr_handle_get_config;
- case UR_GET_STATUS:
- goto tr_handle_get_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_DEVICE:
- switch (std->req.bRequest) {
- case UR_SET_ADDRESS:
- goto tr_handle_set_address;
- case UR_SET_CONFIG:
- goto tr_handle_set_config;
- case UR_CLEAR_FEATURE:
- goto tr_valid; /* nop */
- case UR_SET_DESCRIPTOR:
- goto tr_valid; /* nop */
- case UR_SET_FEATURE:
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_ENDPOINT:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- switch (UGETW(std->req.wValue)) {
- case UF_ENDPOINT_HALT:
- goto tr_handle_clear_halt;
- case UF_DEVICE_REMOTE_WAKEUP:
- goto tr_handle_clear_wakeup;
- default:
- goto tr_stalled;
- }
- break;
- case UR_SET_FEATURE:
- switch (UGETW(std->req.wValue)) {
- case UF_ENDPOINT_HALT:
- goto tr_handle_set_halt;
- case UF_DEVICE_REMOTE_WAKEUP:
- goto tr_handle_set_wakeup;
- default:
- goto tr_stalled;
- }
- break;
- case UR_SYNCH_FRAME:
- goto tr_valid; /* nop */
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_ENDPOINT:
- switch (std->req.bRequest) {
- case UR_GET_STATUS:
- goto tr_handle_get_ep_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_INTERFACE:
- switch (std->req.bRequest) {
- case UR_SET_INTERFACE:
- goto tr_handle_set_interface;
- case UR_CLEAR_FEATURE:
- goto tr_valid; /* nop */
- case UR_SET_FEATURE:
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_INTERFACE:
- switch (std->req.bRequest) {
- case UR_GET_INTERFACE:
- goto tr_handle_get_interface;
- case UR_GET_STATUS:
- goto tr_handle_get_iface_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_CLASS_INTERFACE:
- case UT_WRITE_VENDOR_INTERFACE:
- /* XXX forward */
- break;
-
- case UT_READ_CLASS_INTERFACE:
- case UT_READ_VENDOR_INTERFACE:
- /* XXX forward */
- break;
-
- case UT_WRITE_CLASS_DEVICE:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- goto tr_valid;
- case UR_SET_DESCRIPTOR:
- case UR_SET_FEATURE:
- break;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_CLASS_OTHER:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- goto tr_handle_clear_port_feature;
- case UR_SET_FEATURE:
- goto tr_handle_set_port_feature;
- case UR_CLEAR_TT_BUFFER:
- case UR_RESET_TT:
- case UR_STOP_TT:
- goto tr_valid;
-
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_CLASS_OTHER:
- switch (std->req.bRequest) {
- case UR_GET_TT_STATE:
- goto tr_handle_get_tt_state;
- case UR_GET_STATUS:
- goto tr_handle_get_port_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_CLASS_DEVICE:
- switch (std->req.bRequest) {
- case UR_GET_DESCRIPTOR:
- goto tr_handle_get_class_descriptor;
- case UR_GET_STATUS:
- goto tr_handle_get_class_status;
-
- default:
- goto tr_stalled;
- }
- break;
- default:
- goto tr_stalled;
- }
- goto tr_valid;
-
-tr_handle_get_descriptor:
- switch (value >> 8) {
- case UDESC_DEVICE:
- if (value & 0xff) {
- goto tr_stalled;
- }
- std->len = sizeof(at91dci_devd);
- std->ptr = USB_ADD_BYTES(&at91dci_devd, 0);
- goto tr_valid;
- case UDESC_CONFIG:
- if (value & 0xff) {
- goto tr_stalled;
- }
- std->len = sizeof(at91dci_confd);
- std->ptr = USB_ADD_BYTES(&at91dci_confd, 0);
- goto tr_valid;
- case UDESC_STRING:
- switch (value & 0xff) {
- case 0: /* Language table */
- std->len = sizeof(at91dci_langtab);
- std->ptr = USB_ADD_BYTES(&at91dci_langtab, 0);
- goto tr_valid;
-
- case 1: /* Vendor */
- std->len = sizeof(at91dci_vendor);
- std->ptr = USB_ADD_BYTES(&at91dci_vendor, 0);
- goto tr_valid;
-
- case 2: /* Product */
- std->len = sizeof(at91dci_product);
- std->ptr = USB_ADD_BYTES(&at91dci_product, 0);
- goto tr_valid;
- default:
- break;
- }
- break;
- default:
- goto tr_stalled;
- }
- goto tr_stalled;
-
-tr_handle_get_config:
- std->len = 1;
- sc->sc_hub_temp.wValue[0] = sc->sc_conf;
- goto tr_valid;
-
-tr_handle_get_status:
- std->len = 2;
- USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
- goto tr_valid;
-
-tr_handle_set_address:
- if (value & 0xFF00) {
- goto tr_stalled;
- }
- sc->sc_rt_addr = value;
- goto tr_valid;
-
-tr_handle_set_config:
- if (value >= 2) {
- goto tr_stalled;
- }
- sc->sc_conf = value;
- goto tr_valid;
-
-tr_handle_get_interface:
- std->len = 1;
- sc->sc_hub_temp.wValue[0] = 0;
- goto tr_valid;
-
-tr_handle_get_tt_state:
-tr_handle_get_class_status:
-tr_handle_get_iface_status:
-tr_handle_get_ep_status:
- std->len = 2;
- USETW(sc->sc_hub_temp.wValue, 0);
- goto tr_valid;
-
-tr_handle_set_halt:
-tr_handle_set_interface:
-tr_handle_set_wakeup:
-tr_handle_clear_wakeup:
-tr_handle_clear_halt:
- goto tr_valid;
-
-tr_handle_clear_port_feature:
- if (index != 1) {
- goto tr_stalled;
- }
- DPRINTFN(9, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
-
- switch (value) {
- case UHF_PORT_SUSPEND:
- at91dci_wakeup_peer(xfer);
- break;
-
- case UHF_PORT_ENABLE:
- sc->sc_flags.port_enabled = 0;
- break;
-
- case UHF_PORT_TEST:
- case UHF_PORT_INDICATOR:
- case UHF_C_PORT_ENABLE:
- case UHF_C_PORT_OVER_CURRENT:
- case UHF_C_PORT_RESET:
- /* nops */
- break;
- case UHF_PORT_POWER:
- sc->sc_flags.port_powered = 0;
- at91dci_pull_down(sc);
- at91dci_clocks_off(sc);
- break;
- case UHF_C_PORT_CONNECTION:
- sc->sc_flags.change_connect = 0;
- break;
- case UHF_C_PORT_SUSPEND:
- sc->sc_flags.change_suspend = 0;
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- goto tr_valid;
-
-tr_handle_set_port_feature:
- if (index != 1) {
- goto tr_stalled;
- }
- DPRINTFN(9, "UR_SET_PORT_FEATURE\n");
-
- switch (value) {
- case UHF_PORT_ENABLE:
- sc->sc_flags.port_enabled = 1;
- break;
- case UHF_PORT_SUSPEND:
- case UHF_PORT_RESET:
- case UHF_PORT_TEST:
- case UHF_PORT_INDICATOR:
- /* nops */
- break;
- case UHF_PORT_POWER:
- sc->sc_flags.port_powered = 1;
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- goto tr_valid;
-
-tr_handle_get_port_status:
-
- DPRINTFN(9, "UR_GET_PORT_STATUS\n");
-
- if (index != 1) {
- goto tr_stalled;
- }
- if (sc->sc_flags.status_vbus) {
- at91dci_clocks_on(sc);
- at91dci_pull_up(sc);
- } else {
- at91dci_pull_down(sc);
- at91dci_clocks_off(sc);
- }
-
- /* Select FULL-speed and Device Side Mode */
-
- value = UPS_PORT_MODE_DEVICE;
-
- if (sc->sc_flags.port_powered) {
- value |= UPS_PORT_POWER;
- }
- if (sc->sc_flags.port_enabled) {
- value |= UPS_PORT_ENABLED;
- }
- if (sc->sc_flags.status_vbus &&
- sc->sc_flags.status_bus_reset) {
- value |= UPS_CURRENT_CONNECT_STATUS;
- }
- if (sc->sc_flags.status_suspend) {
- value |= UPS_SUSPEND;
- }
- USETW(sc->sc_hub_temp.ps.wPortStatus, value);
-
- value = 0;
-
- if (sc->sc_flags.change_connect) {
- value |= UPS_C_CONNECT_STATUS;
-
- if (sc->sc_flags.status_vbus &&
- sc->sc_flags.status_bus_reset) {
- /* reset endpoint flags */
- bzero(sc->sc_ep_flags, sizeof(sc->sc_ep_flags));
- }
- }
- if (sc->sc_flags.change_suspend) {
- value |= UPS_C_SUSPEND;
- }
- USETW(sc->sc_hub_temp.ps.wPortChange, value);
- std->len = sizeof(sc->sc_hub_temp.ps);
- goto tr_valid;
-
-tr_handle_get_class_descriptor:
- if (value & 0xFF) {
- goto tr_stalled;
- }
- std->ptr = USB_ADD_BYTES(&at91dci_hubd, 0);
- std->len = sizeof(at91dci_hubd);
- goto tr_valid;
-
-tr_stalled:
- std->err = USB_ERR_STALLED;
-tr_valid:
-done:
- return;
-}
-
-static void
-at91dci_root_ctrl_poll(struct at91dci_softc *sc)
-{
- usb2_sw_transfer(&sc->sc_root_ctrl,
- &at91dci_root_ctrl_done);
-}
-
-struct usb2_pipe_methods at91dci_root_ctrl_methods =
-{
- .open = at91dci_root_ctrl_open,
- .close = at91dci_root_ctrl_close,
- .enter = at91dci_root_ctrl_enter,
- .start = at91dci_root_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 0,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci root interrupt support
- *------------------------------------------------------------------------*/
-static void
-at91dci_root_intr_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_root_intr_close(struct usb2_xfer *xfer)
-{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_intr.xfer == xfer) {
- sc->sc_root_intr.xfer = NULL;
- }
- at91dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-at91dci_root_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_root_intr_start(struct usb2_xfer *xfer)
-{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_intr.xfer = xfer;
-}
-
-struct usb2_pipe_methods at91dci_root_intr_methods =
-{
- .open = at91dci_root_intr_open,
- .close = at91dci_root_intr_close,
- .enter = at91dci_root_intr_enter,
- .start = at91dci_root_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-static void
-at91dci_xfer_setup(struct usb2_setup_params *parm)
-{
- const struct usb2_hw_ep_profile *pf;
- struct at91dci_softc *sc;
- struct usb2_xfer *xfer;
- void *last_obj;
- uint32_t ntd;
- uint32_t n;
- uint8_t ep_no;
-
- sc = AT9100_DCI_BUS2SC(parm->udev->bus);
- xfer = parm->curr_xfer;
-
- /*
- * NOTE: This driver does not use any of the parameters that
- * are computed from the following values. Just set some
- * reasonable dummies:
- */
- parm->hc_max_packet_size = 0x500;
- parm->hc_max_packet_count = 1;
- parm->hc_max_frame_size = 0x500;
-
- usb2_transfer_setup_sub(parm);
-
- /*
- * compute maximum number of TDs
- */
- if (parm->methods == &at91dci_device_ctrl_methods) {
-
- ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC 1 */
- + 1 /* SYNC 2 */ ;
-
- } else if (parm->methods == &at91dci_device_bulk_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else if (parm->methods == &at91dci_device_intr_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else if (parm->methods == &at91dci_device_isoc_fs_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else {
-
- ntd = 0;
- }
-
- /*
- * check if "usb2_transfer_setup_sub" set an error
- */
- if (parm->err) {
- return;
- }
- /*
- * allocate transfer descriptors
- */
- last_obj = NULL;
-
- /*
- * get profile stuff
- */
- if (ntd) {
-
- ep_no = xfer->endpoint & UE_ADDR;
- at91dci_get_hw_ep_profile(parm->udev, &pf, ep_no);
-
- if (pf == NULL) {
- /* should not happen */
- parm->err = USB_ERR_INVAL;
- return;
- }
- } else {
- ep_no = 0;
- pf = NULL;
- }
-
- /* align data */
- parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
-
- for (n = 0; n != ntd; n++) {
-
- struct at91dci_td *td;
-
- if (parm->buf) {
-
- td = USB_ADD_BYTES(parm->buf, parm->size[0]);
-
- /* init TD */
- td->io_tag = sc->sc_io_tag;
- td->io_hdl = sc->sc_io_hdl;
- td->max_packet_size = xfer->max_packet_size;
- td->status_reg = AT91_UDP_CSR(ep_no);
- td->fifo_reg = AT91_UDP_FDR(ep_no);
- if (pf->support_multi_buffer) {
- td->support_multi_buffer = 1;
- }
- td->obj_next = last_obj;
-
- last_obj = td;
- }
- parm->size[0] += sizeof(*td);
- }
-
- xfer->td_start[0] = last_obj;
-}
-
-static void
-at91dci_xfer_unsetup(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-at91dci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
- struct usb2_pipe *pipe)
-{
- struct at91dci_softc *sc = AT9100_DCI_BUS2SC(udev->bus);
-
- DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
- pipe, udev->address,
- edesc->bEndpointAddress, udev->flags.usb2_mode,
- sc->sc_rt_addr);
-
- if (udev->device_index == sc->sc_rt_addr) {
-
- if (udev->flags.usb2_mode != USB_MODE_HOST) {
- /* not supported */
- return;
- }
- switch (edesc->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &at91dci_root_ctrl_methods;
- break;
- case UE_DIR_IN | AT9100_DCI_INTR_ENDPT:
- pipe->methods = &at91dci_root_intr_methods;
- break;
- default:
- /* do nothing */
- break;
- }
- } else {
-
- if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
- /* not supported */
- return;
- }
- if (udev->speed != USB_SPEED_FULL) {
- /* not supported */
- return;
- }
- switch (edesc->bmAttributes & UE_XFERTYPE) {
- case UE_CONTROL:
- pipe->methods = &at91dci_device_ctrl_methods;
- break;
- case UE_INTERRUPT:
- pipe->methods = &at91dci_device_intr_methods;
- break;
- case UE_ISOCHRONOUS:
- pipe->methods = &at91dci_device_isoc_fs_methods;
- break;
- case UE_BULK:
- pipe->methods = &at91dci_device_bulk_methods;
- break;
- default:
- /* do nothing */
- break;
- }
- }
-}
-
-struct usb2_bus_methods at91dci_bus_methods =
-{
- .pipe_init = &at91dci_pipe_init,
- .xfer_setup = &at91dci_xfer_setup,
- .xfer_unsetup = &at91dci_xfer_unsetup,
- .do_poll = &at91dci_do_poll,
- .get_hw_ep_profile = &at91dci_get_hw_ep_profile,
- .set_stall = &at91dci_set_stall,
- .clear_stall = &at91dci_clear_stall,
- .roothub_exec = &at91dci_root_ctrl_task,
-};
diff --git a/sys/dev/usb2/controller/at91dci.h b/sys/dev/usb2/controller/at91dci.h
deleted file mode 100644
index d386307..0000000
--- a/sys/dev/usb2/controller/at91dci.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2006 ATMEL
- * Copyright (c) 2007 Hans Petter Selasky <hselasky@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.
- */
-
-/*
- * USB Device Port (UDP) register definition, based on
- * "AT91RM9200.h" provided by ATMEL.
- */
-
-#ifndef _AT9100_DCI_H_
-#define _AT9100_DCI_H_
-
-#define AT91_MAX_DEVICES (USB_MIN_DEVICES + 1)
-
-#define AT91_UDP_FRM 0x00 /* Frame number register */
-#define AT91_UDP_FRM_MASK (0x7FF << 0) /* Frame Number as Defined in
- * the Packet Field Formats */
-#define AT91_UDP_FRM_ERR (0x1 << 16) /* Frame Error */
-#define AT91_UDP_FRM_OK (0x1 << 17) /* Frame OK */
-
-#define AT91_UDP_GSTATE 0x04 /* Global state register */
-#define AT91_UDP_GSTATE_ADDR (0x1 << 0) /* Addressed state */
-#define AT91_UDP_GSTATE_CONFG (0x1 << 1) /* Configured */
-#define AT91_UDP_GSTATE_ESR (0x1 << 2) /* Enable Send Resume */
-#define AT91_UDP_GSTATE_RSM (0x1 << 3) /* A Resume Has Been Sent to
- * the Host */
-#define AT91_UDP_GSTATE_RMW (0x1 << 4) /* Remote Wake Up Enable */
-
-#define AT91_UDP_FADDR 0x08 /* Function Address Register */
-#define AT91_UDP_FADDR_MASK (0x7F << 0)/* Function Address Mask */
-#define AT91_UDP_FADDR_EN (0x1 << 8)/* Function Enable */
-
-#define AT91_UDP_RES0 0x0C /* Reserved 0 */
-
-#define AT91_UDP_IER 0x10 /* Interrupt Enable Register */
-#define AT91_UDP_IDR 0x14 /* Interrupt Disable Register */
-#define AT91_UDP_IMR 0x18 /* Interrupt Mask Register */
-#define AT91_UDP_ISR 0x1C /* Interrupt Status Register */
-#define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */
-#define AT91_UDP_INT_EP(n) (0x1 <<(n))/* Endpoint "n" Interrupt */
-#define AT91_UDP_INT_RXSUSP (0x1 << 8)/* USB Suspend Interrupt */
-#define AT91_UDP_INT_RXRSM (0x1 << 9)/* USB Resume Interrupt */
-#define AT91_UDP_INT_EXTRSM (0x1 << 10)/* USB External Resume Interrupt */
-#define AT91_UDP_INT_SOFINT (0x1 << 11)/* USB Start Of frame Interrupt */
-#define AT91_UDP_INT_END_BR (0x1 << 12)/* USB End Of Bus Reset Interrupt */
-#define AT91_UDP_INT_WAKEUP (0x1 << 13)/* USB Resume Interrupt */
-
-#define AT91_UDP_INT_BUS \
- (AT91_UDP_INT_RXSUSP|AT91_UDP_INT_RXRSM| \
- AT91_UDP_INT_END_BR)
-
-#define AT91_UDP_INT_EPS \
- (AT91_UDP_INT_EP(0)|AT91_UDP_INT_EP(1)| \
- AT91_UDP_INT_EP(2)|AT91_UDP_INT_EP(3)| \
- AT91_UDP_INT_EP(4)|AT91_UDP_INT_EP(5))
-
-#define AT91_UDP_INT_DEFAULT \
- (AT91_UDP_INT_EPS|AT91_UDP_INT_BUS)
-
-#define AT91_UDP_RES1 0x24 /* Reserved 1 */
-#define AT91_UDP_RST 0x28 /* Reset Endpoint Register */
-#define AT91_UDP_RST_EP(n) (0x1 << (n))/* Reset Endpoint "n" */
-
-#define AT91_UDP_RES2 0x2C /* Reserved 2 */
-
-#define AT91_UDP_CSR(n) (0x30 + (4*(n)))/* Endpoint Control and Status
- * Register */
-#define AT91_UDP_CSR_TXCOMP (0x1 << 0) /* Generates an IN packet with data
- * previously written in the DPR */
-#define AT91_UDP_CSR_RX_DATA_BK0 (0x1 << 1) /* Receive Data Bank 0 */
-#define AT91_UDP_CSR_RXSETUP (0x1 << 2) /* Sends STALL to the Host
- * (Control endpoints) */
-#define AT91_UDP_CSR_ISOERROR (0x1 << 3) /* Isochronous error
- * (Isochronous endpoints) */
-#define AT91_UDP_CSR_STALLSENT (0x1 << 3) /* Stall sent (Control, bulk,
- * interrupt endpoints) */
-#define AT91_UDP_CSR_TXPKTRDY (0x1 << 4) /* Transmit Packet Ready */
-#define AT91_UDP_CSR_FORCESTALL (0x1 << 5) /* Force Stall (used by
- * Control, Bulk and
- * Isochronous endpoints). */
-#define AT91_UDP_CSR_RX_DATA_BK1 (0x1 << 6) /* Receive Data Bank 1 (only
- * used by endpoints with
- * ping-pong attributes). */
-#define AT91_UDP_CSR_DIR (0x1 << 7) /* Transfer Direction */
-#define AT91_UDP_CSR_ET_MASK (0x7 << 8) /* Endpoint transfer type mask */
-#define AT91_UDP_CSR_ET_CTRL (0x0 << 8) /* Control IN+OUT */
-#define AT91_UDP_CSR_ET_ISO (0x1 << 8) /* Isochronous */
-#define AT91_UDP_CSR_ET_BULK (0x2 << 8) /* Bulk */
-#define AT91_UDP_CSR_ET_INT (0x3 << 8) /* Interrupt */
-#define AT91_UDP_CSR_ET_DIR_OUT (0x0 << 8) /* OUT tokens */
-#define AT91_UDP_CSR_ET_DIR_IN (0x4 << 8) /* IN tokens */
-#define AT91_UDP_CSR_DTGLE (0x1 << 11) /* Data Toggle */
-#define AT91_UDP_CSR_EPEDS (0x1 << 15) /* Endpoint Enable Disable */
-#define AT91_UDP_CSR_RXBYTECNT (0x7FF << 16) /* Number Of Bytes Available
- * in the FIFO */
-
-#define AT91_UDP_FDR(n) (0x50 + (4*(n)))/* Endpoint FIFO Data Register */
-#define AT91_UDP_RES3 0x70 /* Reserved 3 */
-#define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */
-#define AT91_UDP_TXVC_DIS (0x1 << 8)
-
-#define AT91_UDP_EP_MAX 6 /* maximum number of endpoints
- * supported */
-
-#define AT91_UDP_READ_4(sc, reg) \
- bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
-
-#define AT91_UDP_WRITE_4(sc, reg, data) \
- bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data)
-
-struct at91dci_td;
-
-typedef uint8_t (at91dci_cmd_t)(struct at91dci_td *td);
-
-struct at91dci_td {
- bus_space_tag_t io_tag;
- bus_space_handle_t io_hdl;
- struct at91dci_td *obj_next;
- at91dci_cmd_t *func;
- struct usb2_page_cache *pc;
- uint32_t offset;
- uint32_t remainder;
- uint16_t max_packet_size;
- uint8_t status_reg;
- uint8_t fifo_reg;
- uint8_t fifo_bank:1;
- uint8_t error:1;
- uint8_t alt_next:1;
- uint8_t short_pkt:1;
- uint8_t support_multi_buffer:1;
- uint8_t did_stall:1;
-};
-
-struct at91dci_std_temp {
- at91dci_cmd_t *func;
- struct usb2_page_cache *pc;
- struct at91dci_td *td;
- struct at91dci_td *td_next;
- uint32_t len;
- uint32_t offset;
- uint16_t max_frame_size;
- uint8_t short_pkt;
- /*
- * short_pkt = 0: transfer should be short terminated
- * short_pkt = 1: transfer should not be short terminated
- */
- uint8_t setup_alt_next;
-};
-
-struct at91dci_config_desc {
- struct usb2_config_descriptor confd;
- struct usb2_interface_descriptor ifcd;
- struct usb2_endpoint_descriptor endpd;
-} __packed;
-
-union at91dci_hub_temp {
- uWord wValue;
- struct usb2_port_status ps;
-};
-
-struct at91dci_ep_flags {
- uint8_t fifo_bank:1; /* hardware specific */
-};
-
-struct at91dci_flags {
- uint8_t change_connect:1;
- uint8_t change_suspend:1;
- uint8_t status_suspend:1; /* set if suspended */
- uint8_t status_vbus:1; /* set if present */
- uint8_t status_bus_reset:1; /* set if reset complete */
- uint8_t remote_wakeup:1;
- uint8_t self_powered:1;
- uint8_t clocks_off:1;
- uint8_t port_powered:1;
- uint8_t port_enabled:1;
- uint8_t d_pulled_up:1;
-};
-
-struct at91dci_softc {
- struct usb2_bus sc_bus;
- union at91dci_hub_temp sc_hub_temp;
- LIST_HEAD(, usb2_xfer) sc_interrupt_list_head;
- struct usb2_sw_transfer sc_root_ctrl;
- struct usb2_sw_transfer sc_root_intr;
-
- struct usb2_device *sc_devices[AT91_MAX_DEVICES];
- struct resource *sc_io_res;
- struct resource *sc_irq_res;
- void *sc_intr_hdl;
- bus_size_t sc_io_size;
- bus_space_tag_t sc_io_tag;
- bus_space_handle_t sc_io_hdl;
-
- void (*sc_clocks_on) (void *arg);
- void (*sc_clocks_off) (void *arg);
- void *sc_clocks_arg;
-
- void (*sc_pull_up) (void *arg);
- void (*sc_pull_down) (void *arg);
- void *sc_pull_arg;
-
- uint8_t sc_rt_addr; /* root HUB address */
- uint8_t sc_dv_addr; /* device address */
- uint8_t sc_conf; /* root HUB config */
-
- uint8_t sc_hub_idata[1];
-
- struct at91dci_flags sc_flags;
- struct at91dci_ep_flags sc_ep_flags[AT91_UDP_EP_MAX];
-};
-
-/* prototypes */
-
-usb2_error_t at91dci_init(struct at91dci_softc *sc);
-void at91dci_uninit(struct at91dci_softc *sc);
-void at91dci_suspend(struct at91dci_softc *sc);
-void at91dci_resume(struct at91dci_softc *sc);
-void at91dci_interrupt(struct at91dci_softc *sc);
-void at91dci_vbus_interrupt(struct at91dci_softc *sc, uint8_t is_on);
-
-#endif /* _AT9100_DCI_H_ */
diff --git a/sys/dev/usb2/controller/at91dci_atmelarm.c b/sys/dev/usb2/controller/at91dci_atmelarm.c
deleted file mode 100644
index 39d3782..0000000
--- a/sys/dev/usb2/controller/at91dci_atmelarm.c
+++ /dev/null
@@ -1,347 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2007-2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/at91dci.h>
-
-#include <sys/rman.h>
-
-#include <arm/at91/at91_pmcvar.h>
-#include <arm/at91/at91rm92reg.h>
-#include <arm/at91/at91_pio_rm9200.h>
-#include <arm/at91/at91_piovar.h>
-
-#define MEM_RID 0
-
-/* Pin Definitions - do they belong here or somewhere else ? */
-
-#define VBUS_MASK AT91C_PIO_PB24
-#define VBUS_BASE AT91RM92_PIOB_BASE
-
-#define PULLUP_MASK AT91C_PIO_PB22
-#define PULLUP_BASE AT91RM92_PIOB_BASE
-
-static device_probe_t at91_udp_probe;
-static device_attach_t at91_udp_attach;
-static device_detach_t at91_udp_detach;
-static device_shutdown_t at91_udp_shutdown;
-
-struct at91_udp_softc {
- struct at91dci_softc sc_dci; /* must be first */
- struct at91_pmc_clock *sc_iclk;
- struct at91_pmc_clock *sc_fclk;
- struct resource *sc_vbus_irq_res;
- void *sc_vbus_intr_hdl;
-};
-
-static void
-at91_vbus_poll(struct at91_udp_softc *sc)
-{
- uint32_t temp;
- uint8_t vbus_val;
-
- /* XXX temporary clear interrupts here */
-
- temp = at91_pio_gpio_clear_interrupt(VBUS_BASE);
-
- /* just forward it */
-
- vbus_val = at91_pio_gpio_get(VBUS_BASE, VBUS_MASK);
- at91dci_vbus_interrupt(&sc->sc_dci, vbus_val);
-}
-
-static void
-at91_udp_clocks_on(void *arg)
-{
- struct at91_udp_softc *sc = arg;
-
- at91_pmc_clock_enable(sc->sc_iclk);
- at91_pmc_clock_enable(sc->sc_fclk);
-}
-
-static void
-at91_udp_clocks_off(void *arg)
-{
- struct at91_udp_softc *sc = arg;
-
- at91_pmc_clock_disable(sc->sc_fclk);
- at91_pmc_clock_disable(sc->sc_iclk);
-}
-
-static void
-at91_udp_pull_up(void *arg)
-{
- at91_pio_gpio_set(PULLUP_BASE, PULLUP_MASK);
-}
-
-static void
-at91_udp_pull_down(void *arg)
-{
- at91_pio_gpio_clear(PULLUP_BASE, PULLUP_MASK);
-}
-
-static int
-at91_udp_probe(device_t dev)
-{
- device_set_desc(dev, "AT91 integrated AT91_UDP controller");
- return (0);
-}
-
-static int
-at91_udp_attach(device_t dev)
-{
- struct at91_udp_softc *sc = device_get_softc(dev);
- int err;
- int rid;
-
- /* setup AT9100 USB device controller interface softc */
-
- sc->sc_dci.sc_clocks_on = &at91_udp_clocks_on;
- sc->sc_dci.sc_clocks_off = &at91_udp_clocks_off;
- sc->sc_dci.sc_clocks_arg = sc;
- sc->sc_dci.sc_pull_up = &at91_udp_pull_up;
- sc->sc_dci.sc_pull_down = &at91_udp_pull_down;
- sc->sc_dci.sc_pull_arg = sc;
-
- /* initialise some bus fields */
- sc->sc_dci.sc_bus.parent = dev;
- sc->sc_dci.sc_bus.devices = sc->sc_dci.sc_devices;
- sc->sc_dci.sc_bus.devices_max = AT91_MAX_DEVICES;
-
- /* get all DMA memory */
- if (usb2_bus_mem_alloc_all(&sc->sc_dci.sc_bus,
- USB_GET_DMA_TAG(dev), NULL)) {
- return (ENOMEM);
- }
- /*
- * configure VBUS input pin, enable deglitch and enable
- * interrupt :
- */
- at91_pio_use_gpio(VBUS_BASE, VBUS_MASK);
- at91_pio_gpio_input(VBUS_BASE, VBUS_MASK);
- at91_pio_gpio_set_deglitch(VBUS_BASE, VBUS_MASK, 1);
- at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 1);
-
- /*
- * configure PULLUP output pin :
- */
- at91_pio_use_gpio(PULLUP_BASE, PULLUP_MASK);
- at91_pio_gpio_output(PULLUP_BASE, PULLUP_MASK, 0);
-
- at91_udp_pull_down(sc);
-
- /* wait 10ms for pulldown to stabilise */
- usb2_pause_mtx(NULL, hz / 100);
-
- sc->sc_iclk = at91_pmc_clock_ref("udc_clk");
- sc->sc_fclk = at91_pmc_clock_ref("udpck");
-
- rid = MEM_RID;
- sc->sc_dci.sc_io_res =
- bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
-
- if (!(sc->sc_dci.sc_io_res)) {
- err = ENOMEM;
- goto error;
- }
- sc->sc_dci.sc_io_tag = rman_get_bustag(sc->sc_dci.sc_io_res);
- sc->sc_dci.sc_io_hdl = rman_get_bushandle(sc->sc_dci.sc_io_res);
- sc->sc_dci.sc_io_size = rman_get_size(sc->sc_dci.sc_io_res);
-
- rid = 0;
- sc->sc_dci.sc_irq_res =
- bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
- if (!(sc->sc_dci.sc_irq_res)) {
- goto error;
- }
- rid = 1;
- sc->sc_vbus_irq_res =
- bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
- if (!(sc->sc_vbus_irq_res)) {
- goto error;
- }
- sc->sc_dci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
- if (!(sc->sc_dci.sc_bus.bdev)) {
- goto error;
- }
- device_set_ivars(sc->sc_dci.sc_bus.bdev, &sc->sc_dci.sc_bus);
-
-#if (__FreeBSD_version >= 700031)
- err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (void *)at91dci_interrupt, sc, &sc->sc_dci.sc_intr_hdl);
-#else
- err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- (void *)at91dci_interrupt, sc, &sc->sc_dci.sc_intr_hdl);
-#endif
- if (err) {
- sc->sc_dci.sc_intr_hdl = NULL;
- goto error;
- }
-#if (__FreeBSD_version >= 700031)
- err = bus_setup_intr(dev, sc->sc_vbus_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (void *)at91_vbus_poll, sc, &sc->sc_vbus_intr_hdl);
-#else
- err = bus_setup_intr(dev, sc->sc_vbus_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- (void *)at91_vbus_poll, sc, &sc->sc_vbus_intr_hdl);
-#endif
- if (err) {
- sc->sc_vbus_intr_hdl = NULL;
- goto error;
- }
- err = at91dci_init(&sc->sc_dci);
- if (!err) {
- err = device_probe_and_attach(sc->sc_dci.sc_bus.bdev);
- }
- if (err) {
- goto error;
- } else {
- /* poll VBUS one time */
- at91_vbus_poll(sc);
- }
- return (0);
-
-error:
- at91_udp_detach(dev);
- return (ENXIO);
-}
-
-static int
-at91_udp_detach(device_t dev)
-{
- struct at91_udp_softc *sc = device_get_softc(dev);
- device_t bdev;
- int err;
-
- if (sc->sc_dci.sc_bus.bdev) {
- bdev = sc->sc_dci.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
- /* during module unload there are lots of children leftover */
- device_delete_all_children(dev);
-
- /* disable Transceiver */
- AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_TXVC, AT91_UDP_TXVC_DIS);
-
- /* disable and clear all interrupts */
- AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_IDR, 0xFFFFFFFF);
- AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_ICR, 0xFFFFFFFF);
-
- /* disable VBUS interrupt */
- at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 0);
-
- if (sc->sc_vbus_irq_res && sc->sc_vbus_intr_hdl) {
- err = bus_teardown_intr(dev, sc->sc_vbus_irq_res,
- sc->sc_vbus_intr_hdl);
- sc->sc_vbus_intr_hdl = NULL;
- }
- if (sc->sc_vbus_irq_res) {
- bus_release_resource(dev, SYS_RES_IRQ, 1,
- sc->sc_vbus_irq_res);
- sc->sc_vbus_irq_res = NULL;
- }
- if (sc->sc_dci.sc_irq_res && sc->sc_dci.sc_intr_hdl) {
- /*
- * only call at91_udp_uninit() after at91_udp_init()
- */
- at91dci_uninit(&sc->sc_dci);
-
- err = bus_teardown_intr(dev, sc->sc_dci.sc_irq_res,
- sc->sc_dci.sc_intr_hdl);
- sc->sc_dci.sc_intr_hdl = NULL;
- }
- if (sc->sc_dci.sc_irq_res) {
- bus_release_resource(dev, SYS_RES_IRQ, 0,
- sc->sc_dci.sc_irq_res);
- sc->sc_dci.sc_irq_res = NULL;
- }
- if (sc->sc_dci.sc_io_res) {
- bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID,
- sc->sc_dci.sc_io_res);
- sc->sc_dci.sc_io_res = NULL;
- }
- usb2_bus_mem_free_all(&sc->sc_dci.sc_bus, NULL);
-
- /* disable clocks */
- at91_pmc_clock_disable(sc->sc_iclk);
- at91_pmc_clock_disable(sc->sc_fclk);
- at91_pmc_clock_deref(sc->sc_fclk);
- at91_pmc_clock_deref(sc->sc_iclk);
-
- return (0);
-}
-
-static int
-at91_udp_shutdown(device_t dev)
-{
- struct at91_udp_softc *sc = device_get_softc(dev);
- int err;
-
- err = bus_generic_shutdown(dev);
- if (err)
- return (err);
-
- at91dci_uninit(&sc->sc_dci);
-
- return (0);
-}
-
-static device_method_t at91_udp_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, at91_udp_probe),
- DEVMETHOD(device_attach, at91_udp_attach),
- DEVMETHOD(device_detach, at91_udp_detach),
- DEVMETHOD(device_shutdown, at91_udp_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t at91_udp_driver = {
- "at91_udp",
- at91_udp_methods,
- sizeof(struct at91_udp_softc),
-};
-
-static devclass_t at91_udp_devclass;
-
-DRIVER_MODULE(at91_udp, atmelarm, at91_udp_driver, at91_udp_devclass, 0, 0);
diff --git a/sys/dev/usb2/controller/atmegadci.c b/sys/dev/usb2/controller/atmegadci.c
deleted file mode 100644
index bea8835d..0000000
--- a/sys/dev/usb2/controller/atmegadci.c
+++ /dev/null
@@ -1,2327 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2009 Hans Petter Selasky. 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 file contains the driver for the ATMEGA series USB Device
- * Controller
- */
-
-/*
- * NOTE: When the chip detects BUS-reset it will also reset the
- * endpoints, Function-address and more.
- */
-
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR atmegadci_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_hub.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/atmegadci.h>
-
-#define ATMEGA_BUS2SC(bus) \
- ((struct atmegadci_softc *)(((uint8_t *)(bus)) - \
- USB_P2U(&(((struct atmegadci_softc *)0)->sc_bus))))
-
-#define ATMEGA_PC2SC(pc) \
- ATMEGA_BUS2SC((pc)->tag_parent->info->bus)
-
-#if USB_DEBUG
-static int atmegadci_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, atmegadci, CTLFLAG_RW, 0, "USB ATMEGA DCI");
-SYSCTL_INT(_hw_usb2_atmegadci, OID_AUTO, debug, CTLFLAG_RW,
- &atmegadci_debug, 0, "ATMEGA DCI debug level");
-#endif
-
-#define ATMEGA_INTR_ENDPT 1
-
-/* prototypes */
-
-struct usb2_bus_methods atmegadci_bus_methods;
-struct usb2_pipe_methods atmegadci_device_bulk_methods;
-struct usb2_pipe_methods atmegadci_device_ctrl_methods;
-struct usb2_pipe_methods atmegadci_device_intr_methods;
-struct usb2_pipe_methods atmegadci_device_isoc_fs_methods;
-struct usb2_pipe_methods atmegadci_root_ctrl_methods;
-struct usb2_pipe_methods atmegadci_root_intr_methods;
-
-static atmegadci_cmd_t atmegadci_setup_rx;
-static atmegadci_cmd_t atmegadci_data_rx;
-static atmegadci_cmd_t atmegadci_data_tx;
-static atmegadci_cmd_t atmegadci_data_tx_sync;
-static void atmegadci_device_done(struct usb2_xfer *, usb2_error_t);
-static void atmegadci_do_poll(struct usb2_bus *);
-static void atmegadci_root_ctrl_poll(struct atmegadci_softc *);
-static void atmegadci_standard_done(struct usb2_xfer *);
-
-static usb2_sw_transfer_func_t atmegadci_root_intr_done;
-static usb2_sw_transfer_func_t atmegadci_root_ctrl_done;
-
-/*
- * Here is a list of what the chip supports:
- */
-static const struct usb2_hw_ep_profile
- atmegadci_ep_profile[2] = {
-
- [0] = {
- .max_in_frame_size = 64,
- .max_out_frame_size = 64,
- .is_simplex = 1,
- .support_control = 1,
- },
- [1] = {
- .max_in_frame_size = 64,
- .max_out_frame_size = 64,
- .is_simplex = 1,
- .support_multi_buffer = 1,
- .support_bulk = 1,
- .support_interrupt = 1,
- .support_isochronous = 1,
- .support_in = 1,
- .support_out = 1,
- },
-};
-
-static void
-atmegadci_get_hw_ep_profile(struct usb2_device *udev,
- const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr)
-{
- if (ep_addr == 0)
- *ppf = atmegadci_ep_profile;
- else if (ep_addr < ATMEGA_EP_MAX)
- *ppf = atmegadci_ep_profile + 1;
- else
- *ppf = NULL;
-}
-
-static void
-atmegadci_clocks_on(struct atmegadci_softc *sc)
-{
- if (sc->sc_flags.clocks_off &&
- sc->sc_flags.port_powered) {
-
- DPRINTFN(5, "\n");
-
- /* turn on clocks */
- (sc->sc_clocks_on) (&sc->sc_bus);
-
- ATMEGA_WRITE_1(sc, ATMEGA_USBCON,
- ATMEGA_USBCON_USBE |
- ATMEGA_USBCON_OTGPADE |
- ATMEGA_USBCON_VBUSTE);
-
- sc->sc_flags.clocks_off = 0;
-
- /* enable transceiver ? */
- }
-}
-
-static void
-atmegadci_clocks_off(struct atmegadci_softc *sc)
-{
- if (!sc->sc_flags.clocks_off) {
-
- DPRINTFN(5, "\n");
-
- /* disable Transceiver ? */
-
- ATMEGA_WRITE_1(sc, ATMEGA_USBCON,
- ATMEGA_USBCON_USBE |
- ATMEGA_USBCON_OTGPADE |
- ATMEGA_USBCON_FRZCLK |
- ATMEGA_USBCON_VBUSTE);
-
- /* turn clocks off */
- (sc->sc_clocks_off) (&sc->sc_bus);
-
- sc->sc_flags.clocks_off = 1;
- }
-}
-
-static void
-atmegadci_pull_up(struct atmegadci_softc *sc)
-{
- /* pullup D+, if possible */
-
- if (!sc->sc_flags.d_pulled_up &&
- sc->sc_flags.port_powered) {
- sc->sc_flags.d_pulled_up = 1;
- ATMEGA_WRITE_1(sc, ATMEGA_UDCON, 0);
- }
-}
-
-static void
-atmegadci_pull_down(struct atmegadci_softc *sc)
-{
- /* pulldown D+, if possible */
-
- if (sc->sc_flags.d_pulled_up) {
- sc->sc_flags.d_pulled_up = 0;
- ATMEGA_WRITE_1(sc, ATMEGA_UDCON, ATMEGA_UDCON_DETACH);
- }
-}
-
-static void
-atmegadci_wakeup_peer(struct usb2_xfer *xfer)
-{
- struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
- uint8_t use_polling;
- uint8_t temp;
-
- if (!sc->sc_flags.status_suspend) {
- return;
- }
- use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
-
- temp = ATMEGA_READ_1(sc, ATMEGA_UDCON);
- ATMEGA_WRITE_1(sc, ATMEGA_UDCON, temp | ATMEGA_UDCON_RMWKUP);
-
- /* wait 8 milliseconds */
- if (use_polling) {
- /* polling */
- DELAY(8000);
- } else {
- /* Wait for reset to complete. */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 125);
- }
-
- /* hardware should have cleared RMWKUP bit */
-}
-
-static void
-atmegadci_set_address(struct atmegadci_softc *sc, uint8_t addr)
-{
- DPRINTFN(5, "addr=%d\n", addr);
-
- ATMEGA_WRITE_1(sc, ATMEGA_UDADDR, addr);
-
- addr |= ATMEGA_UDADDR_ADDEN;
-
- ATMEGA_WRITE_1(sc, ATMEGA_UDADDR, addr);
-}
-
-static uint8_t
-atmegadci_setup_rx(struct atmegadci_td *td)
-{
- struct atmegadci_softc *sc;
- struct usb2_device_request req;
- uint16_t count;
- uint8_t temp;
-
- /* get pointer to softc */
- sc = ATMEGA_PC2SC(td->pc);
-
- /* select endpoint number */
- ATMEGA_WRITE_1(sc, ATMEGA_UENUM, td->ep_no);
-
- /* check endpoint status */
- temp = ATMEGA_READ_1(sc, ATMEGA_UEINTX);
-
- DPRINTFN(5, "UEINTX=0x%02x\n", temp);
-
- if (!(temp & ATMEGA_UEINTX_RXSTPI)) {
- /* abort any ongoing transfer */
- if (!td->did_stall) {
- DPRINTFN(5, "stalling\n");
- ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
- ATMEGA_UECONX_EPEN |
- ATMEGA_UECONX_STALLRQ);
- td->did_stall = 1;
- }
- goto not_complete;
- }
- /* get the packet byte count */
- count =
- (ATMEGA_READ_1(sc, ATMEGA_UEBCHX) << 8) |
- (ATMEGA_READ_1(sc, ATMEGA_UEBCLX));
-
- /* mask away undefined bits */
- count &= 0x7FF;
-
- /* verify data length */
- if (count != td->remainder) {
- DPRINTFN(0, "Invalid SETUP packet "
- "length, %d bytes\n", count);
- goto not_complete;
- }
- if (count != sizeof(req)) {
- DPRINTFN(0, "Unsupported SETUP packet "
- "length, %d bytes\n", count);
- goto not_complete;
- }
- /* receive data */
- ATMEGA_READ_MULTI_1(sc, ATMEGA_UEDATX,
- (void *)&req, sizeof(req));
-
- /* copy data into real buffer */
- usb2_copy_in(td->pc, 0, &req, sizeof(req));
-
- td->offset = sizeof(req);
- td->remainder = 0;
-
- /* sneak peek the set address */
- if ((req.bmRequestType == UT_WRITE_DEVICE) &&
- (req.bRequest == UR_SET_ADDRESS)) {
- sc->sc_dv_addr = req.wValue[0] & 0x7F;
- } else {
- sc->sc_dv_addr = 0xFF;
- }
-
- /* clear SETUP packet interrupt */
- ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, ~ATMEGA_UEINTX_RXSTPI);
- return (0); /* complete */
-
-not_complete:
- /* we only want to know if there is a SETUP packet */
- ATMEGA_WRITE_1(sc, ATMEGA_UEIENX, ATMEGA_UEIENX_RXSTPE);
- return (1); /* not complete */
-}
-
-static uint8_t
-atmegadci_data_rx(struct atmegadci_td *td)
-{
- struct atmegadci_softc *sc;
- struct usb2_page_search buf_res;
- uint16_t count;
- uint8_t temp;
- uint8_t to;
- uint8_t got_short;
-
- to = 3; /* don't loop forever! */
- got_short = 0;
-
- /* get pointer to softc */
- sc = ATMEGA_PC2SC(td->pc);
-
- /* select endpoint number */
- ATMEGA_WRITE_1(sc, ATMEGA_UENUM, td->ep_no);
-
-repeat:
- /* check if any of the FIFO banks have data */
- /* check endpoint status */
- temp = ATMEGA_READ_1(sc, ATMEGA_UEINTX);
-
- DPRINTFN(5, "temp=0x%02x rem=%u\n", temp, td->remainder);
-
- if (temp & ATMEGA_UEINTX_RXSTPI) {
- if (td->remainder == 0) {
- /*
- * We are actually complete and have
- * received the next SETUP
- */
- DPRINTFN(5, "faking complete\n");
- return (0); /* complete */
- }
- /*
- * USB Host Aborted the transfer.
- */
- td->error = 1;
- return (0); /* complete */
- }
- /* check status */
- if (!(temp & (ATMEGA_UEINTX_FIFOCON |
- ATMEGA_UEINTX_RXOUTI))) {
- /* no data */
- goto not_complete;
- }
- /* get the packet byte count */
- count =
- (ATMEGA_READ_1(sc, ATMEGA_UEBCHX) << 8) |
- (ATMEGA_READ_1(sc, ATMEGA_UEBCLX));
-
- /* mask away undefined bits */
- count &= 0x7FF;
-
- /* verify the packet byte count */
- if (count != td->max_packet_size) {
- if (count < td->max_packet_size) {
- /* we have a short packet */
- td->short_pkt = 1;
- got_short = 1;
- } else {
- /* invalid USB packet */
- td->error = 1;
- return (0); /* we are complete */
- }
- }
- /* verify the packet byte count */
- if (count > td->remainder) {
- /* invalid USB packet */
- td->error = 1;
- return (0); /* we are complete */
- }
- while (count > 0) {
- usb2_get_page(td->pc, td->offset, &buf_res);
-
- /* get correct length */
- if (buf_res.length > count) {
- buf_res.length = count;
- }
- /* receive data */
- ATMEGA_READ_MULTI_1(sc, ATMEGA_UEDATX,
- buf_res.buffer, buf_res.length);
-
- /* update counters */
- count -= buf_res.length;
- td->offset += buf_res.length;
- td->remainder -= buf_res.length;
- }
-
- /* clear OUT packet interrupt */
- ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, ATMEGA_UEINTX_RXOUTI ^ 0xFF);
-
- /* release FIFO bank */
- ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, ATMEGA_UEINTX_FIFOCON ^ 0xFF);
-
- /* check if we are complete */
- if ((td->remainder == 0) || got_short) {
- if (td->short_pkt) {
- /* we are complete */
- return (0);
- }
- /* else need to receive a zero length packet */
- }
- if (--to) {
- goto repeat;
- }
-not_complete:
- /* we only want to know if there is a SETUP packet or OUT packet */
- ATMEGA_WRITE_1(sc, ATMEGA_UEIENX,
- ATMEGA_UEIENX_RXSTPE | ATMEGA_UEIENX_RXOUTE);
- return (1); /* not complete */
-}
-
-static uint8_t
-atmegadci_data_tx(struct atmegadci_td *td)
-{
- struct atmegadci_softc *sc;
- struct usb2_page_search buf_res;
- uint16_t count;
- uint8_t to;
- uint8_t temp;
-
- to = 3; /* don't loop forever! */
-
- /* get pointer to softc */
- sc = ATMEGA_PC2SC(td->pc);
-
- /* select endpoint number */
- ATMEGA_WRITE_1(sc, ATMEGA_UENUM, td->ep_no);
-
-repeat:
-
- /* check endpoint status */
- temp = ATMEGA_READ_1(sc, ATMEGA_UEINTX);
-
- DPRINTFN(5, "temp=0x%02x rem=%u\n", temp, td->remainder);
-
- if (temp & ATMEGA_UEINTX_RXSTPI) {
- /*
- * The current transfer was aborted
- * by the USB Host
- */
- td->error = 1;
- return (0); /* complete */
- }
- if (!(temp & (ATMEGA_UEINTX_FIFOCON |
- ATMEGA_UEINTX_TXINI))) {
- /* cannot write any data */
- goto not_complete;
- }
- count = td->max_packet_size;
- if (td->remainder < count) {
- /* we have a short packet */
- td->short_pkt = 1;
- count = td->remainder;
- }
- while (count > 0) {
-
- usb2_get_page(td->pc, td->offset, &buf_res);
-
- /* get correct length */
- if (buf_res.length > count) {
- buf_res.length = count;
- }
- /* transmit data */
- ATMEGA_WRITE_MULTI_1(sc, ATMEGA_UEDATX,
- buf_res.buffer, buf_res.length);
-
- /* update counters */
- count -= buf_res.length;
- td->offset += buf_res.length;
- td->remainder -= buf_res.length;
- }
-
- /* clear IN packet interrupt */
- ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, 0xFF ^ ATMEGA_UEINTX_TXINI);
-
- /* allocate FIFO bank */
- ATMEGA_WRITE_1(sc, ATMEGA_UEINTX, 0xFF ^ ATMEGA_UEINTX_FIFOCON);
-
- /* check remainder */
- if (td->remainder == 0) {
- if (td->short_pkt) {
- return (0); /* complete */
- }
- /* else we need to transmit a short packet */
- }
- if (--to) {
- goto repeat;
- }
-not_complete:
- /* we only want to know if there is a SETUP packet or free IN packet */
- ATMEGA_WRITE_1(sc, ATMEGA_UEIENX,
- ATMEGA_UEIENX_RXSTPE | ATMEGA_UEIENX_TXINE);
- return (1); /* not complete */
-}
-
-static uint8_t
-atmegadci_data_tx_sync(struct atmegadci_td *td)
-{
- struct atmegadci_softc *sc;
- uint8_t temp;
-
- /* get pointer to softc */
- sc = ATMEGA_PC2SC(td->pc);
-
- /* select endpoint number */
- ATMEGA_WRITE_1(sc, ATMEGA_UENUM, td->ep_no);
-
- /* check endpoint status */
- temp = ATMEGA_READ_1(sc, ATMEGA_UEINTX);
-
- DPRINTFN(5, "temp=0x%02x\n", temp);
-
- if (temp & ATMEGA_UEINTX_RXSTPI) {
- DPRINTFN(5, "faking complete\n");
- /* Race condition */
- return (0); /* complete */
- }
- /*
- * The control endpoint has only got one bank, so if that bank
- * is free the packet has been transferred!
- */
- if (!(temp & (ATMEGA_UEINTX_FIFOCON |
- ATMEGA_UEINTX_TXINI))) {
- /* cannot write any data */
- goto not_complete;
- }
- if (sc->sc_dv_addr != 0xFF) {
- /* set new address */
- atmegadci_set_address(sc, sc->sc_dv_addr);
- }
- return (0); /* complete */
-
-not_complete:
- /* we only want to know if there is a SETUP packet or free IN packet */
- ATMEGA_WRITE_1(sc, ATMEGA_UEIENX,
- ATMEGA_UEIENX_RXSTPE | ATMEGA_UEIENX_TXINE);
- return (1); /* not complete */
-}
-
-static uint8_t
-atmegadci_xfer_do_fifo(struct usb2_xfer *xfer)
-{
- struct atmegadci_td *td;
-
- DPRINTFN(9, "\n");
-
- td = xfer->td_transfer_cache;
- while (1) {
- if ((td->func) (td)) {
- /* operation in progress */
- break;
- }
- if (((void *)td) == xfer->td_transfer_last) {
- goto done;
- }
- if (td->error) {
- goto done;
- } else if (td->remainder > 0) {
- /*
- * We had a short transfer. If there is no alternate
- * next, stop processing !
- */
- if (!td->alt_next) {
- goto done;
- }
- }
- /*
- * Fetch the next transfer descriptor and transfer
- * some flags to the next transfer descriptor
- */
- td = td->obj_next;
- xfer->td_transfer_cache = td;
- }
- return (1); /* not complete */
-
-done:
- /* compute all actual lengths */
-
- atmegadci_standard_done(xfer);
- return (0); /* complete */
-}
-
-static void
-atmegadci_interrupt_poll(struct atmegadci_softc *sc)
-{
- struct usb2_xfer *xfer;
-
-repeat:
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
- if (!atmegadci_xfer_do_fifo(xfer)) {
- /* queue has been modified */
- goto repeat;
- }
- }
-}
-
-static void
-atmegadci_vbus_interrupt(struct atmegadci_softc *sc, uint8_t is_on)
-{
- DPRINTFN(5, "vbus = %u\n", is_on);
-
- if (is_on) {
- if (!sc->sc_flags.status_vbus) {
- sc->sc_flags.status_vbus = 1;
-
- /* complete root HUB interrupt endpoint */
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &atmegadci_root_intr_done);
- }
- } else {
- if (sc->sc_flags.status_vbus) {
- sc->sc_flags.status_vbus = 0;
- sc->sc_flags.status_bus_reset = 0;
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 0;
- sc->sc_flags.change_connect = 1;
-
- /* complete root HUB interrupt endpoint */
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &atmegadci_root_intr_done);
- }
- }
-}
-
-void
-atmegadci_interrupt(struct atmegadci_softc *sc)
-{
- uint8_t status;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* read interrupt status */
- status = ATMEGA_READ_1(sc, ATMEGA_UDINT);
-
- /* clear all set interrupts */
- ATMEGA_WRITE_1(sc, ATMEGA_UDINT, ~status);
-
- /* check for any bus state change interrupts */
- if (status & ATMEGA_UDINT_EORSTI) {
-
- DPRINTFN(5, "end of reset\n");
-
- /* set correct state */
- sc->sc_flags.status_bus_reset = 1;
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 0;
- sc->sc_flags.change_connect = 1;
-
- /* disable resume interrupt */
- ATMEGA_WRITE_1(sc, ATMEGA_UDIEN,
- ATMEGA_UDINT_SUSPE |
- ATMEGA_UDINT_EORSTE);
-
- /* complete root HUB interrupt endpoint */
- usb2_sw_transfer(&sc->sc_root_intr,
- &atmegadci_root_intr_done);
- }
- /*
- * If resume and suspend is set at the same time we interpret
- * that like RESUME. Resume is set when there is at least 3
- * milliseconds of inactivity on the USB BUS.
- */
- if (status & ATMEGA_UDINT_EORSMI) {
-
- DPRINTFN(5, "resume interrupt\n");
-
- if (sc->sc_flags.status_suspend) {
- /* update status bits */
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 1;
-
- /* disable resume interrupt */
- ATMEGA_WRITE_1(sc, ATMEGA_UDIEN,
- ATMEGA_UDINT_SUSPE |
- ATMEGA_UDINT_EORSTE);
-
- /* complete root HUB interrupt endpoint */
- usb2_sw_transfer(&sc->sc_root_intr,
- &atmegadci_root_intr_done);
- }
- } else if (status & ATMEGA_UDINT_SUSPI) {
-
- DPRINTFN(5, "suspend interrupt\n");
-
- if (!sc->sc_flags.status_suspend) {
- /* update status bits */
- sc->sc_flags.status_suspend = 1;
- sc->sc_flags.change_suspend = 1;
-
- /* disable suspend interrupt */
- ATMEGA_WRITE_1(sc, ATMEGA_UDIEN,
- ATMEGA_UDINT_EORSMI |
- ATMEGA_UDINT_EORSTE);
-
- /* complete root HUB interrupt endpoint */
- usb2_sw_transfer(&sc->sc_root_intr,
- &atmegadci_root_intr_done);
- }
- }
- /* check VBUS */
- status = ATMEGA_READ_1(sc, ATMEGA_USBINT);
-
- /* clear all set interrupts */
- ATMEGA_WRITE_1(sc, ATMEGA_USBINT, ~status);
-
- if (status & ATMEGA_USBINT_VBUSTI) {
- uint8_t temp;
-
- temp = ATMEGA_READ_1(sc, ATMEGA_USBSTA);
- atmegadci_vbus_interrupt(sc, temp & ATMEGA_USBSTA_VBUS);
- }
- /* check for any endpoint interrupts */
- status = ATMEGA_READ_1(sc, ATMEGA_UEINT);
-
- /* clear all set interrupts */
- ATMEGA_WRITE_1(sc, ATMEGA_UEINT, ~status);
-
- if (status) {
-
- DPRINTFN(5, "real endpoint interrupt 0x%02x\n", status);
-
- atmegadci_interrupt_poll(sc);
- }
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-static void
-atmegadci_setup_standard_chain_sub(struct atmegadci_std_temp *temp)
-{
- struct atmegadci_td *td;
-
- /* get current Transfer Descriptor */
- td = temp->td_next;
- temp->td = td;
-
- /* prepare for next TD */
- temp->td_next = td->obj_next;
-
- /* fill out the Transfer Descriptor */
- td->func = temp->func;
- td->pc = temp->pc;
- td->offset = temp->offset;
- td->remainder = temp->len;
- td->error = 0;
- td->did_stall = 0;
- td->short_pkt = temp->short_pkt;
- td->alt_next = temp->setup_alt_next;
-}
-
-static void
-atmegadci_setup_standard_chain(struct usb2_xfer *xfer)
-{
- struct atmegadci_std_temp temp;
- struct atmegadci_softc *sc;
- struct atmegadci_td *td;
- uint32_t x;
- uint8_t ep_no;
- uint8_t need_sync;
-
- DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
- xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
-
- temp.max_frame_size = xfer->max_frame_size;
-
- td = xfer->td_start[0];
- xfer->td_transfer_first = td;
- xfer->td_transfer_cache = td;
-
- /* setup temp */
-
- temp.td = NULL;
- temp.td_next = xfer->td_start[0];
- temp.setup_alt_next = xfer->flags_int.short_frames_ok;
- temp.offset = 0;
-
- sc = ATMEGA_BUS2SC(xfer->xroot->bus);
- ep_no = (xfer->endpoint & UE_ADDR);
-
- /* check if we should prepend a setup message */
-
- if (xfer->flags_int.control_xfr) {
- if (xfer->flags_int.control_hdr) {
-
- temp.func = &atmegadci_setup_rx;
- temp.len = xfer->frlengths[0];
- temp.pc = xfer->frbuffers + 0;
- temp.short_pkt = temp.len ? 1 : 0;
-
- atmegadci_setup_standard_chain_sub(&temp);
- }
- x = 1;
- } else {
- x = 0;
- }
-
- if (x != xfer->nframes) {
- if (xfer->endpoint & UE_DIR_IN) {
- temp.func = &atmegadci_data_tx;
- need_sync = 1;
- } else {
- temp.func = &atmegadci_data_rx;
- need_sync = 0;
- }
-
- /* setup "pc" pointer */
- temp.pc = xfer->frbuffers + x;
- } else {
- need_sync = 0;
- }
- while (x != xfer->nframes) {
-
- /* DATA0 / DATA1 message */
-
- temp.len = xfer->frlengths[x];
-
- x++;
-
- if (x == xfer->nframes) {
- temp.setup_alt_next = 0;
- }
- if (temp.len == 0) {
-
- /* make sure that we send an USB packet */
-
- temp.short_pkt = 0;
-
- } else {
-
- /* regular data transfer */
-
- temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
- }
-
- atmegadci_setup_standard_chain_sub(&temp);
-
- if (xfer->flags_int.isochronous_xfr) {
- temp.offset += temp.len;
- } else {
- /* get next Page Cache pointer */
- temp.pc = xfer->frbuffers + x;
- }
- }
-
- /* always setup a valid "pc" pointer for status and sync */
- temp.pc = xfer->frbuffers + 0;
-
- /* check if we need to sync */
- if (need_sync && xfer->flags_int.control_xfr) {
-
- /* we need a SYNC point after TX */
- temp.func = &atmegadci_data_tx_sync;
- temp.len = 0;
- temp.short_pkt = 0;
-
- atmegadci_setup_standard_chain_sub(&temp);
- }
- /* check if we should append a status stage */
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- /*
- * Send a DATA1 message and invert the current
- * endpoint direction.
- */
- if (xfer->endpoint & UE_DIR_IN) {
- temp.func = &atmegadci_data_rx;
- need_sync = 0;
- } else {
- temp.func = &atmegadci_data_tx;
- need_sync = 1;
- }
- temp.len = 0;
- temp.short_pkt = 0;
-
- atmegadci_setup_standard_chain_sub(&temp);
- if (need_sync) {
- /* we need a SYNC point after TX */
- temp.func = &atmegadci_data_tx_sync;
- temp.len = 0;
- temp.short_pkt = 0;
-
- atmegadci_setup_standard_chain_sub(&temp);
- }
- }
- /* must have at least one frame! */
- td = temp.td;
- xfer->td_transfer_last = td;
-}
-
-static void
-atmegadci_timeout(void *arg)
-{
- struct usb2_xfer *xfer = arg;
-
- DPRINTF("xfer=%p\n", xfer);
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- /* transfer is transferred */
- atmegadci_device_done(xfer, USB_ERR_TIMEOUT);
-}
-
-static void
-atmegadci_start_standard_chain(struct usb2_xfer *xfer)
-{
- DPRINTFN(9, "\n");
-
- /* poll one time - will turn on interrupts */
- if (atmegadci_xfer_do_fifo(xfer)) {
-
- /* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
-
- /* start timeout, if any */
- if (xfer->timeout != 0) {
- usb2_transfer_timeout_ms(xfer,
- &atmegadci_timeout, xfer->timeout);
- }
- }
-}
-
-static void
-atmegadci_root_intr_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
-
- DPRINTFN(9, "\n");
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_PRE_DATA) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- atmegadci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* setup buffer */
- std->ptr = sc->sc_hub_idata;
- std->len = sizeof(sc->sc_hub_idata);
-
- /* set port bit */
- sc->sc_hub_idata[0] = 0x02; /* we only have one port */
-
-done:
- return;
-}
-
-static usb2_error_t
-atmegadci_standard_done_sub(struct usb2_xfer *xfer)
-{
- struct atmegadci_td *td;
- uint32_t len;
- uint8_t error;
-
- DPRINTFN(9, "\n");
-
- td = xfer->td_transfer_cache;
-
- do {
- len = td->remainder;
-
- if (xfer->aframes != xfer->nframes) {
- /*
- * Verify the length and subtract
- * the remainder from "frlengths[]":
- */
- if (len > xfer->frlengths[xfer->aframes]) {
- td->error = 1;
- } else {
- xfer->frlengths[xfer->aframes] -= len;
- }
- }
- /* Check for transfer error */
- if (td->error) {
- /* the transfer is finished */
- error = 1;
- td = NULL;
- break;
- }
- /* Check for short transfer */
- if (len > 0) {
- if (xfer->flags_int.short_frames_ok) {
- /* follow alt next */
- if (td->alt_next) {
- td = td->obj_next;
- } else {
- td = NULL;
- }
- } else {
- /* the transfer is finished */
- td = NULL;
- }
- error = 0;
- break;
- }
- td = td->obj_next;
-
- /* this USB frame is complete */
- error = 0;
- break;
-
- } while (0);
-
- /* update transfer cache */
-
- xfer->td_transfer_cache = td;
-
- return (error ?
- USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
-}
-
-static void
-atmegadci_standard_done(struct usb2_xfer *xfer)
-{
- usb2_error_t err = 0;
-
- DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
- xfer, xfer->pipe);
-
- /* reset scanner */
-
- xfer->td_transfer_cache = xfer->td_transfer_first;
-
- if (xfer->flags_int.control_xfr) {
-
- if (xfer->flags_int.control_hdr) {
-
- err = atmegadci_standard_done_sub(xfer);
- }
- xfer->aframes = 1;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
- while (xfer->aframes != xfer->nframes) {
-
- err = atmegadci_standard_done_sub(xfer);
- xfer->aframes++;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- err = atmegadci_standard_done_sub(xfer);
- }
-done:
- atmegadci_device_done(xfer, err);
-}
-
-/*------------------------------------------------------------------------*
- * atmegadci_device_done
- *
- * NOTE: this function can be called more than one time on the
- * same USB transfer!
- *------------------------------------------------------------------------*/
-static void
-atmegadci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
-{
- struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
- uint8_t ep_no;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
- xfer, xfer->pipe, error);
-
- if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
- ep_no = (xfer->endpoint & UE_ADDR);
-
- /* select endpoint number */
- ATMEGA_WRITE_1(sc, ATMEGA_UENUM, ep_no);
-
- /* disable endpoint interrupt */
- ATMEGA_WRITE_1(sc, ATMEGA_UEIENX, 0);
-
- DPRINTFN(15, "disabled interrupts!\n");
- }
- /* dequeue transfer and start next transfer */
- usb2_transfer_done(xfer, error);
-}
-
-static void
-atmegadci_set_stall(struct usb2_device *udev, struct usb2_xfer *xfer,
- struct usb2_pipe *pipe)
-{
- struct atmegadci_softc *sc;
- uint8_t ep_no;
-
- USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
-
- DPRINTFN(5, "pipe=%p\n", pipe);
-
- if (xfer) {
- /* cancel any ongoing transfers */
- atmegadci_device_done(xfer, USB_ERR_STALLED);
- }
- sc = ATMEGA_BUS2SC(udev->bus);
- /* get endpoint number */
- ep_no = (pipe->edesc->bEndpointAddress & UE_ADDR);
- /* select endpoint number */
- ATMEGA_WRITE_1(sc, ATMEGA_UENUM, ep_no);
- /* set stall */
- ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
- ATMEGA_UECONX_EPEN |
- ATMEGA_UECONX_STALLRQ);
-}
-
-static void
-atmegadci_clear_stall_sub(struct atmegadci_softc *sc, uint8_t ep_no,
- uint8_t ep_type, uint8_t ep_dir)
-{
- uint8_t temp;
-
- if (ep_type == UE_CONTROL) {
- /* clearing stall is not needed */
- return;
- }
- /* select endpoint number */
- ATMEGA_WRITE_1(sc, ATMEGA_UENUM, ep_no);
-
- /* set endpoint reset */
- ATMEGA_WRITE_1(sc, ATMEGA_UERST, ATMEGA_UERST_MASK(ep_no));
-
- /* clear endpoint reset */
- ATMEGA_WRITE_1(sc, ATMEGA_UERST, 0);
-
- /* set stall */
- ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
- ATMEGA_UECONX_EPEN |
- ATMEGA_UECONX_STALLRQ);
-
- /* reset data toggle */
- ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
- ATMEGA_UECONX_EPEN |
- ATMEGA_UECONX_RSTDT);
-
- /* clear stall */
- ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
- ATMEGA_UECONX_EPEN |
- ATMEGA_UECONX_STALLRQC);
-
- if (ep_type == UE_CONTROL) {
- /* one bank, 64-bytes wMaxPacket */
- ATMEGA_WRITE_1(sc, ATMEGA_UECFG0X,
- ATMEGA_UECFG0X_EPTYPE0);
- ATMEGA_WRITE_1(sc, ATMEGA_UECFG1X,
- ATMEGA_UECFG1X_ALLOC |
- ATMEGA_UECFG1X_EPBK0 |
- ATMEGA_UECFG1X_EPSIZE(7));
- } else {
- temp = 0;
- if (ep_type == UE_BULK) {
- temp |= ATMEGA_UECFG0X_EPTYPE2;
- } else if (ep_type == UE_INTERRUPT) {
- temp |= ATMEGA_UECFG0X_EPTYPE3;
- } else {
- temp |= ATMEGA_UECFG0X_EPTYPE1;
- }
- if (ep_dir & UE_DIR_IN) {
- temp |= ATMEGA_UECFG0X_EPDIR;
- }
- /* two banks, 64-bytes wMaxPacket */
- ATMEGA_WRITE_1(sc, ATMEGA_UECFG0X, temp);
- ATMEGA_WRITE_1(sc, ATMEGA_UECFG1X,
- ATMEGA_UECFG1X_ALLOC |
- ATMEGA_UECFG1X_EPBK1 |
- ATMEGA_UECFG1X_EPSIZE(7));
-
- temp = ATMEGA_READ_1(sc, ATMEGA_UESTA0X);
- if (!(temp & ATMEGA_UESTA0X_CFGOK)) {
- DPRINTFN(0, "Chip rejected configuration\n");
- }
- }
-}
-
-static void
-atmegadci_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe)
-{
- struct atmegadci_softc *sc;
- struct usb2_endpoint_descriptor *ed;
-
- DPRINTFN(5, "pipe=%p\n", pipe);
-
- USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
-
- /* check mode */
- if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
- /* not supported */
- return;
- }
- /* get softc */
- sc = ATMEGA_BUS2SC(udev->bus);
-
- /* get endpoint descriptor */
- ed = pipe->edesc;
-
- /* reset endpoint */
- atmegadci_clear_stall_sub(sc,
- (ed->bEndpointAddress & UE_ADDR),
- (ed->bmAttributes & UE_XFERTYPE),
- (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
-}
-
-usb2_error_t
-atmegadci_init(struct atmegadci_softc *sc)
-{
- uint8_t n;
-
- DPRINTF("start\n");
-
- /* set up the bus structure */
- sc->sc_bus.usbrev = USB_REV_1_1;
- sc->sc_bus.methods = &atmegadci_bus_methods;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* enable USB PAD regulator */
- ATMEGA_WRITE_1(sc, ATMEGA_UHWCON,
- ATMEGA_UHWCON_UVREGE);
-
- /* turn on clocks */
- (sc->sc_clocks_on) (&sc->sc_bus);
-
- /* wait a little for things to stabilise */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
-
- /* enable interrupts */
- ATMEGA_WRITE_1(sc, ATMEGA_UDIEN,
- ATMEGA_UDINT_SUSPE |
- ATMEGA_UDINT_EORSTE);
-
- /* reset all endpoints */
- ATMEGA_WRITE_1(sc, ATMEGA_UERST,
- (1 << ATMEGA_EP_MAX) - 1);
-
- /* disable reset */
- ATMEGA_WRITE_1(sc, ATMEGA_UERST, 0);
-
- /* disable all endpoints */
- for (n = 1; n != ATMEGA_EP_MAX; n++) {
-
- /* select endpoint */
- ATMEGA_WRITE_1(sc, ATMEGA_UENUM, n);
-
- /* disable endpoint interrupt */
- ATMEGA_WRITE_1(sc, ATMEGA_UEIENX, 0);
-
- /* disable endpoint */
- ATMEGA_WRITE_1(sc, ATMEGA_UECONX, 0);
- }
-
- /* turn off clocks */
-
- atmegadci_clocks_off(sc);
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-
- /* catch any lost interrupts */
-
- atmegadci_do_poll(&sc->sc_bus);
-
- return (0); /* success */
-}
-
-void
-atmegadci_uninit(struct atmegadci_softc *sc)
-{
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* turn on clocks */
- (sc->sc_clocks_on) (&sc->sc_bus);
-
- /* disable interrupts */
- ATMEGA_WRITE_1(sc, ATMEGA_UDIEN, 0);
-
- /* reset all endpoints */
- ATMEGA_WRITE_1(sc, ATMEGA_UERST,
- (1 << ATMEGA_EP_MAX) - 1);
-
- /* disable reset */
- ATMEGA_WRITE_1(sc, ATMEGA_UERST, 0);
-
- sc->sc_flags.port_powered = 0;
- sc->sc_flags.status_vbus = 0;
- sc->sc_flags.status_bus_reset = 0;
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 0;
- sc->sc_flags.change_connect = 1;
-
- atmegadci_pull_down(sc);
- atmegadci_clocks_off(sc);
-
- /* disable USB PAD regulator */
- ATMEGA_WRITE_1(sc, ATMEGA_UHWCON, 0);
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-void
-atmegadci_suspend(struct atmegadci_softc *sc)
-{
- return;
-}
-
-void
-atmegadci_resume(struct atmegadci_softc *sc)
-{
- return;
-}
-
-static void
-atmegadci_do_poll(struct usb2_bus *bus)
-{
- struct atmegadci_softc *sc = ATMEGA_BUS2SC(bus);
-
- USB_BUS_LOCK(&sc->sc_bus);
- atmegadci_interrupt_poll(sc);
- atmegadci_root_ctrl_poll(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-/*------------------------------------------------------------------------*
- * at91dci bulk support
- *------------------------------------------------------------------------*/
-static void
-atmegadci_device_bulk_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_device_bulk_close(struct usb2_xfer *xfer)
-{
- atmegadci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-atmegadci_device_bulk_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_device_bulk_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- atmegadci_setup_standard_chain(xfer);
- atmegadci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods atmegadci_device_bulk_methods =
-{
- .open = atmegadci_device_bulk_open,
- .close = atmegadci_device_bulk_close,
- .enter = atmegadci_device_bulk_enter,
- .start = atmegadci_device_bulk_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci control support
- *------------------------------------------------------------------------*/
-static void
-atmegadci_device_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_device_ctrl_close(struct usb2_xfer *xfer)
-{
- atmegadci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-atmegadci_device_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_device_ctrl_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- atmegadci_setup_standard_chain(xfer);
- atmegadci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods atmegadci_device_ctrl_methods =
-{
- .open = atmegadci_device_ctrl_open,
- .close = atmegadci_device_ctrl_close,
- .enter = atmegadci_device_ctrl_enter,
- .start = atmegadci_device_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci interrupt support
- *------------------------------------------------------------------------*/
-static void
-atmegadci_device_intr_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_device_intr_close(struct usb2_xfer *xfer)
-{
- atmegadci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-atmegadci_device_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_device_intr_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- atmegadci_setup_standard_chain(xfer);
- atmegadci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods atmegadci_device_intr_methods =
-{
- .open = atmegadci_device_intr_open,
- .close = atmegadci_device_intr_close,
- .enter = atmegadci_device_intr_enter,
- .start = atmegadci_device_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci full speed isochronous support
- *------------------------------------------------------------------------*/
-static void
-atmegadci_device_isoc_fs_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_device_isoc_fs_close(struct usb2_xfer *xfer)
-{
- atmegadci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-atmegadci_device_isoc_fs_enter(struct usb2_xfer *xfer)
-{
- struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
- uint32_t temp;
- uint32_t nframes;
-
- DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
- xfer, xfer->pipe->isoc_next, xfer->nframes);
-
- /* get the current frame index */
-
- nframes =
- (ATMEGA_READ_1(sc, ATMEGA_UDFNUMH) << 8) |
- (ATMEGA_READ_1(sc, ATMEGA_UDFNUML));
-
- nframes &= ATMEGA_FRAME_MASK;
-
- /*
- * check if the frame index is within the window where the frames
- * will be inserted
- */
- temp = (nframes - xfer->pipe->isoc_next) & ATMEGA_FRAME_MASK;
-
- if ((xfer->pipe->is_synced == 0) ||
- (temp < xfer->nframes)) {
- /*
- * If there is data underflow or the pipe queue is
- * empty we schedule the transfer a few frames ahead
- * of the current frame position. Else two isochronous
- * transfers might overlap.
- */
- xfer->pipe->isoc_next = (nframes + 3) & ATMEGA_FRAME_MASK;
- xfer->pipe->is_synced = 1;
- DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next);
- }
- /*
- * compute how many milliseconds the insertion is ahead of the
- * current frame position:
- */
- temp = (xfer->pipe->isoc_next - nframes) & ATMEGA_FRAME_MASK;
-
- /*
- * pre-compute when the isochronous transfer will be finished:
- */
- xfer->isoc_time_complete =
- usb2_isoc_time_expand(&sc->sc_bus, nframes) + temp +
- xfer->nframes;
-
- /* compute frame number for next insertion */
- xfer->pipe->isoc_next += xfer->nframes;
-
- /* setup TDs */
- atmegadci_setup_standard_chain(xfer);
-}
-
-static void
-atmegadci_device_isoc_fs_start(struct usb2_xfer *xfer)
-{
- /* start TD chain */
- atmegadci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods atmegadci_device_isoc_fs_methods =
-{
- .open = atmegadci_device_isoc_fs_open,
- .close = atmegadci_device_isoc_fs_close,
- .enter = atmegadci_device_isoc_fs_enter,
- .start = atmegadci_device_isoc_fs_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci root control support
- *------------------------------------------------------------------------*
- * simulate a hardware HUB by handling
- * all the necessary requests
- *------------------------------------------------------------------------*/
-
-static void
-atmegadci_root_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_root_ctrl_close(struct usb2_xfer *xfer)
-{
- struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_ctrl.xfer == xfer) {
- sc->sc_root_ctrl.xfer = NULL;
- }
- atmegadci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-/*
- * USB descriptors for the virtual Root HUB:
- */
-
-static const struct usb2_device_descriptor atmegadci_devd = {
- .bLength = sizeof(struct usb2_device_descriptor),
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_HSHUBSTT,
- .bMaxPacketSize = 64,
- .bcdDevice = {0x00, 0x01},
- .iManufacturer = 1,
- .iProduct = 2,
- .bNumConfigurations = 1,
-};
-
-static const struct usb2_device_qualifier atmegadci_odevd = {
- .bLength = sizeof(struct usb2_device_qualifier),
- .bDescriptorType = UDESC_DEVICE_QUALIFIER,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_FSHUB,
- .bMaxPacketSize0 = 0,
- .bNumConfigurations = 0,
-};
-
-static const struct atmegadci_config_desc atmegadci_confd = {
- .confd = {
- .bLength = sizeof(struct usb2_config_descriptor),
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength[0] = sizeof(atmegadci_confd),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_SELF_POWERED,
- .bMaxPower = 0,
- },
- .ifcd = {
- .bLength = sizeof(struct usb2_interface_descriptor),
- .bDescriptorType = UDESC_INTERFACE,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_HSHUBSTT,
- },
-
- .endpd = {
- .bLength = sizeof(struct usb2_endpoint_descriptor),
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = (UE_DIR_IN | ATMEGA_INTR_ENDPT),
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize[0] = 8,
- .bInterval = 255,
- },
-};
-
-static const struct usb2_hub_descriptor_min atmegadci_hubd = {
- .bDescLength = sizeof(atmegadci_hubd),
- .bDescriptorType = UDESC_HUB,
- .bNbrPorts = 1,
- .wHubCharacteristics[0] =
- (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
- .wHubCharacteristics[1] =
- (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 8,
- .bPwrOn2PwrGood = 50,
- .bHubContrCurrent = 0,
- .DeviceRemovable = {0}, /* port is removable */
-};
-
-#define STRING_LANG \
- 0x09, 0x04, /* American English */
-
-#define STRING_VENDOR \
- 'A', 0, 'T', 0, 'M', 0, 'E', 0, 'G', 0, 'A', 0
-
-#define STRING_PRODUCT \
- 'D', 0, 'C', 0, 'I', 0, ' ', 0, 'R', 0, \
- 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
- 'U', 0, 'B', 0,
-
-USB_MAKE_STRING_DESC(STRING_LANG, atmegadci_langtab);
-USB_MAKE_STRING_DESC(STRING_VENDOR, atmegadci_vendor);
-USB_MAKE_STRING_DESC(STRING_PRODUCT, atmegadci_product);
-
-static void
-atmegadci_root_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_root_ctrl_start(struct usb2_xfer *xfer)
-{
- struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_ctrl.xfer = xfer;
-
- usb2_bus_roothub_exec(xfer->xroot->bus);
-}
-
-static void
-atmegadci_root_ctrl_task(struct usb2_bus *bus)
-{
- atmegadci_root_ctrl_poll(ATMEGA_BUS2SC(bus));
-}
-
-static void
-atmegadci_root_ctrl_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
- uint16_t value;
- uint16_t index;
- uint8_t use_polling;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_SETUP) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- atmegadci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* buffer reset */
- std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
- std->len = 0;
-
- value = UGETW(std->req.wValue);
- index = UGETW(std->req.wIndex);
-
- use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
-
- /* demultiplex the control request */
-
- switch (std->req.bmRequestType) {
- case UT_READ_DEVICE:
- switch (std->req.bRequest) {
- case UR_GET_DESCRIPTOR:
- goto tr_handle_get_descriptor;
- case UR_GET_CONFIG:
- goto tr_handle_get_config;
- case UR_GET_STATUS:
- goto tr_handle_get_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_DEVICE:
- switch (std->req.bRequest) {
- case UR_SET_ADDRESS:
- goto tr_handle_set_address;
- case UR_SET_CONFIG:
- goto tr_handle_set_config;
- case UR_CLEAR_FEATURE:
- goto tr_valid; /* nop */
- case UR_SET_DESCRIPTOR:
- goto tr_valid; /* nop */
- case UR_SET_FEATURE:
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_ENDPOINT:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- switch (UGETW(std->req.wValue)) {
- case UF_ENDPOINT_HALT:
- goto tr_handle_clear_halt;
- case UF_DEVICE_REMOTE_WAKEUP:
- goto tr_handle_clear_wakeup;
- default:
- goto tr_stalled;
- }
- break;
- case UR_SET_FEATURE:
- switch (UGETW(std->req.wValue)) {
- case UF_ENDPOINT_HALT:
- goto tr_handle_set_halt;
- case UF_DEVICE_REMOTE_WAKEUP:
- goto tr_handle_set_wakeup;
- default:
- goto tr_stalled;
- }
- break;
- case UR_SYNCH_FRAME:
- goto tr_valid; /* nop */
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_ENDPOINT:
- switch (std->req.bRequest) {
- case UR_GET_STATUS:
- goto tr_handle_get_ep_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_INTERFACE:
- switch (std->req.bRequest) {
- case UR_SET_INTERFACE:
- goto tr_handle_set_interface;
- case UR_CLEAR_FEATURE:
- goto tr_valid; /* nop */
- case UR_SET_FEATURE:
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_INTERFACE:
- switch (std->req.bRequest) {
- case UR_GET_INTERFACE:
- goto tr_handle_get_interface;
- case UR_GET_STATUS:
- goto tr_handle_get_iface_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_CLASS_INTERFACE:
- case UT_WRITE_VENDOR_INTERFACE:
- /* XXX forward */
- break;
-
- case UT_READ_CLASS_INTERFACE:
- case UT_READ_VENDOR_INTERFACE:
- /* XXX forward */
- break;
-
- case UT_WRITE_CLASS_DEVICE:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- goto tr_valid;
- case UR_SET_DESCRIPTOR:
- case UR_SET_FEATURE:
- break;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_CLASS_OTHER:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- goto tr_handle_clear_port_feature;
- case UR_SET_FEATURE:
- goto tr_handle_set_port_feature;
- case UR_CLEAR_TT_BUFFER:
- case UR_RESET_TT:
- case UR_STOP_TT:
- goto tr_valid;
-
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_CLASS_OTHER:
- switch (std->req.bRequest) {
- case UR_GET_TT_STATE:
- goto tr_handle_get_tt_state;
- case UR_GET_STATUS:
- goto tr_handle_get_port_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_CLASS_DEVICE:
- switch (std->req.bRequest) {
- case UR_GET_DESCRIPTOR:
- goto tr_handle_get_class_descriptor;
- case UR_GET_STATUS:
- goto tr_handle_get_class_status;
-
- default:
- goto tr_stalled;
- }
- break;
- default:
- goto tr_stalled;
- }
- goto tr_valid;
-
-tr_handle_get_descriptor:
- switch (value >> 8) {
- case UDESC_DEVICE:
- if (value & 0xff) {
- goto tr_stalled;
- }
- std->len = sizeof(atmegadci_devd);
- std->ptr = USB_ADD_BYTES(&atmegadci_devd, 0);
- goto tr_valid;
- case UDESC_CONFIG:
- if (value & 0xff) {
- goto tr_stalled;
- }
- std->len = sizeof(atmegadci_confd);
- std->ptr = USB_ADD_BYTES(&atmegadci_confd, 0);
- goto tr_valid;
- case UDESC_STRING:
- switch (value & 0xff) {
- case 0: /* Language table */
- std->len = sizeof(atmegadci_langtab);
- std->ptr = USB_ADD_BYTES(&atmegadci_langtab, 0);
- goto tr_valid;
-
- case 1: /* Vendor */
- std->len = sizeof(atmegadci_vendor);
- std->ptr = USB_ADD_BYTES(&atmegadci_vendor, 0);
- goto tr_valid;
-
- case 2: /* Product */
- std->len = sizeof(atmegadci_product);
- std->ptr = USB_ADD_BYTES(&atmegadci_product, 0);
- goto tr_valid;
- default:
- break;
- }
- break;
- default:
- goto tr_stalled;
- }
- goto tr_stalled;
-
-tr_handle_get_config:
- std->len = 1;
- sc->sc_hub_temp.wValue[0] = sc->sc_conf;
- goto tr_valid;
-
-tr_handle_get_status:
- std->len = 2;
- USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
- goto tr_valid;
-
-tr_handle_set_address:
- if (value & 0xFF00) {
- goto tr_stalled;
- }
- sc->sc_rt_addr = value;
- goto tr_valid;
-
-tr_handle_set_config:
- if (value >= 2) {
- goto tr_stalled;
- }
- sc->sc_conf = value;
- goto tr_valid;
-
-tr_handle_get_interface:
- std->len = 1;
- sc->sc_hub_temp.wValue[0] = 0;
- goto tr_valid;
-
-tr_handle_get_tt_state:
-tr_handle_get_class_status:
-tr_handle_get_iface_status:
-tr_handle_get_ep_status:
- std->len = 2;
- USETW(sc->sc_hub_temp.wValue, 0);
- goto tr_valid;
-
-tr_handle_set_halt:
-tr_handle_set_interface:
-tr_handle_set_wakeup:
-tr_handle_clear_wakeup:
-tr_handle_clear_halt:
- goto tr_valid;
-
-tr_handle_clear_port_feature:
- if (index != 1) {
- goto tr_stalled;
- }
- DPRINTFN(9, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
-
- switch (value) {
- case UHF_PORT_SUSPEND:
- atmegadci_wakeup_peer(xfer);
- break;
-
- case UHF_PORT_ENABLE:
- sc->sc_flags.port_enabled = 0;
- break;
-
- case UHF_PORT_TEST:
- case UHF_PORT_INDICATOR:
- case UHF_C_PORT_ENABLE:
- case UHF_C_PORT_OVER_CURRENT:
- case UHF_C_PORT_RESET:
- /* nops */
- break;
- case UHF_PORT_POWER:
- sc->sc_flags.port_powered = 0;
- atmegadci_pull_down(sc);
- atmegadci_clocks_off(sc);
- break;
- case UHF_C_PORT_CONNECTION:
- sc->sc_flags.change_connect = 0;
- break;
- case UHF_C_PORT_SUSPEND:
- sc->sc_flags.change_suspend = 0;
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- goto tr_valid;
-
-tr_handle_set_port_feature:
- if (index != 1) {
- goto tr_stalled;
- }
- DPRINTFN(9, "UR_SET_PORT_FEATURE\n");
-
- switch (value) {
- case UHF_PORT_ENABLE:
- sc->sc_flags.port_enabled = 1;
- break;
- case UHF_PORT_SUSPEND:
- case UHF_PORT_RESET:
- case UHF_PORT_TEST:
- case UHF_PORT_INDICATOR:
- /* nops */
- break;
- case UHF_PORT_POWER:
- sc->sc_flags.port_powered = 1;
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- goto tr_valid;
-
-tr_handle_get_port_status:
-
- DPRINTFN(9, "UR_GET_PORT_STATUS\n");
-
- if (index != 1) {
- goto tr_stalled;
- }
- if (sc->sc_flags.status_vbus) {
- atmegadci_clocks_on(sc);
- atmegadci_pull_up(sc);
- } else {
- atmegadci_pull_down(sc);
- atmegadci_clocks_off(sc);
- }
-
- /* Select FULL-speed and Device Side Mode */
-
- value = UPS_PORT_MODE_DEVICE;
-
- if (sc->sc_flags.port_powered) {
- value |= UPS_PORT_POWER;
- }
- if (sc->sc_flags.port_enabled) {
- value |= UPS_PORT_ENABLED;
- }
- if (sc->sc_flags.status_vbus &&
- sc->sc_flags.status_bus_reset) {
- value |= UPS_CURRENT_CONNECT_STATUS;
- }
- if (sc->sc_flags.status_suspend) {
- value |= UPS_SUSPEND;
- }
- USETW(sc->sc_hub_temp.ps.wPortStatus, value);
-
- value = 0;
-
- if (sc->sc_flags.change_connect) {
- value |= UPS_C_CONNECT_STATUS;
- }
- if (sc->sc_flags.change_suspend) {
- value |= UPS_C_SUSPEND;
- }
- USETW(sc->sc_hub_temp.ps.wPortChange, value);
- std->len = sizeof(sc->sc_hub_temp.ps);
- goto tr_valid;
-
-tr_handle_get_class_descriptor:
- if (value & 0xFF) {
- goto tr_stalled;
- }
- std->ptr = USB_ADD_BYTES(&atmegadci_hubd, 0);
- std->len = sizeof(atmegadci_hubd);
- goto tr_valid;
-
-tr_stalled:
- std->err = USB_ERR_STALLED;
-tr_valid:
-done:
- return;
-}
-
-static void
-atmegadci_root_ctrl_poll(struct atmegadci_softc *sc)
-{
- usb2_sw_transfer(&sc->sc_root_ctrl,
- &atmegadci_root_ctrl_done);
-}
-
-struct usb2_pipe_methods atmegadci_root_ctrl_methods =
-{
- .open = atmegadci_root_ctrl_open,
- .close = atmegadci_root_ctrl_close,
- .enter = atmegadci_root_ctrl_enter,
- .start = atmegadci_root_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 0,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci root interrupt support
- *------------------------------------------------------------------------*/
-static void
-atmegadci_root_intr_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_root_intr_close(struct usb2_xfer *xfer)
-{
- struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_intr.xfer == xfer) {
- sc->sc_root_intr.xfer = NULL;
- }
- atmegadci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-atmegadci_root_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_root_intr_start(struct usb2_xfer *xfer)
-{
- struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_intr.xfer = xfer;
-}
-
-struct usb2_pipe_methods atmegadci_root_intr_methods =
-{
- .open = atmegadci_root_intr_open,
- .close = atmegadci_root_intr_close,
- .enter = atmegadci_root_intr_enter,
- .start = atmegadci_root_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-static void
-atmegadci_xfer_setup(struct usb2_setup_params *parm)
-{
- const struct usb2_hw_ep_profile *pf;
- struct atmegadci_softc *sc;
- struct usb2_xfer *xfer;
- void *last_obj;
- uint32_t ntd;
- uint32_t n;
- uint8_t ep_no;
-
- sc = ATMEGA_BUS2SC(parm->udev->bus);
- xfer = parm->curr_xfer;
-
- /*
- * NOTE: This driver does not use any of the parameters that
- * are computed from the following values. Just set some
- * reasonable dummies:
- */
- parm->hc_max_packet_size = 0x500;
- parm->hc_max_packet_count = 1;
- parm->hc_max_frame_size = 0x500;
-
- usb2_transfer_setup_sub(parm);
-
- /*
- * compute maximum number of TDs
- */
- if (parm->methods == &atmegadci_device_ctrl_methods) {
-
- ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC 1 */
- + 1 /* SYNC 2 */ ;
-
- } else if (parm->methods == &atmegadci_device_bulk_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else if (parm->methods == &atmegadci_device_intr_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else if (parm->methods == &atmegadci_device_isoc_fs_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else {
-
- ntd = 0;
- }
-
- /*
- * check if "usb2_transfer_setup_sub" set an error
- */
- if (parm->err) {
- return;
- }
- /*
- * allocate transfer descriptors
- */
- last_obj = NULL;
-
- /*
- * get profile stuff
- */
- if (ntd) {
-
- ep_no = xfer->endpoint & UE_ADDR;
- atmegadci_get_hw_ep_profile(parm->udev, &pf, ep_no);
-
- if (pf == NULL) {
- /* should not happen */
- parm->err = USB_ERR_INVAL;
- return;
- }
- } else {
- ep_no = 0;
- pf = NULL;
- }
-
- /* align data */
- parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
-
- for (n = 0; n != ntd; n++) {
-
- struct atmegadci_td *td;
-
- if (parm->buf) {
-
- td = USB_ADD_BYTES(parm->buf, parm->size[0]);
-
- /* init TD */
- td->max_packet_size = xfer->max_packet_size;
- td->ep_no = ep_no;
- if (pf->support_multi_buffer) {
- td->support_multi_buffer = 1;
- }
- td->obj_next = last_obj;
-
- last_obj = td;
- }
- parm->size[0] += sizeof(*td);
- }
-
- xfer->td_start[0] = last_obj;
-}
-
-static void
-atmegadci_xfer_unsetup(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-atmegadci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
- struct usb2_pipe *pipe)
-{
- struct atmegadci_softc *sc = ATMEGA_BUS2SC(udev->bus);
-
- DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
- pipe, udev->address,
- edesc->bEndpointAddress, udev->flags.usb2_mode,
- sc->sc_rt_addr);
-
- if (udev->device_index == sc->sc_rt_addr) {
-
- if (udev->flags.usb2_mode != USB_MODE_HOST) {
- /* not supported */
- return;
- }
- switch (edesc->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &atmegadci_root_ctrl_methods;
- break;
- case UE_DIR_IN | ATMEGA_INTR_ENDPT:
- pipe->methods = &atmegadci_root_intr_methods;
- break;
- default:
- /* do nothing */
- break;
- }
- } else {
-
- if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
- /* not supported */
- return;
- }
- if (udev->speed != USB_SPEED_FULL) {
- /* not supported */
- return;
- }
- switch (edesc->bmAttributes & UE_XFERTYPE) {
- case UE_CONTROL:
- pipe->methods = &atmegadci_device_ctrl_methods;
- break;
- case UE_INTERRUPT:
- pipe->methods = &atmegadci_device_intr_methods;
- break;
- case UE_ISOCHRONOUS:
- pipe->methods = &atmegadci_device_isoc_fs_methods;
- break;
- case UE_BULK:
- pipe->methods = &atmegadci_device_bulk_methods;
- break;
- default:
- /* do nothing */
- break;
- }
- }
-}
-
-struct usb2_bus_methods atmegadci_bus_methods =
-{
- .pipe_init = &atmegadci_pipe_init,
- .xfer_setup = &atmegadci_xfer_setup,
- .xfer_unsetup = &atmegadci_xfer_unsetup,
- .do_poll = &atmegadci_do_poll,
- .get_hw_ep_profile = &atmegadci_get_hw_ep_profile,
- .set_stall = &atmegadci_set_stall,
- .clear_stall = &atmegadci_clear_stall,
- .roothub_exec = &atmegadci_root_ctrl_task,
-};
diff --git a/sys/dev/usb2/controller/atmegadci.h b/sys/dev/usb2/controller/atmegadci.h
deleted file mode 100644
index 90b3334..0000000
--- a/sys/dev/usb2/controller/atmegadci.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2009 Hans Petter Selasky. 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.
- */
-
-/*
- * USB Device Port register definitions, copied from ATMEGA
- * documentation provided by ATMEL.
- */
-
-#ifndef _ATMEGADCI_H_
-#define _ATMEGADCI_H_
-
-#define ATMEGA_MAX_DEVICES (USB_MIN_DEVICES + 1)
-
-#ifndef ATMEGA_HAVE_BUS_SPACE
-#define ATMEGA_HAVE_BUS_SPACE 1
-#endif
-
-#define ATMEGA_UEINT 0xF4
-#define ATMEGA_UEINT_MASK(n) (1 << (n)) /* endpoint interrupt mask */
-
-#define ATMEGA_UEBCHX 0xF3 /* FIFO byte count high */
-#define ATMEGA_UEBCLX 0xF2 /* FIFO byte count low */
-#define ATMEGA_UEDATX 0xF1 /* FIFO data */
-
-#define ATMEGA_UEIENX 0xF0 /* interrupt enable register */
-#define ATMEGA_UEIENX_TXINE (1 << 0)
-#define ATMEGA_UEIENX_STALLEDE (1 << 1)
-#define ATMEGA_UEIENX_RXOUTE (1 << 2)
-#define ATMEGA_UEIENX_RXSTPE (1 << 3) /* received SETUP packet */
-#define ATMEGA_UEIENX_NAKOUTE (1 << 4)
-#define ATMEGA_UEIENX_NAKINE (1 << 6)
-#define ATMEGA_UEIENX_FLERRE (1 << 7)
-
-#define ATMEGA_UESTA1X 0xEF
-#define ATMEGA_UESTA1X_CURRBK (3 << 0) /* current bank */
-#define ATMEGA_UESTA1X_CTRLDIR (1 << 2) /* control endpoint direction */
-
-#define ATMEGA_UESTA0X 0xEE
-#define ATMEGA_UESTA0X_NBUSYBK (3 << 0)
-#define ATMEGA_UESTA0X_DTSEQ (3 << 2)
-#define ATMEGA_UESTA0X_UNDERFI (1 << 5) /* underflow */
-#define ATMEGA_UESTA0X_OVERFI (1 << 6) /* overflow */
-#define ATMEGA_UESTA0X_CFGOK (1 << 7)
-
-#define ATMEGA_UECFG1X 0xED /* endpoint config register */
-#define ATMEGA_UECFG1X_ALLOC (1 << 1)
-#define ATMEGA_UECFG1X_EPBK0 (0 << 2)
-#define ATMEGA_UECFG1X_EPBK1 (1 << 2)
-#define ATMEGA_UECFG1X_EPBK2 (2 << 2)
-#define ATMEGA_UECFG1X_EPBK3 (3 << 2)
-#define ATMEGA_UECFG1X_EPSIZE(n) ((n) << 4)
-
-#define ATMEGA_UECFG0X 0xEC
-#define ATMEGA_UECFG0X_EPDIR (1 << 0) /* endpoint direction */
-#define ATMEGA_UECFG0X_EPTYPE0 (0 << 6)
-#define ATMEGA_UECFG0X_EPTYPE1 (1 << 6)
-#define ATMEGA_UECFG0X_EPTYPE2 (2 << 6)
-#define ATMEGA_UECFG0X_EPTYPE3 (3 << 6)
-
-#define ATMEGA_UECONX 0xEB
-#define ATMEGA_UECONX_EPEN (1 << 0)
-#define ATMEGA_UECONX_RSTDT (1 << 3)
-#define ATMEGA_UECONX_STALLRQC (1 << 4) /* stall request clear */
-#define ATMEGA_UECONX_STALLRQ (1 << 5) /* stall request set */
-
-#define ATMEGA_UERST 0xEA /* endpoint reset register */
-#define ATMEGA_UERST_MASK(n) (1 << (n))
-
-#define ATMEGA_UENUM 0xE9 /* endpoint number */
-
-#define ATMEGA_UEINTX 0xE8 /* interrupt register */
-#define ATMEGA_UEINTX_TXINI (1 << 0)
-#define ATMEGA_UEINTX_STALLEDI (1 << 1)
-#define ATMEGA_UEINTX_RXOUTI (1 << 2)
-#define ATMEGA_UEINTX_RXSTPI (1 << 3) /* received setup packet */
-#define ATMEGA_UEINTX_NAKOUTI (1 << 4)
-#define ATMEGA_UEINTX_RWAL (1 << 5)
-#define ATMEGA_UEINTX_NAKINI (1 << 6)
-#define ATMEGA_UEINTX_FIFOCON (1 << 7)
-
-#define ATMEGA_UDMFN 0xE6
-#define ATMEGA_UDMFN_FNCERR (1 << 4)
-
-#define ATMEGA_UDFNUMH 0xE5 /* frame number high */
-#define ATMEGA_UDFNUMH_MASK 7
-
-#define ATMEGA_UDFNUML 0xE4 /* frame number low */
-#define ATMEGA_UDFNUML_MASK 0xFF
-
-#define ATMEGA_FRAME_MASK 0x7FF
-
-#define ATMEGA_UDADDR 0xE3 /* USB address */
-#define ATMEGA_UDADDR_MASK 0x7F
-#define ATMEGA_UDADDR_ADDEN (1 << 7)
-
-#define ATMEGA_UDIEN 0xE2 /* USB device interrupt enable */
-#define ATMEGA_UDINT_SUSPE (1 << 0)
-#define ATMEGA_UDINT_MSOFE (1 << 1)
-#define ATMEGA_UDINT_SOFE (1 << 2)
-#define ATMEGA_UDINT_EORSTE (1 << 3)
-#define ATMEGA_UDINT_WAKEUPE (1 << 4)
-#define ATMEGA_UDINT_EORSME (1 << 5)
-#define ATMEGA_UDINT_UPRSME (1 << 6)
-
-#define ATMEGA_UDINT 0xE1 /* USB device interrupt status */
-#define ATMEGA_UDINT_SUSPI (1 << 0)
-#define ATMEGA_UDINT_MSOFI (1 << 1)
-#define ATMEGA_UDINT_SOFI (1 << 2)
-#define ATMEGA_UDINT_EORSTI (1 << 3)
-#define ATMEGA_UDINT_WAKEUPI (1 << 4)
-#define ATMEGA_UDINT_EORSMI (1 << 5)
-#define ATMEGA_UDINT_UPRSMI (1 << 6)
-
-#define ATMEGA_UDCON 0xE0 /* USB device connection register */
-#define ATMEGA_UDCON_DETACH (1 << 0)
-#define ATMEGA_UDCON_RMWKUP (1 << 1)
-#define ATMEGA_UDCON_LSM (1 << 2)
-#define ATMEGA_UDCON_RSTCPU (1 << 3)
-
-#define ATMEGA_USBINT 0xDA
-#define ATMEGA_USBINT_VBUSTI (1 << 0) /* USB VBUS interrupt */
-
-#define ATMEGA_USBSTA 0xD9
-#define ATMEGA_USBSTA_VBUS (1 << 0)
-#define ATMEGA_USBSTA_ID (1 << 1)
-
-#define ATMEGA_USBCON 0xD8
-#define ATMEGA_USBCON_VBUSTE (1 << 0)
-#define ATMEGA_USBCON_OTGPADE (1 << 4)
-#define ATMEGA_USBCON_FRZCLK (1 << 5)
-#define ATMEGA_USBCON_USBE (1 << 7)
-
-#define ATMEGA_UHWCON 0xD7
-#define ATMEGA_UHWCON_UVREGE (1 << 0)
-
-#define ATMEGA_READ_1(sc, reg) \
- bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
-
-#define ATMEGA_WRITE_1(sc, reg, data) \
- bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data)
-
-#define ATMEGA_WRITE_MULTI_1(sc, reg, ptr, len) \
- bus_space_write_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, ptr, len)
-
-#define ATMEGA_READ_MULTI_1(sc, reg, ptr, len) \
- bus_space_read_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, ptr, len)
-
-/*
- * Maximum number of endpoints supported:
- */
-#define ATMEGA_EP_MAX 7
-
-struct atmegadci_td;
-
-typedef uint8_t (atmegadci_cmd_t)(struct atmegadci_td *td);
-typedef void (atmegadci_clocks_t)(struct usb2_bus *);
-
-struct atmegadci_td {
- struct atmegadci_td *obj_next;
- atmegadci_cmd_t *func;
- struct usb2_page_cache *pc;
- uint32_t offset;
- uint32_t remainder;
- uint16_t max_packet_size;
- uint8_t error:1;
- uint8_t alt_next:1;
- uint8_t short_pkt:1;
- uint8_t support_multi_buffer:1;
- uint8_t did_stall:1;
- uint8_t ep_no:3;
-};
-
-struct atmegadci_std_temp {
- atmegadci_cmd_t *func;
- struct usb2_page_cache *pc;
- struct atmegadci_td *td;
- struct atmegadci_td *td_next;
- uint32_t len;
- uint32_t offset;
- uint16_t max_frame_size;
- uint8_t short_pkt;
- /*
- * short_pkt = 0: transfer should be short terminated
- * short_pkt = 1: transfer should not be short terminated
- */
- uint8_t setup_alt_next;
-};
-
-struct atmegadci_config_desc {
- struct usb2_config_descriptor confd;
- struct usb2_interface_descriptor ifcd;
- struct usb2_endpoint_descriptor endpd;
-} __packed;
-
-union atmegadci_hub_temp {
- uWord wValue;
- struct usb2_port_status ps;
-};
-
-struct atmegadci_flags {
- uint8_t change_connect:1;
- uint8_t change_suspend:1;
- uint8_t status_suspend:1; /* set if suspended */
- uint8_t status_vbus:1; /* set if present */
- uint8_t status_bus_reset:1; /* set if reset complete */
- uint8_t remote_wakeup:1;
- uint8_t self_powered:1;
- uint8_t clocks_off:1;
- uint8_t port_powered:1;
- uint8_t port_enabled:1;
- uint8_t d_pulled_up:1;
-};
-
-struct atmegadci_softc {
- struct usb2_bus sc_bus;
- union atmegadci_hub_temp sc_hub_temp;
- LIST_HEAD(, usb2_xfer) sc_interrupt_list_head;
- struct usb2_sw_transfer sc_root_ctrl;
- struct usb2_sw_transfer sc_root_intr;
-
- /* must be set by by the bus interface layer */
- atmegadci_clocks_t *sc_clocks_on;
- atmegadci_clocks_t *sc_clocks_off;
-
- struct usb2_device *sc_devices[ATMEGA_MAX_DEVICES];
- struct resource *sc_irq_res;
- void *sc_intr_hdl;
-#if (ATMEGA_HAVE_BUS_SPACE != 0)
- struct resource *sc_io_res;
- bus_space_tag_t sc_io_tag;
- bus_space_handle_t sc_io_hdl;
-#endif
- uint8_t sc_rt_addr; /* root hub address */
- uint8_t sc_dv_addr; /* device address */
- uint8_t sc_conf; /* root hub config */
-
- uint8_t sc_hub_idata[1];
-
- struct atmegadci_flags sc_flags;
-};
-
-/* prototypes */
-
-usb2_error_t atmegadci_init(struct atmegadci_softc *sc);
-void atmegadci_uninit(struct atmegadci_softc *sc);
-void atmegadci_suspend(struct atmegadci_softc *sc);
-void atmegadci_resume(struct atmegadci_softc *sc);
-void atmegadci_interrupt(struct atmegadci_softc *sc);
-
-#endif /* _ATMEGADCI_H_ */
diff --git a/sys/dev/usb2/controller/atmegadci_atmelarm.c b/sys/dev/usb2/controller/atmegadci_atmelarm.c
deleted file mode 100644
index e63f5cc..0000000
--- a/sys/dev/usb2/controller/atmegadci_atmelarm.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2009 Hans Petter Selasky. 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.
- */
diff --git a/sys/dev/usb2/controller/ehci2.c b/sys/dev/usb2/controller/ehci2.c
deleted file mode 100644
index 87a6d03..0000000
--- a/sys/dev/usb2/controller/ehci2.c
+++ /dev/null
@@ -1,3965 +0,0 @@
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
- * Copyright (c) 2004 The NetBSD Foundation, Inc. All rights reserved.
- * Copyright (c) 2004 Lennart Augustsson. All rights reserved.
- * Copyright (c) 2004 Charles M. Hannum. 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.
- */
-
-/*
- * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
- *
- * The EHCI 0.96 spec can be found at
- * http://developer.intel.com/technology/usb/download/ehci-r096.pdf
- * 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) command failures are not recovered correctly
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR ehcidebug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_hub.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/ehci2.h>
-
-#define EHCI_BUS2SC(bus) ((ehci_softc_t *)(((uint8_t *)(bus)) - \
- USB_P2U(&(((ehci_softc_t *)0)->sc_bus))))
-
-#if USB_DEBUG
-static int ehcidebug = 0;
-static int ehcinohighspeed = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci");
-SYSCTL_INT(_hw_usb2_ehci, OID_AUTO, debug, CTLFLAG_RW,
- &ehcidebug, 0, "Debug level");
-SYSCTL_INT(_hw_usb2_ehci, OID_AUTO, no_hs, CTLFLAG_RW,
- &ehcinohighspeed, 0, "Disable High Speed USB");
-
-static void ehci_dump_regs(ehci_softc_t *sc);
-static void ehci_dump_sqh(ehci_softc_t *sc, ehci_qh_t *sqh);
-
-#endif
-
-#define EHCI_INTR_ENDPT 1
-
-extern struct usb2_bus_methods ehci_bus_methods;
-extern struct usb2_pipe_methods ehci_device_bulk_methods;
-extern struct usb2_pipe_methods ehci_device_ctrl_methods;
-extern struct usb2_pipe_methods ehci_device_intr_methods;
-extern struct usb2_pipe_methods ehci_device_isoc_fs_methods;
-extern struct usb2_pipe_methods ehci_device_isoc_hs_methods;
-extern struct usb2_pipe_methods ehci_root_ctrl_methods;
-extern struct usb2_pipe_methods ehci_root_intr_methods;
-
-static void ehci_do_poll(struct usb2_bus *bus);
-static void ehci_root_ctrl_poll(ehci_softc_t *sc);
-static void ehci_device_done(struct usb2_xfer *xfer, usb2_error_t error);
-static uint8_t ehci_check_transfer(struct usb2_xfer *xfer);
-static void ehci_timeout(void *arg);
-
-static usb2_sw_transfer_func_t ehci_root_intr_done;
-static usb2_sw_transfer_func_t ehci_root_ctrl_done;
-
-struct ehci_std_temp {
- ehci_softc_t *sc;
- struct usb2_page_cache *pc;
- ehci_qtd_t *td;
- ehci_qtd_t *td_next;
- uint32_t average;
- uint32_t qtd_status;
- uint32_t len;
- uint16_t max_frame_size;
- uint8_t shortpkt;
- uint8_t auto_data_toggle;
- uint8_t setup_alt_next;
- uint8_t short_frames_ok;
-};
-
-/*
- * Byte-order conversion functions.
- */
-static uint32_t
-htoehci32(ehci_softc_t *sc, const uint32_t v)
-{
- return ((sc->sc_flags & EHCI_SCFLG_BIGEDESC) ?
- htobe32(v) : htole32(v));
-}
-
-static uint32_t
-ehci32toh(ehci_softc_t *sc, const uint32_t v)
-{
- return ((sc->sc_flags & EHCI_SCFLG_BIGEDESC) ?
- be32toh(v) : le32toh(v));
-}
-
-void
-ehci_iterate_hw_softc(struct usb2_bus *bus, usb2_bus_mem_sub_cb_t *cb)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(bus);
- uint32_t i;
-
- cb(bus, &sc->sc_hw.pframes_pc, &sc->sc_hw.pframes_pg,
- sizeof(uint32_t) * EHCI_FRAMELIST_COUNT, EHCI_FRAMELIST_ALIGN);
-
- cb(bus, &sc->sc_hw.async_start_pc, &sc->sc_hw.async_start_pg,
- sizeof(ehci_qh_t), EHCI_QH_ALIGN);
-
- for (i = 0; i != EHCI_VIRTUAL_FRAMELIST_COUNT; i++) {
- cb(bus, sc->sc_hw.intr_start_pc + i,
- sc->sc_hw.intr_start_pg + i,
- sizeof(ehci_qh_t), EHCI_QH_ALIGN);
- }
-
- for (i = 0; i != EHCI_VIRTUAL_FRAMELIST_COUNT; i++) {
- cb(bus, sc->sc_hw.isoc_hs_start_pc + i,
- sc->sc_hw.isoc_hs_start_pg + i,
- sizeof(ehci_itd_t), EHCI_ITD_ALIGN);
- }
-
- for (i = 0; i != EHCI_VIRTUAL_FRAMELIST_COUNT; i++) {
- cb(bus, sc->sc_hw.isoc_fs_start_pc + i,
- sc->sc_hw.isoc_fs_start_pg + i,
- sizeof(ehci_sitd_t), EHCI_SITD_ALIGN);
- }
-}
-
-static usb2_error_t
-ehci_hc_reset(ehci_softc_t *sc)
-{
- uint32_t hcr;
- uint32_t n;
-
- EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */
-
- for (n = 0; n != 100; n++) {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
- hcr = EOREAD4(sc, EHCI_USBSTS);
- if (hcr & EHCI_STS_HCH) {
- hcr = 0;
- break;
- }
- }
-
- /*
- * Fall through and try reset anyway even though
- * Table 2-9 in the EHCI spec says this will result
- * in undefined behavior.
- */
-
- EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
- for (n = 0; n != 100; n++) {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
- hcr = EOREAD4(sc, EHCI_USBCMD);
- if (!(hcr & EHCI_CMD_HCRESET)) {
- if (sc->sc_flags & EHCI_SCFLG_SETMODE)
- EOWRITE4(sc, 0x68, 0x3);
- hcr = 0;
- break;
- }
- }
-
- if (hcr) {
- return (USB_ERR_IOERROR);
- }
- return (0);
-}
-
-usb2_error_t
-ehci_init(ehci_softc_t *sc)
-{
- struct usb2_page_search buf_res;
- uint32_t version;
- uint32_t sparams;
- uint32_t cparams;
- uint32_t hcr;
- uint16_t i;
- uint16_t x;
- uint16_t y;
- uint16_t bit;
- usb2_error_t err = 0;
-
- DPRINTF("start\n");
-
- usb2_callout_init_mtx(&sc->sc_tmo_pcd, &sc->sc_bus.bus_mtx, 0);
-
-#if USB_DEBUG
- if (ehcidebug > 2) {
- ehci_dump_regs(sc);
- }
-#endif
-
- 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("sparams=0x%x\n", sparams);
-
- sc->sc_noport = EHCI_HCS_N_PORTS(sparams);
- cparams = EREAD4(sc, EHCI_HCCPARAMS);
- DPRINTF("cparams=0x%x\n", cparams);
-
- if (EHCI_HCC_64BIT(cparams)) {
- DPRINTF("HCC uses 64-bit structures\n");
-
- /* MUST clear segment register if 64 bit capable */
- EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
- }
- sc->sc_bus.usbrev = USB_REV_2_0;
-
- /* Reset the controller */
- DPRINTF("%s: resetting\n", device_get_nameunit(sc->sc_bus.bdev));
-
- USB_BUS_LOCK(&sc->sc_bus);
- err = ehci_hc_reset(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
- if (err) {
- device_printf(sc->sc_bus.bdev, "reset timeout\n");
- return (err);
- }
- /*
- * use current frame-list-size selection 0: 1024*4 bytes 1: 512*4
- * bytes 2: 256*4 bytes 3: unknown
- */
- if (EHCI_CMD_FLS(EOREAD4(sc, EHCI_USBCMD)) == 3) {
- device_printf(sc->sc_bus.bdev, "invalid frame-list-size\n");
- return (USB_ERR_IOERROR);
- }
- /* set up the bus struct */
- sc->sc_bus.methods = &ehci_bus_methods;
-
- sc->sc_eintrs = EHCI_NORMAL_INTRS;
-
- for (i = 0; i < EHCI_VIRTUAL_FRAMELIST_COUNT; i++) {
- ehci_qh_t *qh;
-
- usb2_get_page(sc->sc_hw.intr_start_pc + i, 0, &buf_res);
-
- qh = buf_res.buffer;
-
- /* initialize page cache pointer */
-
- qh->page_cache = sc->sc_hw.intr_start_pc + i;
-
- /* store a pointer to queue head */
-
- sc->sc_intr_p_last[i] = qh;
-
- qh->qh_self =
- htoehci32(sc, buf_res.physaddr) |
- htoehci32(sc, EHCI_LINK_QH);
-
- qh->qh_endp =
- htoehci32(sc, EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH));
- qh->qh_endphub =
- htoehci32(sc, EHCI_QH_SET_MULT(1));
- qh->qh_curqtd = 0;
-
- qh->qh_qtd.qtd_next =
- htoehci32(sc, EHCI_LINK_TERMINATE);
- qh->qh_qtd.qtd_altnext =
- htoehci32(sc, EHCI_LINK_TERMINATE);
- qh->qh_qtd.qtd_status =
- htoehci32(sc, EHCI_QTD_HALTED);
- }
-
- /*
- * the QHs are arranged to give poll intervals that are
- * powers of 2 times 1ms
- */
- bit = EHCI_VIRTUAL_FRAMELIST_COUNT / 2;
- while (bit) {
- x = bit;
- while (x & bit) {
- ehci_qh_t *qh_x;
- ehci_qh_t *qh_y;
-
- y = (x ^ bit) | (bit / 2);
-
- qh_x = sc->sc_intr_p_last[x];
- qh_y = sc->sc_intr_p_last[y];
-
- /*
- * the next QH has half the poll interval
- */
- qh_x->qh_link = qh_y->qh_self;
-
- x++;
- }
- bit >>= 1;
- }
-
- if (1) {
- ehci_qh_t *qh;
-
- qh = sc->sc_intr_p_last[0];
-
- /* the last (1ms) QH terminates */
- qh->qh_link = htoehci32(sc, EHCI_LINK_TERMINATE);
- }
- for (i = 0; i < EHCI_VIRTUAL_FRAMELIST_COUNT; i++) {
- ehci_sitd_t *sitd;
- ehci_itd_t *itd;
-
- usb2_get_page(sc->sc_hw.isoc_fs_start_pc + i, 0, &buf_res);
-
- sitd = buf_res.buffer;
-
- /* initialize page cache pointer */
-
- sitd->page_cache = sc->sc_hw.isoc_fs_start_pc + i;
-
- /* store a pointer to the transfer descriptor */
-
- sc->sc_isoc_fs_p_last[i] = sitd;
-
- /* initialize full speed isochronous */
-
- sitd->sitd_self =
- htoehci32(sc, buf_res.physaddr) |
- htoehci32(sc, EHCI_LINK_SITD);
-
- sitd->sitd_back =
- htoehci32(sc, EHCI_LINK_TERMINATE);
-
- sitd->sitd_next =
- sc->sc_intr_p_last[i | (EHCI_VIRTUAL_FRAMELIST_COUNT / 2)]->qh_self;
-
-
- usb2_get_page(sc->sc_hw.isoc_hs_start_pc + i, 0, &buf_res);
-
- itd = buf_res.buffer;
-
- /* initialize page cache pointer */
-
- itd->page_cache = sc->sc_hw.isoc_hs_start_pc + i;
-
- /* store a pointer to the transfer descriptor */
-
- sc->sc_isoc_hs_p_last[i] = itd;
-
- /* initialize high speed isochronous */
-
- itd->itd_self =
- htoehci32(sc, buf_res.physaddr) |
- htoehci32(sc, EHCI_LINK_ITD);
-
- itd->itd_next =
- sitd->sitd_self;
- }
-
- usb2_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res);
-
- if (1) {
- uint32_t *pframes;
-
- pframes = buf_res.buffer;
-
- /*
- * execution order:
- * pframes -> high speed isochronous ->
- * full speed isochronous -> interrupt QH's
- */
- for (i = 0; i < EHCI_FRAMELIST_COUNT; i++) {
- pframes[i] = sc->sc_isoc_hs_p_last
- [i & (EHCI_VIRTUAL_FRAMELIST_COUNT - 1)]->itd_self;
- }
- }
- /* setup sync list pointer */
- EOWRITE4(sc, EHCI_PERIODICLISTBASE, buf_res.physaddr);
-
- usb2_get_page(&sc->sc_hw.async_start_pc, 0, &buf_res);
-
- if (1) {
-
- ehci_qh_t *qh;
-
- qh = buf_res.buffer;
-
- /* initialize page cache pointer */
-
- qh->page_cache = &sc->sc_hw.async_start_pc;
-
- /* store a pointer to the queue head */
-
- sc->sc_async_p_last = qh;
-
- /* init dummy QH that starts the async list */
-
- qh->qh_self =
- htoehci32(sc, buf_res.physaddr) |
- htoehci32(sc, EHCI_LINK_QH);
-
- /* fill the QH */
- qh->qh_endp =
- htoehci32(sc, EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL);
- qh->qh_endphub = htoehci32(sc, EHCI_QH_SET_MULT(1));
- qh->qh_link = qh->qh_self;
- qh->qh_curqtd = 0;
-
- /* fill the overlay qTD */
- qh->qh_qtd.qtd_next = htoehci32(sc, EHCI_LINK_TERMINATE);
- qh->qh_qtd.qtd_altnext = htoehci32(sc, EHCI_LINK_TERMINATE);
- qh->qh_qtd.qtd_status = htoehci32(sc, EHCI_QTD_HALTED);
- }
- /* flush all cache into memory */
-
- usb2_bus_mem_flush_all(&sc->sc_bus, &ehci_iterate_hw_softc);
-
-#if USB_DEBUG
- if (ehcidebug) {
- ehci_dump_sqh(sc, sc->sc_async_p_last);
- }
-#endif
-
- /* setup async list pointer */
- EOWRITE4(sc, EHCI_ASYNCLISTADDR, buf_res.physaddr | EHCI_LINK_QH);
-
-
- /* enable interrupts */
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
-
- /* turn on controller */
- EOWRITE4(sc, EHCI_USBCMD,
- EHCI_CMD_ITC_1 | /* 1 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++) {
- usb2_pause_mtx(NULL, hz / 1000);
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (!hcr) {
- break;
- }
- }
- if (hcr) {
- device_printf(sc->sc_bus.bdev, "run timeout\n");
- return (USB_ERR_IOERROR);
- }
-
- if (!err) {
- /* catch any lost interrupts */
- ehci_do_poll(&sc->sc_bus);
- }
- return (err);
-}
-
-/*
- * shut down the controller when the system is going down
- */
-void
-ehci_detach(ehci_softc_t *sc)
-{
- USB_BUS_LOCK(&sc->sc_bus);
-
- usb2_callout_stop(&sc->sc_tmo_pcd);
-
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
-
- if (ehci_hc_reset(sc)) {
- DPRINTF("reset failed!\n");
- }
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-
- /* XXX let stray task complete */
- usb2_pause_mtx(NULL, hz / 20);
-
- usb2_callout_drain(&sc->sc_tmo_pcd);
-}
-
-void
-ehci_suspend(ehci_softc_t *sc)
-{
- uint32_t cmd;
- uint32_t hcr;
- uint8_t i;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- 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;
- }
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
- }
-
- if (hcr != 0) {
- device_printf(sc->sc_bus.bdev, "reset timeout\n");
- }
- 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;
- }
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
- }
-
- if (hcr != EHCI_STS_HCH) {
- device_printf(sc->sc_bus.bdev,
- "config timeout\n");
- }
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-void
-ehci_resume(ehci_softc_t *sc)
-{
- struct usb2_page_search buf_res;
- uint32_t cmd;
- uint32_t hcr;
- uint8_t i;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* restore things in case the bios doesn't */
- EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
-
- usb2_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res);
- EOWRITE4(sc, EHCI_PERIODICLISTBASE, buf_res.physaddr);
-
- usb2_get_page(&sc->sc_hw.async_start_pc, 0, &buf_res);
- EOWRITE4(sc, EHCI_ASYNCLISTADDR, buf_res.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) {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(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;
- }
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
- }
- if (hcr == EHCI_STS_HCH) {
- device_printf(sc->sc_bus.bdev, "config timeout\n");
- }
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-
- usb2_pause_mtx(NULL,
- USB_MS_TO_TICKS(USB_RESUME_WAIT));
-
- /* catch any lost interrupts */
- ehci_do_poll(&sc->sc_bus);
-}
-
-void
-ehci_shutdown(ehci_softc_t *sc)
-{
- DPRINTF("stopping the HC\n");
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- if (ehci_hc_reset(sc)) {
- DPRINTF("reset failed!\n");
- }
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-#if USB_DEBUG
-static void
-ehci_dump_regs(ehci_softc_t *sc)
-{
- uint32_t i;
-
- i = EOREAD4(sc, EHCI_USBCMD);
- printf("cmd=0x%08x\n", i);
-
- if (i & EHCI_CMD_ITC_1)
- printf(" EHCI_CMD_ITC_1\n");
- if (i & EHCI_CMD_ITC_2)
- printf(" EHCI_CMD_ITC_2\n");
- if (i & EHCI_CMD_ITC_4)
- printf(" EHCI_CMD_ITC_4\n");
- if (i & EHCI_CMD_ITC_8)
- printf(" EHCI_CMD_ITC_8\n");
- if (i & EHCI_CMD_ITC_16)
- printf(" EHCI_CMD_ITC_16\n");
- if (i & EHCI_CMD_ITC_32)
- printf(" EHCI_CMD_ITC_32\n");
- if (i & EHCI_CMD_ITC_64)
- printf(" EHCI_CMD_ITC_64\n");
- if (i & EHCI_CMD_ASPME)
- printf(" EHCI_CMD_ASPME\n");
- if (i & EHCI_CMD_ASPMC)
- printf(" EHCI_CMD_ASPMC\n");
- if (i & EHCI_CMD_LHCR)
- printf(" EHCI_CMD_LHCR\n");
- if (i & EHCI_CMD_IAAD)
- printf(" EHCI_CMD_IAAD\n");
- if (i & EHCI_CMD_ASE)
- printf(" EHCI_CMD_ASE\n");
- if (i & EHCI_CMD_PSE)
- printf(" EHCI_CMD_PSE\n");
- if (i & EHCI_CMD_FLS_M)
- printf(" EHCI_CMD_FLS_M\n");
- if (i & EHCI_CMD_HCRESET)
- printf(" EHCI_CMD_HCRESET\n");
- if (i & EHCI_CMD_RS)
- printf(" EHCI_CMD_RS\n");
-
- i = EOREAD4(sc, EHCI_USBSTS);
-
- printf("sts=0x%08x\n", i);
-
- if (i & EHCI_STS_ASS)
- printf(" EHCI_STS_ASS\n");
- if (i & EHCI_STS_PSS)
- printf(" EHCI_STS_PSS\n");
- if (i & EHCI_STS_REC)
- printf(" EHCI_STS_REC\n");
- if (i & EHCI_STS_HCH)
- printf(" EHCI_STS_HCH\n");
- if (i & EHCI_STS_IAA)
- printf(" EHCI_STS_IAA\n");
- if (i & EHCI_STS_HSE)
- printf(" EHCI_STS_HSE\n");
- if (i & EHCI_STS_FLR)
- printf(" EHCI_STS_FLR\n");
- if (i & EHCI_STS_PCD)
- printf(" EHCI_STS_PCD\n");
- if (i & EHCI_STS_ERRINT)
- printf(" EHCI_STS_ERRINT\n");
- if (i & EHCI_STS_INT)
- printf(" EHCI_STS_INT\n");
-
- printf("ien=0x%08x\n",
- EOREAD4(sc, EHCI_USBINTR));
- printf("frindex=0x%08x ctrdsegm=0x%08x periodic=0x%08x async=0x%08x\n",
- EOREAD4(sc, EHCI_FRINDEX),
- EOREAD4(sc, EHCI_CTRLDSSEGMENT),
- EOREAD4(sc, EHCI_PERIODICLISTBASE),
- EOREAD4(sc, EHCI_ASYNCLISTADDR));
- for (i = 1; i <= sc->sc_noport; i++) {
- printf("port %d status=0x%08x\n", i,
- EOREAD4(sc, EHCI_PORTSC(i)));
- }
-}
-
-static void
-ehci_dump_link(ehci_softc_t *sc, uint32_t link, int type)
-{
- link = ehci32toh(sc, link);
- printf("0x%08x", link);
- if (link & EHCI_LINK_TERMINATE)
- printf("<T>");
- else {
- printf("<");
- if (type) {
- switch (EHCI_LINK_TYPE(link)) {
- case EHCI_LINK_ITD:
- printf("ITD");
- break;
- case EHCI_LINK_QH:
- printf("QH");
- break;
- case EHCI_LINK_SITD:
- printf("SITD");
- break;
- case EHCI_LINK_FSTN:
- printf("FSTN");
- break;
- }
- }
- printf(">");
- }
-}
-
-static void
-ehci_dump_qtd(ehci_softc_t *sc, ehci_qtd_t *qtd)
-{
- uint32_t s;
-
- printf(" next=");
- ehci_dump_link(sc, qtd->qtd_next, 0);
- printf(" altnext=");
- ehci_dump_link(sc, qtd->qtd_altnext, 0);
- printf("\n");
- s = ehci32toh(sc, qtd->qtd_status);
- printf(" status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
- s, EHCI_QTD_GET_TOGGLE(s), EHCI_QTD_GET_BYTES(s),
- EHCI_QTD_GET_IOC(s), EHCI_QTD_GET_C_PAGE(s));
- printf(" cerr=%d pid=%d stat=%s%s%s%s%s%s%s%s\n",
- EHCI_QTD_GET_CERR(s), EHCI_QTD_GET_PID(s),
- (s & EHCI_QTD_ACTIVE) ? "ACTIVE" : "NOT_ACTIVE",
- (s & EHCI_QTD_HALTED) ? "-HALTED" : "",
- (s & EHCI_QTD_BUFERR) ? "-BUFERR" : "",
- (s & EHCI_QTD_BABBLE) ? "-BABBLE" : "",
- (s & EHCI_QTD_XACTERR) ? "-XACTERR" : "",
- (s & EHCI_QTD_MISSEDMICRO) ? "-MISSED" : "",
- (s & EHCI_QTD_SPLITXSTATE) ? "-SPLIT" : "",
- (s & EHCI_QTD_PINGSTATE) ? "-PING" : "");
-
- for (s = 0; s < 5; s++) {
- printf(" buffer[%d]=0x%08x\n", s,
- ehci32toh(sc, qtd->qtd_buffer[s]));
- }
- for (s = 0; s < 5; s++) {
- printf(" buffer_hi[%d]=0x%08x\n", s,
- ehci32toh(sc, qtd->qtd_buffer_hi[s]));
- }
-}
-
-static uint8_t
-ehci_dump_sqtd(ehci_softc_t *sc, ehci_qtd_t *sqtd)
-{
- uint8_t temp;
-
- usb2_pc_cpu_invalidate(sqtd->page_cache);
- printf("QTD(%p) at 0x%08x:\n", sqtd, ehci32toh(sc, sqtd->qtd_self));
- ehci_dump_qtd(sc, sqtd);
- temp = (sqtd->qtd_next & htoehci32(sc, EHCI_LINK_TERMINATE)) ? 1 : 0;
- return (temp);
-}
-
-static void
-ehci_dump_sqtds(ehci_softc_t *sc, ehci_qtd_t *sqtd)
-{
- uint16_t i;
- uint8_t stop;
-
- stop = 0;
- for (i = 0; sqtd && (i < 20) && !stop; sqtd = sqtd->obj_next, i++) {
- stop = ehci_dump_sqtd(sc, sqtd);
- }
- if (sqtd) {
- printf("dump aborted, too many TDs\n");
- }
-}
-
-static void
-ehci_dump_sqh(ehci_softc_t *sc, ehci_qh_t *qh)
-{
- uint32_t endp;
- uint32_t endphub;
-
- usb2_pc_cpu_invalidate(qh->page_cache);
- printf("QH(%p) at 0x%08x:\n", qh, ehci32toh(sc, qh->qh_self) & ~0x1F);
- printf(" link=");
- ehci_dump_link(sc, qh->qh_link, 1);
- printf("\n");
- endp = ehci32toh(sc, qh->qh_endp);
- printf(" endp=0x%08x\n", endp);
- printf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
- EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp),
- EHCI_QH_GET_ENDPT(endp), EHCI_QH_GET_EPS(endp),
- EHCI_QH_GET_DTC(endp), EHCI_QH_GET_HRECL(endp));
- printf(" mpl=0x%x ctl=%d nrl=%d\n",
- EHCI_QH_GET_MPL(endp), EHCI_QH_GET_CTL(endp),
- EHCI_QH_GET_NRL(endp));
- endphub = ehci32toh(sc, qh->qh_endphub);
- printf(" endphub=0x%08x\n", endphub);
- printf(" smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
- EHCI_QH_GET_SMASK(endphub), EHCI_QH_GET_CMASK(endphub),
- EHCI_QH_GET_HUBA(endphub), EHCI_QH_GET_PORT(endphub),
- EHCI_QH_GET_MULT(endphub));
- printf(" curqtd=");
- ehci_dump_link(sc, qh->qh_curqtd, 0);
- printf("\n");
- printf("Overlay qTD:\n");
- ehci_dump_qtd(sc, (void *)&qh->qh_qtd);
-}
-
-static void
-ehci_dump_sitd(ehci_softc_t *sc, ehci_sitd_t *sitd)
-{
- usb2_pc_cpu_invalidate(sitd->page_cache);
- printf("SITD(%p) at 0x%08x\n", sitd, ehci32toh(sc, sitd->sitd_self) & ~0x1F);
- printf(" next=0x%08x\n", ehci32toh(sc, sitd->sitd_next));
- printf(" portaddr=0x%08x dir=%s addr=%d endpt=0x%x port=0x%x huba=0x%x\n",
- ehci32toh(sc, sitd->sitd_portaddr),
- (sitd->sitd_portaddr & htoehci32(sc, EHCI_SITD_SET_DIR_IN))
- ? "in" : "out",
- EHCI_SITD_GET_ADDR(ehci32toh(sc, sitd->sitd_portaddr)),
- EHCI_SITD_GET_ENDPT(ehci32toh(sc, sitd->sitd_portaddr)),
- EHCI_SITD_GET_PORT(ehci32toh(sc, sitd->sitd_portaddr)),
- EHCI_SITD_GET_HUBA(ehci32toh(sc, sitd->sitd_portaddr)));
- printf(" mask=0x%08x\n", ehci32toh(sc, sitd->sitd_mask));
- printf(" status=0x%08x <%s> len=0x%x\n", ehci32toh(sc, sitd->sitd_status),
- (sitd->sitd_status & htoehci32(sc, EHCI_SITD_ACTIVE)) ? "ACTIVE" : "",
- EHCI_SITD_GET_LEN(ehci32toh(sc, sitd->sitd_status)));
- printf(" back=0x%08x, bp=0x%08x,0x%08x,0x%08x,0x%08x\n",
- ehci32toh(sc, sitd->sitd_back),
- ehci32toh(sc, sitd->sitd_bp[0]),
- ehci32toh(sc, sitd->sitd_bp[1]),
- ehci32toh(sc, sitd->sitd_bp_hi[0]),
- ehci32toh(sc, sitd->sitd_bp_hi[1]));
-}
-
-static void
-ehci_dump_itd(ehci_softc_t *sc, ehci_itd_t *itd)
-{
- usb2_pc_cpu_invalidate(itd->page_cache);
- printf("ITD(%p) at 0x%08x\n", itd, ehci32toh(sc, itd->itd_self) & ~0x1F);
- printf(" next=0x%08x\n", ehci32toh(sc, itd->itd_next));
- printf(" status[0]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[0]),
- (itd->itd_status[0] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[1]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[1]),
- (itd->itd_status[1] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[2]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[2]),
- (itd->itd_status[2] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[3]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[3]),
- (itd->itd_status[3] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[4]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[4]),
- (itd->itd_status[4] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[5]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[5]),
- (itd->itd_status[5] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[6]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[6]),
- (itd->itd_status[6] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" status[7]=0x%08x; <%s>\n", ehci32toh(sc, itd->itd_status[7]),
- (itd->itd_status[7] & htoehci32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : "");
- printf(" bp[0]=0x%08x\n", ehci32toh(sc, itd->itd_bp[0]));
- printf(" addr=0x%02x; endpt=0x%01x\n",
- EHCI_ITD_GET_ADDR(ehci32toh(sc, itd->itd_bp[0])),
- EHCI_ITD_GET_ENDPT(ehci32toh(sc, itd->itd_bp[0])));
- printf(" bp[1]=0x%08x\n", ehci32toh(sc, itd->itd_bp[1]));
- printf(" dir=%s; mpl=0x%02x\n",
- (ehci32toh(sc, itd->itd_bp[1]) & EHCI_ITD_SET_DIR_IN) ? "in" : "out",
- EHCI_ITD_GET_MPL(ehci32toh(sc, itd->itd_bp[1])));
- printf(" bp[2..6]=0x%08x,0x%08x,0x%08x,0x%08x,0x%08x\n",
- ehci32toh(sc, itd->itd_bp[2]),
- ehci32toh(sc, itd->itd_bp[3]),
- ehci32toh(sc, itd->itd_bp[4]),
- ehci32toh(sc, itd->itd_bp[5]),
- ehci32toh(sc, itd->itd_bp[6]));
- printf(" bp_hi=0x%08x,0x%08x,0x%08x,0x%08x,\n"
- " 0x%08x,0x%08x,0x%08x\n",
- ehci32toh(sc, itd->itd_bp_hi[0]),
- ehci32toh(sc, itd->itd_bp_hi[1]),
- ehci32toh(sc, itd->itd_bp_hi[2]),
- ehci32toh(sc, itd->itd_bp_hi[3]),
- ehci32toh(sc, itd->itd_bp_hi[4]),
- ehci32toh(sc, itd->itd_bp_hi[5]),
- ehci32toh(sc, itd->itd_bp_hi[6]));
-}
-
-static void
-ehci_dump_isoc(ehci_softc_t *sc)
-{
- ehci_itd_t *itd;
- ehci_sitd_t *sitd;
- uint16_t max = 1000;
- uint16_t pos;
-
- pos = (EOREAD4(sc, EHCI_FRINDEX) / 8) &
- (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
-
- printf("%s: isochronous dump from frame 0x%03x:\n",
- __FUNCTION__, pos);
-
- itd = sc->sc_isoc_hs_p_last[pos];
- sitd = sc->sc_isoc_fs_p_last[pos];
-
- while (itd && max && max--) {
- ehci_dump_itd(sc, itd);
- itd = itd->prev;
- }
-
- while (sitd && max && max--) {
- ehci_dump_sitd(sc, sitd);
- sitd = sitd->prev;
- }
-}
-
-#endif
-
-static void
-ehci_transfer_intr_enqueue(struct usb2_xfer *xfer)
-{
- /* check for early completion */
- if (ehci_check_transfer(xfer)) {
- return;
- }
- /* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
-
- /* start timeout, if any */
- if (xfer->timeout != 0) {
- usb2_transfer_timeout_ms(xfer, &ehci_timeout, xfer->timeout);
- }
-}
-
-#define EHCI_APPEND_FS_TD(std,last) (last) = _ehci_append_fs_td(std,last)
-static ehci_sitd_t *
-_ehci_append_fs_td(ehci_sitd_t *std, ehci_sitd_t *last)
-{
- DPRINTFN(11, "%p to %p\n", std, last);
-
- /* (sc->sc_bus.mtx) must be locked */
-
- std->next = last->next;
- std->sitd_next = last->sitd_next;
-
- std->prev = last;
-
- usb2_pc_cpu_flush(std->page_cache);
-
- /*
- * the last->next->prev is never followed: std->next->prev = std;
- */
- last->next = std;
- last->sitd_next = std->sitd_self;
-
- usb2_pc_cpu_flush(last->page_cache);
-
- return (std);
-}
-
-#define EHCI_APPEND_HS_TD(std,last) (last) = _ehci_append_hs_td(std,last)
-static ehci_itd_t *
-_ehci_append_hs_td(ehci_itd_t *std, ehci_itd_t *last)
-{
- DPRINTFN(11, "%p to %p\n", std, last);
-
- /* (sc->sc_bus.mtx) must be locked */
-
- std->next = last->next;
- std->itd_next = last->itd_next;
-
- std->prev = last;
-
- usb2_pc_cpu_flush(std->page_cache);
-
- /*
- * the last->next->prev is never followed: std->next->prev = std;
- */
- last->next = std;
- last->itd_next = std->itd_self;
-
- usb2_pc_cpu_flush(last->page_cache);
-
- return (std);
-}
-
-#define EHCI_APPEND_QH(sqh,last) (last) = _ehci_append_qh(sqh,last)
-static ehci_qh_t *
-_ehci_append_qh(ehci_qh_t *sqh, ehci_qh_t *last)
-{
- DPRINTFN(11, "%p to %p\n", sqh, last);
-
- if (sqh->prev != NULL) {
- /* should not happen */
- DPRINTFN(0, "QH already linked!\n");
- return (last);
- }
- /* (sc->sc_bus.mtx) must be locked */
-
- sqh->next = last->next;
- sqh->qh_link = last->qh_link;
-
- sqh->prev = last;
-
- usb2_pc_cpu_flush(sqh->page_cache);
-
- /*
- * the last->next->prev is never followed: sqh->next->prev = sqh;
- */
-
- last->next = sqh;
- last->qh_link = sqh->qh_self;
-
- usb2_pc_cpu_flush(last->page_cache);
-
- return (sqh);
-}
-
-#define EHCI_REMOVE_FS_TD(std,last) (last) = _ehci_remove_fs_td(std,last)
-static ehci_sitd_t *
-_ehci_remove_fs_td(ehci_sitd_t *std, ehci_sitd_t *last)
-{
- DPRINTFN(11, "%p from %p\n", std, last);
-
- /* (sc->sc_bus.mtx) must be locked */
-
- std->prev->next = std->next;
- std->prev->sitd_next = std->sitd_next;
-
- usb2_pc_cpu_flush(std->prev->page_cache);
-
- if (std->next) {
- std->next->prev = std->prev;
- usb2_pc_cpu_flush(std->next->page_cache);
- }
- return ((last == std) ? std->prev : last);
-}
-
-#define EHCI_REMOVE_HS_TD(std,last) (last) = _ehci_remove_hs_td(std,last)
-static ehci_itd_t *
-_ehci_remove_hs_td(ehci_itd_t *std, ehci_itd_t *last)
-{
- DPRINTFN(11, "%p from %p\n", std, last);
-
- /* (sc->sc_bus.mtx) must be locked */
-
- std->prev->next = std->next;
- std->prev->itd_next = std->itd_next;
-
- usb2_pc_cpu_flush(std->prev->page_cache);
-
- if (std->next) {
- std->next->prev = std->prev;
- usb2_pc_cpu_flush(std->next->page_cache);
- }
- return ((last == std) ? std->prev : last);
-}
-
-#define EHCI_REMOVE_QH(sqh,last) (last) = _ehci_remove_qh(sqh,last)
-static ehci_qh_t *
-_ehci_remove_qh(ehci_qh_t *sqh, ehci_qh_t *last)
-{
- DPRINTFN(11, "%p from %p\n", sqh, last);
-
- /* (sc->sc_bus.mtx) must be locked */
-
- /* only remove if not removed from a queue */
- if (sqh->prev) {
-
- sqh->prev->next = sqh->next;
- sqh->prev->qh_link = sqh->qh_link;
-
- usb2_pc_cpu_flush(sqh->prev->page_cache);
-
- if (sqh->next) {
- sqh->next->prev = sqh->prev;
- usb2_pc_cpu_flush(sqh->next->page_cache);
- }
- last = ((last == sqh) ? sqh->prev : last);
-
- sqh->prev = 0;
-
- usb2_pc_cpu_flush(sqh->page_cache);
- }
- return (last);
-}
-
-static usb2_error_t
-ehci_non_isoc_done_sub(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
- ehci_qtd_t *td;
- ehci_qtd_t *td_alt_next;
- uint32_t status;
- uint16_t len;
-
- td = xfer->td_transfer_cache;
- td_alt_next = td->alt_next;
-
- if (xfer->aframes != xfer->nframes) {
- xfer->frlengths[xfer->aframes] = 0;
- }
- while (1) {
-
- usb2_pc_cpu_invalidate(td->page_cache);
- status = ehci32toh(sc, td->qtd_status);
-
- len = EHCI_QTD_GET_BYTES(status);
-
- /*
- * Verify the status length and
- * add the length to "frlengths[]":
- */
- if (len > td->len) {
- /* should not happen */
- DPRINTF("Invalid status length, "
- "0x%04x/0x%04x bytes\n", len, td->len);
- status |= EHCI_QTD_HALTED;
- } else if (xfer->aframes != xfer->nframes) {
- xfer->frlengths[xfer->aframes] += td->len - len;
- }
- /* Check for last transfer */
- if (((void *)td) == xfer->td_transfer_last) {
- if (len == 0) {
- /*
- * Halt is ok if descriptor is last,
- * and complete:
- */
- status &= ~EHCI_QTD_HALTED;
- }
- td = NULL;
- break;
- }
- /* Check for transfer error */
- if (status & EHCI_QTD_HALTED) {
- /* the transfer is finished */
- td = NULL;
- break;
- }
- /* Check for short transfer */
- if (len > 0) {
- if (xfer->flags_int.short_frames_ok) {
- /* follow alt next */
- td = td->alt_next;
- } else {
- /* the transfer is finished */
- td = NULL;
- }
- break;
- }
- td = td->obj_next;
-
- if (td->alt_next != td_alt_next) {
- /* this USB frame is complete */
- break;
- }
- }
-
- /* update transfer cache */
-
- xfer->td_transfer_cache = td;
-
- /* update data toggle */
-
- xfer->pipe->toggle_next =
- (status & EHCI_QTD_TOGGLE_MASK) ? 1 : 0;
-
-#if USB_DEBUG
- if (status & EHCI_QTD_STATERRS) {
- DPRINTFN(11, "error, addr=%d, endpt=0x%02x, frame=0x%02x"
- "status=%s%s%s%s%s%s%s%s\n",
- xfer->address, xfer->endpoint, xfer->aframes,
- (status & EHCI_QTD_ACTIVE) ? "[ACTIVE]" : "[NOT_ACTIVE]",
- (status & EHCI_QTD_HALTED) ? "[HALTED]" : "",
- (status & EHCI_QTD_BUFERR) ? "[BUFERR]" : "",
- (status & EHCI_QTD_BABBLE) ? "[BABBLE]" : "",
- (status & EHCI_QTD_XACTERR) ? "[XACTERR]" : "",
- (status & EHCI_QTD_MISSEDMICRO) ? "[MISSED]" : "",
- (status & EHCI_QTD_SPLITXSTATE) ? "[SPLIT]" : "",
- (status & EHCI_QTD_PINGSTATE) ? "[PING]" : "");
- }
-#endif
-
- return ((status & EHCI_QTD_HALTED) ?
- USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
-}
-
-static void
-ehci_non_isoc_done(struct usb2_xfer *xfer)
-{
- usb2_error_t err = 0;
-
- DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
- xfer, xfer->pipe);
-
-#if USB_DEBUG
- if (ehcidebug > 10) {
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-
- ehci_dump_sqtds(sc, xfer->td_transfer_first);
- }
-#endif
-
- /* reset scanner */
-
- xfer->td_transfer_cache = xfer->td_transfer_first;
-
- if (xfer->flags_int.control_xfr) {
-
- if (xfer->flags_int.control_hdr) {
-
- err = ehci_non_isoc_done_sub(xfer);
- }
- xfer->aframes = 1;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
- while (xfer->aframes != xfer->nframes) {
-
- err = ehci_non_isoc_done_sub(xfer);
- xfer->aframes++;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- err = ehci_non_isoc_done_sub(xfer);
- }
-done:
- ehci_device_done(xfer, err);
-}
-
-/*------------------------------------------------------------------------*
- * ehci_check_transfer
- *
- * Return values:
- * 0: USB transfer is not finished
- * Else: USB transfer is finished
- *------------------------------------------------------------------------*/
-static uint8_t
-ehci_check_transfer(struct usb2_xfer *xfer)
-{
- struct usb2_pipe_methods *methods = xfer->pipe->methods;
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-
- uint32_t status;
-
- DPRINTFN(13, "xfer=%p checking transfer\n", xfer);
-
- if (methods == &ehci_device_isoc_fs_methods) {
- ehci_sitd_t *td;
-
- /* isochronous full speed transfer */
-
- td = xfer->td_transfer_last;
- usb2_pc_cpu_invalidate(td->page_cache);
- status = ehci32toh(sc, td->sitd_status);
-
- /* also check if first is complete */
-
- td = xfer->td_transfer_first;
- usb2_pc_cpu_invalidate(td->page_cache);
- status |= ehci32toh(sc, td->sitd_status);
-
- if (!(status & EHCI_SITD_ACTIVE)) {
- ehci_device_done(xfer, USB_ERR_NORMAL_COMPLETION);
- goto transferred;
- }
- } else if (methods == &ehci_device_isoc_hs_methods) {
- ehci_itd_t *td;
-
- /* isochronous high speed transfer */
-
- td = xfer->td_transfer_last;
- usb2_pc_cpu_invalidate(td->page_cache);
- status =
- td->itd_status[0] | td->itd_status[1] |
- td->itd_status[2] | td->itd_status[3] |
- td->itd_status[4] | td->itd_status[5] |
- td->itd_status[6] | td->itd_status[7];
-
- /* also check first transfer */
- td = xfer->td_transfer_first;
- usb2_pc_cpu_invalidate(td->page_cache);
- status |=
- td->itd_status[0] | td->itd_status[1] |
- td->itd_status[2] | td->itd_status[3] |
- td->itd_status[4] | td->itd_status[5] |
- td->itd_status[6] | td->itd_status[7];
-
- /* if no transactions are active we continue */
- if (!(status & htoehci32(sc, EHCI_ITD_ACTIVE))) {
- ehci_device_done(xfer, USB_ERR_NORMAL_COMPLETION);
- goto transferred;
- }
- } else {
- ehci_qtd_t *td;
-
- /* non-isochronous transfer */
-
- /*
- * check whether there is an error somewhere in the middle,
- * or whether there was a short packet (SPD and not ACTIVE)
- */
- td = xfer->td_transfer_cache;
-
- while (1) {
- usb2_pc_cpu_invalidate(td->page_cache);
- status = ehci32toh(sc, td->qtd_status);
-
- /*
- * if there is an active TD the transfer isn't done
- */
- if (status & EHCI_QTD_ACTIVE) {
- /* update cache */
- xfer->td_transfer_cache = td;
- goto done;
- }
- /*
- * last transfer descriptor makes the transfer done
- */
- if (((void *)td) == xfer->td_transfer_last) {
- break;
- }
- /*
- * any kind of error makes the transfer done
- */
- if (status & EHCI_QTD_HALTED) {
- break;
- }
- /*
- * if there is no alternate next transfer, a short
- * packet also makes the transfer done
- */
- if (EHCI_QTD_GET_BYTES(status)) {
- if (xfer->flags_int.short_frames_ok) {
- /* follow alt next */
- if (td->alt_next) {
- td = td->alt_next;
- continue;
- }
- }
- /* transfer is done */
- break;
- }
- td = td->obj_next;
- }
- ehci_non_isoc_done(xfer);
- goto transferred;
- }
-
-done:
- DPRINTFN(13, "xfer=%p is still active\n", xfer);
- return (0);
-
-transferred:
- return (1);
-}
-
-static void
-ehci_pcd_enable(ehci_softc_t *sc)
-{
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- sc->sc_eintrs |= EHCI_STS_PCD;
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
-
- /* acknowledge any PCD interrupt */
- EOWRITE4(sc, EHCI_USBSTS, EHCI_STS_PCD);
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &ehci_root_intr_done);
-}
-
-static void
-ehci_interrupt_poll(ehci_softc_t *sc)
-{
- struct usb2_xfer *xfer;
-
-repeat:
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
- /*
- * check if transfer is transferred
- */
- if (ehci_check_transfer(xfer)) {
- /* queue has been modified */
- goto repeat;
- }
- }
-}
-
-/*------------------------------------------------------------------------*
- * ehci_interrupt - EHCI interrupt handler
- *
- * NOTE: Do not access "sc->sc_bus.bdev" inside the interrupt handler,
- * hence the interrupt handler will be setup before "sc->sc_bus.bdev"
- * is present !
- *------------------------------------------------------------------------*/
-void
-ehci_interrupt(ehci_softc_t *sc)
-{
- uint32_t status;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- DPRINTFN(16, "real interrupt\n");
-
-#if USB_DEBUG
- if (ehcidebug > 15) {
- ehci_dump_regs(sc);
- }
-#endif
-
- status = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
- if (status == 0) {
- /* the interrupt was not for us */
- goto done;
- }
- if (!(status & sc->sc_eintrs)) {
- goto done;
- }
- EOWRITE4(sc, EHCI_USBSTS, status); /* acknowledge */
-
- status &= sc->sc_eintrs;
-
- if (status & EHCI_STS_HSE) {
- printf("%s: unrecoverable error, "
- "controller halted\n", __FUNCTION__);
-#if USB_DEBUG
- ehci_dump_regs(sc);
- ehci_dump_isoc(sc);
-#endif
- }
- if (status & EHCI_STS_PCD) {
- /*
- * Disable PCD interrupt for now, because it will be
- * on until the port has been reset.
- */
- sc->sc_eintrs &= ~EHCI_STS_PCD;
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &ehci_root_intr_done);
-
- /* do not allow RHSC interrupts > 1 per second */
- usb2_callout_reset(&sc->sc_tmo_pcd, hz,
- (void *)&ehci_pcd_enable, sc);
- }
- status &= ~(EHCI_STS_INT | EHCI_STS_ERRINT | EHCI_STS_PCD | EHCI_STS_IAA);
-
- if (status != 0) {
- /* block unprocessed interrupts */
- sc->sc_eintrs &= ~status;
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
- printf("%s: blocking interrupts 0x%x\n", __FUNCTION__, status);
- }
- /* poll all the USB transfers */
- ehci_interrupt_poll(sc);
-
-done:
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-/*
- * called when a request does not complete
- */
-static void
-ehci_timeout(void *arg)
-{
- struct usb2_xfer *xfer = arg;
-
- DPRINTF("xfer=%p\n", xfer);
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- /* transfer is transferred */
- ehci_device_done(xfer, USB_ERR_TIMEOUT);
-}
-
-static void
-ehci_do_poll(struct usb2_bus *bus)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(bus);
-
- USB_BUS_LOCK(&sc->sc_bus);
- ehci_interrupt_poll(sc);
- ehci_root_ctrl_poll(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-static void
-ehci_setup_standard_chain_sub(struct ehci_std_temp *temp)
-{
- struct usb2_page_search buf_res;
- ehci_qtd_t *td;
- ehci_qtd_t *td_next;
- ehci_qtd_t *td_alt_next;
- uint32_t qtd_altnext;
- uint32_t buf_offset;
- uint32_t average;
- uint32_t len_old;
- uint8_t shortpkt_old;
- uint8_t precompute;
-
- qtd_altnext = htoehci32(temp->sc, EHCI_LINK_TERMINATE);
- td_alt_next = NULL;
- buf_offset = 0;
- shortpkt_old = temp->shortpkt;
- len_old = temp->len;
- precompute = 1;
-
-restart:
-
- td = temp->td;
- td_next = temp->td_next;
-
- while (1) {
-
- if (temp->len == 0) {
-
- if (temp->shortpkt) {
- break;
- }
- /* send a Zero Length Packet, ZLP, last */
-
- temp->shortpkt = 1;
- average = 0;
-
- } else {
-
- average = temp->average;
-
- if (temp->len < average) {
- if (temp->len % temp->max_frame_size) {
- temp->shortpkt = 1;
- }
- average = temp->len;
- }
- }
-
- if (td_next == NULL) {
- panic("%s: out of EHCI transfer descriptors!", __FUNCTION__);
- }
- /* get next TD */
-
- td = td_next;
- td_next = td->obj_next;
-
- /* check if we are pre-computing */
-
- if (precompute) {
-
- /* update remaining length */
-
- temp->len -= average;
-
- continue;
- }
- /* fill out current TD */
-
- td->qtd_status =
- temp->qtd_status |
- htoehci32(temp->sc, EHCI_QTD_SET_BYTES(average));
-
- if (average == 0) {
-
- if (temp->auto_data_toggle == 0) {
-
- /* update data toggle, ZLP case */
-
- temp->qtd_status ^=
- htoehci32(temp->sc, EHCI_QTD_TOGGLE_MASK);
- }
- td->len = 0;
-
- td->qtd_buffer[0] = 0;
- td->qtd_buffer_hi[0] = 0;
-
- td->qtd_buffer[1] = 0;
- td->qtd_buffer_hi[1] = 0;
-
- } else {
-
- uint8_t x;
-
- if (temp->auto_data_toggle == 0) {
-
- /* update data toggle */
-
- if (((average + temp->max_frame_size - 1) /
- temp->max_frame_size) & 1) {
- temp->qtd_status ^=
- htoehci32(temp->sc, EHCI_QTD_TOGGLE_MASK);
- }
- }
- td->len = average;
-
- /* update remaining length */
-
- temp->len -= average;
-
- /* fill out buffer pointers */
-
- usb2_get_page(temp->pc, buf_offset, &buf_res);
- td->qtd_buffer[0] =
- htoehci32(temp->sc, buf_res.physaddr);
- td->qtd_buffer_hi[0] = 0;
-
- x = 1;
-
- while (average > EHCI_PAGE_SIZE) {
- average -= EHCI_PAGE_SIZE;
- buf_offset += EHCI_PAGE_SIZE;
- usb2_get_page(temp->pc, buf_offset, &buf_res);
- td->qtd_buffer[x] =
- htoehci32(temp->sc,
- buf_res.physaddr & (~0xFFF));
- td->qtd_buffer_hi[x] = 0;
- x++;
- }
-
- /*
- * NOTE: The "average" variable is never zero after
- * exiting the loop above !
- *
- * NOTE: We have to subtract one from the offset to
- * ensure that we are computing the physical address
- * of a valid page !
- */
- buf_offset += average;
- usb2_get_page(temp->pc, buf_offset - 1, &buf_res);
- td->qtd_buffer[x] =
- htoehci32(temp->sc,
- buf_res.physaddr & (~0xFFF));
- td->qtd_buffer_hi[x] = 0;
- }
-
- if (td_next) {
- /* link the current TD with the next one */
- td->qtd_next = td_next->qtd_self;
- }
- td->qtd_altnext = qtd_altnext;
- td->alt_next = td_alt_next;
-
- usb2_pc_cpu_flush(td->page_cache);
- }
-
- if (precompute) {
- precompute = 0;
-
- /* setup alt next pointer, if any */
- if (temp->short_frames_ok) {
- if (temp->setup_alt_next) {
- td_alt_next = td_next;
- qtd_altnext = td_next->qtd_self;
- }
- } else {
- /* we use this field internally */
- td_alt_next = td_next;
- }
-
- /* restore */
- temp->shortpkt = shortpkt_old;
- temp->len = len_old;
- goto restart;
- }
- temp->td = td;
- temp->td_next = td_next;
-}
-
-static void
-ehci_setup_standard_chain(struct usb2_xfer *xfer, ehci_qh_t **qh_last)
-{
- struct ehci_std_temp temp;
- struct usb2_pipe_methods *methods;
- ehci_qh_t *qh;
- ehci_qtd_t *td;
- uint32_t qh_endp;
- uint32_t qh_endphub;
- uint32_t x;
-
- DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
- xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
-
- temp.average = xfer->max_usb2_frame_size;
- temp.max_frame_size = xfer->max_frame_size;
- temp.sc = EHCI_BUS2SC(xfer->xroot->bus);
-
- /* toggle the DMA set we are using */
- xfer->flags_int.curr_dma_set ^= 1;
-
- /* get next DMA set */
- td = xfer->td_start[xfer->flags_int.curr_dma_set];
-
- xfer->td_transfer_first = td;
- xfer->td_transfer_cache = td;
-
- temp.td = NULL;
- temp.td_next = td;
- temp.qtd_status = 0;
- temp.setup_alt_next = xfer->flags_int.short_frames_ok;
- temp.short_frames_ok = xfer->flags_int.short_frames_ok;
-
- if (xfer->flags_int.control_xfr) {
- if (xfer->pipe->toggle_next) {
- /* DATA1 is next */
- temp.qtd_status |=
- htoehci32(temp.sc, EHCI_QTD_SET_TOGGLE(1));
- }
- temp.auto_data_toggle = 0;
- } else {
- temp.auto_data_toggle = 1;
- }
-
- if (usb2_get_speed(xfer->xroot->udev) != USB_SPEED_HIGH) {
- /* max 3 retries */
- temp.qtd_status |=
- htoehci32(temp.sc, EHCI_QTD_SET_CERR(3));
- }
- /* check if we should prepend a setup message */
-
- if (xfer->flags_int.control_xfr) {
- if (xfer->flags_int.control_hdr) {
-
- temp.qtd_status &=
- htoehci32(temp.sc, EHCI_QTD_SET_CERR(3));
- temp.qtd_status |= htole32
- (EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) |
- EHCI_QTD_SET_TOGGLE(0));
-
- temp.len = xfer->frlengths[0];
- temp.pc = xfer->frbuffers + 0;
- temp.shortpkt = temp.len ? 1 : 0;
-
- ehci_setup_standard_chain_sub(&temp);
- }
- x = 1;
- } else {
- x = 0;
- }
-
- while (x != xfer->nframes) {
-
- /* DATA0 / DATA1 message */
-
- temp.len = xfer->frlengths[x];
- temp.pc = xfer->frbuffers + x;
-
- x++;
-
- if (x == xfer->nframes) {
- temp.setup_alt_next = 0;
- }
- /* keep previous data toggle and error count */
-
- temp.qtd_status &=
- htoehci32(temp.sc, EHCI_QTD_SET_CERR(3) |
- EHCI_QTD_SET_TOGGLE(1));
-
- if (temp.len == 0) {
-
- /* make sure that we send an USB packet */
-
- temp.shortpkt = 0;
-
- } else {
-
- /* regular data transfer */
-
- temp.shortpkt = (xfer->flags.force_short_xfer) ? 0 : 1;
- }
-
- /* set endpoint direction */
-
- temp.qtd_status |=
- (UE_GET_DIR(xfer->endpoint) == UE_DIR_IN) ?
- htoehci32(temp.sc, EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(EHCI_QTD_PID_IN)) :
- htoehci32(temp.sc, EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(EHCI_QTD_PID_OUT));
-
- ehci_setup_standard_chain_sub(&temp);
- }
-
- /* check if we should append a status stage */
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- /*
- * Send a DATA1 message and invert the current endpoint
- * direction.
- */
-
- temp.qtd_status &= htoehci32(temp.sc, EHCI_QTD_SET_CERR(3) |
- EHCI_QTD_SET_TOGGLE(1));
- temp.qtd_status |=
- (UE_GET_DIR(xfer->endpoint) == UE_DIR_OUT) ?
- htoehci32(temp.sc, EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(EHCI_QTD_PID_IN) |
- EHCI_QTD_SET_TOGGLE(1)) :
- htoehci32(temp.sc, EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(EHCI_QTD_PID_OUT) |
- EHCI_QTD_SET_TOGGLE(1));
-
- temp.len = 0;
- temp.pc = NULL;
- temp.shortpkt = 0;
-
- ehci_setup_standard_chain_sub(&temp);
- }
- td = temp.td;
-
- /* the last TD terminates the transfer: */
- td->qtd_next = htoehci32(temp.sc, EHCI_LINK_TERMINATE);
- td->qtd_altnext = htoehci32(temp.sc, EHCI_LINK_TERMINATE);
- td->qtd_status |= htoehci32(temp.sc, EHCI_QTD_IOC);
-
- usb2_pc_cpu_flush(td->page_cache);
-
- /* must have at least one frame! */
-
- xfer->td_transfer_last = td;
-
-#if USB_DEBUG
- if (ehcidebug > 8) {
- DPRINTF("nexttog=%d; data before transfer:\n",
- xfer->pipe->toggle_next);
- ehci_dump_sqtds(temp.sc,
- xfer->td_transfer_first);
- }
-#endif
-
- methods = xfer->pipe->methods;
-
- qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- /* the "qh_link" field is filled when the QH is added */
-
- qh_endp =
- (EHCI_QH_SET_ADDR(xfer->address) |
- EHCI_QH_SET_ENDPT(UE_GET_ADDR(xfer->endpoint)) |
- EHCI_QH_SET_MPL(xfer->max_packet_size));
-
- if (usb2_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
- qh_endp |= (EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) |
- EHCI_QH_DTC);
- if (methods != &ehci_device_intr_methods)
- qh_endp |= EHCI_QH_SET_NRL(8);
- } else {
-
- if (usb2_get_speed(xfer->xroot->udev) == USB_SPEED_FULL) {
- qh_endp |= (EHCI_QH_SET_EPS(EHCI_QH_SPEED_FULL) |
- EHCI_QH_DTC);
- } else {
- qh_endp |= (EHCI_QH_SET_EPS(EHCI_QH_SPEED_LOW) |
- EHCI_QH_DTC);
- }
-
- if (methods == &ehci_device_ctrl_methods) {
- qh_endp |= EHCI_QH_CTL;
- }
- if (methods != &ehci_device_intr_methods) {
- /* Only try one time per microframe! */
- qh_endp |= EHCI_QH_SET_NRL(1);
- }
- }
-
- qh->qh_endp = htoehci32(temp.sc, qh_endp);
-
- qh_endphub =
- (EHCI_QH_SET_MULT(xfer->max_packet_count & 3) |
- EHCI_QH_SET_CMASK(xfer->usb2_cmask) |
- EHCI_QH_SET_SMASK(xfer->usb2_smask) |
- EHCI_QH_SET_HUBA(xfer->xroot->udev->hs_hub_addr) |
- EHCI_QH_SET_PORT(xfer->xroot->udev->hs_port_no));
-
- qh->qh_endphub = htoehci32(temp.sc, qh_endphub);
- qh->qh_curqtd = htoehci32(temp.sc, 0);
-
- /* fill the overlay qTD */
- qh->qh_qtd.qtd_status = htoehci32(temp.sc, 0);
-
- if (temp.auto_data_toggle) {
-
- /* let the hardware compute the data toggle */
-
- qh->qh_endp &= htoehci32(temp.sc, ~EHCI_QH_DTC);
-
- if (xfer->pipe->toggle_next) {
- /* DATA1 is next */
- qh->qh_qtd.qtd_status |=
- htoehci32(temp.sc, EHCI_QTD_SET_TOGGLE(1));
- }
- }
- td = xfer->td_transfer_first;
-
- qh->qh_qtd.qtd_next = td->qtd_self;
- qh->qh_qtd.qtd_altnext =
- htoehci32(temp.sc, EHCI_LINK_TERMINATE);
-
- usb2_pc_cpu_flush(qh->page_cache);
-
- if (xfer->xroot->udev->pwr_save.suspended == 0) {
- EHCI_APPEND_QH(qh, *qh_last);
- }
-}
-
-static void
-ehci_root_intr_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
- uint16_t i;
- uint16_t m;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_PRE_DATA) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- ehci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* setup buffer */
- std->ptr = sc->sc_hub_idata;
- std->len = sizeof(sc->sc_hub_idata);
-
- /* clear any old interrupt data */
- bzero(sc->sc_hub_idata, sizeof(sc->sc_hub_idata));
-
- /* set bits */
- m = (sc->sc_noport + 1);
- if (m > (8 * sizeof(sc->sc_hub_idata))) {
- m = (8 * sizeof(sc->sc_hub_idata));
- }
- for (i = 1; i < m; i++) {
- /* pick out CHANGE bits from the status register */
- if (EOREAD4(sc, EHCI_PORTSC(i)) & EHCI_PS_CLEAR) {
- sc->sc_hub_idata[i / 8] |= 1 << (i % 8);
- DPRINTF("port %d changed\n", i);
- }
- }
-done:
- return;
-}
-
-static void
-ehci_isoc_fs_done(ehci_softc_t *sc, struct usb2_xfer *xfer)
-{
- uint32_t nframes = xfer->nframes;
- uint32_t status;
- uint32_t *plen = xfer->frlengths;
- uint16_t len = 0;
- ehci_sitd_t *td = xfer->td_transfer_first;
- ehci_sitd_t **pp_last = &sc->sc_isoc_fs_p_last[xfer->qh_pos];
-
- DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
- xfer, xfer->pipe);
-
- while (nframes--) {
- if (td == NULL) {
- panic("%s:%d: out of TD's\n",
- __FUNCTION__, __LINE__);
- }
- if (pp_last >= &sc->sc_isoc_fs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT]) {
- pp_last = &sc->sc_isoc_fs_p_last[0];
- }
-#if USB_DEBUG
- if (ehcidebug > 15) {
- DPRINTF("isoc FS-TD\n");
- ehci_dump_sitd(sc, td);
- }
-#endif
- usb2_pc_cpu_invalidate(td->page_cache);
- status = ehci32toh(sc, td->sitd_status);
-
- len = EHCI_SITD_GET_LEN(status);
-
- if (*plen >= len) {
- len = *plen - len;
- } else {
- len = 0;
- }
-
- *plen = len;
-
- /* remove FS-TD from schedule */
- EHCI_REMOVE_FS_TD(td, *pp_last);
-
- pp_last++;
- plen++;
- td = td->obj_next;
- }
-
- xfer->aframes = xfer->nframes;
-}
-
-static void
-ehci_isoc_hs_done(ehci_softc_t *sc, struct usb2_xfer *xfer)
-{
- uint32_t nframes = xfer->nframes;
- uint32_t status;
- uint32_t *plen = xfer->frlengths;
- uint16_t len = 0;
- uint8_t td_no = 0;
- ehci_itd_t *td = xfer->td_transfer_first;
- ehci_itd_t **pp_last = &sc->sc_isoc_hs_p_last[xfer->qh_pos];
-
- DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
- xfer, xfer->pipe);
-
- while (nframes--) {
- if (td == NULL) {
- panic("%s:%d: out of TD's\n",
- __FUNCTION__, __LINE__);
- }
- if (pp_last >= &sc->sc_isoc_hs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT]) {
- pp_last = &sc->sc_isoc_hs_p_last[0];
- }
-#if USB_DEBUG
- if (ehcidebug > 15) {
- DPRINTF("isoc HS-TD\n");
- ehci_dump_itd(sc, td);
- }
-#endif
-
- usb2_pc_cpu_invalidate(td->page_cache);
- status = ehci32toh(sc, td->itd_status[td_no]);
-
- len = EHCI_ITD_GET_LEN(status);
-
- if (*plen >= len) {
- /*
- * The length is valid. NOTE: The complete
- * length is written back into the status
- * field, and not the remainder like with
- * other transfer descriptor types.
- */
- } else {
- /* Invalid length - truncate */
- len = 0;
- }
-
- *plen = len;
-
- plen++;
- td_no++;
-
- if ((td_no == 8) || (nframes == 0)) {
- /* remove HS-TD from schedule */
- EHCI_REMOVE_HS_TD(td, *pp_last);
- pp_last++;
-
- td_no = 0;
- td = td->obj_next;
- }
- }
- xfer->aframes = xfer->nframes;
-}
-
-/* NOTE: "done" can be run two times in a row,
- * from close and from interrupt
- */
-static void
-ehci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
-{
- struct usb2_pipe_methods *methods = xfer->pipe->methods;
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
- xfer, xfer->pipe, error);
-
- if ((methods == &ehci_device_bulk_methods) ||
- (methods == &ehci_device_ctrl_methods)) {
-#if USB_DEBUG
- if (ehcidebug > 8) {
- DPRINTF("nexttog=%d; data after transfer:\n",
- xfer->pipe->toggle_next);
- ehci_dump_sqtds(sc,
- xfer->td_transfer_first);
- }
-#endif
-
- EHCI_REMOVE_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
- sc->sc_async_p_last);
- }
- if (methods == &ehci_device_intr_methods) {
- EHCI_REMOVE_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
- sc->sc_intr_p_last[xfer->qh_pos]);
- }
- /*
- * Only finish isochronous transfers once which will update
- * "xfer->frlengths".
- */
- if (xfer->td_transfer_first &&
- xfer->td_transfer_last) {
- if (methods == &ehci_device_isoc_fs_methods) {
- ehci_isoc_fs_done(sc, xfer);
- }
- if (methods == &ehci_device_isoc_hs_methods) {
- ehci_isoc_hs_done(sc, xfer);
- }
- xfer->td_transfer_first = NULL;
- xfer->td_transfer_last = NULL;
- }
- /* dequeue transfer and start next transfer */
- usb2_transfer_done(xfer, error);
-}
-
-/*------------------------------------------------------------------------*
- * ehci bulk support
- *------------------------------------------------------------------------*/
-static void
-ehci_device_bulk_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ehci_device_bulk_close(struct usb2_xfer *xfer)
-{
- ehci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-ehci_device_bulk_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ehci_device_bulk_start(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-
- /* setup TD's and QH */
- ehci_setup_standard_chain(xfer, &sc->sc_async_p_last);
-
- /* put transfer on interrupt queue */
- ehci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods ehci_device_bulk_methods =
-{
- .open = ehci_device_bulk_open,
- .close = ehci_device_bulk_close,
- .enter = ehci_device_bulk_enter,
- .start = ehci_device_bulk_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * ehci control support
- *------------------------------------------------------------------------*/
-static void
-ehci_device_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ehci_device_ctrl_close(struct usb2_xfer *xfer)
-{
- ehci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-ehci_device_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ehci_device_ctrl_start(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-
- /* setup TD's and QH */
- ehci_setup_standard_chain(xfer, &sc->sc_async_p_last);
-
- /* put transfer on interrupt queue */
- ehci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods ehci_device_ctrl_methods =
-{
- .open = ehci_device_ctrl_open,
- .close = ehci_device_ctrl_close,
- .enter = ehci_device_ctrl_enter,
- .start = ehci_device_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * ehci interrupt support
- *------------------------------------------------------------------------*/
-static void
-ehci_device_intr_open(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
- uint16_t best;
- uint16_t bit;
- uint16_t x;
- uint8_t slot;
-
- /* Allocate a microframe slot first: */
-
- slot = usb2_intr_schedule_adjust
- (xfer->xroot->udev, xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX);
-
- if (usb2_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
- xfer->usb2_uframe = slot;
- xfer->usb2_smask = (1 << slot) & 0xFF;
- xfer->usb2_cmask = 0;
- } else {
- xfer->usb2_uframe = slot;
- xfer->usb2_smask = (1 << slot) & 0x3F;
- xfer->usb2_cmask = (-(4 << slot)) & 0xFE;
- }
-
- /*
- * Find the best QH position corresponding to the given interval:
- */
-
- best = 0;
- bit = EHCI_VIRTUAL_FRAMELIST_COUNT / 2;
- while (bit) {
- if (xfer->interval >= bit) {
- x = bit;
- best = bit;
- while (x & bit) {
- if (sc->sc_intr_stat[x] <
- sc->sc_intr_stat[best]) {
- best = x;
- }
- x++;
- }
- break;
- }
- bit >>= 1;
- }
-
- sc->sc_intr_stat[best]++;
- xfer->qh_pos = best;
-
- DPRINTFN(3, "best=%d interval=%d\n",
- best, xfer->interval);
-}
-
-static void
-ehci_device_intr_close(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
- uint8_t slot;
-
- slot = usb2_intr_schedule_adjust
- (xfer->xroot->udev, -(xfer->max_frame_size), xfer->usb2_uframe);
-
- sc->sc_intr_stat[xfer->qh_pos]--;
-
- ehci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-ehci_device_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ehci_device_intr_start(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-
- /* setup TD's and QH */
- ehci_setup_standard_chain(xfer, &sc->sc_intr_p_last[xfer->qh_pos]);
-
- /* put transfer on interrupt queue */
- ehci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods ehci_device_intr_methods =
-{
- .open = ehci_device_intr_open,
- .close = ehci_device_intr_close,
- .enter = ehci_device_intr_enter,
- .start = ehci_device_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * ehci full speed isochronous support
- *------------------------------------------------------------------------*/
-static void
-ehci_device_isoc_fs_open(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
- ehci_sitd_t *td;
- uint32_t sitd_portaddr;
- uint8_t ds;
-
- sitd_portaddr =
- EHCI_SITD_SET_ADDR(xfer->address) |
- EHCI_SITD_SET_ENDPT(UE_GET_ADDR(xfer->endpoint)) |
- EHCI_SITD_SET_HUBA(xfer->xroot->udev->hs_hub_addr) |
- EHCI_SITD_SET_PORT(xfer->xroot->udev->hs_port_no);
-
- if (UE_GET_DIR(xfer->endpoint) == UE_DIR_IN) {
- sitd_portaddr |= EHCI_SITD_SET_DIR_IN;
- }
- sitd_portaddr = htoehci32(sc, sitd_portaddr);
-
- /* initialize all TD's */
-
- for (ds = 0; ds != 2; ds++) {
-
- for (td = xfer->td_start[ds]; td; td = td->obj_next) {
-
- td->sitd_portaddr = sitd_portaddr;
-
- /*
- * TODO: make some kind of automatic
- * SMASK/CMASK selection based on micro-frame
- * usage
- *
- * micro-frame usage (8 microframes per 1ms)
- */
- td->sitd_back = htoehci32(sc, EHCI_LINK_TERMINATE);
-
- usb2_pc_cpu_flush(td->page_cache);
- }
- }
-}
-
-static void
-ehci_device_isoc_fs_close(struct usb2_xfer *xfer)
-{
- ehci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-ehci_device_isoc_fs_enter(struct usb2_xfer *xfer)
-{
- struct usb2_page_search buf_res;
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
- struct usb2_fs_isoc_schedule *fss_start;
- struct usb2_fs_isoc_schedule *fss_end;
- struct usb2_fs_isoc_schedule *fss;
- ehci_sitd_t *td;
- ehci_sitd_t *td_last = NULL;
- ehci_sitd_t **pp_last;
- uint32_t *plen;
- uint32_t buf_offset;
- uint32_t nframes;
- uint32_t temp;
- uint32_t sitd_mask;
- uint16_t tlen;
- uint8_t sa;
- uint8_t sb;
- uint8_t error;
-
-#if USB_DEBUG
- uint8_t once = 1;
-
-#endif
-
- DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
- xfer, xfer->pipe->isoc_next, xfer->nframes);
-
- /* get the current frame index */
-
- nframes = EOREAD4(sc, EHCI_FRINDEX) / 8;
-
- /*
- * check if the frame index is within the window where the frames
- * will be inserted
- */
- buf_offset = (nframes - xfer->pipe->isoc_next) &
- (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
-
- if ((xfer->pipe->is_synced == 0) ||
- (buf_offset < xfer->nframes)) {
- /*
- * If there is data underflow or the pipe queue is empty we
- * schedule the transfer a few frames ahead of the current
- * frame position. Else two isochronous transfers might
- * overlap.
- */
- xfer->pipe->isoc_next = (nframes + 3) &
- (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
- xfer->pipe->is_synced = 1;
- DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next);
- }
- /*
- * compute how many milliseconds the insertion is ahead of the
- * current frame position:
- */
- buf_offset = (xfer->pipe->isoc_next - nframes) &
- (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
-
- /*
- * pre-compute when the isochronous transfer will be finished:
- */
- xfer->isoc_time_complete =
- usb2_fs_isoc_schedule_isoc_time_expand
- (xfer->xroot->udev, &fss_start, &fss_end, nframes) + buf_offset +
- xfer->nframes;
-
- /* get the real number of frames */
-
- nframes = xfer->nframes;
-
- buf_offset = 0;
-
- plen = xfer->frlengths;
-
- /* toggle the DMA set we are using */
- xfer->flags_int.curr_dma_set ^= 1;
-
- /* get next DMA set */
- td = xfer->td_start[xfer->flags_int.curr_dma_set];
- xfer->td_transfer_first = td;
-
- pp_last = &sc->sc_isoc_fs_p_last[xfer->pipe->isoc_next];
-
- /* store starting position */
-
- xfer->qh_pos = xfer->pipe->isoc_next;
-
- fss = fss_start + (xfer->qh_pos % USB_ISOC_TIME_MAX);
-
- while (nframes--) {
- if (td == NULL) {
- panic("%s:%d: out of TD's\n",
- __FUNCTION__, __LINE__);
- }
- if (pp_last >= &sc->sc_isoc_fs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT]) {
- pp_last = &sc->sc_isoc_fs_p_last[0];
- }
- if (fss >= fss_end) {
- fss = fss_start;
- }
- /* reuse sitd_portaddr and sitd_back from last transfer */
-
- if (*plen > xfer->max_frame_size) {
-#if USB_DEBUG
- if (once) {
- once = 0;
- printf("%s: frame length(%d) exceeds %d "
- "bytes (frame truncated)\n",
- __FUNCTION__, *plen,
- xfer->max_frame_size);
- }
-#endif
- *plen = xfer->max_frame_size;
- }
- /*
- * We currently don't care if the ISOCHRONOUS schedule is
- * full!
- */
- error = usb2_fs_isoc_schedule_alloc(fss, &sa, *plen);
- if (error) {
- /*
- * The FULL speed schedule is FULL! Set length
- * to zero.
- */
- *plen = 0;
- }
- if (*plen) {
- /*
- * only call "usb2_get_page()" when we have a
- * non-zero length
- */
- usb2_get_page(xfer->frbuffers, buf_offset, &buf_res);
- td->sitd_bp[0] = htoehci32(sc, buf_res.physaddr);
- buf_offset += *plen;
- /*
- * NOTE: We need to subtract one from the offset so
- * that we are on a valid page!
- */
- usb2_get_page(xfer->frbuffers, buf_offset - 1,
- &buf_res);
- temp = buf_res.physaddr & ~0xFFF;
- } else {
- td->sitd_bp[0] = 0;
- temp = 0;
- }
-
- if (UE_GET_DIR(xfer->endpoint) == UE_DIR_OUT) {
- tlen = *plen;
- if (tlen <= 188) {
- temp |= 1; /* T-count = 1, TP = ALL */
- tlen = 1;
- } else {
- tlen += 187;
- tlen /= 188;
- temp |= tlen; /* T-count = [1..6] */
- temp |= 8; /* TP = Begin */
- }
-
- tlen += sa;
-
- if (tlen >= 8) {
- sb = 0;
- } else {
- sb = (1 << tlen);
- }
-
- sa = (1 << sa);
- sa = (sb - sa) & 0x3F;
- sb = 0;
- } else {
- sb = (-(4 << sa)) & 0xFE;
- sa = (1 << sa) & 0x3F;
- }
-
- sitd_mask = (EHCI_SITD_SET_SMASK(sa) |
- EHCI_SITD_SET_CMASK(sb));
-
- td->sitd_bp[1] = htoehci32(sc, temp);
-
- td->sitd_mask = htoehci32(sc, sitd_mask);
-
- if (nframes == 0) {
- td->sitd_status = htole32
- (EHCI_SITD_IOC |
- EHCI_SITD_ACTIVE |
- EHCI_SITD_SET_LEN(*plen));
- } else {
- td->sitd_status = htole32
- (EHCI_SITD_ACTIVE |
- EHCI_SITD_SET_LEN(*plen));
- }
- usb2_pc_cpu_flush(td->page_cache);
-
-#if USB_DEBUG
- if (ehcidebug > 15) {
- DPRINTF("FS-TD %d\n", nframes);
- ehci_dump_sitd(sc, td);
- }
-#endif
- /* insert TD into schedule */
- EHCI_APPEND_FS_TD(td, *pp_last);
- pp_last++;
-
- plen++;
- fss++;
- td_last = td;
- td = td->obj_next;
- }
-
- xfer->td_transfer_last = td_last;
-
- /* update isoc_next */
- xfer->pipe->isoc_next = (pp_last - &sc->sc_isoc_fs_p_last[0]) &
- (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
-}
-
-static void
-ehci_device_isoc_fs_start(struct usb2_xfer *xfer)
-{
- /* put transfer on interrupt queue */
- ehci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods ehci_device_isoc_fs_methods =
-{
- .open = ehci_device_isoc_fs_open,
- .close = ehci_device_isoc_fs_close,
- .enter = ehci_device_isoc_fs_enter,
- .start = ehci_device_isoc_fs_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * ehci high speed isochronous support
- *------------------------------------------------------------------------*/
-static void
-ehci_device_isoc_hs_open(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
- ehci_itd_t *td;
- uint32_t temp;
- uint8_t ds;
-
- /* initialize all TD's */
-
- for (ds = 0; ds != 2; ds++) {
-
- for (td = xfer->td_start[ds]; td; td = td->obj_next) {
-
- /* set TD inactive */
- td->itd_status[0] = 0;
- td->itd_status[1] = 0;
- td->itd_status[2] = 0;
- td->itd_status[3] = 0;
- td->itd_status[4] = 0;
- td->itd_status[5] = 0;
- td->itd_status[6] = 0;
- td->itd_status[7] = 0;
-
- /* set endpoint and address */
- td->itd_bp[0] = htole32
- (EHCI_ITD_SET_ADDR(xfer->address) |
- EHCI_ITD_SET_ENDPT(UE_GET_ADDR(xfer->endpoint)));
-
- temp =
- EHCI_ITD_SET_MPL(xfer->max_packet_size & 0x7FF);
-
- /* set direction */
- if (UE_GET_DIR(xfer->endpoint) == UE_DIR_IN) {
- temp |= EHCI_ITD_SET_DIR_IN;
- }
- /* set maximum packet size */
- td->itd_bp[1] = htoehci32(sc, temp);
-
- /* set transfer multiplier */
- td->itd_bp[2] = htoehci32(sc, xfer->max_packet_count & 3);
-
- usb2_pc_cpu_flush(td->page_cache);
- }
- }
-}
-
-static void
-ehci_device_isoc_hs_close(struct usb2_xfer *xfer)
-{
- ehci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-ehci_device_isoc_hs_enter(struct usb2_xfer *xfer)
-{
- struct usb2_page_search buf_res;
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
- ehci_itd_t *td;
- ehci_itd_t *td_last = NULL;
- ehci_itd_t **pp_last;
- bus_size_t page_addr;
- uint32_t *plen;
- uint32_t status;
- uint32_t buf_offset;
- uint32_t nframes;
- uint32_t itd_offset[8 + 1];
- uint8_t x;
- uint8_t td_no;
- uint8_t page_no;
-
-#if USB_DEBUG
- uint8_t once = 1;
-
-#endif
-
- DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
- xfer, xfer->pipe->isoc_next, xfer->nframes);
-
- /* get the current frame index */
-
- nframes = EOREAD4(sc, EHCI_FRINDEX) / 8;
-
- /*
- * check if the frame index is within the window where the frames
- * will be inserted
- */
- buf_offset = (nframes - xfer->pipe->isoc_next) &
- (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
-
- if ((xfer->pipe->is_synced == 0) ||
- (buf_offset < ((xfer->nframes + 7) / 8))) {
- /*
- * If there is data underflow or the pipe queue is empty we
- * schedule the transfer a few frames ahead of the current
- * frame position. Else two isochronous transfers might
- * overlap.
- */
- xfer->pipe->isoc_next = (nframes + 3) &
- (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
- xfer->pipe->is_synced = 1;
- DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next);
- }
- /*
- * compute how many milliseconds the insertion is ahead of the
- * current frame position:
- */
- buf_offset = (xfer->pipe->isoc_next - nframes) &
- (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
-
- /*
- * pre-compute when the isochronous transfer will be finished:
- */
- xfer->isoc_time_complete =
- usb2_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset +
- ((xfer->nframes + 7) / 8);
-
- /* get the real number of frames */
-
- nframes = xfer->nframes;
-
- buf_offset = 0;
- td_no = 0;
-
- plen = xfer->frlengths;
-
- /* toggle the DMA set we are using */
- xfer->flags_int.curr_dma_set ^= 1;
-
- /* get next DMA set */
- td = xfer->td_start[xfer->flags_int.curr_dma_set];
- xfer->td_transfer_first = td;
-
- pp_last = &sc->sc_isoc_hs_p_last[xfer->pipe->isoc_next];
-
- /* store starting position */
-
- xfer->qh_pos = xfer->pipe->isoc_next;
-
- while (nframes--) {
- if (td == NULL) {
- panic("%s:%d: out of TD's\n",
- __FUNCTION__, __LINE__);
- }
- if (pp_last >= &sc->sc_isoc_hs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT]) {
- pp_last = &sc->sc_isoc_hs_p_last[0];
- }
- /* range check */
- if (*plen > xfer->max_frame_size) {
-#if USB_DEBUG
- if (once) {
- once = 0;
- printf("%s: frame length(%d) exceeds %d bytes "
- "(frame truncated)\n",
- __FUNCTION__, *plen, xfer->max_frame_size);
- }
-#endif
- *plen = xfer->max_frame_size;
- }
- status = (EHCI_ITD_SET_LEN(*plen) |
- EHCI_ITD_ACTIVE |
- EHCI_ITD_SET_PG(0));
- td->itd_status[td_no] = htoehci32(sc, status);
- itd_offset[td_no] = buf_offset;
- buf_offset += *plen;
- plen++;
- td_no++;
-
- if ((td_no == 8) || (nframes == 0)) {
-
- /* the rest of the transfers are not active, if any */
- for (x = td_no; x != 8; x++) {
- td->itd_status[x] = 0; /* not active */
- }
-
- /* check if there is any data to be transferred */
- if (itd_offset[0] != buf_offset) {
- page_no = 0;
- itd_offset[td_no] = buf_offset;
-
- /* get first page offset */
- usb2_get_page(xfer->frbuffers, itd_offset[0], &buf_res);
- /* get page address */
- page_addr = buf_res.physaddr & ~0xFFF;
- /* update page address */
- td->itd_bp[0] &= htoehci32(sc, 0xFFF);
- td->itd_bp[0] |= htoehci32(sc, page_addr);
-
- for (x = 0; x != td_no; x++) {
- /* set page number and page offset */
- status = (EHCI_ITD_SET_PG(page_no) |
- (buf_res.physaddr & 0xFFF));
- td->itd_status[x] |= htoehci32(sc, status);
-
- /* get next page offset */
- if (itd_offset[x + 1] == buf_offset) {
- /*
- * We subtract one so that
- * we don't go off the last
- * page!
- */
- usb2_get_page(xfer->frbuffers, buf_offset - 1, &buf_res);
- } else {
- usb2_get_page(xfer->frbuffers, itd_offset[x + 1], &buf_res);
- }
-
- /* check if we need a new page */
- if ((buf_res.physaddr ^ page_addr) & ~0xFFF) {
- /* new page needed */
- page_addr = buf_res.physaddr & ~0xFFF;
- if (page_no == 6) {
- panic("%s: too many pages\n", __FUNCTION__);
- }
- page_no++;
- /* update page address */
- td->itd_bp[page_no] &= htoehci32(sc, 0xFFF);
- td->itd_bp[page_no] |= htoehci32(sc, page_addr);
- }
- }
- }
- /* set IOC bit if we are complete */
- if (nframes == 0) {
- td->itd_status[7] |= htoehci32(sc, EHCI_ITD_IOC);
- }
- usb2_pc_cpu_flush(td->page_cache);
-#if USB_DEBUG
- if (ehcidebug > 15) {
- DPRINTF("HS-TD %d\n", nframes);
- ehci_dump_itd(sc, td);
- }
-#endif
- /* insert TD into schedule */
- EHCI_APPEND_HS_TD(td, *pp_last);
- pp_last++;
-
- td_no = 0;
- td_last = td;
- td = td->obj_next;
- }
- }
-
- xfer->td_transfer_last = td_last;
-
- /* update isoc_next */
- xfer->pipe->isoc_next = (pp_last - &sc->sc_isoc_hs_p_last[0]) &
- (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
-}
-
-static void
-ehci_device_isoc_hs_start(struct usb2_xfer *xfer)
-{
- /* put transfer on interrupt queue */
- ehci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods ehci_device_isoc_hs_methods =
-{
- .open = ehci_device_isoc_hs_open,
- .close = ehci_device_isoc_hs_close,
- .enter = ehci_device_isoc_hs_enter,
- .start = ehci_device_isoc_hs_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * ehci root control support
- *------------------------------------------------------------------------*
- * simulate a hardware hub by handling
- * all the necessary requests
- *------------------------------------------------------------------------*/
-
-static void
-ehci_root_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ehci_root_ctrl_close(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_ctrl.xfer == xfer) {
- sc->sc_root_ctrl.xfer = NULL;
- }
- ehci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-/* data structures and routines
- * to emulate the root hub:
- */
-
-static const
-struct usb2_device_descriptor ehci_devd =
-{
- sizeof(struct usb2_device_descriptor),
- 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 const
-struct usb2_device_qualifier ehci_odevd =
-{
- sizeof(struct usb2_device_qualifier),
- UDESC_DEVICE_QUALIFIER, /* type */
- {0x00, 0x02}, /* USB version */
- UDCLASS_HUB, /* class */
- UDSUBCLASS_HUB, /* subclass */
- UDPROTO_FSHUB, /* protocol */
- 0, /* max packet */
- 0, /* # of configurations */
- 0
-};
-
-static const struct ehci_config_desc ehci_confd = {
- .confd = {
- .bLength = sizeof(struct usb2_config_descriptor),
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength[0] = sizeof(ehci_confd),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_SELF_POWERED,
- .bMaxPower = 0 /* max power */
- },
-
- .ifcd = {
- .bLength = sizeof(struct usb2_interface_descriptor),
- .bDescriptorType = UDESC_INTERFACE,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_HSHUBSTT,
- 0
- },
-
- .endpd = {
- .bLength = sizeof(struct usb2_endpoint_descriptor),
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = UE_DIR_IN | EHCI_INTR_ENDPT,
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize[0] = 8, /* max packet (63 ports) */
- .bInterval = 255,
- },
-};
-
-static const
-struct usb2_hub_descriptor ehci_hubd =
-{
- 0, /* dynamic length */
- UDESC_HUB,
- 0,
- {0, 0},
- 0,
- 0,
- {0},
-};
-
-static void
-ehci_disown(ehci_softc_t *sc, uint16_t index, uint8_t lowspeed)
-{
- uint32_t port;
- uint32_t v;
-
- DPRINTF("index=%d lowspeed=%d\n", index, lowspeed);
-
- port = EHCI_PORTSC(index);
- v = EOREAD4(sc, port) & ~EHCI_PS_CLEAR;
- EOWRITE4(sc, port, v | EHCI_PS_PO);
-}
-
-static void
-ehci_root_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ehci_root_ctrl_start(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-
- DPRINTF("\n");
-
- sc->sc_root_ctrl.xfer = xfer;
-
- usb2_bus_roothub_exec(xfer->xroot->bus);
-}
-
-static void
-ehci_root_ctrl_task(struct usb2_bus *bus)
-{
- ehci_root_ctrl_poll(EHCI_BUS2SC(bus));
-}
-
-static void
-ehci_root_ctrl_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
- char *ptr;
- uint32_t port;
- uint32_t v;
- uint16_t i;
- uint16_t value;
- uint16_t index;
- uint8_t l;
- uint8_t use_polling;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_SETUP) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- ehci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* buffer reset */
- std->ptr = sc->sc_hub_desc.temp;
- std->len = 0;
-
- value = UGETW(std->req.wValue);
- index = UGETW(std->req.wIndex);
-
- use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
-
- DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
- "wValue=0x%04x wIndex=0x%04x\n",
- std->req.bmRequestType, std->req.bRequest,
- UGETW(std->req.wLength), value, index);
-
-#define C(x,y) ((x) | ((y) << 8))
- switch (C(std->req.bRequest, std->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):
- std->len = 1;
- sc->sc_hub_desc.temp[0] = sc->sc_conf;
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- switch (value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- std->len = sizeof(ehci_devd);
- sc->sc_hub_desc.devd = ehci_devd;
- break;
- /*
- * We can't really operate at another speed,
- * but the specification says we need this
- * descriptor:
- */
- case UDESC_DEVICE_QUALIFIER:
- if ((value & 0xff) != 0) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- std->len = sizeof(ehci_odevd);
- sc->sc_hub_desc.odevd = ehci_odevd;
- break;
-
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- std->len = sizeof(ehci_confd);
- std->ptr = USB_ADD_BYTES(&ehci_confd, 0);
- break;
-
- case UDESC_STRING:
- switch (value & 0xff) {
- case 0: /* Language table */
- ptr = "\001";
- break;
-
- case 1: /* Vendor */
- ptr = sc->sc_vendor;
- break;
-
- case 2: /* Product */
- ptr = "EHCI root HUB";
- break;
-
- default:
- ptr = "";
- break;
- }
-
- std->len = usb2_make_str_desc
- (sc->sc_hub_desc.temp,
- sizeof(sc->sc_hub_desc.temp),
- ptr);
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- std->len = 1;
- sc->sc_hub_desc.temp[0] = 0;
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- std->len = 2;
- USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED);
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- std->len = 2;
- USETW(sc->sc_hub_desc.stat.wStatus, 0);
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- if (value >= USB_MAX_DEVICES) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- if ((value != 0) && (value != 1)) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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):
- std->err = USB_ERR_IOERROR;
- goto done;
- 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(9, "UR_CLEAR_PORT_FEATURE\n");
-
- if ((index < 1) ||
- (index > sc->sc_noport)) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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:
- if ((v & EHCI_PS_SUSP) && (!(v & EHCI_PS_FPR))) {
-
- /*
- * waking up a High Speed device is rather
- * complicated if
- */
- EOWRITE4(sc, port, v | EHCI_PS_FPR);
- }
- /* wait 20ms for resume sequence to complete */
- if (use_polling) {
- /* polling */
- DELAY(20000);
- } else {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 50);
- }
-
- EOWRITE4(sc, port, v & ~(EHCI_PS_SUSP |
- EHCI_PS_FPR | (3 << 10) /* High Speed */ ));
-
- /* settle time */
- if (use_polling) {
- /* polling */
- DELAY(4000);
- } else {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 250);
- }
- break;
- case UHF_PORT_POWER:
- EOWRITE4(sc, port, v & ~EHCI_PS_PP);
- break;
- case UHF_PORT_TEST:
- DPRINTFN(3, "clear port test "
- "%d\n", index);
- break;
- case UHF_PORT_INDICATOR:
- DPRINTFN(3, "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:
- EOWRITE4(sc, port, v | EHCI_PS_SUSP);
- 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:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- if ((value & 0xff) != 0) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- v = EOREAD4(sc, EHCI_HCSPARAMS);
-
- sc->sc_hub_desc.hubd = ehci_hubd;
- sc->sc_hub_desc.hubd.bNbrPorts = sc->sc_noport;
- USETW(sc->sc_hub_desc.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));
- /* XXX can't find out? */
- sc->sc_hub_desc.hubd.bPwrOn2PwrGood = 200;
- for (l = 0; l < sc->sc_noport; l++) {
- /* XXX can't find out? */
- sc->sc_hub_desc.hubd.DeviceRemovable[l / 8] &= ~(1 << (l % 8));
- }
- sc->sc_hub_desc.hubd.bDescLength =
- 8 + ((sc->sc_noport + 7) / 8);
- std->len = sc->sc_hub_desc.hubd.bDescLength;
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
- std->len = 16;
- bzero(sc->sc_hub_desc.temp, 16);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- DPRINTFN(9, "get port status i=%d\n",
- index);
- if ((index < 1) ||
- (index > sc->sc_noport)) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- v = EOREAD4(sc, EHCI_PORTSC(index));
- DPRINTFN(9, "port status=0x%04x\n", v);
- if (sc->sc_flags & EHCI_SCFLG_FORCESPEED) {
- if ((v & 0xc000000) == 0x8000000)
- i = UPS_HIGH_SPEED;
- else if ((v & 0xc000000) == 0x4000000)
- i = UPS_LOW_SPEED;
- else
- i = 0;
- } else {
- i = UPS_HIGH_SPEED;
- }
- if (v & EHCI_PS_CS)
- i |= UPS_CURRENT_CONNECT_STATUS;
- if (v & EHCI_PS_PE)
- i |= UPS_PORT_ENABLED;
- if ((v & EHCI_PS_SUSP) && !(v & EHCI_PS_FPR))
- 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(sc->sc_hub_desc.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 (v & EHCI_PS_FPR)
- i |= UPS_C_SUSPEND;
- if (sc->sc_isreset)
- i |= UPS_C_PORT_RESET;
- USETW(sc->sc_hub_desc.ps.wPortChange, i);
- std->len = sizeof(sc->sc_hub_desc.ps);
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- std->err = USB_ERR_IOERROR;
- goto done;
- 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)) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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(6, "reset port %d\n", index);
-#if USB_DEBUG
- if (ehcinohighspeed) {
- /*
- * Connect USB device to companion
- * controller.
- */
- ehci_disown(sc, index, 1);
- break;
- }
-#endif
- if (EHCI_PS_IS_LOWSPEED(v)) {
- /* Low speed device, give up ownership. */
- ehci_disown(sc, index, 1);
- break;
- }
- /* Start reset sequence. */
- v &= ~(EHCI_PS_PE | EHCI_PS_PR);
- EOWRITE4(sc, port, v | EHCI_PS_PR);
-
- if (use_polling) {
- /* polling */
- DELAY(USB_PORT_ROOT_RESET_DELAY * 1000);
- } else {
- /* Wait for reset to complete. */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_PORT_ROOT_RESET_DELAY));
- }
-
- /* Terminate reset sequence. */
- if (!(sc->sc_flags & EHCI_SCFLG_NORESTERM))
- EOWRITE4(sc, port, v);
-
- if (use_polling) {
- /* polling */
- DELAY(EHCI_PORT_RESET_COMPLETE * 1000);
- } else {
- /* Wait for HC to complete reset. */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(EHCI_PORT_RESET_COMPLETE));
- }
-
- v = EOREAD4(sc, port);
- DPRINTF("ehci after reset, status=0x%08x\n", v);
- if (v & EHCI_PS_PR) {
- device_printf(sc->sc_bus.bdev,
- "port reset timeout\n");
- std->err = USB_ERR_TIMEOUT;
- goto done;
- }
- if (!(v & EHCI_PS_PE)) {
- /*
- * Not a high speed device, give up
- * ownership.
- */
- ehci_disown(sc, index, 0);
- break;
- }
- sc->sc_isreset = 1;
- DPRINTF("ehci port %d reset, status = 0x%08x\n",
- index, v);
- break;
-
- case UHF_PORT_POWER:
- DPRINTFN(3, "set port power %d\n", index);
- EOWRITE4(sc, port, v | EHCI_PS_PP);
- break;
-
- case UHF_PORT_TEST:
- DPRINTFN(3, "set port test %d\n", index);
- break;
-
- case UHF_PORT_INDICATOR:
- DPRINTFN(3, "set port ind %d\n", index);
- EOWRITE4(sc, port, v | EHCI_PS_PIC);
- break;
-
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
-done:
- return;
-}
-
-static void
-ehci_root_ctrl_poll(ehci_softc_t *sc)
-{
- usb2_sw_transfer(&sc->sc_root_ctrl,
- &ehci_root_ctrl_done);
-}
-
-struct usb2_pipe_methods ehci_root_ctrl_methods =
-{
- .open = ehci_root_ctrl_open,
- .close = ehci_root_ctrl_close,
- .enter = ehci_root_ctrl_enter,
- .start = ehci_root_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 0,
-};
-
-/*------------------------------------------------------------------------*
- * ehci root interrupt support
- *------------------------------------------------------------------------*/
-static void
-ehci_root_intr_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ehci_root_intr_close(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_intr.xfer == xfer) {
- sc->sc_root_intr.xfer = NULL;
- }
- ehci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-ehci_root_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ehci_root_intr_start(struct usb2_xfer *xfer)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_intr.xfer = xfer;
-}
-
-struct usb2_pipe_methods ehci_root_intr_methods =
-{
- .open = ehci_root_intr_open,
- .close = ehci_root_intr_close,
- .enter = ehci_root_intr_enter,
- .start = ehci_root_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-static void
-ehci_xfer_setup(struct usb2_setup_params *parm)
-{
- struct usb2_page_search page_info;
- struct usb2_page_cache *pc;
- ehci_softc_t *sc;
- struct usb2_xfer *xfer;
- void *last_obj;
- uint32_t nqtd;
- uint32_t nqh;
- uint32_t nsitd;
- uint32_t nitd;
- uint32_t n;
-
- sc = EHCI_BUS2SC(parm->udev->bus);
- xfer = parm->curr_xfer;
-
- nqtd = 0;
- nqh = 0;
- nsitd = 0;
- nitd = 0;
-
- /*
- * compute maximum number of some structures
- */
- if (parm->methods == &ehci_device_ctrl_methods) {
-
- /*
- * The proof for the "nqtd" formula is illustrated like
- * this:
- *
- * +------------------------------------+
- * | |
- * | |remainder -> |
- * | +-----+---+ |
- * | | xxx | x | frm 0 |
- * | +-----+---++ |
- * | | xxx | xx | frm 1 |
- * | +-----+----+ |
- * | ... |
- * +------------------------------------+
- *
- * "xxx" means a completely full USB transfer descriptor
- *
- * "x" and "xx" means a short USB packet
- *
- * For the remainder of an USB transfer modulo
- * "max_data_length" we need two USB transfer descriptors.
- * One to transfer the remaining data and one to finalise
- * with a zero length packet in case the "force_short_xfer"
- * flag is set. We only need two USB transfer descriptors in
- * the case where the transfer length of the first one is a
- * factor of "max_frame_size". The rest of the needed USB
- * transfer descriptors is given by the buffer size divided
- * by the maximum data payload.
- */
- parm->hc_max_packet_size = 0x400;
- parm->hc_max_packet_count = 1;
- parm->hc_max_frame_size = EHCI_QTD_PAYLOAD_MAX;
- xfer->flags_int.bdma_enable = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nqh = 1;
- nqtd = ((2 * xfer->nframes) + 1 /* STATUS */
- + (xfer->max_data_length / xfer->max_usb2_frame_size));
-
- } else if (parm->methods == &ehci_device_bulk_methods) {
-
- parm->hc_max_packet_size = 0x400;
- parm->hc_max_packet_count = 1;
- parm->hc_max_frame_size = EHCI_QTD_PAYLOAD_MAX;
- xfer->flags_int.bdma_enable = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nqh = 1;
- nqtd = ((2 * xfer->nframes)
- + (xfer->max_data_length / xfer->max_usb2_frame_size));
-
- } else if (parm->methods == &ehci_device_intr_methods) {
-
- if (parm->speed == USB_SPEED_HIGH) {
- parm->hc_max_packet_size = 0x400;
- parm->hc_max_packet_count = 3;
- } else if (parm->speed == USB_SPEED_FULL) {
- parm->hc_max_packet_size = USB_FS_BYTES_PER_HS_UFRAME;
- parm->hc_max_packet_count = 1;
- } else {
- parm->hc_max_packet_size = USB_FS_BYTES_PER_HS_UFRAME / 8;
- parm->hc_max_packet_count = 1;
- }
-
- parm->hc_max_frame_size = EHCI_QTD_PAYLOAD_MAX;
- xfer->flags_int.bdma_enable = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nqh = 1;
- nqtd = ((2 * xfer->nframes)
- + (xfer->max_data_length / xfer->max_usb2_frame_size));
-
- } else if (parm->methods == &ehci_device_isoc_fs_methods) {
-
- parm->hc_max_packet_size = 0x3FF;
- parm->hc_max_packet_count = 1;
- parm->hc_max_frame_size = 0x3FF;
- xfer->flags_int.bdma_enable = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nsitd = xfer->nframes;
-
- } else if (parm->methods == &ehci_device_isoc_hs_methods) {
-
- parm->hc_max_packet_size = 0x400;
- parm->hc_max_packet_count = 3;
- parm->hc_max_frame_size = 0xC00;
- xfer->flags_int.bdma_enable = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nitd = (xfer->nframes + 7) / 8;
-
- } else {
-
- parm->hc_max_packet_size = 0x400;
- parm->hc_max_packet_count = 1;
- parm->hc_max_frame_size = 0x400;
-
- usb2_transfer_setup_sub(parm);
- }
-
-alloc_dma_set:
-
- if (parm->err) {
- return;
- }
- /*
- * Allocate queue heads and transfer descriptors
- */
- last_obj = NULL;
-
- if (usb2_transfer_setup_sub_malloc(
- parm, &pc, sizeof(ehci_itd_t),
- EHCI_ITD_ALIGN, nitd)) {
- parm->err = USB_ERR_NOMEM;
- return;
- }
- if (parm->buf) {
- for (n = 0; n != nitd; n++) {
- ehci_itd_t *td;
-
- usb2_get_page(pc + n, 0, &page_info);
-
- td = page_info.buffer;
-
- /* init TD */
- td->itd_self = htoehci32(sc, page_info.physaddr | EHCI_LINK_ITD);
- td->obj_next = last_obj;
- td->page_cache = pc + n;
-
- last_obj = td;
-
- usb2_pc_cpu_flush(pc + n);
- }
- }
- if (usb2_transfer_setup_sub_malloc(
- parm, &pc, sizeof(ehci_sitd_t),
- EHCI_SITD_ALIGN, nsitd)) {
- parm->err = USB_ERR_NOMEM;
- return;
- }
- if (parm->buf) {
- for (n = 0; n != nsitd; n++) {
- ehci_sitd_t *td;
-
- usb2_get_page(pc + n, 0, &page_info);
-
- td = page_info.buffer;
-
- /* init TD */
- td->sitd_self = htoehci32(sc, page_info.physaddr | EHCI_LINK_SITD);
- td->obj_next = last_obj;
- td->page_cache = pc + n;
-
- last_obj = td;
-
- usb2_pc_cpu_flush(pc + n);
- }
- }
- if (usb2_transfer_setup_sub_malloc(
- parm, &pc, sizeof(ehci_qtd_t),
- EHCI_QTD_ALIGN, nqtd)) {
- parm->err = USB_ERR_NOMEM;
- return;
- }
- if (parm->buf) {
- for (n = 0; n != nqtd; n++) {
- ehci_qtd_t *qtd;
-
- usb2_get_page(pc + n, 0, &page_info);
-
- qtd = page_info.buffer;
-
- /* init TD */
- qtd->qtd_self = htoehci32(sc, page_info.physaddr);
- qtd->obj_next = last_obj;
- qtd->page_cache = pc + n;
-
- last_obj = qtd;
-
- usb2_pc_cpu_flush(pc + n);
- }
- }
- xfer->td_start[xfer->flags_int.curr_dma_set] = last_obj;
-
- last_obj = NULL;
-
- if (usb2_transfer_setup_sub_malloc(
- parm, &pc, sizeof(ehci_qh_t),
- EHCI_QH_ALIGN, nqh)) {
- parm->err = USB_ERR_NOMEM;
- return;
- }
- if (parm->buf) {
- for (n = 0; n != nqh; n++) {
- ehci_qh_t *qh;
-
- usb2_get_page(pc + n, 0, &page_info);
-
- qh = page_info.buffer;
-
- /* init QH */
- qh->qh_self = htoehci32(sc, page_info.physaddr | EHCI_LINK_QH);
- qh->obj_next = last_obj;
- qh->page_cache = pc + n;
-
- last_obj = qh;
-
- usb2_pc_cpu_flush(pc + n);
- }
- }
- xfer->qh_start[xfer->flags_int.curr_dma_set] = last_obj;
-
- if (!xfer->flags_int.curr_dma_set) {
- xfer->flags_int.curr_dma_set = 1;
- goto alloc_dma_set;
- }
-}
-
-static void
-ehci_xfer_unsetup(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ehci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
- struct usb2_pipe *pipe)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(udev->bus);
-
- DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
- pipe, udev->address,
- edesc->bEndpointAddress, udev->flags.usb2_mode,
- sc->sc_addr);
-
- if (udev->flags.usb2_mode != USB_MODE_HOST) {
- /* not supported */
- return;
- }
- if (udev->device_index == sc->sc_addr) {
- switch (edesc->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:
- /* do nothing */
- break;
- }
- } else {
- if ((udev->speed != USB_SPEED_HIGH) &&
- ((udev->hs_hub_addr == 0) ||
- (udev->hs_port_no == 0) ||
- (udev->bus->devices[udev->hs_hub_addr] == NULL) ||
- (udev->bus->devices[udev->hs_hub_addr]->hub == NULL))) {
- /* We need a transaction translator */
- goto done;
- }
- switch (edesc->bmAttributes & UE_XFERTYPE) {
- case UE_CONTROL:
- pipe->methods = &ehci_device_ctrl_methods;
- break;
- case UE_INTERRUPT:
- pipe->methods = &ehci_device_intr_methods;
- break;
- case UE_ISOCHRONOUS:
- if (udev->speed == USB_SPEED_HIGH) {
- pipe->methods = &ehci_device_isoc_hs_methods;
- } else if (udev->speed == USB_SPEED_FULL) {
- pipe->methods = &ehci_device_isoc_fs_methods;
- }
- break;
- case UE_BULK:
- if (udev->speed != USB_SPEED_LOW) {
- pipe->methods = &ehci_device_bulk_methods;
- }
- break;
- default:
- /* do nothing */
- break;
- }
- }
-done:
- return;
-}
-
-static void
-ehci_get_dma_delay(struct usb2_bus *bus, uint32_t *pus)
-{
- /*
- * Wait until the hardware has finished any possible use of
- * the transfer descriptor(s) and QH
- */
- *pus = (188); /* microseconds */
-}
-
-static void
-ehci_device_resume(struct usb2_device *udev)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(udev->bus);
- struct usb2_xfer *xfer;
- struct usb2_pipe_methods *methods;
-
- DPRINTF("\n");
-
- USB_BUS_LOCK(udev->bus);
-
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
-
- if (xfer->xroot->udev == udev) {
-
- methods = xfer->pipe->methods;
-
- if ((methods == &ehci_device_bulk_methods) ||
- (methods == &ehci_device_ctrl_methods)) {
- EHCI_APPEND_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
- sc->sc_async_p_last);
- }
- if (methods == &ehci_device_intr_methods) {
- EHCI_APPEND_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
- sc->sc_intr_p_last[xfer->qh_pos]);
- }
- }
- }
-
- USB_BUS_UNLOCK(udev->bus);
-
- return;
-}
-
-static void
-ehci_device_suspend(struct usb2_device *udev)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(udev->bus);
- struct usb2_xfer *xfer;
- struct usb2_pipe_methods *methods;
-
- DPRINTF("\n");
-
- USB_BUS_LOCK(udev->bus);
-
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
-
- if (xfer->xroot->udev == udev) {
-
- methods = xfer->pipe->methods;
-
- if ((methods == &ehci_device_bulk_methods) ||
- (methods == &ehci_device_ctrl_methods)) {
- EHCI_REMOVE_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
- sc->sc_async_p_last);
- }
- if (methods == &ehci_device_intr_methods) {
- EHCI_REMOVE_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
- sc->sc_intr_p_last[xfer->qh_pos]);
- }
- }
- }
-
- USB_BUS_UNLOCK(udev->bus);
-
- return;
-}
-
-static void
-ehci_set_hw_power(struct usb2_bus *bus)
-{
- ehci_softc_t *sc = EHCI_BUS2SC(bus);
- uint32_t temp;
- uint32_t flags;
-
- DPRINTF("\n");
-
- USB_BUS_LOCK(bus);
-
- flags = bus->hw_power_state;
-
- temp = EOREAD4(sc, EHCI_USBCMD);
-
- temp &= ~(EHCI_CMD_ASE | EHCI_CMD_PSE);
-
- if (flags & (USB_HW_POWER_CONTROL |
- USB_HW_POWER_BULK)) {
- DPRINTF("Async is active\n");
- temp |= EHCI_CMD_ASE;
- }
- if (flags & (USB_HW_POWER_INTERRUPT |
- USB_HW_POWER_ISOC)) {
- DPRINTF("Periodic is active\n");
- temp |= EHCI_CMD_PSE;
- }
- EOWRITE4(sc, EHCI_USBCMD, temp);
-
- USB_BUS_UNLOCK(bus);
-
- return;
-}
-
-struct usb2_bus_methods ehci_bus_methods =
-{
- .pipe_init = ehci_pipe_init,
- .xfer_setup = ehci_xfer_setup,
- .xfer_unsetup = ehci_xfer_unsetup,
- .do_poll = ehci_do_poll,
- .get_dma_delay = ehci_get_dma_delay,
- .device_resume = ehci_device_resume,
- .device_suspend = ehci_device_suspend,
- .set_hw_power = ehci_set_hw_power,
- .roothub_exec = ehci_root_ctrl_task,
-};
diff --git a/sys/dev/usb2/controller/ehci2.h b/sys/dev/usb2/controller/ehci2.h
deleted file mode 100644
index 9d7baa1..0000000
--- a/sys/dev/usb2/controller/ehci2.h
+++ /dev/null
@@ -1,532 +0,0 @@
-/* $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.
- */
-
-#ifndef _EHCI_H_
-#define _EHCI_H_
-
-#define EHCI_MAX_DEVICES USB_MAX_DEVICES
-
-/* 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_USB_REV_MASK 0xff
-#define PCI_USB_REV_PRE_1_0 0x00
-#define PCI_USB_REV_1_0 0x10
-#define PCI_USB_REV_1_1 0x11
-#define PCI_USB_REV_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_BIOS_SEM 0x02
-#define EHCI_LEGSUP_OS_SEM 0x03
-#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)
-
-/*
- * NOTE: the doorbell interrupt is enabled, but the doorbell is never
- * used! SiS chipsets require this.
- */
-#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 */
-
-/*
- * Alignment NOTE: structures must be aligned so that the hardware can index
- * without performing addition.
- */
-#define EHCI_FRAMELIST_ALIGN 0x1000 /* bytes */
-#define EHCI_FRAMELIST_COUNT 1024 /* units */
-#define EHCI_VIRTUAL_FRAMELIST_COUNT 128 /* units */
-
-#if ((8*EHCI_VIRTUAL_FRAMELIST_COUNT) < USB_MAX_HS_ISOC_FRAMES_PER_XFER)
-#error "maximum number of high-speed isochronous frames is higher than supported!"
-#endif
-
-#if (EHCI_VIRTUAL_FRAMELIST_COUNT < USB_MAX_FS_ISOC_FRAMES_PER_XFER)
-#error "maximum number of full-speed isochronous frames is higher than supported!"
-#endif
-
-/* Link types */
-#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)
-
-/* Structures alignment (bytes) */
-#define EHCI_ITD_ALIGN 128
-#define EHCI_SITD_ALIGN 64
-#define EHCI_QTD_ALIGN 64
-#define EHCI_QH_ALIGN 128
-#define EHCI_FSTN_ALIGN 32
-/* Data buffers are divided into one or more pages */
-#define EHCI_PAGE_SIZE 0x1000
-#if ((USB_PAGE_SIZE < EHCI_PAGE_SIZE) || (EHCI_PAGE_SIZE == 0) || \
- (USB_PAGE_SIZE < EHCI_ITD_ALIGN) || (EHCI_ITD_ALIGN == 0) || \
- (USB_PAGE_SIZE < EHCI_SITD_ALIGN) || (EHCI_SITD_ALIGN == 0) || \
- (USB_PAGE_SIZE < EHCI_QTD_ALIGN) || (EHCI_QTD_ALIGN == 0) || \
- (USB_PAGE_SIZE < EHCI_QH_ALIGN) || (EHCI_QH_ALIGN == 0) || \
- (USB_PAGE_SIZE < EHCI_FSTN_ALIGN) || (EHCI_FSTN_ALIGN == 0))
-#error "Invalid USB page size!"
-#endif
-
-
-/*
- * Isochronous Transfer Descriptor. This descriptor is used for high speed
- * transfers only.
- */
-struct ehci_itd {
- volatile uint32_t itd_next;
- volatile uint32_t itd_status[8];
-#define EHCI_ITD_SET_LEN(x) ((x) << 16)
-#define EHCI_ITD_GET_LEN(x) (((x) >> 16) & 0xFFF)
-#define EHCI_ITD_IOC (1 << 15)
-#define EHCI_ITD_SET_PG(x) ((x) << 12)
-#define EHCI_ITD_GET_PG(x) (((x) >> 12) & 0x7)
-#define EHCI_ITD_SET_OFFS(x) (x)
-#define EHCI_ITD_GET_OFFS(x) (((x) >> 0) & 0xFFF)
-#define EHCI_ITD_ACTIVE (1 << 31)
-#define EHCI_ITD_DATABUFERR (1 << 30)
-#define EHCI_ITD_BABBLE (1 << 29)
-#define EHCI_ITD_XACTERR (1 << 28)
- volatile uint32_t itd_bp[7];
- /* itd_bp[0] */
-#define EHCI_ITD_SET_ADDR(x) (x)
-#define EHCI_ITD_GET_ADDR(x) (((x) >> 0) & 0x7F)
-#define EHCI_ITD_SET_ENDPT(x) ((x) << 8)
-#define EHCI_ITD_GET_ENDPT(x) (((x) >> 8) & 0xF)
- /* itd_bp[1] */
-#define EHCI_ITD_SET_DIR_IN (1 << 11)
-#define EHCI_ITD_SET_DIR_OUT (0 << 11)
-#define EHCI_ITD_SET_MPL(x) (x)
-#define EHCI_ITD_GET_MPL(x) (((x) >> 0) & 0x7FF)
- volatile uint32_t itd_bp_hi[7];
-/*
- * Extra information needed:
- */
- uint32_t itd_self;
- struct ehci_itd *next;
- struct ehci_itd *prev;
- struct ehci_itd *obj_next;
- struct usb2_page_cache *page_cache;
-} __aligned(EHCI_ITD_ALIGN);
-
-typedef struct ehci_itd ehci_itd_t;
-
-/*
- * Split Transaction Isochronous Transfer Descriptor. This descriptor is used
- * for full speed transfers only.
- */
-struct ehci_sitd {
- volatile uint32_t sitd_next;
- volatile uint32_t sitd_portaddr;
-#define EHCI_SITD_SET_DIR_OUT (0 << 31)
-#define EHCI_SITD_SET_DIR_IN (1 << 31)
-#define EHCI_SITD_SET_ADDR(x) (x)
-#define EHCI_SITD_GET_ADDR(x) ((x) & 0x7F)
-#define EHCI_SITD_SET_ENDPT(x) ((x) << 8)
-#define EHCI_SITD_GET_ENDPT(x) (((x) >> 8) & 0xF)
-#define EHCI_SITD_GET_DIR(x) ((x) >> 31)
-#define EHCI_SITD_SET_PORT(x) ((x) << 24)
-#define EHCI_SITD_GET_PORT(x) (((x) >> 24) & 0x7F)
-#define EHCI_SITD_SET_HUBA(x) ((x) << 16)
-#define EHCI_SITD_GET_HUBA(x) (((x) >> 16) & 0x7F)
- volatile uint32_t sitd_mask;
-#define EHCI_SITD_SET_SMASK(x) (x)
-#define EHCI_SITD_SET_CMASK(x) ((x) << 8)
- volatile uint32_t sitd_status;
-#define EHCI_SITD_COMPLETE_SPLIT (1<<1)
-#define EHCI_SITD_START_SPLIT (0<<1)
-#define EHCI_SITD_MISSED_MICRO_FRAME (1<<2)
-#define EHCI_SITD_XACTERR (1<<3)
-#define EHCI_SITD_BABBLE (1<<4)
-#define EHCI_SITD_DATABUFERR (1<<5)
-#define EHCI_SITD_ERROR (1<<6)
-#define EHCI_SITD_ACTIVE (1<<7)
-#define EHCI_SITD_IOC (1<<31)
-#define EHCI_SITD_SET_LEN(len) ((len)<<16)
-#define EHCI_SITD_GET_LEN(x) (((x)>>16) & 0x3FF)
- volatile uint32_t sitd_bp[2];
- volatile uint32_t sitd_back;
- volatile uint32_t sitd_bp_hi[2];
-/*
- * Extra information needed:
- */
- uint32_t sitd_self;
- struct ehci_sitd *next;
- struct ehci_sitd *prev;
- struct ehci_sitd *obj_next;
- struct usb2_page_cache *page_cache;
-} __aligned(EHCI_SITD_ALIGN);
-
-typedef struct ehci_sitd ehci_sitd_t;
-
-/* Queue Element Transfer Descriptor */
-struct ehci_qtd {
- volatile uint32_t qtd_next;
- volatile uint32_t qtd_altnext;
- volatile uint32_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 0x74
-#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
-#define EHCI_QTD_NBUFFERS 5
-#define EHCI_QTD_PAYLOAD_MAX ((EHCI_QTD_NBUFFERS-1)*EHCI_PAGE_SIZE)
- volatile uint32_t qtd_buffer[EHCI_QTD_NBUFFERS];
- volatile uint32_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
-/*
- * Extra information needed:
- */
- struct ehci_qtd *alt_next;
- struct ehci_qtd *obj_next;
- struct usb2_page_cache *page_cache;
- uint32_t qtd_self;
- uint16_t len;
-} __aligned(EHCI_QTD_ALIGN);
-
-typedef struct ehci_qtd ehci_qtd_t;
-
-/* Queue Head Sub Structure */
-struct ehci_qh_sub {
- volatile uint32_t qtd_next;
- volatile uint32_t qtd_altnext;
- volatile uint32_t qtd_status;
- volatile uint32_t qtd_buffer[EHCI_QTD_NBUFFERS];
- volatile uint32_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
-} __aligned(4);
-
-/* Queue Head */
-struct ehci_qh {
- volatile uint32_t qh_link;
- volatile uint32_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)
- volatile uint32_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)
- volatile uint32_t qh_curqtd;
- struct ehci_qh_sub qh_qtd;
-/*
- * Extra information needed:
- */
- struct ehci_qh *next;
- struct ehci_qh *prev;
- struct ehci_qh *obj_next;
- struct usb2_page_cache *page_cache;
- uint32_t qh_self;
-} __aligned(EHCI_QH_ALIGN);
-
-typedef struct ehci_qh ehci_qh_t;
-
-/* Periodic Frame Span Traversal Node */
-struct ehci_fstn {
- volatile uint32_t fstn_link;
- volatile uint32_t fstn_back;
-} __aligned(EHCI_FSTN_ALIGN);
-
-typedef struct ehci_fstn ehci_fstn_t;
-
-struct ehci_hw_softc {
- struct usb2_page_cache pframes_pc;
- struct usb2_page_cache async_start_pc;
- struct usb2_page_cache intr_start_pc[EHCI_VIRTUAL_FRAMELIST_COUNT];
- struct usb2_page_cache isoc_hs_start_pc[EHCI_VIRTUAL_FRAMELIST_COUNT];
- struct usb2_page_cache isoc_fs_start_pc[EHCI_VIRTUAL_FRAMELIST_COUNT];
-
- struct usb2_page pframes_pg;
- struct usb2_page async_start_pg;
- struct usb2_page intr_start_pg[EHCI_VIRTUAL_FRAMELIST_COUNT];
- struct usb2_page isoc_hs_start_pg[EHCI_VIRTUAL_FRAMELIST_COUNT];
- struct usb2_page isoc_fs_start_pg[EHCI_VIRTUAL_FRAMELIST_COUNT];
-};
-
-struct ehci_config_desc {
- struct usb2_config_descriptor confd;
- struct usb2_interface_descriptor ifcd;
- struct usb2_endpoint_descriptor endpd;
-} __packed;
-
-union ehci_hub_desc {
- struct usb2_status stat;
- struct usb2_port_status ps;
- struct usb2_device_descriptor devd;
- struct usb2_device_qualifier odevd;
- struct usb2_hub_descriptor hubd;
- uint8_t temp[128];
-};
-
-typedef struct ehci_softc {
- struct ehci_hw_softc sc_hw;
- struct usb2_bus sc_bus; /* base device */
- struct usb2_callout sc_tmo_pcd;
- union ehci_hub_desc sc_hub_desc;
- struct usb2_sw_transfer sc_root_ctrl;
- struct usb2_sw_transfer sc_root_intr;
-
- struct usb2_device *sc_devices[EHCI_MAX_DEVICES];
- struct resource *sc_io_res;
- struct resource *sc_irq_res;
- struct ehci_qh *sc_async_p_last;
- struct ehci_qh *sc_intr_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT];
- struct ehci_sitd *sc_isoc_fs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT];
- struct ehci_itd *sc_isoc_hs_p_last[EHCI_VIRTUAL_FRAMELIST_COUNT];
- void *sc_intr_hdl;
- bus_size_t sc_io_size;
- bus_space_tag_t sc_io_tag;
- bus_space_handle_t sc_io_hdl;
-
- uint32_t sc_eintrs;
- uint32_t sc_cmd; /* shadow of cmd register during
- * suspend */
-
- uint16_t sc_intr_stat[EHCI_VIRTUAL_FRAMELIST_COUNT];
- uint16_t sc_id_vendor; /* vendor ID for root hub */
- uint16_t sc_flags; /* chip specific flags */
-#define EHCI_SCFLG_SETMODE 0x0001 /* set bridge mode again after init */
-#define EHCI_SCFLG_FORCESPEED 0x0002 /* force speed */
-#define EHCI_SCFLG_NORESTERM 0x0004 /* don't terminate reset sequence */
-#define EHCI_SCFLG_BIGEDESC 0x0008 /* big-endian byte order descriptors */
-#define EHCI_SCFLG_BIGEMMIO 0x0010 /* big-endian byte order MMIO */
-#define EHCI_SCFLG_TT 0x0020 /* transaction translator present */
-
- uint8_t sc_offs; /* offset to operational registers */
- uint8_t sc_doorbell_disable; /* set on doorbell failure */
- uint8_t sc_noport;
- uint8_t sc_addr; /* device address */
- uint8_t sc_conf; /* device configuration */
- uint8_t sc_isreset;
- uint8_t sc_hub_idata[8];
-
- char sc_vendor[16]; /* vendor string for root hub */
-
-} ehci_softc_t;
-
-#define EREAD1(sc, a) bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (a))
-#define EREAD2(sc, a) bus_space_read_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (a))
-#define EREAD4(sc, a) bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (a))
-#define EWRITE1(sc, a, x) \
- bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (a), (x))
-#define EWRITE2(sc, a, x) \
- bus_space_write_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (a), (x))
-#define EWRITE4(sc, a, x) \
- bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (a), (x))
-#define EOREAD1(sc, a) \
- bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a))
-#define EOREAD2(sc, a) \
- bus_space_read_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a))
-#define EOREAD4(sc, a) \
- bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a))
-#define EOWRITE1(sc, a, x) \
- bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a), (x))
-#define EOWRITE2(sc, a, x) \
- bus_space_write_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a), (x))
-#define EOWRITE4(sc, a, x) \
- bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (sc)->sc_offs+(a), (x))
-
-usb2_bus_mem_cb_t ehci_iterate_hw_softc;
-
-usb2_error_t ehci_init(ehci_softc_t *sc);
-void ehci_detach(struct ehci_softc *sc);
-void ehci_suspend(struct ehci_softc *sc);
-void ehci_resume(struct ehci_softc *sc);
-void ehci_shutdown(ehci_softc_t *sc);
-void ehci_interrupt(ehci_softc_t *sc);
-
-#endif /* _EHCI_H_ */
diff --git a/sys/dev/usb2/controller/ehci2_ixp4xx.c b/sys/dev/usb2/controller/ehci2_ixp4xx.c
deleted file mode 100644
index 91ce863..0000000
--- a/sys/dev/usb2/controller/ehci2_ixp4xx.c
+++ /dev/null
@@ -1,349 +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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/ehci2.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 device_attach_t ehci_ixp_attach;
-static device_detach_t ehci_ixp_detach;
-static device_shutdown_t ehci_ixp_shutdown;
-static device_suspend_t ehci_ixp_suspend;
-static device_resume_t ehci_ixp_resume;
-
-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 = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
- ehci_suspend(sc);
- return (0);
-}
-
-static int
-ehci_ixp_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_resume(sc);
-
- bus_generic_resume(self);
-
- return (0);
-}
-
-static int
-ehci_ixp_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);
-
- return (0);
-}
-
-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;
- int rid;
-
- /* initialise some bus fields */
- sc->sc_bus.parent = self;
- sc->sc_bus.devices = sc->sc_devices;
- sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
-
- /* get all DMA memory */
- if (usb2_bus_mem_alloc_all(&sc->sc_bus,
- USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
- return (ENOMEM);
- }
-
- sc->sc_bus.usbrev = USB_REV_2_0;
-
- /* NB: hints fix the memory location and irq */
-
- rid = 0;
- sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!sc->sc_io_res) {
- device_printf(self, "Could not map memory\n");
- goto error;
- }
-
- /*
- * 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->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->sc_io_tag = &isc->tag;
- sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
- sc->sc_io_size = IXP435_USB1_SIZE - 0x100;
-
- rid = 0;
- sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_ACTIVE);
- if (sc->sc_irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- goto error;
- }
- sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- goto error;
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
- device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);
-
- sprintf(sc->sc_vendor, "Intel");
-
-
- err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (void *)(void *)ehci_interrupt, sc, &sc->sc_intr_hdl);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->sc_intr_hdl = NULL;
- goto error;
- }
-
- /*
- * 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
- ;
-
- err = ehci_init(sc);
- if (!err) {
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
- if (err) {
- device_printf(self, "USB init failed err=%d\n", err);
- goto error;
- }
- return (0);
-
-error:
- ehci_ixp_detach(self);
- return (ENXIO);
-}
-
-static int
-ehci_ixp_detach(device_t self)
-{
- struct ixp_ehci_softc *isc = device_get_softc(self);
- ehci_softc_t *sc = &isc->base;
- device_t bdev;
- int err;
-
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
- /* during module unload there are lots of children leftover */
- device_delete_all_children(self);
-
- /*
- * disable interrupts that might have been switched on in ehci_init
- */
- if (sc->sc_io_res) {
- EWRITE4(sc, EHCI_USBINTR, 0);
- }
-
- if (sc->sc_irq_res && sc->sc_intr_hdl) {
- /*
- * only call ehci_detach() after ehci_init()
- */
- ehci_detach(sc);
-
- err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
-
- if (err)
- /* XXX or should we panic? */
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->sc_intr_hdl = NULL;
- }
-
- if (sc->sc_irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res);
- sc->sc_irq_res = NULL;
- }
- if (sc->sc_io_res) {
- bus_release_resource(self, SYS_RES_MEMORY, 0,
- sc->sc_io_res);
- sc->sc_io_res = NULL;
- }
- usb2_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
-
- 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);
-MODULE_DEPEND(ehci, usb2_controller, 1, 1, 1);
-MODULE_DEPEND(ehci, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/controller/ehci2_mbus.c b/sys/dev/usb2/controller/ehci2_mbus.c
deleted file mode 100644
index 404617b..0000000
--- a/sys/dev/usb2/controller/ehci2_mbus.c
+++ /dev/null
@@ -1,365 +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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/ehci2.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);
-
-static struct resource *irq_err;
-static 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 = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
- ehci_suspend(sc);
- return (0);
-}
-
-static int
-ehci_mbus_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_resume(sc);
-
- bus_generic_resume(self);
-
- return (0);
-}
-
-static int
-ehci_mbus_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);
-
- 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 = device_get_softc(self);
- bus_space_handle_t bsh;
- int err;
- int rid;
-
- /* initialise some bus fields */
- sc->sc_bus.parent = self;
- sc->sc_bus.devices = sc->sc_devices;
- sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
-
- /* get all DMA memory */
- if (usb2_bus_mem_alloc_all(&sc->sc_bus,
- USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
- return (ENOMEM);
- }
-
- sc->sc_bus.usbrev = USB_REV_2_0;
-
- rid = 0;
- sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!sc->sc_io_res) {
- device_printf(self, "Could not map memory\n");
- goto error;
- }
- sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
- bsh = rman_get_bushandle(sc->sc_io_res);
- sc->sc_io_size = MV_USB_SIZE - MV_USB_HOST_OFST;
-
- /*
- * 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->sc_io_tag, bsh, MV_USB_HOST_OFST,
- sc->sc_io_size, &sc->sc_io_hdl) != 0)
- panic("%s: unable to subregion USB host registers",
- device_get_name(self));
-
- 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->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->sc_irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- goto error;
- }
-
- sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- goto error;
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
- device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);
-
- sprintf(sc->sc_vendor, "Marvell");
-
- 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;
- goto error;
- }
-
- 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->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (void *)(void *)ehci_interrupt, sc, &sc->sc_intr_hdl);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->sc_intr_hdl = NULL;
- goto error;
- }
-
- /*
- * 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) {
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
- if (err) {
- device_printf(self, "USB init failed err=%d\n", err);
- goto error;
- }
- return (0);
-
-error:
- ehci_mbus_detach(self);
- return (ENXIO);
-}
-
-static int
-ehci_mbus_detach(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- device_t bdev;
- int err;
-
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
- /* during module unload there are lots of children leftover */
- device_delete_all_children(self);
-
- /*
- * disable interrupts that might have been switched on in ehci_init
- */
- if (sc->sc_io_res) {
- EWRITE4(sc, EHCI_USBINTR, 0);
- EWRITE4(sc, USB_BRIDGE_INTR_MASK, 0);
- }
- if (sc->sc_irq_res && sc->sc_intr_hdl) {
- /*
- * only call ehci_detach() after ehci_init()
- */
- ehci_detach(sc);
-
- err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
-
- if (err)
- /* XXX or should we panic? */
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->sc_intr_hdl = NULL;
- }
- 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 (irq_err) {
- bus_release_resource(self, SYS_RES_IRQ, 0, irq_err);
- irq_err = NULL;
- }
- if (sc->sc_irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 1, sc->sc_irq_res);
- sc->sc_irq_res = NULL;
- }
- if (sc->sc_io_res) {
- bus_release_resource(self, SYS_RES_MEMORY, 0,
- sc->sc_io_res);
- sc->sc_io_res = NULL;
- }
- usb2_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
-
- 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);
-MODULE_DEPEND(ehci, usb2_controller, 1, 1, 1);
-MODULE_DEPEND(ehci, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/controller/ehci2_pci.c b/sys/dev/usb2/controller/ehci2_pci.c
deleted file mode 100644
index 5e39c8f..0000000
--- a/sys/dev/usb2/controller/ehci2_pci.c
+++ /dev/null
@@ -1,487 +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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/usb2_pci.h>
-#include <dev/usb2/controller/ehci2.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
-
-#define PCI_EHCI_BASE_REG 0x10
-
-static void ehci_pci_takecontroller(device_t self);
-
-static device_probe_t ehci_pci_probe;
-static device_attach_t ehci_pci_attach;
-static device_detach_t ehci_pci_detach;
-static device_suspend_t ehci_pci_suspend;
-static device_resume_t ehci_pci_resume;
-static device_shutdown_t ehci_pci_shutdown;
-
-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_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_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);
-
- return (0);
-}
-
-static const char *
-ehci_pci_match(device_t self)
-{
- uint32_t device_id = pci_get_devid(self);
-
- switch (device_id) {
- case 0x268c8086:
- return ("Intel 63XXESB USB 2.0 controller");
-
- case 0x523910b9:
- return "ALi M5239 USB 2.0 controller";
-
- case 0x10227463:
- return "AMD 8111 USB 2.0 controller";
-
- case 0x20951022:
- return ("AMD CS5536 (Geode) USB 2.0 controller");
-
- case 0x43451002:
- return "ATI SB200 USB 2.0 controller";
- case 0x43731002:
- return "ATI SB400 USB 2.0 controller";
-
- case 0x25ad8086:
- return "Intel 6300ESB USB 2.0 controller";
- case 0x24cd8086:
- return "Intel 82801DB/L/M (ICH4) USB 2.0 controller";
- case 0x24dd8086:
- return "Intel 82801EB/R (ICH5) USB 2.0 controller";
- case 0x265c8086:
- return "Intel 82801FB (ICH6) USB 2.0 controller";
- case 0x27cc8086:
- return "Intel 82801GB/R (ICH7) USB 2.0 controller";
-
- case 0x28368086:
- return "Intel 82801H (ICH8) USB 2.0 controller USB2-A";
- case 0x283a8086:
- return "Intel 82801H (ICH8) USB 2.0 controller USB2-B";
- case 0x293a8086:
- return "Intel 82801I (ICH9) USB 2.0 controller";
- case 0x293c8086:
- return "Intel 82801I (ICH9) USB 2.0 controller";
-
- case 0x00e01033:
- return ("NEC uPD 720100 USB 2.0 controller");
-
- case 0x006810de:
- return "NVIDIA nForce2 USB 2.0 controller";
- case 0x008810de:
- return "NVIDIA nForce2 Ultra 400 USB 2.0 controller";
- case 0x00d810de:
- return "NVIDIA nForce3 USB 2.0 controller";
- case 0x00e810de:
- return "NVIDIA nForce3 250 USB 2.0 controller";
- case 0x005b10de:
- return "NVIDIA nForce4 USB 2.0 controller";
-
- case 0x15621131:
- return "Philips ISP156x USB 2.0 controller";
-
- case 0x31041106:
- return ("VIA VT6202 USB 2.0 controller");
-
- default:
- break;
- }
-
- if ((pci_get_class(self) == PCIC_SERIALBUS)
- && (pci_get_subclass(self) == PCIS_SERIALBUS_USB)
- && (pci_get_progif(self) == PCI_INTERFACE_EHCI)) {
- return ("EHCI (generic) USB 2.0 controller");
- }
- 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 (0);
- } else {
- return (ENXIO);
- }
-}
-
-static int
-ehci_pci_attach(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
- int rid;
-
- /* initialise some bus fields */
- sc->sc_bus.parent = self;
- sc->sc_bus.devices = sc->sc_devices;
- sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
-
- /* get all DMA memory */
- if (usb2_bus_mem_alloc_all(&sc->sc_bus,
- USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
- return (ENOMEM);
- }
-
- pci_enable_busmaster(self);
-
- switch (pci_read_config(self, PCI_USBREV, 1) & PCI_USB_REV_MASK) {
- case PCI_USB_REV_PRE_1_0:
- case PCI_USB_REV_1_0:
- case PCI_USB_REV_1_1:
- /*
- * NOTE: some EHCI USB controllers have the wrong USB
- * revision number. It appears those controllers are
- * fully compliant so we just ignore this value in
- * some common cases.
- */
- device_printf(self, "pre-2.0 USB revision (ignored)\n");
- /* fallthrough */
- case PCI_USB_REV_2_0:
- sc->sc_bus.usbrev = USB_REV_2_0;
- break;
- default:
- /* Quirk for Parallels Desktop 4.0 */
- device_printf(self, "USB revision is unknown. Assuming v2.0.\n");
- sc->sc_bus.usbrev = USB_REV_2_0;
- break;
- }
-
- rid = PCI_CBMEM;
- sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
- if (!sc->sc_io_res) {
- device_printf(self, "Could not map memory\n");
- goto error;
- }
- sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
- sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
- sc->sc_io_size = rman_get_size(sc->sc_io_res);
-
- rid = 0;
- sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->sc_irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- goto error;
- }
- sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- goto error;
- }
- 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_PHILIPS:
- sprintf(sc->sc_vendor, "Philips");
- 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));
- }
-
-#if (__FreeBSD_version >= 700031)
- err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (void *)(void *)ehci_interrupt, sc, &sc->sc_intr_hdl);
-#else
- err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- (void *)(void *)ehci_interrupt, sc, &sc->sc_intr_hdl);
-#endif
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->sc_intr_hdl = NULL;
- goto error;
- }
- ehci_pci_takecontroller(self);
- err = ehci_init(sc);
- if (!err) {
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
- if (err) {
- device_printf(self, "USB init failed err=%d\n", err);
- goto error;
- }
- return (0);
-
-error:
- ehci_pci_detach(self);
- return (ENXIO);
-}
-
-static int
-ehci_pci_detach(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- device_t bdev;
-
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
- /* during module unload there are lots of children leftover */
- device_delete_all_children(self);
-
- pci_disable_busmaster(self);
-
- /*
- * disable interrupts that might have been switched on in ehci_init
- */
- if (sc->sc_io_res) {
- EWRITE4(sc, EHCI_USBINTR, 0);
- }
- if (sc->sc_irq_res && sc->sc_intr_hdl) {
- /*
- * only call ehci_detach() after ehci_init()
- */
- ehci_detach(sc);
-
- int err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
-
- if (err)
- /* XXX or should we panic? */
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->sc_intr_hdl = NULL;
- }
- if (sc->sc_irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res);
- sc->sc_irq_res = NULL;
- }
- if (sc->sc_io_res) {
- bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM,
- sc->sc_io_res);
- sc->sc_io_res = NULL;
- }
- usb2_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
-
- return (0);
-}
-
-static void
-ehci_pci_takecontroller(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- uint32_t cparams;
- uint32_t eec;
- uint16_t to;
- uint8_t eecp;
- uint8_t bios_sem;
-
- 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 == 0) {
- continue;
- }
- device_printf(sc->sc_bus.bdev, "waiting for BIOS "
- "to give up control\n");
- pci_write_config(self, eecp +
- EHCI_LEGSUP_OS_SEM, 1, 1);
- to = 500;
- while (1) {
- bios_sem = pci_read_config(self, eecp +
- EHCI_LEGSUP_BIOS_SEM, 1);
- if (bios_sem == 0)
- break;
-
- if (--to == 0) {
- device_printf(sc->sc_bus.bdev,
- "timed out waiting for BIOS\n");
- break;
- }
- usb2_pause_mtx(NULL, hz / 100); /* wait 10ms */
- }
- }
-}
-
-static driver_t ehci_driver =
-{
- .name = "ehci",
- .methods = (device_method_t[]){
- /* 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}
- },
- .size = sizeof(struct ehci_softc),
-};
-
-static devclass_t ehci_devclass;
-
-DRIVER_MODULE(ehci, pci, ehci_driver, ehci_devclass, 0, 0);
-DRIVER_MODULE(ehci, cardbus, ehci_driver, ehci_devclass, 0, 0);
-MODULE_DEPEND(ehci, usb2_controller, 1, 1, 1);
-MODULE_DEPEND(ehci, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/controller/musb2_otg.c b/sys/dev/usb2/controller/musb2_otg.c
deleted file mode 100644
index fd6b6d3..0000000
--- a/sys/dev/usb2/controller/musb2_otg.c
+++ /dev/null
@@ -1,2875 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-/*
- * Thanks to Mentor Graphics for providing a reference driver for this
- * USB chip at their homepage.
- */
-
-/*
- * This file contains the driver for the Mentor Graphics Inventra USB
- * 2.0 High Speed Dual-Role controller.
- *
- * NOTE: The current implementation only supports Device Side Mode!
- */
-
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR musbotgdebug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_hub.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/musb2_otg.h>
-
-#define MUSBOTG_INTR_ENDPT 1
-
-#define MUSBOTG_BUS2SC(bus) \
- ((struct musbotg_softc *)(((uint8_t *)(bus)) - \
- USB_P2U(&(((struct musbotg_softc *)0)->sc_bus))))
-
-#define MUSBOTG_PC2SC(pc) \
- MUSBOTG_BUS2SC((pc)->tag_parent->info->bus)
-
-#if USB_DEBUG
-static int musbotgdebug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, musbotg, CTLFLAG_RW, 0, "USB musbotg");
-SYSCTL_INT(_hw_usb2_musbotg, OID_AUTO, debug, CTLFLAG_RW,
- &musbotgdebug, 0, "Debug level");
-#endif
-
-/* prototypes */
-
-struct usb2_bus_methods musbotg_bus_methods;
-struct usb2_pipe_methods musbotg_device_bulk_methods;
-struct usb2_pipe_methods musbotg_device_ctrl_methods;
-struct usb2_pipe_methods musbotg_device_intr_methods;
-struct usb2_pipe_methods musbotg_device_isoc_methods;
-struct usb2_pipe_methods musbotg_root_ctrl_methods;
-struct usb2_pipe_methods musbotg_root_intr_methods;
-
-static musbotg_cmd_t musbotg_setup_rx;
-static musbotg_cmd_t musbotg_setup_data_rx;
-static musbotg_cmd_t musbotg_setup_data_tx;
-static musbotg_cmd_t musbotg_setup_status;
-static musbotg_cmd_t musbotg_data_rx;
-static musbotg_cmd_t musbotg_data_tx;
-static void musbotg_device_done(struct usb2_xfer *, usb2_error_t);
-static void musbotg_do_poll(struct usb2_bus *);
-static void musbotg_root_ctrl_poll(struct musbotg_softc *);
-static void musbotg_standard_done(struct usb2_xfer *);
-static void musbotg_interrupt_poll(struct musbotg_softc *);
-
-static usb2_sw_transfer_func_t musbotg_root_intr_done;
-static usb2_sw_transfer_func_t musbotg_root_ctrl_done;
-
-/*
- * Here is a configuration that the chip supports.
- */
-static const struct usb2_hw_ep_profile musbotg_ep_profile[1] = {
-
- [0] = {
- .max_in_frame_size = 64,/* fixed */
- .max_out_frame_size = 64, /* fixed */
- .is_simplex = 1,
- .support_control = 1,
- }
-};
-
-static void
-musbotg_get_hw_ep_profile(struct usb2_device *udev,
- const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr)
-{
- struct musbotg_softc *sc;
-
- sc = MUSBOTG_BUS2SC(udev->bus);
-
- if (ep_addr == 0) {
- /* control endpoint */
- *ppf = musbotg_ep_profile;
- } else if (ep_addr <= sc->sc_ep_max) {
- /* other endpoints */
- *ppf = sc->sc_hw_ep_profile + ep_addr;
- } else {
- *ppf = NULL;
- }
-}
-
-static void
-musbotg_clocks_on(struct musbotg_softc *sc)
-{
- if (sc->sc_flags.clocks_off &&
- sc->sc_flags.port_powered) {
-
- DPRINTFN(4, "\n");
-
- if (sc->sc_clocks_on) {
- (sc->sc_clocks_on) (sc->sc_clocks_arg);
- }
- sc->sc_flags.clocks_off = 0;
-
- /* XXX enable Transceiver */
- }
-}
-
-static void
-musbotg_clocks_off(struct musbotg_softc *sc)
-{
- if (!sc->sc_flags.clocks_off) {
-
- DPRINTFN(4, "\n");
-
- /* XXX disable Transceiver */
-
- if (sc->sc_clocks_off) {
- (sc->sc_clocks_off) (sc->sc_clocks_arg);
- }
- sc->sc_flags.clocks_off = 1;
- }
-}
-
-static void
-musbotg_pull_common(struct musbotg_softc *sc, uint8_t on)
-{
- uint8_t temp;
-
- temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
- if (on)
- temp |= MUSB2_MASK_SOFTC;
- else
- temp &= ~MUSB2_MASK_SOFTC;
-
- MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
-}
-
-static void
-musbotg_pull_up(struct musbotg_softc *sc)
-{
- /* pullup D+, if possible */
-
- if (!sc->sc_flags.d_pulled_up &&
- sc->sc_flags.port_powered) {
- sc->sc_flags.d_pulled_up = 1;
- musbotg_pull_common(sc, 1);
- }
-}
-
-static void
-musbotg_pull_down(struct musbotg_softc *sc)
-{
- /* pulldown D+, if possible */
-
- if (sc->sc_flags.d_pulled_up) {
- sc->sc_flags.d_pulled_up = 0;
- musbotg_pull_common(sc, 0);
- }
-}
-
-static void
-musbotg_wakeup_peer(struct usb2_xfer *xfer)
-{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
- uint8_t temp;
- uint8_t use_polling;
-
- if (!(sc->sc_flags.status_suspend)) {
- return;
- }
- use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
-
- temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
- temp |= MUSB2_MASK_RESUME;
- MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
-
- /* wait 8 milliseconds */
- if (use_polling) {
- /* polling */
- DELAY(8000);
- } else {
- /* Wait for reset to complete. */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 125);
- }
-
- temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
- temp &= ~MUSB2_MASK_RESUME;
- MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
-}
-
-static void
-musbotg_set_address(struct musbotg_softc *sc, uint8_t addr)
-{
- DPRINTFN(4, "addr=%d\n", addr);
- addr &= 0x7F;
- MUSB2_WRITE_1(sc, MUSB2_REG_FADDR, addr);
-}
-
-static uint8_t
-musbotg_setup_rx(struct musbotg_td *td)
-{
- struct musbotg_softc *sc;
- struct usb2_device_request req;
- uint16_t count;
- uint8_t csr;
-
- /* get pointer to softc */
- sc = MUSBOTG_PC2SC(td->pc);
-
- /* select endpoint 0 */
- MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
-
- /* read out FIFO status */
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
-
- DPRINTFN(4, "csr=0x%02x\n", csr);
-
- /*
- * NOTE: If DATAEND is set we should not call the
- * callback, hence the status stage is not complete.
- */
- if (csr & MUSB2_MASK_CSR0L_DATAEND) {
- /* wait for interrupt */
- goto not_complete;
- }
- if (csr & MUSB2_MASK_CSR0L_SENTSTALL) {
- /* clear SENTSTALL */
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
- /* get latest status */
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
- /* update EP0 state */
- sc->sc_ep0_busy = 0;
- }
- if (csr & MUSB2_MASK_CSR0L_SETUPEND) {
- /* clear SETUPEND */
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
- MUSB2_MASK_CSR0L_SETUPEND_CLR);
- /* get latest status */
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
- /* update EP0 state */
- sc->sc_ep0_busy = 0;
- }
- if (sc->sc_ep0_busy) {
- /* abort any ongoing transfer */
- if (!td->did_stall) {
- DPRINTFN(4, "stalling\n");
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
- MUSB2_MASK_CSR0L_SENDSTALL);
- td->did_stall = 1;
- }
- goto not_complete;
- }
- if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
- goto not_complete;
- }
- /* get the packet byte count */
- count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
-
- /* verify data length */
- if (count != td->remainder) {
- DPRINTFN(0, "Invalid SETUP packet "
- "length, %d bytes\n", count);
- goto not_complete;
- }
- if (count != sizeof(req)) {
- DPRINTFN(0, "Unsupported SETUP packet "
- "length, %d bytes\n", count);
- goto not_complete;
- }
- /* receive data */
- bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(0), (void *)&req, sizeof(req));
-
- /* copy data into real buffer */
- usb2_copy_in(td->pc, 0, &req, sizeof(req));
-
- td->offset = sizeof(req);
- td->remainder = 0;
-
- /* set pending command */
- sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
-
- /* we need set stall or dataend after this */
- sc->sc_ep0_busy = 1;
-
- /* sneak peek the set address */
- if ((req.bmRequestType == UT_WRITE_DEVICE) &&
- (req.bRequest == UR_SET_ADDRESS)) {
- sc->sc_dv_addr = req.wValue[0] & 0x7F;
- } else {
- sc->sc_dv_addr = 0xFF;
- }
- return (0); /* complete */
-
-not_complete:
- return (1); /* not complete */
-}
-
-/* Control endpoint only data handling functions (RX/TX/SYNC) */
-
-static uint8_t
-musbotg_setup_data_rx(struct musbotg_td *td)
-{
- struct usb2_page_search buf_res;
- struct musbotg_softc *sc;
- uint16_t count;
- uint8_t csr;
- uint8_t got_short;
-
- /* get pointer to softc */
- sc = MUSBOTG_PC2SC(td->pc);
-
- /* select endpoint 0 */
- MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
-
- /* check if a command is pending */
- if (sc->sc_ep0_cmd) {
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
- sc->sc_ep0_cmd = 0;
- }
- /* read out FIFO status */
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
-
- DPRINTFN(4, "csr=0x%02x\n", csr);
-
- got_short = 0;
-
- if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
- MUSB2_MASK_CSR0L_SENTSTALL)) {
- if (td->remainder == 0) {
- /*
- * We are actually complete and have
- * received the next SETUP
- */
- DPRINTFN(4, "faking complete\n");
- return (0); /* complete */
- }
- /*
- * USB Host Aborted the transfer.
- */
- td->error = 1;
- return (0); /* complete */
- }
- if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
- return (1); /* not complete */
- }
- /* get the packet byte count */
- count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
-
- /* verify the packet byte count */
- if (count != td->max_frame_size) {
- if (count < td->max_frame_size) {
- /* we have a short packet */
- td->short_pkt = 1;
- got_short = 1;
- } else {
- /* invalid USB packet */
- td->error = 1;
- return (0); /* we are complete */
- }
- }
- /* verify the packet byte count */
- if (count > td->remainder) {
- /* invalid USB packet */
- td->error = 1;
- return (0); /* we are complete */
- }
- while (count > 0) {
- uint32_t temp;
-
- usb2_get_page(td->pc, td->offset, &buf_res);
-
- /* get correct length */
- if (buf_res.length > count) {
- buf_res.length = count;
- }
- /* check for unaligned memory address */
- if (USB_P2U(buf_res.buffer) & 3) {
-
- temp = count & ~3;
-
- if (temp) {
- /* receive data 4 bytes at a time */
- bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
- temp / 4);
- }
- temp = count & 3;
- if (temp) {
- /* receive data 1 byte at a time */
- bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(0),
- (void *)(&sc->sc_bounce_buf[count / 4]), temp);
- }
- usb2_copy_in(td->pc, td->offset,
- sc->sc_bounce_buf, count);
-
- /* update offset and remainder */
- td->offset += count;
- td->remainder -= count;
- break;
- }
- /* check if we can optimise */
- if (buf_res.length >= 4) {
-
- /* receive data 4 bytes at a time */
- bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(0), buf_res.buffer,
- buf_res.length / 4);
-
- temp = buf_res.length & ~3;
-
- /* update counters */
- count -= temp;
- td->offset += temp;
- td->remainder -= temp;
- continue;
- }
- /* receive data */
- bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
-
- /* update counters */
- count -= buf_res.length;
- td->offset += buf_res.length;
- td->remainder -= buf_res.length;
- }
-
- /* check if we are complete */
- if ((td->remainder == 0) || got_short) {
- if (td->short_pkt) {
- /* we are complete */
- sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
- return (0);
- }
- /* else need to receive a zero length packet */
- }
- /* write command - need more data */
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
- MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
- return (1); /* not complete */
-}
-
-static uint8_t
-musbotg_setup_data_tx(struct musbotg_td *td)
-{
- struct usb2_page_search buf_res;
- struct musbotg_softc *sc;
- uint16_t count;
- uint8_t csr;
-
- /* get pointer to softc */
- sc = MUSBOTG_PC2SC(td->pc);
-
- /* select endpoint 0 */
- MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
-
- /* check if a command is pending */
- if (sc->sc_ep0_cmd) {
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
- sc->sc_ep0_cmd = 0;
- }
- /* read out FIFO status */
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
-
- DPRINTFN(4, "csr=0x%02x\n", csr);
-
- if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
- MUSB2_MASK_CSR0L_SENTSTALL)) {
- /*
- * The current transfer was aborted
- * by the USB Host
- */
- td->error = 1;
- return (0); /* complete */
- }
- if (csr & MUSB2_MASK_CSR0L_TXPKTRDY) {
- return (1); /* not complete */
- }
- count = td->max_frame_size;
- if (td->remainder < count) {
- /* we have a short packet */
- td->short_pkt = 1;
- count = td->remainder;
- }
- while (count > 0) {
- uint32_t temp;
-
- usb2_get_page(td->pc, td->offset, &buf_res);
-
- /* get correct length */
- if (buf_res.length > count) {
- buf_res.length = count;
- }
- /* check for unaligned memory address */
- if (USB_P2U(buf_res.buffer) & 3) {
-
- usb2_copy_out(td->pc, td->offset,
- sc->sc_bounce_buf, count);
-
- temp = count & ~3;
-
- if (temp) {
- /* transmit data 4 bytes at a time */
- bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
- temp / 4);
- }
- temp = count & 3;
- if (temp) {
- /* receive data 1 byte at a time */
- bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(0),
- ((void *)&sc->sc_bounce_buf[count / 4]), temp);
- }
- /* update offset and remainder */
- td->offset += count;
- td->remainder -= count;
- break;
- }
- /* check if we can optimise */
- if (buf_res.length >= 4) {
-
- /* transmit data 4 bytes at a time */
- bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(0), buf_res.buffer,
- buf_res.length / 4);
-
- temp = buf_res.length & ~3;
-
- /* update counters */
- count -= temp;
- td->offset += temp;
- td->remainder -= temp;
- continue;
- }
- /* transmit data */
- bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
-
- /* update counters */
- count -= buf_res.length;
- td->offset += buf_res.length;
- td->remainder -= buf_res.length;
- }
-
- /* check remainder */
- if (td->remainder == 0) {
- if (td->short_pkt) {
- sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_TXPKTRDY;
- return (0); /* complete */
- }
- /* else we need to transmit a short packet */
- }
- /* write command */
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
- MUSB2_MASK_CSR0L_TXPKTRDY);
-
- return (1); /* not complete */
-}
-
-static uint8_t
-musbotg_setup_status(struct musbotg_td *td)
-{
- struct musbotg_softc *sc;
- uint8_t csr;
-
- /* get pointer to softc */
- sc = MUSBOTG_PC2SC(td->pc);
-
- /* select endpoint 0 */
- MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
-
- if (sc->sc_ep0_busy) {
- sc->sc_ep0_busy = 0;
- sc->sc_ep0_cmd |= MUSB2_MASK_CSR0L_DATAEND;
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
- sc->sc_ep0_cmd = 0;
- }
- /* read out FIFO status */
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
-
- DPRINTFN(4, "csr=0x%02x\n", csr);
-
- if (csr & MUSB2_MASK_CSR0L_DATAEND) {
- /* wait for interrupt */
- return (1); /* not complete */
- }
- if (sc->sc_dv_addr != 0xFF) {
- /* write function address */
- musbotg_set_address(sc, sc->sc_dv_addr);
- }
- return (0); /* complete */
-}
-
-static uint8_t
-musbotg_data_rx(struct musbotg_td *td)
-{
- struct usb2_page_search buf_res;
- struct musbotg_softc *sc;
- uint16_t count;
- uint8_t csr;
- uint8_t to;
- uint8_t got_short;
-
- to = 8; /* don't loop forever! */
- got_short = 0;
-
- /* get pointer to softc */
- sc = MUSBOTG_PC2SC(td->pc);
-
- /* select endpoint */
- MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
-
-repeat:
- /* read out FIFO status */
- csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
-
- DPRINTFN(4, "csr=0x%02x\n", csr);
-
- /* clear overrun */
- if (csr & MUSB2_MASK_CSRL_RXOVERRUN) {
- /* make sure we don't clear "RXPKTRDY" */
- MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
- MUSB2_MASK_CSRL_RXPKTRDY);
- }
- /* check status */
- if (!(csr & MUSB2_MASK_CSRL_RXPKTRDY)) {
- return (1); /* not complete */
- }
- /* get the packet byte count */
- count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
-
- DPRINTFN(4, "count=0x%04x\n", count);
-
- /*
- * Check for short or invalid packet:
- */
- if (count != td->max_frame_size) {
- if (count < td->max_frame_size) {
- /* we have a short packet */
- td->short_pkt = 1;
- got_short = 1;
- } else {
- /* invalid USB packet */
- td->error = 1;
- return (0); /* we are complete */
- }
- }
- /* verify the packet byte count */
- if (count > td->remainder) {
- /* invalid USB packet */
- td->error = 1;
- return (0); /* we are complete */
- }
- while (count > 0) {
- uint32_t temp;
-
- usb2_get_page(td->pc, td->offset, &buf_res);
-
- /* get correct length */
- if (buf_res.length > count) {
- buf_res.length = count;
- }
- /* check for unaligned memory address */
- if (USB_P2U(buf_res.buffer) & 3) {
-
- temp = count & ~3;
-
- if (temp) {
- /* receive data 4 bytes at a time */
- bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(td->ep_no), sc->sc_bounce_buf,
- temp / 4);
- }
- temp = count & 3;
- if (temp) {
- /* receive data 1 byte at a time */
- bus_space_read_multi_1(sc->sc_io_tag,
- sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
- ((void *)&sc->sc_bounce_buf[count / 4]), temp);
- }
- usb2_copy_in(td->pc, td->offset,
- sc->sc_bounce_buf, count);
-
- /* update offset and remainder */
- td->offset += count;
- td->remainder -= count;
- break;
- }
- /* check if we can optimise */
- if (buf_res.length >= 4) {
-
- /* receive data 4 bytes at a time */
- bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
- buf_res.length / 4);
-
- temp = buf_res.length & ~3;
-
- /* update counters */
- count -= temp;
- td->offset += temp;
- td->remainder -= temp;
- continue;
- }
- /* receive data */
- bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
- buf_res.length);
-
- /* update counters */
- count -= buf_res.length;
- td->offset += buf_res.length;
- td->remainder -= buf_res.length;
- }
-
- /* clear status bits */
- MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
-
- /* check if we are complete */
- if ((td->remainder == 0) || got_short) {
- if (td->short_pkt) {
- /* we are complete */
- return (0);
- }
- /* else need to receive a zero length packet */
- }
- if (--to) {
- goto repeat;
- }
- return (1); /* not complete */
-}
-
-static uint8_t
-musbotg_data_tx(struct musbotg_td *td)
-{
- struct usb2_page_search buf_res;
- struct musbotg_softc *sc;
- uint16_t count;
- uint8_t csr;
- uint8_t to;
-
- to = 8; /* don't loop forever! */
-
- /* get pointer to softc */
- sc = MUSBOTG_PC2SC(td->pc);
-
- /* select endpoint */
- MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
-
-repeat:
-
- /* read out FIFO status */
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
-
- DPRINTFN(4, "csr=0x%02x\n", csr);
-
- if (csr & (MUSB2_MASK_CSRL_TXINCOMP |
- MUSB2_MASK_CSRL_TXUNDERRUN)) {
- /* clear status bits */
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
- }
- if (csr & MUSB2_MASK_CSRL_TXPKTRDY) {
- return (1); /* not complete */
- }
- /* check for short packet */
- count = td->max_frame_size;
- if (td->remainder < count) {
- /* we have a short packet */
- td->short_pkt = 1;
- count = td->remainder;
- }
- while (count > 0) {
- uint32_t temp;
-
- usb2_get_page(td->pc, td->offset, &buf_res);
-
- /* get correct length */
- if (buf_res.length > count) {
- buf_res.length = count;
- }
- /* check for unaligned memory address */
- if (USB_P2U(buf_res.buffer) & 3) {
-
- usb2_copy_out(td->pc, td->offset,
- sc->sc_bounce_buf, count);
-
- temp = count & ~3;
-
- if (temp) {
- /* transmit data 4 bytes at a time */
- bus_space_write_multi_4(sc->sc_io_tag,
- sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
- sc->sc_bounce_buf, temp / 4);
- }
- temp = count & 3;
- if (temp) {
- /* receive data 1 byte at a time */
- bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(td->ep_no),
- ((void *)&sc->sc_bounce_buf[count / 4]), temp);
- }
- /* update offset and remainder */
- td->offset += count;
- td->remainder -= count;
- break;
- }
- /* check if we can optimise */
- if (buf_res.length >= 4) {
-
- /* transmit data 4 bytes at a time */
- bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
- buf_res.length / 4);
-
- temp = buf_res.length & ~3;
-
- /* update counters */
- count -= temp;
- td->offset += temp;
- td->remainder -= temp;
- continue;
- }
- /* transmit data */
- bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
- MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
- buf_res.length);
-
- /* update counters */
- count -= buf_res.length;
- td->offset += buf_res.length;
- td->remainder -= buf_res.length;
- }
-
- /* write command */
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
- MUSB2_MASK_CSRL_TXPKTRDY);
-
- /* check remainder */
- if (td->remainder == 0) {
- if (td->short_pkt) {
- return (0); /* complete */
- }
- /* else we need to transmit a short packet */
- }
- if (--to) {
- goto repeat;
- }
- return (1); /* not complete */
-}
-
-static uint8_t
-musbotg_xfer_do_fifo(struct usb2_xfer *xfer)
-{
- struct musbotg_softc *sc;
- struct musbotg_td *td;
-
- DPRINTFN(8, "\n");
-
- td = xfer->td_transfer_cache;
- while (1) {
- if ((td->func) (td)) {
- /* operation in progress */
- break;
- }
- if (((void *)td) == xfer->td_transfer_last) {
- goto done;
- }
- if (td->error) {
- goto done;
- } else if (td->remainder > 0) {
- /*
- * We had a short transfer. If there is no alternate
- * next, stop processing !
- */
- if (!td->alt_next) {
- goto done;
- }
- }
- /*
- * Fetch the next transfer descriptor and transfer
- * some flags to the next transfer descriptor
- */
- td = td->obj_next;
- xfer->td_transfer_cache = td;
- }
- return (1); /* not complete */
-
-done:
- sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
-
- /* compute all actual lengths */
-
- musbotg_standard_done(xfer);
-
- return (0); /* complete */
-}
-
-static void
-musbotg_interrupt_poll(struct musbotg_softc *sc)
-{
- struct usb2_xfer *xfer;
-
-repeat:
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
- if (!musbotg_xfer_do_fifo(xfer)) {
- /* queue has been modified */
- goto repeat;
- }
- }
-}
-
-void
-musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on)
-{
- DPRINTFN(4, "vbus = %u\n", is_on);
-
- USB_BUS_LOCK(&sc->sc_bus);
- if (is_on) {
- if (!sc->sc_flags.status_vbus) {
- sc->sc_flags.status_vbus = 1;
-
- /* complete root HUB interrupt endpoint */
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &musbotg_root_intr_done);
- }
- } else {
- if (sc->sc_flags.status_vbus) {
- sc->sc_flags.status_vbus = 0;
- sc->sc_flags.status_bus_reset = 0;
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 0;
- sc->sc_flags.change_connect = 1;
-
- /* complete root HUB interrupt endpoint */
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &musbotg_root_intr_done);
- }
- }
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-void
-musbotg_interrupt(struct musbotg_softc *sc)
-{
- uint16_t rx_status;
- uint16_t tx_status;
- uint8_t usb_status;
- uint8_t temp;
- uint8_t to = 2;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
-repeat:
-
- /* read all interrupt registers */
- usb_status = MUSB2_READ_1(sc, MUSB2_REG_INTUSB);
-
- /* read all FIFO interrupts */
- rx_status = MUSB2_READ_2(sc, MUSB2_REG_INTRX);
- tx_status = MUSB2_READ_2(sc, MUSB2_REG_INTTX);
-
- /* check for any bus state change interrupts */
-
- if (usb_status & (MUSB2_MASK_IRESET |
- MUSB2_MASK_IRESUME | MUSB2_MASK_ISUSP)) {
-
- DPRINTFN(4, "real bus interrupt 0x%08x\n", usb_status);
-
- if (usb_status & MUSB2_MASK_IRESET) {
-
- /* set correct state */
- sc->sc_flags.status_bus_reset = 1;
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 0;
- sc->sc_flags.change_connect = 1;
-
- /* determine line speed */
- temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
- if (temp & MUSB2_MASK_HSMODE)
- sc->sc_flags.status_high_speed = 1;
- else
- sc->sc_flags.status_high_speed = 0;
-
- /*
- * After reset all interrupts are on and we need to
- * turn them off!
- */
- temp = MUSB2_MASK_IRESET;
- /* disable resume interrupt */
- temp &= ~MUSB2_MASK_IRESUME;
- /* enable suspend interrupt */
- temp |= MUSB2_MASK_ISUSP;
- MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
- /* disable TX and RX interrupts */
- MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
- MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
- }
- /*
- * If RXRSM and RXSUSP is set at the same time we interpret
- * that like RESUME. Resume is set when there is at least 3
- * milliseconds of inactivity on the USB BUS.
- */
- if (usb_status & MUSB2_MASK_IRESUME) {
- if (sc->sc_flags.status_suspend) {
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 1;
-
- temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
- /* disable resume interrupt */
- temp &= ~MUSB2_MASK_IRESUME;
- /* enable suspend interrupt */
- temp |= MUSB2_MASK_ISUSP;
- MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
- }
- } else if (usb_status & MUSB2_MASK_ISUSP) {
- if (!sc->sc_flags.status_suspend) {
- sc->sc_flags.status_suspend = 1;
- sc->sc_flags.change_suspend = 1;
-
- temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
- /* disable suspend interrupt */
- temp &= ~MUSB2_MASK_ISUSP;
- /* enable resume interrupt */
- temp |= MUSB2_MASK_IRESUME;
- MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
- }
- }
- /* complete root HUB interrupt endpoint */
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &musbotg_root_intr_done);
- }
- /* check for any endpoint interrupts */
-
- if (rx_status || tx_status) {
- DPRINTFN(4, "real endpoint interrupt "
- "rx=0x%04x, tx=0x%04x\n", rx_status, tx_status);
- }
- /* poll one time regardless of FIFO status */
-
- musbotg_interrupt_poll(sc);
-
- if (--to)
- goto repeat;
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-static void
-musbotg_setup_standard_chain_sub(struct musbotg_std_temp *temp)
-{
- struct musbotg_td *td;
-
- /* get current Transfer Descriptor */
- td = temp->td_next;
- temp->td = td;
-
- /* prepare for next TD */
- temp->td_next = td->obj_next;
-
- /* fill out the Transfer Descriptor */
- td->func = temp->func;
- td->pc = temp->pc;
- td->offset = temp->offset;
- td->remainder = temp->len;
- td->error = 0;
- td->did_stall = 0;
- td->short_pkt = temp->short_pkt;
- td->alt_next = temp->setup_alt_next;
-}
-
-static void
-musbotg_setup_standard_chain(struct usb2_xfer *xfer)
-{
- struct musbotg_std_temp temp;
- struct musbotg_softc *sc;
- struct musbotg_td *td;
- uint32_t x;
- uint8_t ep_no;
-
- DPRINTFN(8, "addr=%d endpt=%d sumlen=%d speed=%d\n",
- xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
-
- temp.max_frame_size = xfer->max_frame_size;
-
- td = xfer->td_start[0];
- xfer->td_transfer_first = td;
- xfer->td_transfer_cache = td;
-
- /* setup temp */
-
- temp.td = NULL;
- temp.td_next = xfer->td_start[0];
- temp.setup_alt_next = xfer->flags_int.short_frames_ok;
- temp.offset = 0;
-
- sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
- ep_no = (xfer->endpoint & UE_ADDR);
-
- /* check if we should prepend a setup message */
-
- if (xfer->flags_int.control_xfr) {
- if (xfer->flags_int.control_hdr) {
-
- temp.func = &musbotg_setup_rx;
- temp.len = xfer->frlengths[0];
- temp.pc = xfer->frbuffers + 0;
- temp.short_pkt = temp.len ? 1 : 0;
-
- musbotg_setup_standard_chain_sub(&temp);
- }
- x = 1;
- } else {
- x = 0;
- }
-
- if (x != xfer->nframes) {
- if (xfer->endpoint & UE_DIR_IN) {
- if (xfer->flags_int.control_xfr)
- temp.func = &musbotg_setup_data_tx;
- else
- temp.func = &musbotg_data_tx;
- } else {
- if (xfer->flags_int.control_xfr)
- temp.func = &musbotg_setup_data_rx;
- else
- temp.func = &musbotg_data_rx;
- }
-
- /* setup "pc" pointer */
- temp.pc = xfer->frbuffers + x;
- }
- while (x != xfer->nframes) {
-
- /* DATA0 / DATA1 message */
-
- temp.len = xfer->frlengths[x];
-
- x++;
-
- if (x == xfer->nframes) {
- temp.setup_alt_next = 0;
- }
- if (temp.len == 0) {
-
- /* make sure that we send an USB packet */
-
- temp.short_pkt = 0;
-
- } else {
-
- /* regular data transfer */
-
- temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
- }
-
- musbotg_setup_standard_chain_sub(&temp);
-
- if (xfer->flags_int.isochronous_xfr) {
- temp.offset += temp.len;
- } else {
- /* get next Page Cache pointer */
- temp.pc = xfer->frbuffers + x;
- }
- }
-
- /* always setup a valid "pc" pointer for status and sync */
- temp.pc = xfer->frbuffers + 0;
-
- /* check if we should append a status stage */
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- /*
- * Send a DATA1 message and invert the current
- * endpoint direction.
- */
- temp.func = &musbotg_setup_status;
- temp.len = 0;
- temp.short_pkt = 0;
-
- musbotg_setup_standard_chain_sub(&temp);
- }
- /* must have at least one frame! */
- td = temp.td;
- xfer->td_transfer_last = td;
-}
-
-static void
-musbotg_timeout(void *arg)
-{
- struct usb2_xfer *xfer = arg;
-
- DPRINTFN(1, "xfer=%p\n", xfer);
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- /* transfer is transferred */
- musbotg_device_done(xfer, USB_ERR_TIMEOUT);
-}
-
-static void
-musbotg_ep_int_set(struct usb2_xfer *xfer, uint8_t on)
-{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
- uint16_t temp;
- uint8_t ep_no = xfer->endpoint & UE_ADDR;
-
- /*
- * Only enable the endpoint interrupt when we are
- * actually waiting for data, hence we are dealing
- * with level triggered interrupts !
- */
- if (ep_no == 0) {
- temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
- if (on)
- temp |= MUSB2_MASK_EPINT(0);
- else
- temp &= ~MUSB2_MASK_EPINT(0);
-
- MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
- } else {
- if (USB_GET_DATA_ISREAD(xfer)) {
- temp = MUSB2_READ_2(sc, MUSB2_REG_INTRXE);
- if (on)
- temp |= MUSB2_MASK_EPINT(ep_no);
- else
- temp &= ~MUSB2_MASK_EPINT(ep_no);
- MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, temp);
-
- } else {
- temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
- if (on)
- temp |= MUSB2_MASK_EPINT(ep_no);
- else
- temp &= ~MUSB2_MASK_EPINT(ep_no);
- MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
- }
- }
-}
-
-static void
-musbotg_start_standard_chain(struct usb2_xfer *xfer)
-{
- DPRINTFN(8, "\n");
-
- /* poll one time */
- if (musbotg_xfer_do_fifo(xfer)) {
-
- musbotg_ep_int_set(xfer, 1);
-
- DPRINTFN(14, "enabled interrupts on endpoint\n");
-
- /* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
-
- /* start timeout, if any */
- if (xfer->timeout != 0) {
- usb2_transfer_timeout_ms(xfer,
- &musbotg_timeout, xfer->timeout);
- }
- }
-}
-
-static void
-musbotg_root_intr_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
-
- DPRINTFN(8, "\n");
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_PRE_DATA) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- musbotg_device_done(xfer, std->err);
- }
- goto done;
- }
- /* setup buffer */
- std->ptr = sc->sc_hub_idata;
- std->len = sizeof(sc->sc_hub_idata);
-
- /* set port bit */
- sc->sc_hub_idata[0] = 0x02; /* we only have one port */
-
-done:
- return;
-}
-
-static usb2_error_t
-musbotg_standard_done_sub(struct usb2_xfer *xfer)
-{
- struct musbotg_td *td;
- uint32_t len;
- uint8_t error;
-
- DPRINTFN(8, "\n");
-
- td = xfer->td_transfer_cache;
-
- do {
- len = td->remainder;
-
- if (xfer->aframes != xfer->nframes) {
- /*
- * Verify the length and subtract
- * the remainder from "frlengths[]":
- */
- if (len > xfer->frlengths[xfer->aframes]) {
- td->error = 1;
- } else {
- xfer->frlengths[xfer->aframes] -= len;
- }
- }
- /* Check for transfer error */
- if (td->error) {
- /* the transfer is finished */
- error = 1;
- td = NULL;
- break;
- }
- /* Check for short transfer */
- if (len > 0) {
- if (xfer->flags_int.short_frames_ok) {
- /* follow alt next */
- if (td->alt_next) {
- td = td->obj_next;
- } else {
- td = NULL;
- }
- } else {
- /* the transfer is finished */
- td = NULL;
- }
- error = 0;
- break;
- }
- td = td->obj_next;
-
- /* this USB frame is complete */
- error = 0;
- break;
-
- } while (0);
-
- /* update transfer cache */
-
- xfer->td_transfer_cache = td;
-
- return (error ?
- USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
-}
-
-static void
-musbotg_standard_done(struct usb2_xfer *xfer)
-{
- usb2_error_t err = 0;
-
- DPRINTFN(12, "xfer=%p pipe=%p transfer done\n",
- xfer, xfer->pipe);
-
- /* reset scanner */
-
- xfer->td_transfer_cache = xfer->td_transfer_first;
-
- if (xfer->flags_int.control_xfr) {
-
- if (xfer->flags_int.control_hdr) {
-
- err = musbotg_standard_done_sub(xfer);
- }
- xfer->aframes = 1;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
- while (xfer->aframes != xfer->nframes) {
-
- err = musbotg_standard_done_sub(xfer);
- xfer->aframes++;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- err = musbotg_standard_done_sub(xfer);
- }
-done:
- musbotg_device_done(xfer, err);
-}
-
-/*------------------------------------------------------------------------*
- * musbotg_device_done
- *
- * NOTE: this function can be called more than one time on the
- * same USB transfer!
- *------------------------------------------------------------------------*/
-static void
-musbotg_device_done(struct usb2_xfer *xfer, usb2_error_t error)
-{
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
- xfer, xfer->pipe, error);
-
- if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
-
- musbotg_ep_int_set(xfer, 0);
-
- DPRINTFN(14, "disabled interrupts on endpoint\n");
- }
- /* dequeue transfer and start next transfer */
- usb2_transfer_done(xfer, error);
-}
-
-static void
-musbotg_set_stall(struct usb2_device *udev, struct usb2_xfer *xfer,
- struct usb2_pipe *pipe)
-{
- struct musbotg_softc *sc;
- uint8_t ep_no;
-
- USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
-
- DPRINTFN(4, "pipe=%p\n", pipe);
-
- if (xfer) {
- /* cancel any ongoing transfers */
- musbotg_device_done(xfer, USB_ERR_STALLED);
- }
- /* set FORCESTALL */
- sc = MUSBOTG_BUS2SC(udev->bus);
-
- ep_no = (pipe->edesc->bEndpointAddress & UE_ADDR);
-
- /* select endpoint */
- MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
-
- if (pipe->edesc->bEndpointAddress & UE_DIR_IN) {
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
- MUSB2_MASK_CSRL_TXSENDSTALL);
- } else {
- MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
- MUSB2_MASK_CSRL_RXSENDSTALL);
- }
-}
-
-static void
-musbotg_clear_stall_sub(struct musbotg_softc *sc, uint16_t wMaxPacket,
- uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
-{
- uint16_t mps;
- uint16_t temp;
- uint8_t csr;
-
- if (ep_type == UE_CONTROL) {
- /* clearing stall is not needed */
- return;
- }
- /* select endpoint */
- MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
-
- /* compute max frame size */
- mps = wMaxPacket & 0x7FF;
- switch ((wMaxPacket >> 11) & 3) {
- case 1:
- mps *= 2;
- break;
- case 2:
- mps *= 3;
- break;
- default:
- break;
- }
-
- if (ep_dir == UE_DIR_IN) {
-
- temp = 0;
-
- /* Configure endpoint */
- switch (ep_type) {
- case UE_INTERRUPT:
- MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
- MUSB2_MASK_CSRH_TXMODE | temp);
- break;
- case UE_ISOCHRONOUS:
- MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
- MUSB2_MASK_CSRH_TXMODE |
- MUSB2_MASK_CSRH_TXISO | temp);
- break;
- case UE_BULK:
- MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
- MUSB2_MASK_CSRH_TXMODE | temp);
- break;
- default:
- break;
- }
-
- /* Need to flush twice in case of double bufring */
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
- if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
- MUSB2_MASK_CSRL_TXFFLUSH);
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
- if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
- MUSB2_MASK_CSRL_TXFFLUSH);
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
- }
- }
- /* reset data toggle */
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
- MUSB2_MASK_CSRL_TXDT_CLR);
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
-
- /* set double/single buffering */
- temp = MUSB2_READ_2(sc, MUSB2_REG_TXDBDIS);
- if (mps <= (sc->sc_hw_ep_profile[ep_no].
- max_in_frame_size / 2)) {
- /* double buffer */
- temp &= ~(1 << ep_no);
- } else {
- /* single buffer */
- temp |= (1 << ep_no);
- }
- MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, temp);
-
- /* clear sent stall */
- if (csr & MUSB2_MASK_CSRL_TXSENTSTALL) {
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
- csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
- }
- } else {
-
- temp = 0;
-
- /* Configure endpoint */
- switch (ep_type) {
- case UE_INTERRUPT:
- MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
- MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
- MUSB2_MASK_CSRH_RXNYET | temp);
- break;
- case UE_ISOCHRONOUS:
- MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
- MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
- MUSB2_MASK_CSRH_RXNYET |
- MUSB2_MASK_CSRH_RXISO | temp);
- break;
- case UE_BULK:
- MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
- MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH, temp);
- break;
- default:
- break;
- }
-
- /* Need to flush twice in case of double bufring */
- csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
- if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
- MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
- MUSB2_MASK_CSRL_RXFFLUSH);
- csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
- if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
- MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
- MUSB2_MASK_CSRL_RXFFLUSH);
- csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
- }
- }
- /* reset data toggle */
- MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
- MUSB2_MASK_CSRL_RXDT_CLR);
- MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
- csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
-
- /* set double/single buffering */
- temp = MUSB2_READ_2(sc, MUSB2_REG_RXDBDIS);
- if (mps <= (sc->sc_hw_ep_profile[ep_no].
- max_out_frame_size / 2)) {
- /* double buffer */
- temp &= ~(1 << ep_no);
- } else {
- /* single buffer */
- temp |= (1 << ep_no);
- }
- MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, temp);
-
- /* clear sent stall */
- if (csr & MUSB2_MASK_CSRL_RXSENTSTALL) {
- MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
- }
- }
-}
-
-static void
-musbotg_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe)
-{
- struct musbotg_softc *sc;
- struct usb2_endpoint_descriptor *ed;
-
- DPRINTFN(4, "pipe=%p\n", pipe);
-
- USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
-
- /* check mode */
- if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
- /* not supported */
- return;
- }
- /* get softc */
- sc = MUSBOTG_BUS2SC(udev->bus);
-
- /* get endpoint descriptor */
- ed = pipe->edesc;
-
- /* reset endpoint */
- musbotg_clear_stall_sub(sc,
- UGETW(ed->wMaxPacketSize),
- (ed->bEndpointAddress & UE_ADDR),
- (ed->bmAttributes & UE_XFERTYPE),
- (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
-}
-
-usb2_error_t
-musbotg_init(struct musbotg_softc *sc)
-{
- struct usb2_hw_ep_profile *pf;
- uint8_t nrx;
- uint8_t ntx;
- uint8_t temp;
- uint8_t fsize;
- uint8_t frx;
- uint8_t ftx;
-
- DPRINTFN(1, "start\n");
-
- /* set up the bus structure */
- sc->sc_bus.usbrev = USB_REV_2_0;
- sc->sc_bus.methods = &musbotg_bus_methods;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* turn on clocks */
-
- if (sc->sc_clocks_on) {
- (sc->sc_clocks_on) (sc->sc_clocks_arg);
- }
- /* wait a little for things to stabilise */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
-
- /* disable all interrupts */
-
- MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
- MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
- MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
-
- /* disable pullup */
-
- musbotg_pull_common(sc, 0);
-
- /* wait a little bit (10ms) */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
-
- /* disable double packet buffering */
- MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, 0xFFFF);
- MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, 0xFFFF);
-
- /* enable HighSpeed and ISO Update flags */
-
- MUSB2_WRITE_1(sc, MUSB2_REG_POWER,
- MUSB2_MASK_HSENAB | MUSB2_MASK_ISOUPD);
-
- /* clear Session bit, if set */
-
- temp = MUSB2_READ_1(sc, MUSB2_REG_DEVCTL);
- temp &= ~MUSB2_MASK_SESS;
- MUSB2_WRITE_1(sc, MUSB2_REG_DEVCTL, temp);
-
- DPRINTF("DEVCTL=0x%02x\n", temp);
-
- /* disable testmode */
-
- MUSB2_WRITE_1(sc, MUSB2_REG_TESTMODE, 0);
-
- /* set default value */
-
- MUSB2_WRITE_1(sc, MUSB2_REG_MISC, 0);
-
- /* select endpoint index 0 */
-
- MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
-
- /* read out number of endpoints */
-
- nrx =
- (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) / 16);
-
- ntx =
- (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) % 16);
-
- /* these numbers exclude the control endpoint */
-
- DPRINTFN(2, "RX/TX endpoints: %u/%u\n", nrx, ntx);
-
- sc->sc_ep_max = (nrx > ntx) ? nrx : ntx;
- if (sc->sc_ep_max == 0) {
- DPRINTFN(2, "ERROR: Looks like the clocks are off!\n");
- }
- /* read out configuration data */
-
- sc->sc_conf_data = MUSB2_READ_1(sc, MUSB2_REG_CONFDATA);
-
- DPRINTFN(2, "Config Data: 0x%02x\n",
- sc->sc_conf_data);
-
- DPRINTFN(2, "HW version: 0x%04x\n",
- MUSB2_READ_1(sc, MUSB2_REG_HWVERS));
-
- /* initialise endpoint profiles */
-
- for (temp = 1; temp <= sc->sc_ep_max; temp++) {
- pf = sc->sc_hw_ep_profile + temp;
-
- /* select endpoint */
- MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, temp);
-
- fsize = MUSB2_READ_1(sc, MUSB2_REG_FSIZE);
- frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16;;
- ftx = (fsize & MUSB2_MASK_TX_FSIZE);
-
- DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u\n",
- temp, pf->max_in_frame_size,
- pf->max_out_frame_size);
-
- if (frx && ftx && (temp <= nrx) && (temp <= ntx)) {
- pf->max_in_frame_size = 1 << ftx;
- pf->max_out_frame_size = 1 << frx;
- pf->is_simplex = 0; /* duplex */
- pf->support_multi_buffer = 1;
- pf->support_bulk = 1;
- pf->support_interrupt = 1;
- pf->support_isochronous = 1;
- pf->support_in = 1;
- pf->support_out = 1;
- } else if (frx && (temp <= nrx)) {
- pf->max_out_frame_size = 1 << frx;
- pf->is_simplex = 1; /* simplex */
- pf->support_multi_buffer = 1;
- pf->support_bulk = 1;
- pf->support_interrupt = 1;
- pf->support_isochronous = 1;
- pf->support_out = 1;
- } else if (ftx && (temp <= ntx)) {
- pf->max_in_frame_size = 1 << ftx;
- pf->is_simplex = 1; /* simplex */
- pf->support_multi_buffer = 1;
- pf->support_bulk = 1;
- pf->support_interrupt = 1;
- pf->support_isochronous = 1;
- pf->support_in = 1;
- }
- }
-
- /* turn on default interrupts */
-
- MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE,
- MUSB2_MASK_IRESET);
-
- musbotg_clocks_off(sc);
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-
- /* catch any lost interrupts */
-
- musbotg_do_poll(&sc->sc_bus);
-
- return (0); /* success */
-}
-
-void
-musbotg_uninit(struct musbotg_softc *sc)
-{
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* disable all interrupts */
- MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
- MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
- MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
-
- sc->sc_flags.port_powered = 0;
- sc->sc_flags.status_vbus = 0;
- sc->sc_flags.status_bus_reset = 0;
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 0;
- sc->sc_flags.change_connect = 1;
-
- musbotg_pull_down(sc);
- musbotg_clocks_off(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-void
-musbotg_suspend(struct musbotg_softc *sc)
-{
- return;
-}
-
-void
-musbotg_resume(struct musbotg_softc *sc)
-{
- return;
-}
-
-static void
-musbotg_do_poll(struct usb2_bus *bus)
-{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
-
- USB_BUS_LOCK(&sc->sc_bus);
- musbotg_interrupt_poll(sc);
- musbotg_root_ctrl_poll(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-/*------------------------------------------------------------------------*
- * musbotg bulk support
- *------------------------------------------------------------------------*/
-static void
-musbotg_device_bulk_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_device_bulk_close(struct usb2_xfer *xfer)
-{
- musbotg_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-musbotg_device_bulk_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_device_bulk_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- musbotg_setup_standard_chain(xfer);
- musbotg_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods musbotg_device_bulk_methods =
-{
- .open = musbotg_device_bulk_open,
- .close = musbotg_device_bulk_close,
- .enter = musbotg_device_bulk_enter,
- .start = musbotg_device_bulk_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * musbotg control support
- *------------------------------------------------------------------------*/
-static void
-musbotg_device_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_device_ctrl_close(struct usb2_xfer *xfer)
-{
- musbotg_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-musbotg_device_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_device_ctrl_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- musbotg_setup_standard_chain(xfer);
- musbotg_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods musbotg_device_ctrl_methods =
-{
- .open = musbotg_device_ctrl_open,
- .close = musbotg_device_ctrl_close,
- .enter = musbotg_device_ctrl_enter,
- .start = musbotg_device_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * musbotg interrupt support
- *------------------------------------------------------------------------*/
-static void
-musbotg_device_intr_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_device_intr_close(struct usb2_xfer *xfer)
-{
- musbotg_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-musbotg_device_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_device_intr_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- musbotg_setup_standard_chain(xfer);
- musbotg_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods musbotg_device_intr_methods =
-{
- .open = musbotg_device_intr_open,
- .close = musbotg_device_intr_close,
- .enter = musbotg_device_intr_enter,
- .start = musbotg_device_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * musbotg full speed isochronous support
- *------------------------------------------------------------------------*/
-static void
-musbotg_device_isoc_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_device_isoc_close(struct usb2_xfer *xfer)
-{
- musbotg_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-musbotg_device_isoc_enter(struct usb2_xfer *xfer)
-{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
- uint32_t temp;
- uint32_t nframes;
- uint32_t fs_frames;
-
- DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
- xfer, xfer->pipe->isoc_next, xfer->nframes);
-
- /* get the current frame index */
-
- nframes = MUSB2_READ_2(sc, MUSB2_REG_FRAME);
-
- /*
- * check if the frame index is within the window where the frames
- * will be inserted
- */
- temp = (nframes - xfer->pipe->isoc_next) & MUSB2_MASK_FRAME;
-
- if (usb2_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
- fs_frames = (xfer->nframes + 7) / 8;
- } else {
- fs_frames = xfer->nframes;
- }
-
- if ((xfer->pipe->is_synced == 0) ||
- (temp < fs_frames)) {
- /*
- * If there is data underflow or the pipe queue is
- * empty we schedule the transfer a few frames ahead
- * of the current frame position. Else two isochronous
- * transfers might overlap.
- */
- xfer->pipe->isoc_next = (nframes + 3) & MUSB2_MASK_FRAME;
- xfer->pipe->is_synced = 1;
- DPRINTFN(2, "start next=%d\n", xfer->pipe->isoc_next);
- }
- /*
- * compute how many milliseconds the insertion is ahead of the
- * current frame position:
- */
- temp = (xfer->pipe->isoc_next - nframes) & MUSB2_MASK_FRAME;
-
- /*
- * pre-compute when the isochronous transfer will be finished:
- */
- xfer->isoc_time_complete =
- usb2_isoc_time_expand(&sc->sc_bus, nframes) + temp +
- fs_frames;
-
- /* compute frame number for next insertion */
- xfer->pipe->isoc_next += fs_frames;
-
- /* setup TDs */
- musbotg_setup_standard_chain(xfer);
-}
-
-static void
-musbotg_device_isoc_start(struct usb2_xfer *xfer)
-{
- /* start TD chain */
- musbotg_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods musbotg_device_isoc_methods =
-{
- .open = musbotg_device_isoc_open,
- .close = musbotg_device_isoc_close,
- .enter = musbotg_device_isoc_enter,
- .start = musbotg_device_isoc_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * musbotg root control support
- *------------------------------------------------------------------------*
- * simulate a hardware HUB by handling
- * all the necessary requests
- *------------------------------------------------------------------------*/
-static void
-musbotg_root_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_root_ctrl_close(struct usb2_xfer *xfer)
-{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_ctrl.xfer == xfer) {
- sc->sc_root_ctrl.xfer = NULL;
- }
- musbotg_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-/*
- * USB descriptors for the virtual Root HUB:
- */
-
-static const struct usb2_device_descriptor musbotg_devd = {
- .bLength = sizeof(struct usb2_device_descriptor),
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_HSHUBSTT,
- .bMaxPacketSize = 64,
- .bcdDevice = {0x00, 0x01},
- .iManufacturer = 1,
- .iProduct = 2,
- .bNumConfigurations = 1,
-};
-
-static const struct usb2_device_qualifier musbotg_odevd = {
- .bLength = sizeof(struct usb2_device_qualifier),
- .bDescriptorType = UDESC_DEVICE_QUALIFIER,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_FSHUB,
- .bMaxPacketSize0 = 0,
- .bNumConfigurations = 0,
-};
-
-static const struct musbotg_config_desc musbotg_confd = {
- .confd = {
- .bLength = sizeof(struct usb2_config_descriptor),
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength[0] = sizeof(musbotg_confd),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_SELF_POWERED,
- .bMaxPower = 0,
- },
- .ifcd = {
- .bLength = sizeof(struct usb2_interface_descriptor),
- .bDescriptorType = UDESC_INTERFACE,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_HSHUBSTT,
- },
-
- .endpd = {
- .bLength = sizeof(struct usb2_endpoint_descriptor),
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = (UE_DIR_IN | MUSBOTG_INTR_ENDPT),
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize[0] = 8,
- .bInterval = 255,
- },
-};
-
-static const struct usb2_hub_descriptor_min musbotg_hubd = {
- .bDescLength = sizeof(musbotg_hubd),
- .bDescriptorType = UDESC_HUB,
- .bNbrPorts = 1,
- .wHubCharacteristics[0] =
- (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
- .wHubCharacteristics[1] =
- (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 16,
- .bPwrOn2PwrGood = 50,
- .bHubContrCurrent = 0,
- .DeviceRemovable = {0}, /* port is removable */
-};
-
-#define STRING_LANG \
- 0x09, 0x04, /* American English */
-
-#define STRING_VENDOR \
- 'M', 0, 'e', 0, 'n', 0, 't', 0, 'o', 0, 'r', 0, ' ', 0, \
- 'G', 0, 'r', 0, 'a', 0, 'p', 0, 'h', 0, 'i', 0, 'c', 0, 's', 0
-
-#define STRING_PRODUCT \
- 'O', 0, 'T', 0, 'G', 0, ' ', 0, 'R', 0, \
- 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
- 'U', 0, 'B', 0,
-
-USB_MAKE_STRING_DESC(STRING_LANG, musbotg_langtab);
-USB_MAKE_STRING_DESC(STRING_VENDOR, musbotg_vendor);
-USB_MAKE_STRING_DESC(STRING_PRODUCT, musbotg_product);
-
-static void
-musbotg_root_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_root_ctrl_start(struct usb2_xfer *xfer)
-{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_ctrl.xfer = xfer;
-
- usb2_bus_roothub_exec(xfer->xroot->bus);
-}
-
-static void
-musbotg_root_ctrl_task(struct usb2_bus *bus)
-{
- musbotg_root_ctrl_poll(MUSBOTG_BUS2SC(bus));
-}
-
-static void
-musbotg_root_ctrl_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
- uint16_t value;
- uint16_t index;
- uint8_t use_polling;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_SETUP) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- musbotg_device_done(xfer, std->err);
- }
- goto done;
- }
- /* buffer reset */
- std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
- std->len = 0;
-
- value = UGETW(std->req.wValue);
- index = UGETW(std->req.wIndex);
-
- use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
-
- /* demultiplex the control request */
-
- switch (std->req.bmRequestType) {
- case UT_READ_DEVICE:
- switch (std->req.bRequest) {
- case UR_GET_DESCRIPTOR:
- goto tr_handle_get_descriptor;
- case UR_GET_CONFIG:
- goto tr_handle_get_config;
- case UR_GET_STATUS:
- goto tr_handle_get_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_DEVICE:
- switch (std->req.bRequest) {
- case UR_SET_ADDRESS:
- goto tr_handle_set_address;
- case UR_SET_CONFIG:
- goto tr_handle_set_config;
- case UR_CLEAR_FEATURE:
- goto tr_valid; /* nop */
- case UR_SET_DESCRIPTOR:
- goto tr_valid; /* nop */
- case UR_SET_FEATURE:
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_ENDPOINT:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- switch (UGETW(std->req.wValue)) {
- case UF_ENDPOINT_HALT:
- goto tr_handle_clear_halt;
- case UF_DEVICE_REMOTE_WAKEUP:
- goto tr_handle_clear_wakeup;
- default:
- goto tr_stalled;
- }
- break;
- case UR_SET_FEATURE:
- switch (UGETW(std->req.wValue)) {
- case UF_ENDPOINT_HALT:
- goto tr_handle_set_halt;
- case UF_DEVICE_REMOTE_WAKEUP:
- goto tr_handle_set_wakeup;
- default:
- goto tr_stalled;
- }
- break;
- case UR_SYNCH_FRAME:
- goto tr_valid; /* nop */
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_ENDPOINT:
- switch (std->req.bRequest) {
- case UR_GET_STATUS:
- goto tr_handle_get_ep_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_INTERFACE:
- switch (std->req.bRequest) {
- case UR_SET_INTERFACE:
- goto tr_handle_set_interface;
- case UR_CLEAR_FEATURE:
- goto tr_valid; /* nop */
- case UR_SET_FEATURE:
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_INTERFACE:
- switch (std->req.bRequest) {
- case UR_GET_INTERFACE:
- goto tr_handle_get_interface;
- case UR_GET_STATUS:
- goto tr_handle_get_iface_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_CLASS_INTERFACE:
- case UT_WRITE_VENDOR_INTERFACE:
- /* XXX forward */
- break;
-
- case UT_READ_CLASS_INTERFACE:
- case UT_READ_VENDOR_INTERFACE:
- /* XXX forward */
- break;
-
- case UT_WRITE_CLASS_DEVICE:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- goto tr_valid;
- case UR_SET_DESCRIPTOR:
- case UR_SET_FEATURE:
- break;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_CLASS_OTHER:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- goto tr_handle_clear_port_feature;
- case UR_SET_FEATURE:
- goto tr_handle_set_port_feature;
- case UR_CLEAR_TT_BUFFER:
- case UR_RESET_TT:
- case UR_STOP_TT:
- goto tr_valid;
-
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_CLASS_OTHER:
- switch (std->req.bRequest) {
- case UR_GET_TT_STATE:
- goto tr_handle_get_tt_state;
- case UR_GET_STATUS:
- goto tr_handle_get_port_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_CLASS_DEVICE:
- switch (std->req.bRequest) {
- case UR_GET_DESCRIPTOR:
- goto tr_handle_get_class_descriptor;
- case UR_GET_STATUS:
- goto tr_handle_get_class_status;
-
- default:
- goto tr_stalled;
- }
- break;
- default:
- goto tr_stalled;
- }
- goto tr_valid;
-
-tr_handle_get_descriptor:
- switch (value >> 8) {
- case UDESC_DEVICE:
- if (value & 0xff) {
- goto tr_stalled;
- }
- std->len = sizeof(musbotg_devd);
- std->ptr = USB_ADD_BYTES(&musbotg_devd, 0);
- goto tr_valid;
- case UDESC_CONFIG:
- if (value & 0xff) {
- goto tr_stalled;
- }
- std->len = sizeof(musbotg_confd);
- std->ptr = USB_ADD_BYTES(&musbotg_confd, 0);
- goto tr_valid;
- case UDESC_STRING:
- switch (value & 0xff) {
- case 0: /* Language table */
- std->len = sizeof(musbotg_langtab);
- std->ptr = USB_ADD_BYTES(&musbotg_langtab, 0);
- goto tr_valid;
-
- case 1: /* Vendor */
- std->len = sizeof(musbotg_vendor);
- std->ptr = USB_ADD_BYTES(&musbotg_vendor, 0);
- goto tr_valid;
-
- case 2: /* Product */
- std->len = sizeof(musbotg_product);
- std->ptr = USB_ADD_BYTES(&musbotg_product, 0);
- goto tr_valid;
- default:
- break;
- }
- break;
- default:
- goto tr_stalled;
- }
- goto tr_stalled;
-
-tr_handle_get_config:
- std->len = 1;
- sc->sc_hub_temp.wValue[0] = sc->sc_conf;
- goto tr_valid;
-
-tr_handle_get_status:
- std->len = 2;
- USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
- goto tr_valid;
-
-tr_handle_set_address:
- if (value & 0xFF00) {
- goto tr_stalled;
- }
- sc->sc_rt_addr = value;
- goto tr_valid;
-
-tr_handle_set_config:
- if (value >= 2) {
- goto tr_stalled;
- }
- sc->sc_conf = value;
- goto tr_valid;
-
-tr_handle_get_interface:
- std->len = 1;
- sc->sc_hub_temp.wValue[0] = 0;
- goto tr_valid;
-
-tr_handle_get_tt_state:
-tr_handle_get_class_status:
-tr_handle_get_iface_status:
-tr_handle_get_ep_status:
- std->len = 2;
- USETW(sc->sc_hub_temp.wValue, 0);
- goto tr_valid;
-
-tr_handle_set_halt:
-tr_handle_set_interface:
-tr_handle_set_wakeup:
-tr_handle_clear_wakeup:
-tr_handle_clear_halt:
- goto tr_valid;
-
-tr_handle_clear_port_feature:
- if (index != 1) {
- goto tr_stalled;
- }
- DPRINTFN(8, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
-
- switch (value) {
- case UHF_PORT_SUSPEND:
- musbotg_wakeup_peer(xfer);
- break;
-
- case UHF_PORT_ENABLE:
- sc->sc_flags.port_enabled = 0;
- break;
-
- case UHF_PORT_TEST:
- case UHF_PORT_INDICATOR:
- case UHF_C_PORT_ENABLE:
- case UHF_C_PORT_OVER_CURRENT:
- case UHF_C_PORT_RESET:
- /* nops */
- break;
- case UHF_PORT_POWER:
- sc->sc_flags.port_powered = 0;
- musbotg_pull_down(sc);
- musbotg_clocks_off(sc);
- break;
- case UHF_C_PORT_CONNECTION:
- sc->sc_flags.change_connect = 0;
- break;
- case UHF_C_PORT_SUSPEND:
- sc->sc_flags.change_suspend = 0;
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- goto tr_valid;
-
-tr_handle_set_port_feature:
- if (index != 1) {
- goto tr_stalled;
- }
- DPRINTFN(8, "UR_SET_PORT_FEATURE\n");
-
- switch (value) {
- case UHF_PORT_ENABLE:
- sc->sc_flags.port_enabled = 1;
- break;
- case UHF_PORT_SUSPEND:
- case UHF_PORT_RESET:
- case UHF_PORT_TEST:
- case UHF_PORT_INDICATOR:
- /* nops */
- break;
- case UHF_PORT_POWER:
- sc->sc_flags.port_powered = 1;
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- goto tr_valid;
-
-tr_handle_get_port_status:
-
- DPRINTFN(8, "UR_GET_PORT_STATUS\n");
-
- if (index != 1) {
- goto tr_stalled;
- }
- if (sc->sc_flags.status_vbus) {
- musbotg_clocks_on(sc);
- musbotg_pull_up(sc);
- } else {
- musbotg_pull_down(sc);
- musbotg_clocks_off(sc);
- }
-
- /* Select Device Side Mode */
- value = UPS_PORT_MODE_DEVICE;
-
- if (sc->sc_flags.status_high_speed) {
- value |= UPS_HIGH_SPEED;
- }
- if (sc->sc_flags.port_powered) {
- value |= UPS_PORT_POWER;
- }
- if (sc->sc_flags.port_enabled) {
- value |= UPS_PORT_ENABLED;
- }
- if (sc->sc_flags.status_vbus &&
- sc->sc_flags.status_bus_reset) {
- value |= UPS_CURRENT_CONNECT_STATUS;
- }
- if (sc->sc_flags.status_suspend) {
- value |= UPS_SUSPEND;
- }
- USETW(sc->sc_hub_temp.ps.wPortStatus, value);
-
- value = 0;
-
- if (sc->sc_flags.change_connect) {
- value |= UPS_C_CONNECT_STATUS;
-
- if (sc->sc_flags.status_vbus &&
- sc->sc_flags.status_bus_reset) {
- /* reset EP0 state */
- sc->sc_ep0_busy = 0;
- sc->sc_ep0_cmd = 0;
- }
- }
- if (sc->sc_flags.change_suspend) {
- value |= UPS_C_SUSPEND;
- }
- USETW(sc->sc_hub_temp.ps.wPortChange, value);
- std->len = sizeof(sc->sc_hub_temp.ps);
- goto tr_valid;
-
-tr_handle_get_class_descriptor:
- if (value & 0xFF) {
- goto tr_stalled;
- }
- std->ptr = USB_ADD_BYTES(&musbotg_hubd, 0);
- std->len = sizeof(musbotg_hubd);
- goto tr_valid;
-
-tr_stalled:
- std->err = USB_ERR_STALLED;
-tr_valid:
-done:
- return;
-}
-
-static void
-musbotg_root_ctrl_poll(struct musbotg_softc *sc)
-{
- usb2_sw_transfer(&sc->sc_root_ctrl,
- &musbotg_root_ctrl_done);
-}
-
-struct usb2_pipe_methods musbotg_root_ctrl_methods =
-{
- .open = musbotg_root_ctrl_open,
- .close = musbotg_root_ctrl_close,
- .enter = musbotg_root_ctrl_enter,
- .start = musbotg_root_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 0,
-};
-
-/*------------------------------------------------------------------------*
- * musbotg root interrupt support
- *------------------------------------------------------------------------*/
-static void
-musbotg_root_intr_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_root_intr_close(struct usb2_xfer *xfer)
-{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_intr.xfer == xfer) {
- sc->sc_root_intr.xfer = NULL;
- }
- musbotg_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-musbotg_root_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_root_intr_start(struct usb2_xfer *xfer)
-{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_intr.xfer = xfer;
-}
-
-struct usb2_pipe_methods musbotg_root_intr_methods =
-{
- .open = musbotg_root_intr_open,
- .close = musbotg_root_intr_close,
- .enter = musbotg_root_intr_enter,
- .start = musbotg_root_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-static void
-musbotg_xfer_setup(struct usb2_setup_params *parm)
-{
- const struct usb2_hw_ep_profile *pf;
- struct musbotg_softc *sc;
- struct usb2_xfer *xfer;
- void *last_obj;
- uint32_t ntd;
- uint32_t n;
- uint8_t ep_no;
-
- sc = MUSBOTG_BUS2SC(parm->udev->bus);
- xfer = parm->curr_xfer;
-
- /*
- * NOTE: This driver does not use any of the parameters that
- * are computed from the following values. Just set some
- * reasonable dummies:
- */
- parm->hc_max_packet_size = 0x400;
- parm->hc_max_frame_size = 0x400;
-
- if ((parm->methods == &musbotg_device_isoc_methods) ||
- (parm->methods == &musbotg_device_intr_methods))
- parm->hc_max_packet_count = 3;
- else
- parm->hc_max_packet_count = 1;
-
- usb2_transfer_setup_sub(parm);
-
- /*
- * compute maximum number of TDs
- */
- if (parm->methods == &musbotg_device_ctrl_methods) {
-
- ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
-
- } else if (parm->methods == &musbotg_device_bulk_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else if (parm->methods == &musbotg_device_intr_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else if (parm->methods == &musbotg_device_isoc_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else {
-
- ntd = 0;
- }
-
- /*
- * check if "usb2_transfer_setup_sub" set an error
- */
- if (parm->err) {
- return;
- }
- /*
- * allocate transfer descriptors
- */
- last_obj = NULL;
-
- /*
- * get profile stuff
- */
- if (ntd) {
-
- ep_no = xfer->endpoint & UE_ADDR;
- musbotg_get_hw_ep_profile(parm->udev, &pf, ep_no);
-
- if (pf == NULL) {
- /* should not happen */
- parm->err = USB_ERR_INVAL;
- return;
- }
- } else {
- ep_no = 0;
- pf = NULL;
- }
-
- /* align data */
- parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
-
- for (n = 0; n != ntd; n++) {
-
- struct musbotg_td *td;
-
- if (parm->buf) {
-
- td = USB_ADD_BYTES(parm->buf, parm->size[0]);
-
- /* init TD */
- td->max_frame_size = xfer->max_frame_size;
- td->ep_no = ep_no;
- td->obj_next = last_obj;
-
- last_obj = td;
- }
- parm->size[0] += sizeof(*td);
- }
-
- xfer->td_start[0] = last_obj;
-}
-
-static void
-musbotg_xfer_unsetup(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-musbotg_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
- struct usb2_pipe *pipe)
-{
- struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
-
- DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
- pipe, udev->address,
- edesc->bEndpointAddress, udev->flags.usb2_mode,
- sc->sc_rt_addr);
-
- if (udev->device_index == sc->sc_rt_addr) {
-
- if (udev->flags.usb2_mode != USB_MODE_HOST) {
- /* not supported */
- return;
- }
- switch (edesc->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &musbotg_root_ctrl_methods;
- break;
- case UE_DIR_IN | MUSBOTG_INTR_ENDPT:
- pipe->methods = &musbotg_root_intr_methods;
- break;
- default:
- /* do nothing */
- break;
- }
- } else {
-
- if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
- /* not supported */
- return;
- }
- if ((udev->speed != USB_SPEED_FULL) &&
- (udev->speed != USB_SPEED_HIGH)) {
- /* not supported */
- return;
- }
- switch (edesc->bmAttributes & UE_XFERTYPE) {
- case UE_CONTROL:
- pipe->methods = &musbotg_device_ctrl_methods;
- break;
- case UE_INTERRUPT:
- pipe->methods = &musbotg_device_intr_methods;
- break;
- case UE_ISOCHRONOUS:
- pipe->methods = &musbotg_device_isoc_methods;
- break;
- case UE_BULK:
- pipe->methods = &musbotg_device_bulk_methods;
- break;
- default:
- /* do nothing */
- break;
- }
- }
-}
-
-struct usb2_bus_methods musbotg_bus_methods =
-{
- .pipe_init = &musbotg_pipe_init,
- .xfer_setup = &musbotg_xfer_setup,
- .xfer_unsetup = &musbotg_xfer_unsetup,
- .do_poll = &musbotg_do_poll,
- .get_hw_ep_profile = &musbotg_get_hw_ep_profile,
- .set_stall = &musbotg_set_stall,
- .clear_stall = &musbotg_clear_stall,
- .roothub_exec = &musbotg_root_ctrl_task,
-};
diff --git a/sys/dev/usb2/controller/musb2_otg.h b/sys/dev/usb2/controller/musb2_otg.h
deleted file mode 100644
index 0d880e1..0000000
--- a/sys/dev/usb2/controller/musb2_otg.h
+++ /dev/null
@@ -1,407 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 header file defines the registers of the Mentor Graphics
- * USB OnTheGo Inventra chip.
- */
-
-#ifndef _MUSB2_OTG_H_
-#define _MUSB2_OTG_H_
-
-#define MUSB2_MAX_DEVICES (USB_MIN_DEVICES + 1)
-
-/* Common registers */
-
-#define MUSB2_REG_FADDR 0x0000 /* function address register */
-#define MUSB2_MASK_FADDR 0x7F
-
-#define MUSB2_REG_POWER 0x0001 /* power register */
-#define MUSB2_MASK_SUSPM_ENA 0x01
-#define MUSB2_MASK_SUSPMODE 0x02
-#define MUSB2_MASK_RESUME 0x04
-#define MUSB2_MASK_RESET 0x08
-#define MUSB2_MASK_HSMODE 0x10
-#define MUSB2_MASK_HSENAB 0x20
-#define MUSB2_MASK_SOFTC 0x40
-#define MUSB2_MASK_ISOUPD 0x80
-
-/* Endpoint interrupt handling */
-
-#define MUSB2_REG_INTTX 0x0002 /* transmit interrupt register */
-#define MUSB2_REG_INTRX 0x0004 /* receive interrupt register */
-#define MUSB2_REG_INTTXE 0x0006 /* transmit interrupt enable register */
-#define MUSB2_REG_INTRXE 0x0008 /* receive interrupt enable register */
-#define MUSB2_MASK_EPINT(epn) (1 << (epn)) /* epn = [0..15] */
-
-/* Common interrupt handling */
-
-#define MUSB2_REG_INTUSB 0x000A /* USB interrupt register */
-#define MUSB2_MASK_ISUSP 0x01
-#define MUSB2_MASK_IRESUME 0x02
-#define MUSB2_MASK_IRESET 0x04
-#define MUSB2_MASK_IBABBLE 0x04
-#define MUSB2_MASK_ISOF 0x08
-#define MUSB2_MASK_ICONN 0x10
-#define MUSB2_MASK_IDISC 0x20
-#define MUSB2_MASK_ISESSRQ 0x40
-#define MUSB2_MASK_IVBUSERR 0x80
-
-#define MUSB2_REG_INTUSBE 0x000B /* USB interrupt enable register */
-#define MUSB2_REG_FRAME 0x000C /* USB frame register */
-#define MUSB2_MASK_FRAME 0x3FF /* 0..1023 */
-
-#define MUSB2_REG_EPINDEX 0x000E /* endpoint index register */
-#define MUSB2_MASK_EPINDEX 0x0F
-
-#define MUSB2_REG_TESTMODE 0x000F /* test mode register */
-#define MUSB2_MASK_TSE0_NAK 0x01
-#define MUSB2_MASK_TJ 0x02
-#define MUSB2_MASK_TK 0x04
-#define MUSB2_MASK_TPACKET 0x08
-#define MUSB2_MASK_TFORCE_HS 0x10
-#define MUSB2_MASK_TFORCE_LS 0x20
-#define MUSB2_MASK_TFIFO_ACC 0x40
-#define MUSB2_MASK_TFORCE_HC 0x80
-
-#define MUSB2_REG_INDEXED_CSR 0x0010 /* EP control status register offset */
-
-#define MUSB2_REG_TXMAXP (0x0000 + MUSB2_REG_INDEXED_CSR)
-#define MUSB2_REG_RXMAXP (0x0004 + MUSB2_REG_INDEXED_CSR)
-#define MUSB2_MASK_PKTSIZE 0x03FF /* in bytes, should be even */
-#define MUSB2_MASK_PKTMULT 0xFC00 /* HS packet multiplier: 0..2 */
-
-#define MUSB2_REG_TXCSRL (0x0002 + MUSB2_REG_INDEXED_CSR)
-#define MUSB2_MASK_CSRL_TXPKTRDY 0x01
-#define MUSB2_MASK_CSRL_TXFIFONEMPTY 0x02
-#define MUSB2_MASK_CSRL_TXUNDERRUN 0x04 /* Device Mode */
-#define MUSB2_MASK_CSRL_TXERROR 0x04 /* Host Mode */
-#define MUSB2_MASK_CSRL_TXFFLUSH 0x08
-#define MUSB2_MASK_CSRL_TXSENDSTALL 0x10/* Device Mode */
-#define MUSB2_MASK_CSRL_TXSETUPPKT 0x10 /* Host Mode */
-#define MUSB2_MASK_CSRL_TXSENTSTALL 0x20/* Device Mode */
-#define MUSB2_MASK_CSRL_TXSTALLED 0x20 /* Host Mode */
-#define MUSB2_MASK_CSRL_TXDT_CLR 0x40
-#define MUSB2_MASK_CSRL_TXINCOMP 0x80
-
-/* Device Side Mode */
-#define MUSB2_MASK_CSR0L_RXPKTRDY 0x01
-#define MUSB2_MASK_CSR0L_TXPKTRDY 0x02
-#define MUSB2_MASK_CSR0L_SENTSTALL 0x04
-#define MUSB2_MASK_CSR0L_DATAEND 0x08
-#define MUSB2_MASK_CSR0L_SETUPEND 0x10
-#define MUSB2_MASK_CSR0L_SENDSTALL 0x20
-#define MUSB2_MASK_CSR0L_RXPKTRDY_CLR 0x40
-#define MUSB2_MASK_CSR0L_SETUPEND_CLR 0x80
-
-/* Host Side Mode */
-#define MUSB2_MASK_CSR0L_RXSTALL 0x04
-#define MUSB2_MASK_CSR0L_SETUPPKT 0x08
-#define MUSB2_MASK_CSR0L_ERROR 0x10
-#define MUSB2_MASK_CSR0L_REQPKT 0x20
-#define MUSB2_MASK_CSR0L_STATUSPKT 0x40
-#define MUSB2_MASK_CSR0L_NAKTIMO 0x80
-
-#define MUSB2_REG_TXCSRH (0x0003 + MUSB2_REG_INDEXED_CSR)
-#define MUSB2_MASK_CSRH_TXDT_VAL 0x01 /* Host Mode */
-#define MUSB2_MASK_CSRH_TXDT_WR 0x02 /* Host Mode */
-#define MUSB2_MASK_CSRH_TXDMAREQMODE 0x04
-#define MUSB2_MASK_CSRH_TXDT_SWITCH 0x08
-#define MUSB2_MASK_CSRH_TXDMAREQENA 0x10
-#define MUSB2_MASK_CSRH_RXMODE 0x00
-#define MUSB2_MASK_CSRH_TXMODE 0x20
-#define MUSB2_MASK_CSRH_TXISO 0x40 /* Device Mode */
-#define MUSB2_MASK_CSRH_TXAUTOSET 0x80
-
-#define MUSB2_MASK_CSR0H_FFLUSH 0x01 /* Device Side flush FIFO */
-#define MUSB2_MASK_CSR0H_DT 0x02 /* Host Side data toggle */
-#define MUSB2_MASK_CSR0H_DT_SET 0x04 /* Host Side */
-#define MUSB2_MASK_CSR0H_PING_DIS 0x08 /* Host Side */
-
-#define MUSB2_REG_RXCSRL (0x0006 + MUSB2_REG_INDEXED_CSR)
-#define MUSB2_MASK_CSRL_RXPKTRDY 0x01
-#define MUSB2_MASK_CSRL_RXFIFOFULL 0x02
-#define MUSB2_MASK_CSRL_RXOVERRUN 0x04
-#define MUSB2_MASK_CSRL_RXDATAERR 0x08
-#define MUSB2_MASK_CSRL_RXFFLUSH 0x10
-#define MUSB2_MASK_CSRL_RXSENDSTALL 0x20/* Device Mode */
-#define MUSB2_MASK_CSRL_RXREQPKT 0x20 /* Host Mode */
-#define MUSB2_MASK_CSRL_RXSENTSTALL 0x40/* Device Mode */
-#define MUSB2_MASK_CSRL_RXSTALL 0x40 /* Host Mode */
-#define MUSB2_MASK_CSRL_RXDT_CLR 0x80
-
-#define MUSB2_REG_RXCSRH (0x0007 + MUSB2_REG_INDEXED_CSR)
-#define MUSB2_MASK_CSRH_RXINCOMP 0x01
-#define MUSB2_MASK_CSRH_RXDT_VAL 0x02 /* Host Mode */
-#define MUSB2_MASK_CSRH_RXDT_SET 0x04 /* Host Mode */
-#define MUSB2_MASK_CSRH_RXDMAREQMODE 0x08
-#define MUSB2_MASK_CSRH_RXNYET 0x10
-#define MUSB2_MASK_CSRH_RXDMAREQENA 0x20
-#define MUSB2_MASK_CSRH_RXISO 0x40 /* Device Mode */
-#define MUSB2_MASK_CSRH_RXAUTOREQ 0x40 /* Host Mode */
-#define MUSB2_MASK_CSRH_RXAUTOCLEAR 0x80
-
-#define MUSB2_REG_RXCOUNT (0x0008 + MUSB2_REG_INDEXED_CSR)
-#define MUSB2_MASK_RXCOUNT 0xFFFF
-
-#define MUSB2_REG_TXTI (0x000A + MUSB2_REG_INDEXED_CSR)
-#define MUSB2_REG_RXTI (0x000C + MUSB2_REG_INDEXED_CSR)
-
-/* Host Mode */
-#define MUSB2_MASK_TI_SPEED 0xC0
-#define MUSB2_MASK_TI_SPEED_LO 0xC0
-#define MUSB2_MASK_TI_SPEED_FS 0x80
-#define MUSB2_MASK_TI_SPEED_HS 0x40
-#define MUSB2_MASK_TI_PROTO_CTRL 0x00
-#define MUSB2_MASK_TI_PROTO_ISOC 0x10
-#define MUSB2_MASK_TI_PROTO_BULK 0x20
-#define MUSB2_MASK_TI_PROTO_INTR 0x30
-#define MUSB2_MASK_TI_EP_NUM 0x0F
-
-#define MUSB2_REG_TXNAKLIMIT (0x000B /* EPN=0 */ + MUSB2_REG_INDEXED_CSR)
-#define MUSB2_REG_RXNAKLIMIT (0x000D /* EPN=0 */ + MUSB2_REG_INDEXED_CSR)
-#define MUSB2_MASK_NAKLIMIT 0xFF
-
-#define MUSB2_REG_FSIZE (0x000F + MUSB2_REG_INDEXED_CSR)
-#define MUSB2_MASK_RX_FSIZE 0xF0 /* 3..13, 2**n bytes */
-#define MUSB2_MASK_TX_FSIZE 0x0F /* 3..13, 2**n bytes */
-
-#define MUSB2_REG_EPFIFO(n) (0x0020 + (4*(n)))
-
-#define MUSB2_REG_CONFDATA 0x000F /* EPN=0 */
-#define MUSB2_MASK_CD_UTMI_DW 0x01
-#define MUSB2_MASK_CD_SOFTCONE 0x02
-#define MUSB2_MASK_CD_DYNFIFOSZ 0x04
-#define MUSB2_MASK_CD_HBTXE 0x08
-#define MUSB2_MASK_CD_HBRXE 0x10
-#define MUSB2_MASK_CD_BIGEND 0x20
-#define MUSB2_MASK_CD_MPTXE 0x40
-#define MUSB2_MASK_CD_MPRXE 0x80
-
-/* Various registers */
-
-#define MUSB2_REG_DEVCTL 0x0060
-#define MUSB2_MASK_SESS 0x01
-#define MUSB2_MASK_HOSTREQ 0x02
-#define MUSB2_MASK_HOSTMD 0x04
-#define MUSB2_MASK_VBUS0 0x08
-#define MUSB2_MASK_VBUS1 0x10
-#define MUSB2_MASK_LSDEV 0x20
-#define MUSB2_MASK_FSDEV 0x40
-#define MUSB2_MASK_BDEV 0x80
-
-#define MUSB2_REG_MISC 0x0061
-#define MUSB2_MASK_RXEDMA 0x01
-#define MUSB2_MASK_TXEDMA 0x02
-
-#define MUSB2_REG_TXFIFOSZ 0x0062
-#define MUSB2_REG_RXFIFOSZ 0x0063
-#define MUSB2_MASK_FIFODB 0x10 /* set if double buffering, r/w */
-#define MUSB2_MASK_FIFOSZ 0x0F
-#define MUSB2_VAL_FIFOSZ_8 0
-#define MUSB2_VAL_FIFOSZ_16 1
-#define MUSB2_VAL_FIFOSZ_32 2
-#define MUSB2_VAL_FIFOSZ_64 3
-#define MUSB2_VAL_FIFOSZ_128 4
-#define MUSB2_VAL_FIFOSZ_256 5
-#define MUSB2_VAL_FIFOSZ_512 6
-#define MUSB2_VAL_FIFOSZ_1024 7
-#define MUSB2_VAL_FIFOSZ_2048 8
-#define MUSB2_VAL_FIFOSZ_4096 9
-
-#define MUSB2_REG_TXFIFOADD 0x0064
-#define MUSB2_REG_RXFIFOADD 0x0066
-#define MUSB2_MASK_FIFOADD 0xFFF /* unit is 8-bytes */
-
-#define MUSB2_REG_VSTATUS 0x0068
-#define MUSB2_REG_VCONTROL 0x0068
-#define MUSB2_REG_HWVERS 0x006C
-#define MUSB2_REG_ULPI_BASE 0x0070
-
-#define MUSB2_REG_EPINFO 0x0078
-#define MUSB2_MASK_NRXEP 0xF0
-#define MUSB2_MASK_NTXEP 0x0F
-
-#define MUSB2_REG_RAMINFO 0x0079
-#define MUSB2_REG_LINKINFO 0x007A
-
-#define MUSB2_REG_VPLEN 0x007B
-#define MUSB2_MASK_VPLEN 0xFF
-
-#define MUSB2_REG_HS_EOF1 0x007C
-#define MUSB2_REG_FS_EOF1 0x007D
-#define MUSB2_REG_LS_EOF1 0x007E
-#define MUSB2_REG_SOFT_RST 0x007F
-#define MUSB2_MASK_SRST 0x01
-#define MUSB2_MASK_SRSTX 0x02
-
-#define MUSB2_REG_RQPKTCOUNT(n) (0x0300 + (4*(n))
-#define MUSB2_REG_RXDBDIS 0x0340
-#define MUSB2_REG_TXDBDIS 0x0342
-#define MUSB2_MASK_DB(n) (1 << (n)) /* disable double buffer, n = [0..15] */
-
-#define MUSB2_REG_CHIRPTO 0x0344
-#define MUSB2_REG_HSRESUM 0x0346
-
-/* Host Mode only registers */
-
-#define MUSB2_REG_TXFADDR(n) (0x0080 + (8*(n)))
-#define MUSB2_REG_TXHADDR(n) (0x0082 + (8*(n)))
-#define MUSB2_REG_TXHUBPORT(n) (0x0083 + (8*(n)))
-#define MUSB2_REG_RXFADDR(n) (0x0084 + (8*(n)))
-#define MUSB2_REG_RXHADDR(n) (0x0086 + (8*(n)))
-#define MUSB2_REG_RXHPORT(n) (0x0087 + (8*(n)))
-
-#define MUSB2_EP_MAX 16 /* maximum number of endpoints */
-
-#define MUSB2_READ_2(sc, reg) \
- bus_space_read_2((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
-
-#define MUSB2_WRITE_2(sc, reg, data) \
- bus_space_write_2((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data)
-
-#define MUSB2_READ_1(sc, reg) \
- bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
-
-#define MUSB2_WRITE_1(sc, reg, data) \
- bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data)
-
-struct musbotg_td;
-struct musbotg_softc;
-
-typedef uint8_t (musbotg_cmd_t)(struct musbotg_td *td);
-
-struct musbotg_dma {
- struct musbotg_softc *sc;
- uint32_t dma_chan;
- uint8_t busy:1;
- uint8_t complete:1;
- uint8_t error:1;
-};
-
-struct musbotg_td {
- struct musbotg_td *obj_next;
- musbotg_cmd_t *func;
- struct usb2_page_cache *pc;
- uint32_t offset;
- uint32_t remainder;
- uint16_t max_frame_size; /* packet_size * mult */
- uint8_t ep_no;
- uint8_t error:1;
- uint8_t alt_next:1;
- uint8_t short_pkt:1;
- uint8_t support_multi_buffer:1;
- uint8_t did_stall:1;
- uint8_t dma_enabled:1;
-};
-
-struct musbotg_std_temp {
- musbotg_cmd_t *func;
- struct usb2_page_cache *pc;
- struct musbotg_td *td;
- struct musbotg_td *td_next;
- uint32_t len;
- uint32_t offset;
- uint16_t max_frame_size;
- uint8_t short_pkt;
- /*
- * short_pkt = 0: transfer should be short terminated
- * short_pkt = 1: transfer should not be short terminated
- */
- uint8_t setup_alt_next;
-};
-
-struct musbotg_config_desc {
- struct usb2_config_descriptor confd;
- struct usb2_interface_descriptor ifcd;
- struct usb2_endpoint_descriptor endpd;
-} __packed;
-
-union musbotg_hub_temp {
- uWord wValue;
- struct usb2_port_status ps;
-};
-
-struct musbotg_flags {
- uint8_t change_connect:1;
- uint8_t change_suspend:1;
- uint8_t status_suspend:1; /* set if suspended */
- uint8_t status_vbus:1; /* set if present */
- uint8_t status_bus_reset:1; /* set if reset complete */
- uint8_t status_high_speed:1; /* set if High Speed is selected */
- uint8_t remote_wakeup:1;
- uint8_t self_powered:1;
- uint8_t clocks_off:1;
- uint8_t port_powered:1;
- uint8_t port_enabled:1;
- uint8_t d_pulled_up:1;
-};
-
-struct musbotg_softc {
- struct usb2_bus sc_bus;
- union musbotg_hub_temp sc_hub_temp;
- struct usb2_sw_transfer sc_root_ctrl;
- struct usb2_sw_transfer sc_root_intr;
- struct usb2_hw_ep_profile sc_hw_ep_profile[16];
-
- struct usb2_device *sc_devices[MUSB2_MAX_DEVICES];
- struct resource *sc_io_res;
- struct resource *sc_irq_res;
- void *sc_intr_hdl;
- bus_size_t sc_io_size;
- bus_space_tag_t sc_io_tag;
- bus_space_handle_t sc_io_hdl;
-
- void (*sc_clocks_on) (void *arg);
- void (*sc_clocks_off) (void *arg);
- void *sc_clocks_arg;
-
- uint32_t sc_bounce_buf[(1024 * 3) / 4]; /* bounce buffer */
-
- uint8_t sc_ep_max; /* maximum number of RX and TX
- * endpoints supported */
- uint8_t sc_rt_addr; /* root HUB address */
- uint8_t sc_dv_addr; /* device address */
- uint8_t sc_conf; /* root HUB config */
- uint8_t sc_ep0_busy; /* set if ep0 is busy */
- uint8_t sc_ep0_cmd; /* pending commands */
- uint8_t sc_conf_data; /* copy of hardware register */
-
- uint8_t sc_hub_idata[1];
-
- struct musbotg_flags sc_flags;
-};
-
-/* prototypes */
-
-usb2_error_t musbotg_init(struct musbotg_softc *sc);
-void musbotg_uninit(struct musbotg_softc *sc);
-void musbotg_suspend(struct musbotg_softc *sc);
-void musbotg_resume(struct musbotg_softc *sc);
-void musbotg_interrupt(struct musbotg_softc *sc);
-void musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on);
-
-#endif /* _MUSB2_OTG_H_ */
diff --git a/sys/dev/usb2/controller/musb2_otg_atmelarm.c b/sys/dev/usb2/controller/musb2_otg_atmelarm.c
deleted file mode 100644
index 6477c97..0000000
--- a/sys/dev/usb2/controller/musb2_otg_atmelarm.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/musb2_otg.h>
-
-#include <sys/rman.h>
-
-static device_probe_t musbotg_probe;
-static device_attach_t musbotg_attach;
-static device_detach_t musbotg_detach;
-static device_shutdown_t musbotg_shutdown;
-
-struct musbotg_super_softc {
- struct musbotg_softc sc_otg; /* must be first */
-};
-
-static void
-musbotg_vbus_poll(struct musbotg_super_softc *sc)
-{
- uint8_t vbus_val = 1; /* fake VBUS on - TODO */
-
- /* just forward it */
- musbotg_vbus_interrupt(&sc->sc_otg, vbus_val);
-}
-
-static void
-musbotg_clocks_on(void *arg)
-{
-#if 0
- struct musbotg_super_softc *sc = arg;
-
-#endif
-}
-
-static void
-musbotg_clocks_off(void *arg)
-{
-#if 0
- struct musbotg_super_softc *sc = arg;
-
-#endif
-}
-
-static int
-musbotg_probe(device_t dev)
-{
- device_set_desc(dev, "MUSB OTG integrated USB controller");
- return (0);
-}
-
-static int
-musbotg_attach(device_t dev)
-{
- struct musbotg_super_softc *sc = device_get_softc(dev);
- int err;
- int rid;
-
- /* setup MUSB OTG USB controller interface softc */
- sc->sc_otg.sc_clocks_on = &musbotg_clocks_on;
- sc->sc_otg.sc_clocks_off = &musbotg_clocks_off;
- sc->sc_otg.sc_clocks_arg = sc;
-
- /* initialise some bus fields */
- sc->sc_otg.sc_bus.parent = dev;
- sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices;
- sc->sc_otg.sc_bus.devices_max = MUSB2_MAX_DEVICES;
-
- /* get all DMA memory */
- if (usb2_bus_mem_alloc_all(&sc->sc_otg.sc_bus,
- USB_GET_DMA_TAG(dev), NULL)) {
- return (ENOMEM);
- }
- rid = 0;
- sc->sc_otg.sc_io_res =
- bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
-
- if (!(sc->sc_otg.sc_io_res)) {
- err = ENOMEM;
- goto error;
- }
- sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res);
- sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res);
- sc->sc_otg.sc_io_size = rman_get_size(sc->sc_otg.sc_io_res);
-
- rid = 0;
- sc->sc_otg.sc_irq_res =
- bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
- if (!(sc->sc_otg.sc_irq_res)) {
- goto error;
- }
- sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1);
- if (!(sc->sc_otg.sc_bus.bdev)) {
- goto error;
- }
- device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus);
-
-#if (__FreeBSD_version >= 700031)
- err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (void *)musbotg_interrupt, sc, &sc->sc_otg.sc_intr_hdl);
-#else
- err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- (void *)musbotg_interrupt, sc, &sc->sc_otg.sc_intr_hdl);
-#endif
- if (err) {
- sc->sc_otg.sc_intr_hdl = NULL;
- goto error;
- }
- err = musbotg_init(&sc->sc_otg);
- if (!err) {
- err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev);
- }
- if (err) {
- goto error;
- } else {
- /* poll VBUS one time */
- musbotg_vbus_poll(sc);
- }
- return (0);
-
-error:
- musbotg_detach(dev);
- return (ENXIO);
-}
-
-static int
-musbotg_detach(device_t dev)
-{
- struct musbotg_super_softc *sc = device_get_softc(dev);
- device_t bdev;
- int err;
-
- if (sc->sc_otg.sc_bus.bdev) {
- bdev = sc->sc_otg.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
- /* during module unload there are lots of children leftover */
- device_delete_all_children(dev);
-
- if (sc->sc_otg.sc_irq_res && sc->sc_otg.sc_intr_hdl) {
- /*
- * only call musbotg_uninit() after musbotg_init()
- */
- musbotg_uninit(&sc->sc_otg);
-
- err = bus_teardown_intr(dev, sc->sc_otg.sc_irq_res,
- sc->sc_otg.sc_intr_hdl);
- sc->sc_otg.sc_intr_hdl = NULL;
- }
- /* free IRQ channel, if any */
- if (sc->sc_otg.sc_irq_res) {
- bus_release_resource(dev, SYS_RES_IRQ, 0,
- sc->sc_otg.sc_irq_res);
- sc->sc_otg.sc_irq_res = NULL;
- }
- /* free memory resource, if any */
- if (sc->sc_otg.sc_io_res) {
- bus_release_resource(dev, SYS_RES_MEMORY, 0,
- sc->sc_otg.sc_io_res);
- sc->sc_otg.sc_io_res = NULL;
- }
- usb2_bus_mem_free_all(&sc->sc_otg.sc_bus, NULL);
-
- return (0);
-}
-
-static int
-musbotg_shutdown(device_t dev)
-{
- struct musbotg_super_softc *sc = device_get_softc(dev);
- int err;
-
- err = bus_generic_shutdown(dev);
- if (err)
- return (err);
-
- musbotg_uninit(&sc->sc_otg);
-
- return (0);
-}
-
-static device_method_t musbotg_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, musbotg_probe),
- DEVMETHOD(device_attach, musbotg_attach),
- DEVMETHOD(device_detach, musbotg_detach),
- DEVMETHOD(device_shutdown, musbotg_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t musbotg_driver = {
- "musbotg",
- musbotg_methods,
- sizeof(struct musbotg_super_softc),
-};
-
-static devclass_t musbotg_devclass;
-
-DRIVER_MODULE(musbotg, atmelarm, musbotg_driver, musbotg_devclass, 0, 0);
-MODULE_DEPEND(musbotg, usb2_controller, 1, 1, 1);
-MODULE_DEPEND(musbotg, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/controller/ohci2.c b/sys/dev/usb2/controller/ohci2.c
deleted file mode 100644
index 4c65ea7..0000000
--- a/sys/dev/usb2/controller/ohci2.c
+++ /dev/null
@@ -1,2862 +0,0 @@
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
- * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
- * Copyright (c) 1998 Lennart Augustsson. 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$");
-
-/*
- * 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 <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR ohcidebug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_hub.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/ohci2.h>
-
-#define OHCI_BUS2SC(bus) ((ohci_softc_t *)(((uint8_t *)(bus)) - \
- USB_P2U(&(((ohci_softc_t *)0)->sc_bus))))
-
-#if USB_DEBUG
-static int ohcidebug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ohci, CTLFLAG_RW, 0, "USB ohci");
-SYSCTL_INT(_hw_usb2_ohci, OID_AUTO, debug, CTLFLAG_RW,
- &ohcidebug, 0, "ohci debug level");
-static void ohci_dumpregs(ohci_softc_t *);
-static void ohci_dump_tds(ohci_td_t *);
-static uint8_t ohci_dump_td(ohci_td_t *);
-static void ohci_dump_ed(ohci_ed_t *);
-static uint8_t ohci_dump_itd(ohci_itd_t *);
-static void ohci_dump_itds(ohci_itd_t *);
-
-#endif
-
-#define OBARR(sc) bus_space_barrier((sc)->sc_io_tag, (sc)->sc_io_hdl, 0, (sc)->sc_io_size, \
- BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
-#define OWRITE1(sc, r, x) \
- do { OBARR(sc); bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (r), (x)); } while (0)
-#define OWRITE2(sc, r, x) \
- do { OBARR(sc); bus_space_write_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (r), (x)); } while (0)
-#define OWRITE4(sc, r, x) \
- do { OBARR(sc); bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (r), (x)); } while (0)
-#define OREAD1(sc, r) (OBARR(sc), bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (r)))
-#define OREAD2(sc, r) (OBARR(sc), bus_space_read_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (r)))
-#define OREAD4(sc, r) (OBARR(sc), bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (r)))
-
-#define OHCI_INTR_ENDPT 1
-
-extern struct usb2_bus_methods ohci_bus_methods;
-extern struct usb2_pipe_methods ohci_device_bulk_methods;
-extern struct usb2_pipe_methods ohci_device_ctrl_methods;
-extern struct usb2_pipe_methods ohci_device_intr_methods;
-extern struct usb2_pipe_methods ohci_device_isoc_methods;
-extern struct usb2_pipe_methods ohci_root_ctrl_methods;
-extern struct usb2_pipe_methods ohci_root_intr_methods;
-
-static void ohci_root_ctrl_poll(struct ohci_softc *sc);
-static void ohci_do_poll(struct usb2_bus *bus);
-static void ohci_device_done(struct usb2_xfer *xfer, usb2_error_t error);
-
-static usb2_sw_transfer_func_t ohci_root_intr_done;
-static usb2_sw_transfer_func_t ohci_root_ctrl_done;
-static void ohci_timeout(void *arg);
-static uint8_t ohci_check_transfer(struct usb2_xfer *xfer);
-
-struct ohci_std_temp {
- struct usb2_page_cache *pc;
- ohci_td_t *td;
- ohci_td_t *td_next;
- uint32_t average;
- uint32_t td_flags;
- uint32_t len;
- uint16_t max_frame_size;
- uint8_t shortpkt;
- uint8_t setup_alt_next;
- uint8_t short_frames_ok;
-};
-
-static struct ohci_hcca *
-ohci_get_hcca(ohci_softc_t *sc)
-{
- usb2_pc_cpu_invalidate(&sc->sc_hw.hcca_pc);
- return (sc->sc_hcca_p);
-}
-
-void
-ohci_iterate_hw_softc(struct usb2_bus *bus, usb2_bus_mem_sub_cb_t *cb)
-{
- struct ohci_softc *sc = OHCI_BUS2SC(bus);
- uint32_t i;
-
- cb(bus, &sc->sc_hw.hcca_pc, &sc->sc_hw.hcca_pg,
- sizeof(ohci_hcca_t), OHCI_HCCA_ALIGN);
-
- cb(bus, &sc->sc_hw.ctrl_start_pc, &sc->sc_hw.ctrl_start_pg,
- sizeof(ohci_ed_t), OHCI_ED_ALIGN);
-
- cb(bus, &sc->sc_hw.bulk_start_pc, &sc->sc_hw.bulk_start_pg,
- sizeof(ohci_ed_t), OHCI_ED_ALIGN);
-
- cb(bus, &sc->sc_hw.isoc_start_pc, &sc->sc_hw.isoc_start_pg,
- sizeof(ohci_ed_t), OHCI_ED_ALIGN);
-
- for (i = 0; i != OHCI_NO_EDS; i++) {
- cb(bus, sc->sc_hw.intr_start_pc + i, sc->sc_hw.intr_start_pg + i,
- sizeof(ohci_ed_t), OHCI_ED_ALIGN);
- }
-}
-
-static usb2_error_t
-ohci_controller_init(ohci_softc_t *sc)
-{
- struct usb2_page_search buf_res;
- uint32_t i;
- uint32_t ctl;
- uint32_t ival;
- uint32_t hcr;
- uint32_t fm;
- uint32_t per;
- uint32_t desca;
-
- /* Determine in what context we are running. */
- ctl = OREAD4(sc, OHCI_CONTROL);
- if (ctl & OHCI_IR) {
- /* SMM active, request change */
- DPRINTF("SMM active, request owner change\n");
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_OCR);
- for (i = 0; (i < 100) && (ctl & OHCI_IR); i++) {
- usb2_pause_mtx(NULL, hz / 1000);
- ctl = OREAD4(sc, OHCI_CONTROL);
- }
- if (ctl & OHCI_IR) {
- device_printf(sc->sc_bus.bdev,
- "SMM does not respond, resetting\n");
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
- goto reset;
- }
- } else {
- DPRINTF("cold started\n");
-reset:
- /* controller was cold started */
- usb2_pause_mtx(NULL,
- USB_MS_TO_TICKS(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);
-
- usb2_pause_mtx(NULL,
- USB_MS_TO_TICKS(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) {
- device_printf(sc->sc_bus.bdev, "reset timeout\n");
- return (USB_ERR_IOERROR);
- }
-#if 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 */
- usb2_get_page(&sc->sc_hw.hcca_pc, 0, &buf_res);
- OWRITE4(sc, OHCI_HCCA, buf_res.physaddr);
-
- usb2_get_page(&sc->sc_hw.ctrl_start_pc, 0, &buf_res);
- OWRITE4(sc, OHCI_CONTROL_HEAD_ED, buf_res.physaddr);
-
- usb2_get_page(&sc->sc_hw.bulk_start_pc, 0, &buf_res);
- OWRITE4(sc, OHCI_BULK_HEAD_ED, buf_res.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 */
- usb2_pause_mtx(NULL,
- USB_MS_TO_TICKS(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++) {
- usb2_pause_mtx(NULL,
- USB_MS_TO_TICKS(OHCI_READ_DESC_DELAY));
- sc->sc_noport = OHCI_GET_NDP(OREAD4(sc, OHCI_RH_DESCRIPTOR_A));
- }
-
-#if USB_DEBUG
- if (ohcidebug > 5) {
- ohci_dumpregs(sc);
- }
-#endif
- return (USB_ERR_NORMAL_COMPLETION);
-}
-
-static struct ohci_ed *
-ohci_init_ed(struct usb2_page_cache *pc)
-{
- struct usb2_page_search buf_res;
- struct ohci_ed *ed;
-
- usb2_get_page(pc, 0, &buf_res);
-
- ed = buf_res.buffer;
-
- ed->ed_self = htole32(buf_res.physaddr);
- ed->ed_flags = htole32(OHCI_ED_SKIP);
- ed->page_cache = pc;
-
- return (ed);
-}
-
-usb2_error_t
-ohci_init(ohci_softc_t *sc)
-{
- struct usb2_page_search buf_res;
- uint16_t i;
- uint16_t bit;
- uint16_t x;
- uint16_t y;
-
- DPRINTF("start\n");
-
- sc->sc_eintrs = OHCI_NORMAL_INTRS;
-
- /*
- * Setup all ED's
- */
-
- sc->sc_ctrl_p_last =
- ohci_init_ed(&sc->sc_hw.ctrl_start_pc);
-
- sc->sc_bulk_p_last =
- ohci_init_ed(&sc->sc_hw.bulk_start_pc);
-
- sc->sc_isoc_p_last =
- ohci_init_ed(&sc->sc_hw.isoc_start_pc);
-
- for (i = 0; i != OHCI_NO_EDS; i++) {
- sc->sc_intr_p_last[i] =
- ohci_init_ed(sc->sc_hw.intr_start_pc + i);
- }
-
- /*
- * the QHs are arranged to give poll intervals that are
- * powers of 2 times 1ms
- */
- bit = OHCI_NO_EDS / 2;
- while (bit) {
- x = bit;
- while (x & bit) {
- ohci_ed_t *ed_x;
- ohci_ed_t *ed_y;
-
- y = (x ^ bit) | (bit / 2);
-
- /*
- * the next QH has half the poll interval
- */
- ed_x = sc->sc_intr_p_last[x];
- ed_y = sc->sc_intr_p_last[y];
-
- ed_x->next = NULL;
- ed_x->ed_next = ed_y->ed_self;
-
- x++;
- }
- bit >>= 1;
- }
-
- if (1) {
-
- ohci_ed_t *ed_int;
- ohci_ed_t *ed_isc;
-
- ed_int = sc->sc_intr_p_last[0];
- ed_isc = sc->sc_isoc_p_last;
-
- /* the last (1ms) QH */
- ed_int->next = ed_isc;
- ed_int->ed_next = ed_isc->ed_self;
- }
- usb2_get_page(&sc->sc_hw.hcca_pc, 0, &buf_res);
-
- sc->sc_hcca_p = buf_res.buffer;
-
- /*
- * 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_p->hcca_interrupt_table[i] =
- sc->sc_intr_p_last[i | (OHCI_NO_EDS / 2)]->ed_self;
- }
- /* flush all cache into memory */
-
- usb2_bus_mem_flush_all(&sc->sc_bus, &ohci_iterate_hw_softc);
-
- /* set up the bus struct */
- sc->sc_bus.methods = &ohci_bus_methods;
-
- usb2_callout_init_mtx(&sc->sc_tmo_rhsc, &sc->sc_bus.bus_mtx, 0);
-
-#if USB_DEBUG
- if (ohcidebug > 15) {
- for (i = 0; i != OHCI_NO_EDS; i++) {
- printf("ed#%d ", i);
- ohci_dump_ed(sc->sc_intr_p_last[i]);
- }
- printf("iso ");
- ohci_dump_ed(sc->sc_isoc_p_last);
- }
-#endif
-
- sc->sc_bus.usbrev = USB_REV_1_0;
-
- if (ohci_controller_init(sc)) {
- return (USB_ERR_INVAL);
- } else {
- /* catch any lost interrupts */
- ohci_do_poll(&sc->sc_bus);
- return (USB_ERR_NORMAL_COMPLETION);
- }
-}
-
-/*
- * shut down the controller when the system is going down
- */
-void
-ohci_detach(struct ohci_softc *sc)
-{
- USB_BUS_LOCK(&sc->sc_bus);
-
- usb2_callout_stop(&sc->sc_tmo_rhsc);
-
- OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-
- /* XXX let stray task complete */
- usb2_pause_mtx(NULL, hz / 20);
-
- usb2_callout_drain(&sc->sc_tmo_rhsc);
-}
-
-/* NOTE: suspend/resume is called from
- * interrupt context and cannot sleep!
- */
-void
-ohci_suspend(ohci_softc_t *sc)
-{
- uint32_t ctl;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
-#if USB_DEBUG
- DPRINTF("\n");
- if (ohcidebug > 2) {
- ohci_dumpregs(sc);
- }
-#endif
-
- 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);
-
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_WAIT));
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-void
-ohci_resume(ohci_softc_t *sc)
-{
- uint32_t ctl;
-
-#if USB_DEBUG
- DPRINTF("\n");
- if (ohcidebug > 2) {
- ohci_dumpregs(sc);
- }
-#endif
- /* some broken BIOSes never initialize the Controller chip */
- ohci_controller_init(sc);
-
- USB_BUS_LOCK(&sc->sc_bus);
- 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);
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_DELAY));
- ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_RECOVERY));
- sc->sc_control = sc->sc_intre = 0;
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-
- /* catch any lost interrupts */
- ohci_do_poll(&sc->sc_bus);
-}
-
-#if USB_DEBUG
-static void
-ohci_dumpregs(ohci_softc_t *sc)
-{
- struct ohci_hcca *hcca;
-
- 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)));
-
- hcca = ohci_get_hcca(sc);
-
- DPRINTF(" HCCA: frame_number=0x%04x done_head=0x%08x\n",
- le32toh(hcca->hcca_frame_number),
- le32toh(hcca->hcca_done_head));
-}
-static void
-ohci_dump_tds(ohci_td_t *std)
-{
- for (; std; std = std->obj_next) {
- if (ohci_dump_td(std)) {
- break;
- }
- }
-}
-
-static uint8_t
-ohci_dump_td(ohci_td_t *std)
-{
- uint32_t td_flags;
- uint8_t temp;
-
- usb2_pc_cpu_invalidate(std->page_cache);
-
- td_flags = le32toh(std->td_flags);
- temp = (std->td_next == 0);
-
- printf("TD(%p) at 0x%08x: %s%s%s%s%s delay=%d ec=%d "
- "cc=%d\ncbp=0x%08x next=0x%08x be=0x%08x\n",
- std, le32toh(std->td_self),
- (td_flags & OHCI_TD_R) ? "-R" : "",
- (td_flags & OHCI_TD_OUT) ? "-OUT" : "",
- (td_flags & OHCI_TD_IN) ? "-IN" : "",
- ((td_flags & OHCI_TD_TOGGLE_MASK) == OHCI_TD_TOGGLE_1) ? "-TOG1" : "",
- ((td_flags & OHCI_TD_TOGGLE_MASK) == OHCI_TD_TOGGLE_0) ? "-TOG0" : "",
- OHCI_TD_GET_DI(td_flags),
- OHCI_TD_GET_EC(td_flags),
- OHCI_TD_GET_CC(td_flags),
- le32toh(std->td_cbp),
- le32toh(std->td_next),
- le32toh(std->td_be));
-
- return (temp);
-}
-
-static uint8_t
-ohci_dump_itd(ohci_itd_t *sitd)
-{
- uint32_t itd_flags;
- uint16_t i;
- uint8_t temp;
-
- usb2_pc_cpu_invalidate(sitd->page_cache);
-
- itd_flags = le32toh(sitd->itd_flags);
- temp = (sitd->itd_next == 0);
-
- printf("ITD(%p) at 0x%08x: sf=%d di=%d fc=%d cc=%d\n"
- "bp0=0x%08x next=0x%08x be=0x%08x\n",
- sitd, le32toh(sitd->itd_self),
- OHCI_ITD_GET_SF(itd_flags),
- OHCI_ITD_GET_DI(itd_flags),
- OHCI_ITD_GET_FC(itd_flags),
- OHCI_ITD_GET_CC(itd_flags),
- le32toh(sitd->itd_bp0),
- le32toh(sitd->itd_next),
- le32toh(sitd->itd_be));
- for (i = 0; i < OHCI_ITD_NOFFSET; i++) {
- printf("offs[%d]=0x%04x ", i,
- (uint32_t)le16toh(sitd->itd_offset[i]));
- }
- printf("\n");
-
- return (temp);
-}
-
-static void
-ohci_dump_itds(ohci_itd_t *sitd)
-{
- for (; sitd; sitd = sitd->obj_next) {
- if (ohci_dump_itd(sitd)) {
- break;
- }
- }
-}
-
-static void
-ohci_dump_ed(ohci_ed_t *sed)
-{
- uint32_t ed_flags;
- uint32_t ed_headp;
-
- usb2_pc_cpu_invalidate(sed->page_cache);
-
- ed_flags = le32toh(sed->ed_flags);
- ed_headp = le32toh(sed->ed_headp);
-
- printf("ED(%p) at 0x%08x: addr=%d endpt=%d maxp=%d flags=%s%s%s%s%s\n"
- "tailp=0x%08x headflags=%s%s headp=0x%08x nexted=0x%08x\n",
- sed, le32toh(sed->ed_self),
- OHCI_ED_GET_FA(ed_flags),
- OHCI_ED_GET_EN(ed_flags),
- OHCI_ED_GET_MAXP(ed_flags),
- (ed_flags & OHCI_ED_DIR_OUT) ? "-OUT" : "",
- (ed_flags & OHCI_ED_DIR_IN) ? "-IN" : "",
- (ed_flags & OHCI_ED_SPEED) ? "-LOWSPEED" : "",
- (ed_flags & OHCI_ED_SKIP) ? "-SKIP" : "",
- (ed_flags & OHCI_ED_FORMAT_ISO) ? "-ISO" : "",
- le32toh(sed->ed_tailp),
- (ed_headp & OHCI_HALTED) ? "-HALTED" : "",
- (ed_headp & OHCI_TOGGLECARRY) ? "-CARRY" : "",
- le32toh(sed->ed_headp),
- le32toh(sed->ed_next));
-}
-
-#endif
-
-static void
-ohci_transfer_intr_enqueue(struct usb2_xfer *xfer)
-{
- /* check for early completion */
- if (ohci_check_transfer(xfer)) {
- return;
- }
- /* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
-
- /* start timeout, if any */
- if (xfer->timeout != 0) {
- usb2_transfer_timeout_ms(xfer, &ohci_timeout, xfer->timeout);
- }
-}
-
-#define OHCI_APPEND_QH(sed,last) (last) = _ohci_append_qh(sed,last)
-static ohci_ed_t *
-_ohci_append_qh(ohci_ed_t *sed, ohci_ed_t *last)
-{
- DPRINTFN(11, "%p to %p\n", sed, last);
-
- if (sed->prev != NULL) {
- /* should not happen */
- DPRINTFN(0, "ED already linked!\n");
- return (last);
- }
- /* (sc->sc_bus.bus_mtx) must be locked */
-
- sed->next = last->next;
- sed->ed_next = last->ed_next;
- sed->ed_tailp = 0;
-
- sed->prev = last;
-
- usb2_pc_cpu_flush(sed->page_cache);
-
- /*
- * the last->next->prev is never followed: sed->next->prev = sed;
- */
-
- last->next = sed;
- last->ed_next = sed->ed_self;
-
- usb2_pc_cpu_flush(last->page_cache);
-
- return (sed);
-}
-
-#define OHCI_REMOVE_QH(sed,last) (last) = _ohci_remove_qh(sed,last)
-static ohci_ed_t *
-_ohci_remove_qh(ohci_ed_t *sed, ohci_ed_t *last)
-{
- DPRINTFN(11, "%p from %p\n", sed, last);
-
- /* (sc->sc_bus.bus_mtx) must be locked */
-
- /* only remove if not removed from a queue */
- if (sed->prev) {
-
- sed->prev->next = sed->next;
- sed->prev->ed_next = sed->ed_next;
-
- usb2_pc_cpu_flush(sed->prev->page_cache);
-
- if (sed->next) {
- sed->next->prev = sed->prev;
- usb2_pc_cpu_flush(sed->next->page_cache);
- }
- last = ((last == sed) ? sed->prev : last);
-
- sed->prev = 0;
-
- usb2_pc_cpu_flush(sed->page_cache);
- }
- return (last);
-}
-
-static void
-ohci_isoc_done(struct usb2_xfer *xfer)
-{
- uint8_t nframes;
- uint32_t *plen = xfer->frlengths;
- volatile uint16_t *olen;
- uint16_t len = 0;
- ohci_itd_t *td = xfer->td_transfer_first;
-
- while (1) {
- if (td == NULL) {
- panic("%s:%d: out of TD's\n",
- __FUNCTION__, __LINE__);
- }
-#if USB_DEBUG
- if (ohcidebug > 5) {
- DPRINTF("isoc TD\n");
- ohci_dump_itd(td);
- }
-#endif
- usb2_pc_cpu_invalidate(td->page_cache);
-
- nframes = td->frames;
- olen = &td->itd_offset[0];
-
- if (nframes > 8) {
- nframes = 8;
- }
- while (nframes--) {
- len = le16toh(*olen);
-
- if ((len >> 12) == OHCI_CC_NOT_ACCESSED) {
- len = 0;
- } else {
- len &= ((1 << 12) - 1);
- }
-
- if (len > *plen) {
- len = 0;/* invalid length */
- }
- *plen = len;
- plen++;
- olen++;
- }
-
- if (((void *)td) == xfer->td_transfer_last) {
- break;
- }
- td = td->obj_next;
- }
-
- xfer->aframes = xfer->nframes;
- ohci_device_done(xfer, USB_ERR_NORMAL_COMPLETION);
-}
-
-#if USB_DEBUG
-static const char *const
- 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
-
-static usb2_error_t
-ohci_non_isoc_done_sub(struct usb2_xfer *xfer)
-{
- ohci_td_t *td;
- ohci_td_t *td_alt_next;
- uint32_t temp;
- uint32_t phy_start;
- uint32_t phy_end;
- uint32_t td_flags;
- uint16_t cc;
-
- td = xfer->td_transfer_cache;
- td_alt_next = td->alt_next;
- td_flags = 0;
-
- if (xfer->aframes != xfer->nframes) {
- xfer->frlengths[xfer->aframes] = 0;
- }
- while (1) {
-
- usb2_pc_cpu_invalidate(td->page_cache);
- phy_start = le32toh(td->td_cbp);
- td_flags = le32toh(td->td_flags);
- cc = OHCI_TD_GET_CC(td_flags);
-
- if (phy_start) {
- /*
- * short transfer - compute the number of remaining
- * bytes in the hardware buffer:
- */
- phy_end = le32toh(td->td_be);
- temp = (OHCI_PAGE(phy_start ^ phy_end) ?
- (OHCI_PAGE_SIZE + 1) : 0x0001);
- temp += OHCI_PAGE_OFFSET(phy_end);
- temp -= OHCI_PAGE_OFFSET(phy_start);
-
- if (temp > td->len) {
- /* guard against corruption */
- cc = OHCI_CC_STALL;
- } else if (xfer->aframes != xfer->nframes) {
- /*
- * Sum up total transfer length
- * in "frlengths[]":
- */
- xfer->frlengths[xfer->aframes] += td->len - temp;
- }
- } else {
- if (xfer->aframes != xfer->nframes) {
- /* transfer was complete */
- xfer->frlengths[xfer->aframes] += td->len;
- }
- }
- /* Check for last transfer */
- if (((void *)td) == xfer->td_transfer_last) {
- td = NULL;
- break;
- }
- /* Check transfer status */
- if (cc) {
- /* the transfer is finished */
- td = NULL;
- break;
- }
- /* Check for short transfer */
- if (phy_start) {
- if (xfer->flags_int.short_frames_ok) {
- /* follow alt next */
- td = td->alt_next;
- } else {
- /* the transfer is finished */
- td = NULL;
- }
- break;
- }
- td = td->obj_next;
-
- if (td->alt_next != td_alt_next) {
- /* this USB frame is complete */
- break;
- }
- }
-
- /* update transfer cache */
-
- xfer->td_transfer_cache = td;
-
- DPRINTFN(16, "error cc=%d (%s)\n",
- cc, ohci_cc_strs[cc]);
-
- return ((cc == 0) ? USB_ERR_NORMAL_COMPLETION :
- (cc == OHCI_CC_STALL) ? USB_ERR_STALLED : USB_ERR_IOERROR);
-}
-
-static void
-ohci_non_isoc_done(struct usb2_xfer *xfer)
-{
- usb2_error_t err = 0;
-
- DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
- xfer, xfer->pipe);
-
-#if USB_DEBUG
- if (ohcidebug > 10) {
- ohci_dump_tds(xfer->td_transfer_first);
- }
-#endif
-
- /* reset scanner */
-
- xfer->td_transfer_cache = xfer->td_transfer_first;
-
- if (xfer->flags_int.control_xfr) {
-
- if (xfer->flags_int.control_hdr) {
-
- err = ohci_non_isoc_done_sub(xfer);
- }
- xfer->aframes = 1;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
- while (xfer->aframes != xfer->nframes) {
-
- err = ohci_non_isoc_done_sub(xfer);
- xfer->aframes++;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- err = ohci_non_isoc_done_sub(xfer);
- }
-done:
- ohci_device_done(xfer, err);
-}
-
-/*------------------------------------------------------------------------*
- * ohci_check_transfer_sub
- *------------------------------------------------------------------------*/
-static void
-ohci_check_transfer_sub(struct usb2_xfer *xfer)
-{
- ohci_td_t *td;
- ohci_ed_t *ed;
- uint32_t phy_start;
- uint32_t td_flags;
- uint32_t td_next;
- uint16_t cc;
-
- td = xfer->td_transfer_cache;
-
- while (1) {
-
- usb2_pc_cpu_invalidate(td->page_cache);
- phy_start = le32toh(td->td_cbp);
- td_flags = le32toh(td->td_flags);
- td_next = le32toh(td->td_next);
-
- /* Check for last transfer */
- if (((void *)td) == xfer->td_transfer_last) {
- /* the transfer is finished */
- td = NULL;
- break;
- }
- /* Check transfer status */
- cc = OHCI_TD_GET_CC(td_flags);
- if (cc) {
- /* the transfer is finished */
- td = NULL;
- break;
- }
- /*
- * Check if we reached the last packet
- * or if there is a short packet:
- */
-
- if (((td_next & (~0xF)) == OHCI_TD_NEXT_END) || phy_start) {
- /* follow alt next */
- td = td->alt_next;
- break;
- }
- td = td->obj_next;
- }
-
- /* update transfer cache */
-
- xfer->td_transfer_cache = td;
-
- if (td) {
-
- ed = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- ed->ed_headp = td->td_self;
- usb2_pc_cpu_flush(ed->page_cache);
-
- DPRINTFN(13, "xfer=%p following alt next\n", xfer);
- }
-}
-
-/*------------------------------------------------------------------------*
- * ohci_check_transfer
- *
- * Return values:
- * 0: USB transfer is not finished
- * Else: USB transfer is finished
- *------------------------------------------------------------------------*/
-static uint8_t
-ohci_check_transfer(struct usb2_xfer *xfer)
-{
- ohci_ed_t *ed;
- uint32_t ed_flags;
- uint32_t ed_headp;
- uint32_t ed_tailp;
-
- DPRINTFN(13, "xfer=%p checking transfer\n", xfer);
-
- ed = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- usb2_pc_cpu_invalidate(ed->page_cache);
- ed_flags = le32toh(ed->ed_flags);
- ed_headp = le32toh(ed->ed_headp);
- ed_tailp = le32toh(ed->ed_tailp);
-
- if ((ed_flags & OHCI_ED_SKIP) ||
- (ed_headp & OHCI_HALTED) ||
- (((ed_headp ^ ed_tailp) & (~0xF)) == 0)) {
- if (xfer->pipe->methods == &ohci_device_isoc_methods) {
- /* isochronous transfer */
- ohci_isoc_done(xfer);
- } else {
- if (xfer->flags_int.short_frames_ok) {
- ohci_check_transfer_sub(xfer);
- if (xfer->td_transfer_cache) {
- /* not finished yet */
- return (0);
- }
- }
- /* store data-toggle */
- if (ed_headp & OHCI_TOGGLECARRY) {
- xfer->pipe->toggle_next = 1;
- } else {
- xfer->pipe->toggle_next = 0;
- }
-
- /* non-isochronous transfer */
- ohci_non_isoc_done(xfer);
- }
- return (1);
- }
- DPRINTFN(13, "xfer=%p is still active\n", xfer);
- return (0);
-}
-
-static void
-ohci_rhsc_enable(ohci_softc_t *sc)
-{
- DPRINTFN(5, "\n");
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- sc->sc_eintrs |= OHCI_RHSC;
- OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC);
-
- /* acknowledge any RHSC interrupt */
- OWRITE4(sc, OHCI_INTERRUPT_STATUS, OHCI_RHSC);
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &ohci_root_intr_done);
-}
-
-static void
-ohci_interrupt_poll(ohci_softc_t *sc)
-{
- struct usb2_xfer *xfer;
-
-repeat:
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
- /*
- * check if transfer is transferred
- */
- if (ohci_check_transfer(xfer)) {
- /* queue has been modified */
- goto repeat;
- }
- }
-}
-
-/*------------------------------------------------------------------------*
- * ohci_interrupt - OHCI interrupt handler
- *
- * NOTE: Do not access "sc->sc_bus.bdev" inside the interrupt handler,
- * hence the interrupt handler will be setup before "sc->sc_bus.bdev"
- * is present !
- *------------------------------------------------------------------------*/
-void
-ohci_interrupt(ohci_softc_t *sc)
-{
- struct ohci_hcca *hcca;
- uint32_t status;
- uint32_t done;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- hcca = ohci_get_hcca(sc);
-
- DPRINTFN(16, "real interrupt\n");
-
-#if USB_DEBUG
- if (ohcidebug > 15) {
- ohci_dumpregs(sc);
- }
-#endif
-
- done = le32toh(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) {
- status = 0;
-
- if (done & ~OHCI_DONE_INTRS) {
- status |= OHCI_WDH;
- }
- if (done & OHCI_DONE_INTRS) {
- status |= OREAD4(sc, OHCI_INTERRUPT_STATUS);
- }
- hcca->hcca_done_head = 0;
-
- usb2_pc_cpu_flush(&sc->sc_hw.hcca_pc);
- } else {
- status = OREAD4(sc, OHCI_INTERRUPT_STATUS) & ~OHCI_WDH;
- }
-
- status &= ~OHCI_MIE;
- if (status == 0) {
- /*
- * nothing to be done (PCI shared
- * interrupt)
- */
- goto done;
- }
- OWRITE4(sc, OHCI_INTERRUPT_STATUS, status); /* Acknowledge */
-
- status &= sc->sc_eintrs;
- if (status == 0) {
- goto done;
- }
- if (status & (OHCI_SO | OHCI_RD | OHCI_UE | OHCI_RHSC)) {
-#if 0
- if (status & OHCI_SO) {
- /* XXX do what */
- }
-#endif
- if (status & OHCI_RD) {
- printf("%s: resume detect\n", __FUNCTION__);
- /* XXX process resume detect */
- }
- if (status & OHCI_UE) {
- printf("%s: unrecoverable error, "
- "controller halted\n", __FUNCTION__);
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
- /* XXX what else */
- }
- if (status & OHCI_RHSC) {
- /*
- * Disable RHSC interrupt for now, because it will be
- * on until the port has been reset.
- */
- sc->sc_eintrs &= ~OHCI_RHSC;
- OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_RHSC);
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &ohci_root_intr_done);
-
- /* do not allow RHSC interrupts > 1 per second */
- usb2_callout_reset(&sc->sc_tmo_rhsc, hz,
- (void *)&ohci_rhsc_enable, sc);
- }
- }
- status &= ~(OHCI_RHSC | OHCI_WDH | OHCI_SO);
- if (status != 0) {
- /* Block unprocessed interrupts. XXX */
- OWRITE4(sc, OHCI_INTERRUPT_DISABLE, status);
- sc->sc_eintrs &= ~status;
- printf("%s: blocking intrs 0x%x\n",
- __FUNCTION__, status);
- }
- /* poll all the USB transfers */
- ohci_interrupt_poll(sc);
-
-done:
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-/*
- * called when a request does not complete
- */
-static void
-ohci_timeout(void *arg)
-{
- struct usb2_xfer *xfer = arg;
-
- DPRINTF("xfer=%p\n", xfer);
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- /* transfer is transferred */
- ohci_device_done(xfer, USB_ERR_TIMEOUT);
-}
-
-static void
-ohci_do_poll(struct usb2_bus *bus)
-{
- struct ohci_softc *sc = OHCI_BUS2SC(bus);
-
- USB_BUS_LOCK(&sc->sc_bus);
- ohci_interrupt_poll(sc);
- ohci_root_ctrl_poll(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-static void
-ohci_setup_standard_chain_sub(struct ohci_std_temp *temp)
-{
- struct usb2_page_search buf_res;
- ohci_td_t *td;
- ohci_td_t *td_next;
- ohci_td_t *td_alt_next;
- uint32_t buf_offset;
- uint32_t average;
- uint32_t len_old;
- uint8_t shortpkt_old;
- uint8_t precompute;
-
- td_alt_next = NULL;
- buf_offset = 0;
- shortpkt_old = temp->shortpkt;
- len_old = temp->len;
- precompute = 1;
-
- /* software is used to detect short incoming transfers */
-
- if ((temp->td_flags & htole32(OHCI_TD_DP_MASK)) == htole32(OHCI_TD_IN)) {
- temp->td_flags |= htole32(OHCI_TD_R);
- } else {
- temp->td_flags &= ~htole32(OHCI_TD_R);
- }
-
-restart:
-
- td = temp->td;
- td_next = temp->td_next;
-
- while (1) {
-
- if (temp->len == 0) {
-
- if (temp->shortpkt) {
- break;
- }
- /* send a Zero Length Packet, ZLP, last */
-
- temp->shortpkt = 1;
- average = 0;
-
- } else {
-
- average = temp->average;
-
- if (temp->len < average) {
- if (temp->len % temp->max_frame_size) {
- temp->shortpkt = 1;
- }
- average = temp->len;
- }
- }
-
- if (td_next == NULL) {
- panic("%s: out of OHCI transfer descriptors!", __FUNCTION__);
- }
- /* get next TD */
-
- td = td_next;
- td_next = td->obj_next;
-
- /* check if we are pre-computing */
-
- if (precompute) {
-
- /* update remaining length */
-
- temp->len -= average;
-
- continue;
- }
- /* fill out current TD */
- td->td_flags = temp->td_flags;
-
- /* the next TD uses TOGGLE_CARRY */
- temp->td_flags &= ~htole32(OHCI_TD_TOGGLE_MASK);
-
- if (average == 0) {
-
- td->td_cbp = 0;
- td->td_be = ~0;
- td->len = 0;
-
- } else {
-
- usb2_get_page(temp->pc, buf_offset, &buf_res);
- td->td_cbp = htole32(buf_res.physaddr);
- buf_offset += (average - 1);
-
- usb2_get_page(temp->pc, buf_offset, &buf_res);
- td->td_be = htole32(buf_res.physaddr);
- buf_offset++;
-
- td->len = average;
-
- /* update remaining length */
-
- temp->len -= average;
- }
-
- if ((td_next == td_alt_next) && temp->setup_alt_next) {
- /* we need to receive these frames one by one ! */
- td->td_flags &= htole32(~OHCI_TD_INTR_MASK);
- td->td_flags |= htole32(OHCI_TD_SET_DI(1));
- td->td_next = htole32(OHCI_TD_NEXT_END);
- } else {
- if (td_next) {
- /* link the current TD with the next one */
- td->td_next = td_next->td_self;
- }
- }
-
- td->alt_next = td_alt_next;
-
- usb2_pc_cpu_flush(td->page_cache);
- }
-
- if (precompute) {
- precompute = 0;
-
- /* setup alt next pointer, if any */
- if (temp->short_frames_ok) {
- if (temp->setup_alt_next) {
- td_alt_next = td_next;
- }
- } else {
- /* we use this field internally */
- td_alt_next = td_next;
- }
-
- /* restore */
- temp->shortpkt = shortpkt_old;
- temp->len = len_old;
- goto restart;
- }
- temp->td = td;
- temp->td_next = td_next;
-}
-
-static void
-ohci_setup_standard_chain(struct usb2_xfer *xfer, ohci_ed_t **ed_last)
-{
- struct ohci_std_temp temp;
- struct usb2_pipe_methods *methods;
- ohci_ed_t *ed;
- ohci_td_t *td;
- uint32_t ed_flags;
- uint32_t x;
-
- DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
- xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
-
- temp.average = xfer->max_usb2_frame_size;
- temp.max_frame_size = xfer->max_frame_size;
-
- /* toggle the DMA set we are using */
- xfer->flags_int.curr_dma_set ^= 1;
-
- /* get next DMA set */
- td = xfer->td_start[xfer->flags_int.curr_dma_set];
-
- xfer->td_transfer_first = td;
- xfer->td_transfer_cache = td;
-
- temp.td = NULL;
- temp.td_next = td;
- temp.setup_alt_next = xfer->flags_int.short_frames_ok;
- temp.short_frames_ok = xfer->flags_int.short_frames_ok;
-
- methods = xfer->pipe->methods;
-
- /* check if we should prepend a setup message */
-
- if (xfer->flags_int.control_xfr) {
- if (xfer->flags_int.control_hdr) {
-
- temp.td_flags = htole32(OHCI_TD_SETUP | OHCI_TD_NOCC |
- OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR);
-
- temp.len = xfer->frlengths[0];
- temp.pc = xfer->frbuffers + 0;
- temp.shortpkt = temp.len ? 1 : 0;
-
- ohci_setup_standard_chain_sub(&temp);
-
- /*
- * XXX assume that the setup message is
- * contained within one USB packet:
- */
- xfer->pipe->toggle_next = 1;
- }
- x = 1;
- } else {
- x = 0;
- }
- temp.td_flags = htole32(OHCI_TD_NOCC | OHCI_TD_NOINTR);
-
- /* set data toggle */
-
- if (xfer->pipe->toggle_next) {
- temp.td_flags |= htole32(OHCI_TD_TOGGLE_1);
- } else {
- temp.td_flags |= htole32(OHCI_TD_TOGGLE_0);
- }
-
- /* set endpoint direction */
-
- if (UE_GET_DIR(xfer->endpoint) == UE_DIR_IN) {
- temp.td_flags |= htole32(OHCI_TD_IN);
- } else {
- temp.td_flags |= htole32(OHCI_TD_OUT);
- }
-
- while (x != xfer->nframes) {
-
- /* DATA0 / DATA1 message */
-
- temp.len = xfer->frlengths[x];
- temp.pc = xfer->frbuffers + x;
-
- x++;
-
- if (x == xfer->nframes) {
- temp.setup_alt_next = 0;
- }
- if (temp.len == 0) {
-
- /* make sure that we send an USB packet */
-
- temp.shortpkt = 0;
-
- } else {
-
- /* regular data transfer */
-
- temp.shortpkt = (xfer->flags.force_short_xfer) ? 0 : 1;
- }
-
- ohci_setup_standard_chain_sub(&temp);
- }
-
- /* check if we should append a status stage */
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- /*
- * Send a DATA1 message and invert the current endpoint
- * direction.
- */
-
- /* set endpoint direction and data toggle */
-
- if (UE_GET_DIR(xfer->endpoint) == UE_DIR_IN) {
- temp.td_flags = htole32(OHCI_TD_OUT |
- OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1));
- } else {
- temp.td_flags = htole32(OHCI_TD_IN |
- OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1));
- }
-
- temp.len = 0;
- temp.pc = NULL;
- temp.shortpkt = 0;
-
- ohci_setup_standard_chain_sub(&temp);
- }
- td = temp.td;
-
- td->td_next = htole32(OHCI_TD_NEXT_END);
- td->td_flags &= ~htole32(OHCI_TD_INTR_MASK);
- td->td_flags |= htole32(OHCI_TD_SET_DI(1));
-
- usb2_pc_cpu_flush(td->page_cache);
-
- /* must have at least one frame! */
-
- xfer->td_transfer_last = td;
-
-#if USB_DEBUG
- if (ohcidebug > 8) {
- DPRINTF("nexttog=%d; data before transfer:\n",
- xfer->pipe->toggle_next);
- ohci_dump_tds(xfer->td_transfer_first);
- }
-#endif
-
- ed = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- ed_flags = (OHCI_ED_SET_FA(xfer->address) |
- OHCI_ED_SET_EN(UE_GET_ADDR(xfer->endpoint)) |
- OHCI_ED_SET_MAXP(xfer->max_frame_size));
-
- ed_flags |= (OHCI_ED_FORMAT_GEN | OHCI_ED_DIR_TD);
-
- if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
- ed_flags |= OHCI_ED_SPEED;
- }
- ed->ed_flags = htole32(ed_flags);
-
- td = xfer->td_transfer_first;
-
- ed->ed_headp = td->td_self;
-
- if (xfer->xroot->udev->pwr_save.suspended == 0) {
- /* the append function will flush the endpoint descriptor */
- OHCI_APPEND_QH(ed, *ed_last);
-
- if (methods == &ohci_device_bulk_methods) {
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
-
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
- }
- if (methods == &ohci_device_ctrl_methods) {
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
-
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
- }
- } else {
- usb2_pc_cpu_flush(ed->page_cache);
- }
-}
-
-static void
-ohci_root_intr_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
- uint32_t hstatus;
- uint16_t i;
- uint16_t m;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_PRE_DATA) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- ohci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* setup buffer */
- std->ptr = sc->sc_hub_idata;
- std->len = sizeof(sc->sc_hub_idata);
-
- /* clear any old interrupt data */
- bzero(sc->sc_hub_idata, sizeof(sc->sc_hub_idata));
-
- hstatus = OREAD4(sc, OHCI_RH_STATUS);
- DPRINTF("sc=%p xfer=%p hstatus=0x%08x\n",
- sc, xfer, hstatus);
-
- /* set bits */
- m = (sc->sc_noport + 1);
- if (m > (8 * sizeof(sc->sc_hub_idata))) {
- m = (8 * sizeof(sc->sc_hub_idata));
- }
- for (i = 1; i < m; i++) {
- /* pick out CHANGE bits from the status register */
- if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16) {
- sc->sc_hub_idata[i / 8] |= 1 << (i % 8);
- DPRINTF("port %d changed\n", i);
- }
- }
-done:
- return;
-}
-
-/* NOTE: "done" can be run two times in a row,
- * from close and from interrupt
- */
-static void
-ohci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
-{
- struct usb2_pipe_methods *methods = xfer->pipe->methods;
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
- ohci_ed_t *ed;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
-
- DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
- xfer, xfer->pipe, error);
-
- ed = xfer->qh_start[xfer->flags_int.curr_dma_set];
- if (ed) {
- usb2_pc_cpu_invalidate(ed->page_cache);
- }
- if (methods == &ohci_device_bulk_methods) {
- OHCI_REMOVE_QH(ed, sc->sc_bulk_p_last);
- }
- if (methods == &ohci_device_ctrl_methods) {
- OHCI_REMOVE_QH(ed, sc->sc_ctrl_p_last);
- }
- if (methods == &ohci_device_intr_methods) {
- OHCI_REMOVE_QH(ed, sc->sc_intr_p_last[xfer->qh_pos]);
- }
- if (methods == &ohci_device_isoc_methods) {
- OHCI_REMOVE_QH(ed, sc->sc_isoc_p_last);
- }
- xfer->td_transfer_first = NULL;
- xfer->td_transfer_last = NULL;
-
- /* dequeue transfer and start next transfer */
- usb2_transfer_done(xfer, error);
-}
-
-/*------------------------------------------------------------------------*
- * ohci bulk support
- *------------------------------------------------------------------------*/
-static void
-ohci_device_bulk_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ohci_device_bulk_close(struct usb2_xfer *xfer)
-{
- ohci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-ohci_device_bulk_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ohci_device_bulk_start(struct usb2_xfer *xfer)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
-
- /* setup TD's and QH */
- ohci_setup_standard_chain(xfer, &sc->sc_bulk_p_last);
-
- /* put transfer on interrupt queue */
- ohci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods ohci_device_bulk_methods =
-{
- .open = ohci_device_bulk_open,
- .close = ohci_device_bulk_close,
- .enter = ohci_device_bulk_enter,
- .start = ohci_device_bulk_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * ohci control support
- *------------------------------------------------------------------------*/
-static void
-ohci_device_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ohci_device_ctrl_close(struct usb2_xfer *xfer)
-{
- ohci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-ohci_device_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ohci_device_ctrl_start(struct usb2_xfer *xfer)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
-
- /* setup TD's and QH */
- ohci_setup_standard_chain(xfer, &sc->sc_ctrl_p_last);
-
- /* put transfer on interrupt queue */
- ohci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods ohci_device_ctrl_methods =
-{
- .open = ohci_device_ctrl_open,
- .close = ohci_device_ctrl_close,
- .enter = ohci_device_ctrl_enter,
- .start = ohci_device_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * ohci interrupt support
- *------------------------------------------------------------------------*/
-static void
-ohci_device_intr_open(struct usb2_xfer *xfer)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
- uint16_t best;
- uint16_t bit;
- uint16_t x;
-
- best = 0;
- bit = OHCI_NO_EDS / 2;
- while (bit) {
- if (xfer->interval >= bit) {
- x = bit;
- best = bit;
- while (x & bit) {
- if (sc->sc_intr_stat[x] <
- sc->sc_intr_stat[best]) {
- best = x;
- }
- x++;
- }
- break;
- }
- bit >>= 1;
- }
-
- sc->sc_intr_stat[best]++;
- xfer->qh_pos = best;
-
- DPRINTFN(3, "best=%d interval=%d\n",
- best, xfer->interval);
-}
-
-static void
-ohci_device_intr_close(struct usb2_xfer *xfer)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
-
- sc->sc_intr_stat[xfer->qh_pos]--;
-
- ohci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-ohci_device_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ohci_device_intr_start(struct usb2_xfer *xfer)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
-
- /* setup TD's and QH */
- ohci_setup_standard_chain(xfer, &sc->sc_intr_p_last[xfer->qh_pos]);
-
- /* put transfer on interrupt queue */
- ohci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods ohci_device_intr_methods =
-{
- .open = ohci_device_intr_open,
- .close = ohci_device_intr_close,
- .enter = ohci_device_intr_enter,
- .start = ohci_device_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * ohci isochronous support
- *------------------------------------------------------------------------*/
-static void
-ohci_device_isoc_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ohci_device_isoc_close(struct usb2_xfer *xfer)
-{
- /**/
- ohci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-ohci_device_isoc_enter(struct usb2_xfer *xfer)
-{
- struct usb2_page_search buf_res;
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
- struct ohci_hcca *hcca;
- uint32_t buf_offset;
- uint32_t nframes;
- uint32_t ed_flags;
- uint32_t *plen;
- uint16_t itd_offset[OHCI_ITD_NOFFSET];
- uint16_t length;
- uint8_t ncur;
- ohci_itd_t *td;
- ohci_itd_t *td_last = NULL;
- ohci_ed_t *ed;
-
- hcca = ohci_get_hcca(sc);
-
- nframes = le32toh(hcca->hcca_frame_number);
-
- DPRINTFN(6, "xfer=%p isoc_next=%u nframes=%u hcca_fn=%u\n",
- xfer, xfer->pipe->isoc_next, xfer->nframes, nframes);
-
- if ((xfer->pipe->is_synced == 0) ||
- (((nframes - xfer->pipe->isoc_next) & 0xFFFF) < xfer->nframes) ||
- (((xfer->pipe->isoc_next - nframes) & 0xFFFF) >= 128)) {
- /*
- * If there is data underflow or the pipe queue is empty we
- * schedule the transfer a few frames ahead of the current
- * frame position. Else two isochronous transfers might
- * overlap.
- */
- xfer->pipe->isoc_next = (nframes + 3) & 0xFFFF;
- xfer->pipe->is_synced = 1;
- DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next);
- }
- /*
- * compute how many milliseconds the insertion is ahead of the
- * current frame position:
- */
- buf_offset = ((xfer->pipe->isoc_next - nframes) & 0xFFFF);
-
- /*
- * pre-compute when the isochronous transfer will be finished:
- */
- xfer->isoc_time_complete =
- (usb2_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset +
- xfer->nframes);
-
- /* get the real number of frames */
-
- nframes = xfer->nframes;
-
- buf_offset = 0;
-
- plen = xfer->frlengths;
-
- /* toggle the DMA set we are using */
- xfer->flags_int.curr_dma_set ^= 1;
-
- /* get next DMA set */
- td = xfer->td_start[xfer->flags_int.curr_dma_set];
-
- xfer->td_transfer_first = td;
-
- ncur = 0;
- length = 0;
-
- while (nframes--) {
- if (td == NULL) {
- panic("%s:%d: out of TD's\n",
- __FUNCTION__, __LINE__);
- }
- itd_offset[ncur] = length;
- buf_offset += *plen;
- length += *plen;
- plen++;
- ncur++;
-
- if ( /* check if the ITD is full */
- (ncur == OHCI_ITD_NOFFSET) ||
- /* check if we have put more than 4K into the ITD */
- (length & 0xF000) ||
- /* check if it is the last frame */
- (nframes == 0)) {
-
- /* fill current ITD */
- td->itd_flags = htole32(
- OHCI_ITD_NOCC |
- OHCI_ITD_SET_SF(xfer->pipe->isoc_next) |
- OHCI_ITD_NOINTR |
- OHCI_ITD_SET_FC(ncur));
-
- td->frames = ncur;
- xfer->pipe->isoc_next += ncur;
-
- if (length == 0) {
- /* all zero */
- td->itd_bp0 = 0;
- td->itd_be = ~0;
-
- while (ncur--) {
- td->itd_offset[ncur] =
- htole16(OHCI_ITD_MK_OFFS(0));
- }
- } else {
- usb2_get_page(xfer->frbuffers, buf_offset - length, &buf_res);
- length = OHCI_PAGE_MASK(buf_res.physaddr);
- buf_res.physaddr =
- OHCI_PAGE(buf_res.physaddr);
- td->itd_bp0 = htole32(buf_res.physaddr);
- usb2_get_page(xfer->frbuffers, buf_offset - 1, &buf_res);
- td->itd_be = htole32(buf_res.physaddr);
-
- while (ncur--) {
- itd_offset[ncur] += length;
- itd_offset[ncur] =
- OHCI_ITD_MK_OFFS(itd_offset[ncur]);
- td->itd_offset[ncur] =
- htole16(itd_offset[ncur]);
- }
- }
- ncur = 0;
- length = 0;
- td_last = td;
- td = td->obj_next;
-
- if (td) {
- /* link the last TD with the next one */
- td_last->itd_next = td->itd_self;
- }
- usb2_pc_cpu_flush(td_last->page_cache);
- }
- }
-
- /* update the last TD */
- td_last->itd_flags &= ~htole32(OHCI_ITD_NOINTR);
- td_last->itd_flags |= htole32(OHCI_ITD_SET_DI(0));
- td_last->itd_next = 0;
-
- usb2_pc_cpu_flush(td_last->page_cache);
-
- xfer->td_transfer_last = td_last;
-
-#if USB_DEBUG
- if (ohcidebug > 8) {
- DPRINTF("data before transfer:\n");
- ohci_dump_itds(xfer->td_transfer_first);
- }
-#endif
- ed = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- if (UE_GET_DIR(xfer->endpoint) == UE_DIR_IN)
- ed_flags = (OHCI_ED_DIR_IN | OHCI_ED_FORMAT_ISO);
- else
- ed_flags = (OHCI_ED_DIR_OUT | OHCI_ED_FORMAT_ISO);
-
- ed_flags |= (OHCI_ED_SET_FA(xfer->address) |
- OHCI_ED_SET_EN(UE_GET_ADDR(xfer->endpoint)) |
- OHCI_ED_SET_MAXP(xfer->max_frame_size));
-
- if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
- ed_flags |= OHCI_ED_SPEED;
- }
- ed->ed_flags = htole32(ed_flags);
-
- td = xfer->td_transfer_first;
-
- ed->ed_headp = td->itd_self;
-
- /* isochronous transfers are not affected by suspend / resume */
- /* the append function will flush the endpoint descriptor */
-
- OHCI_APPEND_QH(ed, sc->sc_isoc_p_last);
-}
-
-static void
-ohci_device_isoc_start(struct usb2_xfer *xfer)
-{
- /* put transfer on interrupt queue */
- ohci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods ohci_device_isoc_methods =
-{
- .open = ohci_device_isoc_open,
- .close = ohci_device_isoc_close,
- .enter = ohci_device_isoc_enter,
- .start = ohci_device_isoc_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * ohci root control support
- *------------------------------------------------------------------------*
- * simulate a hardware hub by handling
- * all the necessary requests
- *------------------------------------------------------------------------*/
-
-static void
-ohci_root_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ohci_root_ctrl_close(struct usb2_xfer *xfer)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_ctrl.xfer == xfer) {
- sc->sc_root_ctrl.xfer = NULL;
- }
- ohci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-/* data structures and routines
- * to emulate the root hub:
- */
-static const
-struct usb2_device_descriptor ohci_devd =
-{
- sizeof(struct usb2_device_descriptor),
- 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 const
-struct ohci_config_desc ohci_confd =
-{
- .confd = {
- .bLength = sizeof(struct usb2_config_descriptor),
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength[0] = sizeof(ohci_confd),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_SELF_POWERED,
- .bMaxPower = 0, /* max power */
- },
-
- .ifcd = {
- .bLength = sizeof(struct usb2_interface_descriptor),
- .bDescriptorType = UDESC_INTERFACE,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_FSHUB,
- },
-
- .endpd = {
- .bLength = sizeof(struct usb2_endpoint_descriptor),
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = UE_DIR_IN | OHCI_INTR_ENDPT,
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize[0] = 32,/* max packet (255 ports) */
- .bInterval = 255,
- },
-};
-
-static const
-struct usb2_hub_descriptor ohci_hubd =
-{
- 0, /* dynamic length */
- UDESC_HUB,
- 0,
- {0, 0},
- 0,
- 0,
- {0},
-};
-
-static void
-ohci_root_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ohci_root_ctrl_start(struct usb2_xfer *xfer)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_ctrl.xfer = xfer;
-
- usb2_bus_roothub_exec(xfer->xroot->bus);
-}
-
-static void
-ohci_root_ctrl_task(struct usb2_bus *bus)
-{
- ohci_root_ctrl_poll(OHCI_BUS2SC(bus));
-}
-
-static void
-ohci_root_ctrl_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
- char *ptr;
- uint32_t port;
- uint32_t v;
- uint16_t value;
- uint16_t index;
- uint8_t l;
- uint8_t use_polling;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_SETUP) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- ohci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* buffer reset */
- std->ptr = sc->sc_hub_desc.temp;
- std->len = 0;
-
- value = UGETW(std->req.wValue);
- index = UGETW(std->req.wIndex);
-
- use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
-
- DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
- "wValue=0x%04x wIndex=0x%04x\n",
- std->req.bmRequestType, std->req.bRequest,
- UGETW(std->req.wLength), value, index);
-
-#define C(x,y) ((x) | ((y) << 8))
- switch (C(std->req.bRequest, std->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):
- std->len = 1;
- sc->sc_hub_desc.temp[0] = sc->sc_conf;
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- switch (value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- std->len = sizeof(ohci_devd);
- sc->sc_hub_desc.devd = ohci_devd;
- break;
-
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- std->len = sizeof(ohci_confd);
- std->ptr = USB_ADD_BYTES(&ohci_confd, 0);
- break;
-
- case UDESC_STRING:
- switch (value & 0xff) {
- case 0: /* Language table */
- ptr = "\001";
- break;
-
- case 1: /* Vendor */
- ptr = sc->sc_vendor;
- break;
-
- case 2: /* Product */
- ptr = "OHCI root HUB";
- break;
-
- default:
- ptr = "";
- break;
- }
-
- std->len = usb2_make_str_desc
- (sc->sc_hub_desc.temp,
- sizeof(sc->sc_hub_desc.temp),
- ptr);
- break;
-
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- std->len = 1;
- sc->sc_hub_desc.temp[0] = 0;
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- std->len = 2;
- USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED);
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- std->len = 2;
- USETW(sc->sc_hub_desc.stat.wStatus, 0);
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- if (value >= USB_MAX_DEVICES) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- if ((value != 0) && (value != 1)) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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):
- std->err = USB_ERR_IOERROR;
- goto done;
- 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(9, "UR_CLEAR_PORT_FEATURE "
- "port=%d feature=%d\n",
- index, value);
- if ((index < 1) ||
- (index > sc->sc_noport)) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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_enable(sc);
- break;
- default:
- break;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- if ((value & 0xff) != 0) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
-
- sc->sc_hub_desc.hubd = ohci_hubd;
- sc->sc_hub_desc.hubd.bNbrPorts = sc->sc_noport;
- USETW(sc->sc_hub_desc.hubd.wHubCharacteristics,
- (v & OHCI_NPS ? UHD_PWR_NO_SWITCH :
- v & OHCI_PSM ? UHD_PWR_GANGED : UHD_PWR_INDIVIDUAL)
- /* XXX overcurrent */
- );
- sc->sc_hub_desc.hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v);
- v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
-
- for (l = 0; l < sc->sc_noport; l++) {
- if (v & 1) {
- sc->sc_hub_desc.hubd.DeviceRemovable[l / 8] |= (1 << (l % 8));
- }
- v >>= 1;
- }
- sc->sc_hub_desc.hubd.bDescLength =
- 8 + ((sc->sc_noport + 7) / 8);
- std->len = sc->sc_hub_desc.hubd.bDescLength;
- break;
-
- case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
- std->len = 16;
- bzero(sc->sc_hub_desc.temp, 16);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- DPRINTFN(9, "get port status i=%d\n",
- index);
- if ((index < 1) ||
- (index > sc->sc_noport)) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
- DPRINTFN(9, "port status=0x%04x\n", v);
- USETW(sc->sc_hub_desc.ps.wPortStatus, v);
- USETW(sc->sc_hub_desc.ps.wPortChange, v >> 16);
- std->len = sizeof(sc->sc_hub_desc.ps);
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- std->err = USB_ERR_IOERROR;
- goto done;
- 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)) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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(6, "reset port %d\n", index);
- OWRITE4(sc, port, UPS_RESET);
- for (v = 0;; v++) {
- if (v < 12) {
- if (use_polling) {
- /* polling */
- DELAY(USB_PORT_ROOT_RESET_DELAY * 1000);
- } else {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_PORT_ROOT_RESET_DELAY));
- }
-
- if ((OREAD4(sc, port) & UPS_RESET) == 0) {
- break;
- }
- } else {
- std->err = USB_ERR_TIMEOUT;
- goto done;
- }
- }
- DPRINTFN(9, "ohci port %d reset, status = 0x%04x\n",
- index, OREAD4(sc, port));
- break;
- case UHF_PORT_POWER:
- DPRINTFN(3, "set port power %d\n", index);
- OWRITE4(sc, port, UPS_PORT_POWER);
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
-done:
- return;
-}
-
-static void
-ohci_root_ctrl_poll(struct ohci_softc *sc)
-{
- usb2_sw_transfer(&sc->sc_root_ctrl,
- &ohci_root_ctrl_done);
-}
-
-struct usb2_pipe_methods ohci_root_ctrl_methods =
-{
- .open = ohci_root_ctrl_open,
- .close = ohci_root_ctrl_close,
- .enter = ohci_root_ctrl_enter,
- .start = ohci_root_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 0,
-};
-
-/*------------------------------------------------------------------------*
- * ohci root interrupt support
- *------------------------------------------------------------------------*/
-static void
-ohci_root_intr_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ohci_root_intr_close(struct usb2_xfer *xfer)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_intr.xfer == xfer) {
- sc->sc_root_intr.xfer = NULL;
- }
- ohci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-ohci_root_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ohci_root_intr_start(struct usb2_xfer *xfer)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_intr.xfer = xfer;
-}
-
-struct usb2_pipe_methods ohci_root_intr_methods =
-{
- .open = ohci_root_intr_open,
- .close = ohci_root_intr_close,
- .enter = ohci_root_intr_enter,
- .start = ohci_root_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-static void
-ohci_xfer_setup(struct usb2_setup_params *parm)
-{
- struct usb2_page_search page_info;
- struct usb2_page_cache *pc;
- ohci_softc_t *sc;
- struct usb2_xfer *xfer;
- void *last_obj;
- uint32_t ntd;
- uint32_t nitd;
- uint32_t nqh;
- uint32_t n;
-
- sc = OHCI_BUS2SC(parm->udev->bus);
- xfer = parm->curr_xfer;
-
- parm->hc_max_packet_size = 0x500;
- parm->hc_max_packet_count = 1;
- parm->hc_max_frame_size = OHCI_PAGE_SIZE;
-
- /*
- * calculate ntd and nqh
- */
- if (parm->methods == &ohci_device_ctrl_methods) {
- xfer->flags_int.bdma_enable = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nitd = 0;
- ntd = ((2 * xfer->nframes) + 1 /* STATUS */
- + (xfer->max_data_length / xfer->max_usb2_frame_size));
- nqh = 1;
-
- } else if (parm->methods == &ohci_device_bulk_methods) {
- xfer->flags_int.bdma_enable = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nitd = 0;
- ntd = ((2 * xfer->nframes)
- + (xfer->max_data_length / xfer->max_usb2_frame_size));
- nqh = 1;
-
- } else if (parm->methods == &ohci_device_intr_methods) {
- xfer->flags_int.bdma_enable = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nitd = 0;
- ntd = ((2 * xfer->nframes)
- + (xfer->max_data_length / xfer->max_usb2_frame_size));
- nqh = 1;
-
- } else if (parm->methods == &ohci_device_isoc_methods) {
- xfer->flags_int.bdma_enable = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nitd = ((xfer->max_data_length / OHCI_PAGE_SIZE) +
- ((xfer->nframes + OHCI_ITD_NOFFSET - 1) / OHCI_ITD_NOFFSET) +
- 1 /* EXTRA */ );
- ntd = 0;
- nqh = 1;
-
- } else {
-
- usb2_transfer_setup_sub(parm);
-
- nitd = 0;
- ntd = 0;
- nqh = 0;
- }
-
-alloc_dma_set:
-
- if (parm->err) {
- return;
- }
- last_obj = NULL;
-
- if (usb2_transfer_setup_sub_malloc(
- parm, &pc, sizeof(ohci_td_t),
- OHCI_TD_ALIGN, ntd)) {
- parm->err = USB_ERR_NOMEM;
- return;
- }
- if (parm->buf) {
- for (n = 0; n != ntd; n++) {
- ohci_td_t *td;
-
- usb2_get_page(pc + n, 0, &page_info);
-
- td = page_info.buffer;
-
- /* init TD */
- td->td_self = htole32(page_info.physaddr);
- td->obj_next = last_obj;
- td->page_cache = pc + n;
-
- last_obj = td;
-
- usb2_pc_cpu_flush(pc + n);
- }
- }
- if (usb2_transfer_setup_sub_malloc(
- parm, &pc, sizeof(ohci_itd_t),
- OHCI_ITD_ALIGN, nitd)) {
- parm->err = USB_ERR_NOMEM;
- return;
- }
- if (parm->buf) {
- for (n = 0; n != nitd; n++) {
- ohci_itd_t *itd;
-
- usb2_get_page(pc + n, 0, &page_info);
-
- itd = page_info.buffer;
-
- /* init TD */
- itd->itd_self = htole32(page_info.physaddr);
- itd->obj_next = last_obj;
- itd->page_cache = pc + n;
-
- last_obj = itd;
-
- usb2_pc_cpu_flush(pc + n);
- }
- }
- xfer->td_start[xfer->flags_int.curr_dma_set] = last_obj;
-
- last_obj = NULL;
-
- if (usb2_transfer_setup_sub_malloc(
- parm, &pc, sizeof(ohci_ed_t),
- OHCI_ED_ALIGN, nqh)) {
- parm->err = USB_ERR_NOMEM;
- return;
- }
- if (parm->buf) {
- for (n = 0; n != nqh; n++) {
- ohci_ed_t *ed;
-
- usb2_get_page(pc + n, 0, &page_info);
-
- ed = page_info.buffer;
-
- /* init QH */
- ed->ed_self = htole32(page_info.physaddr);
- ed->obj_next = last_obj;
- ed->page_cache = pc + n;
-
- last_obj = ed;
-
- usb2_pc_cpu_flush(pc + n);
- }
- }
- xfer->qh_start[xfer->flags_int.curr_dma_set] = last_obj;
-
- if (!xfer->flags_int.curr_dma_set) {
- xfer->flags_int.curr_dma_set = 1;
- goto alloc_dma_set;
- }
-}
-
-static void
-ohci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
- struct usb2_pipe *pipe)
-{
- ohci_softc_t *sc = OHCI_BUS2SC(udev->bus);
-
- DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
- pipe, udev->address,
- edesc->bEndpointAddress, udev->flags.usb2_mode,
- sc->sc_addr);
-
- if (udev->flags.usb2_mode != USB_MODE_HOST) {
- /* not supported */
- return;
- }
- if (udev->device_index == sc->sc_addr) {
- switch (edesc->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:
- /* do nothing */
- break;
- }
- } else {
- switch (edesc->bmAttributes & UE_XFERTYPE) {
- case UE_CONTROL:
- pipe->methods = &ohci_device_ctrl_methods;
- break;
- case UE_INTERRUPT:
- pipe->methods = &ohci_device_intr_methods;
- break;
- case UE_ISOCHRONOUS:
- if (udev->speed == USB_SPEED_FULL) {
- pipe->methods = &ohci_device_isoc_methods;
- }
- break;
- case UE_BULK:
- if (udev->speed != USB_SPEED_LOW) {
- pipe->methods = &ohci_device_bulk_methods;
- }
- break;
- default:
- /* do nothing */
- break;
- }
- }
-}
-
-static void
-ohci_xfer_unsetup(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-ohci_get_dma_delay(struct usb2_bus *bus, uint32_t *pus)
-{
- /*
- * Wait until hardware has finished any possible use of the
- * transfer descriptor(s) and QH
- */
- *pus = (1125); /* microseconds */
-}
-
-static void
-ohci_device_resume(struct usb2_device *udev)
-{
- struct ohci_softc *sc = OHCI_BUS2SC(udev->bus);
- struct usb2_xfer *xfer;
- struct usb2_pipe_methods *methods;
- ohci_ed_t *ed;
-
- DPRINTF("\n");
-
- USB_BUS_LOCK(udev->bus);
-
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
-
- if (xfer->xroot->udev == udev) {
-
- methods = xfer->pipe->methods;
- ed = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- if (methods == &ohci_device_bulk_methods) {
- OHCI_APPEND_QH(ed, sc->sc_bulk_p_last);
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
- }
- if (methods == &ohci_device_ctrl_methods) {
- OHCI_APPEND_QH(ed, sc->sc_ctrl_p_last);
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
- }
- if (methods == &ohci_device_intr_methods) {
- OHCI_APPEND_QH(ed, sc->sc_intr_p_last[xfer->qh_pos]);
- }
- }
- }
-
- USB_BUS_UNLOCK(udev->bus);
-
- return;
-}
-
-static void
-ohci_device_suspend(struct usb2_device *udev)
-{
- struct ohci_softc *sc = OHCI_BUS2SC(udev->bus);
- struct usb2_xfer *xfer;
- struct usb2_pipe_methods *methods;
- ohci_ed_t *ed;
-
- DPRINTF("\n");
-
- USB_BUS_LOCK(udev->bus);
-
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
-
- if (xfer->xroot->udev == udev) {
-
- methods = xfer->pipe->methods;
- ed = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- if (methods == &ohci_device_bulk_methods) {
- OHCI_REMOVE_QH(ed, sc->sc_bulk_p_last);
- }
- if (methods == &ohci_device_ctrl_methods) {
- OHCI_REMOVE_QH(ed, sc->sc_ctrl_p_last);
- }
- if (methods == &ohci_device_intr_methods) {
- OHCI_REMOVE_QH(ed, sc->sc_intr_p_last[xfer->qh_pos]);
- }
- }
- }
-
- USB_BUS_UNLOCK(udev->bus);
-
- return;
-}
-
-static void
-ohci_set_hw_power(struct usb2_bus *bus)
-{
- struct ohci_softc *sc = OHCI_BUS2SC(bus);
- uint32_t temp;
- uint32_t flags;
-
- DPRINTF("\n");
-
- USB_BUS_LOCK(bus);
-
- flags = bus->hw_power_state;
-
- temp = OREAD4(sc, OHCI_CONTROL);
- temp &= ~(OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE);
-
- if (flags & USB_HW_POWER_CONTROL)
- temp |= OHCI_CLE;
-
- if (flags & USB_HW_POWER_BULK)
- temp |= OHCI_BLE;
-
- if (flags & USB_HW_POWER_INTERRUPT)
- temp |= OHCI_PLE;
-
- if (flags & USB_HW_POWER_ISOC)
- temp |= OHCI_IE | OHCI_PLE;
-
- OWRITE4(sc, OHCI_CONTROL, temp);
-
- USB_BUS_UNLOCK(bus);
-
- return;
-}
-
-struct usb2_bus_methods ohci_bus_methods =
-{
- .pipe_init = ohci_pipe_init,
- .xfer_setup = ohci_xfer_setup,
- .xfer_unsetup = ohci_xfer_unsetup,
- .do_poll = ohci_do_poll,
- .get_dma_delay = ohci_get_dma_delay,
- .device_resume = ohci_device_resume,
- .device_suspend = ohci_device_suspend,
- .set_hw_power = ohci_set_hw_power,
- .roothub_exec = ohci_root_ctrl_task,
-};
diff --git a/sys/dev/usb2/controller/ohci2.h b/sys/dev/usb2/controller/ohci2.h
deleted file mode 100644
index 84a6afd..0000000
--- a/sys/dev/usb2/controller/ohci2.h
+++ /dev/null
@@ -1,366 +0,0 @@
-/* $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 _OHCI_H_
-#define _OHCI_H_
-
-#define OHCI_MAX_DEVICES USB_MAX_DEVICES
-
-/* 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 /* HostControllerFunctionalStat
- * e */
-#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)
-
-#define OHCI_NO_INTRS 32
-#define OHCI_HCCA_SIZE 256
-
-/* Structures alignment (bytes) */
-#define OHCI_HCCA_ALIGN 256
-#define OHCI_ED_ALIGN 16
-#define OHCI_TD_ALIGN 16
-#define OHCI_ITD_ALIGN 32
-
-#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)
-
-#if ((USB_PAGE_SIZE < OHCI_ED_ALIGN) || (OHCI_ED_ALIGN == 0) || \
- (USB_PAGE_SIZE < OHCI_TD_ALIGN) || (OHCI_TD_ALIGN == 0) || \
- (USB_PAGE_SIZE < OHCI_ITD_ALIGN) || (OHCI_ITD_ALIGN == 0) || \
- (USB_PAGE_SIZE < OHCI_PAGE_SIZE) || (OHCI_PAGE_SIZE == 0))
-#error "Invalid USB page size!"
-#endif
-
-#define OHCI_VIRTUAL_FRAMELIST_COUNT 128/* dummy */
-
-#if (OHCI_VIRTUAL_FRAMELIST_COUNT < USB_MAX_FS_ISOC_FRAMES_PER_XFER)
-#error "maximum number of full-speed isochronous frames is higher than supported!"
-#endif
-
-struct ohci_hcca {
- volatile uint32_t hcca_interrupt_table[OHCI_NO_INTRS];
- volatile uint32_t hcca_frame_number;
- volatile uint32_t hcca_done_head;
-#define OHCI_DONE_INTRS 1
-} __aligned(OHCI_HCCA_ALIGN);
-
-typedef struct ohci_hcca ohci_hcca_t;
-
-struct ohci_ed {
- volatile uint32_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)
- volatile uint32_t ed_tailp;
- volatile uint32_t ed_headp;
-#define OHCI_HALTED 0x00000001
-#define OHCI_TOGGLECARRY 0x00000002
-#define OHCI_HEADMASK 0xfffffffc
- volatile uint32_t ed_next;
-/*
- * Extra information needed:
- */
- struct ohci_ed *next;
- struct ohci_ed *prev;
- struct ohci_ed *obj_next;
- struct usb2_page_cache *page_cache;
- uint32_t ed_self;
-} __aligned(OHCI_ED_ALIGN);
-
-typedef struct ohci_ed ohci_ed_t;
-
-struct ohci_td {
- volatile uint32_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_SET_CC(x) ((x) << 28)
-#define OHCI_TD_NOCC 0xf0000000
- volatile uint32_t td_cbp; /* Current Buffer Pointer */
- volatile uint32_t td_next; /* Next TD */
-#define OHCI_TD_NEXT_END 0
- volatile uint32_t td_be; /* Buffer End */
-/*
- * Extra information needed:
- */
- struct ohci_td *obj_next;
- struct ohci_td *alt_next;
- struct usb2_page_cache *page_cache;
- uint32_t td_self;
- uint16_t len;
-} __aligned(OHCI_TD_ALIGN);
-
-typedef struct ohci_td ohci_td_t;
-
-struct ohci_itd {
- volatile uint32_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
-#define OHCI_ITD_NOFFSET 8
- volatile uint32_t itd_bp0; /* Buffer Page 0 */
- volatile uint32_t itd_next; /* Next ITD */
- volatile uint32_t itd_be; /* Buffer End */
- volatile uint16_t itd_offset[OHCI_ITD_NOFFSET]; /* Buffer offsets and
- * Status */
-#define OHCI_ITD_PAGE_SELECT 0x00001000
-#define OHCI_ITD_MK_OFFS(len) (0xe000 | ((len) & 0x1fff))
-#define OHCI_ITD_PSW_LENGTH(x) ((x) & 0xfff) /* Transfer length */
-#define OHCI_ITD_PSW_GET_CC(x) ((x) >> 12) /* Condition Code */
-/*
- * Extra information needed:
- */
- struct ohci_itd *obj_next;
- struct usb2_page_cache *page_cache;
- uint32_t itd_self;
- uint8_t frames;
-} __aligned(OHCI_ITD_ALIGN);
-
-typedef struct ohci_itd ohci_itd_t;
-
-#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
-
-#define OHCI_NO_EDS (2*OHCI_NO_INTRS)
-
-struct ohci_hw_softc {
- struct usb2_page_cache hcca_pc;
- struct usb2_page_cache ctrl_start_pc;
- struct usb2_page_cache bulk_start_pc;
- struct usb2_page_cache isoc_start_pc;
- struct usb2_page_cache intr_start_pc[OHCI_NO_EDS];
-
- struct usb2_page hcca_pg;
- struct usb2_page ctrl_start_pg;
- struct usb2_page bulk_start_pg;
- struct usb2_page isoc_start_pg;
- struct usb2_page intr_start_pg[OHCI_NO_EDS];
-};
-
-struct ohci_config_desc {
- struct usb2_config_descriptor confd;
- struct usb2_interface_descriptor ifcd;
- struct usb2_endpoint_descriptor endpd;
-} __packed;
-
-union ohci_hub_desc {
- struct usb2_status stat;
- struct usb2_port_status ps;
- struct usb2_device_descriptor devd;
- struct usb2_hub_descriptor hubd;
- uint8_t temp[128];
-};
-
-typedef struct ohci_softc {
- struct ohci_hw_softc sc_hw;
- struct usb2_bus sc_bus; /* base device */
- struct usb2_callout sc_tmo_rhsc;
- union ohci_hub_desc sc_hub_desc;
- struct usb2_sw_transfer sc_root_ctrl;
- struct usb2_sw_transfer sc_root_intr;
-
- struct usb2_device *sc_devices[OHCI_MAX_DEVICES];
- struct resource *sc_io_res;
- struct resource *sc_irq_res;
- struct ohci_hcca *sc_hcca_p;
- struct ohci_ed *sc_ctrl_p_last;
- struct ohci_ed *sc_bulk_p_last;
- struct ohci_ed *sc_isoc_p_last;
- struct ohci_ed *sc_intr_p_last[OHCI_NO_EDS];
- void *sc_intr_hdl;
- device_t sc_dev;
- bus_size_t sc_io_size;
- bus_space_tag_t sc_io_tag;
- bus_space_handle_t sc_io_hdl;
-
- uint32_t sc_eintrs; /* enabled interrupts */
- uint32_t sc_control; /* Preserved during suspend/standby */
- uint32_t sc_intre;
-
- uint16_t sc_intr_stat[OHCI_NO_EDS];
- uint16_t sc_id_vendor;
-
- uint8_t sc_noport;
- uint8_t sc_addr; /* device address */
- uint8_t sc_conf; /* device configuration */
- uint8_t sc_hub_idata[32];
-
- char sc_vendor[16];
-
-} ohci_softc_t;
-
-usb2_bus_mem_cb_t ohci_iterate_hw_softc;
-
-usb2_error_t ohci_init(ohci_softc_t *sc);
-void ohci_detach(struct ohci_softc *sc);
-void ohci_suspend(ohci_softc_t *sc);
-void ohci_resume(ohci_softc_t *sc);
-void ohci_interrupt(ohci_softc_t *sc);
-
-#endif /* _OHCI_H_ */
diff --git a/sys/dev/usb2/controller/ohci2_atmelarm.c b/sys/dev/usb2/controller/ohci2_atmelarm.c
deleted file mode 100644
index a7f086c..0000000
--- a/sys/dev/usb2/controller/ohci2_atmelarm.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*-
- * Copyright (c) 2006 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 ``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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/ohci2.h>
-
-#include <sys/rman.h>
-
-#include <arm/at91/at91_pmcvar.h>
-
-#define MEM_RID 0
-
-static device_probe_t ohci_atmelarm_probe;
-static device_attach_t ohci_atmelarm_attach;
-static device_detach_t ohci_atmelarm_detach;
-
-struct at91_ohci_softc {
- struct ohci_softc sc_ohci; /* must be first */
- struct at91_pmc_clock *iclk;
- struct at91_pmc_clock *fclk;
-};
-
-static int
-ohci_atmelarm_probe(device_t dev)
-{
- device_set_desc(dev, "AT91 integrated OHCI controller");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-ohci_atmelarm_attach(device_t dev)
-{
- struct at91_ohci_softc *sc = device_get_softc(dev);
- int err;
- int rid;
-
- /* initialise some bus fields */
- sc->sc_ohci.sc_bus.parent = dev;
- sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
- sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;
-
- /* get all DMA memory */
- if (usb2_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
- USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
- return (ENOMEM);
- }
- sc->iclk = at91_pmc_clock_ref("ohci_clk");
- sc->fclk = at91_pmc_clock_ref("uhpck");
-
- sc->sc_ohci.sc_dev = dev;
-
- rid = MEM_RID;
- sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
- &rid, RF_ACTIVE);
-
- if (!(sc->sc_ohci.sc_io_res)) {
- err = ENOMEM;
- goto error;
- }
- sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res);
- sc->sc_ohci.sc_io_hdl = rman_get_bushandle(sc->sc_ohci.sc_io_res);
- sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res);
-
- rid = 0;
- sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_ACTIVE);
- if (!(sc->sc_ohci.sc_irq_res)) {
- goto error;
- }
- sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
- if (!(sc->sc_ohci.sc_bus.bdev)) {
- goto error;
- }
- device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus);
-
- strlcpy(sc->sc_ohci.sc_vendor, "Atmel", sizeof(sc->sc_ohci.sc_vendor));
-
-#if (__FreeBSD_version >= 700031)
- err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (void *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl);
-#else
- err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- (void *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl);
-#endif
- if (err) {
- sc->sc_ohci.sc_intr_hdl = NULL;
- goto error;
- }
- /*
- * turn on the clocks from the AT91's point of view. Keep the unit in reset.
- */
- at91_pmc_clock_enable(sc->iclk);
- at91_pmc_clock_enable(sc->fclk);
- bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
- OHCI_CONTROL, 0);
-
- err = ohci_init(&sc->sc_ohci);
- if (!err) {
- err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev);
- }
- if (err) {
- goto error;
- }
- return (0);
-
-error:
- ohci_atmelarm_detach(dev);
- return (ENXIO);
-}
-
-static int
-ohci_atmelarm_detach(device_t dev)
-{
- struct at91_ohci_softc *sc = device_get_softc(dev);
- device_t bdev;
- int err;
-
- if (sc->sc_ohci.sc_bus.bdev) {
- bdev = sc->sc_ohci.sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
- /* during module unload there are lots of children leftover */
- device_delete_all_children(dev);
-
- /*
- * Put the controller into reset, then disable clocks and do
- * the MI tear down. We have to disable the clocks/hardware
- * after we do the rest of the teardown. We also disable the
- * clocks in the opposite order we acquire them, but that
- * doesn't seem to be absolutely necessary. We free up the
- * clocks after we disable them, so the system could, in
- * theory, reuse them.
- */
- bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
- OHCI_CONTROL, 0);
-
- at91_pmc_clock_disable(sc->fclk);
- at91_pmc_clock_disable(sc->iclk);
- at91_pmc_clock_deref(sc->fclk);
- at91_pmc_clock_deref(sc->iclk);
-
- if (sc->sc_ohci.sc_irq_res && sc->sc_ohci.sc_intr_hdl) {
- /*
- * only call ohci_detach() after ohci_init()
- */
- ohci_detach(&sc->sc_ohci);
-
- err = bus_teardown_intr(dev, sc->sc_ohci.sc_irq_res, sc->sc_ohci.sc_intr_hdl);
- sc->sc_ohci.sc_intr_hdl = NULL;
- }
- if (sc->sc_ohci.sc_irq_res) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.sc_irq_res);
- sc->sc_ohci.sc_irq_res = NULL;
- }
- if (sc->sc_ohci.sc_io_res) {
- bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID,
- sc->sc_ohci.sc_io_res);
- sc->sc_ohci.sc_io_res = NULL;
- }
- usb2_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc);
-
- return (0);
-}
-
-static device_method_t ohci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ohci_atmelarm_probe),
- DEVMETHOD(device_attach, ohci_atmelarm_attach),
- DEVMETHOD(device_detach, ohci_atmelarm_detach),
- 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(struct at91_ohci_softc),
-};
-
-static devclass_t ohci_devclass;
-
-DRIVER_MODULE(ohci, atmelarm, ohci_driver, ohci_devclass, 0, 0);
-MODULE_DEPEND(ohci, usb2_controller, 1, 1, 1);
-MODULE_DEPEND(ohci, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/controller/ohci2_pci.c b/sys/dev/usb2/controller/ohci2_pci.c
deleted file mode 100644
index 7d3506e..0000000
--- a/sys/dev/usb2/controller/ohci2_pci.c
+++ /dev/null
@@ -1,388 +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 <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/usb2_pci.h>
-#include <dev/usb2/controller/ohci2.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_BASE_REG 0x10
-
-static device_probe_t ohci_pci_probe;
-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_suspend(sc);
- return (0);
-}
-
-static int
-ohci_pci_resume(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
- uint32_t reg, int_line;
-
- if (pci_get_powerstate(self) != PCI_POWERSTATE_D0) {
- device_printf(self, "chip is in D%d mode "
- "-- setting to D0\n", pci_get_powerstate(self));
- reg = pci_read_config(self, PCI_CBMEM, 4);
- int_line = pci_read_config(self, PCIR_INTLINE, 4);
- pci_set_powerstate(self, PCI_POWERSTATE_D0);
- pci_write_config(self, PCI_CBMEM, reg, 4);
- pci_write_config(self, PCIR_INTLINE, int_line, 4);
- }
- ohci_resume(sc);
-
- bus_generic_resume(self);
- return (0);
-}
-
-static const char *
-ohci_pci_match(device_t self)
-{
- uint32_t device_id = pci_get_devid(self);
-
- switch (device_id) {
- case 0x523710b9:
- return ("AcerLabs M5237 (Aladdin-V) USB controller");
-
- case 0x740c1022:
- return ("AMD-756 USB Controller");
-
- case 0x74141022:
- return ("AMD-766 USB Controller");
-
- case 0x43741002:
- return "ATI SB400 USB Controller";
- case 0x43751002:
- return "ATI SB400 USB Controller";
-
- case 0x06701095:
- return ("CMD Tech 670 (USB0670) USB controller");
-
- case 0x06731095:
- return ("CMD Tech 673 (USB0673) USB controller");
-
- case 0xc8611045:
- return ("OPTi 82C861 (FireLink) USB controller");
-
- case 0x00351033:
- return ("NEC uPD 9210 USB controller");
-
- case 0x00d710de:
- return ("nVidia nForce3 USB Controller");
-
- case 0x70011039:
- return ("SiS 5571 USB controller");
-
- case 0x1103108e:
- return "Sun PCIO-2 USB controller";
-
- case 0x0019106b:
- return ("Apple KeyLargo USB controller");
-
- default:
- break;
- }
- if ((pci_get_class(self) == PCIC_SERIALBUS) &&
- (pci_get_subclass(self) == PCIS_SERIALBUS_USB) &&
- (pci_get_progif(self) == PCI_INTERFACE_OHCI)) {
- return ("OHCI (generic) USB controller");
- }
- return (NULL);
-}
-
-static int
-ohci_pci_probe(device_t self)
-{
- const char *desc = ohci_pci_match(self);
-
- if (desc) {
- device_set_desc(self, desc);
- return (0);
- } else {
- return (ENXIO);
- }
-}
-
-static int
-ohci_pci_attach(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
- int rid;
- int err;
-
- /* initialise some bus fields */
- sc->sc_bus.parent = self;
- sc->sc_bus.devices = sc->sc_devices;
- sc->sc_bus.devices_max = OHCI_MAX_DEVICES;
-
- /* get all DMA memory */
- if (usb2_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self),
- &ohci_iterate_hw_softc)) {
- return (ENOMEM);
- }
- sc->sc_dev = self;
-
- 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) == 0x1103108e && pci_get_intpin(self) == 0)
- pci_set_intpin(self, 4);
-
- rid = PCI_CBMEM;
- sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
- if (!sc->sc_io_res) {
- device_printf(self, "Could not map memory\n");
- goto error;
- }
- sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
- sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
- sc->sc_io_size = rman_get_size(sc->sc_io_res);
-
- rid = 0;
- sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->sc_irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- goto error;
- }
- sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- goto error;
- }
- 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;
- case PCI_OHCI_VENDORID_SUN:
- sprintf(sc->sc_vendor, "SUN");
- 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));
- }
-
- /* sc->sc_bus.usbrev; set by ohci_init() */
-
-#if (__FreeBSD_version >= 700031)
- err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (void *)(void *)ohci_interrupt, sc, &sc->sc_intr_hdl);
-#else
- err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- (void *)(void *)ohci_interrupt, sc, &sc->sc_intr_hdl);
-#endif
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->sc_intr_hdl = NULL;
- goto error;
- }
- err = ohci_init(sc);
- if (!err) {
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
- if (err) {
- device_printf(self, "USB init failed\n");
- goto error;
- }
- return (0);
-
-error:
- ohci_pci_detach(self);
- return (ENXIO);
-}
-
-static int
-ohci_pci_detach(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
- device_t bdev;
-
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
- /* during module unload there are lots of children leftover */
- device_delete_all_children(self);
-
- pci_disable_busmaster(self);
-
- if (sc->sc_irq_res && sc->sc_intr_hdl) {
- /*
- * only call ohci_detach() after ohci_init()
- */
- ohci_detach(sc);
-
- int err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
-
- if (err) {
- /* XXX or should we panic? */
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- }
- sc->sc_intr_hdl = NULL;
- }
- if (sc->sc_irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res);
- sc->sc_irq_res = NULL;
- }
- if (sc->sc_io_res) {
- bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM,
- sc->sc_io_res);
- sc->sc_io_res = NULL;
- }
- usb2_bus_mem_free_all(&sc->sc_bus, &ohci_iterate_hw_softc);
-
- return (0);
-}
-
-static driver_t ohci_driver =
-{
- .name = "ohci",
- .methods = (device_method_t[]){
- /* 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}
- },
- .size = sizeof(struct ohci_softc),
-};
-
-static devclass_t ohci_devclass;
-
-DRIVER_MODULE(ohci, pci, ohci_driver, ohci_devclass, 0, 0);
-DRIVER_MODULE(ohci, cardbus, ohci_driver, ohci_devclass, 0, 0);
-MODULE_DEPEND(ohci, usb2_controller, 1, 1, 1);
-MODULE_DEPEND(ohci, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/controller/uhci2.c b/sys/dev/usb2/controller/uhci2.c
deleted file mode 100644
index a5af720..0000000
--- a/sys/dev/usb2/controller/uhci2.c
+++ /dev/null
@@ -1,3381 +0,0 @@
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
- * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
- * Copyright (c) 1998 Lennart Augustsson. 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$");
-
-/*
- * 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 <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR uhcidebug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_hub.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/uhci2.h>
-
-#define alt_next next
-#define UHCI_BUS2SC(bus) ((uhci_softc_t *)(((uint8_t *)(bus)) - \
- USB_P2U(&(((uhci_softc_t *)0)->sc_bus))))
-
-#if USB_DEBUG
-static int uhcidebug = 0;
-static int uhcinoloop = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uhci, CTLFLAG_RW, 0, "USB uhci");
-SYSCTL_INT(_hw_usb2_uhci, OID_AUTO, debug, CTLFLAG_RW,
- &uhcidebug, 0, "uhci debug level");
-SYSCTL_INT(_hw_usb2_uhci, OID_AUTO, loop, CTLFLAG_RW,
- &uhcinoloop, 0, "uhci noloop");
-static void uhci_dumpregs(uhci_softc_t *sc);
-static void uhci_dump_tds(uhci_td_t *td);
-
-#endif
-
-#define UBARR(sc) bus_space_barrier((sc)->sc_io_tag, (sc)->sc_io_hdl, 0, (sc)->sc_io_size, \
- BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
-#define UWRITE1(sc, r, x) \
- do { UBARR(sc); bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (r), (x)); \
- } while (/*CONSTCOND*/0)
-#define UWRITE2(sc, r, x) \
- do { UBARR(sc); bus_space_write_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (r), (x)); \
- } while (/*CONSTCOND*/0)
-#define UWRITE4(sc, r, x) \
- do { UBARR(sc); bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (r), (x)); \
- } while (/*CONSTCOND*/0)
-#define UREAD1(sc, r) (UBARR(sc), bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (r)))
-#define UREAD2(sc, r) (UBARR(sc), bus_space_read_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (r)))
-#define UREAD4(sc, r) (UBARR(sc), bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (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_INTR_ENDPT 1
-
-struct uhci_mem_layout {
-
- struct usb2_page_search buf_res;
- struct usb2_page_search fix_res;
-
- struct usb2_page_cache *buf_pc;
- struct usb2_page_cache *fix_pc;
-
- uint32_t buf_offset;
-
- uint16_t max_frame_size;
-};
-
-struct uhci_std_temp {
-
- struct uhci_mem_layout ml;
- uhci_td_t *td;
- uhci_td_t *td_next;
- uint32_t average;
- uint32_t td_status;
- uint32_t td_token;
- uint32_t len;
- uint16_t max_frame_size;
- uint8_t shortpkt;
- uint8_t setup_alt_next;
- uint8_t short_frames_ok;
-};
-
-extern struct usb2_bus_methods uhci_bus_methods;
-extern struct usb2_pipe_methods uhci_device_bulk_methods;
-extern struct usb2_pipe_methods uhci_device_ctrl_methods;
-extern struct usb2_pipe_methods uhci_device_intr_methods;
-extern struct usb2_pipe_methods uhci_device_isoc_methods;
-extern struct usb2_pipe_methods uhci_root_ctrl_methods;
-extern struct usb2_pipe_methods uhci_root_intr_methods;
-
-static void uhci_root_ctrl_poll(struct uhci_softc *);
-static void uhci_do_poll(struct usb2_bus *);
-static void uhci_device_done(struct usb2_xfer *, usb2_error_t);
-static void uhci_transfer_intr_enqueue(struct usb2_xfer *);
-static void uhci_root_intr_check(void *);
-static void uhci_timeout(void *);
-static uint8_t uhci_check_transfer(struct usb2_xfer *);
-
-void
-uhci_iterate_hw_softc(struct usb2_bus *bus, usb2_bus_mem_sub_cb_t *cb)
-{
- struct uhci_softc *sc = UHCI_BUS2SC(bus);
- uint32_t i;
-
- cb(bus, &sc->sc_hw.pframes_pc, &sc->sc_hw.pframes_pg,
- sizeof(uint32_t) * UHCI_FRAMELIST_COUNT, UHCI_FRAMELIST_ALIGN);
-
- cb(bus, &sc->sc_hw.ls_ctl_start_pc, &sc->sc_hw.ls_ctl_start_pg,
- sizeof(uhci_qh_t), UHCI_QH_ALIGN);
-
- cb(bus, &sc->sc_hw.fs_ctl_start_pc, &sc->sc_hw.fs_ctl_start_pg,
- sizeof(uhci_qh_t), UHCI_QH_ALIGN);
-
- cb(bus, &sc->sc_hw.bulk_start_pc, &sc->sc_hw.bulk_start_pg,
- sizeof(uhci_qh_t), UHCI_QH_ALIGN);
-
- cb(bus, &sc->sc_hw.last_qh_pc, &sc->sc_hw.last_qh_pg,
- sizeof(uhci_qh_t), UHCI_QH_ALIGN);
-
- cb(bus, &sc->sc_hw.last_td_pc, &sc->sc_hw.last_td_pg,
- sizeof(uhci_td_t), UHCI_TD_ALIGN);
-
- for (i = 0; i != UHCI_VFRAMELIST_COUNT; i++) {
- cb(bus, sc->sc_hw.isoc_start_pc + i,
- sc->sc_hw.isoc_start_pg + i,
- sizeof(uhci_td_t), UHCI_TD_ALIGN);
- }
-
- for (i = 0; i != UHCI_IFRAMELIST_COUNT; i++) {
- cb(bus, sc->sc_hw.intr_start_pc + i,
- sc->sc_hw.intr_start_pg + i,
- sizeof(uhci_qh_t), UHCI_QH_ALIGN);
- }
-}
-
-static void
-uhci_mem_layout_init(struct uhci_mem_layout *ml, struct usb2_xfer *xfer)
-{
- ml->buf_pc = xfer->frbuffers + 0;
- ml->fix_pc = xfer->buf_fixup;
-
- ml->buf_offset = 0;
-
- ml->max_frame_size = xfer->max_frame_size;
-}
-
-static void
-uhci_mem_layout_fixup(struct uhci_mem_layout *ml, struct uhci_td *td)
-{
- usb2_get_page(ml->buf_pc, ml->buf_offset, &ml->buf_res);
-
- if (ml->buf_res.length < td->len) {
-
- /* need to do a fixup */
-
- usb2_get_page(ml->fix_pc, 0, &ml->fix_res);
-
- td->td_buffer = htole32(ml->fix_res.physaddr);
-
- /*
- * The UHCI driver cannot handle
- * page crossings, so a fixup is
- * needed:
- *
- * +----+----+ - - -
- * | YYY|Y |
- * +----+----+ - - -
- * \ \
- * \ \
- * +----+
- * |YYYY| (fixup)
- * +----+
- */
-
- if ((td->td_token & htole32(UHCI_TD_PID)) ==
- htole32(UHCI_TD_PID_IN)) {
- td->fix_pc = ml->fix_pc;
- usb2_pc_cpu_invalidate(ml->fix_pc);
-
- } else {
- td->fix_pc = NULL;
-
- /* copy data to fixup location */
-
- usb2_copy_out(ml->buf_pc, ml->buf_offset,
- ml->fix_res.buffer, td->len);
-
- usb2_pc_cpu_flush(ml->fix_pc);
- }
-
- /* prepare next fixup */
-
- ml->fix_pc++;
-
- } else {
-
- td->td_buffer = htole32(ml->buf_res.physaddr);
- td->fix_pc = NULL;
- }
-
- /* prepare next data location */
-
- ml->buf_offset += td->len;
-}
-
-void
-uhci_reset(uhci_softc_t *sc)
-{
- struct usb2_page_search buf_res;
- uint16_t n;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- DPRINTF("resetting the HC\n");
-
- /* disable interrupts */
-
- UWRITE2(sc, UHCI_INTR, 0);
-
- /* global reset */
-
- UHCICMD(sc, UHCI_CMD_GRESET);
-
- /* wait */
-
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_BUS_RESET_DELAY));
-
- /* terminate all transfers */
-
- UHCICMD(sc, UHCI_CMD_HCRESET);
-
- /* the reset bit goes low when the controller is done */
-
- n = UHCI_RESET_TIMEOUT;
- while (n--) {
- /* wait one millisecond */
-
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
-
- if (!(UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET)) {
- goto done_1;
- }
- }
-
- device_printf(sc->sc_bus.bdev,
- "controller did not reset\n");
-
-done_1:
-
- n = 10;
- while (n--) {
- /* wait one millisecond */
-
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
-
- /* check if HC is stopped */
- if (UREAD2(sc, UHCI_STS) & UHCI_STS_HCH) {
- goto done_2;
- }
- }
-
- device_printf(sc->sc_bus.bdev,
- "controller did not stop\n");
-
-done_2:
-
- /* reload the configuration */
- usb2_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res);
- UWRITE4(sc, UHCI_FLBASEADDR, buf_res.physaddr);
- UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum);
- UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
-}
-
-static void
-uhci_start(uhci_softc_t *sc)
-{
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- DPRINTFN(2, "enabling\n");
-
- /* enable interrupts */
-
- UWRITE2(sc, UHCI_INTR,
- (UHCI_INTR_TOCRCIE |
- UHCI_INTR_RIE |
- UHCI_INTR_IOCE |
- UHCI_INTR_SPIE));
-
- /*
- * assume 64 byte packets at frame end and start HC controller
- */
-
- UHCICMD(sc, (UHCI_CMD_MAXP | UHCI_CMD_RS));
-
- uint8_t n = 10;
-
- while (n--) {
- /* wait one millisecond */
-
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
-
- /* check that controller has started */
-
- if (!(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH)) {
- goto done;
- }
- }
-
- device_printf(sc->sc_bus.bdev,
- "cannot start HC controller\n");
-
-done:
- return;
-}
-
-static struct uhci_qh *
-uhci_init_qh(struct usb2_page_cache *pc)
-{
- struct usb2_page_search buf_res;
- struct uhci_qh *qh;
-
- usb2_get_page(pc, 0, &buf_res);
-
- qh = buf_res.buffer;
-
- qh->qh_self =
- htole32(buf_res.physaddr) |
- htole32(UHCI_PTR_QH);
-
- qh->page_cache = pc;
-
- return (qh);
-}
-
-static struct uhci_td *
-uhci_init_td(struct usb2_page_cache *pc)
-{
- struct usb2_page_search buf_res;
- struct uhci_td *td;
-
- usb2_get_page(pc, 0, &buf_res);
-
- td = buf_res.buffer;
-
- td->td_self =
- htole32(buf_res.physaddr) |
- htole32(UHCI_PTR_TD);
-
- td->page_cache = pc;
-
- return (td);
-}
-
-usb2_error_t
-uhci_init(uhci_softc_t *sc)
-{
- uint16_t bit;
- uint16_t x;
- uint16_t y;
-
- DPRINTF("start\n");
-
-#if USB_DEBUG
- if (uhcidebug > 2) {
- uhci_dumpregs(sc);
- }
-#endif
-
- sc->sc_saved_sof = 0x40; /* default value */
- sc->sc_saved_frnum = 0; /* default frame number */
-
- /*
- * Setup QH's
- */
- sc->sc_ls_ctl_p_last =
- uhci_init_qh(&sc->sc_hw.ls_ctl_start_pc);
-
- sc->sc_fs_ctl_p_last =
- uhci_init_qh(&sc->sc_hw.fs_ctl_start_pc);
-
- sc->sc_bulk_p_last =
- uhci_init_qh(&sc->sc_hw.bulk_start_pc);
-#if 0
- sc->sc_reclaim_qh_p =
- sc->sc_fs_ctl_p_last;
-#else
- /* setup reclaim looping point */
- sc->sc_reclaim_qh_p =
- sc->sc_bulk_p_last;
-#endif
-
- sc->sc_last_qh_p =
- uhci_init_qh(&sc->sc_hw.last_qh_pc);
-
- sc->sc_last_td_p =
- uhci_init_td(&sc->sc_hw.last_td_pc);
-
- for (x = 0; x != UHCI_VFRAMELIST_COUNT; x++) {
- sc->sc_isoc_p_last[x] =
- uhci_init_td(sc->sc_hw.isoc_start_pc + x);
- }
-
- for (x = 0; x != UHCI_IFRAMELIST_COUNT; x++) {
- sc->sc_intr_p_last[x] =
- uhci_init_qh(sc->sc_hw.intr_start_pc + x);
- }
-
- /*
- * the QHs are arranged to give poll intervals that are
- * powers of 2 times 1ms
- */
- bit = UHCI_IFRAMELIST_COUNT / 2;
- while (bit) {
- x = bit;
- while (x & bit) {
- uhci_qh_t *qh_x;
- uhci_qh_t *qh_y;
-
- y = (x ^ bit) | (bit / 2);
-
- /*
- * the next QH has half the poll interval
- */
- qh_x = sc->sc_intr_p_last[x];
- qh_y = sc->sc_intr_p_last[y];
-
- qh_x->h_next = NULL;
- qh_x->qh_h_next = qh_y->qh_self;
- qh_x->e_next = NULL;
- qh_x->qh_e_next = htole32(UHCI_PTR_T);
- x++;
- }
- bit >>= 1;
- }
-
- if (1) {
- uhci_qh_t *qh_ls;
- uhci_qh_t *qh_intr;
-
- qh_ls = sc->sc_ls_ctl_p_last;
- qh_intr = sc->sc_intr_p_last[0];
-
- /* start QH for interrupt traffic */
- qh_intr->h_next = qh_ls;
- qh_intr->qh_h_next = qh_ls->qh_self;
- qh_intr->e_next = 0;
- qh_intr->qh_e_next = htole32(UHCI_PTR_T);
- }
- for (x = 0; x != UHCI_VFRAMELIST_COUNT; x++) {
-
- uhci_td_t *td_x;
- uhci_qh_t *qh_intr;
-
- td_x = sc->sc_isoc_p_last[x];
- qh_intr = sc->sc_intr_p_last[x | (UHCI_IFRAMELIST_COUNT / 2)];
-
- /* start TD for isochronous traffic */
- td_x->next = NULL;
- td_x->td_next = qh_intr->qh_self;
- td_x->td_status = htole32(UHCI_TD_IOS);
- td_x->td_token = htole32(0);
- td_x->td_buffer = htole32(0);
- }
-
- if (1) {
- uhci_qh_t *qh_ls;
- uhci_qh_t *qh_fs;
-
- qh_ls = sc->sc_ls_ctl_p_last;
- qh_fs = sc->sc_fs_ctl_p_last;
-
- /* start QH where low speed control traffic will be queued */
- qh_ls->h_next = qh_fs;
- qh_ls->qh_h_next = qh_fs->qh_self;
- qh_ls->e_next = 0;
- qh_ls->qh_e_next = htole32(UHCI_PTR_T);
- }
- if (1) {
- uhci_qh_t *qh_ctl;
- uhci_qh_t *qh_blk;
- uhci_qh_t *qh_lst;
- uhci_td_t *td_lst;
-
- qh_ctl = sc->sc_fs_ctl_p_last;
- qh_blk = sc->sc_bulk_p_last;
-
- /* start QH where full speed control traffic will be queued */
- qh_ctl->h_next = qh_blk;
- qh_ctl->qh_h_next = qh_blk->qh_self;
- qh_ctl->e_next = 0;
- qh_ctl->qh_e_next = htole32(UHCI_PTR_T);
-
- qh_lst = sc->sc_last_qh_p;
-
- /* start QH where bulk traffic will be queued */
- qh_blk->h_next = qh_lst;
- qh_blk->qh_h_next = qh_lst->qh_self;
- qh_blk->e_next = 0;
- qh_blk->qh_e_next = htole32(UHCI_PTR_T);
-
- td_lst = sc->sc_last_td_p;
-
- /* end QH which is used for looping the QHs */
- qh_lst->h_next = 0;
- qh_lst->qh_h_next = htole32(UHCI_PTR_T); /* end of QH chain */
- qh_lst->e_next = td_lst;
- qh_lst->qh_e_next = td_lst->td_self;
-
- /*
- * end TD which hangs from the last QH, to avoid a bug in the PIIX
- * that makes it run berserk otherwise
- */
- td_lst->next = 0;
- td_lst->td_next = htole32(UHCI_PTR_T);
- td_lst->td_status = htole32(0); /* inactive */
- td_lst->td_token = htole32(0);
- td_lst->td_buffer = htole32(0);
- }
- if (1) {
- struct usb2_page_search buf_res;
- uint32_t *pframes;
-
- usb2_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res);
-
- pframes = buf_res.buffer;
-
-
- /*
- * Setup UHCI framelist
- *
- * Execution order:
- *
- * pframes -> full speed isochronous -> interrupt QH's -> low
- * speed control -> full speed control -> bulk transfers
- *
- */
-
- for (x = 0; x != UHCI_FRAMELIST_COUNT; x++) {
- pframes[x] =
- sc->sc_isoc_p_last[x % UHCI_VFRAMELIST_COUNT]->td_self;
- }
- }
- /* flush all cache into memory */
-
- usb2_bus_mem_flush_all(&sc->sc_bus, &uhci_iterate_hw_softc);
-
- /* set up the bus struct */
- sc->sc_bus.methods = &uhci_bus_methods;
-
- USB_BUS_LOCK(&sc->sc_bus);
- /* reset the controller */
- uhci_reset(sc);
-
- /* start the controller */
- uhci_start(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
-
- /* catch lost interrupts */
- uhci_do_poll(&sc->sc_bus);
-
- return (0);
-}
-
-/* NOTE: suspend/resume is called from
- * interrupt context and cannot sleep!
- */
-
-void
-uhci_suspend(uhci_softc_t *sc)
-{
- USB_BUS_LOCK(&sc->sc_bus);
-
-#if USB_DEBUG
- if (uhcidebug > 2) {
- uhci_dumpregs(sc);
- }
-#endif
- /* save some state if BIOS doesn't */
-
- sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM);
- sc->sc_saved_sof = UREAD1(sc, UHCI_SOF);
-
- /* stop the controller */
-
- uhci_reset(sc);
-
- /* enter global suspend */
-
- UHCICMD(sc, UHCI_CMD_EGSM);
-
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_WAIT));
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-void
-uhci_resume(uhci_softc_t *sc)
-{
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* reset the controller */
-
- uhci_reset(sc);
-
- /* force global resume */
-
- UHCICMD(sc, UHCI_CMD_FGR);
-
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_DELAY));
-
- /* and start traffic again */
-
- uhci_start(sc);
-
-#if USB_DEBUG
- if (uhcidebug > 2) {
- uhci_dumpregs(sc);
- }
-#endif
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-
- /* catch lost interrupts */
- uhci_do_poll(&sc->sc_bus);
-}
-
-#if USB_DEBUG
-static void
-uhci_dumpregs(uhci_softc_t *sc)
-{
- DPRINTFN(0, "%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));
-}
-
-static uint8_t
-uhci_dump_td(uhci_td_t *p)
-{
- uint32_t td_next;
- uint32_t td_status;
- uint32_t td_token;
- uint8_t temp;
-
- usb2_pc_cpu_invalidate(p->page_cache);
-
- td_next = le32toh(p->td_next);
- td_status = le32toh(p->td_status);
- td_token = le32toh(p->td_token);
-
- /*
- * Check whether the link pointer in this TD marks the link pointer
- * as end of queue:
- */
- temp = ((td_next & UHCI_PTR_T) || (td_next == 0));
-
- printf("TD(%p) at 0x%08x = link=0x%08x status=0x%08x "
- "token=0x%08x buffer=0x%08x\n",
- p,
- le32toh(p->td_self),
- td_next,
- td_status,
- td_token,
- le32toh(p->td_buffer));
-
- printf("TD(%p) td_next=%s%s%s td_status=%s%s%s%s%s%s%s%s%s%s%s, errcnt=%d, actlen=%d pid=%02x,"
- "addr=%d,endpt=%d,D=%d,maxlen=%d\n",
- p,
- (td_next & 1) ? "-T" : "",
- (td_next & 2) ? "-Q" : "",
- (td_next & 4) ? "-VF" : "",
- (td_status & UHCI_TD_BITSTUFF) ? "-BITSTUFF" : "",
- (td_status & UHCI_TD_CRCTO) ? "-CRCTO" : "",
- (td_status & UHCI_TD_NAK) ? "-NAK" : "",
- (td_status & UHCI_TD_BABBLE) ? "-BABBLE" : "",
- (td_status & UHCI_TD_DBUFFER) ? "-DBUFFER" : "",
- (td_status & UHCI_TD_STALLED) ? "-STALLED" : "",
- (td_status & UHCI_TD_ACTIVE) ? "-ACTIVE" : "",
- (td_status & UHCI_TD_IOC) ? "-IOC" : "",
- (td_status & UHCI_TD_IOS) ? "-IOS" : "",
- (td_status & UHCI_TD_LS) ? "-LS" : "",
- (td_status & UHCI_TD_SPD) ? "-SPD" : "",
- UHCI_TD_GET_ERRCNT(td_status),
- UHCI_TD_GET_ACTLEN(td_status),
- UHCI_TD_GET_PID(td_token),
- UHCI_TD_GET_DEVADDR(td_token),
- UHCI_TD_GET_ENDPT(td_token),
- UHCI_TD_GET_DT(td_token),
- UHCI_TD_GET_MAXLEN(td_token));
-
- return (temp);
-}
-
-static uint8_t
-uhci_dump_qh(uhci_qh_t *sqh)
-{
- uint8_t temp;
- uint32_t qh_h_next;
- uint32_t qh_e_next;
-
- usb2_pc_cpu_invalidate(sqh->page_cache);
-
- qh_h_next = le32toh(sqh->qh_h_next);
- qh_e_next = le32toh(sqh->qh_e_next);
-
- DPRINTFN(0, "QH(%p) at 0x%08x: h_next=0x%08x e_next=0x%08x\n", sqh,
- le32toh(sqh->qh_self), qh_h_next, qh_e_next);
-
- temp = ((((sqh->h_next != NULL) && !(qh_h_next & UHCI_PTR_T)) ? 1 : 0) |
- (((sqh->e_next != NULL) && !(qh_e_next & UHCI_PTR_T)) ? 2 : 0));
-
- return (temp);
-}
-
-static void
-uhci_dump_all(uhci_softc_t *sc)
-{
- uhci_dumpregs(sc);
- uhci_dump_qh(sc->sc_ls_ctl_p_last);
- uhci_dump_qh(sc->sc_fs_ctl_p_last);
- uhci_dump_qh(sc->sc_bulk_p_last);
- uhci_dump_qh(sc->sc_last_qh_p);
-}
-
-static void
-uhci_dump_qhs(uhci_qh_t *sqh)
-{
- uint8_t temp;
-
- temp = 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 (temp & 1)
- uhci_dump_qhs(sqh->h_next);
- else
- DPRINTF("No QH\n");
-
- if (temp & 2)
- uhci_dump_tds(sqh->e_next);
- else
- DPRINTF("No TD\n");
-}
-
-static void
-uhci_dump_tds(uhci_td_t *td)
-{
- for (;
- td != NULL;
- td = td->obj_next) {
- if (uhci_dump_td(td)) {
- break;
- }
- }
-}
-
-#endif
-
-/*
- * Let the last QH loop back to the full 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.
- */
-static void
-uhci_add_loop(uhci_softc_t *sc)
-{
- struct uhci_qh *qh_lst;
- struct uhci_qh *qh_rec;
-
-#if USB_DEBUG
- if (uhcinoloop) {
- return;
- }
-#endif
- if (++(sc->sc_loops) == 1) {
- DPRINTFN(6, "add\n");
-
- qh_lst = sc->sc_last_qh_p;
- qh_rec = sc->sc_reclaim_qh_p;
-
- /* NOTE: we don't loop back the soft pointer */
-
- qh_lst->qh_h_next = qh_rec->qh_self;
- usb2_pc_cpu_flush(qh_lst->page_cache);
- }
-}
-
-static void
-uhci_rem_loop(uhci_softc_t *sc)
-{
- struct uhci_qh *qh_lst;
-
-#if USB_DEBUG
- if (uhcinoloop) {
- return;
- }
-#endif
- if (--(sc->sc_loops) == 0) {
- DPRINTFN(6, "remove\n");
-
- qh_lst = sc->sc_last_qh_p;
- qh_lst->qh_h_next = htole32(UHCI_PTR_T);
- usb2_pc_cpu_flush(qh_lst->page_cache);
- }
-}
-
-static void
-uhci_transfer_intr_enqueue(struct usb2_xfer *xfer)
-{
- /* check for early completion */
- if (uhci_check_transfer(xfer)) {
- return;
- }
- /* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
-
- /* start timeout, if any */
- if (xfer->timeout != 0) {
- usb2_transfer_timeout_ms(xfer, &uhci_timeout, xfer->timeout);
- }
-}
-
-#define UHCI_APPEND_TD(std,last) (last) = _uhci_append_td(std,last)
-static uhci_td_t *
-_uhci_append_td(uhci_td_t *std, uhci_td_t *last)
-{
- DPRINTFN(11, "%p to %p\n", std, last);
-
- /* (sc->sc_bus.mtx) must be locked */
-
- std->next = last->next;
- std->td_next = last->td_next;
-
- std->prev = last;
-
- usb2_pc_cpu_flush(std->page_cache);
-
- /*
- * the last->next->prev is never followed: std->next->prev = std;
- */
- last->next = std;
- last->td_next = std->td_self;
-
- usb2_pc_cpu_flush(last->page_cache);
-
- return (std);
-}
-
-#define UHCI_APPEND_QH(sqh,last) (last) = _uhci_append_qh(sqh,last)
-static uhci_qh_t *
-_uhci_append_qh(uhci_qh_t *sqh, uhci_qh_t *last)
-{
- DPRINTFN(11, "%p to %p\n", sqh, last);
-
- if (sqh->h_prev != NULL) {
- /* should not happen */
- DPRINTFN(0, "QH already linked!\n");
- return (last);
- }
- /* (sc->sc_bus.mtx) must be locked */
-
- sqh->h_next = last->h_next;
- sqh->qh_h_next = last->qh_h_next;
-
- sqh->h_prev = last;
-
- usb2_pc_cpu_flush(sqh->page_cache);
-
- /*
- * The "last->h_next->h_prev" is never followed:
- *
- * "sqh->h_next->h_prev" = sqh;
- */
-
- last->h_next = sqh;
- last->qh_h_next = sqh->qh_self;
-
- usb2_pc_cpu_flush(last->page_cache);
-
- return (sqh);
-}
-
-/**/
-
-#define UHCI_REMOVE_TD(std,last) (last) = _uhci_remove_td(std,last)
-static uhci_td_t *
-_uhci_remove_td(uhci_td_t *std, uhci_td_t *last)
-{
- DPRINTFN(11, "%p from %p\n", std, last);
-
- /* (sc->sc_bus.mtx) must be locked */
-
- std->prev->next = std->next;
- std->prev->td_next = std->td_next;
-
- usb2_pc_cpu_flush(std->prev->page_cache);
-
- if (std->next) {
- std->next->prev = std->prev;
- usb2_pc_cpu_flush(std->next->page_cache);
- }
- return ((last == std) ? std->prev : last);
-}
-
-#define UHCI_REMOVE_QH(sqh,last) (last) = _uhci_remove_qh(sqh,last)
-static uhci_qh_t *
-_uhci_remove_qh(uhci_qh_t *sqh, uhci_qh_t *last)
-{
- DPRINTFN(11, "%p from %p\n", sqh, last);
-
- /* (sc->sc_bus.mtx) must be locked */
-
- /* only remove if not removed from a queue */
- if (sqh->h_prev) {
-
- sqh->h_prev->h_next = sqh->h_next;
- sqh->h_prev->qh_h_next = sqh->qh_h_next;
-
- usb2_pc_cpu_flush(sqh->h_prev->page_cache);
-
- if (sqh->h_next) {
- sqh->h_next->h_prev = sqh->h_prev;
- usb2_pc_cpu_flush(sqh->h_next->page_cache);
- }
- last = ((last == sqh) ? sqh->h_prev : last);
-
- sqh->h_prev = 0;
-
- usb2_pc_cpu_flush(sqh->page_cache);
- }
- return (last);
-}
-
-static void
-uhci_isoc_done(uhci_softc_t *sc, struct usb2_xfer *xfer)
-{
- struct usb2_page_search res;
- uint32_t nframes = xfer->nframes;
- uint32_t status;
- uint32_t offset = 0;
- uint32_t *plen = xfer->frlengths;
- uint16_t len = 0;
- uhci_td_t *td = xfer->td_transfer_first;
- uhci_td_t **pp_last = &sc->sc_isoc_p_last[xfer->qh_pos];
-
- DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
- xfer, xfer->pipe);
-
- /* sync any DMA memory before doing fixups */
-
- usb2_bdma_post_sync(xfer);
-
- while (nframes--) {
- if (td == NULL) {
- panic("%s:%d: out of TD's\n",
- __FUNCTION__, __LINE__);
- }
- if (pp_last >= &sc->sc_isoc_p_last[UHCI_VFRAMELIST_COUNT]) {
- pp_last = &sc->sc_isoc_p_last[0];
- }
-#if USB_DEBUG
- if (uhcidebug > 5) {
- DPRINTF("isoc TD\n");
- uhci_dump_td(td);
- }
-#endif
- usb2_pc_cpu_invalidate(td->page_cache);
- status = le32toh(td->td_status);
-
- len = UHCI_TD_GET_ACTLEN(status);
-
- if (len > *plen) {
- len = *plen;
- }
- if (td->fix_pc) {
-
- usb2_get_page(td->fix_pc, 0, &res);
-
- /* copy data from fixup location to real location */
-
- usb2_pc_cpu_invalidate(td->fix_pc);
-
- usb2_copy_in(xfer->frbuffers, offset,
- res.buffer, len);
- }
- offset += *plen;
-
- *plen = len;
-
- /* remove TD from schedule */
- UHCI_REMOVE_TD(td, *pp_last);
-
- pp_last++;
- plen++;
- td = td->obj_next;
- }
-
- xfer->aframes = xfer->nframes;
-}
-
-static usb2_error_t
-uhci_non_isoc_done_sub(struct usb2_xfer *xfer)
-{
- struct usb2_page_search res;
- uhci_td_t *td;
- uhci_td_t *td_alt_next;
- uint32_t status;
- uint32_t token;
- uint16_t len;
-
- td = xfer->td_transfer_cache;
- td_alt_next = td->alt_next;
-
- if (xfer->aframes != xfer->nframes) {
- xfer->frlengths[xfer->aframes] = 0;
- }
- while (1) {
-
- usb2_pc_cpu_invalidate(td->page_cache);
- status = le32toh(td->td_status);
- token = le32toh(td->td_token);
-
- /*
- * Verify the status and add
- * up the actual length:
- */
-
- len = UHCI_TD_GET_ACTLEN(status);
- if (len > td->len) {
- /* should not happen */
- DPRINTF("Invalid status length, "
- "0x%04x/0x%04x bytes\n", len, td->len);
- status |= UHCI_TD_STALLED;
-
- } else if ((xfer->aframes != xfer->nframes) && (len > 0)) {
-
- if (td->fix_pc) {
-
- usb2_get_page(td->fix_pc, 0, &res);
-
- /*
- * copy data from fixup location to real
- * location
- */
-
- usb2_pc_cpu_invalidate(td->fix_pc);
-
- usb2_copy_in(xfer->frbuffers + xfer->aframes,
- xfer->frlengths[xfer->aframes], res.buffer, len);
- }
- /* update actual length */
-
- xfer->frlengths[xfer->aframes] += len;
- }
- /* Check for last transfer */
- if (((void *)td) == xfer->td_transfer_last) {
- td = NULL;
- break;
- }
- if (status & UHCI_TD_STALLED) {
- /* the transfer is finished */
- td = NULL;
- break;
- }
- /* Check for short transfer */
- if (len != td->len) {
- if (xfer->flags_int.short_frames_ok) {
- /* follow alt next */
- td = td->alt_next;
- } else {
- /* the transfer is finished */
- td = NULL;
- }
- break;
- }
- td = td->obj_next;
-
- if (td->alt_next != td_alt_next) {
- /* this USB frame is complete */
- break;
- }
- }
-
- /* update transfer cache */
-
- xfer->td_transfer_cache = td;
-
- /* update data toggle */
-
- xfer->pipe->toggle_next = (token & UHCI_TD_SET_DT(1)) ? 0 : 1;
-
-#if USB_DEBUG
- if (status & UHCI_TD_ERROR) {
- DPRINTFN(11, "error, addr=%d, endpt=0x%02x, frame=0x%02x "
- "status=%s%s%s%s%s%s%s%s%s%s%s\n",
- xfer->address, xfer->endpoint, xfer->aframes,
- (status & UHCI_TD_BITSTUFF) ? "[BITSTUFF]" : "",
- (status & UHCI_TD_CRCTO) ? "[CRCTO]" : "",
- (status & UHCI_TD_NAK) ? "[NAK]" : "",
- (status & UHCI_TD_BABBLE) ? "[BABBLE]" : "",
- (status & UHCI_TD_DBUFFER) ? "[DBUFFER]" : "",
- (status & UHCI_TD_STALLED) ? "[STALLED]" : "",
- (status & UHCI_TD_ACTIVE) ? "[ACTIVE]" : "[NOT_ACTIVE]",
- (status & UHCI_TD_IOC) ? "[IOC]" : "",
- (status & UHCI_TD_IOS) ? "[IOS]" : "",
- (status & UHCI_TD_LS) ? "[LS]" : "",
- (status & UHCI_TD_SPD) ? "[SPD]" : "");
- }
-#endif
- return (status & UHCI_TD_STALLED) ?
- USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION;
-}
-
-static void
-uhci_non_isoc_done(struct usb2_xfer *xfer)
-{
- usb2_error_t err = 0;
-
- DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
- xfer, xfer->pipe);
-
-#if USB_DEBUG
- if (uhcidebug > 10) {
- uhci_dump_tds(xfer->td_transfer_first);
- }
-#endif
-
- /* sync any DMA memory before doing fixups */
-
- usb2_bdma_post_sync(xfer);
-
- /* reset scanner */
-
- xfer->td_transfer_cache = xfer->td_transfer_first;
-
- if (xfer->flags_int.control_xfr) {
- if (xfer->flags_int.control_hdr) {
-
- err = uhci_non_isoc_done_sub(xfer);
- }
- xfer->aframes = 1;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
- while (xfer->aframes != xfer->nframes) {
-
- err = uhci_non_isoc_done_sub(xfer);
- xfer->aframes++;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- err = uhci_non_isoc_done_sub(xfer);
- }
-done:
- uhci_device_done(xfer, err);
-}
-
-/*------------------------------------------------------------------------*
- * uhci_check_transfer_sub
- *
- * The main purpose of this function is to update the data-toggle
- * in case it is wrong.
- *------------------------------------------------------------------------*/
-static void
-uhci_check_transfer_sub(struct usb2_xfer *xfer)
-{
- uhci_qh_t *qh;
- uhci_td_t *td;
- uhci_td_t *td_alt_next;
-
- uint32_t td_token;
- uint32_t td_self;
-
- td = xfer->td_transfer_cache;
- qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- td_token = td->obj_next->td_token;
- td = td->alt_next;
- xfer->td_transfer_cache = td;
- td_self = td->td_self;
- td_alt_next = td->alt_next;
-
- if ((td->td_token ^ td_token) & htole32(UHCI_TD_SET_DT(1))) {
-
- /*
- * The data toggle is wrong and
- * we need to switch it !
- */
-
- while (1) {
-
- td->td_token ^= htole32(UHCI_TD_SET_DT(1));
- usb2_pc_cpu_flush(td->page_cache);
-
- if (td == xfer->td_transfer_last) {
- /* last transfer */
- break;
- }
- td = td->obj_next;
-
- if (td->alt_next != td_alt_next) {
- /* next frame */
- break;
- }
- }
- }
- /* update the QH */
- qh->qh_e_next = td_self;
- usb2_pc_cpu_flush(qh->page_cache);
-
- DPRINTFN(13, "xfer=%p following alt next\n", xfer);
-}
-
-/*------------------------------------------------------------------------*
- * uhci_check_transfer
- *
- * Return values:
- * 0: USB transfer is not finished
- * Else: USB transfer is finished
- *------------------------------------------------------------------------*/
-static uint8_t
-uhci_check_transfer(struct usb2_xfer *xfer)
-{
- uint32_t status;
- uint32_t token;
- uhci_td_t *td;
-
- DPRINTFN(16, "xfer=%p checking transfer\n", xfer);
-
- if (xfer->pipe->methods == &uhci_device_isoc_methods) {
- /* isochronous transfer */
-
- td = xfer->td_transfer_last;
-
- usb2_pc_cpu_invalidate(td->page_cache);
- status = le32toh(td->td_status);
-
- /* check also if the first is complete */
-
- td = xfer->td_transfer_first;
-
- usb2_pc_cpu_invalidate(td->page_cache);
- status |= le32toh(td->td_status);
-
- if (!(status & UHCI_TD_ACTIVE)) {
- uhci_device_done(xfer, USB_ERR_NORMAL_COMPLETION);
- goto transferred;
- }
- } else {
- /* non-isochronous transfer */
-
- /*
- * check whether there is an error somewhere
- * in the middle, or whether there was a short
- * packet (SPD and not ACTIVE)
- */
- td = xfer->td_transfer_cache;
-
- while (1) {
- usb2_pc_cpu_invalidate(td->page_cache);
- status = le32toh(td->td_status);
- token = le32toh(td->td_token);
-
- /*
- * if there is an active TD the transfer isn't done
- */
- if (status & UHCI_TD_ACTIVE) {
- /* update cache */
- xfer->td_transfer_cache = td;
- goto done;
- }
- /*
- * last transfer descriptor makes the transfer done
- */
- if (((void *)td) == xfer->td_transfer_last) {
- break;
- }
- /*
- * any kind of error makes the transfer done
- */
- if (status & UHCI_TD_STALLED) {
- break;
- }
- /*
- * check if we reached the last packet
- * or if there is a short packet:
- */
- if ((td->td_next == htole32(UHCI_PTR_T)) ||
- (UHCI_TD_GET_ACTLEN(status) < td->len)) {
-
- if (xfer->flags_int.short_frames_ok) {
- /* follow alt next */
- if (td->alt_next) {
- /* update cache */
- xfer->td_transfer_cache = td;
- uhci_check_transfer_sub(xfer);
- goto done;
- }
- }
- /* transfer is done */
- break;
- }
- td = td->obj_next;
- }
- uhci_non_isoc_done(xfer);
- goto transferred;
- }
-
-done:
- DPRINTFN(13, "xfer=%p is still active\n", xfer);
- return (0);
-
-transferred:
- return (1);
-}
-
-static void
-uhci_interrupt_poll(uhci_softc_t *sc)
-{
- struct usb2_xfer *xfer;
-
-repeat:
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
- /*
- * check if transfer is transferred
- */
- if (uhci_check_transfer(xfer)) {
- /* queue has been modified */
- goto repeat;
- }
- }
-}
-
-/*------------------------------------------------------------------------*
- * uhci_interrupt - UHCI interrupt handler
- *
- * NOTE: Do not access "sc->sc_bus.bdev" inside the interrupt handler,
- * hence the interrupt handler will be setup before "sc->sc_bus.bdev"
- * is present !
- *------------------------------------------------------------------------*/
-void
-uhci_interrupt(uhci_softc_t *sc)
-{
- uint32_t status;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- DPRINTFN(16, "real interrupt\n");
-
-#if USB_DEBUG
- if (uhcidebug > 15) {
- uhci_dumpregs(sc);
- }
-#endif
- status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS;
- if (status == 0) {
- /* the interrupt was not for us */
- goto done;
- }
- if (status & (UHCI_STS_RD | UHCI_STS_HSE |
- UHCI_STS_HCPE | UHCI_STS_HCH)) {
-
- if (status & UHCI_STS_RD) {
-#if USB_DEBUG
- printf("%s: resume detect\n",
- __FUNCTION__);
-#endif
- }
- if (status & UHCI_STS_HSE) {
- printf("%s: host system error\n",
- __FUNCTION__);
- }
- if (status & UHCI_STS_HCPE) {
- printf("%s: host controller process error\n",
- __FUNCTION__);
- }
- if (status & UHCI_STS_HCH) {
- /* no acknowledge needed */
- DPRINTF("%s: host controller halted\n",
- __FUNCTION__);
-#if USB_DEBUG
- if (uhcidebug > 0) {
- uhci_dump_all(sc);
- }
-#endif
- }
- }
- /* get acknowledge bits */
- status &= (UHCI_STS_USBINT |
- UHCI_STS_USBEI |
- UHCI_STS_RD |
- UHCI_STS_HSE |
- UHCI_STS_HCPE);
-
- if (status == 0) {
- /* nothing to acknowledge */
- goto done;
- }
- /* acknowledge interrupts */
- UWRITE2(sc, UHCI_STS, status);
-
- /* poll all the USB transfers */
- uhci_interrupt_poll(sc);
-
-done:
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-/*
- * called when a request does not complete
- */
-static void
-uhci_timeout(void *arg)
-{
- struct usb2_xfer *xfer = arg;
-
- DPRINTF("xfer=%p\n", xfer);
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- /* transfer is transferred */
- uhci_device_done(xfer, USB_ERR_TIMEOUT);
-}
-
-static void
-uhci_do_poll(struct usb2_bus *bus)
-{
- struct uhci_softc *sc = UHCI_BUS2SC(bus);
-
- USB_BUS_LOCK(&sc->sc_bus);
- uhci_interrupt_poll(sc);
- uhci_root_ctrl_poll(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-static void
-uhci_setup_standard_chain_sub(struct uhci_std_temp *temp)
-{
- uhci_td_t *td;
- uhci_td_t *td_next;
- uhci_td_t *td_alt_next;
- uint32_t average;
- uint32_t len_old;
- uint8_t shortpkt_old;
- uint8_t precompute;
-
- td_alt_next = NULL;
- shortpkt_old = temp->shortpkt;
- len_old = temp->len;
- precompute = 1;
-
- /* software is used to detect short incoming transfers */
-
- if ((temp->td_token & htole32(UHCI_TD_PID)) == htole32(UHCI_TD_PID_IN)) {
- temp->td_status |= htole32(UHCI_TD_SPD);
- } else {
- temp->td_status &= ~htole32(UHCI_TD_SPD);
- }
-
- temp->ml.buf_offset = 0;
-
-restart:
-
- temp->td_token &= ~htole32(UHCI_TD_SET_MAXLEN(0));
- temp->td_token |= htole32(UHCI_TD_SET_MAXLEN(temp->average));
-
- td = temp->td;
- td_next = temp->td_next;
-
- while (1) {
-
- if (temp->len == 0) {
-
- if (temp->shortpkt) {
- break;
- }
- /* send a Zero Length Packet, ZLP, last */
-
- temp->shortpkt = 1;
- temp->td_token |= htole32(UHCI_TD_SET_MAXLEN(0));
- average = 0;
-
- } else {
-
- average = temp->average;
-
- if (temp->len < average) {
- temp->shortpkt = 1;
- temp->td_token &= ~htole32(UHCI_TD_SET_MAXLEN(0));
- temp->td_token |= htole32(UHCI_TD_SET_MAXLEN(temp->len));
- average = temp->len;
- }
- }
-
- if (td_next == NULL) {
- panic("%s: out of UHCI transfer descriptors!", __FUNCTION__);
- }
- /* get next TD */
-
- td = td_next;
- td_next = td->obj_next;
-
- /* check if we are pre-computing */
-
- if (precompute) {
-
- /* update remaining length */
-
- temp->len -= average;
-
- continue;
- }
- /* fill out current TD */
-
- td->td_status = temp->td_status;
- td->td_token = temp->td_token;
-
- /* update data toggle */
-
- temp->td_token ^= htole32(UHCI_TD_SET_DT(1));
-
- if (average == 0) {
-
- td->len = 0;
- td->td_buffer = 0;
- td->fix_pc = NULL;
-
- } else {
-
- /* update remaining length */
-
- temp->len -= average;
-
- td->len = average;
-
- /* fill out buffer pointer and do fixup, if any */
-
- uhci_mem_layout_fixup(&temp->ml, td);
- }
-
- td->alt_next = td_alt_next;
-
- if ((td_next == td_alt_next) && temp->setup_alt_next) {
- /* we need to receive these frames one by one ! */
- td->td_status |= htole32(UHCI_TD_IOC);
- td->td_next = htole32(UHCI_PTR_T);
- } else {
- if (td_next) {
- /* link the current TD with the next one */
- td->td_next = td_next->td_self;
- }
- }
-
- usb2_pc_cpu_flush(td->page_cache);
- }
-
- if (precompute) {
- precompute = 0;
-
- /* setup alt next pointer, if any */
- if (temp->short_frames_ok) {
- if (temp->setup_alt_next) {
- td_alt_next = td_next;
- }
- } else {
- /* we use this field internally */
- td_alt_next = td_next;
- }
-
- /* restore */
- temp->shortpkt = shortpkt_old;
- temp->len = len_old;
- goto restart;
- }
- temp->td = td;
- temp->td_next = td_next;
-}
-
-static uhci_td_t *
-uhci_setup_standard_chain(struct usb2_xfer *xfer)
-{
- struct uhci_std_temp temp;
- uhci_td_t *td;
- uint32_t x;
-
- DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
- xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
-
- temp.average = xfer->max_frame_size;
- temp.max_frame_size = xfer->max_frame_size;
-
- /* toggle the DMA set we are using */
- xfer->flags_int.curr_dma_set ^= 1;
-
- /* get next DMA set */
- td = xfer->td_start[xfer->flags_int.curr_dma_set];
- xfer->td_transfer_first = td;
- xfer->td_transfer_cache = td;
-
- temp.td = NULL;
- temp.td_next = td;
- temp.setup_alt_next = xfer->flags_int.short_frames_ok;
- temp.short_frames_ok = xfer->flags_int.short_frames_ok;
-
- uhci_mem_layout_init(&temp.ml, xfer);
-
- temp.td_status =
- htole32(UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) |
- UHCI_TD_ACTIVE));
-
- if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
- temp.td_status |= htole32(UHCI_TD_LS);
- }
- temp.td_token =
- htole32(UHCI_TD_SET_ENDPT(xfer->endpoint) |
- UHCI_TD_SET_DEVADDR(xfer->address));
-
- if (xfer->pipe->toggle_next) {
- /* DATA1 is next */
- temp.td_token |= htole32(UHCI_TD_SET_DT(1));
- }
- /* check if we should prepend a setup message */
-
- if (xfer->flags_int.control_xfr) {
-
- if (xfer->flags_int.control_hdr) {
-
- temp.td_token &= htole32(UHCI_TD_SET_DEVADDR(0x7F) |
- UHCI_TD_SET_ENDPT(0xF));
- temp.td_token |= htole32(UHCI_TD_PID_SETUP |
- UHCI_TD_SET_DT(0));
-
- temp.len = xfer->frlengths[0];
- temp.ml.buf_pc = xfer->frbuffers + 0;
- temp.shortpkt = temp.len ? 1 : 0;
-
- uhci_setup_standard_chain_sub(&temp);
- }
- x = 1;
- } else {
- x = 0;
- }
-
- while (x != xfer->nframes) {
-
- /* DATA0 / DATA1 message */
-
- temp.len = xfer->frlengths[x];
- temp.ml.buf_pc = xfer->frbuffers + x;
-
- x++;
-
- if (x == xfer->nframes) {
- temp.setup_alt_next = 0;
- }
- /*
- * Keep previous data toggle,
- * device address and endpoint number:
- */
-
- temp.td_token &= htole32(UHCI_TD_SET_DEVADDR(0x7F) |
- UHCI_TD_SET_ENDPT(0xF) |
- UHCI_TD_SET_DT(1));
-
- if (temp.len == 0) {
-
- /* make sure that we send an USB packet */
-
- temp.shortpkt = 0;
-
- } else {
-
- /* regular data transfer */
-
- temp.shortpkt = (xfer->flags.force_short_xfer) ? 0 : 1;
- }
-
- /* set endpoint direction */
-
- temp.td_token |=
- (UE_GET_DIR(xfer->endpoint) == UE_DIR_IN) ?
- htole32(UHCI_TD_PID_IN) :
- htole32(UHCI_TD_PID_OUT);
-
- uhci_setup_standard_chain_sub(&temp);
- }
-
- /* check if we should append a status stage */
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- /*
- * send a DATA1 message and reverse the current endpoint
- * direction
- */
-
- temp.td_token &= htole32(UHCI_TD_SET_DEVADDR(0x7F) |
- UHCI_TD_SET_ENDPT(0xF) |
- UHCI_TD_SET_DT(1));
- temp.td_token |=
- (UE_GET_DIR(xfer->endpoint) == UE_DIR_OUT) ?
- htole32(UHCI_TD_PID_IN | UHCI_TD_SET_DT(1)) :
- htole32(UHCI_TD_PID_OUT | UHCI_TD_SET_DT(1));
-
- temp.len = 0;
- temp.ml.buf_pc = NULL;
- temp.shortpkt = 0;
-
- uhci_setup_standard_chain_sub(&temp);
- }
- td = temp.td;
-
- td->td_next = htole32(UHCI_PTR_T);
-
- /* set interrupt bit */
-
- td->td_status |= htole32(UHCI_TD_IOC);
-
- usb2_pc_cpu_flush(td->page_cache);
-
- /* must have at least one frame! */
-
- xfer->td_transfer_last = td;
-
-#if USB_DEBUG
- if (uhcidebug > 8) {
- DPRINTF("nexttog=%d; data before transfer:\n",
- xfer->pipe->toggle_next);
- uhci_dump_tds(xfer->td_transfer_first);
- }
-#endif
- return (xfer->td_transfer_first);
-}
-
-/* NOTE: "done" can be run two times in a row,
- * from close and from interrupt
- */
-
-static void
-uhci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
-{
- struct usb2_pipe_methods *methods = xfer->pipe->methods;
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
- uhci_qh_t *qh;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
- xfer, xfer->pipe, error);
-
- qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
- if (qh) {
- usb2_pc_cpu_invalidate(qh->page_cache);
- }
- if (xfer->flags_int.bandwidth_reclaimed) {
- xfer->flags_int.bandwidth_reclaimed = 0;
- uhci_rem_loop(sc);
- }
- if (methods == &uhci_device_bulk_methods) {
- UHCI_REMOVE_QH(qh, sc->sc_bulk_p_last);
- }
- if (methods == &uhci_device_ctrl_methods) {
- if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
- UHCI_REMOVE_QH(qh, sc->sc_ls_ctl_p_last);
- } else {
- UHCI_REMOVE_QH(qh, sc->sc_fs_ctl_p_last);
- }
- }
- if (methods == &uhci_device_intr_methods) {
- UHCI_REMOVE_QH(qh, sc->sc_intr_p_last[xfer->qh_pos]);
- }
- /*
- * Only finish isochronous transfers once
- * which will update "xfer->frlengths".
- */
- if (xfer->td_transfer_first &&
- xfer->td_transfer_last) {
- if (methods == &uhci_device_isoc_methods) {
- uhci_isoc_done(sc, xfer);
- }
- xfer->td_transfer_first = NULL;
- xfer->td_transfer_last = NULL;
- }
- /* dequeue transfer and start next transfer */
- usb2_transfer_done(xfer, error);
-}
-
-/*------------------------------------------------------------------------*
- * uhci bulk support
- *------------------------------------------------------------------------*/
-static void
-uhci_device_bulk_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uhci_device_bulk_close(struct usb2_xfer *xfer)
-{
- uhci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-uhci_device_bulk_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uhci_device_bulk_start(struct usb2_xfer *xfer)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
- uhci_td_t *td;
- uhci_qh_t *qh;
-
- /* setup TD's */
- td = uhci_setup_standard_chain(xfer);
-
- /* setup QH */
- qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- qh->e_next = td;
- qh->qh_e_next = td->td_self;
-
- if (xfer->xroot->udev->pwr_save.suspended == 0) {
- UHCI_APPEND_QH(qh, sc->sc_bulk_p_last);
- uhci_add_loop(sc);
- xfer->flags_int.bandwidth_reclaimed = 1;
- } else {
- usb2_pc_cpu_flush(qh->page_cache);
- }
-
- /* put transfer on interrupt queue */
- uhci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods uhci_device_bulk_methods =
-{
- .open = uhci_device_bulk_open,
- .close = uhci_device_bulk_close,
- .enter = uhci_device_bulk_enter,
- .start = uhci_device_bulk_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * uhci control support
- *------------------------------------------------------------------------*/
-static void
-uhci_device_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uhci_device_ctrl_close(struct usb2_xfer *xfer)
-{
- uhci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-uhci_device_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uhci_device_ctrl_start(struct usb2_xfer *xfer)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
- uhci_qh_t *qh;
- uhci_td_t *td;
-
- /* setup TD's */
- td = uhci_setup_standard_chain(xfer);
-
- /* setup QH */
- qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- qh->e_next = td;
- qh->qh_e_next = td->td_self;
-
- /*
- * NOTE: some devices choke on bandwidth- reclamation for control
- * transfers
- */
- if (xfer->xroot->udev->pwr_save.suspended == 0) {
- if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
- UHCI_APPEND_QH(qh, sc->sc_ls_ctl_p_last);
- } else {
- UHCI_APPEND_QH(qh, sc->sc_fs_ctl_p_last);
- }
- } else {
- usb2_pc_cpu_flush(qh->page_cache);
- }
- /* put transfer on interrupt queue */
- uhci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods uhci_device_ctrl_methods =
-{
- .open = uhci_device_ctrl_open,
- .close = uhci_device_ctrl_close,
- .enter = uhci_device_ctrl_enter,
- .start = uhci_device_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * uhci interrupt support
- *------------------------------------------------------------------------*/
-static void
-uhci_device_intr_open(struct usb2_xfer *xfer)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
- uint16_t best;
- uint16_t bit;
- uint16_t x;
-
- best = 0;
- bit = UHCI_IFRAMELIST_COUNT / 2;
- while (bit) {
- if (xfer->interval >= bit) {
- x = bit;
- best = bit;
- while (x & bit) {
- if (sc->sc_intr_stat[x] <
- sc->sc_intr_stat[best]) {
- best = x;
- }
- x++;
- }
- break;
- }
- bit >>= 1;
- }
-
- sc->sc_intr_stat[best]++;
- xfer->qh_pos = best;
-
- DPRINTFN(3, "best=%d interval=%d\n",
- best, xfer->interval);
-}
-
-static void
-uhci_device_intr_close(struct usb2_xfer *xfer)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
-
- sc->sc_intr_stat[xfer->qh_pos]--;
-
- uhci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-uhci_device_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uhci_device_intr_start(struct usb2_xfer *xfer)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
- uhci_qh_t *qh;
- uhci_td_t *td;
-
- /* setup TD's */
- td = uhci_setup_standard_chain(xfer);
-
- /* setup QH */
- qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- qh->e_next = td;
- qh->qh_e_next = td->td_self;
-
- if (xfer->xroot->udev->pwr_save.suspended == 0) {
-
- /* enter QHs into the controller data structures */
- UHCI_APPEND_QH(qh, sc->sc_intr_p_last[xfer->qh_pos]);
-
- } else {
- usb2_pc_cpu_flush(qh->page_cache);
- }
-
- /* put transfer on interrupt queue */
- uhci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods uhci_device_intr_methods =
-{
- .open = uhci_device_intr_open,
- .close = uhci_device_intr_close,
- .enter = uhci_device_intr_enter,
- .start = uhci_device_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * uhci isochronous support
- *------------------------------------------------------------------------*/
-static void
-uhci_device_isoc_open(struct usb2_xfer *xfer)
-{
- uhci_td_t *td;
- uint32_t td_token;
- uint8_t ds;
-
- td_token =
- (UE_GET_DIR(xfer->endpoint) == UE_DIR_IN) ?
- UHCI_TD_IN(0, xfer->endpoint, xfer->address, 0) :
- UHCI_TD_OUT(0, xfer->endpoint, xfer->address, 0);
-
- td_token = htole32(td_token);
-
- /* initialize all TD's */
-
- for (ds = 0; ds != 2; ds++) {
-
- for (td = xfer->td_start[ds]; td; td = td->obj_next) {
-
- /* mark TD as inactive */
- td->td_status = htole32(UHCI_TD_IOS);
- td->td_token = td_token;
-
- usb2_pc_cpu_flush(td->page_cache);
- }
- }
-}
-
-static void
-uhci_device_isoc_close(struct usb2_xfer *xfer)
-{
- uhci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-uhci_device_isoc_enter(struct usb2_xfer *xfer)
-{
- struct uhci_mem_layout ml;
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
- uint32_t nframes;
- uint32_t temp;
- uint32_t *plen;
-
-#if USB_DEBUG
- uint8_t once = 1;
-
-#endif
- uhci_td_t *td;
- uhci_td_t *td_last = NULL;
- uhci_td_t **pp_last;
-
- DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
- xfer, xfer->pipe->isoc_next, xfer->nframes);
-
- nframes = UREAD2(sc, UHCI_FRNUM);
-
- temp = (nframes - xfer->pipe->isoc_next) &
- (UHCI_VFRAMELIST_COUNT - 1);
-
- if ((xfer->pipe->is_synced == 0) ||
- (temp < xfer->nframes)) {
- /*
- * If there is data underflow or the pipe queue is empty we
- * schedule the transfer a few frames ahead of the current
- * frame position. Else two isochronous transfers might
- * overlap.
- */
- xfer->pipe->isoc_next = (nframes + 3) & (UHCI_VFRAMELIST_COUNT - 1);
- xfer->pipe->is_synced = 1;
- DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next);
- }
- /*
- * compute how many milliseconds the insertion is ahead of the
- * current frame position:
- */
- temp = (xfer->pipe->isoc_next - nframes) &
- (UHCI_VFRAMELIST_COUNT - 1);
-
- /*
- * pre-compute when the isochronous transfer will be finished:
- */
- xfer->isoc_time_complete =
- usb2_isoc_time_expand(&sc->sc_bus, nframes) + temp +
- xfer->nframes;
-
- /* get the real number of frames */
-
- nframes = xfer->nframes;
-
- uhci_mem_layout_init(&ml, xfer);
-
- plen = xfer->frlengths;
-
- /* toggle the DMA set we are using */
- xfer->flags_int.curr_dma_set ^= 1;
-
- /* get next DMA set */
- td = xfer->td_start[xfer->flags_int.curr_dma_set];
- xfer->td_transfer_first = td;
-
- pp_last = &sc->sc_isoc_p_last[xfer->pipe->isoc_next];
-
- /* store starting position */
-
- xfer->qh_pos = xfer->pipe->isoc_next;
-
- while (nframes--) {
- if (td == NULL) {
- panic("%s:%d: out of TD's\n",
- __FUNCTION__, __LINE__);
- }
- if (pp_last >= &sc->sc_isoc_p_last[UHCI_VFRAMELIST_COUNT]) {
- pp_last = &sc->sc_isoc_p_last[0];
- }
- if (*plen > xfer->max_frame_size) {
-#if USB_DEBUG
- if (once) {
- once = 0;
- printf("%s: frame length(%d) exceeds %d "
- "bytes (frame truncated)\n",
- __FUNCTION__, *plen,
- xfer->max_frame_size);
- }
-#endif
- *plen = xfer->max_frame_size;
- }
- /* reuse td_token from last transfer */
-
- td->td_token &= htole32(~UHCI_TD_MAXLEN_MASK);
- td->td_token |= htole32(UHCI_TD_SET_MAXLEN(*plen));
-
- td->len = *plen;
-
- if (td->len == 0) {
- /*
- * Do not call "uhci_mem_layout_fixup()" when the
- * length is zero!
- */
- td->td_buffer = 0;
- td->fix_pc = NULL;
-
- } else {
-
- /* fill out buffer pointer and do fixup, if any */
-
- uhci_mem_layout_fixup(&ml, td);
-
- }
-
- /* update status */
- if (nframes == 0) {
- td->td_status = htole32
- (UHCI_TD_ZERO_ACTLEN
- (UHCI_TD_SET_ERRCNT(0) |
- UHCI_TD_ACTIVE |
- UHCI_TD_IOS |
- UHCI_TD_IOC));
- } else {
- td->td_status = htole32
- (UHCI_TD_ZERO_ACTLEN
- (UHCI_TD_SET_ERRCNT(0) |
- UHCI_TD_ACTIVE |
- UHCI_TD_IOS));
- }
-
- usb2_pc_cpu_flush(td->page_cache);
-
-#if USB_DEBUG
- if (uhcidebug > 5) {
- DPRINTF("TD %d\n", nframes);
- uhci_dump_td(td);
- }
-#endif
- /* insert TD into schedule */
- UHCI_APPEND_TD(td, *pp_last);
- pp_last++;
-
- plen++;
- td_last = td;
- td = td->obj_next;
- }
-
- xfer->td_transfer_last = td_last;
-
- /* update isoc_next */
- xfer->pipe->isoc_next = (pp_last - &sc->sc_isoc_p_last[0]) &
- (UHCI_VFRAMELIST_COUNT - 1);
-}
-
-static void
-uhci_device_isoc_start(struct usb2_xfer *xfer)
-{
- /* put transfer on interrupt queue */
- uhci_transfer_intr_enqueue(xfer);
-}
-
-struct usb2_pipe_methods uhci_device_isoc_methods =
-{
- .open = uhci_device_isoc_open,
- .close = uhci_device_isoc_close,
- .enter = uhci_device_isoc_enter,
- .start = uhci_device_isoc_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * uhci root control support
- *------------------------------------------------------------------------*
- * simulate a hardware hub by handling
- * all the necessary requests
- *------------------------------------------------------------------------*/
-
-static void
-uhci_root_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uhci_root_ctrl_close(struct usb2_xfer *xfer)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_ctrl.xfer == xfer) {
- sc->sc_root_ctrl.xfer = NULL;
- }
- uhci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-/* data structures and routines
- * to emulate the root hub:
- */
-
-static const
-struct usb2_device_descriptor uhci_devd =
-{
- sizeof(struct usb2_device_descriptor),
- 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 const struct uhci_config_desc uhci_confd = {
- .confd = {
- .bLength = sizeof(struct usb2_config_descriptor),
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength[0] = sizeof(uhci_confd),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_SELF_POWERED,
- .bMaxPower = 0 /* max power */
- },
-
- .ifcd = {
- .bLength = sizeof(struct usb2_interface_descriptor),
- .bDescriptorType = UDESC_INTERFACE,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_FSHUB,
- },
-
- .endpd = {
- .bLength = sizeof(struct usb2_endpoint_descriptor),
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = UE_DIR_IN | UHCI_INTR_ENDPT,
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize[0] = 8, /* max packet (63 ports) */
- .bInterval = 255,
- },
-};
-
-static const
-struct usb2_hub_descriptor_min uhci_hubd_piix =
-{
- sizeof(uhci_hubd_piix),
- UDESC_HUB,
- 2,
- {UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0},
- 50, /* power on to power good */
- 0,
- {0x00}, /* both ports are removable */
-};
-
-/*
- * 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 usb2_error_t
-uhci_portreset(uhci_softc_t *sc, uint16_t index, uint8_t use_polling)
-{
- uint16_t port;
- uint16_t x;
- uint8_t lim;
-
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else
- return (USB_ERR_IOERROR);
-
- /*
- * Before we do anything, turn on SOF messages on the USB
- * BUS. Some USB devices do not cope without them!
- */
- if (!(UREAD2(sc, UHCI_CMD) & UHCI_CMD_RS)) {
-
- DPRINTF("Activating SOFs!\n");
-
- UHCICMD(sc, (UHCI_CMD_MAXP | UHCI_CMD_RS));
-
- /* wait a little bit */
- if (use_polling) {
- DELAY(10000);
- } else {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
- }
- }
-
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_PR);
-
- if (use_polling) {
- /* polling */
- DELAY(USB_PORT_ROOT_RESET_DELAY * 1000);
- } else {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_PORT_ROOT_RESET_DELAY));
- }
-
- DPRINTFN(4, "uhci port %d reset, status0 = 0x%04x\n",
- index, UREAD2(sc, port));
-
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
-
-
- mtx_unlock(&sc->sc_bus.bus_mtx);
-
- /*
- * This delay needs to be exactly 100us, else some USB devices
- * fail to attach!
- */
- DELAY(100);
-
- mtx_lock(&sc->sc_bus.bus_mtx);
-
- DPRINTFN(4, "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 = 0; lim < 12; lim++) {
-
- if (use_polling) {
- /* polling */
- DELAY(USB_PORT_RESET_DELAY * 1000);
- } else {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_PORT_RESET_DELAY));
- }
-
- x = UREAD2(sc, port);
-
- DPRINTFN(4, "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(4, "uhci port %d loop %u, device detached\n",
- index, lim);
- goto done;
- }
- 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 */
- goto done;
- }
- UWRITE2(sc, port, URWMASK(x) | UHCI_PORTSC_PE);
- }
-
- DPRINTFN(2, "uhci port %d reset timed out\n", index);
- return (USB_ERR_TIMEOUT);
-
-done:
- DPRINTFN(4, "uhci port %d reset, status2 = 0x%04x\n",
- index, UREAD2(sc, port));
-
- sc->sc_isreset = 1;
- return (USB_ERR_NORMAL_COMPLETION);
-}
-
-static void
-uhci_root_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uhci_root_ctrl_start(struct usb2_xfer *xfer)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
-
- DPRINTF("\n");
-
- sc->sc_root_ctrl.xfer = xfer;
-
- usb2_bus_roothub_exec(xfer->xroot->bus);
-}
-
-static void
-uhci_root_ctrl_task(struct usb2_bus *bus)
-{
- uhci_root_ctrl_poll(UHCI_BUS2SC(bus));
-}
-
-static void
-uhci_root_ctrl_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
- char *ptr;
- uint16_t x;
- uint16_t port;
- uint16_t value;
- uint16_t index;
- uint16_t status;
- uint16_t change;
- uint8_t use_polling;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_SETUP) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- uhci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* buffer reset */
- std->ptr = sc->sc_hub_desc.temp;
- std->len = 0;
-
- value = UGETW(std->req.wValue);
- index = UGETW(std->req.wIndex);
-
- use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
-
- DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
- "wValue=0x%04x wIndex=0x%04x\n",
- std->req.bmRequestType, std->req.bRequest,
- UGETW(std->req.wLength), value, index);
-
-#define C(x,y) ((x) | ((y) << 8))
- switch (C(std->req.bRequest, std->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):
- std->len = 1;
- sc->sc_hub_desc.temp[0] = sc->sc_conf;
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- switch (value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- std->len = sizeof(uhci_devd);
- sc->sc_hub_desc.devd = uhci_devd;
- break;
-
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- std->len = sizeof(uhci_confd);
- std->ptr = USB_ADD_BYTES(&uhci_confd, 0);
- break;
-
- case UDESC_STRING:
- switch (value & 0xff) {
- case 0: /* Language table */
- ptr = "\001";
- break;
-
- case 1: /* Vendor */
- ptr = sc->sc_vendor;
- break;
-
- case 2: /* Product */
- ptr = "UHCI root HUB";
- break;
-
- default:
- ptr = "";
- break;
- }
-
- std->len = usb2_make_str_desc
- (sc->sc_hub_desc.temp,
- sizeof(sc->sc_hub_desc.temp),
- ptr);
- break;
-
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- std->len = 1;
- sc->sc_hub_desc.temp[0] = 0;
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- std->len = 2;
- USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED);
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- std->len = 2;
- USETW(sc->sc_hub_desc.stat.wStatus, 0);
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- if (value >= USB_MAX_DEVICES) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- if ((value != 0) && (value != 1)) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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):
- std->err = USB_ERR_IOERROR;
- goto done;
- 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(4, "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 {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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;
- std->err = USB_ERR_NORMAL_COMPLETION;
- goto done;
- case UHF_C_PORT_SUSPEND:
- sc->sc_isresumed &= ~(1 << index);
- break;
- case UHF_PORT_CONNECTION:
- case UHF_PORT_OVER_CURRENT:
- case UHF_PORT_POWER:
- case UHF_PORT_LOW_SPEED:
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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 {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- std->len = 1;
- sc->sc_hub_desc.temp[0] =
- ((UREAD2(sc, port) & UHCI_PORTSC_LS) >>
- UHCI_PORTSC_LS_SHIFT);
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- if ((value & 0xff) != 0) {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- std->len = sizeof(uhci_hubd_piix);
- std->ptr = USB_ADD_BYTES(&uhci_hubd_piix, 0);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
- std->len = 16;
- bzero(sc->sc_hub_desc.temp, 16);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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_LSDA)
- status |= UPS_LOW_SPEED;
- if ((x & UHCI_PORTSC_PE) && (x & UHCI_PORTSC_RD)) {
- /* need to do a write back */
- UWRITE2(sc, port, URWMASK(x));
-
- /* wait 20ms for resume sequence to complete */
- if (use_polling) {
- /* polling */
- DELAY(20000);
- } else {
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 50);
- }
-
- /* clear suspend and resume detect */
- UWRITE2(sc, port, URWMASK(x) & ~(UHCI_PORTSC_RD |
- UHCI_PORTSC_SUSP));
-
- /* wait a little bit */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 500);
-
- sc->sc_isresumed |= (1 << index);
-
- } else if (x & UHCI_PORTSC_SUSP) {
- status |= UPS_SUSPEND;
- }
- status |= UPS_PORT_POWER;
- if (sc->sc_isresumed & (1 << index))
- change |= UPS_C_SUSPEND;
- if (sc->sc_isreset)
- change |= UPS_C_PORT_RESET;
- USETW(sc->sc_hub_desc.ps.wPortStatus, status);
- USETW(sc->sc_hub_desc.ps.wPortChange, change);
- std->len = sizeof(sc->sc_hub_desc.ps);
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- std->err = USB_ERR_IOERROR;
- goto done;
- 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 {
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- 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:
- std->err = uhci_portreset(sc, index, use_polling);
- goto done;
- case UHF_PORT_POWER:
- /* pretend we turned on power */
- std->err = USB_ERR_NORMAL_COMPLETION;
- goto done;
- 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:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
-done:
- return;
-}
-
-static void
-uhci_root_ctrl_poll(struct uhci_softc *sc)
-{
- usb2_sw_transfer(&sc->sc_root_ctrl,
- &uhci_root_ctrl_done);
-}
-
-struct usb2_pipe_methods uhci_root_ctrl_methods =
-{
- .open = uhci_root_ctrl_open,
- .close = uhci_root_ctrl_close,
- .enter = uhci_root_ctrl_enter,
- .start = uhci_root_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 0,
-};
-
-/*------------------------------------------------------------------------*
- * uhci root interrupt support
- *------------------------------------------------------------------------*/
-static void
-uhci_root_intr_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uhci_root_intr_close(struct usb2_xfer *xfer)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_intr.xfer == xfer) {
- sc->sc_root_intr.xfer = NULL;
- }
- uhci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-uhci_root_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uhci_root_intr_start(struct usb2_xfer *xfer)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_intr.xfer = xfer;
-
- usb2_transfer_timeout_ms(xfer,
- &uhci_root_intr_check, xfer->interval);
-}
-
-static void
-uhci_root_intr_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_PRE_DATA) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer is transferred */
- uhci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* setup buffer */
- std->ptr = sc->sc_hub_idata;
- std->len = sizeof(sc->sc_hub_idata);
-done:
- return;
-}
-
-/*
- * this routine is executed periodically and simulates interrupts
- * from the root controller interrupt pipe for port status change
- */
-static void
-uhci_root_intr_check(void *arg)
-{
- struct usb2_xfer *xfer = arg;
- uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
-
- DPRINTFN(21, "\n");
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- sc->sc_hub_idata[0] = 0;
-
- if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC |
- UHCI_PORTSC_OCIC | UHCI_PORTSC_RD)) {
- sc->sc_hub_idata[0] |= 1 << 1;
- }
- if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC |
- UHCI_PORTSC_OCIC | UHCI_PORTSC_RD)) {
- sc->sc_hub_idata[0] |= 1 << 2;
- }
- if (sc->sc_hub_idata[0] == 0) {
- /*
- * no change or controller not running, try again in a while
- */
- uhci_root_intr_start(xfer);
- } else {
- usb2_sw_transfer(&sc->sc_root_intr,
- &uhci_root_intr_done);
- }
-}
-
-struct usb2_pipe_methods uhci_root_intr_methods =
-{
- .open = uhci_root_intr_open,
- .close = uhci_root_intr_close,
- .enter = uhci_root_intr_enter,
- .start = uhci_root_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-static void
-uhci_xfer_setup(struct usb2_setup_params *parm)
-{
- struct usb2_page_search page_info;
- struct usb2_page_cache *pc;
- uhci_softc_t *sc;
- struct usb2_xfer *xfer;
- void *last_obj;
- uint32_t ntd;
- uint32_t nqh;
- uint32_t nfixup;
- uint32_t n;
- uint16_t align;
-
- sc = UHCI_BUS2SC(parm->udev->bus);
- xfer = parm->curr_xfer;
-
- parm->hc_max_packet_size = 0x500;
- parm->hc_max_packet_count = 1;
- parm->hc_max_frame_size = 0x500;
-
- /*
- * compute ntd and nqh
- */
- if (parm->methods == &uhci_device_ctrl_methods) {
- xfer->flags_int.bdma_enable = 1;
- xfer->flags_int.bdma_no_post_sync = 1;
-
- usb2_transfer_setup_sub(parm);
-
- /* see EHCI HC driver for proof of "ntd" formula */
-
- nqh = 1;
- ntd = ((2 * xfer->nframes) + 1 /* STATUS */
- + (xfer->max_data_length / xfer->max_frame_size));
-
- } else if (parm->methods == &uhci_device_bulk_methods) {
- xfer->flags_int.bdma_enable = 1;
- xfer->flags_int.bdma_no_post_sync = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nqh = 1;
- ntd = ((2 * xfer->nframes)
- + (xfer->max_data_length / xfer->max_frame_size));
-
- } else if (parm->methods == &uhci_device_intr_methods) {
- xfer->flags_int.bdma_enable = 1;
- xfer->flags_int.bdma_no_post_sync = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nqh = 1;
- ntd = ((2 * xfer->nframes)
- + (xfer->max_data_length / xfer->max_frame_size));
-
- } else if (parm->methods == &uhci_device_isoc_methods) {
- xfer->flags_int.bdma_enable = 1;
- xfer->flags_int.bdma_no_post_sync = 1;
-
- usb2_transfer_setup_sub(parm);
-
- nqh = 0;
- ntd = xfer->nframes;
-
- } else {
-
- usb2_transfer_setup_sub(parm);
-
- nqh = 0;
- ntd = 0;
- }
-
- if (parm->err) {
- return;
- }
- /*
- * NOTE: the UHCI controller requires that
- * every packet must be contiguous on
- * the same USB memory page !
- */
- nfixup = (parm->bufsize / USB_PAGE_SIZE) + 1;
-
- /*
- * Compute a suitable power of two alignment
- * for our "max_frame_size" fixup buffer(s):
- */
- align = xfer->max_frame_size;
- n = 0;
- while (align) {
- align >>= 1;
- n++;
- }
-
- /* check for power of two */
- if (!(xfer->max_frame_size &
- (xfer->max_frame_size - 1))) {
- n--;
- }
- /*
- * We don't allow alignments of
- * less than 8 bytes:
- *
- * NOTE: Allocating using an aligment
- * of 1 byte has special meaning!
- */
- if (n < 3) {
- n = 3;
- }
- align = (1 << n);
-
- if (usb2_transfer_setup_sub_malloc(
- parm, &pc, xfer->max_frame_size,
- align, nfixup)) {
- parm->err = USB_ERR_NOMEM;
- return;
- }
- xfer->buf_fixup = pc;
-
-alloc_dma_set:
-
- if (parm->err) {
- return;
- }
- last_obj = NULL;
-
- if (usb2_transfer_setup_sub_malloc(
- parm, &pc, sizeof(uhci_td_t),
- UHCI_TD_ALIGN, ntd)) {
- parm->err = USB_ERR_NOMEM;
- return;
- }
- if (parm->buf) {
- for (n = 0; n != ntd; n++) {
- uhci_td_t *td;
-
- usb2_get_page(pc + n, 0, &page_info);
-
- td = page_info.buffer;
-
- /* init TD */
- if ((parm->methods == &uhci_device_bulk_methods) ||
- (parm->methods == &uhci_device_ctrl_methods) ||
- (parm->methods == &uhci_device_intr_methods)) {
- /* set depth first bit */
- td->td_self = htole32(page_info.physaddr |
- UHCI_PTR_TD | UHCI_PTR_VF);
- } else {
- td->td_self = htole32(page_info.physaddr |
- UHCI_PTR_TD);
- }
-
- td->obj_next = last_obj;
- td->page_cache = pc + n;
-
- last_obj = td;
-
- usb2_pc_cpu_flush(pc + n);
- }
- }
- xfer->td_start[xfer->flags_int.curr_dma_set] = last_obj;
-
- last_obj = NULL;
-
- if (usb2_transfer_setup_sub_malloc(
- parm, &pc, sizeof(uhci_qh_t),
- UHCI_QH_ALIGN, nqh)) {
- parm->err = USB_ERR_NOMEM;
- return;
- }
- if (parm->buf) {
- for (n = 0; n != nqh; n++) {
- uhci_qh_t *qh;
-
- usb2_get_page(pc + n, 0, &page_info);
-
- qh = page_info.buffer;
-
- /* init QH */
- qh->qh_self = htole32(page_info.physaddr | UHCI_PTR_QH);
- qh->obj_next = last_obj;
- qh->page_cache = pc + n;
-
- last_obj = qh;
-
- usb2_pc_cpu_flush(pc + n);
- }
- }
- xfer->qh_start[xfer->flags_int.curr_dma_set] = last_obj;
-
- if (!xfer->flags_int.curr_dma_set) {
- xfer->flags_int.curr_dma_set = 1;
- goto alloc_dma_set;
- }
-}
-
-static void
-uhci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
- struct usb2_pipe *pipe)
-{
- uhci_softc_t *sc = UHCI_BUS2SC(udev->bus);
-
- DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
- pipe, udev->address,
- edesc->bEndpointAddress, udev->flags.usb2_mode,
- sc->sc_addr);
-
- if (udev->flags.usb2_mode != USB_MODE_HOST) {
- /* not supported */
- return;
- }
- if (udev->device_index == sc->sc_addr) {
- switch (edesc->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:
- /* do nothing */
- break;
- }
- } else {
- switch (edesc->bmAttributes & UE_XFERTYPE) {
- case UE_CONTROL:
- pipe->methods = &uhci_device_ctrl_methods;
- break;
- case UE_INTERRUPT:
- pipe->methods = &uhci_device_intr_methods;
- break;
- case UE_ISOCHRONOUS:
- if (udev->speed == USB_SPEED_FULL) {
- pipe->methods = &uhci_device_isoc_methods;
- }
- break;
- case UE_BULK:
- if (udev->speed != USB_SPEED_LOW) {
- pipe->methods = &uhci_device_bulk_methods;
- }
- break;
- default:
- /* do nothing */
- break;
- }
- }
-}
-
-static void
-uhci_xfer_unsetup(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uhci_get_dma_delay(struct usb2_bus *bus, uint32_t *pus)
-{
- /*
- * Wait until hardware has finished any possible use of the
- * transfer descriptor(s) and QH
- */
- *pus = (1125); /* microseconds */
-}
-
-static void
-uhci_device_resume(struct usb2_device *udev)
-{
- struct uhci_softc *sc = UHCI_BUS2SC(udev->bus);
- struct usb2_xfer *xfer;
- struct usb2_pipe_methods *methods;
- uhci_qh_t *qh;
-
- DPRINTF("\n");
-
- USB_BUS_LOCK(udev->bus);
-
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
-
- if (xfer->xroot->udev == udev) {
-
- methods = xfer->pipe->methods;
- qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- if (methods == &uhci_device_bulk_methods) {
- UHCI_APPEND_QH(qh, sc->sc_bulk_p_last);
- uhci_add_loop(sc);
- xfer->flags_int.bandwidth_reclaimed = 1;
- }
- if (methods == &uhci_device_ctrl_methods) {
- if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
- UHCI_APPEND_QH(qh, sc->sc_ls_ctl_p_last);
- } else {
- UHCI_APPEND_QH(qh, sc->sc_fs_ctl_p_last);
- }
- }
- if (methods == &uhci_device_intr_methods) {
- UHCI_APPEND_QH(qh, sc->sc_intr_p_last[xfer->qh_pos]);
- }
- }
- }
-
- USB_BUS_UNLOCK(udev->bus);
-
- return;
-}
-
-static void
-uhci_device_suspend(struct usb2_device *udev)
-{
- struct uhci_softc *sc = UHCI_BUS2SC(udev->bus);
- struct usb2_xfer *xfer;
- struct usb2_pipe_methods *methods;
- uhci_qh_t *qh;
-
- DPRINTF("\n");
-
- USB_BUS_LOCK(udev->bus);
-
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
-
- if (xfer->xroot->udev == udev) {
-
- methods = xfer->pipe->methods;
- qh = xfer->qh_start[xfer->flags_int.curr_dma_set];
-
- if (xfer->flags_int.bandwidth_reclaimed) {
- xfer->flags_int.bandwidth_reclaimed = 0;
- uhci_rem_loop(sc);
- }
- if (methods == &uhci_device_bulk_methods) {
- UHCI_REMOVE_QH(qh, sc->sc_bulk_p_last);
- }
- if (methods == &uhci_device_ctrl_methods) {
- if (xfer->xroot->udev->speed == USB_SPEED_LOW) {
- UHCI_REMOVE_QH(qh, sc->sc_ls_ctl_p_last);
- } else {
- UHCI_REMOVE_QH(qh, sc->sc_fs_ctl_p_last);
- }
- }
- if (methods == &uhci_device_intr_methods) {
- UHCI_REMOVE_QH(qh, sc->sc_intr_p_last[xfer->qh_pos]);
- }
- }
- }
-
- USB_BUS_UNLOCK(udev->bus);
-
- return;
-}
-
-static void
-uhci_set_hw_power(struct usb2_bus *bus)
-{
- struct uhci_softc *sc = UHCI_BUS2SC(bus);
- uint32_t flags;
-
- DPRINTF("\n");
-
- USB_BUS_LOCK(bus);
-
- flags = bus->hw_power_state;
-
- /*
- * WARNING: Some FULL speed USB devices require periodic SOF
- * messages! If any USB devices are connected through the
- * UHCI, power save will be disabled!
- */
- if (flags & (USB_HW_POWER_CONTROL |
- USB_HW_POWER_NON_ROOT_HUB |
- USB_HW_POWER_BULK |
- USB_HW_POWER_INTERRUPT |
- USB_HW_POWER_ISOC)) {
- DPRINTF("Some USB transfer is "
- "active on %u.\n",
- device_get_unit(sc->sc_bus.bdev));
- UHCICMD(sc, (UHCI_CMD_MAXP | UHCI_CMD_RS));
- } else {
- DPRINTF("Power save on %u.\n",
- device_get_unit(sc->sc_bus.bdev));
- UHCICMD(sc, UHCI_CMD_MAXP);
- }
-
- USB_BUS_UNLOCK(bus);
-
- return;
-}
-
-
-struct usb2_bus_methods uhci_bus_methods =
-{
- .pipe_init = uhci_pipe_init,
- .xfer_setup = uhci_xfer_setup,
- .xfer_unsetup = uhci_xfer_unsetup,
- .do_poll = uhci_do_poll,
- .get_dma_delay = uhci_get_dma_delay,
- .device_resume = uhci_device_resume,
- .device_suspend = uhci_device_suspend,
- .set_hw_power = uhci_set_hw_power,
- .roothub_exec = uhci_root_ctrl_task,
-};
diff --git a/sys/dev/usb2/controller/uhci2.h b/sys/dev/usb2/controller/uhci2.h
deleted file mode 100644
index 9365a4c..0000000
--- a/sys/dev/usb2/controller/uhci2.h
+++ /dev/null
@@ -1,321 +0,0 @@
-/* $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 _UHCI_H_
-#define _UHCI_H_
-
-#define UHCI_MAX_DEVICES USB_MAX_DEVICES
-
-/* PCI config registers */
-#define PCI_USBREV 0x60 /* USB protocol revision */
-#define PCI_USB_REV_MASK 0xff
-#define PCI_USB_REV_PRE_1_0 0x00
-#define PCI_USB_REV_1_0 0x10
-#define PCI_USB_REV_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 /* units */
-#define UHCI_FRAMELIST_ALIGN 4096 /* bytes */
-
-/* Structures alignment (bytes) */
-#define UHCI_TD_ALIGN 16
-#define UHCI_QH_ALIGN 16
-
-#if ((USB_PAGE_SIZE < UHCI_TD_ALIGN) || (UHCI_TD_ALIGN == 0) || \
- (USB_PAGE_SIZE < UHCI_QH_ALIGN) || (UHCI_QH_ALIGN == 0))
-#error "Invalid USB page size!"
-#endif
-
-typedef uint32_t uhci_physaddr_t;
-
-#define UHCI_PTR_T 0x00000001
-#define UHCI_PTR_TD 0x00000000
-#define UHCI_PTR_QH 0x00000002
-#define UHCI_PTR_VF 0x00000004
-
-#define UHCI_QH_REMOVE_DELAY 5 /* us - QH remove delay */
-
-/*
- * The Queue Heads (QH) and Transfer Descriptors (TD) are accessed by
- * both the CPU and the USB-controller which run concurrently. Great
- * care must be taken. When the data-structures are linked into the
- * USB controller's frame list, the USB-controller "owns" the
- * td_status and qh_elink fields, which will not be written by the
- * CPU.
- *
- */
-
-struct uhci_td {
-/*
- * Data used by the UHCI controller.
- * volatile is used in order to mantain struct members ordering.
- */
- volatile uint32_t td_next;
- volatile uint32_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
- volatile uint32_t td_token;
-#define UHCI_TD_PID 0x000000ff
-#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
- volatile uint32_t td_buffer;
-/*
- * Extra information needed:
- */
- struct uhci_td *next;
- struct uhci_td *prev;
- struct uhci_td *obj_next;
- struct usb2_page_cache *page_cache;
- struct usb2_page_cache *fix_pc;
- uint32_t td_self;
- uint16_t len;
-} __aligned(UHCI_TD_ALIGN);
-
-typedef struct uhci_td 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))
-
-struct uhci_qh {
-/*
- * Data used by the UHCI controller.
- */
- volatile uint32_t qh_h_next;
- volatile uint32_t qh_e_next;
-/*
- * Extra information needed:
- */
- struct uhci_qh *h_next;
- struct uhci_qh *h_prev;
- struct uhci_qh *obj_next;
- struct uhci_td *e_next;
- struct usb2_page_cache *page_cache;
- uint32_t qh_self;
- uint16_t intr_pos;
-} __aligned(UHCI_QH_ALIGN);
-
-typedef struct uhci_qh uhci_qh_t;
-
-/* Maximum number of isochronous TD's and QH's interrupt */
-#define UHCI_VFRAMELIST_COUNT 128
-#define UHCI_IFRAMELIST_COUNT (2 * UHCI_VFRAMELIST_COUNT)
-
-#if (((UHCI_VFRAMELIST_COUNT & (UHCI_VFRAMELIST_COUNT-1)) != 0) || \
- (UHCI_VFRAMELIST_COUNT > UHCI_FRAMELIST_COUNT))
-#error "UHCI_VFRAMELIST_COUNT is not power of two"
-#error "or UHCI_VFRAMELIST_COUNT > UHCI_FRAMELIST_COUNT"
-#endif
-
-#if (UHCI_VFRAMELIST_COUNT < USB_MAX_FS_ISOC_FRAMES_PER_XFER)
-#error "maximum number of full-speed isochronous frames is higher than supported!"
-#endif
-
-struct uhci_config_desc {
- struct usb2_config_descriptor confd;
- struct usb2_interface_descriptor ifcd;
- struct usb2_endpoint_descriptor endpd;
-} __packed;
-
-union uhci_hub_desc {
- struct usb2_status stat;
- struct usb2_port_status ps;
- struct usb2_device_descriptor devd;
- uint8_t temp[128];
-};
-
-struct uhci_hw_softc {
- struct usb2_page_cache pframes_pc;
- struct usb2_page_cache isoc_start_pc[UHCI_VFRAMELIST_COUNT];
- struct usb2_page_cache intr_start_pc[UHCI_IFRAMELIST_COUNT];
- struct usb2_page_cache ls_ctl_start_pc;
- struct usb2_page_cache fs_ctl_start_pc;
- struct usb2_page_cache bulk_start_pc;
- struct usb2_page_cache last_qh_pc;
- struct usb2_page_cache last_td_pc;
-
- struct usb2_page pframes_pg;
- struct usb2_page isoc_start_pg[UHCI_VFRAMELIST_COUNT];
- struct usb2_page intr_start_pg[UHCI_IFRAMELIST_COUNT];
- struct usb2_page ls_ctl_start_pg;
- struct usb2_page fs_ctl_start_pg;
- struct usb2_page bulk_start_pg;
- struct usb2_page last_qh_pg;
- struct usb2_page last_td_pg;
-};
-
-typedef struct uhci_softc {
- struct uhci_hw_softc sc_hw;
- struct usb2_bus sc_bus; /* base device */
- union uhci_hub_desc sc_hub_desc;
- struct usb2_sw_transfer sc_root_ctrl;
- struct usb2_sw_transfer sc_root_intr;
-
- struct usb2_device *sc_devices[UHCI_MAX_DEVICES];
- struct uhci_td *sc_isoc_p_last[UHCI_VFRAMELIST_COUNT]; /* pointer to last TD
- * for isochronous */
- struct uhci_qh *sc_intr_p_last[UHCI_IFRAMELIST_COUNT]; /* pointer to last QH
- * for interrupt */
- struct uhci_qh *sc_ls_ctl_p_last; /* pointer to last QH for low
- * speed control */
- struct uhci_qh *sc_fs_ctl_p_last; /* pointer to last QH for full
- * speed control */
- struct uhci_qh *sc_bulk_p_last; /* pointer to last QH for bulk */
- struct uhci_qh *sc_reclaim_qh_p;
- struct uhci_qh *sc_last_qh_p;
- struct uhci_td *sc_last_td_p;
- struct resource *sc_io_res;
- struct resource *sc_irq_res;
- void *sc_intr_hdl;
- device_t sc_dev;
- bus_size_t sc_io_size;
- bus_space_tag_t sc_io_tag;
- bus_space_handle_t sc_io_hdl;
-
- uint32_t sc_loops; /* number of QHs that wants looping */
-
- uint16_t sc_intr_stat[UHCI_IFRAMELIST_COUNT];
- uint16_t sc_saved_frnum;
-
- uint8_t sc_addr; /* device address */
- uint8_t sc_conf; /* device configuration */
- uint8_t sc_isreset; /* bits set if a root hub is reset */
- uint8_t sc_isresumed; /* bits set if a port was resumed */
- uint8_t sc_saved_sof;
- uint8_t sc_hub_idata[1];
-
- char sc_vendor[16]; /* vendor string for root hub */
-} uhci_softc_t;
-
-usb2_bus_mem_cb_t uhci_iterate_hw_softc;
-
-usb2_error_t uhci_init(uhci_softc_t *sc);
-void uhci_suspend(uhci_softc_t *sc);
-void uhci_resume(uhci_softc_t *sc);
-void uhci_reset(uhci_softc_t *sc);
-void uhci_interrupt(uhci_softc_t *sc);
-
-#endif /* _UHCI_H_ */
diff --git a/sys/dev/usb2/controller/uhci2_pci.c b/sys/dev/usb2/controller/uhci2_pci.c
deleted file mode 100644
index 725cd84..0000000
--- a/sys/dev/usb2/controller/uhci2_pci.c
+++ /dev/null
@@ -1,444 +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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_debug.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/usb2_pci.h>
-#include <dev/usb2/controller/uhci2.h>
-
-#define PCI_UHCI_VENDORID_INTEL 0x8086
-#define PCI_UHCI_VENDORID_VIA 0x1106
-
-/* PIIX4E has no separate stepping */
-
-#define PCI_UHCI_BASE_REG 0x20
-
-static device_probe_t uhci_pci_probe;
-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_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_resume(sc);
-
- bus_generic_resume(self);
- return (0);
-}
-
-static const char *
-uhci_pci_match(device_t self)
-{
- uint32_t device_id = pci_get_devid(self);
-
- switch (device_id) {
- case 0x26888086:
- return ("Intel 631XESB/632XESB/3100 USB controller USB-1");
-
- case 0x26898086:
- return ("Intel 631XESB/632XESB/3100 USB controller USB-2");
-
- case 0x268a8086:
- return ("Intel 631XESB/632XESB/3100 USB controller USB-3");
-
- case 0x268b8086:
- return ("Intel 631XESB/632XESB/3100 USB controller USB-4");
-
- case 0x70208086:
- return ("Intel 82371SB (PIIX3) USB controller");
-
- case 0x71128086:
- return ("Intel 82371AB/EB (PIIX4) USB controller");
-
- case 0x24128086:
- return ("Intel 82801AA (ICH) USB controller");
-
- case 0x24228086:
- return ("Intel 82801AB (ICH0) USB controller");
-
- case 0x24428086:
- return ("Intel 82801BA/BAM (ICH2) USB controller USB-A");
-
- case 0x24448086:
- return ("Intel 82801BA/BAM (ICH2) USB controller USB-B");
-
- case 0x24828086:
- return ("Intel 82801CA/CAM (ICH3) USB controller USB-A");
-
- case 0x24848086:
- return ("Intel 82801CA/CAM (ICH3) USB controller USB-B");
-
- case 0x24878086:
- return ("Intel 82801CA/CAM (ICH3) USB controller USB-C");
-
- case 0x24c28086:
- return ("Intel 82801DB (ICH4) USB controller USB-A");
-
- case 0x24c48086:
- return ("Intel 82801DB (ICH4) USB controller USB-B");
-
- case 0x24c78086:
- return ("Intel 82801DB (ICH4) USB controller USB-C");
-
- case 0x24d28086:
- return ("Intel 82801EB (ICH5) USB controller USB-A");
-
- case 0x24d48086:
- return ("Intel 82801EB (ICH5) USB controller USB-B");
-
- case 0x24d78086:
- return ("Intel 82801EB (ICH5) USB controller USB-C");
-
- case 0x24de8086:
- return ("Intel 82801EB (ICH5) USB controller USB-D");
-
- case 0x26588086:
- return ("Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-A");
-
- case 0x26598086:
- return ("Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-B");
-
- case 0x265a8086:
- return ("Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-C");
-
- case 0x265b8086:
- return ("Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-D");
-
- case 0x28308086:
- return ("Intel 82801H (ICH8) USB controller USB-A");
- case 0x28318086:
- return ("Intel 82801H (ICH8) USB controller USB-B");
- case 0x28328086:
- return ("Intel 82801H (ICH8) USB controller USB-C");
- case 0x28348086:
- return ("Intel 82801H (ICH8) USB controller USB-D");
- case 0x28358086:
- return ("Intel 82801H (ICH8) USB controller USB-E");
- case 0x29348086:
- return ("Intel 82801I (ICH9) USB controller");
- case 0x29358086:
- return ("Intel 82801I (ICH9) USB controller");
- case 0x29368086:
- return ("Intel 82801I (ICH9) USB controller");
- case 0x29378086:
- return ("Intel 82801I (ICH9) USB controller");
- case 0x29388086:
- return ("Intel 82801I (ICH9) USB controller");
- case 0x29398086:
- return ("Intel 82801I (ICH9) USB controller");
-
- case 0x719a8086:
- return ("Intel 82443MX USB controller");
-
- case 0x76028086:
- return ("Intel 82372FB/82468GX USB controller");
-
- case 0x30381106:
- return ("VIA 83C572 USB controller");
-
- default:
- break;
- }
-
- if ((pci_get_class(self) == PCIC_SERIALBUS) &&
- (pci_get_subclass(self) == PCIS_SERIALBUS_USB) &&
- (pci_get_progif(self) == PCI_INTERFACE_UHCI)) {
- return ("UHCI (generic) USB controller");
- }
- return (NULL);
-}
-
-static int
-uhci_pci_probe(device_t self)
-{
- const char *desc = uhci_pci_match(self);
-
- if (desc) {
- device_set_desc(self, desc);
- return (0);
- } else {
- return (ENXIO);
- }
-}
-
-static int
-uhci_pci_attach(device_t self)
-{
- uhci_softc_t *sc = device_get_softc(self);
- int rid;
- int err;
-
- /* initialise some bus fields */
- sc->sc_bus.parent = self;
- sc->sc_bus.devices = sc->sc_devices;
- sc->sc_bus.devices_max = UHCI_MAX_DEVICES;
-
- /* get all DMA memory */
- if (usb2_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self),
- &uhci_iterate_hw_softc)) {
- return ENOMEM;
- }
- sc->sc_dev = self;
-
- pci_enable_busmaster(self);
-
- rid = PCI_UHCI_BASE_REG;
- sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_IOPORT, &rid,
- RF_ACTIVE);
- if (!sc->sc_io_res) {
- device_printf(self, "Could not map ports\n");
- goto error;
- }
- sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
- sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
- sc->sc_io_size = rman_get_size(sc->sc_io_res);
-
- /* disable interrupts */
- bus_space_write_2(sc->sc_io_tag, sc->sc_io_hdl, UHCI_INTR, 0);
-
- rid = 0;
- sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->sc_irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- goto error;
- }
- sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- goto error;
- }
- 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_USB_REV_MASK) {
- case PCI_USB_REV_PRE_1_0:
- sc->sc_bus.usbrev = USB_REV_PRE_1_0;
- break;
- case PCI_USB_REV_1_0:
- sc->sc_bus.usbrev = USB_REV_1_0;
- break;
- default:
- /* Quirk for Parallels Desktop 4.0 */
- device_printf(self, "USB revision is unknown. Assuming v1.1.\n");
- sc->sc_bus.usbrev = USB_REV_1_1;
- break;
- }
-
-#if (__FreeBSD_version >= 700031)
- err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (void *)(void *)uhci_interrupt, sc, &sc->sc_intr_hdl);
-#else
- err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- (void *)(void *)uhci_interrupt, sc, &sc->sc_intr_hdl);
-#endif
-
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->sc_intr_hdl = NULL;
- goto error;
- }
- /*
- * 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?
- */
-#if 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);
-
- err = uhci_init(sc);
- if (!err) {
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
- if (err) {
- device_printf(self, "USB init failed\n");
- goto error;
- }
- return (0);
-
-error:
- uhci_pci_detach(self);
- return (ENXIO);
-}
-
-int
-uhci_pci_detach(device_t self)
-{
- uhci_softc_t *sc = device_get_softc(self);
- device_t bdev;
-
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(self, bdev);
- }
- /* during module unload there are lots of children leftover */
- device_delete_all_children(self);
-
- /*
- * disable interrupts that might have been switched on in
- * uhci_init.
- */
- if (sc->sc_io_res) {
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* stop the controller */
- uhci_reset(sc);
-
- USB_BUS_UNLOCK(&sc->sc_bus);
- }
- pci_disable_busmaster(self);
-
- if (sc->sc_irq_res && sc->sc_intr_hdl) {
- int err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
-
- if (err) {
- /* XXX or should we panic? */
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- }
- sc->sc_intr_hdl = NULL;
- }
- if (sc->sc_irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res);
- sc->sc_irq_res = NULL;
- }
- if (sc->sc_io_res) {
- bus_release_resource(self, SYS_RES_IOPORT, PCI_UHCI_BASE_REG,
- sc->sc_io_res);
- sc->sc_io_res = NULL;
- }
- usb2_bus_mem_free_all(&sc->sc_bus, &uhci_iterate_hw_softc);
-
- return (0);
-}
-
-static driver_t uhci_driver =
-{
- .name = "uhci",
- .methods = (device_method_t[]){
- /* 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}
- },
- .size = sizeof(struct uhci_softc),
-};
-
-static devclass_t uhci_devclass;
-
-DRIVER_MODULE(uhci, pci, uhci_driver, uhci_devclass, 0, 0);
-DRIVER_MODULE(uhci, cardbus, uhci_driver, uhci_devclass, 0, 0);
-MODULE_DEPEND(uhci, usb2_controller, 1, 1, 1);
-MODULE_DEPEND(uhci, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/controller/usb2_bus.h b/sys/dev/usb2/controller/usb2_bus.h
deleted file mode 100644
index 59287c4..0000000
--- a/sys/dev/usb2/controller/usb2_bus.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_BUS_H_
-#define _USB2_BUS_H_
-
-/*
- * The following structure defines the USB explore message sent to the
- * USB explore process.
- */
-
-struct usb2_bus_msg {
- struct usb2_proc_msg hdr;
- struct usb2_bus *bus;
-};
-
-/*
- * The following structure defines the USB statistics structure.
- */
-struct usb2_bus_stat {
- uint32_t uds_requests[4];
-};
-
-/*
- * The following structure defines an USB BUS. There is one USB BUS
- * for every Host or Device controller.
- */
-struct usb2_bus {
- struct usb2_bus_stat stats_err;
- struct usb2_bus_stat stats_ok;
- struct usb2_process explore_proc;
- struct usb2_process roothub_proc;
- struct root_hold_token *bus_roothold;
- /*
- * There are two callback processes. One for Giant locked
- * callbacks. One for non-Giant locked callbacks. This should
- * avoid congestion and reduce response time in most cases.
- */
- struct usb2_process giant_callback_proc;
- struct usb2_process non_giant_callback_proc;
- struct usb2_bus_msg explore_msg[2];
- struct usb2_bus_msg detach_msg[2];
- struct usb2_bus_msg attach_msg[2];
- struct usb2_bus_msg roothub_msg[2];
- /*
- * This mutex protects the USB hardware:
- */
- struct mtx bus_mtx;
- struct usb2_perm perm;
- struct usb2_xfer_queue intr_q;
- struct usb2_callout power_wdog; /* power management */
-
- device_t parent;
- device_t bdev; /* filled by HC driver */
-
- struct usb2_dma_parent_tag dma_parent_tag[1];
- struct usb2_dma_tag dma_tags[USB_BUS_DMA_TAG_MAX];
-
- struct usb2_bus_methods *methods; /* filled by HC driver */
- struct usb2_device **devices;
-
- uint32_t hw_power_state; /* see USB_HW_POWER_XXX */
- uint32_t uframe_usage[USB_HS_MICRO_FRAMES_MAX];
- uint32_t transfer_count[4];
- uint16_t isoc_time_last; /* in milliseconds */
-
- uint8_t alloc_failed; /* Set if memory allocation failed. */
- uint8_t driver_added_refcount; /* Current driver generation count */
- uint8_t usbrev; /* USB revision. See "USB_REV_XXX". */
-
- uint8_t devices_max; /* maximum number of USB devices */
- uint8_t do_probe; /* set if USB BUS should be re-probed */
-
- union {
- struct usb2_hw_ep_scratch hw_ep_scratch[1];
- struct usb2_temp_setup temp_setup[1];
- uint8_t data[128];
- } scratch[1];
-};
-
-#endif /* _USB2_BUS_H_ */
diff --git a/sys/dev/usb2/controller/usb2_controller.c b/sys/dev/usb2/controller/usb2_controller.c
deleted file mode 100644
index cd334ab..0000000
--- a/sys/dev/usb2/controller/usb2_controller.c
+++ /dev/null
@@ -1,623 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#define USB_DEBUG_VAR usb2_ctrl_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_hub.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-
-/* function prototypes */
-
-static device_probe_t usb2_probe;
-static device_attach_t usb2_attach;
-static device_detach_t usb2_detach;
-
-static void usb2_attach_sub(device_t, struct usb2_bus *);
-static void usb2_post_init(void *);
-static void usb2_bus_mem_flush_all_cb(struct usb2_bus *,
- struct usb2_page_cache *, struct usb2_page *, uint32_t,
- uint32_t);
-static void usb2_bus_mem_alloc_all_cb(struct usb2_bus *,
- struct usb2_page_cache *, struct usb2_page *, uint32_t,
- uint32_t);
-static void usb2_bus_mem_free_all_cb(struct usb2_bus *,
- struct usb2_page_cache *, struct usb2_page *, uint32_t,
- uint32_t);
-static void usb2_bus_roothub(struct usb2_proc_msg *pm);
-
-/* static variables */
-
-#if USB_DEBUG
-static int usb2_ctrl_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ctrl, CTLFLAG_RW, 0, "USB controller");
-SYSCTL_INT(_hw_usb2_ctrl, OID_AUTO, debug, CTLFLAG_RW, &usb2_ctrl_debug, 0,
- "Debug level");
-#endif
-
-static uint8_t usb2_post_init_called = 0;
-
-static devclass_t usb2_devclass;
-
-static device_method_t usb2_methods[] = {
- DEVMETHOD(device_probe, usb2_probe),
- DEVMETHOD(device_attach, usb2_attach),
- DEVMETHOD(device_detach, usb2_detach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- {0, 0}
-};
-
-static driver_t usb2_driver = {
- .name = "usbus",
- .methods = usb2_methods,
- .size = 0,
-};
-
-DRIVER_MODULE(usbus, ohci, usb2_driver, usb2_devclass, 0, 0);
-DRIVER_MODULE(usbus, uhci, usb2_driver, usb2_devclass, 0, 0);
-DRIVER_MODULE(usbus, ehci, usb2_driver, usb2_devclass, 0, 0);
-DRIVER_MODULE(usbus, at91_udp, usb2_driver, usb2_devclass, 0, 0);
-DRIVER_MODULE(usbus, uss820, usb2_driver, usb2_devclass, 0, 0);
-
-MODULE_DEPEND(usb2_controller, usb2_core, 1, 1, 1);
-MODULE_VERSION(usb2_controller, 1);
-
-/*------------------------------------------------------------------------*
- * usb2_probe
- *
- * This function is called from "{ehci,ohci,uhci}_pci_attach()".
- *------------------------------------------------------------------------*/
-static int
-usb2_probe(device_t dev)
-{
- DPRINTF("\n");
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_attach
- *------------------------------------------------------------------------*/
-static int
-usb2_attach(device_t dev)
-{
- struct usb2_bus *bus = device_get_ivars(dev);
-
- DPRINTF("\n");
-
- if (bus == NULL) {
- DPRINTFN(0, "USB device has no ivars\n");
- return (ENXIO);
- }
-
- /* delay vfs_mountroot until the bus is explored */
- bus->bus_roothold = root_mount_hold(device_get_nameunit(dev));
-
- if (usb2_post_init_called) {
- mtx_lock(&Giant);
- usb2_attach_sub(dev, bus);
- mtx_unlock(&Giant);
- usb2_needs_explore(bus, 1);
- }
- return (0); /* return success */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_detach
- *------------------------------------------------------------------------*/
-static int
-usb2_detach(device_t dev)
-{
- struct usb2_bus *bus = device_get_softc(dev);
-
- DPRINTF("\n");
-
- if (bus == NULL) {
- /* was never setup properly */
- return (0);
- }
- /* Stop power watchdog */
- usb2_callout_drain(&bus->power_wdog);
-
- /* Let the USB explore process detach all devices. */
- if (bus->bus_roothold != NULL) {
- root_mount_rel(bus->bus_roothold);
- bus->bus_roothold = NULL;
- }
-
- USB_BUS_LOCK(bus);
- if (usb2_proc_msignal(&bus->explore_proc,
- &bus->detach_msg[0], &bus->detach_msg[1])) {
- /* ignore */
- }
- /* Wait for detach to complete */
-
- usb2_proc_mwait(&bus->explore_proc,
- &bus->detach_msg[0], &bus->detach_msg[1]);
-
- USB_BUS_UNLOCK(bus);
-
- /* Get rid of USB callback processes */
-
- usb2_proc_free(&bus->giant_callback_proc);
- usb2_proc_free(&bus->non_giant_callback_proc);
-
- /* Get rid of USB roothub process */
-
- usb2_proc_free(&bus->roothub_proc);
-
- /* Get rid of USB explore process */
-
- usb2_proc_free(&bus->explore_proc);
-
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_explore
- *
- * This function is used to explore the device tree from the root.
- *------------------------------------------------------------------------*/
-static void
-usb2_bus_explore(struct usb2_proc_msg *pm)
-{
- struct usb2_bus *bus;
- struct usb2_device *udev;
-
- bus = ((struct usb2_bus_msg *)pm)->bus;
- udev = bus->devices[USB_ROOT_HUB_ADDR];
-
- if (udev && udev->hub) {
-
- if (bus->do_probe) {
- bus->do_probe = 0;
- bus->driver_added_refcount++;
- }
- if (bus->driver_added_refcount == 0) {
- /* avoid zero, hence that is memory default */
- bus->driver_added_refcount = 1;
- }
- USB_BUS_UNLOCK(bus);
-
- mtx_lock(&Giant);
-
- /*
- * First update the USB power state!
- */
- usb2_bus_powerd(bus);
-
- /*
- * Explore the Root USB HUB. This call can sleep,
- * exiting Giant, which is actually Giant.
- */
- (udev->hub->explore) (udev);
-
- mtx_unlock(&Giant);
-
- USB_BUS_LOCK(bus);
- }
- if (bus->bus_roothold != NULL) {
- root_mount_rel(bus->bus_roothold);
- bus->bus_roothold = NULL;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_detach
- *
- * This function is used to detach the device tree from the root.
- *------------------------------------------------------------------------*/
-static void
-usb2_bus_detach(struct usb2_proc_msg *pm)
-{
- struct usb2_bus *bus;
- struct usb2_device *udev;
- device_t dev;
-
- bus = ((struct usb2_bus_msg *)pm)->bus;
- udev = bus->devices[USB_ROOT_HUB_ADDR];
- dev = bus->bdev;
- /* clear the softc */
- device_set_softc(dev, NULL);
- USB_BUS_UNLOCK(bus);
-
- mtx_lock(&Giant);
-
- /* detach children first */
- bus_generic_detach(dev);
-
- /*
- * Free USB Root device, but not any sub-devices, hence they
- * are freed by the caller of this function:
- */
- usb2_detach_device(udev, USB_IFACE_INDEX_ANY, 0);
- usb2_free_device(udev);
-
- mtx_unlock(&Giant);
- USB_BUS_LOCK(bus);
- /* clear bdev variable last */
- bus->bdev = NULL;
-}
-
-static void
-usb2_power_wdog(void *arg)
-{
- struct usb2_bus *bus = arg;
-
- USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
-
- usb2_callout_reset(&bus->power_wdog,
- 4 * hz, usb2_power_wdog, arg);
-
- USB_BUS_UNLOCK(bus);
-
- usb2_bus_power_update(bus);
-
- return;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_attach
- *
- * This function attaches USB in context of the explore thread.
- *------------------------------------------------------------------------*/
-static void
-usb2_bus_attach(struct usb2_proc_msg *pm)
-{
- struct usb2_bus *bus;
- struct usb2_device *child;
- device_t dev;
- usb2_error_t err;
- uint8_t speed;
-
- bus = ((struct usb2_bus_msg *)pm)->bus;
- dev = bus->bdev;
-
- DPRINTF("\n");
-
- switch (bus->usbrev) {
- case USB_REV_1_0:
- speed = USB_SPEED_FULL;
- device_printf(bus->bdev, "12Mbps Full Speed USB v1.0\n");
- break;
-
- case USB_REV_1_1:
- speed = USB_SPEED_FULL;
- device_printf(bus->bdev, "12Mbps Full Speed USB v1.1\n");
- break;
-
- case USB_REV_2_0:
- speed = USB_SPEED_HIGH;
- device_printf(bus->bdev, "480Mbps High Speed USB v2.0\n");
- break;
-
- case USB_REV_2_5:
- speed = USB_SPEED_VARIABLE;
- device_printf(bus->bdev, "480Mbps Wireless USB v2.5\n");
- break;
-
- default:
- device_printf(bus->bdev, "Unsupported USB revision!\n");
- return;
- }
-
- USB_BUS_UNLOCK(bus);
- mtx_lock(&Giant); /* XXX not required by USB */
-
- /* Allocate the Root USB device */
-
- child = usb2_alloc_device(bus->bdev, bus, NULL, 0, 0, 1,
- speed, USB_MODE_HOST);
- if (child) {
- err = usb2_probe_and_attach(child,
- USB_IFACE_INDEX_ANY);
- if (!err) {
- if (!bus->devices[USB_ROOT_HUB_ADDR]->hub) {
- err = USB_ERR_NO_ROOT_HUB;
- }
- }
- } else {
- err = USB_ERR_NOMEM;
- }
-
- mtx_unlock(&Giant);
- USB_BUS_LOCK(bus);
-
- if (err) {
- device_printf(bus->bdev, "Root HUB problem, error=%s\n",
- usb2_errstr(err));
- }
-
- /* set softc - we are ready */
- device_set_softc(dev, bus);
-
- /* start watchdog - this function will unlock the BUS lock ! */
- usb2_power_wdog(bus);
-
- /* need to return locked */
- USB_BUS_LOCK(bus);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_attach_sub
- *
- * This function creates a thread which runs the USB attach code. It
- * is factored out, hence it can be called at two different places in
- * time. During bootup this function is called from
- * "usb2_post_init". During hot-plug it is called directly from the
- * "usb2_attach()" method.
- *------------------------------------------------------------------------*/
-static void
-usb2_attach_sub(device_t dev, struct usb2_bus *bus)
-{
- const char *pname = device_get_nameunit(dev);
-
- /* Initialise USB process messages */
- bus->explore_msg[0].hdr.pm_callback = &usb2_bus_explore;
- bus->explore_msg[0].bus = bus;
- bus->explore_msg[1].hdr.pm_callback = &usb2_bus_explore;
- bus->explore_msg[1].bus = bus;
-
- bus->detach_msg[0].hdr.pm_callback = &usb2_bus_detach;
- bus->detach_msg[0].bus = bus;
- bus->detach_msg[1].hdr.pm_callback = &usb2_bus_detach;
- bus->detach_msg[1].bus = bus;
-
- bus->attach_msg[0].hdr.pm_callback = &usb2_bus_attach;
- bus->attach_msg[0].bus = bus;
- bus->attach_msg[1].hdr.pm_callback = &usb2_bus_attach;
- bus->attach_msg[1].bus = bus;
-
- bus->roothub_msg[0].hdr.pm_callback = &usb2_bus_roothub;
- bus->roothub_msg[0].bus = bus;
- bus->roothub_msg[1].hdr.pm_callback = &usb2_bus_roothub;
- bus->roothub_msg[1].bus = bus;
-
- /* Create USB explore, roothub and callback processes */
-
- if (usb2_proc_create(&bus->giant_callback_proc,
- &bus->bus_mtx, pname, USB_PRI_MED)) {
- printf("WARNING: Creation of USB Giant "
- "callback process failed.\n");
- } else if (usb2_proc_create(&bus->non_giant_callback_proc,
- &bus->bus_mtx, pname, USB_PRI_HIGH)) {
- printf("WARNING: Creation of USB non-Giant "
- "callback process failed.\n");
- } else if (usb2_proc_create(&bus->roothub_proc,
- &bus->bus_mtx, pname, USB_PRI_HIGH)) {
- printf("WARNING: Creation of USB roothub "
- "process failed.\n");
- } else if (usb2_proc_create(&bus->explore_proc,
- &bus->bus_mtx, pname, USB_PRI_MED)) {
- printf("WARNING: Creation of USB explore "
- "process failed.\n");
- } else {
- /* Get final attach going */
- USB_BUS_LOCK(bus);
- if (usb2_proc_msignal(&bus->explore_proc,
- &bus->attach_msg[0], &bus->attach_msg[1])) {
- /* ignore */
- }
- USB_BUS_UNLOCK(bus);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_post_init
- *
- * This function is called to attach all USB busses that were found
- * during bootup.
- *------------------------------------------------------------------------*/
-static void
-usb2_post_init(void *arg)
-{
- struct usb2_bus *bus;
- devclass_t dc;
- device_t dev;
- int max;
- int n;
-
- mtx_lock(&Giant);
-
- usb2_devclass_ptr = devclass_find("usbus");
-
- dc = usb2_devclass_ptr;
- if (dc) {
- max = devclass_get_maxunit(dc) + 1;
- for (n = 0; n != max; n++) {
- dev = devclass_get_device(dc, n);
- if (dev && device_is_attached(dev)) {
- bus = device_get_ivars(dev);
- if (bus) {
- mtx_lock(&Giant);
- usb2_attach_sub(dev, bus);
- mtx_unlock(&Giant);
- }
- }
- }
- } else {
- DPRINTFN(0, "no devclass\n");
- }
- usb2_post_init_called = 1;
-
- /* explore all USB busses in parallell */
-
- usb2_needs_explore_all();
-
- mtx_unlock(&Giant);
-}
-
-SYSINIT(usb2_post_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb2_post_init, NULL);
-SYSUNINIT(usb2_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb2_bus_unload, NULL);
-
-/*------------------------------------------------------------------------*
- * usb2_bus_mem_flush_all_cb
- *------------------------------------------------------------------------*/
-static void
-usb2_bus_mem_flush_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc,
- struct usb2_page *pg, uint32_t size, uint32_t align)
-{
- usb2_pc_cpu_flush(pc);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_mem_flush_all - factored out code
- *------------------------------------------------------------------------*/
-void
-usb2_bus_mem_flush_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb)
-{
- if (cb) {
- cb(bus, &usb2_bus_mem_flush_all_cb);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_mem_alloc_all_cb
- *------------------------------------------------------------------------*/
-static void
-usb2_bus_mem_alloc_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc,
- struct usb2_page *pg, uint32_t size, uint32_t align)
-{
- /* need to initialize the page cache */
- pc->tag_parent = bus->dma_parent_tag;
-
- if (usb2_pc_alloc_mem(pc, pg, size, align)) {
- bus->alloc_failed = 1;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_mem_alloc_all - factored out code
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_bus_mem_alloc_all(struct usb2_bus *bus, bus_dma_tag_t dmat,
- usb2_bus_mem_cb_t *cb)
-{
- bus->alloc_failed = 0;
-
- mtx_init(&bus->bus_mtx, device_get_nameunit(bus->parent),
- NULL, MTX_DEF | MTX_RECURSE);
-
- usb2_callout_init_mtx(&bus->power_wdog,
- &bus->bus_mtx, CALLOUT_RETURNUNLOCKED);
-
- TAILQ_INIT(&bus->intr_q.head);
-
- usb2_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags,
- dmat, &bus->bus_mtx, NULL, NULL, 32, USB_BUS_DMA_TAG_MAX);
-
- if ((bus->devices_max > USB_MAX_DEVICES) ||
- (bus->devices_max < USB_MIN_DEVICES) ||
- (bus->devices == NULL)) {
- DPRINTFN(0, "Devices field has not been "
- "initialised properly!\n");
- bus->alloc_failed = 1; /* failure */
- }
- if (cb) {
- cb(bus, &usb2_bus_mem_alloc_all_cb);
- }
- if (bus->alloc_failed) {
- usb2_bus_mem_free_all(bus, cb);
- }
- return (bus->alloc_failed);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_mem_free_all_cb
- *------------------------------------------------------------------------*/
-static void
-usb2_bus_mem_free_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc,
- struct usb2_page *pg, uint32_t size, uint32_t align)
-{
- usb2_pc_free_mem(pc);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_mem_free_all - factored out code
- *------------------------------------------------------------------------*/
-void
-usb2_bus_mem_free_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb)
-{
- if (cb) {
- cb(bus, &usb2_bus_mem_free_all_cb);
- }
- usb2_dma_tag_unsetup(bus->dma_parent_tag);
-
- mtx_destroy(&bus->bus_mtx);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_roothub
- *
- * This function is used to execute roothub control requests on the
- * roothub and is called from the roothub process.
- *------------------------------------------------------------------------*/
-static void
-usb2_bus_roothub(struct usb2_proc_msg *pm)
-{
- struct usb2_bus *bus;
-
- bus = ((struct usb2_bus_msg *)pm)->bus;
-
- USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
-
- (bus->methods->roothub_exec) (bus);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_roothub_exec
- *
- * This function is used to schedule the "roothub_done" bus callback
- * method. The bus lock must be locked when calling this function.
- *------------------------------------------------------------------------*/
-void
-usb2_bus_roothub_exec(struct usb2_bus *bus)
-{
- USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
-
- if (usb2_proc_msignal(&bus->roothub_proc,
- &bus->roothub_msg[0], &bus->roothub_msg[1])) {
- /* ignore */
- }
-}
diff --git a/sys/dev/usb2/controller/usb2_controller.h b/sys/dev/usb2/controller/usb2_controller.h
deleted file mode 100644
index 80633d9..0000000
--- a/sys/dev/usb2/controller/usb2_controller.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_CONTROLLER_H_
-#define _USB2_CONTROLLER_H_
-
-/* defines */
-
-#define USB_BUS_DMA_TAG_MAX 8
-
-/* structure prototypes */
-
-struct usb2_bus;
-struct usb2_page;
-struct usb2_pipe;
-struct usb2_page_cache;
-struct usb2_setup_params;
-struct usb2_hw_ep_profile;
-struct usb2_fs_isoc_schedule;
-struct usb2_config_descriptor;
-struct usb2_endpoint_descriptor;
-
-/* typedefs */
-
-typedef void (usb2_bus_mem_sub_cb_t)(struct usb2_bus *bus, struct usb2_page_cache *pc, struct usb2_page *pg, uint32_t size, uint32_t align);
-typedef void (usb2_bus_mem_cb_t)(struct usb2_bus *bus, usb2_bus_mem_sub_cb_t *scb);
-
-/*
- * The following structure is used to define all the USB BUS
- * callbacks.
- */
-struct usb2_bus_methods {
-
- /* USB Device and Host mode - Mandatory */
-
- void (*pipe_init) (struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc, struct usb2_pipe *pipe);
- void (*do_poll) (struct usb2_bus *);
- void (*xfer_setup) (struct usb2_setup_params *parm);
- void (*xfer_unsetup) (struct usb2_xfer *xfer);
- void (*get_dma_delay) (struct usb2_bus *, uint32_t *pdelay);
- void (*device_suspend) (struct usb2_device *udev);
- void (*device_resume) (struct usb2_device *udev);
- void (*set_hw_power) (struct usb2_bus *bus);
- /*
- * The following flag is set if one or more control transfers are
- * active:
- */
-#define USB_HW_POWER_CONTROL 0x01
- /*
- * The following flag is set if one or more bulk transfers are
- * active:
- */
-#define USB_HW_POWER_BULK 0x02
- /*
- * The following flag is set if one or more interrupt transfers are
- * active:
- */
-#define USB_HW_POWER_INTERRUPT 0x04
- /*
- * The following flag is set if one or more isochronous transfers
- * are active:
- */
-#define USB_HW_POWER_ISOC 0x08
- /*
- * The following flag is set if one or more non-root-HUB devices
- * are present on the given USB bus:
- */
-#define USB_HW_POWER_NON_ROOT_HUB 0x10
-
- /* USB Device mode only - Mandatory */
-
- void (*get_hw_ep_profile) (struct usb2_device *udev, const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr);
- void (*set_stall) (struct usb2_device *udev, struct usb2_xfer *xfer, struct usb2_pipe *pipe);
- void (*clear_stall) (struct usb2_device *udev, struct usb2_pipe *pipe);
-
- /* USB Device and Host mode - Optional */
-
- void (*roothub_exec) (struct usb2_bus *);
-};
-
-/*
- * The following structure is used to define all the USB pipe
- * callbacks.
- */
-struct usb2_pipe_methods {
-
- /* Mandatory USB Device and Host mode callbacks: */
-
- void (*open) (struct usb2_xfer *xfer);
- void (*close) (struct usb2_xfer *xfer);
-
- void (*enter) (struct usb2_xfer *xfer);
- void (*start) (struct usb2_xfer *xfer);
-
- /* Optional */
-
- void *info;
-
- /* Flags */
-
- uint8_t enter_is_cancelable:1;
- uint8_t start_is_cancelable:1;
-};
-
-/*
- * The following structure keeps information about what a hardware USB
- * endpoint supports.
- */
-struct usb2_hw_ep_profile {
- uint16_t max_in_frame_size; /* IN-token direction */
- uint16_t max_out_frame_size; /* OUT-token direction */
- uint8_t is_simplex:1;
- uint8_t support_multi_buffer:1;
- uint8_t support_bulk:1;
- uint8_t support_control:1;
- uint8_t support_interrupt:1;
- uint8_t support_isochronous:1;
- uint8_t support_in:1; /* IN-token is supported */
- uint8_t support_out:1; /* OUT-token is supported */
-};
-
-/*
- * The following structure is used when trying to allocate hardware
- * endpoints for an USB configuration in USB device side mode.
- */
-struct usb2_hw_ep_scratch_sub {
- const struct usb2_hw_ep_profile *pf;
- uint16_t max_frame_size;
- uint8_t hw_endpoint_out;
- uint8_t hw_endpoint_in;
- uint8_t needs_ep_type;
- uint8_t needs_in:1;
- uint8_t needs_out:1;
-};
-
-/*
- * The following structure is used when trying to allocate hardware
- * endpoints for an USB configuration in USB device side mode.
- */
-struct usb2_hw_ep_scratch {
- struct usb2_hw_ep_scratch_sub ep[USB_EP_MAX];
- struct usb2_hw_ep_scratch_sub *ep_max;
- struct usb2_config_descriptor *cd;
- struct usb2_device *udev;
- struct usb2_bus_methods *methods;
- uint8_t bmOutAlloc[(USB_EP_MAX + 15) / 16];
- uint8_t bmInAlloc[(USB_EP_MAX + 15) / 16];
-};
-
-/*
- * The following structure is used when generating USB descriptors
- * from USB templates.
- */
-struct usb2_temp_setup {
- void *buf;
- uint32_t size;
- uint8_t usb2_speed;
- uint8_t self_powered;
- uint8_t bNumEndpoints;
- uint8_t bInterfaceNumber;
- uint8_t bAlternateSetting;
- uint8_t bConfigurationValue;
- usb2_error_t err;
-};
-
-/* prototypes */
-
-void usb2_bus_mem_flush_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb);
-uint8_t usb2_bus_mem_alloc_all(struct usb2_bus *bus, bus_dma_tag_t dmat, usb2_bus_mem_cb_t *cb);
-void usb2_bus_mem_free_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb);
-void usb2_bus_roothub_exec(struct usb2_bus *bus);
-uint16_t usb2_isoc_time_expand(struct usb2_bus *bus, uint16_t isoc_time_curr);
-uint16_t usb2_fs_isoc_schedule_isoc_time_expand(struct usb2_device *udev, struct usb2_fs_isoc_schedule **pp_start, struct usb2_fs_isoc_schedule **pp_end, uint16_t isoc_time);
-uint8_t usb2_fs_isoc_schedule_alloc(struct usb2_fs_isoc_schedule *fss, uint8_t *pstart, uint16_t len);
-
-#endif /* _USB2_CONTROLLER_H_ */
diff --git a/sys/dev/usb2/controller/usb2_pci.h b/sys/dev/usb2/controller/usb2_pci.h
deleted file mode 100644
index 9297c29..0000000
--- a/sys/dev/usb2/controller/usb2_pci.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_PCI_H_
-#define _USB2_PCI_H_
-
-/*
- * We don't want the following files included everywhere, that's why
- * they are in a separate file.
- */
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-
-#include <sys/rman.h>
-
-#endif /* _USB2_PCI_H_ */
diff --git a/sys/dev/usb2/controller/uss820dci.c b/sys/dev/usb2/controller/uss820dci.c
deleted file mode 100644
index 1e034bf..0000000
--- a/sys/dev/usb2/controller/uss820dci.c
+++ /dev/null
@@ -1,2489 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky <hselasky@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.
- */
-
-/*
- * This file contains the driver for the USS820 series USB Device
- * Controller
- *
- * NOTE: The datasheet does not document everything!
- */
-
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_revision.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR uss820dcidebug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_hub.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/uss820dci.h>
-
-#define USS820_DCI_BUS2SC(bus) \
- ((struct uss820dci_softc *)(((uint8_t *)(bus)) - \
- USB_P2U(&(((struct uss820dci_softc *)0)->sc_bus))))
-
-#define USS820_DCI_PC2SC(pc) \
- USS820_DCI_BUS2SC((pc)->tag_parent->info->bus)
-
-#if USB_DEBUG
-static int uss820dcidebug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uss820dci, CTLFLAG_RW, 0, "USB uss820dci");
-SYSCTL_INT(_hw_usb2_uss820dci, OID_AUTO, debug, CTLFLAG_RW,
- &uss820dcidebug, 0, "uss820dci debug level");
-#endif
-
-#define USS820_DCI_INTR_ENDPT 1
-
-/* prototypes */
-
-struct usb2_bus_methods uss820dci_bus_methods;
-struct usb2_pipe_methods uss820dci_device_bulk_methods;
-struct usb2_pipe_methods uss820dci_device_ctrl_methods;
-struct usb2_pipe_methods uss820dci_device_intr_methods;
-struct usb2_pipe_methods uss820dci_device_isoc_fs_methods;
-struct usb2_pipe_methods uss820dci_root_ctrl_methods;
-struct usb2_pipe_methods uss820dci_root_intr_methods;
-
-static uss820dci_cmd_t uss820dci_setup_rx;
-static uss820dci_cmd_t uss820dci_data_rx;
-static uss820dci_cmd_t uss820dci_data_tx;
-static uss820dci_cmd_t uss820dci_data_tx_sync;
-static void uss820dci_device_done(struct usb2_xfer *, usb2_error_t);
-static void uss820dci_do_poll(struct usb2_bus *);
-static void uss820dci_root_ctrl_poll(struct uss820dci_softc *);
-static void uss820dci_standard_done(struct usb2_xfer *);
-static void uss820dci_intr_set(struct usb2_xfer *, uint8_t);
-static void uss820dci_update_shared_1(struct uss820dci_softc *, uint8_t,
- uint8_t, uint8_t);
-
-static usb2_sw_transfer_func_t uss820dci_root_intr_done;
-static usb2_sw_transfer_func_t uss820dci_root_ctrl_done;
-
-/*
- * Here is a list of what the USS820D chip can support. The main
- * limitation is that the sum of the buffer sizes must be less than
- * 1120 bytes.
- */
-static const struct usb2_hw_ep_profile
- uss820dci_ep_profile[] = {
-
- [0] = {
- .max_in_frame_size = 32,
- .max_out_frame_size = 32,
- .is_simplex = 0,
- .support_control = 1,
- },
- [1] = {
- .max_in_frame_size = 64,
- .max_out_frame_size = 64,
- .is_simplex = 0,
- .support_multi_buffer = 1,
- .support_bulk = 1,
- .support_interrupt = 1,
- .support_in = 1,
- .support_out = 1,
- },
- [2] = {
- .max_in_frame_size = 8,
- .max_out_frame_size = 8,
- .is_simplex = 0,
- .support_multi_buffer = 1,
- .support_bulk = 1,
- .support_interrupt = 1,
- .support_in = 1,
- .support_out = 1,
- },
- [3] = {
- .max_in_frame_size = 256,
- .max_out_frame_size = 256,
- .is_simplex = 0,
- .support_multi_buffer = 1,
- .support_isochronous = 1,
- .support_in = 1,
- .support_out = 1,
- },
-};
-
-static void
-uss820dci_update_shared_1(struct uss820dci_softc *sc, uint8_t reg,
- uint8_t keep_mask, uint8_t set_mask)
-{
- uint8_t temp;
-
- USS820_WRITE_1(sc, USS820_PEND, 1);
- temp = USS820_READ_1(sc, reg);
- temp &= (keep_mask);
- temp |= (set_mask);
- USS820_WRITE_1(sc, reg, temp);
- USS820_WRITE_1(sc, USS820_PEND, 0);
-}
-
-static void
-uss820dci_get_hw_ep_profile(struct usb2_device *udev,
- const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr)
-{
- if (ep_addr == 0) {
- *ppf = uss820dci_ep_profile + 0;
- } else if (ep_addr < 5) {
- *ppf = uss820dci_ep_profile + 1;
- } else if (ep_addr < 7) {
- *ppf = uss820dci_ep_profile + 2;
- } else if (ep_addr == 7) {
- *ppf = uss820dci_ep_profile + 3;
- } else {
- *ppf = NULL;
- }
-}
-
-static void
-uss820dci_pull_up(struct uss820dci_softc *sc)
-{
- uint8_t temp;
-
- /* pullup D+, if possible */
-
- if (!sc->sc_flags.d_pulled_up &&
- sc->sc_flags.port_powered) {
- sc->sc_flags.d_pulled_up = 1;
-
- DPRINTF("\n");
-
- temp = USS820_READ_1(sc, USS820_MCSR);
- temp |= USS820_MCSR_DPEN;
- USS820_WRITE_1(sc, USS820_MCSR, temp);
- }
-}
-
-static void
-uss820dci_pull_down(struct uss820dci_softc *sc)
-{
- uint8_t temp;
-
- /* pulldown D+, if possible */
-
- if (sc->sc_flags.d_pulled_up) {
- sc->sc_flags.d_pulled_up = 0;
-
- DPRINTF("\n");
-
- temp = USS820_READ_1(sc, USS820_MCSR);
- temp &= ~USS820_MCSR_DPEN;
- USS820_WRITE_1(sc, USS820_MCSR, temp);
- }
-}
-
-static void
-uss820dci_wakeup_peer(struct uss820dci_softc *sc)
-{
- if (!(sc->sc_flags.status_suspend)) {
- return;
- }
- DPRINTFN(0, "not supported\n");
-}
-
-static void
-uss820dci_set_address(struct uss820dci_softc *sc, uint8_t addr)
-{
- DPRINTFN(5, "addr=%d\n", addr);
-
- USS820_WRITE_1(sc, USS820_FADDR, addr);
-}
-
-static uint8_t
-uss820dci_setup_rx(struct uss820dci_td *td)
-{
- struct uss820dci_softc *sc;
- struct usb2_device_request req;
- uint16_t count;
- uint8_t rx_stat;
- uint8_t temp;
-
- /* select the correct endpoint */
- bus_space_write_1(td->io_tag, td->io_hdl,
- td->ep_reg, td->ep_index);
-
- /* read out FIFO status */
- rx_stat = bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_stat_reg);
-
- /* get pointer to softc */
- sc = USS820_DCI_PC2SC(td->pc);
-
- DPRINTFN(5, "rx_stat=0x%02x rem=%u\n", rx_stat, td->remainder);
-
- if (!(rx_stat & USS820_RXSTAT_RXSETUP)) {
- /* abort any ongoing transfer */
- if (!td->did_stall) {
- DPRINTFN(5, "stalling\n");
-
- /* set stall */
-
- uss820dci_update_shared_1(sc, USS820_EPCON, 0xFF,
- (USS820_EPCON_TXSTL | USS820_EPCON_RXSTL));
-
- td->did_stall = 1;
- }
- goto not_complete;
- }
- /* clear stall and all I/O */
- uss820dci_update_shared_1(sc, USS820_EPCON,
- 0xFF ^ (USS820_EPCON_TXSTL |
- USS820_EPCON_RXSTL |
- USS820_EPCON_RXIE |
- USS820_EPCON_TXOE), 0);
-
- /* clear end overwrite flag */
- uss820dci_update_shared_1(sc, USS820_RXSTAT,
- 0xFF ^ USS820_RXSTAT_EDOVW, 0);
-
- /* get the packet byte count */
- count = bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_count_low_reg);
- count |= (bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_count_high_reg) << 8);
- count &= 0x3FF;
-
- /* verify data length */
- if (count != td->remainder) {
- DPRINTFN(0, "Invalid SETUP packet "
- "length, %d bytes\n", count);
- goto not_complete;
- }
- if (count != sizeof(req)) {
- DPRINTFN(0, "Unsupported SETUP packet "
- "length, %d bytes\n", count);
- goto not_complete;
- }
- /* receive data */
- bus_space_read_multi_1(td->io_tag, td->io_hdl,
- td->rx_fifo_reg, (void *)&req, sizeof(req));
-
- /* read out FIFO status */
- rx_stat = bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_stat_reg);
-
- if (rx_stat & (USS820_RXSTAT_EDOVW |
- USS820_RXSTAT_STOVW)) {
- DPRINTF("new SETUP packet received\n");
- return (1); /* not complete */
- }
- /* clear receive setup bit */
- uss820dci_update_shared_1(sc, USS820_RXSTAT,
- 0xFF ^ (USS820_RXSTAT_RXSETUP |
- USS820_RXSTAT_EDOVW |
- USS820_RXSTAT_STOVW), 0);
-
- /* set RXFFRC bit */
- temp = bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_cntl_reg);
- temp |= USS820_RXCON_RXFFRC;
- bus_space_write_1(td->io_tag, td->io_hdl,
- td->rx_cntl_reg, temp);
-
- /* copy data into real buffer */
- usb2_copy_in(td->pc, 0, &req, sizeof(req));
-
- td->offset = sizeof(req);
- td->remainder = 0;
-
- /* sneak peek the set address */
- if ((req.bmRequestType == UT_WRITE_DEVICE) &&
- (req.bRequest == UR_SET_ADDRESS)) {
- sc->sc_dv_addr = req.wValue[0] & 0x7F;
- } else {
- sc->sc_dv_addr = 0xFF;
- }
- return (0); /* complete */
-
-not_complete:
- /* clear end overwrite flag, if any */
- if (rx_stat & USS820_RXSTAT_RXSETUP) {
- uss820dci_update_shared_1(sc, USS820_RXSTAT,
- 0xFF ^ (USS820_RXSTAT_EDOVW |
- USS820_RXSTAT_STOVW |
- USS820_RXSTAT_RXSETUP), 0);
- }
- return (1); /* not complete */
-
-}
-
-static uint8_t
-uss820dci_data_rx(struct uss820dci_td *td)
-{
- struct usb2_page_search buf_res;
- uint16_t count;
- uint8_t rx_flag;
- uint8_t rx_stat;
- uint8_t rx_cntl;
- uint8_t to;
- uint8_t got_short;
-
- to = 2; /* don't loop forever! */
- got_short = 0;
-
- /* select the correct endpoint */
- bus_space_write_1(td->io_tag, td->io_hdl, td->ep_reg, td->ep_index);
-
- /* check if any of the FIFO banks have data */
-repeat:
- /* read out FIFO flag */
- rx_flag = bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_flag_reg);
- /* read out FIFO status */
- rx_stat = bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_stat_reg);
-
- DPRINTFN(5, "rx_stat=0x%02x rx_flag=0x%02x rem=%u\n",
- rx_stat, rx_flag, td->remainder);
-
- if (rx_stat & (USS820_RXSTAT_RXSETUP |
- USS820_RXSTAT_RXSOVW |
- USS820_RXSTAT_EDOVW)) {
- if (td->remainder == 0) {
- /*
- * We are actually complete and have
- * received the next SETUP
- */
- DPRINTFN(5, "faking complete\n");
- return (0); /* complete */
- }
- /*
- * USB Host Aborted the transfer.
- */
- td->error = 1;
- return (0); /* complete */
- }
- /* check for errors */
- if (rx_flag & (USS820_RXFLG_RXOVF |
- USS820_RXFLG_RXURF)) {
- DPRINTFN(5, "overflow or underflow\n");
- /* should not happen */
- td->error = 1;
- return (0); /* complete */
- }
- /* check status */
- if (!(rx_flag & (USS820_RXFLG_RXFIF0 |
- USS820_RXFLG_RXFIF1))) {
-
- /* read out EPCON register */
- /* enable RX input */
- if (!td->did_stall) {
- uss820dci_update_shared_1(USS820_DCI_PC2SC(td->pc),
- USS820_EPCON, 0xFF, USS820_EPCON_RXIE);
- td->did_stall = 1;
- }
- return (1); /* not complete */
- }
- /* get the packet byte count */
- count = bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_count_low_reg);
-
- count |= (bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_count_high_reg) << 8);
- count &= 0x3FF;
-
- DPRINTFN(5, "count=0x%04x\n", count);
-
- /* verify the packet byte count */
- if (count != td->max_packet_size) {
- if (count < td->max_packet_size) {
- /* we have a short packet */
- td->short_pkt = 1;
- got_short = 1;
- } else {
- /* invalid USB packet */
- td->error = 1;
- return (0); /* we are complete */
- }
- }
- /* verify the packet byte count */
- if (count > td->remainder) {
- /* invalid USB packet */
- td->error = 1;
- return (0); /* we are complete */
- }
- while (count > 0) {
- usb2_get_page(td->pc, td->offset, &buf_res);
-
- /* get correct length */
- if (buf_res.length > count) {
- buf_res.length = count;
- }
- /* receive data */
- bus_space_read_multi_1(td->io_tag, td->io_hdl,
- td->rx_fifo_reg, buf_res.buffer, buf_res.length);
-
- /* update counters */
- count -= buf_res.length;
- td->offset += buf_res.length;
- td->remainder -= buf_res.length;
- }
-
- /* set RXFFRC bit */
- rx_cntl = bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_cntl_reg);
- rx_cntl |= USS820_RXCON_RXFFRC;
- bus_space_write_1(td->io_tag, td->io_hdl,
- td->rx_cntl_reg, rx_cntl);
-
- /* check if we are complete */
- if ((td->remainder == 0) || got_short) {
- if (td->short_pkt) {
- /* we are complete */
- return (0);
- }
- /* else need to receive a zero length packet */
- }
- if (--to) {
- goto repeat;
- }
- return (1); /* not complete */
-}
-
-static uint8_t
-uss820dci_data_tx(struct uss820dci_td *td)
-{
- struct usb2_page_search buf_res;
- uint16_t count;
- uint16_t count_copy;
- uint8_t rx_stat;
- uint8_t tx_flag;
- uint8_t to;
-
- /* select the correct endpoint */
- bus_space_write_1(td->io_tag, td->io_hdl,
- td->ep_reg, td->ep_index);
-
- to = 2; /* don't loop forever! */
-
-repeat:
- /* read out TX FIFO flags */
- tx_flag = bus_space_read_1(td->io_tag, td->io_hdl,
- td->tx_flag_reg);
-
- /* read out RX FIFO status last */
- rx_stat = bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_stat_reg);
-
- DPRINTFN(5, "rx_stat=0x%02x tx_flag=0x%02x rem=%u\n",
- rx_stat, tx_flag, td->remainder);
-
- if (rx_stat & (USS820_RXSTAT_RXSETUP |
- USS820_RXSTAT_RXSOVW |
- USS820_RXSTAT_EDOVW)) {
- /*
- * The current transfer was aborted
- * by the USB Host
- */
- td->error = 1;
- return (0); /* complete */
- }
- if (tx_flag & (USS820_TXFLG_TXOVF |
- USS820_TXFLG_TXURF)) {
- td->error = 1;
- return (0); /* complete */
- }
- if (tx_flag & USS820_TXFLG_TXFIF0) {
- if (tx_flag & USS820_TXFLG_TXFIF1) {
- return (1); /* not complete */
- }
- }
- if ((!td->support_multi_buffer) &&
- (tx_flag & (USS820_TXFLG_TXFIF0 |
- USS820_TXFLG_TXFIF1))) {
- return (1); /* not complete */
- }
- count = td->max_packet_size;
- if (td->remainder < count) {
- /* we have a short packet */
- td->short_pkt = 1;
- count = td->remainder;
- }
- count_copy = count;
- while (count > 0) {
-
- usb2_get_page(td->pc, td->offset, &buf_res);
-
- /* get correct length */
- if (buf_res.length > count) {
- buf_res.length = count;
- }
- /* transmit data */
- bus_space_write_multi_1(td->io_tag, td->io_hdl,
- td->tx_fifo_reg, buf_res.buffer, buf_res.length);
-
- /* update counters */
- count -= buf_res.length;
- td->offset += buf_res.length;
- td->remainder -= buf_res.length;
- }
-
- /* post-write high packet byte count first */
- bus_space_write_1(td->io_tag, td->io_hdl,
- td->tx_count_high_reg, count_copy >> 8);
-
- /* post-write low packet byte count last */
- bus_space_write_1(td->io_tag, td->io_hdl,
- td->tx_count_low_reg, count_copy);
-
- /*
- * Enable TX output, which must happen after that we have written
- * data into the FIFO. This is undocumented.
- */
- if (!td->did_stall) {
- uss820dci_update_shared_1(USS820_DCI_PC2SC(td->pc),
- USS820_EPCON, 0xFF, USS820_EPCON_TXOE);
- td->did_stall = 1;
- }
- /* check remainder */
- if (td->remainder == 0) {
- if (td->short_pkt) {
- return (0); /* complete */
- }
- /* else we need to transmit a short packet */
- }
- if (--to) {
- goto repeat;
- }
- return (1); /* not complete */
-}
-
-static uint8_t
-uss820dci_data_tx_sync(struct uss820dci_td *td)
-{
- struct uss820dci_softc *sc;
- uint8_t rx_stat;
- uint8_t tx_flag;
-
- /* select the correct endpoint */
- bus_space_write_1(td->io_tag, td->io_hdl,
- td->ep_reg, td->ep_index);
-
- /* read out TX FIFO flag */
- tx_flag = bus_space_read_1(td->io_tag, td->io_hdl,
- td->tx_flag_reg);
-
- /* read out RX FIFO status last */
- rx_stat = bus_space_read_1(td->io_tag, td->io_hdl,
- td->rx_stat_reg);
-
- DPRINTFN(5, "rx_stat=0x%02x rem=%u\n", rx_stat, td->remainder);
-
- if (rx_stat & (USS820_RXSTAT_RXSETUP |
- USS820_RXSTAT_RXSOVW |
- USS820_RXSTAT_EDOVW)) {
- DPRINTFN(5, "faking complete\n");
- /* Race condition */
- return (0); /* complete */
- }
- DPRINTFN(5, "tx_flag=0x%02x rem=%u\n",
- tx_flag, td->remainder);
-
- if (tx_flag & (USS820_TXFLG_TXOVF |
- USS820_TXFLG_TXURF)) {
- td->error = 1;
- return (0); /* complete */
- }
- if (tx_flag & (USS820_TXFLG_TXFIF0 |
- USS820_TXFLG_TXFIF1)) {
- return (1); /* not complete */
- }
- sc = USS820_DCI_PC2SC(td->pc);
- if (sc->sc_dv_addr != 0xFF) {
- /* write function address */
- uss820dci_set_address(sc, sc->sc_dv_addr);
- }
- return (0); /* complete */
-}
-
-static uint8_t
-uss820dci_xfer_do_fifo(struct usb2_xfer *xfer)
-{
- struct uss820dci_td *td;
-
- DPRINTFN(9, "\n");
-
- td = xfer->td_transfer_cache;
- while (1) {
- if ((td->func) (td)) {
- /* operation in progress */
- break;
- }
- if (((void *)td) == xfer->td_transfer_last) {
- goto done;
- }
- if (td->error) {
- goto done;
- } else if (td->remainder > 0) {
- /*
- * We had a short transfer. If there is no alternate
- * next, stop processing !
- */
- if (!td->alt_next) {
- goto done;
- }
- }
- /*
- * Fetch the next transfer descriptor.
- */
- td = td->obj_next;
- xfer->td_transfer_cache = td;
- }
- return (1); /* not complete */
-
-done:
- /* compute all actual lengths */
-
- uss820dci_standard_done(xfer);
-
- return (0); /* complete */
-}
-
-static void
-uss820dci_interrupt_poll(struct uss820dci_softc *sc)
-{
- struct usb2_xfer *xfer;
-
-repeat:
- TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
- if (!uss820dci_xfer_do_fifo(xfer)) {
- /* queue has been modified */
- goto repeat;
- }
- }
-}
-
-static void
-uss820dci_wait_suspend(struct uss820dci_softc *sc, uint8_t on)
-{
- uint8_t scr;
- uint8_t scratch;
-
- scr = USS820_READ_1(sc, USS820_SCR);
- scratch = USS820_READ_1(sc, USS820_SCRATCH);
-
- if (on) {
- scr |= USS820_SCR_IE_SUSP;
- scratch &= ~USS820_SCRATCH_IE_RESUME;
- } else {
- scr &= ~USS820_SCR_IE_SUSP;
- scratch |= USS820_SCRATCH_IE_RESUME;
- }
-
- USS820_WRITE_1(sc, USS820_SCR, scr);
- USS820_WRITE_1(sc, USS820_SCRATCH, scratch);
-}
-
-void
-uss820dci_interrupt(struct uss820dci_softc *sc)
-{
- uint8_t ssr;
- uint8_t event;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- ssr = USS820_READ_1(sc, USS820_SSR);
-
- ssr &= (USS820_SSR_SUSPEND |
- USS820_SSR_RESUME |
- USS820_SSR_RESET);
-
- /* acknowledge all interrupts */
-
- uss820dci_update_shared_1(sc, USS820_SSR, 0, 0);
-
- /* check for any bus state change interrupts */
-
- if (ssr) {
-
- event = 0;
-
- if (ssr & USS820_SSR_RESET) {
- sc->sc_flags.status_bus_reset = 1;
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 0;
- sc->sc_flags.change_connect = 1;
-
- /* disable resume interrupt */
- uss820dci_wait_suspend(sc, 1);
-
- event = 1;
- }
- /*
- * If "RESUME" and "SUSPEND" is set at the same time
- * we interpret that like "RESUME". Resume is set when
- * there is at least 3 milliseconds of inactivity on
- * the USB BUS.
- */
- if (ssr & USS820_SSR_RESUME) {
- if (sc->sc_flags.status_suspend) {
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 1;
- /* disable resume interrupt */
- uss820dci_wait_suspend(sc, 1);
- event = 1;
- }
- } else if (ssr & USS820_SSR_SUSPEND) {
- if (!sc->sc_flags.status_suspend) {
- sc->sc_flags.status_suspend = 1;
- sc->sc_flags.change_suspend = 1;
- /* enable resume interrupt */
- uss820dci_wait_suspend(sc, 0);
- event = 1;
- }
- }
- if (event) {
-
- DPRINTF("real bus interrupt 0x%02x\n", ssr);
-
- /* complete root HUB interrupt endpoint */
-
- usb2_sw_transfer(&sc->sc_root_intr,
- &uss820dci_root_intr_done);
- }
- }
- /* acknowledge all SBI interrupts */
- uss820dci_update_shared_1(sc, USS820_SBI, 0, 0);
-
- /* acknowledge all SBI1 interrupts */
- uss820dci_update_shared_1(sc, USS820_SBI1, 0, 0);
-
- /* poll all active transfers */
- uss820dci_interrupt_poll(sc);
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-static void
-uss820dci_setup_standard_chain_sub(struct uss820_std_temp *temp)
-{
- struct uss820dci_td *td;
-
- /* get current Transfer Descriptor */
- td = temp->td_next;
- temp->td = td;
-
- /* prepare for next TD */
- temp->td_next = td->obj_next;
-
- /* fill out the Transfer Descriptor */
- td->func = temp->func;
- td->pc = temp->pc;
- td->offset = temp->offset;
- td->remainder = temp->len;
- td->error = 0;
- td->did_stall = 0;
- td->short_pkt = temp->short_pkt;
- td->alt_next = temp->setup_alt_next;
-}
-
-static void
-uss820dci_setup_standard_chain(struct usb2_xfer *xfer)
-{
- struct uss820_std_temp temp;
- struct uss820dci_softc *sc;
- struct uss820dci_td *td;
- uint32_t x;
- uint8_t ep_no;
-
- DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
- xfer->address, UE_GET_ADDR(xfer->endpoint),
- xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
-
- temp.max_frame_size = xfer->max_frame_size;
-
- td = xfer->td_start[0];
- xfer->td_transfer_first = td;
- xfer->td_transfer_cache = td;
-
- /* setup temp */
-
- temp.td = NULL;
- temp.td_next = xfer->td_start[0];
- temp.setup_alt_next = xfer->flags_int.short_frames_ok;
- temp.offset = 0;
-
- sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
- ep_no = (xfer->endpoint & UE_ADDR);
-
- /* check if we should prepend a setup message */
-
- if (xfer->flags_int.control_xfr) {
- if (xfer->flags_int.control_hdr) {
-
- temp.func = &uss820dci_setup_rx;
- temp.len = xfer->frlengths[0];
- temp.pc = xfer->frbuffers + 0;
- temp.short_pkt = temp.len ? 1 : 0;
-
- uss820dci_setup_standard_chain_sub(&temp);
- }
- x = 1;
- } else {
- x = 0;
- }
-
- if (x != xfer->nframes) {
- if (xfer->endpoint & UE_DIR_IN) {
- temp.func = &uss820dci_data_tx;
- } else {
- temp.func = &uss820dci_data_rx;
- }
-
- /* setup "pc" pointer */
- temp.pc = xfer->frbuffers + x;
- }
- while (x != xfer->nframes) {
-
- /* DATA0 / DATA1 message */
-
- temp.len = xfer->frlengths[x];
-
- x++;
-
- if (x == xfer->nframes) {
- temp.setup_alt_next = 0;
- }
- if (temp.len == 0) {
-
- /* make sure that we send an USB packet */
-
- temp.short_pkt = 0;
-
- } else {
-
- /* regular data transfer */
-
- temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
- }
-
- uss820dci_setup_standard_chain_sub(&temp);
-
- if (xfer->flags_int.isochronous_xfr) {
- temp.offset += temp.len;
- } else {
- /* get next Page Cache pointer */
- temp.pc = xfer->frbuffers + x;
- }
- }
-
- /* always setup a valid "pc" pointer for status and sync */
- temp.pc = xfer->frbuffers + 0;
-
- /* check if we should append a status stage */
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
- uint8_t need_sync;
-
- /*
- * Send a DATA1 message and invert the current
- * endpoint direction.
- */
- if (xfer->endpoint & UE_DIR_IN) {
- temp.func = &uss820dci_data_rx;
- need_sync = 0;
- } else {
- temp.func = &uss820dci_data_tx;
- need_sync = 1;
- }
- temp.len = 0;
- temp.short_pkt = 0;
-
- uss820dci_setup_standard_chain_sub(&temp);
- if (need_sync) {
- /* we need a SYNC point after TX */
- temp.func = &uss820dci_data_tx_sync;
- temp.len = 0;
- temp.short_pkt = 0;
-
- uss820dci_setup_standard_chain_sub(&temp);
- }
- }
- /* must have at least one frame! */
- td = temp.td;
- xfer->td_transfer_last = td;
-}
-
-static void
-uss820dci_timeout(void *arg)
-{
- struct usb2_xfer *xfer = arg;
-
- DPRINTF("xfer=%p\n", xfer);
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- /* transfer is transferred */
- uss820dci_device_done(xfer, USB_ERR_TIMEOUT);
-}
-
-static void
-uss820dci_intr_set(struct usb2_xfer *xfer, uint8_t set)
-{
- struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
- uint8_t ep_no = (xfer->endpoint & UE_ADDR);
- uint8_t ep_reg;
- uint8_t temp;
-
- DPRINTFN(15, "endpoint 0x%02x\n", xfer->endpoint);
-
- if (ep_no > 3) {
- ep_reg = USS820_SBIE1;
- } else {
- ep_reg = USS820_SBIE;
- }
-
- ep_no &= 3;
- ep_no = 1 << (2 * ep_no);
-
- if (xfer->flags_int.control_xfr) {
- if (xfer->flags_int.control_hdr) {
- ep_no <<= 1; /* RX interrupt only */
- } else {
- ep_no |= (ep_no << 1); /* RX and TX interrupt */
- }
- } else {
- if (!(xfer->endpoint & UE_DIR_IN)) {
- ep_no <<= 1;
- }
- }
- temp = USS820_READ_1(sc, ep_reg);
- if (set) {
- temp |= ep_no;
- } else {
- temp &= ~ep_no;
- }
- USS820_WRITE_1(sc, ep_reg, temp);
-}
-
-static void
-uss820dci_start_standard_chain(struct usb2_xfer *xfer)
-{
- DPRINTFN(9, "\n");
-
- /* poll one time */
- if (uss820dci_xfer_do_fifo(xfer)) {
-
- /*
- * Only enable the endpoint interrupt when we are
- * actually waiting for data, hence we are dealing
- * with level triggered interrupts !
- */
- uss820dci_intr_set(xfer, 1);
-
- /* put transfer on interrupt queue */
- usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
-
- /* start timeout, if any */
- if (xfer->timeout != 0) {
- usb2_transfer_timeout_ms(xfer,
- &uss820dci_timeout, xfer->timeout);
- }
- }
-}
-
-static void
-uss820dci_root_intr_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
-
- DPRINTFN(9, "\n");
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_PRE_DATA) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- uss820dci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* setup buffer */
- std->ptr = sc->sc_hub_idata;
- std->len = sizeof(sc->sc_hub_idata);
-
- /* set port bit */
- sc->sc_hub_idata[0] = 0x02; /* we only have one port */
-
-done:
- return;
-}
-
-static usb2_error_t
-uss820dci_standard_done_sub(struct usb2_xfer *xfer)
-{
- struct uss820dci_td *td;
- uint32_t len;
- uint8_t error;
-
- DPRINTFN(9, "\n");
-
- td = xfer->td_transfer_cache;
-
- do {
- len = td->remainder;
-
- if (xfer->aframes != xfer->nframes) {
- /*
- * Verify the length and subtract
- * the remainder from "frlengths[]":
- */
- if (len > xfer->frlengths[xfer->aframes]) {
- td->error = 1;
- } else {
- xfer->frlengths[xfer->aframes] -= len;
- }
- }
- /* Check for transfer error */
- if (td->error) {
- /* the transfer is finished */
- error = 1;
- td = NULL;
- break;
- }
- /* Check for short transfer */
- if (len > 0) {
- if (xfer->flags_int.short_frames_ok) {
- /* follow alt next */
- if (td->alt_next) {
- td = td->obj_next;
- } else {
- td = NULL;
- }
- } else {
- /* the transfer is finished */
- td = NULL;
- }
- error = 0;
- break;
- }
- td = td->obj_next;
-
- /* this USB frame is complete */
- error = 0;
- break;
-
- } while (0);
-
- /* update transfer cache */
-
- xfer->td_transfer_cache = td;
-
- return (error ?
- USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
-}
-
-static void
-uss820dci_standard_done(struct usb2_xfer *xfer)
-{
- usb2_error_t err = 0;
-
- DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
- xfer, xfer->pipe);
-
- /* reset scanner */
-
- xfer->td_transfer_cache = xfer->td_transfer_first;
-
- if (xfer->flags_int.control_xfr) {
-
- if (xfer->flags_int.control_hdr) {
-
- err = uss820dci_standard_done_sub(xfer);
- }
- xfer->aframes = 1;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
- while (xfer->aframes != xfer->nframes) {
-
- err = uss820dci_standard_done_sub(xfer);
- xfer->aframes++;
-
- if (xfer->td_transfer_cache == NULL) {
- goto done;
- }
- }
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- err = uss820dci_standard_done_sub(xfer);
- }
-done:
- uss820dci_device_done(xfer, err);
-}
-
-/*------------------------------------------------------------------------*
- * uss820dci_device_done
- *
- * NOTE: this function can be called more than one time on the
- * same USB transfer!
- *------------------------------------------------------------------------*/
-static void
-uss820dci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
-{
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
- xfer, xfer->pipe, error);
-
- if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
- uss820dci_intr_set(xfer, 0);
- }
- /* dequeue transfer and start next transfer */
- usb2_transfer_done(xfer, error);
-}
-
-static void
-uss820dci_set_stall(struct usb2_device *udev, struct usb2_xfer *xfer,
- struct usb2_pipe *pipe)
-{
- struct uss820dci_softc *sc;
- uint8_t ep_no;
- uint8_t ep_type;
- uint8_t ep_dir;
- uint8_t temp;
-
- USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
-
- DPRINTFN(5, "pipe=%p\n", pipe);
-
- if (xfer) {
- /* cancel any ongoing transfers */
- uss820dci_device_done(xfer, USB_ERR_STALLED);
- }
- /* set FORCESTALL */
- sc = USS820_DCI_BUS2SC(udev->bus);
- ep_no = (pipe->edesc->bEndpointAddress & UE_ADDR);
- ep_dir = (pipe->edesc->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT));
- ep_type = (pipe->edesc->bmAttributes & UE_XFERTYPE);
-
- if (ep_type == UE_CONTROL) {
- /* should not happen */
- return;
- }
- USS820_WRITE_1(sc, USS820_EPINDEX, ep_no);
-
- if (ep_dir == UE_DIR_IN) {
- temp = USS820_EPCON_TXSTL;
- } else {
- temp = USS820_EPCON_RXSTL;
- }
- uss820dci_update_shared_1(sc, USS820_EPCON, 0xFF, temp);
-}
-
-static void
-uss820dci_clear_stall_sub(struct uss820dci_softc *sc,
- uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
-{
- uint8_t temp;
-
- if (ep_type == UE_CONTROL) {
- /* clearing stall is not needed */
- return;
- }
- /* select endpoint index */
- USS820_WRITE_1(sc, USS820_EPINDEX, ep_no);
-
- /* clear stall and disable I/O transfers */
- if (ep_dir == UE_DIR_IN) {
- temp = 0xFF ^ (USS820_EPCON_TXOE |
- USS820_EPCON_TXSTL);
- } else {
- temp = 0xFF ^ (USS820_EPCON_RXIE |
- USS820_EPCON_RXSTL);
- }
- uss820dci_update_shared_1(sc, USS820_EPCON, temp, 0);
-
- if (ep_dir == UE_DIR_IN) {
- /* reset data toggle */
- USS820_WRITE_1(sc, USS820_TXSTAT,
- USS820_TXSTAT_TXSOVW);
-
- /* reset FIFO */
- temp = USS820_READ_1(sc, USS820_TXCON);
- temp |= USS820_TXCON_TXCLR;
- USS820_WRITE_1(sc, USS820_TXCON, temp);
- temp &= ~USS820_TXCON_TXCLR;
- USS820_WRITE_1(sc, USS820_TXCON, temp);
- } else {
-
- /* reset data toggle */
- uss820dci_update_shared_1(sc, USS820_RXSTAT,
- 0, USS820_RXSTAT_RXSOVW);
-
- /* reset FIFO */
- temp = USS820_READ_1(sc, USS820_RXCON);
- temp |= USS820_RXCON_RXCLR;
- temp &= ~USS820_RXCON_RXFFRC;
- USS820_WRITE_1(sc, USS820_RXCON, temp);
- temp &= ~USS820_RXCON_RXCLR;
- USS820_WRITE_1(sc, USS820_RXCON, temp);
- }
-}
-
-static void
-uss820dci_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe)
-{
- struct uss820dci_softc *sc;
- struct usb2_endpoint_descriptor *ed;
-
- USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
-
- DPRINTFN(5, "pipe=%p\n", pipe);
-
- /* check mode */
- if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
- /* not supported */
- return;
- }
- /* get softc */
- sc = USS820_DCI_BUS2SC(udev->bus);
-
- /* get endpoint descriptor */
- ed = pipe->edesc;
-
- /* reset endpoint */
- uss820dci_clear_stall_sub(sc,
- (ed->bEndpointAddress & UE_ADDR),
- (ed->bmAttributes & UE_XFERTYPE),
- (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
-}
-
-usb2_error_t
-uss820dci_init(struct uss820dci_softc *sc)
-{
- const struct usb2_hw_ep_profile *pf;
- uint8_t n;
- uint8_t temp;
-
- DPRINTF("start\n");
-
- /* set up the bus structure */
- sc->sc_bus.usbrev = USB_REV_1_1;
- sc->sc_bus.methods = &uss820dci_bus_methods;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* we always have VBUS */
- sc->sc_flags.status_vbus = 1;
-
- /* reset the chip */
- USS820_WRITE_1(sc, USS820_SCR, USS820_SCR_SRESET);
- DELAY(100);
- USS820_WRITE_1(sc, USS820_SCR, 0);
-
- /* wait for reset to complete */
- for (n = 0;; n++) {
-
- temp = USS820_READ_1(sc, USS820_MCSR);
-
- if (temp & USS820_MCSR_INIT) {
- break;
- }
- if (n == 100) {
- USB_BUS_UNLOCK(&sc->sc_bus);
- return (USB_ERR_INVAL);
- }
- /* wait a little for things to stabilise */
- DELAY(100);
- }
-
- /* do a pulldown */
- uss820dci_pull_down(sc);
-
- /* wait 10ms for pulldown to stabilise */
- usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
-
- /* check hardware revision */
- temp = USS820_READ_1(sc, USS820_REV);
-
- if (temp < 0x13) {
- USB_BUS_UNLOCK(&sc->sc_bus);
- return (USB_ERR_INVAL);
- }
- /* enable interrupts */
- USS820_WRITE_1(sc, USS820_SCR,
- USS820_SCR_T_IRQ |
- USS820_SCR_IE_RESET |
- /* USS820_SCR_RWUPE | */
- USS820_SCR_IE_SUSP |
- USS820_SCR_IRQPOL);
-
- /* enable interrupts */
- USS820_WRITE_1(sc, USS820_SCRATCH,
- USS820_SCRATCH_IE_RESUME);
-
- /* enable features */
- USS820_WRITE_1(sc, USS820_MCSR,
- USS820_MCSR_BDFEAT |
- USS820_MCSR_FEAT);
-
- sc->sc_flags.mcsr_feat = 1;
-
- /* disable interrupts */
- USS820_WRITE_1(sc, USS820_SBIE, 0);
-
- /* disable interrupts */
- USS820_WRITE_1(sc, USS820_SBIE1, 0);
-
- /* disable all endpoints */
- for (n = 0; n != USS820_EP_MAX; n++) {
-
- /* select endpoint */
- USS820_WRITE_1(sc, USS820_EPINDEX, n);
-
- /* disable endpoint */
- uss820dci_update_shared_1(sc, USS820_EPCON, 0, 0);
- }
-
- /*
- * Initialise default values for some registers that cannot be
- * changed during operation!
- */
- for (n = 0; n != USS820_EP_MAX; n++) {
-
- uss820dci_get_hw_ep_profile(NULL, &pf, n);
-
- /* the maximum frame sizes should be the same */
- if (pf->max_in_frame_size != pf->max_out_frame_size) {
- DPRINTF("Max frame size mismatch %u != %u\n",
- pf->max_in_frame_size, pf->max_out_frame_size);
- }
- if (pf->support_isochronous) {
- if (pf->max_in_frame_size <= 64) {
- temp = (USS820_TXCON_FFSZ_16_64 |
- USS820_TXCON_TXISO |
- USS820_TXCON_ATM);
- } else if (pf->max_in_frame_size <= 256) {
- temp = (USS820_TXCON_FFSZ_64_256 |
- USS820_TXCON_TXISO |
- USS820_TXCON_ATM);
- } else if (pf->max_in_frame_size <= 512) {
- temp = (USS820_TXCON_FFSZ_8_512 |
- USS820_TXCON_TXISO |
- USS820_TXCON_ATM);
- } else { /* 1024 bytes */
- temp = (USS820_TXCON_FFSZ_32_1024 |
- USS820_TXCON_TXISO |
- USS820_TXCON_ATM);
- }
- } else {
- if ((pf->max_in_frame_size <= 8) &&
- (sc->sc_flags.mcsr_feat)) {
- temp = (USS820_TXCON_FFSZ_8_512 |
- USS820_TXCON_ATM);
- } else if (pf->max_in_frame_size <= 16) {
- temp = (USS820_TXCON_FFSZ_16_64 |
- USS820_TXCON_ATM);
- } else if ((pf->max_in_frame_size <= 32) &&
- (sc->sc_flags.mcsr_feat)) {
- temp = (USS820_TXCON_FFSZ_32_1024 |
- USS820_TXCON_ATM);
- } else { /* 64 bytes */
- temp = (USS820_TXCON_FFSZ_64_256 |
- USS820_TXCON_ATM);
- }
- }
-
- /* need to configure the chip early */
-
- USS820_WRITE_1(sc, USS820_EPINDEX, n);
- USS820_WRITE_1(sc, USS820_TXCON, temp);
- USS820_WRITE_1(sc, USS820_RXCON, temp);
-
- if (pf->support_control) {
- temp = USS820_EPCON_CTLEP |
- USS820_EPCON_RXSPM |
- USS820_EPCON_RXIE |
- USS820_EPCON_RXEPEN |
- USS820_EPCON_TXOE |
- USS820_EPCON_TXEPEN;
- } else {
- temp = USS820_EPCON_RXEPEN | USS820_EPCON_TXEPEN;
- }
-
- uss820dci_update_shared_1(sc, USS820_EPCON, 0xFF, temp);
- }
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-
- /* catch any lost interrupts */
-
- uss820dci_do_poll(&sc->sc_bus);
-
- return (0); /* success */
-}
-
-void
-uss820dci_uninit(struct uss820dci_softc *sc)
-{
- uint8_t temp;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* disable all interrupts */
- temp = USS820_READ_1(sc, USS820_SCR);
- temp &= ~USS820_SCR_T_IRQ;
- USS820_WRITE_1(sc, USS820_SCR, temp);
-
- sc->sc_flags.port_powered = 0;
- sc->sc_flags.status_vbus = 0;
- sc->sc_flags.status_bus_reset = 0;
- sc->sc_flags.status_suspend = 0;
- sc->sc_flags.change_suspend = 0;
- sc->sc_flags.change_connect = 1;
-
- uss820dci_pull_down(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-void
-uss820dci_suspend(struct uss820dci_softc *sc)
-{
- return;
-}
-
-void
-uss820dci_resume(struct uss820dci_softc *sc)
-{
- return;
-}
-
-static void
-uss820dci_do_poll(struct usb2_bus *bus)
-{
- struct uss820dci_softc *sc = USS820_DCI_BUS2SC(bus);
-
- USB_BUS_LOCK(&sc->sc_bus);
- uss820dci_interrupt_poll(sc);
- uss820dci_root_ctrl_poll(sc);
- USB_BUS_UNLOCK(&sc->sc_bus);
-}
-
-/*------------------------------------------------------------------------*
- * at91dci bulk support
- *------------------------------------------------------------------------*/
-static void
-uss820dci_device_bulk_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_device_bulk_close(struct usb2_xfer *xfer)
-{
- uss820dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-uss820dci_device_bulk_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_device_bulk_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- uss820dci_setup_standard_chain(xfer);
- uss820dci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods uss820dci_device_bulk_methods =
-{
- .open = uss820dci_device_bulk_open,
- .close = uss820dci_device_bulk_close,
- .enter = uss820dci_device_bulk_enter,
- .start = uss820dci_device_bulk_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci control support
- *------------------------------------------------------------------------*/
-static void
-uss820dci_device_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_device_ctrl_close(struct usb2_xfer *xfer)
-{
- uss820dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-uss820dci_device_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_device_ctrl_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- uss820dci_setup_standard_chain(xfer);
- uss820dci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods uss820dci_device_ctrl_methods =
-{
- .open = uss820dci_device_ctrl_open,
- .close = uss820dci_device_ctrl_close,
- .enter = uss820dci_device_ctrl_enter,
- .start = uss820dci_device_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci interrupt support
- *------------------------------------------------------------------------*/
-static void
-uss820dci_device_intr_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_device_intr_close(struct usb2_xfer *xfer)
-{
- uss820dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-uss820dci_device_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_device_intr_start(struct usb2_xfer *xfer)
-{
- /* setup TDs */
- uss820dci_setup_standard_chain(xfer);
- uss820dci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods uss820dci_device_intr_methods =
-{
- .open = uss820dci_device_intr_open,
- .close = uss820dci_device_intr_close,
- .enter = uss820dci_device_intr_enter,
- .start = uss820dci_device_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci full speed isochronous support
- *------------------------------------------------------------------------*/
-static void
-uss820dci_device_isoc_fs_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_device_isoc_fs_close(struct usb2_xfer *xfer)
-{
- uss820dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-uss820dci_device_isoc_fs_enter(struct usb2_xfer *xfer)
-{
- struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
- uint32_t temp;
- uint32_t nframes;
-
- DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
- xfer, xfer->pipe->isoc_next, xfer->nframes);
-
- /* get the current frame index - we don't need the high bits */
-
- nframes = USS820_READ_1(sc, USS820_SOFL);
-
- /*
- * check if the frame index is within the window where the
- * frames will be inserted
- */
- temp = (nframes - xfer->pipe->isoc_next) & USS820_SOFL_MASK;
-
- if ((xfer->pipe->is_synced == 0) ||
- (temp < xfer->nframes)) {
- /*
- * If there is data underflow or the pipe queue is
- * empty we schedule the transfer a few frames ahead
- * of the current frame position. Else two isochronous
- * transfers might overlap.
- */
- xfer->pipe->isoc_next = (nframes + 3) & USS820_SOFL_MASK;
- xfer->pipe->is_synced = 1;
- DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next);
- }
- /*
- * compute how many milliseconds the insertion is ahead of the
- * current frame position:
- */
- temp = (xfer->pipe->isoc_next - nframes) & USS820_SOFL_MASK;
-
- /*
- * pre-compute when the isochronous transfer will be finished:
- */
- xfer->isoc_time_complete =
- usb2_isoc_time_expand(&sc->sc_bus, nframes) + temp +
- xfer->nframes;
-
- /* compute frame number for next insertion */
- xfer->pipe->isoc_next += xfer->nframes;
-
- /* setup TDs */
- uss820dci_setup_standard_chain(xfer);
-}
-
-static void
-uss820dci_device_isoc_fs_start(struct usb2_xfer *xfer)
-{
- /* start TD chain */
- uss820dci_start_standard_chain(xfer);
-}
-
-struct usb2_pipe_methods uss820dci_device_isoc_fs_methods =
-{
- .open = uss820dci_device_isoc_fs_open,
- .close = uss820dci_device_isoc_fs_close,
- .enter = uss820dci_device_isoc_fs_enter,
- .start = uss820dci_device_isoc_fs_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci root control support
- *------------------------------------------------------------------------*
- * simulate a hardware HUB by handling
- * all the necessary requests
- *------------------------------------------------------------------------*/
-
-static void
-uss820dci_root_ctrl_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_root_ctrl_close(struct usb2_xfer *xfer)
-{
- struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_ctrl.xfer == xfer) {
- sc->sc_root_ctrl.xfer = NULL;
- }
- uss820dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-/*
- * USB descriptors for the virtual Root HUB:
- */
-
-static const struct usb2_device_descriptor uss820dci_devd = {
- .bLength = sizeof(struct usb2_device_descriptor),
- .bDescriptorType = UDESC_DEVICE,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_HSHUBSTT,
- .bMaxPacketSize = 64,
- .bcdDevice = {0x00, 0x01},
- .iManufacturer = 1,
- .iProduct = 2,
- .bNumConfigurations = 1,
-};
-
-static const struct usb2_device_qualifier uss820dci_odevd = {
- .bLength = sizeof(struct usb2_device_qualifier),
- .bDescriptorType = UDESC_DEVICE_QUALIFIER,
- .bcdUSB = {0x00, 0x02},
- .bDeviceClass = UDCLASS_HUB,
- .bDeviceSubClass = UDSUBCLASS_HUB,
- .bDeviceProtocol = UDPROTO_FSHUB,
- .bMaxPacketSize0 = 0,
- .bNumConfigurations = 0,
-};
-
-static const struct uss820dci_config_desc uss820dci_confd = {
- .confd = {
- .bLength = sizeof(struct usb2_config_descriptor),
- .bDescriptorType = UDESC_CONFIG,
- .wTotalLength[0] = sizeof(uss820dci_confd),
- .bNumInterface = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = UC_SELF_POWERED,
- .bMaxPower = 0,
- },
- .ifcd = {
- .bLength = sizeof(struct usb2_interface_descriptor),
- .bDescriptorType = UDESC_INTERFACE,
- .bNumEndpoints = 1,
- .bInterfaceClass = UICLASS_HUB,
- .bInterfaceSubClass = UISUBCLASS_HUB,
- .bInterfaceProtocol = UIPROTO_HSHUBSTT,
- },
-
- .endpd = {
- .bLength = sizeof(struct usb2_endpoint_descriptor),
- .bDescriptorType = UDESC_ENDPOINT,
- .bEndpointAddress = (UE_DIR_IN | USS820_DCI_INTR_ENDPT),
- .bmAttributes = UE_INTERRUPT,
- .wMaxPacketSize[0] = 8,
- .bInterval = 255,
- },
-};
-
-static const struct usb2_hub_descriptor_min uss820dci_hubd = {
- .bDescLength = sizeof(uss820dci_hubd),
- .bDescriptorType = UDESC_HUB,
- .bNbrPorts = 1,
- .wHubCharacteristics[0] =
- (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
- .wHubCharacteristics[1] =
- (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 8,
- .bPwrOn2PwrGood = 50,
- .bHubContrCurrent = 0,
- .DeviceRemovable = {0}, /* port is removable */
-};
-
-#define STRING_LANG \
- 0x09, 0x04, /* American English */
-
-#define STRING_VENDOR \
- 'A', 0, 'G', 0, 'E', 0, 'R', 0, 'E', 0
-
-#define STRING_PRODUCT \
- 'D', 0, 'C', 0, 'I', 0, ' ', 0, 'R', 0, \
- 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
- 'U', 0, 'B', 0,
-
-USB_MAKE_STRING_DESC(STRING_LANG, uss820dci_langtab);
-USB_MAKE_STRING_DESC(STRING_VENDOR, uss820dci_vendor);
-USB_MAKE_STRING_DESC(STRING_PRODUCT, uss820dci_product);
-
-static void
-uss820dci_root_ctrl_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_root_ctrl_start(struct usb2_xfer *xfer)
-{
- struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_ctrl.xfer = xfer;
-
- usb2_bus_roothub_exec(xfer->xroot->bus);
-}
-
-static void
-uss820dci_root_ctrl_task(struct usb2_bus *bus)
-{
- uss820dci_root_ctrl_poll(USS820_DCI_BUS2SC(bus));
-}
-
-static void
-uss820dci_root_ctrl_done(struct usb2_xfer *xfer,
- struct usb2_sw_transfer *std)
-{
- struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
- uint16_t value;
- uint16_t index;
- uint8_t use_polling;
-
- USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
-
- if (std->state != USB_SW_TR_SETUP) {
- if (std->state == USB_SW_TR_PRE_CALLBACK) {
- /* transfer transferred */
- uss820dci_device_done(xfer, std->err);
- }
- goto done;
- }
- /* buffer reset */
- std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
- std->len = 0;
-
- value = UGETW(std->req.wValue);
- index = UGETW(std->req.wIndex);
-
- use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
-
- /* demultiplex the control request */
-
- switch (std->req.bmRequestType) {
- case UT_READ_DEVICE:
- switch (std->req.bRequest) {
- case UR_GET_DESCRIPTOR:
- goto tr_handle_get_descriptor;
- case UR_GET_CONFIG:
- goto tr_handle_get_config;
- case UR_GET_STATUS:
- goto tr_handle_get_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_DEVICE:
- switch (std->req.bRequest) {
- case UR_SET_ADDRESS:
- goto tr_handle_set_address;
- case UR_SET_CONFIG:
- goto tr_handle_set_config;
- case UR_CLEAR_FEATURE:
- goto tr_valid; /* nop */
- case UR_SET_DESCRIPTOR:
- goto tr_valid; /* nop */
- case UR_SET_FEATURE:
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_ENDPOINT:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- switch (UGETW(std->req.wValue)) {
- case UF_ENDPOINT_HALT:
- goto tr_handle_clear_halt;
- case UF_DEVICE_REMOTE_WAKEUP:
- goto tr_handle_clear_wakeup;
- default:
- goto tr_stalled;
- }
- break;
- case UR_SET_FEATURE:
- switch (UGETW(std->req.wValue)) {
- case UF_ENDPOINT_HALT:
- goto tr_handle_set_halt;
- case UF_DEVICE_REMOTE_WAKEUP:
- goto tr_handle_set_wakeup;
- default:
- goto tr_stalled;
- }
- break;
- case UR_SYNCH_FRAME:
- goto tr_valid; /* nop */
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_ENDPOINT:
- switch (std->req.bRequest) {
- case UR_GET_STATUS:
- goto tr_handle_get_ep_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_INTERFACE:
- switch (std->req.bRequest) {
- case UR_SET_INTERFACE:
- goto tr_handle_set_interface;
- case UR_CLEAR_FEATURE:
- goto tr_valid; /* nop */
- case UR_SET_FEATURE:
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_INTERFACE:
- switch (std->req.bRequest) {
- case UR_GET_INTERFACE:
- goto tr_handle_get_interface;
- case UR_GET_STATUS:
- goto tr_handle_get_iface_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_CLASS_INTERFACE:
- case UT_WRITE_VENDOR_INTERFACE:
- /* XXX forward */
- break;
-
- case UT_READ_CLASS_INTERFACE:
- case UT_READ_VENDOR_INTERFACE:
- /* XXX forward */
- break;
-
- case UT_WRITE_CLASS_DEVICE:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- goto tr_valid;
- case UR_SET_DESCRIPTOR:
- case UR_SET_FEATURE:
- break;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_CLASS_OTHER:
- switch (std->req.bRequest) {
- case UR_CLEAR_FEATURE:
- goto tr_handle_clear_port_feature;
- case UR_SET_FEATURE:
- goto tr_handle_set_port_feature;
- case UR_CLEAR_TT_BUFFER:
- case UR_RESET_TT:
- case UR_STOP_TT:
- goto tr_valid;
-
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_CLASS_OTHER:
- switch (std->req.bRequest) {
- case UR_GET_TT_STATE:
- goto tr_handle_get_tt_state;
- case UR_GET_STATUS:
- goto tr_handle_get_port_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_CLASS_DEVICE:
- switch (std->req.bRequest) {
- case UR_GET_DESCRIPTOR:
- goto tr_handle_get_class_descriptor;
- case UR_GET_STATUS:
- goto tr_handle_get_class_status;
-
- default:
- goto tr_stalled;
- }
- break;
- default:
- goto tr_stalled;
- }
- goto tr_valid;
-
-tr_handle_get_descriptor:
- switch (value >> 8) {
- case UDESC_DEVICE:
- if (value & 0xff) {
- goto tr_stalled;
- }
- std->len = sizeof(uss820dci_devd);
- std->ptr = USB_ADD_BYTES(&uss820dci_devd, 0);
- goto tr_valid;
- case UDESC_CONFIG:
- if (value & 0xff) {
- goto tr_stalled;
- }
- std->len = sizeof(uss820dci_confd);
- std->ptr = USB_ADD_BYTES(&uss820dci_confd, 0);
- goto tr_valid;
- case UDESC_STRING:
- switch (value & 0xff) {
- case 0: /* Language table */
- std->len = sizeof(uss820dci_langtab);
- std->ptr = USB_ADD_BYTES(&uss820dci_langtab, 0);
- goto tr_valid;
-
- case 1: /* Vendor */
- std->len = sizeof(uss820dci_vendor);
- std->ptr = USB_ADD_BYTES(&uss820dci_vendor, 0);
- goto tr_valid;
-
- case 2: /* Product */
- std->len = sizeof(uss820dci_product);
- std->ptr = USB_ADD_BYTES(&uss820dci_product, 0);
- goto tr_valid;
- default:
- break;
- }
- break;
- default:
- goto tr_stalled;
- }
- goto tr_stalled;
-
-tr_handle_get_config:
- std->len = 1;
- sc->sc_hub_temp.wValue[0] = sc->sc_conf;
- goto tr_valid;
-
-tr_handle_get_status:
- std->len = 2;
- USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
- goto tr_valid;
-
-tr_handle_set_address:
- if (value & 0xFF00) {
- goto tr_stalled;
- }
- sc->sc_rt_addr = value;
- goto tr_valid;
-
-tr_handle_set_config:
- if (value >= 2) {
- goto tr_stalled;
- }
- sc->sc_conf = value;
- goto tr_valid;
-
-tr_handle_get_interface:
- std->len = 1;
- sc->sc_hub_temp.wValue[0] = 0;
- goto tr_valid;
-
-tr_handle_get_tt_state:
-tr_handle_get_class_status:
-tr_handle_get_iface_status:
-tr_handle_get_ep_status:
- std->len = 2;
- USETW(sc->sc_hub_temp.wValue, 0);
- goto tr_valid;
-
-tr_handle_set_halt:
-tr_handle_set_interface:
-tr_handle_set_wakeup:
-tr_handle_clear_wakeup:
-tr_handle_clear_halt:
- goto tr_valid;
-
-tr_handle_clear_port_feature:
- if (index != 1) {
- goto tr_stalled;
- }
- DPRINTFN(9, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
-
- switch (value) {
- case UHF_PORT_SUSPEND:
- uss820dci_wakeup_peer(sc);
- break;
-
- case UHF_PORT_ENABLE:
- sc->sc_flags.port_enabled = 0;
- break;
-
- case UHF_PORT_TEST:
- case UHF_PORT_INDICATOR:
- case UHF_C_PORT_ENABLE:
- case UHF_C_PORT_OVER_CURRENT:
- case UHF_C_PORT_RESET:
- /* nops */
- break;
- case UHF_PORT_POWER:
- sc->sc_flags.port_powered = 0;
- uss820dci_pull_down(sc);
- break;
- case UHF_C_PORT_CONNECTION:
- sc->sc_flags.change_connect = 0;
- break;
- case UHF_C_PORT_SUSPEND:
- sc->sc_flags.change_suspend = 0;
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- goto tr_valid;
-
-tr_handle_set_port_feature:
- if (index != 1) {
- goto tr_stalled;
- }
- DPRINTFN(9, "UR_SET_PORT_FEATURE\n");
-
- switch (value) {
- case UHF_PORT_ENABLE:
- sc->sc_flags.port_enabled = 1;
- break;
- case UHF_PORT_SUSPEND:
- case UHF_PORT_RESET:
- case UHF_PORT_TEST:
- case UHF_PORT_INDICATOR:
- /* nops */
- break;
- case UHF_PORT_POWER:
- sc->sc_flags.port_powered = 1;
- break;
- default:
- std->err = USB_ERR_IOERROR;
- goto done;
- }
- goto tr_valid;
-
-tr_handle_get_port_status:
-
- DPRINTFN(9, "UR_GET_PORT_STATUS\n");
-
- if (index != 1) {
- goto tr_stalled;
- }
- if (sc->sc_flags.status_vbus) {
- uss820dci_pull_up(sc);
- } else {
- uss820dci_pull_down(sc);
- }
-
- /* Select FULL-speed and Device Side Mode */
-
- value = UPS_PORT_MODE_DEVICE;
-
- if (sc->sc_flags.port_powered) {
- value |= UPS_PORT_POWER;
- }
- if (sc->sc_flags.port_enabled) {
- value |= UPS_PORT_ENABLED;
- }
- if (sc->sc_flags.status_vbus &&
- sc->sc_flags.status_bus_reset) {
- value |= UPS_CURRENT_CONNECT_STATUS;
- }
- if (sc->sc_flags.status_suspend) {
- value |= UPS_SUSPEND;
- }
- USETW(sc->sc_hub_temp.ps.wPortStatus, value);
-
- value = 0;
-
- if (sc->sc_flags.change_connect) {
- value |= UPS_C_CONNECT_STATUS;
- }
- if (sc->sc_flags.change_suspend) {
- value |= UPS_C_SUSPEND;
- }
- USETW(sc->sc_hub_temp.ps.wPortChange, value);
- std->len = sizeof(sc->sc_hub_temp.ps);
- goto tr_valid;
-
-tr_handle_get_class_descriptor:
- if (value & 0xFF) {
- goto tr_stalled;
- }
- std->ptr = USB_ADD_BYTES(&uss820dci_hubd, 0);
- std->len = sizeof(uss820dci_hubd);
- goto tr_valid;
-
-tr_stalled:
- std->err = USB_ERR_STALLED;
-tr_valid:
-done:
- return;
-}
-
-static void
-uss820dci_root_ctrl_poll(struct uss820dci_softc *sc)
-{
- usb2_sw_transfer(&sc->sc_root_ctrl,
- &uss820dci_root_ctrl_done);
-}
-
-struct usb2_pipe_methods uss820dci_root_ctrl_methods =
-{
- .open = uss820dci_root_ctrl_open,
- .close = uss820dci_root_ctrl_close,
- .enter = uss820dci_root_ctrl_enter,
- .start = uss820dci_root_ctrl_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 0,
-};
-
-/*------------------------------------------------------------------------*
- * at91dci root interrupt support
- *------------------------------------------------------------------------*/
-static void
-uss820dci_root_intr_open(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_root_intr_close(struct usb2_xfer *xfer)
-{
- struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
-
- if (sc->sc_root_intr.xfer == xfer) {
- sc->sc_root_intr.xfer = NULL;
- }
- uss820dci_device_done(xfer, USB_ERR_CANCELLED);
-}
-
-static void
-uss820dci_root_intr_enter(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_root_intr_start(struct usb2_xfer *xfer)
-{
- struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
-
- sc->sc_root_intr.xfer = xfer;
-}
-
-struct usb2_pipe_methods uss820dci_root_intr_methods =
-{
- .open = uss820dci_root_intr_open,
- .close = uss820dci_root_intr_close,
- .enter = uss820dci_root_intr_enter,
- .start = uss820dci_root_intr_start,
- .enter_is_cancelable = 1,
- .start_is_cancelable = 1,
-};
-
-static void
-uss820dci_xfer_setup(struct usb2_setup_params *parm)
-{
- const struct usb2_hw_ep_profile *pf;
- struct uss820dci_softc *sc;
- struct usb2_xfer *xfer;
- void *last_obj;
- uint32_t ntd;
- uint32_t n;
- uint8_t ep_no;
-
- sc = USS820_DCI_BUS2SC(parm->udev->bus);
- xfer = parm->curr_xfer;
-
- /*
- * NOTE: This driver does not use any of the parameters that
- * are computed from the following values. Just set some
- * reasonable dummies:
- */
- parm->hc_max_packet_size = 0x500;
- parm->hc_max_packet_count = 1;
- parm->hc_max_frame_size = 0x500;
-
- usb2_transfer_setup_sub(parm);
-
- /*
- * compute maximum number of TDs
- */
- if (parm->methods == &uss820dci_device_ctrl_methods) {
-
- ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
-
- } else if (parm->methods == &uss820dci_device_bulk_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else if (parm->methods == &uss820dci_device_intr_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else if (parm->methods == &uss820dci_device_isoc_fs_methods) {
-
- ntd = xfer->nframes + 1 /* SYNC */ ;
-
- } else {
-
- ntd = 0;
- }
-
- /*
- * check if "usb2_transfer_setup_sub" set an error
- */
- if (parm->err) {
- return;
- }
- /*
- * allocate transfer descriptors
- */
- last_obj = NULL;
-
- /*
- * get profile stuff
- */
- if (ntd) {
-
- ep_no = xfer->endpoint & UE_ADDR;
- uss820dci_get_hw_ep_profile(parm->udev, &pf, ep_no);
-
- if (pf == NULL) {
- /* should not happen */
- parm->err = USB_ERR_INVAL;
- return;
- }
- } else {
- ep_no = 0;
- pf = NULL;
- }
-
- /* align data */
- parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
-
- for (n = 0; n != ntd; n++) {
-
- struct uss820dci_td *td;
-
- if (parm->buf) {
-
- td = USB_ADD_BYTES(parm->buf, parm->size[0]);
-
- /* init TD */
- td->io_tag = sc->sc_io_tag;
- td->io_hdl = sc->sc_io_hdl;
- td->max_packet_size = xfer->max_packet_size;
- td->rx_stat_reg = USS820_GET_REG(sc, USS820_RXSTAT);
- td->tx_stat_reg = USS820_GET_REG(sc, USS820_TXSTAT);
- td->rx_flag_reg = USS820_GET_REG(sc, USS820_RXFLG);
- td->tx_flag_reg = USS820_GET_REG(sc, USS820_TXFLG);
- td->rx_fifo_reg = USS820_GET_REG(sc, USS820_RXDAT);
- td->tx_fifo_reg = USS820_GET_REG(sc, USS820_TXDAT);
- td->rx_count_low_reg = USS820_GET_REG(sc, USS820_RXCNTL);
- td->rx_count_high_reg = USS820_GET_REG(sc, USS820_RXCNTH);
- td->tx_count_low_reg = USS820_GET_REG(sc, USS820_TXCNTL);
- td->tx_count_high_reg = USS820_GET_REG(sc, USS820_TXCNTH);
- td->rx_cntl_reg = USS820_GET_REG(sc, USS820_RXCON);
- td->tx_cntl_reg = USS820_GET_REG(sc, USS820_TXCON);
- td->pend_reg = USS820_GET_REG(sc, USS820_PEND);
- td->ep_reg = USS820_GET_REG(sc, USS820_EPINDEX);
- td->ep_index = ep_no;
- if (pf->support_multi_buffer &&
- (parm->methods != &uss820dci_device_ctrl_methods)) {
- td->support_multi_buffer = 1;
- }
- td->obj_next = last_obj;
-
- last_obj = td;
- }
- parm->size[0] += sizeof(*td);
- }
-
- xfer->td_start[0] = last_obj;
-}
-
-static void
-uss820dci_xfer_unsetup(struct usb2_xfer *xfer)
-{
- return;
-}
-
-static void
-uss820dci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
- struct usb2_pipe *pipe)
-{
- struct uss820dci_softc *sc = USS820_DCI_BUS2SC(udev->bus);
-
- DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
- pipe, udev->address,
- edesc->bEndpointAddress, udev->flags.usb2_mode,
- sc->sc_rt_addr);
-
- if (udev->device_index == sc->sc_rt_addr) {
-
- if (udev->flags.usb2_mode != USB_MODE_HOST) {
- /* not supported */
- return;
- }
- switch (edesc->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &uss820dci_root_ctrl_methods;
- break;
- case UE_DIR_IN | USS820_DCI_INTR_ENDPT:
- pipe->methods = &uss820dci_root_intr_methods;
- break;
- default:
- /* do nothing */
- break;
- }
- } else {
-
- if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
- /* not supported */
- return;
- }
- if (udev->speed != USB_SPEED_FULL) {
- /* not supported */
- return;
- }
- switch (edesc->bmAttributes & UE_XFERTYPE) {
- case UE_CONTROL:
- pipe->methods = &uss820dci_device_ctrl_methods;
- break;
- case UE_INTERRUPT:
- pipe->methods = &uss820dci_device_intr_methods;
- break;
- case UE_ISOCHRONOUS:
- pipe->methods = &uss820dci_device_isoc_fs_methods;
- break;
- case UE_BULK:
- pipe->methods = &uss820dci_device_bulk_methods;
- break;
- default:
- /* do nothing */
- break;
- }
- }
-}
-
-struct usb2_bus_methods uss820dci_bus_methods =
-{
- .pipe_init = &uss820dci_pipe_init,
- .xfer_setup = &uss820dci_xfer_setup,
- .xfer_unsetup = &uss820dci_xfer_unsetup,
- .do_poll = &uss820dci_do_poll,
- .get_hw_ep_profile = &uss820dci_get_hw_ep_profile,
- .set_stall = &uss820dci_set_stall,
- .clear_stall = &uss820dci_clear_stall,
- .roothub_exec = &uss820dci_root_ctrl_task,
-};
diff --git a/sys/dev/usb2/controller/uss820dci.h b/sys/dev/usb2/controller/uss820dci.h
deleted file mode 100644
index f99e2d5..0000000
--- a/sys/dev/usb2/controller/uss820dci.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2007 Hans Petter Selasky <hselasky@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.
- */
-
-#ifndef _USS820_DCI_H_
-#define _USS820_DCI_H_
-
-#define USS820_MAX_DEVICES (USB_MIN_DEVICES + 1)
-
-#define USS820_EP_MAX 8 /* maximum number of endpoints */
-
-#define USS820_TXDAT 0x00 /* Transmit FIFO data */
-
-#define USS820_TXCNTL 0x01 /* Transmit FIFO byte count low */
-#define USS820_TXCNTL_MASK 0xFF
-
-#define USS820_TXCNTH 0x02 /* Transmit FIFO byte count high */
-#define USS820_TXCNTH_MASK 0x03
-#define USS820_TXCNTH_UNUSED 0xFC
-
-#define USS820_TXCON 0x03 /* USB transmit FIFO control */
-#define USS820_TXCON_REVRP 0x01
-#define USS820_TXCON_ADVRM 0x02
-#define USS820_TXCON_ATM 0x04 /* Automatic Transmit Management */
-#define USS820_TXCON_TXISO 0x08 /* Transmit Isochronous Data */
-#define USS820_TXCON_UNUSED 0x10
-#define USS820_TXCON_FFSZ_16_64 0x00
-#define USS820_TXCON_FFSZ_64_256 0x20
-#define USS820_TXCON_FFSZ_8_512 0x40
-#define USS820_TXCON_FFSZ_32_1024 0x60
-#define USS820_TXCON_FFSZ_MASK 0x60
-#define USS820_TXCON_TXCLR 0x80 /* Transmit FIFO clear */
-
-#define USS820_TXFLG 0x04 /* Transmit FIFO flag (Read Only) */
-#define USS820_TXFLG_TXOVF 0x01 /* TX overrun */
-#define USS820_TXFLG_TXURF 0x02 /* TX underrun */
-#define USS820_TXFLG_TXFULL 0x04 /* TX full */
-#define USS820_TXFLG_TXEMP 0x08 /* TX empty */
-#define USS820_TXFLG_UNUSED 0x30
-#define USS820_TXFLG_TXFIF0 0x40
-#define USS820_TXFLG_TXFIF1 0x80
-
-#define USS820_RXDAT 0x05 /* Receive FIFO data */
-
-#define USS820_RXCNTL 0x06 /* Receive FIFO byte count low */
-#define USS820_RXCNTL_MASK 0xFF
-
-#define USS820_RXCNTH 0x07 /* Receive FIFO byte count high */
-#define USS820_RXCNTH_MASK 0x03
-#define USS820_RXCNTH_UNUSED 0xFC
-
-#define USS820_RXCON 0x08 /* Receive FIFO control */
-#define USS820_RXCON_REVWP 0x01
-#define USS820_RXCON_ADVWM 0x02
-#define USS820_RXCON_ARM 0x04 /* Auto Receive Management */
-#define USS820_RXCON_RXISO 0x08 /* Receive Isochronous Data */
-#define USS820_RXCON_RXFFRC 0x10 /* FIFO Read Complete */
-#define USS820_RXCON_FFSZ_16_64 0x00
-#define USS820_RXCON_FFSZ_64_256 0x20
-#define USS820_RXCON_FFSZ_8_512 0x40
-#define USS820_RXCON_FFSZ_32_1024 0x60
-#define USS820_RXCON_RXCLR 0x80 /* Receive FIFO clear */
-
-#define USS820_RXFLG 0x09 /* Receive FIFO flag (Read Only) */
-#define USS820_RXFLG_RXOVF 0x01 /* RX overflow */
-#define USS820_RXFLG_RXURF 0x02 /* RX underflow */
-#define USS820_RXFLG_RXFULL 0x04 /* RX full */
-#define USS820_RXFLG_RXEMP 0x08 /* RX empty */
-#define USS820_RXFLG_RXFLUSH 0x10 /* RX flush */
-#define USS820_RXFLG_UNUSED 0x20
-#define USS820_RXFLG_RXFIF0 0x40
-#define USS820_RXFLG_RXFIF1 0x80
-
-#define USS820_EPINDEX 0x0a /* Endpoint index selection */
-#define USS820_EPINDEX_MASK 0x07
-#define USS820_EPINDEX_UNUSED 0xF8
-
-#define USS820_EPCON 0x0b /* Endpoint control */
-#define USS820_EPCON_TXEPEN 0x01 /* Transmit Endpoint Enable */
-#define USS820_EPCON_TXOE 0x02 /* Transmit Output Enable */
-#define USS820_EPCON_RXEPEN 0x04 /* Receive Endpoint Enable */
-#define USS820_EPCON_RXIE 0x08 /* Receive Input Enable */
-#define USS820_EPCON_RXSPM 0x10 /* Receive Single-Packet Mode */
-#define USS820_EPCON_CTLEP 0x20 /* Control Endpoint */
-#define USS820_EPCON_TXSTL 0x40 /* Stall Transmit Endpoint */
-#define USS820_EPCON_RXSTL 0x80 /* Stall Receive Endpoint */
-
-#define USS820_TXSTAT 0x0c /* Transmit status */
-#define USS820_TXSTAT_TXACK 0x01 /* Transmit Acknowledge */
-#define USS820_TXSTAT_TXERR 0x02 /* Transmit Error */
-#define USS820_TXSTAT_TXVOID 0x04 /* Transmit Void */
-#define USS820_TXSTAT_TXSOVW 0x08 /* Transmit Data Sequence Overwrite
- * Bit */
-#define USS820_TXSTAT_TXFLUSH 0x10 /* Transmit FIFO Packet Flushed */
-#define USS820_TXSTAT_TXNAKE 0x20 /* Transmit NAK Mode Enable */
-#define USS820_TXSTAT_TXDSAM 0x40 /* Transmit Data-Set-Available Mode */
-#define USS820_TXSTAT_TXSEQ 0x80 /* Transmitter Current Sequence Bit */
-
-#define USS820_RXSTAT 0x0d /* Receive status */
-#define USS820_RXSTAT_RXACK 0x01 /* Receive Acknowledge */
-#define USS820_RXSTAT_RXERR 0x02 /* Receive Error */
-#define USS820_RXSTAT_RXVOID 0x04 /* Receive Void */
-#define USS820_RXSTAT_RXSOVW 0x08 /* Receive Data Sequence Overwrite Bit */
-#define USS820_RXSTAT_EDOVW 0x10 /* End Overwrite Flag */
-#define USS820_RXSTAT_STOVW 0x20 /* Start Overwrite Flag */
-#define USS820_RXSTAT_RXSETUP 0x40 /* Received SETUP token */
-#define USS820_RXSTAT_RXSEQ 0x80 /* Receiver Endpoint Sequence Bit */
-
-#define USS820_SOFL 0x0e /* Start Of Frame counter low */
-#define USS820_SOFL_MASK 0xFF
-
-#define USS820_SOFH 0x0f /* Start Of Frame counter high */
-#define USS820_SOFH_MASK 0x07
-#define USS820_SOFH_SOFDIS 0x08 /* SOF Pin Output Disable */
-#define USS820_SOFH_FTLOCK 0x10 /* Frame Timer Lock */
-#define USS820_SOFH_SOFIE 0x20 /* SOF Interrupt Enable */
-#define USS820_SOFH_ASOF 0x40 /* Any Start of Frame */
-#define USS820_SOFH_SOFACK 0x80 /* SOF Token Received Without Error */
-
-#define USS820_FADDR 0x10 /* Function Address */
-#define USS820_FADDR_MASK 0x7F
-#define USS820_FADDR_UNUSED 0x80
-
-#define USS820_SCR 0x11 /* System Control */
-#define USS820_SCR_UNUSED 0x01
-#define USS820_SCR_T_IRQ 0x02 /* Global Interrupt Enable */
-#define USS820_SCR_IRQLVL 0x04 /* Interrupt Mode */
-#define USS820_SCR_SRESET 0x08 /* Software reset */
-#define USS820_SCR_IE_RESET 0x10 /* Enable Reset Interrupt */
-#define USS820_SCR_IE_SUSP 0x20 /* Enable Suspend Interrupt */
-#define USS820_SCR_RWUPE 0x40 /* Enable Remote Wake-Up Feature */
-#define USS820_SCR_IRQPOL 0x80 /* IRQ polarity */
-
-#define USS820_SSR 0x12 /* System Status */
-#define USS820_SSR_RESET 0x01 /* Reset Condition Detected on USB
- * cable */
-#define USS820_SSR_SUSPEND 0x02 /* Suspend Detected */
-#define USS820_SSR_RESUME 0x04 /* Resume Detected */
-#define USS820_SSR_SUSPDIS 0x08 /* Suspend Disable */
-#define USS820_SSR_SUSPPO 0x10 /* Suspend Power Off */
-#define USS820_SSR_UNUSED 0xE0
-
-#define USS820_UNK0 0x13 /* Unknown */
-#define USS820_UNK0_UNUSED 0xFF
-
-#define USS820_SBI 0x14 /* Serial bus interrupt low */
-#define USS820_SBI_FTXD0 0x01 /* Function Transmit Done, EP 0 */
-#define USS820_SBI_FRXD0 0x02 /* Function Receive Done, EP 0 */
-#define USS820_SBI_FTXD1 0x04
-#define USS820_SBI_FRXD1 0x08
-#define USS820_SBI_FTXD2 0x10
-#define USS820_SBI_FRXD2 0x20
-#define USS820_SBI_FTXD3 0x40
-#define USS820_SBI_FRXD3 0x80
-
-#define USS820_SBI1 0x15 /* Serial bus interrupt high */
-#define USS820_SBI1_FTXD4 0x01
-#define USS820_SBI1_FRXD4 0x02
-#define USS820_SBI1_FTXD5 0x04
-#define USS820_SBI1_FRXD5 0x08
-#define USS820_SBI1_FTXD6 0x10
-#define USS820_SBI1_FRXD6 0x20
-#define USS820_SBI1_FTXD7 0x40
-#define USS820_SBI1_FRXD7 0x80
-
-#define USS820_SBIE 0x16 /* Serial bus interrupt enable low */
-#define USS820_SBIE_FTXIE0 0x01
-#define USS820_SBIE_FRXIE0 0x02
-#define USS820_SBIE_FTXIE1 0x04
-#define USS820_SBIE_FRXIE1 0x08
-#define USS820_SBIE_FTXIE2 0x10
-#define USS820_SBIE_FRXIE2 0x20
-#define USS820_SBIE_FTXIE3 0x40
-#define USS820_SBIE_FRXIE3 0x80
-
-#define USS820_SBIE1 0x17 /* Serial bus interrupt enable high */
-#define USS820_SBIE1_FTXIE4 0x01
-#define USS820_SBIE1_FRXIE4 0x02
-#define USS820_SBIE1_FTXIE5 0x04
-#define USS820_SBIE1_FRXIE5 0x08
-#define USS820_SBIE1_FTXIE6 0x10
-#define USS820_SBIE1_FRXIE6 0x20
-#define USS820_SBIE1_FTXIE7 0x40
-#define USS820_SBIE1_FRXIE7 0x80
-
-#define USS820_REV 0x18 /* Hardware revision */
-#define USS820_REV_MIN 0x0F
-#define USS820_REV_MAJ 0xF0
-
-#define USS820_LOCK 0x19 /* Suspend power-off locking */
-#define USS820_LOCK_UNLOCKED 0x01
-#define USS820_LOCK_UNUSED 0xFE
-
-#define USS820_PEND 0x1a /* Pend hardware status update */
-#define USS820_PEND_PEND 0x01
-#define USS820_PEND_UNUSED 0xFE
-
-#define USS820_SCRATCH 0x1b /* Scratch firmware information */
-#define USS820_SCRATCH_MASK 0x7F
-#define USS820_SCRATCH_IE_RESUME 0x80 /* Enable Resume Interrupt */
-
-#define USS820_MCSR 0x1c /* Miscellaneous control and status */
-#define USS820_MCSR_DPEN 0x01 /* DPLS Pull-Up Enable */
-#define USS820_MCSR_SUSPLOE 0x02 /* Suspend Lock Out Enable */
-#define USS820_MCSR_BDFEAT 0x04 /* Board Feature Enable */
-#define USS820_MCSR_FEAT 0x08 /* Feature Enable */
-#define USS820_MCSR_PKGID 0x10 /* Package Identification */
-#define USS820_MCSR_SUSPS 0x20 /* Suspend Status */
-#define USS820_MCSR_INIT 0x40 /* Device Initialized */
-#define USS820_MCSR_RWUPR 0x80 /* Remote Wakeup-Up Remember */
-
-#define USS820_DSAV 0x1d /* Data set available low (Read Only) */
-#define USS820_DSAV_TXAV0 0x01
-#define USS820_DSAV_RXAV0 0x02
-#define USS820_DSAV_TXAV1 0x04
-#define USS820_DSAV_RXAV1 0x08
-#define USS820_DSAV_TXAV2 0x10
-#define USS820_DSAV_RXAV2 0x20
-#define USS820_DSAV_TXAV3 0x40
-#define USS820_DSAV_RXAV3 0x80
-
-#define USS820_DSAV1 0x1e /* Data set available high */
-#define USS820_DSAV1_TXAV4 0x01
-#define USS820_DSAV1_RXAV4 0x02
-#define USS820_DSAV1_TXAV5 0x04
-#define USS820_DSAV1_RXAV5 0x08
-#define USS820_DSAV1_TXAV6 0x10
-#define USS820_DSAV1_RXAV6 0x20
-#define USS820_DSAV1_TXAV7 0x40
-#define USS820_DSAV1_RXAV7 0x80
-
-#define USS820_UNK1 0x1f /* Unknown */
-#define USS820_UNK1_UNKNOWN 0xFF
-
-#define USS820_GET_REG(sc,reg) \
- ((reg) << (sc)->sc_reg_shift)
-
-#define USS820_READ_1(sc, reg) \
- bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, \
- USS820_GET_REG(sc,reg))
-
-#define USS820_WRITE_1(sc, reg, data) \
- bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, \
- USS820_GET_REG(sc,reg), data)
-
-struct uss820dci_td;
-
-typedef uint8_t (uss820dci_cmd_t)(struct uss820dci_td *td);
-
-struct uss820dci_td {
- bus_space_tag_t io_tag;
- bus_space_handle_t io_hdl;
- struct uss820dci_td *obj_next;
- uss820dci_cmd_t *func;
- struct usb2_page_cache *pc;
- uint32_t offset;
- uint32_t remainder;
- uint16_t max_packet_size;
- uint8_t rx_stat_reg;
- uint8_t tx_stat_reg;
- uint8_t rx_flag_reg;
- uint8_t tx_flag_reg;
- uint8_t rx_fifo_reg;
- uint8_t tx_fifo_reg;
- uint8_t rx_count_low_reg;
- uint8_t rx_count_high_reg;
- uint8_t tx_count_low_reg;
- uint8_t tx_count_high_reg;
- uint8_t rx_cntl_reg;
- uint8_t tx_cntl_reg;
- uint8_t ep_reg;
- uint8_t pend_reg;
- uint8_t ep_index;
- uint8_t error:1;
- uint8_t alt_next:1;
- uint8_t short_pkt:1;
- uint8_t support_multi_buffer:1;
- uint8_t did_stall:1;
-};
-
-struct uss820_std_temp {
- uss820dci_cmd_t *func;
- struct usb2_page_cache *pc;
- struct uss820dci_td *td;
- struct uss820dci_td *td_next;
- uint32_t len;
- uint32_t offset;
- uint16_t max_frame_size;
- uint8_t short_pkt;
- /*
- * short_pkt = 0: transfer should be short terminated
- * short_pkt = 1: transfer should not be short terminated
- */
- uint8_t setup_alt_next;
-};
-
-struct uss820dci_config_desc {
- struct usb2_config_descriptor confd;
- struct usb2_interface_descriptor ifcd;
- struct usb2_endpoint_descriptor endpd;
-} __packed;
-
-union uss820_hub_temp {
- uWord wValue;
- struct usb2_port_status ps;
-};
-
-struct uss820_flags {
- uint8_t change_connect:1;
- uint8_t change_suspend:1;
- uint8_t status_suspend:1; /* set if suspended */
- uint8_t status_vbus:1; /* set if present */
- uint8_t status_bus_reset:1; /* set if reset complete */
- uint8_t clocks_off:1;
- uint8_t port_powered:1;
- uint8_t port_enabled:1;
- uint8_t d_pulled_up:1;
- uint8_t mcsr_feat:1;
-};
-
-struct uss820dci_softc {
- struct usb2_bus sc_bus;
- union uss820_hub_temp sc_hub_temp;
- LIST_HEAD(, usb2_xfer) sc_interrupt_list_head;
- struct usb2_sw_transfer sc_root_ctrl;
- struct usb2_sw_transfer sc_root_intr;
-
- struct usb2_device *sc_devices[USS820_MAX_DEVICES];
- struct resource *sc_io_res;
- struct resource *sc_irq_res;
- void *sc_intr_hdl;
- bus_size_t sc_io_size;
- bus_space_tag_t sc_io_tag;
- bus_space_handle_t sc_io_hdl;
-
- uint8_t sc_rt_addr; /* root HUB address */
- uint8_t sc_dv_addr; /* device address */
- uint8_t sc_conf; /* root HUB config */
- uint8_t sc_reg_shift;
-
- uint8_t sc_hub_idata[1];
-
- struct uss820_flags sc_flags;
-};
-
-/* prototypes */
-
-usb2_error_t uss820dci_init(struct uss820dci_softc *sc);
-void uss820dci_uninit(struct uss820dci_softc *sc);
-void uss820dci_suspend(struct uss820dci_softc *sc);
-void uss820dci_resume(struct uss820dci_softc *sc);
-void uss820dci_interrupt(struct uss820dci_softc *sc);
-
-#endif /* _USS820_DCI_H_ */
diff --git a/sys/dev/usb2/controller/uss820dci_atmelarm.c b/sys/dev/usb2/controller/uss820dci_atmelarm.c
deleted file mode 100644
index 387c167..0000000
--- a/sys/dev/usb2/controller/uss820dci_atmelarm.c
+++ /dev/null
@@ -1,239 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2008 Hans Petter Selasky <hselasky@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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <dev/usb2/controller/uss820dci.h>
-
-#include <sys/rman.h>
-
-static device_probe_t uss820_atmelarm_probe;
-static device_attach_t uss820_atmelarm_attach;
-static device_detach_t uss820_atmelarm_detach;
-static device_suspend_t uss820_atmelarm_suspend;
-static device_resume_t uss820_atmelarm_resume;
-static device_shutdown_t uss820_atmelarm_shutdown;
-
-static device_method_t uss820dci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uss820_atmelarm_probe),
- DEVMETHOD(device_attach, uss820_atmelarm_attach),
- DEVMETHOD(device_detach, uss820_atmelarm_detach),
- DEVMETHOD(device_suspend, uss820_atmelarm_suspend),
- DEVMETHOD(device_resume, uss820_atmelarm_resume),
- DEVMETHOD(device_shutdown, uss820_atmelarm_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t uss820dci_driver = {
- .name = "uss820",
- .methods = uss820dci_methods,
- .size = sizeof(struct uss820dci_softc),
-};
-
-static devclass_t uss820dci_devclass;
-
-DRIVER_MODULE(uss820, atmelarm, uss820dci_driver, uss820dci_devclass, 0, 0);
-MODULE_DEPEND(uss820, usb2_controller, 1, 1, 1);
-MODULE_DEPEND(uss820, usb2_core, 1, 1, 1);
-
-static const char *const uss820_desc = "USS820 USB Device Controller";
-
-static int
-uss820_atmelarm_suspend(device_t dev)
-{
- struct uss820dci_softc *sc = device_get_softc(dev);
- int err;
-
- err = bus_generic_suspend(dev);
- if (err == 0) {
- uss820dci_suspend(sc);
- }
- return (err);
-}
-
-static int
-uss820_atmelarm_resume(device_t dev)
-{
- struct uss820dci_softc *sc = device_get_softc(dev);
- int err;
-
- uss820dci_resume(sc);
-
- err = bus_generic_resume(dev);
-
- return (err);
-}
-
-static int
-uss820_atmelarm_shutdown(device_t dev)
-{
- struct uss820dci_softc *sc = device_get_softc(dev);
- int err;
-
- err = bus_generic_shutdown(dev);
- if (err)
- return (err);
-
- uss820dci_uninit(sc);
-
- return (0);
-}
-
-static int
-uss820_atmelarm_probe(device_t dev)
-{
- device_set_desc(dev, uss820_desc);
- return (0); /* success */
-}
-
-static int
-uss820_atmelarm_attach(device_t dev)
-{
- struct uss820dci_softc *sc = device_get_softc(dev);
- int err;
- int rid;
-
- /* initialise some bus fields */
- sc->sc_bus.parent = dev;
- sc->sc_bus.devices = sc->sc_devices;
- sc->sc_bus.devices_max = USS820_MAX_DEVICES;
-
- /* get all DMA memory */
- if (usb2_bus_mem_alloc_all(&sc->sc_bus,
- USB_GET_DMA_TAG(dev), NULL)) {
- return (ENOMEM);
- }
- rid = 0;
- sc->sc_io_res =
- bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
-
- if (!sc->sc_io_res) {
- goto error;
- }
- sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
- sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
- sc->sc_io_size = rman_get_size(sc->sc_io_res);
-
- /* multiply all addresses by 4 */
- sc->sc_reg_shift = 2;
-
- rid = 0;
- sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->sc_irq_res == NULL) {
- goto error;
- }
- sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
- if (!(sc->sc_bus.bdev)) {
- goto error;
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-
-#if (__FreeBSD_version >= 700031)
- err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- NULL, (void *)uss820dci_interrupt, sc, &sc->sc_intr_hdl);
-#else
- err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
- (void *)uss820dci_interrupt, sc, &sc->sc_intr_hdl);
-#endif
- if (err) {
- sc->sc_intr_hdl = NULL;
- goto error;
- }
- err = uss820dci_init(sc);
- if (err) {
- device_printf(dev, "Init failed\n");
- goto error;
- }
- err = device_probe_and_attach(sc->sc_bus.bdev);
- if (err) {
- device_printf(dev, "USB probe and attach failed\n");
- goto error;
- }
- return (0);
-
-error:
- uss820_atmelarm_detach(dev);
- return (ENXIO);
-}
-
-static int
-uss820_atmelarm_detach(device_t dev)
-{
- struct uss820dci_softc *sc = device_get_softc(dev);
- device_t bdev;
- int err;
-
- if (sc->sc_bus.bdev) {
- bdev = sc->sc_bus.bdev;
- device_detach(bdev);
- device_delete_child(dev, bdev);
- }
- /* during module unload there are lots of children leftover */
- device_delete_all_children(dev);
-
- if (sc->sc_irq_res && sc->sc_intr_hdl) {
- /*
- * only call at91_udp_uninit() after at91_udp_init()
- */
- uss820dci_uninit(sc);
-
- err = bus_teardown_intr(dev, sc->sc_irq_res,
- sc->sc_intr_hdl);
- sc->sc_intr_hdl = NULL;
- }
- if (sc->sc_irq_res) {
- bus_release_resource(dev, SYS_RES_IRQ, 0,
- sc->sc_irq_res);
- sc->sc_irq_res = NULL;
- }
- if (sc->sc_io_res) {
- bus_release_resource(dev, SYS_RES_IOPORT, 0,
- sc->sc_io_res);
- sc->sc_io_res = NULL;
- }
- usb2_bus_mem_free_all(&sc->sc_bus, NULL);
-
- return (0);
-}
diff --git a/sys/dev/usb2/core/README.TXT b/sys/dev/usb2/core/README.TXT
deleted file mode 100644
index 7367230..0000000
--- a/sys/dev/usb2/core/README.TXT
+++ /dev/null
@@ -1,411 +0,0 @@
-
-$FreeBSD$
-
-DESCRIPTION OF THE NEW USB API
-
-The new USB 2.0 API consists of 5 functions. All transfer types are
-managed using these functions. There is no longer need for separate
-functions to setup INTERRUPT- and ISOCHRONOUS- transfers.
-
-+--------------------------------------------------------------+
-| |
-| "usb2_transfer_setup" - This function will allocate all |
-| necessary DMA memory and might |
-| sleep! |
-| |
-| "usb2_transfer_unsetup" - This function will stop the USB |
-| transfer, if it is currently |
-| active, release all DMA |
-| memory and might sleep! |
-| |
-| "usb2_transfer_start" - This function will start an USB |
-| transfer, if not already started.|
-| This function is always |
-| non-blocking. ** |
-| |
-| "usb2_transfer_stop" - This function will stop an USB |
-| transfer, if not already stopped.|
-| The callback function will be |
-| called before this function |
-| returns. This function is always |
-| non-blocking. ** |
-| |
-| "usb2_transfer_drain" - This function will stop an USB |
-| transfer, if not already stopped |
-| and wait for any additional |
-| DMA load operations to complete. |
-| Buffers that are loaded into DMA |
-| using "usb2_set_frame_data" can |
-| safely be freed after that |
-| this function has returned. This |
-| function can block the caller. |
-| |
-| ** These functions must be called with the private driver's |
-| lock locked. |
-| |
-| NOTE: These USB API functions are NULL safe, with regard |
-| to the USB transfer structure pointer. |
-+--------------------------------------------------------------+
-
-Reference: /sys/dev/usb2/core/usb2_transfer.c
-
-/*
- * A simple USB callback state-machine:
- *
- * +->-----------------------+
- * | |
- * +-<-+-------[tr_setup]--------+-<-+-<-[start/restart]
- * | |
- * | |
- * | |
- * +------>-[tr_transferred]---------+
- * | |
- * +--------->-[tr_error]------------+
- */
-
-void
-usb2_default_callback(struct usb2_xfer *xfer)
-{
- /*
- * NOTE: it is not allowed to return
- * before "USB_CHECK_STATUS()",
- * even if the system is tearing down!
- */
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- /*
- * Setup xfer->frlengths[], xfer->nframes
- * and write data to xfer->frbuffers[], if any
- */
-
- /**/
- usb2_start_hardware(xfer);
- return;
-
- case USB_ST_TRANSFERRED:
- /*
- * Read data from xfer->frbuffers[], if any.
- * "xfer->frlengths[]" should now have been
- * updated to the actual length.
- */
- return;
-
- default: /* Error */
- /* print error message and clear stall for example */
- return;
- }
-}
-
-=== Notes for USB control transfers ===
-
-An USB control transfer has three parts. First the SETUP packet, then
-DATA packet(s) and then a STATUS packet. The SETUP packet is always
-pointed to by "xfer->frbuffers[0]" and the length is stored in
-"xfer->frlengths[0]" also if there should not be sent any SETUP
-packet! If an USB control transfer has no DATA stage, then
-"xfer->nframes" should be set to 1. Else the default value is
-"xfer->nframes" equal to 2.
-
-Example1: SETUP + STATUS
- xfer->nframes = 1;
- xfer->frlenghts[0] = 8;
- usb2_start_hardware(xfer);
-
-Example2: SETUP + DATA + STATUS
- xfer->nframes = 2;
- xfer->frlenghts[0] = 8;
- xfer->frlenghts[1] = 1;
- usb2_start_hardware(xfer);
-
-Example3: SETUP + DATA + STATUS - split
-1st callback:
- xfer->nframes = 1;
- xfer->frlenghts[0] = 8;
- usb2_start_hardware(xfer);
-
-2nd callback:
- /* IMPORTANT: frbuffer[0] must still point at the setup packet! */
- xfer->nframes = 2;
- xfer->frlenghts[0] = 0;
- xfer->frlenghts[1] = 1;
- usb2_start_hardware(xfer);
-
-Example4: SETUP + STATUS - split
-1st callback:
- xfer->nframes = 1;
- xfer->frlenghts[0] = 8;
- xfer->flags.manual_status = 1;
- usb2_start_hardware(xfer);
-
-2nd callback:
- xfer->nframes = 1;
- xfer->frlenghts[0] = 0;
- xfer->flags.manual_status = 0;
- usb2_start_hardware(xfer);
-
-
-=== General USB transfer notes ===
-
- 1) Something that one should be aware of is that all USB callbacks support
-recursation. That means one can start/stop whatever transfer from the callback
-of another transfer one desires. Also the transfer that is currently called
-back. Recursion is handled like this that when the callback that wants to
-recurse returns it is called one more time.
-
- 2) After that the "usb2_start_hardware()" function has been called in
-the callback one can always depend on that "tr_error" or "tr_transferred"
-will get jumped afterwards. Always!
-
- 3) Sleeping functions can only be called from the attach routine of the
-driver. Else one should not use sleeping functions unless one has to. It is
-very difficult with sleep, because one has to think that the device might have
-detached when the thread returns from sleep.
-
- 4) Polling.
-
- use_polling
- This flag can be used with any callback and will cause the
- "usb2_transfer_start()" function to wait using "DELAY()",
- without exiting any mutexes, until the transfer is finished or
- has timed out. This flag can be changed during operation.
-
- NOTE: If polling is used the "timeout" field should be non-zero!
- NOTE: USB_ERR_CANCELLED is returned in case of timeout
- instead of USB_ERR_TIMEOUT!
-
-
-
-USB device driver examples:
-
-/sys/dev/usb2/ethernet/if_axe.c
-/sys/dev/usb2/ethernet/if_aue.c
-
-QUICK REFERENCE
-===============
-
-
-/*------------------------------------------------------------------------*
- * usb2_error_t
- * usb2_transfer_setup(udev, ifaces, pxfer, setup_start,
- * n_setup, priv_sc, priv_mtx)
- *------------------------------------------------------------------------*/
-
-- "udev" is a pointer to "struct usb2_device".
-
-- "ifaces" array of interface index numbers to use. See "if_index".
-
-- "pxfer" is a pointer to an array of USB transfer pointers that are
- initialized to NULL, and then pointed to allocated USB transfers.
-
-- "setup_start" is a pointer to an array of USB config structures.
-
-- "n_setup" is a number telling the USB system how many USB transfers
- should be setup.
-
-- "priv_sc" is the private softc pointer, which will be used to
- initialize "xfer->priv_sc".
-
-- "priv_mtx" is the private mutex protecting the transfer structure and
- the softc. This pointer is used to initialize "xfer->priv_mtx".
-
-/*------------------------------------------------------------------------*
- * void
- * usb2_transfer_unsetup(pxfer, n_setup)
- *------------------------------------------------------------------------*/
-
-- "pxfer" is a pointer to an array of USB transfer pointers, that may
- be NULL, that should be freed by the USB system.
-
-- "n_setup" is a number telling the USB system how many USB transfers
- should be unsetup
-
-NOTE: This function can sleep, waiting for active mutexes to become unlocked!
-NOTE: It is not allowed to call "usb2_transfer_unsetup" from the callback
- of a USB transfer.
-
-/*------------------------------------------------------------------------*
- * void
- * usb2_transfer_start(xfer)
- *------------------------------------------------------------------------*/
-
-- "xfer" is pointer to a USB transfer that should be started
-
-NOTE: this function must be called with "priv_mtx" locked
-
-/*------------------------------------------------------------------------*
- * void
- * usb2_transfer_stop(xfer)
- *------------------------------------------------------------------------*/
-
-- "xfer" is a pointer to a USB transfer that should be stopped
-
-NOTE: this function must be called with "priv_mtx" locked
-
-NOTE: if the transfer was in progress, the callback will called with
- "xfer->error=USB_ERR_CANCELLED", before this function returns
-
-/*------------------------------------------------------------------------*
- * struct usb2_config {
- * type, endpoint, direction, interval, timeout, frames, index
- * flags, bufsize, callback
- * };
- *------------------------------------------------------------------------*/
-
-- The "type" field selects the USB pipe type. Valid values are:
- UE_INTERRUPT, UE_CONTROL, UE_BULK, UE_ISOCHRONOUS. The special
- value UE_BULK_INTR will select BULK and INTERRUPT pipes.
- This field is mandatory.
-
-- The "endpoint" field selects the USB endpoint number. A value of
- 0xFF, "-1" or "UE_ADDR_ANY" will select the first matching endpoint.
- This field is mandatory.
-
-- The "direction" field selects the USB endpoint direction. A value of
- "UE_DIR_ANY" will select the first matching endpoint. Else valid
- values are: "UE_DIR_IN" and "UE_DIR_OUT". "UE_DIR_IN" and
- "UE_DIR_OUT" can be binary ORed by "UE_DIR_SID" which means that the
- direction will be swapped in case of USB_MODE_DEVICE. Note that
- "UE_DIR_IN" refers to the data transfer direction of the "IN" tokens
- and "UE_DIR_OUT" refers to the data transfer direction of the "OUT"
- tokens. This field is mandatory.
-
-- The "interval" field selects the interrupt interval. The value of this
- field is given in milliseconds and is independent of device speed. Depending
- on the endpoint type, this field has different meaning:
-
- UE_INTERRUPT)
- "0" use the default interrupt interval based on endpoint descriptor.
- "Else" use the given value for polling rate.
-
- UE_ISOCHRONOUS)
- "0" use default.
- "Else" the value is ignored.
-
- UE_BULK)
- UE_CONTROL)
- "0" no transfer pre-delay.
- "Else" a delay as given by this field in milliseconds is
- inserted before the hardware is started when
- "usb2_start_hardware()" is called.
- NOTE: The transfer timeout, if any, is started after that
- the pre-delay has elapsed!
-
-- The "timeout" field, if non-zero, will set the transfer timeout in
- milliseconds. If the "timeout" field is zero and the transfer type
- is ISOCHRONOUS a timeout of 250ms will be used.
-
-- The "frames" field sets the maximum number of frames. If zero is
- specified it will yield the following results:
-
- UE_BULK)
- UE_INTERRUPT)
- xfer->nframes = 1;
-
- UE_CONTROL)
- xfer->nframes = 2;
-
- UE_ISOCHRONOUS)
- Not allowed. Will cause an error.
-
-- The "ep_index" field allows you to give a number, in case more
- endpoints match the description, that selects which matching
- "ep_index" should be used.
-
-- The "if_index" field allows you to select which of the interface
- numbers in the "ifaces" array parameter passed to "usb2_transfer_setup"
- that should be used when setting up the given USB transfer.
-
-- The "flags" field has type "struct usb2_xfer_flags" and allows one
- to set initial flags an USB transfer. Valid flags are:
-
- force_short_xfer
- This flag forces the last transmitted USB packet to be short.
- A short packet has a length of less than "xfer->max_packet_size",
- which derives from "wMaxPacketSize". This flag can be changed
- during operation.
-
- short_xfer_ok
- This flag allows the received transfer length, "xfer->actlen"
- to be less than "xfer->sumlen" upon completion of a transfer.
- This flag can be changed during operation.
-
- pipe_bof
- This flag causes a failing USB transfer to remain first
- in the PIPE queue except in the case of "xfer->error" equal
- to "USB_ERR_CANCELLED". No other USB transfers in the affected
- PIPE queue will be started until either:
-
- 1) The failing USB transfer is stopped using "usb2_transfer_stop()".
- 2) The failing USB transfer performs a successful transfer.
-
- The purpose of this flag is to avoid races when multiple
- transfers are queued for execution on an USB endpoint, and the
- first executing transfer fails leading to the need for
- clearing of stall for example. In this case this flag is used
- to prevent the following USB transfers from being executed at
- the same time the clear-stall command is executed on the USB
- control endpoint. This flag can be changed during operation.
-
- "BOF" is short for "Block On Failure"
-
- NOTE: This flag should be set on all BULK and INTERRUPT
- USB transfers which use an endpoint that can be shared
- between userland and kernel.
-
- proxy_buffer
- Setting this flag will cause that the total buffer size will
- be rounded up to the nearest atomic hardware transfer
- size. The maximum data length of any USB transfer is always
- stored in the "xfer->max_data_length". For control transfers
- the USB kernel will allocate additional space for the 8-bytes
- of SETUP header. These 8-bytes are not counted by the
- "xfer->max_data_length" variable. This flag can not be changed
- during operation.
-
- ext_buffer
- Setting this flag will cause that no data buffer will be
- allocated. Instead the USB client must supply a data buffer.
- This flag can not be changed during operation.
-
- manual_status
- Setting this flag prevents an USB STATUS stage to be appended
- to the end of the USB control transfer. If no control data is
- transferred this flag must be cleared. Else an error will be
- returned to the USB callback. This flag is mostly useful for
- the USB device side. This flag can be changed during
- operation.
-
- no_pipe_ok
- Setting this flag causes the USB_ERR_NO_PIPE error to be
- ignored. This flag can not be changed during operation.
-
- stall_pipe
- Setting this flag will cause STALL pids to be sent to the
- endpoint belonging to this transfer before the transfer is
- started. The transfer is started at the moment the host issues
- a clear-stall command on the STALL'ed endpoint. This flag can
- be changed during operation. This flag does only have effect
- in USB device side mode except for control endpoints. This
- flag is cleared when the stall command has been executed. This
- flag can only be changed outside the callback function by
- using the functions "usb2_transfer_set_stall()" and
- "usb2_transfer_clear_stall()" !
-
-- The "bufsize" field sets the total buffer size in bytes. If
- this field is zero, "wMaxPacketSize" will be used, multiplied by the
- "frames" field if the transfer type is ISOCHRONOUS. This is useful for
- setting up interrupt pipes. This field is mandatory.
-
- NOTE: For control transfers "bufsize" includes
- the length of the request structure.
-
-- The "callback" pointer sets the USB callback. This field is mandatory.
-
-MUTEX NOTE:
-===========
-
-When you create a mutex using "mtx_init()", don't forget to call
-"mtx_destroy()" at detach, else you can get "freed memory accessed"
-panics.
-
---HPS
diff --git a/sys/dev/usb2/core/usb2_busdma.c b/sys/dev/usb2/core/usb2_busdma.c
deleted file mode 100644
index 8254e6e..0000000
--- a/sys/dev/usb2/core/usb2_busdma.c
+++ /dev/null
@@ -1,1426 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_debug.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-
-static void usb2_dma_tag_create(struct usb2_dma_tag *, uint32_t, uint32_t);
-static void usb2_dma_tag_destroy(struct usb2_dma_tag *);
-
-#ifdef __FreeBSD__
-static void usb2_dma_lock_cb(void *, bus_dma_lock_op_t);
-static int32_t usb2_m_copy_in_cb(void *, void *, uint32_t);
-static void usb2_pc_alloc_mem_cb(void *, bus_dma_segment_t *, int, int);
-static void usb2_pc_load_mem_cb(void *, bus_dma_segment_t *, int, int);
-static void usb2_pc_common_mem_cb(void *, bus_dma_segment_t *, int, int,
- uint8_t);
-#endif
-
-#ifdef __NetBSD__
-static int32_t usb2_m_copy_in_cb(void *, caddr_t, uint32_t);
-static void usb2_pc_common_mem_cb(struct usb2_page_cache *,
- bus_dma_segment_t *, int, int, uint8_t);
-#endif
-
-/*------------------------------------------------------------------------*
- * usb2_get_page - lookup DMA-able memory for the given offset
- *
- * NOTE: Only call this function when the "page_cache" structure has
- * been properly initialized !
- *------------------------------------------------------------------------*/
-void
-usb2_get_page(struct usb2_page_cache *pc, uint32_t offset,
- struct usb2_page_search *res)
-{
- struct usb2_page *page;
-
- if (pc->page_start) {
-
- /* Case 1 - something has been loaded into DMA */
-
- if (pc->buffer) {
-
- /* Case 1a - Kernel Virtual Address */
-
- res->buffer = USB_ADD_BYTES(pc->buffer, offset);
- }
- offset += pc->page_offset_buf;
-
- /* compute destination page */
-
- page = pc->page_start;
-
- if (pc->ismultiseg) {
-
- page += (offset / USB_PAGE_SIZE);
-
- offset %= USB_PAGE_SIZE;
-
- res->length = USB_PAGE_SIZE - offset;
- res->physaddr = page->physaddr + offset;
- } else {
- res->length = 0 - 1;
- res->physaddr = page->physaddr + offset;
- }
- if (!pc->buffer) {
-
- /* Case 1b - Non Kernel Virtual Address */
-
- res->buffer = USB_ADD_BYTES(page->buffer, offset);
- }
- } else {
-
- /* Case 2 - Plain PIO */
-
- res->buffer = USB_ADD_BYTES(pc->buffer, offset);
- res->length = 0 - 1;
- res->physaddr = 0;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_copy_in - copy directly to DMA-able memory
- *------------------------------------------------------------------------*/
-void
-usb2_copy_in(struct usb2_page_cache *cache, uint32_t offset,
- const void *ptr, uint32_t len)
-{
- struct usb2_page_search buf_res;
-
- while (len != 0) {
-
- usb2_get_page(cache, offset, &buf_res);
-
- if (buf_res.length > len) {
- buf_res.length = len;
- }
- bcopy(ptr, buf_res.buffer, buf_res.length);
-
- offset += buf_res.length;
- len -= buf_res.length;
- ptr = USB_ADD_BYTES(ptr, buf_res.length);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_copy_in_user - copy directly to DMA-able memory from userland
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-int
-usb2_copy_in_user(struct usb2_page_cache *cache, uint32_t offset,
- const void *ptr, uint32_t len)
-{
- struct usb2_page_search buf_res;
- int error;
-
- while (len != 0) {
-
- usb2_get_page(cache, offset, &buf_res);
-
- if (buf_res.length > len) {
- buf_res.length = len;
- }
- error = copyin(ptr, buf_res.buffer, buf_res.length);
- if (error)
- return (error);
-
- offset += buf_res.length;
- len -= buf_res.length;
- ptr = USB_ADD_BYTES(ptr, buf_res.length);
- }
- return (0); /* success */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_m_copy_in - copy a mbuf chain directly into DMA-able memory
- *------------------------------------------------------------------------*/
-struct usb2_m_copy_in_arg {
- struct usb2_page_cache *cache;
- uint32_t dst_offset;
-};
-
-static int32_t
-#ifdef __FreeBSD__
-usb2_m_copy_in_cb(void *arg, void *src, uint32_t count)
-#else
-usb2_m_copy_in_cb(void *arg, caddr_t src, uint32_t count)
-#endif
-{
- register struct usb2_m_copy_in_arg *ua = arg;
-
- usb2_copy_in(ua->cache, ua->dst_offset, src, count);
- ua->dst_offset += count;
- return (0);
-}
-
-void
-usb2_m_copy_in(struct usb2_page_cache *cache, uint32_t dst_offset,
- struct mbuf *m, uint32_t src_offset, uint32_t src_len)
-{
- struct usb2_m_copy_in_arg arg = {cache, dst_offset};
- register int error;
-
- error = m_apply(m, src_offset, src_len, &usb2_m_copy_in_cb, &arg);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_uiomove - factored out code
- *------------------------------------------------------------------------*/
-int
-usb2_uiomove(struct usb2_page_cache *pc, struct uio *uio,
- uint32_t pc_offset, uint32_t len)
-{
- struct usb2_page_search res;
- int error = 0;
-
- while (len != 0) {
-
- usb2_get_page(pc, pc_offset, &res);
-
- if (res.length > len) {
- res.length = len;
- }
- /*
- * "uiomove()" can sleep so one needs to make a wrapper,
- * exiting the mutex and checking things
- */
- error = uiomove(res.buffer, res.length, uio);
-
- if (error) {
- break;
- }
- pc_offset += res.length;
- len -= res.length;
- }
- return (error);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_copy_out - copy directly from DMA-able memory
- *------------------------------------------------------------------------*/
-void
-usb2_copy_out(struct usb2_page_cache *cache, uint32_t offset,
- void *ptr, uint32_t len)
-{
- struct usb2_page_search res;
-
- while (len != 0) {
-
- usb2_get_page(cache, offset, &res);
-
- if (res.length > len) {
- res.length = len;
- }
- bcopy(res.buffer, ptr, res.length);
-
- offset += res.length;
- len -= res.length;
- ptr = USB_ADD_BYTES(ptr, res.length);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_copy_out_user - copy directly from DMA-able memory to userland
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-int
-usb2_copy_out_user(struct usb2_page_cache *cache, uint32_t offset,
- void *ptr, uint32_t len)
-{
- struct usb2_page_search res;
- int error;
-
- while (len != 0) {
-
- usb2_get_page(cache, offset, &res);
-
- if (res.length > len) {
- res.length = len;
- }
- error = copyout(res.buffer, ptr, res.length);
- if (error)
- return (error);
-
- offset += res.length;
- len -= res.length;
- ptr = USB_ADD_BYTES(ptr, res.length);
- }
- return (0); /* success */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bzero - zero DMA-able memory
- *------------------------------------------------------------------------*/
-void
-usb2_bzero(struct usb2_page_cache *cache, uint32_t offset, uint32_t len)
-{
- struct usb2_page_search res;
-
- while (len != 0) {
-
- usb2_get_page(cache, offset, &res);
-
- if (res.length > len) {
- res.length = len;
- }
- bzero(res.buffer, res.length);
-
- offset += res.length;
- len -= res.length;
- }
-}
-
-
-#ifdef __FreeBSD__
-
-/*------------------------------------------------------------------------*
- * usb2_dma_lock_cb - dummy callback
- *------------------------------------------------------------------------*/
-static void
-usb2_dma_lock_cb(void *arg, bus_dma_lock_op_t op)
-{
- /* we use "mtx_owned()" instead of this function */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_dma_tag_create - allocate a DMA tag
- *
- * NOTE: If the "align" parameter has a value of 1 the DMA-tag will
- * allow multi-segment mappings. Else all mappings are single-segment.
- *------------------------------------------------------------------------*/
-static void
-usb2_dma_tag_create(struct usb2_dma_tag *udt,
- uint32_t size, uint32_t align)
-{
- bus_dma_tag_t tag;
-
- if (bus_dma_tag_create
- ( /* parent */ udt->tag_parent->tag,
- /* alignment */ align,
- /* boundary */ USB_PAGE_SIZE,
- /* lowaddr */ (2ULL << (udt->tag_parent->dma_bits - 1)) - 1,
- /* highaddr */ BUS_SPACE_MAXADDR,
- /* filter */ NULL,
- /* filterarg */ NULL,
- /* maxsize */ size,
- /* nsegments */ (align == 1) ?
- (2 + (size / USB_PAGE_SIZE)) : 1,
- /* maxsegsz */ (align == 1) ?
- USB_PAGE_SIZE : size,
- /* flags */ BUS_DMA_KEEP_PG_OFFSET,
- /* lockfn */ &usb2_dma_lock_cb,
- /* lockarg */ NULL,
- &tag)) {
- tag = NULL;
- }
- udt->tag = tag;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_dma_tag_free - free a DMA tag
- *------------------------------------------------------------------------*/
-static void
-usb2_dma_tag_destroy(struct usb2_dma_tag *udt)
-{
- bus_dma_tag_destroy(udt->tag);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_alloc_mem_cb - BUS-DMA callback function
- *------------------------------------------------------------------------*/
-static void
-usb2_pc_alloc_mem_cb(void *arg, bus_dma_segment_t *segs,
- int nseg, int error)
-{
- usb2_pc_common_mem_cb(arg, segs, nseg, error, 0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_load_mem_cb - BUS-DMA callback function
- *------------------------------------------------------------------------*/
-static void
-usb2_pc_load_mem_cb(void *arg, bus_dma_segment_t *segs,
- int nseg, int error)
-{
- usb2_pc_common_mem_cb(arg, segs, nseg, error, 1);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_common_mem_cb - BUS-DMA callback function
- *------------------------------------------------------------------------*/
-static void
-usb2_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs,
- int nseg, int error, uint8_t isload)
-{
- struct usb2_dma_parent_tag *uptag;
- struct usb2_page_cache *pc;
- struct usb2_page *pg;
- uint32_t rem;
- uint8_t owned;
-
- pc = arg;
- uptag = pc->tag_parent;
-
- /*
- * XXX There is sometimes recursive locking here.
- * XXX We should try to find a better solution.
- * XXX Until further the "owned" variable does
- * XXX the trick.
- */
-
- if (error) {
- goto done;
- }
- pg = pc->page_start;
- pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1);
- rem = segs->ds_addr & (USB_PAGE_SIZE - 1);
- pc->page_offset_buf = rem;
- pc->page_offset_end += rem;
- nseg--;
-#if (USB_DEBUG != 0)
- if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) {
- /*
- * This check verifies that the physical address is correct:
- */
- DPRINTFN(0, "Page offset was not preserved!\n");
- error = 1;
- goto done;
- }
-#endif
- while (nseg > 0) {
- nseg--;
- segs++;
- pg++;
- pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1);
- }
-
-done:
- owned = mtx_owned(uptag->mtx);
- if (!owned)
- mtx_lock(uptag->mtx);
-
- uptag->dma_error = (error ? 1 : 0);
- if (isload) {
- (uptag->func) (uptag);
- } else {
- usb2_cv_broadcast(uptag->cv);
- }
- if (!owned)
- mtx_unlock(uptag->mtx);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_alloc_mem - allocate DMA'able memory
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_pc_alloc_mem(struct usb2_page_cache *pc, struct usb2_page *pg,
- uint32_t size, uint32_t align)
-{
- struct usb2_dma_parent_tag *uptag;
- struct usb2_dma_tag *utag;
- bus_dmamap_t map;
- void *ptr;
- int err;
-
- uptag = pc->tag_parent;
-
- if (align != 1) {
- /*
- * The alignment must be greater or equal to the
- * "size" else the object can be split between two
- * memory pages and we get a problem!
- */
- while (align < size) {
- align *= 2;
- if (align == 0) {
- goto error;
- }
- }
-#if 1
- /*
- * XXX BUS-DMA workaround - FIXME later:
- *
- * We assume that that the aligment at this point of
- * the code is greater than or equal to the size and
- * less than two times the size, so that if we double
- * the size, the size will be greater than the
- * alignment.
- *
- * The bus-dma system has a check for "alignment"
- * being less than "size". If that check fails we end
- * up using contigmalloc which is page based even for
- * small allocations. Try to avoid that to save
- * memory, hence we sometimes to a large number of
- * small allocations!
- */
- if (size <= (USB_PAGE_SIZE / 2)) {
- size *= 2;
- }
-#endif
- }
- /* get the correct DMA tag */
- utag = usb2_dma_tag_find(uptag, size, align);
- if (utag == NULL) {
- goto error;
- }
- /* allocate memory */
- if (bus_dmamem_alloc(
- utag->tag, &ptr, (BUS_DMA_WAITOK | BUS_DMA_COHERENT), &map)) {
- goto error;
- }
- /* setup page cache */
- pc->buffer = ptr;
- pc->page_start = pg;
- pc->page_offset_buf = 0;
- pc->page_offset_end = size;
- pc->map = map;
- pc->tag = utag->tag;
- pc->ismultiseg = (align == 1);
-
- mtx_lock(uptag->mtx);
-
- /* load memory into DMA */
- err = bus_dmamap_load(
- utag->tag, map, ptr, size, &usb2_pc_alloc_mem_cb,
- pc, (BUS_DMA_WAITOK | BUS_DMA_COHERENT));
-
- if (err == EINPROGRESS) {
- usb2_cv_wait(uptag->cv, uptag->mtx);
- err = 0;
- }
- mtx_unlock(uptag->mtx);
-
- if (err || uptag->dma_error) {
- bus_dmamem_free(utag->tag, ptr, map);
- goto error;
- }
- bzero(ptr, size);
-
- usb2_pc_cpu_flush(pc);
-
- return (0);
-
-error:
- /* reset most of the page cache */
- pc->buffer = NULL;
- pc->page_start = NULL;
- pc->page_offset_buf = 0;
- pc->page_offset_end = 0;
- pc->map = NULL;
- pc->tag = NULL;
- return (1);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_free_mem - free DMA memory
- *
- * This function is NULL safe.
- *------------------------------------------------------------------------*/
-void
-usb2_pc_free_mem(struct usb2_page_cache *pc)
-{
- if (pc && pc->buffer) {
-
- bus_dmamap_unload(pc->tag, pc->map);
-
- bus_dmamem_free(pc->tag, pc->buffer, pc->map);
-
- pc->buffer = NULL;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_load_mem - load virtual memory into DMA
- *
- * Return values:
- * 0: Success
- * Else: Error
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_pc_load_mem(struct usb2_page_cache *pc, uint32_t size, uint8_t sync)
-{
- /* setup page cache */
- pc->page_offset_buf = 0;
- pc->page_offset_end = size;
- pc->ismultiseg = 1;
-
- mtx_assert(pc->tag_parent->mtx, MA_OWNED);
-
- if (size > 0) {
- if (sync) {
- struct usb2_dma_parent_tag *uptag;
- int err;
-
- uptag = pc->tag_parent;
-
- /*
- * We have to unload the previous loaded DMA
- * pages before trying to load a new one!
- */
- bus_dmamap_unload(pc->tag, pc->map);
-
- /*
- * Try to load memory into DMA.
- */
- err = bus_dmamap_load(
- pc->tag, pc->map, pc->buffer, size,
- &usb2_pc_alloc_mem_cb, pc, BUS_DMA_WAITOK);
- if (err == EINPROGRESS) {
- usb2_cv_wait(uptag->cv, uptag->mtx);
- err = 0;
- }
- if (err || uptag->dma_error) {
- return (1);
- }
- } else {
-
- /*
- * We have to unload the previous loaded DMA
- * pages before trying to load a new one!
- */
- bus_dmamap_unload(pc->tag, pc->map);
-
- /*
- * Try to load memory into DMA. The callback
- * will be called in all cases:
- */
- if (bus_dmamap_load(
- pc->tag, pc->map, pc->buffer, size,
- &usb2_pc_load_mem_cb, pc, BUS_DMA_WAITOK)) {
- }
- }
- } else {
- if (!sync) {
- /*
- * Call callback so that refcount is decremented
- * properly:
- */
- pc->tag_parent->dma_error = 0;
- (pc->tag_parent->func) (pc->tag_parent);
- }
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_cpu_invalidate - invalidate CPU cache
- *------------------------------------------------------------------------*/
-void
-usb2_pc_cpu_invalidate(struct usb2_page_cache *pc)
-{
- if (pc->page_offset_end == pc->page_offset_buf) {
- /* nothing has been loaded into this page cache! */
- return;
- }
- bus_dmamap_sync(pc->tag, pc->map,
- BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_cpu_flush - flush CPU cache
- *------------------------------------------------------------------------*/
-void
-usb2_pc_cpu_flush(struct usb2_page_cache *pc)
-{
- if (pc->page_offset_end == pc->page_offset_buf) {
- /* nothing has been loaded into this page cache! */
- return;
- }
- bus_dmamap_sync(pc->tag, pc->map,
- BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_dmamap_create - create a DMA map
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_pc_dmamap_create(struct usb2_page_cache *pc, uint32_t size)
-{
- struct usb2_xfer_root *info;
- struct usb2_dma_tag *utag;
-
- /* get info */
- info = pc->tag_parent->info;
-
- /* sanity check */
- if (info == NULL) {
- goto error;
- }
- utag = usb2_dma_tag_find(pc->tag_parent, size, 1);
- if (utag == NULL) {
- goto error;
- }
- /* create DMA map */
- if (bus_dmamap_create(utag->tag, 0, &pc->map)) {
- goto error;
- }
- pc->tag = utag->tag;
- return 0; /* success */
-
-error:
- pc->map = NULL;
- pc->tag = NULL;
- return 1; /* failure */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_dmamap_destroy
- *
- * This function is NULL safe.
- *------------------------------------------------------------------------*/
-void
-usb2_pc_dmamap_destroy(struct usb2_page_cache *pc)
-{
- if (pc && pc->tag) {
- bus_dmamap_destroy(pc->tag, pc->map);
- pc->tag = NULL;
- pc->map = NULL;
- }
-}
-
-#endif
-
-#ifdef __NetBSD__
-
-/*------------------------------------------------------------------------*
- * usb2_dma_tag_create - allocate a DMA tag
- *
- * NOTE: If the "align" parameter has a value of 1 the DMA-tag will
- * allow multi-segment mappings. Else all mappings are single-segment.
- *------------------------------------------------------------------------*/
-static void
-usb2_dma_tag_create(struct usb2_dma_tag *udt,
- uint32_t size, uint32_t align)
-{
- uint32_t nseg;
-
- if (align == 1) {
- nseg = (2 + (size / USB_PAGE_SIZE));
- } else {
- nseg = 1;
- }
-
- udt->p_seg = malloc(nseg * sizeof(*(udt->p_seg)),
- M_USB, M_WAITOK | M_ZERO);
-
- if (udt->p_seg == NULL) {
- return;
- }
- udt->tag = udt->tag_parent->tag;
- udt->n_seg = nseg;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_dma_tag_free - free a DMA tag
- *------------------------------------------------------------------------*/
-static void
-usb2_dma_tag_destroy(struct usb2_dma_tag *udt)
-{
- free(udt->p_seg, M_USB);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_common_mem_cb - BUS-DMA callback function
- *------------------------------------------------------------------------*/
-static void
-usb2_pc_common_mem_cb(struct usb2_page_cache *pc, bus_dma_segment_t *segs,
- int nseg, int error, uint8_t isload, uint8_t dolock)
-{
- struct usb2_dma_parent_tag *uptag;
- struct usb2_page *pg;
- uint32_t rem;
- uint8_t ext_seg; /* extend last segment */
-
- uptag = pc->tag_parent;
-
- if (error) {
- goto done;
- }
- pg = pc->page_start;
- pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1);
- rem = segs->ds_addr & (USB_PAGE_SIZE - 1);
- pc->page_offset_buf = rem;
- pc->page_offset_end += rem;
- if (nseg < ((pc->page_offset_end +
- (USB_PAGE_SIZE - 1)) / USB_PAGE_SIZE)) {
- ext_seg = 1;
- } else {
- ext_seg = 0;
- }
- nseg--;
-#if (USB_DEBUG != 0)
- if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) {
- /*
- * This check verifies that the physical address is correct:
- */
- DPRINTFN(0, "Page offset was not preserved!\n");
- error = 1;
- goto done;
- }
-#endif
- while (nseg > 0) {
- nseg--;
- segs++;
- pg++;
- pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1);
- }
-
- /*
- * XXX The segments we get from BUS-DMA are not aligned,
- * XXX so we need to extend the last segment if we are
- * XXX unaligned and cross the segment boundary!
- */
- if (ext_seg && pc->ismultiseg) {
- (pg + 1)->physaddr = pg->physaddr + USB_PAGE_SIZE;
- }
-done:
- if (dolock)
- mtx_lock(uptag->mtx);
-
- uptag->dma_error = (error ? 1 : 0);
- if (isload) {
- (uptag->func) (uptag);
- }
- if (dolock)
- mtx_unlock(uptag->mtx);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_alloc_mem - allocate DMA'able memory
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_pc_alloc_mem(struct usb2_page_cache *pc, struct usb2_page *pg,
- uint32_t size, uint32_t align)
-{
- struct usb2_dma_parent_tag *uptag;
- struct usb2_dma_tag *utag;
- caddr_t ptr = NULL;
- bus_dmamap_t map;
- int seg_count;
-
- uptag = pc->tag_parent;
-
- if (align != 1) {
- /*
- * The alignment must be greater or equal to the
- * "size" else the object can be split between two
- * memory pages and we get a problem!
- */
- while (align < size) {
- align *= 2;
- if (align == 0) {
- goto done_5;
- }
- }
- }
- /* get the correct DMA tag */
- utag = usb2_dma_tag_find(pc->tag_parent, size, align);
- if (utag == NULL) {
- goto done_5;
- }
- if (bus_dmamem_alloc(utag->tag, size, align, 0, utag->p_seg,
- utag->n_seg, &seg_count, BUS_DMA_WAITOK)) {
- goto done_4;
- }
- if (bus_dmamem_map(utag->tag, utag->p_seg, seg_count, size,
- &ptr, BUS_DMA_WAITOK | BUS_DMA_COHERENT)) {
- goto done_3;
- }
- if (bus_dmamap_create(utag->tag, size, utag->n_seg, (align == 1) ?
- USB_PAGE_SIZE : size, 0, BUS_DMA_WAITOK, &map)) {
- goto done_2;
- }
- if (bus_dmamap_load(utag->tag, map, ptr, size, NULL,
- BUS_DMA_WAITOK)) {
- goto done_1;
- }
- pc->p_seg = malloc(seg_count * sizeof(*(pc->p_seg)),
- M_USB, M_WAITOK | M_ZERO);
- if (pc->p_seg == NULL) {
- goto done_0;
- }
- /* store number if actual segments used */
- pc->n_seg = seg_count;
-
- /* make a copy of the segments */
- bcopy(utag->p_seg, pc->p_seg,
- seg_count * sizeof(*(pc->p_seg)));
-
- /* setup page cache */
- pc->buffer = ptr;
- pc->page_start = pg;
- pc->page_offset_buf = 0;
- pc->page_offset_end = size;
- pc->map = map;
- pc->tag = utag->tag;
- pc->ismultiseg = (align == 1);
-
- usb2_pc_common_mem_cb(pc, utag->p_seg, seg_count, 0, 0, 1);
-
- bzero(ptr, size);
-
- usb2_pc_cpu_flush(pc);
-
- return (0);
-
-done_0:
- bus_dmamap_unload(utag->tag, map);
-done_1:
- bus_dmamap_destroy(utag->tag, map);
-done_2:
- bus_dmamem_unmap(utag->tag, ptr, size);
-done_3:
- bus_dmamem_free(utag->tag, utag->p_seg, seg_count);
-done_4:
- /* utag is destroyed later */
-done_5:
- /* reset most of the page cache */
- pc->buffer = NULL;
- pc->page_start = NULL;
- pc->page_offset_buf = 0;
- pc->page_offset_end = 0;
- pc->map = NULL;
- pc->tag = NULL;
- pc->n_seg = 0;
- pc->p_seg = NULL;
- return (1);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_free_mem - free DMA memory
- *
- * This function is NULL safe.
- *------------------------------------------------------------------------*/
-void
-usb2_pc_free_mem(struct usb2_page_cache *pc)
-{
- if (pc && pc->buffer) {
- bus_dmamap_unload(pc->tag, pc->map);
- bus_dmamap_destroy(pc->tag, pc->map);
- bus_dmamem_unmap(pc->tag, pc->buffer,
- pc->page_offset_end - pc->page_offset_buf);
- bus_dmamem_free(pc->tag, pc->p_seg, pc->n_seg);
- free(pc->p_seg, M_USB);
- pc->buffer = NULL;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_load_mem - load virtual memory into DMA
- *
- * Return values:
- * 0: Success
- * Else: Error
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_pc_load_mem(struct usb2_page_cache *pc, uint32_t size, uint8_t sync)
-{
- int error;
-
- /* setup page cache */
- pc->page_offset_buf = 0;
- pc->page_offset_end = size;
- pc->ismultiseg = 1;
-
- if (size > 0) {
-
- /*
- * We have to unload the previous loaded DMA
- * pages before trying to load a new one!
- */
- bus_dmamap_unload(pc->tag, pc->map);
-
- /* try to load memory into DMA using using no wait option */
- if (bus_dmamap_load(pc->tag, pc->map, pc->buffer,
- size, NULL, BUS_DMA_NOWAIT)) {
- error = ENOMEM;
- } else {
- error = 0;
- }
-
- usb2_pc_common_mem_cb(pc, pc->map->dm_segs,
- pc->map->dm_nsegs, error, !sync);
-
- if (error) {
- return (1);
- }
- } else {
- if (!sync) {
- /*
- * Call callback so that refcount is decremented
- * properly:
- */
- pc->tag_parent->dma_error = 0;
- (pc->tag_parent->func) (pc->tag_parent);
- }
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_cpu_invalidate - invalidate CPU cache
- *------------------------------------------------------------------------*/
-void
-usb2_pc_cpu_invalidate(struct usb2_page_cache *pc)
-{
- uint32_t len;
-
- len = pc->page_offset_end - pc->page_offset_buf;
-
- if (len == 0) {
- /* nothing has been loaded into this page cache */
- return;
- }
- bus_dmamap_sync(pc->tag, pc->map, 0, len,
- BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_cpu_flush - flush CPU cache
- *------------------------------------------------------------------------*/
-void
-usb2_pc_cpu_flush(struct usb2_page_cache *pc)
-{
- uint32_t len;
-
- len = pc->page_offset_end - pc->page_offset_buf;
-
- if (len == 0) {
- /* nothing has been loaded into this page cache */
- return;
- }
- bus_dmamap_sync(pc->tag, pc->map, 0, len,
- BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_dmamap_create - create a DMA map
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_pc_dmamap_create(struct usb2_page_cache *pc, uint32_t size)
-{
- struct usb2_xfer_root *info;
- struct usb2_dma_tag *utag;
-
- /* get info */
- info = pc->tag_parent->info;
-
- /* sanity check */
- if (info == NULL) {
- goto error;
- }
- utag = usb2_dma_tag_find(pc->tag_parent, size, 1);
- if (utag == NULL) {
- goto error;
- }
- if (bus_dmamap_create(utag->tag, size, utag->n_seg,
- USB_PAGE_SIZE, 0, BUS_DMA_WAITOK, &pc->map)) {
- goto error;
- }
- pc->tag = utag->tag;
- pc->p_seg = utag->p_seg;
- pc->n_seg = utag->n_seg;
- return 0; /* success */
-
-error:
- pc->map = NULL;
- pc->tag = NULL;
- pc->p_seg = NULL;
- pc->n_seg = 0;
- return 1; /* failure */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pc_dmamap_destroy
- *
- * This function is NULL safe.
- *------------------------------------------------------------------------*/
-void
-usb2_pc_dmamap_destroy(struct usb2_page_cache *pc)
-{
- if (pc && pc->tag) {
- bus_dmamap_destroy(pc->tag, pc->map);
- pc->tag = NULL;
- pc->map = NULL;
- }
-}
-
-#endif
-
-/*------------------------------------------------------------------------*
- * usb2_dma_tag_find - factored out code
- *------------------------------------------------------------------------*/
-struct usb2_dma_tag *
-usb2_dma_tag_find(struct usb2_dma_parent_tag *udpt,
- uint32_t size, uint32_t align)
-{
- struct usb2_dma_tag *udt;
- uint8_t nudt;
-
- USB_ASSERT(align > 0, ("Invalid parameter align = 0!\n"));
- USB_ASSERT(size > 0, ("Invalid parameter size = 0!\n"));
-
- udt = udpt->utag_first;
- nudt = udpt->utag_max;
-
- while (nudt--) {
-
- if (udt->align == 0) {
- usb2_dma_tag_create(udt, size, align);
- if (udt->tag == NULL) {
- return (NULL);
- }
- udt->align = align;
- udt->size = size;
- return (udt);
- }
- if ((udt->align == align) && (udt->size == size)) {
- return (udt);
- }
- udt++;
- }
- return (NULL);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_dma_tag_setup - initialise USB DMA tags
- *------------------------------------------------------------------------*/
-void
-usb2_dma_tag_setup(struct usb2_dma_parent_tag *udpt,
- struct usb2_dma_tag *udt, bus_dma_tag_t dmat,
- struct mtx *mtx, usb2_dma_callback_t *func,
- struct usb2_xfer_root *info, uint8_t ndmabits,
- uint8_t nudt)
-{
- bzero(udpt, sizeof(*udpt));
-
- /* sanity checking */
- if ((nudt == 0) ||
- (ndmabits == 0) ||
- (mtx == NULL)) {
- /* something is corrupt */
- return;
- }
-#ifdef __FreeBSD__
- /* initialise condition variable */
- usb2_cv_init(udpt->cv, "USB DMA CV");
-#endif
-
- /* store some information */
- udpt->mtx = mtx;
- udpt->info = info;
- udpt->func = func;
- udpt->tag = dmat;
- udpt->utag_first = udt;
- udpt->utag_max = nudt;
- udpt->dma_bits = ndmabits;
-
- while (nudt--) {
- bzero(udt, sizeof(*udt));
- udt->tag_parent = udpt;
- udt++;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_tag_unsetup - factored out code
- *------------------------------------------------------------------------*/
-void
-usb2_dma_tag_unsetup(struct usb2_dma_parent_tag *udpt)
-{
- struct usb2_dma_tag *udt;
- uint8_t nudt;
-
- udt = udpt->utag_first;
- nudt = udpt->utag_max;
-
- while (nudt--) {
-
- if (udt->align) {
- /* destroy the USB DMA tag */
- usb2_dma_tag_destroy(udt);
- udt->align = 0;
- }
- udt++;
- }
-
- if (udpt->utag_max) {
-#ifdef __FreeBSD__
- /* destroy the condition variable */
- usb2_cv_destroy(udpt->cv);
-#endif
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bdma_work_loop
- *
- * This function handles loading of virtual buffers into DMA and is
- * only called when "dma_refcount" is zero.
- *------------------------------------------------------------------------*/
-void
-usb2_bdma_work_loop(struct usb2_xfer_queue *pq)
-{
- struct usb2_xfer_root *info;
- struct usb2_xfer *xfer;
- uint32_t nframes;
-
- xfer = pq->curr;
- info = xfer->xroot;
-
- mtx_assert(info->xfer_mtx, MA_OWNED);
-
- if (xfer->error) {
- /* some error happened */
- USB_BUS_LOCK(info->bus);
- usb2_transfer_done(xfer, 0);
- USB_BUS_UNLOCK(info->bus);
- return;
- }
- if (!xfer->flags_int.bdma_setup) {
- struct usb2_page *pg;
- uint32_t frlength_0;
- uint8_t isread;
-
- xfer->flags_int.bdma_setup = 1;
-
- /* reset BUS-DMA load state */
-
- info->dma_error = 0;
-
- if (xfer->flags_int.isochronous_xfr) {
- /* only one frame buffer */
- nframes = 1;
- frlength_0 = xfer->sumlen;
- } else {
- /* can be multiple frame buffers */
- nframes = xfer->nframes;
- frlength_0 = xfer->frlengths[0];
- }
-
- /*
- * Set DMA direction first. This is needed to
- * select the correct cache invalidate and cache
- * flush operations.
- */
- isread = USB_GET_DATA_ISREAD(xfer);
- pg = xfer->dma_page_ptr;
-
- if (xfer->flags_int.control_xfr &&
- xfer->flags_int.control_hdr) {
- /* special case */
- if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
- /* The device controller writes to memory */
- xfer->frbuffers[0].isread = 1;
- } else {
- /* The host controller reads from memory */
- xfer->frbuffers[0].isread = 0;
- }
- } else {
- /* default case */
- xfer->frbuffers[0].isread = isread;
- }
-
- /*
- * Setup the "page_start" pointer which points to an array of
- * USB pages where information about the physical address of a
- * page will be stored. Also initialise the "isread" field of
- * the USB page caches.
- */
- xfer->frbuffers[0].page_start = pg;
-
- info->dma_nframes = nframes;
- info->dma_currframe = 0;
- info->dma_frlength_0 = frlength_0;
-
- pg += (frlength_0 / USB_PAGE_SIZE);
- pg += 2;
-
- while (--nframes > 0) {
- xfer->frbuffers[nframes].isread = isread;
- xfer->frbuffers[nframes].page_start = pg;
-
- pg += (xfer->frlengths[nframes] / USB_PAGE_SIZE);
- pg += 2;
- }
-
- }
- if (info->dma_error) {
- USB_BUS_LOCK(info->bus);
- usb2_transfer_done(xfer, USB_ERR_DMA_LOAD_FAILED);
- USB_BUS_UNLOCK(info->bus);
- return;
- }
- if (info->dma_currframe != info->dma_nframes) {
-
- if (info->dma_currframe == 0) {
- /* special case */
- usb2_pc_load_mem(xfer->frbuffers,
- info->dma_frlength_0, 0);
- } else {
- /* default case */
- nframes = info->dma_currframe;
- usb2_pc_load_mem(xfer->frbuffers + nframes,
- xfer->frlengths[nframes], 0);
- }
-
- /* advance frame index */
- info->dma_currframe++;
-
- return;
- }
- /* go ahead */
- usb2_bdma_pre_sync(xfer);
-
- /* start loading next USB transfer, if any */
- usb2_command_wrapper(pq, NULL);
-
- /* finally start the hardware */
- usb2_pipe_enter(xfer);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bdma_done_event
- *
- * This function is called when the BUS-DMA has loaded virtual memory
- * into DMA, if any.
- *------------------------------------------------------------------------*/
-void
-usb2_bdma_done_event(struct usb2_dma_parent_tag *udpt)
-{
- struct usb2_xfer_root *info;
-
- info = udpt->info;
-
- mtx_assert(info->xfer_mtx, MA_OWNED);
-
- /* copy error */
- info->dma_error = udpt->dma_error;
-
- /* enter workloop again */
- usb2_command_wrapper(&info->dma_q,
- info->dma_q.curr);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bdma_pre_sync
- *
- * This function handles DMA synchronisation that must be done before
- * an USB transfer is started.
- *------------------------------------------------------------------------*/
-void
-usb2_bdma_pre_sync(struct usb2_xfer *xfer)
-{
- struct usb2_page_cache *pc;
- uint32_t nframes;
-
- if (xfer->flags_int.isochronous_xfr) {
- /* only one frame buffer */
- nframes = 1;
- } else {
- /* can be multiple frame buffers */
- nframes = xfer->nframes;
- }
-
- pc = xfer->frbuffers;
-
- while (nframes--) {
-
- if (pc->isread) {
- usb2_pc_cpu_invalidate(pc);
- } else {
- usb2_pc_cpu_flush(pc);
- }
- pc++;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bdma_post_sync
- *
- * This function handles DMA synchronisation that must be done after
- * an USB transfer is complete.
- *------------------------------------------------------------------------*/
-void
-usb2_bdma_post_sync(struct usb2_xfer *xfer)
-{
- struct usb2_page_cache *pc;
- uint32_t nframes;
-
- if (xfer->flags_int.isochronous_xfr) {
- /* only one frame buffer */
- nframes = 1;
- } else {
- /* can be multiple frame buffers */
- nframes = xfer->nframes;
- }
-
- pc = xfer->frbuffers;
-
- while (nframes--) {
- if (pc->isread) {
- usb2_pc_cpu_invalidate(pc);
- }
- pc++;
- }
-}
diff --git a/sys/dev/usb2/core/usb2_busdma.h b/sys/dev/usb2/core/usb2_busdma.h
deleted file mode 100644
index 3c1600b..0000000
--- a/sys/dev/usb2/core/usb2_busdma.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_BUSDMA_H_
-#define _USB2_BUSDMA_H_
-
-#include <sys/uio.h>
-#include <sys/mbuf.h>
-
-#include <machine/bus.h>
-
-/* defines */
-
-#define USB_PAGE_SIZE PAGE_SIZE /* use system PAGE_SIZE */
-
-#ifdef __FreeBSD__
-#if (__FreeBSD_version >= 700020)
-#define USB_GET_DMA_TAG(dev) bus_get_dma_tag(dev)
-#else
-#define USB_GET_DMA_TAG(dev) NULL /* XXX */
-#endif
-#endif
-
-/* structure prototypes */
-
-struct usb2_xfer_root;
-struct usb2_dma_parent_tag;
-
-/*
- * The following typedef defines the USB DMA load done callback.
- */
-
-typedef void (usb2_dma_callback_t)(struct usb2_dma_parent_tag *udpt);
-
-/*
- * The following structure defines physical and non kernel virtual
- * address of a memory page having size USB_PAGE_SIZE.
- */
-struct usb2_page {
- bus_size_t physaddr;
- void *buffer; /* non Kernel Virtual Address */
-};
-
-/*
- * The following structure is used when needing the kernel virtual
- * pointer and the physical address belonging to an offset in an USB
- * page cache.
- */
-struct usb2_page_search {
- void *buffer;
- bus_size_t physaddr;
- uint32_t length;
-};
-
-/*
- * The following structure is used to keep information about a DMA
- * memory allocation.
- */
-struct usb2_page_cache {
-
-#ifdef __FreeBSD__
- bus_dma_tag_t tag;
- bus_dmamap_t map;
-#endif
-#ifdef __NetBSD__
- bus_dma_tag_t tag;
- bus_dmamap_t map;
- bus_dma_segment_t *p_seg;
-#endif
- struct usb2_page *page_start;
- struct usb2_dma_parent_tag *tag_parent; /* always set */
- void *buffer; /* virtual buffer pointer */
-#ifdef __NetBSD__
- int n_seg;
-#endif
- uint32_t page_offset_buf;
- uint32_t page_offset_end;
- uint8_t isread:1; /* set if we are currently reading
- * from the memory. Else write. */
- uint8_t ismultiseg:1; /* set if we can have multiple
- * segments */
-};
-
-/*
- * The following structure describes the parent USB DMA tag.
- */
-struct usb2_dma_parent_tag {
-#ifdef __FreeBSD__
- struct cv cv[1]; /* internal condition variable */
-#endif
-
- bus_dma_tag_t tag; /* always set */
-
- struct mtx *mtx; /* private mutex, always set */
- struct usb2_xfer_root *info; /* used by the callback function */
- usb2_dma_callback_t *func; /* load complete callback function */
- struct usb2_dma_tag *utag_first;/* pointer to first USB DMA tag */
-
- uint8_t dma_error; /* set if DMA load operation failed */
- uint8_t dma_bits; /* number of DMA address lines */
- uint8_t utag_max; /* number of USB DMA tags */
-};
-
-/*
- * The following structure describes an USB DMA tag.
- */
-struct usb2_dma_tag {
-#ifdef __NetBSD__
- bus_dma_segment_t *p_seg;
-#endif
- struct usb2_dma_parent_tag *tag_parent;
- bus_dma_tag_t tag;
-
- uint32_t align;
- uint32_t size;
-#ifdef __NetBSD__
- uint32_t n_seg;
-#endif
-};
-
-/* function prototypes */
-
-int usb2_uiomove(struct usb2_page_cache *pc, struct uio *uio,
- uint32_t pc_offset, uint32_t len);
-struct usb2_dma_tag *usb2_dma_tag_find(struct usb2_dma_parent_tag *udpt,
- uint32_t size, uint32_t align);
-uint8_t usb2_pc_alloc_mem(struct usb2_page_cache *pc, struct usb2_page *pg,
- uint32_t size, uint32_t align);
-uint8_t usb2_pc_dmamap_create(struct usb2_page_cache *pc, uint32_t size);
-uint8_t usb2_pc_load_mem(struct usb2_page_cache *pc, uint32_t size,
- uint8_t sync);
-void usb2_bdma_done_event(struct usb2_dma_parent_tag *udpt);
-void usb2_bdma_post_sync(struct usb2_xfer *xfer);
-void usb2_bdma_pre_sync(struct usb2_xfer *xfer);
-void usb2_bdma_work_loop(struct usb2_xfer_queue *pq);
-void usb2_bzero(struct usb2_page_cache *cache, uint32_t offset,
- uint32_t len);
-void usb2_copy_in(struct usb2_page_cache *cache, uint32_t offset,
- const void *ptr, uint32_t len);
-int usb2_copy_in_user(struct usb2_page_cache *cache, uint32_t offset,
- const void *ptr, uint32_t len);
-void usb2_copy_out(struct usb2_page_cache *cache, uint32_t offset,
- void *ptr, uint32_t len);
-int usb2_copy_out_user(struct usb2_page_cache *cache, uint32_t offset,
- void *ptr, uint32_t len);
-void usb2_dma_tag_setup(struct usb2_dma_parent_tag *udpt,
- struct usb2_dma_tag *udt, bus_dma_tag_t dmat, struct mtx *mtx,
- usb2_dma_callback_t *func, struct usb2_xfer_root *info,
- uint8_t ndmabits, uint8_t nudt);
-void usb2_dma_tag_unsetup(struct usb2_dma_parent_tag *udpt);
-void usb2_get_page(struct usb2_page_cache *pc, uint32_t offset,
- struct usb2_page_search *res);
-void usb2_m_copy_in(struct usb2_page_cache *cache, uint32_t dst_offset,
- struct mbuf *m, uint32_t src_offset, uint32_t src_len);
-void usb2_pc_cpu_flush(struct usb2_page_cache *pc);
-void usb2_pc_cpu_invalidate(struct usb2_page_cache *pc);
-void usb2_pc_dmamap_destroy(struct usb2_page_cache *pc);
-void usb2_pc_free_mem(struct usb2_page_cache *pc);
-
-#endif /* _USB2_BUSDMA_H_ */
diff --git a/sys/dev/usb2/core/usb2_compat_linux.c b/sys/dev/usb2/core/usb2_compat_linux.c
deleted file mode 100644
index 4f52ea3..0000000
--- a/sys/dev/usb2/core/usb2_compat_linux.c
+++ /dev/null
@@ -1,1653 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2007 Luigi Rizzo - Universita` di Pisa. All rights reserved.
- * Copyright (c) 2007 Hans Petter Selasky. 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 <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_compat_linux.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_parse.h>
-#include <dev/usb2/core/usb2_hub.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_debug.h>
-
-struct usb_linux_softc {
- LIST_ENTRY(usb_linux_softc) sc_attached_list;
-
- device_t sc_fbsd_dev;
- struct usb2_device *sc_fbsd_udev;
- struct usb_interface *sc_ui;
- struct usb_driver *sc_udrv;
-};
-
-/* prototypes */
-static device_probe_t usb_linux_probe;
-static device_attach_t usb_linux_attach;
-static device_detach_t usb_linux_detach;
-static device_suspend_t usb_linux_suspend;
-static device_resume_t usb_linux_resume;
-static device_shutdown_t usb_linux_shutdown;
-
-static usb2_callback_t usb_linux_isoc_callback;
-static usb2_callback_t usb_linux_non_isoc_callback;
-
-static usb_complete_t usb_linux_wait_complete;
-
-static uint16_t usb_max_isoc_frames(struct usb_device *);
-static int usb_start_wait_urb(struct urb *, uint32_t, uint16_t *);
-static const struct usb_device_id *usb_linux_lookup_id(
- const struct usb_device_id *, struct usb2_attach_arg *);
-static struct usb_driver *usb_linux_get_usb_driver(struct usb_linux_softc *);
-static struct usb_device *usb_linux_create_usb_device(struct usb2_device *,
- device_t);
-static void usb_linux_cleanup_interface(struct usb_device *,
- struct usb_interface *);
-static void usb_linux_complete(struct usb2_xfer *);
-static int usb_unlink_urb_sub(struct urb *, uint8_t);
-
-/*------------------------------------------------------------------------*
- * FreeBSD USB interface
- *------------------------------------------------------------------------*/
-
-static LIST_HEAD(, usb_linux_softc) usb_linux_attached_list;
-static LIST_HEAD(, usb_driver) usb_linux_driver_list;
-
-static device_method_t usb_linux_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, usb_linux_probe),
- DEVMETHOD(device_attach, usb_linux_attach),
- DEVMETHOD(device_detach, usb_linux_detach),
- DEVMETHOD(device_suspend, usb_linux_suspend),
- DEVMETHOD(device_resume, usb_linux_resume),
- DEVMETHOD(device_shutdown, usb_linux_shutdown),
-
- {0, 0}
-};
-
-static driver_t usb_linux_driver = {
- .name = "usb_linux",
- .methods = usb_linux_methods,
- .size = sizeof(struct usb_linux_softc),
-};
-
-static devclass_t usb_linux_devclass;
-
-DRIVER_MODULE(usb_linux, ushub, usb_linux_driver, usb_linux_devclass, NULL, 0);
-
-/*------------------------------------------------------------------------*
- * usb_linux_lookup_id
- *
- * This functions takes an array of "struct usb_device_id" and tries
- * to match the entries with the information in "struct usb2_attach_arg".
- * If it finds a match the matching entry will be returned.
- * Else "NULL" will be returned.
- *------------------------------------------------------------------------*/
-static const struct usb_device_id *
-usb_linux_lookup_id(const struct usb_device_id *id, struct usb2_attach_arg *uaa)
-{
- if (id == NULL) {
- goto done;
- }
- /*
- * Keep on matching array entries until we find one with
- * "match_flags" equal to zero, which indicates the end of the
- * array:
- */
- for (; id->match_flags; id++) {
-
- if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
- (id->idVendor != uaa->info.idVendor)) {
- continue;
- }
- if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
- (id->idProduct != uaa->info.idProduct)) {
- continue;
- }
- if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
- (id->bcdDevice_lo > uaa->info.bcdDevice)) {
- continue;
- }
- if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
- (id->bcdDevice_hi < uaa->info.bcdDevice)) {
- continue;
- }
- if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
- (id->bDeviceClass != uaa->info.bDeviceClass)) {
- continue;
- }
- if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
- (id->bDeviceSubClass != uaa->info.bDeviceSubClass)) {
- continue;
- }
- if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
- (id->bDeviceProtocol != uaa->info.bDeviceProtocol)) {
- continue;
- }
- if ((uaa->info.bDeviceClass == 0xFF) &&
- !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
- (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS |
- USB_DEVICE_ID_MATCH_INT_PROTOCOL))) {
- continue;
- }
- if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
- (id->bInterfaceClass != uaa->info.bInterfaceClass)) {
- continue;
- }
- if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
- (id->bInterfaceSubClass != uaa->info.bInterfaceSubClass)) {
- continue;
- }
- if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
- (id->bInterfaceProtocol != uaa->info.bInterfaceProtocol)) {
- continue;
- }
- /* we found a match! */
- return (id);
- }
-
-done:
- return (NULL);
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_probe
- *
- * This function is the FreeBSD probe callback. It is called from the
- * FreeBSD USB stack through the "device_probe_and_attach()" function.
- *------------------------------------------------------------------------*/
-static int
-usb_linux_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct usb_driver *udrv;
- int err = ENXIO;
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- mtx_lock(&Giant);
- LIST_FOREACH(udrv, &usb_linux_driver_list, linux_driver_list) {
- if (usb_linux_lookup_id(udrv->id_table, uaa)) {
- err = 0;
- break;
- }
- }
- mtx_unlock(&Giant);
-
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_get_usb_driver
- *
- * This function returns the pointer to the "struct usb_driver" where
- * the Linux USB device driver "struct usb_device_id" match was found.
- * We apply a lock before reading out the pointer to avoid races.
- *------------------------------------------------------------------------*/
-static struct usb_driver *
-usb_linux_get_usb_driver(struct usb_linux_softc *sc)
-{
- struct usb_driver *udrv;
-
- mtx_lock(&Giant);
- udrv = sc->sc_udrv;
- mtx_unlock(&Giant);
- return (udrv);
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_attach
- *
- * This function is the FreeBSD attach callback. It is called from the
- * FreeBSD USB stack through the "device_probe_and_attach()" function.
- * This function is called when "usb_linux_probe()" returns zero.
- *------------------------------------------------------------------------*/
-static int
-usb_linux_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct usb_linux_softc *sc = device_get_softc(dev);
- struct usb_driver *udrv;
- struct usb_device *p_dev;
- const struct usb_device_id *id = NULL;
-
- mtx_lock(&Giant);
- LIST_FOREACH(udrv, &usb_linux_driver_list, linux_driver_list) {
- id = usb_linux_lookup_id(udrv->id_table, uaa);
- if (id)
- break;
- }
- mtx_unlock(&Giant);
-
- if (id == NULL) {
- return (ENXIO);
- }
- /*
- * Save some memory and only create the Linux compat structure when
- * needed:
- */
- p_dev = uaa->device->linux_dev;
- if (p_dev == NULL) {
- p_dev = usb_linux_create_usb_device(uaa->device, dev);
- if (p_dev == NULL) {
- return (ENOMEM);
- }
- uaa->device->linux_dev = p_dev;
- }
- device_set_usb2_desc(dev);
-
- sc->sc_fbsd_udev = uaa->device;
- sc->sc_fbsd_dev = dev;
- sc->sc_udrv = udrv;
- sc->sc_ui = usb_ifnum_to_if(p_dev, uaa->info.bIfaceNum);
- if (sc->sc_ui == NULL) {
- return (EINVAL);
- }
- if (udrv->probe) {
- if ((udrv->probe) (sc->sc_ui, id)) {
- return (ENXIO);
- }
- }
- mtx_lock(&Giant);
- LIST_INSERT_HEAD(&usb_linux_attached_list, sc, sc_attached_list);
- mtx_unlock(&Giant);
-
- /* success */
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_detach
- *
- * This function is the FreeBSD detach callback. It is called from the
- * FreeBSD USB stack through the "device_detach()" function.
- *------------------------------------------------------------------------*/
-static int
-usb_linux_detach(device_t dev)
-{
- struct usb_linux_softc *sc = device_get_softc(dev);
- struct usb_driver *udrv = NULL;
-
- mtx_lock(&Giant);
- if (sc->sc_attached_list.le_prev) {
- LIST_REMOVE(sc, sc_attached_list);
- sc->sc_attached_list.le_prev = NULL;
- udrv = sc->sc_udrv;
- sc->sc_udrv = NULL;
- }
- mtx_unlock(&Giant);
-
- if (udrv && udrv->disconnect) {
- (udrv->disconnect) (sc->sc_ui);
- }
- /*
- * Make sure that we free all FreeBSD USB transfers belonging to
- * this Linux "usb_interface", hence they will most likely not be
- * needed any more.
- */
- usb_linux_cleanup_interface(sc->sc_fbsd_udev->linux_dev, sc->sc_ui);
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_suspend
- *
- * This function is the FreeBSD suspend callback. Usually it does nothing.
- *------------------------------------------------------------------------*/
-static int
-usb_linux_suspend(device_t dev)
-{
- struct usb_linux_softc *sc = device_get_softc(dev);
- struct usb_driver *udrv = usb_linux_get_usb_driver(sc);
- int err;
-
- if (udrv && udrv->suspend) {
- err = (udrv->suspend) (sc->sc_ui, 0);
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_resume
- *
- * This function is the FreeBSD resume callback. Usually it does nothing.
- *------------------------------------------------------------------------*/
-static int
-usb_linux_resume(device_t dev)
-{
- struct usb_linux_softc *sc = device_get_softc(dev);
- struct usb_driver *udrv = usb_linux_get_usb_driver(sc);
- int err;
-
- if (udrv && udrv->resume) {
- err = (udrv->resume) (sc->sc_ui);
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_shutdown
- *
- * This function is the FreeBSD shutdown callback. Usually it does nothing.
- *------------------------------------------------------------------------*/
-static int
-usb_linux_shutdown(device_t dev)
-{
- struct usb_linux_softc *sc = device_get_softc(dev);
- struct usb_driver *udrv = usb_linux_get_usb_driver(sc);
-
- if (udrv && udrv->shutdown) {
- (udrv->shutdown) (sc->sc_ui);
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * Linux emulation layer
- *------------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------------*
- * usb_max_isoc_frames
- *
- * The following function returns the maximum number of isochronous
- * frames that we support per URB. It is not part of the Linux USB API.
- *------------------------------------------------------------------------*/
-static uint16_t
-usb_max_isoc_frames(struct usb_device *dev)
-{
- ; /* indent fix */
- switch (usb2_get_speed(dev->bsd_udev)) {
- case USB_SPEED_LOW:
- case USB_SPEED_FULL:
- return (USB_MAX_FULL_SPEED_ISOC_FRAMES);
- default:
- return (USB_MAX_HIGH_SPEED_ISOC_FRAMES);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb_submit_urb
- *
- * This function is used to queue an URB after that it has been
- * initialized. If it returns non-zero, it means that the URB was not
- * queued.
- *------------------------------------------------------------------------*/
-int
-usb_submit_urb(struct urb *urb, uint16_t mem_flags)
-{
- struct usb_host_endpoint *uhe;
-
- if (urb == NULL) {
- return (-EINVAL);
- }
- mtx_assert(&Giant, MA_OWNED);
-
- if (urb->pipe == NULL) {
- return (-EINVAL);
- }
- uhe = urb->pipe;
-
- /*
- * Check that we have got a FreeBSD USB transfer that will dequeue
- * the URB structure and do the real transfer. If there are no USB
- * transfers, then we return an error.
- */
- if (uhe->bsd_xfer[0] ||
- uhe->bsd_xfer[1]) {
- /* we are ready! */
-
- TAILQ_INSERT_HEAD(&uhe->bsd_urb_list, urb, bsd_urb_list);
-
- urb->status = -EINPROGRESS;
-
- usb2_transfer_start(uhe->bsd_xfer[0]);
- usb2_transfer_start(uhe->bsd_xfer[1]);
- } else {
- /* no pipes have been setup yet! */
- urb->status = -EINVAL;
- return (-EINVAL);
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb_unlink_urb
- *
- * This function is used to stop an URB after that it is been
- * submitted, but before the "complete" callback has been called. On
- *------------------------------------------------------------------------*/
-int
-usb_unlink_urb(struct urb *urb)
-{
- return (usb_unlink_urb_sub(urb, 0));
-}
-
-static void
-usb_unlink_bsd(struct usb2_xfer *xfer,
- struct urb *urb, uint8_t drain)
-{
- if (xfer &&
- usb2_transfer_pending(xfer) &&
- (xfer->priv_fifo == (void *)urb)) {
- if (drain) {
- mtx_unlock(&Giant);
- usb2_transfer_drain(xfer);
- mtx_lock(&Giant);
- } else {
- usb2_transfer_stop(xfer);
- }
- usb2_transfer_start(xfer);
- }
-}
-
-static int
-usb_unlink_urb_sub(struct urb *urb, uint8_t drain)
-{
- struct usb_host_endpoint *uhe;
- uint16_t x;
-
- if (urb == NULL) {
- return (-EINVAL);
- }
- mtx_assert(&Giant, MA_OWNED);
-
- if (urb->pipe == NULL) {
- return (-EINVAL);
- }
- uhe = urb->pipe;
-
- if (urb->bsd_urb_list.tqe_prev) {
-
- /* not started yet, just remove it from the queue */
- TAILQ_REMOVE(&uhe->bsd_urb_list, urb, bsd_urb_list);
- urb->bsd_urb_list.tqe_prev = NULL;
- urb->status = -ECONNRESET;
- urb->actual_length = 0;
-
- for (x = 0; x < urb->number_of_packets; x++) {
- urb->iso_frame_desc[x].actual_length = 0;
- }
-
- if (urb->complete) {
- (urb->complete) (urb);
- }
- } else {
-
- /*
- * If the URB is not on the URB list, then check if one of
- * the FreeBSD USB transfer are processing the current URB.
- * If so, re-start that transfer, which will lead to the
- * termination of that URB:
- */
- usb_unlink_bsd(uhe->bsd_xfer[0], urb, drain);
- usb_unlink_bsd(uhe->bsd_xfer[1], urb, drain);
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb_clear_halt
- *
- * This function must always be used to clear the stall. Stall is when
- * an USB endpoint returns a stall message to the USB host controller.
- * Until the stall is cleared, no data can be transferred.
- *------------------------------------------------------------------------*/
-int
-usb_clear_halt(struct usb_device *dev, struct usb_host_endpoint *uhe)
-{
- struct usb2_config cfg[1];
- struct usb2_pipe *pipe;
- uint8_t type;
- uint8_t addr;
-
- if (uhe == NULL)
- return (-EINVAL);
-
- type = uhe->desc.bmAttributes & UE_XFERTYPE;
- addr = uhe->desc.bEndpointAddress;
-
- bzero(cfg, sizeof(cfg));
-
- cfg[0].type = type;
- cfg[0].endpoint = addr & UE_ADDR;
- cfg[0].direction = addr & (UE_DIR_OUT | UE_DIR_IN);
-
- pipe = usb2_get_pipe(dev->bsd_udev, uhe->bsd_iface_index, cfg);
- if (pipe == NULL)
- return (-EINVAL);
-
- usb2_clear_data_toggle(dev->bsd_udev, pipe);
-
- return (usb_control_msg(dev, &dev->ep0,
- UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT,
- UF_ENDPOINT_HALT, addr, NULL, 0, 1000));
-}
-
-/*------------------------------------------------------------------------*
- * usb_start_wait_urb
- *
- * This is an internal function that is used to perform synchronous
- * Linux USB transfers.
- *------------------------------------------------------------------------*/
-static int
-usb_start_wait_urb(struct urb *urb, uint32_t timeout, uint16_t *p_actlen)
-{
- int err;
-
- /* you must have a timeout! */
- if (timeout == 0) {
- timeout = 1;
- }
- urb->complete = &usb_linux_wait_complete;
- urb->timeout = timeout;
- urb->transfer_flags |= URB_WAIT_WAKEUP;
- urb->transfer_flags &= ~URB_IS_SLEEPING;
-
- err = usb_submit_urb(urb, 0);
- if (err)
- goto done;
-
- /*
- * the URB might have completed before we get here, so check that by
- * using some flags!
- */
- while (urb->transfer_flags & URB_WAIT_WAKEUP) {
- urb->transfer_flags |= URB_IS_SLEEPING;
- usb2_cv_wait(&urb->cv_wait, &Giant);
- urb->transfer_flags &= ~URB_IS_SLEEPING;
- }
-
- err = urb->status;
-
-done:
- if (err) {
- *p_actlen = 0;
- } else {
- *p_actlen = urb->actual_length;
- }
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb_control_msg
- *
- * The following function performs a control transfer sequence one any
- * control, bulk or interrupt endpoint, specified by "uhe". A control
- * transfer means that you transfer an 8-byte header first followed by
- * a data-phase as indicated by the 8-byte header. The "timeout" is
- * given in milliseconds.
- *
- * Return values:
- * 0: Success
- * < 0: Failure
- * > 0: Acutal length
- *------------------------------------------------------------------------*/
-int
-usb_control_msg(struct usb_device *dev, struct usb_host_endpoint *uhe,
- uint8_t request, uint8_t requesttype,
- uint16_t value, uint16_t index, void *data,
- uint16_t size, uint32_t timeout)
-{
- struct usb2_device_request req;
- struct urb *urb;
- int err;
- uint16_t actlen;
- uint8_t type;
- uint8_t addr;
-
- req.bmRequestType = requesttype;
- req.bRequest = request;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, size);
-
- if (uhe == NULL) {
- return (-EINVAL);
- }
- type = (uhe->desc.bmAttributes & UE_XFERTYPE);
- addr = (uhe->desc.bEndpointAddress & UE_ADDR);
-
- if (type != UE_CONTROL) {
- return (-EINVAL);
- }
- if (addr == 0) {
- /*
- * The FreeBSD USB stack supports standard control
- * transfers on control endpoint zero:
- */
- err = usb2_do_request_flags(dev->bsd_udev,
- &Giant, &req, data, USB_SHORT_XFER_OK,
- &actlen, timeout);
- if (err) {
- err = -EPIPE;
- } else {
- err = actlen;
- }
- return (err);
- }
- if (dev->bsd_udev->flags.usb2_mode != USB_MODE_HOST) {
- /* not supported */
- return (-EINVAL);
- }
- err = usb_setup_endpoint(dev, uhe, 1 /* dummy */ );
-
- /*
- * NOTE: we need to allocate real memory here so that we don't
- * transfer data to/from the stack!
- *
- * 0xFFFF is a FreeBSD specific magic value.
- */
- urb = usb_alloc_urb(0xFFFF, size);
- if (urb == NULL)
- return (-ENOMEM);
-
- urb->dev = dev;
- urb->pipe = uhe;
-
- bcopy(&req, urb->setup_packet, sizeof(req));
-
- if (size && (!(req.bmRequestType & UT_READ))) {
- /* move the data to a real buffer */
- bcopy(data, USB_ADD_BYTES(urb->setup_packet,
- sizeof(req)), size);
- }
- err = usb_start_wait_urb(urb, timeout, &actlen);
-
- if (req.bmRequestType & UT_READ) {
- if (actlen) {
- bcopy(USB_ADD_BYTES(urb->setup_packet,
- sizeof(req)), data, actlen);
- }
- }
- usb_free_urb(urb);
-
- if (err == 0) {
- err = actlen;
- }
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb_set_interface
- *
- * The following function will select which alternate setting of an
- * USB interface you plan to use. By default alternate setting with
- * index zero is selected. Note that "iface_no" is not the interface
- * index, but rather the value of "bInterfaceNumber".
- *------------------------------------------------------------------------*/
-int
-usb_set_interface(struct usb_device *dev, uint8_t iface_no, uint8_t alt_index)
-{
- struct usb_interface *p_ui = usb_ifnum_to_if(dev, iface_no);
- int err;
-
- if (p_ui == NULL)
- return (-EINVAL);
- if (alt_index >= p_ui->num_altsetting)
- return (-EINVAL);
- usb_linux_cleanup_interface(dev, p_ui);
- err = -usb2_set_alt_interface_index(dev->bsd_udev,
- p_ui->bsd_iface_index, alt_index);
- if (err == 0) {
- p_ui->cur_altsetting = p_ui->altsetting + alt_index;
- }
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb_setup_endpoint
- *
- * The following function is an extension to the Linux USB API that
- * allows you to set a maximum buffer size for a given USB endpoint.
- * The maximum buffer size is per URB. If you don't call this function
- * to set a maximum buffer size, the endpoint will not be functional.
- * Note that for isochronous endpoints the maximum buffer size must be
- * a non-zero dummy, hence this function will base the maximum buffer
- * size on "wMaxPacketSize".
- *------------------------------------------------------------------------*/
-int
-usb_setup_endpoint(struct usb_device *dev,
- struct usb_host_endpoint *uhe, uint32_t bufsize)
-{
- struct usb2_config cfg[2];
- uint8_t type = uhe->desc.bmAttributes & UE_XFERTYPE;
- uint8_t addr = uhe->desc.bEndpointAddress;
-
- if (uhe->fbsd_buf_size == bufsize) {
- /* optimize */
- return (0);
- }
- usb2_transfer_unsetup(uhe->bsd_xfer, 2);
-
- uhe->fbsd_buf_size = bufsize;
-
- if (bufsize == 0) {
- return (0);
- }
- bzero(cfg, sizeof(cfg));
-
- if (type == UE_ISOCHRONOUS) {
-
- /*
- * Isochronous transfers are special in that they don't fit
- * into the BULK/INTR/CONTROL transfer model.
- */
-
- cfg[0].type = type;
- cfg[0].endpoint = addr & UE_ADDR;
- cfg[0].direction = addr & (UE_DIR_OUT | UE_DIR_IN);
- cfg[0].mh.callback = &usb_linux_isoc_callback;
- cfg[0].mh.bufsize = 0; /* use wMaxPacketSize */
- cfg[0].mh.frames = usb_max_isoc_frames(dev);
- cfg[0].mh.flags.proxy_buffer = 1;
-#if 0
- /*
- * The Linux USB API allows non back-to-back
- * isochronous frames which we do not support. If the
- * isochronous frames are not back-to-back we need to
- * do a copy, and then we need a buffer for
- * that. Enable this at your own risk.
- */
- cfg[0].mh.flags.ext_buffer = 1;
-#endif
- cfg[0].mh.flags.short_xfer_ok = 1;
-
- bcopy(cfg, cfg + 1, sizeof(*cfg));
-
- /* Allocate and setup two generic FreeBSD USB transfers */
-
- if (usb2_transfer_setup(dev->bsd_udev, &uhe->bsd_iface_index,
- uhe->bsd_xfer, cfg, 2, uhe, &Giant)) {
- return (-EINVAL);
- }
- } else {
- if (bufsize > (1 << 22)) {
- /* limit buffer size */
- bufsize = (1 << 22);
- }
- /* Allocate and setup one generic FreeBSD USB transfer */
-
- cfg[0].type = type;
- cfg[0].endpoint = addr & UE_ADDR;
- cfg[0].direction = addr & (UE_DIR_OUT | UE_DIR_IN);
- cfg[0].mh.callback = &usb_linux_non_isoc_callback;
- cfg[0].mh.bufsize = bufsize;
- cfg[0].mh.flags.ext_buffer = 1; /* enable zero-copy */
- cfg[0].mh.flags.proxy_buffer = 1;
- cfg[0].mh.flags.short_xfer_ok = 1;
-
- if (usb2_transfer_setup(dev->bsd_udev, &uhe->bsd_iface_index,
- uhe->bsd_xfer, cfg, 1, uhe, &Giant)) {
- return (-EINVAL);
- }
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_create_usb_device
- *
- * The following function is used to build up a per USB device
- * structure tree, that mimics the Linux one. The root structure
- * is returned by this function.
- *------------------------------------------------------------------------*/
-static struct usb_device *
-usb_linux_create_usb_device(struct usb2_device *udev, device_t dev)
-{
- struct usb2_config_descriptor *cd = usb2_get_config_descriptor(udev);
- struct usb2_descriptor *desc;
- struct usb2_interface_descriptor *id;
- struct usb2_endpoint_descriptor *ed;
- struct usb_device *p_ud = NULL;
- struct usb_interface *p_ui = NULL;
- struct usb_host_interface *p_uhi = NULL;
- struct usb_host_endpoint *p_uhe = NULL;
- uint32_t size;
- uint16_t niface_total;
- uint16_t nedesc;
- uint16_t iface_no_curr;
- uint16_t iface_index;
- uint8_t pass;
- uint8_t iface_no;
-
- /*
- * We do two passes. One pass for computing necessary memory size
- * and one pass to initialize all the allocated memory structures.
- */
- for (pass = 0; pass < 2; pass++) {
-
- iface_no_curr = 0 - 1;
- niface_total = 0;
- iface_index = 0;
- nedesc = 0;
- desc = NULL;
-
- /*
- * Iterate over all the USB descriptors. Use the USB config
- * descriptor pointer provided by the FreeBSD USB stack.
- */
- while ((desc = usb2_desc_foreach(cd, desc))) {
-
- /*
- * Build up a tree according to the descriptors we
- * find:
- */
- switch (desc->bDescriptorType) {
- case UDESC_DEVICE:
- break;
-
- case UDESC_ENDPOINT:
- ed = (void *)desc;
- if ((ed->bLength < sizeof(*ed)) ||
- (iface_index == 0))
- break;
- if (p_uhe) {
- bcopy(ed, &p_uhe->desc, sizeof(p_uhe->desc));
- p_uhe->bsd_iface_index = iface_index - 1;
- p_uhe++;
- }
- if (p_uhi) {
- (p_uhi - 1)->desc.bNumEndpoints++;
- }
- nedesc++;
- break;
-
- case UDESC_INTERFACE:
- id = (void *)desc;
- if (id->bLength < sizeof(*id))
- break;
- if (p_uhi) {
- bcopy(id, &p_uhi->desc, sizeof(p_uhi->desc));
- p_uhi->desc.bNumEndpoints = 0;
- p_uhi->endpoint = p_uhe;
- p_uhi->string = "";
- p_uhi->bsd_iface_index = iface_index;
- p_uhi++;
- }
- iface_no = id->bInterfaceNumber;
- niface_total++;
- if (iface_no_curr != iface_no) {
- if (p_ui) {
- p_ui->altsetting = p_uhi - 1;
- p_ui->cur_altsetting = p_uhi - 1;
- p_ui->num_altsetting = 1;
- p_ui->bsd_iface_index = iface_index;
- p_ui->linux_udev = p_ud;
- p_ui++;
- }
- iface_no_curr = iface_no;
- iface_index++;
- } else {
- if (p_ui) {
- (p_ui - 1)->num_altsetting++;
- }
- }
- break;
-
- default:
- break;
- }
- }
-
- if (pass == 0) {
-
- size = ((sizeof(*p_ud) * 1) +
- (sizeof(*p_uhe) * nedesc) +
- (sizeof(*p_ui) * iface_index) +
- (sizeof(*p_uhi) * niface_total));
-
- p_ud = malloc(size, M_USBDEV, M_WAITOK | M_ZERO);
- if (p_ud == NULL) {
- goto done;
- }
- p_uhe = (void *)(p_ud + 1);
- p_ui = (void *)(p_uhe + nedesc);
- p_uhi = (void *)(p_ui + iface_index);
-
- p_ud->product = "";
- p_ud->manufacturer = "";
- p_ud->serial = "";
- p_ud->speed = usb2_get_speed(udev);
- p_ud->bsd_udev = udev;
- p_ud->bsd_iface_start = p_ui;
- p_ud->bsd_iface_end = p_ui + iface_index;
- p_ud->bsd_endpoint_start = p_uhe;
- p_ud->bsd_endpoint_end = p_uhe + nedesc;
- p_ud->devnum = device_get_unit(dev);
- bcopy(&udev->ddesc, &p_ud->descriptor,
- sizeof(p_ud->descriptor));
- bcopy(udev->default_pipe.edesc, &p_ud->ep0.desc,
- sizeof(p_ud->ep0.desc));
- }
- }
-done:
- return (p_ud);
-}
-
-/*------------------------------------------------------------------------*
- * usb_alloc_urb
- *
- * This function should always be used when you allocate an URB for
- * use with the USB Linux stack. In case of an isochronous transfer
- * you must specifiy the maximum number of "iso_packets" which you
- * plan to transfer per URB. This function is always blocking, and
- * "mem_flags" are not regarded like on Linux.
- *------------------------------------------------------------------------*/
-struct urb *
-usb_alloc_urb(uint16_t iso_packets, uint16_t mem_flags)
-{
- struct urb *urb;
- uint32_t size;
-
- if (iso_packets == 0xFFFF) {
- /*
- * FreeBSD specific magic value to ask for control transfer
- * memory allocation:
- */
- size = sizeof(*urb) + sizeof(struct usb2_device_request) + mem_flags;
- } else {
- size = sizeof(*urb) + (iso_packets * sizeof(urb->iso_frame_desc[0]));
- }
-
- urb = malloc(size, M_USBDEV, M_WAITOK | M_ZERO);
- if (urb) {
-
- usb2_cv_init(&urb->cv_wait, "URBWAIT");
- if (iso_packets == 0xFFFF) {
- urb->setup_packet = (void *)(urb + 1);
- urb->transfer_buffer = (void *)(urb->setup_packet +
- sizeof(struct usb2_device_request));
- } else {
- urb->number_of_packets = iso_packets;
- }
- }
- return (urb);
-}
-
-/*------------------------------------------------------------------------*
- * usb_find_host_endpoint
- *
- * The following function will return the Linux USB host endpoint
- * structure that matches the given endpoint type and endpoint
- * value. If no match is found, NULL is returned. This function is not
- * part of the Linux USB API and is only used internally.
- *------------------------------------------------------------------------*/
-struct usb_host_endpoint *
-usb_find_host_endpoint(struct usb_device *dev, uint8_t type, uint8_t ep)
-{
- struct usb_host_endpoint *uhe;
- struct usb_host_endpoint *uhe_end;
- struct usb_host_interface *uhi;
- struct usb_interface *ui;
- uint8_t ea;
- uint8_t at;
- uint8_t mask;
-
- if (dev == NULL) {
- return (NULL);
- }
- if (type == UE_CONTROL) {
- mask = UE_ADDR;
- } else {
- mask = (UE_DIR_IN | UE_DIR_OUT | UE_ADDR);
- }
-
- ep &= mask;
-
- /*
- * Iterate over all the interfaces searching the selected alternate
- * setting only, and all belonging endpoints.
- */
- for (ui = dev->bsd_iface_start;
- ui != dev->bsd_iface_end;
- ui++) {
- uhi = ui->cur_altsetting;
- if (uhi) {
- uhe_end = uhi->endpoint + uhi->desc.bNumEndpoints;
- for (uhe = uhi->endpoint;
- uhe != uhe_end;
- uhe++) {
- ea = uhe->desc.bEndpointAddress;
- at = uhe->desc.bmAttributes;
-
- if (((ea & mask) == ep) &&
- ((at & UE_XFERTYPE) == type)) {
- return (uhe);
- }
- }
- }
- }
-
- if ((type == UE_CONTROL) && ((ep & UE_ADDR) == 0)) {
- return (&dev->ep0);
- }
- return (NULL);
-}
-
-/*------------------------------------------------------------------------*
- * usb_altnum_to_altsetting
- *
- * The following function returns a pointer to an alternate setting by
- * index given a "usb_interface" pointer. If the alternate setting by
- * index does not exist, NULL is returned. And alternate setting is a
- * variant of an interface, but usually with slightly different
- * characteristics.
- *------------------------------------------------------------------------*/
-struct usb_host_interface *
-usb_altnum_to_altsetting(const struct usb_interface *intf, uint8_t alt_index)
-{
- if (alt_index >= intf->num_altsetting) {
- return (NULL);
- }
- return (intf->altsetting + alt_index);
-}
-
-/*------------------------------------------------------------------------*
- * usb_ifnum_to_if
- *
- * The following function searches up an USB interface by
- * "bInterfaceNumber". If no match is found, NULL is returned.
- *------------------------------------------------------------------------*/
-struct usb_interface *
-usb_ifnum_to_if(struct usb_device *dev, uint8_t iface_no)
-{
- struct usb_interface *p_ui;
-
- for (p_ui = dev->bsd_iface_start;
- p_ui != dev->bsd_iface_end;
- p_ui++) {
- if ((p_ui->num_altsetting > 0) &&
- (p_ui->altsetting->desc.bInterfaceNumber == iface_no)) {
- return (p_ui);
- }
- }
- return (NULL);
-}
-
-/*------------------------------------------------------------------------*
- * usb_buffer_alloc
- *------------------------------------------------------------------------*/
-void *
-usb_buffer_alloc(struct usb_device *dev, uint32_t size, uint16_t mem_flags, uint8_t *dma_addr)
-{
- return (malloc(size, M_USBDEV, M_WAITOK | M_ZERO));
-}
-
-/*------------------------------------------------------------------------*
- * usb_get_intfdata
- *------------------------------------------------------------------------*/
-void *
-usb_get_intfdata(struct usb_interface *intf)
-{
- return (intf->bsd_priv_sc);
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_register
- *
- * The following function is used by the "USB_DRIVER_EXPORT()" macro,
- * and is used to register a Linux USB driver, so that its
- * "usb_device_id" structures gets searched a probe time. This
- * function is not part of the Linux USB API, and is for internal use
- * only.
- *------------------------------------------------------------------------*/
-void
-usb_linux_register(void *arg)
-{
- struct usb_driver *drv = arg;
-
- mtx_lock(&Giant);
- LIST_INSERT_HEAD(&usb_linux_driver_list, drv, linux_driver_list);
- mtx_unlock(&Giant);
-
- usb2_needs_explore_all();
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_deregister
- *
- * The following function is used by the "USB_DRIVER_EXPORT()" macro,
- * and is used to deregister a Linux USB driver. This function will
- * ensure that all driver instances belonging to the Linux USB device
- * driver in question, gets detached before the driver is
- * unloaded. This function is not part of the Linux USB API, and is
- * for internal use only.
- *------------------------------------------------------------------------*/
-void
-usb_linux_deregister(void *arg)
-{
- struct usb_driver *drv = arg;
- struct usb_linux_softc *sc;
-
-repeat:
- mtx_lock(&Giant);
- LIST_FOREACH(sc, &usb_linux_attached_list, sc_attached_list) {
- if (sc->sc_udrv == drv) {
- mtx_unlock(&Giant);
- device_detach(sc->sc_fbsd_dev);
- goto repeat;
- }
- }
- LIST_REMOVE(drv, linux_driver_list);
- mtx_unlock(&Giant);
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_free_device
- *
- * The following function is only used by the FreeBSD USB stack, to
- * cleanup and free memory after that a Linux USB device was attached.
- *------------------------------------------------------------------------*/
-void
-usb_linux_free_device(struct usb_device *dev)
-{
- struct usb_host_endpoint *uhe;
- struct usb_host_endpoint *uhe_end;
- int err;
-
- uhe = dev->bsd_endpoint_start;
- uhe_end = dev->bsd_endpoint_end;
- while (uhe != uhe_end) {
- err = usb_setup_endpoint(dev, uhe, 0);
- uhe++;
- }
- err = usb_setup_endpoint(dev, &dev->ep0, 0);
- free(dev, M_USBDEV);
-}
-
-/*------------------------------------------------------------------------*
- * usb_buffer_free
- *------------------------------------------------------------------------*/
-void
-usb_buffer_free(struct usb_device *dev, uint32_t size,
- void *addr, uint8_t dma_addr)
-{
- free(addr, M_USBDEV);
-}
-
-/*------------------------------------------------------------------------*
- * usb_free_urb
- *------------------------------------------------------------------------*/
-void
-usb_free_urb(struct urb *urb)
-{
- if (urb == NULL) {
- return;
- }
- /* make sure that the current URB is not active */
- usb_kill_urb(urb);
-
- /* destroy condition variable */
- usb2_cv_destroy(&urb->cv_wait);
-
- /* just free it */
- free(urb, M_USBDEV);
-}
-
-/*------------------------------------------------------------------------*
- * usb_init_urb
- *
- * The following function can be used to initialize a custom URB. It
- * is not recommended to use this function. Use "usb_alloc_urb()"
- * instead.
- *------------------------------------------------------------------------*/
-void
-usb_init_urb(struct urb *urb)
-{
- if (urb == NULL) {
- return;
- }
- bzero(urb, sizeof(*urb));
-}
-
-/*------------------------------------------------------------------------*
- * usb_kill_urb
- *------------------------------------------------------------------------*/
-void
-usb_kill_urb(struct urb *urb)
-{
- if (usb_unlink_urb_sub(urb, 1)) {
- /* ignore */
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb_set_intfdata
- *
- * The following function sets the per Linux USB interface private
- * data pointer. It is used by most Linux USB device drivers.
- *------------------------------------------------------------------------*/
-void
-usb_set_intfdata(struct usb_interface *intf, void *data)
-{
- intf->bsd_priv_sc = data;
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_cleanup_interface
- *
- * The following function will release all FreeBSD USB transfers
- * associated with a Linux USB interface. It is for internal use only.
- *------------------------------------------------------------------------*/
-static void
-usb_linux_cleanup_interface(struct usb_device *dev, struct usb_interface *iface)
-{
- struct usb_host_interface *uhi;
- struct usb_host_interface *uhi_end;
- struct usb_host_endpoint *uhe;
- struct usb_host_endpoint *uhe_end;
- int err;
-
- uhi = iface->altsetting;
- uhi_end = iface->altsetting + iface->num_altsetting;
- while (uhi != uhi_end) {
- uhe = uhi->endpoint;
- uhe_end = uhi->endpoint + uhi->desc.bNumEndpoints;
- while (uhe != uhe_end) {
- err = usb_setup_endpoint(dev, uhe, 0);
- uhe++;
- }
- uhi++;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_wait_complete
- *
- * The following function is used by "usb_start_wait_urb()" to wake it
- * up, when an USB transfer has finished.
- *------------------------------------------------------------------------*/
-static void
-usb_linux_wait_complete(struct urb *urb)
-{
- if (urb->transfer_flags & URB_IS_SLEEPING) {
- usb2_cv_signal(&urb->cv_wait);
- }
- urb->transfer_flags &= ~URB_WAIT_WAKEUP;
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_complete
- *------------------------------------------------------------------------*/
-static void
-usb_linux_complete(struct usb2_xfer *xfer)
-{
- struct urb *urb;
-
- urb = xfer->priv_fifo;
- xfer->priv_fifo = NULL;
- if (urb->complete) {
- (urb->complete) (urb);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_isoc_callback
- *
- * The following is the FreeBSD isochronous USB callback. Isochronous
- * frames are USB packets transferred 1000 or 8000 times per second,
- * depending on whether a full- or high- speed USB transfer is
- * used.
- *------------------------------------------------------------------------*/
-static void
-usb_linux_isoc_callback(struct usb2_xfer *xfer)
-{
- uint32_t max_frame = xfer->max_frame_size;
- uint32_t offset;
- uint16_t x;
- struct urb *urb = xfer->priv_fifo;
- struct usb_host_endpoint *uhe = xfer->priv_sc;
- struct usb_iso_packet_descriptor *uipd;
-
- DPRINTF("\n");
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (urb->bsd_isread) {
-
- /* copy in data with regard to the URB */
-
- offset = 0;
-
- for (x = 0; x < urb->number_of_packets; x++) {
- uipd = urb->iso_frame_desc + x;
- uipd->actual_length = xfer->frlengths[x];
- uipd->status = 0;
- if (!xfer->flags.ext_buffer) {
- usb2_copy_out(xfer->frbuffers, offset,
- USB_ADD_BYTES(urb->transfer_buffer,
- uipd->offset), uipd->actual_length);
- }
- offset += max_frame;
- }
- } else {
- for (x = 0; x < urb->number_of_packets; x++) {
- uipd = urb->iso_frame_desc + x;
- uipd->actual_length = xfer->frlengths[x];
- uipd->status = 0;
- }
- }
-
- urb->actual_length = xfer->actlen;
-
- /* check for short transfer */
- if (xfer->actlen < xfer->sumlen) {
- /* short transfer */
- if (urb->transfer_flags & URB_SHORT_NOT_OK) {
- urb->status = -EPIPE; /* XXX should be
- * EREMOTEIO */
- } else {
- urb->status = 0;
- }
- } else {
- /* success */
- urb->status = 0;
- }
-
- /* call callback */
- usb_linux_complete(xfer);
-
- case USB_ST_SETUP:
-tr_setup:
-
- if (xfer->priv_fifo == NULL) {
-
- /* get next transfer */
- urb = TAILQ_FIRST(&uhe->bsd_urb_list);
- if (urb == NULL) {
- /* nothing to do */
- return;
- }
- TAILQ_REMOVE(&uhe->bsd_urb_list, urb, bsd_urb_list);
- urb->bsd_urb_list.tqe_prev = NULL;
-
- x = xfer->max_frame_count;
- if (urb->number_of_packets > x) {
- /* XXX simply truncate the transfer */
- urb->number_of_packets = x;
- }
- } else {
- DPRINTF("Already got a transfer\n");
-
- /* already got a transfer (should not happen) */
- urb = xfer->priv_fifo;
- }
-
- urb->bsd_isread = (uhe->desc.bEndpointAddress & UE_DIR_IN) ? 1 : 0;
-
- if (!(urb->bsd_isread)) {
-
- /* copy out data with regard to the URB */
-
- offset = 0;
-
- for (x = 0; x < urb->number_of_packets; x++) {
- uipd = urb->iso_frame_desc + x;
- xfer->frlengths[x] = uipd->length;
- if (!xfer->flags.ext_buffer) {
- usb2_copy_in(xfer->frbuffers, offset,
- USB_ADD_BYTES(urb->transfer_buffer,
- uipd->offset), uipd->length);
- }
- offset += uipd->length;
- }
- } else {
-
- /*
- * compute the transfer length into the "offset"
- * variable
- */
-
- offset = urb->number_of_packets * max_frame;
-
- /* setup "frlengths" array */
-
- for (x = 0; x < urb->number_of_packets; x++) {
- uipd = urb->iso_frame_desc + x;
- xfer->frlengths[x] = max_frame;
- }
- }
-
- if (xfer->flags.ext_buffer) {
- /* set virtual address to load */
- usb2_set_frame_data(xfer,
- urb->transfer_buffer, 0);
- }
- xfer->priv_fifo = urb;
- xfer->flags.force_short_xfer = 0;
- xfer->timeout = urb->timeout;
- xfer->nframes = urb->number_of_packets;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- urb->status = -ECONNRESET;
- } else {
- urb->status = -EPIPE; /* stalled */
- }
-
- /* Set zero for "actual_length" */
- urb->actual_length = 0;
-
- /* Set zero for "actual_length" */
- for (x = 0; x < urb->number_of_packets; x++) {
- urb->iso_frame_desc[x].actual_length = 0;
- }
-
- /* call callback */
- usb_linux_complete(xfer);
-
- if (xfer->error == USB_ERR_CANCELLED) {
- /* we need to return in this case */
- return;
- }
- goto tr_setup;
-
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb_linux_non_isoc_callback
- *
- * The following is the FreeBSD BULK/INTERRUPT and CONTROL USB
- * callback. It dequeues Linux USB stack compatible URB's, transforms
- * the URB fields into a FreeBSD USB transfer, and defragments the USB
- * transfer as required. When the transfer is complete the "complete"
- * callback is called.
- *------------------------------------------------------------------------*/
-static void
-usb_linux_non_isoc_callback(struct usb2_xfer *xfer)
-{
- enum {
- REQ_SIZE = sizeof(struct usb2_device_request)
- };
- struct urb *urb = xfer->priv_fifo;
- struct usb_host_endpoint *uhe = xfer->priv_sc;
- uint8_t *ptr;
- uint32_t max_bulk = xfer->max_data_length;
- uint8_t data_frame = xfer->flags_int.control_xfr ? 1 : 0;
-
- DPRINTF("\n");
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (xfer->flags_int.control_xfr) {
-
- /* don't transfer the setup packet again: */
-
- xfer->frlengths[0] = 0;
- }
- if (urb->bsd_isread && (!xfer->flags.ext_buffer)) {
- /* copy in data with regard to the URB */
- usb2_copy_out(xfer->frbuffers + data_frame, 0,
- urb->bsd_data_ptr, xfer->frlengths[data_frame]);
- }
- urb->bsd_length_rem -= xfer->frlengths[data_frame];
- urb->bsd_data_ptr += xfer->frlengths[data_frame];
- urb->actual_length += xfer->frlengths[data_frame];
-
- /* check for short transfer */
- if (xfer->actlen < xfer->sumlen) {
- urb->bsd_length_rem = 0;
-
- /* short transfer */
- if (urb->transfer_flags & URB_SHORT_NOT_OK) {
- urb->status = -EPIPE;
- } else {
- urb->status = 0;
- }
- } else {
- /* check remainder */
- if (urb->bsd_length_rem > 0) {
- goto setup_bulk;
- }
- /* success */
- urb->status = 0;
- }
-
- /* call callback */
- usb_linux_complete(xfer);
-
- case USB_ST_SETUP:
-tr_setup:
- /* get next transfer */
- urb = TAILQ_FIRST(&uhe->bsd_urb_list);
- if (urb == NULL) {
- /* nothing to do */
- return;
- }
- TAILQ_REMOVE(&uhe->bsd_urb_list, urb, bsd_urb_list);
- urb->bsd_urb_list.tqe_prev = NULL;
-
- xfer->priv_fifo = urb;
- xfer->flags.force_short_xfer = 0;
- xfer->timeout = urb->timeout;
-
- if (xfer->flags_int.control_xfr) {
-
- /*
- * USB control transfers need special handling.
- * First copy in the header, then copy in data!
- */
- if (!xfer->flags.ext_buffer) {
- usb2_copy_in(xfer->frbuffers, 0,
- urb->setup_packet, REQ_SIZE);
- } else {
- /* set virtual address to load */
- usb2_set_frame_data(xfer,
- urb->setup_packet, 0);
- }
-
- xfer->frlengths[0] = REQ_SIZE;
-
- ptr = urb->setup_packet;
-
- /* setup data transfer direction and length */
- urb->bsd_isread = (ptr[0] & UT_READ) ? 1 : 0;
- urb->bsd_length_rem = ptr[6] | (ptr[7] << 8);
-
- } else {
-
- /* setup data transfer direction */
-
- urb->bsd_length_rem = urb->transfer_buffer_length;
- urb->bsd_isread = (uhe->desc.bEndpointAddress &
- UE_DIR_IN) ? 1 : 0;
- }
-
- urb->bsd_data_ptr = urb->transfer_buffer;
- urb->actual_length = 0;
-
-setup_bulk:
- if (max_bulk > urb->bsd_length_rem) {
- max_bulk = urb->bsd_length_rem;
- }
- /* check if we need to force a short transfer */
-
- if ((max_bulk == urb->bsd_length_rem) &&
- (urb->transfer_flags & URB_ZERO_PACKET) &&
- (!xfer->flags_int.control_xfr)) {
- xfer->flags.force_short_xfer = 1;
- }
- /* check if we need to copy in data */
-
- if (xfer->flags.ext_buffer) {
- /* set virtual address to load */
- usb2_set_frame_data(xfer, urb->bsd_data_ptr,
- data_frame);
- } else if (!urb->bsd_isread) {
- /* copy out data with regard to the URB */
- usb2_copy_in(xfer->frbuffers + data_frame, 0,
- urb->bsd_data_ptr, max_bulk);
- }
- xfer->frlengths[data_frame] = max_bulk;
- if (xfer->flags_int.control_xfr) {
- if (max_bulk > 0) {
- xfer->nframes = 2;
- } else {
- xfer->nframes = 1;
- }
- } else {
- xfer->nframes = 1;
- }
- usb2_start_hardware(xfer);
- return;
-
- default:
- if (xfer->error == USB_ERR_CANCELLED) {
- urb->status = -ECONNRESET;
- } else {
- urb->status = -EPIPE;
- }
-
- /* Set zero for "actual_length" */
- urb->actual_length = 0;
-
- /* call callback */
- usb_linux_complete(xfer);
-
- if (xfer->error == USB_ERR_CANCELLED) {
- /* we need to return in this case */
- return;
- }
- goto tr_setup;
- }
-}
diff --git a/sys/dev/usb2/core/usb2_compat_linux.h b/sys/dev/usb2/core/usb2_compat_linux.h
deleted file mode 100644
index 8ebb7e3..0000000
--- a/sys/dev/usb2/core/usb2_compat_linux.h
+++ /dev/null
@@ -1,472 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2007 Luigi Rizzo - Universita` di Pisa. All rights reserved.
- * Copyright (c) 2007 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB_COMPAT_LINUX_H
-#define _USB_COMPAT_LINUX_H
-
-struct usb_device;
-struct usb_interface;
-struct usb_driver;
-struct urb;
-
-typedef void *pm_message_t;
-typedef void (usb_complete_t)(struct urb *);
-
-#define USB_MAX_FULL_SPEED_ISOC_FRAMES (60 * 1)
-#define USB_MAX_HIGH_SPEED_ISOC_FRAMES (60 * 8)
-
-/*
- * Linux compatible USB device drivers put their device information
- * into the "usb_device_id" structure using the "USB_DEVICE()" macro.
- * The "MODULE_DEVICE_TABLE()" macro can be used to export this
- * information to userland.
- */
-struct usb_device_id {
- /* which fields to match against */
- uint16_t match_flags;
-#define USB_DEVICE_ID_MATCH_VENDOR 0x0001
-#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002
-#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004
-#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008
-#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010
-#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020
-#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040
-#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080
-#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
-#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
-
- /* Used for product specific matches; the BCD range is inclusive */
- uint16_t idVendor;
- uint16_t idProduct;
- uint16_t bcdDevice_lo;
- uint16_t bcdDevice_hi;
-
- /* Used for device class matches */
- uint8_t bDeviceClass;
- uint8_t bDeviceSubClass;
- uint8_t bDeviceProtocol;
-
- /* Used for interface class matches */
- uint8_t bInterfaceClass;
- uint8_t bInterfaceSubClass;
- uint8_t bInterfaceProtocol;
-
- /* Hook for driver specific information */
- unsigned long driver_info;
-};
-
-#define USB_DEVICE_ID_MATCH_DEVICE \
- (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
-
-#define USB_DEVICE(vend,prod) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), \
- .idProduct = (prod)
-
-/* The "usb_driver" structure holds the Linux USB device driver
- * callbacks, and a pointer to device ID's which this entry should
- * match against. Usually this entry is exposed to the USB emulation
- * layer using the "USB_DRIVER_EXPORT()" macro, which is defined
- * below.
- */
-struct usb_driver {
- const char *name;
-
- int (*probe) (struct usb_interface *intf,
- const struct usb_device_id *id);
-
- void (*disconnect) (struct usb_interface *intf);
-
- int (*ioctl) (struct usb_interface *intf, unsigned int code,
- void *buf);
-
- int (*suspend) (struct usb_interface *intf, pm_message_t message);
- int (*resume) (struct usb_interface *intf);
-
- const struct usb_device_id *id_table;
-
- void (*shutdown) (struct usb_interface *intf);
-
- LIST_ENTRY(usb_driver) linux_driver_list;
-};
-
-#define USB_DRIVER_EXPORT(id,p_usb_drv) \
- SYSINIT(id,SI_SUB_KLD,SI_ORDER_FIRST,usb_linux_register,p_usb_drv); \
- SYSUNINIT(id,SI_SUB_KLD,SI_ORDER_ANY,usb_linux_deregister,p_usb_drv)
-
-/*
- * The following structure is the same as "usb_device_descriptor_t"
- * except that 16-bit values are "uint16_t" and not an array of "uint8_t".
- * It is used by Linux USB device drivers.
- */
-struct usb_device_descriptor {
- uint8_t bLength;
- uint8_t bDescriptorType;
-
- uint16_t bcdUSB;
- uint8_t bDeviceClass;
- uint8_t bDeviceSubClass;
- uint8_t bDeviceProtocol;
- uint8_t bMaxPacketSize0;
- uint16_t idVendor;
- uint16_t idProduct;
- uint16_t bcdDevice;
- uint8_t iManufacturer;
- uint8_t iProduct;
- uint8_t iSerialNumber;
- uint8_t bNumConfigurations;
-} __packed;
-
-/*
- * The following structure is the same as
- * "usb_interface_descriptor_t". It is used by
- * Linux USB device drivers.
- */
-struct usb_interface_descriptor {
- uint8_t bLength;
- uint8_t bDescriptorType;
-
- uint8_t bInterfaceNumber;
- uint8_t bAlternateSetting;
- uint8_t bNumEndpoints;
- uint8_t bInterfaceClass;
- uint8_t bInterfaceSubClass;
- uint8_t bInterfaceProtocol;
- uint8_t iInterface;
-} __packed;
-
-/*
- * The following structure is the same as "usb_endpoint_descriptor_t"
- * except that 16-bit values are "uint16_t" and not an array of "uint8_t".
- * It is used by Linux USB device drivers.
- */
-struct usb_endpoint_descriptor {
- uint8_t bLength;
- uint8_t bDescriptorType;
-
- uint8_t bEndpointAddress;
- uint8_t bmAttributes;
- uint16_t wMaxPacketSize;
- uint8_t bInterval;
-
- /* extension for audio endpoints only: */
- uint8_t bRefresh;
- uint8_t bSynchAddress;
-} __packed;
-
-#define USB_DT_ENDPOINT_SIZE 7
-#define USB_DT_ENDPOINT_AUDIO_SIZE 9
-
-/*
- * Endpoints
- */
-#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
-#define USB_ENDPOINT_DIR_MASK 0x80
-
-#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
-#define USB_ENDPOINT_XFER_CONTROL 0
-#define USB_ENDPOINT_XFER_ISOC 1
-#define USB_ENDPOINT_XFER_BULK 2
-#define USB_ENDPOINT_XFER_INT 3
-#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
-
-/* CONTROL REQUEST SUPPORT */
-
-/*
- * Definition of direction mask for
- * "bEndpointAddress" and "bmRequestType":
- */
-#define USB_DIR_MASK 0x80
-#define USB_DIR_OUT 0x00 /* write to USB device */
-#define USB_DIR_IN 0x80 /* read from USB device */
-
-/*
- * Definition of type mask for
- * "bmRequestType":
- */
-#define USB_TYPE_MASK (0x03 << 5)
-#define USB_TYPE_STANDARD (0x00 << 5)
-#define USB_TYPE_CLASS (0x01 << 5)
-#define USB_TYPE_VENDOR (0x02 << 5)
-#define USB_TYPE_RESERVED (0x03 << 5)
-
-/*
- * Definition of receiver mask for
- * "bmRequestType":
- */
-#define USB_RECIP_MASK 0x1f
-#define USB_RECIP_DEVICE 0x00
-#define USB_RECIP_INTERFACE 0x01
-#define USB_RECIP_ENDPOINT 0x02
-#define USB_RECIP_OTHER 0x03
-
-/*
- * Definition of standard request values for
- * "bRequest":
- */
-#define USB_REQ_GET_STATUS 0x00
-#define USB_REQ_CLEAR_FEATURE 0x01
-#define USB_REQ_SET_FEATURE 0x03
-#define USB_REQ_SET_ADDRESS 0x05
-#define USB_REQ_GET_DESCRIPTOR 0x06
-#define USB_REQ_SET_DESCRIPTOR 0x07
-#define USB_REQ_GET_CONFIGURATION 0x08
-#define USB_REQ_SET_CONFIGURATION 0x09
-#define USB_REQ_GET_INTERFACE 0x0A
-#define USB_REQ_SET_INTERFACE 0x0B
-#define USB_REQ_SYNCH_FRAME 0x0C
-
-#define USB_REQ_SET_ENCRYPTION 0x0D /* Wireless USB */
-#define USB_REQ_GET_ENCRYPTION 0x0E
-#define USB_REQ_SET_HANDSHAKE 0x0F
-#define USB_REQ_GET_HANDSHAKE 0x10
-#define USB_REQ_SET_CONNECTION 0x11
-#define USB_REQ_SET_SECURITY_DATA 0x12
-#define USB_REQ_GET_SECURITY_DATA 0x13
-#define USB_REQ_SET_WUSB_DATA 0x14
-#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
-#define USB_REQ_LOOPBACK_DATA_READ 0x16
-#define USB_REQ_SET_INTERFACE_DS 0x17
-
-/*
- * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
- * are read as a bit array returned by USB_REQ_GET_STATUS. (So there
- * are at most sixteen features of each type.)
- */
-#define USB_DEVICE_SELF_POWERED 0 /* (read only) */
-#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */
-#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */
-#define USB_DEVICE_BATTERY 2 /* (wireless) */
-#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */
-#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless) */
-#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */
-#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */
-#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */
-
-#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
-
-#define PIPE_ISOCHRONOUS 0x01 /* UE_ISOCHRONOUS */
-#define PIPE_INTERRUPT 0x03 /* UE_INTERRUPT */
-#define PIPE_CONTROL 0x00 /* UE_CONTROL */
-#define PIPE_BULK 0x02 /* UE_BULK */
-
-/* Whenever Linux references an USB endpoint:
- * a) to initialize "urb->pipe"
- * b) second argument passed to "usb_control_msg()"
- *
- * Then it uses one of the following macros. The "endpoint" argument
- * is the physical endpoint value masked by 0xF. The "dev" argument
- * is a pointer to "struct usb_device".
- */
-#define usb_sndctrlpipe(dev,endpoint) \
- usb_find_host_endpoint(dev, PIPE_CONTROL, (endpoint) | USB_DIR_OUT)
-
-#define usb_rcvctrlpipe(dev,endpoint) \
- usb_find_host_endpoint(dev, PIPE_CONTROL, (endpoint) | USB_DIR_IN)
-
-#define usb_sndisocpipe(dev,endpoint) \
- usb_find_host_endpoint(dev, PIPE_ISOCHRONOUS, (endpoint) | USB_DIR_OUT)
-
-#define usb_rcvisocpipe(dev,endpoint) \
- usb_find_host_endpoint(dev, PIPE_ISOCHRONOUS, (endpoint) | USB_DIR_IN)
-
-#define usb_sndbulkpipe(dev,endpoint) \
- usb_find_host_endpoint(dev, PIPE_BULK, (endpoint) | USB_DIR_OUT)
-
-#define usb_rcvbulkpipe(dev,endpoint) \
- usb_find_host_endpoint(dev, PIPE_BULK, (endpoint) | USB_DIR_IN)
-
-#define usb_sndintpipe(dev,endpoint) \
- usb_find_host_endpoint(dev, PIPE_INTERRUPT, (endpoint) | USB_DIR_OUT)
-
-#define usb_rcvintpipe(dev,endpoint) \
- usb_find_host_endpoint(dev, PIPE_INTERRUPT, (endpoint) | USB_DIR_IN)
-
-/* The following four structures makes up a tree, where we have the
- * leaf structure, "usb_host_endpoint", first, and the root structure,
- * "usb_device", last. The four structures below mirror the structure
- * of the USB descriptors belonging to an USB configuration. Please
- * refer to the USB specification for a definition of "endpoints" and
- * "interfaces".
- */
-struct usb_host_endpoint {
- struct usb_endpoint_descriptor desc;
-
- TAILQ_HEAD(, urb) bsd_urb_list;
-
- struct usb2_xfer *bsd_xfer[2];
-
- uint8_t *extra; /* Extra descriptors */
-
- uint32_t fbsd_buf_size;
-
- uint16_t extralen;
-
- uint8_t bsd_iface_index;
-} __aligned(USB_HOST_ALIGN);
-
-struct usb_host_interface {
- struct usb_interface_descriptor desc;
-
- /* the following array has size "desc.bNumEndpoint" */
- struct usb_host_endpoint *endpoint;
-
- const char *string; /* iInterface string, if present */
- uint8_t *extra; /* Extra descriptors */
-
- uint16_t extralen;
-
- uint8_t bsd_iface_index;
-} __aligned(USB_HOST_ALIGN);
-
-struct usb_interface {
- /* array of alternate settings for this interface */
- struct usb_host_interface *altsetting;
- struct usb_host_interface *cur_altsetting;
- struct usb_device *linux_udev;
- void *bsd_priv_sc; /* device specific information */
-
- uint8_t num_altsetting; /* number of alternate settings */
- uint8_t bsd_iface_index;
-} __aligned(USB_HOST_ALIGN);
-
-struct usb_device {
- struct usb_device_descriptor descriptor;
- struct usb_host_endpoint ep0;
-
- struct usb2_device *bsd_udev;
- struct usb_interface *bsd_iface_start;
- struct usb_interface *bsd_iface_end;
- struct usb_host_endpoint *bsd_endpoint_start;
- struct usb_host_endpoint *bsd_endpoint_end;
-
- /* static strings from the device */
- const char *product; /* iProduct string, if present */
- const char *manufacturer; /* iManufacturer string, if present */
- const char *serial; /* iSerialNumber string, if present */
-
- uint16_t devnum;
-
- uint8_t speed; /* USB_SPEED_XXX */
-} __aligned(USB_HOST_ALIGN);
-
-/*
- * The following structure is used to extend "struct urb" when we are
- * dealing with an isochronous endpoint. It contains information about
- * the data offset and data length of an isochronous packet.
- * The "actual_length" field is updated before the "complete"
- * callback in the "urb" structure is called.
- */
-struct usb_iso_packet_descriptor {
- uint32_t offset; /* depreciated buffer offset (the
- * packets are usually back to back) */
- uint16_t length; /* expected length */
- uint16_t actual_length;
- uint16_t status;
-};
-
-/*
- * The following structure holds various information about an USB
- * transfer. This structure is used for all kinds of USB transfers.
- *
- * URB is short for USB Request Block.
- */
-struct urb {
- TAILQ_ENTRY(urb) bsd_urb_list;
- struct cv cv_wait;
-
- struct usb_device *dev; /* (in) pointer to associated device */
- struct usb_host_endpoint *pipe; /* (in) pipe pointer */
- uint8_t *setup_packet; /* (in) setup packet (control only) */
- uint8_t *bsd_data_ptr;
- void *transfer_buffer; /* (in) associated data buffer */
- void *context; /* (in) context for completion */
- usb_complete_t *complete; /* (in) completion routine */
-
- uint32_t transfer_buffer_length;/* (in) data buffer length */
- uint32_t actual_length; /* (return) actual transfer length */
- uint32_t bsd_length_rem;
- uint32_t timeout; /* FreeBSD specific */
-
- uint16_t transfer_flags; /* (in) */
-#define URB_SHORT_NOT_OK 0x0001 /* report short transfers like errors */
-#define URB_ISO_ASAP 0x0002 /* ignore "start_frame" field */
-#define URB_ZERO_PACKET 0x0004 /* the USB transfer ends with a short
- * packet */
-#define URB_NO_TRANSFER_DMA_MAP 0x0008 /* "transfer_dma" is valid on submit */
-#define URB_WAIT_WAKEUP 0x0010 /* custom flags */
-#define URB_IS_SLEEPING 0x0020 /* custom flags */
-
- uint16_t start_frame; /* (modify) start frame (ISO) */
- uint16_t number_of_packets; /* (in) number of ISO packets */
- uint16_t interval; /* (modify) transfer interval
- * (INT/ISO) */
- uint16_t error_count; /* (return) number of ISO errors */
- int16_t status; /* (return) status */
-
- uint8_t setup_dma; /* (in) not used on FreeBSD */
- uint8_t transfer_dma; /* (in) not used on FreeBSD */
- uint8_t bsd_isread;
-
- struct usb_iso_packet_descriptor iso_frame_desc[]; /* (in) ISO ONLY */
-};
-
-/* various prototypes */
-
-int usb_submit_urb(struct urb *urb, uint16_t mem_flags);
-int usb_unlink_urb(struct urb *urb);
-int usb_clear_halt(struct usb_device *dev, struct usb_host_endpoint *uhe);
-int usb_control_msg(struct usb_device *dev, struct usb_host_endpoint *pipe,
- uint8_t request, uint8_t requesttype, uint16_t value,
- uint16_t index, void *data, uint16_t size, uint32_t timeout);
-int usb_set_interface(struct usb_device *dev, uint8_t ifnum,
- uint8_t alternate);
-int usb_setup_endpoint(struct usb_device *dev,
- struct usb_host_endpoint *uhe, uint32_t bufsize);
-
-struct usb_host_endpoint *usb_find_host_endpoint(struct usb_device *dev,
- uint8_t type, uint8_t ep);
-struct urb *usb_alloc_urb(uint16_t iso_packets, uint16_t mem_flags);
-struct usb_host_interface *usb_altnum_to_altsetting(
- const struct usb_interface *intf, uint8_t alt_index);
-struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, uint8_t iface_no);
-
-void *usb_buffer_alloc(struct usb_device *dev, uint32_t size,
- uint16_t mem_flags, uint8_t *dma_addr);
-void *usb_get_intfdata(struct usb_interface *intf);
-
-void usb_buffer_free(struct usb_device *dev, uint32_t size, void *addr, uint8_t dma_addr);
-void usb_free_urb(struct urb *urb);
-void usb_init_urb(struct urb *urb);
-void usb_kill_urb(struct urb *urb);
-void usb_set_intfdata(struct usb_interface *intf, void *data);
-void usb_linux_register(void *arg);
-void usb_linux_deregister(void *arg);
-
-#define interface_to_usbdev(intf) (intf)->linux_udev
-#define interface_to_bsddev(intf) (intf)->linux_udev->bsd_udev
-
-#endif /* _USB_COMPAT_LINUX_H */
diff --git a/sys/dev/usb2/core/usb2_core.c b/sys/dev/usb2/core/usb2_core.c
deleted file mode 100644
index b96f53c..0000000
--- a/sys/dev/usb2/core/usb2_core.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-/*
- * USB specifications and other documentation can be found at
- * http://www.usb.org/developers/docs/ and
- * http://www.usb.org/developers/devclass_docs/
- */
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-
-MALLOC_DEFINE(M_USB, "USB", "USB");
-MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
-MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
-
-MODULE_VERSION(usb2_core, 1);
diff --git a/sys/dev/usb2/core/usb2_core.h b/sys/dev/usb2/core/usb2_core.h
deleted file mode 100644
index 06f77cb..0000000
--- a/sys/dev/usb2/core/usb2_core.h
+++ /dev/null
@@ -1,467 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-/*
- * Including this file is mandatory for all USB related c-files in the
- * kernel.
- */
-
-#ifndef _USB2_CORE_H_
-#define _USB2_CORE_H_
-
-/* Default USB configuration */
-
-#ifndef USB_NO_POLL
-#define USB_NO_POLL 0
-#endif
-
-#ifndef USB_USE_CONDVAR
-#define USB_USE_CONDVAR 0
-#endif
-
-#ifndef USB_TD_GET_PROC
-#define USB_TD_GET_PROC(td) (td)->td_proc
-#endif
-
-#ifndef USB_PROC_GET_GID
-#define USB_PROC_GET_GID(td) (td)->p_pgid
-#endif
-
-#ifndef USB_VNOPS_FO_CLOSE
-#define USB_VNOPS_FO_CLOSE(fp, td, perr) do { \
- (td)->td_fpop = (fp); \
- *(perr) = vnops.fo_close(fp, td); \
- (td)->td_fpop = NULL; \
-} while (0)
-#endif
-
-#ifndef USB_VNOPS_FO_STAT
-#define USB_VNOPS_FO_STAT(fp, sb, cred, td) \
- vnops.fo_stat(fp, sb, cred, td)
-#endif
-
-#ifndef USB_VNOPS_FO_TRUNCATE
-#define USB_VNOPS_FO_TRUNCATE(fp, length, cred, td) \
- vnops.fo_truncate(fp, length, cred, td)
-#endif
-
-/* Include files */
-
-#include <sys/stdint.h>
-#include <sys/stddef.h>
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bus.h>
-#include <sys/linker_set.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/condvar.h>
-#include <sys/sysctl.h>
-#include <sys/sx.h>
-#include <sys/unistd.h>
-#include <sys/callout.h>
-#include <sys/malloc.h>
-#include <sys/priv.h>
-
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_revision.h>
-
-#include "usb2_if.h"
-#include "opt_usb.h"
-#include "opt_bus.h"
-
-#define USB_STACK_VERSION 2000 /* 2.0 */
-
-#define USB_HOST_ALIGN 8 /* bytes, must be power of two */
-
-#define USB_ISOC_TIME_MAX 128 /* ms */
-#define USB_FS_ISOC_UFRAME_MAX 4 /* exclusive unit */
-
-#if (USB_FS_ISOC_UFRAME_MAX > 6)
-#error "USB_FS_ISOC_UFRAME_MAX cannot be set higher than 6"
-#endif
-
-#define USB_MAX_FS_ISOC_FRAMES_PER_XFER (120) /* units */
-#define USB_MAX_HS_ISOC_FRAMES_PER_XFER (8*120) /* units */
-
-#define USB_MAX_IPACKET 8 /* maximum size of the initial USB
- * data packet */
-#ifndef USB_VERBOSE
-#define USB_VERBOSE 1
-#endif
-
-#define USB_HUB_MAX_DEPTH 5
-
-/* USB transfer states */
-
-#define USB_ST_SETUP 0
-#define USB_ST_TRANSFERRED 1
-#define USB_ST_ERROR 2
-
-/*
- * The following macro will return the current state of an USB
- * transfer like defined by the "USB_ST_XXX" enums.
- */
-#define USB_GET_STATE(xfer) ((xfer)->usb2_state)
-
-/*
- * The following macro will tell if an USB transfer is currently
- * receiving or transferring data.
- */
-#define USB_GET_DATA_ISREAD(xfer) (((xfer)->flags_int.usb2_mode == \
- USB_MODE_DEVICE) ? ((xfer->endpoint & UE_DIR_IN) ? 0 : 1) : \
- ((xfer->endpoint & UE_DIR_IN) ? 1 : 0))
-
-/*
- * The following macros are used used to convert milliseconds into
- * HZ. We use 1024 instead of 1000 milliseconds per second to save a
- * full division.
- */
-#define USB_MS_HZ 1024
-
-#define USB_MS_TO_TICKS(ms) \
- (((uint32_t)((((uint32_t)(ms)) * ((uint32_t)(hz))) + USB_MS_HZ - 1)) / USB_MS_HZ)
-
-/* macros */
-
-#define usb2_callout_init_mtx(c,m,f) callout_init_mtx(&(c)->co,m,f)
-#define usb2_callout_reset(c,t,f,d) callout_reset(&(c)->co,t,f,d)
-#define usb2_callout_stop(c) callout_stop(&(c)->co)
-#define usb2_callout_drain(c) callout_drain(&(c)->co)
-#define usb2_callout_pending(c) callout_pending(&(c)->co)
-
-#define USB_BUS_LOCK(_b) mtx_lock(&(_b)->bus_mtx)
-#define USB_BUS_UNLOCK(_b) mtx_unlock(&(_b)->bus_mtx)
-#define USB_BUS_LOCK_ASSERT(_b, _t) mtx_assert(&(_b)->bus_mtx, _t)
-#define USB_XFER_LOCK(_x) mtx_lock((_x)->xroot->xfer_mtx)
-#define USB_XFER_UNLOCK(_x) mtx_unlock((_x)->xroot->xfer_mtx)
-#define USB_XFER_LOCK_ASSERT(_x, _t) mtx_assert((_x)->xroot->xfer_mtx, _t)
-/* structure prototypes */
-
-struct file;
-struct usb2_bus;
-struct usb2_device;
-struct usb2_page;
-struct usb2_page_cache;
-struct usb2_xfer;
-struct usb2_xfer_root;
-
-/* typedefs */
-
-typedef uint8_t usb2_error_t;
-
-typedef void (usb2_callback_t)(struct usb2_xfer *);
-
-/* structures */
-
-/*
- * This structure contains permissions.
- */
-
-struct usb2_perm {
- uint32_t uid;
- uint32_t gid;
- uint16_t mode;
-};
-
-/*
- * Common queue structure for USB transfers.
- */
-struct usb2_xfer_queue {
- TAILQ_HEAD(, usb2_xfer) head;
- struct usb2_xfer *curr; /* current USB transfer processed */
- void (*command) (struct usb2_xfer_queue *pq);
- uint8_t recurse_1:1;
- uint8_t recurse_2:1;
-};
-
-/*
- * The following is a wrapper for the callout structure to ease
- * porting the code to other platforms.
- */
-struct usb2_callout {
- struct callout co;
-};
-
-/*
- * The following structure defines a set of USB transfer flags.
- */
-struct usb2_xfer_flags {
- uint8_t force_short_xfer:1; /* force a short transmit transfer
- * last */
- uint8_t short_xfer_ok:1; /* allow short receive transfers */
- uint8_t short_frames_ok:1; /* allow short frames */
- uint8_t pipe_bof:1; /* block pipe on failure */
- uint8_t proxy_buffer:1; /* makes buffer size a factor of
- * "max_frame_size" */
- uint8_t ext_buffer:1; /* uses external DMA buffer */
- uint8_t manual_status:1; /* non automatic status stage on
- * control transfers */
- uint8_t no_pipe_ok:1; /* set if "USB_ERR_NO_PIPE" error can
- * be ignored */
- uint8_t stall_pipe:1; /* set if the endpoint belonging to
- * this USB transfer should be stalled
- * before starting this transfer! */
-};
-
-/*
- * The following structure defines a set of internal USB transfer
- * flags.
- */
-struct usb2_xfer_flags_int {
- uint16_t control_rem; /* remainder in bytes */
-
- uint8_t open:1; /* set if USB pipe has been opened */
- uint8_t transferring:1; /* set if an USB transfer is in
- * progress */
- uint8_t did_dma_delay:1; /* set if we waited for HW DMA */
- uint8_t did_close:1; /* set if we closed the USB transfer */
- uint8_t draining:1; /* set if we are draining an USB
- * transfer */
- uint8_t started:1; /* keeps track of started or stopped */
- uint8_t bandwidth_reclaimed:1;
- uint8_t control_xfr:1; /* set if control transfer */
- uint8_t control_hdr:1; /* set if control header should be
- * sent */
- uint8_t control_act:1; /* set if control transfer is active */
-
- uint8_t short_frames_ok:1; /* filtered version */
- uint8_t short_xfer_ok:1; /* filtered version */
- uint8_t bdma_enable:1; /* filtered version (only set if
- * hardware supports DMA) */
- uint8_t bdma_no_post_sync:1; /* set if the USB callback wrapper
- * should not do the BUS-DMA post sync
- * operation */
- uint8_t bdma_setup:1; /* set if BUS-DMA has been setup */
- uint8_t isochronous_xfr:1; /* set if isochronous transfer */
- uint8_t usb2_mode:1; /* shadow copy of "udev->usb2_mode" */
- uint8_t curr_dma_set:1; /* used by USB HC/DC driver */
- uint8_t can_cancel_immed:1; /* set if USB transfer can be
- * cancelled immediately */
-};
-
-/*
- * The following structure defines the symmetric part of an USB config
- * structure.
- */
-struct usb2_config_sub {
- usb2_callback_t *callback; /* USB transfer callback */
- uint32_t bufsize; /* total pipe buffer size in bytes */
- uint32_t frames; /* maximum number of USB frames */
- uint16_t interval; /* interval in milliseconds */
-#define USB_DEFAULT_INTERVAL 0
- uint16_t timeout; /* transfer timeout in milliseconds */
- struct usb2_xfer_flags flags; /* transfer flags */
-};
-
-/*
- * The following structure define an USB configuration, that basically
- * is used when setting up an USB transfer.
- */
-struct usb2_config {
- struct usb2_config_sub mh; /* parameters for USB_MODE_HOST */
- struct usb2_config_sub md; /* parameters for USB_MODE_DEVICE */
- uint8_t type; /* pipe type */
- uint8_t endpoint; /* pipe number */
- uint8_t direction; /* pipe direction */
- uint8_t ep_index; /* pipe index match to use */
- uint8_t if_index; /* "ifaces" index to use */
-};
-
-/*
- * The following structure defines an USB transfer.
- */
-struct usb2_xfer {
- struct usb2_callout timeout_handle;
- TAILQ_ENTRY(usb2_xfer) wait_entry; /* used at various places */
-
- struct usb2_page_cache *buf_fixup; /* fixup buffer(s) */
- struct usb2_xfer_queue *wait_queue; /* pointer to queue that we
- * are waiting on */
- struct usb2_page *dma_page_ptr;
- struct usb2_pipe *pipe; /* our USB pipe */
- struct usb2_xfer_root *xroot; /* used by HC driver */
- void *qh_start[2]; /* used by HC driver */
- void *td_start[2]; /* used by HC driver */
- void *td_transfer_first; /* used by HC driver */
- void *td_transfer_last; /* used by HC driver */
- void *td_transfer_cache; /* used by HC driver */
- void *priv_sc; /* device driver data pointer 1 */
- void *priv_fifo; /* device driver data pointer 2 */
- void *local_buffer;
- uint32_t *frlengths;
- struct usb2_page_cache *frbuffers;
- usb2_callback_t *callback;
-
- uint32_t max_usb2_frame_size;
- uint32_t max_data_length;
- uint32_t sumlen; /* sum of all lengths in bytes */
- uint32_t actlen; /* actual length in bytes */
- uint32_t timeout; /* milliseconds */
-#define USB_NO_TIMEOUT 0
-#define USB_DEFAULT_TIMEOUT 5000 /* 5000 ms = 5 seconds */
-
- uint32_t max_frame_count; /* initial value of "nframes" after
- * setup */
- uint32_t nframes; /* number of USB frames to transfer */
- uint32_t aframes; /* actual number of USB frames
- * transferred */
-
- uint16_t max_packet_size;
- uint16_t max_frame_size;
- uint16_t qh_pos;
- uint16_t isoc_time_complete; /* in ms */
- uint16_t interval; /* milliseconds */
-
- uint8_t address; /* physical USB address */
- uint8_t endpoint; /* physical USB endpoint */
- uint8_t max_packet_count;
- uint8_t usb2_smask;
- uint8_t usb2_cmask;
- uint8_t usb2_uframe;
- uint8_t usb2_state;
-
- usb2_error_t error;
-
- struct usb2_xfer_flags flags;
- struct usb2_xfer_flags_int flags_int;
-};
-
-/*
- * The following structure keeps information that is used to match
- * against an array of "usb2_device_id" elements.
- */
-struct usb2_lookup_info {
- uint16_t idVendor;
- uint16_t idProduct;
- uint16_t bcdDevice;
- uint8_t bDeviceClass;
- uint8_t bDeviceSubClass;
- uint8_t bDeviceProtocol;
- uint8_t bInterfaceClass;
- uint8_t bInterfaceSubClass;
- uint8_t bInterfaceProtocol;
- uint8_t bIfaceIndex;
- uint8_t bIfaceNum;
- uint8_t bConfigIndex;
- uint8_t bConfigNum;
-};
-
-/* Structure used by probe and attach */
-
-struct usb2_attach_arg {
- struct usb2_lookup_info info;
- device_t temp_dev; /* for internal use */
- const void *driver_info; /* for internal use */
- struct usb2_device *device; /* current device */
- struct usb2_interface *iface; /* current interface */
- uint8_t usb2_mode; /* see USB_MODE_XXX */
- uint8_t port;
- uint8_t use_generic; /* hint for generic drivers */
-};
-
-/* Structure used when referring an USB device */
-
-struct usb2_location {
- struct usb2_bus *bus;
- struct usb2_device *udev;
- struct usb2_interface *iface;
- struct usb2_fifo *rxfifo;
- struct usb2_fifo *txfifo;
- uint32_t devloc; /* original devloc */
- uint16_t bus_index; /* bus index */
- uint8_t dev_index; /* device index */
- uint8_t iface_index; /* interface index */
- uint8_t fifo_index; /* FIFO index */
- uint8_t is_read; /* set if location has read access */
- uint8_t is_write; /* set if location has write access */
- uint8_t is_uref; /* set if USB refcount decr. needed */
- uint8_t is_usbfs; /* set if USB-FS is active */
-};
-
-/* external variables */
-
-MALLOC_DECLARE(M_USB);
-MALLOC_DECLARE(M_USBDEV);
-MALLOC_DECLARE(M_USBHC);
-
-extern struct mtx usb2_ref_lock;
-
-/* typedefs */
-
-typedef struct malloc_type *usb2_malloc_type;
-
-/* prototypes */
-
-const char *usb2_errstr(usb2_error_t error);
-struct usb2_config_descriptor *usb2_get_config_descriptor(
- struct usb2_device *udev);
-struct usb2_device_descriptor *usb2_get_device_descriptor(
- struct usb2_device *udev);
-struct usb2_interface *usb2_get_iface(struct usb2_device *udev,
- uint8_t iface_index);
-struct usb2_interface_descriptor *usb2_get_interface_descriptor(
- struct usb2_interface *iface);
-uint8_t usb2_clear_stall_callback(struct usb2_xfer *xfer1,
- struct usb2_xfer *xfer2);
-uint8_t usb2_get_interface_altindex(struct usb2_interface *iface);
-usb2_error_t usb2_set_alt_interface_index(struct usb2_device *udev,
- uint8_t iface_index, uint8_t alt_index);
-uint8_t usb2_get_mode(struct usb2_device *udev);
-uint8_t usb2_get_speed(struct usb2_device *udev);
-uint32_t usb2_get_isoc_fps(struct usb2_device *udev);
-usb2_error_t usb2_transfer_setup(struct usb2_device *udev,
- const uint8_t *ifaces, struct usb2_xfer **pxfer,
- const struct usb2_config *setup_start, uint16_t n_setup,
- void *priv_sc, struct mtx *priv_mtx);
-void usb2_set_frame_data(struct usb2_xfer *xfer, void *ptr,
- uint32_t frindex);
-void usb2_set_frame_offset(struct usb2_xfer *xfer, uint32_t offset,
- uint32_t frindex);
-void usb2_start_hardware(struct usb2_xfer *xfer);
-void usb2_transfer_clear_stall(struct usb2_xfer *xfer);
-void usb2_transfer_drain(struct usb2_xfer *xfer);
-void usb2_transfer_set_stall(struct usb2_xfer *xfer);
-uint8_t usb2_transfer_pending(struct usb2_xfer *xfer);
-void usb2_transfer_start(struct usb2_xfer *xfer);
-void usb2_transfer_stop(struct usb2_xfer *xfer);
-void usb2_transfer_unsetup(struct usb2_xfer **pxfer, uint16_t n_setup);
-usb2_error_t usb2_ref_device(struct file *fp, struct usb2_location *ploc,
- uint32_t devloc);
-void usb2_unref_device(struct usb2_location *ploc);
-void usb2_set_parent_iface(struct usb2_device *udev, uint8_t iface_index,
- uint8_t parent_index);
-void usb2_set_iface_perm(struct usb2_device *udev, uint8_t iface_index,
- uint32_t uid, uint32_t gid, uint16_t mode);
-uint8_t usb2_get_bus_index(struct usb2_device *udev);
-uint8_t usb2_get_device_index(struct usb2_device *udev);
-void usb2_set_power_mode(struct usb2_device *udev, uint8_t power_mode);
-
-#endif /* _USB2_CORE_H_ */
diff --git a/sys/dev/usb2/core/usb2_debug.c b/sys/dev/usb2/core/usb2_debug.c
deleted file mode 100644
index 46d27b4..0000000
--- a/sys/dev/usb2/core/usb2_debug.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_transfer.h>
-
-/*
- * Define this unconditionally in case a kernel module is loaded that
- * has been compiled with debugging options.
- */
-int usb2_debug = 0;
-
-SYSCTL_NODE(_hw, OID_AUTO, usb2, CTLFLAG_RW, 0, "USB debugging");
-SYSCTL_INT(_hw_usb2, OID_AUTO, debug, CTLFLAG_RW,
- &usb2_debug, 0, "Debug level");
-
-/*------------------------------------------------------------------------*
- * usb2_dump_iface
- *
- * This function dumps information about an USB interface.
- *------------------------------------------------------------------------*/
-void
-usb2_dump_iface(struct usb2_interface *iface)
-{
- printf("usb2_dump_iface: iface=%p\n", iface);
- if (iface == NULL) {
- return;
- }
- printf(" iface=%p idesc=%p altindex=%d\n",
- iface, iface->idesc, iface->alt_index);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_dump_device
- *
- * This function dumps information about an USB device.
- *------------------------------------------------------------------------*/
-void
-usb2_dump_device(struct usb2_device *udev)
-{
- printf("usb2_dump_device: dev=%p\n", udev);
- if (udev == NULL) {
- return;
- }
- printf(" bus=%p \n"
- " address=%d config=%d depth=%d speed=%d self_powered=%d\n"
- " power=%d langid=%d\n",
- udev->bus,
- udev->address, udev->curr_config_no, udev->depth, udev->speed,
- udev->flags.self_powered, udev->power, udev->langid);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_dump_queue
- *
- * This function dumps the USB transfer that are queued up on an USB pipe.
- *------------------------------------------------------------------------*/
-void
-usb2_dump_queue(struct usb2_pipe *pipe)
-{
- struct usb2_xfer *xfer;
-
- printf("usb2_dump_queue: pipe=%p xfer: ", pipe);
- TAILQ_FOREACH(xfer, &pipe->pipe_q.head, wait_entry) {
- printf(" %p", xfer);
- }
- printf("\n");
-}
-
-/*------------------------------------------------------------------------*
- * usb2_dump_pipe
- *
- * This function dumps information about an USB pipe.
- *------------------------------------------------------------------------*/
-void
-usb2_dump_pipe(struct usb2_pipe *pipe)
-{
- if (pipe) {
- printf("usb2_dump_pipe: pipe=%p", pipe);
-
- printf(" edesc=%p isoc_next=%d toggle_next=%d",
- pipe->edesc, pipe->isoc_next, pipe->toggle_next);
-
- if (pipe->edesc) {
- printf(" bEndpointAddress=0x%02x",
- pipe->edesc->bEndpointAddress);
- }
- printf("\n");
- usb2_dump_queue(pipe);
- } else {
- printf("usb2_dump_pipe: pipe=NULL\n");
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_dump_xfer
- *
- * This function dumps information about an USB transfer.
- *------------------------------------------------------------------------*/
-void
-usb2_dump_xfer(struct usb2_xfer *xfer)
-{
- struct usb2_device *udev;
- printf("usb2_dump_xfer: xfer=%p\n", xfer);
- if (xfer == NULL) {
- return;
- }
- if (xfer->pipe == NULL) {
- printf("xfer %p: pipe=NULL\n",
- xfer);
- return;
- }
- udev = xfer->xroot->udev;
- printf("xfer %p: udev=%p vid=0x%04x pid=0x%04x addr=%d "
- "pipe=%p ep=0x%02x attr=0x%02x\n",
- xfer, udev,
- UGETW(udev->ddesc.idVendor),
- UGETW(udev->ddesc.idProduct),
- udev->address, xfer->pipe,
- xfer->pipe->edesc->bEndpointAddress,
- xfer->pipe->edesc->bmAttributes);
-}
diff --git a/sys/dev/usb2/core/usb2_debug.h b/sys/dev/usb2/core/usb2_debug.h
deleted file mode 100644
index 92dcbd5..0000000
--- a/sys/dev/usb2/core/usb2_debug.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 file contains various factored out debug macros. */
-
-#ifndef _USB2_DEBUG_H_
-#define _USB2_DEBUG_H_
-
-/* Declare parent SYSCTL USB node. */
-SYSCTL_DECL(_hw_usb2);
-
-/* Declare global USB debug variable. */
-extern int usb2_debug;
-
-/* Force debugging until further */
-#ifndef USB_DEBUG
-#define USB_DEBUG 1
-#endif
-
-/* Check if USB debugging is enabled. */
-#ifdef USB_DEBUG_VAR
-#if (USB_DEBUG != 0)
-#define DPRINTFN(n,fmt,...) do { \
- if ((USB_DEBUG_VAR) >= (n)) { \
- printf("%s:%u: " fmt, \
- __FUNCTION__, __LINE__,## __VA_ARGS__); \
- } \
-} while (0)
-#define DPRINTF(...) DPRINTFN(1, __VA_ARGS__)
-#else
-#define DPRINTF(...) do { } while (0)
-#define DPRINTFN(...) do { } while (0)
-#endif
-#endif
-
-struct usb2_interface;
-struct usb2_device;
-struct usb2_pipe;
-struct usb2_xfer;
-
-void usb2_dump_iface(struct usb2_interface *iface);
-void usb2_dump_device(struct usb2_device *udev);
-void usb2_dump_queue(struct usb2_pipe *pipe);
-void usb2_dump_pipe(struct usb2_pipe *pipe);
-void usb2_dump_xfer(struct usb2_xfer *xfer);
-
-#endif /* _USB2_DEBUG_H_ */
diff --git a/sys/dev/usb2/core/usb2_dev.c b/sys/dev/usb2/core/usb2_dev.c
deleted file mode 100644
index 18b1f9f..0000000
--- a/sys/dev/usb2/core/usb2_dev.c
+++ /dev/null
@@ -1,2814 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2006-2008 Hans Petter Selasky. 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.
- *
- *
- * usb2_dev.c - An abstraction layer for creating devices under /dev/...
- */
-
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR usb2_fifo_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-#include <dev/usb2/core/usb2_dev.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_generic.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-
-#include <sys/filio.h>
-#include <sys/ttycom.h>
-#include <sys/syscallsubr.h>
-
-#include <machine/stdarg.h>
-
-#if USB_DEBUG
-static int usb2_fifo_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, dev, CTLFLAG_RW, 0, "USB device");
-SYSCTL_INT(_hw_usb2_dev, OID_AUTO, debug, CTLFLAG_RW,
- &usb2_fifo_debug, 0, "Debug Level");
-#endif
-
-#if ((__FreeBSD_version >= 700001) || (__FreeBSD_version == 0) || \
- ((__FreeBSD_version >= 600034) && (__FreeBSD_version < 700000)))
-#define USB_UCRED struct ucred *ucred,
-#else
-#define USB_UCRED
-#endif
-
-/* prototypes */
-
-static uint32_t usb2_path_convert_one(const char **);
-static uint32_t usb2_path_convert(const char *);
-static int usb2_check_access(int, struct usb2_perm *);
-static int usb2_fifo_open(struct usb2_fifo *, struct file *,
- struct thread *, int);
-static void usb2_fifo_close(struct usb2_fifo *, struct thread *, int);
-static void usb2_dev_init(void *);
-static void usb2_dev_init_post(void *);
-static void usb2_dev_uninit(void *);
-static int usb2_fifo_uiomove(struct usb2_fifo *, void *, int,
- struct uio *);
-static void usb2_fifo_check_methods(struct usb2_fifo_methods *);
-static void usb2_clone(void *, USB_UCRED char *, int, struct cdev **);
-static struct usb2_fifo *usb2_fifo_alloc(void);
-static struct usb2_pipe *usb2_dev_get_pipe(struct usb2_device *, uint8_t,
- uint8_t, uint8_t);
-
-static d_fdopen_t usb2_fdopen;
-static d_close_t usb2_close;
-static d_ioctl_t usb2_ioctl;
-
-static fo_rdwr_t usb2_read_f;
-static fo_rdwr_t usb2_write_f;
-
-#if __FreeBSD_version > 800009
-static fo_truncate_t usb2_truncate_f;
-
-#endif
-static fo_ioctl_t usb2_ioctl_f;
-static fo_poll_t usb2_poll_f;
-static fo_kqfilter_t usb2_kqfilter_f;
-static fo_stat_t usb2_stat_f;
-static fo_close_t usb2_close_f;
-
-static usb2_fifo_open_t usb2_fifo_dummy_open;
-static usb2_fifo_close_t usb2_fifo_dummy_close;
-static usb2_fifo_ioctl_t usb2_fifo_dummy_ioctl;
-static usb2_fifo_cmd_t usb2_fifo_dummy_cmd;
-
-static struct usb2_perm usb2_perm = {
- .uid = UID_ROOT,
- .gid = GID_OPERATOR,
- .mode = 0660,
-};
-
-static struct cdevsw usb2_devsw = {
- .d_version = D_VERSION,
- .d_fdopen = usb2_fdopen,
- .d_close = usb2_close,
- .d_ioctl = usb2_ioctl,
- .d_name = "usb",
- .d_flags = D_TRACKCLOSE,
-};
-
-static struct fileops usb2_ops_f = {
- .fo_read = usb2_read_f,
- .fo_write = usb2_write_f,
-#if __FreeBSD_version > 800009
- .fo_truncate = usb2_truncate_f,
-#endif
- .fo_ioctl = usb2_ioctl_f,
- .fo_poll = usb2_poll_f,
- .fo_kqfilter = usb2_kqfilter_f,
- .fo_stat = usb2_stat_f,
- .fo_close = usb2_close_f,
- .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
-};
-
-static const dev_clone_fn usb2_clone_ptr = &usb2_clone;
-static struct cdev *usb2_dev;
-static uint32_t usb2_last_devloc = 0 - 1;
-static eventhandler_tag usb2_clone_tag;
-static void *usb2_old_f_data;
-static struct fileops *usb2_old_f_ops;
-static TAILQ_HEAD(, usb2_symlink) usb2_sym_head;
-static struct sx usb2_sym_lock;
-
-struct mtx usb2_ref_lock;
-
-static uint32_t
-usb2_path_convert_one(const char **pp)
-{
- const char *ptr;
- uint32_t temp = 0;
-
- ptr = *pp;
-
- while ((*ptr >= '0') && (*ptr <= '9')) {
- temp *= 10;
- temp += (*ptr - '0');
- if (temp >= 1000000) {
- /* catch overflow early */
- return (0 - 1);
- }
- ptr++;
- }
-
- if (*ptr == '.') {
- /* skip dot */
- ptr++;
- }
- *pp = ptr;
-
- return (temp);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_path_convert
- *
- * Path format: "/dev/usb<bus>.<dev>.<iface>.<fifo>"
- *
- * Returns: Path converted into numerical format.
- *------------------------------------------------------------------------*/
-static uint32_t
-usb2_path_convert(const char *path)
-{
- uint32_t temp;
- uint32_t devloc;
-
- devloc = 0;
-
- temp = usb2_path_convert_one(&path);
-
- if (temp >= USB_BUS_MAX) {
- return (0 - 1);
- }
- devloc += temp;
-
- temp = usb2_path_convert_one(&path);
-
- if (temp >= USB_DEV_MAX) {
- return (0 - 1);
- }
- devloc += (temp * USB_BUS_MAX);
-
- temp = usb2_path_convert_one(&path);
-
- if (temp >= USB_IFACE_MAX) {
- return (0 - 1);
- }
- devloc += (temp * USB_DEV_MAX * USB_BUS_MAX);
-
- temp = usb2_path_convert_one(&path);
-
- if (temp >= ((USB_FIFO_MAX / 2) + (USB_EP_MAX / 2))) {
- return (0 - 1);
- }
- devloc += (temp * USB_IFACE_MAX * USB_DEV_MAX * USB_BUS_MAX);
-
- return (devloc);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_set_iface_perm
- *
- * This function will set the interface permissions.
- *------------------------------------------------------------------------*/
-void
-usb2_set_iface_perm(struct usb2_device *udev, uint8_t iface_index,
- uint32_t uid, uint32_t gid, uint16_t mode)
-{
- struct usb2_interface *iface;
-
- iface = usb2_get_iface(udev, iface_index);
- if (iface && iface->idesc) {
- mtx_lock(&usb2_ref_lock);
- iface->perm.uid = uid;
- iface->perm.gid = gid;
- iface->perm.mode = mode;
- mtx_unlock(&usb2_ref_lock);
-
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_set_perm
- *
- * This function will set the permissions at the given level.
- *
- * Return values:
- * 0: Success.
- * Else: Failure.
- *------------------------------------------------------------------------*/
-static int
-usb2_set_perm(struct usb2_dev_perm *psrc, uint8_t level)
-{
- struct usb2_location loc;
- struct usb2_perm *pdst;
- uint32_t devloc;
- int error;
-
- /* check if the current thread can change USB permissions. */
- error = priv_check(curthread, PRIV_ROOT);
- if (error) {
- return (error);
- }
- /* range check device location */
- if ((psrc->bus_index >= USB_BUS_MAX) ||
- (psrc->dev_index >= USB_DEV_MAX) ||
- (psrc->iface_index >= USB_IFACE_MAX)) {
- return (EINVAL);
- }
- if (level == 1)
- devloc = USB_BUS_MAX; /* use root-HUB to access bus */
- else
- devloc = 0;
- switch (level) {
- case 3:
- devloc += psrc->iface_index *
- USB_DEV_MAX * USB_BUS_MAX;
- /* FALLTHROUGH */
- case 2:
- devloc += psrc->dev_index *
- USB_BUS_MAX;
- /* FALLTHROUGH */
- case 1:
- devloc += psrc->bus_index;
- break;
- default:
- break;
- }
-
- if ((level > 0) && (level < 4)) {
- error = usb2_ref_device(NULL, &loc, devloc);
- if (error) {
- return (error);
- }
- }
- switch (level) {
- case 3:
- if (loc.iface == NULL) {
- usb2_unref_device(&loc);
- return (EINVAL);
- }
- pdst = &loc.iface->perm;
- break;
- case 2:
- pdst = &loc.udev->perm;
- break;
- case 1:
- pdst = &loc.bus->perm;
- break;
- default:
- pdst = &usb2_perm;
- break;
- }
-
- /* all permissions are protected by "usb2_ref_lock" */
- mtx_lock(&usb2_ref_lock);
- pdst->uid = psrc->user_id;
- pdst->gid = psrc->group_id;
- pdst->mode = psrc->mode;
- mtx_unlock(&usb2_ref_lock);
-
- if ((level > 0) && (level < 4)) {
- usb2_unref_device(&loc);
- }
- return (0); /* success */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_get_perm
- *
- * This function will get the permissions at the given level.
- *
- * Return values:
- * 0: Success.
- * Else: Failure.
- *------------------------------------------------------------------------*/
-static int
-usb2_get_perm(struct usb2_dev_perm *pdst, uint8_t level)
-{
- struct usb2_location loc;
- struct usb2_perm *psrc;
- uint32_t devloc;
- int error;
-
- if ((pdst->bus_index >= USB_BUS_MAX) ||
- (pdst->dev_index >= USB_DEV_MAX) ||
- (pdst->iface_index >= USB_IFACE_MAX)) {
- return (EINVAL);
- }
- if (level == 1)
- devloc = USB_BUS_MAX; /* use root-HUB to access bus */
- else
- devloc = 0;
- switch (level) {
- case 3:
- devloc += pdst->iface_index *
- USB_DEV_MAX * USB_BUS_MAX;
- /* FALLTHROUGH */
- case 2:
- devloc += pdst->dev_index *
- USB_BUS_MAX;
- /* FALLTHROUGH */
- case 1:
- devloc += pdst->bus_index;
- break;
- default:
- break;
- }
-
- if ((level > 0) && (level < 4)) {
- error = usb2_ref_device(NULL, &loc, devloc);
- if (error) {
- return (error);
- }
- }
- switch (level) {
- case 3:
- if (loc.iface == NULL) {
- usb2_unref_device(&loc);
- return (EINVAL);
- }
- psrc = &loc.iface->perm;
- break;
- case 2:
- psrc = &loc.udev->perm;
- break;
- case 1:
- psrc = &loc.bus->perm;
- break;
- default:
- psrc = &usb2_perm;
- break;
- }
-
- /* all permissions are protected by "usb2_ref_lock" */
- mtx_lock(&usb2_ref_lock);
- if (psrc->mode != 0) {
- pdst->user_id = psrc->uid;
- pdst->group_id = psrc->gid;
- pdst->mode = psrc->mode;
- } else {
- /* access entry at this level and location is not active */
- pdst->user_id = 0;
- pdst->group_id = 0;
- pdst->mode = 0;
- }
- mtx_unlock(&usb2_ref_lock);
-
- if ((level > 0) && (level < 4)) {
- usb2_unref_device(&loc);
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_check_access
- *
- * This function will verify the given access information.
- *
- * Return values:
- * 0: Access granted.
- * Else: No access granted.
- *------------------------------------------------------------------------*/
-static int
-usb2_check_access(int fflags, struct usb2_perm *puser)
-{
- mode_t accmode;
-
- if ((fflags & (FWRITE | FREAD)) && (puser->mode != 0)) {
- /* continue */
- } else {
- return (EPERM); /* no access */
- }
-
- accmode = 0;
- if (fflags & FWRITE)
- accmode |= VWRITE;
- if (fflags & FREAD)
- accmode |= VREAD;
-
- return (vaccess(VCHR, puser->mode, puser->uid,
- puser->gid, accmode, curthread->td_ucred, NULL));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_ref_device
- *
- * This function is used to atomically refer an USB device by its
- * device location. If this function returns success the USB device
- * will not dissappear until the USB device is unreferenced.
- *
- * Return values:
- * 0: Success, refcount incremented on the given USB device.
- * Else: Failure.
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_ref_device(struct file *fp, struct usb2_location *ploc, uint32_t devloc)
-{
- struct usb2_fifo **ppf;
- struct usb2_fifo *f;
- int fflags;
- uint8_t dev_ep_index;
-
- if (fp) {
- /* check if we need uref */
- ploc->is_uref = devloc ? 0 : 1;
- /* get devloc - already verified */
- devloc = USB_P2U(fp->f_data);
- /* get file flags */
- fflags = fp->f_flag;
- } else {
- /* only ref device */
- fflags = 0;
- /* search for FIFO */
- ploc->is_uref = 1;
- /* check "devloc" */
- if (devloc >= (USB_BUS_MAX * USB_DEV_MAX *
- USB_IFACE_MAX * ((USB_EP_MAX / 2) + (USB_FIFO_MAX / 2)))) {
- return (USB_ERR_INVAL);
- }
- }
-
- /* store device location */
- ploc->devloc = devloc;
- ploc->bus_index = devloc % USB_BUS_MAX;
- ploc->dev_index = (devloc / USB_BUS_MAX) % USB_DEV_MAX;
- ploc->iface_index = (devloc / (USB_BUS_MAX *
- USB_DEV_MAX)) % USB_IFACE_MAX;
- ploc->fifo_index = (devloc / (USB_BUS_MAX * USB_DEV_MAX *
- USB_IFACE_MAX));
-
- mtx_lock(&usb2_ref_lock);
- ploc->bus = devclass_get_softc(usb2_devclass_ptr, ploc->bus_index);
- if (ploc->bus == NULL) {
- DPRINTFN(2, "no bus at %u\n", ploc->bus_index);
- goto error;
- }
- if (ploc->dev_index >= ploc->bus->devices_max) {
- DPRINTFN(2, "invalid dev index, %u\n", ploc->dev_index);
- goto error;
- }
- ploc->udev = ploc->bus->devices[ploc->dev_index];
- if (ploc->udev == NULL) {
- DPRINTFN(2, "no device at %u\n", ploc->dev_index);
- goto error;
- }
- if (ploc->udev->refcount == USB_DEV_REF_MAX) {
- DPRINTFN(2, "no dev ref\n");
- goto error;
- }
- /* check if we are doing an open */
- if (fp == NULL) {
- /* set defaults */
- ploc->txfifo = NULL;
- ploc->rxfifo = NULL;
- ploc->is_write = 0;
- ploc->is_read = 0;
- ploc->is_usbfs = 0;
- /* NOTE: variable overloading: */
- dev_ep_index = ploc->fifo_index;
- } else {
- /* initialise "is_usbfs" flag */
- ploc->is_usbfs = 0;
- dev_ep_index = 255; /* dummy */
-
- /* check for write */
- if (fflags & FWRITE) {
- ppf = ploc->udev->fifo;
- f = ppf[ploc->fifo_index + USB_FIFO_TX];
- ploc->txfifo = f;
- ploc->is_write = 1; /* ref */
- if ((f == NULL) ||
- (f->refcount == USB_FIFO_REF_MAX) ||
- (f->curr_file != fp)) {
- goto error;
- }
- /* check if USB-FS is active */
- if (f->fs_ep_max != 0) {
- ploc->is_usbfs = 1;
- }
- /*
- * Get real endpoint index associated with
- * this FIFO:
- */
- dev_ep_index = f->dev_ep_index;
- } else {
- ploc->txfifo = NULL;
- ploc->is_write = 0; /* no ref */
- }
-
- /* check for read */
- if (fflags & FREAD) {
- ppf = ploc->udev->fifo;
- f = ppf[ploc->fifo_index + USB_FIFO_RX];
- ploc->rxfifo = f;
- ploc->is_read = 1; /* ref */
- if ((f == NULL) ||
- (f->refcount == USB_FIFO_REF_MAX) ||
- (f->curr_file != fp)) {
- goto error;
- }
- /* check if USB-FS is active */
- if (f->fs_ep_max != 0) {
- ploc->is_usbfs = 1;
- }
- /*
- * Get real endpoint index associated with
- * this FIFO:
- */
- dev_ep_index = f->dev_ep_index;
- } else {
- ploc->rxfifo = NULL;
- ploc->is_read = 0; /* no ref */
- }
- }
-
- /* check if we require an interface */
- ploc->iface = usb2_get_iface(ploc->udev, ploc->iface_index);
- if (dev_ep_index != 0) {
- /* non control endpoint - we need an interface */
- if (ploc->iface == NULL) {
- DPRINTFN(2, "no iface\n");
- goto error;
- }
- if (ploc->iface->idesc == NULL) {
- DPRINTFN(2, "no idesc\n");
- goto error;
- }
- }
- /* when everything is OK we increment the refcounts */
- if (ploc->is_write) {
- DPRINTFN(2, "ref write\n");
- ploc->txfifo->refcount++;
- }
- if (ploc->is_read) {
- DPRINTFN(2, "ref read\n");
- ploc->rxfifo->refcount++;
- }
- if (ploc->is_uref) {
- DPRINTFN(2, "ref udev - needed\n");
- ploc->udev->refcount++;
- }
- mtx_unlock(&usb2_ref_lock);
-
- if (ploc->is_uref) {
- /*
- * We are about to alter the bus-state. Apply the
- * required locks.
- */
- sx_xlock(ploc->udev->default_sx + 1);
- mtx_lock(&Giant); /* XXX */
- }
- return (0);
-
-error:
- mtx_unlock(&usb2_ref_lock);
- DPRINTFN(2, "fail\n");
- return (USB_ERR_INVAL);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_uref_location
- *
- * This function is used to upgrade an USB reference to include the
- * USB device reference on a USB location.
- *
- * Return values:
- * 0: Success, refcount incremented on the given USB device.
- * Else: Failure.
- *------------------------------------------------------------------------*/
-static usb2_error_t
-usb2_uref_location(struct usb2_location *ploc)
-{
- /*
- * Check if we already got an USB reference on this location:
- */
- if (ploc->is_uref) {
- return (0); /* success */
- }
- mtx_lock(&usb2_ref_lock);
- if (ploc->bus != devclass_get_softc(usb2_devclass_ptr, ploc->bus_index)) {
- DPRINTFN(2, "bus changed at %u\n", ploc->bus_index);
- goto error;
- }
- if (ploc->udev != ploc->bus->devices[ploc->dev_index]) {
- DPRINTFN(2, "device changed at %u\n", ploc->dev_index);
- goto error;
- }
- if (ploc->udev->refcount == USB_DEV_REF_MAX) {
- DPRINTFN(2, "no dev ref\n");
- goto error;
- }
- DPRINTFN(2, "ref udev\n");
- ploc->udev->refcount++;
- mtx_unlock(&usb2_ref_lock);
-
- /* set "uref" */
- ploc->is_uref = 1;
-
- /*
- * We are about to alter the bus-state. Apply the
- * required locks.
- */
- sx_xlock(ploc->udev->default_sx + 1);
- mtx_lock(&Giant); /* XXX */
- return (0);
-
-error:
- mtx_unlock(&usb2_ref_lock);
- DPRINTFN(2, "fail\n");
- return (USB_ERR_INVAL);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_unref_device
- *
- * This function will release the reference count by one unit for the
- * given USB device.
- *------------------------------------------------------------------------*/
-void
-usb2_unref_device(struct usb2_location *ploc)
-{
- if (ploc->is_uref) {
- mtx_unlock(&Giant); /* XXX */
- sx_unlock(ploc->udev->default_sx + 1);
- }
- mtx_lock(&usb2_ref_lock);
- if (ploc->is_read) {
- if (--(ploc->rxfifo->refcount) == 0) {
- usb2_cv_signal(&ploc->rxfifo->cv_drain);
- }
- }
- if (ploc->is_write) {
- if (--(ploc->txfifo->refcount) == 0) {
- usb2_cv_signal(&ploc->txfifo->cv_drain);
- }
- }
- if (ploc->is_uref) {
- if (--(ploc->udev->refcount) == 0) {
- usb2_cv_signal(ploc->udev->default_cv + 1);
- }
- }
- mtx_unlock(&usb2_ref_lock);
-}
-
-static struct usb2_fifo *
-usb2_fifo_alloc(void)
-{
- struct usb2_fifo *f;
-
- f = malloc(sizeof(*f), M_USBDEV, M_WAITOK | M_ZERO);
- if (f) {
- usb2_cv_init(&f->cv_io, "FIFO-IO");
- usb2_cv_init(&f->cv_drain, "FIFO-DRAIN");
- f->refcount = 1;
- }
- return (f);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fifo_create
- *------------------------------------------------------------------------*/
-static int
-usb2_fifo_create(struct usb2_location *ploc, uint32_t *pdevloc, int fflags)
-{
- struct usb2_device *udev = ploc->udev;
- struct usb2_fifo *f;
- struct usb2_pipe *pipe;
- uint8_t iface_index = ploc->iface_index;
-
- /* NOTE: variable overloading: */
- uint8_t dev_ep_index = ploc->fifo_index;
- uint8_t n;
- uint8_t is_tx;
- uint8_t is_rx;
- uint8_t no_null;
- uint8_t is_busy;
-
- is_tx = (fflags & FWRITE) ? 1 : 0;
- is_rx = (fflags & FREAD) ? 1 : 0;
- no_null = 1;
- is_busy = 0;
-
- /* search for a free FIFO slot */
-
- for (n = 0;; n += 2) {
-
- if (n == USB_FIFO_MAX) {
- if (no_null) {
- no_null = 0;
- n = 0;
- } else {
- /* end of FIFOs reached */
- return (ENOMEM);
- }
- }
- /* Check for TX FIFO */
- if (is_tx) {
- f = udev->fifo[n + USB_FIFO_TX];
- if (f != NULL) {
- if (f->dev_ep_index != dev_ep_index) {
- /* wrong endpoint index */
- continue;
- }
- if ((dev_ep_index != 0) &&
- (f->iface_index != iface_index)) {
- /* wrong interface index */
- continue;
- }
- if (f->curr_file != NULL) {
- /* FIFO is opened */
- is_busy = 1;
- continue;
- }
- } else if (no_null) {
- continue;
- }
- }
- /* Check for RX FIFO */
- if (is_rx) {
- f = udev->fifo[n + USB_FIFO_RX];
- if (f != NULL) {
- if (f->dev_ep_index != dev_ep_index) {
- /* wrong endpoint index */
- continue;
- }
- if ((dev_ep_index != 0) &&
- (f->iface_index != iface_index)) {
- /* wrong interface index */
- continue;
- }
- if (f->curr_file != NULL) {
- /* FIFO is opened */
- is_busy = 1;
- continue;
- }
- } else if (no_null) {
- continue;
- }
- }
- break;
- }
-
- if (no_null == 0) {
- if (dev_ep_index >= (USB_EP_MAX / 2)) {
- /* we don't create any endpoints in this range */
- return (is_busy ? EBUSY : EINVAL);
- }
- }
- /* Check TX FIFO */
- if (is_tx &&
- (udev->fifo[n + USB_FIFO_TX] == NULL)) {
- pipe = usb2_dev_get_pipe(udev,
- iface_index, dev_ep_index, USB_FIFO_TX);
- if (pipe == NULL) {
- return (EINVAL);
- }
- f = usb2_fifo_alloc();
- if (f == NULL) {
- return (ENOMEM);
- }
- /* update some fields */
- f->fifo_index = n + USB_FIFO_TX;
- f->dev_ep_index = dev_ep_index;
- f->priv_mtx = udev->default_mtx;
- f->priv_sc0 = pipe;
- f->methods = &usb2_ugen_methods;
- f->iface_index = iface_index;
- f->udev = udev;
- mtx_lock(&usb2_ref_lock);
- udev->fifo[n + USB_FIFO_TX] = f;
- mtx_unlock(&usb2_ref_lock);
- }
- /* Check RX FIFO */
- if (is_rx &&
- (udev->fifo[n + USB_FIFO_RX] == NULL)) {
-
- pipe = usb2_dev_get_pipe(udev,
- iface_index, dev_ep_index, USB_FIFO_RX);
- if (pipe == NULL) {
- return (EINVAL);
- }
- f = usb2_fifo_alloc();
- if (f == NULL) {
- return (ENOMEM);
- }
- /* update some fields */
- f->fifo_index = n + USB_FIFO_RX;
- f->dev_ep_index = dev_ep_index;
- f->priv_mtx = udev->default_mtx;
- f->priv_sc0 = pipe;
- f->methods = &usb2_ugen_methods;
- f->iface_index = iface_index;
- f->udev = udev;
- mtx_lock(&usb2_ref_lock);
- udev->fifo[n + USB_FIFO_RX] = f;
- mtx_unlock(&usb2_ref_lock);
- }
- if (is_tx) {
- ploc->txfifo = udev->fifo[n + USB_FIFO_TX];
- }
- if (is_rx) {
- ploc->rxfifo = udev->fifo[n + USB_FIFO_RX];
- }
- /* replace endpoint index by FIFO index */
-
- (*pdevloc) %= (USB_BUS_MAX * USB_DEV_MAX * USB_IFACE_MAX);
- (*pdevloc) += (USB_BUS_MAX * USB_DEV_MAX * USB_IFACE_MAX) * n;
-
- /* complete */
-
- return (0);
-}
-
-void
-usb2_fifo_free(struct usb2_fifo *f)
-{
- uint8_t n;
-
- if (f == NULL) {
- /* be NULL safe */
- return;
- }
- /* destroy symlink devices, if any */
- for (n = 0; n != 2; n++) {
- if (f->symlink[n]) {
- usb2_free_symlink(f->symlink[n]);
- f->symlink[n] = NULL;
- }
- }
- mtx_lock(&usb2_ref_lock);
-
- /* delink ourselves to stop calls from userland */
- if ((f->fifo_index < USB_FIFO_MAX) &&
- (f->udev != NULL) &&
- (f->udev->fifo[f->fifo_index] == f)) {
- f->udev->fifo[f->fifo_index] = NULL;
- } else {
- DPRINTFN(0, "USB FIFO %p has not been linked!\n", f);
- }
-
- /* decrease refcount */
- f->refcount--;
- /* prevent any write flush */
- f->flag_iserror = 1;
- /* need to wait until all callers have exited */
- while (f->refcount != 0) {
- mtx_unlock(&usb2_ref_lock); /* avoid LOR */
- mtx_lock(f->priv_mtx);
- /* get I/O thread out of any sleep state */
- if (f->flag_sleeping) {
- f->flag_sleeping = 0;
- usb2_cv_broadcast(&f->cv_io);
- }
- mtx_unlock(f->priv_mtx);
- mtx_lock(&usb2_ref_lock);
-
- /* wait for sync */
- usb2_cv_wait(&f->cv_drain, &usb2_ref_lock);
- }
- mtx_unlock(&usb2_ref_lock);
-
- /* take care of closing the device here, if any */
- usb2_fifo_close(f, curthread, 0);
-
- usb2_cv_destroy(&f->cv_io);
- usb2_cv_destroy(&f->cv_drain);
-
- free(f, M_USBDEV);
-}
-
-static struct usb2_pipe *
-usb2_dev_get_pipe(struct usb2_device *udev,
- uint8_t iface_index, uint8_t ep_index, uint8_t dir)
-{
- struct usb2_pipe *pipe;
- uint8_t ep_dir;
-
- if (ep_index == 0) {
- pipe = &udev->default_pipe;
- } else {
- if (dir == USB_FIFO_RX) {
- if (udev->flags.usb2_mode == USB_MODE_HOST) {
- ep_dir = UE_DIR_IN;
- } else {
- ep_dir = UE_DIR_OUT;
- }
- } else {
- if (udev->flags.usb2_mode == USB_MODE_HOST) {
- ep_dir = UE_DIR_OUT;
- } else {
- ep_dir = UE_DIR_IN;
- }
- }
- pipe = usb2_get_pipe_by_addr(udev, ep_index | ep_dir);
- }
-
- if (pipe == NULL) {
- /* if the pipe does not exist then return */
- return (NULL);
- }
- if (pipe->edesc == NULL) {
- /* invalid pipe */
- return (NULL);
- }
- if (ep_index != 0) {
- if (pipe->iface_index != iface_index) {
- /*
- * Permissions violation - trying to access a
- * pipe that does not belong to the interface.
- */
- return (NULL);
- }
- }
- return (pipe); /* success */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fifo_open
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static int
-usb2_fifo_open(struct usb2_fifo *f, struct file *fp, struct thread *td,
- int fflags)
-{
- int err;
-
- if (f == NULL) {
- /* no FIFO there */
- DPRINTFN(2, "no FIFO\n");
- return (ENXIO);
- }
- /* remove FWRITE and FREAD flags */
- fflags &= ~(FWRITE | FREAD);
-
- /* set correct file flags */
- if ((f->fifo_index & 1) == USB_FIFO_TX) {
- fflags |= FWRITE;
- } else {
- fflags |= FREAD;
- }
-
- /* check if we are already opened */
- /* we don't need any locks when checking this variable */
- if (f->curr_file) {
- err = EBUSY;
- goto done;
- }
- /* call open method */
- err = (f->methods->f_open) (f, fflags, td);
- if (err) {
- goto done;
- }
- mtx_lock(f->priv_mtx);
-
- /* reset sleep flag */
- f->flag_sleeping = 0;
-
- /* reset error flag */
- f->flag_iserror = 0;
-
- /* reset complete flag */
- f->flag_iscomplete = 0;
-
- /* reset select flag */
- f->flag_isselect = 0;
-
- /* reset flushing flag */
- f->flag_flushing = 0;
-
- /* reset ASYNC proc flag */
- f->async_p = NULL;
-
- /* set which file we belong to */
- mtx_lock(&usb2_ref_lock);
- f->curr_file = fp;
- mtx_unlock(&usb2_ref_lock);
-
- /* reset queue */
- usb2_fifo_reset(f);
-
- mtx_unlock(f->priv_mtx);
-done:
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fifo_reset
- *------------------------------------------------------------------------*/
-void
-usb2_fifo_reset(struct usb2_fifo *f)
-{
- struct usb2_mbuf *m;
-
- if (f == NULL) {
- return;
- }
- while (1) {
- USB_IF_DEQUEUE(&f->used_q, m);
- if (m) {
- USB_IF_ENQUEUE(&f->free_q, m);
- } else {
- break;
- }
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fifo_close
- *------------------------------------------------------------------------*/
-static void
-usb2_fifo_close(struct usb2_fifo *f, struct thread *td, int fflags)
-{
- int err;
-
- /* check if we are not opened */
- if (!f->curr_file) {
- /* nothing to do - already closed */
- return;
- }
- mtx_lock(f->priv_mtx);
-
- /* clear current file flag */
- f->curr_file = NULL;
-
- /* check if we are selected */
- if (f->flag_isselect) {
- selwakeup(&f->selinfo);
- f->flag_isselect = 0;
- }
- /* check if a thread wants SIGIO */
- if (f->async_p != NULL) {
- PROC_LOCK(f->async_p);
- psignal(f->async_p, SIGIO);
- PROC_UNLOCK(f->async_p);
- f->async_p = NULL;
- }
- /* remove FWRITE and FREAD flags */
- fflags &= ~(FWRITE | FREAD);
-
- /* flush written data, if any */
- if ((f->fifo_index & 1) == USB_FIFO_TX) {
-
- if (!f->flag_iserror) {
-
- /* set flushing flag */
- f->flag_flushing = 1;
-
- /* start write transfer, if not already started */
- (f->methods->f_start_write) (f);
-
- /* check if flushed already */
- while (f->flag_flushing &&
- (!f->flag_iserror)) {
- /* wait until all data has been written */
- f->flag_sleeping = 1;
- err = usb2_cv_wait_sig(&f->cv_io, f->priv_mtx);
- if (err) {
- DPRINTF("signal received\n");
- break;
- }
- }
- }
- fflags |= FWRITE;
-
- /* stop write transfer, if not already stopped */
- (f->methods->f_stop_write) (f);
- } else {
- fflags |= FREAD;
-
- /* stop write transfer, if not already stopped */
- (f->methods->f_stop_read) (f);
- }
-
- /* check if we are sleeping */
- if (f->flag_sleeping) {
- DPRINTFN(2, "Sleeping at close!\n");
- }
- mtx_unlock(f->priv_mtx);
-
- /* call close method */
- (f->methods->f_close) (f, fflags, td);
-
- DPRINTF("closed\n");
-}
-
-/*------------------------------------------------------------------------*
- * usb2_check_thread_perm
- *
- * Returns:
- * 0: Has permission.
- * Else: No permission.
- *------------------------------------------------------------------------*/
-int
-usb2_check_thread_perm(struct usb2_device *udev, struct thread *td,
- int fflags, uint8_t iface_index, uint8_t ep_index)
-{
- struct usb2_interface *iface;
- int err;
-
- if (ep_index != 0) {
- /*
- * Non-control endpoints are always
- * associated with an interface:
- */
- iface = usb2_get_iface(udev, iface_index);
- if (iface == NULL) {
- return (EINVAL);
- }
- if (iface->idesc == NULL) {
- return (EINVAL);
- }
- } else {
- iface = NULL;
- }
- /* scan down the permissions tree */
- if ((iface != NULL) &&
- (usb2_check_access(fflags, &iface->perm) == 0)) {
- /* we got access through the interface */
- err = 0;
- } else if (udev &&
- (usb2_check_access(fflags, &udev->perm) == 0)) {
- /* we got access through the device */
- err = 0;
- } else if (udev->bus &&
- (usb2_check_access(fflags, &udev->bus->perm) == 0)) {
- /* we got access through the USB bus */
- err = 0;
- } else if (usb2_check_access(fflags, &usb2_perm) == 0) {
- /* we got general access */
- err = 0;
- } else {
- /* no access */
- err = EPERM;
- }
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fdopen - cdev callback
- *------------------------------------------------------------------------*/
-static int
-usb2_fdopen(struct cdev *dev, int xxx_oflags, struct thread *td,
- struct file *fp)
-{
- struct usb2_location loc;
- uint32_t devloc;
- int err;
- int fflags;
-
- DPRINTFN(2, "oflags=0x%08x\n", xxx_oflags);
-
- devloc = usb2_last_devloc;
- usb2_last_devloc = (0 - 1); /* reset "usb2_last_devloc" */
-
- if (fp == NULL) {
- DPRINTFN(2, "fp == NULL\n");
- return (ENXIO);
- }
- if (usb2_old_f_data != fp->f_data) {
- if (usb2_old_f_data != NULL) {
- DPRINTFN(0, "File data mismatch!\n");
- return (ENXIO);
- }
- usb2_old_f_data = fp->f_data;
- }
- if (usb2_old_f_ops != fp->f_ops) {
- if (usb2_old_f_ops != NULL) {
- DPRINTFN(0, "File ops mismatch!\n");
- return (ENXIO);
- }
- usb2_old_f_ops = fp->f_ops;
- }
- fflags = fp->f_flag;
- DPRINTFN(2, "fflags=0x%08x\n", fflags);
-
- if (!(fflags & (FREAD | FWRITE))) {
- /* should not happen */
- return (EPERM);
- }
- if (devloc == (uint32_t)(0 - 2)) {
- /* tried to open "/dev/usb" */
- return (0);
- } else if (devloc == (uint32_t)(0 - 1)) {
- /* tried to open "/dev/usb " */
- DPRINTFN(2, "no devloc\n");
- return (ENXIO);
- }
- err = usb2_ref_device(NULL, &loc, devloc);
- if (err) {
- DPRINTFN(2, "cannot ref device\n");
- return (ENXIO);
- }
- /*
- * NOTE: Variable overloading. "usb2_fifo_create" will update
- * the FIFO index. Right here we can assume that the
- * "fifo_index" is the same like the endpoint number without
- * direction mask, if the "fifo_index" is less than 16.
- */
- err = usb2_check_thread_perm(loc.udev, td, fflags,
- loc.iface_index, loc.fifo_index);
-
- /* check for error */
- if (err) {
- usb2_unref_device(&loc);
- return (err);
- }
- /* create FIFOs, if any */
- err = usb2_fifo_create(&loc, &devloc, fflags);
- /* check for error */
- if (err) {
- usb2_unref_device(&loc);
- return (err);
- }
- if (fflags & FREAD) {
- err = usb2_fifo_open(loc.rxfifo, fp, td, fflags);
- if (err) {
- DPRINTFN(2, "read open failed\n");
- usb2_unref_device(&loc);
- return (err);
- }
- }
- if (fflags & FWRITE) {
- err = usb2_fifo_open(loc.txfifo, fp, td, fflags);
- if (err) {
- DPRINTFN(2, "write open failed\n");
- if (fflags & FREAD) {
- usb2_fifo_close(loc.rxfifo, td,
- fflags);
- }
- usb2_unref_device(&loc);
- return (err);
- }
- }
- /*
- * Take over the file so that we get all the callbacks
- * directly and don't have to create another device:
- */
- finit(fp, fp->f_flag, DTYPE_VNODE,
- ((uint8_t *)0) + devloc, &usb2_ops_f);
-
- usb2_unref_device(&loc);
-
- DPRINTFN(2, "error=%d\n", err);
-
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_close - cdev callback
- *------------------------------------------------------------------------*/
-static int
-usb2_close(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- DPRINTF("\n");
- return (0); /* nothing to do */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_close - cdev callback
- *------------------------------------------------------------------------*/
-static int
-usb2_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
- int fflag, struct thread *td)
-{
- union {
- struct usb2_read_dir *urd;
- struct usb2_dev_perm *udp;
- void *data;
- } u;
- int err;
-
- u.data = data;
-
- switch (cmd) {
- case USB_READ_DIR:
- err = usb2_read_symlink(u.urd->urd_data,
- u.urd->urd_startentry, u.urd->urd_maxlen);
- break;
- case USB_SET_IFACE_PERM:
- err = usb2_set_perm(u.udp, 3);
- break;
- case USB_SET_DEVICE_PERM:
- err = usb2_set_perm(u.udp, 2);
- break;
- case USB_SET_BUS_PERM:
- err = usb2_set_perm(u.udp, 1);
- break;
- case USB_SET_ROOT_PERM:
- err = usb2_set_perm(u.udp, 0);
- break;
- case USB_GET_IFACE_PERM:
- err = usb2_get_perm(u.udp, 3);
- break;
- case USB_GET_DEVICE_PERM:
- err = usb2_get_perm(u.udp, 2);
- break;
- case USB_GET_BUS_PERM:
- err = usb2_get_perm(u.udp, 1);
- break;
- case USB_GET_ROOT_PERM:
- err = usb2_get_perm(u.udp, 0);
- break;
- case USB_DEV_QUIRK_GET:
- case USB_QUIRK_NAME_GET:
- case USB_DEV_QUIRK_ADD:
- case USB_DEV_QUIRK_REMOVE:
- err = usb2_quirk_ioctl_p(cmd, data, fflag, td);
- break;
- default:
- err = ENOTTY;
- break;
- }
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_clone - cdev callback
- *
- * This function is the kernel clone callback for "/dev/usbX.Y".
- *
- * NOTE: This function assumes that the clone and device open
- * operation is atomic.
- *------------------------------------------------------------------------*/
-static void
-usb2_clone(void *arg, USB_UCRED char *name, int namelen, struct cdev **dev)
-{
- enum {
- USB_DNAME_LEN = sizeof(USB_DEVICE_NAME) - 1,
- USB_GNAME_LEN = sizeof(USB_GENERIC_NAME) - 1,
- };
-
- if (*dev) {
- /* someone else has created a device */
- return;
- }
- /* reset device location */
- usb2_last_devloc = (uint32_t)(0 - 1);
-
- /*
- * Check if we are matching "usb", "ugen" or an internal
- * symbolic link:
- */
- if ((namelen >= USB_DNAME_LEN) &&
- (bcmp(name, USB_DEVICE_NAME, USB_DNAME_LEN) == 0)) {
- if (namelen == USB_DNAME_LEN) {
- /* USB management device location */
- usb2_last_devloc = (uint32_t)(0 - 2);
- } else {
- /* USB endpoint */
- usb2_last_devloc =
- usb2_path_convert(name + USB_DNAME_LEN);
- }
- } else if ((namelen >= USB_GNAME_LEN) &&
- (bcmp(name, USB_GENERIC_NAME, USB_GNAME_LEN) == 0)) {
- if (namelen == USB_GNAME_LEN) {
- /* USB management device location */
- usb2_last_devloc = (uint32_t)(0 - 2);
- } else {
- /* USB endpoint */
- usb2_last_devloc =
- usb2_path_convert(name + USB_GNAME_LEN);
- }
- }
- if (usb2_last_devloc == (uint32_t)(0 - 1)) {
- /* Search for symbolic link */
- usb2_last_devloc =
- usb2_lookup_symlink(name, namelen);
- }
- if (usb2_last_devloc == (uint32_t)(0 - 1)) {
- /* invalid location */
- return;
- }
- dev_ref(usb2_dev);
- *dev = usb2_dev;
-}
-
-static void
-usb2_dev_init(void *arg)
-{
- mtx_init(&usb2_ref_lock, "USB ref mutex", NULL, MTX_DEF);
- sx_init(&usb2_sym_lock, "USB sym mutex");
- TAILQ_INIT(&usb2_sym_head);
-
- /* check the UGEN methods */
- usb2_fifo_check_methods(&usb2_ugen_methods);
-}
-
-SYSINIT(usb2_dev_init, SI_SUB_KLD, SI_ORDER_FIRST, usb2_dev_init, NULL);
-
-static void
-usb2_dev_init_post(void *arg)
-{
- /*
- * Create a dummy device so that we are visible. This device
- * should never be opened. Therefore a space character is
- * appended after the USB device name.
- *
- * NOTE: The permissions of this device is 0666, because we
- * check the permissions again in the open routine against the
- * real USB permissions which are not 0666. Else USB access
- * will be limited to one user and one group.
- */
- usb2_dev = make_dev(&usb2_devsw, 0, UID_ROOT, GID_OPERATOR,
- 0666, USB_DEVICE_NAME " ");
- if (usb2_dev == NULL) {
- DPRINTFN(0, "Could not create usb bus device!\n");
- }
- usb2_clone_tag = EVENTHANDLER_REGISTER(dev_clone, usb2_clone_ptr, NULL, 1000);
- if (usb2_clone_tag == NULL) {
- DPRINTFN(0, "Registering clone handler failed!\n");
- }
-}
-
-SYSINIT(usb2_dev_init_post, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, usb2_dev_init_post, NULL);
-
-static void
-usb2_dev_uninit(void *arg)
-{
- if (usb2_clone_tag) {
- EVENTHANDLER_DEREGISTER(dev_clone, usb2_clone_tag);
- usb2_clone_tag = NULL;
- }
- if (usb2_dev) {
- destroy_dev(usb2_dev);
- usb2_dev = NULL;
- }
- mtx_destroy(&usb2_ref_lock);
- sx_destroy(&usb2_sym_lock);
-}
-
-SYSUNINIT(usb2_dev_uninit, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb2_dev_uninit, NULL);
-
-static int
-usb2_close_f(struct file *fp, struct thread *td)
-{
- struct usb2_location loc;
- int fflags;
- int err;
-
- fflags = fp->f_flag;
-
- DPRINTFN(2, "fflags=%u\n", fflags);
-
- err = usb2_ref_device(fp, &loc, 0 /* need uref */ );;
-
- /* restore some file variables */
- fp->f_ops = usb2_old_f_ops;
- fp->f_data = usb2_old_f_data;
-
- /* check for error */
- if (err) {
- DPRINTFN(2, "could not ref\n");
- goto done;
- }
- if (fflags & FREAD) {
- usb2_fifo_close(loc.rxfifo, td, fflags);
- }
- if (fflags & FWRITE) {
- usb2_fifo_close(loc.txfifo, td, fflags);
- }
- usb2_unref_device(&loc);
-
-done:
- /* call old close method */
- USB_VNOPS_FO_CLOSE(fp, td, &err);
-
- return (err);
-}
-
-static int
-usb2_ioctl_f_sub(struct usb2_fifo *f, u_long cmd, void *addr,
- struct thread *td)
-{
- int error = 0;
-
- switch (cmd) {
- case FIODTYPE:
- *(int *)addr = 0; /* character device */
- break;
-
- case FIONBIO:
- /* handled by upper FS layer */
- break;
-
- case FIOASYNC:
- if (*(int *)addr) {
- if (f->async_p != NULL) {
- error = EBUSY;
- break;
- }
- f->async_p = USB_TD_GET_PROC(td);
- } else {
- f->async_p = NULL;
- }
- break;
-
- /* XXX this is not the most general solution */
- case TIOCSPGRP:
- if (f->async_p == NULL) {
- error = EINVAL;
- break;
- }
- if (*(int *)addr != USB_PROC_GET_GID(f->async_p)) {
- error = EPERM;
- break;
- }
- break;
- default:
- return (ENOIOCTL);
- }
- return (error);
-}
-
-static int
-usb2_ioctl_f(struct file *fp, u_long cmd, void *addr,
- struct ucred *cred, struct thread *td)
-{
- struct usb2_location loc;
- struct usb2_fifo *f;
- int fflags;
- int err;
-
- err = usb2_ref_device(fp, &loc, 1 /* no uref */ );;
- if (err) {
- return (ENXIO);
- }
- fflags = fp->f_flag;
-
- DPRINTFN(2, "fflags=%u, cmd=0x%lx\n", fflags, cmd);
-
- f = NULL; /* set default value */
- err = ENOIOCTL; /* set default value */
-
- if (fflags & FWRITE) {
- f = loc.txfifo;
- err = usb2_ioctl_f_sub(f, cmd, addr, td);
- }
- if (fflags & FREAD) {
- f = loc.rxfifo;
- err = usb2_ioctl_f_sub(f, cmd, addr, td);
- }
- if (err == ENOIOCTL) {
- err = (f->methods->f_ioctl) (f, cmd, addr, fflags, td);
- if (err == ENOIOCTL) {
- if (usb2_uref_location(&loc)) {
- err = ENXIO;
- goto done;
- }
- err = (f->methods->f_ioctl_post) (f, cmd, addr, fflags, td);
- }
- }
- if (err == ENOIOCTL) {
- err = ENOTTY;
- }
-done:
- usb2_unref_device(&loc);
- return (err);
-}
-
-/* ARGSUSED */
-static int
-usb2_kqfilter_f(struct file *fp, struct knote *kn)
-{
- return (ENXIO);
-}
-
-/* ARGSUSED */
-static int
-usb2_poll_f(struct file *fp, int events,
- struct ucred *cred, struct thread *td)
-{
- struct usb2_location loc;
- struct usb2_fifo *f;
- struct usb2_mbuf *m;
- int fflags;
- int revents;
-
- revents = usb2_ref_device(fp, &loc, 1 /* no uref */ );;
- if (revents) {
- return (POLLHUP);
- }
- fflags = fp->f_flag;
-
- /* Figure out who needs service */
-
- if ((events & (POLLOUT | POLLWRNORM)) &&
- (fflags & FWRITE)) {
-
- f = loc.txfifo;
-
- mtx_lock(f->priv_mtx);
-
- if (!loc.is_usbfs) {
- if (f->flag_iserror) {
- /* we got an error */
- m = (void *)1;
- } else {
- if (f->queue_data == NULL) {
- /*
- * start write transfer, if not
- * already started
- */
- (f->methods->f_start_write) (f);
- }
- /* check if any packets are available */
- USB_IF_POLL(&f->free_q, m);
- }
- } else {
- if (f->flag_iscomplete) {
- m = (void *)1;
- } else {
- m = NULL;
- }
- }
-
- if (m) {
- revents |= events & (POLLOUT | POLLWRNORM);
- } else {
- f->flag_isselect = 1;
- selrecord(td, &f->selinfo);
- }
-
- mtx_unlock(f->priv_mtx);
- }
- if ((events & (POLLIN | POLLRDNORM)) &&
- (fflags & FREAD)) {
-
- f = loc.rxfifo;
-
- mtx_lock(f->priv_mtx);
-
- if (!loc.is_usbfs) {
- if (f->flag_iserror) {
- /* we have and error */
- m = (void *)1;
- } else {
- if (f->queue_data == NULL) {
- /*
- * start read transfer, if not
- * already started
- */
- (f->methods->f_start_read) (f);
- }
- /* check if any packets are available */
- USB_IF_POLL(&f->used_q, m);
- }
- } else {
- if (f->flag_iscomplete) {
- m = (void *)1;
- } else {
- m = NULL;
- }
- }
-
- if (m) {
- revents |= events & (POLLIN | POLLRDNORM);
- } else {
- f->flag_isselect = 1;
- selrecord(td, &f->selinfo);
-
- if (!loc.is_usbfs) {
- /* start reading data */
- (f->methods->f_start_read) (f);
- }
- }
-
- mtx_unlock(f->priv_mtx);
- }
- usb2_unref_device(&loc);
- return (revents);
-}
-
-/* ARGSUSED */
-static int
-usb2_read_f(struct file *fp, struct uio *uio, struct ucred *cred,
- int flags, struct thread *td)
-{
- struct usb2_location loc;
- struct usb2_fifo *f;
- struct usb2_mbuf *m;
- int fflags;
- int resid;
- int io_len;
- int err;
- uint8_t tr_data = 0;
-
- DPRINTFN(2, "\n");
-
- fflags = fp->f_flag & (O_NONBLOCK | O_DIRECT | FREAD | FWRITE);
- if (fflags & O_DIRECT)
- fflags |= IO_DIRECT;
-
- err = usb2_ref_device(fp, &loc, 1 /* no uref */ );
- if (err) {
- return (ENXIO);
- }
- f = loc.rxfifo;
- if (f == NULL) {
- /* should not happen */
- return (EPERM);
- }
- resid = uio->uio_resid;
-
- if ((flags & FOF_OFFSET) == 0)
- uio->uio_offset = fp->f_offset;
-
- mtx_lock(f->priv_mtx);
-
- /* check for permanent read error */
- if (f->flag_iserror) {
- err = EIO;
- goto done;
- }
- /* check if USB-FS interface is active */
- if (loc.is_usbfs) {
- /*
- * The queue is used for events that should be
- * retrieved using the "USB_FS_COMPLETE" ioctl.
- */
- err = EINVAL;
- goto done;
- }
- while (uio->uio_resid > 0) {
-
- USB_IF_DEQUEUE(&f->used_q, m);
-
- if (m == NULL) {
-
- /* start read transfer, if not already started */
-
- (f->methods->f_start_read) (f);
-
- if (fflags & O_NONBLOCK) {
- if (tr_data) {
- /* return length before error */
- break;
- }
- err = EWOULDBLOCK;
- break;
- }
- DPRINTF("sleeping\n");
-
- err = usb2_fifo_wait(f);
- if (err) {
- break;
- }
- continue;
- }
- if (f->methods->f_filter_read) {
- /*
- * Sometimes it is convenient to process data at the
- * expense of a userland process instead of a kernel
- * process.
- */
- (f->methods->f_filter_read) (f, m);
- }
- tr_data = 1;
-
- io_len = MIN(m->cur_data_len, uio->uio_resid);
-
- DPRINTFN(2, "transfer %d bytes from %p\n",
- io_len, m->cur_data_ptr);
-
- err = usb2_fifo_uiomove(f,
- m->cur_data_ptr, io_len, uio);
-
- m->cur_data_len -= io_len;
- m->cur_data_ptr += io_len;
-
- if (m->cur_data_len == 0) {
-
- uint8_t last_packet;
-
- last_packet = m->last_packet;
-
- USB_IF_ENQUEUE(&f->free_q, m);
-
- if (last_packet) {
- /* keep framing */
- break;
- }
- } else {
- USB_IF_PREPEND(&f->used_q, m);
- }
-
- if (err) {
- break;
- }
- }
-done:
- mtx_unlock(f->priv_mtx);
-
- usb2_unref_device(&loc);
-
- if ((flags & FOF_OFFSET) == 0)
- fp->f_offset = uio->uio_offset;
- fp->f_nextoff = uio->uio_offset;
- return (err);
-}
-
-static int
-usb2_stat_f(struct file *fp, struct stat *sb, struct ucred *cred, struct thread *td)
-{
- return (USB_VNOPS_FO_STAT(fp, sb, cred, td));
-}
-
-#if __FreeBSD_version > 800009
-static int
-usb2_truncate_f(struct file *fp, off_t length, struct ucred *cred, struct thread *td)
-{
- return (USB_VNOPS_FO_TRUNCATE(fp, length, cred, td));
-}
-
-#endif
-
-/* ARGSUSED */
-static int
-usb2_write_f(struct file *fp, struct uio *uio, struct ucred *cred,
- int flags, struct thread *td)
-{
- struct usb2_location loc;
- struct usb2_fifo *f;
- struct usb2_mbuf *m;
- int fflags;
- int resid;
- int io_len;
- int err;
- uint8_t tr_data = 0;
-
- DPRINTFN(2, "\n");
-
- fflags = fp->f_flag & (O_NONBLOCK | O_DIRECT |
- FREAD | FWRITE | O_FSYNC);
- if (fflags & O_DIRECT)
- fflags |= IO_DIRECT;
-
- err = usb2_ref_device(fp, &loc, 1 /* no uref */ );
- if (err) {
- return (ENXIO);
- }
- f = loc.txfifo;
- if (f == NULL) {
- /* should not happen */
- usb2_unref_device(&loc);
- return (EPERM);
- }
- resid = uio->uio_resid;
-
- if ((flags & FOF_OFFSET) == 0)
- uio->uio_offset = fp->f_offset;
-
- mtx_lock(f->priv_mtx);
-
- /* check for permanent write error */
- if (f->flag_iserror) {
- err = EIO;
- goto done;
- }
- /* check if USB-FS interface is active */
- if (loc.is_usbfs) {
- /*
- * The queue is used for events that should be
- * retrieved using the "USB_FS_COMPLETE" ioctl.
- */
- err = EINVAL;
- goto done;
- }
- if (f->queue_data == NULL) {
- /* start write transfer, if not already started */
- (f->methods->f_start_write) (f);
- }
- /* we allow writing zero length data */
- do {
- USB_IF_DEQUEUE(&f->free_q, m);
-
- if (m == NULL) {
-
- if (fflags & O_NONBLOCK) {
- if (tr_data) {
- /* return length before error */
- break;
- }
- err = EWOULDBLOCK;
- break;
- }
- DPRINTF("sleeping\n");
-
- err = usb2_fifo_wait(f);
- if (err) {
- break;
- }
- continue;
- }
- tr_data = 1;
-
- USB_MBUF_RESET(m);
-
- io_len = MIN(m->cur_data_len, uio->uio_resid);
-
- m->cur_data_len = io_len;
-
- DPRINTFN(2, "transfer %d bytes to %p\n",
- io_len, m->cur_data_ptr);
-
- err = usb2_fifo_uiomove(f,
- m->cur_data_ptr, io_len, uio);
-
- if (err) {
- USB_IF_ENQUEUE(&f->free_q, m);
- break;
- }
- if (f->methods->f_filter_write) {
- /*
- * Sometimes it is convenient to process data at the
- * expense of a userland process instead of a kernel
- * process.
- */
- (f->methods->f_filter_write) (f, m);
- }
- USB_IF_ENQUEUE(&f->used_q, m);
-
- (f->methods->f_start_write) (f);
-
- } while (uio->uio_resid > 0);
-done:
- mtx_unlock(f->priv_mtx);
-
- usb2_unref_device(&loc);
-
- if ((flags & FOF_OFFSET) == 0)
- fp->f_offset = uio->uio_offset;
- fp->f_nextoff = uio->uio_offset;
-
- return (err);
-}
-
-static int
-usb2_fifo_uiomove(struct usb2_fifo *f, void *cp,
- int n, struct uio *uio)
-{
- int error;
-
- mtx_unlock(f->priv_mtx);
-
- /*
- * "uiomove()" can sleep so one needs to make a wrapper,
- * exiting the mutex and checking things:
- */
- error = uiomove(cp, n, uio);
-
- mtx_lock(f->priv_mtx);
-
- return (error);
-}
-
-int
-usb2_fifo_wait(struct usb2_fifo *f)
-{
- int err;
-
- mtx_assert(f->priv_mtx, MA_OWNED);
-
- if (f->flag_iserror) {
- /* we are gone */
- return (EIO);
- }
- f->flag_sleeping = 1;
-
- err = usb2_cv_wait_sig(&f->cv_io, f->priv_mtx);
-
- if (f->flag_iserror) {
- /* we are gone */
- err = EIO;
- }
- return (err);
-}
-
-void
-usb2_fifo_signal(struct usb2_fifo *f)
-{
- if (f->flag_sleeping) {
- f->flag_sleeping = 0;
- usb2_cv_broadcast(&f->cv_io);
- }
-}
-
-void
-usb2_fifo_wakeup(struct usb2_fifo *f)
-{
- usb2_fifo_signal(f);
-
- if (f->flag_isselect) {
- selwakeup(&f->selinfo);
- f->flag_isselect = 0;
- }
- if (f->async_p != NULL) {
- PROC_LOCK(f->async_p);
- psignal(f->async_p, SIGIO);
- PROC_UNLOCK(f->async_p);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fifo_opened
- *
- * Returns:
- * 0: FIFO not opened.
- * Else: FIFO is opened.
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_fifo_opened(struct usb2_fifo *f)
-{
- uint8_t temp;
- uint8_t do_unlock;
-
- if (f == NULL) {
- return (0); /* be NULL safe */
- }
- if (mtx_owned(f->priv_mtx)) {
- do_unlock = 0;
- } else {
- do_unlock = 1;
- mtx_lock(f->priv_mtx);
- }
- temp = f->curr_file ? 1 : 0;
- if (do_unlock) {
- mtx_unlock(f->priv_mtx);
- }
- return (temp);
-}
-
-
-static int
-usb2_fifo_dummy_open(struct usb2_fifo *fifo,
- int fflags, struct thread *td)
-{
- return (0);
-}
-
-static void
-usb2_fifo_dummy_close(struct usb2_fifo *fifo,
- int fflags, struct thread *td)
-{
- return;
-}
-
-static int
-usb2_fifo_dummy_ioctl(struct usb2_fifo *fifo, u_long cmd, void *addr,
- int fflags, struct thread *td)
-{
- return (ENOIOCTL);
-}
-
-static void
-usb2_fifo_dummy_cmd(struct usb2_fifo *fifo)
-{
- fifo->flag_flushing = 0; /* not flushing */
-}
-
-static void
-usb2_fifo_check_methods(struct usb2_fifo_methods *pm)
-{
- /* check that all callback functions are OK */
-
- if (pm->f_open == NULL)
- pm->f_open = &usb2_fifo_dummy_open;
-
- if (pm->f_close == NULL)
- pm->f_close = &usb2_fifo_dummy_close;
-
- if (pm->f_ioctl == NULL)
- pm->f_ioctl = &usb2_fifo_dummy_ioctl;
-
- if (pm->f_ioctl_post == NULL)
- pm->f_ioctl_post = &usb2_fifo_dummy_ioctl;
-
- if (pm->f_start_read == NULL)
- pm->f_start_read = &usb2_fifo_dummy_cmd;
-
- if (pm->f_stop_read == NULL)
- pm->f_stop_read = &usb2_fifo_dummy_cmd;
-
- if (pm->f_start_write == NULL)
- pm->f_start_write = &usb2_fifo_dummy_cmd;
-
- if (pm->f_stop_write == NULL)
- pm->f_stop_write = &usb2_fifo_dummy_cmd;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fifo_attach
- *
- * The following function will create a duplex FIFO.
- *
- * Return values:
- * 0: Success.
- * Else: Failure.
- *------------------------------------------------------------------------*/
-int
-usb2_fifo_attach(struct usb2_device *udev, void *priv_sc,
- struct mtx *priv_mtx, struct usb2_fifo_methods *pm,
- struct usb2_fifo_sc *f_sc, uint16_t unit, uint16_t subunit,
- uint8_t iface_index)
-{
- struct usb2_fifo *f_tx;
- struct usb2_fifo *f_rx;
- char buf[32];
- char src[32];
- uint8_t n;
-
- f_sc->fp[USB_FIFO_TX] = NULL;
- f_sc->fp[USB_FIFO_RX] = NULL;
-
- if (pm == NULL)
- return (EINVAL);
-
- /* check the methods */
- usb2_fifo_check_methods(pm);
-
- if (priv_mtx == NULL)
- priv_mtx = &Giant;
-
- /* search for a free FIFO slot */
- for (n = 0;; n += 2) {
-
- if (n == USB_FIFO_MAX) {
- /* end of FIFOs reached */
- return (ENOMEM);
- }
- /* Check for TX FIFO */
- if (udev->fifo[n + USB_FIFO_TX] != NULL) {
- continue;
- }
- /* Check for RX FIFO */
- if (udev->fifo[n + USB_FIFO_RX] != NULL) {
- continue;
- }
- break;
- }
-
- f_tx = usb2_fifo_alloc();
- f_rx = usb2_fifo_alloc();
-
- if ((f_tx == NULL) || (f_rx == NULL)) {
- usb2_fifo_free(f_tx);
- usb2_fifo_free(f_rx);
- return (ENOMEM);
- }
- /* initialise FIFO structures */
-
- f_tx->fifo_index = n + USB_FIFO_TX;
- f_tx->dev_ep_index = (n / 2) + (USB_EP_MAX / 2);
- f_tx->priv_mtx = priv_mtx;
- f_tx->priv_sc0 = priv_sc;
- f_tx->methods = pm;
- f_tx->iface_index = iface_index;
- f_tx->udev = udev;
-
- f_rx->fifo_index = n + USB_FIFO_RX;
- f_rx->dev_ep_index = (n / 2) + (USB_EP_MAX / 2);
- f_rx->priv_mtx = priv_mtx;
- f_rx->priv_sc0 = priv_sc;
- f_rx->methods = pm;
- f_rx->iface_index = iface_index;
- f_rx->udev = udev;
-
- f_sc->fp[USB_FIFO_TX] = f_tx;
- f_sc->fp[USB_FIFO_RX] = f_rx;
-
- mtx_lock(&usb2_ref_lock);
- udev->fifo[f_tx->fifo_index] = f_tx;
- udev->fifo[f_rx->fifo_index] = f_rx;
- mtx_unlock(&usb2_ref_lock);
-
- if (snprintf(src, sizeof(src),
- USB_DEVICE_NAME "%u.%u.%u.%u",
- device_get_unit(udev->bus->bdev),
- udev->device_index,
- iface_index,
- f_tx->dev_ep_index)) {
- /* ignore */
- }
- for (n = 0; n != 4; n++) {
-
- if (pm->basename[n] == NULL) {
- continue;
- }
- if (subunit == 0xFFFF) {
- if (snprintf(buf, sizeof(buf),
- "%s%u%s", pm->basename[n],
- unit, pm->postfix[n] ?
- pm->postfix[n] : "")) {
- /* ignore */
- }
- } else {
- if (snprintf(buf, sizeof(buf),
- "%s%u.%u%s", pm->basename[n],
- unit, subunit, pm->postfix[n] ?
- pm->postfix[n] : "")) {
- /* ignore */
- }
- }
-
- /*
- * Distribute the symbolic links into two FIFO structures:
- */
- if (n & 1) {
- f_rx->symlink[n / 2] =
- usb2_alloc_symlink(src, "%s", buf);
- } else {
- f_tx->symlink[n / 2] =
- usb2_alloc_symlink(src, "%s", buf);
- }
- printf("Symlink: %s -> %s\n", buf, src);
- }
-
- DPRINTFN(2, "attached %p/%p\n", f_tx, f_rx);
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fifo_alloc_buffer
- *
- * Return values:
- * 0: Success
- * Else failure
- *------------------------------------------------------------------------*/
-int
-usb2_fifo_alloc_buffer(struct usb2_fifo *f, uint32_t bufsize,
- uint16_t nbuf)
-{
- usb2_fifo_free_buffer(f);
-
- /* allocate an endpoint */
- f->free_q.ifq_maxlen = nbuf;
- f->used_q.ifq_maxlen = nbuf;
-
- f->queue_data = usb2_alloc_mbufs(
- M_USBDEV, &f->free_q, bufsize, nbuf);
-
- if ((f->queue_data == NULL) && bufsize && nbuf) {
- return (ENOMEM);
- }
- return (0); /* success */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fifo_free_buffer
- *
- * This function will free the buffers associated with a FIFO. This
- * function can be called multiple times in a row.
- *------------------------------------------------------------------------*/
-void
-usb2_fifo_free_buffer(struct usb2_fifo *f)
-{
- if (f->queue_data) {
- /* free old buffer */
- free(f->queue_data, M_USBDEV);
- f->queue_data = NULL;
- }
- /* reset queues */
-
- bzero(&f->free_q, sizeof(f->free_q));
- bzero(&f->used_q, sizeof(f->used_q));
-}
-
-void
-usb2_fifo_detach(struct usb2_fifo_sc *f_sc)
-{
- if (f_sc == NULL) {
- return;
- }
- usb2_fifo_free(f_sc->fp[USB_FIFO_TX]);
- usb2_fifo_free(f_sc->fp[USB_FIFO_RX]);
-
- f_sc->fp[USB_FIFO_TX] = NULL;
- f_sc->fp[USB_FIFO_RX] = NULL;
-
- DPRINTFN(2, "detached %p\n", f_sc);
-}
-
-uint32_t
-usb2_fifo_put_bytes_max(struct usb2_fifo *f)
-{
- struct usb2_mbuf *m;
- uint32_t len;
-
- USB_IF_POLL(&f->free_q, m);
-
- if (m) {
- len = m->max_data_len;
- } else {
- len = 0;
- }
- return (len);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fifo_put_data
- *
- * what:
- * 0 - normal operation
- * 1 - set last packet flag to enforce framing
- *------------------------------------------------------------------------*/
-void
-usb2_fifo_put_data(struct usb2_fifo *f, struct usb2_page_cache *pc,
- uint32_t offset, uint32_t len, uint8_t what)
-{
- struct usb2_mbuf *m;
- uint32_t io_len;
-
- while (len || (what == 1)) {
-
- USB_IF_DEQUEUE(&f->free_q, m);
-
- if (m) {
- USB_MBUF_RESET(m);
-
- io_len = MIN(len, m->cur_data_len);
-
- usb2_copy_out(pc, offset, m->cur_data_ptr, io_len);
-
- m->cur_data_len = io_len;
- offset += io_len;
- len -= io_len;
-
- if ((len == 0) && (what == 1)) {
- m->last_packet = 1;
- }
- USB_IF_ENQUEUE(&f->used_q, m);
-
- usb2_fifo_wakeup(f);
-
- if ((len == 0) || (what == 1)) {
- break;
- }
- } else {
- break;
- }
- }
-}
-
-void
-usb2_fifo_put_data_linear(struct usb2_fifo *f, void *ptr,
- uint32_t len, uint8_t what)
-{
- struct usb2_mbuf *m;
- uint32_t io_len;
-
- while (len || (what == 1)) {
-
- USB_IF_DEQUEUE(&f->free_q, m);
-
- if (m) {
- USB_MBUF_RESET(m);
-
- io_len = MIN(len, m->cur_data_len);
-
- bcopy(ptr, m->cur_data_ptr, io_len);
-
- m->cur_data_len = io_len;
- ptr = USB_ADD_BYTES(ptr, io_len);
- len -= io_len;
-
- if ((len == 0) && (what == 1)) {
- m->last_packet = 1;
- }
- USB_IF_ENQUEUE(&f->used_q, m);
-
- usb2_fifo_wakeup(f);
-
- if ((len == 0) || (what == 1)) {
- break;
- }
- } else {
- break;
- }
- }
-}
-
-uint8_t
-usb2_fifo_put_data_buffer(struct usb2_fifo *f, void *ptr, uint32_t len)
-{
- struct usb2_mbuf *m;
-
- USB_IF_DEQUEUE(&f->free_q, m);
-
- if (m) {
- m->cur_data_len = len;
- m->cur_data_ptr = ptr;
- USB_IF_ENQUEUE(&f->used_q, m);
- usb2_fifo_wakeup(f);
- return (1);
- }
- return (0);
-}
-
-void
-usb2_fifo_put_data_error(struct usb2_fifo *f)
-{
- f->flag_iserror = 1;
- usb2_fifo_wakeup(f);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fifo_get_data
- *
- * what:
- * 0 - normal operation
- * 1 - only get one "usb2_mbuf"
- *
- * returns:
- * 0 - no more data
- * 1 - data in buffer
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_fifo_get_data(struct usb2_fifo *f, struct usb2_page_cache *pc,
- uint32_t offset, uint32_t len, uint32_t *actlen,
- uint8_t what)
-{
- struct usb2_mbuf *m;
- uint32_t io_len;
- uint8_t tr_data = 0;
-
- actlen[0] = 0;
-
- while (1) {
-
- USB_IF_DEQUEUE(&f->used_q, m);
-
- if (m) {
-
- tr_data = 1;
-
- io_len = MIN(len, m->cur_data_len);
-
- usb2_copy_in(pc, offset, m->cur_data_ptr, io_len);
-
- len -= io_len;
- offset += io_len;
- actlen[0] += io_len;
- m->cur_data_ptr += io_len;
- m->cur_data_len -= io_len;
-
- if ((m->cur_data_len == 0) || (what == 1)) {
- USB_IF_ENQUEUE(&f->free_q, m);
-
- usb2_fifo_wakeup(f);
-
- if (what == 1) {
- break;
- }
- } else {
- USB_IF_PREPEND(&f->used_q, m);
- }
- } else {
-
- if (tr_data) {
- /* wait for data to be written out */
- break;
- }
- if (f->flag_flushing) {
- f->flag_flushing = 0;
- usb2_fifo_wakeup(f);
- }
- break;
- }
- if (len == 0) {
- break;
- }
- }
- return (tr_data);
-}
-
-uint8_t
-usb2_fifo_get_data_linear(struct usb2_fifo *f, void *ptr,
- uint32_t len, uint32_t *actlen, uint8_t what)
-{
- struct usb2_mbuf *m;
- uint32_t io_len;
- uint8_t tr_data = 0;
-
- actlen[0] = 0;
-
- while (1) {
-
- USB_IF_DEQUEUE(&f->used_q, m);
-
- if (m) {
-
- tr_data = 1;
-
- io_len = MIN(len, m->cur_data_len);
-
- bcopy(m->cur_data_ptr, ptr, io_len);
-
- len -= io_len;
- ptr = USB_ADD_BYTES(ptr, io_len);
- actlen[0] += io_len;
- m->cur_data_ptr += io_len;
- m->cur_data_len -= io_len;
-
- if ((m->cur_data_len == 0) || (what == 1)) {
- USB_IF_ENQUEUE(&f->free_q, m);
-
- usb2_fifo_wakeup(f);
-
- if (what == 1) {
- break;
- }
- } else {
- USB_IF_PREPEND(&f->used_q, m);
- }
- } else {
-
- if (tr_data) {
- /* wait for data to be written out */
- break;
- }
- if (f->flag_flushing) {
- f->flag_flushing = 0;
- usb2_fifo_wakeup(f);
- }
- break;
- }
- if (len == 0) {
- break;
- }
- }
- return (tr_data);
-}
-
-uint8_t
-usb2_fifo_get_data_buffer(struct usb2_fifo *f, void **pptr, uint32_t *plen)
-{
- struct usb2_mbuf *m;
-
- USB_IF_POLL(&f->used_q, m);
-
- if (m) {
- *plen = m->cur_data_len;
- *pptr = m->cur_data_ptr;
-
- return (1);
- }
- return (0);
-}
-
-void
-usb2_fifo_get_data_error(struct usb2_fifo *f)
-{
- f->flag_iserror = 1;
- usb2_fifo_wakeup(f);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_alloc_symlink
- *
- * Return values:
- * NULL: Failure
- * Else: Pointer to symlink entry
- *------------------------------------------------------------------------*/
-struct usb2_symlink *
-usb2_alloc_symlink(const char *target, const char *fmt,...)
-{
- struct usb2_symlink *ps;
- va_list ap;
-
- ps = malloc(sizeof(*ps), M_USBDEV, M_WAITOK);
- if (ps == NULL) {
- return (ps);
- }
- strlcpy(ps->dst_path, target, sizeof(ps->dst_path));
- ps->dst_len = strlen(ps->dst_path);
-
- va_start(ap, fmt);
- vsnrprintf(ps->src_path,
- sizeof(ps->src_path), 32, fmt, ap);
- va_end(ap);
- ps->src_len = strlen(ps->src_path);
-
- sx_xlock(&usb2_sym_lock);
- TAILQ_INSERT_TAIL(&usb2_sym_head, ps, sym_entry);
- sx_unlock(&usb2_sym_lock);
- return (ps);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_free_symlink
- *------------------------------------------------------------------------*/
-void
-usb2_free_symlink(struct usb2_symlink *ps)
-{
- if (ps == NULL) {
- return;
- }
- sx_xlock(&usb2_sym_lock);
- TAILQ_REMOVE(&usb2_sym_head, ps, sym_entry);
- sx_unlock(&usb2_sym_lock);
-
- free(ps, M_USBDEV);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_lookup_symlink
- *
- * Return value:
- * Numerical device location
- *------------------------------------------------------------------------*/
-uint32_t
-usb2_lookup_symlink(const char *src_ptr, uint8_t src_len)
-{
- enum {
- USB_DNAME_LEN = sizeof(USB_DEVICE_NAME) - 1,
- };
- struct usb2_symlink *ps;
- uint32_t temp;
-
- sx_xlock(&usb2_sym_lock);
-
- TAILQ_FOREACH(ps, &usb2_sym_head, sym_entry) {
-
- if (src_len != ps->src_len)
- continue;
-
- if (memcmp(ps->src_path, src_ptr, src_len))
- continue;
-
- if (USB_DNAME_LEN > ps->dst_len)
- continue;
-
- if (memcmp(ps->dst_path, USB_DEVICE_NAME, USB_DNAME_LEN))
- continue;
-
- temp = usb2_path_convert(ps->dst_path + USB_DNAME_LEN);
- sx_unlock(&usb2_sym_lock);
-
- return (temp);
- }
- sx_unlock(&usb2_sym_lock);
- return (0 - 1);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_read_symlink
- *
- * Return value:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-int
-usb2_read_symlink(uint8_t *user_ptr, uint32_t startentry, uint32_t user_len)
-{
- struct usb2_symlink *ps;
- uint32_t temp;
- uint32_t delta = 0;
- uint8_t len;
- int error = 0;
-
- sx_xlock(&usb2_sym_lock);
-
- TAILQ_FOREACH(ps, &usb2_sym_head, sym_entry) {
-
- /*
- * Compute total length of source and destination symlink
- * strings pluss one length byte and two NUL bytes:
- */
- temp = ps->src_len + ps->dst_len + 3;
-
- if (temp > 255) {
- /*
- * Skip entry because this length cannot fit
- * into one byte:
- */
- continue;
- }
- if (startentry != 0) {
- /* decrement read offset */
- startentry--;
- continue;
- }
- if (temp > user_len) {
- /* out of buffer space */
- break;
- }
- len = temp;
-
- /* copy out total length */
-
- error = copyout(&len,
- USB_ADD_BYTES(user_ptr, delta), 1);
- if (error) {
- break;
- }
- delta += 1;
-
- /* copy out source string */
-
- error = copyout(ps->src_path,
- USB_ADD_BYTES(user_ptr, delta), ps->src_len);
- if (error) {
- break;
- }
- len = 0;
- delta += ps->src_len;
- error = copyout(&len,
- USB_ADD_BYTES(user_ptr, delta), 1);
- if (error) {
- break;
- }
- delta += 1;
-
- /* copy out destination string */
-
- error = copyout(ps->dst_path,
- USB_ADD_BYTES(user_ptr, delta), ps->dst_len);
- if (error) {
- break;
- }
- len = 0;
- delta += ps->dst_len;
- error = copyout(&len,
- USB_ADD_BYTES(user_ptr, delta), 1);
- if (error) {
- break;
- }
- delta += 1;
-
- user_len -= temp;
- }
-
- /* a zero length entry indicates the end */
-
- if ((user_len != 0) && (error == 0)) {
-
- len = 0;
-
- error = copyout(&len,
- USB_ADD_BYTES(user_ptr, delta), 1);
- }
- sx_unlock(&usb2_sym_lock);
- return (error);
-}
diff --git a/sys/dev/usb2/core/usb2_dev.h b/sys/dev/usb2/core/usb2_dev.h
deleted file mode 100644
index 6203572..0000000
--- a/sys/dev/usb2/core/usb2_dev.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_DEV_H_
-#define _USB2_DEV_H_
-
-#include <sys/file.h>
-#include <sys/vnode.h>
-#include <sys/poll.h>
-#include <sys/signalvar.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/proc.h>
-
-#define USB_FIFO_TX 0
-#define USB_FIFO_RX 1
-
-struct usb2_fifo;
-struct usb2_mbuf;
-
-typedef int (usb2_fifo_open_t)(struct usb2_fifo *fifo, int fflags, struct thread *td);
-typedef void (usb2_fifo_close_t)(struct usb2_fifo *fifo, int fflags, struct thread *td);
-typedef int (usb2_fifo_ioctl_t)(struct usb2_fifo *fifo, u_long cmd, void *addr, int fflags, struct thread *td);
-typedef void (usb2_fifo_cmd_t)(struct usb2_fifo *fifo);
-typedef void (usb2_fifo_filter_t)(struct usb2_fifo *fifo, struct usb2_mbuf *m);
-
-struct usb2_symlink {
- TAILQ_ENTRY(usb2_symlink) sym_entry;
- char src_path[32]; /* Source path - including terminating
- * zero */
- char dst_path[32]; /* Destination path - including
- * terminating zero */
- uint8_t src_len; /* String length */
- uint8_t dst_len; /* String length */
-};
-
-/*
- * Locking note for the following functions. All the
- * "usb2_fifo_cmd_t" and "usb2_fifo_filter_t" functions are called
- * locked. The others are called unlocked.
- */
-struct usb2_fifo_methods {
- usb2_fifo_open_t *f_open;
- usb2_fifo_close_t *f_close;
- usb2_fifo_ioctl_t *f_ioctl;
- /*
- * NOTE: The post-ioctl callback is called after the USB reference
- * gets locked in the IOCTL handler:
- */
- usb2_fifo_ioctl_t *f_ioctl_post;
- usb2_fifo_cmd_t *f_start_read;
- usb2_fifo_cmd_t *f_stop_read;
- usb2_fifo_cmd_t *f_start_write;
- usb2_fifo_cmd_t *f_stop_write;
- usb2_fifo_filter_t *f_filter_read;
- usb2_fifo_filter_t *f_filter_write;
- const char *basename[4];
- const char *postfix[4];
-};
-
-/*
- * Most of the fields in the "usb2_fifo" structure are used by the
- * generic USB access layer.
- */
-struct usb2_fifo {
- struct usb2_ifqueue free_q;
- struct usb2_ifqueue used_q;
- struct selinfo selinfo;
- struct cv cv_io;
- struct cv cv_drain;
- struct usb2_fifo_methods *methods;
- struct usb2_symlink *symlink[2];/* our symlinks */
- struct proc *async_p; /* process that wants SIGIO */
- struct usb2_fs_endpoint *fs_ep_ptr;
- struct usb2_device *udev;
- struct usb2_xfer *xfer[2];
- struct usb2_xfer **fs_xfer;
- struct mtx *priv_mtx; /* client data */
- struct file *curr_file; /* set if FIFO is opened by a FILE */
- void *priv_sc0; /* client data */
- void *priv_sc1; /* client data */
- void *queue_data;
- uint32_t timeout; /* timeout in milliseconds */
- uint32_t bufsize; /* BULK and INTERRUPT buffer size */
- uint16_t nframes; /* for isochronous mode */
- uint16_t dev_ep_index; /* our device endpoint index */
- uint8_t flag_sleeping; /* set if FIFO is sleeping */
- uint8_t flag_iscomplete; /* set if a USB transfer is complete */
- uint8_t flag_iserror; /* set if FIFO error happened */
- uint8_t flag_isselect; /* set if FIFO is selected */
- uint8_t flag_flushing; /* set if FIFO is flushing data */
- uint8_t flag_short; /* set if short_ok or force_short
- * transfer flags should be set */
- uint8_t flag_stall; /* set if clear stall should be run */
- uint8_t iface_index; /* set to the interface we belong to */
- uint8_t fifo_index; /* set to the FIFO index in "struct
- * usb2_device" */
- uint8_t fs_ep_max;
- uint8_t fifo_zlp; /* zero length packet count */
- uint8_t refcount;
-#define USB_FIFO_REF_MAX 0xFF
-};
-
-struct usb2_fifo_sc {
- struct usb2_fifo *fp[2];
-};
-
-int usb2_fifo_wait(struct usb2_fifo *fifo);
-void usb2_fifo_signal(struct usb2_fifo *fifo);
-int usb2_fifo_alloc_buffer(struct usb2_fifo *f, uint32_t bufsize,
- uint16_t nbuf);
-void usb2_fifo_free_buffer(struct usb2_fifo *f);
-int usb2_fifo_attach(struct usb2_device *udev, void *priv_sc,
- struct mtx *priv_mtx, struct usb2_fifo_methods *pm,
- struct usb2_fifo_sc *f_sc, uint16_t unit, uint16_t subunit,
- uint8_t iface_index);
-void usb2_fifo_detach(struct usb2_fifo_sc *f_sc);
-uint32_t usb2_fifo_put_bytes_max(struct usb2_fifo *fifo);
-void usb2_fifo_put_data(struct usb2_fifo *fifo, struct usb2_page_cache *pc,
- uint32_t offset, uint32_t len, uint8_t what);
-void usb2_fifo_put_data_linear(struct usb2_fifo *fifo, void *ptr,
- uint32_t len, uint8_t what);
-uint8_t usb2_fifo_put_data_buffer(struct usb2_fifo *f, void *ptr, uint32_t len);
-void usb2_fifo_put_data_error(struct usb2_fifo *fifo);
-uint8_t usb2_fifo_get_data(struct usb2_fifo *fifo, struct usb2_page_cache *pc,
- uint32_t offset, uint32_t len, uint32_t *actlen, uint8_t what);
-uint8_t usb2_fifo_get_data_linear(struct usb2_fifo *fifo, void *ptr,
- uint32_t len, uint32_t *actlen, uint8_t what);
-uint8_t usb2_fifo_get_data_buffer(struct usb2_fifo *f, void **pptr,
- uint32_t *plen);
-void usb2_fifo_get_data_error(struct usb2_fifo *fifo);
-uint8_t usb2_fifo_opened(struct usb2_fifo *fifo);
-void usb2_fifo_free(struct usb2_fifo *f);
-void usb2_fifo_reset(struct usb2_fifo *f);
-int usb2_check_thread_perm(struct usb2_device *udev, struct thread *td,
- int fflags, uint8_t iface_index, uint8_t ep_index);
-void usb2_fifo_wakeup(struct usb2_fifo *f);
-struct usb2_symlink *usb2_alloc_symlink(const char *target,
- const char *fmt,...);
-void usb2_free_symlink(struct usb2_symlink *ps);
-uint32_t usb2_lookup_symlink(const char *src_ptr, uint8_t src_len);
-int usb2_read_symlink(uint8_t *user_ptr, uint32_t startentry,
- uint32_t user_len);
-
-#endif /* _USB2_DEV_H_ */
diff --git a/sys/dev/usb2/core/usb2_device.c b/sys/dev/usb2/core/usb2_device.c
deleted file mode 100644
index 31e8a84..0000000
--- a/sys/dev/usb2/core/usb2_device.c
+++ /dev/null
@@ -1,2192 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-#include "usbdevs.h"
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_parse.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-#include <dev/usb2/core/usb2_hub.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-#include <dev/usb2/core/usb2_dev.h>
-#include <dev/usb2/core/usb2_msctest.h>
-#include <dev/usb2/core/usb2_generic.h>
-
-#include <dev/usb2/quirk/usb2_quirk.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-
-/* function prototypes */
-
-static void usb2_fill_pipe_data(struct usb2_device *, uint8_t,
- struct usb2_endpoint_descriptor *, struct usb2_pipe *);
-static void usb2_free_pipe_data(struct usb2_device *, uint8_t, uint8_t);
-static void usb2_free_iface_data(struct usb2_device *);
-static void usb2_detach_device_sub(struct usb2_device *, device_t *,
- uint8_t);
-static uint8_t usb2_probe_and_attach_sub(struct usb2_device *,
- struct usb2_attach_arg *);
-static void usb2_init_attach_arg(struct usb2_device *,
- struct usb2_attach_arg *);
-static void usb2_suspend_resume_sub(struct usb2_device *, device_t,
- uint8_t);
-static void usb2_clear_stall_proc(struct usb2_proc_msg *_pm);
-static void usb2_check_strings(struct usb2_device *);
-static usb2_error_t usb2_fill_iface_data(struct usb2_device *, uint8_t,
- uint8_t);
-static void usb2_notify_addq(const char *type, struct usb2_device *);
-static void usb2_fifo_free_wrap(struct usb2_device *, uint8_t, uint8_t);
-
-/* This variable is global to allow easy access to it: */
-
-int usb2_template = 0;
-
-SYSCTL_INT(_hw_usb2, OID_AUTO, template, CTLFLAG_RW,
- &usb2_template, 0, "Selected USB device side template");
-
-
-/*------------------------------------------------------------------------*
- * usb2_get_pipe_by_addr
- *
- * This function searches for an USB pipe by endpoint address and
- * direction.
- *
- * Returns:
- * NULL: Failure
- * Else: Success
- *------------------------------------------------------------------------*/
-struct usb2_pipe *
-usb2_get_pipe_by_addr(struct usb2_device *udev, uint8_t ea_val)
-{
- struct usb2_pipe *pipe = udev->pipes;
- struct usb2_pipe *pipe_end = udev->pipes + USB_EP_MAX;
- enum {
- EA_MASK = (UE_DIR_IN | UE_DIR_OUT | UE_ADDR),
- };
-
- /*
- * According to the USB specification not all bits are used
- * for the endpoint address. Keep defined bits only:
- */
- ea_val &= EA_MASK;
-
- /*
- * Iterate accross all the USB pipes searching for a match
- * based on the endpoint address:
- */
- for (; pipe != pipe_end; pipe++) {
-
- if (pipe->edesc == NULL) {
- continue;
- }
- /* do the mask and check the value */
- if ((pipe->edesc->bEndpointAddress & EA_MASK) == ea_val) {
- goto found;
- }
- }
-
- /*
- * The default pipe is always present and is checked separately:
- */
- if ((udev->default_pipe.edesc) &&
- ((udev->default_pipe.edesc->bEndpointAddress & EA_MASK) == ea_val)) {
- pipe = &udev->default_pipe;
- goto found;
- }
- return (NULL);
-
-found:
- return (pipe);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_get_pipe
- *
- * This function searches for an USB pipe based on the information
- * given by the passed "struct usb2_config" pointer.
- *
- * Return values:
- * NULL: No match.
- * Else: Pointer to "struct usb2_pipe".
- *------------------------------------------------------------------------*/
-struct usb2_pipe *
-usb2_get_pipe(struct usb2_device *udev, uint8_t iface_index,
- const struct usb2_config *setup)
-{
- struct usb2_pipe *pipe = udev->pipes;
- struct usb2_pipe *pipe_end = udev->pipes + USB_EP_MAX;
- uint8_t index = setup->ep_index;
- uint8_t ea_mask;
- uint8_t ea_val;
- uint8_t type_mask;
- uint8_t type_val;
-
- DPRINTFN(10, "udev=%p iface_index=%d address=0x%x "
- "type=0x%x dir=0x%x index=%d\n",
- udev, iface_index, setup->endpoint,
- setup->type, setup->direction, setup->ep_index);
-
- /* setup expected endpoint direction mask and value */
-
- if (setup->direction == UE_DIR_ANY) {
- /* match any endpoint direction */
- ea_mask = 0;
- ea_val = 0;
- } else {
- /* match the given endpoint direction */
- ea_mask = (UE_DIR_IN | UE_DIR_OUT);
- ea_val = (setup->direction & (UE_DIR_IN | UE_DIR_OUT));
- }
-
- /* setup expected endpoint address */
-
- if (setup->endpoint == UE_ADDR_ANY) {
- /* match any endpoint address */
- } else {
- /* match the given endpoint address */
- ea_mask |= UE_ADDR;
- ea_val |= (setup->endpoint & UE_ADDR);
- }
-
- /* setup expected endpoint type */
-
- if (setup->type == UE_BULK_INTR) {
- /* this will match BULK and INTERRUPT endpoints */
- type_mask = 2;
- type_val = 2;
- } else if (setup->type == UE_TYPE_ANY) {
- /* match any endpoint type */
- type_mask = 0;
- type_val = 0;
- } else {
- /* match the given endpoint type */
- type_mask = UE_XFERTYPE;
- type_val = (setup->type & UE_XFERTYPE);
- }
-
- /*
- * Iterate accross all the USB pipes searching for a match
- * based on the endpoint address. Note that we are searching
- * the pipes from the beginning of the "udev->pipes" array.
- */
- for (; pipe != pipe_end; pipe++) {
-
- if ((pipe->edesc == NULL) ||
- (pipe->iface_index != iface_index)) {
- continue;
- }
- /* do the masks and check the values */
-
- if (((pipe->edesc->bEndpointAddress & ea_mask) == ea_val) &&
- ((pipe->edesc->bmAttributes & type_mask) == type_val)) {
- if (!index--) {
- goto found;
- }
- }
- }
-
- /*
- * Match against default pipe last, so that "any pipe", "any
- * address" and "any direction" returns the first pipe of the
- * interface. "iface_index" and "direction" is ignored:
- */
- if ((udev->default_pipe.edesc) &&
- ((udev->default_pipe.edesc->bEndpointAddress & ea_mask) == ea_val) &&
- ((udev->default_pipe.edesc->bmAttributes & type_mask) == type_val) &&
- (!index)) {
- pipe = &udev->default_pipe;
- goto found;
- }
- return (NULL);
-
-found:
- return (pipe);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_interface_count
- *
- * This function stores the number of USB interfaces excluding
- * alternate settings, which the USB config descriptor reports into
- * the unsigned 8-bit integer pointed to by "count".
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_interface_count(struct usb2_device *udev, uint8_t *count)
-{
- if (udev->cdesc == NULL) {
- *count = 0;
- return (USB_ERR_NOT_CONFIGURED);
- }
- *count = udev->cdesc->bNumInterface;
- return (USB_ERR_NORMAL_COMPLETION);
-}
-
-
-/*------------------------------------------------------------------------*
- * usb2_fill_pipe_data
- *
- * This function will initialise the USB pipe structure pointed to by
- * the "pipe" argument.
- *------------------------------------------------------------------------*/
-static void
-usb2_fill_pipe_data(struct usb2_device *udev, uint8_t iface_index,
- struct usb2_endpoint_descriptor *edesc, struct usb2_pipe *pipe)
-{
- bzero(pipe, sizeof(*pipe));
-
- (udev->bus->methods->pipe_init) (udev, edesc, pipe);
-
- if (pipe->methods == NULL) {
- /* the pipe is invalid: just return */
- return;
- }
- /* initialise USB pipe structure */
- pipe->edesc = edesc;
- pipe->iface_index = iface_index;
- TAILQ_INIT(&pipe->pipe_q.head);
- pipe->pipe_q.command = &usb2_pipe_start;
-
- /* clear stall, if any */
- if (udev->bus->methods->clear_stall) {
- USB_BUS_LOCK(udev->bus);
- (udev->bus->methods->clear_stall) (udev, pipe);
- USB_BUS_UNLOCK(udev->bus);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_free_pipe_data
- *
- * This function will free USB pipe data for the given interface
- * index. Hence we do not have any dynamic allocations we simply clear
- * "pipe->edesc" to indicate that the USB pipe structure can be
- * reused. The pipes belonging to the given interface should not be in
- * use when this function is called and no check is performed to
- * prevent this.
- *------------------------------------------------------------------------*/
-static void
-usb2_free_pipe_data(struct usb2_device *udev,
- uint8_t iface_index, uint8_t iface_mask)
-{
- struct usb2_pipe *pipe = udev->pipes;
- struct usb2_pipe *pipe_end = udev->pipes + USB_EP_MAX;
-
- while (pipe != pipe_end) {
- if ((pipe->iface_index & iface_mask) == iface_index) {
- /* free pipe */
- pipe->edesc = NULL;
- }
- pipe++;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fill_iface_data
- *
- * This function will fill in interface data and allocate USB pipes
- * for all the endpoints that belong to the given interface. This
- * function is typically called when setting the configuration or when
- * setting an alternate interface.
- *------------------------------------------------------------------------*/
-static usb2_error_t
-usb2_fill_iface_data(struct usb2_device *udev,
- uint8_t iface_index, uint8_t alt_index)
-{
- struct usb2_interface *iface = usb2_get_iface(udev, iface_index);
- struct usb2_pipe *pipe;
- struct usb2_pipe *pipe_end;
- struct usb2_interface_descriptor *id;
- struct usb2_endpoint_descriptor *ed = NULL;
- struct usb2_descriptor *desc;
- uint8_t nendpt;
-
- if (iface == NULL) {
- return (USB_ERR_INVAL);
- }
- DPRINTFN(5, "iface_index=%d alt_index=%d\n",
- iface_index, alt_index);
-
- sx_assert(udev->default_sx + 1, SA_LOCKED);
-
- pipe = udev->pipes;
- pipe_end = udev->pipes + USB_EP_MAX;
-
- /*
- * Check if any USB pipes on the given USB interface are in
- * use:
- */
- while (pipe != pipe_end) {
- if ((pipe->edesc != NULL) &&
- (pipe->iface_index == iface_index) &&
- (pipe->refcount != 0)) {
- return (USB_ERR_IN_USE);
- }
- pipe++;
- }
-
- pipe = &udev->pipes[0];
-
- id = usb2_find_idesc(udev->cdesc, iface_index, alt_index);
- if (id == NULL) {
- return (USB_ERR_INVAL);
- }
- /*
- * Free old pipes after we know that an interface descriptor exists,
- * if any.
- */
- usb2_free_pipe_data(udev, iface_index, 0 - 1);
-
- /* Setup USB interface structure */
- iface->idesc = id;
- iface->alt_index = alt_index;
- iface->parent_iface_index = USB_IFACE_INDEX_ANY;
-
- nendpt = id->bNumEndpoints;
- DPRINTFN(5, "found idesc nendpt=%d\n", nendpt);
-
- desc = (void *)id;
-
- while (nendpt--) {
- DPRINTFN(11, "endpt=%d\n", nendpt);
-
- while ((desc = usb2_desc_foreach(udev->cdesc, desc))) {
- if ((desc->bDescriptorType == UDESC_ENDPOINT) &&
- (desc->bLength >= sizeof(*ed))) {
- goto found;
- }
- if (desc->bDescriptorType == UDESC_INTERFACE) {
- break;
- }
- }
- goto error;
-
-found:
- ed = (void *)desc;
-
- /* find a free pipe */
- while (pipe != pipe_end) {
- if (pipe->edesc == NULL) {
- /* pipe is free */
- usb2_fill_pipe_data(udev, iface_index, ed, pipe);
- break;
- }
- pipe++;
- }
- }
- return (USB_ERR_NORMAL_COMPLETION);
-
-error:
- /* passed end, or bad desc */
- DPRINTFN(0, "%s: bad descriptor(s), addr=%d!\n",
- __FUNCTION__, udev->address);
-
- /* free old pipes if any */
- usb2_free_pipe_data(udev, iface_index, 0 - 1);
- return (USB_ERR_INVAL);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_free_iface_data
- *
- * This function will free all USB interfaces and USB pipes belonging
- * to an USB device.
- *------------------------------------------------------------------------*/
-static void
-usb2_free_iface_data(struct usb2_device *udev)
-{
- struct usb2_interface *iface = udev->ifaces;
- struct usb2_interface *iface_end = udev->ifaces + USB_IFACE_MAX;
-
- /* mtx_assert() */
-
- /* free Linux compat device, if any */
- if (udev->linux_dev) {
- usb_linux_free_device(udev->linux_dev);
- udev->linux_dev = NULL;
- }
- /* free all pipes, if any */
- usb2_free_pipe_data(udev, 0, 0);
-
- /* free all interfaces, if any */
- while (iface != iface_end) {
- iface->idesc = NULL;
- iface->alt_index = 0;
- iface->parent_iface_index = USB_IFACE_INDEX_ANY;
- iface->perm.mode = 0; /* disable permissions */
- iface++;
- }
-
- /* free "cdesc" after "ifaces", if any */
- if (udev->cdesc) {
- free(udev->cdesc, M_USB);
- udev->cdesc = NULL;
- }
- /* set unconfigured state */
- udev->curr_config_no = USB_UNCONFIG_NO;
- udev->curr_config_index = USB_UNCONFIG_INDEX;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_set_config_index
- *
- * This function selects configuration by index, independent of the
- * actual configuration number. This function should not be used by
- * USB drivers.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_set_config_index(struct usb2_device *udev, uint8_t index)
-{
- struct usb2_status ds;
- struct usb2_hub_descriptor hd;
- struct usb2_config_descriptor *cdp;
- uint16_t power;
- uint16_t max_power;
- uint8_t nifc;
- uint8_t selfpowered;
- uint8_t do_unlock;
- usb2_error_t err;
-
- DPRINTFN(6, "udev=%p index=%d\n", udev, index);
-
- /* automatic locking */
- if (sx_xlocked(udev->default_sx + 1)) {
- do_unlock = 0;
- } else {
- do_unlock = 1;
- sx_xlock(udev->default_sx + 1);
- }
-
- /* detach all interface drivers */
- usb2_detach_device(udev, USB_IFACE_INDEX_ANY, 1);
-
- /* free all FIFOs except control endpoint FIFOs */
- usb2_fifo_free_wrap(udev, USB_IFACE_INDEX_ANY, 0);
-
- /* free all configuration data structures */
- usb2_free_iface_data(udev);
-
- if (index == USB_UNCONFIG_INDEX) {
- /*
- * Leave unallocated when unconfiguring the
- * device. "usb2_free_iface_data()" will also reset
- * the current config number and index.
- */
- err = usb2_req_set_config(udev, &Giant, USB_UNCONFIG_NO);
- goto done;
- }
- /* get the full config descriptor */
- err = usb2_req_get_config_desc_full(udev,
- &Giant, &cdp, M_USB, index);
- if (err) {
- goto done;
- }
- /* set the new config descriptor */
-
- udev->cdesc = cdp;
-
- if (cdp->bNumInterface > USB_IFACE_MAX) {
- DPRINTFN(0, "too many interfaces: %d\n", cdp->bNumInterface);
- cdp->bNumInterface = USB_IFACE_MAX;
- }
- /* Figure out if the device is self or bus powered. */
- selfpowered = 0;
- if ((!udev->flags.uq_bus_powered) &&
- (cdp->bmAttributes & UC_SELF_POWERED) &&
- (udev->flags.usb2_mode == USB_MODE_HOST)) {
- /* May be self powered. */
- if (cdp->bmAttributes & UC_BUS_POWERED) {
- /* Must ask device. */
- if (udev->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.
- */
- err = usb2_req_get_hub_descriptor
- (udev, &Giant, &hd, 1);
- if (err) {
- DPRINTFN(0, "could not read "
- "HUB descriptor: %s\n",
- usb2_errstr(err));
-
- } else if (UGETW(hd.wHubCharacteristics) &
- UHD_PWR_INDIVIDUAL) {
- selfpowered = 1;
- }
- DPRINTF("characteristics=0x%04x\n",
- UGETW(hd.wHubCharacteristics));
- } else {
- err = usb2_req_get_device_status
- (udev, &Giant, &ds);
- if (err) {
- DPRINTFN(0, "could not read "
- "device status: %s\n",
- usb2_errstr(err));
- } else if (UGETW(ds.wStatus) & UDS_SELF_POWERED) {
- selfpowered = 1;
- }
- DPRINTF("status=0x%04x \n",
- UGETW(ds.wStatus));
- }
- } else
- selfpowered = 1;
- }
- DPRINTF("udev=%p cdesc=%p (addr %d) cno=%d attr=0x%02x, "
- "selfpowered=%d, power=%d\n",
- udev, cdp,
- cdp->bConfigurationValue, udev->address, cdp->bmAttributes,
- selfpowered, cdp->bMaxPower * 2);
-
- /* Check if we have enough power. */
- power = cdp->bMaxPower * 2;
-
- if (udev->parent_hub) {
- max_power = udev->parent_hub->hub->portpower;
- } else {
- max_power = USB_MAX_POWER;
- }
-
- if (power > max_power) {
- DPRINTFN(0, "power exceeded %d > %d\n", power, max_power);
- err = USB_ERR_NO_POWER;
- goto done;
- }
- /* Only update "self_powered" in USB Host Mode */
- if (udev->flags.usb2_mode == USB_MODE_HOST) {
- udev->flags.self_powered = selfpowered;
- }
- udev->power = power;
- udev->curr_config_no = cdp->bConfigurationValue;
- udev->curr_config_index = index;
-
- /* Set the actual configuration value. */
- err = usb2_req_set_config(udev, &Giant, cdp->bConfigurationValue);
- if (err) {
- goto done;
- }
- /* Allocate and fill interface data. */
- nifc = cdp->bNumInterface;
- while (nifc--) {
- err = usb2_fill_iface_data(udev, nifc, 0);
- if (err) {
- goto done;
- }
- }
-
-done:
- DPRINTF("error=%s\n", usb2_errstr(err));
- if (err) {
- usb2_free_iface_data(udev);
- }
- if (do_unlock) {
- sx_unlock(udev->default_sx + 1);
- }
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_set_alt_interface_index
- *
- * This function will select an alternate interface index for the
- * given interface index. The interface should not be in use when this
- * function is called. That means there should be no open USB
- * transfers. Else an error is returned.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_set_alt_interface_index(struct usb2_device *udev,
- uint8_t iface_index, uint8_t alt_index)
-{
- struct usb2_interface *iface = usb2_get_iface(udev, iface_index);
- usb2_error_t err;
- uint8_t do_unlock;
-
- /* automatic locking */
- if (sx_xlocked(udev->default_sx + 1)) {
- do_unlock = 0;
- } else {
- do_unlock = 1;
- sx_xlock(udev->default_sx + 1);
- }
- if (iface == NULL) {
- err = USB_ERR_INVAL;
- goto done;
- }
- if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
- usb2_detach_device(udev, iface_index, 1);
- }
- /*
- * Free all generic FIFOs for this interface, except control
- * endpoint FIFOs:
- */
- usb2_fifo_free_wrap(udev, iface_index, 0);
-
- err = usb2_fill_iface_data(udev, iface_index, alt_index);
- if (err) {
- goto done;
- }
- err = usb2_req_set_alt_interface_no
- (udev, &Giant, iface_index,
- iface->idesc->bAlternateSetting);
-
-done:
- if (do_unlock) {
- sx_unlock(udev->default_sx + 1);
- }
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_set_endpoint_stall
- *
- * This function is used to make a BULK or INTERRUPT endpoint
- * send STALL tokens.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_set_endpoint_stall(struct usb2_device *udev, struct usb2_pipe *pipe,
- uint8_t do_stall)
-{
- struct usb2_xfer *xfer;
- uint8_t et;
- uint8_t was_stalled;
-
- if (pipe == NULL) {
- /* nothing to do */
- DPRINTF("Cannot find endpoint\n");
- /*
- * Pretend that the clear or set stall request is
- * successful else some USB host stacks can do
- * strange things, especially when a control endpoint
- * stalls.
- */
- return (0);
- }
- et = (pipe->edesc->bmAttributes & UE_XFERTYPE);
-
- if ((et != UE_BULK) &&
- (et != UE_INTERRUPT)) {
- /*
- * Should not stall control
- * nor isochronous endpoints.
- */
- DPRINTF("Invalid endpoint\n");
- return (0);
- }
- USB_BUS_LOCK(udev->bus);
-
- /* store current stall state */
- was_stalled = pipe->is_stalled;
-
- /* check for no change */
- if (was_stalled && do_stall) {
- /* if the pipe is already stalled do nothing */
- USB_BUS_UNLOCK(udev->bus);
- DPRINTF("No change\n");
- return (0);
- }
- /* set stalled state */
- pipe->is_stalled = 1;
-
- if (do_stall || (!was_stalled)) {
- if (!was_stalled) {
- /* lookup the current USB transfer, if any */
- xfer = pipe->pipe_q.curr;
- } else {
- xfer = NULL;
- }
-
- /*
- * If "xfer" is non-NULL the "set_stall" method will
- * complete the USB transfer like in case of a timeout
- * setting the error code "USB_ERR_STALLED".
- */
- (udev->bus->methods->set_stall) (udev, xfer, pipe);
- }
- if (!do_stall) {
- pipe->toggle_next = 0; /* reset data toggle */
- pipe->is_stalled = 0; /* clear stalled state */
-
- (udev->bus->methods->clear_stall) (udev, pipe);
-
- /* start up the current or next transfer, if any */
- usb2_command_wrapper(&pipe->pipe_q, pipe->pipe_q.curr);
- }
- USB_BUS_UNLOCK(udev->bus);
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_reset_iface_endpoints - used in USB device side mode
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_reset_iface_endpoints(struct usb2_device *udev, uint8_t iface_index)
-{
- struct usb2_pipe *pipe;
- struct usb2_pipe *pipe_end;
- usb2_error_t err;
-
- pipe = udev->pipes;
- pipe_end = udev->pipes + USB_EP_MAX;
-
- for (; pipe != pipe_end; pipe++) {
-
- if ((pipe->edesc == NULL) ||
- (pipe->iface_index != iface_index)) {
- continue;
- }
- /* simulate a clear stall from the peer */
- err = usb2_set_endpoint_stall(udev, pipe, 0);
- if (err) {
- /* just ignore */
- }
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_detach_device_sub
- *
- * This function will try to detach an USB device. If it fails a panic
- * will result.
- *------------------------------------------------------------------------*/
-static void
-usb2_detach_device_sub(struct usb2_device *udev, device_t *ppdev,
- uint8_t free_subdev)
-{
- device_t dev;
- int err;
-
- if (!free_subdev) {
-
- *ppdev = NULL;
-
- } else if (*ppdev) {
-
- /*
- * NOTE: It is important to clear "*ppdev" before deleting
- * the child due to some device methods being called late
- * during the delete process !
- */
- dev = *ppdev;
- *ppdev = NULL;
-
- device_printf(dev, "at %s, port %d, addr %d "
- "(disconnected)\n",
- device_get_nameunit(udev->parent_dev),
- udev->port_no, udev->address);
-
- if (device_is_attached(dev)) {
- if (udev->flags.suspended) {
- err = DEVICE_RESUME(dev);
- if (err) {
- device_printf(dev, "Resume failed!\n");
- }
- }
- if (device_detach(dev)) {
- goto error;
- }
- }
- if (device_delete_child(udev->parent_dev, dev)) {
- goto error;
- }
- }
- return;
-
-error:
- /* Detach is not allowed to fail in the USB world */
- panic("An USB driver would not detach!\n");
-}
-
-/*------------------------------------------------------------------------*
- * usb2_detach_device
- *
- * The following function will detach the matching interfaces.
- * This function is NULL safe.
- *------------------------------------------------------------------------*/
-void
-usb2_detach_device(struct usb2_device *udev, uint8_t iface_index,
- uint8_t free_subdev)
-{
- struct usb2_interface *iface;
- uint8_t i;
- uint8_t do_unlock;
-
- if (udev == NULL) {
- /* nothing to do */
- return;
- }
- DPRINTFN(4, "udev=%p\n", udev);
-
- /* automatic locking */
- if (sx_xlocked(udev->default_sx + 1)) {
- do_unlock = 0;
- } else {
- do_unlock = 1;
- sx_xlock(udev->default_sx + 1);
- }
-
- /*
- * First detach the child to give the child's detach routine a
- * chance to detach the sub-devices in the correct order.
- * Then delete the child using "device_delete_child()" which
- * will detach all sub-devices from the bottom and upwards!
- */
- if (iface_index != USB_IFACE_INDEX_ANY) {
- i = iface_index;
- iface_index = i + 1;
- } else {
- i = 0;
- iface_index = USB_IFACE_MAX;
- }
-
- /* do the detach */
-
- for (; i != iface_index; i++) {
-
- iface = usb2_get_iface(udev, i);
- if (iface == NULL) {
- /* looks like the end of the USB interfaces */
- break;
- }
- usb2_detach_device_sub(udev, &iface->subdev, free_subdev);
- }
-
- if (do_unlock) {
- sx_unlock(udev->default_sx + 1);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_probe_and_attach_sub
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-usb2_probe_and_attach_sub(struct usb2_device *udev,
- struct usb2_attach_arg *uaa)
-{
- struct usb2_interface *iface;
- device_t dev;
- int err;
-
- iface = uaa->iface;
- if (iface->parent_iface_index != USB_IFACE_INDEX_ANY) {
- /* leave interface alone */
- return (0);
- }
- dev = iface->subdev;
- if (dev) {
-
- /* clean up after module unload */
-
- if (device_is_attached(dev)) {
- /* already a device there */
- return (0);
- }
- /* clear "iface->subdev" as early as possible */
-
- iface->subdev = NULL;
-
- if (device_delete_child(udev->parent_dev, dev)) {
-
- /*
- * Panic here, else one can get a double call
- * to device_detach(). USB devices should
- * never fail on detach!
- */
- panic("device_delete_child() failed!\n");
- }
- }
- if (uaa->temp_dev == NULL) {
-
- /* create a new child */
- uaa->temp_dev = device_add_child(udev->parent_dev, NULL, -1);
- if (uaa->temp_dev == NULL) {
- device_printf(udev->parent_dev,
- "Device creation failed!\n");
- return (1); /* failure */
- }
- device_set_ivars(uaa->temp_dev, uaa);
- device_quiet(uaa->temp_dev);
- }
- /*
- * Set "subdev" before probe and attach so that "devd" gets
- * the information it needs.
- */
- iface->subdev = uaa->temp_dev;
-
- if (device_probe_and_attach(iface->subdev) == 0) {
- /*
- * The USB attach arguments are only available during probe
- * and attach !
- */
- uaa->temp_dev = NULL;
- device_set_ivars(iface->subdev, NULL);
-
- if (udev->flags.suspended) {
- err = DEVICE_SUSPEND(iface->subdev);
- device_printf(iface->subdev, "Suspend failed\n");
- }
- return (0); /* success */
- } else {
- /* No USB driver found */
- iface->subdev = NULL;
- }
- return (1); /* failure */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_set_parent_iface
- *
- * Using this function will lock the alternate interface setting on an
- * interface. It is typically used for multi interface drivers. In USB
- * device side mode it is assumed that the alternate interfaces all
- * have the same endpoint descriptors. The default parent index value
- * is "USB_IFACE_INDEX_ANY". Then the alternate setting value is not
- * locked.
- *------------------------------------------------------------------------*/
-void
-usb2_set_parent_iface(struct usb2_device *udev, uint8_t iface_index,
- uint8_t parent_index)
-{
- struct usb2_interface *iface;
-
- iface = usb2_get_iface(udev, iface_index);
- if (iface) {
- iface->parent_iface_index = parent_index;
- }
-}
-
-static void
-usb2_init_attach_arg(struct usb2_device *udev,
- struct usb2_attach_arg *uaa)
-{
- bzero(uaa, sizeof(*uaa));
-
- uaa->device = udev;
- uaa->usb2_mode = udev->flags.usb2_mode;
- uaa->port = udev->port_no;
-
- uaa->info.idVendor = UGETW(udev->ddesc.idVendor);
- uaa->info.idProduct = UGETW(udev->ddesc.idProduct);
- uaa->info.bcdDevice = UGETW(udev->ddesc.bcdDevice);
- uaa->info.bDeviceClass = udev->ddesc.bDeviceClass;
- uaa->info.bDeviceSubClass = udev->ddesc.bDeviceSubClass;
- uaa->info.bDeviceProtocol = udev->ddesc.bDeviceProtocol;
- uaa->info.bConfigIndex = udev->curr_config_index;
- uaa->info.bConfigNum = udev->curr_config_no;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_probe_and_attach
- *
- * This function is called from "uhub_explore_sub()",
- * "usb2_handle_set_config()" and "usb2_handle_request()".
- *
- * Returns:
- * 0: Success
- * Else: A control transfer failed
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_probe_and_attach(struct usb2_device *udev, uint8_t iface_index)
-{
- struct usb2_attach_arg uaa;
- struct usb2_interface *iface;
- uint8_t i;
- uint8_t j;
- uint8_t do_unlock;
-
- if (udev == NULL) {
- DPRINTF("udev == NULL\n");
- return (USB_ERR_INVAL);
- }
- /* automatic locking */
- if (sx_xlocked(udev->default_sx + 1)) {
- do_unlock = 0;
- } else {
- do_unlock = 1;
- sx_xlock(udev->default_sx + 1);
- }
-
- if (udev->curr_config_index == USB_UNCONFIG_INDEX) {
- /* do nothing - no configuration has been set */
- goto done;
- }
- /* setup USB attach arguments */
-
- usb2_init_attach_arg(udev, &uaa);
-
- /* Check if only one interface should be probed: */
- if (iface_index != USB_IFACE_INDEX_ANY) {
- i = iface_index;
- j = i + 1;
- } else {
- i = 0;
- j = USB_IFACE_MAX;
- }
-
- /* Do the probe and attach */
- for (; i != j; i++) {
-
- iface = usb2_get_iface(udev, i);
- if (iface == NULL) {
- /*
- * Looks like the end of the USB
- * interfaces !
- */
- DPRINTFN(2, "end of interfaces "
- "at %u\n", i);
- break;
- }
- if (iface->idesc == NULL) {
- /* no interface descriptor */
- continue;
- }
- uaa.iface = iface;
-
- uaa.info.bInterfaceClass =
- iface->idesc->bInterfaceClass;
- uaa.info.bInterfaceSubClass =
- iface->idesc->bInterfaceSubClass;
- uaa.info.bInterfaceProtocol =
- iface->idesc->bInterfaceProtocol;
- uaa.info.bIfaceIndex = i;
- uaa.info.bIfaceNum =
- iface->idesc->bInterfaceNumber;
- uaa.use_generic = 0;
-
- DPRINTFN(2, "iclass=%u/%u/%u iindex=%u/%u\n",
- uaa.info.bInterfaceClass,
- uaa.info.bInterfaceSubClass,
- uaa.info.bInterfaceProtocol,
- uaa.info.bIfaceIndex,
- uaa.info.bIfaceNum);
-
- /* try specific interface drivers first */
-
- if (usb2_probe_and_attach_sub(udev, &uaa)) {
- /* ignore */
- }
- /* try generic interface drivers last */
-
- uaa.use_generic = 1;
-
- if (usb2_probe_and_attach_sub(udev, &uaa)) {
- /* ignore */
- }
- }
-
- if (uaa.temp_dev) {
- /* remove the last created child; it is unused */
-
- if (device_delete_child(udev->parent_dev, uaa.temp_dev)) {
- DPRINTFN(0, "device delete child failed!\n");
- }
- }
-done:
- if (do_unlock) {
- sx_unlock(udev->default_sx + 1);
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_suspend_resume_sub
- *
- * This function is called when the suspend or resume methods should
- * be executed on an USB device.
- *------------------------------------------------------------------------*/
-static void
-usb2_suspend_resume_sub(struct usb2_device *udev, device_t dev, uint8_t do_suspend)
-{
- int err;
-
- if (dev == NULL) {
- return;
- }
- if (!device_is_attached(dev)) {
- return;
- }
- if (do_suspend) {
- err = DEVICE_SUSPEND(dev);
- } else {
- err = DEVICE_RESUME(dev);
- }
- if (err) {
- device_printf(dev, "%s failed!\n",
- do_suspend ? "Suspend" : "Resume");
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_suspend_resume
- *
- * The following function will suspend or resume the USB device.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_suspend_resume(struct usb2_device *udev, uint8_t do_suspend)
-{
- struct usb2_interface *iface;
- uint8_t i;
-
- if (udev == NULL) {
- /* nothing to do */
- return (0);
- }
- DPRINTFN(4, "udev=%p do_suspend=%d\n", udev, do_suspend);
-
- sx_assert(udev->default_sx + 1, SA_LOCKED);
-
- USB_BUS_LOCK(udev->bus);
- /* filter the suspend events */
- if (udev->flags.suspended == do_suspend) {
- USB_BUS_UNLOCK(udev->bus);
- /* nothing to do */
- return (0);
- }
- udev->flags.suspended = do_suspend;
- USB_BUS_UNLOCK(udev->bus);
-
- /* do the suspend or resume */
-
- for (i = 0; i != USB_IFACE_MAX; i++) {
-
- iface = usb2_get_iface(udev, i);
- if (iface == NULL) {
- /* looks like the end of the USB interfaces */
- break;
- }
- usb2_suspend_resume_sub(udev, iface->subdev, do_suspend);
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_clear_stall_proc
- *
- * This function performs generic USB clear stall operations.
- *------------------------------------------------------------------------*/
-static void
-usb2_clear_stall_proc(struct usb2_proc_msg *_pm)
-{
- struct usb2_clear_stall_msg *pm = (void *)_pm;
- struct usb2_device *udev = pm->udev;
-
- /* Change lock */
- USB_BUS_UNLOCK(udev->bus);
- mtx_lock(udev->default_mtx);
-
- /* Start clear stall callback */
- usb2_transfer_start(udev->default_xfer[1]);
-
- /* Change lock */
- mtx_unlock(udev->default_mtx);
- USB_BUS_LOCK(udev->bus);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_alloc_device
- *
- * This function allocates a new USB device. This function is 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 get strings.
- *
- * Return values:
- * 0: Failure
- * Else: Success
- *------------------------------------------------------------------------*/
-struct usb2_device *
-usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus,
- struct usb2_device *parent_hub, uint8_t depth,
- uint8_t port_index, uint8_t port_no, uint8_t speed, uint8_t usb2_mode)
-{
- struct usb2_attach_arg uaa;
- struct usb2_device *udev;
- struct usb2_device *adev;
- struct usb2_device *hub;
- uint8_t *scratch_ptr;
- uint32_t scratch_size;
- usb2_error_t err;
- uint8_t device_index;
-
- DPRINTF("parent_dev=%p, bus=%p, parent_hub=%p, depth=%u, "
- "port_index=%u, port_no=%u, speed=%u, usb2_mode=%u\n",
- parent_dev, bus, parent_hub, depth, port_index, port_no,
- speed, usb2_mode);
-
- /*
- * Find an unused device index. In USB Host mode this is the
- * same as the device address.
- *
- * Device index zero is not used and device index 1 should
- * always be the root hub.
- */
- for (device_index = USB_ROOT_HUB_ADDR;
- (device_index != bus->devices_max) &&
- (bus->devices[device_index] != NULL);
- device_index++) /* nop */;
-
- if (device_index == bus->devices_max) {
- device_printf(bus->bdev,
- "No free USB device index for new device!\n");
- return (NULL);
- }
-
- if (depth > 0x10) {
- device_printf(bus->bdev,
- "Invalid device depth!\n");
- return (NULL);
- }
- udev = malloc(sizeof(*udev), M_USB, M_WAITOK | M_ZERO);
- if (udev == NULL) {
- return (NULL);
- }
- /* initialise our SX-lock */
- sx_init(udev->default_sx, "0123456789ABCDEF - USB device SX lock" + depth);
-
- /* initialise our SX-lock */
- sx_init(udev->default_sx + 1, "0123456789ABCDEF - USB config SX lock" + depth);
-
- usb2_cv_init(udev->default_cv, "WCTRL");
- usb2_cv_init(udev->default_cv + 1, "UGONE");
-
- /* initialise our mutex */
- mtx_init(udev->default_mtx, "USB device mutex", NULL, MTX_DEF);
-
- /* initialise generic clear stall */
- udev->cs_msg[0].hdr.pm_callback = &usb2_clear_stall_proc;
- udev->cs_msg[0].udev = udev;
- udev->cs_msg[1].hdr.pm_callback = &usb2_clear_stall_proc;
- udev->cs_msg[1].udev = udev;
-
- /* initialise some USB device fields */
- udev->parent_hub = parent_hub;
- udev->parent_dev = parent_dev;
- udev->port_index = port_index;
- udev->port_no = port_no;
- udev->depth = depth;
- udev->bus = bus;
- udev->address = USB_START_ADDR; /* default value */
- udev->plugtime = (uint32_t)ticks;
- /*
- * We need to force the power mode to "on" because there are plenty
- * of USB devices out there that do not work very well with
- * automatic suspend and resume!
- */
- udev->power_mode = USB_POWER_MODE_ON;
- udev->pwr_save.last_xfer_time = ticks;
-
- /* we are not ready yet */
- udev->refcount = 1;
-
- /* set up default endpoint descriptor */
- udev->default_ep_desc.bLength = sizeof(udev->default_ep_desc);
- udev->default_ep_desc.bDescriptorType = UDESC_ENDPOINT;
- udev->default_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
- udev->default_ep_desc.bmAttributes = UE_CONTROL;
- udev->default_ep_desc.wMaxPacketSize[0] = USB_MAX_IPACKET;
- udev->default_ep_desc.wMaxPacketSize[1] = 0;
- udev->default_ep_desc.bInterval = 0;
- udev->ddesc.bMaxPacketSize = USB_MAX_IPACKET;
-
- udev->speed = speed;
- udev->flags.usb2_mode = usb2_mode;
-
- /* speed combination should be checked by the parent HUB */
-
- hub = udev->parent_hub;
-
- /* search for our High Speed USB HUB, if any */
-
- adev = udev;
- hub = udev->parent_hub;
-
- while (hub) {
- if (hub->speed == USB_SPEED_HIGH) {
- udev->hs_hub_addr = hub->address;
- udev->hs_port_no = adev->port_no;
- break;
- }
- adev = hub;
- hub = hub->parent_hub;
- }
-
- /* init the default pipe */
- usb2_fill_pipe_data(udev, 0,
- &udev->default_ep_desc,
- &udev->default_pipe);
-
- /* set device index */
- udev->device_index = device_index;
-
- if (udev->flags.usb2_mode == USB_MODE_HOST) {
-
- err = usb2_req_set_address(udev, &Giant, device_index);
-
- /* This is the new USB device address from now on */
-
- udev->address = device_index;
-
- /*
- * We ignore any set-address errors, hence there are
- * buggy USB devices out there that actually receive
- * the SETUP PID, but manage to set the address before
- * the STATUS stage is ACK'ed. If the device responds
- * to the subsequent get-descriptor at the new
- * address, then we know that the set-address command
- * was successful.
- */
- if (err) {
- DPRINTFN(0, "set address %d failed "
- "(ignored)\n", udev->address);
- }
- /* allow device time to set new address */
- usb2_pause_mtx(&Giant,
- USB_MS_TO_TICKS(USB_SET_ADDRESS_SETTLE));
- } else {
- /* We are not self powered */
- udev->flags.self_powered = 0;
-
- /* Set unconfigured state */
- udev->curr_config_no = USB_UNCONFIG_NO;
- udev->curr_config_index = USB_UNCONFIG_INDEX;
-
- /* Setup USB descriptors */
- err = (usb2_temp_setup_by_index_p) (udev, usb2_template);
- if (err) {
- DPRINTFN(0, "setting up USB template failed maybe the USB "
- "template module has not been loaded\n");
- goto done;
- }
- }
-
- /*
- * Get the first 8 bytes of the device descriptor !
- *
- * NOTE: "usb2_do_request" will check the device descriptor
- * next time we do a request to see if the maximum packet size
- * changed! The 8 first bytes of the device descriptor
- * contains the maximum packet size to use on control endpoint
- * 0. If this value is different from "USB_MAX_IPACKET" a new
- * USB control request will be setup!
- */
- err = usb2_req_get_desc(udev, &Giant, &udev->ddesc,
- USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0);
- if (err) {
- DPRINTFN(0, "getting device descriptor "
- "at addr %d failed!\n", udev->address);
- /* XXX try to re-enumerate the device */
- err = usb2_req_re_enumerate(udev, &Giant);
- if (err) {
- goto done;
- }
- }
- DPRINTF("adding unit addr=%d, rev=%02x, class=%d, "
- "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
- udev->address, UGETW(udev->ddesc.bcdUSB),
- udev->ddesc.bDeviceClass,
- udev->ddesc.bDeviceSubClass,
- udev->ddesc.bDeviceProtocol,
- udev->ddesc.bMaxPacketSize,
- udev->ddesc.bLength,
- udev->speed);
-
- /* get the full device descriptor */
- err = usb2_req_get_device_desc(udev, &Giant, &udev->ddesc);
- if (err) {
- DPRINTF("addr=%d, getting full desc failed\n",
- udev->address);
- goto done;
- }
- /*
- * Setup temporary USB attach args so that we can figure out some
- * basic quirks for this device.
- */
- usb2_init_attach_arg(udev, &uaa);
-
- if (usb2_test_quirk(&uaa, UQ_BUS_POWERED)) {
- udev->flags.uq_bus_powered = 1;
- }
- if (usb2_test_quirk(&uaa, UQ_POWER_CLAIM)) {
- udev->flags.uq_power_claim = 1;
- }
- if (usb2_test_quirk(&uaa, UQ_NO_STRINGS)) {
- udev->flags.no_strings = 1;
- }
- /*
- * Workaround for buggy USB devices.
- *
- * It appears that some string-less USB chips will crash and
- * disappear if any attempts are made to read any string
- * descriptors.
- *
- * Try to detect such chips by checking the strings in the USB
- * device descriptor. If no strings are present there we
- * simply disable all USB strings.
- */
- scratch_ptr = udev->bus->scratch[0].data;
- scratch_size = sizeof(udev->bus->scratch[0].data);
-
- if (udev->ddesc.iManufacturer ||
- udev->ddesc.iProduct ||
- udev->ddesc.iSerialNumber) {
- /* read out the language ID string */
- err = usb2_req_get_string_desc(udev, &Giant,
- (char *)scratch_ptr, 4, scratch_size,
- USB_LANGUAGE_TABLE);
- } else {
- err = USB_ERR_INVAL;
- }
-
- if (err || (scratch_ptr[0] < 4)) {
- udev->flags.no_strings = 1;
- } else {
- /* pick the first language as the default */
- udev->langid = UGETW(scratch_ptr + 2);
- }
-
- /* assume 100mA bus powered for now. Changed when configured. */
- udev->power = USB_MIN_POWER;
-
- /* get serial number string */
- err = usb2_req_get_string_any
- (udev, &Giant, (char *)scratch_ptr,
- scratch_size, udev->ddesc.iSerialNumber);
-
- strlcpy(udev->serial, (char *)scratch_ptr, sizeof(udev->serial));
-
- /* get manufacturer string */
- err = usb2_req_get_string_any
- (udev, &Giant, (char *)scratch_ptr,
- scratch_size, udev->ddesc.iManufacturer);
-
- strlcpy(udev->manufacturer, (char *)scratch_ptr, sizeof(udev->manufacturer));
-
- /* get product string */
- err = usb2_req_get_string_any
- (udev, &Giant, (char *)scratch_ptr,
- scratch_size, udev->ddesc.iProduct);
-
- strlcpy(udev->product, (char *)scratch_ptr, sizeof(udev->product));
-
- /* finish up all the strings */
- usb2_check_strings(udev);
-
- if (udev->flags.usb2_mode == USB_MODE_HOST) {
- uint8_t config_index;
- uint8_t config_quirk;
- uint8_t set_config_failed = 0;
-
- /*
- * Most USB devices should attach to config index 0 by
- * default
- */
- if (usb2_test_quirk(&uaa, UQ_CFG_INDEX_0)) {
- config_index = 0;
- config_quirk = 1;
- } else if (usb2_test_quirk(&uaa, UQ_CFG_INDEX_1)) {
- config_index = 1;
- config_quirk = 1;
- } else if (usb2_test_quirk(&uaa, UQ_CFG_INDEX_2)) {
- config_index = 2;
- config_quirk = 1;
- } else if (usb2_test_quirk(&uaa, UQ_CFG_INDEX_3)) {
- config_index = 3;
- config_quirk = 1;
- } else if (usb2_test_quirk(&uaa, UQ_CFG_INDEX_4)) {
- config_index = 4;
- config_quirk = 1;
- } else {
- config_index = 0;
- config_quirk = 0;
- }
-
-repeat_set_config:
-
- DPRINTF("setting config %u\n", config_index);
-
- /* get the USB device configured */
- sx_xlock(udev->default_sx + 1);
- err = usb2_set_config_index(udev, config_index);
- sx_unlock(udev->default_sx + 1);
- if (err) {
- if (udev->ddesc.bNumConfigurations != 0) {
- if (!set_config_failed) {
- set_config_failed = 1;
- /* XXX try to re-enumerate the device */
- err = usb2_req_re_enumerate(
- udev, &Giant);
- if (err == 0)
- goto repeat_set_config;
- }
- DPRINTFN(0, "Failure selecting "
- "configuration index %u: %s, port %u, "
- "addr %u (ignored)\n",
- config_index, usb2_errstr(err), udev->port_no,
- udev->address);
- }
- /*
- * Some USB devices do not have any
- * configurations. Ignore any set config
- * failures!
- */
- err = 0;
- } else if (config_quirk) {
- /* user quirk selects configuration index */
- } else if ((config_index + 1) < udev->ddesc.bNumConfigurations) {
-
- if ((udev->cdesc->bNumInterface < 2) &&
- (usb2_get_no_endpoints(udev->cdesc) == 0)) {
- DPRINTFN(0, "Found no endpoints "
- "(trying next config)!\n");
- config_index++;
- goto repeat_set_config;
- }
- if (config_index == 0) {
- /*
- * Try to figure out if we have an
- * auto-install disk there:
- */
- if (usb2_test_autoinstall(udev, 0, 0) == 0) {
- DPRINTFN(0, "Found possible auto-install "
- "disk (trying next config)\n");
- config_index++;
- goto repeat_set_config;
- }
- }
- } else if (usb2_test_huawei_autoinst_p(udev, &uaa) == 0) {
- DPRINTFN(0, "Found Huawei auto-install disk!\n");
- err = USB_ERR_STALLED; /* fake an error */
- }
- } else {
- err = 0; /* set success */
- }
-
- DPRINTF("new dev (addr %d), udev=%p, parent_hub=%p\n",
- udev->address, udev, udev->parent_hub);
-
- /* register our device - we are ready */
- usb2_bus_port_set_device(bus, parent_hub ?
- parent_hub->hub->ports + port_index : NULL, udev, device_index);
-
- /* make a symlink for UGEN */
- if (snprintf((char *)scratch_ptr, scratch_size,
- USB_DEVICE_NAME "%u.%u.0.0",
- device_get_unit(udev->bus->bdev),
- udev->device_index)) {
- /* ignore */
- }
- udev->ugen_symlink =
- usb2_alloc_symlink((char *)scratch_ptr, "ugen%u.%u",
- device_get_unit(udev->bus->bdev),
- udev->device_index);
-
- printf("ugen%u.%u: <%s> at %s\n",
- device_get_unit(udev->bus->bdev),
- udev->device_index, udev->manufacturer,
- device_get_nameunit(udev->bus->bdev));
-
- usb2_notify_addq("+", udev);
-done:
- if (err) {
- /* free device */
- usb2_free_device(udev);
- udev = NULL;
- }
- return (udev);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_free_device
- *
- * This function is NULL safe and will free an USB device.
- *------------------------------------------------------------------------*/
-void
-usb2_free_device(struct usb2_device *udev)
-{
- struct usb2_bus *bus;
-
- if (udev == NULL) {
- /* already freed */
- return;
- }
- DPRINTFN(4, "udev=%p port=%d\n", udev, udev->port_no);
-
- usb2_notify_addq("-", udev);
-
- bus = udev->bus;
-
- printf("ugen%u.%u: <%s> at %s (disconnected)\n",
- device_get_unit(bus->bdev),
- udev->device_index, udev->manufacturer,
- device_get_nameunit(bus->bdev));
-
- /*
- * Destroy UGEN symlink, if any
- */
- if (udev->ugen_symlink) {
- usb2_free_symlink(udev->ugen_symlink);
- udev->ugen_symlink = NULL;
- }
- /*
- * Unregister our device first which will prevent any further
- * references:
- */
- usb2_bus_port_set_device(bus, udev->parent_hub ?
- udev->parent_hub->hub->ports + udev->port_index : NULL,
- NULL, USB_ROOT_HUB_ADDR);
-
- /* wait for all pending references to go away: */
-
- mtx_lock(&usb2_ref_lock);
- udev->refcount--;
- while (udev->refcount != 0) {
- usb2_cv_wait(udev->default_cv + 1, &usb2_ref_lock);
- }
- mtx_unlock(&usb2_ref_lock);
-
- if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
- /* stop receiving any control transfers (Device Side Mode) */
- usb2_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
- }
- /* free all FIFOs */
- usb2_fifo_free_wrap(udev, USB_IFACE_INDEX_ANY, 1);
-
- /*
- * Free all interface related data and FIFOs, if any.
- */
- usb2_free_iface_data(udev);
-
- /* unsetup any leftover default USB transfers */
- usb2_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
-
- /* template unsetup, if any */
- (usb2_temp_unsetup_p) (udev);
-
- /*
- * Make sure that our clear-stall messages are not queued
- * anywhere:
- */
- USB_BUS_LOCK(udev->bus);
- usb2_proc_mwait(&udev->bus->non_giant_callback_proc,
- &udev->cs_msg[0], &udev->cs_msg[1]);
- USB_BUS_UNLOCK(udev->bus);
-
- sx_destroy(udev->default_sx);
- sx_destroy(udev->default_sx + 1);
-
- usb2_cv_destroy(udev->default_cv);
- usb2_cv_destroy(udev->default_cv + 1);
-
- mtx_destroy(udev->default_mtx);
-
- /* free device */
- free(udev, M_USB);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_get_iface
- *
- * This function is the safe way to get the USB interface structure
- * pointer by interface index.
- *
- * Return values:
- * NULL: Interface not present.
- * Else: Pointer to USB interface structure.
- *------------------------------------------------------------------------*/
-struct usb2_interface *
-usb2_get_iface(struct usb2_device *udev, uint8_t iface_index)
-{
- struct usb2_interface *iface = udev->ifaces + iface_index;
-
- if ((iface < udev->ifaces) ||
- (iface_index >= USB_IFACE_MAX) ||
- (udev->cdesc == NULL) ||
- (iface_index >= udev->cdesc->bNumInterface)) {
- return (NULL);
- }
- return (iface);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_find_descriptor
- *
- * This function will lookup the first descriptor that matches the
- * criteria given by the arguments "type" and "subtype". Descriptors
- * will only be searched within the interface having the index
- * "iface_index". If the "id" argument points to an USB descriptor,
- * it will be skipped before the search is started. This allows
- * searching for multiple descriptors using the same criteria. Else
- * the search is started after the interface descriptor.
- *
- * Return values:
- * NULL: End of descriptors
- * Else: A descriptor matching the criteria
- *------------------------------------------------------------------------*/
-void *
-usb2_find_descriptor(struct usb2_device *udev, void *id, uint8_t iface_index,
- uint8_t type, uint8_t type_mask,
- uint8_t subtype, uint8_t subtype_mask)
-{
- struct usb2_descriptor *desc;
- struct usb2_config_descriptor *cd;
- struct usb2_interface *iface;
-
- cd = usb2_get_config_descriptor(udev);
- if (cd == NULL) {
- return (NULL);
- }
- if (id == NULL) {
- iface = usb2_get_iface(udev, iface_index);
- if (iface == NULL) {
- return (NULL);
- }
- id = usb2_get_interface_descriptor(iface);
- if (id == NULL) {
- return (NULL);
- }
- }
- desc = (void *)id;
-
- while ((desc = usb2_desc_foreach(cd, desc))) {
-
- if (desc->bDescriptorType == UDESC_INTERFACE) {
- break;
- }
- if (((desc->bDescriptorType & type_mask) == type) &&
- ((desc->bDescriptorSubtype & subtype_mask) == subtype)) {
- return (desc);
- }
- }
- return (NULL);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_devinfo
- *
- * This function will dump information from the device descriptor
- * belonging to the USB device pointed to by "udev", to the string
- * pointed to by "dst_ptr" having a maximum length of "dst_len" bytes
- * including the terminating zero.
- *------------------------------------------------------------------------*/
-void
-usb2_devinfo(struct usb2_device *udev, char *dst_ptr, uint16_t dst_len)
-{
- struct usb2_device_descriptor *udd = &udev->ddesc;
- uint16_t bcdDevice;
- uint16_t bcdUSB;
-
- bcdUSB = UGETW(udd->bcdUSB);
- bcdDevice = UGETW(udd->bcdDevice);
-
- if (udd->bDeviceClass != 0xFF) {
- snprintf(dst_ptr, dst_len, "%s %s, class %d/%d, rev %x.%02x/"
- "%x.%02x, addr %d", udev->manufacturer, udev->product,
- udd->bDeviceClass, udd->bDeviceSubClass,
- (bcdUSB >> 8), bcdUSB & 0xFF,
- (bcdDevice >> 8), bcdDevice & 0xFF,
- udev->address);
- } else {
- snprintf(dst_ptr, dst_len, "%s %s, rev %x.%02x/"
- "%x.%02x, addr %d", udev->manufacturer, udev->product,
- (bcdUSB >> 8), bcdUSB & 0xFF,
- (bcdDevice >> 8), bcdDevice & 0xFF,
- udev->address);
- }
-}
-
-#if USB_VERBOSE
-/*
- * Descriptions of of known vendors and devices ("products").
- */
-struct usb_knowndev {
- uint16_t vendor;
- uint16_t product;
- uint32_t flags;
- const char *vendorname;
- const char *productname;
-};
-
-#define USB_KNOWNDEV_NOPROD 0x01 /* match on vendor only */
-
-#include "usbdevs.h"
-#include "usbdevs_data.h"
-#endif /* USB_VERBOSE */
-
-/*------------------------------------------------------------------------*
- * usb2_check_strings
- *
- * This function checks the manufacturer and product strings and will
- * fill in defaults for missing strings.
- *------------------------------------------------------------------------*/
-static void
-usb2_check_strings(struct usb2_device *udev)
-{
- struct usb2_device_descriptor *udd = &udev->ddesc;
- const char *vendor;
- const char *product;
-
-#if USB_VERBOSE
- const struct usb_knowndev *kdp;
-
-#endif
- uint16_t vendor_id;
- uint16_t product_id;
-
- usb2_trim_spaces(udev->manufacturer);
- usb2_trim_spaces(udev->product);
-
- if (udev->manufacturer[0]) {
- vendor = udev->manufacturer;
- } else {
- vendor = NULL;
- }
-
- if (udev->product[0]) {
- product = udev->product;
- } else {
- product = NULL;
- }
-
- vendor_id = UGETW(udd->idVendor);
- product_id = UGETW(udd->idProduct);
-
-#if USB_VERBOSE
- if (vendor == NULL || product == NULL) {
-
- for (kdp = usb_knowndevs;
- kdp->vendorname != NULL;
- kdp++) {
- if (kdp->vendor == vendor_id &&
- (kdp->product == product_id ||
- (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 && *vendor) {
- if (udev->manufacturer != vendor) {
- strlcpy(udev->manufacturer, vendor,
- sizeof(udev->manufacturer));
- }
- } else {
- snprintf(udev->manufacturer,
- sizeof(udev->manufacturer), "vendor 0x%04x", vendor_id);
- }
-
- if (product && *product) {
- if (udev->product != product) {
- strlcpy(udev->product, product,
- sizeof(udev->product));
- }
- } else {
- snprintf(udev->product,
- sizeof(udev->product), "product 0x%04x", product_id);
- }
-}
-
-/*
- * Returns:
- * See: USB_MODE_XXX
- */
-uint8_t
-usb2_get_mode(struct usb2_device *udev)
-{
- return (udev->flags.usb2_mode);
-}
-
-/*
- * Returns:
- * See: USB_SPEED_XXX
- */
-uint8_t
-usb2_get_speed(struct usb2_device *udev)
-{
- return (udev->speed);
-}
-
-uint32_t
-usb2_get_isoc_fps(struct usb2_device *udev)
-{
- ; /* indent fix */
- switch (udev->speed) {
- case USB_SPEED_LOW:
- case USB_SPEED_FULL:
- return (1000);
- default:
- return (8000);
- }
-}
-
-struct usb2_device_descriptor *
-usb2_get_device_descriptor(struct usb2_device *udev)
-{
- if (udev == NULL)
- return (NULL); /* be NULL safe */
- return (&udev->ddesc);
-}
-
-struct usb2_config_descriptor *
-usb2_get_config_descriptor(struct usb2_device *udev)
-{
- if (udev == NULL)
- return (NULL); /* be NULL safe */
- return (udev->cdesc);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_test_quirk - test a device for a given quirk
- *
- * Return values:
- * 0: The USB device does not have the given quirk.
- * Else: The USB device has the given quirk.
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_test_quirk(const struct usb2_attach_arg *uaa, uint16_t quirk)
-{
- uint8_t found;
-
- found = (usb2_test_quirk_p) (&uaa->info, quirk);
- return (found);
-}
-
-struct usb2_interface_descriptor *
-usb2_get_interface_descriptor(struct usb2_interface *iface)
-{
- if (iface == NULL)
- return (NULL); /* be NULL safe */
- return (iface->idesc);
-}
-
-uint8_t
-usb2_get_interface_altindex(struct usb2_interface *iface)
-{
- return (iface->alt_index);
-}
-
-uint8_t
-usb2_get_bus_index(struct usb2_device *udev)
-{
- return ((uint8_t)device_get_unit(udev->bus->bdev));
-}
-
-uint8_t
-usb2_get_device_index(struct usb2_device *udev)
-{
- return (udev->device_index);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_notify_addq
- *
- * This function will generate events for dev.
- *------------------------------------------------------------------------*/
-static void
-usb2_notify_addq(const char *type, struct usb2_device *udev)
-{
- char *data = NULL;
- struct malloc_type *mt;
-
- mtx_lock(&malloc_mtx);
- mt = malloc_desc2type("bus"); /* XXX M_BUS */
- mtx_unlock(&malloc_mtx);
- if (mt == NULL)
- return;
-
- data = malloc(512, mt, M_NOWAIT);
- if (data == NULL)
- return;
-
- /* String it all together. */
- if (udev->parent_hub) {
- snprintf(data, 1024,
- "%s"
- "ugen%u.%u "
- "vendor=0x%04x "
- "product=0x%04x "
- "devclass=0x%02x "
- "devsubclass=0x%02x "
- "sernum=\"%s\" "
- "at "
- "port=%u "
- "on "
- "ugen%u.%u\n",
- type,
- device_get_unit(udev->bus->bdev),
- udev->device_index,
- UGETW(udev->ddesc.idVendor),
- UGETW(udev->ddesc.idProduct),
- udev->ddesc.bDeviceClass,
- udev->ddesc.bDeviceSubClass,
- udev->serial,
- udev->port_no,
- device_get_unit(udev->bus->bdev),
- udev->parent_hub->device_index);
- } else {
- snprintf(data, 1024,
- "%s"
- "ugen%u.%u "
- "vendor=0x%04x "
- "product=0x%04x "
- "devclass=0x%02x "
- "devsubclass=0x%02x "
- "sernum=\"%s\" "
- "at port=%u "
- "on "
- "%s\n",
- type,
- device_get_unit(udev->bus->bdev),
- udev->device_index,
- UGETW(udev->ddesc.idVendor),
- UGETW(udev->ddesc.idProduct),
- udev->ddesc.bDeviceClass,
- udev->ddesc.bDeviceSubClass,
- udev->serial,
- udev->port_no,
- device_get_nameunit(device_get_parent(udev->bus->bdev)));
- }
- devctl_queue_data(data);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fifo_free_wrap
- *
- * This function will free the FIFOs.
- *
- * Flag values, if "iface_index" is equal to "USB_IFACE_INDEX_ANY".
- * 0: Free all FIFOs except generic control endpoints.
- * 1: Free all FIFOs.
- *
- * Flag values, if "iface_index" is not equal to "USB_IFACE_INDEX_ANY".
- * Not used.
- *------------------------------------------------------------------------*/
-static void
-usb2_fifo_free_wrap(struct usb2_device *udev,
- uint8_t iface_index, uint8_t flag)
-{
- struct usb2_fifo *f;
- uint16_t i;
-
- /*
- * Free any USB FIFOs on the given interface:
- */
- for (i = 0; i != USB_FIFO_MAX; i++) {
- f = udev->fifo[i];
- if (f == NULL) {
- continue;
- }
- /* Check if the interface index matches */
- if (iface_index == f->iface_index) {
- if (f->methods != &usb2_ugen_methods) {
- /*
- * Don't free any non-generic FIFOs in
- * this case.
- */
- continue;
- }
- if ((f->dev_ep_index == 0) &&
- (f->fs_xfer == NULL)) {
- /* no need to free this FIFO */
- continue;
- }
- } else if (iface_index == USB_IFACE_INDEX_ANY) {
- if ((f->methods == &usb2_ugen_methods) &&
- (f->dev_ep_index == 0) && (flag == 0) &&
- (f->fs_xfer == NULL)) {
- /* no need to free this FIFO */
- continue;
- }
- } else {
- /* no need to free this FIFO */
- continue;
- }
- /* free this FIFO */
- usb2_fifo_free(f);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_peer_can_wakeup
- *
- * Return values:
- * 0: Peer cannot do resume signalling.
- * Else: Peer can do resume signalling.
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_peer_can_wakeup(struct usb2_device *udev)
-{
- const struct usb2_config_descriptor *cdp;
-
- cdp = udev->cdesc;
- if ((cdp != NULL) && (udev->flags.usb2_mode == USB_MODE_HOST)) {
- return (cdp->bmAttributes & UC_REMOTE_WAKEUP);
- }
- return (0); /* not supported */
-}
diff --git a/sys/dev/usb2/core/usb2_device.h b/sys/dev/usb2/core/usb2_device.h
deleted file mode 100644
index 11686e2..0000000
--- a/sys/dev/usb2/core/usb2_device.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_DEVICE_H_
-#define _USB2_DEVICE_H_
-
-struct usb2_symlink;
-
-#define USB_DEFAULT_XFER_MAX 2
-
-struct usb2_clear_stall_msg {
- struct usb2_proc_msg hdr;
- struct usb2_device *udev;
-};
-
-/*
- * The following structure defines an USB pipe which is equal to an
- * USB endpoint.
- */
-struct usb2_pipe {
- struct usb2_xfer_queue pipe_q; /* queue of USB transfers */
-
- struct usb2_xfer *xfer_block; /* blocking USB transfer */
- struct usb2_endpoint_descriptor *edesc;
- struct usb2_pipe_methods *methods; /* set by HC driver */
-
- uint16_t isoc_next;
- uint16_t refcount;
-
- uint8_t toggle_next:1; /* next data toggle value */
- uint8_t is_stalled:1; /* set if pipe is stalled */
- uint8_t is_synced:1; /* set if we a synchronised */
- uint8_t unused:5;
- uint8_t iface_index; /* not used by "default pipe" */
-};
-
-/*
- * The following structure defines an USB interface.
- */
-struct usb2_interface {
- struct usb2_perm perm; /* interface permissions */
- struct usb2_interface_descriptor *idesc;
- device_t subdev;
- uint8_t alt_index;
- uint8_t parent_iface_index;
-};
-
-/*
- * The following structure defines the USB device flags.
- */
-struct usb2_device_flags {
- uint8_t usb2_mode:1; /* USB mode (see USB_MODE_XXX) */
- uint8_t self_powered:1; /* set if USB device is self powered */
- uint8_t suspended:1; /* set if USB device is suspended */
- uint8_t no_strings:1; /* set if USB device does not support
- * strings */
- uint8_t remote_wakeup:1; /* set if remote wakeup is enabled */
- uint8_t uq_bus_powered:1; /* set if BUS powered quirk is present */
- uint8_t uq_power_claim:1; /* set if power claim quirk is present */
-};
-
-/*
- * The following structure is used for power-save purposes. The data
- * in this structure is protected by the USB BUS lock.
- */
-struct usb2_power_save {
- int last_xfer_time; /* copy of "ticks" */
- uint32_t type_refs[4]; /* transfer reference count */
- uint32_t read_refs; /* data read references */
- uint32_t write_refs; /* data write references */
- uint8_t suspended; /* set if USB device is suspended */
-};
-
-/*
- * The following structure defines an USB device. There exists one of
- * these structures for every USB device.
- */
-struct usb2_device {
- struct usb2_clear_stall_msg cs_msg[2]; /* generic clear stall
- * messages */
- struct usb2_perm perm;
- struct sx default_sx[2];
- struct mtx default_mtx[1];
- struct cv default_cv[2];
- struct usb2_interface ifaces[USB_IFACE_MAX];
- struct usb2_pipe default_pipe; /* Control Endpoint 0 */
- struct usb2_pipe pipes[USB_EP_MAX];
- struct usb2_power_save pwr_save;/* power save data */
-
- struct usb2_bus *bus; /* our USB BUS */
- device_t parent_dev; /* parent device */
- struct usb2_device *parent_hub;
- struct usb2_config_descriptor *cdesc; /* full config descr */
- struct usb2_hub *hub; /* only if this is a hub */
- struct usb_device *linux_dev;
- struct usb2_xfer *default_xfer[USB_DEFAULT_XFER_MAX];
- struct usb2_temp_data *usb2_template_ptr;
- struct usb2_pipe *pipe_curr; /* current clear stall pipe */
- struct usb2_fifo *fifo[USB_FIFO_MAX];
- struct usb2_symlink *ugen_symlink; /* our generic symlink */
-
- uint32_t plugtime; /* copy of "ticks" */
-
- uint16_t refcount;
-#define USB_DEV_REF_MAX 0xffff
-
- uint16_t power; /* mA the device uses */
- uint16_t langid; /* language for strings */
-
- uint8_t address; /* device addess */
- uint8_t device_index; /* device index in "bus->devices" */
- uint8_t curr_config_index; /* current configuration index */
- uint8_t curr_config_no; /* current configuration number */
- uint8_t depth; /* distance from root HUB */
- uint8_t speed; /* low/full/high speed */
- uint8_t port_index; /* parent HUB port index */
- uint8_t port_no; /* parent HUB port number */
- uint8_t hs_hub_addr; /* high-speed HUB address */
- uint8_t hs_port_no; /* high-speed HUB port number */
- uint8_t driver_added_refcount; /* our driver added generation count */
- uint8_t power_mode; /* see USB_POWER_XXX */
-
- /* the "flags" field is write-protected by "bus->mtx" */
-
- struct usb2_device_flags flags;
-
- struct usb2_endpoint_descriptor default_ep_desc; /* for pipe 0 */
- struct usb2_device_descriptor ddesc; /* device descriptor */
-
- char serial[64]; /* serial number */
- char manufacturer[64]; /* manufacturer string */
- char product[64]; /* product string */
-};
-
-/* function prototypes */
-
-struct usb2_device *usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus,
- struct usb2_device *parent_hub, uint8_t depth,
- uint8_t port_index, uint8_t port_no, uint8_t speed,
- uint8_t usb2_mode);
-struct usb2_pipe *usb2_get_pipe(struct usb2_device *udev, uint8_t iface_index,
- const struct usb2_config *setup);
-struct usb2_pipe *usb2_get_pipe_by_addr(struct usb2_device *udev, uint8_t ea_val);
-usb2_error_t usb2_interface_count(struct usb2_device *udev, uint8_t *count);
-usb2_error_t usb2_probe_and_attach(struct usb2_device *udev,
- uint8_t iface_index);
-usb2_error_t usb2_reset_iface_endpoints(struct usb2_device *udev,
- uint8_t iface_index);
-usb2_error_t usb2_set_config_index(struct usb2_device *udev, uint8_t index);
-usb2_error_t usb2_set_endpoint_stall(struct usb2_device *udev,
- struct usb2_pipe *pipe, uint8_t do_stall);
-usb2_error_t usb2_suspend_resume(struct usb2_device *udev,
- uint8_t do_suspend);
-void usb2_detach_device(struct usb2_device *udev, uint8_t iface_index,
- uint8_t free_subdev);
-void usb2_devinfo(struct usb2_device *udev, char *dst_ptr, uint16_t dst_len);
-void usb2_free_device(struct usb2_device *udev);
-void *usb2_find_descriptor(struct usb2_device *udev, void *id,
- uint8_t iface_index, uint8_t type, uint8_t type_mask,
- uint8_t subtype, uint8_t subtype_mask);
-void usb_linux_free_device(struct usb_device *dev);
-uint8_t usb2_peer_can_wakeup(struct usb2_device *udev);
-
-#endif /* _USB2_DEVICE_H_ */
diff --git a/sys/dev/usb2/core/usb2_dynamic.c b/sys/dev/usb2/core/usb2_dynamic.c
deleted file mode 100644
index 3e0bdf1..0000000
--- a/sys/dev/usb2/core/usb2_dynamic.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-
-/* function prototypes */
-static usb2_temp_get_desc_t usb2_temp_get_desc_w;
-static usb2_temp_setup_by_index_t usb2_temp_setup_by_index_w;
-static usb2_temp_unsetup_t usb2_temp_unsetup_w;
-static usb2_test_quirk_t usb2_test_quirk_w;
-static usb2_test_huawei_autoinst_t usb2_test_huawei_autoinst_w;
-static usb2_quirk_ioctl_t usb2_quirk_ioctl_w;
-
-/* global variables */
-usb2_temp_get_desc_t *usb2_temp_get_desc_p = &usb2_temp_get_desc_w;
-usb2_temp_setup_by_index_t *usb2_temp_setup_by_index_p = &usb2_temp_setup_by_index_w;
-usb2_temp_unsetup_t *usb2_temp_unsetup_p = &usb2_temp_unsetup_w;
-usb2_test_quirk_t *usb2_test_quirk_p = &usb2_test_quirk_w;
-usb2_test_huawei_autoinst_t *usb2_test_huawei_autoinst_p = &usb2_test_huawei_autoinst_w;
-usb2_quirk_ioctl_t *usb2_quirk_ioctl_p = &usb2_quirk_ioctl_w;
-devclass_t usb2_devclass_ptr = NULL;
-
-static usb2_error_t
-usb2_temp_setup_by_index_w(struct usb2_device *udev, uint16_t index)
-{
- return (USB_ERR_INVAL);
-}
-
-static uint8_t
-usb2_test_quirk_w(const struct usb2_lookup_info *info, uint16_t quirk)
-{
- return (0); /* no match */
-}
-
-static int
-usb2_quirk_ioctl_w(unsigned long cmd, caddr_t data, int fflag, struct thread *td)
-{
- return (ENOIOCTL);
-}
-
-static void
-usb2_temp_get_desc_w(struct usb2_device *udev, struct usb2_device_request *req, const void **pPtr, uint16_t *pLength)
-{
- /* stall */
- *pPtr = NULL;
- *pLength = 0;
-}
-
-static void
-usb2_temp_unsetup_w(struct usb2_device *udev)
-{
- if (udev->usb2_template_ptr) {
-
- free(udev->usb2_template_ptr, M_USB);
-
- udev->usb2_template_ptr = NULL;
- }
-}
-
-static uint8_t
-usb2_test_huawei_autoinst_w(struct usb2_device *udev,
- struct usb2_attach_arg *uaa)
-{
- return (USB_ERR_INVAL);
-}
-
-void
-usb2_quirk_unload(void *arg)
-{
- /* reset function pointers */
-
- usb2_test_quirk_p = &usb2_test_quirk_w;
- usb2_quirk_ioctl_p = &usb2_quirk_ioctl_w;
-
- /* wait for CPU to exit the loaded functions, if any */
-
- /* XXX this is a tradeoff */
-
- pause("WAIT", hz);
-}
-
-void
-usb2_temp_unload(void *arg)
-{
- /* reset function pointers */
-
- usb2_temp_get_desc_p = &usb2_temp_get_desc_w;
- usb2_temp_setup_by_index_p = &usb2_temp_setup_by_index_w;
- usb2_temp_unsetup_p = &usb2_temp_unsetup_w;
-
- /* wait for CPU to exit the loaded functions, if any */
-
- /* XXX this is a tradeoff */
-
- pause("WAIT", hz);
-}
-
-void
-usb2_bus_unload(void *arg)
-{
- /* reset function pointers */
-
- usb2_devclass_ptr = NULL;
-
- /* wait for CPU to exit the loaded functions, if any */
-
- /* XXX this is a tradeoff */
-
- pause("WAIT", hz);
-}
-
-void
-usb2_test_huawei_unload(void *arg)
-{
- /* reset function pointers */
-
- usb2_test_huawei_autoinst_p = &usb2_test_huawei_autoinst_w;
-
- /* wait for CPU to exit the loaded functions, if any */
-
- /* XXX this is a tradeoff */
-
- pause("WAIT", 16*hz);
-}
diff --git a/sys/dev/usb2/core/usb2_dynamic.h b/sys/dev/usb2/core/usb2_dynamic.h
deleted file mode 100644
index 2c45d09..0000000
--- a/sys/dev/usb2/core/usb2_dynamic.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_DYNAMIC_H_
-#define _USB2_DYNAMIC_H_
-
-/* prototypes */
-
-struct usb2_device;
-struct usb2_lookup_info;
-struct usb2_device_request;
-
-/* typedefs */
-
-typedef usb2_error_t (usb2_temp_setup_by_index_t)(struct usb2_device *udev,
- uint16_t index);
-typedef usb2_error_t (usb2_test_huawei_autoinst_t)(struct usb2_device *udev,
- struct usb2_attach_arg *uaa);
-typedef uint8_t (usb2_test_quirk_t)(const struct usb2_lookup_info *info,
- uint16_t quirk);
-typedef int (usb2_quirk_ioctl_t)(unsigned long cmd, caddr_t data,
- int fflag, struct thread *td);
-typedef void (usb2_temp_get_desc_t)(struct usb2_device *udev,
- struct usb2_device_request *req, const void **pPtr,
- uint16_t *pLength);
-typedef void (usb2_temp_unsetup_t)(struct usb2_device *udev);
-
-/* global function pointers */
-
-extern usb2_temp_get_desc_t *usb2_temp_get_desc_p;
-extern usb2_temp_setup_by_index_t *usb2_temp_setup_by_index_p;
-extern usb2_temp_unsetup_t *usb2_temp_unsetup_p;
-extern usb2_test_quirk_t *usb2_test_quirk_p;
-extern usb2_test_huawei_autoinst_t *usb2_test_huawei_autoinst_p;
-extern usb2_quirk_ioctl_t *usb2_quirk_ioctl_p;
-extern devclass_t usb2_devclass_ptr;
-
-/* function prototypes */
-
-void usb2_test_huawei_unload(void *);
-void usb2_temp_unload(void *);
-void usb2_quirk_unload(void *);
-void usb2_bus_unload(void *);
-
-uint8_t usb2_test_quirk(const struct usb2_attach_arg *uaa, uint16_t quirk);
-
-#endif /* _USB2_DYNAMIC_H_ */
diff --git a/sys/dev/usb2/core/usb2_error.c b/sys/dev/usb2/core/usb2_error.c
deleted file mode 100644
index 8ee57b4..0000000
--- a/sys/dev/usb2/core/usb2_error.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#include <dev/usb2/core/usb2_core.h>
-
-static const char* usb_errstr_table[USB_ERR_MAX] = {
- [USB_ERR_NORMAL_COMPLETION] = "USB_ERR_NORMAL_COMPLETION",
- [USB_ERR_PENDING_REQUESTS] = "USB_ERR_PENDING_REQUESTS",
- [USB_ERR_NOT_STARTED] = "USB_ERR_NOT_STARTED",
- [USB_ERR_INVAL] = "USB_ERR_INVAL",
- [USB_ERR_NOMEM] = "USB_ERR_NOMEM",
- [USB_ERR_CANCELLED] = "USB_ERR_CANCELLED",
- [USB_ERR_BAD_ADDRESS] = "USB_ERR_BAD_ADDRESS",
- [USB_ERR_BAD_BUFSIZE] = "USB_ERR_BAD_BUFSIZE",
- [USB_ERR_BAD_FLAG] = "USB_ERR_BAD_FLAG",
- [USB_ERR_NO_CALLBACK] = "USB_ERR_NO_CALLBACK",
- [USB_ERR_IN_USE] = "USB_ERR_IN_USE",
- [USB_ERR_NO_ADDR] = "USB_ERR_NO_ADDR",
- [USB_ERR_NO_PIPE] = "USB_ERR_NO_PIPE",
- [USB_ERR_ZERO_NFRAMES] = "USB_ERR_ZERO_NFRAMES",
- [USB_ERR_ZERO_MAXP] = "USB_ERR_ZERO_MAXP",
- [USB_ERR_SET_ADDR_FAILED] = "USB_ERR_SET_ADDR_FAILED",
- [USB_ERR_NO_POWER] = "USB_ERR_NO_POWER",
- [USB_ERR_TOO_DEEP] = "USB_ERR_TOO_DEEP",
- [USB_ERR_IOERROR] = "USB_ERR_IOERROR",
- [USB_ERR_NOT_CONFIGURED] = "USB_ERR_NOT_CONFIGURED",
- [USB_ERR_TIMEOUT] = "USB_ERR_TIMEOUT",
- [USB_ERR_SHORT_XFER] = "USB_ERR_SHORT_XFER",
- [USB_ERR_STALLED] = "USB_ERR_STALLED",
- [USB_ERR_INTERRUPTED] = "USB_ERR_INTERRUPTED",
- [USB_ERR_DMA_LOAD_FAILED] = "USB_ERR_DMA_LOAD_FAILED",
- [USB_ERR_BAD_CONTEXT] = "USB_ERR_BAD_CONTEXT",
- [USB_ERR_NO_ROOT_HUB] = "USB_ERR_NO_ROOT_HUB",
- [USB_ERR_NO_INTR_THREAD] = "USB_ERR_NO_INTR_THREAD",
- [USB_ERR_NOT_LOCKED] = "USB_ERR_NOT_LOCKED",
-};
-
-/*------------------------------------------------------------------------*
- * usb2_errstr
- *
- * This function converts an USB error code into a string.
- *------------------------------------------------------------------------*/
-const char *
-usb2_errstr(usb2_error_t err)
-{
- return (err < USB_ERR_MAX ? usb_errstr_table[err] : "USB_ERR_UNKNOWN");
-}
diff --git a/sys/dev/usb2/core/usb2_generic.c b/sys/dev/usb2/core/usb2_generic.c
deleted file mode 100644
index 49f683d..0000000
--- a/sys/dev/usb2/core/usb2_generic.c
+++ /dev/null
@@ -1,2195 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR ugen_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-#include <dev/usb2/core/usb2_dev.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_hub.h>
-#include <dev/usb2/core/usb2_generic.h>
-#include <dev/usb2/core/usb2_transfer.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-
-/* defines */
-
-#define UGEN_BULK_FS_BUFFER_SIZE (64*32) /* bytes */
-#define UGEN_BULK_HS_BUFFER_SIZE (1024*32) /* bytes */
-#define UGEN_HW_FRAMES 50 /* number of milliseconds per transfer */
-
-/* function prototypes */
-
-static usb2_callback_t ugen_read_clear_stall_callback;
-static usb2_callback_t ugen_write_clear_stall_callback;
-static usb2_callback_t ugen_default_read_callback;
-static usb2_callback_t ugen_default_write_callback;
-static usb2_callback_t ugen_isoc_read_callback;
-static usb2_callback_t ugen_isoc_write_callback;
-static usb2_callback_t ugen_default_fs_callback;
-
-static usb2_fifo_open_t ugen_open;
-static usb2_fifo_close_t ugen_close;
-static usb2_fifo_ioctl_t ugen_ioctl;
-static usb2_fifo_ioctl_t ugen_ioctl_post;
-static usb2_fifo_cmd_t ugen_start_read;
-static usb2_fifo_cmd_t ugen_start_write;
-static usb2_fifo_cmd_t ugen_stop_io;
-
-static int ugen_transfer_setup(struct usb2_fifo *,
- const struct usb2_config *, uint8_t);
-static int ugen_open_pipe_write(struct usb2_fifo *);
-static int ugen_open_pipe_read(struct usb2_fifo *);
-static int ugen_set_config(struct usb2_fifo *, uint8_t);
-static int ugen_set_interface(struct usb2_fifo *, uint8_t, uint8_t);
-static int ugen_get_cdesc(struct usb2_fifo *, struct usb2_gen_descriptor *);
-static int ugen_get_sdesc(struct usb2_fifo *, struct usb2_gen_descriptor *);
-static int ugen_get_iface_driver(struct usb2_fifo *f, struct usb2_gen_descriptor *ugd);
-static int usb2_gen_fill_deviceinfo(struct usb2_fifo *,
- struct usb2_device_info *);
-static int ugen_re_enumerate(struct usb2_fifo *);
-static int ugen_iface_ioctl(struct usb2_fifo *, u_long, void *, int);
-static uint8_t ugen_fs_get_complete(struct usb2_fifo *, uint8_t *);
-static int ugen_fs_uninit(struct usb2_fifo *f);
-
-/* structures */
-
-struct usb2_fifo_methods usb2_ugen_methods = {
- .f_open = &ugen_open,
- .f_close = &ugen_close,
- .f_ioctl = &ugen_ioctl,
- .f_ioctl_post = &ugen_ioctl_post,
- .f_start_read = &ugen_start_read,
- .f_stop_read = &ugen_stop_io,
- .f_start_write = &ugen_start_write,
- .f_stop_write = &ugen_stop_io,
-};
-
-#if USB_DEBUG
-static int ugen_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ugen, CTLFLAG_RW, 0, "USB generic");
-SYSCTL_INT(_hw_usb2_ugen, OID_AUTO, debug, CTLFLAG_RW, &ugen_debug,
- 0, "Debug level");
-#endif
-
-
-/* prototypes */
-
-static int
-ugen_transfer_setup(struct usb2_fifo *f,
- const struct usb2_config *setup, uint8_t n_setup)
-{
- struct usb2_pipe *pipe = f->priv_sc0;
- struct usb2_device *udev = f->udev;
- uint8_t iface_index = pipe->iface_index;
- int error;
-
- mtx_unlock(f->priv_mtx);
-
- /*
- * "usb2_transfer_setup()" can sleep so one needs to make a wrapper,
- * exiting the mutex and checking things
- */
- error = usb2_transfer_setup(udev, &iface_index, f->xfer,
- setup, n_setup, f, f->priv_mtx);
- if (error == 0) {
-
- if (f->xfer[0]->nframes == 1) {
- error = usb2_fifo_alloc_buffer(f,
- f->xfer[0]->max_data_length, 2);
- } else {
- error = usb2_fifo_alloc_buffer(f,
- f->xfer[0]->max_frame_size,
- 2 * f->xfer[0]->nframes);
- }
- if (error) {
- usb2_transfer_unsetup(f->xfer, n_setup);
- }
- }
- mtx_lock(f->priv_mtx);
-
- return (error);
-}
-
-static int
-ugen_open(struct usb2_fifo *f, int fflags, struct thread *td)
-{
- struct usb2_pipe *pipe = f->priv_sc0;
- struct usb2_endpoint_descriptor *ed = pipe->edesc;
- uint8_t type;
-
- DPRINTFN(6, "flag=0x%x\n", fflags);
-
- mtx_lock(f->priv_mtx);
- switch (usb2_get_speed(f->udev)) {
- case USB_SPEED_LOW:
- case USB_SPEED_FULL:
- f->nframes = UGEN_HW_FRAMES;
- f->bufsize = UGEN_BULK_FS_BUFFER_SIZE;
- break;
- default:
- f->nframes = UGEN_HW_FRAMES * 8;
- f->bufsize = UGEN_BULK_HS_BUFFER_SIZE;
- break;
- }
-
- type = ed->bmAttributes & UE_XFERTYPE;
- if (type == UE_INTERRUPT) {
- f->bufsize = 0; /* use "wMaxPacketSize" */
- }
- f->timeout = USB_NO_TIMEOUT;
- f->flag_short = 0;
- f->fifo_zlp = 0;
- mtx_unlock(f->priv_mtx);
-
- return (0);
-}
-
-static void
-ugen_close(struct usb2_fifo *f, int fflags, struct thread *td)
-{
- DPRINTFN(6, "flag=0x%x\n", fflags);
-
- /* cleanup */
-
- mtx_lock(f->priv_mtx);
- usb2_transfer_stop(f->xfer[0]);
- usb2_transfer_stop(f->xfer[1]);
- mtx_unlock(f->priv_mtx);
-
- usb2_transfer_unsetup(f->xfer, 2);
- usb2_fifo_free_buffer(f);
-
- if (ugen_fs_uninit(f)) {
- /* ignore any errors - we are closing */
- DPRINTFN(6, "no FIFOs\n");
- }
-}
-
-static int
-ugen_open_pipe_write(struct usb2_fifo *f)
-{
- struct usb2_config usb2_config[2];
- struct usb2_pipe *pipe = f->priv_sc0;
- struct usb2_endpoint_descriptor *ed = pipe->edesc;
-
- mtx_assert(f->priv_mtx, MA_OWNED);
-
- if (f->xfer[0] || f->xfer[1]) {
- /* transfers are already opened */
- return (0);
- }
- bzero(usb2_config, sizeof(usb2_config));
-
- usb2_config[1].type = UE_CONTROL;
- usb2_config[1].endpoint = 0;
- usb2_config[1].direction = UE_DIR_ANY;
- usb2_config[1].mh.timeout = 1000; /* 1 second */
- usb2_config[1].mh.interval = 50;/* 50 milliseconds */
- usb2_config[1].mh.bufsize = sizeof(struct usb2_device_request);
- usb2_config[1].mh.callback = &ugen_write_clear_stall_callback;
-
- usb2_config[0].type = ed->bmAttributes & UE_XFERTYPE;
- usb2_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
- usb2_config[0].direction = ed->bEndpointAddress & (UE_DIR_OUT | UE_DIR_IN);
- usb2_config[0].mh.interval = USB_DEFAULT_INTERVAL;
- usb2_config[0].mh.flags.proxy_buffer = 1;
-
- switch (ed->bmAttributes & UE_XFERTYPE) {
- case UE_INTERRUPT:
- case UE_BULK:
- if (f->flag_short) {
- usb2_config[0].mh.flags.force_short_xfer = 1;
- }
- usb2_config[0].mh.callback = &ugen_default_write_callback;
- usb2_config[0].mh.timeout = f->timeout;
- usb2_config[0].mh.frames = 1;
- usb2_config[0].mh.bufsize = f->bufsize;
- usb2_config[0].md = usb2_config[0].mh; /* symmetric config */
- if (ugen_transfer_setup(f, usb2_config, 2)) {
- return (EIO);
- }
- /* first transfer does not clear stall */
- f->flag_stall = 0;
- break;
-
- case UE_ISOCHRONOUS:
- usb2_config[0].mh.flags.short_xfer_ok = 1;
- usb2_config[0].mh.bufsize = 0; /* use default */
- usb2_config[0].mh.frames = f->nframes;
- usb2_config[0].mh.callback = &ugen_isoc_write_callback;
- usb2_config[0].mh.timeout = 0;
- usb2_config[0].md = usb2_config[0].mh; /* symmetric config */
-
- /* clone configuration */
- usb2_config[1] = usb2_config[0];
-
- if (ugen_transfer_setup(f, usb2_config, 2)) {
- return (EIO);
- }
- break;
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-static int
-ugen_open_pipe_read(struct usb2_fifo *f)
-{
- struct usb2_config usb2_config[2];
- struct usb2_pipe *pipe = f->priv_sc0;
- struct usb2_endpoint_descriptor *ed = pipe->edesc;
-
- mtx_assert(f->priv_mtx, MA_OWNED);
-
- if (f->xfer[0] || f->xfer[1]) {
- /* transfers are already opened */
- return (0);
- }
- bzero(usb2_config, sizeof(usb2_config));
-
- usb2_config[1].type = UE_CONTROL;
- usb2_config[1].endpoint = 0;
- usb2_config[1].direction = UE_DIR_ANY;
- usb2_config[1].mh.timeout = 1000; /* 1 second */
- usb2_config[1].mh.interval = 50;/* 50 milliseconds */
- usb2_config[1].mh.bufsize = sizeof(struct usb2_device_request);
- usb2_config[1].mh.callback = &ugen_read_clear_stall_callback;
-
- usb2_config[0].type = ed->bmAttributes & UE_XFERTYPE;
- usb2_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
- usb2_config[0].direction = UE_DIR_IN;
- usb2_config[0].mh.interval = USB_DEFAULT_INTERVAL;
- usb2_config[0].mh.flags.proxy_buffer = 1;
-
- switch (ed->bmAttributes & UE_XFERTYPE) {
- case UE_INTERRUPT:
- case UE_BULK:
- if (f->flag_short) {
- usb2_config[0].mh.flags.short_xfer_ok = 1;
- }
- usb2_config[0].mh.timeout = f->timeout;
- usb2_config[0].mh.frames = 1;
- usb2_config[0].mh.callback = &ugen_default_read_callback;
- usb2_config[0].mh.bufsize = f->bufsize;
- usb2_config[0].md = usb2_config[0].mh; /* symmetric config */
-
- if (ugen_transfer_setup(f, usb2_config, 2)) {
- return (EIO);
- }
- /* first transfer does not clear stall */
- f->flag_stall = 0;
- break;
-
- case UE_ISOCHRONOUS:
- usb2_config[0].mh.flags.short_xfer_ok = 1;
- usb2_config[0].mh.bufsize = 0; /* use default */
- usb2_config[0].mh.frames = f->nframes;
- usb2_config[0].mh.callback = &ugen_isoc_read_callback;
- usb2_config[0].mh.timeout = 0;
- usb2_config[0].md = usb2_config[0].mh; /* symmetric config */
-
- /* clone configuration */
- usb2_config[1] = usb2_config[0];
-
- if (ugen_transfer_setup(f, usb2_config, 2)) {
- return (EIO);
- }
- break;
-
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-static void
-ugen_start_read(struct usb2_fifo *f)
-{
- /* check that pipes are open */
- if (ugen_open_pipe_read(f)) {
- /* signal error */
- usb2_fifo_put_data_error(f);
- }
- /* start transfers */
- usb2_transfer_start(f->xfer[0]);
- usb2_transfer_start(f->xfer[1]);
-}
-
-static void
-ugen_start_write(struct usb2_fifo *f)
-{
- /* check that pipes are open */
- if (ugen_open_pipe_write(f)) {
- /* signal error */
- usb2_fifo_get_data_error(f);
- }
- /* start transfers */
- usb2_transfer_start(f->xfer[0]);
- usb2_transfer_start(f->xfer[1]);
-}
-
-static void
-ugen_stop_io(struct usb2_fifo *f)
-{
- /* stop transfers */
- usb2_transfer_stop(f->xfer[0]);
- usb2_transfer_stop(f->xfer[1]);
-}
-
-static void
-ugen_default_read_callback(struct usb2_xfer *xfer)
-{
- struct usb2_fifo *f = xfer->priv_sc;
- struct usb2_mbuf *m;
-
- DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes);
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- if (xfer->actlen == 0) {
- if (f->fifo_zlp != 4) {
- f->fifo_zlp++;
- } else {
- /*
- * Throttle a little bit we have multiple ZLPs
- * in a row!
- */
- xfer->interval = 64; /* ms */
- }
- } else {
- /* clear throttle */
- xfer->interval = 0;
- f->fifo_zlp = 0;
- }
- usb2_fifo_put_data(f, xfer->frbuffers, 0,
- xfer->actlen, 1);
-
- case USB_ST_SETUP:
- if (f->flag_stall) {
- usb2_transfer_start(f->xfer[1]);
- break;
- }
- USB_IF_POLL(&f->free_q, m);
- if (m) {
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- f->flag_stall = 1;
- f->fifo_zlp = 0;
- usb2_transfer_start(f->xfer[1]);
- }
- break;
- }
-}
-
-static void
-ugen_default_write_callback(struct usb2_xfer *xfer)
-{
- struct usb2_fifo *f = xfer->priv_sc;
- uint32_t actlen;
-
- DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes);
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
- /*
- * If writing is in stall, just jump to clear stall
- * callback and solve the situation.
- */
- if (f->flag_stall) {
- usb2_transfer_start(f->xfer[1]);
- break;
- }
- /*
- * Write data, setup and perform hardware transfer.
- */
- if (usb2_fifo_get_data(f, xfer->frbuffers, 0,
- xfer->max_data_length, &actlen, 0)) {
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- f->flag_stall = 1;
- usb2_transfer_start(f->xfer[1]);
- }
- break;
- }
-}
-
-static void
-ugen_read_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct usb2_fifo *f = xfer->priv_sc;
- struct usb2_xfer *xfer_other = f->xfer[0];
-
- if (f->flag_stall == 0) {
- /* nothing to do */
- return;
- }
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTFN(5, "f=%p: stall cleared\n", f);
- f->flag_stall = 0;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
-ugen_write_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct usb2_fifo *f = xfer->priv_sc;
- struct usb2_xfer *xfer_other = f->xfer[0];
-
- if (f->flag_stall == 0) {
- /* nothing to do */
- return;
- }
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTFN(5, "f=%p: stall cleared\n", f);
- f->flag_stall = 0;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
-ugen_isoc_read_callback(struct usb2_xfer *xfer)
-{
- struct usb2_fifo *f = xfer->priv_sc;
- uint32_t offset;
- uint16_t n;
-
- DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes);
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- DPRINTFN(6, "actlen=%d\n", xfer->actlen);
-
- offset = 0;
-
- for (n = 0; n != xfer->aframes; n++) {
- usb2_fifo_put_data(f, xfer->frbuffers, offset,
- xfer->frlengths[n], 1);
- offset += xfer->max_frame_size;
- }
-
- case USB_ST_SETUP:
-tr_setup:
- for (n = 0; n != xfer->nframes; n++) {
- /* setup size for next transfer */
- xfer->frlengths[n] = xfer->max_frame_size;
- }
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- break;
- }
- goto tr_setup;
- }
-}
-
-static void
-ugen_isoc_write_callback(struct usb2_xfer *xfer)
-{
- struct usb2_fifo *f = xfer->priv_sc;
- uint32_t actlen;
- uint32_t offset;
- uint16_t n;
-
- DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes);
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- case USB_ST_SETUP:
-tr_setup:
- offset = 0;
- for (n = 0; n != xfer->nframes; n++) {
- if (usb2_fifo_get_data(f, xfer->frbuffers, offset,
- xfer->max_frame_size, &actlen, 1)) {
- xfer->frlengths[n] = actlen;
- offset += actlen;
- } else {
- break;
- }
- }
-
- for (; n != xfer->nframes; n++) {
- /* fill in zero frames */
- xfer->frlengths[n] = 0;
- }
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- break;
- }
- goto tr_setup;
- }
-}
-
-static int
-ugen_set_config(struct usb2_fifo *f, uint8_t index)
-{
- DPRINTFN(2, "index %u\n", index);
-
- if (f->udev->flags.usb2_mode != USB_MODE_HOST) {
- /* not possible in device side mode */
- return (ENOTTY);
- }
- if (f->udev->curr_config_index == index) {
- /* no change needed */
- return (0);
- }
- /* make sure all FIFO's are gone */
- /* else there can be a deadlock */
- if (ugen_fs_uninit(f)) {
- /* ignore any errors */
- DPRINTFN(6, "no FIFOs\n");
- }
- /* change setting - will free generic FIFOs, if any */
- if (usb2_set_config_index(f->udev, index)) {
- return (EIO);
- }
- /* probe and attach */
- if (usb2_probe_and_attach(f->udev, USB_IFACE_INDEX_ANY)) {
- return (EIO);
- }
- return (0);
-}
-
-static int
-ugen_set_interface(struct usb2_fifo *f,
- uint8_t iface_index, uint8_t alt_index)
-{
- DPRINTFN(2, "%u, %u\n", iface_index, alt_index);
-
- if (f->udev->flags.usb2_mode != USB_MODE_HOST) {
- /* not possible in device side mode */
- return (ENOTTY);
- }
- /* make sure all FIFO's are gone */
- /* else there can be a deadlock */
- if (ugen_fs_uninit(f)) {
- /* ignore any errors */
- DPRINTFN(6, "no FIFOs\n");
- }
- /* change setting - will free generic FIFOs, if any */
- if (usb2_set_alt_interface_index(f->udev, iface_index, alt_index)) {
- return (EIO);
- }
- /* probe and attach */
- if (usb2_probe_and_attach(f->udev, iface_index)) {
- return (EIO);
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * ugen_get_cdesc
- *
- * This function will retrieve the complete configuration descriptor
- * at the given index.
- *------------------------------------------------------------------------*/
-static int
-ugen_get_cdesc(struct usb2_fifo *f, struct usb2_gen_descriptor *ugd)
-{
- struct usb2_config_descriptor *cdesc;
- struct usb2_device *udev = f->udev;
- int error;
- uint16_t len;
- uint8_t free_data;
-
- DPRINTFN(6, "\n");
-
- if (ugd->ugd_data == NULL) {
- /* userland pointer should not be zero */
- return (EINVAL);
- }
- if ((ugd->ugd_config_index == USB_UNCONFIG_INDEX) ||
- (ugd->ugd_config_index == udev->curr_config_index)) {
- cdesc = usb2_get_config_descriptor(udev);
- if (cdesc == NULL) {
- return (ENXIO);
- }
- free_data = 0;
-
- } else {
- if (usb2_req_get_config_desc_full(udev,
- &Giant, &cdesc, M_USBDEV,
- ugd->ugd_config_index)) {
- return (ENXIO);
- }
- free_data = 1;
- }
-
- len = UGETW(cdesc->wTotalLength);
- if (len > ugd->ugd_maxlen) {
- len = ugd->ugd_maxlen;
- }
- DPRINTFN(6, "len=%u\n", len);
-
- ugd->ugd_actlen = len;
- ugd->ugd_offset = 0;
-
- error = copyout(cdesc, ugd->ugd_data, len);
-
- if (free_data) {
- free(cdesc, M_USBDEV);
- }
- return (error);
-}
-
-static int
-ugen_get_sdesc(struct usb2_fifo *f, struct usb2_gen_descriptor *ugd)
-{
- void *ptr = f->udev->bus->scratch[0].data;
- uint16_t size = sizeof(f->udev->bus->scratch[0].data);
- int error;
-
- if (usb2_req_get_string_desc(f->udev, &Giant, ptr,
- size, ugd->ugd_lang_id, ugd->ugd_string_index)) {
- error = EINVAL;
- } else {
-
- if (size > ((uint8_t *)ptr)[0]) {
- size = ((uint8_t *)ptr)[0];
- }
- if (size > ugd->ugd_maxlen) {
- size = ugd->ugd_maxlen;
- }
- ugd->ugd_actlen = size;
- ugd->ugd_offset = 0;
-
- error = copyout(ptr, ugd->ugd_data, size);
- }
- return (error);
-}
-
-/*------------------------------------------------------------------------*
- * ugen_get_iface_driver
- *
- * This function generates an USB interface description for userland.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static int
-ugen_get_iface_driver(struct usb2_fifo *f, struct usb2_gen_descriptor *ugd)
-{
- struct usb2_device *udev = f->udev;
- struct usb2_interface *iface;
- const char *ptr;
- const char *desc;
- unsigned int len;
- unsigned int maxlen;
- char buf[128];
- int error;
-
- DPRINTFN(6, "\n");
-
- if ((ugd->ugd_data == NULL) || (ugd->ugd_maxlen == 0)) {
- /* userland pointer should not be zero */
- return (EINVAL);
- }
-
- iface = usb2_get_iface(udev, ugd->ugd_iface_index);
- if ((iface == NULL) || (iface->idesc == NULL)) {
- /* invalid interface index */
- return (EINVAL);
- }
-
- /* read out device nameunit string, if any */
- if ((iface->subdev != NULL) &&
- device_is_attached(iface->subdev) &&
- (ptr = device_get_nameunit(iface->subdev)) &&
- (desc = device_get_desc(iface->subdev))) {
-
- /* print description */
- snprintf(buf, sizeof(buf), "%s: <%s>", ptr, desc);
-
- /* range checks */
- maxlen = ugd->ugd_maxlen - 1;
- len = strlen(buf);
- if (len > maxlen)
- len = maxlen;
-
- /* update actual length, including terminating zero */
- ugd->ugd_actlen = len + 1;
-
- /* copy out interface description */
- error = copyout(buf, ugd->ugd_data, ugd->ugd_actlen);
- } else {
- /* zero length string is default */
- error = copyout("", ugd->ugd_data, 1);
- }
- return (error);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_gen_fill_deviceinfo
- *
- * This function dumps information about an USB device to the
- * structure pointed to by the "di" argument.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static int
-usb2_gen_fill_deviceinfo(struct usb2_fifo *f, struct usb2_device_info *di)
-{
- struct usb2_device *udev;
- struct usb2_device *hub;
-
- udev = f->udev;
-
- bzero(di, sizeof(di[0]));
-
- di->udi_bus = device_get_unit(udev->bus->bdev);
- di->udi_addr = udev->address;
- di->udi_index = udev->device_index;
- strlcpy(di->udi_serial, udev->serial,
- sizeof(di->udi_serial));
- strlcpy(di->udi_vendor, udev->manufacturer,
- sizeof(di->udi_vendor));
- strlcpy(di->udi_product, udev->product,
- sizeof(di->udi_product));
- usb2_printBCD(di->udi_release, sizeof(di->udi_release),
- UGETW(udev->ddesc.bcdDevice));
- di->udi_vendorNo = UGETW(udev->ddesc.idVendor);
- di->udi_productNo = UGETW(udev->ddesc.idProduct);
- di->udi_releaseNo = UGETW(udev->ddesc.bcdDevice);
- di->udi_class = udev->ddesc.bDeviceClass;
- di->udi_subclass = udev->ddesc.bDeviceSubClass;
- di->udi_protocol = udev->ddesc.bDeviceProtocol;
- di->udi_config_no = udev->curr_config_no;
- di->udi_config_index = udev->curr_config_index;
- di->udi_power = udev->flags.self_powered ? 0 : udev->power;
- di->udi_speed = udev->speed;
- di->udi_mode = udev->flags.usb2_mode;
- di->udi_power_mode = udev->power_mode;
- if (udev->flags.suspended) {
- di->udi_suspended = 1;
- } else {
- di->udi_suspended = 0;
- }
-
- hub = udev->parent_hub;
- if (hub) {
- di->udi_hubaddr = hub->address;
- di->udi_hubindex = hub->device_index;
- di->udi_hubport = udev->port_no;
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * ugen_check_request
- *
- * Return values:
- * 0: Access allowed
- * Else: No access
- *------------------------------------------------------------------------*/
-static int
-ugen_check_request(struct usb2_device *udev, struct usb2_device_request *req)
-{
- struct usb2_pipe *pipe;
- int error;
-
- /*
- * Avoid requests that would damage the bus integrity:
- */
- if (((req->bmRequestType == UT_WRITE_DEVICE) &&
- (req->bRequest == UR_SET_ADDRESS)) ||
- ((req->bmRequestType == UT_WRITE_DEVICE) &&
- (req->bRequest == UR_SET_CONFIG)) ||
- ((req->bmRequestType == UT_WRITE_INTERFACE) &&
- (req->bRequest == UR_SET_INTERFACE))) {
- /*
- * These requests can be useful for testing USB drivers.
- */
- error = priv_check(curthread, PRIV_DRIVER);
- if (error) {
- return (error);
- }
- }
- /*
- * Special case - handle clearing of stall
- */
- if (req->bmRequestType == UT_WRITE_ENDPOINT) {
-
- pipe = usb2_get_pipe_by_addr(udev, req->wIndex[0]);
- if (pipe == NULL) {
- return (EINVAL);
- }
- if (usb2_check_thread_perm(udev, curthread, FREAD | FWRITE,
- pipe->iface_index, req->wIndex[0] & UE_ADDR)) {
- return (EPERM);
- }
- if ((req->bRequest == UR_CLEAR_FEATURE) &&
- (UGETW(req->wValue) == UF_ENDPOINT_HALT)) {
- usb2_clear_data_toggle(udev, pipe);
- }
- }
- /* TODO: add more checks to verify the interface index */
-
- return (0);
-}
-
-int
-ugen_do_request(struct usb2_fifo *f, struct usb2_ctl_request *ur)
-{
- int error;
- uint16_t len;
- uint16_t actlen;
-
- if (ugen_check_request(f->udev, &ur->ucr_request)) {
- return (EPERM);
- }
- len = UGETW(ur->ucr_request.wLength);
-
- /* check if "ucr_data" is valid */
- if (len != 0) {
- if (ur->ucr_data == NULL) {
- return (EFAULT);
- }
- }
- /* do the USB request */
- error = usb2_do_request_flags
- (f->udev, NULL, &ur->ucr_request, ur->ucr_data,
- (ur->ucr_flags & USB_SHORT_XFER_OK) |
- USB_USER_DATA_PTR, &actlen,
- USB_DEFAULT_TIMEOUT);
-
- ur->ucr_actlen = actlen;
-
- if (error) {
- error = EIO;
- }
- return (error);
-}
-
-/*------------------------------------------------------------------------
- * ugen_re_enumerate
- *------------------------------------------------------------------------*/
-static int
-ugen_re_enumerate(struct usb2_fifo *f)
-{
- struct usb2_device *udev = f->udev;
- int error;
-
- /*
- * This request can be useful for testing USB drivers:
- */
- error = priv_check(curthread, PRIV_DRIVER);
- if (error) {
- return (error);
- }
- /* get the device unconfigured */
- error = ugen_set_config(f, USB_UNCONFIG_INDEX);
- if (error) {
- return (error);
- }
- /* do a bus-reset */
- mtx_lock(f->priv_mtx);
- error = usb2_req_re_enumerate(udev, f->priv_mtx);
- mtx_unlock(f->priv_mtx);
-
- if (error) {
- return (ENXIO);
- }
- /* restore configuration to index 0 */
- error = ugen_set_config(f, 0);
- if (error) {
- return (error);
- }
- return (0);
-}
-
-int
-ugen_fs_uninit(struct usb2_fifo *f)
-{
- if (f->fs_xfer == NULL) {
- return (EINVAL);
- }
- usb2_transfer_unsetup(f->fs_xfer, f->fs_ep_max);
- free(f->fs_xfer, M_USB);
- f->fs_xfer = NULL;
- f->fs_ep_max = 0;
- f->fs_ep_ptr = NULL;
- f->flag_iscomplete = 0;
- usb2_fifo_free_buffer(f);
- return (0);
-}
-
-static uint8_t
-ugen_fs_get_complete(struct usb2_fifo *f, uint8_t *pindex)
-{
- struct usb2_mbuf *m;
-
- USB_IF_DEQUEUE(&f->used_q, m);
-
- if (m) {
- *pindex = *((uint8_t *)(m->cur_data_ptr));
-
- USB_IF_ENQUEUE(&f->free_q, m);
-
- return (0); /* success */
- } else {
-
- *pindex = 0; /* fix compiler warning */
-
- f->flag_iscomplete = 0;
- }
- return (1); /* failure */
-}
-
-static void
-ugen_fs_set_complete(struct usb2_fifo *f, uint8_t index)
-{
- struct usb2_mbuf *m;
-
- USB_IF_DEQUEUE(&f->free_q, m);
-
- if (m == NULL) {
- /* can happen during close */
- DPRINTF("out of buffers\n");
- return;
- }
- USB_MBUF_RESET(m);
-
- *((uint8_t *)(m->cur_data_ptr)) = index;
-
- USB_IF_ENQUEUE(&f->used_q, m);
-
- f->flag_iscomplete = 1;
-
- usb2_fifo_wakeup(f);
-}
-
-static int
-ugen_fs_copy_in(struct usb2_fifo *f, uint8_t ep_index)
-{
- struct usb2_device_request *req;
- struct usb2_xfer *xfer;
- struct usb2_fs_endpoint fs_ep;
- void *uaddr; /* userland pointer */
- void *kaddr;
- uint32_t offset;
- uint32_t length;
- uint32_t n;
- uint32_t rem;
- int error;
- uint8_t isread;
-
- if (ep_index >= f->fs_ep_max) {
- return (EINVAL);
- }
- xfer = f->fs_xfer[ep_index];
- if (xfer == NULL) {
- return (EINVAL);
- }
- mtx_lock(f->priv_mtx);
- if (usb2_transfer_pending(xfer)) {
- mtx_unlock(f->priv_mtx);
- return (EBUSY); /* should not happen */
- }
- mtx_unlock(f->priv_mtx);
-
- error = copyin(f->fs_ep_ptr +
- ep_index, &fs_ep, sizeof(fs_ep));
- if (error) {
- return (error);
- }
- /* security checks */
-
- if (fs_ep.nFrames > xfer->max_frame_count) {
- xfer->error = USB_ERR_INVAL;
- goto complete;
- }
- if (fs_ep.nFrames == 0) {
- xfer->error = USB_ERR_INVAL;
- goto complete;
- }
- error = copyin(fs_ep.ppBuffer,
- &uaddr, sizeof(uaddr));
- if (error) {
- return (error);
- }
- /* reset first frame */
- usb2_set_frame_offset(xfer, 0, 0);
-
- if (xfer->flags_int.control_xfr) {
-
- req = xfer->frbuffers[0].buffer;
-
- error = copyin(fs_ep.pLength,
- &length, sizeof(length));
- if (error) {
- return (error);
- }
- if (length >= sizeof(*req)) {
- xfer->error = USB_ERR_INVAL;
- goto complete;
- }
- if (length != 0) {
- error = copyin(uaddr, req, length);
- if (error) {
- return (error);
- }
- }
- if (ugen_check_request(f->udev, req)) {
- xfer->error = USB_ERR_INVAL;
- goto complete;
- }
- xfer->frlengths[0] = length;
-
- /* Host mode only ! */
- if ((req->bmRequestType &
- (UT_READ | UT_WRITE)) == UT_READ) {
- isread = 1;
- } else {
- isread = 0;
- }
- n = 1;
- offset = sizeof(*req);
-
- } else {
- /* Device and Host mode */
- if (USB_GET_DATA_ISREAD(xfer)) {
- isread = 1;
- } else {
- isread = 0;
- }
- n = 0;
- offset = 0;
- }
-
- rem = xfer->max_data_length;
- xfer->nframes = fs_ep.nFrames;
- xfer->timeout = fs_ep.timeout;
- if (xfer->timeout > 65535) {
- xfer->timeout = 65535;
- }
- if (fs_ep.flags & USB_FS_FLAG_SINGLE_SHORT_OK)
- xfer->flags.short_xfer_ok = 1;
- else
- xfer->flags.short_xfer_ok = 0;
-
- if (fs_ep.flags & USB_FS_FLAG_MULTI_SHORT_OK)
- xfer->flags.short_frames_ok = 1;
- else
- xfer->flags.short_frames_ok = 0;
-
- if (fs_ep.flags & USB_FS_FLAG_FORCE_SHORT)
- xfer->flags.force_short_xfer = 1;
- else
- xfer->flags.force_short_xfer = 0;
-
- if (fs_ep.flags & USB_FS_FLAG_CLEAR_STALL)
- xfer->flags.stall_pipe = 1;
- else
- xfer->flags.stall_pipe = 0;
-
- for (; n != xfer->nframes; n++) {
-
- error = copyin(fs_ep.pLength + n,
- &length, sizeof(length));
- if (error) {
- break;
- }
- xfer->frlengths[n] = length;
-
- if (length > rem) {
- xfer->error = USB_ERR_INVAL;
- goto complete;
- }
- rem -= length;
-
- if (!isread) {
-
- /* we need to know the source buffer */
- error = copyin(fs_ep.ppBuffer + n,
- &uaddr, sizeof(uaddr));
- if (error) {
- break;
- }
- if (xfer->flags_int.isochronous_xfr) {
- /* get kernel buffer address */
- kaddr = xfer->frbuffers[0].buffer;
- kaddr = USB_ADD_BYTES(kaddr, offset);
- } else {
- /* set current frame offset */
- usb2_set_frame_offset(xfer, offset, n);
-
- /* get kernel buffer address */
- kaddr = xfer->frbuffers[n].buffer;
- }
-
- /* move data */
- error = copyin(uaddr, kaddr, length);
- if (error) {
- break;
- }
- }
- offset += length;
- }
- return (error);
-
-complete:
- mtx_lock(f->priv_mtx);
- ugen_fs_set_complete(f, ep_index);
- mtx_unlock(f->priv_mtx);
- return (0);
-}
-
-static int
-ugen_fs_copy_out(struct usb2_fifo *f, uint8_t ep_index)
-{
- struct usb2_device_request *req;
- struct usb2_xfer *xfer;
- struct usb2_fs_endpoint fs_ep;
- struct usb2_fs_endpoint *fs_ep_uptr; /* userland ptr */
- void *uaddr; /* userland ptr */
- void *kaddr;
- uint32_t offset;
- uint32_t length;
- uint32_t temp;
- uint32_t n;
- uint32_t rem;
- int error;
- uint8_t isread;
-
- if (ep_index >= f->fs_ep_max) {
- return (EINVAL);
- }
- xfer = f->fs_xfer[ep_index];
- if (xfer == NULL) {
- return (EINVAL);
- }
- mtx_lock(f->priv_mtx);
- if (usb2_transfer_pending(xfer)) {
- mtx_unlock(f->priv_mtx);
- return (EBUSY); /* should not happen */
- }
- mtx_unlock(f->priv_mtx);
-
- fs_ep_uptr = f->fs_ep_ptr + ep_index;
- error = copyin(fs_ep_uptr, &fs_ep, sizeof(fs_ep));
- if (error) {
- return (error);
- }
- fs_ep.status = xfer->error;
- fs_ep.aFrames = xfer->aframes;
- fs_ep.isoc_time_complete = xfer->isoc_time_complete;
- if (xfer->error) {
- goto complete;
- }
- if (xfer->flags_int.control_xfr) {
- req = xfer->frbuffers[0].buffer;
-
- /* Host mode only ! */
- if ((req->bmRequestType & (UT_READ | UT_WRITE)) == UT_READ) {
- isread = 1;
- } else {
- isread = 0;
- }
- if (xfer->nframes == 0)
- n = 0; /* should never happen */
- else
- n = 1;
- } else {
- /* Device and Host mode */
- if (USB_GET_DATA_ISREAD(xfer)) {
- isread = 1;
- } else {
- isread = 0;
- }
- n = 0;
- }
-
- /* Update lengths and copy out data */
-
- rem = xfer->max_data_length;
- offset = 0;
-
- for (; n != xfer->nframes; n++) {
-
- /* get initial length into "temp" */
- error = copyin(fs_ep.pLength + n,
- &temp, sizeof(temp));
- if (error) {
- return (error);
- }
- if (temp > rem) {
- /* the userland length has been corrupted */
- DPRINTF("corrupt userland length "
- "%u > %u\n", temp, rem);
- fs_ep.status = USB_ERR_INVAL;
- goto complete;
- }
- rem -= temp;
-
- /* get actual transfer length */
- length = xfer->frlengths[n];
- if (length > temp) {
- /* data overflow */
- fs_ep.status = USB_ERR_INVAL;
- DPRINTF("data overflow %u > %u\n",
- length, temp);
- goto complete;
- }
- if (isread) {
-
- /* we need to know the destination buffer */
- error = copyin(fs_ep.ppBuffer + n,
- &uaddr, sizeof(uaddr));
- if (error) {
- return (error);
- }
- if (xfer->flags_int.isochronous_xfr) {
- /* only one frame buffer */
- kaddr = USB_ADD_BYTES(
- xfer->frbuffers[0].buffer, offset);
- } else {
- /* multiple frame buffers */
- kaddr = xfer->frbuffers[n].buffer;
- }
-
- /* move data */
- error = copyout(kaddr, uaddr, length);
- if (error) {
- return (error);
- }
- }
- /*
- * Update offset according to initial length, which is
- * needed by isochronous transfers!
- */
- offset += temp;
-
- /* update length */
- error = copyout(&length,
- fs_ep.pLength + n, sizeof(length));
- if (error) {
- return (error);
- }
- }
-
-complete:
- /* update "aFrames" */
- error = copyout(&fs_ep.aFrames, &fs_ep_uptr->aFrames,
- sizeof(fs_ep.aFrames));
- if (error)
- goto done;
-
- /* update "isoc_time_complete" */
- error = copyout(&fs_ep.isoc_time_complete,
- &fs_ep_uptr->isoc_time_complete,
- sizeof(fs_ep.isoc_time_complete));
- if (error)
- goto done;
- /* update "status" */
- error = copyout(&fs_ep.status, &fs_ep_uptr->status,
- sizeof(fs_ep.status));
-done:
- return (error);
-}
-
-static uint8_t
-ugen_fifo_in_use(struct usb2_fifo *f, int fflags)
-{
- struct usb2_fifo *f_rx;
- struct usb2_fifo *f_tx;
-
- f_rx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_RX];
- f_tx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_TX];
-
- if ((fflags & FREAD) && f_rx &&
- (f_rx->xfer[0] || f_rx->xfer[1])) {
- return (1); /* RX FIFO in use */
- }
- if ((fflags & FWRITE) && f_tx &&
- (f_tx->xfer[0] || f_tx->xfer[1])) {
- return (1); /* TX FIFO in use */
- }
- return (0); /* not in use */
-}
-
-static int
-ugen_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags,
- struct thread *td)
-{
- struct usb2_config usb2_config[1];
- struct usb2_device_request req;
- union {
- struct usb2_fs_complete *pcomp;
- struct usb2_fs_start *pstart;
- struct usb2_fs_stop *pstop;
- struct usb2_fs_open *popen;
- struct usb2_fs_close *pclose;
- struct usb2_fs_clear_stall_sync *pstall;
- void *addr;
- } u;
- struct usb2_pipe *pipe;
- struct usb2_endpoint_descriptor *ed;
- int error = 0;
- uint8_t iface_index;
- uint8_t isread;
- uint8_t ep_index;
-
- u.addr = addr;
-
- DPRINTFN(6, "cmd=0x%08lx\n", cmd);
-
- switch (cmd) {
- case USB_FS_COMPLETE:
- mtx_lock(f->priv_mtx);
- error = ugen_fs_get_complete(f, &ep_index);
- mtx_unlock(f->priv_mtx);
-
- if (error) {
- error = EBUSY;
- break;
- }
- u.pcomp->ep_index = ep_index;
- error = ugen_fs_copy_out(f, u.pcomp->ep_index);
- break;
-
- case USB_FS_START:
- error = ugen_fs_copy_in(f, u.pstart->ep_index);
- if (error) {
- break;
- }
- mtx_lock(f->priv_mtx);
- usb2_transfer_start(f->fs_xfer[u.pstart->ep_index]);
- mtx_unlock(f->priv_mtx);
- break;
-
- case USB_FS_STOP:
- if (u.pstop->ep_index >= f->fs_ep_max) {
- error = EINVAL;
- break;
- }
- mtx_lock(f->priv_mtx);
- usb2_transfer_stop(f->fs_xfer[u.pstop->ep_index]);
- mtx_unlock(f->priv_mtx);
- break;
-
- case USB_FS_OPEN:
- if (u.popen->ep_index >= f->fs_ep_max) {
- error = EINVAL;
- break;
- }
- if (f->fs_xfer[u.popen->ep_index] != NULL) {
- error = EBUSY;
- break;
- }
- if (u.popen->max_bufsize > USB_FS_MAX_BUFSIZE) {
- u.popen->max_bufsize = USB_FS_MAX_BUFSIZE;
- }
- if (u.popen->max_frames > USB_FS_MAX_FRAMES) {
- u.popen->max_frames = USB_FS_MAX_FRAMES;
- break;
- }
- if (u.popen->max_frames == 0) {
- error = EINVAL;
- break;
- }
- pipe = usb2_get_pipe_by_addr(f->udev, u.popen->ep_no);
- if (pipe == NULL) {
- error = EINVAL;
- break;
- }
- ed = pipe->edesc;
- if (ed == NULL) {
- error = ENXIO;
- break;
- }
- iface_index = pipe->iface_index;
-
- error = usb2_check_thread_perm(f->udev, curthread, fflags,
- iface_index, u.popen->ep_no);
- if (error) {
- break;
- }
- bzero(usb2_config, sizeof(usb2_config));
-
- usb2_config[0].type = ed->bmAttributes & UE_XFERTYPE;
- usb2_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
- usb2_config[0].direction = ed->bEndpointAddress & (UE_DIR_OUT | UE_DIR_IN);
- usb2_config[0].mh.interval = USB_DEFAULT_INTERVAL;
- usb2_config[0].mh.flags.proxy_buffer = 1;
- usb2_config[0].mh.callback = &ugen_default_fs_callback;
- usb2_config[0].mh.timeout = 0; /* no timeout */
- usb2_config[0].mh.frames = u.popen->max_frames;
- usb2_config[0].mh.bufsize = u.popen->max_bufsize;
- usb2_config[0].md = usb2_config[0].mh; /* symmetric config */
-
- if (usb2_config[0].type == UE_CONTROL) {
- if (f->udev->flags.usb2_mode != USB_MODE_HOST) {
- error = EINVAL;
- break;
- }
- } else {
-
- isread = ((usb2_config[0].endpoint &
- (UE_DIR_IN | UE_DIR_OUT)) == UE_DIR_IN);
-
- if (f->udev->flags.usb2_mode != USB_MODE_HOST) {
- isread = !isread;
- }
- /* check permissions */
- if (isread) {
- if (!(fflags & FREAD)) {
- error = EPERM;
- break;
- }
- } else {
- if (!(fflags & FWRITE)) {
- error = EPERM;
- break;
- }
- }
- }
- error = usb2_transfer_setup(f->udev, &iface_index,
- f->fs_xfer + u.popen->ep_index, usb2_config, 1,
- f, f->priv_mtx);
- if (error == 0) {
- /* update maximums */
- u.popen->max_packet_length =
- f->fs_xfer[u.popen->ep_index]->max_frame_size;
- u.popen->max_bufsize =
- f->fs_xfer[u.popen->ep_index]->max_data_length;
- f->fs_xfer[u.popen->ep_index]->priv_fifo =
- ((uint8_t *)0) + u.popen->ep_index;
- } else {
- error = ENOMEM;
- }
- break;
-
- case USB_FS_CLOSE:
- if (u.pclose->ep_index >= f->fs_ep_max) {
- error = EINVAL;
- break;
- }
- if (f->fs_xfer[u.pclose->ep_index] == NULL) {
- error = EINVAL;
- break;
- }
- usb2_transfer_unsetup(f->fs_xfer + u.pclose->ep_index, 1);
- break;
-
- case USB_FS_CLEAR_STALL_SYNC:
- if (u.pstall->ep_index >= f->fs_ep_max) {
- error = EINVAL;
- break;
- }
- if (f->fs_xfer[u.pstall->ep_index] == NULL) {
- error = EINVAL;
- break;
- }
- if (f->udev->flags.usb2_mode != USB_MODE_HOST) {
- error = EINVAL;
- break;
- }
- mtx_lock(f->priv_mtx);
- error = usb2_transfer_pending(f->fs_xfer[u.pstall->ep_index]);
- mtx_unlock(f->priv_mtx);
-
- if (error) {
- return (EBUSY);
- }
- pipe = f->fs_xfer[u.pstall->ep_index]->pipe;
-
- /* setup a clear-stall packet */
- req.bmRequestType = UT_WRITE_ENDPOINT;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, UF_ENDPOINT_HALT);
- req.wIndex[0] = pipe->edesc->bEndpointAddress;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- error = usb2_do_request(f->udev, NULL, &req, NULL);
- if (error == 0) {
- usb2_clear_data_toggle(f->udev, pipe);
- } else {
- error = ENXIO;
- }
- break;
-
- default:
- error = ENOIOCTL;
- break;
- }
-
- DPRINTFN(6, "error=%d\n", error);
-
- return (error);
-}
-
-static int
-ugen_set_short_xfer(struct usb2_fifo *f, void *addr)
-{
- uint8_t t;
-
- if (*(int *)addr)
- t = 1;
- else
- t = 0;
-
- if (f->flag_short == t) {
- /* same value like before - accept */
- return (0);
- }
- if (f->xfer[0] || f->xfer[1]) {
- /* cannot change this during transfer */
- return (EBUSY);
- }
- f->flag_short = t;
- return (0);
-}
-
-static int
-ugen_set_timeout(struct usb2_fifo *f, void *addr)
-{
- f->timeout = *(int *)addr;
- if (f->timeout > 65535) {
- /* limit user input */
- f->timeout = 65535;
- }
- return (0);
-}
-
-static int
-ugen_get_frame_size(struct usb2_fifo *f, void *addr)
-{
- if (f->xfer[0]) {
- *(int *)addr = f->xfer[0]->max_frame_size;
- } else {
- return (EINVAL);
- }
- return (0);
-}
-
-static int
-ugen_set_buffer_size(struct usb2_fifo *f, void *addr)
-{
- uint32_t t;
-
- if (*(int *)addr < 1024)
- t = 1024;
- else if (*(int *)addr < (256 * 1024))
- t = *(int *)addr;
- else
- t = 256 * 1024;
-
- if (f->bufsize == t) {
- /* same value like before - accept */
- return (0);
- }
- if (f->xfer[0] || f->xfer[1]) {
- /* cannot change this during transfer */
- return (EBUSY);
- }
- f->bufsize = t;
- return (0);
-}
-
-static int
-ugen_get_buffer_size(struct usb2_fifo *f, void *addr)
-{
- *(int *)addr = f->bufsize;
- return (0);
-}
-
-static int
-ugen_get_iface_desc(struct usb2_fifo *f,
- struct usb2_interface_descriptor *idesc)
-{
- struct usb2_interface *iface;
-
- iface = usb2_get_iface(f->udev, f->iface_index);
- if (iface && iface->idesc) {
- *idesc = *(iface->idesc);
- } else {
- return (EIO);
- }
- return (0);
-}
-
-static int
-ugen_get_endpoint_desc(struct usb2_fifo *f,
- struct usb2_endpoint_descriptor *ed)
-{
- struct usb2_pipe *pipe;
-
- pipe = f->priv_sc0;
-
- if (pipe && pipe->edesc) {
- *ed = *pipe->edesc;
- } else {
- return (EINVAL);
- }
- return (0);
-}
-
-static int
-ugen_set_power_mode(struct usb2_fifo *f, int mode)
-{
- struct usb2_device *udev = f->udev;
- int err;
- uint8_t old_mode;
-
- if ((udev == NULL) ||
- (udev->parent_hub == NULL)) {
- return (EINVAL);
- }
- err = priv_check(curthread, PRIV_ROOT);
- if (err)
- return (err);
-
- /* get old power mode */
- old_mode = udev->power_mode;
-
- /* if no change, then just return */
- if (old_mode == mode)
- return (0);
-
- switch (mode) {
- case USB_POWER_MODE_OFF:
- /* get the device unconfigured */
- err = ugen_set_config(f, USB_UNCONFIG_INDEX);
- if (err) {
- DPRINTFN(0, "Could not unconfigure "
- "device (ignored)\n");
- }
-
- /* clear port enable */
- err = usb2_req_clear_port_feature(udev->parent_hub,
- NULL, udev->port_no, UHF_PORT_ENABLE);
- break;
-
- case USB_POWER_MODE_ON:
- case USB_POWER_MODE_SAVE:
- break;
-
- case USB_POWER_MODE_RESUME:
- err = usb2_req_clear_port_feature(udev->parent_hub,
- NULL, udev->port_no, UHF_PORT_SUSPEND);
- mode = USB_POWER_MODE_SAVE;
- break;
-
- case USB_POWER_MODE_SUSPEND:
- err = usb2_req_set_port_feature(udev->parent_hub,
- NULL, udev->port_no, UHF_PORT_SUSPEND);
- mode = USB_POWER_MODE_SAVE;
- break;
-
- default:
- return (EINVAL);
- }
-
- if (err)
- return (ENXIO); /* I/O failure */
-
- /* if we are powered off we need to re-enumerate first */
- if (old_mode == USB_POWER_MODE_OFF) {
- err = ugen_re_enumerate(f);
- if (err)
- return (err);
- }
-
- /* set new power mode */
- usb2_set_power_mode(udev, mode);
-
- return (0); /* success */
-}
-
-static int
-ugen_get_power_mode(struct usb2_fifo *f)
-{
- struct usb2_device *udev = f->udev;
-
- if ((udev == NULL) ||
- (udev->parent_hub == NULL)) {
- return (USB_POWER_MODE_ON);
- }
- return (udev->power_mode);
-}
-
-static int
-ugen_do_port_feature(struct usb2_fifo *f, uint8_t port_no,
- uint8_t set, uint16_t feature)
-{
- struct usb2_device *udev = f->udev;
- struct usb2_hub *hub;
- int err;
-
- err = priv_check(curthread, PRIV_ROOT);
- if (err) {
- return (err);
- }
- if (port_no == 0) {
- return (EINVAL);
- }
- if ((udev == NULL) ||
- (udev->hub == NULL)) {
- return (EINVAL);
- }
- hub = udev->hub;
-
- if (port_no > hub->nports) {
- return (EINVAL);
- }
- if (set)
- err = usb2_req_set_port_feature(udev,
- NULL, port_no, feature);
- else
- err = usb2_req_clear_port_feature(udev,
- NULL, port_no, feature);
-
- if (err)
- return (ENXIO); /* failure */
-
- return (0); /* success */
-}
-
-static int
-ugen_iface_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
-{
- struct usb2_fifo *f_rx;
- struct usb2_fifo *f_tx;
- int error = 0;
-
- f_rx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_RX];
- f_tx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_TX];
-
- switch (cmd) {
- case USB_SET_RX_SHORT_XFER:
- if (fflags & FREAD) {
- error = ugen_set_short_xfer(f_rx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_SET_TX_FORCE_SHORT:
- if (fflags & FWRITE) {
- error = ugen_set_short_xfer(f_tx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_SET_RX_TIMEOUT:
- if (fflags & FREAD) {
- error = ugen_set_timeout(f_rx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_SET_TX_TIMEOUT:
- if (fflags & FWRITE) {
- error = ugen_set_timeout(f_tx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_GET_RX_FRAME_SIZE:
- if (fflags & FREAD) {
- error = ugen_get_frame_size(f_rx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_GET_TX_FRAME_SIZE:
- if (fflags & FWRITE) {
- error = ugen_get_frame_size(f_tx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_SET_RX_BUFFER_SIZE:
- if (fflags & FREAD) {
- error = ugen_set_buffer_size(f_rx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_SET_TX_BUFFER_SIZE:
- if (fflags & FWRITE) {
- error = ugen_set_buffer_size(f_tx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_GET_RX_BUFFER_SIZE:
- if (fflags & FREAD) {
- error = ugen_get_buffer_size(f_rx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_GET_TX_BUFFER_SIZE:
- if (fflags & FWRITE) {
- error = ugen_get_buffer_size(f_tx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_GET_RX_INTERFACE_DESC:
- if (fflags & FREAD) {
- error = ugen_get_iface_desc(f_rx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_GET_TX_INTERFACE_DESC:
- if (fflags & FWRITE) {
- error = ugen_get_iface_desc(f_tx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_GET_RX_ENDPOINT_DESC:
- if (fflags & FREAD) {
- error = ugen_get_endpoint_desc(f_rx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_GET_TX_ENDPOINT_DESC:
- if (fflags & FWRITE) {
- error = ugen_get_endpoint_desc(f_tx, addr);
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_SET_RX_STALL_FLAG:
- if ((fflags & FREAD) && (*(int *)addr)) {
- f_rx->flag_stall = 1;
- }
- break;
-
- case USB_SET_TX_STALL_FLAG:
- if ((fflags & FWRITE) && (*(int *)addr)) {
- f_tx->flag_stall = 1;
- }
- break;
-
- default:
- error = ENOIOCTL;
- break;
- }
- return (error);
-}
-
-static int
-ugen_ioctl_post(struct usb2_fifo *f, u_long cmd, void *addr, int fflags,
- struct thread *td)
-{
- union {
- struct usb2_interface_descriptor *idesc;
- struct usb2_alt_interface *ai;
- struct usb2_device_descriptor *ddesc;
- struct usb2_config_descriptor *cdesc;
- struct usb2_device_stats *stat;
- struct usb2_fs_init *pinit;
- struct usb2_fs_uninit *puninit;
- uint32_t *ptime;
- void *addr;
- int *pint;
- } u;
- struct usb2_device_descriptor *dtemp;
- struct usb2_config_descriptor *ctemp;
- struct usb2_interface *iface;
- int error = 0;
- uint8_t n;
-
- u.addr = addr;
-
- DPRINTFN(6, "cmd=0x%08lx\n", cmd);
-
- switch (cmd) {
- case USB_DISCOVER:
- usb2_needs_explore_all();
- break;
-
- case USB_SETDEBUG:
- if (!(fflags & FWRITE)) {
- error = EPERM;
- break;
- }
- usb2_debug = *(int *)addr;
- break;
-
- case USB_GET_CONFIG:
- *(int *)addr = f->udev->curr_config_index;
- break;
-
- case USB_SET_CONFIG:
- if (!(fflags & FWRITE)) {
- error = EPERM;
- break;
- }
- error = ugen_set_config(f, *(int *)addr);
- break;
-
- case USB_GET_ALTINTERFACE:
- iface = usb2_get_iface(f->udev,
- u.ai->uai_interface_index);
- if (iface && iface->idesc) {
- u.ai->uai_alt_index = iface->alt_index;
- } else {
- error = EINVAL;
- }
- break;
-
- case USB_SET_ALTINTERFACE:
- if (!(fflags & FWRITE)) {
- error = EPERM;
- break;
- }
- error = ugen_set_interface(f,
- u.ai->uai_interface_index, u.ai->uai_alt_index);
- break;
-
- case USB_GET_DEVICE_DESC:
- dtemp = usb2_get_device_descriptor(f->udev);
- if (!dtemp) {
- error = EIO;
- break;
- }
- *u.ddesc = *dtemp;
- break;
-
- case USB_GET_CONFIG_DESC:
- ctemp = usb2_get_config_descriptor(f->udev);
- if (!ctemp) {
- error = EIO;
- break;
- }
- *u.cdesc = *ctemp;
- break;
-
- case USB_GET_FULL_DESC:
- error = ugen_get_cdesc(f, addr);
- break;
-
- case USB_GET_STRING_DESC:
- error = ugen_get_sdesc(f, addr);
- break;
-
- case USB_GET_IFACE_DRIVER:
- error = ugen_get_iface_driver(f, addr);
- break;
-
- case USB_REQUEST:
- case USB_DO_REQUEST:
- if (!(fflags & FWRITE)) {
- error = EPERM;
- break;
- }
- error = ugen_do_request(f, addr);
- break;
-
- case USB_DEVICEINFO:
- case USB_GET_DEVICEINFO:
- error = usb2_gen_fill_deviceinfo(f, addr);
- break;
-
- case USB_DEVICESTATS:
- for (n = 0; n != 4; n++) {
-
- u.stat->uds_requests_fail[n] =
- f->udev->bus->stats_err.uds_requests[n];
-
- u.stat->uds_requests_ok[n] =
- f->udev->bus->stats_ok.uds_requests[n];
- }
- break;
-
- case USB_DEVICEENUMERATE:
- error = ugen_re_enumerate(f);
- break;
-
- case USB_GET_PLUGTIME:
- *u.ptime = f->udev->plugtime;
- break;
-
- case USB_CLAIM_INTERFACE:
- case USB_RELEASE_INTERFACE:
- /* TODO */
- break;
-
- case USB_IFACE_DRIVER_ACTIVE:
- /* TODO */
- *u.pint = 0;
- break;
-
- case USB_IFACE_DRIVER_DETACH:
- /* TODO */
- error = priv_check(curthread, PRIV_DRIVER);
- if (error) {
- break;
- }
- error = EINVAL;
- break;
-
- case USB_SET_POWER_MODE:
- error = ugen_set_power_mode(f, *u.pint);
- break;
-
- case USB_GET_POWER_MODE:
- *u.pint = ugen_get_power_mode(f);
- break;
-
- case USB_SET_PORT_ENABLE:
- error = ugen_do_port_feature(f,
- *u.pint, 1, UHF_PORT_ENABLE);
- break;
-
- case USB_SET_PORT_DISABLE:
- error = ugen_do_port_feature(f,
- *u.pint, 0, UHF_PORT_ENABLE);
- break;
-
- case USB_FS_INIT:
- /* verify input parameters */
- if (u.pinit->pEndpoints == NULL) {
- error = EINVAL;
- break;
- }
- if (u.pinit->ep_index_max > 127) {
- error = EINVAL;
- break;
- }
- if (u.pinit->ep_index_max == 0) {
- error = EINVAL;
- break;
- }
- if (f->fs_xfer != NULL) {
- error = EBUSY;
- break;
- }
- if (f->dev_ep_index != 0) {
- error = EINVAL;
- break;
- }
- if (ugen_fifo_in_use(f, fflags)) {
- error = EBUSY;
- break;
- }
- error = usb2_fifo_alloc_buffer(f, 1, u.pinit->ep_index_max);
- if (error) {
- break;
- }
- f->fs_xfer = malloc(sizeof(f->fs_xfer[0]) *
- u.pinit->ep_index_max, M_USB, M_WAITOK | M_ZERO);
- if (f->fs_xfer == NULL) {
- usb2_fifo_free_buffer(f);
- error = ENOMEM;
- break;
- }
- f->fs_ep_max = u.pinit->ep_index_max;
- f->fs_ep_ptr = u.pinit->pEndpoints;
- break;
-
- case USB_FS_UNINIT:
- if (u.puninit->dummy != 0) {
- error = EINVAL;
- break;
- }
- error = ugen_fs_uninit(f);
- break;
-
- default:
- mtx_lock(f->priv_mtx);
- error = ugen_iface_ioctl(f, cmd, addr, fflags);
- mtx_unlock(f->priv_mtx);
- break;
- }
- DPRINTFN(6, "error=%d\n", error);
- return (error);
-}
-
-static void
-ugen_default_fs_callback(struct usb2_xfer *xfer)
-{
- ; /* workaround for a bug in "indent" */
-
- DPRINTF("st=%u alen=%u aframes=%u\n",
- USB_GET_STATE(xfer), xfer->actlen, xfer->aframes);
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- usb2_start_hardware(xfer);
- break;
- default:
- ugen_fs_set_complete(xfer->priv_sc, USB_P2U(xfer->priv_fifo));
- break;
- }
-}
diff --git a/sys/dev/usb2/core/usb2_generic.h b/sys/dev/usb2/core/usb2_generic.h
deleted file mode 100644
index 3a4e7c9..0000000
--- a/sys/dev/usb2/core/usb2_generic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_GENERIC_H_
-#define _USB2_GENERIC_H_
-
-extern struct usb2_fifo_methods usb2_ugen_methods;
-int ugen_do_request(struct usb2_fifo *f, struct usb2_ctl_request *ur);
-
-#endif /* _USB2_GENERIC_H_ */
diff --git a/sys/dev/usb2/core/usb2_handle_request.c b/sys/dev/usb2/core/usb2_handle_request.c
deleted file mode 100644
index 65f0f01..0000000
--- a/sys/dev/usb2/core/usb2_handle_request.c
+++ /dev/null
@@ -1,756 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-#include <dev/usb2/core/usb2_hub.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-
-/* enum */
-
-enum {
- ST_DATA,
- ST_POST_STATUS,
-};
-
-/* function prototypes */
-
-static uint8_t usb2_handle_get_stall(struct usb2_device *, uint8_t);
-static usb2_error_t usb2_handle_remote_wakeup(struct usb2_xfer *, uint8_t);
-static usb2_error_t usb2_handle_request(struct usb2_xfer *);
-static usb2_error_t usb2_handle_set_config(struct usb2_xfer *, uint8_t);
-static usb2_error_t usb2_handle_set_stall(struct usb2_xfer *, uint8_t,
- uint8_t);
-static usb2_error_t usb2_handle_iface_request(struct usb2_xfer *, void **,
- uint16_t *, struct usb2_device_request, uint16_t,
- uint8_t);
-
-/*------------------------------------------------------------------------*
- * usb2_handle_request_callback
- *
- * This function is the USB callback for generic USB Device control
- * transfers.
- *------------------------------------------------------------------------*/
-void
-usb2_handle_request_callback(struct usb2_xfer *xfer)
-{
- usb2_error_t err;
-
- /* check the current transfer state */
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-
- /* handle the request */
- err = usb2_handle_request(xfer);
-
- if (err) {
-
- if (err == USB_ERR_BAD_CONTEXT) {
- /* we need to re-setup the control transfer */
- usb2_needs_explore(xfer->xroot->bus, 0);
- break;
- }
- /*
- * If no control transfer is active,
- * receive the next SETUP message:
- */
- goto tr_restart;
- }
- usb2_start_hardware(xfer);
- break;
-
- default:
- if (xfer->error != USB_ERR_CANCELLED) {
- /* should not happen - try stalling */
- goto tr_restart;
- }
- break;
- }
- return;
-
-tr_restart:
- xfer->frlengths[0] = sizeof(struct usb2_device_request);
- xfer->nframes = 1;
- xfer->flags.manual_status = 1;
- xfer->flags.force_short_xfer = 0;
- xfer->flags.stall_pipe = 1; /* cancel previous transfer, if any */
- usb2_start_hardware(xfer);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_handle_set_config
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static usb2_error_t
-usb2_handle_set_config(struct usb2_xfer *xfer, uint8_t conf_no)
-{
- struct usb2_device *udev = xfer->xroot->udev;
- usb2_error_t err = 0;
-
- /*
- * We need to protect against other threads doing probe and
- * attach:
- */
- USB_XFER_UNLOCK(xfer);
- mtx_lock(&Giant); /* XXX */
- sx_xlock(udev->default_sx + 1);
-
- if (conf_no == USB_UNCONFIG_NO) {
- conf_no = USB_UNCONFIG_INDEX;
- } else {
- /*
- * The relationship between config number and config index
- * is very simple in our case:
- */
- conf_no--;
- }
-
- if (usb2_set_config_index(udev, conf_no)) {
- DPRINTF("set config %d failed\n", conf_no);
- err = USB_ERR_STALLED;
- goto done;
- }
- if (usb2_probe_and_attach(udev, USB_IFACE_INDEX_ANY)) {
- DPRINTF("probe and attach failed\n");
- err = USB_ERR_STALLED;
- goto done;
- }
-done:
- mtx_unlock(&Giant); /* XXX */
- sx_unlock(udev->default_sx + 1);
- USB_XFER_LOCK(xfer);
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_handle_iface_request
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static usb2_error_t
-usb2_handle_iface_request(struct usb2_xfer *xfer,
- void **ppdata, uint16_t *plen,
- struct usb2_device_request req, uint16_t off, uint8_t state)
-{
- struct usb2_interface *iface;
- struct usb2_interface *iface_parent; /* parent interface */
- struct usb2_device *udev = xfer->xroot->udev;
- int error;
- uint8_t iface_index;
-
- if ((req.bmRequestType & 0x1F) == UT_INTERFACE) {
- iface_index = req.wIndex[0]; /* unicast */
- } else {
- iface_index = 0; /* broadcast */
- }
-
- /*
- * We need to protect against other threads doing probe and
- * attach:
- */
- USB_XFER_UNLOCK(xfer);
- mtx_lock(&Giant); /* XXX */
- sx_xlock(udev->default_sx + 1);
-
- error = ENXIO;
-
-tr_repeat:
- iface = usb2_get_iface(udev, iface_index);
- if ((iface == NULL) ||
- (iface->idesc == NULL)) {
- /* end of interfaces non-existing interface */
- goto tr_stalled;
- }
- /* forward request to interface, if any */
-
- if ((error != 0) &&
- (error != ENOTTY) &&
- (iface->subdev != NULL) &&
- device_is_attached(iface->subdev)) {
-#if 0
- DEVMETHOD(usb2_handle_request, NULL); /* dummy */
-#endif
- error = USB2_HANDLE_REQUEST(iface->subdev,
- &req, ppdata, plen,
- off, (state == ST_POST_STATUS));
- }
- iface_parent = usb2_get_iface(udev, iface->parent_iface_index);
-
- if ((iface_parent == NULL) ||
- (iface_parent->idesc == NULL)) {
- /* non-existing interface */
- iface_parent = NULL;
- }
- /* forward request to parent interface, if any */
-
- if ((error != 0) &&
- (error != ENOTTY) &&
- (iface_parent != NULL) &&
- (iface_parent->subdev != NULL) &&
- ((req.bmRequestType & 0x1F) == UT_INTERFACE) &&
- (iface_parent->subdev != iface->subdev) &&
- device_is_attached(iface_parent->subdev)) {
- error = USB2_HANDLE_REQUEST(iface_parent->subdev,
- &req, ppdata, plen, off,
- (state == ST_POST_STATUS));
- }
- if (error == 0) {
- /* negativly adjust pointer and length */
- *ppdata = ((uint8_t *)(*ppdata)) - off;
- *plen += off;
- goto tr_valid;
- } else if (error == ENOTTY) {
- goto tr_stalled;
- }
- if ((req.bmRequestType & 0x1F) != UT_INTERFACE) {
- iface_index++; /* iterate */
- goto tr_repeat;
- }
- if (state == ST_POST_STATUS) {
- /* we are complete */
- goto tr_valid;
- }
- switch (req.bmRequestType) {
- case UT_WRITE_INTERFACE:
- switch (req.bRequest) {
- case UR_SET_INTERFACE:
- /*
- * Handle special case. If we have parent interface
- * we just reset the endpoints, because this is a
- * multi interface device and re-attaching only a
- * part of the device is not possible. Also if the
- * alternate setting is the same like before we just
- * reset the interface endoints.
- */
- if ((iface_parent != NULL) ||
- (iface->alt_index == req.wValue[0])) {
- error = usb2_reset_iface_endpoints(udev,
- iface_index);
- if (error) {
- DPRINTF("alt setting failed %s\n",
- usb2_errstr(error));
- goto tr_stalled;
- }
- break;
- }
- error = usb2_set_alt_interface_index(udev,
- iface_index, req.wValue[0]);
- if (error) {
- DPRINTF("alt setting failed %s\n",
- usb2_errstr(error));
- goto tr_stalled;
- }
- error = usb2_probe_and_attach(udev,
- iface_index);
- if (error) {
- DPRINTF("alt setting probe failed\n");
- goto tr_stalled;
- }
- break;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_INTERFACE:
- switch (req.bRequest) {
- case UR_GET_INTERFACE:
- *ppdata = &iface->alt_index;
- *plen = 1;
- break;
-
- default:
- goto tr_stalled;
- }
- break;
- default:
- goto tr_stalled;
- }
-tr_valid:
- mtx_unlock(&Giant);
- sx_unlock(udev->default_sx + 1);
- USB_XFER_LOCK(xfer);
- return (0);
-
-tr_stalled:
- mtx_unlock(&Giant);
- sx_unlock(udev->default_sx + 1);
- USB_XFER_LOCK(xfer);
- return (USB_ERR_STALLED);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_handle_stall
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static usb2_error_t
-usb2_handle_set_stall(struct usb2_xfer *xfer, uint8_t ep, uint8_t do_stall)
-{
- struct usb2_device *udev = xfer->xroot->udev;
- usb2_error_t err;
-
- USB_XFER_UNLOCK(xfer);
- err = usb2_set_endpoint_stall(udev,
- usb2_get_pipe_by_addr(udev, ep), do_stall);
- USB_XFER_LOCK(xfer);
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_handle_get_stall
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-usb2_handle_get_stall(struct usb2_device *udev, uint8_t ea_val)
-{
- struct usb2_pipe *pipe;
- uint8_t halted;
-
- pipe = usb2_get_pipe_by_addr(udev, ea_val);
- if (pipe == NULL) {
- /* nothing to do */
- return (0);
- }
- USB_BUS_LOCK(udev->bus);
- halted = pipe->is_stalled;
- USB_BUS_UNLOCK(udev->bus);
-
- return (halted);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_handle_remote_wakeup
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static usb2_error_t
-usb2_handle_remote_wakeup(struct usb2_xfer *xfer, uint8_t is_on)
-{
- struct usb2_device *udev;
- struct usb2_bus *bus;
-
- udev = xfer->xroot->udev;
- bus = udev->bus;
-
- USB_BUS_LOCK(bus);
-
- if (is_on) {
- udev->flags.remote_wakeup = 1;
- } else {
- udev->flags.remote_wakeup = 0;
- }
-
- USB_BUS_UNLOCK(bus);
-
- /* In case we are out of sync, update the power state. */
-
- usb2_bus_power_update(udev->bus);
-
- return (0); /* success */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_handle_request
- *
- * Internal state sequence:
- *
- * ST_DATA -> ST_POST_STATUS
- *
- * Returns:
- * 0: Ready to start hardware
- * Else: Stall current transfer, if any
- *------------------------------------------------------------------------*/
-static usb2_error_t
-usb2_handle_request(struct usb2_xfer *xfer)
-{
- struct usb2_device_request req;
- struct usb2_device *udev;
- const void *src_zcopy; /* zero-copy source pointer */
- const void *src_mcopy; /* non zero-copy source pointer */
- uint16_t off; /* data offset */
- uint16_t rem; /* data remainder */
- uint16_t max_len; /* max fragment length */
- uint16_t wValue;
- uint16_t wIndex;
- uint8_t state;
- usb2_error_t err;
- union {
- uWord wStatus;
- uint8_t buf[2];
- } temp;
-
- /*
- * Filter the USB transfer state into
- * something which we understand:
- */
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- state = ST_DATA;
-
- if (!xfer->flags_int.control_act) {
- /* nothing to do */
- goto tr_stalled;
- }
- break;
-
- default: /* USB_ST_TRANSFERRED */
- if (!xfer->flags_int.control_act) {
- state = ST_POST_STATUS;
- } else {
- state = ST_DATA;
- }
- break;
- }
-
- /* reset frame stuff */
-
- xfer->frlengths[0] = 0;
-
- usb2_set_frame_offset(xfer, 0, 0);
- usb2_set_frame_offset(xfer, sizeof(req), 1);
-
- /* get the current request, if any */
-
- usb2_copy_out(xfer->frbuffers, 0, &req, sizeof(req));
-
- if (xfer->flags_int.control_rem == 0xFFFF) {
- /* first time - not initialised */
- rem = UGETW(req.wLength);
- off = 0;
- } else {
- /* not first time - initialised */
- rem = xfer->flags_int.control_rem;
- off = UGETW(req.wLength) - rem;
- }
-
- /* set some defaults */
-
- max_len = 0;
- src_zcopy = NULL;
- src_mcopy = NULL;
- udev = xfer->xroot->udev;
-
- /* get some request fields decoded */
-
- wValue = UGETW(req.wValue);
- wIndex = UGETW(req.wIndex);
-
- DPRINTF("req 0x%02x 0x%02x 0x%04x 0x%04x "
- "off=0x%x rem=0x%x, state=%d\n", req.bmRequestType,
- req.bRequest, wValue, wIndex, off, rem, state);
-
- /* demultiplex the control request */
-
- switch (req.bmRequestType) {
- case UT_READ_DEVICE:
- if (state != ST_DATA) {
- break;
- }
- switch (req.bRequest) {
- case UR_GET_DESCRIPTOR:
- goto tr_handle_get_descriptor;
- case UR_GET_CONFIG:
- goto tr_handle_get_config;
- case UR_GET_STATUS:
- goto tr_handle_get_status;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_DEVICE:
- switch (req.bRequest) {
- case UR_SET_ADDRESS:
- goto tr_handle_set_address;
- case UR_SET_CONFIG:
- goto tr_handle_set_config;
- case UR_CLEAR_FEATURE:
- switch (wValue) {
- case UF_DEVICE_REMOTE_WAKEUP:
- goto tr_handle_clear_wakeup;
- default:
- goto tr_stalled;
- }
- break;
- case UR_SET_FEATURE:
- switch (wValue) {
- case UF_DEVICE_REMOTE_WAKEUP:
- goto tr_handle_set_wakeup;
- default:
- goto tr_stalled;
- }
- break;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_WRITE_ENDPOINT:
- switch (req.bRequest) {
- case UR_CLEAR_FEATURE:
- switch (wValue) {
- case UF_ENDPOINT_HALT:
- goto tr_handle_clear_halt;
- default:
- goto tr_stalled;
- }
- break;
- case UR_SET_FEATURE:
- switch (wValue) {
- case UF_ENDPOINT_HALT:
- goto tr_handle_set_halt;
- default:
- goto tr_stalled;
- }
- break;
- default:
- goto tr_stalled;
- }
- break;
-
- case UT_READ_ENDPOINT:
- switch (req.bRequest) {
- case UR_GET_STATUS:
- goto tr_handle_get_ep_status;
- default:
- goto tr_stalled;
- }
- break;
- default:
- /* we use "USB_ADD_BYTES" to de-const the src_zcopy */
- err = usb2_handle_iface_request(xfer,
- USB_ADD_BYTES(&src_zcopy, 0),
- &max_len, req, off, state);
- if (err == 0) {
- goto tr_valid;
- }
- /*
- * Reset zero-copy pointer and max length
- * variable in case they were unintentionally
- * set:
- */
- src_zcopy = NULL;
- max_len = 0;
-
- /*
- * Check if we have a vendor specific
- * descriptor:
- */
- goto tr_handle_get_descriptor;
- }
- goto tr_valid;
-
-tr_handle_get_descriptor:
- (usb2_temp_get_desc_p) (udev, &req, &src_zcopy, &max_len);
- if (src_zcopy == NULL) {
- goto tr_stalled;
- }
- goto tr_valid;
-
-tr_handle_get_config:
- temp.buf[0] = udev->curr_config_no;
- src_mcopy = temp.buf;
- max_len = 1;
- goto tr_valid;
-
-tr_handle_get_status:
-
- wValue = 0;
-
- USB_BUS_LOCK(udev->bus);
- if (udev->flags.remote_wakeup) {
- wValue |= UDS_REMOTE_WAKEUP;
- }
- if (udev->flags.self_powered) {
- wValue |= UDS_SELF_POWERED;
- }
- USB_BUS_UNLOCK(udev->bus);
-
- USETW(temp.wStatus, wValue);
- src_mcopy = temp.wStatus;
- max_len = sizeof(temp.wStatus);
- goto tr_valid;
-
-tr_handle_set_address:
- if (state == ST_DATA) {
- if (wValue >= 0x80) {
- /* invalid value */
- goto tr_stalled;
- } else if (udev->curr_config_no != 0) {
- /* we are configured ! */
- goto tr_stalled;
- }
- } else if (state == ST_POST_STATUS) {
- udev->address = (wValue & 0x7F);
- goto tr_bad_context;
- }
- goto tr_valid;
-
-tr_handle_set_config:
- if (state == ST_DATA) {
- if (usb2_handle_set_config(xfer, req.wValue[0])) {
- goto tr_stalled;
- }
- }
- goto tr_valid;
-
-tr_handle_clear_halt:
- if (state == ST_DATA) {
- if (usb2_handle_set_stall(xfer, req.wIndex[0], 0)) {
- goto tr_stalled;
- }
- }
- goto tr_valid;
-
-tr_handle_clear_wakeup:
- if (state == ST_DATA) {
- if (usb2_handle_remote_wakeup(xfer, 0)) {
- goto tr_stalled;
- }
- }
- goto tr_valid;
-
-tr_handle_set_halt:
- if (state == ST_DATA) {
- if (usb2_handle_set_stall(xfer, req.wIndex[0], 1)) {
- goto tr_stalled;
- }
- }
- goto tr_valid;
-
-tr_handle_set_wakeup:
- if (state == ST_DATA) {
- if (usb2_handle_remote_wakeup(xfer, 1)) {
- goto tr_stalled;
- }
- }
- goto tr_valid;
-
-tr_handle_get_ep_status:
- if (state == ST_DATA) {
- temp.wStatus[0] =
- usb2_handle_get_stall(udev, req.wIndex[0]);
- temp.wStatus[1] = 0;
- src_mcopy = temp.wStatus;
- max_len = sizeof(temp.wStatus);
- }
- goto tr_valid;
-
-tr_valid:
- if (state == ST_POST_STATUS) {
- goto tr_stalled;
- }
- /* subtract offset from length */
-
- max_len -= off;
-
- /* Compute the real maximum data length */
-
- if (max_len > xfer->max_data_length) {
- max_len = xfer->max_data_length;
- }
- if (max_len > rem) {
- max_len = rem;
- }
- /*
- * If the remainder is greater than the maximum data length,
- * we need to truncate the value for the sake of the
- * comparison below:
- */
- if (rem > xfer->max_data_length) {
- rem = xfer->max_data_length;
- }
- if (rem != max_len) {
- /*
- * If we don't transfer the data we can transfer, then
- * the transfer is short !
- */
- xfer->flags.force_short_xfer = 1;
- xfer->nframes = 2;
- } else {
- /*
- * Default case
- */
- xfer->flags.force_short_xfer = 0;
- xfer->nframes = max_len ? 2 : 1;
- }
- if (max_len > 0) {
- if (src_mcopy) {
- src_mcopy = USB_ADD_BYTES(src_mcopy, off);
- usb2_copy_in(xfer->frbuffers + 1, 0,
- src_mcopy, max_len);
- } else {
- usb2_set_frame_data(xfer,
- USB_ADD_BYTES(src_zcopy, off), 1);
- }
- xfer->frlengths[1] = max_len;
- } else {
- /* the end is reached, send status */
- xfer->flags.manual_status = 0;
- xfer->frlengths[1] = 0;
- }
- DPRINTF("success\n");
- return (0); /* success */
-
-tr_stalled:
- DPRINTF("%s\n", (state == ST_POST_STATUS) ?
- "complete" : "stalled");
- return (USB_ERR_STALLED);
-
-tr_bad_context:
- DPRINTF("bad context\n");
- return (USB_ERR_BAD_CONTEXT);
-}
diff --git a/sys/dev/usb2/core/usb2_handle_request.h b/sys/dev/usb2/core/usb2_handle_request.h
deleted file mode 100644
index 6cc0503..0000000
--- a/sys/dev/usb2/core/usb2_handle_request.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_HANDLE_REQUEST_H_
-#define _USB2_HANDLE_REQUEST_H_
-
-#endif /* _USB2_HANDLE_REQUEST_H_ */
diff --git a/sys/dev/usb2/core/usb2_hid.c b/sys/dev/usb2/core/usb2_hid.c
deleted file mode 100644
index 04d7d4d..0000000
--- a/sys/dev/usb2/core/usb2_hid.c
+++ /dev/null
@@ -1,582 +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 <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_hid.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_parse.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_hid.h>
-
-static void hid_clear_local(struct hid_item *);
-
-#define MAXUSAGE 100
-struct hid_data {
- const uint8_t *start;
- const uint8_t *end;
- const uint8_t *p;
- struct hid_item cur;
- int32_t usages[MAXUSAGE];
- int nu;
- int minset;
- int multi;
- int multimax;
- int kindset;
-};
-
-/*------------------------------------------------------------------------*
- * hid_clear_local
- *------------------------------------------------------------------------*/
-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;
-}
-
-/*------------------------------------------------------------------------*
- * hid_start_parse
- *------------------------------------------------------------------------*/
-struct hid_data *
-hid_start_parse(const 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 = ((const uint8_t *)d) + len;
- s->kindset = kindset;
- return (s);
-}
-
-/*------------------------------------------------------------------------*
- * hid_end_parse
- *------------------------------------------------------------------------*/
-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);
-}
-
-/*------------------------------------------------------------------------*
- * hid_get_item
- *------------------------------------------------------------------------*/
-int
-hid_get_item(struct hid_data *s, struct hid_item *h)
-{
- struct hid_item *c = &s->cur;
- unsigned int bTag, bType, bSize;
- uint32_t oldpos;
- const uint8_t *data;
- int32_t dval;
- const uint8_t *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;
- }
- }
-}
-
-/*------------------------------------------------------------------------*
- * hid_report_size
- *------------------------------------------------------------------------*/
-int
-hid_report_size(const void *buf, int len, enum hid_kind k, uint8_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);
-}
-
-/*------------------------------------------------------------------------*
- * hid_locate
- *------------------------------------------------------------------------*/
-int
-hid_locate(const void *desc, int size, uint32_t u, enum hid_kind k,
- struct hid_location *loc, uint32_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);
-}
-
-/*------------------------------------------------------------------------*
- * hid_get_data
- *------------------------------------------------------------------------*/
-uint32_t
-hid_get_data(const uint8_t *buf, uint32_t len, struct hid_location *loc)
-{
- uint32_t hpos = loc->pos;
- uint32_t hsize = loc->size;
- uint32_t data;
- int i, s, t;
-
- DPRINTFN(11, "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) {
- t = (i / 8);
- if (t < len) {
- data |= buf[t] << ((t - s) * 8);
- }
- }
- data >>= hpos % 8;
- data &= (1 << hsize) - 1;
- hsize = 32 - hsize;
- /* Sign extend */
- data = ((int32_t)data << hsize) >> hsize;
- DPRINTFN(11, "hid_get_data: loc %d/%d = %lu\n",
- loc->pos, loc->size, (long)data);
- return (data);
-}
-
-/*------------------------------------------------------------------------*
- * hid_is_collection
- *------------------------------------------------------------------------*/
-int
-hid_is_collection(const void *desc, int size, uint32_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);
-}
-
-/*------------------------------------------------------------------------*
- * hid_get_descriptor_from_usb
- *
- * This function will search for a HID descriptor between two USB
- * interface descriptors.
- *
- * Return values:
- * NULL: No more HID descriptors.
- * Else: Pointer to HID descriptor.
- *------------------------------------------------------------------------*/
-struct usb2_hid_descriptor *
-hid_get_descriptor_from_usb(struct usb2_config_descriptor *cd,
- struct usb2_interface_descriptor *id)
-{
- struct usb2_descriptor *desc = (void *)id;
-
- if (desc == NULL) {
- return (NULL);
- }
- while ((desc = usb2_desc_foreach(cd, desc))) {
- if ((desc->bDescriptorType == UDESC_HID) &&
- (desc->bLength >= USB_HID_DESCRIPTOR_SIZE(0))) {
- return (void *)desc;
- }
- if (desc->bDescriptorType == UDESC_INTERFACE) {
- break;
- }
- }
- return (NULL);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_hid_desc
- *
- * This function will read out an USB report descriptor from the USB
- * device.
- *
- * Return values:
- * NULL: Failure.
- * Else: Success. The pointer should eventually be passed to free().
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_hid_desc(struct usb2_device *udev, struct mtx *mtx,
- void **descp, uint16_t *sizep,
- usb2_malloc_type mem, uint8_t iface_index)
-{
- struct usb2_interface *iface = usb2_get_iface(udev, iface_index);
- struct usb2_hid_descriptor *hid;
- usb2_error_t err;
-
- if ((iface == NULL) || (iface->idesc == NULL)) {
- return (USB_ERR_INVAL);
- }
- hid = hid_get_descriptor_from_usb
- (usb2_get_config_descriptor(udev), iface->idesc);
-
- if (hid == NULL) {
- return (USB_ERR_IOERROR);
- }
- *sizep = UGETW(hid->descrs[0].wDescriptorLength);
- if (*sizep == 0) {
- return (USB_ERR_IOERROR);
- }
- if (mtx)
- mtx_unlock(mtx);
-
- *descp = malloc(*sizep, mem, M_ZERO | M_WAITOK);
-
- if (mtx)
- mtx_lock(mtx);
-
- if (*descp == NULL) {
- return (USB_ERR_NOMEM);
- }
- err = usb2_req_get_report_descriptor
- (udev, mtx, *descp, *sizep, iface_index);
-
- if (err) {
- free(*descp, mem);
- *descp = NULL;
- return (err);
- }
- return (USB_ERR_NORMAL_COMPLETION);
-}
diff --git a/sys/dev/usb2/core/usb2_hid.h b/sys/dev/usb2/core/usb2_hid.h
deleted file mode 100644
index 3fb7368..0000000
--- a/sys/dev/usb2/core/usb2_hid.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
- * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
- * Copyright (c) 1998 Lennart Augustsson. 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.
- */
-
-#ifndef _USB2_CORE_HID_H_
-#define _USB2_CORE_HID_H_
-
-struct usb2_hid_descriptor;
-struct usb2_config_descriptor;
-
-enum hid_kind {
- hid_input, hid_output, hid_feature, hid_collection, hid_endcollection
-};
-
-struct hid_location {
- uint32_t size;
- uint32_t count;
- uint32_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;
- uint32_t flags;
- /* Location */
- struct hid_location loc;
- /* */
- struct hid_item *next;
-};
-
-/* prototypes from "usb2_hid.c" */
-
-struct hid_data *hid_start_parse(const 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(const void *buf, int len, enum hid_kind k, uint8_t *id);
-int hid_locate(const void *desc, int size, uint32_t usage,
- enum hid_kind kind, struct hid_location *loc, uint32_t *flags);
-uint32_t hid_get_data(const uint8_t *buf, uint32_t len,
- struct hid_location *loc);
-int hid_is_collection(const void *desc, int size, uint32_t usage);
-struct usb2_hid_descriptor *hid_get_descriptor_from_usb(
- struct usb2_config_descriptor *cd,
- struct usb2_interface_descriptor *id);
-usb2_error_t usb2_req_get_hid_desc(struct usb2_device *udev, struct mtx *mtx,
- void **descp, uint16_t *sizep, usb2_malloc_type mem,
- uint8_t iface_index);
-
-#endif /* _USB2_CORE_HID_H_ */
diff --git a/sys/dev/usb2/core/usb2_hub.c b/sys/dev/usb2/core/usb2_hub.c
deleted file mode 100644
index 8c2d639..0000000
--- a/sys/dev/usb2/core/usb2_hub.c
+++ /dev/null
@@ -1,1842 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
- * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-/*
- * USB spec: http://www.usb.org/developers/docs/usbspec.zip
- */
-
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-
-#define USB_DEBUG_VAR uhub_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_hub.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-
-#define UHUB_INTR_INTERVAL 250 /* ms */
-#define UHUB_N_TRANSFER 1
-
-#if USB_DEBUG
-static int uhub_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB HUB");
-SYSCTL_INT(_hw_usb2_uhub, OID_AUTO, debug, CTLFLAG_RW, &uhub_debug, 0,
- "Debug level");
-#endif
-
-static int usb2_power_timeout = 30; /* seconds */
-
-SYSCTL_INT(_hw_usb2, OID_AUTO, power_timeout, CTLFLAG_RW,
- &usb2_power_timeout, 0, "USB power timeout");
-
-struct uhub_current_state {
- uint16_t port_change;
- uint16_t port_status;
-};
-
-struct uhub_softc {
- struct uhub_current_state sc_st;/* current state */
- device_t sc_dev; /* base device */
- struct usb2_device *sc_udev; /* USB device */
- struct usb2_xfer *sc_xfer[UHUB_N_TRANSFER]; /* interrupt xfer */
- uint8_t sc_flags;
-#define UHUB_FLAG_DID_EXPLORE 0x01
- char sc_name[32];
-};
-
-#define UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol)
-#define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
-#define UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
-
-/* prototypes for type checking: */
-
-static device_probe_t uhub_probe;
-static device_attach_t uhub_attach;
-static device_detach_t uhub_detach;
-static device_suspend_t uhub_suspend;
-static device_resume_t uhub_resume;
-
-static bus_driver_added_t uhub_driver_added;
-static bus_child_location_str_t uhub_child_location_string;
-static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string;
-
-static usb2_callback_t uhub_intr_callback;
-
-static void usb2_dev_resume_peer(struct usb2_device *udev);
-static void usb2_dev_suspend_peer(struct usb2_device *udev);
-
-static const struct usb2_config uhub_config[UHUB_N_TRANSFER] = {
-
- [0] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_ANY,
- .mh.timeout = 0,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = &uhub_intr_callback,
- .mh.interval = UHUB_INTR_INTERVAL,
- },
-};
-
-/*
- * driver instance for "hub" connected to "usb"
- * and "hub" connected to "hub"
- */
-static devclass_t uhub_devclass;
-
-static driver_t uhub_driver =
-{
- .name = "ushub",
- .methods = (device_method_t[]){
- DEVMETHOD(device_probe, uhub_probe),
- DEVMETHOD(device_attach, uhub_attach),
- DEVMETHOD(device_detach, uhub_detach),
-
- DEVMETHOD(device_suspend, uhub_suspend),
- DEVMETHOD(device_resume, uhub_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- DEVMETHOD(bus_child_location_str, uhub_child_location_string),
- DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string),
- DEVMETHOD(bus_driver_added, uhub_driver_added),
- {0, 0}
- },
- .size = sizeof(struct uhub_softc)
-};
-
-DRIVER_MODULE(ushub, usbus, uhub_driver, uhub_devclass, 0, 0);
-DRIVER_MODULE(ushub, ushub, uhub_driver, uhub_devclass, NULL, 0);
-
-static void
-uhub_intr_callback(struct usb2_xfer *xfer)
-{
- struct uhub_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(2, "\n");
- /*
- * This is an indication that some port
- * has changed status. Notify the bus
- * event handler thread that we need
- * to be explored again:
- */
- usb2_needs_explore(sc->sc_udev->bus, 0);
-
- case USB_ST_SETUP:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /*
- * Do a clear-stall. The "stall_pipe" flag
- * will get cleared before next callback by
- * the USB stack.
- */
- xfer->flags.stall_pipe = 1;
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- }
- break;
- }
-}
-
-/*------------------------------------------------------------------------*
- * uhub_explore_sub - subroutine
- *
- * Return values:
- * 0: Success
- * Else: A control transaction failed
- *------------------------------------------------------------------------*/
-static usb2_error_t
-uhub_explore_sub(struct uhub_softc *sc, struct usb2_port *up)
-{
- struct usb2_bus *bus;
- struct usb2_device *child;
- uint8_t refcount;
- usb2_error_t err;
-
- bus = sc->sc_udev->bus;
- err = 0;
-
- /* get driver added refcount from USB bus */
- refcount = bus->driver_added_refcount;
-
- /* get device assosiated with the given port */
- child = usb2_bus_port_get_device(bus, up);
- if (child == NULL) {
- /* nothing to do */
- goto done;
- }
- /* check if probe and attach should be done */
-
- if (child->driver_added_refcount != refcount) {
- child->driver_added_refcount = refcount;
- err = usb2_probe_and_attach(child,
- USB_IFACE_INDEX_ANY);
- if (err) {
- goto done;
- }
- }
- /* start control transfer, if device mode */
-
- if (child->flags.usb2_mode == USB_MODE_DEVICE) {
- usb2_default_transfer_setup(child);
- }
- /* if a HUB becomes present, do a recursive HUB explore */
-
- if (child->hub) {
- err = (child->hub->explore) (child);
- }
-done:
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * uhub_read_port_status - factored out code
- *------------------------------------------------------------------------*/
-static usb2_error_t
-uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
-{
- struct usb2_port_status ps;
- usb2_error_t err;
-
- err = usb2_req_get_port_status(
- sc->sc_udev, &Giant, &ps, portno);
-
- /* update status regardless of error */
-
- sc->sc_st.port_status = UGETW(ps.wPortStatus);
- sc->sc_st.port_change = UGETW(ps.wPortChange);
-
- /* debugging print */
-
- DPRINTFN(4, "port %d, wPortStatus=0x%04x, "
- "wPortChange=0x%04x, err=%s\n",
- portno, sc->sc_st.port_status,
- sc->sc_st.port_change, usb2_errstr(err));
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * uhub_reattach_port
- *
- * Returns:
- * 0: Success
- * Else: A control transaction failed
- *------------------------------------------------------------------------*/
-static usb2_error_t
-uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
-{
- struct usb2_device *child;
- struct usb2_device *udev;
- usb2_error_t err;
- uint8_t timeout;
- uint8_t speed;
- uint8_t usb2_mode;
-
- DPRINTF("reattaching port %d\n", portno);
-
- err = 0;
- timeout = 0;
- udev = sc->sc_udev;
- child = usb2_bus_port_get_device(udev->bus,
- udev->hub->ports + portno - 1);
-
-repeat:
-
- /* first clear the port connection change bit */
-
- err = usb2_req_clear_port_feature(udev, &Giant,
- portno, UHF_C_PORT_CONNECTION);
-
- if (err) {
- goto error;
- }
- /* detach any existing devices */
-
- if (child) {
- usb2_detach_device(child, USB_IFACE_INDEX_ANY, 1);
- usb2_free_device(child);
- child = NULL;
- }
- /* get fresh status */
-
- err = uhub_read_port_status(sc, portno);
- if (err) {
- goto error;
- }
- /* check if nothing is connected to the port */
-
- if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS)) {
- goto error;
- }
- /* check if there is no power on the port and print a warning */
-
- if (!(sc->sc_st.port_status & UPS_PORT_POWER)) {
- DPRINTF("WARNING: strange, connected port %d "
- "has no power\n", portno);
- }
- /* check if the device is in Host Mode */
-
- if (!(sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)) {
-
- DPRINTF("Port %d is in Host Mode\n", portno);
-
- if (sc->sc_st.port_status & UPS_SUSPEND) {
- DPRINTF("Port %d was still "
- "suspended, clearing.\n", portno);
- err = usb2_req_clear_port_feature(sc->sc_udev,
- &Giant, portno, UHF_PORT_SUSPEND);
- }
- /* USB Host Mode */
-
- /* wait for maximum device power up time */
-
- usb2_pause_mtx(&Giant,
- USB_MS_TO_TICKS(USB_PORT_POWERUP_DELAY));
-
- /* reset port, which implies enabling it */
-
- err = usb2_req_reset_port(udev, &Giant, portno);
-
- if (err) {
- DPRINTFN(0, "port %d reset "
- "failed, error=%s\n",
- portno, usb2_errstr(err));
- goto error;
- }
- /* get port status again, it might have changed during reset */
-
- err = uhub_read_port_status(sc, portno);
- if (err) {
- goto error;
- }
- /* check if something changed during port reset */
-
- if ((sc->sc_st.port_change & UPS_C_CONNECT_STATUS) ||
- (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS))) {
- if (timeout) {
- DPRINTFN(0, "giving up port reset "
- "- device vanished!\n");
- goto error;
- }
- timeout = 1;
- goto repeat;
- }
- } else {
- DPRINTF("Port %d is in Device Mode\n", portno);
- }
-
- /*
- * Figure out the device speed
- */
- switch (udev->speed) {
- case USB_SPEED_HIGH:
- if (sc->sc_st.port_status & UPS_HIGH_SPEED)
- speed = USB_SPEED_HIGH;
- else if (sc->sc_st.port_status & UPS_LOW_SPEED)
- speed = USB_SPEED_LOW;
- else
- speed = USB_SPEED_FULL;
- break;
- case USB_SPEED_FULL:
- if (sc->sc_st.port_status & UPS_LOW_SPEED)
- speed = USB_SPEED_LOW;
- else
- speed = USB_SPEED_FULL;
- break;
- case USB_SPEED_LOW:
- speed = USB_SPEED_LOW;
- break;
- default:
- /* same speed like parent */
- speed = udev->speed;
- break;
- }
- /*
- * Figure out the device mode
- *
- * NOTE: This part is currently FreeBSD specific.
- */
- if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)
- usb2_mode = USB_MODE_DEVICE;
- else
- usb2_mode = USB_MODE_HOST;
-
- /* need to create a new child */
-
- child = usb2_alloc_device(sc->sc_dev, udev->bus, udev,
- udev->depth + 1, portno - 1, portno, speed, usb2_mode);
- if (child == NULL) {
- DPRINTFN(0, "could not allocate new device!\n");
- goto error;
- }
- return (0); /* success */
-
-error:
- if (child) {
- usb2_detach_device(child, USB_IFACE_INDEX_ANY, 1);
- usb2_free_device(child);
- child = NULL;
- }
- if (err == 0) {
- if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
- err = usb2_req_clear_port_feature(
- sc->sc_udev, &Giant,
- portno, UHF_PORT_ENABLE);
- }
- }
- if (err) {
- DPRINTFN(0, "device problem (%s), "
- "disabling port %d\n", usb2_errstr(err), portno);
- }
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * uhub_suspend_resume_port
- *
- * Returns:
- * 0: Success
- * Else: A control transaction failed
- *------------------------------------------------------------------------*/
-static usb2_error_t
-uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno)
-{
- struct usb2_device *child;
- struct usb2_device *udev;
- uint8_t is_suspend;
- usb2_error_t err;
-
- DPRINTF("port %d\n", portno);
-
- udev = sc->sc_udev;
- child = usb2_bus_port_get_device(udev->bus,
- udev->hub->ports + portno - 1);
-
- /* first clear the port suspend change bit */
-
- err = usb2_req_clear_port_feature(udev, &Giant,
- portno, UHF_C_PORT_SUSPEND);
- if (err) {
- DPRINTF("clearing suspend failed.\n");
- goto done;
- }
- /* get fresh status */
-
- err = uhub_read_port_status(sc, portno);
- if (err) {
- DPRINTF("reading port status failed.\n");
- goto done;
- }
- /* get current state */
-
- if (sc->sc_st.port_status & UPS_SUSPEND) {
- is_suspend = 1;
- } else {
- is_suspend = 0;
- }
-
- DPRINTF("suspended=%u\n", is_suspend);
-
- /* do the suspend or resume */
-
- if (child) {
- /*
- * This code handle two cases: 1) Host Mode - we can only
- * receive resume here 2) Device Mode - we can receive
- * suspend and resume here
- */
- if (is_suspend == 0)
- usb2_dev_resume_peer(child);
- else if (child->flags.usb2_mode == USB_MODE_DEVICE)
- usb2_dev_suspend_peer(child);
- }
-done:
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * uhub_explore
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static usb2_error_t
-uhub_explore(struct usb2_device *udev)
-{
- struct usb2_hub *hub;
- struct uhub_softc *sc;
- struct usb2_port *up;
- usb2_error_t err;
- uint8_t portno;
- uint8_t x;
-
- hub = udev->hub;
- sc = hub->hubsoftc;
-
- DPRINTFN(11, "udev=%p addr=%d\n", udev, udev->address);
-
- /* ignore hubs that are too deep */
- if (udev->depth > USB_HUB_MAX_DEPTH) {
- return (USB_ERR_TOO_DEEP);
- }
- if (udev->pwr_save.suspended) {
- /* need to wait until the child signals resume */
- DPRINTF("Device is suspended!\n");
- return (0);
- }
- for (x = 0; x != hub->nports; x++) {
- up = hub->ports + x;
- portno = x + 1;
-
- err = uhub_read_port_status(sc, portno);
- if (err) {
- /* most likely the HUB is gone */
- break;
- }
- if (sc->sc_st.port_change & UPS_C_OVERCURRENT_INDICATOR) {
- DPRINTF("Overcurrent on port %u.\n", portno);
- err = usb2_req_clear_port_feature(
- udev, &Giant, portno, UHF_C_PORT_OVER_CURRENT);
- if (err) {
- /* most likely the HUB is gone */
- break;
- }
- }
- if (!(sc->sc_flags & UHUB_FLAG_DID_EXPLORE)) {
- /*
- * Fake a connect status change so that the
- * status gets checked initially!
- */
- sc->sc_st.port_change |=
- UPS_C_CONNECT_STATUS;
- }
- if (sc->sc_st.port_change & UPS_C_PORT_ENABLED) {
- err = usb2_req_clear_port_feature(
- udev, &Giant, portno, UHF_C_PORT_ENABLE);
- if (err) {
- /* most likely the HUB is gone */
- break;
- }
- if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) {
- /*
- * Ignore the port error if the device
- * has vanished !
- */
- } else if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
- DPRINTFN(0, "illegal enable change, "
- "port %d\n", portno);
- } else {
-
- if (up->restartcnt == USB_RESTART_MAX) {
- /* XXX could try another speed ? */
- DPRINTFN(0, "port error, giving up "
- "port %d\n", portno);
- } else {
- sc->sc_st.port_change |=
- UPS_C_CONNECT_STATUS;
- up->restartcnt++;
- }
- }
- }
- if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) {
- err = uhub_reattach_port(sc, portno);
- if (err) {
- /* most likely the HUB is gone */
- break;
- }
- }
- if (sc->sc_st.port_change & UPS_C_SUSPEND) {
- err = uhub_suspend_resume_port(sc, portno);
- if (err) {
- /* most likely the HUB is gone */
- break;
- }
- }
- err = uhub_explore_sub(sc, up);
- if (err) {
- /* no device(s) present */
- continue;
- }
- /* explore succeeded - reset restart counter */
- up->restartcnt = 0;
- }
-
- /* initial status checked */
- sc->sc_flags |= UHUB_FLAG_DID_EXPLORE;
-
- /* return success */
- return (USB_ERR_NORMAL_COMPLETION);
-}
-
-static int
-uhub_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- /*
- * The subclass for USB HUBs is ignored because it is 0 for
- * some and 1 for others.
- */
- if ((uaa->info.bConfigIndex == 0) &&
- (uaa->info.bDeviceClass == UDCLASS_HUB)) {
- return (0);
- }
- return (ENXIO);
-}
-
-static int
-uhub_attach(device_t dev)
-{
- struct uhub_softc *sc = device_get_softc(dev);
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct usb2_device *udev = uaa->device;
- struct usb2_device *parent_hub = udev->parent_hub;
- struct usb2_hub *hub;
- struct usb2_hub_descriptor hubdesc;
- uint16_t pwrdly;
- uint8_t x;
- uint8_t nports;
- uint8_t portno;
- uint8_t removable;
- uint8_t iface_index;
- usb2_error_t err;
-
- sc->sc_udev = udev;
- sc->sc_dev = dev;
-
- snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
- device_get_nameunit(dev));
-
- device_set_usb2_desc(dev);
-
- DPRINTFN(2, "depth=%d selfpowered=%d, parent=%p, "
- "parent->selfpowered=%d\n",
- udev->depth,
- udev->flags.self_powered,
- parent_hub,
- parent_hub ?
- parent_hub->flags.self_powered : 0);
-
- if (udev->depth > USB_HUB_MAX_DEPTH) {
- DPRINTFN(0, "hub depth, %d, exceeded. HUB ignored!\n",
- USB_HUB_MAX_DEPTH);
- goto error;
- }
- if (!udev->flags.self_powered && parent_hub &&
- (!parent_hub->flags.self_powered)) {
- DPRINTFN(0, "bus powered HUB connected to "
- "bus powered HUB. HUB ignored!\n");
- goto error;
- }
- /* get HUB descriptor */
-
- DPRINTFN(2, "getting HUB descriptor\n");
-
- /* assuming that there is one port */
- err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, 1);
-
- nports = hubdesc.bNbrPorts;
-
- if (!err && (nports >= 8)) {
- /* get complete HUB descriptor */
- err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, nports);
- }
- if (err) {
- DPRINTFN(0, "getting hub descriptor failed,"
- "error=%s\n", usb2_errstr(err));
- goto error;
- }
- if (hubdesc.bNbrPorts != nports) {
- DPRINTFN(0, "number of ports changed!\n");
- goto error;
- }
- if (nports == 0) {
- DPRINTFN(0, "portless HUB!\n");
- goto error;
- }
- hub = malloc(sizeof(hub[0]) + (sizeof(hub->ports[0]) * nports),
- M_USBDEV, M_WAITOK | M_ZERO);
-
- if (hub == NULL) {
- goto error;
- }
- udev->hub = hub;
-
- /* init FULL-speed ISOCHRONOUS schedule */
- usb2_fs_isoc_schedule_init_all(hub->fs_isoc_schedule);
-
- /* initialize HUB structure */
- hub->hubsoftc = sc;
- hub->explore = &uhub_explore;
- hub->nports = hubdesc.bNbrPorts;
- hub->hubudev = udev;
-
- /* if self powered hub, give ports maximum current */
- if (udev->flags.self_powered) {
- hub->portpower = USB_MAX_POWER;
- } else {
- hub->portpower = USB_MIN_POWER;
- }
-
- /* set up interrupt pipe */
- iface_index = 0;
- err = usb2_transfer_setup(udev, &iface_index, sc->sc_xfer,
- uhub_config, UHUB_N_TRANSFER, sc, &Giant);
- if (err) {
- DPRINTFN(0, "cannot setup interrupt transfer, "
- "errstr=%s!\n", usb2_errstr(err));
- goto error;
- }
- /* wait with power off for a while */
- usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(USB_POWER_DOWN_TIME));
-
- /*
- * 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
- */
-
- /* XXX should check for none, individual, or ganged power? */
-
- removable = 0;
- pwrdly = ((hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
- USB_EXTRA_POWER_UP_TIME);
-
- for (x = 0; x != nports; x++) {
- /* set up data structures */
- struct usb2_port *up = hub->ports + x;
-
- up->device_index = 0;
- up->restartcnt = 0;
- portno = x + 1;
-
- /* check if port is removable */
- if (!UHD_NOT_REMOV(&hubdesc, portno)) {
- removable++;
- }
- if (!err) {
- /* turn the power on */
- err = usb2_req_set_port_feature(udev, &Giant,
- portno, UHF_PORT_POWER);
- }
- if (err) {
- DPRINTFN(0, "port %d power on failed, %s\n",
- portno, usb2_errstr(err));
- }
- DPRINTF("turn on port %d power\n",
- portno);
-
- /* wait for stable power */
- usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(pwrdly));
- }
-
- device_printf(dev, "%d port%s with %d "
- "removable, %s powered\n", nports, (nports != 1) ? "s" : "",
- removable, udev->flags.self_powered ? "self" : "bus");
-
- /* start the interrupt endpoint */
-
- USB_XFER_LOCK(sc->sc_xfer[0]);
- usb2_transfer_start(sc->sc_xfer[0]);
- USB_XFER_UNLOCK(sc->sc_xfer[0]);
-
- /* Enable automatic power save on all USB HUBs */
-
- usb2_set_power_mode(udev, USB_POWER_MODE_SAVE);
-
- return (0);
-
-error:
- usb2_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
-
- if (udev->hub) {
- free(udev->hub, M_USBDEV);
- udev->hub = NULL;
- }
- return (ENXIO);
-}
-
-/*
- * Called from process context when the hub is gone.
- * Detach all devices on active ports.
- */
-static int
-uhub_detach(device_t dev)
-{
- struct uhub_softc *sc = device_get_softc(dev);
- struct usb2_hub *hub = sc->sc_udev->hub;
- struct usb2_device *child;
- uint8_t x;
-
- /* detach all children first */
- bus_generic_detach(dev);
-
- if (hub == NULL) { /* must be partially working */
- return (0);
- }
- for (x = 0; x != hub->nports; x++) {
-
- child = usb2_bus_port_get_device(sc->sc_udev->bus, hub->ports + x);
-
- if (child == NULL) {
- continue;
- }
- /*
- * Subdevices are not freed, because the caller of
- * uhub_detach() will do that.
- */
- usb2_detach_device(child, USB_IFACE_INDEX_ANY, 0);
- usb2_free_device(child);
- child = NULL;
- }
-
- usb2_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
-
- free(hub, M_USBDEV);
- sc->sc_udev->hub = NULL;
- return (0);
-}
-
-static int
-uhub_suspend(device_t dev)
-{
- DPRINTF("\n");
- /* Sub-devices are not suspended here! */
- return (0);
-}
-
-static int
-uhub_resume(device_t dev)
-{
- DPRINTF("\n");
- /* Sub-devices are not resumed here! */
- return (0);
-}
-
-static void
-uhub_driver_added(device_t dev, driver_t *driver)
-{
- usb2_needs_explore_all();
-}
-
-struct hub_result {
- struct usb2_device *udev;
- uint8_t portno;
- uint8_t iface_index;
-};
-
-static void
-uhub_find_iface_index(struct usb2_hub *hub, device_t child,
- struct hub_result *res)
-{
- struct usb2_interface *iface;
- struct usb2_device *udev;
- uint8_t nports;
- uint8_t x;
- uint8_t i;
-
- nports = hub->nports;
- for (x = 0; x != nports; x++) {
- udev = usb2_bus_port_get_device(hub->hubudev->bus,
- hub->ports + x);
- if (!udev) {
- continue;
- }
- for (i = 0; i != USB_IFACE_MAX; i++) {
- iface = usb2_get_iface(udev, i);
- if (iface &&
- (iface->subdev == child)) {
- res->iface_index = i;
- res->udev = udev;
- res->portno = x + 1;
- return;
- }
- }
- }
- res->iface_index = 0;
- res->udev = NULL;
- res->portno = 0;
-}
-
-static int
-uhub_child_location_string(device_t parent, device_t child,
- char *buf, size_t buflen)
-{
- struct uhub_softc *sc = device_get_softc(parent);
- struct usb2_hub *hub = sc->sc_udev->hub;
- struct hub_result res;
-
- mtx_lock(&Giant);
- uhub_find_iface_index(hub, child, &res);
- if (!res.udev) {
- DPRINTF("device not on hub\n");
- if (buflen) {
- buf[0] = '\0';
- }
- goto done;
- }
- snprintf(buf, buflen, "port=%u interface=%u",
- res.portno, res.iface_index);
-done:
- mtx_unlock(&Giant);
-
- return (0);
-}
-
-static int
-uhub_child_pnpinfo_string(device_t parent, device_t child,
- char *buf, size_t buflen)
-{
- struct uhub_softc *sc = device_get_softc(parent);
- struct usb2_hub *hub = sc->sc_udev->hub;
- struct usb2_interface *iface;
- struct hub_result res;
-
- mtx_lock(&Giant);
- uhub_find_iface_index(hub, child, &res);
- if (!res.udev) {
- DPRINTF("device not on hub\n");
- if (buflen) {
- buf[0] = '\0';
- }
- goto done;
- }
- iface = usb2_get_iface(res.udev, res.iface_index);
- if (iface && iface->idesc) {
- snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
- "devclass=0x%02x devsubclass=0x%02x "
- "sernum=\"%s\" "
- "intclass=0x%02x intsubclass=0x%02x",
- UGETW(res.udev->ddesc.idVendor),
- UGETW(res.udev->ddesc.idProduct),
- res.udev->ddesc.bDeviceClass,
- res.udev->ddesc.bDeviceSubClass,
- res.udev->serial,
- iface->idesc->bInterfaceClass,
- iface->idesc->bInterfaceSubClass);
- } else {
- if (buflen) {
- buf[0] = '\0';
- }
- goto done;
- }
-done:
- mtx_unlock(&Giant);
-
- return (0);
-}
-
-/*
- * The USB Transaction Translator:
- * ===============================
- *
- * When doing LOW- and FULL-speed USB transfers accross a HIGH-speed
- * USB HUB, bandwidth must be allocated for ISOCHRONOUS and INTERRUPT
- * USB transfers. To utilize bandwidth dynamically the "scatter and
- * gather" principle must be applied. This means that bandwidth must
- * be divided into equal parts of bandwidth. With regard to USB all
- * data is transferred in smaller packets with length
- * "wMaxPacketSize". The problem however is that "wMaxPacketSize" is
- * not a constant!
- *
- * The bandwidth scheduler which I have implemented will simply pack
- * the USB transfers back to back until there is no more space in the
- * schedule. Out of the 8 microframes which the USB 2.0 standard
- * provides, only 6 are available for non-HIGH-speed devices. I have
- * reserved the first 4 microframes for ISOCHRONOUS transfers. The
- * last 2 microframes I have reserved for INTERRUPT transfers. Without
- * this division, it is very difficult to allocate and free bandwidth
- * dynamically.
- *
- * NOTE about the Transaction Translator in USB HUBs:
- *
- * USB HUBs have a very simple Transaction Translator, that will
- * simply pipeline all the SPLIT transactions. That means that the
- * transactions will be executed in the order they are queued!
- *
- */
-
-/*------------------------------------------------------------------------*
- * usb2_intr_find_best_slot
- *
- * Return value:
- * The best Transaction Translation slot for an interrupt endpoint.
- *------------------------------------------------------------------------*/
-static uint8_t
-usb2_intr_find_best_slot(uint32_t *ptr, uint8_t start, uint8_t end)
-{
- uint32_t max = 0xffffffff;
- uint8_t x;
- uint8_t y;
-
- y = 0;
-
- /* find the last slot with lesser used bandwidth */
-
- for (x = start; x < end; x++) {
- if (max >= ptr[x]) {
- max = ptr[x];
- y = x;
- }
- }
- return (y);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_intr_schedule_adjust
- *
- * This function will update the bandwith usage for the microframe
- * having index "slot" by "len" bytes. "len" can be negative. If the
- * "slot" argument is greater or equal to "USB_HS_MICRO_FRAMES_MAX"
- * the "slot" argument will be replaced by the slot having least used
- * bandwidth.
- *
- * Returns:
- * The slot on which the bandwidth update was done.
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_intr_schedule_adjust(struct usb2_device *udev, int16_t len, uint8_t slot)
-{
- struct usb2_bus *bus = udev->bus;
- struct usb2_hub *hub;
- uint8_t speed;
-
- USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
-
- speed = usb2_get_speed(udev);
-
- switch (speed) {
- case USB_SPEED_LOW:
- case USB_SPEED_FULL:
- if (speed == USB_SPEED_LOW) {
- len *= 8;
- }
- /*
- * The Host Controller Driver should have
- * performed checks so that the lookup
- * below does not result in a NULL pointer
- * access.
- */
-
- hub = bus->devices[udev->hs_hub_addr]->hub;
- if (slot >= USB_HS_MICRO_FRAMES_MAX) {
- slot = usb2_intr_find_best_slot(hub->uframe_usage,
- USB_FS_ISOC_UFRAME_MAX, 6);
- }
- hub->uframe_usage[slot] += len;
- bus->uframe_usage[slot] += len;
- break;
- default:
- if (slot >= USB_HS_MICRO_FRAMES_MAX) {
- slot = usb2_intr_find_best_slot(bus->uframe_usage, 0,
- USB_HS_MICRO_FRAMES_MAX);
- }
- bus->uframe_usage[slot] += len;
- break;
- }
- return (slot);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fs_isoc_schedule_init_sub
- *
- * This function initialises an USB FULL speed isochronous schedule
- * entry.
- *------------------------------------------------------------------------*/
-static void
-usb2_fs_isoc_schedule_init_sub(struct usb2_fs_isoc_schedule *fss)
-{
- fss->total_bytes = (USB_FS_ISOC_UFRAME_MAX *
- USB_FS_BYTES_PER_HS_UFRAME);
- fss->frame_bytes = (USB_FS_BYTES_PER_HS_UFRAME);
- fss->frame_slot = 0;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fs_isoc_schedule_init_all
- *
- * This function will reset the complete USB FULL speed isochronous
- * bandwidth schedule.
- *------------------------------------------------------------------------*/
-void
-usb2_fs_isoc_schedule_init_all(struct usb2_fs_isoc_schedule *fss)
-{
- struct usb2_fs_isoc_schedule *fss_end = fss + USB_ISOC_TIME_MAX;
-
- while (fss != fss_end) {
- usb2_fs_isoc_schedule_init_sub(fss);
- fss++;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_isoc_time_expand
- *
- * This function will expand the time counter from 7-bit to 16-bit.
- *
- * Returns:
- * 16-bit isochronous time counter.
- *------------------------------------------------------------------------*/
-uint16_t
-usb2_isoc_time_expand(struct usb2_bus *bus, uint16_t isoc_time_curr)
-{
- uint16_t rem;
-
- USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
-
- rem = bus->isoc_time_last & (USB_ISOC_TIME_MAX - 1);
-
- isoc_time_curr &= (USB_ISOC_TIME_MAX - 1);
-
- if (isoc_time_curr < rem) {
- /* the time counter wrapped around */
- bus->isoc_time_last += USB_ISOC_TIME_MAX;
- }
- /* update the remainder */
-
- bus->isoc_time_last &= ~(USB_ISOC_TIME_MAX - 1);
- bus->isoc_time_last |= isoc_time_curr;
-
- return (bus->isoc_time_last);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fs_isoc_schedule_isoc_time_expand
- *
- * This function does multiple things. First of all it will expand the
- * passed isochronous time, which is the return value. Then it will
- * store where the current FULL speed isochronous schedule is
- * positioned in time and where the end is. See "pp_start" and
- * "pp_end" arguments.
- *
- * Returns:
- * Expanded version of "isoc_time".
- *
- * NOTE: This function depends on being called regularly with
- * intervals less than "USB_ISOC_TIME_MAX".
- *------------------------------------------------------------------------*/
-uint16_t
-usb2_fs_isoc_schedule_isoc_time_expand(struct usb2_device *udev,
- struct usb2_fs_isoc_schedule **pp_start,
- struct usb2_fs_isoc_schedule **pp_end,
- uint16_t isoc_time)
-{
- struct usb2_fs_isoc_schedule *fss_end;
- struct usb2_fs_isoc_schedule *fss_a;
- struct usb2_fs_isoc_schedule *fss_b;
- struct usb2_hub *hs_hub;
-
- isoc_time = usb2_isoc_time_expand(udev->bus, isoc_time);
-
- hs_hub = udev->bus->devices[udev->hs_hub_addr]->hub;
-
- if (hs_hub != NULL) {
-
- fss_a = hs_hub->fs_isoc_schedule +
- (hs_hub->isoc_last_time % USB_ISOC_TIME_MAX);
-
- hs_hub->isoc_last_time = isoc_time;
-
- fss_b = hs_hub->fs_isoc_schedule +
- (isoc_time % USB_ISOC_TIME_MAX);
-
- fss_end = hs_hub->fs_isoc_schedule + USB_ISOC_TIME_MAX;
-
- *pp_start = hs_hub->fs_isoc_schedule;
- *pp_end = fss_end;
-
- while (fss_a != fss_b) {
- if (fss_a == fss_end) {
- fss_a = hs_hub->fs_isoc_schedule;
- continue;
- }
- usb2_fs_isoc_schedule_init_sub(fss_a);
- fss_a++;
- }
-
- } else {
-
- *pp_start = NULL;
- *pp_end = NULL;
- }
- return (isoc_time);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_fs_isoc_schedule_alloc
- *
- * This function will allocate bandwidth for an isochronous FULL speed
- * transaction in the FULL speed schedule. The microframe slot where
- * the transaction should be started is stored in the byte pointed to
- * by "pstart". The "len" argument specifies the length of the
- * transaction in bytes.
- *
- * Returns:
- * 0: Success
- * Else: Error
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_fs_isoc_schedule_alloc(struct usb2_fs_isoc_schedule *fss,
- uint8_t *pstart, uint16_t len)
-{
- uint8_t slot = fss->frame_slot;
-
- /* Compute overhead and bit-stuffing */
-
- len += 8;
-
- len *= 7;
- len /= 6;
-
- if (len > fss->total_bytes) {
- *pstart = 0; /* set some dummy value */
- return (1); /* error */
- }
- if (len > 0) {
-
- fss->total_bytes -= len;
-
- while (len >= fss->frame_bytes) {
- len -= fss->frame_bytes;
- fss->frame_bytes = USB_FS_BYTES_PER_HS_UFRAME;
- fss->frame_slot++;
- }
-
- fss->frame_bytes -= len;
- }
- *pstart = slot;
- return (0); /* success */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_port_get_device
- *
- * This function is NULL safe.
- *------------------------------------------------------------------------*/
-struct usb2_device *
-usb2_bus_port_get_device(struct usb2_bus *bus, struct usb2_port *up)
-{
- if ((bus == NULL) || (up == NULL)) {
- /* be NULL safe */
- return (NULL);
- }
- if (up->device_index == 0) {
- /* nothing to do */
- return (NULL);
- }
- return (bus->devices[up->device_index]);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_port_set_device
- *
- * This function is NULL safe.
- *------------------------------------------------------------------------*/
-void
-usb2_bus_port_set_device(struct usb2_bus *bus, struct usb2_port *up,
- struct usb2_device *udev, uint8_t device_index)
-{
- if (bus == NULL) {
- /* be NULL safe */
- return;
- }
- /*
- * There is only one case where we don't
- * have an USB port, and that is the Root Hub!
- */
- if (up) {
- if (udev) {
- up->device_index = device_index;
- } else {
- device_index = up->device_index;
- up->device_index = 0;
- }
- }
- /*
- * Make relationships to our new device
- */
- if (device_index != 0) {
- mtx_lock(&usb2_ref_lock);
- bus->devices[device_index] = udev;
- mtx_unlock(&usb2_ref_lock);
- }
- /*
- * Debug print
- */
- DPRINTFN(2, "bus %p devices[%u] = %p\n", bus, device_index, udev);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_needs_explore
- *
- * This functions is called when the USB event thread needs to run.
- *------------------------------------------------------------------------*/
-void
-usb2_needs_explore(struct usb2_bus *bus, uint8_t do_probe)
-{
- DPRINTF("\n");
-
- if (bus == NULL) {
- DPRINTF("No bus pointer!\n");
- return;
- }
- USB_BUS_LOCK(bus);
- if (do_probe) {
- bus->do_probe = 1;
- }
- if (usb2_proc_msignal(&bus->explore_proc,
- &bus->explore_msg[0], &bus->explore_msg[1])) {
- /* ignore */
- }
- USB_BUS_UNLOCK(bus);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_needs_explore_all
- *
- * This function is called whenever a new driver is loaded and will
- * cause that all USB busses are re-explored.
- *------------------------------------------------------------------------*/
-void
-usb2_needs_explore_all(void)
-{
- struct usb2_bus *bus;
- devclass_t dc;
- device_t dev;
- int max;
-
- DPRINTFN(3, "\n");
-
- dc = usb2_devclass_ptr;
- if (dc == NULL) {
- DPRINTFN(0, "no devclass\n");
- return;
- }
- /*
- * Explore all USB busses in parallell.
- */
- max = devclass_get_maxunit(dc);
- while (max >= 0) {
- dev = devclass_get_device(dc, max);
- if (dev) {
- bus = device_get_softc(dev);
- if (bus) {
- usb2_needs_explore(bus, 1);
- }
- }
- max--;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_power_update
- *
- * This function will ensure that all USB devices on the given bus are
- * properly suspended or resumed according to the device transfer
- * state.
- *------------------------------------------------------------------------*/
-void
-usb2_bus_power_update(struct usb2_bus *bus)
-{
- usb2_needs_explore(bus, 0 /* no probe */ );
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_power_ref
- *
- * This function will modify the power save reference counts and
- * wakeup the USB device associated with the given USB transfer, if
- * needed.
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_power_ref(struct usb2_xfer *xfer, int val)
-{
- static const uint32_t power_mask[4] = {
- [UE_CONTROL] = USB_HW_POWER_CONTROL,
- [UE_BULK] = USB_HW_POWER_BULK,
- [UE_INTERRUPT] = USB_HW_POWER_INTERRUPT,
- [UE_ISOCHRONOUS] = USB_HW_POWER_ISOC,
- };
- struct usb2_device *udev;
- uint8_t needs_explore;
- uint8_t needs_hw_power;
- uint8_t xfer_type;
-
- udev = xfer->xroot->udev;
-
- if (udev->device_index == USB_ROOT_HUB_ADDR) {
- /* no power save for root HUB */
- return;
- }
- USB_BUS_LOCK(udev->bus);
-
- xfer_type = xfer->pipe->edesc->bmAttributes & UE_XFERTYPE;
-
- udev->pwr_save.last_xfer_time = ticks;
- udev->pwr_save.type_refs[xfer_type] += val;
-
- if (xfer->flags_int.control_xfr) {
- udev->pwr_save.read_refs += val;
- if (xfer->flags_int.usb2_mode == USB_MODE_HOST) {
- /*
- * it is not allowed to suspend during a control
- * transfer
- */
- udev->pwr_save.write_refs += val;
- }
- } else if (USB_GET_DATA_ISREAD(xfer)) {
- udev->pwr_save.read_refs += val;
- } else {
- udev->pwr_save.write_refs += val;
- }
-
- if (udev->pwr_save.suspended)
- needs_explore =
- (udev->pwr_save.write_refs != 0) ||
- ((udev->pwr_save.read_refs != 0) &&
- (usb2_peer_can_wakeup(udev) == 0));
- else
- needs_explore = 0;
-
- if (!(udev->bus->hw_power_state & power_mask[xfer_type])) {
- DPRINTF("Adding type %u to power state\n", xfer_type);
- udev->bus->hw_power_state |= power_mask[xfer_type];
- needs_hw_power = 1;
- } else {
- needs_hw_power = 0;
- }
-
- USB_BUS_UNLOCK(udev->bus);
-
- if (needs_explore) {
- DPRINTF("update\n");
- usb2_bus_power_update(udev->bus);
- } else if (needs_hw_power) {
- DPRINTF("needs power\n");
- if (udev->bus->methods->set_hw_power != NULL) {
- (udev->bus->methods->set_hw_power) (udev->bus);
- }
- }
- return;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_bus_powerd
- *
- * This function implements the USB power daemon and is called
- * regularly from the USB explore thread.
- *------------------------------------------------------------------------*/
-void
-usb2_bus_powerd(struct usb2_bus *bus)
-{
- struct usb2_device *udev;
- unsigned int temp;
- unsigned int limit;
- unsigned int mintime;
- uint32_t type_refs[5];
- uint8_t x;
- uint8_t rem_wakeup;
-
- limit = usb2_power_timeout;
- if (limit == 0)
- limit = hz;
- else if (limit > 255)
- limit = 255 * hz;
- else
- limit = limit * hz;
-
- DPRINTF("bus=%p\n", bus);
-
- USB_BUS_LOCK(bus);
-
- /*
- * The root HUB device is never suspended
- * and we simply skip it.
- */
- for (x = USB_ROOT_HUB_ADDR + 1;
- x != bus->devices_max; x++) {
-
- udev = bus->devices[x];
- if (udev == NULL)
- continue;
-
- rem_wakeup = usb2_peer_can_wakeup(udev);
-
- temp = ticks - udev->pwr_save.last_xfer_time;
-
- if ((udev->power_mode == USB_POWER_MODE_ON) ||
- (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0) ||
- (udev->pwr_save.write_refs != 0) ||
- ((udev->pwr_save.read_refs != 0) &&
- (rem_wakeup == 0))) {
-
- /* check if we are suspended */
- if (udev->pwr_save.suspended != 0) {
- USB_BUS_UNLOCK(bus);
- usb2_dev_resume_peer(udev);
- USB_BUS_LOCK(bus);
- }
- } else if (temp >= limit) {
-
- /* check if we are not suspended */
- if (udev->pwr_save.suspended == 0) {
- USB_BUS_UNLOCK(bus);
- usb2_dev_suspend_peer(udev);
- USB_BUS_LOCK(bus);
- }
- }
- }
-
- /* reset counters */
-
- mintime = 0 - 1;
- type_refs[0] = 0;
- type_refs[1] = 0;
- type_refs[2] = 0;
- type_refs[3] = 0;
- type_refs[4] = 0;
-
- /* Re-loop all the devices to get the actual state */
-
- for (x = USB_ROOT_HUB_ADDR + 1;
- x != bus->devices_max; x++) {
-
- udev = bus->devices[x];
- if (udev == NULL)
- continue;
-
- /* we found a non-Root-Hub USB device */
- type_refs[4] += 1;
-
- /* "last_xfer_time" can be updated by a resume */
- temp = ticks - udev->pwr_save.last_xfer_time;
-
- /*
- * Compute minimum time since last transfer for the complete
- * bus:
- */
- if (temp < mintime)
- mintime = temp;
-
- if (udev->pwr_save.suspended == 0) {
- type_refs[0] += udev->pwr_save.type_refs[0];
- type_refs[1] += udev->pwr_save.type_refs[1];
- type_refs[2] += udev->pwr_save.type_refs[2];
- type_refs[3] += udev->pwr_save.type_refs[3];
- }
- }
-
- if (mintime >= (1 * hz)) {
- /* recompute power masks */
- DPRINTF("Recomputing power masks\n");
- bus->hw_power_state = 0;
- if (type_refs[UE_CONTROL] != 0)
- bus->hw_power_state |= USB_HW_POWER_CONTROL;
- if (type_refs[UE_BULK] != 0)
- bus->hw_power_state |= USB_HW_POWER_BULK;
- if (type_refs[UE_INTERRUPT] != 0)
- bus->hw_power_state |= USB_HW_POWER_INTERRUPT;
- if (type_refs[UE_ISOCHRONOUS] != 0)
- bus->hw_power_state |= USB_HW_POWER_ISOC;
- if (type_refs[4] != 0)
- bus->hw_power_state |= USB_HW_POWER_NON_ROOT_HUB;
- }
- USB_BUS_UNLOCK(bus);
-
- if (bus->methods->set_hw_power != NULL) {
- /* always update hardware power! */
- (bus->methods->set_hw_power) (bus);
- }
- return;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_dev_resume_peer
- *
- * This function will resume an USB peer and do the required USB
- * signalling to get an USB device out of the suspended state.
- *------------------------------------------------------------------------*/
-static void
-usb2_dev_resume_peer(struct usb2_device *udev)
-{
- struct usb2_bus *bus;
- int err;
-
- /* be NULL safe */
- if (udev == NULL)
- return;
-
- /* check if already resumed */
- if (udev->pwr_save.suspended == 0)
- return;
-
- /* we need a parent HUB to do resume */
- if (udev->parent_hub == NULL)
- return;
-
- DPRINTF("udev=%p\n", udev);
-
- if ((udev->flags.usb2_mode == USB_MODE_DEVICE) &&
- (udev->flags.remote_wakeup == 0)) {
- /*
- * If the host did not set the remote wakeup feature, we can
- * not wake it up either!
- */
- DPRINTF("remote wakeup is not set!\n");
- return;
- }
- /* get bus pointer */
- bus = udev->bus;
-
- /* resume parent hub first */
- usb2_dev_resume_peer(udev->parent_hub);
-
- /* resume current port (Valid in Host and Device Mode) */
- err = usb2_req_clear_port_feature(udev->parent_hub,
- &Giant, udev->port_no, UHF_PORT_SUSPEND);
- if (err) {
- DPRINTFN(0, "Resuming port failed!\n");
- return;
- }
- /* resume settle time */
- usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(USB_PORT_RESUME_DELAY));
-
- if (bus->methods->device_resume != NULL) {
- /* resume USB device on the USB controller */
- (bus->methods->device_resume) (udev);
- }
- USB_BUS_LOCK(bus);
- /* set that this device is now resumed */
- udev->pwr_save.suspended = 0;
- /* make sure that we don't go into suspend right away */
- udev->pwr_save.last_xfer_time = ticks;
-
- /* make sure the needed power masks are on */
- if (udev->pwr_save.type_refs[UE_CONTROL] != 0)
- bus->hw_power_state |= USB_HW_POWER_CONTROL;
- if (udev->pwr_save.type_refs[UE_BULK] != 0)
- bus->hw_power_state |= USB_HW_POWER_BULK;
- if (udev->pwr_save.type_refs[UE_INTERRUPT] != 0)
- bus->hw_power_state |= USB_HW_POWER_INTERRUPT;
- if (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0)
- bus->hw_power_state |= USB_HW_POWER_ISOC;
- USB_BUS_UNLOCK(bus);
-
- if (bus->methods->set_hw_power != NULL) {
- /* always update hardware power! */
- (bus->methods->set_hw_power) (bus);
- }
- sx_xlock(udev->default_sx + 1);
- /* notify all sub-devices about resume */
- err = usb2_suspend_resume(udev, 0);
- sx_unlock(udev->default_sx + 1);
-
- /* check if peer has wakeup capability */
- if (usb2_peer_can_wakeup(udev)) {
- /* clear remote wakeup */
- err = usb2_req_clear_device_feature(udev,
- &Giant, UF_DEVICE_REMOTE_WAKEUP);
- if (err) {
- DPRINTFN(0, "Clearing device "
- "remote wakeup failed: %s!\n",
- usb2_errstr(err));
- }
- }
- return;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_dev_suspend_peer
- *
- * This function will suspend an USB peer and do the required USB
- * signalling to get an USB device into the suspended state.
- *------------------------------------------------------------------------*/
-static void
-usb2_dev_suspend_peer(struct usb2_device *udev)
-{
- struct usb2_device *hub;
- struct usb2_device *child;
- uint32_t temp;
- int err;
- uint8_t x;
- uint8_t nports;
- uint8_t suspend_parent;
-
-repeat:
- /* be NULL safe */
- if (udev == NULL)
- return;
-
- /* check if already suspended */
- if (udev->pwr_save.suspended)
- return;
-
- /* we need a parent HUB to do suspend */
- if (udev->parent_hub == NULL)
- return;
-
- DPRINTF("udev=%p\n", udev);
-
- /* check if all devices on the parent hub are suspended */
- hub = udev->parent_hub;
- if (hub != NULL) {
- nports = hub->hub->nports;
- suspend_parent = 1;
-
- for (x = 0; x != nports; x++) {
-
- child = usb2_bus_port_get_device(hub->bus,
- hub->hub->ports + x);
-
- if (child == NULL)
- continue;
-
- if (child->pwr_save.suspended)
- continue;
-
- if (child == udev)
- continue;
-
- /* another device on the HUB is not suspended */
- suspend_parent = 0;
-
- break;
- }
- } else {
- suspend_parent = 0;
- }
-
- sx_xlock(udev->default_sx + 1);
- /* notify all sub-devices about suspend */
- err = usb2_suspend_resume(udev, 1);
- sx_unlock(udev->default_sx + 1);
-
- if (usb2_peer_can_wakeup(udev)) {
- /* allow device to do remote wakeup */
- err = usb2_req_set_device_feature(udev,
- &Giant, UF_DEVICE_REMOTE_WAKEUP);
- if (err) {
- DPRINTFN(0, "Setting device "
- "remote wakeup failed!\n");
- }
- }
- USB_BUS_LOCK(udev->bus);
- /*
- * Set that this device is suspended. This variable must be set
- * before calling USB controller suspend callbacks.
- */
- udev->pwr_save.suspended = 1;
- USB_BUS_UNLOCK(udev->bus);
-
- if (udev->bus->methods->device_suspend != NULL) {
-
- /* suspend device on the USB controller */
- (udev->bus->methods->device_suspend) (udev);
-
- /* do DMA delay */
- temp = usb2_get_dma_delay(udev->bus);
- usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(temp));
-
- }
- /* suspend current port */
- err = usb2_req_set_port_feature(udev->parent_hub,
- &Giant, udev->port_no, UHF_PORT_SUSPEND);
- if (err) {
- DPRINTFN(0, "Suspending port failed\n");
- return;
- }
- if (suspend_parent) {
- udev = udev->parent_hub;
- goto repeat;
- }
- return;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_set_power_mode
- *
- * This function will set the power mode, see USB_POWER_MODE_XXX for a
- * USB device.
- *------------------------------------------------------------------------*/
-void
-usb2_set_power_mode(struct usb2_device *udev, uint8_t power_mode)
-{
- /* filter input argument */
- if ((power_mode != USB_POWER_MODE_ON) &&
- (power_mode != USB_POWER_MODE_OFF)) {
- power_mode = USB_POWER_MODE_SAVE;
- }
- udev->power_mode = power_mode; /* update copy of power mode */
-
- usb2_bus_power_update(udev->bus);
-
- return;
-}
diff --git a/sys/dev/usb2/core/usb2_hub.h b/sys/dev/usb2/core/usb2_hub.h
deleted file mode 100644
index 87d85b3..0000000
--- a/sys/dev/usb2/core/usb2_hub.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_HUB_H_
-#define _USB2_HUB_H_
-
-/*
- * The following structure defines an USB port.
- */
-struct usb2_port {
- uint8_t restartcnt;
-#define USB_RESTART_MAX 5
- uint8_t device_index; /* zero means not valid */
- uint8_t usb2_mode:1; /* current USB mode */
- uint8_t unused:7;
-};
-
-/*
- * The following structure defines how many bytes are
- * left in an 1ms USB time slot.
- */
-struct usb2_fs_isoc_schedule {
- uint16_t total_bytes;
- uint8_t frame_bytes;
- uint8_t frame_slot;
-};
-
-/*
- * The following structure defines an USB HUB.
- */
-struct usb2_hub {
- struct usb2_fs_isoc_schedule fs_isoc_schedule[USB_ISOC_TIME_MAX];
- struct usb2_device *hubudev; /* the HUB device */
- usb2_error_t (*explore) (struct usb2_device *hub);
- void *hubsoftc;
- uint32_t uframe_usage[USB_HS_MICRO_FRAMES_MAX];
- uint16_t portpower; /* mA per USB port */
- uint8_t isoc_last_time;
- uint8_t nports;
- struct usb2_port ports[0];
-};
-
-/* function prototypes */
-
-uint8_t usb2_intr_schedule_adjust(struct usb2_device *udev, int16_t len,
- uint8_t slot);
-void usb2_fs_isoc_schedule_init_all(struct usb2_fs_isoc_schedule *fss);
-void usb2_bus_port_set_device(struct usb2_bus *bus, struct usb2_port *up,
- struct usb2_device *udev, uint8_t device_index);
-struct usb2_device *usb2_bus_port_get_device(struct usb2_bus *bus,
- struct usb2_port *up);
-void usb2_needs_explore(struct usb2_bus *bus, uint8_t do_probe);
-void usb2_needs_explore_all(void);
-void usb2_bus_power_update(struct usb2_bus *bus);
-void usb2_bus_powerd(struct usb2_bus *bus);
-
-#endif /* _USB2_HUB_H_ */
diff --git a/sys/dev/usb2/core/usb2_if.m b/sys/dev/usb2/core/usb2_if.m
deleted file mode 100644
index d0db8d4..0000000
--- a/sys/dev/usb2/core/usb2_if.m
+++ /dev/null
@@ -1,52 +0,0 @@
-#-
-# Copyright (c) 2008 Hans Petter Selasky. 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 usb2;
-
-# The device received a control request
-#
-# Return values:
-# 0: Success
-# ENOTTY: Transaction stalled
-# Else: Use builtin request handler
-#
-METHOD int handle_request {
- device_t dev;
- const void *req; /* pointer to the device request */
- void **pptr; /* data pointer */
- uint16_t *plen; /* maximum transfer length */
- uint16_t offset; /* data offset */
- uint8_t is_complete; /* set if transfer is complete */
-};
-
diff --git a/sys/dev/usb2/core/usb2_lookup.c b/sys/dev/usb2/core/usb2_lookup.c
deleted file mode 100644
index eaab8a3..0000000
--- a/sys/dev/usb2/core/usb2_lookup.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-
-/*------------------------------------------------------------------------*
- * usb2_lookup_id_by_info
- *
- * This functions takes an array of "struct usb2_device_id" and tries
- * to match the entries with the information in "struct usb2_lookup_info".
- *
- * NOTE: The "sizeof_id" parameter must be a multiple of the
- * usb2_device_id structure size. Else the behaviour of this function
- * is undefined.
- *
- * Return values:
- * NULL: No match found.
- * Else: Pointer to matching entry.
- *------------------------------------------------------------------------*/
-const struct usb2_device_id *
-usb2_lookup_id_by_info(const struct usb2_device_id *id, uint32_t sizeof_id,
- const struct usb2_lookup_info *info)
-{
- const struct usb2_device_id *id_end;
-
- if (id == NULL) {
- goto done;
- }
- id_end = (const void *)(((const uint8_t *)id) + sizeof_id);
-
- /*
- * Keep on matching array entries until we find a match or
- * until we reach the end of the matching array:
- */
- for (; id != id_end; id++) {
-
- if ((id->match_flag_vendor) &&
- (id->idVendor != info->idVendor)) {
- continue;
- }
- if ((id->match_flag_product) &&
- (id->idProduct != info->idProduct)) {
- continue;
- }
- if ((id->match_flag_dev_lo) &&
- (id->bcdDevice_lo > info->bcdDevice)) {
- continue;
- }
- if ((id->match_flag_dev_hi) &&
- (id->bcdDevice_hi < info->bcdDevice)) {
- continue;
- }
- if ((id->match_flag_dev_class) &&
- (id->bDeviceClass != info->bDeviceClass)) {
- continue;
- }
- if ((id->match_flag_dev_subclass) &&
- (id->bDeviceSubClass != info->bDeviceSubClass)) {
- continue;
- }
- if ((id->match_flag_dev_protocol) &&
- (id->bDeviceProtocol != info->bDeviceProtocol)) {
- continue;
- }
- if ((info->bDeviceClass == 0xFF) &&
- (!(id->match_flag_vendor)) &&
- ((id->match_flag_int_class) ||
- (id->match_flag_int_subclass) ||
- (id->match_flag_int_protocol))) {
- continue;
- }
- if ((id->match_flag_int_class) &&
- (id->bInterfaceClass != info->bInterfaceClass)) {
- continue;
- }
- if ((id->match_flag_int_subclass) &&
- (id->bInterfaceSubClass != info->bInterfaceSubClass)) {
- continue;
- }
- if ((id->match_flag_int_protocol) &&
- (id->bInterfaceProtocol != info->bInterfaceProtocol)) {
- continue;
- }
- /* We found a match! */
- return (id);
- }
-
-done:
- return (NULL);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_lookup_id_by_uaa - factored out code
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-int
-usb2_lookup_id_by_uaa(const struct usb2_device_id *id, uint32_t sizeof_id,
- struct usb2_attach_arg *uaa)
-{
- id = usb2_lookup_id_by_info(id, sizeof_id, &uaa->info);
- if (id) {
- /* copy driver info */
- uaa->driver_info = id->driver_info;
- return (0);
- }
- return (ENXIO);
-}
diff --git a/sys/dev/usb2/core/usb2_lookup.h b/sys/dev/usb2/core/usb2_lookup.h
deleted file mode 100644
index e447292..0000000
--- a/sys/dev/usb2/core/usb2_lookup.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_LOOKUP_H_
-#define _USB2_LOOKUP_H_
-
-struct usb2_attach_arg;
-
-/*
- * The following structure is used when looking up an USB driver for
- * an USB device. It is inspired by the Linux structure called
- * "usb2_device_id".
- */
-struct usb2_device_id {
-
- /* Hook for driver specific information */
- const void *driver_info;
-
- /* Used for product specific matches; the BCD range is inclusive */
- uint16_t idVendor;
- uint16_t idProduct;
- uint16_t bcdDevice_lo;
- uint16_t bcdDevice_hi;
-
- /* Used for device class matches */
- uint8_t bDeviceClass;
- uint8_t bDeviceSubClass;
- uint8_t bDeviceProtocol;
-
- /* Used for interface class matches */
- uint8_t bInterfaceClass;
- uint8_t bInterfaceSubClass;
- uint8_t bInterfaceProtocol;
-
- /* Select which fields to match against */
- uint8_t match_flag_vendor:1;
- uint8_t match_flag_product:1;
- uint8_t match_flag_dev_lo:1;
- uint8_t match_flag_dev_hi:1;
- uint8_t match_flag_dev_class:1;
- uint8_t match_flag_dev_subclass:1;
- uint8_t match_flag_dev_protocol:1;
- uint8_t match_flag_int_class:1;
- uint8_t match_flag_int_subclass:1;
- uint8_t match_flag_int_protocol:1;
-};
-
-#define USB_VENDOR(vend) \
- .match_flag_vendor = 1, .idVendor = (vend)
-
-#define USB_PRODUCT(prod) \
- .match_flag_product = 1, .idProduct = (prod)
-
-#define USB_VP(vend,prod) \
- USB_VENDOR(vend), USB_PRODUCT(prod)
-
-#define USB_VPI(vend,prod,info) \
- USB_VENDOR(vend), USB_PRODUCT(prod), USB_DRIVER_INFO(info)
-
-#define USB_DEV_BCD_GTEQ(lo) /* greater than or equal */ \
- .match_flag_dev_lo = 1, .bcdDevice_lo = (lo)
-
-#define USB_DEV_BCD_LTEQ(hi) /* less than or equal */ \
- .match_flag_dev_hi = 1, .bcdDevice_hi = (hi)
-
-#define USB_DEV_CLASS(dc) \
- .match_flag_dev_class = 1, .bDeviceClass = (dc)
-
-#define USB_DEV_SUBCLASS(dsc) \
- .match_flag_dev_subclass = 1, .bDeviceSubClass = (dsc)
-
-#define USB_DEV_PROTOCOL(dp) \
- .match_flag_dev_protocol = 1, .bDeviceProtocol = (dp)
-
-#define USB_IFACE_CLASS(ic) \
- .match_flag_int_class = 1, .bInterfaceClass = (ic)
-
-#define USB_IFACE_SUBCLASS(isc) \
- .match_flag_int_subclass = 1, .bInterfaceSubClass = (isc)
-
-#define USB_IFACE_PROTOCOL(ip) \
- .match_flag_int_protocol = 1, .bInterfaceProtocol = (ip)
-
-#define USB_IF_CSI(class,subclass,info) \
- USB_IFACE_CLASS(class), USB_IFACE_SUBCLASS(subclass), USB_DRIVER_INFO(info)
-
-#define USB_DRIVER_INFO(ptr) \
- .driver_info = ((const void *)(ptr))
-
-#define USB_GET_DRIVER_INFO(did) \
- (((const uint8_t *)((did)->driver_info)) - ((const uint8_t *)0))
-
-const struct usb2_device_id *usb2_lookup_id_by_info(
- const struct usb2_device_id *id, uint32_t sizeof_id,
- const struct usb2_lookup_info *info);
-int usb2_lookup_id_by_uaa(const struct usb2_device_id *id,
- uint32_t sizeof_id, struct usb2_attach_arg *uaa);
-
-#endif /* _USB2_LOOKUP_H_ */
diff --git a/sys/dev/usb2/core/usb2_mbuf.c b/sys/dev/usb2/core/usb2_mbuf.c
deleted file mode 100644
index 1f06f0f..0000000
--- a/sys/dev/usb2/core/usb2_mbuf.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-
-/*------------------------------------------------------------------------*
- * usb2_alloc_mbufs - allocate mbufs to an usbd interface queue
- *
- * Returns:
- * A pointer that should be passed to "free()" when the buffer(s)
- * should be released.
- *------------------------------------------------------------------------*/
-void *
-usb2_alloc_mbufs(struct malloc_type *type, struct usb2_ifqueue *ifq,
- uint32_t block_size, uint16_t nblocks)
-{
- struct usb2_mbuf *m_ptr;
- uint8_t *data_ptr;
- void *free_ptr = NULL;
- uint32_t alloc_size;
-
- /* align data */
- block_size += ((-block_size) & (USB_HOST_ALIGN - 1));
-
- if (nblocks && block_size) {
-
- alloc_size = (block_size + sizeof(struct usb2_mbuf)) * nblocks;
-
- free_ptr = malloc(alloc_size, type, M_WAITOK | M_ZERO);
-
- if (free_ptr == NULL) {
- goto done;
- }
- m_ptr = free_ptr;
- data_ptr = (void *)(m_ptr + nblocks);
-
- while (nblocks--) {
-
- m_ptr->cur_data_ptr =
- m_ptr->min_data_ptr = data_ptr;
-
- m_ptr->cur_data_len =
- m_ptr->max_data_len = block_size;
-
- USB_IF_ENQUEUE(ifq, m_ptr);
-
- m_ptr++;
- data_ptr += block_size;
- }
- }
-done:
- return (free_ptr);
-}
diff --git a/sys/dev/usb2/core/usb2_mbuf.h b/sys/dev/usb2/core/usb2_mbuf.h
deleted file mode 100644
index 109340c..0000000
--- a/sys/dev/usb2/core/usb2_mbuf.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_MBUF_H_
-#define _USB2_MBUF_H_
-
-/*
- * The following structure defines a minimum re-implementation of the
- * mbuf system in the kernel.
- */
-struct usb2_mbuf {
- uint8_t *cur_data_ptr;
- uint8_t *min_data_ptr;
- struct usb2_mbuf *usb2_nextpkt;
- struct usb2_mbuf *usb2_next;
-
- uint32_t cur_data_len;
- uint32_t max_data_len;
- uint8_t last_packet:1;
- uint8_t unused:7;
-};
-
-/*
- * The following structure defines a minimum re-implementation of the
- * ifqueue structure in the kernel.
- */
-struct usb2_ifqueue {
- struct usb2_mbuf *ifq_head;
- struct usb2_mbuf *ifq_tail;
-
- uint32_t ifq_len;
- uint32_t ifq_maxlen;
-};
-
-#define USB_IF_ENQUEUE(ifq, m) do { \
- (m)->usb2_nextpkt = NULL; \
- if ((ifq)->ifq_tail == NULL) \
- (ifq)->ifq_head = (m); \
- else \
- (ifq)->ifq_tail->usb2_nextpkt = (m); \
- (ifq)->ifq_tail = (m); \
- (ifq)->ifq_len++; \
- } while (0)
-
-#define USB_IF_DEQUEUE(ifq, m) do { \
- (m) = (ifq)->ifq_head; \
- if (m) { \
- if (((ifq)->ifq_head = (m)->usb2_nextpkt) == NULL) { \
- (ifq)->ifq_tail = NULL; \
- } \
- (m)->usb2_nextpkt = NULL; \
- (ifq)->ifq_len--; \
- } \
- } while (0)
-
-#define USB_IF_PREPEND(ifq, m) do { \
- (m)->usb2_nextpkt = (ifq)->ifq_head; \
- if ((ifq)->ifq_tail == NULL) { \
- (ifq)->ifq_tail = (m); \
- } \
- (ifq)->ifq_head = (m); \
- (ifq)->ifq_len++; \
- } while (0)
-
-#define USB_IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
-#define USB_IF_QLEN(ifq) ((ifq)->ifq_len)
-#define USB_IF_POLL(ifq, m) ((m) = (ifq)->ifq_head)
-
-#define USB_MBUF_RESET(m) do { \
- (m)->cur_data_ptr = (m)->min_data_ptr; \
- (m)->cur_data_len = (m)->max_data_len; \
- (m)->last_packet = 0; \
- } while (0)
-
-/* prototypes */
-void *usb2_alloc_mbufs(struct malloc_type *type, struct usb2_ifqueue *ifq,
- uint32_t block_size, uint16_t nblocks);
-
-#endif /* _USB2_MBUF_H_ */
diff --git a/sys/dev/usb2/core/usb2_msctest.c b/sys/dev/usb2/core/usb2_msctest.c
deleted file mode 100644
index fbd7dbc..0000000
--- a/sys/dev/usb2/core/usb2_msctest.c
+++ /dev/null
@@ -1,578 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-/*
- * The following file contains code that will detect USB autoinstall
- * disks.
- *
- * TODO: Potentially we could add code to automatically detect USB
- * mass storage quirks for not supported SCSI commands!
- */
-
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_msctest.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_lookup.h>
-
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-enum {
- ST_COMMAND,
- ST_DATA_RD,
- ST_DATA_RD_CS,
- ST_DATA_WR,
- ST_DATA_WR_CS,
- ST_STATUS,
- ST_MAX,
-};
-
-enum {
- DIR_IN,
- DIR_OUT,
- DIR_NONE,
-};
-
-#define BULK_SIZE 64 /* dummy */
-
-/* Command Block Wrapper */
-struct bbb_cbw {
- 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;
-
-/* Command Status Wrapper */
-struct bbb_csw {
- uDWord dCSWSignature;
-#define CSWSIGNATURE 0x53425355
- uDWord dCSWTag;
- uDWord dCSWDataResidue;
- uByte bCSWStatus;
-#define CSWSTATUS_GOOD 0x0
-#define CSWSTATUS_FAILED 0x1
-#define CSWSTATUS_PHASE 0x2
-} __packed;
-
-struct bbb_transfer {
- struct mtx mtx;
- struct cv cv;
- struct bbb_cbw cbw;
- struct bbb_csw csw;
-
- struct usb2_xfer *xfer[ST_MAX];
-
- uint8_t *data_ptr;
-
- uint32_t data_len; /* bytes */
- uint32_t data_rem; /* bytes */
- uint32_t data_timeout; /* ms */
- uint32_t actlen; /* bytes */
-
- uint8_t cmd_len; /* bytes */
- uint8_t dir;
- uint8_t lun;
- uint8_t state;
- uint8_t error;
- uint8_t status_try;
-
- uint8_t buffer[256];
-};
-
-static usb2_callback_t bbb_command_callback;
-static usb2_callback_t bbb_data_read_callback;
-static usb2_callback_t bbb_data_rd_cs_callback;
-static usb2_callback_t bbb_data_write_callback;
-static usb2_callback_t bbb_data_wr_cs_callback;
-static usb2_callback_t bbb_status_callback;
-
-static const struct usb2_config bbb_config[ST_MAX] = {
-
- [ST_COMMAND] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = sizeof(struct bbb_cbw),
- .mh.flags = {},
- .mh.callback = &bbb_command_callback,
- .mh.timeout = 4 * USB_MS_HZ, /* 4 seconds */
- },
-
- [ST_DATA_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = BULK_SIZE,
- .mh.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
- .mh.callback = &bbb_data_read_callback,
- .mh.timeout = 4 * USB_MS_HZ, /* 4 seconds */
- },
-
- [ST_DATA_RD_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &bbb_data_rd_cs_callback,
- .mh.timeout = 1 * USB_MS_HZ, /* 1 second */
- },
-
- [ST_DATA_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = BULK_SIZE,
- .mh.flags = {.proxy_buffer = 1,},
- .mh.callback = &bbb_data_write_callback,
- .mh.timeout = 4 * USB_MS_HZ, /* 4 seconds */
- },
-
- [ST_DATA_WR_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &bbb_data_wr_cs_callback,
- .mh.timeout = 1 * USB_MS_HZ, /* 1 second */
- },
-
- [ST_STATUS] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = sizeof(struct bbb_csw),
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &bbb_status_callback,
- .mh.timeout = 1 * USB_MS_HZ, /* 1 second */
- },
-};
-
-static void
-bbb_done(struct bbb_transfer *sc, uint8_t error)
-{
- struct usb2_xfer *xfer;
-
- xfer = sc->xfer[sc->state];
-
- /* verify the error code */
-
- if (error) {
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
- error = 1;
- break;
- default:
- error = 2;
- break;
- }
- }
- sc->error = error;
- sc->state = ST_COMMAND;
- sc->status_try = 1;
- usb2_cv_signal(&sc->cv);
-}
-
-static void
-bbb_transfer_start(struct bbb_transfer *sc, uint8_t xfer_index)
-{
- sc->state = xfer_index;
- usb2_transfer_start(sc->xfer[xfer_index]);
-}
-
-static void
-bbb_data_clear_stall_callback(struct usb2_xfer *xfer,
- uint8_t next_xfer, uint8_t stall_xfer)
-{
- struct bbb_transfer *sc = xfer->priv_sc;
-
- if (usb2_clear_stall_callback(xfer, sc->xfer[stall_xfer])) {
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
- bbb_transfer_start(sc, next_xfer);
- break;
- default:
- bbb_done(sc, 1);
- break;
- }
- }
-}
-
-static void
-bbb_command_callback(struct usb2_xfer *xfer)
-{
- struct bbb_transfer *sc = xfer->priv_sc;
- uint32_t tag;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- bbb_transfer_start
- (sc, ((sc->dir == DIR_IN) ? ST_DATA_RD :
- (sc->dir == DIR_OUT) ? ST_DATA_WR :
- ST_STATUS));
- break;
-
- case USB_ST_SETUP:
- sc->status_try = 0;
- tag = UGETDW(sc->cbw.dCBWTag) + 1;
- USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE);
- USETDW(sc->cbw.dCBWTag, tag);
- USETDW(sc->cbw.dCBWDataTransferLength, sc->data_len);
- sc->cbw.bCBWFlags = ((sc->dir == DIR_IN) ? CBWFLAGS_IN : CBWFLAGS_OUT);
- sc->cbw.bCBWLUN = sc->lun;
- sc->cbw.bCDBLength = sc->cmd_len;
- if (sc->cbw.bCDBLength > sizeof(sc->cbw.CBWCDB)) {
- sc->cbw.bCDBLength = sizeof(sc->cbw.CBWCDB);
- DPRINTFN(0, "Truncating long command!\n");
- }
- xfer->frlengths[0] = sizeof(sc->cbw);
-
- usb2_set_frame_data(xfer, &sc->cbw, 0);
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- bbb_done(sc, 1);
- break;
- }
-}
-
-static void
-bbb_data_read_callback(struct usb2_xfer *xfer)
-{
- struct bbb_transfer *sc = xfer->priv_sc;
- uint32_t max_bulk = xfer->max_data_length;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- sc->data_rem -= xfer->actlen;
- sc->data_ptr += xfer->actlen;
- sc->actlen += xfer->actlen;
-
- if (xfer->actlen < xfer->sumlen) {
- /* short transfer */
- sc->data_rem = 0;
- }
- case USB_ST_SETUP:
- DPRINTF("max_bulk=%d, data_rem=%d\n",
- max_bulk, sc->data_rem);
-
- if (sc->data_rem == 0) {
- bbb_transfer_start(sc, ST_STATUS);
- break;
- }
- if (max_bulk > sc->data_rem) {
- max_bulk = sc->data_rem;
- }
- xfer->timeout = sc->data_timeout;
- xfer->frlengths[0] = max_bulk;
-
- usb2_set_frame_data(xfer, sc->data_ptr, 0);
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- bbb_done(sc, 1);
- } else {
- bbb_transfer_start(sc, ST_DATA_RD_CS);
- }
- break;
- }
-}
-
-static void
-bbb_data_rd_cs_callback(struct usb2_xfer *xfer)
-{
- bbb_data_clear_stall_callback(xfer, ST_STATUS,
- ST_DATA_RD);
-}
-
-static void
-bbb_data_write_callback(struct usb2_xfer *xfer)
-{
- struct bbb_transfer *sc = xfer->priv_sc;
- uint32_t max_bulk = xfer->max_data_length;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- sc->data_rem -= xfer->actlen;
- sc->data_ptr += xfer->actlen;
- sc->actlen += xfer->actlen;
-
- if (xfer->actlen < xfer->sumlen) {
- /* short transfer */
- sc->data_rem = 0;
- }
- case USB_ST_SETUP:
- DPRINTF("max_bulk=%d, data_rem=%d\n",
- max_bulk, sc->data_rem);
-
- if (sc->data_rem == 0) {
- bbb_transfer_start(sc, ST_STATUS);
- return;
- }
- if (max_bulk > sc->data_rem) {
- max_bulk = sc->data_rem;
- }
- xfer->timeout = sc->data_timeout;
- xfer->frlengths[0] = max_bulk;
-
- usb2_set_frame_data(xfer, sc->data_ptr, 0);
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- bbb_done(sc, 1);
- } else {
- bbb_transfer_start(sc, ST_DATA_WR_CS);
- }
- return;
-
- }
-}
-
-static void
-bbb_data_wr_cs_callback(struct usb2_xfer *xfer)
-{
- bbb_data_clear_stall_callback(xfer, ST_STATUS,
- ST_DATA_WR);
-}
-
-static void
-bbb_status_callback(struct usb2_xfer *xfer)
-{
- struct bbb_transfer *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- /* very simple status check */
-
- if (xfer->actlen < sizeof(sc->csw)) {
- bbb_done(sc, 1);/* error */
- } else if (sc->csw.bCSWStatus == CSWSTATUS_GOOD) {
- bbb_done(sc, 0);/* success */
- } else {
- bbb_done(sc, 1);/* error */
- }
- break;
-
- case USB_ST_SETUP:
- xfer->frlengths[0] = sizeof(sc->csw);
-
- usb2_set_frame_data(xfer, &sc->csw, 0);
- usb2_start_hardware(xfer);
- break;
-
- default:
- DPRINTFN(0, "Failed to read CSW: %s, try %d\n",
- usb2_errstr(xfer->error), sc->status_try);
-
- if ((xfer->error == USB_ERR_CANCELLED) ||
- (sc->status_try)) {
- bbb_done(sc, 1);
- } else {
- sc->status_try = 1;
- bbb_transfer_start(sc, ST_DATA_RD_CS);
- }
- break;
- }
-}
-
-/*------------------------------------------------------------------------*
- * bbb_command_start - execute a SCSI command synchronously
- *
- * Return values
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun,
- void *data_ptr, uint32_t data_len, uint8_t cmd_len,
- uint32_t data_timeout)
-{
- sc->lun = lun;
- sc->dir = data_len ? dir : DIR_NONE;
- sc->data_ptr = data_ptr;
- sc->data_len = data_len;
- sc->data_rem = data_len;
- sc->data_timeout = (data_timeout + USB_MS_HZ);
- sc->actlen = 0;
- sc->cmd_len = cmd_len;
-
- usb2_transfer_start(sc->xfer[sc->state]);
-
- while (usb2_transfer_pending(sc->xfer[sc->state])) {
- usb2_cv_wait(&sc->cv, &sc->mtx);
- }
- return (sc->error);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_test_autoinstall
- *
- * Return values:
- * 0: This interface is an auto install disk (CD-ROM)
- * Else: Not an auto install disk.
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_test_autoinstall(struct usb2_device *udev, uint8_t iface_index,
- uint8_t do_eject)
-{
- struct usb2_interface *iface;
- struct usb2_interface_descriptor *id;
- usb2_error_t err;
- uint8_t timeout;
- uint8_t sid_type;
- struct bbb_transfer *sc;
-
- if (udev == NULL) {
- return (USB_ERR_INVAL);
- }
- iface = usb2_get_iface(udev, iface_index);
- if (iface == NULL) {
- return (USB_ERR_INVAL);
- }
- id = iface->idesc;
- if (id == NULL) {
- return (USB_ERR_INVAL);
- }
- if (id->bInterfaceClass != UICLASS_MASS) {
- return (USB_ERR_INVAL);
- }
- switch (id->bInterfaceSubClass) {
- case UISUBCLASS_SCSI:
- case UISUBCLASS_UFI:
- break;
- default:
- return (USB_ERR_INVAL);
- }
-
- switch (id->bInterfaceProtocol) {
- case UIPROTO_MASS_BBB_OLD:
- case UIPROTO_MASS_BBB:
- break;
- default:
- return (USB_ERR_INVAL);
- }
-
- sc = malloc(sizeof(*sc), M_USB, M_WAITOK | M_ZERO);
- if (sc == NULL) {
- return (USB_ERR_NOMEM);
- }
- mtx_init(&sc->mtx, "USB autoinstall", NULL, MTX_DEF);
- usb2_cv_init(&sc->cv, "WBBB");
-
- err = usb2_transfer_setup(udev,
- &iface_index, sc->xfer, bbb_config,
- ST_MAX, sc, &sc->mtx);
-
- if (err) {
- goto done;
- }
- mtx_lock(&sc->mtx);
-
- timeout = 4; /* tries */
-
-repeat_inquiry:
-
- sc->cbw.CBWCDB[0] = 0x12; /* INQUIRY */
- sc->cbw.CBWCDB[1] = 0;
- sc->cbw.CBWCDB[2] = 0;
- sc->cbw.CBWCDB[3] = 0;
- sc->cbw.CBWCDB[4] = 0x24; /* length */
- sc->cbw.CBWCDB[5] = 0;
- err = bbb_command_start(sc, DIR_IN, 0,
- sc->buffer, 0x24, 6, USB_MS_HZ);
-
- if ((sc->actlen != 0) && (err == 0)) {
- sid_type = sc->buffer[0] & 0x1F;
- if (sid_type == 0x05) {
- /* CD-ROM */
- if (do_eject) {
- /* 0: opcode: SCSI START/STOP */
- sc->cbw.CBWCDB[0] = 0x1b;
- /* 1: byte2: Not immediate */
- sc->cbw.CBWCDB[1] = 0x00;
- /* 2..3: reserved */
- sc->cbw.CBWCDB[2] = 0x00;
- sc->cbw.CBWCDB[3] = 0x00;
- /* 4: Load/Eject command */
- sc->cbw.CBWCDB[4] = 0x02;
- /* 5: control */
- sc->cbw.CBWCDB[5] = 0x00;
- err = bbb_command_start(sc, DIR_OUT, 0,
- NULL, 0, 6, USB_MS_HZ);
-
- DPRINTFN(0, "Eject CD command "
- "status: %s\n", usb2_errstr(err));
- }
- err = 0;
- goto done;
- }
- } else if ((err != 2) && --timeout) {
- usb2_pause_mtx(&sc->mtx, hz);
- goto repeat_inquiry;
- }
- err = USB_ERR_INVAL;
- goto done;
-
-done:
- mtx_unlock(&sc->mtx);
- usb2_transfer_unsetup(sc->xfer, ST_MAX);
- mtx_destroy(&sc->mtx);
- usb2_cv_destroy(&sc->cv);
- free(sc, M_USB);
- return (err);
-}
diff --git a/sys/dev/usb2/core/usb2_msctest.h b/sys/dev/usb2/core/usb2_msctest.h
deleted file mode 100644
index 5bf64d0..0000000
--- a/sys/dev/usb2/core/usb2_msctest.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_MSCTEST_H_
-#define _USB2_MSCTEST_H_
-
-usb2_error_t usb2_test_autoinstall(struct usb2_device *udev,
- uint8_t iface_index, uint8_t do_eject);
-
-#endif /* _USB2_MSCTEST_H_ */
diff --git a/sys/dev/usb2/core/usb2_parse.c b/sys/dev/usb2/core/usb2_parse.c
deleted file mode 100644
index 1f722b5..0000000
--- a/sys/dev/usb2/core/usb2_parse.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_parse.h>
-
-/*------------------------------------------------------------------------*
- * usb2_desc_foreach
- *
- * This function is the safe way to iterate across the USB config
- * descriptor. It contains several checks against invalid
- * descriptors. If the "desc" argument passed to this function is
- * "NULL" the first descriptor, if any, will be returned.
- *
- * Return values:
- * NULL: End of descriptors
- * Else: Next descriptor after "desc"
- *------------------------------------------------------------------------*/
-struct usb2_descriptor *
-usb2_desc_foreach(struct usb2_config_descriptor *cd,
- struct usb2_descriptor *_desc)
-{
- uint8_t *desc_next;
- uint8_t *start;
- uint8_t *end;
- uint8_t *desc;
-
- /* be NULL safe */
- if (cd == NULL)
- return (NULL);
-
- /* We assume that the "wTotalLength" has been checked. */
- start = (uint8_t *)cd;
- end = start + UGETW(cd->wTotalLength);
- desc = (uint8_t *)_desc;
-
- /* Get start of next USB descriptor. */
- if (desc == NULL)
- desc = start;
- else
- desc = desc + desc[0];
-
- /* Check that the next USB descriptor is within the range. */
- if ((desc < start) || (desc >= end))
- return (NULL); /* out of range, or EOD */
-
- /* Check that the second next USB descriptor is within range. */
- desc_next = desc + desc[0];
- if ((desc_next < start) || (desc_next > end))
- return (NULL); /* out of range */
-
- /* Check minimum descriptor length. */
- if (desc[0] < 3)
- return (NULL); /* too short descriptor */
-
- /* Return start of next descriptor. */
- return ((struct usb2_descriptor *)desc);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_find_idesc
- *
- * This function will return the interface descriptor, if any, that
- * has index "iface_index" and alternate index "alt_index".
- *
- * Return values:
- * NULL: End of descriptors
- * Else: A valid interface descriptor
- *------------------------------------------------------------------------*/
-struct usb2_interface_descriptor *
-usb2_find_idesc(struct usb2_config_descriptor *cd,
- uint8_t iface_index, uint8_t alt_index)
-{
- struct usb2_descriptor *desc = NULL;
- struct usb2_interface_descriptor *id;
- uint8_t curidx = 0;
- uint8_t lastidx = 0;
- uint8_t curaidx = 0;
- uint8_t first = 1;
-
- while ((desc = usb2_desc_foreach(cd, desc))) {
- if ((desc->bDescriptorType == UDESC_INTERFACE) &&
- (desc->bLength >= sizeof(*id))) {
- id = (void *)desc;
-
- if (first) {
- first = 0;
- lastidx = id->bInterfaceNumber;
-
- } else if (id->bInterfaceNumber != lastidx) {
-
- lastidx = id->bInterfaceNumber;
- curidx++;
- curaidx = 0;
-
- } else {
- curaidx++;
- }
-
- if ((iface_index == curidx) && (alt_index == curaidx)) {
- return (id);
- }
- }
- }
- return (NULL);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_find_edesc
- *
- * This function will return the endpoint descriptor for the passed
- * interface index, alternate index and endpoint index.
- *
- * Return values:
- * NULL: End of descriptors
- * Else: A valid endpoint descriptor
- *------------------------------------------------------------------------*/
-struct usb2_endpoint_descriptor *
-usb2_find_edesc(struct usb2_config_descriptor *cd,
- uint8_t iface_index, uint8_t alt_index, uint8_t ep_index)
-{
- struct usb2_descriptor *desc = NULL;
- struct usb2_interface_descriptor *d;
- uint8_t curidx = 0;
-
- d = usb2_find_idesc(cd, iface_index, alt_index);
- if (d == NULL)
- return (NULL);
-
- if (ep_index >= d->bNumEndpoints) /* quick exit */
- return (NULL);
-
- desc = ((void *)d);
-
- while ((desc = usb2_desc_foreach(cd, desc))) {
- if (desc->bDescriptorType == UDESC_INTERFACE) {
- break;
- }
- if (desc->bDescriptorType == UDESC_ENDPOINT) {
- if (curidx == ep_index) {
- if (desc->bLength <
- sizeof(struct usb2_endpoint_descriptor)) {
- /* endpoint index is invalid */
- break;
- }
- return ((void *)desc);
- }
- curidx++;
- }
- }
- return (NULL);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_get_no_endpoints
- *
- * This function will count the total number of endpoints available.
- *------------------------------------------------------------------------*/
-uint16_t
-usb2_get_no_endpoints(struct usb2_config_descriptor *cd)
-{
- struct usb2_descriptor *desc = NULL;
- uint16_t count = 0;
-
- while ((desc = usb2_desc_foreach(cd, desc))) {
- if (desc->bDescriptorType == UDESC_ENDPOINT) {
- count++;
- }
- }
- return (count);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_get_no_alts
- *
- * Return value:
- * Number of alternate settings for the given "ifaceno".
- *
- * NOTE: The returned can be larger than the actual number of
- * alternate settings.
- *------------------------------------------------------------------------*/
-uint16_t
-usb2_get_no_alts(struct usb2_config_descriptor *cd, uint8_t ifaceno)
-{
- struct usb2_descriptor *desc = NULL;
- struct usb2_interface_descriptor *id;
- uint16_t n = 0;
-
- while ((desc = usb2_desc_foreach(cd, desc))) {
- if ((desc->bDescriptorType == UDESC_INTERFACE) &&
- (desc->bLength >= sizeof(*id))) {
- id = (void *)desc;
- if (id->bInterfaceNumber == ifaceno) {
- n++;
- }
- }
- }
- return (n);
-}
diff --git a/sys/dev/usb2/core/usb2_parse.h b/sys/dev/usb2/core/usb2_parse.h
deleted file mode 100644
index a9e6509..0000000
--- a/sys/dev/usb2/core/usb2_parse.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_PARSE_H_
-#define _USB2_PARSE_H_
-
-struct usb2_descriptor *usb2_desc_foreach(struct usb2_config_descriptor *cd,
- struct usb2_descriptor *desc);
-struct usb2_interface_descriptor *usb2_find_idesc(
- struct usb2_config_descriptor *cd, uint8_t iface_index,
- uint8_t alt_index);
-struct usb2_endpoint_descriptor *usb2_find_edesc(
- struct usb2_config_descriptor *cd, uint8_t iface_index,
- uint8_t alt_index, uint8_t ep_index);
-uint16_t usb2_get_no_endpoints(struct usb2_config_descriptor *cd);
-uint16_t usb2_get_no_alts(struct usb2_config_descriptor *cd, uint8_t ifaceno);
-
-#endif /* _USB2_PARSE_H_ */
diff --git a/sys/dev/usb2/core/usb2_process.c b/sys/dev/usb2/core/usb2_process.c
deleted file mode 100644
index 4c50695..0000000
--- a/sys/dev/usb2/core/usb2_process.c
+++ /dev/null
@@ -1,426 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#define USB_DEBUG_VAR usb2_proc_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <sys/proc.h>
-#include <sys/kthread.h>
-#include <sys/sched.h>
-
-#if (__FreeBSD_version < 700000)
-#define thread_lock(td) mtx_lock_spin(&sched_lock)
-#define thread_unlock(td) mtx_unlock_spin(&sched_lock)
-#endif
-
-#if (__FreeBSD_version >= 800000)
-#define USB_THREAD_CREATE(f, s, p, ...) \
- kproc_create((f), (s), (p), RFHIGHPID, 0, __VA_ARGS__)
-#define USB_THREAD_SUSPEND(p) kproc_suspend(p,0)
-#define USB_THREAD_EXIT(err) kproc_exit(err)
-#else
-#define USB_THREAD_CREATE(f, s, p, ...) \
- kthread_create((f), (s), (p), RFHIGHPID, 0, __VA_ARGS__)
-#define USB_THREAD_SUSPEND(p) kthread_suspend(p,0)
-#define USB_THREAD_EXIT(err) kthread_exit(err)
-#endif
-
-#if USB_DEBUG
-static int usb2_proc_debug;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, proc, CTLFLAG_RW, 0, "USB process");
-SYSCTL_INT(_hw_usb2_proc, OID_AUTO, debug, CTLFLAG_RW, &usb2_proc_debug, 0,
- "Debug level");
-#endif
-
-/*------------------------------------------------------------------------*
- * usb2_process
- *
- * This function is the USB process dispatcher.
- *------------------------------------------------------------------------*/
-static void
-usb2_process(void *arg)
-{
- struct usb2_process *up = arg;
- struct usb2_proc_msg *pm;
- struct thread *td;
-
- /* adjust priority */
- td = curthread;
- thread_lock(td);
- sched_prio(td, up->up_prio);
- thread_unlock(td);
-
- mtx_lock(up->up_mtx);
-
- up->up_curtd = td;
-
- while (1) {
-
- if (up->up_gone)
- break;
-
- /*
- * NOTE to reimplementors: dequeueing a command from the
- * "used" queue and executing it must be atomic, with regard
- * to the "up_mtx" mutex. That means any attempt to queue a
- * command by another thread must be blocked until either:
- *
- * 1) the command sleeps
- *
- * 2) the command returns
- *
- * Here is a practical example that shows how this helps
- * solving a problem:
- *
- * Assume that you want to set the baud rate on a USB serial
- * device. During the programming of the device you don't
- * want to receive nor transmit any data, because it will be
- * garbage most likely anyway. The programming of our USB
- * device takes 20 milliseconds and it needs to call
- * functions that sleep.
- *
- * Non-working solution: Before we queue the programming
- * command, we stop transmission and reception of data. Then
- * we queue a programming command. At the end of the
- * programming command we enable transmission and reception
- * of data.
- *
- * Problem: If a second programming command is queued while the
- * first one is sleeping, we end up enabling transmission
- * and reception of data too early.
- *
- * Working solution: Before we queue the programming command,
- * we stop transmission and reception of data. Then we queue
- * a programming command. Then we queue a second command
- * that only enables transmission and reception of data.
- *
- * Why it works: If a second programming command is queued
- * while the first one is sleeping, then the queueing of a
- * second command to enable the data transfers, will cause
- * the previous one, which is still on the queue, to be
- * removed from the queue, and re-inserted after the last
- * baud rate programming command, which then gives the
- * desired result.
- */
- pm = TAILQ_FIRST(&up->up_qhead);
-
- if (pm) {
- DPRINTF("Message pm=%p, cb=%p (enter)\n",
- pm, pm->pm_callback);
-
- (pm->pm_callback) (pm);
-
- if (pm == TAILQ_FIRST(&up->up_qhead)) {
- /* nothing changed */
- TAILQ_REMOVE(&up->up_qhead, pm, pm_qentry);
- pm->pm_qentry.tqe_prev = NULL;
- }
- DPRINTF("Message pm=%p (leave)\n", pm);
-
- continue;
- }
- /* end if messages - check if anyone is waiting for sync */
- if (up->up_dsleep) {
- up->up_dsleep = 0;
- usb2_cv_broadcast(&up->up_drain);
- }
- up->up_msleep = 1;
- usb2_cv_wait(&up->up_cv, up->up_mtx);
- }
-
- up->up_ptr = NULL;
- usb2_cv_signal(&up->up_cv);
- mtx_unlock(up->up_mtx);
-
- USB_THREAD_EXIT(0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_proc_create
- *
- * This function will create a process using the given "prio" that can
- * execute callbacks. The mutex pointed to by "p_mtx" will be applied
- * before calling the callbacks and released after that the callback
- * has returned. The structure pointed to by "up" is assumed to be
- * zeroed before this function is called.
- *
- * Return values:
- * 0: success
- * Else: failure
- *------------------------------------------------------------------------*/
-int
-usb2_proc_create(struct usb2_process *up, struct mtx *p_mtx,
- const char *pmesg, uint8_t prio)
-{
- up->up_mtx = p_mtx;
- up->up_prio = prio;
-
- TAILQ_INIT(&up->up_qhead);
-
- usb2_cv_init(&up->up_cv, "wmsg");
- usb2_cv_init(&up->up_drain, "dmsg");
-
- if (USB_THREAD_CREATE(&usb2_process, up,
- &up->up_ptr, pmesg)) {
- DPRINTFN(0, "Unable to create USB process.");
- up->up_ptr = NULL;
- goto error;
- }
- return (0);
-
-error:
- usb2_proc_free(up);
- return (ENOMEM);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_proc_free
- *
- * NOTE: If the structure pointed to by "up" is all zero, this
- * function does nothing.
- *
- * NOTE: Messages that are pending on the process queue will not be
- * removed nor called.
- *------------------------------------------------------------------------*/
-void
-usb2_proc_free(struct usb2_process *up)
-{
- /* check if not initialised */
- if (up->up_mtx == NULL)
- return;
-
- usb2_proc_drain(up);
-
- usb2_cv_destroy(&up->up_cv);
- usb2_cv_destroy(&up->up_drain);
-
- /* make sure that we do not enter here again */
- up->up_mtx = NULL;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_proc_msignal
- *
- * This function will queue one of the passed USB process messages on
- * the USB process queue. The first message that is not already queued
- * will get queued. If both messages are already queued the one queued
- * last will be removed from the queue and queued in the end. The USB
- * process mutex must be locked when calling this function. This
- * function exploits the fact that a process can only do one callback
- * at a time. The message that was queued is returned.
- *------------------------------------------------------------------------*/
-void *
-usb2_proc_msignal(struct usb2_process *up, void *_pm0, void *_pm1)
-{
- struct usb2_proc_msg *pm0 = _pm0;
- struct usb2_proc_msg *pm1 = _pm1;
- struct usb2_proc_msg *pm2;
- uint32_t d;
- uint8_t t;
-
- /* check if gone, return dummy value */
- if (up->up_gone)
- return (_pm0);
-
- mtx_assert(up->up_mtx, MA_OWNED);
-
- t = 0;
-
- if (pm0->pm_qentry.tqe_prev) {
- t |= 1;
- }
- if (pm1->pm_qentry.tqe_prev) {
- t |= 2;
- }
- if (t == 0) {
- /*
- * No entries are queued. Queue "pm0" and use the existing
- * message number.
- */
- pm2 = pm0;
- } else if (t == 1) {
- /* Check if we need to increment the message number. */
- if (pm0->pm_num == up->up_msg_num) {
- up->up_msg_num++;
- }
- pm2 = pm1;
- } else if (t == 2) {
- /* Check if we need to increment the message number. */
- if (pm1->pm_num == up->up_msg_num) {
- up->up_msg_num++;
- }
- pm2 = pm0;
- } else if (t == 3) {
- /*
- * Both entries are queued. Re-queue the entry closest to
- * the end.
- */
- d = (pm1->pm_num - pm0->pm_num);
-
- /* Check sign after subtraction */
- if (d & 0x80000000) {
- pm2 = pm0;
- } else {
- pm2 = pm1;
- }
-
- TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry);
- } else {
- pm2 = NULL; /* panic - should not happen */
- }
-
- DPRINTF(" t=%u, num=%u\n", t, up->up_msg_num);
-
- /* Put message last on queue */
-
- pm2->pm_num = up->up_msg_num;
- TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry);
-
- /* Check if we need to wakeup the USB process. */
-
- if (up->up_msleep) {
- up->up_msleep = 0; /* save "cv_signal()" calls */
- usb2_cv_signal(&up->up_cv);
- }
- return (pm2);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_proc_is_gone
- *
- * Return values:
- * 0: USB process is running
- * Else: USB process is tearing down
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_proc_is_gone(struct usb2_process *up)
-{
- if (up->up_gone)
- return (1);
-
- mtx_assert(up->up_mtx, MA_OWNED);
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_proc_mwait
- *
- * This function will return when the USB process message pointed to
- * by "pm" is no longer on a queue. This function must be called
- * having "up->up_mtx" locked.
- *------------------------------------------------------------------------*/
-void
-usb2_proc_mwait(struct usb2_process *up, void *_pm0, void *_pm1)
-{
- struct usb2_proc_msg *pm0 = _pm0;
- struct usb2_proc_msg *pm1 = _pm1;
-
- /* check if gone */
- if (up->up_gone)
- return;
-
- mtx_assert(up->up_mtx, MA_OWNED);
-
- if (up->up_curtd == curthread) {
- /* Just remove the messages from the queue. */
- if (pm0->pm_qentry.tqe_prev) {
- TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry);
- pm0->pm_qentry.tqe_prev = NULL;
- }
- if (pm1->pm_qentry.tqe_prev) {
- TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry);
- pm1->pm_qentry.tqe_prev = NULL;
- }
- } else
- while (pm0->pm_qentry.tqe_prev ||
- pm1->pm_qentry.tqe_prev) {
- /* check if config thread is gone */
- if (up->up_gone)
- break;
- up->up_dsleep = 1;
- usb2_cv_wait(&up->up_drain, up->up_mtx);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_proc_drain
- *
- * This function will tear down an USB process, waiting for the
- * currently executing command to return.
- *
- * NOTE: If the structure pointed to by "up" is all zero,
- * this function does nothing.
- *------------------------------------------------------------------------*/
-void
-usb2_proc_drain(struct usb2_process *up)
-{
- /* check if not initialised */
- if (up->up_mtx == NULL)
- return;
- /* handle special case with Giant */
- if (up->up_mtx != &Giant)
- mtx_assert(up->up_mtx, MA_NOTOWNED);
-
- mtx_lock(up->up_mtx);
-
- /* Set the gone flag */
-
- up->up_gone = 1;
-
- while (up->up_ptr) {
-
- /* Check if we need to wakeup the USB process */
-
- if (up->up_msleep || up->up_csleep) {
- up->up_msleep = 0;
- up->up_csleep = 0;
- usb2_cv_signal(&up->up_cv);
- }
- /* Check if we are still cold booted */
-
- if (cold) {
- USB_THREAD_SUSPEND(up->up_ptr);
- printf("WARNING: A USB process has "
- "been left suspended!\n");
- break;
- }
- usb2_cv_wait(&up->up_cv, up->up_mtx);
- }
- /* Check if someone is waiting - should not happen */
-
- if (up->up_dsleep) {
- up->up_dsleep = 0;
- usb2_cv_broadcast(&up->up_drain);
- DPRINTF("WARNING: Someone is waiting "
- "for USB process drain!\n");
- }
- mtx_unlock(up->up_mtx);
-}
diff --git a/sys/dev/usb2/core/usb2_process.h b/sys/dev/usb2/core/usb2_process.h
deleted file mode 100644
index 756b929..0000000
--- a/sys/dev/usb2/core/usb2_process.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_PROCESS_H_
-#define _USB2_PROCESS_H_
-
-#include <sys/priority.h>
-
-/* defines */
-#define USB_PRI_HIGH PI_NET
-#define USB_PRI_MED PI_DISK
-
-#define USB_PROC_WAIT_TIMEOUT 2
-#define USB_PROC_WAIT_DRAIN 1
-#define USB_PROC_WAIT_NORMAL 0
-
-/* structure prototypes */
-
-struct usb2_proc_msg;
-
-/* typedefs */
-
-typedef void (usb2_proc_callback_t)(struct usb2_proc_msg *hdr);
-
-/*
- * The following structure defines the USB process message header.
- */
-struct usb2_proc_msg {
- TAILQ_ENTRY(usb2_proc_msg) pm_qentry;
- usb2_proc_callback_t *pm_callback;
- uint32_t pm_num;
-};
-
-/*
- * The following structure defines the USB process.
- */
-struct usb2_process {
- TAILQ_HEAD(, usb2_proc_msg) up_qhead;
- struct cv up_cv;
- struct cv up_drain;
-
- struct proc *up_ptr;
- struct thread *up_curtd;
- struct mtx *up_mtx;
-
- uint32_t up_msg_num;
-
- uint8_t up_prio;
- uint8_t up_gone;
- uint8_t up_msleep;
- uint8_t up_csleep;
- uint8_t up_dsleep;
-};
-
-/* prototypes */
-
-uint8_t usb2_proc_is_gone(struct usb2_process *up);
-int usb2_proc_create(struct usb2_process *up, struct mtx *p_mtx,
- const char *pmesg, uint8_t prio);
-void usb2_proc_drain(struct usb2_process *up);
-void usb2_proc_mwait(struct usb2_process *up, void *pm0, void *pm1);
-void usb2_proc_free(struct usb2_process *up);
-void *usb2_proc_msignal(struct usb2_process *up, void *pm0, void *pm1);
-
-#endif /* _USB2_PROCESS_H_ */
diff --git a/sys/dev/usb2/core/usb2_request.c b/sys/dev/usb2/core/usb2_request.c
deleted file mode 100644
index 75a14ff..0000000
--- a/sys/dev/usb2/core/usb2_request.c
+++ /dev/null
@@ -1,1486 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
- * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-#include <dev/usb2/include/usb2_hid.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-#include <sys/ctype.h>
-
-#if USB_DEBUG
-static int usb2_pr_poll_delay = USB_PORT_RESET_DELAY;
-static int usb2_pr_recovery_delay = USB_PORT_RESET_RECOVERY;
-static int usb2_ss_delay = 0;
-
-SYSCTL_INT(_hw_usb2, OID_AUTO, pr_poll_delay, CTLFLAG_RW,
- &usb2_pr_poll_delay, 0, "USB port reset poll delay in ms");
-SYSCTL_INT(_hw_usb2, OID_AUTO, pr_recovery_delay, CTLFLAG_RW,
- &usb2_pr_recovery_delay, 0, "USB port reset recovery delay in ms");
-SYSCTL_INT(_hw_usb2, OID_AUTO, ss_delay, CTLFLAG_RW,
- &usb2_ss_delay, 0, "USB status stage delay in ms");
-#endif
-
-/*------------------------------------------------------------------------*
- * usb2_do_request_callback
- *
- * This function is the USB callback for generic USB Host control
- * transfers.
- *------------------------------------------------------------------------*/
-void
-usb2_do_request_callback(struct usb2_xfer *xfer)
-{
- ; /* workaround for a bug in "indent" */
-
- DPRINTF("st=%u\n", USB_GET_STATE(xfer));
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- usb2_start_hardware(xfer);
- break;
- default:
- usb2_cv_signal(xfer->xroot->udev->default_cv);
- break;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_do_clear_stall_callback
- *
- * This function is the USB callback for generic clear stall requests.
- *------------------------------------------------------------------------*/
-void
-usb2_do_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct usb2_device_request req;
- struct usb2_device *udev;
- struct usb2_pipe *pipe;
- struct usb2_pipe *pipe_end;
- struct usb2_pipe *pipe_first;
- uint8_t to = USB_EP_MAX;
-
- udev = xfer->xroot->udev;
-
- USB_BUS_LOCK(udev->bus);
-
- /* round robin pipe clear stall */
-
- pipe = udev->pipe_curr;
- pipe_end = udev->pipes + USB_EP_MAX;
- pipe_first = udev->pipes;
- if (pipe == NULL) {
- pipe = pipe_first;
- }
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- if (pipe->edesc &&
- pipe->is_stalled) {
- pipe->toggle_next = 0;
- pipe->is_stalled = 0;
- /* start up the current or next transfer, if any */
- usb2_command_wrapper(&pipe->pipe_q,
- pipe->pipe_q.curr);
- }
- pipe++;
-
- case USB_ST_SETUP:
-tr_setup:
- if (pipe == pipe_end) {
- pipe = pipe_first;
- }
- if (pipe->edesc &&
- pipe->is_stalled) {
-
- /* setup a clear-stall packet */
-
- req.bmRequestType = UT_WRITE_ENDPOINT;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, UF_ENDPOINT_HALT);
- req.wIndex[0] = pipe->edesc->bEndpointAddress;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- /* copy in the transfer */
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
-
- /* set length */
- xfer->frlengths[0] = sizeof(req);
- xfer->nframes = 1;
- USB_BUS_UNLOCK(udev->bus);
-
- usb2_start_hardware(xfer);
-
- USB_BUS_LOCK(udev->bus);
- break;
- }
- pipe++;
- if (--to)
- goto tr_setup;
- break;
-
- default:
- if (xfer->error == USB_ERR_CANCELLED) {
- break;
- }
- goto tr_setup;
- }
-
- /* store current pipe */
- udev->pipe_curr = pipe;
- USB_BUS_UNLOCK(udev->bus);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_do_request_flags and usb2_do_request
- *
- * Description of arguments passed to these functions:
- *
- * "udev" - this is the "usb2_device" structure pointer on which the
- * request should be performed. It is possible to call this function
- * in both Host Side mode and Device Side mode.
- *
- * "mtx" - if this argument is non-NULL the mutex pointed to by it
- * will get dropped and picked up during the execution of this
- * function, hence this function sometimes needs to sleep. If this
- * argument is NULL it has no effect.
- *
- * "req" - this argument must always be non-NULL and points to an
- * 8-byte structure holding the USB request to be done. The USB
- * request structure has a bit telling the direction of the USB
- * request, if it is a read or a write.
- *
- * "data" - if the "wLength" part of the structure pointed to by "req"
- * is non-zero this argument must point to a valid kernel buffer which
- * can hold at least "wLength" bytes. If "wLength" is zero "data" can
- * be NULL.
- *
- * "flags" - here is a list of valid flags:
- *
- * o USB_SHORT_XFER_OK: allows the data transfer to be shorter than
- * specified
- *
- * o USB_USE_POLLING: forces the transfer to complete from the
- * current context by polling the interrupt handler. This flag can be
- * used to perform USB transfers after that the kernel has crashed.
- *
- * o USB_DELAY_STATUS_STAGE: allows the status stage to be performed
- * at a later point in time. This is tunable by the "hw.usb.ss_delay"
- * sysctl. This flag is mostly useful for debugging.
- *
- * o USB_USER_DATA_PTR: treat the "data" pointer like a userland
- * pointer.
- *
- * "actlen" - if non-NULL the actual transfer length will be stored in
- * the 16-bit unsigned integer pointed to by "actlen". This
- * information is mostly useful when the "USB_SHORT_XFER_OK" flag is
- * used.
- *
- * "timeout" - gives the timeout for the control transfer in
- * milliseconds. A "timeout" value less than 50 milliseconds is
- * treated like a 50 millisecond timeout. A "timeout" value greater
- * than 30 seconds is treated like a 30 second timeout. This USB stack
- * does not allow control requests without a timeout.
- *
- * NOTE: This function is thread safe. All calls to
- * "usb2_do_request_flags" will be serialised by the use of an
- * internal "sx_lock".
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_device_request *req, void *data, uint32_t flags,
- uint16_t *actlen, uint32_t timeout)
-{
- struct usb2_xfer *xfer;
- const void *desc;
- int err = 0;
- uint32_t start_ticks;
- uint32_t delta_ticks;
- uint32_t max_ticks;
- uint16_t length;
- uint16_t temp;
-
- if (timeout < 50) {
- /* timeout is too small */
- timeout = 50;
- }
- if (timeout > 30000) {
- /* timeout is too big */
- timeout = 30000;
- }
- length = UGETW(req->wLength);
-
- DPRINTFN(5, "udev=%p bmRequestType=0x%02x bRequest=0x%02x "
- "wValue=0x%02x%02x wIndex=0x%02x%02x wLength=0x%02x%02x\n",
- udev, req->bmRequestType, req->bRequest,
- req->wValue[1], req->wValue[0],
- req->wIndex[1], req->wIndex[0],
- req->wLength[1], req->wLength[0]);
-
- /*
- * Set "actlen" to a known value in case the caller does not
- * check the return value:
- */
- if (actlen) {
- *actlen = 0;
- }
- if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
- DPRINTF("USB device mode\n");
- (usb2_temp_get_desc_p) (udev, req, &desc, &temp);
- if (length > temp) {
- if (!(flags & USB_SHORT_XFER_OK)) {
- return (USB_ERR_SHORT_XFER);
- }
- length = temp;
- }
- if (actlen) {
- *actlen = length;
- }
- if (length > 0) {
- if (flags & USB_USER_DATA_PTR) {
- if (copyout(desc, data, length)) {
- return (USB_ERR_INVAL);
- }
- } else {
- bcopy(desc, data, length);
- }
- }
- return (0); /* success */
- }
- if (mtx) {
- mtx_unlock(mtx);
- if (mtx != &Giant) {
- mtx_assert(mtx, MA_NOTOWNED);
- }
- }
- /*
- * Grab the default sx-lock so that serialisation
- * is achieved when multiple threads are involved:
- */
-
- sx_xlock(udev->default_sx);
-
- /*
- * Setup a new USB transfer or use the existing one, if any:
- */
- usb2_default_transfer_setup(udev);
-
- xfer = udev->default_xfer[0];
- if (xfer == NULL) {
- /* most likely out of memory */
- err = USB_ERR_NOMEM;
- goto done;
- }
- USB_XFER_LOCK(xfer);
-
- if (flags & USB_DELAY_STATUS_STAGE) {
- xfer->flags.manual_status = 1;
- } else {
- xfer->flags.manual_status = 0;
- }
-
- xfer->timeout = timeout;
-
- start_ticks = ticks;
-
- max_ticks = USB_MS_TO_TICKS(timeout);
-
- usb2_copy_in(xfer->frbuffers, 0, req, sizeof(*req));
-
- xfer->frlengths[0] = sizeof(*req);
- xfer->nframes = 2;
-
- while (1) {
- temp = length;
- if (temp > xfer->max_data_length) {
- temp = xfer->max_data_length;
- }
- xfer->frlengths[1] = temp;
-
- if (temp > 0) {
- if (!(req->bmRequestType & UT_READ)) {
- if (flags & USB_USER_DATA_PTR) {
- USB_XFER_UNLOCK(xfer);
- err = usb2_copy_in_user(xfer->frbuffers + 1,
- 0, data, temp);
- USB_XFER_LOCK(xfer);
- if (err) {
- err = USB_ERR_INVAL;
- break;
- }
- } else {
- usb2_copy_in(xfer->frbuffers + 1, 0, data, temp);
- }
- }
- xfer->nframes = 2;
- } else {
- if (xfer->frlengths[0] == 0) {
- if (xfer->flags.manual_status) {
-#if USB_DEBUG
- int temp;
-
- temp = usb2_ss_delay;
- if (temp > 5000) {
- temp = 5000;
- }
- if (temp > 0) {
- usb2_pause_mtx(
- xfer->xroot->xfer_mtx,
- USB_MS_TO_TICKS(temp));
- }
-#endif
- xfer->flags.manual_status = 0;
- } else {
- break;
- }
- }
- xfer->nframes = 1;
- }
-
- usb2_transfer_start(xfer);
-
- while (usb2_transfer_pending(xfer)) {
- if ((flags & USB_USE_POLLING) || cold) {
- usb2_do_poll(udev->default_xfer, USB_DEFAULT_XFER_MAX);
- } else {
- usb2_cv_wait(udev->default_cv,
- xfer->xroot->xfer_mtx);
- }
- }
-
- err = xfer->error;
-
- if (err) {
- break;
- }
- /* subtract length of SETUP packet, if any */
-
- if (xfer->aframes > 0) {
- xfer->actlen -= xfer->frlengths[0];
- } else {
- xfer->actlen = 0;
- }
-
- /* check for short packet */
-
- if (temp > xfer->actlen) {
- temp = xfer->actlen;
- if (!(flags & USB_SHORT_XFER_OK)) {
- err = USB_ERR_SHORT_XFER;
- }
- length = temp;
- }
- if (temp > 0) {
- if (req->bmRequestType & UT_READ) {
- if (flags & USB_USER_DATA_PTR) {
- USB_XFER_UNLOCK(xfer);
- err = usb2_copy_out_user(xfer->frbuffers + 1,
- 0, data, temp);
- USB_XFER_LOCK(xfer);
- if (err) {
- err = USB_ERR_INVAL;
- break;
- }
- } else {
- usb2_copy_out(xfer->frbuffers + 1,
- 0, data, temp);
- }
- }
- }
- /*
- * Clear "frlengths[0]" so that we don't send the setup
- * packet again:
- */
- xfer->frlengths[0] = 0;
-
- /* update length and data pointer */
- length -= temp;
- data = USB_ADD_BYTES(data, temp);
-
- if (actlen) {
- (*actlen) += temp;
- }
- /* check for timeout */
-
- delta_ticks = ticks - start_ticks;
- if (delta_ticks > max_ticks) {
- if (!err) {
- err = USB_ERR_TIMEOUT;
- }
- }
- if (err) {
- break;
- }
- }
-
- if (err) {
- /*
- * Make sure that the control endpoint is no longer
- * blocked in case of a non-transfer related error:
- */
- usb2_transfer_stop(xfer);
- }
- USB_XFER_UNLOCK(xfer);
-
-done:
- sx_xunlock(udev->default_sx);
-
- if (mtx) {
- mtx_lock(mtx);
- }
- return ((usb2_error_t)err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_do_request_proc - factored out code
- *
- * This function is factored out code. It does basically the same like
- * usb2_do_request_flags, except it will check the status of the
- * passed process argument before doing the USB request. If the
- * process is draining the USB_ERR_IOERROR code will be returned. It
- * is assumed that the mutex associated with the process is locked
- * when calling this function.
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_do_request_proc(struct usb2_device *udev, struct usb2_process *pproc,
- struct usb2_device_request *req, void *data, uint32_t flags,
- uint16_t *actlen, uint32_t timeout)
-{
- usb2_error_t err;
- uint16_t len;
-
- /* get request data length */
- len = UGETW(req->wLength);
-
- /* check if the device is being detached */
- if (usb2_proc_is_gone(pproc)) {
- err = USB_ERR_IOERROR;
- goto done;
- }
-
- /* forward the USB request */
- err = usb2_do_request_flags(udev, pproc->up_mtx,
- req, data, flags, actlen, timeout);
-
-done:
- /* on failure we zero the data */
- /* on short packet we zero the unused data */
- if ((len != 0) && (req->bmRequestType & UE_DIR_IN)) {
- if (err)
- memset(data, 0, len);
- else if (actlen && *actlen != len)
- memset(((uint8_t *)data) + *actlen, 0, len - *actlen);
- }
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_reset_port
- *
- * This function will instruct an USB HUB to perform a reset sequence
- * on the specified port number.
- *
- * Returns:
- * 0: Success. The USB device should now be at address zero.
- * Else: Failure. No USB device is present and the USB port should be
- * disabled.
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_reset_port(struct usb2_device *udev, struct mtx *mtx, uint8_t port)
-{
- struct usb2_port_status ps;
- usb2_error_t err;
- uint16_t n;
-
-#if USB_DEBUG
- uint16_t pr_poll_delay;
- uint16_t pr_recovery_delay;
-
-#endif
- err = usb2_req_set_port_feature(udev, mtx, port, UHF_PORT_RESET);
- if (err) {
- goto done;
- }
-#if USB_DEBUG
- /* range check input parameters */
- pr_poll_delay = usb2_pr_poll_delay;
- if (pr_poll_delay < 1) {
- pr_poll_delay = 1;
- } else if (pr_poll_delay > 1000) {
- pr_poll_delay = 1000;
- }
- pr_recovery_delay = usb2_pr_recovery_delay;
- if (pr_recovery_delay > 1000) {
- pr_recovery_delay = 1000;
- }
-#endif
- n = 0;
- while (1) {
-#if USB_DEBUG
- /* wait for the device to recover from reset */
- usb2_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay));
- n += pr_poll_delay;
-#else
- /* wait for the device to recover from reset */
- usb2_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_DELAY));
- n += USB_PORT_RESET_DELAY;
-#endif
- err = usb2_req_get_port_status(udev, mtx, &ps, port);
- if (err) {
- goto done;
- }
- /* if the device disappeared, just give up */
- if (!(UGETW(ps.wPortStatus) & UPS_CURRENT_CONNECT_STATUS)) {
- goto done;
- }
- /* check if reset is complete */
- if (UGETW(ps.wPortChange) & UPS_C_PORT_RESET) {
- break;
- }
- /* check for timeout */
- if (n > 1000) {
- n = 0;
- break;
- }
- }
-
- /* clear port reset first */
- err = usb2_req_clear_port_feature(
- udev, mtx, port, UHF_C_PORT_RESET);
- if (err) {
- goto done;
- }
- /* check for timeout */
- if (n == 0) {
- err = USB_ERR_TIMEOUT;
- goto done;
- }
-#if USB_DEBUG
- /* wait for the device to recover from reset */
- usb2_pause_mtx(mtx, USB_MS_TO_TICKS(pr_recovery_delay));
-#else
- /* wait for the device to recover from reset */
- usb2_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_RECOVERY));
-#endif
-
-done:
- DPRINTFN(2, "port %d reset returning error=%s\n",
- port, usb2_errstr(err));
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_desc
- *
- * This function can be used to retrieve USB descriptors. It contains
- * some additional logic like zeroing of missing descriptor bytes and
- * retrying an USB descriptor in case of failure. The "min_len"
- * argument specifies the minimum descriptor length. The "max_len"
- * argument specifies the maximum descriptor length. If the real
- * descriptor length is less than the minimum length the missing
- * byte(s) will be zeroed. The length field, first byte, of the USB
- * descriptor will get overwritten in case it indicates a length that
- * is too big. Also the type field, second byte, of the USB descriptor
- * will get forced to the correct type.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_desc(struct usb2_device *udev, struct mtx *mtx, void *desc,
- uint16_t min_len, uint16_t max_len,
- uint16_t id, uint8_t type, uint8_t index,
- uint8_t retries)
-{
- struct usb2_device_request req;
- uint8_t *buf;
- usb2_error_t err;
-
- DPRINTFN(4, "id=%d, type=%d, index=%d, max_len=%d\n",
- id, type, index, max_len);
-
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW2(req.wValue, type, index);
- USETW(req.wIndex, id);
-
- while (1) {
-
- if ((min_len < 2) || (max_len < 2)) {
- err = USB_ERR_INVAL;
- goto done;
- }
- USETW(req.wLength, min_len);
-
- err = usb2_do_request_flags(udev, mtx, &req,
- desc, 0, NULL, 1000);
-
- if (err) {
- if (!retries) {
- goto done;
- }
- retries--;
-
- usb2_pause_mtx(mtx, hz / 5);
-
- continue;
- }
- buf = desc;
-
- if (min_len == max_len) {
-
- /* enforce correct type and length */
-
- if (buf[0] > min_len) {
- buf[0] = min_len;
- }
- buf[1] = type;
-
- goto done;
- }
- /* range check */
-
- if (max_len > buf[0]) {
- max_len = buf[0];
- }
- /* zero minimum data */
-
- while (min_len > max_len) {
- min_len--;
- buf[min_len] = 0;
- }
-
- /* set new minimum length */
-
- min_len = max_len;
- }
-done:
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_string_any
- *
- * This function will return the string given by "string_index"
- * using the first language ID. The maximum length "len" includes
- * the terminating zero. The "len" argument should be twice as
- * big pluss 2 bytes, compared with the actual maximum string length !
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_string_any(struct usb2_device *udev, struct mtx *mtx, char *buf,
- uint16_t len, uint8_t string_index)
-{
- char *s;
- uint8_t *temp;
- uint16_t i;
- uint16_t n;
- uint16_t c;
- uint8_t swap;
- usb2_error_t err;
-
- if (len == 0) {
- /* should not happen */
- return (USB_ERR_NORMAL_COMPLETION);
- }
- if (string_index == 0) {
- /* this is the language table */
- buf[0] = 0;
- return (USB_ERR_INVAL);
- }
- if (udev->flags.no_strings) {
- buf[0] = 0;
- return (USB_ERR_STALLED);
- }
- err = usb2_req_get_string_desc
- (udev, mtx, buf, len, udev->langid, string_index);
- if (err) {
- buf[0] = 0;
- return (err);
- }
- temp = (uint8_t *)buf;
-
- if (temp[0] < 2) {
- /* string length is too short */
- buf[0] = 0;
- return (USB_ERR_INVAL);
- }
- /* reserve one byte for terminating zero */
- len--;
-
- /* find maximum length */
- s = buf;
- n = (temp[0] / 2) - 1;
- if (n > len) {
- n = len;
- }
- /* skip descriptor header */
- temp += 2;
-
- /* reset swap state */
- swap = 3;
-
- /* convert and filter */
- for (i = 0; (i != n); i++) {
- c = UGETW(temp + (2 * i));
-
- /* convert from Unicode, handle buggy strings */
- if (((c & 0xff00) == 0) && (swap & 1)) {
- /* Little Endian, default */
- *s = c;
- swap = 1;
- } else if (((c & 0x00ff) == 0) && (swap & 2)) {
- /* Big Endian */
- *s = c >> 8;
- swap = 2;
- } else {
- /* silently skip bad character */
- continue;
- }
-
- /*
- * Filter by default - we don't allow greater and less than
- * signs because they might confuse the dmesg printouts!
- */
- if ((*s == '<') || (*s == '>') || (!isprint(*s))) {
- /* silently skip bad character */
- continue;
- }
- s++;
- }
- *s = 0; /* zero terminate resulting string */
- return (USB_ERR_NORMAL_COMPLETION);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_string_desc
- *
- * If you don't know the language ID, consider using
- * "usb2_req_get_string_any()".
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_string_desc(struct usb2_device *udev, struct mtx *mtx, void *sdesc,
- uint16_t max_len, uint16_t lang_id,
- uint8_t string_index)
-{
- return (usb2_req_get_desc(udev, mtx, sdesc, 2, max_len, lang_id,
- UDESC_STRING, string_index, 0));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_config_desc
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_config_desc(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_config_descriptor *d, uint8_t conf_index)
-{
- usb2_error_t err;
-
- DPRINTFN(4, "confidx=%d\n", conf_index);
-
- err = usb2_req_get_desc(udev, mtx, d, sizeof(*d),
- sizeof(*d), 0, UDESC_CONFIG, conf_index, 0);
- if (err) {
- goto done;
- }
- /* Extra sanity checking */
- if (UGETW(d->wTotalLength) < sizeof(*d)) {
- err = USB_ERR_INVAL;
- }
-done:
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_config_desc_full
- *
- * This function gets the complete USB configuration descriptor and
- * ensures that "wTotalLength" is correct.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_config_desc_full(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_config_descriptor **ppcd, struct malloc_type *mtype,
- uint8_t index)
-{
- struct usb2_config_descriptor cd;
- struct usb2_config_descriptor *cdesc;
- uint16_t len;
- usb2_error_t err;
-
- DPRINTFN(4, "index=%d\n", index);
-
- *ppcd = NULL;
-
- err = usb2_req_get_config_desc(udev, mtx, &cd, index);
- if (err) {
- return (err);
- }
- /* get full descriptor */
- len = UGETW(cd.wTotalLength);
- if (len < sizeof(*cdesc)) {
- /* corrupt descriptor */
- return (USB_ERR_INVAL);
- }
- cdesc = malloc(len, mtype, M_WAITOK);
- if (cdesc == NULL) {
- return (USB_ERR_NOMEM);
- }
- err = usb2_req_get_desc(udev, mtx, cdesc, len, len, 0,
- UDESC_CONFIG, index, 3);
- if (err) {
- free(cdesc, mtype);
- return (err);
- }
- /* make sure that the device is not fooling us: */
- USETW(cdesc->wTotalLength, len);
-
- *ppcd = cdesc;
-
- return (0); /* success */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_device_desc
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_device_desc(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_device_descriptor *d)
-{
- DPRINTFN(4, "\n");
- return (usb2_req_get_desc(udev, mtx, d, sizeof(*d),
- sizeof(*d), 0, UDESC_DEVICE, 0, 3));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_alt_interface_no
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_alt_interface_no(struct usb2_device *udev, struct mtx *mtx,
- uint8_t *alt_iface_no, uint8_t iface_index)
-{
- struct usb2_interface *iface = usb2_get_iface(udev, iface_index);
- struct usb2_device_request req;
-
- if ((iface == NULL) || (iface->idesc == NULL)) {
- return (USB_ERR_INVAL);
- }
- req.bmRequestType = UT_READ_INTERFACE;
- req.bRequest = UR_GET_INTERFACE;
- USETW(req.wValue, 0);
- req.wIndex[0] = iface->idesc->bInterfaceNumber;
- req.wIndex[1] = 0;
- USETW(req.wLength, 1);
- return (usb2_do_request(udev, mtx, &req, alt_iface_no));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_set_alt_interface_no
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_set_alt_interface_no(struct usb2_device *udev, struct mtx *mtx,
- uint8_t iface_index, uint8_t alt_no)
-{
- struct usb2_interface *iface = usb2_get_iface(udev, iface_index);
- struct usb2_device_request req;
-
- if ((iface == NULL) || (iface->idesc == NULL)) {
- return (USB_ERR_INVAL);
- }
- req.bmRequestType = UT_WRITE_INTERFACE;
- req.bRequest = UR_SET_INTERFACE;
- req.wValue[0] = alt_no;
- req.wValue[1] = 0;
- req.wIndex[0] = iface->idesc->bInterfaceNumber;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
- return (usb2_do_request(udev, mtx, &req, 0));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_device_status
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_device_status(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_status *st)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(*st));
- return (usb2_do_request(udev, mtx, &req, st));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_hub_descriptor
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_hub_descriptor(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_hub_descriptor *hd, uint8_t nports)
-{
- struct usb2_device_request req;
- uint16_t len = (nports + 7 + (8 * 8)) / 8;
-
- req.bmRequestType = UT_READ_CLASS_DEVICE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW2(req.wValue, UDESC_HUB, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, len);
- return (usb2_do_request(udev, mtx, &req, hd));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_hub_status
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_hub_status(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_hub_status *st)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_READ_CLASS_DEVICE;
- req.bRequest = UR_GET_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(struct usb2_hub_status));
- return (usb2_do_request(udev, mtx, &req, st));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_set_address
- *
- * This function is used to set the address for an USB device. After
- * port reset the USB device will respond at address zero.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_set_address(struct usb2_device *udev, struct mtx *mtx, uint16_t addr)
-{
- struct usb2_device_request req;
-
- DPRINTFN(6, "setting device address=%d\n", addr);
-
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_SET_ADDRESS;
- USETW(req.wValue, addr);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- /* Setting the address should not take more than 1 second ! */
- return (usb2_do_request_flags(udev, mtx, &req, NULL,
- USB_DELAY_STATUS_STAGE, NULL, 1000));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_port_status
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_port_status(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_port_status *ps, uint8_t port)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_READ_CLASS_OTHER;
- req.bRequest = UR_GET_STATUS;
- USETW(req.wValue, 0);
- req.wIndex[0] = port;
- req.wIndex[1] = 0;
- USETW(req.wLength, sizeof *ps);
- return (usb2_do_request(udev, mtx, &req, ps));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_clear_hub_feature
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_clear_hub_feature(struct usb2_device *udev, struct mtx *mtx,
- uint16_t sel)
-{
- struct usb2_device_request 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 (usb2_do_request(udev, mtx, &req, 0));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_set_hub_feature
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_set_hub_feature(struct usb2_device *udev, struct mtx *mtx,
- uint16_t sel)
-{
- struct usb2_device_request 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 (usb2_do_request(udev, mtx, &req, 0));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_clear_port_feature
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_clear_port_feature(struct usb2_device *udev, struct mtx *mtx,
- uint8_t port, uint16_t sel)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_CLASS_OTHER;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, sel);
- req.wIndex[0] = port;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
- return (usb2_do_request(udev, mtx, &req, 0));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_set_port_feature
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_set_port_feature(struct usb2_device *udev, struct mtx *mtx,
- uint8_t port, uint16_t sel)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_CLASS_OTHER;
- req.bRequest = UR_SET_FEATURE;
- USETW(req.wValue, sel);
- req.wIndex[0] = port;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
- return (usb2_do_request(udev, mtx, &req, 0));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_set_protocol
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_set_protocol(struct usb2_device *udev, struct mtx *mtx,
- uint8_t iface_index, uint16_t report)
-{
- struct usb2_interface *iface = usb2_get_iface(udev, iface_index);
- struct usb2_device_request req;
-
- if ((iface == NULL) || (iface->idesc == NULL)) {
- return (USB_ERR_INVAL);
- }
- DPRINTFN(5, "iface=%p, report=%d, endpt=%d\n",
- iface, report, iface->idesc->bInterfaceNumber);
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_PROTOCOL;
- USETW(req.wValue, report);
- req.wIndex[0] = iface->idesc->bInterfaceNumber;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
- return (usb2_do_request(udev, mtx, &req, 0));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_set_report
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_set_report(struct usb2_device *udev, struct mtx *mtx, void *data, uint16_t len,
- uint8_t iface_index, uint8_t type, uint8_t id)
-{
- struct usb2_interface *iface = usb2_get_iface(udev, iface_index);
- struct usb2_device_request req;
-
- if ((iface == NULL) || (iface->idesc == NULL)) {
- return (USB_ERR_INVAL);
- }
- DPRINTFN(5, "len=%d\n", len);
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, type, id);
- req.wIndex[0] = iface->idesc->bInterfaceNumber;
- req.wIndex[1] = 0;
- USETW(req.wLength, len);
- return (usb2_do_request(udev, mtx, &req, data));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_report
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_report(struct usb2_device *udev, struct mtx *mtx, void *data,
- uint16_t len, uint8_t iface_index, uint8_t type, uint8_t id)
-{
- struct usb2_interface *iface = usb2_get_iface(udev, iface_index);
- struct usb2_device_request req;
-
- if ((iface == NULL) || (iface->idesc == NULL) || (id == 0)) {
- return (USB_ERR_INVAL);
- }
- DPRINTFN(5, "len=%d\n", len);
-
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_GET_REPORT;
- USETW2(req.wValue, type, id);
- req.wIndex[0] = iface->idesc->bInterfaceNumber;
- req.wIndex[1] = 0;
- USETW(req.wLength, len);
- return (usb2_do_request(udev, mtx, &req, data));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_set_idle
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_set_idle(struct usb2_device *udev, struct mtx *mtx,
- uint8_t iface_index, uint8_t duration, uint8_t id)
-{
- struct usb2_interface *iface = usb2_get_iface(udev, iface_index);
- struct usb2_device_request req;
-
- if ((iface == NULL) || (iface->idesc == NULL)) {
- return (USB_ERR_INVAL);
- }
- DPRINTFN(5, "%d %d\n", duration, id);
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_IDLE;
- USETW2(req.wValue, duration, id);
- req.wIndex[0] = iface->idesc->bInterfaceNumber;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
- return (usb2_do_request(udev, mtx, &req, 0));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_report_descriptor
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_report_descriptor(struct usb2_device *udev, struct mtx *mtx,
- void *d, uint16_t size, uint8_t iface_index)
-{
- struct usb2_interface *iface = usb2_get_iface(udev, iface_index);
- struct usb2_device_request req;
-
- if ((iface == NULL) || (iface->idesc == NULL)) {
- return (USB_ERR_INVAL);
- }
- req.bmRequestType = UT_READ_INTERFACE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW2(req.wValue, UDESC_REPORT, 0); /* report id should be 0 */
- req.wIndex[0] = iface->idesc->bInterfaceNumber;
- req.wIndex[1] = 0;
- USETW(req.wLength, size);
- return (usb2_do_request(udev, mtx, &req, d));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_set_config
- *
- * This function is used to select the current configuration number in
- * both USB device side mode and USB host side mode. When setting the
- * configuration the function of the interfaces can change.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_set_config(struct usb2_device *udev, struct mtx *mtx, uint8_t conf)
-{
- struct usb2_device_request req;
-
- DPRINTF("setting config %d\n", conf);
-
- /* do "set configuration" request */
-
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_SET_CONFIG;
- req.wValue[0] = conf;
- req.wValue[1] = 0;
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- return (usb2_do_request(udev, mtx, &req, 0));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_get_config
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_get_config(struct usb2_device *udev, struct mtx *mtx, uint8_t *pconf)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_CONFIG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 1);
- return (usb2_do_request(udev, mtx, &req, pconf));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_re_enumerate
- *
- * NOTE: After this function returns the hardware is in the
- * unconfigured state! The application is responsible for setting a
- * new configuration.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_re_enumerate(struct usb2_device *udev, struct mtx *mtx)
-{
- struct usb2_device *parent_hub;
- usb2_error_t err;
- uint8_t old_addr;
- uint8_t do_retry = 1;
-
- if (udev->flags.usb2_mode != USB_MODE_HOST) {
- return (USB_ERR_INVAL);
- }
- old_addr = udev->address;
- parent_hub = udev->parent_hub;
- if (parent_hub == NULL) {
- return (USB_ERR_INVAL);
- }
-retry:
- err = usb2_req_reset_port(parent_hub, mtx, udev->port_no);
- if (err) {
- DPRINTFN(0, "addr=%d, port reset failed\n", old_addr);
- goto done;
- }
- /*
- * After that the port has been reset our device should be at
- * address zero:
- */
- udev->address = USB_START_ADDR;
-
- /* reset "bMaxPacketSize" */
- udev->ddesc.bMaxPacketSize = USB_MAX_IPACKET;
-
- /*
- * Restore device address:
- */
- err = usb2_req_set_address(udev, mtx, old_addr);
- if (err) {
- /* XXX ignore any errors! */
- DPRINTFN(0, "addr=%d, set address failed! (ignored)\n",
- old_addr);
- }
- /* restore device address */
- udev->address = old_addr;
-
- /* allow device time to set new address */
- usb2_pause_mtx(mtx, USB_MS_TO_TICKS(USB_SET_ADDRESS_SETTLE));
-
- /* get the device descriptor */
- err = usb2_req_get_desc(udev, mtx, &udev->ddesc,
- USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0);
- if (err) {
- DPRINTFN(0, "getting device descriptor "
- "at addr %d failed!\n", udev->address);
- goto done;
- }
- /* get the full device descriptor */
- err = usb2_req_get_device_desc(udev, mtx, &udev->ddesc);
- if (err) {
- DPRINTFN(0, "addr=%d, getting device "
- "descriptor failed!\n", old_addr);
- goto done;
- }
-done:
- if (err && do_retry) {
- /* give the USB firmware some time to load */
- usb2_pause_mtx(mtx, hz / 2);
- /* no more retries after this retry */
- do_retry = 0;
- /* try again */
- goto retry;
- }
- /* restore address */
- udev->address = old_addr;
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_clear_device_feature
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_clear_device_feature(struct usb2_device *udev, struct mtx *mtx,
- uint16_t sel)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, sel);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- return (usb2_do_request(udev, mtx, &req, 0));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_req_set_device_feature
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_req_set_device_feature(struct usb2_device *udev, struct mtx *mtx,
- uint16_t sel)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_SET_FEATURE;
- USETW(req.wValue, sel);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- return (usb2_do_request(udev, mtx, &req, 0));
-}
diff --git a/sys/dev/usb2/core/usb2_request.h b/sys/dev/usb2/core/usb2_request.h
deleted file mode 100644
index 8a360b7..0000000
--- a/sys/dev/usb2/core/usb2_request.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_REQUEST_H_
-#define _USB2_REQUEST_H_
-
-struct usb2_process;
-
-usb2_error_t usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_device_request *req, void *data, uint32_t flags,
- uint16_t *actlen, uint32_t timeout);
-usb2_error_t usb2_do_request_proc(struct usb2_device *udev, struct usb2_process *pproc,
- struct usb2_device_request *req, void *data, uint32_t flags,
- uint16_t *actlen, uint32_t timeout);
-usb2_error_t usb2_req_clear_hub_feature(struct usb2_device *udev,
- struct mtx *mtx, uint16_t sel);
-usb2_error_t usb2_req_clear_port_feature(struct usb2_device *udev,
- struct mtx *mtx, uint8_t port, uint16_t sel);
-usb2_error_t usb2_req_get_alt_interface_no(struct usb2_device *udev,
- struct mtx *mtx, uint8_t *alt_iface_no,
- uint8_t iface_index);
-usb2_error_t usb2_req_get_config(struct usb2_device *udev, struct mtx *mtx,
- uint8_t *pconf);
-usb2_error_t usb2_req_get_config_desc(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_config_descriptor *d, uint8_t conf_index);
-usb2_error_t usb2_req_get_config_desc_full(struct usb2_device *udev,
- struct mtx *mtx, struct usb2_config_descriptor **ppcd,
- struct malloc_type *mtype, uint8_t conf_index);
-usb2_error_t usb2_req_get_desc(struct usb2_device *udev, struct mtx *mtx,
- void *desc, uint16_t min_len, uint16_t max_len, uint16_t id,
- uint8_t type, uint8_t index, uint8_t retries);
-usb2_error_t usb2_req_get_device_desc(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_device_descriptor *d);
-usb2_error_t usb2_req_get_device_status(struct usb2_device *udev,
- struct mtx *mtx, struct usb2_status *st);
-usb2_error_t usb2_req_get_hub_descriptor(struct usb2_device *udev,
- struct mtx *mtx, struct usb2_hub_descriptor *hd,
- uint8_t nports);
-usb2_error_t usb2_req_get_hub_status(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_hub_status *st);
-usb2_error_t usb2_req_get_port_status(struct usb2_device *udev, struct mtx *mtx,
- struct usb2_port_status *ps, uint8_t port);
-usb2_error_t usb2_req_get_report(struct usb2_device *udev, struct mtx *mtx,
- void *data, uint16_t len, uint8_t iface_index, uint8_t type,
- uint8_t id);
-usb2_error_t usb2_req_get_report_descriptor(struct usb2_device *udev,
- struct mtx *mtx, void *d, uint16_t size,
- uint8_t iface_index);
-usb2_error_t usb2_req_get_string_any(struct usb2_device *udev, struct mtx *mtx,
- char *buf, uint16_t len, uint8_t string_index);
-usb2_error_t usb2_req_get_string_desc(struct usb2_device *udev, struct mtx *mtx,
- void *sdesc, uint16_t max_len, uint16_t lang_id,
- uint8_t string_index);
-usb2_error_t usb2_req_reset_port(struct usb2_device *udev, struct mtx *mtx,
- uint8_t port);
-usb2_error_t usb2_req_set_address(struct usb2_device *udev, struct mtx *mtx,
- uint16_t addr);
-usb2_error_t usb2_req_set_alt_interface_no(struct usb2_device *udev,
- struct mtx *mtx, uint8_t iface_index, uint8_t alt_no);
-usb2_error_t usb2_req_set_config(struct usb2_device *udev, struct mtx *mtx,
- uint8_t conf);
-usb2_error_t usb2_req_set_hub_feature(struct usb2_device *udev, struct mtx *mtx,
- uint16_t sel);
-usb2_error_t usb2_req_set_idle(struct usb2_device *udev, struct mtx *mtx,
- uint8_t iface_index, uint8_t duration, uint8_t id);
-usb2_error_t usb2_req_set_port_feature(struct usb2_device *udev,
- struct mtx *mtx, uint8_t port, uint16_t sel);
-usb2_error_t usb2_req_set_protocol(struct usb2_device *udev, struct mtx *mtx,
- uint8_t iface_index, uint16_t report);
-usb2_error_t usb2_req_set_report(struct usb2_device *udev, struct mtx *mtx,
- void *data, uint16_t len, uint8_t iface_index,
- uint8_t type, uint8_t id);
-usb2_error_t usb2_req_re_enumerate(struct usb2_device *udev, struct mtx *mtx);
-usb2_error_t usb2_req_clear_device_feature(struct usb2_device *udev, struct mtx *mtx, uint16_t sel);
-usb2_error_t usb2_req_set_device_feature(struct usb2_device *udev, struct mtx *mtx, uint16_t sel);
-
-#define usb2_do_request(u,m,r,d) \
- usb2_do_request_flags(u,m,r,d,0,NULL,USB_DEFAULT_TIMEOUT)
-
-#endif /* _USB2_REQUEST_H_ */
diff --git a/sys/dev/usb2/core/usb2_sw_transfer.c b/sys/dev/usb2/core/usb2_sw_transfer.c
deleted file mode 100644
index 23f89ba..0000000
--- a/sys/dev/usb2/core/usb2_sw_transfer.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_sw_transfer.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_debug.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-
-/*------------------------------------------------------------------------*
- * usb2_sw_transfer - factored out code
- *
- * This function is basically used for the Virtual Root HUB, and can
- * emulate control, bulk and interrupt endpoints. Data is exchanged
- * using the "std->ptr" and "std->len" fields, that allows kernel
- * virtual memory to be transferred. All state is kept in the
- * structure pointed to by the "std" argument passed to this
- * function. The "func" argument points to a function that is called
- * back in the various states, so that the application using this
- * function can get a chance to select the outcome. The "func"
- * function is allowed to sleep, exiting all mutexes. If this function
- * will sleep the "enter" and "start" methods must be marked
- * non-cancelable, hence there is no extra cancelled checking in this
- * function.
- *------------------------------------------------------------------------*/
-void
-usb2_sw_transfer(struct usb2_sw_transfer *std,
- usb2_sw_transfer_func_t *func)
-{
- struct usb2_xfer *xfer;
- uint32_t len;
- uint8_t shortpkt = 0;
-
- xfer = std->xfer;
- if (xfer == NULL) {
- /* the transfer is gone */
- DPRINTF("xfer gone\n");
- return;
- }
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- std->xfer = NULL;
-
- /* check for control transfer */
- if (xfer->flags_int.control_xfr) {
- /* check if we are transferring the SETUP packet */
- if (xfer->flags_int.control_hdr) {
-
- /* copy out the USB request */
-
- if (xfer->frlengths[0] == sizeof(std->req)) {
- usb2_copy_out(xfer->frbuffers, 0,
- &std->req, sizeof(std->req));
- } else {
- std->err = USB_ERR_INVAL;
- goto done;
- }
-
- xfer->aframes = 1;
-
- std->err = 0;
- std->state = USB_SW_TR_SETUP;
-
- (func) (xfer, std);
-
- if (std->err) {
- goto done;
- }
- } else {
- /* skip the first frame in this case */
- xfer->aframes = 1;
- }
- }
- std->err = 0;
- std->state = USB_SW_TR_PRE_DATA;
-
- (func) (xfer, std);
-
- if (std->err) {
- goto done;
- }
- /* Transfer data. Iterate accross all frames. */
- while (xfer->aframes != xfer->nframes) {
-
- len = xfer->frlengths[xfer->aframes];
-
- if (len > std->len) {
- len = std->len;
- shortpkt = 1;
- }
- if (len > 0) {
- if ((xfer->endpoint & (UE_DIR_IN | UE_DIR_OUT)) == UE_DIR_IN) {
- usb2_copy_in(xfer->frbuffers + xfer->aframes, 0,
- std->ptr, len);
- } else {
- usb2_copy_out(xfer->frbuffers + xfer->aframes, 0,
- std->ptr, len);
- }
- }
- std->ptr += len;
- std->len -= len;
- xfer->frlengths[xfer->aframes] = len;
- xfer->aframes++;
-
- if (shortpkt) {
- break;
- }
- }
-
- std->err = 0;
- std->state = USB_SW_TR_POST_DATA;
-
- (func) (xfer, std);
-
- if (std->err) {
- goto done;
- }
- /* check if the control transfer is complete */
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
-
- std->err = 0;
- std->state = USB_SW_TR_STATUS;
-
- (func) (xfer, std);
-
- if (std->err) {
- goto done;
- }
- }
-done:
- DPRINTF("done err=%s\n", usb2_errstr(std->err));
- std->state = USB_SW_TR_PRE_CALLBACK;
- (func) (xfer, std);
-}
diff --git a/sys/dev/usb2/core/usb2_sw_transfer.h b/sys/dev/usb2/core/usb2_sw_transfer.h
deleted file mode 100644
index d2da0eb..0000000
--- a/sys/dev/usb2/core/usb2_sw_transfer.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_SW_TRANSFER_H_
-#define _USB2_SW_TRANSFER_H_
-
-/* Software transfer function state argument values */
-
-enum {
- USB_SW_TR_SETUP,
- USB_SW_TR_STATUS,
- USB_SW_TR_PRE_DATA,
- USB_SW_TR_POST_DATA,
- USB_SW_TR_PRE_CALLBACK,
-};
-
-struct usb2_sw_transfer;
-
-typedef void (usb2_sw_transfer_func_t)(struct usb2_xfer *, struct usb2_sw_transfer *);
-
-/*
- * The following structure is used to keep the state of a standard
- * root transfer.
- */
-struct usb2_sw_transfer {
- struct usb2_device_request req;
- struct usb2_xfer *xfer;
- uint8_t *ptr;
- uint16_t len;
- uint8_t state;
- usb2_error_t err;
-};
-
-/* prototypes */
-
-void usb2_sw_transfer(struct usb2_sw_transfer *std,
- usb2_sw_transfer_func_t *func);
-
-#endif /* _USB2_SW_TRANSFER_H_ */
diff --git a/sys/dev/usb2/core/usb2_transfer.c b/sys/dev/usb2/core/usb2_transfer.c
deleted file mode 100644
index 2572b25..0000000
--- a/sys/dev/usb2/core/usb2_transfer.c
+++ /dev/null
@@ -1,2826 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-
-struct usb2_std_packet_size {
- struct {
- uint16_t min; /* inclusive */
- uint16_t max; /* inclusive */
- } range;
-
- uint16_t fixed[4];
-};
-
-/*
- * This table stores the all the allowed packet sizes based on
- * endpoint type and USB speed:
- */
-static const struct usb2_std_packet_size
- usb2_std_packet_size[4][USB_SPEED_MAX] = {
-
- [UE_INTERRUPT] = {
- [USB_SPEED_LOW] = {.range = {0, 8}},
- [USB_SPEED_FULL] = {.range = {0, 64}},
- [USB_SPEED_HIGH] = {.range = {0, 1024}},
- [USB_SPEED_VARIABLE] = {.range = {0, 1024}},
- [USB_SPEED_SUPER] = {.range = {0, 1024}},
- },
-
- [UE_CONTROL] = {
- [USB_SPEED_LOW] = {.fixed = {8, 8, 8, 8}},
- [USB_SPEED_FULL] = {.fixed = {8, 16, 32, 64}},
- [USB_SPEED_HIGH] = {.fixed = {64, 64, 64, 64}},
- [USB_SPEED_VARIABLE] = {.fixed = {512, 512, 512, 512}},
- [USB_SPEED_SUPER] = {.fixed = {512, 512, 512, 512}},
- },
-
- [UE_BULK] = {
- [USB_SPEED_LOW] = {.fixed = {0, 0, 0, 0}}, /* invalid */
- [USB_SPEED_FULL] = {.fixed = {8, 16, 32, 64}},
- [USB_SPEED_HIGH] = {.fixed = {512, 512, 512, 512}},
- [USB_SPEED_VARIABLE] = {.fixed = {512, 512, 1024, 1536}},
- [USB_SPEED_SUPER] = {.fixed = {1024, 1024, 1024, 1024}},
- },
-
- [UE_ISOCHRONOUS] = {
- [USB_SPEED_LOW] = {.fixed = {0, 0, 0, 0}}, /* invalid */
- [USB_SPEED_FULL] = {.range = {0, 1023}},
- [USB_SPEED_HIGH] = {.range = {0, 1024}},
- [USB_SPEED_VARIABLE] = {.range = {0, 3584}},
- [USB_SPEED_SUPER] = {.range = {0, 1024}},
- },
-};
-
-static const struct usb2_config usb2_control_ep_cfg[USB_DEFAULT_XFER_MAX] = {
-
- /* This transfer is used for generic control endpoint transfers */
-
- [0] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control endpoint */
- .direction = UE_DIR_ANY,
- .mh.bufsize = 1024, /* bytes */
- .mh.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
- .mh.callback = &usb2_do_request_callback,
- .md.bufsize = 1024, /* bytes */
- .md.flags = {.proxy_buffer = 1,.short_xfer_ok = 0,},
- .md.callback = &usb2_handle_request_callback,
- },
-
- /* This transfer is used for generic clear stall only */
-
- [1] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &usb2_do_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
-};
-
-/* function prototypes */
-
-static void usb2_update_max_frame_size(struct usb2_xfer *);
-static void usb2_transfer_unsetup_sub(struct usb2_xfer_root *, uint8_t);
-static void usb2_control_transfer_init(struct usb2_xfer *);
-static uint8_t usb2_start_hardware_sub(struct usb2_xfer *);
-static void usb2_callback_proc(struct usb2_proc_msg *);
-static void usb2_callback_ss_done_defer(struct usb2_xfer *);
-static void usb2_callback_wrapper(struct usb2_xfer_queue *);
-static void usb2_dma_delay_done_cb(void *);
-static void usb2_transfer_start_cb(void *);
-static uint8_t usb2_callback_wrapper_sub(struct usb2_xfer *);
-
-/*------------------------------------------------------------------------*
- * usb2_update_max_frame_size
- *
- * This function updates the maximum frame size, hence high speed USB
- * can transfer multiple consecutive packets.
- *------------------------------------------------------------------------*/
-static void
-usb2_update_max_frame_size(struct usb2_xfer *xfer)
-{
- /* compute maximum frame size */
-
- if (xfer->max_packet_count == 2) {
- xfer->max_frame_size = 2 * xfer->max_packet_size;
- } else if (xfer->max_packet_count == 3) {
- xfer->max_frame_size = 3 * xfer->max_packet_size;
- } else {
- xfer->max_frame_size = xfer->max_packet_size;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_get_dma_delay
- *
- * The following function is called when we need to
- * synchronize with DMA hardware.
- *
- * Returns:
- * 0: no DMA delay required
- * Else: milliseconds of DMA delay
- *------------------------------------------------------------------------*/
-uint32_t
-usb2_get_dma_delay(struct usb2_bus *bus)
-{
- uint32_t temp = 0;
-
- if (bus->methods->get_dma_delay) {
- (bus->methods->get_dma_delay) (bus, &temp);
- /*
- * Round up and convert to milliseconds. Note that we use
- * 1024 milliseconds per second. to save a division.
- */
- temp += 0x3FF;
- temp /= 0x400;
- }
- return (temp);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_setup_sub_malloc
- *
- * This function will allocate one or more DMA'able memory chunks
- * according to "size", "align" and "count" arguments. "ppc" is
- * pointed to a linear array of USB page caches afterwards.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_transfer_setup_sub_malloc(struct usb2_setup_params *parm,
- struct usb2_page_cache **ppc, uint32_t size, uint32_t align,
- uint32_t count)
-{
- struct usb2_page_cache *pc;
- struct usb2_page *pg;
- void *buf;
- uint32_t n_dma_pc;
- uint32_t n_obj;
- uint32_t x;
- uint32_t y;
- uint32_t r;
- uint32_t z;
-
- USB_ASSERT(align > 1, ("Invalid alignment, 0x%08x!\n",
- align));
- USB_ASSERT(size > 0, ("Invalid size = 0!\n"));
-
- if (count == 0) {
- return (0); /* nothing to allocate */
- }
- /*
- * Make sure that the size is aligned properly.
- */
- size = -((-size) & (-align));
-
- /*
- * Try multi-allocation chunks to reduce the number of DMA
- * allocations, hence DMA allocations are slow.
- */
- if (size >= PAGE_SIZE) {
- n_dma_pc = count;
- n_obj = 1;
- } else {
- /* compute number of objects per page */
- n_obj = (PAGE_SIZE / size);
- /*
- * Compute number of DMA chunks, rounded up
- * to nearest one:
- */
- n_dma_pc = ((count + n_obj - 1) / n_obj);
- }
-
- if (parm->buf == NULL) {
- /* for the future */
- parm->dma_page_ptr += n_dma_pc;
- parm->dma_page_cache_ptr += n_dma_pc;
- parm->dma_page_ptr += count;
- parm->xfer_page_cache_ptr += count;
- return (0);
- }
- for (x = 0; x != n_dma_pc; x++) {
- /* need to initialize the page cache */
- parm->dma_page_cache_ptr[x].tag_parent =
- &parm->curr_xfer->xroot->dma_parent_tag;
- }
- for (x = 0; x != count; x++) {
- /* need to initialize the page cache */
- parm->xfer_page_cache_ptr[x].tag_parent =
- &parm->curr_xfer->xroot->dma_parent_tag;
- }
-
- if (ppc) {
- *ppc = parm->xfer_page_cache_ptr;
- }
- r = count; /* set remainder count */
- z = n_obj * size; /* set allocation size */
- pc = parm->xfer_page_cache_ptr;
- pg = parm->dma_page_ptr;
-
- for (x = 0; x != n_dma_pc; x++) {
-
- if (r < n_obj) {
- /* compute last remainder */
- z = r * size;
- n_obj = r;
- }
- if (usb2_pc_alloc_mem(parm->dma_page_cache_ptr,
- pg, z, align)) {
- return (1); /* failure */
- }
- /* Set beginning of current buffer */
- buf = parm->dma_page_cache_ptr->buffer;
- /* Make room for one DMA page cache and one page */
- parm->dma_page_cache_ptr++;
- pg++;
-
- for (y = 0; (y != n_obj); y++, r--, pc++, pg++) {
-
- /* Load sub-chunk into DMA */
- if (usb2_pc_dmamap_create(pc, size)) {
- return (1); /* failure */
- }
- pc->buffer = USB_ADD_BYTES(buf, y * size);
- pc->page_start = pg;
-
- mtx_lock(pc->tag_parent->mtx);
- if (usb2_pc_load_mem(pc, size, 1 /* synchronous */ )) {
- mtx_unlock(pc->tag_parent->mtx);
- return (1); /* failure */
- }
- mtx_unlock(pc->tag_parent->mtx);
- }
- }
-
- parm->xfer_page_cache_ptr = pc;
- parm->dma_page_ptr = pg;
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_setup_sub - transfer setup subroutine
- *
- * This function must be called from the "xfer_setup" callback of the
- * USB Host or Device controller driver when setting up an USB
- * transfer. This function will setup correct packet sizes, buffer
- * sizes, flags and more, that are stored in the "usb2_xfer"
- * structure.
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_setup_sub(struct usb2_setup_params *parm)
-{
- enum {
- REQ_SIZE = 8,
- MIN_PKT = 8,
- };
- struct usb2_xfer *xfer = parm->curr_xfer;
- const struct usb2_config_sub *setup_sub = parm->curr_setup_sub;
- struct usb2_endpoint_descriptor *edesc;
- struct usb2_std_packet_size std_size;
- uint32_t n_frlengths;
- uint32_t n_frbuffers;
- uint32_t x;
- uint8_t type;
- uint8_t zmps;
-
- /*
- * Sanity check. The following parameters must be initialized before
- * calling this function.
- */
- if ((parm->hc_max_packet_size == 0) ||
- (parm->hc_max_packet_count == 0) ||
- (parm->hc_max_frame_size == 0)) {
- parm->err = USB_ERR_INVAL;
- goto done;
- }
- edesc = xfer->pipe->edesc;
-
- type = (edesc->bmAttributes & UE_XFERTYPE);
-
- xfer->flags = setup_sub->flags;
- xfer->nframes = setup_sub->frames;
- xfer->timeout = setup_sub->timeout;
- xfer->callback = setup_sub->callback;
- xfer->interval = setup_sub->interval;
- xfer->endpoint = edesc->bEndpointAddress;
- xfer->max_packet_size = UGETW(edesc->wMaxPacketSize);
- xfer->max_packet_count = 1;
- /* make a shadow copy: */
- xfer->flags_int.usb2_mode = parm->udev->flags.usb2_mode;
-
- parm->bufsize = setup_sub->bufsize;
-
- if (parm->speed == USB_SPEED_HIGH) {
- xfer->max_packet_count += (xfer->max_packet_size >> 11) & 3;
- xfer->max_packet_size &= 0x7FF;
- }
- /* range check "max_packet_count" */
-
- if (xfer->max_packet_count > parm->hc_max_packet_count) {
- xfer->max_packet_count = parm->hc_max_packet_count;
- }
- /* filter "wMaxPacketSize" according to HC capabilities */
-
- if ((xfer->max_packet_size > parm->hc_max_packet_size) ||
- (xfer->max_packet_size == 0)) {
- xfer->max_packet_size = parm->hc_max_packet_size;
- }
- /* filter "wMaxPacketSize" according to standard sizes */
-
- std_size = usb2_std_packet_size[type][parm->speed];
-
- if (std_size.range.min || std_size.range.max) {
-
- if (xfer->max_packet_size < std_size.range.min) {
- xfer->max_packet_size = std_size.range.min;
- }
- if (xfer->max_packet_size > std_size.range.max) {
- xfer->max_packet_size = std_size.range.max;
- }
- } else {
-
- if (xfer->max_packet_size >= std_size.fixed[3]) {
- xfer->max_packet_size = std_size.fixed[3];
- } else if (xfer->max_packet_size >= std_size.fixed[2]) {
- xfer->max_packet_size = std_size.fixed[2];
- } else if (xfer->max_packet_size >= std_size.fixed[1]) {
- xfer->max_packet_size = std_size.fixed[1];
- } else {
- /* only one possibility left */
- xfer->max_packet_size = std_size.fixed[0];
- }
- }
-
- /* compute "max_frame_size" */
-
- usb2_update_max_frame_size(xfer);
-
- /* check interrupt interval and transfer pre-delay */
-
- if (type == UE_ISOCHRONOUS) {
-
- uint32_t frame_limit;
-
- xfer->interval = 0; /* not used, must be zero */
- xfer->flags_int.isochronous_xfr = 1; /* set flag */
-
- if (xfer->timeout == 0) {
- /*
- * set a default timeout in
- * case something goes wrong!
- */
- xfer->timeout = 1000 / 4;
- }
- switch (parm->speed) {
- case USB_SPEED_LOW:
- case USB_SPEED_FULL:
- frame_limit = USB_MAX_FS_ISOC_FRAMES_PER_XFER;
- break;
- default:
- frame_limit = USB_MAX_HS_ISOC_FRAMES_PER_XFER;
- break;
- }
-
- if (xfer->nframes > frame_limit) {
- /*
- * this is not going to work
- * cross hardware
- */
- parm->err = USB_ERR_INVAL;
- goto done;
- }
- if (xfer->nframes == 0) {
- /*
- * this is not a valid value
- */
- parm->err = USB_ERR_ZERO_NFRAMES;
- goto done;
- }
- } else {
-
- /*
- * if a value is specified use that else check the endpoint
- * descriptor
- */
- if (xfer->interval == 0) {
-
- if (type == UE_INTERRUPT) {
-
- xfer->interval = edesc->bInterval;
-
- switch (parm->speed) {
- case USB_SPEED_SUPER:
- case USB_SPEED_VARIABLE:
- /* 125us -> 1ms */
- if (xfer->interval < 4)
- xfer->interval = 1;
- else if (xfer->interval > 16)
- xfer->interval = (1<<(16-4));
- else
- xfer->interval =
- (1 << (xfer->interval-4));
- break;
- case USB_SPEED_HIGH:
- /* 125us -> 1ms */
- xfer->interval /= 8;
- break;
- default:
- break;
- }
- if (xfer->interval == 0) {
- /*
- * One millisecond is the smallest
- * interval we support:
- */
- xfer->interval = 1;
- }
- }
- }
- }
-
- /*
- * NOTE: we do not allow "max_packet_size" or "max_frame_size"
- * to be equal to zero when setting up USB transfers, hence
- * this leads to alot of extra code in the USB kernel.
- */
-
- if ((xfer->max_frame_size == 0) ||
- (xfer->max_packet_size == 0)) {
-
- zmps = 1;
-
- if ((parm->bufsize <= MIN_PKT) &&
- (type != UE_CONTROL) &&
- (type != UE_BULK)) {
-
- /* workaround */
- xfer->max_packet_size = MIN_PKT;
- xfer->max_packet_count = 1;
- parm->bufsize = 0; /* automatic setup length */
- usb2_update_max_frame_size(xfer);
-
- } else {
- parm->err = USB_ERR_ZERO_MAXP;
- goto done;
- }
-
- } else {
- zmps = 0;
- }
-
- /*
- * check if we should setup a default
- * length:
- */
-
- if (parm->bufsize == 0) {
-
- parm->bufsize = xfer->max_frame_size;
-
- if (type == UE_ISOCHRONOUS) {
- parm->bufsize *= xfer->nframes;
- }
- }
- /*
- * check if we are about to setup a proxy
- * type of buffer:
- */
-
- if (xfer->flags.proxy_buffer) {
-
- /* round bufsize up */
-
- parm->bufsize += (xfer->max_frame_size - 1);
-
- if (parm->bufsize < xfer->max_frame_size) {
- /* length wrapped around */
- parm->err = USB_ERR_INVAL;
- goto done;
- }
- /* subtract remainder */
-
- parm->bufsize -= (parm->bufsize % xfer->max_frame_size);
-
- /* add length of USB device request structure, if any */
-
- if (type == UE_CONTROL) {
- parm->bufsize += REQ_SIZE; /* SETUP message */
- }
- }
- xfer->max_data_length = parm->bufsize;
-
- /* Setup "n_frlengths" and "n_frbuffers" */
-
- if (type == UE_ISOCHRONOUS) {
- n_frlengths = xfer->nframes;
- n_frbuffers = 1;
- } else {
-
- if (type == UE_CONTROL) {
- xfer->flags_int.control_xfr = 1;
- if (xfer->nframes == 0) {
- if (parm->bufsize <= REQ_SIZE) {
- /*
- * there will never be any data
- * stage
- */
- xfer->nframes = 1;
- } else {
- xfer->nframes = 2;
- }
- }
- } else {
- if (xfer->nframes == 0) {
- xfer->nframes = 1;
- }
- }
-
- n_frlengths = xfer->nframes;
- n_frbuffers = xfer->nframes;
- }
-
- /*
- * check if we have room for the
- * USB device request structure:
- */
-
- if (type == UE_CONTROL) {
-
- if (xfer->max_data_length < REQ_SIZE) {
- /* length wrapped around or too small bufsize */
- parm->err = USB_ERR_INVAL;
- goto done;
- }
- xfer->max_data_length -= REQ_SIZE;
- }
- /* setup "frlengths" */
-
- xfer->frlengths = parm->xfer_length_ptr;
-
- parm->xfer_length_ptr += n_frlengths;
-
- /* setup "frbuffers" */
-
- xfer->frbuffers = parm->xfer_page_cache_ptr;
-
- parm->xfer_page_cache_ptr += n_frbuffers;
-
- /*
- * check if we need to setup
- * a local buffer:
- */
-
- if (!xfer->flags.ext_buffer) {
-
- /* align data */
- parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
-
- if (parm->buf) {
-
- xfer->local_buffer =
- USB_ADD_BYTES(parm->buf, parm->size[0]);
-
- usb2_set_frame_offset(xfer, 0, 0);
-
- if ((type == UE_CONTROL) && (n_frbuffers > 1)) {
- usb2_set_frame_offset(xfer, REQ_SIZE, 1);
- }
- }
- parm->size[0] += parm->bufsize;
-
- /* align data again */
- parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
- }
- /*
- * Compute maximum buffer size
- */
-
- if (parm->bufsize_max < parm->bufsize) {
- parm->bufsize_max = parm->bufsize;
- }
- if (xfer->flags_int.bdma_enable) {
- /*
- * Setup "dma_page_ptr".
- *
- * Proof for formula below:
- *
- * Assume there are three USB frames having length "a", "b" and
- * "c". These USB frames will at maximum need "z"
- * "usb2_page" structures. "z" is given by:
- *
- * z = ((a / USB_PAGE_SIZE) + 2) + ((b / USB_PAGE_SIZE) + 2) +
- * ((c / USB_PAGE_SIZE) + 2);
- *
- * Constraining "a", "b" and "c" like this:
- *
- * (a + b + c) <= parm->bufsize
- *
- * We know that:
- *
- * z <= ((parm->bufsize / USB_PAGE_SIZE) + (3*2));
- *
- * Here is the general formula:
- */
- xfer->dma_page_ptr = parm->dma_page_ptr;
- parm->dma_page_ptr += (2 * n_frbuffers);
- parm->dma_page_ptr += (parm->bufsize / USB_PAGE_SIZE);
- }
- if (zmps) {
- /* correct maximum data length */
- xfer->max_data_length = 0;
- }
- /* subtract USB frame remainder from "hc_max_frame_size" */
-
- xfer->max_usb2_frame_size =
- (parm->hc_max_frame_size -
- (parm->hc_max_frame_size % xfer->max_frame_size));
-
- if (xfer->max_usb2_frame_size == 0) {
- parm->err = USB_ERR_INVAL;
- goto done;
- }
- /* initialize max frame count */
-
- xfer->max_frame_count = xfer->nframes;
-
- /* initialize frame buffers */
-
- if (parm->buf) {
- for (x = 0; x != n_frbuffers; x++) {
- xfer->frbuffers[x].tag_parent =
- &xfer->xroot->dma_parent_tag;
-
- if (xfer->flags_int.bdma_enable &&
- (parm->bufsize_max > 0)) {
-
- if (usb2_pc_dmamap_create(
- xfer->frbuffers + x,
- parm->bufsize_max)) {
- parm->err = USB_ERR_NOMEM;
- goto done;
- }
- }
- }
- }
-done:
- if (parm->err) {
- /*
- * Set some dummy values so that we avoid division by zero:
- */
- xfer->max_usb2_frame_size = 1;
- xfer->max_frame_size = 1;
- xfer->max_packet_size = 1;
- xfer->max_data_length = 0;
- xfer->nframes = 0;
- xfer->max_frame_count = 0;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_setup - setup an array of USB transfers
- *
- * NOTE: You must always call "usb2_transfer_unsetup" after calling
- * "usb2_transfer_setup" if success was returned.
- *
- * The idea is that the USB device driver should pre-allocate all its
- * transfers by one call to this function.
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-usb2_error_t
-usb2_transfer_setup(struct usb2_device *udev,
- const uint8_t *ifaces, struct usb2_xfer **ppxfer,
- const struct usb2_config *setup_start, uint16_t n_setup,
- void *priv_sc, struct mtx *xfer_mtx)
-{
- struct usb2_xfer dummy;
- struct usb2_setup_params parm;
- const struct usb2_config *setup_end = setup_start + n_setup;
- const struct usb2_config *setup;
- struct usb2_pipe *pipe;
- struct usb2_xfer_root *info;
- struct usb2_xfer *xfer;
- void *buf = NULL;
- uint16_t n;
- uint16_t refcount;
-
- parm.err = 0;
- refcount = 0;
- info = NULL;
-
- WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
- "usb2_transfer_setup can sleep!");
-
- /* do some checking first */
-
- if (n_setup == 0) {
- DPRINTFN(6, "setup array has zero length!\n");
- return (USB_ERR_INVAL);
- }
- if (ifaces == 0) {
- DPRINTFN(6, "ifaces array is NULL!\n");
- return (USB_ERR_INVAL);
- }
- if (xfer_mtx == NULL) {
- DPRINTFN(6, "using global lock\n");
- xfer_mtx = &Giant;
- }
- /* sanity checks */
- for (setup = setup_start, n = 0;
- setup != setup_end; setup++, n++) {
- if ((setup->mh.bufsize == 0xffffffff) ||
- (setup->md.bufsize == 0xffffffff)) {
- parm.err = USB_ERR_BAD_BUFSIZE;
- DPRINTF("invalid bufsize\n");
- }
- if ((setup->mh.callback == NULL) &&
- (setup->md.callback == NULL)) {
- parm.err = USB_ERR_NO_CALLBACK;
- DPRINTF("no callback\n");
- }
- ppxfer[n] = NULL;
- }
-
- if (parm.err) {
- goto done;
- }
- bzero(&parm, sizeof(parm));
-
- parm.udev = udev;
- parm.speed = usb2_get_speed(udev);
- parm.hc_max_packet_count = 1;
-
- if (parm.speed >= USB_SPEED_MAX) {
- parm.err = USB_ERR_INVAL;
- goto done;
- }
- /* setup all transfers */
-
- while (1) {
-
- if (buf) {
- /*
- * Initialize the "usb2_xfer_root" structure,
- * which is common for all our USB transfers.
- */
- info = USB_ADD_BYTES(buf, 0);
-
- info->memory_base = buf;
- info->memory_size = parm.size[0];
-
- info->dma_page_cache_start = USB_ADD_BYTES(buf, parm.size[4]);
- info->dma_page_cache_end = USB_ADD_BYTES(buf, parm.size[5]);
- info->xfer_page_cache_start = USB_ADD_BYTES(buf, parm.size[5]);
- info->xfer_page_cache_end = USB_ADD_BYTES(buf, parm.size[2]);
-
- usb2_cv_init(&info->cv_drain, "WDRAIN");
-
- info->xfer_mtx = xfer_mtx;
-
- usb2_dma_tag_setup(&info->dma_parent_tag,
- parm.dma_tag_p, udev->bus->dma_parent_tag[0].tag,
- xfer_mtx, &usb2_bdma_done_event, info, 32, parm.dma_tag_max);
-
- info->bus = udev->bus;
- info->udev = udev;
-
- TAILQ_INIT(&info->done_q.head);
- info->done_q.command = &usb2_callback_wrapper;
-
- TAILQ_INIT(&info->dma_q.head);
- info->dma_q.command = &usb2_bdma_work_loop;
-
- info->done_m[0].hdr.pm_callback = &usb2_callback_proc;
- info->done_m[0].xroot = info;
- info->done_m[1].hdr.pm_callback = &usb2_callback_proc;
- info->done_m[1].xroot = info;
-
- if (xfer_mtx == &Giant)
- info->done_p =
- &udev->bus->giant_callback_proc;
- else
- info->done_p =
- &udev->bus->non_giant_callback_proc;
- }
- /* reset sizes */
-
- parm.size[0] = 0;
- parm.buf = buf;
- parm.size[0] += sizeof(info[0]);
-
- for (setup = setup_start, n = 0;
- setup != setup_end; setup++, n++) {
-
- /* select mode specific structure */
- if (udev->flags.usb2_mode == USB_MODE_HOST) {
- parm.curr_setup_sub = &setup->mh;
- } else {
- parm.curr_setup_sub = &setup->md;
- }
- /* skip USB transfers without callbacks: */
- if (parm.curr_setup_sub->callback == NULL) {
- continue;
- }
- /* see if there is a matching endpoint */
- pipe = usb2_get_pipe(udev,
- ifaces[setup->if_index], setup);
-
- if (!pipe) {
- if (parm.curr_setup_sub->flags.no_pipe_ok) {
- continue;
- }
- parm.err = USB_ERR_NO_PIPE;
- goto done;
- }
- /* store current setup pointer */
- parm.curr_setup = setup;
-
- /* align data properly */
- parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
-
- if (buf) {
-
- /*
- * Common initialization of the
- * "usb2_xfer" structure.
- */
- xfer = USB_ADD_BYTES(buf, parm.size[0]);
-
- ppxfer[n] = xfer;
- xfer->address = udev->address;
- xfer->priv_sc = priv_sc;
- xfer->xroot = info;
- info->setup_refcount++;
-
- usb2_callout_init_mtx(&xfer->timeout_handle,
- &udev->bus->bus_mtx, 0);
- } else {
- /*
- * Setup a dummy xfer, hence we are
- * writing to the "usb2_xfer"
- * structure pointed to by "xfer"
- * before we have allocated any
- * memory:
- */
- xfer = &dummy;
- bzero(&dummy, sizeof(dummy));
- refcount++;
- }
-
- parm.size[0] += sizeof(xfer[0]);
-
- xfer->pipe = pipe;
-
- if (buf) {
- /*
- * Increment the pipe refcount. This
- * basically prevents setting a new
- * configuration and alternate setting
- * when USB transfers are in use on
- * the given interface. Search the USB
- * code for "pipe->refcount" if you
- * want more information.
- */
- xfer->pipe->refcount++;
- }
- parm.methods = xfer->pipe->methods;
- parm.curr_xfer = xfer;
-
- /*
- * Call the Host or Device controller transfer setup
- * routine:
- */
- (udev->bus->methods->xfer_setup) (&parm);
-
- if (parm.err) {
- goto done;
- }
- }
-
- if (buf || parm.err) {
- goto done;
- }
- if (refcount == 0) {
- /* no transfers - nothing to do ! */
- goto done;
- }
- /* align data properly */
- parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
-
- /* store offset temporarily */
- parm.size[1] = parm.size[0];
-
- /*
- * The number of DMA tags required depends on
- * the number of endpoints. The current estimate
- * for maximum number of DMA tags per endpoint
- * is two.
- */
- parm.dma_tag_max += 2 * MIN(n_setup, USB_EP_MAX);
-
- /*
- * DMA tags for QH, TD, Data and more.
- */
- parm.dma_tag_max += 8;
-
- parm.dma_tag_p += parm.dma_tag_max;
-
- parm.size[0] += ((uint8_t *)parm.dma_tag_p) -
- ((uint8_t *)0);
-
- /* align data properly */
- parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
-
- /* store offset temporarily */
- parm.size[3] = parm.size[0];
-
- parm.size[0] += ((uint8_t *)parm.dma_page_ptr) -
- ((uint8_t *)0);
-
- /* align data properly */
- parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
-
- /* store offset temporarily */
- parm.size[4] = parm.size[0];
-
- parm.size[0] += ((uint8_t *)parm.dma_page_cache_ptr) -
- ((uint8_t *)0);
-
- /* store end offset temporarily */
- parm.size[5] = parm.size[0];
-
- parm.size[0] += ((uint8_t *)parm.xfer_page_cache_ptr) -
- ((uint8_t *)0);
-
- /* store end offset temporarily */
-
- parm.size[2] = parm.size[0];
-
- /* align data properly */
- parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
-
- parm.size[6] = parm.size[0];
-
- parm.size[0] += ((uint8_t *)parm.xfer_length_ptr) -
- ((uint8_t *)0);
-
- /* align data properly */
- parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
-
- /* allocate zeroed memory */
- buf = malloc(parm.size[0], M_USB, M_WAITOK | M_ZERO);
-
- if (buf == NULL) {
- parm.err = USB_ERR_NOMEM;
- DPRINTFN(0, "cannot allocate memory block for "
- "configuration (%d bytes)\n",
- parm.size[0]);
- goto done;
- }
- parm.dma_tag_p = USB_ADD_BYTES(buf, parm.size[1]);
- parm.dma_page_ptr = USB_ADD_BYTES(buf, parm.size[3]);
- parm.dma_page_cache_ptr = USB_ADD_BYTES(buf, parm.size[4]);
- parm.xfer_page_cache_ptr = USB_ADD_BYTES(buf, parm.size[5]);
- parm.xfer_length_ptr = USB_ADD_BYTES(buf, parm.size[6]);
- }
-
-done:
- if (buf) {
- if (info->setup_refcount == 0) {
- /*
- * "usb2_transfer_unsetup_sub" will unlock
- * the bus mutex before returning !
- */
- USB_BUS_LOCK(info->bus);
-
- /* something went wrong */
- usb2_transfer_unsetup_sub(info, 0);
- }
- }
- if (parm.err) {
- usb2_transfer_unsetup(ppxfer, n_setup);
- }
- return (parm.err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_unsetup_sub - factored out code
- *------------------------------------------------------------------------*/
-static void
-usb2_transfer_unsetup_sub(struct usb2_xfer_root *info, uint8_t needs_delay)
-{
- struct usb2_page_cache *pc;
- uint32_t temp;
-
- USB_BUS_LOCK_ASSERT(info->bus, MA_OWNED);
-
- /* wait for any outstanding DMA operations */
-
- if (needs_delay) {
- temp = usb2_get_dma_delay(info->bus);
- usb2_pause_mtx(&info->bus->bus_mtx,
- USB_MS_TO_TICKS(temp));
- }
-
- /* make sure that our done messages are not queued anywhere */
- usb2_proc_mwait(info->done_p, &info->done_m[0], &info->done_m[1]);
-
- USB_BUS_UNLOCK(info->bus);
-
- /* free DMA'able memory, if any */
- pc = info->dma_page_cache_start;
- while (pc != info->dma_page_cache_end) {
- usb2_pc_free_mem(pc);
- pc++;
- }
-
- /* free DMA maps in all "xfer->frbuffers" */
- pc = info->xfer_page_cache_start;
- while (pc != info->xfer_page_cache_end) {
- usb2_pc_dmamap_destroy(pc);
- pc++;
- }
-
- /* free all DMA tags */
- usb2_dma_tag_unsetup(&info->dma_parent_tag);
-
- usb2_cv_destroy(&info->cv_drain);
-
- /*
- * free the "memory_base" last, hence the "info" structure is
- * contained within the "memory_base"!
- */
- free(info->memory_base, M_USB);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_unsetup - unsetup/free an array of USB transfers
- *
- * NOTE: All USB transfers in progress will get called back passing
- * the error code "USB_ERR_CANCELLED" before this function
- * returns.
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_unsetup(struct usb2_xfer **pxfer, uint16_t n_setup)
-{
- struct usb2_xfer *xfer;
- struct usb2_xfer_root *info;
- uint8_t needs_delay = 0;
-
- WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
- "usb2_transfer_unsetup can sleep!");
-
- while (n_setup--) {
- xfer = pxfer[n_setup];
-
- if (xfer) {
- if (xfer->pipe) {
- USB_XFER_LOCK(xfer);
- USB_BUS_LOCK(xfer->xroot->bus);
-
- /*
- * HINT: when you start/stop a transfer, it
- * might be a good idea to directly use the
- * "pxfer[]" structure:
- *
- * usb2_transfer_start(sc->pxfer[0]);
- * usb2_transfer_stop(sc->pxfer[0]);
- *
- * That way, if your code has many parts that
- * will not stop running under the same
- * lock, in other words "xfer_mtx", the
- * usb2_transfer_start and
- * usb2_transfer_stop functions will simply
- * return when they detect a NULL pointer
- * argument.
- *
- * To avoid any races we clear the "pxfer[]"
- * pointer while holding the private mutex
- * of the driver:
- */
- pxfer[n_setup] = NULL;
-
- USB_BUS_UNLOCK(xfer->xroot->bus);
- USB_XFER_UNLOCK(xfer);
-
- usb2_transfer_drain(xfer);
-
- if (xfer->flags_int.bdma_enable) {
- needs_delay = 1;
- }
- /*
- * NOTE: default pipe does not have an
- * interface, even if pipe->iface_index == 0
- */
- xfer->pipe->refcount--;
-
- } else {
- /* clear the transfer pointer */
- pxfer[n_setup] = NULL;
- }
-
- usb2_callout_drain(&xfer->timeout_handle);
-
- if (xfer->xroot) {
- info = xfer->xroot;
-
- USB_BUS_LOCK(info->bus);
-
- USB_ASSERT(info->setup_refcount != 0,
- ("Invalid setup "
- "reference count!\n"));
-
- info->setup_refcount--;
-
- if (info->setup_refcount == 0) {
- usb2_transfer_unsetup_sub(info,
- needs_delay);
- } else {
- USB_BUS_UNLOCK(info->bus);
- }
- }
- }
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_control_transfer_init - factored out code
- *
- * In USB Device Mode we have to wait for the SETUP packet which
- * containst the "struct usb2_device_request" structure, before we can
- * transfer any data. In USB Host Mode we already have the SETUP
- * packet at the moment the USB transfer is started. This leads us to
- * having to setup the USB transfer at two different places in
- * time. This function just contains factored out control transfer
- * initialisation code, so that we don't duplicate the code.
- *------------------------------------------------------------------------*/
-static void
-usb2_control_transfer_init(struct usb2_xfer *xfer)
-{
- struct usb2_device_request req;
-
- /* copy out the USB request header */
-
- usb2_copy_out(xfer->frbuffers, 0, &req, sizeof(req));
-
- /* setup remainder */
-
- xfer->flags_int.control_rem = UGETW(req.wLength);
-
- /* copy direction to endpoint variable */
-
- xfer->endpoint &= ~(UE_DIR_IN | UE_DIR_OUT);
- xfer->endpoint |=
- (req.bmRequestType & UT_READ) ? UE_DIR_IN : UE_DIR_OUT;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_start_hardware_sub
- *
- * This function handles initialisation of control transfers. Control
- * transfers are special in that regard that they can both transmit
- * and receive data.
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-usb2_start_hardware_sub(struct usb2_xfer *xfer)
-{
- uint32_t len;
-
- /* Check for control endpoint stall */
- if (xfer->flags.stall_pipe) {
- /* no longer active */
- xfer->flags_int.control_act = 0;
- }
- /*
- * Check if there is a control
- * transfer in progress:
- */
- if (xfer->flags_int.control_act) {
-
- if (xfer->flags_int.control_hdr) {
-
- /* clear send header flag */
-
- xfer->flags_int.control_hdr = 0;
-
- /* setup control transfer */
- if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
- usb2_control_transfer_init(xfer);
- }
- }
- /* get data length */
-
- len = xfer->sumlen;
-
- } else {
-
- /* the size of the SETUP structure is hardcoded ! */
-
- if (xfer->frlengths[0] != sizeof(struct usb2_device_request)) {
- DPRINTFN(0, "Wrong framelength %u != %zu\n",
- xfer->frlengths[0], sizeof(struct
- usb2_device_request));
- goto error;
- }
- /* check USB mode */
- if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
-
- /* check number of frames */
- if (xfer->nframes != 1) {
- /*
- * We need to receive the setup
- * message first so that we know the
- * data direction!
- */
- DPRINTF("Misconfigured transfer\n");
- goto error;
- }
- /*
- * Set a dummy "control_rem" value. This
- * variable will be overwritten later by a
- * call to "usb2_control_transfer_init()" !
- */
- xfer->flags_int.control_rem = 0xFFFF;
- } else {
-
- /* setup "endpoint" and "control_rem" */
-
- usb2_control_transfer_init(xfer);
- }
-
- /* set transfer-header flag */
-
- xfer->flags_int.control_hdr = 1;
-
- /* get data length */
-
- len = (xfer->sumlen - sizeof(struct usb2_device_request));
- }
-
- /* check if there is a length mismatch */
-
- if (len > xfer->flags_int.control_rem) {
- DPRINTFN(0, "Length greater than remaining length!\n");
- goto error;
- }
- /* check if we are doing a short transfer */
-
- if (xfer->flags.force_short_xfer) {
- xfer->flags_int.control_rem = 0;
- } else {
- if ((len != xfer->max_data_length) &&
- (len != xfer->flags_int.control_rem) &&
- (xfer->nframes != 1)) {
- DPRINTFN(0, "Short control transfer without "
- "force_short_xfer set!\n");
- goto error;
- }
- xfer->flags_int.control_rem -= len;
- }
-
- /* the status part is executed when "control_act" is 0 */
-
- if ((xfer->flags_int.control_rem > 0) ||
- (xfer->flags.manual_status)) {
- /* don't execute the STATUS stage yet */
- xfer->flags_int.control_act = 1;
-
- /* sanity check */
- if ((!xfer->flags_int.control_hdr) &&
- (xfer->nframes == 1)) {
- /*
- * This is not a valid operation!
- */
- DPRINTFN(0, "Invalid parameter "
- "combination\n");
- goto error;
- }
- } else {
- /* time to execute the STATUS stage */
- xfer->flags_int.control_act = 0;
- }
- return (0); /* success */
-
-error:
- return (1); /* failure */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_start_hardware - start USB hardware for the given transfer
- *
- * This function should only be called from the USB callback.
- *------------------------------------------------------------------------*/
-void
-usb2_start_hardware(struct usb2_xfer *xfer)
-{
- uint32_t x;
-
- DPRINTF("xfer=%p, pipe=%p, nframes=%d, dir=%s\n",
- xfer, xfer->pipe, xfer->nframes, USB_GET_DATA_ISREAD(xfer) ?
- "read" : "write");
-
-#if USB_DEBUG
- if (USB_DEBUG_VAR > 0) {
- USB_BUS_LOCK(xfer->xroot->bus);
-
- usb2_dump_pipe(xfer->pipe);
-
- USB_BUS_UNLOCK(xfer->xroot->bus);
- }
-#endif
-
- USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_NOTOWNED);
-
- /* Only open the USB transfer once! */
- if (!xfer->flags_int.open) {
- xfer->flags_int.open = 1;
-
- DPRINTF("open\n");
-
- USB_BUS_LOCK(xfer->xroot->bus);
- (xfer->pipe->methods->open) (xfer);
- USB_BUS_UNLOCK(xfer->xroot->bus);
- }
- /* set "transferring" flag */
- xfer->flags_int.transferring = 1;
-
- /* increment power reference */
- usb2_transfer_power_ref(xfer, 1);
-
- /*
- * Check if the transfer is waiting on a queue, most
- * frequently the "done_q":
- */
- if (xfer->wait_queue) {
- USB_BUS_LOCK(xfer->xroot->bus);
- usb2_transfer_dequeue(xfer);
- USB_BUS_UNLOCK(xfer->xroot->bus);
- }
- /* clear "did_dma_delay" flag */
- xfer->flags_int.did_dma_delay = 0;
-
- /* clear "did_close" flag */
- xfer->flags_int.did_close = 0;
-
- /* clear "bdma_setup" flag */
- xfer->flags_int.bdma_setup = 0;
-
- /* by default we cannot cancel any USB transfer immediately */
- xfer->flags_int.can_cancel_immed = 0;
-
- /* clear lengths and frame counts by default */
- xfer->sumlen = 0;
- xfer->actlen = 0;
- xfer->aframes = 0;
-
- /* clear any previous errors */
- xfer->error = 0;
-
- /* sanity check */
-
- if (xfer->nframes == 0) {
- if (xfer->flags.stall_pipe) {
- /*
- * Special case - want to stall without transferring
- * any data:
- */
- DPRINTF("xfer=%p nframes=0: stall "
- "or clear stall!\n", xfer);
- USB_BUS_LOCK(xfer->xroot->bus);
- xfer->flags_int.can_cancel_immed = 1;
- /* start the transfer */
- usb2_command_wrapper(&xfer->pipe->pipe_q, xfer);
- USB_BUS_UNLOCK(xfer->xroot->bus);
- return;
- }
- USB_BUS_LOCK(xfer->xroot->bus);
- usb2_transfer_done(xfer, USB_ERR_INVAL);
- USB_BUS_UNLOCK(xfer->xroot->bus);
- return;
- }
- /* compute total transfer length */
-
- for (x = 0; x != xfer->nframes; x++) {
- xfer->sumlen += xfer->frlengths[x];
- if (xfer->sumlen < xfer->frlengths[x]) {
- /* length wrapped around */
- USB_BUS_LOCK(xfer->xroot->bus);
- usb2_transfer_done(xfer, USB_ERR_INVAL);
- USB_BUS_UNLOCK(xfer->xroot->bus);
- return;
- }
- }
-
- /* clear some internal flags */
-
- xfer->flags_int.short_xfer_ok = 0;
- xfer->flags_int.short_frames_ok = 0;
-
- /* check if this is a control transfer */
-
- if (xfer->flags_int.control_xfr) {
-
- if (usb2_start_hardware_sub(xfer)) {
- USB_BUS_LOCK(xfer->xroot->bus);
- usb2_transfer_done(xfer, USB_ERR_STALLED);
- USB_BUS_UNLOCK(xfer->xroot->bus);
- return;
- }
- }
- /*
- * Setup filtered version of some transfer flags,
- * in case of data read direction
- */
- if (USB_GET_DATA_ISREAD(xfer)) {
-
- if (xfer->flags_int.control_xfr) {
-
- /*
- * Control transfers do not support reception
- * of multiple short USB frames !
- */
-
- if (xfer->flags.short_xfer_ok) {
- xfer->flags_int.short_xfer_ok = 1;
- }
- } else {
-
- if (xfer->flags.short_frames_ok) {
- xfer->flags_int.short_xfer_ok = 1;
- xfer->flags_int.short_frames_ok = 1;
- } else if (xfer->flags.short_xfer_ok) {
- xfer->flags_int.short_xfer_ok = 1;
- }
- }
- }
- /*
- * Check if BUS-DMA support is enabled and try to load virtual
- * buffers into DMA, if any:
- */
- if (xfer->flags_int.bdma_enable) {
- /* insert the USB transfer last in the BUS-DMA queue */
- usb2_command_wrapper(&xfer->xroot->dma_q, xfer);
- return;
- }
- /*
- * Enter the USB transfer into the Host Controller or
- * Device Controller schedule:
- */
- usb2_pipe_enter(xfer);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pipe_enter - factored out code
- *------------------------------------------------------------------------*/
-void
-usb2_pipe_enter(struct usb2_xfer *xfer)
-{
- struct usb2_pipe *pipe;
-
- USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
-
- USB_BUS_LOCK(xfer->xroot->bus);
-
- pipe = xfer->pipe;
-
- DPRINTF("enter\n");
-
- /* enter the transfer */
- (pipe->methods->enter) (xfer);
-
- /* check cancelability */
- if (pipe->methods->enter_is_cancelable) {
- xfer->flags_int.can_cancel_immed = 1;
- /* check for transfer error */
- if (xfer->error) {
- /* some error has happened */
- usb2_transfer_done(xfer, 0);
- USB_BUS_UNLOCK(xfer->xroot->bus);
- return;
- }
- } else {
- xfer->flags_int.can_cancel_immed = 0;
- }
-
- /* start the transfer */
- usb2_command_wrapper(&pipe->pipe_q, xfer);
- USB_BUS_UNLOCK(xfer->xroot->bus);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_start - start an USB transfer
- *
- * NOTE: Calling this function more than one time will only
- * result in a single transfer start, until the USB transfer
- * completes.
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_start(struct usb2_xfer *xfer)
-{
- if (xfer == NULL) {
- /* transfer is gone */
- return;
- }
- USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
-
- /* mark the USB transfer started */
-
- if (!xfer->flags_int.started) {
- xfer->flags_int.started = 1;
- }
- /* check if the USB transfer callback is already transferring */
-
- if (xfer->flags_int.transferring) {
- return;
- }
- USB_BUS_LOCK(xfer->xroot->bus);
- /* call the USB transfer callback */
- usb2_callback_ss_done_defer(xfer);
- USB_BUS_UNLOCK(xfer->xroot->bus);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_stop - stop an USB transfer
- *
- * NOTE: Calling this function more than one time will only
- * result in a single transfer stop.
- * NOTE: When this function returns it is not safe to free nor
- * reuse any DMA buffers. See "usb2_transfer_drain()".
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_stop(struct usb2_xfer *xfer)
-{
- struct usb2_pipe *pipe;
-
- if (xfer == NULL) {
- /* transfer is gone */
- return;
- }
- USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
-
- /* check if the USB transfer was ever opened */
-
- if (!xfer->flags_int.open) {
- /* nothing to do except clearing the "started" flag */
- xfer->flags_int.started = 0;
- return;
- }
- /* try to stop the current USB transfer */
-
- USB_BUS_LOCK(xfer->xroot->bus);
- xfer->error = USB_ERR_CANCELLED;/* override any previous error */
- /*
- * Clear "open" and "started" when both private and USB lock
- * is locked so that we don't get a race updating "flags_int"
- */
- xfer->flags_int.open = 0;
- xfer->flags_int.started = 0;
-
- /*
- * Check if we can cancel the USB transfer immediately.
- */
- if (xfer->flags_int.transferring) {
- if (xfer->flags_int.can_cancel_immed &&
- (!xfer->flags_int.did_close)) {
- DPRINTF("close\n");
- /*
- * The following will lead to an USB_ERR_CANCELLED
- * error code being passed to the USB callback.
- */
- (xfer->pipe->methods->close) (xfer);
- /* only close once */
- xfer->flags_int.did_close = 1;
- } else {
- /* need to wait for the next done callback */
- }
- } else {
- DPRINTF("close\n");
-
- /* close here and now */
- (xfer->pipe->methods->close) (xfer);
-
- /*
- * Any additional DMA delay is done by
- * "usb2_transfer_unsetup()".
- */
-
- /*
- * Special case. Check if we need to restart a blocked
- * pipe.
- */
- pipe = xfer->pipe;
-
- /*
- * If the current USB transfer is completing we need
- * to start the next one:
- */
- if (pipe->pipe_q.curr == xfer) {
- usb2_command_wrapper(&pipe->pipe_q, NULL);
- }
- }
-
- USB_BUS_UNLOCK(xfer->xroot->bus);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_pending
- *
- * This function will check if an USB transfer is pending which is a
- * little bit complicated!
- * Return values:
- * 0: Not pending
- * 1: Pending: The USB transfer will receive a callback in the future.
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_transfer_pending(struct usb2_xfer *xfer)
-{
- struct usb2_xfer_root *info;
- struct usb2_xfer_queue *pq;
-
- if (xfer == NULL) {
- /* transfer is gone */
- return (0);
- }
- USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
-
- if (xfer->flags_int.transferring) {
- /* trivial case */
- return (1);
- }
- USB_BUS_LOCK(xfer->xroot->bus);
- if (xfer->wait_queue) {
- /* we are waiting on a queue somewhere */
- USB_BUS_UNLOCK(xfer->xroot->bus);
- return (1);
- }
- info = xfer->xroot;
- pq = &info->done_q;
-
- if (pq->curr == xfer) {
- /* we are currently scheduled for callback */
- USB_BUS_UNLOCK(xfer->xroot->bus);
- return (1);
- }
- /* we are not pending */
- USB_BUS_UNLOCK(xfer->xroot->bus);
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_drain
- *
- * This function will stop the USB transfer and wait for any
- * additional BUS-DMA and HW-DMA operations to complete. Buffers that
- * are loaded into DMA can safely be freed or reused after that this
- * function has returned.
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_drain(struct usb2_xfer *xfer)
-{
- WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
- "usb2_transfer_drain can sleep!");
-
- if (xfer == NULL) {
- /* transfer is gone */
- return;
- }
- if (xfer->xroot->xfer_mtx != &Giant) {
- USB_XFER_LOCK_ASSERT(xfer, MA_NOTOWNED);
- }
- USB_XFER_LOCK(xfer);
-
- usb2_transfer_stop(xfer);
-
- while (usb2_transfer_pending(xfer)) {
- xfer->flags_int.draining = 1;
- /*
- * Wait until the current outstanding USB
- * transfer is complete !
- */
- usb2_cv_wait(&xfer->xroot->cv_drain, xfer->xroot->xfer_mtx);
- }
- USB_XFER_UNLOCK(xfer);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_set_frame_data
- *
- * This function sets the pointer of the buffer that should
- * loaded directly into DMA for the given USB frame. Passing "ptr"
- * equal to NULL while the corresponding "frlength" is greater
- * than zero gives undefined results!
- *------------------------------------------------------------------------*/
-void
-usb2_set_frame_data(struct usb2_xfer *xfer, void *ptr, uint32_t frindex)
-{
- /* set virtual address to load and length */
- xfer->frbuffers[frindex].buffer = ptr;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_set_frame_offset
- *
- * This function sets the frame data buffer offset relative to the beginning
- * of the USB DMA buffer allocated for this USB transfer.
- *------------------------------------------------------------------------*/
-void
-usb2_set_frame_offset(struct usb2_xfer *xfer, uint32_t offset,
- uint32_t frindex)
-{
- USB_ASSERT(!xfer->flags.ext_buffer, ("Cannot offset data frame "
- "when the USB buffer is external!\n"));
-
- /* set virtual address to load */
- xfer->frbuffers[frindex].buffer =
- USB_ADD_BYTES(xfer->local_buffer, offset);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_callback_proc - factored out code
- *
- * This function performs USB callbacks.
- *------------------------------------------------------------------------*/
-static void
-usb2_callback_proc(struct usb2_proc_msg *_pm)
-{
- struct usb2_done_msg *pm = (void *)_pm;
- struct usb2_xfer_root *info = pm->xroot;
-
- /* Change locking order */
- USB_BUS_UNLOCK(info->bus);
-
- /*
- * We exploit the fact that the mutex is the same for all
- * callbacks that will be called from this thread:
- */
- mtx_lock(info->xfer_mtx);
- USB_BUS_LOCK(info->bus);
-
- /* Continue where we lost track */
- usb2_command_wrapper(&info->done_q,
- info->done_q.curr);
-
- mtx_unlock(info->xfer_mtx);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_callback_ss_done_defer
- *
- * This function will defer the start, stop and done callback to the
- * correct thread.
- *------------------------------------------------------------------------*/
-static void
-usb2_callback_ss_done_defer(struct usb2_xfer *xfer)
-{
- struct usb2_xfer_root *info = xfer->xroot;
- struct usb2_xfer_queue *pq = &info->done_q;
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- if (pq->curr != xfer) {
- usb2_transfer_enqueue(pq, xfer);
- }
- if (!pq->recurse_1) {
-
- /*
- * We have to postpone the callback due to the fact we
- * will have a Lock Order Reversal, LOR, if we try to
- * proceed !
- */
- if (usb2_proc_msignal(info->done_p,
- &info->done_m[0], &info->done_m[1])) {
- /* ignore */
- }
- } else {
- /* clear second recurse flag */
- pq->recurse_2 = 0;
- }
- return;
-
-}
-
-/*------------------------------------------------------------------------*
- * usb2_callback_wrapper
- *
- * This is a wrapper for USB callbacks. This wrapper does some
- * auto-magic things like figuring out if we can call the callback
- * directly from the current context or if we need to wakeup the
- * interrupt process.
- *------------------------------------------------------------------------*/
-static void
-usb2_callback_wrapper(struct usb2_xfer_queue *pq)
-{
- struct usb2_xfer *xfer = pq->curr;
- struct usb2_xfer_root *info = xfer->xroot;
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
- if (!mtx_owned(xfer->xroot->xfer_mtx)) {
- /*
- * Cases that end up here:
- *
- * 5) HW interrupt done callback or other source.
- */
- DPRINTFN(3, "case 5\n");
-
- /*
- * We have to postpone the callback due to the fact we
- * will have a Lock Order Reversal, LOR, if we try to
- * proceed !
- */
- if (usb2_proc_msignal(info->done_p,
- &info->done_m[0], &info->done_m[1])) {
- /* ignore */
- }
- return;
- }
- /*
- * Cases that end up here:
- *
- * 1) We are starting a transfer
- * 2) We are prematurely calling back a transfer
- * 3) We are stopping a transfer
- * 4) We are doing an ordinary callback
- */
- DPRINTFN(3, "case 1-4\n");
- /* get next USB transfer in the queue */
- info->done_q.curr = NULL;
-
- USB_BUS_UNLOCK(xfer->xroot->bus);
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_NOTOWNED);
-
- /* set correct USB state for callback */
- if (!xfer->flags_int.transferring) {
- xfer->usb2_state = USB_ST_SETUP;
- if (!xfer->flags_int.started) {
- /* we got stopped before we even got started */
- USB_BUS_LOCK(xfer->xroot->bus);
- goto done;
- }
- } else {
-
- if (usb2_callback_wrapper_sub(xfer)) {
- /* the callback has been deferred */
- USB_BUS_LOCK(xfer->xroot->bus);
- goto done;
- }
- /* decrement power reference */
- usb2_transfer_power_ref(xfer, -1);
-
- xfer->flags_int.transferring = 0;
-
- if (xfer->error) {
- xfer->usb2_state = USB_ST_ERROR;
- } else {
- /* set transferred state */
- xfer->usb2_state = USB_ST_TRANSFERRED;
-
- /* sync DMA memory, if any */
- if (xfer->flags_int.bdma_enable &&
- (!xfer->flags_int.bdma_no_post_sync)) {
- usb2_bdma_post_sync(xfer);
- }
- }
- }
-
- /* call processing routine */
- (xfer->callback) (xfer);
-
- /* pickup the USB mutex again */
- USB_BUS_LOCK(xfer->xroot->bus);
-
- /*
- * Check if we got started after that we got cancelled, but
- * before we managed to do the callback.
- */
- if ((!xfer->flags_int.open) &&
- (xfer->flags_int.started) &&
- (xfer->usb2_state == USB_ST_ERROR)) {
- /* try to loop, but not recursivly */
- usb2_command_wrapper(&info->done_q, xfer);
- return;
- }
-
-done:
- /*
- * Check if we are draining.
- */
- if (xfer->flags_int.draining &&
- (!xfer->flags_int.transferring)) {
- /* "usb2_transfer_drain()" is waiting for end of transfer */
- xfer->flags_int.draining = 0;
- usb2_cv_broadcast(&xfer->xroot->cv_drain);
- }
-
- /* do the next callback, if any */
- usb2_command_wrapper(&info->done_q,
- info->done_q.curr);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_dma_delay_done_cb
- *
- * This function is called when the DMA delay has been exectuded, and
- * will make sure that the callback is called to complete the USB
- * transfer. This code path is ususally only used when there is an USB
- * error like USB_ERR_CANCELLED.
- *------------------------------------------------------------------------*/
-static void
-usb2_dma_delay_done_cb(void *arg)
-{
- struct usb2_xfer *xfer = arg;
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- DPRINTFN(3, "Completed %p\n", xfer);
-
- /* queue callback for execution, again */
- usb2_transfer_done(xfer, 0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_dequeue
- *
- * - This function is used to remove an USB transfer from a USB
- * transfer queue.
- *
- * - This function can be called multiple times in a row.
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_dequeue(struct usb2_xfer *xfer)
-{
- struct usb2_xfer_queue *pq;
-
- pq = xfer->wait_queue;
- if (pq) {
- TAILQ_REMOVE(&pq->head, xfer, wait_entry);
- xfer->wait_queue = NULL;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_enqueue
- *
- * - This function is used to insert an USB transfer into a USB *
- * transfer queue.
- *
- * - This function can be called multiple times in a row.
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_enqueue(struct usb2_xfer_queue *pq, struct usb2_xfer *xfer)
-{
- /*
- * Insert the USB transfer into the queue, if it is not
- * already on a USB transfer queue:
- */
- if (xfer->wait_queue == NULL) {
- xfer->wait_queue = pq;
- TAILQ_INSERT_TAIL(&pq->head, xfer, wait_entry);
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_done
- *
- * - This function is used to remove an USB transfer from the busdma,
- * pipe or interrupt queue.
- *
- * - This function is used to queue the USB transfer on the done
- * queue.
- *
- * - This function is used to stop any USB transfer timeouts.
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_done(struct usb2_xfer *xfer, usb2_error_t error)
-{
- struct usb2_xfer_queue *pq;
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- DPRINTF("err=%s\n", usb2_errstr(error));
-
- /*
- * If we are not transferring then just return.
- * This can happen during transfer cancel.
- */
- if (!xfer->flags_int.transferring) {
- DPRINTF("not transferring\n");
- return;
- }
- /* only set transfer error if not already set */
- if (!xfer->error) {
- xfer->error = error;
- }
- /* stop any callouts */
- usb2_callout_stop(&xfer->timeout_handle);
-
- /*
- * If we are waiting on a queue, just remove the USB transfer
- * from the queue, if any. We should have the required locks
- * locked to do the remove when this function is called.
- */
- usb2_transfer_dequeue(xfer);
-
- if (mtx_owned(xfer->xroot->xfer_mtx)) {
- /*
- * If the private USB lock is not locked, then we assume
- * that the BUS-DMA load stage has been passed:
- */
- pq = &xfer->xroot->dma_q;
-
- if (pq->curr == xfer) {
- /* start the next BUS-DMA load, if any */
- usb2_command_wrapper(pq, NULL);
- }
- }
- /* keep some statistics */
- if (xfer->error) {
- xfer->xroot->bus->stats_err.uds_requests
- [xfer->pipe->edesc->bmAttributes & UE_XFERTYPE]++;
- } else {
- xfer->xroot->bus->stats_ok.uds_requests
- [xfer->pipe->edesc->bmAttributes & UE_XFERTYPE]++;
- }
-
- /* call the USB transfer callback */
- usb2_callback_ss_done_defer(xfer);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_start_cb
- *
- * This function is called to start the USB transfer when
- * "xfer->interval" is greater than zero, and and the endpoint type is
- * BULK or CONTROL.
- *------------------------------------------------------------------------*/
-static void
-usb2_transfer_start_cb(void *arg)
-{
- struct usb2_xfer *xfer = arg;
- struct usb2_pipe *pipe = xfer->pipe;
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- DPRINTF("start\n");
-
- /* start the transfer */
- (pipe->methods->start) (xfer);
-
- /* check cancelability */
- if (pipe->methods->start_is_cancelable) {
- xfer->flags_int.can_cancel_immed = 1;
- if (xfer->error) {
- /* some error has happened */
- usb2_transfer_done(xfer, 0);
- }
- } else {
- xfer->flags_int.can_cancel_immed = 0;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_set_stall
- *
- * This function is used to set the stall flag outside the
- * callback. This function is NULL safe.
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_set_stall(struct usb2_xfer *xfer)
-{
- if (xfer == NULL) {
- /* tearing down */
- return;
- }
- USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
-
- /* avoid any races by locking the USB mutex */
- USB_BUS_LOCK(xfer->xroot->bus);
-
- xfer->flags.stall_pipe = 1;
-
- USB_BUS_UNLOCK(xfer->xroot->bus);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_clear_stall
- *
- * This function is used to clear the stall flag outside the
- * callback. This function is NULL safe.
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_clear_stall(struct usb2_xfer *xfer)
-{
- if (xfer == NULL) {
- /* tearing down */
- return;
- }
- USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
-
- /* avoid any races by locking the USB mutex */
- USB_BUS_LOCK(xfer->xroot->bus);
-
- xfer->flags.stall_pipe = 0;
-
- USB_BUS_UNLOCK(xfer->xroot->bus);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pipe_start
- *
- * This function is used to add an USB transfer to the pipe transfer list.
- *------------------------------------------------------------------------*/
-void
-usb2_pipe_start(struct usb2_xfer_queue *pq)
-{
- struct usb2_pipe *pipe;
- struct usb2_xfer *xfer;
- uint8_t type;
-
- xfer = pq->curr;
- pipe = xfer->pipe;
-
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- /*
- * If the pipe is already stalled we do nothing !
- */
- if (pipe->is_stalled) {
- return;
- }
- /*
- * Check if we are supposed to stall the pipe:
- */
- if (xfer->flags.stall_pipe) {
- /* clear stall command */
- xfer->flags.stall_pipe = 0;
-
- /*
- * Only stall BULK and INTERRUPT endpoints.
- */
- type = (pipe->edesc->bmAttributes & UE_XFERTYPE);
- if ((type == UE_BULK) ||
- (type == UE_INTERRUPT)) {
- struct usb2_device *udev;
- struct usb2_xfer_root *info;
-
- info = xfer->xroot;
- udev = info->udev;
- pipe->is_stalled = 1;
-
- if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
- (udev->bus->methods->set_stall) (
- udev, NULL, pipe);
- } else if (udev->default_xfer[1]) {
- info = udev->default_xfer[1]->xroot;
- if (usb2_proc_msignal(
- &info->bus->non_giant_callback_proc,
- &udev->cs_msg[0], &udev->cs_msg[1])) {
- /* ignore */
- }
- } else {
- /* should not happen */
- DPRINTFN(0, "No stall handler!\n");
- }
- /*
- * We get started again when the stall is cleared!
- */
- return;
- }
- }
- /* Set or clear stall complete - special case */
- if (xfer->nframes == 0) {
- /* we are complete */
- xfer->aframes = 0;
- usb2_transfer_done(xfer, 0);
- return;
- }
- /*
- * Handled cases:
- *
- * 1) Start the first transfer queued.
- *
- * 2) Re-start the current USB transfer.
- */
- /*
- * Check if there should be any
- * pre transfer start delay:
- */
- if (xfer->interval > 0) {
- type = (pipe->edesc->bmAttributes & UE_XFERTYPE);
- if ((type == UE_BULK) ||
- (type == UE_CONTROL)) {
- usb2_transfer_timeout_ms(xfer,
- &usb2_transfer_start_cb,
- xfer->interval);
- return;
- }
- }
- DPRINTF("start\n");
-
- /* start USB transfer */
- (pipe->methods->start) (xfer);
-
- /* check cancelability */
- if (pipe->methods->start_is_cancelable) {
- xfer->flags_int.can_cancel_immed = 1;
- if (xfer->error) {
- /* some error has happened */
- usb2_transfer_done(xfer, 0);
- }
- } else {
- xfer->flags_int.can_cancel_immed = 0;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_transfer_timeout_ms
- *
- * This function is used to setup a timeout on the given USB
- * transfer. If the timeout has been deferred the callback given by
- * "cb" will get called after "ms" milliseconds.
- *------------------------------------------------------------------------*/
-void
-usb2_transfer_timeout_ms(struct usb2_xfer *xfer,
- void (*cb) (void *arg), uint32_t ms)
-{
- USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
-
- /* defer delay */
- usb2_callout_reset(&xfer->timeout_handle,
- USB_MS_TO_TICKS(ms), cb, xfer);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_callback_wrapper_sub
- *
- * - This function will update variables in an USB transfer after
- * that the USB transfer is complete.
- *
- * - This function is used to start the next USB transfer on the
- * pipe transfer queue, if any.
- *
- * NOTE: In some special cases the USB transfer will not be removed from
- * the pipe queue, but remain first. To enforce USB transfer removal call
- * this function passing the error code "USB_ERR_CANCELLED".
- *
- * Return values:
- * 0: Success.
- * Else: The callback has been deferred.
- *------------------------------------------------------------------------*/
-static uint8_t
-usb2_callback_wrapper_sub(struct usb2_xfer *xfer)
-{
- struct usb2_pipe *pipe;
- uint32_t x;
-
- if ((!xfer->flags_int.open) &&
- (!xfer->flags_int.did_close)) {
- DPRINTF("close\n");
- USB_BUS_LOCK(xfer->xroot->bus);
- (xfer->pipe->methods->close) (xfer);
- USB_BUS_UNLOCK(xfer->xroot->bus);
- /* only close once */
- xfer->flags_int.did_close = 1;
- return (1); /* wait for new callback */
- }
- /*
- * If we have a non-hardware induced error we
- * need to do the DMA delay!
- */
- if (((xfer->error == USB_ERR_CANCELLED) ||
- (xfer->error == USB_ERR_TIMEOUT)) &&
- (!xfer->flags_int.did_dma_delay)) {
-
- uint32_t temp;
-
- /* only delay once */
- xfer->flags_int.did_dma_delay = 1;
-
- /* we can not cancel this delay */
- xfer->flags_int.can_cancel_immed = 0;
-
- temp = usb2_get_dma_delay(xfer->xroot->bus);
-
- DPRINTFN(3, "DMA delay, %u ms, "
- "on %p\n", temp, xfer);
-
- if (temp != 0) {
- USB_BUS_LOCK(xfer->xroot->bus);
- usb2_transfer_timeout_ms(xfer,
- &usb2_dma_delay_done_cb, temp);
- USB_BUS_UNLOCK(xfer->xroot->bus);
- return (1); /* wait for new callback */
- }
- }
- /* check actual number of frames */
- if (xfer->aframes > xfer->nframes) {
- if (xfer->error == 0) {
- panic("%s: actual number of frames, %d, is "
- "greater than initial number of frames, %d!\n",
- __FUNCTION__, xfer->aframes, xfer->nframes);
- } else {
- /* just set some valid value */
- xfer->aframes = xfer->nframes;
- }
- }
- /* compute actual length */
- xfer->actlen = 0;
-
- for (x = 0; x != xfer->aframes; x++) {
- xfer->actlen += xfer->frlengths[x];
- }
-
- /*
- * Frames that were not transferred get zero actual length in
- * case the USB device driver does not check the actual number
- * of frames transferred, "xfer->aframes":
- */
- for (; x < xfer->nframes; x++) {
- xfer->frlengths[x] = 0;
- }
-
- /* check actual length */
- if (xfer->actlen > xfer->sumlen) {
- if (xfer->error == 0) {
- panic("%s: actual length, %d, is greater than "
- "initial length, %d!\n",
- __FUNCTION__, xfer->actlen, xfer->sumlen);
- } else {
- /* just set some valid value */
- xfer->actlen = xfer->sumlen;
- }
- }
- DPRINTFN(6, "xfer=%p pipe=%p sts=%d alen=%d, slen=%d, afrm=%d, nfrm=%d\n",
- xfer, xfer->pipe, xfer->error, xfer->actlen, xfer->sumlen,
- xfer->aframes, xfer->nframes);
-
- if (xfer->error) {
- /* end of control transfer, if any */
- xfer->flags_int.control_act = 0;
-
- /* check if we should block the execution queue */
- if ((xfer->error != USB_ERR_CANCELLED) &&
- (xfer->flags.pipe_bof)) {
- DPRINTFN(2, "xfer=%p: Block On Failure "
- "on pipe=%p\n", xfer, xfer->pipe);
- goto done;
- }
- } else {
- /* check for short transfers */
- if (xfer->actlen < xfer->sumlen) {
-
- /* end of control transfer, if any */
- xfer->flags_int.control_act = 0;
-
- if (!xfer->flags_int.short_xfer_ok) {
- xfer->error = USB_ERR_SHORT_XFER;
- if (xfer->flags.pipe_bof) {
- DPRINTFN(2, "xfer=%p: Block On Failure on "
- "Short Transfer on pipe %p.\n",
- xfer, xfer->pipe);
- goto done;
- }
- }
- } else {
- /*
- * Check if we are in the middle of a
- * control transfer:
- */
- if (xfer->flags_int.control_act) {
- DPRINTFN(5, "xfer=%p: Control transfer "
- "active on pipe=%p\n", xfer, xfer->pipe);
- goto done;
- }
- }
- }
-
- pipe = xfer->pipe;
-
- /*
- * If the current USB transfer is completing we need to start the
- * next one:
- */
- USB_BUS_LOCK(xfer->xroot->bus);
- if (pipe->pipe_q.curr == xfer) {
- usb2_command_wrapper(&pipe->pipe_q, NULL);
-
- if (pipe->pipe_q.curr || TAILQ_FIRST(&pipe->pipe_q.head)) {
- /* there is another USB transfer waiting */
- } else {
- /* this is the last USB transfer */
- /* clear isochronous sync flag */
- xfer->pipe->is_synced = 0;
- }
- }
- USB_BUS_UNLOCK(xfer->xroot->bus);
-done:
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_command_wrapper
- *
- * This function is used to execute commands non-recursivly on an USB
- * transfer.
- *------------------------------------------------------------------------*/
-void
-usb2_command_wrapper(struct usb2_xfer_queue *pq, struct usb2_xfer *xfer)
-{
- if (xfer) {
- /*
- * If the transfer is not already processing,
- * queue it!
- */
- if (pq->curr != xfer) {
- usb2_transfer_enqueue(pq, xfer);
- if (pq->curr != NULL) {
- /* something is already processing */
- DPRINTFN(6, "busy %p\n", pq->curr);
- return;
- }
- }
- } else {
- /* Get next element in queue */
- pq->curr = NULL;
- }
-
- if (!pq->recurse_1) {
-
- do {
-
- /* set both recurse flags */
- pq->recurse_1 = 1;
- pq->recurse_2 = 1;
-
- if (pq->curr == NULL) {
- xfer = TAILQ_FIRST(&pq->head);
- if (xfer) {
- TAILQ_REMOVE(&pq->head, xfer,
- wait_entry);
- xfer->wait_queue = NULL;
- pq->curr = xfer;
- } else {
- break;
- }
- }
- DPRINTFN(6, "cb %p (enter)\n", pq->curr);
- (pq->command) (pq);
- DPRINTFN(6, "cb %p (leave)\n", pq->curr);
-
- } while (!pq->recurse_2);
-
- /* clear first recurse flag */
- pq->recurse_1 = 0;
-
- } else {
- /* clear second recurse flag */
- pq->recurse_2 = 0;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_default_transfer_setup
- *
- * This function is used to setup the default USB control endpoint
- * transfer.
- *------------------------------------------------------------------------*/
-void
-usb2_default_transfer_setup(struct usb2_device *udev)
-{
- struct usb2_xfer *xfer;
- uint8_t no_resetup;
- uint8_t iface_index;
-
-repeat:
-
- xfer = udev->default_xfer[0];
- if (xfer) {
- USB_XFER_LOCK(xfer);
- no_resetup =
- ((xfer->address == udev->address) &&
- (udev->default_ep_desc.wMaxPacketSize[0] ==
- udev->ddesc.bMaxPacketSize));
- if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
- if (no_resetup) {
- /*
- * NOTE: checking "xfer->address" and
- * starting the USB transfer must be
- * atomic!
- */
- usb2_transfer_start(xfer);
- }
- }
- USB_XFER_UNLOCK(xfer);
- } else {
- no_resetup = 0;
- }
-
- if (no_resetup) {
- /*
- * All parameters are exactly the same like before.
- * Just return.
- */
- return;
- }
- /*
- * Update wMaxPacketSize for the default control endpoint:
- */
- udev->default_ep_desc.wMaxPacketSize[0] =
- udev->ddesc.bMaxPacketSize;
-
- /*
- * Unsetup any existing USB transfer:
- */
- usb2_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
-
- /*
- * Try to setup a new USB transfer for the
- * default control endpoint:
- */
- iface_index = 0;
- if (usb2_transfer_setup(udev, &iface_index,
- udev->default_xfer, usb2_control_ep_cfg, USB_DEFAULT_XFER_MAX, NULL,
- udev->default_mtx)) {
- DPRINTFN(0, "could not setup default "
- "USB transfer!\n");
- } else {
- goto repeat;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_clear_data_toggle - factored out code
- *
- * NOTE: the intention of this function is not to reset the hardware
- * data toggle.
- *------------------------------------------------------------------------*/
-void
-usb2_clear_data_toggle(struct usb2_device *udev, struct usb2_pipe *pipe)
-{
- DPRINTFN(5, "udev=%p pipe=%p\n", udev, pipe);
-
- USB_BUS_LOCK(udev->bus);
- pipe->toggle_next = 0;
- USB_BUS_UNLOCK(udev->bus);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_clear_stall_callback - factored out clear stall callback
- *
- * Input parameters:
- * xfer1: Clear Stall Control Transfer
- * xfer2: Stalled USB Transfer
- *
- * This function is NULL safe.
- *
- * Return values:
- * 0: In progress
- * Else: Finished
- *
- * Clear stall config example:
- *
- * static const struct usb2_config my_clearstall = {
- * .type = UE_CONTROL,
- * .endpoint = 0,
- * .direction = UE_DIR_ANY,
- * .interval = 50, //50 milliseconds
- * .bufsize = sizeof(struct usb2_device_request),
- * .mh.timeout = 1000, //1.000 seconds
- * .mh.flags = { },
- * .mh.callback = &my_clear_stall_callback, // **
- * };
- *
- * ** "my_clear_stall_callback" calls "usb2_clear_stall_callback"
- * passing the correct parameters.
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_clear_stall_callback(struct usb2_xfer *xfer1,
- struct usb2_xfer *xfer2)
-{
- struct usb2_device_request req;
-
- if (xfer2 == NULL) {
- /* looks like we are tearing down */
- DPRINTF("NULL input parameter\n");
- return (0);
- }
- USB_XFER_LOCK_ASSERT(xfer1, MA_OWNED);
- USB_XFER_LOCK_ASSERT(xfer2, MA_OWNED);
-
- switch (USB_GET_STATE(xfer1)) {
- case USB_ST_SETUP:
-
- /*
- * pre-clear the data toggle to DATA0 ("umass.c" and
- * "ata-usb.c" depends on this)
- */
-
- usb2_clear_data_toggle(xfer2->xroot->udev, xfer2->pipe);
-
- /* setup a clear-stall packet */
-
- req.bmRequestType = UT_WRITE_ENDPOINT;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, UF_ENDPOINT_HALT);
- req.wIndex[0] = xfer2->pipe->edesc->bEndpointAddress;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- /*
- * "usb2_transfer_setup_sub()" will ensure that
- * we have sufficient room in the buffer for
- * the request structure!
- */
-
- /* copy in the transfer */
-
- usb2_copy_in(xfer1->frbuffers, 0, &req, sizeof(req));
-
- /* set length */
- xfer1->frlengths[0] = sizeof(req);
- xfer1->nframes = 1;
-
- usb2_start_hardware(xfer1);
- return (0);
-
- case USB_ST_TRANSFERRED:
- break;
-
- default: /* Error */
- if (xfer1->error == USB_ERR_CANCELLED) {
- return (0);
- }
- break;
- }
- return (1); /* Clear Stall Finished */
-}
-
-#if (USB_NO_POLL == 0)
-
-/*------------------------------------------------------------------------*
- * usb2_callout_poll
- *------------------------------------------------------------------------*/
-static void
-usb2_callout_poll(struct usb2_xfer *xfer)
-{
- struct usb2_callout *co;
- void (*cb) (void *);
- void *arg;
- struct mtx *mtx;
- uint32_t delta;
-
- if (xfer == NULL) {
- return;
- }
- co = &xfer->timeout_handle;
-
-#if __FreeBSD_version >= 800000
- mtx = (void *)(co->co.c_lock);
-#else
- mtx = co->co.c_mtx;
-#endif
- mtx_lock(mtx);
-
- if (usb2_callout_pending(co)) {
- delta = ticks - co->co.c_time;
- if (!(delta & 0x80000000)) {
-
- cb = co->co.c_func;
- arg = co->co.c_arg;
-
- /* timed out */
- usb2_callout_stop(co);
-
- (cb) (arg);
- }
- }
- mtx_unlock(mtx);
-}
-
-
-/*------------------------------------------------------------------------*
- * usb2_do_poll
- *
- * This function is called from keyboard driver when in polling
- * mode.
- *------------------------------------------------------------------------*/
-void
-usb2_do_poll(struct usb2_xfer **ppxfer, uint16_t max)
-{
- struct usb2_xfer *xfer;
- struct usb2_xfer_root *xroot;
- struct usb2_device *udev;
- struct usb2_proc_msg *pm;
- uint32_t to;
- uint16_t n;
-
- /* compute system tick delay */
- to = ((uint32_t)(1000000)) / ((uint32_t)(hz));
- DELAY(to);
- atomic_add_int((volatile int *)&ticks, 1);
-
- for (n = 0; n != max; n++) {
- xfer = ppxfer[n];
- if (xfer) {
- xroot = xfer->xroot;
- udev = xroot->udev;
-
- /*
- * Poll hardware - signal that we are polling by
- * locking the private mutex:
- */
- USB_XFER_LOCK(xfer);
- (udev->bus->methods->do_poll) (udev->bus);
- USB_XFER_UNLOCK(xfer);
-
- /* poll clear stall start */
- USB_BUS_LOCK(xfer->xroot->bus);
- pm = &udev->cs_msg[0].hdr;
- (pm->pm_callback) (pm);
- USB_BUS_UNLOCK(xfer->xroot->bus);
-
- if (udev->default_xfer[1]) {
-
- /* poll timeout */
- usb2_callout_poll(udev->default_xfer[1]);
-
- /* poll clear stall done thread */
- USB_BUS_LOCK(xfer->xroot->bus);
- pm = &udev->default_xfer[1]->
- xroot->done_m[0].hdr;
- (pm->pm_callback) (pm);
- USB_BUS_UNLOCK(xfer->xroot->bus);
- }
- /* poll timeout */
- usb2_callout_poll(xfer);
-
- /* poll done thread */
- USB_BUS_LOCK(xfer->xroot->bus);
- pm = &xroot->done_m[0].hdr;
- (pm->pm_callback) (pm);
- USB_BUS_UNLOCK(xfer->xroot->bus);
- }
- }
-}
-
-#else
-
-void
-usb2_do_poll(struct usb2_xfer **ppxfer, uint16_t max)
-{
- /* polling not supported */
-}
-
-#endif
diff --git a/sys/dev/usb2/core/usb2_transfer.h b/sys/dev/usb2/core/usb2_transfer.h
deleted file mode 100644
index 34124c5..0000000
--- a/sys/dev/usb2/core/usb2_transfer.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_TRANSFER_H_
-#define _USB2_TRANSFER_H_
-
-/*
- * The following structure defines the messages that is used to signal
- * the "done_p" USB process.
- */
-struct usb2_done_msg {
- struct usb2_proc_msg hdr;
- struct usb2_xfer_root *xroot;
-};
-
-/*
- * The following structure is used to keep information about memory
- * that should be automatically freed at the moment all USB transfers
- * have been freed.
- */
-struct usb2_xfer_root {
- struct usb2_xfer_queue dma_q;
- struct usb2_xfer_queue done_q;
- struct usb2_done_msg done_m[2];
- struct cv cv_drain;
- struct usb2_dma_parent_tag dma_parent_tag;
-
- struct usb2_process *done_p; /* pointer to callback process */
- void *memory_base;
- struct mtx *xfer_mtx; /* cannot be changed during operation */
- struct usb2_page_cache *dma_page_cache_start;
- struct usb2_page_cache *dma_page_cache_end;
- struct usb2_page_cache *xfer_page_cache_start;
- struct usb2_page_cache *xfer_page_cache_end;
- struct usb2_bus *bus; /* pointer to USB bus (cached) */
- struct usb2_device *udev; /* pointer to USB device */
-
- uint32_t memory_size;
- uint32_t setup_refcount;
- uint32_t page_size;
- uint32_t dma_nframes; /* number of page caches to load */
- uint32_t dma_currframe; /* currect page cache number */
- uint32_t dma_frlength_0; /* length of page cache zero */
- uint8_t dma_error; /* set if virtual memory could not be
- * loaded */
- uint8_t done_sleep; /* set if done thread is sleeping */
-};
-
-/*
- * The following structure is used when setting up an array of USB
- * transfers.
- */
-struct usb2_setup_params {
- struct usb2_dma_tag *dma_tag_p;
- struct usb2_page *dma_page_ptr;
- struct usb2_page_cache *dma_page_cache_ptr; /* these will be
- * auto-freed */
- struct usb2_page_cache *xfer_page_cache_ptr; /* these will not be
- * auto-freed */
- struct usb2_device *udev;
- struct usb2_xfer *curr_xfer;
- const struct usb2_config *curr_setup;
- const struct usb2_config_sub *curr_setup_sub;
- const struct usb2_pipe_methods *methods;
- void *buf;
- uint32_t *xfer_length_ptr;
-
- uint32_t size[7];
- uint32_t bufsize;
- uint32_t bufsize_max;
- uint32_t hc_max_frame_size;
-
- uint16_t hc_max_packet_size;
- uint8_t hc_max_packet_count;
- uint8_t speed;
- uint8_t dma_tag_max;
- usb2_error_t err;
-};
-
-/* function prototypes */
-
-uint8_t usb2_transfer_setup_sub_malloc(struct usb2_setup_params *parm,
- struct usb2_page_cache **ppc, uint32_t size, uint32_t align,
- uint32_t count);
-void usb2_command_wrapper(struct usb2_xfer_queue *pq,
- struct usb2_xfer *xfer);
-void usb2_pipe_enter(struct usb2_xfer *xfer);
-void usb2_pipe_start(struct usb2_xfer_queue *pq);
-void usb2_transfer_dequeue(struct usb2_xfer *xfer);
-void usb2_transfer_done(struct usb2_xfer *xfer, usb2_error_t error);
-void usb2_transfer_enqueue(struct usb2_xfer_queue *pq,
- struct usb2_xfer *xfer);
-void usb2_transfer_setup_sub(struct usb2_setup_params *parm);
-void usb2_default_transfer_setup(struct usb2_device *udev);
-void usb2_clear_data_toggle(struct usb2_device *udev,
- struct usb2_pipe *pipe);
-void usb2_do_poll(struct usb2_xfer **ppxfer, uint16_t max);
-usb2_callback_t usb2_do_request_callback;
-usb2_callback_t usb2_handle_request_callback;
-usb2_callback_t usb2_do_clear_stall_callback;
-void usb2_transfer_timeout_ms(struct usb2_xfer *xfer,
- void (*cb) (void *arg), uint32_t ms);
-uint32_t usb2_get_dma_delay(struct usb2_bus *bus);
-void usb2_transfer_power_ref(struct usb2_xfer *xfer, int val);
-
-#endif /* _USB2_TRANSFER_H_ */
diff --git a/sys/dev/usb2/core/usb2_util.c b/sys/dev/usb2/core/usb2_util.c
deleted file mode 100644
index 5dca332..0000000
--- a/sys/dev/usb2/core/usb2_util.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-
-/* function prototypes */
-#if (USB_USE_CONDVAR == 0)
-static int usb2_msleep(void *chan, struct mtx *mtx, int priority, const char *wmesg, int timo);
-
-#endif
-
-/*------------------------------------------------------------------------*
- * device_delete_all_children - delete all children of a device
- *------------------------------------------------------------------------*/
-int
-device_delete_all_children(device_t dev)
-{
- device_t *devlist;
- int devcount;
- int error;
-
- error = device_get_children(dev, &devlist, &devcount);
- if (error == 0) {
- while (devcount-- > 0) {
- error = device_delete_child(dev, devlist[devcount]);
- if (error) {
- break;
- }
- }
- free(devlist, M_TEMP);
- }
- return (error);
-}
-
-/*------------------------------------------------------------------------*
- * device_set_usb2_desc
- *
- * This function can be called at probe or attach to set the USB
- * device supplied textual description for the given device.
- *------------------------------------------------------------------------*/
-void
-device_set_usb2_desc(device_t dev)
-{
- struct usb2_attach_arg *uaa;
- struct usb2_device *udev;
- struct usb2_interface *iface;
- char *temp_p;
- usb2_error_t err;
-
- if (dev == NULL) {
- /* should not happen */
- return;
- }
- uaa = device_get_ivars(dev);
- if (uaa == NULL) {
- /* can happen if called at the wrong time */
- return;
- }
- udev = uaa->device;
- iface = uaa->iface;
-
- if ((iface == NULL) ||
- (iface->idesc == NULL) ||
- (iface->idesc->iInterface == 0)) {
- err = USB_ERR_INVAL;
- } else {
- err = 0;
- }
-
- temp_p = (char *)udev->bus->scratch[0].data;
-
- if (!err) {
- /* try to get the interface string ! */
- err = usb2_req_get_string_any
- (udev, NULL, temp_p,
- sizeof(udev->bus->scratch), iface->idesc->iInterface);
- }
- if (err) {
- /* use default description */
- usb2_devinfo(udev, temp_p,
- sizeof(udev->bus->scratch));
- }
- device_set_desc_copy(dev, temp_p);
- device_printf(dev, "<%s> on %s\n", temp_p,
- device_get_nameunit(udev->bus->bdev));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_pause_mtx - factored out code
- *
- * This function will delay the code by the passed number of system
- * ticks. The passed mutex "mtx" will be dropped while waiting, if
- * "mtx" is not NULL.
- *------------------------------------------------------------------------*/
-void
-usb2_pause_mtx(struct mtx *mtx, int _ticks)
-{
- if (mtx != NULL)
- mtx_unlock(mtx);
-
- if (cold) {
- /* convert to milliseconds */
- _ticks = (_ticks * 1000) / hz;
- /* convert to microseconds, rounded up */
- _ticks = (_ticks + 1) * 1000;
- DELAY(_ticks);
-
- } else {
-
- /*
- * Add one to the number of ticks so that we don't return
- * too early!
- */
- _ticks++;
-
- if (pause("USBWAIT", _ticks)) {
- /* ignore */
- }
- }
- if (mtx != NULL)
- mtx_lock(mtx);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_printBCD
- *
- * This function will print the version number "bcd" to the string
- * pointed to by "p" having a maximum length of "p_len" bytes
- * including the terminating zero.
- *------------------------------------------------------------------------*/
-void
-usb2_printBCD(char *p, uint16_t p_len, uint16_t bcd)
-{
- if (snprintf(p, p_len, "%x.%02x", bcd >> 8, bcd & 0xff)) {
- /* ignore any errors */
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_trim_spaces
- *
- * This function removes spaces at the beginning and the end of the string
- * pointed to by the "p" argument.
- *------------------------------------------------------------------------*/
-void
-usb2_trim_spaces(char *p)
-{
- char *q;
- char *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 */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_get_devid
- *
- * This function returns the USB Vendor and Product ID like a 32-bit
- * unsigned integer.
- *------------------------------------------------------------------------*/
-uint32_t
-usb2_get_devid(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- return ((uaa->info.idVendor << 16) | (uaa->info.idProduct));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_make_str_desc - convert an ASCII string into a UNICODE string
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_make_str_desc(void *ptr, uint16_t max_len, const char *s)
-{
- struct usb2_string_descriptor *p = ptr;
- uint8_t totlen;
- int j;
-
- if (max_len < 2) {
- /* invalid length */
- return (0);
- }
- max_len = ((max_len / 2) - 1);
-
- j = strlen(s);
-
- if (j < 0) {
- j = 0;
- }
- if (j > 126) {
- j = 126;
- }
- if (max_len > j) {
- max_len = j;
- }
- totlen = (max_len + 1) * 2;
-
- p->bLength = totlen;
- p->bDescriptorType = UDESC_STRING;
-
- while (max_len--) {
- USETW2(p->bString[max_len], 0, s[max_len]);
- }
- return (totlen);
-}
-
-#if (USB_USE_CONDVAR == 0)
-
-/*------------------------------------------------------------------------*
- * usb2_cv_init - wrapper function
- *------------------------------------------------------------------------*/
-void
-usb2_cv_init(struct cv *cv, const char *desc)
-{
- cv_init(cv, desc);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_cv_destroy - wrapper function
- *------------------------------------------------------------------------*/
-void
-usb2_cv_destroy(struct cv *cv)
-{
- cv_destroy(cv);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_cv_wait - wrapper function
- *------------------------------------------------------------------------*/
-void
-usb2_cv_wait(struct cv *cv, struct mtx *mtx)
-{
- int err;
-
- err = usb2_msleep(cv, mtx, 0, cv_wmesg(cv), 0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_cv_wait_sig - wrapper function
- *------------------------------------------------------------------------*/
-int
-usb2_cv_wait_sig(struct cv *cv, struct mtx *mtx)
-{
- int err;
-
- err = usb2_msleep(cv, mtx, PCATCH, cv_wmesg(cv), 0);
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_cv_timedwait - wrapper function
- *------------------------------------------------------------------------*/
-int
-usb2_cv_timedwait(struct cv *cv, struct mtx *mtx, int timo)
-{
- int err;
-
- if (timo == 0)
- timo = 1; /* zero means no timeout */
- err = usb2_msleep(cv, mtx, 0, cv_wmesg(cv), timo);
- return (err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_cv_signal - wrapper function
- *------------------------------------------------------------------------*/
-void
-usb2_cv_signal(struct cv *cv)
-{
- wakeup_one(cv);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_cv_broadcast - wrapper function
- *------------------------------------------------------------------------*/
-void
-usb2_cv_broadcast(struct cv *cv)
-{
- wakeup(cv);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_msleep - wrapper function
- *------------------------------------------------------------------------*/
-static int
-usb2_msleep(void *chan, struct mtx *mtx, int priority, const char *wmesg,
- int timo)
-{
- int err;
-
- if (mtx == &Giant) {
- err = tsleep(chan, priority, wmesg, timo);
- } else {
-#ifdef mtx_sleep
- err = mtx_sleep(chan, mtx, priority, wmesg, timo);
-#else
- err = msleep(chan, mtx, priority, wmesg, timo);
-#endif
- }
- return (err);
-}
-
-#endif
diff --git a/sys/dev/usb2/core/usb2_util.h b/sys/dev/usb2/core/usb2_util.h
deleted file mode 100644
index e081c31..0000000
--- a/sys/dev/usb2/core/usb2_util.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_UTIL_H_
-#define _USB2_UTIL_H_
-
-int device_delete_all_children(device_t dev);
-uint32_t usb2_get_devid(device_t dev);
-uint8_t usb2_make_str_desc(void *ptr, uint16_t max_len, const char *s);
-void device_set_usb2_desc(device_t dev);
-void usb2_pause_mtx(struct mtx *mtx, int _ticks);
-void usb2_printBCD(char *p, uint16_t p_len, uint16_t bcd);
-void usb2_trim_spaces(char *p);
-
-#if (USB_USE_CONDVAR == 0)
-void usb2_cv_init(struct cv *cv, const char *desc);
-void usb2_cv_destroy(struct cv *cv);
-void usb2_cv_wait(struct cv *cv, struct mtx *mtx);
-int usb2_cv_wait_sig(struct cv *cv, struct mtx *mtx);
-int usb2_cv_timedwait(struct cv *cv, struct mtx *mtx, int timo);
-void usb2_cv_signal(struct cv *cv);
-void usb2_cv_broadcast(struct cv *cv);
-
-#else
-#define usb2_cv_init cv_init
-#define usb2_cv_destroy cv_destroy
-#define usb2_cv_wait cv_wait
-#define usb2_cv_wait_sig cv_wait_sig
-#define usb2_cv_timedwait cv_timedwait
-#define usb2_cv_signal cv_signal
-#define usb2_cv_broadcast cv_broadcast
-#endif
-
-#endif /* _USB2_UTIL_H_ */
diff --git a/sys/dev/usb2/ethernet/if_aue2.c b/sys/dev/usb2/ethernet/if_aue2.c
deleted file mode 100644
index c280e5e..0000000
--- a/sys/dev/usb2/ethernet/if_aue2.c
+++ /dev/null
@@ -1,1054 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
- *
- * Copyright (c) 2006
- * Alfred Perlstein <alfred@freebsd.org>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * ADMtek AN986 Pegasus and AN8511 Pegasus II USB to ethernet driver.
- * Datasheet is available from http://www.admtek.com.tw.
- *
- * Written by Bill Paul <wpaul@ee.columbia.edu>
- * Electrical Engineering Department
- * Columbia University, New York City
- *
- * SMP locking by Alfred Perlstein <alfred@freebsd.org>.
- * RED Inc.
- */
-
-/*
- * The Pegasus chip uses four USB "endpoints" to provide 10/100 ethernet
- * support: the control endpoint for reading/writing registers, burst
- * read endpoint for packet reception, burst write for packet transmission
- * and one for "interrupts." The chip uses the same RX filter scheme
- * as the other ADMtek ethernet parts: one perfect filter entry for the
- * the station address and a 64-bit multicast hash table. The chip supports
- * both MII and HomePNA attachments.
- *
- * Since the maximum data transfer speed of USB is supposed to be 12Mbps,
- * you're never really going to get 100Mbps speeds from this device. I
- * think the idea is to allow the device to connect to 10 or 100Mbps
- * networks, not necessarily to provide 100Mbps performance. Also, since
- * the controller uses an external PHY chip, it's possible that board
- * designers might simply choose a 10Mbps PHY.
- *
- * Registers are accessed using usb2_ether_do_request(). Packet
- * transfers are done using usb2_transfer() and friends.
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR aue_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_auereg.h>
-
-#if USB_DEBUG
-static int aue_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, aue, CTLFLAG_RW, 0, "USB aue");
-SYSCTL_INT(_hw_usb2_aue, OID_AUTO, debug, CTLFLAG_RW, &aue_debug, 0,
- "Debug level");
-#endif
-
-/*
- * Various supported device vendors/products.
- */
-static const struct usb2_device_id aue_devs[] = {
- {USB_VPI(USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460B, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_DSB650TX_PNA, 0)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE1000, AUE_FLAG_LSYS)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX10, 0)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1, AUE_FLAG_PNA | AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX2, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX4, AUE_FLAG_PNA)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX5, AUE_FLAG_PNA)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX6, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX7, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX8, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX9, AUE_FLAG_PNA)},
- {USB_VPI(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SS1001, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_USB320_EC, 0)},
- {USB_VPI(USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_2, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_3, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_4, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS, AUE_FLAG_PNA | AUE_FLAG_DUAL_PHY)},
- {USB_VPI(USB_VENDOR_AEI, USB_PRODUCT_AEI_FASTETHERNET, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ALLIEDTELESYN, USB_PRODUCT_ALLIEDTELESYN_ATUSB100, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC110T, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2LAN, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100, 0)},
- {USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBE100, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBEL100, 0)},
- {USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBLP100, AUE_FLAG_PNA)},
- {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXS, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TX, 0)},
- {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX1, AUE_FLAG_LSYS)},
- {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX2, AUE_FLAG_LSYS | AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX3, AUE_FLAG_LSYS | AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX4, AUE_FLAG_LSYS | AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA, AUE_FLAG_PNA)},
- {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX, AUE_FLAG_LSYS)},
- {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650, AUE_FLAG_LSYS)},
- {USB_VPI(USB_VENDOR_ELCON, USB_PRODUCT_ELCON_PLAN, AUE_FLAG_PNA | AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSB20, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBLTX, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX0, 0)},
- {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX1, AUE_FLAG_LSYS)},
- {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2, 0)},
- {USB_VPI(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX3, AUE_FLAG_LSYS)},
- {USB_VPI(USB_VENDOR_ELSA, USB_PRODUCT_ELSA_USB2ETHERNET, 0)},
- {USB_VPI(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNBR402W, 0)},
- {USB_VPI(USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_HN210E, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTXS, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX, 0)},
- {USB_VPI(USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_KNU101TX, 0)},
- {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100H1, AUE_FLAG_LSYS | AUE_FLAG_PNA)},
- {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX, AUE_FLAG_LSYS)},
- {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TA, AUE_FLAG_LSYS)},
- {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX1, AUE_FLAG_LSYS | AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX2, AUE_FLAG_LSYS | AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T, AUE_FLAG_LSYS)},
- {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUA2TX5, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1, 0)},
- {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX5, 0)},
- {USB_VPI(USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA101, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_SIIG2, USB_PRODUCT_SIIG2_USBTOETHER, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTNIC, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB, 0)},
- {USB_VPI(USB_VENDOR_SMC, USB_PRODUCT_SMC_2206USB, AUE_FLAG_PII)},
- {USB_VPI(USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100, 0)},
- {USB_VPI(USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB110, AUE_FLAG_PII)},
-};
-
-/* prototypes */
-
-static device_probe_t aue_probe;
-static device_attach_t aue_attach;
-static device_detach_t aue_detach;
-static device_shutdown_t aue_shutdown;
-static miibus_readreg_t aue_miibus_readreg;
-static miibus_writereg_t aue_miibus_writereg;
-static miibus_statchg_t aue_miibus_statchg;
-
-static usb2_callback_t aue_intr_callback;
-static usb2_callback_t aue_bulk_read_callback;
-static usb2_callback_t aue_bulk_write_callback;
-
-static usb2_ether_fn_t aue_attach_post;
-static usb2_ether_fn_t aue_init;
-static usb2_ether_fn_t aue_stop;
-static usb2_ether_fn_t aue_start;
-static usb2_ether_fn_t aue_tick;
-static usb2_ether_fn_t aue_setmulti;
-static usb2_ether_fn_t aue_setpromisc;
-
-static uint8_t aue_csr_read_1(struct aue_softc *, uint16_t);
-static uint16_t aue_csr_read_2(struct aue_softc *, uint16_t);
-static void aue_csr_write_1(struct aue_softc *, uint16_t, uint8_t);
-static void aue_csr_write_2(struct aue_softc *, uint16_t, uint16_t);
-static void aue_eeprom_getword(struct aue_softc *, int, uint16_t *);
-static void aue_read_eeprom(struct aue_softc *, uint8_t *, uint16_t,
- uint16_t);
-static void aue_reset(struct aue_softc *);
-static void aue_reset_pegasus_II(struct aue_softc *);
-
-static int aue_ifmedia_upd(struct ifnet *);
-static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-
-static const struct usb2_config aue_config[AUE_N_TRANSFER] = {
-
- [AUE_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = (MCLBYTES + 2),
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = aue_bulk_write_callback,
- .mh.timeout = 10000, /* 10 seconds */
- },
-
- [AUE_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = (MCLBYTES + 4 + ETHER_CRC_LEN),
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = aue_bulk_read_callback,
- },
-
- [AUE_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = aue_intr_callback,
- },
-};
-
-static device_method_t aue_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, aue_probe),
- DEVMETHOD(device_attach, aue_attach),
- DEVMETHOD(device_detach, aue_detach),
- DEVMETHOD(device_shutdown, aue_shutdown),
-
- /* bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
-
- /* MII interface */
- DEVMETHOD(miibus_readreg, aue_miibus_readreg),
- DEVMETHOD(miibus_writereg, aue_miibus_writereg),
- DEVMETHOD(miibus_statchg, aue_miibus_statchg),
-
- {0, 0}
-};
-
-static driver_t aue_driver = {
- .name = "aue",
- .methods = aue_methods,
- .size = sizeof(struct aue_softc)
-};
-
-static devclass_t aue_devclass;
-
-DRIVER_MODULE(aue, ushub, aue_driver, aue_devclass, NULL, 0);
-DRIVER_MODULE(miibus, aue, miibus_driver, miibus_devclass, 0, 0);
-MODULE_DEPEND(aue, usb2_ethernet, 1, 1, 1);
-MODULE_DEPEND(aue, usb2_core, 1, 1, 1);
-MODULE_DEPEND(aue, ether, 1, 1, 1);
-MODULE_DEPEND(aue, miibus, 1, 1, 1);
-
-static const struct usb2_ether_methods aue_ue_methods = {
- .ue_attach_post = aue_attach_post,
- .ue_start = aue_start,
- .ue_init = aue_init,
- .ue_stop = aue_stop,
- .ue_tick = aue_tick,
- .ue_setmulti = aue_setmulti,
- .ue_setpromisc = aue_setpromisc,
- .ue_mii_upd = aue_ifmedia_upd,
- .ue_mii_sts = aue_ifmedia_sts,
-};
-
-#define AUE_SETBIT(sc, reg, x) \
- aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x))
-
-#define AUE_CLRBIT(sc, reg, x) \
- aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x))
-
-static uint8_t
-aue_csr_read_1(struct aue_softc *sc, uint16_t reg)
-{
- struct usb2_device_request req;
- usb2_error_t err;
- uint8_t val;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = AUE_UR_READREG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 1);
-
- err = usb2_ether_do_request(&sc->sc_ue, &req, &val, 1000);
- if (err)
- return (0);
- return (val);
-}
-
-static uint16_t
-aue_csr_read_2(struct aue_softc *sc, uint16_t reg)
-{
- struct usb2_device_request req;
- usb2_error_t err;
- uint16_t val;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = AUE_UR_READREG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 2);
-
- err = usb2_ether_do_request(&sc->sc_ue, &req, &val, 1000);
- if (err)
- return (0);
- return (le16toh(val));
-}
-
-static void
-aue_csr_write_1(struct aue_softc *sc, uint16_t reg, uint8_t val)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = AUE_UR_WRITEREG;
- req.wValue[0] = val;
- req.wValue[1] = 0;
- USETW(req.wIndex, reg);
- USETW(req.wLength, 1);
-
- if (usb2_ether_do_request(&sc->sc_ue, &req, &val, 1000)) {
- /* error ignored */
- }
-}
-
-static void
-aue_csr_write_2(struct aue_softc *sc, uint16_t reg, uint16_t val)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = AUE_UR_WRITEREG;
- USETW(req.wValue, val);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 2);
-
- val = htole16(val);
-
- if (usb2_ether_do_request(&sc->sc_ue, &req, &val, 1000)) {
- /* error ignored */
- }
-}
-
-/*
- * Read a word of data stored in the EEPROM at address 'addr.'
- */
-static void
-aue_eeprom_getword(struct aue_softc *sc, int addr, uint16_t *dest)
-{
- int i;
- uint16_t word = 0;
-
- aue_csr_write_1(sc, AUE_EE_REG, addr);
- aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ);
-
- for (i = 0; i != AUE_TIMEOUT; i++) {
- if (aue_csr_read_1(sc, AUE_EE_CTL) & AUE_EECTL_DONE)
- break;
- if (usb2_ether_pause(&sc->sc_ue, hz / 100))
- break;
- }
-
- if (i == AUE_TIMEOUT)
- device_printf(sc->sc_ue.ue_dev, "EEPROM read timed out\n");
-
- word = aue_csr_read_2(sc, AUE_EE_DATA);
- *dest = word;
-}
-
-/*
- * Read a sequence of words from the EEPROM.
- */
-static void
-aue_read_eeprom(struct aue_softc *sc, uint8_t *dest,
- uint16_t off, uint16_t len)
-{
- uint16_t *ptr = (uint16_t *)dest;
- int i;
-
- for (i = 0; i != len; i++, ptr++)
- aue_eeprom_getword(sc, off + i, ptr);
-}
-
-static int
-aue_miibus_readreg(device_t dev, int phy, int reg)
-{
- struct aue_softc *sc = device_get_softc(dev);
- int i, locked;
- uint16_t val = 0;
-
- locked = mtx_owned(&sc->sc_mtx);
- if (!locked)
- AUE_LOCK(sc);
-
- /*
- * The Am79C901 HomePNA PHY actually contains two transceivers: a 1Mbps
- * HomePNA PHY and a 10Mbps full/half duplex ethernet PHY with NWAY
- * autoneg. However in the ADMtek adapter, only the 1Mbps PHY is
- * actually connected to anything, so we ignore the 10Mbps one. It
- * happens to be configured for MII address 3, so we filter that out.
- */
- if (sc->sc_flags & AUE_FLAG_DUAL_PHY) {
- if (phy == 3)
- goto done;
-#if 0
- if (phy != 1)
- goto done;
-#endif
- }
- aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
- aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ);
-
- for (i = 0; i != AUE_TIMEOUT; i++) {
- if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
- break;
- if (usb2_ether_pause(&sc->sc_ue, hz / 100))
- break;
- }
-
- if (i == AUE_TIMEOUT)
- device_printf(sc->sc_ue.ue_dev, "MII read timed out\n");
-
- val = aue_csr_read_2(sc, AUE_PHY_DATA);
-
-done:
- if (!locked)
- AUE_UNLOCK(sc);
- return (val);
-}
-
-static int
-aue_miibus_writereg(device_t dev, int phy, int reg, int data)
-{
- struct aue_softc *sc = device_get_softc(dev);
- int i;
- int locked;
-
- if (phy == 3)
- return (0);
-
- locked = mtx_owned(&sc->sc_mtx);
- if (!locked)
- AUE_LOCK(sc);
-
- aue_csr_write_2(sc, AUE_PHY_DATA, data);
- aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
- aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_WRITE);
-
- for (i = 0; i != AUE_TIMEOUT; i++) {
- if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
- break;
- if (usb2_ether_pause(&sc->sc_ue, hz / 100))
- break;
- }
-
- if (i == AUE_TIMEOUT)
- device_printf(sc->sc_ue.ue_dev, "MII read timed out\n");
-
- if (!locked)
- AUE_UNLOCK(sc);
- return (0);
-}
-
-static void
-aue_miibus_statchg(device_t dev)
-{
- struct aue_softc *sc = device_get_softc(dev);
- struct mii_data *mii = GET_MII(sc);
- int locked;
-
- locked = mtx_owned(&sc->sc_mtx);
- if (!locked)
- AUE_LOCK(sc);
-
- AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
- if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
- AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
- else
- AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
-
- if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
- AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
- else
- AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
-
- AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
-
- /*
- * Set the LED modes on the LinkSys adapter.
- * This turns on the 'dual link LED' bin in the auxmode
- * register of the Broadcom PHY.
- */
- if (sc->sc_flags & AUE_FLAG_LSYS) {
- uint16_t auxmode;
-
- auxmode = aue_miibus_readreg(dev, 0, 0x1b);
- aue_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04);
- }
- if (!locked)
- AUE_UNLOCK(sc);
-}
-
-#define AUE_BITS 6
-static void
-aue_setmulti(struct usb2_ether *ue)
-{
- struct aue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
- struct ifmultiaddr *ifma;
- uint32_t h = 0;
- uint32_t i;
- uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
- AUE_LOCK_ASSERT(sc, MA_OWNED);
-
- if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
- AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
- return;
- }
-
- AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
-
- /* now program new ones */
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr), ETHER_ADDR_LEN) & ((1 << AUE_BITS) - 1);
- hashtbl[(h >> 3)] |= 1 << (h & 0x7);
- }
- IF_ADDR_UNLOCK(ifp);
-
- /* write the hashtable */
- for (i = 0; i != 8; i++)
- aue_csr_write_1(sc, AUE_MAR0 + i, hashtbl[i]);
-}
-
-static void
-aue_reset_pegasus_II(struct aue_softc *sc)
-{
- /* Magic constants taken from Linux driver. */
- aue_csr_write_1(sc, AUE_REG_1D, 0);
- aue_csr_write_1(sc, AUE_REG_7B, 2);
-#if 0
- if ((sc->sc_flags & HAS_HOME_PNA) && mii_mode)
- aue_csr_write_1(sc, AUE_REG_81, 6);
- else
-#endif
- aue_csr_write_1(sc, AUE_REG_81, 2);
-}
-
-static void
-aue_reset(struct aue_softc *sc)
-{
- int i;
-
- AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC);
-
- for (i = 0; i != AUE_TIMEOUT; i++) {
- if (!(aue_csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC))
- break;
- if (usb2_ether_pause(&sc->sc_ue, hz / 100))
- break;
- }
-
- if (i == AUE_TIMEOUT)
- device_printf(sc->sc_ue.ue_dev, "reset failed\n");
-
- /*
- * The PHY(s) attached to the Pegasus chip may be held
- * in reset until we flip on the GPIO outputs. Make sure
- * to set the GPIO pins high so that the PHY(s) will
- * be enabled.
- *
- * Note: We force all of the GPIO pins low first, *then*
- * enable the ones we want.
- */
- aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0);
- aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0|AUE_GPIO_SEL1);
-
- if (sc->sc_flags & AUE_FLAG_LSYS) {
- /* Grrr. LinkSys has to be different from everyone else. */
- aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_SEL0|AUE_GPIO_SEL1);
- aue_csr_write_1(sc, AUE_GPIO0,
- AUE_GPIO_SEL0|AUE_GPIO_SEL1|AUE_GPIO_OUT0);
- }
- if (sc->sc_flags & AUE_FLAG_PII)
- aue_reset_pegasus_II(sc);
-
- /* Wait a little while for the chip to get its brains in order: */
- usb2_ether_pause(&sc->sc_ue, hz / 100);
-}
-
-static void
-aue_attach_post(struct usb2_ether *ue)
-{
- struct aue_softc *sc = usb2_ether_getsc(ue);
-
- /* reset the adapter */
- aue_reset(sc);
-
- /* get station address from the EEPROM */
- aue_read_eeprom(sc, ue->ue_eaddr, 0, 3);
-}
-
-/*
- * Probe for a Pegasus chip.
- */
-static int
-aue_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
- if (uaa->info.bConfigIndex != AUE_CONFIG_INDEX)
- return (ENXIO);
- if (uaa->info.bIfaceIndex != AUE_IFACE_IDX)
- return (ENXIO);
- /*
- * Belkin USB Bluetooth dongles of the F8T012xx1 model series conflict
- * with older Belkin USB2LAN adapters. Skip if_aue if we detect one of
- * the devices that look like Bluetooth adapters.
- */
- if (uaa->info.idVendor == USB_VENDOR_BELKIN &&
- uaa->info.idProduct == USB_PRODUCT_BELKIN_F8T012 &&
- uaa->info.bcdDevice == 0x0413)
- return (ENXIO);
-
- return (usb2_lookup_id_by_uaa(aue_devs, sizeof(aue_devs), uaa));
-}
-
-/*
- * Attach the interface. Allocate softc structures, do ifmedia
- * setup and ethernet/BPF attach.
- */
-static int
-aue_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct aue_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
- uint8_t iface_index;
- int error;
-
- sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
-
- if (uaa->info.bcdDevice >= 0x0201) {
- /* XXX currently undocumented */
- sc->sc_flags |= AUE_FLAG_VER_2;
- }
-
- device_set_usb2_desc(dev);
- mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
-
- iface_index = AUE_IFACE_IDX;
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, aue_config, AUE_N_TRANSFER,
- sc, &sc->sc_mtx);
- if (error) {
- device_printf(dev, "allocating USB transfers failed!\n");
- goto detach;
- }
-
- ue->ue_sc = sc;
- ue->ue_dev = dev;
- ue->ue_udev = uaa->device;
- ue->ue_mtx = &sc->sc_mtx;
- ue->ue_methods = &aue_ue_methods;
-
- error = usb2_ether_ifattach(ue);
- if (error) {
- device_printf(dev, "could not attach interface\n");
- goto detach;
- }
- return (0); /* success */
-
-detach:
- aue_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-aue_detach(device_t dev)
-{
- struct aue_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
-
- usb2_transfer_unsetup(sc->sc_xfer, AUE_N_TRANSFER);
- usb2_ether_ifdetach(ue);
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static void
-aue_intr_callback(struct usb2_xfer *xfer)
-{
- struct aue_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
- struct aue_intrpkt pkt;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) &&
- xfer->actlen >= sizeof(pkt)) {
-
- usb2_copy_out(xfer->frbuffers, 0, &pkt, sizeof(pkt));
-
- if (pkt.aue_txstat0)
- ifp->if_oerrors++;
- if (pkt.aue_txstat0 & (AUE_TXSTAT0_LATECOLL &
- AUE_TXSTAT0_EXCESSCOLL))
- ifp->if_collisions++;
- }
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-aue_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct aue_softc *sc = xfer->priv_sc;
- struct usb2_ether *ue = &sc->sc_ue;
- struct ifnet *ifp = usb2_ether_getifp(ue);
- struct aue_rxpkt stat;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(11, "received %d bytes\n", xfer->actlen);
-
- if (sc->sc_flags & AUE_FLAG_VER_2) {
-
- if (xfer->actlen == 0) {
- ifp->if_ierrors++;
- goto tr_setup;
- }
- } else {
-
- if (xfer->actlen <= (sizeof(stat) + ETHER_CRC_LEN)) {
- ifp->if_ierrors++;
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers,
- xfer->actlen - sizeof(stat), &stat, sizeof(stat));
-
- /*
- * turn off all the non-error bits in the rx status
- * word:
- */
- stat.aue_rxstat &= AUE_RXSTAT_MASK;
- if (stat.aue_rxstat) {
- ifp->if_ierrors++;
- goto tr_setup;
- }
- /* No errors; receive the packet. */
- xfer->actlen -= (sizeof(stat) + ETHER_CRC_LEN);
- }
- usb2_ether_rxbuf(ue, xfer->frbuffers, 0, xfer->actlen);
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- usb2_ether_rxflush(ue);
- return;
-
- default: /* Error */
- DPRINTF("bulk read error, %s\n",
- usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-aue_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct aue_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
- struct mbuf *m;
- uint8_t buf[2];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(11, "transfer of %d bytes complete\n", xfer->actlen);
- ifp->if_opackets++;
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- if ((sc->sc_flags & AUE_FLAG_LINK) == 0) {
- /*
- * don't send anything if there is no link !
- */
- return;
- }
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
-
- if (m == NULL)
- return;
- if (m->m_pkthdr.len > MCLBYTES)
- m->m_pkthdr.len = MCLBYTES;
- if (sc->sc_flags & AUE_FLAG_VER_2) {
-
- xfer->frlengths[0] = m->m_pkthdr.len;
-
- usb2_m_copy_in(xfer->frbuffers, 0,
- m, 0, m->m_pkthdr.len);
-
- } else {
-
- xfer->frlengths[0] = (m->m_pkthdr.len + 2);
-
- /*
- * The ADMtek documentation says that the
- * packet length is supposed to be specified
- * in the first two bytes of the transfer,
- * however it actually seems to ignore this
- * info and base the frame size on the bulk
- * transfer length.
- */
- buf[0] = (uint8_t)(m->m_pkthdr.len);
- buf[1] = (uint8_t)(m->m_pkthdr.len >> 8);
-
- usb2_copy_in(xfer->frbuffers, 0, buf, 2);
-
- usb2_m_copy_in(xfer->frbuffers, 2,
- m, 0, m->m_pkthdr.len);
- }
-
- /*
- * if there's a BPF listener, bounce a copy
- * of this frame to him:
- */
- BPF_MTAP(ifp, m);
-
- m_freem(m);
-
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- DPRINTFN(11, "transfer error, %s\n",
- usb2_errstr(xfer->error));
-
- ifp->if_oerrors++;
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-aue_tick(struct usb2_ether *ue)
-{
- struct aue_softc *sc = usb2_ether_getsc(ue);
- struct mii_data *mii = GET_MII(sc);
-
- AUE_LOCK_ASSERT(sc, MA_OWNED);
-
- mii_tick(mii);
- if ((sc->sc_flags & AUE_FLAG_LINK) == 0
- && mii->mii_media_status & IFM_ACTIVE &&
- IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
- sc->sc_flags |= AUE_FLAG_LINK;
- aue_start(ue);
- }
-}
-
-static void
-aue_start(struct usb2_ether *ue)
-{
- struct aue_softc *sc = usb2_ether_getsc(ue);
-
- /*
- * start the USB transfers, if not already started:
- */
- usb2_transfer_start(sc->sc_xfer[AUE_INTR_DT_RD]);
- usb2_transfer_start(sc->sc_xfer[AUE_BULK_DT_RD]);
- usb2_transfer_start(sc->sc_xfer[AUE_BULK_DT_WR]);
-}
-
-static void
-aue_init(struct usb2_ether *ue)
-{
- struct aue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
- int i;
-
- AUE_LOCK_ASSERT(sc, MA_OWNED);
-
- /*
- * Cancel pending I/O
- */
- aue_reset(sc);
-
- /* Set MAC address */
- for (i = 0; i != ETHER_ADDR_LEN; i++)
- aue_csr_write_1(sc, AUE_PAR0 + i, IF_LLADDR(ifp)[i]);
-
- /* update promiscuous setting */
- aue_setpromisc(ue);
-
- /* Load the multicast filter. */
- aue_setmulti(ue);
-
- /* Enable RX and TX */
- aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB);
- AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB);
- AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR);
-
- usb2_transfer_set_stall(sc->sc_xfer[AUE_BULK_DT_WR]);
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- aue_start(ue);
-}
-
-static void
-aue_setpromisc(struct usb2_ether *ue)
-{
- struct aue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- AUE_LOCK_ASSERT(sc, MA_OWNED);
-
- /* if we want promiscuous mode, set the allframes bit: */
- if (ifp->if_flags & IFF_PROMISC)
- AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
- else
- AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
-}
-
-/*
- * Set media options.
- */
-static int
-aue_ifmedia_upd(struct ifnet *ifp)
-{
- struct aue_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- AUE_LOCK_ASSERT(sc, MA_OWNED);
-
- sc->sc_flags &= ~AUE_FLAG_LINK;
- if (mii->mii_instance) {
- struct mii_softc *miisc;
-
- LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
- mii_phy_reset(miisc);
- }
- mii_mediachg(mii);
- return (0);
-}
-
-/*
- * Report current media status.
- */
-static void
-aue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct aue_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- AUE_LOCK(sc);
- mii_pollstat(mii);
- AUE_UNLOCK(sc);
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
-}
-
-/*
- * Stop the adapter and free any mbufs allocated to the
- * RX and TX lists.
- */
-static void
-aue_stop(struct usb2_ether *ue)
-{
- struct aue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- AUE_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- sc->sc_flags &= ~AUE_FLAG_LINK;
-
- /*
- * stop all the transfers, if not already stopped:
- */
- usb2_transfer_stop(sc->sc_xfer[AUE_BULK_DT_WR]);
- usb2_transfer_stop(sc->sc_xfer[AUE_BULK_DT_RD]);
- usb2_transfer_stop(sc->sc_xfer[AUE_INTR_DT_RD]);
-
- aue_csr_write_1(sc, AUE_CTL0, 0);
- aue_csr_write_1(sc, AUE_CTL1, 0);
- aue_reset(sc);
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static int
-aue_shutdown(device_t dev)
-{
- struct aue_softc *sc = device_get_softc(dev);
-
- usb2_ether_ifshutdown(&sc->sc_ue);
-
- return (0);
-}
diff --git a/sys/dev/usb2/ethernet/if_auereg.h b/sys/dev/usb2/ethernet/if_auereg.h
deleted file mode 100644
index 249c913..0000000
--- a/sys/dev/usb2/ethernet/if_auereg.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999
- * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * Register definitions for ADMtek Pegasus AN986 USB to Ethernet
- * chip. The Pegasus uses a total of four USB endpoints: the control
- * endpoint (0), a bulk read endpoint for receiving packets (1),
- * a bulk write endpoint for sending packets (2) and an interrupt
- * endpoint for passing RX and TX status (3). Endpoint 0 is used
- * to read and write the ethernet module's registers. All registers
- * are 8 bits wide.
- *
- * Packet transfer is done in 64 byte chunks. The last chunk in a
- * transfer is denoted by having a length less that 64 bytes. For
- * the RX case, the data includes an optional RX status word.
- */
-
-#define AUE_UR_READREG 0xF0
-#define AUE_UR_WRITEREG 0xF1
-
-#define AUE_CONFIG_INDEX 0 /* config number 1 */
-#define AUE_IFACE_IDX 0
-
-/*
- * Note that while the ADMtek technically has four endpoints, the control
- * endpoint (endpoint 0) is regarded as special by the USB code and drivers
- * don't have direct access to it (we access it using usb2_do_request()
- * when reading/writing registers. Consequently, our endpoint indexes
- * don't match those in the ADMtek Pegasus manual: we consider the RX data
- * endpoint to be index 0 and work up from there.
- */
-enum {
- AUE_BULK_DT_WR,
- AUE_BULK_DT_RD,
- AUE_INTR_DT_RD,
- AUE_N_TRANSFER,
-};
-
-#define AUE_INTR_PKTLEN 0x8
-
-#define AUE_CTL0 0x00
-#define AUE_CTL1 0x01
-#define AUE_CTL2 0x02
-#define AUE_MAR0 0x08
-#define AUE_MAR1 0x09
-#define AUE_MAR2 0x0A
-#define AUE_MAR3 0x0B
-#define AUE_MAR4 0x0C
-#define AUE_MAR5 0x0D
-#define AUE_MAR6 0x0E
-#define AUE_MAR7 0x0F
-#define AUE_MAR AUE_MAR0
-#define AUE_PAR0 0x10
-#define AUE_PAR1 0x11
-#define AUE_PAR2 0x12
-#define AUE_PAR3 0x13
-#define AUE_PAR4 0x14
-#define AUE_PAR5 0x15
-#define AUE_PAR AUE_PAR0
-#define AUE_PAUSE0 0x18
-#define AUE_PAUSE1 0x19
-#define AUE_PAUSE AUE_PAUSE0
-#define AUE_RX_FLOWCTL_CNT 0x1A
-#define AUE_RX_FLOWCTL_FIFO 0x1B
-#define AUE_REG_1D 0x1D
-#define AUE_EE_REG 0x20
-#define AUE_EE_DATA0 0x21
-#define AUE_EE_DATA1 0x22
-#define AUE_EE_DATA AUE_EE_DATA0
-#define AUE_EE_CTL 0x23
-#define AUE_PHY_ADDR 0x25
-#define AUE_PHY_DATA0 0x26
-#define AUE_PHY_DATA1 0x27
-#define AUE_PHY_DATA AUE_PHY_DATA0
-#define AUE_PHY_CTL 0x28
-#define AUE_USB_STS 0x2A
-#define AUE_TXSTAT0 0x2B
-#define AUE_TXSTAT1 0x2C
-#define AUE_TXSTAT AUE_TXSTAT0
-#define AUE_RXSTAT 0x2D
-#define AUE_PKTLOST0 0x2E
-#define AUE_PKTLOST1 0x2F
-#define AUE_PKTLOST AUE_PKTLOST0
-
-#define AUE_REG_7B 0x7B
-#define AUE_GPIO0 0x7E
-#define AUE_GPIO1 0x7F
-#define AUE_REG_81 0x81
-
-#define AUE_CTL0_INCLUDE_RXCRC 0x01
-#define AUE_CTL0_ALLMULTI 0x02
-#define AUE_CTL0_STOP_BACKOFF 0x04
-#define AUE_CTL0_RXSTAT_APPEND 0x08
-#define AUE_CTL0_WAKEON_ENB 0x10
-#define AUE_CTL0_RXPAUSE_ENB 0x20
-#define AUE_CTL0_RX_ENB 0x40
-#define AUE_CTL0_TX_ENB 0x80
-
-#define AUE_CTL1_HOMELAN 0x04
-#define AUE_CTL1_RESETMAC 0x08
-#define AUE_CTL1_SPEEDSEL 0x10 /* 0 = 10mbps, 1 = 100mbps */
-#define AUE_CTL1_DUPLEX 0x20 /* 0 = half, 1 = full */
-#define AUE_CTL1_DELAYHOME 0x40
-
-#define AUE_CTL2_EP3_CLR 0x01 /* reading EP3 clrs status regs */
-#define AUE_CTL2_RX_BADFRAMES 0x02
-#define AUE_CTL2_RX_PROMISC 0x04
-#define AUE_CTL2_LOOPBACK 0x08
-#define AUE_CTL2_EEPROMWR_ENB 0x10
-#define AUE_CTL2_EEPROM_LOAD 0x20
-
-#define AUE_EECTL_WRITE 0x01
-#define AUE_EECTL_READ 0x02
-#define AUE_EECTL_DONE 0x04
-
-#define AUE_PHYCTL_PHYREG 0x1F
-#define AUE_PHYCTL_WRITE 0x20
-#define AUE_PHYCTL_READ 0x40
-#define AUE_PHYCTL_DONE 0x80
-
-#define AUE_USBSTS_SUSPEND 0x01
-#define AUE_USBSTS_RESUME 0x02
-
-#define AUE_TXSTAT0_JABTIMO 0x04
-#define AUE_TXSTAT0_CARLOSS 0x08
-#define AUE_TXSTAT0_NOCARRIER 0x10
-#define AUE_TXSTAT0_LATECOLL 0x20
-#define AUE_TXSTAT0_EXCESSCOLL 0x40
-#define AUE_TXSTAT0_UNDERRUN 0x80
-
-#define AUE_TXSTAT1_PKTCNT 0x0F
-#define AUE_TXSTAT1_FIFO_EMPTY 0x40
-#define AUE_TXSTAT1_FIFO_FULL 0x80
-
-#define AUE_RXSTAT_OVERRUN 0x01
-#define AUE_RXSTAT_PAUSE 0x02
-
-#define AUE_GPIO_IN0 0x01
-#define AUE_GPIO_OUT0 0x02
-#define AUE_GPIO_SEL0 0x04
-#define AUE_GPIO_IN1 0x08
-#define AUE_GPIO_OUT1 0x10
-#define AUE_GPIO_SEL1 0x20
-
-#define AUE_TIMEOUT 100 /* 10*ms */
-#define AUE_MIN_FRAMELEN 60
-
-#define AUE_RXSTAT_MCAST 0x01
-#define AUE_RXSTAT_GIANT 0x02
-#define AUE_RXSTAT_RUNT 0x04
-#define AUE_RXSTAT_CRCERR 0x08
-#define AUE_RXSTAT_DRIBBLE 0x10
-#define AUE_RXSTAT_MASK 0x1E
-
-#define GET_MII(sc) usb2_ether_getmii(&(sc)->sc_ue)
-
-struct aue_intrpkt {
- uint8_t aue_txstat0;
- uint8_t aue_txstat1;
- uint8_t aue_rxstat;
- uint8_t aue_rxlostpkt0;
- uint8_t aue_rxlostpkt1;
- uint8_t aue_wakeupstat;
- uint8_t aue_rsvd;
-} __packed;
-
-struct aue_rxpkt {
- uint16_t aue_pktlen;
- uint8_t aue_rxstat;
- uint8_t pad;
-} __packed;
-
-struct aue_softc {
- struct usb2_ether sc_ue;
- struct mtx sc_mtx;
- struct usb2_xfer *sc_xfer[AUE_N_TRANSFER];
-
- int sc_flags;
-#define AUE_FLAG_LSYS 0x0001 /* use Linksys reset */
-#define AUE_FLAG_PNA 0x0002 /* has Home PNA */
-#define AUE_FLAG_PII 0x0004 /* Pegasus II chip */
-#define AUE_FLAG_LINK 0x0008 /* wait for link to come up */
-#define AUE_FLAG_VER_2 0x0200 /* chip is version 2 */
-#define AUE_FLAG_DUAL_PHY 0x0400 /* chip has two transcivers */
-};
-
-#define AUE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
-#define AUE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
-#define AUE_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)
diff --git a/sys/dev/usb2/ethernet/if_axe2.c b/sys/dev/usb2/ethernet/if_axe2.c
deleted file mode 100644
index b578be9..0000000
--- a/sys/dev/usb2/ethernet/if_axe2.c
+++ /dev/null
@@ -1,1076 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000-2003
- * Bill Paul <wpaul@windriver.com>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver.
- * Used in the LinkSys USB200M and various other adapters.
- *
- * Manuals available from:
- * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF
- * Note: you need the manual for the AX88170 chip (USB 1.x ethernet
- * controller) to find the definitions for the RX control register.
- * http://www.asix.com.tw/datasheet/mac/Ax88170.PDF
- *
- * Written by Bill Paul <wpaul@windriver.com>
- * Senior Engineer
- * Wind River Systems
- */
-
-/*
- * The AX88172 provides USB ethernet supports at 10 and 100Mbps.
- * It uses an external PHY (reference designs use a RealTek chip),
- * and has a 64-bit multicast hash filter. There is some information
- * missing from the manual which one needs to know in order to make
- * the chip function:
- *
- * - You must set bit 7 in the RX control register, otherwise the
- * chip won't receive any packets.
- * - You must initialize all 3 IPG registers, or you won't be able
- * to send any packets.
- *
- * Note that this device appears to only support loading the station
- * address via autload from the EEPROM (i.e. there's no way to manaully
- * set it).
- *
- * (Adam Weinberger wanted me to name this driver if_gir.c.)
- */
-
-/*
- * Ax88178 and Ax88772 support backported from the OpenBSD driver.
- * 2007/02/12, J.R. Oldroyd, fbsd@opal.com
- *
- * Manual here:
- * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf
- * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR axe_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_axereg.h>
-
-/*
- * AXE_178_MAX_FRAME_BURST
- * max frame burst size for Ax88178 and Ax88772
- * 0 2048 bytes
- * 1 4096 bytes
- * 2 8192 bytes
- * 3 16384 bytes
- * use the largest your system can handle without USB stalling.
- *
- * NB: 88772 parts appear to generate lots of input errors with
- * a 2K rx buffer and 8K is only slightly faster than 4K on an
- * EHCI port on a T42 so change at your own risk.
- */
-#define AXE_178_MAX_FRAME_BURST 1
-
-#if USB_DEBUG
-static int axe_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, axe, CTLFLAG_RW, 0, "USB axe");
-SYSCTL_INT(_hw_usb2_axe, OID_AUTO, debug, CTLFLAG_RW, &axe_debug, 0,
- "Debug level");
-#endif
-
-/*
- * Various supported device vendors/products.
- */
-static const struct usb2_device_id axe_devs[] = {
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UF200, 0)},
- {USB_VPI(USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2, 0)},
- {USB_VPI(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ETHERNET, AXE_FLAG_772)},
- {USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172, 0)},
- {USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178, AXE_FLAG_178)},
- {USB_VPI(USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772, AXE_FLAG_772)},
- {USB_VPI(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T, 0)},
- {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055, AXE_FLAG_178)},
- {USB_VPI(USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR, 0)},
- {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2, AXE_FLAG_772)},
- {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX, 0)},
- {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100, 0)},
- {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1, AXE_FLAG_772)},
- {USB_VPI(USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E, 0)},
- {USB_VPI(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2, AXE_FLAG_178)},
- {USB_VPI(USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1, 0)},
- {USB_VPI(USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M, 0)},
- {USB_VPI(USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000, AXE_FLAG_178)},
- {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX, 0)},
- {USB_VPI(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120, 0)},
- {USB_VPI(USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS, AXE_FLAG_772)},
- {USB_VPI(USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T, AXE_FLAG_178)},
- {USB_VPI(USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029, 0)},
- {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028, AXE_FLAG_178)},
- {USB_VPI(USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL, 0)},
-};
-
-static device_probe_t axe_probe;
-static device_attach_t axe_attach;
-static device_detach_t axe_detach;
-static device_shutdown_t axe_shutdown;
-
-static usb2_callback_t axe_intr_callback;
-static usb2_callback_t axe_bulk_read_callback;
-static usb2_callback_t axe_bulk_write_callback;
-
-static miibus_readreg_t axe_miibus_readreg;
-static miibus_writereg_t axe_miibus_writereg;
-static miibus_statchg_t axe_miibus_statchg;
-
-static usb2_ether_fn_t axe_attach_post;
-static usb2_ether_fn_t axe_init;
-static usb2_ether_fn_t axe_stop;
-static usb2_ether_fn_t axe_start;
-static usb2_ether_fn_t axe_tick;
-static usb2_ether_fn_t axe_setmulti;
-static usb2_ether_fn_t axe_setpromisc;
-
-static int axe_ifmedia_upd(struct ifnet *);
-static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-static int axe_cmd(struct axe_softc *, int, int, int, void *);
-static void axe_ax88178_init(struct axe_softc *);
-static void axe_ax88772_init(struct axe_softc *);
-static int axe_get_phyno(struct axe_softc *, int);
-
-static const struct usb2_config axe_config[AXE_N_TRANSFER] = {
-
- [AXE_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = AXE_BULK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = axe_bulk_write_callback,
- .mh.timeout = 10000, /* 10 seconds */
- },
-
- [AXE_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
-#if (MCLBYTES < 2048)
-#error "(MCLBYTES < 2048)"
-#endif
- .mh.bufsize = MCLBYTES,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = axe_bulk_read_callback,
- .mh.timeout = 0, /* no timeout */
- },
-
- [AXE_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = axe_intr_callback,
- },
-};
-
-static device_method_t axe_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, axe_probe),
- DEVMETHOD(device_attach, axe_attach),
- DEVMETHOD(device_detach, axe_detach),
- DEVMETHOD(device_shutdown, axe_shutdown),
-
- /* bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
-
- /* MII interface */
- DEVMETHOD(miibus_readreg, axe_miibus_readreg),
- DEVMETHOD(miibus_writereg, axe_miibus_writereg),
- DEVMETHOD(miibus_statchg, axe_miibus_statchg),
-
- {0, 0}
-};
-
-static driver_t axe_driver = {
- .name = "axe",
- .methods = axe_methods,
- .size = sizeof(struct axe_softc),
-};
-
-static devclass_t axe_devclass;
-
-DRIVER_MODULE(axe, ushub, axe_driver, axe_devclass, NULL, 0);
-DRIVER_MODULE(miibus, axe, miibus_driver, miibus_devclass, 0, 0);
-MODULE_DEPEND(axe, usb2_ethernet, 1, 1, 1);
-MODULE_DEPEND(axe, usb2_core, 1, 1, 1);
-MODULE_DEPEND(axe, ether, 1, 1, 1);
-MODULE_DEPEND(axe, miibus, 1, 1, 1);
-
-static const struct usb2_ether_methods axe_ue_methods = {
- .ue_attach_post = axe_attach_post,
- .ue_start = axe_start,
- .ue_init = axe_init,
- .ue_stop = axe_stop,
- .ue_tick = axe_tick,
- .ue_setmulti = axe_setmulti,
- .ue_setpromisc = axe_setpromisc,
- .ue_mii_upd = axe_ifmedia_upd,
- .ue_mii_sts = axe_ifmedia_sts,
-};
-
-static int
-axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf)
-{
- struct usb2_device_request req;
- usb2_error_t err;
-
- AXE_LOCK_ASSERT(sc, MA_OWNED);
-
- req.bmRequestType = (AXE_CMD_IS_WRITE(cmd) ?
- UT_WRITE_VENDOR_DEVICE :
- UT_READ_VENDOR_DEVICE);
- req.bRequest = AXE_CMD_CMD(cmd);
- USETW(req.wValue, val);
- USETW(req.wIndex, index);
- USETW(req.wLength, AXE_CMD_LEN(cmd));
-
- err = usb2_ether_do_request(&sc->sc_ue, &req, buf, 1000);
-
- return (err);
-}
-
-static int
-axe_miibus_readreg(device_t dev, int phy, int reg)
-{
- struct axe_softc *sc = device_get_softc(dev);
- uint16_t val;
- int locked;
-
- if (sc->sc_phyno != phy)
- return (0);
-
- locked = mtx_owned(&sc->sc_mtx);
- if (!locked)
- AXE_LOCK(sc);
-
- axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
- axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &val);
- axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
-
- val = le16toh(val);
- if ((sc->sc_flags & AXE_FLAG_772) != 0 && reg == MII_BMSR) {
- /*
- * BMSR of AX88772 indicates that it supports extended
- * capability but the extended status register is
- * revered for embedded ethernet PHY. So clear the
- * extended capability bit of BMSR.
- */
- val &= ~BMSR_EXTCAP;
- }
-
- if (!locked)
- AXE_UNLOCK(sc);
- return (val);
-}
-
-static int
-axe_miibus_writereg(device_t dev, int phy, int reg, int val)
-{
- struct axe_softc *sc = device_get_softc(dev);
- int locked;
-
- val = htole16(val);
-
- if (sc->sc_phyno != phy)
- return (0);
-
- locked = mtx_owned(&sc->sc_mtx);
- if (!locked)
- AXE_LOCK(sc);
-
- axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
- axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val);
- axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
-
- if (!locked)
- AXE_UNLOCK(sc);
- return (0);
-}
-
-static void
-axe_miibus_statchg(device_t dev)
-{
- struct axe_softc *sc = device_get_softc(dev);
- struct mii_data *mii = GET_MII(sc);
- struct ifnet *ifp;
- uint16_t val;
- int err, locked;
-
- locked = mtx_owned(&sc->sc_mtx);
- if (!locked)
- AXE_LOCK(sc);
-
- ifp = usb2_ether_getifp(&sc->sc_ue);
- if (mii == NULL || ifp == NULL ||
- (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- goto done;
-
- sc->sc_flags &= ~AXE_FLAG_LINK;
- if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
- (IFM_ACTIVE | IFM_AVALID)) {
- switch (IFM_SUBTYPE(mii->mii_media_active)) {
- case IFM_10_T:
- case IFM_100_TX:
- sc->sc_flags |= AXE_FLAG_LINK;
- break;
- case IFM_1000_T:
- if ((sc->sc_flags & AXE_FLAG_178) == 0)
- break;
- sc->sc_flags |= AXE_FLAG_LINK;
- break;
- default:
- break;
- }
- }
-
- /* Lost link, do nothing. */
- if ((sc->sc_flags & AXE_FLAG_LINK) == 0)
- goto done;
-
- val = 0;
- if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
- val |= AXE_MEDIA_FULL_DUPLEX;
- if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) {
- val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC;
- if ((sc->sc_flags & AXE_FLAG_178) != 0)
- val |= AXE_178_MEDIA_ENCK;
- switch (IFM_SUBTYPE(mii->mii_media_active)) {
- case IFM_1000_T:
- val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK;
- break;
- case IFM_100_TX:
- val |= AXE_178_MEDIA_100TX;
- break;
- case IFM_10_T:
- /* doesn't need to be handled */
- break;
- }
- }
- err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
- if (err)
- device_printf(dev, "media change failed, error %d\n", err);
-done:
- if (!locked)
- AXE_UNLOCK(sc);
-}
-
-/*
- * Set media options.
- */
-static int
-axe_ifmedia_upd(struct ifnet *ifp)
-{
- struct axe_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
- int error;
-
- AXE_LOCK_ASSERT(sc, MA_OWNED);
-
- if (mii->mii_instance) {
- struct mii_softc *miisc;
-
- LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
- mii_phy_reset(miisc);
- }
- error = mii_mediachg(mii);
- return (error);
-}
-
-/*
- * Report current media status.
- */
-static void
-axe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct axe_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- AXE_LOCK(sc);
- mii_pollstat(mii);
- AXE_UNLOCK(sc);
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
-}
-
-static void
-axe_setmulti(struct usb2_ether *ue)
-{
- struct axe_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
- struct ifmultiaddr *ifma;
- uint32_t h = 0;
- uint16_t rxmode;
- uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
- AXE_LOCK_ASSERT(sc, MA_OWNED);
-
- axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode);
- rxmode = le16toh(rxmode);
-
- if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
- rxmode |= AXE_RXCMD_ALLMULTI;
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
- return;
- }
- rxmode &= ~AXE_RXCMD_ALLMULTI;
-
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
- {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
- hashtbl[h / 8] |= 1 << (h % 8);
- }
- IF_ADDR_UNLOCK(ifp);
-
- axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, (void *)&hashtbl);
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
-}
-
-static int
-axe_get_phyno(struct axe_softc *sc, int sel)
-{
- int phyno;
-
- switch (AXE_PHY_TYPE(sc->sc_phyaddrs[sel])) {
- case PHY_TYPE_100_HOME:
- case PHY_TYPE_GIG:
- phyno = AXE_PHY_NO(sc->sc_phyaddrs[sel]);
- break;
- case PHY_TYPE_SPECIAL:
- /* FALLTHROUGH */
- case PHY_TYPE_RSVD:
- /* FALLTHROUGH */
- case PHY_TYPE_NON_SUP:
- /* FALLTHROUGH */
- default:
- phyno = -1;
- break;
- }
-
- return (phyno);
-}
-
-static void
-axe_ax88178_init(struct axe_softc *sc)
-{
- int gpio0 = 0, phymode = 0;
- uint16_t eeprom;
-
- axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL);
- /* XXX magic */
- axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom);
- eeprom = le16toh(eeprom);
- axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL);
-
- /* if EEPROM is invalid we have to use to GPIO0 */
- if (eeprom == 0xffff) {
- phymode = 0;
- gpio0 = 1;
- } else {
- phymode = eeprom & 7;
- gpio0 = (eeprom & 0x80) ? 0 : 1;
- }
-
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 16);
-
- if ((eeprom >> 8) != 0x01) {
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 32);
-
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 3);
-
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 32);
- } else {
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 32);
-
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 32);
- }
-
- /* soft reset */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 4);
-
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
- AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 4);
- /* Enable MII/GMII/RGMII interface to work with external PHY. */
- axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 4);
-
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
-}
-
-static void
-axe_ax88772_init(struct axe_softc *sc)
-{
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 16);
-
- if (sc->sc_phyno == AXE_772_PHY_NO_EPHY) {
- /* ask for the embedded PHY */
- axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 64);
-
- /* power down and reset state, pin reset state */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
- AXE_SW_RESET_CLEAR, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 16);
-
- /* power down/reset state, pin operating state */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
- AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 4);
-
- /* power up, reset */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL);
-
- /* power up, operating */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
- AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL);
- } else {
- /* ask for external PHY */
- axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x00, NULL);
- usb2_ether_pause(&sc->sc_ue, hz / 64);
-
- /* power down internal PHY */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
- AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
- }
-
- usb2_ether_pause(&sc->sc_ue, hz / 4);
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
-}
-
-static void
-axe_reset(struct axe_softc *sc)
-{
- struct usb2_config_descriptor *cd;
- usb2_error_t err;
-
- cd = usb2_get_config_descriptor(sc->sc_ue.ue_udev);
-
- err = usb2_req_set_config(sc->sc_ue.ue_udev, &sc->sc_mtx,
- cd->bConfigurationValue);
- if (err)
- DPRINTF("reset failed (ignored)\n");
-
- /* Wait a little while for the chip to get its brains in order. */
- usb2_ether_pause(&sc->sc_ue, hz / 100);
-}
-
-static void
-axe_attach_post(struct usb2_ether *ue)
-{
- struct axe_softc *sc = usb2_ether_getsc(ue);
-
- /*
- * Load PHY indexes first. Needed by axe_xxx_init().
- */
- axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, sc->sc_phyaddrs);
-#if 1
- device_printf(sc->sc_ue.ue_dev, "PHYADDR 0x%02x:0x%02x\n",
- sc->sc_phyaddrs[0], sc->sc_phyaddrs[1]);
-#endif
- sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI);
- if (sc->sc_phyno == -1)
- sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC);
- if (sc->sc_phyno == -1) {
- device_printf(sc->sc_ue.ue_dev,
- "no valid PHY address found, assuming PHY address 0\n");
- sc->sc_phyno = 0;
- }
-
- if (sc->sc_flags & AXE_FLAG_178)
- axe_ax88178_init(sc);
- else if (sc->sc_flags & AXE_FLAG_772)
- axe_ax88772_init(sc);
-
- /*
- * Get station address.
- */
- if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772))
- axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, ue->ue_eaddr);
- else
- axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, ue->ue_eaddr);
-
- /*
- * Fetch IPG values.
- */
- axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs);
-}
-
-/*
- * Probe for a AX88172 chip.
- */
-static int
-axe_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
- if (uaa->info.bConfigIndex != AXE_CONFIG_IDX)
- return (ENXIO);
- if (uaa->info.bIfaceIndex != AXE_IFACE_IDX)
- return (ENXIO);
-
- return (usb2_lookup_id_by_uaa(axe_devs, sizeof(axe_devs), uaa));
-}
-
-/*
- * Attach the interface. Allocate softc structures, do ifmedia
- * setup and ethernet/BPF attach.
- */
-static int
-axe_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct axe_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
- uint8_t iface_index;
- int error;
-
- sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
-
- device_set_usb2_desc(dev);
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
-
- iface_index = AXE_IFACE_IDX;
- error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
- axe_config, AXE_N_TRANSFER, sc, &sc->sc_mtx);
- if (error) {
- device_printf(dev, "allocating USB transfers failed!\n");
- goto detach;
- }
-
- ue->ue_sc = sc;
- ue->ue_dev = dev;
- ue->ue_udev = uaa->device;
- ue->ue_mtx = &sc->sc_mtx;
- ue->ue_methods = &axe_ue_methods;
-
- error = usb2_ether_ifattach(ue);
- if (error) {
- device_printf(dev, "could not attach interface\n");
- goto detach;
- }
- return (0); /* success */
-
-detach:
- axe_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-axe_detach(device_t dev)
-{
- struct axe_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
-
- usb2_transfer_unsetup(sc->sc_xfer, AXE_N_TRANSFER);
- usb2_ether_ifdetach(ue);
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static void
-axe_intr_callback(struct usb2_xfer *xfer)
-{
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-#if (AXE_BULK_BUF_SIZE >= 0x10000)
-#error "Please update axe_bulk_read_callback()!"
-#endif
-
-static void
-axe_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct axe_softc *sc = xfer->priv_sc;
- struct usb2_ether *ue = &sc->sc_ue;
- struct ifnet *ifp = usb2_ether_getifp(ue);
- struct axe_sframe_hdr hdr;
- int error, pos, len, adjust;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- pos = 0;
- while (1) {
- if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) {
- if (xfer->actlen < sizeof(hdr)) {
- /* too little data */
- break;
- }
- usb2_copy_out(xfer->frbuffers, pos, &hdr, sizeof(hdr));
-
- if ((hdr.len ^ hdr.ilen) != 0xFFFF) {
- /* we lost sync */
- break;
- }
- xfer->actlen -= sizeof(hdr);
- pos += sizeof(hdr);
-
- len = le16toh(hdr.len);
- if (len > xfer->actlen) {
- /* invalid length */
- break;
- }
- adjust = (len & 1);
-
- } else {
- len = xfer->actlen;
- adjust = 0;
- }
- error = usb2_ether_rxbuf(ue, xfer->frbuffers, pos, len);
- if (error)
- break;
-
- pos += len;
- xfer->actlen -= len;
-
- if (xfer->actlen <= adjust) {
- /* we are finished */
- goto tr_setup;
- }
- pos += adjust;
- xfer->actlen -= adjust;
- }
-
- /* count an error */
- ifp->if_ierrors++;
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- usb2_ether_rxflush(ue);
- return;
-
- default: /* Error */
- DPRINTF("bulk read error, %s\n",
- usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-#if ((AXE_BULK_BUF_SIZE >= 0x10000) || (AXE_BULK_BUF_SIZE < (MCLBYTES+4)))
-#error "Please update axe_bulk_write_callback()!"
-#endif
-
-static void
-axe_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct axe_softc *sc = xfer->priv_sc;
- struct axe_sframe_hdr hdr;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
- struct mbuf *m;
- int pos;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(11, "transfer complete\n");
- ifp->if_opackets++;
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- if ((sc->sc_flags & AXE_FLAG_LINK) == 0) {
- /*
- * don't send anything if there is no link !
- */
- return;
- }
- pos = 0;
-
- while (1) {
-
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
-
- if (m == NULL) {
- if (pos > 0)
- break; /* send out data */
- return;
- }
- if (m->m_pkthdr.len > MCLBYTES) {
- m->m_pkthdr.len = MCLBYTES;
- }
- if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) {
-
- hdr.len = htole16(m->m_pkthdr.len);
- hdr.ilen = ~hdr.len;
-
- usb2_copy_in(xfer->frbuffers, pos, &hdr, sizeof(hdr));
-
- pos += sizeof(hdr);
-
- /*
- * NOTE: Some drivers force a short packet
- * by appending a dummy header with zero
- * length at then end of the USB transfer.
- * This driver uses the
- * USB_FORCE_SHORT_XFER flag instead.
- */
- }
- usb2_m_copy_in(xfer->frbuffers, pos,
- m, 0, m->m_pkthdr.len);
-
- pos += m->m_pkthdr.len;
-
- /*
- * if there's a BPF listener, bounce a copy
- * of this frame to him:
- */
- BPF_MTAP(ifp, m);
-
- m_freem(m);
-
- if (sc->sc_flags & (AXE_FLAG_772 | AXE_FLAG_178)) {
- if (pos > (AXE_BULK_BUF_SIZE - MCLBYTES - sizeof(hdr))) {
- /* send out frame(s) */
- break;
- }
- } else {
- /* send out frame */
- break;
- }
- }
-
- xfer->frlengths[0] = pos;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- DPRINTFN(11, "transfer error, %s\n",
- usb2_errstr(xfer->error));
-
- ifp->if_oerrors++;
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-static void
-axe_tick(struct usb2_ether *ue)
-{
- struct axe_softc *sc = usb2_ether_getsc(ue);
- struct mii_data *mii = GET_MII(sc);
-
- AXE_LOCK_ASSERT(sc, MA_OWNED);
-
- mii_tick(mii);
- if ((sc->sc_flags & AXE_FLAG_LINK) == 0) {
- axe_miibus_statchg(ue->ue_dev);
- if ((sc->sc_flags & AXE_FLAG_LINK) != 0)
- axe_start(ue);
- }
-}
-
-static void
-axe_start(struct usb2_ether *ue)
-{
- struct axe_softc *sc = usb2_ether_getsc(ue);
-
- /*
- * start the USB transfers, if not already started:
- */
- usb2_transfer_start(sc->sc_xfer[AXE_INTR_DT_RD]);
- usb2_transfer_start(sc->sc_xfer[AXE_BULK_DT_RD]);
- usb2_transfer_start(sc->sc_xfer[AXE_BULK_DT_WR]);
-}
-
-static void
-axe_init(struct usb2_ether *ue)
-{
- struct axe_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
- uint16_t rxmode;
-
- AXE_LOCK_ASSERT(sc, MA_OWNED);
-
- /* Cancel pending I/O */
- axe_stop(ue);
-
-#ifdef notdef
- /* Set MAC address */
- axe_mac(sc, IF_LLADDR(ifp), 1);
-#endif
-
- /* Set transmitter IPG values */
- if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) {
- axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->sc_ipgs[2],
- (sc->sc_ipgs[1] << 8) | (sc->sc_ipgs[0]), NULL);
- } else {
- axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->sc_ipgs[0], NULL);
- axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->sc_ipgs[1], NULL);
- axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->sc_ipgs[2], NULL);
- }
-
- /* Enable receiver, set RX mode */
- rxmode = (AXE_RXCMD_MULTICAST | AXE_RXCMD_ENABLE);
- if (sc->sc_flags & (AXE_FLAG_178 | AXE_FLAG_772)) {
- rxmode |= AXE_178_RXCMD_MFB_2048; /* chip default */
- } else {
- rxmode |= AXE_172_RXCMD_UNICAST;
- }
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- rxmode |= AXE_RXCMD_PROMISC;
-
- if (ifp->if_flags & IFF_BROADCAST)
- rxmode |= AXE_RXCMD_BROADCAST;
-
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
-
- /* Load the multicast filter. */
- axe_setmulti(ue);
-
- usb2_transfer_set_stall(sc->sc_xfer[AXE_BULK_DT_WR]);
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- axe_start(ue);
-}
-
-static void
-axe_setpromisc(struct usb2_ether *ue)
-{
- struct axe_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
- uint16_t rxmode;
-
- axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode);
-
- rxmode = le16toh(rxmode);
-
- if (ifp->if_flags & IFF_PROMISC) {
- rxmode |= AXE_RXCMD_PROMISC;
- } else {
- rxmode &= ~AXE_RXCMD_PROMISC;
- }
-
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
-
- axe_setmulti(ue);
-}
-
-static void
-axe_stop(struct usb2_ether *ue)
-{
- struct axe_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- AXE_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- sc->sc_flags &= ~AXE_FLAG_LINK;
-
- /*
- * stop all the transfers, if not already stopped:
- */
- usb2_transfer_stop(sc->sc_xfer[AXE_BULK_DT_WR]);
- usb2_transfer_stop(sc->sc_xfer[AXE_BULK_DT_RD]);
- usb2_transfer_stop(sc->sc_xfer[AXE_INTR_DT_RD]);
-
- axe_reset(sc);
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static int
-axe_shutdown(device_t dev)
-{
- struct axe_softc *sc = device_get_softc(dev);
-
- usb2_ether_ifshutdown(&sc->sc_ue);
-
- return (0);
-}
diff --git a/sys/dev/usb2/ethernet/if_axereg.h b/sys/dev/usb2/ethernet/if_axereg.h
deleted file mode 100644
index dc063e3..0000000
--- a/sys/dev/usb2/ethernet/if_axereg.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000-2003
- * Bill Paul <wpaul@windriver.com>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * Definitions for the ASIX Electronics AX88172, AX88178
- * and AX88772 to ethernet controllers.
- */
-
-/*
- * Vendor specific commands. ASIX conveniently doesn't document the 'set
- * NODEID' command in their datasheet (thanks a lot guys).
- * To make handling these commands easier, I added some extra data which is
- * decided by the axe_cmd() routine. Commands are encoded in 16 bits, with
- * the format: LDCC. L and D are both nibbles in the high byte. L represents
- * the data length (0 to 15) and D represents the direction (0 for vendor read,
- * 1 for vendor write). CC is the command byte, as specified in the manual.
- */
-
-#define AXE_CMD_IS_WRITE(x) (((x) & 0x0F00) >> 8)
-#define AXE_CMD_LEN(x) (((x) & 0xF000) >> 12)
-#define AXE_CMD_CMD(x) ((x) & 0x00FF)
-
-#define AXE_172_CMD_READ_RXTX_SRAM 0x2002
-#define AXE_182_CMD_READ_RXTX_SRAM 0x8002
-#define AXE_172_CMD_WRITE_RX_SRAM 0x0103
-#define AXE_182_CMD_WRITE_RXTX_SRAM 0x8103
-#define AXE_172_CMD_WRITE_TX_SRAM 0x0104
-#define AXE_CMD_MII_OPMODE_SW 0x0106
-#define AXE_CMD_MII_READ_REG 0x2007
-#define AXE_CMD_MII_WRITE_REG 0x2108
-#define AXE_CMD_MII_READ_OPMODE 0x1009
-#define AXE_CMD_MII_OPMODE_HW 0x010A
-#define AXE_CMD_SROM_READ 0x200B
-#define AXE_CMD_SROM_WRITE 0x010C
-#define AXE_CMD_SROM_WR_ENABLE 0x010D
-#define AXE_CMD_SROM_WR_DISABLE 0x010E
-#define AXE_CMD_RXCTL_READ 0x200F
-#define AXE_CMD_RXCTL_WRITE 0x0110
-#define AXE_CMD_READ_IPG012 0x3011
-#define AXE_172_CMD_WRITE_IPG0 0x0112
-#define AXE_178_CMD_WRITE_IPG012 0x0112
-#define AXE_172_CMD_WRITE_IPG1 0x0113
-#define AXE_178_CMD_READ_NODEID 0x6013
-#define AXE_172_CMD_WRITE_IPG2 0x0114
-#define AXE_178_CMD_WRITE_NODEID 0x6114
-#define AXE_CMD_READ_MCAST 0x8015
-#define AXE_CMD_WRITE_MCAST 0x8116
-#define AXE_172_CMD_READ_NODEID 0x6017
-#define AXE_172_CMD_WRITE_NODEID 0x6118
-
-#define AXE_CMD_READ_PHYID 0x2019
-#define AXE_172_CMD_READ_MEDIA 0x101A
-#define AXE_178_CMD_READ_MEDIA 0x201A
-#define AXE_CMD_WRITE_MEDIA 0x011B
-#define AXE_CMD_READ_MONITOR_MODE 0x101C
-#define AXE_CMD_WRITE_MONITOR_MODE 0x011D
-#define AXE_CMD_READ_GPIO 0x101E
-#define AXE_CMD_WRITE_GPIO 0x011F
-
-#define AXE_CMD_SW_RESET_REG 0x0120
-#define AXE_CMD_SW_PHY_STATUS 0x0021
-#define AXE_CMD_SW_PHY_SELECT 0x0122
-
-#define AXE_SW_RESET_CLEAR 0x00
-#define AXE_SW_RESET_RR 0x01
-#define AXE_SW_RESET_RT 0x02
-#define AXE_SW_RESET_PRTE 0x04
-#define AXE_SW_RESET_PRL 0x08
-#define AXE_SW_RESET_BZ 0x10
-#define AXE_SW_RESET_IPRL 0x20
-#define AXE_SW_RESET_IPPD 0x40
-
-/* AX88178 documentation says to always write this bit... */
-#define AXE_178_RESET_MAGIC 0x40
-
-#define AXE_178_MEDIA_GMII 0x0001
-#define AXE_MEDIA_FULL_DUPLEX 0x0002
-#define AXE_172_MEDIA_TX_ABORT_ALLOW 0x0004
-
-/* AX88178/88772 documentation says to always write 1 to bit 2 */
-#define AXE_178_MEDIA_MAGIC 0x0004
-/* AX88772 documentation says to always write 0 to bit 3 */
-#define AXE_178_MEDIA_ENCK 0x0008
-#define AXE_172_MEDIA_FLOW_CONTROL_EN 0x0010
-#define AXE_178_MEDIA_RXFLOW_CONTROL_EN 0x0010
-#define AXE_178_MEDIA_TXFLOW_CONTROL_EN 0x0020
-#define AXE_178_MEDIA_JUMBO_EN 0x0040
-#define AXE_178_MEDIA_LTPF_ONLY 0x0080
-#define AXE_178_MEDIA_RX_EN 0x0100
-#define AXE_178_MEDIA_100TX 0x0200
-#define AXE_178_MEDIA_SBP 0x0800
-#define AXE_178_MEDIA_SUPERMAC 0x1000
-
-#define AXE_RXCMD_PROMISC 0x0001
-#define AXE_RXCMD_ALLMULTI 0x0002
-#define AXE_172_RXCMD_UNICAST 0x0004
-#define AXE_178_RXCMD_KEEP_INVALID_CRC 0x0004
-#define AXE_RXCMD_BROADCAST 0x0008
-#define AXE_RXCMD_MULTICAST 0x0010
-#define AXE_RXCMD_ENABLE 0x0080
-#define AXE_178_RXCMD_MFB_MASK 0x0300
-#define AXE_178_RXCMD_MFB_2048 0x0000
-#define AXE_178_RXCMD_MFB_4096 0x0100
-#define AXE_178_RXCMD_MFB_8192 0x0200
-#define AXE_178_RXCMD_MFB_16384 0x0300
-
-#define AXE_PHY_SEL_PRI 1
-#define AXE_PHY_SEL_SEC 0
-#define AXE_PHY_TYPE_MASK 0xE0
-#define AXE_PHY_TYPE_SHIFT 5
-#define AXE_PHY_TYPE(x) \
- (((x) & AXE_PHY_TYPE_MASK) >> AXE_PHY_TYPE_SHIFT)
-
-#define PHY_TYPE_100_HOME 0 /* 10/100 or 1M HOME PHY */
-#define PHY_TYPE_GIG 1 /* Gigabit PHY */
-#define PHY_TYPE_SPECIAL 4 /* Special case */
-#define PHY_TYPE_RSVD 5 /* Reserved */
-#define PHY_TYPE_NON_SUP 7 /* Non-supported PHY */
-
-#define AXE_PHY_NO_MASK 0x1F
-#define AXE_PHY_NO(x) ((x) & AXE_PHY_NO_MASK)
-
-#define AXE_772_PHY_NO_EPHY 0x10 /* Embedded 10/100 PHY of AX88772 */
-
-#define AXE_BULK_BUF_SIZE 16384 /* bytes */
-
-#define AXE_CTL_READ 0x01
-#define AXE_CTL_WRITE 0x02
-
-#define AXE_CONFIG_IDX 0 /* config number 1 */
-#define AXE_IFACE_IDX 0
-
-struct axe_sframe_hdr {
- uint16_t len;
- uint16_t ilen;
-} __packed;
-
-#define GET_MII(sc) usb2_ether_getmii(&(sc)->sc_ue)
-
-/* The interrupt endpoint is currently unused by the ASIX part. */
-enum {
- AXE_BULK_DT_WR,
- AXE_BULK_DT_RD,
- AXE_INTR_DT_RD,
- AXE_N_TRANSFER,
-};
-
-struct axe_softc {
- struct usb2_ether sc_ue;
- struct mtx sc_mtx;
- struct usb2_xfer *sc_xfer[AXE_N_TRANSFER];
- int sc_phyno;
-
- int sc_flags;
-#define AXE_FLAG_LINK 0x0001
-#define AXE_FLAG_772 0x1000 /* AX88772 */
-#define AXE_FLAG_178 0x2000 /* AX88178 */
-
- uint8_t sc_ipgs[3];
- uint8_t sc_phyaddrs[2];
-};
-
-#define AXE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
-#define AXE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
-#define AXE_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)
diff --git a/sys/dev/usb2/ethernet/if_cdce2.c b/sys/dev/usb2/ethernet/if_cdce2.c
deleted file mode 100644
index 78b54cf..0000000
--- a/sys/dev/usb2/ethernet/if_cdce2.c
+++ /dev/null
@@ -1,771 +0,0 @@
-/* $NetBSD: if_cdce.c,v 1.4 2004/10/24 12:50:54 augustss Exp $ */
-
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com>
- * Copyright (c) 2003-2005 Craig Boston
- * Copyright (c) 2004 Daniel Hartmeier
- * Copyright (c) 2009 Hans Petter Selasky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul, THE VOICES IN HIS HEAD OR
- * THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * USB Communication Device Class (Ethernet Networking Control Model)
- * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR cdce_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_parse.h>
-#include <dev/usb2/core/usb2_device.h>
-
-#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_cdcereg.h>
-
-static device_probe_t cdce_probe;
-static device_attach_t cdce_attach;
-static device_detach_t cdce_detach;
-static device_shutdown_t cdce_shutdown;
-static device_suspend_t cdce_suspend;
-static device_resume_t cdce_resume;
-static usb2_handle_request_t cdce_handle_request;
-
-static usb2_callback_t cdce_bulk_write_callback;
-static usb2_callback_t cdce_bulk_read_callback;
-static usb2_callback_t cdce_intr_read_callback;
-static usb2_callback_t cdce_intr_write_callback;
-
-static usb2_ether_fn_t cdce_attach_post;
-static usb2_ether_fn_t cdce_init;
-static usb2_ether_fn_t cdce_stop;
-static usb2_ether_fn_t cdce_start;
-static usb2_ether_fn_t cdce_setmulti;
-static usb2_ether_fn_t cdce_setpromisc;
-
-static uint32_t cdce_m_crc32(struct mbuf *, uint32_t, uint32_t);
-
-#if USB_DEBUG
-static int cdce_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, cdce, CTLFLAG_RW, 0, "USB CDC-Ethernet");
-SYSCTL_INT(_hw_usb2_cdce, OID_AUTO, debug, CTLFLAG_RW, &cdce_debug, 0,
- "Debug level");
-#endif
-
-static const struct usb2_config cdce_config[CDCE_N_TRANSFER] = {
-
- [CDCE_BULK_A] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .if_index = 0,
- /* Host Mode */
- .mh.frames = CDCE_FRAMES_MAX,
- .mh.bufsize = (CDCE_FRAMES_MAX * MCLBYTES),
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,},
- .mh.callback = cdce_bulk_write_callback,
- .mh.timeout = 10000, /* 10 seconds */
- /* Device Mode */
- .md.frames = CDCE_FRAMES_MAX,
- .md.bufsize = (CDCE_FRAMES_MAX * MCLBYTES),
- .md.flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,.ext_buffer = 1,},
- .md.callback = cdce_bulk_read_callback,
- .md.timeout = 0, /* no timeout */
- },
-
- [CDCE_BULK_B] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .if_index = 0,
- /* Host Mode */
- .mh.frames = CDCE_FRAMES_MAX,
- .mh.bufsize = (CDCE_FRAMES_MAX * MCLBYTES),
- .mh.flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,.ext_buffer = 1,},
- .mh.callback = cdce_bulk_read_callback,
- .mh.timeout = 0, /* no timeout */
- /* Device Mode */
- .md.frames = CDCE_FRAMES_MAX,
- .md.bufsize = (CDCE_FRAMES_MAX * MCLBYTES),
- .md.flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,},
- .md.callback = cdce_bulk_write_callback,
- .md.timeout = 10000, /* 10 seconds */
- },
-
- [CDCE_INTR] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .if_index = 1,
- /* Host Mode */
- .mh.bufsize = CDCE_IND_SIZE_MAX,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,},
- .mh.callback = cdce_intr_read_callback,
- .mh.timeout = 0,
- /* Device Mode */
- .md.bufsize = CDCE_IND_SIZE_MAX,
- .md.flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,},
- .md.callback = cdce_intr_write_callback,
- .md.timeout = 10000, /* 10 seconds */
- },
-};
-
-static device_method_t cdce_methods[] = {
- /* USB interface */
- DEVMETHOD(usb2_handle_request, cdce_handle_request),
-
- /* Device interface */
- DEVMETHOD(device_probe, cdce_probe),
- DEVMETHOD(device_attach, cdce_attach),
- DEVMETHOD(device_detach, cdce_detach),
- DEVMETHOD(device_suspend, cdce_suspend),
- DEVMETHOD(device_resume, cdce_resume),
- DEVMETHOD(device_shutdown, cdce_shutdown),
-
- {0, 0}
-};
-
-static driver_t cdce_driver = {
- .name = "cdce",
- .methods = cdce_methods,
- .size = sizeof(struct cdce_softc),
-};
-
-static devclass_t cdce_devclass;
-
-DRIVER_MODULE(cdce, ushub, cdce_driver, cdce_devclass, NULL, 0);
-MODULE_VERSION(cdce, 1);
-MODULE_DEPEND(cdce, usb2_ethernet, 1, 1, 1);
-MODULE_DEPEND(cdce, usb2_core, 1, 1, 1);
-MODULE_DEPEND(cdce, ether, 1, 1, 1);
-
-static const struct usb2_ether_methods cdce_ue_methods = {
- .ue_attach_post = cdce_attach_post,
- .ue_start = cdce_start,
- .ue_init = cdce_init,
- .ue_stop = cdce_stop,
- .ue_setmulti = cdce_setmulti,
- .ue_setpromisc = cdce_setpromisc,
-};
-
-static const struct usb2_device_id cdce_devs[] = {
- {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)},
- {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)},
-
- {USB_VPI(USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, CDCE_FLAG_NO_UNION)},
- {USB_VPI(USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, CDCE_FLAG_NO_UNION)},
- {USB_VPI(USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, CDCE_FLAG_NO_UNION)},
- {USB_VPI(USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00, CDCE_FLAG_NO_UNION)},
- {USB_VPI(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
- {USB_VPI(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
- {USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_ETHERNETGADGET, CDCE_FLAG_NO_UNION)},
- {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501, CDCE_FLAG_NO_UNION)},
- {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500, CDCE_FLAG_ZAURUS)},
- {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
- {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLA300, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
- {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC700, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
- {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC750, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)},
-};
-
-static int
-cdce_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- return (usb2_lookup_id_by_uaa(cdce_devs, sizeof(cdce_devs), uaa));
-}
-
-static void
-cdce_attach_post(struct usb2_ether *ue)
-{
- /* no-op */
- return;
-}
-
-static int
-cdce_attach(device_t dev)
-{
- struct cdce_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct usb2_interface *iface;
- const struct usb2_cdc_union_descriptor *ud;
- const struct usb2_interface_descriptor *id;
- const struct usb2_cdc_ethernet_descriptor *ued;
- int error;
- uint8_t i;
- char eaddr_str[5 * ETHER_ADDR_LEN]; /* approx */
-
- sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
-
- device_set_usb2_desc(dev);
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
-
- if (sc->sc_flags & CDCE_FLAG_NO_UNION) {
- sc->sc_ifaces_index[0] = uaa->info.bIfaceIndex;
- sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex;
- sc->sc_data_iface_no = 0; /* not used */
- goto alloc_transfers;
- }
- ud = usb2_find_descriptor
- (uaa->device, NULL, uaa->info.bIfaceIndex,
- UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_UNION, 0 - 1);
-
- if ((ud == NULL) || (ud->bLength < sizeof(*ud))) {
- device_printf(dev, "no union descriptor!\n");
- goto detach;
- }
- sc->sc_data_iface_no = ud->bSlaveInterface[0];
-
- for (i = 0;; i++) {
-
- iface = usb2_get_iface(uaa->device, i);
-
- if (iface) {
-
- id = usb2_get_interface_descriptor(iface);
-
- if (id && (id->bInterfaceNumber ==
- sc->sc_data_iface_no)) {
- sc->sc_ifaces_index[0] = i;
- sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex;
- usb2_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
- break;
- }
- } else {
- device_printf(dev, "no data interface found!\n");
- goto detach;
- }
- }
-
- /*
- * <quote>
- *
- * The Data Class interface of a networking device shall have
- * a minimum of two interface settings. The first setting
- * (the default interface setting) includes no endpoints and
- * therefore no networking traffic is exchanged whenever the
- * default interface setting is selected. One or more
- * additional interface settings are used for normal
- * operation, and therefore each includes a pair of endpoints
- * (one IN, and one OUT) to exchange network traffic. Select
- * an alternate interface setting to initialize the network
- * aspects of the device and to enable the exchange of
- * network traffic.
- *
- * </quote>
- *
- * Some devices, most notably cable modems, include interface
- * settings that have no IN or OUT endpoint, therefore loop
- * through the list of all available interface settings
- * looking for one with both IN and OUT endpoints.
- */
-
-alloc_transfers:
-
- for (i = 0; i != 32; i++) {
-
- error = usb2_set_alt_interface_index
- (uaa->device, sc->sc_ifaces_index[0], i);
-
- if (error) {
- device_printf(dev, "no valid alternate "
- "setting found!\n");
- goto detach;
- }
- error = usb2_transfer_setup
- (uaa->device, sc->sc_ifaces_index,
- sc->sc_xfer, cdce_config, CDCE_N_TRANSFER,
- sc, &sc->sc_mtx);
-
- if (error == 0) {
- break;
- }
- }
-
- ued = usb2_find_descriptor
- (uaa->device, NULL, uaa->info.bIfaceIndex,
- UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_ENF, 0 - 1);
-
- if ((ued == NULL) || (ued->bLength < sizeof(*ued))) {
- error = USB_ERR_INVAL;
- } else {
- error = usb2_req_get_string_any(uaa->device, NULL,
- eaddr_str, sizeof(eaddr_str), ued->iMacAddress);
- }
-
- if (error) {
-
- /* fake MAC address */
-
- device_printf(dev, "faking MAC address\n");
- sc->sc_ue.ue_eaddr[0] = 0x2a;
- memcpy(&sc->sc_ue.ue_eaddr[1], &ticks, sizeof(uint32_t));
- sc->sc_ue.ue_eaddr[5] = device_get_unit(dev);
-
- } else {
-
- bzero(sc->sc_ue.ue_eaddr, sizeof(sc->sc_ue.ue_eaddr));
-
- for (i = 0; i != (ETHER_ADDR_LEN * 2); i++) {
-
- char c = eaddr_str[i];
-
- if ('0' <= c && c <= '9')
- c -= '0';
- else if (c != 0)
- c -= 'A' - 10;
- else
- break;
-
- c &= 0xf;
-
- if ((i & 1) == 0)
- c <<= 4;
- sc->sc_ue.ue_eaddr[i / 2] |= c;
- }
-
- if (uaa->usb2_mode == USB_MODE_DEVICE) {
- /*
- * Do not use the same MAC address like the peer !
- */
- sc->sc_ue.ue_eaddr[5] ^= 0xFF;
- }
- }
-
- ue->ue_sc = sc;
- ue->ue_dev = dev;
- ue->ue_udev = uaa->device;
- ue->ue_mtx = &sc->sc_mtx;
- ue->ue_methods = &cdce_ue_methods;
-
- error = usb2_ether_ifattach(ue);
- if (error) {
- device_printf(dev, "could not attach interface\n");
- goto detach;
- }
- return (0); /* success */
-
-detach:
- cdce_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-cdce_detach(device_t dev)
-{
- struct cdce_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
-
- /* stop all USB transfers first */
- usb2_transfer_unsetup(sc->sc_xfer, CDCE_N_TRANSFER);
- usb2_ether_ifdetach(ue);
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static void
-cdce_start(struct usb2_ether *ue)
-{
- struct cdce_softc *sc = usb2_ether_getsc(ue);
-
- /*
- * Start the USB transfers, if not already started:
- */
- usb2_transfer_start(sc->sc_xfer[CDCE_BULK_B]);
- usb2_transfer_start(sc->sc_xfer[CDCE_BULK_A]);
-}
-
-static void
-cdce_free_queue(struct mbuf **ppm, uint8_t n)
-{
- uint8_t x;
- for (x = 0; x != n; x++) {
- if (ppm[x] != NULL) {
- m_freem(ppm[x]);
- ppm[x] = NULL;
- }
- }
-}
-
-static void
-cdce_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct cdce_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
- struct mbuf *m;
- struct mbuf *mt;
- uint32_t crc;
- uint8_t x;
-
- DPRINTFN(1, "\n");
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(11, "transfer complete: "
- "%u bytes in %u frames\n", xfer->actlen,
- xfer->aframes);
-
- ifp->if_opackets++;
-
- /* free all previous TX buffers */
- cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX);
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- for (x = 0; x != CDCE_FRAMES_MAX; x++) {
-
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
-
- if (m == NULL)
- break;
-
- if (sc->sc_flags & CDCE_FLAG_ZAURUS) {
- /*
- * Zaurus wants a 32-bit CRC appended
- * to every frame
- */
-
- crc = cdce_m_crc32(m, 0, m->m_pkthdr.len);
- crc = htole32(crc);
-
- if (!m_append(m, 4, (void *)&crc)) {
- m_freem(m);
- ifp->if_oerrors++;
- continue;
- }
- }
- if (m->m_len != m->m_pkthdr.len) {
- mt = m_defrag(m, M_DONTWAIT);
- if (mt == NULL) {
- m_freem(m);
- ifp->if_oerrors++;
- continue;
- }
- m = mt;
- }
- if (m->m_pkthdr.len > MCLBYTES) {
- m->m_pkthdr.len = MCLBYTES;
- }
- sc->sc_tx_buf[x] = m;
- xfer->frlengths[x] = m->m_len;
- usb2_set_frame_data(xfer, m->m_data, x);
-
- /*
- * If there's a BPF listener, bounce a copy of
- * this frame to him:
- */
- BPF_MTAP(ifp, m);
- }
- if (x != 0) {
- xfer->nframes = x;
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- DPRINTFN(11, "transfer error, %s\n",
- usb2_errstr(xfer->error));
-
- /* free all previous TX buffers */
- cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX);
-
- /* count output errors */
- ifp->if_oerrors++;
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- break;
- }
-}
-
-static int32_t
-cdce_m_crc32_cb(void *arg, void *src, uint32_t count)
-{
- uint32_t *p_crc = arg;
-
- *p_crc = crc32_raw(src, count, *p_crc);
- return (0);
-}
-
-static uint32_t
-cdce_m_crc32(struct mbuf *m, uint32_t src_offset, uint32_t src_len)
-{
- uint32_t crc = 0xFFFFFFFF;
- int error;
-
- error = m_apply(m, src_offset, src_len, cdce_m_crc32_cb, &crc);
- return (crc ^ 0xFFFFFFFF);
-}
-
-static void
-cdce_init(struct usb2_ether *ue)
-{
- struct cdce_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- CDCE_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
-
- /* start interrupt transfer */
- usb2_transfer_start(sc->sc_xfer[CDCE_INTR]);
-
- /* stall data write direction, which depends on USB mode */
- if (usb2_get_mode(sc->sc_ue.ue_udev) == USB_MODE_HOST)
- usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_A]);
- else
- usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_B]);
-
- /* start data transfers */
- cdce_start(ue);
-}
-
-static void
-cdce_stop(struct usb2_ether *ue)
-{
- struct cdce_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- CDCE_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-
- /*
- * stop all the transfers, if not already stopped:
- */
- usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_A]);
- usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_B]);
- usb2_transfer_stop(sc->sc_xfer[CDCE_INTR]);
-}
-
-static void
-cdce_setmulti(struct usb2_ether *ue)
-{
- /* no-op */
- return;
-}
-
-static void
-cdce_setpromisc(struct usb2_ether *ue)
-{
- /* no-op */
- return;
-}
-
-static int
-cdce_shutdown(device_t dev)
-{
- struct cdce_softc *sc = device_get_softc(dev);
-
- usb2_ether_ifshutdown(&sc->sc_ue);
-
- return (0);
-}
-
-static int
-cdce_suspend(device_t dev)
-{
- device_printf(dev, "Suspending\n");
- return (0);
-}
-
-static int
-cdce_resume(device_t dev)
-{
- device_printf(dev, "Resuming\n");
- return (0);
-}
-
-static void
-cdce_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct cdce_softc *sc = xfer->priv_sc;
- struct mbuf *m;
- uint8_t x;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- DPRINTF("received %u bytes in %u frames\n",
- xfer->actlen, xfer->aframes);
-
- for (x = 0; x != xfer->aframes; x++) {
-
- m = sc->sc_rx_buf[x];
- sc->sc_rx_buf[x] = NULL;
-
- /* Strip off CRC added by Zaurus, if any */
- if ((sc->sc_flags & CDCE_FLAG_ZAURUS) &&
- (xfer->frlengths[x] >= 14))
- xfer->frlengths[x] -= 4;
-
- if (xfer->frlengths[x] < sizeof(struct ether_header)) {
- m_freem(m);
- continue;
- }
- /* queue up mbuf */
- usb2_ether_rxmbuf(&sc->sc_ue, m, xfer->frlengths[x]);
- }
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
- /*
- * TODO: Implement support for multi frame transfers,
- * when the USB hardware supports it.
- */
- for (x = 0; x != 1; x++) {
- if (sc->sc_rx_buf[x] == NULL) {
- m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (m == NULL)
- goto tr_stall;
- sc->sc_rx_buf[x] = m;
- /* adjust for ethernet */
- m->m_len = m->m_pkthdr.len = MCLBYTES;
- m_adj(m, ETHER_ALIGN);
- } else {
- m = sc->sc_rx_buf[x];
- }
-
- usb2_set_frame_data(xfer, m->m_data, x);
- xfer->frlengths[x] = m->m_len;
- }
- /* set number of frames and start hardware */
- xfer->nframes = x;
- usb2_start_hardware(xfer);
- /* flush any received frames */
- usb2_ether_rxflush(&sc->sc_ue);
- break;
-
- default: /* Error */
- DPRINTF("error = %s\n",
- usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
-tr_stall:
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- xfer->nframes = 0;
- usb2_start_hardware(xfer);
- break;
- }
-
- /* need to free the RX-mbufs when we are cancelled */
- cdce_free_queue(sc->sc_rx_buf, CDCE_FRAMES_MAX);
- break;
- }
-}
-
-static void
-cdce_intr_read_callback(struct usb2_xfer *xfer)
-{
- ; /* style fix */
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- DPRINTF("Received %d bytes\n",
- xfer->actlen);
-
- /* TODO: decode some indications */
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* start clear stall */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- break;
- }
-}
-
-static void
-cdce_intr_write_callback(struct usb2_xfer *xfer)
-{
- ; /* style fix */
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- DPRINTF("Transferred %d bytes\n", xfer->actlen);
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
-#if 0
- xfer->frlengths[0] = XXX;
- usb2_start_hardware(xfer);
-#endif
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* start clear stall */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- break;
- }
-}
-
-static int
-cdce_handle_request(device_t dev,
- const void *req, void **pptr, uint16_t *plen,
- uint16_t offset, uint8_t is_complete)
-{
- return (ENXIO); /* use builtin handler */
-}
diff --git a/sys/dev/usb2/ethernet/if_cdcereg.h b/sys/dev/usb2/ethernet/if_cdcereg.h
deleted file mode 100644
index dac5121..0000000
--- a/sys/dev/usb2/ethernet/if_cdcereg.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*-
- * Copyright (c) 2003-2005 Craig Boston
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul, THE VOICES IN HIS HEAD OR
- * THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _USB_IF_CDCEREG_H_
-#define _USB_IF_CDCEREG_H_
-
-#define CDCE_FRAMES_MAX 8 /* units */
-#define CDCE_IND_SIZE_MAX 32 /* bytes */
-
-enum {
- CDCE_BULK_A,
- CDCE_BULK_B,
- CDCE_INTR,
- CDCE_N_TRANSFER,
-};
-
-struct cdce_softc {
- struct usb2_ether sc_ue;
- struct mtx sc_mtx;
- struct usb2_xfer *sc_xfer[CDCE_N_TRANSFER];
- struct mbuf *sc_rx_buf[CDCE_FRAMES_MAX];
- struct mbuf *sc_tx_buf[CDCE_FRAMES_MAX];
-
- int sc_flags;
-#define CDCE_FLAG_ZAURUS 0x0001
-#define CDCE_FLAG_NO_UNION 0x0002
-#define CDCE_FLAG_RX_DATA 0x0010
-
- uint8_t sc_eaddr_str_index;
- uint8_t sc_data_iface_no;
- uint8_t sc_ifaces_index[2];
-};
-
-#define CDCE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
-#define CDCE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
-#define CDCE_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)
-#endif /* _USB_IF_CDCEREG_H_ */
diff --git a/sys/dev/usb2/ethernet/if_cue2.c b/sys/dev/usb2/ethernet/if_cue2.c
deleted file mode 100644
index 630a210..0000000
--- a/sys/dev/usb2/ethernet/if_cue2.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * CATC USB-EL1210A USB to ethernet driver. Used in the CATC Netmate
- * adapters and others.
- *
- * Written by Bill Paul <wpaul@ee.columbia.edu>
- * Electrical Engineering Department
- * Columbia University, New York City
- */
-
-/*
- * The CATC USB-EL1210A provides USB ethernet support at 10Mbps. The
- * RX filter uses a 512-bit multicast hash table, single perfect entry
- * for the station address, and promiscuous mode. Unlike the ADMtek
- * and KLSI chips, the CATC ASIC supports read and write combining
- * mode where multiple packets can be transfered using a single bulk
- * transaction, which helps performance a great deal.
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR cue_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_cuereg.h>
-
-/*
- * Various supported device vendors/products.
- */
-
-/* Belkin F5U111 adapter covered by NETMATE entry */
-
-static const struct usb2_device_id cue_devs[] = {
- {USB_VPI(USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE, 0)},
- {USB_VPI(USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2, 0)},
- {USB_VPI(USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK, 0)},
-};
-
-/* prototypes */
-
-static device_probe_t cue_probe;
-static device_attach_t cue_attach;
-static device_detach_t cue_detach;
-static device_shutdown_t cue_shutdown;
-
-static usb2_callback_t cue_bulk_read_callback;
-static usb2_callback_t cue_bulk_write_callback;
-
-static usb2_ether_fn_t cue_attach_post;
-static usb2_ether_fn_t cue_init;
-static usb2_ether_fn_t cue_stop;
-static usb2_ether_fn_t cue_start;
-static usb2_ether_fn_t cue_tick;
-static usb2_ether_fn_t cue_setmulti;
-static usb2_ether_fn_t cue_setpromisc;
-
-static uint8_t cue_csr_read_1(struct cue_softc *, uint16_t);
-static uint16_t cue_csr_read_2(struct cue_softc *, uint8_t);
-static int cue_csr_write_1(struct cue_softc *, uint16_t, uint16_t);
-static int cue_mem(struct cue_softc *, uint8_t, uint16_t, void *, int);
-static int cue_getmac(struct cue_softc *, void *);
-static uint32_t cue_mchash(const uint8_t *);
-static void cue_reset(struct cue_softc *);
-
-#if USB_DEBUG
-static int cue_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, cue, CTLFLAG_RW, 0, "USB cue");
-SYSCTL_INT(_hw_usb2_cue, OID_AUTO, debug, CTLFLAG_RW, &cue_debug, 0,
- "Debug level");
-#endif
-
-static const struct usb2_config cue_config[CUE_N_TRANSFER] = {
-
- [CUE_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = (MCLBYTES + 2),
- .mh.flags = {.pipe_bof = 1,},
- .mh.callback = cue_bulk_write_callback,
- .mh.timeout = 10000, /* 10 seconds */
- },
-
- [CUE_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = (MCLBYTES + 2),
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = cue_bulk_read_callback,
- },
-};
-
-static device_method_t cue_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, cue_probe),
- DEVMETHOD(device_attach, cue_attach),
- DEVMETHOD(device_detach, cue_detach),
- DEVMETHOD(device_shutdown, cue_shutdown),
-
- {0, 0}
-};
-
-static driver_t cue_driver = {
- .name = "cue",
- .methods = cue_methods,
- .size = sizeof(struct cue_softc),
-};
-
-static devclass_t cue_devclass;
-
-DRIVER_MODULE(cue, ushub, cue_driver, cue_devclass, NULL, 0);
-MODULE_DEPEND(cue, usb2_ethernet, 1, 1, 1);
-MODULE_DEPEND(cue, usb2_core, 1, 1, 1);
-MODULE_DEPEND(cue, ether, 1, 1, 1);
-
-static const struct usb2_ether_methods cue_ue_methods = {
- .ue_attach_post = cue_attach_post,
- .ue_start = cue_start,
- .ue_init = cue_init,
- .ue_stop = cue_stop,
- .ue_tick = cue_tick,
- .ue_setmulti = cue_setmulti,
- .ue_setpromisc = cue_setpromisc,
-};
-
-#define CUE_SETBIT(sc, reg, x) \
- cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x))
-
-#define CUE_CLRBIT(sc, reg, x) \
- cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x))
-
-static uint8_t
-cue_csr_read_1(struct cue_softc *sc, uint16_t reg)
-{
- struct usb2_device_request req;
- uint8_t val;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = CUE_CMD_READREG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 1);
-
- if (usb2_ether_do_request(&sc->sc_ue, &req, &val, 1000)) {
- /* ignore any errors */
- }
- return (val);
-}
-
-static uint16_t
-cue_csr_read_2(struct cue_softc *sc, uint8_t reg)
-{
- struct usb2_device_request req;
- uint16_t val;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = CUE_CMD_READREG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 2);
-
- (void)usb2_ether_do_request(&sc->sc_ue, &req, &val, 1000);
- return (le16toh(val));
-}
-
-static int
-cue_csr_write_1(struct cue_softc *sc, uint16_t reg, uint16_t val)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = CUE_CMD_WRITEREG;
- USETW(req.wValue, val);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 0);
-
- return (usb2_ether_do_request(&sc->sc_ue, &req, NULL, 1000));
-}
-
-static int
-cue_mem(struct cue_softc *sc, uint8_t cmd, uint16_t addr, void *buf, int len)
-{
- struct usb2_device_request req;
-
- if (cmd == CUE_CMD_READSRAM)
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- else
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = cmd;
- USETW(req.wValue, 0);
- USETW(req.wIndex, addr);
- USETW(req.wLength, len);
-
- return (usb2_ether_do_request(&sc->sc_ue, &req, buf, 1000));
-}
-
-static int
-cue_getmac(struct cue_softc *sc, void *buf)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = CUE_CMD_GET_MACADDR;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, ETHER_ADDR_LEN);
-
- return (usb2_ether_do_request(&sc->sc_ue, &req, buf, 1000));
-}
-
-#define CUE_BITS 9
-
-static uint32_t
-cue_mchash(const uint8_t *addr)
-{
- uint32_t crc;
-
- /* Compute CRC for the address value. */
- crc = ether_crc32_le(addr, ETHER_ADDR_LEN);
-
- return (crc & ((1 << CUE_BITS) - 1));
-}
-
-static void
-cue_setpromisc(struct usb2_ether *ue)
-{
- struct cue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- CUE_LOCK_ASSERT(sc, MA_OWNED);
-
- /* if we want promiscuous mode, set the allframes bit */
- if (ifp->if_flags & IFF_PROMISC)
- CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
- else
- CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
-
- /* write multicast hash-bits */
- cue_setmulti(ue);
-}
-
-static void
-cue_setmulti(struct usb2_ether *ue)
-{
- struct cue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
- struct ifmultiaddr *ifma;
- uint32_t h = 0, i;
- uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
- CUE_LOCK_ASSERT(sc, MA_OWNED);
-
- if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
- for (i = 0; i < 8; i++)
- hashtbl[i] = 0xff;
- cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
- &hashtbl, 8);
- return;
- }
-
- /* now program new ones */
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
- {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = cue_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
- hashtbl[h >> 3] |= 1 << (h & 0x7);
- }
- IF_ADDR_UNLOCK(ifp);
-
- /*
- * Also include the broadcast address in the filter
- * so we can receive broadcast frames.
- */
- if (ifp->if_flags & IFF_BROADCAST) {
- h = cue_mchash(ifp->if_broadcastaddr);
- hashtbl[h >> 3] |= 1 << (h & 0x7);
- }
-
- cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, &hashtbl, 8);
-}
-
-static void
-cue_reset(struct cue_softc *sc)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = CUE_CMD_RESET;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- if (usb2_ether_do_request(&sc->sc_ue, &req, NULL, 1000)) {
- /* ignore any errors */
- }
-
- /*
- * wait a little while for the chip to get its brains in order:
- */
- usb2_ether_pause(&sc->sc_ue, hz / 100);
-}
-
-static void
-cue_attach_post(struct usb2_ether *ue)
-{
- struct cue_softc *sc = usb2_ether_getsc(ue);
-
- cue_getmac(sc, ue->ue_eaddr);
-}
-
-static int
-cue_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
- if (uaa->info.bConfigIndex != CUE_CONFIG_IDX)
- return (ENXIO);
- if (uaa->info.bIfaceIndex != CUE_IFACE_IDX)
- return (ENXIO);
-
- return (usb2_lookup_id_by_uaa(cue_devs, sizeof(cue_devs), uaa));
-}
-
-/*
- * Attach the interface. Allocate softc structures, do ifmedia
- * setup and ethernet/BPF attach.
- */
-static int
-cue_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct cue_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
- uint8_t iface_index;
- int error;
-
- device_set_usb2_desc(dev);
- mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
-
- iface_index = CUE_IFACE_IDX;
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, cue_config, CUE_N_TRANSFER, sc, &sc->sc_mtx);
- if (error) {
- device_printf(dev, "allocating USB transfers failed!\n");
- goto detach;
- }
-
- ue->ue_sc = sc;
- ue->ue_dev = dev;
- ue->ue_udev = uaa->device;
- ue->ue_mtx = &sc->sc_mtx;
- ue->ue_methods = &cue_ue_methods;
-
- error = usb2_ether_ifattach(ue);
- if (error) {
- device_printf(dev, "could not attach interface\n");
- goto detach;
- }
- return (0); /* success */
-
-detach:
- cue_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-cue_detach(device_t dev)
-{
- struct cue_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
-
- usb2_transfer_unsetup(sc->sc_xfer, CUE_N_TRANSFER);
- usb2_ether_ifdetach(ue);
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static void
-cue_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct cue_softc *sc = xfer->priv_sc;
- struct usb2_ether *ue = &sc->sc_ue;
- struct ifnet *ifp = usb2_ether_getifp(ue);
- uint8_t buf[2];
- int len;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (xfer->actlen <= (2 + sizeof(struct ether_header))) {
- ifp->if_ierrors++;
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, 0, buf, 2);
- xfer->actlen -= 2;
- len = buf[0] | (buf[1] << 8);
- len = min(xfer->actlen, len);
-
- usb2_ether_rxbuf(ue, xfer->frbuffers, 2, len);
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- usb2_ether_rxflush(ue);
- return;
-
- default: /* Error */
- DPRINTF("bulk read error, %s\n",
- usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-static void
-cue_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct cue_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
- struct mbuf *m;
- uint8_t buf[2];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(11, "transfer complete\n");
- ifp->if_opackets++;
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
-
- if (m == NULL)
- return;
- if (m->m_pkthdr.len > MCLBYTES)
- m->m_pkthdr.len = MCLBYTES;
- xfer->frlengths[0] = (m->m_pkthdr.len + 2);
-
- /* the first two bytes are the frame length */
-
- buf[0] = (uint8_t)(m->m_pkthdr.len);
- buf[1] = (uint8_t)(m->m_pkthdr.len >> 8);
-
- usb2_copy_in(xfer->frbuffers, 0, buf, 2);
-
- usb2_m_copy_in(xfer->frbuffers, 2,
- m, 0, m->m_pkthdr.len);
-
- /*
- * If there's a BPF listener, bounce a copy of this frame
- * to him.
- */
- BPF_MTAP(ifp, m);
-
- m_freem(m);
-
- usb2_start_hardware(xfer);
-
- return;
-
- default: /* Error */
- DPRINTFN(11, "transfer error, %s\n",
- usb2_errstr(xfer->error));
-
- ifp->if_oerrors++;
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-cue_tick(struct usb2_ether *ue)
-{
- struct cue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- CUE_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL);
- ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL);
- ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL);
-
- if (cue_csr_read_2(sc, CUE_RX_FRAMEERR))
- ifp->if_ierrors++;
-}
-
-static void
-cue_start(struct usb2_ether *ue)
-{
- struct cue_softc *sc = usb2_ether_getsc(ue);
-
- /*
- * start the USB transfers, if not already started:
- */
- usb2_transfer_start(sc->sc_xfer[CUE_BULK_DT_RD]);
- usb2_transfer_start(sc->sc_xfer[CUE_BULK_DT_WR]);
-}
-
-static void
-cue_init(struct usb2_ether *ue)
-{
- struct cue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
- int i;
-
- CUE_LOCK_ASSERT(sc, MA_OWNED);
-
- /*
- * Cancel pending I/O and free all RX/TX buffers.
- */
- cue_stop(ue);
-#if 0
- cue_reset(sc);
-#endif
- /* Set MAC address */
- for (i = 0; i < ETHER_ADDR_LEN; i++)
- cue_csr_write_1(sc, CUE_PAR0 - i, IF_LLADDR(ifp)[i]);
-
- /* Enable RX logic. */
- cue_csr_write_1(sc, CUE_ETHCTL, CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON);
-
- /* Load the multicast filter */
- cue_setpromisc(ue);
-
- /*
- * Set the number of RX and TX buffers that we want
- * to reserve inside the ASIC.
- */
- cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES);
- cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES);
-
- /* Set advanced operation modes. */
- cue_csr_write_1(sc, CUE_ADVANCED_OPMODES,
- CUE_AOP_EMBED_RXLEN | 0x01);/* 1 wait state */
-
- /* Program the LED operation. */
- cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK);
-
- usb2_transfer_set_stall(sc->sc_xfer[CUE_BULK_DT_WR]);
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- cue_start(ue);
-}
-
-/*
- * Stop the adapter and free any mbufs allocated to the
- * RX and TX lists.
- */
-static void
-cue_stop(struct usb2_ether *ue)
-{
- struct cue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- CUE_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-
- /*
- * stop all the transfers, if not already stopped:
- */
- usb2_transfer_stop(sc->sc_xfer[CUE_BULK_DT_WR]);
- usb2_transfer_stop(sc->sc_xfer[CUE_BULK_DT_RD]);
-
- cue_csr_write_1(sc, CUE_ETHCTL, 0);
- cue_reset(sc);
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static int
-cue_shutdown(device_t dev)
-{
- struct cue_softc *sc = device_get_softc(dev);
-
- usb2_ether_ifshutdown(&sc->sc_ue);
-
- return (0);
-}
diff --git a/sys/dev/usb2/ethernet/if_cuereg.h b/sys/dev/usb2/ethernet/if_cuereg.h
deleted file mode 100644
index ca3a816..0000000
--- a/sys/dev/usb2/ethernet/if_cuereg.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * Definitions for the CATC Netmate II USB to ethernet controller.
- */
-
-/* Vendor specific control commands. */
-#define CUE_CMD_RESET 0xF4
-#define CUE_CMD_GET_MACADDR 0xF2
-#define CUE_CMD_WRITEREG 0xFA
-#define CUE_CMD_READREG 0xFB
-#define CUE_CMD_READSRAM 0xF1
-#define CUE_CMD_WRITESRAM 0xFC
-/* Internal registers. */
-#define CUE_TX_BUFCNT 0x20
-#define CUE_RX_BUFCNT 0x21
-#define CUE_ADVANCED_OPMODES 0x22
-#define CUE_TX_BUFPKTS 0x23
-#define CUE_RX_BUFPKTS 0x24
-#define CUE_RX_MAXCHAIN 0x25
-#define CUE_ETHCTL 0x60
-#define CUE_ETHSTS 0x61
-#define CUE_PAR5 0x62
-#define CUE_PAR4 0x63
-#define CUE_PAR3 0x64
-#define CUE_PAR2 0x65
-#define CUE_PAR1 0x66
-#define CUE_PAR0 0x67
-/* Error counters, all 16 bits wide. */
-#define CUE_TX_SINGLECOLL 0x69
-#define CUE_TX_MULTICOLL 0x6B
-#define CUE_TX_EXCESSCOLL 0x6D
-#define CUE_RX_FRAMEERR 0x6F
-#define CUE_LEDCTL 0x81
-/* Advenced operating mode register. */
-#define CUE_AOP_SRAMWAITS 0x03
-#define CUE_AOP_EMBED_RXLEN 0x08
-#define CUE_AOP_RXCOMBINE 0x10
-#define CUE_AOP_TXCOMBINE 0x20
-#define CUE_AOP_EVEN_PKT_READS 0x40
-#define CUE_AOP_LOOPBK 0x80
-/* Ethernet control register. */
-#define CUE_ETHCTL_RX_ON 0x01
-#define CUE_ETHCTL_LINK_POLARITY 0x02
-#define CUE_ETHCTL_LINK_FORCE_OK 0x04
-#define CUE_ETHCTL_MCAST_ON 0x08
-#define CUE_ETHCTL_PROMISC 0x10
-/* Ethernet status register. */
-#define CUE_ETHSTS_NO_CARRIER 0x01
-#define CUE_ETHSTS_LATECOLL 0x02
-#define CUE_ETHSTS_EXCESSCOLL 0x04
-#define CUE_ETHSTS_TXBUF_AVAIL 0x08
-#define CUE_ETHSTS_BAD_POLARITY 0x10
-#define CUE_ETHSTS_LINK_OK 0x20
-/* LED control register. */
-#define CUE_LEDCTL_BLINK_1X 0x00
-#define CUE_LEDCTL_BLINK_2X 0x01
-#define CUE_LEDCTL_BLINK_QUARTER_ON 0x02
-#define CUE_LEDCTL_BLINK_QUARTER_OFF 0x03
-#define CUE_LEDCTL_OFF 0x04
-#define CUE_LEDCTL_FOLLOW_LINK 0x08
-
-/*
- * Address in ASIC's internal SRAM where the multicast hash table lives.
- * The table is 64 bytes long, giving us a 512-bit table. We have to set
- * the bit that corresponds to the broadcast address in order to enable
- * reception of broadcast frames.
- */
-#define CUE_MCAST_TABLE_ADDR 0xFA80
-
-#define CUE_TIMEOUT 1000
-#define CUE_MIN_FRAMELEN 60
-#define CUE_RX_FRAMES 1
-#define CUE_TX_FRAMES 1
-
-#define CUE_CTL_READ 0x01
-#define CUE_CTL_WRITE 0x02
-
-#define CUE_CONFIG_IDX 0 /* config number 1 */
-#define CUE_IFACE_IDX 0
-
-/* The interrupt endpoint is currently unused by the KLSI part. */
-enum {
- CUE_BULK_DT_WR,
- CUE_BULK_DT_RD,
- CUE_N_TRANSFER,
-};
-
-struct cue_softc {
- struct usb2_ether sc_ue;
- struct mtx sc_mtx;
- struct usb2_xfer *sc_xfer[CUE_N_TRANSFER];
-
- int sc_flags;
-#define CUE_FLAG_LINK 0x0001 /* got a link */
-};
-
-#define CUE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
-#define CUE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
-#define CUE_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)
diff --git a/sys/dev/usb2/ethernet/if_kue2.c b/sys/dev/usb2/ethernet/if_kue2.c
deleted file mode 100644
index b99f363..0000000
--- a/sys/dev/usb2/ethernet/if_kue2.c
+++ /dev/null
@@ -1,704 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Kawasaki LSI KL5KUSB101B USB to ethernet adapter driver.
- *
- * Written by Bill Paul <wpaul@ee.columbia.edu>
- * Electrical Engineering Department
- * Columbia University, New York City
- */
-
-/*
- * The KLSI USB to ethernet adapter chip contains an USB serial interface,
- * ethernet MAC and embedded microcontroller (called the QT Engine).
- * The chip must have firmware loaded into it before it will operate.
- * Packets are passed between the chip and host via bulk transfers.
- * There is an interrupt endpoint mentioned in the software spec, however
- * it's currently unused. This device is 10Mbps half-duplex only, hence
- * there is no media selection logic. The MAC supports a 128 entry
- * multicast filter, though the exact size of the filter can depend
- * on the firmware. Curiously, while the software spec describes various
- * ethernet statistics counters, my sample adapter and firmware combination
- * claims not to support any statistics counters at all.
- *
- * Note that once we load the firmware in the device, we have to be
- * careful not to load it again: if you restart your computer but
- * leave the adapter attached to the USB controller, it may remain
- * powered on and retain its firmware. In this case, we don't need
- * to load the firmware a second time.
- *
- * Special thanks to Rob Furr for providing an ADS Technologies
- * adapter for development and testing. No monkeys were harmed during
- * the development of this driver.
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR kue_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_kuereg.h>
-#include <dev/usb2/ethernet/if_kuefw.h>
-
-/*
- * Various supported device vendors/products.
- */
-static const struct usb2_device_id kue_devs[] = {
- {USB_VPI(USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250, 0)},
- {USB_VPI(USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460, 0)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450, 0)},
- {USB_VPI(USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT, 0)},
- {USB_VPI(USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BTX, 0)},
- {USB_VPI(USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101, 0)},
- {USB_VPI(USB_VENDOR_ASANTE, USB_PRODUCT_ASANTE_EA, 0)},
- {USB_VPI(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_DSB650C, 0)},
- {USB_VPI(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T, 0)},
- {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T, 0)},
- {USB_VPI(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C, 0)},
- {USB_VPI(USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45, 0)},
- {USB_VPI(USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX1, 0)},
- {USB_VPI(USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX2, 0)},
- {USB_VPI(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT, 0)},
- {USB_VPI(USB_VENDOR_JATON, USB_PRODUCT_JATON_EDA, 0)},
- {USB_VPI(USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_XX1, 0)},
- {USB_VPI(USB_VENDOR_KLSI, USB_PRODUCT_AOX_USB101, 0)},
- {USB_VPI(USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT, 0)},
- {USB_VPI(USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BTN, 0)},
- {USB_VPI(USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T, 0)},
- {USB_VPI(USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EA, 0)},
- {USB_VPI(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101, 0)},
- {USB_VPI(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101X, 0)},
- {USB_VPI(USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET, 0)},
- {USB_VPI(USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2, 0)},
- {USB_VPI(USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3, 0)},
- {USB_VPI(USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA8, 0)},
- {USB_VPI(USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA9, 0)},
- {USB_VPI(USB_VENDOR_PORTSMITH, USB_PRODUCT_PORTSMITH_EEA, 0)},
- {USB_VPI(USB_VENDOR_SHARK, USB_PRODUCT_SHARK_PA, 0)},
- {USB_VPI(USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_GPE, 0)},
- {USB_VPI(USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_U2E, 0)},
- {USB_VPI(USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB, 0)},
-};
-
-/* prototypes */
-
-static device_probe_t kue_probe;
-static device_attach_t kue_attach;
-static device_detach_t kue_detach;
-static device_shutdown_t kue_shutdown;
-
-static usb2_callback_t kue_bulk_read_callback;
-static usb2_callback_t kue_bulk_write_callback;
-
-static usb2_ether_fn_t kue_attach_post;
-static usb2_ether_fn_t kue_init;
-static usb2_ether_fn_t kue_stop;
-static usb2_ether_fn_t kue_start;
-static usb2_ether_fn_t kue_setmulti;
-static usb2_ether_fn_t kue_setpromisc;
-
-static int kue_do_request(struct kue_softc *,
- struct usb2_device_request *, void *);
-static int kue_setword(struct kue_softc *, uint8_t, uint16_t);
-static int kue_ctl(struct kue_softc *, uint8_t, uint8_t, uint16_t,
- void *, int);
-static int kue_load_fw(struct kue_softc *);
-static void kue_reset(struct kue_softc *);
-
-#if USB_DEBUG
-static int kue_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, kue, CTLFLAG_RW, 0, "USB kue");
-SYSCTL_INT(_hw_usb2_kue, OID_AUTO, debug, CTLFLAG_RW, &kue_debug, 0,
- "Debug level");
-#endif
-
-static const struct usb2_config kue_config[KUE_N_TRANSFER] = {
-
- [KUE_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = (MCLBYTES + 2 + 64),
- .mh.flags = {.pipe_bof = 1,},
- .mh.callback = kue_bulk_write_callback,
- .mh.timeout = 10000, /* 10 seconds */
- },
-
- [KUE_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = (MCLBYTES + 2),
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = kue_bulk_read_callback,
- .mh.timeout = 0, /* no timeout */
- },
-};
-
-static device_method_t kue_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, kue_probe),
- DEVMETHOD(device_attach, kue_attach),
- DEVMETHOD(device_detach, kue_detach),
- DEVMETHOD(device_shutdown, kue_shutdown),
-
- {0, 0}
-};
-
-static driver_t kue_driver = {
- .name = "kue",
- .methods = kue_methods,
- .size = sizeof(struct kue_softc),
-};
-
-static devclass_t kue_devclass;
-
-DRIVER_MODULE(kue, ushub, kue_driver, kue_devclass, NULL, 0);
-MODULE_DEPEND(kue, usb2_ethernet, 1, 1, 1);
-MODULE_DEPEND(kue, usb2_core, 1, 1, 1);
-MODULE_DEPEND(kue, ether, 1, 1, 1);
-
-static const struct usb2_ether_methods kue_ue_methods = {
- .ue_attach_post = kue_attach_post,
- .ue_start = kue_start,
- .ue_init = kue_init,
- .ue_stop = kue_stop,
- .ue_setmulti = kue_setmulti,
- .ue_setpromisc = kue_setpromisc,
-};
-
-/*
- * We have a custom do_request function which is almost like the
- * regular do_request function, except it has a much longer timeout.
- * Why? Because we need to make requests over the control endpoint
- * to download the firmware to the device, which can take longer
- * than the default timeout.
- */
-static int
-kue_do_request(struct kue_softc *sc, struct usb2_device_request *req,
- void *data)
-{
- usb2_error_t err;
-
- err = usb2_ether_do_request(&sc->sc_ue, req, data, 60000);
-
- return (err);
-}
-
-static int
-kue_setword(struct kue_softc *sc, uint8_t breq, uint16_t word)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = breq;
- USETW(req.wValue, word);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- return (kue_do_request(sc, &req, NULL));
-}
-
-static int
-kue_ctl(struct kue_softc *sc, uint8_t rw, uint8_t breq,
- uint16_t val, void *data, int len)
-{
- struct usb2_device_request req;
-
- if (rw == KUE_CTL_WRITE)
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- else
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
-
-
- req.bRequest = breq;
- USETW(req.wValue, val);
- USETW(req.wIndex, 0);
- USETW(req.wLength, len);
-
- return (kue_do_request(sc, &req, data));
-}
-
-static int
-kue_load_fw(struct kue_softc *sc)
-{
- struct usb2_device_descriptor *dd;
- uint16_t hwrev;
- usb2_error_t err;
-
- dd = usb2_get_device_descriptor(sc->sc_ue.ue_udev);
- hwrev = UGETW(dd->bcdDevice);
-
- /*
- * First, check if we even need to load the firmware.
- * If the device was still attached when the system was
- * rebooted, it may already have firmware loaded in it.
- * If this is the case, we don't need to do it again.
- * And in fact, if we try to load it again, we'll hang,
- * so we have to avoid this condition if we don't want
- * to look stupid.
- *
- * We can test this quickly by checking the bcdRevision
- * code. The NIC will return a different revision code if
- * it's probed while the firmware is still loaded and
- * running.
- */
- if (hwrev == 0x0202)
- return(0);
-
- /* Load code segment */
- err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
- 0, kue_code_seg, sizeof(kue_code_seg));
- if (err) {
- device_printf(sc->sc_ue.ue_dev, "failed to load code segment: %s\n",
- usb2_errstr(err));
- return(ENXIO);
- }
-
- /* Load fixup segment */
- err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
- 0, kue_fix_seg, sizeof(kue_fix_seg));
- if (err) {
- device_printf(sc->sc_ue.ue_dev, "failed to load fixup segment: %s\n",
- usb2_errstr(err));
- return(ENXIO);
- }
-
- /* Send trigger command. */
- err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
- 0, kue_trig_seg, sizeof(kue_trig_seg));
- if (err) {
- device_printf(sc->sc_ue.ue_dev, "failed to load trigger segment: %s\n",
- usb2_errstr(err));
- return(ENXIO);
- }
-
- return (0);
-}
-
-static void
-kue_setpromisc(struct usb2_ether *ue)
-{
- struct kue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- KUE_LOCK_ASSERT(sc, MA_OWNED);
-
- if (ifp->if_flags & IFF_PROMISC)
- sc->sc_rxfilt |= KUE_RXFILT_PROMISC;
- else
- sc->sc_rxfilt &= ~KUE_RXFILT_PROMISC;
-
- kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->sc_rxfilt);
-}
-
-static void
-kue_setmulti(struct usb2_ether *ue)
-{
- struct kue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
- struct ifmultiaddr *ifma;
- int i = 0;
-
- KUE_LOCK_ASSERT(sc, MA_OWNED);
-
- if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
- sc->sc_rxfilt |= KUE_RXFILT_ALLMULTI;
- sc->sc_rxfilt &= ~KUE_RXFILT_MULTICAST;
- kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->sc_rxfilt);
- return;
- }
-
- sc->sc_rxfilt &= ~KUE_RXFILT_ALLMULTI;
-
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
- {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- /*
- * If there are too many addresses for the
- * internal filter, switch over to allmulti mode.
- */
- if (i == KUE_MCFILTCNT(sc))
- break;
- bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
- KUE_MCFILT(sc, i), ETHER_ADDR_LEN);
- i++;
- }
- IF_ADDR_UNLOCK(ifp);
-
- if (i == KUE_MCFILTCNT(sc))
- sc->sc_rxfilt |= KUE_RXFILT_ALLMULTI;
- else {
- sc->sc_rxfilt |= KUE_RXFILT_MULTICAST;
- kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS,
- i, sc->sc_mcfilters, i * ETHER_ADDR_LEN);
- }
-
- kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->sc_rxfilt);
-}
-
-/*
- * Issue a SET_CONFIGURATION command to reset the MAC. This should be
- * done after the firmware is loaded into the adapter in order to
- * bring it into proper operation.
- */
-static void
-kue_reset(struct kue_softc *sc)
-{
- struct usb2_config_descriptor *cd;
- usb2_error_t err;
-
- cd = usb2_get_config_descriptor(sc->sc_ue.ue_udev);
-
- err = usb2_req_set_config(sc->sc_ue.ue_udev, &sc->sc_mtx,
- cd->bConfigurationValue);
- if (err)
- DPRINTF("reset failed (ignored)\n");
-
- /* wait a little while for the chip to get its brains in order */
- usb2_ether_pause(&sc->sc_ue, hz / 100);
-}
-
-static void
-kue_attach_post(struct usb2_ether *ue)
-{
- struct kue_softc *sc = usb2_ether_getsc(ue);
- int error;
-
- /* load the firmware into the NIC */
- error = kue_load_fw(sc);
- if (error) {
- device_printf(sc->sc_ue.ue_dev, "could not load firmware\n");
- /* ignore the error */
- }
-
- /* reset the adapter */
- kue_reset(sc);
-
- /* read ethernet descriptor */
- kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR,
- 0, &sc->sc_desc, sizeof(sc->sc_desc));
-
- /* copy in ethernet address */
- memcpy(ue->ue_eaddr, sc->sc_desc.kue_macaddr, sizeof(ue->ue_eaddr));
-}
-
-/*
- * Probe for a KLSI chip.
- */
-static int
-kue_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
- if (uaa->info.bConfigIndex != KUE_CONFIG_IDX)
- return (ENXIO);
- if (uaa->info.bIfaceIndex != KUE_IFACE_IDX)
- return (ENXIO);
-
- return (usb2_lookup_id_by_uaa(kue_devs, sizeof(kue_devs), uaa));
-}
-
-/*
- * Attach the interface. Allocate softc structures, do
- * setup and ethernet/BPF attach.
- */
-static int
-kue_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct kue_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
- uint8_t iface_index;
- int error;
-
- device_set_usb2_desc(dev);
- mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
-
- iface_index = KUE_IFACE_IDX;
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, kue_config, KUE_N_TRANSFER, sc, &sc->sc_mtx);
- if (error) {
- device_printf(dev, "allocating USB transfers failed!\n");
- goto detach;
- }
-
- sc->sc_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN,
- M_USBDEV, M_WAITOK);
- if (sc->sc_mcfilters == NULL) {
- device_printf(dev, "failed allocating USB memory!\n");
- goto detach;
- }
-
- ue->ue_sc = sc;
- ue->ue_dev = dev;
- ue->ue_udev = uaa->device;
- ue->ue_mtx = &sc->sc_mtx;
- ue->ue_methods = &kue_ue_methods;
-
- error = usb2_ether_ifattach(ue);
- if (error) {
- device_printf(dev, "could not attach interface\n");
- goto detach;
- }
- return (0); /* success */
-
-detach:
- kue_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-kue_detach(device_t dev)
-{
- struct kue_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
-
- usb2_transfer_unsetup(sc->sc_xfer, KUE_N_TRANSFER);
- usb2_ether_ifdetach(ue);
- mtx_destroy(&sc->sc_mtx);
- free(sc->sc_mcfilters, M_USBDEV);
-
- return (0);
-}
-
-/*
- * A frame has been uploaded: pass the resulting mbuf chain up to
- * the higher level protocols.
- */
-static void
-kue_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct kue_softc *sc = xfer->priv_sc;
- struct usb2_ether *ue = &sc->sc_ue;
- struct ifnet *ifp = usb2_ether_getifp(ue);
- uint8_t buf[2];
- int len;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (xfer->actlen <= (2 + sizeof(struct ether_header))) {
- ifp->if_ierrors++;
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, 0, buf, 2);
- xfer->actlen -= 2;
- len = buf[0] | (buf[1] << 8);
- len = min(xfer->actlen, len);
-
- usb2_ether_rxbuf(ue, xfer->frbuffers, 2, len);
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- usb2_ether_rxflush(ue);
- return;
-
- default: /* Error */
- DPRINTF("bulk read error, %s\n",
- usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-static void
-kue_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct kue_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
- struct mbuf *m;
- int total_len;
- int temp_len;
- uint8_t buf[2];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(11, "transfer complete\n");
- ifp->if_opackets++;
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
-
- if (m == NULL)
- return;
- if (m->m_pkthdr.len > MCLBYTES)
- m->m_pkthdr.len = MCLBYTES;
- temp_len = (m->m_pkthdr.len + 2);
- total_len = (temp_len + (64 - (temp_len % 64)));
-
- /* the first two bytes are the frame length */
-
- buf[0] = (uint8_t)(m->m_pkthdr.len);
- buf[1] = (uint8_t)(m->m_pkthdr.len >> 8);
-
- usb2_copy_in(xfer->frbuffers, 0, buf, 2);
-
- usb2_m_copy_in(xfer->frbuffers, 2,
- m, 0, m->m_pkthdr.len);
-
- usb2_bzero(xfer->frbuffers, temp_len,
- total_len - temp_len);
-
- xfer->frlengths[0] = total_len;
-
- /*
- * if there's a BPF listener, bounce a copy
- * of this frame to him:
- */
- BPF_MTAP(ifp, m);
-
- m_freem(m);
-
- usb2_start_hardware(xfer);
-
- return;
-
- default: /* Error */
- DPRINTFN(11, "transfer error, %s\n",
- usb2_errstr(xfer->error));
-
- ifp->if_oerrors++;
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-static void
-kue_start(struct usb2_ether *ue)
-{
- struct kue_softc *sc = usb2_ether_getsc(ue);
-
- /*
- * start the USB transfers, if not already started:
- */
- usb2_transfer_start(sc->sc_xfer[KUE_BULK_DT_RD]);
- usb2_transfer_start(sc->sc_xfer[KUE_BULK_DT_WR]);
-}
-
-static void
-kue_init(struct usb2_ether *ue)
-{
- struct kue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- KUE_LOCK_ASSERT(sc, MA_OWNED);
-
- /* set MAC address */
- kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MAC,
- 0, IF_LLADDR(ifp), ETHER_ADDR_LEN);
-
- /* I'm not sure how to tune these. */
-#if 0
- /*
- * Leave this one alone for now; setting it
- * wrong causes lockups on some machines/controllers.
- */
- kue_setword(sc, KUE_CMD_SET_SOFS, 1);
-#endif
- kue_setword(sc, KUE_CMD_SET_URB_SIZE, 64);
-
- /* load the multicast filter */
- kue_setpromisc(ue);
-
- usb2_transfer_set_stall(sc->sc_xfer[KUE_BULK_DT_WR]);
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- kue_start(ue);
-}
-
-static void
-kue_stop(struct usb2_ether *ue)
-{
- struct kue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- KUE_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-
- /*
- * stop all the transfers, if not already stopped:
- */
- usb2_transfer_stop(sc->sc_xfer[KUE_BULK_DT_WR]);
- usb2_transfer_stop(sc->sc_xfer[KUE_BULK_DT_RD]);
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static int
-kue_shutdown(device_t dev)
-{
- struct kue_softc *sc = device_get_softc(dev);
-
- usb2_ether_ifshutdown(&sc->sc_ue);
-
- return (0);
-}
diff --git a/sys/dev/usb2/ethernet/if_kuefw.h b/sys/dev/usb2/ethernet/if_kuefw.h
deleted file mode 100644
index 2b055a9..0000000
--- a/sys/dev/usb2/ethernet/if_kuefw.h
+++ /dev/null
@@ -1,685 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * This file contains the firmware needed to make the KLSI chip work,
- * along with a few constants related to the QT Engine microcontroller
- * embedded in the KLSI part.
- *
- * Firmware is loaded using the vendor-specific 'send scan data'
- * command (0xFF). The basic operation is that we must load the
- * firmware, then issue some trigger commands to fix it up and start
- * it running. There are three transfers: load the binary code,
- * load the 'fixup' (data segment?), then issue a command to
- * start the code firmware running. The data itself is prefixed by
- * a 16-bit signature word, a 16-bit length value, a type byte
- * and an interrupt (command) byte. The code segment is of type
- * 0x02 (replacement interrupt vector data) and the fixup segment
- * is of type 0x03 (replacement interrupt fixup data). The interrupt
- * code is 0x64 (load new code). The length word is the total length
- * of the segment minus 7. I precomputed the values and stuck them
- * into the appropriate locations within the segments to save some
- * work in the driver.
- */
-
-/* QT controller data block types. */
-/* Write data into specific memory location. */
-#define KUE_QTBTYPE_WRITE_DATA 0x00
-/* Write data into interrupt vector location */
-#define KUE_QTBTYPE_WRITE_INTVEC 0x01
-/* Replace interrupt vector with this data */
-#define KUE_QTBTYPE_REPL_INTVEC 0x02
-/* Fixup interrupt vector code with this data */
-#define KUE_QTBTYPE_FIXUP_INTVEC 0x03
-/* Force jump to location */
-#define KUE_QTBTYPE_JUMP 0x04
-/* Force call to location */
-#define KUE_QTBTYPE_CALL 0x05
-/* Force interrupt call */
-#define KUE_QTBTYPE_CALLINTR 0x06
-/*
- * Cause data to be written using the specified QT engine
- * interrupt, from starting location in memory for a specified
- * number of bytes.
- */
-#define KUE_QTBTYPE_WRITE_WITH_INTR 0x07
-/* Cause data from stream to be written using specified QT interrupt. */
-#define KUE_QTBTYPE_WRITE_STR_WITH_INTR 0x08
-/* Cause data to be written to config locations. */
-/* Addresses assume 0xc000 offset. */
-#define KUE_QTBTYPE_WRITE_CONFIG 0x09
-
-#define KUE_QTINTR_LOAD_CODE 0x64
-#define KUE_QTINTR_TRIGGER_CODE 0x3B
-#define KUE_QTINTR_LOAD_CODE_HIGH 0x9C
-
-/* Firmware code segment */
-static unsigned char kue_code_seg[] =
-{
- /******************************************/
- /* NOTE: B6/C3 is data header signature */
- /* 0xAA/0xBB is data length = total */
- /* bytes - 7, 0xCC is type, 0xDD is */
- /* interrupt to use. */
- /******************************************/
- 0xB6, 0xC3, 0xf7, 0x0e, 0x02, 0x64,
- 0x9f, 0xcf, 0xbc, 0x08, 0xe7, 0x57, 0x00, 0x00,
- 0x9a, 0x08, 0x97, 0xc1, 0xe7, 0x67, 0xff, 0x1f,
- 0x28, 0xc0, 0xe7, 0x87, 0x00, 0x04, 0x24, 0xc0,
- 0xe7, 0x67, 0xff, 0xf9, 0x22, 0xc0, 0x97, 0xcf,
- 0xe7, 0x09, 0xa2, 0xc0, 0x94, 0x08, 0xd7, 0x09,
- 0x00, 0xc0, 0xe7, 0x59, 0xba, 0x08, 0x94, 0x08,
- 0x03, 0xc1, 0xe7, 0x67, 0xff, 0xf7, 0x24, 0xc0,
- 0xe7, 0x05, 0x00, 0xc0, 0xa7, 0xcf, 0x92, 0x08,
- 0xe7, 0x57, 0x00, 0x00, 0x8e, 0x08, 0xa7, 0xa1,
- 0x8e, 0x08, 0x97, 0xcf, 0xe7, 0x57, 0x00, 0x00,
- 0xf2, 0x09, 0x0a, 0xc0, 0xe7, 0x57, 0x00, 0x00,
- 0xa4, 0xc0, 0xa7, 0xc0, 0x56, 0x08, 0x9f, 0xaf,
- 0x70, 0x09, 0xe7, 0x07, 0x00, 0x00, 0xf2, 0x09,
- 0xe7, 0x57, 0xff, 0xff, 0x90, 0x08, 0x9f, 0xa0,
- 0x40, 0x00, 0xe7, 0x59, 0x90, 0x08, 0x94, 0x08,
- 0x9f, 0xa0, 0x40, 0x00, 0xc8, 0x09, 0xa2, 0x08,
- 0x08, 0x62, 0x9f, 0xa1, 0x14, 0x0a, 0xe7, 0x57,
- 0x00, 0x00, 0x52, 0x08, 0xa7, 0xc0, 0x56, 0x08,
- 0x9f, 0xaf, 0x04, 0x00, 0xe7, 0x57, 0x00, 0x00,
- 0x8e, 0x08, 0xa7, 0xc1, 0x56, 0x08, 0xc0, 0x09,
- 0xa8, 0x08, 0x00, 0x60, 0x05, 0xc4, 0xc0, 0x59,
- 0x94, 0x08, 0x02, 0xc0, 0x9f, 0xaf, 0xee, 0x00,
- 0xe7, 0x59, 0xae, 0x08, 0x94, 0x08, 0x02, 0xc1,
- 0x9f, 0xaf, 0xf6, 0x00, 0x9f, 0xaf, 0x9e, 0x03,
- 0xef, 0x57, 0x00, 0x00, 0xf0, 0x09, 0x9f, 0xa1,
- 0xde, 0x01, 0xe7, 0x57, 0x00, 0x00, 0x78, 0x08,
- 0x9f, 0xa0, 0xe4, 0x03, 0x9f, 0xaf, 0x2c, 0x04,
- 0xa7, 0xcf, 0x56, 0x08, 0x48, 0x02, 0xe7, 0x09,
- 0x94, 0x08, 0xa8, 0x08, 0xc8, 0x37, 0x04, 0x00,
- 0x9f, 0xaf, 0x68, 0x04, 0x97, 0xcf, 0xe7, 0x57,
- 0x00, 0x00, 0xa6, 0x08, 0x97, 0xc0, 0xd7, 0x09,
- 0x00, 0xc0, 0xc1, 0xdf, 0xc8, 0x09, 0x9c, 0x08,
- 0x08, 0x62, 0x1d, 0xc0, 0x27, 0x04, 0x9c, 0x08,
- 0x10, 0x94, 0xf0, 0x07, 0xee, 0x09, 0x02, 0x00,
- 0xc1, 0x07, 0x01, 0x00, 0x70, 0x00, 0x04, 0x00,
- 0xf0, 0x07, 0x44, 0x01, 0x06, 0x00, 0x50, 0xaf,
- 0xe7, 0x09, 0x94, 0x08, 0xae, 0x08, 0xe7, 0x17,
- 0x14, 0x00, 0xae, 0x08, 0xe7, 0x67, 0xff, 0x07,
- 0xae, 0x08, 0xe7, 0x07, 0xff, 0xff, 0xa8, 0x08,
- 0xe7, 0x07, 0x00, 0x00, 0xa6, 0x08, 0xe7, 0x05,
- 0x00, 0xc0, 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0,
- 0xc1, 0xdf, 0x48, 0x02, 0xd0, 0x09, 0x9c, 0x08,
- 0x27, 0x02, 0x9c, 0x08, 0xe7, 0x09, 0x20, 0xc0,
- 0xee, 0x09, 0xe7, 0xd0, 0xee, 0x09, 0xe7, 0x05,
- 0x00, 0xc0, 0x97, 0xcf, 0x48, 0x02, 0xc8, 0x37,
- 0x04, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x60,
- 0x21, 0xc0, 0xc0, 0x37, 0x3e, 0x00, 0x23, 0xc9,
- 0xc0, 0x57, 0xb4, 0x05, 0x1b, 0xc8, 0xc0, 0x17,
- 0x3f, 0x00, 0xc0, 0x67, 0xc0, 0xff, 0x30, 0x00,
- 0x08, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x04, 0x00,
- 0x00, 0x02, 0xc0, 0x17, 0x4c, 0x00, 0x30, 0x00,
- 0x06, 0x00, 0xf0, 0x07, 0xbe, 0x01, 0x0a, 0x00,
- 0x48, 0x02, 0xc1, 0x07, 0x02, 0x00, 0xd7, 0x09,
- 0x00, 0xc0, 0xc1, 0xdf, 0x51, 0xaf, 0xe7, 0x05,
- 0x00, 0xc0, 0x97, 0xcf, 0x9f, 0xaf, 0x68, 0x04,
- 0x9f, 0xaf, 0xe4, 0x03, 0x97, 0xcf, 0x9f, 0xaf,
- 0xe4, 0x03, 0xc9, 0x37, 0x04, 0x00, 0xc1, 0xdf,
- 0xc8, 0x09, 0x70, 0x08, 0x50, 0x02, 0x67, 0x02,
- 0x70, 0x08, 0xd1, 0x07, 0x00, 0x00, 0xc0, 0xdf,
- 0x9f, 0xaf, 0xde, 0x01, 0x97, 0xcf, 0xe7, 0x57,
- 0x00, 0x00, 0xaa, 0x08, 0x97, 0xc1, 0xe7, 0x57,
- 0x01, 0x00, 0x7a, 0x08, 0x97, 0xc0, 0xc8, 0x09,
- 0x6e, 0x08, 0x08, 0x62, 0x97, 0xc0, 0x00, 0x02,
- 0xc0, 0x17, 0x0e, 0x00, 0x27, 0x00, 0x34, 0x01,
- 0x27, 0x0c, 0x0c, 0x00, 0x36, 0x01, 0xef, 0x57,
- 0x00, 0x00, 0xf0, 0x09, 0x9f, 0xc0, 0xbe, 0x02,
- 0xe7, 0x57, 0x00, 0x00, 0xb0, 0x08, 0x97, 0xc1,
- 0xe7, 0x07, 0x09, 0x00, 0x12, 0xc0, 0xe7, 0x77,
- 0x00, 0x08, 0x20, 0xc0, 0x9f, 0xc1, 0xb6, 0x02,
- 0xe7, 0x57, 0x09, 0x00, 0x12, 0xc0, 0x77, 0xc9,
- 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0xe7, 0x77,
- 0x00, 0x08, 0x20, 0xc0, 0x2f, 0xc1, 0xe7, 0x07,
- 0x00, 0x00, 0x42, 0xc0, 0xe7, 0x07, 0x05, 0x00,
- 0x90, 0xc0, 0xc8, 0x07, 0x0a, 0x00, 0xe7, 0x77,
- 0x04, 0x00, 0x20, 0xc0, 0x09, 0xc1, 0x08, 0xda,
- 0x7a, 0xc1, 0xe7, 0x07, 0x00, 0x01, 0x42, 0xc0,
- 0xe7, 0x07, 0x04, 0x00, 0x90, 0xc0, 0x1a, 0xcf,
- 0xe7, 0x07, 0x01, 0x00, 0x7a, 0x08, 0x00, 0xd8,
- 0x27, 0x50, 0x34, 0x01, 0x17, 0xc1, 0xe7, 0x77,
- 0x02, 0x00, 0x20, 0xc0, 0x79, 0xc1, 0x27, 0x50,
- 0x34, 0x01, 0x10, 0xc1, 0xe7, 0x77, 0x02, 0x00,
- 0x20, 0xc0, 0x79, 0xc0, 0x9f, 0xaf, 0xd8, 0x02,
- 0xe7, 0x05, 0x00, 0xc0, 0x00, 0x60, 0x9f, 0xc0,
- 0xde, 0x01, 0x97, 0xcf, 0xe7, 0x07, 0x01, 0x00,
- 0xb8, 0x08, 0x06, 0xcf, 0xe7, 0x07, 0x30, 0x0e,
- 0x02, 0x00, 0xe7, 0x07, 0x50, 0xc3, 0x12, 0xc0,
- 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf, 0xe7, 0x07,
- 0x01, 0x00, 0xb8, 0x08, 0x97, 0xcf, 0xe7, 0x07,
- 0x50, 0xc3, 0x12, 0xc0, 0xe7, 0x07, 0x30, 0x0e,
- 0x02, 0x00, 0xe7, 0x07, 0x01, 0x00, 0x7a, 0x08,
- 0xe7, 0x07, 0x05, 0x00, 0x90, 0xc0, 0x97, 0xcf,
- 0xe7, 0x07, 0x00, 0x01, 0x42, 0xc0, 0xe7, 0x07,
- 0x04, 0x00, 0x90, 0xc0, 0xe7, 0x07, 0x00, 0x00,
- 0x7a, 0x08, 0xe7, 0x57, 0x0f, 0x00, 0xb2, 0x08,
- 0x13, 0xc1, 0x9f, 0xaf, 0x2e, 0x08, 0xca, 0x09,
- 0xac, 0x08, 0xf2, 0x17, 0x01, 0x00, 0x5c, 0x00,
- 0xf2, 0x27, 0x00, 0x00, 0x5e, 0x00, 0xe7, 0x07,
- 0x00, 0x00, 0xb2, 0x08, 0xe7, 0x07, 0x01, 0x00,
- 0xb4, 0x08, 0xc0, 0x07, 0xff, 0xff, 0x97, 0xcf,
- 0x9f, 0xaf, 0x4c, 0x03, 0xc0, 0x69, 0xb4, 0x08,
- 0x57, 0x00, 0x9f, 0xde, 0x33, 0x00, 0xc1, 0x05,
- 0x27, 0xd8, 0xb2, 0x08, 0x27, 0xd2, 0xb4, 0x08,
- 0xe7, 0x87, 0x01, 0x00, 0xb4, 0x08, 0xe7, 0x67,
- 0xff, 0x03, 0xb4, 0x08, 0x00, 0x60, 0x97, 0xc0,
- 0xe7, 0x07, 0x01, 0x00, 0xb0, 0x08, 0x27, 0x00,
- 0x12, 0xc0, 0x97, 0xcf, 0xc0, 0x09, 0xb6, 0x08,
- 0x00, 0xd2, 0x02, 0xc3, 0xc0, 0x97, 0x05, 0x80,
- 0x27, 0x00, 0xb6, 0x08, 0xc0, 0x99, 0x82, 0x08,
- 0xc0, 0x99, 0xa2, 0xc0, 0x97, 0xcf, 0xe7, 0x07,
- 0x00, 0x00, 0xb0, 0x08, 0xc0, 0xdf, 0x97, 0xcf,
- 0xc8, 0x09, 0x72, 0x08, 0x08, 0x62, 0x02, 0xc0,
- 0x10, 0x64, 0x07, 0xc1, 0xe7, 0x07, 0x00, 0x00,
- 0x64, 0x08, 0xe7, 0x07, 0xc8, 0x05, 0x24, 0x00,
- 0x97, 0xcf, 0x27, 0x04, 0x72, 0x08, 0xc8, 0x17,
- 0x0e, 0x00, 0x27, 0x02, 0x64, 0x08, 0xe7, 0x07,
- 0xd6, 0x05, 0x24, 0x00, 0x97, 0xcf, 0xd7, 0x09,
- 0x00, 0xc0, 0xc1, 0xdf, 0xe7, 0x57, 0x00, 0x00,
- 0x62, 0x08, 0x13, 0xc1, 0x9f, 0xaf, 0x70, 0x03,
- 0xe7, 0x57, 0x00, 0x00, 0x64, 0x08, 0x13, 0xc0,
- 0xe7, 0x09, 0x64, 0x08, 0x30, 0x01, 0xe7, 0x07,
- 0xf2, 0x05, 0x32, 0x01, 0xe7, 0x07, 0x10, 0x00,
- 0x96, 0xc0, 0xe7, 0x09, 0x64, 0x08, 0x62, 0x08,
- 0x04, 0xcf, 0xe7, 0x57, 0x00, 0x00, 0x64, 0x08,
- 0x02, 0xc1, 0x9f, 0xaf, 0x70, 0x03, 0xe7, 0x05,
- 0x00, 0xc0, 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0,
- 0xc1, 0xdf, 0xc8, 0x09, 0x72, 0x08, 0x27, 0x02,
- 0x78, 0x08, 0x08, 0x62, 0x03, 0xc1, 0xe7, 0x05,
- 0x00, 0xc0, 0x97, 0xcf, 0x27, 0x04, 0x72, 0x08,
- 0xe7, 0x05, 0x00, 0xc0, 0xf0, 0x07, 0x40, 0x00,
- 0x08, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x04, 0x00,
- 0x00, 0x02, 0xc0, 0x17, 0x0c, 0x00, 0x30, 0x00,
- 0x06, 0x00, 0xf0, 0x07, 0x64, 0x01, 0x0a, 0x00,
- 0xc8, 0x17, 0x04, 0x00, 0xc1, 0x07, 0x02, 0x00,
- 0x51, 0xaf, 0x97, 0xcf, 0xe7, 0x57, 0x00, 0x00,
- 0x6a, 0x08, 0x97, 0xc0, 0xc1, 0xdf, 0xc8, 0x09,
- 0x6a, 0x08, 0x27, 0x04, 0x6a, 0x08, 0x27, 0x52,
- 0x6c, 0x08, 0x03, 0xc1, 0xe7, 0x07, 0x6a, 0x08,
- 0x6c, 0x08, 0xc0, 0xdf, 0x17, 0x02, 0xc8, 0x17,
- 0x0e, 0x00, 0x9f, 0xaf, 0x16, 0x05, 0xc8, 0x05,
- 0x00, 0x60, 0x03, 0xc0, 0x9f, 0xaf, 0x80, 0x04,
- 0x97, 0xcf, 0x9f, 0xaf, 0x68, 0x04, 0x97, 0xcf,
- 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x08, 0x62,
- 0x1c, 0xc0, 0xd0, 0x09, 0x72, 0x08, 0x27, 0x02,
- 0x72, 0x08, 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf,
- 0x97, 0x02, 0xca, 0x09, 0xac, 0x08, 0xf2, 0x17,
- 0x01, 0x00, 0x04, 0x00, 0xf2, 0x27, 0x00, 0x00,
- 0x06, 0x00, 0xca, 0x17, 0x2c, 0x00, 0xf8, 0x77,
- 0x01, 0x00, 0x0e, 0x00, 0x06, 0xc0, 0xca, 0xd9,
- 0xf8, 0x57, 0xff, 0x00, 0x0e, 0x00, 0x01, 0xc1,
- 0xca, 0xd9, 0x22, 0x1c, 0x0c, 0x00, 0xe2, 0x27,
- 0x00, 0x00, 0xe2, 0x17, 0x01, 0x00, 0xe2, 0x27,
- 0x00, 0x00, 0xca, 0x05, 0x00, 0x0c, 0x0c, 0x00,
- 0xc0, 0x17, 0x41, 0x00, 0xc0, 0x67, 0xc0, 0xff,
- 0x30, 0x00, 0x08, 0x00, 0x00, 0x02, 0xc0, 0x17,
- 0x0c, 0x00, 0x30, 0x00, 0x06, 0x00, 0xf0, 0x07,
- 0xdc, 0x00, 0x0a, 0x00, 0xf0, 0x07, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x0c, 0x08, 0x00, 0x40, 0xd1,
- 0x01, 0x00, 0xc0, 0x19, 0xa6, 0x08, 0xc0, 0x59,
- 0x98, 0x08, 0x04, 0xc9, 0x49, 0xaf, 0x9f, 0xaf,
- 0xee, 0x00, 0x4a, 0xaf, 0x67, 0x10, 0xa6, 0x08,
- 0xc8, 0x17, 0x04, 0x00, 0xc1, 0x07, 0x01, 0x00,
- 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x50, 0xaf,
- 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf, 0xc0, 0x07,
- 0x01, 0x00, 0xc1, 0x09, 0x7c, 0x08, 0xc1, 0x77,
- 0x01, 0x00, 0x97, 0xc1, 0xd8, 0x77, 0x01, 0x00,
- 0x12, 0xc0, 0xc9, 0x07, 0x4c, 0x08, 0x9f, 0xaf,
- 0x64, 0x05, 0x04, 0xc1, 0xc1, 0x77, 0x08, 0x00,
- 0x13, 0xc0, 0x97, 0xcf, 0xc1, 0x77, 0x02, 0x00,
- 0x97, 0xc1, 0xc1, 0x77, 0x10, 0x00, 0x0c, 0xc0,
- 0x9f, 0xaf, 0x86, 0x05, 0x97, 0xcf, 0xc1, 0x77,
- 0x04, 0x00, 0x06, 0xc0, 0xc9, 0x07, 0x7e, 0x08,
- 0x9f, 0xaf, 0x64, 0x05, 0x97, 0xc0, 0x00, 0xcf,
- 0x00, 0x90, 0x97, 0xcf, 0x50, 0x54, 0x97, 0xc1,
- 0x70, 0x5c, 0x02, 0x00, 0x02, 0x00, 0x97, 0xc1,
- 0x70, 0x5c, 0x04, 0x00, 0x04, 0x00, 0x97, 0xcf,
- 0xc0, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00,
- 0x0c, 0x00, 0x06, 0x00, 0x00, 0x00, 0xcb, 0x09,
- 0x88, 0x08, 0xcc, 0x09, 0x8a, 0x08, 0x0b, 0x53,
- 0x11, 0xc0, 0xc9, 0x02, 0xca, 0x07, 0x78, 0x05,
- 0x9f, 0xaf, 0x64, 0x05, 0x97, 0xc0, 0x0a, 0xc8,
- 0x82, 0x08, 0x0a, 0xcf, 0x82, 0x08, 0x9f, 0xaf,
- 0x64, 0x05, 0x97, 0xc0, 0x05, 0xc2, 0x89, 0x30,
- 0x82, 0x60, 0x78, 0xc1, 0x00, 0x90, 0x97, 0xcf,
- 0x89, 0x10, 0x09, 0x53, 0x79, 0xc2, 0x89, 0x30,
- 0x82, 0x08, 0x7a, 0xcf, 0xc0, 0xdf, 0x97, 0xcf,
- 0xe7, 0x09, 0x96, 0xc0, 0x66, 0x08, 0xe7, 0x09,
- 0x98, 0xc0, 0x68, 0x08, 0x0f, 0xcf, 0xe7, 0x09,
- 0x96, 0xc0, 0x66, 0x08, 0xe7, 0x09, 0x98, 0xc0,
- 0x68, 0x08, 0xe7, 0x09, 0x64, 0x08, 0x30, 0x01,
- 0xe7, 0x07, 0xf2, 0x05, 0x32, 0x01, 0xe7, 0x07,
- 0x10, 0x00, 0x96, 0xc0, 0xd7, 0x09, 0x00, 0xc0,
- 0x17, 0x02, 0xc8, 0x09, 0x62, 0x08, 0xc8, 0x37,
- 0x0e, 0x00, 0xe7, 0x57, 0x04, 0x00, 0x68, 0x08,
- 0x3d, 0xc0, 0xe7, 0x87, 0x00, 0x08, 0x24, 0xc0,
- 0xe7, 0x09, 0x94, 0x08, 0xba, 0x08, 0xe7, 0x17,
- 0x64, 0x00, 0xba, 0x08, 0xe7, 0x67, 0xff, 0x07,
- 0xba, 0x08, 0xe7, 0x77, 0x2a, 0x00, 0x66, 0x08,
- 0x30, 0xc0, 0x97, 0x02, 0xca, 0x09, 0xac, 0x08,
- 0xe7, 0x77, 0x20, 0x00, 0x66, 0x08, 0x0e, 0xc0,
- 0xf2, 0x17, 0x01, 0x00, 0x10, 0x00, 0xf2, 0x27,
- 0x00, 0x00, 0x12, 0x00, 0xe7, 0x77, 0x0a, 0x00,
- 0x66, 0x08, 0xca, 0x05, 0x1e, 0xc0, 0x97, 0x02,
- 0xca, 0x09, 0xac, 0x08, 0xf2, 0x17, 0x01, 0x00,
- 0x0c, 0x00, 0xf2, 0x27, 0x00, 0x00, 0x0e, 0x00,
- 0xe7, 0x77, 0x02, 0x00, 0x66, 0x08, 0x07, 0xc0,
- 0xf2, 0x17, 0x01, 0x00, 0x44, 0x00, 0xf2, 0x27,
- 0x00, 0x00, 0x46, 0x00, 0x06, 0xcf, 0xf2, 0x17,
- 0x01, 0x00, 0x60, 0x00, 0xf2, 0x27, 0x00, 0x00,
- 0x62, 0x00, 0xca, 0x05, 0x9f, 0xaf, 0x68, 0x04,
- 0x0f, 0xcf, 0x57, 0x02, 0x09, 0x02, 0xf1, 0x09,
- 0x68, 0x08, 0x0c, 0x00, 0xf1, 0xda, 0x0c, 0x00,
- 0xc8, 0x09, 0x6c, 0x08, 0x50, 0x02, 0x67, 0x02,
- 0x6c, 0x08, 0xd1, 0x07, 0x00, 0x00, 0xc9, 0x05,
- 0xe7, 0x09, 0x64, 0x08, 0x62, 0x08, 0xe7, 0x57,
- 0x00, 0x00, 0x62, 0x08, 0x02, 0xc0, 0x9f, 0xaf,
- 0x70, 0x03, 0xc8, 0x05, 0xe7, 0x05, 0x00, 0xc0,
- 0xc0, 0xdf, 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0,
- 0x17, 0x00, 0x17, 0x02, 0x97, 0x02, 0xc0, 0x09,
- 0x92, 0xc0, 0xe7, 0x87, 0x00, 0x08, 0x24, 0xc0,
- 0xe7, 0x09, 0x94, 0x08, 0xba, 0x08, 0xe7, 0x17,
- 0x64, 0x00, 0xba, 0x08, 0xe7, 0x67, 0xff, 0x07,
- 0xba, 0x08, 0xe7, 0x07, 0x04, 0x00, 0x90, 0xc0,
- 0xca, 0x09, 0xac, 0x08, 0xe7, 0x07, 0x00, 0x00,
- 0x7a, 0x08, 0xe7, 0x07, 0x66, 0x03, 0x02, 0x00,
- 0xc0, 0x77, 0x02, 0x00, 0x10, 0xc0, 0xef, 0x57,
- 0x00, 0x00, 0xf0, 0x09, 0x04, 0xc0, 0x9f, 0xaf,
- 0xd8, 0x02, 0x9f, 0xcf, 0x12, 0x08, 0xf2, 0x17,
- 0x01, 0x00, 0x50, 0x00, 0xf2, 0x27, 0x00, 0x00,
- 0x52, 0x00, 0x9f, 0xcf, 0x12, 0x08, 0xef, 0x57,
- 0x00, 0x00, 0xf0, 0x09, 0x08, 0xc0, 0xe7, 0x57,
- 0x00, 0x00, 0xb8, 0x08, 0xe7, 0x07, 0x00, 0x00,
- 0xb8, 0x08, 0x0a, 0xc0, 0x03, 0xcf, 0xc0, 0x77,
- 0x10, 0x00, 0x06, 0xc0, 0xf2, 0x17, 0x01, 0x00,
- 0x58, 0x00, 0xf2, 0x27, 0x00, 0x00, 0x5a, 0x00,
- 0xc0, 0x77, 0x80, 0x00, 0x06, 0xc0, 0xf2, 0x17,
- 0x01, 0x00, 0x70, 0x00, 0xf2, 0x27, 0x00, 0x00,
- 0x72, 0x00, 0xc0, 0x77, 0x08, 0x00, 0x1d, 0xc1,
- 0xf2, 0x17, 0x01, 0x00, 0x08, 0x00, 0xf2, 0x27,
- 0x00, 0x00, 0x0a, 0x00, 0xc0, 0x77, 0x00, 0x02,
- 0x06, 0xc0, 0xf2, 0x17, 0x01, 0x00, 0x64, 0x00,
- 0xf2, 0x27, 0x00, 0x00, 0x66, 0x00, 0xc0, 0x77,
- 0x40, 0x00, 0x06, 0xc0, 0xf2, 0x17, 0x01, 0x00,
- 0x5c, 0x00, 0xf2, 0x27, 0x00, 0x00, 0x5e, 0x00,
- 0xc0, 0x77, 0x01, 0x00, 0x01, 0xc0, 0x37, 0xcf,
- 0x36, 0xcf, 0xf2, 0x17, 0x01, 0x00, 0x00, 0x00,
- 0xf2, 0x27, 0x00, 0x00, 0x02, 0x00, 0xef, 0x57,
- 0x00, 0x00, 0xf0, 0x09, 0x18, 0xc0, 0xe7, 0x57,
- 0x01, 0x00, 0xb2, 0x08, 0x0e, 0xc2, 0x07, 0xc8,
- 0xf2, 0x17, 0x01, 0x00, 0x50, 0x00, 0xf2, 0x27,
- 0x00, 0x00, 0x52, 0x00, 0x06, 0xcf, 0xf2, 0x17,
- 0x01, 0x00, 0x54, 0x00, 0xf2, 0x27, 0x00, 0x00,
- 0x56, 0x00, 0xe7, 0x07, 0x00, 0x00, 0xb2, 0x08,
- 0xe7, 0x07, 0x01, 0x00, 0xb4, 0x08, 0xc8, 0x09,
- 0x34, 0x01, 0xca, 0x17, 0x14, 0x00, 0xd8, 0x77,
- 0x01, 0x00, 0x05, 0xc0, 0xca, 0xd9, 0xd8, 0x57,
- 0xff, 0x00, 0x01, 0xc0, 0xca, 0xd9, 0xe2, 0x19,
- 0x94, 0xc0, 0xe2, 0x27, 0x00, 0x00, 0xe2, 0x17,
- 0x01, 0x00, 0xe2, 0x27, 0x00, 0x00, 0x9f, 0xaf,
- 0x2e, 0x08, 0x9f, 0xaf, 0xde, 0x01, 0xe7, 0x57,
- 0x00, 0x00, 0xaa, 0x08, 0x9f, 0xa1, 0xf0, 0x0b,
- 0xca, 0x05, 0xc8, 0x05, 0xc0, 0x05, 0xe7, 0x05,
- 0x00, 0xc0, 0xc0, 0xdf, 0x97, 0xcf, 0xc8, 0x09,
- 0x6e, 0x08, 0x08, 0x62, 0x97, 0xc0, 0x27, 0x04,
- 0x6e, 0x08, 0x27, 0x52, 0x70, 0x08, 0x03, 0xc1,
- 0xe7, 0x07, 0x6e, 0x08, 0x70, 0x08, 0x9f, 0xaf,
- 0x68, 0x04, 0x97, 0xcf, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x33, 0xcc,
- 0x00, 0x00, 0x00, 0x00, 0xe7, 0x57, 0x00, 0x80,
- 0xb2, 0x00, 0x06, 0xc2, 0xe7, 0x07, 0x52, 0x0e,
- 0x12, 0x00, 0xe7, 0x07, 0x98, 0x0e, 0xb2, 0x00,
- 0xe7, 0x07, 0xa4, 0x09, 0xf2, 0x02, 0xc8, 0x09,
- 0xb4, 0x00, 0xf8, 0x07, 0x02, 0x00, 0x0d, 0x00,
- 0xd7, 0x09, 0x0e, 0xc0, 0xe7, 0x07, 0x00, 0x00,
- 0x0e, 0xc0, 0xc8, 0x09, 0xdc, 0x00, 0xf0, 0x07,
- 0xff, 0xff, 0x09, 0x00, 0xf0, 0x07, 0xfb, 0x13,
- 0x0b, 0x00, 0xe7, 0x09, 0xc0, 0x00, 0x58, 0x08,
- 0xe7, 0x09, 0xbe, 0x00, 0x54, 0x08, 0xe7, 0x09,
- 0x10, 0x00, 0x92, 0x08, 0xc8, 0x07, 0xb4, 0x09,
- 0x9f, 0xaf, 0x8c, 0x09, 0x9f, 0xaf, 0xe2, 0x0b,
- 0xc0, 0x07, 0x80, 0x01, 0x44, 0xaf, 0x27, 0x00,
- 0x88, 0x08, 0x27, 0x00, 0x8a, 0x08, 0x27, 0x00,
- 0x8c, 0x08, 0xc0, 0x07, 0x74, 0x00, 0x44, 0xaf,
- 0x27, 0x00, 0xac, 0x08, 0x08, 0x00, 0x00, 0x90,
- 0xc1, 0x07, 0x1d, 0x00, 0x20, 0x00, 0x20, 0x00,
- 0x01, 0xda, 0x7c, 0xc1, 0x9f, 0xaf, 0x8a, 0x0b,
- 0xc0, 0x07, 0x4c, 0x00, 0x48, 0xaf, 0x27, 0x00,
- 0x56, 0x08, 0x9f, 0xaf, 0x72, 0x0c, 0xe7, 0x07,
- 0x00, 0x80, 0x96, 0x08, 0xef, 0x57, 0x00, 0x00,
- 0xf0, 0x09, 0x03, 0xc0, 0xe7, 0x07, 0x01, 0x00,
- 0x1c, 0xc0, 0xe7, 0x05, 0x0e, 0xc0, 0x97, 0xcf,
- 0x49, 0xaf, 0xe7, 0x87, 0x43, 0x00, 0x0e, 0xc0,
- 0xe7, 0x07, 0xff, 0xff, 0x94, 0x08, 0x9f, 0xaf,
- 0x8a, 0x0c, 0xc0, 0x07, 0x01, 0x00, 0x60, 0xaf,
- 0x4a, 0xaf, 0x97, 0xcf, 0x00, 0x08, 0x09, 0x08,
- 0x11, 0x08, 0x00, 0xda, 0x7c, 0xc1, 0x97, 0xcf,
- 0x67, 0x04, 0xcc, 0x02, 0xc0, 0xdf, 0x51, 0x94,
- 0xb1, 0xaf, 0x06, 0x00, 0xc1, 0xdf, 0xc9, 0x09,
- 0xcc, 0x02, 0x49, 0x62, 0x75, 0xc1, 0xc0, 0xdf,
- 0xa7, 0xcf, 0xd6, 0x02, 0x0e, 0x00, 0x24, 0x00,
- 0xd6, 0x05, 0x22, 0x00, 0xc4, 0x06, 0xd0, 0x00,
- 0xf0, 0x0b, 0xaa, 0x00, 0x0e, 0x0a, 0xbe, 0x00,
- 0x2c, 0x0c, 0x10, 0x00, 0x20, 0x00, 0x04, 0x00,
- 0xc4, 0x05, 0x02, 0x00, 0x66, 0x03, 0x06, 0x00,
- 0x00, 0x00, 0x24, 0xc0, 0x04, 0x04, 0x28, 0xc0,
- 0xfe, 0xfb, 0x1e, 0xc0, 0x00, 0x04, 0x22, 0xc0,
- 0xff, 0xf0, 0xc0, 0x00, 0x60, 0x0b, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x34, 0x0a, 0x3e, 0x0a,
- 0x9e, 0x0a, 0xa8, 0x0a, 0xce, 0x0a, 0xd2, 0x0a,
- 0xd6, 0x0a, 0x00, 0x0b, 0x10, 0x0b, 0x1e, 0x0b,
- 0x20, 0x0b, 0x28, 0x0b, 0x28, 0x0b, 0x27, 0x02,
- 0xa2, 0x08, 0x97, 0xcf, 0xe7, 0x07, 0x00, 0x00,
- 0xa2, 0x08, 0x0a, 0x0e, 0x01, 0x00, 0xca, 0x57,
- 0x0e, 0x00, 0x9f, 0xc3, 0x2a, 0x0b, 0xca, 0x37,
- 0x00, 0x00, 0x9f, 0xc2, 0x2a, 0x0b, 0x0a, 0xd2,
- 0xb2, 0xcf, 0xf4, 0x09, 0xc8, 0x09, 0xde, 0x00,
- 0x07, 0x06, 0x9f, 0xcf, 0x3c, 0x0b, 0xf0, 0x57,
- 0x80, 0x01, 0x06, 0x00, 0x9f, 0xc8, 0x2a, 0x0b,
- 0x27, 0x0c, 0x02, 0x00, 0x86, 0x08, 0xc0, 0x09,
- 0x88, 0x08, 0x27, 0x00, 0x8a, 0x08, 0xe7, 0x07,
- 0x00, 0x00, 0x84, 0x08, 0x27, 0x00, 0x5c, 0x08,
- 0x00, 0x1c, 0x06, 0x00, 0x27, 0x00, 0x8c, 0x08,
- 0x41, 0x90, 0x67, 0x50, 0x86, 0x08, 0x0d, 0xc0,
- 0x67, 0x00, 0x5a, 0x08, 0x27, 0x0c, 0x06, 0x00,
- 0x5e, 0x08, 0xe7, 0x07, 0x8a, 0x0a, 0x60, 0x08,
- 0xc8, 0x07, 0x5a, 0x08, 0x41, 0x90, 0x51, 0xaf,
- 0x97, 0xcf, 0x9f, 0xaf, 0xac, 0x0e, 0xe7, 0x09,
- 0x8c, 0x08, 0x8a, 0x08, 0xe7, 0x09, 0x86, 0x08,
- 0x84, 0x08, 0x59, 0xaf, 0x97, 0xcf, 0x27, 0x0c,
- 0x02, 0x00, 0x7c, 0x08, 0x59, 0xaf, 0x97, 0xcf,
- 0x09, 0x0c, 0x02, 0x00, 0x09, 0xda, 0x49, 0xd2,
- 0xc9, 0x19, 0xac, 0x08, 0xc8, 0x07, 0x5a, 0x08,
- 0xe0, 0x07, 0x00, 0x00, 0x60, 0x02, 0xe0, 0x07,
- 0x04, 0x00, 0xd0, 0x07, 0x9a, 0x0a, 0x48, 0xdb,
- 0x41, 0x90, 0x50, 0xaf, 0x97, 0xcf, 0x59, 0xaf,
- 0x97, 0xcf, 0x59, 0xaf, 0x97, 0xcf, 0xf0, 0x57,
- 0x06, 0x00, 0x06, 0x00, 0x26, 0xc1, 0xe7, 0x07,
- 0x7e, 0x08, 0x5c, 0x08, 0x41, 0x90, 0x67, 0x00,
- 0x5a, 0x08, 0x27, 0x0c, 0x06, 0x00, 0x5e, 0x08,
- 0xe7, 0x07, 0x5c, 0x0b, 0x60, 0x08, 0xc8, 0x07,
- 0x5a, 0x08, 0x41, 0x90, 0x51, 0xaf, 0x97, 0xcf,
- 0x07, 0x0c, 0x06, 0x00, 0xc7, 0x57, 0x06, 0x00,
- 0x10, 0xc1, 0xc8, 0x07, 0x7e, 0x08, 0x16, 0xcf,
- 0x00, 0x0c, 0x02, 0x00, 0x00, 0xda, 0x40, 0xd1,
- 0x27, 0x00, 0x98, 0x08, 0x1f, 0xcf, 0x1e, 0xcf,
- 0x27, 0x0c, 0x02, 0x00, 0xa4, 0x08, 0x1a, 0xcf,
- 0x00, 0xcf, 0x27, 0x02, 0x20, 0x01, 0xe7, 0x07,
- 0x08, 0x00, 0x22, 0x01, 0xe7, 0x07, 0x13, 0x00,
- 0xb0, 0xc0, 0x97, 0xcf, 0x41, 0x90, 0x67, 0x00,
- 0x5a, 0x08, 0xe7, 0x01, 0x5e, 0x08, 0x27, 0x02,
- 0x5c, 0x08, 0xe7, 0x07, 0x5c, 0x0b, 0x60, 0x08,
- 0xc8, 0x07, 0x5a, 0x08, 0xc1, 0x07, 0x00, 0x80,
- 0x50, 0xaf, 0x97, 0xcf, 0x59, 0xaf, 0x97, 0xcf,
- 0x00, 0x60, 0x05, 0xc0, 0xe7, 0x07, 0x00, 0x00,
- 0x9a, 0x08, 0xa7, 0xcf, 0x58, 0x08, 0x9f, 0xaf,
- 0xe2, 0x0b, 0xe7, 0x07, 0x01, 0x00, 0x9a, 0x08,
- 0x49, 0xaf, 0xd7, 0x09, 0x00, 0xc0, 0x07, 0xaf,
- 0xe7, 0x05, 0x00, 0xc0, 0x4a, 0xaf, 0xa7, 0xcf,
- 0x58, 0x08, 0xc0, 0x07, 0x40, 0x00, 0x44, 0xaf,
- 0x27, 0x00, 0xa0, 0x08, 0x08, 0x00, 0xc0, 0x07,
- 0x20, 0x00, 0x20, 0x94, 0x00, 0xda, 0x7d, 0xc1,
- 0xc0, 0x07, 0xfe, 0x7f, 0x44, 0xaf, 0x40, 0x00,
- 0x41, 0x90, 0xc0, 0x37, 0x08, 0x00, 0xdf, 0xde,
- 0x50, 0x06, 0xc0, 0x57, 0x10, 0x00, 0x02, 0xc2,
- 0xc0, 0x07, 0x10, 0x00, 0x27, 0x00, 0x76, 0x08,
- 0x41, 0x90, 0x9f, 0xde, 0x40, 0x06, 0x44, 0xaf,
- 0x27, 0x00, 0x74, 0x08, 0xc0, 0x09, 0x76, 0x08,
- 0x41, 0x90, 0x00, 0xd2, 0x00, 0xd8, 0x9f, 0xde,
- 0x08, 0x00, 0x44, 0xaf, 0x27, 0x00, 0x9e, 0x08,
- 0x97, 0xcf, 0xe7, 0x87, 0x00, 0x84, 0x28, 0xc0,
- 0xe7, 0x67, 0xff, 0xf3, 0x24, 0xc0, 0x97, 0xcf,
- 0xe7, 0x87, 0x01, 0x00, 0xaa, 0x08, 0xe7, 0x57,
- 0x00, 0x00, 0x7a, 0x08, 0x97, 0xc1, 0x9f, 0xaf,
- 0xe2, 0x0b, 0xe7, 0x87, 0x00, 0x06, 0x22, 0xc0,
- 0xe7, 0x07, 0x00, 0x00, 0x90, 0xc0, 0xe7, 0x67,
- 0xfe, 0xff, 0x3e, 0xc0, 0xe7, 0x07, 0x2e, 0x00,
- 0x0a, 0xc0, 0xe7, 0x87, 0x01, 0x00, 0x3e, 0xc0,
- 0xe7, 0x07, 0xff, 0xff, 0x94, 0x08, 0x9f, 0xaf,
- 0xf0, 0x0c, 0x97, 0xcf, 0x17, 0x00, 0xa7, 0xaf,
- 0x54, 0x08, 0xc0, 0x05, 0x27, 0x00, 0x52, 0x08,
- 0xe7, 0x87, 0x01, 0x00, 0xaa, 0x08, 0x9f, 0xaf,
- 0xe2, 0x0b, 0xe7, 0x07, 0x0c, 0x00, 0x40, 0xc0,
- 0x9f, 0xaf, 0xf0, 0x0c, 0xe7, 0x07, 0x00, 0x00,
- 0x78, 0x08, 0x00, 0x90, 0xe7, 0x09, 0x88, 0x08,
- 0x8a, 0x08, 0x27, 0x00, 0x84, 0x08, 0x27, 0x00,
- 0x7c, 0x08, 0x9f, 0xaf, 0x8a, 0x0c, 0xe7, 0x07,
- 0x00, 0x00, 0xb2, 0x02, 0xe7, 0x07, 0x00, 0x00,
- 0xb4, 0x02, 0xc0, 0x07, 0x06, 0x00, 0xc8, 0x09,
- 0xde, 0x00, 0xc8, 0x17, 0x03, 0x00, 0xc9, 0x07,
- 0x7e, 0x08, 0x29, 0x0a, 0x00, 0xda, 0x7d, 0xc1,
- 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf,
- 0x00, 0x90, 0x27, 0x00, 0x6a, 0x08, 0xe7, 0x07,
- 0x6a, 0x08, 0x6c, 0x08, 0x27, 0x00, 0x6e, 0x08,
- 0xe7, 0x07, 0x6e, 0x08, 0x70, 0x08, 0x27, 0x00,
- 0x78, 0x08, 0x27, 0x00, 0x62, 0x08, 0x27, 0x00,
- 0x64, 0x08, 0xc8, 0x09, 0x74, 0x08, 0xc1, 0x09,
- 0x76, 0x08, 0xc9, 0x07, 0x72, 0x08, 0x11, 0x02,
- 0x09, 0x02, 0xc8, 0x17, 0x40, 0x06, 0x01, 0xda,
- 0x7a, 0xc1, 0x51, 0x94, 0xc8, 0x09, 0x9e, 0x08,
- 0xc9, 0x07, 0x9c, 0x08, 0xc1, 0x09, 0x76, 0x08,
- 0x01, 0xd2, 0x01, 0xd8, 0x11, 0x02, 0x09, 0x02,
- 0xc8, 0x17, 0x08, 0x00, 0x01, 0xda, 0x7a, 0xc1,
- 0x51, 0x94, 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf,
- 0xe7, 0x57, 0x00, 0x00, 0x52, 0x08, 0x97, 0xc0,
- 0x9f, 0xaf, 0x04, 0x00, 0xe7, 0x09, 0x94, 0x08,
- 0x90, 0x08, 0xe7, 0x57, 0xff, 0xff, 0x90, 0x08,
- 0x04, 0xc1, 0xe7, 0x07, 0xf0, 0x0c, 0x8e, 0x08,
- 0x97, 0xcf, 0xe7, 0x17, 0x32, 0x00, 0x90, 0x08,
- 0xe7, 0x67, 0xff, 0x07, 0x90, 0x08, 0xe7, 0x07,
- 0x26, 0x0d, 0x8e, 0x08, 0x97, 0xcf, 0xd7, 0x09,
- 0x00, 0xc0, 0xc1, 0xdf, 0xe7, 0x57, 0x00, 0x00,
- 0x96, 0x08, 0x23, 0xc0, 0xe7, 0x07, 0x00, 0x80,
- 0x80, 0xc0, 0xe7, 0x07, 0x04, 0x00, 0x90, 0xc0,
- 0xe7, 0x07, 0x00, 0x00, 0x80, 0xc0, 0xe7, 0x07,
- 0x00, 0x80, 0x80, 0xc0, 0xc0, 0x07, 0x00, 0x00,
- 0xc0, 0x07, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00,
- 0xe7, 0x07, 0x00, 0x00, 0x80, 0xc0, 0xe7, 0x07,
- 0x00, 0x80, 0x80, 0xc0, 0xe7, 0x07, 0x00, 0x80,
- 0x40, 0xc0, 0xc0, 0x07, 0x00, 0x00, 0xe7, 0x07,
- 0x00, 0x00, 0x40, 0xc0, 0xe7, 0x07, 0x00, 0x00,
- 0x80, 0xc0, 0xef, 0x57, 0x00, 0x00, 0xf1, 0x09,
- 0x9f, 0xa0, 0xc0, 0x0d, 0xe7, 0x07, 0x04, 0x00,
- 0x90, 0xc0, 0xe7, 0x07, 0x00, 0x02, 0x40, 0xc0,
- 0xe7, 0x07, 0x0c, 0x02, 0x40, 0xc0, 0xe7, 0x07,
- 0x00, 0x00, 0x96, 0x08, 0xe7, 0x07, 0x00, 0x00,
- 0x8e, 0x08, 0xe7, 0x07, 0x00, 0x00, 0xaa, 0x08,
- 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x9f, 0xaf,
- 0x9e, 0x03, 0xe7, 0x05, 0x00, 0xc0, 0x9f, 0xaf,
- 0xde, 0x01, 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf,
- 0x9f, 0xaf, 0xde, 0x0d, 0xef, 0x77, 0x00, 0x00,
- 0xf1, 0x09, 0x97, 0xc1, 0x9f, 0xaf, 0xde, 0x0d,
- 0xef, 0x77, 0x00, 0x00, 0xf1, 0x09, 0x97, 0xc1,
- 0xef, 0x07, 0x01, 0x00, 0xf1, 0x09, 0xe7, 0x87,
- 0x00, 0x08, 0x1e, 0xc0, 0xe7, 0x87, 0x00, 0x08,
- 0x22, 0xc0, 0xe7, 0x67, 0xff, 0xf7, 0x22, 0xc0,
- 0xe7, 0x77, 0x00, 0x08, 0x20, 0xc0, 0x11, 0xc0,
- 0xe7, 0x67, 0xff, 0xf7, 0x1e, 0xc0, 0xe7, 0x87,
- 0x00, 0x08, 0x22, 0xc0, 0xe7, 0x67, 0xff, 0xf7,
- 0x22, 0xc0, 0xe7, 0x77, 0x00, 0x08, 0x20, 0xc0,
- 0x04, 0xc1, 0xe7, 0x87, 0x00, 0x08, 0x22, 0xc0,
- 0x97, 0xcf, 0xe7, 0x07, 0x01, 0x01, 0xf0, 0x09,
- 0xef, 0x57, 0x18, 0x00, 0xfe, 0xff, 0x97, 0xc2,
- 0xef, 0x07, 0x00, 0x00, 0xf0, 0x09, 0x97, 0xcf,
- 0xd7, 0x09, 0x00, 0xc0, 0x17, 0x00, 0x17, 0x02,
- 0x97, 0x02, 0xe7, 0x57, 0x00, 0x00, 0x7a, 0x08,
- 0x06, 0xc0, 0xc0, 0x09, 0x92, 0xc0, 0xc0, 0x77,
- 0x09, 0x02, 0x9f, 0xc1, 0xea, 0x06, 0x9f, 0xcf,
- 0x20, 0x08, 0xd7, 0x09, 0x0e, 0xc0, 0xe7, 0x07,
- 0x00, 0x00, 0x0e, 0xc0, 0x9f, 0xaf, 0x66, 0x0e,
- 0xe7, 0x05, 0x0e, 0xc0, 0x97, 0xcf, 0xd7, 0x09,
- 0x00, 0xc0, 0x17, 0x02, 0xc8, 0x09, 0xb0, 0xc0,
- 0xe7, 0x67, 0xfe, 0x7f, 0xb0, 0xc0, 0xc8, 0x77,
- 0x00, 0x20, 0x9f, 0xc1, 0x64, 0xeb, 0xe7, 0x57,
- 0x00, 0x00, 0xc8, 0x02, 0x9f, 0xc1, 0x80, 0xeb,
- 0xc8, 0x99, 0xca, 0x02, 0xc8, 0x67, 0x04, 0x00,
- 0x9f, 0xc1, 0x96, 0xeb, 0x9f, 0xcf, 0x4c, 0xeb,
- 0xe7, 0x07, 0x00, 0x00, 0xa6, 0xc0, 0xe7, 0x09,
- 0xb0, 0xc0, 0xc8, 0x02, 0xe7, 0x07, 0x03, 0x00,
- 0xb0, 0xc0, 0x97, 0xcf, 0xc0, 0x09, 0x86, 0x08,
- 0xc0, 0x37, 0x01, 0x00, 0x97, 0xc9, 0xc9, 0x09,
- 0x88, 0x08, 0x02, 0x00, 0x41, 0x90, 0x48, 0x02,
- 0xc9, 0x17, 0x06, 0x00, 0x9f, 0xaf, 0x64, 0x05,
- 0x9f, 0xa2, 0xd6, 0x0e, 0x02, 0xda, 0x77, 0xc1,
- 0x41, 0x60, 0x71, 0xc1, 0x97, 0xcf, 0x17, 0x02,
- 0x57, 0x02, 0x43, 0x04, 0x21, 0x04, 0xe0, 0x00,
- 0x43, 0x04, 0x21, 0x04, 0xe0, 0x00, 0x43, 0x04,
- 0x21, 0x04, 0xe0, 0x00, 0xc1, 0x07, 0x01, 0x00,
- 0xc9, 0x05, 0xc8, 0x05, 0x97, 0xcf,
- 0, 0
-};
-
-/* Firmware fixup (data?) segment */
-static unsigned char kue_fix_seg[] =
-{
- /******************************************/
- /* NOTE: B6/C3 is data header signature */
- /* 0xAA/0xBB is data length = total */
- /* bytes - 7, 0xCC is type, 0xDD is */
- /* interrupt to use. */
- /******************************************/
- 0xB6, 0xC3, 0xc9, 0x02, 0x03, 0x64,
- 0x02, 0x00, 0x08, 0x00, 0x24, 0x00, 0x2e, 0x00,
- 0x2c, 0x00, 0x3e, 0x00, 0x44, 0x00, 0x48, 0x00,
- 0x50, 0x00, 0x5c, 0x00, 0x60, 0x00, 0x66, 0x00,
- 0x6c, 0x00, 0x70, 0x00, 0x76, 0x00, 0x74, 0x00,
- 0x7a, 0x00, 0x7e, 0x00, 0x84, 0x00, 0x8a, 0x00,
- 0x8e, 0x00, 0x92, 0x00, 0x98, 0x00, 0x9c, 0x00,
- 0xa0, 0x00, 0xa8, 0x00, 0xae, 0x00, 0xb4, 0x00,
- 0xb2, 0x00, 0xba, 0x00, 0xbe, 0x00, 0xc4, 0x00,
- 0xc8, 0x00, 0xce, 0x00, 0xd2, 0x00, 0xd6, 0x00,
- 0xda, 0x00, 0xe2, 0x00, 0xe0, 0x00, 0xea, 0x00,
- 0xf2, 0x00, 0xfe, 0x00, 0x06, 0x01, 0x0c, 0x01,
- 0x1a, 0x01, 0x24, 0x01, 0x22, 0x01, 0x2a, 0x01,
- 0x30, 0x01, 0x36, 0x01, 0x3c, 0x01, 0x4e, 0x01,
- 0x52, 0x01, 0x58, 0x01, 0x5c, 0x01, 0x9c, 0x01,
- 0xb6, 0x01, 0xba, 0x01, 0xc0, 0x01, 0xca, 0x01,
- 0xd0, 0x01, 0xda, 0x01, 0xe2, 0x01, 0xea, 0x01,
- 0xf0, 0x01, 0x0a, 0x02, 0x0e, 0x02, 0x14, 0x02,
- 0x26, 0x02, 0x6c, 0x02, 0x8e, 0x02, 0x98, 0x02,
- 0xa0, 0x02, 0xa6, 0x02, 0xba, 0x02, 0xc6, 0x02,
- 0xce, 0x02, 0xe8, 0x02, 0xee, 0x02, 0xf4, 0x02,
- 0xf8, 0x02, 0x0a, 0x03, 0x10, 0x03, 0x1a, 0x03,
- 0x1e, 0x03, 0x2a, 0x03, 0x2e, 0x03, 0x34, 0x03,
- 0x3a, 0x03, 0x44, 0x03, 0x4e, 0x03, 0x5a, 0x03,
- 0x5e, 0x03, 0x6a, 0x03, 0x72, 0x03, 0x80, 0x03,
- 0x84, 0x03, 0x8c, 0x03, 0x94, 0x03, 0x98, 0x03,
- 0xa8, 0x03, 0xae, 0x03, 0xb4, 0x03, 0xba, 0x03,
- 0xce, 0x03, 0xcc, 0x03, 0xd6, 0x03, 0xdc, 0x03,
- 0xec, 0x03, 0xf0, 0x03, 0xfe, 0x03, 0x1c, 0x04,
- 0x30, 0x04, 0x38, 0x04, 0x3c, 0x04, 0x40, 0x04,
- 0x48, 0x04, 0x46, 0x04, 0x54, 0x04, 0x5e, 0x04,
- 0x64, 0x04, 0x74, 0x04, 0x78, 0x04, 0x84, 0x04,
- 0xd8, 0x04, 0xec, 0x04, 0xf0, 0x04, 0xf8, 0x04,
- 0xfe, 0x04, 0x1c, 0x05, 0x2c, 0x05, 0x30, 0x05,
- 0x4a, 0x05, 0x56, 0x05, 0x5a, 0x05, 0x88, 0x05,
- 0x8c, 0x05, 0x96, 0x05, 0x9a, 0x05, 0xa8, 0x05,
- 0xcc, 0x05, 0xd2, 0x05, 0xda, 0x05, 0xe0, 0x05,
- 0xe4, 0x05, 0xfc, 0x05, 0x06, 0x06, 0x14, 0x06,
- 0x12, 0x06, 0x1a, 0x06, 0x20, 0x06, 0x26, 0x06,
- 0x2e, 0x06, 0x34, 0x06, 0x48, 0x06, 0x52, 0x06,
- 0x64, 0x06, 0x86, 0x06, 0x90, 0x06, 0x9a, 0x06,
- 0xa0, 0x06, 0xac, 0x06, 0xaa, 0x06, 0xb2, 0x06,
- 0xb8, 0x06, 0xdc, 0x06, 0xda, 0x06, 0xe2, 0x06,
- 0xe8, 0x06, 0xf2, 0x06, 0xf8, 0x06, 0xfc, 0x06,
- 0x0a, 0x07, 0x10, 0x07, 0x14, 0x07, 0x24, 0x07,
- 0x2a, 0x07, 0x32, 0x07, 0x38, 0x07, 0xb2, 0x07,
- 0xba, 0x07, 0xde, 0x07, 0xe4, 0x07, 0x10, 0x08,
- 0x14, 0x08, 0x1a, 0x08, 0x1e, 0x08, 0x30, 0x08,
- 0x38, 0x08, 0x3c, 0x08, 0x44, 0x08, 0x42, 0x08,
- 0x48, 0x08, 0xc6, 0x08, 0xcc, 0x08, 0xd2, 0x08,
- 0xfe, 0x08, 0x04, 0x09, 0x0a, 0x09, 0x0e, 0x09,
- 0x12, 0x09, 0x16, 0x09, 0x20, 0x09, 0x24, 0x09,
- 0x28, 0x09, 0x32, 0x09, 0x46, 0x09, 0x4a, 0x09,
- 0x50, 0x09, 0x54, 0x09, 0x5a, 0x09, 0x60, 0x09,
- 0x7c, 0x09, 0x80, 0x09, 0xb8, 0x09, 0xbc, 0x09,
- 0xc0, 0x09, 0xc4, 0x09, 0xc8, 0x09, 0xcc, 0x09,
- 0xd0, 0x09, 0xd4, 0x09, 0xec, 0x09, 0xf4, 0x09,
- 0xf6, 0x09, 0xf8, 0x09, 0xfa, 0x09, 0xfc, 0x09,
- 0xfe, 0x09, 0x00, 0x0a, 0x02, 0x0a, 0x04, 0x0a,
- 0x06, 0x0a, 0x08, 0x0a, 0x0a, 0x0a, 0x0c, 0x0a,
- 0x10, 0x0a, 0x18, 0x0a, 0x24, 0x0a, 0x2c, 0x0a,
- 0x32, 0x0a, 0x3c, 0x0a, 0x46, 0x0a, 0x4c, 0x0a,
- 0x50, 0x0a, 0x54, 0x0a, 0x5a, 0x0a, 0x5e, 0x0a,
- 0x66, 0x0a, 0x6c, 0x0a, 0x72, 0x0a, 0x78, 0x0a,
- 0x7e, 0x0a, 0x7c, 0x0a, 0x82, 0x0a, 0x8c, 0x0a,
- 0x92, 0x0a, 0x90, 0x0a, 0x98, 0x0a, 0x96, 0x0a,
- 0xa2, 0x0a, 0xb2, 0x0a, 0xb6, 0x0a, 0xc4, 0x0a,
- 0xe2, 0x0a, 0xe0, 0x0a, 0xe8, 0x0a, 0xee, 0x0a,
- 0xf4, 0x0a, 0xf2, 0x0a, 0xf8, 0x0a, 0x0c, 0x0b,
- 0x1a, 0x0b, 0x24, 0x0b, 0x40, 0x0b, 0x44, 0x0b,
- 0x48, 0x0b, 0x4e, 0x0b, 0x4c, 0x0b, 0x52, 0x0b,
- 0x68, 0x0b, 0x6c, 0x0b, 0x70, 0x0b, 0x76, 0x0b,
- 0x88, 0x0b, 0x92, 0x0b, 0xbe, 0x0b, 0xca, 0x0b,
- 0xce, 0x0b, 0xde, 0x0b, 0xf4, 0x0b, 0xfa, 0x0b,
- 0x00, 0x0c, 0x24, 0x0c, 0x28, 0x0c, 0x30, 0x0c,
- 0x36, 0x0c, 0x3c, 0x0c, 0x40, 0x0c, 0x4a, 0x0c,
- 0x50, 0x0c, 0x58, 0x0c, 0x56, 0x0c, 0x5c, 0x0c,
- 0x60, 0x0c, 0x64, 0x0c, 0x80, 0x0c, 0x94, 0x0c,
- 0x9a, 0x0c, 0x98, 0x0c, 0x9e, 0x0c, 0xa4, 0x0c,
- 0xa2, 0x0c, 0xa8, 0x0c, 0xac, 0x0c, 0xb0, 0x0c,
- 0xb4, 0x0c, 0xb8, 0x0c, 0xbc, 0x0c, 0xce, 0x0c,
- 0xd2, 0x0c, 0xd6, 0x0c, 0xf4, 0x0c, 0xfa, 0x0c,
- 0x00, 0x0d, 0xfe, 0x0c, 0x06, 0x0d, 0x0e, 0x0d,
- 0x0c, 0x0d, 0x16, 0x0d, 0x1c, 0x0d, 0x22, 0x0d,
- 0x20, 0x0d, 0x30, 0x0d, 0x7e, 0x0d, 0x82, 0x0d,
- 0x9a, 0x0d, 0xa0, 0x0d, 0xa6, 0x0d, 0xb0, 0x0d,
- 0xb8, 0x0d, 0xc2, 0x0d, 0xc8, 0x0d, 0xce, 0x0d,
- 0xd4, 0x0d, 0xdc, 0x0d, 0x1e, 0x0e, 0x2c, 0x0e,
- 0x3e, 0x0e, 0x4c, 0x0e, 0x50, 0x0e, 0x5e, 0x0e,
- 0xae, 0x0e, 0xb8, 0x0e, 0xc6, 0x0e, 0xca, 0x0e,
- 0, 0
-};
-
-/* Fixup command. */
-#define KUE_TRIGCMD_OFFSET 5
-static unsigned char kue_trig_seg[] = {
- 0xb6, 0xc3, 0x01, 0x00, 0x06, 0x64, 0x00, 0x00
-};
diff --git a/sys/dev/usb2/ethernet/if_kuereg.h b/sys/dev/usb2/ethernet/if_kuereg.h
deleted file mode 100644
index 8650687..0000000
--- a/sys/dev/usb2/ethernet/if_kuereg.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * Definitions for the KLSI KL5KUSB101B USB to ethernet controller.
- * The KLSI part is controlled via vendor control requests, the structure
- * of which depend a bit on the firmware running on the internal
- * microcontroller. The one exception is the 'send scan data' command,
- * which is used to load the firmware.
- */
-
-#define KUE_CMD_GET_ETHER_DESCRIPTOR 0x00
-#define KUE_CMD_SET_MCAST_FILTERS 0x01
-#define KUE_CMD_SET_PKT_FILTER 0x02
-#define KUE_CMD_GET_ETHERSTATS 0x03
-#define KUE_CMD_GET_GPIO 0x04
-#define KUE_CMD_SET_GPIO 0x05
-#define KUE_CMD_SET_MAC 0x06
-#define KUE_CMD_GET_MAC 0x07
-#define KUE_CMD_SET_URB_SIZE 0x08
-#define KUE_CMD_SET_SOFS 0x09
-#define KUE_CMD_SET_EVEN_PKTS 0x0A
-#define KUE_CMD_SEND_SCAN 0xFF
-
-struct kue_ether_desc {
- uint8_t kue_len;
- uint8_t kue_rsvd0;
- uint8_t kue_rsvd1;
- uint8_t kue_macaddr[ETHER_ADDR_LEN];
- uint8_t kue_etherstats[4];
- uint8_t kue_maxseg[2];
- uint8_t kue_mcastfilt[2];
- uint8_t kue_rsvd2;
-} __packed;
-
-#define KUE_ETHERSTATS(x) UGETDW((x)->sc_desc.kue_etherstats)
-#define KUE_MAXSEG(x) UGETW((x)->sc_desc.kue_maxseg)
-#define KUE_MCFILTCNT(x) (UGETW((x)->sc_desc.kue_mcastfilt) & 0x7FFF)
-#define KUE_MCFILT(x, y) \
- (char *)&(sc->sc_mcfilters[y * ETHER_ADDR_LEN])
-
-#define KUE_STAT_TX_OK 0x00000001
-#define KUE_STAT_RX_OK 0x00000002
-#define KUE_STAT_TX_ERR 0x00000004
-#define KUE_STAT_RX_ERR 0x00000008
-#define KUE_STAT_RX_NOBUF 0x00000010
-#define KUE_STAT_TX_UCAST_BYTES 0x00000020
-#define KUE_STAT_TX_UCAST_FRAMES 0x00000040
-#define KUE_STAT_TX_MCAST_BYTES 0x00000080
-#define KUE_STAT_TX_MCAST_FRAMES 0x00000100
-#define KUE_STAT_TX_BCAST_BYTES 0x00000200
-#define KUE_STAT_TX_BCAST_FRAMES 0x00000400
-#define KUE_STAT_RX_UCAST_BYTES 0x00000800
-#define KUE_STAT_RX_UCAST_FRAMES 0x00001000
-#define KUE_STAT_RX_MCAST_BYTES 0x00002000
-#define KUE_STAT_RX_MCAST_FRAMES 0x00004000
-#define KUE_STAT_RX_BCAST_BYTES 0x00008000
-#define KUE_STAT_RX_BCAST_FRAMES 0x00010000
-#define KUE_STAT_RX_CRCERR 0x00020000
-#define KUE_STAT_TX_QUEUE_LENGTH 0x00040000
-#define KUE_STAT_RX_ALIGNERR 0x00080000
-#define KUE_STAT_TX_SINGLECOLL 0x00100000
-#define KUE_STAT_TX_MULTICOLL 0x00200000
-#define KUE_STAT_TX_DEFERRED 0x00400000
-#define KUE_STAT_TX_MAXCOLLS 0x00800000
-#define KUE_STAT_RX_OVERRUN 0x01000000
-#define KUE_STAT_TX_UNDERRUN 0x02000000
-#define KUE_STAT_TX_SQE_ERR 0x04000000
-#define KUE_STAT_TX_CARRLOSS 0x08000000
-#define KUE_STAT_RX_LATECOLL 0x10000000
-
-#define KUE_RXFILT_PROMISC 0x0001
-#define KUE_RXFILT_ALLMULTI 0x0002
-#define KUE_RXFILT_UNICAST 0x0004
-#define KUE_RXFILT_BROADCAST 0x0008
-#define KUE_RXFILT_MULTICAST 0x0010
-
-#define KUE_TIMEOUT 1000
-#define KUE_MIN_FRAMELEN 60
-
-#define KUE_CTL_READ 0x01
-#define KUE_CTL_WRITE 0x02
-
-#define KUE_CONFIG_IDX 0 /* config number 1 */
-#define KUE_IFACE_IDX 0
-
-/* The interrupt endpoint is currently unused by the KLSI part. */
-#define KUE_ENDPT_MAX 4
-enum {
- KUE_BULK_DT_WR,
- KUE_BULK_DT_RD,
- KUE_N_TRANSFER,
-};
-
-struct kue_softc {
- struct usb2_ether sc_ue;
- struct mtx sc_mtx;
- struct kue_ether_desc sc_desc;
- struct usb2_xfer *sc_xfer[KUE_N_TRANSFER];
- uint8_t *sc_mcfilters;
-
- int sc_flags;
-#define KUE_FLAG_LINK 0x0001
-
- uint16_t sc_rxfilt;
-};
-
-#define KUE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
-#define KUE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
-#define KUE_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)
diff --git a/sys/dev/usb2/ethernet/if_rue2.c b/sys/dev/usb2/ethernet/if_rue2.c
deleted file mode 100644
index 690092f..0000000
--- a/sys/dev/usb2/ethernet/if_rue2.c
+++ /dev/null
@@ -1,913 +0,0 @@
-/*-
- * Copyright (c) 2001-2003, Shunsuke Akiyama <akiyama@FreeBSD.org>.
- * Copyright (c) 1997, 1998, 1999, 2000 Bill Paul <wpaul@ee.columbia.edu>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * RealTek RTL8150 USB to fast ethernet controller driver.
- * Datasheet is available from
- * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/.
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR rue_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_ruereg.h>
-
-#if USB_DEBUG
-static int rue_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, rue, CTLFLAG_RW, 0, "USB rue");
-SYSCTL_INT(_hw_usb2_rue, OID_AUTO, debug, CTLFLAG_RW,
- &rue_debug, 0, "Debug level");
-#endif
-
-/*
- * Various supported device vendors/products.
- */
-
-static const struct usb2_device_id rue_devs[] = {
- {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX, 0)},
- {USB_VPI(USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_USBKR100, 0)},
-};
-
-/* prototypes */
-
-static device_probe_t rue_probe;
-static device_attach_t rue_attach;
-static device_detach_t rue_detach;
-static device_shutdown_t rue_shutdown;
-
-static miibus_readreg_t rue_miibus_readreg;
-static miibus_writereg_t rue_miibus_writereg;
-static miibus_statchg_t rue_miibus_statchg;
-
-static usb2_callback_t rue_intr_callback;
-static usb2_callback_t rue_bulk_read_callback;
-static usb2_callback_t rue_bulk_write_callback;
-
-static usb2_ether_fn_t rue_attach_post;
-static usb2_ether_fn_t rue_init;
-static usb2_ether_fn_t rue_stop;
-static usb2_ether_fn_t rue_start;
-static usb2_ether_fn_t rue_tick;
-static usb2_ether_fn_t rue_setmulti;
-static usb2_ether_fn_t rue_setpromisc;
-
-static int rue_read_mem(struct rue_softc *, uint16_t, void *, int);
-static int rue_write_mem(struct rue_softc *, uint16_t, void *, int);
-static uint8_t rue_csr_read_1(struct rue_softc *, uint16_t);
-static uint16_t rue_csr_read_2(struct rue_softc *, uint16_t);
-static int rue_csr_write_1(struct rue_softc *, uint16_t, uint8_t);
-static int rue_csr_write_2(struct rue_softc *, uint16_t, uint16_t);
-static int rue_csr_write_4(struct rue_softc *, int, uint32_t);
-
-static void rue_reset(struct rue_softc *);
-static int rue_ifmedia_upd(struct ifnet *);
-static void rue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-
-static const struct usb2_config rue_config[RUE_N_TRANSFER] = {
-
- [RUE_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = MCLBYTES,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = rue_bulk_write_callback,
- .mh.timeout = 10000, /* 10 seconds */
- },
-
- [RUE_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = (MCLBYTES + 4),
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = rue_bulk_read_callback,
- .mh.timeout = 0, /* no timeout */
- },
-
- [RUE_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = rue_intr_callback,
- },
-};
-
-static device_method_t rue_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, rue_probe),
- DEVMETHOD(device_attach, rue_attach),
- DEVMETHOD(device_detach, rue_detach),
- DEVMETHOD(device_shutdown, rue_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
-
- /* MII interface */
- DEVMETHOD(miibus_readreg, rue_miibus_readreg),
- DEVMETHOD(miibus_writereg, rue_miibus_writereg),
- DEVMETHOD(miibus_statchg, rue_miibus_statchg),
-
- {0, 0}
-};
-
-static driver_t rue_driver = {
- .name = "rue",
- .methods = rue_methods,
- .size = sizeof(struct rue_softc),
-};
-
-static devclass_t rue_devclass;
-
-DRIVER_MODULE(rue, ushub, rue_driver, rue_devclass, NULL, 0);
-DRIVER_MODULE(miibus, rue, miibus_driver, miibus_devclass, 0, 0);
-MODULE_DEPEND(rue, usb2_ethernet, 1, 1, 1);
-MODULE_DEPEND(rue, usb2_core, 1, 1, 1);
-MODULE_DEPEND(rue, ether, 1, 1, 1);
-MODULE_DEPEND(rue, miibus, 1, 1, 1);
-
-static const struct usb2_ether_methods rue_ue_methods = {
- .ue_attach_post = rue_attach_post,
- .ue_start = rue_start,
- .ue_init = rue_init,
- .ue_stop = rue_stop,
- .ue_tick = rue_tick,
- .ue_setmulti = rue_setmulti,
- .ue_setpromisc = rue_setpromisc,
- .ue_mii_upd = rue_ifmedia_upd,
- .ue_mii_sts = rue_ifmedia_sts,
-};
-
-#define RUE_SETBIT(sc, reg, x) \
- rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) | (x))
-
-#define RUE_CLRBIT(sc, reg, x) \
- rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) & ~(x))
-
-static int
-rue_read_mem(struct rue_softc *sc, uint16_t addr, void *buf, int len)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = UR_SET_ADDRESS;
- USETW(req.wValue, addr);
- USETW(req.wIndex, 0);
- USETW(req.wLength, len);
-
- return (usb2_ether_do_request(&sc->sc_ue, &req, buf, 1000));
-}
-
-static int
-rue_write_mem(struct rue_softc *sc, uint16_t addr, void *buf, int len)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UR_SET_ADDRESS;
- USETW(req.wValue, addr);
- USETW(req.wIndex, 0);
- USETW(req.wLength, len);
-
- return (usb2_ether_do_request(&sc->sc_ue, &req, buf, 1000));
-}
-
-static uint8_t
-rue_csr_read_1(struct rue_softc *sc, uint16_t reg)
-{
- uint8_t val;
-
- rue_read_mem(sc, reg, &val, 1);
- return (val);
-}
-
-static uint16_t
-rue_csr_read_2(struct rue_softc *sc, uint16_t reg)
-{
- uint8_t val[2];
-
- rue_read_mem(sc, reg, &val, 2);
- return (UGETW(val));
-}
-
-static int
-rue_csr_write_1(struct rue_softc *sc, uint16_t reg, uint8_t val)
-{
- return (rue_write_mem(sc, reg, &val, 1));
-}
-
-static int
-rue_csr_write_2(struct rue_softc *sc, uint16_t reg, uint16_t val)
-{
- uint8_t temp[2];
-
- USETW(temp, val);
- return (rue_write_mem(sc, reg, &temp, 2));
-}
-
-static int
-rue_csr_write_4(struct rue_softc *sc, int reg, uint32_t val)
-{
- uint8_t temp[4];
-
- USETDW(temp, val);
- return (rue_write_mem(sc, reg, &temp, 4));
-}
-
-static int
-rue_miibus_readreg(device_t dev, int phy, int reg)
-{
- struct rue_softc *sc = device_get_softc(dev);
- uint16_t rval;
- uint16_t ruereg;
- int locked;
-
- if (phy != 0) /* RTL8150 supports PHY == 0, only */
- return (0);
-
- locked = mtx_owned(&sc->sc_mtx);
- if (!locked)
- RUE_LOCK(sc);
-
- switch (reg) {
- case MII_BMCR:
- ruereg = RUE_BMCR;
- break;
- case MII_BMSR:
- ruereg = RUE_BMSR;
- break;
- case MII_ANAR:
- ruereg = RUE_ANAR;
- break;
- case MII_ANER:
- ruereg = RUE_AER;
- break;
- case MII_ANLPAR:
- ruereg = RUE_ANLP;
- break;
- case MII_PHYIDR1:
- case MII_PHYIDR2:
- rval = 0;
- goto done;
- default:
- if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) {
- rval = rue_csr_read_1(sc, reg);
- goto done;
- }
- device_printf(sc->sc_ue.ue_dev, "bad phy register\n");
- rval = 0;
- goto done;
- }
-
- rval = rue_csr_read_2(sc, ruereg);
-done:
- if (!locked)
- RUE_UNLOCK(sc);
- return (rval);
-}
-
-static int
-rue_miibus_writereg(device_t dev, int phy, int reg, int data)
-{
- struct rue_softc *sc = device_get_softc(dev);
- uint16_t ruereg;
- int locked;
-
- if (phy != 0) /* RTL8150 supports PHY == 0, only */
- return (0);
-
- locked = mtx_owned(&sc->sc_mtx);
- if (!locked)
- RUE_LOCK(sc);
-
- switch (reg) {
- case MII_BMCR:
- ruereg = RUE_BMCR;
- break;
- case MII_BMSR:
- ruereg = RUE_BMSR;
- break;
- case MII_ANAR:
- ruereg = RUE_ANAR;
- break;
- case MII_ANER:
- ruereg = RUE_AER;
- break;
- case MII_ANLPAR:
- ruereg = RUE_ANLP;
- break;
- case MII_PHYIDR1:
- case MII_PHYIDR2:
- goto done;
- default:
- if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) {
- rue_csr_write_1(sc, reg, data);
- goto done;
- }
- device_printf(sc->sc_ue.ue_dev, " bad phy register\n");
- goto done;
- }
- rue_csr_write_2(sc, ruereg, data);
-done:
- if (!locked)
- RUE_UNLOCK(sc);
- return (0);
-}
-
-static void
-rue_miibus_statchg(device_t dev)
-{
- /*
- * When the code below is enabled the card starts doing weird
- * things after link going from UP to DOWN and back UP.
- *
- * Looks like some of register writes below messes up PHY
- * interface.
- *
- * No visible regressions were found after commenting this code
- * out, so that disable it for good.
- */
-#if 0
- struct rue_softc *sc = device_get_softc(dev);
- struct mii_data *mii = GET_MII(sc);
- uint16_t bmcr;
- int locked;
-
- locked = mtx_owned(&sc->sc_mtx);
- if (!locked)
- RUE_LOCK(sc);
-
- RUE_CLRBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
-
- bmcr = rue_csr_read_2(sc, RUE_BMCR);
-
- if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
- bmcr |= RUE_BMCR_SPD_SET;
- else
- bmcr &= ~RUE_BMCR_SPD_SET;
-
- if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
- bmcr |= RUE_BMCR_DUPLEX;
- else
- bmcr &= ~RUE_BMCR_DUPLEX;
-
- rue_csr_write_2(sc, RUE_BMCR, bmcr);
-
- RUE_SETBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
-
- if (!locked)
- RUE_UNLOCK(sc);
-#endif
-}
-
-static void
-rue_setpromisc(struct usb2_ether *ue)
-{
- struct rue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- RUE_LOCK_ASSERT(sc, MA_OWNED);
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- RUE_SETBIT(sc, RUE_RCR, RUE_RCR_AAP);
- else
- RUE_CLRBIT(sc, RUE_RCR, RUE_RCR_AAP);
-}
-
-/*
- * Program the 64-bit multicast hash filter.
- */
-static void
-rue_setmulti(struct usb2_ether *ue)
-{
- struct rue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
- uint16_t rxcfg;
- int h = 0;
- uint32_t hashes[2] = { 0, 0 };
- struct ifmultiaddr *ifma;
- int mcnt = 0;
-
- RUE_LOCK_ASSERT(sc, MA_OWNED);
-
- rxcfg = rue_csr_read_2(sc, RUE_RCR);
-
- if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
- rxcfg |= (RUE_RCR_AAM | RUE_RCR_AAP);
- rxcfg &= ~RUE_RCR_AM;
- rue_csr_write_2(sc, RUE_RCR, rxcfg);
- rue_csr_write_4(sc, RUE_MAR0, 0xFFFFFFFF);
- rue_csr_write_4(sc, RUE_MAR4, 0xFFFFFFFF);
- return;
- }
-
- /* first, zot all the existing hash bits */
- rue_csr_write_4(sc, RUE_MAR0, 0);
- rue_csr_write_4(sc, RUE_MAR4, 0);
-
- /* now program new ones */
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link)
- {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
- if (h < 32)
- hashes[0] |= (1 << h);
- else
- hashes[1] |= (1 << (h - 32));
- mcnt++;
- }
- IF_ADDR_UNLOCK(ifp);
-
- if (mcnt)
- rxcfg |= RUE_RCR_AM;
- else
- rxcfg &= ~RUE_RCR_AM;
-
- rxcfg &= ~(RUE_RCR_AAM | RUE_RCR_AAP);
-
- rue_csr_write_2(sc, RUE_RCR, rxcfg);
- rue_csr_write_4(sc, RUE_MAR0, hashes[0]);
- rue_csr_write_4(sc, RUE_MAR4, hashes[1]);
-}
-
-static void
-rue_reset(struct rue_softc *sc)
-{
- int i;
-
- rue_csr_write_1(sc, RUE_CR, RUE_CR_SOFT_RST);
-
- for (i = 0; i != RUE_TIMEOUT; i++) {
- if (usb2_ether_pause(&sc->sc_ue, hz / 1000))
- break;
- if (!(rue_csr_read_1(sc, RUE_CR) & RUE_CR_SOFT_RST))
- break;
- }
- if (i == RUE_TIMEOUT)
- device_printf(sc->sc_ue.ue_dev, "reset never completed!\n");
-
- usb2_ether_pause(&sc->sc_ue, hz / 100);
-}
-
-static void
-rue_attach_post(struct usb2_ether *ue)
-{
- struct rue_softc *sc = usb2_ether_getsc(ue);
-
- /* reset the adapter */
- rue_reset(sc);
-
- /* get station address from the EEPROM */
- rue_read_mem(sc, RUE_EEPROM_IDR0, ue->ue_eaddr, ETHER_ADDR_LEN);
-}
-
-/*
- * Probe for a RTL8150 chip.
- */
-static int
-rue_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
- if (uaa->info.bConfigIndex != RUE_CONFIG_IDX)
- return (ENXIO);
- if (uaa->info.bIfaceIndex != RUE_IFACE_IDX)
- return (ENXIO);
-
- return (usb2_lookup_id_by_uaa(rue_devs, sizeof(rue_devs), uaa));
-}
-
-/*
- * Attach the interface. Allocate softc structures, do ifmedia
- * setup and ethernet/BPF attach.
- */
-static int
-rue_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct rue_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
- uint8_t iface_index;
- int error;
-
- device_set_usb2_desc(dev);
- mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
-
- iface_index = RUE_IFACE_IDX;
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, rue_config, RUE_N_TRANSFER,
- sc, &sc->sc_mtx);
- if (error) {
- device_printf(dev, "allocating USB transfers failed!\n");
- goto detach;
- }
-
- ue->ue_sc = sc;
- ue->ue_dev = dev;
- ue->ue_udev = uaa->device;
- ue->ue_mtx = &sc->sc_mtx;
- ue->ue_methods = &rue_ue_methods;
-
- error = usb2_ether_ifattach(ue);
- if (error) {
- device_printf(dev, "could not attach interface\n");
- goto detach;
- }
- return (0); /* success */
-
-detach:
- rue_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-rue_detach(device_t dev)
-{
- struct rue_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
-
- usb2_transfer_unsetup(sc->sc_xfer, RUE_N_TRANSFER);
- usb2_ether_ifdetach(ue);
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static void
-rue_intr_callback(struct usb2_xfer *xfer)
-{
- struct rue_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
- struct rue_intrpkt pkt;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (ifp && (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
- (xfer->actlen >= sizeof(pkt))) {
-
- usb2_copy_out(xfer->frbuffers, 0, &pkt, sizeof(pkt));
-
- ifp->if_ierrors += pkt.rue_rxlost_cnt;
- ifp->if_ierrors += pkt.rue_crcerr_cnt;
- ifp->if_collisions += pkt.rue_col_cnt;
- }
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-rue_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct rue_softc *sc = xfer->priv_sc;
- struct usb2_ether *ue = &sc->sc_ue;
- struct ifnet *ifp = usb2_ether_getifp(ue);
- uint16_t status;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (xfer->actlen < 4) {
- ifp->if_ierrors++;
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, xfer->actlen - 4,
- &status, sizeof(status));
- xfer->actlen -= 4;
-
- /* check recieve packet was valid or not */
- status = le16toh(status);
- if ((status & RUE_RXSTAT_VALID) == 0) {
- ifp->if_ierrors++;
- goto tr_setup;
- }
- usb2_ether_rxbuf(ue, xfer->frbuffers, 0, xfer->actlen);
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- usb2_ether_rxflush(ue);
- return;
-
- default: /* Error */
- DPRINTF("bulk read error, %s\n",
- usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-rue_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct rue_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
- struct mbuf *m;
- int temp_len;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(11, "transfer complete\n");
- ifp->if_opackets++;
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- if ((sc->sc_flags & RUE_FLAG_LINK) == 0) {
- /*
- * don't send anything if there is no link !
- */
- return;
- }
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
-
- if (m == NULL)
- return;
- if (m->m_pkthdr.len > MCLBYTES)
- m->m_pkthdr.len = MCLBYTES;
- temp_len = m->m_pkthdr.len;
-
- usb2_m_copy_in(xfer->frbuffers, 0,
- m, 0, m->m_pkthdr.len);
-
- /*
- * This is an undocumented behavior.
- * RTL8150 chip doesn't send frame length smaller than
- * RUE_MIN_FRAMELEN (60) byte packet.
- */
- if (temp_len < RUE_MIN_FRAMELEN) {
- usb2_bzero(xfer->frbuffers, temp_len,
- RUE_MIN_FRAMELEN - temp_len);
- temp_len = RUE_MIN_FRAMELEN;
- }
- xfer->frlengths[0] = temp_len;
-
- /*
- * if there's a BPF listener, bounce a copy
- * of this frame to him:
- */
- BPF_MTAP(ifp, m);
-
- m_freem(m);
-
- usb2_start_hardware(xfer);
-
- return;
-
- default: /* Error */
- DPRINTFN(11, "transfer error, %s\n",
- usb2_errstr(xfer->error));
-
- ifp->if_oerrors++;
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-rue_tick(struct usb2_ether *ue)
-{
- struct rue_softc *sc = usb2_ether_getsc(ue);
- struct mii_data *mii = GET_MII(sc);
-
- RUE_LOCK_ASSERT(sc, MA_OWNED);
-
- mii_tick(mii);
- if ((sc->sc_flags & RUE_FLAG_LINK) == 0
- && mii->mii_media_status & IFM_ACTIVE &&
- IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
- sc->sc_flags |= RUE_FLAG_LINK;
- rue_start(ue);
- }
-}
-
-static void
-rue_start(struct usb2_ether *ue)
-{
- struct rue_softc *sc = usb2_ether_getsc(ue);
-
- /*
- * start the USB transfers, if not already started:
- */
- usb2_transfer_start(sc->sc_xfer[RUE_INTR_DT_RD]);
- usb2_transfer_start(sc->sc_xfer[RUE_BULK_DT_RD]);
- usb2_transfer_start(sc->sc_xfer[RUE_BULK_DT_WR]);
-}
-
-static void
-rue_init(struct usb2_ether *ue)
-{
- struct rue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- RUE_LOCK_ASSERT(sc, MA_OWNED);
-
- /*
- * Cancel pending I/O
- */
- rue_reset(sc);
-
- /* Set MAC address */
- rue_write_mem(sc, RUE_IDR0, IF_LLADDR(ifp), ETHER_ADDR_LEN);
-
- rue_stop(ue);
-
- /*
- * Set the initial TX and RX configuration.
- */
- rue_csr_write_1(sc, RUE_TCR, RUE_TCR_CONFIG);
- rue_csr_write_2(sc, RUE_RCR, RUE_RCR_CONFIG|RUE_RCR_AB);
-
- /* Load the multicast filter */
- rue_setpromisc(ue);
- /* Load the multicast filter. */
- rue_setmulti(ue);
-
- /* Enable RX and TX */
- rue_csr_write_1(sc, RUE_CR, (RUE_CR_TE | RUE_CR_RE | RUE_CR_EP3CLREN));
-
- usb2_transfer_set_stall(sc->sc_xfer[RUE_BULK_DT_WR]);
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- rue_start(ue);
-}
-
-/*
- * Set media options.
- */
-static int
-rue_ifmedia_upd(struct ifnet *ifp)
-{
- struct rue_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- RUE_LOCK_ASSERT(sc, MA_OWNED);
-
- sc->sc_flags &= ~RUE_FLAG_LINK;
- if (mii->mii_instance) {
- struct mii_softc *miisc;
-
- LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
- mii_phy_reset(miisc);
- }
- mii_mediachg(mii);
- return (0);
-}
-
-/*
- * Report current media status.
- */
-static void
-rue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct rue_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- RUE_LOCK(sc);
- mii_pollstat(mii);
- RUE_UNLOCK(sc);
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
-}
-
-static void
-rue_stop(struct usb2_ether *ue)
-{
- struct rue_softc *sc = usb2_ether_getsc(ue);
- struct ifnet *ifp = usb2_ether_getifp(ue);
-
- RUE_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- sc->sc_flags &= ~RUE_FLAG_LINK;
-
- /*
- * stop all the transfers, if not already stopped:
- */
- usb2_transfer_stop(sc->sc_xfer[RUE_BULK_DT_WR]);
- usb2_transfer_stop(sc->sc_xfer[RUE_BULK_DT_RD]);
- usb2_transfer_stop(sc->sc_xfer[RUE_INTR_DT_RD]);
-
- rue_csr_write_1(sc, RUE_CR, 0x00);
-
- rue_reset(sc);
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static int
-rue_shutdown(device_t dev)
-{
- struct rue_softc *sc = device_get_softc(dev);
-
- usb2_ether_ifshutdown(&sc->sc_ue);
-
- return (0);
-}
diff --git a/sys/dev/usb2/ethernet/if_ruereg.h b/sys/dev/usb2/ethernet/if_ruereg.h
deleted file mode 100644
index a94d45a..0000000
--- a/sys/dev/usb2/ethernet/if_ruereg.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*-
- * Copyright (c) 2001-2003, Shunsuke Akiyama <akiyama@FreeBSD.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#define RUE_CONFIG_IDX 0 /* config number 1 */
-#define RUE_IFACE_IDX 0
-
-#define RUE_INTR_PKTLEN 0x8
-
-#define RUE_TIMEOUT 50
-#define RUE_MIN_FRAMELEN 60
-
-/* Registers. */
-#define RUE_IDR0 0x0120
-#define RUE_IDR1 0x0121
-#define RUE_IDR2 0x0122
-#define RUE_IDR3 0x0123
-#define RUE_IDR4 0x0124
-#define RUE_IDR5 0x0125
-
-#define RUE_MAR0 0x0126
-#define RUE_MAR1 0x0127
-#define RUE_MAR2 0x0128
-#define RUE_MAR3 0x0129
-#define RUE_MAR4 0x012A
-#define RUE_MAR5 0x012B
-#define RUE_MAR6 0x012C
-#define RUE_MAR7 0x012D
-
-#define RUE_CR 0x012E /* B, R/W */
-#define RUE_CR_SOFT_RST 0x10
-#define RUE_CR_RE 0x08
-#define RUE_CR_TE 0x04
-#define RUE_CR_EP3CLREN 0x02
-
-#define RUE_TCR 0x012F /* B, R/W */
-#define RUE_TCR_TXRR1 0x80
-#define RUE_TCR_TXRR0 0x40
-#define RUE_TCR_IFG1 0x10
-#define RUE_TCR_IFG0 0x08
-#define RUE_TCR_NOCRC 0x01
-#define RUE_TCR_CONFIG (RUE_TCR_TXRR1 | RUE_TCR_TXRR0 | \
- RUE_TCR_IFG1 | RUE_TCR_IFG0)
-
-#define RUE_RCR 0x0130 /* W, R/W */
-#define RUE_RCR_TAIL 0x80
-#define RUE_RCR_AER 0x40
-#define RUE_RCR_AR 0x20
-#define RUE_RCR_AM 0x10
-#define RUE_RCR_AB 0x08
-#define RUE_RCR_AD 0x04
-#define RUE_RCR_AAM 0x02
-#define RUE_RCR_AAP 0x01
-#define RUE_RCR_CONFIG (RUE_RCR_TAIL | RUE_RCR_AD)
-
-#define RUE_TSR 0x0132
-#define RUE_RSR 0x0133
-#define RUE_CON0 0x0135
-#define RUE_CON1 0x0136
-#define RUE_MSR 0x0137
-#define RUE_PHYADD 0x0138
-#define RUE_PHYDAT 0x0139
-
-#define RUE_PHYCNT 0x013B /* B, R/W */
-#define RUE_PHYCNT_PHYOWN 0x40
-#define RUE_PHYCNT_RWCR 0x20
-
-#define RUE_GPPC 0x013D
-#define RUE_WAKECNT 0x013E
-
-#define RUE_BMCR 0x0140
-#define RUE_BMCR_SPD_SET 0x2000
-#define RUE_BMCR_DUPLEX 0x0100
-
-#define RUE_BMSR 0x0142
-
-#define RUE_ANAR 0x0144 /* W, R/W */
-#define RUE_ANAR_PAUSE 0x0400
-
-#define RUE_ANLP 0x0146 /* W, R/O */
-#define RUE_ANLP_PAUSE 0x0400
-
-#define RUE_AER 0x0148
-
-#define RUE_NWAYT 0x014A
-#define RUE_CSCR 0x014C
-
-#define RUE_CRC0 0x014E
-#define RUE_CRC1 0x0150
-#define RUE_CRC2 0x0152
-#define RUE_CRC3 0x0154
-#define RUE_CRC4 0x0156
-
-#define RUE_BYTEMASK0 0x0158
-#define RUE_BYTEMASK1 0x0160
-#define RUE_BYTEMASK2 0x0168
-#define RUE_BYTEMASK3 0x0170
-#define RUE_BYTEMASK4 0x0178
-
-#define RUE_PHY1 0x0180
-#define RUE_PHY2 0x0184
-
-#define RUE_TW1 0x0186
-
-#define RUE_REG_MIN 0x0120
-#define RUE_REG_MAX 0x0189
-
-/* EEPROM address declarations. */
-#define RUE_EEPROM_BASE 0x1200
-#define RUE_EEPROM_IDR0 (RUE_EEPROM_BASE + 0x02)
-#define RUE_EEPROM_IDR1 (RUE_EEPROM_BASE + 0x03)
-#define RUE_EEPROM_IDR2 (RUE_EEPROM_BASE + 0x03)
-#define RUE_EEPROM_IDR3 (RUE_EEPROM_BASE + 0x03)
-#define RUE_EEPROM_IDR4 (RUE_EEPROM_BASE + 0x03)
-#define RUE_EEPROM_IDR5 (RUE_EEPROM_BASE + 0x03)
-#define RUE_EEPROM_INTERVAL (RUE_EEPROM_BASE + 0x17)
-
-#define RUE_RXSTAT_VALID (0x01 << 12)
-#define RUE_RXSTAT_RUNT (0x02 << 12)
-#define RUE_RXSTAT_PMATCH (0x04 << 12)
-#define RUE_RXSTAT_MCAST (0x08 << 12)
-
-#define GET_MII(sc) usb2_ether_getmii(&(sc)->sc_ue)
-
-struct rue_intrpkt {
- uint8_t rue_tsr;
- uint8_t rue_rsr;
- uint8_t rue_gep_msr;
- uint8_t rue_waksr;
- uint8_t rue_txok_cnt;
- uint8_t rue_rxlost_cnt;
- uint8_t rue_crcerr_cnt;
- uint8_t rue_col_cnt;
-} __packed;
-
-struct rue_type {
- uint16_t rue_vid;
- uint16_t rue_did;
-};
-
-enum {
- RUE_BULK_DT_WR,
- RUE_BULK_DT_RD,
- RUE_INTR_DT_RD,
- RUE_N_TRANSFER,
-};
-
-struct rue_softc {
- struct usb2_ether sc_ue;
- struct mtx sc_mtx;
- struct usb2_xfer *sc_xfer[RUE_N_TRANSFER];
-
- int sc_flags;
-#define RUE_FLAG_LINK 0x0001
-};
-
-#define RUE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
-#define RUE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
-#define RUE_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)
diff --git a/sys/dev/usb2/ethernet/if_udav2.c b/sys/dev/usb2/ethernet/if_udav2.c
deleted file mode 100644
index 3bec08a..0000000
--- a/sys/dev/usb2/ethernet/if_udav2.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/* $NetBSD: if_udav.c,v 1.2 2003/09/04 15:17:38 tsutsui Exp $ */
-/* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2003
- * Shingo WATANABE <nabe@nabechan.org>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-/*
- * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY)
- * The spec can be found at the following url.
- * http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf
- */
-
-/*
- * TODO:
- * Interrupt Endpoint support
- * External PHYs
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR udav_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/ethernet/usb2_ethernet.h>
-#include <dev/usb2/ethernet/if_udavreg.h>
-
-/* prototypes */
-
-static device_probe_t udav_probe;
-static device_attach_t udav_attach;
-static device_detach_t udav_detach;
-static device_shutdown_t udav_shutdown;
-
-static usb2_callback_t udav_bulk_write_callback;
-static usb2_callback_t udav_bulk_read_callback;
-static usb2_callback_t udav_intr_callback;
-
-static usb2_ether_fn_t udav_attach_post;
-static usb2_ether_fn_t udav_init;
-static usb2_ether_fn_t udav_stop;
-static usb2_ether_fn_t udav_start;
-static usb2_ether_fn_t udav_tick;
-static usb2_ether_fn_t udav_setmulti;
-static usb2_ether_fn_t udav_setpromisc;
-
-static int udav_csr_read(struct udav_softc *, uint16_t, void *, int);
-static int udav_csr_write(struct udav_softc *, uint16_t, void *, int);
-static uint8_t udav_csr_read1(struct udav_softc *, uint16_t);
-static int udav_csr_write1(struct udav_softc *, uint16_t, uint8_t);
-static void udav_reset(struct udav_softc *);
-static int udav_ifmedia_upd(struct ifnet *);
-static void udav_ifmedia_status(struct ifnet *, struct ifmediareq *);
-
-static miibus_readreg_t udav_miibus_readreg;
-static miibus_writereg_t udav_miibus_writereg;
-static miibus_statchg_t udav_miibus_statchg;
-
-static const struct usb2_config udav_config[UDAV_N_TRANSFER] = {
-
- [UDAV_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = (MCLBYTES + 2),
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = udav_bulk_write_callback,
- .mh.timeout = 10000, /* 10 seconds */
- },
-
- [UDAV_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = (MCLBYTES + 3),
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = udav_bulk_read_callback,
- .mh.timeout = 0, /* no timeout */
- },
-
- [UDAV_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = udav_intr_callback,
- },
-};
-
-static device_method_t udav_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, udav_probe),
- DEVMETHOD(device_attach, udav_attach),
- DEVMETHOD(device_detach, udav_detach),
- DEVMETHOD(device_shutdown, udav_shutdown),
-
- /* bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
-
- /* MII interface */
- DEVMETHOD(miibus_readreg, udav_miibus_readreg),
- DEVMETHOD(miibus_writereg, udav_miibus_writereg),
- DEVMETHOD(miibus_statchg, udav_miibus_statchg),
-
- {0, 0}
-};
-
-static driver_t udav_driver = {
- .name = "udav",
- .methods = udav_methods,
- .size = sizeof(struct udav_softc),
-};
-
-static devclass_t udav_devclass;
-
-DRIVER_MODULE(udav, ushub, udav_driver, udav_devclass, NULL, 0);
-DRIVER_MODULE(miibus, udav, miibus_driver, miibus_devclass, 0, 0);
-MODULE_DEPEND(udav, usb2_ethernet, 1, 1, 1);
-MODULE_DEPEND(udav, usb2_core, 1, 1, 1);
-MODULE_DEPEND(udav, ether, 1, 1, 1);
-MODULE_DEPEND(udav, miibus, 1, 1, 1);
-
-static const struct usb2_ether_methods udav_ue_methods = {
- .ue_attach_post = udav_attach_post,
- .ue_start = udav_start,
- .ue_init = udav_init,
- .ue_stop = udav_stop,
- .ue_tick = udav_tick,
- .ue_setmulti = udav_setmulti,
- .ue_setpromisc = udav_setpromisc,
- .ue_mii_upd = udav_ifmedia_upd,
- .ue_mii_sts = udav_ifmedia_status,
-};
-
-#if USB_DEBUG
-static int udav_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, udav, CTLFLAG_RW, 0, "USB udav");
-SYSCTL_INT(_hw_usb2_udav, OID_AUTO, debug, CTLFLAG_RW, &udav_debug, 0,
- "Debug level");
-#endif
-
-#define UDAV_SETBIT(sc, reg, x) \
- udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
-
-#define UDAV_CLRBIT(sc, reg, x) \
- udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
-
-static const struct usb2_device_id udav_devs[] = {
- /* ShanTou DM9601 USB NIC */
- {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601, 0)},
- /* ShanTou ST268 USB NIC */
- {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268, 0)},
- /* Corega USB-TXC */
- {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC, 0)},
-};
-
-static void
-udav_attach_post(struct usb2_ether *ue)
-{
- struct udav_softc *sc = usb2_ether_getsc(ue);
-
- /* reset the adapter */
- udav_reset(sc);
-
- /* Get Ethernet Address */
- udav_csr_read(sc, UDAV_PAR, ue->ue_eaddr, ETHER_ADDR_LEN);
-}
-
-static int
-udav_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
- if (uaa->info.bConfigIndex != UDAV_CONFIG_INDEX)
- return (ENXIO);
- if (uaa->info.bIfaceIndex != UDAV_IFACE_INDEX)
- return (ENXIO);
-
- return (usb2_lookup_id_by_uaa(udav_devs, sizeof(udav_devs), uaa));
-}
-
-static int
-udav_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct udav_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
- uint8_t iface_index;
- int error;
-
- sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
-
- device_set_usb2_desc(dev);
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
-
- iface_index = UDAV_IFACE_INDEX;
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, udav_config, UDAV_N_TRANSFER, sc, &sc->sc_mtx);
- if (error) {
- device_printf(dev, "allocating USB transfers failed!\n");
- goto detach;
- }
-
- ue->ue_sc = sc;
- ue->ue_dev = dev;
- ue->ue_udev = uaa->device;
- ue->ue_mtx = &sc->sc_mtx;
- ue->ue_methods = &udav_ue_methods;
-
- error = usb2_ether_ifattach(ue);
- if (error) {
- device_printf(dev, "could not attach interface\n");
- goto detach;
- }
-
- return (0); /* success */
-
-detach:
- udav_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-udav_detach(device_t dev)
-{
- struct udav_softc *sc = device_get_softc(dev);
- struct usb2_ether *ue = &sc->sc_ue;
-
- usb2_transfer_unsetup(sc->sc_xfer, UDAV_N_TRANSFER);
- usb2_ether_ifdetach(ue);
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-#if 0
-static int
-udav_mem_read(struct udav_softc *sc, uint16_t offset, void *buf,
- int len)
-{
- struct usb2_device_request req;
-
- len &= 0xff;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_MEM_READ;
- USETW(req.wValue, 0x0000);
- USETW(req.wIndex, offset);
- USETW(req.wLength, len);
-
- return (usb2_ether_do_request(&sc->sc_ue, &req, buf, 1000));
-}
-
-static int
-udav_mem_write(struct udav_softc *sc, uint16_t offset, void *buf,
- int len)
-{
- struct usb2_device_request req;
-
- len &= 0xff;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_MEM_WRITE;
- USETW(req.wValue, 0x0000);
- USETW(req.wIndex, offset);
- USETW(req.wLength, len);
-
- return (usb2_ether_do_request(&sc->sc_ue, &req, buf, 1000));
-}
-
-static int
-udav_mem_write1(struct udav_softc *sc, uint16_t offset,
- uint8_t ch)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_MEM_WRITE1;
- USETW(req.wValue, ch);
- USETW(req.wIndex, offset);
- USETW(req.wLength, 0x0000);
-
- return (usb2_ether_do_request(&sc->sc_ue, &req, NULL, 1000));
-}
-#endif
-
-static int
-udav_csr_read(struct udav_softc *sc, uint16_t offset, void *buf, int len)
-{
- struct usb2_device_request req;
-
- len &= 0xff;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_REG_READ;
- USETW(req.wValue, 0x0000);
- USETW(req.wIndex, offset);
- USETW(req.wLength, len);
-
- return (usb2_ether_do_request(&sc->sc_ue, &req, buf, 1000));
-}
-
-static int
-udav_csr_write(struct udav_softc *sc, uint16_t offset, void *buf, int len)
-{
- struct usb2_device_request req;
-
- offset &= 0xff;
- len &= 0xff;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_REG_WRITE;
- USETW(req.wValue, 0x0000);
- USETW(req.wIndex, offset);
- USETW(req.wLength, len);
-
- return (usb2_ether_do_request(&sc->sc_ue, &req, buf, 1000));
-}
-
-static uint8_t
-udav_csr_read1(struct udav_softc *sc, uint16_t offset)
-{
- uint8_t val;
-
- udav_csr_read(sc, offset, &val, 1);
- return (val);
-}
-
-static int
-udav_csr_write1(struct udav_softc *sc, uint16_t offset,
- uint8_t ch)
-{
- struct usb2_device_request req;
-
- offset &= 0xff;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_REG_WRITE1;
- USETW(req.wValue, ch);
- USETW(req.wIndex, offset);
- USETW(req.wLength, 0x0000);
-
- return (usb2_ether_do_request(&sc->sc_ue, &req, NULL, 1000));
-}
-
-static void
-udav_init(struct usb2_ether *ue)
-{
- struct udav_softc *sc = ue->ue_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
-
- UDAV_LOCK_ASSERT(sc, MA_OWNED);
-
- /*
- * Cancel pending I/O
- */
- udav_stop(ue);
-
- /* set MAC address */
- udav_csr_write(sc, UDAV_PAR, IF_LLADDR(ifp), ETHER_ADDR_LEN);
-
- /* initialize network control register */
-
- /* disable loopback */
- UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1);
-
- /* Initialize RX control register */
- UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
-
- /* load multicast filter and update promiscious mode bit */
- udav_setpromisc(ue);
-
- /* enable RX */
- UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN);
-
- /* clear POWER_DOWN state of internal PHY */
- UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
- UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0);
-
- usb2_transfer_set_stall(sc->sc_xfer[UDAV_BULK_DT_WR]);
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- udav_start(ue);
-}
-
-static void
-udav_reset(struct udav_softc *sc)
-{
- int i;
-
- /* Select PHY */
-#if 1
- /*
- * XXX: force select internal phy.
- * external phy routines are not tested.
- */
- UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
-#else
- if (sc->sc_flags & UDAV_EXT_PHY)
- UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
- else
- UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
-#endif
-
- UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_RST);
-
- for (i = 0; i < UDAV_TX_TIMEOUT; i++) {
- if (!(udav_csr_read1(sc, UDAV_NCR) & UDAV_NCR_RST))
- break;
- if (usb2_ether_pause(&sc->sc_ue, hz / 100))
- break;
- }
-
- usb2_ether_pause(&sc->sc_ue, hz / 100);
-}
-
-#define UDAV_BITS 6
-static void
-udav_setmulti(struct usb2_ether *ue)
-{
- struct udav_softc *sc = ue->ue_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
- struct ifmultiaddr *ifma;
- uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- int h = 0;
-
- UDAV_LOCK_ASSERT(sc, MA_OWNED);
-
- if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
- UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
- return;
- }
-
- /* first, zot all the existing hash bits */
- memset(hashtbl, 0x00, sizeof(hashtbl));
- hashtbl[7] |= 0x80; /* broadcast address */
- udav_csr_write(sc, UDAV_MAR, hashtbl, sizeof(hashtbl));
-
- /* now program new ones */
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
- {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
- hashtbl[h / 8] |= 1 << (h % 8);
- }
- IF_ADDR_UNLOCK(ifp);
-
- /* disable all multicast */
- UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
-
- /* write hash value to the register */
- udav_csr_write(sc, UDAV_MAR, hashtbl, sizeof(hashtbl));
-}
-
-static void
-udav_setpromisc(struct usb2_ether *ue)
-{
- struct udav_softc *sc = ue->ue_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
- uint8_t rxmode;
-
- rxmode = udav_csr_read1(sc, UDAV_RCR);
- rxmode &= ~(UDAV_RCR_ALL | UDAV_RCR_PRMSC);
-
- if (ifp->if_flags & IFF_PROMISC)
- rxmode |= UDAV_RCR_ALL | UDAV_RCR_PRMSC;
- else if (ifp->if_flags & IFF_ALLMULTI)
- rxmode |= UDAV_RCR_ALL;
-
- /* write new mode bits */
- udav_csr_write1(sc, UDAV_RCR, rxmode);
-}
-
-static void
-udav_start(struct usb2_ether *ue)
-{
- struct udav_softc *sc = ue->ue_sc;
-
- /*
- * start the USB transfers, if not already started:
- */
- usb2_transfer_start(sc->sc_xfer[UDAV_INTR_DT_RD]);
- usb2_transfer_start(sc->sc_xfer[UDAV_BULK_DT_RD]);
- usb2_transfer_start(sc->sc_xfer[UDAV_BULK_DT_WR]);
-}
-
-static void
-udav_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct udav_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
- struct mbuf *m;
- int extra_len;
- int temp_len;
- uint8_t buf[2];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(11, "transfer complete\n");
- ifp->if_opackets++;
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- if ((sc->sc_flags & UDAV_FLAG_LINK) == 0) {
- /*
- * don't send anything if there is no link !
- */
- return;
- }
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
-
- if (m == NULL)
- return;
- if (m->m_pkthdr.len > MCLBYTES)
- m->m_pkthdr.len = MCLBYTES;
- if (m->m_pkthdr.len < UDAV_MIN_FRAME_LEN) {
- extra_len = UDAV_MIN_FRAME_LEN - m->m_pkthdr.len;
- } else {
- extra_len = 0;
- }
-
- temp_len = (m->m_pkthdr.len + extra_len);
-
- /*
- * the frame length is specified in the first 2 bytes of the
- * buffer
- */
- buf[0] = (uint8_t)(temp_len);
- buf[1] = (uint8_t)(temp_len >> 8);
-
- temp_len += 2;
-
- usb2_copy_in(xfer->frbuffers, 0, buf, 2);
-
- usb2_m_copy_in(xfer->frbuffers, 2,
- m, 0, m->m_pkthdr.len);
-
- if (extra_len) {
- usb2_bzero(xfer->frbuffers, temp_len - extra_len,
- extra_len);
- }
- /*
- * if there's a BPF listener, bounce a copy
- * of this frame to him:
- */
- BPF_MTAP(ifp, m);
-
- m_freem(m);
-
- xfer->frlengths[0] = temp_len;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- DPRINTFN(11, "transfer error, %s\n",
- usb2_errstr(xfer->error));
-
- ifp->if_oerrors++;
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-udav_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct udav_softc *sc = xfer->priv_sc;
- struct usb2_ether *ue = &sc->sc_ue;
- struct ifnet *ifp = usb2_ether_getifp(ue);
- struct udav_rxpkt stat;
- int len;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (xfer->actlen < sizeof(stat) + ETHER_CRC_LEN) {
- ifp->if_ierrors++;
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, 0, &stat, sizeof(stat));
- xfer->actlen -= sizeof(stat);
- len = min(xfer->actlen, le16toh(stat.pktlen));
- len -= ETHER_CRC_LEN;
-
- if (stat.rxstat & UDAV_RSR_LCS) {
- ifp->if_collisions++;
- goto tr_setup;
- }
- if (stat.rxstat & UDAV_RSR_ERR) {
- ifp->if_ierrors++;
- goto tr_setup;
- }
- usb2_ether_rxbuf(ue, xfer->frbuffers, sizeof(stat), len);
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- usb2_ether_rxflush(ue);
- return;
-
- default: /* Error */
- DPRINTF("bulk read error, %s\n",
- usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-udav_intr_callback(struct usb2_xfer *xfer)
-{
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-udav_stop(struct usb2_ether *ue)
-{
- struct udav_softc *sc = ue->ue_sc;
- struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
-
- UDAV_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- sc->sc_flags &= ~UDAV_FLAG_LINK;
-
- /*
- * stop all the transfers, if not already stopped:
- */
- usb2_transfer_stop(sc->sc_xfer[UDAV_BULK_DT_WR]);
- usb2_transfer_stop(sc->sc_xfer[UDAV_BULK_DT_RD]);
- usb2_transfer_stop(sc->sc_xfer[UDAV_INTR_DT_RD]);
-
- udav_reset(sc);
-}
-
-static int
-udav_ifmedia_upd(struct ifnet *ifp)
-{
- struct udav_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- UDAV_LOCK_ASSERT(sc, MA_OWNED);
-
- sc->sc_flags &= ~UDAV_FLAG_LINK;
- if (mii->mii_instance) {
- struct mii_softc *miisc;
-
- LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
- mii_phy_reset(miisc);
- }
- mii_mediachg(mii);
- return (0);
-}
-
-static void
-udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct udav_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- UDAV_LOCK(sc);
- mii_pollstat(mii);
- UDAV_UNLOCK(sc);
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
-}
-
-static void
-udav_tick(struct usb2_ether *ue)
-{
- struct udav_softc *sc = ue->ue_sc;
- struct mii_data *mii = GET_MII(sc);
-
- UDAV_LOCK_ASSERT(sc, MA_OWNED);
-
- mii_tick(mii);
- if ((sc->sc_flags & UDAV_FLAG_LINK) == 0
- && mii->mii_media_status & IFM_ACTIVE &&
- IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
- sc->sc_flags |= UDAV_FLAG_LINK;
- udav_start(ue);
- }
-}
-
-static int
-udav_miibus_readreg(device_t dev, int phy, int reg)
-{
- struct udav_softc *sc = device_get_softc(dev);
- uint16_t data16;
- uint8_t val[2];
- int locked;
-
- /* XXX: one PHY only for the internal PHY */
- if (phy != 0)
- return (0);
-
- locked = mtx_owned(&sc->sc_mtx);
- if (!locked)
- UDAV_LOCK(sc);
-
- /* select internal PHY and set PHY register address */
- udav_csr_write1(sc, UDAV_EPAR,
- UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
-
- /* select PHY operation and start read command */
- udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR);
-
- /* XXX: should we wait? */
-
- /* end read command */
- UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRR);
-
- /* retrieve the result from data registers */
- udav_csr_read(sc, UDAV_EPDRL, val, 2);
-
- data16 = (val[0] | (val[1] << 8));
-
- DPRINTFN(11, "phy=%d reg=0x%04x => 0x%04x\n",
- phy, reg, data16);
-
- if (!locked)
- UDAV_UNLOCK(sc);
- return (data16);
-}
-
-static int
-udav_miibus_writereg(device_t dev, int phy, int reg, int data)
-{
- struct udav_softc *sc = device_get_softc(dev);
- uint8_t val[2];
- int locked;
-
- /* XXX: one PHY only for the internal PHY */
- if (phy != 0)
- return (0);
-
- locked = mtx_owned(&sc->sc_mtx);
- if (!locked)
- UDAV_LOCK(sc);
-
- /* select internal PHY and set PHY register address */
- udav_csr_write1(sc, UDAV_EPAR,
- UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
-
- /* put the value to the data registers */
- val[0] = (data & 0xff);
- val[1] = (data >> 8) & 0xff;
- udav_csr_write(sc, UDAV_EPDRL, val, 2);
-
- /* select PHY operation and start write command */
- udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW);
-
- /* XXX: should we wait? */
-
- /* end write command */
- UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW);
-
- if (!locked)
- UDAV_UNLOCK(sc);
- return (0);
-}
-
-static void
-udav_miibus_statchg(device_t dev)
-{
- /* nothing to do */
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static int
-udav_shutdown(device_t dev)
-{
- struct udav_softc *sc = device_get_softc(dev);
-
- usb2_ether_ifshutdown(&sc->sc_ue);
-
- return (0);
-}
diff --git a/sys/dev/usb2/ethernet/if_udavreg.h b/sys/dev/usb2/ethernet/if_udavreg.h
deleted file mode 100644
index d652f5b..0000000
--- a/sys/dev/usb2/ethernet/if_udavreg.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/* $NetBSD: if_udavreg.h,v 1.2 2003/09/04 15:17:39 tsutsui Exp $ */
-/* $nabe: if_udavreg.h,v 1.2 2003/08/21 16:26:40 nabe Exp $ */
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2003
- * Shingo WATANABE <nabe@nabechan.org>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#define UDAV_IFACE_INDEX 0
-#define UDAV_CONFIG_INDEX 0 /* config number 1 */
-
-#define UDAV_TX_TIMEOUT 1000
-#define UDAV_TIMEOUT 10000
-
-#define UDAV_TX_TIMEOUT 1000
-#define UDAV_TIMEOUT 10000
-
-/* Packet length */
-#define UDAV_MIN_FRAME_LEN 60
-
-/* Request */
-#define UDAV_REQ_REG_READ 0x00 /* Read from register(s) */
-#define UDAV_REQ_REG_WRITE 0x01 /* Write to register(s) */
-#define UDAV_REQ_REG_WRITE1 0x03 /* Write to a register */
-
-#define UDAV_REQ_MEM_READ 0x02 /* Read from memory */
-#define UDAV_REQ_MEM_WRITE 0x05 /* Write to memory */
-#define UDAV_REQ_MEM_WRITE1 0x07 /* Write a byte to memory */
-
-/* Registers */
-#define UDAV_NCR 0x00 /* Network Control Register */
-#define UDAV_NCR_EXT_PHY (1<<7) /* Select External PHY */
-#define UDAV_NCR_WAKEEN (1<<6) /* Wakeup Event Enable */
-#define UDAV_NCR_FCOL (1<<4) /* Force Collision Mode */
-#define UDAV_NCR_FDX (1<<3) /* Full-Duplex Mode (RO on Int. PHY) */
-#define UDAV_NCR_LBK1 (1<<2) /* Lookback Mode */
-#define UDAV_NCR_LBK0 (1<<1) /* Lookback Mode */
-#define UDAV_NCR_RST (1<<0) /* Software reset */
-
-#define UDAV_RCR 0x05 /* RX Control Register */
-#define UDAV_RCR_WTDIS (1<<6) /* Watchdog Timer Disable */
-#define UDAV_RCR_DIS_LONG (1<<5) /* Discard Long Packet(over 1522Byte) */
-#define UDAV_RCR_DIS_CRC (1<<4) /* Discard CRC Error Packet */
-#define UDAV_RCR_ALL (1<<3) /* Pass All Multicast */
-#define UDAV_RCR_RUNT (1<<2) /* Pass Runt Packet */
-#define UDAV_RCR_PRMSC (1<<1) /* Promiscuous Mode */
-#define UDAV_RCR_RXEN (1<<0) /* RX Enable */
-
-#define UDAV_RSR 0x06 /* RX Status Register */
-#define UDAV_RSR_RF (1<<7) /* Runt Frame */
-#define UDAV_RSR_MF (1<<6) /* Multicast Frame */
-#define UDAV_RSR_LCS (1<<5) /* Late Collision Seen */
-#define UDAV_RSR_RWTO (1<<4) /* Receive Watchdog Time-Out */
-#define UDAV_RSR_PLE (1<<3) /* Physical Layer Error */
-#define UDAV_RSR_AE (1<<2) /* Alignment Error */
-#define UDAV_RSR_CE (1<<1) /* CRC Error */
-#define UDAV_RSR_FOE (1<<0) /* FIFO Overflow Error */
-#define UDAV_RSR_ERR (UDAV_RSR_RF | UDAV_RSR_LCS | \
- UDAV_RSR_RWTO | UDAV_RSR_PLE | \
- UDAV_RSR_AE | UDAV_RSR_CE | UDAV_RSR_FOE)
-
-#define UDAV_EPCR 0x0b /* EEPROM & PHY Control Register */
-#define UDAV_EPCR_REEP (1<<5) /* Reload EEPROM */
-#define UDAV_EPCR_WEP (1<<4) /* Write EEPROM enable */
-#define UDAV_EPCR_EPOS (1<<3) /* EEPROM or PHY Operation Select */
-#define UDAV_EPCR_ERPRR (1<<2) /* EEPROM/PHY Register Read Command */
-#define UDAV_EPCR_ERPRW (1<<1) /* EEPROM/PHY Register Write Command */
-#define UDAV_EPCR_ERRE (1<<0) /* EEPROM/PHY Access Status */
-
-#define UDAV_EPAR 0x0c /* EEPROM & PHY Control Register */
-#define UDAV_EPAR_PHY_ADR1 (1<<7) /* PHY Address bit 1 */
-#define UDAV_EPAR_PHY_ADR0 (1<<6) /* PHY Address bit 0 */
-#define UDAV_EPAR_EROA (1<<0) /* EEPROM Word/PHY Register Address */
-#define UDAV_EPAR_EROA_MASK (0x1f) /* [5:0] */
-
-#define UDAV_EPDRL 0x0d /* EEPROM & PHY Data Register */
-#define UDAV_EPDRH 0x0e /* EEPROM & PHY Data Register */
-
-#define UDAV_PAR0 0x10 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR1 0x11 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR2 0x12 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR3 0x13 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR4 0x14 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR5 0x15 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR UDAV_PAR0
-
-#define UDAV_MAR0 0x16 /* Multicast Register */
-#define UDAV_MAR1 0x17 /* Multicast Register */
-#define UDAV_MAR2 0x18 /* Multicast Register */
-#define UDAV_MAR3 0x19 /* Multicast Register */
-#define UDAV_MAR4 0x1a /* Multicast Register */
-#define UDAV_MAR5 0x1b /* Multicast Register */
-#define UDAV_MAR6 0x1c /* Multicast Register */
-#define UDAV_MAR7 0x1d /* Multicast Register */
-#define UDAV_MAR UDAV_MAR0
-
-#define UDAV_GPCR 0x1e /* General purpose control register */
-#define UDAV_GPCR_GEP_CNTL6 (1<<6) /* General purpose control 6 */
-#define UDAV_GPCR_GEP_CNTL5 (1<<5) /* General purpose control 5 */
-#define UDAV_GPCR_GEP_CNTL4 (1<<4) /* General purpose control 4 */
-#define UDAV_GPCR_GEP_CNTL3 (1<<3) /* General purpose control 3 */
-#define UDAV_GPCR_GEP_CNTL2 (1<<2) /* General purpose control 2 */
-#define UDAV_GPCR_GEP_CNTL1 (1<<1) /* General purpose control 1 */
-#define UDAV_GPCR_GEP_CNTL0 (1<<0) /* General purpose control 0 */
-
-#define UDAV_GPR 0x1f /* General purpose register */
-#define UDAV_GPR_GEPIO6 (1<<6) /* General purpose 6 */
-#define UDAV_GPR_GEPIO5 (1<<5) /* General purpose 5 */
-#define UDAV_GPR_GEPIO4 (1<<4) /* General purpose 4 */
-#define UDAV_GPR_GEPIO3 (1<<3) /* General purpose 3 */
-#define UDAV_GPR_GEPIO2 (1<<2) /* General purpose 2 */
-#define UDAV_GPR_GEPIO1 (1<<1) /* General purpose 1 */
-#define UDAV_GPR_GEPIO0 (1<<0) /* General purpose 0 */
-
-#define GET_MII(sc) usb2_ether_getmii(&(sc)->sc_ue)
-
-struct udav_rxpkt {
- uint8_t rxstat;
- uint16_t pktlen;
-} __packed;
-
-enum {
- UDAV_BULK_DT_WR,
- UDAV_BULK_DT_RD,
- UDAV_INTR_DT_RD,
- UDAV_N_TRANSFER,
-};
-
-struct udav_softc {
- struct usb2_ether sc_ue;
- struct mtx sc_mtx;
- struct usb2_xfer *sc_xfer[UDAV_N_TRANSFER];
-
- int sc_flags;
-#define UDAV_FLAG_LINK 0x0001
-#define UDAV_FLAG_EXT_PHY 0x0040
-};
-
-#define UDAV_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
-#define UDAV_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
-#define UDAV_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)
diff --git a/sys/dev/usb2/ethernet/usb2_ethernet.c b/sys/dev/usb2/ethernet/usb2_ethernet.c
deleted file mode 100644
index a01f942..0000000
--- a/sys/dev/usb2/ethernet/usb2_ethernet.c
+++ /dev/null
@@ -1,587 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2009 Andrew Thompson (thompsa@FreeBSD.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 <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_endian.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/ethernet/usb2_ethernet.h>
-
-SYSCTL_NODE(_net, OID_AUTO, ue, CTLFLAG_RD, 0, "USB Ethernet parameters");
-
-#define UE_LOCK(_ue) mtx_lock((_ue)->ue_mtx)
-#define UE_UNLOCK(_ue) mtx_unlock((_ue)->ue_mtx)
-#define UE_LOCK_ASSERT(_ue, t) mtx_assert((_ue)->ue_mtx, t)
-
-MODULE_DEPEND(usb2_ethernet, usb2_core, 1, 1, 1);
-MODULE_DEPEND(usb2_ethernet, miibus, 1, 1, 1);
-
-static struct unrhdr *ueunit;
-
-static usb2_proc_callback_t ue_attach_post_task;
-static usb2_proc_callback_t ue_promisc_task;
-static usb2_proc_callback_t ue_setmulti_task;
-static usb2_proc_callback_t ue_ifmedia_task;
-static usb2_proc_callback_t ue_tick_task;
-static usb2_proc_callback_t ue_start_task;
-static usb2_proc_callback_t ue_stop_task;
-
-static void ue_init(void *);
-static void ue_start(struct ifnet *);
-static int ue_ifmedia_upd(struct ifnet *);
-static void ue_watchdog(void *);
-
-/*
- * Return values:
- * 0: success
- * Else: device has been detached
- */
-uint8_t
-usb2_ether_pause(struct usb2_ether *ue, unsigned int _ticks)
-{
- if (usb2_proc_is_gone(&ue->ue_tq)) {
- /* nothing to do */
- return (1);
- }
- usb2_pause_mtx(ue->ue_mtx, _ticks);
- return (0);
-}
-
-static void
-ue_queue_command(struct usb2_ether *ue,
- usb2_proc_callback_t *fn,
- struct usb2_proc_msg *t0, struct usb2_proc_msg *t1)
-{
- struct usb2_ether_cfg_task *task;
-
- UE_LOCK_ASSERT(ue, MA_OWNED);
-
- if (usb2_proc_is_gone(&ue->ue_tq)) {
- return; /* nothing to do */
- }
- /*
- * NOTE: The task cannot get executed before we drop the
- * "sc_mtx" mutex. It is safe to update fields in the message
- * structure after that the message got queued.
- */
- task = (struct usb2_ether_cfg_task *)
- usb2_proc_msignal(&ue->ue_tq, t0, t1);
-
- /* Setup callback and self pointers */
- task->hdr.pm_callback = fn;
- task->ue = ue;
-
- /*
- * Start and stop must be synchronous!
- */
- if ((fn == ue_start_task) || (fn == ue_stop_task))
- usb2_proc_mwait(&ue->ue_tq, t0, t1);
-}
-
-struct ifnet *
-usb2_ether_getifp(struct usb2_ether *ue)
-{
- return (ue->ue_ifp);
-}
-
-struct mii_data *
-usb2_ether_getmii(struct usb2_ether *ue)
-{
- return (device_get_softc(ue->ue_miibus));
-}
-
-void *
-usb2_ether_getsc(struct usb2_ether *ue)
-{
- return (ue->ue_sc);
-}
-
-static int
-ue_sysctl_parent(SYSCTL_HANDLER_ARGS)
-{
- struct usb2_ether *ue = arg1;
- const char *name;
-
- name = device_get_nameunit(ue->ue_dev);
- return SYSCTL_OUT(req, name, strlen(name));
-}
-
-int
-usb2_ether_ifattach(struct usb2_ether *ue)
-{
- int error;
-
- /* check some critical parameters */
- if ((ue->ue_dev == NULL) ||
- (ue->ue_udev == NULL) ||
- (ue->ue_mtx == NULL) ||
- (ue->ue_methods == NULL))
- return (EINVAL);
-
- error = usb2_proc_create(&ue->ue_tq, ue->ue_mtx,
- device_get_nameunit(ue->ue_dev), USB_PRI_MED);
- if (error) {
- device_printf(ue->ue_dev, "could not setup taskqueue\n");
- goto error;
- }
-
- /* fork rest of the attach code */
- UE_LOCK(ue);
- ue_queue_command(ue, ue_attach_post_task,
- &ue->ue_sync_task[0].hdr,
- &ue->ue_sync_task[1].hdr);
- UE_UNLOCK(ue);
-
-error:
- return (error);
-}
-
-static void
-ue_attach_post_task(struct usb2_proc_msg *_task)
-{
- struct usb2_ether_cfg_task *task =
- (struct usb2_ether_cfg_task *)_task;
- struct usb2_ether *ue = task->ue;
- struct ifnet *ifp;
- int error;
- char num[14]; /* sufficient for 32 bits */
-
- /* first call driver's post attach routine */
- ue->ue_methods->ue_attach_post(ue);
-
- UE_UNLOCK(ue);
-
- ue->ue_unit = alloc_unr(ueunit);
- usb2_callout_init_mtx(&ue->ue_watchdog, ue->ue_mtx, 0);
- sysctl_ctx_init(&ue->ue_sysctl_ctx);
-
- ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(ue->ue_dev, "could not allocate ifnet\n");
- goto error;
- }
-
- ifp->if_softc = ue;
- if_initname(ifp, "ue", ue->ue_unit);
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- if (ue->ue_methods->ue_ioctl != NULL)
- ifp->if_ioctl = ue->ue_methods->ue_ioctl;
- else
- ifp->if_ioctl = usb2_ether_ioctl;
- ifp->if_start = ue_start;
- ifp->if_init = ue_init;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
- ue->ue_ifp = ifp;
-
- if (ue->ue_methods->ue_mii_upd != NULL &&
- ue->ue_methods->ue_mii_sts != NULL) {
- mtx_lock(&Giant); /* device_xxx() depends on this */
- error = mii_phy_probe(ue->ue_dev, &ue->ue_miibus,
- ue_ifmedia_upd, ue->ue_methods->ue_mii_sts);
- mtx_unlock(&Giant);
- if (error) {
- device_printf(ue->ue_dev, "MII without any PHY\n");
- goto error;
- }
- }
-
- if_printf(ifp, "<USB Ethernet> on %s\n", device_get_nameunit(ue->ue_dev));
- ether_ifattach(ifp, ue->ue_eaddr);
-
- snprintf(num, sizeof(num), "%u", ue->ue_unit);
- ue->ue_sysctl_oid = SYSCTL_ADD_NODE(&ue->ue_sysctl_ctx,
- &SYSCTL_NODE_CHILDREN(_net, ue),
- OID_AUTO, num, CTLFLAG_RD, NULL, "");
- SYSCTL_ADD_PROC(&ue->ue_sysctl_ctx,
- SYSCTL_CHILDREN(ue->ue_sysctl_oid), OID_AUTO,
- "%parent", CTLFLAG_RD, ue, 0,
- ue_sysctl_parent, "A", "parent device");
-
- UE_LOCK(ue);
- return;
-
-error:
- free_unr(ueunit, ue->ue_unit);
- if (ue->ue_ifp != NULL) {
- if_free(ue->ue_ifp);
- ue->ue_ifp = NULL;
- }
- UE_LOCK(ue);
- return;
-}
-
-void
-usb2_ether_ifdetach(struct usb2_ether *ue)
-{
- struct ifnet *ifp;
-
- /* wait for any post attach or other command to complete */
- usb2_proc_drain(&ue->ue_tq);
-
- /* read "ifnet" pointer after taskqueue drain */
- ifp = ue->ue_ifp;
-
- if (ifp != NULL) {
-
- /* we are not running any more */
- UE_LOCK(ue);
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- UE_UNLOCK(ue);
-
- /* drain any callouts */
- usb2_callout_drain(&ue->ue_watchdog);
-
- /* detach miibus */
- if (ue->ue_miibus != NULL) {
- mtx_lock(&Giant); /* device_xxx() depends on this */
- device_delete_child(ue->ue_dev, ue->ue_miibus);
- mtx_unlock(&Giant);
- }
-
- /* detach ethernet */
- ether_ifdetach(ifp);
-
- /* free interface instance */
- if_free(ifp);
-
- /* free sysctl */
- sysctl_ctx_free(&ue->ue_sysctl_ctx);
-
- /* free unit */
- free_unr(ueunit, ue->ue_unit);
- }
-
- /* free taskqueue, if any */
- usb2_proc_free(&ue->ue_tq);
-}
-
-void
-usb2_ether_ifshutdown(struct usb2_ether *ue)
-{
- struct ifnet *ifp = ue->ue_ifp;
-
- UE_LOCK(ue);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ue_queue_command(ue, ue_stop_task,
- &ue->ue_sync_task[0].hdr,
- &ue->ue_sync_task[1].hdr);
- UE_UNLOCK(ue);
-}
-
-uint8_t
-usb2_ether_is_gone(struct usb2_ether *ue)
-{
- return (usb2_proc_is_gone(&ue->ue_tq));
-}
-
-static void
-ue_init(void *arg)
-{
- struct usb2_ether *ue = arg;
-
- UE_LOCK(ue);
- ue_queue_command(ue, ue_start_task,
- &ue->ue_sync_task[0].hdr,
- &ue->ue_sync_task[1].hdr);
- UE_UNLOCK(ue);
-}
-
-static void
-ue_start_task(struct usb2_proc_msg *_task)
-{
- struct usb2_ether_cfg_task *task =
- (struct usb2_ether_cfg_task *)_task;
- struct usb2_ether *ue = task->ue;
- struct ifnet *ifp = ue->ue_ifp;
-
- UE_LOCK_ASSERT(ue, MA_OWNED);
-
- ue->ue_methods->ue_init(ue);
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
- if (ue->ue_methods->ue_tick != NULL)
- usb2_callout_reset(&ue->ue_watchdog, hz, ue_watchdog, ue);
-}
-
-static void
-ue_stop_task(struct usb2_proc_msg *_task)
-{
- struct usb2_ether_cfg_task *task =
- (struct usb2_ether_cfg_task *)_task;
- struct usb2_ether *ue = task->ue;
-
- UE_LOCK_ASSERT(ue, MA_OWNED);
-
- usb2_callout_stop(&ue->ue_watchdog);
-
- ue->ue_methods->ue_stop(ue);
-}
-
-static void
-ue_start(struct ifnet *ifp)
-{
- struct usb2_ether *ue = ifp->if_softc;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
- UE_LOCK(ue);
- ue->ue_methods->ue_start(ue);
- UE_UNLOCK(ue);
-}
-
-static void
-ue_promisc_task(struct usb2_proc_msg *_task)
-{
- struct usb2_ether_cfg_task *task =
- (struct usb2_ether_cfg_task *)_task;
- struct usb2_ether *ue = task->ue;
-
- ue->ue_methods->ue_setpromisc(ue);
-}
-
-static void
-ue_setmulti_task(struct usb2_proc_msg *_task)
-{
- struct usb2_ether_cfg_task *task =
- (struct usb2_ether_cfg_task *)_task;
- struct usb2_ether *ue = task->ue;
-
- ue->ue_methods->ue_setmulti(ue);
-}
-
-static int
-ue_ifmedia_upd(struct ifnet *ifp)
-{
- struct usb2_ether *ue = ifp->if_softc;
-
- /* Defer to process context */
- UE_LOCK(ue);
- ue_queue_command(ue, ue_ifmedia_task,
- &ue->ue_media_task[0].hdr,
- &ue->ue_media_task[1].hdr);
- UE_UNLOCK(ue);
-
- return (0);
-}
-
-static void
-ue_ifmedia_task(struct usb2_proc_msg *_task)
-{
- struct usb2_ether_cfg_task *task =
- (struct usb2_ether_cfg_task *)_task;
- struct usb2_ether *ue = task->ue;
- struct ifnet *ifp = ue->ue_ifp;
-
- ue->ue_methods->ue_mii_upd(ifp);
-}
-
-static void
-ue_watchdog(void *arg)
-{
- struct usb2_ether *ue = arg;
- struct ifnet *ifp = ue->ue_ifp;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
- ue_queue_command(ue, ue_tick_task,
- &ue->ue_tick_task[0].hdr,
- &ue->ue_tick_task[1].hdr);
-
- usb2_callout_reset(&ue->ue_watchdog, hz, ue_watchdog, ue);
-}
-
-static void
-ue_tick_task(struct usb2_proc_msg *_task)
-{
- struct usb2_ether_cfg_task *task =
- (struct usb2_ether_cfg_task *)_task;
- struct usb2_ether *ue = task->ue;
- struct ifnet *ifp = ue->ue_ifp;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
- ue->ue_methods->ue_tick(ue);
-}
-
-int
-usb2_ether_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct usb2_ether *ue = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *)data;
- struct mii_data *mii;
- int error = 0;
-
- switch (command) {
- case SIOCSIFFLAGS:
- UE_LOCK(ue);
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ue_queue_command(ue, ue_promisc_task,
- &ue->ue_promisc_task[0].hdr,
- &ue->ue_promisc_task[1].hdr);
- else
- ue_queue_command(ue, ue_start_task,
- &ue->ue_sync_task[0].hdr,
- &ue->ue_sync_task[1].hdr);
- } else {
- ue_queue_command(ue, ue_stop_task,
- &ue->ue_sync_task[0].hdr,
- &ue->ue_sync_task[1].hdr);
- }
- UE_UNLOCK(ue);
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- UE_LOCK(ue);
- ue_queue_command(ue, ue_setmulti_task,
- &ue->ue_multi_task[0].hdr,
- &ue->ue_multi_task[1].hdr);
- UE_UNLOCK(ue);
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- if (ue->ue_miibus != NULL) {
- mii = device_get_softc(ue->ue_miibus);
- error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
- } else
- error = ether_ioctl(ifp, command, data);
- break;
- default:
- error = ether_ioctl(ifp, command, data);
- break;
- }
- return (error);
-}
-
-static int
-usb2_ether_modevent(module_t mod, int type, void *data)
-{
-
- switch (type) {
- case MOD_LOAD:
- ueunit = new_unrhdr(0, INT_MAX, NULL);
- break;
- case MOD_UNLOAD:
- break;
- default:
- return (EOPNOTSUPP);
- }
- return (0);
-}
-static moduledata_t usb2_ether_mod = {
- "usb2_ethernet",
- usb2_ether_modevent,
- 0
-};
-
-int
-usb2_ether_rxmbuf(struct usb2_ether *ue, struct mbuf *m,
- unsigned int len)
-{
- struct ifnet *ifp = ue->ue_ifp;
-
- UE_LOCK_ASSERT(ue, MA_OWNED);
-
- /* finalize mbuf */
- ifp->if_ipackets++;
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = len;
-
- /* enqueue for later when the lock can be released */
- _IF_ENQUEUE(&ue->ue_rxq, m);
- return (0);
-}
-
-int
-usb2_ether_rxbuf(struct usb2_ether *ue, struct usb2_page_cache *pc,
- unsigned int offset, unsigned int len)
-{
- struct ifnet *ifp = ue->ue_ifp;
- struct mbuf *m;
-
- UE_LOCK_ASSERT(ue, MA_OWNED);
-
- if (len < ETHER_HDR_LEN || len > MCLBYTES)
- return (1);
-
- m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (m == NULL) {
- ifp->if_ierrors++;
- return (ENOMEM);
- }
-
- m_adj(m, ETHER_ALIGN);
- usb2_copy_out(pc, offset, mtod(m, uint8_t *), len);
-
- /* finalize mbuf */
- ifp->if_ipackets++;
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = len;
-
- /* enqueue for later when the lock can be released */
- _IF_ENQUEUE(&ue->ue_rxq, m);
- return (0);
-}
-
-void
-usb2_ether_rxflush(struct usb2_ether *ue)
-{
- struct ifnet *ifp = ue->ue_ifp;
- struct mbuf *m;
-
- UE_LOCK_ASSERT(ue, MA_OWNED);
-
- for (;;) {
- _IF_DEQUEUE(&ue->ue_rxq, m);
- if (m == NULL)
- break;
-
- /*
- * The USB xfer has been resubmitted so its safe to unlock now.
- */
- UE_UNLOCK(ue);
- ifp->if_input(ifp, m);
- UE_LOCK(ue);
- }
-}
-
-DECLARE_MODULE(usb2_ethernet, usb2_ether_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
-MODULE_VERSION(usb2_ethernet, 1);
diff --git a/sys/dev/usb2/ethernet/usb2_ethernet.h b/sys/dev/usb2/ethernet/usb2_ethernet.h
deleted file mode 100644
index 0ee36f2..0000000
--- a/sys/dev/usb2/ethernet/usb2_ethernet.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_ETHERNET_H_
-#define _USB2_ETHERNET_H_
-
-#include "opt_inet.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/limits.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-#include <net/bpf.h>
-#include <net/ethernet.h>
-
-#include "miibus_if.h"
-
-#include <dev/mii/mii.h>
-#include <dev/mii/miivar.h>
-
-struct usb2_ether;
-struct usb2_device_request;
-
-typedef void (usb2_ether_fn_t)(struct usb2_ether *);
-
-struct usb2_ether_methods {
- usb2_ether_fn_t *ue_attach_post;
- usb2_ether_fn_t *ue_start;
- usb2_ether_fn_t *ue_init;
- usb2_ether_fn_t *ue_stop;
- usb2_ether_fn_t *ue_setmulti;
- usb2_ether_fn_t *ue_setpromisc;
- usb2_ether_fn_t *ue_tick;
- int (*ue_mii_upd)(struct ifnet *);
- void (*ue_mii_sts)(struct ifnet *,
- struct ifmediareq *);
- int (*ue_ioctl)(struct ifnet *, u_long, caddr_t);
-
-};
-
-struct usb2_ether_cfg_task {
- struct usb2_proc_msg hdr;
- struct usb2_ether *ue;
-};
-
-struct usb2_ether {
- /* NOTE: the "ue_ifp" pointer must be first --hps */
- struct ifnet *ue_ifp;
- struct mtx *ue_mtx;
- const struct usb2_ether_methods *ue_methods;
- struct sysctl_oid *ue_sysctl_oid;
- void *ue_sc;
- struct usb2_device *ue_udev; /* used by usb2_ether_do_request() */
- device_t ue_dev;
- device_t ue_miibus;
-
- struct usb2_process ue_tq;
- struct sysctl_ctx_list ue_sysctl_ctx;
- struct ifqueue ue_rxq;
- struct usb2_callout ue_watchdog;
- struct usb2_ether_cfg_task ue_sync_task[2];
- struct usb2_ether_cfg_task ue_media_task[2];
- struct usb2_ether_cfg_task ue_multi_task[2];
- struct usb2_ether_cfg_task ue_promisc_task[2];
- struct usb2_ether_cfg_task ue_tick_task[2];
-
- int ue_unit;
-
- /* ethernet address from eeprom */
- uint8_t ue_eaddr[ETHER_ADDR_LEN];
-};
-
-#define usb2_ether_do_request(ue,req,data,timo) \
- usb2_do_request_proc((ue)->ue_udev,&(ue)->ue_tq,req,data,0,NULL,timo)
-
-uint8_t usb2_ether_pause(struct usb2_ether *, unsigned int);
-struct ifnet *usb2_ether_getifp(struct usb2_ether *);
-struct mii_data *usb2_ether_getmii(struct usb2_ether *);
-void *usb2_ether_getsc(struct usb2_ether *);
-int usb2_ether_ifattach(struct usb2_ether *);
-void usb2_ether_ifdetach(struct usb2_ether *);
-int usb2_ether_ioctl(struct ifnet *, u_long, caddr_t);
-int usb2_ether_rxmbuf(struct usb2_ether *, struct mbuf *,
- unsigned int);
-int usb2_ether_rxbuf(struct usb2_ether *,
- struct usb2_page_cache *,
- unsigned int, unsigned int);
-void usb2_ether_rxflush(struct usb2_ether *);
-void usb2_ether_ifshutdown(struct usb2_ether *);
-uint8_t usb2_ether_is_gone(struct usb2_ether *);
-#endif /* _USB2_ETHERNET_H_ */
diff --git a/sys/dev/usb2/image/usb2_image.c b/sys/dev/usb2/image/usb2_image.c
deleted file mode 100644
index 5f6badb..0000000
--- a/sys/dev/usb2/image/usb2_image.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/image/usb2_image.h>
-
-MODULE_VERSION(usb2_image, 1);
-MODULE_DEPEND(usb2_image, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/image/usb2_image.h b/sys/dev/usb2/image/usb2_image.h
deleted file mode 100644
index ce1526e..0000000
--- a/sys/dev/usb2/image/usb2_image.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_IMAGE_H_
-#define _USB2_IMAGE_H_
-
-#endif /* _USB2_IMAGE_H_ */
diff --git a/sys/dev/usb2/image/uscanner2.c b/sys/dev/usb2/image/uscanner2.c
deleted file mode 100644
index 54dfd55..0000000
--- a/sys/dev/usb2/image/uscanner2.c
+++ /dev/null
@@ -1,644 +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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR uscanner_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-#include <dev/usb2/core/usb2_dev.h>
-
-#if USB_DEBUG
-static int uscanner_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uscanner, CTLFLAG_RW, 0, "USB uscanner");
-SYSCTL_INT(_hw_usb2_uscanner, OID_AUTO, debug, CTLFLAG_RW, &uscanner_debug,
- 0, "uscanner debug level");
-#endif
-
-/*
- * uscanner transfers macros definition.
- */
-#define USCANNER_BSIZE (1 << 15)
-#define USCANNER_IFQ_MAXLEN 2
-
-/*
- * Transfers stallings handling flags definition.
- */
-#define USCANNER_FLAG_READ_STALL 0x01
-#define USCANNER_FLAG_WRITE_STALL 0x02
-
-/*
- * uscanner_info flags definition.
- */
-#define USCANNER_FLAG_KEEP_OPEN 0x04
-
-enum {
- USCANNER_BULK_DT_WR,
- USCANNER_BULK_DT_RD,
- USCANNER_BULK_CS_WR,
- USCANNER_BULK_CS_RD,
- USCANNER_N_TRANSFER = 4,
-};
-
-struct uscanner_softc {
- struct usb2_fifo_sc sc_fifo;
- struct mtx sc_mtx;
-
- struct usb2_xfer *sc_xfer[USCANNER_N_TRANSFER];
-
- uint8_t sc_flags; /* Used to prevent stalls */
-};
-
-/*
- * Prototypes for driver handling routines (sorted by use).
- */
-static device_probe_t uscanner_probe;
-static device_attach_t uscanner_attach;
-static device_detach_t uscanner_detach;
-
-/*
- * Prototypes for xfer transfer callbacks.
- */
-static usb2_callback_t uscanner_read_callback;
-static usb2_callback_t uscanner_read_clear_stall_callback;
-static usb2_callback_t uscanner_write_callback;
-static usb2_callback_t uscanner_write_clear_stall_callback;
-
-/*
- * Prototypes for the character device handling routines.
- */
-static usb2_fifo_close_t uscanner_close;
-static usb2_fifo_cmd_t uscanner_start_read;
-static usb2_fifo_cmd_t uscanner_start_write;
-static usb2_fifo_cmd_t uscanner_stop_read;
-static usb2_fifo_cmd_t uscanner_stop_write;
-static usb2_fifo_open_t uscanner_open;
-
-static struct usb2_fifo_methods uscanner_fifo_methods = {
- .f_close = &uscanner_close,
- .f_open = &uscanner_open,
- .f_start_read = &uscanner_start_read,
- .f_start_write = &uscanner_start_write,
- .f_stop_read = &uscanner_stop_read,
- .f_stop_write = &uscanner_stop_write,
- .basename[0] = "uscanner",
-};
-
-/*
- * xfer transfers array. Resolve-stalling callbacks are marked as control
- * transfers.
- */
-static const struct usb2_config uscanner_config[USCANNER_N_TRANSFER] = {
- [USCANNER_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = USCANNER_BSIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.proxy_buffer = 1,.force_short_xfer = 1,},
- .mh.callback = &uscanner_write_callback,
- },
-
- [USCANNER_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = USCANNER_BSIZE,
- .mh.flags = {.pipe_bof = 1,.proxy_buffer = 1,.short_xfer_ok = 1,},
- .mh.callback = &uscanner_read_callback,
- },
-
- [USCANNER_BULK_CS_WR] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &uscanner_write_clear_stall_callback,
- .mh.timeout = 1000,
- .mh.interval = 50, /* 50ms */
- },
-
- [USCANNER_BULK_CS_RD] = {
- .type = UE_CONTROL,
- .endpoint = 0x00,
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &uscanner_read_clear_stall_callback,
- .mh.timeout = 1000,
- .mh.interval = 50, /* 50ms */
- },
-};
-
-static devclass_t uscanner_devclass;
-
-static device_method_t uscanner_methods[] = {
- DEVMETHOD(device_probe, uscanner_probe),
- DEVMETHOD(device_attach, uscanner_attach),
- DEVMETHOD(device_detach, uscanner_detach),
- {0, 0}
-};
-
-static driver_t uscanner_driver = {
- .name = "uscanner",
- .methods = uscanner_methods,
- .size = sizeof(struct uscanner_softc),
-};
-
-DRIVER_MODULE(uscanner, ushub, uscanner_driver, uscanner_devclass, NULL, 0);
-MODULE_DEPEND(uscanner, usb2_image, 1, 1, 1);
-MODULE_DEPEND(uscanner, usb2_core, 1, 1, 1);
-
-/*
- * USB scanners device IDs
- */
-static const struct usb2_device_id uscanner_devs[] = {
- /* Acer */
- {USB_VPI(USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U, 0)},
- {USB_VPI(USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640U, 0)},
- {USB_VPI(USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640BT, 0)},
- {USB_VPI(USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_620U, 0)},
- {USB_VPI(USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_1240U, 0)},
- {USB_VPI(USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_C310U, 0)},
- {USB_VPI(USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_4300U, 0)},
- /* AGFA */
- {USB_VPI(USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1236U, 0)},
- {USB_VPI(USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U, 0)},
- {USB_VPI(USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U2, 0)},
- {USB_VPI(USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANTOUCH, 0)},
- {USB_VPI(USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE40, 0)},
- {USB_VPI(USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE50, 0)},
- {USB_VPI(USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE20, 0)},
- {USB_VPI(USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE25, 0)},
- {USB_VPI(USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE26, 0)},
- {USB_VPI(USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE52, 0)},
- /* Avision */
- {USB_VPI(USB_VENDOR_AVISION, USB_PRODUCT_AVISION_1200U, 0)},
- /* Canon */
- {USB_VPI(USB_VENDOR_CANON, USB_PRODUCT_CANON_N656U, 0)},
- {USB_VPI(USB_VENDOR_CANON, USB_PRODUCT_CANON_N676U, 0)},
- {USB_VPI(USB_VENDOR_CANON, USB_PRODUCT_CANON_N1220U, 0)},
- {USB_VPI(USB_VENDOR_CANON, USB_PRODUCT_CANON_D660U, 0)},
- {USB_VPI(USB_VENDOR_CANON, USB_PRODUCT_CANON_N1240U, 0)},
- {USB_VPI(USB_VENDOR_CANON, USB_PRODUCT_CANON_LIDE25, 0)},
- /* Epson */
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_636, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_610, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1200, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1240, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1250, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1270, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1600, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1640, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_640U, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1650, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1660, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1670, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1260, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_RX425, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_3200, USCANNER_FLAG_KEEP_OPEN)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9700F, USCANNER_FLAG_KEEP_OPEN)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_CX5400, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX7400, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9300UF, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_2480, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_3500, USCANNER_FLAG_KEEP_OPEN)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_3590, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4200, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4800, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4990, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_5000, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_6000, 0)},
- {USB_VPI(USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX8400, 0)},
- /* HP */
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_2200C, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_3300C, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_3400CSE, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_4100C, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_4200C, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_4300C, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_4470C, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_4670V, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_S20, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_5200C, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_5300C, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_5400C, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_6200C, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_6300C, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_82x0C, 0)},
- /* Kye */
- {USB_VPI(USB_VENDOR_KYE, USB_PRODUCT_KYE_VIVIDPRO, 0)},
- /* Microtek */
- {USB_VPI(USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_X6U, 0)},
- {USB_VPI(USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX, 0)},
- {USB_VPI(USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX2, 0)},
- {USB_VPI(USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_C6, 0)},
- {USB_VPI(USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL, 0)},
- {USB_VPI(USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL2, 0)},
- {USB_VPI(USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6UL, 0)},
- /* Minolta */
- {USB_VPI(USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_5400, 0)},
- /* Mustek */
- {USB_VPI(USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CU, 0)},
- {USB_VPI(USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200F, 0)},
- {USB_VPI(USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200TA, 0)},
- {USB_VPI(USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600USB, 0)},
- {USB_VPI(USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600CU, 0)},
- {USB_VPI(USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USB, 0)},
- {USB_VPI(USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200UB, 0)},
- {USB_VPI(USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USBPLUS, 0)},
- {USB_VPI(USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CUPLUS, 0)},
- /* National */
- {USB_VPI(USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW1200, 0)},
- {USB_VPI(USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW2400, 0)},
- /* Nikon */
- {USB_VPI(USB_VENDOR_NIKON, USB_PRODUCT_NIKON_LS40, 0)},
- /* Primax */
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2X300, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E300, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2300, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E3002, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_9600, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_600U, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_6200, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_19200, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_1200U, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G600, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_636I, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2600, 0)},
- {USB_VPI(USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E600, 0)},
- /* Scanlogic */
- {USB_VPI(USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_336CX, 0)},
- /* Ultima */
- {USB_VPI(USB_VENDOR_ULTIMA, USB_PRODUCT_ULTIMA_1200UBPLUS, 0)},
- /* UMAX */
- {USB_VPI(USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1220U, 0)},
- {USB_VPI(USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1236U, 0)},
- {USB_VPI(USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2000U, 0)},
- {USB_VPI(USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2100U, 0)},
- {USB_VPI(USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2200U, 0)},
- {USB_VPI(USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA3400, 0)},
- /* Visioneer */
- {USB_VPI(USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_3000, 0)},
- {USB_VPI(USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_5300, 0)},
- {USB_VPI(USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_7600, 0)},
- {USB_VPI(USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6100, 0)},
- {USB_VPI(USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6200, 0)},
- {USB_VPI(USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8100, 0)},
- {USB_VPI(USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8600, 0)}
-};
-
-/*
- * uscanner device probing method.
- */
-static int
-uscanner_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa;
-
- DPRINTFN(11, "\n");
-
- uaa = device_get_ivars(dev);
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- /* Give other class drivers a chance for multifunctional scanners. */
- if (uaa->use_generic == 0) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(uscanner_devs, sizeof(uscanner_devs), uaa));
-}
-
-/*
- * uscanner device attaching method.
- */
-static int
-uscanner_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa;
- struct uscanner_softc *sc;
- int unit;
- int error;
-
- uaa = device_get_ivars(dev);
- sc = device_get_softc(dev);
- unit = device_get_unit(dev);
-
- /*
- * A first path softc structure filling. sc_fifo and
- * sc_xfer are initialised later.
- */
- sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
- mtx_init(&sc->sc_mtx, "uscanner mutex", NULL, MTX_DEF | MTX_RECURSE);
-
- /*
- * Announce the device:
- */
- device_set_usb2_desc(dev);
-
- /*
- * Setup the transfer.
- */
- if ((error = usb2_transfer_setup(uaa->device, &uaa->info.bIfaceIndex, sc->sc_xfer,
- uscanner_config, USCANNER_N_TRANSFER, sc, &sc->sc_mtx))) {
- device_printf(dev, "could not setup transfers, "
- "error=%s\n", usb2_errstr(error));
- goto detach;
- }
- /* set interface permissions */
- usb2_set_iface_perm(uaa->device, uaa->info.bIfaceIndex,
- UID_ROOT, GID_OPERATOR, 0644);
-
- error = usb2_fifo_attach(uaa->device, sc, &sc->sc_mtx,
- &uscanner_fifo_methods, &sc->sc_fifo,
- unit, 0 - 1, uaa->info.bIfaceIndex);
- if (error) {
- goto detach;
- }
- return (0);
-
-detach:
- uscanner_detach(dev);
- return (ENOMEM);
-}
-
-/*
- * uscanner device detaching method.
- */
-static int
-uscanner_detach(device_t dev)
-{
- struct uscanner_softc *sc;
-
- sc = device_get_softc(dev);
-
- usb2_fifo_detach(&sc->sc_fifo);
- usb2_transfer_unsetup(sc->sc_xfer, USCANNER_N_TRANSFER);
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-/*
- * Reading callback. Implemented as an "in" bulk transfer.
- */
-static void
-uscanner_read_callback(struct usb2_xfer *xfer)
-{
- struct uscanner_softc *sc;
- struct usb2_fifo *f;
-
- sc = xfer->priv_sc;
- f = sc->sc_fifo.fp[USB_FIFO_RX];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_fifo_put_data(f, xfer->frbuffers, 0,
- xfer->actlen, 1);
-
- case USB_ST_SETUP:
- /*
- * If reading is in stall, just jump to clear stall callback and
- * solve the situation.
- */
- if (sc->sc_flags & USCANNER_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_CS_RD]);
- break;
- }
- if (usb2_fifo_put_bytes_max(f) != 0) {
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- sc->sc_flags |= USCANNER_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_CS_RD]);
- }
- break;
- }
-}
-
-/*
- * Removing stall on reading callback.
- */
-static void
-uscanner_read_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct uscanner_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[USCANNER_BULK_DT_RD];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~USCANNER_FLAG_READ_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-/*
- * Writing callback. Implemented as an "out" bulk transfer.
- */
-static void
-uscanner_write_callback(struct usb2_xfer *xfer)
-{
- struct uscanner_softc *sc;
- struct usb2_fifo *f;
- uint32_t actlen;
-
- sc = xfer->priv_sc;
- f = sc->sc_fifo.fp[USB_FIFO_TX];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
- /*
- * If writing is in stall, just jump to clear stall callback and
- * solve the situation.
- */
- if (sc->sc_flags & USCANNER_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_CS_WR]);
- break;
- }
- /*
- * Write datas, setup and perform hardware transfer.
- */
- if (usb2_fifo_get_data(f, xfer->frbuffers, 0,
- xfer->max_data_length, &actlen, 0)) {
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- sc->sc_flags |= USCANNER_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_CS_WR]);
- }
- break;
- }
-}
-
-/*
- * Removing stall on writing callback.
- */
-static void
-uscanner_write_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct uscanner_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[USCANNER_BULK_DT_WR];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~USCANNER_FLAG_WRITE_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-/*
- * uscanner character device opening method.
- */
-static int
-uscanner_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- struct uscanner_softc *sc;
-
- sc = fifo->priv_sc0;
-
- if (!(sc->sc_flags & USCANNER_FLAG_KEEP_OPEN)) {
- if (fflags & FWRITE) {
- sc->sc_flags |= USCANNER_FLAG_WRITE_STALL;
- }
- if (fflags & FREAD) {
- sc->sc_flags |= USCANNER_FLAG_READ_STALL;
- }
- }
- if (fflags & FREAD) {
- if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[USCANNER_BULK_DT_RD]->max_data_length,
- USCANNER_IFQ_MAXLEN)) {
- return (ENOMEM);
- }
- }
- if (fflags & FWRITE) {
- if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[USCANNER_BULK_DT_WR]->max_data_length,
- USCANNER_IFQ_MAXLEN)) {
- return (ENOMEM);
- }
- }
- return (0);
-}
-
-static void
-uscanner_close(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- if (fflags & (FREAD | FWRITE)) {
- usb2_fifo_free_buffer(fifo);
- }
-}
-
-/*
- * uscanner character device start reading method.
- */
-static void
-uscanner_start_read(struct usb2_fifo *fifo)
-{
- struct uscanner_softc *sc;
-
- sc = fifo->priv_sc0;
- usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_DT_RD]);
-}
-
-/*
- * uscanner character device start writing method.
- */
-static void
-uscanner_start_write(struct usb2_fifo *fifo)
-{
- struct uscanner_softc *sc;
-
- sc = fifo->priv_sc0;
- usb2_transfer_start(sc->sc_xfer[USCANNER_BULK_DT_WR]);
-}
-
-/*
- * uscanner character device stop reading method.
- */
-static void
-uscanner_stop_read(struct usb2_fifo *fifo)
-{
- struct uscanner_softc *sc;
-
- sc = fifo->priv_sc0;
- usb2_transfer_stop(sc->sc_xfer[USCANNER_BULK_CS_RD]);
- usb2_transfer_stop(sc->sc_xfer[USCANNER_BULK_DT_RD]);
-}
-
-/*
- * uscanner character device stop writing method.
- */
-static void
-uscanner_stop_write(struct usb2_fifo *fifo)
-{
- struct uscanner_softc *sc;
-
- sc = fifo->priv_sc0;
- usb2_transfer_stop(sc->sc_xfer[USCANNER_BULK_CS_WR]);
- usb2_transfer_stop(sc->sc_xfer[USCANNER_BULK_DT_WR]);
-}
diff --git a/sys/dev/usb2/include/ufm2_ioctl.h b/sys/dev/usb2/include/ufm2_ioctl.h
deleted file mode 100644
index 921b3d4..0000000
--- a/sys/dev/usb2/include/ufm2_ioctl.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * Copyright (c) 2001 M. Warner Losh
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This code is based on ugen.c and ulpt.c developed by Lennart Augustsson.
- * This code includes software developed by the NetBSD Foundation, Inc. and
- * its contributors.
- */
-
-/* $FreeBSD$ */
-
-#include <sys/ioccom.h>
-
-#define FM_SET_FREQ _IOWR('U', 200, int)
-#define FM_GET_FREQ _IOWR('U', 201, int)
-#define FM_START _IOWR('U', 202, int)
-#define FM_STOP _IOWR('U', 203, int)
-#define FM_GET_STAT _IOWR('U', 204, int)
diff --git a/sys/dev/usb2/include/usb2_cdc.h b/sys/dev/usb2/include/usb2_cdc.h
deleted file mode 100644
index d1e3dcb..0000000
--- a/sys/dev/usb2/include/usb2_cdc.h
+++ /dev/null
@@ -1,191 +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 _USB_CDC_H_
-#define _USB_CDC_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
-
-struct usb2_cdc_header_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uWord bcdCDC;
-} __packed;
-
-struct usb2_cdc_cm_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bmCapabilities;
-#define USB_CDC_CM_DOES_CM 0x01
-#define USB_CDC_CM_OVER_DATA 0x02
- uByte bDataInterface;
-} __packed;
-
-struct usb2_cdc_acm_descriptor {
- 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
-} __packed;
-
-struct usb2_cdc_union_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bMasterInterface;
- uByte bSlaveInterface[1];
-} __packed;
-
-struct usb2_cdc_ethernet_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte iMacAddress;
- uDWord bmEthernetStatistics;
- uWord wMaxSegmentSize;
- uWord wNumberMCFilters;
- uByte bNumberPowerFilters;
-} __packed;
-
-#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
-
-struct usb2_cdc_abstract_state {
- uWord wState;
-#define UCDC_IDLE_SETTING 0x0001
-#define UCDC_DATA_MULTIPLEXED 0x0002
-} __packed;
-
-#define UCDC_ABSTRACT_STATE_LENGTH 2
-
-struct usb2_cdc_line_state {
- 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;
-} __packed;
-
-#define UCDC_LINE_STATE_LENGTH 7
-
-struct usb2_cdc_notification {
- 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];
-} __packed;
-
-#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 /* _USB_CDC_H_ */
diff --git a/sys/dev/usb2/include/usb2_defs.h b/sys/dev/usb2/include/usb2_defs.h
deleted file mode 100644
index 64caf39..0000000
--- a/sys/dev/usb2/include/usb2_defs.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_DEFS_H_
-#define _USB2_DEFS_H_
-
-/* Definition of some USB constants */
-
-#define USB_BUS_MAX 256 /* units */
-#define USB_DEV_MAX 128 /* units */
-#define USB_IFACE_MAX 32 /* units */
-#define USB_EP_MAX (2*16) /* hardcoded */
-#define USB_FIFO_MAX (4 * USB_EP_MAX)
-
-#define USB_ROOT_HUB_ADDR 1 /* index */
-
-#define USB_MIN_DEVICES 2 /* unused + root HUB */
-
-#define USB_MAX_DEVICES USB_DEV_MAX /* including virtual root HUB and
- * address zero */
-#define USB_MAX_ENDPOINTS USB_EP_MAX /* 2 directions on 16 endpoints */
-
-#define USB_UNCONFIG_INDEX 0xFF /* internal use only */
-#define USB_IFACE_INDEX_ANY 0xFF /* internal use only */
-
-#define USB_START_ADDR 0 /* default USB device BUS address
- * after USB bus reset */
-
-#define USB_CONTROL_ENDPOINT 0 /* default control endpoint */
-
-#define USB_FRAMES_PER_SECOND_FS 1000 /* full speed */
-#define USB_FRAMES_PER_SECOND_HS 8000 /* high speed */
-
-#define USB_FS_BYTES_PER_HS_UFRAME 188 /* bytes */
-#define USB_HS_MICRO_FRAMES_MAX 8 /* units */
-
-/* sanity checks */
-
-#if (USB_FIFO_MAX < USB_EP_MAX)
-#error "There cannot be less FIFOs than USB endpoints."
-#endif
-#if (USB_FIFO_MAX & 1)
-#error "Number of FIFOs must be odd."
-#endif
-#if (USB_EP_MAX < (2*16))
-#error "Number of hardware USB endpoints cannot be less than 32."
-#endif
-#if (USB_MAX_DEVICES < USB_MIN_DEVICES)
-#error "Minimum number of devices is greater than maximum number of devices."
-#endif
-#if (USB_ROOT_HUB_ADDR >= USB_MIN_DEVICES)
-#error "The root hub address must be less than USB_MIN_DEVICES."
-#endif
-#endif /* _USB2_DEFS_H_ */
diff --git a/sys/dev/usb2/include/usb2_endian.h b/sys/dev/usb2/include/usb2_endian.h
deleted file mode 100644
index 2f49008..0000000
--- a/sys/dev/usb2/include/usb2_endian.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* $FreeBSD$ */
-/*
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_ENDIAN_H_
-#define _USB2_ENDIAN_H_
-
-#include <sys/stdint.h>
-#include <sys/endian.h>
-
-/*
- * Declare the basic USB record types. USB records have an alignment
- * of 1 byte and are always packed.
- */
-typedef uint8_t uByte;
-typedef uint8_t uWord[2];
-typedef uint8_t uDWord[4];
-typedef uint8_t uQWord[8];
-
-/*
- * Define a set of macros that can get and set data independent of
- * CPU endianness and CPU alignment requirements:
- */
-#define UGETB(w) \
- ((w)[0])
-
-#define UGETW(w) \
- ((w)[0] | \
- ((w)[1] << 8))
-
-#define UGETDW(w) \
- ((w)[0] | \
- ((w)[1] << 8) | \
- ((w)[2] << 16) | \
- ((w)[3] << 24))
-
-#define UGETQW(w) \
- ((w)[0] | \
- ((w)[1] << 8) | \
- ((w)[2] << 16) | \
- ((w)[3] << 24) | \
- (((uint64_t)((w)[4])) << 32) | \
- (((uint64_t)((w)[5])) << 40) | \
- (((uint64_t)((w)[6])) << 48) | \
- (((uint64_t)((w)[7])) << 56))
-
-#define USETB(w,v) do { \
- (w)[0] = (uint8_t)(v); \
-} while (0)
-
-#define USETW(w,v) do { \
- (w)[0] = (uint8_t)(v); \
- (w)[1] = (uint8_t)((v) >> 8); \
-} while (0)
-
-#define USETDW(w,v) do { \
- (w)[0] = (uint8_t)(v); \
- (w)[1] = (uint8_t)((v) >> 8); \
- (w)[2] = (uint8_t)((v) >> 16); \
- (w)[3] = (uint8_t)((v) >> 24); \
-} while (0)
-
-#define USETQW(w,v) do { \
- (w)[0] = (uint8_t)(v); \
- (w)[1] = (uint8_t)((v) >> 8); \
- (w)[2] = (uint8_t)((v) >> 16); \
- (w)[3] = (uint8_t)((v) >> 24); \
- (w)[4] = (uint8_t)((v) >> 32); \
- (w)[5] = (uint8_t)((v) >> 40); \
- (w)[6] = (uint8_t)((v) >> 48); \
- (w)[7] = (uint8_t)((v) >> 56); \
-} while (0)
-
-#define USETW2(w,b1,b0) do { \
- (w)[0] = (uint8_t)(b0); \
- (w)[1] = (uint8_t)(b1); \
-} while (0)
-
-#define USETW4(w,b3,b2,b1,b0) do { \
- (w)[0] = (uint8_t)(b0); \
- (w)[1] = (uint8_t)(b1); \
- (w)[2] = (uint8_t)(b2); \
- (w)[3] = (uint8_t)(b3); \
-} while (0)
-
-#define USETW8(w,b7,b6,b5,b4,b3,b2,b1,b0) do { \
- (w)[0] = (uint8_t)(b0); \
- (w)[1] = (uint8_t)(b1); \
- (w)[2] = (uint8_t)(b2); \
- (w)[3] = (uint8_t)(b3); \
- (w)[4] = (uint8_t)(b4); \
- (w)[5] = (uint8_t)(b5); \
- (w)[6] = (uint8_t)(b6); \
- (w)[7] = (uint8_t)(b7); \
-} while (0)
-
-#endif /* _USB2_ENDIAN_H_ */
diff --git a/sys/dev/usb2/include/usb2_error.h b/sys/dev/usb2/include/usb2_error.h
deleted file mode 100644
index 91f0245..0000000
--- a/sys/dev/usb2/include/usb2_error.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_ERROR_H_
-#define _USB2_ERROR_H_
-
-enum { /* keep in sync with usb_errstr_table */
- USB_ERR_NORMAL_COMPLETION = 0,
- USB_ERR_PENDING_REQUESTS, /* 1 */
- USB_ERR_NOT_STARTED, /* 2 */
- USB_ERR_INVAL, /* 3 */
- USB_ERR_NOMEM, /* 4 */
- USB_ERR_CANCELLED, /* 5 */
- USB_ERR_BAD_ADDRESS, /* 6 */
- USB_ERR_BAD_BUFSIZE, /* 7 */
- USB_ERR_BAD_FLAG, /* 8 */
- USB_ERR_NO_CALLBACK, /* 9 */
- USB_ERR_IN_USE, /* 10 */
- USB_ERR_NO_ADDR, /* 11 */
- USB_ERR_NO_PIPE, /* 12 */
- USB_ERR_ZERO_NFRAMES, /* 13 */
- USB_ERR_ZERO_MAXP, /* 14 */
- USB_ERR_SET_ADDR_FAILED, /* 15 */
- USB_ERR_NO_POWER, /* 16 */
- USB_ERR_TOO_DEEP, /* 17 */
- USB_ERR_IOERROR, /* 18 */
- USB_ERR_NOT_CONFIGURED, /* 19 */
- USB_ERR_TIMEOUT, /* 20 */
- USB_ERR_SHORT_XFER, /* 21 */
- USB_ERR_STALLED, /* 22 */
- USB_ERR_INTERRUPTED, /* 23 */
- USB_ERR_DMA_LOAD_FAILED, /* 24 */
- USB_ERR_BAD_CONTEXT, /* 25 */
- USB_ERR_NO_ROOT_HUB, /* 26 */
- USB_ERR_NO_INTR_THREAD, /* 27 */
- USB_ERR_NOT_LOCKED, /* 28 */
- USB_ERR_MAX
-};
-
-#endif /* _USB2_ERROR_H_ */
diff --git a/sys/dev/usb2/include/usb2_hid.h b/sys/dev/usb2/include/usb2_hid.h
deleted file mode 100644
index 1a8650e..0000000
--- a/sys/dev/usb2/include/usb2_hid.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
- * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
- * Copyright (c) 1998 Lennart Augustsson. 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.
- */
-
-#ifndef _USB2_HID_H_
-#define _USB2_HID_H_
-
-#include <dev/usb2/include/usb2_endian.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
-
-struct usb2_hid_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uWord bcdHID;
- uByte bCountryCode;
- uByte bNumDescriptors;
- struct {
- uByte bDescriptorType;
- uWord wDescriptorLength;
- } descrs[1];
-} __packed;
-
-#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 /* _USB2_HID_H_ */
diff --git a/sys/dev/usb2/include/usb2_ioctl.h b/sys/dev/usb2/include/usb2_ioctl.h
deleted file mode 100644
index 58c392a..0000000
--- a/sys/dev/usb2/include/usb2_ioctl.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
- * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
- * Copyright (c) 1998 Lennart Augustsson. 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.
- */
-
-#ifndef _USB2_IOCTL_H_
-#define _USB2_IOCTL_H_
-
-#include <sys/ioccom.h>
-
-/* Building "kdump" depends on these includes */
-
-#include <dev/usb2/include/usb2_endian.h>
-#include <dev/usb2/include/usb2_standard.h>
-
-#define USB_DEVICE_NAME "usb"
-#define USB_GENERIC_NAME "ugen"
-
-struct usb2_read_dir {
- void *urd_data;
- uint32_t urd_startentry;
- uint32_t urd_maxlen;
-};
-
-struct usb2_ctl_request {
- void *ucr_data;
- uint16_t ucr_flags;
-#define USB_USE_POLLING 0x0001 /* internal flag */
-#define USB_SHORT_XFER_OK 0x0004 /* allow short reads */
-#define USB_DELAY_STATUS_STAGE 0x0010 /* insert delay before STATUS stage */
-#define USB_USER_DATA_PTR 0x0020 /* internal flag */
- uint16_t ucr_actlen; /* actual length transferred */
- uint8_t ucr_addr; /* zero - currently not used */
- struct usb2_device_request ucr_request;
-};
-
-struct usb2_alt_interface {
- uint8_t uai_interface_index;
- uint8_t uai_alt_index;
-};
-
-struct usb2_gen_descriptor {
- void *ugd_data;
- uint16_t ugd_lang_id;
- uint16_t ugd_maxlen;
- uint16_t ugd_actlen;
- uint16_t ugd_offset;
- uint8_t ugd_config_index;
- uint8_t ugd_string_index;
- uint8_t ugd_iface_index;
- uint8_t ugd_altif_index;
- uint8_t ugd_endpt_index;
- uint8_t ugd_report_type;
- uint8_t reserved[8];
-};
-
-struct usb2_device_info {
- uint16_t udi_productNo;
- uint16_t udi_vendorNo;
- uint16_t udi_releaseNo;
- uint16_t udi_power; /* power consumption in mA, 0 if
- * selfpowered */
- uint8_t udi_bus;
- uint8_t udi_addr; /* device address */
- uint8_t udi_index; /* device index */
- uint8_t udi_class;
- uint8_t udi_subclass;
- uint8_t udi_protocol;
- uint8_t udi_config_no; /* current config number */
- uint8_t udi_config_index; /* current config index */
- uint8_t udi_speed; /* see "USB_SPEED_XXX" */
- uint8_t udi_mode; /* see "USB_MODE_XXX" */
- uint8_t udi_nports;
- uint8_t udi_hubaddr; /* parent HUB address */
- uint8_t udi_hubindex; /* parent HUB device index */
- uint8_t udi_hubport; /* parent HUB port */
- uint8_t udi_power_mode; /* see "USB_POWER_MODE_XXX" */
- uint8_t udi_suspended; /* set if device is suspended */
- uint8_t udi_reserved[16]; /* leave space for the future */
- char udi_product[128];
- char udi_vendor[128];
- char udi_serial[64];
- char udi_release[8];
-};
-
-struct usb2_device_stats {
- uint32_t uds_requests_ok[4]; /* Indexed by transfer type UE_XXX */
- uint32_t uds_requests_fail[4]; /* Indexed by transfer type UE_XXX */
-};
-
-struct usb2_fs_start {
- uint8_t ep_index;
-};
-
-struct usb2_fs_stop {
- uint8_t ep_index;
-};
-
-struct usb2_fs_complete {
- uint8_t ep_index;
-};
-
-/* This structure is used for all endpoint types */
-struct usb2_fs_endpoint {
- /*
- * NOTE: isochronous USB transfer only use one buffer, but can have
- * multiple frame lengths !
- */
- void **ppBuffer; /* pointer to userland buffers */
- uint32_t *pLength; /* pointer to frame lengths, updated
- * to actual length */
- uint32_t nFrames; /* number of frames */
- uint32_t aFrames; /* actual number of frames */
- uint16_t flags;
- /* a single short frame will terminate */
-#define USB_FS_FLAG_SINGLE_SHORT_OK 0x0001
- /* multiple short frames are allowed */
-#define USB_FS_FLAG_MULTI_SHORT_OK 0x0002
- /* all frame(s) transmitted are short terminated */
-#define USB_FS_FLAG_FORCE_SHORT 0x0004
- /* will do a clear-stall before xfer */
-#define USB_FS_FLAG_CLEAR_STALL 0x0008
- uint16_t timeout; /* in milliseconds */
- /* isocronous completion time in milliseconds - used for echo cancel */
- uint16_t isoc_time_complete;
- /* timeout value for no timeout */
-#define USB_FS_TIMEOUT_NONE 0
- uint8_t status; /* see USB_ERR_XXX */
-};
-
-struct usb2_fs_init {
- /* userland pointer to endpoints structure */
- struct usb2_fs_endpoint *pEndpoints;
- /* maximum number of endpoints */
- uint8_t ep_index_max;
-};
-
-struct usb2_fs_uninit {
- uint8_t dummy; /* zero */
-};
-
-struct usb2_fs_open {
-#define USB_FS_MAX_BUFSIZE (1 << 18)
- uint32_t max_bufsize;
-#define USB_FS_MAX_FRAMES (1 << 12)
- uint32_t max_frames;
- uint16_t max_packet_length; /* read only */
- uint8_t dev_index; /* currently unused */
- uint8_t ep_index;
- uint8_t ep_no; /* bEndpointNumber */
-};
-
-struct usb2_fs_close {
- uint8_t ep_index;
-};
-
-struct usb2_fs_clear_stall_sync {
- uint8_t ep_index;
-};
-
-struct usb2_dev_perm {
- /* Access information */
- uint32_t user_id;
- uint32_t group_id;
- uint16_t mode;
-
- /* Device location */
- uint16_t bus_index;
- uint16_t dev_index;
- uint16_t iface_index;
-};
-
-struct usb2_gen_quirk {
- uint16_t index; /* Quirk Index */
- uint16_t vid; /* Vendor ID */
- uint16_t pid; /* Product ID */
- uint16_t bcdDeviceLow; /* Low Device Revision */
- uint16_t bcdDeviceHigh; /* High Device Revision */
- uint16_t reserved[2];
- /*
- * String version of quirk including terminating zero. See UQ_XXX in
- * "usb2_quirk.h".
- */
- char quirkname[64 - 14];
-};
-
-/* USB controller */
-#define USB_REQUEST _IOWR('U', 1, struct usb2_ctl_request)
-#define USB_SETDEBUG _IOW ('U', 2, int)
-#define USB_DISCOVER _IO ('U', 3)
-#define USB_DEVICEINFO _IOWR('U', 4, struct usb2_device_info)
-#define USB_DEVICESTATS _IOR ('U', 5, struct usb2_device_stats)
-#define USB_DEVICEENUMERATE _IOW ('U', 6, int)
-
-/* Generic HID device */
-#define USB_GET_REPORT_DESC _IOWR('U', 21, struct usb2_gen_descriptor)
-#define USB_SET_IMMED _IOW ('U', 22, int)
-#define USB_GET_REPORT _IOWR('U', 23, struct usb2_gen_descriptor)
-#define USB_SET_REPORT _IOW ('U', 24, struct usb2_gen_descriptor)
-#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 usb2_alt_interface)
-#define USB_SET_ALTINTERFACE _IOWR('U', 103, struct usb2_alt_interface)
-#define USB_GET_DEVICE_DESC _IOR ('U', 105, struct usb2_device_descriptor)
-#define USB_GET_CONFIG_DESC _IOR ('U', 106, struct usb2_config_descriptor)
-#define USB_GET_RX_INTERFACE_DESC _IOR ('U', 107, struct usb2_interface_descriptor)
-#define USB_GET_RX_ENDPOINT_DESC _IOR ('U', 108, struct usb2_endpoint_descriptor)
-#define USB_GET_FULL_DESC _IOWR('U', 109, struct usb2_gen_descriptor)
-#define USB_GET_STRING_DESC _IOWR('U', 110, struct usb2_gen_descriptor)
-#define USB_DO_REQUEST _IOWR('U', 111, struct usb2_ctl_request)
-#define USB_GET_DEVICEINFO _IOR ('U', 112, struct usb2_device_info)
-#define USB_SET_RX_SHORT_XFER _IOW ('U', 113, int)
-#define USB_SET_RX_TIMEOUT _IOW ('U', 114, int)
-#define USB_GET_RX_FRAME_SIZE _IOR ('U', 115, int)
-#define USB_GET_RX_BUFFER_SIZE _IOR ('U', 117, int)
-#define USB_SET_RX_BUFFER_SIZE _IOW ('U', 118, int)
-#define USB_SET_RX_STALL_FLAG _IOW ('U', 119, int)
-#define USB_SET_TX_STALL_FLAG _IOW ('U', 120, int)
-#define USB_GET_IFACE_DRIVER _IOWR('U', 121, struct usb2_gen_descriptor)
-#define USB_CLAIM_INTERFACE _IOW ('U', 122, int)
-#define USB_RELEASE_INTERFACE _IOW ('U', 123, int)
-#define USB_IFACE_DRIVER_ACTIVE _IOW ('U', 124, int)
-#define USB_IFACE_DRIVER_DETACH _IOW ('U', 125, int)
-#define USB_GET_PLUGTIME _IOR ('U', 126, uint32_t)
-#define USB_READ_DIR _IOW ('U', 127, struct usb2_read_dir)
-#define USB_SET_ROOT_PERM _IOW ('U', 128, struct usb2_dev_perm)
-#define USB_SET_BUS_PERM _IOW ('U', 129, struct usb2_dev_perm)
-#define USB_SET_DEVICE_PERM _IOW ('U', 130, struct usb2_dev_perm)
-#define USB_SET_IFACE_PERM _IOW ('U', 131, struct usb2_dev_perm)
-#define USB_GET_ROOT_PERM _IOWR('U', 132, struct usb2_dev_perm)
-#define USB_GET_BUS_PERM _IOWR('U', 133, struct usb2_dev_perm)
-#define USB_GET_DEVICE_PERM _IOWR('U', 134, struct usb2_dev_perm)
-#define USB_GET_IFACE_PERM _IOWR('U', 135, struct usb2_dev_perm)
-#define USB_SET_TX_FORCE_SHORT _IOW ('U', 136, int)
-#define USB_SET_TX_TIMEOUT _IOW ('U', 137, int)
-#define USB_GET_TX_FRAME_SIZE _IOR ('U', 138, int)
-#define USB_GET_TX_BUFFER_SIZE _IOR ('U', 139, int)
-#define USB_SET_TX_BUFFER_SIZE _IOW ('U', 140, int)
-#define USB_GET_TX_INTERFACE_DESC _IOR ('U', 141, struct usb2_interface_descriptor)
-#define USB_GET_TX_ENDPOINT_DESC _IOR ('U', 142, struct usb2_endpoint_descriptor)
-#define USB_SET_PORT_ENABLE _IOW ('U', 143, int)
-#define USB_SET_PORT_DISABLE _IOW ('U', 144, int)
-#define USB_SET_POWER_MODE _IOW ('U', 145, int)
-#define USB_GET_POWER_MODE _IOR ('U', 146, int)
-
-/* Modem device */
-#define USB_GET_CM_OVER_DATA _IOR ('U', 180, int)
-#define USB_SET_CM_OVER_DATA _IOW ('U', 181, int)
-
-/* USB file system interface */
-#define USB_FS_START _IOW ('U', 192, struct usb2_fs_start)
-#define USB_FS_STOP _IOW ('U', 193, struct usb2_fs_stop)
-#define USB_FS_COMPLETE _IOR ('U', 194, struct usb2_fs_complete)
-#define USB_FS_INIT _IOW ('U', 195, struct usb2_fs_init)
-#define USB_FS_UNINIT _IOW ('U', 196, struct usb2_fs_uninit)
-#define USB_FS_OPEN _IOWR('U', 197, struct usb2_fs_open)
-#define USB_FS_CLOSE _IOW ('U', 198, struct usb2_fs_close)
-#define USB_FS_CLEAR_STALL_SYNC _IOW ('U', 199, struct usb2_fs_clear_stall_sync)
-
-/* USB quirk system interface */
-#define USB_DEV_QUIRK_GET _IOWR('Q', 0, struct usb2_gen_quirk)
-#define USB_QUIRK_NAME_GET _IOWR('Q', 1, struct usb2_gen_quirk)
-#define USB_DEV_QUIRK_ADD _IOW ('Q', 2, struct usb2_gen_quirk)
-#define USB_DEV_QUIRK_REMOVE _IOW ('Q', 3, struct usb2_gen_quirk)
-
-#endif /* _USB2_IOCTL_H_ */
diff --git a/sys/dev/usb2/include/usb2_mfunc.h b/sys/dev/usb2/include/usb2_mfunc.h
deleted file mode 100644
index 0fad203..0000000
--- a/sys/dev/usb2/include/usb2_mfunc.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 file contains various macro functions. */
-
-#ifndef _USB2_MFUNC_H_
-#define _USB2_MFUNC_H_
-
-#define USB_LOG2(n) ( \
-((x) <= (1<<0x00)) ? 0x00 : \
-((x) <= (1<<0x01)) ? 0x01 : \
-((x) <= (1<<0x02)) ? 0x02 : \
-((x) <= (1<<0x03)) ? 0x03 : \
-((x) <= (1<<0x04)) ? 0x04 : \
-((x) <= (1<<0x05)) ? 0x05 : \
-((x) <= (1<<0x06)) ? 0x06 : \
-((x) <= (1<<0x07)) ? 0x07 : \
-((x) <= (1<<0x08)) ? 0x08 : \
-((x) <= (1<<0x09)) ? 0x09 : \
-((x) <= (1<<0x0A)) ? 0x0A : \
-((x) <= (1<<0x0B)) ? 0x0B : \
-((x) <= (1<<0x0C)) ? 0x0C : \
-((x) <= (1<<0x0D)) ? 0x0D : \
-((x) <= (1<<0x0E)) ? 0x0E : \
-((x) <= (1<<0x0F)) ? 0x0F : \
-((x) <= (1<<0x10)) ? 0x10 : \
-((x) <= (1<<0x11)) ? 0x11 : \
-((x) <= (1<<0x12)) ? 0x12 : \
-((x) <= (1<<0x13)) ? 0x13 : \
-((x) <= (1<<0x14)) ? 0x14 : \
-((x) <= (1<<0x15)) ? 0x15 : \
-((x) <= (1<<0x16)) ? 0x16 : \
-((x) <= (1<<0x17)) ? 0x17 : \
-((x) <= (1<<0x18)) ? 0x18 : \
-((x) <= (1<<0x19)) ? 0x19 : \
-((x) <= (1<<0x1A)) ? 0x1A : \
-((x) <= (1<<0x1B)) ? 0x1B : \
-((x) <= (1<<0x1C)) ? 0x1C : \
-((x) <= (1<<0x1D)) ? 0x1D : \
-((x) <= (1<<0x1E)) ? 0x1E : \
-0x1F)
-
-
-/* helper for converting pointers to integers */
-#define USB_P2U(ptr) \
- (((const uint8_t *)(ptr)) - ((const uint8_t *)0))
-
-/* helper for computing offsets */
-#define USB_ADD_BYTES(ptr,size) \
- ((void *)(USB_P2U(ptr) + (size)))
-
-/* debug macro */
-#define USB_ASSERT KASSERT
-
-#endif /* _USB2_MFUNC_H_ */
diff --git a/sys/dev/usb2/include/usb2_revision.h b/sys/dev/usb2/include/usb2_revision.h
deleted file mode 100644
index 06d1b21..0000000
--- a/sys/dev/usb2/include/usb2_revision.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_REVISION_H_
-#define _USB2_REVISION_H_
-
-/*
- * The "USB_SPEED" macro defines all the supported USB speeds.
- */
-enum {
- USB_SPEED_VARIABLE,
- USB_SPEED_LOW,
- USB_SPEED_FULL,
- USB_SPEED_HIGH,
- USB_SPEED_SUPER,
- USB_SPEED_MAX
-};
-
-/*
- * The "USB_REV" macro defines all the supported USB revisions.
- */
-enum {
- USB_REV_UNKNOWN,
- USB_REV_PRE_1_0,
- USB_REV_1_0,
- USB_REV_1_1,
- USB_REV_2_0,
- USB_REV_2_5,
- USB_REV_3_0,
- USB_REV_MAX
-};
-
-/*
- * The "USB_MODE" macro defines all the supported USB modes.
- */
-enum {
- USB_MODE_HOST,
- USB_MODE_DEVICE,
- USB_MODE_MAX
-};
-
-#endif /* _USB2_REVISION_H_ */
diff --git a/sys/dev/usb2/include/usb2_standard.h b/sys/dev/usb2/include/usb2_standard.h
deleted file mode 100644
index f81f346..0000000
--- a/sys/dev/usb2/include/usb2_standard.h
+++ /dev/null
@@ -1,619 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
- * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
- * Copyright (c) 1998 Lennart Augustsson. 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 file contains standard definitions for the following USB
- * protocol versions:
- *
- * USB v1.0
- * USB v1.1
- * USB v2.0
- * USB v3.0
- */
-
-#ifndef _USB2_STANDARD_H_
-#define _USB2_STANDARD_H_
-
-#include <dev/usb2/include/usb2_endian.h>
-
-/*
- * Minimum time a device needs to be powered down to go through a
- * power cycle. These values are not in the USB specification.
- */
-#define USB_POWER_DOWN_TIME 200 /* ms */
-#define USB_PORT_POWER_DOWN_TIME 100 /* ms */
-
-/* Definition of software USB power modes */
-#define USB_POWER_MODE_OFF 0 /* turn off device */
-#define USB_POWER_MODE_ON 1 /* always on */
-#define USB_POWER_MODE_SAVE 2 /* automatic suspend and resume */
-#define USB_POWER_MODE_SUSPEND 3 /* force suspend */
-#define USB_POWER_MODE_RESUME 4 /* force resume */
-
-#if 0
-/* These are the values from the USB specification. */
-#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_PORT_RESUME_DELAY 20 /* 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 and 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_PORT_RESUME_DELAY (20*2) /* 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 */
-
-/*
- * USB record layout in memory:
- *
- * - USB config 0
- * - USB interfaces
- * - USB alternative interfaces
- * - USB pipes
- *
- * - USB config 1
- * - USB interfaces
- * - USB alternative interfaces
- * - USB pipes
- */
-
-/* Declaration of USB records */
-
-struct usb2_device_request {
- uByte bmRequestType;
- uByte bRequest;
- uWord wValue;
- uWord wIndex;
- uWord wLength;
-} __packed;
-
-#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 USB_LANGUAGE_TABLE 0x00 /* language ID string index */
-#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_DEBUG 0x0A
-#define UDESC_IFACE_ASSOC 0x0B /* interface association */
-#define UDESC_BOS 0x0F /* binary object store */
-#define UDESC_DEVICE_CAPABILITY 0x10
-#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 UDESC_ENDPOINT_SS_COMP 0x30 /* super speed */
-#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
-#define UR_SET_SEL 0x30
-#define UR_ISOCH_DELAY 0x31
-
-/* 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
-#define UR_SET_HUB_DEPTH 0x0c
-#define UR_GET_PORT_ERR_COUNT 0x0d
-
-/* Feature numbers */
-#define UF_ENDPOINT_HALT 0
-#define UF_DEVICE_REMOTE_WAKEUP 1
-#define UF_TEST_MODE 2
-#define UF_U1_ENABLE 0x30
-#define UF_U2_ENABLE 0x31
-#define UF_LTM_ENABLE 0x32
-
-/* HUB specific 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_LINK_STATE 5
-#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
-
-/* SuperSpeed HUB specific features */
-#define UHF_PORT_U1_TIMEOUT 23
-#define UHF_PORT_U2_TIMEOUT 24
-#define UHF_C_PORT_LINK_STATE 25
-#define UHF_C_PORT_CONFIG_ERROR 26
-#define UHF_PORT_REMOTE_WAKE_MASK 27
-#define UHF_BH_PORT_RESET 28
-#define UHF_C_BH_PORT_RESET 29
-#define UHF_FORCE_LINKPM_ACCEPT 30
-
-struct usb2_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
-} __packed;
-
-struct usb2_device_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uWord bcdUSB;
-#define UD_USB_2_0 0x0200
-#define UD_USB_3_0 0x0300
-#define UD_IS_USB2(d) ((d)->bcdUSB[1] == 0x02)
-#define UD_IS_USB3(d) ((d)->bcdUSB[1] == 0x03)
- 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;
-} __packed;
-
-/* Binary Device Object Store (BOS) */
-struct usb2_bos_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uWord wTotalLength;
- uByte bNumDeviceCaps;
-} __packed;
-
-/* Binary Device Object Store Capability */
-struct usb2_bos_cap_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDevCapabilityType;
-#define USB_DEVCAP_RESERVED 0x00
-#define USB_DEVCAP_WUSB 0x01
-#define USB_DEVCAP_USB2EXT 0x02
-#define USB_DEVCAP_SUPER_SPEED 0x03
-#define USB_DEVCAP_CONTAINER_ID 0x04
- /* data ... */
-} __packed;
-
-struct usb2_devcap_usb2ext_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDevCapabilityType;
- uByte bmAttributes;
-#define USB_V2EXT_LPM 0x02
-} __packed;
-
-struct usb2_devcap_ss_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDevCapabilityType;
- uByte bmAttributes;
- uWord wSpeedsSupported;
- uByte bFunctionaltySupport;
- uByte bU1DevExitLat;
- uByte bU2DevExitLat;
-} __packed;
-
-struct usb2_devcap_container_id_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDevCapabilityType;
- uByte bReserved;
- uByte ContainerID;
-} __packed;
-
-/* 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
-
-struct usb2_config_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uWord wTotalLength;
- uByte bNumInterface;
- uByte bConfigurationValue;
-#define USB_UNCONFIG_NO 0
- 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
-} __packed;
-
-struct usb2_interface_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bInterfaceNumber;
- uByte bAlternateSetting;
- uByte bNumEndpoints;
- uByte bInterfaceClass;
- uByte bInterfaceSubClass;
- uByte bInterfaceProtocol;
- uByte iInterface;
-} __packed;
-
-struct usb2_interface_assoc_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bFirstInterface;
- uByte bInterfaceCount;
- uByte bFunctionClass;
- uByte bFunctionSubClass;
- uByte bFunctionProtocol;
- uByte iFunction;
-} __packed;
-
-/* Interface class codes */
-#define UICLASS_UNSPEC 0x00
-#define UICLASS_AUDIO 0x01 /* audio */
-#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 UISUBCLASS_WIRELESS_HANDSET_CM 8
-#define UISUBCLASS_DEVICE_MGMT 9
-#define UISUBCLASS_MOBILE_DIRECT_LINE_MODEL 10
-#define UISUBCLASS_OBEX 11
-#define UISUBCLASS_ETHERNET_EMULATION_MODEL 12
-
-#define UIPROTO_CDC_AT 1
-#define UIPROTO_CDC_ETH_512X4 0x76 /* FreeBSD specific */
-
-#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 UISUBCLASS_SIC 1 /* still image class */
-#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
-
-struct usb2_endpoint_descriptor {
- 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_DIR_ANY 0xff /* for internal use only! */
-#define UE_ADDR 0x0f
-#define UE_ADDR_ANY 0xff /* for internal use only! */
-#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_BULK_INTR 0xfe /* for internal use only! */
-#define UE_TYPE_ANY 0xff /* for internal use only! */
-#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_ZERO_MPS 0xFFFF /* for internal use only */
- uByte bInterval;
-} __packed;
-
-struct usb2_endpoint_ss_comp_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uWord bMaxBurst;
- uByte bmAttributes;
- uWord wBytesPerInterval;
-} __packed;
-
-struct usb2_string_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uWord bString[126];
- uByte bUnused;
-} __packed;
-
-#define USB_MAKE_STRING_DESC(m,name) \
-struct name { \
- uByte bLength; \
- uByte bDescriptorType; \
- uByte bData[sizeof((uint8_t []){m})]; \
-} __packed; \
-static const struct name name = { \
- .bLength = sizeof(struct name), \
- .bDescriptorType = UDESC_STRING, \
- .bData = { m }, \
-}
-
-struct usb2_hub_descriptor {
- 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)
- uByte PortPowerCtrlMask[1]; /* deprecated */
-} __packed;
-
-struct usb2_hub_ss_descriptor {
- uByte bDescLength;
- uByte bDescriptorType;
- uByte bNbrPorts; /* max 15 */
- uWord wHubCharacteristics;
- uByte bPwrOn2PwrGood; /* delay in 2 ms units */
- uByte bHubContrCurrent;
- uByte bHubHdrDecLat;
- uWord wHubDelay;
- uByte DeviceRemovable[2]; /* max 15 ports */
-} __packed;
-
-/* minimum HUB descriptor (8-ports maximum) */
-struct usb2_hub_descriptor_min {
- uByte bDescLength;
- uByte bDescriptorType;
- uByte bNbrPorts;
- uWord wHubCharacteristics;
- uByte bPwrOn2PwrGood;
- uByte bHubContrCurrent;
- uByte DeviceRemovable[1];
- uByte PortPowerCtrlMask[1];
-} __packed;
-
-struct usb2_device_qualifier {
- uByte bLength;
- uByte bDescriptorType;
- uWord bcdUSB;
- uByte bDeviceClass;
- uByte bDeviceSubClass;
- uByte bDeviceProtocol;
- uByte bMaxPacketSize0;
- uByte bNumConfigurations;
- uByte bReserved;
-} __packed;
-
-struct usb2_otg_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bmAttributes;
-#define UOTG_SRP 0x01
-#define UOTG_HNP 0x02
-} __packed;
-
-/* OTG feature selectors */
-#define UOTG_B_HNP_ENABLE 3
-#define UOTG_A_HNP_SUPPORT 4
-#define UOTG_A_ALT_HNP_SUPPORT 5
-
-struct usb2_status {
- uWord wStatus;
-/* Device status flags */
-#define UDS_SELF_POWERED 0x0001
-#define UDS_REMOTE_WAKEUP 0x0002
-/* Endpoint status flags */
-#define UES_HALT 0x0001
-} __packed;
-
-struct usb2_hub_status {
- uWord wHubStatus;
-#define UHS_LOCAL_POWER 0x0001
-#define UHS_OVER_CURRENT 0x0002
- uWord wHubChange;
-} __packed;
-
-struct usb2_port_status {
- 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
-#define UPS_PORT_MODE_DEVICE 0x8000 /* currently FreeBSD specific */
- 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
-} __packed;
-
-#endif /* _USB2_STANDARD_H_ */
diff --git a/sys/dev/usb2/input/uhid2.c b/sys/dev/usb2/input/uhid2.c
deleted file mode 100644
index 84eb49c..0000000
--- a/sys/dev/usb2/input/uhid2.c
+++ /dev/null
@@ -1,791 +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
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_hid.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-
-#define USB_DEBUG_VAR uhid_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-#include <dev/usb2/core/usb2_dev.h>
-#include <dev/usb2/core/usb2_hid.h>
-
-#include <dev/usb2/input/usb2_input.h>
-#include <dev/usb2/input/usb2_rdesc.h>
-
-#include <dev/usb2/quirk/usb2_quirk.h>
-
-#if USB_DEBUG
-static int uhid_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uhid, CTLFLAG_RW, 0, "USB uhid");
-SYSCTL_INT(_hw_usb2_uhid, OID_AUTO, debug, CTLFLAG_RW,
- &uhid_debug, 0, "Debug level");
-#endif
-
-#define UHID_BSIZE 1024 /* bytes, buffer size */
-#define UHID_FRAME_NUM 50 /* bytes, frame number */
-
-enum {
- UHID_INTR_DT_RD,
- UHID_CTRL_DT_WR,
- UHID_CTRL_DT_RD,
- UHID_N_TRANSFER,
-};
-
-struct uhid_softc {
- struct usb2_fifo_sc sc_fifo;
- struct mtx sc_mtx;
-
- struct usb2_xfer *sc_xfer[UHID_N_TRANSFER];
- struct usb2_device *sc_udev;
- void *sc_repdesc_ptr;
-
- uint32_t sc_isize;
- uint32_t sc_osize;
- uint32_t sc_fsize;
-
- uint16_t sc_repdesc_size;
-
- uint8_t sc_iface_no;
- uint8_t sc_iface_index;
- uint8_t sc_iid;
- uint8_t sc_oid;
- uint8_t sc_fid;
- uint8_t sc_flags;
-#define UHID_FLAG_IMMED 0x01 /* set if read should be immediate */
-#define UHID_FLAG_STATIC_DESC 0x04 /* set if report descriptors are
- * static */
-};
-
-static const uint8_t uhid_xb360gp_report_descr[] = {UHID_XB360GP_REPORT_DESCR()};
-static const uint8_t uhid_graphire_report_descr[] = {UHID_GRAPHIRE_REPORT_DESCR()};
-static const uint8_t uhid_graphire3_4x5_report_descr[] = {UHID_GRAPHIRE3_4X5_REPORT_DESCR()};
-
-/* prototypes */
-
-static device_probe_t uhid_probe;
-static device_attach_t uhid_attach;
-static device_detach_t uhid_detach;
-
-static usb2_callback_t uhid_intr_callback;
-static usb2_callback_t uhid_write_callback;
-static usb2_callback_t uhid_read_callback;
-
-static usb2_fifo_cmd_t uhid_start_read;
-static usb2_fifo_cmd_t uhid_stop_read;
-static usb2_fifo_cmd_t uhid_start_write;
-static usb2_fifo_cmd_t uhid_stop_write;
-static usb2_fifo_open_t uhid_open;
-static usb2_fifo_close_t uhid_close;
-static usb2_fifo_ioctl_t uhid_ioctl;
-
-static struct usb2_fifo_methods uhid_fifo_methods = {
- .f_open = &uhid_open,
- .f_close = &uhid_close,
- .f_ioctl = &uhid_ioctl,
- .f_start_read = &uhid_start_read,
- .f_stop_read = &uhid_stop_read,
- .f_start_write = &uhid_start_write,
- .f_stop_write = &uhid_stop_write,
- .basename[0] = "uhid",
-};
-
-static void
-uhid_intr_callback(struct usb2_xfer *xfer)
-{
- struct uhid_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTF("transferred!\n");
-
- if (xfer->actlen >= sc->sc_isize) {
- usb2_fifo_put_data(
- sc->sc_fifo.fp[USB_FIFO_RX],
- xfer->frbuffers,
- 0, sc->sc_isize, 1);
- } else {
- /* ignore it */
- DPRINTF("ignored short transfer, "
- "%d bytes\n", xfer->actlen);
- }
-
- case USB_ST_SETUP:
-re_submit:
- if (usb2_fifo_put_bytes_max(
- sc->sc_fifo.fp[USB_FIFO_RX]) != 0) {
- xfer->frlengths[0] = sc->sc_isize;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto re_submit;
- }
- return;
- }
-}
-
-static void
-uhid_fill_set_report(struct usb2_device_request *req, uint8_t iface_no,
- uint8_t type, uint8_t id, uint16_t size)
-{
- req->bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req->bRequest = UR_SET_REPORT;
- USETW2(req->wValue, type, id);
- req->wIndex[0] = iface_no;
- req->wIndex[1] = 0;
- USETW(req->wLength, size);
-}
-
-static void
-uhid_fill_get_report(struct usb2_device_request *req, uint8_t iface_no,
- uint8_t type, uint8_t id, uint16_t size)
-{
- req->bmRequestType = UT_READ_CLASS_INTERFACE;
- req->bRequest = UR_GET_REPORT;
- USETW2(req->wValue, type, id);
- req->wIndex[0] = iface_no;
- req->wIndex[1] = 0;
- USETW(req->wLength, size);
-}
-
-static void
-uhid_write_callback(struct usb2_xfer *xfer)
-{
- struct uhid_softc *sc = xfer->priv_sc;
- struct usb2_device_request req;
- uint32_t size = sc->sc_osize;
- uint32_t actlen;
- uint8_t id;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- case USB_ST_SETUP:
- /* try to extract the ID byte */
- if (sc->sc_oid) {
-
- if (usb2_fifo_get_data(
- sc->sc_fifo.fp[USB_FIFO_TX],
- xfer->frbuffers,
- 0, 1, &actlen, 0)) {
- if (actlen != 1) {
- goto tr_error;
- }
- usb2_copy_out(xfer->frbuffers, 0, &id, 1);
-
- } else {
- return;
- }
- if (size) {
- size--;
- }
- } else {
- id = 0;
- }
-
- if (usb2_fifo_get_data(
- sc->sc_fifo.fp[USB_FIFO_TX],
- xfer->frbuffers + 1,
- 0, UHID_BSIZE, &actlen, 1)) {
- if (actlen != size) {
- goto tr_error;
- }
- uhid_fill_set_report
- (&req, sc->sc_iface_no,
- UHID_OUTPUT_REPORT, id, size);
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
-
- xfer->frlengths[0] = sizeof(req);
- xfer->frlengths[1] = size;
- xfer->nframes = xfer->frlengths[1] ? 2 : 1;
- usb2_start_hardware(xfer);
- }
- return;
-
- default:
-tr_error:
- /* bomb out */
- usb2_fifo_get_data_error(sc->sc_fifo.fp[USB_FIFO_TX]);
- return;
- }
-}
-
-static void
-uhid_read_callback(struct usb2_xfer *xfer)
-{
- struct uhid_softc *sc = xfer->priv_sc;
- struct usb2_device_request req;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_fifo_put_data(sc->sc_fifo.fp[USB_FIFO_RX], xfer->frbuffers,
- sizeof(req), sc->sc_isize, 1);
- return;
-
- case USB_ST_SETUP:
-
- if (usb2_fifo_put_bytes_max(sc->sc_fifo.fp[USB_FIFO_RX]) > 0) {
-
- uhid_fill_get_report
- (&req, sc->sc_iface_no, UHID_INPUT_REPORT,
- sc->sc_iid, sc->sc_isize);
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
-
- xfer->frlengths[0] = sizeof(req);
- xfer->frlengths[1] = sc->sc_isize;
- xfer->nframes = xfer->frlengths[1] ? 2 : 1;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- /* bomb out */
- usb2_fifo_put_data_error(sc->sc_fifo.fp[USB_FIFO_RX]);
- return;
- }
-}
-
-static const struct usb2_config uhid_config[UHID_N_TRANSFER] = {
-
- [UHID_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = UHID_BSIZE,
- .mh.callback = &uhid_intr_callback,
- },
-
- [UHID_CTRL_DT_WR] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request) + UHID_BSIZE,
- .mh.callback = &uhid_write_callback,
- .mh.timeout = 1000, /* 1 second */
- },
-
- [UHID_CTRL_DT_RD] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request) + UHID_BSIZE,
- .mh.callback = &uhid_read_callback,
- .mh.timeout = 1000, /* 1 second */
- },
-};
-
-static void
-uhid_start_read(struct usb2_fifo *fifo)
-{
- struct uhid_softc *sc = fifo->priv_sc0;
-
- if (sc->sc_flags & UHID_FLAG_IMMED) {
- usb2_transfer_start(sc->sc_xfer[UHID_CTRL_DT_RD]);
- } else {
- usb2_transfer_start(sc->sc_xfer[UHID_INTR_DT_RD]);
- }
-}
-
-static void
-uhid_stop_read(struct usb2_fifo *fifo)
-{
- struct uhid_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_stop(sc->sc_xfer[UHID_CTRL_DT_RD]);
- usb2_transfer_stop(sc->sc_xfer[UHID_INTR_DT_RD]);
-}
-
-static void
-uhid_start_write(struct usb2_fifo *fifo)
-{
- struct uhid_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_start(sc->sc_xfer[UHID_CTRL_DT_WR]);
-}
-
-static void
-uhid_stop_write(struct usb2_fifo *fifo)
-{
- struct uhid_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_stop(sc->sc_xfer[UHID_CTRL_DT_WR]);
-}
-
-static int
-uhid_get_report(struct uhid_softc *sc, uint8_t type,
- uint8_t id, void *kern_data, void *user_data,
- uint16_t len)
-{
- int err;
- uint8_t free_data = 0;
-
- if (kern_data == NULL) {
- kern_data = malloc(len, M_USBDEV, M_WAITOK);
- if (kern_data == NULL) {
- err = ENOMEM;
- goto done;
- }
- free_data = 1;
- }
- err = usb2_req_get_report(sc->sc_udev, NULL, kern_data,
- len, sc->sc_iface_index, type, id);
- if (err) {
- err = ENXIO;
- goto done;
- }
- if (user_data) {
- /* dummy buffer */
- err = copyout(kern_data, user_data, len);
- if (err) {
- goto done;
- }
- }
-done:
- if (free_data) {
- free(kern_data, M_USBDEV);
- }
- return (err);
-}
-
-static int
-uhid_set_report(struct uhid_softc *sc, uint8_t type,
- uint8_t id, void *kern_data, void *user_data,
- uint16_t len)
-{
- int err;
- uint8_t free_data = 0;
-
- if (kern_data == NULL) {
- kern_data = malloc(len, M_USBDEV, M_WAITOK);
- if (kern_data == NULL) {
- err = ENOMEM;
- goto done;
- }
- free_data = 1;
- err = copyin(user_data, kern_data, len);
- if (err) {
- goto done;
- }
- }
- err = usb2_req_set_report(sc->sc_udev, NULL, kern_data,
- len, sc->sc_iface_index, type, id);
- if (err) {
- err = ENXIO;
- goto done;
- }
-done:
- if (free_data) {
- free(kern_data, M_USBDEV);
- }
- return (err);
-}
-
-static int
-uhid_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- struct uhid_softc *sc = fifo->priv_sc0;
-
- /*
- * The buffers are one byte larger than maximum so that one
- * can detect too large read/writes and short transfers:
- */
- if (fflags & FREAD) {
- /* reset flags */
- sc->sc_flags &= ~UHID_FLAG_IMMED;
-
- if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_isize + 1, UHID_FRAME_NUM)) {
- return (ENOMEM);
- }
- }
- if (fflags & FWRITE) {
- if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_osize + 1, UHID_FRAME_NUM)) {
- return (ENOMEM);
- }
- }
- return (0);
-}
-
-static void
-uhid_close(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- if (fflags & (FREAD | FWRITE)) {
- usb2_fifo_free_buffer(fifo);
- }
-}
-
-static int
-uhid_ioctl(struct usb2_fifo *fifo, u_long cmd, void *addr,
- int fflags, struct thread *td)
-{
- struct uhid_softc *sc = fifo->priv_sc0;
- struct usb2_gen_descriptor *ugd;
- uint32_t size;
- int error = 0;
- uint8_t id;
-
- switch (cmd) {
- case USB_GET_REPORT_DESC:
- ugd = addr;
- if (sc->sc_repdesc_size > ugd->ugd_maxlen) {
- size = ugd->ugd_maxlen;
- } else {
- size = sc->sc_repdesc_size;
- }
- ugd->ugd_actlen = size;
- if (ugd->ugd_data == NULL)
- break; /* descriptor length only */
- error = copyout(sc->sc_repdesc_ptr, ugd->ugd_data, size);
- break;
-
- case USB_SET_IMMED:
- if (!(fflags & FREAD)) {
- error = EPERM;
- break;
- }
- if (*(int *)addr) {
-
- /* do a test read */
-
- error = uhid_get_report(sc, UHID_INPUT_REPORT,
- sc->sc_iid, NULL, NULL, sc->sc_isize);
- if (error) {
- break;
- }
- mtx_lock(&sc->sc_mtx);
- sc->sc_flags |= UHID_FLAG_IMMED;
- mtx_unlock(&sc->sc_mtx);
- } else {
- mtx_lock(&sc->sc_mtx);
- sc->sc_flags &= ~UHID_FLAG_IMMED;
- mtx_unlock(&sc->sc_mtx);
- }
- break;
-
- case USB_GET_REPORT:
- if (!(fflags & FREAD)) {
- error = EPERM;
- break;
- }
- ugd = addr;
- switch (ugd->ugd_report_type) {
- 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);
- }
- error = uhid_get_report(sc, ugd->ugd_report_type, id,
- NULL, ugd->ugd_data, size);
- break;
-
- case USB_SET_REPORT:
- if (!(fflags & FWRITE)) {
- error = EPERM;
- break;
- }
- ugd = addr;
- switch (ugd->ugd_report_type) {
- 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);
- }
- error = uhid_set_report(sc, ugd->ugd_report_type, id,
- NULL, ugd->ugd_data, size);
- break;
-
- case USB_GET_REPORT_ID:
- *(int *)addr = 0; /* XXX: we only support reportid 0? */
- break;
-
- default:
- error = EINVAL;
- break;
- }
- return (error);
-}
-
-static int
-uhid_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- DPRINTFN(11, "\n");
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->use_generic == 0) {
- /* give Mouse and Keyboard drivers a try first */
- return (ENXIO);
- }
- if (uaa->info.bInterfaceClass != UICLASS_HID) {
-
- /* the Xbox 360 gamepad doesn't use the HID class */
-
- if ((uaa->info.bInterfaceClass != UICLASS_VENDOR) ||
- (uaa->info.bInterfaceSubClass != UISUBCLASS_XBOX360_CONTROLLER) ||
- (uaa->info.bInterfaceProtocol != UIPROTO_XBOX360_GAMEPAD)) {
- return (ENXIO);
- }
- }
- if (usb2_test_quirk(uaa, UQ_HID_IGNORE)) {
- return (ENXIO);
- }
- return (0);
-}
-
-static int
-uhid_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct uhid_softc *sc = device_get_softc(dev);
- int unit = device_get_unit(dev);
- int error = 0;
-
- DPRINTFN(10, "sc=%p\n", sc);
-
- device_set_usb2_desc(dev);
-
- mtx_init(&sc->sc_mtx, "uhid lock", NULL, MTX_DEF | MTX_RECURSE);
-
- sc->sc_udev = uaa->device;
-
- sc->sc_iface_no = uaa->info.bIfaceNum;
- sc->sc_iface_index = uaa->info.bIfaceIndex;
-
- error = usb2_transfer_setup(uaa->device,
- &uaa->info.bIfaceIndex, sc->sc_xfer, uhid_config,
- UHID_N_TRANSFER, sc, &sc->sc_mtx);
-
- if (error) {
- DPRINTF("error=%s\n", usb2_errstr(error));
- goto detach;
- }
- if (uaa->info.idVendor == USB_VENDOR_WACOM) {
-
- /* the report descriptor for the Wacom Graphire is broken */
-
- if (uaa->info.idProduct == USB_PRODUCT_WACOM_GRAPHIRE) {
-
- sc->sc_repdesc_size = sizeof(uhid_graphire_report_descr);
- sc->sc_repdesc_ptr = USB_ADD_BYTES(uhid_graphire_report_descr, 0);
- sc->sc_flags |= UHID_FLAG_STATIC_DESC;
-
- } else if (uaa->info.idProduct == USB_PRODUCT_WACOM_GRAPHIRE3_4X5) {
-
- static uint8_t reportbuf[] = {2, 2, 2};
-
- /*
- * The Graphire3 needs 0x0202 to be written to
- * feature report ID 2 before it'll start
- * returning digitizer data.
- */
- error = usb2_req_set_report
- (uaa->device, &Giant, reportbuf, sizeof(reportbuf),
- uaa->info.bIfaceIndex, UHID_FEATURE_REPORT, 2);
-
- if (error) {
- DPRINTF("set report failed, error=%s (ignored)\n",
- usb2_errstr(error));
- }
- sc->sc_repdesc_size = sizeof(uhid_graphire3_4x5_report_descr);
- sc->sc_repdesc_ptr = USB_ADD_BYTES(uhid_graphire3_4x5_report_descr, 0);
- sc->sc_flags |= UHID_FLAG_STATIC_DESC;
- }
- } else if ((uaa->info.bInterfaceClass == UICLASS_VENDOR) &&
- (uaa->info.bInterfaceSubClass == UISUBCLASS_XBOX360_CONTROLLER) &&
- (uaa->info.bInterfaceProtocol == UIPROTO_XBOX360_GAMEPAD)) {
-
- /* the Xbox 360 gamepad has no report descriptor */
- sc->sc_repdesc_size = sizeof(uhid_xb360gp_report_descr);
- sc->sc_repdesc_ptr = USB_ADD_BYTES(uhid_xb360gp_report_descr, 0);
- sc->sc_flags |= UHID_FLAG_STATIC_DESC;
- }
- if (sc->sc_repdesc_ptr == NULL) {
-
- error = usb2_req_get_hid_desc
- (uaa->device, &Giant, &sc->sc_repdesc_ptr,
- &sc->sc_repdesc_size, M_USBDEV, uaa->info.bIfaceIndex);
-
- if (error) {
- device_printf(dev, "no report descriptor\n");
- goto detach;
- }
- }
- error = usb2_req_set_idle(uaa->device, &Giant,
- uaa->info.bIfaceIndex, 0, 0);
-
- if (error) {
- DPRINTF("set idle failed, error=%s (ignored)\n",
- usb2_errstr(error));
- }
- sc->sc_isize = hid_report_size
- (sc->sc_repdesc_ptr, sc->sc_repdesc_size, hid_input, &sc->sc_iid);
-
- sc->sc_osize = hid_report_size
- (sc->sc_repdesc_ptr, sc->sc_repdesc_size, hid_output, &sc->sc_oid);
-
- sc->sc_fsize = hid_report_size
- (sc->sc_repdesc_ptr, sc->sc_repdesc_size, hid_feature, &sc->sc_fid);
-
- if (sc->sc_isize > UHID_BSIZE) {
- DPRINTF("input size is too large, "
- "%d bytes (truncating)\n",
- sc->sc_isize);
- sc->sc_isize = UHID_BSIZE;
- }
- if (sc->sc_osize > UHID_BSIZE) {
- DPRINTF("output size is too large, "
- "%d bytes (truncating)\n",
- sc->sc_osize);
- sc->sc_osize = UHID_BSIZE;
- }
- if (sc->sc_fsize > UHID_BSIZE) {
- DPRINTF("feature size is too large, "
- "%d bytes (truncating)\n",
- sc->sc_fsize);
- sc->sc_fsize = UHID_BSIZE;
- }
- /* set interface permissions */
- usb2_set_iface_perm(uaa->device, uaa->info.bIfaceIndex,
- UID_ROOT, GID_OPERATOR, 0644);
-
- error = usb2_fifo_attach(uaa->device, sc, &sc->sc_mtx,
- &uhid_fifo_methods, &sc->sc_fifo,
- unit, 0 - 1, uaa->info.bIfaceIndex);
- if (error) {
- goto detach;
- }
- return (0); /* success */
-
-detach:
- uhid_detach(dev);
- return (ENOMEM);
-}
-
-static int
-uhid_detach(device_t dev)
-{
- struct uhid_softc *sc = device_get_softc(dev);
-
- usb2_fifo_detach(&sc->sc_fifo);
-
- usb2_transfer_unsetup(sc->sc_xfer, UHID_N_TRANSFER);
-
- if (sc->sc_repdesc_ptr) {
- if (!(sc->sc_flags & UHID_FLAG_STATIC_DESC)) {
- free(sc->sc_repdesc_ptr, M_USBDEV);
- }
- }
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static devclass_t uhid_devclass;
-
-static device_method_t uhid_methods[] = {
- DEVMETHOD(device_probe, uhid_probe),
- DEVMETHOD(device_attach, uhid_attach),
- DEVMETHOD(device_detach, uhid_detach),
- {0, 0}
-};
-
-static driver_t uhid_driver = {
- .name = "uhid",
- .methods = uhid_methods,
- .size = sizeof(struct uhid_softc),
-};
-
-DRIVER_MODULE(uhid, ushub, uhid_driver, uhid_devclass, NULL, 0);
-MODULE_DEPEND(uhid, usb2_input, 1, 1, 1);
-MODULE_DEPEND(uhid, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/input/ukbd2.c b/sys/dev/usb2/input/ukbd2.c
deleted file mode 100644
index 487e560..0000000
--- a/sys/dev/usb2/input/ukbd2.c
+++ /dev/null
@@ -1,1492 +0,0 @@
-#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
- */
-
-#include "opt_compat.h"
-#include "opt_kbd.h"
-#include "opt_ukbd.h"
-
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_hid.h>
-
-#define USB_DEBUG_VAR ukbd_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-#include <dev/usb2/core/usb2_hid.h>
-
-#include <dev/usb2/input/usb2_input.h>
-
-#include <dev/usb2/quirk/usb2_quirk.h>
-
-#include <sys/ioccom.h>
-#include <sys/filio.h>
-#include <sys/tty.h>
-#include <sys/kbio.h>
-
-#include <dev/kbd/kbdreg.h>
-
-/* 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
-
-/* the following file must be included after "ukbdmap.h" */
-#include <dev/kbd/kbdtables.h>
-
-#if USB_DEBUG
-static int ukbd_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ukbd, CTLFLAG_RW, 0, "USB ukbd");
-SYSCTL_INT(_hw_usb2_ukbd, OID_AUTO, debug, CTLFLAG_RW,
- &ukbd_debug, 0, "Debug level");
-#endif
-
-#define UPROTO_BOOT_KEYBOARD 1
-
-#define UKBD_EMULATE_ATSCANCODE 1
-#define UKBD_DRIVER_NAME "ukbd"
-#define UKBD_NMOD 8 /* units */
-#define UKBD_NKEYCODE 6 /* units */
-#define UKBD_IN_BUF_SIZE (2*(UKBD_NMOD + (2*UKBD_NKEYCODE))) /* bytes */
-#define UKBD_IN_BUF_FULL (UKBD_IN_BUF_SIZE / 2) /* bytes */
-#define UKBD_NFKEY (sizeof(fkey_tab)/sizeof(fkey_tab[0])) /* units */
-
-struct ukbd_data {
- uint8_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
- uint8_t reserved;
- uint8_t keycode[UKBD_NKEYCODE];
-} __packed;
-
-enum {
- UKBD_INTR_DT,
- UKBD_INTR_CS,
- UKBD_CTRL_LED,
- UKBD_N_TRANSFER = 3,
-};
-
-struct ukbd_softc {
- keyboard_t sc_kbd;
- keymap_t sc_keymap;
- accentmap_t sc_accmap;
- fkeytab_t sc_fkeymap[UKBD_NFKEY];
- struct usb2_callout sc_callout;
- struct ukbd_data sc_ndata;
- struct ukbd_data sc_odata;
-
- struct usb2_device *sc_udev;
- struct usb2_interface *sc_iface;
- struct usb2_xfer *sc_xfer[UKBD_N_TRANSFER];
-
- uint32_t sc_ntime[UKBD_NKEYCODE];
- uint32_t sc_otime[UKBD_NKEYCODE];
- uint32_t sc_input[UKBD_IN_BUF_SIZE]; /* input buffer */
- uint32_t sc_time_ms;
- uint32_t sc_composed_char; /* composed char code, if non-zero */
-#ifdef UKBD_EMULATE_ATSCANCODE
- uint32_t sc_buffered_char[2];
-#endif
- uint32_t sc_flags; /* flags */
-#define UKBD_FLAG_COMPOSE 0x0001
-#define UKBD_FLAG_POLLING 0x0002
-#define UKBD_FLAG_SET_LEDS 0x0004
-#define UKBD_FLAG_INTR_STALL 0x0008
-#define UKBD_FLAG_ATTACHED 0x0010
-#define UKBD_FLAG_GONE 0x0020
-
- int32_t sc_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
- int32_t sc_state; /* shift/lock key state */
- int32_t sc_accents; /* accent key index (> 0) */
-
- uint16_t sc_inputs;
- uint16_t sc_inputhead;
- uint16_t sc_inputtail;
-
- uint8_t sc_leds; /* store for async led requests */
- uint8_t sc_iface_index;
- uint8_t sc_iface_no;
-};
-
-#define KEY_ERROR 0x01
-
-#define KEY_PRESS 0
-#define KEY_RELEASE 0x400
-#define KEY_INDEX(c) ((c) & 0xFF)
-
-#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)
-
-struct ukbd_mods {
- uint32_t mask, key;
-};
-
-static const struct ukbd_mods ukbd_mods[UKBD_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 const uint8_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 */
-};
-
-/* prototypes */
-static void ukbd_timeout(void *);
-static void ukbd_set_leds(struct ukbd_softc *, uint8_t);
-static int ukbd_set_typematic(keyboard_t *, int);
-#ifdef UKBD_EMULATE_ATSCANCODE
-static int ukbd_key2scan(struct ukbd_softc *, int, int, int);
-#endif
-static uint32_t ukbd_read_char(keyboard_t *, int);
-static void ukbd_clear_state(keyboard_t *);
-static int ukbd_ioctl(keyboard_t *, u_long, caddr_t);
-static int ukbd_enable(keyboard_t *);
-static int ukbd_disable(keyboard_t *);
-static void ukbd_interrupt(struct ukbd_softc *);
-
-static device_probe_t ukbd_probe;
-static device_attach_t ukbd_attach;
-static device_detach_t ukbd_detach;
-static device_resume_t ukbd_resume;
-
-static void
-ukbd_put_key(struct ukbd_softc *sc, uint32_t key)
-{
- mtx_assert(&Giant, MA_OWNED);
-
- DPRINTF("0x%02x (%d) %s\n", key, key,
- (key & KEY_RELEASE) ? "released" : "pressed");
-
- if (sc->sc_inputs < UKBD_IN_BUF_SIZE) {
- sc->sc_input[sc->sc_inputtail] = key;
- ++(sc->sc_inputs);
- ++(sc->sc_inputtail);
- if (sc->sc_inputtail >= UKBD_IN_BUF_SIZE) {
- sc->sc_inputtail = 0;
- }
- } else {
- DPRINTF("input buffer is full\n");
- }
-}
-
-static int32_t
-ukbd_get_key(struct ukbd_softc *sc, uint8_t wait)
-{
- int32_t c;
-
- mtx_assert(&Giant, MA_OWNED);
-
- if (sc->sc_inputs == 0) {
- /* start transfer, if not already started */
- usb2_transfer_start(sc->sc_xfer[UKBD_INTR_DT]);
- }
- if (sc->sc_flags & UKBD_FLAG_POLLING) {
- DPRINTFN(2, "polling\n");
-
- while (sc->sc_inputs == 0) {
-
- usb2_do_poll(sc->sc_xfer, UKBD_N_TRANSFER);
-
- DELAY(1000); /* delay 1 ms */
-
- sc->sc_time_ms++;
-
- /* support repetition of keys: */
-
- ukbd_interrupt(sc);
-
- if (!wait) {
- break;
- }
- }
- }
- if (sc->sc_inputs == 0) {
- c = -1;
- } else {
- c = sc->sc_input[sc->sc_inputhead];
- --(sc->sc_inputs);
- ++(sc->sc_inputhead);
- if (sc->sc_inputhead >= UKBD_IN_BUF_SIZE) {
- sc->sc_inputhead = 0;
- }
- }
- return (c);
-}
-
-static void
-ukbd_interrupt(struct ukbd_softc *sc)
-{
- uint32_t n_mod;
- uint32_t o_mod;
- uint32_t now = sc->sc_time_ms;
- uint32_t dtime;
- uint32_t c;
- uint8_t key;
- uint8_t i;
- uint8_t j;
-
- if (sc->sc_ndata.keycode[0] == KEY_ERROR) {
- goto done;
- }
- n_mod = sc->sc_ndata.modifiers;
- o_mod = sc->sc_odata.modifiers;
- if (n_mod != o_mod) {
- for (i = 0; i < UKBD_NMOD; i++) {
- if ((n_mod & ukbd_mods[i].mask) !=
- (o_mod & ukbd_mods[i].mask)) {
- ukbd_put_key(sc, ukbd_mods[i].key |
- ((n_mod & ukbd_mods[i].mask) ?
- KEY_PRESS : KEY_RELEASE));
- }
- }
- }
- /* Check for released keys. */
- for (i = 0; i < UKBD_NKEYCODE; i++) {
- key = sc->sc_odata.keycode[i];
- if (key == 0) {
- continue;
- }
- for (j = 0; j < UKBD_NKEYCODE; j++) {
- if (sc->sc_ndata.keycode[j] == 0) {
- continue;
- }
- if (key == sc->sc_ndata.keycode[j]) {
- goto rfound;
- }
- }
- ukbd_put_key(sc, key | KEY_RELEASE);
-rfound: ;
- }
-
- /* Check for pressed keys. */
- for (i = 0; i < UKBD_NKEYCODE; i++) {
- key = sc->sc_ndata.keycode[i];
- if (key == 0) {
- continue;
- }
- sc->sc_ntime[i] = now + sc->sc_kbd.kb_delay1;
- for (j = 0; j < UKBD_NKEYCODE; j++) {
- if (sc->sc_odata.keycode[j] == 0) {
- continue;
- }
- if (key == sc->sc_odata.keycode[j]) {
-
- /* key is still pressed */
-
- sc->sc_ntime[i] = sc->sc_otime[j];
- dtime = (sc->sc_otime[j] - now);
-
- if (!(dtime & 0x80000000)) {
- /* time has not elapsed */
- goto pfound;
- }
- sc->sc_ntime[i] = now + sc->sc_kbd.kb_delay2;
- break;
- }
- }
- ukbd_put_key(sc, 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 != UKBD_NKEYCODE; j++) {
- if (j != i)
- sc->sc_ntime[j] = now + (100 * 1000);
- }
-pfound: ;
- }
-
- sc->sc_odata = sc->sc_ndata;
-
- bcopy(sc->sc_ntime, sc->sc_otime, sizeof(sc->sc_otime));
-
- if (sc->sc_inputs == 0) {
- goto done;
- }
- if (sc->sc_flags & UKBD_FLAG_POLLING) {
- goto done;
- }
- if (KBD_IS_ACTIVE(&sc->sc_kbd) &&
- KBD_IS_BUSY(&sc->sc_kbd)) {
- /* let the callback function process the input */
- (sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT,
- sc->sc_kbd.kb_callback.kc_arg);
- } else {
- /* read and discard the input, no one is waiting for it */
- do {
- c = ukbd_read_char(&sc->sc_kbd, 0);
- } while (c != NOKEY);
- }
-done:
- return;
-}
-
-static void
-ukbd_timeout(void *arg)
-{
- struct ukbd_softc *sc = arg;
-
- mtx_assert(&Giant, MA_OWNED);
-
- if (!(sc->sc_flags & UKBD_FLAG_POLLING)) {
- sc->sc_time_ms += 25; /* milliseconds */
- }
- ukbd_interrupt(sc);
-
- usb2_callout_reset(&sc->sc_callout, hz / 40, &ukbd_timeout, sc);
-}
-
-static void
-ukbd_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct ukbd_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[UKBD_INTR_DT];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UKBD_FLAG_INTR_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
-ukbd_intr_callback(struct usb2_xfer *xfer)
-{
- struct ukbd_softc *sc = xfer->priv_sc;
- uint16_t len = xfer->actlen;
- uint8_t i;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTF("actlen=%d bytes\n", len);
-
- if (len > sizeof(sc->sc_ndata)) {
- len = sizeof(sc->sc_ndata);
- }
- if (len) {
- bzero(&sc->sc_ndata, sizeof(sc->sc_ndata));
- usb2_copy_out(xfer->frbuffers, 0, &sc->sc_ndata, len);
-#if USB_DEBUG
- if (sc->sc_ndata.modifiers) {
- DPRINTF("mod: 0x%04x\n", sc->sc_ndata.modifiers);
- }
- for (i = 0; i < UKBD_NKEYCODE; i++) {
- if (sc->sc_ndata.keycode[i]) {
- DPRINTF("[%d] = %d\n", i, sc->sc_ndata.keycode[i]);
- }
- }
-#endif /* USB_DEBUG */
- ukbd_interrupt(sc);
- }
- case USB_ST_SETUP:
- if (sc->sc_flags & UKBD_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[UKBD_INTR_CS]);
- return;
- }
- if (sc->sc_inputs < UKBD_IN_BUF_FULL) {
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- } else {
- DPRINTF("input queue is full!\n");
- }
- return;
-
- default: /* Error */
- DPRINTF("error=%s\n", usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- sc->sc_flags |= UKBD_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[UKBD_INTR_CS]);
- }
- return;
- }
-}
-
-static void
-ukbd_set_leds_callback(struct usb2_xfer *xfer)
-{
- struct usb2_device_request req;
- uint8_t buf[1];
- struct ukbd_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- case USB_ST_SETUP:
- if (sc->sc_flags & UKBD_FLAG_SET_LEDS) {
- sc->sc_flags &= ~UKBD_FLAG_SET_LEDS;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, UHID_OUTPUT_REPORT, 0);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 1);
-
- buf[0] = sc->sc_leds;
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
- usb2_copy_in(xfer->frbuffers + 1, 0, buf, sizeof(buf));
-
- xfer->frlengths[0] = sizeof(req);
- xfer->frlengths[1] = sizeof(buf);
- xfer->nframes = 2;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- DPRINTFN(0, "error=%s\n", usb2_errstr(xfer->error));
- return;
- }
-}
-
-static const struct usb2_config ukbd_config[UKBD_N_TRANSFER] = {
-
- [UKBD_INTR_DT] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = &ukbd_intr_callback,
- },
-
- [UKBD_INTR_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.callback = &ukbd_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
-
- [UKBD_CTRL_LED] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request) + 1,
- .mh.callback = &ukbd_set_leds_callback,
- .mh.timeout = 1000, /* 1 second */
- },
-};
-
-static int
-ukbd_probe(device_t dev)
-{
- keyboard_switch_t *sw = kbd_get_switch(UKBD_DRIVER_NAME);
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- DPRINTFN(11, "\n");
-
- if (sw == NULL) {
- return (ENXIO);
- }
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- /* check that the keyboard speaks the boot protocol: */
- if ((uaa->info.bInterfaceClass == UICLASS_HID)
- && (uaa->info.bInterfaceSubClass == UISUBCLASS_BOOT)
- && (uaa->info.bInterfaceProtocol == UPROTO_BOOT_KEYBOARD)) {
- if (usb2_test_quirk(uaa, UQ_KBD_IGNORE))
- return (ENXIO);
- else
- return (0);
- }
- return (ENXIO);
-}
-
-static int
-ukbd_attach(device_t dev)
-{
- struct ukbd_softc *sc = device_get_softc(dev);
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- int32_t unit = device_get_unit(dev);
- keyboard_t *kbd = &sc->sc_kbd;
- usb2_error_t err;
- uint16_t n;
-
- mtx_assert(&Giant, MA_OWNED);
-
- kbd_init_struct(kbd, UKBD_DRIVER_NAME, KB_OTHER, unit, 0, 0, 0);
-
- kbd->kb_data = (void *)sc;
-
- device_set_usb2_desc(dev);
-
- sc->sc_udev = uaa->device;
- sc->sc_iface = uaa->iface;
- sc->sc_iface_index = uaa->info.bIfaceIndex;
- sc->sc_iface_no = uaa->info.bIfaceNum;
- sc->sc_mode = K_XLATE;
- sc->sc_iface = uaa->iface;
-
- usb2_callout_init_mtx(&sc->sc_callout, &Giant, 0);
-
- err = usb2_transfer_setup(uaa->device,
- &uaa->info.bIfaceIndex, sc->sc_xfer, ukbd_config,
- UKBD_N_TRANSFER, sc, &Giant);
-
- if (err) {
- DPRINTF("error=%s\n", usb2_errstr(err));
- goto detach;
- }
- /* setup default keyboard maps */
-
- sc->sc_keymap = key_map;
- sc->sc_accmap = accent_map;
- for (n = 0; n < UKBD_NFKEY; n++) {
- sc->sc_fkeymap[n] = fkey_tab[n];
- }
-
- kbd_set_maps(kbd, &sc->sc_keymap, &sc->sc_accmap,
- sc->sc_fkeymap, UKBD_NFKEY);
-
- KBD_FOUND_DEVICE(kbd);
-
- ukbd_clear_state(kbd);
-
- /*
- * FIXME: set the initial value for lock keys in "sc_state"
- * according to the BIOS data?
- */
- KBD_PROBE_DONE(kbd);
-
- /* ignore if SETIDLE fails, hence it is not crucial */
- err = usb2_req_set_idle(sc->sc_udev, &Giant, sc->sc_iface_index, 0, 0);
-
- ukbd_ioctl(kbd, KDSETLED, (caddr_t)&sc->sc_state);
-
- KBD_INIT_DONE(kbd);
-
- if (kbd_register(kbd) < 0) {
- goto detach;
- }
- KBD_CONFIG_DONE(kbd);
-
- ukbd_enable(kbd);
-
-#ifdef KBD_INSTALL_CDEV
- if (kbd_attach(kbd)) {
- goto detach;
- }
-#endif
- sc->sc_flags |= UKBD_FLAG_ATTACHED;
-
- if (bootverbose) {
- genkbd_diag(kbd, bootverbose);
- }
- /* lock keyboard mutex */
-
- mtx_lock(&Giant);
-
- /* start the keyboard */
-
- usb2_transfer_start(sc->sc_xfer[UKBD_INTR_DT]);
-
- /* start the timer */
-
- ukbd_timeout(sc);
- mtx_unlock(&Giant);
- return (0); /* success */
-
-detach:
- ukbd_detach(dev);
- return (ENXIO); /* error */
-}
-
-int
-ukbd_detach(device_t dev)
-{
- struct ukbd_softc *sc = device_get_softc(dev);
- int error;
-
- mtx_assert(&Giant, MA_OWNED);
-
- DPRINTF("\n");
-
- if (sc->sc_flags & UKBD_FLAG_POLLING) {
- panic("cannot detach polled keyboard!\n");
- }
- sc->sc_flags |= UKBD_FLAG_GONE;
-
- usb2_callout_stop(&sc->sc_callout);
-
- ukbd_disable(&sc->sc_kbd);
-
-#ifdef KBD_INSTALL_CDEV
- if (sc->sc_flags & UKBD_FLAG_ATTACHED) {
- error = kbd_detach(&sc->sc_kbd);
- if (error) {
- /* usb attach cannot return an error */
- device_printf(dev, "WARNING: kbd_detach() "
- "returned non-zero! (ignored)\n");
- }
- }
-#endif
- if (KBD_IS_CONFIGURED(&sc->sc_kbd)) {
- error = kbd_unregister(&sc->sc_kbd);
- if (error) {
- /* usb attach cannot return an error */
- device_printf(dev, "WARNING: kbd_unregister() "
- "returned non-zero! (ignored)\n");
- }
- }
- sc->sc_kbd.kb_flags = 0;
-
- usb2_transfer_unsetup(sc->sc_xfer, UKBD_N_TRANSFER);
-
- usb2_callout_drain(&sc->sc_callout);
-
- DPRINTF("%s: disconnected\n",
- device_get_nameunit(dev));
-
- return (0);
-}
-
-static int
-ukbd_resume(device_t dev)
-{
- struct ukbd_softc *sc = device_get_softc(dev);
-
- mtx_assert(&Giant, MA_OWNED);
-
- ukbd_clear_state(&sc->sc_kbd);
-
- return (0);
-}
-
-/* early keyboard probe, not supported */
-static int
-ukbd_configure(int flags)
-{
- return (0);
-}
-
-/* detect a keyboard, not used */
-static int
-ukbd__probe(int unit, void *arg, int flags)
-{
- mtx_assert(&Giant, MA_OWNED);
- return (ENXIO);
-}
-
-/* reset and initialize the device, not used */
-static int
-ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
-{
- mtx_assert(&Giant, MA_OWNED);
- return (ENXIO);
-}
-
-/* test the interface to the device, not used */
-static int
-ukbd_test_if(keyboard_t *kbd)
-{
- mtx_assert(&Giant, MA_OWNED);
- return (0);
-}
-
-/* finish using this keyboard, not used */
-static int
-ukbd_term(keyboard_t *kbd)
-{
- mtx_assert(&Giant, MA_OWNED);
- return (ENXIO);
-}
-
-/* keyboard interrupt routine, not used */
-static int
-ukbd_intr(keyboard_t *kbd, void *arg)
-{
- mtx_assert(&Giant, MA_OWNED);
- return (0);
-}
-
-/* lock the access to the keyboard, not used */
-static int
-ukbd_lock(keyboard_t *kbd, int lock)
-{
- mtx_assert(&Giant, MA_OWNED);
- return (1);
-}
-
-/*
- * 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)
-{
- mtx_assert(&Giant, MA_OWNED);
- KBD_ACTIVATE(kbd);
- return (0);
-}
-
-/* disallow the access to the device */
-static int
-ukbd_disable(keyboard_t *kbd)
-{
- mtx_assert(&Giant, MA_OWNED);
- KBD_DEACTIVATE(kbd);
- return (0);
-}
-
-/* check if data is waiting */
-static int
-ukbd_check(keyboard_t *kbd)
-{
- struct ukbd_softc *sc = kbd->kb_data;
-
- if (!mtx_owned(&Giant)) {
- return (0); /* XXX */
- }
- mtx_assert(&Giant, MA_OWNED);
-
- if (!KBD_IS_ACTIVE(kbd)) {
- return (0);
- }
-#ifdef UKBD_EMULATE_ATSCANCODE
- if (sc->sc_buffered_char[0]) {
- return (1);
- }
-#endif
- if (sc->sc_inputs > 0) {
- return (1);
- }
- return (0);
-}
-
-/* check if char is waiting */
-static int
-ukbd_check_char(keyboard_t *kbd)
-{
- struct ukbd_softc *sc = kbd->kb_data;
-
- if (!mtx_owned(&Giant)) {
- return (0); /* XXX */
- }
- mtx_assert(&Giant, MA_OWNED);
-
- if (!KBD_IS_ACTIVE(kbd)) {
- return (0);
- }
- if ((sc->sc_composed_char > 0) &&
- (!(sc->sc_flags & UKBD_FLAG_COMPOSE))) {
- return (1);
- }
- return (ukbd_check(kbd));
-}
-
-
-/* read one byte from the keyboard if it's allowed */
-static int
-ukbd_read(keyboard_t *kbd, int wait)
-{
- struct ukbd_softc *sc = kbd->kb_data;
- int32_t usbcode;
-
-#ifdef UKBD_EMULATE_ATSCANCODE
- uint32_t keycode;
- uint32_t scancode;
-
-#endif
-
- if (!mtx_owned(&Giant)) {
- return -1; /* XXX */
- }
- mtx_assert(&Giant, MA_OWNED);
-
-#ifdef UKBD_EMULATE_ATSCANCODE
- if (sc->sc_buffered_char[0]) {
- scancode = sc->sc_buffered_char[0];
- if (scancode & SCAN_PREFIX) {
- sc->sc_buffered_char[0] &= ~SCAN_PREFIX;
- return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
- }
- sc->sc_buffered_char[0] = sc->sc_buffered_char[1];
- sc->sc_buffered_char[1] = 0;
- return (scancode);
- }
-#endif /* UKBD_EMULATE_ATSCANCODE */
-
- /* XXX */
- usbcode = ukbd_get_key(sc, (wait == FALSE) ? 0 : 1);
- 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;
- }
- return (ukbd_key2scan(sc, keycode, sc->sc_ndata.modifiers,
- (usbcode & KEY_RELEASE)));
-#else /* !UKBD_EMULATE_ATSCANCODE */
- return (usbcode);
-#endif /* UKBD_EMULATE_ATSCANCODE */
-}
-
-/* read char from the keyboard */
-static uint32_t
-ukbd_read_char(keyboard_t *kbd, int wait)
-{
- struct ukbd_softc *sc = kbd->kb_data;
- uint32_t action;
- uint32_t keycode;
- int32_t usbcode;
-
-#ifdef UKBD_EMULATE_ATSCANCODE
- uint32_t scancode;
-
-#endif
- if (!mtx_owned(&Giant)) {
- return (NOKEY); /* XXX */
- }
- mtx_assert(&Giant, MA_OWNED);
-
-next_code:
-
- /* do we have a composed char to return ? */
-
- if ((sc->sc_composed_char > 0) &&
- (!(sc->sc_flags & UKBD_FLAG_COMPOSE))) {
-
- action = sc->sc_composed_char;
- sc->sc_composed_char = 0;
-
- if (action > 0xFF) {
- goto errkey;
- }
- goto done;
- }
-#ifdef UKBD_EMULATE_ATSCANCODE
-
- /* do we have a pending raw scan code? */
-
- if (sc->sc_mode == K_RAW) {
- scancode = sc->sc_buffered_char[0];
- if (scancode) {
- if (scancode & SCAN_PREFIX) {
- sc->sc_buffered_char[0] = (scancode & ~SCAN_PREFIX);
- return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
- }
- sc->sc_buffered_char[0] = sc->sc_buffered_char[1];
- sc->sc_buffered_char[1] = 0;
- return (scancode);
- }
- }
-#endif /* UKBD_EMULATE_ATSCANCODE */
-
- /* see if there is something in the keyboard port */
- /* XXX */
- usbcode = ukbd_get_key(sc, (wait == FALSE) ? 0 : 1);
- 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 (sc->sc_mode == K_RAW) {
- return (ukbd_key2scan(sc, keycode, sc->sc_ndata.modifiers,
- (usbcode & KEY_RELEASE)));
- }
-#else /* !UKBD_EMULATE_ATSCANCODE */
-
- /* return the byte as is for the K_RAW mode */
- if (sc->sc_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 (sc->sc_flags & UKBD_FLAG_COMPOSE) {
- sc->sc_flags &= ~UKBD_FLAG_COMPOSE;
-
- if (sc->sc_composed_char > 0xFF) {
- sc->sc_composed_char = 0;
- }
- }
- } else {
- if (!(sc->sc_flags & UKBD_FLAG_COMPOSE)) {
- sc->sc_flags |= UKBD_FLAG_COMPOSE;
- sc->sc_composed_char = 0;
- }
- }
- break;
- /* XXX: I don't like these... */
- case 0x5c: /* print screen */
- if (sc->sc_flags & ALTS) {
- keycode = 0x54; /* sysrq */
- }
- break;
- case 0x68: /* pause/break */
- if (sc->sc_flags & CTLS) {
- keycode = 0x6c; /* break */
- }
- break;
- }
-
- /* return the key code in the K_CODE mode */
- if (usbcode & KEY_RELEASE) {
- keycode |= SCAN_RELEASE;
- }
- if (sc->sc_mode == K_CODE) {
- return (keycode);
- }
- /* compose a character code */
- if (sc->sc_flags & UKBD_FLAG_COMPOSE) {
- switch (keycode) {
- /* key pressed, process it */
- case 0x47:
- case 0x48:
- case 0x49: /* keypad 7,8,9 */
- sc->sc_composed_char *= 10;
- sc->sc_composed_char += keycode - 0x40;
- goto check_composed;
-
- case 0x4B:
- case 0x4C:
- case 0x4D: /* keypad 4,5,6 */
- sc->sc_composed_char *= 10;
- sc->sc_composed_char += keycode - 0x47;
- goto check_composed;
-
- case 0x4F:
- case 0x50:
- case 0x51: /* keypad 1,2,3 */
- sc->sc_composed_char *= 10;
- sc->sc_composed_char += keycode - 0x4E;
- goto check_composed;
-
- case 0x52: /* keypad 0 */
- sc->sc_composed_char *= 10;
- goto check_composed;
-
- /* 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 (sc->sc_composed_char > 0) {
- sc->sc_flags &= ~UKBD_FLAG_COMPOSE;
- sc->sc_composed_char = 0;
- goto errkey;
- }
- break;
- }
- }
- /* keycode to key action */
- action = genkbd_keyaction(kbd, SCAN_CHAR(keycode),
- (keycode & SCAN_RELEASE),
- &sc->sc_state, &sc->sc_accents);
- if (action == NOKEY) {
- goto next_code;
- }
-done:
- return (action);
-
-check_composed:
- if (sc->sc_composed_char <= 0xFF) {
- goto next_code;
- }
-errkey:
- return (ERRKEY);
-}
-
-/* some useful control functions */
-static int
-ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
-{
- /* translate LED_XXX bits into the device specific bits */
- static const uint8_t ledmap[8] = {
- 0, 2, 1, 3, 4, 6, 5, 7,
- };
- struct ukbd_softc *sc = kbd->kb_data;
- int i;
-
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
- int ival;
-
-#endif
- if (!mtx_owned(&Giant)) {
- /*
- * XXX big problem: If scroll lock is pressed and "printf()"
- * is called, the CPU will get here, to un-scroll lock the
- * keyboard. But if "printf()" acquires the "Giant" lock,
- * there will be a locking order reversal problem, so the
- * keyboard system must get out of "Giant" first, before the
- * CPU can proceed here ...
- */
- return (EINVAL);
- }
- mtx_assert(&Giant, MA_OWNED);
-
- switch (cmd) {
- case KDGKBMODE: /* get keyboard mode */
- *(int *)arg = sc->sc_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 (sc->sc_mode != K_XLATE) {
- /* make lock key state and LED state match */
- sc->sc_state &= ~LOCK_MASK;
- sc->sc_state |= KBD_LED_VAL(kbd);
- }
- /* FALLTHROUGH */
- case K_RAW:
- case K_CODE:
- if (sc->sc_mode != *(int *)arg) {
- ukbd_clear_state(kbd);
- sc->sc_mode = *(int *)arg;
- }
- break;
- default:
- 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 "sc_state" won't be changed */
- if (*(int *)arg & ~LOCK_MASK) {
- return (EINVAL);
- }
- i = *(int *)arg;
- /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
- if (sc->sc_mode == K_XLATE &&
- kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
- if (i & ALKED)
- i |= CLKED;
- else
- i &= ~CLKED;
- }
- if (KBD_HAS_DEVICE(kbd)) {
- ukbd_set_leds(sc, ledmap[i & LED_MASK]);
- }
- KBD_LED_VAL(kbd) = *(int *)arg;
- break;
- case KDGKBSTATE: /* get lock key state */
- *(int *)arg = sc->sc_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) {
- return (EINVAL);
- }
- sc->sc_state &= ~LOCK_MASK;
- sc->sc_state |= *(int *)arg;
-
- /* set LEDs and quit */
- return (ukbd_ioctl(kbd, KDSETLED, arg));
-
- case KDSETREPEAT: /* set keyboard repeat rate (new
- * interface) */
- if (!KBD_HAS_DEVICE(kbd)) {
- return (0);
- }
- if (((int *)arg)[1] < 0) {
- return (EINVAL);
- }
- if (((int *)arg)[0] < 0) {
- return (EINVAL);
- }
- if (((int *)arg)[0] < 200) /* 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) */
- return (ukbd_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 */
- sc->sc_accents = 0;
- /* FALLTHROUGH */
- default:
- return (genkbd_commonioctl(kbd, cmd, arg));
- }
-
- return (0);
-}
-
-/* clear the internal state of the keyboard */
-static void
-ukbd_clear_state(keyboard_t *kbd)
-{
- struct ukbd_softc *sc = kbd->kb_data;
-
- if (!mtx_owned(&Giant)) {
- return; /* XXX */
- }
- mtx_assert(&Giant, MA_OWNED);
-
- sc->sc_flags &= ~(UKBD_FLAG_COMPOSE | UKBD_FLAG_POLLING);
- sc->sc_state &= LOCK_MASK; /* preserve locking key state */
- sc->sc_accents = 0;
- sc->sc_composed_char = 0;
-#ifdef UKBD_EMULATE_ATSCANCODE
- sc->sc_buffered_char[0] = 0;
- sc->sc_buffered_char[1] = 0;
-#endif
- bzero(&sc->sc_ndata, sizeof(sc->sc_ndata));
- bzero(&sc->sc_odata, sizeof(sc->sc_odata));
- bzero(&sc->sc_ntime, sizeof(sc->sc_ntime));
- bzero(&sc->sc_otime, sizeof(sc->sc_otime));
-}
-
-/* save the internal state, not used */
-static int
-ukbd_get_state(keyboard_t *kbd, void *buf, size_t len)
-{
- mtx_assert(&Giant, MA_OWNED);
- return (len == 0) ? 1 : -1;
-}
-
-/* set the internal state, not used */
-static int
-ukbd_set_state(keyboard_t *kbd, void *buf, size_t len)
-{
- mtx_assert(&Giant, MA_OWNED);
- return (EINVAL);
-}
-
-static int
-ukbd_poll(keyboard_t *kbd, int on)
-{
- struct ukbd_softc *sc = kbd->kb_data;
-
- if (!mtx_owned(&Giant)) {
- return (0); /* XXX */
- }
- mtx_assert(&Giant, MA_OWNED);
-
- if (on) {
- sc->sc_flags |= UKBD_FLAG_POLLING;
- } else {
- sc->sc_flags &= ~UKBD_FLAG_POLLING;
- }
- return (0);
-}
-
-/* local functions */
-
-static void
-ukbd_set_leds(struct ukbd_softc *sc, uint8_t leds)
-{
- DPRINTF("leds=0x%02x\n", leds);
-
- sc->sc_leds = leds;
- sc->sc_flags |= UKBD_FLAG_SET_LEDS;
-
- /* start transfer, if not already started */
-
- usb2_transfer_start(sc->sc_xfer[UKBD_CTRL_LED]);
-}
-
-static int
-ukbd_set_typematic(keyboard_t *kbd, int code)
-{
- static const int delays[] = {250, 500, 750, 1000};
- static const 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
-ukbd_key2scan(struct ukbd_softc *sc, int code, int shift, int up)
-{
- static const 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,
- };
-
- if ((code >= 89) && (code < (89 + (sizeof(scan) / sizeof(scan[0]))))) {
- code = scan[code - 89] | SCAN_PREFIX_E0;
- }
- /* Pause/Break */
- if ((code == 104) && (!(shift & (MOD_CONTROL_L | MOD_CONTROL_R)))) {
- code = (0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL);
- }
- if (shift & (MOD_SHIFT_L | MOD_SHIFT_R)) {
- code &= ~SCAN_PREFIX_SHIFT;
- }
- code |= (up ? SCAN_RELEASE : SCAN_PRESS);
-
- if (code & SCAN_PREFIX) {
- if (code & SCAN_PREFIX_CTL) {
- /* Ctrl */
- sc->sc_buffered_char[0] = (0x1d | (code & SCAN_RELEASE));
- sc->sc_buffered_char[1] = (code & ~SCAN_PREFIX);
- } else if (code & SCAN_PREFIX_SHIFT) {
- /* Shift */
- sc->sc_buffered_char[0] = (0x2a | (code & SCAN_RELEASE));
- sc->sc_buffered_char[1] = (code & ~SCAN_PREFIX_SHIFT);
- } else {
- sc->sc_buffered_char[0] = (code & ~SCAN_PREFIX);
- sc->sc_buffered_char[1] = 0;
- }
- return ((code & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
- }
- return (code);
-
-}
-
-#endif /* UKBD_EMULATE_ATSCANCODE */
-
-keyboard_switch_t ukbdsw = {
- .probe = &ukbd__probe,
- .init = &ukbd_init,
- .term = &ukbd_term,
- .intr = &ukbd_intr,
- .test_if = &ukbd_test_if,
- .enable = &ukbd_enable,
- .disable = &ukbd_disable,
- .read = &ukbd_read,
- .check = &ukbd_check,
- .read_char = &ukbd_read_char,
- .check_char = &ukbd_check_char,
- .ioctl = &ukbd_ioctl,
- .lock = &ukbd_lock,
- .clear_state = &ukbd_clear_state,
- .get_state = &ukbd_get_state,
- .set_state = &ukbd_set_state,
- .get_fkeystr = &genkbd_get_fkeystr,
- .poll = &ukbd_poll,
- .diag = &genkbd_diag,
-};
-
-KEYBOARD_DRIVER(ukbd, ukbdsw, ukbd_configure);
-
-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 (0);
-}
-
-static devclass_t ukbd_devclass;
-
-static device_method_t ukbd_methods[] = {
- DEVMETHOD(device_probe, ukbd_probe),
- DEVMETHOD(device_attach, ukbd_attach),
- DEVMETHOD(device_detach, ukbd_detach),
- DEVMETHOD(device_resume, ukbd_resume),
- {0, 0}
-};
-
-static driver_t ukbd_driver = {
- .name = "ukbd",
- .methods = ukbd_methods,
- .size = sizeof(struct ukbd_softc),
-};
-
-DRIVER_MODULE(ukbd, ushub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0);
-MODULE_DEPEND(ukbd, usb2_input, 1, 1, 1);
-MODULE_DEPEND(ukbd, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/input/ums2.c b/sys/dev/usb2/input/ums2.c
deleted file mode 100644
index 9de44f6..0000000
--- a/sys/dev/usb2/input/ums2.c
+++ /dev/null
@@ -1,904 +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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_hid.h>
-
-#define USB_DEBUG_VAR ums_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_transfer.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-#include <dev/usb2/core/usb2_dev.h>
-#include <dev/usb2/core/usb2_hid.h>
-
-#include <dev/usb2/input/usb2_input.h>
-
-#include <dev/usb2/quirk/usb2_quirk.h>
-
-#include <sys/ioccom.h>
-#include <sys/filio.h>
-#include <sys/tty.h>
-#include <sys/mouse.h>
-
-#if USB_DEBUG
-static int ums_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ums, CTLFLAG_RW, 0, "USB ums");
-SYSCTL_INT(_hw_usb2_ums, OID_AUTO, debug, CTLFLAG_RW,
- &ums_debug, 0, "Debug level");
-#endif
-
-#define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
-#define MOUSE_FLAGS (HIO_RELATIVE)
-
-#define UMS_BUF_SIZE 8 /* bytes */
-#define UMS_IFQ_MAXLEN 50 /* units */
-#define UMS_BUTTON_MAX 31 /* exclusive, must be less than 32 */
-#define UMS_BUT(i) ((i) < 3 ? (((i) + 2) % 3) : (i))
-
-enum {
- UMS_INTR_DT,
- UMS_INTR_CS,
- UMS_N_TRANSFER = 2,
-};
-
-struct ums_softc {
- struct usb2_fifo_sc sc_fifo;
- struct mtx sc_mtx;
- struct usb2_callout sc_callout;
- struct hid_location sc_loc_w;
- struct hid_location sc_loc_x;
- struct hid_location sc_loc_y;
- struct hid_location sc_loc_z;
- struct hid_location sc_loc_t;
- struct hid_location sc_loc_btn[UMS_BUTTON_MAX];
- mousehw_t sc_hw;
- mousemode_t sc_mode;
- mousestatus_t sc_status;
-
- struct usb2_xfer *sc_xfer[UMS_N_TRANSFER];
-
- uint32_t sc_flags;
-#define UMS_FLAG_X_AXIS 0x0001
-#define UMS_FLAG_Y_AXIS 0x0002
-#define UMS_FLAG_Z_AXIS 0x0004
-#define UMS_FLAG_T_AXIS 0x0008
-#define UMS_FLAG_SBU 0x0010 /* spurious button up events */
-#define UMS_FLAG_INTR_STALL 0x0020 /* set if transfer error */
-#define UMS_FLAG_REVZ 0x0040 /* Z-axis is reversed */
-#define UMS_FLAG_W_AXIS 0x0080
-
- uint8_t sc_buttons;
- uint8_t sc_iid;
- uint8_t sc_temp[64];
-};
-
-static void ums_put_queue_timeout(void *__sc);
-
-static usb2_callback_t ums_clear_stall_callback;
-static usb2_callback_t ums_intr_callback;
-
-static device_probe_t ums_probe;
-static device_attach_t ums_attach;
-static device_detach_t ums_detach;
-
-static usb2_fifo_cmd_t ums_start_read;
-static usb2_fifo_cmd_t ums_stop_read;
-static usb2_fifo_open_t ums_open;
-static usb2_fifo_close_t ums_close;
-static usb2_fifo_ioctl_t ums_ioctl;
-
-static void ums_put_queue(struct ums_softc *sc, int32_t dx, int32_t dy, int32_t dz, int32_t dt, int32_t buttons);
-
-static struct usb2_fifo_methods ums_fifo_methods = {
- .f_open = &ums_open,
- .f_close = &ums_close,
- .f_ioctl = &ums_ioctl,
- .f_start_read = &ums_start_read,
- .f_stop_read = &ums_stop_read,
- .basename[0] = "ums",
-};
-
-static void
-ums_put_queue_timeout(void *__sc)
-{
- struct ums_softc *sc = __sc;
-
- mtx_assert(&sc->sc_mtx, MA_OWNED);
-
- ums_put_queue(sc, 0, 0, 0, 0, 0);
-}
-
-static void
-ums_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct ums_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[UMS_INTR_DT];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UMS_FLAG_INTR_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
-ums_intr_callback(struct usb2_xfer *xfer)
-{
- struct ums_softc *sc = xfer->priv_sc;
- uint8_t *buf = sc->sc_temp;
- uint16_t len = xfer->actlen;
- int32_t buttons = 0;
- int32_t dw;
- int32_t dx;
- int32_t dy;
- int32_t dz;
- int32_t dt;
- uint8_t i;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(6, "sc=%p actlen=%d\n", sc, len);
-
- if (len > sizeof(sc->sc_temp)) {
- DPRINTFN(6, "truncating large packet to %zu bytes\n",
- sizeof(sc->sc_temp));
- len = sizeof(sc->sc_temp);
- }
- if (len == 0) {
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, 0, buf, len);
-
- DPRINTFN(6, "data = %02x %02x %02x %02x "
- "%02x %02x %02x %02x\n",
- (len > 0) ? buf[0] : 0, (len > 1) ? buf[1] : 0,
- (len > 2) ? buf[2] : 0, (len > 3) ? buf[3] : 0,
- (len > 4) ? buf[4] : 0, (len > 5) ? buf[5] : 0,
- (len > 6) ? buf[6] : 0, (len > 7) ? buf[7] : 0);
-
- /*
- * 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_FLAG_T_AXIS so use it as an
- * identifier.
- *
- *
- * 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.
- *
- * We probably should switch to some more official quirk.
- */
- if (sc->sc_iid) {
- if (sc->sc_flags & UMS_FLAG_T_AXIS) {
- if (*buf == 0x02) {
- goto tr_setup;
- }
- } else {
- if (*buf != sc->sc_iid) {
- goto tr_setup;
- }
- }
-
- len--;
- buf++;
-
- } else {
- if (sc->sc_flags & UMS_FLAG_SBU) {
- if ((*buf == 0x14) || (*buf == 0x15)) {
- goto tr_setup;
- }
- }
- }
-
- dw = (sc->sc_flags & UMS_FLAG_W_AXIS) ?
- hid_get_data(buf, len, &sc->sc_loc_w) : 0;
-
- dx = (sc->sc_flags & UMS_FLAG_X_AXIS) ?
- hid_get_data(buf, len, &sc->sc_loc_x) : 0;
-
- dy = (sc->sc_flags & UMS_FLAG_Y_AXIS) ?
- -hid_get_data(buf, len, &sc->sc_loc_y) : 0;
-
- dz = (sc->sc_flags & UMS_FLAG_Z_AXIS) ?
- -hid_get_data(buf, len, &sc->sc_loc_z) : 0;
-
- if (sc->sc_flags & UMS_FLAG_REVZ) {
- dz = -dz;
- }
- dt = (sc->sc_flags & UMS_FLAG_T_AXIS) ?
- -hid_get_data(buf, len, &sc->sc_loc_t): 0;
-
- for (i = 0; i < sc->sc_buttons; i++) {
- if (hid_get_data(buf, len, &sc->sc_loc_btn[i])) {
- buttons |= (1 << UMS_BUT(i));
- }
- }
-
- if (dx || dy || dz || dt || dw ||
- (buttons != sc->sc_status.button)) {
-
- DPRINTFN(6, "x:%d y:%d z:%d t:%d w:%d buttons:0x%08x\n",
- dx, dy, dz, dt, dw, buttons);
-
- sc->sc_status.button = buttons;
- sc->sc_status.dx += dx;
- sc->sc_status.dy += dy;
- sc->sc_status.dz += dz;
- /*
- * sc->sc_status.dt += dt;
- * no way to export this yet
- */
-
- /*
- * 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->sc_flags & UMS_FLAG_SBU) &&
- (dx == 0) && (dy == 0) && (dz == 0) && (dt == 0) &&
- (dw == 0) && (buttons == 0)) {
-
- usb2_callout_reset(&sc->sc_callout, hz / 20,
- &ums_put_queue_timeout, sc);
- } else {
-
- usb2_callout_stop(&sc->sc_callout);
-
- ums_put_queue(sc, dx, dy, dz, dt, buttons);
- }
- }
- case USB_ST_SETUP:
-tr_setup:
- if (sc->sc_flags & UMS_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[UMS_INTR_CS]);
- } else {
- /* check if we can put more data into the FIFO */
- if (usb2_fifo_put_bytes_max(
- sc->sc_fifo.fp[USB_FIFO_RX]) != 0) {
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- }
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* start clear stall */
- sc->sc_flags |= UMS_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[UMS_INTR_CS]);
- }
- return;
- }
-}
-
-static const struct usb2_config ums_config[UMS_N_TRANSFER] = {
-
- [UMS_INTR_DT] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = &ums_intr_callback,
- },
-
- [UMS_INTR_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.callback = &ums_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
-};
-
-static int
-ums_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct usb2_interface_descriptor *id;
- void *d_ptr;
- int32_t error = 0;
- uint16_t d_len;
-
- DPRINTFN(11, "\n");
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->iface == NULL) {
- return (ENXIO);
- }
- id = usb2_get_interface_descriptor(uaa->iface);
-
- if ((id == NULL) ||
- (id->bInterfaceClass != UICLASS_HID)) {
- return (ENXIO);
- }
- error = usb2_req_get_hid_desc
- (uaa->device, &Giant,
- &d_ptr, &d_len, M_TEMP, uaa->info.bIfaceIndex);
-
- if (error) {
- return (ENXIO);
- }
- if (hid_is_collection(d_ptr, d_len,
- HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE))) {
- error = 0;
- } else if ((id->bInterfaceSubClass == UISUBCLASS_BOOT) &&
- (id->bInterfaceProtocol == UIPROTO_MOUSE)) {
- error = 0;
- } else {
- error = ENXIO;
- }
-
- free(d_ptr, M_TEMP);
- return (error);
-}
-
-static int
-ums_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ums_softc *sc = device_get_softc(dev);
- void *d_ptr = NULL;
- int unit = device_get_unit(dev);
- int32_t isize;
- uint32_t flags;
- int32_t err;
- uint16_t d_len;
- uint8_t i;
-
- DPRINTFN(11, "sc=%p\n", sc);
-
- device_set_usb2_desc(dev);
-
- mtx_init(&sc->sc_mtx, "ums lock", NULL, MTX_DEF | MTX_RECURSE);
-
- usb2_callout_init_mtx(&sc->sc_callout, &sc->sc_mtx, 0);
-
- /*
- * Force the report (non-boot) protocol.
- *
- * Mice without boot protocol support may choose not to implement
- * Set_Protocol at all; Ignore any error.
- */
- err = usb2_req_set_protocol(uaa->device, NULL, uaa->info.bIfaceIndex, 1);
-
- err = usb2_transfer_setup(uaa->device,
- &uaa->info.bIfaceIndex, sc->sc_xfer, ums_config,
- UMS_N_TRANSFER, sc, &sc->sc_mtx);
-
- if (err) {
- DPRINTF("error=%s\n", usb2_errstr(err));
- goto detach;
- }
- err = usb2_req_get_hid_desc
- (uaa->device, &Giant, &d_ptr,
- &d_len, M_TEMP, uaa->info.bIfaceIndex);
-
- if (err) {
- device_printf(dev, "error reading report description\n");
- goto detach;
- }
- if (hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
- hid_input, &sc->sc_loc_x, &flags)) {
-
- if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) {
- sc->sc_flags |= UMS_FLAG_X_AXIS;
- }
- }
- if (hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
- hid_input, &sc->sc_loc_y, &flags)) {
-
- if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) {
- sc->sc_flags |= UMS_FLAG_Y_AXIS;
- }
- }
- /* Try the wheel first as the Z activator since it's tradition. */
- if (hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_WHEEL), hid_input, &sc->sc_loc_z, &flags) ||
- hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_TWHEEL), hid_input, &sc->sc_loc_z, &flags)) {
- if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) {
- sc->sc_flags |= UMS_FLAG_Z_AXIS;
- }
- /*
- * We might have both a wheel and Z direction, if so put
- * put the Z on the W coordinate.
- */
- if (hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_Z), hid_input, &sc->sc_loc_w, &flags)) {
-
- if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) {
- sc->sc_flags |= UMS_FLAG_W_AXIS;
- }
- }
- } else if (hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_Z), hid_input, &sc->sc_loc_z, &flags)) {
-
- if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) {
- sc->sc_flags |= UMS_FLAG_Z_AXIS;
- }
- }
- /*
- * The Microsoft Wireless Intellimouse 2.0 reports it's wheel
- * using 0x0048, which is 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(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL),
- hid_input, &sc->sc_loc_t, &flags)) {
-
- sc->sc_loc_t.pos += 8;
-
- if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) {
- sc->sc_flags |= UMS_FLAG_T_AXIS;
- }
- }
- /* figure out the number of buttons */
-
- for (i = 0; i < UMS_BUTTON_MAX; i++) {
- if (!hid_locate(d_ptr, d_len, HID_USAGE2(HUP_BUTTON, (i + 1)),
- hid_input, &sc->sc_loc_btn[i], NULL)) {
- break;
- }
- }
-
- sc->sc_buttons = i;
-
- isize = hid_report_size(d_ptr, d_len, 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 (usb2_test_quirk(uaa, UQ_MS_BAD_CLASS)) {
- sc->sc_flags = (UMS_FLAG_X_AXIS |
- UMS_FLAG_Y_AXIS |
- UMS_FLAG_Z_AXIS |
- UMS_FLAG_SBU);
- sc->sc_buttons = 3;
- 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->info.idVendor == USB_VENDOR_MICROSOFT) &&
- (uaa->info.idProduct == USB_PRODUCT_MICROSOFT_WLNOTEBOOK3)) {
- sc->sc_flags = (UMS_FLAG_X_AXIS |
- UMS_FLAG_Y_AXIS |
- UMS_FLAG_Z_AXIS);
- sc->sc_buttons = 3;
- 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;
- }
- if (usb2_test_quirk(uaa, UQ_MS_REVZ)) {
- /* Some wheels need the Z axis reversed. */
- sc->sc_flags |= UMS_FLAG_REVZ;
- }
- if (isize > sc->sc_xfer[UMS_INTR_DT]->max_frame_size) {
- DPRINTF("WARNING: report size, %d bytes, is larger "
- "than interrupt size, %d bytes!\n",
- isize, sc->sc_xfer[UMS_INTR_DT]->max_frame_size);
- }
- /* announce information about the mouse */
-
- device_printf(dev, "%d buttons and [%s%s%s%s%s] coordinates\n",
- (sc->sc_buttons),
- (sc->sc_flags & UMS_FLAG_X_AXIS) ? "X" : "",
- (sc->sc_flags & UMS_FLAG_Y_AXIS) ? "Y" : "",
- (sc->sc_flags & UMS_FLAG_Z_AXIS) ? "Z" : "",
- (sc->sc_flags & UMS_FLAG_T_AXIS) ? "T" : "",
- (sc->sc_flags & UMS_FLAG_W_AXIS) ? "W" : "");
-
- free(d_ptr, M_TEMP);
- d_ptr = NULL;
-
-#if USB_DEBUG
- DPRINTF("sc=%p\n", sc);
- DPRINTF("X\t%d/%d\n", sc->sc_loc_x.pos, sc->sc_loc_x.size);
- DPRINTF("Y\t%d/%d\n", sc->sc_loc_y.pos, sc->sc_loc_y.size);
- DPRINTF("Z\t%d/%d\n", sc->sc_loc_z.pos, sc->sc_loc_z.size);
- DPRINTF("T\t%d/%d\n", sc->sc_loc_t.pos, sc->sc_loc_t.size);
- DPRINTF("W\t%d/%d\n", sc->sc_loc_w.pos, sc->sc_loc_w.size);
-
- for (i = 0; i < sc->sc_buttons; i++) {
- DPRINTF("B%d\t%d/%d\n",
- i + 1, sc->sc_loc_btn[i].pos, sc->sc_loc_btn[i].size);
- }
- DPRINTF("size=%d, id=%d\n", isize, sc->sc_iid);
-#endif
-
- if (sc->sc_buttons > MOUSE_MSC_MAXBUTTON)
- sc->sc_hw.buttons = MOUSE_MSC_MAXBUTTON;
- else
- sc->sc_hw.buttons = sc->sc_buttons;
-
- sc->sc_hw.iftype = MOUSE_IF_USB;
- sc->sc_hw.type = MOUSE_MOUSE;
- sc->sc_hw.model = MOUSE_MODEL_GENERIC;
- sc->sc_hw.hwid = 0;
-
- sc->sc_mode.protocol = MOUSE_PROTO_MSC;
- sc->sc_mode.rate = -1;
- sc->sc_mode.resolution = MOUSE_RES_UNKNOWN;
- sc->sc_mode.accelfactor = 0;
- sc->sc_mode.level = 0;
- sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE;
- sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
- sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
-
- sc->sc_status.flags = 0;
- sc->sc_status.button = 0;
- sc->sc_status.obutton = 0;
- sc->sc_status.dx = 0;
- sc->sc_status.dy = 0;
- sc->sc_status.dz = 0;
-
- /* set interface permissions */
- usb2_set_iface_perm(uaa->device, uaa->info.bIfaceIndex,
- UID_ROOT, GID_OPERATOR, 0644);
-
- err = usb2_fifo_attach(uaa->device, sc, &sc->sc_mtx,
- &ums_fifo_methods, &sc->sc_fifo,
- unit, 0 - 1, uaa->info.bIfaceIndex);
- if (err) {
- goto detach;
- }
- return (0);
-
-detach:
- if (d_ptr) {
- free(d_ptr, M_TEMP);
- }
- ums_detach(dev);
- return (ENOMEM);
-}
-
-static int
-ums_detach(device_t self)
-{
- struct ums_softc *sc = device_get_softc(self);
-
- DPRINTF("sc=%p\n", sc);
-
- usb2_fifo_detach(&sc->sc_fifo);
-
- usb2_transfer_unsetup(sc->sc_xfer, UMS_N_TRANSFER);
-
- usb2_callout_drain(&sc->sc_callout);
-
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static void
-ums_start_read(struct usb2_fifo *fifo)
-{
- struct ums_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_start(sc->sc_xfer[UMS_INTR_DT]);
-}
-
-static void
-ums_stop_read(struct usb2_fifo *fifo)
-{
- struct ums_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_stop(sc->sc_xfer[UMS_INTR_CS]);
- usb2_transfer_stop(sc->sc_xfer[UMS_INTR_DT]);
- usb2_callout_stop(&sc->sc_callout);
-}
-
-
-#if ((MOUSE_SYS_PACKETSIZE != 8) || \
- (MOUSE_MSC_PACKETSIZE != 5))
-#error "Software assumptions are not met. Please update code."
-#endif
-
-static void
-ums_put_queue(struct ums_softc *sc, int32_t dx, int32_t dy,
- int32_t dz, int32_t dt, int32_t buttons)
-{
- uint8_t buf[8];
-
- if (1) {
-
- 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;
-
- buf[0] = sc->sc_mode.syncmask[1];
- buf[0] |= (~buttons) & MOUSE_MSC_BUTTONS;
- buf[1] = dx >> 1;
- buf[2] = dy >> 1;
- buf[3] = dx - (dx >> 1);
- buf[4] = dy - (dy >> 1);
-
- if (sc->sc_mode.level == 1) {
- buf[5] = dz >> 1;
- buf[6] = dz - (dz >> 1);
- buf[7] = (((~buttons) >> 3) & MOUSE_SYS_EXTBUTTONS);
- }
- usb2_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf,
- sc->sc_mode.packetsize, 1);
-
- } else {
- DPRINTF("Buffer full, discarded packet\n");
- }
-}
-
-static void
-ums_reset_buf(struct ums_softc *sc)
-{
- /* reset read queue */
- usb2_fifo_reset(sc->sc_fifo.fp[USB_FIFO_RX]);
-}
-
-static int
-ums_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- struct ums_softc *sc = fifo->priv_sc0;
-
- DPRINTFN(2, "\n");
-
- if (fflags & FREAD) {
-
- /* reset status */
-
- sc->sc_status.flags = 0;
- sc->sc_status.button = 0;
- sc->sc_status.obutton = 0;
- sc->sc_status.dx = 0;
- sc->sc_status.dy = 0;
- sc->sc_status.dz = 0;
- /* sc->sc_status.dt = 0; */
-
- if (usb2_fifo_alloc_buffer(fifo,
- UMS_BUF_SIZE, UMS_IFQ_MAXLEN)) {
- return (ENOMEM);
- }
- }
- return (0);
-}
-
-static void
-ums_close(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- if (fflags & FREAD) {
- usb2_fifo_free_buffer(fifo);
- }
-}
-
-static int
-ums_ioctl(struct usb2_fifo *fifo, u_long cmd, void *addr,
- int fflags, struct thread *td)
-{
- struct ums_softc *sc = fifo->priv_sc0;
- mousemode_t mode;
- int error = 0;
-
- DPRINTFN(2, "\n");
-
- mtx_lock(&sc->sc_mtx);
-
- switch (cmd) {
- case MOUSE_GETHWINFO:
- *(mousehw_t *)addr = sc->sc_hw;
- break;
-
- case MOUSE_GETMODE:
- *(mousemode_t *)addr = sc->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)) {
- error = EINVAL;
- goto done;
- } else {
- sc->sc_mode.level = mode.level;
- }
-
- if (sc->sc_mode.level == 0) {
- if (sc->sc_buttons > MOUSE_MSC_MAXBUTTON)
- sc->sc_hw.buttons = MOUSE_MSC_MAXBUTTON;
- else
- sc->sc_hw.buttons = sc->sc_buttons;
- sc->sc_mode.protocol = MOUSE_PROTO_MSC;
- sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE;
- sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
- sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
- } else if (sc->sc_mode.level == 1) {
- if (sc->sc_buttons > MOUSE_SYS_MAXBUTTON)
- sc->sc_hw.buttons = MOUSE_SYS_MAXBUTTON;
- else
- sc->sc_hw.buttons = sc->sc_buttons;
- sc->sc_mode.protocol = MOUSE_PROTO_SYSMOUSE;
- sc->sc_mode.packetsize = MOUSE_SYS_PACKETSIZE;
- sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK;
- sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC;
- }
- ums_reset_buf(sc);
- break;
-
- case MOUSE_GETLEVEL:
- *(int *)addr = sc->sc_mode.level;
- break;
-
- case MOUSE_SETLEVEL:
- if (*(int *)addr < 0 || *(int *)addr > 1) {
- error = EINVAL;
- goto done;
- }
- sc->sc_mode.level = *(int *)addr;
-
- if (sc->sc_mode.level == 0) {
- if (sc->sc_buttons > MOUSE_MSC_MAXBUTTON)
- sc->sc_hw.buttons = MOUSE_MSC_MAXBUTTON;
- else
- sc->sc_hw.buttons = sc->sc_buttons;
- sc->sc_mode.protocol = MOUSE_PROTO_MSC;
- sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE;
- sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
- sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
- } else if (sc->sc_mode.level == 1) {
- if (sc->sc_buttons > MOUSE_SYS_MAXBUTTON)
- sc->sc_hw.buttons = MOUSE_SYS_MAXBUTTON;
- else
- sc->sc_hw.buttons = sc->sc_buttons;
- sc->sc_mode.protocol = MOUSE_PROTO_SYSMOUSE;
- sc->sc_mode.packetsize = MOUSE_SYS_PACKETSIZE;
- sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK;
- sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC;
- }
- ums_reset_buf(sc);
- break;
-
- case MOUSE_GETSTATUS:{
- mousestatus_t *status = (mousestatus_t *)addr;
-
- *status = sc->sc_status;
- sc->sc_status.obutton = sc->sc_status.button;
- sc->sc_status.button = 0;
- sc->sc_status.dx = 0;
- sc->sc_status.dy = 0;
- sc->sc_status.dz = 0;
- /* sc->sc_status.dt = 0; */
-
- 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;
- }
-
-done:
- mtx_unlock(&sc->sc_mtx);
- return (error);
-}
-
-static devclass_t ums_devclass;
-
-static device_method_t ums_methods[] = {
- DEVMETHOD(device_probe, ums_probe),
- DEVMETHOD(device_attach, ums_attach),
- DEVMETHOD(device_detach, ums_detach),
- {0, 0}
-};
-
-static driver_t ums_driver = {
- .name = "ums",
- .methods = ums_methods,
- .size = sizeof(struct ums_softc),
-};
-
-DRIVER_MODULE(ums, ushub, ums_driver, ums_devclass, NULL, 0);
-MODULE_DEPEND(ums, usb2_input, 1, 1, 1);
-MODULE_DEPEND(ums, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/input/usb2_input.c b/sys/dev/usb2/input/usb2_input.c
deleted file mode 100644
index 56f9ff2..0000000
--- a/sys/dev/usb2/input/usb2_input.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/input/usb2_input.h>
-
-MODULE_VERSION(usb2_input, 1);
-MODULE_DEPEND(usb2_input, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/input/usb2_input.h b/sys/dev/usb2/input/usb2_input.h
deleted file mode 100644
index 0b51853..0000000
--- a/sys/dev/usb2/input/usb2_input.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_INPUT_H_
-#define _USB2_INPUT_H_
-
-#endif /* _USB2_INPUT_H_ */
diff --git a/sys/dev/usb2/input/usb2_rdesc.h b/sys/dev/usb2/input/usb2_rdesc.h
deleted file mode 100644
index 9f4363d..0000000
--- a/sys/dev/usb2/input/usb2_rdesc.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/*-
- * Copyright (c) 2000 Nick Hibma <n_hibma@freebsd.org>
- * All rights reserved.
- *
- * Copyright (c) 2005 Ed Schouten <ed@fxq.nl>
- * 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$
- *
- * This file contains replacements for broken HID report descriptors.
- */
-
-#define 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 */\
-
-#define 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 */\
-
-/*
- * The descriptor has no output report format, thus preventing you from
- * controlling the LEDs and the built-in rumblers.
- */
-#define 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 */\
-
diff --git a/sys/dev/usb2/misc/udbp2.c b/sys/dev/usb2/misc/udbp2.c
deleted file mode 100644
index b60bbf7..0000000
--- a/sys/dev/usb2/misc/udbp2.c
+++ /dev/null
@@ -1,854 +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
- * streaming, and <5k to avoid overflowing the system with small TDs).
- */
-
-
-/* probe/attach/detach:
- * Connect the driver to the hardware and netgraph
- *
- * 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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR udbp_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_parse.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <sys/mbuf.h>
-
-#include <netgraph/ng_message.h>
-#include <netgraph/netgraph.h>
-#include <netgraph/ng_parse.h>
-#include <netgraph/bluetooth/include/ng_bluetooth.h>
-
-#include <dev/usb2/misc/udbp2.h>
-
-#if USB_DEBUG
-static int udbp_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, udbp, CTLFLAG_RW, 0, "USB udbp");
-SYSCTL_INT(_hw_usb2_udbp, OID_AUTO, debug, CTLFLAG_RW,
- &udbp_debug, 0, "udbp debug level");
-#endif
-
-#define UDBP_TIMEOUT 2000 /* timeout on outbound transfers, in
- * msecs */
-#define UDBP_BUFFERSIZE MCLBYTES /* maximum number of bytes in one
- * transfer */
-#define UDBP_T_WR 0
-#define UDBP_T_RD 1
-#define UDBP_T_WR_CS 2
-#define UDBP_T_RD_CS 3
-#define UDBP_T_MAX 4
-#define UDBP_Q_MAXLEN 50
-
-struct udbp_softc {
-
- struct mtx sc_mtx;
- struct ng_bt_mbufq sc_xmitq_hipri; /* hi-priority transmit queue */
- struct ng_bt_mbufq sc_xmitq; /* low-priority transmit queue */
-
- struct usb2_xfer *sc_xfer[UDBP_T_MAX];
- node_p sc_node; /* back pointer to node */
- hook_p sc_hook; /* pointer to the hook */
- struct mbuf *sc_bulk_in_buffer;
-
- uint32_t sc_packets_in; /* packets in from downstream */
- uint32_t sc_packets_out; /* packets out towards downstream */
-
- uint8_t sc_flags;
-#define UDBP_FLAG_READ_STALL 0x01 /* read transfer stalled */
-#define UDBP_FLAG_WRITE_STALL 0x02 /* write transfer stalled */
-
- uint8_t sc_name[16];
-};
-
-/* prototypes */
-
-static int udbp_modload(module_t mod, int event, void *data);
-
-static device_probe_t udbp_probe;
-static device_attach_t udbp_attach;
-static device_detach_t udbp_detach;
-
-static usb2_callback_t udbp_bulk_read_callback;
-static usb2_callback_t udbp_bulk_read_clear_stall_callback;
-static usb2_callback_t udbp_bulk_write_callback;
-static usb2_callback_t udbp_bulk_write_clear_stall_callback;
-
-static void udbp_bulk_read_complete(node_p, hook_p, void *, int);
-
-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,
-};
-
-/* USB config */
-static const struct usb2_config udbp_config[UDBP_T_MAX] = {
-
- [UDBP_T_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UDBP_BUFFERSIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &udbp_bulk_write_callback,
- .mh.timeout = UDBP_TIMEOUT,
- },
-
- [UDBP_T_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UDBP_BUFFERSIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &udbp_bulk_read_callback,
- },
-
- [UDBP_T_WR_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &udbp_bulk_write_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
-
- [UDBP_T_RD_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &udbp_bulk_read_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
-};
-
-static devclass_t udbp_devclass;
-
-static device_method_t udbp_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, udbp_probe),
- DEVMETHOD(device_attach, udbp_attach),
- DEVMETHOD(device_detach, udbp_detach),
- {0, 0}
-};
-
-static driver_t udbp_driver = {
- .name = "udbp",
- .methods = udbp_methods,
- .size = sizeof(struct udbp_softc),
-};
-
-DRIVER_MODULE(udbp, ushub, udbp_driver, udbp_devclass, udbp_modload, 0);
-MODULE_DEPEND(udbp, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
-MODULE_DEPEND(udbp, usb2_misc, 1, 1, 1);
-MODULE_DEPEND(udbp, usb2_core, 1, 1, 1);
-
-static int
-udbp_modload(module_t mod, int event, void *data)
-{
- int error;
-
- switch (event) {
- case MOD_LOAD:
- error = ng_newtype(&ng_udbp_typestruct);
- if (error != 0) {
- printf("%s: Could not register "
- "Netgraph node type, error=%d\n",
- NG_UDBP_NODE_TYPE, error);
- }
- break;
-
- case MOD_UNLOAD:
- error = ng_rmtype(&ng_udbp_typestruct);
- break;
-
- default:
- error = EOPNOTSUPP;
- break;
- }
- return (error);
-}
-
-static int
-udbp_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- /*
- * 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->info.idVendor == USB_VENDOR_NETCHIP) &&
- (uaa->info.idProduct == USB_PRODUCT_NETCHIP_TURBOCONNECT)))
- return (0);
-
- if (((uaa->info.idVendor == USB_VENDOR_PROLIFIC) &&
- ((uaa->info.idProduct == USB_PRODUCT_PROLIFIC_PL2301) ||
- (uaa->info.idProduct == USB_PRODUCT_PROLIFIC_PL2302))))
- return (0);
-
- if ((uaa->info.idVendor == USB_VENDOR_ANCHOR) &&
- (uaa->info.idProduct == USB_PRODUCT_ANCHOR_EZLINK))
- return (0);
-
- if ((uaa->info.idVendor == USB_VENDOR_GENESYS) &&
- (uaa->info.idProduct == USB_PRODUCT_GENESYS_GL620USB))
- return (0);
-
- return (ENXIO);
-}
-
-static int
-udbp_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct udbp_softc *sc = device_get_softc(dev);
- int error;
-
- device_set_usb2_desc(dev);
-
- snprintf(sc->sc_name, sizeof(sc->sc_name),
- "%s", device_get_nameunit(dev));
-
- mtx_init(&sc->sc_mtx, "udbp lock", NULL, MTX_DEF | MTX_RECURSE);
-
- error = usb2_transfer_setup(uaa->device, &uaa->info.bIfaceIndex,
- sc->sc_xfer, udbp_config, UDBP_T_MAX, sc, &sc->sc_mtx);
- if (error) {
- DPRINTF("error=%s\n", usb2_errstr(error));
- goto detach;
- }
- NG_BT_MBUFQ_INIT(&sc->sc_xmitq, UDBP_Q_MAXLEN);
-
- NG_BT_MBUFQ_INIT(&sc->sc_xmitq_hipri, UDBP_Q_MAXLEN);
-
- /* create Netgraph node */
-
- if (ng_make_node_common(&ng_udbp_typestruct, &sc->sc_node) != 0) {
- printf("%s: Could not create Netgraph node\n",
- sc->sc_name);
- sc->sc_node = NULL;
- goto detach;
- }
- /* name node */
-
- if (ng_name_node(sc->sc_node, sc->sc_name) != 0) {
- printf("%s: Could not name node\n",
- sc->sc_name);
- NG_NODE_UNREF(sc->sc_node);
- sc->sc_node = NULL;
- goto detach;
- }
- NG_NODE_SET_PRIVATE(sc->sc_node, sc);
-
- /* the device is now operational */
-
- return (0); /* success */
-
-detach:
- udbp_detach(dev);
- return (ENOMEM); /* failure */
-}
-
-static int
-udbp_detach(device_t dev)
-{
- struct udbp_softc *sc = device_get_softc(dev);
-
- /* destroy Netgraph node */
-
- if (sc->sc_node != NULL) {
- NG_NODE_SET_PRIVATE(sc->sc_node, NULL);
- ng_rmnode_self(sc->sc_node);
- sc->sc_node = NULL;
- }
- /* free USB transfers, if any */
-
- usb2_transfer_unsetup(sc->sc_xfer, UDBP_T_MAX);
-
- mtx_destroy(&sc->sc_mtx);
-
- /* destroy queues */
-
- NG_BT_MBUFQ_DESTROY(&sc->sc_xmitq);
- NG_BT_MBUFQ_DESTROY(&sc->sc_xmitq_hipri);
-
- /* extra check */
-
- if (sc->sc_bulk_in_buffer) {
- m_freem(sc->sc_bulk_in_buffer);
- sc->sc_bulk_in_buffer = NULL;
- }
- return (0); /* success */
-}
-
-static void
-udbp_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct udbp_softc *sc = xfer->priv_sc;
- struct mbuf *m;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- /* allocate new mbuf */
-
- MGETHDR(m, M_DONTWAIT, MT_DATA);
-
- if (m == NULL) {
- goto tr_setup;
- }
- MCLGET(m, M_DONTWAIT);
-
- if (!(m->m_flags & M_EXT)) {
- m_freem(m);
- goto tr_setup;
- }
- m->m_pkthdr.len = m->m_len = xfer->actlen;
-
- usb2_copy_out(xfer->frbuffers, 0, m->m_data, xfer->actlen);
-
- sc->sc_bulk_in_buffer = m;
-
- DPRINTF("received package %d "
- "bytes\n", xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- if (sc->sc_bulk_in_buffer) {
- ng_send_fn(sc->sc_node, NULL, &udbp_bulk_read_complete, NULL, 0);
- return;
- }
- if (sc->sc_flags & UDBP_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[UDBP_T_RD_CS]);
- return;
- }
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- sc->sc_flags |= UDBP_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[UDBP_T_RD_CS]);
- }
- return;
-
- }
-}
-
-static void
-udbp_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct udbp_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[UDBP_T_RD];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UDBP_FLAG_READ_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
-udbp_bulk_read_complete(node_p node, hook_p hook, void *arg1, int arg2)
-{
- struct udbp_softc *sc = NG_NODE_PRIVATE(node);
- struct mbuf *m;
- int error;
-
- if (sc == NULL) {
- return;
- }
- mtx_lock(&sc->sc_mtx);
-
- m = sc->sc_bulk_in_buffer;
-
- if (m) {
-
- sc->sc_bulk_in_buffer = NULL;
-
- if ((sc->sc_hook == NULL) ||
- NG_HOOK_NOT_VALID(sc->sc_hook)) {
- DPRINTF("No upstream hook\n");
- goto done;
- }
- sc->sc_packets_in++;
-
- NG_SEND_DATA_ONLY(error, sc->sc_hook, m);
-
- m = NULL;
- }
-done:
- if (m) {
- m_freem(m);
- }
- /* start USB bulk-in transfer, if not already started */
-
- usb2_transfer_start(sc->sc_xfer[UDBP_T_RD]);
-
- mtx_unlock(&sc->sc_mtx);
-}
-
-static void
-udbp_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct udbp_softc *sc = xfer->priv_sc;
- struct mbuf *m;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- sc->sc_packets_out++;
-
- case USB_ST_SETUP:
- if (sc->sc_flags & UDBP_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[UDBP_T_WR_CS]);
- return;
- }
- /* get next mbuf, if any */
-
- NG_BT_MBUFQ_DEQUEUE(&sc->sc_xmitq_hipri, m);
- if (m == NULL) {
- NG_BT_MBUFQ_DEQUEUE(&sc->sc_xmitq, m);
- if (m == NULL) {
- DPRINTF("Data queue is empty\n");
- return;
- }
- }
- if (m->m_pkthdr.len > MCLBYTES) {
- DPRINTF("truncating large packet "
- "from %d to %d bytes\n", m->m_pkthdr.len,
- MCLBYTES);
- m->m_pkthdr.len = MCLBYTES;
- }
- usb2_m_copy_in(xfer->frbuffers, 0, m, 0, m->m_pkthdr.len);
-
- xfer->frlengths[0] = m->m_pkthdr.len;
-
- m_freem(m);
-
- DPRINTF("packet out: %d bytes\n",
- xfer->frlengths[0]);
-
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- sc->sc_flags |= UDBP_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[UDBP_T_WR_CS]);
- }
- return;
-
- }
-}
-
-static void
-udbp_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct udbp_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[UDBP_T_WR];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UDBP_FLAG_WRITE_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-/***********************************************************************
- * 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)
-{
- struct udbp_softc *sc = NG_NODE_PRIVATE(node);
- int32_t error = 0;
-
- if (strcmp(name, NG_UDBP_HOOK_NAME)) {
- return (EINVAL);
- }
- mtx_lock(&sc->sc_mtx);
-
- if (sc->sc_hook != NULL) {
- error = EISCONN;
- } else {
- sc->sc_hook = hook;
- NG_HOOK_SET_PRIVATE(hook, NULL);
- }
-
- mtx_unlock(&sc->sc_mtx);
-
- return (error);
-}
-
-/*
- * 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)
-{
- struct udbp_softc *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;
- mtx_lock(&sc->sc_mtx);
- stats->packets_in = sc->sc_packets_in;
- stats->packets_out = sc->sc_packets_out;
- mtx_unlock(&sc->sc_mtx);
- break;
- }
- case NGM_UDBP_SET_FLAG:
- if (msg->header.arglen != sizeof(uint32_t)) {
- error = EINVAL;
- break;
- }
- DPRINTF("flags = 0x%08x\n",
- *((uint32_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)
-{
- struct udbp_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- struct ng_bt_mbufq *queue_ptr;
- struct mbuf *m;
- struct ng_tag_prio *ptag;
- int error;
-
- if (sc == NULL) {
- NG_FREE_ITEM(item);
- return (EHOSTDOWN);
- }
- NGI_GET_M(item, m);
- NG_FREE_ITEM(item);
-
- /*
- * Now queue the data for when it can be sent
- */
- ptag = (void *)m_tag_locate(m, NGM_GENERIC_COOKIE,
- NG_TAG_PRIO, NULL);
-
- if (ptag && (ptag->priority > NG_PRIO_CUTOFF))
- queue_ptr = &sc->sc_xmitq_hipri;
- else
- queue_ptr = &sc->sc_xmitq;
-
- mtx_lock(&sc->sc_mtx);
-
- if (NG_BT_MBUFQ_FULL(queue_ptr)) {
- NG_BT_MBUFQ_DROP(queue_ptr);
- NG_FREE_M(m);
- error = ENOBUFS;
- } else {
- NG_BT_MBUFQ_ENQUEUE(queue_ptr, m);
- /*
- * start bulk-out transfer, if not already started:
- */
- usb2_transfer_start(sc->sc_xfer[UDBP_T_WR]);
- error = 0;
- }
-
- mtx_unlock(&sc->sc_mtx);
-
- 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)
-{
- struct udbp_softc *sc = NG_NODE_PRIVATE(node);
-
- /* Let old node go */
- NG_NODE_SET_PRIVATE(node, NULL);
- NG_NODE_UNREF(node); /* forget it ever existed */
-
- if (sc == NULL) {
- goto done;
- }
- /* Create Netgraph node */
- if (ng_make_node_common(&ng_udbp_typestruct, &sc->sc_node) != 0) {
- printf("%s: Could not create Netgraph node\n",
- sc->sc_name);
- sc->sc_node = NULL;
- goto done;
- }
- /* Name node */
- if (ng_name_node(sc->sc_node, sc->sc_name) != 0) {
- printf("%s: Could not name Netgraph node\n",
- sc->sc_name);
- NG_NODE_UNREF(sc->sc_node);
- sc->sc_node = NULL;
- goto done;
- }
- NG_NODE_SET_PRIVATE(sc->sc_node, sc);
-
-done:
- if (sc) {
- mtx_unlock(&sc->sc_mtx);
- }
- return (0);
-}
-
-/*
- * 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)
-{
- struct udbp_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
-
- /* probably not at splnet, force outward queueing */
- NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
-
- mtx_lock(&sc->sc_mtx);
-
- sc->sc_flags |= (UDBP_FLAG_READ_STALL |
- UDBP_FLAG_WRITE_STALL);
-
- /* start bulk-in transfer */
- usb2_transfer_start(sc->sc_xfer[UDBP_T_RD]);
-
- /* start bulk-out transfer */
- usb2_transfer_start(sc->sc_xfer[UDBP_T_WR]);
-
- mtx_unlock(&sc->sc_mtx);
-
- return (0);
-}
-
-/*
- * Dook disconnection
- *
- * For this type, removal of the last link destroys the node
- */
-static int
-ng_udbp_disconnect(hook_p hook)
-{
- struct udbp_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- int error = 0;
-
- if (sc != NULL) {
-
- mtx_lock(&sc->sc_mtx);
-
- if (hook != sc->sc_hook) {
- error = EINVAL;
- } else {
-
- /* stop bulk-in transfer */
- usb2_transfer_stop(sc->sc_xfer[UDBP_T_RD_CS]);
- usb2_transfer_stop(sc->sc_xfer[UDBP_T_RD]);
-
- /* stop bulk-out transfer */
- usb2_transfer_stop(sc->sc_xfer[UDBP_T_WR_CS]);
- usb2_transfer_stop(sc->sc_xfer[UDBP_T_WR]);
-
- /* cleanup queues */
- NG_BT_MBUFQ_DRAIN(&sc->sc_xmitq);
- NG_BT_MBUFQ_DRAIN(&sc->sc_xmitq_hipri);
-
- if (sc->sc_bulk_in_buffer) {
- m_freem(sc->sc_bulk_in_buffer);
- sc->sc_bulk_in_buffer = NULL;
- }
- sc->sc_hook = NULL;
- }
-
- mtx_unlock(&sc->sc_mtx);
- }
- 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 (error);
-}
diff --git a/sys/dev/usb2/misc/udbp2.h b/sys/dev/usb2/misc/udbp2.h
deleted file mode 100644
index e6fd853..0000000
--- a/sys/dev/usb2/misc/udbp2.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 {
- uint32_t packets_in; /* packets in from downstream */
- uint32_t packets_out; /* packets out towards downstream */
-};
-
-/*
- * This is used to define the 'parse type' for a struct ngudbpstat, which
- * is bascially a description of how to convert a binary struct ngudbpstat
- * to an ASCII string and back. See ng_parse.h for more info.
- *
- * This needs to be kept in sync with the above structure definition
- */
-#define NG_UDBP_STATS_TYPE_INFO { \
- { "packets_in", &ng_parse_int32_type }, \
- { "packets_out", &ng_parse_int32_type }, \
- { NULL }, \
-}
-
-#endif /* _NETGRAPH_UDBP_H_ */
diff --git a/sys/dev/usb2/misc/ufm2.c b/sys/dev/usb2/misc/ufm2.c
deleted file mode 100644
index df62436..0000000
--- a/sys/dev/usb2/misc/ufm2.c
+++ /dev/null
@@ -1,330 +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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/ufm2_ioctl.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-#include <dev/usb2/core/usb2_dev.h>
-
-#define UFM_CMD0 0x00
-#define UFM_CMD_SET_FREQ 0x01
-#define UFM_CMD2 0x02
-
-struct ufm_softc {
- struct usb2_fifo_sc sc_fifo;
- struct mtx sc_mtx;
-
- struct usb2_device *sc_udev;
-
- uint32_t sc_unit;
- uint32_t sc_freq;
-
- uint8_t sc_name[16];
-};
-
-/* prototypes */
-
-static device_probe_t ufm_probe;
-static device_attach_t ufm_attach;
-static device_detach_t ufm_detach;
-
-static usb2_fifo_ioctl_t ufm_ioctl;
-static usb2_fifo_open_t ufm_open;
-
-static struct usb2_fifo_methods ufm_fifo_methods = {
- .f_ioctl = &ufm_ioctl,
- .f_open = &ufm_open,
- .basename[0] = "ufm",
-};
-
-static int ufm_do_req(struct ufm_softc *, uint8_t, uint16_t, uint16_t,
- uint8_t *);
-static int ufm_set_freq(struct ufm_softc *, void *);
-static int ufm_get_freq(struct ufm_softc *, void *);
-static int ufm_start(struct ufm_softc *, void *);
-static int ufm_stop(struct ufm_softc *, void *);
-static int ufm_get_stat(struct ufm_softc *, void *);
-
-static devclass_t ufm_devclass;
-
-static device_method_t ufm_methods[] = {
- DEVMETHOD(device_probe, ufm_probe),
- DEVMETHOD(device_attach, ufm_attach),
- DEVMETHOD(device_detach, ufm_detach),
- {0, 0}
-};
-
-static driver_t ufm_driver = {
- .name = "ufm",
- .methods = ufm_methods,
- .size = sizeof(struct ufm_softc),
-};
-
-MODULE_DEPEND(ufm, usb2_misc, 1, 1, 1);
-DRIVER_MODULE(ufm, ushub, ufm_driver, ufm_devclass, NULL, 0);
-MODULE_DEPEND(ufm, usb2_core, 1, 1, 1);
-
-static int
-ufm_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if ((uaa->info.idVendor == USB_VENDOR_CYPRESS) &&
- (uaa->info.idProduct == USB_PRODUCT_CYPRESS_FMRADIO)) {
- return (0);
- }
- return (ENXIO);
-}
-
-static int
-ufm_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ufm_softc *sc = device_get_softc(dev);
- int error;
-
- sc->sc_udev = uaa->device;
- sc->sc_unit = device_get_unit(dev);
-
- snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
- device_get_nameunit(dev));
-
- mtx_init(&sc->sc_mtx, "ufm lock", NULL, MTX_DEF | MTX_RECURSE);
-
- device_set_usb2_desc(dev);
-
- /* set interface permissions */
- usb2_set_iface_perm(uaa->device, uaa->info.bIfaceIndex,
- UID_ROOT, GID_OPERATOR, 0644);
-
- error = usb2_fifo_attach(uaa->device, sc, &sc->sc_mtx,
- &ufm_fifo_methods, &sc->sc_fifo,
- device_get_unit(dev), 0 - 1, uaa->info.bIfaceIndex);
- if (error) {
- goto detach;
- }
- return (0); /* success */
-
-detach:
- ufm_detach(dev);
- return (ENXIO);
-}
-
-static int
-ufm_detach(device_t dev)
-{
- struct ufm_softc *sc = device_get_softc(dev);
-
- usb2_fifo_detach(&sc->sc_fifo);
-
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static int
-ufm_open(struct usb2_fifo *dev, int fflags, struct thread *td)
-{
- if ((fflags & (FWRITE | FREAD)) != (FWRITE | FREAD)) {
- return (EACCES);
- }
- return (0);
-}
-
-static int
-ufm_do_req(struct ufm_softc *sc, uint8_t request,
- uint16_t value, uint16_t index, uint8_t *retbuf)
-{
- int error;
-
- struct usb2_device_request req;
- uint8_t buf[1];
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = request;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, 1);
-
- error = usb2_do_request(sc->sc_udev, NULL, &req, buf);
-
- if (retbuf) {
- *retbuf = buf[0];
- }
- if (error) {
- return (ENXIO);
- }
- return (0);
-}
-
-static int
-ufm_set_freq(struct ufm_softc *sc, void *addr)
-{
- int freq = *(int *)addr;
-
- /*
- * 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.
- */
- mtx_lock(&sc->sc_mtx);
- sc->sc_freq = freq;
- mtx_unlock(&sc->sc_mtx);
-
- freq = (freq + 10700001) / 12500;
-
- /* This appears to set the frequency */
- if (ufm_do_req(sc, UFM_CMD_SET_FREQ,
- freq >> 8, freq, NULL) != 0) {
- return (EIO);
- }
- /* Not sure what this does */
- if (ufm_do_req(sc, UFM_CMD0,
- 0x96, 0xb7, NULL) != 0) {
- return (EIO);
- }
- return (0);
-}
-
-static int
-ufm_get_freq(struct ufm_softc *sc, void *addr)
-{
- int *valp = (int *)addr;
-
- mtx_lock(&sc->sc_mtx);
- *valp = sc->sc_freq;
- mtx_unlock(&sc->sc_mtx);
- return (0);
-}
-
-static int
-ufm_start(struct ufm_softc *sc, void *addr)
-{
- uint8_t ret;
-
- if (ufm_do_req(sc, UFM_CMD0,
- 0x00, 0xc7, &ret)) {
- return (EIO);
- }
- if (ufm_do_req(sc, UFM_CMD2,
- 0x01, 0x00, &ret)) {
- return (EIO);
- }
- if (ret & 0x1) {
- return (EIO);
- }
- return (0);
-}
-
-static int
-ufm_stop(struct ufm_softc *sc, void *addr)
-{
- if (ufm_do_req(sc, UFM_CMD0,
- 0x16, 0x1C, NULL)) {
- return (EIO);
- }
- if (ufm_do_req(sc, UFM_CMD2,
- 0x00, 0x00, NULL)) {
- return (EIO);
- }
- return (0);
-}
-
-static int
-ufm_get_stat(struct ufm_softc *sc, void *addr)
-{
- uint8_t ret;
-
- /*
- * Note, there's a 240ms settle time before the status
- * will be valid, so sleep that amount.
- */
- usb2_pause_mtx(NULL, hz / 4);
-
- if (ufm_do_req(sc, UFM_CMD0,
- 0x00, 0x24, &ret)) {
- return (EIO);
- }
- *(int *)addr = ret;
-
- return (0);
-}
-
-static int
-ufm_ioctl(struct usb2_fifo *fifo, u_long cmd, void *addr,
- int fflags, struct thread *td)
-{
- struct ufm_softc *sc = fifo->priv_sc0;
- int error = 0;
-
- 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:
- error = ENOTTY;
- break;
- }
- return (error);
-}
diff --git a/sys/dev/usb2/misc/usb2_misc.c b/sys/dev/usb2/misc/usb2_misc.c
deleted file mode 100644
index 74eb6c5..0000000
--- a/sys/dev/usb2/misc/usb2_misc.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/misc/usb2_misc.h>
-
-MODULE_VERSION(usb2_misc, 1);
-MODULE_DEPEND(usb2_misc, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/misc/usb2_misc.h b/sys/dev/usb2/misc/usb2_misc.h
deleted file mode 100644
index dabf9e3..0000000
--- a/sys/dev/usb2/misc/usb2_misc.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_MISC_H_
-#define _USB2_MISC_H_
-
-#endif /* _USB2_MISC_H_ */
diff --git a/sys/dev/usb2/ndis/if_ndis_usb2.c b/sys/dev/usb2/ndis/if_ndis_usb2.c
deleted file mode 100644
index 3e2aaa2..0000000
--- a/sys/dev/usb2/ndis/if_ndis_usb2.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*-
- * Copyright (c) 2005
- * Bill Paul <wpaul@windriver.com>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#include <dev/usb2/core/usb2_core.h>
-
-#include <sys/socket.h>
-#include <sys/rman.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/bpf.h>
-
-#include <net80211/ieee80211_var.h>
-
-#include <compat/ndis/pe_var.h>
-#include <compat/ndis/cfg_var.h>
-#include <compat/ndis/resource_var.h>
-#include <compat/ndis/ntoskrnl_var.h>
-#include <compat/ndis/ndis_var.h>
-
-#include <dev/if_ndis/if_ndisvar.h>
-
-MODULE_DEPEND(ndis, usb2_ndis, 1, 1, 1);
-MODULE_DEPEND(ndis, usb2_core, 1, 1, 1);
-MODULE_DEPEND(ndis, ndisapi, 1, 1, 1);
-MODULE_DEPEND(ndis, if_ndis, 1, 1, 1);
-
-static device_probe_t ndisusb2_probe;
-static device_attach_t ndisusb2_attach;
-static struct resource_list *ndis_get_resource_list(device_t, device_t);
-
-extern device_attach_t ndis_attach;
-extern device_shutdown_t ndis_shutdown;
-extern device_detach_t ndis_detach;
-extern device_suspend_t ndis_suspend;
-extern device_resume_t ndis_resume;
-extern int ndisdrv_modevent(module_t, int, void *);
-
-extern unsigned char drv_data[];
-
-static device_method_t ndis_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ndisusb2_probe),
- DEVMETHOD(device_attach, ndisusb2_attach),
- DEVMETHOD(device_detach, ndis_detach),
- DEVMETHOD(device_shutdown, ndis_shutdown),
-
- /* bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
- DEVMETHOD(bus_get_resource_list, ndis_get_resource_list),
-
- {0, 0}
-};
-
-static driver_t ndis_driver = {
- "ndis",
- ndis_methods,
- sizeof(struct ndis_softc)
-};
-
-static devclass_t ndis_devclass;
-
-DRIVER_MODULE(ndis, ushub, ndis_driver, ndis_devclass, ndisdrv_modevent, 0);
-
-static int
-ndisusb2_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (windrv_lookup(0, "USB Bus") == NULL) {
- return (ENXIO);
- }
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- return (ENXIO);
-}
-
-static int
-ndisusb2_attach(device_t dev)
-{
- struct ndis_softc *sc = device_get_softc(dev);
- driver_object *drv;
-
- sc->ndis_dev = dev;
-
- /* Create PDO for this device instance */
-
- drv = windrv_lookup(0, "USB Bus");
- windrv_create_pdo(drv, dev);
-
- if (ndis_attach(dev) != 0) {
- return (ENXIO);
- }
- return (0); /* success */
-}
-
-static struct resource_list *
-ndis_get_resource_list(device_t dev, device_t child)
-{
- struct ndis_softc *sc = device_get_softc(dev);
-
- return (BUS_GET_RESOURCE_LIST(device_get_parent(sc->ndis_dev), dev));
-}
diff --git a/sys/dev/usb2/ndis/usb2_ndis.c b/sys/dev/usb2/ndis/usb2_ndis.c
deleted file mode 100644
index 1776e0d..0000000
--- a/sys/dev/usb2/ndis/usb2_ndis.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/ndis/usb2_ndis.h>
-
-MODULE_VERSION(usb2_ndis, 1);
-MODULE_DEPEND(usb2_ndis, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/ndis/usb2_ndis.h b/sys/dev/usb2/ndis/usb2_ndis.h
deleted file mode 100644
index 7f187e1..0000000
--- a/sys/dev/usb2/ndis/usb2_ndis.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_NDIS_H_
-#define _USB2_NDIS_H_
-
-#endif /* _USB2_NDIS_H_ */
diff --git a/sys/dev/usb2/quirk/usb2_quirk.c b/sys/dev/usb2/quirk/usb2_quirk.c
deleted file mode 100644
index f86be0a..0000000
--- a/sys/dev/usb2/quirk/usb2_quirk.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
- * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include "usbdevs.h"
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-
-#include <dev/usb2/quirk/usb2_quirk.h>
-
-MODULE_DEPEND(usb2_quirk, usb2_core, 1, 1, 1);
-MODULE_VERSION(usb2_quirk, 1);
-
-/*
- * The following macro adds one or more quirks for a USB device:
- */
-#define USB_QUIRK_ENTRY(v,p,l,h,...) \
- .vid = (v), .pid = (p), .lo_rev = (l), .hi_rev = (h), .quirks = { __VA_ARGS__ }
-
-#define USB_DEV_QUIRKS_MAX 128
-#define USB_SUB_QUIRKS_MAX 8
-
-struct usb2_quirk_entry {
- uint16_t vid;
- uint16_t pid;
- uint16_t lo_rev;
- uint16_t hi_rev;
- uint16_t quirks[USB_SUB_QUIRKS_MAX];
-};
-
-static struct mtx usb2_quirk_mtx;
-
-static struct usb2_quirk_entry usb2_quirks[USB_DEV_QUIRKS_MAX] = {
- {USB_QUIRK_ENTRY(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_LCM, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4, 0x094, 0x094, UQ_SWAP_UNICODE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, 0x0a2, UQ_BAD_ADC, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, 0x0a2, UQ_AU_NO_XU, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, 0x103, 0x103, UQ_BAD_ADC, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495, 0x000, 0x000, UQ_BAD_AUDIO, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, 0x110, 0x110, UQ_SPUR_BUT_UP, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB, 0x001, 0x001, UQ_SPUR_BUT_UP, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100, 0x102, 0x102, UQ_BUS_POWERED, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, 0x102, 0x102, UQ_BUS_POWERED, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, 0x110, 0x110, UQ_POWER_CLAIM, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0x009, 0x009, UQ_AU_NO_FRAC, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE, 0x100, 0x100, UQ_AU_INP_ASYNC, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN53B, 0x0000, 0xFFFF, UQ_NO_STRINGS, UQ_NONE)},
-
- /*
- * XXX The following quirks should have a more specific revision
- * number:
- */
- {USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_895C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_880C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_815C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_810C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_830C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_HP, USB_PRODUCT_HP_1220C, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_XEROX, USB_PRODUCT_XEROX_WCM15, 0x0000, 0xFFFF, UQ_BROKEN_BIDIR, UQ_NONE)},
- /* Devices which should be ignored by uhid */
- {USB_QUIRK_ENTRY(USB_VENDOR_APC, USB_PRODUCT_APC_UPS, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_1500CAVRLCD, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD2X20, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD4X20, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G, 0x0000, 0xFFFF, UQ_HID_IGNORE, UQ_NONE)},
- /* Devices which should be ignored by both ukbd and uhid */
- {USB_QUIRK_ENTRY(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_WISPY1A, 0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY1B, 0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_TENX, USB_PRODUCT_TENX_UAUDIO0, 0x0101, 0x0101, UQ_AUDIO_SWAP_LR, UQ_NONE)},
- /* MS keyboards do weird things */
- {USB_QUIRK_ENTRY(USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK, 0x0000, 0xFFFF, UQ_MS_BAD_CLASS, UQ_MS_LEADING_BYTE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK2, 0x0000, 0xFFFF, UQ_MS_BAD_CLASS, UQ_MS_LEADING_BYTE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE, 0x0000, 0xFFFF, UQ_MS_LEADING_BYTE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_COMFORT3000, 0x0000, 0xFFFF, UQ_MS_BAD_CLASS, UQ_MS_LEADING_BYTE, UQ_NONE)},
- {USB_QUIRK_ENTRY(USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24X, 0x0000, 0xFFFF, UQ_KBD_IGNORE, UQ_HID_IGNORE, UQ_NONE)},
-};
-
-static const char *usb_quirk_str[USB_QUIRK_MAX] = {
- [UQ_NONE] = "UQ_NONE",
- [UQ_AUDIO_SWAP_LR] = "UQ_AUDIO_SWAP_LR",
- [UQ_AU_INP_ASYNC] = "UQ_AU_INP_ASYNC",
- [UQ_AU_NO_FRAC] = "UQ_AU_NO_FRAC",
- [UQ_AU_NO_XU] = "UQ_AU_NO_XU",
- [UQ_BAD_ADC] = "UQ_BAD_ADC",
- [UQ_BAD_AUDIO] = "UQ_BAD_AUDIO",
- [UQ_BROKEN_BIDIR] = "UQ_BROKEN_BIDIR",
- [UQ_BUS_POWERED] = "UQ_BUS_POWERED",
- [UQ_HID_IGNORE] = "UQ_HID_IGNORE",
- [UQ_KBD_IGNORE] = "UQ_KBD_IGNORE",
- [UQ_MS_BAD_CLASS] = "UQ_MS_BAD_CLASS",
- [UQ_MS_LEADING_BYTE] = "UQ_MS_LEADING_BYTE",
- [UQ_MS_REVZ] = "UQ_MS_REVZ",
- [UQ_NO_STRINGS] = "UQ_NO_STRINGS",
- [UQ_OPEN_CLEARSTALL] = "UQ_OPEN_CLEARSTALL",
- [UQ_POWER_CLAIM] = "UQ_POWER_CLAIM",
- [UQ_SPUR_BUT_UP] = "UQ_SPUR_BUT_UP",
- [UQ_SWAP_UNICODE] = "UQ_SWAP_UNICODE",
- [UQ_CFG_INDEX_1] = "UQ_CFG_INDEX_1",
- [UQ_CFG_INDEX_2] = "UQ_CFG_INDEX_2",
- [UQ_CFG_INDEX_3] = "UQ_CFG_INDEX_3",
- [UQ_CFG_INDEX_4] = "UQ_CFG_INDEX_4",
- [UQ_CFG_INDEX_0] = "UQ_CFG_INDEX_0",
-};
-
-/*------------------------------------------------------------------------*
- * usb2_quirkstr
- *
- * This function converts an USB quirk code into a string.
- *------------------------------------------------------------------------*/
-static const char *
-usb2_quirkstr(uint16_t quirk)
-{
- return ((quirk < USB_QUIRK_MAX) ?
- usb_quirk_str[quirk] : "USB_QUIRK_UNKNOWN");
-}
-
-/*------------------------------------------------------------------------*
- * usb2_test_quirk_by_info
- *
- * Returns:
- * 0: Quirk not found
- * Else: Quirk found
- *------------------------------------------------------------------------*/
-static uint8_t
-usb2_test_quirk_by_info(const struct usb2_lookup_info *info, uint16_t quirk)
-{
- uint16_t x;
- uint16_t y;
-
- if (quirk == UQ_NONE) {
- return (0);
- }
- mtx_lock(&usb2_quirk_mtx);
-
- for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) {
- /* see if quirk information does not match */
- if ((usb2_quirks[x].vid != info->idVendor) ||
- (usb2_quirks[x].pid != info->idProduct) ||
- (usb2_quirks[x].lo_rev > info->bcdDevice) ||
- (usb2_quirks[x].hi_rev < info->bcdDevice)) {
- continue;
- }
- /* lookup quirk */
- for (y = 0; y != USB_SUB_QUIRKS_MAX; y++) {
- if (usb2_quirks[x].quirks[y] == quirk) {
- mtx_unlock(&usb2_quirk_mtx);
- DPRINTF("Found quirk '%s'.\n", usb2_quirkstr(quirk));
- return (1);
- }
- }
- /* no quirk found */
- break;
- }
- mtx_unlock(&usb2_quirk_mtx);
- return (0);
-}
-
-static struct usb2_quirk_entry *
-usb2_quirk_get_entry(uint16_t vid, uint16_t pid,
- uint16_t lo_rev, uint16_t hi_rev, uint8_t do_alloc)
-{
- uint16_t x;
-
- mtx_assert(&usb2_quirk_mtx, MA_OWNED);
-
- if ((vid | pid | lo_rev | hi_rev) == 0) {
- /* all zero - special case */
- return (usb2_quirks + USB_DEV_QUIRKS_MAX - 1);
- }
- /* search for an existing entry */
- for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) {
- /* see if quirk information does not match */
- if ((usb2_quirks[x].vid != vid) ||
- (usb2_quirks[x].pid != pid) ||
- (usb2_quirks[x].lo_rev != lo_rev) ||
- (usb2_quirks[x].hi_rev != hi_rev)) {
- continue;
- }
- return (usb2_quirks + x);
- }
-
- if (do_alloc == 0) {
- /* no match */
- return (NULL);
- }
- /* search for a free entry */
- for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) {
- /* see if quirk information does not match */
- if ((usb2_quirks[x].vid |
- usb2_quirks[x].pid |
- usb2_quirks[x].lo_rev |
- usb2_quirks[x].hi_rev) != 0) {
- continue;
- }
- usb2_quirks[x].vid = vid;
- usb2_quirks[x].pid = pid;
- usb2_quirks[x].lo_rev = lo_rev;
- usb2_quirks[x].hi_rev = hi_rev;
-
- return (usb2_quirks + x);
- }
-
- /* no entry found */
- return (NULL);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_quirk_ioctl - handle quirk IOCTLs
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static int
-usb2_quirk_ioctl(unsigned long cmd, caddr_t data,
- int fflag, struct thread *td)
-{
- struct usb2_gen_quirk *pgq;
- struct usb2_quirk_entry *pqe;
- uint32_t x;
- uint32_t y;
- int err;
-
- switch (cmd) {
- case USB_DEV_QUIRK_GET:
- pgq = (void *)data;
- x = pgq->index % USB_SUB_QUIRKS_MAX;
- y = pgq->index / USB_SUB_QUIRKS_MAX;
- if (y >= USB_DEV_QUIRKS_MAX) {
- return (EINVAL);
- }
- mtx_lock(&usb2_quirk_mtx);
- /* copy out data */
- pgq->vid = usb2_quirks[y].vid;
- pgq->pid = usb2_quirks[y].pid;
- pgq->bcdDeviceLow = usb2_quirks[y].lo_rev;
- pgq->bcdDeviceHigh = usb2_quirks[y].hi_rev;
- strlcpy(pgq->quirkname,
- usb2_quirkstr(usb2_quirks[y].quirks[x]),
- sizeof(pgq->quirkname));
- mtx_unlock(&usb2_quirk_mtx);
- return (0); /* success */
-
- case USB_QUIRK_NAME_GET:
- pgq = (void *)data;
- x = pgq->index;
- if (x >= USB_QUIRK_MAX) {
- return (EINVAL);
- }
- strlcpy(pgq->quirkname,
- usb2_quirkstr(x), sizeof(pgq->quirkname));
- return (0); /* success */
-
- case USB_DEV_QUIRK_ADD:
- pgq = (void *)data;
-
- /* check privileges */
- err = priv_check(curthread, PRIV_DRIVER);
- if (err) {
- return (err);
- }
- /* convert quirk string into numerical */
- for (y = 0; y != USB_DEV_QUIRKS_MAX; y++) {
- if (strcmp(pgq->quirkname, usb2_quirkstr(y)) == 0) {
- break;
- }
- }
- if (y == USB_DEV_QUIRKS_MAX) {
- return (EINVAL);
- }
- if (y == UQ_NONE) {
- return (EINVAL);
- }
- mtx_lock(&usb2_quirk_mtx);
- pqe = usb2_quirk_get_entry(pgq->vid, pgq->pid,
- pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 1);
- for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
- if (pqe->quirks[x] == UQ_NONE) {
- pqe->quirks[x] = y;
- break;
- }
- }
- mtx_unlock(&usb2_quirk_mtx);
- if (x == USB_SUB_QUIRKS_MAX) {
- return (ENOMEM);
- }
- return (0); /* success */
-
- case USB_DEV_QUIRK_REMOVE:
- pgq = (void *)data;
- /* check privileges */
- err = priv_check(curthread, PRIV_DRIVER);
- if (err) {
- return (err);
- }
- /* convert quirk string into numerical */
- for (y = 0; y != USB_DEV_QUIRKS_MAX; y++) {
- if (strcmp(pgq->quirkname, usb2_quirkstr(y)) == 0) {
- break;
- }
- }
- if (y == USB_DEV_QUIRKS_MAX) {
- return (EINVAL);
- }
- if (y == UQ_NONE) {
- return (EINVAL);
- }
- mtx_lock(&usb2_quirk_mtx);
- pqe = usb2_quirk_get_entry(pgq->vid, pgq->pid,
- pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 0);
- for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
- if (pqe->quirks[x] == y) {
- pqe->quirks[x] = UQ_NONE;
- break;
- }
- }
- if (x == USB_SUB_QUIRKS_MAX) {
- mtx_unlock(&usb2_quirk_mtx);
- return (ENOMEM);
- }
- for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
- if (pqe->quirks[x] != UQ_NONE) {
- break;
- }
- }
- if (x == USB_SUB_QUIRKS_MAX) {
- /* all quirk entries are unused - release */
- memset(pqe, 0, sizeof(pqe));
- }
- mtx_unlock(&usb2_quirk_mtx);
- return (0); /* success */
-
- default:
- break;
- }
- return (ENOIOCTL);
-}
-
-static void
-usb2_quirk_init(void *arg)
-{
- /* initialize mutex */
- mtx_init(&usb2_quirk_mtx, "USB quirk", NULL, MTX_DEF);
-
- /* register our function */
- usb2_test_quirk_p = &usb2_test_quirk_by_info;
- usb2_quirk_ioctl_p = &usb2_quirk_ioctl;
-}
-
-static void
-usb2_quirk_uninit(void *arg)
-{
- usb2_quirk_unload(arg);
-
- /* destroy mutex */
- mtx_destroy(&usb2_quirk_mtx);
-}
-
-SYSINIT(usb2_quirk_init, SI_SUB_LOCK, SI_ORDER_FIRST, usb2_quirk_init, NULL);
-SYSUNINIT(usb2_quirk_uninit, SI_SUB_LOCK, SI_ORDER_ANY, usb2_quirk_uninit, NULL);
diff --git a/sys/dev/usb2/quirk/usb2_quirk.h b/sys/dev/usb2/quirk/usb2_quirk.h
deleted file mode 100644
index c9223e8..0000000
--- a/sys/dev/usb2/quirk/usb2_quirk.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_QUIRK_H_
-#define _USB2_QUIRK_H_
-
-/* NOTE: UQ_NONE is not a valid quirk */
-enum { /* keep in sync with usb_quirk_str table */
- UQ_NONE,
- UQ_AUDIO_SWAP_LR, /* left and right sound channels are swapped */
- UQ_AU_INP_ASYNC, /* input is async despite claim of adaptive */
- UQ_AU_NO_FRAC, /* don't adjust for fractional samples */
- UQ_AU_NO_XU, /* audio device has broken extension unit */
- UQ_BAD_ADC, /* bad audio spec version number */
- UQ_BAD_AUDIO, /* device claims audio class, but isn't */
- UQ_BROKEN_BIDIR, /* printer has broken bidir mode */
- UQ_BUS_POWERED, /* device is bus powered, despite claim */
- UQ_HID_IGNORE, /* device should be ignored by hid class */
- UQ_KBD_IGNORE, /* device should be ignored by kbd class */
- UQ_MS_BAD_CLASS, /* doesn't identify properly */
- UQ_MS_LEADING_BYTE, /* mouse sends an unknown leading byte */
- UQ_MS_REVZ, /* mouse has Z-axis reversed */
- UQ_NO_STRINGS, /* string descriptors are broken */
- UQ_OPEN_CLEARSTALL, /* device needs clear endpoint stall */
- UQ_POWER_CLAIM, /* hub lies about power status */
- UQ_SPUR_BUT_UP, /* spurious mouse button up events */
- UQ_SWAP_UNICODE, /* has some Unicode strings swapped */
- UQ_CFG_INDEX_1, /* select configuration index 1 by default */
- UQ_CFG_INDEX_2, /* select configuration index 2 by default */
- UQ_CFG_INDEX_3, /* select configuration index 3 by default */
- UQ_CFG_INDEX_4, /* select configuration index 4 by default */
- UQ_CFG_INDEX_0, /* select configuration index 0 by default */
- USB_QUIRK_MAX
-};
-
-#endif /* _USB2_QUIRK_H_ */
diff --git a/sys/dev/usb2/serial/u3g2.c b/sys/dev/usb2/serial/u3g2.c
deleted file mode 100644
index e97c671..0000000
--- a/sys/dev/usb2/serial/u3g2.c
+++ /dev/null
@@ -1,583 +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$
- */
-
-/*
- * NOTE:
- *
- * - 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.
- *
- * NOTE:
- *
- * - The device ID's are stored in "core/usb2_msctest.c"
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR u3g_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_msctest.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-#include <dev/usb2/core/usb2_device.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#if USB_DEBUG
-static int u3g_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, u3g, CTLFLAG_RW, 0, "USB u3g");
-SYSCTL_INT(_hw_usb2_u3g, OID_AUTO, debug, CTLFLAG_RW,
- &u3g_debug, 0, "u3g debug level");
-#endif
-
-#define U3G_MAXPORTS 4
-#define U3G_CONFIG_INDEX 0
-#define U3G_BSIZE 2048
-
-#define U3GSP_GPRS 0
-#define U3GSP_EDGE 1
-#define U3GSP_CDMA 2
-#define U3GSP_UMTS 3
-#define U3GSP_HSDPA 4
-#define U3GSP_HSUPA 5
-#define U3GSP_HSPA 6
-#define U3GSP_MAX 7
-
-#define U3GFL_NONE 0x00 /* No flags */
-#define U3GFL_HUAWEI_INIT 0x01 /* Init command required */
-#define U3GFL_SCSI_EJECT 0x02 /* SCSI eject command required */
-#define U3GFL_SIERRA_INIT 0x04 /* Init command required */
-
-struct u3g_speeds_s {
- uint32_t ispeed;
- uint32_t ospeed;
-};
-
-enum {
- U3G_BULK_WR,
- U3G_BULK_RD,
- U3G_N_TRANSFER,
-};
-
-struct u3g_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom[U3G_MAXPORTS];
-
- struct usb2_xfer *sc_xfer[U3G_MAXPORTS][U3G_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint8_t sc_lsr; /* local status register */
- uint8_t sc_msr; /* U3G status register */
- uint8_t sc_numports;
-};
-
-static device_probe_t u3g_probe;
-static device_attach_t u3g_attach;
-static device_detach_t u3g_detach;
-
-static usb2_callback_t u3g_write_callback;
-static usb2_callback_t u3g_read_callback;
-
-static void u3g_start_read(struct usb2_com_softc *ucom);
-static void u3g_stop_read(struct usb2_com_softc *ucom);
-static void u3g_start_write(struct usb2_com_softc *ucom);
-static void u3g_stop_write(struct usb2_com_softc *ucom);
-
-static int u3g_driver_loaded(struct module *mod, int what, void *arg);
-
-static const struct usb2_config u3g_config[U3G_N_TRANSFER] = {
-
- [U3G_BULK_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = U3G_BSIZE,/* bytes */
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &u3g_write_callback,
- },
-
- [U3G_BULK_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = U3G_BSIZE,/* bytes */
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &u3g_read_callback,
- },
-};
-
-static const struct usb2_com_callback u3g_callback = {
- .usb2_com_start_read = &u3g_start_read,
- .usb2_com_stop_read = &u3g_stop_read,
- .usb2_com_start_write = &u3g_start_write,
- .usb2_com_stop_write = &u3g_stop_write,
-};
-
-#if 0
-static const struct u3g_speeds_s u3g_speeds[U3GSP_MAX] = {
- [U3GSP_GPRS] = {64000, 64000},
- [U3GSP_EDGE] = {384000, 64000},
- [U3GSP_CDMA] = {384000, 64000},
- [U3GSP_UMTS] = {384000, 64000},
- [U3GSP_HSDPA] = {1200000, 384000},
- [U3GSP_HSUPA] = {1200000, 384000},
- [U3GSP_HSPA] = {7200000, 384000},
-};
-#endif
-
-static device_method_t u3g_methods[] = {
- DEVMETHOD(device_probe, u3g_probe),
- DEVMETHOD(device_attach, u3g_attach),
- DEVMETHOD(device_detach, u3g_detach),
- {0, 0}
-};
-
-static devclass_t u3g_devclass;
-
-static driver_t u3g_driver = {
- .name = "u3g",
- .methods = u3g_methods,
- .size = sizeof(struct u3g_softc),
-};
-
-DRIVER_MODULE(u3g, ushub, u3g_driver, u3g_devclass, u3g_driver_loaded, 0);
-MODULE_DEPEND(u3g, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(u3g, usb2_core, 1, 1, 1);
-
-/* Huawei specific defines */
-
-#define U3GINFO(flag,speed) ((flag)|((speed) * 256))
-#define U3G_GET_SPEED(uaa) (USB_GET_DRIVER_INFO(uaa) / 256)
-
-/*
- * NOTE: The entries marked with XXX should be checked for the correct
- * speed indication to set the buffer sizes.
- */
-static const struct usb2_device_id u3g_devs[] = {
- /* OEM: Option */
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3G, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))},
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAXHSUPA, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))},
- {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G, U3GINFO(U3GSP_UMTS, U3GFL_NONE))},
- /* OEM: Qualcomm, Inc. */
- {USB_VPI(USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_STOR, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
- /* OEM: Huawei */
- {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE, U3GINFO(U3GSP_HSDPA, U3GFL_HUAWEI_INIT))},
- {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220, U3GINFO(U3GSP_HSPA, U3GFL_HUAWEI_INIT))},
- /* OEM: Novatel */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_CDMA_MODEM, U3GINFO(U3GSP_CDMA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ES620, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U720, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740_2, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U870, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V620, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V640, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720, U3GINFO(U3GSP_UMTS, U3GFL_SCSI_EJECT))}, /* XXX */
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_X950D, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_XU870, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD, U3GINFO(U3GSP_HSUPA, U3GFL_SCSI_EJECT))},
- {USB_VPI(USB_VENDOR_DELL, USB_PRODUCT_DELL_U740, U3GINFO(U3GSP_HSDPA, U3GFL_SCSI_EJECT))},
- /* OEM: Merlin */
- {USB_VPI(USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- /* OEM: Sierra Wireless: */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD595, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MINI5725, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC875U, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_HS2300, U3GINFO(U3GSP_HSDPA, U3GFL_NONE))},
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781, U3GINFO(U3GSP_UMTS, U3GFL_NONE))}, /* XXX */
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_HS2300, U3GINFO(U3GSP_HSPA, U3GFL_NONE))}, /* XXX */
- /* Sierra TruInstaller device ID */
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_TRUINSTALL, U3GINFO(U3GSP_UMTS, U3GFL_SIERRA_INIT))},
-};
-
-static void
-u3g_sierra_init(struct usb2_device *udev)
-{
- struct usb2_device_request req;
-
- DPRINTFN(0, "\n");
-
- 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);
-
- if (usb2_do_request_flags(udev, NULL, &req,
- NULL, 0, NULL, USB_MS_HZ)) {
- /* ignore any errors */
- }
- return;
-}
-
-static void
-u3g_huawei_init(struct usb2_device *udev)
-{
- struct usb2_device_request req;
-
- DPRINTFN(0, "\n");
-
- 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);
-
- if (usb2_do_request_flags(udev, NULL, &req,
- NULL, 0, NULL, USB_MS_HZ)) {
- /* ignore any errors */
- }
- return;
-}
-
-static int
-u3g_lookup_huawei(struct usb2_attach_arg *uaa)
-{
- /* Calling the lookup function will also set the driver info! */
- return (usb2_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa));
-}
-
-/*
- * The following function 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.
- */
-static usb2_error_t
-u3g_test_huawei_autoinst(struct usb2_device *udev,
- struct usb2_attach_arg *uaa)
-{
- struct usb2_interface *iface;
- struct usb2_interface_descriptor *id;
- uint32_t flags;
-
- if (udev == NULL) {
- return (USB_ERR_INVAL);
- }
- iface = usb2_get_iface(udev, 0);
- if (iface == NULL) {
- return (USB_ERR_INVAL);
- }
- id = iface->idesc;
- if (id == NULL) {
- return (USB_ERR_INVAL);
- }
- if (id->bInterfaceClass != UICLASS_MASS) {
- return (USB_ERR_INVAL);
- }
- if (u3g_lookup_huawei(uaa)) {
- /* no device match */
- return (USB_ERR_INVAL);
- }
- flags = USB_GET_DRIVER_INFO(uaa);
-
- if (flags & U3GFL_HUAWEI_INIT) {
- u3g_huawei_init(udev);
- } else if (flags & U3GFL_SCSI_EJECT) {
- return (usb2_test_autoinstall(udev, 0, 1));
- } else if (flags & U3GFL_SIERRA_INIT) {
- u3g_sierra_init(udev);
- } else {
- /* no quirks */
- return (USB_ERR_INVAL);
- }
- return (0); /* success */
-}
-
-static int
-u3g_driver_loaded(struct module *mod, int what, void *arg)
-{
- switch (what) {
- case MOD_LOAD:
- /* register our autoinstall handler */
- usb2_test_huawei_autoinst_p = &u3g_test_huawei_autoinst;
- break;
- case MOD_UNLOAD:
- usb2_test_huawei_unload(NULL);
- break;
- default:
- return (EOPNOTSUPP);
- }
- return (0);
-}
-
-static int
-u3g_probe(device_t self)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != U3G_CONFIG_INDEX) {
- return (ENXIO);
- }
- if (uaa->info.bInterfaceClass != UICLASS_VENDOR) {
- return (ENXIO);
- }
- return (u3g_lookup_huawei(uaa));
-}
-
-static int
-u3g_attach(device_t dev)
-{
- struct usb2_config u3g_config_tmp[U3G_N_TRANSFER];
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct u3g_softc *sc = device_get_softc(dev);
- struct usb2_interface *iface;
- struct usb2_interface_descriptor *id;
- uint8_t m;
- uint8_t n;
- uint8_t i;
- uint8_t x;
- int error;
-
- DPRINTF("sc=%p\n", sc);
-
- /* copy in USB config */
- for (n = 0; n != U3G_N_TRANSFER; n++)
- u3g_config_tmp[n] = u3g_config[n];
-
- device_set_usb2_desc(dev);
-
- sc->sc_udev = uaa->device;
-
- x = 0; /* interface index */
- i = 0; /* endpoint index */
- m = 0; /* number of ports */
-
- while (m != U3G_MAXPORTS) {
-
- /* update BULK endpoint index */
- for (n = 0; n != U3G_N_TRANSFER; n++)
- u3g_config_tmp[n].ep_index = i;
-
- iface = usb2_get_iface(uaa->device, x);
- if (iface == NULL) {
- if (m != 0)
- break; /* end of interfaces */
- DPRINTF("did not find any modem endpoints\n");
- goto detach;
- }
-
- id = usb2_get_interface_descriptor(iface);
- if ((id == NULL) ||
- (id->bInterfaceClass != UICLASS_VENDOR)) {
- /* next interface */
- x++;
- i = 0;
- continue;
- }
-
- /* try to allocate a set of BULK endpoints */
- error = usb2_transfer_setup(uaa->device, &x,
- sc->sc_xfer[m], u3g_config_tmp, U3G_N_TRANSFER,
- &sc->sc_ucom[m], &Giant);
- if (error) {
- /* next interface */
- x++;
- i = 0;
- continue;
- }
-
- /* grab other interface, if any */
- if (x != uaa->info.bIfaceIndex)
- usb2_set_parent_iface(uaa->device, x,
- uaa->info.bIfaceIndex);
-
- /* set stall by default */
- usb2_transfer_set_stall(sc->sc_xfer[m][U3G_BULK_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[m][U3G_BULK_RD]);
-
- m++; /* found one port */
- i++; /* next endpoint index */
- }
-
- sc->sc_numports = m;
-
- error = usb2_com_attach(&sc->sc_super_ucom, sc->sc_ucom,
- sc->sc_numports, sc, &u3g_callback, &Giant);
- if (error) {
- DPRINTF("usb2_com_attach failed\n");
- goto detach;
- }
- if (sc->sc_numports != 1) {
- /* be verbose */
- device_printf(dev, "Found %u ports.\n",
- (unsigned int)sc->sc_numports);
- }
- return (0);
-
-detach:
- u3g_detach(dev);
- return (ENXIO);
-}
-
-static int
-u3g_detach(device_t dev)
-{
- struct u3g_softc *sc = device_get_softc(dev);
- uint8_t m;
-
- DPRINTF("sc=%p\n", sc);
-
- /* NOTE: It is not dangerous to detach more ports than attached! */
- usb2_com_detach(&sc->sc_super_ucom, sc->sc_ucom, U3G_MAXPORTS);
-
- for (m = 0; m != U3G_MAXPORTS; m++)
- usb2_transfer_unsetup(sc->sc_xfer[m], U3G_N_TRANSFER);
-
- return (0);
-}
-
-static void
-u3g_start_read(struct usb2_com_softc *ucom)
-{
- struct u3g_softc *sc = ucom->sc_parent;
-
- /* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_RD]);
- return;
-}
-
-static void
-u3g_stop_read(struct usb2_com_softc *ucom)
-{
- struct u3g_softc *sc = ucom->sc_parent;
-
- /* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_RD]);
- return;
-}
-
-static void
-u3g_start_write(struct usb2_com_softc *ucom)
-{
- struct u3g_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_WR]);
- return;
-}
-
-static void
-u3g_stop_write(struct usb2_com_softc *ucom)
-{
- struct u3g_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_WR]);
- return;
-}
-
-static void
-u3g_write_callback(struct usb2_xfer *xfer)
-{
- struct usb2_com_softc *ucom = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- case USB_ST_SETUP:
-tr_setup:
- if (usb2_com_get_data(ucom, xfer->frbuffers, 0,
- U3G_BSIZE, &actlen)) {
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* do a builtin clear-stall */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- break;
- }
- return;
-}
-
-static void
-u3g_read_callback(struct usb2_xfer *xfer)
-{
- struct usb2_com_softc *ucom = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(ucom, xfer->frbuffers, 0, xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* do a builtin clear-stall */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- break;
- }
- return;
-}
diff --git a/sys/dev/usb2/serial/uark2.c b/sys/dev/usb2/serial/uark2.c
deleted file mode 100644
index 83bce0f..0000000
--- a/sys/dev/usb2/serial/uark2.c
+++ /dev/null
@@ -1,407 +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$
- */
-
-/*
- * NOTE: all function names beginning like "uark_cfg_" can only
- * be called from within the config thread function !
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#define UARK_BUF_SIZE 1024 /* bytes */
-
-#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
-
-enum {
- UARK_BULK_DT_WR,
- UARK_BULK_DT_RD,
- UARK_N_TRANSFER,
-};
-
-struct uark_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_xfer *sc_xfer[UARK_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint8_t sc_msr;
- uint8_t sc_lsr;
-};
-
-/* prototypes */
-
-static device_probe_t uark_probe;
-static device_attach_t uark_attach;
-static device_detach_t uark_detach;
-
-static usb2_callback_t uark_bulk_write_callback;
-static usb2_callback_t uark_bulk_read_callback;
-
-static void uark_start_read(struct usb2_com_softc *);
-static void uark_stop_read(struct usb2_com_softc *);
-static void uark_start_write(struct usb2_com_softc *);
-static void uark_stop_write(struct usb2_com_softc *);
-static int uark_pre_param(struct usb2_com_softc *, struct termios *);
-static void uark_cfg_param(struct usb2_com_softc *, struct termios *);
-static void uark_cfg_get_status(struct usb2_com_softc *, uint8_t *,
- uint8_t *);
-static void uark_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static void uark_cfg_write(struct uark_softc *, uint16_t, uint16_t);
-
-static const struct usb2_config
- uark_xfer_config[UARK_N_TRANSFER] = {
-
- [UARK_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UARK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &uark_bulk_write_callback,
- },
-
- [UARK_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UARK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &uark_bulk_read_callback,
- },
-};
-
-static const struct usb2_com_callback uark_callback = {
- .usb2_com_cfg_get_status = &uark_cfg_get_status,
- .usb2_com_cfg_set_break = &uark_cfg_set_break,
- .usb2_com_cfg_param = &uark_cfg_param,
- .usb2_com_pre_param = &uark_pre_param,
- .usb2_com_start_read = &uark_start_read,
- .usb2_com_stop_read = &uark_stop_read,
- .usb2_com_start_write = &uark_start_write,
- .usb2_com_stop_write = &uark_stop_write,
-};
-
-static device_method_t uark_methods[] = {
- /* Device methods */
- DEVMETHOD(device_probe, uark_probe),
- DEVMETHOD(device_attach, uark_attach),
- DEVMETHOD(device_detach, uark_detach),
- {0, 0}
-};
-
-static devclass_t uark_devclass;
-
-static driver_t uark_driver = {
- .name = "uark",
- .methods = uark_methods,
- .size = sizeof(struct uark_softc),
-};
-
-DRIVER_MODULE(uark, ushub, uark_driver, uark_devclass, NULL, 0);
-MODULE_DEPEND(uark, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(uark, usb2_core, 1, 1, 1);
-
-static const struct usb2_device_id uark_devs[] = {
- {USB_VPI(USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116, 0)},
-};
-
-static int
-uark_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != 0) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != UARK_IFACE_INDEX) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(uark_devs, sizeof(uark_devs), uaa));
-}
-
-static int
-uark_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct uark_softc *sc = device_get_softc(dev);
- int32_t error;
- uint8_t iface_index;
-
- device_set_usb2_desc(dev);
-
- sc->sc_udev = uaa->device;
-
- iface_index = UARK_IFACE_INDEX;
- error = usb2_transfer_setup
- (uaa->device, &iface_index, sc->sc_xfer,
- uark_xfer_config, UARK_N_TRANSFER, sc, &Giant);
-
- if (error) {
- device_printf(dev, "allocating control USB "
- "transfers failed!\n");
- goto detach;
- }
- /* clear stall at first run */
- usb2_transfer_set_stall(sc->sc_xfer[UARK_BULK_DT_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[UARK_BULK_DT_RD]);
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &uark_callback, &Giant);
- if (error) {
- DPRINTF("usb2_com_attach failed\n");
- goto detach;
- }
- return (0); /* success */
-
-detach:
- uark_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-uark_detach(device_t dev)
-{
- struct uark_softc *sc = device_get_softc(dev);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UARK_N_TRANSFER);
-
- return (0);
-}
-
-static void
-uark_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct uark_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- UARK_BUF_SIZE, &actlen)) {
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-static void
-uark_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct uark_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0,
- xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uark_start_read(struct usb2_com_softc *ucom)
-{
- struct uark_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UARK_BULK_DT_RD]);
-}
-
-static void
-uark_stop_read(struct usb2_com_softc *ucom)
-{
- struct uark_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UARK_BULK_DT_RD]);
-}
-
-static void
-uark_start_write(struct usb2_com_softc *ucom)
-{
- struct uark_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UARK_BULK_DT_WR]);
-}
-
-static void
-uark_stop_write(struct usb2_com_softc *ucom)
-{
- struct uark_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UARK_BULK_DT_WR]);
-}
-
-static int
-uark_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- if ((t->c_ospeed < 300) || (t->c_ospeed > 115200))
- return (EINVAL);
- return (0);
-}
-
-static void
-uark_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct uark_softc *sc = ucom->sc_parent;
- uint32_t speed = t->c_ospeed;
- uint16_t data;
-
- /*
- * NOTE: When reverse computing the baud rate from the "data" all
- * allowed baud rates are within 3% of the initial baud rate.
- */
- data = (UARK_BAUD_REF + (speed / 2)) / speed;
-
- uark_cfg_write(sc, 3, 0x83);
- uark_cfg_write(sc, 0, data & 0xFF);
- uark_cfg_write(sc, 1, data >> 8);
- uark_cfg_write(sc, 3, 0x03);
-
- if (t->c_cflag & CSTOPB)
- data = UARK_STOP_BITS_2;
- else
- data = UARK_STOP_BITS_1;
-
- if (t->c_cflag & PARENB) {
- if (t->c_cflag & PARODD)
- data |= UARK_PARITY_ODD;
- else
- data |= UARK_PARITY_EVEN;
- } else
- data |= UARK_PARITY_NONE;
-
- switch (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;
- default:
- case CS8:
- data |= UARK_SET_DATA_BITS(8);
- break;
- }
- uark_cfg_write(sc, 3, 0x00);
- uark_cfg_write(sc, 3, data);
-}
-
-static void
-uark_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
- struct uark_softc *sc = ucom->sc_parent;
-
- *lsr = sc->sc_lsr;
- *msr = sc->sc_msr;
-}
-
-static void
-uark_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uark_softc *sc = ucom->sc_parent;
-
- DPRINTF("onoff=%d\n", onoff);
-
- uark_cfg_write(sc, 4, onoff ? 0x01 : 0x00);
-}
-
-static void
-uark_cfg_write(struct uark_softc *sc, uint16_t index, uint16_t value)
-{
- struct usb2_device_request req;
- usb2_error_t err;
-
- req.bmRequestType = UARK_WRITE;
- req.bRequest = UARK_REQUEST;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, 0);
-
- err = usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
- if (err) {
- DPRINTFN(0, "device request failed, err=%s "
- "(ignored)\n", usb2_errstr(err));
- }
-}
diff --git a/sys/dev/usb2/serial/ubsa2.c b/sys/dev/usb2/serial/ubsa2.c
deleted file mode 100644
index 7aeb988..0000000
--- a/sys/dev/usb2/serial/ubsa2.c
+++ /dev/null
@@ -1,634 +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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-
-#define USB_DEBUG_VAR ubsa_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#if USB_DEBUG
-static int ubsa_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ubsa, CTLFLAG_RW, 0, "USB ubsa");
-SYSCTL_INT(_hw_usb2_ubsa, OID_AUTO, debug, CTLFLAG_RW,
- &ubsa_debug, 0, "ubsa debug level");
-#endif
-
-#define UBSA_BSIZE 1024 /* bytes */
-
-#define UBSA_CONFIG_INDEX 0
-#define UBSA_IFACE_INDEX 0
-
-#define UBSA_REG_BAUDRATE 0x00
-#define UBSA_REG_STOP_BITS 0x01
-#define UBSA_REG_DATA_BITS 0x02
-#define UBSA_REG_PARITY 0x03
-#define UBSA_REG_DTR 0x0A
-#define UBSA_REG_RTS 0x0B
-#define UBSA_REG_BREAK 0x0C
-#define UBSA_REG_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 */
-
-enum {
- UBSA_BULK_DT_WR,
- UBSA_BULK_DT_RD,
- UBSA_INTR_DT_RD,
- UBSA_N_TRANSFER,
-};
-
-struct ubsa_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_xfer *sc_xfer[UBSA_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint8_t sc_iface_no; /* interface number */
- uint8_t sc_iface_index; /* interface index */
- uint8_t sc_lsr; /* local status register */
- uint8_t sc_msr; /* UBSA status register */
-};
-
-static device_probe_t ubsa_probe;
-static device_attach_t ubsa_attach;
-static device_detach_t ubsa_detach;
-
-static usb2_callback_t ubsa_write_callback;
-static usb2_callback_t ubsa_read_callback;
-static usb2_callback_t ubsa_intr_callback;
-
-static void ubsa_cfg_request(struct ubsa_softc *, uint8_t, uint16_t);
-static void ubsa_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
-static void ubsa_cfg_set_rts(struct usb2_com_softc *, uint8_t);
-static void ubsa_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static int ubsa_pre_param(struct usb2_com_softc *, struct termios *);
-static void ubsa_cfg_param(struct usb2_com_softc *, struct termios *);
-static void ubsa_start_read(struct usb2_com_softc *);
-static void ubsa_stop_read(struct usb2_com_softc *);
-static void ubsa_start_write(struct usb2_com_softc *);
-static void ubsa_stop_write(struct usb2_com_softc *);
-static void ubsa_cfg_get_status(struct usb2_com_softc *, uint8_t *,
- uint8_t *);
-
-static const struct usb2_config ubsa_config[UBSA_N_TRANSFER] = {
-
- [UBSA_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UBSA_BSIZE, /* bytes */
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &ubsa_write_callback,
- },
-
- [UBSA_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UBSA_BSIZE, /* bytes */
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &ubsa_read_callback,
- },
-
- [UBSA_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = &ubsa_intr_callback,
- },
-};
-
-static const struct usb2_com_callback ubsa_callback = {
- .usb2_com_cfg_get_status = &ubsa_cfg_get_status,
- .usb2_com_cfg_set_dtr = &ubsa_cfg_set_dtr,
- .usb2_com_cfg_set_rts = &ubsa_cfg_set_rts,
- .usb2_com_cfg_set_break = &ubsa_cfg_set_break,
- .usb2_com_cfg_param = &ubsa_cfg_param,
- .usb2_com_pre_param = &ubsa_pre_param,
- .usb2_com_start_read = &ubsa_start_read,
- .usb2_com_stop_read = &ubsa_stop_read,
- .usb2_com_start_write = &ubsa_start_write,
- .usb2_com_stop_write = &ubsa_stop_write,
-};
-
-static const struct usb2_device_id ubsa_devs[] = {
- /* AnyData ADU-500A */
- {USB_VPI(USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_500A, 0)},
- /* AnyData ADU-E100A/H */
- {USB_VPI(USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_E100X, 0)},
- /* Axesstel MV100H */
- {USB_VPI(USB_VENDOR_AXESSTEL, USB_PRODUCT_AXESSTEL_DATAMODEM, 0)},
- /* BELKIN F5U103 */
- {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U103, 0)},
- /* BELKIN F5U120 */
- {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U120, 0)},
- /* GoHubs GO-COM232 */
- {USB_VPI(USB_VENDOR_ETEK, USB_PRODUCT_ETEK_1COM, 0)},
- /* GoHubs GO-COM232 */
- {USB_VPI(USB_VENDOR_GOHUBS, USB_PRODUCT_GOHUBS_GOCOM232, 0)},
- /* Peracom */
- {USB_VPI(USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1, 0)},
-};
-
-static device_method_t ubsa_methods[] = {
- DEVMETHOD(device_probe, ubsa_probe),
- DEVMETHOD(device_attach, ubsa_attach),
- DEVMETHOD(device_detach, ubsa_detach),
- {0, 0}
-};
-
-static devclass_t ubsa_devclass;
-
-static driver_t ubsa_driver = {
- .name = "ubsa",
- .methods = ubsa_methods,
- .size = sizeof(struct ubsa_softc),
-};
-
-DRIVER_MODULE(ubsa, ushub, ubsa_driver, ubsa_devclass, NULL, 0);
-MODULE_DEPEND(ubsa, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(ubsa, usb2_core, 1, 1, 1);
-
-static int
-ubsa_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != UBSA_CONFIG_INDEX) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != UBSA_IFACE_INDEX) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(ubsa_devs, sizeof(ubsa_devs), uaa));
-}
-
-static int
-ubsa_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ubsa_softc *sc = device_get_softc(dev);
- int error;
-
- DPRINTF("sc=%p\n", sc);
-
- device_set_usb2_desc(dev);
-
- sc->sc_udev = uaa->device;
- sc->sc_iface_no = uaa->info.bIfaceNum;
- sc->sc_iface_index = UBSA_IFACE_INDEX;
-
- error = usb2_transfer_setup(uaa->device, &sc->sc_iface_index,
- sc->sc_xfer, ubsa_config, UBSA_N_TRANSFER, sc, &Giant);
-
- if (error) {
- DPRINTF("could not allocate all pipes\n");
- goto detach;
- }
- /* clear stall at first run */
- usb2_transfer_set_stall(sc->sc_xfer[UBSA_BULK_DT_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[UBSA_BULK_DT_RD]);
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &ubsa_callback, &Giant);
- if (error) {
- DPRINTF("usb2_com_attach failed\n");
- goto detach;
- }
- return (0);
-
-detach:
- ubsa_detach(dev);
- return (ENXIO);
-}
-
-static int
-ubsa_detach(device_t dev)
-{
- struct ubsa_softc *sc = device_get_softc(dev);
-
- DPRINTF("sc=%p\n", sc);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UBSA_N_TRANSFER);
-
- return (0);
-}
-
-static void
-ubsa_cfg_request(struct ubsa_softc *sc, uint8_t index, uint16_t value)
-{
- struct usb2_device_request req;
- usb2_error_t err;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = index;
- USETW(req.wValue, value);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- err = usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
- if (err) {
- DPRINTFN(0, "device request failed, err=%s "
- "(ignored)\n", usb2_errstr(err));
- }
-}
-
-static void
-ubsa_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct ubsa_softc *sc = ucom->sc_parent;
-
- DPRINTF("onoff = %d\n", onoff);
-
- ubsa_cfg_request(sc, UBSA_REG_DTR, onoff ? 1 : 0);
-}
-
-static void
-ubsa_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct ubsa_softc *sc = ucom->sc_parent;
-
- DPRINTF("onoff = %d\n", onoff);
-
- ubsa_cfg_request(sc, UBSA_REG_RTS, onoff ? 1 : 0);
-}
-
-static void
-ubsa_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct ubsa_softc *sc = ucom->sc_parent;
-
- DPRINTF("onoff = %d\n", onoff);
-
- ubsa_cfg_request(sc, UBSA_REG_BREAK, onoff ? 1 : 0);
-}
-
-static int
-ubsa_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct ubsa_softc *sc = ucom->sc_parent;
-
- DPRINTF("sc = %p\n", sc);
-
- switch (t->c_ospeed) {
- case B0:
- case B300:
- case B600:
- case B1200:
- case B2400:
- case B4800:
- case B9600:
- case B19200:
- case B38400:
- case B57600:
- case B115200:
- case B230400:
- break;
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-static void
-ubsa_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct ubsa_softc *sc = ucom->sc_parent;
- uint16_t value = 0;
-
- DPRINTF("sc = %p\n", sc);
-
- switch (t->c_ospeed) {
- case B0:
- ubsa_cfg_request(sc, UBSA_REG_FLOW_CTRL, 0);
- ubsa_cfg_set_dtr(&sc->sc_ucom, 0);
- ubsa_cfg_set_rts(&sc->sc_ucom, 0);
- 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 / t->c_ospeed;
- ubsa_cfg_request(sc, UBSA_REG_BAUDRATE, value);
- break;
- default:
- return;
- }
-
- if (t->c_cflag & PARENB)
- value = (t->c_cflag & PARODD) ? UBSA_PARITY_ODD : UBSA_PARITY_EVEN;
- else
- value = UBSA_PARITY_NONE;
-
- ubsa_cfg_request(sc, UBSA_REG_PARITY, value);
-
- switch (t->c_cflag & CSIZE) {
- case CS5:
- value = 0;
- break;
- case CS6:
- value = 1;
- break;
- case CS7:
- value = 2;
- break;
- default:
- case CS8:
- value = 3;
- break;
- }
-
- ubsa_cfg_request(sc, UBSA_REG_DATA_BITS, value);
-
- value = (t->c_cflag & CSTOPB) ? 1 : 0;
-
- ubsa_cfg_request(sc, UBSA_REG_STOP_BITS, value);
-
- value = 0;
- if (t->c_cflag & CRTSCTS)
- value |= UBSA_FLOW_OCTS | UBSA_FLOW_IRTS;
-
- if (t->c_iflag & (IXON | IXOFF))
- value |= UBSA_FLOW_OXON | UBSA_FLOW_IXON;
-
- ubsa_cfg_request(sc, UBSA_REG_FLOW_CTRL, value);
-}
-
-static void
-ubsa_start_read(struct usb2_com_softc *ucom)
-{
- struct ubsa_softc *sc = ucom->sc_parent;
-
- /* start interrupt endpoint */
- usb2_transfer_start(sc->sc_xfer[UBSA_INTR_DT_RD]);
-
- /* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[UBSA_BULK_DT_RD]);
-}
-
-static void
-ubsa_stop_read(struct usb2_com_softc *ucom)
-{
- struct ubsa_softc *sc = ucom->sc_parent;
-
- /* stop interrupt endpoint */
- usb2_transfer_stop(sc->sc_xfer[UBSA_INTR_DT_RD]);
-
- /* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[UBSA_BULK_DT_RD]);
-}
-
-static void
-ubsa_start_write(struct usb2_com_softc *ucom)
-{
- struct ubsa_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UBSA_BULK_DT_WR]);
-}
-
-static void
-ubsa_stop_write(struct usb2_com_softc *ucom)
-{
- struct ubsa_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UBSA_BULK_DT_WR]);
-}
-
-static void
-ubsa_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
- struct ubsa_softc *sc = ucom->sc_parent;
-
- DPRINTF("\n");
-
- *lsr = sc->sc_lsr;
- *msr = sc->sc_msr;
-}
-
-static void
-ubsa_write_callback(struct usb2_xfer *xfer)
-{
- struct ubsa_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- UBSA_BSIZE, &actlen)) {
-
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-static void
-ubsa_read_callback(struct usb2_xfer *xfer)
-{
- struct ubsa_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-static void
-ubsa_intr_callback(struct usb2_xfer *xfer)
-{
- struct ubsa_softc *sc = xfer->priv_sc;
- uint8_t buf[4];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (xfer->actlen >= sizeof(buf)) {
-
- usb2_copy_out(xfer->frbuffers, 0, buf, sizeof(buf));
-
- /*
- * incidentally, Belkin adapter status bits match
- * UART 16550 bits
- */
- sc->sc_lsr = buf[2];
- sc->sc_msr = buf[3];
-
- DPRINTF("lsr = 0x%02x, msr = 0x%02x\n",
- sc->sc_lsr, sc->sc_msr);
-
- usb2_com_status_change(&sc->sc_ucom);
- } else {
- DPRINTF("ignoring short packet, %d bytes\n",
- xfer->actlen);
- }
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
diff --git a/sys/dev/usb2/serial/ubser2.c b/sys/dev/usb2/serial/ubser2.c
deleted file mode 100644
index 4ec1542..0000000
--- a/sys/dev/usb2/serial/ubser2.c
+++ /dev/null
@@ -1,518 +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 <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR ubser_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_device.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#define UBSER_UNIT_MAX 32
-
-/* Vendor Interface Requests */
-#define VENDOR_GET_NUMSER 0x01
-#define VENDOR_SET_BREAK 0x02
-#define VENDOR_CLEAR_BREAK 0x03
-
-#if USB_DEBUG
-static int ubser_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ubser, CTLFLAG_RW, 0, "USB ubser");
-SYSCTL_INT(_hw_usb2_ubser, OID_AUTO, debug, CTLFLAG_RW,
- &ubser_debug, 0, "ubser debug level");
-#endif
-
-enum {
- UBSER_BULK_DT_WR,
- UBSER_BULK_DT_RD,
- UBSER_N_TRANSFER,
-};
-
-struct ubser_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom[UBSER_UNIT_MAX];
-
- struct usb2_xfer *sc_xfer[UBSER_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint16_t sc_tx_size;
-
- uint8_t sc_numser;
- uint8_t sc_iface_no;
- uint8_t sc_iface_index;
- uint8_t sc_curr_tx_unit;
- uint8_t sc_name[16];
-};
-
-/* prototypes */
-
-static device_probe_t ubser_probe;
-static device_attach_t ubser_attach;
-static device_detach_t ubser_detach;
-
-static usb2_callback_t ubser_write_callback;
-static usb2_callback_t ubser_read_callback;
-
-static int ubser_pre_param(struct usb2_com_softc *, struct termios *);
-static void ubser_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static void ubser_cfg_get_status(struct usb2_com_softc *, uint8_t *,
- uint8_t *);
-static void ubser_start_read(struct usb2_com_softc *);
-static void ubser_stop_read(struct usb2_com_softc *);
-static void ubser_start_write(struct usb2_com_softc *);
-static void ubser_stop_write(struct usb2_com_softc *);
-
-static const struct usb2_config ubser_config[UBSER_N_TRANSFER] = {
-
- [UBSER_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &ubser_write_callback,
- },
-
- [UBSER_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &ubser_read_callback,
- },
-};
-
-static const struct usb2_com_callback ubser_callback = {
- .usb2_com_cfg_set_break = &ubser_cfg_set_break,
- .usb2_com_cfg_get_status = &ubser_cfg_get_status,
- .usb2_com_pre_param = &ubser_pre_param,
- .usb2_com_start_read = &ubser_start_read,
- .usb2_com_stop_read = &ubser_stop_read,
- .usb2_com_start_write = &ubser_start_write,
- .usb2_com_stop_write = &ubser_stop_write,
-};
-
-static device_method_t ubser_methods[] = {
- DEVMETHOD(device_probe, ubser_probe),
- DEVMETHOD(device_attach, ubser_attach),
- DEVMETHOD(device_detach, ubser_detach),
- {0, 0}
-};
-
-static devclass_t ubser_devclass;
-
-static driver_t ubser_driver = {
- .name = "ubser",
- .methods = ubser_methods,
- .size = sizeof(struct ubser_softc),
-};
-
-DRIVER_MODULE(ubser, ushub, ubser_driver, ubser_devclass, NULL, 0);
-MODULE_DEPEND(ubser, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(ubser, usb2_core, 1, 1, 1);
-
-static int
-ubser_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- /* check if this is a BWCT vendor specific ubser interface */
- if ((strcmp(uaa->device->manufacturer, "BWCT") == 0) &&
- (uaa->info.bInterfaceClass == 0xff) &&
- (uaa->info.bInterfaceSubClass == 0x00))
- return (0);
-
- return (ENXIO);
-}
-
-static int
-ubser_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ubser_softc *sc = device_get_softc(dev);
- struct usb2_device_request req;
- uint8_t n;
- int error;
-
- device_set_usb2_desc(dev);
-
- snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
- device_get_nameunit(dev));
-
- sc->sc_iface_no = uaa->info.bIfaceNum;
- sc->sc_iface_index = uaa->info.bIfaceIndex;
- sc->sc_udev = uaa->device;
-
- /* get number of serials */
- req.bmRequestType = UT_READ_VENDOR_INTERFACE;
- req.bRequest = VENDOR_GET_NUMSER;
- USETW(req.wValue, 0);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 1);
- error = usb2_do_request_flags
- (uaa->device, &Giant, &req, &sc->sc_numser,
- 0, NULL, USB_DEFAULT_TIMEOUT);
-
- if (error || (sc->sc_numser == 0)) {
- device_printf(dev, "failed to get number "
- "of serial ports: %s\n",
- usb2_errstr(error));
- goto detach;
- }
- if (sc->sc_numser > UBSER_UNIT_MAX)
- sc->sc_numser = UBSER_UNIT_MAX;
-
- device_printf(dev, "found %i serials\n", sc->sc_numser);
-
- error = usb2_transfer_setup(uaa->device, &sc->sc_iface_index,
- sc->sc_xfer, ubser_config, UBSER_N_TRANSFER, sc, &Giant);
- if (error) {
- goto detach;
- }
- sc->sc_tx_size = sc->sc_xfer[UBSER_BULK_DT_WR]->max_data_length;
-
- if (sc->sc_tx_size == 0) {
- DPRINTFN(0, "invalid tx_size!\n");
- goto detach;
- }
- /* initialize port numbers */
-
- for (n = 0; n < sc->sc_numser; n++) {
- sc->sc_ucom[n].sc_portno = n;
- }
-
- error = usb2_com_attach(&sc->sc_super_ucom, sc->sc_ucom,
- sc->sc_numser, sc, &ubser_callback, &Giant);
- if (error) {
- goto detach;
- }
- mtx_lock(&Giant);
-
- usb2_transfer_set_stall(sc->sc_xfer[UBSER_BULK_DT_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[UBSER_BULK_DT_RD]);
-
- usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_RD]);
-
- mtx_unlock(&Giant);
-
- return (0); /* success */
-
-detach:
- ubser_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-ubser_detach(device_t dev)
-{
- struct ubser_softc *sc = device_get_softc(dev);
-
- DPRINTF("\n");
-
- usb2_com_detach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_numser);
-
- usb2_transfer_unsetup(sc->sc_xfer, UBSER_N_TRANSFER);
-
- return (0);
-}
-
-static int
-ubser_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- DPRINTF("\n");
-
- /*
- * The firmware on our devices can only do 8n1@9600bps
- * without handshake.
- * We refuse to accept other configurations.
- */
-
- /* ensure 9600bps */
- switch (t->c_ospeed) {
- case 9600:
- break;
- default:
- return (EINVAL);
- }
-
- /* 2 stop bits not possible */
- if (t->c_cflag & CSTOPB)
- return (EINVAL);
-
- /* XXX parity handling not possible with current firmware */
- if (t->c_cflag & PARENB)
- return (EINVAL);
-
- /* we can only do 8 data bits */
- switch (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.
- */
-
- return (0);
-}
-
-static __inline void
-ubser_inc_tx_unit(struct ubser_softc *sc)
-{
- sc->sc_curr_tx_unit++;
- if (sc->sc_curr_tx_unit >= sc->sc_numser) {
- sc->sc_curr_tx_unit = 0;
- }
-}
-
-static void
-ubser_write_callback(struct usb2_xfer *xfer)
-{
- struct ubser_softc *sc = xfer->priv_sc;
- uint8_t buf[1];
- uint8_t first_unit = sc->sc_curr_tx_unit;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- do {
- if (usb2_com_get_data(sc->sc_ucom + sc->sc_curr_tx_unit,
- xfer->frbuffers, 1, sc->sc_tx_size - 1,
- &actlen)) {
-
- buf[0] = sc->sc_curr_tx_unit;
-
- usb2_copy_in(xfer->frbuffers, 0, buf, 1);
-
- xfer->frlengths[0] = actlen + 1;
- usb2_start_hardware(xfer);
-
- ubser_inc_tx_unit(sc); /* round robin */
-
- break;
- }
- ubser_inc_tx_unit(sc);
-
- } while (sc->sc_curr_tx_unit != first_unit);
-
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-static void
-ubser_read_callback(struct usb2_xfer *xfer)
-{
- struct ubser_softc *sc = xfer->priv_sc;
- uint8_t buf[1];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- if (xfer->actlen < 1) {
- DPRINTF("invalid actlen=0!\n");
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, 0, buf, 1);
-
- if (buf[0] >= sc->sc_numser) {
- DPRINTF("invalid serial number!\n");
- goto tr_setup;
- }
- usb2_com_put_data(sc->sc_ucom + buf[0],
- xfer->frbuffers, 1, xfer->actlen - 1);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-static void
-ubser_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct ubser_softc *sc = ucom->sc_parent;
- uint8_t x = ucom->sc_portno;
- struct usb2_device_request req;
- usb2_error_t err;
-
- if (onoff) {
-
- req.bmRequestType = UT_READ_VENDOR_INTERFACE;
- req.bRequest = VENDOR_SET_BREAK;
- req.wValue[0] = x;
- req.wValue[1] = 0;
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- err = usb2_com_cfg_do_request(sc->sc_udev, ucom,
- &req, NULL, 0, 1000);
- if (err) {
- DPRINTFN(0, "send break failed, error=%s\n",
- usb2_errstr(err));
- }
- }
-}
-
-static void
-ubser_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
- /* fake status bits */
- *lsr = 0;
- *msr = SER_DCD;
-}
-
-static void
-ubser_start_read(struct usb2_com_softc *ucom)
-{
- struct ubser_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_RD]);
-}
-
-static void
-ubser_stop_read(struct usb2_com_softc *ucom)
-{
- struct ubser_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_DT_RD]);
-}
-
-static void
-ubser_start_write(struct usb2_com_softc *ucom)
-{
- struct ubser_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_WR]);
-}
-
-static void
-ubser_stop_write(struct usb2_com_softc *ucom)
-{
- struct ubser_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_DT_WR]);
-}
diff --git a/sys/dev/usb2/serial/uchcom2.c b/sys/dev/usb2/serial/uchcom2.c
deleted file mode 100644
index 2c3e8f2..0000000
--- a/sys/dev/usb2/serial/uchcom2.c
+++ /dev/null
@@ -1,883 +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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-
-#define USB_DEBUG_VAR uchcom_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#if USB_DEBUG
-static int uchcom_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uchcom, CTLFLAG_RW, 0, "USB uchcom");
-SYSCTL_INT(_hw_usb2_uchcom, OID_AUTO, debug, CTLFLAG_RW,
- &uchcom_debug, 0, "uchcom debug level");
-#endif
-
-#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 UCHCOM_BULK_BUF_SIZE 1024 /* bytes */
-
-enum {
- UCHCOM_BULK_DT_WR,
- UCHCOM_BULK_DT_RD,
- UCHCOM_INTR_DT_RD,
- UCHCOM_N_TRANSFER,
-};
-
-struct uchcom_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_xfer *sc_xfer[UCHCOM_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint8_t sc_dtr; /* local copy */
- uint8_t sc_rts; /* local copy */
- uint8_t sc_version;
- uint8_t sc_msr;
- uint8_t sc_lsr; /* local status register */
-};
-
-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 usb2_device_id uchcom_devs[] = {
- {USB_VPI(USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341SER, 0)},
-};
-
-/* protypes */
-
-static int uchcom_pre_param(struct usb2_com_softc *, struct termios *);
-static void uchcom_cfg_get_status(struct usb2_com_softc *, uint8_t *,
- uint8_t *);
-static void uchcom_cfg_param(struct usb2_com_softc *, struct termios *);
-static void uchcom_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static void uchcom_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
-static void uchcom_cfg_set_rts(struct usb2_com_softc *, uint8_t);
-static void uchcom_start_read(struct usb2_com_softc *);
-static void uchcom_start_write(struct usb2_com_softc *);
-static void uchcom_stop_read(struct usb2_com_softc *);
-static void uchcom_stop_write(struct usb2_com_softc *);
-static void uchcom_update_version(struct uchcom_softc *);
-static void uchcom_convert_status(struct uchcom_softc *, uint8_t);
-static void uchcom_update_status(struct uchcom_softc *);
-static void uchcom_set_dtrrts(struct uchcom_softc *);
-static int uchcom_calc_divider_settings(struct uchcom_divider *, uint32_t);
-static void uchcom_set_dte_rate(struct uchcom_softc *, uint32_t);
-static void uchcom_set_line_control(struct uchcom_softc *, tcflag_t);
-static void uchcom_clear_chip(struct uchcom_softc *);
-static void uchcom_reset_chip(struct uchcom_softc *);
-
-static device_probe_t uchcom_probe;
-static device_attach_t uchcom_attach;
-static device_detach_t uchcom_detach;
-
-static usb2_callback_t uchcom_intr_callback;
-static usb2_callback_t uchcom_write_callback;
-static usb2_callback_t uchcom_read_callback;
-
-static const struct usb2_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
-
- [UCHCOM_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UCHCOM_BULK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &uchcom_write_callback,
- },
-
- [UCHCOM_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UCHCOM_BULK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &uchcom_read_callback,
- },
-
- [UCHCOM_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = &uchcom_intr_callback,
- },
-};
-
-struct usb2_com_callback uchcom_callback = {
- .usb2_com_cfg_get_status = &uchcom_cfg_get_status,
- .usb2_com_cfg_set_dtr = &uchcom_cfg_set_dtr,
- .usb2_com_cfg_set_rts = &uchcom_cfg_set_rts,
- .usb2_com_cfg_set_break = &uchcom_cfg_set_break,
- .usb2_com_cfg_param = &uchcom_cfg_param,
- .usb2_com_pre_param = &uchcom_pre_param,
- .usb2_com_start_read = &uchcom_start_read,
- .usb2_com_stop_read = &uchcom_stop_read,
- .usb2_com_start_write = &uchcom_start_write,
- .usb2_com_stop_write = &uchcom_stop_write,
-};
-
-/* ----------------------------------------------------------------------
- * driver entry points
- */
-
-static int
-uchcom_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- DPRINTFN(11, "\n");
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != UCHCOM_CONFIG_INDEX) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != UCHCOM_IFACE_INDEX) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(uchcom_devs, sizeof(uchcom_devs), uaa));
-}
-
-static int
-uchcom_attach(device_t dev)
-{
- struct uchcom_softc *sc = device_get_softc(dev);
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- int error;
- uint8_t iface_index;
-
- DPRINTFN(11, "\n");
-
- device_set_usb2_desc(dev);
-
- sc->sc_udev = uaa->device;
-
- switch (uaa->info.bcdDevice) {
- case UCHCOM_REV_CH340:
- device_printf(dev, "CH340 detected\n");
- break;
- default:
- device_printf(dev, "CH341 detected\n");
- break;
- }
-
- iface_index = UCHCOM_IFACE_INDEX;
- error = usb2_transfer_setup(uaa->device,
- &iface_index, sc->sc_xfer, uchcom_config_data,
- UCHCOM_N_TRANSFER, sc, &Giant);
-
- if (error) {
- DPRINTF("one or more missing USB endpoints, "
- "error=%s\n", usb2_errstr(error));
- goto detach;
- }
- /*
- * Do the initialization during attach so that the system does not
- * sleep during open:
- */
- uchcom_update_version(sc);
- uchcom_clear_chip(sc);
- uchcom_reset_chip(sc);
- uchcom_update_status(sc);
-
- sc->sc_dtr = 1;
- sc->sc_rts = 1;
-
- /* clear stall at first run */
- usb2_transfer_set_stall(sc->sc_xfer[UCHCOM_BULK_DT_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[UCHCOM_BULK_DT_RD]);
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &uchcom_callback, &Giant);
- if (error) {
- goto detach;
- }
- return (0);
-
-detach:
- uchcom_detach(dev);
- return (ENXIO);
-}
-
-static int
-uchcom_detach(device_t dev)
-{
- struct uchcom_softc *sc = device_get_softc(dev);
-
- DPRINTFN(11, "\n");
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UCHCOM_N_TRANSFER);
-
- return (0);
-}
-
-/* ----------------------------------------------------------------------
- * low level i/o
- */
-
-static void
-uchcom_ctrl_write(struct uchcom_softc *sc, uint8_t reqno,
- uint16_t value, uint16_t index)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = reqno;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev,
- &sc->sc_ucom, &req, NULL, 0, 1000);
-}
-
-static void
-uchcom_ctrl_read(struct uchcom_softc *sc, uint8_t reqno,
- uint16_t value, uint16_t index, void *buf, uint16_t buflen)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = reqno;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, buflen);
-
- usb2_com_cfg_do_request(sc->sc_udev,
- &sc->sc_ucom, &req, buf, USB_SHORT_XFER_OK, 1000);
-}
-
-static void
-uchcom_write_reg(struct uchcom_softc *sc,
- uint8_t reg1, uint8_t val1, uint8_t reg2, uint8_t val2)
-{
- DPRINTF("0x%02X<-0x%02X, 0x%02X<-0x%02X\n",
- (unsigned)reg1, (unsigned)val1,
- (unsigned)reg2, (unsigned)val2);
- uchcom_ctrl_write(
- sc, UCHCOM_REQ_WRITE_REG,
- reg1 | ((uint16_t)reg2 << 8), val1 | ((uint16_t)val2 << 8));
-}
-
-static void
-uchcom_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];
-
- uchcom_ctrl_read(
- sc, UCHCOM_REQ_READ_REG,
- reg1 | ((uint16_t)reg2 << 8), 0, buf, sizeof(buf));
-
- DPRINTF("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];
-}
-
-static void
-uchcom_get_version(struct uchcom_softc *sc, uint8_t *rver)
-{
- uint8_t buf[UCHCOM_INPUT_BUF_SIZE];
-
- uchcom_ctrl_read(
- sc, UCHCOM_REQ_GET_VERSION, 0, 0, buf, sizeof(buf));
-
- if (rver)
- *rver = buf[0];
-}
-
-static void
-uchcom_get_status(struct uchcom_softc *sc, uint8_t *rval)
-{
- uchcom_read_reg(sc, UCHCOM_REG_STAT1, rval, UCHCOM_REG_STAT2, NULL);
-}
-
-static void
-uchcom_set_dtrrts_10(struct uchcom_softc *sc, uint8_t val)
-{
- uchcom_write_reg(sc, UCHCOM_REG_STAT1, val, UCHCOM_REG_STAT1, val);
-}
-
-static void
-uchcom_set_dtrrts_20(struct uchcom_softc *sc, uint8_t val)
-{
- uchcom_ctrl_write(sc, UCHCOM_REQ_SET_DTRRTS, val, 0);
-}
-
-
-/* ----------------------------------------------------------------------
- * middle layer
- */
-
-static void
-uchcom_update_version(struct uchcom_softc *sc)
-{
- uchcom_get_version(sc, &sc->sc_version);
-}
-
-static void
-uchcom_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 void
-uchcom_update_status(struct uchcom_softc *sc)
-{
- uint8_t cur;
-
- uchcom_get_status(sc, &cur);
- uchcom_convert_status(sc, cur);
-}
-
-
-static void
-uchcom_set_dtrrts(struct uchcom_softc *sc)
-{
- uint8_t val = 0;
-
- if (sc->sc_dtr)
- val |= UCHCOM_DTR_MASK;
- if (sc->sc_rts)
- val |= UCHCOM_RTS_MASK;
-
- if (sc->sc_version < UCHCOM_VER_20)
- uchcom_set_dtrrts_10(sc, ~val);
- else
- uchcom_set_dtrrts_20(sc, ~val);
-}
-
-static void
-uchcom_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uchcom_softc *sc = ucom->sc_parent;
- uint8_t brk1;
- uint8_t brk2;
-
- uchcom_read_reg(sc, UCHCOM_REG_BREAK1, &brk1, UCHCOM_REG_BREAK2, &brk2);
- 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;
- }
- uchcom_write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_BREAK2, brk2);
-}
-
-static int
-uchcom_calc_divider_settings(struct uchcom_divider *dp, uint32_t rate)
-{
- const struct uchcom_divider_record *rp;
- uint32_t div;
- uint32_t rem;
- uint32_t mod;
- uint8_t i;
-
- /* 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 void
-uchcom_set_dte_rate(struct uchcom_softc *sc, uint32_t rate)
-{
- struct uchcom_divider dv;
-
- if (uchcom_calc_divider_settings(&dv, rate))
- return;
-
- uchcom_write_reg(sc,
- UCHCOM_REG_BPS_PRE, dv.dv_prescaler,
- UCHCOM_REG_BPS_DIV, dv.dv_div);
- uchcom_write_reg(sc,
- UCHCOM_REG_BPS_MOD, dv.dv_mod,
- UCHCOM_REG_BPS_PAD, 0);
-}
-
-static void
-uchcom_set_line_control(struct uchcom_softc *sc, tcflag_t cflag)
-{
- uint8_t lcr1 = 0;
- uint8_t lcr2 = 0;
-
- uchcom_read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2);
-
- 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.
- */
-
- if (cflag & PARENB) {
- lcr1 |= UCHCOM_LCR1_PARENB;
- if (cflag & PARODD)
- lcr2 |= UCHCOM_LCR2_PARODD;
- else
- lcr2 |= UCHCOM_LCR2_PAREVEN;
- }
- uchcom_write_reg(sc, UCHCOM_REG_LCR1, lcr1, UCHCOM_REG_LCR2, lcr2);
-}
-
-static void
-uchcom_clear_chip(struct uchcom_softc *sc)
-{
- DPRINTF("\n");
- uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0);
-}
-
-static void
-uchcom_reset_chip(struct uchcom_softc *sc)
-{
- uint16_t val;
- uint16_t idx;
- uint8_t lcr1;
- uint8_t lcr2;
- uint8_t pre;
- uint8_t div;
- uint8_t mod;
-
- uchcom_read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2);
- uchcom_read_reg(sc, UCHCOM_REG_BPS_PRE, &pre, UCHCOM_REG_BPS_DIV, &div);
- uchcom_read_reg(sc, UCHCOM_REG_BPS_MOD, &mod, UCHCOM_REG_BPS_PAD, NULL);
-
- val = 0;
- idx = 0;
- 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("reset v=0x%04X, i=0x%04X\n", val, idx);
-
- uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, val, idx);
-}
-
-/* ----------------------------------------------------------------------
- * methods for ucom
- */
-static void
-uchcom_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
- struct uchcom_softc *sc = ucom->sc_parent;
-
- DPRINTF("\n");
-
- *lsr = sc->sc_lsr;
- *msr = sc->sc_msr;
-}
-
-static void
-uchcom_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uchcom_softc *sc = ucom->sc_parent;
-
- DPRINTF("onoff = %d\n", onoff);
-
- sc->sc_dtr = onoff;
- uchcom_set_dtrrts(sc);
-}
-
-static void
-uchcom_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uchcom_softc *sc = ucom->sc_parent;
-
- DPRINTF("onoff = %d\n", onoff);
-
- sc->sc_rts = onoff;
- uchcom_set_dtrrts(sc);
-}
-
-static int
-uchcom_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct uchcom_divider dv;
-
- switch (t->c_cflag & CSIZE) {
- case CS5:
- case CS6:
- case CS7:
- return (EIO);
- default:
- break;
- }
-
- if (uchcom_calc_divider_settings(&dv, t->c_ospeed)) {
- return (EIO);
- }
- return (0); /* success */
-}
-
-static void
-uchcom_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct uchcom_softc *sc = ucom->sc_parent;
-
- uchcom_set_line_control(sc, t->c_cflag);
- uchcom_set_dte_rate(sc, t->c_ospeed);
-}
-
-static void
-uchcom_start_read(struct usb2_com_softc *ucom)
-{
- struct uchcom_softc *sc = ucom->sc_parent;
-
- /* start interrupt endpoint */
- usb2_transfer_start(sc->sc_xfer[UCHCOM_INTR_DT_RD]);
-
- /* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_DT_RD]);
-}
-
-static void
-uchcom_stop_read(struct usb2_com_softc *ucom)
-{
- struct uchcom_softc *sc = ucom->sc_parent;
-
- /* stop interrupt endpoint */
- usb2_transfer_stop(sc->sc_xfer[UCHCOM_INTR_DT_RD]);
-
- /* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_DT_RD]);
-}
-
-static void
-uchcom_start_write(struct usb2_com_softc *ucom)
-{
- struct uchcom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_DT_WR]);
-}
-
-static void
-uchcom_stop_write(struct usb2_com_softc *ucom)
-{
- struct uchcom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_DT_WR]);
-}
-
-/* ----------------------------------------------------------------------
- * callback when the modem status is changed.
- */
-static void
-uchcom_intr_callback(struct usb2_xfer *xfer)
-{
- struct uchcom_softc *sc = xfer->priv_sc;
- uint8_t buf[UCHCOM_INTR_LEAST];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- DPRINTF("actlen = %u\n", xfer->actlen);
-
- if (xfer->actlen >= UCHCOM_INTR_LEAST) {
- usb2_copy_out(xfer->frbuffers, 0, buf,
- UCHCOM_INTR_LEAST);
-
- DPRINTF("data = 0x%02X 0x%02X 0x%02X 0x%02X\n",
- (unsigned)buf[0], (unsigned)buf[1],
- (unsigned)buf[2], (unsigned)buf[3]);
-
- uchcom_convert_status(sc, buf[UCHCOM_INTR_STAT1]);
- usb2_com_status_change(&sc->sc_ucom);
- }
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- break;
- }
-}
-
-static void
-uchcom_write_callback(struct usb2_xfer *xfer)
-{
- struct uchcom_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- UCHCOM_BULK_BUF_SIZE, &actlen)) {
-
- DPRINTF("actlen = %d\n", actlen);
-
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-static void
-uchcom_read_callback(struct usb2_xfer *xfer)
-{
- struct uchcom_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static device_method_t uchcom_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uchcom_probe),
- DEVMETHOD(device_attach, uchcom_attach),
- DEVMETHOD(device_detach, uchcom_detach),
-
- {0, 0}
-};
-
-static driver_t uchcom_driver = {
- "ucom",
- uchcom_methods,
- sizeof(struct uchcom_softc)
-};
-
-static devclass_t uchcom_devclass;
-
-DRIVER_MODULE(uchcom, ushub, uchcom_driver, uchcom_devclass, NULL, 0);
-MODULE_DEPEND(uchcom, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(uchcom, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/serial/ucycom2.c b/sys/dev/usb2/serial/ucycom2.c
deleted file mode 100644
index 5bf59a2..0000000
--- a/sys/dev/usb2/serial/ucycom2.c
+++ /dev/null
@@ -1,564 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * 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.
- */
-
-/*
- * Device driver for Cypress CY7C637xx and CY7C640/1xx series USB to
- * RS232 bridges.
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-#include <dev/usb2/include/usb2_hid.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_hid.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#define UCYCOM_MAX_IOLEN (1024 + 2) /* bytes */
-
-#define UCYCOM_IFACE_INDEX 0
-
-enum {
- UCYCOM_CTRL_RD,
- UCYCOM_INTR_RD,
- UCYCOM_N_TRANSFER,
-};
-
-struct ucycom_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[UCYCOM_N_TRANSFER];
-
- uint32_t sc_model;
-#define MODEL_CY7C63743 0x63743
-#define MODEL_CY7C64013 0x64013
-
- uint16_t sc_flen; /* feature report length */
- uint16_t sc_ilen; /* input report length */
- uint16_t sc_olen; /* output report length */
-
- uint8_t sc_fid; /* feature report id */
- uint8_t sc_iid; /* input report id */
- uint8_t sc_oid; /* output report id */
- 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_name[16];
- uint8_t sc_iface_no;
- uint8_t sc_temp_cfg[32];
-};
-
-/* prototypes */
-
-static device_probe_t ucycom_probe;
-static device_attach_t ucycom_attach;
-static device_detach_t ucycom_detach;
-
-static usb2_callback_t ucycom_ctrl_write_callback;
-static usb2_callback_t ucycom_intr_read_callback;
-
-static void ucycom_cfg_open(struct usb2_com_softc *);
-static void ucycom_start_read(struct usb2_com_softc *);
-static void ucycom_stop_read(struct usb2_com_softc *);
-static void ucycom_start_write(struct usb2_com_softc *);
-static void ucycom_stop_write(struct usb2_com_softc *);
-static void ucycom_cfg_write(struct ucycom_softc *, uint32_t, uint8_t);
-static int ucycom_pre_param(struct usb2_com_softc *, struct termios *);
-static void ucycom_cfg_param(struct usb2_com_softc *, struct termios *);
-
-static const struct usb2_config ucycom_config[UCYCOM_N_TRANSFER] = {
-
- [UCYCOM_CTRL_RD] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = (sizeof(struct usb2_device_request) + UCYCOM_MAX_IOLEN),
- .mh.flags = {},
- .mh.callback = &ucycom_ctrl_write_callback,
- .mh.timeout = 1000, /* 1 second */
- },
-
- [UCYCOM_INTR_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = UCYCOM_MAX_IOLEN,
- .mh.callback = &ucycom_intr_read_callback,
- },
-};
-
-static const struct usb2_com_callback ucycom_callback = {
- .usb2_com_cfg_param = &ucycom_cfg_param,
- .usb2_com_cfg_open = &ucycom_cfg_open,
- .usb2_com_pre_param = &ucycom_pre_param,
- .usb2_com_start_read = &ucycom_start_read,
- .usb2_com_stop_read = &ucycom_stop_read,
- .usb2_com_start_write = &ucycom_start_write,
- .usb2_com_stop_write = &ucycom_stop_write,
-};
-
-static device_method_t ucycom_methods[] = {
- DEVMETHOD(device_probe, ucycom_probe),
- DEVMETHOD(device_attach, ucycom_attach),
- DEVMETHOD(device_detach, ucycom_detach),
- {0, 0}
-};
-
-static devclass_t ucycom_devclass;
-
-static driver_t ucycom_driver = {
- .name = "ucycom",
- .methods = ucycom_methods,
- .size = sizeof(struct ucycom_softc),
-};
-
-DRIVER_MODULE(ucycom, ushub, ucycom_driver, ucycom_devclass, NULL, 0);
-MODULE_DEPEND(ucycom, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(ucycom, usb2_core, 1, 1, 1);
-
-/*
- * Supported devices
- */
-static const struct usb2_device_id ucycom_devs[] = {
- {USB_VPI(USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE, MODEL_CY7C64013)},
-};
-
-#define UCYCOM_DEFAULT_RATE 4800
-#define UCYCOM_DEFAULT_CFG 0x03 /* N-8-1 */
-
-static int
-ucycom_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != 0) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != UCYCOM_IFACE_INDEX) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(ucycom_devs, sizeof(ucycom_devs), uaa));
-}
-
-static int
-ucycom_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ucycom_softc *sc = device_get_softc(dev);
- void *urd_ptr = NULL;
- int32_t error;
- uint16_t urd_len;
- uint8_t iface_index;
-
- sc->sc_udev = uaa->device;
-
- device_set_usb2_desc(dev);
-
- snprintf(sc->sc_name, sizeof(sc->sc_name),
- "%s", device_get_nameunit(dev));
-
- DPRINTF("\n");
-
- /* get chip model */
- sc->sc_model = USB_GET_DRIVER_INFO(uaa);
- if (sc->sc_model == 0) {
- device_printf(dev, "unsupported device\n");
- goto detach;
- }
- device_printf(dev, "Cypress CY7C%X USB to RS232 bridge\n", sc->sc_model);
-
- /* get report descriptor */
-
- error = usb2_req_get_hid_desc
- (uaa->device, &Giant,
- &urd_ptr, &urd_len, M_USBDEV,
- UCYCOM_IFACE_INDEX);
-
- if (error) {
- device_printf(dev, "failed to get report "
- "descriptor: %s\n",
- usb2_errstr(error));
- goto detach;
- }
- /* get report sizes */
-
- sc->sc_flen = hid_report_size(urd_ptr, urd_len, hid_feature, &sc->sc_fid);
- sc->sc_ilen = hid_report_size(urd_ptr, urd_len, hid_input, &sc->sc_iid);
- sc->sc_olen = hid_report_size(urd_ptr, urd_len, hid_output, &sc->sc_oid);
-
- if ((sc->sc_ilen > UCYCOM_MAX_IOLEN) || (sc->sc_ilen < 1) ||
- (sc->sc_olen > UCYCOM_MAX_IOLEN) || (sc->sc_olen < 2) ||
- (sc->sc_flen > UCYCOM_MAX_IOLEN) || (sc->sc_flen < 5)) {
- device_printf(dev, "invalid report size i=%d, o=%d, f=%d, max=%d\n",
- sc->sc_ilen, sc->sc_olen, sc->sc_flen,
- UCYCOM_MAX_IOLEN);
- goto detach;
- }
- sc->sc_iface_no = uaa->info.bIfaceNum;
-
- iface_index = UCYCOM_IFACE_INDEX;
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, ucycom_config, UCYCOM_N_TRANSFER,
- sc, &Giant);
- if (error) {
- device_printf(dev, "allocating USB "
- "transfers failed!\n");
- goto detach;
- }
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &ucycom_callback, &Giant);
-
- if (error) {
- goto detach;
- }
- if (urd_ptr) {
- free(urd_ptr, M_USBDEV);
- }
- return (0); /* success */
-
-detach:
- if (urd_ptr) {
- free(urd_ptr, M_USBDEV);
- }
- ucycom_detach(dev);
- return (ENXIO);
-}
-
-static int
-ucycom_detach(device_t dev)
-{
- struct ucycom_softc *sc = device_get_softc(dev);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UCYCOM_N_TRANSFER);
-
- return (0);
-}
-
-static void
-ucycom_cfg_open(struct usb2_com_softc *ucom)
-{
- struct ucycom_softc *sc = ucom->sc_parent;
-
- /* set default configuration */
- ucycom_cfg_write(sc, UCYCOM_DEFAULT_RATE, UCYCOM_DEFAULT_CFG);
-}
-
-static void
-ucycom_start_read(struct usb2_com_softc *ucom)
-{
- struct ucycom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UCYCOM_INTR_RD]);
-}
-
-static void
-ucycom_stop_read(struct usb2_com_softc *ucom)
-{
- struct ucycom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UCYCOM_INTR_RD]);
-}
-
-static void
-ucycom_start_write(struct usb2_com_softc *ucom)
-{
- struct ucycom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UCYCOM_CTRL_RD]);
-}
-
-static void
-ucycom_stop_write(struct usb2_com_softc *ucom)
-{
- struct ucycom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UCYCOM_CTRL_RD]);
-}
-
-static void
-ucycom_ctrl_write_callback(struct usb2_xfer *xfer)
-{
- struct ucycom_softc *sc = xfer->priv_sc;
- struct usb2_device_request req;
- uint8_t data[2];
- uint8_t offset;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-tr_transferred:
- case USB_ST_SETUP:
-
- switch (sc->sc_model) {
- case MODEL_CY7C63743:
- offset = 1;
- break;
- case MODEL_CY7C64013:
- offset = 2;
- break;
- default:
- offset = 0;
- break;
- }
-
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers + 1, offset,
- sc->sc_olen - offset, &actlen)) {
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, UHID_OUTPUT_REPORT, sc->sc_oid);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, sc->sc_olen);
-
- switch (sc->sc_model) {
- case MODEL_CY7C63743:
- data[0] = actlen;
- break;
- case MODEL_CY7C64013:
- data[0] = 0;
- data[1] = actlen;
- break;
- default:
- break;
- }
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
- usb2_copy_in(xfer->frbuffers + 1, 0, data, offset);
-
- xfer->frlengths[0] = sizeof(req);
- xfer->frlengths[1] = sc->sc_olen;
- xfer->nframes = xfer->frlengths[1] ? 2 : 1;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- return;
- }
- DPRINTF("error=%s\n",
- usb2_errstr(xfer->error));
- goto tr_transferred;
- }
-}
-
-static void
-ucycom_cfg_write(struct ucycom_softc *sc, uint32_t baud, uint8_t cfg)
-{
- struct usb2_device_request req;
- uint16_t len;
- usb2_error_t err;
-
- len = sc->sc_flen;
- if (len > sizeof(sc->sc_temp_cfg)) {
- len = sizeof(sc->sc_temp_cfg);
- }
- sc->sc_cfg = cfg;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, UHID_FEATURE_REPORT, sc->sc_fid);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, len);
-
- sc->sc_temp_cfg[0] = (baud & 0xff);
- sc->sc_temp_cfg[1] = (baud >> 8) & 0xff;
- sc->sc_temp_cfg[2] = (baud >> 16) & 0xff;
- sc->sc_temp_cfg[3] = (baud >> 24) & 0xff;
- sc->sc_temp_cfg[4] = cfg;
-
- err = usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, sc->sc_temp_cfg, 0, 1000);
- if (err) {
- DPRINTFN(0, "device request failed, err=%s "
- "(ignored)\n", usb2_errstr(err));
- }
-}
-
-static int
-ucycom_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- switch (t->c_ospeed) {
- 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);
- }
- return (0);
-}
-
-static void
-ucycom_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct ucycom_softc *sc = ucom->sc_parent;
- uint8_t cfg;
-
- DPRINTF("\n");
-
- if (t->c_cflag & CIGNORE) {
- cfg = sc->sc_cfg;
- } else {
- cfg = 0;
- switch (t->c_cflag & CSIZE) {
- default:
- case CS8:
- ++cfg;
- case CS7:
- ++cfg;
- case CS6:
- ++cfg;
- case CS5:
- break;
- }
-
- 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;
- }
-
- ucycom_cfg_write(sc, t->c_ospeed, cfg);
-}
-
-static void
-ucycom_intr_read_callback(struct usb2_xfer *xfer)
-{
- struct ucycom_softc *sc = xfer->priv_sc;
- uint8_t buf[2];
- uint32_t offset;
- uint32_t len;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- switch (sc->sc_model) {
- case MODEL_CY7C63743:
- if (xfer->actlen < 1) {
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, 0, buf, 1);
-
- sc->sc_ist = buf[0] & ~0x07;
- len = buf[0] & 0x07;
-
- (xfer->actlen)--;
-
- offset = 1;
-
- break;
-
- case MODEL_CY7C64013:
- if (xfer->actlen < 2) {
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, 0, buf, 2);
-
- sc->sc_ist = buf[0] & ~0x07;
- len = buf[1];
-
- (xfer->actlen) -= 2;
-
- offset = 2;
-
- break;
-
- default:
- DPRINTFN(0, "unsupported model number!\n");
- goto tr_setup;
- }
-
- if (len > xfer->actlen) {
- len = xfer->actlen;
- }
- if (len) {
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers,
- offset, len);
- }
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = sc->sc_ilen;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
diff --git a/sys/dev/usb2/serial/ufoma2.c b/sys/dev/usb2/serial/ufoma2.c
deleted file mode 100644
index 12f49d7..0000000
--- a/sys/dev/usb2/serial/ufoma2.c
+++ /dev/null
@@ -1,1212 +0,0 @@
-/* $NetBSD: umodem.c,v 1.45 2002/09/23 05:51:23 simonb Exp $ */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#define UFOMA_HANDSFREE
-/*-
- * 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:
- * - Implement a Call Device for modems without multiplexed commands.
- */
-
-/*
- * NOTE: all function names beginning like "ufoma_cfg_" can only
- * be called from within the config thread function !
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_parse.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-#include <sys/sysctl.h>
-#include <sys/sbuf.h>
-
-typedef struct ufoma_mobile_acm_descriptor {
- uint8_t bFunctionLength;
- uint8_t bDescriptorType;
- uint8_t bDescriptorSubtype;
- uint8_t bType;
- uint8_t bMode[1];
-} __packed usb2_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_ACKNOWLEDGE 0x31
-
-#define UFOMA_MAX_TIMEOUT 15 /* standard says 10 seconds */
-#define UFOMA_CMD_BUF_SIZE 64 /* bytes */
-
-#define UFOMA_BULK_BUF_SIZE 1024 /* bytes */
-
-enum {
- UFOMA_CTRL_ENDPT_INTR,
- UFOMA_CTRL_ENDPT_READ,
- UFOMA_CTRL_ENDPT_WRITE,
- UFOMA_CTRL_ENDPT_MAX,
-};
-
-enum {
- UFOMA_BULK_ENDPT_WRITE,
- UFOMA_BULK_ENDPT_READ,
- UFOMA_BULK_ENDPT_MAX,
-};
-
-struct ufoma_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
- struct cv sc_cv;
-
- struct usb2_xfer *sc_ctrl_xfer[UFOMA_CTRL_ENDPT_MAX];
- struct usb2_xfer *sc_bulk_xfer[UFOMA_BULK_ENDPT_MAX];
- uint8_t *sc_modetable;
- device_t sc_dev;
- struct usb2_device *sc_udev;
-
- uint32_t sc_unit;
-
- uint16_t sc_line;
-
- uint8_t sc_num_msg;
- uint8_t sc_nobulk;
- uint8_t sc_ctrl_iface_no;
- uint8_t sc_ctrl_iface_index;
- uint8_t sc_data_iface_no;
- uint8_t sc_data_iface_index;
- uint8_t sc_cm_cap;
- uint8_t sc_acm_cap;
- uint8_t sc_lsr;
- uint8_t sc_msr;
- uint8_t sc_modetoactivate;
- uint8_t sc_currentmode;
- uint8_t sc_name[16];
-};
-
-/* prototypes */
-
-static device_probe_t ufoma_probe;
-static device_attach_t ufoma_attach;
-static device_detach_t ufoma_detach;
-
-static usb2_callback_t ufoma_ctrl_read_callback;
-static usb2_callback_t ufoma_ctrl_write_callback;
-static usb2_callback_t ufoma_intr_callback;
-static usb2_callback_t ufoma_bulk_write_callback;
-static usb2_callback_t ufoma_bulk_read_callback;
-
-static void *ufoma_get_intconf(struct usb2_config_descriptor *,
- struct usb2_interface_descriptor *, uint8_t, uint8_t);
-static void ufoma_cfg_link_state(struct ufoma_softc *);
-static void ufoma_cfg_activate_state(struct ufoma_softc *, uint16_t);
-static void ufoma_cfg_open(struct usb2_com_softc *);
-static void ufoma_cfg_close(struct usb2_com_softc *);
-static void ufoma_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static void ufoma_cfg_get_status(struct usb2_com_softc *, uint8_t *,
- uint8_t *);
-static void ufoma_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
-static void ufoma_cfg_set_rts(struct usb2_com_softc *, uint8_t);
-static int ufoma_pre_param(struct usb2_com_softc *, struct termios *);
-static void ufoma_cfg_param(struct usb2_com_softc *, struct termios *);
-static int ufoma_modem_setup(device_t, struct ufoma_softc *,
- struct usb2_attach_arg *);
-static void ufoma_start_read(struct usb2_com_softc *);
-static void ufoma_stop_read(struct usb2_com_softc *);
-static void ufoma_start_write(struct usb2_com_softc *);
-static void ufoma_stop_write(struct usb2_com_softc *);
-
-/*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 const struct usb2_config
- ufoma_ctrl_config[UFOMA_CTRL_ENDPT_MAX] = {
-
- [UFOMA_CTRL_ENDPT_INTR] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = sizeof(struct usb2_cdc_notification),
- .mh.callback = &ufoma_intr_callback,
- },
-
- [UFOMA_CTRL_ENDPT_READ] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = (sizeof(struct usb2_device_request) + UFOMA_CMD_BUF_SIZE),
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &ufoma_ctrl_read_callback,
- .mh.timeout = 1000, /* 1 second */
- },
-
- [UFOMA_CTRL_ENDPT_WRITE] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = (sizeof(struct usb2_device_request) + 1),
- .mh.flags = {},
- .mh.callback = &ufoma_ctrl_write_callback,
- .mh.timeout = 1000, /* 1 second */
- },
-};
-
-static const struct usb2_config
- ufoma_bulk_config[UFOMA_BULK_ENDPT_MAX] = {
-
- [UFOMA_BULK_ENDPT_WRITE] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UFOMA_BULK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &ufoma_bulk_write_callback,
- },
-
- [UFOMA_BULK_ENDPT_READ] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UFOMA_BULK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &ufoma_bulk_read_callback,
- },
-};
-
-static const struct usb2_com_callback ufoma_callback = {
- .usb2_com_cfg_get_status = &ufoma_cfg_get_status,
- .usb2_com_cfg_set_dtr = &ufoma_cfg_set_dtr,
- .usb2_com_cfg_set_rts = &ufoma_cfg_set_rts,
- .usb2_com_cfg_set_break = &ufoma_cfg_set_break,
- .usb2_com_cfg_param = &ufoma_cfg_param,
- .usb2_com_cfg_open = &ufoma_cfg_open,
- .usb2_com_cfg_close = &ufoma_cfg_close,
- .usb2_com_pre_param = &ufoma_pre_param,
- .usb2_com_start_read = &ufoma_start_read,
- .usb2_com_stop_read = &ufoma_stop_read,
- .usb2_com_start_write = &ufoma_start_write,
- .usb2_com_stop_write = &ufoma_stop_write,
-};
-
-static device_method_t ufoma_methods[] = {
- /* Device methods */
- DEVMETHOD(device_probe, ufoma_probe),
- DEVMETHOD(device_attach, ufoma_attach),
- DEVMETHOD(device_detach, ufoma_detach),
- {0, 0}
-};
-
-static devclass_t ufoma_devclass;
-
-static driver_t ufoma_driver = {
- .name = "ufoma",
- .methods = ufoma_methods,
- .size = sizeof(struct ufoma_softc),
-};
-
-DRIVER_MODULE(ufoma, ushub, ufoma_driver, ufoma_devclass, NULL, 0);
-MODULE_DEPEND(ufoma, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(ufoma, usb2_core, 1, 1, 1);
-
-static int
-ufoma_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct usb2_interface_descriptor *id;
- struct usb2_config_descriptor *cd;
- usb2_mcpc_acm_descriptor *mad;
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- id = usb2_get_interface_descriptor(uaa->iface);
- cd = usb2_get_config_descriptor(uaa->device);
-
- if ((id == NULL) ||
- (cd == NULL) ||
- (id->bInterfaceClass != UICLASS_CDC) ||
- (id->bInterfaceSubClass != UISUBCLASS_MCPC)) {
- return (ENXIO);
- }
- mad = ufoma_get_intconf(cd, id, UDESC_VS_INTERFACE, UDESCSUB_MCPC_ACM);
- if (mad == NULL) {
- return (ENXIO);
- }
-#ifndef UFOMA_HANDSFREE
- if ((mad->bType == UMCPC_ACM_TYPE_AB5) ||
- (mad->bType == UMCPC_ACM_TYPE_AB6)) {
- return (ENXIO);
- }
-#endif
- return (0);
-}
-
-static int
-ufoma_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ufoma_softc *sc = device_get_softc(dev);
- struct usb2_config_descriptor *cd;
- struct usb2_interface_descriptor *id;
- struct sysctl_ctx_list *sctx;
- struct sysctl_oid *soid;
-
- usb2_mcpc_acm_descriptor *mad;
- uint8_t elements;
- int32_t error;
-
- sc->sc_udev = uaa->device;
- sc->sc_dev = dev;
- sc->sc_unit = device_get_unit(dev);
-
- usb2_cv_init(&sc->sc_cv, "CWAIT");
-
- device_set_usb2_desc(dev);
-
- snprintf(sc->sc_name, sizeof(sc->sc_name),
- "%s", device_get_nameunit(dev));
-
- DPRINTF("\n");
-
- /* setup control transfers */
-
- cd = usb2_get_config_descriptor(uaa->device);
- id = usb2_get_interface_descriptor(uaa->iface);
- sc->sc_ctrl_iface_no = id->bInterfaceNumber;
- sc->sc_ctrl_iface_index = uaa->info.bIfaceIndex;
-
- error = usb2_transfer_setup(uaa->device,
- &sc->sc_ctrl_iface_index, sc->sc_ctrl_xfer,
- ufoma_ctrl_config, UFOMA_CTRL_ENDPT_MAX, sc, &Giant);
-
- if (error) {
- device_printf(dev, "allocating control USB "
- "transfers failed!\n");
- goto detach;
- }
- mad = ufoma_get_intconf(cd, id, UDESC_VS_INTERFACE, UDESCSUB_MCPC_ACM);
- if (mad == NULL) {
- goto detach;
- }
- if (mad->bFunctionLength < sizeof(*mad)) {
- device_printf(dev, "invalid MAD descriptor\n");
- goto detach;
- }
- if ((mad->bType == UMCPC_ACM_TYPE_AB5) ||
- (mad->bType == UMCPC_ACM_TYPE_AB6)) {
- sc->sc_nobulk = 1;
- } else {
- sc->sc_nobulk = 0;
- if (ufoma_modem_setup(dev, sc, uaa)) {
- goto detach;
- }
- }
-
- elements = (mad->bFunctionLength - sizeof(*mad) + 1);
-
- /* initialize mode variables */
-
- sc->sc_modetable = malloc(elements + 1, M_USBDEV, M_WAITOK);
-
- if (sc->sc_modetable == NULL) {
- goto detach;
- }
- 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];
-
- /* clear stall at first run, if any */
- usb2_transfer_set_stall(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_WRITE]);
- usb2_transfer_set_stall(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_READ]);
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &ufoma_callback, &Giant);
- if (error) {
- DPRINTF("usb2_com_attach failed\n");
- goto detach;
- }
- /*Sysctls*/
- sctx = device_get_sysctl_ctx(dev);
- soid = device_get_sysctl_tree(dev);
-
- 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");
- SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "comunit",
- CTLFLAG_RD, &(sc->sc_ucom.sc_unit), 0,
- "Unit number as USB serial");
-
- return (0); /* success */
-
-detach:
- ufoma_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-ufoma_detach(device_t dev)
-{
- struct ufoma_softc *sc = device_get_softc(dev);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_ctrl_xfer, UFOMA_CTRL_ENDPT_MAX);
-
- usb2_transfer_unsetup(sc->sc_bulk_xfer, UFOMA_BULK_ENDPT_MAX);
-
- if (sc->sc_modetable) {
- free(sc->sc_modetable, M_USBDEV);
- }
- usb2_cv_destroy(&sc->sc_cv);
-
- return (0);
-}
-
-static void *
-ufoma_get_intconf(struct usb2_config_descriptor *cd, struct usb2_interface_descriptor *id,
- uint8_t type, uint8_t subtype)
-{
- struct usb2_descriptor *desc = (void *)id;
-
- while ((desc = usb2_desc_foreach(cd, desc))) {
-
- if (desc->bDescriptorType == UDESC_INTERFACE) {
- return (NULL);
- }
- if ((desc->bDescriptorType == type) &&
- (desc->bDescriptorSubtype == subtype)) {
- break;
- }
- }
- return (desc);
-}
-
-static void
-ufoma_cfg_link_state(struct ufoma_softc *sc)
-{
- struct usb2_device_request req;
- int32_t error;
-
- req.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
- req.bRequest = UMCPC_SET_LINK;
- USETW(req.wValue, UMCPC_CM_MOBILE_ACM);
- USETW(req.wIndex, sc->sc_ctrl_iface_no);
- USETW(req.wLength, sc->sc_modetable[0]);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, sc->sc_modetable, 0, 1000);
-
- error = usb2_cv_timedwait(&sc->sc_cv, &Giant, hz);
-
- if (error) {
- DPRINTF("NO response\n");
- }
-}
-
-static void
-ufoma_cfg_activate_state(struct ufoma_softc *sc, uint16_t state)
-{
- struct usb2_device_request req;
- int32_t error;
-
- req.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
- req.bRequest = UMCPC_ACTIVATE_MODE;
- USETW(req.wValue, state);
- USETW(req.wIndex, sc->sc_ctrl_iface_no);
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-
- error = usb2_cv_timedwait(&sc->sc_cv, &Giant,
- (UFOMA_MAX_TIMEOUT * hz));
- if (error) {
- DPRINTF("No response\n");
- }
-}
-
-static void
-ufoma_ctrl_read_callback(struct usb2_xfer *xfer)
-{
- struct ufoma_softc *sc = xfer->priv_sc;
- struct usb2_device_request req;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-tr_transferred:
- if (xfer->aframes != xfer->nframes) {
- goto tr_setup;
- }
- if (xfer->frlengths[1] > 0) {
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers + 1,
- 0, xfer->frlengths[1]);
- }
- case USB_ST_SETUP:
-tr_setup:
- if (sc->sc_num_msg) {
- sc->sc_num_msg--;
-
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UCDC_GET_ENCAPSULATED_RESPONSE;
- USETW(req.wIndex, sc->sc_ctrl_iface_no);
- USETW(req.wValue, 0);
- USETW(req.wLength, UFOMA_CMD_BUF_SIZE);
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
-
- xfer->frlengths[0] = sizeof(req);
- xfer->frlengths[1] = UFOMA_CMD_BUF_SIZE;
- xfer->nframes = 2;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- DPRINTF("error = %s\n",
- usb2_errstr(xfer->error));
-
- if (xfer->error == USB_ERR_CANCELLED) {
- return;
- } else {
- goto tr_setup;
- }
-
- goto tr_transferred;
- }
-}
-
-static void
-ufoma_ctrl_write_callback(struct usb2_xfer *xfer)
-{
- struct ufoma_softc *sc = xfer->priv_sc;
- struct usb2_device_request req;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-tr_transferred:
- case USB_ST_SETUP:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers + 1,
- 0, 1, &actlen)) {
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND;
- USETW(req.wIndex, sc->sc_ctrl_iface_no);
- USETW(req.wValue, 0);
- USETW(req.wLength, 1);
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
-
- xfer->frlengths[0] = sizeof(req);
- xfer->frlengths[1] = 1;
- xfer->nframes = 2;
-
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- DPRINTF("error = %s\n",
- usb2_errstr(xfer->error));
-
- if (xfer->error == USB_ERR_CANCELLED) {
- return;
- } else {
- goto tr_setup;
- }
-
- goto tr_transferred;
- }
-}
-
-static void
-ufoma_intr_callback(struct usb2_xfer *xfer)
-{
- struct ufoma_softc *sc = xfer->priv_sc;
- struct usb2_cdc_notification pkt;
- uint16_t wLen;
- uint16_t temp;
- uint8_t mstatus;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- if (xfer->actlen < 8) {
- DPRINTF("too short message\n");
- goto tr_setup;
- }
- if (xfer->actlen > sizeof(pkt)) {
- DPRINTF("truncating message\n");
- xfer->actlen = sizeof(pkt);
- }
- usb2_copy_out(xfer->frbuffers, 0, &pkt, xfer->actlen);
-
- xfer->actlen -= 8;
-
- wLen = UGETW(pkt.wLength);
- if (xfer->actlen > wLen) {
- xfer->actlen = wLen;
- }
- if ((pkt.bmRequestType == UT_READ_VENDOR_INTERFACE) &&
- (pkt.bNotification == UMCPC_REQUEST_ACKNOWLEDGE)) {
- temp = UGETW(pkt.wValue);
- sc->sc_currentmode = (temp >> 8);
- if (!(temp & 0xff)) {
- DPRINTF("Mode change failed!\n");
- }
- usb2_cv_signal(&sc->sc_cv);
- }
- if (pkt.bmRequestType != UCDC_NOTIFICATION) {
- goto tr_setup;
- }
- switch (pkt.bNotification) {
- case UCDC_N_RESPONSE_AVAILABLE:
- if (!(sc->sc_nobulk)) {
- DPRINTF("Wrong serial state!\n");
- break;
- }
- if (sc->sc_num_msg != 0xFF) {
- sc->sc_num_msg++;
- }
- usb2_transfer_start(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_READ]);
- break;
-
- case UCDC_N_SERIAL_STATE:
- if (sc->sc_nobulk) {
- DPRINTF("Wrong serial state!\n");
- break;
- }
- /*
- * Set the serial state in ucom driver based on
- * the bits from the notify message
- */
- if (xfer->actlen < 2) {
- DPRINTF("invalid notification "
- "length, %d bytes!\n", xfer->actlen);
- break;
- }
- DPRINTF("notify bytes = 0x%02x, 0x%02x\n",
- pkt.data[0], pkt.data[1]);
-
- /* currently, lsr is always zero. */
- sc->sc_lsr = 0;
- sc->sc_msr = 0;
-
- mstatus = pkt.data[0];
-
- if (mstatus & UCDC_N_SERIAL_RI) {
- sc->sc_msr |= SER_RI;
- }
- if (mstatus & UCDC_N_SERIAL_DSR) {
- sc->sc_msr |= SER_DSR;
- }
- if (mstatus & UCDC_N_SERIAL_DCD) {
- sc->sc_msr |= SER_DCD;
- }
- usb2_com_status_change(&sc->sc_ucom);
- break;
-
- default:
- break;
- }
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-ufoma_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct ufoma_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- UFOMA_BULK_BUF_SIZE, &actlen)) {
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-ufoma_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct ufoma_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0,
- xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-ufoma_cfg_open(struct usb2_com_softc *ucom)
-{
- struct ufoma_softc *sc = ucom->sc_parent;
-
- /* empty input queue */
-
- if (sc->sc_num_msg != 0xFF) {
- sc->sc_num_msg++;
- }
- if (sc->sc_currentmode == UMCPC_ACM_MODE_UNLINKED) {
- ufoma_cfg_link_state(sc);
- }
- if (sc->sc_currentmode == UMCPC_ACM_MODE_DEACTIVATED) {
- ufoma_cfg_activate_state(sc, sc->sc_modetoactivate);
- }
-}
-
-static void
-ufoma_cfg_close(struct usb2_com_softc *ucom)
-{
- struct ufoma_softc *sc = ucom->sc_parent;
-
- ufoma_cfg_activate_state(sc, UMCPC_ACM_MODE_DEACTIVATED);
-}
-
-static void
-ufoma_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct ufoma_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
- uint16_t wValue;
-
- if (sc->sc_nobulk ||
- (sc->sc_currentmode == UMCPC_ACM_MODE_OBEX)) {
- return;
- }
- if (!(sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK)) {
- return;
- }
- wValue = onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
- USETW(req.wValue, wValue);
- req.wIndex[0] = sc->sc_ctrl_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-ufoma_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
- struct ufoma_softc *sc = ucom->sc_parent;
-
- *lsr = sc->sc_lsr;
- *msr = sc->sc_msr;
-}
-
-static void
-ufoma_cfg_set_line_state(struct ufoma_softc *sc)
-{
- struct usb2_device_request req;
-
- /* Don't send line state emulation request for OBEX port */
- if (sc->sc_currentmode == UMCPC_ACM_MODE_OBEX) {
- return;
- }
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, sc->sc_line);
- req.wIndex[0] = sc->sc_ctrl_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-ufoma_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct ufoma_softc *sc = ucom->sc_parent;
-
- if (sc->sc_nobulk) {
- return;
- }
- if (onoff)
- sc->sc_line |= UCDC_LINE_DTR;
- else
- sc->sc_line &= ~UCDC_LINE_DTR;
-
- ufoma_cfg_set_line_state(sc);
-}
-
-static void
-ufoma_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct ufoma_softc *sc = ucom->sc_parent;
-
- if (sc->sc_nobulk) {
- return;
- }
- if (onoff)
- sc->sc_line |= UCDC_LINE_RTS;
- else
- sc->sc_line &= ~UCDC_LINE_RTS;
-
- ufoma_cfg_set_line_state(sc);
-}
-
-static int
-ufoma_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- return (0); /* we accept anything */
-}
-
-static void
-ufoma_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct ufoma_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
- struct usb2_cdc_line_state ls;
-
- if (sc->sc_nobulk ||
- (sc->sc_currentmode == UMCPC_ACM_MODE_OBEX)) {
- return;
- }
- DPRINTF("\n");
-
- bzero(&ls, sizeof(ls));
-
- USETDW(ls.dwDTERate, t->c_ospeed);
-
- if (t->c_cflag & CSTOPB) {
- ls.bCharFormat = UCDC_STOP_BIT_2;
- } else {
- ls.bCharFormat = UCDC_STOP_BIT_1;
- }
-
- if (t->c_cflag & PARENB) {
- if (t->c_cflag & PARODD) {
- ls.bParityType = UCDC_PARITY_ODD;
- } else {
- ls.bParityType = UCDC_PARITY_EVEN;
- }
- } else {
- ls.bParityType = UCDC_PARITY_NONE;
- }
-
- switch (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;
- }
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_LINE_CODING;
- USETW(req.wValue, 0);
- req.wIndex[0] = sc->sc_ctrl_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, UCDC_LINE_STATE_LENGTH);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, &ls, 0, 1000);
-}
-
-static int
-ufoma_modem_setup(device_t dev, struct ufoma_softc *sc,
- struct usb2_attach_arg *uaa)
-{
- struct usb2_config_descriptor *cd;
- struct usb2_cdc_acm_descriptor *acm;
- struct usb2_cdc_cm_descriptor *cmd;
- struct usb2_interface_descriptor *id;
- struct usb2_interface *iface;
- uint8_t i;
- int32_t error;
-
- cd = usb2_get_config_descriptor(uaa->device);
- id = usb2_get_interface_descriptor(uaa->iface);
-
- cmd = ufoma_get_intconf(cd, id, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
-
- if ((cmd == NULL) ||
- (cmd->bLength < sizeof(*cmd))) {
- return (EINVAL);
- }
- sc->sc_cm_cap = cmd->bmCapabilities;
- sc->sc_data_iface_no = cmd->bDataInterface;
-
- acm = ufoma_get_intconf(cd, id, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM);
-
- if ((acm == NULL) ||
- (acm->bLength < sizeof(*acm))) {
- return (EINVAL);
- }
- sc->sc_acm_cap = acm->bmCapabilities;
-
- device_printf(dev, "data interface %d, has %sCM over data, "
- "has %sbreak\n",
- 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 ");
-
- /* get the data interface too */
-
- for (i = 0;; i++) {
-
- iface = usb2_get_iface(uaa->device, i);
-
- if (iface) {
-
- id = usb2_get_interface_descriptor(iface);
-
- if (id && (id->bInterfaceNumber == sc->sc_data_iface_no)) {
- sc->sc_data_iface_index = i;
- usb2_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
- break;
- }
- } else {
- device_printf(dev, "no data interface!\n");
- return (EINVAL);
- }
- }
-
- error = usb2_transfer_setup(uaa->device,
- &sc->sc_data_iface_index, sc->sc_bulk_xfer,
- ufoma_bulk_config, UFOMA_BULK_ENDPT_MAX, sc, &Giant);
-
- if (error) {
- device_printf(dev, "allocating BULK USB "
- "transfers failed!\n");
- return (EINVAL);
- }
- return (0);
-}
-
-static void
-ufoma_start_read(struct usb2_com_softc *ucom)
-{
- struct ufoma_softc *sc = ucom->sc_parent;
-
- /* start interrupt transfer */
- usb2_transfer_start(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_INTR]);
-
- /* start data transfer */
- if (sc->sc_nobulk) {
- usb2_transfer_start(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_READ]);
- } else {
- usb2_transfer_start(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_READ]);
- }
-}
-
-static void
-ufoma_stop_read(struct usb2_com_softc *ucom)
-{
- struct ufoma_softc *sc = ucom->sc_parent;
-
- /* stop interrupt transfer */
- usb2_transfer_stop(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_INTR]);
-
- /* stop data transfer */
- if (sc->sc_nobulk) {
- usb2_transfer_stop(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_READ]);
- } else {
- usb2_transfer_stop(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_READ]);
- }
-}
-
-static void
-ufoma_start_write(struct usb2_com_softc *ucom)
-{
- struct ufoma_softc *sc = ucom->sc_parent;
-
- if (sc->sc_nobulk) {
- usb2_transfer_start(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_WRITE]);
- } else {
- usb2_transfer_start(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_WRITE]);
- }
-}
-
-static void
-ufoma_stop_write(struct usb2_com_softc *ucom)
-{
- struct ufoma_softc *sc = ucom->sc_parent;
-
- if (sc->sc_nobulk) {
- usb2_transfer_stop(sc->sc_ctrl_xfer[UFOMA_CTRL_ENDPT_WRITE]);
- } else {
- usb2_transfer_stop(sc->sc_bulk_xfer[UFOMA_BULK_ENDPT_WRITE]);
- }
-}
-
-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 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 int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS)
-{
- struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
- struct sbuf sb;
- int i;
- char *mode;
-
- sbuf_new(&sb, NULL, 1, SBUF_AUTOEXTEND);
- for(i = 1; i < sc->sc_modetable[0]; i++){
- mode = ufoma_mode_to_str(sc->sc_modetable[i]);
- if(mode !=NULL){
- sbuf_cat(&sb, mode);
- }else{
- sbuf_printf(&sb, "(%02x)", sc->sc_modetable[i]);
- }
- if(i < (sc->sc_modetable[0]-1))
- sbuf_cat(&sb, ",");
- }
- sbuf_trim(&sb);
- sbuf_finish(&sb);
- sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req);
- sbuf_delete(&sb);
-
- return 0;
-}
-static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS)
-{
- struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
- char *mode;
- char subbuf[]="(XXX)";
- mode = ufoma_mode_to_str(sc->sc_currentmode);
- if(!mode){
- mode = subbuf;
- snprintf(subbuf, sizeof(subbuf), "(%02x)", sc->sc_currentmode);
- }
- sysctl_handle_string(oidp, mode, strlen(mode), req);
-
- return 0;
-
-}
-static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS)
-{
- struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
- char *mode;
- char subbuf[40];
- int newmode;
- int error;
- int i;
-
- mode = ufoma_mode_to_str(sc->sc_modetoactivate);
- if(mode){
- strncpy(subbuf, mode, sizeof(subbuf));
- }else{
- snprintf(subbuf, sizeof(subbuf), "(%02x)", sc->sc_modetoactivate);
- }
- error = sysctl_handle_string(oidp, subbuf, sizeof(subbuf), req);
- if(error != 0 || req->newptr == NULL){
- return error;
- }
-
- if((newmode = ufoma_str_to_mode(subbuf)) == -1){
- return EINVAL;
- }
-
- for(i = 1 ; i < sc->sc_modetable[0] ; i++){
- if(sc->sc_modetable[i] == newmode){
- sc->sc_modetoactivate = newmode;
- return 0;
- }
- }
-
- return EINVAL;
-}
diff --git a/sys/dev/usb2/serial/uftdi2.c b/sys/dev/usb2/serial/uftdi2.c
deleted file mode 100644
index af211ed..0000000
--- a/sys/dev/usb2/serial/uftdi2.c
+++ /dev/null
@@ -1,784 +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$");
-
-/*
- * NOTE: all function names beginning like "uftdi_cfg_" can only
- * be called from within the config thread function !
- */
-
-/*
- * FTDI FT8U100AX serial adapter driver
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-
-#define USB_DEBUG_VAR uftdi_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-#include <dev/usb2/serial/uftdi2_reg.h>
-
-#if USB_DEBUG
-static int uftdi_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uftdi, CTLFLAG_RW, 0, "USB uftdi");
-SYSCTL_INT(_hw_usb2_uftdi, OID_AUTO, debug, CTLFLAG_RW,
- &uftdi_debug, 0, "Debug level");
-#endif
-
-#define UFTDI_CONFIG_INDEX 0
-#define UFTDI_IFACE_INDEX 0
-
-#define UFTDI_IBUFSIZE 64 /* bytes, maximum number of bytes per
- * frame */
-#define UFTDI_OBUFSIZE 64 /* bytes, cannot be increased due to
- * do size encoding */
-
-enum {
- UFTDI_BULK_DT_WR,
- UFTDI_BULK_DT_RD,
- UFTDI_N_TRANSFER,
-};
-
-struct uftdi_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[UFTDI_N_TRANSFER];
- device_t sc_dev;
-
- uint32_t sc_unit;
- enum uftdi_type sc_type;
-
- uint16_t sc_last_lcr;
-
- uint8_t sc_iface_index;
- uint8_t sc_hdrlen;
- uint8_t sc_msr;
- uint8_t sc_lsr;
-
- uint8_t sc_name[16];
-};
-
-struct uftdi_param_config {
- uint16_t rate;
- uint16_t lcr;
- uint8_t v_start;
- uint8_t v_stop;
- uint8_t v_flow;
-};
-
-/* prototypes */
-
-static device_probe_t uftdi_probe;
-static device_attach_t uftdi_attach;
-static device_detach_t uftdi_detach;
-
-static usb2_callback_t uftdi_write_callback;
-static usb2_callback_t uftdi_read_callback;
-
-static void uftdi_cfg_open(struct usb2_com_softc *);
-static void uftdi_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
-static void uftdi_cfg_set_rts(struct usb2_com_softc *, uint8_t);
-static void uftdi_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static int uftdi_set_parm_soft(struct termios *,
- struct uftdi_param_config *, uint8_t);
-static int uftdi_pre_param(struct usb2_com_softc *, struct termios *);
-static void uftdi_cfg_param(struct usb2_com_softc *, struct termios *);
-static void uftdi_cfg_get_status(struct usb2_com_softc *, uint8_t *,
- uint8_t *);
-static void uftdi_start_read(struct usb2_com_softc *);
-static void uftdi_stop_read(struct usb2_com_softc *);
-static void uftdi_start_write(struct usb2_com_softc *);
-static void uftdi_stop_write(struct usb2_com_softc *);
-static uint8_t uftdi_8u232am_getrate(uint32_t, uint16_t *);
-
-static const struct usb2_config uftdi_config[UFTDI_N_TRANSFER] = {
-
- [UFTDI_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UFTDI_OBUFSIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &uftdi_write_callback,
- },
-
- [UFTDI_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UFTDI_IBUFSIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &uftdi_read_callback,
- },
-};
-
-static const struct usb2_com_callback uftdi_callback = {
- .usb2_com_cfg_get_status = &uftdi_cfg_get_status,
- .usb2_com_cfg_set_dtr = &uftdi_cfg_set_dtr,
- .usb2_com_cfg_set_rts = &uftdi_cfg_set_rts,
- .usb2_com_cfg_set_break = &uftdi_cfg_set_break,
- .usb2_com_cfg_param = &uftdi_cfg_param,
- .usb2_com_cfg_open = &uftdi_cfg_open,
- .usb2_com_pre_param = &uftdi_pre_param,
- .usb2_com_start_read = &uftdi_start_read,
- .usb2_com_stop_read = &uftdi_stop_read,
- .usb2_com_start_write = &uftdi_start_write,
- .usb2_com_stop_write = &uftdi_stop_write,
-};
-
-static device_method_t uftdi_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uftdi_probe),
- DEVMETHOD(device_attach, uftdi_attach),
- DEVMETHOD(device_detach, uftdi_detach),
-
- {0, 0}
-};
-
-static devclass_t uftdi_devclass;
-
-static driver_t uftdi_driver = {
- .name = "uftdi",
- .methods = uftdi_methods,
- .size = sizeof(struct uftdi_softc),
-};
-
-DRIVER_MODULE(uftdi, ushub, uftdi_driver, uftdi_devclass, NULL, 0);
-MODULE_DEPEND(uftdi, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(uftdi, usb2_core, 1, 1, 1);
-
-static struct usb2_device_id uftdi_devs[] = {
- {USB_VPI(USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U100AX, UFTDI_TYPE_SIO)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232C, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U232AM, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SEMC_DSS20, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CFA_631, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CFA_632, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CFA_633, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CFA_634, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CFA_635, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_USBSERIAL, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MX2_3, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MX4_5, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LK202, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LK204, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13M, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13S, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13U, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_EISCOU, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_UOPTBR, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_EMCU2D, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PCMSFU, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_EMCU2H, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MAXSTREAM, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_SIIG2, USB_PRODUCT_SIIG2_US2308, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_VALUECAN, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_NEOVI, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_BBELECTRONICS, USB_PRODUCT_BBELECTRONICS_USOTL4, UFTDI_TYPE_8U232AM)},
- {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_PCOPRS1, UFTDI_TYPE_8U232AM)},
-};
-
-static int
-uftdi_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != UFTDI_CONFIG_INDEX) {
- return (ENXIO);
- }
- /* attach to all present interfaces */
-
- return (usb2_lookup_id_by_uaa(uftdi_devs, sizeof(uftdi_devs), uaa));
-}
-
-static int
-uftdi_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct uftdi_softc *sc = device_get_softc(dev);
- int error;
-
- sc->sc_udev = uaa->device;
- sc->sc_dev = dev;
- sc->sc_unit = device_get_unit(dev);
-
- device_set_usb2_desc(dev);
-
- snprintf(sc->sc_name, sizeof(sc->sc_name),
- "%s", device_get_nameunit(dev));
-
- DPRINTF("\n");
-
- sc->sc_iface_index = uaa->info.bIfaceIndex;
- sc->sc_type = USB_GET_DRIVER_INFO(uaa);
-
- switch (sc->sc_type) {
- case UFTDI_TYPE_SIO:
- sc->sc_hdrlen = 1;
- break;
- case UFTDI_TYPE_8U232AM:
- default:
- sc->sc_hdrlen = 0;
- break;
- }
-
- error = usb2_transfer_setup(uaa->device,
- &sc->sc_iface_index, sc->sc_xfer, uftdi_config,
- UFTDI_N_TRANSFER, sc, &Giant);
-
- if (error) {
- device_printf(dev, "allocating USB "
- "transfers failed!\n");
- goto detach;
- }
- sc->sc_ucom.sc_portno = FTDI_PIT_SIOA + uaa->info.bIfaceNum;
-
- /* clear stall at first run */
- usb2_transfer_set_stall(sc->sc_xfer[UFTDI_BULK_DT_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[UFTDI_BULK_DT_RD]);
-
- /* set a valid "lcr" value */
-
- sc->sc_last_lcr =
- (FTDI_SIO_SET_DATA_STOP_BITS_2 |
- FTDI_SIO_SET_DATA_PARITY_NONE |
- FTDI_SIO_SET_DATA_BITS(8));
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &uftdi_callback, &Giant);
- if (error) {
- goto detach;
- }
- return (0); /* success */
-
-detach:
- uftdi_detach(dev);
- return (ENXIO);
-}
-
-static int
-uftdi_detach(device_t dev)
-{
- struct uftdi_softc *sc = device_get_softc(dev);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UFTDI_N_TRANSFER);
-
- return (0);
-}
-
-static void
-uftdi_cfg_open(struct usb2_com_softc *ucom)
-{
- struct uftdi_softc *sc = ucom->sc_parent;
- uint16_t wIndex = ucom->sc_portno;
- struct usb2_device_request req;
-
- DPRINTF("");
-
- /* 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, wIndex);
- USETW(req.wLength, 0);
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-
- /* 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, wIndex);
- USETW(req.wLength, 0);
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-
- /*
- * NOTE: with the new UCOM layer there will always be a
- * "uftdi_cfg_param()" call after "open()", so there is no need for
- * "open()" to configure anything
- */
-}
-
-static void
-uftdi_write_callback(struct usb2_xfer *xfer)
-{
- struct uftdi_softc *sc = xfer->priv_sc;
- uint32_t actlen;
- uint8_t buf[1];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers,
- sc->sc_hdrlen, UFTDI_OBUFSIZE - sc->sc_hdrlen,
- &actlen)) {
-
- if (sc->sc_hdrlen > 0) {
- buf[0] =
- FTDI_OUT_TAG(actlen, sc->sc_ucom.sc_portno);
- usb2_copy_in(xfer->frbuffers, 0, buf, 1);
- }
- xfer->frlengths[0] = actlen + sc->sc_hdrlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uftdi_read_callback(struct usb2_xfer *xfer)
-{
- struct uftdi_softc *sc = xfer->priv_sc;
- uint8_t buf[2];
- uint8_t ftdi_msr;
- uint8_t msr;
- uint8_t lsr;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (xfer->actlen < 2) {
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, 0, buf, 2);
-
- ftdi_msr = FTDI_GET_MSR(buf);
- lsr = FTDI_GET_LSR(buf);
-
- msr = 0;
- if (ftdi_msr & FTDI_SIO_CTS_MASK)
- msr |= SER_CTS;
- if (ftdi_msr & FTDI_SIO_DSR_MASK)
- msr |= SER_DSR;
- if (ftdi_msr & FTDI_SIO_RI_MASK)
- msr |= SER_RI;
- if (ftdi_msr & FTDI_SIO_RLSD_MASK)
- msr |= SER_DCD;
-
- if ((sc->sc_msr != msr) ||
- ((sc->sc_lsr & FTDI_LSR_MASK) != (lsr & FTDI_LSR_MASK))) {
- DPRINTF("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;
-
- usb2_com_status_change(&sc->sc_ucom);
- }
- xfer->actlen -= 2;
-
- if (xfer->actlen > 0) {
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 2,
- xfer->actlen);
- }
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uftdi_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uftdi_softc *sc = ucom->sc_parent;
- uint16_t wIndex = ucom->sc_portno;
- uint16_t wValue;
- struct usb2_device_request req;
-
- wValue = onoff ? FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_MODEM_CTRL;
- USETW(req.wValue, wValue);
- USETW(req.wIndex, wIndex);
- USETW(req.wLength, 0);
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-uftdi_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uftdi_softc *sc = ucom->sc_parent;
- uint16_t wIndex = ucom->sc_portno;
- uint16_t wValue;
- struct usb2_device_request req;
-
- wValue = onoff ? FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_MODEM_CTRL;
- USETW(req.wValue, wValue);
- USETW(req.wIndex, wIndex);
- USETW(req.wLength, 0);
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-uftdi_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uftdi_softc *sc = ucom->sc_parent;
- uint16_t wIndex = ucom->sc_portno;
- uint16_t wValue;
- struct usb2_device_request req;
-
- if (onoff) {
- sc->sc_last_lcr |= FTDI_SIO_SET_BREAK;
- } else {
- sc->sc_last_lcr &= ~FTDI_SIO_SET_BREAK;
- }
-
- wValue = sc->sc_last_lcr;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_DATA;
- USETW(req.wValue, wValue);
- USETW(req.wIndex, wIndex);
- USETW(req.wLength, 0);
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static int
-uftdi_set_parm_soft(struct termios *t,
- struct uftdi_param_config *cfg, uint8_t type)
-{
- bzero(cfg, sizeof(*cfg));
-
- switch (type) {
- case UFTDI_TYPE_SIO:
- switch (t->c_ospeed) {
- case 300:
- cfg->rate = ftdi_sio_b300;
- break;
- case 600:
- cfg->rate = ftdi_sio_b600;
- break;
- case 1200:
- cfg->rate = ftdi_sio_b1200;
- break;
- case 2400:
- cfg->rate = ftdi_sio_b2400;
- break;
- case 4800:
- cfg->rate = ftdi_sio_b4800;
- break;
- case 9600:
- cfg->rate = ftdi_sio_b9600;
- break;
- case 19200:
- cfg->rate = ftdi_sio_b19200;
- break;
- case 38400:
- cfg->rate = ftdi_sio_b38400;
- break;
- case 57600:
- cfg->rate = ftdi_sio_b57600;
- break;
- case 115200:
- cfg->rate = ftdi_sio_b115200;
- break;
- default:
- return (EINVAL);
- }
- break;
-
- case UFTDI_TYPE_8U232AM:
- if (uftdi_8u232am_getrate(t->c_ospeed, &cfg->rate)) {
- return (EINVAL);
- }
- break;
- }
-
- if (t->c_cflag & CSTOPB)
- cfg->lcr = FTDI_SIO_SET_DATA_STOP_BITS_2;
- else
- cfg->lcr = FTDI_SIO_SET_DATA_STOP_BITS_1;
-
- if (t->c_cflag & PARENB) {
- if (t->c_cflag & PARODD) {
- cfg->lcr |= FTDI_SIO_SET_DATA_PARITY_ODD;
- } else {
- cfg->lcr |= FTDI_SIO_SET_DATA_PARITY_EVEN;
- }
- } else {
- cfg->lcr |= FTDI_SIO_SET_DATA_PARITY_NONE;
- }
-
- switch (t->c_cflag & CSIZE) {
- case CS5:
- cfg->lcr |= FTDI_SIO_SET_DATA_BITS(5);
- break;
-
- case CS6:
- cfg->lcr |= FTDI_SIO_SET_DATA_BITS(6);
- break;
-
- case CS7:
- cfg->lcr |= FTDI_SIO_SET_DATA_BITS(7);
- break;
-
- case CS8:
- cfg->lcr |= FTDI_SIO_SET_DATA_BITS(8);
- break;
- }
-
- if (t->c_cflag & CRTSCTS) {
- cfg->v_flow = FTDI_SIO_RTS_CTS_HS;
- } else if (t->c_iflag & (IXON | IXOFF)) {
- cfg->v_flow = FTDI_SIO_XON_XOFF_HS;
- cfg->v_start = t->c_cc[VSTART];
- cfg->v_stop = t->c_cc[VSTOP];
- } else {
- cfg->v_flow = FTDI_SIO_DISABLE_FLOW_CTRL;
- }
-
- return (0);
-}
-
-static int
-uftdi_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct uftdi_softc *sc = ucom->sc_parent;
- struct uftdi_param_config cfg;
-
- DPRINTF("\n");
-
- return (uftdi_set_parm_soft(t, &cfg, sc->sc_type));
-}
-
-static void
-uftdi_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct uftdi_softc *sc = ucom->sc_parent;
- uint16_t wIndex = ucom->sc_portno;
- struct uftdi_param_config cfg;
- struct usb2_device_request req;
-
- if (uftdi_set_parm_soft(t, &cfg, sc->sc_type)) {
- /* should not happen */
- return;
- }
- sc->sc_last_lcr = cfg.lcr;
-
- DPRINTF("\n");
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_BAUD_RATE;
- USETW(req.wValue, cfg.rate);
- USETW(req.wIndex, wIndex);
- USETW(req.wLength, 0);
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_DATA;
- USETW(req.wValue, cfg.lcr);
- USETW(req.wIndex, wIndex);
- USETW(req.wLength, 0);
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_FLOW_CTRL;
- USETW2(req.wValue, cfg.v_stop, cfg.v_start);
- USETW2(req.wIndex, cfg.v_flow, wIndex);
- USETW(req.wLength, 0);
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-uftdi_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
- struct uftdi_softc *sc = ucom->sc_parent;
-
- DPRINTF("msr=0x%02x lsr=0x%02x\n",
- sc->sc_msr, sc->sc_lsr);
-
- *msr = sc->sc_msr;
- *lsr = sc->sc_lsr;
-}
-
-static void
-uftdi_start_read(struct usb2_com_softc *ucom)
-{
- struct uftdi_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UFTDI_BULK_DT_RD]);
-}
-
-static void
-uftdi_stop_read(struct usb2_com_softc *ucom)
-{
- struct uftdi_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UFTDI_BULK_DT_RD]);
-}
-
-static void
-uftdi_start_write(struct usb2_com_softc *ucom)
-{
- struct uftdi_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UFTDI_BULK_DT_WR]);
-}
-
-static void
-uftdi_stop_write(struct usb2_com_softc *ucom)
-{
- struct uftdi_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UFTDI_BULK_DT_WR]);
-}
-
-/*------------------------------------------------------------------------*
- * uftdi_8u232am_getrate
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-uftdi_8u232am_getrate(uint32_t speed, uint16_t *rate)
-{
- /* Table of the nearest even powers-of-2 for values 0..15. */
- static const uint8_t roundoff[16] = {
- 0, 2, 2, 4, 4, 4, 8, 8,
- 8, 8, 8, 8, 16, 16, 16, 16,
- };
- uint32_t d;
- uint32_t freq;
- uint16_t result;
-
- if ((speed < 178) || (speed > ((3000000 * 100) / 97)))
- return (1); /* prevent numerical overflow */
-
- /* 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 < ((FTDI_8U232AM_FREQ * 1600ULL) / 103)) ||
- (freq > ((FTDI_8U232AM_FREQ * 1600ULL) / 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);
-}
diff --git a/sys/dev/usb2/serial/uftdi2_reg.h b/sys/dev/usb2/serial/uftdi2_reg.h
deleted file mode 100644
index 0074bc5..0000000
--- a/sys/dev/usb2/serial/uftdi2_reg.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/* $NetBSD: uftdireg.h,v 1.6 2002/07/11 21:14:28 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*
- * Definitions for the FTDI USB Single Port Serial Converter -
- * known as FTDI_SIO (Serial Input/Output application of the chipset)
- *
- * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side,
- * USB on the other.
- *
- * Thanx to FTDI (http://www.ftdi.co.uk) for so kindly providing details
- * of the protocol required to talk to the device and ongoing assistence
- * during development.
- *
- * Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc. is the original
- * author of this file.
- */
-/* Modified by Lennart Augustsson */
-
-/* Vendor Request Interface */
-#define FTDI_SIO_RESET 0 /* Reset the port */
-#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
-#define FTDI_SIO_SET_FLOW_CTRL 2 /* Set flow control register */
-#define FTDI_SIO_SET_BAUD_RATE 3 /* Set baud rate */
-#define FTDI_SIO_SET_DATA 4 /* Set the data characteristics of the
- * port */
-#define FTDI_SIO_GET_STATUS 5 /* Retrieve current value of status
- * reg */
-#define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */
-#define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */
-
-/* Port Identifier Table */
-#define FTDI_PIT_DEFAULT 0 /* SIOA */
-#define FTDI_PIT_SIOA 1 /* SIOA */
-#define FTDI_PIT_SIOB 2 /* SIOB */
-#define FTDI_PIT_PARALLEL 3 /* Parallel */
-
-enum uftdi_type {
- UFTDI_TYPE_SIO,
- UFTDI_TYPE_8U232AM
-};
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_RESET
- * wValue: Control Value
- * 0 = Reset SIO
- * 1 = Purge RX buffer
- * 2 = Purge TX buffer
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * The Reset SIO command has this effect:
- *
- * Sets flow control set to 'none'
- * Event char = 0x0d
- * Event trigger = disabled
- * Purge RX buffer
- * Purge TX buffer
- * Clear DTR
- * Clear RTS
- * baud and data format not reset
- *
- * The Purge RX and TX buffer commands affect nothing except the buffers
- *
- */
-/* FTDI_SIO_RESET */
-#define FTDI_SIO_RESET_SIO 0
-#define FTDI_SIO_RESET_PURGE_RX 1
-#define FTDI_SIO_RESET_PURGE_TX 2
-
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_SET_BAUDRATE
- * wValue: BaudRate value - see below
- * wIndex: Port
- * wLength: 0
- * Data: None
- */
-/* FTDI_SIO_SET_BAUDRATE */
-enum {
- ftdi_sio_b300 = 0,
- ftdi_sio_b600 = 1,
- ftdi_sio_b1200 = 2,
- ftdi_sio_b2400 = 3,
- ftdi_sio_b4800 = 4,
- ftdi_sio_b9600 = 5,
- ftdi_sio_b19200 = 6,
- ftdi_sio_b38400 = 7,
- ftdi_sio_b57600 = 8,
- ftdi_sio_b115200 = 9
-};
-
-#define FTDI_8U232AM_FREQ 3000000
-
-/* Bounds for normal divisors as 4-bit fixed precision ints. */
-#define FTDI_8U232AM_MIN_DIV 0x20
-#define FTDI_8U232AM_MAX_DIV 0x3fff8
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_SET_DATA
- * wValue: Data characteristics (see below)
- * wIndex: Port
- * wLength: 0
- * Data: No
- *
- * Data characteristics
- *
- * B0..7 Number of data bits
- * B8..10 Parity
- * 0 = None
- * 1 = Odd
- * 2 = Even
- * 3 = Mark
- * 4 = Space
- * B11..13 Stop Bits
- * 0 = 1
- * 1 = 1.5
- * 2 = 2
- * B14..15 Reserved
- *
- */
-/* FTDI_SIO_SET_DATA */
-#define FTDI_SIO_SET_DATA_BITS(n) (n)
-#define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8)
-#define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11)
-#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11)
-#define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11)
-#define FTDI_SIO_SET_BREAK (0x1 << 14)
-
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_MODEM_CTRL
- * wValue: ControlValue (see below)
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * NOTE: If the device is in RTS/CTS flow control, the RTS set by this
- * command will be IGNORED without an error being returned
- * Also - you can not set DTR and RTS with one control message
- *
- * ControlValue
- * B0 DTR state
- * 0 = reset
- * 1 = set
- * B1 RTS state
- * 0 = reset
- * 1 = set
- * B2..7 Reserved
- * B8 DTR state enable
- * 0 = ignore
- * 1 = use DTR state
- * B9 RTS state enable
- * 0 = ignore
- * 1 = use RTS state
- * B10..15 Reserved
- */
-/* FTDI_SIO_MODEM_CTRL */
-#define FTDI_SIO_SET_DTR_MASK 0x1
-#define FTDI_SIO_SET_DTR_HIGH (1 | ( FTDI_SIO_SET_DTR_MASK << 8))
-#define FTDI_SIO_SET_DTR_LOW (0 | ( FTDI_SIO_SET_DTR_MASK << 8))
-#define FTDI_SIO_SET_RTS_MASK 0x2
-#define FTDI_SIO_SET_RTS_HIGH (2 | ( FTDI_SIO_SET_RTS_MASK << 8))
-#define FTDI_SIO_SET_RTS_LOW (0 | ( FTDI_SIO_SET_RTS_MASK << 8))
-
-
-/*
- * BmRequestType: 0100 0000b
- * bRequest: FTDI_SIO_SET_FLOW_CTRL
- * wValue: Xoff/Xon
- * wIndex: Protocol/Port - hIndex is protocl / lIndex is port
- * wLength: 0
- * Data: None
- *
- * hIndex protocol is:
- * B0 Output handshaking using RTS/CTS
- * 0 = disabled
- * 1 = enabled
- * B1 Output handshaking using DTR/DSR
- * 0 = disabled
- * 1 = enabled
- * B2 Xon/Xoff handshaking
- * 0 = disabled
- * 1 = enabled
- *
- * A value of zero in the hIndex field disables handshaking
- *
- * If Xon/Xoff handshaking is specified, the hValue field should contain the
- * XOFF character and the lValue field contains the XON character.
- */
-/* FTDI_SIO_SET_FLOW_CTRL */
-#define FTDI_SIO_DISABLE_FLOW_CTRL 0x0
-#define FTDI_SIO_RTS_CTS_HS 0x1
-#define FTDI_SIO_DTR_DSR_HS 0x2
-#define FTDI_SIO_XON_XOFF_HS 0x4
-
-
-/*
- * BmRequestType: 0100 0000b
- * bRequest: FTDI_SIO_SET_EVENT_CHAR
- * wValue: Event Char
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * wValue:
- * B0..7 Event Character
- * B8 Event Character Processing
- * 0 = disabled
- * 1 = enabled
- * B9..15 Reserved
- *
- * FTDI_SIO_SET_EVENT_CHAR
- *
- * Set the special event character for the specified communications port.
- * If the device sees this character it will immediately return the
- * data read so far - rather than wait 40ms or until 62 bytes are read
- * which is what normally happens.
- */
-
-
-
-/*
- * BmRequestType: 0100 0000b
- * bRequest: FTDI_SIO_SET_ERROR_CHAR
- * wValue: Error Char
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * Error Char
- * B0..7 Error Character
- * B8 Error Character Processing
- * 0 = disabled
- * 1 = enabled
- * B9..15 Reserved
- *
- *
- * FTDI_SIO_SET_ERROR_CHAR
- * Set the parity error replacement character for the specified communications
- * port.
- */
-
-
-/*
- * BmRequestType: 1100 0000b
- * bRequest: FTDI_SIO_GET_MODEM_STATUS
- * wValue: zero
- * wIndex: Port
- * wLength: 1
- * Data: Status
- *
- * One byte of data is returned
- * B0..3 0
- * B4 CTS
- * 0 = inactive
- * 1 = active
- * B5 DSR
- * 0 = inactive
- * 1 = active
- * B6 Ring Indicator (RI)
- * 0 = inactive
- * 1 = active
- * B7 Receive Line Signal Detect (RLSD)
- * 0 = inactive
- * 1 = active
- *
- * FTDI_SIO_GET_MODEM_STATUS
- * Retrieve the current value of the modem status register.
- */
-#define FTDI_SIO_CTS_MASK 0x10
-#define FTDI_SIO_DSR_MASK 0x20
-#define FTDI_SIO_RI_MASK 0x40
-#define FTDI_SIO_RLSD_MASK 0x80
-
-
-
-/*
- *
- * DATA FORMAT
- *
- * IN Endpoint
- *
- * The device reserves the first two bytes of data on this endpoint to contain
- * the current values of the modem and line status registers. In the absence of
- * data, the device generates a message consisting of these two status bytes
- * every 40 ms.
- *
- * Byte 0: Modem Status
- * NOTE: 4 upper bits have same layout as the MSR register in a 16550
- *
- * Offset Description
- * B0..3 Port
- * B4 Clear to Send (CTS)
- * B5 Data Set Ready (DSR)
- * B6 Ring Indicator (RI)
- * B7 Receive Line Signal Detect (RLSD)
- *
- * Byte 1: Line Status
- * NOTE: same layout as the LSR register in a 16550
- *
- * Offset Description
- * B0 Data Ready (DR)
- * B1 Overrun Error (OE)
- * B2 Parity Error (PE)
- * B3 Framing Error (FE)
- * B4 Break Interrupt (BI)
- * B5 Transmitter Holding Register (THRE)
- * B6 Transmitter Empty (TEMT)
- * B7 Error in RCVR FIFO
- *
- *
- * OUT Endpoint
- *
- * This device reserves the first bytes of data on this endpoint contain the
- * length and port identifier of the message. For the FTDI USB Serial converter
- * the port identifier is always 1.
- *
- * Byte 0: Port & length
- *
- * Offset Description
- * B0..1 Port
- * B2..7 Length of message - (not including Byte 0)
- *
- */
-#define FTDI_PORT_MASK 0x0f
-#define FTDI_MSR_MASK 0xf0
-#define FTDI_GET_MSR(p) (((p)[0]) & FTDI_MSR_MASK)
-#define FTDI_GET_LSR(p) ((p)[1])
-#define FTDI_LSR_MASK (~0x60) /* interesting bits */
-#define FTDI_OUT_TAG(len, port) (((len) << 2) | (port))
diff --git a/sys/dev/usb2/serial/ugensa2.c b/sys/dev/usb2/serial/ugensa2.c
deleted file mode 100644
index 248fc7e..0000000
--- a/sys/dev/usb2/serial/ugensa2.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: ugensa.c,v 1.9.2.1 2007/03/24 14:55:50 yamt Exp $ */
-
-/*
- * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Roland C. Dowdeswell <elric@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.
- */
-
-/*
- * NOTE: all function names beginning like "ugensa_cfg_" can only
- * be called from within the config thread function !
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_device.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#define UGENSA_BUF_SIZE 2048 /* bytes */
-#define UGENSA_CONFIG_INDEX 0
-#define UGENSA_IFACE_INDEX 0
-#define UGENSA_IFACE_MAX 8 /* exclusivly */
-
-enum {
- UGENSA_BULK_DT_WR,
- UGENSA_BULK_DT_RD,
- UGENSA_N_TRANSFER,
-};
-
-struct ugensa_sub_softc {
- struct usb2_com_softc *sc_usb2_com_ptr;
- struct usb2_xfer *sc_xfer[UGENSA_N_TRANSFER];
-};
-
-struct ugensa_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom[UGENSA_IFACE_MAX];
- struct ugensa_sub_softc sc_sub[UGENSA_IFACE_MAX];
-
- struct mtx sc_mtx;
- uint8_t sc_niface;
-};
-
-/* prototypes */
-
-static device_probe_t ugensa_probe;
-static device_attach_t ugensa_attach;
-static device_detach_t ugensa_detach;
-
-static usb2_callback_t ugensa_bulk_write_callback;
-static usb2_callback_t ugensa_bulk_read_callback;
-
-static void ugensa_start_read(struct usb2_com_softc *);
-static void ugensa_stop_read(struct usb2_com_softc *);
-static void ugensa_start_write(struct usb2_com_softc *);
-static void ugensa_stop_write(struct usb2_com_softc *);
-
-static const struct usb2_config
- ugensa_xfer_config[UGENSA_N_TRANSFER] = {
-
- [UGENSA_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UGENSA_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &ugensa_bulk_write_callback,
- },
-
- [UGENSA_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UGENSA_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &ugensa_bulk_read_callback,
- },
-};
-
-static const struct usb2_com_callback ugensa_callback = {
- .usb2_com_start_read = &ugensa_start_read,
- .usb2_com_stop_read = &ugensa_stop_read,
- .usb2_com_start_write = &ugensa_start_write,
- .usb2_com_stop_write = &ugensa_stop_write,
-};
-
-static device_method_t ugensa_methods[] = {
- /* Device methods */
- DEVMETHOD(device_probe, ugensa_probe),
- DEVMETHOD(device_attach, ugensa_attach),
- DEVMETHOD(device_detach, ugensa_detach),
- {0, 0}
-};
-
-static devclass_t ugensa_devclass;
-
-static driver_t ugensa_driver = {
- .name = "ugensa",
- .methods = ugensa_methods,
- .size = sizeof(struct ugensa_softc),
-};
-
-DRIVER_MODULE(ugensa, ushub, ugensa_driver, ugensa_devclass, NULL, 0);
-MODULE_DEPEND(ugensa, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(ugensa, usb2_core, 1, 1, 1);
-
-static const struct usb2_device_id ugensa_devs[] = {
- {USB_VPI(USB_VENDOR_AIRPRIME, USB_PRODUCT_AIRPRIME_PC5220, 0)},
- {USB_VPI(USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CDMA_MODEM1, 0)},
- {USB_VPI(USB_VENDOR_KYOCERA2, USB_PRODUCT_KYOCERA2_CDMA_MSM_K, 0)},
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_49GPLUS, 0)},
- {USB_VPI(USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_FLEXPACKGPS, 0)},
-};
-
-static int
-ugensa_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != UGENSA_CONFIG_INDEX) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != 0) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(ugensa_devs, sizeof(ugensa_devs), uaa));
-}
-
-static int
-ugensa_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ugensa_softc *sc = device_get_softc(dev);
- struct ugensa_sub_softc *ssc;
- struct usb2_interface *iface;
- int32_t error;
- uint8_t iface_index;
- int x, cnt;
-
- device_set_usb2_desc(dev);
- mtx_init(&sc->sc_mtx, "ugensa", NULL, MTX_DEF);
-
- /* Figure out how many interfaces this device has got */
- for (cnt = 0; cnt < UGENSA_IFACE_MAX; cnt++) {
- if ((usb2_get_pipe(uaa->device, cnt, ugensa_xfer_config + 0) == NULL) ||
- (usb2_get_pipe(uaa->device, cnt, ugensa_xfer_config + 1) == NULL)) {
- /* we have reached the end */
- break;
- }
- }
-
- if (cnt == 0) {
- device_printf(dev, "No interfaces!\n");
- goto detach;
- }
- for (x = 0; x < cnt; x++) {
- iface = usb2_get_iface(uaa->device, x);
- if (iface->idesc->bInterfaceClass != UICLASS_VENDOR)
- /* Not a serial port, most likely a SD reader */
- continue;
-
- ssc = sc->sc_sub + sc->sc_niface;
- ssc->sc_usb2_com_ptr = sc->sc_ucom + sc->sc_niface;
-
- iface_index = (UGENSA_IFACE_INDEX + x);
- error = usb2_transfer_setup(uaa->device,
- &iface_index, ssc->sc_xfer, ugensa_xfer_config,
- UGENSA_N_TRANSFER, ssc, &sc->sc_mtx);
-
- if (error) {
- device_printf(dev, "allocating USB "
- "transfers failed!\n");
- goto detach;
- }
- /* clear stall at first run */
- usb2_transfer_set_stall(ssc->sc_xfer[UGENSA_BULK_DT_WR]);
- usb2_transfer_set_stall(ssc->sc_xfer[UGENSA_BULK_DT_RD]);
-
- /* initialize port number */
- ssc->sc_usb2_com_ptr->sc_portno = sc->sc_niface;
- sc->sc_niface++;
- if (x != uaa->info.bIfaceIndex)
- usb2_set_parent_iface(uaa->device, x,
- uaa->info.bIfaceIndex);
- }
- device_printf(dev, "Found %d interfaces.\n", sc->sc_niface);
-
- error = usb2_com_attach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_niface, sc,
- &ugensa_callback, &sc->sc_mtx);
- if (error) {
- DPRINTF("attach failed\n");
- goto detach;
- }
- return (0); /* success */
-
-detach:
- ugensa_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-ugensa_detach(device_t dev)
-{
- struct ugensa_softc *sc = device_get_softc(dev);
- uint8_t x;
-
- usb2_com_detach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_niface);
-
- for (x = 0; x < sc->sc_niface; x++) {
- usb2_transfer_unsetup(sc->sc_sub[x].sc_xfer, UGENSA_N_TRANSFER);
- }
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static void
-ugensa_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct ugensa_sub_softc *ssc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(ssc->sc_usb2_com_ptr, xfer->frbuffers, 0,
- UGENSA_BUF_SIZE, &actlen)) {
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-ugensa_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct ugensa_sub_softc *ssc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(ssc->sc_usb2_com_ptr, xfer->frbuffers, 0,
- xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-ugensa_start_read(struct usb2_com_softc *ucom)
-{
- struct ugensa_softc *sc = ucom->sc_parent;
- struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno;
-
- usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_DT_RD]);
-}
-
-static void
-ugensa_stop_read(struct usb2_com_softc *ucom)
-{
- struct ugensa_softc *sc = ucom->sc_parent;
- struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno;
-
- usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_DT_RD]);
-}
-
-static void
-ugensa_start_write(struct usb2_com_softc *ucom)
-{
- struct ugensa_softc *sc = ucom->sc_parent;
- struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno;
-
- usb2_transfer_start(ssc->sc_xfer[UGENSA_BULK_DT_WR]);
-}
-
-static void
-ugensa_stop_write(struct usb2_com_softc *ucom)
-{
- struct ugensa_softc *sc = ucom->sc_parent;
- struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno;
-
- usb2_transfer_stop(ssc->sc_xfer[UGENSA_BULK_DT_WR]);
-}
diff --git a/sys/dev/usb2/serial/uipaq2.c b/sys/dev/usb2/serial/uipaq2.c
deleted file mode 100644
index 68ba3fc..0000000
--- a/sys/dev/usb2/serial/uipaq2.c
+++ /dev/null
@@ -1,1314 +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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#define UIPAQ_CONFIG_INDEX 0 /* config number 1 */
-#define UIPAQ_IFACE_INDEX 0
-
-#define UIPAQ_BUF_SIZE 1024
-
-enum {
- UIPAQ_BULK_DT_WR,
- UIPAQ_BULK_DT_RD,
- UIPAQ_N_TRANSFER,
-};
-
-struct uipaq_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_xfer *sc_xfer[UIPAQ_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint16_t sc_line;
-
- uint8_t sc_lsr; /* local status register */
- uint8_t sc_msr; /* modem status register */
-};
-
-static device_probe_t uipaq_probe;
-static device_attach_t uipaq_attach;
-static device_detach_t uipaq_detach;
-
-static usb2_callback_t uipaq_write_callback;
-static usb2_callback_t uipaq_read_callback;
-
-static void uipaq_start_read(struct usb2_com_softc *);
-static void uipaq_stop_read(struct usb2_com_softc *);
-static void uipaq_start_write(struct usb2_com_softc *);
-static void uipaq_stop_write(struct usb2_com_softc *);
-static void uipaq_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
-static void uipaq_cfg_set_rts(struct usb2_com_softc *, uint8_t);
-static void uipaq_cfg_set_break(struct usb2_com_softc *, uint8_t);
-
-static const struct usb2_config uipaq_config_data[UIPAQ_N_TRANSFER] = {
-
- [UIPAQ_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UIPAQ_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &uipaq_write_callback,
- },
-
- [UIPAQ_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UIPAQ_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &uipaq_read_callback,
- },
-};
-
-static const struct usb2_com_callback uipaq_callback = {
- .usb2_com_cfg_set_dtr = &uipaq_cfg_set_dtr,
- .usb2_com_cfg_set_rts = &uipaq_cfg_set_rts,
- .usb2_com_cfg_set_break = &uipaq_cfg_set_break,
- .usb2_com_start_read = &uipaq_start_read,
- .usb2_com_stop_read = &uipaq_stop_read,
- .usb2_com_start_write = &uipaq_start_write,
- .usb2_com_stop_write = &uipaq_stop_write,
-};
-
-/*
- * 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 usb2_device_id uipaq_devs[] = {
- /* Socket USB Sync */
- {USB_VPI(0x0104, 0x00be, 0)},
- /* USB Sync 0301 */
- {USB_VPI(0x04ad, 0x0301, 0)},
- /* USB Sync 0302 */
- {USB_VPI(0x04ad, 0x0302, 0)},
- /* USB Sync 0303 */
- {USB_VPI(0x04ad, 0x0303, 0)},
- /* GPS Pocket PC USB Sync */
- {USB_VPI(0x04ad, 0x0306, 0)},
- /* HHP PDT */
- {USB_VPI(0x0536, 0x01a0, 0)},
- /* Intermec Mobile Computer */
- {USB_VPI(0x067e, 0x1001, 0)},
- /* Linkup Systems USB Sync */
- {USB_VPI(0x094b, 0x0001, 0)},
- /* BCOM USB Sync 0065 */
- {USB_VPI(0x0960, 0x0065, 0)},
- /* BCOM USB Sync 0066 */
- {USB_VPI(0x0960, 0x0066, 0)},
- /* BCOM USB Sync 0067 */
- {USB_VPI(0x0960, 0x0067, 0)},
- /* Portatec USB Sync */
- {USB_VPI(0x0961, 0x0010, 0)},
- /* Trimble GeoExplorer */
- {USB_VPI(0x099e, 0x0052, 0)},
- /* TDS Data Collector */
- {USB_VPI(0x099e, 0x4000, 0)},
- /* Motorola iDEN Smartphone */
- {USB_VPI(0x0c44, 0x03a2, 0)},
- /* Cesscom Luxian Series */
- {USB_VPI(0x0c8e, 0x6000, 0)},
- /* Motorola PowerPad Pocket PCDevice */
- {USB_VPI(0x0cad, 0x9001, 0)},
- /* Freedom Scientific USB Sync */
- {USB_VPI(0x0f4e, 0x0200, 0)},
- /* Cyberbank USB Sync */
- {USB_VPI(0x0f98, 0x0201, 0)},
- /* Wistron USB Sync */
- {USB_VPI(0x0fb8, 0x3001, 0)},
- /* Wistron USB Sync */
- {USB_VPI(0x0fb8, 0x3002, 0)},
- /* Wistron USB Sync */
- {USB_VPI(0x0fb8, 0x3003, 0)},
- /* Wistron USB Sync */
- {USB_VPI(0x0fb8, 0x4001, 0)},
- /* E-TEN USB Sync */
- {USB_VPI(0x1066, 0x00ce, 0)},
- /* E-TEN P3XX Pocket PC */
- {USB_VPI(0x1066, 0x0300, 0)},
- /* E-TEN P5XX Pocket PC */
- {USB_VPI(0x1066, 0x0500, 0)},
- /* E-TEN P6XX Pocket PC */
- {USB_VPI(0x1066, 0x0600, 0)},
- /* E-TEN P7XX Pocket PC */
- {USB_VPI(0x1066, 0x0700, 0)},
- /* Psion Teklogix Sync 753x */
- {USB_VPI(0x1114, 0x0001, 0)},
- /* Psion Teklogix Sync netBookPro */
- {USB_VPI(0x1114, 0x0004, 0)},
- /* Psion Teklogix Sync 7525 */
- {USB_VPI(0x1114, 0x0006, 0)},
- /* VES USB Sync */
- {USB_VPI(0x1182, 0x1388, 0)},
- /* Rugged Pocket PC 2003 */
- {USB_VPI(0x11d9, 0x1002, 0)},
- /* Rugged Pocket PC 2003 */
- {USB_VPI(0x11d9, 0x1003, 0)},
- /* USB Sync 03 */
- {USB_VPI(0x1231, 0xce01, 0)},
- /* USB Sync 03 */
- {USB_VPI(0x1231, 0xce02, 0)},
- /* Mio DigiWalker PPC StrongARM */
- {USB_VPI(0x3340, 0x011c, 0)},
- /* Mio DigiWalker 338 */
- {USB_VPI(0x3340, 0x0326, 0)},
- /* Mio DigiWalker 338 */
- {USB_VPI(0x3340, 0x0426, 0)},
- /* Mio DigiWalker USB Sync */
- {USB_VPI(0x3340, 0x043a, 0)},
- /* MiTAC USB Sync 528 */
- {USB_VPI(0x3340, 0x051c, 0)},
- /* Mio DigiWalker SmartPhone USB Sync */
- {USB_VPI(0x3340, 0x053a, 0)},
- /* MiTAC USB Sync */
- {USB_VPI(0x3340, 0x071c, 0)},
- /* Generic PPC StrongARM */
- {USB_VPI(0x3340, 0x0b1c, 0)},
- /* Generic PPC USB Sync */
- {USB_VPI(0x3340, 0x0e3a, 0)},
- /* Itautec USB Sync */
- {USB_VPI(0x3340, 0x0f1c, 0)},
- /* Generic SmartPhone USB Sync */
- {USB_VPI(0x3340, 0x0f3a, 0)},
- /* Itautec USB Sync */
- {USB_VPI(0x3340, 0x1326, 0)},
- /* YAKUMO USB Sync */
- {USB_VPI(0x3340, 0x191c, 0)},
- /* Vobis USB Sync */
- {USB_VPI(0x3340, 0x2326, 0)},
- /* MEDION Winodws Moble USB Sync */
- {USB_VPI(0x3340, 0x3326, 0)},
- /* Legend USB Sync */
- {USB_VPI(0x3708, 0x20ce, 0)},
- /* Lenovo USB Sync */
- {USB_VPI(0x3708, 0x21ce, 0)},
- /* Mobile Media Technology USB Sync */
- {USB_VPI(0x4113, 0x0210, 0)},
- /* Mobile Media Technology USB Sync */
- {USB_VPI(0x4113, 0x0211, 0)},
- /* Mobile Media Technology USB Sync */
- {USB_VPI(0x4113, 0x0400, 0)},
- /* Mobile Media Technology USB Sync */
- {USB_VPI(0x4113, 0x0410, 0)},
- /* Smartphone */
- {USB_VPI(0x4505, 0x0010, 0)},
- /* SAGEM Wireless Assistant */
- {USB_VPI(0x5e04, 0xce00, 0)},
- /* c10 Series */
- {USB_VPI(USB_VENDOR_ACER, 0x1631, 0)},
- /* c20 Series */
- {USB_VPI(USB_VENDOR_ACER, 0x1632, 0)},
- /* Acer n10 Handheld USB Sync */
- {USB_VPI(USB_VENDOR_ACER, 0x16e1, 0)},
- /* Acer n20 Handheld USB Sync */
- {USB_VPI(USB_VENDOR_ACER, 0x16e2, 0)},
- /* Acer n30 Handheld USB Sync */
- {USB_VPI(USB_VENDOR_ACER, 0x16e3, 0)},
- /* ASUS USB Sync */
- {USB_VPI(USB_VENDOR_ASUS, 0x4200, 0)},
- /* ASUS USB Sync */
- {USB_VPI(USB_VENDOR_ASUS, 0x4201, 0)},
- /* ASUS USB Sync */
- {USB_VPI(USB_VENDOR_ASUS, 0x4202, 0)},
- /* ASUS USB Sync */
- {USB_VPI(USB_VENDOR_ASUS, 0x9200, 0)},
- /* ASUS USB Sync */
- {USB_VPI(USB_VENDOR_ASUS, 0x9202, 0)},
- /**/
- {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_P535, 0)},
- /* CASIO USB Sync 2001 */
- {USB_VPI(USB_VENDOR_CASIO, 0x2001, 0)},
- /* CASIO USB Sync 2003 */
- {USB_VPI(USB_VENDOR_CASIO, 0x2003, 0)},
- /**/
- {USB_VPI(USB_VENDOR_CASIO, USB_PRODUCT_CASIO_BE300, 0)},
- /* MyGuide 7000 XL USB Sync */
- {USB_VPI(USB_VENDOR_COMPAL, 0x0531, 0)},
- /* Compaq iPAQ USB Sync */
- {USB_VPI(USB_VENDOR_COMPAQ, 0x0032, 0)},
- /**/
- {USB_VPI(USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQPOCKETPC, 0)},
- /* Dell Axim USB Sync */
- {USB_VPI(USB_VENDOR_DELL, 0x4001, 0)},
- /* Dell Axim USB Sync */
- {USB_VPI(USB_VENDOR_DELL, 0x4002, 0)},
- /* Dell Axim USB Sync */
- {USB_VPI(USB_VENDOR_DELL, 0x4003, 0)},
- /* Dell Axim USB Sync */
- {USB_VPI(USB_VENDOR_DELL, 0x4004, 0)},
- /* Dell Axim USB Sync */
- {USB_VPI(USB_VENDOR_DELL, 0x4005, 0)},
- /* Dell Axim USB Sync */
- {USB_VPI(USB_VENDOR_DELL, 0x4006, 0)},
- /* Dell Axim USB Sync */
- {USB_VPI(USB_VENDOR_DELL, 0x4007, 0)},
- /* Dell Axim USB Sync */
- {USB_VPI(USB_VENDOR_DELL, 0x4008, 0)},
- /* Dell Axim USB Sync */
- {USB_VPI(USB_VENDOR_DELL, 0x4009, 0)},
- /* Fujitsu Siemens Computers USB Sync */
- {USB_VPI(USB_VENDOR_FSC, 0x1001, 0)},
- /* FUJITSU USB Sync */
- {USB_VPI(USB_VENDOR_FUJITSU, 0x1058, 0)},
- /* FUJITSU USB Sync */
- {USB_VPI(USB_VENDOR_FUJITSU, 0x1079, 0)},
- /* Askey USB Sync */
- {USB_VPI(USB_VENDOR_GIGASET, 0x0601, 0)},
- /* Hitachi USB Sync */
- {USB_VPI(USB_VENDOR_HITACHI, 0x0014, 0)},
- /* HP USB Sync 1612 */
- {USB_VPI(USB_VENDOR_HP, 0x1216, 0)},
- /* HP USB Sync 1620 */
- {USB_VPI(USB_VENDOR_HP, 0x2016, 0)},
- /* HP USB Sync 1621 */
- {USB_VPI(USB_VENDOR_HP, 0x2116, 0)},
- /* HP USB Sync 1622 */
- {USB_VPI(USB_VENDOR_HP, 0x2216, 0)},
- /* HP USB Sync 1630 */
- {USB_VPI(USB_VENDOR_HP, 0x3016, 0)},
- /* HP USB Sync 1631 */
- {USB_VPI(USB_VENDOR_HP, 0x3116, 0)},
- /* HP USB Sync 1632 */
- {USB_VPI(USB_VENDOR_HP, 0x3216, 0)},
- /* HP USB Sync 1640 */
- {USB_VPI(USB_VENDOR_HP, 0x4016, 0)},
- /* HP USB Sync 1641 */
- {USB_VPI(USB_VENDOR_HP, 0x4116, 0)},
- /* HP USB Sync 1642 */
- {USB_VPI(USB_VENDOR_HP, 0x4216, 0)},
- /* HP USB Sync 1650 */
- {USB_VPI(USB_VENDOR_HP, 0x5016, 0)},
- /* HP USB Sync 1651 */
- {USB_VPI(USB_VENDOR_HP, 0x5116, 0)},
- /* HP USB Sync 1652 */
- {USB_VPI(USB_VENDOR_HP, 0x5216, 0)},
- /**/
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_2215, 0)},
- /**/
- {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_568J, 0)},
- /* HTC USB Modem */
- {USB_VPI(USB_VENDOR_HTC, 0x00cf, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a01, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a02, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a03, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a04, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a05, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a06, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a07, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a08, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a09, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a0a, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a0b, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a0c, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a0d, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a0e, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a0f, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a10, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a11, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a12, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a13, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a14, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a15, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a16, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a17, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a18, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a19, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a1a, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a1b, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a1c, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a1d, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a1e, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a1f, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a20, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a21, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a22, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a23, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a24, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a25, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a26, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a27, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a28, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a29, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a2a, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a2b, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a2c, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a2d, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a2e, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a2f, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a30, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a31, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a32, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a33, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a34, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a35, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a36, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a37, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a38, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a39, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a3a, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a3b, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a3c, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a3d, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a3e, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a3f, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a40, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a41, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a42, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a43, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a44, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a45, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a46, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a47, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a48, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a49, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a4a, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a4b, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a4c, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a4d, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a4e, 0)},
- /* PocketPC USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a4f, 0)},
- /* HTC SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a50, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a52, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a53, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a54, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a55, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a56, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a57, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a58, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a59, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a5a, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a5b, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a5c, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a5d, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a5e, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a5f, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a60, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a61, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a62, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a63, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a64, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a65, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a66, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a67, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a68, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a69, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a6a, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a6b, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a6c, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a6d, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a6e, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a6f, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a70, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a71, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a72, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a73, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a74, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a75, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a76, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a77, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a78, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a79, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a7a, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a7b, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a7c, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a7d, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a7e, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a7f, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a80, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a81, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a82, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a83, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a84, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a85, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a86, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a87, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a88, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a89, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a8a, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a8b, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a8c, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a8d, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a8e, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a8f, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a90, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a91, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a92, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a93, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a94, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a95, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a96, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a97, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a98, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a99, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a9a, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a9b, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a9c, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a9d, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a9e, 0)},
- /* SmartPhone USB Sync */
- {USB_VPI(USB_VENDOR_HTC, 0x0a9f, 0)},
- /* "High Tech Computer Corp" */
- {USB_VPI(USB_VENDOR_HTC, 0x0bce, 0)},
- /**/
- {USB_VPI(USB_VENDOR_HTC, USB_PRODUCT_HTC_PPC6700MODEM, 0)},
- /**/
- {USB_VPI(USB_VENDOR_HTC, USB_PRODUCT_HTC_SMARTPHONE, 0)},
- /**/
- {USB_VPI(USB_VENDOR_HTC, USB_PRODUCT_HTC_WINMOBILE, 0)},
- /* JVC USB Sync */
- {USB_VPI(USB_VENDOR_JVC, 0x3011, 0)},
- /* JVC USB Sync */
- {USB_VPI(USB_VENDOR_JVC, 0x3012, 0)},
- /* LGE USB Sync */
- {USB_VPI(USB_VENDOR_LG, 0x9c01, 0)},
- /* Microsoft USB Sync */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x00ce, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0400, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0401, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0402, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0403, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0404, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0405, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0406, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0407, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0408, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0409, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x040a, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x040b, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x040c, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x040d, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x040e, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x040f, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0410, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0411, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0412, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0413, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0414, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0415, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0416, 0)},
- /* Windows Pocket PC 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0417, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0432, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0433, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0434, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0435, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0436, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0437, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0438, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0439, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x043a, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x043b, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x043c, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x043d, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x043e, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x043f, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0440, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0441, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0442, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0443, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0444, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0445, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0446, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0447, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0448, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0449, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x044a, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x044b, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x044c, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x044d, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x044e, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x044f, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0450, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0451, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0452, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0453, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0454, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0455, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0456, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0457, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0458, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0459, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x045a, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x045b, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x045c, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x045d, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x045e, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x045f, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0460, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0461, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0462, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0463, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0464, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0465, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0466, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0467, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0468, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0469, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x046a, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x046b, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x046c, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x046d, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x046e, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x046f, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0470, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0471, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0472, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0473, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0474, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0475, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0476, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0477, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0478, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x0479, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x047a, 0)},
- /* Windows Pocket PC 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x047b, 0)},
- /* Windows Smartphone 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04c8, 0)},
- /* Windows Smartphone 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04c9, 0)},
- /* Windows Smartphone 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04ca, 0)},
- /* Windows Smartphone 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04cb, 0)},
- /* Windows Smartphone 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04cc, 0)},
- /* Windows Smartphone 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04cd, 0)},
- /* Windows Smartphone 2002 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04ce, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04d7, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04d8, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04d9, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04da, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04db, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04dc, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04dd, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04de, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04df, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04e0, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04e1, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04e2, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04e3, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04e4, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04e5, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04e6, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04e7, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04e8, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04e9, 0)},
- /* Windows Smartphone 2003 */
- {USB_VPI(USB_VENDOR_MICROSOFT, 0x04ea, 0)},
- /* Motorola MPx200 Smartphone */
- {USB_VPI(USB_VENDOR_MOTOROLA2, 0x4204, 0)},
- /* Motorola MPc GSM */
- {USB_VPI(USB_VENDOR_MOTOROLA2, 0x4214, 0)},
- /* Motorola MPx220 Smartphone */
- {USB_VPI(USB_VENDOR_MOTOROLA2, 0x4224, 0)},
- /* Motorola MPc CDMA */
- {USB_VPI(USB_VENDOR_MOTOROLA2, 0x4234, 0)},
- /* Motorola MPx100 Smartphone */
- {USB_VPI(USB_VENDOR_MOTOROLA2, 0x4244, 0)},
- /* NEC USB Sync */
- {USB_VPI(USB_VENDOR_NEC, 0x00d5, 0)},
- /* NEC USB Sync */
- {USB_VPI(USB_VENDOR_NEC, 0x00d6, 0)},
- /* NEC USB Sync */
- {USB_VPI(USB_VENDOR_NEC, 0x00d7, 0)},
- /* NEC USB Sync */
- {USB_VPI(USB_VENDOR_NEC, 0x8024, 0)},
- /* NEC USB Sync */
- {USB_VPI(USB_VENDOR_NEC, 0x8025, 0)},
- /* Panasonic USB Sync */
- {USB_VPI(USB_VENDOR_PANASONIC, 0x2500, 0)},
- /* Samsung NEXiO USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x5f00, 0)},
- /* Samsung NEXiO USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x5f01, 0)},
- /* Samsung NEXiO USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x5f02, 0)},
- /* Samsung NEXiO USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x5f03, 0)},
- /* Samsung NEXiO USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x5f04, 0)},
- /* Samsung MITs USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x6611, 0)},
- /* Samsung MITs USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x6613, 0)},
- /* Samsung MITs USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x6615, 0)},
- /* Samsung MITs USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x6617, 0)},
- /* Samsung MITs USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x6619, 0)},
- /* Samsung MITs USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x661b, 0)},
- /* Samsung MITs USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x662e, 0)},
- /* Samsung MITs USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x6630, 0)},
- /* Samsung MITs USB Sync */
- {USB_VPI(USB_VENDOR_SAMSUNG, 0x6632, 0)},
- /* SHARP WS003SH USB Modem */
- {USB_VPI(USB_VENDOR_SHARP, 0x9102, 0)},
- /* SHARP WS004SH USB Modem */
- {USB_VPI(USB_VENDOR_SHARP, 0x9121, 0)},
- /* SHARP S01SH USB Modem */
- {USB_VPI(USB_VENDOR_SHARP, 0x9151, 0)},
-/**/
- {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_WZERO3ES, 0)},
- /* Symbol USB Sync */
- {USB_VPI(USB_VENDOR_SYMBOL, 0x2000, 0)},
- /* Symbol USB Sync 0x2001 */
- {USB_VPI(USB_VENDOR_SYMBOL, 0x2001, 0)},
- /* Symbol USB Sync 0x2002 */
- {USB_VPI(USB_VENDOR_SYMBOL, 0x2002, 0)},
- /* Symbol USB Sync 0x2003 */
- {USB_VPI(USB_VENDOR_SYMBOL, 0x2003, 0)},
- /* Symbol USB Sync 0x2004 */
- {USB_VPI(USB_VENDOR_SYMBOL, 0x2004, 0)},
- /* Symbol USB Sync 0x2005 */
- {USB_VPI(USB_VENDOR_SYMBOL, 0x2005, 0)},
- /* Symbol USB Sync 0x2006 */
- {USB_VPI(USB_VENDOR_SYMBOL, 0x2006, 0)},
- /* Symbol USB Sync 0x2007 */
- {USB_VPI(USB_VENDOR_SYMBOL, 0x2007, 0)},
- /* Symbol USB Sync 0x2008 */
- {USB_VPI(USB_VENDOR_SYMBOL, 0x2008, 0)},
- /* Symbol USB Sync 0x2009 */
- {USB_VPI(USB_VENDOR_SYMBOL, 0x2009, 0)},
- /* Symbol USB Sync 0x200a */
- {USB_VPI(USB_VENDOR_SYMBOL, 0x200a, 0)},
- /* TOSHIBA USB Sync 0700 */
- {USB_VPI(USB_VENDOR_TOSHIBA, 0x0700, 0)},
- /* TOSHIBA Pocket PC e310 */
- {USB_VPI(USB_VENDOR_TOSHIBA, 0x0705, 0)},
- /* TOSHIBA Pocket PC e330 Series */
- {USB_VPI(USB_VENDOR_TOSHIBA, 0x0707, 0)},
- /* TOSHIBA Pocket PC e350Series */
- {USB_VPI(USB_VENDOR_TOSHIBA, 0x0708, 0)},
- /* TOSHIBA Pocket PC e750 Series */
- {USB_VPI(USB_VENDOR_TOSHIBA, 0x0709, 0)},
- /* TOSHIBA Pocket PC e400 Series */
- {USB_VPI(USB_VENDOR_TOSHIBA, 0x070a, 0)},
- /* TOSHIBA Pocket PC e800 Series */
- {USB_VPI(USB_VENDOR_TOSHIBA, 0x070b, 0)},
- /* TOSHIBA Pocket PC e740 */
- {USB_VPI(USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_POCKETPC_E740, 0)},
- /* ViewSonic Color Pocket PC V35 */
- {USB_VPI(USB_VENDOR_VIEWSONIC, 0x0ed9, 0)},
- /* ViewSonic Color Pocket PC V36 */
- {USB_VPI(USB_VENDOR_VIEWSONIC, 0x1527, 0)},
- /* ViewSonic Color Pocket PC V37 */
- {USB_VPI(USB_VENDOR_VIEWSONIC, 0x1529, 0)},
- /* ViewSonic Color Pocket PC V38 */
- {USB_VPI(USB_VENDOR_VIEWSONIC, 0x152b, 0)},
- /* ViewSonic Pocket PC */
- {USB_VPI(USB_VENDOR_VIEWSONIC, 0x152e, 0)},
- /* ViewSonic Communicator Pocket PC */
- {USB_VPI(USB_VENDOR_VIEWSONIC, 0x1921, 0)},
- /* ViewSonic Smartphone */
- {USB_VPI(USB_VENDOR_VIEWSONIC, 0x1922, 0)},
- /* ViewSonic Pocket PC V30 */
- {USB_VPI(USB_VENDOR_VIEWSONIC, 0x1923, 0)},
-};
-
-static device_method_t uipaq_methods[] = {
- DEVMETHOD(device_probe, uipaq_probe),
- DEVMETHOD(device_attach, uipaq_attach),
- DEVMETHOD(device_detach, uipaq_detach),
- {0, 0}
-};
-
-static devclass_t uipaq_devclass;
-
-static driver_t uipaq_driver = {
- .name = "uipaq",
- .methods = uipaq_methods,
- .size = sizeof(struct uipaq_softc),
-};
-
-DRIVER_MODULE(uipaq, ushub, uipaq_driver, uipaq_devclass, NULL, 0);
-MODULE_DEPEND(uipaq, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(uipaq, usb2_core, 1, 1, 1);
-
-static int
-uipaq_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != UIPAQ_CONFIG_INDEX) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != UIPAQ_IFACE_INDEX) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(uipaq_devs, sizeof(uipaq_devs), uaa));
-}
-
-static int
-uipaq_attach(device_t dev)
-{
- struct usb2_device_request req;
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct uipaq_softc *sc = device_get_softc(dev);
- int error;
- uint8_t iface_index;
- uint8_t i;
-
- sc->sc_udev = uaa->device;
-
- device_set_usb2_desc(dev);
-
- /*
- * Send magic bytes, cribbed from Linux ipaq driver that
- * claims to have sniffed them from Win98. Wait for driver to
- * become ready on device side?
- */
- 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 != 64; i++) {
- error =
- usb2_do_request_flags(uaa->device, NULL, &req,
- NULL, 0, NULL, 100);
- if (error == 0)
- break;
- usb2_pause_mtx(NULL, hz / 10);
- }
-
- iface_index = UIPAQ_IFACE_INDEX;
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, uipaq_config_data,
- UIPAQ_N_TRANSFER, sc, &Giant);
-
- if (error) {
- goto detach;
- }
- /* clear stall at first run */
- usb2_transfer_set_stall(sc->sc_xfer[UIPAQ_BULK_DT_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[UIPAQ_BULK_DT_RD]);
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &uipaq_callback, &Giant);
- if (error) {
- goto detach;
- }
- return (0);
-
-detach:
- uipaq_detach(dev);
- return (ENXIO);
-}
-
-int
-uipaq_detach(device_t dev)
-{
- struct uipaq_softc *sc = device_get_softc(dev);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UIPAQ_N_TRANSFER);
-
- return (0);
-}
-
-static void
-uipaq_start_read(struct usb2_com_softc *ucom)
-{
- struct uipaq_softc *sc = ucom->sc_parent;
-
- /* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[UIPAQ_BULK_DT_RD]);
-}
-
-static void
-uipaq_stop_read(struct usb2_com_softc *ucom)
-{
- struct uipaq_softc *sc = ucom->sc_parent;
-
- /* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[UIPAQ_BULK_DT_RD]);
-}
-
-static void
-uipaq_start_write(struct usb2_com_softc *ucom)
-{
- struct uipaq_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UIPAQ_BULK_DT_WR]);
-}
-
-static void
-uipaq_stop_write(struct usb2_com_softc *ucom)
-{
- struct uipaq_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UIPAQ_BULK_DT_WR]);
-}
-
-static void
-uipaq_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uipaq_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
-
- DPRINTF("onoff=%d\n", onoff);
-
- if (onoff)
- sc->sc_line |= UCDC_LINE_DTR;
- else
- sc->sc_line &= ~UCDC_LINE_DTR;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, sc->sc_line);
- req.wIndex[0] = UIPAQ_IFACE_INDEX;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-uipaq_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uipaq_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
-
- DPRINTF("onoff=%d\n", onoff);
-
- if (onoff)
- sc->sc_line |= UCDC_LINE_RTS;
- else
- sc->sc_line &= ~UCDC_LINE_RTS;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, sc->sc_line);
- req.wIndex[0] = UIPAQ_IFACE_INDEX;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-uipaq_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uipaq_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
- uint16_t temp;
-
- temp = onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
- USETW(req.wValue, temp);
- req.wIndex[0] = UIPAQ_IFACE_INDEX;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-uipaq_write_callback(struct usb2_xfer *xfer)
-{
- struct uipaq_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- UIPAQ_BUF_SIZE, &actlen)) {
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uipaq_read_callback(struct usb2_xfer *xfer)
-{
- struct uipaq_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0,
- xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
diff --git a/sys/dev/usb2/serial/ulpt2.c b/sys/dev/usb2/serial/ulpt2.c
deleted file mode 100644
index 1a4d9a7..0000000
--- a/sys/dev/usb2/serial/ulpt2.c
+++ /dev/null
@@ -1,726 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/* $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.
- */
-
-/*
- * Printer Class spec: http://www.usb.org/developers/data/devclass/usbprint109.PDF
- * Printer Class spec: http://www.usb.org/developers/devclass_docs/usbprint11.pdf
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR ulpt_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-#include <dev/usb2/core/usb2_dev.h>
-#include <dev/usb2/core/usb2_parse.h>
-
-#include <sys/syslog.h>
-
-#if USB_DEBUG
-static int ulpt_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ulpt, CTLFLAG_RW, 0, "USB ulpt");
-SYSCTL_INT(_hw_usb2_ulpt, OID_AUTO, debug, CTLFLAG_RW,
- &ulpt_debug, 0, "Debug level");
-#endif
-
-#define ULPT_BSIZE (1<<15) /* bytes */
-#define ULPT_IFQ_MAXLEN 2 /* units */
-
-#define UR_GET_DEVICE_ID 0x00
-#define UR_GET_PORT_STATUS 0x01
-#define UR_SOFT_RESET 0x02
-
-#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)
-
-enum {
- ULPT_BULK_DT_WR,
- ULPT_BULK_DT_RD,
- ULPT_INTR_DT_RD,
- ULPT_N_TRANSFER,
-};
-
-struct ulpt_softc {
- struct usb2_fifo_sc sc_fifo;
- struct usb2_fifo_sc sc_fifo_noreset;
- struct mtx sc_mtx;
- struct usb2_callout sc_watchdog;
-
- device_t sc_dev;
- struct usb2_device *sc_udev;
- struct usb2_fifo *sc_fifo_open[2];
- struct usb2_xfer *sc_xfer[ULPT_N_TRANSFER];
-
- int sc_fflags; /* current open flags, FREAD and
- * FWRITE */
- uint8_t sc_iface_no;
- uint8_t sc_last_status;
- uint8_t sc_zlps; /* number of consequtive zero length
- * packets received */
-};
-
-/* prototypes */
-
-static device_probe_t ulpt_probe;
-static device_attach_t ulpt_attach;
-static device_detach_t ulpt_detach;
-
-static usb2_callback_t ulpt_write_callback;
-static usb2_callback_t ulpt_read_callback;
-static usb2_callback_t ulpt_status_callback;
-
-static void ulpt_reset(struct ulpt_softc *);
-static void ulpt_watchdog(void *);
-
-static usb2_fifo_close_t ulpt_close;
-static usb2_fifo_cmd_t ulpt_start_read;
-static usb2_fifo_cmd_t ulpt_start_write;
-static usb2_fifo_cmd_t ulpt_stop_read;
-static usb2_fifo_cmd_t ulpt_stop_write;
-static usb2_fifo_ioctl_t ulpt_ioctl;
-static usb2_fifo_open_t ulpt_open;
-static usb2_fifo_open_t unlpt_open;
-
-static struct usb2_fifo_methods ulpt_fifo_methods = {
- .f_close = &ulpt_close,
- .f_ioctl = &ulpt_ioctl,
- .f_open = &ulpt_open,
- .f_start_read = &ulpt_start_read,
- .f_start_write = &ulpt_start_write,
- .f_stop_read = &ulpt_stop_read,
- .f_stop_write = &ulpt_stop_write,
- .basename[0] = "ulpt",
-};
-
-static struct usb2_fifo_methods unlpt_fifo_methods = {
- .f_close = &ulpt_close,
- .f_ioctl = &ulpt_ioctl,
- .f_open = &unlpt_open,
- .f_start_read = &ulpt_start_read,
- .f_start_write = &ulpt_start_write,
- .f_stop_read = &ulpt_stop_read,
- .f_stop_write = &ulpt_stop_write,
- .basename[0] = "unlpt",
-};
-
-static void
-ulpt_reset(struct ulpt_softc *sc)
-{
- struct usb2_device_request req;
-
- DPRINTFN(2, "\n");
-
- req.bRequest = UR_SOFT_RESET;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_iface_no);
- 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.
- */
-
- mtx_lock(&sc->sc_mtx);
- req.bmRequestType = UT_WRITE_CLASS_OTHER;
- if (usb2_do_request_flags(sc->sc_udev, &sc->sc_mtx,
- &req, NULL, 0, NULL, 2 * USB_MS_HZ)) { /* 1.0 */
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- if (usb2_do_request_flags(sc->sc_udev, &sc->sc_mtx,
- &req, NULL, 0, NULL, 2 * USB_MS_HZ)) { /* 1.1 */
- /* ignore error */
- }
- }
- mtx_unlock(&sc->sc_mtx);
-}
-
-static void
-ulpt_write_callback(struct usb2_xfer *xfer)
-{
- struct ulpt_softc *sc = xfer->priv_sc;
- struct usb2_fifo *f = sc->sc_fifo_open[USB_FIFO_TX];
- uint32_t actlen;
-
- if (f == NULL) {
- /* should not happen */
- DPRINTF("no FIFO\n");
- return;
- }
- DPRINTF("state=0x%x\n", USB_GET_STATE(xfer));
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- case USB_ST_SETUP:
-tr_setup:
- if (usb2_fifo_get_data(f, xfer->frbuffers,
- 0, xfer->max_data_length, &actlen, 0)) {
-
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- break;
- }
-}
-
-static void
-ulpt_read_callback(struct usb2_xfer *xfer)
-{
- struct ulpt_softc *sc = xfer->priv_sc;
- struct usb2_fifo *f = sc->sc_fifo_open[USB_FIFO_RX];
-
- if (f == NULL) {
- /* should not happen */
- DPRINTF("no FIFO\n");
- return;
- }
- DPRINTF("state=0x%x\n", USB_GET_STATE(xfer));
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (xfer->actlen == 0) {
-
- if (sc->sc_zlps == 4) {
- /* enable BULK throttle */
- xfer->interval = 500; /* ms */
- } else {
- sc->sc_zlps++;
- }
- } else {
- /* disable BULK throttle */
-
- xfer->interval = 0;
- sc->sc_zlps = 0;
- }
-
- usb2_fifo_put_data(f, xfer->frbuffers,
- 0, xfer->actlen, 1);
-
- case USB_ST_SETUP:
-tr_setup:
- if (usb2_fifo_put_bytes_max(f) != 0) {
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- /* disable BULK throttle */
- xfer->interval = 0;
- sc->sc_zlps = 0;
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- break;
- }
-}
-
-static void
-ulpt_status_callback(struct usb2_xfer *xfer)
-{
- struct ulpt_softc *sc = xfer->priv_sc;
- struct usb2_device_request req;
- uint8_t cur_status;
- uint8_t new_status;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- usb2_copy_out(xfer->frbuffers + 1, 0, &cur_status, 1);
-
- cur_status = (cur_status ^ LPS_INVERT) & LPS_MASK;
- new_status = cur_status & ~sc->sc_last_status;
- sc->sc_last_status = cur_status;
-
- if (new_status & LPS_SELECT)
- log(LOG_NOTICE, "%s: offline\n",
- device_get_nameunit(sc->sc_dev));
- else if (new_status & LPS_NOPAPER)
- log(LOG_NOTICE, "%s: out of paper\n",
- device_get_nameunit(sc->sc_dev));
- else if (new_status & LPS_NERR)
- log(LOG_NOTICE, "%s: output error\n",
- device_get_nameunit(sc->sc_dev));
- break;
-
- case USB_ST_SETUP:
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_GET_PORT_STATUS;
- USETW(req.wValue, 0);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 1);
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
-
- xfer->frlengths[0] = sizeof(req);
- xfer->frlengths[1] = 1;
- xfer->nframes = 2;
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- DPRINTF("error=%s\n", usb2_errstr(xfer->error));
- if (xfer->error != USB_ERR_CANCELLED) {
- /* wait for next watchdog timeout */
- }
- break;
- }
-}
-
-static const struct usb2_config ulpt_config[ULPT_N_TRANSFER] = {
- [ULPT_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = ULPT_BSIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.proxy_buffer = 1},
- .mh.callback = &ulpt_write_callback,
- },
-
- [ULPT_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = ULPT_BSIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.proxy_buffer = 1},
- .mh.callback = &ulpt_read_callback,
- },
-
- [ULPT_INTR_DT_RD] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request) + 1,
- .mh.callback = &ulpt_status_callback,
- .mh.timeout = 1000, /* 1 second */
- },
-};
-
-static void
-ulpt_start_read(struct usb2_fifo *fifo)
-{
- struct ulpt_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_start(sc->sc_xfer[ULPT_BULK_DT_RD]);
-}
-
-static void
-ulpt_stop_read(struct usb2_fifo *fifo)
-{
- struct ulpt_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_stop(sc->sc_xfer[ULPT_BULK_DT_RD]);
-}
-
-static void
-ulpt_start_write(struct usb2_fifo *fifo)
-{
- struct ulpt_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_start(sc->sc_xfer[ULPT_BULK_DT_WR]);
-}
-
-static void
-ulpt_stop_write(struct usb2_fifo *fifo)
-{
- struct ulpt_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_stop(sc->sc_xfer[ULPT_BULK_DT_WR]);
-}
-
-static int
-ulpt_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- struct ulpt_softc *sc = fifo->priv_sc0;
-
- /* we assume that open is a serial process */
-
- if (sc->sc_fflags == 0) {
- ulpt_reset(sc);
- }
- return (unlpt_open(fifo, fflags, td));
-}
-
-static int
-unlpt_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- struct ulpt_softc *sc = fifo->priv_sc0;
-
- if (sc->sc_fflags & fflags) {
- return (EBUSY);
- }
- if (fflags & FREAD) {
- /* clear stall first */
- mtx_lock(&sc->sc_mtx);
- usb2_transfer_set_stall(sc->sc_xfer[ULPT_BULK_DT_RD]);
- mtx_unlock(&sc->sc_mtx);
- if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[ULPT_BULK_DT_RD]->max_data_length,
- ULPT_IFQ_MAXLEN)) {
- return (ENOMEM);
- }
- /* set which FIFO is opened */
- sc->sc_fifo_open[USB_FIFO_RX] = fifo;
- }
- if (fflags & FWRITE) {
- /* clear stall first */
- mtx_lock(&sc->sc_mtx);
- usb2_transfer_set_stall(sc->sc_xfer[ULPT_BULK_DT_WR]);
- mtx_unlock(&sc->sc_mtx);
- if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[ULPT_BULK_DT_WR]->max_data_length,
- ULPT_IFQ_MAXLEN)) {
- return (ENOMEM);
- }
- /* set which FIFO is opened */
- sc->sc_fifo_open[USB_FIFO_TX] = fifo;
- }
- sc->sc_fflags |= fflags & (FREAD | FWRITE);
- return (0);
-}
-
-static void
-ulpt_close(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- struct ulpt_softc *sc = fifo->priv_sc0;
-
- sc->sc_fflags &= ~(fflags & (FREAD | FWRITE));
-
- if (fflags & (FREAD | FWRITE)) {
- usb2_fifo_free_buffer(fifo);
- }
-}
-
-static int
-ulpt_ioctl(struct usb2_fifo *fifo, u_long cmd, void *data,
- int fflags, struct thread *td)
-{
- return (ENODEV);
-}
-
-static int
-ulpt_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- DPRINTFN(11, "\n");
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if ((uaa->info.bInterfaceClass == UICLASS_PRINTER) &&
- (uaa->info.bInterfaceSubClass == UISUBCLASS_PRINTER) &&
- ((uaa->info.bInterfaceProtocol == UIPROTO_PRINTER_UNI) ||
- (uaa->info.bInterfaceProtocol == UIPROTO_PRINTER_BI) ||
- (uaa->info.bInterfaceProtocol == UIPROTO_PRINTER_1284))) {
- return (0);
- }
- return (ENXIO);
-}
-
-static int
-ulpt_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct ulpt_softc *sc = device_get_softc(dev);
- struct usb2_interface_descriptor *id;
- int unit = device_get_unit(dev);
- int error;
- uint8_t iface_index = uaa->info.bIfaceIndex;
- uint8_t alt_index;
-
- DPRINTFN(11, "sc=%p\n", sc);
-
- sc->sc_dev = dev;
- sc->sc_udev = uaa->device;
-
- device_set_usb2_desc(dev);
-
- mtx_init(&sc->sc_mtx, "ulpt lock", NULL, MTX_DEF | MTX_RECURSE);
-
- usb2_callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
-
- /* search through all the descriptors looking for bidir mode */
-
- id = usb2_get_interface_descriptor(uaa->iface);
- alt_index = 0 - 1;
- while (1) {
- if (id == NULL) {
- break;
- }
- if ((id->bDescriptorType == UDESC_INTERFACE) &&
- (id->bLength >= sizeof(*id))) {
- if (id->bInterfaceNumber != uaa->info.bIfaceNum) {
- break;
- } else {
- alt_index++;
- if ((id->bInterfaceClass == UICLASS_PRINTER) &&
- (id->bInterfaceSubClass == UISUBCLASS_PRINTER) &&
- (id->bInterfaceProtocol == UIPROTO_PRINTER_BI)) {
- goto found;
- }
- }
- }
- id = (void *)usb2_desc_foreach(
- usb2_get_config_descriptor(uaa->device), (void *)id);
- }
- goto detach;
-
-found:
-
- DPRINTF("setting alternate "
- "config number: %d\n", alt_index);
-
- if (alt_index) {
-
- error = usb2_set_alt_interface_index
- (uaa->device, iface_index, alt_index);
-
- if (error) {
- DPRINTF("could not set alternate "
- "config, error=%s\n", usb2_errstr(error));
- goto detach;
- }
- }
- sc->sc_iface_no = id->bInterfaceNumber;
-
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, ulpt_config, ULPT_N_TRANSFER,
- sc, &sc->sc_mtx);
- if (error) {
- DPRINTF("error=%s\n", usb2_errstr(error));
- goto detach;
- }
- device_printf(sc->sc_dev, "using bi-directional mode\n");
-
-#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*
- */
- {
- struct usb2_config_descriptor *cd = usb2_get_config_descriptor(dev);
- struct usb2_device_request 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);
- error = usb2_do_request_flags(dev, &req, devinfo, USB_SHORT_XFER_OK,
- &alen, USB_DEFAULT_TIMEOUT);
- if (error) {
- device_printf(sc->sc_dev, "cannot get device id\n");
- } else if (alen <= 2) {
- device_printf(sc->sc_dev, "empty device id, no "
- "printer connected?\n");
- } 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
-
- /* set interface permissions */
- usb2_set_iface_perm(uaa->device, uaa->info.bIfaceIndex,
- UID_ROOT, GID_OPERATOR, 0644);
-
- error = usb2_fifo_attach(uaa->device, sc, &sc->sc_mtx,
- &ulpt_fifo_methods, &sc->sc_fifo,
- unit, 0 - 1, uaa->info.bIfaceIndex);
- if (error) {
- goto detach;
- }
- error = usb2_fifo_attach(uaa->device, sc, &sc->sc_mtx,
- &unlpt_fifo_methods, &sc->sc_fifo_noreset,
- unit, 0 - 1, uaa->info.bIfaceIndex);
- if (error) {
- goto detach;
- }
- /* start reading of status */
-
- mtx_lock(&sc->sc_mtx);
- ulpt_watchdog(sc);
- mtx_unlock(&sc->sc_mtx);
- return (0);
-
-detach:
- ulpt_detach(dev);
- return (ENOMEM);
-}
-
-static int
-ulpt_detach(device_t dev)
-{
- struct ulpt_softc *sc = device_get_softc(dev);
-
- DPRINTF("sc=%p\n", sc);
-
- usb2_fifo_detach(&sc->sc_fifo);
- usb2_fifo_detach(&sc->sc_fifo_noreset);
-
- mtx_lock(&sc->sc_mtx);
- usb2_callout_stop(&sc->sc_watchdog);
- mtx_unlock(&sc->sc_mtx);
-
- usb2_transfer_unsetup(sc->sc_xfer, ULPT_N_TRANSFER);
-
- usb2_callout_drain(&sc->sc_watchdog);
-
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-#if 0
-/* XXX This does not belong here. */
-
-/*
- * Compare two strings until the second ends.
- */
-
-static uint8_t
-ieee1284_compare(const char *a, const char *b)
-{
- while (1) {
-
- if (*b == 0) {
- break;
- }
- if (*a != *b) {
- return 1;
- }
- b++;
- a++;
- }
- return 0;
-}
-
-/*
- * 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 (ieee1284_compare(p, "MFG:") == 0 ||
- ieee1284_compare(p, "MANUFACTURER:") == 0 ||
- ieee1284_compare(p, "MDL:") == 0 ||
- ieee1284_compare(p, "MODEL:") == 0) {
- q = strchr(p, ';');
- if (q)
- printf("%.*s", (int)(q - p + 1), p);
- }
- }
-}
-
-#endif
-
-static void
-ulpt_watchdog(void *arg)
-{
- struct ulpt_softc *sc = arg;
-
- mtx_assert(&sc->sc_mtx, MA_OWNED);
-
- usb2_transfer_start(sc->sc_xfer[ULPT_INTR_DT_RD]);
-
- usb2_callout_reset(&sc->sc_watchdog,
- hz, &ulpt_watchdog, sc);
-}
-
-static devclass_t ulpt_devclass;
-
-static device_method_t ulpt_methods[] = {
- DEVMETHOD(device_probe, ulpt_probe),
- DEVMETHOD(device_attach, ulpt_attach),
- DEVMETHOD(device_detach, ulpt_detach),
- {0, 0}
-};
-
-static driver_t ulpt_driver = {
- .name = "ulpt",
- .methods = ulpt_methods,
- .size = sizeof(struct ulpt_softc),
-};
-
-DRIVER_MODULE(ulpt, ushub, ulpt_driver, ulpt_devclass, NULL, 0);
-MODULE_DEPEND(ulpt, usb2_core, 1, 1, 1);
-MODULE_DEPEND(ulpt, usb2_serial, 1, 1, 1);
diff --git a/sys/dev/usb2/serial/umct2.c b/sys/dev/usb2/serial/umct2.c
deleted file mode 100644
index f5d13d9..0000000
--- a/sys/dev/usb2/serial/umct2.c
+++ /dev/null
@@ -1,579 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * 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.
- *
- */
-
-/*
- * 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.
- */
-
-/*
- * NOTE: all function names beginning like "umct_cfg_" can only
- * be called from within the config thread function !
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_device.h>
-
-#include <dev/usb2/serial/usb2_serial.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
-
-enum {
- UMCT_BULK_DT_WR,
- UMCT_BULK_DT_RD,
- UMCT_INTR_DT_RD,
- UMCT_N_TRANSFER,
-};
-
-struct umct_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[UMCT_N_TRANSFER];
-
- uint32_t sc_unit;
-
- uint16_t sc_obufsize;
-
- uint8_t sc_lsr;
- uint8_t sc_msr;
- uint8_t sc_lcr;
- uint8_t sc_mcr;
- uint8_t sc_iface_no;
- uint8_t sc_name[16];
-};
-
-/* prototypes */
-
-static device_probe_t umct_probe;
-static device_attach_t umct_attach;
-static device_detach_t umct_detach;
-
-static usb2_callback_t umct_intr_callback;
-static usb2_callback_t umct_write_callback;
-static usb2_callback_t umct_read_callback;
-
-static void umct_cfg_do_request(struct umct_softc *sc, uint8_t request,
- uint16_t len, uint32_t value);
-static void umct_cfg_get_status(struct usb2_com_softc *, uint8_t *,
- uint8_t *);
-static void umct_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static void umct_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
-static void umct_cfg_set_rts(struct usb2_com_softc *, uint8_t);
-static uint8_t umct_calc_baud(uint32_t);
-static int umct_pre_param(struct usb2_com_softc *, struct termios *);
-static void umct_cfg_param(struct usb2_com_softc *, struct termios *);
-static void umct_start_read(struct usb2_com_softc *);
-static void umct_stop_read(struct usb2_com_softc *);
-static void umct_start_write(struct usb2_com_softc *);
-static void umct_stop_write(struct usb2_com_softc *);
-
-static const struct usb2_config umct_config[UMCT_N_TRANSFER] = {
-
- [UMCT_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &umct_write_callback,
- },
-
- [UMCT_BULK_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = &umct_read_callback,
- .ep_index = 0, /* first interrupt endpoint */
- },
-
- [UMCT_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = &umct_intr_callback,
- .ep_index = 1, /* second interrupt endpoint */
- },
-};
-
-static const struct usb2_com_callback umct_callback = {
- .usb2_com_cfg_get_status = &umct_cfg_get_status,
- .usb2_com_cfg_set_dtr = &umct_cfg_set_dtr,
- .usb2_com_cfg_set_rts = &umct_cfg_set_rts,
- .usb2_com_cfg_set_break = &umct_cfg_set_break,
- .usb2_com_cfg_param = &umct_cfg_param,
- .usb2_com_pre_param = &umct_pre_param,
- .usb2_com_start_read = &umct_start_read,
- .usb2_com_stop_read = &umct_stop_read,
- .usb2_com_start_write = &umct_start_write,
- .usb2_com_stop_write = &umct_stop_write,
-};
-
-static const struct usb2_device_id umct_devs[] = {
- {USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, 0)},
- {USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_SITECOM_USB232, 0)},
- {USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_DU_H3SP_USB232, 0)},
- {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U109, 0)},
- {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U409, 0)},
-};
-
-static device_method_t umct_methods[] = {
- DEVMETHOD(device_probe, umct_probe),
- DEVMETHOD(device_attach, umct_attach),
- DEVMETHOD(device_detach, umct_detach),
- {0, 0}
-};
-
-static devclass_t umct_devclass;
-
-static driver_t umct_driver = {
- .name = "umct",
- .methods = umct_methods,
- .size = sizeof(struct umct_softc),
-};
-
-DRIVER_MODULE(umct, ushub, umct_driver, umct_devclass, NULL, 0);
-MODULE_DEPEND(umct, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(umct, usb2_core, 1, 1, 1);
-
-static int
-umct_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != UMCT_CONFIG_INDEX) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != UMCT_IFACE_INDEX) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(umct_devs, sizeof(umct_devs), uaa));
-}
-
-static int
-umct_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct umct_softc *sc = device_get_softc(dev);
- int32_t error;
- uint16_t maxp;
- uint8_t iface_index;
-
- sc->sc_udev = uaa->device;
- sc->sc_unit = device_get_unit(dev);
-
- device_set_usb2_desc(dev);
-
- snprintf(sc->sc_name, sizeof(sc->sc_name),
- "%s", device_get_nameunit(dev));
-
- sc->sc_iface_no = uaa->info.bIfaceNum;
-
- iface_index = UMCT_IFACE_INDEX;
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, umct_config, UMCT_N_TRANSFER, sc, &Giant);
-
- if (error) {
- device_printf(dev, "allocating USB "
- "transfers failed!\n");
- goto detach;
- }
- /*
- * 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.
- */
- maxp = UGETW(sc->sc_xfer[UMCT_BULK_DT_RD]->pipe->edesc->wMaxPacketSize);
- if (maxp == 0x2) {
-
- /* guessed wrong - switch around endpoints */
-
- struct usb2_xfer *temp = sc->sc_xfer[UMCT_INTR_DT_RD];
-
- sc->sc_xfer[UMCT_INTR_DT_RD] = sc->sc_xfer[UMCT_BULK_DT_RD];
- sc->sc_xfer[UMCT_BULK_DT_RD] = temp;
-
- sc->sc_xfer[UMCT_BULK_DT_RD]->callback = &umct_read_callback;
- sc->sc_xfer[UMCT_INTR_DT_RD]->callback = &umct_intr_callback;
- }
- sc->sc_obufsize = sc->sc_xfer[UMCT_BULK_DT_WR]->max_data_length;
-
- if (uaa->info.idProduct == USB_PRODUCT_MCT_SITECOM_USB232) {
- if (sc->sc_obufsize > 16) {
- sc->sc_obufsize = 16;
- }
- }
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &umct_callback, &Giant);
- if (error) {
- goto detach;
- }
- return (0); /* success */
-
-detach:
- umct_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-umct_detach(device_t dev)
-{
- struct umct_softc *sc = device_get_softc(dev);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UMCT_N_TRANSFER);
-
- return (0);
-}
-
-static void
-umct_cfg_do_request(struct umct_softc *sc, uint8_t request,
- uint16_t len, uint32_t value)
-{
- struct usb2_device_request req;
- usb2_error_t err;
- uint8_t temp[4];
-
- if (len > 4)
- len = 4;
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = request;
- USETW(req.wValue, 0);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, len);
- USETDW(temp, value);
-
- err = usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, temp, 0, 1000);
- if (err) {
- DPRINTFN(0, "device request failed, err=%s "
- "(ignored)\n", usb2_errstr(err));
- }
- return;
-}
-
-static void
-umct_intr_callback(struct usb2_xfer *xfer)
-{
- struct umct_softc *sc = xfer->priv_sc;
- uint8_t buf[2];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- if (xfer->actlen < 2) {
- DPRINTF("too short message\n");
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, 0, buf, sizeof(buf));
-
- sc->sc_msr = buf[0];
- sc->sc_lsr = buf[1];
-
- usb2_com_status_change(&sc->sc_ucom);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-umct_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
- struct umct_softc *sc = ucom->sc_parent;
-
- *lsr = sc->sc_lsr;
- *msr = sc->sc_msr;
-}
-
-static void
-umct_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct umct_softc *sc = ucom->sc_parent;
-
- if (onoff)
- sc->sc_lcr |= 0x40;
- else
- sc->sc_lcr &= ~0x40;
-
- umct_cfg_do_request(sc, UMCT_SET_LCR, UMCT_SET_LCR_SIZE, sc->sc_lcr);
-}
-
-static void
-umct_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct umct_softc *sc = ucom->sc_parent;
-
- if (onoff)
- sc->sc_mcr |= 0x01;
- else
- sc->sc_mcr &= ~0x01;
-
- umct_cfg_do_request(sc, UMCT_SET_MCR, UMCT_SET_MCR_SIZE, sc->sc_mcr);
-}
-
-static void
-umct_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct umct_softc *sc = ucom->sc_parent;
-
- if (onoff)
- sc->sc_mcr |= 0x02;
- else
- sc->sc_mcr &= ~0x02;
-
- umct_cfg_do_request(sc, UMCT_SET_MCR, UMCT_SET_MCR_SIZE, sc->sc_mcr);
-}
-
-static uint8_t
-umct_calc_baud(uint32_t 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_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- return (0); /* we accept anything */
-}
-
-static void
-umct_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct umct_softc *sc = ucom->sc_parent;
- uint32_t value;
-
- value = umct_calc_baud(t->c_ospeed);
- umct_cfg_do_request(sc, UMCT_SET_BAUD, UMCT_SET_BAUD_SIZE, value);
-
- value = (sc->sc_lcr & 0x40);
-
- switch (t->c_cflag & CSIZE) {
- case CS5:
- value |= 0x0;
- break;
- case CS6:
- value |= 0x1;
- break;
- case CS7:
- value |= 0x2;
- break;
- default:
- case CS8:
- value |= 0x3;
- break;
- }
-
- value |= (t->c_cflag & CSTOPB) ? 0x4 : 0;
- if (t->c_cflag & PARENB) {
- value |= 0x8;
- value |= (t->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_cfg_do_request(sc, UMCT_SET_LCR, UMCT_SET_LCR_SIZE, value);
-}
-
-static void
-umct_start_read(struct usb2_com_softc *ucom)
-{
- struct umct_softc *sc = ucom->sc_parent;
-
- /* start interrupt endpoint */
- usb2_transfer_start(sc->sc_xfer[UMCT_INTR_DT_RD]);
-
- /* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[UMCT_BULK_DT_RD]);
-}
-
-static void
-umct_stop_read(struct usb2_com_softc *ucom)
-{
- struct umct_softc *sc = ucom->sc_parent;
-
- /* stop interrupt endpoint */
- usb2_transfer_stop(sc->sc_xfer[UMCT_INTR_DT_RD]);
-
- /* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[UMCT_BULK_DT_RD]);
-}
-
-static void
-umct_start_write(struct usb2_com_softc *ucom)
-{
- struct umct_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UMCT_BULK_DT_WR]);
-}
-
-static void
-umct_stop_write(struct usb2_com_softc *ucom)
-{
- struct umct_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UMCT_BULK_DT_WR]);
-}
-
-static void
-umct_write_callback(struct usb2_xfer *xfer)
-{
- struct umct_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- sc->sc_obufsize, &actlen)) {
-
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-umct_read_callback(struct usb2_xfer *xfer)
-{
- struct umct_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers,
- 0, xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
diff --git a/sys/dev/usb2/serial/umodem2.c b/sys/dev/usb2/serial/umodem2.c
deleted file mode 100644
index cfb9715..0000000
--- a/sys/dev/usb2/serial/umodem2.c
+++ /dev/null
@@ -1,788 +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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR umodem_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_device.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#if USB_DEBUG
-static int umodem_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, umodem, CTLFLAG_RW, 0, "USB umodem");
-SYSCTL_INT(_hw_usb2_umodem, OID_AUTO, debug, CTLFLAG_RW,
- &umodem_debug, 0, "Debug level");
-#endif
-
-static const struct usb2_device_id umodem_devs[] = {
- /* Generic Modem class match */
- {USB_IFACE_CLASS(UICLASS_CDC),
- USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),
- USB_IFACE_PROTOCOL(UIPROTO_CDC_AT)},
- /* Kyocera AH-K3001V */
- {USB_VPI(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_AHK3001V, 1)},
- {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, 1)},
- {USB_VPI(USB_VENDOR_CURITEL, USB_PRODUCT_CURITEL_PC5740, 1)},
-};
-
-/*
- * As speeds for umodem deivces increase, these numbers will need to
- * be increased. They should be good for G3 speeds and below.
- *
- * TODO: The TTY buffers should be increased!
- */
-#define UMODEM_BUF_SIZE 1024
-
-enum {
- UMODEM_BULK_WR,
- UMODEM_BULK_RD,
- UMODEM_INTR_RD,
- UMODEM_N_TRANSFER,
-};
-
-#define UMODEM_MODVER 1 /* module version */
-
-struct umodem_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_xfer *sc_xfer[UMODEM_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint16_t sc_line;
-
- uint8_t sc_lsr; /* local status register */
- uint8_t sc_msr; /* modem status register */
- uint8_t sc_ctrl_iface_no;
- uint8_t sc_data_iface_no;
- uint8_t sc_iface_index[2];
- uint8_t sc_cm_over_data;
- uint8_t sc_cm_cap; /* CM capabilities */
- uint8_t sc_acm_cap; /* ACM capabilities */
-};
-
-static device_probe_t umodem_probe;
-static device_attach_t umodem_attach;
-static device_detach_t umodem_detach;
-
-static usb2_callback_t umodem_intr_callback;
-static usb2_callback_t umodem_write_callback;
-static usb2_callback_t umodem_read_callback;
-
-static void umodem_start_read(struct usb2_com_softc *);
-static void umodem_stop_read(struct usb2_com_softc *);
-static void umodem_start_write(struct usb2_com_softc *);
-static void umodem_stop_write(struct usb2_com_softc *);
-static void umodem_get_caps(struct usb2_attach_arg *, uint8_t *, uint8_t *);
-static void umodem_cfg_get_status(struct usb2_com_softc *, uint8_t *,
- uint8_t *);
-static int umodem_pre_param(struct usb2_com_softc *, struct termios *);
-static void umodem_cfg_param(struct usb2_com_softc *, struct termios *);
-static int umodem_ioctl(struct usb2_com_softc *, uint32_t, caddr_t, int,
- struct thread *);
-static void umodem_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
-static void umodem_cfg_set_rts(struct usb2_com_softc *, uint8_t);
-static void umodem_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static void *umodem_get_desc(struct usb2_attach_arg *, uint8_t, uint8_t);
-static usb2_error_t umodem_set_comm_feature(struct usb2_device *, uint8_t,
- uint16_t, uint16_t);
-
-static const struct usb2_config umodem_config[UMODEM_N_TRANSFER] = {
-
- [UMODEM_BULK_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .if_index = 0,
- .mh.bufsize = UMODEM_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &umodem_write_callback,
- },
-
- [UMODEM_BULK_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .if_index = 0,
- .mh.bufsize = UMODEM_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &umodem_read_callback,
- },
-
- [UMODEM_INTR_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .if_index = 1,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = &umodem_intr_callback,
- },
-};
-
-static const struct usb2_com_callback umodem_callback = {
- .usb2_com_cfg_get_status = &umodem_cfg_get_status,
- .usb2_com_cfg_set_dtr = &umodem_cfg_set_dtr,
- .usb2_com_cfg_set_rts = &umodem_cfg_set_rts,
- .usb2_com_cfg_set_break = &umodem_cfg_set_break,
- .usb2_com_cfg_param = &umodem_cfg_param,
- .usb2_com_pre_param = &umodem_pre_param,
- .usb2_com_ioctl = &umodem_ioctl,
- .usb2_com_start_read = &umodem_start_read,
- .usb2_com_stop_read = &umodem_stop_read,
- .usb2_com_start_write = &umodem_start_write,
- .usb2_com_stop_write = &umodem_stop_write,
-};
-
-static device_method_t umodem_methods[] = {
- DEVMETHOD(device_probe, umodem_probe),
- DEVMETHOD(device_attach, umodem_attach),
- DEVMETHOD(device_detach, umodem_detach),
- {0, 0}
-};
-
-static devclass_t umodem_devclass;
-
-static driver_t umodem_driver = {
- .name = "umodem",
- .methods = umodem_methods,
- .size = sizeof(struct umodem_softc),
-};
-
-DRIVER_MODULE(umodem, ushub, umodem_driver, umodem_devclass, NULL, 0);
-MODULE_DEPEND(umodem, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(umodem, usb2_core, 1, 1, 1);
-MODULE_VERSION(umodem, UMODEM_MODVER);
-
-static int
-umodem_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- uint8_t cm;
- uint8_t acm;
- int error;
-
- DPRINTFN(11, "\n");
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- error = usb2_lookup_id_by_uaa(umodem_devs, sizeof(umodem_devs), uaa);
- if (error) {
- return (error);
- }
- if (uaa->driver_info == NULL) {
- /* some modems do not have any capabilities */
- return (error);
- }
- umodem_get_caps(uaa, &cm, &acm);
- if (!(cm & USB_CDC_CM_DOES_CM) ||
- !(cm & USB_CDC_CM_OVER_DATA) ||
- !(acm & USB_CDC_ACM_HAS_LINE)) {
- error = ENXIO;
- }
- return (error);
-}
-
-static int
-umodem_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct umodem_softc *sc = device_get_softc(dev);
- struct usb2_cdc_cm_descriptor *cmd;
- uint8_t i;
- int error;
-
- device_set_usb2_desc(dev);
-
- sc->sc_ctrl_iface_no = uaa->info.bIfaceNum;
- sc->sc_iface_index[1] = uaa->info.bIfaceIndex;
- sc->sc_udev = uaa->device;
-
- umodem_get_caps(uaa, &sc->sc_cm_cap, &sc->sc_acm_cap);
-
- /* get the data interface number */
-
- cmd = umodem_get_desc(uaa, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
-
- if ((cmd == NULL) || (cmd->bLength < sizeof(*cmd))) {
- device_printf(dev, "no CM descriptor!\n");
- goto detach;
- }
- sc->sc_data_iface_no = cmd->bDataInterface;
-
- device_printf(dev, "data interface %d, has %sCM over "
- "data, has %sbreak\n",
- 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 ");
-
- /* get the data interface too */
-
- for (i = 0;; i++) {
- struct usb2_interface *iface;
- struct usb2_interface_descriptor *id;
-
- iface = usb2_get_iface(uaa->device, i);
-
- if (iface) {
-
- id = usb2_get_interface_descriptor(iface);
-
- if (id && (id->bInterfaceNumber == sc->sc_data_iface_no)) {
- sc->sc_iface_index[0] = i;
- usb2_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
- break;
- }
- } else {
- device_printf(dev, "no data interface!\n");
- goto detach;
- }
- }
-
- if (sc->sc_cm_cap & USB_CDC_CM_OVER_DATA) {
- if (sc->sc_acm_cap & USB_CDC_ACM_HAS_FEATURE) {
-
- error = umodem_set_comm_feature
- (uaa->device, sc->sc_ctrl_iface_no,
- UCDC_ABSTRACT_STATE, UCDC_DATA_MULTIPLEXED);
-
- /* ignore any errors */
- }
- sc->sc_cm_over_data = 1;
- }
- error = usb2_transfer_setup(uaa->device,
- sc->sc_iface_index, sc->sc_xfer,
- umodem_config, UMODEM_N_TRANSFER,
- sc, &Giant);
- if (error) {
- goto detach;
- }
-
- /* clear stall at first run */
- usb2_transfer_set_stall(sc->sc_xfer[UMODEM_BULK_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[UMODEM_BULK_RD]);
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &umodem_callback, &Giant);
- if (error) {
- goto detach;
- }
- return (0);
-
-detach:
- umodem_detach(dev);
- return (ENXIO);
-}
-
-static void
-umodem_start_read(struct usb2_com_softc *ucom)
-{
- struct umodem_softc *sc = ucom->sc_parent;
-
- /* start interrupt endpoint, if any */
- usb2_transfer_start(sc->sc_xfer[UMODEM_INTR_RD]);
-
- /* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[UMODEM_BULK_RD]);
-}
-
-static void
-umodem_stop_read(struct usb2_com_softc *ucom)
-{
- struct umodem_softc *sc = ucom->sc_parent;
-
- /* stop interrupt endpoint, if any */
- usb2_transfer_stop(sc->sc_xfer[UMODEM_INTR_RD]);
-
- /* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[UMODEM_BULK_RD]);
-}
-
-static void
-umodem_start_write(struct usb2_com_softc *ucom)
-{
- struct umodem_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UMODEM_BULK_WR]);
-}
-
-static void
-umodem_stop_write(struct usb2_com_softc *ucom)
-{
- struct umodem_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UMODEM_BULK_WR]);
-}
-
-static void
-umodem_get_caps(struct usb2_attach_arg *uaa, uint8_t *cm, uint8_t *acm)
-{
- struct usb2_cdc_cm_descriptor *cmd;
- struct usb2_cdc_acm_descriptor *cad;
-
- *cm = *acm = 0;
-
- cmd = umodem_get_desc(uaa, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
- if ((cmd == NULL) || (cmd->bLength < sizeof(*cmd))) {
- DPRINTF("no CM desc\n");
- return;
- }
- *cm = cmd->bmCapabilities;
-
- cad = umodem_get_desc(uaa, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM);
- if ((cad == NULL) || (cad->bLength < sizeof(*cad))) {
- DPRINTF("no ACM desc\n");
- return;
- }
- *acm = cad->bmCapabilities;
-}
-
-static void
-umodem_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
- struct umodem_softc *sc = ucom->sc_parent;
-
- DPRINTF("\n");
-
- *lsr = sc->sc_lsr;
- *msr = sc->sc_msr;
-}
-
-static int
-umodem_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- return (0); /* we accept anything */
-}
-
-static void
-umodem_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct umodem_softc *sc = ucom->sc_parent;
- struct usb2_cdc_line_state ls;
- struct usb2_device_request req;
-
- DPRINTF("sc=%p\n", sc);
-
- bzero(&ls, sizeof(ls));
-
- USETDW(ls.dwDTERate, t->c_ospeed);
-
- ls.bCharFormat = (t->c_cflag & CSTOPB) ?
- UCDC_STOP_BIT_2 : UCDC_STOP_BIT_1;
-
- ls.bParityType = (t->c_cflag & PARENB) ?
- ((t->c_cflag & PARODD) ?
- UCDC_PARITY_ODD : UCDC_PARITY_EVEN) : UCDC_PARITY_NONE;
-
- switch (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;
- }
-
- DPRINTF("rate=%d fmt=%d parity=%d bits=%d\n",
- UGETDW(ls.dwDTERate), ls.bCharFormat,
- ls.bParityType, ls.bDataBits);
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_LINE_CODING;
- USETW(req.wValue, 0);
- req.wIndex[0] = sc->sc_ctrl_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, sizeof(ls));
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, &ls, 0, 1000);
-}
-
-static int
-umodem_ioctl(struct usb2_com_softc *ucom, uint32_t cmd, caddr_t data,
- int flag, struct thread *td)
-{
- struct umodem_softc *sc = ucom->sc_parent;
- int error = 0;
-
- DPRINTF("cmd=0x%08x\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("unknown\n");
- error = ENOIOCTL;
- break;
- }
-
- return (error);
-}
-
-static void
-umodem_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct umodem_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
-
- DPRINTF("onoff=%d\n", onoff);
-
- if (onoff)
- sc->sc_line |= UCDC_LINE_DTR;
- else
- sc->sc_line &= ~UCDC_LINE_DTR;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, sc->sc_line);
- req.wIndex[0] = sc->sc_ctrl_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-umodem_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct umodem_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
-
- DPRINTF("onoff=%d\n", onoff);
-
- if (onoff)
- sc->sc_line |= UCDC_LINE_RTS;
- else
- sc->sc_line &= ~UCDC_LINE_RTS;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, sc->sc_line);
- req.wIndex[0] = sc->sc_ctrl_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-umodem_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct umodem_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
- uint16_t temp;
-
- DPRINTF("onoff=%d\n", onoff);
-
- if (sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK) {
-
- temp = onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
- USETW(req.wValue, temp);
- req.wIndex[0] = sc->sc_ctrl_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
- }
-}
-
-static void
-umodem_intr_callback(struct usb2_xfer *xfer)
-{
- struct usb2_cdc_notification pkt;
- struct umodem_softc *sc = xfer->priv_sc;
- uint16_t wLen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (xfer->actlen < 8) {
- DPRINTF("received short packet, "
- "%d bytes\n", xfer->actlen);
- goto tr_setup;
- }
- if (xfer->actlen > sizeof(pkt)) {
- DPRINTF("truncating message\n");
- xfer->actlen = sizeof(pkt);
- }
- usb2_copy_out(xfer->frbuffers, 0, &pkt, xfer->actlen);
-
- xfer->actlen -= 8;
-
- wLen = UGETW(pkt.wLength);
- if (xfer->actlen > wLen) {
- xfer->actlen = wLen;
- }
- if (pkt.bmRequestType != UCDC_NOTIFICATION) {
- DPRINTF("unknown message type, "
- "0x%02x, on notify pipe!\n",
- pkt.bmRequestType);
- goto tr_setup;
- }
- switch (pkt.bNotification) {
- case UCDC_N_SERIAL_STATE:
- /*
- * Set the serial state in ucom driver based on
- * the bits from the notify message
- */
- if (xfer->actlen < 2) {
- DPRINTF("invalid notification "
- "length, %d bytes!\n", xfer->actlen);
- break;
- }
- DPRINTF("notify bytes = %02x%02x\n",
- pkt.data[0],
- pkt.data[1]);
-
- /* Currently, lsr is always zero. */
- sc->sc_lsr = 0;
- sc->sc_msr = 0;
-
- if (pkt.data[0] & UCDC_N_SERIAL_RI) {
- sc->sc_msr |= SER_RI;
- }
- if (pkt.data[0] & UCDC_N_SERIAL_DSR) {
- sc->sc_msr |= SER_DSR;
- }
- if (pkt.data[0] & UCDC_N_SERIAL_DCD) {
- sc->sc_msr |= SER_DCD;
- }
- usb2_com_status_change(&sc->sc_ucom);
- break;
-
- default:
- DPRINTF("unknown notify message: 0x%02x\n",
- pkt.bNotification);
- break;
- }
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
-
- }
-}
-
-static void
-umodem_write_callback(struct usb2_xfer *xfer)
-{
- struct umodem_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- UMODEM_BUF_SIZE, &actlen)) {
-
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-umodem_read_callback(struct usb2_xfer *xfer)
-{
- struct umodem_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- DPRINTF("actlen=%d\n", xfer->actlen);
-
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0,
- xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void *
-umodem_get_desc(struct usb2_attach_arg *uaa, uint8_t type, uint8_t subtype)
-{
- return (usb2_find_descriptor(uaa->device, NULL, uaa->info.bIfaceIndex,
- type, 0 - 1, subtype, 0 - 1));
-}
-
-static usb2_error_t
-umodem_set_comm_feature(struct usb2_device *udev, uint8_t iface_no,
- uint16_t feature, uint16_t state)
-{
- struct usb2_device_request req;
- struct usb2_cdc_abstract_state ast;
-
- DPRINTF("feature=%d state=%d\n",
- feature, state);
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_COMM_FEATURE;
- USETW(req.wValue, feature);
- req.wIndex[0] = iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, UCDC_ABSTRACT_STATE_LENGTH);
- USETW(ast.wState, state);
-
- return (usb2_do_request(udev, &Giant, &req, &ast));
-}
-
-static int
-umodem_detach(device_t dev)
-{
- struct umodem_softc *sc = device_get_softc(dev);
-
- DPRINTF("sc=%p\n", sc);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UMODEM_N_TRANSFER);
-
- return (0);
-}
diff --git a/sys/dev/usb2/serial/umoscom2.c b/sys/dev/usb2/serial/umoscom2.c
deleted file mode 100644
index 9d09527..0000000
--- a/sys/dev/usb2/serial/umoscom2.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/* $FreeBSD$ */
-/* $OpenBSD: umoscom.c,v 1.2 2006/10/26 06:02:43 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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-
-#define USB_DEBUG_VAR umoscom_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#if USB_DEBUG
-static int umoscom_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, umoscom, CTLFLAG_RW, 0, "USB umoscom");
-SYSCTL_INT(_hw_usb2_umoscom, OID_AUTO, debug, CTLFLAG_RW,
- &umoscom_debug, 0, "Debug level");
-#endif
-
-#define UMOSCOM_BUFSIZE 1024 /* bytes */
-
-#define UMOSCOM_CONFIG_INDEX 0
-#define UMOSCOM_IFACE_INDEX 0
-
-/* interrupt packet */
-#define UMOSCOM_IIR_RLS 0x06
-#define UMOSCOM_IIR_RDA 0x04
-#define UMOSCOM_IIR_CTI 0x0c
-#define UMOSCOM_IIR_THR 0x02
-#define UMOSCOM_IIR_MS 0x00
-
-/* registers */
-#define UMOSCOM_READ 0x0d
-#define UMOSCOM_WRITE 0x0e
-#define UMOSCOM_UART_REG 0x0300
-#define UMOSCOM_VEND_REG 0x0000
-
-#define UMOSCOM_TXBUF 0x00 /* Write */
-#define UMOSCOM_RXBUF 0x00 /* Read */
-#define UMOSCOM_INT 0x01
-#define UMOSCOM_FIFO 0x02 /* Write */
-#define UMOSCOM_ISR 0x02 /* Read */
-#define UMOSCOM_LCR 0x03
-#define UMOSCOM_MCR 0x04
-#define UMOSCOM_LSR 0x05
-#define UMOSCOM_MSR 0x06
-#define UMOSCOM_SCRATCH 0x07
-#define UMOSCOM_DIV_LO 0x08
-#define UMOSCOM_DIV_HI 0x09
-#define UMOSCOM_EFR 0x0a
-#define UMOSCOM_XON1 0x0b
-#define UMOSCOM_XON2 0x0c
-#define UMOSCOM_XOFF1 0x0d
-#define UMOSCOM_XOFF2 0x0e
-
-#define UMOSCOM_BAUDLO 0x00
-#define UMOSCOM_BAUDHI 0x01
-
-#define UMOSCOM_INT_RXEN 0x01
-#define UMOSCOM_INT_TXEN 0x02
-#define UMOSCOM_INT_RSEN 0x04
-#define UMOSCOM_INT_MDMEM 0x08
-#define UMOSCOM_INT_SLEEP 0x10
-#define UMOSCOM_INT_XOFF 0x20
-#define UMOSCOM_INT_RTS 0x40
-
-#define UMOSCOM_FIFO_EN 0x01
-#define UMOSCOM_FIFO_RXCLR 0x02
-#define UMOSCOM_FIFO_TXCLR 0x04
-#define UMOSCOM_FIFO_DMA_BLK 0x08
-#define UMOSCOM_FIFO_TXLVL_MASK 0x30
-#define UMOSCOM_FIFO_TXLVL_8 0x00
-#define UMOSCOM_FIFO_TXLVL_16 0x10
-#define UMOSCOM_FIFO_TXLVL_32 0x20
-#define UMOSCOM_FIFO_TXLVL_56 0x30
-#define UMOSCOM_FIFO_RXLVL_MASK 0xc0
-#define UMOSCOM_FIFO_RXLVL_8 0x00
-#define UMOSCOM_FIFO_RXLVL_16 0x40
-#define UMOSCOM_FIFO_RXLVL_56 0x80
-#define UMOSCOM_FIFO_RXLVL_80 0xc0
-
-#define UMOSCOM_ISR_MDM 0x00
-#define UMOSCOM_ISR_NONE 0x01
-#define UMOSCOM_ISR_TX 0x02
-#define UMOSCOM_ISR_RX 0x04
-#define UMOSCOM_ISR_LINE 0x06
-#define UMOSCOM_ISR_RXTIMEOUT 0x0c
-#define UMOSCOM_ISR_RX_XOFF 0x10
-#define UMOSCOM_ISR_RTSCTS 0x20
-#define UMOSCOM_ISR_FIFOEN 0xc0
-
-#define UMOSCOM_LCR_DBITS(x) ((x) - 5)
-#define UMOSCOM_LCR_STOP_BITS_1 0x00
-#define UMOSCOM_LCR_STOP_BITS_2 0x04 /* 2 if 6-8 bits/char or 1.5 if 5 */
-#define UMOSCOM_LCR_PARITY_NONE 0x00
-#define UMOSCOM_LCR_PARITY_ODD 0x08
-#define UMOSCOM_LCR_PARITY_EVEN 0x18
-#define UMOSCOM_LCR_BREAK 0x40
-#define UMOSCOM_LCR_DIVLATCH_EN 0x80
-
-#define UMOSCOM_MCR_DTR 0x01
-#define UMOSCOM_MCR_RTS 0x02
-#define UMOSCOM_MCR_LOOP 0x04
-#define UMOSCOM_MCR_INTEN 0x08
-#define UMOSCOM_MCR_LOOPBACK 0x10
-#define UMOSCOM_MCR_XONANY 0x20
-#define UMOSCOM_MCR_IRDA_EN 0x40
-#define UMOSCOM_MCR_BAUD_DIV4 0x80
-
-#define UMOSCOM_LSR_RXDATA 0x01
-#define UMOSCOM_LSR_RXOVER 0x02
-#define UMOSCOM_LSR_RXPAR_ERR 0x04
-#define UMOSCOM_LSR_RXFRM_ERR 0x08
-#define UMOSCOM_LSR_RXBREAK 0x10
-#define UMOSCOM_LSR_TXEMPTY 0x20
-#define UMOSCOM_LSR_TXALLEMPTY 0x40
-#define UMOSCOM_LSR_TXFIFO_ERR 0x80
-
-#define UMOSCOM_MSR_CTS_CHG 0x01
-#define UMOSCOM_MSR_DSR_CHG 0x02
-#define UMOSCOM_MSR_RI_CHG 0x04
-#define UMOSCOM_MSR_CD_CHG 0x08
-#define UMOSCOM_MSR_CTS 0x10
-#define UMOSCOM_MSR_RTS 0x20
-#define UMOSCOM_MSR_RI 0x40
-#define UMOSCOM_MSR_CD 0x80
-
-#define UMOSCOM_BAUD_REF 115200
-
-enum {
- UMOSCOM_BULK_DT_WR,
- UMOSCOM_BULK_DT_RD,
- UMOSCOM_INTR_DT_RD,
- UMOSCOM_N_TRANSFER,
-};
-
-struct umoscom_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_xfer *sc_xfer[UMOSCOM_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint8_t sc_mcr;
- uint8_t sc_lcr;
-};
-
-/* prototypes */
-
-static device_probe_t umoscom_probe;
-static device_attach_t umoscom_attach;
-static device_detach_t umoscom_detach;
-
-static usb2_callback_t umoscom_write_callback;
-static usb2_callback_t umoscom_read_callback;
-static usb2_callback_t umoscom_intr_callback;
-
-static void umoscom_cfg_open(struct usb2_com_softc *);
-static void umoscom_cfg_close(struct usb2_com_softc *);
-static void umoscom_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static void umoscom_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
-static void umoscom_cfg_set_rts(struct usb2_com_softc *, uint8_t);
-static int umoscom_pre_param(struct usb2_com_softc *, struct termios *);
-static void umoscom_cfg_param(struct usb2_com_softc *, struct termios *);
-static void umoscom_cfg_get_status(struct usb2_com_softc *, uint8_t *,
- uint8_t *);
-static void umoscom_cfg_write(struct umoscom_softc *, uint16_t, uint16_t);
-static uint8_t umoscom_cfg_read(struct umoscom_softc *, uint16_t);
-static void umoscom_start_read(struct usb2_com_softc *);
-static void umoscom_stop_read(struct usb2_com_softc *);
-static void umoscom_start_write(struct usb2_com_softc *);
-static void umoscom_stop_write(struct usb2_com_softc *);
-
-static const struct usb2_config umoscom_config_data[UMOSCOM_N_TRANSFER] = {
-
- [UMOSCOM_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UMOSCOM_BUFSIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &umoscom_write_callback,
- },
-
- [UMOSCOM_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UMOSCOM_BUFSIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &umoscom_read_callback,
- },
-
- [UMOSCOM_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = &umoscom_intr_callback,
- },
-};
-
-static const struct usb2_com_callback umoscom_callback = {
- /* configuration callbacks */
- .usb2_com_cfg_get_status = &umoscom_cfg_get_status,
- .usb2_com_cfg_set_dtr = &umoscom_cfg_set_dtr,
- .usb2_com_cfg_set_rts = &umoscom_cfg_set_rts,
- .usb2_com_cfg_set_break = &umoscom_cfg_set_break,
- .usb2_com_cfg_param = &umoscom_cfg_param,
- .usb2_com_cfg_open = &umoscom_cfg_open,
- .usb2_com_cfg_close = &umoscom_cfg_close,
-
- /* other callbacks */
- .usb2_com_pre_param = &umoscom_pre_param,
- .usb2_com_start_read = &umoscom_start_read,
- .usb2_com_stop_read = &umoscom_stop_read,
- .usb2_com_start_write = &umoscom_start_write,
- .usb2_com_stop_write = &umoscom_stop_write,
-};
-
-static device_method_t umoscom_methods[] = {
- DEVMETHOD(device_probe, umoscom_probe),
- DEVMETHOD(device_attach, umoscom_attach),
- DEVMETHOD(device_detach, umoscom_detach),
- {0, 0}
-};
-
-static devclass_t umoscom_devclass;
-
-static driver_t umoscom_driver = {
- .name = "umoscom",
- .methods = umoscom_methods,
- .size = sizeof(struct umoscom_softc),
-};
-
-DRIVER_MODULE(umoscom, ushub, umoscom_driver, umoscom_devclass, NULL, 0);
-MODULE_DEPEND(umoscom, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(umoscom, usb2_core, 1, 1, 1);
-
-static const struct usb2_device_id umoscom_devs[] = {
- {USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7703, 0)}
-};
-
-static int
-umoscom_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != UMOSCOM_CONFIG_INDEX) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != UMOSCOM_IFACE_INDEX) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(umoscom_devs, sizeof(umoscom_devs), uaa));
-}
-
-static int
-umoscom_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct umoscom_softc *sc = device_get_softc(dev);
- int error;
- uint8_t iface_index;
-
- sc->sc_udev = uaa->device;
- sc->sc_mcr = 0x08; /* enable interrupts */
-
- /* XXX the device doesn't provide any ID string, so set a static one */
- device_set_desc(dev, "MOSCHIP USB Serial Port Adapter");
- device_printf(dev, "<MOSCHIP USB Serial Port Adapter>\n");
-
- iface_index = UMOSCOM_IFACE_INDEX;
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, umoscom_config_data,
- UMOSCOM_N_TRANSFER, sc, &Giant);
-
- if (error) {
- goto detach;
- }
- /* clear stall at first run */
- usb2_transfer_set_stall(sc->sc_xfer[UMOSCOM_BULK_DT_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[UMOSCOM_BULK_DT_RD]);
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &umoscom_callback, &Giant);
- if (error) {
- goto detach;
- }
- return (0);
-
-detach:
- device_printf(dev, "attach error: %s\n", usb2_errstr(error));
- umoscom_detach(dev);
- return (ENXIO);
-}
-
-static int
-umoscom_detach(device_t dev)
-{
- struct umoscom_softc *sc = device_get_softc(dev);
-
- mtx_lock(&Giant);
-
- mtx_unlock(&Giant);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UMOSCOM_N_TRANSFER);
-
- return (0);
-}
-
-static void
-umoscom_cfg_open(struct usb2_com_softc *ucom)
-{
- struct umoscom_softc *sc = ucom->sc_parent;
-
- DPRINTF("\n");
-
- /* Purge FIFOs or odd things happen */
- umoscom_cfg_write(sc, UMOSCOM_FIFO, 0x00 | UMOSCOM_UART_REG);
-
- /* Enable FIFO */
- umoscom_cfg_write(sc, UMOSCOM_FIFO, UMOSCOM_FIFO_EN |
- UMOSCOM_FIFO_RXCLR | UMOSCOM_FIFO_TXCLR |
- UMOSCOM_FIFO_DMA_BLK | UMOSCOM_FIFO_RXLVL_MASK |
- UMOSCOM_UART_REG);
-
- /* Enable Interrupt Registers */
- umoscom_cfg_write(sc, UMOSCOM_INT, 0x0C | UMOSCOM_UART_REG);
-
- /* Magic */
- umoscom_cfg_write(sc, 0x01, 0x08);
-
- /* Magic */
- umoscom_cfg_write(sc, 0x00, 0x02);
-}
-
-static void
-umoscom_cfg_close(struct usb2_com_softc *ucom)
-{
- return;
-}
-
-static void
-umoscom_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct umoscom_softc *sc = ucom->sc_parent;
- uint16_t val;
-
- val = sc->sc_lcr;
- if (onoff)
- val |= UMOSCOM_LCR_BREAK;
-
- umoscom_cfg_write(sc, UMOSCOM_LCR, val | UMOSCOM_UART_REG);
-}
-
-static void
-umoscom_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct umoscom_softc *sc = ucom->sc_parent;
-
- if (onoff)
- sc->sc_mcr |= UMOSCOM_MCR_DTR;
- else
- sc->sc_mcr &= ~UMOSCOM_MCR_DTR;
-
- umoscom_cfg_write(sc, UMOSCOM_MCR, sc->sc_mcr | UMOSCOM_UART_REG);
-}
-
-static void
-umoscom_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct umoscom_softc *sc = ucom->sc_parent;
-
- if (onoff)
- sc->sc_mcr |= UMOSCOM_MCR_RTS;
- else
- sc->sc_mcr &= ~UMOSCOM_MCR_RTS;
-
- umoscom_cfg_write(sc, UMOSCOM_MCR, sc->sc_mcr | UMOSCOM_UART_REG);
-}
-
-static int
-umoscom_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- if ((t->c_ospeed <= 1) || (t->c_ospeed > 115200))
- return (EINVAL);
-
- return (0);
-}
-
-static void
-umoscom_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct umoscom_softc *sc = ucom->sc_parent;
- uint16_t data;
-
- DPRINTF("speed=%d\n", t->c_ospeed);
-
- data = ((uint32_t)UMOSCOM_BAUD_REF) / ((uint32_t)t->c_ospeed);
-
- if (data == 0) {
- DPRINTF("invalid baud rate!\n");
- return;
- }
- umoscom_cfg_write(sc, UMOSCOM_LCR,
- UMOSCOM_LCR_DIVLATCH_EN | UMOSCOM_UART_REG);
-
- umoscom_cfg_write(sc, UMOSCOM_BAUDLO,
- (data & 0xFF) | UMOSCOM_UART_REG);
-
- umoscom_cfg_write(sc, UMOSCOM_BAUDHI,
- ((data >> 8) & 0xFF) | UMOSCOM_UART_REG);
-
- if (t->c_cflag & CSTOPB)
- data = UMOSCOM_LCR_STOP_BITS_2;
- else
- data = UMOSCOM_LCR_STOP_BITS_1;
-
- if (t->c_cflag & PARENB) {
- if (t->c_cflag & PARODD)
- data |= UMOSCOM_LCR_PARITY_ODD;
- else
- data |= UMOSCOM_LCR_PARITY_EVEN;
- } else
- data |= UMOSCOM_LCR_PARITY_NONE;
-
- switch (t->c_cflag & CSIZE) {
- case CS5:
- data |= UMOSCOM_LCR_DBITS(5);
- break;
- case CS6:
- data |= UMOSCOM_LCR_DBITS(6);
- break;
- case CS7:
- data |= UMOSCOM_LCR_DBITS(7);
- break;
- case CS8:
- data |= UMOSCOM_LCR_DBITS(8);
- break;
- }
-
- sc->sc_lcr = data;
- umoscom_cfg_write(sc, UMOSCOM_LCR, data | UMOSCOM_UART_REG);
-}
-
-static void
-umoscom_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *p_lsr, uint8_t *p_msr)
-{
- struct umoscom_softc *sc = ucom->sc_parent;
- uint8_t lsr;
- uint8_t msr;
-
- DPRINTFN(5, "\n");
-
- /* read status registers */
-
- lsr = umoscom_cfg_read(sc, UMOSCOM_LSR);
- msr = umoscom_cfg_read(sc, UMOSCOM_MSR);
-
- /* translate bits */
-
- if (msr & UMOSCOM_MSR_CTS)
- *p_msr |= SER_CTS;
-
- if (msr & UMOSCOM_MSR_CD)
- *p_msr |= SER_DCD;
-
- if (msr & UMOSCOM_MSR_RI)
- *p_msr |= SER_RI;
-
- if (msr & UMOSCOM_MSR_RTS)
- *p_msr |= SER_DSR;
-}
-
-static void
-umoscom_cfg_write(struct umoscom_softc *sc, uint16_t reg, uint16_t val)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UMOSCOM_WRITE;
- USETW(req.wValue, val);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static uint8_t
-umoscom_cfg_read(struct umoscom_softc *sc, uint16_t reg)
-{
- struct usb2_device_request req;
- uint8_t val;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = UMOSCOM_READ;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 1);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, &val, 0, 1000);
-
- DPRINTF("reg=0x%04x, val=0x%02x\n", reg, val);
-
- return (val);
-}
-
-static void
-umoscom_start_read(struct usb2_com_softc *ucom)
-{
- struct umoscom_softc *sc = ucom->sc_parent;
-
-#if 0
- /* start interrupt endpoint */
- usb2_transfer_start(sc->sc_xfer[UMOSCOM_INTR_DT_RD]);
-#endif
- /* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_DT_RD]);
-}
-
-static void
-umoscom_stop_read(struct usb2_com_softc *ucom)
-{
- struct umoscom_softc *sc = ucom->sc_parent;
-
- /* stop interrupt transfer */
- usb2_transfer_stop(sc->sc_xfer[UMOSCOM_INTR_DT_RD]);
-
- /* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_DT_RD]);
-}
-
-static void
-umoscom_start_write(struct usb2_com_softc *ucom)
-{
- struct umoscom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_DT_WR]);
-}
-
-static void
-umoscom_stop_write(struct usb2_com_softc *ucom)
-{
- struct umoscom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_DT_WR]);
-}
-
-static void
-umoscom_write_callback(struct usb2_xfer *xfer)
-{
- struct umoscom_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- DPRINTF("\n");
-
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- UMOSCOM_BUFSIZE, &actlen)) {
-
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- DPRINTFN(0, "transfer failed\n");
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-umoscom_read_callback(struct usb2_xfer *xfer)
-{
- struct umoscom_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTF("got %d bytes\n", xfer->actlen);
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- DPRINTF("\n");
-
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- DPRINTFN(0, "transfer failed\n");
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-umoscom_intr_callback(struct usb2_xfer *xfer)
-{
- struct umoscom_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- if (xfer->actlen < 2) {
- DPRINTF("too short message\n");
- goto tr_setup;
- }
- usb2_com_status_change(&sc->sc_ucom);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- DPRINTFN(0, "transfer failed\n");
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
diff --git a/sys/dev/usb2/serial/uplcom2.c b/sys/dev/usb2/serial/uplcom2.c
deleted file mode 100644
index b55edfd..0000000
--- a/sys/dev/usb2/serial/uplcom2.c
+++ /dev/null
@@ -1,831 +0,0 @@
-/* $NetBSD: uplcom.c,v 1.21 2001/11/13 06:24:56 lukem Exp $ */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * 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.
- */
-
-/*-
- * 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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-
-#define USB_DEBUG_VAR uplcom_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#if USB_DEBUG
-static int uplcom_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uplcom, CTLFLAG_RW, 0, "USB uplcom");
-SYSCTL_INT(_hw_usb2_uplcom, OID_AUTO, debug, CTLFLAG_RW,
- &uplcom_debug, 0, "Debug level");
-#endif
-
-#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 0 /* default */
-#endif
-
-#define UPLCOM_BULK_BUF_SIZE 1024 /* bytes */
-
-#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
-
-enum {
- UPLCOM_BULK_DT_WR,
- UPLCOM_BULK_DT_RD,
- UPLCOM_INTR_DT_RD,
- UPLCOM_N_TRANSFER,
-};
-
-struct uplcom_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_xfer *sc_xfer[UPLCOM_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint16_t sc_line;
-
- uint8_t sc_lsr; /* local status register */
- uint8_t sc_msr; /* uplcom status register */
- uint8_t sc_chiptype; /* type of chip */
- uint8_t sc_ctrl_iface_no;
- uint8_t sc_data_iface_no;
- uint8_t sc_iface_index[2];
-};
-
-/* prototypes */
-
-static usb2_error_t uplcom_reset(struct uplcom_softc *, struct usb2_device *);
-static int uplcom_pl2303x_init(struct usb2_device *);
-static void uplcom_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
-static void uplcom_cfg_set_rts(struct usb2_com_softc *, uint8_t);
-static void uplcom_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static int uplcom_pre_param(struct usb2_com_softc *, struct termios *);
-static void uplcom_cfg_param(struct usb2_com_softc *, struct termios *);
-static void uplcom_start_read(struct usb2_com_softc *);
-static void uplcom_stop_read(struct usb2_com_softc *);
-static void uplcom_start_write(struct usb2_com_softc *);
-static void uplcom_stop_write(struct usb2_com_softc *);
-static void uplcom_cfg_get_status(struct usb2_com_softc *, uint8_t *,
- uint8_t *);
-
-static device_probe_t uplcom_probe;
-static device_attach_t uplcom_attach;
-static device_detach_t uplcom_detach;
-
-static usb2_callback_t uplcom_intr_callback;
-static usb2_callback_t uplcom_write_callback;
-static usb2_callback_t uplcom_read_callback;
-
-static const struct usb2_config uplcom_config_data[UPLCOM_N_TRANSFER] = {
-
- [UPLCOM_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UPLCOM_BULK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &uplcom_write_callback,
- .if_index = 0,
- },
-
- [UPLCOM_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UPLCOM_BULK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &uplcom_read_callback,
- .if_index = 0,
- },
-
- [UPLCOM_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = &uplcom_intr_callback,
- .if_index = 1,
- },
-};
-
-struct usb2_com_callback uplcom_callback = {
- .usb2_com_cfg_get_status = &uplcom_cfg_get_status,
- .usb2_com_cfg_set_dtr = &uplcom_cfg_set_dtr,
- .usb2_com_cfg_set_rts = &uplcom_cfg_set_rts,
- .usb2_com_cfg_set_break = &uplcom_cfg_set_break,
- .usb2_com_cfg_param = &uplcom_cfg_param,
- .usb2_com_pre_param = &uplcom_pre_param,
- .usb2_com_start_read = &uplcom_start_read,
- .usb2_com_stop_read = &uplcom_stop_read,
- .usb2_com_start_write = &uplcom_start_write,
- .usb2_com_stop_write = &uplcom_stop_write,
-};
-
-#define USB_UPL(v,p,rl,rh,t) \
- USB_VENDOR(v), USB_PRODUCT(p), USB_DEV_BCD_GTEQ(rl), \
- USB_DEV_BCD_LTEQ(rh), USB_DRIVER_INFO(t)
-
-static const struct usb2_device_id uplcom_devs[] = {
- /* Belkin F5U257 */
- {USB_UPL(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U257, 0, 0xFFFF, TYPE_PL2303X)},
- /* I/O DATA USB-RSAQ */
- {USB_UPL(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBRSAQ, 0, 0xFFFF, TYPE_PL2303)},
- /* I/O DATA USB-RSAQ2 */
- {USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ2, 0, 0xFFFF, TYPE_PL2303)},
- /* I/O DATA USB-RSAQ3 */
- {USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ3, 0, 0xFFFF, TYPE_PL2303X)},
- /* PLANEX USB-RS232 URS-03 */
- {USB_UPL(USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC232A, 0, 0xFFFF, TYPE_PL2303)},
- /* TrendNet TU-S9 */
- {USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, 0x0400, 0xFFFF, TYPE_PL2303X)},
- /* ST Lab USB-SERIAL-4 */
- {USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, 0x0300, 0x03FF, TYPE_PL2303X)},
- /* IOGEAR/ATEN UC-232A (also ST Lab USB-SERIAL-1) */
- {USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, 0, 0x02FF, TYPE_PL2303)},
- /* TDK USB-PHS Adapter UHA6400 */
- {USB_UPL(USB_VENDOR_TDK, USB_PRODUCT_TDK_UHA6400, 0, 0xFFFF, TYPE_PL2303)},
- /* RATOC REX-USB60 */
- {USB_UPL(USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60, 0, 0xFFFF, TYPE_PL2303)},
- /* ELECOM UC-SGT */
- {USB_UPL(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT, 0, 0xFFFF, TYPE_PL2303)},
- {USB_UPL(USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT0, 0, 0xFFFF, TYPE_PL2303)},
- /* Sagem USB-Serial Controller */
- {USB_UPL(USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_USBSERIAL, 0, 0xFFFF, TYPE_PL2303X)},
- /* Sony Ericsson USB Cable */
- {USB_UPL(USB_VENDOR_SONYERICSSON, USB_PRODUCT_SONYERICSSON_DCU10, 0, 0xFFFF, TYPE_PL2303)},
- /* SOURCENEXT KeikaiDenwa 8 */
- {USB_UPL(USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8, 0, 0xFFFF, TYPE_PL2303)},
- /* SOURCENEXT KeikaiDenwa 8 with charger */
- {USB_UPL(USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG, 0, 0, TYPE_PL2303)},
- /* HAL Corporation Crossam2+USB */
- {USB_UPL(USB_VENDOR_HAL, USB_PRODUCT_HAL_IMR001, 0, 0xFFFF, TYPE_PL2303)},
- /* Sitecom USB to Serial */
- {USB_UPL(USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_SERIAL, 0, 0xFFFF, TYPE_PL2303)},
- /* Tripp-Lite U209-000-R */
- {USB_UPL(USB_VENDOR_TRIPPLITE, USB_PRODUCT_TRIPPLITE_U209, 0, 0xFFFF, TYPE_PL2303X)},
- {USB_UPL(USB_VENDOR_RADIOSHACK, USB_PRODUCT_RADIOSHACK_USBCABLE, 0, 0xFFFF, TYPE_PL2303)},
- /* Prolific Pharos */
- {USB_UPL(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PHAROS, 0, 0xFFFF, TYPE_PL2303)},
- /* Willcom W-SIM */
- {USB_UPL(USB_VENDOR_PROLIFIC2, USB_PRODUCT_PROLIFIC2_WSIM, 0, 0xFFFF, TYPE_PL2303X)},
-};
-
-static device_method_t uplcom_methods[] = {
- DEVMETHOD(device_probe, uplcom_probe),
- DEVMETHOD(device_attach, uplcom_attach),
- DEVMETHOD(device_detach, uplcom_detach),
- {0, 0}
-};
-
-static devclass_t uplcom_devclass;
-
-static driver_t uplcom_driver = {
- .name = "uplcom",
- .methods = uplcom_methods,
- .size = sizeof(struct uplcom_softc),
-};
-
-DRIVER_MODULE(uplcom, ushub, uplcom_driver, uplcom_devclass, NULL, 0);
-MODULE_DEPEND(uplcom, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(uplcom, usb2_core, 1, 1, 1);
-MODULE_VERSION(uplcom, UPLCOM_MODVER);
-
-static int
-uplcom_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- DPRINTFN(11, "\n");
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != UPLCOM_CONFIG_INDEX) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != UPLCOM_IFACE_INDEX) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(uplcom_devs, sizeof(uplcom_devs), uaa));
-}
-
-static int
-uplcom_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct uplcom_softc *sc = device_get_softc(dev);
- struct usb2_interface *iface;
- struct usb2_interface_descriptor *id;
- int error;
-
- DPRINTFN(11, "\n");
-
- device_set_usb2_desc(dev);
-
- DPRINTF("sc = %p\n", sc);
-
- sc->sc_chiptype = USB_GET_DRIVER_INFO(uaa);
- sc->sc_udev = uaa->device;
-
- DPRINTF("chiptype: %s\n",
- (sc->sc_chiptype == TYPE_PL2303X) ?
- "2303X" : "2303");
-
- /*
- * 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) |
- */
-
- sc->sc_ctrl_iface_no = uaa->info.bIfaceNum;
- sc->sc_iface_index[1] = UPLCOM_IFACE_INDEX;
-
- iface = usb2_get_iface(uaa->device, UPLCOM_SECOND_IFACE_INDEX);
- if (iface) {
- id = usb2_get_interface_descriptor(iface);
- if (id == NULL) {
- device_printf(dev, "no interface descriptor (2)!\n");
- goto detach;
- }
- sc->sc_data_iface_no = id->bInterfaceNumber;
- sc->sc_iface_index[0] = UPLCOM_SECOND_IFACE_INDEX;
- usb2_set_parent_iface(uaa->device,
- UPLCOM_SECOND_IFACE_INDEX, uaa->info.bIfaceIndex);
- } else {
- sc->sc_data_iface_no = sc->sc_ctrl_iface_no;
- sc->sc_iface_index[0] = UPLCOM_IFACE_INDEX;
- }
-
- error = usb2_transfer_setup(uaa->device,
- sc->sc_iface_index, sc->sc_xfer, uplcom_config_data,
- UPLCOM_N_TRANSFER, sc, &Giant);
- if (error) {
- DPRINTF("one or more missing USB endpoints, "
- "error=%s\n", usb2_errstr(error));
- goto detach;
- }
- error = uplcom_reset(sc, uaa->device);
- if (error) {
- device_printf(dev, "reset failed, error=%s\n",
- usb2_errstr(error));
- goto detach;
- }
- /* clear stall at first run */
- usb2_transfer_set_stall(sc->sc_xfer[UPLCOM_BULK_DT_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[UPLCOM_BULK_DT_RD]);
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &uplcom_callback, &Giant);
- if (error) {
- goto detach;
- }
- /*
- * do the initialization during attach so that the system does not
- * sleep during open:
- */
- if (sc->sc_chiptype == TYPE_PL2303X) {
- if (uplcom_pl2303x_init(uaa->device)) {
- device_printf(dev, "init failed!\n");
- goto detach;
- }
- }
- return (0);
-
-detach:
- uplcom_detach(dev);
- return (ENXIO);
-}
-
-static int
-uplcom_detach(device_t dev)
-{
- struct uplcom_softc *sc = device_get_softc(dev);
-
- DPRINTF("sc=%p\n", sc);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UPLCOM_N_TRANSFER);
-
- return (0);
-}
-
-static usb2_error_t
-uplcom_reset(struct uplcom_softc *sc, struct usb2_device *udev)
-{
- struct usb2_device_request req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UPLCOM_SET_REQUEST;
- USETW(req.wValue, 0);
- req.wIndex[0] = sc->sc_data_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- return (usb2_do_request(udev, &Giant, &req, NULL));
-}
-
-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, 1},
- {UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x0404, 0, 0},
- {UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8484, 0, 1},
- {UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8383, 0, 1},
- {UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8484, 0, 1},
- {UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x0404, 1, 0},
- {UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8484, 0, 1},
- {UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8383, 0, 1},
- {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},
- {UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 8, 0, 0},
- {UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 9, 0, 0},
-};
-
-#define N_PL2302X_INIT (sizeof(pl2303x)/sizeof(pl2303x[0]))
-
-static int
-uplcom_pl2303x_init(struct usb2_device *udev)
-{
- struct usb2_device_request req;
- usb2_error_t err;
- uint8_t buf[4];
- uint8_t 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 = usb2_do_request(udev, &Giant, &req, buf);
- if (err) {
- DPRINTF("error=%s\n", usb2_errstr(err));
- return (EIO);
- }
- }
- return (0);
-}
-
-static void
-uplcom_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uplcom_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
-
- DPRINTF("onoff = %d\n", onoff);
-
- if (onoff)
- sc->sc_line |= UCDC_LINE_DTR;
- else
- sc->sc_line &= ~UCDC_LINE_DTR;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, sc->sc_line);
- req.wIndex[0] = sc->sc_data_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-uplcom_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uplcom_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
-
- DPRINTF("onoff = %d\n", onoff);
-
- if (onoff)
- sc->sc_line |= UCDC_LINE_RTS;
- else
- sc->sc_line &= ~UCDC_LINE_RTS;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, sc->sc_line);
- req.wIndex[0] = sc->sc_data_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static void
-uplcom_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uplcom_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
- uint16_t temp;
-
- DPRINTF("onoff = %d\n", onoff);
-
- temp = (onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF);
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
- USETW(req.wValue, temp);
- req.wIndex[0] = sc->sc_data_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
-}
-
-static const int32_t 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_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- uint8_t i;
-
- DPRINTF("\n");
-
- /* check requested baud rate */
-
- for (i = 0;; i++) {
-
- if (i != N_UPLCOM_RATES) {
- if (uplcom_rates[i] == t->c_ospeed) {
- break;
- }
- } else {
- DPRINTF("invalid baud rate (%d)\n", t->c_ospeed);
- return (EIO);
- }
- }
-
- return (0);
-}
-
-static void
-uplcom_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct uplcom_softc *sc = ucom->sc_parent;
- struct usb2_cdc_line_state ls;
- struct usb2_device_request req;
-
- DPRINTF("sc = %p\n", sc);
-
- bzero(&ls, sizeof(ls));
-
- USETDW(ls.dwDTERate, t->c_ospeed);
-
- if (t->c_cflag & CSTOPB) {
- ls.bCharFormat = UCDC_STOP_BIT_2;
- } else {
- ls.bCharFormat = UCDC_STOP_BIT_1;
- }
-
- if (t->c_cflag & PARENB) {
- if (t->c_cflag & PARODD) {
- ls.bParityType = UCDC_PARITY_ODD;
- } else {
- ls.bParityType = UCDC_PARITY_EVEN;
- }
- } else {
- ls.bParityType = UCDC_PARITY_NONE;
- }
-
- switch (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;
- }
-
- DPRINTF("rate=%d fmt=%d parity=%d bits=%d\n",
- UGETDW(ls.dwDTERate), ls.bCharFormat,
- ls.bParityType, ls.bDataBits);
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_LINE_CODING;
- USETW(req.wValue, 0);
- req.wIndex[0] = sc->sc_data_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, UCDC_LINE_STATE_LENGTH);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, &ls, 0, 1000);
-
- if (t->c_cflag & CRTSCTS) {
-
- DPRINTF("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);
-
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
- } else {
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UPLCOM_SET_REQUEST;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
- }
-}
-
-static void
-uplcom_start_read(struct usb2_com_softc *ucom)
-{
- struct uplcom_softc *sc = ucom->sc_parent;
-
- /* start interrupt endpoint */
- usb2_transfer_start(sc->sc_xfer[UPLCOM_INTR_DT_RD]);
-
- /* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_DT_RD]);
-}
-
-static void
-uplcom_stop_read(struct usb2_com_softc *ucom)
-{
- struct uplcom_softc *sc = ucom->sc_parent;
-
- /* stop interrupt endpoint */
- usb2_transfer_stop(sc->sc_xfer[UPLCOM_INTR_DT_RD]);
-
- /* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_DT_RD]);
-}
-
-static void
-uplcom_start_write(struct usb2_com_softc *ucom)
-{
- struct uplcom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_DT_WR]);
-}
-
-static void
-uplcom_stop_write(struct usb2_com_softc *ucom)
-{
- struct uplcom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_DT_WR]);
-}
-
-static void
-uplcom_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
- struct uplcom_softc *sc = ucom->sc_parent;
-
- DPRINTF("\n");
-
- *lsr = sc->sc_lsr;
- *msr = sc->sc_msr;
-}
-
-static void
-uplcom_intr_callback(struct usb2_xfer *xfer)
-{
- struct uplcom_softc *sc = xfer->priv_sc;
- uint8_t buf[9];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- DPRINTF("actlen = %u\n", xfer->actlen);
-
- if (xfer->actlen >= 9) {
-
- usb2_copy_out(xfer->frbuffers, 0, buf, sizeof(buf));
-
- DPRINTF("status = 0x%02x\n", buf[8]);
-
- sc->sc_lsr = 0;
- sc->sc_msr = 0;
-
- if (buf[8] & RSAQ_STATUS_CTS) {
- sc->sc_msr |= SER_CTS;
- }
- if (buf[8] & RSAQ_STATUS_DSR) {
- sc->sc_msr |= SER_DSR;
- }
- if (buf[8] & RSAQ_STATUS_DCD) {
- sc->sc_msr |= SER_DCD;
- }
- usb2_com_status_change(&sc->sc_ucom);
- }
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uplcom_write_callback(struct usb2_xfer *xfer)
-{
- struct uplcom_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- UPLCOM_BULK_BUF_SIZE, &actlen)) {
-
- DPRINTF("actlen = %d\n", actlen);
-
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uplcom_read_callback(struct usb2_xfer *xfer)
-{
- struct uplcom_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
diff --git a/sys/dev/usb2/serial/usb2_serial.c b/sys/dev/usb2/serial/usb2_serial.c
deleted file mode 100644
index 1036550..0000000
--- a/sys/dev/usb2/serial/usb2_serial.c
+++ /dev/null
@@ -1,1127 +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 <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-
-#define USB_DEBUG_VAR usb2_com_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#if USB_DEBUG
-static int usb2_com_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom");
-SYSCTL_INT(_hw_usb2_ucom, OID_AUTO, debug, CTLFLAG_RW,
- &usb2_com_debug, 0, "ucom debug level");
-#endif
-
-static usb2_proc_callback_t usb2_com_cfg_start_transfers;
-static usb2_proc_callback_t usb2_com_cfg_open;
-static usb2_proc_callback_t usb2_com_cfg_close;
-static usb2_proc_callback_t usb2_com_cfg_line_state;
-static usb2_proc_callback_t usb2_com_cfg_status_change;
-static usb2_proc_callback_t usb2_com_cfg_param;
-
-static uint8_t usb2_com_units_alloc(uint32_t, uint32_t *);
-static void usb2_com_units_free(uint32_t, uint32_t);
-static int usb2_com_attach_tty(struct usb2_com_softc *, uint32_t);
-static void usb2_com_detach_tty(struct usb2_com_softc *);
-static void usb2_com_queue_command(struct usb2_com_softc *,
- usb2_proc_callback_t *, struct termios *pt,
- struct usb2_proc_msg *t0, struct usb2_proc_msg *t1);
-static void usb2_com_shutdown(struct usb2_com_softc *);
-static void usb2_com_break(struct usb2_com_softc *, uint8_t);
-static void usb2_com_dtr(struct usb2_com_softc *, uint8_t);
-static void usb2_com_rts(struct usb2_com_softc *, uint8_t);
-
-static tsw_open_t usb2_com_open;
-static tsw_close_t usb2_com_close;
-static tsw_ioctl_t usb2_com_ioctl;
-static tsw_modem_t usb2_com_modem;
-static tsw_param_t usb2_com_param;
-static tsw_outwakeup_t usb2_com_outwakeup;
-static tsw_free_t usb2_com_free;
-
-static struct ttydevsw usb2_com_class = {
- .tsw_flags = TF_INITLOCK | TF_CALLOUT,
- .tsw_open = usb2_com_open,
- .tsw_close = usb2_com_close,
- .tsw_outwakeup = usb2_com_outwakeup,
- .tsw_ioctl = usb2_com_ioctl,
- .tsw_param = usb2_com_param,
- .tsw_modem = usb2_com_modem,
- .tsw_free = usb2_com_free,
-};
-
-MODULE_DEPEND(usb2_serial, usb2_core, 1, 1, 1);
-MODULE_VERSION(usb2_serial, 1);
-
-#define UCOM_UNIT_MAX 0x1000 /* exclusive */
-#define UCOM_SUB_UNIT_MAX 0x100 /* exclusive */
-
-static uint8_t usb2_com_bitmap[(UCOM_UNIT_MAX + 7) / 8];
-
-static uint8_t
-usb2_com_units_alloc(uint32_t sub_units, uint32_t *p_root_unit)
-{
- uint32_t n;
- uint32_t o;
- uint32_t x;
- uint32_t max = UCOM_UNIT_MAX - (UCOM_UNIT_MAX % sub_units);
- uint8_t error = 1;
-
- mtx_lock(&Giant);
-
- for (n = 0; n < max; n += sub_units) {
-
- /* check for free consecutive bits */
-
- for (o = 0; o < sub_units; o++) {
-
- x = n + o;
-
- if (usb2_com_bitmap[x / 8] & (1 << (x % 8))) {
- goto skip;
- }
- }
-
- /* allocate */
-
- for (o = 0; o < sub_units; o++) {
-
- x = n + o;
-
- usb2_com_bitmap[x / 8] |= (1 << (x % 8));
- }
-
- error = 0;
-
- break;
-
-skip: ;
- }
-
- mtx_unlock(&Giant);
-
- /*
- * Always set the variable pointed to by "p_root_unit" so that
- * the compiler does not think that it is used uninitialised:
- */
- *p_root_unit = n;
-
- return (error);
-}
-
-static void
-usb2_com_units_free(uint32_t root_unit, uint32_t sub_units)
-{
- uint32_t x;
-
- mtx_lock(&Giant);
-
- while (sub_units--) {
- x = root_unit + sub_units;
- usb2_com_bitmap[x / 8] &= ~(1 << (x % 8));
- }
-
- mtx_unlock(&Giant);
-}
-
-/*
- * "N" sub_units are setup at a time. All sub-units will
- * be given sequential unit numbers. The number of
- * sub-units can be used to differentiate among
- * different types of devices.
- *
- * The mutex pointed to by "mtx" is applied before all
- * callbacks are called back. Also "mtx" must be applied
- * before calling into the ucom-layer!
- */
-int
-usb2_com_attach(struct usb2_com_super_softc *ssc, struct usb2_com_softc *sc,
- uint32_t sub_units, void *parent,
- const struct usb2_com_callback *callback, struct mtx *mtx)
-{
- uint32_t n;
- uint32_t root_unit;
- int error = 0;
-
- if ((sc == NULL) ||
- (sub_units == 0) ||
- (sub_units > UCOM_SUB_UNIT_MAX) ||
- (callback == NULL)) {
- return (EINVAL);
- }
-
- /* XXX unit management does not really belong here */
- if (usb2_com_units_alloc(sub_units, &root_unit)) {
- return (ENOMEM);
- }
-
- error = usb2_proc_create(&ssc->sc_tq, mtx, "ucom", USB_PRI_MED);
- if (error) {
- usb2_com_units_free(root_unit, sub_units);
- return (error);
- }
-
- for (n = 0; n != sub_units; n++, sc++) {
- sc->sc_unit = root_unit + n;
- sc->sc_local_unit = n;
- sc->sc_super = ssc;
- sc->sc_mtx = mtx;
- sc->sc_parent = parent;
- sc->sc_callback = callback;
-
- error = usb2_com_attach_tty(sc, sub_units);
- if (error) {
- usb2_com_detach(ssc, sc - n, n);
- usb2_com_units_free(root_unit + n, sub_units - n);
- return (error);
- }
- sc->sc_flag |= UCOM_FLAG_ATTACHED;
- }
- return (0);
-}
-
-/*
- * NOTE: the following function will do nothing if
- * the structure pointed to by "ssc" and "sc" is zero.
- */
-void
-usb2_com_detach(struct usb2_com_super_softc *ssc, struct usb2_com_softc *sc,
- uint32_t sub_units)
-{
- uint32_t n;
-
- usb2_proc_drain(&ssc->sc_tq);
-
- for (n = 0; n != sub_units; n++, sc++) {
- if (sc->sc_flag & UCOM_FLAG_ATTACHED) {
-
- usb2_com_detach_tty(sc);
-
- usb2_com_units_free(sc->sc_unit, 1);
-
- /* avoid duplicate detach: */
- sc->sc_flag &= ~UCOM_FLAG_ATTACHED;
- }
- }
- usb2_proc_free(&ssc->sc_tq);
-}
-
-static int
-usb2_com_attach_tty(struct usb2_com_softc *sc, uint32_t sub_units)
-{
- struct tty *tp;
- int error = 0;
- char buf[32]; /* temporary TTY device name buffer */
-
- tp = tty_alloc(&usb2_com_class, sc, sc->sc_mtx);
- if (tp == NULL) {
- error = ENOMEM;
- goto done;
- }
- DPRINTF("tp = %p, unit = %d\n", tp, sc->sc_unit);
-
- buf[0] = 0; /* set some default value */
-
- /* Check if the client has a custom TTY name */
- if (sc->sc_callback->usb2_com_tty_name) {
- sc->sc_callback->usb2_com_tty_name(sc, buf,
- sizeof(buf), sc->sc_local_unit);
- }
- if (buf[0] == 0) {
- /* Use default TTY name */
- if (sub_units > 1) {
- /* multiple modems in one */
- if (snprintf(buf, sizeof(buf), "U%u.%u",
- sc->sc_unit - sc->sc_local_unit,
- sc->sc_local_unit)) {
- /* ignore */
- }
- } else {
- /* single modem */
- if (snprintf(buf, sizeof(buf), "U%u", sc->sc_unit)) {
- /* ignore */
- }
- }
- }
- tty_makedev(tp, NULL, "%s", buf);
-
- sc->sc_tty = tp;
-
- DPRINTF("ttycreate: %s\n", buf);
- usb2_cv_init(&sc->sc_cv, "usb2_com");
-
-done:
- return (error);
-}
-
-static void
-usb2_com_detach_tty(struct usb2_com_softc *sc)
-{
- struct tty *tp = sc->sc_tty;
-
- DPRINTF("sc = %p, tp = %p\n", sc, sc->sc_tty);
-
- /* the config thread has been stopped when we get here */
-
- mtx_lock(sc->sc_mtx);
- sc->sc_flag |= UCOM_FLAG_GONE;
- sc->sc_flag &= ~(UCOM_FLAG_HL_READY |
- UCOM_FLAG_LL_READY);
- mtx_unlock(sc->sc_mtx);
- if (tp) {
- tty_lock(tp);
-
- usb2_com_close(tp); /* close, if any */
-
- tty_rel_gone(tp);
-
- mtx_lock(sc->sc_mtx);
- /* Wait for the callback after the TTY is torn down */
- while (sc->sc_ttyfreed == 0)
- usb2_cv_wait(&sc->sc_cv, sc->sc_mtx);
- /*
- * make sure that read and write transfers are stopped
- */
- if (sc->sc_callback->usb2_com_stop_read) {
- (sc->sc_callback->usb2_com_stop_read) (sc);
- }
- if (sc->sc_callback->usb2_com_stop_write) {
- (sc->sc_callback->usb2_com_stop_write) (sc);
- }
- mtx_unlock(sc->sc_mtx);
- }
- usb2_cv_destroy(&sc->sc_cv);
-}
-
-static void
-usb2_com_queue_command(struct usb2_com_softc *sc,
- usb2_proc_callback_t *fn, struct termios *pt,
- struct usb2_proc_msg *t0, struct usb2_proc_msg *t1)
-{
- struct usb2_com_super_softc *ssc = sc->sc_super;
- struct usb2_com_param_task *task;
-
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- if (usb2_proc_is_gone(&ssc->sc_tq)) {
- DPRINTF("proc is gone\n");
- return; /* nothing to do */
- }
- /*
- * NOTE: The task cannot get executed before we drop the
- * "sc_mtx" mutex. It is safe to update fields in the message
- * structure after that the message got queued.
- */
- task = (struct usb2_com_param_task *)
- usb2_proc_msignal(&ssc->sc_tq, t0, t1);
-
- /* Setup callback and softc pointers */
- task->hdr.pm_callback = fn;
- task->sc = sc;
-
- /*
- * Make a copy of the termios. This field is only present if
- * the "pt" field is not NULL.
- */
- if (pt != NULL)
- task->termios_copy = *pt;
-
- /*
- * Closing the device should be synchronous.
- */
- if (fn == usb2_com_cfg_close)
- usb2_proc_mwait(&ssc->sc_tq, t0, t1);
-
-}
-
-static void
-usb2_com_shutdown(struct usb2_com_softc *sc)
-{
- struct tty *tp = sc->sc_tty;
-
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- DPRINTF("\n");
-
- /*
- * Hang up if necessary:
- */
- if (tp->t_termios.c_cflag & HUPCL) {
- usb2_com_modem(tp, 0, SER_DTR);
- }
-}
-
-/*
- * Return values:
- * 0: normal
- * else: taskqueue is draining or gone
- */
-uint8_t
-usb2_com_cfg_is_gone(struct usb2_com_softc *sc)
-{
- struct usb2_com_super_softc *ssc = sc->sc_super;
-
- return (usb2_proc_is_gone(&ssc->sc_tq));
-}
-
-static void
-usb2_com_cfg_start_transfers(struct usb2_proc_msg *_task)
-{
- struct usb2_com_cfg_task *task =
- (struct usb2_com_cfg_task *)_task;
- struct usb2_com_softc *sc = task->sc;
-
- if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
- return;
- }
- if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
- /* TTY device closed */
- return;
- }
- sc->sc_flag |= UCOM_FLAG_GP_DATA;
-
- if (sc->sc_callback->usb2_com_start_read) {
- (sc->sc_callback->usb2_com_start_read) (sc);
- }
- if (sc->sc_callback->usb2_com_start_write) {
- (sc->sc_callback->usb2_com_start_write) (sc);
- }
-}
-
-static void
-usb2_com_start_transfers(struct usb2_com_softc *sc)
-{
- if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
- return;
- }
- /*
- * Make sure that data transfers are started in both
- * directions:
- */
- if (sc->sc_callback->usb2_com_start_read) {
- (sc->sc_callback->usb2_com_start_read) (sc);
- }
- if (sc->sc_callback->usb2_com_start_write) {
- (sc->sc_callback->usb2_com_start_write) (sc);
- }
-}
-
-static void
-usb2_com_cfg_open(struct usb2_proc_msg *_task)
-{
- struct usb2_com_cfg_task *task =
- (struct usb2_com_cfg_task *)_task;
- struct usb2_com_softc *sc = task->sc;
-
- DPRINTF("\n");
-
- if (sc->sc_flag & UCOM_FLAG_LL_READY) {
-
- /* already opened */
-
- } else {
-
- sc->sc_flag |= UCOM_FLAG_LL_READY;
-
- if (sc->sc_callback->usb2_com_cfg_open) {
- (sc->sc_callback->usb2_com_cfg_open) (sc);
-
- /* wait a little */
- usb2_pause_mtx(sc->sc_mtx, hz / 10);
- }
- }
-}
-
-static int
-usb2_com_open(struct tty *tp)
-{
- struct usb2_com_softc *sc = tty_softc(tp);
- int error;
-
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- if (sc->sc_flag & UCOM_FLAG_GONE) {
- return (ENXIO);
- }
- if (sc->sc_flag & UCOM_FLAG_HL_READY) {
- /* already opened */
- return (0);
- }
- DPRINTF("tp = %p\n", tp);
-
- if (sc->sc_callback->usb2_com_pre_open) {
- /*
- * give the lower layer a chance to disallow TTY open, for
- * example if the device is not present:
- */
- error = (sc->sc_callback->usb2_com_pre_open) (sc);
- if (error) {
- return (error);
- }
- }
- sc->sc_flag |= UCOM_FLAG_HL_READY;
-
- /* Disable transfers */
- sc->sc_flag &= ~UCOM_FLAG_GP_DATA;
-
- sc->sc_lsr = 0;
- sc->sc_msr = 0;
- sc->sc_mcr = 0;
-
- /* reset programmed line state */
- sc->sc_pls_curr = 0;
- sc->sc_pls_set = 0;
- sc->sc_pls_clr = 0;
-
- usb2_com_queue_command(sc, usb2_com_cfg_open, NULL,
- &sc->sc_open_task[0].hdr,
- &sc->sc_open_task[1].hdr);
-
- /* Queue transfer enable command last */
- usb2_com_queue_command(sc, usb2_com_cfg_start_transfers, NULL,
- &sc->sc_start_task[0].hdr,
- &sc->sc_start_task[1].hdr);
-
- usb2_com_modem(tp, SER_DTR | SER_RTS, 0);
-
- usb2_com_break(sc, 0);
-
- usb2_com_status_change(sc);
-
- return (0);
-}
-
-static void
-usb2_com_cfg_close(struct usb2_proc_msg *_task)
-{
- struct usb2_com_cfg_task *task =
- (struct usb2_com_cfg_task *)_task;
- struct usb2_com_softc *sc = task->sc;
-
- DPRINTF("\n");
-
- if (sc->sc_flag & UCOM_FLAG_LL_READY) {
-
- sc->sc_flag &= ~(UCOM_FLAG_LL_READY |
- UCOM_FLAG_GP_DATA);
-
- if (sc->sc_callback->usb2_com_cfg_close) {
- (sc->sc_callback->usb2_com_cfg_close) (sc);
- }
- } else {
- /* already closed */
- }
-}
-
-static void
-usb2_com_close(struct tty *tp)
-{
- struct usb2_com_softc *sc = tty_softc(tp);
-
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- DPRINTF("tp=%p\n", tp);
-
- if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
- DPRINTF("tp=%p already closed\n", tp);
- return;
- }
- usb2_com_shutdown(sc);
-
- usb2_com_queue_command(sc, usb2_com_cfg_close, NULL,
- &sc->sc_close_task[0].hdr,
- &sc->sc_close_task[1].hdr);
-
- sc->sc_flag &= ~(UCOM_FLAG_HL_READY |
- UCOM_FLAG_WR_START |
- UCOM_FLAG_RTS_IFLOW);
-
- if (sc->sc_callback->usb2_com_stop_read) {
- (sc->sc_callback->usb2_com_stop_read) (sc);
- }
- if (sc->sc_callback->usb2_com_stop_write) {
- (sc->sc_callback->usb2_com_stop_write) (sc);
- }
-}
-
-static int
-usb2_com_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
-{
- struct usb2_com_softc *sc = tty_softc(tp);
- int error;
-
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
- return (EIO);
- }
- DPRINTF("cmd = 0x%08lx\n", cmd);
-
- switch (cmd) {
- case TIOCSBRK:
- usb2_com_break(sc, 1);
- error = 0;
- break;
- case TIOCCBRK:
- usb2_com_break(sc, 0);
- error = 0;
- break;
- default:
- if (sc->sc_callback->usb2_com_ioctl) {
- error = (sc->sc_callback->usb2_com_ioctl)
- (sc, cmd, data, 0, td);
- } else {
- error = ENOIOCTL;
- }
- break;
- }
- return (error);
-}
-
-static int
-usb2_com_modem(struct tty *tp, int sigon, int sigoff)
-{
- struct usb2_com_softc *sc = tty_softc(tp);
- uint8_t onoff;
-
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
- return (0);
- }
- if ((sigon == 0) && (sigoff == 0)) {
-
- if (sc->sc_mcr & SER_DTR) {
- sigon |= SER_DTR;
- }
- if (sc->sc_mcr & SER_RTS) {
- sigon |= SER_RTS;
- }
- if (sc->sc_msr & SER_CTS) {
- sigon |= SER_CTS;
- }
- if (sc->sc_msr & SER_DCD) {
- sigon |= SER_DCD;
- }
- if (sc->sc_msr & SER_DSR) {
- sigon |= SER_DSR;
- }
- if (sc->sc_msr & SER_RI) {
- sigon |= SER_RI;
- }
- return (sigon);
- }
- if (sigon & SER_DTR) {
- sc->sc_mcr |= SER_DTR;
- }
- if (sigoff & SER_DTR) {
- sc->sc_mcr &= ~SER_DTR;
- }
- if (sigon & SER_RTS) {
- sc->sc_mcr |= SER_RTS;
- }
- if (sigoff & SER_RTS) {
- sc->sc_mcr &= ~SER_RTS;
- }
- onoff = (sc->sc_mcr & SER_DTR) ? 1 : 0;
- usb2_com_dtr(sc, onoff);
-
- onoff = (sc->sc_mcr & SER_RTS) ? 1 : 0;
- usb2_com_rts(sc, onoff);
-
- return (0);
-}
-
-static void
-usb2_com_cfg_line_state(struct usb2_proc_msg *_task)
-{
- struct usb2_com_cfg_task *task =
- (struct usb2_com_cfg_task *)_task;
- struct usb2_com_softc *sc = task->sc;
- uint8_t notch_bits;
- uint8_t any_bits;
- uint8_t prev_value;
- uint8_t last_value;
- uint8_t mask;
-
- if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
- return;
- }
-
- mask = 0;
- /* compute callback mask */
- if (sc->sc_callback->usb2_com_cfg_set_dtr)
- mask |= UCOM_LS_DTR;
- if (sc->sc_callback->usb2_com_cfg_set_rts)
- mask |= UCOM_LS_RTS;
- if (sc->sc_callback->usb2_com_cfg_set_break)
- mask |= UCOM_LS_BREAK;
-
- /* compute the bits we are to program */
- notch_bits = (sc->sc_pls_set & sc->sc_pls_clr) & mask;
- any_bits = (sc->sc_pls_set | sc->sc_pls_clr) & mask;
- prev_value = sc->sc_pls_curr ^ notch_bits;
- last_value = sc->sc_pls_curr;
-
- /* reset programmed line state */
- sc->sc_pls_curr = 0;
- sc->sc_pls_set = 0;
- sc->sc_pls_clr = 0;
-
- /* ensure that we don't loose any levels */
- if (notch_bits & UCOM_LS_DTR)
- sc->sc_callback->usb2_com_cfg_set_dtr(sc,
- (prev_value & UCOM_LS_DTR) ? 1 : 0);
- if (notch_bits & UCOM_LS_RTS)
- sc->sc_callback->usb2_com_cfg_set_rts(sc,
- (prev_value & UCOM_LS_RTS) ? 1 : 0);
- if (notch_bits & UCOM_LS_BREAK)
- sc->sc_callback->usb2_com_cfg_set_break(sc,
- (prev_value & UCOM_LS_BREAK) ? 1 : 0);
-
- /* set last value */
- if (any_bits & UCOM_LS_DTR)
- sc->sc_callback->usb2_com_cfg_set_dtr(sc,
- (last_value & UCOM_LS_DTR) ? 1 : 0);
- if (any_bits & UCOM_LS_RTS)
- sc->sc_callback->usb2_com_cfg_set_rts(sc,
- (last_value & UCOM_LS_RTS) ? 1 : 0);
- if (any_bits & UCOM_LS_BREAK)
- sc->sc_callback->usb2_com_cfg_set_break(sc,
- (last_value & UCOM_LS_BREAK) ? 1 : 0);
-}
-
-static void
-usb2_com_line_state(struct usb2_com_softc *sc,
- uint8_t set_bits, uint8_t clear_bits)
-{
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
- return;
- }
-
- DPRINTF("on=0x%02x, off=0x%02x\n", set_bits, clear_bits);
-
- /* update current programmed line state */
- sc->sc_pls_curr |= set_bits;
- sc->sc_pls_curr &= ~clear_bits;
- sc->sc_pls_set |= set_bits;
- sc->sc_pls_clr |= clear_bits;
-
- /* defer driver programming */
- usb2_com_queue_command(sc, usb2_com_cfg_line_state, NULL,
- &sc->sc_line_state_task[0].hdr,
- &sc->sc_line_state_task[1].hdr);
-}
-
-static void
-usb2_com_break(struct usb2_com_softc *sc, uint8_t onoff)
-{
- DPRINTF("onoff = %d\n", onoff);
-
- if (onoff)
- usb2_com_line_state(sc, UCOM_LS_BREAK, 0);
- else
- usb2_com_line_state(sc, 0, UCOM_LS_BREAK);
-}
-
-static void
-usb2_com_dtr(struct usb2_com_softc *sc, uint8_t onoff)
-{
- DPRINTF("onoff = %d\n", onoff);
-
- if (onoff)
- usb2_com_line_state(sc, UCOM_LS_DTR, 0);
- else
- usb2_com_line_state(sc, 0, UCOM_LS_DTR);
-}
-
-static void
-usb2_com_rts(struct usb2_com_softc *sc, uint8_t onoff)
-{
- DPRINTF("onoff = %d\n", onoff);
-
- if (onoff)
- usb2_com_line_state(sc, UCOM_LS_RTS, 0);
- else
- usb2_com_line_state(sc, 0, UCOM_LS_RTS);
-}
-
-static void
-usb2_com_cfg_status_change(struct usb2_proc_msg *_task)
-{
- struct usb2_com_cfg_task *task =
- (struct usb2_com_cfg_task *)_task;
- struct usb2_com_softc *sc = task->sc;
- struct tty *tp;
- uint8_t new_msr;
- uint8_t new_lsr;
- uint8_t onoff;
-
- tp = sc->sc_tty;
-
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
- return;
- }
- if (sc->sc_callback->usb2_com_cfg_get_status == NULL) {
- return;
- }
- /* get status */
-
- new_msr = 0;
- new_lsr = 0;
-
- (sc->sc_callback->usb2_com_cfg_get_status) (sc, &new_lsr, &new_msr);
-
- if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
- /* TTY device closed */
- return;
- }
- onoff = ((sc->sc_msr ^ new_msr) & SER_DCD);
-
- sc->sc_msr = new_msr;
- sc->sc_lsr = new_lsr;
-
- if (onoff) {
-
- onoff = (sc->sc_msr & SER_DCD) ? 1 : 0;
-
- DPRINTF("DCD changed to %d\n", onoff);
-
- ttydisc_modem(tp, onoff);
- }
-}
-
-void
-usb2_com_status_change(struct usb2_com_softc *sc)
-{
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
- return;
- }
- DPRINTF("\n");
-
- usb2_com_queue_command(sc, usb2_com_cfg_status_change, NULL,
- &sc->sc_status_task[0].hdr,
- &sc->sc_status_task[1].hdr);
-}
-
-static void
-usb2_com_cfg_param(struct usb2_proc_msg *_task)
-{
- struct usb2_com_param_task *task =
- (struct usb2_com_param_task *)_task;
- struct usb2_com_softc *sc = task->sc;
-
- if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
- return;
- }
- if (sc->sc_callback->usb2_com_cfg_param == NULL) {
- return;
- }
-
- (sc->sc_callback->usb2_com_cfg_param) (sc, &task->termios_copy);
-
- /* wait a little */
- usb2_pause_mtx(sc->sc_mtx, hz / 10);
-}
-
-static int
-usb2_com_param(struct tty *tp, struct termios *t)
-{
- struct usb2_com_softc *sc = tty_softc(tp);
- uint8_t opened;
- int error;
-
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- opened = 0;
- error = 0;
-
- if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
-
- /* XXX the TTY layer should call "open()" first! */
-
- error = usb2_com_open(tp);
- if (error) {
- goto done;
- }
- opened = 1;
- }
- DPRINTF("sc = %p\n", sc);
-
- /* Check requested parameters. */
- if (t->c_ospeed < 0) {
- DPRINTF("negative ospeed\n");
- error = EINVAL;
- goto done;
- }
- if (t->c_ispeed && (t->c_ispeed != t->c_ospeed)) {
- DPRINTF("mismatch ispeed and ospeed\n");
- error = EINVAL;
- goto done;
- }
- t->c_ispeed = t->c_ospeed;
-
- if (sc->sc_callback->usb2_com_pre_param) {
- /* Let the lower layer verify the parameters */
- error = (sc->sc_callback->usb2_com_pre_param) (sc, t);
- if (error) {
- DPRINTF("callback error = %d\n", error);
- goto done;
- }
- }
-
- /* Disable transfers */
- sc->sc_flag &= ~UCOM_FLAG_GP_DATA;
-
- /* Queue baud rate programming command first */
- usb2_com_queue_command(sc, usb2_com_cfg_param, t,
- &sc->sc_param_task[0].hdr,
- &sc->sc_param_task[1].hdr);
-
- /* Queue transfer enable command last */
- usb2_com_queue_command(sc, usb2_com_cfg_start_transfers, NULL,
- &sc->sc_start_task[0].hdr,
- &sc->sc_start_task[1].hdr);
-
- if (t->c_cflag & CRTS_IFLOW) {
- sc->sc_flag |= UCOM_FLAG_RTS_IFLOW;
- } else if (sc->sc_flag & UCOM_FLAG_RTS_IFLOW) {
- sc->sc_flag &= ~UCOM_FLAG_RTS_IFLOW;
- usb2_com_modem(tp, SER_RTS, 0);
- }
-done:
- if (error) {
- if (opened) {
- usb2_com_close(tp);
- }
- }
- return (error);
-}
-
-static void
-usb2_com_outwakeup(struct tty *tp)
-{
- struct usb2_com_softc *sc = tty_softc(tp);
-
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- DPRINTF("sc = %p\n", sc);
-
- if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
- /* The higher layer is not ready */
- return;
- }
- sc->sc_flag |= UCOM_FLAG_WR_START;
-
- usb2_com_start_transfers(sc);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_com_get_data
- *
- * Return values:
- * 0: No data is available.
- * Else: Data is available.
- *------------------------------------------------------------------------*/
-uint8_t
-usb2_com_get_data(struct usb2_com_softc *sc, struct usb2_page_cache *pc,
- uint32_t offset, uint32_t len, uint32_t *actlen)
-{
- struct usb2_page_search res;
- struct tty *tp = sc->sc_tty;
- uint32_t cnt;
- uint32_t offset_orig;
-
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- if ((!(sc->sc_flag & UCOM_FLAG_HL_READY)) ||
- (!(sc->sc_flag & UCOM_FLAG_GP_DATA)) ||
- (!(sc->sc_flag & UCOM_FLAG_WR_START))) {
- actlen[0] = 0;
- return (0); /* multiport device polling */
- }
- offset_orig = offset;
-
- while (len != 0) {
-
- usb2_get_page(pc, offset, &res);
-
- if (res.length > len) {
- res.length = len;
- }
- /* copy data directly into USB buffer */
- cnt = ttydisc_getc(tp, res.buffer, res.length);
-
- offset += cnt;
- len -= cnt;
-
- if (cnt < res.length) {
- /* end of buffer */
- break;
- }
- }
-
- actlen[0] = offset - offset_orig;
-
- DPRINTF("cnt=%d\n", actlen[0]);
-
- if (actlen[0] == 0) {
- return (0);
- }
- return (1);
-}
-
-void
-usb2_com_put_data(struct usb2_com_softc *sc, struct usb2_page_cache *pc,
- uint32_t offset, uint32_t len)
-{
- struct usb2_page_search res;
- struct tty *tp = sc->sc_tty;
- char *buf;
- uint32_t cnt;
-
- mtx_assert(sc->sc_mtx, MA_OWNED);
-
- if ((!(sc->sc_flag & UCOM_FLAG_HL_READY)) ||
- (!(sc->sc_flag & UCOM_FLAG_GP_DATA))) {
- return; /* multiport device polling */
- }
- if (len == 0)
- return; /* no data */
-
- /* set a flag to prevent recursation ? */
-
- while (len > 0) {
-
- usb2_get_page(pc, offset, &res);
-
- if (res.length > len) {
- res.length = len;
- }
- len -= res.length;
- offset += res.length;
-
- /* pass characters to tty layer */
-
- buf = res.buffer;
- cnt = res.length;
-
- /* first check if we can pass the buffer directly */
-
- if (ttydisc_can_bypass(tp)) {
- if (ttydisc_rint_bypass(tp, buf, cnt) != cnt) {
- DPRINTF("tp=%p, data lost\n", tp);
- }
- continue;
- }
- /* need to loop */
-
- for (cnt = 0; cnt != res.length; cnt++) {
- if (ttydisc_rint(tp, buf[cnt], 0) == -1) {
- /* XXX what should we do? */
-
- DPRINTF("tp=%p, lost %d "
- "chars\n", tp, res.length - cnt);
- break;
- }
- }
- }
- ttydisc_rint_done(tp);
-}
-
-static void
-usb2_com_free(void *xsc)
-{
- struct usb2_com_softc *sc = xsc;
-
- mtx_lock(sc->sc_mtx);
- sc->sc_ttyfreed = 1;
- usb2_cv_signal(&sc->sc_cv);
- mtx_unlock(sc->sc_mtx);
-}
diff --git a/sys/dev/usb2/serial/usb2_serial.h b/sys/dev/usb2/serial/usb2_serial.h
deleted file mode 100644
index c7d57a0..0000000
--- a/sys/dev/usb2/serial/usb2_serial.h
+++ /dev/null
@@ -1,198 +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.
- */
-
-#ifndef _USB2_SERIAL_H_
-#define _USB2_SERIAL_H_
-
-#include <sys/tty.h>
-#include <sys/serial.h>
-#include <sys/fcntl.h>
-#include <sys/termios.h>
-
-/* Module interface related macros */
-#define UCOM_MODVER 1
-
-#define UCOM_MINVER 1
-#define UCOM_PREFVER UCOM_MODVER
-#define UCOM_MAXVER 1
-
-struct usb2_device;
-struct usb2_com_softc;
-struct usb2_device_request;
-struct thread;
-
-/*
- * NOTE: There is no guarantee that "usb2_com_cfg_close()" will
- * be called after "usb2_com_cfg_open()" if the device is detached
- * while it is open!
- */
-struct usb2_com_callback {
- void (*usb2_com_cfg_get_status) (struct usb2_com_softc *, uint8_t *plsr, uint8_t *pmsr);
- void (*usb2_com_cfg_set_dtr) (struct usb2_com_softc *, uint8_t);
- void (*usb2_com_cfg_set_rts) (struct usb2_com_softc *, uint8_t);
- void (*usb2_com_cfg_set_break) (struct usb2_com_softc *, uint8_t);
- void (*usb2_com_cfg_param) (struct usb2_com_softc *, struct termios *);
- void (*usb2_com_cfg_open) (struct usb2_com_softc *);
- void (*usb2_com_cfg_close) (struct usb2_com_softc *);
- int (*usb2_com_pre_open) (struct usb2_com_softc *);
- int (*usb2_com_pre_param) (struct usb2_com_softc *, struct termios *);
- int (*usb2_com_ioctl) (struct usb2_com_softc *, uint32_t, caddr_t, int, struct thread *);
- void (*usb2_com_start_read) (struct usb2_com_softc *);
- void (*usb2_com_stop_read) (struct usb2_com_softc *);
- void (*usb2_com_start_write) (struct usb2_com_softc *);
- void (*usb2_com_stop_write) (struct usb2_com_softc *);
- void (*usb2_com_tty_name) (struct usb2_com_softc *, char *pbuf, uint16_t buflen, uint16_t local_subunit);
-};
-
-/* 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 */
-
-struct usb2_com_cfg_task {
- struct usb2_proc_msg hdr;
- struct usb2_com_softc *sc;
-};
-
-struct usb2_com_param_task {
- struct usb2_proc_msg hdr;
- struct usb2_com_softc *sc;
- struct termios termios_copy;
-};
-
-struct usb2_com_super_softc {
- struct usb2_process sc_tq;
-};
-
-struct usb2_com_softc {
- /*
- * NOTE: To avoid loosing level change information we use two
- * tasks instead of one for all commands.
- *
- * Level changes are transitions like:
- *
- * ON->OFF
- * OFF->ON
- * OPEN->CLOSE
- * CLOSE->OPEN
- */
- struct usb2_com_cfg_task sc_start_task[2];
- struct usb2_com_cfg_task sc_open_task[2];
- struct usb2_com_cfg_task sc_close_task[2];
- struct usb2_com_cfg_task sc_line_state_task[2];
- struct usb2_com_cfg_task sc_status_task[2];
- struct usb2_com_param_task sc_param_task[2];
- struct cv sc_cv;
- const struct usb2_com_callback *sc_callback;
- struct usb2_com_super_softc *sc_super;
- struct tty *sc_tty;
- struct mtx *sc_mtx;
- void *sc_parent;
- uint32_t sc_unit;
- uint32_t sc_local_unit;
- uint16_t sc_portno;
- uint8_t sc_flag;
-#define UCOM_FLAG_RTS_IFLOW 0x01 /* use RTS input flow control */
-#define UCOM_FLAG_GONE 0x02 /* the device is gone */
-#define UCOM_FLAG_ATTACHED 0x04 /* set if attached */
-#define UCOM_FLAG_GP_DATA 0x08 /* set if get and put data is possible */
-#define UCOM_FLAG_WR_START 0x10 /* set if write start was issued */
-#define UCOM_FLAG_LL_READY 0x20 /* set if low layer is ready */
-#define UCOM_FLAG_HL_READY 0x40 /* set if high layer is ready */
- uint8_t sc_lsr;
- uint8_t sc_msr;
- uint8_t sc_mcr;
- uint8_t sc_ttyfreed; /* set when TTY has been freed */
- /* programmed line state bits */
- uint8_t sc_pls_set; /* set bits */
- uint8_t sc_pls_clr; /* cleared bits */
- uint8_t sc_pls_curr; /* last state */
-#define UCOM_LS_DTR 0x01
-#define UCOM_LS_RTS 0x02
-#define UCOM_LS_BREAK 0x04
-};
-
-#define usb2_com_cfg_do_request(udev,com,req,ptr,flags,timo) \
- usb2_do_request_proc(udev,&(com)->sc_super->sc_tq,req,ptr,flags,NULL,timo)
-
-int usb2_com_attach(struct usb2_com_super_softc *,
- struct usb2_com_softc *, uint32_t, void *,
- const struct usb2_com_callback *callback, struct mtx *);
-void usb2_com_detach(struct usb2_com_super_softc *,
- struct usb2_com_softc *, uint32_t);
-void usb2_com_status_change(struct usb2_com_softc *);
-uint8_t usb2_com_get_data(struct usb2_com_softc *, struct usb2_page_cache *,
- uint32_t, uint32_t, uint32_t *);
-void usb2_com_put_data(struct usb2_com_softc *, struct usb2_page_cache *,
- uint32_t, uint32_t);
-uint8_t usb2_com_cfg_is_gone(struct usb2_com_softc *);
-#endif /* _USB2_SERIAL_H_ */
diff --git a/sys/dev/usb2/serial/uslcom2.c b/sys/dev/usb2/serial/uslcom2.c
deleted file mode 100644
index 56b4a9a..0000000
--- a/sys/dev/usb2/serial/uslcom2.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/* $OpenBSD: uslcom.c,v 1.17 2007/11/24 10:52:12 jsg Exp $ */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * 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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR uslcom_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#if USB_DEBUG
-static int uslcom_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uslcom, CTLFLAG_RW, 0, "USB uslcom");
-SYSCTL_INT(_hw_usb2_uslcom, OID_AUTO, debug, CTLFLAG_RW,
- &uslcom_debug, 0, "Debug level");
-#endif
-
-#define USLCOM_BULK_BUF_SIZE 1024
-#define USLCOM_CONFIG_INDEX 0
-#define USLCOM_IFACE_INDEX 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_PORT_NO 0xFFFF /* XXX think this should be 0 --hps */
-
-#define USLCOM_BREAK_OFF 0x00
-#define USLCOM_BREAK_ON 0x01
-
-enum {
- USLCOM_BULK_DT_WR,
- USLCOM_BULK_DT_RD,
- USLCOM_N_TRANSFER,
-};
-
-struct uslcom_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_xfer *sc_xfer[USLCOM_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint8_t sc_msr;
- uint8_t sc_lsr;
-};
-
-static device_probe_t uslcom_probe;
-static device_attach_t uslcom_attach;
-static device_detach_t uslcom_detach;
-
-static usb2_callback_t uslcom_write_callback;
-static usb2_callback_t uslcom_read_callback;
-
-static void uslcom_open(struct usb2_com_softc *);
-static void uslcom_close(struct usb2_com_softc *);
-static void uslcom_set_dtr(struct usb2_com_softc *, uint8_t);
-static void uslcom_set_rts(struct usb2_com_softc *, uint8_t);
-static void uslcom_set_break(struct usb2_com_softc *, uint8_t);
-static int uslcom_pre_param(struct usb2_com_softc *, struct termios *);
-static void uslcom_param(struct usb2_com_softc *, struct termios *);
-static void uslcom_get_status(struct usb2_com_softc *, uint8_t *, uint8_t *);
-static void uslcom_start_read(struct usb2_com_softc *);
-static void uslcom_stop_read(struct usb2_com_softc *);
-static void uslcom_start_write(struct usb2_com_softc *);
-static void uslcom_stop_write(struct usb2_com_softc *);
-
-static const struct usb2_config uslcom_config[USLCOM_N_TRANSFER] = {
-
- [USLCOM_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = USLCOM_BULK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &uslcom_write_callback,
- },
-
- [USLCOM_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = USLCOM_BULK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &uslcom_read_callback,
- },
-};
-
-struct usb2_com_callback uslcom_callback = {
- .usb2_com_cfg_open = &uslcom_open,
- .usb2_com_cfg_close = &uslcom_close,
- .usb2_com_cfg_get_status = &uslcom_get_status,
- .usb2_com_cfg_set_dtr = &uslcom_set_dtr,
- .usb2_com_cfg_set_rts = &uslcom_set_rts,
- .usb2_com_cfg_set_break = &uslcom_set_break,
- .usb2_com_cfg_param = &uslcom_param,
- .usb2_com_pre_param = &uslcom_pre_param,
- .usb2_com_start_read = &uslcom_start_read,
- .usb2_com_stop_read = &uslcom_stop_read,
- .usb2_com_start_write = &uslcom_start_write,
- .usb2_com_stop_write = &uslcom_stop_write,
-};
-
-static const struct usb2_device_id uslcom_devs[] = {
- { USB_VPI(USB_VENDOR_BALTECH, USB_PRODUCT_BALTECH_CARDREADER, 0) },
- { USB_VPI(USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD, 0) },
- { USB_VPI(USB_VENDOR_JABLOTRON, USB_PRODUCT_JABLOTRON_PC60B, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ARGUSISP, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CRUMB128, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_DEGREE, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_BURNSIDE, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_HELICOM, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_HARP, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_JTAG, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_LIN, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_POLOLU, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2102, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP210X_2, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_SUUNTO, 0) },
- { USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_TRAQMATE, 0) },
- { USB_VPI(USB_VENDOR_SILABS2, USB_PRODUCT_SILABS2_DCU11CLONE, 0) },
- { USB_VPI(USB_VENDOR_USI, USB_PRODUCT_USI_MC60, 0) },
-};
-
-static device_method_t uslcom_methods[] = {
- DEVMETHOD(device_probe, uslcom_probe),
- DEVMETHOD(device_attach, uslcom_attach),
- DEVMETHOD(device_detach, uslcom_detach),
- {0, 0}
-};
-
-static devclass_t uslcom_devclass;
-
-static driver_t uslcom_driver = {
- .name = "uslcom",
- .methods = uslcom_methods,
- .size = sizeof(struct uslcom_softc),
-};
-
-DRIVER_MODULE(uslcom, ushub, uslcom_driver, uslcom_devclass, NULL, 0);
-MODULE_DEPEND(uslcom, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(uslcom, usb2_core, 1, 1, 1);
-MODULE_VERSION(uslcom, 1);
-
-static int
-uslcom_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- DPRINTFN(11, "\n");
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != USLCOM_CONFIG_INDEX) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != USLCOM_IFACE_INDEX) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(uslcom_devs, sizeof(uslcom_devs), uaa));
-}
-
-static int
-uslcom_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct uslcom_softc *sc = device_get_softc(dev);
- int error;
-
- DPRINTFN(11, "\n");
-
- device_set_usb2_desc(dev);
-
- sc->sc_udev = uaa->device;
-
- error = usb2_transfer_setup(uaa->device,
- &uaa->info.bIfaceIndex, sc->sc_xfer, uslcom_config,
- USLCOM_N_TRANSFER, sc, &Giant);
- if (error) {
- DPRINTF("one or more missing USB endpoints, "
- "error=%s\n", usb2_errstr(error));
- goto detach;
- }
- /* clear stall at first run */
- usb2_transfer_set_stall(sc->sc_xfer[USLCOM_BULK_DT_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[USLCOM_BULK_DT_RD]);
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &uslcom_callback, &Giant);
- if (error) {
- goto detach;
- }
- return (0);
-
-detach:
- uslcom_detach(dev);
- return (ENXIO);
-}
-
-static int
-uslcom_detach(device_t dev)
-{
- struct uslcom_softc *sc = device_get_softc(dev);
-
- DPRINTF("sc=%p\n", sc);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, USLCOM_N_TRANSFER);
-
- return (0);
-}
-
-static void
-uslcom_open(struct usb2_com_softc *ucom)
-{
- struct uslcom_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_UART;
- USETW(req.wValue, USLCOM_UART_ENABLE);
- USETW(req.wIndex, USLCOM_PORT_NO);
- USETW(req.wLength, 0);
-
- if (usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000)) {
- DPRINTF("UART enable failed (ignored)\n");
- }
-}
-
-static void
-uslcom_close(struct usb2_com_softc *ucom)
-{
- struct uslcom_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_UART;
- USETW(req.wValue, USLCOM_UART_DISABLE);
- USETW(req.wIndex, USLCOM_PORT_NO);
- USETW(req.wLength, 0);
-
- if (usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000)) {
- DPRINTF("UART disable failed (ignored)\n");
- }
-}
-
-static void
-uslcom_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uslcom_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
- uint16_t ctl;
-
- DPRINTF("onoff = %d\n", onoff);
-
- ctl = onoff ? USLCOM_CTRL_DTR_ON : 0;
- ctl |= USLCOM_CTRL_DTR_SET;
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_CTRL;
- USETW(req.wValue, ctl);
- USETW(req.wIndex, USLCOM_PORT_NO);
- USETW(req.wLength, 0);
-
- if (usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000)) {
- DPRINTF("Setting DTR failed (ignored)\n");
- }
-}
-
-static void
-uslcom_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uslcom_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
- uint16_t ctl;
-
- DPRINTF("onoff = %d\n", onoff);
-
- ctl = onoff ? USLCOM_CTRL_RTS_ON : 0;
- ctl |= USLCOM_CTRL_RTS_SET;
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_CTRL;
- USETW(req.wValue, ctl);
- USETW(req.wIndex, USLCOM_PORT_NO);
- USETW(req.wLength, 0);
-
- if (usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000)) {
- DPRINTF("Setting DTR failed (ignored)\n");
- }
-}
-
-static int
-uslcom_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- if (t->c_ospeed <= 0 || t->c_ospeed > 921600)
- return (EINVAL);
- return (0);
-}
-
-static void
-uslcom_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct uslcom_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
- uint16_t data;
-
- DPRINTF("\n");
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_BAUD_RATE;
- USETW(req.wValue, USLCOM_BAUD_REF / t->c_ospeed);
- USETW(req.wIndex, USLCOM_PORT_NO);
- USETW(req.wLength, 0);
-
- if (usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000)) {
- DPRINTF("Set baudrate failed (ignored)\n");
- }
-
- if (t->c_cflag & CSTOPB)
- data = USLCOM_STOP_BITS_2;
- else
- data = USLCOM_STOP_BITS_1;
- if (t->c_cflag & PARENB) {
- if (t->c_cflag & PARODD)
- data |= USLCOM_PARITY_ODD;
- else
- data |= USLCOM_PARITY_EVEN;
- } else
- data |= USLCOM_PARITY_NONE;
- switch (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, USLCOM_PORT_NO);
- USETW(req.wLength, 0);
-
- if (usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000)) {
- DPRINTF("Set format failed (ignored)\n");
- }
- return;
-}
-
-static void
-uslcom_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
- struct uslcom_softc *sc = ucom->sc_parent;
-
- DPRINTF("\n");
-
- *lsr = sc->sc_lsr;
- *msr = sc->sc_msr;
-}
-
-static void
-uslcom_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uslcom_softc *sc = ucom->sc_parent;
- struct usb2_device_request req;
- uint16_t brk = onoff ? USLCOM_BREAK_ON : USLCOM_BREAK_OFF;
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_BREAK;
- USETW(req.wValue, brk);
- USETW(req.wIndex, USLCOM_PORT_NO);
- USETW(req.wLength, 0);
-
- if (usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000)) {
- DPRINTF("Set BREAK failed (ignored)\n");
- }
-}
-
-static void
-uslcom_write_callback(struct usb2_xfer *xfer)
-{
- struct uslcom_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- USLCOM_BULK_BUF_SIZE, &actlen)) {
-
- DPRINTF("actlen = %d\n", actlen);
-
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uslcom_read_callback(struct usb2_xfer *xfer)
-{
- struct uslcom_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uslcom_start_read(struct usb2_com_softc *ucom)
-{
- struct uslcom_softc *sc = ucom->sc_parent;
-
- /* start read endpoint */
- usb2_transfer_start(sc->sc_xfer[USLCOM_BULK_DT_RD]);
-}
-
-static void
-uslcom_stop_read(struct usb2_com_softc *ucom)
-{
- struct uslcom_softc *sc = ucom->sc_parent;
-
- /* stop read endpoint */
- usb2_transfer_stop(sc->sc_xfer[USLCOM_BULK_DT_RD]);
-}
-
-static void
-uslcom_start_write(struct usb2_com_softc *ucom)
-{
- struct uslcom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[USLCOM_BULK_DT_WR]);
-}
-
-static void
-uslcom_stop_write(struct usb2_com_softc *ucom)
-{
- struct uslcom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[USLCOM_BULK_DT_WR]);
-}
diff --git a/sys/dev/usb2/serial/uvisor2.c b/sys/dev/usb2/serial/uvisor2.c
deleted file mode 100644
index a33623b..0000000
--- a/sys/dev/usb2/serial/uvisor2.c
+++ /dev/null
@@ -1,610 +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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-
-#define USB_DEBUG_VAR uvisor_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#if USB_DEBUG
-static int uvisor_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uvisor, CTLFLAG_RW, 0, "USB uvisor");
-SYSCTL_INT(_hw_usb2_uvisor, OID_AUTO, debug, CTLFLAG_RW,
- &uvisor_debug, 0, "Debug level");
-#endif
-
-#define UVISOR_CONFIG_INDEX 0
-#define UVISOR_IFACE_INDEX 0
-#define UVISOR_BUFSIZE 1024 /* bytes */
-
-/* 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;
- } __packed connections[UVISOR_MAX_CONN];
-} __packed;
-
-#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;
- } __packed connections[UVISOR_MAX_CONN];
-} __packed;
-
-enum {
- UVISOR_BULK_DT_WR,
- UVISOR_BULK_DT_RD,
- UVISOR_N_TRANSFER,
-};
-
-struct uvisor_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_xfer *sc_xfer[UVISOR_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint16_t sc_flag;
-#define UVISOR_FLAG_PALM4 0x0001
-#define UVISOR_FLAG_VISOR 0x0002
-#define UVISOR_FLAG_PALM35 0x0004
-#define UVISOR_FLAG_SEND_NOTIFY 0x0008
-
- uint8_t sc_iface_no;
- uint8_t sc_iface_index;
-};
-
-/* prototypes */
-
-static device_probe_t uvisor_probe;
-static device_attach_t uvisor_attach;
-static device_detach_t uvisor_detach;
-
-static usb2_callback_t uvisor_write_callback;
-static usb2_callback_t uvisor_read_callback;
-
-static usb2_error_t uvisor_init(struct uvisor_softc *, struct usb2_device *,
- struct usb2_config *);
-static void uvisor_cfg_open(struct usb2_com_softc *);
-static void uvisor_cfg_close(struct usb2_com_softc *);
-static void uvisor_start_read(struct usb2_com_softc *);
-static void uvisor_stop_read(struct usb2_com_softc *);
-static void uvisor_start_write(struct usb2_com_softc *);
-static void uvisor_stop_write(struct usb2_com_softc *);
-
-static const struct usb2_config uvisor_config[UVISOR_N_TRANSFER] = {
-
- [UVISOR_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UVISOR_BUFSIZE, /* bytes */
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &uvisor_write_callback,
- },
-
- [UVISOR_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UVISOR_BUFSIZE, /* bytes */
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &uvisor_read_callback,
- },
-};
-
-static const struct usb2_com_callback uvisor_callback = {
- .usb2_com_cfg_open = &uvisor_cfg_open,
- .usb2_com_cfg_close = &uvisor_cfg_close,
- .usb2_com_start_read = &uvisor_start_read,
- .usb2_com_stop_read = &uvisor_stop_read,
- .usb2_com_start_write = &uvisor_start_write,
- .usb2_com_stop_write = &uvisor_stop_write,
-};
-
-static device_method_t uvisor_methods[] = {
- DEVMETHOD(device_probe, uvisor_probe),
- DEVMETHOD(device_attach, uvisor_attach),
- DEVMETHOD(device_detach, uvisor_detach),
- {0, 0}
-};
-
-static devclass_t uvisor_devclass;
-
-static driver_t uvisor_driver = {
- .name = "uvisor",
- .methods = uvisor_methods,
- .size = sizeof(struct uvisor_softc),
-};
-
-DRIVER_MODULE(uvisor, ushub, uvisor_driver, uvisor_devclass, NULL, 0);
-MODULE_DEPEND(uvisor, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(uvisor, usb2_core, 1, 1, 1);
-
-static const struct usb2_device_id uvisor_devs[] = {
- {USB_VPI(USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_IQUE_3600, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_FOSSIL, USB_PRODUCT_FOSSIL_WRISTPDA, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR, UVISOR_FLAG_VISOR)},
- {USB_VPI(USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO600, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M500, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M505, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M515, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_I705, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M125, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M130, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE31, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_I500, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40, 0)},
- {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60, UVISOR_FLAG_PALM4)},
- {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_35, UVISOR_FLAG_PALM35)},
-/* {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_25, UVISOR_FLAG_PALM4 )}, */
- {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TJ37, UVISOR_FLAG_PALM4)},
-/* {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TH55, UVISOR_FLAG_PALM4 )}, See PR 80935 */
- {USB_VPI(USB_VENDOR_TAPWAVE, USB_PRODUCT_TAPWAVE_ZODIAC, UVISOR_FLAG_PALM4)},
-};
-
-static int
-uvisor_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != UVISOR_CONFIG_INDEX) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != UVISOR_IFACE_INDEX) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(uvisor_devs, sizeof(uvisor_devs), uaa));
-}
-
-static int
-uvisor_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct uvisor_softc *sc = device_get_softc(dev);
- struct usb2_config uvisor_config_copy[UVISOR_N_TRANSFER];
- int error;
-
- DPRINTF("sc=%p\n", sc);
- bcopy(uvisor_config, uvisor_config_copy,
- sizeof(uvisor_config_copy));
- device_set_usb2_desc(dev);
-
- sc->sc_udev = uaa->device;
-
- /* configure the device */
-
- sc->sc_flag = USB_GET_DRIVER_INFO(uaa);
- sc->sc_iface_no = uaa->info.bIfaceNum;
- sc->sc_iface_index = UVISOR_IFACE_INDEX;
-
- error = uvisor_init(sc, uaa->device, uvisor_config_copy);
-
- if (error) {
- DPRINTF("init failed, error=%s\n",
- usb2_errstr(error));
- goto detach;
- }
- error = usb2_transfer_setup(uaa->device, &sc->sc_iface_index,
- sc->sc_xfer, uvisor_config_copy, UVISOR_N_TRANSFER,
- sc, &Giant);
- if (error) {
- DPRINTF("could not allocate all pipes\n");
- goto detach;
- }
- /* clear stall at first run */
- usb2_transfer_set_stall(sc->sc_xfer[UVISOR_BULK_DT_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[UVISOR_BULK_DT_RD]);
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &uvisor_callback, &Giant);
- if (error) {
- DPRINTF("usb2_com_attach failed\n");
- goto detach;
- }
- return (0);
-
-detach:
- uvisor_detach(dev);
- return (ENXIO);
-}
-
-static int
-uvisor_detach(device_t dev)
-{
- struct uvisor_softc *sc = device_get_softc(dev);
-
- DPRINTF("sc=%p\n", sc);
-
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UVISOR_N_TRANSFER);
-
- return (0);
-}
-
-static usb2_error_t
-uvisor_init(struct uvisor_softc *sc, struct usb2_device *udev, struct usb2_config *config)
-{
- usb2_error_t err = 0;
- struct usb2_device_request req;
- struct uvisor_connection_info coninfo;
- struct uvisor_palm_connection_info pconinfo;
- uint16_t actlen;
- uWord wAvail;
- uint8_t buffer[256];
-
- if (sc->sc_flag & UVISOR_FLAG_VISOR) {
- DPRINTF("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 = usb2_do_request_flags
- (udev, &Giant, &req, &coninfo, USB_SHORT_XFER_OK,
- &actlen, USB_DEFAULT_TIMEOUT);
-
- if (err) {
- goto done;
- }
- }
-#if USB_DEBUG
- if (sc->sc_flag & UVISOR_FLAG_VISOR) {
- uint16_t i, np;
- const char *desc;
-
- np = UGETW(coninfo.num_ports);
- if (np > UVISOR_MAX_CONN) {
- np = UVISOR_MAX_CONN;
- }
- DPRINTF("Number of ports: %d\n", np);
-
- for (i = 0; i < np; ++i) {
- switch (coninfo.connections[i].port_function_id) {
- case UVISOR_FUNCTION_GENERIC:
- desc = "Generic";
- break;
- case UVISOR_FUNCTION_DEBUGGER:
- desc = "Debugger";
- break;
- case UVISOR_FUNCTION_HOTSYNC:
- desc = "HotSync";
- break;
- case UVISOR_FUNCTION_REMOTE_FILE_SYS:
- desc = "Remote File System";
- break;
- default:
- desc = "unknown";
- break;
- }
- DPRINTF("Port %d is for %s\n",
- coninfo.connections[i].port, desc);
- }
- }
-#endif
-
- if (sc->sc_flag & UVISOR_FLAG_PALM4) {
- uint8_t 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 = usb2_do_request_flags
- (udev, &Giant, &req, &pconinfo, USB_SHORT_XFER_OK,
- &actlen, USB_DEFAULT_TIMEOUT);
-
- if (err) {
- goto done;
- }
- if (actlen < 12) {
- DPRINTF("too little data\n");
- err = USB_ERR_INVAL;
- goto done;
- }
- if (pconinfo.endpoint_numbers_different) {
- port = pconinfo.connections[0].end_point_info;
- config[0].endpoint = (port & 0xF); /* output */
- config[1].endpoint = (port >> 4); /* input */
- } else {
- port = pconinfo.connections[0].port;
- config[0].endpoint = (port & 0xF); /* output */
- config[1].endpoint = (port & 0xF); /* input */
- }
-#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 = usb2_do_request(udev, &req, buffer);
- if (err) {
- goto done;
- }
-#endif
- }
- if (sc->sc_flag & UVISOR_FLAG_PALM35) {
- /* get the config number */
- DPRINTF("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 = usb2_do_request(udev, &Giant, &req, buffer);
- if (err) {
- goto done;
- }
- /* get the interface number */
- DPRINTF("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 = usb2_do_request(udev, &Giant, &req, buffer);
- if (err) {
- goto done;
- }
- }
- DPRINTF("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(wAvail));
- err = usb2_do_request(udev, &Giant, &req, &wAvail);
- if (err) {
- goto done;
- }
- DPRINTF("avail=%d\n", UGETW(wAvail));
-
- DPRINTF("done\n");
-done:
- return (err);
-}
-
-static void
-uvisor_cfg_open(struct usb2_com_softc *ucom)
-{
- return;
-}
-
-static void
-uvisor_cfg_close(struct usb2_com_softc *ucom)
-{
- struct uvisor_softc *sc = ucom->sc_parent;
- uint8_t buffer[UVISOR_CONNECTION_INFO_SIZE];
- struct usb2_device_request req;
- usb2_error_t err;
-
- 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);
-
- err = usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, buffer, 0, 1000);
- if (err) {
- DPRINTFN(0, "close notification failed, error=%s\n",
- usb2_errstr(err));
- }
-}
-
-static void
-uvisor_start_read(struct usb2_com_softc *ucom)
-{
- struct uvisor_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_DT_RD]);
-}
-
-static void
-uvisor_stop_read(struct usb2_com_softc *ucom)
-{
- struct uvisor_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UVISOR_BULK_DT_RD]);
-}
-
-static void
-uvisor_start_write(struct usb2_com_softc *ucom)
-{
- struct uvisor_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_DT_WR]);
-}
-
-static void
-uvisor_stop_write(struct usb2_com_softc *ucom)
-{
- struct uvisor_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UVISOR_BULK_DT_WR]);
-}
-
-static void
-uvisor_write_callback(struct usb2_xfer *xfer)
-{
- struct uvisor_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- UVISOR_BUFSIZE, &actlen)) {
-
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uvisor_read_callback(struct usb2_xfer *xfer)
-{
- struct uvisor_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
diff --git a/sys/dev/usb2/serial/uvscom2.c b/sys/dev/usb2/serial/uvscom2.c
deleted file mode 100644
index 1783904..0000000
--- a/sys/dev/usb2/serial/uvscom2.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/* $NetBSD: usb/uvscom.c,v 1.1 2002/03/19 15:08:42 augustss Exp $ */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * 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.
- *
- */
-
-/*
- * 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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_cdc.h>
-
-#define USB_DEBUG_VAR uvscom_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-
-#include <dev/usb2/serial/usb2_serial.h>
-
-#if USB_DEBUG
-static int uvscom_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uvscom, CTLFLAG_RW, 0, "USB uvscom");
-SYSCTL_INT(_hw_usb2_uvscom, OID_AUTO, debug, CTLFLAG_RW,
- &uvscom_debug, 0, "Debug level");
-#endif
-
-#define UVSCOM_MODVER 1 /* module version */
-
-#define UVSCOM_CONFIG_INDEX 0
-#define UVSCOM_IFACE_INDEX 0
-
-/* 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
-#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)
-
-#define UVSCOM_BULK_BUF_SIZE 1024 /* bytes */
-
-enum {
- UVSCOM_BULK_DT_WR,
- UVSCOM_BULK_DT_RD,
- UVSCOM_INTR_DT_RD,
- UVSCOM_N_TRANSFER,
-};
-
-struct uvscom_softc {
- struct usb2_com_super_softc sc_super_ucom;
- struct usb2_com_softc sc_ucom;
-
- struct usb2_xfer *sc_xfer[UVSCOM_N_TRANSFER];
- struct usb2_device *sc_udev;
-
- uint16_t sc_line; /* line control register */
-
- uint8_t sc_iface_no; /* interface number */
- uint8_t sc_iface_index; /* interface index */
- uint8_t sc_lsr; /* local status register */
- uint8_t sc_msr; /* uvscom status register */
- uint8_t sc_unit_status; /* unit status */
-};
-
-/* prototypes */
-
-static device_probe_t uvscom_probe;
-static device_attach_t uvscom_attach;
-static device_detach_t uvscom_detach;
-
-static usb2_callback_t uvscom_write_callback;
-static usb2_callback_t uvscom_read_callback;
-static usb2_callback_t uvscom_intr_callback;
-
-static void uvscom_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
-static void uvscom_cfg_set_rts(struct usb2_com_softc *, uint8_t);
-static void uvscom_cfg_set_break(struct usb2_com_softc *, uint8_t);
-static int uvscom_pre_param(struct usb2_com_softc *, struct termios *);
-static void uvscom_cfg_param(struct usb2_com_softc *, struct termios *);
-static int uvscom_pre_open(struct usb2_com_softc *);
-static void uvscom_cfg_open(struct usb2_com_softc *);
-static void uvscom_cfg_close(struct usb2_com_softc *);
-static void uvscom_start_read(struct usb2_com_softc *);
-static void uvscom_stop_read(struct usb2_com_softc *);
-static void uvscom_start_write(struct usb2_com_softc *);
-static void uvscom_stop_write(struct usb2_com_softc *);
-static void uvscom_cfg_get_status(struct usb2_com_softc *, uint8_t *,
- uint8_t *);
-static void uvscom_cfg_write(struct uvscom_softc *, uint8_t, uint16_t);
-static uint16_t uvscom_cfg_read_status(struct uvscom_softc *);
-
-static const struct usb2_config uvscom_config[UVSCOM_N_TRANSFER] = {
-
- [UVSCOM_BULK_DT_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UVSCOM_BULK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = &uvscom_write_callback,
- },
-
- [UVSCOM_BULK_DT_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UVSCOM_BULK_BUF_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &uvscom_read_callback,
- },
-
- [UVSCOM_INTR_DT_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.bufsize = 0, /* use wMaxPacketSize */
- .mh.callback = &uvscom_intr_callback,
- },
-};
-
-static const struct usb2_com_callback uvscom_callback = {
- .usb2_com_cfg_get_status = &uvscom_cfg_get_status,
- .usb2_com_cfg_set_dtr = &uvscom_cfg_set_dtr,
- .usb2_com_cfg_set_rts = &uvscom_cfg_set_rts,
- .usb2_com_cfg_set_break = &uvscom_cfg_set_break,
- .usb2_com_cfg_param = &uvscom_cfg_param,
- .usb2_com_cfg_open = &uvscom_cfg_open,
- .usb2_com_cfg_close = &uvscom_cfg_close,
- .usb2_com_pre_open = &uvscom_pre_open,
- .usb2_com_pre_param = &uvscom_pre_param,
- .usb2_com_start_read = &uvscom_start_read,
- .usb2_com_stop_read = &uvscom_stop_read,
- .usb2_com_start_write = &uvscom_start_write,
- .usb2_com_stop_write = &uvscom_stop_write,
-};
-
-static const struct usb2_device_id uvscom_devs[] = {
- /* SUNTAC U-Cable type A4 */
- {USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS144L4, 0)},
- /* SUNTAC U-Cable type D2 */
- {USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_DS96L, 0)},
- /* SUNTAC Ir-Trinity */
- {USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_IS96U, 0)},
- /* SUNTAC U-Cable type P1 */
- {USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_PS64P1, 0)},
- /* SUNTAC Slipper U */
- {USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_VS10U, 0)},
-};
-
-static device_method_t uvscom_methods[] = {
- DEVMETHOD(device_probe, uvscom_probe),
- DEVMETHOD(device_attach, uvscom_attach),
- DEVMETHOD(device_detach, uvscom_detach),
- {0, 0}
-};
-
-static devclass_t uvscom_devclass;
-
-static driver_t uvscom_driver = {
- .name = "uvscom",
- .methods = uvscom_methods,
- .size = sizeof(struct uvscom_softc),
-};
-
-DRIVER_MODULE(uvscom, ushub, uvscom_driver, uvscom_devclass, NULL, 0);
-MODULE_DEPEND(uvscom, usb2_serial, 1, 1, 1);
-MODULE_DEPEND(uvscom, usb2_core, 1, 1, 1);
-MODULE_VERSION(uvscom, UVSCOM_MODVER);
-
-static int
-uvscom_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->info.bConfigIndex != UVSCOM_CONFIG_INDEX) {
- return (ENXIO);
- }
- if (uaa->info.bIfaceIndex != UVSCOM_IFACE_INDEX) {
- return (ENXIO);
- }
- return (usb2_lookup_id_by_uaa(uvscom_devs, sizeof(uvscom_devs), uaa));
-}
-
-static int
-uvscom_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct uvscom_softc *sc = device_get_softc(dev);
- int error;
-
- device_set_usb2_desc(dev);
-
- sc->sc_udev = uaa->device;
-
- DPRINTF("sc=%p\n", sc);
-
- sc->sc_iface_no = uaa->info.bIfaceNum;
- sc->sc_iface_index = UVSCOM_IFACE_INDEX;
-
- error = usb2_transfer_setup(uaa->device, &sc->sc_iface_index,
- sc->sc_xfer, uvscom_config, UVSCOM_N_TRANSFER, sc, &Giant);
-
- if (error) {
- DPRINTF("could not allocate all USB transfers!\n");
- goto detach;
- }
- sc->sc_line = UVSCOM_LINE_INIT;
-
- /* clear stall at first run */
- usb2_transfer_set_stall(sc->sc_xfer[UVSCOM_BULK_DT_WR]);
- usb2_transfer_set_stall(sc->sc_xfer[UVSCOM_BULK_DT_RD]);
-
- error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
- &uvscom_callback, &Giant);
- if (error) {
- goto detach;
- }
- /* start interrupt pipe */
- mtx_lock(&Giant);
- usb2_transfer_start(sc->sc_xfer[UVSCOM_INTR_DT_RD]);
- mtx_unlock(&Giant);
-
- return (0);
-
-detach:
- uvscom_detach(dev);
- return (ENXIO);
-}
-
-static int
-uvscom_detach(device_t dev)
-{
- struct uvscom_softc *sc = device_get_softc(dev);
-
- DPRINTF("sc=%p\n", sc);
-
- /* stop interrupt pipe */
-
- if (sc->sc_xfer[UVSCOM_INTR_DT_RD]) {
- usb2_transfer_stop(sc->sc_xfer[UVSCOM_INTR_DT_RD]);
- }
- usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
-
- usb2_transfer_unsetup(sc->sc_xfer, UVSCOM_N_TRANSFER);
-
- return (0);
-}
-
-static void
-uvscom_write_callback(struct usb2_xfer *xfer)
-{
- struct uvscom_softc *sc = xfer->priv_sc;
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_SETUP:
- case USB_ST_TRANSFERRED:
-tr_setup:
- if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
- UVSCOM_BULK_BUF_SIZE, &actlen)) {
-
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uvscom_read_callback(struct usb2_xfer *xfer)
-{
- struct uvscom_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uvscom_intr_callback(struct usb2_xfer *xfer)
-{
- struct uvscom_softc *sc = xfer->priv_sc;
- uint8_t buf[2];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- if (xfer->actlen >= 2) {
-
- usb2_copy_out(xfer->frbuffers, 0, buf, sizeof(buf));
-
- sc->sc_lsr = 0;
- sc->sc_msr = 0;
- sc->sc_unit_status = buf[1];
-
- if (buf[0] & UVSCOM_TXRDY) {
- sc->sc_lsr |= ULSR_TXRDY;
- }
- if (buf[0] & UVSCOM_RXRDY) {
- sc->sc_lsr |= ULSR_RXRDY;
- }
- if (buf[1] & UVSCOM_CTS) {
- sc->sc_msr |= SER_CTS;
- }
- if (buf[1] & UVSCOM_DSR) {
- sc->sc_msr |= SER_DSR;
- }
- if (buf[1] & UVSCOM_DCD) {
- sc->sc_msr |= SER_DCD;
- }
- /*
- * the UCOM layer will ignore this call if the TTY
- * device is closed!
- */
- usb2_com_status_change(&sc->sc_ucom);
- }
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static void
-uvscom_cfg_set_dtr(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
-
- DPRINTF("onoff = %d\n", onoff);
-
- if (onoff)
- sc->sc_line |= UVSCOM_DTR;
- else
- sc->sc_line &= ~UVSCOM_DTR;
-
- uvscom_cfg_write(sc, UVSCOM_LINE_CTL, sc->sc_line);
-}
-
-static void
-uvscom_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
-
- DPRINTF("onoff = %d\n", onoff);
-
- if (onoff)
- sc->sc_line |= UVSCOM_RTS;
- else
- sc->sc_line &= ~UVSCOM_RTS;
-
- uvscom_cfg_write(sc, UVSCOM_LINE_CTL, sc->sc_line);
-}
-
-static void
-uvscom_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
-
- DPRINTF("onoff = %d\n", onoff);
-
- if (onoff)
- sc->sc_line |= UVSCOM_BREAK;
- else
- sc->sc_line &= ~UVSCOM_BREAK;
-
- uvscom_cfg_write(sc, UVSCOM_LINE_CTL, sc->sc_line);
-}
-
-static int
-uvscom_pre_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- switch (t->c_ospeed) {
- case B150:
- case B300:
- case B600:
- case B1200:
- case B2400:
- case B4800:
- case B9600:
- case B19200:
- case B38400:
- case B57600:
- case B115200:
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-static void
-uvscom_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
- uint16_t value;
-
- DPRINTF("\n");
-
- switch (t->c_ospeed) {
- case B150:
- value = UVSCOM_SPEED_150BPS;
- break;
- case B300:
- value = UVSCOM_SPEED_300BPS;
- break;
- case B600:
- value = UVSCOM_SPEED_600BPS;
- break;
- case B1200:
- value = UVSCOM_SPEED_1200BPS;
- break;
- case B2400:
- value = UVSCOM_SPEED_2400BPS;
- break;
- case B4800:
- value = UVSCOM_SPEED_4800BPS;
- break;
- case B9600:
- value = UVSCOM_SPEED_9600BPS;
- break;
- case B19200:
- value = UVSCOM_SPEED_19200BPS;
- break;
- case B38400:
- value = UVSCOM_SPEED_38400BPS;
- break;
- case B57600:
- value = UVSCOM_SPEED_57600BPS;
- break;
- case B115200:
- value = UVSCOM_SPEED_115200BPS;
- break;
- default:
- return;
- }
-
- uvscom_cfg_write(sc, UVSCOM_SET_SPEED, value);
-
- value = 0;
-
- if (t->c_cflag & CSTOPB) {
- value |= UVSCOM_STOP_BIT_2;
- }
- if (t->c_cflag & PARENB) {
- if (t->c_cflag & PARODD) {
- value |= UVSCOM_PARITY_ODD;
- } else {
- value |= UVSCOM_PARITY_EVEN;
- }
- } else {
- value |= UVSCOM_PARITY_NONE;
- }
-
- switch (t->c_cflag & CSIZE) {
- case CS5:
- value |= UVSCOM_DATA_BIT_5;
- break;
- case CS6:
- value |= UVSCOM_DATA_BIT_6;
- break;
- case CS7:
- value |= UVSCOM_DATA_BIT_7;
- break;
- default:
- case CS8:
- value |= UVSCOM_DATA_BIT_8;
- break;
- }
-
- uvscom_cfg_write(sc, UVSCOM_SET_PARAM, value);
-}
-
-static int
-uvscom_pre_open(struct usb2_com_softc *ucom)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
-
- DPRINTF("sc = %p\n", sc);
-
- /* check if PC card was inserted */
-
- if (sc->sc_unit_status & UVSCOM_NOCARD) {
- DPRINTF("no PC card!\n");
- return (ENXIO);
- }
- return (0);
-}
-
-static void
-uvscom_cfg_open(struct usb2_com_softc *ucom)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
-
- DPRINTF("sc = %p\n", sc);
-
- uvscom_cfg_read_status(sc);
-}
-
-static void
-uvscom_cfg_close(struct usb2_com_softc *ucom)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
-
- DPRINTF("sc=%p\n", sc);
-
- uvscom_cfg_write(sc, UVSCOM_SHUTDOWN, 0);
-}
-
-static void
-uvscom_start_read(struct usb2_com_softc *ucom)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UVSCOM_BULK_DT_RD]);
-}
-
-static void
-uvscom_stop_read(struct usb2_com_softc *ucom)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UVSCOM_BULK_DT_RD]);
-}
-
-static void
-uvscom_start_write(struct usb2_com_softc *ucom)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_start(sc->sc_xfer[UVSCOM_BULK_DT_WR]);
-}
-
-static void
-uvscom_stop_write(struct usb2_com_softc *ucom)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
-
- usb2_transfer_stop(sc->sc_xfer[UVSCOM_BULK_DT_WR]);
-}
-
-static void
-uvscom_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
-{
- struct uvscom_softc *sc = ucom->sc_parent;
-
- *lsr = sc->sc_lsr;
- *msr = sc->sc_msr;
-}
-
-static void
-uvscom_cfg_write(struct uvscom_softc *sc, uint8_t index, uint16_t value)
-{
- struct usb2_device_request req;
- usb2_error_t err;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = index;
- USETW(req.wValue, value);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- err = usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, NULL, 0, 1000);
- if (err) {
- DPRINTFN(0, "device request failed, err=%s "
- "(ignored)\n", usb2_errstr(err));
- }
-}
-
-static uint16_t
-uvscom_cfg_read_status(struct uvscom_softc *sc)
-{
- struct usb2_device_request req;
- usb2_error_t err;
- uint8_t data[2];
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = UVSCOM_READ_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 2);
-
- err = usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
- &req, data, 0, 1000);
- if (err) {
- DPRINTFN(0, "device request failed, err=%s "
- "(ignored)\n", usb2_errstr(err));
- }
- return (data[0] | (data[1] << 8));
-}
diff --git a/sys/dev/usb2/sound/uaudio2.c b/sys/dev/usb2/sound/uaudio2.c
deleted file mode 100644
index 731e271..0000000
--- a/sys/dev/usb2/sound/uaudio2.c
+++ /dev/null
@@ -1,3751 +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
- */
-
-/*
- * 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 $
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR uaudio_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_parse.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-#include <dev/usb2/core/usb2_dev.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-
-#include <dev/usb2/quirk/usb2_quirk.h>
-#include <dev/usb2/sound/uaudio2_reg.h>
-#include <dev/usb2/sound/uaudio2.h>
-
-#include <sys/reboot.h> /* for bootverbose */
-
-#include <dev/sound/pcm/sound.h>
-#include <dev/sound/chip.h>
-#include "feeder_if.h"
-
-static int uaudio_default_rate = 96000;
-static int uaudio_default_bits = 32;
-static int uaudio_default_channels = 2;
-
-#if USB_DEBUG
-static int uaudio_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
-SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, debug, CTLFLAG_RW,
- &uaudio_debug, 0, "uaudio debug level");
-SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_rate, CTLFLAG_RW,
- &uaudio_default_rate, 0, "uaudio default sample rate");
-SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_bits, CTLFLAG_RW,
- &uaudio_default_bits, 0, "uaudio default sample bits");
-SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_channels, CTLFLAG_RW,
- &uaudio_default_channels, 0, "uaudio default sample channels");
-#endif
-
-#define UAUDIO_MINFRAMES 16 /* must be factor of 8 due HS-USB */
-#define UAUDIO_NCHANBUFS 2 /* number of outstanding request */
-#define UAUDIO_RECURSE_LIMIT 24 /* rounds */
-
-#define MAKE_WORD(h,l) (((h) << 8) | (l))
-#define BIT_TEST(bm,bno) (((bm)[(bno) / 8] >> (7 - ((bno) % 8))) & 1)
-
-struct uaudio_mixer_node {
- int32_t minval;
- int32_t maxval;
-#define MIX_MAX_CHAN 8
- int32_t wValue[MIX_MAX_CHAN]; /* using nchan */
- uint32_t delta;
- uint32_t mul;
- uint32_t ctl;
-
- uint16_t wData[MIX_MAX_CHAN]; /* using nchan */
- uint16_t wIndex;
-
- uint8_t update[(MIX_MAX_CHAN + 7) / 8];
- 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_UNKNOWN 6
-#define MIX_SIZE(n) ((((n) == MIX_SIGNED_16) || \
- ((n) == MIX_UNSIGNED_16)) ? 2 : 1)
-#define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
-
-#define MAX_SELECTOR_INPUT_PIN 256
- uint8_t slctrtype[MAX_SELECTOR_INPUT_PIN];
- uint8_t class;
-
- struct uaudio_mixer_node *next;
-};
-
-struct uaudio_chan {
- struct pcmchan_caps pcm_cap; /* capabilities */
-
- struct snd_dbuf *pcm_buf;
- const struct usb2_config *usb2_cfg;
- struct mtx *pcm_mtx; /* lock protecting this structure */
- struct uaudio_softc *priv_sc;
- struct pcm_channel *pcm_ch;
- struct usb2_xfer *xfer[UAUDIO_NCHANBUFS];
- const struct usb2_audio_streaming_interface_descriptor *p_asid;
- const struct usb2_audio_streaming_type1_descriptor *p_asf1d;
- const struct usb2_audio_streaming_endpoint_descriptor *p_sed;
- const usb2_endpoint_descriptor_audio_t *p_ed1;
- const usb2_endpoint_descriptor_audio_t *p_ed2;
- const struct uaudio_format *p_fmt;
-
- uint8_t *buf; /* pointer to buffer */
- uint8_t *start; /* upper layer buffer start */
- uint8_t *end; /* upper layer buffer end */
- uint8_t *cur; /* current position in upper layer
- * buffer */
-
- uint32_t intr_size; /* in bytes */
- uint32_t block_size;
- uint32_t sample_rate;
- uint32_t format;
- uint32_t pcm_format[2];
-
- uint16_t bytes_per_frame;
-
- uint8_t valid;
- uint8_t iface_index;
- uint8_t iface_alt_index;
-};
-
-#define UMIDI_N_TRANSFER 4 /* units */
-#define UMIDI_CABLES_MAX 16 /* units */
-#define UMIDI_BULK_SIZE 1024 /* bytes */
-
-struct umidi_sub_chan {
- struct usb2_fifo_sc fifo;
- uint8_t *temp_cmd;
- uint8_t temp_0[4];
- uint8_t temp_1[4];
- uint8_t state;
-#define UMIDI_ST_UNKNOWN 0 /* scan for command */
-#define UMIDI_ST_1PARAM 1
-#define UMIDI_ST_2PARAM_1 2
-#define UMIDI_ST_2PARAM_2 3
-#define UMIDI_ST_SYSEX_0 4
-#define UMIDI_ST_SYSEX_1 5
-#define UMIDI_ST_SYSEX_2 6
-
- uint8_t read_open:1;
- uint8_t write_open:1;
- uint8_t unused:6;
-};
-
-struct umidi_chan {
-
- struct umidi_sub_chan sub[UMIDI_CABLES_MAX];
- struct mtx mtx;
-
- struct usb2_xfer *xfer[UMIDI_N_TRANSFER];
-
- uint8_t iface_index;
- uint8_t iface_alt_index;
-
- uint8_t flags;
-#define UMIDI_FLAG_READ_STALL 0x01
-#define UMIDI_FLAG_WRITE_STALL 0x02
-
- uint8_t read_open_refcount;
- uint8_t write_open_refcount;
-
- uint8_t curr_cable;
- uint8_t max_cable;
- uint8_t valid;
-};
-
-struct uaudio_softc {
- struct sbuf sc_sndstat;
- struct sndcard_func sc_sndcard_func;
- struct uaudio_chan sc_rec_chan;
- struct uaudio_chan sc_play_chan;
- struct umidi_chan sc_midi_chan;
-
- struct usb2_device *sc_udev;
- struct usb2_xfer *sc_mixer_xfer[1];
- struct uaudio_mixer_node *sc_mixer_root;
- struct uaudio_mixer_node *sc_mixer_curr;
-
- uint32_t sc_mix_info;
- uint32_t sc_recsrc_info;
-
- uint16_t sc_audio_rev;
- uint16_t sc_mixer_count;
-
- uint8_t sc_sndstat_valid;
- uint8_t sc_mixer_iface_index;
- uint8_t sc_mixer_iface_no;
- uint8_t sc_mixer_chan;
- uint8_t sc_pcm_registered:1;
- uint8_t sc_mixer_init:1;
- uint8_t sc_uq_audio_swap_lr:1;
- uint8_t sc_uq_au_inp_async:1;
- uint8_t sc_uq_au_no_xu:1;
- uint8_t sc_uq_bad_adc:1;
-};
-
-struct uaudio_search_result {
- uint8_t bit_input[(256 + 7) / 8];
- uint8_t bit_output[(256 + 7) / 8];
- uint8_t bit_visited[(256 + 7) / 8];
- uint8_t recurse_level;
- uint8_t id_max;
-};
-
-struct uaudio_terminal_node {
- union {
- const struct usb2_descriptor *desc;
- const struct usb2_audio_input_terminal *it;
- const struct usb2_audio_output_terminal *ot;
- const struct usb2_audio_mixer_unit_0 *mu;
- const struct usb2_audio_selector_unit *su;
- const struct usb2_audio_feature_unit *fu;
- const struct usb2_audio_processing_unit_0 *pu;
- const struct usb2_audio_extension_unit_0 *eu;
- } u;
- struct uaudio_search_result usr;
- struct uaudio_terminal_node *root;
-};
-
-struct uaudio_format {
- uint16_t wFormat;
- uint8_t bPrecision;
- uint32_t freebsd_fmt;
- const char *description;
-};
-
-static const struct uaudio_format uaudio_formats[] = {
-
- {UA_FMT_PCM8, 8, AFMT_U8, "8-bit U-LE PCM"},
- {UA_FMT_PCM8, 16, AFMT_U16_LE, "16-bit U-LE PCM"},
- {UA_FMT_PCM8, 24, AFMT_U24_LE, "24-bit U-LE PCM"},
- {UA_FMT_PCM8, 32, AFMT_U32_LE, "32-bit U-LE PCM"},
-
- {UA_FMT_PCM, 8, AFMT_S8, "8-bit S-LE PCM"},
- {UA_FMT_PCM, 16, AFMT_S16_LE, "16-bit S-LE PCM"},
- {UA_FMT_PCM, 24, AFMT_S24_LE, "24-bit S-LE PCM"},
- {UA_FMT_PCM, 32, AFMT_S32_LE, "32-bit S-LE PCM"},
-
- {UA_FMT_ALAW, 8, AFMT_A_LAW, "8-bit A-Law"},
- {UA_FMT_MULAW, 8, AFMT_MU_LAW, "8-bit mu-Law"},
-
- {0, 0, 0, NULL}
-};
-
-#define UAC_OUTPUT 0
-#define UAC_INPUT 1
-#define UAC_EQUAL 2
-#define UAC_RECORD 3
-#define UAC_NCLASSES 4
-
-#if USB_DEBUG
-static const char *uac_names[] = {
- "outputs", "inputs", "equalization", "record"
-};
-
-#endif
-
-/* prototypes */
-
-static device_probe_t uaudio_probe;
-static device_attach_t uaudio_attach;
-static device_detach_t uaudio_detach;
-
-static usb2_callback_t uaudio_chan_play_callback;
-static usb2_callback_t uaudio_chan_record_callback;
-static usb2_callback_t uaudio_mixer_write_cfg_callback;
-static usb2_callback_t umidi_read_clear_stall_callback;
-static usb2_callback_t umidi_bulk_read_callback;
-static usb2_callback_t umidi_write_clear_stall_callback;
-static usb2_callback_t umidi_bulk_write_callback;
-
-static void uaudio_chan_fill_info_sub(struct uaudio_softc *,
- struct usb2_device *, uint32_t, uint16_t, uint8_t, uint8_t);
-static void uaudio_chan_fill_info(struct uaudio_softc *,
- struct usb2_device *);
-static void uaudio_mixer_add_ctl_sub(struct uaudio_softc *,
- struct uaudio_mixer_node *);
-static void uaudio_mixer_add_ctl(struct uaudio_softc *,
- struct uaudio_mixer_node *);
-static void uaudio_mixer_add_input(struct uaudio_softc *,
- const struct uaudio_terminal_node *, int);
-static void uaudio_mixer_add_output(struct uaudio_softc *,
- const struct uaudio_terminal_node *, int);
-static void uaudio_mixer_add_mixer(struct uaudio_softc *,
- const struct uaudio_terminal_node *, int);
-static void uaudio_mixer_add_selector(struct uaudio_softc *,
- const struct uaudio_terminal_node *, int);
-static uint32_t uaudio_mixer_feature_get_bmaControls(
- const struct usb2_audio_feature_unit *, uint8_t);
-static void uaudio_mixer_add_feature(struct uaudio_softc *,
- const struct uaudio_terminal_node *, int);
-static void uaudio_mixer_add_processing_updown(struct uaudio_softc *,
- const struct uaudio_terminal_node *, int);
-static void uaudio_mixer_add_processing(struct uaudio_softc *,
- const struct uaudio_terminal_node *, int);
-static void uaudio_mixer_add_extension(struct uaudio_softc *,
- const struct uaudio_terminal_node *, int);
-static struct usb2_audio_cluster uaudio_mixer_get_cluster(uint8_t,
- const struct uaudio_terminal_node *);
-static uint16_t uaudio_mixer_determine_class(const struct uaudio_terminal_node *,
- struct uaudio_mixer_node *);
-static uint16_t uaudio_mixer_feature_name(const struct uaudio_terminal_node *,
- struct uaudio_mixer_node *);
-static const struct uaudio_terminal_node *uaudio_mixer_get_input(
- const struct uaudio_terminal_node *, uint8_t);
-static const struct uaudio_terminal_node *uaudio_mixer_get_output(
- const struct uaudio_terminal_node *, uint8_t);
-static void uaudio_mixer_find_inputs_sub(struct uaudio_terminal_node *,
- const uint8_t *, uint8_t, struct uaudio_search_result *);
-static void uaudio_mixer_find_outputs_sub(struct uaudio_terminal_node *,
- uint8_t, uint8_t, struct uaudio_search_result *);
-static void uaudio_mixer_fill_info(struct uaudio_softc *,
- struct usb2_device *, void *);
-static uint16_t uaudio_mixer_get(struct usb2_device *, uint8_t,
- struct uaudio_mixer_node *);
-static void uaudio_mixer_ctl_set(struct uaudio_softc *,
- struct uaudio_mixer_node *, uint8_t, int32_t val);
-static usb2_error_t uaudio_set_speed(struct usb2_device *, uint8_t, uint32_t);
-static int uaudio_mixer_signext(uint8_t, int);
-static int uaudio_mixer_bsd2value(struct uaudio_mixer_node *, int32_t val);
-static const void *uaudio_mixer_verify_desc(const void *, uint32_t);
-static void uaudio_mixer_init(struct uaudio_softc *);
-static uint8_t umidi_convert_to_usb(struct umidi_sub_chan *, uint8_t, uint8_t);
-static struct umidi_sub_chan *umidi_sub_by_fifo(struct usb2_fifo *);
-static void umidi_start_read(struct usb2_fifo *);
-static void umidi_stop_read(struct usb2_fifo *);
-static void umidi_start_write(struct usb2_fifo *);
-static void umidi_stop_write(struct usb2_fifo *);
-static int umidi_open(struct usb2_fifo *, int, struct thread *);
-static int umidi_ioctl(struct usb2_fifo *, u_long cmd, void *, int, struct thread *);
-static void umidi_close(struct usb2_fifo *, int, struct thread *);
-static void umidi_init(device_t dev);
-static int32_t umidi_probe(device_t dev);
-static int32_t umidi_detach(device_t dev);
-
-#if USB_DEBUG
-static void uaudio_chan_dump_ep_desc(
- const usb2_endpoint_descriptor_audio_t *);
-static void uaudio_mixer_dump_cluster(uint8_t,
- const struct uaudio_terminal_node *);
-static const char *uaudio_mixer_get_terminal_name(uint16_t);
-#endif
-
-static const struct usb2_config
- uaudio_cfg_record[UAUDIO_NCHANBUFS] = {
- [0] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UAUDIO_MINFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &uaudio_chan_record_callback,
- },
-
- [1] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UAUDIO_MINFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &uaudio_chan_record_callback,
- },
-};
-
-static const struct usb2_config
- uaudio_cfg_play[UAUDIO_NCHANBUFS] = {
- [0] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UAUDIO_MINFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &uaudio_chan_play_callback,
- },
-
- [1] = {
- .type = UE_ISOCHRONOUS,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = 0, /* use "wMaxPacketSize * frames" */
- .mh.frames = UAUDIO_MINFRAMES,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &uaudio_chan_play_callback,
- },
-};
-
-static const struct usb2_config
- uaudio_mixer_config[1] = {
- [0] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = (sizeof(struct usb2_device_request) + 4),
- .mh.callback = &uaudio_mixer_write_cfg_callback,
- .mh.timeout = 1000, /* 1 second */
- },
-};
-
-static const
-uint8_t umidi_cmd_to_len[16] = {
- [0x0] = 0, /* reserved */
- [0x1] = 0, /* reserved */
- [0x2] = 2, /* bytes */
- [0x3] = 3, /* bytes */
- [0x4] = 3, /* bytes */
- [0x5] = 1, /* bytes */
- [0x6] = 2, /* bytes */
- [0x7] = 3, /* bytes */
- [0x8] = 3, /* bytes */
- [0x9] = 3, /* bytes */
- [0xA] = 3, /* bytes */
- [0xB] = 3, /* bytes */
- [0xC] = 2, /* bytes */
- [0xD] = 2, /* bytes */
- [0xE] = 3, /* bytes */
- [0xF] = 1, /* bytes */
-};
-
-static const struct usb2_config
- umidi_config[UMIDI_N_TRANSFER] = {
- [0] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UMIDI_BULK_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &umidi_bulk_write_callback,
- },
-
- [1] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UMIDI_BULK_SIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = &umidi_bulk_read_callback,
- },
-
- [2] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umidi_write_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
-
- [3] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umidi_read_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
-};
-
-static devclass_t uaudio_devclass;
-
-static device_method_t uaudio_methods[] = {
- DEVMETHOD(device_probe, uaudio_probe),
- DEVMETHOD(device_attach, uaudio_attach),
- DEVMETHOD(device_detach, uaudio_detach),
- 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),
- {0, 0}
-};
-
-static driver_t uaudio_driver = {
- .name = "uaudio",
- .methods = uaudio_methods,
- .size = sizeof(struct uaudio_softc),
-};
-
-static int
-uaudio_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
-
- if (uaa->use_generic == 0)
- return (ENXIO);
-
- /* trigger on the control interface */
-
- if ((uaa->info.bInterfaceClass == UICLASS_AUDIO) &&
- (uaa->info.bInterfaceSubClass == UISUBCLASS_AUDIOCONTROL)) {
- if (usb2_test_quirk(uaa, UQ_BAD_AUDIO))
- return (ENXIO);
- else
- return (0);
- }
- return (ENXIO);
-}
-
-static int
-uaudio_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct uaudio_softc *sc = device_get_softc(dev);
- struct usb2_interface_descriptor *id;
- device_t child;
-
- sc->sc_play_chan.priv_sc = sc;
- sc->sc_rec_chan.priv_sc = sc;
- sc->sc_udev = uaa->device;
-
- if (usb2_test_quirk(uaa, UQ_AUDIO_SWAP_LR))
- sc->sc_uq_audio_swap_lr = 1;
-
- if (usb2_test_quirk(uaa, UQ_AU_INP_ASYNC))
- sc->sc_uq_au_inp_async = 1;
-
- if (usb2_test_quirk(uaa, UQ_AU_NO_XU))
- sc->sc_uq_au_no_xu = 1;
-
- if (usb2_test_quirk(uaa, UQ_BAD_ADC))
- sc->sc_uq_bad_adc = 1;
-
- umidi_init(dev);
-
- device_set_usb2_desc(dev);
-
- id = usb2_get_interface_descriptor(uaa->iface);
-
- uaudio_chan_fill_info(sc, uaa->device);
-
- uaudio_mixer_fill_info(sc, uaa->device, id);
-
- sc->sc_mixer_iface_index = uaa->info.bIfaceIndex;
- sc->sc_mixer_iface_no = uaa->info.bIfaceNum;
-
- DPRINTF("audio rev %d.%02x\n",
- sc->sc_audio_rev >> 8,
- sc->sc_audio_rev & 0xff);
-
- DPRINTF("%d mixer controls\n",
- sc->sc_mixer_count);
-
- if (sc->sc_play_chan.valid) {
- device_printf(dev, "Play: %d Hz, %d ch, %s format\n",
- sc->sc_play_chan.sample_rate,
- sc->sc_play_chan.p_asf1d->bNrChannels,
- sc->sc_play_chan.p_fmt->description);
- } else {
- device_printf(dev, "No playback!\n");
- }
-
- if (sc->sc_rec_chan.valid) {
- device_printf(dev, "Record: %d Hz, %d ch, %s format\n",
- sc->sc_rec_chan.sample_rate,
- sc->sc_rec_chan.p_asf1d->bNrChannels,
- sc->sc_rec_chan.p_fmt->description);
- } else {
- device_printf(dev, "No recording!\n");
- }
-
- if (sc->sc_midi_chan.valid) {
-
- if (umidi_probe(dev)) {
- goto detach;
- }
- device_printf(dev, "MIDI sequencer\n");
- } else {
- device_printf(dev, "No midi sequencer\n");
- }
-
- DPRINTF("doing child attach\n");
-
- /* attach the children */
-
- sc->sc_sndcard_func.func = SCF_PCM;
-
- child = device_add_child(dev, "pcm", -1);
-
- if (child == NULL) {
- DPRINTF("out of memory\n");
- goto detach;
- }
- device_set_ivars(child, &sc->sc_sndcard_func);
-
- if (bus_generic_attach(dev)) {
- DPRINTF("child attach failed\n");
- goto detach;
- }
- return (0); /* success */
-
-detach:
- uaudio_detach(dev);
- return (ENXIO);
-}
-
-static void
-uaudio_pcm_setflags(device_t dev, uint32_t flags)
-{
- pcm_setflags(dev, pcm_getflags(dev) | flags);
-}
-
-int
-uaudio_attach_sub(device_t dev, kobj_class_t mixer_class, kobj_class_t chan_class)
-{
- struct uaudio_softc *sc = device_get_softc(device_get_parent(dev));
- char status[SND_STATUSLEN];
-
- uaudio_mixer_init(sc);
-
- if (sc->sc_uq_audio_swap_lr) {
- DPRINTF("hardware has swapped left and right\n");
- uaudio_pcm_setflags(dev, SD_F_PSWAPLR);
- }
- if (!(sc->sc_mix_info & SOUND_MASK_PCM)) {
-
- DPRINTF("emulating master volume\n");
-
- /*
- * Emulate missing pcm mixer controller
- * through FEEDER_VOLUME
- */
- uaudio_pcm_setflags(dev, SD_F_SOFTPCMVOL);
- }
- if (mixer_init(dev, mixer_class, sc)) {
- goto detach;
- }
- sc->sc_mixer_init = 1;
-
- snprintf(status, sizeof(status), "at ? %s", PCM_KLDSTRING(snd_uaudio));
-
- if (pcm_register(dev, sc,
- sc->sc_play_chan.valid ? 1 : 0,
- sc->sc_rec_chan.valid ? 1 : 0)) {
- goto detach;
- }
- sc->sc_pcm_registered = 1;
-
- if (sc->sc_play_chan.valid) {
- pcm_addchan(dev, PCMDIR_PLAY, chan_class, sc);
- }
- if (sc->sc_rec_chan.valid) {
- pcm_addchan(dev, PCMDIR_REC, chan_class, sc);
- }
- pcm_setstatus(dev, status);
-
- return (0); /* success */
-
-detach:
- uaudio_detach_sub(dev);
- return (ENXIO);
-}
-
-int
-uaudio_detach_sub(device_t dev)
-{
- struct uaudio_softc *sc = device_get_softc(device_get_parent(dev));
- int error = 0;
-
-repeat:
- if (sc->sc_pcm_registered) {
- error = pcm_unregister(dev);
- } else {
- if (sc->sc_mixer_init) {
- error = mixer_uninit(dev);
- }
- }
-
- if (error) {
- device_printf(dev, "Waiting for sound application to exit!\n");
- usb2_pause_mtx(NULL, 2 * hz);
- goto repeat; /* try again */
- }
- return (0); /* success */
-}
-
-static int
-uaudio_detach(device_t dev)
-{
- struct uaudio_softc *sc = device_get_softc(dev);
-
- if (bus_generic_detach(dev)) {
- DPRINTF("detach failed!\n");
- }
- sbuf_delete(&sc->sc_sndstat);
- sc->sc_sndstat_valid = 0;
-
- umidi_detach(dev);
-
- return (0);
-}
-
-/*========================================================================*
- * AS - Audio Stream - routines
- *========================================================================*/
-
-#if USB_DEBUG
-static void
-uaudio_chan_dump_ep_desc(const usb2_endpoint_descriptor_audio_t *ed)
-{
- if (ed) {
- DPRINTF("endpoint=%p bLength=%d bDescriptorType=%d \n"
- "bEndpointAddress=%d bmAttributes=0x%x \n"
- "wMaxPacketSize=%d bInterval=%d \n"
- "bRefresh=%d bSynchAddress=%d\n",
- ed, ed->bLength, ed->bDescriptorType,
- ed->bEndpointAddress, ed->bmAttributes,
- UGETW(ed->wMaxPacketSize), ed->bInterval,
- ed->bRefresh, ed->bSynchAddress);
- }
-}
-
-#endif
-
-static void
-uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb2_device *udev,
- uint32_t rate, uint16_t fps, uint8_t channels,
- uint8_t bit_resolution)
-{
- struct usb2_descriptor *desc = NULL;
- const struct usb2_audio_streaming_interface_descriptor *asid = NULL;
- const struct usb2_audio_streaming_type1_descriptor *asf1d = NULL;
- const struct usb2_audio_streaming_endpoint_descriptor *sed = NULL;
- const usb2_endpoint_descriptor_audio_t *ed1 = NULL;
- const usb2_endpoint_descriptor_audio_t *ed2 = NULL;
- struct usb2_config_descriptor *cd = usb2_get_config_descriptor(udev);
- struct usb2_interface_descriptor *id;
- const struct uaudio_format *p_fmt;
- struct uaudio_chan *chan;
- uint16_t curidx = 0xFFFF;
- uint16_t lastidx = 0xFFFF;
- uint16_t alt_index = 0;
- uint16_t wFormat;
- uint8_t ep_dir;
- uint8_t ep_type;
- uint8_t ep_sync;
- uint8_t bChannels;
- uint8_t bBitResolution;
- uint8_t x;
- uint8_t audio_if = 0;
- uint8_t sample_size;
-
- while ((desc = usb2_desc_foreach(cd, desc))) {
-
- if ((desc->bDescriptorType == UDESC_INTERFACE) &&
- (desc->bLength >= sizeof(*id))) {
-
- id = (void *)desc;
-
- if (id->bInterfaceNumber != lastidx) {
- lastidx = id->bInterfaceNumber;
- curidx++;
- alt_index = 0;
-
- } else {
- alt_index++;
- }
-
- if ((id->bInterfaceClass == UICLASS_AUDIO) &&
- (id->bInterfaceSubClass == UISUBCLASS_AUDIOSTREAM)) {
- audio_if = 1;
- } else {
- audio_if = 0;
- }
-
- if ((id->bInterfaceClass == UICLASS_AUDIO) &&
- (id->bInterfaceSubClass == UISUBCLASS_MIDISTREAM)) {
-
- /*
- * XXX could allow multiple MIDI interfaces
- * XXX
- */
-
- if ((sc->sc_midi_chan.valid == 0) &&
- usb2_get_iface(udev, curidx)) {
- sc->sc_midi_chan.iface_index = curidx;
- sc->sc_midi_chan.iface_alt_index = alt_index;
- sc->sc_midi_chan.valid = 1;
- }
- }
- asid = NULL;
- asf1d = NULL;
- ed1 = NULL;
- ed2 = NULL;
- sed = NULL;
- }
- if ((desc->bDescriptorType == UDESC_CS_INTERFACE) &&
- (desc->bDescriptorSubtype == AS_GENERAL) &&
- (desc->bLength >= sizeof(*asid))) {
- if (asid == NULL) {
- asid = (void *)desc;
- }
- }
- if ((desc->bDescriptorType == UDESC_CS_INTERFACE) &&
- (desc->bDescriptorSubtype == FORMAT_TYPE) &&
- (desc->bLength >= sizeof(*asf1d))) {
- if (asf1d == NULL) {
- asf1d = (void *)desc;
- if (asf1d->bFormatType != FORMAT_TYPE_I) {
- DPRINTFN(11, "ignored bFormatType = %d\n",
- asf1d->bFormatType);
- asf1d = NULL;
- continue;
- }
- if (asf1d->bLength < (sizeof(*asf1d) +
- (asf1d->bSamFreqType == 0) ? 6 :
- (asf1d->bSamFreqType * 3))) {
- DPRINTFN(11, "'asf1d' descriptor is too short\n");
- asf1d = NULL;
- continue;
- }
- }
- }
- if ((desc->bDescriptorType == UDESC_ENDPOINT) &&
- (desc->bLength >= sizeof(*ed1))) {
- if (ed1 == NULL) {
- ed1 = (void *)desc;
- if (UE_GET_XFERTYPE(ed1->bmAttributes) != UE_ISOCHRONOUS) {
- ed1 = NULL;
- }
- } else {
- if (ed2 == NULL) {
- ed2 = (void *)desc;
- if (UE_GET_XFERTYPE(ed2->bmAttributes) != UE_ISOCHRONOUS) {
- ed2 = NULL;
- continue;
- }
- if (ed2->bSynchAddress != 0) {
- DPRINTFN(11, "invalid endpoint: bSynchAddress != 0\n");
- ed2 = NULL;
- continue;
- }
- if (ed2->bEndpointAddress != ed1->bSynchAddress) {
- DPRINTFN(11, "invalid endpoint addresses: "
- "ep[0]->bSynchAddress=0x%x "
- "ep[1]->bEndpointAddress=0x%x\n",
- ed1->bSynchAddress,
- ed2->bEndpointAddress);
- ed2 = NULL;
- continue;
- }
- }
- }
- }
- if ((desc->bDescriptorType == UDESC_CS_ENDPOINT) &&
- (desc->bDescriptorSubtype == AS_GENERAL) &&
- (desc->bLength >= sizeof(*sed))) {
- if (sed == NULL) {
- sed = (void *)desc;
- }
- }
- if (audio_if && asid && asf1d && ed1 && sed) {
-
- ep_dir = UE_GET_DIR(ed1->bEndpointAddress);
- ep_type = UE_GET_ISO_TYPE(ed1->bmAttributes);
- ep_sync = 0;
-
- if ((sc->sc_uq_au_inp_async) &&
- (ep_dir == UE_DIR_IN) && (ep_type == UE_ISO_ADAPT)) {
- ep_type = UE_ISO_ASYNC;
- }
- if ((ep_dir == UE_DIR_IN) && (ep_type == UE_ISO_ADAPT)) {
- ep_sync = 1;
- }
- if ((ep_dir != UE_DIR_IN) && (ep_type == UE_ISO_ASYNC)) {
- ep_sync = 1;
- }
- /* Ignore sync endpoint information until further. */
-#if 0
- if (ep_sync && (!ed2)) {
- continue;
- }
- /*
- * we can't handle endpoints that need a sync pipe
- * yet
- */
-
- if (ep_sync) {
- DPRINTF("skipped sync interface\n");
- audio_if = 0;
- continue;
- }
-#endif
-
- wFormat = UGETW(asid->wFormatTag);
- bChannels = asf1d->bNrChannels;
- bBitResolution = asf1d->bBitResolution;
-
- if (asf1d->bSamFreqType == 0) {
- DPRINTFN(16, "Sample rate: %d-%dHz\n",
- UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
-
- if ((rate >= UA_SAMP_LO(asf1d)) &&
- (rate <= UA_SAMP_HI(asf1d))) {
- goto found_rate;
- }
- } else {
-
- for (x = 0; x < asf1d->bSamFreqType; x++) {
- DPRINTFN(16, "Sample rate = %dHz\n",
- UA_GETSAMP(asf1d, x));
-
- if (rate == UA_GETSAMP(asf1d, x)) {
- goto found_rate;
- }
- }
- }
-
- audio_if = 0;
- continue;
-
- found_rate:
-
- for (p_fmt = uaudio_formats;
- p_fmt->wFormat;
- p_fmt++) {
- if ((p_fmt->wFormat == wFormat) &&
- (p_fmt->bPrecision == bBitResolution)) {
- goto found_format;
- }
- }
-
- audio_if = 0;
- continue;
-
- found_format:
-
- if ((bChannels == channels) &&
- (bBitResolution == bit_resolution)) {
-
- chan = (ep_dir == UE_DIR_IN) ?
- &sc->sc_rec_chan :
- &sc->sc_play_chan;
-
- if ((chan->valid == 0) && usb2_get_iface(udev, curidx)) {
-
- chan->valid = 1;
-#if USB_DEBUG
- uaudio_chan_dump_ep_desc(ed1);
- uaudio_chan_dump_ep_desc(ed2);
-
- if (sed->bmAttributes & UA_SED_FREQ_CONTROL) {
- DPRINTFN(2, "FREQ_CONTROL\n");
- }
- if (sed->bmAttributes & UA_SED_PITCH_CONTROL) {
- DPRINTFN(2, "PITCH_CONTROL\n");
- }
-#endif
- DPRINTF("Sample rate = %dHz, channels = %d, "
- "bits = %d, format = %s\n", rate, channels,
- bit_resolution, p_fmt->description);
-
- chan->sample_rate = rate;
- chan->p_asid = asid;
- chan->p_asf1d = asf1d;
- chan->p_ed1 = ed1;
- chan->p_ed2 = ed2;
- chan->p_fmt = p_fmt;
- chan->p_sed = sed;
- chan->iface_index = curidx;
- chan->iface_alt_index = alt_index;
-
- if (ep_dir == UE_DIR_IN)
- chan->usb2_cfg =
- uaudio_cfg_record;
- else
- chan->usb2_cfg =
- uaudio_cfg_play;
-
- sample_size = ((chan->p_asf1d->bNrChannels *
- chan->p_asf1d->bBitResolution) / 8);
-
- /*
- * NOTE: "chan->bytes_per_frame"
- * should not be zero!
- */
- chan->bytes_per_frame = ((rate / fps) * sample_size);
-
- if (sc->sc_sndstat_valid) {
- sbuf_printf(&sc->sc_sndstat, "\n\t"
- "mode %d.%d:(%s) %dch, %d/%dbit, %s, %dHz",
- curidx, alt_index,
- (ep_dir == UE_DIR_IN) ? "input" : "output",
- asf1d->bNrChannels, asf1d->bBitResolution,
- asf1d->bSubFrameSize * 8,
- p_fmt->description, rate);
- }
- }
- }
- audio_if = 0;
- continue;
- }
- }
-}
-
-static void
-uaudio_chan_fill_info(struct uaudio_softc *sc, struct usb2_device *udev)
-{
- uint32_t rate = uaudio_default_rate;
- uint32_t z;
- uint16_t fps = usb2_get_isoc_fps(udev);
- uint8_t bits = uaudio_default_bits;
- uint8_t y;
- uint8_t channels = uaudio_default_channels;
- uint8_t x;
-
- bits -= (bits % 8);
- if ((bits == 0) || (bits > 32)) {
- /* set a valid value */
- bits = 32;
- }
- rate -= (rate % fps);
- if ((rate == 0) || (rate > 192000)) {
- /* set a valid value */
- rate = 192000 - (192000 % fps);
- }
- if ((channels == 0) || (channels > 2)) {
- /* set a valid value */
- channels = 2;
- }
- if (sbuf_new(&sc->sc_sndstat, NULL, 4096, SBUF_AUTOEXTEND)) {
- sc->sc_sndstat_valid = 1;
- }
- /* try to search for a valid config */
-
- for (x = channels; x; x--) {
- for (y = bits; y; y -= 8) {
- for (z = rate; z; z -= fps) {
- uaudio_chan_fill_info_sub(sc, udev, z, fps, x, y);
-
- if (sc->sc_rec_chan.valid &&
- sc->sc_play_chan.valid) {
- goto done;
- }
- }
- }
- }
-
-done:
- if (sc->sc_sndstat_valid) {
- sbuf_finish(&sc->sc_sndstat);
- }
-}
-
-static void
-uaudio_chan_play_callback(struct usb2_xfer *xfer)
-{
- struct uaudio_chan *ch = xfer->priv_sc;
- uint32_t *p_len = xfer->frlengths;
- uint32_t total;
- uint32_t blockcount;
- uint32_t n;
- uint32_t offset;
-
- /* allow dynamic sizing of play buffer */
- total = ch->intr_size;
-
- /* allow dynamic sizing of play buffer */
- blockcount = total / ch->bytes_per_frame;
-
- /* align units */
- blockcount -= (blockcount % UAUDIO_MINFRAMES);
-
- /* range check - min */
- if (blockcount == 0) {
- blockcount = UAUDIO_MINFRAMES;
- }
- /* range check - max */
- if (blockcount > xfer->max_frame_count) {
- blockcount = xfer->max_frame_count;
- }
- /* compute the total length */
- total = blockcount * ch->bytes_per_frame;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-tr_transferred:
- if (xfer->actlen < xfer->sumlen) {
- DPRINTF("short transfer, "
- "%d of %d bytes\n", xfer->actlen, total);
- }
- chn_intr(ch->pcm_ch);
-
- case USB_ST_SETUP:
- if (ch->bytes_per_frame > xfer->max_frame_size) {
- DPRINTF("bytes per transfer, %d, "
- "exceeds maximum, %d!\n",
- ch->bytes_per_frame,
- xfer->max_frame_size);
- break;
- }
- /* setup frame length */
- xfer->nframes = blockcount;
- for (n = 0; n != blockcount; n++) {
- p_len[n] = ch->bytes_per_frame;
- }
-
- if (ch->end == ch->start) {
- DPRINTF("no buffer!\n");
- break;
- }
- DPRINTFN(6, "transfer %d bytes\n", total);
-
- offset = 0;
-
- while (total > 0) {
-
- n = (ch->end - ch->cur);
- if (n > total) {
- n = total;
- }
- usb2_copy_in(xfer->frbuffers, offset, ch->cur, n);
-
- total -= n;
- ch->cur += n;
- offset += n;
-
- if (ch->cur >= ch->end) {
- ch->cur = ch->start;
- }
- }
-
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- break;
- }
- goto tr_transferred;
- }
-}
-
-static void
-uaudio_chan_record_callback(struct usb2_xfer *xfer)
-{
- struct uaudio_chan *ch = xfer->priv_sc;
- uint32_t *p_len = xfer->frlengths;
- uint32_t n;
- uint32_t m;
- uint32_t total;
- uint32_t blockcount;
- uint32_t offset0;
- uint32_t offset1;
-
- /* allow dynamic sizing of play buffer */
- total = ch->intr_size;
-
- /* allow dynamic sizing of play buffer */
- blockcount = total / ch->bytes_per_frame;
-
- /* align units */
- blockcount -= (blockcount % UAUDIO_MINFRAMES);
-
- /* range check - min */
- if (blockcount == 0) {
- blockcount = UAUDIO_MINFRAMES;
- }
- /* range check - max */
- if (blockcount > xfer->max_frame_count) {
- blockcount = xfer->max_frame_count;
- }
- /* compute the total length */
- total = blockcount * ch->bytes_per_frame;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-tr_transferred:
- if (xfer->actlen < total) {
- DPRINTF("short transfer, "
- "%d of %d bytes\n", xfer->actlen, total);
- } else {
- DPRINTFN(6, "transferred %d bytes\n", xfer->actlen);
- }
-
- offset0 = 0;
-
- for (n = 0; n != xfer->nframes; n++) {
-
- offset1 = offset0;
-
- while (p_len[n] > 0) {
-
- m = (ch->end - ch->cur);
-
- if (m > p_len[n]) {
- m = p_len[n];
- }
- usb2_copy_out(xfer->frbuffers, offset1, ch->cur, m);
-
- p_len[n] -= m;
- offset1 += m;
- ch->cur += m;
-
- if (ch->cur >= ch->end) {
- ch->cur = ch->start;
- }
- }
-
- offset0 += ch->bytes_per_frame;
- }
-
- chn_intr(ch->pcm_ch);
-
- case USB_ST_SETUP:
- if (ch->bytes_per_frame > xfer->max_frame_size) {
- DPRINTF("bytes per transfer, %d, "
- "exceeds maximum, %d!\n",
- ch->bytes_per_frame,
- xfer->max_frame_size);
- return;
- }
- xfer->nframes = blockcount;
- for (n = 0; n != xfer->nframes; n++) {
- p_len[n] = ch->bytes_per_frame;
- }
-
- if (ch->end == ch->start) {
- DPRINTF("no buffer!\n");
- return;
- }
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- return;
- }
- goto tr_transferred;
- }
-}
-
-void *
-uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b,
- struct pcm_channel *c, int dir)
-{
- struct uaudio_chan *ch = ((dir == PCMDIR_PLAY) ?
- &sc->sc_play_chan : &sc->sc_rec_chan);
- uint32_t buf_size;
- uint8_t endpoint;
- uint8_t iface_index;
- uint8_t alt_index;
- usb2_error_t err;
-
- /* compute required buffer size */
- buf_size = (ch->bytes_per_frame * UAUDIO_MINFRAMES);
-
- /* setup interrupt interval */
- ch->intr_size = buf_size;
-
- /* double buffering */
- buf_size *= 2;
-
- ch->buf = malloc(buf_size, M_DEVBUF, M_WAITOK | M_ZERO);
- if (ch->buf == NULL) {
- goto error;
- }
- if (sndbuf_setup(b, ch->buf, buf_size) != 0) {
- goto error;
- }
- ch->start = ch->buf;
- ch->end = ch->buf + buf_size;
- ch->cur = ch->buf;
- ch->pcm_ch = c;
- ch->pcm_mtx = c->lock;
- ch->pcm_buf = b;
-
- if (ch->pcm_mtx == NULL) {
- DPRINTF("ERROR: PCM channels does not have a mutex!\n");
- goto error;
- }
- /* setup play/record format */
-
- ch->pcm_cap.fmtlist = ch->pcm_format;
-
- ch->pcm_format[0] = 0;
- ch->pcm_format[1] = 0;
-
- ch->pcm_cap.minspeed = ch->sample_rate;
- ch->pcm_cap.maxspeed = ch->sample_rate;
-
- ch->pcm_cap.fmtlist[0] = ch->p_fmt->freebsd_fmt;
-
- if (ch->p_asf1d->bNrChannels == 2) {
- ch->pcm_cap.fmtlist[0] |= AFMT_STEREO;
- }
- ch->pcm_cap.fmtlist[1] = 0;
-
-
- /* set alternate interface corresponding to the mode */
-
- endpoint = ch->p_ed1->bEndpointAddress;
- iface_index = ch->iface_index;
- alt_index = ch->iface_alt_index;
-
- DPRINTF("endpoint=0x%02x, speed=%d, iface=%d alt=%d\n",
- endpoint, ch->sample_rate, iface_index, alt_index);
-
- err = usb2_set_alt_interface_index(sc->sc_udev, iface_index, alt_index);
- if (err) {
- DPRINTF("setting of alternate index failed: %s!\n",
- usb2_errstr(err));
- goto error;
- }
- usb2_set_parent_iface(sc->sc_udev, iface_index, sc->sc_mixer_iface_index);
-
- /*
- * 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 (ch->p_asf1d->bSamFreqType != 1) {
- if (uaudio_set_speed(sc->sc_udev, endpoint, ch->sample_rate)) {
- /*
- * If the endpoint is adaptive setting the speed may
- * fail.
- */
- DPRINTF("setting of sample rate failed! (continuing anyway)\n");
- }
- }
- if (usb2_transfer_setup(sc->sc_udev, &iface_index, ch->xfer,
- ch->usb2_cfg, UAUDIO_NCHANBUFS, ch, ch->pcm_mtx)) {
- DPRINTF("could not allocate USB transfers!\n");
- goto error;
- }
- return (ch);
-
-error:
- uaudio_chan_free(ch);
- return (NULL);
-}
-
-int
-uaudio_chan_free(struct uaudio_chan *ch)
-{
- if (ch->buf != NULL) {
- free(ch->buf, M_DEVBUF);
- ch->buf = NULL;
- }
- usb2_transfer_unsetup(ch->xfer, UAUDIO_NCHANBUFS);
-
- ch->valid = 0;
-
- return (0);
-}
-
-int
-uaudio_chan_set_param_blocksize(struct uaudio_chan *ch, uint32_t blocksize)
-{
- uaudio_chan_set_param_fragments(ch, blocksize, 0 - 1);
-
- return (ch->block_size);
-}
-
-int
-uaudio_chan_set_param_fragments(struct uaudio_chan *ch, uint32_t blocksize,
- uint32_t blockcount)
-{
- /* we only support one size */
- blocksize = ch->intr_size;
- blockcount = 2;
-
- if ((sndbuf_getblksz(ch->pcm_buf) != blocksize) ||
- (sndbuf_getblkcnt(ch->pcm_buf) != blockcount)) {
- DPRINTFN(1, "resizing to %u x "
- "%u bytes\n", blockcount, blocksize);
- if (sndbuf_resize(ch->pcm_buf, blockcount, blocksize)) {
- DPRINTFN(0, "failed to resize sound buffer, count=%u, "
- "size=%u\n", blockcount, blocksize);
- }
- }
- ch->block_size = sndbuf_getblksz(ch->pcm_buf);
-
- return (1);
-}
-
-int
-uaudio_chan_set_param_speed(struct uaudio_chan *ch, uint32_t speed)
-{
- if (speed != ch->sample_rate) {
- DPRINTF("rate conversion required\n");
- }
- return (ch->sample_rate);
-}
-
-int
-uaudio_chan_getptr(struct uaudio_chan *ch)
-{
- return (ch->cur - ch->start);
-}
-
-struct pcmchan_caps *
-uaudio_chan_getcaps(struct uaudio_chan *ch)
-{
- return (&ch->pcm_cap);
-}
-
-int
-uaudio_chan_set_param_format(struct uaudio_chan *ch, uint32_t format)
-{
- ch->format = format;
- return (0);
-}
-
-int
-uaudio_chan_start(struct uaudio_chan *ch)
-{
- ch->cur = ch->start;
-
-#if (UAUDIO_NCHANBUFS != 2)
-#error "please update code"
-#endif
- if (ch->xfer[0]) {
- usb2_transfer_start(ch->xfer[0]);
- }
- if (ch->xfer[1]) {
- usb2_transfer_start(ch->xfer[1]);
- }
- return (0);
-}
-
-int
-uaudio_chan_stop(struct uaudio_chan *ch)
-{
-#if (UAUDIO_NCHANBUFS != 2)
-#error "please update code"
-#endif
- usb2_transfer_stop(ch->xfer[0]);
- usb2_transfer_stop(ch->xfer[1]);
- return (0);
-}
-
-/*========================================================================*
- * AC - Audio Controller - routines
- *========================================================================*/
-
-static void
-uaudio_mixer_add_ctl_sub(struct uaudio_softc *sc, struct uaudio_mixer_node *mc)
-{
- struct uaudio_mixer_node *p_mc_new =
- malloc(sizeof(*p_mc_new), M_USBDEV, M_WAITOK);
-
- if (p_mc_new) {
- bcopy(mc, p_mc_new, sizeof(*p_mc_new));
- p_mc_new->next = sc->sc_mixer_root;
- sc->sc_mixer_root = p_mc_new;
- sc->sc_mixer_count++;
- } else {
- DPRINTF("out of memory\n");
- }
-}
-
-static void
-uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct uaudio_mixer_node *mc)
-{
- int32_t res;
-
- if (mc->class < UAC_NCLASSES) {
- DPRINTF("adding %s.%d\n",
- uac_names[mc->class], mc->ctl);
- } else {
- DPRINTF("adding %d\n", mc->ctl);
- }
-
- 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_mixer_get(sc->sc_udev, GET_MIN, mc);
-
- mc->minval = uaudio_mixer_signext(mc->type, mc->minval);
-
- mc->maxval = uaudio_mixer_get(sc->sc_udev, GET_MAX, mc);
-
- mc->maxval = 1 + uaudio_mixer_signext(mc->type, mc->maxval);
-
- mc->mul = mc->maxval - mc->minval;
- if (mc->mul == 0) {
- mc->mul = 1;
- }
- res = uaudio_mixer_get(sc->sc_udev, GET_RES, mc);
- if (res > 0) {
- mc->delta = ((res * 255) + (mc->mul / 2)) / mc->mul;
- }
- }
-
- if (mc->maxval < mc->minval) {
- mc->maxval = mc->minval;
- }
- uaudio_mixer_add_ctl_sub(sc, mc);
-
-#if USB_DEBUG
- if (uaudio_debug > 2) {
- uint8_t i;
-
- for (i = 0; i < mc->nchan; i++) {
- DPRINTF("[mix] wValue=%04x\n", mc->wValue[0]);
- }
- DPRINTF("[mix] wIndex=%04x type=%d ctl='%d' "
- "min=%d max=%d\n",
- mc->wIndex, mc->type, mc->ctl,
- mc->minval, mc->maxval);
- }
-#endif
-}
-
-static void
-uaudio_mixer_add_input(struct uaudio_softc *sc,
- const struct uaudio_terminal_node *iot, int id)
-{
-#if USB_DEBUG
- const struct usb2_audio_input_terminal *d = iot[id].u.it;
-
- DPRINTFN(3, "bTerminalId=%d wTerminalType=0x%04x "
- "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
- "iChannelNames=%d\n",
- d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
- d->bNrChannels, UGETW(d->wChannelConfig),
- d->iChannelNames);
-#endif
-}
-
-static void
-uaudio_mixer_add_output(struct uaudio_softc *sc,
- const struct uaudio_terminal_node *iot, int id)
-{
-#if USB_DEBUG
- const struct usb2_audio_output_terminal *d = iot[id].u.ot;
-
- DPRINTFN(3, "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_mixer_add_mixer(struct uaudio_softc *sc,
- const struct uaudio_terminal_node *iot, int id)
-{
- struct uaudio_mixer_node mix;
-
- const struct usb2_audio_mixer_unit_0 *d0 = iot[id].u.mu;
- const struct usb2_audio_mixer_unit_1 *d1;
-
- uint32_t bno; /* bit number */
- uint32_t p; /* bit number accumulator */
- uint32_t mo; /* matching outputs */
- uint32_t mc; /* matching channels */
- uint32_t ichs; /* input channels */
- uint32_t ochs; /* output channels */
- uint32_t c;
- uint32_t chs; /* channels */
- uint32_t i;
- uint32_t o;
-
- DPRINTFN(3, "bUnitId=%d bNrInPins=%d\n",
- d0->bUnitId, d0->bNrInPins);
-
- /* compute the number of input channels */
-
- ichs = 0;
- for (i = 0; i < d0->bNrInPins; i++) {
- ichs += (uaudio_mixer_get_cluster(d0->baSourceId[i], iot)
- .bNrChannels);
- }
-
- d1 = (const void *)(d0->baSourceId + d0->bNrInPins);
-
- /* and the number of output channels */
-
- ochs = d1->bNrChannels;
-
- DPRINTFN(3, "ichs=%d ochs=%d\n", ichs, ochs);
-
- bzero(&mix, sizeof(mix));
-
- mix.wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no);
- uaudio_mixer_determine_class(&iot[id], &mix);
- mix.type = MIX_SIGNED_16;
-
- if (uaudio_mixer_verify_desc(d0, ((ichs * ochs) + 7) / 8) == NULL) {
- return;
- }
- for (p = i = 0; i < d0->bNrInPins; i++) {
- chs = uaudio_mixer_get_cluster(d0->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_TEST(d1->bmControls, bno)) {
- mo++;
- }
- }
- if (mo == 1) {
- mc++;
- }
- }
- if ((mc == chs) && (chs <= MIX_MAX_CHAN)) {
-
- /* repeat bit-scan */
-
- mc = 0;
- for (c = 0; c < chs; c++) {
- for (o = 0; o < ochs; o++) {
- bno = ((p + c) * ochs) + o;
- if (BIT_TEST(d1->bmControls, bno)) {
- mix.wValue[mc++] = MAKE_WORD(p + c + 1, o + 1);
- }
- }
- }
- mix.nchan = chs;
- uaudio_mixer_add_ctl(sc, &mix);
- } else {
- /* XXX */
- }
- p += chs;
- }
-}
-
-static void
-uaudio_mixer_add_selector(struct uaudio_softc *sc,
- const struct uaudio_terminal_node *iot, int id)
-{
- const struct usb2_audio_selector_unit *d = iot[id].u.su;
- struct uaudio_mixer_node mix;
- uint16_t i;
-
- DPRINTFN(3, "bUnitId=%d bNrInPins=%d\n",
- d->bUnitId, d->bNrInPins);
-
- if (d->bNrInPins == 0) {
- return;
- }
- bzero(&mix, sizeof(mix));
-
- mix.wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no);
- mix.wValue[0] = MAKE_WORD(0, 0);
- uaudio_mixer_determine_class(&iot[id], &mix);
- mix.nchan = 1;
- mix.type = MIX_SELECTOR;
-
- mix.ctl = SOUND_MIXER_NRDEVICES;
- mix.minval = 1;
- mix.maxval = d->bNrInPins;
-
- if (mix.maxval > MAX_SELECTOR_INPUT_PIN) {
- mix.maxval = MAX_SELECTOR_INPUT_PIN;
- }
- mix.mul = (mix.maxval - mix.minval);
- for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) {
- mix.slctrtype[i] = SOUND_MIXER_NRDEVICES;
- }
-
- for (i = 0; i < mix.maxval; i++) {
- mix.slctrtype[i] = uaudio_mixer_feature_name
- (&iot[d->baSourceId[i]], &mix);
- }
-
- mix.class = 0; /* not used */
-
- uaudio_mixer_add_ctl(sc, &mix);
-}
-
-static uint32_t
-uaudio_mixer_feature_get_bmaControls(const struct usb2_audio_feature_unit *d,
- uint8_t index)
-{
- uint32_t temp = 0;
- uint32_t offset = (index * d->bControlSize);
-
- if (d->bControlSize > 0) {
- temp |= d->bmaControls[offset];
- if (d->bControlSize > 1) {
- temp |= d->bmaControls[offset + 1] << 8;
- if (d->bControlSize > 2) {
- temp |= d->bmaControls[offset + 2] << 16;
- if (d->bControlSize > 3) {
- temp |= d->bmaControls[offset + 3] << 24;
- }
- }
- }
- }
- return (temp);
-}
-
-static void
-uaudio_mixer_add_feature(struct uaudio_softc *sc,
- const struct uaudio_terminal_node *iot, int id)
-{
- const struct usb2_audio_feature_unit *d = iot[id].u.fu;
- struct uaudio_mixer_node mix;
- uint32_t fumask;
- uint32_t mmask;
- uint32_t cmask;
- uint16_t mixernumber;
- uint8_t nchan;
- uint8_t chan;
- uint8_t ctl;
- uint8_t i;
-
- if (d->bControlSize == 0) {
- return;
- }
- bzero(&mix, sizeof(mix));
-
- nchan = (d->bLength - 7) / d->bControlSize;
- mmask = uaudio_mixer_feature_get_bmaControls(d, 0);
- cmask = 0;
-
- if (nchan == 0) {
- return;
- }
- /* figure out what we can control */
-
- for (chan = 1; chan < nchan; chan++) {
- DPRINTFN(10, "chan=%d mask=%x\n",
- chan, uaudio_mixer_feature_get_bmaControls(d, chan));
-
- cmask |= uaudio_mixer_feature_get_bmaControls(d, chan);
- }
-
- if (nchan > MIX_MAX_CHAN) {
- nchan = MIX_MAX_CHAN;
- }
- mix.wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no);
-
- for (ctl = 1; ctl <= LOUDNESS_CONTROL; ctl++) {
-
- fumask = FU_MASK(ctl);
-
- DPRINTFN(5, "ctl=%d fumask=0x%04x\n",
- ctl, fumask);
-
- if (mmask & fumask) {
- mix.nchan = 1;
- mix.wValue[0] = MAKE_WORD(ctl, 0);
- } else if (cmask & fumask) {
- mix.nchan = nchan - 1;
- for (i = 1; i < nchan; i++) {
- if (uaudio_mixer_feature_get_bmaControls(d, i) & fumask)
- mix.wValue[i - 1] = MAKE_WORD(ctl, i);
- else
- mix.wValue[i - 1] = -1;
- }
- } else {
- continue;
- }
-
- mixernumber = uaudio_mixer_feature_name(&iot[id], &mix);
-
- switch (ctl) {
- case MUTE_CONTROL:
- mix.type = MIX_ON_OFF;
- mix.ctl = SOUND_MIXER_NRDEVICES;
- break;
-
- case VOLUME_CONTROL:
- mix.type = MIX_SIGNED_16;
- mix.ctl = mixernumber;
- break;
-
- case BASS_CONTROL:
- mix.type = MIX_SIGNED_8;
- mix.ctl = SOUND_MIXER_BASS;
- break;
-
- case MID_CONTROL:
- mix.type = MIX_SIGNED_8;
- mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
- break;
-
- case TREBLE_CONTROL:
- mix.type = MIX_SIGNED_8;
- mix.ctl = SOUND_MIXER_TREBLE;
- break;
-
- case GRAPHIC_EQUALIZER_CONTROL:
- continue; /* XXX don't add anything */
- break;
-
- case AGC_CONTROL:
- mix.type = MIX_ON_OFF;
- mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
- break;
-
- case DELAY_CONTROL:
- mix.type = MIX_UNSIGNED_16;
- mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
- break;
-
- case BASS_BOOST_CONTROL:
- mix.type = MIX_ON_OFF;
- mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
- break;
-
- case LOUDNESS_CONTROL:
- mix.type = MIX_ON_OFF;
- mix.ctl = SOUND_MIXER_LOUD; /* Is this correct ? */
- break;
-
- default:
- mix.type = MIX_UNKNOWN;
- break;
- }
-
- if (mix.type != MIX_UNKNOWN) {
- uaudio_mixer_add_ctl(sc, &mix);
- }
- }
-}
-
-static void
-uaudio_mixer_add_processing_updown(struct uaudio_softc *sc,
- const struct uaudio_terminal_node *iot, int id)
-{
- const struct usb2_audio_processing_unit_0 *d0 = iot[id].u.pu;
- const struct usb2_audio_processing_unit_1 *d1 =
- (const void *)(d0->baSourceId + d0->bNrInPins);
- const struct usb2_audio_processing_unit_updown *ud =
- (const void *)(d1->bmControls + d1->bControlSize);
- struct uaudio_mixer_node mix;
- uint8_t i;
-
- if (uaudio_mixer_verify_desc(d0, sizeof(*ud)) == NULL) {
- return;
- }
- if (uaudio_mixer_verify_desc(d0, sizeof(*ud) + (2 * ud->bNrModes))
- == NULL) {
- return;
- }
- DPRINTFN(3, "bUnitId=%d bNrModes=%d\n",
- d0->bUnitId, ud->bNrModes);
-
- if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
- DPRINTF("no mode select\n");
- return;
- }
- bzero(&mix, sizeof(mix));
-
- mix.wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no);
- mix.nchan = 1;
- mix.wValue[0] = MAKE_WORD(UD_MODE_SELECT_CONTROL, 0);
- uaudio_mixer_determine_class(&iot[id], &mix);
- mix.type = MIX_ON_OFF; /* XXX */
-
- for (i = 0; i < ud->bNrModes; i++) {
- DPRINTFN(3, "i=%d bm=0x%x\n", i, UGETW(ud->waModes[i]));
- /* XXX */
- }
-
- uaudio_mixer_add_ctl(sc, &mix);
-}
-
-static void
-uaudio_mixer_add_processing(struct uaudio_softc *sc,
- const struct uaudio_terminal_node *iot, int id)
-{
- const struct usb2_audio_processing_unit_0 *d0 = iot[id].u.pu;
- const struct usb2_audio_processing_unit_1 *d1 =
- (const void *)(d0->baSourceId + d0->bNrInPins);
- struct uaudio_mixer_node mix;
- uint16_t ptype;
-
- bzero(&mix, sizeof(mix));
-
- ptype = UGETW(d0->wProcessType);
-
- DPRINTFN(3, "wProcessType=%d bUnitId=%d "
- "bNrInPins=%d\n", ptype, d0->bUnitId, d0->bNrInPins);
-
- if (d1->bControlSize == 0) {
- return;
- }
- if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
- mix.wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no);
- mix.nchan = 1;
- mix.wValue[0] = MAKE_WORD(XX_ENABLE_CONTROL, 0);
- uaudio_mixer_determine_class(&iot[id], &mix);
- mix.type = MIX_ON_OFF;
- uaudio_mixer_add_ctl(sc, &mix);
- }
- switch (ptype) {
- case UPDOWNMIX_PROCESS:
- uaudio_mixer_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:
- DPRINTF("unit %d, type=%d is not implemented\n",
- d0->bUnitId, ptype);
- break;
- }
-}
-
-static void
-uaudio_mixer_add_extension(struct uaudio_softc *sc,
- const struct uaudio_terminal_node *iot, int id)
-{
- const struct usb2_audio_extension_unit_0 *d0 = iot[id].u.eu;
- const struct usb2_audio_extension_unit_1 *d1 =
- (const void *)(d0->baSourceId + d0->bNrInPins);
- struct uaudio_mixer_node mix;
-
- DPRINTFN(3, "bUnitId=%d bNrInPins=%d\n",
- d0->bUnitId, d0->bNrInPins);
-
- if (sc->sc_uq_au_no_xu) {
- return;
- }
- if (d1->bControlSize == 0) {
- return;
- }
- if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
-
- bzero(&mix, sizeof(mix));
-
- mix.wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no);
- mix.nchan = 1;
- mix.wValue[0] = MAKE_WORD(UA_EXT_ENABLE, 0);
- uaudio_mixer_determine_class(&iot[id], &mix);
- mix.type = MIX_ON_OFF;
-
- uaudio_mixer_add_ctl(sc, &mix);
- }
-}
-
-static const void *
-uaudio_mixer_verify_desc(const void *arg, uint32_t len)
-{
- const struct usb2_audio_mixer_unit_1 *d1;
- const struct usb2_audio_extension_unit_1 *e1;
- const struct usb2_audio_processing_unit_1 *u1;
-
- union {
- const struct usb2_descriptor *desc;
- const struct usb2_audio_input_terminal *it;
- const struct usb2_audio_output_terminal *ot;
- const struct usb2_audio_mixer_unit_0 *mu;
- const struct usb2_audio_selector_unit *su;
- const struct usb2_audio_feature_unit *fu;
- const struct usb2_audio_processing_unit_0 *pu;
- const struct usb2_audio_extension_unit_0 *eu;
- } u;
-
- u.desc = arg;
-
- if (u.desc == NULL) {
- goto error;
- }
- if (u.desc->bDescriptorType != UDESC_CS_INTERFACE) {
- goto error;
- }
- switch (u.desc->bDescriptorSubtype) {
- case UDESCSUB_AC_INPUT:
- len += sizeof(*u.it);
- break;
-
- case UDESCSUB_AC_OUTPUT:
- len += sizeof(*u.ot);
- break;
-
- case UDESCSUB_AC_MIXER:
- len += sizeof(*u.mu);
-
- if (u.desc->bLength < len) {
- goto error;
- }
- len += u.mu->bNrInPins;
-
- if (u.desc->bLength < len) {
- goto error;
- }
- d1 = (const void *)(u.mu->baSourceId + u.mu->bNrInPins);
-
- len += sizeof(*d1);
- break;
-
- case UDESCSUB_AC_SELECTOR:
- len += sizeof(*u.su);
-
- if (u.desc->bLength < len) {
- goto error;
- }
- len += u.su->bNrInPins;
- break;
-
- case UDESCSUB_AC_FEATURE:
- len += (sizeof(*u.fu) + 1);
- break;
-
- case UDESCSUB_AC_PROCESSING:
- len += sizeof(*u.pu);
-
- if (u.desc->bLength < len) {
- goto error;
- }
- len += u.pu->bNrInPins;
-
- if (u.desc->bLength < len) {
- goto error;
- }
- u1 = (const void *)(u.pu->baSourceId + u.pu->bNrInPins);
-
- len += sizeof(*u1);
-
- if (u.desc->bLength < len) {
- goto error;
- }
- len += u1->bControlSize;
-
- break;
-
- case UDESCSUB_AC_EXTENSION:
- len += sizeof(*u.eu);
-
- if (u.desc->bLength < len) {
- goto error;
- }
- len += u.eu->bNrInPins;
-
- if (u.desc->bLength < len) {
- goto error;
- }
- e1 = (const void *)(u.eu->baSourceId + u.eu->bNrInPins);
-
- len += sizeof(*e1);
-
- if (u.desc->bLength < len) {
- goto error;
- }
- len += e1->bControlSize;
- break;
-
- default:
- goto error;
- }
-
- if (u.desc->bLength < len) {
- goto error;
- }
- return (u.desc);
-
-error:
- if (u.desc) {
- DPRINTF("invalid descriptor, type=%d, "
- "sub_type=%d, len=%d of %d bytes\n",
- u.desc->bDescriptorType,
- u.desc->bDescriptorSubtype,
- u.desc->bLength, len);
- }
- return (NULL);
-}
-
-#if USB_DEBUG
-static void
-uaudio_mixer_dump_cluster(uint8_t id, const struct uaudio_terminal_node *iot)
-{
- 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",
- };
- uint16_t cc;
- uint8_t i;
- const struct usb2_audio_cluster cl = uaudio_mixer_get_cluster(id, iot);
-
- cc = UGETW(cl.wChannelConfig);
-
- DPRINTF("cluster: bNrChannels=%u iChannelNames=%u wChannelConfig="
- "0x%04x:\n", cl.iChannelNames, cl.bNrChannels, cc);
-
- for (i = 0; cc; i++) {
- if (cc & 1) {
- DPRINTF(" - %s\n", channel_names[i]);
- }
- cc >>= 1;
- }
-}
-
-#endif
-
-static struct usb2_audio_cluster
-uaudio_mixer_get_cluster(uint8_t id, const struct uaudio_terminal_node *iot)
-{
- struct usb2_audio_cluster r;
- const struct usb2_descriptor *dp;
- uint8_t i;
-
- for (i = 0; i < UAUDIO_RECURSE_LIMIT; i++) { /* avoid infinite loops */
- dp = iot[id].u.desc;
- if (dp == NULL) {
- goto error;
- }
- switch (dp->bDescriptorSubtype) {
- case UDESCSUB_AC_INPUT:
- r.bNrChannels = iot[id].u.it->bNrChannels;
- r.wChannelConfig[0] = iot[id].u.it->wChannelConfig[0];
- r.wChannelConfig[1] = iot[id].u.it->wChannelConfig[1];
- r.iChannelNames = iot[id].u.it->iChannelNames;
- goto done;
-
- case UDESCSUB_AC_OUTPUT:
- id = iot[id].u.ot->bSourceId;
- break;
-
- case UDESCSUB_AC_MIXER:
- r = *(const struct usb2_audio_cluster *)
- &iot[id].u.mu->baSourceId[iot[id].u.mu->
- bNrInPins];
- goto done;
-
- case UDESCSUB_AC_SELECTOR:
- if (iot[id].u.su->bNrInPins > 0) {
- /* XXX This is not really right */
- id = iot[id].u.su->baSourceId[0];
- }
- break;
-
- case UDESCSUB_AC_FEATURE:
- id = iot[id].u.fu->bSourceId;
- break;
-
- case UDESCSUB_AC_PROCESSING:
- r = *((const struct usb2_audio_cluster *)
- &iot[id].u.pu->baSourceId[iot[id].u.pu->
- bNrInPins]);
- goto done;
-
- case UDESCSUB_AC_EXTENSION:
- r = *((const struct usb2_audio_cluster *)
- &iot[id].u.eu->baSourceId[iot[id].u.eu->
- bNrInPins]);
- goto done;
-
- default:
- goto error;
- }
- }
-error:
- DPRINTF("bad data\n");
- bzero(&r, sizeof(r));
-done:
- return (r);
-}
-
-#if USB_DEBUG
-
-struct uaudio_tt_to_string {
- uint16_t terminal_type;
- const char *desc;
-};
-
-static const struct uaudio_tt_to_string uaudio_tt_to_string[] = {
-
- /* USB terminal types */
- {UAT_UNDEFINED, "UAT_UNDEFINED"},
- {UAT_STREAM, "UAT_STREAM"},
- {UAT_VENDOR, "UAT_VENDOR"},
-
- /* input terminal types */
- {UATI_UNDEFINED, "UATI_UNDEFINED"},
- {UATI_MICROPHONE, "UATI_MICROPHONE"},
- {UATI_DESKMICROPHONE, "UATI_DESKMICROPHONE"},
- {UATI_PERSONALMICROPHONE, "UATI_PERSONALMICROPHONE"},
- {UATI_OMNIMICROPHONE, "UATI_OMNIMICROPHONE"},
- {UATI_MICROPHONEARRAY, "UATI_MICROPHONEARRAY"},
- {UATI_PROCMICROPHONEARR, "UATI_PROCMICROPHONEARR"},
-
- /* output terminal types */
- {UATO_UNDEFINED, "UATO_UNDEFINED"},
- {UATO_SPEAKER, "UATO_SPEAKER"},
- {UATO_HEADPHONES, "UATO_HEADPHONES"},
- {UATO_DISPLAYAUDIO, "UATO_DISPLAYAUDIO"},
- {UATO_DESKTOPSPEAKER, "UATO_DESKTOPSPEAKER"},
- {UATO_ROOMSPEAKER, "UATO_ROOMSPEAKER"},
- {UATO_COMMSPEAKER, "UATO_COMMSPEAKER"},
- {UATO_SUBWOOFER, "UATO_SUBWOOFER"},
-
- /* bidir terminal types */
- {UATB_UNDEFINED, "UATB_UNDEFINED"},
- {UATB_HANDSET, "UATB_HANDSET"},
- {UATB_HEADSET, "UATB_HEADSET"},
- {UATB_SPEAKERPHONE, "UATB_SPEAKERPHONE"},
- {UATB_SPEAKERPHONEESUP, "UATB_SPEAKERPHONEESUP"},
- {UATB_SPEAKERPHONEECANC, "UATB_SPEAKERPHONEECANC"},
-
- /* telephony terminal types */
- {UATT_UNDEFINED, "UATT_UNDEFINED"},
- {UATT_PHONELINE, "UATT_PHONELINE"},
- {UATT_TELEPHONE, "UATT_TELEPHONE"},
- {UATT_DOWNLINEPHONE, "UATT_DOWNLINEPHONE"},
-
- /* external terminal types */
- {UATE_UNDEFINED, "UATE_UNDEFINED"},
- {UATE_ANALOGCONN, "UATE_ANALOGCONN"},
- {UATE_LINECONN, "UATE_LINECONN"},
- {UATE_LEGACYCONN, "UATE_LEGACYCONN"},
- {UATE_DIGITALAUIFC, "UATE_DIGITALAUIFC"},
- {UATE_SPDIF, "UATE_SPDIF"},
- {UATE_1394DA, "UATE_1394DA"},
- {UATE_1394DV, "UATE_1394DV"},
-
- /* embedded function terminal types */
- {UATF_UNDEFINED, "UATF_UNDEFINED"},
- {UATF_CALIBNOISE, "UATF_CALIBNOISE"},
- {UATF_EQUNOISE, "UATF_EQUNOISE"},
- {UATF_CDPLAYER, "UATF_CDPLAYER"},
- {UATF_DAT, "UATF_DAT"},
- {UATF_DCC, "UATF_DCC"},
- {UATF_MINIDISK, "UATF_MINIDISK"},
- {UATF_ANALOGTAPE, "UATF_ANALOGTAPE"},
- {UATF_PHONOGRAPH, "UATF_PHONOGRAPH"},
- {UATF_VCRAUDIO, "UATF_VCRAUDIO"},
- {UATF_VIDEODISCAUDIO, "UATF_VIDEODISCAUDIO"},
- {UATF_DVDAUDIO, "UATF_DVDAUDIO"},
- {UATF_TVTUNERAUDIO, "UATF_TVTUNERAUDIO"},
- {UATF_SATELLITE, "UATF_SATELLITE"},
- {UATF_CABLETUNER, "UATF_CABLETUNER"},
- {UATF_DSS, "UATF_DSS"},
- {UATF_RADIORECV, "UATF_RADIORECV"},
- {UATF_RADIOXMIT, "UATF_RADIOXMIT"},
- {UATF_MULTITRACK, "UATF_MULTITRACK"},
- {UATF_SYNTHESIZER, "UATF_SYNTHESIZER"},
-
- /* unknown */
- {0x0000, "UNKNOWN"},
-};
-
-static const char *
-uaudio_mixer_get_terminal_name(uint16_t terminal_type)
-{
- const struct uaudio_tt_to_string *uat = uaudio_tt_to_string;
-
- while (uat->terminal_type) {
- if (uat->terminal_type == terminal_type) {
- break;
- }
- uat++;
- }
- if (uat->terminal_type == 0) {
- DPRINTF("unknown terminal type (0x%04x)", terminal_type);
- }
- return (uat->desc);
-}
-
-#endif
-
-static uint16_t
-uaudio_mixer_determine_class(const struct uaudio_terminal_node *iot,
- struct uaudio_mixer_node *mix)
-{
- uint16_t terminal_type = 0x0000;
- const struct uaudio_terminal_node *input[2];
- const struct uaudio_terminal_node *output[2];
-
- input[0] = uaudio_mixer_get_input(iot, 0);
- input[1] = uaudio_mixer_get_input(iot, 1);
-
- output[0] = uaudio_mixer_get_output(iot, 0);
- output[1] = uaudio_mixer_get_output(iot, 1);
-
- /*
- * check if there is only
- * one output terminal:
- */
- if (output[0] && (!output[1])) {
- terminal_type = UGETW(output[0]->u.ot->wTerminalType);
- }
- /*
- * If the only output terminal is USB,
- * the class is UAC_RECORD.
- */
- if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
-
- mix->class = UAC_RECORD;
- if (input[0] && (!input[1])) {
- terminal_type = UGETW(input[0]->u.it->wTerminalType);
- } else {
- terminal_type = 0;
- }
- goto done;
- }
- /*
- * if the unit is connected to just
- * one input terminal, the
- * class is UAC_INPUT:
- */
- if (input[0] && (!input[1])) {
- mix->class = UAC_INPUT;
- terminal_type = UGETW(input[0]->u.it->wTerminalType);
- goto done;
- }
- /*
- * Otherwise, the class is UAC_OUTPUT.
- */
- mix->class = UAC_OUTPUT;
-done:
- return (terminal_type);
-}
-
-struct uaudio_tt_to_feature {
- uint16_t terminal_type;
- uint16_t feature;
-};
-
-static const struct uaudio_tt_to_feature uaudio_tt_to_feature[] = {
-
- {UAT_STREAM, SOUND_MIXER_PCM},
-
- {UATI_MICROPHONE, SOUND_MIXER_MIC},
- {UATI_DESKMICROPHONE, SOUND_MIXER_MIC},
- {UATI_PERSONALMICROPHONE, SOUND_MIXER_MIC},
- {UATI_OMNIMICROPHONE, SOUND_MIXER_MIC},
- {UATI_MICROPHONEARRAY, SOUND_MIXER_MIC},
- {UATI_PROCMICROPHONEARR, SOUND_MIXER_MIC},
-
- {UATO_SPEAKER, SOUND_MIXER_SPEAKER},
- {UATO_DESKTOPSPEAKER, SOUND_MIXER_SPEAKER},
- {UATO_ROOMSPEAKER, SOUND_MIXER_SPEAKER},
- {UATO_COMMSPEAKER, SOUND_MIXER_SPEAKER},
-
- {UATE_ANALOGCONN, SOUND_MIXER_LINE},
- {UATE_LINECONN, SOUND_MIXER_LINE},
- {UATE_LEGACYCONN, SOUND_MIXER_LINE},
-
- {UATE_DIGITALAUIFC, SOUND_MIXER_ALTPCM},
- {UATE_SPDIF, SOUND_MIXER_ALTPCM},
- {UATE_1394DA, SOUND_MIXER_ALTPCM},
- {UATE_1394DV, SOUND_MIXER_ALTPCM},
-
- {UATF_CDPLAYER, SOUND_MIXER_CD},
-
- {UATF_SYNTHESIZER, SOUND_MIXER_SYNTH},
-
- {UATF_VIDEODISCAUDIO, SOUND_MIXER_VIDEO},
- {UATF_DVDAUDIO, SOUND_MIXER_VIDEO},
- {UATF_TVTUNERAUDIO, SOUND_MIXER_VIDEO},
-
- /* telephony terminal types */
- {UATT_UNDEFINED, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */
- {UATT_PHONELINE, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */
- {UATT_TELEPHONE, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */
- {UATT_DOWNLINEPHONE, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */
-
- {UATF_RADIORECV, SOUND_MIXER_RADIO},
- {UATF_RADIOXMIT, SOUND_MIXER_RADIO},
-
- {UAT_UNDEFINED, SOUND_MIXER_VOLUME},
- {UAT_VENDOR, SOUND_MIXER_VOLUME},
- {UATI_UNDEFINED, SOUND_MIXER_VOLUME},
-
- /* output terminal types */
- {UATO_UNDEFINED, SOUND_MIXER_VOLUME},
- {UATO_DISPLAYAUDIO, SOUND_MIXER_VOLUME},
- {UATO_SUBWOOFER, SOUND_MIXER_VOLUME},
- {UATO_HEADPHONES, SOUND_MIXER_VOLUME},
-
- /* bidir terminal types */
- {UATB_UNDEFINED, SOUND_MIXER_VOLUME},
- {UATB_HANDSET, SOUND_MIXER_VOLUME},
- {UATB_HEADSET, SOUND_MIXER_VOLUME},
- {UATB_SPEAKERPHONE, SOUND_MIXER_VOLUME},
- {UATB_SPEAKERPHONEESUP, SOUND_MIXER_VOLUME},
- {UATB_SPEAKERPHONEECANC, SOUND_MIXER_VOLUME},
-
- /* external terminal types */
- {UATE_UNDEFINED, SOUND_MIXER_VOLUME},
-
- /* embedded function terminal types */
- {UATF_UNDEFINED, SOUND_MIXER_VOLUME},
- {UATF_CALIBNOISE, SOUND_MIXER_VOLUME},
- {UATF_EQUNOISE, SOUND_MIXER_VOLUME},
- {UATF_DAT, SOUND_MIXER_VOLUME},
- {UATF_DCC, SOUND_MIXER_VOLUME},
- {UATF_MINIDISK, SOUND_MIXER_VOLUME},
- {UATF_ANALOGTAPE, SOUND_MIXER_VOLUME},
- {UATF_PHONOGRAPH, SOUND_MIXER_VOLUME},
- {UATF_VCRAUDIO, SOUND_MIXER_VOLUME},
- {UATF_SATELLITE, SOUND_MIXER_VOLUME},
- {UATF_CABLETUNER, SOUND_MIXER_VOLUME},
- {UATF_DSS, SOUND_MIXER_VOLUME},
- {UATF_MULTITRACK, SOUND_MIXER_VOLUME},
- {0xffff, SOUND_MIXER_VOLUME},
-
- /* default */
- {0x0000, SOUND_MIXER_VOLUME},
-};
-
-static uint16_t
-uaudio_mixer_feature_name(const struct uaudio_terminal_node *iot,
- struct uaudio_mixer_node *mix)
-{
- const struct uaudio_tt_to_feature *uat = uaudio_tt_to_feature;
- uint16_t terminal_type = uaudio_mixer_determine_class(iot, mix);
-
- if ((mix->class == UAC_RECORD) && (terminal_type == 0)) {
- return (SOUND_MIXER_IMIX);
- }
- while (uat->terminal_type) {
- if (uat->terminal_type == terminal_type) {
- break;
- }
- uat++;
- }
-
- DPRINTF("terminal_type=%s (0x%04x) -> %d\n",
- uaudio_mixer_get_terminal_name(terminal_type),
- terminal_type, uat->feature);
-
- return (uat->feature);
-}
-
-const static struct uaudio_terminal_node *
-uaudio_mixer_get_input(const struct uaudio_terminal_node *iot, uint8_t index)
-{
- struct uaudio_terminal_node *root = iot->root;
- uint8_t n;
-
- n = iot->usr.id_max;
- do {
- if (iot->usr.bit_input[n / 8] & (1 << (n % 8))) {
- if (!index--) {
- return (root + n);
- }
- }
- } while (n--);
-
- return (NULL);
-}
-
-const static struct uaudio_terminal_node *
-uaudio_mixer_get_output(const struct uaudio_terminal_node *iot, uint8_t index)
-{
- struct uaudio_terminal_node *root = iot->root;
- uint8_t n;
-
- n = iot->usr.id_max;
- do {
- if (iot->usr.bit_output[n / 8] & (1 << (n % 8))) {
- if (!index--) {
- return (root + n);
- }
- }
- } while (n--);
-
- return (NULL);
-}
-
-static void
-uaudio_mixer_find_inputs_sub(struct uaudio_terminal_node *root,
- const uint8_t *p_id, uint8_t n_id,
- struct uaudio_search_result *info)
-{
- struct uaudio_terminal_node *iot;
- uint8_t n;
- uint8_t i;
-
- if (info->recurse_level >= UAUDIO_RECURSE_LIMIT) {
- return;
- }
- info->recurse_level++;
-
- for (n = 0; n < n_id; n++) {
-
- i = p_id[n];
-
- if (info->bit_visited[i / 8] & (1 << (i % 8))) {
- /* don't go into a circle */
- DPRINTF("avoided going into a circle at id=%d!\n", i);
- continue;
- } else {
- info->bit_visited[i / 8] |= (1 << (i % 8));
- }
-
- iot = (root + i);
-
- if (iot->u.desc == NULL) {
- continue;
- }
- switch (iot->u.desc->bDescriptorSubtype) {
- case UDESCSUB_AC_INPUT:
- info->bit_input[i / 8] |= (1 << (i % 8));
- break;
-
- case UDESCSUB_AC_FEATURE:
- uaudio_mixer_find_inputs_sub
- (root, &iot->u.fu->bSourceId, 1, info);
- break;
-
- case UDESCSUB_AC_OUTPUT:
- uaudio_mixer_find_inputs_sub
- (root, &iot->u.ot->bSourceId, 1, info);
- break;
-
- case UDESCSUB_AC_MIXER:
- uaudio_mixer_find_inputs_sub
- (root, iot->u.mu->baSourceId,
- iot->u.mu->bNrInPins, info);
- break;
-
- case UDESCSUB_AC_SELECTOR:
- uaudio_mixer_find_inputs_sub
- (root, iot->u.su->baSourceId,
- iot->u.su->bNrInPins, info);
- break;
-
- case UDESCSUB_AC_PROCESSING:
- uaudio_mixer_find_inputs_sub
- (root, iot->u.pu->baSourceId,
- iot->u.pu->bNrInPins, info);
- break;
-
- case UDESCSUB_AC_EXTENSION:
- uaudio_mixer_find_inputs_sub
- (root, iot->u.eu->baSourceId,
- iot->u.eu->bNrInPins, info);
- break;
-
- case UDESCSUB_AC_HEADER:
- default:
- break;
- }
- }
- info->recurse_level--;
-}
-
-static void
-uaudio_mixer_find_outputs_sub(struct uaudio_terminal_node *root, uint8_t id,
- uint8_t n_id, struct uaudio_search_result *info)
-{
- struct uaudio_terminal_node *iot = (root + id);
- uint8_t j;
-
- j = n_id;
- do {
- if ((j != id) && ((root + j)->u.desc) &&
- ((root + j)->u.desc->bDescriptorSubtype == UDESCSUB_AC_OUTPUT)) {
-
- /*
- * "j" (output) <--- virtual wire <--- "id" (input)
- *
- * if "j" has "id" on the input, then "id" have "j" on
- * the output, because they are connected:
- */
- if ((root + j)->usr.bit_input[id / 8] & (1 << (id % 8))) {
- iot->usr.bit_output[j / 8] |= (1 << (j % 8));
- }
- }
- } while (j--);
-}
-
-static void
-uaudio_mixer_fill_info(struct uaudio_softc *sc, struct usb2_device *udev,
- void *desc)
-{
- const struct usb2_audio_control_descriptor *acdp;
- struct usb2_config_descriptor *cd = usb2_get_config_descriptor(udev);
- const struct usb2_descriptor *dp;
- const struct usb2_audio_unit *au;
- struct uaudio_terminal_node *iot = NULL;
- uint16_t wTotalLen;
- uint8_t ID_max = 0; /* inclusive */
- uint8_t i;
-
- desc = usb2_desc_foreach(cd, desc);
-
- if (desc == NULL) {
- DPRINTF("no Audio Control header\n");
- goto done;
- }
- acdp = desc;
-
- if ((acdp->bLength < sizeof(*acdp)) ||
- (acdp->bDescriptorType != UDESC_CS_INTERFACE) ||
- (acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)) {
- DPRINTF("invalid Audio Control header\n");
- goto done;
- }
- /* "wTotalLen" is allowed to be corrupt */
- wTotalLen = UGETW(acdp->wTotalLength) - acdp->bLength;
-
- /* get USB audio revision */
- sc->sc_audio_rev = UGETW(acdp->bcdADC);
-
- DPRINTFN(3, "found AC header, vers=%03x, len=%d\n",
- sc->sc_audio_rev, wTotalLen);
-
- if (sc->sc_audio_rev != UAUDIO_VERSION) {
-
- if (sc->sc_uq_bad_adc) {
-
- } else {
- DPRINTF("invalid audio version\n");
- goto done;
- }
- }
- iot = malloc(sizeof(struct uaudio_terminal_node) * 256, M_TEMP,
- M_WAITOK | M_ZERO);
-
- if (iot == NULL) {
- DPRINTF("no memory!\n");
- goto done;
- }
- while ((desc = usb2_desc_foreach(cd, desc))) {
-
- dp = desc;
-
- if (dp->bLength > wTotalLen) {
- break;
- } else {
- wTotalLen -= dp->bLength;
- }
-
- au = uaudio_mixer_verify_desc(dp, 0);
-
- if (au) {
- iot[au->bUnitId].u.desc = (const void *)au;
- if (au->bUnitId > ID_max) {
- ID_max = au->bUnitId;
- }
- }
- }
-
- DPRINTF("Maximum ID=%d\n", ID_max);
-
- /*
- * determine sourcing inputs for
- * all nodes in the tree:
- */
- i = ID_max;
- do {
- uaudio_mixer_find_inputs_sub(iot, &i, 1, &((iot + i)->usr));
- } while (i--);
-
- /*
- * determine outputs for
- * all nodes in the tree:
- */
- i = ID_max;
- do {
- uaudio_mixer_find_outputs_sub(iot, i, ID_max, &((iot + i)->usr));
- } while (i--);
-
- /* set "id_max" and "root" */
-
- i = ID_max;
- do {
- (iot + i)->usr.id_max = ID_max;
- (iot + i)->root = iot;
- } while (i--);
-
-#if USB_DEBUG
- i = ID_max;
- do {
- uint8_t j;
-
- if (iot[i].u.desc == NULL) {
- continue;
- }
- DPRINTF("id %d:\n", i);
-
- switch (iot[i].u.desc->bDescriptorSubtype) {
- case UDESCSUB_AC_INPUT:
- DPRINTF(" - AC_INPUT type=%s\n",
- uaudio_mixer_get_terminal_name
- (UGETW(iot[i].u.it->wTerminalType)));
- uaudio_mixer_dump_cluster(i, iot);
- break;
-
- case UDESCSUB_AC_OUTPUT:
- DPRINTF(" - AC_OUTPUT type=%s "
- "src=%d\n", uaudio_mixer_get_terminal_name
- (UGETW(iot[i].u.ot->wTerminalType)),
- iot[i].u.ot->bSourceId);
- break;
-
- case UDESCSUB_AC_MIXER:
- DPRINTF(" - AC_MIXER src:\n");
- for (j = 0; j < iot[i].u.mu->bNrInPins; j++) {
- DPRINTF(" - %d\n", iot[i].u.mu->baSourceId[j]);
- }
- uaudio_mixer_dump_cluster(i, iot);
- break;
-
- case UDESCSUB_AC_SELECTOR:
- DPRINTF(" - AC_SELECTOR src:\n");
- for (j = 0; j < iot[i].u.su->bNrInPins; j++) {
- DPRINTF(" - %d\n", iot[i].u.su->baSourceId[j]);
- }
- break;
-
- case UDESCSUB_AC_FEATURE:
- DPRINTF(" - AC_FEATURE src=%d\n", iot[i].u.fu->bSourceId);
- break;
-
- case UDESCSUB_AC_PROCESSING:
- DPRINTF(" - AC_PROCESSING src:\n");
- for (j = 0; j < iot[i].u.pu->bNrInPins; j++) {
- DPRINTF(" - %d\n", iot[i].u.pu->baSourceId[j]);
- }
- uaudio_mixer_dump_cluster(i, iot);
- break;
-
- case UDESCSUB_AC_EXTENSION:
- DPRINTF(" - AC_EXTENSION src:\n");
- for (j = 0; j < iot[i].u.eu->bNrInPins; j++) {
- DPRINTF("%d ", iot[i].u.eu->baSourceId[j]);
- }
- uaudio_mixer_dump_cluster(i, iot);
- break;
-
- default:
- DPRINTF("unknown audio control (subtype=%d)\n",
- iot[i].u.desc->bDescriptorSubtype);
- }
-
- DPRINTF("Inputs to this ID are:\n");
-
- j = ID_max;
- do {
- if (iot[i].usr.bit_input[j / 8] & (1 << (j % 8))) {
- DPRINTF(" -- ID=%d\n", j);
- }
- } while (j--);
-
- DPRINTF("Outputs from this ID are:\n");
-
- j = ID_max;
- do {
- if (iot[i].usr.bit_output[j / 8] & (1 << (j % 8))) {
- DPRINTF(" -- ID=%d\n", j);
- }
- } while (j--);
-
- } while (i--);
-#endif
-
- /*
- * scan the config to create a linked
- * list of "mixer" nodes:
- */
-
- i = ID_max;
- do {
- dp = iot[i].u.desc;
-
- if (dp == NULL) {
- continue;
- }
- DPRINTFN(11, "id=%d subtype=%d\n",
- i, dp->bDescriptorSubtype);
-
- switch (dp->bDescriptorSubtype) {
- case UDESCSUB_AC_HEADER:
- DPRINTF("unexpected AC header\n");
- break;
-
- case UDESCSUB_AC_INPUT:
- uaudio_mixer_add_input(sc, iot, i);
- break;
-
- case UDESCSUB_AC_OUTPUT:
- uaudio_mixer_add_output(sc, iot, i);
- break;
-
- case UDESCSUB_AC_MIXER:
- uaudio_mixer_add_mixer(sc, iot, i);
- break;
-
- case UDESCSUB_AC_SELECTOR:
- uaudio_mixer_add_selector(sc, iot, i);
- break;
-
- case UDESCSUB_AC_FEATURE:
- uaudio_mixer_add_feature(sc, iot, i);
- break;
-
- case UDESCSUB_AC_PROCESSING:
- uaudio_mixer_add_processing(sc, iot, i);
- break;
-
- case UDESCSUB_AC_EXTENSION:
- uaudio_mixer_add_extension(sc, iot, i);
- break;
-
- default:
- DPRINTF("bad AC desc subtype=0x%02x\n",
- dp->bDescriptorSubtype);
- break;
- }
-
- } while (i--);
-
-done:
- if (iot) {
- free(iot, M_TEMP);
- }
-}
-
-static uint16_t
-uaudio_mixer_get(struct usb2_device *udev, uint8_t what,
- struct uaudio_mixer_node *mc)
-{
- struct usb2_device_request req;
- uint16_t val;
- uint16_t len = MIX_SIZE(mc->type);
- uint8_t data[4];
- usb2_error_t err;
-
- if (mc->wValue[0] == -1) {
- return (0);
- }
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = what;
- USETW(req.wValue, mc->wValue[0]);
- USETW(req.wIndex, mc->wIndex);
- USETW(req.wLength, len);
-
- err = usb2_do_request(udev, &Giant, &req, data);
- if (err) {
- DPRINTF("err=%s\n", usb2_errstr(err));
- return (0);
- }
- if (len < 1) {
- data[0] = 0;
- }
- if (len < 2) {
- data[1] = 0;
- }
- val = (data[0] | (data[1] << 8));
-
- DPRINTFN(3, "val=%d\n", val);
-
- return (val);
-}
-
-static void
-uaudio_mixer_write_cfg_callback(struct usb2_xfer *xfer)
-{
- struct usb2_device_request req;
- struct uaudio_softc *sc = xfer->priv_sc;
- struct uaudio_mixer_node *mc = sc->sc_mixer_curr;
- uint16_t len;
- uint8_t repeat = 1;
- uint8_t update;
- uint8_t chan;
- uint8_t buf[2];
-
- DPRINTF("\n");
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-tr_transferred:
- case USB_ST_SETUP:
-tr_setup:
-
- if (mc == NULL) {
- mc = sc->sc_mixer_root;
- sc->sc_mixer_curr = mc;
- sc->sc_mixer_chan = 0;
- repeat = 0;
- }
- while (mc) {
- while (sc->sc_mixer_chan < mc->nchan) {
-
- len = MIX_SIZE(mc->type);
-
- chan = sc->sc_mixer_chan;
-
- sc->sc_mixer_chan++;
-
- update = ((mc->update[chan / 8] & (1 << (chan % 8))) &&
- (mc->wValue[chan] != -1));
-
- mc->update[chan / 8] &= ~(1 << (chan % 8));
-
- if (update) {
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = SET_CUR;
- USETW(req.wValue, mc->wValue[chan]);
- USETW(req.wIndex, mc->wIndex);
- USETW(req.wLength, len);
-
- if (len > 0) {
- buf[0] = (mc->wData[chan] & 0xFF);
- }
- if (len > 1) {
- buf[1] = (mc->wData[chan] >> 8) & 0xFF;
- }
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
- usb2_copy_in(xfer->frbuffers + 1, 0, buf, len);
-
- xfer->frlengths[0] = sizeof(req);
- xfer->frlengths[1] = len;
- xfer->nframes = xfer->frlengths[1] ? 2 : 1;
- usb2_start_hardware(xfer);
- return;
- }
- }
-
- mc = mc->next;
- sc->sc_mixer_curr = mc;
- sc->sc_mixer_chan = 0;
- }
-
- if (repeat) {
- goto tr_setup;
- }
- break;
-
- default: /* Error */
- DPRINTF("error=%s\n", usb2_errstr(xfer->error));
- if (xfer->error == USB_ERR_CANCELLED) {
- /* do nothing - we are detaching */
- break;
- }
- goto tr_transferred;
- }
-}
-
-static usb2_error_t
-uaudio_set_speed(struct usb2_device *udev, uint8_t endpt, uint32_t speed)
-{
- struct usb2_device_request req;
- uint8_t data[3];
-
- DPRINTFN(6, "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;
-
- return (usb2_do_request(udev, &Giant, &req, data));
-}
-
-static int
-uaudio_mixer_signext(uint8_t type, int val)
-{
- if (!MIX_UNSIGNED(type)) {
- if (MIX_SIZE(type) == 2) {
- val = (int16_t)val;
- } else {
- val = (int8_t)val;
- }
- }
- return (val);
-}
-
-static int
-uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, int32_t val)
-{
- 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(6, "type=0x%03x val=%d min=%d max=%d val=%d\n",
- mc->type, val, mc->minval, mc->maxval, val);
- return (val);
-}
-
-static void
-uaudio_mixer_ctl_set(struct uaudio_softc *sc, struct uaudio_mixer_node *mc,
- uint8_t chan, int32_t val)
-{
- val = uaudio_mixer_bsd2value(mc, val);
-
- mc->update[chan / 8] |= (1 << (chan % 8));
- mc->wData[chan] = val;
-
- /* start the transfer, if not already started */
-
- usb2_transfer_start(sc->sc_mixer_xfer[0]);
-}
-
-static void
-uaudio_mixer_init(struct uaudio_softc *sc)
-{
- struct uaudio_mixer_node *mc;
- int32_t i;
-
- for (mc = sc->sc_mixer_root; mc;
- mc = mc->next) {
-
- if (mc->ctl != SOUND_MIXER_NRDEVICES) {
- /*
- * Set device mask bits. See
- * /usr/include/machine/soundcard.h
- */
- sc->sc_mix_info |= (1 << mc->ctl);
- }
- if ((mc->ctl == SOUND_MIXER_NRDEVICES) &&
- (mc->type == MIX_SELECTOR)) {
-
- for (i = mc->minval; (i > 0) && (i <= mc->maxval); i++) {
- if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES) {
- continue;
- }
- sc->sc_recsrc_info |= 1 << mc->slctrtype[i - 1];
- }
- }
- }
-}
-
-int
-uaudio_mixer_init_sub(struct uaudio_softc *sc, struct snd_mixer *m)
-{
- DPRINTF("\n");
-
- if (usb2_transfer_setup(sc->sc_udev, &sc->sc_mixer_iface_index,
- sc->sc_mixer_xfer, uaudio_mixer_config, 1, sc,
- mixer_get_lock(m))) {
- DPRINTFN(0, "could not allocate USB "
- "transfer for audio mixer!\n");
- return (ENOMEM);
- }
- if (!(sc->sc_mix_info & SOUND_MASK_VOLUME)) {
- mix_setparentchild(m, SOUND_MIXER_VOLUME, SOUND_MASK_PCM);
- mix_setrealdev(m, SOUND_MIXER_VOLUME, SOUND_MIXER_NONE);
- }
- mix_setdevs(m, sc->sc_mix_info);
- mix_setrecdevs(m, sc->sc_recsrc_info);
- return (0);
-}
-
-int
-uaudio_mixer_uninit_sub(struct uaudio_softc *sc)
-{
- DPRINTF("\n");
-
- usb2_transfer_unsetup(sc->sc_mixer_xfer, 1);
-
- return (0);
-}
-
-void
-uaudio_mixer_set(struct uaudio_softc *sc, unsigned type,
- unsigned left, unsigned right)
-{
- struct uaudio_mixer_node *mc;
-
- for (mc = sc->sc_mixer_root; mc;
- mc = mc->next) {
-
- if (mc->ctl == type) {
- if (mc->nchan == 2) {
- /* set Right */
- uaudio_mixer_ctl_set(sc, mc, 1, (int)(right * 255) / 100);
- }
- /* set Left or Mono */
- uaudio_mixer_ctl_set(sc, mc, 0, (int)(left * 255) / 100);
- }
- }
-}
-
-uint32_t
-uaudio_mixer_setrecsrc(struct uaudio_softc *sc, uint32_t src)
-{
- struct uaudio_mixer_node *mc;
- uint32_t mask;
- uint32_t temp;
- int32_t i;
-
- for (mc = sc->sc_mixer_root; mc;
- mc = mc->next) {
-
- if ((mc->ctl == SOUND_MIXER_NRDEVICES) &&
- (mc->type == MIX_SELECTOR)) {
-
- /* compute selector mask */
-
- mask = 0;
- for (i = mc->minval; (i > 0) && (i <= mc->maxval); i++) {
- mask |= (1 << mc->slctrtype[i - 1]);
- }
-
- temp = mask & src;
- if (temp == 0) {
- continue;
- }
- /* find the first set bit */
- temp = (-temp) & temp;
-
- /* update "src" */
- src &= ~mask;
- src |= temp;
-
- for (i = mc->minval; (i > 0) && (i <= mc->maxval); i++) {
- if (temp != (1 << mc->slctrtype[i - 1])) {
- continue;
- }
- uaudio_mixer_ctl_set(sc, mc, 0, i);
- break;
- }
- }
- }
- return (src);
-}
-
-/*========================================================================*
- * MIDI support routines
- *========================================================================*/
-
-static void
-umidi_read_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct umidi_chan *chan = xfer->priv_sc;
- struct usb2_xfer *xfer_other = chan->xfer[1];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- chan->flags &= ~UMIDI_FLAG_READ_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
-umidi_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct umidi_chan *chan = xfer->priv_sc;
- struct umidi_sub_chan *sub;
- uint8_t buf[1];
- uint8_t cmd_len;
- uint8_t cn;
- uint16_t pos;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- DPRINTF("actlen=%d bytes\n", xfer->actlen);
-
- if (xfer->actlen == 0) {
- /* should not happen */
- goto tr_error;
- }
- pos = 0;
-
- while (xfer->actlen >= 4) {
-
- usb2_copy_out(xfer->frbuffers, pos, buf, 1);
-
- cmd_len = umidi_cmd_to_len[buf[0] & 0xF]; /* command length */
- cn = buf[0] >> 4; /* cable number */
- sub = &chan->sub[cn];
-
- if (cmd_len && (cn < chan->max_cable) && sub->read_open) {
- usb2_fifo_put_data(sub->fifo.fp[USB_FIFO_RX], xfer->frbuffers,
- pos + 1, cmd_len, 1);
- } else {
- /* ignore the command */
- }
-
- xfer->actlen -= 4;
- pos += 4;
- }
-
- case USB_ST_SETUP:
- DPRINTF("start\n");
-
- if (chan->flags & UMIDI_FLAG_READ_STALL) {
- usb2_transfer_start(chan->xfer[3]);
- return;
- }
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default:
-tr_error:
-
- DPRINTF("error=%s\n", usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- chan->flags |= UMIDI_FLAG_READ_STALL;
- usb2_transfer_start(chan->xfer[3]);
- }
- return;
-
- }
-}
-
-static void
-umidi_write_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct umidi_chan *chan = xfer->priv_sc;
- struct usb2_xfer *xfer_other = chan->xfer[0];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- chan->flags &= ~UMIDI_FLAG_WRITE_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-/*
- * The following statemachine, that converts MIDI commands to
- * USB MIDI packets, derives from Linux's usbmidi.c, which
- * was written by "Clemens Ladisch":
- *
- * Returns:
- * 0: No command
- * Else: Command is complete
- */
-static uint8_t
-umidi_convert_to_usb(struct umidi_sub_chan *sub, uint8_t cn, uint8_t b)
-{
- uint8_t p0 = (cn << 4);
-
- if (b >= 0xf8) {
- sub->temp_0[0] = p0 | 0x0f;
- sub->temp_0[1] = b;
- sub->temp_0[2] = 0;
- sub->temp_0[3] = 0;
- sub->temp_cmd = sub->temp_0;
- return (1);
-
- } else if (b >= 0xf0) {
- switch (b) {
- case 0xf0: /* system exclusive begin */
- sub->temp_1[1] = b;
- sub->state = UMIDI_ST_SYSEX_1;
- break;
- case 0xf1: /* MIDI time code */
- case 0xf3: /* song select */
- sub->temp_1[1] = b;
- sub->state = UMIDI_ST_1PARAM;
- break;
- case 0xf2: /* song position pointer */
- sub->temp_1[1] = b;
- sub->state = UMIDI_ST_2PARAM_1;
- break;
- case 0xf4: /* unknown */
- case 0xf5: /* unknown */
- sub->state = UMIDI_ST_UNKNOWN;
- break;
- case 0xf6: /* tune request */
- sub->temp_1[0] = p0 | 0x05;
- sub->temp_1[1] = 0xf6;
- sub->temp_1[2] = 0;
- sub->temp_1[3] = 0;
- sub->temp_cmd = sub->temp_1;
- sub->state = UMIDI_ST_UNKNOWN;
- return (1);
-
- case 0xf7: /* system exclusive end */
- switch (sub->state) {
- case UMIDI_ST_SYSEX_0:
- sub->temp_1[0] = p0 | 0x05;
- sub->temp_1[1] = 0xf7;
- sub->temp_1[2] = 0;
- sub->temp_1[3] = 0;
- sub->temp_cmd = sub->temp_1;
- sub->state = UMIDI_ST_UNKNOWN;
- return (1);
- case UMIDI_ST_SYSEX_1:
- sub->temp_1[0] = p0 | 0x06;
- sub->temp_1[2] = 0xf7;
- sub->temp_1[3] = 0;
- sub->temp_cmd = sub->temp_1;
- sub->state = UMIDI_ST_UNKNOWN;
- return (1);
- case UMIDI_ST_SYSEX_2:
- sub->temp_1[0] = p0 | 0x07;
- sub->temp_1[3] = 0xf7;
- sub->temp_cmd = sub->temp_1;
- sub->state = UMIDI_ST_UNKNOWN;
- return (1);
- }
- sub->state = UMIDI_ST_UNKNOWN;
- break;
- }
- } else if (b >= 0x80) {
- sub->temp_1[1] = b;
- if ((b >= 0xc0) && (b <= 0xdf)) {
- sub->state = UMIDI_ST_1PARAM;
- } else {
- sub->state = UMIDI_ST_2PARAM_1;
- }
- } else { /* b < 0x80 */
- switch (sub->state) {
- case UMIDI_ST_1PARAM:
- if (sub->temp_1[1] < 0xf0) {
- p0 |= sub->temp_1[1] >> 4;
- } else {
- p0 |= 0x02;
- sub->state = UMIDI_ST_UNKNOWN;
- }
- sub->temp_1[0] = p0;
- sub->temp_1[2] = b;
- sub->temp_1[3] = 0;
- sub->temp_cmd = sub->temp_1;
- return (1);
- case UMIDI_ST_2PARAM_1:
- sub->temp_1[2] = b;
- sub->state = UMIDI_ST_2PARAM_2;
- break;
- case UMIDI_ST_2PARAM_2:
- if (sub->temp_1[1] < 0xf0) {
- p0 |= sub->temp_1[1] >> 4;
- sub->state = UMIDI_ST_2PARAM_1;
- } else {
- p0 |= 0x03;
- sub->state = UMIDI_ST_UNKNOWN;
- }
- sub->temp_1[0] = p0;
- sub->temp_1[3] = b;
- sub->temp_cmd = sub->temp_1;
- return (1);
- case UMIDI_ST_SYSEX_0:
- sub->temp_1[1] = b;
- sub->state = UMIDI_ST_SYSEX_1;
- break;
- case UMIDI_ST_SYSEX_1:
- sub->temp_1[2] = b;
- sub->state = UMIDI_ST_SYSEX_2;
- break;
- case UMIDI_ST_SYSEX_2:
- sub->temp_1[0] = p0 | 0x04;
- sub->temp_1[3] = b;
- sub->temp_cmd = sub->temp_1;
- sub->state = UMIDI_ST_SYSEX_0;
- return (1);
- }
- }
- return (0);
-}
-
-static void
-umidi_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct umidi_chan *chan = xfer->priv_sc;
- struct umidi_sub_chan *sub;
- uint32_t actlen;
- uint16_t total_length;
- uint8_t buf;
- uint8_t start_cable;
- uint8_t tr_any;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTF("actlen=%d bytes\n", xfer->actlen);
-
- case USB_ST_SETUP:
-
- DPRINTF("start\n");
-
- if (chan->flags & UMIDI_FLAG_WRITE_STALL) {
- usb2_transfer_start(chan->xfer[2]);
- return;
- }
- total_length = 0; /* reset */
-
- start_cable = chan->curr_cable;
-
- tr_any = 0;
-
- while (1) {
-
- /* round robin de-queueing */
-
- sub = &chan->sub[chan->curr_cable];
-
- if (sub->write_open) {
- usb2_fifo_get_data(sub->fifo.fp[USB_FIFO_TX],
- xfer->frbuffers, total_length,
- 1, &actlen, 0);
- } else {
- actlen = 0;
- }
-
- if (actlen) {
- usb2_copy_out(xfer->frbuffers, total_length, &buf, 1);
-
- tr_any = 1;
-
- DPRINTF("byte=0x%02x\n", buf);
-
- if (umidi_convert_to_usb(sub, chan->curr_cable, buf)) {
-
- DPRINTF("sub= %02x %02x %02x %02x\n",
- sub->temp_cmd[0], sub->temp_cmd[1],
- sub->temp_cmd[2], sub->temp_cmd[3]);
-
- usb2_copy_in(xfer->frbuffers, total_length,
- sub->temp_cmd, 4);
-
- total_length += 4;
-
- if (total_length >= UMIDI_BULK_SIZE) {
- break;
- }
- } else {
- continue;
- }
- }
- chan->curr_cable++;
- if (chan->curr_cable >= chan->max_cable) {
- chan->curr_cable = 0;
- }
- if (chan->curr_cable == start_cable) {
- if (tr_any == 0) {
- break;
- }
- tr_any = 0;
- }
- }
-
- if (total_length) {
- xfer->frlengths[0] = total_length;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
-
- DPRINTF("error=%s\n", usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- chan->flags |= UMIDI_FLAG_WRITE_STALL;
- usb2_transfer_start(chan->xfer[2]);
- }
- return;
-
- }
-}
-
-static struct umidi_sub_chan *
-umidi_sub_by_fifo(struct usb2_fifo *fifo)
-{
- struct umidi_chan *chan = fifo->priv_sc0;
- struct umidi_sub_chan *sub;
- uint32_t n;
-
- for (n = 0; n < UMIDI_CABLES_MAX; n++) {
- sub = &chan->sub[n];
- if ((sub->fifo.fp[USB_FIFO_RX] == fifo) ||
- (sub->fifo.fp[USB_FIFO_TX] == fifo)) {
- return (sub);
- }
- }
-
- panic("%s:%d cannot find usb2_fifo!\n",
- __FILE__, __LINE__);
-
- return (NULL);
-}
-
-static void
-umidi_start_read(struct usb2_fifo *fifo)
-{
- struct umidi_chan *chan = fifo->priv_sc0;
-
- usb2_transfer_start(chan->xfer[1]);
-}
-
-static void
-umidi_stop_read(struct usb2_fifo *fifo)
-{
- struct umidi_chan *chan = fifo->priv_sc0;
- struct umidi_sub_chan *sub = umidi_sub_by_fifo(fifo);
-
- DPRINTF("\n");
-
- sub->read_open = 0;
-
- if (--(chan->read_open_refcount) == 0) {
- /*
- * XXX don't stop the read transfer here, hence that causes
- * problems with some MIDI adapters
- */
- DPRINTF("(stopping read transfer)\n");
- }
-}
-
-static void
-umidi_start_write(struct usb2_fifo *fifo)
-{
- struct umidi_chan *chan = fifo->priv_sc0;
-
- usb2_transfer_start(chan->xfer[0]);
-}
-
-static void
-umidi_stop_write(struct usb2_fifo *fifo)
-{
- struct umidi_chan *chan = fifo->priv_sc0;
- struct umidi_sub_chan *sub = umidi_sub_by_fifo(fifo);
-
- DPRINTF("\n");
-
- sub->write_open = 0;
-
- if (--(chan->write_open_refcount) == 0) {
- DPRINTF("(stopping write transfer)\n");
- usb2_transfer_stop(chan->xfer[2]);
- usb2_transfer_stop(chan->xfer[0]);
- }
-}
-
-static int
-umidi_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- struct umidi_chan *chan = fifo->priv_sc0;
- struct umidi_sub_chan *sub = umidi_sub_by_fifo(fifo);
-
- if (fflags & FREAD) {
- if (usb2_fifo_alloc_buffer(fifo, 4, (1024 / 4))) {
- return (ENOMEM);
- }
- mtx_lock(fifo->priv_mtx);
- chan->read_open_refcount++;
- sub->read_open = 1;
- mtx_unlock(fifo->priv_mtx);
- }
- if (fflags & FWRITE) {
- if (usb2_fifo_alloc_buffer(fifo, 32, (1024 / 32))) {
- return (ENOMEM);
- }
- /* clear stall first */
- mtx_lock(fifo->priv_mtx);
- chan->flags |= UMIDI_FLAG_WRITE_STALL;
- chan->write_open_refcount++;
- sub->write_open = 1;
-
- /* reset */
- sub->state = UMIDI_ST_UNKNOWN;
- mtx_unlock(fifo->priv_mtx);
- }
- return (0); /* success */
-}
-
-static void
-umidi_close(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- if (fflags & FREAD) {
- usb2_fifo_free_buffer(fifo);
- }
- if (fflags & FWRITE) {
- usb2_fifo_free_buffer(fifo);
- }
-}
-
-
-static int
-umidi_ioctl(struct usb2_fifo *fifo, u_long cmd, void *data,
- int fflags, struct thread *td)
-{
- return (ENODEV);
-}
-
-static void
-umidi_init(device_t dev)
-{
- struct uaudio_softc *sc = device_get_softc(dev);
- struct umidi_chan *chan = &sc->sc_midi_chan;
-
- mtx_init(&chan->mtx, "umidi lock", NULL, MTX_DEF | MTX_RECURSE);
-}
-
-static struct usb2_fifo_methods umidi_fifo_methods = {
- .f_start_read = &umidi_start_read,
- .f_start_write = &umidi_start_write,
- .f_stop_read = &umidi_stop_read,
- .f_stop_write = &umidi_stop_write,
- .f_open = &umidi_open,
- .f_close = &umidi_close,
- .f_ioctl = &umidi_ioctl,
- .basename[0] = "umidi",
-};
-
-static int32_t
-umidi_probe(device_t dev)
-{
- struct uaudio_softc *sc = device_get_softc(dev);
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct umidi_chan *chan = &sc->sc_midi_chan;
- struct umidi_sub_chan *sub;
- int unit = device_get_unit(dev);
- int error;
- uint32_t n;
-
- if (usb2_set_alt_interface_index(sc->sc_udev, chan->iface_index,
- chan->iface_alt_index)) {
- DPRINTF("setting of alternate index failed!\n");
- goto detach;
- }
- usb2_set_parent_iface(sc->sc_udev, chan->iface_index, sc->sc_mixer_iface_index);
-
- error = usb2_transfer_setup(uaa->device, &chan->iface_index,
- chan->xfer, umidi_config, UMIDI_N_TRANSFER,
- chan, &chan->mtx);
- if (error) {
- DPRINTF("error=%s\n", usb2_errstr(error));
- goto detach;
- }
- if ((chan->max_cable > UMIDI_CABLES_MAX) ||
- (chan->max_cable == 0)) {
- chan->max_cable = UMIDI_CABLES_MAX;
- }
- /* set interface permissions */
- usb2_set_iface_perm(sc->sc_udev, chan->iface_index,
- UID_ROOT, GID_OPERATOR, 0644);
-
- for (n = 0; n < chan->max_cable; n++) {
-
- sub = &chan->sub[n];
-
- error = usb2_fifo_attach(sc->sc_udev, chan, &chan->mtx,
- &umidi_fifo_methods, &sub->fifo, unit, n,
- chan->iface_index);
- if (error) {
- goto detach;
- }
- }
-
- mtx_lock(&chan->mtx);
-
- /* clear stall first */
- chan->flags |= UMIDI_FLAG_READ_STALL;
-
- /*
- * NOTE: at least one device will not work properly unless
- * the BULK pipe is open all the time.
- */
- usb2_transfer_start(chan->xfer[1]);
-
- mtx_unlock(&chan->mtx);
-
- return (0); /* success */
-
-detach:
- return (ENXIO); /* failure */
-}
-
-static int32_t
-umidi_detach(device_t dev)
-{
- struct uaudio_softc *sc = device_get_softc(dev);
- struct umidi_chan *chan = &sc->sc_midi_chan;
- uint32_t n;
-
- for (n = 0; n < UMIDI_CABLES_MAX; n++) {
- usb2_fifo_detach(&chan->sub[n].fifo);
- }
-
- mtx_lock(&chan->mtx);
-
- usb2_transfer_stop(chan->xfer[3]);
- usb2_transfer_stop(chan->xfer[1]);
-
- mtx_unlock(&chan->mtx);
-
- usb2_transfer_unsetup(chan->xfer, UMIDI_N_TRANSFER);
-
- mtx_destroy(&chan->mtx);
-
- return (0);
-}
-
-DRIVER_MODULE(uaudio, ushub, uaudio_driver, uaudio_devclass, NULL, 0);
-MODULE_DEPEND(uaudio, usb2_sound, 1, 1, 1);
-MODULE_DEPEND(uaudio, usb2_core, 1, 1, 1);
-MODULE_DEPEND(uaudio, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
-MODULE_VERSION(uaudio, 1);
diff --git a/sys/dev/usb2/sound/uaudio2.h b/sys/dev/usb2/sound/uaudio2.h
deleted file mode 100644
index e763c6d..0000000
--- a/sys/dev/usb2/sound/uaudio2.h
+++ /dev/null
@@ -1,63 +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.
- */
-
-/* prototypes from "uaudio.c" used by "uaudio_pcm.c" */
-
-struct uaudio_chan;
-struct uaudio_softc;
-struct snd_dbuf;
-struct snd_mixer;
-struct pcm_channel;
-
-extern int uaudio_attach_sub(device_t dev, kobj_class_t mixer_class,
- kobj_class_t chan_class);
-extern int uaudio_detach_sub(device_t dev);
-extern void *uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b,
- struct pcm_channel *c, int dir);
-extern int uaudio_chan_free(struct uaudio_chan *ch);
-extern int uaudio_chan_set_param_blocksize(struct uaudio_chan *ch,
- uint32_t blocksize);
-extern int uaudio_chan_set_param_fragments(struct uaudio_chan *ch,
- uint32_t blocksize, uint32_t blockcount);
-extern int uaudio_chan_set_param_speed(struct uaudio_chan *ch,
- uint32_t speed);
-extern int uaudio_chan_getptr(struct uaudio_chan *ch);
-extern struct pcmchan_caps *uaudio_chan_getcaps(struct uaudio_chan *ch);
-extern int uaudio_chan_set_param_format(struct uaudio_chan *ch,
- uint32_t format);
-extern int uaudio_chan_start(struct uaudio_chan *ch);
-extern int uaudio_chan_stop(struct uaudio_chan *ch);
-extern int uaudio_mixer_init_sub(struct uaudio_softc *sc,
- struct snd_mixer *m);
-extern int uaudio_mixer_uninit_sub(struct uaudio_softc *sc);
-extern void uaudio_mixer_set(struct uaudio_softc *sc, unsigned type,
- unsigned left, unsigned right);
-extern uint32_t uaudio_mixer_setrecsrc(struct uaudio_softc *sc, uint32_t src);
-
-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/dev/usb2/sound/uaudio2_pcm.c b/sys/dev/usb2/sound/uaudio2_pcm.c
deleted file mode 100644
index c073c19..0000000
--- a/sys/dev/usb2/sound/uaudio2_pcm.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2000-2002 Hiroyuki Aizu <aizu@navi.org>
- * Copyright (c) 2006 Hans Petter Selasky
- *
- * 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/usb2/sound/uaudio2.h>
-
-#include "mixer_if.h"
-
-/************************************************************/
-static void *
-ua_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
-{
- return (uaudio_chan_init(devinfo, b, c, dir));
-}
-
-static int
-ua_chan_free(kobj_t obj, void *data)
-{
- return (uaudio_chan_free(data));
-}
-
-static int
-ua_chan_setformat(kobj_t obj, void *data, uint32_t format)
-{
- /*
- * At this point, no need to query as we
- * shouldn't select an unsorted format
- */
- return (uaudio_chan_set_param_format(data, format));
-}
-
-static int
-ua_chan_setspeed(kobj_t obj, void *data, uint32_t speed)
-{
- return (uaudio_chan_set_param_speed(data, speed));
-}
-
-static int
-ua_chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
-{
- return (uaudio_chan_set_param_blocksize(data, blocksize));
-}
-
-static int
-ua_chan_setfragments(kobj_t obj, void *data, uint32_t blocksize, uint32_t blockcount)
-{
- return (uaudio_chan_set_param_fragments(data, blocksize, blockcount));
-}
-
-static int
-ua_chan_trigger(kobj_t obj, void *data, int go)
-{
- if (!PCMTRIG_COMMON(go)) {
- return (0);
- }
- if (go == PCMTRIG_START) {
- return (uaudio_chan_start(data));
- } else {
- return (uaudio_chan_stop(data));
- }
-}
-
-static int
-ua_chan_getptr(kobj_t obj, void *data)
-{
- return (uaudio_chan_getptr(data));
-}
-
-static struct pcmchan_caps *
-ua_chan_getcaps(kobj_t obj, void *data)
-{
- return (uaudio_chan_getcaps(data));
-}
-
-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)
-{
- return (uaudio_mixer_init_sub(mix_getdevinfo(m), m));
-}
-
-static int
-ua_mixer_set(struct snd_mixer *m, unsigned type, unsigned left, unsigned right)
-{
- struct mtx *mtx = mixer_get_lock(m);
- uint8_t do_unlock;
-
- if (mtx_owned(mtx)) {
- do_unlock = 0;
- } else {
- do_unlock = 1;
- mtx_lock(mtx);
- }
- uaudio_mixer_set(mix_getdevinfo(m), type, left, right);
- if (do_unlock) {
- mtx_unlock(mtx);
- }
- return (left | (right << 8));
-}
-
-static int
-ua_mixer_setrecsrc(struct snd_mixer *m, uint32_t src)
-{
- struct mtx *mtx = mixer_get_lock(m);
- int retval;
- uint8_t do_unlock;
-
- if (mtx_owned(mtx)) {
- do_unlock = 0;
- } else {
- do_unlock = 1;
- mtx_lock(mtx);
- }
- retval = uaudio_mixer_setrecsrc(mix_getdevinfo(m), src);
- if (do_unlock) {
- mtx_unlock(mtx);
- }
- return (retval);
-}
-
-static int
-ua_mixer_uninit(struct snd_mixer *m)
-{
- return (uaudio_mixer_uninit_sub(mix_getdevinfo(m)));
-}
-
-static kobj_method_t ua_mixer_methods[] = {
- KOBJMETHOD(mixer_init, ua_mixer_init),
- KOBJMETHOD(mixer_uninit, ua_mixer_uninit),
- 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)
-{
- 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);
- }
- device_set_desc(dev, "USB audio");
-
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-ua_attach(device_t dev)
-{
- return (uaudio_attach_sub(dev, &ua_mixer_class, &ua_chan_class));
-}
-
-static int
-ua_detach(device_t dev)
-{
- return (uaudio_detach_sub(dev));
-}
-
-/************************************************************/
-
-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/dev/usb2/sound/uaudio2_reg.h b/sys/dev/usb2/sound/uaudio2_reg.h
deleted file mode 100644
index 2bf68a1..0000000
--- a/sys/dev/usb2/sound/uaudio2_reg.h
+++ /dev/null
@@ -1,406 +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 struct usb2_endpoint_descriptor */
-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;
-} __packed usb2_endpoint_descriptor_audio_t;
-
-struct usb2_audio_control_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uWord bcdADC;
- uWord wTotalLength;
- uByte bInCollection;
- uByte baInterfaceNr[1];
-} __packed;
-
-struct usb2_audio_streaming_interface_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bTerminalLink;
- uByte bDelay;
- uWord wFormatTag;
-} __packed;
-
-struct usb2_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;
-} __packed;
-
-struct usb2_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[0];
-#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)
-} __packed;
-
-struct usb2_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;
-} __packed;
-
-/* Shared by all units and terminals */
-struct usb2_audio_unit {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
-};
-
-/* UDESCSUB_AC_INPUT */
-struct usb2_audio_input_terminal {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bTerminalId;
- uWord wTerminalType;
- uByte bAssocTerminal;
- uByte bNrChannels;
- uWord wChannelConfig;
- uByte iChannelNames;
-/* uByte iTerminal; */
-} __packed;
-
-/* UDESCSUB_AC_OUTPUT */
-struct usb2_audio_output_terminal {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bTerminalId;
- uWord wTerminalType;
- uByte bAssocTerminal;
- uByte bSourceId;
- uByte iTerminal;
-} __packed;
-
-/* UDESCSUB_AC_MIXER */
-struct usb2_audio_mixer_unit_0 {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
- uByte bNrInPins;
- uByte baSourceId[0]; /* [bNrInPins] */
- /* struct usb2_audio_mixer_unit_1 */
-} __packed;
-struct usb2_audio_mixer_unit_1 {
- uByte bNrChannels;
- uWord wChannelConfig;
- uByte iChannelNames;
- uByte bmControls[0]; /* [see source code] */
- /* uByte iMixer; */
-} __packed;
-
-/* UDESCSUB_AC_SELECTOR */
-struct usb2_audio_selector_unit {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
- uByte bNrInPins;
- uByte baSourceId[0]; /* [bNrInPins] */
- /* uByte iSelector; */
-} __packed;
-
-/* UDESCSUB_AC_FEATURE */
-struct usb2_audio_feature_unit {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
- uByte bSourceId;
- uByte bControlSize;
- uByte bmaControls[0]; /* [bControlSize * x] */
- /* uByte iFeature; */
-} __packed;
-
-/* UDESCSUB_AC_PROCESSING */
-struct usb2_audio_processing_unit_0 {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
- uWord wProcessType;
- uByte bNrInPins;
- uByte baSourceId[0]; /* [bNrInPins] */
- /* struct usb2_audio_processing_unit_1 */
-} __packed;
-struct usb2_audio_processing_unit_1 {
- uByte bNrChannels;
- uWord wChannelConfig;
- uByte iChannelNames;
- uByte bControlSize;
- uByte bmControls[0]; /* [bControlSize] */
-#define UA_PROC_ENABLE_MASK 1
-} __packed;
-
-struct usb2_audio_processing_unit_updown {
- uByte iProcessing;
- uByte bNrModes;
- uWord waModes[0]; /* [bNrModes] */
-} __packed;
-
-/* UDESCSUB_AC_EXTENSION */
-struct usb2_audio_extension_unit_0 {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bUnitId;
- uWord wExtensionCode;
- uByte bNrInPins;
- uByte baSourceId[0]; /* [bNrInPins] */
- /* struct usb2_audio_extension_unit_1 */
-} __packed;
-struct usb2_audio_extension_unit_1 {
- uByte bNrChannels;
- uWord wChannelConfig;
- uByte iChannelNames;
- uByte bControlSize;
- uByte bmControls[0]; /* [bControlSize] */
-#define UA_EXT_ENABLE_MASK 1
-#define UA_EXT_ENABLE 1
- /* uByte iExtension; */
-} __packed;
-
-/* 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/dev/usb2/sound/usb2_sound.c b/sys/dev/usb2/sound/usb2_sound.c
deleted file mode 100644
index 0e6994b..0000000
--- a/sys/dev/usb2/sound/usb2_sound.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/sound/usb2_sound.h>
-
-MODULE_VERSION(usb2_sound, 1);
-MODULE_DEPEND(usb2_sound, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/sound/usb2_sound.h b/sys/dev/usb2/sound/usb2_sound.h
deleted file mode 100644
index 5b6ae15..0000000
--- a/sys/dev/usb2/sound/usb2_sound.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_SOUND_H_
-#define _USB2_SOUND_H_
-
-#endif /* _USB2_SOUND_H_ */
diff --git a/sys/dev/usb2/storage/ata-usb2.c b/sys/dev/usb2/storage/ata-usb2.c
deleted file mode 100644
index a4d2da4..0000000
--- a/sys/dev/usb2/storage/ata-usb2.c
+++ /dev/null
@@ -1,1103 +0,0 @@
-/*-
- * Copyright (c) 2006 - 2008 Søren Schmidt <sos@FreeBSD.org>
- * All rights reserved.
- *
- * Copyright (c) 2006 Hans Petter Selasky
- * 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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_transfer.h>
-
-#include <sys/ata.h>
-#include <sys/bio.h>
-#include <sys/sema.h>
-#include <sys/taskqueue.h>
-#include <vm/uma.h>
-
-#include <dev/ata/ata-all.h>
-#include <ata_if.h>
-
-#define ATAUSB_BULK_SIZE (1<<17)
-
-/* Command Block Wrapper */
-struct bbb_cbw {
- uint8_t signature[4];
-#define CBWSIGNATURE 0x43425355
-
- uint8_t tag[4];
- uint8_t transfer_length[4];
- uint8_t flags;
-#define CBWFLAGS_OUT 0x00
-#define CBWFLAGS_IN 0x80
-
- uint8_t lun;
- uint8_t length;
-#define CBWCDBLENGTH 16
-
- uint8_t cdb[CBWCDBLENGTH];
-} __packed;
-
-/* Command Status Wrapper */
-struct bbb_csw {
- uint8_t signature[4];
-#define CSWSIGNATURE 0x53425355
-
- uint8_t tag[4];
- uint8_t residue[4];
- uint8_t status;
-#define CSWSTATUS_GOOD 0x0
-#define CSWSTATUS_FAILED 0x1
-#define CSWSTATUS_PHASE 0x2
-} __packed;
-
-/* USB-ATA 'controller' softc */
-struct atausb2_softc {
- struct bbb_cbw cbw;
- struct bbb_csw csw;
- struct mtx locked_mtx;
-
- struct ata_channel *locked_ch;
- struct ata_channel *restart_ch;
- struct ata_request *ata_request;
-
-#define ATAUSB_T_BBB_RESET1 0
-#define ATAUSB_T_BBB_RESET2 1
-#define ATAUSB_T_BBB_RESET3 2
-#define ATAUSB_T_BBB_COMMAND 3
-#define ATAUSB_T_BBB_DATA_READ 4
-#define ATAUSB_T_BBB_DATA_RD_CS 5
-#define ATAUSB_T_BBB_DATA_WRITE 6
-#define ATAUSB_T_BBB_DATA_WR_CS 7
-#define ATAUSB_T_BBB_STATUS 8
-#define ATAUSB_T_BBB_MAX 9
-
-#define ATAUSB_T_MAX ATAUSB_T_BBB_MAX
-
- struct usb2_xfer *xfer[ATAUSB_T_MAX];
- caddr_t ata_data;
- device_t dev;
-
- uint32_t timeout;
- uint32_t ata_donecount;
- uint32_t ata_bytecount;
-
- uint8_t last_xfer_no;
- uint8_t usb2_speed;
- uint8_t intr_stalled;
- uint8_t maxlun;
- uint8_t iface_no;
- uint8_t status_try;
-};
-
-static const int atausbdebug = 0;
-
-/* prototypes */
-
-static device_probe_t atausb2_probe;
-static device_attach_t atausb2_attach;
-static device_detach_t atausb2_detach;
-
-static usb2_callback_t atausb2_t_bbb_reset1_callback;
-static usb2_callback_t atausb2_t_bbb_reset2_callback;
-static usb2_callback_t atausb2_t_bbb_reset3_callback;
-static usb2_callback_t atausb2_t_bbb_command_callback;
-static usb2_callback_t atausb2_t_bbb_data_read_callback;
-static usb2_callback_t atausb2_t_bbb_data_rd_cs_callback;
-static usb2_callback_t atausb2_t_bbb_data_write_callback;
-static usb2_callback_t atausb2_t_bbb_data_wr_cs_callback;
-static usb2_callback_t atausb2_t_bbb_status_callback;
-static usb2_callback_t atausb2_tr_error;
-
-static void atausb2_cancel_request(struct atausb2_softc *sc);
-static void atausb2_transfer_start(struct atausb2_softc *sc, uint8_t xfer_no);
-static void atausb2_t_bbb_data_clear_stall_callback(struct usb2_xfer *xfer, uint8_t next_xfer, uint8_t stall_xfer);
-static int ata_usbchannel_begin_transaction(struct ata_request *request);
-static int ata_usbchannel_end_transaction(struct ata_request *request);
-
-static device_probe_t ata_usbchannel_probe;
-static device_attach_t ata_usbchannel_attach;
-static device_detach_t ata_usbchannel_detach;
-
-static ata_setmode_t ata_usbchannel_setmode;
-static ata_locking_t ata_usbchannel_locking;
-
-/*
- * USB frontend part
- */
-
-struct usb2_config atausb2_config[ATAUSB_T_BBB_MAX] = {
-
- [ATAUSB_T_BBB_RESET1] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &atausb2_t_bbb_reset1_callback,
- .mh.timeout = 5000, /* 5 seconds */
- .mh.interval = 500, /* 500 milliseconds */
- },
-
- [ATAUSB_T_BBB_RESET2] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &atausb2_t_bbb_reset2_callback,
- .mh.timeout = 5000, /* 5 seconds */
- .mh.interval = 50, /* 50 milliseconds */
- },
-
- [ATAUSB_T_BBB_RESET3] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &atausb2_t_bbb_reset3_callback,
- .mh.timeout = 5000, /* 5 seconds */
- .mh.interval = 50, /* 50 milliseconds */
- },
-
- [ATAUSB_T_BBB_COMMAND] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = sizeof(struct bbb_cbw),
- .mh.flags = {},
- .mh.callback = &atausb2_t_bbb_command_callback,
- .mh.timeout = 5000, /* 5 seconds */
- },
-
- [ATAUSB_T_BBB_DATA_READ] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = ATAUSB_BULK_SIZE,
- .mh.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
- .mh.callback = &atausb2_t_bbb_data_read_callback,
- .mh.timeout = 0, /* overwritten later */
- },
-
- [ATAUSB_T_BBB_DATA_RD_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &atausb2_t_bbb_data_rd_cs_callback,
- .mh.timeout = 5000, /* 5 seconds */
- },
-
- [ATAUSB_T_BBB_DATA_WRITE] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = ATAUSB_BULK_SIZE,
- .mh.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
- .mh.callback = &atausb2_t_bbb_data_write_callback,
- .mh.timeout = 0, /* overwritten later */
- },
-
- [ATAUSB_T_BBB_DATA_WR_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &atausb2_t_bbb_data_wr_cs_callback,
- .mh.timeout = 5000, /* 5 seconds */
- },
-
- [ATAUSB_T_BBB_STATUS] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = sizeof(struct bbb_csw),
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &atausb2_t_bbb_status_callback,
- .mh.timeout = 5000, /* ms */
- },
-};
-
-static devclass_t atausb2_devclass;
-
-static device_method_t atausb2_methods[] = {
- DEVMETHOD(device_probe, atausb2_probe),
- DEVMETHOD(device_attach, atausb2_attach),
- DEVMETHOD(device_detach, atausb2_detach),
- {0, 0}
-};
-
-static driver_t atausb2_driver = {
- .name = "atausb",
- .methods = atausb2_methods,
- .size = sizeof(struct atausb2_softc),
-};
-
-DRIVER_MODULE(atausb, ushub, atausb2_driver, atausb2_devclass, 0, 0);
-MODULE_DEPEND(atausb, usb2_storage, 1, 1, 1);
-MODULE_DEPEND(atausb, usb2_core, 1, 1, 1);
-MODULE_VERSION(atausb, 1);
-
-static int
-atausb2_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct usb2_interface_descriptor *id;
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->use_generic == 0) {
- /* give other drivers a try first */
- return (ENXIO);
- }
- id = usb2_get_interface_descriptor(uaa->iface);
- if ((!id) || (id->bInterfaceClass != UICLASS_MASS)) {
- return (ENXIO);
- }
- 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 (0);
- default:
- return (0);
- }
- break;
- default:
- return (0);
- }
-}
-
-static int
-atausb2_attach(device_t dev)
-{
- struct atausb2_softc *sc = device_get_softc(dev);
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct usb2_interface_descriptor *id;
- const char *proto, *subclass;
- struct usb2_device_request request;
- uint16_t i;
- uint8_t maxlun;
- uint8_t has_intr;
- int err;
-
- device_set_usb2_desc(dev);
-
- sc->dev = dev;
- sc->maxlun = 0;
- sc->locked_ch = NULL;
- sc->restart_ch = NULL;
- sc->usb2_speed = usb2_get_speed(uaa->device);
- mtx_init(&sc->locked_mtx, "ATAUSB lock", NULL, (MTX_DEF | MTX_RECURSE));
-
- id = usb2_get_interface_descriptor(uaa->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";
- }
-
- has_intr = (id->bInterfaceProtocol == UIPROTO_MASS_CBI_I);
- sc->iface_no = id->bInterfaceNumber;
-
- device_printf(dev, "using %s over %s\n", subclass, proto);
- if (strcmp(proto, "Bulk-Only") ||
- (strcmp(subclass, "ATAPI") && strcmp(subclass, "SCSI"))) {
- goto detach;
- }
- err = usb2_transfer_setup(uaa->device, &uaa->info.bIfaceIndex,
- sc->xfer, atausb2_config, ATAUSB_T_BBB_MAX, sc,
- &sc->locked_mtx);
-
- /* skip reset first time */
- sc->last_xfer_no = ATAUSB_T_BBB_COMMAND;
-
- if (err) {
- device_printf(sc->dev, "could not setup required "
- "transfers, %s\n", usb2_errstr(err));
- goto detach;
- }
- /* get number of devices so we can add matching channels */
- request.bmRequestType = UT_READ_CLASS_INTERFACE;
- request.bRequest = 0xfe; /* GET_MAX_LUN; */
- USETW(request.wValue, 0);
- USETW(request.wIndex, sc->iface_no);
- USETW(request.wLength, sizeof(maxlun));
- err = usb2_do_request(uaa->device, &Giant, &request, &maxlun);
-
- if (err) {
- if (bootverbose) {
- device_printf(sc->dev, "get maxlun not supported %s\n",
- usb2_errstr(err));
- }
- } else {
- sc->maxlun = maxlun;
- if (bootverbose) {
- device_printf(sc->dev, "maxlun=%d\n", sc->maxlun);
- }
- }
-
- /* ata channels are children to this USB control device */
- for (i = 0; i <= sc->maxlun; i++) {
- if (!device_add_child(sc->dev, "ata",
- devclass_find_free_unit(ata_devclass, 2))) {
- device_printf(sc->dev, "failed to attach ata child device\n");
- goto detach;
- }
- }
- bus_generic_attach(sc->dev);
-
- return (0);
-
-detach:
- atausb2_detach(dev);
- return (ENXIO);
-}
-
-static int
-atausb2_detach(device_t dev)
-{
- struct atausb2_softc *sc = device_get_softc(dev);
- device_t *children;
- int nchildren, i;
-
- /* teardown our statemachine */
-
- usb2_transfer_unsetup(sc->xfer, ATAUSB_T_MAX);
-
- /* detach & delete all children, if any */
-
- if (!device_get_children(dev, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++) {
- device_delete_child(dev, children[i]);
- }
- free(children, M_TEMP);
- }
- mtx_destroy(&sc->locked_mtx);
- return (0);
-}
-
-static void
-atausb2_transfer_start(struct atausb2_softc *sc, uint8_t xfer_no)
-{
- if (atausbdebug) {
- device_printf(sc->dev, "BBB transfer %d\n", xfer_no);
- }
- if (sc->xfer[xfer_no]) {
- sc->last_xfer_no = xfer_no;
- usb2_transfer_start(sc->xfer[xfer_no]);
- } else {
- atausb2_cancel_request(sc);
- }
-}
-
-static void
-atausb2_t_bbb_reset1_callback(struct usb2_xfer *xfer)
-{
- struct atausb2_softc *sc = xfer->priv_sc;
- struct usb2_device_request req;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- atausb2_transfer_start(sc, ATAUSB_T_BBB_RESET2);
- return;
-
- case USB_ST_SETUP:
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = 0xff; /* bulk-only reset */
- USETW(req.wValue, 0);
- req.wIndex[0] = sc->iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
-
- xfer->frlengths[0] = sizeof(req);
- xfer->nframes = 1;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- atausb2_tr_error(xfer);
- return;
-
- }
-}
-
-static void
-atausb2_t_bbb_reset2_callback(struct usb2_xfer *xfer)
-{
- atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_RESET3,
- ATAUSB_T_BBB_DATA_READ);
-}
-
-static void
-atausb2_t_bbb_reset3_callback(struct usb2_xfer *xfer)
-{
- atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_COMMAND,
- ATAUSB_T_BBB_DATA_WRITE);
-}
-
-static void
-atausb2_t_bbb_data_clear_stall_callback(struct usb2_xfer *xfer,
- uint8_t next_xfer,
- uint8_t stall_xfer)
-{
- struct atausb2_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-tr_transferred:
- atausb2_transfer_start(sc, next_xfer);
- return;
-
- case USB_ST_SETUP:
- if (usb2_clear_stall_callback(xfer, sc->xfer[stall_xfer])) {
- goto tr_transferred;
- }
- return;
-
- default: /* Error */
- atausb2_tr_error(xfer);
- return;
-
- }
-}
-
-static void
-atausb2_t_bbb_command_callback(struct usb2_xfer *xfer)
-{
- struct atausb2_softc *sc = xfer->priv_sc;
- struct ata_request *request = sc->ata_request;
- struct ata_channel *ch;
- uint32_t tag;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- atausb2_transfer_start
- (sc, ((request->flags & ATA_R_READ) ? ATAUSB_T_BBB_DATA_READ :
- (request->flags & ATA_R_WRITE) ? ATAUSB_T_BBB_DATA_WRITE :
- ATAUSB_T_BBB_STATUS));
- return;
-
- case USB_ST_SETUP:
-
- sc->status_try = 0;
-
- if (request) {
- ch = device_get_softc(request->parent);
-
- sc->timeout = (request->timeout * 1000) + 5000;
-
- tag = UGETDW(sc->cbw.tag) + 1;
-
- USETDW(sc->cbw.signature, CBWSIGNATURE);
- USETDW(sc->cbw.tag, tag);
- 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 */
-
- usb2_copy_in(xfer->frbuffers, 0, &sc->cbw, sizeof(sc->cbw));
-
- xfer->frlengths[0] = sizeof(sc->cbw);
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- atausb2_tr_error(xfer);
- return;
-
- }
-}
-
-static void
-atausb2_t_bbb_data_read_callback(struct usb2_xfer *xfer)
-{
- struct atausb2_softc *sc = xfer->priv_sc;
- uint32_t max_bulk = xfer->max_data_length;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- usb2_copy_out(xfer->frbuffers, 0,
- sc->ata_data, xfer->actlen);
-
- sc->ata_bytecount -= xfer->actlen;
- sc->ata_data += xfer->actlen;
- sc->ata_donecount += xfer->actlen;
-
- if (xfer->actlen < xfer->sumlen) {
- /* short transfer */
- sc->ata_bytecount = 0;
- }
- case USB_ST_SETUP:
-
- if (atausbdebug > 1) {
- device_printf(sc->dev, "%s: max_bulk=%d, ata_bytecount=%d\n",
- __FUNCTION__, max_bulk, sc->ata_bytecount);
- }
- if (sc->ata_bytecount == 0) {
- atausb2_transfer_start(sc, ATAUSB_T_BBB_STATUS);
- return;
- }
- if (max_bulk > sc->ata_bytecount) {
- max_bulk = sc->ata_bytecount;
- }
- xfer->timeout = sc->timeout;
- xfer->frlengths[0] = max_bulk;
-
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- atausb2_tr_error(xfer);
- } else {
- atausb2_transfer_start(sc, ATAUSB_T_BBB_DATA_RD_CS);
- }
- return;
-
- }
-}
-
-static void
-atausb2_t_bbb_data_rd_cs_callback(struct usb2_xfer *xfer)
-{
- atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_STATUS,
- ATAUSB_T_BBB_DATA_READ);
-}
-
-static void
-atausb2_t_bbb_data_write_callback(struct usb2_xfer *xfer)
-{
- struct atausb2_softc *sc = xfer->priv_sc;
- uint32_t max_bulk = xfer->max_data_length;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- sc->ata_bytecount -= xfer->actlen;
- sc->ata_data += xfer->actlen;
- sc->ata_donecount += xfer->actlen;
-
- case USB_ST_SETUP:
-
- if (atausbdebug > 1) {
- device_printf(sc->dev, "%s: max_bulk=%d, ata_bytecount=%d\n",
- __FUNCTION__, max_bulk, sc->ata_bytecount);
- }
- if (sc->ata_bytecount == 0) {
- atausb2_transfer_start(sc, ATAUSB_T_BBB_STATUS);
- return;
- }
- if (max_bulk > sc->ata_bytecount) {
- max_bulk = sc->ata_bytecount;
- }
- xfer->timeout = sc->timeout;
- xfer->frlengths[0] = max_bulk;
-
- usb2_copy_in(xfer->frbuffers, 0,
- sc->ata_data, max_bulk);
-
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- atausb2_tr_error(xfer);
- } else {
- atausb2_transfer_start(sc, ATAUSB_T_BBB_DATA_WR_CS);
- }
- return;
-
- }
-}
-
-static void
-atausb2_t_bbb_data_wr_cs_callback(struct usb2_xfer *xfer)
-{
- atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_STATUS,
- ATAUSB_T_BBB_DATA_WRITE);
-}
-
-static void
-atausb2_t_bbb_status_callback(struct usb2_xfer *xfer)
-{
- struct atausb2_softc *sc = xfer->priv_sc;
- struct ata_request *request = sc->ata_request;
- uint32_t residue;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (xfer->actlen < sizeof(sc->csw)) {
- bzero(&sc->csw, sizeof(sc->csw));
- }
- usb2_copy_out(xfer->frbuffers, 0, &sc->csw, xfer->actlen);
-
- if (request->flags & (ATA_R_READ | ATA_R_WRITE)) {
- request->donecount = sc->ata_donecount;
- }
- residue = UGETDW(sc->csw.residue);
-
- if (!residue) {
- residue = (request->bytecount - request->donecount);
- }
- if (residue > request->bytecount) {
- if (atausbdebug) {
- device_printf(sc->dev, "truncating residue from %d "
- "to %d bytes\n", residue,
- request->bytecount);
- }
- residue = request->bytecount;
- }
- /* 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);
- }
- goto tr_error;
- } 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));
- }
- goto tr_error;
- } else if (sc->csw.status > CSWSTATUS_PHASE) {
- if (atausbdebug) {
- device_printf(sc->dev, "bad CSW status %d > %d\n",
- sc->csw.status, CSWSTATUS_PHASE);
- }
- goto tr_error;
- } else if (sc->csw.status == CSWSTATUS_PHASE) {
- if (atausbdebug) {
- device_printf(sc->dev, "phase error residue = %d\n", residue);
- }
- goto tr_error;
- } else if (request->donecount > request->bytecount) {
- if (atausbdebug) {
- device_printf(sc->dev, "buffer overrun %d > %d\n",
- request->donecount, request->bytecount);
- }
- goto tr_error;
- } else if (sc->csw.status == CSWSTATUS_FAILED) {
- if (atausbdebug) {
- device_printf(sc->dev, "CSWSTATUS_FAILED\n");
- }
- request->error = ATA_E_ATAPI_SENSE_MASK;
- }
- sc->last_xfer_no = ATAUSB_T_BBB_COMMAND;
-
- sc->ata_request = NULL;
-
- /* drop the USB transfer lock while doing the ATA interrupt */
- mtx_unlock(&sc->locked_mtx);
-
- ata_interrupt(device_get_softc(request->parent));
-
- mtx_lock(&sc->locked_mtx);
- return;
-
- case USB_ST_SETUP:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default:
-tr_error:
- if ((xfer->error == USB_ERR_CANCELLED) ||
- (sc->status_try)) {
- atausb2_tr_error(xfer);
- } else {
- sc->status_try = 1;
- atausb2_transfer_start(sc, ATAUSB_T_BBB_DATA_RD_CS);
- }
- return;
-
- }
-}
-
-static void
-atausb2_cancel_request(struct atausb2_softc *sc)
-{
- struct ata_request *request;
-
- mtx_assert(&sc->locked_mtx, MA_OWNED);
-
- request = sc->ata_request;
- sc->ata_request = NULL;
- sc->last_xfer_no = ATAUSB_T_BBB_RESET1;
-
- if (request) {
- request->error = ATA_E_ATAPI_SENSE_MASK;
-
- mtx_unlock(&sc->locked_mtx);
-
- ata_interrupt(device_get_softc(request->parent));
-
- mtx_lock(&sc->locked_mtx);
- }
-}
-
-static void
-atausb2_tr_error(struct usb2_xfer *xfer)
-{
- struct atausb2_softc *sc = xfer->priv_sc;
-
- if (xfer->error != USB_ERR_CANCELLED) {
-
- if (atausbdebug) {
- device_printf(sc->dev, "transfer failed, %s, in state %d "
- "-> BULK reset\n", usb2_errstr(xfer->error),
- sc->last_xfer_no);
- }
- }
- atausb2_cancel_request(sc);
-}
-
-/*
- * ATA backend part
- */
-struct atapi_inquiry {
- uint8_t device_type;
- uint8_t device_modifier;
- uint8_t version;
- uint8_t response_format;
- uint8_t length;
- uint8_t reserved[2];
- uint8_t flags;
- uint8_t vendor[8];
- uint8_t product[16];
- uint8_t revision[4];
- /* uint8_t crap[60]; */
-} __packed;
-
-static int
-ata_usbchannel_begin_transaction(struct ata_request *request)
-{
- struct atausb2_softc *sc =
- device_get_softc(device_get_parent(request->parent));
- int error;
-
- if (atausbdebug > 1) {
- device_printf(request->dev, "begin_transaction %s\n",
- ata_cmd2str(request));
- }
- mtx_lock(&sc->locked_mtx);
-
- /* sanity, just in case */
- if (sc->ata_request) {
- device_printf(request->dev, "begin is busy, "
- "state = %d\n", sc->last_xfer_no);
- request->result = EBUSY;
- error = ATA_OP_FINISHED;
- goto done;
- }
- /*
- * XXX SOS convert the request into the format used, only BBB for
- * now
- */
-
- /* 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;
- error = ATA_OP_FINISHED;
- goto done;
- }
- 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); */
- }
- if (sc->xfer[sc->last_xfer_no]) {
-
- sc->ata_request = request;
- sc->ata_bytecount = request->bytecount;
- sc->ata_data = request->data;
- sc->ata_donecount = 0;
-
- usb2_transfer_start(sc->xfer[sc->last_xfer_no]);
- error = ATA_OP_CONTINUES;
- } else {
- request->result = EIO;
- error = ATA_OP_FINISHED;
- }
-
-done:
- mtx_unlock(&sc->locked_mtx);
- return (error);
-}
-
-static 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;
- uint16_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 = (uint16_t *)(atadev->param.model + sizeof(atadev->param.model));
- while (--ptr >= (uint16_t *)atadev->param.model) {
- *ptr = ntohs(*ptr);
- }
- strncpy(atadev->param.revision, inquiry->revision, 4);
- ptr = (uint16_t *)(atadev->param.revision + sizeof(atadev->param.revision));
- while (--ptr >= (uint16_t *)atadev->param.revision) {
- *ptr = ntohs(*ptr);
- }
- request->result = 0;
- }
- return (ATA_OP_FINISHED);
-}
-
-static int
-ata_usbchannel_probe(device_t dev)
-{
- struct ata_channel *ch = device_get_softc(dev);
- device_t *children;
- int count, i;
- char buffer[32];
-
- /* take care of green memory */
- bzero(ch, sizeof(struct ata_channel));
-
- /* find channel number on this controller */
- if (!device_get_children(device_get_parent(dev), &children, &count)) {
- for (i = 0; i < count; i++) {
- if (children[i] == dev)
- ch->unit = i;
- }
- free(children, M_TEMP);
- }
- snprintf(buffer, sizeof(buffer), "USB lun %d", ch->unit);
- device_set_desc_copy(dev, buffer);
-
- return (0);
-}
-
-static int
-ata_usbchannel_attach(device_t dev)
-{
- struct ata_channel *ch = device_get_softc(dev);
-
- /* initialize the softc basics */
- ch->dev = 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;
-
- /* 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 atausb2_softc *sc = device_get_softc(GRANDPARENT(dev));
- struct ata_device *atadev = device_get_softc(dev);
-
- if (sc->usb2_speed == USB_SPEED_HIGH)
- atadev->mode = ATA_USB2;
- else
- atadev->mode = ATA_USB1;
-}
-
-static int
-ata_usbchannel_locking(device_t dev, int flags)
-{
- struct atausb2_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/dev/usb2/storage/umass2.c b/sys/dev/usb2/storage/umass2.c
deleted file mode 100644
index ff83290..0000000
--- a/sys/dev/usb2/storage/umass2.c
+++ /dev/null
@@ -1,3620 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * 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->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_t_*_callback.
- * The state machine is started through either umass_command_start() 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.
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_transfer.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>
-
-#if 1
-/* this enables loading of virtual buffers into DMA */
-#define UMASS_USB_FLAGS .ext_buffer=1,
-#else
-#define UMASS_USB_FLAGS
-#endif
-
-#if USB_DEBUG
-#define DIF(m, x) \
- do { \
- if (umass_debug & (m)) { x ; } \
- } while (0)
-
-#define DPRINTF(sc, m, fmt, ...) \
- do { \
- if (umass_debug & (m)) { \
- printf("%s:%s: " fmt, \
- (sc) ? (const char *)(sc)->sc_name : \
- (const char *)"umassX", \
- __FUNCTION__ ,## __VA_ARGS__); \
- } \
- } while (0)
-
-#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 */
-static int umass_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, umass, CTLFLAG_RW, 0, "USB umass");
-SYSCTL_INT(_hw_usb2_umass, OID_AUTO, debug, CTLFLAG_RW,
- &umass_debug, 0, "umass debug level");
-#else
-#define DIF(...) do { } while (0)
-#define DPRINTF(...) do { } while (0)
-#endif
-
-#define UMASS_GONE ((struct umass_softc *)1)
-
-#define UMASS_BULK_SIZE (1 << 17)
-#define UMASS_CBI_DIAGNOSTIC_CMDLEN 12 /* bytes */
-#define UMASS_MAX_CMDLEN MAX(12, CAM_MAX_CDBLEN) /* bytes */
-
-/* USB transfer definitions */
-
-#define UMASS_T_BBB_RESET1 0 /* Bulk-Only */
-#define UMASS_T_BBB_RESET2 1
-#define UMASS_T_BBB_RESET3 2
-#define UMASS_T_BBB_COMMAND 3
-#define UMASS_T_BBB_DATA_READ 4
-#define UMASS_T_BBB_DATA_RD_CS 5
-#define UMASS_T_BBB_DATA_WRITE 6
-#define UMASS_T_BBB_DATA_WR_CS 7
-#define UMASS_T_BBB_STATUS 8
-#define UMASS_T_BBB_MAX 9
-
-#define UMASS_T_CBI_RESET1 0 /* CBI */
-#define UMASS_T_CBI_RESET2 1
-#define UMASS_T_CBI_RESET3 2
-#define UMASS_T_CBI_COMMAND 3
-#define UMASS_T_CBI_DATA_READ 4
-#define UMASS_T_CBI_DATA_RD_CS 5
-#define UMASS_T_CBI_DATA_WRITE 6
-#define UMASS_T_CBI_DATA_WR_CS 7
-#define UMASS_T_CBI_STATUS 8
-#define UMASS_T_CBI_RESET4 9
-#define UMASS_T_CBI_MAX 10
-
-#define UMASS_T_MAX MAX(UMASS_T_CBI_MAX, UMASS_T_BBB_MAX)
-
-/* Generic definitions */
-
-/* Direction for transfer */
-#define DIR_NONE 0
-#define DIR_IN 1
-#define DIR_OUT 2
-
-/* device name */
-#define DEVNAME "umass"
-#define DEVNAME_SIM "umass-sim"
-
-/* 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 /* ms */
-
-/* CAM specific definitions */
-
-#define UMASS_SCSIID_MAX 1 /* maximum number of drives expected */
-#define UMASS_SCSIID_HOST UMASS_SCSIID_MAX
-
-/* 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 union {
- struct {
- uint8_t type;
-#define IDB_TYPE_CCI 0x00
- uint8_t 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
- } __packed common;
-
- struct {
- uint8_t asc;
- uint8_t ascq;
- } __packed ufi;
-} __packed umass_cbi_sbl_t;
-
-struct umass_softc; /* see below */
-
-typedef void (umass_callback_t)(struct umass_softc *sc, union ccb *ccb,
- uint32_t residue, uint8_t 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 uint8_t (umass_transform_t)(struct umass_softc *sc, uint8_t *cmd_ptr,
- uint8_t cmd_len);
-
-struct umass_devdescr {
- uint32_t vid;
-#define VID_WILDCARD 0xffffffff
-#define VID_EOT 0xfffffffe
- uint32_t pid;
-#define PID_WILDCARD 0xffffffff
-#define PID_EOT 0xfffffffe
- uint32_t rid;
-#define RID_WILDCARD 0xffffffff
-#define RID_EOT 0xfffffffe
-
- /* wire and command protocol */
- uint16_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 */
- uint16_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 const struct umass_devdescr umass_devdescr[] = {
- {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_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_ALCOR, USB_PRODUCT_ALCOR_TRANSCEND, 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_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_DZ_MV100A, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_GETMAXLUN
- },
- {USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_USB, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- NO_INQUIRY
- },
- {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_USBCABLE, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_TEST_UNIT_READY | NO_START_STOP | ALT_IFACE_1
- },
- {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_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_MYSON, USB_PRODUCT_MYSON_STARREADER, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_SYNCHRONIZE_CACHE
- },
- {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_SDS_HOTFIND_D, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN | NO_SYNCHRONIZE_CACHE
- },
- {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_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_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_SANDISK, USB_PRODUCT_SANDISK_SDDR31, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- READ_CAPACITY_OFFBY1
- },
- {USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- {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_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_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_HANDYCAM, 0x0500,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- RBC_PAD_TO_12
- },
- {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, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- {USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC, 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_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
- },
- {USB_VENDOR_MEIZU, USB_PRODUCT_MEIZU_M6_SL, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY | NO_SYNCHRONIZE_CACHE
- },
- {VID_EOT, PID_EOT, RID_EOT, 0, 0}
-};
-
-struct umass_softc {
-
- struct scsi_sense cam_scsi_sense;
- struct scsi_test_unit_ready cam_scsi_test_unit_ready;
- struct mtx sc_mtx;
- struct {
- uint8_t *data_ptr;
- union ccb *ccb;
- umass_callback_t *callback;
-
- uint32_t data_len; /* bytes */
- uint32_t data_rem; /* bytes */
- uint32_t data_timeout; /* ms */
- uint32_t actlen; /* bytes */
-
- uint8_t cmd_data[UMASS_MAX_CMDLEN];
- uint8_t cmd_len; /* bytes */
- uint8_t dir;
- uint8_t lun;
- } sc_transfer;
-
- /* 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_sbl_t sbl; /* status block */
-
- device_t sc_dev;
- struct usb2_device *sc_udev;
- struct cam_sim *sc_sim; /* SCSI Interface Module */
- struct usb2_xfer *sc_xfer[UMASS_T_MAX];
-
- /*
- * The command transform function is used to convert the SCSI
- * commands into their derivatives, like UFI, ATAPI, and friends.
- */
- umass_transform_t *sc_transform;
-
- uint32_t sc_unit;
-
- uint16_t sc_proto; /* wire and cmd protocol */
- uint16_t sc_quirks; /* they got it almost right */
-
- uint8_t sc_name[16];
- uint8_t sc_iface_no; /* interface number */
- uint8_t sc_maxlun; /* maximum LUN number, inclusive */
- uint8_t sc_last_xfer_index;
- uint8_t sc_status_try;
-};
-
-struct umass_probe_proto {
- uint16_t quirks;
- uint16_t proto;
-
- int32_t error;
-};
-
-/* prototypes */
-
-static device_probe_t umass_probe;
-static device_attach_t umass_attach;
-static device_detach_t umass_detach;
-
-static usb2_callback_t umass_tr_error;
-static usb2_callback_t umass_t_bbb_reset1_callback;
-static usb2_callback_t umass_t_bbb_reset2_callback;
-static usb2_callback_t umass_t_bbb_reset3_callback;
-static usb2_callback_t umass_t_bbb_command_callback;
-static usb2_callback_t umass_t_bbb_data_read_callback;
-static usb2_callback_t umass_t_bbb_data_rd_cs_callback;
-static usb2_callback_t umass_t_bbb_data_write_callback;
-static usb2_callback_t umass_t_bbb_data_wr_cs_callback;
-static usb2_callback_t umass_t_bbb_status_callback;
-static usb2_callback_t umass_t_cbi_reset1_callback;
-static usb2_callback_t umass_t_cbi_reset2_callback;
-static usb2_callback_t umass_t_cbi_reset3_callback;
-static usb2_callback_t umass_t_cbi_reset4_callback;
-static usb2_callback_t umass_t_cbi_command_callback;
-static usb2_callback_t umass_t_cbi_data_read_callback;
-static usb2_callback_t umass_t_cbi_data_rd_cs_callback;
-static usb2_callback_t umass_t_cbi_data_write_callback;
-static usb2_callback_t umass_t_cbi_data_wr_cs_callback;
-static usb2_callback_t umass_t_cbi_status_callback;
-
-static void umass_cancel_ccb(struct umass_softc *);
-static void umass_init_shuttle(struct umass_softc *);
-static void umass_reset(struct umass_softc *);
-static void umass_t_bbb_data_clear_stall_callback(struct usb2_xfer *,
- uint8_t, uint8_t);
-static void umass_command_start(struct umass_softc *, uint8_t, void *,
- uint32_t, uint32_t, umass_callback_t *, union ccb *);
-static uint8_t umass_bbb_get_max_lun(struct umass_softc *);
-static void umass_cbi_start_status(struct umass_softc *);
-static void umass_t_cbi_data_clear_stall_callback(struct usb2_xfer *,
- uint8_t, uint8_t);
-static int umass_cam_attach_sim(struct umass_softc *);
-static void umass_cam_rescan_callback(struct cam_periph *, union ccb *);
-static void umass_cam_rescan(struct umass_softc *);
-static void umass_cam_attach(struct umass_softc *);
-static void umass_cam_detach_sim(struct umass_softc *);
-static void umass_cam_action(struct cam_sim *, union ccb *);
-static void umass_cam_poll(struct cam_sim *);
-static void umass_cam_cb(struct umass_softc *, union ccb *, uint32_t,
- uint8_t);
-static void umass_cam_sense_cb(struct umass_softc *, union ccb *, uint32_t,
- uint8_t);
-static void umass_cam_quirk_cb(struct umass_softc *, union ccb *, uint32_t,
- uint8_t);
-static uint8_t umass_scsi_transform(struct umass_softc *, uint8_t *, uint8_t);
-static uint8_t umass_rbc_transform(struct umass_softc *, uint8_t *, uint8_t);
-static uint8_t umass_ufi_transform(struct umass_softc *, uint8_t *, uint8_t);
-static uint8_t umass_atapi_transform(struct umass_softc *, uint8_t *,
- uint8_t);
-static uint8_t umass_no_transform(struct umass_softc *, uint8_t *, uint8_t);
-static uint8_t umass_std_transform(struct umass_softc *, union ccb *, uint8_t
- *, uint8_t);
-
-#if USB_DEBUG
-static void umass_bbb_dump_cbw(struct umass_softc *, umass_bbb_cbw_t *);
-static void umass_bbb_dump_csw(struct umass_softc *, umass_bbb_csw_t *);
-static void umass_cbi_dump_cmd(struct umass_softc *, void *, uint8_t);
-static void umass_dump_buffer(struct umass_softc *, uint8_t *, uint32_t,
- uint32_t);
-#endif
-
-struct usb2_config umass_bbb_config[UMASS_T_BBB_MAX] = {
-
- [UMASS_T_BBB_RESET1] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umass_t_bbb_reset1_callback,
- .mh.timeout = 5000, /* 5 seconds */
- .mh.interval = 500, /* 500 milliseconds */
- },
-
- [UMASS_T_BBB_RESET2] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umass_t_bbb_reset2_callback,
- .mh.timeout = 5000, /* 5 seconds */
- .mh.interval = 50, /* 50 milliseconds */
- },
-
- [UMASS_T_BBB_RESET3] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umass_t_bbb_reset3_callback,
- .mh.timeout = 5000, /* 5 seconds */
- .mh.interval = 50, /* 50 milliseconds */
- },
-
- [UMASS_T_BBB_COMMAND] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = sizeof(umass_bbb_cbw_t),
- .mh.flags = {},
- .mh.callback = &umass_t_bbb_command_callback,
- .mh.timeout = 5000, /* 5 seconds */
- },
-
- [UMASS_T_BBB_DATA_READ] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UMASS_BULK_SIZE,
- .mh.flags = {.proxy_buffer = 1,.short_xfer_ok = 1, UMASS_USB_FLAGS},
- .mh.callback = &umass_t_bbb_data_read_callback,
- .mh.timeout = 0, /* overwritten later */
- },
-
- [UMASS_T_BBB_DATA_RD_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umass_t_bbb_data_rd_cs_callback,
- .mh.timeout = 5000, /* 5 seconds */
- },
-
- [UMASS_T_BBB_DATA_WRITE] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UMASS_BULK_SIZE,
- .mh.flags = {.proxy_buffer = 1,.short_xfer_ok = 1, UMASS_USB_FLAGS},
- .mh.callback = &umass_t_bbb_data_write_callback,
- .mh.timeout = 0, /* overwritten later */
- },
-
- [UMASS_T_BBB_DATA_WR_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umass_t_bbb_data_wr_cs_callback,
- .mh.timeout = 5000, /* 5 seconds */
- },
-
- [UMASS_T_BBB_STATUS] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = sizeof(umass_bbb_csw_t),
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.callback = &umass_t_bbb_status_callback,
- .mh.timeout = 5000, /* ms */
- },
-};
-
-struct usb2_config umass_cbi_config[UMASS_T_CBI_MAX] = {
-
- [UMASS_T_CBI_RESET1] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = (sizeof(struct usb2_device_request) +
- UMASS_CBI_DIAGNOSTIC_CMDLEN),
- .mh.flags = {},
- .mh.callback = &umass_t_cbi_reset1_callback,
- .mh.timeout = 5000, /* 5 seconds */
- .mh.interval = 500, /* 500 milliseconds */
- },
-
- [UMASS_T_CBI_RESET2] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umass_t_cbi_reset2_callback,
- .mh.timeout = 5000, /* 5 seconds */
- .mh.interval = 50, /* 50 milliseconds */
- },
-
- [UMASS_T_CBI_RESET3] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umass_t_cbi_reset3_callback,
- .mh.timeout = 5000, /* 5 seconds */
- .mh.interval = 50, /* 50 milliseconds */
- },
-
- [UMASS_T_CBI_COMMAND] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = (sizeof(struct usb2_device_request) +
- UMASS_MAX_CMDLEN),
- .mh.flags = {},
- .mh.callback = &umass_t_cbi_command_callback,
- .mh.timeout = 5000, /* 5 seconds */
- },
-
- [UMASS_T_CBI_DATA_READ] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = UMASS_BULK_SIZE,
- .mh.flags = {.proxy_buffer = 1,.short_xfer_ok = 1, UMASS_USB_FLAGS},
- .mh.callback = &umass_t_cbi_data_read_callback,
- .mh.timeout = 0, /* overwritten later */
- },
-
- [UMASS_T_CBI_DATA_RD_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umass_t_cbi_data_rd_cs_callback,
- .mh.timeout = 5000, /* 5 seconds */
- },
-
- [UMASS_T_CBI_DATA_WRITE] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = UMASS_BULK_SIZE,
- .mh.flags = {.proxy_buffer = 1,.short_xfer_ok = 1, UMASS_USB_FLAGS},
- .mh.callback = &umass_t_cbi_data_write_callback,
- .mh.timeout = 0, /* overwritten later */
- },
-
- [UMASS_T_CBI_DATA_WR_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umass_t_cbi_data_wr_cs_callback,
- .mh.timeout = 5000, /* 5 seconds */
- },
-
- [UMASS_T_CBI_STATUS] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.flags = {.short_xfer_ok = 1,},
- .mh.bufsize = sizeof(umass_cbi_sbl_t),
- .mh.callback = &umass_t_cbi_status_callback,
- .mh.timeout = 5000, /* ms */
- },
-
- [UMASS_T_CBI_RESET4] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &umass_t_cbi_reset4_callback,
- .mh.timeout = 5000, /* ms */
- },
-};
-
-/* If device cannot return valid inquiry data, fake it */
-static const uint8_t fake_inq_data[SHORT_INQUIRY_LENGTH] = {
- 0, /* removable */ 0x80, SCSI_REV_2, SCSI_REV_2,
- /* additional_length */ 31, 0, 0, 0
-};
-
-#define UFI_COMMAND_LENGTH 12 /* UFI commands are always 12 bytes */
-#define ATAPI_COMMAND_LENGTH 12 /* ATAPI commands are always 12 bytes */
-
-static devclass_t umass_devclass;
-
-static device_method_t umass_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, umass_probe),
- DEVMETHOD(device_attach, umass_attach),
- DEVMETHOD(device_detach, umass_detach),
- {0, 0}
-};
-
-static driver_t umass_driver = {
- .name = "umass",
- .methods = umass_methods,
- .size = sizeof(struct umass_softc),
-};
-
-DRIVER_MODULE(umass, ushub, umass_driver, umass_devclass, NULL, 0);
-MODULE_DEPEND(umass, usb2_storage, 1, 1, 1);
-MODULE_DEPEND(umass, usb2_core, 1, 1, 1);
-MODULE_DEPEND(umass, cam, 1, 1, 1);
-
-/*
- * USB device probe/attach/detach
- */
-
-/*
- * Match the device we are seeing with the
- * devices supported.
- */
-static struct umass_probe_proto
-umass_probe_proto(device_t dev, struct usb2_attach_arg *uaa)
-{
- const struct umass_devdescr *udd = umass_devdescr;
- struct usb2_interface_descriptor *id;
- struct umass_probe_proto ret;
-
- bzero(&ret, sizeof(ret));
-
- /*
- * An entry specifically for Y-E Data devices as they don't fit in
- * the device description table.
- */
- if ((uaa->info.idVendor == USB_VENDOR_YEDATA) &&
- (uaa->info.idProduct == USB_PRODUCT_YEDATA_FLASHBUSTERU)) {
-
- /*
- * Revisions < 1.28 do not handle the interrupt endpoint
- * very well.
- */
- if (uaa->info.bcdDevice < 0x128) {
- ret.proto = UMASS_PROTO_UFI | UMASS_PROTO_CBI;
- } else {
- ret.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 (uaa->info.bcdDevice <= 0x128) {
- ret.quirks |= NO_TEST_UNIT_READY;
- }
- ret.quirks |= RS_NO_CLEAR_UA | FLOPPY_SPEED;
- ret.error = 0;
- goto done;
- }
- /*
- * Check the list of supported devices for a match. While looking,
- * check for wildcarded and fully matched. First match wins.
- */
- for (; udd->vid != VID_EOT; udd++) {
- if ((udd->vid == VID_WILDCARD) &&
- (udd->pid == PID_WILDCARD) &&
- (udd->rid == RID_WILDCARD)) {
- device_printf(dev, "ignoring invalid "
- "wildcard quirk\n");
- continue;
- }
- if (((udd->vid == uaa->info.idVendor) ||
- (udd->vid == VID_WILDCARD)) &&
- ((udd->pid == uaa->info.idProduct) ||
- (udd->pid == PID_WILDCARD))) {
- if (udd->rid == RID_WILDCARD) {
- ret.proto = udd->proto;
- ret.quirks = udd->quirks;
- ret.error = 0;
- goto done;
- } else if (udd->rid == uaa->info.bcdDevice) {
- ret.proto = udd->proto;
- ret.quirks = udd->quirks;
- ret.error = 0;
- goto done;
- } /* else RID does not match */
- }
- }
-
- /* Check for a standards compliant device */
- id = usb2_get_interface_descriptor(uaa->iface);
- if ((id == NULL) ||
- (id->bInterfaceClass != UICLASS_MASS)) {
- ret.error = ENXIO;
- goto done;
- }
- switch (id->bInterfaceSubClass) {
- case UISUBCLASS_SCSI:
- ret.proto |= UMASS_PROTO_SCSI;
- break;
- case UISUBCLASS_UFI:
- ret.proto |= UMASS_PROTO_UFI;
- break;
- case UISUBCLASS_RBC:
- ret.proto |= UMASS_PROTO_RBC;
- break;
- case UISUBCLASS_SFF8020I:
- case UISUBCLASS_SFF8070I:
- ret.proto |= UMASS_PROTO_ATAPI;
- break;
- default:
- device_printf(dev, "unsupported command "
- "protocol %d\n", id->bInterfaceSubClass);
- ret.error = ENXIO;
- goto done;
- }
-
- switch (id->bInterfaceProtocol) {
- case UIPROTO_MASS_CBI:
- ret.proto |= UMASS_PROTO_CBI;
- break;
- case UIPROTO_MASS_CBI_I:
- ret.proto |= UMASS_PROTO_CBI_I;
- break;
- case UIPROTO_MASS_BBB_OLD:
- case UIPROTO_MASS_BBB:
- ret.proto |= UMASS_PROTO_BBB;
- break;
- default:
- device_printf(dev, "unsupported wire "
- "protocol %d\n", id->bInterfaceProtocol);
- ret.error = ENXIO;
- goto done;
- }
-
- ret.error = 0;
-done:
- return (ret);
-}
-
-static int
-umass_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct umass_probe_proto temp;
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if (uaa->use_generic == 0) {
- /* give other drivers a try first */
- return (ENXIO);
- }
- temp = umass_probe_proto(dev, uaa);
-
- return (temp.error);
-}
-
-static int
-umass_attach(device_t dev)
-{
- struct umass_softc *sc = device_get_softc(dev);
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct umass_probe_proto temp = umass_probe_proto(dev, uaa);
- struct usb2_interface_descriptor *id;
- int32_t err;
-
- /*
- * NOTE: the softc struct is bzero-ed in device_set_driver.
- * We can safely call umass_detach without specifically
- * initializing the struct.
- */
-
- sc->sc_dev = dev;
- sc->sc_udev = uaa->device;
- sc->sc_proto = temp.proto;
- sc->sc_quirks = temp.quirks;
- sc->sc_unit = device_get_unit(dev);
-
- snprintf(sc->sc_name, sizeof(sc->sc_name),
- "%s", device_get_nameunit(dev));
-
- device_set_usb2_desc(dev);
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(dev),
- NULL, MTX_DEF | MTX_RECURSE);
-
- /* get interface index */
-
- id = usb2_get_interface_descriptor(uaa->iface);
- if (id == NULL) {
- device_printf(dev, "failed to get "
- "interface number\n");
- goto detach;
- }
- sc->sc_iface_no = id->bInterfaceNumber;
-
-#if USB_DEBUG
- device_printf(dev, " ");
-
- switch (sc->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->sc_proto & UMASS_PROTO_COMMAND);
- break;
- }
-
- printf(" over ");
-
- switch (sc->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");
- break;
- default:
- printf("(unknown 0x%02x)",
- sc->sc_proto & UMASS_PROTO_WIRE);
- }
-
- printf("; quirks = 0x%04x\n", sc->sc_quirks);
-#endif
-
- if (sc->sc_quirks & ALT_IFACE_1) {
- err = usb2_set_alt_interface_index
- (uaa->device, uaa->info.bIfaceIndex, 1);
-
- if (err) {
- DPRINTF(sc, UDMASS_USB, "could not switch to "
- "Alt Interface 1\n");
- goto detach;
- }
- }
- /* allocate all required USB transfers */
-
- if (sc->sc_proto & UMASS_PROTO_BBB) {
-
- err = usb2_transfer_setup(uaa->device,
- &uaa->info.bIfaceIndex, sc->sc_xfer, umass_bbb_config,
- UMASS_T_BBB_MAX, sc, &sc->sc_mtx);
-
- /* skip reset first time */
- sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND;
-
- } else if (sc->sc_proto & (UMASS_PROTO_CBI | UMASS_PROTO_CBI_I)) {
-
- err = usb2_transfer_setup(uaa->device,
- &uaa->info.bIfaceIndex, sc->sc_xfer, umass_cbi_config,
- (sc->sc_proto & UMASS_PROTO_CBI_I) ?
- UMASS_T_CBI_MAX : (UMASS_T_CBI_MAX - 2), sc,
- &sc->sc_mtx);
-
- /* skip reset first time */
- sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
-
- } else {
- err = USB_ERR_INVAL;
- }
-
- if (err) {
- device_printf(dev, "could not setup required "
- "transfers, %s\n", usb2_errstr(err));
- goto detach;
- }
- sc->sc_transform =
- (sc->sc_proto & UMASS_PROTO_SCSI) ? &umass_scsi_transform :
- (sc->sc_proto & UMASS_PROTO_UFI) ? &umass_ufi_transform :
- (sc->sc_proto & UMASS_PROTO_ATAPI) ? &umass_atapi_transform :
- (sc->sc_proto & UMASS_PROTO_RBC) ? &umass_rbc_transform :
- &umass_no_transform;
-
- /* from here onwards the device can be used. */
-
- if (sc->sc_quirks & SHUTTLE_INIT) {
- umass_init_shuttle(sc);
- }
- /* get the maximum LUN supported by the device */
-
- if (((sc->sc_proto & UMASS_PROTO_WIRE) == UMASS_PROTO_BBB) &&
- !(sc->sc_quirks & NO_GETMAXLUN))
- sc->sc_maxlun = umass_bbb_get_max_lun(sc);
- else
- sc->sc_maxlun = 0;
-
- /* Prepare the SCSI command block */
- sc->cam_scsi_sense.opcode = REQUEST_SENSE;
- sc->cam_scsi_test_unit_ready.opcode = TEST_UNIT_READY;
-
- /*
- * some devices need a delay after that the configuration value is
- * set to function properly:
- */
- usb2_pause_mtx(&Giant, hz);
-
- /* register the SIM */
- err = umass_cam_attach_sim(sc);
- if (err) {
- goto detach;
- }
- /* scan the SIM */
- umass_cam_attach(sc);
-
- DPRINTF(sc, UDMASS_GEN, "Attach finished\n");
-
- return (0); /* success */
-
-detach:
- umass_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-umass_detach(device_t dev)
-{
- struct umass_softc *sc = device_get_softc(dev);
-
- DPRINTF(sc, UDMASS_USB, "\n");
-
- /* teardown our statemachine */
-
- usb2_transfer_unsetup(sc->sc_xfer, UMASS_T_MAX);
-
-#if (__FreeBSD_version >= 700037)
- mtx_lock(&sc->sc_mtx);
-#endif
- umass_cam_detach_sim(sc);
-
-#if (__FreeBSD_version >= 700037)
- mtx_unlock(&sc->sc_mtx);
-#endif
-
- return (0); /* success */
-}
-
-static void
-umass_init_shuttle(struct umass_softc *sc)
-{
- struct usb2_device_request req;
- usb2_error_t err;
- uint8_t status[2] = {0, 0};
-
- /*
- * 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);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, sizeof(status));
- err = usb2_do_request(sc->sc_udev, &Giant, &req, &status);
-
- DPRINTF(sc, UDMASS_GEN, "Shuttle init returned 0x%02x%02x\n",
- status[0], status[1]);
-}
-
-/*
- * Generic functions to handle transfers
- */
-
-static void
-umass_transfer_start(struct umass_softc *sc, uint8_t xfer_index)
-{
- DPRINTF(sc, UDMASS_GEN, "transfer index = "
- "%d\n", xfer_index);
-
- if (sc->sc_xfer[xfer_index]) {
- sc->sc_last_xfer_index = xfer_index;
- usb2_transfer_start(sc->sc_xfer[xfer_index]);
- } else {
- umass_cancel_ccb(sc);
- }
-}
-
-static void
-umass_reset(struct umass_softc *sc)
-{
- DPRINTF(sc, UDMASS_GEN, "resetting device\n");
-
- /*
- * stop the last transfer, if not already stopped:
- */
- usb2_transfer_stop(sc->sc_xfer[sc->sc_last_xfer_index]);
- umass_transfer_start(sc, 0);
-}
-
-static void
-umass_cancel_ccb(struct umass_softc *sc)
-{
- union ccb *ccb;
-
- mtx_assert(&sc->sc_mtx, MA_OWNED);
-
- ccb = sc->sc_transfer.ccb;
- sc->sc_transfer.ccb = NULL;
- sc->sc_last_xfer_index = 0;
-
- if (ccb) {
- (sc->sc_transfer.callback)
- (sc, ccb, (sc->sc_transfer.data_len -
- sc->sc_transfer.actlen), STATUS_WIRE_FAILED);
- }
-}
-
-static void
-umass_tr_error(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
-
- if (xfer->error != USB_ERR_CANCELLED) {
-
- DPRINTF(sc, UDMASS_GEN, "transfer error, %s -> "
- "reset\n", usb2_errstr(xfer->error));
- }
- umass_cancel_ccb(sc);
-}
-
-/*
- * BBB protocol specific functions
- */
-
-static void
-umass_t_bbb_reset1_callback(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
- struct usb2_device_request req;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- umass_transfer_start(sc, UMASS_T_BBB_RESET2);
- return;
-
- case USB_ST_SETUP:
- /*
- * 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, using 3 transfers:
- * UMASS_T_BBB_RESET1
- * UMASS_T_BBB_RESET2
- * UMASS_T_BBB_RESET3
- */
-
- DPRINTF(sc, UDMASS_BBB, "BBB reset!\n");
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_BBB_RESET; /* bulk only reset */
- USETW(req.wValue, 0);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 0);
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
-
- xfer->frlengths[0] = sizeof(req);
- xfer->nframes = 1;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- umass_tr_error(xfer);
- return;
-
- }
-}
-
-static void
-umass_t_bbb_reset2_callback(struct usb2_xfer *xfer)
-{
- umass_t_bbb_data_clear_stall_callback(xfer, UMASS_T_BBB_RESET3,
- UMASS_T_BBB_DATA_READ);
-}
-
-static void
-umass_t_bbb_reset3_callback(struct usb2_xfer *xfer)
-{
- umass_t_bbb_data_clear_stall_callback(xfer, UMASS_T_BBB_COMMAND,
- UMASS_T_BBB_DATA_WRITE);
-}
-
-static void
-umass_t_bbb_data_clear_stall_callback(struct usb2_xfer *xfer,
- uint8_t next_xfer,
- uint8_t stall_xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-tr_transferred:
- umass_transfer_start(sc, next_xfer);
- return;
-
- case USB_ST_SETUP:
- if (usb2_clear_stall_callback(xfer, sc->sc_xfer[stall_xfer])) {
- goto tr_transferred;
- }
- return;
-
- default: /* Error */
- umass_tr_error(xfer);
- return;
-
- }
-}
-
-static void
-umass_t_bbb_command_callback(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
- union ccb *ccb = sc->sc_transfer.ccb;
- uint32_t tag;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- umass_transfer_start
- (sc, ((sc->sc_transfer.dir == DIR_IN) ? UMASS_T_BBB_DATA_READ :
- (sc->sc_transfer.dir == DIR_OUT) ? UMASS_T_BBB_DATA_WRITE :
- UMASS_T_BBB_STATUS));
- return;
-
- case USB_ST_SETUP:
-
- sc->sc_status_try = 0;
-
- if (ccb) {
-
- /*
- * the initial value is not important,
- * as long as the values are unique:
- */
- tag = UGETDW(sc->cbw.dCBWTag) + 1;
-
- USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE);
- USETDW(sc->cbw.dCBWTag, tag);
-
- /*
- * dCBWDataTransferLength:
- * 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.
- */
- USETDW(sc->cbw.dCBWDataTransferLength, sc->sc_transfer.data_len);
-
- /*
- * dCBWFlags:
- * 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
- */
- sc->cbw.bCBWFlags = ((sc->sc_transfer.dir == DIR_IN) ?
- CBWFLAGS_IN : CBWFLAGS_OUT);
- sc->cbw.bCBWLUN = sc->sc_transfer.lun;
-
- if (sc->sc_transfer.cmd_len > sizeof(sc->cbw.CBWCDB)) {
- sc->sc_transfer.cmd_len = sizeof(sc->cbw.CBWCDB);
- DPRINTF(sc, UDMASS_BBB, "Truncating long command!\n");
- }
- sc->cbw.bCDBLength = sc->sc_transfer.cmd_len;
-
- bcopy(sc->sc_transfer.cmd_data, sc->cbw.CBWCDB,
- sc->sc_transfer.cmd_len);
-
- bzero(sc->sc_transfer.cmd_data + sc->sc_transfer.cmd_len,
- sizeof(sc->cbw.CBWCDB) - sc->sc_transfer.cmd_len);
-
- DIF(UDMASS_BBB, umass_bbb_dump_cbw(sc, &sc->cbw));
-
- usb2_copy_in(xfer->frbuffers, 0, &sc->cbw, sizeof(sc->cbw));
-
- xfer->frlengths[0] = sizeof(sc->cbw);
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- umass_tr_error(xfer);
- return;
-
- }
-}
-
-static void
-umass_t_bbb_data_read_callback(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
- uint32_t max_bulk = xfer->max_data_length;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- if (!xfer->flags.ext_buffer) {
- usb2_copy_out(xfer->frbuffers, 0,
- sc->sc_transfer.data_ptr, xfer->actlen);
- }
- sc->sc_transfer.data_rem -= xfer->actlen;
- sc->sc_transfer.data_ptr += xfer->actlen;
- sc->sc_transfer.actlen += xfer->actlen;
-
- if (xfer->actlen < xfer->sumlen) {
- /* short transfer */
- sc->sc_transfer.data_rem = 0;
- }
- case USB_ST_SETUP:
- DPRINTF(sc, UDMASS_BBB, "max_bulk=%d, data_rem=%d\n",
- max_bulk, sc->sc_transfer.data_rem);
-
- if (sc->sc_transfer.data_rem == 0) {
- umass_transfer_start(sc, UMASS_T_BBB_STATUS);
- return;
- }
- if (max_bulk > sc->sc_transfer.data_rem) {
- max_bulk = sc->sc_transfer.data_rem;
- }
- xfer->timeout = sc->sc_transfer.data_timeout;
- xfer->frlengths[0] = max_bulk;
-
- if (xfer->flags.ext_buffer) {
- usb2_set_frame_data(xfer, sc->sc_transfer.data_ptr, 0);
- }
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- umass_tr_error(xfer);
- } else {
- umass_transfer_start(sc, UMASS_T_BBB_DATA_RD_CS);
- }
- return;
-
- }
-}
-
-static void
-umass_t_bbb_data_rd_cs_callback(struct usb2_xfer *xfer)
-{
- umass_t_bbb_data_clear_stall_callback(xfer, UMASS_T_BBB_STATUS,
- UMASS_T_BBB_DATA_READ);
-}
-
-static void
-umass_t_bbb_data_write_callback(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
- uint32_t max_bulk = xfer->max_data_length;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- sc->sc_transfer.data_rem -= xfer->actlen;
- sc->sc_transfer.data_ptr += xfer->actlen;
- sc->sc_transfer.actlen += xfer->actlen;
-
- if (xfer->actlen < xfer->sumlen) {
- /* short transfer */
- sc->sc_transfer.data_rem = 0;
- }
- case USB_ST_SETUP:
- DPRINTF(sc, UDMASS_BBB, "max_bulk=%d, data_rem=%d\n",
- max_bulk, sc->sc_transfer.data_rem);
-
- if (sc->sc_transfer.data_rem == 0) {
- umass_transfer_start(sc, UMASS_T_BBB_STATUS);
- return;
- }
- if (max_bulk > sc->sc_transfer.data_rem) {
- max_bulk = sc->sc_transfer.data_rem;
- }
- xfer->timeout = sc->sc_transfer.data_timeout;
- xfer->frlengths[0] = max_bulk;
-
- if (xfer->flags.ext_buffer) {
- usb2_set_frame_data(xfer, sc->sc_transfer.data_ptr, 0);
- } else {
- usb2_copy_in(xfer->frbuffers, 0,
- sc->sc_transfer.data_ptr, max_bulk);
- }
-
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- umass_tr_error(xfer);
- } else {
- umass_transfer_start(sc, UMASS_T_BBB_DATA_WR_CS);
- }
- return;
-
- }
-}
-
-static void
-umass_t_bbb_data_wr_cs_callback(struct usb2_xfer *xfer)
-{
- umass_t_bbb_data_clear_stall_callback(xfer, UMASS_T_BBB_STATUS,
- UMASS_T_BBB_DATA_WRITE);
-}
-
-static void
-umass_t_bbb_status_callback(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
- union ccb *ccb = sc->sc_transfer.ccb;
- uint32_t residue;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- /*
- * Do a full reset if there is something wrong with the CSW:
- */
- sc->sc_status_try = 1;
-
- /* Zero missing parts of the CSW: */
-
- if (xfer->actlen < sizeof(sc->csw)) {
- bzero(&sc->csw, sizeof(sc->csw));
- }
- usb2_copy_out(xfer->frbuffers, 0, &sc->csw, xfer->actlen);
-
- DIF(UDMASS_BBB, umass_bbb_dump_csw(sc, &sc->csw));
-
- residue = UGETDW(sc->csw.dCSWDataResidue);
-
- if (!residue) {
- residue = (sc->sc_transfer.data_len -
- sc->sc_transfer.actlen);
- }
- if (residue > sc->sc_transfer.data_len) {
- DPRINTF(sc, UDMASS_BBB, "truncating residue from %d "
- "to %d bytes\n", residue, sc->sc_transfer.data_len);
- residue = sc->sc_transfer.data_len;
- }
- /* translate weird command-status signatures: */
- if (sc->sc_quirks & WRONG_CSWSIG) {
-
- uint32_t temp = UGETDW(sc->csw.dCSWSignature);
-
- if ((temp == CSWSIGNATURE_OLYMPUS_C1) ||
- (temp == CSWSIGNATURE_IMAGINATION_DBX1)) {
- USETDW(sc->csw.dCSWSignature, CSWSIGNATURE);
- }
- }
- /* check CSW and handle eventual error */
- if (UGETDW(sc->csw.dCSWSignature) != CSWSIGNATURE) {
- DPRINTF(sc, UDMASS_BBB, "bad CSW signature 0x%08x != 0x%08x\n",
- UGETDW(sc->csw.dCSWSignature), CSWSIGNATURE);
- /*
- * Invalid CSW: Wrong signature or wrong tag might
- * indicate that we lost synchronization. Reset the
- * device.
- */
- goto tr_error;
- } else if (UGETDW(sc->csw.dCSWTag) != UGETDW(sc->cbw.dCBWTag)) {
- DPRINTF(sc, UDMASS_BBB, "Invalid CSW: tag 0x%08x should be "
- "0x%08x\n", UGETDW(sc->csw.dCSWTag),
- UGETDW(sc->cbw.dCBWTag));
- goto tr_error;
- } else if (sc->csw.bCSWStatus > CSWSTATUS_PHASE) {
- DPRINTF(sc, UDMASS_BBB, "Invalid CSW: status %d > %d\n",
- sc->csw.bCSWStatus, CSWSTATUS_PHASE);
- goto tr_error;
- } else if (sc->csw.bCSWStatus == CSWSTATUS_PHASE) {
- DPRINTF(sc, UDMASS_BBB, "Phase error, residue = "
- "%d\n", residue);
- goto tr_error;
- } else if (sc->sc_transfer.actlen > sc->sc_transfer.data_len) {
- DPRINTF(sc, UDMASS_BBB, "Buffer overrun %d > %d\n",
- sc->sc_transfer.actlen, sc->sc_transfer.data_len);
- goto tr_error;
- } else if (sc->csw.bCSWStatus == CSWSTATUS_FAILED) {
- DPRINTF(sc, UDMASS_BBB, "Command failed, residue = "
- "%d\n", residue);
-
- sc->sc_transfer.ccb = NULL;
-
- sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND;
-
- (sc->sc_transfer.callback)
- (sc, ccb, residue, STATUS_CMD_FAILED);
- } else {
- sc->sc_transfer.ccb = NULL;
-
- sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND;
-
- (sc->sc_transfer.callback)
- (sc, ccb, residue, STATUS_CMD_OK);
- }
- return;
-
- case USB_ST_SETUP:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default:
-tr_error:
- DPRINTF(sc, UDMASS_BBB, "Failed to read CSW: %s, try %d\n",
- usb2_errstr(xfer->error), sc->sc_status_try);
-
- if ((xfer->error == USB_ERR_CANCELLED) ||
- (sc->sc_status_try)) {
- umass_tr_error(xfer);
- } else {
- sc->sc_status_try = 1;
- umass_transfer_start(sc, UMASS_T_BBB_DATA_RD_CS);
- }
- return;
-
- }
-}
-
-static void
-umass_command_start(struct umass_softc *sc, uint8_t dir,
- void *data_ptr, uint32_t data_len,
- uint32_t data_timeout, umass_callback_t *callback,
- union ccb *ccb)
-{
- sc->sc_transfer.lun = ccb->ccb_h.target_lun;
-
- /*
- * NOTE: assumes that "sc->sc_transfer.cmd_data" and
- * "sc->sc_transfer.cmd_len" has been properly
- * initialized.
- */
-
- sc->sc_transfer.dir = data_len ? dir : DIR_NONE;
- sc->sc_transfer.data_ptr = data_ptr;
- sc->sc_transfer.data_len = data_len;
- sc->sc_transfer.data_rem = data_len;
- sc->sc_transfer.data_timeout = (data_timeout + UMASS_TIMEOUT);
-
- sc->sc_transfer.actlen = 0;
- sc->sc_transfer.callback = callback;
- sc->sc_transfer.ccb = ccb;
-
- if (sc->sc_xfer[sc->sc_last_xfer_index]) {
- usb2_transfer_start(sc->sc_xfer[sc->sc_last_xfer_index]);
- } else {
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- }
-}
-
-static uint8_t
-umass_bbb_get_max_lun(struct umass_softc *sc)
-{
- struct usb2_device_request req;
- usb2_error_t err;
- uint8_t buf = 0;
-
- /* 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);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, 1);
-
- err = usb2_do_request(sc->sc_udev, &Giant, &req, &buf);
- if (err) {
- buf = 0;
-
- /* Device doesn't support Get Max Lun request. */
- printf("%s: Get Max Lun not supported (%s)\n",
- sc->sc_name, usb2_errstr(err));
- }
- return (buf);
-}
-
-/*
- * Command/Bulk/Interrupt (CBI) specific functions
- */
-
-static void
-umass_cbi_start_status(struct umass_softc *sc)
-{
- if (sc->sc_xfer[UMASS_T_CBI_STATUS]) {
- umass_transfer_start(sc, UMASS_T_CBI_STATUS);
- } else {
- union ccb *ccb = sc->sc_transfer.ccb;
-
- sc->sc_transfer.ccb = NULL;
-
- sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
-
- (sc->sc_transfer.callback)
- (sc, ccb, (sc->sc_transfer.data_len -
- sc->sc_transfer.actlen), STATUS_CMD_UNKNOWN);
- }
-}
-
-static void
-umass_t_cbi_reset1_callback(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
- struct usb2_device_request req;
- uint8_t buf[UMASS_CBI_DIAGNOSTIC_CMDLEN];
-
- uint8_t i;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- umass_transfer_start(sc, UMASS_T_CBI_RESET2);
- return;
-
- case USB_ST_SETUP:
- /*
- * 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, using 3 transfers:
- * UMASS_T_CBI_RESET1
- * UMASS_T_CBI_RESET2
- * UMASS_T_CBI_RESET3
- * UMASS_T_CBI_RESET4 (only if there is an interrupt endpoint)
- */
-
- DPRINTF(sc, UDMASS_CBI, "CBI reset!\n");
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_CBI_ADSC;
- USETW(req.wValue, 0);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- USETW(req.wLength, UMASS_CBI_DIAGNOSTIC_CMDLEN);
-
- /*
- * 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
- * specification)
- */
- buf[0] = 0x1d; /* Command Block Reset */
- buf[1] = 0x04;
-
- for (i = 2; i < UMASS_CBI_DIAGNOSTIC_CMDLEN; i++) {
- buf[i] = 0xff;
- }
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
- usb2_copy_in(xfer->frbuffers + 1, 0, buf, sizeof(buf));
-
- xfer->frlengths[0] = sizeof(req);
- xfer->frlengths[1] = sizeof(buf);
- xfer->nframes = 2;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- umass_tr_error(xfer);
- return;
-
- }
-}
-
-static void
-umass_t_cbi_reset2_callback(struct usb2_xfer *xfer)
-{
- umass_t_cbi_data_clear_stall_callback(xfer, UMASS_T_CBI_RESET3,
- UMASS_T_CBI_DATA_READ);
-}
-
-static void
-umass_t_cbi_reset3_callback(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
-
- umass_t_cbi_data_clear_stall_callback
- (xfer, (sc->sc_xfer[UMASS_T_CBI_RESET4] &&
- sc->sc_xfer[UMASS_T_CBI_STATUS]) ?
- UMASS_T_CBI_RESET4 : UMASS_T_CBI_COMMAND,
- UMASS_T_CBI_DATA_WRITE);
-}
-
-static void
-umass_t_cbi_reset4_callback(struct usb2_xfer *xfer)
-{
- umass_t_cbi_data_clear_stall_callback(xfer, UMASS_T_CBI_COMMAND,
- UMASS_T_CBI_STATUS);
-}
-
-static void
-umass_t_cbi_data_clear_stall_callback(struct usb2_xfer *xfer,
- uint8_t next_xfer,
- uint8_t stall_xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-tr_transferred:
- if (next_xfer == UMASS_T_CBI_STATUS) {
- umass_cbi_start_status(sc);
- } else {
- umass_transfer_start(sc, next_xfer);
- }
- return;
-
- case USB_ST_SETUP:
- if (usb2_clear_stall_callback(xfer, sc->sc_xfer[stall_xfer])) {
- goto tr_transferred; /* should not happen */
- }
- return;
-
- default: /* Error */
- umass_tr_error(xfer);
- return;
-
- }
-}
-
-static void
-umass_t_cbi_command_callback(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
- union ccb *ccb = sc->sc_transfer.ccb;
- struct usb2_device_request req;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (sc->sc_transfer.dir == DIR_NONE) {
- umass_cbi_start_status(sc);
- } else {
- umass_transfer_start
- (sc, (sc->sc_transfer.dir == DIR_IN) ?
- UMASS_T_CBI_DATA_READ : UMASS_T_CBI_DATA_WRITE);
- }
- return;
-
- case USB_ST_SETUP:
-
- if (ccb) {
-
- /*
- * do a CBI transfer with cmd_len bytes from
- * cmd_data, possibly a data phase of data_len
- * bytes from/to the device and finally a status
- * read phase.
- */
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_CBI_ADSC;
- USETW(req.wValue, 0);
- req.wIndex[0] = sc->sc_iface_no;
- req.wIndex[1] = 0;
- req.wLength[0] = sc->sc_transfer.cmd_len;
- req.wLength[1] = 0;
-
- usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
- usb2_copy_in(xfer->frbuffers + 1, 0, sc->sc_transfer.cmd_data,
- sc->sc_transfer.cmd_len);
-
- xfer->frlengths[0] = sizeof(req);
- xfer->frlengths[1] = sc->sc_transfer.cmd_len;
- xfer->nframes = xfer->frlengths[1] ? 2 : 1;
-
- DIF(UDMASS_CBI,
- umass_cbi_dump_cmd(sc,
- sc->sc_transfer.cmd_data,
- sc->sc_transfer.cmd_len));
-
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- umass_tr_error(xfer);
- return;
-
- }
-}
-
-static void
-umass_t_cbi_data_read_callback(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
- uint32_t max_bulk = xfer->max_data_length;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- if (!xfer->flags.ext_buffer) {
- usb2_copy_out(xfer->frbuffers, 0,
- sc->sc_transfer.data_ptr, xfer->actlen);
- }
- sc->sc_transfer.data_rem -= xfer->actlen;
- sc->sc_transfer.data_ptr += xfer->actlen;
- sc->sc_transfer.actlen += xfer->actlen;
-
- if (xfer->actlen < xfer->sumlen) {
- /* short transfer */
- sc->sc_transfer.data_rem = 0;
- }
- case USB_ST_SETUP:
- DPRINTF(sc, UDMASS_CBI, "max_bulk=%d, data_rem=%d\n",
- max_bulk, sc->sc_transfer.data_rem);
-
- if (sc->sc_transfer.data_rem == 0) {
- umass_cbi_start_status(sc);
- return;
- }
- if (max_bulk > sc->sc_transfer.data_rem) {
- max_bulk = sc->sc_transfer.data_rem;
- }
- xfer->timeout = sc->sc_transfer.data_timeout;
-
- if (xfer->flags.ext_buffer) {
- usb2_set_frame_data(xfer, sc->sc_transfer.data_ptr, 0);
- }
- xfer->frlengths[0] = max_bulk;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if ((xfer->error == USB_ERR_CANCELLED) ||
- (sc->sc_transfer.callback != &umass_cam_cb)) {
- umass_tr_error(xfer);
- } else {
- umass_transfer_start(sc, UMASS_T_CBI_DATA_RD_CS);
- }
- return;
-
- }
-}
-
-static void
-umass_t_cbi_data_rd_cs_callback(struct usb2_xfer *xfer)
-{
- umass_t_cbi_data_clear_stall_callback(xfer, UMASS_T_CBI_STATUS,
- UMASS_T_CBI_DATA_READ);
-}
-
-static void
-umass_t_cbi_data_write_callback(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
- uint32_t max_bulk = xfer->max_data_length;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- sc->sc_transfer.data_rem -= xfer->actlen;
- sc->sc_transfer.data_ptr += xfer->actlen;
- sc->sc_transfer.actlen += xfer->actlen;
-
- if (xfer->actlen < xfer->sumlen) {
- /* short transfer */
- sc->sc_transfer.data_rem = 0;
- }
- case USB_ST_SETUP:
- DPRINTF(sc, UDMASS_CBI, "max_bulk=%d, data_rem=%d\n",
- max_bulk, sc->sc_transfer.data_rem);
-
- if (sc->sc_transfer.data_rem == 0) {
- umass_cbi_start_status(sc);
- return;
- }
- if (max_bulk > sc->sc_transfer.data_rem) {
- max_bulk = sc->sc_transfer.data_rem;
- }
- xfer->timeout = sc->sc_transfer.data_timeout;
-
- if (xfer->flags.ext_buffer) {
- usb2_set_frame_data(xfer, sc->sc_transfer.data_ptr, 0);
- } else {
- usb2_copy_in(xfer->frbuffers, 0,
- sc->sc_transfer.data_ptr, max_bulk);
- }
-
- xfer->frlengths[0] = max_bulk;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- if ((xfer->error == USB_ERR_CANCELLED) ||
- (sc->sc_transfer.callback != &umass_cam_cb)) {
- umass_tr_error(xfer);
- } else {
- umass_transfer_start(sc, UMASS_T_CBI_DATA_WR_CS);
- }
- return;
-
- }
-}
-
-static void
-umass_t_cbi_data_wr_cs_callback(struct usb2_xfer *xfer)
-{
- umass_t_cbi_data_clear_stall_callback(xfer, UMASS_T_CBI_STATUS,
- UMASS_T_CBI_DATA_WRITE);
-}
-
-static void
-umass_t_cbi_status_callback(struct usb2_xfer *xfer)
-{
- struct umass_softc *sc = xfer->priv_sc;
- union ccb *ccb = sc->sc_transfer.ccb;
- uint32_t residue;
- uint8_t status;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- if (xfer->actlen < sizeof(sc->sbl)) {
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, 0, &sc->sbl, sizeof(sc->sbl));
-
- residue = (sc->sc_transfer.data_len -
- sc->sc_transfer.actlen);
-
- /* dissect the information in the buffer */
-
- if (sc->sc_proto & UMASS_PROTO_UFI) {
-
- /*
- * Section 3.4.3.1.3 specifies that the UFI command
- * protocol returns an ASC and ASCQ in the interrupt
- * data block.
- */
-
- DPRINTF(sc, UDMASS_CBI, "UFI CCI, ASC = 0x%02x, "
- "ASCQ = 0x%02x\n", sc->sbl.ufi.asc,
- sc->sbl.ufi.ascq);
-
- status = (((sc->sbl.ufi.asc == 0) &&
- (sc->sbl.ufi.ascq == 0)) ?
- STATUS_CMD_OK : STATUS_CMD_FAILED);
-
- sc->sc_transfer.ccb = NULL;
-
- sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
-
- (sc->sc_transfer.callback)
- (sc, ccb, residue, status);
-
- return;
-
- } else {
-
- /* Command Interrupt Data Block */
-
- DPRINTF(sc, UDMASS_CBI, "type=0x%02x, value=0x%02x\n",
- sc->sbl.common.type, sc->sbl.common.value);
-
- if (sc->sbl.common.type == IDB_TYPE_CCI) {
-
- status = (sc->sbl.common.value & IDB_VALUE_STATUS_MASK);
-
- status = ((status == IDB_VALUE_PASS) ? STATUS_CMD_OK :
- (status == IDB_VALUE_FAIL) ? STATUS_CMD_FAILED :
- (status == IDB_VALUE_PERSISTENT) ? STATUS_CMD_FAILED :
- STATUS_WIRE_FAILED);
-
- sc->sc_transfer.ccb = NULL;
-
- sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
-
- (sc->sc_transfer.callback)
- (sc, ccb, residue, status);
-
- return;
- }
- }
-
- /* fallthrough */
-
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- return;
-
- default: /* Error */
- DPRINTF(sc, UDMASS_CBI, "Failed to read CSW: %s\n",
- usb2_errstr(xfer->error));
- umass_tr_error(xfer);
- return;
-
- }
-}
-
-/*
- * 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->sc_sim = cam_sim_alloc
- (&umass_cam_action, &umass_cam_poll,
- DEVNAME_SIM,
- sc /* priv */ ,
- sc->sc_unit /* unit number */ ,
-#if (__FreeBSD_version >= 700037)
- &sc->sc_mtx /* mutex */ ,
-#endif
- 1 /* maximum device openings */ ,
- 0 /* maximum tagged device openings */ ,
- devq);
-
- if (sc->sc_sim == NULL) {
- cam_simq_free(devq);
- return (ENOMEM);
- }
-
-#if (__FreeBSD_version >= 700037)
- mtx_lock(&sc->sc_mtx);
-#endif
-
-#if (__FreeBSD_version >= 700048)
- if (xpt_bus_register(sc->sc_sim, sc->sc_dev, sc->sc_unit) != CAM_SUCCESS) {
- mtx_unlock(&sc->sc_mtx);
- return (ENOMEM);
- }
-#else
- if (xpt_bus_register(sc->sc_sim, sc->sc_unit) != CAM_SUCCESS) {
-#if (__FreeBSD_version >= 700037)
- mtx_unlock(&sc->sc_mtx);
-#endif
- return (ENOMEM);
- }
-#endif
-
-#if (__FreeBSD_version >= 700037)
- mtx_unlock(&sc->sc_mtx);
-#endif
- return (0);
-}
-
-static void
-umass_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
-{
-#if USB_DEBUG
- struct umass_softc *sc = NULL;
-
- if (ccb->ccb_h.status != CAM_REQ_CMP) {
- DPRINTF(sc, UDMASS_SCSI, "%s:%d Rescan failed, 0x%04x\n",
- periph->periph_name, periph->unit_number,
- ccb->ccb_h.status);
- } else {
- DPRINTF(sc, 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(struct umass_softc *sc)
-{
- struct cam_path *path;
- union ccb *ccb;
-
- DPRINTF(sc, UDMASS_SCSI, "scbus%d: scanning for %d:%d:%d\n",
- cam_sim_path(sc->sc_sim),
- cam_sim_path(sc->sc_sim),
- sc->sc_unit, CAM_LUN_WILDCARD);
-
- ccb = malloc(sizeof(*ccb), M_USBDEV, M_WAITOK | M_ZERO);
-
- if (ccb == NULL) {
- return;
- }
-#if (__FreeBSD_version >= 700037)
- mtx_lock(&sc->sc_mtx);
-#endif
-
- if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->sc_sim),
- CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)
- != CAM_REQ_CMP) {
-#if (__FreeBSD_version >= 700037)
- mtx_unlock(&sc->sc_mtx);
-#endif
- 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);
-
-#if (__FreeBSD_version >= 700037)
- mtx_unlock(&sc->sc_mtx);
-#endif
-
- /* The scan is in progress now. */
-}
-
-static void
-umass_cam_attach(struct umass_softc *sc)
-{
-#ifndef USB_DEBUG
- if (bootverbose)
-#endif
- printf("%s:%d:%d:%d: Attached to scbus%d\n",
- sc->sc_name, cam_sim_path(sc->sc_sim),
- sc->sc_unit, CAM_LUN_WILDCARD,
- cam_sim_path(sc->sc_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.
- */
-
- /* scan the new sim */
- umass_cam_rescan(sc);
- }
-}
-
-/* umass_cam_detach
- * detach from the CAM layer
- */
-
-static void
-umass_cam_detach_sim(struct umass_softc *sc)
-{
- if (sc->sc_sim != NULL) {
- if (xpt_bus_deregister(cam_sim_path(sc->sc_sim))) {
- /* accessing the softc is not possible after this */
- sc->sc_sim->softc = UMASS_GONE;
- cam_sim_free(sc->sc_sim, /* free_devq */ TRUE);
- } else {
- panic("%s: CAM layer is busy!\n",
- sc->sc_name);
- }
- sc->sc_sim = NULL;
- }
-}
-
-/* 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;
-
- if (sc == UMASS_GONE) {
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
- if (sc) {
-#if (__FreeBSD_version < 700037)
- mtx_lock(&sc->sc_mtx);
-#endif
- }
- /*
- * 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) {
- DPRINTF(sc, UDMASS_GEN, "%s:%d:%d:%d:func_code 0x%04x: "
- "Invalid target (target needed)\n",
- DEVNAME_SIM, cam_sim_path(sc->sc_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);
- goto done;
- }
- 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(sc, UDMASS_SCSI, "%s:%d:%d:%d:func_code 0x%04x: "
- "Invalid target (no wildcard)\n",
- DEVNAME_SIM, cam_sim_path(sc->sc_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);
- goto done;
- }
- 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:
- {
- uint8_t *cmd;
- uint8_t dir;
-
- if (ccb->csio.ccb_h.flags & CAM_CDB_POINTER) {
- cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_ptr);
- } else {
- cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_bytes);
- }
-
- DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_SCSI_IO: "
- "cmd: 0x%02x, flags: 0x%02x, "
- "%db cmd/%db data/%db sense\n",
- cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
- ccb->ccb_h.target_lun, cmd[0],
- ccb->ccb_h.flags & CAM_DIR_MASK, ccb->csio.cdb_len,
- ccb->csio.dxfer_len, ccb->csio.sense_len);
-
- if (sc->sc_transfer.ccb) {
- DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_SCSI_IO: "
- "I/O in progress, deferring\n",
- cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
- ccb->ccb_h.target_lun);
- ccb->ccb_h.status = CAM_SCSI_BUSY;
- xpt_done(ccb);
- goto done;
- }
- switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
- case CAM_DIR_IN:
- dir = DIR_IN;
- break;
- case CAM_DIR_OUT:
- dir = DIR_OUT;
- DIF(UDMASS_SCSI,
- umass_dump_buffer(sc, ccb->csio.data_ptr,
- ccb->csio.dxfer_len, 48));
- break;
- default:
- dir = DIR_NONE;
- }
-
- ccb->ccb_h.status = CAM_REQ_INPROG | CAM_SIM_QUEUED;
-
- /*
- * sc->sc_transform will convert the command to the
- * command format needed by the specific command set
- * and return the converted command in
- * "sc->sc_transfer.cmd_data"
- */
- if (umass_std_transform(sc, ccb, cmd, ccb->csio.cdb_len)) {
-
- if (sc->sc_transfer.cmd_data[0] == INQUIRY) {
-
- /*
- * Handle EVPD inquiry for broken devices first
- * NO_INQUIRY also implies NO_INQUIRY_EVPD
- */
- if ((sc->sc_quirks & (NO_INQUIRY_EVPD | NO_INQUIRY)) &&
- (sc->sc_transfer.cmd_data[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);
- goto done;
- }
- /*
- * Return fake inquiry data for
- * broken devices
- */
- if (sc->sc_quirks & NO_INQUIRY) {
- memcpy(ccb->csio.data_ptr, &fake_inq_data,
- sizeof(fake_inq_data));
- ccb->csio.scsi_status = SCSI_STATUS_OK;
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- goto done;
- }
- if (sc->sc_quirks & FORCE_SHORT_INQUIRY) {
- ccb->csio.dxfer_len = SHORT_INQUIRY_LENGTH;
- }
- } else if (sc->sc_transfer.cmd_data[0] == SYNCHRONIZE_CACHE) {
- if (sc->sc_quirks & NO_SYNCHRONIZE_CACHE) {
- ccb->csio.scsi_status = SCSI_STATUS_OK;
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- goto done;
- }
- }
- umass_command_start(sc, dir, ccb->csio.data_ptr,
- ccb->csio.dxfer_len,
- ccb->ccb_h.timeout,
- &umass_cam_cb, ccb);
- }
- break;
- }
- case XPT_PATH_INQ:
- {
- struct ccb_pathinq *cpi = &ccb->cpi;
-
- DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_PATH_INQ:.\n",
- sc ? cam_sim_path(sc->sc_sim) : -1, 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;
- strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
- strlcpy(cpi->hba_vid, "USB SCSI", HBA_IDLEN);
- strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
- cpi->unit_number = cam_sim_unit(sim);
- cpi->bus_id = sc->sc_unit;
-#if (__FreeBSD_version >= 700025)
- cpi->protocol = PROTO_SCSI;
- cpi->protocol_version = SCSI_REV_2;
- cpi->transport = XPORT_USB;
- cpi->transport_version = 0;
-#endif
- if (sc == NULL) {
- cpi->base_transfer_speed = 0;
- cpi->max_lun = 0;
- } else {
- if (sc->sc_quirks & FLOPPY_SPEED) {
- cpi->base_transfer_speed =
- UMASS_FLOPPY_TRANSFER_SPEED;
- } else if (usb2_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->sc_maxlun;
- }
-
- cpi->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
- case XPT_RESET_DEV:
- {
- DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_RESET_DEV:.\n",
- cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
- ccb->ccb_h.target_lun);
-
- umass_reset(sc);
-
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
- case XPT_GET_TRAN_SETTINGS:
- {
- struct ccb_trans_settings *cts = &ccb->cts;
-
- DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_GET_TRAN_SETTINGS:.\n",
- cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
- ccb->ccb_h.target_lun);
-
-#if (__FreeBSD_version >= 700025)
- cts->protocol = PROTO_SCSI;
- cts->protocol_version = SCSI_REV_2;
- cts->transport = XPORT_USB;
- cts->transport_version = 0;
- cts->xport_specific.valid = 0;
-#else
- cts->valid = 0;
- cts->flags = 0; /* no disconnection, tagging */
-#endif
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
- case XPT_SET_TRAN_SETTINGS:
- {
- DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:XPT_SET_TRAN_SETTINGS:.\n",
- cam_sim_path(sc->sc_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(sc, UDMASS_SCSI, "%d:%d:%d:XPT_NOOP:.\n",
- sc ? cam_sim_path(sc->sc_sim) : -1, ccb->ccb_h.target_id,
- ccb->ccb_h.target_lun);
-
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
- default:
- DPRINTF(sc, UDMASS_SCSI, "%d:%d:%d:func_code 0x%04x: "
- "Not implemented\n",
- sc ? cam_sim_path(sc->sc_sim) : -1, 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;
- }
-
-done:
-#if (__FreeBSD_version < 700037)
- if (sc) {
- mtx_unlock(&sc->sc_mtx);
- }
-#endif
- return;
-}
-
-static void
-umass_cam_poll(struct cam_sim *sim)
-{
- struct umass_softc *sc = (struct umass_softc *)sim->softc;
-
- if (sc == UMASS_GONE)
- return;
-
- DPRINTF(sc, UDMASS_SCSI, "CAM poll\n");
-
- usb2_do_poll(sc->sc_xfer, UMASS_T_MAX);
-}
-
-
-/* umass_cam_cb
- * finalise a completed CAM command
- */
-
-static void
-umass_cam_cb(struct umass_softc *sc, union ccb *ccb, uint32_t residue,
- uint8_t status)
-{
- ccb->csio.resid = residue;
-
- switch (status) {
- case STATUS_CMD_OK:
- ccb->ccb_h.status = CAM_REQ_CMP;
- if ((sc->sc_quirks & READ_CAPACITY_OFFBY1) &&
- (ccb->ccb_h.func_code == XPT_SCSI_IO) &&
- (ccb->csio.cdb_io.cdb_bytes[0] == READ_CAPACITY)) {
- struct scsi_read_capacity_data *rcap;
- uint32_t maxsector;
-
- rcap = (void *)(ccb->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:
-
- /* fetch sense data */
-
- /* the rest of the command was filled in at attach */
- sc->cam_scsi_sense.length = ccb->csio.sense_len;
-
- DPRINTF(sc, UDMASS_SCSI, "Fetching %d bytes of "
- "sense data\n", ccb->csio.sense_len);
-
- if (umass_std_transform(sc, ccb, &sc->cam_scsi_sense.opcode,
- sizeof(sc->cam_scsi_sense))) {
-
- if ((sc->sc_quirks & FORCE_SHORT_INQUIRY) &&
- (sc->sc_transfer.cmd_data[0] == INQUIRY)) {
- ccb->csio.sense_len = SHORT_INQUIRY_LENGTH;
- }
- umass_command_start(sc, DIR_IN, &ccb->csio.sense_data.error_code,
- ccb->csio.sense_len, ccb->ccb_h.timeout,
- &umass_cam_sense_cb, ccb);
- }
- break;
-
- default:
- /*
- * 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;
- }
-}
-
-/*
- * Finalise a completed autosense operation
- */
-static void
-umass_cam_sense_cb(struct umass_softc *sc, union ccb *ccb, uint32_t residue,
- uint8_t status)
-{
- uint8_t *cmd;
- uint8_t key;
-
- switch (status) {
- case STATUS_CMD_OK:
- case STATUS_CMD_UNKNOWN:
- case STATUS_CMD_FAILED:
-
- if (ccb->csio.ccb_h.flags & CAM_CDB_POINTER) {
- cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_ptr);
- } else {
- cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_bytes);
- }
-
- key = (ccb->csio.sense_data.flags & SSD_KEY);
-
- /*
- * Getting sense data always succeeds (apart from wire
- * failures):
- */
- if ((sc->sc_quirks & RS_NO_CLEAR_UA) &&
- (cmd[0] == INQUIRY) &&
- (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 (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->sc_quirks & RS_NO_CLEAR_UA) &&
- (cmd[0] == READ_CAPACITY) &&
- (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;
- ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
-
-#if 0
- DELAY(300000);
-#endif
- DPRINTF(sc, UDMASS_SCSI, "Doing a sneaky"
- "TEST_UNIT_READY\n");
-
- /* the rest of the command was filled in at attach */
-
- if (umass_std_transform(sc, ccb,
- &sc->cam_scsi_test_unit_ready.opcode,
- sizeof(sc->cam_scsi_test_unit_ready))) {
- umass_command_start(sc, DIR_NONE, NULL, 0,
- ccb->ccb_h.timeout,
- &umass_cam_quirk_cb, ccb);
- }
- break;
- } else {
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
- | CAM_AUTOSNS_VALID;
- ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
- }
- xpt_done(ccb);
- break;
-
- default:
- DPRINTF(sc, UDMASS_SCSI, "Autosense failed, "
- "status %d\n", 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, union ccb *ccb, uint32_t residue,
- uint8_t status)
-{
- DPRINTF(sc, UDMASS_SCSI, "Test unit ready "
- "returned status %d\n", status);
-
- 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 uint8_t
-umass_scsi_transform(struct umass_softc *sc, uint8_t *cmd_ptr,
- uint8_t cmd_len)
-{
- if ((cmd_len == 0) ||
- (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
- DPRINTF(sc, UDMASS_SCSI, "Invalid command "
- "length: %d bytes\n", cmd_len);
- return (0); /* failure */
- }
- sc->sc_transfer.cmd_len = cmd_len;
-
- switch (cmd_ptr[0]) {
- case TEST_UNIT_READY:
- if (sc->sc_quirks & NO_TEST_UNIT_READY) {
- DPRINTF(sc, UDMASS_SCSI, "Converted TEST_UNIT_READY "
- "to START_UNIT\n");
- bzero(sc->sc_transfer.cmd_data, cmd_len);
- sc->sc_transfer.cmd_data[0] = START_STOP_UNIT;
- sc->sc_transfer.cmd_data[4] = SSS_START;
- return (1);
- }
- break;
-
- case INQUIRY:
- /*
- * some drives wedge when asked for full inquiry
- * information.
- */
- if (sc->sc_quirks & FORCE_SHORT_INQUIRY) {
- bcopy(cmd_ptr, sc->sc_transfer.cmd_data, cmd_len);
- sc->sc_transfer.cmd_data[4] = SHORT_INQUIRY_LENGTH;
- return (1);
- }
- break;
- }
-
- bcopy(cmd_ptr, sc->sc_transfer.cmd_data, cmd_len);
- return (1);
-}
-
-static uint8_t
-umass_rbc_transform(struct umass_softc *sc, uint8_t *cmd_ptr, uint8_t cmd_len)
-{
- if ((cmd_len == 0) ||
- (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
- DPRINTF(sc, UDMASS_SCSI, "Invalid command "
- "length: %d bytes\n", cmd_len);
- return (0); /* failure */
- }
- switch (cmd_ptr[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:
-
- bcopy(cmd_ptr, sc->sc_transfer.cmd_data, cmd_len);
-
- if ((sc->sc_quirks & RBC_PAD_TO_12) && (cmd_len < 12)) {
- bzero(sc->sc_transfer.cmd_data + cmd_len, 12 - cmd_len);
- cmd_len = 12;
- }
- sc->sc_transfer.cmd_len = cmd_len;
- return (1); /* sucess */
-
- /* All other commands are not legal in RBC */
- default:
- DPRINTF(sc, UDMASS_SCSI, "Unsupported RBC "
- "command 0x%02x\n", cmd_ptr[0]);
- return (0); /* failure */
- }
-}
-
-static uint8_t
-umass_ufi_transform(struct umass_softc *sc, uint8_t *cmd_ptr,
- uint8_t cmd_len)
-{
- if ((cmd_len == 0) ||
- (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
- DPRINTF(sc, UDMASS_SCSI, "Invalid command "
- "length: %d bytes\n", cmd_len);
- return (0); /* failure */
- }
- /* An UFI command is always 12 bytes in length */
- sc->sc_transfer.cmd_len = UFI_COMMAND_LENGTH;
-
- /* Zero the command data */
- bzero(sc->sc_transfer.cmd_data, UFI_COMMAND_LENGTH);
-
- switch (cmd_ptr[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->sc_quirks & NO_TEST_UNIT_READY) {
- /*
- * Some devices do not support this command. Start
- * Stop Unit should give the same results
- */
- DPRINTF(sc, UDMASS_UFI, "Converted TEST_UNIT_READY "
- "to START_UNIT\n");
-
- sc->sc_transfer.cmd_data[0] = START_STOP_UNIT;
- sc->sc_transfer.cmd_data[4] = SSS_START;
- return (1);
- }
- break;
-
- 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:
- break;
-
- /*
- * 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:
- DPRINTF(sc, UDMASS_SCSI, "Unsupported UFI "
- "command 0x%02x\n", cmd_ptr[0]);
- return (0); /* failure */
- }
-
- bcopy(cmd_ptr, sc->sc_transfer.cmd_data, cmd_len);
- return (1); /* success */
-}
-
-/*
- * 8070i (ATAPI) specific functions
- */
-static uint8_t
-umass_atapi_transform(struct umass_softc *sc, uint8_t *cmd_ptr,
- uint8_t cmd_len)
-{
- if ((cmd_len == 0) ||
- (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
- DPRINTF(sc, UDMASS_SCSI, "Invalid command "
- "length: %d bytes\n", cmd_len);
- return (0); /* failure */
- }
- /* An ATAPI command is always 12 bytes in length. */
- sc->sc_transfer.cmd_len = ATAPI_COMMAND_LENGTH;
-
- /* Zero the command data */
- bzero(sc->sc_transfer.cmd_data, ATAPI_COMMAND_LENGTH);
-
- switch (cmd_ptr[0]) {
- /*
- * Commands of which the format has been verified. They
- * should work. Copy the command into the destination
- * buffer.
- */
- case INQUIRY:
- /*
- * some drives wedge when asked for full inquiry
- * information.
- */
- if (sc->sc_quirks & FORCE_SHORT_INQUIRY) {
- bcopy(cmd_ptr, sc->sc_transfer.cmd_data, cmd_len);
-
- sc->sc_transfer.cmd_data[4] = SHORT_INQUIRY_LENGTH;
- return (1);
- }
- break;
-
- case TEST_UNIT_READY:
- if (sc->sc_quirks & NO_TEST_UNIT_READY) {
- DPRINTF(sc, UDMASS_SCSI, "Converted TEST_UNIT_READY "
- "to START_UNIT\n");
- sc->sc_transfer.cmd_data[0] = START_STOP_UNIT;
- sc->sc_transfer.cmd_data[4] = SSS_START;
- return (1);
- }
- break;
-
- 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 */
- break;;
-
- case READ_12:
- case WRITE_12:
- default:
- DPRINTF(sc, UDMASS_SCSI, "Unsupported ATAPI "
- "command 0x%02x - trying anyway\n",
- cmd_ptr[0]);
- break;;
- }
-
- bcopy(cmd_ptr, sc->sc_transfer.cmd_data, cmd_len);
- return (1); /* success */
-}
-
-static uint8_t
-umass_no_transform(struct umass_softc *sc, uint8_t *cmd,
- uint8_t cmdlen)
-{
- return (0); /* failure */
-}
-
-static uint8_t
-umass_std_transform(struct umass_softc *sc, union ccb *ccb,
- uint8_t *cmd, uint8_t cmdlen)
-{
- uint8_t retval;
-
- retval = (sc->sc_transform) (sc, cmd, cmdlen);
-
- if (retval == 2) {
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- return (0);
- } else if (retval == 0) {
- ccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(ccb);
- return (0);
- }
- /* Command should be executed */
- return (1);
-}
-
-#if USB_DEBUG
-static void
-umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw)
-{
- uint8_t *c = cbw->CBWCDB;
-
- uint32_t dlen = UGETDW(cbw->dCBWDataTransferLength);
- uint32_t tag = UGETDW(cbw->dCBWTag);
-
- uint8_t clen = cbw->bCDBLength;
- uint8_t flags = cbw->bCBWFlags;
- uint8_t lun = cbw->bCBWLUN;
-
- DPRINTF(sc, UDMASS_BBB, "CBW %d: cmd = %db "
- "(0x%02x%02x%02x%02x%02x%02x%s), "
- "data = %db, lun = %d, dir = %s\n",
- tag, clen,
- c[0], c[1], c[2], c[3], c[4], c[5], (clen > 6 ? "..." : ""),
- dlen, lun, (flags == CBWFLAGS_IN ? "in" :
- (flags == CBWFLAGS_OUT ? "out" : "<invalid>")));
-}
-
-static void
-umass_bbb_dump_csw(struct umass_softc *sc, umass_bbb_csw_t *csw)
-{
- uint32_t sig = UGETDW(csw->dCSWSignature);
- uint32_t tag = UGETDW(csw->dCSWTag);
- uint32_t res = UGETDW(csw->dCSWDataResidue);
- uint8_t status = csw->bCSWStatus;
-
- DPRINTF(sc, UDMASS_BBB, "CSW %d: sig = 0x%08x (%s), tag = 0x%08x, "
- "res = %d, status = 0x%02x (%s)\n",
- 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, uint8_t cmdlen)
-{
- uint8_t *c = cmd;
- uint8_t dir = sc->sc_transfer.dir;
-
- DPRINTF(sc, UDMASS_BBB, "cmd = %db "
- "(0x%02x%02x%02x%02x%02x%02x%s), "
- "data = %db, dir = %s\n",
- cmdlen,
- c[0], c[1], c[2], c[3], c[4], c[5], (cmdlen > 6 ? "..." : ""),
- sc->sc_transfer.data_len,
- (dir == DIR_IN ? "in" :
- (dir == DIR_OUT ? "out" :
- (dir == DIR_NONE ? "no data phase" : "<invalid>"))));
-}
-
-static void
-umass_dump_buffer(struct umass_softc *sc, uint8_t *buffer, uint32_t buflen,
- uint32_t printlen)
-{
- uint32_t 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(sc, UDMASS_GEN, "0x %s%s\n",
- s1, s2);
- s2[0] = '\0';
- }
- sprintf(&s1[j * 2], "%02x", buffer[i] & 0xff);
- }
- if (buflen > printlen)
- sprintf(s3, " ...");
- DPRINTF(sc, UDMASS_GEN, "0x %s%s%s\n",
- s1, s2, s3);
-}
-
-#endif
diff --git a/sys/dev/usb2/storage/urio2.c b/sys/dev/usb2/storage/urio2.c
deleted file mode 100644
index e592f77..0000000
--- a/sys/dev/usb2/storage/urio2.c
+++ /dev/null
@@ -1,480 +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 "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_ioctl.h>
-#include <dev/usb/rio500_usb.h>
-
-#define USB_DEBUG_VAR urio_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_mbuf.h>
-#include <dev/usb2/core/usb2_dev.h>
-#include <dev/usb2/core/usb2_generic.h>
-
-#if USB_DEBUG
-static int urio_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, urio, CTLFLAG_RW, 0, "USB urio");
-SYSCTL_INT(_hw_usb2_urio, OID_AUTO, debug, CTLFLAG_RW,
- &urio_debug, 0, "urio debug level");
-#endif
-
-#define URIO_T_WR 0
-#define URIO_T_RD 1
-#define URIO_T_WR_CS 2
-#define URIO_T_RD_CS 3
-#define URIO_T_MAX 4
-
-#define URIO_BSIZE (1<<12) /* bytes */
-#define URIO_IFQ_MAXLEN 2 /* units */
-
-struct urio_softc {
- struct usb2_fifo_sc sc_fifo;
- struct mtx sc_mtx;
-
- struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[URIO_T_MAX];
-
- uint8_t sc_flags;
-#define URIO_FLAG_READ_STALL 0x01 /* read transfer stalled */
-#define URIO_FLAG_WRITE_STALL 0x02 /* write transfer stalled */
-
- uint8_t sc_name[16];
-};
-
-/* prototypes */
-
-static device_probe_t urio_probe;
-static device_attach_t urio_attach;
-static device_detach_t urio_detach;
-
-static usb2_callback_t urio_write_callback;
-static usb2_callback_t urio_write_clear_stall_callback;
-static usb2_callback_t urio_read_callback;
-static usb2_callback_t urio_read_clear_stall_callback;
-
-static usb2_fifo_close_t urio_close;
-static usb2_fifo_cmd_t urio_start_read;
-static usb2_fifo_cmd_t urio_start_write;
-static usb2_fifo_cmd_t urio_stop_read;
-static usb2_fifo_cmd_t urio_stop_write;
-static usb2_fifo_ioctl_t urio_ioctl;
-static usb2_fifo_open_t urio_open;
-
-static struct usb2_fifo_methods urio_fifo_methods = {
- .f_close = &urio_close,
- .f_ioctl = &urio_ioctl,
- .f_open = &urio_open,
- .f_start_read = &urio_start_read,
- .f_start_write = &urio_start_write,
- .f_stop_read = &urio_stop_read,
- .f_stop_write = &urio_stop_write,
- .basename[0] = "urio",
-};
-
-static const struct usb2_config urio_config[URIO_T_MAX] = {
- [URIO_T_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = URIO_BSIZE,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.proxy_buffer = 1,},
- .mh.callback = &urio_write_callback,
- },
-
- [URIO_T_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = URIO_BSIZE,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.proxy_buffer = 1,},
- .mh.callback = &urio_read_callback,
- },
-
- [URIO_T_WR_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &urio_write_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
-
- [URIO_T_RD_CS] = {
- .type = UE_CONTROL,
- .endpoint = 0x00, /* Control pipe */
- .direction = UE_DIR_ANY,
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.flags = {},
- .mh.callback = &urio_read_clear_stall_callback,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- },
-};
-
-static devclass_t urio_devclass;
-
-static device_method_t urio_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, urio_probe),
- DEVMETHOD(device_attach, urio_attach),
- DEVMETHOD(device_detach, urio_detach),
- {0, 0}
-};
-
-static driver_t urio_driver = {
- .name = "urio",
- .methods = urio_methods,
- .size = sizeof(struct urio_softc),
-};
-
-DRIVER_MODULE(urio, ushub, urio_driver, urio_devclass, NULL, 0);
-MODULE_DEPEND(urio, usb2_storage, 1, 1, 1);
-MODULE_DEPEND(urio, usb2_core, 1, 1, 1);
-
-static int
-urio_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST) {
- return (ENXIO);
- }
- if ((((uaa->info.idVendor == USB_VENDOR_DIAMOND) &&
- (uaa->info.idProduct == USB_PRODUCT_DIAMOND_RIO500USB)) ||
- ((uaa->info.idVendor == USB_VENDOR_DIAMOND2) &&
- ((uaa->info.idProduct == USB_PRODUCT_DIAMOND2_RIO600USB) ||
- (uaa->info.idProduct == USB_PRODUCT_DIAMOND2_RIO800USB)))))
- return (0);
- else
- return (ENXIO);
-}
-
-static int
-urio_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct urio_softc *sc = device_get_softc(dev);
- int error;
-
- device_set_usb2_desc(dev);
-
- sc->sc_udev = uaa->device;
-
- mtx_init(&sc->sc_mtx, "urio lock", NULL, MTX_DEF | MTX_RECURSE);
-
- snprintf(sc->sc_name, sizeof(sc->sc_name),
- "%s", device_get_nameunit(dev));
-
- error = usb2_transfer_setup(uaa->device,
- &uaa->info.bIfaceIndex, sc->sc_xfer,
- urio_config, URIO_T_MAX, sc, &sc->sc_mtx);
-
- if (error) {
- DPRINTF("error=%s\n", usb2_errstr(error));
- goto detach;
- }
- /* set interface permissions */
- usb2_set_iface_perm(uaa->device, uaa->info.bIfaceIndex,
- UID_ROOT, GID_OPERATOR, 0644);
-
- error = usb2_fifo_attach(uaa->device, sc, &sc->sc_mtx,
- &urio_fifo_methods, &sc->sc_fifo,
- device_get_unit(dev), 0 - 1, uaa->info.bIfaceIndex);
- if (error) {
- goto detach;
- }
- return (0); /* success */
-
-detach:
- urio_detach(dev);
- return (ENOMEM); /* failure */
-}
-
-static void
-urio_write_callback(struct usb2_xfer *xfer)
-{
- struct urio_softc *sc = xfer->priv_sc;
- struct usb2_fifo *f = sc->sc_fifo.fp[USB_FIFO_TX];
- uint32_t actlen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- case USB_ST_SETUP:
- if (sc->sc_flags & URIO_FLAG_WRITE_STALL) {
- usb2_transfer_start(sc->sc_xfer[URIO_T_WR_CS]);
- return;
- }
- if (usb2_fifo_get_data(f, xfer->frbuffers, 0,
- xfer->max_data_length, &actlen, 0)) {
-
- xfer->frlengths[0] = actlen;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- sc->sc_flags |= URIO_FLAG_WRITE_STALL;
- usb2_transfer_start(sc->sc_xfer[URIO_T_WR_CS]);
- }
- return;
- }
-}
-
-static void
-urio_write_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct urio_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[URIO_T_WR];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~URIO_FLAG_WRITE_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
-urio_read_callback(struct usb2_xfer *xfer)
-{
- struct urio_softc *sc = xfer->priv_sc;
- struct usb2_fifo *f = sc->sc_fifo.fp[USB_FIFO_RX];
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_fifo_put_data(f, xfer->frbuffers, 0,
- xfer->actlen, 1);
-
- case USB_ST_SETUP:
- if (sc->sc_flags & URIO_FLAG_READ_STALL) {
- usb2_transfer_start(sc->sc_xfer[URIO_T_RD_CS]);
- return;
- }
- if (usb2_fifo_put_bytes_max(f) != 0) {
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- sc->sc_flags |= URIO_FLAG_READ_STALL;
- usb2_transfer_start(sc->sc_xfer[URIO_T_RD_CS]);
- }
- return;
- }
-}
-
-static void
-urio_read_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct urio_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[URIO_T_RD];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~URIO_FLAG_READ_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
-urio_start_read(struct usb2_fifo *fifo)
-{
- struct urio_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_start(sc->sc_xfer[URIO_T_RD]);
-}
-
-static void
-urio_stop_read(struct usb2_fifo *fifo)
-{
- struct urio_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_stop(sc->sc_xfer[URIO_T_RD_CS]);
- usb2_transfer_stop(sc->sc_xfer[URIO_T_RD]);
-}
-
-static void
-urio_start_write(struct usb2_fifo *fifo)
-{
- struct urio_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_start(sc->sc_xfer[URIO_T_WR]);
-}
-
-static void
-urio_stop_write(struct usb2_fifo *fifo)
-{
- struct urio_softc *sc = fifo->priv_sc0;
-
- usb2_transfer_stop(sc->sc_xfer[URIO_T_WR_CS]);
- usb2_transfer_stop(sc->sc_xfer[URIO_T_WR]);
-}
-
-static int
-urio_open(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- struct urio_softc *sc = fifo->priv_sc0;
-
- if ((fflags & (FWRITE | FREAD)) != (FWRITE | FREAD)) {
- return (EACCES);
- }
- if (fflags & FREAD) {
- /* clear stall first */
- mtx_lock(&sc->sc_mtx);
- sc->sc_flags |= URIO_FLAG_READ_STALL;
- mtx_unlock(&sc->sc_mtx);
-
- if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[URIO_T_RD]->max_data_length,
- URIO_IFQ_MAXLEN)) {
- return (ENOMEM);
- }
- }
- if (fflags & FWRITE) {
- /* clear stall first */
- sc->sc_flags |= URIO_FLAG_WRITE_STALL;
-
- if (usb2_fifo_alloc_buffer(fifo,
- sc->sc_xfer[URIO_T_WR]->max_data_length,
- URIO_IFQ_MAXLEN)) {
- return (ENOMEM);
- }
- }
- return (0); /* success */
-}
-
-static void
-urio_close(struct usb2_fifo *fifo, int fflags, struct thread *td)
-{
- if (fflags & (FREAD | FWRITE)) {
- usb2_fifo_free_buffer(fifo);
- }
-}
-
-static int
-urio_ioctl(struct usb2_fifo *fifo, u_long cmd, void *addr,
- int fflags, struct thread *td)
-{
- struct usb2_ctl_request ur;
- struct RioCommand *rio_cmd;
- int error;
-
- switch (cmd) {
- case RIO_RECV_COMMAND:
- if (!(fflags & FWRITE)) {
- error = EPERM;
- goto done;
- }
- bzero(&ur, sizeof(ur));
- rio_cmd = addr;
- ur.ucr_request.bmRequestType =
- rio_cmd->requesttype | UT_READ_VENDOR_DEVICE;
- break;
-
- case RIO_SEND_COMMAND:
- if (!(fflags & FWRITE)) {
- error = EPERM;
- goto done;
- }
- bzero(&ur, sizeof(ur));
- rio_cmd = addr;
- ur.ucr_request.bmRequestType =
- rio_cmd->requesttype | UT_WRITE_VENDOR_DEVICE;
- break;
-
- default:
- error = EINVAL;
- goto done;
- }
-
- DPRINTFN(2, "Sending command\n");
-
- /* Send rio control message */
- ur.ucr_request.bRequest = rio_cmd->request;
- USETW(ur.ucr_request.wValue, rio_cmd->value);
- USETW(ur.ucr_request.wIndex, rio_cmd->index);
- USETW(ur.ucr_request.wLength, rio_cmd->length);
- ur.ucr_data = rio_cmd->buffer;
-
- /* reuse generic USB code */
- error = ugen_do_request(fifo, &ur);
-
-done:
- return (error);
-}
-
-static int
-urio_detach(device_t dev)
-{
- struct urio_softc *sc = device_get_softc(dev);
-
- DPRINTF("\n");
-
- usb2_fifo_detach(&sc->sc_fifo);
-
- usb2_transfer_unsetup(sc->sc_xfer, URIO_T_MAX);
-
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
diff --git a/sys/dev/usb2/storage/usb2_storage.c b/sys/dev/usb2/storage/usb2_storage.c
deleted file mode 100644
index c8233ef..0000000
--- a/sys/dev/usb2/storage/usb2_storage.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/storage/usb2_storage.h>
-
-MODULE_VERSION(usb2_storage, 1);
-MODULE_DEPEND(usb2_storage, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/storage/usb2_storage.h b/sys/dev/usb2/storage/usb2_storage.h
deleted file mode 100644
index f40828a..0000000
--- a/sys/dev/usb2/storage/usb2_storage.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_STORAGE_H_
-#define _USB2_STORAGE_H_
-
-#endif /* _USB2_STORAGE_H_ */
diff --git a/sys/dev/usb2/storage/ustorage2_fs.c b/sys/dev/usb2/storage/ustorage2_fs.c
deleted file mode 100644
index 2fb42a5..0000000
--- a/sys/dev/usb2/storage/ustorage2_fs.c
+++ /dev/null
@@ -1,1898 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (C) 2003-2005 Alan Stern
- * Copyright (C) 2008 Hans Petter Selasky
- * 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.
- * 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 names of the above-listed copyright holders may not be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
- */
-
-/*
- * NOTE: Much of the SCSI statemachine handling code derives from the
- * Linux USB gadget stack.
- */
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-#include <dev/usb2/include/usb2_defs.h>
-
-#define USB_DEBUG_VAR ustorage_fs_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_util.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_device.h>
-
-#if USB_DEBUG
-static int ustorage_fs_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ustorage_fs, CTLFLAG_RW, 0, "USB ustorage_fs");
-SYSCTL_INT(_hw_usb2_ustorage_fs, OID_AUTO, debug, CTLFLAG_RW,
- &ustorage_fs_debug, 0, "ustorage_fs debug level");
-#endif
-
-/* Define some limits */
-
-#define USTORAGE_FS_BULK_SIZE (1 << 17)
-#define USTORAGE_FS_MAX_LUN 8
-#define USTORAGE_FS_RELEASE 0x0101
-#define USTORAGE_FS_RAM_SECT (1 << 13)
-
-static uint8_t *ustorage_fs_ramdisk;
-
-/* USB transfer definitions */
-
-#define USTORAGE_FS_T_BBB_COMMAND 0
-#define USTORAGE_FS_T_BBB_DATA_DUMP 1
-#define USTORAGE_FS_T_BBB_DATA_READ 2
-#define USTORAGE_FS_T_BBB_DATA_WRITE 3
-#define USTORAGE_FS_T_BBB_STATUS 4
-#define USTORAGE_FS_T_BBB_MAX 5
-
-/* USB data stage direction */
-
-#define DIR_NONE 0
-#define DIR_READ 1
-#define DIR_WRITE 2
-
-/* USB interface specific control request */
-
-#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 ustorage_fs_bbb_cbw_t;
-
-#define USTORAGE_FS_BBB_CBW_SIZE 31
-
-/* Command Status Wrapper */
-typedef struct {
- uDWord dCSWSignature;
-#define CSWSIGNATURE 0x53425355
- uDWord dCSWTag;
- uDWord dCSWDataResidue;
- uByte bCSWStatus;
-#define CSWSTATUS_GOOD 0x0
-#define CSWSTATUS_FAILED 0x1
-#define CSWSTATUS_PHASE 0x2
-} __packed ustorage_fs_bbb_csw_t;
-
-#define USTORAGE_FS_BBB_CSW_SIZE 13
-
-struct ustorage_fs_lun {
-
- void *memory_image;
-
- uint32_t num_sectors;
- uint32_t sense_data;
- uint32_t sense_data_info;
- uint32_t unit_attention_data;
-
- uint8_t read_only:1;
- uint8_t prevent_medium_removal:1;
- uint8_t info_valid:1;
- uint8_t removable:1;
-};
-
-struct ustorage_fs_softc {
-
- ustorage_fs_bbb_cbw_t sc_cbw; /* Command Wrapper Block */
- ustorage_fs_bbb_csw_t sc_csw; /* Command Status Block */
-
- struct mtx sc_mtx;
-
- struct ustorage_fs_lun sc_lun[USTORAGE_FS_MAX_LUN];
-
- struct {
- uint8_t *data_ptr;
- struct ustorage_fs_lun *currlun;
-
- uint32_t data_rem; /* bytes, as reported by the command
- * block wrapper */
- uint32_t offset; /* bytes */
-
- uint8_t cbw_dir;
- uint8_t cmd_dir;
- uint8_t lun;
- uint8_t cmd_data[CBWCDBLENGTH];
- uint8_t cmd_len;
- uint8_t data_short:1;
- uint8_t data_error:1;
- } sc_transfer;
-
- device_t sc_dev;
- struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[USTORAGE_FS_T_BBB_MAX];
-
- uint32_t sc_unit;
-
- uint8_t sc_name[16];
- uint8_t sc_iface_no; /* interface number */
- uint8_t sc_last_lun;
- uint8_t sc_last_xfer_index;
- uint8_t sc_qdata[1024];
-};
-
-/* prototypes */
-
-static device_probe_t ustorage_fs_probe;
-static device_attach_t ustorage_fs_attach;
-static device_detach_t ustorage_fs_detach;
-static device_suspend_t ustorage_fs_suspend;
-static device_resume_t ustorage_fs_resume;
-static device_shutdown_t ustorage_fs_shutdown;
-static usb2_handle_request_t ustorage_fs_handle_request;
-
-static usb2_callback_t ustorage_fs_t_bbb_command_callback;
-static usb2_callback_t ustorage_fs_t_bbb_data_dump_callback;
-static usb2_callback_t ustorage_fs_t_bbb_data_read_callback;
-static usb2_callback_t ustorage_fs_t_bbb_data_write_callback;
-static usb2_callback_t ustorage_fs_t_bbb_status_callback;
-
-static void ustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index);
-static void ustorage_fs_transfer_stop(struct ustorage_fs_softc *sc);
-
-static uint8_t ustorage_fs_verify(struct ustorage_fs_softc *sc);
-static uint8_t ustorage_fs_inquiry(struct ustorage_fs_softc *sc);
-static uint8_t ustorage_fs_request_sense(struct ustorage_fs_softc *sc);
-static uint8_t ustorage_fs_read_capacity(struct ustorage_fs_softc *sc);
-static uint8_t ustorage_fs_mode_sense(struct ustorage_fs_softc *sc);
-static uint8_t ustorage_fs_start_stop(struct ustorage_fs_softc *sc);
-static uint8_t ustorage_fs_prevent_allow(struct ustorage_fs_softc *sc);
-static uint8_t ustorage_fs_read_format_capacities(struct ustorage_fs_softc *sc);
-static uint8_t ustorage_fs_mode_select(struct ustorage_fs_softc *sc);
-static uint8_t ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask);
-static uint8_t ustorage_fs_read(struct ustorage_fs_softc *sc);
-static uint8_t ustorage_fs_write(struct ustorage_fs_softc *sc);
-static uint8_t ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t cmd_size, uint16_t mask, uint8_t needs_medium);
-static uint8_t ustorage_fs_do_cmd(struct ustorage_fs_softc *sc);
-
-static device_method_t ustorage_fs_methods[] = {
- /* USB interface */
- DEVMETHOD(usb2_handle_request, ustorage_fs_handle_request),
-
- /* Device interface */
- DEVMETHOD(device_probe, ustorage_fs_probe),
- DEVMETHOD(device_attach, ustorage_fs_attach),
- DEVMETHOD(device_detach, ustorage_fs_detach),
- DEVMETHOD(device_suspend, ustorage_fs_suspend),
- DEVMETHOD(device_resume, ustorage_fs_resume),
- DEVMETHOD(device_shutdown, ustorage_fs_shutdown),
-
- {0, 0}
-};
-
-static driver_t ustorage_fs_driver = {
- .name = "ustorage_fs",
- .methods = ustorage_fs_methods,
- .size = sizeof(struct ustorage_fs_softc),
-};
-
-static devclass_t ustorage_fs_devclass;
-
-DRIVER_MODULE(ustorage_fs, ushub, ustorage_fs_driver, ustorage_fs_devclass, NULL, 0);
-MODULE_VERSION(ustorage_fs, 0);
-MODULE_DEPEND(ustorage_fs, usb2_storage, 1, 1, 1);
-MODULE_DEPEND(ustorage_fs, usb2_core, 1, 1, 1);
-
-struct usb2_config ustorage_fs_bbb_config[USTORAGE_FS_T_BBB_MAX] = {
-
- [USTORAGE_FS_T_BBB_COMMAND] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .md.bufsize = sizeof(ustorage_fs_bbb_cbw_t),
- .md.flags = {.ext_buffer = 1,},
- .md.callback = &ustorage_fs_t_bbb_command_callback,
- },
-
- [USTORAGE_FS_T_BBB_DATA_DUMP] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .md.bufsize = 0, /* use wMaxPacketSize */
- .md.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
- .md.callback = &ustorage_fs_t_bbb_data_dump_callback,
- },
-
- [USTORAGE_FS_T_BBB_DATA_READ] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .md.bufsize = USTORAGE_FS_BULK_SIZE,
- .md.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer = 1},
- .md.callback = &ustorage_fs_t_bbb_data_read_callback,
- },
-
- [USTORAGE_FS_T_BBB_DATA_WRITE] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .md.bufsize = USTORAGE_FS_BULK_SIZE,
- .md.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer = 1},
- .md.callback = &ustorage_fs_t_bbb_data_write_callback,
- },
-
- [USTORAGE_FS_T_BBB_STATUS] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .md.bufsize = sizeof(ustorage_fs_bbb_csw_t),
- .md.flags = {.short_xfer_ok = 1,.ext_buffer = 1,},
- .md.callback = &ustorage_fs_t_bbb_status_callback,
- },
-};
-
-/*
- * USB device probe/attach/detach
- */
-
-static int
-ustorage_fs_probe(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct usb2_interface_descriptor *id;
-
- if (uaa->usb2_mode != USB_MODE_DEVICE) {
- return (ENXIO);
- }
- if (uaa->use_generic == 0) {
- /* give other drivers a try first */
- return (ENXIO);
- }
- /* Check for a standards compliant device */
- id = usb2_get_interface_descriptor(uaa->iface);
- if ((id == NULL) ||
- (id->bInterfaceClass != UICLASS_MASS) ||
- (id->bInterfaceSubClass != UISUBCLASS_SCSI) ||
- (id->bInterfaceProtocol != UIPROTO_MASS_BBB)) {
- return (ENXIO);
- }
- return (0);
-}
-
-static int
-ustorage_fs_attach(device_t dev)
-{
- struct ustorage_fs_softc *sc = device_get_softc(dev);
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct usb2_interface_descriptor *id;
- int err;
-
- /*
- * NOTE: the softc struct is bzero-ed in device_set_driver.
- * We can safely call ustorage_fs_detach without specifically
- * initializing the struct.
- */
-
- sc->sc_dev = dev;
- sc->sc_udev = uaa->device;
- sc->sc_unit = device_get_unit(dev);
-
- if (sc->sc_unit == 0) {
- if (ustorage_fs_ramdisk == NULL) {
- /*
- * allocate a memory image for our ramdisk until
- * further
- */
- ustorage_fs_ramdisk =
- malloc(USTORAGE_FS_RAM_SECT << 9, M_USB, M_ZERO | M_WAITOK);
- if (ustorage_fs_ramdisk == NULL) {
- return (ENOMEM);
- }
- }
- sc->sc_lun[0].memory_image = ustorage_fs_ramdisk;
- sc->sc_lun[0].num_sectors = USTORAGE_FS_RAM_SECT;
- sc->sc_lun[0].removable = 1;
- }
- snprintf(sc->sc_name, sizeof(sc->sc_name),
- "%s", device_get_nameunit(dev));
-
- device_set_usb2_desc(dev);
-
- mtx_init(&sc->sc_mtx, "USTORAGE_FS lock",
- NULL, (MTX_DEF | MTX_RECURSE));
-
- /* get interface index */
-
- id = usb2_get_interface_descriptor(uaa->iface);
- if (id == NULL) {
- device_printf(dev, "failed to get "
- "interface number\n");
- goto detach;
- }
- sc->sc_iface_no = id->bInterfaceNumber;
-
- err = usb2_transfer_setup(uaa->device,
- &uaa->info.bIfaceIndex, sc->sc_xfer, ustorage_fs_bbb_config,
- USTORAGE_FS_T_BBB_MAX, sc, &sc->sc_mtx);
- if (err) {
- device_printf(dev, "could not setup required "
- "transfers, %s\n", usb2_errstr(err));
- goto detach;
- }
- /* start Mass Storage State Machine */
-
- mtx_lock(&sc->sc_mtx);
- ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_COMMAND);
- mtx_unlock(&sc->sc_mtx);
-
- return (0); /* success */
-
-detach:
- ustorage_fs_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static int
-ustorage_fs_detach(device_t dev)
-{
- struct ustorage_fs_softc *sc = device_get_softc(dev);
-
- /* teardown our statemachine */
-
- usb2_transfer_unsetup(sc->sc_xfer, USTORAGE_FS_T_BBB_MAX);
-
- mtx_destroy(&sc->sc_mtx);
-
- return (0); /* success */
-}
-
-static int
-ustorage_fs_suspend(device_t dev)
-{
- device_printf(dev, "suspending\n");
- return (0); /* success */
-}
-
-static int
-ustorage_fs_resume(device_t dev)
-{
- device_printf(dev, "resuming\n");
- return (0); /* success */
-}
-
-static int
-ustorage_fs_shutdown(device_t dev)
-{
- return (0); /* success */
-}
-
-/*
- * Generic functions to handle transfers
- */
-
-static void
-ustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index)
-{
- if (sc->sc_xfer[xfer_index]) {
- sc->sc_last_xfer_index = xfer_index;
- usb2_transfer_start(sc->sc_xfer[xfer_index]);
- }
-}
-
-static void
-ustorage_fs_transfer_stop(struct ustorage_fs_softc *sc)
-{
- usb2_transfer_stop(sc->sc_xfer[sc->sc_last_xfer_index]);
- mtx_unlock(&sc->sc_mtx);
- usb2_transfer_drain(sc->sc_xfer[sc->sc_last_xfer_index]);
- mtx_lock(&sc->sc_mtx);
-}
-
-static int
-ustorage_fs_handle_request(device_t dev,
- const void *preq, void **pptr, uint16_t *plen,
- uint16_t offset, uint8_t is_complete)
-{
- struct ustorage_fs_softc *sc = device_get_softc(dev);
- const struct usb2_device_request *req = preq;
-
- if (!is_complete) {
- if (req->bRequest == UR_BBB_RESET) {
- *plen = 0;
- mtx_lock(&sc->sc_mtx);
- ustorage_fs_transfer_stop(sc);
- sc->sc_transfer.data_error = 1;
- ustorage_fs_transfer_start(sc,
- USTORAGE_FS_T_BBB_COMMAND);
- mtx_unlock(&sc->sc_mtx);
- return (0);
- } else if (req->bRequest == UR_BBB_GET_MAX_LUN) {
- if (offset == 0) {
- *plen = 1;
- *pptr = &sc->sc_last_lun;
- } else {
- *plen = 0;
- }
- return (0);
- }
- }
- return (ENXIO); /* use builtin handler */
-}
-
-static void
-ustorage_fs_t_bbb_command_callback(struct usb2_xfer *xfer)
-{
- struct ustorage_fs_softc *sc = xfer->priv_sc;
- uint32_t tag;
- uint8_t error = 0;
-
- DPRINTF("\n");
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- tag = UGETDW(sc->sc_cbw.dCBWSignature);
-
- if (tag != CBWSIGNATURE) {
- /* do nothing */
- DPRINTF("invalid signature 0x%08x\n", tag);
- break;
- }
- tag = UGETDW(sc->sc_cbw.dCBWTag);
-
- /* echo back tag */
- USETDW(sc->sc_csw.dCSWTag, tag);
-
- /* reset status */
- sc->sc_csw.bCSWStatus = 0;
-
- /* reset data offset, data length and data remainder */
- sc->sc_transfer.offset = 0;
- sc->sc_transfer.data_rem =
- UGETDW(sc->sc_cbw.dCBWDataTransferLength);
-
- /* reset data flags */
- sc->sc_transfer.data_short = 0;
-
- /* extract LUN */
- sc->sc_transfer.lun = sc->sc_cbw.bCBWLUN;
-
- if (sc->sc_transfer.data_rem == 0) {
- sc->sc_transfer.cbw_dir = DIR_NONE;
- } else {
- if (sc->sc_cbw.bCBWFlags & CBWFLAGS_IN) {
- sc->sc_transfer.cbw_dir = DIR_WRITE;
- } else {
- sc->sc_transfer.cbw_dir = DIR_READ;
- }
- }
-
- sc->sc_transfer.cmd_len = sc->sc_cbw.bCDBLength;
- if ((sc->sc_transfer.cmd_len > sizeof(sc->sc_cbw.CBWCDB)) ||
- (sc->sc_transfer.cmd_len == 0)) {
- /* just halt - this is invalid */
- DPRINTF("invalid command length %d bytes\n",
- sc->sc_transfer.cmd_len);
- break;
- }
- bcopy(sc->sc_cbw.CBWCDB, sc->sc_transfer.cmd_data,
- sc->sc_transfer.cmd_len);
-
- bzero(sc->sc_cbw.CBWCDB + sc->sc_transfer.cmd_len,
- sizeof(sc->sc_cbw.CBWCDB) - sc->sc_transfer.cmd_len);
-
- error = ustorage_fs_do_cmd(sc);
- if (error) {
- /* got an error */
- DPRINTF("command failed\n");
- break;
- }
- if ((sc->sc_transfer.data_rem > 0) &&
- (sc->sc_transfer.cbw_dir != sc->sc_transfer.cmd_dir)) {
- /* contradicting data transfer direction */
- error = 1;
- DPRINTF("data direction mismatch\n");
- break;
- }
- switch (sc->sc_transfer.cbw_dir) {
- case DIR_READ:
- ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_DATA_READ);
- break;
- case DIR_WRITE:
- ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_DATA_WRITE);
- break;
- default:
- ustorage_fs_transfer_start(sc,
- USTORAGE_FS_T_BBB_STATUS);
- break;
- }
- break;
-
- case USB_ST_SETUP:
-tr_setup:
- if (sc->sc_transfer.data_error) {
- sc->sc_transfer.data_error = 0;
- xfer->flags.stall_pipe = 1;
- DPRINTF("stall pipe\n");
- } else {
- xfer->flags.stall_pipe = 0;
- }
-
- xfer->frlengths[0] = sizeof(sc->sc_cbw);
- usb2_set_frame_data(xfer, &sc->sc_cbw, 0);
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- DPRINTF("error\n");
- if (xfer->error == USB_ERR_CANCELLED) {
- break;
- }
- /* If the pipe is already stalled, don't do another stall */
- if (!xfer->pipe->is_stalled) {
- sc->sc_transfer.data_error = 1;
- }
- /* try again */
- goto tr_setup;
- }
- if (error) {
- if (sc->sc_csw.bCSWStatus == 0) {
- /* set some default error code */
- sc->sc_csw.bCSWStatus = CSWSTATUS_FAILED;
- }
- if (sc->sc_transfer.cbw_dir == DIR_READ) {
- /* dump all data */
- ustorage_fs_transfer_start(sc,
- USTORAGE_FS_T_BBB_DATA_DUMP);
- return;
- }
- if (sc->sc_transfer.cbw_dir == DIR_WRITE) {
- /* need to stall before status */
- sc->sc_transfer.data_error = 1;
- }
- ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_STATUS);
- }
-}
-
-static void
-ustorage_fs_t_bbb_data_dump_callback(struct usb2_xfer *xfer)
-{
- struct ustorage_fs_softc *sc = xfer->priv_sc;
- uint32_t max_bulk = xfer->max_data_length;
-
- DPRINTF("\n");
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- sc->sc_transfer.data_rem -= xfer->actlen;
- sc->sc_transfer.offset += xfer->actlen;
-
- if ((xfer->actlen != xfer->sumlen) ||
- (sc->sc_transfer.data_rem == 0)) {
- /* short transfer or end of data */
- ustorage_fs_transfer_start(sc,
- USTORAGE_FS_T_BBB_STATUS);
- break;
- }
- /* Fallthrough */
-
- case USB_ST_SETUP:
-tr_setup:
- if (max_bulk > sc->sc_transfer.data_rem) {
- max_bulk = sc->sc_transfer.data_rem;
- }
- if (sc->sc_transfer.data_error) {
- sc->sc_transfer.data_error = 0;
- xfer->flags.stall_pipe = 1;
- } else {
- xfer->flags.stall_pipe = 0;
- }
- xfer->frlengths[0] = max_bulk;
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- break;
- }
- /*
- * If the pipe is already stalled, don't do another stall:
- */
- if (!xfer->pipe->is_stalled) {
- sc->sc_transfer.data_error = 1;
- }
- /* try again */
- goto tr_setup;
- }
-}
-
-static void
-ustorage_fs_t_bbb_data_read_callback(struct usb2_xfer *xfer)
-{
- struct ustorage_fs_softc *sc = xfer->priv_sc;
- uint32_t max_bulk = xfer->max_data_length;
-
- DPRINTF("\n");
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- sc->sc_transfer.data_rem -= xfer->actlen;
- sc->sc_transfer.data_ptr += xfer->actlen;
- sc->sc_transfer.offset += xfer->actlen;
-
- if ((xfer->actlen != xfer->sumlen) ||
- (sc->sc_transfer.data_rem == 0)) {
- /* short transfer or end of data */
- ustorage_fs_transfer_start(sc,
- USTORAGE_FS_T_BBB_STATUS);
- break;
- }
- /* Fallthrough */
-
- case USB_ST_SETUP:
-tr_setup:
- if (max_bulk > sc->sc_transfer.data_rem) {
- max_bulk = sc->sc_transfer.data_rem;
- }
- if (sc->sc_transfer.data_error) {
- sc->sc_transfer.data_error = 0;
- xfer->flags.stall_pipe = 1;
- } else {
- xfer->flags.stall_pipe = 0;
- }
-
- xfer->frlengths[0] = max_bulk;
- usb2_set_frame_data(xfer, sc->sc_transfer.data_ptr, 0);
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- break;
- }
- /* If the pipe is already stalled, don't do another stall */
- if (!xfer->pipe->is_stalled) {
- sc->sc_transfer.data_error = 1;
- }
- /* try again */
- goto tr_setup;
- }
-}
-
-static void
-ustorage_fs_t_bbb_data_write_callback(struct usb2_xfer *xfer)
-{
- struct ustorage_fs_softc *sc = xfer->priv_sc;
- uint32_t max_bulk = xfer->max_data_length;
-
- DPRINTF("\n");
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- sc->sc_transfer.data_rem -= xfer->actlen;
- sc->sc_transfer.data_ptr += xfer->actlen;
- sc->sc_transfer.offset += xfer->actlen;
-
- if ((xfer->actlen != xfer->sumlen) ||
- (sc->sc_transfer.data_rem == 0)) {
- /* short transfer or end of data */
- ustorage_fs_transfer_start(sc,
- USTORAGE_FS_T_BBB_STATUS);
- break;
- }
- case USB_ST_SETUP:
-tr_setup:
- if (max_bulk >= sc->sc_transfer.data_rem) {
- max_bulk = sc->sc_transfer.data_rem;
- if (sc->sc_transfer.data_short) {
- xfer->flags.force_short_xfer = 1;
- } else {
- xfer->flags.force_short_xfer = 0;
- }
- } else {
- xfer->flags.force_short_xfer = 0;
- }
-
- if (sc->sc_transfer.data_error) {
- sc->sc_transfer.data_error = 0;
- xfer->flags.stall_pipe = 1;
- } else {
- xfer->flags.stall_pipe = 0;
- }
-
- xfer->frlengths[0] = max_bulk;
- usb2_set_frame_data(xfer, sc->sc_transfer.data_ptr, 0);
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- if (xfer->error == USB_ERR_CANCELLED) {
- break;
- }
- /*
- * If the pipe is already stalled, don't do another
- * stall
- */
- if (!xfer->pipe->is_stalled) {
- sc->sc_transfer.data_error = 1;
- }
- /* try again */
- goto tr_setup;
- }
-}
-
-static void
-ustorage_fs_t_bbb_status_callback(struct usb2_xfer *xfer)
-{
- struct ustorage_fs_softc *sc = xfer->priv_sc;
-
- DPRINTF("\n");
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_COMMAND);
- break;
-
- case USB_ST_SETUP:
-tr_setup:
- USETDW(sc->sc_csw.dCSWSignature, CSWSIGNATURE);
- USETDW(sc->sc_csw.dCSWDataResidue, sc->sc_transfer.data_rem);
-
- if (sc->sc_transfer.data_error) {
- sc->sc_transfer.data_error = 0;
- xfer->flags.stall_pipe = 1;
- } else {
- xfer->flags.stall_pipe = 0;
- }
-
- xfer->frlengths[0] = sizeof(sc->sc_csw);
- usb2_set_frame_data(xfer, &sc->sc_csw, 0);
- usb2_start_hardware(xfer);
- break;
-
- default:
- if (xfer->error == USB_ERR_CANCELLED) {
- break;
- }
- /* If the pipe is already stalled, don't do another stall */
- if (!xfer->pipe->is_stalled) {
- sc->sc_transfer.data_error = 1;
- }
- /* try again */
- goto tr_setup;
- }
-}
-
-/* SCSI commands that we recognize */
-#define SC_FORMAT_UNIT 0x04
-#define SC_INQUIRY 0x12
-#define SC_MODE_SELECT_6 0x15
-#define SC_MODE_SELECT_10 0x55
-#define SC_MODE_SENSE_6 0x1a
-#define SC_MODE_SENSE_10 0x5a
-#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
-#define SC_READ_6 0x08
-#define SC_READ_10 0x28
-#define SC_READ_12 0xa8
-#define SC_READ_CAPACITY 0x25
-#define SC_READ_FORMAT_CAPACITIES 0x23
-#define SC_RELEASE 0x17
-#define SC_REQUEST_SENSE 0x03
-#define SC_RESERVE 0x16
-#define SC_SEND_DIAGNOSTIC 0x1d
-#define SC_START_STOP_UNIT 0x1b
-#define SC_SYNCHRONIZE_CACHE 0x35
-#define SC_TEST_UNIT_READY 0x00
-#define SC_VERIFY 0x2f
-#define SC_WRITE_6 0x0a
-#define SC_WRITE_10 0x2a
-#define SC_WRITE_12 0xaa
-
-/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
-#define SS_NO_SENSE 0
-#define SS_COMMUNICATION_FAILURE 0x040800
-#define SS_INVALID_COMMAND 0x052000
-#define SS_INVALID_FIELD_IN_CDB 0x052400
-#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
-#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500
-#define SS_MEDIUM_NOT_PRESENT 0x023a00
-#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302
-#define SS_NOT_READY_TO_READY_TRANSITION 0x062800
-#define SS_RESET_OCCURRED 0x062900
-#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900
-#define SS_UNRECOVERED_READ_ERROR 0x031100
-#define SS_WRITE_ERROR 0x030c02
-#define SS_WRITE_PROTECTED 0x072700
-
-#define SK(x) ((uint8_t) ((x) >> 16)) /* Sense Key byte, etc. */
-#define ASC(x) ((uint8_t) ((x) >> 8))
-#define ASCQ(x) ((uint8_t) (x))
-
-/* Routines for unaligned data access */
-
-static uint16_t
-get_be16(uint8_t *buf)
-{
- return ((uint16_t)buf[0] << 8) | ((uint16_t)buf[1]);
-}
-
-static uint32_t
-get_be32(uint8_t *buf)
-{
- return ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
- ((uint32_t)buf[2] << 8) | ((uint32_t)buf[3]);
-}
-
-static void
-put_be16(uint8_t *buf, uint16_t val)
-{
- buf[0] = val >> 8;
- buf[1] = val;
-}
-
-static void
-put_be32(uint8_t *buf, uint32_t val)
-{
- buf[0] = val >> 24;
- buf[1] = val >> 16;
- buf[2] = val >> 8;
- buf[3] = val & 0xff;
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_verify
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_verify(struct ustorage_fs_softc *sc)
-{
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
- uint32_t lba;
- uint32_t vlen;
- uint64_t file_offset;
- uint64_t amount_left;
-
- /*
- * Get the starting Logical Block Address
- */
- lba = get_be32(&sc->sc_transfer.cmd_data[2]);
-
- /*
- * We allow DPO (Disable Page Out = don't save data in the cache)
- * but we don't implement it.
- */
- if ((sc->sc_transfer.cmd_data[1] & ~0x10) != 0) {
- currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return (1);
- }
- vlen = get_be16(&sc->sc_transfer.cmd_data[7]);
- if (vlen == 0) {
- goto done;
- }
- /* No default reply */
-
- /* Prepare to carry out the file verify */
- amount_left = vlen;
- amount_left <<= 9;
- file_offset = lba;
- file_offset <<= 9;
-
- /* Range check */
- vlen += lba;
-
- if ((vlen < lba) ||
- (vlen > currlun->num_sectors) ||
- (lba >= currlun->num_sectors)) {
- currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- return (1);
- }
- /* XXX TODO: verify that data is readable */
-done:
- return (ustorage_fs_min_len(sc, 0, 0 - 1));
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_inquiry
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_inquiry(struct ustorage_fs_softc *sc)
-{
- uint8_t *buf = sc->sc_transfer.data_ptr;
- static const char vendor_id[] = "FreeBSD ";
- static const char product_id[] = "File-Stor Gadget";
-
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
-
- if (!sc->sc_transfer.currlun) {
- /* Unsupported LUNs are okay */
- memset(buf, 0, 36);
- buf[0] = 0x7f;
- /* Unsupported, no device - type */
- return (ustorage_fs_min_len(sc, 36, 0 - 1));
- }
- memset(buf, 0, 8);
- /* Non - removable, direct - access device */
- if (currlun->removable)
- buf[1] = 0x80;
- buf[2] = 2;
- /* ANSI SCSI level 2 */
- buf[3] = 2;
- /* SCSI - 2 INQUIRY data format */
- buf[4] = 31;
- /* Additional length */
- /* No special options */
- /*
- * NOTE: We are writing an extra zero here, that is not
- * transferred to the peer:
- */
- snprintf(buf + 8, 28 + 1, "%-8s%-16s%04x", vendor_id, product_id,
- USTORAGE_FS_RELEASE);
- return (ustorage_fs_min_len(sc, 36, 0 - 1));
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_request_sense
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_request_sense(struct ustorage_fs_softc *sc)
-{
- uint8_t *buf = sc->sc_transfer.data_ptr;
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
- uint32_t sd;
- uint32_t sdinfo;
- uint8_t valid;
-
- /*
- * From the SCSI-2 spec., section 7.9 (Unit attention condition):
- *
- * If a REQUEST SENSE command is received from an initiator
- * with a pending unit attention condition (before the target
- * generates the contingent allegiance condition), then the
- * target shall either:
- * a) report any pending sense data and preserve the unit
- * attention condition on the logical unit, or,
- * b) report the unit attention condition, may discard any
- * pending sense data, and clear the unit attention
- * condition on the logical unit for that initiator.
- *
- * FSG normally uses option a); enable this code to use option b).
- */
-#if 0
- if (currlun && currlun->unit_attention_data != SS_NO_SENSE) {
- currlun->sense_data = currlun->unit_attention_data;
- currlun->unit_attention_data = SS_NO_SENSE;
- }
-#endif
-
- if (!currlun) {
- /* Unsupported LUNs are okay */
- sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
- sdinfo = 0;
- valid = 0;
- } else {
- sd = currlun->sense_data;
- sdinfo = currlun->sense_data_info;
- valid = currlun->info_valid << 7;
- currlun->sense_data = SS_NO_SENSE;
- currlun->sense_data_info = 0;
- currlun->info_valid = 0;
- }
-
- memset(buf, 0, 18);
- buf[0] = valid | 0x70;
- /* Valid, current error */
- buf[2] = SK(sd);
- put_be32(&buf[3], sdinfo);
- /* Sense information */
- buf[7] = 18 - 8;
- /* Additional sense length */
- buf[12] = ASC(sd);
- buf[13] = ASCQ(sd);
- return (ustorage_fs_min_len(sc, 18, 0 - 1));
-}
-
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_read_capacity
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_read_capacity(struct ustorage_fs_softc *sc)
-{
- uint8_t *buf = sc->sc_transfer.data_ptr;
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
- uint32_t lba = get_be32(&sc->sc_transfer.cmd_data[2]);
- uint8_t pmi = sc->sc_transfer.cmd_data[8];
-
- /* Check the PMI and LBA fields */
- if ((pmi > 1) || ((pmi == 0) && (lba != 0))) {
- currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return (1);
- }
- put_be32(&buf[0], currlun->num_sectors - 1);
- /* Max logical block */
- put_be32(&buf[4], 512);
- /* Block length */
- return (ustorage_fs_min_len(sc, 8, 0 - 1));
-}
-
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_mode_sense
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_mode_sense(struct ustorage_fs_softc *sc)
-{
- uint8_t *buf = sc->sc_transfer.data_ptr;
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
- uint8_t *buf0;
- uint16_t len;
- uint16_t limit;
- uint8_t mscmnd = sc->sc_transfer.cmd_data[0];
- uint8_t pc;
- uint8_t page_code;
- uint8_t changeable_values;
- uint8_t all_pages;
-
- buf0 = buf;
-
- if ((sc->sc_transfer.cmd_data[1] & ~0x08) != 0) {
- /* Mask away DBD */
- currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return (1);
- }
- pc = sc->sc_transfer.cmd_data[2] >> 6;
- page_code = sc->sc_transfer.cmd_data[2] & 0x3f;
- if (pc == 3) {
- currlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED;
- return (1);
- }
- changeable_values = (pc == 1);
- all_pages = (page_code == 0x3f);
-
- /*
- * Write the mode parameter header. Fixed values are: default
- * medium type, no cache control (DPOFUA), and no block descriptors.
- * The only variable value is the WriteProtect bit. We will fill in
- * the mode data length later.
- */
- memset(buf, 0, 8);
- if (mscmnd == SC_MODE_SENSE_6) {
- buf[2] = (currlun->read_only ? 0x80 : 0x00);
- /* WP, DPOFUA */
- buf += 4;
- limit = 255;
- } else {
- /* SC_MODE_SENSE_10 */
- buf[3] = (currlun->read_only ? 0x80 : 0x00);
- /* WP, DPOFUA */
- buf += 8;
- limit = 65535;
- /* Should really be mod_data.buflen */
- }
-
- /* No block descriptors */
-
- /*
- * The mode pages, in numerical order.
- */
- if ((page_code == 0x08) || all_pages) {
- buf[0] = 0x08;
- /* Page code */
- buf[1] = 10;
- /* Page length */
- memset(buf + 2, 0, 10);
- /* None of the fields are changeable */
-
- if (!changeable_values) {
- buf[2] = 0x04;
- /* Write cache enable, */
- /* Read cache not disabled */
- /* No cache retention priorities */
- put_be16(&buf[4], 0xffff);
- /* Don 't disable prefetch */
- /* Minimum prefetch = 0 */
- put_be16(&buf[8], 0xffff);
- /* Maximum prefetch */
- put_be16(&buf[10], 0xffff);
- /* Maximum prefetch ceiling */
- }
- buf += 12;
- }
- /*
- * Check that a valid page was requested and the mode data length
- * isn't too long.
- */
- len = buf - buf0;
- if (len > limit) {
- currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return (1);
- }
- /* Store the mode data length */
- if (mscmnd == SC_MODE_SENSE_6)
- buf0[0] = len - 1;
- else
- put_be16(buf0, len - 2);
- return (ustorage_fs_min_len(sc, len, 0 - 1));
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_start_stop
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_start_stop(struct ustorage_fs_softc *sc)
-{
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
- uint8_t loej;
- uint8_t start;
- uint8_t immed;
-
- if (!currlun->removable) {
- currlun->sense_data = SS_INVALID_COMMAND;
- return (1);
- }
- immed = sc->sc_transfer.cmd_data[1] & 0x01;
- loej = sc->sc_transfer.cmd_data[4] & 0x02;
- start = sc->sc_transfer.cmd_data[4] & 0x01;
-
- if (immed || loej || start) {
- /* compile fix */
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_prevent_allow
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_prevent_allow(struct ustorage_fs_softc *sc)
-{
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
- uint8_t prevent;
-
- if (!currlun->removable) {
- currlun->sense_data = SS_INVALID_COMMAND;
- return (1);
- }
- prevent = sc->sc_transfer.cmd_data[4] & 0x01;
- if ((sc->sc_transfer.cmd_data[4] & ~0x01) != 0) {
- /* Mask away Prevent */
- currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return (1);
- }
- if (currlun->prevent_medium_removal && !prevent) {
- //fsync_sub(currlun);
- }
- currlun->prevent_medium_removal = prevent;
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_read_format_capacities
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_read_format_capacities(struct ustorage_fs_softc *sc)
-{
- uint8_t *buf = sc->sc_transfer.data_ptr;
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
-
- buf[0] = buf[1] = buf[2] = 0;
- buf[3] = 8;
- /* Only the Current / Maximum Capacity Descriptor */
- buf += 4;
-
- put_be32(&buf[0], currlun->num_sectors);
- /* Number of blocks */
- put_be32(&buf[4], 512);
- /* Block length */
- buf[4] = 0x02;
- /* Current capacity */
- return (ustorage_fs_min_len(sc, 12, 0 - 1));
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_mode_select
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_mode_select(struct ustorage_fs_softc *sc)
-{
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
-
- /* We don't support MODE SELECT */
- currlun->sense_data = SS_INVALID_COMMAND;
- return (1);
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_synchronize_cache
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_synchronize_cache(struct ustorage_fs_softc *sc)
-{
-#if 0
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
- uint8_t rc;
-
- /*
- * We ignore the requested LBA and write out all dirty data buffers.
- */
- rc = 0;
- if (rc) {
- currlun->sense_data = SS_WRITE_ERROR;
- }
-#endif
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_read - read data from disk
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_read(struct ustorage_fs_softc *sc)
-{
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
- uint64_t file_offset;
- uint32_t lba;
- uint32_t len;
-
- /*
- * Get the starting Logical Block Address and check that it's not
- * too big
- */
- if (sc->sc_transfer.cmd_data[0] == SC_READ_6) {
- lba = (sc->sc_transfer.cmd_data[1] << 16) |
- get_be16(&sc->sc_transfer.cmd_data[2]);
- } else {
- lba = get_be32(&sc->sc_transfer.cmd_data[2]);
-
- /*
- * We allow DPO (Disable Page Out = don't save data in the
- * cache) and FUA (Force Unit Access = don't read from the
- * cache), but we don't implement them.
- */
- if ((sc->sc_transfer.cmd_data[1] & ~0x18) != 0) {
- currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return (1);
- }
- }
- len = sc->sc_transfer.data_rem >> 9;
- len += lba;
-
- if ((len < lba) ||
- (len > currlun->num_sectors) ||
- (lba >= currlun->num_sectors)) {
- currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- return (1);
- }
- file_offset = lba;
- file_offset <<= 9;
-
- sc->sc_transfer.data_ptr =
- USB_ADD_BYTES(currlun->memory_image, (uint32_t)file_offset);
-
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_write - write data to disk
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_write(struct ustorage_fs_softc *sc)
-{
- struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
- uint64_t file_offset;
- uint32_t lba;
- uint32_t len;
-
- if (currlun->read_only) {
- currlun->sense_data = SS_WRITE_PROTECTED;
- return (1);
- }
- /* XXX clear SYNC */
-
- /*
- * Get the starting Logical Block Address and check that it's not
- * too big.
- */
- if (sc->sc_transfer.cmd_data[0] == SC_WRITE_6)
- lba = (sc->sc_transfer.cmd_data[1] << 16) |
- get_be16(&sc->sc_transfer.cmd_data[2]);
- else {
- lba = get_be32(&sc->sc_transfer.cmd_data[2]);
-
- /*
- * We allow DPO (Disable Page Out = don't save data in the
- * cache) and FUA (Force Unit Access = write directly to the
- * medium). We don't implement DPO; we implement FUA by
- * performing synchronous output.
- */
- if ((sc->sc_transfer.cmd_data[1] & ~0x18) != 0) {
- currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- return (1);
- }
- if (sc->sc_transfer.cmd_data[1] & 0x08) {
- /* FUA */
- /* XXX set SYNC flag here */
- }
- }
-
- len = sc->sc_transfer.data_rem >> 9;
- len += lba;
-
- if ((len < lba) ||
- (len > currlun->num_sectors) ||
- (lba >= currlun->num_sectors)) {
- currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- return (1);
- }
- file_offset = lba;
- file_offset <<= 9;
-
- sc->sc_transfer.data_ptr =
- USB_ADD_BYTES(currlun->memory_image, (uint32_t)file_offset);
-
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_min_len
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask)
-{
- if (len != sc->sc_transfer.data_rem) {
-
- if (sc->sc_transfer.cbw_dir == DIR_READ) {
- /*
- * there must be something wrong about this SCSI
- * command
- */
- sc->sc_csw.bCSWStatus = CSWSTATUS_PHASE;
- return (1);
- }
- /* compute the minimum length */
-
- if (sc->sc_transfer.data_rem > len) {
- /* data ends prematurely */
- sc->sc_transfer.data_rem = len;
- sc->sc_transfer.data_short = 1;
- }
- /* check length alignment */
-
- if (sc->sc_transfer.data_rem & ~mask) {
- /* data ends prematurely */
- sc->sc_transfer.data_rem &= mask;
- sc->sc_transfer.data_short = 1;
- }
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_check_cmd - check command routine
- *
- * Check whether the command is properly formed and whether its data
- * size and direction agree with the values we already have.
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t min_cmd_size,
- uint16_t mask, uint8_t needs_medium)
-{
- struct ustorage_fs_lun *currlun;
- uint8_t lun = (sc->sc_transfer.cmd_data[1] >> 5);
- uint8_t i;
-
- /* Verify the length of the command itself */
- if (min_cmd_size > sc->sc_transfer.cmd_len) {
- DPRINTF("%u > %u\n",
- min_cmd_size, sc->sc_transfer.cmd_len);
- sc->sc_csw.bCSWStatus = CSWSTATUS_PHASE;
- return (1);
- }
- /* Mask away the LUN */
- sc->sc_transfer.cmd_data[1] &= 0x1f;
-
- /* Check if LUN is correct */
- if (lun != sc->sc_transfer.lun) {
-
- }
- /* Check the LUN */
- if (sc->sc_transfer.lun <= sc->sc_last_lun) {
- sc->sc_transfer.currlun = currlun =
- sc->sc_lun + sc->sc_transfer.lun;
- if (sc->sc_transfer.cmd_data[0] != SC_REQUEST_SENSE) {
- currlun->sense_data = SS_NO_SENSE;
- currlun->sense_data_info = 0;
- currlun->info_valid = 0;
- }
- /*
- * If a unit attention condition exists, only INQUIRY
- * and REQUEST SENSE commands are allowed. Anything
- * else must fail!
- */
- if ((currlun->unit_attention_data != SS_NO_SENSE) &&
- (sc->sc_transfer.cmd_data[0] != SC_INQUIRY) &&
- (sc->sc_transfer.cmd_data[0] != SC_REQUEST_SENSE)) {
- currlun->sense_data = currlun->unit_attention_data;
- currlun->unit_attention_data = SS_NO_SENSE;
- return (1);
- }
- } else {
- sc->sc_transfer.currlun = currlun = NULL;
-
- /*
- * INQUIRY and REQUEST SENSE commands are explicitly allowed
- * to use unsupported LUNs; all others may not.
- */
- if ((sc->sc_transfer.cmd_data[0] != SC_INQUIRY) &&
- (sc->sc_transfer.cmd_data[0] != SC_REQUEST_SENSE)) {
- return (1);
- }
- }
-
- /*
- * Check that only command bytes listed in the mask are
- * non-zero.
- */
- for (i = 0; i != min_cmd_size; i++) {
- if (sc->sc_transfer.cmd_data[i] && !(mask & (1 << i))) {
- if (currlun) {
- currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
- }
- return (1);
- }
- }
-
- /*
- * If the medium isn't mounted and the command needs to access
- * it, return an error.
- */
- if (currlun && (!currlun->memory_image) && needs_medium) {
- currlun->sense_data = SS_MEDIUM_NOT_PRESENT;
- return (1);
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * ustorage_fs_do_cmd - do command
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static uint8_t
-ustorage_fs_do_cmd(struct ustorage_fs_softc *sc)
-{
- uint8_t error = 1;
- uint8_t i;
-
- /* set default data transfer pointer */
- sc->sc_transfer.data_ptr = sc->sc_qdata;
-
- DPRINTF("cmd_data[0]=0x%02x, data_rem=0x%08x\n",
- sc->sc_transfer.cmd_data[0], sc->sc_transfer.data_rem);
-
- switch (sc->sc_transfer.cmd_data[0]) {
- case SC_INQUIRY:
- sc->sc_transfer.cmd_dir = DIR_WRITE;
- error = ustorage_fs_min_len(sc, sc->sc_transfer.cmd_data[4], 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 6,
- (1 << 4) | 1, 0);
- if (error) {
- break;
- }
- error = ustorage_fs_inquiry(sc);
-
- break;
-
- case SC_MODE_SELECT_6:
- sc->sc_transfer.cmd_dir = DIR_READ;
- error = ustorage_fs_min_len(sc, sc->sc_transfer.cmd_data[4], 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 6,
- (1 << 1) | (1 << 4) | 1, 0);
- if (error) {
- break;
- }
- error = ustorage_fs_mode_select(sc);
-
- break;
-
- case SC_MODE_SELECT_10:
- sc->sc_transfer.cmd_dir = DIR_READ;
- error = ustorage_fs_min_len(sc,
- get_be16(&sc->sc_transfer.cmd_data[7]), 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 10,
- (1 << 1) | (3 << 7) | 1, 0);
- if (error) {
- break;
- }
- error = ustorage_fs_mode_select(sc);
-
- break;
-
- case SC_MODE_SENSE_6:
- sc->sc_transfer.cmd_dir = DIR_WRITE;
- error = ustorage_fs_min_len(sc, sc->sc_transfer.cmd_data[4], 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 6,
- (1 << 1) | (1 << 2) | (1 << 4) | 1, 0);
- if (error) {
- break;
- }
- error = ustorage_fs_mode_sense(sc);
-
- break;
-
- case SC_MODE_SENSE_10:
- sc->sc_transfer.cmd_dir = DIR_WRITE;
- error = ustorage_fs_min_len(sc,
- get_be16(&sc->sc_transfer.cmd_data[7]), 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 10,
- (1 << 1) | (1 << 2) | (3 << 7) | 1, 0);
- if (error) {
- break;
- }
- error = ustorage_fs_mode_sense(sc);
-
- break;
-
- case SC_PREVENT_ALLOW_MEDIUM_REMOVAL:
- error = ustorage_fs_min_len(sc, 0, 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 6,
- (1 << 4) | 1, 0);
- if (error) {
- break;
- }
- error = ustorage_fs_prevent_allow(sc);
-
- break;
-
- case SC_READ_6:
- i = sc->sc_transfer.cmd_data[4];
- sc->sc_transfer.cmd_dir = DIR_WRITE;
- error = ustorage_fs_min_len(sc,
- ((i == 0) ? 256 : i) << 9, 0 - (1 << 9));
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 6,
- (7 << 1) | (1 << 4) | 1, 1);
- if (error) {
- break;
- }
- error = ustorage_fs_read(sc);
-
- break;
-
- case SC_READ_10:
- sc->sc_transfer.cmd_dir = DIR_WRITE;
- error = ustorage_fs_min_len(sc,
- get_be16(&sc->sc_transfer.cmd_data[7]) << 9, 0 - (1 << 9));
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 10,
- (1 << 1) | (0xf << 2) | (3 << 7) | 1, 1);
- if (error) {
- break;
- }
- error = ustorage_fs_read(sc);
-
- break;
-
- case SC_READ_12:
- sc->sc_transfer.cmd_dir = DIR_WRITE;
- error = ustorage_fs_min_len(sc,
- get_be32(&sc->sc_transfer.cmd_data[6]) << 9, 0 - (1 << 9));
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 12,
- (1 << 1) | (0xf << 2) | (0xf << 6) | 1, 1);
- if (error) {
- break;
- }
- error = ustorage_fs_read(sc);
-
- break;
-
- case SC_READ_CAPACITY:
- sc->sc_transfer.cmd_dir = DIR_WRITE;
- error = ustorage_fs_check_cmd(sc, 10,
- (0xf << 2) | (1 << 8) | 1, 1);
- if (error) {
- break;
- }
- error = ustorage_fs_read_capacity(sc);
-
- break;
-
- case SC_READ_FORMAT_CAPACITIES:
- sc->sc_transfer.cmd_dir = DIR_WRITE;
- error = ustorage_fs_min_len(sc,
- get_be16(&sc->sc_transfer.cmd_data[7]), 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 10,
- (3 << 7) | 1, 1);
- if (error) {
- break;
- }
- error = ustorage_fs_read_format_capacities(sc);
-
- break;
-
- case SC_REQUEST_SENSE:
- sc->sc_transfer.cmd_dir = DIR_WRITE;
- error = ustorage_fs_min_len(sc, sc->sc_transfer.cmd_data[4], 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 6,
- (1 << 4) | 1, 0);
- if (error) {
- break;
- }
- error = ustorage_fs_request_sense(sc);
-
- break;
-
- case SC_START_STOP_UNIT:
- error = ustorage_fs_min_len(sc, 0, 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 6,
- (1 << 1) | (1 << 4) | 1, 0);
- if (error) {
- break;
- }
- error = ustorage_fs_start_stop(sc);
-
- break;
-
- case SC_SYNCHRONIZE_CACHE:
- error = ustorage_fs_min_len(sc, 0, 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 10,
- (0xf << 2) | (3 << 7) | 1, 1);
- if (error) {
- break;
- }
- error = ustorage_fs_synchronize_cache(sc);
-
- break;
-
- case SC_TEST_UNIT_READY:
- error = ustorage_fs_min_len(sc, 0, 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 6,
- 0 | 1, 1);
- break;
-
- /*
- * Although optional, this command is used by MS-Windows.
- * We support a minimal version: BytChk must be 0.
- */
- case SC_VERIFY:
- error = ustorage_fs_min_len(sc, 0, 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 10,
- (1 << 1) | (0xf << 2) | (3 << 7) | 1, 1);
- if (error) {
- break;
- }
- error = ustorage_fs_verify(sc);
-
- break;
-
- case SC_WRITE_6:
- i = sc->sc_transfer.cmd_data[4];
- sc->sc_transfer.cmd_dir = DIR_READ;
- error = ustorage_fs_min_len(sc,
- ((i == 0) ? 256 : i) << 9, 0 - (1 << 9));
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 6,
- (7 << 1) | (1 << 4) | 1, 1);
- if (error) {
- break;
- }
- error = ustorage_fs_write(sc);
-
- break;
-
- case SC_WRITE_10:
- sc->sc_transfer.cmd_dir = DIR_READ;
- error = ustorage_fs_min_len(sc,
- get_be16(&sc->sc_transfer.cmd_data[7]) << 9, 0 - (1 << 9));
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 10,
- (1 << 1) | (0xf << 2) | (3 << 7) | 1, 1);
- if (error) {
- break;
- }
- error = ustorage_fs_write(sc);
-
- break;
-
- case SC_WRITE_12:
- sc->sc_transfer.cmd_dir = DIR_READ;
- error = ustorage_fs_min_len(sc,
- get_be32(&sc->sc_transfer.cmd_data[6]) << 9, 0 - (1 << 9));
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, 12,
- (1 << 1) | (0xf << 2) | (0xf << 6) | 1, 1);
- if (error) {
- break;
- }
- error = ustorage_fs_write(sc);
-
- break;
-
- /*
- * Some mandatory commands that we recognize but don't
- * implement. They don't mean much in this setting.
- * It's left as an exercise for anyone interested to
- * implement RESERVE and RELEASE in terms of Posix
- * locks.
- */
- case SC_FORMAT_UNIT:
- case SC_RELEASE:
- case SC_RESERVE:
- case SC_SEND_DIAGNOSTIC:
- /* Fallthrough */
-
- default:
- error = ustorage_fs_min_len(sc, 0, 0 - 1);
- if (error) {
- break;
- }
- error = ustorage_fs_check_cmd(sc, sc->sc_transfer.cmd_len,
- 0xff, 0);
- if (error) {
- break;
- }
- sc->sc_transfer.currlun->sense_data =
- SS_INVALID_COMMAND;
- error = 1;
-
- break;
- }
- return (error);
-}
diff --git a/sys/dev/usb2/template/usb2_template.c b/sys/dev/usb2/template/usb2_template.c
deleted file mode 100644
index 3bd0d64..0000000
--- a/sys/dev/usb2/template/usb2_template.c
+++ /dev/null
@@ -1,1312 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2007 Hans Petter Selasky. 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 file contains sub-routines to build up USB descriptors from
- * USB templates.
- */
-
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_cdc.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_defs.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR usb2_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_parse.h>
-#include <dev/usb2/core/usb2_device.h>
-#include <dev/usb2/core/usb2_dynamic.h>
-
-#include <dev/usb2/controller/usb2_controller.h>
-#include <dev/usb2/controller/usb2_bus.h>
-
-#include <dev/usb2/template/usb2_template.h>
-
-MODULE_DEPEND(usb2_template, usb2_core, 1, 1, 1);
-MODULE_VERSION(usb2_template, 1);
-
-/* function prototypes */
-
-static void usb2_make_raw_desc(struct usb2_temp_setup *, const uint8_t *);
-static void usb2_make_endpoint_desc(struct usb2_temp_setup *,
- const struct usb2_temp_endpoint_desc *);
-static void usb2_make_interface_desc(struct usb2_temp_setup *,
- const struct usb2_temp_interface_desc *);
-static void usb2_make_config_desc(struct usb2_temp_setup *,
- const struct usb2_temp_config_desc *);
-static void usb2_make_device_desc(struct usb2_temp_setup *,
- const struct usb2_temp_device_desc *);
-static uint8_t usb2_hw_ep_match(const struct usb2_hw_ep_profile *, uint8_t,
- uint8_t);
-static uint8_t usb2_hw_ep_find_match(struct usb2_hw_ep_scratch *,
- struct usb2_hw_ep_scratch_sub *, uint8_t);
-static uint8_t usb2_hw_ep_get_needs(struct usb2_hw_ep_scratch *, uint8_t,
- uint8_t);
-static usb2_error_t usb2_hw_ep_resolve(struct usb2_device *,
- struct usb2_descriptor *);
-static const struct usb2_temp_device_desc *usb2_temp_get_tdd(struct usb2_device *);
-static void *usb2_temp_get_device_desc(struct usb2_device *);
-static void *usb2_temp_get_qualifier_desc(struct usb2_device *);
-static void *usb2_temp_get_config_desc(struct usb2_device *, uint16_t *,
- uint8_t);
-static const void *usb2_temp_get_string_desc(struct usb2_device *, uint16_t,
- uint8_t);
-static const void *usb2_temp_get_vendor_desc(struct usb2_device *,
- const struct usb2_device_request *);
-static const void *usb2_temp_get_hub_desc(struct usb2_device *);
-static void usb2_temp_get_desc(struct usb2_device *,
- struct usb2_device_request *, const void **, uint16_t *);
-static usb2_error_t usb2_temp_setup(struct usb2_device *,
- const struct usb2_temp_device_desc *);
-static void usb2_temp_unsetup(struct usb2_device *);
-static usb2_error_t usb2_temp_setup_by_index(struct usb2_device *,
- uint16_t index);
-static void usb2_temp_init(void *);
-
-/*------------------------------------------------------------------------*
- * usb2_make_raw_desc
- *
- * This function will insert a raw USB descriptor into the generated
- * USB configuration.
- *------------------------------------------------------------------------*/
-static void
-usb2_make_raw_desc(struct usb2_temp_setup *temp,
- const uint8_t *raw)
-{
- void *dst;
- uint8_t len;
-
- /*
- * The first byte of any USB descriptor gives the length.
- */
- if (raw) {
- len = raw[0];
- if (temp->buf) {
- dst = USB_ADD_BYTES(temp->buf, temp->size);
- bcopy(raw, dst, len);
-
- /* check if we have got a CDC union descriptor */
-
- if ((raw[0] >= sizeof(struct usb2_cdc_union_descriptor)) &&
- (raw[1] == UDESC_CS_INTERFACE) &&
- (raw[2] == UDESCSUB_CDC_UNION)) {
- struct usb2_cdc_union_descriptor *ud = (void *)dst;
-
- /* update the interface numbers */
-
- ud->bMasterInterface +=
- temp->bInterfaceNumber;
- ud->bSlaveInterface[0] +=
- temp->bInterfaceNumber;
- }
- }
- temp->size += len;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_make_endpoint_desc
- *
- * This function will generate an USB endpoint descriptor from the
- * given USB template endpoint descriptor, which will be inserted into
- * the USB configuration.
- *------------------------------------------------------------------------*/
-static void
-usb2_make_endpoint_desc(struct usb2_temp_setup *temp,
- const struct usb2_temp_endpoint_desc *ted)
-{
- struct usb2_endpoint_descriptor *ed;
- const void **rd;
- uint16_t old_size;
- uint16_t mps;
- uint8_t ea = 0; /* Endpoint Address */
- uint8_t et = 0; /* Endpiont Type */
-
- /* Reserve memory */
- old_size = temp->size;
- temp->size += sizeof(*ed);
-
- /* Scan all Raw Descriptors first */
-
- rd = ted->ppRawDesc;
- if (rd) {
- while (*rd) {
- usb2_make_raw_desc(temp, *rd);
- rd++;
- }
- }
- if (ted->pPacketSize == NULL) {
- /* not initialized */
- temp->err = USB_ERR_INVAL;
- return;
- }
- mps = ted->pPacketSize->mps[temp->usb2_speed];
- if (mps == 0) {
- /* not initialized */
- temp->err = USB_ERR_INVAL;
- return;
- } else if (mps == UE_ZERO_MPS) {
- /* escape for Zero Max Packet Size */
- mps = 0;
- }
- ea = (ted->bEndpointAddress & (UE_ADDR | UE_DIR_IN | UE_DIR_OUT));
- et = (ted->bmAttributes & UE_XFERTYPE);
-
- /*
- * Fill out the real USB endpoint descriptor
- * in case there is a buffer present:
- */
- if (temp->buf) {
- ed = USB_ADD_BYTES(temp->buf, old_size);
- ed->bLength = sizeof(*ed);
- ed->bDescriptorType = UDESC_ENDPOINT;
- ed->bEndpointAddress = ea;
- ed->bmAttributes = ted->bmAttributes;
- USETW(ed->wMaxPacketSize, mps);
-
- /* setup bInterval parameter */
-
- if (ted->pIntervals &&
- ted->pIntervals->bInterval[temp->usb2_speed]) {
- ed->bInterval =
- ted->pIntervals->bInterval[temp->usb2_speed];
- } else {
- switch (et) {
- case UE_BULK:
- case UE_CONTROL:
- ed->bInterval = 0; /* not used */
- break;
- case UE_INTERRUPT:
- switch (temp->usb2_speed) {
- case USB_SPEED_LOW:
- case USB_SPEED_FULL:
- ed->bInterval = 1; /* 1 ms */
- break;
- default:
- ed->bInterval = 8; /* 8*125 us */
- break;
- }
- break;
- default: /* UE_ISOCHRONOUS */
- switch (temp->usb2_speed) {
- case USB_SPEED_LOW:
- case USB_SPEED_FULL:
- ed->bInterval = 1; /* 1 ms */
- break;
- default:
- ed->bInterval = 1; /* 125 us */
- break;
- }
- break;
- }
- }
- }
- temp->bNumEndpoints++;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_make_interface_desc
- *
- * This function will generate an USB interface descriptor from the
- * given USB template interface descriptor, which will be inserted
- * into the USB configuration.
- *------------------------------------------------------------------------*/
-static void
-usb2_make_interface_desc(struct usb2_temp_setup *temp,
- const struct usb2_temp_interface_desc *tid)
-{
- struct usb2_interface_descriptor *id;
- const struct usb2_temp_endpoint_desc **ted;
- const void **rd;
- uint16_t old_size;
-
- /* Reserve memory */
-
- old_size = temp->size;
- temp->size += sizeof(*id);
-
- /* Update interface and alternate interface numbers */
-
- if (tid->isAltInterface == 0) {
- temp->bAlternateSetting = 0;
- temp->bInterfaceNumber++;
- } else {
- temp->bAlternateSetting++;
- }
-
- /* Scan all Raw Descriptors first */
-
- rd = tid->ppRawDesc;
-
- if (rd) {
- while (*rd) {
- usb2_make_raw_desc(temp, *rd);
- rd++;
- }
- }
- /* Reset some counters */
-
- temp->bNumEndpoints = 0;
-
- /* Scan all Endpoint Descriptors second */
-
- ted = tid->ppEndpoints;
- if (ted) {
- while (*ted) {
- usb2_make_endpoint_desc(temp, *ted);
- ted++;
- }
- }
- /*
- * Fill out the real USB interface descriptor
- * in case there is a buffer present:
- */
- if (temp->buf) {
- id = USB_ADD_BYTES(temp->buf, old_size);
- id->bLength = sizeof(*id);
- id->bDescriptorType = UDESC_INTERFACE;
- id->bInterfaceNumber = temp->bInterfaceNumber;
- id->bAlternateSetting = temp->bAlternateSetting;
- id->bNumEndpoints = temp->bNumEndpoints;
- id->bInterfaceClass = tid->bInterfaceClass;
- id->bInterfaceSubClass = tid->bInterfaceSubClass;
- id->bInterfaceProtocol = tid->bInterfaceProtocol;
- id->iInterface = tid->iInterface;
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_make_config_desc
- *
- * This function will generate an USB config descriptor from the given
- * USB template config descriptor, which will be inserted into the USB
- * configuration.
- *------------------------------------------------------------------------*/
-static void
-usb2_make_config_desc(struct usb2_temp_setup *temp,
- const struct usb2_temp_config_desc *tcd)
-{
- struct usb2_config_descriptor *cd;
- const struct usb2_temp_interface_desc **tid;
- uint16_t old_size;
-
- /* Reserve memory */
-
- old_size = temp->size;
- temp->size += sizeof(*cd);
-
- /* Reset some counters */
-
- temp->bInterfaceNumber = 0 - 1;
- temp->bAlternateSetting = 0;
-
- /* Scan all the USB interfaces */
-
- tid = tcd->ppIfaceDesc;
- if (tid) {
- while (*tid) {
- usb2_make_interface_desc(temp, *tid);
- tid++;
- }
- }
- /*
- * Fill out the real USB config descriptor
- * in case there is a buffer present:
- */
- if (temp->buf) {
- cd = USB_ADD_BYTES(temp->buf, old_size);
-
- /* compute total size */
- old_size = temp->size - old_size;
-
- cd->bLength = sizeof(*cd);
- cd->bDescriptorType = UDESC_CONFIG;
- USETW(cd->wTotalLength, old_size);
- cd->bNumInterface = temp->bInterfaceNumber + 1;
- cd->bConfigurationValue = temp->bConfigurationValue;
- cd->iConfiguration = tcd->iConfiguration;
- cd->bmAttributes = tcd->bmAttributes;
- cd->bMaxPower = tcd->bMaxPower;
- cd->bmAttributes |= (UC_REMOTE_WAKEUP | UC_BUS_POWERED);
-
- if (temp->self_powered) {
- cd->bmAttributes |= UC_SELF_POWERED;
- } else {
- cd->bmAttributes &= ~UC_SELF_POWERED;
- }
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_make_device_desc
- *
- * This function will generate an USB device descriptor from the
- * given USB template device descriptor.
- *------------------------------------------------------------------------*/
-static void
-usb2_make_device_desc(struct usb2_temp_setup *temp,
- const struct usb2_temp_device_desc *tdd)
-{
- struct usb2_temp_data *utd;
- const struct usb2_temp_config_desc **tcd;
- uint16_t old_size;
-
- /* Reserve memory */
-
- old_size = temp->size;
- temp->size += sizeof(*utd);
-
- /* Scan all the USB configs */
-
- temp->bConfigurationValue = 1;
- tcd = tdd->ppConfigDesc;
- if (tcd) {
- while (*tcd) {
- usb2_make_config_desc(temp, *tcd);
- temp->bConfigurationValue++;
- tcd++;
- }
- }
- /*
- * Fill out the real USB device descriptor
- * in case there is a buffer present:
- */
-
- if (temp->buf) {
- utd = USB_ADD_BYTES(temp->buf, old_size);
-
- /* Store a pointer to our template device descriptor */
- utd->tdd = tdd;
-
- /* Fill out USB device descriptor */
- utd->udd.bLength = sizeof(utd->udd);
- utd->udd.bDescriptorType = UDESC_DEVICE;
- utd->udd.bDeviceClass = tdd->bDeviceClass;
- utd->udd.bDeviceSubClass = tdd->bDeviceSubClass;
- utd->udd.bDeviceProtocol = tdd->bDeviceProtocol;
- USETW(utd->udd.idVendor, tdd->idVendor);
- USETW(utd->udd.idProduct, tdd->idProduct);
- USETW(utd->udd.bcdDevice, tdd->bcdDevice);
- utd->udd.iManufacturer = tdd->iManufacturer;
- utd->udd.iProduct = tdd->iProduct;
- utd->udd.iSerialNumber = tdd->iSerialNumber;
- utd->udd.bNumConfigurations = temp->bConfigurationValue - 1;
-
- /*
- * Fill out the USB device qualifier. Pretend that we
- * don't support any other speeds by setting
- * "bNumConfigurations" equal to zero. That saves us
- * generating an extra set of configuration
- * descriptors.
- */
- utd->udq.bLength = sizeof(utd->udq);
- utd->udq.bDescriptorType = UDESC_DEVICE_QUALIFIER;
- utd->udq.bDeviceClass = tdd->bDeviceClass;
- utd->udq.bDeviceSubClass = tdd->bDeviceSubClass;
- utd->udq.bDeviceProtocol = tdd->bDeviceProtocol;
- utd->udq.bNumConfigurations = 0;
- USETW(utd->udq.bcdUSB, 0x0200);
- utd->udq.bMaxPacketSize0 = 0;
-
- switch (temp->usb2_speed) {
- case USB_SPEED_LOW:
- USETW(utd->udd.bcdUSB, 0x0110);
- utd->udd.bMaxPacketSize = 8;
- break;
- case USB_SPEED_FULL:
- USETW(utd->udd.bcdUSB, 0x0110);
- utd->udd.bMaxPacketSize = 32;
- break;
- case USB_SPEED_HIGH:
- USETW(utd->udd.bcdUSB, 0x0200);
- utd->udd.bMaxPacketSize = 64;
- break;
- case USB_SPEED_VARIABLE:
- USETW(utd->udd.bcdUSB, 0x0250);
- utd->udd.bMaxPacketSize = 255; /* 512 bytes */
- break;
- default:
- temp->err = USB_ERR_INVAL;
- break;
- }
- }
-}
-
-/*------------------------------------------------------------------------*
- * usb2_hw_ep_match
- *
- * Return values:
- * 0: The endpoint profile does not match the criterias
- * Else: The endpoint profile matches the criterias
- *------------------------------------------------------------------------*/
-static uint8_t
-usb2_hw_ep_match(const struct usb2_hw_ep_profile *pf,
- uint8_t ep_type, uint8_t ep_dir_in)
-{
- if (ep_type == UE_CONTROL) {
- /* special */
- return (pf->support_control);
- }
- if ((pf->support_in && ep_dir_in) ||
- (pf->support_out && !ep_dir_in)) {
- if ((pf->support_interrupt && (ep_type == UE_INTERRUPT)) ||
- (pf->support_isochronous && (ep_type == UE_ISOCHRONOUS)) ||
- (pf->support_bulk && (ep_type == UE_BULK))) {
- return (1);
- }
- }
- return (0);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_hw_ep_find_match
- *
- * This function is used to find the best matching endpoint profile
- * for and endpoint belonging to an USB descriptor.
- *
- * Return values:
- * 0: Success. Got a match.
- * Else: Failure. No match.
- *------------------------------------------------------------------------*/
-static uint8_t
-usb2_hw_ep_find_match(struct usb2_hw_ep_scratch *ues,
- struct usb2_hw_ep_scratch_sub *ep, uint8_t is_simplex)
-{
- const struct usb2_hw_ep_profile *pf;
- uint16_t distance;
- uint16_t temp;
- uint16_t max_frame_size;
- uint8_t n;
- uint8_t best_n;
- uint8_t dir_in;
- uint8_t dir_out;
-
- distance = 0xFFFF;
- best_n = 0;
-
- if ((!ep->needs_in) && (!ep->needs_out)) {
- return (0); /* we are done */
- }
- if (ep->needs_ep_type == UE_CONTROL) {
- dir_in = 1;
- dir_out = 1;
- } else {
- if (ep->needs_in) {
- dir_in = 1;
- dir_out = 0;
- } else {
- dir_in = 0;
- dir_out = 1;
- }
- }
-
- for (n = 1; n != (USB_EP_MAX / 2); n++) {
-
- /* get HW endpoint profile */
- (ues->methods->get_hw_ep_profile) (ues->udev, &pf, n);
- if (pf == NULL) {
- /* end of profiles */
- break;
- }
- /* check if IN-endpoint is reserved */
- if (dir_in || pf->is_simplex) {
- if (ues->bmInAlloc[n / 8] & (1 << (n % 8))) {
- /* mismatch */
- continue;
- }
- }
- /* check if OUT-endpoint is reserved */
- if (dir_out || pf->is_simplex) {
- if (ues->bmOutAlloc[n / 8] & (1 << (n % 8))) {
- /* mismatch */
- continue;
- }
- }
- /* check simplex */
- if (pf->is_simplex == is_simplex) {
- /* mismatch */
- continue;
- }
- /* check if HW endpoint matches */
- if (!usb2_hw_ep_match(pf, ep->needs_ep_type, dir_in)) {
- /* mismatch */
- continue;
- }
- /* get maximum frame size */
- if (dir_in)
- max_frame_size = pf->max_in_frame_size;
- else
- max_frame_size = pf->max_out_frame_size;
-
- /* check if we have a matching profile */
- if (max_frame_size >= ep->max_frame_size) {
- temp = (max_frame_size - ep->max_frame_size);
- if (distance > temp) {
- distance = temp;
- best_n = n;
- ep->pf = pf;
- }
- }
- }
-
- /* see if we got a match */
- if (best_n != 0) {
- /* get the correct profile */
- pf = ep->pf;
-
- /* reserve IN-endpoint */
- if (dir_in) {
- ues->bmInAlloc[best_n / 8] |=
- (1 << (best_n % 8));
- ep->hw_endpoint_in = best_n | UE_DIR_IN;
- ep->needs_in = 0;
- }
- /* reserve OUT-endpoint */
- if (dir_out) {
- ues->bmOutAlloc[best_n / 8] |=
- (1 << (best_n % 8));
- ep->hw_endpoint_out = best_n | UE_DIR_OUT;
- ep->needs_out = 0;
- }
- return (0); /* got a match */
- }
- return (1); /* failure */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_hw_ep_get_needs
- *
- * This function will figure out the type and number of endpoints
- * which are needed for an USB configuration.
- *
- * Return values:
- * 0: Success.
- * Else: Failure.
- *------------------------------------------------------------------------*/
-static uint8_t
-usb2_hw_ep_get_needs(struct usb2_hw_ep_scratch *ues,
- uint8_t ep_type, uint8_t is_complete)
-{
- const struct usb2_hw_ep_profile *pf;
- struct usb2_hw_ep_scratch_sub *ep_iface;
- struct usb2_hw_ep_scratch_sub *ep_curr;
- struct usb2_hw_ep_scratch_sub *ep_max;
- struct usb2_hw_ep_scratch_sub *ep_end;
- struct usb2_descriptor *desc;
- struct usb2_interface_descriptor *id;
- struct usb2_endpoint_descriptor *ed;
- uint16_t wMaxPacketSize;
- uint16_t temp;
- uint8_t speed;
- uint8_t ep_no;
-
- ep_iface = ues->ep_max;
- ep_curr = ues->ep_max;
- ep_end = ues->ep + USB_EP_MAX;
- ep_max = ues->ep_max;
- desc = NULL;
- speed = usb2_get_speed(ues->udev);
-
-repeat:
-
- while ((desc = usb2_desc_foreach(ues->cd, desc))) {
-
- if ((desc->bDescriptorType == UDESC_INTERFACE) &&
- (desc->bLength >= sizeof(*id))) {
-
- id = (void *)desc;
-
- if (id->bAlternateSetting == 0) {
- /* going forward */
- ep_iface = ep_max;
- } else {
- /* reset */
- ep_curr = ep_iface;
- }
- }
- if ((desc->bDescriptorType == UDESC_ENDPOINT) &&
- (desc->bLength >= sizeof(*ed))) {
-
- ed = (void *)desc;
-
- goto handle_endpoint_desc;
- }
- }
- ues->ep_max = ep_max;
- return (0);
-
-handle_endpoint_desc:
- temp = (ed->bmAttributes & UE_XFERTYPE);
-
- if (temp == ep_type) {
-
- if (ep_curr == ep_end) {
- /* too many endpoints */
- return (1); /* failure */
- }
- wMaxPacketSize = UGETW(ed->wMaxPacketSize);
- if ((wMaxPacketSize & 0xF800) &&
- (speed == USB_SPEED_HIGH)) {
- /* handle packet multiplier */
- temp = (wMaxPacketSize >> 11) & 3;
- wMaxPacketSize &= 0x7FF;
- if (temp == 1) {
- wMaxPacketSize *= 2;
- } else {
- wMaxPacketSize *= 3;
- }
- }
- /*
- * Check if we have a fixed endpoint number, else the
- * endpoint number is allocated dynamically:
- */
- ep_no = (ed->bEndpointAddress & UE_ADDR);
- if (ep_no != 0) {
-
- /* get HW endpoint profile */
- (ues->methods->get_hw_ep_profile)
- (ues->udev, &pf, ep_no);
- if (pf == NULL) {
- /* HW profile does not exist - failure */
- DPRINTFN(0, "Endpoint profile %u "
- "does not exist\n", ep_no);
- return (1);
- }
- /* reserve fixed endpoint number */
- if (ep_type == UE_CONTROL) {
- ues->bmInAlloc[ep_no / 8] |=
- (1 << (ep_no % 8));
- ues->bmOutAlloc[ep_no / 8] |=
- (1 << (ep_no % 8));
- if ((pf->max_in_frame_size < wMaxPacketSize) ||
- (pf->max_out_frame_size < wMaxPacketSize)) {
- DPRINTFN(0, "Endpoint profile %u "
- "has too small buffer!\n", ep_no);
- return (1);
- }
- } else if (ed->bEndpointAddress & UE_DIR_IN) {
- ues->bmInAlloc[ep_no / 8] |=
- (1 << (ep_no % 8));
- if (pf->max_in_frame_size < wMaxPacketSize) {
- DPRINTFN(0, "Endpoint profile %u "
- "has too small buffer!\n", ep_no);
- return (1);
- }
- } else {
- ues->bmOutAlloc[ep_no / 8] |=
- (1 << (ep_no % 8));
- if (pf->max_out_frame_size < wMaxPacketSize) {
- DPRINTFN(0, "Endpoint profile %u "
- "has too small buffer!\n", ep_no);
- return (1);
- }
- }
- } else if (is_complete) {
-
- /* check if we have enough buffer space */
- if (wMaxPacketSize >
- ep_curr->max_frame_size) {
- return (1); /* failure */
- }
- if (ed->bEndpointAddress & UE_DIR_IN) {
- ed->bEndpointAddress =
- ep_curr->hw_endpoint_in;
- } else {
- ed->bEndpointAddress =
- ep_curr->hw_endpoint_out;
- }
-
- } else {
-
- /* compute the maximum frame size */
- if (ep_curr->max_frame_size < wMaxPacketSize) {
- ep_curr->max_frame_size = wMaxPacketSize;
- }
- if (temp == UE_CONTROL) {
- ep_curr->needs_in = 1;
- ep_curr->needs_out = 1;
- } else {
- if (ed->bEndpointAddress & UE_DIR_IN) {
- ep_curr->needs_in = 1;
- } else {
- ep_curr->needs_out = 1;
- }
- }
- ep_curr->needs_ep_type = ep_type;
- }
-
- ep_curr++;
- if (ep_max < ep_curr) {
- ep_max = ep_curr;
- }
- }
- goto repeat;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_hw_ep_resolve
- *
- * This function will try to resolve endpoint requirements by the
- * given endpoint profiles that the USB hardware reports.
- *
- * Return values:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static usb2_error_t
-usb2_hw_ep_resolve(struct usb2_device *udev,
- struct usb2_descriptor *desc)
-{
- struct usb2_hw_ep_scratch *ues;
- struct usb2_hw_ep_scratch_sub *ep;
- const struct usb2_hw_ep_profile *pf;
- struct usb2_bus_methods *methods;
- struct usb2_device_descriptor *dd;
- uint16_t mps;
-
- if (desc == NULL) {
- return (USB_ERR_INVAL);
- }
- /* get bus methods */
- methods = udev->bus->methods;
-
- if (methods->get_hw_ep_profile == NULL) {
- return (USB_ERR_INVAL);
- }
- if (desc->bDescriptorType == UDESC_DEVICE) {
-
- if (desc->bLength < sizeof(*dd)) {
- return (USB_ERR_INVAL);
- }
- dd = (void *)desc;
-
- /* get HW control endpoint 0 profile */
- (methods->get_hw_ep_profile) (udev, &pf, 0);
- if (pf == NULL) {
- return (USB_ERR_INVAL);
- }
- if (!usb2_hw_ep_match(pf, UE_CONTROL, 0)) {
- DPRINTFN(0, "Endpoint 0 does not "
- "support control\n");
- return (USB_ERR_INVAL);
- }
- mps = dd->bMaxPacketSize;
-
- if (udev->speed == USB_SPEED_FULL) {
- /*
- * We can optionally choose another packet size !
- */
- while (1) {
- /* check if "mps" is ok */
- if (pf->max_in_frame_size >= mps) {
- break;
- }
- /* reduce maximum packet size */
- mps /= 2;
-
- /* check if "mps" is too small */
- if (mps < 8) {
- return (USB_ERR_INVAL);
- }
- }
-
- dd->bMaxPacketSize = mps;
-
- } else {
- /* We only have one choice */
- if (mps == 255) {
- mps = 512;
- }
- /* Check if we support the specified wMaxPacketSize */
- if (pf->max_in_frame_size < mps) {
- return (USB_ERR_INVAL);
- }
- }
- return (0); /* success */
- }
- if (desc->bDescriptorType != UDESC_CONFIG) {
- return (USB_ERR_INVAL);
- }
- if (desc->bLength < sizeof(*(ues->cd))) {
- return (USB_ERR_INVAL);
- }
- ues = udev->bus->scratch[0].hw_ep_scratch;
-
- bzero(ues, sizeof(*ues));
-
- ues->ep_max = ues->ep;
- ues->cd = (void *)desc;
- ues->methods = methods;
- ues->udev = udev;
-
- /* Get all the endpoints we need */
-
- if (usb2_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 0) ||
- usb2_hw_ep_get_needs(ues, UE_INTERRUPT, 0) ||
- usb2_hw_ep_get_needs(ues, UE_CONTROL, 0) ||
- usb2_hw_ep_get_needs(ues, UE_BULK, 0)) {
- DPRINTFN(0, "Could not get needs\n");
- return (USB_ERR_INVAL);
- }
- for (ep = ues->ep; ep != ues->ep_max; ep++) {
-
- while (ep->needs_in || ep->needs_out) {
-
- /*
- * First try to use a simplex endpoint.
- * Then try to use a duplex endpoint.
- */
- if (usb2_hw_ep_find_match(ues, ep, 1) &&
- usb2_hw_ep_find_match(ues, ep, 0)) {
- DPRINTFN(0, "Could not find match\n");
- return (USB_ERR_INVAL);
- }
- }
- }
-
- ues->ep_max = ues->ep;
-
- /* Update all endpoint addresses */
-
- if (usb2_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 1) ||
- usb2_hw_ep_get_needs(ues, UE_INTERRUPT, 1) ||
- usb2_hw_ep_get_needs(ues, UE_CONTROL, 1) ||
- usb2_hw_ep_get_needs(ues, UE_BULK, 1)) {
- DPRINTFN(0, "Could not update endpoint address\n");
- return (USB_ERR_INVAL);
- }
- return (0); /* success */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_temp_get_tdd
- *
- * Returns:
- * NULL: No USB template device descriptor found.
- * Else: Pointer to the USB template device descriptor.
- *------------------------------------------------------------------------*/
-static const struct usb2_temp_device_desc *
-usb2_temp_get_tdd(struct usb2_device *udev)
-{
- if (udev->usb2_template_ptr == NULL) {
- return (NULL);
- }
- return (udev->usb2_template_ptr->tdd);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_temp_get_device_desc
- *
- * Returns:
- * NULL: No USB device descriptor found.
- * Else: Pointer to USB device descriptor.
- *------------------------------------------------------------------------*/
-static void *
-usb2_temp_get_device_desc(struct usb2_device *udev)
-{
- struct usb2_device_descriptor *dd;
-
- if (udev->usb2_template_ptr == NULL) {
- return (NULL);
- }
- dd = &udev->usb2_template_ptr->udd;
- if (dd->bDescriptorType != UDESC_DEVICE) {
- /* sanity check failed */
- return (NULL);
- }
- return (dd);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_temp_get_qualifier_desc
- *
- * Returns:
- * NULL: No USB device_qualifier descriptor found.
- * Else: Pointer to USB device_qualifier descriptor.
- *------------------------------------------------------------------------*/
-static void *
-usb2_temp_get_qualifier_desc(struct usb2_device *udev)
-{
- struct usb2_device_qualifier *dq;
-
- if (udev->usb2_template_ptr == NULL) {
- return (NULL);
- }
- dq = &udev->usb2_template_ptr->udq;
- if (dq->bDescriptorType != UDESC_DEVICE_QUALIFIER) {
- /* sanity check failed */
- return (NULL);
- }
- return (dq);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_temp_get_config_desc
- *
- * Returns:
- * NULL: No USB config descriptor found.
- * Else: Pointer to USB config descriptor having index "index".
- *------------------------------------------------------------------------*/
-static void *
-usb2_temp_get_config_desc(struct usb2_device *udev,
- uint16_t *pLength, uint8_t index)
-{
- struct usb2_device_descriptor *dd;
- struct usb2_config_descriptor *cd;
- uint16_t temp;
-
- if (udev->usb2_template_ptr == NULL) {
- return (NULL);
- }
- dd = &udev->usb2_template_ptr->udd;
- cd = (void *)(udev->usb2_template_ptr + 1);
-
- if (index >= dd->bNumConfigurations) {
- /* out of range */
- return (NULL);
- }
- while (index--) {
- if (cd->bDescriptorType != UDESC_CONFIG) {
- /* sanity check failed */
- return (NULL);
- }
- temp = UGETW(cd->wTotalLength);
- cd = USB_ADD_BYTES(cd, temp);
- }
-
- if (pLength) {
- *pLength = UGETW(cd->wTotalLength);
- }
- return (cd);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_temp_get_vendor_desc
- *
- * Returns:
- * NULL: No vendor descriptor found.
- * Else: Pointer to a vendor descriptor.
- *------------------------------------------------------------------------*/
-static const void *
-usb2_temp_get_vendor_desc(struct usb2_device *udev,
- const struct usb2_device_request *req)
-{
- const struct usb2_temp_device_desc *tdd;
-
- tdd = usb2_temp_get_tdd(udev);
- if (tdd == NULL) {
- return (NULL);
- }
- if (tdd->getVendorDesc == NULL) {
- return (NULL);
- }
- return ((tdd->getVendorDesc) (req));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_temp_get_string_desc
- *
- * Returns:
- * NULL: No string descriptor found.
- * Else: Pointer to a string descriptor.
- *------------------------------------------------------------------------*/
-static const void *
-usb2_temp_get_string_desc(struct usb2_device *udev,
- uint16_t lang_id, uint8_t string_index)
-{
- const struct usb2_temp_device_desc *tdd;
-
- tdd = usb2_temp_get_tdd(udev);
- if (tdd == NULL) {
- return (NULL);
- }
- if (tdd->getStringDesc == NULL) {
- return (NULL);
- }
- return ((tdd->getStringDesc) (lang_id, string_index));
-}
-
-/*------------------------------------------------------------------------*
- * usb2_temp_get_hub_desc
- *
- * Returns:
- * NULL: No USB HUB descriptor found.
- * Else: Pointer to a USB HUB descriptor.
- *------------------------------------------------------------------------*/
-static const void *
-usb2_temp_get_hub_desc(struct usb2_device *udev)
-{
- return (NULL); /* needs to be implemented */
-}
-
-/*------------------------------------------------------------------------*
- * usb2_temp_get_desc
- *
- * This function is a demultiplexer for local USB device side control
- * endpoint requests.
- *------------------------------------------------------------------------*/
-static void
-usb2_temp_get_desc(struct usb2_device *udev, struct usb2_device_request *req,
- const void **pPtr, uint16_t *pLength)
-{
- const uint8_t *buf;
- uint16_t len;
-
- buf = NULL;
- len = 0;
-
- switch (req->bmRequestType) {
- case UT_READ_DEVICE:
- switch (req->bRequest) {
- case UR_GET_DESCRIPTOR:
- goto tr_handle_get_descriptor;
- default:
- goto tr_stalled;
- }
- break;
- case UT_READ_CLASS_DEVICE:
- switch (req->bRequest) {
- case UR_GET_DESCRIPTOR:
- goto tr_handle_get_class_descriptor;
- default:
- goto tr_stalled;
- }
- break;
- case UT_READ_VENDOR_DEVICE:
- case UT_READ_VENDOR_OTHER:
- buf = usb2_temp_get_vendor_desc(udev, req);
- goto tr_valid;
- default:
- goto tr_stalled;
- }
-
-tr_handle_get_descriptor:
- switch (req->wValue[1]) {
- case UDESC_DEVICE:
- if (req->wValue[0]) {
- goto tr_stalled;
- }
- buf = usb2_temp_get_device_desc(udev);
- goto tr_valid;
- case UDESC_DEVICE_QUALIFIER:
- if (udev->speed != USB_SPEED_HIGH) {
- goto tr_stalled;
- }
- if (req->wValue[0]) {
- goto tr_stalled;
- }
- buf = usb2_temp_get_qualifier_desc(udev);
- goto tr_valid;
- case UDESC_OTHER_SPEED_CONFIGURATION:
- if (udev->speed != USB_SPEED_HIGH) {
- goto tr_stalled;
- }
- case UDESC_CONFIG:
- buf = usb2_temp_get_config_desc(udev,
- &len, req->wValue[0]);
- goto tr_valid;
- case UDESC_STRING:
- buf = usb2_temp_get_string_desc(udev,
- UGETW(req->wIndex), req->wValue[0]);
- goto tr_valid;
- default:
- goto tr_stalled;
- }
- goto tr_stalled;
-
-tr_handle_get_class_descriptor:
- if (req->wValue[0]) {
- goto tr_stalled;
- }
- buf = usb2_temp_get_hub_desc(udev);
- goto tr_valid;
-
-tr_valid:
- if (buf == NULL) {
- goto tr_stalled;
- }
- if (len == 0) {
- len = buf[0];
- }
- *pPtr = buf;
- *pLength = len;
- return;
-
-tr_stalled:
- *pPtr = NULL;
- *pLength = 0;
-}
-
-/*------------------------------------------------------------------------*
- * usb2_temp_setup
- *
- * This function generates USB descriptors according to the given USB
- * template device descriptor. It will also try to figure out the best
- * matching endpoint addresses using the hardware endpoint profiles.
- *
- * Returns:
- * 0: Success
- * Else: Failure
- *------------------------------------------------------------------------*/
-static usb2_error_t
-usb2_temp_setup(struct usb2_device *udev,
- const struct usb2_temp_device_desc *tdd)
-{
- struct usb2_temp_setup *uts;
- void *buf;
- uint8_t n;
-
- if (tdd == NULL) {
- /* be NULL safe */
- return (0);
- }
- uts = udev->bus->scratch[0].temp_setup;
-
- bzero(uts, sizeof(*uts));
-
- uts->usb2_speed = udev->speed;
- uts->self_powered = udev->flags.self_powered;
-
- /* first pass */
-
- usb2_make_device_desc(uts, tdd);
-
- if (uts->err) {
- /* some error happened */
- return (uts->err);
- }
- /* sanity check */
- if (uts->size == 0) {
- return (USB_ERR_INVAL);
- }
- /* allocate zeroed memory */
- uts->buf = malloc(uts->size, M_USB, M_WAITOK | M_ZERO);
- if (uts->buf == NULL) {
- /* could not allocate memory */
- return (USB_ERR_NOMEM);
- }
- /* second pass */
-
- uts->size = 0;
-
- usb2_make_device_desc(uts, tdd);
-
- /*
- * Store a pointer to our descriptors:
- */
- udev->usb2_template_ptr = uts->buf;
-
- if (uts->err) {
- /* some error happened during second pass */
- goto error;
- }
- /*
- * Resolve all endpoint addresses !
- */
- buf = usb2_temp_get_device_desc(udev);
- uts->err = usb2_hw_ep_resolve(udev, buf);
- if (uts->err) {
- DPRINTFN(0, "Could not resolve endpoints for "
- "Device Descriptor, error = %s\n",
- usb2_errstr(uts->err));
- goto error;
- }
- for (n = 0;; n++) {
-
- buf = usb2_temp_get_config_desc(udev, NULL, n);
- if (buf == NULL) {
- break;
- }
- uts->err = usb2_hw_ep_resolve(udev, buf);
- if (uts->err) {
- DPRINTFN(0, "Could not resolve endpoints for "
- "Config Descriptor %u, error = %s\n", n,
- usb2_errstr(uts->err));
- goto error;
- }
- }
- return (uts->err);
-
-error:
- usb2_temp_unsetup(udev);
- return (uts->err);
-}
-
-/*------------------------------------------------------------------------*
- * usb2_temp_unsetup
- *
- * This function frees any memory associated with the currently
- * setup template, if any.
- *------------------------------------------------------------------------*/
-static void
-usb2_temp_unsetup(struct usb2_device *udev)
-{
- if (udev->usb2_template_ptr) {
-
- free(udev->usb2_template_ptr, M_USB);
-
- udev->usb2_template_ptr = NULL;
- }
-}
-
-static usb2_error_t
-usb2_temp_setup_by_index(struct usb2_device *udev, uint16_t index)
-{
- usb2_error_t err;
-
- switch (index) {
- case 0:
- err = usb2_temp_setup(udev, &usb2_template_msc);
- break;
- case 1:
- err = usb2_temp_setup(udev, &usb2_template_cdce);
- break;
- case 2:
- err = usb2_temp_setup(udev, &usb2_template_mtp);
- break;
- default:
- return (USB_ERR_INVAL);
- }
-
- return (err);
-}
-
-static void
-usb2_temp_init(void *arg)
-{
- /* register our functions */
- usb2_temp_get_desc_p = &usb2_temp_get_desc;
- usb2_temp_setup_by_index_p = &usb2_temp_setup_by_index;
- usb2_temp_unsetup_p = &usb2_temp_unsetup;
-}
-
-SYSINIT(usb2_temp_init, SI_SUB_LOCK, SI_ORDER_FIRST, usb2_temp_init, NULL);
-SYSUNINIT(usb2_temp_unload, SI_SUB_LOCK, SI_ORDER_ANY, usb2_temp_unload, NULL);
diff --git a/sys/dev/usb2/template/usb2_template.h b/sys/dev/usb2/template/usb2_template.h
deleted file mode 100644
index 361de3a..0000000
--- a/sys/dev/usb2/template/usb2_template.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2007 Hans Petter Selasky <hselasky@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.
- */
-
-/* USB templates are used to build up real USB descriptors */
-
-#ifndef _USB_TEMPLATE_H_
-#define _USB_TEMPLATE_H_
-
-typedef const void *(usb2_temp_get_string_desc_t)(uint16_t lang_id, uint8_t string_index);
-typedef const void *(usb2_temp_get_vendor_desc_t)(const struct usb2_device_request *req);
-
-struct usb2_temp_packet_size {
- uint16_t mps[USB_SPEED_MAX];
-};
-
-struct usb2_temp_interval {
- uint8_t bInterval[USB_SPEED_MAX];
-};
-
-struct usb2_temp_endpoint_desc {
- const void **ppRawDesc;
- const struct usb2_temp_packet_size *pPacketSize;
- const struct usb2_temp_interval *pIntervals;
- /*
- * If (bEndpointAddress & UE_ADDR) is non-zero the endpoint number
- * is pre-selected for this endpoint descriptor. Else an endpoint
- * number is automatically chosen.
- */
- uint8_t bEndpointAddress; /* UE_DIR_IN or UE_DIR_OUT */
- uint8_t bmAttributes;
-};
-
-struct usb2_temp_interface_desc {
- const void **ppRawDesc;
- const struct usb2_temp_endpoint_desc **ppEndpoints;
- uint8_t bInterfaceClass;
- uint8_t bInterfaceSubClass;
- uint8_t bInterfaceProtocol;
- uint8_t iInterface;
- uint8_t isAltInterface;
-};
-
-struct usb2_temp_config_desc {
- const struct usb2_temp_interface_desc **ppIfaceDesc;
- uint8_t bmAttributes;
- uint8_t bMaxPower;
- uint8_t iConfiguration;
-};
-
-struct usb2_temp_device_desc {
- usb2_temp_get_string_desc_t *getStringDesc;
- usb2_temp_get_vendor_desc_t *getVendorDesc;
- const struct usb2_temp_config_desc **ppConfigDesc;
- uint16_t idVendor;
- uint16_t idProduct;
- uint16_t bcdDevice;
- uint8_t bDeviceClass;
- uint8_t bDeviceSubClass;
- uint8_t bDeviceProtocol;
- uint8_t iManufacturer;
- uint8_t iProduct;
- uint8_t iSerialNumber;
-};
-
-struct usb2_temp_data {
- const struct usb2_temp_device_desc *tdd;
- struct usb2_device_descriptor udd; /* device descriptor */
- struct usb2_device_qualifier udq; /* device qualifier */
-};
-
-/* prototypes */
-
-extern const struct usb2_temp_device_desc usb2_template_cdce;
-extern const struct usb2_temp_device_desc usb2_template_msc; /* Mass Storage Class */
-extern const struct usb2_temp_device_desc usb2_template_mtp; /* Message Transfer
- * Protocol */
-
-#endif /* _USB_TEMPLATE_H_ */
diff --git a/sys/dev/usb2/template/usb2_template_cdce.c b/sys/dev/usb2/template/usb2_template_cdce.c
deleted file mode 100644
index bc123df..0000000
--- a/sys/dev/usb2/template/usb2_template_cdce.c
+++ /dev/null
@@ -1,292 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2007 Hans Petter Selasky <hselasky@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.
- */
-
-/*
- * This file contains the USB templates for a CDC USB ethernet device.
- */
-
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_cdc.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-
-#include <dev/usb2/core/usb2_core.h>
-
-#include <dev/usb2/template/usb2_template.h>
-
-enum {
- STRING_LANG_INDEX,
- STRING_MAC_INDEX,
- STRING_ETH_CONTROL_INDEX,
- STRING_ETH_DATA_INDEX,
- STRING_ETH_CONFIG_INDEX,
- STRING_ETH_VENDOR_INDEX,
- STRING_ETH_PRODUCT_INDEX,
- STRING_ETH_SERIAL_INDEX,
- STRING_ETH_MAX,
-};
-
-#define STRING_LANG \
- 0x09, 0x04, /* American English */
-
-#define STRING_MAC \
- '2', 0, 'A', 0, '2', 0, '3', 0, \
- '4', 0, '5', 0, '6', 0, '7', 0, \
- '8', 0, '9', 0, 'A', 0, 'B', 0,
-
-#define STRING_ETH_CONTROL \
- 'U', 0, 'S', 0, 'B', 0, ' ', 0, \
- 'E', 0, 't', 0, 'h', 0, 'e', 0, \
- 'r', 0, 'n', 0, 'e', 0, 't', 0, \
- ' ', 0, 'C', 0, 'o', 0, 'm', 0, \
- 'm', 0, ' ', 0, 'i', 0, 'n', 0, \
- 't', 0, 'e', 0, 'r', 0, 'f', 0, \
- 'a', 0, 'c', 0, 'e', 0,
-
-#define STRING_ETH_DATA \
- 'U', 0, 'S', 0, 'B', 0, ' ', 0, \
- 'E', 0, 't', 0, 'h', 0, 'e', 0, \
- 'r', 0, 'n', 0, 'e', 0, 't', 0, \
- ' ', 0, 'D', 0, 'a', 0, 't', 0, \
- 'a', 0, ' ', 0, 'i', 0, 'n', 0, \
- 't', 0, 'e', 0, 'r', 0, 'f', 0, \
- 'a', 0, 'c', 0, 'e', 0,
-
-#define STRING_ETH_CONFIG \
- 'D', 0, 'e', 0, 'f', 0, 'a', 0, \
- 'u', 0, 'l', 0, 't', 0, ' ', 0, \
- 'c', 0, 'o', 0, 'n', 0, 'f', 0, \
- 'i', 0, 'g', 0,
-
-#define STRING_ETH_VENDOR \
- 'F', 0, 'r', 0, 'e', 0, 'e', 0, \
- 'B', 0, 'S', 0, 'D', 0, ' ', 0, \
- 'f', 0, 'o', 0, 'u', 0, 'n', 0, \
- 'd', 0, 'a', 0, 't', 0, 'i', 0, \
- 'o', 0, 'n', 0,
-
-#define STRING_ETH_PRODUCT \
- 'U', 0, 'S', 0, 'B', 0, ' ', 0, \
- 'E', 0, 't', 0, 'h', 0, 'e', 0, \
- 'r', 0, 'n', 0, 'e', 0, 't', 0, \
- ' ', 0, 'A', 0, 'd', 0, 'a', 0, \
- 'p', 0, 't', 0, 'e', 0, 'r', 0,
-
-#define STRING_ETH_SERIAL \
- 'D', 0, 'e', 0, 'c', 0, 'e', 0, \
- 'm', 0, 'b', 0, 'e', 0, 'r', 0, \
- ' ', 0, '2', 0, '0', 0, '0', 0, \
- '7', 0,
-
-/* make the real string descriptors */
-
-USB_MAKE_STRING_DESC(STRING_LANG, string_lang);
-USB_MAKE_STRING_DESC(STRING_MAC, string_mac);
-USB_MAKE_STRING_DESC(STRING_ETH_CONTROL, string_eth_control);
-USB_MAKE_STRING_DESC(STRING_ETH_DATA, string_eth_data);
-USB_MAKE_STRING_DESC(STRING_ETH_CONFIG, string_eth_config);
-USB_MAKE_STRING_DESC(STRING_ETH_VENDOR, string_eth_vendor);
-USB_MAKE_STRING_DESC(STRING_ETH_PRODUCT, string_eth_product);
-USB_MAKE_STRING_DESC(STRING_ETH_SERIAL, string_eth_serial);
-
-/* prototypes */
-
-static usb2_temp_get_string_desc_t eth_get_string_desc;
-
-static const struct usb2_cdc_union_descriptor eth_union_desc = {
- .bLength = sizeof(eth_union_desc),
- .bDescriptorType = UDESC_CS_INTERFACE,
- .bDescriptorSubtype = UDESCSUB_CDC_UNION,
- .bMasterInterface = 0, /* this is automatically updated */
- .bSlaveInterface[0] = 1, /* this is automatically updated */
-};
-
-static const struct usb2_cdc_header_descriptor eth_header_desc = {
- .bLength = sizeof(eth_header_desc),
- .bDescriptorType = UDESC_CS_INTERFACE,
- .bDescriptorSubtype = UDESCSUB_CDC_HEADER,
- .bcdCDC[0] = 0x10,
- .bcdCDC[1] = 0x01,
-};
-
-static const struct usb2_cdc_ethernet_descriptor eth_enf_desc = {
- .bLength = sizeof(eth_enf_desc),
- .bDescriptorType = UDESC_CS_INTERFACE,
- .bDescriptorSubtype = UDESCSUB_CDC_ENF,
- .iMacAddress = STRING_MAC_INDEX,
- .bmEthernetStatistics = {0, 0, 0, 0},
- .wMaxSegmentSize = {0xEA, 0x05},/* 1514 bytes */
- .wNumberMCFilters = {0, 0},
- .bNumberPowerFilters = 0,
-};
-
-static const void *eth_control_if_desc[] = {
- &eth_union_desc,
- &eth_header_desc,
- &eth_enf_desc,
- NULL,
-};
-
-static const struct usb2_temp_packet_size bulk_mps = {
- .mps[USB_SPEED_FULL] = 64,
- .mps[USB_SPEED_HIGH] = 512,
-};
-
-static const struct usb2_temp_packet_size intr_mps = {
- .mps[USB_SPEED_FULL] = 8,
- .mps[USB_SPEED_HIGH] = 8,
-};
-
-static const struct usb2_temp_endpoint_desc bulk_in_ep = {
- .pPacketSize = &bulk_mps,
-#ifdef USB_HIP_IN_EP_0
- .bEndpointAddress = USB_HIP_IN_EP_0,
-#else
- .bEndpointAddress = UE_DIR_IN,
-#endif
- .bmAttributes = UE_BULK,
-};
-
-static const struct usb2_temp_endpoint_desc bulk_out_ep = {
- .pPacketSize = &bulk_mps,
-#ifdef USB_HIP_OUT_EP_0
- .bEndpointAddress = USB_HIP_OUT_EP_0,
-#else
- .bEndpointAddress = UE_DIR_OUT,
-#endif
- .bmAttributes = UE_BULK,
-};
-
-static const struct usb2_temp_endpoint_desc intr_in_ep = {
- .pPacketSize = &intr_mps,
- .bEndpointAddress = UE_DIR_IN,
- .bmAttributes = UE_INTERRUPT,
-};
-
-static const struct usb2_temp_endpoint_desc *eth_intr_endpoints[] = {
- &intr_in_ep,
- NULL,
-};
-
-static const struct usb2_temp_interface_desc eth_control_interface = {
- .ppEndpoints = eth_intr_endpoints,
- .ppRawDesc = eth_control_if_desc,
- .bInterfaceClass = UICLASS_CDC,
- .bInterfaceSubClass = UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL,
- .bInterfaceProtocol = 0,
- .iInterface = STRING_ETH_CONTROL_INDEX,
-};
-
-static const struct usb2_temp_endpoint_desc *eth_data_endpoints[] = {
- &bulk_in_ep,
- &bulk_out_ep,
- NULL,
-};
-
-static const struct usb2_temp_interface_desc eth_data_null_interface = {
- .ppEndpoints = NULL, /* no endpoints */
- .bInterfaceClass = UICLASS_CDC_DATA,
- .bInterfaceSubClass = 0,
- .bInterfaceProtocol = 0,
- .iInterface = STRING_ETH_DATA_INDEX,
-};
-
-static const struct usb2_temp_interface_desc eth_data_interface = {
- .ppEndpoints = eth_data_endpoints,
- .bInterfaceClass = UICLASS_CDC_DATA,
- .bInterfaceSubClass = UISUBCLASS_DATA,
- .bInterfaceProtocol = 0,
- .iInterface = STRING_ETH_DATA_INDEX,
- .isAltInterface = 1, /* this is an alternate setting */
-};
-
-static const struct usb2_temp_interface_desc *eth_interfaces[] = {
- &eth_control_interface,
- &eth_data_null_interface,
- &eth_data_interface,
- NULL,
-};
-
-static const struct usb2_temp_config_desc eth_config_desc = {
- .ppIfaceDesc = eth_interfaces,
- .bmAttributes = UC_BUS_POWERED,
- .bMaxPower = 25, /* 50 mA */
- .iConfiguration = STRING_ETH_CONFIG_INDEX,
-};
-
-static const struct usb2_temp_config_desc *eth_configs[] = {
- &eth_config_desc,
- NULL,
-};
-
-const struct usb2_temp_device_desc usb2_template_cdce = {
- .getStringDesc = &eth_get_string_desc,
- .ppConfigDesc = eth_configs,
- .idVendor = 0x0001,
- .idProduct = 0x0001,
- .bcdDevice = 0x0100,
- .bDeviceClass = UDCLASS_COMM,
- .bDeviceSubClass = 0,
- .bDeviceProtocol = 0,
- .iManufacturer = STRING_ETH_VENDOR_INDEX,
- .iProduct = STRING_ETH_PRODUCT_INDEX,
- .iSerialNumber = STRING_ETH_SERIAL_INDEX,
-};
-
-/*------------------------------------------------------------------------*
- * eth_get_string_desc
- *
- * Return values:
- * NULL: Failure. No such string.
- * Else: Success. Pointer to string descriptor is returned.
- *------------------------------------------------------------------------*/
-static const void *
-eth_get_string_desc(uint16_t lang_id, uint8_t string_index)
-{
- static const void *ptr[STRING_ETH_MAX] = {
- [STRING_LANG_INDEX] = &string_lang,
- [STRING_MAC_INDEX] = &string_mac,
- [STRING_ETH_CONTROL_INDEX] = &string_eth_control,
- [STRING_ETH_DATA_INDEX] = &string_eth_data,
- [STRING_ETH_CONFIG_INDEX] = &string_eth_config,
- [STRING_ETH_VENDOR_INDEX] = &string_eth_vendor,
- [STRING_ETH_PRODUCT_INDEX] = &string_eth_product,
- [STRING_ETH_SERIAL_INDEX] = &string_eth_serial,
- };
-
- if (string_index == 0) {
- return (&string_lang);
- }
- if (lang_id != 0x0409) {
- return (NULL);
- }
- if (string_index < STRING_ETH_MAX) {
- return (ptr[string_index]);
- }
- return (NULL);
-}
diff --git a/sys/dev/usb2/template/usb2_template_msc.c b/sys/dev/usb2/template/usb2_template_msc.c
deleted file mode 100644
index b8bc7ad..0000000
--- a/sys/dev/usb2/template/usb2_template_msc.c
+++ /dev/null
@@ -1,199 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2008 Hans Petter Selasky <hselasky@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.
- */
-
-/*
- * This file contains the USB templates for an USB Mass Storage Device.
- */
-
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-
-#include <dev/usb2/core/usb2_core.h>
-
-#include <dev/usb2/template/usb2_template.h>
-
-enum {
- STRING_LANG_INDEX,
- STRING_MSC_DATA_INDEX,
- STRING_MSC_CONFIG_INDEX,
- STRING_MSC_VENDOR_INDEX,
- STRING_MSC_PRODUCT_INDEX,
- STRING_MSC_SERIAL_INDEX,
- STRING_MSC_MAX,
-};
-
-#define STRING_LANG \
- 0x09, 0x04, /* American English */
-
-#define STRING_MSC_DATA \
- 'U', 0, 'S', 0, 'B', 0, ' ', 0, \
- 'M', 0, 'a', 0, 's', 0, 's', 0, \
- ' ', 0, 'S', 0, 't', 0, 'o', 0, \
- 'r', 0, 'a', 0, 'g', 0, 'e', 0, \
- ' ', 0, 'I', 0, 'n', 0, 't', 0, \
- 'e', 0, 'r', 0, 'f', 0, 'a', 0, \
- 'c', 0, 'e', 0,
-
-#define STRING_MSC_CONFIG \
- 'D', 0, 'e', 0, 'f', 0, 'a', 0, \
- 'u', 0, 'l', 0, 't', 0, ' ', 0, \
- 'c', 0, 'o', 0, 'n', 0, 'f', 0, \
- 'i', 0, 'g', 0,
-
-#define STRING_MSC_VENDOR \
- 'F', 0, 'r', 0, 'e', 0, 'e', 0, \
- 'B', 0, 'S', 0, 'D', 0, ' ', 0, \
- 'f', 0, 'o', 0, 'u', 0, 'n', 0, \
- 'd', 0, 'a', 0, 't', 0, 'i', 0, \
- 'o', 0, 'n', 0,
-
-#define STRING_MSC_PRODUCT \
- 'U', 0, 'S', 0, 'B', 0, ' ', 0, \
- 'M', 0, 'e', 0, 'm', 0, 'o', 0, \
- 'r', 0, 'y', 0, ' ', 0, 'S', 0, \
- 't', 0, 'i', 0, 'c', 0, 'k', 0
-
-#define STRING_MSC_SERIAL \
- 'M', 0, 'a', 0, 'r', 0, 'c', 0, \
- 'h', 0, ' ', 0, '2', 0, '0', 0, \
- '0', 0, '8', 0,
-
-/* make the real string descriptors */
-
-USB_MAKE_STRING_DESC(STRING_LANG, string_lang);
-USB_MAKE_STRING_DESC(STRING_MSC_DATA, string_msc_data);
-USB_MAKE_STRING_DESC(STRING_MSC_CONFIG, string_msc_config);
-USB_MAKE_STRING_DESC(STRING_MSC_VENDOR, string_msc_vendor);
-USB_MAKE_STRING_DESC(STRING_MSC_PRODUCT, string_msc_product);
-USB_MAKE_STRING_DESC(STRING_MSC_SERIAL, string_msc_serial);
-
-/* prototypes */
-
-static usb2_temp_get_string_desc_t msc_get_string_desc;
-
-static const struct usb2_temp_packet_size bulk_mps = {
- .mps[USB_SPEED_FULL] = 64,
- .mps[USB_SPEED_HIGH] = 512,
-};
-
-static const struct usb2_temp_endpoint_desc bulk_in_ep = {
- .pPacketSize = &bulk_mps,
-#ifdef USB_HIP_IN_EP_0
- .bEndpointAddress = USB_HIP_IN_EP_0,
-#else
- .bEndpointAddress = UE_DIR_IN,
-#endif
- .bmAttributes = UE_BULK,
-};
-
-static const struct usb2_temp_endpoint_desc bulk_out_ep = {
- .pPacketSize = &bulk_mps,
-#ifdef USB_HIP_OUT_EP_0
- .bEndpointAddress = USB_HIP_OUT_EP_0,
-#else
- .bEndpointAddress = UE_DIR_OUT,
-#endif
- .bmAttributes = UE_BULK,
-};
-
-static const struct usb2_temp_endpoint_desc *msc_data_endpoints[] = {
- &bulk_in_ep,
- &bulk_out_ep,
- NULL,
-};
-
-static const struct usb2_temp_interface_desc msc_data_interface = {
- .ppEndpoints = msc_data_endpoints,
- .bInterfaceClass = UICLASS_MASS,
- .bInterfaceSubClass = UISUBCLASS_SCSI,
- .bInterfaceProtocol = UIPROTO_MASS_BBB,
- .iInterface = STRING_MSC_DATA_INDEX,
-};
-
-static const struct usb2_temp_interface_desc *msc_interfaces[] = {
- &msc_data_interface,
- NULL,
-};
-
-static const struct usb2_temp_config_desc msc_config_desc = {
- .ppIfaceDesc = msc_interfaces,
- .bmAttributes = UC_BUS_POWERED,
- .bMaxPower = 25, /* 50 mA */
- .iConfiguration = STRING_MSC_CONFIG_INDEX,
-};
-
-static const struct usb2_temp_config_desc *msc_configs[] = {
- &msc_config_desc,
- NULL,
-};
-
-const struct usb2_temp_device_desc usb2_template_msc = {
- .getStringDesc = &msc_get_string_desc,
- .ppConfigDesc = msc_configs,
- .idVendor = 0x0001,
- .idProduct = 0x0001,
- .bcdDevice = 0x0100,
- .bDeviceClass = UDCLASS_COMM,
- .bDeviceSubClass = 0,
- .bDeviceProtocol = 0,
- .iManufacturer = STRING_MSC_VENDOR_INDEX,
- .iProduct = STRING_MSC_PRODUCT_INDEX,
- .iSerialNumber = STRING_MSC_SERIAL_INDEX,
-};
-
-/*------------------------------------------------------------------------*
- * msc_get_string_desc
- *
- * Return values:
- * NULL: Failure. No such string.
- * Else: Success. Pointer to string descriptor is returned.
- *------------------------------------------------------------------------*/
-static const void *
-msc_get_string_desc(uint16_t lang_id, uint8_t string_index)
-{
- static const void *ptr[STRING_MSC_MAX] = {
- [STRING_LANG_INDEX] = &string_lang,
- [STRING_MSC_DATA_INDEX] = &string_msc_data,
- [STRING_MSC_CONFIG_INDEX] = &string_msc_config,
- [STRING_MSC_VENDOR_INDEX] = &string_msc_vendor,
- [STRING_MSC_PRODUCT_INDEX] = &string_msc_product,
- [STRING_MSC_SERIAL_INDEX] = &string_msc_serial,
- };
-
- if (string_index == 0) {
- return (&string_lang);
- }
- if (lang_id != 0x0409) {
- return (NULL);
- }
- if (string_index < STRING_MSC_MAX) {
- return (ptr[string_index]);
- }
- return (NULL);
-}
diff --git a/sys/dev/usb2/template/usb2_template_mtp.c b/sys/dev/usb2/template/usb2_template_mtp.c
deleted file mode 100644
index f1599fc..0000000
--- a/sys/dev/usb2/template/usb2_template_mtp.c
+++ /dev/null
@@ -1,262 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2008 Hans Petter Selasky <hselasky@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.
- */
-
-/*
- * This file contains the USB templates for an USB Message Transfer
- * Protocol device.
- *
- * NOTE: It is common practice that MTP devices use some dummy
- * descriptor cludges to be automatically detected by the host
- * operating system. These descriptors are documented in the LibMTP
- * library at sourceforge.net. The alternative is to supply the host
- * operating system the VID and PID of your device.
- */
-
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-
-#include <dev/usb2/core/usb2_core.h>
-
-#include <dev/usb2/template/usb2_template.h>
-
-#define MTP_BREQUEST 0x08
-
-enum {
- STRING_LANG_INDEX,
- STRING_MTP_DATA_INDEX,
- STRING_MTP_CONFIG_INDEX,
- STRING_MTP_VENDOR_INDEX,
- STRING_MTP_PRODUCT_INDEX,
- STRING_MTP_SERIAL_INDEX,
- STRING_MTP_MAX,
-};
-
-#define STRING_LANG \
- 0x09, 0x04, /* American English */
-
-#define STRING_MTP_DATA \
- 'U', 0, 'S', 0, 'B', 0, ' ', 0, \
- 'M', 0, 'T', 0, 'P', 0, \
- ' ', 0, 'I', 0, 'n', 0, 't', 0, \
- 'e', 0, 'r', 0, 'f', 0, 'a', 0, \
- 'c', 0, 'e', 0,
-
-#define STRING_MTP_CONFIG \
- 'D', 0, 'e', 0, 'f', 0, 'a', 0, \
- 'u', 0, 'l', 0, 't', 0, ' ', 0, \
- 'c', 0, 'o', 0, 'n', 0, 'f', 0, \
- 'i', 0, 'g', 0,
-
-#define STRING_MTP_VENDOR \
- 'F', 0, 'r', 0, 'e', 0, 'e', 0, \
- 'B', 0, 'S', 0, 'D', 0, ' ', 0, \
- 'f', 0, 'o', 0, 'u', 0, 'n', 0, \
- 'd', 0, 'a', 0, 't', 0, 'i', 0, \
- 'o', 0, 'n', 0,
-
-#define STRING_MTP_PRODUCT \
- 'U', 0, 'S', 0, 'B', 0, ' ', 0, \
- 'M', 0, 'T', 0, 'P', 0,
-
-#define STRING_MTP_SERIAL \
- 'J', 0, 'u', 0, 'n', 0, 'e', 0, \
- ' ', 0, '2', 0, '0', 0, '0', 0, \
- '8', 0,
-
-/* make the real string descriptors */
-
-USB_MAKE_STRING_DESC(STRING_LANG, string_lang);
-USB_MAKE_STRING_DESC(STRING_MTP_DATA, string_mtp_data);
-USB_MAKE_STRING_DESC(STRING_MTP_CONFIG, string_mtp_config);
-USB_MAKE_STRING_DESC(STRING_MTP_VENDOR, string_mtp_vendor);
-USB_MAKE_STRING_DESC(STRING_MTP_PRODUCT, string_mtp_product);
-USB_MAKE_STRING_DESC(STRING_MTP_SERIAL, string_mtp_serial);
-
-/* prototypes */
-
-static usb2_temp_get_string_desc_t mtp_get_string_desc;
-static usb2_temp_get_vendor_desc_t mtp_get_vendor_desc;
-
-static const struct usb2_temp_packet_size bulk_mps = {
- .mps[USB_SPEED_FULL] = 64,
- .mps[USB_SPEED_HIGH] = 512,
-};
-
-static const struct usb2_temp_packet_size intr_mps = {
- .mps[USB_SPEED_FULL] = 64,
- .mps[USB_SPEED_HIGH] = 64,
-};
-
-static const struct usb2_temp_endpoint_desc bulk_out_ep = {
- .pPacketSize = &bulk_mps,
-#ifdef USB_HIP_OUT_EP_0
- .bEndpointAddress = USB_HIP_OUT_EP_0,
-#else
- .bEndpointAddress = UE_DIR_OUT,
-#endif
- .bmAttributes = UE_BULK,
-};
-
-static const struct usb2_temp_endpoint_desc intr_in_ep = {
- .pPacketSize = &intr_mps,
- .bEndpointAddress = UE_DIR_IN,
- .bmAttributes = UE_INTERRUPT,
-};
-
-static const struct usb2_temp_endpoint_desc bulk_in_ep = {
- .pPacketSize = &bulk_mps,
-#ifdef USB_HIP_IN_EP_0
- .bEndpointAddress = USB_HIP_IN_EP_0,
-#else
- .bEndpointAddress = UE_DIR_IN,
-#endif
- .bmAttributes = UE_BULK,
-};
-
-static const struct usb2_temp_endpoint_desc *mtp_data_endpoints[] = {
- &bulk_in_ep,
- &bulk_out_ep,
- &intr_in_ep,
- NULL,
-};
-
-static const struct usb2_temp_interface_desc mtp_data_interface = {
- .ppEndpoints = mtp_data_endpoints,
- .bInterfaceClass = UICLASS_IMAGE,
- .bInterfaceSubClass = UISUBCLASS_SIC, /* Still Image Class */
- .bInterfaceProtocol = 1, /* PIMA 15740 */
- .iInterface = STRING_MTP_DATA_INDEX,
-};
-
-static const struct usb2_temp_interface_desc *mtp_interfaces[] = {
- &mtp_data_interface,
- NULL,
-};
-
-static const struct usb2_temp_config_desc mtp_config_desc = {
- .ppIfaceDesc = mtp_interfaces,
- .bmAttributes = UC_BUS_POWERED,
- .bMaxPower = 25, /* 50 mA */
- .iConfiguration = STRING_MTP_CONFIG_INDEX,
-};
-
-static const struct usb2_temp_config_desc *mtp_configs[] = {
- &mtp_config_desc,
- NULL,
-};
-
-const struct usb2_temp_device_desc usb2_template_mtp = {
- .getStringDesc = &mtp_get_string_desc,
- .getVendorDesc = &mtp_get_vendor_desc,
- .ppConfigDesc = mtp_configs,
- .idVendor = 0x0001,
- .idProduct = 0x0001,
- .bcdDevice = 0x0100,
- .bDeviceClass = 0,
- .bDeviceSubClass = 0,
- .bDeviceProtocol = 0,
- .iManufacturer = STRING_MTP_VENDOR_INDEX,
- .iProduct = STRING_MTP_PRODUCT_INDEX,
- .iSerialNumber = STRING_MTP_SERIAL_INDEX,
-};
-
-/*------------------------------------------------------------------------*
- * mtp_get_vendor_desc
- *
- * Return values:
- * NULL: Failure. No such vendor descriptor.
- * Else: Success. Pointer to vendor descriptor is returned.
- *------------------------------------------------------------------------*/
-static const void *
-mtp_get_vendor_desc(const struct usb2_device_request *req)
-{
- static const uint8_t dummy_desc[0x28] = {
- 0x28, 0, 0, 0, 0, 1, 4, 0,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 0x4D, 0x54, 0x50, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- };
-
- if ((req->bmRequestType == UT_READ_VENDOR_DEVICE) &&
- (req->bRequest == MTP_BREQUEST) && (req->wValue[0] == 0) &&
- (req->wValue[1] == 0) && (req->wIndex[1] == 0) &&
- ((req->wIndex[0] == 4) || (req->wIndex[0] == 5))) {
- /*
- * By returning this descriptor LibMTP will
- * automatically pickup our device.
- */
- return (dummy_desc);
- }
- return (NULL);
-}
-
-/*------------------------------------------------------------------------*
- * mtp_get_string_desc
- *
- * Return values:
- * NULL: Failure. No such string.
- * Else: Success. Pointer to string descriptor is returned.
- *------------------------------------------------------------------------*/
-static const void *
-mtp_get_string_desc(uint16_t lang_id, uint8_t string_index)
-{
- static const void *ptr[STRING_MTP_MAX] = {
- [STRING_LANG_INDEX] = &string_lang,
- [STRING_MTP_DATA_INDEX] = &string_mtp_data,
- [STRING_MTP_CONFIG_INDEX] = &string_mtp_config,
- [STRING_MTP_VENDOR_INDEX] = &string_mtp_vendor,
- [STRING_MTP_PRODUCT_INDEX] = &string_mtp_product,
- [STRING_MTP_SERIAL_INDEX] = &string_mtp_serial,
- };
-
- static const uint8_t dummy_desc[0x12] = {
- 0x12, 0x03, 0x4D, 0x00, 0x53, 0x00, 0x46, 0x00,
- 0x54, 0x00, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00,
- MTP_BREQUEST, 0x00,
- };
-
- if (string_index == 0xEE) {
- /*
- * By returning this string LibMTP will automatically
- * pickup our device.
- */
- return (dummy_desc);
- }
- if (string_index == 0) {
- return (&string_lang);
- }
- if (lang_id != 0x0409) {
- return (NULL);
- }
- if (string_index < STRING_MTP_MAX) {
- return (ptr[string_index]);
- }
- return (NULL);
-}
diff --git a/sys/dev/usb2/wlan/if_rum2.c b/sys/dev/usb2/wlan/if_rum2.c
deleted file mode 100644
index 6b702fa..0000000
--- a/sys/dev/usb2/wlan/if_rum2.c
+++ /dev/null
@@ -1,2436 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr>
- * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
- * Copyright (c) 2007-2008 Hans Petter Selasky <hselasky@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$");
-
-/*-
- * Ralink Technology RT2501USB/RT2601USB chipset driver
- * http://www.ralinktech.com.tw/
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR rum_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/wlan/usb2_wlan.h>
-#include <dev/usb2/wlan/if_rumreg.h>
-#include <dev/usb2/wlan/if_rumvar.h>
-#include <dev/usb2/wlan/if_rumfw.h>
-
-#if USB_DEBUG
-static int rum_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum");
-SYSCTL_INT(_hw_usb2_rum, OID_AUTO, debug, CTLFLAG_RW, &rum_debug, 0,
- "Debug level");
-#endif
-
-#define rum_do_request(sc,req,data) \
- usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000)
-
-static const struct usb2_device_id rum_devs[] = {
- { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM) },
- { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2) },
- { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3) },
- { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4) },
- { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700) },
- { USB_VP(USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GO) },
- { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_1) },
- { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_2) },
- { USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A) },
- { USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3) },
- { USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GC) },
- { USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GR) },
- { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU2) },
- { USB_VP(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GL) },
- { USB_VP(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GPX) },
- { USB_VP(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F) },
- { USB_VP(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573) },
- { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1) },
- { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340) },
- { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA111) },
- { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA110) },
- { USB_VP(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS) },
- { USB_VP(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWI05GS) },
- { USB_VP(USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573) },
- { USB_VP(USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573) },
- { USB_VP(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254LB) },
- { USB_VP(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP) },
- { USB_VP(USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G) },
- { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP) },
- { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP) },
- { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1) },
- { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2) },
- { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3) },
- { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_4) },
- { USB_VP(USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RT2573) },
- { USB_VP(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP) },
- { USB_VP(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54MINI2) },
- { USB_VP(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM) },
- { USB_VP(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573) },
- { USB_VP(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2) },
- { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573) },
- { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573_2) },
- { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671) },
- { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2) },
- { USB_VP(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172) },
- { USB_VP(USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2573) },
- { USB_VP(USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573) },
-};
-
-MODULE_DEPEND(rum, wlan, 1, 1, 1);
-MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1);
-MODULE_DEPEND(rum, usb2_wlan, 1, 1, 1);
-MODULE_DEPEND(rum, usb2_core, 1, 1, 1);
-
-static device_probe_t rum_match;
-static device_attach_t rum_attach;
-static device_detach_t rum_detach;
-
-static usb2_callback_t rum_bulk_read_callback;
-static usb2_callback_t rum_bulk_write_callback;
-
-static usb2_proc_callback_t rum_attach_post;
-static usb2_proc_callback_t rum_task;
-static usb2_proc_callback_t rum_scantask;
-static usb2_proc_callback_t rum_promisctask;
-static usb2_proc_callback_t rum_amrr_task;
-static usb2_proc_callback_t rum_init_task;
-static usb2_proc_callback_t rum_stop_task;
-
-static struct ieee80211vap *rum_vap_create(struct ieee80211com *,
- const char name[IFNAMSIZ], int unit, int opmode,
- int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void rum_vap_delete(struct ieee80211vap *);
-static void rum_tx_free(struct rum_tx_data *, int);
-static void rum_setup_tx_list(struct rum_softc *);
-static void rum_unsetup_tx_list(struct rum_softc *);
-static int rum_newstate(struct ieee80211vap *,
- enum ieee80211_state, int);
-static void rum_setup_tx_desc(struct rum_softc *,
- struct rum_tx_desc *, uint32_t, uint16_t, int,
- int);
-static int rum_tx_mgt(struct rum_softc *, struct mbuf *,
- struct ieee80211_node *);
-static int rum_tx_raw(struct rum_softc *, struct mbuf *,
- struct ieee80211_node *,
- const struct ieee80211_bpf_params *);
-static int rum_tx_data(struct rum_softc *, struct mbuf *,
- struct ieee80211_node *);
-static void rum_start(struct ifnet *);
-static int rum_ioctl(struct ifnet *, u_long, caddr_t);
-static void rum_eeprom_read(struct rum_softc *, uint16_t, void *,
- int);
-static uint32_t rum_read(struct rum_softc *, uint16_t);
-static void rum_read_multi(struct rum_softc *, uint16_t, void *,
- int);
-static void rum_write(struct rum_softc *, uint16_t, uint32_t);
-static void rum_write_multi(struct rum_softc *, uint16_t, void *,
- size_t);
-static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t);
-static uint8_t rum_bbp_read(struct rum_softc *, uint8_t);
-static void rum_rf_write(struct rum_softc *, uint8_t, uint32_t);
-static void rum_select_antenna(struct rum_softc *);
-static void rum_enable_mrr(struct rum_softc *);
-static void rum_set_txpreamble(struct rum_softc *);
-static void rum_set_basicrates(struct rum_softc *);
-static void rum_select_band(struct rum_softc *,
- struct ieee80211_channel *);
-static void rum_set_chan(struct rum_softc *,
- struct ieee80211_channel *);
-static void rum_enable_tsf_sync(struct rum_softc *);
-static void rum_update_slot(struct ifnet *);
-static void rum_set_bssid(struct rum_softc *, const uint8_t *);
-static void rum_set_macaddr(struct rum_softc *, const uint8_t *);
-static const char *rum_get_rf(int);
-static void rum_read_eeprom(struct rum_softc *);
-static int rum_bbp_init(struct rum_softc *);
-static void rum_init(void *);
-static int rum_load_microcode(struct rum_softc *, const u_char *,
- size_t);
-static int rum_prepare_beacon(struct rum_softc *,
- struct ieee80211vap *);
-static int rum_raw_xmit(struct ieee80211_node *, struct mbuf *,
- const struct ieee80211_bpf_params *);
-static struct ieee80211_node *rum_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void rum_newassoc(struct ieee80211_node *, int);
-static void rum_scan_start(struct ieee80211com *);
-static void rum_scan_end(struct ieee80211com *);
-static void rum_set_channel(struct ieee80211com *);
-static int rum_get_rssi(struct rum_softc *, uint8_t);
-static void rum_amrr_start(struct rum_softc *,
- struct ieee80211_node *);
-static void rum_amrr_timeout(void *);
-static int rum_pause(struct rum_softc *, int);
-static void rum_queue_command(struct rum_softc *,
- usb2_proc_callback_t *, struct usb2_proc_msg *,
- struct usb2_proc_msg *);
-
-static const struct {
- uint32_t reg;
- uint32_t val;
-} rum_def_mac[] = {
- { RT2573_TXRX_CSR0, 0x025fb032 },
- { RT2573_TXRX_CSR1, 0x9eaa9eaf },
- { RT2573_TXRX_CSR2, 0x8a8b8c8d },
- { RT2573_TXRX_CSR3, 0x00858687 },
- { RT2573_TXRX_CSR7, 0x2e31353b },
- { RT2573_TXRX_CSR8, 0x2a2a2a2c },
- { RT2573_TXRX_CSR15, 0x0000000f },
- { RT2573_MAC_CSR6, 0x00000fff },
- { RT2573_MAC_CSR8, 0x016c030a },
- { RT2573_MAC_CSR10, 0x00000718 },
- { RT2573_MAC_CSR12, 0x00000004 },
- { RT2573_MAC_CSR13, 0x00007f00 },
- { RT2573_SEC_CSR0, 0x00000000 },
- { RT2573_SEC_CSR1, 0x00000000 },
- { RT2573_SEC_CSR5, 0x00000000 },
- { RT2573_PHY_CSR1, 0x000023b0 },
- { RT2573_PHY_CSR5, 0x00040a06 },
- { RT2573_PHY_CSR6, 0x00080606 },
- { RT2573_PHY_CSR7, 0x00000408 },
- { RT2573_AIFSN_CSR, 0x00002273 },
- { RT2573_CWMIN_CSR, 0x00002344 },
- { RT2573_CWMAX_CSR, 0x000034aa }
-};
-
-static const struct {
- uint8_t reg;
- uint8_t val;
-} rum_def_bbp[] = {
- { 3, 0x80 },
- { 15, 0x30 },
- { 17, 0x20 },
- { 21, 0xc8 },
- { 22, 0x38 },
- { 23, 0x06 },
- { 24, 0xfe },
- { 25, 0x0a },
- { 26, 0x0d },
- { 32, 0x0b },
- { 34, 0x12 },
- { 37, 0x07 },
- { 39, 0xf8 },
- { 41, 0x60 },
- { 53, 0x10 },
- { 54, 0x18 },
- { 60, 0x10 },
- { 61, 0x04 },
- { 62, 0x04 },
- { 75, 0xfe },
- { 86, 0xfe },
- { 88, 0xfe },
- { 90, 0x0f },
- { 99, 0x00 },
- { 102, 0x16 },
- { 107, 0x04 }
-};
-
-static const struct rfprog {
- uint8_t chan;
- uint32_t r1, r2, r3, r4;
-} rum_rf5226[] = {
- { 1, 0x00b03, 0x001e1, 0x1a014, 0x30282 },
- { 2, 0x00b03, 0x001e1, 0x1a014, 0x30287 },
- { 3, 0x00b03, 0x001e2, 0x1a014, 0x30282 },
- { 4, 0x00b03, 0x001e2, 0x1a014, 0x30287 },
- { 5, 0x00b03, 0x001e3, 0x1a014, 0x30282 },
- { 6, 0x00b03, 0x001e3, 0x1a014, 0x30287 },
- { 7, 0x00b03, 0x001e4, 0x1a014, 0x30282 },
- { 8, 0x00b03, 0x001e4, 0x1a014, 0x30287 },
- { 9, 0x00b03, 0x001e5, 0x1a014, 0x30282 },
- { 10, 0x00b03, 0x001e5, 0x1a014, 0x30287 },
- { 11, 0x00b03, 0x001e6, 0x1a014, 0x30282 },
- { 12, 0x00b03, 0x001e6, 0x1a014, 0x30287 },
- { 13, 0x00b03, 0x001e7, 0x1a014, 0x30282 },
- { 14, 0x00b03, 0x001e8, 0x1a014, 0x30284 },
-
- { 34, 0x00b03, 0x20266, 0x36014, 0x30282 },
- { 38, 0x00b03, 0x20267, 0x36014, 0x30284 },
- { 42, 0x00b03, 0x20268, 0x36014, 0x30286 },
- { 46, 0x00b03, 0x20269, 0x36014, 0x30288 },
-
- { 36, 0x00b03, 0x00266, 0x26014, 0x30288 },
- { 40, 0x00b03, 0x00268, 0x26014, 0x30280 },
- { 44, 0x00b03, 0x00269, 0x26014, 0x30282 },
- { 48, 0x00b03, 0x0026a, 0x26014, 0x30284 },
- { 52, 0x00b03, 0x0026b, 0x26014, 0x30286 },
- { 56, 0x00b03, 0x0026c, 0x26014, 0x30288 },
- { 60, 0x00b03, 0x0026e, 0x26014, 0x30280 },
- { 64, 0x00b03, 0x0026f, 0x26014, 0x30282 },
-
- { 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 },
- { 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 },
- { 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 },
- { 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 },
- { 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 },
- { 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 },
- { 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 },
- { 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 },
- { 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 },
- { 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 },
- { 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 },
-
- { 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 },
- { 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 },
- { 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 },
- { 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 },
- { 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 }
-}, rum_rf5225[] = {
- { 1, 0x00b33, 0x011e1, 0x1a014, 0x30282 },
- { 2, 0x00b33, 0x011e1, 0x1a014, 0x30287 },
- { 3, 0x00b33, 0x011e2, 0x1a014, 0x30282 },
- { 4, 0x00b33, 0x011e2, 0x1a014, 0x30287 },
- { 5, 0x00b33, 0x011e3, 0x1a014, 0x30282 },
- { 6, 0x00b33, 0x011e3, 0x1a014, 0x30287 },
- { 7, 0x00b33, 0x011e4, 0x1a014, 0x30282 },
- { 8, 0x00b33, 0x011e4, 0x1a014, 0x30287 },
- { 9, 0x00b33, 0x011e5, 0x1a014, 0x30282 },
- { 10, 0x00b33, 0x011e5, 0x1a014, 0x30287 },
- { 11, 0x00b33, 0x011e6, 0x1a014, 0x30282 },
- { 12, 0x00b33, 0x011e6, 0x1a014, 0x30287 },
- { 13, 0x00b33, 0x011e7, 0x1a014, 0x30282 },
- { 14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },
-
- { 34, 0x00b33, 0x01266, 0x26014, 0x30282 },
- { 38, 0x00b33, 0x01267, 0x26014, 0x30284 },
- { 42, 0x00b33, 0x01268, 0x26014, 0x30286 },
- { 46, 0x00b33, 0x01269, 0x26014, 0x30288 },
-
- { 36, 0x00b33, 0x01266, 0x26014, 0x30288 },
- { 40, 0x00b33, 0x01268, 0x26014, 0x30280 },
- { 44, 0x00b33, 0x01269, 0x26014, 0x30282 },
- { 48, 0x00b33, 0x0126a, 0x26014, 0x30284 },
- { 52, 0x00b33, 0x0126b, 0x26014, 0x30286 },
- { 56, 0x00b33, 0x0126c, 0x26014, 0x30288 },
- { 60, 0x00b33, 0x0126e, 0x26014, 0x30280 },
- { 64, 0x00b33, 0x0126f, 0x26014, 0x30282 },
-
- { 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 },
- { 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 },
- { 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 },
- { 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 },
- { 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 },
- { 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 },
- { 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 },
- { 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 },
- { 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 },
- { 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 },
- { 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 },
-
- { 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 },
- { 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 },
- { 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 },
- { 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 },
- { 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
-};
-
-static const struct usb2_config rum_config[RUM_N_TRANSFER] = {
- [RUM_BULK_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = (MCLBYTES + RT2573_TX_DESC_SIZE + 8),
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = rum_bulk_write_callback,
- .mh.timeout = 5000, /* ms */
- },
- [RUM_BULK_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = (MCLBYTES + RT2573_RX_DESC_SIZE),
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = rum_bulk_read_callback,
- },
-};
-
-static int
-rum_match(device_t self)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
- if (uaa->info.bConfigIndex != 0)
- return (ENXIO);
- if (uaa->info.bIfaceIndex != RT2573_IFACE_INDEX)
- return (ENXIO);
-
- return (usb2_lookup_id_by_uaa(rum_devs, sizeof(rum_devs), uaa));
-}
-
-static int
-rum_attach(device_t self)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(self);
- struct rum_softc *sc = device_get_softc(self);
- uint8_t iface_index;
- int error;
-
- device_set_usb2_desc(self);
- sc->sc_udev = uaa->device;
- sc->sc_dev = self;
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(self),
- MTX_NETWORK_LOCK, MTX_DEF);
-
- iface_index = RT2573_IFACE_INDEX;
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, rum_config, RUM_N_TRANSFER, sc, &sc->sc_mtx);
- if (error) {
- device_printf(self, "could not allocate USB transfers, "
- "err=%s\n", usb2_errstr(error));
- goto detach;
- }
- error = usb2_proc_create(&sc->sc_tq, &sc->sc_mtx,
- device_get_nameunit(self), USB_PRI_MED);
- if (error) {
- device_printf(self, "could not setup config thread!\n");
- goto detach;
- }
-
- /* fork rest of the attach code */
- RUM_LOCK(sc);
- rum_queue_command(sc, rum_attach_post,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- RUM_UNLOCK(sc);
- return (0);
-
-detach:
- rum_detach(self);
- return (ENXIO); /* failure */
-}
-
-static void
-rum_attach_post(struct usb2_proc_msg *pm)
-{
- struct rum_task *task = (struct rum_task *)pm;
- struct rum_softc *sc = task->sc;
- struct ifnet *ifp;
- struct ieee80211com *ic;
- unsigned int ntries;
- int error;
- uint32_t tmp;
- uint8_t bands;
-
- /* retrieve RT2573 rev. no */
- for (ntries = 0; ntries < 100; ntries++) {
- if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0)
- break;
- if (rum_pause(sc, hz / 100))
- break;
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev, "timeout waiting for chip to settle\n");
- return;
- }
-
- /* retrieve MAC address and various other things from EEPROM */
- rum_read_eeprom(sc);
-
- device_printf(sc->sc_dev, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
- tmp, rum_get_rf(sc->rf_rev));
-
- error = rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode));
- if (error != 0) {
- RUM_UNLOCK(sc);
- device_printf(sc->sc_dev, "could not load 8051 microcode\n");
- return;
- }
- RUM_UNLOCK(sc);
-
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- RUM_LOCK(sc);
- return;
- }
- ic = ifp->if_l2com;
-
- ifp->if_softc = sc;
- if_initname(ifp, "rum", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = rum_init;
- ifp->if_ioctl = rum_ioctl;
- ifp->if_start = rum_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
- ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
- IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
-
- /* set device capabilities */
- ic->ic_caps =
- IEEE80211_C_STA /* station mode supported */
- | IEEE80211_C_IBSS /* IBSS mode supported */
- | IEEE80211_C_MONITOR /* monitor mode supported */
- | IEEE80211_C_HOSTAP /* HostAp mode supported */
- | IEEE80211_C_TXPMGT /* tx power management */
- | IEEE80211_C_SHPREAMBLE /* short preamble supported */
- | IEEE80211_C_SHSLOT /* short slot time supported */
- | IEEE80211_C_BGSCAN /* bg scanning supported */
- | IEEE80211_C_WPA /* 802.11i */
- ;
-
- bands = 0;
- setbit(&bands, IEEE80211_MODE_11B);
- setbit(&bands, IEEE80211_MODE_11G);
- if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226)
- setbit(&bands, IEEE80211_MODE_11A);
- ieee80211_init_channels(ic, NULL, &bands);
-
- ieee80211_ifattach(ic);
- ic->ic_newassoc = rum_newassoc;
- ic->ic_raw_xmit = rum_raw_xmit;
- ic->ic_node_alloc = rum_node_alloc;
- ic->ic_scan_start = rum_scan_start;
- ic->ic_scan_end = rum_scan_end;
- ic->ic_set_channel = rum_set_channel;
-
- ic->ic_vap_create = rum_vap_create;
- ic->ic_vap_delete = rum_vap_delete;
-
- sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
-
- bpfattach(ifp, DLT_IEEE802_11_RADIO,
- sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
-
- sc->sc_rxtap_len = sizeof sc->sc_rxtap;
- sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
- sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT);
-
- sc->sc_txtap_len = sizeof sc->sc_txtap;
- sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
- sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT);
-
- if (bootverbose)
- ieee80211_announce(ic);
-
- RUM_LOCK(sc);
-}
-
-static int
-rum_detach(device_t self)
-{
- struct rum_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
-
- /* wait for any post attach or other command to complete */
- usb2_proc_drain(&sc->sc_tq);
-
- /* stop all USB transfers */
- usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER);
- usb2_proc_free(&sc->sc_tq);
-
- /* free TX list, if any */
- RUM_LOCK(sc);
- rum_unsetup_tx_list(sc);
- RUM_UNLOCK(sc);
-
- if (ifp) {
- ic = ifp->if_l2com;
- bpfdetach(ifp);
- ieee80211_ifdetach(ic);
- if_free(ifp);
- }
-
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static struct ieee80211vap *
-rum_vap_create(struct ieee80211com *ic,
- const char name[IFNAMSIZ], int unit, int opmode, int flags,
- const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
- struct rum_vap *rvp;
- struct ieee80211vap *vap;
-
- if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
- return NULL;
- rvp = (struct rum_vap *) malloc(sizeof(struct rum_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (rvp == NULL)
- return NULL;
- vap = &rvp->vap;
- /* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
-
- /* override state transition machine */
- rvp->newstate = vap->iv_newstate;
- vap->iv_newstate = rum_newstate;
-
- rvp->sc = sc;
- usb2_callout_init_mtx(&rvp->amrr_ch, &sc->sc_mtx, 0);
- ieee80211_amrr_init(&rvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
-
- /* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
- ic->ic_opmode = opmode;
- return vap;
-}
-
-static void
-rum_vap_delete(struct ieee80211vap *vap)
-{
- struct rum_vap *rvp = RUM_VAP(vap);
-
- usb2_callout_drain(&rvp->amrr_ch);
- ieee80211_amrr_cleanup(&rvp->amrr);
- ieee80211_vap_detach(vap);
- free(rvp, M_80211_VAP);
-}
-
-static void
-rum_tx_free(struct rum_tx_data *data, int txerr)
-{
- struct rum_softc *sc = data->sc;
-
- if (data->m != NULL) {
- if (data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m,
- txerr ? ETIMEDOUT : 0);
- m_freem(data->m);
- data->m = NULL;
-
- ieee80211_free_node(data->ni);
- data->ni = NULL;
- }
- STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
- sc->tx_nfree++;
-}
-
-static void
-rum_setup_tx_list(struct rum_softc *sc)
-{
- struct rum_tx_data *data;
- int i;
-
- sc->tx_nfree = 0;
- STAILQ_INIT(&sc->tx_q);
- STAILQ_INIT(&sc->tx_free);
-
- for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
- data = &sc->tx_data[i];
-
- data->sc = sc;
- STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
- sc->tx_nfree++;
- }
-}
-
-static void
-rum_unsetup_tx_list(struct rum_softc *sc)
-{
- struct rum_tx_data *data;
- int i;
-
- /* make sure any subsequent use of the queues will fail */
- sc->tx_nfree = 0;
- STAILQ_INIT(&sc->tx_q);
- STAILQ_INIT(&sc->tx_free);
-
- /* free up all node references and mbufs */
- for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
- data = &sc->tx_data[i];
-
- if (data->m != NULL) {
- m_freem(data->m);
- data->m = NULL;
- }
- if (data->ni != NULL) {
- ieee80211_free_node(data->ni);
- data->ni = NULL;
- }
- }
-}
-
-static void
-rum_task(struct usb2_proc_msg *pm)
-{
- struct rum_task *task = (struct rum_task *)pm;
- struct rum_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct rum_vap *rvp = RUM_VAP(vap);
- const struct ieee80211_txparam *tp;
- enum ieee80211_state ostate;
- struct ieee80211_node *ni;
- uint32_t tmp;
-
- ostate = vap->iv_state;
-
- switch (sc->sc_state) {
- case IEEE80211_S_INIT:
- if (ostate == IEEE80211_S_RUN) {
- /* abort TSF synchronization */
- tmp = rum_read(sc, RT2573_TXRX_CSR9);
- rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
- }
- break;
-
- case IEEE80211_S_RUN:
- ni = vap->iv_bss;
-
- if (vap->iv_opmode != IEEE80211_M_MONITOR) {
- rum_update_slot(ic->ic_ifp);
- rum_enable_mrr(sc);
- rum_set_txpreamble(sc);
- rum_set_basicrates(sc);
- IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
- rum_set_bssid(sc, sc->sc_bssid);
- }
-
- if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
- vap->iv_opmode == IEEE80211_M_IBSS)
- rum_prepare_beacon(sc, vap);
-
- if (vap->iv_opmode != IEEE80211_M_MONITOR)
- rum_enable_tsf_sync(sc);
-
- /* enable automatic rate adaptation */
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
- if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
- rum_amrr_start(sc, ni);
- break;
- default:
- break;
- }
-
- RUM_UNLOCK(sc);
- IEEE80211_LOCK(ic);
- rvp->newstate(vap, sc->sc_state, sc->sc_arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
- IEEE80211_UNLOCK(ic);
- RUM_LOCK(sc);
-}
-
-static int
-rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
-{
- struct rum_vap *rvp = RUM_VAP(vap);
- struct ieee80211com *ic = vap->iv_ic;
- struct rum_softc *sc = ic->ic_ifp->if_softc;
-
- DPRINTF("%s -> %s\n",
- ieee80211_state_name[vap->iv_state],
- ieee80211_state_name[nstate]);
-
- RUM_LOCK(sc);
- usb2_callout_stop(&rvp->amrr_ch);
-
- /* do it in a process context */
- sc->sc_state = nstate;
- sc->sc_arg = arg;
- RUM_UNLOCK(sc);
-
- if (nstate == IEEE80211_S_INIT) {
- rvp->newstate(vap, nstate, arg);
- return 0;
- } else {
- RUM_LOCK(sc);
- rum_queue_command(sc, rum_task, &sc->sc_task[0].hdr,
- &sc->sc_task[1].hdr);
- RUM_UNLOCK(sc);
- return EINPROGRESS;
- }
-}
-
-static void
-rum_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct rum_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211_channel *c = ic->ic_curchan;
- struct rum_tx_data *data;
- struct mbuf *m;
- unsigned int len;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(11, "transfer complete, %d bytes\n", xfer->actlen);
-
- /* free resources */
- data = xfer->priv_fifo;
- rum_tx_free(data, 0);
- xfer->priv_fifo = NULL;
-
- ifp->if_opackets++;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- data = STAILQ_FIRST(&sc->tx_q);
- if (data) {
- STAILQ_REMOVE_HEAD(&sc->tx_q, next);
- m = data->m;
-
- if (m->m_pkthdr.len > (MCLBYTES + RT2573_TX_DESC_SIZE)) {
- DPRINTFN(0, "data overflow, %u bytes\n",
- m->m_pkthdr.len);
- m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE);
- }
- usb2_copy_in(xfer->frbuffers, 0, &data->desc,
- RT2573_TX_DESC_SIZE);
- usb2_m_copy_in(xfer->frbuffers, RT2573_TX_DESC_SIZE, m,
- 0, m->m_pkthdr.len);
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = data->rate;
- tap->wt_chan_freq = htole16(c->ic_freq);
- tap->wt_chan_flags = htole16(c->ic_flags);
- tap->wt_antenna = sc->tx_ant;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
- }
-
- /* align end on a 4-bytes boundary */
- len = (RT2573_TX_DESC_SIZE + m->m_pkthdr.len + 3) & ~3;
- if ((len % 64) == 0)
- len += 4;
-
- DPRINTFN(11, "sending frame len=%u xferlen=%u\n",
- m->m_pkthdr.len, len);
-
- xfer->frlengths[0] = len;
- xfer->priv_fifo = data;
-
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- DPRINTFN(11, "transfer error, %s\n",
- usb2_errstr(xfer->error));
-
- ifp->if_oerrors++;
- data = xfer->priv_fifo;
- if (data != NULL) {
- rum_tx_free(data, xfer->error);
- xfer->priv_fifo = NULL;
- }
-
- if (xfer->error == USB_ERR_STALLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- if (xfer->error == USB_ERR_TIMEOUT)
- device_printf(sc->sc_dev, "device timeout\n");
- break;
- }
-}
-
-static void
-rum_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct rum_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211_node *ni;
- struct mbuf *m = NULL;
- uint32_t flags;
- uint8_t rssi = 0;
- unsigned int len;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- DPRINTFN(15, "rx done, actlen=%d\n", xfer->actlen);
-
- len = xfer->actlen;
- if (len < RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN) {
- DPRINTF("%s: xfer too short %d\n",
- device_get_nameunit(sc->sc_dev), len);
- ifp->if_ierrors++;
- goto tr_setup;
- }
-
- len -= RT2573_RX_DESC_SIZE;
- usb2_copy_out(xfer->frbuffers, 0, &sc->sc_rx_desc,
- RT2573_RX_DESC_SIZE);
-
- rssi = rum_get_rssi(sc, sc->sc_rx_desc.rssi);
- flags = le32toh(sc->sc_rx_desc.flags);
- if (flags & RT2573_RX_CRC_ERROR) {
- /*
- * This should not happen since we did not
- * request to receive those frames when we
- * filled RUM_TXRX_CSR2:
- */
- DPRINTFN(5, "PHY or CRC error\n");
- ifp->if_ierrors++;
- goto tr_setup;
- }
-
- m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (m == NULL) {
- DPRINTF("could not allocate mbuf\n");
- ifp->if_ierrors++;
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, RT2573_RX_DESC_SIZE,
- mtod(m, uint8_t *), len);
-
- /* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
-
- tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
- tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
- (flags & RT2573_RX_OFDM) ?
- IEEE80211_T_OFDM : IEEE80211_T_CCK);
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wr_antenna = sc->rx_ant;
- tap->wr_antsignal = rssi;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
- }
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
-
- /*
- * At the end of a USB callback it is always safe to unlock
- * the private mutex of a device! That is why we do the
- * "ieee80211_input" here, and not some lines up!
- */
- if (m) {
- RUM_UNLOCK(sc);
- ni = ieee80211_find_rxnode(ic,
- mtod(m, struct ieee80211_frame_min *));
- if (ni != NULL) {
- (void) ieee80211_input(ni, m, rssi,
- RT2573_NOISE_FLOOR, 0);
- ieee80211_free_node(ni);
- } else
- (void) ieee80211_input_all(ic, m, rssi,
- RT2573_NOISE_FLOOR, 0);
- RUM_LOCK(sc);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static uint8_t
-rum_plcp_signal(int rate)
-{
- switch (rate) {
- /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
- case 12: return 0xb;
- case 18: return 0xf;
- case 24: return 0xa;
- case 36: return 0xe;
- case 48: return 0x9;
- case 72: return 0xd;
- case 96: return 0x8;
- case 108: return 0xc;
-
- /* CCK rates (NB: not IEEE std, device-specific) */
- case 2: return 0x0;
- case 4: return 0x1;
- case 11: return 0x2;
- case 22: return 0x3;
- }
- return 0xff; /* XXX unsupported/unknown rate */
-}
-
-static void
-rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
- uint32_t flags, uint16_t xflags, int len, int rate)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint16_t plcp_length;
- int remainder;
-
- desc->flags = htole32(flags);
- desc->flags |= htole32(RT2573_TX_VALID);
- desc->flags |= htole32(len << 16);
-
- desc->xflags = htole16(xflags);
-
- desc->wme = htole16(RT2573_QID(0) | RT2573_AIFSN(2) |
- RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10));
-
- /* setup PLCP fields */
- desc->plcp_signal = rum_plcp_signal(rate);
- desc->plcp_service = 4;
-
- len += IEEE80211_CRC_LEN;
- if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) {
- desc->flags |= htole32(RT2573_TX_OFDM);
-
- plcp_length = len & 0xfff;
- desc->plcp_length_hi = plcp_length >> 6;
- desc->plcp_length_lo = plcp_length & 0x3f;
- } else {
- plcp_length = (16 * len + rate - 1) / rate;
- if (rate == 22) {
- remainder = (16 * len) % 22;
- if (remainder != 0 && remainder < 7)
- desc->plcp_service |= RT2573_PLCP_LENGEXT;
- }
- desc->plcp_length_hi = plcp_length >> 8;
- desc->plcp_length_lo = plcp_length & 0xff;
-
- if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- desc->plcp_signal |= 0x08;
- }
-}
-
-#define RUM_TX_TIMEOUT 5000
-
-static int
-rum_sendprot(struct rum_softc *sc,
- const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate)
-{
- struct ieee80211com *ic = ni->ni_ic;
- const struct ieee80211_frame *wh;
- struct rum_tx_data *data;
- struct mbuf *mprot;
- int protrate, ackrate, pktlen, flags, isshort;
- uint16_t dur;
-
- RUM_LOCK_ASSERT(sc, MA_OWNED);
- KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY,
- ("protection %d", prot));
-
- wh = mtod(m, const struct ieee80211_frame *);
- pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
-
- protrate = ieee80211_ctl_rate(sc->sc_rates, rate);
- ackrate = ieee80211_ack_rate(sc->sc_rates, rate);
-
- isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
- dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort);
- + ieee80211_ack_duration(sc->sc_rates, rate, isshort);
- flags = RT2573_TX_MORE_FRAG;
- if (prot == IEEE80211_PROT_RTSCTS) {
- /* NB: CTS is the same size as an ACK */
- dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort);
- flags |= RT2573_TX_NEED_ACK;
- mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur);
- } else {
- mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
- }
- if (mprot == NULL) {
- /* XXX stat + msg */
- return ENOBUFS;
- }
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
-
- data->m = mprot;
- data->ni = ieee80211_ref_node(ni);
- data->rate = protrate;
- rum_setup_tx_desc(sc, &data->desc, flags, 0, mprot->m_pkthdr.len, protrate);
-
- STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
- usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
-
- return 0;
-}
-
-static int
-rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct rum_tx_data *data;
- struct ieee80211_frame *wh;
- const struct ieee80211_txparam *tp;
- struct ieee80211_key *k;
- uint32_t flags = 0;
- uint16_t dur;
-
- RUM_LOCK_ASSERT(sc, MA_OWNED);
-
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
-
- wh = mtod(m0, struct ieee80211_frame *);
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return ENOBUFS;
- }
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- flags |= RT2573_TX_NEED_ACK;
-
- dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate,
- ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
-
- /* tell hardware to add timestamp for probe responses */
- if ((wh->i_fc[0] &
- (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
- (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
- flags |= RT2573_TX_TIMESTAMP;
- }
-
- data->m = m0;
- data->ni = ni;
- data->rate = tp->mgmtrate;
-
- rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, tp->mgmtrate);
-
- DPRINTFN(10, "sending mgt frame len=%d rate=%d\n",
- m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate);
-
- STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
- usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
-
- return 0;
-}
-
-static int
-rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
- const struct ieee80211_bpf_params *params)
-{
- struct rum_tx_data *data;
- uint32_t flags;
- int rate, error;
-
- RUM_LOCK_ASSERT(sc, MA_OWNED);
- KASSERT(params != NULL, ("no raw xmit params"));
-
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
-
- rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
- /* XXX validate */
- if (rate == 0) {
- m_freem(m0);
- return EINVAL;
- }
- flags = 0;
- if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
- flags |= RT2573_TX_NEED_ACK;
- if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) {
- error = rum_sendprot(sc, m0, ni,
- params->ibp_flags & IEEE80211_BPF_RTS ?
- IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
- rate);
- if (error) {
- m_freem(m0);
- return error;
- }
- flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
- }
-
- data->m = m0;
- data->ni = ni;
- data->rate = rate;
-
- /* XXX need to setup descriptor ourself */
- rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate);
-
- DPRINTFN(10, "sending raw frame len=%u rate=%u\n",
- m0->m_pkthdr.len, rate);
-
- STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
- usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
-
- return 0;
-}
-
-static int
-rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct rum_tx_data *data;
- struct ieee80211_frame *wh;
- const struct ieee80211_txparam *tp;
- struct ieee80211_key *k;
- uint32_t flags = 0;
- uint16_t dur;
- int error, rate;
-
- RUM_LOCK_ASSERT(sc, MA_OWNED);
-
- wh = mtod(m0, struct ieee80211_frame *);
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
- if (IEEE80211_IS_MULTICAST(wh->i_addr1))
- rate = tp->mcastrate;
- else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
- rate = tp->ucastrate;
- else
- rate = ni->ni_txrate;
-
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return ENOBUFS;
- }
-
- /* packet header may have moved, reset our local pointer */
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- int prot = IEEE80211_PROT_NONE;
- if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
- prot = IEEE80211_PROT_RTSCTS;
- else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
- ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM)
- prot = ic->ic_protmode;
- if (prot != IEEE80211_PROT_NONE) {
- error = rum_sendprot(sc, m0, ni, prot, rate);
- if (error) {
- m_freem(m0);
- return error;
- }
- flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
- }
- }
-
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
-
- data->m = m0;
- data->ni = ni;
- data->rate = rate;
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- flags |= RT2573_TX_NEED_ACK;
- flags |= RT2573_TX_MORE_FRAG;
-
- dur = ieee80211_ack_duration(sc->sc_rates, rate,
- ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
- }
-
- rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate);
-
- DPRINTFN(10, "sending frame len=%d rate=%d\n",
- m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate);
-
- STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
- usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
-
- return 0;
-}
-
-static void
-rum_start(struct ifnet *ifp)
-{
- struct rum_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- RUM_LOCK(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- RUM_UNLOCK(sc);
- return;
- }
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->tx_nfree == 0) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
- ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
- m = ieee80211_encap(ni, m);
- if (m == NULL) {
- ieee80211_free_node(ni);
- continue;
- }
- if (rum_tx_data(sc, m, ni) != 0) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- break;
- }
- }
- RUM_UNLOCK(sc);
-}
-
-static int
-rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct rum_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- RUM_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- rum_queue_command(sc, rum_init_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- startall = 1;
- } else
- rum_queue_command(sc, rum_promisctask,
- &sc->sc_promisctask[0].hdr,
- &sc->sc_promisctask[1].hdr);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- rum_queue_command(sc, rum_stop_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- }
- }
- RUM_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-static void
-rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len)
-{
- struct usb2_device_request req;
- usb2_error_t error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RT2573_READ_EEPROM;
- USETW(req.wValue, 0);
- USETW(req.wIndex, addr);
- USETW(req.wLength, len);
-
- error = rum_do_request(sc, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
- usb2_errstr(error));
- }
-}
-
-static uint32_t
-rum_read(struct rum_softc *sc, uint16_t reg)
-{
- uint32_t val;
-
- rum_read_multi(sc, reg, &val, sizeof val);
-
- return le32toh(val);
-}
-
-static void
-rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len)
-{
- struct usb2_device_request req;
- usb2_error_t error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RT2573_READ_MULTI_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, len);
-
- error = rum_do_request(sc, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "could not multi read MAC register: %s\n",
- usb2_errstr(error));
- }
-}
-
-static void
-rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
-{
- uint32_t tmp = htole32(val);
-
- rum_write_multi(sc, reg, &tmp, sizeof tmp);
-}
-
-static void
-rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len)
-{
- struct usb2_device_request req;
- usb2_error_t error;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = RT2573_WRITE_MULTI_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, len);
-
- error = rum_do_request(sc, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "could not multi write MAC register: %s\n",
- usb2_errstr(error));
- }
-}
-
-static void
-rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
-{
- uint32_t tmp;
- int ntries;
-
- for (ntries = 0; ntries < 100; ntries++) {
- if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
- break;
- if (rum_pause(sc, hz / 100))
- break;
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev, "could not write to BBP\n");
- return;
- }
-
- tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val;
- rum_write(sc, RT2573_PHY_CSR3, tmp);
-}
-
-static uint8_t
-rum_bbp_read(struct rum_softc *sc, uint8_t reg)
-{
- uint32_t val;
- int ntries;
-
- for (ntries = 0; ntries < 100; ntries++) {
- if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
- break;
- if (rum_pause(sc, hz / 100))
- break;
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev, "could not read BBP\n");
- return 0;
- }
-
- val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8;
- rum_write(sc, RT2573_PHY_CSR3, val);
-
- for (ntries = 0; ntries < 100; ntries++) {
- val = rum_read(sc, RT2573_PHY_CSR3);
- if (!(val & RT2573_BBP_BUSY))
- return val & 0xff;
- if (rum_pause(sc, hz / 100))
- break;
- }
-
- device_printf(sc->sc_dev, "could not read BBP\n");
- return 0;
-}
-
-static void
-rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
-{
- uint32_t tmp;
- int ntries;
-
- for (ntries = 0; ntries < 100; ntries++) {
- if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY))
- break;
- if (rum_pause(sc, hz / 100))
- break;
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev, "could not write to RF\n");
- return;
- }
-
- tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 |
- (reg & 3);
- rum_write(sc, RT2573_PHY_CSR4, tmp);
-
- /* remember last written value in sc */
- sc->rf_regs[reg] = val;
-
- DPRINTFN(15, "RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff);
-}
-
-static void
-rum_select_antenna(struct rum_softc *sc)
-{
- uint8_t bbp4, bbp77;
- uint32_t tmp;
-
- bbp4 = rum_bbp_read(sc, 4);
- bbp77 = rum_bbp_read(sc, 77);
-
- /* TBD */
-
- /* make sure Rx is disabled before switching antenna */
- tmp = rum_read(sc, RT2573_TXRX_CSR0);
- rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
-
- rum_bbp_write(sc, 4, bbp4);
- rum_bbp_write(sc, 77, bbp77);
-
- rum_write(sc, RT2573_TXRX_CSR0, tmp);
-}
-
-/*
- * Enable multi-rate retries for frames sent at OFDM rates.
- * In 802.11b/g mode, allow fallback to CCK rates.
- */
-static void
-rum_enable_mrr(struct rum_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t tmp;
-
- tmp = rum_read(sc, RT2573_TXRX_CSR4);
-
- tmp &= ~RT2573_MRR_CCK_FALLBACK;
- if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan))
- tmp |= RT2573_MRR_CCK_FALLBACK;
- tmp |= RT2573_MRR_ENABLED;
-
- rum_write(sc, RT2573_TXRX_CSR4, tmp);
-}
-
-static void
-rum_set_txpreamble(struct rum_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t tmp;
-
- tmp = rum_read(sc, RT2573_TXRX_CSR4);
-
- tmp &= ~RT2573_SHORT_PREAMBLE;
- if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
- tmp |= RT2573_SHORT_PREAMBLE;
-
- rum_write(sc, RT2573_TXRX_CSR4, tmp);
-}
-
-static void
-rum_set_basicrates(struct rum_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- /* update basic rate set */
- if (ic->ic_curmode == IEEE80211_MODE_11B) {
- /* 11b basic rates: 1, 2Mbps */
- rum_write(sc, RT2573_TXRX_CSR5, 0x3);
- } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) {
- /* 11a basic rates: 6, 12, 24Mbps */
- rum_write(sc, RT2573_TXRX_CSR5, 0x150);
- } else {
- /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
- rum_write(sc, RT2573_TXRX_CSR5, 0xf);
- }
-}
-
-/*
- * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
- * driver.
- */
-static void
-rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
-{
- uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
- uint32_t tmp;
-
- /* update all BBP registers that depend on the band */
- bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
- bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48;
- if (IEEE80211_IS_CHAN_5GHZ(c)) {
- bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
- bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10;
- }
- if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
- (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
- bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
- }
-
- sc->bbp17 = bbp17;
- rum_bbp_write(sc, 17, bbp17);
- rum_bbp_write(sc, 96, bbp96);
- rum_bbp_write(sc, 104, bbp104);
-
- if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
- (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
- rum_bbp_write(sc, 75, 0x80);
- rum_bbp_write(sc, 86, 0x80);
- rum_bbp_write(sc, 88, 0x80);
- }
-
- rum_bbp_write(sc, 35, bbp35);
- rum_bbp_write(sc, 97, bbp97);
- rum_bbp_write(sc, 98, bbp98);
-
- tmp = rum_read(sc, RT2573_PHY_CSR0);
- tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ);
- if (IEEE80211_IS_CHAN_2GHZ(c))
- tmp |= RT2573_PA_PE_2GHZ;
- else
- tmp |= RT2573_PA_PE_5GHZ;
- rum_write(sc, RT2573_PHY_CSR0, tmp);
-}
-
-static void
-rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- const struct rfprog *rfprog;
- uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
- int8_t power;
- int i, chan;
-
- chan = ieee80211_chan2ieee(ic, c);
- if (chan == 0 || chan == IEEE80211_CHAN_ANY)
- return;
-
- /* select the appropriate RF settings based on what EEPROM says */
- rfprog = (sc->rf_rev == RT2573_RF_5225 ||
- sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226;
-
- /* find the settings for this channel (we know it exists) */
- for (i = 0; rfprog[i].chan != chan; i++);
-
- power = sc->txpow[i];
- if (power < 0) {
- bbp94 += power;
- power = 0;
- } else if (power > 31) {
- bbp94 += power - 31;
- power = 31;
- }
-
- /*
- * If we are switching from the 2GHz band to the 5GHz band or
- * vice-versa, BBP registers need to be reprogrammed.
- */
- if (c->ic_flags != ic->ic_curchan->ic_flags) {
- rum_select_band(sc, c);
- rum_select_antenna(sc);
- }
- ic->ic_curchan = c;
-
- rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
- rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
- rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
- rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
-
- rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
- rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
- rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1);
- rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
-
- rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
- rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
- rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
- rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
-
- rum_pause(sc, hz / 100);
-
- /* enable smart mode for MIMO-capable RFs */
- bbp3 = rum_bbp_read(sc, 3);
-
- bbp3 &= ~RT2573_SMART_MODE;
- if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527)
- bbp3 |= RT2573_SMART_MODE;
-
- rum_bbp_write(sc, 3, bbp3);
-
- if (bbp94 != RT2573_BBPR94_DEFAULT)
- rum_bbp_write(sc, 94, bbp94);
-}
-
-/*
- * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
- * and HostAP operating modes.
- */
-static void
-rum_enable_tsf_sync(struct rum_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- uint32_t tmp;
-
- if (vap->iv_opmode != IEEE80211_M_STA) {
- /*
- * Change default 16ms TBTT adjustment to 8ms.
- * Must be done before enabling beacon generation.
- */
- rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8);
- }
-
- tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
-
- /* set beacon interval (in 1/16ms unit) */
- tmp |= vap->iv_bss->ni_intval * 16;
-
- tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT;
- if (vap->iv_opmode == IEEE80211_M_STA)
- tmp |= RT2573_TSF_MODE(1);
- else
- tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON;
-
- rum_write(sc, RT2573_TXRX_CSR9, tmp);
-}
-
-static void
-rum_update_slot(struct ifnet *ifp)
-{
- struct rum_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- uint8_t slottime;
- uint32_t tmp;
-
- slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
-
- tmp = rum_read(sc, RT2573_MAC_CSR9);
- tmp = (tmp & ~0xff) | slottime;
- rum_write(sc, RT2573_MAC_CSR9, tmp);
-
- DPRINTF("setting slot time to %uus\n", slottime);
-}
-
-static void
-rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
-{
- uint32_t tmp;
-
- tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
- rum_write(sc, RT2573_MAC_CSR4, tmp);
-
- tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16;
- rum_write(sc, RT2573_MAC_CSR5, tmp);
-}
-
-static void
-rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
-{
- uint32_t tmp;
-
- tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
- rum_write(sc, RT2573_MAC_CSR2, tmp);
-
- tmp = addr[4] | addr[5] << 8 | 0xff << 16;
- rum_write(sc, RT2573_MAC_CSR3, tmp);
-}
-
-static void
-rum_promisctask(struct usb2_proc_msg *pm)
-{
- struct rum_task *task = (struct rum_task *)pm;
- struct rum_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- uint32_t tmp;
-
- tmp = rum_read(sc, RT2573_TXRX_CSR0);
-
- tmp &= ~RT2573_DROP_NOT_TO_ME;
- if (!(ifp->if_flags & IFF_PROMISC))
- tmp |= RT2573_DROP_NOT_TO_ME;
-
- rum_write(sc, RT2573_TXRX_CSR0, tmp);
-
- DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
- "entering" : "leaving");
-}
-
-static const char *
-rum_get_rf(int rev)
-{
- switch (rev) {
- case RT2573_RF_2527: return "RT2527 (MIMO XR)";
- case RT2573_RF_2528: return "RT2528";
- case RT2573_RF_5225: return "RT5225 (MIMO XR)";
- case RT2573_RF_5226: return "RT5226";
- default: return "unknown";
- }
-}
-
-static void
-rum_read_eeprom(struct rum_softc *sc)
-{
- uint16_t val;
-#ifdef RUM_DEBUG
- int i;
-#endif
-
- /* read MAC address */
- rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_bssid, 6);
-
- rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
- val = le16toh(val);
- sc->rf_rev = (val >> 11) & 0x1f;
- sc->hw_radio = (val >> 10) & 0x1;
- sc->rx_ant = (val >> 4) & 0x3;
- sc->tx_ant = (val >> 2) & 0x3;
- sc->nb_ant = val & 0x3;
-
- DPRINTF("RF revision=%d\n", sc->rf_rev);
-
- rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2);
- val = le16toh(val);
- sc->ext_5ghz_lna = (val >> 6) & 0x1;
- sc->ext_2ghz_lna = (val >> 4) & 0x1;
-
- DPRINTF("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
- sc->ext_2ghz_lna, sc->ext_5ghz_lna);
-
- rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2);
- val = le16toh(val);
- if ((val & 0xff) != 0xff)
- sc->rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */
-
- /* Only [-10, 10] is valid */
- if (sc->rssi_2ghz_corr < -10 || sc->rssi_2ghz_corr > 10)
- sc->rssi_2ghz_corr = 0;
-
- rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2);
- val = le16toh(val);
- if ((val & 0xff) != 0xff)
- sc->rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */
-
- /* Only [-10, 10] is valid */
- if (sc->rssi_5ghz_corr < -10 || sc->rssi_5ghz_corr > 10)
- sc->rssi_5ghz_corr = 0;
-
- if (sc->ext_2ghz_lna)
- sc->rssi_2ghz_corr -= 14;
- if (sc->ext_5ghz_lna)
- sc->rssi_5ghz_corr -= 14;
-
- DPRINTF("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
- sc->rssi_2ghz_corr, sc->rssi_5ghz_corr);
-
- rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2);
- val = le16toh(val);
- if ((val & 0xff) != 0xff)
- sc->rffreq = val & 0xff;
-
- DPRINTF("RF freq=%d\n", sc->rffreq);
-
- /* read Tx power for all a/b/g channels */
- rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14);
- /* XXX default Tx power for 802.11a channels */
- memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14);
-#ifdef RUM_DEBUG
- for (i = 0; i < 14; i++)
- DPRINTF("Channel=%d Tx power=%d\n", i + 1, sc->txpow[i]);
-#endif
-
- /* read default values for BBP registers */
- rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
-#ifdef RUM_DEBUG
- for (i = 0; i < 14; i++) {
- if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
- continue;
- DPRINTF("BBP R%d=%02x\n", sc->bbp_prom[i].reg,
- sc->bbp_prom[i].val);
- }
-#endif
-}
-
-static int
-rum_bbp_init(struct rum_softc *sc)
-{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
- int i, ntries;
-
- /* wait for BBP to be ready */
- for (ntries = 0; ntries < 100; ntries++) {
- const uint8_t val = rum_bbp_read(sc, 0);
- if (val != 0 && val != 0xff)
- break;
- if (rum_pause(sc, hz / 100))
- break;
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev, "timeout waiting for BBP\n");
- return EIO;
- }
-
- /* initialize BBP registers to default values */
- for (i = 0; i < N(rum_def_bbp); i++)
- rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
-
- /* write vendor-specific BBP values (from EEPROM) */
- for (i = 0; i < 16; i++) {
- if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
- continue;
- rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
- }
-
- return 0;
-#undef N
-}
-
-static void
-rum_init_task(struct usb2_proc_msg *pm)
-{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
- struct rum_task *task = (struct rum_task *)pm;
- struct rum_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t tmp;
- usb2_error_t error;
- int i, ntries;
-
- RUM_LOCK_ASSERT(sc, MA_OWNED);
-
- rum_stop_task(pm);
-
- /* initialize MAC registers to default values */
- for (i = 0; i < N(rum_def_mac); i++)
- rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
-
- /* set host ready */
- rum_write(sc, RT2573_MAC_CSR1, 3);
- rum_write(sc, RT2573_MAC_CSR1, 0);
-
- /* wait for BBP/RF to wakeup */
- for (ntries = 0; ntries < 100; ntries++) {
- if (rum_read(sc, RT2573_MAC_CSR12) & 8)
- break;
- rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */
- if (rum_pause(sc, hz / 100))
- break;
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev,
- "timeout waiting for BBP/RF to wakeup\n");
- goto fail;
- }
-
- if ((error = rum_bbp_init(sc)) != 0)
- goto fail;
-
- /* select default channel */
- rum_select_band(sc, ic->ic_curchan);
- rum_select_antenna(sc);
- rum_set_chan(sc, ic->ic_curchan);
-
- /* clear STA registers */
- rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
-
- IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
- rum_set_macaddr(sc, ic->ic_myaddr);
-
- /* initialize ASIC */
- rum_write(sc, RT2573_MAC_CSR1, 4);
-
- /*
- * Allocate Tx and Rx xfer queues.
- */
- rum_setup_tx_list(sc);
-
- /* update Rx filter */
- tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
-
- tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR;
- if (ic->ic_opmode != IEEE80211_M_MONITOR) {
- tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR |
- RT2573_DROP_ACKCTS;
- if (ic->ic_opmode != IEEE80211_M_HOSTAP)
- tmp |= RT2573_DROP_TODS;
- if (!(ifp->if_flags & IFF_PROMISC))
- tmp |= RT2573_DROP_NOT_TO_ME;
- }
- rum_write(sc, RT2573_TXRX_CSR0, tmp);
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- usb2_transfer_set_stall(sc->sc_xfer[RUM_BULK_WR]);
- usb2_transfer_start(sc->sc_xfer[RUM_BULK_RD]);
- return;
-
-fail: rum_stop_task(pm);
-#undef N
-}
-
-static void
-rum_init(void *priv)
-{
- struct rum_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- RUM_LOCK(sc);
- rum_queue_command(sc, rum_init_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- RUM_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
-rum_stop_task(struct usb2_proc_msg *pm)
-{
- struct rum_task *task = (struct rum_task *)pm;
- struct rum_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- uint32_t tmp;
-
- RUM_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- RUM_UNLOCK(sc);
-
- /*
- * Drain the USB transfers, if not already drained:
- */
- usb2_transfer_drain(sc->sc_xfer[RUM_BULK_WR]);
- usb2_transfer_drain(sc->sc_xfer[RUM_BULK_RD]);
-
- RUM_LOCK(sc);
-
- rum_unsetup_tx_list(sc);
-
- /* disable Rx */
- tmp = rum_read(sc, RT2573_TXRX_CSR0);
- rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
-
- /* reset ASIC */
- rum_write(sc, RT2573_MAC_CSR1, 3);
- rum_write(sc, RT2573_MAC_CSR1, 0);
-}
-
-static int
-rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size)
-{
- struct usb2_device_request req;
- uint16_t reg = RT2573_MCU_CODE_BASE;
- usb2_error_t error;
-
- /* copy firmware image into NIC */
- for (; size >= 4; reg += 4, ucode += 4, size -= 4)
- rum_write(sc, reg, UGETDW(ucode));
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = RT2573_MCU_CNTL;
- USETW(req.wValue, RT2573_MCU_RUN);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- error = rum_do_request(sc, &req, NULL);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not run firmware: %s\n",
- usb2_errstr(error));
- }
- return error;
-}
-
-static int
-rum_prepare_beacon(struct rum_softc *sc, struct ieee80211vap *vap)
-{
- struct ieee80211com *ic = vap->iv_ic;
- const struct ieee80211_txparam *tp;
- struct rum_tx_desc desc;
- struct mbuf *m0;
-
- m0 = ieee80211_beacon_alloc(vap->iv_bss, &RUM_VAP(vap)->bo);
- if (m0 == NULL) {
- return ENOBUFS;
- }
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
- rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ,
- m0->m_pkthdr.len, tp->mgmtrate);
-
- /* copy the first 24 bytes of Tx descriptor into NIC memory */
- rum_write_multi(sc, RT2573_HW_BEACON_BASE0, (uint8_t *)&desc, 24);
-
- /* copy beacon header and payload into NIC memory */
- rum_write_multi(sc, RT2573_HW_BEACON_BASE0 + 24, mtod(m0, uint8_t *),
- m0->m_pkthdr.len);
-
- m_freem(m0);
-
- return 0;
-}
-
-static int
-rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
- const struct ieee80211_bpf_params *params)
-{
- struct ifnet *ifp = ni->ni_ic->ic_ifp;
- struct rum_softc *sc = ifp->if_softc;
-
- RUM_LOCK(sc);
- /* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- RUM_UNLOCK(sc);
- m_freem(m);
- ieee80211_free_node(ni);
- return ENETDOWN;
- }
- if (sc->tx_nfree == 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- RUM_UNLOCK(sc);
- m_freem(m);
- ieee80211_free_node(ni);
- return EIO;
- }
-
- ifp->if_opackets++;
-
- if (params == NULL) {
- /*
- * Legacy path; interpret frame contents to decide
- * precisely how to send the frame.
- */
- if (rum_tx_mgt(sc, m, ni) != 0)
- goto bad;
- } else {
- /*
- * Caller supplied explicit parameters to use in
- * sending the frame.
- */
- if (rum_tx_raw(sc, m, ni, params) != 0)
- goto bad;
- }
- RUM_UNLOCK(sc);
-
- return 0;
-bad:
- ifp->if_oerrors++;
- RUM_UNLOCK(sc);
- ieee80211_free_node(ni);
- return EIO;
-}
-
-static void
-rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct rum_vap *rvp = RUM_VAP(vap);
-
- /* clear statistic registers (STA_CSR0 to STA_CSR5) */
- rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
-
- ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni);
-
- usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
-}
-
-static void
-rum_amrr_timeout(void *arg)
-{
- struct rum_vap *rvp = arg;
- struct rum_softc *sc = rvp->sc;
-
- rum_queue_command(sc, rum_amrr_task,
- &rvp->amrr_task[0].hdr, &rvp->amrr_task[1].hdr);
-}
-
-static void
-rum_amrr_task(struct usb2_proc_msg *pm)
-{
- struct rum_task *task = (struct rum_task *)pm;
- struct rum_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct rum_vap *rvp = RUM_VAP(vap);
- struct ieee80211_node *ni = vap->iv_bss;
- int ok, fail;
-
- /* read and clear statistic registers (STA_CSR0 to STA_CSR10) */
- rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof(sc->sta));
-
- ok = (le32toh(sc->sta[4]) >> 16) + /* TX ok w/o retry */
- (le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ retry */
- fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */
-
- ieee80211_amrr_tx_update(&RUM_NODE(ni)->amn,
- ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail);
- (void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn);
-
- ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */
-
- usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
-}
-
-/* ARGUSED */
-static struct ieee80211_node *
-rum_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct rum_node *rn;
-
- rn = malloc(sizeof(struct rum_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return rn != NULL ? &rn->ni : NULL;
-}
-
-static void
-rum_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni);
-}
-
-static void
-rum_scan_start(struct ieee80211com *ic)
-{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
-
- RUM_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = RUM_SCAN_START;
- rum_queue_command(sc, rum_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
- RUM_UNLOCK(sc);
-
-}
-
-static void
-rum_scan_end(struct ieee80211com *ic)
-{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
-
- RUM_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = RUM_SCAN_END;
- rum_queue_command(sc, rum_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
- RUM_UNLOCK(sc);
-
-}
-
-static void
-rum_set_channel(struct ieee80211com *ic)
-{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
-
- RUM_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = RUM_SET_CHANNEL;
- sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
- rum_queue_command(sc, rum_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
- RUM_UNLOCK(sc);
-}
-
-static void
-rum_scantask(struct usb2_proc_msg *pm)
-{
- struct rum_task *task = (struct rum_task *)pm;
- struct rum_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t tmp;
-
- RUM_LOCK_ASSERT(sc, MA_OWNED);
-
- switch (sc->sc_scan_action) {
- case RUM_SCAN_START:
- /* abort TSF synchronization */
- tmp = rum_read(sc, RT2573_TXRX_CSR9);
- rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
- rum_set_bssid(sc, ifp->if_broadcastaddr);
- break;
-
- case RUM_SET_CHANNEL:
- rum_set_chan(sc, ic->ic_curchan);
- break;
-
- default: /* RUM_SCAN_END */
- rum_enable_tsf_sync(sc);
- rum_set_bssid(sc, sc->sc_bssid);
- break;
- }
-}
-
-static int
-rum_get_rssi(struct rum_softc *sc, uint8_t raw)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- int lna, agc, rssi;
-
- lna = (raw >> 5) & 0x3;
- agc = raw & 0x1f;
-
- if (lna == 0) {
- /*
- * No RSSI mapping
- *
- * NB: Since RSSI is relative to noise floor, -1 is
- * adequate for caller to know error happened.
- */
- return -1;
- }
-
- rssi = (2 * agc) - RT2573_NOISE_FLOOR;
-
- if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
- rssi += sc->rssi_2ghz_corr;
-
- if (lna == 1)
- rssi -= 64;
- else if (lna == 2)
- rssi -= 74;
- else if (lna == 3)
- rssi -= 90;
- } else {
- rssi += sc->rssi_5ghz_corr;
-
- if (!sc->ext_5ghz_lna && lna != 1)
- rssi += 4;
-
- if (lna == 1)
- rssi -= 64;
- else if (lna == 2)
- rssi -= 86;
- else if (lna == 3)
- rssi -= 100;
- }
- return rssi;
-}
-
-static int
-rum_pause(struct rum_softc *sc, int timeout)
-{
- if (usb2_proc_is_gone(&sc->sc_tq))
- return (1);
-
- usb2_pause_mtx(&sc->sc_mtx, timeout);
- return (0);
-}
-
-static void
-rum_queue_command(struct rum_softc *sc, usb2_proc_callback_t *fn,
- struct usb2_proc_msg *t0, struct usb2_proc_msg *t1)
-{
- struct rum_task *task;
-
- RUM_LOCK_ASSERT(sc, MA_OWNED);
-
- if (usb2_proc_is_gone(&sc->sc_tq)) {
- DPRINTF("proc is gone\n");
- return; /* nothing to do */
- }
- /*
- * NOTE: The task cannot get executed before we drop the
- * "sc_mtx" mutex. It is safe to update fields in the message
- * structure after that the message got queued.
- */
- task = (struct rum_task *)
- usb2_proc_msignal(&sc->sc_tq, t0, t1);
-
- /* Setup callback and softc pointers */
- task->hdr.pm_callback = fn;
- task->sc = sc;
-
- /*
- * Init and stop must be synchronous!
- */
- if ((fn == rum_init_task) || (fn == rum_stop_task))
- usb2_proc_mwait(&sc->sc_tq, t0, t1);
-}
-
-static device_method_t rum_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, rum_match),
- DEVMETHOD(device_attach, rum_attach),
- DEVMETHOD(device_detach, rum_detach),
-
- { 0, 0 }
-};
-
-static driver_t rum_driver = {
- .name = "rum",
- .methods = rum_methods,
- .size = sizeof(struct rum_softc),
-};
-
-static devclass_t rum_devclass;
-
-DRIVER_MODULE(rum, ushub, rum_driver, rum_devclass, NULL, 0);
diff --git a/sys/dev/usb2/wlan/if_rumfw.h b/sys/dev/usb2/wlan/if_rumfw.h
deleted file mode 100644
index 0f08674..0000000
--- a/sys/dev/usb2/wlan/if_rumfw.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005-2006, Ralink Technology, Corp.
- * Paul Lin <paul_lin@ralinktech.com.tw>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file contains the loadable 8051 microcode for the Ralink RT2573
- * chipset.
- */
-
-static const uint8_t rt2573_ucode[] = {
- 0x02, 0x13, 0x25, 0x12, 0x10, 0xd9, 0x02, 0x12, 0x58, 0x02, 0x13,
- 0x58, 0x02, 0x13, 0x5a, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0x12, 0x13,
- 0x5c, 0xd0, 0xd0, 0x22, 0x02, 0x14, 0x5c, 0x02, 0x14, 0xe7, 0xed,
- 0x4c, 0x70, 0x44, 0x90, 0x01, 0xa8, 0x74, 0x80, 0xf0, 0xef, 0x30,
- 0xe5, 0x07, 0xe4, 0x90, 0x00, 0x0f, 0xf0, 0x80, 0x2c, 0xe5, 0x40,
- 0x24, 0xc0, 0x60, 0x13, 0x24, 0xc0, 0x60, 0x16, 0x24, 0xc0, 0x60,
- 0x19, 0x24, 0xc0, 0x70, 0x1a, 0xe4, 0x90, 0x00, 0x0b, 0xf0, 0x80,
- 0x13, 0xe4, 0x90, 0x00, 0x13, 0xf0, 0x80, 0x0c, 0xe4, 0x90, 0x00,
- 0x1b, 0xf0, 0x80, 0x05, 0xe4, 0x90, 0x00, 0x23, 0xf0, 0xe4, 0x90,
- 0x01, 0xa8, 0xf0, 0xd3, 0x22, 0x90, 0x02, 0x02, 0xed, 0xf0, 0x90,
- 0x02, 0x01, 0xef, 0xf0, 0xd3, 0x22, 0xef, 0x24, 0xc0, 0x60, 0x1f,
- 0x24, 0xc0, 0x60, 0x2e, 0x24, 0xc0, 0x60, 0x3d, 0x24, 0xc0, 0x70,
- 0x53, 0x90, 0x00, 0x0b, 0xe0, 0x30, 0xe1, 0x02, 0xc3, 0x22, 0x90,
- 0x00, 0x09, 0xe0, 0xfe, 0x90, 0x00, 0x08, 0x80, 0x37, 0x90, 0x00,
- 0x13, 0xe0, 0x30, 0xe1, 0x02, 0xc3, 0x22, 0x90, 0x00, 0x11, 0xe0,
- 0xfe, 0x90, 0x00, 0x10, 0x80, 0x24, 0x90, 0x00, 0x1b, 0xe0, 0x30,
- 0xe1, 0x02, 0xc3, 0x22, 0x90, 0x00, 0x19, 0xe0, 0xfe, 0x90, 0x00,
- 0x18, 0x80, 0x11, 0x90, 0x00, 0x23, 0xe0, 0x30, 0xe1, 0x02, 0xc3,
- 0x22, 0x90, 0x00, 0x21, 0xe0, 0xfe, 0x90, 0x00, 0x20, 0xe0, 0xfd,
- 0xee, 0xf5, 0x37, 0xed, 0xf5, 0x38, 0xd3, 0x22, 0x30, 0x09, 0x20,
- 0x20, 0x04, 0x0b, 0x90, 0x02, 0x08, 0xe0, 0x54, 0x0f, 0x70, 0x03,
- 0x02, 0x12, 0x57, 0xc2, 0x09, 0x90, 0x02, 0x00, 0xe0, 0x44, 0x04,
- 0xf0, 0x74, 0x04, 0x12, 0x0c, 0x3a, 0xc2, 0x04, 0xc2, 0x07, 0x90,
- 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80, 0xf6, 0x90, 0x03,
- 0x26, 0xe0, 0x20, 0xe2, 0x03, 0x02, 0x12, 0x57, 0x90, 0x02, 0x08,
- 0xe0, 0x70, 0x1b, 0x20, 0x07, 0x03, 0x02, 0x12, 0x57, 0x90, 0x03,
- 0x12, 0xe0, 0x64, 0x22, 0x60, 0x03, 0x02, 0x12, 0x57, 0xd2, 0x09,
- 0xc2, 0x07, 0x74, 0x02, 0x12, 0x0c, 0x3a, 0x22, 0x90, 0x02, 0x03,
- 0xe0, 0x30, 0xe4, 0x47, 0x20, 0x06, 0x44, 0xe5, 0x3c, 0x60, 0x34,
- 0xe5, 0x40, 0x24, 0xc0, 0x60, 0x14, 0x24, 0xc0, 0x60, 0x18, 0x24,
- 0xc0, 0x60, 0x1c, 0x24, 0xc0, 0x70, 0x22, 0x90, 0x00, 0x0b, 0xe0,
- 0x30, 0xe1, 0x1b, 0x22, 0x90, 0x00, 0x13, 0xe0, 0x30, 0xe1, 0x13,
- 0x22, 0x90, 0x00, 0x1b, 0xe0, 0x30, 0xe1, 0x0b, 0x22, 0x90, 0x00,
- 0x23, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x12, 0x57, 0x90, 0x02, 0x03,
- 0x74, 0x01, 0xf0, 0x00, 0xe0, 0x54, 0xc0, 0xf5, 0x40, 0xe5, 0x40,
- 0x24, 0xc0, 0x60, 0x20, 0x24, 0xc0, 0x60, 0x30, 0x24, 0xc0, 0x60,
- 0x40, 0x24, 0xc0, 0x70, 0x56, 0x90, 0x00, 0x0b, 0xe0, 0x30, 0xe1,
- 0x03, 0x02, 0x12, 0x57, 0x90, 0x00, 0x09, 0xe0, 0xfe, 0x90, 0x00,
- 0x08, 0x80, 0x3a, 0x90, 0x00, 0x13, 0xe0, 0x30, 0xe1, 0x03, 0x02,
- 0x12, 0x57, 0x90, 0x00, 0x11, 0xe0, 0xfe, 0x90, 0x00, 0x10, 0x80,
- 0x26, 0x90, 0x00, 0x1b, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x12, 0x57,
- 0x90, 0x00, 0x19, 0xe0, 0xfe, 0x90, 0x00, 0x18, 0x80, 0x12, 0x90,
- 0x00, 0x23, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x12, 0x57, 0x90, 0x00,
- 0x21, 0xe0, 0xfe, 0x90, 0x00, 0x20, 0xe0, 0xfd, 0xee, 0xf5, 0x37,
- 0xed, 0xf5, 0x38, 0x90, 0x03, 0x27, 0x74, 0x82, 0xf0, 0x90, 0x02,
- 0x01, 0xe5, 0x40, 0xf0, 0x90, 0x02, 0x06, 0xe0, 0xf5, 0x3c, 0xc3,
- 0xe5, 0x38, 0x95, 0x3a, 0xe5, 0x37, 0x95, 0x39, 0x50, 0x21, 0xe5,
- 0x40, 0x44, 0x05, 0xff, 0xe5, 0x37, 0xa2, 0xe7, 0x13, 0xfc, 0xe5,
- 0x38, 0x13, 0xfd, 0x12, 0x10, 0x20, 0xe5, 0x3c, 0x30, 0xe2, 0x04,
- 0xd2, 0x06, 0x80, 0x02, 0xc2, 0x06, 0x53, 0x3c, 0x01, 0x22, 0x30,
- 0x0b, 0x07, 0xe4, 0x90, 0x02, 0x02, 0xf0, 0x80, 0x06, 0x90, 0x02,
- 0x02, 0x74, 0x20, 0xf0, 0xe5, 0x40, 0x44, 0x01, 0x90, 0x02, 0x01,
- 0xf0, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80, 0xf6,
- 0x90, 0x03, 0x27, 0x74, 0x02, 0xf0, 0xaf, 0x40, 0x12, 0x10, 0x74,
- 0x40, 0xa5, 0x00, 0x80, 0xf6, 0x22, 0x90, 0x7f, 0xf8, 0xe0, 0xb4,
- 0x02, 0x03, 0x12, 0x16, 0x38, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0,
- 0x03, 0x00, 0x80, 0xf6, 0x90, 0x03, 0x26, 0xe0, 0x20, 0xe1, 0x07,
- 0xe5, 0x3b, 0x70, 0x03, 0x02, 0x13, 0x24, 0xe5, 0x3b, 0x70, 0x15,
- 0x90, 0x03, 0x24, 0xe0, 0x75, 0xf0, 0x40, 0xa4, 0xf5, 0x36, 0x85,
- 0xf0, 0x35, 0x75, 0x24, 0x83, 0x75, 0x3b, 0x01, 0x80, 0x03, 0x75,
- 0x24, 0x03, 0xd3, 0xe5, 0x36, 0x95, 0x3a, 0xe5, 0x35, 0x95, 0x39,
- 0x40, 0x36, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80,
- 0xf6, 0x90, 0x03, 0x27, 0xe5, 0x24, 0xf0, 0x90, 0x00, 0x0f, 0xe0,
- 0x30, 0xe1, 0x04, 0x30, 0x0e, 0xf6, 0x22, 0x30, 0x0b, 0x07, 0xe4,
- 0x90, 0x02, 0x02, 0xf0, 0x80, 0x06, 0x90, 0x02, 0x02, 0x74, 0x20,
- 0xf0, 0x90, 0x02, 0x01, 0x74, 0x21, 0xf0, 0x75, 0x24, 0x03, 0x80,
- 0x3d, 0xe5, 0x35, 0xa2, 0xe7, 0x13, 0xfe, 0xe5, 0x36, 0x13, 0xfd,
- 0xac, 0x06, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80,
- 0xf6, 0x90, 0x03, 0x27, 0xe5, 0x24, 0xf0, 0x90, 0x00, 0x0f, 0xe0,
- 0x30, 0xe1, 0x04, 0x30, 0x0e, 0xf6, 0x22, 0x7f, 0x25, 0x12, 0x10,
- 0x20, 0xe5, 0x36, 0xb5, 0x3a, 0x08, 0xe5, 0x35, 0xb5, 0x39, 0x03,
- 0x00, 0x80, 0x04, 0xe4, 0xf5, 0x3b, 0x22, 0xc3, 0xe5, 0x36, 0x95,
- 0x3a, 0xf5, 0x36, 0xe5, 0x35, 0x95, 0x39, 0xf5, 0x35, 0x02, 0x12,
- 0x96, 0x22, 0x75, 0xa8, 0x0f, 0x90, 0x03, 0x06, 0x74, 0x01, 0xf0,
- 0x90, 0x03, 0x07, 0xf0, 0x90, 0x03, 0x08, 0x04, 0xf0, 0x90, 0x03,
- 0x09, 0x74, 0x6c, 0xf0, 0x90, 0x03, 0x0a, 0x74, 0xff, 0xf0, 0x90,
- 0x03, 0x02, 0x74, 0x1f, 0xf0, 0x90, 0x03, 0x00, 0x74, 0x04, 0xf0,
- 0x90, 0x03, 0x25, 0x74, 0x31, 0xf0, 0xd2, 0xaf, 0x22, 0x00, 0x22,
- 0x00, 0x22, 0x90, 0x03, 0x05, 0xe0, 0x30, 0xe0, 0x0b, 0xe0, 0x44,
- 0x01, 0xf0, 0x30, 0x09, 0x02, 0xd2, 0x04, 0xc2, 0x07, 0x22, 0x8d,
- 0x24, 0xa9, 0x07, 0x90, 0x7f, 0xfc, 0xe0, 0x75, 0x25, 0x00, 0xf5,
- 0x26, 0xa3, 0xe0, 0x75, 0x27, 0x00, 0xf5, 0x28, 0xa3, 0xe0, 0xff,
- 0xa3, 0xe0, 0xfd, 0xe9, 0x30, 0xe5, 0x14, 0x54, 0xc0, 0x60, 0x05,
- 0x43, 0x05, 0x03, 0x80, 0x03, 0x53, 0x05, 0xfc, 0xef, 0x54, 0x3f,
- 0x44, 0x40, 0xff, 0x80, 0x06, 0x53, 0x07, 0x3f, 0x53, 0x05, 0xf0,
- 0xe5, 0x24, 0x30, 0xe0, 0x05, 0x43, 0x05, 0x10, 0x80, 0x03, 0x53,
- 0x05, 0xef, 0x90, 0x7f, 0xfc, 0xe5, 0x26, 0xf0, 0xa3, 0xe5, 0x28,
- 0xf0, 0xa3, 0xef, 0xf0, 0xa3, 0xed, 0xf0, 0x22, 0x8f, 0x24, 0xa9,
- 0x05, 0x90, 0x7f, 0xfc, 0xe0, 0x75, 0x25, 0x00, 0xf5, 0x26, 0xa3,
- 0xe0, 0x75, 0x27, 0x00, 0xf5, 0x28, 0xa3, 0xe0, 0xff, 0xa3, 0xe0,
- 0xfd, 0xe5, 0x24, 0x30, 0xe5, 0x0b, 0x43, 0x05, 0x0f, 0xef, 0x54,
- 0x3f, 0x44, 0x40, 0xff, 0x80, 0x06, 0x53, 0x05, 0xf0, 0x53, 0x07,
- 0x3f, 0xe9, 0x30, 0xe0, 0x05, 0x43, 0x05, 0x10, 0x80, 0x03, 0x53,
- 0x05, 0xef, 0x90, 0x7f, 0xfc, 0xe5, 0x26, 0xf0, 0xa3, 0xe5, 0x28,
- 0xf0, 0xa3, 0xef, 0xf0, 0xa3, 0xed, 0xf0, 0x22, 0x90, 0x7f, 0xfc,
- 0xe0, 0xf9, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfb,
- 0xef, 0x30, 0xe5, 0x0b, 0x43, 0x03, 0x0f, 0xec, 0x54, 0x3f, 0x44,
- 0x40, 0xfc, 0x80, 0x06, 0x53, 0x03, 0xf0, 0x53, 0x04, 0x3f, 0xed,
- 0x30, 0xe0, 0x07, 0xef, 0x54, 0xc0, 0x60, 0x07, 0x80, 0x0a, 0xef,
- 0x54, 0xc0, 0x60, 0x05, 0x43, 0x03, 0x10, 0x80, 0x03, 0x53, 0x03,
- 0xef, 0x90, 0x7f, 0xfc, 0xe9, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xec,
- 0xf0, 0xa3, 0xeb, 0xf0, 0x22, 0xe5, 0x4b, 0xfd, 0x54, 0x1f, 0x90,
- 0x7f, 0xf8, 0xf0, 0xe5, 0x4a, 0xf5, 0x09, 0x90, 0x30, 0x38, 0xe0,
- 0x90, 0x7f, 0xfc, 0xf0, 0x90, 0x30, 0x39, 0xe0, 0x90, 0x7f, 0xfd,
- 0xf0, 0x90, 0x30, 0x3a, 0xe0, 0x90, 0x7f, 0xfe, 0xf0, 0x90, 0x30,
- 0x3b, 0xe0, 0x90, 0x7f, 0xff, 0xf0, 0xed, 0x30, 0xe5, 0x0c, 0x54,
- 0xc0, 0x60, 0x0d, 0x90, 0x7f, 0xf0, 0xe5, 0x47, 0xf0, 0x80, 0x05,
- 0xe4, 0x90, 0x7f, 0xf0, 0xf0, 0x90, 0x7f, 0xf8, 0xe0, 0x14, 0x60,
- 0x08, 0x24, 0xfe, 0x60, 0x0d, 0x24, 0x03, 0x80, 0x12, 0xaf, 0x05,
- 0xad, 0x09, 0x12, 0x13, 0xc5, 0x80, 0x10, 0xaf, 0x05, 0xad, 0x09,
- 0x12, 0x14, 0x12, 0x80, 0x07, 0xaf, 0x05, 0xad, 0x09, 0x12, 0x13,
- 0x6f, 0x90, 0x7f, 0xfc, 0xe0, 0x90, 0x30, 0x38, 0xf0, 0x90, 0x7f,
- 0xfd, 0xe0, 0x90, 0x30, 0x39, 0xf0, 0x90, 0x7f, 0xfe, 0xe0, 0x90,
- 0x30, 0x3a, 0xf0, 0x90, 0x7f, 0xff, 0xe0, 0x90, 0x30, 0x3b, 0xf0,
- 0x22, 0xe5, 0x4b, 0x64, 0x01, 0x60, 0x03, 0x02, 0x15, 0x71, 0xf5,
- 0x4b, 0xe5, 0x44, 0x45, 0x43, 0x70, 0x03, 0x02, 0x15, 0xa0, 0x12,
- 0x0c, 0x14, 0x12, 0x0b, 0x86, 0x50, 0xfb, 0x90, 0x00, 0x00, 0xe0,
- 0xf5, 0x25, 0x12, 0x15, 0xb4, 0xc2, 0x92, 0xe4, 0xf5, 0x24, 0xe5,
- 0x24, 0xc3, 0x95, 0x25, 0x50, 0x49, 0x7e, 0x00, 0x7f, 0x4c, 0x74,
- 0x40, 0x25, 0x24, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xad, 0x82, 0xfc,
- 0x75, 0x2b, 0x02, 0x7b, 0x10, 0x12, 0x07, 0x1e, 0xc2, 0x93, 0x12,
- 0x15, 0xa1, 0x7d, 0xa0, 0x12, 0x15, 0xd0, 0xe5, 0x24, 0x54, 0x0f,
- 0x24, 0x4c, 0xf8, 0xe6, 0xfd, 0xaf, 0x4b, 0xae, 0x4a, 0x12, 0x15,
- 0xd8, 0x05, 0x4b, 0xe5, 0x4b, 0x70, 0x02, 0x05, 0x4a, 0x12, 0x0a,
- 0x5f, 0x05, 0x24, 0xe5, 0x24, 0x54, 0x0f, 0x70, 0xd5, 0xd2, 0x93,
- 0x80, 0xb0, 0xc3, 0xe5, 0x44, 0x95, 0x25, 0xf5, 0x44, 0xe5, 0x43,
- 0x94, 0x00, 0xf5, 0x43, 0x02, 0x14, 0xf2, 0x12, 0x15, 0xb4, 0xc2,
- 0x93, 0xc2, 0x92, 0x12, 0x15, 0xa1, 0x7d, 0x80, 0x12, 0x15, 0xd0,
- 0x7d, 0xaa, 0x74, 0x55, 0xff, 0xfe, 0x12, 0x15, 0xd8, 0x7d, 0x55,
- 0x7f, 0xaa, 0x7e, 0x2a, 0x12, 0x15, 0xd8, 0x7d, 0x30, 0xaf, 0x4b,
- 0xae, 0x4a, 0x12, 0x15, 0xd8, 0x12, 0x0a, 0x5f, 0xd2, 0x93, 0x22,
- 0x7d, 0xaa, 0x74, 0x55, 0xff, 0xfe, 0x12, 0x15, 0xd8, 0x7d, 0x55,
- 0x7f, 0xaa, 0x7e, 0x2a, 0x12, 0x15, 0xd8, 0x22, 0xad, 0x47, 0x7f,
- 0x34, 0x7e, 0x30, 0x12, 0x15, 0xd8, 0x7d, 0xff, 0x7f, 0x35, 0x7e,
- 0x30, 0x12, 0x15, 0xd8, 0xe4, 0xfd, 0x7f, 0x37, 0x7e, 0x30, 0x12,
- 0x15, 0xd8, 0x22, 0x74, 0x55, 0xff, 0xfe, 0x12, 0x15, 0xd8, 0x22,
- 0x8f, 0x82, 0x8e, 0x83, 0xed, 0xf0, 0x22, 0xe4, 0xfc, 0x90, 0x7f,
- 0xf0, 0xe0, 0xaf, 0x09, 0x14, 0x60, 0x14, 0x14, 0x60, 0x15, 0x14,
- 0x60, 0x16, 0x14, 0x60, 0x17, 0x14, 0x60, 0x18, 0x24, 0x05, 0x70,
- 0x16, 0xe4, 0xfc, 0x80, 0x12, 0x7c, 0x01, 0x80, 0x0e, 0x7c, 0x03,
- 0x80, 0x0a, 0x7c, 0x07, 0x80, 0x06, 0x7c, 0x0f, 0x80, 0x02, 0x7c,
- 0x1f, 0xec, 0x6f, 0xf4, 0x54, 0x1f, 0xfc, 0x90, 0x30, 0x34, 0xe0,
- 0x54, 0xe0, 0x4c, 0xfd, 0xa3, 0xe0, 0xfc, 0x43, 0x04, 0x1f, 0x7f,
- 0x34, 0x7e, 0x30, 0x12, 0x15, 0xd8, 0xad, 0x04, 0x0f, 0x12, 0x15,
- 0xd8, 0xe4, 0xfd, 0x7f, 0x37, 0x02, 0x15, 0xd8, 0x02, 0x15, 0xdf,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
- 0x29, 0xe9
-};
diff --git a/sys/dev/usb2/wlan/if_rumreg.h b/sys/dev/usb2/wlan/if_rumreg.h
deleted file mode 100644
index 75a51bc..0000000
--- a/sys/dev/usb2/wlan/if_rumreg.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr>
- * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define RT2573_NOISE_FLOOR -95
-
-#define RT2573_TX_DESC_SIZE (sizeof (struct rum_tx_desc))
-#define RT2573_RX_DESC_SIZE (sizeof (struct rum_rx_desc))
-
-#define RT2573_CONFIG_NO 1
-#define RT2573_IFACE_INDEX 0
-
-#define RT2573_MCU_CNTL 0x01
-#define RT2573_WRITE_MAC 0x02
-#define RT2573_READ_MAC 0x03
-#define RT2573_WRITE_MULTI_MAC 0x06
-#define RT2573_READ_MULTI_MAC 0x07
-#define RT2573_READ_EEPROM 0x09
-#define RT2573_WRITE_LED 0x0a
-
-/*
- * Control and status registers.
- */
-#define RT2573_AIFSN_CSR 0x0400
-#define RT2573_CWMIN_CSR 0x0404
-#define RT2573_CWMAX_CSR 0x0408
-#define RT2573_MCU_CODE_BASE 0x0800
-#define RT2573_HW_BEACON_BASE0 0x2400
-#define RT2573_MAC_CSR0 0x3000
-#define RT2573_MAC_CSR1 0x3004
-#define RT2573_MAC_CSR2 0x3008
-#define RT2573_MAC_CSR3 0x300c
-#define RT2573_MAC_CSR4 0x3010
-#define RT2573_MAC_CSR5 0x3014
-#define RT2573_MAC_CSR6 0x3018
-#define RT2573_MAC_CSR7 0x301c
-#define RT2573_MAC_CSR8 0x3020
-#define RT2573_MAC_CSR9 0x3024
-#define RT2573_MAC_CSR10 0x3028
-#define RT2573_MAC_CSR11 0x302c
-#define RT2573_MAC_CSR12 0x3030
-#define RT2573_MAC_CSR13 0x3034
-#define RT2573_MAC_CSR14 0x3038
-#define RT2573_MAC_CSR15 0x303c
-#define RT2573_TXRX_CSR0 0x3040
-#define RT2573_TXRX_CSR1 0x3044
-#define RT2573_TXRX_CSR2 0x3048
-#define RT2573_TXRX_CSR3 0x304c
-#define RT2573_TXRX_CSR4 0x3050
-#define RT2573_TXRX_CSR5 0x3054
-#define RT2573_TXRX_CSR6 0x3058
-#define RT2573_TXRX_CSR7 0x305c
-#define RT2573_TXRX_CSR8 0x3060
-#define RT2573_TXRX_CSR9 0x3064
-#define RT2573_TXRX_CSR10 0x3068
-#define RT2573_TXRX_CSR11 0x306c
-#define RT2573_TXRX_CSR12 0x3070
-#define RT2573_TXRX_CSR13 0x3074
-#define RT2573_TXRX_CSR14 0x3078
-#define RT2573_TXRX_CSR15 0x307c
-#define RT2573_PHY_CSR0 0x3080
-#define RT2573_PHY_CSR1 0x3084
-#define RT2573_PHY_CSR2 0x3088
-#define RT2573_PHY_CSR3 0x308c
-#define RT2573_PHY_CSR4 0x3090
-#define RT2573_PHY_CSR5 0x3094
-#define RT2573_PHY_CSR6 0x3098
-#define RT2573_PHY_CSR7 0x309c
-#define RT2573_SEC_CSR0 0x30a0
-#define RT2573_SEC_CSR1 0x30a4
-#define RT2573_SEC_CSR2 0x30a8
-#define RT2573_SEC_CSR3 0x30ac
-#define RT2573_SEC_CSR4 0x30b0
-#define RT2573_SEC_CSR5 0x30b4
-#define RT2573_STA_CSR0 0x30c0
-#define RT2573_STA_CSR1 0x30c4
-#define RT2573_STA_CSR2 0x30c8
-#define RT2573_STA_CSR3 0x30cc
-#define RT2573_STA_CSR4 0x30d0
-#define RT2573_STA_CSR5 0x30d4
-
-
-/* possible flags for register RT2573_MAC_CSR1 */
-#define RT2573_RESET_ASIC (1 << 0)
-#define RT2573_RESET_BBP (1 << 1)
-#define RT2573_HOST_READY (1 << 2)
-
-/* possible flags for register MAC_CSR5 */
-#define RT2573_ONE_BSSID 3
-
-/* possible flags for register TXRX_CSR0 */
-/* Tx filter flags are in the low 16 bits */
-#define RT2573_AUTO_TX_SEQ (1 << 15)
-/* Rx filter flags are in the high 16 bits */
-#define RT2573_DISABLE_RX (1 << 16)
-#define RT2573_DROP_CRC_ERROR (1 << 17)
-#define RT2573_DROP_PHY_ERROR (1 << 18)
-#define RT2573_DROP_CTL (1 << 19)
-#define RT2573_DROP_NOT_TO_ME (1 << 20)
-#define RT2573_DROP_TODS (1 << 21)
-#define RT2573_DROP_VER_ERROR (1 << 22)
-#define RT2573_DROP_MULTICAST (1 << 23)
-#define RT2573_DROP_BROADCAST (1 << 24)
-#define RT2573_DROP_ACKCTS (1 << 25)
-
-/* possible flags for register TXRX_CSR4 */
-#define RT2573_SHORT_PREAMBLE (1 << 18)
-#define RT2573_MRR_ENABLED (1 << 19)
-#define RT2573_MRR_CCK_FALLBACK (1 << 22)
-
-/* possible flags for register TXRX_CSR9 */
-#define RT2573_TSF_TICKING (1 << 16)
-#define RT2573_TSF_MODE(x) (((x) & 0x3) << 17)
-/* TBTT stands for Target Beacon Transmission Time */
-#define RT2573_ENABLE_TBTT (1 << 19)
-#define RT2573_GENERATE_BEACON (1 << 20)
-
-/* possible flags for register PHY_CSR0 */
-#define RT2573_PA_PE_2GHZ (1 << 16)
-#define RT2573_PA_PE_5GHZ (1 << 17)
-
-/* possible flags for register PHY_CSR3 */
-#define RT2573_BBP_READ (1 << 15)
-#define RT2573_BBP_BUSY (1 << 16)
-/* possible flags for register PHY_CSR4 */
-#define RT2573_RF_20BIT (20 << 24)
-#define RT2573_RF_BUSY (1 << 31)
-
-/* LED values */
-#define RT2573_LED_RADIO (1 << 8)
-#define RT2573_LED_G (1 << 9)
-#define RT2573_LED_A (1 << 10)
-#define RT2573_LED_ON 0x1e1e
-#define RT2573_LED_OFF 0x0
-
-#define RT2573_MCU_RUN (1 << 3)
-
-#define RT2573_SMART_MODE (1 << 0)
-
-#define RT2573_BBPR94_DEFAULT 6
-
-#define RT2573_BBP_WRITE (1 << 15)
-
-/* dual-band RF */
-#define RT2573_RF_5226 1
-#define RT2573_RF_5225 3
-/* single-band RF */
-#define RT2573_RF_2528 2
-#define RT2573_RF_2527 4
-
-#define RT2573_BBP_VERSION 0
-
-struct rum_tx_desc {
- uint32_t flags;
-#define RT2573_TX_BURST (1 << 0)
-#define RT2573_TX_VALID (1 << 1)
-#define RT2573_TX_MORE_FRAG (1 << 2)
-#define RT2573_TX_NEED_ACK (1 << 3)
-#define RT2573_TX_TIMESTAMP (1 << 4)
-#define RT2573_TX_OFDM (1 << 5)
-#define RT2573_TX_IFS_SIFS (1 << 6)
-#define RT2573_TX_LONG_RETRY (1 << 7)
-
- uint16_t wme;
-#define RT2573_QID(v) (v)
-#define RT2573_AIFSN(v) ((v) << 4)
-#define RT2573_LOGCWMIN(v) ((v) << 8)
-#define RT2573_LOGCWMAX(v) ((v) << 12)
-
- uint16_t xflags;
-#define RT2573_TX_HWSEQ (1 << 12)
-
- uint8_t plcp_signal;
- uint8_t plcp_service;
-#define RT2573_PLCP_LENGEXT 0x80
-
- uint8_t plcp_length_lo;
- uint8_t plcp_length_hi;
-
- uint32_t iv;
- uint32_t eiv;
-
- uint8_t offset;
- uint8_t qid;
- uint8_t txpower;
-#define RT2573_DEFAULT_TXPOWER 0
-
- uint8_t reserved;
-} __packed;
-
-struct rum_rx_desc {
- uint32_t flags;
-#define RT2573_RX_BUSY (1 << 0)
-#define RT2573_RX_DROP (1 << 1)
-#define RT2573_RX_CRC_ERROR (1 << 6)
-#define RT2573_RX_OFDM (1 << 7)
-
- uint8_t rate;
- uint8_t rssi;
- uint8_t reserved1;
- uint8_t offset;
- uint32_t iv;
- uint32_t eiv;
- uint32_t reserved2[2];
-} __packed;
-
-#define RT2573_RF1 0
-#define RT2573_RF2 2
-#define RT2573_RF3 1
-#define RT2573_RF4 3
-
-#define RT2573_EEPROM_MACBBP 0x0000
-#define RT2573_EEPROM_ADDRESS 0x0004
-#define RT2573_EEPROM_ANTENNA 0x0020
-#define RT2573_EEPROM_CONFIG2 0x0022
-#define RT2573_EEPROM_BBP_BASE 0x0026
-#define RT2573_EEPROM_TXPOWER 0x0046
-#define RT2573_EEPROM_FREQ_OFFSET 0x005e
-#define RT2573_EEPROM_RSSI_2GHZ_OFFSET 0x009a
-#define RT2573_EEPROM_RSSI_5GHZ_OFFSET 0x009c
diff --git a/sys/dev/usb2/wlan/if_rumvar.h b/sys/dev/usb2/wlan/if_rumvar.h
deleted file mode 100644
index 1b58dc4..0000000
--- a/sys/dev/usb2/wlan/if_rumvar.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr>
- * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define RUM_TX_LIST_COUNT 8
-
-struct rum_rx_radiotap_header {
- struct ieee80211_radiotap_header wr_ihdr;
- uint8_t wr_flags;
- uint8_t wr_rate;
- uint16_t wr_chan_freq;
- uint16_t wr_chan_flags;
- uint8_t wr_antenna;
- uint8_t wr_antsignal;
-};
-
-#define RT2573_RX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_ANTENNA) | \
- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
-
-struct rum_tx_radiotap_header {
- struct ieee80211_radiotap_header wt_ihdr;
- uint8_t wt_flags;
- uint8_t wt_rate;
- uint16_t wt_chan_freq;
- uint16_t wt_chan_flags;
- uint8_t wt_antenna;
-};
-
-#define RT2573_TX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_ANTENNA))
-
-struct rum_softc;
-
-struct rum_task {
- struct usb2_proc_msg hdr;
- struct rum_softc *sc;
-};
-
-struct rum_tx_data {
- STAILQ_ENTRY(rum_tx_data) next;
- struct rum_softc *sc;
- struct rum_tx_desc desc;
- struct mbuf *m;
- struct ieee80211_node *ni;
- int rate;
-};
-typedef STAILQ_HEAD(, rum_tx_data) rum_txdhead;
-
-struct rum_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amn;
-};
-#define RUM_NODE(ni) ((struct rum_node *)(ni))
-
-struct rum_vap {
- struct ieee80211vap vap;
- struct rum_softc *sc;
- struct ieee80211_beacon_offsets bo;
- struct ieee80211_amrr amrr;
- struct usb2_callout amrr_ch;
- struct rum_task amrr_task[2];
-
- int (*newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
-};
-#define RUM_VAP(vap) ((struct rum_vap *)(vap))
-
-enum {
- RUM_BULK_WR,
- RUM_BULK_RD,
- RUM_N_TRANSFER = 2,
-};
-
-struct rum_softc {
- struct ifnet *sc_ifp;
- device_t sc_dev;
- struct usb2_device *sc_udev;
- struct usb2_process sc_tq;
-
- const struct ieee80211_rate_table *sc_rates;
- struct usb2_xfer *sc_xfer[RUM_N_TRANSFER];
-
- uint8_t rf_rev;
- uint8_t rffreq;
-
- enum ieee80211_state sc_state;
- int sc_arg;
- struct rum_task sc_synctask[2];
- struct rum_task sc_task[2];
- struct rum_task sc_promisctask[2];
- struct rum_task sc_scantask[2];
- int sc_scan_action;
-#define RUM_SCAN_START 0
-#define RUM_SCAN_END 1
-#define RUM_SET_CHANNEL 2
-
- struct rum_tx_data tx_data[RUM_TX_LIST_COUNT];
- rum_txdhead tx_q;
- rum_txdhead tx_free;
- int tx_nfree;
- struct rum_rx_desc sc_rx_desc;
-
- struct mtx sc_mtx;
-
- uint32_t sta[6];
- uint32_t rf_regs[4];
- uint8_t txpow[44];
- uint8_t sc_bssid[6];
-
- struct {
- uint8_t val;
- uint8_t reg;
- } __packed bbp_prom[16];
-
- int hw_radio;
- int rx_ant;
- int tx_ant;
- int nb_ant;
- int ext_2ghz_lna;
- int ext_5ghz_lna;
- int rssi_2ghz_corr;
- int rssi_5ghz_corr;
- uint8_t bbp17;
-
- struct rum_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
-
- struct rum_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
-};
-
-#define RUM_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
-#define RUM_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
-#define RUM_LOCK_ASSERT(sc, t) mtx_assert(&(sc)->sc_mtx, t)
diff --git a/sys/dev/usb2/wlan/if_ural2.c b/sys/dev/usb2/wlan/if_ural2.c
deleted file mode 100644
index b48cecd..0000000
--- a/sys/dev/usb2/wlan/if_ural2.c
+++ /dev/null
@@ -1,2365 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005, 2006
- * Damien Bergamini <damien.bergamini@free.fr>
- *
- * Copyright (c) 2006, 2008
- * Hans Petter Selasky <hselasky@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$");
-
-/*-
- * Ralink Technology RT2500USB chipset driver
- * http://www.ralinktech.com/
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#define USB_DEBUG_VAR ural_debug
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/wlan/usb2_wlan.h>
-#include <dev/usb2/wlan/if_uralreg.h>
-#include <dev/usb2/wlan/if_uralvar.h>
-
-#if USB_DEBUG
-static int ural_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, ural, CTLFLAG_RW, 0, "USB ural");
-SYSCTL_INT(_hw_usb2_ural, OID_AUTO, debug, CTLFLAG_RW, &ural_debug, 0,
- "Debug level");
-#endif
-
-#define ural_do_request(sc,req,data) \
- usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000)
-
-#define URAL_RSSI(rssi) \
- ((rssi) > (RAL_NOISE_FLOOR + RAL_RSSI_CORR) ? \
- ((rssi) - (RAL_NOISE_FLOOR + RAL_RSSI_CORR)) : 0)
-
-/* various supported device vendors/products */
-static const struct usb2_device_id ural_devs[] = {
- { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL167G) },
- { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_RALINK_RT2570) },
- { USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050) },
- { USB_VP(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7051) },
- { USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_HU200TS) },
- { USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54G) },
- { USB_VP(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GP) },
- { USB_VP(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU) },
- { USB_VP(USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122) },
- { USB_VP(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GN54G) },
- { USB_VP(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWBKG) },
- { USB_VP(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254) },
- { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54) },
- { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54AI) },
- { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54YB) },
- { USB_VP(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_NINWIFI) },
- { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570) },
- { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_2) },
- { USB_VP(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_3) },
- { USB_VP(USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_NV902) },
- { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570) },
- { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_2) },
- { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_3) },
- { USB_VP(USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WL54G) },
- { USB_VP(USB_VENDOR_SMC, USB_PRODUCT_SMC_2862WG) },
- { USB_VP(USB_VENDOR_SPHAIRON, USB_PRODUCT_SPHAIRON_UB801R) },
- { USB_VP(USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2570) },
- { USB_VP(USB_VENDOR_VTECH, USB_PRODUCT_VTECH_RT2570) },
- { USB_VP(USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2570) },
-};
-
-static usb2_callback_t ural_bulk_read_callback;
-static usb2_callback_t ural_bulk_write_callback;
-
-static usb2_proc_callback_t ural_attach_post;
-static usb2_proc_callback_t ural_task;
-static usb2_proc_callback_t ural_scantask;
-static usb2_proc_callback_t ural_promisctask;
-static usb2_proc_callback_t ural_amrr_task;
-static usb2_proc_callback_t ural_init_task;
-static usb2_proc_callback_t ural_stop_task;
-
-static struct ieee80211vap *ural_vap_create(struct ieee80211com *,
- const char name[IFNAMSIZ], int unit, int opmode,
- int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void ural_vap_delete(struct ieee80211vap *);
-static void ural_tx_free(struct ural_tx_data *, int);
-static void ural_setup_tx_list(struct ural_softc *);
-static void ural_unsetup_tx_list(struct ural_softc *);
-static int ural_newstate(struct ieee80211vap *,
- enum ieee80211_state, int);
-static void ural_setup_tx_desc(struct ural_softc *,
- struct ural_tx_desc *, uint32_t, int, int);
-static int ural_tx_bcn(struct ural_softc *, struct mbuf *,
- struct ieee80211_node *);
-static int ural_tx_mgt(struct ural_softc *, struct mbuf *,
- struct ieee80211_node *);
-static int ural_tx_data(struct ural_softc *, struct mbuf *,
- struct ieee80211_node *);
-static void ural_start(struct ifnet *);
-static int ural_ioctl(struct ifnet *, u_long, caddr_t);
-static void ural_set_testmode(struct ural_softc *);
-static void ural_eeprom_read(struct ural_softc *, uint16_t, void *,
- int);
-static uint16_t ural_read(struct ural_softc *, uint16_t);
-static void ural_read_multi(struct ural_softc *, uint16_t, void *,
- int);
-static void ural_write(struct ural_softc *, uint16_t, uint16_t);
-static void ural_write_multi(struct ural_softc *, uint16_t, void *,
- int) __unused;
-static void ural_bbp_write(struct ural_softc *, uint8_t, uint8_t);
-static uint8_t ural_bbp_read(struct ural_softc *, uint8_t);
-static void ural_rf_write(struct ural_softc *, uint8_t, uint32_t);
-static struct ieee80211_node *ural_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void ural_newassoc(struct ieee80211_node *, int);
-static void ural_scan_start(struct ieee80211com *);
-static void ural_scan_end(struct ieee80211com *);
-static void ural_set_channel(struct ieee80211com *);
-static void ural_set_chan(struct ural_softc *,
- struct ieee80211_channel *);
-static void ural_disable_rf_tune(struct ural_softc *);
-static void ural_enable_tsf_sync(struct ural_softc *);
-static void ural_update_slot(struct ifnet *);
-static void ural_set_txpreamble(struct ural_softc *);
-static void ural_set_basicrates(struct ural_softc *,
- const struct ieee80211_channel *);
-static void ural_set_bssid(struct ural_softc *, const uint8_t *);
-static void ural_set_macaddr(struct ural_softc *, uint8_t *);
-static const char *ural_get_rf(int);
-static void ural_read_eeprom(struct ural_softc *);
-static int ural_bbp_init(struct ural_softc *);
-static void ural_set_txantenna(struct ural_softc *, int);
-static void ural_set_rxantenna(struct ural_softc *, int);
-static void ural_init(void *);
-static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *,
- const struct ieee80211_bpf_params *);
-static void ural_amrr_start(struct ural_softc *,
- struct ieee80211_node *);
-static void ural_amrr_timeout(void *);
-static int ural_pause(struct ural_softc *sc, int timeout);
-static void ural_queue_command(struct ural_softc *,
- usb2_proc_callback_t *, struct usb2_proc_msg *,
- struct usb2_proc_msg *);
-
-/*
- * Default values for MAC registers; values taken from the reference driver.
- */
-static const struct {
- uint16_t reg;
- uint16_t val;
-} ural_def_mac[] = {
- { RAL_TXRX_CSR5, 0x8c8d },
- { RAL_TXRX_CSR6, 0x8b8a },
- { RAL_TXRX_CSR7, 0x8687 },
- { RAL_TXRX_CSR8, 0x0085 },
- { RAL_MAC_CSR13, 0x1111 },
- { RAL_MAC_CSR14, 0x1e11 },
- { RAL_TXRX_CSR21, 0xe78f },
- { RAL_MAC_CSR9, 0xff1d },
- { RAL_MAC_CSR11, 0x0002 },
- { RAL_MAC_CSR22, 0x0053 },
- { RAL_MAC_CSR15, 0x0000 },
- { RAL_MAC_CSR8, RAL_FRAME_SIZE },
- { RAL_TXRX_CSR19, 0x0000 },
- { RAL_TXRX_CSR18, 0x005a },
- { RAL_PHY_CSR2, 0x0000 },
- { RAL_TXRX_CSR0, 0x1ec0 },
- { RAL_PHY_CSR4, 0x000f }
-};
-
-/*
- * Default values for BBP registers; values taken from the reference driver.
- */
-static const struct {
- uint8_t reg;
- uint8_t val;
-} ural_def_bbp[] = {
- { 3, 0x02 },
- { 4, 0x19 },
- { 14, 0x1c },
- { 15, 0x30 },
- { 16, 0xac },
- { 17, 0x48 },
- { 18, 0x18 },
- { 19, 0xff },
- { 20, 0x1e },
- { 21, 0x08 },
- { 22, 0x08 },
- { 23, 0x08 },
- { 24, 0x80 },
- { 25, 0x50 },
- { 26, 0x08 },
- { 27, 0x23 },
- { 30, 0x10 },
- { 31, 0x2b },
- { 32, 0xb9 },
- { 34, 0x12 },
- { 35, 0x50 },
- { 39, 0xc4 },
- { 40, 0x02 },
- { 41, 0x60 },
- { 53, 0x10 },
- { 54, 0x18 },
- { 56, 0x08 },
- { 57, 0x10 },
- { 58, 0x08 },
- { 61, 0x60 },
- { 62, 0x10 },
- { 75, 0xff }
-};
-
-/*
- * Default values for RF register R2 indexed by channel numbers.
- */
-static const uint32_t ural_rf2522_r2[] = {
- 0x307f6, 0x307fb, 0x30800, 0x30805, 0x3080a, 0x3080f, 0x30814,
- 0x30819, 0x3081e, 0x30823, 0x30828, 0x3082d, 0x30832, 0x3083e
-};
-
-static const uint32_t ural_rf2523_r2[] = {
- 0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d,
- 0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346
-};
-
-static const uint32_t ural_rf2524_r2[] = {
- 0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d,
- 0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346
-};
-
-static const uint32_t ural_rf2525_r2[] = {
- 0x20327, 0x20328, 0x20329, 0x2032a, 0x2032b, 0x2032c, 0x2032d,
- 0x2032e, 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20346
-};
-
-static const uint32_t ural_rf2525_hi_r2[] = {
- 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20344, 0x20345,
- 0x20346, 0x20347, 0x20348, 0x20349, 0x2034a, 0x2034b, 0x2034e
-};
-
-static const uint32_t ural_rf2525e_r2[] = {
- 0x2044d, 0x2044e, 0x2044f, 0x20460, 0x20461, 0x20462, 0x20463,
- 0x20464, 0x20465, 0x20466, 0x20467, 0x20468, 0x20469, 0x2046b
-};
-
-static const uint32_t ural_rf2526_hi_r2[] = {
- 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d, 0x0022d,
- 0x0022e, 0x0022e, 0x0022f, 0x0022d, 0x00240, 0x00240, 0x00241
-};
-
-static const uint32_t ural_rf2526_r2[] = {
- 0x00226, 0x00227, 0x00227, 0x00228, 0x00228, 0x00229, 0x00229,
- 0x0022a, 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d
-};
-
-/*
- * For dual-band RF, RF registers R1 and R4 also depend on channel number;
- * values taken from the reference driver.
- */
-static const struct {
- uint8_t chan;
- uint32_t r1;
- uint32_t r2;
- uint32_t r4;
-} ural_rf5222[] = {
- { 1, 0x08808, 0x0044d, 0x00282 },
- { 2, 0x08808, 0x0044e, 0x00282 },
- { 3, 0x08808, 0x0044f, 0x00282 },
- { 4, 0x08808, 0x00460, 0x00282 },
- { 5, 0x08808, 0x00461, 0x00282 },
- { 6, 0x08808, 0x00462, 0x00282 },
- { 7, 0x08808, 0x00463, 0x00282 },
- { 8, 0x08808, 0x00464, 0x00282 },
- { 9, 0x08808, 0x00465, 0x00282 },
- { 10, 0x08808, 0x00466, 0x00282 },
- { 11, 0x08808, 0x00467, 0x00282 },
- { 12, 0x08808, 0x00468, 0x00282 },
- { 13, 0x08808, 0x00469, 0x00282 },
- { 14, 0x08808, 0x0046b, 0x00286 },
-
- { 36, 0x08804, 0x06225, 0x00287 },
- { 40, 0x08804, 0x06226, 0x00287 },
- { 44, 0x08804, 0x06227, 0x00287 },
- { 48, 0x08804, 0x06228, 0x00287 },
- { 52, 0x08804, 0x06229, 0x00287 },
- { 56, 0x08804, 0x0622a, 0x00287 },
- { 60, 0x08804, 0x0622b, 0x00287 },
- { 64, 0x08804, 0x0622c, 0x00287 },
-
- { 100, 0x08804, 0x02200, 0x00283 },
- { 104, 0x08804, 0x02201, 0x00283 },
- { 108, 0x08804, 0x02202, 0x00283 },
- { 112, 0x08804, 0x02203, 0x00283 },
- { 116, 0x08804, 0x02204, 0x00283 },
- { 120, 0x08804, 0x02205, 0x00283 },
- { 124, 0x08804, 0x02206, 0x00283 },
- { 128, 0x08804, 0x02207, 0x00283 },
- { 132, 0x08804, 0x02208, 0x00283 },
- { 136, 0x08804, 0x02209, 0x00283 },
- { 140, 0x08804, 0x0220a, 0x00283 },
-
- { 149, 0x08808, 0x02429, 0x00281 },
- { 153, 0x08808, 0x0242b, 0x00281 },
- { 157, 0x08808, 0x0242d, 0x00281 },
- { 161, 0x08808, 0x0242f, 0x00281 }
-};
-
-static const struct usb2_config ural_config[URAL_N_TRANSFER] = {
- [URAL_BULK_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = (RAL_FRAME_SIZE + RAL_TX_DESC_SIZE + 4),
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = ural_bulk_write_callback,
- .mh.timeout = 5000, /* ms */
- },
- [URAL_BULK_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = (RAL_FRAME_SIZE + RAL_RX_DESC_SIZE),
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = ural_bulk_read_callback,
- },
-};
-
-static device_probe_t ural_match;
-static device_attach_t ural_attach;
-static device_detach_t ural_detach;
-
-static device_method_t ural_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ural_match),
- DEVMETHOD(device_attach, ural_attach),
- DEVMETHOD(device_detach, ural_detach),
-
- { 0, 0 }
-};
-
-static driver_t ural_driver = {
- .name = "ural",
- .methods = ural_methods,
- .size = sizeof(struct ural_softc),
-};
-
-static devclass_t ural_devclass;
-
-DRIVER_MODULE(ural, ushub, ural_driver, ural_devclass, NULL, 0);
-MODULE_DEPEND(ural, usb2_wlan, 1, 1, 1);
-MODULE_DEPEND(ural, usb2_core, 1, 1, 1);
-MODULE_DEPEND(ural, wlan, 1, 1, 1);
-MODULE_DEPEND(ural, wlan_amrr, 1, 1, 1);
-
-static int
-ural_match(device_t self)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
- if (uaa->info.bConfigIndex != 0)
- return (ENXIO);
- if (uaa->info.bIfaceIndex != RAL_IFACE_INDEX)
- return (ENXIO);
-
- return (usb2_lookup_id_by_uaa(ural_devs, sizeof(ural_devs), uaa));
-}
-
-static int
-ural_attach(device_t self)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(self);
- struct ural_softc *sc = device_get_softc(self);
- int error;
- uint8_t iface_index;
-
- device_set_usb2_desc(self);
- sc->sc_udev = uaa->device;
- sc->sc_dev = self;
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(self),
- MTX_NETWORK_LOCK, MTX_DEF);
-
- iface_index = RAL_IFACE_INDEX;
- error = usb2_transfer_setup(uaa->device,
- &iface_index, sc->sc_xfer, ural_config,
- URAL_N_TRANSFER, sc, &sc->sc_mtx);
- if (error) {
- device_printf(self, "could not allocate USB transfers, "
- "err=%s\n", usb2_errstr(error));
- goto detach;
- }
- error = usb2_proc_create(&sc->sc_tq, &sc->sc_mtx,
- device_get_nameunit(self), USB_PRI_MED);
- if (error) {
- device_printf(self, "could not setup config thread!\n");
- goto detach;
- }
-
- /* fork rest of the attach code */
- RAL_LOCK(sc);
- ural_queue_command(sc, ural_attach_post,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- RAL_UNLOCK(sc);
- return (0);
-
-detach:
- ural_detach(self);
- return (ENXIO); /* failure */
-}
-
-static void
-ural_attach_post(struct usb2_proc_msg *pm)
-{
- struct ural_task *task = (struct ural_task *)pm;
- struct ural_softc *sc = task->sc;
- struct ifnet *ifp;
- struct ieee80211com *ic;
- uint8_t bands;
-
- /* retrieve RT2570 rev. no */
- sc->asic_rev = ural_read(sc, RAL_MAC_CSR0);
-
- /* retrieve MAC address and various other things from EEPROM */
- ural_read_eeprom(sc);
- RAL_UNLOCK(sc);
-
- device_printf(sc->sc_dev, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n",
- sc->asic_rev, ural_get_rf(sc->rf_rev));
-
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- RAL_LOCK(sc);
- return;
- }
- ic = ifp->if_l2com;
-
- ifp->if_softc = sc;
- if_initname(ifp, "ural", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = ural_init;
- ifp->if_ioctl = ural_ioctl;
- ifp->if_start = ural_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
- ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
- IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
-
- /* set device capabilities */
- ic->ic_caps =
- IEEE80211_C_STA /* station mode supported */
- | IEEE80211_C_IBSS /* IBSS mode supported */
- | IEEE80211_C_MONITOR /* monitor mode supported */
- | IEEE80211_C_HOSTAP /* HostAp mode supported */
- | IEEE80211_C_TXPMGT /* tx power management */
- | IEEE80211_C_SHPREAMBLE /* short preamble supported */
- | IEEE80211_C_SHSLOT /* short slot time supported */
- | IEEE80211_C_BGSCAN /* bg scanning supported */
- | IEEE80211_C_WPA /* 802.11i */
- ;
-
- bands = 0;
- setbit(&bands, IEEE80211_MODE_11B);
- setbit(&bands, IEEE80211_MODE_11G);
- if (sc->rf_rev == RAL_RF_5222)
- setbit(&bands, IEEE80211_MODE_11A);
- ieee80211_init_channels(ic, NULL, &bands);
-
- ieee80211_ifattach(ic);
- ic->ic_newassoc = ural_newassoc;
- ic->ic_raw_xmit = ural_raw_xmit;
- ic->ic_node_alloc = ural_node_alloc;
- ic->ic_scan_start = ural_scan_start;
- ic->ic_scan_end = ural_scan_end;
- ic->ic_set_channel = ural_set_channel;
-
- ic->ic_vap_create = ural_vap_create;
- ic->ic_vap_delete = ural_vap_delete;
-
- sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
-
- bpfattach(ifp, DLT_IEEE802_11_RADIO,
- sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
-
- sc->sc_rxtap_len = sizeof sc->sc_rxtap;
- sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
- sc->sc_rxtap.wr_ihdr.it_present = htole32(RAL_RX_RADIOTAP_PRESENT);
-
- sc->sc_txtap_len = sizeof sc->sc_txtap;
- sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
- sc->sc_txtap.wt_ihdr.it_present = htole32(RAL_TX_RADIOTAP_PRESENT);
-
- if (bootverbose)
- ieee80211_announce(ic);
-
- RAL_LOCK(sc);
-}
-
-static int
-ural_detach(device_t self)
-{
- struct ural_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
-
- /* wait for any post attach or other command to complete */
- usb2_proc_drain(&sc->sc_tq);
-
- /* stop all USB transfers */
- usb2_transfer_unsetup(sc->sc_xfer, URAL_N_TRANSFER);
- usb2_proc_free(&sc->sc_tq);
-
- /* free TX list, if any */
- RAL_LOCK(sc);
- ural_unsetup_tx_list(sc);
- RAL_UNLOCK(sc);
-
- if (ifp) {
- ic = ifp->if_l2com;
- bpfdetach(ifp);
- ieee80211_ifdetach(ic);
- if_free(ifp);
- }
-
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static struct ieee80211vap *
-ural_vap_create(struct ieee80211com *ic,
- const char name[IFNAMSIZ], int unit, int opmode, int flags,
- const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct ural_softc *sc = ic->ic_ifp->if_softc;
- struct ural_vap *uvp;
- struct ieee80211vap *vap;
-
- if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
- return NULL;
- uvp = (struct ural_vap *) malloc(sizeof(struct ural_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return NULL;
- vap = &uvp->vap;
- /* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
-
- /* override state transition machine */
- uvp->newstate = vap->iv_newstate;
- vap->iv_newstate = ural_newstate;
-
- uvp->sc = sc;
- usb2_callout_init_mtx(&uvp->amrr_ch, &sc->sc_mtx, 0);
- ieee80211_amrr_init(&uvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
-
- /* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
- ic->ic_opmode = opmode;
- return vap;
-}
-
-static void
-ural_vap_delete(struct ieee80211vap *vap)
-{
- struct ural_vap *uvp = URAL_VAP(vap);
-
- usb2_callout_drain(&uvp->amrr_ch);
- ieee80211_amrr_cleanup(&uvp->amrr);
- ieee80211_vap_detach(vap);
- free(uvp, M_80211_VAP);
-}
-
-static void
-ural_tx_free(struct ural_tx_data *data, int txerr)
-{
- struct ural_softc *sc = data->sc;
-
- if (data->m != NULL) {
- if (data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m,
- txerr ? ETIMEDOUT : 0);
- m_freem(data->m);
- data->m = NULL;
-
- ieee80211_free_node(data->ni);
- data->ni = NULL;
- }
- STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
- sc->tx_nfree++;
-}
-
-static void
-ural_setup_tx_list(struct ural_softc *sc)
-{
- struct ural_tx_data *data;
- int i;
-
- sc->tx_nfree = 0;
- STAILQ_INIT(&sc->tx_q);
- STAILQ_INIT(&sc->tx_free);
-
- for (i = 0; i < RAL_TX_LIST_COUNT; i++) {
- data = &sc->tx_data[i];
-
- data->sc = sc;
- STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
- sc->tx_nfree++;
- }
-}
-
-static void
-ural_unsetup_tx_list(struct ural_softc *sc)
-{
- struct ural_tx_data *data;
- int i;
-
- /* make sure any subsequent use of the queues will fail */
- sc->tx_nfree = 0;
- STAILQ_INIT(&sc->tx_q);
- STAILQ_INIT(&sc->tx_free);
-
- /* free up all node references and mbufs */
- for (i = 0; i < RAL_TX_LIST_COUNT; i++) {
- data = &sc->tx_data[i];
-
- if (data->m != NULL) {
- m_freem(data->m);
- data->m = NULL;
- }
- if (data->ni != NULL) {
- ieee80211_free_node(data->ni);
- data->ni = NULL;
- }
- }
-}
-
-static void
-ural_task(struct usb2_proc_msg *pm)
-{
- struct ural_task *task = (struct ural_task *)pm;
- struct ural_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ural_vap *uvp = URAL_VAP(vap);
- const struct ieee80211_txparam *tp;
- enum ieee80211_state ostate;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- ostate = vap->iv_state;
-
- switch (sc->sc_state) {
- case IEEE80211_S_INIT:
- if (ostate == IEEE80211_S_RUN) {
- /* abort TSF synchronization */
- ural_write(sc, RAL_TXRX_CSR19, 0);
-
- /* force tx led to stop blinking */
- ural_write(sc, RAL_MAC_CSR20, 0);
- }
- break;
-
- case IEEE80211_S_RUN:
- ni = vap->iv_bss;
-
- if (vap->iv_opmode != IEEE80211_M_MONITOR) {
- ural_update_slot(ic->ic_ifp);
- ural_set_txpreamble(sc);
- ural_set_basicrates(sc, ic->ic_bsschan);
- IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
- ural_set_bssid(sc, sc->sc_bssid);
- }
-
- if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
- vap->iv_opmode == IEEE80211_M_IBSS) {
- m = ieee80211_beacon_alloc(ni, &uvp->bo);
- if (m == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate beacon\n");
- return;
- }
-
- if (ural_tx_bcn(sc, m, ni) != 0) {
- device_printf(sc->sc_dev,
- "could not send beacon\n");
- return;
- }
- }
-
- /* make tx led blink on tx (controlled by ASIC) */
- ural_write(sc, RAL_MAC_CSR20, 1);
-
- if (vap->iv_opmode != IEEE80211_M_MONITOR)
- ural_enable_tsf_sync(sc);
-
- /* enable automatic rate adaptation */
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
- if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
- ural_amrr_start(sc, ni);
-
- break;
-
- default:
- break;
- }
-
- RAL_UNLOCK(sc);
- IEEE80211_LOCK(ic);
- uvp->newstate(vap, sc->sc_state, sc->sc_arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
- IEEE80211_UNLOCK(ic);
- RAL_LOCK(sc);
-}
-
-static void
-ural_scantask(struct usb2_proc_msg *pm)
-{
- struct ural_task *task = (struct ural_task *)pm;
- struct ural_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- RAL_LOCK_ASSERT(sc, MA_OWNED);
-
- switch (sc->sc_scan_action) {
- case URAL_SCAN_START:
- /* abort TSF synchronization */
- DPRINTF("starting scan\n");
- ural_write(sc, RAL_TXRX_CSR19, 0);
- ural_set_bssid(sc, ifp->if_broadcastaddr);
- break;
-
- case URAL_SET_CHANNEL:
- ural_set_chan(sc, ic->ic_curchan);
- break;
-
- default: /* URAL_SCAN_END */
- DPRINTF("stopping scan\n");
- ural_enable_tsf_sync(sc);
- ural_set_bssid(sc, sc->sc_bssid);
- break;
- }
-}
-
-static int
-ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
-{
- struct ural_vap *uvp = URAL_VAP(vap);
- struct ieee80211com *ic = vap->iv_ic;
- struct ural_softc *sc = ic->ic_ifp->if_softc;
-
- DPRINTF("%s -> %s\n",
- ieee80211_state_name[vap->iv_state],
- ieee80211_state_name[nstate]);
-
- RAL_LOCK(sc);
- usb2_callout_stop(&uvp->amrr_ch);
-
- /* do it in a process context */
- sc->sc_state = nstate;
- sc->sc_arg = arg;
- RAL_UNLOCK(sc);
-
- if (nstate == IEEE80211_S_INIT) {
- uvp->newstate(vap, nstate, arg);
- return 0;
- } else {
- RAL_LOCK(sc);
- ural_queue_command(sc, ural_task, &sc->sc_task[0].hdr,
- &sc->sc_task[1].hdr);
- RAL_UNLOCK(sc);
- return EINPROGRESS;
- }
-}
-
-
-static void
-ural_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct ural_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211_channel *c = ic->ic_curchan;
- struct ural_tx_data *data;
- struct mbuf *m;
- unsigned int len;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTFN(11, "transfer complete, %d bytes\n", xfer->actlen);
-
- /* free resources */
- data = xfer->priv_fifo;
- ural_tx_free(data, 0);
- xfer->priv_fifo = NULL;
-
- ifp->if_opackets++;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- data = STAILQ_FIRST(&sc->tx_q);
- if (data) {
- STAILQ_REMOVE_HEAD(&sc->tx_q, next);
- m = data->m;
-
- if (m->m_pkthdr.len > (RAL_FRAME_SIZE + RAL_TX_DESC_SIZE)) {
- DPRINTFN(0, "data overflow, %u bytes\n",
- m->m_pkthdr.len);
- m->m_pkthdr.len = (RAL_FRAME_SIZE + RAL_TX_DESC_SIZE);
- }
- usb2_copy_in(xfer->frbuffers, 0, &data->desc,
- RAL_TX_DESC_SIZE);
- usb2_m_copy_in(xfer->frbuffers, RAL_TX_DESC_SIZE, m, 0,
- m->m_pkthdr.len);
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = data->rate;
- tap->wt_chan_freq = htole16(c->ic_freq);
- tap->wt_chan_flags = htole16(c->ic_flags);
- tap->wt_antenna = sc->tx_ant;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
- }
-
- /* xfer length needs to be a multiple of two! */
- len = (RAL_TX_DESC_SIZE + m->m_pkthdr.len + 1) & ~1;
- if ((len % 64) == 0)
- len += 2;
-
- DPRINTFN(11, "sending frame len=%u xferlen=%u\n",
- m->m_pkthdr.len, len);
-
- xfer->frlengths[0] = len;
- xfer->priv_fifo = data;
-
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- DPRINTFN(11, "transfer error, %s\n",
- usb2_errstr(xfer->error));
-
- ifp->if_oerrors++;
- data = xfer->priv_fifo;
- if (data != NULL) {
- ural_tx_free(data, xfer->error);
- xfer->priv_fifo = NULL;
- }
-
- if (xfer->error == USB_ERR_STALLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- if (xfer->error == USB_ERR_TIMEOUT)
- device_printf(sc->sc_dev, "device timeout\n");
- break;
- }
-}
-
-static void
-ural_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct ural_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211_node *ni;
- struct mbuf *m = NULL;
- uint32_t flags;
- uint8_t rssi = 0;
- unsigned int len;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
-
- DPRINTFN(15, "rx done, actlen=%d\n", xfer->actlen);
-
- len = xfer->actlen;
- if (len < RAL_RX_DESC_SIZE + IEEE80211_MIN_LEN) {
- DPRINTF("%s: xfer too short %d\n",
- device_get_nameunit(sc->sc_dev), len);
- ifp->if_ierrors++;
- goto tr_setup;
- }
-
- len -= RAL_RX_DESC_SIZE;
- /* rx descriptor is located at the end */
- usb2_copy_out(xfer->frbuffers, len, &sc->sc_rx_desc,
- RAL_RX_DESC_SIZE);
-
- rssi = URAL_RSSI(sc->sc_rx_desc.rssi);
- flags = le32toh(sc->sc_rx_desc.flags);
- if (flags & (RAL_RX_PHY_ERROR | RAL_RX_CRC_ERROR)) {
- /*
- * This should not happen since we did not
- * request to receive those frames when we
- * filled RAL_TXRX_CSR2:
- */
- DPRINTFN(5, "PHY or CRC error\n");
- ifp->if_ierrors++;
- goto tr_setup;
- }
-
- m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (m == NULL) {
- DPRINTF("could not allocate mbuf\n");
- ifp->if_ierrors++;
- goto tr_setup;
- }
- usb2_copy_out(xfer->frbuffers, 0, mtod(m, uint8_t *), len);
-
- /* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct ural_rx_radiotap_header *tap = &sc->sc_rxtap;
-
- tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
- tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
- (flags & RAL_RX_OFDM) ?
- IEEE80211_T_OFDM : IEEE80211_T_CCK);
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wr_antenna = sc->rx_ant;
- tap->wr_antsignal = rssi;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
- }
- /* Strip trailing 802.11 MAC FCS. */
- m_adj(m, -IEEE80211_CRC_LEN);
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
-
- /*
- * At the end of a USB callback it is always safe to unlock
- * the private mutex of a device! That is why we do the
- * "ieee80211_input" here, and not some lines up!
- */
- if (m) {
- RAL_UNLOCK(sc);
- ni = ieee80211_find_rxnode(ic,
- mtod(m, struct ieee80211_frame_min *));
- if (ni != NULL) {
- (void) ieee80211_input(ni, m, rssi,
- RAL_NOISE_FLOOR, 0);
- ieee80211_free_node(ni);
- } else
- (void) ieee80211_input_all(ic, m, rssi,
- RAL_NOISE_FLOOR, 0);
- RAL_LOCK(sc);
- }
- return;
-
- default: /* Error */
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- return;
- }
-}
-
-static uint8_t
-ural_plcp_signal(int rate)
-{
- switch (rate) {
- /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
- case 12: return 0xb;
- case 18: return 0xf;
- case 24: return 0xa;
- case 36: return 0xe;
- case 48: return 0x9;
- case 72: return 0xd;
- case 96: return 0x8;
- case 108: return 0xc;
-
- /* CCK rates (NB: not IEEE std, device-specific) */
- case 2: return 0x0;
- case 4: return 0x1;
- case 11: return 0x2;
- case 22: return 0x3;
- }
- return 0xff; /* XXX unsupported/unknown rate */
-}
-
-static void
-ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc,
- uint32_t flags, int len, int rate)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint16_t plcp_length;
- int remainder;
-
- desc->flags = htole32(flags);
- desc->flags |= htole32(RAL_TX_NEWSEQ);
- desc->flags |= htole32(len << 16);
-
- desc->wme = htole16(RAL_AIFSN(2) | RAL_LOGCWMIN(3) | RAL_LOGCWMAX(5));
- desc->wme |= htole16(RAL_IVOFFSET(sizeof (struct ieee80211_frame)));
-
- /* setup PLCP fields */
- desc->plcp_signal = ural_plcp_signal(rate);
- desc->plcp_service = 4;
-
- len += IEEE80211_CRC_LEN;
- if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) {
- desc->flags |= htole32(RAL_TX_OFDM);
-
- plcp_length = len & 0xfff;
- desc->plcp_length_hi = plcp_length >> 6;
- desc->plcp_length_lo = plcp_length & 0x3f;
- } else {
- plcp_length = (16 * len + rate - 1) / rate;
- if (rate == 22) {
- remainder = (16 * len) % 22;
- if (remainder != 0 && remainder < 7)
- desc->plcp_service |= RAL_PLCP_LENGEXT;
- }
- desc->plcp_length_hi = plcp_length >> 8;
- desc->plcp_length_lo = plcp_length & 0xff;
-
- if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- desc->plcp_signal |= 0x08;
- }
-
- desc->iv = 0;
- desc->eiv = 0;
-}
-
-#define RAL_TX_TIMEOUT 5000
-
-static int
-ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
- const struct ieee80211_txparam *tp;
- struct ural_tx_data *data;
-
- if (sc->tx_nfree == 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- m_freem(m0);
- ieee80211_free_node(ni);
- return EIO;
- }
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
-
- data->m = m0;
- data->ni = ni;
- data->rate = tp->mgmtrate;
-
- ural_setup_tx_desc(sc, &data->desc,
- RAL_TX_IFS_NEWBACKOFF | RAL_TX_TIMESTAMP, m0->m_pkthdr.len,
- tp->mgmtrate);
-
- DPRINTFN(10, "sending beacon frame len=%u rate=%u\n",
- m0->m_pkthdr.len, tp->mgmtrate);
-
- STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
- usb2_transfer_start(sc->sc_xfer[URAL_BULK_WR]);
-
- return (0);
-}
-
-static int
-ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- const struct ieee80211_txparam *tp;
- struct ural_tx_data *data;
- struct ieee80211_frame *wh;
- struct ieee80211_key *k;
- uint32_t flags;
- uint16_t dur;
-
- RAL_LOCK_ASSERT(sc, MA_OWNED);
-
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
-
- wh = mtod(m0, struct ieee80211_frame *);
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return ENOBUFS;
- }
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- data->m = m0;
- data->ni = ni;
- data->rate = tp->mgmtrate;
-
- flags = 0;
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- flags |= RAL_TX_ACK;
-
- dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate,
- ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
-
- /* tell hardware to add timestamp for probe responses */
- if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
- IEEE80211_FC0_TYPE_MGT &&
- (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
- IEEE80211_FC0_SUBTYPE_PROBE_RESP)
- flags |= RAL_TX_TIMESTAMP;
- }
-
- ural_setup_tx_desc(sc, &data->desc, flags, m0->m_pkthdr.len, tp->mgmtrate);
-
- DPRINTFN(10, "sending mgt frame len=%u rate=%u\n",
- m0->m_pkthdr.len, tp->mgmtrate);
-
- STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
- usb2_transfer_start(sc->sc_xfer[URAL_BULK_WR]);
-
- return 0;
-}
-
-static int
-ural_sendprot(struct ural_softc *sc,
- const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate)
-{
- struct ieee80211com *ic = ni->ni_ic;
- const struct ieee80211_frame *wh;
- struct ural_tx_data *data;
- struct mbuf *mprot;
- int protrate, ackrate, pktlen, flags, isshort;
- uint16_t dur;
-
- KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY,
- ("protection %d", prot));
-
- wh = mtod(m, const struct ieee80211_frame *);
- pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
-
- protrate = ieee80211_ctl_rate(sc->sc_rates, rate);
- ackrate = ieee80211_ack_rate(sc->sc_rates, rate);
-
- isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
- dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort);
- + ieee80211_ack_duration(sc->sc_rates, rate, isshort);
- flags = RAL_TX_RETRY(7);
- if (prot == IEEE80211_PROT_RTSCTS) {
- /* NB: CTS is the same size as an ACK */
- dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort);
- flags |= RAL_TX_ACK;
- mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur);
- } else {
- mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
- }
- if (mprot == NULL) {
- /* XXX stat + msg */
- return ENOBUFS;
- }
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
-
- data->m = mprot;
- data->ni = ieee80211_ref_node(ni);
- data->rate = protrate;
- ural_setup_tx_desc(sc, &data->desc, flags, mprot->m_pkthdr.len, protrate);
-
- STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
- usb2_transfer_start(sc->sc_xfer[URAL_BULK_WR]);
-
- return 0;
-}
-
-static int
-ural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
- const struct ieee80211_bpf_params *params)
-{
- struct ural_tx_data *data;
- uint32_t flags;
- int error;
- int rate;
-
- RAL_LOCK_ASSERT(sc, MA_OWNED);
- KASSERT(params != NULL, ("no raw xmit params"));
-
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
-
- rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
- /* XXX validate */
- if (rate == 0) {
- m_freem(m0);
- return EINVAL;
- }
- flags = 0;
- if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
- flags |= RAL_TX_ACK;
- if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) {
- error = ural_sendprot(sc, m0, ni,
- params->ibp_flags & IEEE80211_BPF_RTS ?
- IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
- rate);
- if (error) {
- m_freem(m0);
- return error;
- }
- flags |= RAL_TX_IFS_SIFS;
- }
-
- data->m = m0;
- data->ni = ni;
- data->rate = rate;
-
- /* XXX need to setup descriptor ourself */
- ural_setup_tx_desc(sc, &data->desc, flags, m0->m_pkthdr.len, rate);
-
- DPRINTFN(10, "sending raw frame len=%u rate=%u\n",
- m0->m_pkthdr.len, rate);
-
- STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
- usb2_transfer_start(sc->sc_xfer[URAL_BULK_WR]);
-
- return 0;
-}
-
-static int
-ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct ural_tx_data *data;
- struct ieee80211_frame *wh;
- const struct ieee80211_txparam *tp;
- struct ieee80211_key *k;
- uint32_t flags = 0;
- uint16_t dur;
- int error, rate;
-
- RAL_LOCK_ASSERT(sc, MA_OWNED);
-
- wh = mtod(m0, struct ieee80211_frame *);
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
- if (IEEE80211_IS_MULTICAST(wh->i_addr1))
- rate = tp->mcastrate;
- else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
- rate = tp->ucastrate;
- else
- rate = ni->ni_txrate;
-
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return ENOBUFS;
- }
- /* packet header may have moved, reset our local pointer */
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- int prot = IEEE80211_PROT_NONE;
- if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
- prot = IEEE80211_PROT_RTSCTS;
- else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
- ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM)
- prot = ic->ic_protmode;
- if (prot != IEEE80211_PROT_NONE) {
- error = ural_sendprot(sc, m0, ni, prot, rate);
- if (error) {
- m_freem(m0);
- return error;
- }
- flags |= RAL_TX_IFS_SIFS;
- }
- }
-
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
-
- data->m = m0;
- data->ni = ni;
- data->rate = rate;
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- flags |= RAL_TX_ACK;
- flags |= RAL_TX_RETRY(7);
-
- dur = ieee80211_ack_duration(sc->sc_rates, rate,
- ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
- }
-
- ural_setup_tx_desc(sc, &data->desc, flags, m0->m_pkthdr.len, rate);
-
- DPRINTFN(10, "sending data frame len=%u rate=%u\n",
- m0->m_pkthdr.len, rate);
-
- STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
- usb2_transfer_start(sc->sc_xfer[URAL_BULK_WR]);
-
- return 0;
-}
-
-static void
-ural_start(struct ifnet *ifp)
-{
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- RAL_LOCK(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- RAL_UNLOCK(sc);
- return;
- }
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->tx_nfree == 0) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
- ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
- m = ieee80211_encap(ni, m);
- if (m == NULL) {
- ieee80211_free_node(ni);
- continue;
- }
- if (ural_tx_data(sc, m, ni) != 0) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- break;
- }
- }
- RAL_UNLOCK(sc);
-}
-
-static int
-ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- RAL_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- ural_queue_command(sc, ural_init_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- startall = 1;
- } else
- ural_queue_command(sc, ural_promisctask,
- &sc->sc_promisctask[0].hdr,
- &sc->sc_promisctask[1].hdr);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- ural_queue_command(sc, ural_stop_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- }
- }
- RAL_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- default:
- error = ether_ioctl(ifp, cmd, data);
- break;
- }
- return error;
-}
-
-static void
-ural_set_testmode(struct ural_softc *sc)
-{
- struct usb2_device_request req;
- usb2_error_t error;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = RAL_VENDOR_REQUEST;
- USETW(req.wValue, 4);
- USETW(req.wIndex, 1);
- USETW(req.wLength, 0);
-
- error = ural_do_request(sc, &req, NULL);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not set test mode: %s\n",
- usb2_errstr(error));
- }
-}
-
-static void
-ural_eeprom_read(struct ural_softc *sc, uint16_t addr, void *buf, int len)
-{
- struct usb2_device_request req;
- usb2_error_t error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RAL_READ_EEPROM;
- USETW(req.wValue, 0);
- USETW(req.wIndex, addr);
- USETW(req.wLength, len);
-
- error = ural_do_request(sc, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
- usb2_errstr(error));
- }
-}
-
-static uint16_t
-ural_read(struct ural_softc *sc, uint16_t reg)
-{
- struct usb2_device_request req;
- usb2_error_t error;
- uint16_t val;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RAL_READ_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, sizeof (uint16_t));
-
- error = ural_do_request(sc, &req, &val);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not read MAC register: %s\n",
- usb2_errstr(error));
- return 0;
- }
-
- return le16toh(val);
-}
-
-static void
-ural_read_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len)
-{
- struct usb2_device_request req;
- usb2_error_t error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RAL_READ_MULTI_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, len);
-
- error = ural_do_request(sc, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not read MAC register: %s\n",
- usb2_errstr(error));
- }
-}
-
-static void
-ural_write(struct ural_softc *sc, uint16_t reg, uint16_t val)
-{
- struct usb2_device_request req;
- usb2_error_t error;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = RAL_WRITE_MAC;
- USETW(req.wValue, val);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 0);
-
- error = ural_do_request(sc, &req, NULL);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not write MAC register: %s\n",
- usb2_errstr(error));
- }
-}
-
-static void
-ural_write_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len)
-{
- struct usb2_device_request req;
- usb2_error_t error;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = RAL_WRITE_MULTI_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, len);
-
- error = ural_do_request(sc, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not write MAC register: %s\n",
- usb2_errstr(error));
- }
-}
-
-static void
-ural_bbp_write(struct ural_softc *sc, uint8_t reg, uint8_t val)
-{
- uint16_t tmp;
- int ntries;
-
- for (ntries = 0; ntries < 100; ntries++) {
- if (!(ural_read(sc, RAL_PHY_CSR8) & RAL_BBP_BUSY))
- break;
- if (ural_pause(sc, hz / 100))
- break;
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev, "could not write to BBP\n");
- return;
- }
-
- tmp = reg << 8 | val;
- ural_write(sc, RAL_PHY_CSR7, tmp);
-}
-
-static uint8_t
-ural_bbp_read(struct ural_softc *sc, uint8_t reg)
-{
- uint16_t val;
- int ntries;
-
- val = RAL_BBP_WRITE | reg << 8;
- ural_write(sc, RAL_PHY_CSR7, val);
-
- for (ntries = 0; ntries < 100; ntries++) {
- if (!(ural_read(sc, RAL_PHY_CSR8) & RAL_BBP_BUSY))
- break;
- if (ural_pause(sc, hz / 100))
- break;
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev, "could not read BBP\n");
- return 0;
- }
-
- return ural_read(sc, RAL_PHY_CSR7) & 0xff;
-}
-
-static void
-ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val)
-{
- uint32_t tmp;
- int ntries;
-
- for (ntries = 0; ntries < 100; ntries++) {
- if (!(ural_read(sc, RAL_PHY_CSR10) & RAL_RF_LOBUSY))
- break;
- if (ural_pause(sc, hz / 100))
- break;
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev, "could not write to RF\n");
- return;
- }
-
- tmp = RAL_RF_BUSY | RAL_RF_20BIT | (val & 0xfffff) << 2 | (reg & 0x3);
- ural_write(sc, RAL_PHY_CSR9, tmp & 0xffff);
- ural_write(sc, RAL_PHY_CSR10, tmp >> 16);
-
- /* remember last written value in sc */
- sc->rf_regs[reg] = val;
-
- DPRINTFN(15, "RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff);
-}
-
-/* ARGUSED */
-static struct ieee80211_node *
-ural_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct ural_node *un;
-
- un = malloc(sizeof(struct ural_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return un != NULL ? &un->ni : NULL;
-}
-
-static void
-ural_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&URAL_VAP(vap)->amrr, &URAL_NODE(ni)->amn, ni);
-}
-
-static void
-ural_scan_start(struct ieee80211com *ic)
-{
- struct ural_softc *sc = ic->ic_ifp->if_softc;
-
- RAL_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = URAL_SCAN_START;
- ural_queue_command(sc, ural_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
- RAL_UNLOCK(sc);
-
-}
-
-static void
-ural_scan_end(struct ieee80211com *ic)
-{
- struct ural_softc *sc = ic->ic_ifp->if_softc;
-
- RAL_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = URAL_SCAN_END;
- ural_queue_command(sc, ural_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
- RAL_UNLOCK(sc);
-
-}
-
-static void
-ural_set_channel(struct ieee80211com *ic)
-{
- struct ural_softc *sc = ic->ic_ifp->if_softc;
-
- RAL_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = URAL_SET_CHANNEL;
- ural_queue_command(sc, ural_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
-
- sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
- RAL_UNLOCK(sc);
-}
-
-static void
-ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint8_t power, tmp;
- int i, chan;
-
- chan = ieee80211_chan2ieee(ic, c);
- if (chan == 0 || chan == IEEE80211_CHAN_ANY)
- return;
-
- if (IEEE80211_IS_CHAN_2GHZ(c))
- power = min(sc->txpow[chan - 1], 31);
- else
- power = 31;
-
- /* adjust txpower using ifconfig settings */
- power -= (100 - ic->ic_txpowlimit) / 8;
-
- DPRINTFN(2, "setting channel to %u, txpower to %u\n", chan, power);
-
- switch (sc->rf_rev) {
- case RAL_RF_2522:
- ural_rf_write(sc, RAL_RF1, 0x00814);
- ural_rf_write(sc, RAL_RF2, ural_rf2522_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
- break;
-
- case RAL_RF_2523:
- ural_rf_write(sc, RAL_RF1, 0x08804);
- ural_rf_write(sc, RAL_RF2, ural_rf2523_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x38044);
- ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
- break;
-
- case RAL_RF_2524:
- ural_rf_write(sc, RAL_RF1, 0x0c808);
- ural_rf_write(sc, RAL_RF2, ural_rf2524_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
- ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
- break;
-
- case RAL_RF_2525:
- ural_rf_write(sc, RAL_RF1, 0x08808);
- ural_rf_write(sc, RAL_RF2, ural_rf2525_hi_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
- ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
-
- ural_rf_write(sc, RAL_RF1, 0x08808);
- ural_rf_write(sc, RAL_RF2, ural_rf2525_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
- ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
- break;
-
- case RAL_RF_2525E:
- ural_rf_write(sc, RAL_RF1, 0x08808);
- ural_rf_write(sc, RAL_RF2, ural_rf2525e_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
- ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00286 : 0x00282);
- break;
-
- case RAL_RF_2526:
- ural_rf_write(sc, RAL_RF2, ural_rf2526_hi_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381);
- ural_rf_write(sc, RAL_RF1, 0x08804);
-
- ural_rf_write(sc, RAL_RF2, ural_rf2526_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
- ural_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381);
- break;
-
- /* dual-band RF */
- case RAL_RF_5222:
- for (i = 0; ural_rf5222[i].chan != chan; i++);
-
- ural_rf_write(sc, RAL_RF1, ural_rf5222[i].r1);
- ural_rf_write(sc, RAL_RF2, ural_rf5222[i].r2);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
- ural_rf_write(sc, RAL_RF4, ural_rf5222[i].r4);
- break;
- }
-
- if (ic->ic_opmode != IEEE80211_M_MONITOR &&
- (ic->ic_flags & IEEE80211_F_SCAN) == 0) {
- /* set Japan filter bit for channel 14 */
- tmp = ural_bbp_read(sc, 70);
-
- tmp &= ~RAL_JAPAN_FILTER;
- if (chan == 14)
- tmp |= RAL_JAPAN_FILTER;
-
- ural_bbp_write(sc, 70, tmp);
-
- /* clear CRC errors */
- ural_read(sc, RAL_STA_CSR0);
-
- ural_pause(sc, hz / 100);
- ural_disable_rf_tune(sc);
- }
-
- /* XXX doesn't belong here */
- /* update basic rate set */
- ural_set_basicrates(sc, c);
-}
-
-/*
- * Disable RF auto-tuning.
- */
-static void
-ural_disable_rf_tune(struct ural_softc *sc)
-{
- uint32_t tmp;
-
- if (sc->rf_rev != RAL_RF_2523) {
- tmp = sc->rf_regs[RAL_RF1] & ~RAL_RF1_AUTOTUNE;
- ural_rf_write(sc, RAL_RF1, tmp);
- }
-
- tmp = sc->rf_regs[RAL_RF3] & ~RAL_RF3_AUTOTUNE;
- ural_rf_write(sc, RAL_RF3, tmp);
-
- DPRINTFN(2, "disabling RF autotune\n");
-}
-
-/*
- * Refer to IEEE Std 802.11-1999 pp. 123 for more information on TSF
- * synchronization.
- */
-static void
-ural_enable_tsf_sync(struct ural_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- uint16_t logcwmin, preload, tmp;
-
- /* first, disable TSF synchronization */
- ural_write(sc, RAL_TXRX_CSR19, 0);
-
- tmp = (16 * vap->iv_bss->ni_intval) << 4;
- ural_write(sc, RAL_TXRX_CSR18, tmp);
-
- logcwmin = (ic->ic_opmode == IEEE80211_M_IBSS) ? 2 : 0;
- preload = (ic->ic_opmode == IEEE80211_M_IBSS) ? 320 : 6;
- tmp = logcwmin << 12 | preload;
- ural_write(sc, RAL_TXRX_CSR20, tmp);
-
- /* finally, enable TSF synchronization */
- tmp = RAL_ENABLE_TSF | RAL_ENABLE_TBCN;
- if (ic->ic_opmode == IEEE80211_M_STA)
- tmp |= RAL_ENABLE_TSF_SYNC(1);
- else
- tmp |= RAL_ENABLE_TSF_SYNC(2) | RAL_ENABLE_BEACON_GENERATOR;
- ural_write(sc, RAL_TXRX_CSR19, tmp);
-
- DPRINTF("enabling TSF synchronization\n");
-}
-
-#define RAL_RXTX_TURNAROUND 5 /* us */
-static void
-ural_update_slot(struct ifnet *ifp)
-{
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- uint16_t slottime, sifs, eifs;
-
- slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
-
- /*
- * These settings may sound a bit inconsistent but this is what the
- * reference driver does.
- */
- if (ic->ic_curmode == IEEE80211_MODE_11B) {
- sifs = 16 - RAL_RXTX_TURNAROUND;
- eifs = 364;
- } else {
- sifs = 10 - RAL_RXTX_TURNAROUND;
- eifs = 64;
- }
-
- ural_write(sc, RAL_MAC_CSR10, slottime);
- ural_write(sc, RAL_MAC_CSR11, sifs);
- ural_write(sc, RAL_MAC_CSR12, eifs);
-}
-
-static void
-ural_set_txpreamble(struct ural_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint16_t tmp;
-
- tmp = ural_read(sc, RAL_TXRX_CSR10);
-
- tmp &= ~RAL_SHORT_PREAMBLE;
- if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
- tmp |= RAL_SHORT_PREAMBLE;
-
- ural_write(sc, RAL_TXRX_CSR10, tmp);
-}
-
-static void
-ural_set_basicrates(struct ural_softc *sc, const struct ieee80211_channel *c)
-{
- /* XXX wrong, take from rate set */
- /* update basic rate set */
- if (IEEE80211_IS_CHAN_5GHZ(c)) {
- /* 11a basic rates: 6, 12, 24Mbps */
- ural_write(sc, RAL_TXRX_CSR11, 0x150);
- } else if (IEEE80211_IS_CHAN_ANYG(c)) {
- /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
- ural_write(sc, RAL_TXRX_CSR11, 0x15f);
- } else {
- /* 11b basic rates: 1, 2Mbps */
- ural_write(sc, RAL_TXRX_CSR11, 0x3);
- }
-}
-
-static void
-ural_set_bssid(struct ural_softc *sc, const uint8_t *bssid)
-{
- uint16_t tmp;
-
- tmp = bssid[0] | bssid[1] << 8;
- ural_write(sc, RAL_MAC_CSR5, tmp);
-
- tmp = bssid[2] | bssid[3] << 8;
- ural_write(sc, RAL_MAC_CSR6, tmp);
-
- tmp = bssid[4] | bssid[5] << 8;
- ural_write(sc, RAL_MAC_CSR7, tmp);
-
- DPRINTF("setting BSSID to %6D\n", bssid, ":");
-}
-
-static void
-ural_set_macaddr(struct ural_softc *sc, uint8_t *addr)
-{
- uint16_t tmp;
-
- tmp = addr[0] | addr[1] << 8;
- ural_write(sc, RAL_MAC_CSR2, tmp);
-
- tmp = addr[2] | addr[3] << 8;
- ural_write(sc, RAL_MAC_CSR3, tmp);
-
- tmp = addr[4] | addr[5] << 8;
- ural_write(sc, RAL_MAC_CSR4, tmp);
-
- DPRINTF("setting MAC address to %6D\n", addr, ":");
-}
-
-static void
-ural_promisctask(struct usb2_proc_msg *pm)
-{
- struct ural_task *task = (struct ural_task *)pm;
- struct ural_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- uint32_t tmp;
-
- tmp = ural_read(sc, RAL_TXRX_CSR2);
-
- tmp &= ~RAL_DROP_NOT_TO_ME;
- if (!(ifp->if_flags & IFF_PROMISC))
- tmp |= RAL_DROP_NOT_TO_ME;
-
- ural_write(sc, RAL_TXRX_CSR2, tmp);
-
- DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
- "entering" : "leaving");
-}
-
-static const char *
-ural_get_rf(int rev)
-{
- switch (rev) {
- case RAL_RF_2522: return "RT2522";
- case RAL_RF_2523: return "RT2523";
- case RAL_RF_2524: return "RT2524";
- case RAL_RF_2525: return "RT2525";
- case RAL_RF_2525E: return "RT2525e";
- case RAL_RF_2526: return "RT2526";
- case RAL_RF_5222: return "RT5222";
- default: return "unknown";
- }
-}
-
-static void
-ural_read_eeprom(struct ural_softc *sc)
-{
- uint16_t val;
-
- ural_eeprom_read(sc, RAL_EEPROM_CONFIG0, &val, 2);
- val = le16toh(val);
- sc->rf_rev = (val >> 11) & 0x7;
- sc->hw_radio = (val >> 10) & 0x1;
- sc->led_mode = (val >> 6) & 0x7;
- sc->rx_ant = (val >> 4) & 0x3;
- sc->tx_ant = (val >> 2) & 0x3;
- sc->nb_ant = val & 0x3;
-
- /* read MAC address */
- ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, sc->sc_bssid, 6);
-
- /* read default values for BBP registers */
- ural_eeprom_read(sc, RAL_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
-
- /* read Tx power for all b/g channels */
- ural_eeprom_read(sc, RAL_EEPROM_TXPOWER, sc->txpow, 14);
-}
-
-static int
-ural_bbp_init(struct ural_softc *sc)
-{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
- int i, ntries;
-
- /* wait for BBP to be ready */
- for (ntries = 0; ntries < 100; ntries++) {
- if (ural_bbp_read(sc, RAL_BBP_VERSION) != 0)
- break;
- if (ural_pause(sc, hz / 100))
- break;
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev, "timeout waiting for BBP\n");
- return EIO;
- }
-
- /* initialize BBP registers to default values */
- for (i = 0; i < N(ural_def_bbp); i++)
- ural_bbp_write(sc, ural_def_bbp[i].reg, ural_def_bbp[i].val);
-
-#if 0
- /* initialize BBP registers to values stored in EEPROM */
- for (i = 0; i < 16; i++) {
- if (sc->bbp_prom[i].reg == 0xff)
- continue;
- ural_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
- }
-#endif
-
- return 0;
-#undef N
-}
-
-static void
-ural_set_txantenna(struct ural_softc *sc, int antenna)
-{
- uint16_t tmp;
- uint8_t tx;
-
- tx = ural_bbp_read(sc, RAL_BBP_TX) & ~RAL_BBP_ANTMASK;
- if (antenna == 1)
- tx |= RAL_BBP_ANTA;
- else if (antenna == 2)
- tx |= RAL_BBP_ANTB;
- else
- tx |= RAL_BBP_DIVERSITY;
-
- /* need to force I/Q flip for RF 2525e, 2526 and 5222 */
- if (sc->rf_rev == RAL_RF_2525E || sc->rf_rev == RAL_RF_2526 ||
- sc->rf_rev == RAL_RF_5222)
- tx |= RAL_BBP_FLIPIQ;
-
- ural_bbp_write(sc, RAL_BBP_TX, tx);
-
- /* update values in PHY_CSR5 and PHY_CSR6 */
- tmp = ural_read(sc, RAL_PHY_CSR5) & ~0x7;
- ural_write(sc, RAL_PHY_CSR5, tmp | (tx & 0x7));
-
- tmp = ural_read(sc, RAL_PHY_CSR6) & ~0x7;
- ural_write(sc, RAL_PHY_CSR6, tmp | (tx & 0x7));
-}
-
-static void
-ural_set_rxantenna(struct ural_softc *sc, int antenna)
-{
- uint8_t rx;
-
- rx = ural_bbp_read(sc, RAL_BBP_RX) & ~RAL_BBP_ANTMASK;
- if (antenna == 1)
- rx |= RAL_BBP_ANTA;
- else if (antenna == 2)
- rx |= RAL_BBP_ANTB;
- else
- rx |= RAL_BBP_DIVERSITY;
-
- /* need to force no I/Q flip for RF 2525e and 2526 */
- if (sc->rf_rev == RAL_RF_2525E || sc->rf_rev == RAL_RF_2526)
- rx &= ~RAL_BBP_FLIPIQ;
-
- ural_bbp_write(sc, RAL_BBP_RX, rx);
-}
-
-static void
-ural_init_task(struct usb2_proc_msg *pm)
-{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
- struct ural_task *task = (struct ural_task *)pm;
- struct ural_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint16_t tmp;
- int i, ntries;
-
- RAL_LOCK_ASSERT(sc, MA_OWNED);
-
- ural_set_testmode(sc);
- ural_write(sc, 0x308, 0x00f0); /* XXX magic */
-
- ural_stop_task(pm);
-
- /* initialize MAC registers to default values */
- for (i = 0; i < N(ural_def_mac); i++)
- ural_write(sc, ural_def_mac[i].reg, ural_def_mac[i].val);
-
- /* wait for BBP and RF to wake up (this can take a long time!) */
- for (ntries = 0; ntries < 100; ntries++) {
- tmp = ural_read(sc, RAL_MAC_CSR17);
- if ((tmp & (RAL_BBP_AWAKE | RAL_RF_AWAKE)) ==
- (RAL_BBP_AWAKE | RAL_RF_AWAKE))
- break;
- if (ural_pause(sc, hz / 100))
- break;
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev,
- "timeout waiting for BBP/RF to wakeup\n");
- goto fail;
- }
-
- /* we're ready! */
- ural_write(sc, RAL_MAC_CSR1, RAL_HOST_READY);
-
- /* set basic rate set (will be updated later) */
- ural_write(sc, RAL_TXRX_CSR11, 0x15f);
-
- if (ural_bbp_init(sc) != 0)
- goto fail;
-
- ural_set_chan(sc, ic->ic_curchan);
-
- /* clear statistic registers (STA_CSR0 to STA_CSR10) */
- ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta);
-
- ural_set_txantenna(sc, sc->tx_ant);
- ural_set_rxantenna(sc, sc->rx_ant);
-
- IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
- ural_set_macaddr(sc, ic->ic_myaddr);
-
- /*
- * Allocate Tx and Rx xfer queues.
- */
- ural_setup_tx_list(sc);
-
- /* kick Rx */
- tmp = RAL_DROP_PHY | RAL_DROP_CRC;
- if (ic->ic_opmode != IEEE80211_M_MONITOR) {
- tmp |= RAL_DROP_CTL | RAL_DROP_BAD_VERSION;
- if (ic->ic_opmode != IEEE80211_M_HOSTAP)
- tmp |= RAL_DROP_TODS;
- if (!(ifp->if_flags & IFF_PROMISC))
- tmp |= RAL_DROP_NOT_TO_ME;
- }
- ural_write(sc, RAL_TXRX_CSR2, tmp);
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- usb2_transfer_start(sc->sc_xfer[URAL_BULK_RD]);
- return;
-
-fail: ural_stop_task(pm);
-#undef N
-}
-
-static void
-ural_init(void *priv)
-{
- struct ural_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- RAL_LOCK(sc);
- ural_queue_command(sc, ural_init_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- RAL_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
-ural_stop_task(struct usb2_proc_msg *pm)
-{
- struct ural_task *task = (struct ural_task *)pm;
- struct ural_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
-
- RAL_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- /*
- * Drain all the transfers, if not already drained:
- */
- RAL_UNLOCK(sc);
- usb2_transfer_drain(sc->sc_xfer[URAL_BULK_WR]);
- usb2_transfer_drain(sc->sc_xfer[URAL_BULK_RD]);
- RAL_LOCK(sc);
-
- ural_unsetup_tx_list(sc);
-
- /* disable Rx */
- ural_write(sc, RAL_TXRX_CSR2, RAL_DISABLE_RX);
- /* reset ASIC and BBP (but won't reset MAC registers!) */
- ural_write(sc, RAL_MAC_CSR1, RAL_RESET_ASIC | RAL_RESET_BBP);
- /* wait a little */
- ural_pause(sc, hz / 10);
- ural_write(sc, RAL_MAC_CSR1, 0);
-}
-
-static int
-ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
- const struct ieee80211_bpf_params *params)
-{
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct ural_softc *sc = ifp->if_softc;
-
- RAL_LOCK(sc);
- /* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- RAL_UNLOCK(sc);
- m_freem(m);
- ieee80211_free_node(ni);
- return ENETDOWN;
- }
- if (sc->tx_nfree == 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- RAL_UNLOCK(sc);
- m_freem(m);
- ieee80211_free_node(ni);
- return EIO;
- }
-
- ifp->if_opackets++;
-
- if (params == NULL) {
- /*
- * Legacy path; interpret frame contents to decide
- * precisely how to send the frame.
- */
- if (ural_tx_mgt(sc, m, ni) != 0)
- goto bad;
- } else {
- /*
- * Caller supplied explicit parameters to use in
- * sending the frame.
- */
- if (ural_tx_raw(sc, m, ni, params) != 0)
- goto bad;
- }
- RAL_UNLOCK(sc);
- return 0;
-bad:
- ifp->if_oerrors++;
- RAL_UNLOCK(sc);
- ieee80211_free_node(ni);
- return EIO; /* XXX */
-}
-
-static void
-ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ural_vap *uvp = URAL_VAP(vap);
-
- /* clear statistic registers (STA_CSR0 to STA_CSR10) */
- ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta);
-
- ieee80211_amrr_node_init(&uvp->amrr, &URAL_NODE(ni)->amn, ni);
-
- usb2_callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, uvp);
-}
-
-static void
-ural_amrr_timeout(void *arg)
-{
- struct ural_vap *uvp = arg;
- struct ural_softc *sc = uvp->sc;
-
- ural_queue_command(sc, ural_amrr_task,
- &uvp->amrr_task[0].hdr, &uvp->amrr_task[1].hdr);
-}
-
-static void
-ural_amrr_task(struct usb2_proc_msg *pm)
-{
- struct ural_task *task = (struct ural_task *)pm;
- struct ural_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ural_vap *uvp = URAL_VAP(vap);
- struct ieee80211_node *ni = vap->iv_bss;
- int ok, fail;
-
- /* read and clear statistic registers (STA_CSR0 to STA_CSR10) */
- ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof(sc->sta));
-
- ok = sc->sta[7] + /* TX ok w/o retry */
- sc->sta[8]; /* TX ok w/ retry */
- fail = sc->sta[9]; /* TX retry-fail count */
-
- ieee80211_amrr_tx_update(&URAL_NODE(ni)->amn,
- ok+fail, ok, sc->sta[8] + fail);
- (void) ieee80211_amrr_choose(ni, &URAL_NODE(ni)->amn);
-
- ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */
-
- usb2_callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, uvp);
-}
-
-static int
-ural_pause(struct ural_softc *sc, int timeout)
-{
- if (usb2_proc_is_gone(&sc->sc_tq))
- return (1);
-
- usb2_pause_mtx(&sc->sc_mtx, timeout);
- return (0);
-}
-
-static void
-ural_queue_command(struct ural_softc *sc, usb2_proc_callback_t *fn,
- struct usb2_proc_msg *t0, struct usb2_proc_msg *t1)
-{
- struct ural_task *task;
-
- RAL_LOCK_ASSERT(sc, MA_OWNED);
-
- if (usb2_proc_is_gone(&sc->sc_tq)) {
- DPRINTF("proc is gone\n");
- return; /* nothing to do */
- }
- /*
- * NOTE: The task cannot get executed before we drop the
- * "sc_mtx" mutex. It is safe to update fields in the message
- * structure after that the message got queued.
- */
- task = (struct ural_task *)
- usb2_proc_msignal(&sc->sc_tq, t0, t1);
-
- /* Setup callback and softc pointers */
- task->hdr.pm_callback = fn;
- task->sc = sc;
-
- /*
- * Init and stop must be synchronous!
- */
- if ((fn == ural_init_task) || (fn == ural_stop_task))
- usb2_proc_mwait(&sc->sc_tq, t0, t1);
-}
-
diff --git a/sys/dev/usb2/wlan/if_uralreg.h b/sys/dev/usb2/wlan/if_uralreg.h
deleted file mode 100644
index 042cf5a..0000000
--- a/sys/dev/usb2/wlan/if_uralreg.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005, 2006
- * Damien Bergamini <damien.bergamini@free.fr>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define RAL_NOISE_FLOOR -95
-#define RAL_RSSI_CORR 120
-
-#define RAL_RX_DESC_SIZE (sizeof (struct ural_rx_desc))
-#define RAL_TX_DESC_SIZE (sizeof (struct ural_tx_desc))
-#define RAL_FRAME_SIZE 0x780 /* NOTE: using 0x980 does not work */
-
-#define RAL_CONFIG_NO 1
-#define RAL_IFACE_INDEX 0
-
-#define RAL_VENDOR_REQUEST 0x01
-#define RAL_WRITE_MAC 0x02
-#define RAL_READ_MAC 0x03
-#define RAL_WRITE_MULTI_MAC 0x06
-#define RAL_READ_MULTI_MAC 0x07
-#define RAL_READ_EEPROM 0x09
-
-/*
- * MAC registers.
- */
-#define RAL_MAC_CSR0 0x0400 /* ASIC Version */
-#define RAL_MAC_CSR1 0x0402 /* System control */
-#define RAL_MAC_CSR2 0x0404 /* MAC addr0 */
-#define RAL_MAC_CSR3 0x0406 /* MAC addr1 */
-#define RAL_MAC_CSR4 0x0408 /* MAC addr2 */
-#define RAL_MAC_CSR5 0x040a /* BSSID0 */
-#define RAL_MAC_CSR6 0x040c /* BSSID1 */
-#define RAL_MAC_CSR7 0x040e /* BSSID2 */
-#define RAL_MAC_CSR8 0x0410 /* Max frame length */
-#define RAL_MAC_CSR9 0x0412 /* Timer control */
-#define RAL_MAC_CSR10 0x0414 /* Slot time */
-#define RAL_MAC_CSR11 0x0416 /* IFS */
-#define RAL_MAC_CSR12 0x0418 /* EIFS */
-#define RAL_MAC_CSR13 0x041a /* Power mode0 */
-#define RAL_MAC_CSR14 0x041c /* Power mode1 */
-#define RAL_MAC_CSR15 0x041e /* Power saving transition0 */
-#define RAL_MAC_CSR16 0x0420 /* Power saving transition1 */
-#define RAL_MAC_CSR17 0x0422 /* Power state control */
-#define RAL_MAC_CSR18 0x0424 /* Auto wake-up control */
-#define RAL_MAC_CSR19 0x0426 /* GPIO control */
-#define RAL_MAC_CSR20 0x0428 /* LED control0 */
-#define RAL_MAC_CSR22 0x042c /* XXX not documented */
-
-/*
- * Tx/Rx Registers.
- */
-#define RAL_TXRX_CSR0 0x0440 /* Security control */
-#define RAL_TXRX_CSR2 0x0444 /* Rx control */
-#define RAL_TXRX_CSR5 0x044a /* CCK Tx BBP ID0 */
-#define RAL_TXRX_CSR6 0x044c /* CCK Tx BBP ID1 */
-#define RAL_TXRX_CSR7 0x044e /* OFDM Tx BBP ID0 */
-#define RAL_TXRX_CSR8 0x0450 /* OFDM Tx BBP ID1 */
-#define RAL_TXRX_CSR10 0x0454 /* Auto responder control */
-#define RAL_TXRX_CSR11 0x0456 /* Auto responder basic rate */
-#define RAL_TXRX_CSR18 0x0464 /* Beacon interval */
-#define RAL_TXRX_CSR19 0x0466 /* Beacon/sync control */
-#define RAL_TXRX_CSR20 0x0468 /* Beacon alignment */
-#define RAL_TXRX_CSR21 0x046a /* XXX not documented */
-
-/*
- * Security registers.
- */
-#define RAL_SEC_CSR0 0x0480 /* Shared key 0, word 0 */
-
-/*
- * PHY registers.
- */
-#define RAL_PHY_CSR2 0x04c4 /* Tx MAC configuration */
-#define RAL_PHY_CSR4 0x04c8 /* Interface configuration */
-#define RAL_PHY_CSR5 0x04ca /* BBP Pre-Tx CCK */
-#define RAL_PHY_CSR6 0x04cc /* BBP Pre-Tx OFDM */
-#define RAL_PHY_CSR7 0x04ce /* BBP serial control */
-#define RAL_PHY_CSR8 0x04d0 /* BBP serial status */
-#define RAL_PHY_CSR9 0x04d2 /* RF serial control0 */
-#define RAL_PHY_CSR10 0x04d4 /* RF serial control1 */
-
-/*
- * Statistics registers.
- */
-#define RAL_STA_CSR0 0x04e0 /* FCS error */
-
-
-#define RAL_DISABLE_RX (1 << 0)
-#define RAL_DROP_CRC (1 << 1)
-#define RAL_DROP_PHY (1 << 2)
-#define RAL_DROP_CTL (1 << 3)
-#define RAL_DROP_NOT_TO_ME (1 << 4)
-#define RAL_DROP_TODS (1 << 5)
-#define RAL_DROP_BAD_VERSION (1 << 6)
-#define RAL_DROP_MULTICAST (1 << 9)
-#define RAL_DROP_BROADCAST (1 << 10)
-
-#define RAL_SHORT_PREAMBLE (1 << 2)
-
-#define RAL_RESET_ASIC (1 << 0)
-#define RAL_RESET_BBP (1 << 1)
-#define RAL_HOST_READY (1 << 2)
-
-#define RAL_ENABLE_TSF (1 << 0)
-#define RAL_ENABLE_TSF_SYNC(x) (((x) & 0x3) << 1)
-#define RAL_ENABLE_TBCN (1 << 3)
-#define RAL_ENABLE_BEACON_GENERATOR (1 << 4)
-
-#define RAL_RF_AWAKE (3 << 7)
-#define RAL_BBP_AWAKE (3 << 5)
-
-#define RAL_BBP_WRITE (1 << 15)
-#define RAL_BBP_BUSY (1 << 0)
-
-#define RAL_RF1_AUTOTUNE 0x08000
-#define RAL_RF3_AUTOTUNE 0x00040
-
-#define RAL_RF_2522 0x00
-#define RAL_RF_2523 0x01
-#define RAL_RF_2524 0x02
-#define RAL_RF_2525 0x03
-#define RAL_RF_2525E 0x04
-#define RAL_RF_2526 0x05
-/* dual-band RF */
-#define RAL_RF_5222 0x10
-
-#define RAL_BBP_VERSION 0
-#define RAL_BBP_TX 2
-#define RAL_BBP_RX 14
-
-#define RAL_BBP_ANTA 0x00
-#define RAL_BBP_DIVERSITY 0x01
-#define RAL_BBP_ANTB 0x02
-#define RAL_BBP_ANTMASK 0x03
-#define RAL_BBP_FLIPIQ 0x04
-
-#define RAL_JAPAN_FILTER 0x08
-
-struct ural_tx_desc {
- uint32_t flags;
-#define RAL_TX_RETRY(x) ((x) << 4)
-#define RAL_TX_MORE_FRAG (1 << 8)
-#define RAL_TX_ACK (1 << 9)
-#define RAL_TX_TIMESTAMP (1 << 10)
-#define RAL_TX_OFDM (1 << 11)
-#define RAL_TX_NEWSEQ (1 << 12)
-
-#define RAL_TX_IFS_MASK 0x00006000
-#define RAL_TX_IFS_BACKOFF (0 << 13)
-#define RAL_TX_IFS_SIFS (1 << 13)
-#define RAL_TX_IFS_NEWBACKOFF (2 << 13)
-#define RAL_TX_IFS_NONE (3 << 13)
-
- uint16_t wme;
-#define RAL_LOGCWMAX(x) (((x) & 0xf) << 12)
-#define RAL_LOGCWMIN(x) (((x) & 0xf) << 8)
-#define RAL_AIFSN(x) (((x) & 0x3) << 6)
-#define RAL_IVOFFSET(x) (((x) & 0x3f))
-
- uint16_t reserved1;
- uint8_t plcp_signal;
- uint8_t plcp_service;
-#define RAL_PLCP_LENGEXT 0x80
-
- uint8_t plcp_length_lo;
- uint8_t plcp_length_hi;
- uint32_t iv;
- uint32_t eiv;
-} __packed;
-
-struct ural_rx_desc {
- uint32_t flags;
-#define RAL_RX_CRC_ERROR (1 << 5)
-#define RAL_RX_OFDM (1 << 6)
-#define RAL_RX_PHY_ERROR (1 << 7)
-
- uint8_t rssi;
- uint8_t rate;
- uint16_t reserved;
-
- uint32_t iv;
- uint32_t eiv;
-} __packed;
-
-#define RAL_RF_LOBUSY (1 << 15)
-#define RAL_RF_BUSY (1 << 31)
-#define RAL_RF_20BIT (20 << 24)
-
-#define RAL_RF1 0
-#define RAL_RF2 2
-#define RAL_RF3 1
-#define RAL_RF4 3
-
-#define RAL_EEPROM_ADDRESS 0x0004
-#define RAL_EEPROM_TXPOWER 0x003c
-#define RAL_EEPROM_CONFIG0 0x0016
-#define RAL_EEPROM_BBP_BASE 0x001c
diff --git a/sys/dev/usb2/wlan/if_uralvar.h b/sys/dev/usb2/wlan/if_uralvar.h
deleted file mode 100644
index c7e5469..0000000
--- a/sys/dev/usb2/wlan/if_uralvar.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005
- * Damien Bergamini <damien.bergamini@free.fr>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define RAL_TX_LIST_COUNT 8
-
-#define URAL_SCAN_START 1
-#define URAL_SCAN_END 2
-#define URAL_SET_CHANNEL 3
-
-
-struct ural_rx_radiotap_header {
- struct ieee80211_radiotap_header wr_ihdr;
- uint8_t wr_flags;
- uint8_t wr_rate;
- uint16_t wr_chan_freq;
- uint16_t wr_chan_flags;
- uint8_t wr_antenna;
- uint8_t wr_antsignal;
-};
-
-#define RAL_RX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_ANTENNA) | \
- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
-
-struct ural_tx_radiotap_header {
- struct ieee80211_radiotap_header wt_ihdr;
- uint8_t wt_flags;
- uint8_t wt_rate;
- uint16_t wt_chan_freq;
- uint16_t wt_chan_flags;
- uint8_t wt_antenna;
-};
-
-#define RAL_TX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_ANTENNA))
-
-struct ural_softc;
-
-struct ural_task {
- struct usb2_proc_msg hdr;
- struct ural_softc *sc;
-};
-
-struct ural_tx_data {
- STAILQ_ENTRY(ural_tx_data) next;
- struct ural_softc *sc;
- struct ural_tx_desc desc;
- struct mbuf *m;
- struct ieee80211_node *ni;
- int rate;
-};
-typedef STAILQ_HEAD(, ural_tx_data) ural_txdhead;
-
-struct ural_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amn;
-};
-#define URAL_NODE(ni) ((struct ural_node *)(ni))
-
-struct ural_vap {
- struct ieee80211vap vap;
- struct ural_softc *sc;
- struct ieee80211_beacon_offsets bo;
- struct ieee80211_amrr amrr;
- struct usb2_callout amrr_ch;
- struct ural_task amrr_task[2];
-
- int (*newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
-};
-#define URAL_VAP(vap) ((struct ural_vap *)(vap))
-
-enum {
- URAL_BULK_WR,
- URAL_BULK_RD,
- URAL_N_TRANSFER = 2,
-};
-
-struct ural_softc {
- struct ifnet *sc_ifp;
- device_t sc_dev;
- struct usb2_device *sc_udev;
- struct usb2_process sc_tq;
-
- const struct ieee80211_rate_table *sc_rates;
-
- uint32_t asic_rev;
- uint8_t rf_rev;
-
- struct usb2_xfer *sc_xfer[URAL_N_TRANSFER];
-
- enum ieee80211_state sc_state;
- int sc_arg;
- int sc_scan_action; /* should be an enum */
- struct ural_task sc_synctask[2];
- struct ural_task sc_task[2];
- struct ural_task sc_promisctask[2];
- struct ural_task sc_scantask[2];
-
- struct ural_tx_data tx_data[RAL_TX_LIST_COUNT];
- ural_txdhead tx_q;
- ural_txdhead tx_free;
- int tx_nfree;
- struct ural_rx_desc sc_rx_desc;
-
- struct mtx sc_mtx;
-
- uint16_t sta[11];
- uint32_t rf_regs[4];
- uint8_t txpow[14];
- uint8_t sc_bssid[6];
-
- struct {
- uint8_t val;
- uint8_t reg;
- } __packed bbp_prom[16];
-
- int led_mode;
- int hw_radio;
- int rx_ant;
- int tx_ant;
- int nb_ant;
-
- struct ural_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
-
- struct ural_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
-};
-
-#define RAL_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
-#define RAL_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
-#define RAL_LOCK_ASSERT(sc, t) mtx_assert(&(sc)->sc_mtx, t)
diff --git a/sys/dev/usb2/wlan/if_zyd2.c b/sys/dev/usb2/wlan/if_zyd2.c
deleted file mode 100644
index a5b1e2e..0000000
--- a/sys/dev/usb2/wlan/if_zyd2.c
+++ /dev/null
@@ -1,3122 +0,0 @@
-/* $OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $ */
-/* $NetBSD: if_zyd.c,v 1.7 2007/06/21 04:04:29 kiyohara Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
- * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * ZyDAS ZD1211/ZD1211B USB WLAN driver.
- */
-
-#include "usbdevs.h"
-#include <dev/usb2/include/usb2_standard.h>
-#include <dev/usb2/include/usb2_mfunc.h>
-#include <dev/usb2/include/usb2_error.h>
-
-#include <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/core/usb2_lookup.h>
-#include <dev/usb2/core/usb2_process.h>
-#include <dev/usb2/core/usb2_debug.h>
-#include <dev/usb2/core/usb2_request.h>
-#include <dev/usb2/core/usb2_busdma.h>
-#include <dev/usb2/core/usb2_util.h>
-
-#include <dev/usb2/wlan/usb2_wlan.h>
-#include <dev/usb2/wlan/if_zydreg.h>
-#include <dev/usb2/wlan/if_zydfw.h>
-
-#if USB_DEBUG
-static int zyd_debug = 0;
-
-SYSCTL_NODE(_hw_usb2, OID_AUTO, zyd, CTLFLAG_RW, 0, "USB zyd");
-SYSCTL_INT(_hw_usb2_zyd, OID_AUTO, debug, CTLFLAG_RW, &zyd_debug, 0,
- "zyd debug level");
-
-enum {
- ZYD_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
- ZYD_DEBUG_RECV = 0x00000002, /* basic recv operation */
- ZYD_DEBUG_RESET = 0x00000004, /* reset processing */
- ZYD_DEBUG_INIT = 0x00000008, /* device init */
- ZYD_DEBUG_TX_PROC = 0x00000010, /* tx ISR proc */
- ZYD_DEBUG_RX_PROC = 0x00000020, /* rx ISR proc */
- ZYD_DEBUG_STATE = 0x00000040, /* 802.11 state transitions */
- ZYD_DEBUG_STAT = 0x00000080, /* statistic */
- ZYD_DEBUG_FW = 0x00000100, /* firmware */
- ZYD_DEBUG_CMD = 0x00000200, /* fw commands */
- ZYD_DEBUG_ANY = 0xffffffff
-};
-#define DPRINTF(sc, m, fmt, ...) do { \
- if (zyd_debug & (m)) \
- printf("%s: " fmt, __func__, ## __VA_ARGS__); \
-} while (0)
-#else
-#define DPRINTF(sc, m, fmt, ...) do { \
- (void) sc; \
-} while (0)
-#endif
-
-#define zyd_do_request(sc,req,data) \
- usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000)
-
-static device_probe_t zyd_match;
-static device_attach_t zyd_attach;
-static device_detach_t zyd_detach;
-
-static usb2_callback_t zyd_intr_read_callback;
-static usb2_callback_t zyd_intr_write_callback;
-static usb2_callback_t zyd_bulk_read_callback;
-static usb2_callback_t zyd_bulk_write_callback;
-
-static usb2_proc_callback_t zyd_attach_post;
-static usb2_proc_callback_t zyd_task;
-static usb2_proc_callback_t zyd_scantask;
-static usb2_proc_callback_t zyd_multitask;
-static usb2_proc_callback_t zyd_init_task;
-static usb2_proc_callback_t zyd_stop_task;
-
-static struct ieee80211vap *zyd_vap_create(struct ieee80211com *,
- const char name[IFNAMSIZ], int unit, int opmode,
- int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void zyd_vap_delete(struct ieee80211vap *);
-static void zyd_tx_free(struct zyd_tx_data *, int);
-static void zyd_setup_tx_list(struct zyd_softc *);
-static void zyd_unsetup_tx_list(struct zyd_softc *);
-static struct ieee80211_node *zyd_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static int zyd_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-static int zyd_cmd(struct zyd_softc *, uint16_t, const void *, int,
- void *, int, int);
-static int zyd_read16(struct zyd_softc *, uint16_t, uint16_t *);
-static int zyd_read32(struct zyd_softc *, uint16_t, uint32_t *);
-static int zyd_write16(struct zyd_softc *, uint16_t, uint16_t);
-static int zyd_write32(struct zyd_softc *, uint16_t, uint32_t);
-static int zyd_rfwrite(struct zyd_softc *, uint32_t);
-static int zyd_lock_phy(struct zyd_softc *);
-static int zyd_unlock_phy(struct zyd_softc *);
-static int zyd_rf_attach(struct zyd_softc *, uint8_t);
-static const char *zyd_rf_name(uint8_t);
-static int zyd_hw_init(struct zyd_softc *);
-static int zyd_read_pod(struct zyd_softc *);
-static int zyd_read_eeprom(struct zyd_softc *);
-static int zyd_get_macaddr(struct zyd_softc *);
-static int zyd_set_macaddr(struct zyd_softc *, const uint8_t *);
-static int zyd_set_bssid(struct zyd_softc *, const uint8_t *);
-static int zyd_switch_radio(struct zyd_softc *, int);
-static int zyd_set_led(struct zyd_softc *, int, int);
-static void zyd_set_multi(struct zyd_softc *);
-static void zyd_update_mcast(struct ifnet *);
-static int zyd_set_rxfilter(struct zyd_softc *);
-static void zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *);
-static int zyd_set_beacon_interval(struct zyd_softc *, int);
-static void zyd_rx_data(struct usb2_xfer *, int, uint16_t);
-static int zyd_tx_mgt(struct zyd_softc *, struct mbuf *,
- struct ieee80211_node *);
-static int zyd_tx_data(struct zyd_softc *, struct mbuf *,
- struct ieee80211_node *);
-static void zyd_start(struct ifnet *);
-static int zyd_raw_xmit(struct ieee80211_node *, struct mbuf *,
- const struct ieee80211_bpf_params *);
-static int zyd_ioctl(struct ifnet *, u_long, caddr_t);
-static void zyd_init(void *);
-static int zyd_loadfirmware(struct zyd_softc *);
-static void zyd_newassoc(struct ieee80211_node *, int);
-static void zyd_scan_start(struct ieee80211com *);
-static void zyd_scan_end(struct ieee80211com *);
-static void zyd_set_channel(struct ieee80211com *);
-static int zyd_rfmd_init(struct zyd_rf *);
-static int zyd_rfmd_switch_radio(struct zyd_rf *, int);
-static int zyd_rfmd_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_al2230_init(struct zyd_rf *);
-static int zyd_al2230_switch_radio(struct zyd_rf *, int);
-static int zyd_al2230_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_al2230_set_channel_b(struct zyd_rf *, uint8_t);
-static int zyd_al2230_init_b(struct zyd_rf *);
-static int zyd_al7230B_init(struct zyd_rf *);
-static int zyd_al7230B_switch_radio(struct zyd_rf *, int);
-static int zyd_al7230B_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_al2210_init(struct zyd_rf *);
-static int zyd_al2210_switch_radio(struct zyd_rf *, int);
-static int zyd_al2210_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_gct_init(struct zyd_rf *);
-static int zyd_gct_switch_radio(struct zyd_rf *, int);
-static int zyd_gct_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_maxim_init(struct zyd_rf *);
-static int zyd_maxim_switch_radio(struct zyd_rf *, int);
-static int zyd_maxim_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_maxim2_init(struct zyd_rf *);
-static int zyd_maxim2_switch_radio(struct zyd_rf *, int);
-static int zyd_maxim2_set_channel(struct zyd_rf *, uint8_t);
-static void zyd_queue_command(struct zyd_softc *, usb2_proc_callback_t *,
- struct usb2_proc_msg *, struct usb2_proc_msg *);
-
-static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY;
-static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB;
-
-/* various supported device vendors/products */
-#define ZYD_ZD1211 0
-#define ZYD_ZD1211B 1
-
-static const struct usb2_device_id zyd_devs[] = {
- /* ZYD_ZD1211 */
- {USB_VPI(USB_VENDOR_3COM2, USB_PRODUCT_3COM2_3CRUSB10075, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WL54, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL159G, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_CYBERTAN, USB_PRODUCT_CYBERTAN_TG54USB, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_DRAYTEK, USB_PRODUCT_DRAYTEK_VIGOR550, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54GD, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54GZL, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GWUS54GZ, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GWUS54MINI, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_XG760A, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_SENAO, USB_PRODUCT_SENAO_NUB8301, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_SWEEX, USB_PRODUCT_SWEEX_ZD1211, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_QUICKWLAN, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZD1211_1, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZD1211_2, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_G240, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_ALL0298V2, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UB_A, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UB, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_UR055G, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_ZD1211, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_AG225H, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_ZYAIRG220, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G200V2, ZYD_ZD1211)},
- {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G202, ZYD_ZD1211)},
- /* ZYD_ZD1211B */
- {USB_VPI(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBG, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_ZD1211B, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_A9T_WIFI, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050_V4000, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_ZD1211B, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSBF54G, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_FIBERLINE, USB_PRODUCT_FIBERLINE_WL430U, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54L, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SNU5600, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US54GXS, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_XG76NA, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_ZD1211B, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UBC1, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_USR, USB_PRODUCT_USR_USR5423, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_VTECH, USB_PRODUCT_VTECH_ZD1211B, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_ZD1211B, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211B, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_M202, ZYD_ZD1211B)},
- {USB_VPI(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G220V2, ZYD_ZD1211B)},
-};
-
-static const struct usb2_config zyd_config[ZYD_N_TRANSFER] = {
- [ZYD_BULK_WR] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = ZYD_MAX_TXBUFSZ,
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = zyd_bulk_write_callback,
- .ep_index = 0,
- .mh.timeout = 10000, /* 10 seconds */
- },
- [ZYD_BULK_RD] = {
- .type = UE_BULK,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = ZYX_MAX_RXBUFSZ,
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = zyd_bulk_read_callback,
- .ep_index = 0,
- },
- [ZYD_INTR_WR] = {
- .type = UE_BULK_INTR,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_OUT,
- .mh.bufsize = sizeof(struct zyd_cmd),
- .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
- .mh.callback = zyd_intr_write_callback,
- .mh.timeout = 1000, /* 1 second */
- .ep_index = 1,
- },
- [ZYD_INTR_RD] = {
- .type = UE_INTERRUPT,
- .endpoint = UE_ADDR_ANY,
- .direction = UE_DIR_IN,
- .mh.bufsize = sizeof(struct zyd_cmd),
- .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
- .mh.callback = zyd_intr_read_callback,
- },
-};
-#define zyd_read16_m(sc, val, data) do { \
- error = zyd_read16(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define zyd_write16_m(sc, val, data) do { \
- error = zyd_write16(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define zyd_read32_m(sc, val, data) do { \
- error = zyd_read32(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define zyd_write32_m(sc, val, data) do { \
- error = zyd_write32(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-
-static int
-zyd_match(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
-
- if (uaa->usb2_mode != USB_MODE_HOST)
- return (ENXIO);
- if (uaa->info.bConfigIndex != ZYD_CONFIG_INDEX)
- return (ENXIO);
- if (uaa->info.bIfaceIndex != ZYD_IFACE_INDEX)
- return (ENXIO);
-
- return (usb2_lookup_id_by_uaa(zyd_devs, sizeof(zyd_devs), uaa));
-}
-
-static int
-zyd_attach(device_t dev)
-{
- struct usb2_attach_arg *uaa = device_get_ivars(dev);
- struct zyd_softc *sc = device_get_softc(dev);
- int error;
- uint8_t iface_index;
-
- if (uaa->info.bcdDevice < 0x4330) {
- device_printf(dev, "device version mismatch: 0x%X "
- "(only >= 43.30 supported)\n",
- uaa->info.bcdDevice);
- return (EINVAL);
- }
-
- device_set_usb2_desc(dev);
- sc->sc_dev = dev;
- sc->sc_udev = uaa->device;
- sc->sc_macrev = USB_GET_DRIVER_INFO(uaa);
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev),
- MTX_NETWORK_LOCK, MTX_DEF);
-
- STAILQ_INIT(&sc->sc_rqh);
-
- iface_index = ZYD_IFACE_INDEX;
- error = usb2_transfer_setup(uaa->device,
- &iface_index, sc->sc_xfer, zyd_config,
- ZYD_N_TRANSFER, sc, &sc->sc_mtx);
- if (error) {
- device_printf(dev, "could not allocate USB transfers, "
- "err=%s\n", usb2_errstr(error));
- goto detach;
- }
- error = usb2_proc_create(&sc->sc_tq, &sc->sc_mtx,
- device_get_nameunit(dev), USB_PRI_MED);
- if (error) {
- device_printf(dev, "could not setup config thread!\n");
- goto detach;
- }
-
- /* fork rest of the attach code */
- ZYD_LOCK(sc);
- zyd_queue_command(sc, zyd_attach_post,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- ZYD_UNLOCK(sc);
- return (0);
-
-detach:
- zyd_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static void
-zyd_attach_post(struct usb2_proc_msg *pm)
-{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
- struct ifnet *ifp;
- struct ieee80211com *ic;
- int error;
- uint8_t bands;
-
- if ((error = zyd_get_macaddr(sc)) != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM\n");
- return;
- }
-
- ZYD_UNLOCK(sc);
-
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- ZYD_LOCK(sc);
- return;
- }
- ifp->if_softc = sc;
- if_initname(ifp, "zyd", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = zyd_init;
- ifp->if_ioctl = zyd_ioctl;
- ifp->if_start = zyd_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
- ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
- ic->ic_opmode = IEEE80211_M_STA;
- IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
-
- /* set device capabilities */
- ic->ic_caps =
- IEEE80211_C_STA /* station mode */
- | IEEE80211_C_MONITOR /* monitor mode */
- | IEEE80211_C_SHPREAMBLE /* short preamble supported */
- | IEEE80211_C_SHSLOT /* short slot time supported */
- | IEEE80211_C_BGSCAN /* capable of bg scanning */
- | IEEE80211_C_WPA /* 802.11i */
- ;
-
- bands = 0;
- setbit(&bands, IEEE80211_MODE_11B);
- setbit(&bands, IEEE80211_MODE_11G);
- ieee80211_init_channels(ic, NULL, &bands);
-
- ieee80211_ifattach(ic);
- ic->ic_newassoc = zyd_newassoc;
- ic->ic_raw_xmit = zyd_raw_xmit;
- ic->ic_node_alloc = zyd_node_alloc;
- ic->ic_scan_start = zyd_scan_start;
- ic->ic_scan_end = zyd_scan_end;
- ic->ic_set_channel = zyd_set_channel;
-
- ic->ic_vap_create = zyd_vap_create;
- ic->ic_vap_delete = zyd_vap_delete;
- ic->ic_update_mcast = zyd_update_mcast;
- ic->ic_update_promisc = zyd_update_mcast;
-
- bpfattach(ifp, DLT_IEEE802_11_RADIO,
- sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap));
- sc->sc_rxtap_len = sizeof(sc->sc_rxtap);
- sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
- sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT);
- sc->sc_txtap_len = sizeof(sc->sc_txtap);
- sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
- sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT);
-
- if (bootverbose)
- ieee80211_announce(ic);
-
- ZYD_LOCK(sc);
-}
-
-static int
-zyd_detach(device_t dev)
-{
- struct zyd_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
-
- /* wait for any post attach or other command to complete */
- usb2_proc_drain(&sc->sc_tq);
-
- /* stop all USB transfers */
- usb2_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER);
- usb2_proc_free(&sc->sc_tq);
-
- /* free TX list, if any */
- zyd_unsetup_tx_list(sc);
-
- if (ifp) {
- ic = ifp->if_l2com;
- bpfdetach(ifp);
- ieee80211_ifdetach(ic);
- if_free(ifp);
- }
-
- mtx_destroy(&sc->sc_mtx);
-
- return (0);
-}
-
-static struct ieee80211vap *
-zyd_vap_create(struct ieee80211com *ic,
- const char name[IFNAMSIZ], int unit, int opmode, int flags,
- const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct zyd_vap *zvp;
- struct ieee80211vap *vap;
-
- if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
- return (NULL);
- zvp = (struct zyd_vap *) malloc(sizeof(struct zyd_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (zvp == NULL)
- return (NULL);
- vap = &zvp->vap;
- /* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
-
- /* override state transition machine */
- zvp->newstate = vap->iv_newstate;
- vap->iv_newstate = zyd_newstate;
-
- ieee80211_amrr_init(&zvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
-
- /* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
- ic->ic_opmode = opmode;
- return (vap);
-}
-
-static void
-zyd_vap_delete(struct ieee80211vap *vap)
-{
- struct zyd_vap *zvp = ZYD_VAP(vap);
-
- ieee80211_amrr_cleanup(&zvp->amrr);
- ieee80211_vap_detach(vap);
- free(zvp, M_80211_VAP);
-}
-
-static void
-zyd_tx_free(struct zyd_tx_data *data, int txerr)
-{
- struct zyd_softc *sc = data->sc;
-
- if (data->m != NULL) {
- if (data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m,
- txerr ? ETIMEDOUT : 0);
- m_freem(data->m);
- data->m = NULL;
-
- ieee80211_free_node(data->ni);
- data->ni = NULL;
- }
- STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
- sc->tx_nfree++;
-}
-
-static void
-zyd_setup_tx_list(struct zyd_softc *sc)
-{
- struct zyd_tx_data *data;
- int i;
-
- sc->tx_nfree = 0;
- STAILQ_INIT(&sc->tx_q);
- STAILQ_INIT(&sc->tx_free);
-
- for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
- data = &sc->tx_data[i];
-
- data->sc = sc;
- STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
- sc->tx_nfree++;
- }
-}
-
-static void
-zyd_unsetup_tx_list(struct zyd_softc *sc)
-{
- struct zyd_tx_data *data;
- int i;
-
- /* make sure any subsequent use of the queues will fail */
- sc->tx_nfree = 0;
- STAILQ_INIT(&sc->tx_q);
- STAILQ_INIT(&sc->tx_free);
-
- /* free up all node references and mbufs */
- for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
- data = &sc->tx_data[i];
-
- if (data->m != NULL) {
- m_freem(data->m);
- data->m = NULL;
- }
- if (data->ni != NULL) {
- ieee80211_free_node(data->ni);
- data->ni = NULL;
- }
- }
-}
-
-/* ARGUSED */
-static struct ieee80211_node *
-zyd_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct zyd_node *zn;
-
- zn = malloc(sizeof(struct zyd_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return (zn != NULL) ? (&zn->ni) : (NULL);
-}
-
-static void
-zyd_task(struct usb2_proc_msg *pm)
-{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ieee80211_node *ni = vap->iv_bss;
- struct zyd_vap *zvp = ZYD_VAP(vap);
- int error;
-
- switch (sc->sc_state) {
- case IEEE80211_S_AUTH:
- zyd_set_chan(sc, ic->ic_curchan);
- break;
- case IEEE80211_S_RUN:
- if (vap->iv_opmode == IEEE80211_M_MONITOR)
- break;
-
- /* turn link LED on */
- error = zyd_set_led(sc, ZYD_LED1, 1);
- if (error != 0)
- goto fail;
-
- /* make data LED blink upon Tx */
- zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1);
-
- IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
- zyd_set_bssid(sc, sc->sc_bssid);
- break;
- default:
- break;
- }
-fail:
- ZYD_UNLOCK(sc);
- IEEE80211_LOCK(ic);
- zvp->newstate(vap, sc->sc_state, sc->sc_arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
- IEEE80211_UNLOCK(ic);
- ZYD_LOCK(sc);
-}
-
-static int
-zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
-{
- struct zyd_vap *zvp = ZYD_VAP(vap);
- struct ieee80211com *ic = vap->iv_ic;
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
-
- DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__,
- ieee80211_state_name[vap->iv_state],
- ieee80211_state_name[nstate]);
-
- ZYD_LOCK(sc);
- /* do it in a process context */
- sc->sc_state = nstate;
- sc->sc_arg = arg;
- ZYD_UNLOCK(sc);
-
- if (nstate == IEEE80211_S_INIT) {
- zvp->newstate(vap, nstate, arg);
- return (0);
- } else {
- ZYD_LOCK(sc);
- zyd_queue_command(sc, zyd_task, &sc->sc_task[0].hdr,
- &sc->sc_task[1].hdr);
- ZYD_UNLOCK(sc);
- return (EINPROGRESS);
- }
-}
-
-/*
- * Callback handler for interrupt transfer
- */
-static void
-zyd_intr_read_callback(struct usb2_xfer *xfer)
-{
- struct zyd_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ieee80211_node *ni;
- struct zyd_cmd *cmd = &sc->sc_ibuf;
- int datalen;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_copy_out(xfer->frbuffers, 0, cmd, sizeof(*cmd));
-
- switch (le16toh(cmd->code)) {
- case ZYD_NOTIF_RETRYSTATUS:
- {
- struct zyd_notif_retry *retry =
- (struct zyd_notif_retry *)cmd->data;
-
- DPRINTF(sc, ZYD_DEBUG_TX_PROC,
- "retry intr: rate=0x%x addr=%s count=%d (0x%x)\n",
- le16toh(retry->rate), ether_sprintf(retry->macaddr),
- le16toh(retry->count)&0xff, le16toh(retry->count));
-
- /*
- * Find the node to which the packet was sent and
- * update its retry statistics. In BSS mode, this node
- * is the AP we're associated to so no lookup is
- * actually needed.
- */
- ni = ieee80211_find_txnode(vap, retry->macaddr);
- if (ni != NULL) {
- ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn,
- IEEE80211_AMRR_FAILURE, 1);
- ieee80211_free_node(ni);
- }
- if (le16toh(retry->count) & 0x100)
- ifp->if_oerrors++; /* too many retries */
- break;
- }
- case ZYD_NOTIF_IORD:
- {
- struct zyd_rq *rqp;
-
- if (le16toh(*(uint16_t *)cmd->data) == ZYD_CR_INTERRUPT)
- break; /* HMAC interrupt */
-
- datalen = xfer->actlen - sizeof(cmd->code);
- datalen -= 2; /* XXX: padding? */
-
- STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) {
- int i, cnt;
-
- if (rqp->olen != datalen)
- continue;
- cnt = rqp->olen / sizeof(struct zyd_pair);
- for (i = 0; i < cnt; i++) {
- if (*(((const uint16_t *)rqp->idata) + i) !=
- (((struct zyd_pair *)cmd->data) + i)->reg)
- break;
- }
- if (i != cnt)
- continue;
- /* copy answer into caller-supplied buffer */
- bcopy(cmd->data, rqp->odata, rqp->olen);
- DPRINTF(sc, ZYD_DEBUG_CMD,
- "command %p complete, data = %*D \n",
- rqp, rqp->olen, rqp->odata, ":");
- wakeup(rqp); /* wakeup caller */
- break;
- }
- if (rqp == NULL) {
- device_printf(sc->sc_dev,
- "unexpected IORD notification %*D\n",
- datalen, cmd->data, ":");
- }
- break;
- }
- default:
- device_printf(sc->sc_dev, "unknown notification %x\n",
- le16toh(cmd->code));
- }
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- break;
-
- default: /* Error */
- DPRINTF(sc, ZYD_DEBUG_CMD, "error = %s\n",
- usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- break;
- }
-}
-
-static void
-zyd_intr_write_callback(struct usb2_xfer *xfer)
-{
- struct zyd_softc *sc = xfer->priv_sc;
- struct zyd_rq *rqp;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- rqp = xfer->priv_fifo;
- DPRINTF(sc, ZYD_DEBUG_CMD, "command %p transferred\n", rqp);
- if ((rqp->flags & ZYD_CMD_FLAG_READ) == 0)
- wakeup(rqp); /* wakeup caller */
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) {
- if (rqp->flags & ZYD_CMD_FLAG_SENT)
- continue;
-
- usb2_copy_in(xfer->frbuffers, 0, rqp->cmd, rqp->ilen);
-
- xfer->frlengths[0] = rqp->ilen;
- xfer->priv_fifo = rqp;
- rqp->flags |= ZYD_CMD_FLAG_SENT;
- usb2_start_hardware(xfer);
- break;
- }
- break;
-
- default: /* Error */
- DPRINTF(sc, ZYD_DEBUG_ANY, "error = %s\n",
- usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- break;
- }
-}
-
-static int
-zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen,
- void *odata, int olen, int flags)
-{
- struct zyd_cmd cmd;
- struct zyd_rq rq;
- int error;
-
- if (ilen > sizeof(cmd.data))
- return (EINVAL);
-
- if (usb2_proc_is_gone(&sc->sc_tq))
- return (ENXIO);
-
- cmd.code = htole16(code);
- bcopy(idata, cmd.data, ilen);
- DPRINTF(sc, ZYD_DEBUG_CMD, "sending cmd %p = %*D\n",
- &rq, ilen, idata, ":");
-
- rq.cmd = &cmd;
- rq.idata = idata;
- rq.odata = odata;
- rq.ilen = sizeof(uint16_t) + ilen;
- rq.olen = olen;
- rq.flags = flags;
- STAILQ_INSERT_TAIL(&sc->sc_rqh, &rq, rq);
- usb2_transfer_start(sc->sc_xfer[ZYD_INTR_RD]);
- usb2_transfer_start(sc->sc_xfer[ZYD_INTR_WR]);
-
- /* wait at most one second for command reply */
- error = mtx_sleep(&rq, &sc->sc_mtx, 0 , "zydcmd", hz);
- if (error)
- device_printf(sc->sc_dev, "command timeout\n");
- STAILQ_REMOVE(&sc->sc_rqh, &rq, zyd_rq, rq);
- DPRINTF(sc, ZYD_DEBUG_CMD, "finsihed cmd %p, error = %d \n",
- &rq, error);
-
- return (error);
-}
-
-static int
-zyd_read16(struct zyd_softc *sc, uint16_t reg, uint16_t *val)
-{
- struct zyd_pair tmp;
- int error;
-
- reg = htole16(reg);
- error = zyd_cmd(sc, ZYD_CMD_IORD, &reg, sizeof(reg), &tmp, sizeof(tmp),
- ZYD_CMD_FLAG_READ);
- if (error == 0)
- *val = le16toh(tmp.val);
- return (error);
-}
-
-static int
-zyd_read32(struct zyd_softc *sc, uint16_t reg, uint32_t *val)
-{
- struct zyd_pair tmp[2];
- uint16_t regs[2];
- int error;
-
- regs[0] = htole16(ZYD_REG32_HI(reg));
- regs[1] = htole16(ZYD_REG32_LO(reg));
- error = zyd_cmd(sc, ZYD_CMD_IORD, regs, sizeof(regs), tmp, sizeof(tmp),
- ZYD_CMD_FLAG_READ);
- if (error == 0)
- *val = le16toh(tmp[0].val) << 16 | le16toh(tmp[1].val);
- return (error);
-}
-
-static int
-zyd_write16(struct zyd_softc *sc, uint16_t reg, uint16_t val)
-{
- struct zyd_pair pair;
-
- pair.reg = htole16(reg);
- pair.val = htole16(val);
-
- return zyd_cmd(sc, ZYD_CMD_IOWR, &pair, sizeof(pair), NULL, 0, 0);
-}
-
-static int
-zyd_write32(struct zyd_softc *sc, uint16_t reg, uint32_t val)
-{
- struct zyd_pair pair[2];
-
- pair[0].reg = htole16(ZYD_REG32_HI(reg));
- pair[0].val = htole16(val >> 16);
- pair[1].reg = htole16(ZYD_REG32_LO(reg));
- pair[1].val = htole16(val & 0xffff);
-
- return zyd_cmd(sc, ZYD_CMD_IOWR, pair, sizeof(pair), NULL, 0, 0);
-}
-
-static int
-zyd_rfwrite(struct zyd_softc *sc, uint32_t val)
-{
- struct zyd_rf *rf = &sc->sc_rf;
- struct zyd_rfwrite_cmd req;
- uint16_t cr203;
- int error, i;
-
- zyd_read16_m(sc, ZYD_CR203, &cr203);
- cr203 &= ~(ZYD_RF_IF_LE | ZYD_RF_CLK | ZYD_RF_DATA);
-
- req.code = htole16(2);
- req.width = htole16(rf->width);
- for (i = 0; i < rf->width; i++) {
- req.bit[i] = htole16(cr203);
- if (val & (1 << (rf->width - 1 - i)))
- req.bit[i] |= htole16(ZYD_RF_DATA);
- }
- error = zyd_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + 2 * rf->width, NULL, 0, 0);
-fail:
- return (error);
-}
-
-static int
-zyd_rfwrite_cr(struct zyd_softc *sc, uint32_t val)
-{
- int error;
-
- zyd_write16_m(sc, ZYD_CR244, (val >> 16) & 0xff);
- zyd_write16_m(sc, ZYD_CR243, (val >> 8) & 0xff);
- zyd_write16_m(sc, ZYD_CR242, (val >> 0) & 0xff);
-fail:
- return (error);
-}
-
-static int
-zyd_lock_phy(struct zyd_softc *sc)
-{
- int error;
- uint32_t tmp;
-
- zyd_read32_m(sc, ZYD_MAC_MISC, &tmp);
- tmp &= ~ZYD_UNLOCK_PHY_REGS;
- zyd_write32_m(sc, ZYD_MAC_MISC, tmp);
-fail:
- return (error);
-}
-
-static int
-zyd_unlock_phy(struct zyd_softc *sc)
-{
- int error;
- uint32_t tmp;
-
- zyd_read32_m(sc, ZYD_MAC_MISC, &tmp);
- tmp |= ZYD_UNLOCK_PHY_REGS;
- zyd_write32_m(sc, ZYD_MAC_MISC, tmp);
-fail:
- return (error);
-}
-
-/*
- * RFMD RF methods.
- */
-static int
-zyd_rfmd_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_RFMD_PHY;
- static const uint32_t rfini[] = ZYD_RFMD_RF;
- int i, error;
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++) {
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
- }
-
- /* init RFMD radio */
- for (i = 0; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_rfmd_switch_radio(struct zyd_rf *rf, int on)
-{
- int error;
- struct zyd_softc *sc = rf->rf_sc;
-
- zyd_write16_m(sc, ZYD_CR10, on ? 0x89 : 0x15);
- zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x81);
-fail:
- return (error);
-}
-
-static int
-zyd_rfmd_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
- int error;
- struct zyd_softc *sc = rf->rf_sc;
- static const struct {
- uint32_t r1, r2;
- } rfprog[] = ZYD_RFMD_CHANTABLE;
-
- error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
-
-fail:
- return (error);
-}
-
-/*
- * AL2230 RF methods.
- */
-static int
-zyd_al2230_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY;
- static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT;
- static const struct zyd_phy_pair phypll[] = {
- { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x3f },
- { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 }
- };
- static const uint32_t rfini1[] = ZYD_AL2230_RF_PART1;
- static const uint32_t rfini2[] = ZYD_AL2230_RF_PART2;
- static const uint32_t rfini3[] = ZYD_AL2230_RF_PART3;
- int i, error;
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) {
- for (i = 0; i < N(phy2230s); i++)
- zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val);
- }
-
- /* init AL2230 radio */
- for (i = 0; i < N(rfini1); i++) {
- error = zyd_rfwrite(sc, rfini1[i]);
- if (error != 0)
- goto fail;
- }
-
- if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0)
- error = zyd_rfwrite(sc, 0x000824);
- else
- error = zyd_rfwrite(sc, 0x0005a4);
- if (error != 0)
- goto fail;
-
- for (i = 0; i < N(rfini2); i++) {
- error = zyd_rfwrite(sc, rfini2[i]);
- if (error != 0)
- goto fail;
- }
-
- for (i = 0; i < N(phypll); i++)
- zyd_write16_m(sc, phypll[i].reg, phypll[i].val);
-
- for (i = 0; i < N(rfini3); i++) {
- error = zyd_rfwrite(sc, rfini3[i]);
- if (error != 0)
- goto fail;
- }
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al2230_fini(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int error, i;
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phy[] = ZYD_AL2230_PHY_FINI_PART1;
-
- for (i = 0; i < N(phy); i++)
- zyd_write16_m(sc, phy[i].reg, phy[i].val);
-
- if (sc->sc_newphy != 0)
- zyd_write16_m(sc, ZYD_CR9, 0xe1);
-
- zyd_write16_m(sc, ZYD_CR203, 0x6);
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al2230_init_b(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1;
- static const struct zyd_phy_pair phy2[] = ZYD_AL2230_PHY_PART2;
- static const struct zyd_phy_pair phy3[] = ZYD_AL2230_PHY_PART3;
- static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT;
- static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY_B;
- static const uint32_t rfini_part1[] = ZYD_AL2230_RF_B_PART1;
- static const uint32_t rfini_part2[] = ZYD_AL2230_RF_B_PART2;
- static const uint32_t rfini_part3[] = ZYD_AL2230_RF_B_PART3;
- static const uint32_t zyd_al2230_chtable[][3] = ZYD_AL2230_CHANTABLE;
- int i, error;
-
- for (i = 0; i < N(phy1); i++)
- zyd_write16_m(sc, phy1[i].reg, phy1[i].val);
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) {
- for (i = 0; i < N(phy2230s); i++)
- zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val);
- }
-
- for (i = 0; i < 3; i++) {
- error = zyd_rfwrite_cr(sc, zyd_al2230_chtable[0][i]);
- if (error != 0)
- return (error);
- }
-
- for (i = 0; i < N(rfini_part1); i++) {
- error = zyd_rfwrite_cr(sc, rfini_part1[i]);
- if (error != 0)
- return (error);
- }
-
- if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0)
- error = zyd_rfwrite(sc, 0x241000);
- else
- error = zyd_rfwrite(sc, 0x25a000);
- if (error != 0)
- goto fail;
-
- for (i = 0; i < N(rfini_part2); i++) {
- error = zyd_rfwrite_cr(sc, rfini_part2[i]);
- if (error != 0)
- return (error);
- }
-
- for (i = 0; i < N(phy2); i++)
- zyd_write16_m(sc, phy2[i].reg, phy2[i].val);
-
- for (i = 0; i < N(rfini_part3); i++) {
- error = zyd_rfwrite_cr(sc, rfini_part3[i]);
- if (error != 0)
- return (error);
- }
-
- for (i = 0; i < N(phy3); i++)
- zyd_write16_m(sc, phy3[i].reg, phy3[i].val);
-
- error = zyd_al2230_fini(rf);
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al2230_switch_radio(struct zyd_rf *rf, int on)
-{
- struct zyd_softc *sc = rf->rf_sc;
- int error, on251 = (sc->sc_macrev == ZYD_ZD1211) ? 0x3f : 0x7f;
-
- zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x04);
- zyd_write16_m(sc, ZYD_CR251, on ? on251 : 0x2f);
-fail:
- return (error);
-}
-
-static int
-zyd_al2230_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int error, i;
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phy1[] = {
- { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 },
- };
- static const struct {
- uint32_t r1, r2, r3;
- } rfprog[] = ZYD_AL2230_CHANTABLE;
-
- error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r3);
- if (error != 0)
- goto fail;
-
- for (i = 0; i < N(phy1); i++)
- zyd_write16_m(sc, phy1[i].reg, phy1[i].val);
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al2230_set_channel_b(struct zyd_rf *rf, uint8_t chan)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int error, i;
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1;
- static const struct {
- uint32_t r1, r2, r3;
- } rfprog[] = ZYD_AL2230_CHANTABLE_B;
-
- for (i = 0; i < N(phy1); i++)
- zyd_write16_m(sc, phy1[i].reg, phy1[i].val);
-
- error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r3);
- if (error != 0)
- goto fail;
- error = zyd_al2230_fini(rf);
-fail:
- return (error);
-#undef N
-}
-
-#define ZYD_AL2230_PHY_BANDEDGE6 \
-{ \
- { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \
- { ZYD_CR47, 0x1e } \
-}
-
-static int
-zyd_al2230_bandedge6(struct zyd_rf *rf, struct ieee80211_channel *c)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int error = 0, i;
- struct zyd_softc *sc = rf->rf_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6;
- int chan = ieee80211_chan2ieee(ic, c);
-
- if (chan == 1 || chan == 11)
- r[0].val = 0x12;
-
- for (i = 0; i < N(r); i++)
- zyd_write16_m(sc, r[i].reg, r[i].val);
-fail:
- return (error);
-#undef N
-}
-
-/*
- * AL7230B RF methods.
- */
-static int
-zyd_al7230B_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini_1[] = ZYD_AL7230B_PHY_1;
- static const struct zyd_phy_pair phyini_2[] = ZYD_AL7230B_PHY_2;
- static const struct zyd_phy_pair phyini_3[] = ZYD_AL7230B_PHY_3;
- static const uint32_t rfini_1[] = ZYD_AL7230B_RF_1;
- static const uint32_t rfini_2[] = ZYD_AL7230B_RF_2;
- int i, error;
-
- /* for AL7230B, PHY and RF need to be initialized in "phases" */
-
- /* init RF-dependent PHY registers, part one */
- for (i = 0; i < N(phyini_1); i++)
- zyd_write16_m(sc, phyini_1[i].reg, phyini_1[i].val);
-
- /* init AL7230B radio, part one */
- for (i = 0; i < N(rfini_1); i++) {
- if ((error = zyd_rfwrite(sc, rfini_1[i])) != 0)
- return (error);
- }
- /* init RF-dependent PHY registers, part two */
- for (i = 0; i < N(phyini_2); i++)
- zyd_write16_m(sc, phyini_2[i].reg, phyini_2[i].val);
-
- /* init AL7230B radio, part two */
- for (i = 0; i < N(rfini_2); i++) {
- if ((error = zyd_rfwrite(sc, rfini_2[i])) != 0)
- return (error);
- }
- /* init RF-dependent PHY registers, part three */
- for (i = 0; i < N(phyini_3); i++)
- zyd_write16_m(sc, phyini_3[i].reg, phyini_3[i].val);
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al7230B_switch_radio(struct zyd_rf *rf, int on)
-{
- int error;
- struct zyd_softc *sc = rf->rf_sc;
-
- zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x04);
- zyd_write16_m(sc, ZYD_CR251, on ? 0x3f : 0x2f);
-fail:
- return (error);
-}
-
-static int
-zyd_al7230B_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct {
- uint32_t r1, r2;
- } rfprog[] = ZYD_AL7230B_CHANTABLE;
- static const uint32_t rfsc[] = ZYD_AL7230B_RF_SETCHANNEL;
- int i, error;
-
- zyd_write16_m(sc, ZYD_CR240, 0x57);
- zyd_write16_m(sc, ZYD_CR251, 0x2f);
-
- for (i = 0; i < N(rfsc); i++) {
- if ((error = zyd_rfwrite(sc, rfsc[i])) != 0)
- return (error);
- }
-
- zyd_write16_m(sc, ZYD_CR128, 0x14);
- zyd_write16_m(sc, ZYD_CR129, 0x12);
- zyd_write16_m(sc, ZYD_CR130, 0x10);
- zyd_write16_m(sc, ZYD_CR38, 0x38);
- zyd_write16_m(sc, ZYD_CR136, 0xdf);
-
- error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, 0x3c9000);
- if (error != 0)
- goto fail;
-
- zyd_write16_m(sc, ZYD_CR251, 0x3f);
- zyd_write16_m(sc, ZYD_CR203, 0x06);
- zyd_write16_m(sc, ZYD_CR240, 0x08);
-fail:
- return (error);
-#undef N
-}
-
-/*
- * AL2210 RF methods.
- */
-static int
-zyd_al2210_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_AL2210_PHY;
- static const uint32_t rfini[] = ZYD_AL2210_RF;
- uint32_t tmp;
- int i, error;
-
- zyd_write32_m(sc, ZYD_CR18, 2);
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- /* init AL2210 radio */
- for (i = 0; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
- zyd_write16_m(sc, ZYD_CR47, 0x1e);
- zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp);
- zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1);
- zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1);
- zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05);
- zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00);
- zyd_write16_m(sc, ZYD_CR47, 0x1e);
- zyd_write32_m(sc, ZYD_CR18, 3);
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al2210_switch_radio(struct zyd_rf *rf, int on)
-{
- /* vendor driver does nothing for this RF chip */
-
- return (0);
-}
-
-static int
-zyd_al2210_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
- int error;
- struct zyd_softc *sc = rf->rf_sc;
- static const uint32_t rfprog[] = ZYD_AL2210_CHANTABLE;
- uint32_t tmp;
-
- zyd_write32_m(sc, ZYD_CR18, 2);
- zyd_write16_m(sc, ZYD_CR47, 0x1e);
- zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp);
- zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1);
- zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1);
- zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05);
- zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00);
- zyd_write16_m(sc, ZYD_CR47, 0x1e);
-
- /* actually set the channel */
- error = zyd_rfwrite(sc, rfprog[chan - 1]);
- if (error != 0)
- goto fail;
-
- zyd_write32_m(sc, ZYD_CR18, 3);
-fail:
- return (error);
-}
-
-/*
- * GCT RF methods.
- */
-static int
-zyd_gct_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_GCT_PHY;
- static const uint32_t rfini[] = ZYD_GCT_RF;
- int i, error;
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- /* init cgt radio */
- for (i = 0; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_gct_switch_radio(struct zyd_rf *rf, int on)
-{
- /* vendor driver does nothing for this RF chip */
-
- return (0);
-}
-
-static int
-zyd_gct_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
- int error;
- struct zyd_softc *sc = rf->rf_sc;
- static const uint32_t rfprog[] = ZYD_GCT_CHANTABLE;
-
- error = zyd_rfwrite(sc, 0x1c0000);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1]);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, 0x1c0008);
-fail:
- return (error);
-}
-
-/*
- * Maxim RF methods.
- */
-static int
-zyd_maxim_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY;
- static const uint32_t rfini[] = ZYD_MAXIM_RF;
- uint16_t tmp;
- int i, error;
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4));
-
- /* init maxim radio */
- for (i = 0; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4));
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_maxim_switch_radio(struct zyd_rf *rf, int on)
-{
-
- /* vendor driver does nothing for this RF chip */
- return (0);
-}
-
-static int
-zyd_maxim_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY;
- static const uint32_t rfini[] = ZYD_MAXIM_RF;
- static const struct {
- uint32_t r1, r2;
- } rfprog[] = ZYD_MAXIM_CHANTABLE;
- uint16_t tmp;
- int i, error;
-
- /*
- * Do the same as we do when initializing it, except for the channel
- * values coming from the two channel tables.
- */
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4));
-
- /* first two values taken from the chantables */
- error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
-
- /* init maxim radio - skipping the two first values */
- for (i = 2; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4));
-fail:
- return (error);
-#undef N
-}
-
-/*
- * Maxim2 RF methods.
- */
-static int
-zyd_maxim2_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
- static const uint32_t rfini[] = ZYD_MAXIM2_RF;
- uint16_t tmp;
- int i, error;
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4));
-
- /* init maxim2 radio */
- for (i = 0; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4));
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_maxim2_switch_radio(struct zyd_rf *rf, int on)
-{
-
- /* vendor driver does nothing for this RF chip */
- return (0);
-}
-
-static int
-zyd_maxim2_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
- static const uint32_t rfini[] = ZYD_MAXIM2_RF;
- static const struct {
- uint32_t r1, r2;
- } rfprog[] = ZYD_MAXIM2_CHANTABLE;
- uint16_t tmp;
- int i, error;
-
- /*
- * Do the same as we do when initializing it, except for the channel
- * values coming from the two channel tables.
- */
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4));
-
- /* first two values taken from the chantables */
- error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
-
- /* init maxim2 radio - skipping the two first values */
- for (i = 2; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4));
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_rf_attach(struct zyd_softc *sc, uint8_t type)
-{
- struct zyd_rf *rf = &sc->sc_rf;
-
- rf->rf_sc = sc;
-
- switch (type) {
- case ZYD_RF_RFMD:
- rf->init = zyd_rfmd_init;
- rf->switch_radio = zyd_rfmd_switch_radio;
- rf->set_channel = zyd_rfmd_set_channel;
- rf->width = 24; /* 24-bit RF values */
- break;
- case ZYD_RF_AL2230:
- case ZYD_RF_AL2230S:
- if (sc->sc_macrev == ZYD_ZD1211B) {
- rf->init = zyd_al2230_init_b;
- rf->set_channel = zyd_al2230_set_channel_b;
- } else {
- rf->init = zyd_al2230_init;
- rf->set_channel = zyd_al2230_set_channel;
- }
- rf->switch_radio = zyd_al2230_switch_radio;
- rf->bandedge6 = zyd_al2230_bandedge6;
- rf->width = 24; /* 24-bit RF values */
- break;
- case ZYD_RF_AL7230B:
- rf->init = zyd_al7230B_init;
- rf->switch_radio = zyd_al7230B_switch_radio;
- rf->set_channel = zyd_al7230B_set_channel;
- rf->width = 24; /* 24-bit RF values */
- break;
- case ZYD_RF_AL2210:
- rf->init = zyd_al2210_init;
- rf->switch_radio = zyd_al2210_switch_radio;
- rf->set_channel = zyd_al2210_set_channel;
- rf->width = 24; /* 24-bit RF values */
- break;
- case ZYD_RF_GCT:
- rf->init = zyd_gct_init;
- rf->switch_radio = zyd_gct_switch_radio;
- rf->set_channel = zyd_gct_set_channel;
- rf->width = 21; /* 21-bit RF values */
- break;
- case ZYD_RF_MAXIM_NEW:
- rf->init = zyd_maxim_init;
- rf->switch_radio = zyd_maxim_switch_radio;
- rf->set_channel = zyd_maxim_set_channel;
- rf->width = 18; /* 18-bit RF values */
- break;
- case ZYD_RF_MAXIM_NEW2:
- rf->init = zyd_maxim2_init;
- rf->switch_radio = zyd_maxim2_switch_radio;
- rf->set_channel = zyd_maxim2_set_channel;
- rf->width = 18; /* 18-bit RF values */
- break;
- default:
- device_printf(sc->sc_dev,
- "sorry, radio \"%s\" is not supported yet\n",
- zyd_rf_name(type));
- return (EINVAL);
- }
- return (0);
-}
-
-static const char *
-zyd_rf_name(uint8_t type)
-{
- static const char * const zyd_rfs[] = {
- "unknown", "unknown", "UW2451", "UCHIP", "AL2230",
- "AL7230B", "THETA", "AL2210", "MAXIM_NEW", "GCT",
- "AL2230S", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2",
- "PHILIPS"
- };
-
- return zyd_rfs[(type > 15) ? 0 : type];
-}
-
-static int
-zyd_hw_init(struct zyd_softc *sc)
-{
- int error;
- const struct zyd_phy_pair *phyp;
- struct zyd_rf *rf = &sc->sc_rf;
- uint16_t val;
-
- /* specify that the plug and play is finished */
- zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1);
- zyd_read16_m(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->sc_fwbase);
- DPRINTF(sc, ZYD_DEBUG_FW, "firmware base address=0x%04x\n",
- sc->sc_fwbase);
-
- /* retrieve firmware revision number */
- zyd_read16_m(sc, sc->sc_fwbase + ZYD_FW_FIRMWARE_REV, &sc->sc_fwrev);
- zyd_write32_m(sc, ZYD_CR_GPI_EN, 0);
- zyd_write32_m(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f);
- /* set mandatory rates - XXX assumes 802.11b/g */
- zyd_write32_m(sc, ZYD_MAC_MAN_RATE, 0x150f);
-
- /* disable interrupts */
- zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0);
-
- if ((error = zyd_read_pod(sc)) != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM\n");
- goto fail;
- }
-
- /* PHY init (resetting) */
- error = zyd_lock_phy(sc);
- if (error != 0)
- goto fail;
- phyp = (sc->sc_macrev == ZYD_ZD1211B) ? zyd_def_phyB : zyd_def_phy;
- for (; phyp->reg != 0; phyp++)
- zyd_write16_m(sc, phyp->reg, phyp->val);
- if (sc->sc_macrev == ZYD_ZD1211 && sc->sc_fix_cr157 != 0) {
- zyd_read16_m(sc, ZYD_EEPROM_PHY_REG, &val);
- zyd_write32_m(sc, ZYD_CR157, val >> 8);
- }
- error = zyd_unlock_phy(sc);
- if (error != 0)
- goto fail;
-
- /* HMAC init */
- zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000020);
- zyd_write32_m(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808);
- zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0x00000000);
- zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0x00000000);
- zyd_write32_m(sc, ZYD_MAC_GHTBL, 0x00000000);
- zyd_write32_m(sc, ZYD_MAC_GHTBH, 0x80000000);
- zyd_write32_m(sc, ZYD_MAC_MISC, 0x000000a4);
- zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f);
- zyd_write32_m(sc, ZYD_MAC_BCNCFG, 0x00f00401);
- zyd_write32_m(sc, ZYD_MAC_PHY_DELAY2, 0x00000000);
- zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000080);
- zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000);
- zyd_write32_m(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100);
- zyd_write32_m(sc, ZYD_CR_RX_PE_DELAY, 0x00000070);
- zyd_write32_m(sc, ZYD_CR_PS_CTRL, 0x10000000);
- zyd_write32_m(sc, ZYD_MAC_RTSCTSRATE, 0x02030203);
- zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1);
- zyd_write32_m(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114);
- zyd_write32_m(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0a47c032);
- zyd_write32_m(sc, ZYD_MAC_CAM_MODE, 0x3);
-
- if (sc->sc_macrev == ZYD_ZD1211) {
- zyd_write32_m(sc, ZYD_MAC_RETRY, 0x00000002);
- zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640);
- } else {
- zyd_write32_m(sc, ZYD_MACB_MAX_RETRY, 0x02020202);
- zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f);
- zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f);
- zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f);
- zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f);
- zyd_write32_m(sc, ZYD_MACB_AIFS_CTL1, 0x00280028);
- zyd_write32_m(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C);
- zyd_write32_m(sc, ZYD_MACB_TXOP, 0x01800824);
- zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0eff);
- }
-
- /* init beacon interval to 100ms */
- if ((error = zyd_set_beacon_interval(sc, 100)) != 0)
- goto fail;
-
- if ((error = zyd_rf_attach(sc, sc->sc_rfrev)) != 0) {
- device_printf(sc->sc_dev, "could not attach RF, rev 0x%x\n",
- sc->sc_rfrev);
- goto fail;
- }
-
- /* RF chip init */
- error = zyd_lock_phy(sc);
- if (error != 0)
- goto fail;
- error = (*rf->init)(rf);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "radio initialization failed, error %d\n", error);
- goto fail;
- }
- error = zyd_unlock_phy(sc);
- if (error != 0)
- goto fail;
-
- if ((error = zyd_read_eeprom(sc)) != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM\n");
- goto fail;
- }
-
-fail: return (error);
-}
-
-static int
-zyd_read_pod(struct zyd_softc *sc)
-{
- int error;
- uint32_t tmp;
-
- zyd_read32_m(sc, ZYD_EEPROM_POD, &tmp);
- sc->sc_rfrev = tmp & 0x0f;
- sc->sc_ledtype = (tmp >> 4) & 0x01;
- sc->sc_al2230s = (tmp >> 7) & 0x01;
- sc->sc_cckgain = (tmp >> 8) & 0x01;
- sc->sc_fix_cr157 = (tmp >> 13) & 0x01;
- sc->sc_parev = (tmp >> 16) & 0x0f;
- sc->sc_bandedge6 = (tmp >> 21) & 0x01;
- sc->sc_newphy = (tmp >> 31) & 0x01;
- sc->sc_txled = ((tmp & (1 << 24)) && (tmp & (1 << 29))) ? 0 : 1;
-fail:
- return (error);
-}
-
-static int
-zyd_read_eeprom(struct zyd_softc *sc)
-{
- uint16_t val;
- int error, i;
-
- /* read Tx power calibration tables */
- for (i = 0; i < 7; i++) {
- zyd_read16_m(sc, ZYD_EEPROM_PWR_CAL + i, &val);
- sc->sc_pwrcal[i * 2] = val >> 8;
- sc->sc_pwrcal[i * 2 + 1] = val & 0xff;
- zyd_read16_m(sc, ZYD_EEPROM_PWR_INT + i, &val);
- sc->sc_pwrint[i * 2] = val >> 8;
- sc->sc_pwrint[i * 2 + 1] = val & 0xff;
- zyd_read16_m(sc, ZYD_EEPROM_36M_CAL + i, &val);
- sc->sc_ofdm36_cal[i * 2] = val >> 8;
- sc->sc_ofdm36_cal[i * 2 + 1] = val & 0xff;
- zyd_read16_m(sc, ZYD_EEPROM_48M_CAL + i, &val);
- sc->sc_ofdm48_cal[i * 2] = val >> 8;
- sc->sc_ofdm48_cal[i * 2 + 1] = val & 0xff;
- zyd_read16_m(sc, ZYD_EEPROM_54M_CAL + i, &val);
- sc->sc_ofdm54_cal[i * 2] = val >> 8;
- sc->sc_ofdm54_cal[i * 2 + 1] = val & 0xff;
- }
-fail:
- return (error);
-}
-
-static int
-zyd_get_macaddr(struct zyd_softc *sc)
-{
- struct usb2_device_request req;
- usb2_error_t error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = ZYD_READFWDATAREQ;
- USETW(req.wValue, ZYD_EEPROM_MAC_ADDR_P1);
- USETW(req.wIndex, 0);
- USETW(req.wLength, IEEE80211_ADDR_LEN);
-
- error = zyd_do_request(sc, &req, sc->sc_bssid);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
- usb2_errstr(error));
- }
-
- return (error);
-}
-
-static int
-zyd_set_macaddr(struct zyd_softc *sc, const uint8_t *addr)
-{
- int error;
- uint32_t tmp;
-
- tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
- zyd_write32_m(sc, ZYD_MAC_MACADRL, tmp);
- tmp = addr[5] << 8 | addr[4];
- zyd_write32_m(sc, ZYD_MAC_MACADRH, tmp);
-fail:
- return (error);
-}
-
-static int
-zyd_set_bssid(struct zyd_softc *sc, const uint8_t *addr)
-{
- int error;
- uint32_t tmp;
-
- tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
- zyd_write32_m(sc, ZYD_MAC_BSSADRL, tmp);
- tmp = addr[5] << 8 | addr[4];
- zyd_write32_m(sc, ZYD_MAC_BSSADRH, tmp);
-fail:
- return (error);
-}
-
-static int
-zyd_switch_radio(struct zyd_softc *sc, int on)
-{
- struct zyd_rf *rf = &sc->sc_rf;
- int error;
-
- error = zyd_lock_phy(sc);
- if (error != 0)
- goto fail;
- error = (*rf->switch_radio)(rf, on);
- if (error != 0)
- goto fail;
- error = zyd_unlock_phy(sc);
-fail:
- return (error);
-}
-
-static int
-zyd_set_led(struct zyd_softc *sc, int which, int on)
-{
- int error;
- uint32_t tmp;
-
- zyd_read32_m(sc, ZYD_MAC_TX_PE_CONTROL, &tmp);
- tmp &= ~which;
- if (on)
- tmp |= which;
- zyd_write32_m(sc, ZYD_MAC_TX_PE_CONTROL, tmp);
-fail:
- return (error);
-}
-
-static void
-zyd_multitask(struct usb2_proc_msg *pm)
-{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
-
- zyd_set_multi(sc);
-}
-
-static void
-zyd_set_multi(struct zyd_softc *sc)
-{
- int error;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifmultiaddr *ifma;
- uint32_t low, high;
- uint8_t v;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
- low = 0x00000000;
- high = 0x80000000;
-
- if (ic->ic_opmode == IEEE80211_M_MONITOR ||
- (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
- low = 0xffffffff;
- high = 0xffffffff;
- } else {
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- v = ((uint8_t *)LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr))[5] >> 2;
- if (v < 32)
- low |= 1 << v;
- else
- high |= 1 << (v - 32);
- }
- IF_ADDR_UNLOCK(ifp);
- }
-
- /* reprogram multicast global hash table */
- zyd_write32_m(sc, ZYD_MAC_GHTBL, low);
- zyd_write32_m(sc, ZYD_MAC_GHTBH, high);
-fail:
- if (error != 0)
- device_printf(sc->sc_dev,
- "could not set multicast hash table\n");
-}
-
-static void
-zyd_update_mcast(struct ifnet *ifp)
-{
- struct zyd_softc *sc = ifp->if_softc;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
- ZYD_LOCK(sc);
- zyd_queue_command(sc, zyd_multitask,
- &sc->sc_mcasttask[0].hdr, &sc->sc_mcasttask[1].hdr);
- ZYD_UNLOCK(sc);
-}
-
-static int
-zyd_set_rxfilter(struct zyd_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t rxfilter;
-
- switch (ic->ic_opmode) {
- case IEEE80211_M_STA:
- rxfilter = ZYD_FILTER_BSS;
- break;
- case IEEE80211_M_IBSS:
- case IEEE80211_M_HOSTAP:
- rxfilter = ZYD_FILTER_HOSTAP;
- break;
- case IEEE80211_M_MONITOR:
- rxfilter = ZYD_FILTER_MONITOR;
- break;
- default:
- /* should not get there */
- return (EINVAL);
- }
- return zyd_write32(sc, ZYD_MAC_RXFILTER, rxfilter);
-}
-
-static void
-zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c)
-{
- int error;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct zyd_rf *rf = &sc->sc_rf;
- uint32_t tmp;
- int chan;
-
- chan = ieee80211_chan2ieee(ic, c);
- if (chan == 0 || chan == IEEE80211_CHAN_ANY) {
- /* XXX should NEVER happen */
- device_printf(sc->sc_dev,
- "%s: invalid channel %x\n", __func__, chan);
- return;
- }
-
- error = zyd_lock_phy(sc);
- if (error != 0)
- goto fail;
-
- error = (*rf->set_channel)(rf, chan);
- if (error != 0)
- goto fail;
-
- /* update Tx power */
- zyd_write16_m(sc, ZYD_CR31, sc->sc_pwrint[chan - 1]);
-
- if (sc->sc_macrev == ZYD_ZD1211B) {
- zyd_write16_m(sc, ZYD_CR67, sc->sc_ofdm36_cal[chan - 1]);
- zyd_write16_m(sc, ZYD_CR66, sc->sc_ofdm48_cal[chan - 1]);
- zyd_write16_m(sc, ZYD_CR65, sc->sc_ofdm54_cal[chan - 1]);
- zyd_write16_m(sc, ZYD_CR68, sc->sc_pwrcal[chan - 1]);
- zyd_write16_m(sc, ZYD_CR69, 0x28);
- zyd_write16_m(sc, ZYD_CR69, 0x2a);
- }
- if (sc->sc_cckgain) {
- /* set CCK baseband gain from EEPROM */
- if (zyd_read32(sc, ZYD_EEPROM_PHY_REG, &tmp) == 0)
- zyd_write16_m(sc, ZYD_CR47, tmp & 0xff);
- }
- if (sc->sc_bandedge6 && rf->bandedge6 != NULL) {
- error = (*rf->bandedge6)(rf, c);
- if (error != 0)
- goto fail;
- }
- zyd_write32_m(sc, ZYD_CR_CONFIG_PHILIPS, 0);
-
- error = zyd_unlock_phy(sc);
- if (error != 0)
- goto fail;
-
- sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq =
- htole16(c->ic_freq);
- sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags =
- htole16(c->ic_flags);
-fail:
- return;
-}
-
-static int
-zyd_set_beacon_interval(struct zyd_softc *sc, int bintval)
-{
- int error;
- uint32_t val;
-
- zyd_read32_m(sc, ZYD_CR_ATIM_WND_PERIOD, &val);
- sc->sc_atim_wnd = val;
- zyd_read32_m(sc, ZYD_CR_PRE_TBTT, &val);
- sc->sc_pre_tbtt = val;
- sc->sc_bcn_int = bintval;
-
- if (sc->sc_bcn_int <= 5)
- sc->sc_bcn_int = 5;
- if (sc->sc_pre_tbtt < 4 || sc->sc_pre_tbtt >= sc->sc_bcn_int)
- sc->sc_pre_tbtt = sc->sc_bcn_int - 1;
- if (sc->sc_atim_wnd >= sc->sc_pre_tbtt)
- sc->sc_atim_wnd = sc->sc_pre_tbtt - 1;
-
- zyd_write32_m(sc, ZYD_CR_ATIM_WND_PERIOD, sc->sc_atim_wnd);
- zyd_write32_m(sc, ZYD_CR_PRE_TBTT, sc->sc_pre_tbtt);
- zyd_write32_m(sc, ZYD_CR_BCN_INTERVAL, sc->sc_bcn_int);
-fail:
- return (error);
-}
-
-static void
-zyd_rx_data(struct usb2_xfer *xfer, int offset, uint16_t len)
-{
- struct zyd_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct zyd_plcphdr plcp;
- struct zyd_rx_stat stat;
- struct mbuf *m;
- int rlen, rssi;
-
- if (len < ZYD_MIN_FRAGSZ) {
- DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too short (length=%d)\n",
- device_get_nameunit(sc->sc_dev), len);
- ifp->if_ierrors++;
- return;
- }
- usb2_copy_out(xfer->frbuffers, offset, &plcp, sizeof(plcp));
- usb2_copy_out(xfer->frbuffers, offset + len - sizeof(stat),
- &stat, sizeof(stat));
-
- if (stat.flags & ZYD_RX_ERROR) {
- DPRINTF(sc, ZYD_DEBUG_RECV,
- "%s: RX status indicated error (%x)\n",
- device_get_nameunit(sc->sc_dev), stat.flags);
- ifp->if_ierrors++;
- return;
- }
-
- /* compute actual frame length */
- rlen = len - sizeof(struct zyd_plcphdr) -
- sizeof(struct zyd_rx_stat) - IEEE80211_CRC_LEN;
-
- /* allocate a mbuf to store the frame */
- if (rlen > MCLBYTES) {
- DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too long (length=%d)\n",
- device_get_nameunit(sc->sc_dev), rlen);
- ifp->if_ierrors++;
- return;
- } else if (rlen > MHLEN)
- m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- else
- m = m_gethdr(M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- DPRINTF(sc, ZYD_DEBUG_RECV, "%s: could not allocate rx mbuf\n",
- device_get_nameunit(sc->sc_dev));
- ifp->if_ierrors++;
- return;
- }
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = rlen;
- usb2_copy_out(xfer->frbuffers, offset + sizeof(plcp),
- mtod(m, uint8_t *), rlen);
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap;
-
- tap->wr_flags = 0;
- if (stat.flags & (ZYD_RX_BADCRC16 | ZYD_RX_BADCRC32))
- tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
- /* XXX toss, no way to express errors */
- if (stat.flags & ZYD_RX_DECRYPTERR)
- tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
- tap->wr_rate = ieee80211_plcp2rate(plcp.signal,
- (stat.flags & ZYD_RX_OFDM) ?
- IEEE80211_T_OFDM : IEEE80211_T_CCK);
- tap->wr_antsignal = stat.rssi + -95;
- tap->wr_antnoise = -95; /* XXX */
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
- }
- rssi = (stat.rssi > 63) ? 127 : 2 * stat.rssi;
-
- sc->sc_rx_data[sc->sc_rx_count].rssi = rssi;
- sc->sc_rx_data[sc->sc_rx_count].m = m;
- sc->sc_rx_count++;
-}
-
-static void
-zyd_bulk_read_callback(struct usb2_xfer *xfer)
-{
- struct zyd_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211_node *ni;
- struct zyd_rx_desc desc;
- struct mbuf *m;
- uint32_t offset;
- uint8_t rssi;
- int8_t nf;
- int i;
-
- sc->sc_rx_count = 0;
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- usb2_copy_out(xfer->frbuffers, xfer->actlen - sizeof(desc),
- &desc, sizeof(desc));
-
- offset = 0;
- if (UGETW(desc.tag) == ZYD_TAG_MULTIFRAME) {
- DPRINTF(sc, ZYD_DEBUG_RECV,
- "%s: received multi-frame transfer\n", __func__);
-
- for (i = 0; i < ZYD_MAX_RXFRAMECNT; i++) {
- uint16_t len16 = UGETW(desc.len[i]);
-
- if (len16 == 0 || len16 > xfer->actlen)
- break;
-
- zyd_rx_data(xfer, offset, len16);
-
- /* next frame is aligned on a 32-bit boundary */
- len16 = (len16 + 3) & ~3;
- offset += len16;
- if (len16 > xfer->actlen)
- break;
- xfer->actlen -= len16;
- }
- } else {
- DPRINTF(sc, ZYD_DEBUG_RECV,
- "%s: received single-frame transfer\n", __func__);
-
- zyd_rx_data(xfer, 0, xfer->actlen);
- }
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
-
- /*
- * At the end of a USB callback it is always safe to unlock
- * the private mutex of a device! That is why we do the
- * "ieee80211_input" here, and not some lines up!
- */
- ZYD_UNLOCK(sc);
- for (i = 0; i < sc->sc_rx_count; i++) {
- rssi = sc->sc_rx_data[i].rssi;
- m = sc->sc_rx_data[i].m;
- sc->sc_rx_data[i].m = NULL;
-
- nf = -95; /* XXX */
-
- ni = ieee80211_find_rxnode(ic,
- mtod(m, struct ieee80211_frame_min *));
- if (ni != NULL) {
- (void)ieee80211_input(ni, m, rssi, nf, 0);
- ieee80211_free_node(ni);
- } else
- (void)ieee80211_input_all(ic, m, rssi, nf, 0);
- }
- ZYD_LOCK(sc);
- break;
-
- default: /* Error */
- DPRINTF(sc, ZYD_DEBUG_ANY, "frame error: %s\n", usb2_errstr(xfer->error));
-
- if (xfer->error != USB_ERR_CANCELLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- break;
- }
-}
-
-static uint8_t
-zyd_plcp_signal(int rate)
-{
- switch (rate) {
- /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
- case 12:
- return (0xb);
- case 18:
- return (0xf);
- case 24:
- return (0xa);
- case 36:
- return (0xe);
- case 48:
- return (0x9);
- case 72:
- return (0xd);
- case 96:
- return (0x8);
- case 108:
- return (0xc);
- /* CCK rates (NB: not IEEE std, device-specific) */
- case 2:
- return (0x0);
- case 4:
- return (0x1);
- case 11:
- return (0x2);
- case 22:
- return (0x3);
- }
- return (0xff); /* XXX unsupported/unknown rate */
-}
-
-static int
-zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
- struct zyd_tx_desc *desc;
- struct zyd_tx_data *data;
- struct ieee80211_frame *wh;
- struct ieee80211_key *k;
- int rate, totlen;
- uint16_t pktlen;
-
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
- desc = &data->desc;
-
- rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
-
- wh = mtod(m0, struct ieee80211_frame *);
-
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return (ENOBUFS);
- }
- }
-
- data->ni = ni;
- data->m = m0;
- data->rate = rate;
-
- wh = mtod(m0, struct ieee80211_frame *);
-
- totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
-
- /* fill Tx descriptor */
- desc->len = htole16(totlen);
-
- desc->flags = ZYD_TX_FLAG_BACKOFF;
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- /* multicast frames are not sent at OFDM rates in 802.11b/g */
- if (totlen > vap->iv_rtsthreshold) {
- desc->flags |= ZYD_TX_FLAG_RTS;
- } else if (ZYD_RATE_IS_OFDM(rate) &&
- (ic->ic_flags & IEEE80211_F_USEPROT)) {
- if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
- desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF;
- else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
- desc->flags |= ZYD_TX_FLAG_RTS;
- }
- } else
- desc->flags |= ZYD_TX_FLAG_MULTICAST;
-
- if ((wh->i_fc[0] &
- (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
- (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL))
- desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL);
-
- desc->phy = zyd_plcp_signal(rate);
- if (ZYD_RATE_IS_OFDM(rate)) {
- desc->phy |= ZYD_TX_PHY_OFDM;
- if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
- desc->phy |= ZYD_TX_PHY_5GHZ;
- } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
-
- /* actual transmit length (XXX why +10?) */
- pktlen = ZYD_TX_DESC_SIZE + 10;
- if (sc->sc_macrev == ZYD_ZD1211)
- pktlen += totlen;
- desc->pktlen = htole16(pktlen);
-
- desc->plcp_length = (16 * totlen + rate - 1) / rate;
- desc->plcp_service = 0;
- if (rate == 22) {
- const int remainder = (16 * totlen) % 22;
- if (remainder != 0 && remainder < 7)
- desc->plcp_service |= ZYD_PLCP_LENGEXT;
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = rate;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
- }
-
- DPRINTF(sc, ZYD_DEBUG_XMIT,
- "%s: sending mgt frame len=%zu rate=%u\n",
- device_get_nameunit(sc->sc_dev), (size_t)m0->m_pkthdr.len,
- rate);
-
- STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
- usb2_transfer_start(sc->sc_xfer[ZYD_BULK_WR]);
-
- return (0);
-}
-
-static void
-zyd_bulk_write_callback(struct usb2_xfer *xfer)
-{
- struct zyd_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211_channel *c = ic->ic_curchan;
- struct zyd_tx_data *data;
- struct mbuf *m;
-
- switch (USB_GET_STATE(xfer)) {
- case USB_ST_TRANSFERRED:
- DPRINTF(sc, ZYD_DEBUG_ANY, "transfer complete, %u bytes\n",
- xfer->actlen);
-
- /* free resources */
- data = xfer->priv_fifo;
- zyd_tx_free(data, 0);
- xfer->priv_fifo = NULL;
-
- ifp->if_opackets++;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- /* FALLTHROUGH */
- case USB_ST_SETUP:
-tr_setup:
- data = STAILQ_FIRST(&sc->tx_q);
- if (data) {
- STAILQ_REMOVE_HEAD(&sc->tx_q, next);
- m = data->m;
-
- if (m->m_pkthdr.len > ZYD_MAX_TXBUFSZ) {
- DPRINTF(sc, ZYD_DEBUG_ANY, "data overflow, %u bytes\n",
- m->m_pkthdr.len);
- m->m_pkthdr.len = ZYD_MAX_TXBUFSZ;
- }
- usb2_copy_in(xfer->frbuffers, 0, &data->desc,
- ZYD_TX_DESC_SIZE);
- usb2_m_copy_in(xfer->frbuffers, ZYD_TX_DESC_SIZE, m, 0,
- m->m_pkthdr.len);
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = data->rate;
- tap->wt_chan_freq = htole16(c->ic_freq);
- tap->wt_chan_flags = htole16(c->ic_flags);
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
- }
-
- xfer->frlengths[0] = ZYD_TX_DESC_SIZE + m->m_pkthdr.len;
- xfer->priv_fifo = data;
- usb2_start_hardware(xfer);
- }
- break;
-
- default: /* Error */
- DPRINTF(sc, ZYD_DEBUG_ANY, "transfer error, %s\n",
- usb2_errstr(xfer->error));
-
- ifp->if_oerrors++;
- data = xfer->priv_fifo;
- xfer->priv_fifo = NULL;
- if (data != NULL)
- zyd_tx_free(data, xfer->error);
-
- if (xfer->error == USB_ERR_STALLED) {
- /* try to clear stall first */
- xfer->flags.stall_pipe = 1;
- goto tr_setup;
- }
- if (xfer->error == USB_ERR_TIMEOUT)
- device_printf(sc->sc_dev, "device timeout\n");
- break;
- }
-}
-
-static int
-zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct zyd_tx_desc *desc;
- struct zyd_tx_data *data;
- struct ieee80211_frame *wh;
- const struct ieee80211_txparam *tp;
- struct ieee80211_key *k;
- int rate, totlen;
- uint16_t pktlen;
-
- wh = mtod(m0, struct ieee80211_frame *);
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
- desc = &data->desc;
-
- desc->flags = ZYD_TX_FLAG_BACKOFF;
- tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
- if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- rate = tp->mcastrate;
- desc->flags |= ZYD_TX_FLAG_MULTICAST;
- } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
- rate = tp->ucastrate;
- } else {
- (void) ieee80211_amrr_choose(ni, &ZYD_NODE(ni)->amn);
- rate = ni->ni_txrate;
- }
-
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return (ENOBUFS);
- }
- /* packet header may have moved, reset our local pointer */
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- data->ni = ni;
- data->m = m0;
-
- totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
-
- /* fill Tx descriptor */
- desc->len = htole16(totlen);
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- /* multicast frames are not sent at OFDM rates in 802.11b/g */
- if (totlen > vap->iv_rtsthreshold) {
- desc->flags |= ZYD_TX_FLAG_RTS;
- } else if (ZYD_RATE_IS_OFDM(rate) &&
- (ic->ic_flags & IEEE80211_F_USEPROT)) {
- if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
- desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF;
- else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
- desc->flags |= ZYD_TX_FLAG_RTS;
- }
- }
-
- if ((wh->i_fc[0] &
- (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
- (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL))
- desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL);
-
- desc->phy = zyd_plcp_signal(rate);
- if (ZYD_RATE_IS_OFDM(rate)) {
- desc->phy |= ZYD_TX_PHY_OFDM;
- if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
- desc->phy |= ZYD_TX_PHY_5GHZ;
- } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
-
- /* actual transmit length (XXX why +10?) */
- pktlen = sizeof(struct zyd_tx_desc) + 10;
- if (sc->sc_macrev == ZYD_ZD1211)
- pktlen += totlen;
- desc->pktlen = htole16(pktlen);
-
- desc->plcp_length = (16 * totlen + rate - 1) / rate;
- desc->plcp_service = 0;
- if (rate == 22) {
- const int remainder = (16 * totlen) % 22;
- if (remainder != 0 && remainder < 7)
- desc->plcp_service |= ZYD_PLCP_LENGEXT;
- }
-
- DPRINTF(sc, ZYD_DEBUG_XMIT,
- "%s: sending data frame len=%zu rate=%u\n",
- device_get_nameunit(sc->sc_dev), (size_t)m0->m_pkthdr.len,
- rate);
-
- STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
- usb2_transfer_start(sc->sc_xfer[ZYD_BULK_WR]);
-
- return (0);
-}
-
-static void
-zyd_start(struct ifnet *ifp)
-{
- struct zyd_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- ZYD_LOCK(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->tx_nfree == 0) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
- ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
- m = ieee80211_encap(ni, m);
- if (m == NULL) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- continue;
- }
- if (zyd_tx_data(sc, m, ni) != 0) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- break;
- }
- }
- ZYD_UNLOCK(sc);
-}
-
-static int
-zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
- const struct ieee80211_bpf_params *params)
-{
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct zyd_softc *sc = ifp->if_softc;
-
- ZYD_LOCK(sc);
- /* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- ZYD_UNLOCK(sc);
- m_freem(m);
- ieee80211_free_node(ni);
- return (ENETDOWN);
- }
- if (sc->tx_nfree == 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- ZYD_UNLOCK(sc);
- m_freem(m);
- ieee80211_free_node(ni);
- return (ENOBUFS); /* XXX */
- }
-
- /*
- * Legacy path; interpret frame contents to decide
- * precisely how to send the frame.
- * XXX raw path
- */
- if (zyd_tx_mgt(sc, m, ni) != 0) {
- ZYD_UNLOCK(sc);
- ifp->if_oerrors++;
- ieee80211_free_node(ni);
- return (EIO);
- }
- ZYD_UNLOCK(sc);
- return (0);
-}
-
-static int
-zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct zyd_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- ZYD_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if ((ifp->if_flags ^ sc->sc_if_flags) &
- (IFF_ALLMULTI | IFF_PROMISC))
- zyd_set_multi(sc);
- } else {
- zyd_queue_command(sc, zyd_init_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- zyd_queue_command(sc, zyd_stop_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- }
- }
- sc->sc_if_flags = ifp->if_flags;
- ZYD_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return (error);
-}
-
-static void
-zyd_init_task(struct usb2_proc_msg *pm)
-{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct usb2_config_descriptor *cd;
- int error;
- uint32_t val;
-
- ZYD_LOCK_ASSERT(sc, MA_OWNED);
-
- if (!(sc->sc_flags & ZYD_FLAG_INITONCE)) {
- error = zyd_loadfirmware(sc);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "could not load firmware (error=%d)\n", error);
- goto fail;
- }
-
- /* reset device */
- cd = usb2_get_config_descriptor(sc->sc_udev);
- error = usb2_req_set_config(sc->sc_udev, &sc->sc_mtx,
- cd->bConfigurationValue);
- if (error)
- device_printf(sc->sc_dev, "reset failed, continuing\n");
-
- error = zyd_hw_init(sc);
- if (error) {
- device_printf(sc->sc_dev,
- "hardware initialization failed\n");
- goto fail;
- }
-
- device_printf(sc->sc_dev,
- "HMAC ZD1211%s, FW %02x.%02x, RF %s S%x, PA%x LED %x "
- "BE%x NP%x Gain%x F%x\n",
- (sc->sc_macrev == ZYD_ZD1211) ? "": "B",
- sc->sc_fwrev >> 8, sc->sc_fwrev & 0xff,
- zyd_rf_name(sc->sc_rfrev), sc->sc_al2230s, sc->sc_parev,
- sc->sc_ledtype, sc->sc_bandedge6, sc->sc_newphy,
- sc->sc_cckgain, sc->sc_fix_cr157);
-
- /* read regulatory domain (currently unused) */
- zyd_read32_m(sc, ZYD_EEPROM_SUBID, &val);
- sc->sc_regdomain = val >> 16;
- DPRINTF(sc, ZYD_DEBUG_INIT, "regulatory domain %x\n",
- sc->sc_regdomain);
-
- /* we'll do software WEP decryption for now */
- DPRINTF(sc, ZYD_DEBUG_INIT, "%s: setting encryption type\n",
- __func__);
- zyd_write32_m(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER);
-
- sc->sc_flags |= ZYD_FLAG_INITONCE;
- }
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- zyd_stop_task(pm);
-
- IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
- DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %s\n",
- ether_sprintf(ic->ic_myaddr));
- error = zyd_set_macaddr(sc, ic->ic_myaddr);
- if (error != 0)
- return;
-
- /* set basic rates */
- if (ic->ic_curmode == IEEE80211_MODE_11B)
- zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x0003);
- else if (ic->ic_curmode == IEEE80211_MODE_11A)
- zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x1500);
- else /* assumes 802.11b/g */
- zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0xff0f);
-
- /* promiscuous mode */
- zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0);
- /* multicast setup */
- zyd_set_multi(sc);
- /* set RX filter */
- error = zyd_set_rxfilter(sc);
- if (error != 0)
- goto fail;
-
- /* switch radio transmitter ON */
- error = zyd_switch_radio(sc, 1);
- if (error != 0)
- goto fail;
- /* set default BSS channel */
- zyd_set_chan(sc, ic->ic_curchan);
-
- /*
- * Allocate Tx and Rx xfer queues.
- */
- zyd_setup_tx_list(sc);
-
- /* enable interrupts */
- zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- usb2_transfer_start(sc->sc_xfer[ZYD_BULK_RD]);
- usb2_transfer_start(sc->sc_xfer[ZYD_INTR_RD]);
-
- return;
-
-fail: zyd_stop_task(pm);
- return;
-}
-
-static void
-zyd_init(void *priv)
-{
- struct zyd_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- ZYD_LOCK(sc);
- zyd_queue_command(sc, zyd_init_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- ZYD_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
-zyd_stop_task(struct usb2_proc_msg *pm)
-{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- int error;
-
- ZYD_LOCK_ASSERT(sc, MA_OWNED);
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- /*
- * Drain all the transfers, if not already drained:
- */
- ZYD_UNLOCK(sc);
- usb2_transfer_drain(sc->sc_xfer[ZYD_BULK_WR]);
- usb2_transfer_drain(sc->sc_xfer[ZYD_BULK_RD]);
- ZYD_LOCK(sc);
-
- zyd_unsetup_tx_list(sc);
-
- /* Stop now if the device was never set up */
- if (!(sc->sc_flags & ZYD_FLAG_INITONCE))
- return;
-
- /* switch radio transmitter OFF */
- error = zyd_switch_radio(sc, 0);
- if (error != 0)
- goto fail;
- /* disable Rx */
- zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0);
- /* disable interrupts */
- zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0);
-
-fail:
- return;
-}
-
-static int
-zyd_loadfirmware(struct zyd_softc *sc)
-{
- struct usb2_device_request req;
- size_t size;
- u_char *fw;
- uint8_t stat;
- uint16_t addr;
-
- if (sc->sc_flags & ZYD_FLAG_FWLOADED)
- return (0);
-
- if (sc->sc_macrev == ZYD_ZD1211) {
- fw = (u_char *)zd1211_firmware;
- size = sizeof(zd1211_firmware);
- } else {
- fw = (u_char *)zd1211b_firmware;
- size = sizeof(zd1211b_firmware);
- }
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = ZYD_DOWNLOADREQ;
- USETW(req.wIndex, 0);
-
- addr = ZYD_FIRMWARE_START_ADDR;
- while (size > 0) {
- /*
- * When the transfer size is 4096 bytes, it is not
- * likely to be able to transfer it.
- * The cause is port or machine or chip?
- */
- const int mlen = min(size, 64);
-
- DPRINTF(sc, ZYD_DEBUG_FW,
- "loading firmware block: len=%d, addr=0x%x\n", mlen, addr);
-
- USETW(req.wValue, addr);
- USETW(req.wLength, mlen);
- if (zyd_do_request(sc, &req, fw) != 0)
- return (EIO);
-
- addr += mlen / 2;
- fw += mlen;
- size -= mlen;
- }
-
- /* check whether the upload succeeded */
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = ZYD_DOWNLOADSTS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(stat));
- if (zyd_do_request(sc, &req, &stat) != 0)
- return (EIO);
-
- sc->sc_flags |= ZYD_FLAG_FWLOADED;
-
- return (stat & 0x80) ? (EIO) : (0);
-}
-
-static void
-zyd_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&ZYD_VAP(vap)->amrr, &ZYD_NODE(ni)->amn, ni);
-}
-
-static void
-zyd_scan_start(struct ieee80211com *ic)
-{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
-
- ZYD_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = ZYD_SCAN_START;
- zyd_queue_command(sc, zyd_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
- ZYD_UNLOCK(sc);
-}
-
-static void
-zyd_scan_end(struct ieee80211com *ic)
-{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
-
- ZYD_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = ZYD_SCAN_END;
- zyd_queue_command(sc, zyd_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
- ZYD_UNLOCK(sc);
-}
-
-static void
-zyd_set_channel(struct ieee80211com *ic)
-{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
-
- ZYD_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = ZYD_SET_CHANNEL;
- zyd_queue_command(sc, zyd_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
- ZYD_UNLOCK(sc);
-}
-
-static void
-zyd_scantask(struct usb2_proc_msg *pm)
-{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- ZYD_LOCK_ASSERT(sc, MA_OWNED);
-
- switch (sc->sc_scan_action) {
- case ZYD_SCAN_START:
- /* want broadcast address while scanning */
- zyd_set_bssid(sc, ifp->if_broadcastaddr);
- break;
-
- case ZYD_SET_CHANNEL:
- zyd_set_chan(sc, ic->ic_curchan);
- break;
-
- default: /* ZYD_SCAN_END */
- /* restore previous bssid */
- zyd_set_bssid(sc, sc->sc_bssid);
- break;
- }
-}
-
-static void
-zyd_queue_command(struct zyd_softc *sc, usb2_proc_callback_t *fn,
- struct usb2_proc_msg *t0, struct usb2_proc_msg *t1)
-{
- struct zyd_task *task;
-
- ZYD_LOCK_ASSERT(sc, MA_OWNED);
-
- if (usb2_proc_is_gone(&sc->sc_tq)) {
- DPRINTF(sc, ZYD_DEBUG_STATE, "proc is gone\n");
- return; /* nothing to do */
- }
- /*
- * NOTE: The task cannot get executed before we drop the
- * "sc_mtx" mutex. It is safe to update fields in the message
- * structure after that the message got queued.
- */
- task = (struct zyd_task *)
- usb2_proc_msignal(&sc->sc_tq, t0, t1);
-
- /* Setup callback and softc pointers */
- task->hdr.pm_callback = fn;
- task->sc = sc;
-
- /*
- * Init and stop must be synchronous!
- */
- if ((fn == zyd_init_task) || (fn == zyd_stop_task))
- usb2_proc_mwait(&sc->sc_tq, t0, t1);
-}
-
-static device_method_t zyd_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, zyd_match),
- DEVMETHOD(device_attach, zyd_attach),
- DEVMETHOD(device_detach, zyd_detach),
-
- { 0, 0 }
-};
-
-static driver_t zyd_driver = {
- "zyd",
- zyd_methods,
- sizeof(struct zyd_softc)
-};
-
-static devclass_t zyd_devclass;
-
-DRIVER_MODULE(zyd, ushub, zyd_driver, zyd_devclass, NULL, 0);
-MODULE_DEPEND(zyd, usb2_wlan, 1, 1, 1);
-MODULE_DEPEND(zyd, usb2_core, 1, 1, 1);
-MODULE_DEPEND(zyd, wlan, 1, 1, 1);
-MODULE_DEPEND(zyd, wlan_amrr, 1, 1, 1);
diff --git a/sys/dev/usb2/wlan/if_zydfw.h b/sys/dev/usb2/wlan/if_zydfw.h
deleted file mode 100644
index 46f5c2a..0000000
--- a/sys/dev/usb2/wlan/if_zydfw.h
+++ /dev/null
@@ -1,1144 +0,0 @@
-/*
- * Copyright (C) 2001, 2002, 2003,2004 ZyDAS Technology Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted provided
- * that the following conditions are met:
- * 1. Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistribution in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* $FreeBSD$ */
-
-uint8_t zd1211_firmware[] = {
- 0x08, 0x91, 0xFF, 0xED, 0x09, 0x93, 0x1E, 0xEE,
- 0xD1, 0x94, 0x11, 0xEE, 0x88, 0xD4, 0xD1, 0x96,
- 0xD1, 0x98, 0x5C, 0x99, 0x5C, 0x99, 0x4C, 0x99,
- 0x04, 0x9D, 0xD1, 0x98, 0xD1, 0x9A, 0x03, 0xEE,
- 0xF4, 0x94, 0xD3, 0xD4, 0x41, 0x2A, 0x40, 0x4A,
- 0x45, 0xBE, 0x88, 0x92, 0x41, 0x24, 0x40, 0x44,
- 0x53, 0xBE, 0x40, 0xF0, 0x93, 0xEE, 0x41, 0xEE,
- 0x98, 0x9A, 0xD4, 0xF7, 0x02, 0x00, 0x1F, 0xEC,
- 0x00, 0x00, 0xB2, 0xF8, 0x4D, 0x00, 0xA1, 0xEC,
- 0x00, 0x00, 0xA6, 0xF7, 0x21, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xD8,
- 0xA0, 0x90, 0x98, 0x9A, 0x98, 0x9A, 0xA0, 0xD8,
- 0x40, 0xF0, 0xB4, 0xF0, 0xA0, 0x90, 0x98, 0x9A,
- 0xA0, 0xD8, 0x40, 0xF0, 0x64, 0xEF, 0xA0, 0x90,
- 0x98, 0x9A, 0xA0, 0xD8, 0x40, 0xF0, 0xF6, 0xF0,
- 0xA0, 0x90, 0x98, 0x9A, 0xA0, 0xD8, 0x40, 0xF0,
- 0xF7, 0xF6, 0xA0, 0x90, 0x98, 0x9A, 0xA0, 0xD8,
- 0x40, 0xF0, 0xF8, 0xF5, 0xA0, 0x90, 0x98, 0x9A,
- 0xA0, 0xD8, 0x40, 0xF0, 0xF1, 0xF0, 0xA0, 0x90,
- 0x98, 0x9A, 0x98, 0x9A, 0xA0, 0xD8, 0x40, 0xF0,
- 0x97, 0xF7, 0xA0, 0x90, 0x98, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x0D, 0x03, 0x03, 0x00,
- 0x09, 0x05, 0x01, 0x00, 0xC2, 0x94, 0x42, 0x02,
- 0xC1, 0x92, 0x03, 0x96, 0x1B, 0xD7, 0x2A, 0x86,
- 0x1A, 0xD5, 0x2B, 0x86, 0x09, 0xA3, 0x00, 0x80,
- 0x19, 0xD3, 0x2C, 0x86, 0x00, 0xEE, 0x0A, 0x65,
- 0xC0, 0x7A, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3,
- 0xFE, 0xFF, 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x42, 0x20, 0x08, 0x0B, 0x01, 0x00,
- 0x0D, 0x03, 0x05, 0x00, 0x05, 0x94, 0xC5, 0xD4,
- 0x09, 0x05, 0x01, 0x00, 0xC2, 0x94, 0x01, 0xD4,
- 0x42, 0x02, 0xC1, 0x96, 0x0A, 0x65, 0xC0, 0x7A,
- 0x02, 0x99, 0xC4, 0x92, 0x41, 0xA2, 0xC4, 0xD2,
- 0xC5, 0x98, 0x1C, 0xD9, 0x2A, 0x86, 0x01, 0x98,
- 0x1C, 0xD9, 0x2B, 0x86, 0x1B, 0xD7, 0x2C, 0x86,
- 0x00, 0xEE, 0x09, 0xB3, 0xFE, 0xFF, 0xC2, 0xD2,
- 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x41, 0x20, 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0,
- 0xE5, 0xEE, 0x11, 0x93, 0xD8, 0xF7, 0x41, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0xAE, 0xEE, 0x40, 0xF1,
- 0x40, 0x92, 0x19, 0xD3, 0xD8, 0xF7, 0xC5, 0x92,
- 0x41, 0x92, 0x19, 0xD3, 0x00, 0x83, 0x40, 0x92,
- 0x19, 0xD3, 0x00, 0x83, 0x0F, 0x9F, 0x95, 0xF8,
- 0x0F, 0x9F, 0x99, 0xEE, 0x42, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0x99, 0xEE, 0x40, 0x92, 0x19, 0xD3,
- 0xD8, 0xF7, 0x09, 0x93, 0xC7, 0xF7, 0x19, 0xD3,
- 0x91, 0xEC, 0x40, 0xF0, 0x5F, 0xF2, 0x09, 0x63,
- 0x00, 0x80, 0x19, 0xD3, 0xF2, 0xBD, 0x0F, 0x9F,
- 0x99, 0xEE, 0x41, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0x92,
- 0x19, 0xD3, 0x12, 0x95, 0x19, 0xD3, 0x10, 0x95,
- 0x19, 0xD3, 0x02, 0x80, 0x19, 0xD3, 0x03, 0x82,
- 0x09, 0x93, 0xC7, 0xF7, 0x19, 0xD3, 0x91, 0xEC,
- 0x40, 0xF0, 0x5F, 0xF2, 0x40, 0xF0, 0xDE, 0xF3,
- 0x11, 0x93, 0x04, 0xEC, 0x42, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0xE3, 0xEE, 0x40, 0x92, 0x19, 0xD3,
- 0x04, 0xEC, 0x40, 0xF0, 0x38, 0xF2, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00,
- 0x11, 0x93, 0x44, 0x96, 0x09, 0xB3, 0xFF, 0xFD,
- 0x19, 0xD3, 0x44, 0x96, 0x40, 0xF0, 0x90, 0xF7,
- 0x6E, 0x92, 0x19, 0xD3, 0x05, 0x84, 0x40, 0xF0,
- 0xC4, 0xEE, 0x4B, 0x62, 0x0A, 0x95, 0x2E, 0xEE,
- 0xD1, 0xD4, 0x0B, 0x97, 0x2B, 0xEE, 0xD1, 0xD6,
- 0x0A, 0x95, 0x00, 0xEE, 0xD1, 0xD4, 0x0B, 0x97,
- 0x2F, 0xEE, 0xD1, 0xD6, 0x0A, 0x95, 0x34, 0xEE,
- 0xD1, 0xD4, 0x0B, 0x97, 0x39, 0xEE, 0xD1, 0xD6,
- 0x0A, 0x95, 0x3E, 0xEE, 0xD1, 0xD4, 0x0B, 0x97,
- 0x43, 0xEE, 0xD1, 0xD6, 0x0A, 0x95, 0x48, 0xEE,
- 0xD1, 0xD4, 0x0B, 0x97, 0x4D, 0xEE, 0xD1, 0xD6,
- 0x0A, 0x95, 0x4E, 0xEE, 0xC1, 0xD4, 0x0A, 0x65,
- 0x00, 0x44, 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2,
- 0xC2, 0xD2, 0x43, 0xF1, 0x09, 0x93, 0x01, 0x3F,
- 0x19, 0xD3, 0xC0, 0x85, 0x11, 0x93, 0x44, 0x96,
- 0x09, 0xB3, 0xFF, 0xFC, 0x19, 0xD3, 0x44, 0x96,
- 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B,
- 0x01, 0x00, 0x0D, 0x03, 0x03, 0x00, 0x03, 0x96,
- 0x41, 0x02, 0x03, 0x99, 0xC4, 0x94, 0x42, 0x04,
- 0xC1, 0x04, 0xC2, 0x94, 0xC3, 0xD4, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00,
- 0x40, 0x92, 0x19, 0xD3, 0x94, 0xEC, 0x13, 0x97,
- 0x95, 0xEC, 0x1B, 0xD7, 0x02, 0x80, 0x11, 0x93,
- 0x99, 0xEC, 0x19, 0xD3, 0x7C, 0x96, 0x0B, 0x97,
- 0xA0, 0x00, 0x1B, 0xD7, 0x6E, 0xEC, 0x0A, 0x65,
- 0x0E, 0x42, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3,
- 0xFF, 0xBF, 0x11, 0xA3, 0x9A, 0xEC, 0xC2, 0xD2,
- 0x0A, 0x65, 0xEB, 0x43, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xA3, 0xC0, 0x00, 0xC2, 0xD2, 0x0A, 0x65,
- 0xE9, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3,
- 0xBF, 0xFF, 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x47, 0x20, 0x08, 0x0B, 0x01, 0x00,
- 0x14, 0x99, 0x03, 0x80, 0x0C, 0xB3, 0x00, 0x10,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x97, 0xF0,
- 0x11, 0x93, 0x9F, 0xEC, 0x41, 0x02, 0x19, 0xD3,
- 0x9F, 0xEC, 0x11, 0x93, 0xD6, 0xF7, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0x84, 0xEF, 0x0A, 0x65,
- 0xFE, 0x7F, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3,
- 0x00, 0x04, 0xC2, 0xD2, 0x0F, 0x9F, 0xB1, 0xF0,
- 0x11, 0x93, 0x94, 0xEC, 0x02, 0xD2, 0x40, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0xD0, 0xEF, 0x41, 0x92,
- 0x19, 0xD3, 0x94, 0xEC, 0x19, 0xD3, 0x9F, 0xEC,
- 0x12, 0x95, 0x02, 0x80, 0x1A, 0xD5, 0x95, 0xEC,
- 0x13, 0x97, 0x7C, 0x96, 0x1B, 0xD7, 0x99, 0xEC,
- 0x0A, 0x65, 0x0E, 0x42, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xB3, 0x00, 0x40, 0x19, 0xD3, 0x9A, 0xEC,
- 0x09, 0x63, 0x00, 0x40, 0xC2, 0xD2, 0x02, 0x94,
- 0x1A, 0xD5, 0x7C, 0x96, 0x0C, 0xB3, 0x00, 0x08,
- 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0xB0, 0xEF,
- 0x0C, 0xB3, 0xFF, 0x07, 0x0F, 0x9F, 0xB4, 0xEF,
- 0x11, 0x93, 0x06, 0x80, 0x09, 0xB3, 0xFF, 0x07,
- 0x09, 0x03, 0x00, 0xA0, 0x19, 0xD3, 0x97, 0xEC,
- 0x40, 0x98, 0x0B, 0x97, 0x9C, 0xEC, 0x04, 0x95,
- 0x03, 0x05, 0x14, 0x03, 0x97, 0xEC, 0x46, 0x02,
- 0xC1, 0x92, 0xC2, 0xD2, 0x41, 0x08, 0x42, 0x48,
- 0x02, 0x9E, 0x0F, 0x9F, 0xBB, 0xEF, 0x11, 0x93,
- 0x97, 0xEC, 0xC1, 0x92, 0xC5, 0xD2, 0x5F, 0xB2,
- 0x19, 0xD3, 0x9B, 0xEC, 0x0F, 0x9F, 0xD3, 0xEF,
- 0x13, 0x97, 0x98, 0xEC, 0xC5, 0xD6, 0x11, 0x93,
- 0x03, 0x80, 0x09, 0xB3, 0x00, 0x08, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0xE9, 0xEF, 0x11, 0x93,
- 0xDC, 0xF7, 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7,
- 0x11, 0x93, 0xDB, 0xF7, 0x09, 0xA3, 0x00, 0x10,
- 0x19, 0xD3, 0xDB, 0xF7, 0x40, 0x98, 0x1C, 0xD9,
- 0x9B, 0xEC, 0x12, 0x95, 0x9B, 0xEC, 0x40, 0x44,
- 0x02, 0x4E, 0x0F, 0x9F, 0x86, 0xF0, 0x0A, 0xB3,
- 0x08, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x07, 0xF0, 0x0A, 0xB3, 0x07, 0x00, 0x09, 0x05,
- 0xA9, 0xEC, 0xC2, 0x94, 0x01, 0xD4, 0x09, 0x03,
- 0xA1, 0xEC, 0xC1, 0x92, 0x19, 0xD3, 0x9B, 0xEC,
- 0xC5, 0x94, 0x0A, 0xB5, 0x00, 0xFF, 0x01, 0xA5,
- 0xC5, 0xD4, 0x0F, 0x9F, 0x13, 0xF0, 0x0A, 0x05,
- 0xFF, 0xFF, 0x0A, 0x03, 0xB1, 0xEC, 0xC1, 0x92,
- 0x01, 0xD2, 0x1A, 0xD5, 0x9B, 0xEC, 0xC5, 0x96,
- 0x0B, 0x07, 0xFF, 0xFF, 0xC5, 0xD6, 0x11, 0x93,
- 0x97, 0xEC, 0xC5, 0x98, 0xC1, 0xD8, 0x11, 0x93,
- 0x97, 0xEC, 0x09, 0x05, 0x0B, 0x00, 0x03, 0xD4,
- 0xC2, 0x96, 0x06, 0xD6, 0x7B, 0x95, 0x7A, 0x95,
- 0x4C, 0x02, 0xC1, 0x92, 0x59, 0x93, 0x59, 0x93,
- 0x01, 0xA5, 0x01, 0x98, 0x0C, 0xF5, 0x7B, 0x93,
- 0x09, 0x09, 0x01, 0x00, 0x06, 0x92, 0x09, 0xB3,
- 0xFF, 0x00, 0x04, 0xD2, 0x5C, 0x93, 0x59, 0x93,
- 0x04, 0x94, 0x01, 0xA5, 0x03, 0x96, 0xC3, 0xD4,
- 0x11, 0x93, 0x97, 0xEC, 0x4C, 0x02, 0x05, 0xD2,
- 0xC1, 0x92, 0x09, 0xB3, 0x00, 0xFF, 0x7C, 0x95,
- 0x7A, 0x95, 0x02, 0xA3, 0x05, 0x98, 0xC4, 0xD2,
- 0x12, 0x95, 0x97, 0xEC, 0x45, 0x04, 0x02, 0x97,
- 0xC3, 0x92, 0x09, 0xA3, 0x00, 0x01, 0xC2, 0xD2,
- 0x12, 0x95, 0x9B, 0xEC, 0x0A, 0xB3, 0x08, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x5B, 0xF0,
- 0x12, 0x95, 0x97, 0xEC, 0x4A, 0x04, 0x02, 0x99,
- 0xC4, 0x92, 0x01, 0x98, 0x0C, 0xF3, 0x7B, 0x93,
- 0x41, 0x02, 0x0F, 0x9F, 0x7C, 0xF0, 0x43, 0x44,
- 0x02, 0x8E, 0x0F, 0x9F, 0x7D, 0xF0, 0x11, 0x93,
- 0x97, 0xEC, 0x42, 0x02, 0x0A, 0x05, 0xFF, 0xFF,
- 0xC1, 0xD4, 0x11, 0x93, 0x97, 0xEC, 0x4A, 0x02,
- 0x12, 0x95, 0x60, 0x96, 0xC1, 0xD4, 0x12, 0x95,
- 0x97, 0xEC, 0x4B, 0x04, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xB3, 0x1F, 0xFF, 0xC2, 0xD2, 0x12, 0x95,
- 0x97, 0xEC, 0x4B, 0x04, 0x11, 0x93, 0x62, 0x96,
- 0x41, 0x93, 0x59, 0x93, 0x02, 0x99, 0xC4, 0xA2,
- 0xC2, 0xD2, 0xC5, 0x92, 0x19, 0xD3, 0x98, 0xEC,
- 0x0A, 0x95, 0x0C, 0x02, 0x1A, 0xD5, 0x02, 0x80,
- 0x0F, 0x9F, 0xB1, 0xF0, 0x09, 0x63, 0xFE, 0x7F,
- 0x01, 0x97, 0xC3, 0x94, 0x0A, 0xA5, 0x00, 0x04,
- 0xC1, 0xD4, 0x11, 0x93, 0x9F, 0xEC, 0x09, 0xA3,
- 0x00, 0x01, 0x19, 0xD3, 0x9F, 0xEC, 0x40, 0xF0,
- 0x39, 0xEF, 0x0F, 0x9F, 0xB1, 0xF0, 0x11, 0x93,
- 0x94, 0xEC, 0x41, 0x42, 0x02, 0x5E, 0x0F, 0x9F,
- 0xA6, 0xF0, 0x40, 0xF0, 0x39, 0xEF, 0x11, 0x93,
- 0x95, 0xEC, 0x44, 0xB2, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xB1, 0xF0, 0x48, 0x98, 0x1C, 0xD9,
- 0x02, 0x80, 0x11, 0x93, 0x91, 0xEC, 0x41, 0x22,
- 0x0A, 0x95, 0xB1, 0xF0, 0x88, 0xD4, 0x88, 0xDC,
- 0x91, 0x9A, 0x47, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93,
- 0x04, 0x82, 0x48, 0xB2, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xC8, 0xF0, 0x0A, 0x65, 0xFD, 0x7D,
- 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xFF, 0xFE,
- 0xC2, 0xD2, 0x41, 0x92, 0x19, 0xD3, 0xBF, 0xEC,
- 0x11, 0x93, 0x04, 0x82, 0x43, 0xB2, 0x12, 0x95,
- 0x03, 0x82, 0x02, 0xB3, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xEF, 0xF0, 0x0A, 0xB3, 0x00, 0xFF,
- 0x48, 0xA2, 0x19, 0xD3, 0x03, 0x82, 0x40, 0xF0,
- 0xEB, 0xF3, 0x11, 0x93, 0xBF, 0xEC, 0x41, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0xEF, 0xF0, 0x11, 0x93,
- 0x07, 0x82, 0x11, 0x43, 0x03, 0xEC, 0x02, 0x0E,
- 0x0F, 0x9F, 0xEF, 0xF0, 0x11, 0x93, 0x03, 0x82,
- 0x09, 0xA3, 0x00, 0x01, 0x19, 0xD3, 0x03, 0x82,
- 0x40, 0x96, 0x1B, 0xD7, 0xBF, 0xEC, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00,
- 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B,
- 0x01, 0x00, 0x11, 0x93, 0x20, 0xBC, 0xC8, 0xD2,
- 0x40, 0xF0, 0x48, 0xF1, 0x41, 0x00, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x42, 0x20, 0x08, 0x0B,
- 0x01, 0x00, 0x0D, 0x03, 0x05, 0x00, 0x05, 0x94,
- 0x41, 0x02, 0xC1, 0x92, 0x01, 0x97, 0xC3, 0x96,
- 0xC2, 0xD6, 0x0A, 0x45, 0x00, 0x95, 0x02, 0x5E,
- 0x0F, 0x9F, 0x45, 0xF1, 0xC1, 0x92, 0x41, 0xB2,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x45, 0xF1,
- 0x11, 0x93, 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0x45, 0xF1, 0x41, 0x98, 0x1C, 0xD9,
- 0xC0, 0xEC, 0x12, 0x95, 0x02, 0x80, 0x01, 0xD4,
- 0x40, 0xF0, 0x56, 0xF2, 0x0B, 0x67, 0xFD, 0x7D,
- 0x03, 0x99, 0xC4, 0x92, 0x0C, 0x99, 0x96, 0x03,
- 0x1C, 0xD9, 0x06, 0x82, 0x41, 0x98, 0x1C, 0xD9,
- 0x02, 0x82, 0x42, 0x98, 0x1C, 0xD9, 0x05, 0x82,
- 0x0C, 0x69, 0x80, 0x7F, 0x1C, 0xD9, 0x00, 0xB0,
- 0x09, 0xA3, 0x00, 0x01, 0xC3, 0xD2, 0x01, 0x94,
- 0x0A, 0xB3, 0x04, 0x00, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0x43, 0xF1, 0x42, 0xA4, 0x1A, 0xD5,
- 0x02, 0x80, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x42, 0x20, 0x08, 0x0B, 0x01, 0x00,
- 0x05, 0x92, 0xC5, 0xD2, 0x60, 0xB2, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0x55, 0xF1, 0x40, 0xF0,
- 0x35, 0xF7, 0xC5, 0x94, 0x0A, 0xB3, 0x10, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x5E, 0xF1,
- 0x40, 0xF0, 0x23, 0xF6, 0xC5, 0x96, 0x0B, 0xB3,
- 0x40, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x67, 0xF1, 0x40, 0xF0, 0x5D, 0xF5, 0xC5, 0x94,
- 0x0A, 0xB3, 0x01, 0x00, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xC8, 0xF1, 0x13, 0x97, 0x21, 0xBC,
- 0x01, 0xD6, 0x0B, 0xB3, 0x02, 0x00, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0x79, 0xF1, 0x40, 0xF0,
- 0x62, 0xFB, 0x01, 0x94, 0x0A, 0xB3, 0x04, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x82, 0xF1,
- 0x40, 0xF0, 0x6C, 0xFB, 0x01, 0x96, 0x0B, 0xB3,
- 0x01, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0xA2, 0xF1, 0x40, 0xF0, 0xB0, 0xFA, 0x41, 0x92,
- 0x19, 0xD3, 0xD5, 0xF7, 0x11, 0x93, 0x03, 0xEC,
- 0x09, 0x43, 0x40, 0x00, 0x02, 0x5E, 0x0F, 0x9F,
- 0x98, 0xF1, 0x40, 0x94, 0x1A, 0xD5, 0xD5, 0xF7,
- 0x11, 0x93, 0x00, 0xEC, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xAB, 0xF1, 0x40, 0xF0, 0x38, 0xF2,
- 0x0F, 0x9F, 0xAB, 0xF1, 0x01, 0x96, 0x0B, 0xB3,
- 0x08, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0xAB, 0xF1, 0x40, 0xF0, 0x7C, 0xFB, 0x01, 0x94,
- 0x0A, 0xB3, 0x10, 0x00, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xB4, 0xF1, 0x40, 0xF0, 0x87, 0xFB,
- 0x11, 0x93, 0x10, 0xEC, 0x42, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0xBF, 0xF1, 0x44, 0x96, 0x1B, 0xD7,
- 0x0B, 0xBC, 0x0F, 0x9F, 0xC5, 0xF1, 0x41, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0xC5, 0xF1, 0x19, 0xD3,
- 0x0B, 0xBC, 0x40, 0x92, 0x19, 0xD3, 0x10, 0xEC,
- 0xC5, 0x94, 0x0A, 0xB3, 0x80, 0x00, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0x12, 0xF2, 0x13, 0x97,
- 0x28, 0xBC, 0x01, 0xD6, 0x0B, 0xB3, 0x40, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0xDA, 0xF1,
- 0x40, 0xF0, 0x18, 0xF7, 0x01, 0x94, 0x0A, 0xB3,
- 0x02, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0xED, 0xF1, 0x40, 0xF0, 0xC4, 0xEE, 0x40, 0xF0,
- 0x8F, 0xFB, 0x40, 0xF0, 0x1B, 0xF2, 0x40, 0x96,
- 0x1B, 0xD7, 0x00, 0xEC, 0x41, 0x92, 0x19, 0xD3,
- 0xD8, 0xF7, 0x01, 0x94, 0x0A, 0xB3, 0x04, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x09, 0xF2,
- 0x40, 0xF0, 0x9E, 0xFB, 0x09, 0x63, 0x00, 0x44,
- 0x01, 0x97, 0xC3, 0x94, 0x48, 0xA4, 0xC1, 0xD4,
- 0x00, 0xEE, 0x40, 0x92, 0x19, 0xD3, 0x12, 0x95,
- 0x19, 0xD3, 0x10, 0x95, 0x19, 0xD3, 0x02, 0x80,
- 0x19, 0xD3, 0x03, 0x82, 0x41, 0x92, 0x19, 0xD3,
- 0xD8, 0xF7, 0x01, 0x94, 0x0A, 0xB3, 0x08, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x12, 0xF2,
- 0x40, 0xF0, 0xAE, 0xFB, 0x0A, 0x65, 0x00, 0x44,
- 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2, 0xC2, 0xD2,
- 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x09, 0x63, 0x00, 0x40,
- 0x19, 0xD3, 0xF2, 0xBD, 0x0A, 0x65, 0xEA, 0x43,
- 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2, 0xC2, 0xD2,
- 0x0A, 0x65, 0xE9, 0x43, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xA3, 0x40, 0x00, 0xC2, 0xD2, 0x0A, 0x65,
- 0xEB, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3,
- 0xC0, 0x00, 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x09, 0x63,
- 0x00, 0x80, 0x19, 0xD3, 0xF2, 0xBD, 0x0A, 0x65,
- 0xE8, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3,
- 0xC0, 0x00, 0xC2, 0xD2, 0x0A, 0x65, 0xEB, 0x43,
- 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xBF, 0xFF,
- 0xC2, 0xD2, 0x0A, 0x65, 0xEA, 0x43, 0x02, 0x97,
- 0xC3, 0x92, 0x09, 0xB3, 0xFB, 0xFF, 0xC2, 0xD2,
- 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B,
- 0x01, 0x00, 0x09, 0x93, 0x00, 0x01, 0x19, 0xD3,
- 0x02, 0x80, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x09, 0x93, 0x00, 0x09,
- 0x19, 0xD3, 0x02, 0x80, 0x40, 0xF0, 0x56, 0xF2,
- 0x40, 0x92, 0x19, 0xD3, 0x94, 0xEC, 0xC8, 0xD2,
- 0x09, 0x93, 0x91, 0xEC, 0xC8, 0xD2, 0x40, 0xF0,
- 0x2A, 0xEF, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0,
- 0x3B, 0xF5, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x85, 0xF2, 0x0A, 0x65, 0xFE, 0x7F, 0x02, 0x97,
- 0xC3, 0x92, 0x44, 0xA2, 0xC2, 0xD2, 0x0F, 0x9F,
- 0x92, 0xF2, 0x40, 0xF0, 0x94, 0xF2, 0x40, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0x92, 0xF2, 0xC8, 0xD2,
- 0x09, 0x93, 0x91, 0xEC, 0xC8, 0xD2, 0x40, 0xF0,
- 0x2A, 0xEF, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93,
- 0xF1, 0xBD, 0x19, 0xD3, 0xB6, 0xEC, 0x11, 0x93,
- 0xB4, 0xEC, 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F,
- 0xAC, 0xF2, 0x09, 0x63, 0x00, 0x80, 0x01, 0x97,
- 0xC3, 0x94, 0x0A, 0x07, 0x07, 0x00, 0xC1, 0xD6,
- 0x0A, 0x05, 0x00, 0xA0, 0x1A, 0xD5, 0x96, 0xEC,
- 0x11, 0x93, 0xB6, 0xEC, 0x19, 0xD3, 0x01, 0x80,
- 0x0A, 0x65, 0xFE, 0x7F, 0x02, 0x97, 0xC3, 0x92,
- 0x41, 0xA2, 0xC2, 0xD2, 0x40, 0x92, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x41, 0x20, 0x08, 0x0B,
- 0x01, 0x00, 0x13, 0x97, 0xB4, 0xEC, 0x40, 0x46,
- 0x02, 0x5E, 0x0F, 0x9F, 0x2C, 0xF3, 0x12, 0x95,
- 0x96, 0xEC, 0x0A, 0x03, 0x07, 0x00, 0xC1, 0x92,
- 0xC2, 0xD2, 0x11, 0x93, 0x96, 0xEC, 0x09, 0x05,
- 0x01, 0x00, 0x48, 0x02, 0xC1, 0x92, 0xC2, 0xD2,
- 0x11, 0x93, 0x96, 0xEC, 0x4E, 0x02, 0xC1, 0x94,
- 0xC5, 0xD6, 0xC5, 0x92, 0x11, 0x07, 0x96, 0xEC,
- 0x0B, 0x03, 0x0F, 0x00, 0xC1, 0x98, 0x46, 0x06,
- 0x7A, 0x93, 0x79, 0x93, 0x5C, 0x95, 0x5A, 0x95,
- 0x02, 0xA3, 0xC3, 0xD2, 0x04, 0x95, 0xC5, 0x96,
- 0x41, 0x06, 0xC5, 0xD6, 0x42, 0x46, 0x02, 0x9E,
- 0x0F, 0x9F, 0xD5, 0xF2, 0x11, 0x93, 0x96, 0xEC,
- 0x09, 0x05, 0x05, 0x00, 0x41, 0x02, 0xC1, 0x92,
- 0xC2, 0xD2, 0x11, 0x93, 0x96, 0xEC, 0xC1, 0x92,
- 0x09, 0xB5, 0x1F, 0x00, 0x43, 0x44, 0x02, 0x8E,
- 0x0F, 0x9F, 0x02, 0xF3, 0x40, 0x44, 0x02, 0x4E,
- 0x0F, 0x9F, 0x03, 0xF3, 0x0A, 0x05, 0xFF, 0xFF,
- 0x0F, 0x9F, 0x03, 0xF3, 0x43, 0x94, 0x11, 0x93,
- 0x96, 0xEC, 0x42, 0x02, 0xC1, 0xD4, 0x11, 0x93,
- 0x96, 0xEC, 0x49, 0x02, 0xC1, 0x92, 0x19, 0xD3,
- 0xB4, 0xEC, 0x09, 0x05, 0xF2, 0xFF, 0x1A, 0xD5,
- 0x92, 0xEC, 0x09, 0x43, 0xD0, 0x07, 0x02, 0x9E,
- 0x0F, 0x9F, 0x2C, 0xF3, 0x11, 0x93, 0xDC, 0xF7,
- 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7, 0x11, 0x93,
- 0xDB, 0xF7, 0x09, 0xA3, 0x40, 0x00, 0x19, 0xD3,
- 0xDB, 0xF7, 0x09, 0x63, 0x00, 0x80, 0x01, 0x95,
- 0xC2, 0x94, 0x1A, 0xD5, 0xB5, 0xEC, 0x40, 0x96,
- 0x1B, 0xD7, 0xB4, 0xEC, 0x0F, 0x9F, 0x92, 0xF3,
- 0x11, 0x93, 0x92, 0xEC, 0x12, 0x95, 0xB6, 0xEC,
- 0x02, 0x43, 0x02, 0x8E, 0x0F, 0x9F, 0x7A, 0xF3,
- 0x02, 0x0E, 0x0F, 0x9F, 0x4D, 0xF3, 0x11, 0x93,
- 0xDC, 0xF7, 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7,
- 0x11, 0x93, 0xDB, 0xF7, 0x09, 0xA3, 0x80, 0x00,
- 0x19, 0xD3, 0xDB, 0xF7, 0x09, 0x63, 0x00, 0x80,
- 0x01, 0x95, 0xC2, 0x94, 0x1A, 0xD5, 0xB5, 0xEC,
- 0x40, 0x96, 0x1B, 0xD7, 0xB4, 0xEC, 0x0F, 0x9F,
- 0x92, 0xF3, 0x11, 0x93, 0x03, 0x80, 0x09, 0xB3,
- 0x00, 0x40, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x5F, 0xF3, 0x11, 0x93, 0xC0, 0xEC, 0x40, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0x5F, 0xF3, 0x40, 0xF0,
- 0xA6, 0xF3, 0x0F, 0x9F, 0x94, 0xF3, 0x41, 0x92,
- 0xC8, 0xD2, 0x0A, 0x95, 0x91, 0xEC, 0xC8, 0xD4,
- 0x40, 0xF0, 0x2A, 0xEF, 0x42, 0x00, 0x11, 0x93,
- 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x72, 0xF3, 0x42, 0x96, 0x1B, 0xD7, 0xC0, 0xEC,
- 0x0F, 0x9F, 0x94, 0xF3, 0x0A, 0x65, 0xFE, 0x7F,
- 0x02, 0x97, 0xC3, 0x92, 0x42, 0xA2, 0xC2, 0xD2,
- 0x0F, 0x9F, 0x94, 0xF3, 0x12, 0x45, 0x03, 0xEC,
- 0x02, 0x4E, 0x0F, 0x9F, 0x8C, 0xF3, 0x11, 0x93,
- 0xDC, 0xF7, 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7,
- 0x11, 0x93, 0xDB, 0xF7, 0x09, 0xA3, 0x00, 0x08,
- 0x19, 0xD3, 0xDB, 0xF7, 0x1A, 0xD5, 0x92, 0xEC,
- 0x11, 0x93, 0x92, 0xEC, 0x19, 0x25, 0x92, 0xEC,
- 0x09, 0x63, 0x00, 0x80, 0x19, 0xD3, 0xF2, 0xBD,
- 0x41, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0, 0xA6, 0xF3,
- 0x40, 0x92, 0xC8, 0xD2, 0x09, 0x93, 0x91, 0xEC,
- 0xC8, 0xD2, 0x40, 0xF0, 0x2A, 0xEF, 0x42, 0x00,
- 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B,
- 0x01, 0x00, 0x11, 0x93, 0xD7, 0xF7, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0xB6, 0xF3, 0x0A, 0x65,
- 0xBC, 0x69, 0x02, 0x97, 0xC3, 0x92, 0x09, 0x83,
- 0x00, 0x02, 0xC2, 0xD2, 0x11, 0x93, 0x03, 0x80,
- 0x09, 0xB3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0xC9, 0xF3, 0x11, 0x93, 0xDC, 0xF7,
- 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7, 0x11, 0x93,
- 0xDB, 0xF7, 0x09, 0xA3, 0x00, 0x20, 0x19, 0xD3,
- 0xDB, 0xF7, 0x11, 0x93, 0xB5, 0xEC, 0x19, 0xD3,
- 0x04, 0x80, 0x12, 0x95, 0xB4, 0xEC, 0x1A, 0xD5,
- 0x05, 0x80, 0x09, 0x63, 0x00, 0x80, 0x01, 0x97,
- 0xC3, 0x96, 0x1B, 0xD7, 0xB5, 0xEC, 0x40, 0x94,
- 0x1A, 0xD5, 0xB4, 0xEC, 0x19, 0xD3, 0xF2, 0xBD,
- 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B,
- 0x01, 0x00, 0x09, 0x93, 0x96, 0x03, 0x19, 0xD3,
- 0x06, 0x82, 0x09, 0x93, 0x00, 0x01, 0x19, 0xD3,
- 0x03, 0x82, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x47, 0x20, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93,
- 0x01, 0x82, 0xC5, 0xD2, 0x40, 0x94, 0x01, 0xD4,
- 0x13, 0x97, 0xB8, 0xEC, 0x02, 0xD6, 0x03, 0x95,
- 0x0C, 0x99, 0xBB, 0xEC, 0x04, 0x05, 0x13, 0x97,
- 0x03, 0xEC, 0x01, 0x27, 0x02, 0x99, 0xC4, 0x92,
- 0x03, 0x03, 0xC2, 0xD2, 0x14, 0x99, 0xBA, 0xEC,
- 0x03, 0x09, 0x1C, 0xD9, 0xBA, 0xEC, 0x12, 0x95,
- 0x04, 0x82, 0x0A, 0xB3, 0x02, 0x00, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0x29, 0xF5, 0x01, 0x92,
- 0x03, 0xD2, 0x0A, 0xA3, 0x02, 0x00, 0x19, 0xD3,
- 0x04, 0x82, 0x02, 0x96, 0x0B, 0x05, 0x01, 0x00,
- 0x1A, 0xD5, 0xB8, 0xEC, 0xC5, 0x92, 0x43, 0x42,
- 0x02, 0x9E, 0x0F, 0x9F, 0x37, 0xF4, 0x42, 0x44,
- 0x02, 0x8E, 0x0F, 0x9F, 0x37, 0xF4, 0x11, 0x93,
- 0xBF, 0xEC, 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F,
- 0x37, 0xF4, 0x0C, 0x49, 0xD3, 0x08, 0x02, 0x8E,
- 0x0F, 0x9F, 0x37, 0xF4, 0x11, 0x63, 0x07, 0x82,
- 0x11, 0xA3, 0x07, 0x82, 0x71, 0x93, 0x79, 0x93,
- 0x79, 0x93, 0x79, 0x93, 0x03, 0xD2, 0xC5, 0x94,
- 0x0A, 0xB5, 0xFC, 0xFF, 0x04, 0xD4, 0x03, 0x96,
- 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0x46, 0xF4,
- 0x11, 0x93, 0xB8, 0xEC, 0x41, 0x42, 0x02, 0x8E,
- 0x0F, 0x9F, 0x4D, 0xF4, 0xC5, 0x98, 0x0C, 0x03,
- 0xFF, 0xFF, 0x42, 0x42, 0x02, 0x8E, 0x0F, 0x9F,
- 0x74, 0xF4, 0x0A, 0x95, 0xBB, 0xEC, 0x42, 0x92,
- 0x19, 0xD3, 0xB9, 0xEC, 0xC5, 0x96, 0x43, 0x46,
- 0x02, 0x9E, 0x0F, 0x9F, 0x66, 0xF4, 0x0B, 0x07,
- 0xFC, 0xFF, 0xC5, 0xD6, 0xD2, 0x98, 0x1C, 0xD9,
- 0xC8, 0xBC, 0xD2, 0x96, 0x1B, 0xD7, 0xCA, 0xBC,
- 0x09, 0x03, 0xFF, 0xFF, 0x40, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0x52, 0xF4, 0x19, 0xD3, 0xB9, 0xEC,
- 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0x72, 0xF4,
- 0x0A, 0x05, 0xFE, 0xFF, 0xCA, 0xD2, 0xC2, 0xD2,
- 0x0F, 0x9F, 0x74, 0xF4, 0x1A, 0xD5, 0x93, 0xEC,
- 0x03, 0x98, 0x40, 0x48, 0x02, 0x5E, 0x0F, 0x9F,
- 0xA1, 0xF4, 0x11, 0x93, 0xB8, 0xEC, 0x41, 0x42,
- 0x02, 0x9E, 0x0F, 0x9F, 0x84, 0xF4, 0x04, 0x94,
- 0x48, 0x44, 0x02, 0x4E, 0x0F, 0x9F, 0x8F, 0xF4,
- 0x41, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0xA1, 0xF4,
- 0x11, 0x93, 0x04, 0x82, 0x41, 0xB2, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0xA1, 0xF4, 0x41, 0x96,
- 0x01, 0xD6, 0x0A, 0x65, 0xBD, 0x43, 0x02, 0x99,
- 0xC4, 0x92, 0x09, 0xA3, 0x80, 0x00, 0xC2, 0xD2,
- 0x0A, 0x65, 0xE8, 0x43, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xB3, 0xBF, 0xFF, 0xC2, 0xD2, 0x0F, 0x9F,
- 0xFA, 0xF4, 0xC5, 0x98, 0x43, 0x48, 0x02, 0x9E,
- 0x0F, 0x9F, 0xFA, 0xF4, 0x4F, 0x96, 0x0C, 0xB3,
- 0x01, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0xAE, 0xF4, 0x47, 0x96, 0x11, 0x93, 0xB7, 0xEC,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0xD6, 0xF4,
- 0x11, 0x93, 0xB8, 0xEC, 0x41, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0xD6, 0xF4, 0x12, 0x95, 0x00, 0x82,
- 0x0A, 0x05, 0xFF, 0xAF, 0x05, 0xD4, 0xC8, 0xD6,
- 0xC8, 0xD2, 0x40, 0xF0, 0x7B, 0xF7, 0x42, 0x00,
- 0x05, 0x96, 0xC3, 0x94, 0x01, 0xB5, 0x40, 0x44,
- 0x02, 0x4E, 0x0F, 0x9F, 0xD6, 0xF4, 0x06, 0x98,
- 0x50, 0x98, 0x1C, 0xD9, 0xA2, 0xBC, 0x40, 0x98,
- 0x1C, 0xD9, 0xA2, 0xBC, 0x40, 0x92, 0x03, 0xD2,
- 0x0F, 0x9F, 0xFF, 0xF4, 0x03, 0x94, 0x40, 0x44,
- 0x02, 0x5E, 0x0F, 0x9F, 0xE3, 0xF4, 0x0A, 0x65,
- 0x5E, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x48, 0xA2,
- 0xC2, 0xD2, 0x0F, 0x9F, 0xFF, 0xF4, 0x11, 0x93,
- 0xB8, 0xEC, 0x0C, 0x99, 0xBB, 0xEC, 0x04, 0x03,
- 0x04, 0x96, 0x13, 0x25, 0x03, 0xEC, 0xC1, 0xD4,
- 0x11, 0x93, 0xBA, 0xEC, 0x19, 0x05, 0xBA, 0xEC,
- 0x1B, 0xD7, 0x01, 0x82, 0x0A, 0x65, 0xFD, 0x7D,
- 0x02, 0x99, 0xC4, 0x92, 0x43, 0xA2, 0xC2, 0xD2,
- 0x41, 0x92, 0x01, 0xD2, 0x03, 0x94, 0x40, 0x44,
- 0x02, 0x5E, 0x0F, 0x9F, 0x13, 0xF5, 0x11, 0x93,
- 0xB9, 0xEC, 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F,
- 0x0B, 0xF5, 0x19, 0xD3, 0xB8, 0xEC, 0x19, 0xD3,
- 0xBA, 0xEC, 0x19, 0xD3, 0xBB, 0xEC, 0x03, 0x96,
- 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0x13, 0xF5,
- 0x41, 0x98, 0x1C, 0xD9, 0xB7, 0xEC, 0x11, 0x93,
- 0xBF, 0xEC, 0x41, 0x42, 0x02, 0x5E, 0x0F, 0x9F,
- 0x24, 0xF5, 0x11, 0x93, 0x00, 0x82, 0x19, 0xD3,
- 0x02, 0x82, 0x0A, 0x65, 0xFD, 0x7D, 0x02, 0x97,
- 0xC3, 0x92, 0x09, 0xA3, 0x00, 0x01, 0xC2, 0xD2,
- 0x40, 0x98, 0x1C, 0xD9, 0xBF, 0xEC, 0x0F, 0x9F,
- 0x2C, 0xF5, 0x01, 0x92, 0x19, 0xD3, 0xB7, 0xEC,
- 0x01, 0x94, 0x40, 0x44, 0x02, 0x5E, 0x0F, 0x9F,
- 0x38, 0xF5, 0x0A, 0x65, 0xEA, 0x43, 0x02, 0x97,
- 0xC3, 0x92, 0x09, 0xB3, 0xFB, 0xFF, 0xC2, 0xD2,
- 0x47, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x12, 0x95, 0x03, 0x80,
- 0x0A, 0xB3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0x57, 0xF5, 0x0A, 0xB7, 0x00, 0x08,
- 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0x5A, 0xF5,
- 0x11, 0x93, 0x03, 0xEC, 0x41, 0x02, 0x09, 0xB3,
- 0xFE, 0xFF, 0x12, 0x95, 0x07, 0x80, 0x01, 0x45,
- 0x02, 0x8E, 0x0F, 0x9F, 0x5A, 0xF5, 0x41, 0x92,
- 0x0F, 0x9F, 0x5B, 0xF5, 0x40, 0x92, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x41, 0x20, 0x08, 0x0B,
- 0x01, 0x00, 0x0A, 0x65, 0xE9, 0x43, 0x02, 0x97,
- 0xC3, 0x92, 0x09, 0xA3, 0x40, 0x00, 0xC2, 0xD2,
- 0x13, 0x97, 0x6E, 0xEC, 0x0B, 0x47, 0xA0, 0x00,
- 0x02, 0x5E, 0x0F, 0x9F, 0x86, 0xF5, 0x09, 0x63,
- 0x08, 0x43, 0x0A, 0x65, 0xFF, 0x5F, 0x01, 0x99,
- 0xC4, 0xD4, 0x0A, 0x95, 0x9B, 0xEC, 0xD2, 0x96,
- 0x1B, 0xD7, 0xFA, 0xBC, 0xD2, 0x96, 0xC4, 0xD6,
- 0xD2, 0x98, 0x1C, 0xD9, 0xFA, 0xBC, 0xD2, 0x96,
- 0xC1, 0xD6, 0xC2, 0x94, 0x1A, 0xD5, 0xFA, 0xBC,
- 0x0F, 0x9F, 0xC4, 0xF5, 0x0C, 0x69, 0xFF, 0x6F,
- 0x1C, 0xD9, 0xF8, 0xBC, 0x0B, 0x47, 0x10, 0x95,
- 0x02, 0x5E, 0x0F, 0x9F, 0x9E, 0xF5, 0x0A, 0x95,
- 0x6F, 0xEC, 0x09, 0x63, 0x06, 0x43, 0x01, 0x99,
- 0xC4, 0xD6, 0xD2, 0x96, 0x1B, 0xD7, 0xF8, 0xBC,
- 0x0C, 0x69, 0xEE, 0x6A, 0xC1, 0xD8, 0xC2, 0x94,
- 0x1A, 0xD5, 0xF8, 0xBC, 0x40, 0x92, 0xC5, 0xD2,
- 0x11, 0x43, 0xC1, 0xEC, 0x02, 0x0E, 0x0F, 0x9F,
- 0xC1, 0xF5, 0xC5, 0x94, 0x0A, 0x03, 0x71, 0xEC,
- 0xC1, 0x94, 0x1A, 0xD5, 0xFA, 0xBC, 0x11, 0x93,
- 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0xB3, 0xF5, 0x0A, 0x95, 0x6F, 0xEC, 0xC8, 0xD4,
- 0x40, 0xF0, 0x9C, 0xF7, 0x19, 0xD3, 0xF8, 0xBC,
- 0x41, 0x00, 0xC5, 0x96, 0x41, 0x06, 0xC5, 0xD6,
- 0x13, 0x47, 0xC1, 0xEC, 0x02, 0x1E, 0x0F, 0x9F,
- 0xA5, 0xF5, 0x40, 0x98, 0x1C, 0xD9, 0xFA, 0xBC,
- 0x40, 0x92, 0x19, 0xD3, 0x6E, 0xEC, 0x19, 0xD3,
- 0xC1, 0xEC, 0x0A, 0x65, 0x52, 0x43, 0x02, 0x97,
- 0xC3, 0x92, 0x48, 0xA2, 0xC2, 0xD2, 0x0A, 0x65,
- 0xEB, 0x43, 0x02, 0x99, 0xC4, 0x92, 0x09, 0xB3,
- 0xBF, 0xFF, 0xC2, 0xD2, 0x41, 0x00, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x43, 0x20, 0x08, 0x0B,
- 0x01, 0x00, 0x06, 0x92, 0x01, 0xD2, 0x0A, 0x65,
- 0xF0, 0x6A, 0x0B, 0x97, 0x6F, 0xEC, 0x02, 0x99,
- 0xC4, 0x98, 0xD3, 0xD8, 0x02, 0xD6, 0x0A, 0x03,
- 0x02, 0x00, 0x01, 0x97, 0xC3, 0x98, 0x02, 0x96,
- 0xC3, 0xD8, 0x01, 0x96, 0xC1, 0xD6, 0x1A, 0xD5,
- 0x6E, 0xEC, 0xC5, 0x98, 0x14, 0x99, 0x6F, 0xEC,
- 0xC2, 0xD8, 0x43, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0x92,
- 0xC8, 0xD2, 0x40, 0xF0, 0xD9, 0xF5, 0x41, 0x00,
- 0x11, 0x93, 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0x13, 0xF6, 0x42, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0x10, 0xF6, 0x0A, 0x65, 0xFE, 0x7F,
- 0x02, 0x97, 0xC3, 0x92, 0x42, 0xA2, 0xC2, 0xD2,
- 0x40, 0x92, 0x19, 0xD3, 0xC0, 0xEC, 0x0A, 0x65,
- 0xEB, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3,
- 0xC0, 0x00, 0xC2, 0xD2, 0x0A, 0x65, 0xE9, 0x43,
- 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xBF, 0xFF,
- 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x63, 0x20, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93,
- 0xAF, 0xBC, 0x47, 0xB2, 0x59, 0x95, 0x5A, 0x95,
- 0x12, 0xA5, 0xBF, 0xBC, 0x0A, 0xB3, 0x01, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x35, 0xF6,
- 0x41, 0x04, 0x05, 0x93, 0x40, 0x96, 0x20, 0xD6,
- 0x62, 0x97, 0x0F, 0x9F, 0x44, 0xF6, 0x14, 0x99,
- 0xFC, 0xBC, 0xD1, 0xD8, 0x14, 0x99, 0xFE, 0xBC,
- 0xD1, 0xD8, 0x20, 0x98, 0x42, 0x08, 0x20, 0xD8,
- 0x20, 0x98, 0x03, 0x49, 0x02, 0x1E, 0x0F, 0x9F,
- 0x3B, 0xF6, 0xC5, 0x92, 0x62, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0x5D, 0xF6, 0x02, 0x8E, 0x0F, 0x9F,
- 0x57, 0xF6, 0x61, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x81, 0xF6, 0x0F, 0x9F, 0xAE, 0xF6, 0x63, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0xA4, 0xF6, 0x0F, 0x9F,
- 0xAE, 0xF6, 0x0D, 0x03, 0x01, 0x00, 0x0C, 0x99,
- 0x71, 0xEC, 0x0B, 0x05, 0xFF, 0xFF, 0x40, 0x96,
- 0x0F, 0x9F, 0x6A, 0xF6, 0xD1, 0x96, 0xD4, 0xD6,
- 0x20, 0x96, 0x41, 0x06, 0x20, 0xD6, 0x02, 0x47,
- 0x02, 0x1E, 0x0F, 0x9F, 0x66, 0xF6, 0x1A, 0xD5,
- 0xC1, 0xEC, 0x0A, 0x65, 0xEB, 0x43, 0x02, 0x99,
- 0xC4, 0x92, 0x09, 0xA3, 0xC0, 0x00, 0xC2, 0xD2,
- 0x0A, 0x65, 0xE9, 0x43, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xB3, 0xBF, 0xFF, 0xC2, 0xD2, 0x0F, 0x9F,
- 0xAE, 0xF6, 0x0A, 0x03, 0xFE, 0xFF, 0x61, 0x95,
- 0x40, 0x98, 0x20, 0xD8, 0x02, 0x49, 0x02, 0x0E,
- 0x0F, 0x9F, 0xAE, 0xF6, 0x0D, 0x03, 0x01, 0x00,
- 0x21, 0xD2, 0x20, 0x92, 0x05, 0x03, 0x42, 0x02,
- 0xC8, 0xD2, 0x21, 0x96, 0xC3, 0x92, 0x42, 0x06,
- 0x21, 0xD6, 0xC8, 0xD2, 0x22, 0xD4, 0x40, 0xF0,
- 0x01, 0xF1, 0x42, 0x00, 0x20, 0x98, 0x42, 0x08,
- 0x20, 0xD8, 0x22, 0x94, 0x02, 0x49, 0x02, 0x1E,
- 0x0F, 0x9F, 0x8D, 0xF6, 0x0F, 0x9F, 0xAE, 0xF6,
- 0x0D, 0x03, 0x03, 0x00, 0xC8, 0xD2, 0x02, 0x92,
- 0xC8, 0xD2, 0x01, 0x96, 0xC8, 0xD6, 0x40, 0xF0,
- 0xB1, 0xF6, 0x43, 0x00, 0x63, 0x00, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x45, 0x20, 0x08, 0x0B,
- 0x01, 0x00, 0x0D, 0x03, 0x08, 0x00, 0x08, 0x94,
- 0xC5, 0xD4, 0x09, 0x05, 0x01, 0x00, 0xC2, 0x94,
- 0x03, 0xD4, 0x42, 0x02, 0xC1, 0x92, 0x01, 0xD2,
- 0x02, 0x97, 0xC5, 0x94, 0x0A, 0x83, 0xFF, 0xFF,
- 0x11, 0xB3, 0x2C, 0x93, 0x09, 0xB3, 0xFB, 0xFF,
- 0x19, 0xD3, 0x2C, 0x93, 0x03, 0x92, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0xE4, 0xF6, 0x01, 0x94,
- 0xD2, 0x92, 0x19, 0xD3, 0x2C, 0x93, 0x01, 0xD4,
- 0x02, 0x94, 0x12, 0x95, 0x2C, 0x93, 0x44, 0xA4,
- 0x1A, 0xD5, 0x2C, 0x93, 0x0A, 0xB5, 0xFB, 0xFF,
- 0x1A, 0xD5, 0x2C, 0x93, 0x0B, 0x07, 0xFF, 0xFF,
- 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0xCF, 0xF6,
- 0x09, 0x63, 0xD4, 0x6C, 0x01, 0x95, 0xC2, 0x96,
- 0xC5, 0x94, 0x02, 0xA7, 0xC1, 0xD6, 0x03, 0x92,
- 0x54, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0xF4, 0xF6,
- 0x0A, 0x83, 0xFF, 0xFF, 0x1B, 0xB3, 0x2C, 0x93,
- 0x45, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x09, 0x63, 0x00, 0x40,
- 0x19, 0xD3, 0xF2, 0xBD, 0x40, 0xF0, 0x3B, 0xF5,
- 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0x08, 0xF7,
- 0x40, 0xF0, 0x94, 0xF2, 0x0F, 0x9F, 0x16, 0xF7,
- 0x40, 0x96, 0xC8, 0xD6, 0x09, 0x93, 0x91, 0xEC,
- 0xC8, 0xD2, 0x40, 0xF0, 0x2A, 0xEF, 0x0A, 0x65,
- 0xFE, 0x7F, 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2,
- 0xC2, 0xD2, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x0A, 0x65,
- 0xE8, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3,
- 0x40, 0x00, 0xC2, 0xD2, 0x0A, 0x65, 0xEA, 0x43,
- 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xFB, 0xFF,
- 0xC2, 0xD2, 0x40, 0x92, 0x19, 0xD3, 0x2D, 0xBC,
- 0x0A, 0x65, 0xD8, 0x43, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xB3, 0xBF, 0xFF, 0xC2, 0xD2, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00,
- 0x09, 0x63, 0xEA, 0x43, 0x01, 0x97, 0xC3, 0x94,
- 0x44, 0xA4, 0xC1, 0xD4, 0x11, 0x93, 0xB9, 0xEC,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x6F, 0xF7,
- 0x12, 0x95, 0x93, 0xEC, 0x0B, 0x67, 0x36, 0x43,
- 0xD2, 0x98, 0x1C, 0xD9, 0xC8, 0xBC, 0xD2, 0x98,
- 0x03, 0x93, 0xC1, 0xD8, 0x11, 0x93, 0xB9, 0xEC,
- 0x09, 0x03, 0xFF, 0xFF, 0x19, 0xD3, 0xB9, 0xEC,
- 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0x48, 0xF7,
- 0x19, 0xD3, 0xB8, 0xEC, 0x19, 0xD3, 0xBA, 0xEC,
- 0x0A, 0x05, 0xFE, 0xFF, 0xCA, 0xD2, 0xCA, 0xD2,
- 0xC2, 0xD2, 0x0A, 0x65, 0x5E, 0x43, 0x02, 0x97,
- 0xC3, 0x92, 0x48, 0xA2, 0xC2, 0xD2, 0x0A, 0x65,
- 0xEA, 0x43, 0x02, 0x99, 0xC4, 0x92, 0x09, 0xB3,
- 0xFB, 0xFF, 0x0F, 0x9F, 0x78, 0xF7, 0x11, 0x93,
- 0x03, 0xEC, 0x19, 0xD3, 0x01, 0x82, 0x0A, 0x65,
- 0xFD, 0x7D, 0x02, 0x97, 0xC3, 0x92, 0x43, 0xA2,
- 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x03, 0x92, 0x04, 0x96,
- 0x0D, 0x5E, 0x50, 0x46, 0x02, 0x0E, 0x40, 0x92,
- 0x09, 0xEE, 0x44, 0x46, 0x04, 0x0E, 0x59, 0x93,
- 0x44, 0x26, 0x04, 0x5E, 0x46, 0xEE, 0x41, 0x93,
- 0x41, 0x26, 0x43, 0x4E, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0,
- 0xB1, 0xFE, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x03, 0x94,
- 0x1A, 0xD5, 0xA3, 0xF7, 0x11, 0x93, 0x00, 0x90,
- 0x88, 0x98, 0x90, 0x9A, 0x1D, 0x00, 0x1A, 0x00,
- 0x03, 0x00, 0x03, 0x00, 0x18, 0x00, 0x19, 0x00,
- 0x1A, 0x00, 0x1B, 0x00, 0x16, 0x00, 0x21, 0x00,
- 0x12, 0x00, 0x09, 0x00, 0x13, 0x00, 0x19, 0x00,
- 0x19, 0x00, 0x19, 0x00, 0x21, 0x00, 0x2D, 0x00,
- 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x69,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x5F, 0xF2, 0xCD, 0xF7, 0x00, 0x00, 0x74, 0xF2,
- 0xCD, 0xF7, 0x00, 0x00, 0xB9, 0xF2, 0xCA, 0xF7,
- 0xD1, 0xF7, 0x00, 0x00, 0x97, 0xF3, 0xCD, 0xF7,
- 0x05, 0x46, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/*
- * current zd1211b firmware version.
- */
-#define ZD1211B_FIRMWARE_VER 4705
-
-uint8_t zd1211b_firmware[] = {
- 0x08, 0x91, 0xff, 0xed, 0x09, 0x93, 0x1e, 0xee, 0xd1, 0x94, 0x11,
- 0xee, 0x88, 0xd4, 0xd1, 0x96, 0xd1, 0x98, 0x5c, 0x99, 0x5c, 0x99,
- 0x4c, 0x99, 0x04, 0x9d, 0xd1, 0x98, 0xd1, 0x9a, 0x03, 0xee, 0xf4,
- 0x94, 0xd3, 0xd4, 0x41, 0x2a, 0x40, 0x4a, 0x45, 0xbe, 0x88, 0x92,
- 0x41, 0x24, 0x40, 0x44, 0x53, 0xbe, 0x40, 0xf0, 0x4e, 0xee, 0x41,
- 0xee, 0x98, 0x9a, 0x72, 0xf7, 0x02, 0x00, 0x1f, 0xec, 0x00, 0x00,
- 0xb2, 0xf8, 0x4d, 0x00, 0xa1, 0xec, 0x00, 0x00, 0x43, 0xf7, 0x22,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xd8,
- 0xa0, 0x90, 0x98, 0x9a, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x5a,
- 0xf0, 0xa0, 0x90, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x0a, 0xef,
- 0xa0, 0x90, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x97, 0xf0, 0xa0,
- 0x90, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x94, 0xf6, 0xa0, 0x90,
- 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x95, 0xf5, 0xa0, 0x90, 0x98,
- 0x9a, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x34, 0xf7, 0xa0, 0x90,
- 0x98, 0x9a, 0x88, 0xda, 0x41, 0x20, 0x08, 0x0b, 0x01, 0x00, 0x40,
- 0xf0, 0x8e, 0xee, 0x40, 0x96, 0x0a, 0x65, 0x00, 0x7d, 0x11, 0x93,
- 0x76, 0xf7, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x57, 0xee, 0x40,
- 0xf1, 0x1b, 0xd7, 0x76, 0xf7, 0xc5, 0x92, 0x02, 0x99, 0x41, 0x92,
- 0xc4, 0xd2, 0x40, 0x92, 0xc4, 0xd2, 0x0f, 0x9f, 0x95, 0xf8, 0x0f,
- 0x9f, 0x57, 0xee, 0x41, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x08, 0x0b, 0x01, 0x00, 0x40, 0x92, 0x19, 0xd3, 0x12, 0x95, 0x19,
- 0xd3, 0x10, 0x95, 0x19, 0xd3, 0x02, 0x80, 0x19, 0xd3, 0x03, 0x82,
- 0x09, 0x93, 0x65, 0xf7, 0x19, 0xd3, 0x91, 0xec, 0x40, 0xf0, 0x07,
- 0xf2, 0x40, 0xf0, 0x75, 0xf3, 0x11, 0x93, 0x04, 0xec, 0x42, 0x42,
- 0x02, 0x5e, 0x0f, 0x9f, 0x8c, 0xee, 0x40, 0x92, 0x19, 0xd3, 0x04,
- 0xec, 0x40, 0xf0, 0xe0, 0xf1, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0x44, 0x96, 0x09, 0xb3, 0xff,
- 0xfd, 0x19, 0xd3, 0x44, 0x96, 0x40, 0xf0, 0x2d, 0xf7, 0x40, 0xf0,
- 0x6d, 0xee, 0x4b, 0x62, 0x0a, 0x95, 0x2e, 0xee, 0xd1, 0xd4, 0x0b,
- 0x97, 0x2b, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x00, 0xee, 0xd1, 0xd4,
- 0x0b, 0x97, 0x2f, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x34, 0xee, 0xd1,
- 0xd4, 0x0b, 0x97, 0x39, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x3e, 0xee,
- 0xd1, 0xd4, 0x0b, 0x97, 0x43, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x2e,
- 0xee, 0xd1, 0xd4, 0x0b, 0x97, 0x48, 0xee, 0xd1, 0xd6, 0x0a, 0x95,
- 0x49, 0xee, 0xc1, 0xd4, 0x0a, 0x65, 0x00, 0x44, 0x02, 0x97, 0xc3,
- 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x43, 0xf1, 0x09, 0x93, 0x01, 0x3f,
- 0x19, 0xd3, 0xc0, 0x85, 0x11, 0x93, 0x44, 0x96, 0x09, 0xb3, 0xff,
- 0xfc, 0x19, 0xd3, 0x44, 0x96, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x08, 0x0b, 0x01, 0x00, 0x0d, 0x03, 0x03, 0x00, 0x03, 0x96, 0x41,
- 0x02, 0x03, 0x99, 0xc4, 0x94, 0x42, 0x04, 0xc1, 0x04, 0xc2, 0x94,
- 0xc3, 0xd4, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01,
- 0x00, 0x40, 0x92, 0x19, 0xd3, 0x94, 0xec, 0x13, 0x97, 0x95, 0xec,
- 0x1b, 0xd7, 0x02, 0x80, 0x11, 0x93, 0x99, 0xec, 0x19, 0xd3, 0x7c,
- 0x96, 0x0b, 0x97, 0xa0, 0x00, 0x1b, 0xd7, 0x6e, 0xec, 0x0a, 0x65,
- 0x0e, 0x42, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xff, 0xbf, 0x11,
- 0xa3, 0x9a, 0xec, 0xc2, 0xd2, 0x0a, 0x65, 0xeb, 0x43, 0x02, 0x97,
- 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2, 0xd2, 0x0a, 0x65, 0xe9,
- 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff, 0xc2, 0xd2,
- 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x47, 0x20, 0x08, 0x0b, 0x01,
- 0x00, 0x14, 0x99, 0x03, 0x80, 0x0c, 0xb3, 0x00, 0x10, 0x40, 0x42,
- 0x02, 0x4e, 0x0f, 0x9f, 0x3d, 0xf0, 0x11, 0x93, 0x9f, 0xec, 0x41,
- 0x02, 0x19, 0xd3, 0x9f, 0xec, 0x11, 0x93, 0x74, 0xf7, 0x40, 0x42,
- 0x02, 0x4e, 0x0f, 0x9f, 0x2a, 0xef, 0x0a, 0x65, 0xfe, 0x7f, 0x02,
- 0x97, 0xc3, 0x92, 0x09, 0xa3, 0x00, 0x04, 0xc2, 0xd2, 0x0f, 0x9f,
- 0x57, 0xf0, 0x11, 0x93, 0x94, 0xec, 0x02, 0xd2, 0x40, 0x42, 0x02,
- 0x5e, 0x0f, 0x9f, 0x76, 0xef, 0x41, 0x92, 0x19, 0xd3, 0x94, 0xec,
- 0x19, 0xd3, 0x9f, 0xec, 0x12, 0x95, 0x02, 0x80, 0x1a, 0xd5, 0x95,
- 0xec, 0x13, 0x97, 0x7c, 0x96, 0x1b, 0xd7, 0x99, 0xec, 0x0a, 0x65,
- 0x0e, 0x42, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0x00, 0x40, 0x19,
- 0xd3, 0x9a, 0xec, 0x09, 0x63, 0x00, 0x40, 0xc2, 0xd2, 0x02, 0x94,
- 0x1a, 0xd5, 0x7c, 0x96, 0x0c, 0xb3, 0x00, 0x08, 0x40, 0x42, 0x02,
- 0x5e, 0x0f, 0x9f, 0x56, 0xef, 0x0c, 0xb3, 0xff, 0x07, 0x0f, 0x9f,
- 0x5a, 0xef, 0x11, 0x93, 0x06, 0x80, 0x09, 0xb3, 0xff, 0x07, 0x09,
- 0x03, 0x00, 0xa0, 0x19, 0xd3, 0x97, 0xec, 0x40, 0x98, 0x0b, 0x97,
- 0x9c, 0xec, 0x04, 0x95, 0x03, 0x05, 0x14, 0x03, 0x97, 0xec, 0x46,
- 0x02, 0xc1, 0x92, 0xc2, 0xd2, 0x41, 0x08, 0x42, 0x48, 0x02, 0x9e,
- 0x0f, 0x9f, 0x61, 0xef, 0x11, 0x93, 0x97, 0xec, 0xc1, 0x92, 0xc5,
- 0xd2, 0x5f, 0xb2, 0x19, 0xd3, 0x9b, 0xec, 0x0f, 0x9f, 0x79, 0xef,
- 0x13, 0x97, 0x98, 0xec, 0xc5, 0xd6, 0x11, 0x93, 0x03, 0x80, 0x09,
- 0xb3, 0x00, 0x08, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x8f, 0xef,
- 0x11, 0x93, 0x7a, 0xf7, 0x41, 0x02, 0x19, 0xd3, 0x7a, 0xf7, 0x11,
- 0x93, 0x79, 0xf7, 0x09, 0xa3, 0x00, 0x10, 0x19, 0xd3, 0x79, 0xf7,
- 0x40, 0x98, 0x1c, 0xd9, 0x9b, 0xec, 0x12, 0x95, 0x9b, 0xec, 0x40,
- 0x44, 0x02, 0x4e, 0x0f, 0x9f, 0x2c, 0xf0, 0x0a, 0xb3, 0x08, 0x00,
- 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xad, 0xef, 0x0a, 0xb3, 0x07,
- 0x00, 0x09, 0x05, 0xa9, 0xec, 0xc2, 0x94, 0x01, 0xd4, 0x09, 0x03,
- 0xa1, 0xec, 0xc1, 0x92, 0x19, 0xd3, 0x9b, 0xec, 0xc5, 0x94, 0x0a,
- 0xb5, 0x00, 0xff, 0x01, 0xa5, 0xc5, 0xd4, 0x0f, 0x9f, 0xb9, 0xef,
- 0x0a, 0x05, 0xff, 0xff, 0x0a, 0x03, 0xb1, 0xec, 0xc1, 0x92, 0x01,
- 0xd2, 0x1a, 0xd5, 0x9b, 0xec, 0xc5, 0x96, 0x0b, 0x07, 0xff, 0xff,
- 0xc5, 0xd6, 0x11, 0x93, 0x97, 0xec, 0xc5, 0x98, 0xc1, 0xd8, 0x11,
- 0x93, 0x97, 0xec, 0x09, 0x05, 0x0b, 0x00, 0x03, 0xd4, 0xc2, 0x96,
- 0x06, 0xd6, 0x7b, 0x95, 0x7a, 0x95, 0x4c, 0x02, 0xc1, 0x92, 0x59,
- 0x93, 0x59, 0x93, 0x01, 0xa5, 0x01, 0x98, 0x0c, 0xf5, 0x7b, 0x93,
- 0x09, 0x09, 0x01, 0x00, 0x06, 0x92, 0x09, 0xb3, 0xff, 0x00, 0x04,
- 0xd2, 0x5c, 0x93, 0x59, 0x93, 0x04, 0x94, 0x01, 0xa5, 0x03, 0x96,
- 0xc3, 0xd4, 0x11, 0x93, 0x97, 0xec, 0x4c, 0x02, 0x05, 0xd2, 0xc1,
- 0x92, 0x09, 0xb3, 0x00, 0xff, 0x7c, 0x95, 0x7a, 0x95, 0x02, 0xa3,
- 0x05, 0x98, 0xc4, 0xd2, 0x12, 0x95, 0x97, 0xec, 0x45, 0x04, 0x02,
- 0x97, 0xc3, 0x92, 0x09, 0xa3, 0x00, 0x01, 0xc2, 0xd2, 0x12, 0x95,
- 0x9b, 0xec, 0x0a, 0xb3, 0x08, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f,
- 0x9f, 0x01, 0xf0, 0x12, 0x95, 0x97, 0xec, 0x4a, 0x04, 0x02, 0x99,
- 0xc4, 0x92, 0x01, 0x98, 0x0c, 0xf3, 0x7b, 0x93, 0x41, 0x02, 0x0f,
- 0x9f, 0x22, 0xf0, 0x43, 0x44, 0x02, 0x8e, 0x0f, 0x9f, 0x23, 0xf0,
- 0x11, 0x93, 0x97, 0xec, 0x42, 0x02, 0x0a, 0x05, 0xff, 0xff, 0xc1,
- 0xd4, 0x11, 0x93, 0x97, 0xec, 0x4a, 0x02, 0x12, 0x95, 0x60, 0x96,
- 0xc1, 0xd4, 0x12, 0x95, 0x97, 0xec, 0x4b, 0x04, 0x02, 0x97, 0xc3,
- 0x92, 0x09, 0xb3, 0x1f, 0xff, 0xc2, 0xd2, 0x12, 0x95, 0x97, 0xec,
- 0x4b, 0x04, 0x11, 0x93, 0x62, 0x96, 0x41, 0x93, 0x59, 0x93, 0x02,
- 0x99, 0xc4, 0xa2, 0xc2, 0xd2, 0xc5, 0x92, 0x19, 0xd3, 0x98, 0xec,
- 0x0a, 0x95, 0x0c, 0x02, 0x1a, 0xd5, 0x02, 0x80, 0x0f, 0x9f, 0x57,
- 0xf0, 0x09, 0x63, 0xfe, 0x7f, 0x01, 0x97, 0xc3, 0x94, 0x0a, 0xa5,
- 0x00, 0x04, 0xc1, 0xd4, 0x11, 0x93, 0x9f, 0xec, 0x09, 0xa3, 0x00,
- 0x01, 0x19, 0xd3, 0x9f, 0xec, 0x40, 0xf0, 0xdf, 0xee, 0x0f, 0x9f,
- 0x57, 0xf0, 0x11, 0x93, 0x94, 0xec, 0x41, 0x42, 0x02, 0x5e, 0x0f,
- 0x9f, 0x4c, 0xf0, 0x40, 0xf0, 0xdf, 0xee, 0x11, 0x93, 0x95, 0xec,
- 0x44, 0xb2, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x57, 0xf0, 0x48,
- 0x98, 0x1c, 0xd9, 0x02, 0x80, 0x11, 0x93, 0x91, 0xec, 0x41, 0x22,
- 0x0a, 0x95, 0x57, 0xf0, 0x88, 0xd4, 0x88, 0xdc, 0x91, 0x9a, 0x47,
- 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00,
- 0x11, 0x93, 0x04, 0x82, 0x48, 0xb2, 0x40, 0x42, 0x02, 0x4e, 0x0f,
- 0x9f, 0x6e, 0xf0, 0x0a, 0x65, 0xfd, 0x7d, 0x02, 0x97, 0xc3, 0x92,
- 0x09, 0xb3, 0xff, 0xfe, 0xc2, 0xd2, 0x41, 0x92, 0x19, 0xd3, 0xbf,
- 0xec, 0x11, 0x93, 0x04, 0x82, 0x43, 0xb2, 0x12, 0x95, 0x03, 0x82,
- 0x02, 0xb3, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x95, 0xf0, 0x0a,
- 0xb3, 0x00, 0xff, 0x48, 0xa2, 0x19, 0xd3, 0x03, 0x82, 0x40, 0xf0,
- 0x82, 0xf3, 0x11, 0x93, 0xbf, 0xec, 0x41, 0x42, 0x02, 0x5e, 0x0f,
- 0x9f, 0x95, 0xf0, 0x11, 0x93, 0x07, 0x82, 0x11, 0x43, 0x03, 0xec,
- 0x02, 0x0e, 0x0f, 0x9f, 0x95, 0xf0, 0x11, 0x93, 0x03, 0x82, 0x09,
- 0xa3, 0x00, 0x01, 0x19, 0xd3, 0x03, 0x82, 0x40, 0x96, 0x1b, 0xd7,
- 0xbf, 0xec, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01,
- 0x00, 0x11, 0x93, 0x20, 0xbc, 0xc8, 0xd2, 0x40, 0xf0, 0xe9, 0xf0,
- 0x41, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x42, 0x20, 0x08,
- 0x0b, 0x01, 0x00, 0x0d, 0x03, 0x05, 0x00, 0x05, 0x94, 0x41, 0x02,
- 0xc1, 0x92, 0x01, 0x97, 0xc3, 0x96, 0xc2, 0xd6, 0x0a, 0x45, 0x00,
- 0x95, 0x02, 0x5e, 0x0f, 0x9f, 0xe6, 0xf0, 0xc1, 0x92, 0x41, 0xb2,
- 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xe6, 0xf0, 0x11, 0x93, 0xc0,
- 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xe6, 0xf0, 0x41, 0x98,
- 0x1c, 0xd9, 0xc0, 0xec, 0x12, 0x95, 0x02, 0x80, 0x01, 0xd4, 0x40,
- 0xf0, 0xfe, 0xf1, 0x0b, 0x67, 0xfd, 0x7d, 0x03, 0x99, 0xc4, 0x92,
- 0x0c, 0x99, 0x96, 0x03, 0x1c, 0xd9, 0x06, 0x82, 0x41, 0x98, 0x1c,
- 0xd9, 0x02, 0x82, 0x42, 0x98, 0x1c, 0xd9, 0x05, 0x82, 0x0c, 0x69,
- 0x80, 0x7f, 0x1c, 0xd9, 0x00, 0xb0, 0x09, 0xa3, 0x00, 0x01, 0xc3,
- 0xd2, 0x01, 0x94, 0x0a, 0xb3, 0x04, 0x00, 0x40, 0x42, 0x02, 0x4e,
- 0x0f, 0x9f, 0xe4, 0xf0, 0x42, 0xa4, 0x1a, 0xd5, 0x02, 0x80, 0x42,
- 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x42, 0x20, 0x08, 0x0b,
- 0x01, 0x00, 0x05, 0x92, 0xc5, 0xd2, 0x60, 0xb2, 0x40, 0x42, 0x02,
- 0x4e, 0x0f, 0x9f, 0xf6, 0xf0, 0x40, 0xf0, 0xd2, 0xf6, 0xc5, 0x94,
- 0x0a, 0xb3, 0x10, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xff,
- 0xf0, 0x40, 0xf0, 0xc0, 0xf5, 0xc5, 0x96, 0x0b, 0xb3, 0x40, 0x00,
- 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x08, 0xf1, 0x40, 0xf0, 0xfa,
- 0xf4, 0xc5, 0x94, 0x0a, 0xb3, 0x01, 0x00, 0x40, 0x42, 0x02, 0x4e,
- 0x0f, 0x9f, 0x70, 0xf1, 0x13, 0x97, 0x21, 0xbc, 0x01, 0xd6, 0x0b,
- 0xb3, 0x02, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x1a, 0xf1,
- 0x40, 0xf0, 0x62, 0xfb, 0x01, 0x94, 0x0a, 0xb3, 0x04, 0x00, 0x40,
- 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x23, 0xf1, 0x40, 0xf0, 0x6c, 0xfb,
- 0x01, 0x96, 0x0b, 0xb3, 0x01, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f,
- 0x9f, 0x4c, 0xf1, 0x40, 0xf0, 0xb0, 0xfa, 0x41, 0x92, 0x19, 0xd3,
- 0x73, 0xf7, 0x11, 0x93, 0x03, 0xec, 0x09, 0x43, 0x40, 0x00, 0x02,
- 0x5e, 0x0f, 0x9f, 0x39, 0xf1, 0x40, 0x94, 0x1a, 0xd5, 0x73, 0xf7,
- 0x11, 0x93, 0x00, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x55,
- 0xf1, 0x11, 0x93, 0xc1, 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f,
- 0x55, 0xf1, 0x40, 0xf0, 0xe0, 0xf1, 0x41, 0x96, 0x1b, 0xd7, 0xc1,
- 0xec, 0x0f, 0x9f, 0x55, 0xf1, 0x01, 0x94, 0x0a, 0xb3, 0x08, 0x00,
- 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x55, 0xf1, 0x40, 0xf0, 0x7c,
- 0xfb, 0x01, 0x96, 0x0b, 0xb3, 0x10, 0x00, 0x40, 0x42, 0x02, 0x4e,
- 0x0f, 0x9f, 0x5e, 0xf1, 0x40, 0xf0, 0x87, 0xfb, 0x11, 0x93, 0x10,
- 0xec, 0x42, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x67, 0xf1, 0x44, 0x92,
- 0x0f, 0x9f, 0x6b, 0xf1, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x6d,
- 0xf1, 0x19, 0xd3, 0x0b, 0xbc, 0x40, 0x94, 0x1a, 0xd5, 0x10, 0xec,
- 0xc5, 0x96, 0x0b, 0xb3, 0x80, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f,
- 0x9f, 0xba, 0xf1, 0x11, 0x93, 0x28, 0xbc, 0x01, 0xd2, 0x09, 0xb3,
- 0x40, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x82, 0xf1, 0x40,
- 0xf0, 0xb5, 0xf6, 0x01, 0x94, 0x0a, 0xb3, 0x02, 0x00, 0x40, 0x42,
- 0x02, 0x4e, 0x0f, 0x9f, 0x95, 0xf1, 0x40, 0xf0, 0x6d, 0xee, 0x40,
- 0xf0, 0x8f, 0xfb, 0x40, 0xf0, 0xc3, 0xf1, 0x40, 0x96, 0x1b, 0xd7,
- 0x00, 0xec, 0x41, 0x92, 0x19, 0xd3, 0x76, 0xf7, 0x01, 0x94, 0x0a,
- 0xb3, 0x04, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xb1, 0xf1,
- 0x40, 0xf0, 0x9e, 0xfb, 0x09, 0x63, 0x00, 0x44, 0x01, 0x97, 0xc3,
- 0x94, 0x48, 0xa4, 0xc1, 0xd4, 0x00, 0xee, 0x40, 0x92, 0x19, 0xd3,
- 0x12, 0x95, 0x19, 0xd3, 0x10, 0x95, 0x19, 0xd3, 0x02, 0x80, 0x19,
- 0xd3, 0x03, 0x82, 0x41, 0x92, 0x19, 0xd3, 0x76, 0xf7, 0x01, 0x94,
- 0x0a, 0xb3, 0x08, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xba,
- 0xf1, 0x40, 0xf0, 0xae, 0xfb, 0x0a, 0x65, 0x00, 0x44, 0x02, 0x97,
- 0xc3, 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x42, 0x00, 0x88, 0x98, 0x90,
- 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09, 0x63, 0x00, 0x40,
- 0x19, 0xd3, 0xf2, 0xbd, 0x0a, 0x65, 0xea, 0x43, 0x02, 0x97, 0xc3,
- 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97,
- 0xc3, 0x92, 0x09, 0xa3, 0x40, 0x00, 0xc2, 0xd2, 0x0a, 0x65, 0xeb,
- 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2, 0xd2,
- 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09,
- 0x63, 0x00, 0x80, 0x19, 0xd3, 0xf2, 0xbd, 0x0a, 0x65, 0xe8, 0x43,
- 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2, 0xd2, 0x0a,
- 0x65, 0xeb, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff,
- 0xc2, 0xd2, 0x0a, 0x65, 0xea, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09,
- 0xb3, 0xfb, 0xff, 0xc2, 0xd2, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x08, 0x0b, 0x01, 0x00, 0x09, 0x93, 0x00, 0x01, 0x19, 0xd3, 0x02,
- 0x80, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00,
- 0x09, 0x93, 0x00, 0x09, 0x19, 0xd3, 0x02, 0x80, 0x40, 0xf0, 0xfe,
- 0xf1, 0x40, 0x92, 0x19, 0xd3, 0x94, 0xec, 0xc8, 0xd2, 0x09, 0x93,
- 0x91, 0xec, 0xc8, 0xd2, 0x40, 0xf0, 0xd0, 0xee, 0x42, 0x00, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0xf0,
- 0xd8, 0xf4, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x2d, 0xf2, 0x0a,
- 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3, 0x92, 0x44, 0xa2, 0xc2, 0xd2,
- 0x0f, 0x9f, 0x3a, 0xf2, 0x40, 0xf0, 0x3c, 0xf2, 0x40, 0x42, 0x02,
- 0x5e, 0x0f, 0x9f, 0x3a, 0xf2, 0xc8, 0xd2, 0x09, 0x93, 0x91, 0xec,
- 0xc8, 0xd2, 0x40, 0xf0, 0xd0, 0xee, 0x42, 0x00, 0x88, 0x98, 0x90,
- 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0xf1, 0xbd,
- 0x19, 0xd3, 0xb6, 0xec, 0x11, 0x93, 0xb4, 0xec, 0x40, 0x42, 0x02,
- 0x5e, 0x0f, 0x9f, 0x54, 0xf2, 0x09, 0x63, 0x00, 0x80, 0x01, 0x97,
- 0xc3, 0x94, 0x0a, 0x07, 0x07, 0x00, 0xc1, 0xd6, 0x0a, 0x05, 0x00,
- 0xa0, 0x1a, 0xd5, 0x96, 0xec, 0x11, 0x93, 0xb6, 0xec, 0x19, 0xd3,
- 0x01, 0x80, 0x0a, 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3, 0x92, 0x41,
- 0xa2, 0xc2, 0xd2, 0x40, 0x92, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x41, 0x20, 0x08, 0x0b, 0x01, 0x00, 0x13, 0x97, 0xb4, 0xec, 0x40,
- 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xc3, 0xf2, 0x12, 0x95, 0x96, 0xec,
- 0x0a, 0x03, 0x07, 0x00, 0xc1, 0x92, 0xc2, 0xd2, 0x11, 0x93, 0x96,
- 0xec, 0x09, 0x05, 0x01, 0x00, 0x48, 0x02, 0xc1, 0x92, 0xc2, 0xd2,
- 0x11, 0x93, 0x96, 0xec, 0x4e, 0x02, 0xc1, 0x94, 0xc5, 0xd6, 0xc5,
- 0x92, 0x11, 0x07, 0x96, 0xec, 0x0b, 0x03, 0x0f, 0x00, 0xc1, 0x98,
- 0x46, 0x06, 0x7a, 0x93, 0x79, 0x93, 0x5c, 0x95, 0x5a, 0x95, 0x02,
- 0xa3, 0xc3, 0xd2, 0x04, 0x95, 0xc5, 0x96, 0x41, 0x06, 0xc5, 0xd6,
- 0x42, 0x46, 0x02, 0x9e, 0x0f, 0x9f, 0x7d, 0xf2, 0x11, 0x93, 0x96,
- 0xec, 0x09, 0x05, 0x05, 0x00, 0x41, 0x02, 0xc1, 0x92, 0xc2, 0xd2,
- 0x11, 0x93, 0x96, 0xec, 0xc1, 0x92, 0x09, 0xb5, 0x1f, 0x00, 0x43,
- 0x44, 0x02, 0x8e, 0x0f, 0x9f, 0xaa, 0xf2, 0x40, 0x44, 0x02, 0x4e,
- 0x0f, 0x9f, 0xab, 0xf2, 0x0a, 0x05, 0xff, 0xff, 0x0f, 0x9f, 0xab,
- 0xf2, 0x43, 0x94, 0x11, 0x93, 0x96, 0xec, 0x42, 0x02, 0xc1, 0xd4,
- 0x13, 0x97, 0x96, 0xec, 0x03, 0x93, 0xd1, 0x94, 0x7a, 0x95, 0x7a,
- 0x95, 0xc1, 0x92, 0x59, 0x93, 0x59, 0x93, 0x01, 0x05, 0x49, 0x06,
- 0xc3, 0x92, 0x7f, 0xb2, 0x01, 0x05, 0x1a, 0xd5, 0xb4, 0xec, 0x0a,
- 0x05, 0xf2, 0xff, 0x1a, 0xd5, 0x92, 0xec, 0x11, 0x93, 0x92, 0xec,
- 0x12, 0x95, 0xb6, 0xec, 0x02, 0x43, 0x02, 0x8e, 0x0f, 0x9f, 0x11,
- 0xf3, 0x02, 0x0e, 0x0f, 0x9f, 0xe4, 0xf2, 0x11, 0x93, 0x7a, 0xf7,
- 0x41, 0x02, 0x19, 0xd3, 0x7a, 0xf7, 0x11, 0x93, 0x79, 0xf7, 0x09,
- 0xa3, 0x80, 0x00, 0x19, 0xd3, 0x79, 0xf7, 0x09, 0x63, 0x00, 0x80,
- 0x01, 0x95, 0xc2, 0x94, 0x1a, 0xd5, 0xb5, 0xec, 0x40, 0x96, 0x1b,
- 0xd7, 0xb4, 0xec, 0x0f, 0x9f, 0x29, 0xf3, 0x11, 0x93, 0x03, 0x80,
- 0x09, 0xb3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xf6,
- 0xf2, 0x11, 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f,
- 0xf6, 0xf2, 0x40, 0xf0, 0x3d, 0xf3, 0x0f, 0x9f, 0x2b, 0xf3, 0x41,
- 0x92, 0xc8, 0xd2, 0x0a, 0x95, 0x91, 0xec, 0xc8, 0xd4, 0x40, 0xf0,
- 0xd0, 0xee, 0x42, 0x00, 0x11, 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02,
- 0x4e, 0x0f, 0x9f, 0x09, 0xf3, 0x42, 0x96, 0x1b, 0xd7, 0xc0, 0xec,
- 0x0f, 0x9f, 0x2b, 0xf3, 0x0a, 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3,
- 0x92, 0x42, 0xa2, 0xc2, 0xd2, 0x0f, 0x9f, 0x2b, 0xf3, 0x12, 0x45,
- 0x03, 0xec, 0x02, 0x4e, 0x0f, 0x9f, 0x23, 0xf3, 0x11, 0x93, 0x7a,
- 0xf7, 0x41, 0x02, 0x19, 0xd3, 0x7a, 0xf7, 0x11, 0x93, 0x79, 0xf7,
- 0x09, 0xa3, 0x00, 0x08, 0x19, 0xd3, 0x79, 0xf7, 0x1a, 0xd5, 0x92,
- 0xec, 0x11, 0x93, 0x92, 0xec, 0x19, 0x25, 0x92, 0xec, 0x09, 0x63,
- 0x00, 0x80, 0x19, 0xd3, 0xf2, 0xbd, 0x41, 0x00, 0x88, 0x98, 0x90,
- 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0xf0, 0x3d, 0xf3,
- 0x40, 0x92, 0xc8, 0xd2, 0x09, 0x93, 0x91, 0xec, 0xc8, 0xd2, 0x40,
- 0xf0, 0xd0, 0xee, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0x75, 0xf7, 0x40, 0x42, 0x02,
- 0x4e, 0x0f, 0x9f, 0x4d, 0xf3, 0x0a, 0x65, 0xbc, 0x69, 0x02, 0x97,
- 0xc3, 0x92, 0x09, 0x83, 0x00, 0x02, 0xc2, 0xd2, 0x11, 0x93, 0x03,
- 0x80, 0x09, 0xb3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f,
- 0x60, 0xf3, 0x11, 0x93, 0x7a, 0xf7, 0x41, 0x02, 0x19, 0xd3, 0x7a,
- 0xf7, 0x11, 0x93, 0x79, 0xf7, 0x09, 0xa3, 0x00, 0x20, 0x19, 0xd3,
- 0x79, 0xf7, 0x11, 0x93, 0xb5, 0xec, 0x19, 0xd3, 0x04, 0x80, 0x12,
- 0x95, 0xb4, 0xec, 0x1a, 0xd5, 0x05, 0x80, 0x09, 0x63, 0x00, 0x80,
- 0x01, 0x97, 0xc3, 0x96, 0x1b, 0xd7, 0xb5, 0xec, 0x40, 0x94, 0x1a,
- 0xd5, 0xb4, 0xec, 0x19, 0xd3, 0xf2, 0xbd, 0x88, 0x98, 0x90, 0x9a,
- 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09, 0x93, 0x96, 0x03, 0x19,
- 0xd3, 0x06, 0x82, 0x09, 0x93, 0x00, 0x01, 0x19, 0xd3, 0x03, 0x82,
- 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x47, 0x20, 0x08, 0x0b, 0x01,
- 0x00, 0x11, 0x93, 0x01, 0x82, 0xc5, 0xd2, 0x40, 0x94, 0x01, 0xd4,
- 0x13, 0x97, 0xb8, 0xec, 0x02, 0xd6, 0x03, 0x95, 0x0c, 0x99, 0xbb,
- 0xec, 0x04, 0x05, 0x13, 0x97, 0x03, 0xec, 0x01, 0x27, 0x02, 0x99,
- 0xc4, 0x92, 0x03, 0x03, 0xc2, 0xd2, 0x14, 0x99, 0xba, 0xec, 0x03,
- 0x09, 0x1c, 0xd9, 0xba, 0xec, 0x12, 0x95, 0x04, 0x82, 0x0a, 0xb3,
- 0x02, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xc6, 0xf4, 0x01,
- 0x92, 0x03, 0xd2, 0x0a, 0xa3, 0x02, 0x00, 0x19, 0xd3, 0x04, 0x82,
- 0x02, 0x96, 0x0b, 0x05, 0x01, 0x00, 0x1a, 0xd5, 0xb8, 0xec, 0xc5,
- 0x92, 0x43, 0x42, 0x02, 0x9e, 0x0f, 0x9f, 0xce, 0xf3, 0x42, 0x44,
- 0x02, 0x8e, 0x0f, 0x9f, 0xce, 0xf3, 0x11, 0x93, 0xbf, 0xec, 0x40,
- 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xce, 0xf3, 0x0c, 0x49, 0xd3, 0x08,
- 0x02, 0x8e, 0x0f, 0x9f, 0xce, 0xf3, 0x11, 0x63, 0x07, 0x82, 0x11,
- 0xa3, 0x07, 0x82, 0x71, 0x93, 0x79, 0x93, 0x79, 0x93, 0x79, 0x93,
- 0x03, 0xd2, 0xc5, 0x94, 0x0a, 0xb5, 0xfc, 0xff, 0x04, 0xd4, 0x03,
- 0x96, 0x40, 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xdd, 0xf3, 0x11, 0x93,
- 0xb8, 0xec, 0x41, 0x42, 0x02, 0x8e, 0x0f, 0x9f, 0xe4, 0xf3, 0xc5,
- 0x98, 0x0c, 0x03, 0xff, 0xff, 0x42, 0x42, 0x02, 0x8e, 0x0f, 0x9f,
- 0x0b, 0xf4, 0x0a, 0x95, 0xbb, 0xec, 0x42, 0x92, 0x19, 0xd3, 0xb9,
- 0xec, 0xc5, 0x96, 0x43, 0x46, 0x02, 0x9e, 0x0f, 0x9f, 0xfd, 0xf3,
- 0x0b, 0x07, 0xfc, 0xff, 0xc5, 0xd6, 0xd2, 0x98, 0x1c, 0xd9, 0xc8,
- 0xbc, 0xd2, 0x96, 0x1b, 0xd7, 0xca, 0xbc, 0x09, 0x03, 0xff, 0xff,
- 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xe9, 0xf3, 0x19, 0xd3, 0xb9,
- 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x09, 0xf4, 0x0a, 0x05,
- 0xfe, 0xff, 0xca, 0xd2, 0xc2, 0xd2, 0x0f, 0x9f, 0x0b, 0xf4, 0x1a,
- 0xd5, 0x93, 0xec, 0x03, 0x98, 0x40, 0x48, 0x02, 0x5e, 0x0f, 0x9f,
- 0x38, 0xf4, 0x11, 0x93, 0xb8, 0xec, 0x41, 0x42, 0x02, 0x9e, 0x0f,
- 0x9f, 0x1b, 0xf4, 0x04, 0x94, 0x48, 0x44, 0x02, 0x4e, 0x0f, 0x9f,
- 0x26, 0xf4, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x38, 0xf4, 0x11,
- 0x93, 0x04, 0x82, 0x41, 0xb2, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f,
- 0x38, 0xf4, 0x41, 0x96, 0x01, 0xd6, 0x0a, 0x65, 0xbd, 0x43, 0x02,
- 0x99, 0xc4, 0x92, 0x09, 0xa3, 0x80, 0x00, 0xc2, 0xd2, 0x0a, 0x65,
- 0xe8, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff, 0xc2,
- 0xd2, 0x0f, 0x9f, 0x97, 0xf4, 0xc5, 0x98, 0x43, 0x48, 0x02, 0x9e,
- 0x0f, 0x9f, 0x97, 0xf4, 0x4f, 0x96, 0x0c, 0xb3, 0x01, 0x00, 0x40,
- 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x45, 0xf4, 0x47, 0x96, 0x11, 0x93,
- 0xb7, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x73, 0xf4, 0x11,
- 0x93, 0xb8, 0xec, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x73, 0xf4,
- 0x12, 0x95, 0x00, 0x82, 0x0a, 0x05, 0xff, 0xaf, 0x05, 0xd4, 0xc8,
- 0xd6, 0xc8, 0xd2, 0x40, 0xf0, 0x18, 0xf7, 0x42, 0x00, 0x05, 0x96,
- 0xc3, 0x94, 0x01, 0xb5, 0x40, 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0x68,
- 0xf4, 0x11, 0x93, 0xba, 0xec, 0x4d, 0x42, 0x02, 0x8e, 0x0f, 0x9f,
- 0x73, 0xf4, 0x06, 0x98, 0x50, 0x98, 0x1c, 0xd9, 0xa2, 0xbc, 0x40,
- 0x98, 0x1c, 0xd9, 0xa2, 0xbc, 0x40, 0x92, 0x03, 0xd2, 0x0f, 0x9f,
- 0x9c, 0xf4, 0x03, 0x94, 0x40, 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0x80,
- 0xf4, 0x0a, 0x65, 0x5e, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x48, 0xa2,
- 0xc2, 0xd2, 0x0f, 0x9f, 0x9c, 0xf4, 0x11, 0x93, 0xb8, 0xec, 0x0c,
- 0x99, 0xbb, 0xec, 0x04, 0x03, 0x04, 0x96, 0x13, 0x25, 0x03, 0xec,
- 0xc1, 0xd4, 0x11, 0x93, 0xba, 0xec, 0x19, 0x05, 0xba, 0xec, 0x1b,
- 0xd7, 0x01, 0x82, 0x0a, 0x65, 0xfd, 0x7d, 0x02, 0x99, 0xc4, 0x92,
- 0x43, 0xa2, 0xc2, 0xd2, 0x41, 0x92, 0x01, 0xd2, 0x03, 0x94, 0x40,
- 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0xb0, 0xf4, 0x11, 0x93, 0xb9, 0xec,
- 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xa8, 0xf4, 0x19, 0xd3, 0xb8,
- 0xec, 0x19, 0xd3, 0xba, 0xec, 0x19, 0xd3, 0xbb, 0xec, 0x03, 0x96,
- 0x40, 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xb0, 0xf4, 0x41, 0x98, 0x1c,
- 0xd9, 0xb7, 0xec, 0x11, 0x93, 0xbf, 0xec, 0x41, 0x42, 0x02, 0x5e,
- 0x0f, 0x9f, 0xc1, 0xf4, 0x11, 0x93, 0x00, 0x82, 0x19, 0xd3, 0x02,
- 0x82, 0x0a, 0x65, 0xfd, 0x7d, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3,
- 0x00, 0x01, 0xc2, 0xd2, 0x40, 0x98, 0x1c, 0xd9, 0xbf, 0xec, 0x0f,
- 0x9f, 0xc9, 0xf4, 0x01, 0x92, 0x19, 0xd3, 0xb7, 0xec, 0x01, 0x94,
- 0x40, 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0xd5, 0xf4, 0x0a, 0x65, 0xea,
- 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xfb, 0xff, 0xc2, 0xd2,
- 0x47, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01,
- 0x00, 0x12, 0x95, 0x03, 0x80, 0x0a, 0xb3, 0x00, 0x40, 0x40, 0x42,
- 0x02, 0x4e, 0x0f, 0x9f, 0xf4, 0xf4, 0x0a, 0xb7, 0x00, 0x08, 0x40,
- 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xf7, 0xf4, 0x11, 0x93, 0x03, 0xec,
- 0x41, 0x02, 0x09, 0xb3, 0xfe, 0xff, 0x12, 0x95, 0x07, 0x80, 0x01,
- 0x45, 0x02, 0x8e, 0x0f, 0x9f, 0xf7, 0xf4, 0x41, 0x92, 0x0f, 0x9f,
- 0xf8, 0xf4, 0x40, 0x92, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x41,
- 0x20, 0x08, 0x0b, 0x01, 0x00, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97,
- 0xc3, 0x92, 0x09, 0xa3, 0x40, 0x00, 0xc2, 0xd2, 0x13, 0x97, 0x6e,
- 0xec, 0x0b, 0x47, 0xa0, 0x00, 0x02, 0x5e, 0x0f, 0x9f, 0x23, 0xf5,
- 0x09, 0x63, 0x08, 0x43, 0x0a, 0x65, 0xff, 0x5f, 0x01, 0x99, 0xc4,
- 0xd4, 0x0a, 0x95, 0x9b, 0xec, 0xd2, 0x96, 0x1b, 0xd7, 0xfa, 0xbc,
- 0xd2, 0x96, 0xc4, 0xd6, 0xd2, 0x98, 0x1c, 0xd9, 0xfa, 0xbc, 0xd2,
- 0x96, 0xc1, 0xd6, 0xc2, 0x94, 0x1a, 0xd5, 0xfa, 0xbc, 0x0f, 0x9f,
- 0x61, 0xf5, 0x0c, 0x69, 0xff, 0x6f, 0x1c, 0xd9, 0xf8, 0xbc, 0x0b,
- 0x47, 0x10, 0x95, 0x02, 0x5e, 0x0f, 0x9f, 0x3b, 0xf5, 0x0a, 0x95,
- 0x6f, 0xec, 0x09, 0x63, 0x06, 0x43, 0x01, 0x99, 0xc4, 0xd6, 0xd2,
- 0x96, 0x1b, 0xd7, 0xf8, 0xbc, 0x0c, 0x69, 0xee, 0x6a, 0xc1, 0xd8,
- 0xc2, 0x94, 0x1a, 0xd5, 0xf8, 0xbc, 0x40, 0x92, 0xc5, 0xd2, 0x11,
- 0x43, 0xc2, 0xec, 0x02, 0x0e, 0x0f, 0x9f, 0x5e, 0xf5, 0xc5, 0x94,
- 0x0a, 0x03, 0x71, 0xec, 0xc1, 0x94, 0x1a, 0xd5, 0xfa, 0xbc, 0x11,
- 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x50, 0xf5,
- 0x0a, 0x95, 0x6f, 0xec, 0xc8, 0xd4, 0x40, 0xf0, 0x39, 0xf7, 0x19,
- 0xd3, 0xf8, 0xbc, 0x41, 0x00, 0xc5, 0x96, 0x41, 0x06, 0xc5, 0xd6,
- 0x13, 0x47, 0xc2, 0xec, 0x02, 0x1e, 0x0f, 0x9f, 0x42, 0xf5, 0x40,
- 0x98, 0x1c, 0xd9, 0xfa, 0xbc, 0x40, 0x92, 0x19, 0xd3, 0x6e, 0xec,
- 0x19, 0xd3, 0xc2, 0xec, 0x0a, 0x65, 0x52, 0x43, 0x02, 0x97, 0xc3,
- 0x92, 0x48, 0xa2, 0xc2, 0xd2, 0x0a, 0x65, 0xeb, 0x43, 0x02, 0x99,
- 0xc4, 0x92, 0x09, 0xb3, 0xbf, 0xff, 0xc2, 0xd2, 0x41, 0x00, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x43, 0x20, 0x08, 0x0b, 0x01, 0x00,
- 0x06, 0x92, 0x01, 0xd2, 0x0a, 0x65, 0xf0, 0x6a, 0x0b, 0x97, 0x6f,
- 0xec, 0x02, 0x99, 0xc4, 0x98, 0xd3, 0xd8, 0x02, 0xd6, 0x0a, 0x03,
- 0x02, 0x00, 0x01, 0x97, 0xc3, 0x98, 0x02, 0x96, 0xc3, 0xd8, 0x01,
- 0x96, 0xc1, 0xd6, 0x1a, 0xd5, 0x6e, 0xec, 0xc5, 0x98, 0x14, 0x99,
- 0x6f, 0xec, 0xc2, 0xd8, 0x43, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88,
- 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0x92, 0xc8, 0xd2, 0x40, 0xf0,
- 0x76, 0xf5, 0x41, 0x00, 0x11, 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02,
- 0x4e, 0x0f, 0x9f, 0xb0, 0xf5, 0x42, 0x42, 0x02, 0x5e, 0x0f, 0x9f,
- 0xad, 0xf5, 0x0a, 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3, 0x92, 0x42,
- 0xa2, 0xc2, 0xd2, 0x40, 0x92, 0x19, 0xd3, 0xc0, 0xec, 0x0a, 0x65,
- 0xeb, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2,
- 0xd2, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3,
- 0xbf, 0xff, 0xc2, 0xd2, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x63,
- 0x20, 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0xaf, 0xbc, 0x47, 0xb2,
- 0x59, 0x95, 0x5a, 0x95, 0x12, 0xa5, 0xbf, 0xbc, 0x0a, 0xb3, 0x01,
- 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xd2, 0xf5, 0x41, 0x04,
- 0x05, 0x93, 0x40, 0x96, 0x20, 0xd6, 0x62, 0x97, 0x0f, 0x9f, 0xe1,
- 0xf5, 0x14, 0x99, 0xfc, 0xbc, 0xd1, 0xd8, 0x14, 0x99, 0xfe, 0xbc,
- 0xd1, 0xd8, 0x20, 0x98, 0x42, 0x08, 0x20, 0xd8, 0x20, 0x98, 0x03,
- 0x49, 0x02, 0x1e, 0x0f, 0x9f, 0xd8, 0xf5, 0xc5, 0x92, 0x62, 0x42,
- 0x02, 0x4e, 0x0f, 0x9f, 0xfa, 0xf5, 0x02, 0x8e, 0x0f, 0x9f, 0xf4,
- 0xf5, 0x61, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x1e, 0xf6, 0x0f, 0x9f,
- 0x4b, 0xf6, 0x63, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x41, 0xf6, 0x0f,
- 0x9f, 0x4b, 0xf6, 0x0d, 0x03, 0x01, 0x00, 0x0c, 0x99, 0x71, 0xec,
- 0x0b, 0x05, 0xff, 0xff, 0x40, 0x96, 0x0f, 0x9f, 0x07, 0xf6, 0xd1,
- 0x96, 0xd4, 0xd6, 0x20, 0x96, 0x41, 0x06, 0x20, 0xd6, 0x02, 0x47,
- 0x02, 0x1e, 0x0f, 0x9f, 0x03, 0xf6, 0x1a, 0xd5, 0xc2, 0xec, 0x0a,
- 0x65, 0xeb, 0x43, 0x02, 0x99, 0xc4, 0x92, 0x09, 0xa3, 0xc0, 0x00,
- 0xc2, 0xd2, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09,
- 0xb3, 0xbf, 0xff, 0xc2, 0xd2, 0x0f, 0x9f, 0x4b, 0xf6, 0x0a, 0x03,
- 0xfe, 0xff, 0x61, 0x95, 0x40, 0x98, 0x20, 0xd8, 0x02, 0x49, 0x02,
- 0x0e, 0x0f, 0x9f, 0x4b, 0xf6, 0x0d, 0x03, 0x01, 0x00, 0x21, 0xd2,
- 0x20, 0x92, 0x05, 0x03, 0x42, 0x02, 0xc8, 0xd2, 0x21, 0x96, 0xc3,
- 0x92, 0x42, 0x06, 0x21, 0xd6, 0xc8, 0xd2, 0x22, 0xd4, 0x40, 0xf0,
- 0xa2, 0xf0, 0x42, 0x00, 0x20, 0x98, 0x42, 0x08, 0x20, 0xd8, 0x22,
- 0x94, 0x02, 0x49, 0x02, 0x1e, 0x0f, 0x9f, 0x2a, 0xf6, 0x0f, 0x9f,
- 0x4b, 0xf6, 0x0d, 0x03, 0x03, 0x00, 0xc8, 0xd2, 0x02, 0x92, 0xc8,
- 0xd2, 0x01, 0x96, 0xc8, 0xd6, 0x40, 0xf0, 0x4e, 0xf6, 0x43, 0x00,
- 0x63, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x45, 0x20, 0x08,
- 0x0b, 0x01, 0x00, 0x0d, 0x03, 0x08, 0x00, 0x08, 0x94, 0xc5, 0xd4,
- 0x09, 0x05, 0x01, 0x00, 0xc2, 0x94, 0x03, 0xd4, 0x42, 0x02, 0xc1,
- 0x92, 0x01, 0xd2, 0x02, 0x97, 0xc5, 0x94, 0x0a, 0x83, 0xff, 0xff,
- 0x11, 0xb3, 0x2c, 0x93, 0x09, 0xb3, 0xfb, 0xff, 0x19, 0xd3, 0x2c,
- 0x93, 0x03, 0x92, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x81, 0xf6,
- 0x01, 0x94, 0xd2, 0x92, 0x19, 0xd3, 0x2c, 0x93, 0x01, 0xd4, 0x02,
- 0x94, 0x12, 0x95, 0x2c, 0x93, 0x44, 0xa4, 0x1a, 0xd5, 0x2c, 0x93,
- 0x0a, 0xb5, 0xfb, 0xff, 0x1a, 0xd5, 0x2c, 0x93, 0x0b, 0x07, 0xff,
- 0xff, 0x40, 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0x6c, 0xf6, 0x09, 0x63,
- 0xd4, 0x6c, 0x01, 0x95, 0xc2, 0x96, 0xc5, 0x94, 0x02, 0xa7, 0xc1,
- 0xd6, 0x03, 0x92, 0x54, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x91, 0xf6,
- 0x0a, 0x83, 0xff, 0xff, 0x1b, 0xb3, 0x2c, 0x93, 0x45, 0x00, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09, 0x63,
- 0x00, 0x40, 0x19, 0xd3, 0xf2, 0xbd, 0x40, 0xf0, 0xd8, 0xf4, 0x40,
- 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xa5, 0xf6, 0x40, 0xf0, 0x3c, 0xf2,
- 0x0f, 0x9f, 0xb3, 0xf6, 0x40, 0x96, 0xc8, 0xd6, 0x09, 0x93, 0x91,
- 0xec, 0xc8, 0xd2, 0x40, 0xf0, 0xd0, 0xee, 0x0a, 0x65, 0xfe, 0x7f,
- 0x02, 0x97, 0xc3, 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x42, 0x00, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x0a, 0x65,
- 0xe8, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0x40, 0x00, 0xc2,
- 0xd2, 0x0a, 0x65, 0xea, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3,
- 0xfb, 0xff, 0xc2, 0xd2, 0x40, 0x92, 0x19, 0xd3, 0x2d, 0xbc, 0x0a,
- 0x65, 0xd8, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff,
- 0xc2, 0xd2, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01,
- 0x00, 0x09, 0x63, 0xea, 0x43, 0x01, 0x97, 0xc3, 0x94, 0x44, 0xa4,
- 0xc1, 0xd4, 0x11, 0x93, 0xb9, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f,
- 0x9f, 0x0c, 0xf7, 0x12, 0x95, 0x93, 0xec, 0x0b, 0x67, 0x36, 0x43,
- 0xd2, 0x98, 0x1c, 0xd9, 0xc8, 0xbc, 0xd2, 0x98, 0x03, 0x93, 0xc1,
- 0xd8, 0x11, 0x93, 0xb9, 0xec, 0x09, 0x03, 0xff, 0xff, 0x19, 0xd3,
- 0xb9, 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xe5, 0xf6, 0x19,
- 0xd3, 0xb8, 0xec, 0x19, 0xd3, 0xba, 0xec, 0x0a, 0x05, 0xfe, 0xff,
- 0xca, 0xd2, 0xca, 0xd2, 0xc2, 0xd2, 0x0a, 0x65, 0x5e, 0x43, 0x02,
- 0x97, 0xc3, 0x92, 0x48, 0xa2, 0xc2, 0xd2, 0x0a, 0x65, 0xea, 0x43,
- 0x02, 0x99, 0xc4, 0x92, 0x09, 0xb3, 0xfb, 0xff, 0x0f, 0x9f, 0x15,
- 0xf7, 0x11, 0x93, 0x03, 0xec, 0x19, 0xd3, 0x01, 0x82, 0x0a, 0x65,
- 0xfd, 0x7d, 0x02, 0x97, 0xc3, 0x92, 0x43, 0xa2, 0xc2, 0xd2, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x03, 0x92,
- 0x04, 0x96, 0x0d, 0x5e, 0x50, 0x46, 0x02, 0x0e, 0x40, 0x92, 0x09,
- 0xee, 0x44, 0x46, 0x04, 0x0e, 0x59, 0x93, 0x44, 0x26, 0x04, 0x5e,
- 0x46, 0xee, 0x41, 0x93, 0x41, 0x26, 0x43, 0x4e, 0x88, 0x98, 0x90,
- 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0xf0, 0xb1, 0xfe,
- 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x03, 0x94,
- 0x1a, 0xd5, 0x40, 0xf7, 0x11, 0x93, 0x00, 0x90, 0x88, 0x98, 0x90,
- 0x9a, 0x1d, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x03, 0x00, 0x18, 0x00,
- 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x16, 0x00, 0x21, 0x00, 0x12,
- 0x00, 0x09, 0x00, 0x13, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00,
- 0x21, 0x00, 0x2d, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x7e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf2, 0x6b, 0xf7, 0x00, 0x00,
- 0x1c, 0xf2, 0x6b, 0xf7, 0x00, 0x00, 0x61, 0xf2, 0x68, 0xf7, 0x6f,
- 0xf7, 0x00, 0x00, 0x2e, 0xf3, 0x6b, 0xf7, 0x25, 0x47, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00
-};
diff --git a/sys/dev/usb2/wlan/if_zydreg.h b/sys/dev/usb2/wlan/if_zydreg.h
deleted file mode 100644
index 8ef34e3..0000000
--- a/sys/dev/usb2/wlan/if_zydreg.h
+++ /dev/null
@@ -1,1338 +0,0 @@
-/* $OpenBSD: if_zydreg.h,v 1.19 2006/11/30 19:28:07 damien Exp $ */
-/* $NetBSD: if_zydreg.h,v 1.2 2007/06/16 11:18:45 kiyohara Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
- * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * ZyDAS ZD1211/ZD1211B USB WLAN driver.
- */
-
-#define ZYD_CR_GPI_EN 0x9418
-#define ZYD_CR_RADIO_PD 0x942c
-#define ZYD_CR_RF2948_PD 0x942c
-#define ZYD_CR_EN_PS_MANUAL_AGC 0x943c
-#define ZYD_CR_CONFIG_PHILIPS 0x9440
-#define ZYD_CR_I2C_WRITE 0x9444
-#define ZYD_CR_SA2400_SER_RP 0x9448
-#define ZYD_CR_RADIO_PE 0x9458
-#define ZYD_CR_RST_BUS_MASTER 0x945c
-#define ZYD_CR_RFCFG 0x9464
-#define ZYD_CR_HSTSCHG 0x946c
-#define ZYD_CR_PHY_ON 0x9474
-#define ZYD_CR_RX_DELAY 0x9478
-#define ZYD_CR_RX_PE_DELAY 0x947c
-#define ZYD_CR_GPIO_1 0x9490
-#define ZYD_CR_GPIO_2 0x9494
-#define ZYD_CR_EnZYD_CRyBufMux 0x94a8
-#define ZYD_CR_PS_CTRL 0x9500
-#define ZYD_CR_ADDA_PWR_DWN 0x9504
-#define ZYD_CR_ADDA_MBIAS_WT 0x9508
-#define ZYD_CR_INTERRUPT 0x9510
-#define ZYD_CR_MAC_PS_STATE 0x950c
-#define ZYD_CR_ATIM_WND_PERIOD 0x951c
-#define ZYD_CR_BCN_INTERVAL 0x9520
-#define ZYD_CR_PRE_TBTT 0x9524
-
-/*
- * MAC registers.
- */
-#define ZYD_MAC_MACADRL 0x9610 /* MAC address (low) */
-#define ZYD_MAC_MACADRH 0x9614 /* MAC address (high) */
-#define ZYD_MAC_BSSADRL 0x9618 /* BSS address (low) */
-#define ZYD_MAC_BSSADRH 0x961c /* BSS address (high) */
-#define ZYD_MAC_BCNCFG 0x9620 /* BCN configuration */
-#define ZYD_MAC_GHTBL 0x9624 /* Group hash table (low) */
-#define ZYD_MAC_GHTBH 0x9628 /* Group hash table (high) */
-#define ZYD_MAC_RX_TIMEOUT 0x962c /* Rx timeout value */
-#define ZYD_MAC_BAS_RATE 0x9630 /* Basic rate setting */
-#define ZYD_MAC_MAN_RATE 0x9634 /* Mandatory rate setting */
-#define ZYD_MAC_RTSCTSRATE 0x9638 /* RTS CTS rate */
-#define ZYD_MAC_BACKOFF_PROTECT 0x963c /* Backoff protection */
-#define ZYD_MAC_RX_THRESHOLD 0x9640 /* Rx threshold */
-#define ZYD_MAC_TX_PE_CONTROL 0x9644 /* Tx_PE control */
-#define ZYD_MAC_AFTER_PNP 0x9648 /* After PnP */
-#define ZYD_MAC_RX_PE_DELAY 0x964c /* Rx_pe delay */
-#define ZYD_MAC_RX_ADDR2_L 0x9650 /* RX address2 (low) */
-#define ZYD_MAC_RX_ADDR2_H 0x9654 /* RX address2 (high) */
-#define ZYD_MAC_SIFS_ACK_TIME 0x9658 /* Dynamic SIFS ack time */
-#define ZYD_MAC_PHY_DELAY 0x9660 /* PHY delay */
-#define ZYD_MAC_PHY_DELAY2 0x966c /* PHY delay */
-#define ZYD_MAC_BCNFIFO 0x9670 /* Beacon FIFO I/O port */
-#define ZYD_MAC_SNIFFER 0x9674 /* Sniffer on/off */
-#define ZYD_MAC_ENCRYPTION_TYPE 0x9678 /* Encryption type */
-#define ZYD_MAC_RETRY 0x967c /* Retry time */
-#define ZYD_MAC_MISC 0x9680 /* Misc */
-#define ZYD_MAC_STMACHINESTAT 0x9684 /* State machine status */
-#define ZYD_MAC_TX_UNDERRUN_CNT 0x9688 /* TX underrun counter */
-#define ZYD_MAC_RXFILTER 0x968c /* Send to host settings */
-#define ZYD_MAC_ACK_EXT 0x9690 /* Acknowledge extension */
-#define ZYD_MAC_BCNFIFOST 0x9694 /* BCN FIFO set and status */
-#define ZYD_MAC_DIFS_EIFS_SIFS 0x9698 /* DIFS, EIFS & SIFS settings */
-#define ZYD_MAC_RX_TIMEOUT_CNT 0x969c /* RX timeout count */
-#define ZYD_MAC_RX_TOTAL_FRAME 0x96a0 /* RX total frame count */
-#define ZYD_MAC_RX_CRC32_CNT 0x96a4 /* RX CRC32 frame count */
-#define ZYD_MAC_RX_CRC16_CNT 0x96a8 /* RX CRC16 frame count */
-#define ZYD_MAC_RX_UDEC 0x96ac /* RX unicast decr. error count */
-#define ZYD_MAC_RX_OVERRUN_CNT 0x96b0 /* RX FIFO overrun count */
-#define ZYD_MAC_RX_MDEC 0x96bc /* RX multicast decr. err. cnt. */
-#define ZYD_MAC_NAV_TCR 0x96c4 /* NAV timer count read */
-#define ZYD_MAC_BACKOFF_ST_RD 0x96c8 /* Backoff status read */
-#define ZYD_MAC_DM_RETRY_CNT_RD 0x96cc /* DM retry count read */
-#define ZYD_MAC_RX_ACR 0x96d0 /* RX arbitration count read */
-#define ZYD_MAC_TX_CCR 0x96d4 /* Tx complete count read */
-#define ZYD_MAC_TCB_ADDR 0x96e8 /* Current PCI process TCP addr */
-#define ZYD_MAC_RCB_ADDR 0x96ec /* Next RCB address */
-#define ZYD_MAC_CONT_WIN_LIMIT 0x96f0 /* Contention window limit */
-#define ZYD_MAC_TX_PKT 0x96f4 /* Tx total packet count read */
-#define ZYD_MAC_DL_CTRL 0x96f8 /* Download control */
-#define ZYD_MAC_CAM_MODE 0x9700 /* CAM: Continuous Access Mode */
-#define ZYD_MACB_TXPWR_CTL1 0x9b00
-#define ZYD_MACB_TXPWR_CTL2 0x9b04
-#define ZYD_MACB_TXPWR_CTL3 0x9b08
-#define ZYD_MACB_TXPWR_CTL4 0x9b0c
-#define ZYD_MACB_AIFS_CTL1 0x9b10
-#define ZYD_MACB_AIFS_CTL2 0x9b14
-#define ZYD_MACB_TXOP 0x9b20
-#define ZYD_MACB_MAX_RETRY 0x9b28
-
-/*
- * Miscellanous registers.
- */
-#define ZYD_FIRMWARE_START_ADDR 0xee00
-#define ZYD_FIRMWARE_BASE_ADDR 0xee1d /* Firmware base address */
-
-/*
- * EEPROM registers.
- */
-#define ZYD_EEPROM_START_HEAD 0xf800 /* EEPROM start */
-#define ZYD_EEPROM_SUBID 0xf817
-#define ZYD_EEPROM_POD 0xf819
-#define ZYD_EEPROM_MAC_ADDR_P1 0xf81b /* Part 1 of the MAC address */
-#define ZYD_EEPROM_MAC_ADDR_P2 0xf81d /* Part 2 of the MAC address */
-#define ZYD_EEPROM_PWR_CAL 0xf81f /* Calibration */
-#define ZYD_EEPROM_PWR_INT 0xf827 /* Calibration */
-#define ZYD_EEPROM_ALLOWEDCHAN 0xf82f /* Allowed CH mask, 1 bit each */
-#define ZYD_EEPROM_DEVICE_VER 0xf837 /* Device version */
-#define ZYD_EEPROM_PHY_REG 0xf83c /* PHY registers */
-#define ZYD_EEPROM_36M_CAL 0xf83f /* Calibration */
-#define ZYD_EEPROM_11A_INT 0xf847 /* Interpolation */
-#define ZYD_EEPROM_48M_CAL 0xf84f /* Calibration */
-#define ZYD_EEPROM_48M_INT 0xf857 /* Interpolation */
-#define ZYD_EEPROM_54M_CAL 0xf85f /* Calibration */
-#define ZYD_EEPROM_54M_INT 0xf867 /* Interpolation */
-
-/*
- * Firmware registers offsets (relative to fwbase).
- */
-#define ZYD_FW_FIRMWARE_REV 0x0000 /* Firmware version */
-#define ZYD_FW_USB_SPEED 0x0001 /* USB speed (!=0 if highspeed) */
-#define ZYD_FW_FIX_TX_RATE 0x0002 /* Fixed TX rate */
-#define ZYD_FW_LINK_STATUS 0x0003
-#define ZYD_FW_SOFT_RESET 0x0004
-#define ZYD_FW_FLASH_CHK 0x0005
-
-/* possible flags for register ZYD_FW_LINK_STATUS */
-#define ZYD_LED1 (1 << 8)
-#define ZYD_LED2 (1 << 9)
-
-/*
- * RF IDs.
- */
-#define ZYD_RF_UW2451 0x2 /* not supported yet */
-#define ZYD_RF_UCHIP 0x3 /* not supported yet */
-#define ZYD_RF_AL2230 0x4
-#define ZYD_RF_AL7230B 0x5
-#define ZYD_RF_THETA 0x6 /* not supported yet */
-#define ZYD_RF_AL2210 0x7
-#define ZYD_RF_MAXIM_NEW 0x8
-#define ZYD_RF_GCT 0x9
-#define ZYD_RF_AL2230S 0xa /* not supported yet */
-#define ZYD_RF_RALINK 0xb /* not supported yet */
-#define ZYD_RF_INTERSIL 0xc /* not supported yet */
-#define ZYD_RF_RFMD 0xd
-#define ZYD_RF_MAXIM_NEW2 0xe
-#define ZYD_RF_PHILIPS 0xf /* not supported yet */
-
-/*
- * PHY registers (8 bits, not documented).
- */
-#define ZYD_CR0 0x9000
-#define ZYD_CR1 0x9004
-#define ZYD_CR2 0x9008
-#define ZYD_CR3 0x900c
-#define ZYD_CR5 0x9010
-#define ZYD_CR6 0x9014
-#define ZYD_CR7 0x9018
-#define ZYD_CR8 0x901c
-#define ZYD_CR4 0x9020
-#define ZYD_CR9 0x9024
-#define ZYD_CR10 0x9028
-#define ZYD_CR11 0x902c
-#define ZYD_CR12 0x9030
-#define ZYD_CR13 0x9034
-#define ZYD_CR14 0x9038
-#define ZYD_CR15 0x903c
-#define ZYD_CR16 0x9040
-#define ZYD_CR17 0x9044
-#define ZYD_CR18 0x9048
-#define ZYD_CR19 0x904c
-#define ZYD_CR20 0x9050
-#define ZYD_CR21 0x9054
-#define ZYD_CR22 0x9058
-#define ZYD_CR23 0x905c
-#define ZYD_CR24 0x9060
-#define ZYD_CR25 0x9064
-#define ZYD_CR26 0x9068
-#define ZYD_CR27 0x906c
-#define ZYD_CR28 0x9070
-#define ZYD_CR29 0x9074
-#define ZYD_CR30 0x9078
-#define ZYD_CR31 0x907c
-#define ZYD_CR32 0x9080
-#define ZYD_CR33 0x9084
-#define ZYD_CR34 0x9088
-#define ZYD_CR35 0x908c
-#define ZYD_CR36 0x9090
-#define ZYD_CR37 0x9094
-#define ZYD_CR38 0x9098
-#define ZYD_CR39 0x909c
-#define ZYD_CR40 0x90a0
-#define ZYD_CR41 0x90a4
-#define ZYD_CR42 0x90a8
-#define ZYD_CR43 0x90ac
-#define ZYD_CR44 0x90b0
-#define ZYD_CR45 0x90b4
-#define ZYD_CR46 0x90b8
-#define ZYD_CR47 0x90bc
-#define ZYD_CR48 0x90c0
-#define ZYD_CR49 0x90c4
-#define ZYD_CR50 0x90c8
-#define ZYD_CR51 0x90cc
-#define ZYD_CR52 0x90d0
-#define ZYD_CR53 0x90d4
-#define ZYD_CR54 0x90d8
-#define ZYD_CR55 0x90dc
-#define ZYD_CR56 0x90e0
-#define ZYD_CR57 0x90e4
-#define ZYD_CR58 0x90e8
-#define ZYD_CR59 0x90ec
-#define ZYD_CR60 0x90f0
-#define ZYD_CR61 0x90f4
-#define ZYD_CR62 0x90f8
-#define ZYD_CR63 0x90fc
-#define ZYD_CR64 0x9100
-#define ZYD_CR65 0x9104
-#define ZYD_CR66 0x9108
-#define ZYD_CR67 0x910c
-#define ZYD_CR68 0x9110
-#define ZYD_CR69 0x9114
-#define ZYD_CR70 0x9118
-#define ZYD_CR71 0x911c
-#define ZYD_CR72 0x9120
-#define ZYD_CR73 0x9124
-#define ZYD_CR74 0x9128
-#define ZYD_CR75 0x912c
-#define ZYD_CR76 0x9130
-#define ZYD_CR77 0x9134
-#define ZYD_CR78 0x9138
-#define ZYD_CR79 0x913c
-#define ZYD_CR80 0x9140
-#define ZYD_CR81 0x9144
-#define ZYD_CR82 0x9148
-#define ZYD_CR83 0x914c
-#define ZYD_CR84 0x9150
-#define ZYD_CR85 0x9154
-#define ZYD_CR86 0x9158
-#define ZYD_CR87 0x915c
-#define ZYD_CR88 0x9160
-#define ZYD_CR89 0x9164
-#define ZYD_CR90 0x9168
-#define ZYD_CR91 0x916c
-#define ZYD_CR92 0x9170
-#define ZYD_CR93 0x9174
-#define ZYD_CR94 0x9178
-#define ZYD_CR95 0x917c
-#define ZYD_CR96 0x9180
-#define ZYD_CR97 0x9184
-#define ZYD_CR98 0x9188
-#define ZYD_CR99 0x918c
-#define ZYD_CR100 0x9190
-#define ZYD_CR101 0x9194
-#define ZYD_CR102 0x9198
-#define ZYD_CR103 0x919c
-#define ZYD_CR104 0x91a0
-#define ZYD_CR105 0x91a4
-#define ZYD_CR106 0x91a8
-#define ZYD_CR107 0x91ac
-#define ZYD_CR108 0x91b0
-#define ZYD_CR109 0x91b4
-#define ZYD_CR110 0x91b8
-#define ZYD_CR111 0x91bc
-#define ZYD_CR112 0x91c0
-#define ZYD_CR113 0x91c4
-#define ZYD_CR114 0x91c8
-#define ZYD_CR115 0x91cc
-#define ZYD_CR116 0x91d0
-#define ZYD_CR117 0x91d4
-#define ZYD_CR118 0x91d8
-#define ZYD_CR119 0x91dc
-#define ZYD_CR120 0x91e0
-#define ZYD_CR121 0x91e4
-#define ZYD_CR122 0x91e8
-#define ZYD_CR123 0x91ec
-#define ZYD_CR124 0x91f0
-#define ZYD_CR125 0x91f4
-#define ZYD_CR126 0x91f8
-#define ZYD_CR127 0x91fc
-#define ZYD_CR128 0x9200
-#define ZYD_CR129 0x9204
-#define ZYD_CR130 0x9208
-#define ZYD_CR131 0x920c
-#define ZYD_CR132 0x9210
-#define ZYD_CR133 0x9214
-#define ZYD_CR134 0x9218
-#define ZYD_CR135 0x921c
-#define ZYD_CR136 0x9220
-#define ZYD_CR137 0x9224
-#define ZYD_CR138 0x9228
-#define ZYD_CR139 0x922c
-#define ZYD_CR140 0x9230
-#define ZYD_CR141 0x9234
-#define ZYD_CR142 0x9238
-#define ZYD_CR143 0x923c
-#define ZYD_CR144 0x9240
-#define ZYD_CR145 0x9244
-#define ZYD_CR146 0x9248
-#define ZYD_CR147 0x924c
-#define ZYD_CR148 0x9250
-#define ZYD_CR149 0x9254
-#define ZYD_CR150 0x9258
-#define ZYD_CR151 0x925c
-#define ZYD_CR152 0x9260
-#define ZYD_CR153 0x9264
-#define ZYD_CR154 0x9268
-#define ZYD_CR155 0x926c
-#define ZYD_CR156 0x9270
-#define ZYD_CR157 0x9274
-#define ZYD_CR158 0x9278
-#define ZYD_CR159 0x927c
-#define ZYD_CR160 0x9280
-#define ZYD_CR161 0x9284
-#define ZYD_CR162 0x9288
-#define ZYD_CR163 0x928c
-#define ZYD_CR164 0x9290
-#define ZYD_CR165 0x9294
-#define ZYD_CR166 0x9298
-#define ZYD_CR167 0x929c
-#define ZYD_CR168 0x92a0
-#define ZYD_CR169 0x92a4
-#define ZYD_CR170 0x92a8
-#define ZYD_CR171 0x92ac
-#define ZYD_CR172 0x92b0
-#define ZYD_CR173 0x92b4
-#define ZYD_CR174 0x92b8
-#define ZYD_CR175 0x92bc
-#define ZYD_CR176 0x92c0
-#define ZYD_CR177 0x92c4
-#define ZYD_CR178 0x92c8
-#define ZYD_CR179 0x92cc
-#define ZYD_CR180 0x92d0
-#define ZYD_CR181 0x92d4
-#define ZYD_CR182 0x92d8
-#define ZYD_CR183 0x92dc
-#define ZYD_CR184 0x92e0
-#define ZYD_CR185 0x92e4
-#define ZYD_CR186 0x92e8
-#define ZYD_CR187 0x92ec
-#define ZYD_CR188 0x92f0
-#define ZYD_CR189 0x92f4
-#define ZYD_CR190 0x92f8
-#define ZYD_CR191 0x92fc
-#define ZYD_CR192 0x9300
-#define ZYD_CR193 0x9304
-#define ZYD_CR194 0x9308
-#define ZYD_CR195 0x930c
-#define ZYD_CR196 0x9310
-#define ZYD_CR197 0x9314
-#define ZYD_CR198 0x9318
-#define ZYD_CR199 0x931c
-#define ZYD_CR200 0x9320
-#define ZYD_CR201 0x9324
-#define ZYD_CR202 0x9328
-#define ZYD_CR203 0x932c
-#define ZYD_CR204 0x9330
-#define ZYD_CR205 0x9334
-#define ZYD_CR206 0x9338
-#define ZYD_CR207 0x933c
-#define ZYD_CR208 0x9340
-#define ZYD_CR209 0x9344
-#define ZYD_CR210 0x9348
-#define ZYD_CR211 0x934c
-#define ZYD_CR212 0x9350
-#define ZYD_CR213 0x9354
-#define ZYD_CR214 0x9358
-#define ZYD_CR215 0x935c
-#define ZYD_CR216 0x9360
-#define ZYD_CR217 0x9364
-#define ZYD_CR218 0x9368
-#define ZYD_CR219 0x936c
-#define ZYD_CR220 0x9370
-#define ZYD_CR221 0x9374
-#define ZYD_CR222 0x9378
-#define ZYD_CR223 0x937c
-#define ZYD_CR224 0x9380
-#define ZYD_CR225 0x9384
-#define ZYD_CR226 0x9388
-#define ZYD_CR227 0x938c
-#define ZYD_CR228 0x9390
-#define ZYD_CR229 0x9394
-#define ZYD_CR230 0x9398
-#define ZYD_CR231 0x939c
-#define ZYD_CR232 0x93a0
-#define ZYD_CR233 0x93a4
-#define ZYD_CR234 0x93a8
-#define ZYD_CR235 0x93ac
-#define ZYD_CR236 0x93b0
-#define ZYD_CR240 0x93c0
-#define ZYD_CR241 0x93c4
-#define ZYD_CR242 0x93c8
-#define ZYD_CR243 0x93cc
-#define ZYD_CR244 0x93d0
-#define ZYD_CR245 0x93d4
-#define ZYD_CR251 0x93ec
-#define ZYD_CR252 0x93f0
-#define ZYD_CR253 0x93f4
-#define ZYD_CR254 0x93f8
-#define ZYD_CR255 0x93fc
-
-/* copied nearly verbatim from the Linux driver rewrite */
-#define ZYD_DEF_PHY \
-{ \
- { ZYD_CR0, 0x0a }, { ZYD_CR1, 0x06 }, { ZYD_CR2, 0x26 }, \
- { ZYD_CR3, 0x38 }, { ZYD_CR4, 0x80 }, { ZYD_CR9, 0xa0 }, \
- { ZYD_CR10, 0x81 }, { ZYD_CR11, 0x00 }, { ZYD_CR12, 0x7f }, \
- { ZYD_CR13, 0x8c }, { ZYD_CR14, 0x80 }, { ZYD_CR15, 0x3d }, \
- { ZYD_CR16, 0x20 }, { ZYD_CR17, 0x1e }, { ZYD_CR18, 0x0a }, \
- { ZYD_CR19, 0x48 }, { ZYD_CR20, 0x0c }, { ZYD_CR21, 0x0c }, \
- { ZYD_CR22, 0x23 }, { ZYD_CR23, 0x90 }, { ZYD_CR24, 0x14 }, \
- { ZYD_CR25, 0x40 }, { ZYD_CR26, 0x10 }, { ZYD_CR27, 0x19 }, \
- { ZYD_CR28, 0x7f }, { ZYD_CR29, 0x80 }, { ZYD_CR30, 0x4b }, \
- { ZYD_CR31, 0x60 }, { ZYD_CR32, 0x43 }, { ZYD_CR33, 0x08 }, \
- { ZYD_CR34, 0x06 }, { ZYD_CR35, 0x0a }, { ZYD_CR36, 0x00 }, \
- { ZYD_CR37, 0x00 }, { ZYD_CR38, 0x38 }, { ZYD_CR39, 0x0c }, \
- { ZYD_CR40, 0x84 }, { ZYD_CR41, 0x2a }, { ZYD_CR42, 0x80 }, \
- { ZYD_CR43, 0x10 }, { ZYD_CR44, 0x12 }, { ZYD_CR46, 0xff }, \
- { ZYD_CR47, 0x1e }, { ZYD_CR48, 0x26 }, { ZYD_CR49, 0x5b }, \
- { ZYD_CR64, 0xd0 }, { ZYD_CR65, 0x04 }, { ZYD_CR66, 0x58 }, \
- { ZYD_CR67, 0xc9 }, { ZYD_CR68, 0x88 }, { ZYD_CR69, 0x41 }, \
- { ZYD_CR70, 0x23 }, { ZYD_CR71, 0x10 }, { ZYD_CR72, 0xff }, \
- { ZYD_CR73, 0x32 }, { ZYD_CR74, 0x30 }, { ZYD_CR75, 0x65 }, \
- { ZYD_CR76, 0x41 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x30 }, \
- { ZYD_CR79, 0x68 }, { ZYD_CR80, 0x64 }, { ZYD_CR81, 0x64 }, \
- { ZYD_CR82, 0x00 }, { ZYD_CR83, 0x00 }, { ZYD_CR84, 0x00 }, \
- { ZYD_CR85, 0x02 }, { ZYD_CR86, 0x00 }, { ZYD_CR87, 0x00 }, \
- { ZYD_CR88, 0xff }, { ZYD_CR89, 0xfc }, { ZYD_CR90, 0x00 }, \
- { ZYD_CR91, 0x00 }, { ZYD_CR92, 0x00 }, { ZYD_CR93, 0x08 }, \
- { ZYD_CR94, 0x00 }, { ZYD_CR95, 0x00 }, { ZYD_CR96, 0xff }, \
- { ZYD_CR97, 0xe7 }, { ZYD_CR98, 0x00 }, { ZYD_CR99, 0x00 }, \
- { ZYD_CR100, 0x00 }, { ZYD_CR101, 0xae }, { ZYD_CR102, 0x02 }, \
- { ZYD_CR103, 0x00 }, { ZYD_CR104, 0x03 }, { ZYD_CR105, 0x65 }, \
- { ZYD_CR106, 0x04 }, { ZYD_CR107, 0x00 }, { ZYD_CR108, 0x0a }, \
- { ZYD_CR109, 0xaa }, { ZYD_CR110, 0xaa }, { ZYD_CR111, 0x25 }, \
- { ZYD_CR112, 0x25 }, { ZYD_CR113, 0x00 }, { ZYD_CR119, 0x1e }, \
- { ZYD_CR125, 0x90 }, { ZYD_CR126, 0x00 }, { ZYD_CR127, 0x00 }, \
- { ZYD_CR5, 0x00 }, { ZYD_CR6, 0x00 }, { ZYD_CR7, 0x00 }, \
- { ZYD_CR8, 0x00 }, { ZYD_CR9, 0x20 }, { ZYD_CR12, 0xf0 }, \
- { ZYD_CR20, 0x0e }, { ZYD_CR21, 0x0e }, { ZYD_CR27, 0x10 }, \
- { ZYD_CR44, 0x33 }, { ZYD_CR47, 0x1E }, { ZYD_CR83, 0x24 }, \
- { ZYD_CR84, 0x04 }, { ZYD_CR85, 0x00 }, { ZYD_CR86, 0x0C }, \
- { ZYD_CR87, 0x12 }, { ZYD_CR88, 0x0C }, { ZYD_CR89, 0x00 }, \
- { ZYD_CR90, 0x10 }, { ZYD_CR91, 0x08 }, { ZYD_CR93, 0x00 }, \
- { ZYD_CR94, 0x01 }, { ZYD_CR95, 0x00 }, { ZYD_CR96, 0x50 }, \
- { ZYD_CR97, 0x37 }, { ZYD_CR98, 0x35 }, { ZYD_CR101, 0x13 }, \
- { ZYD_CR102, 0x27 }, { ZYD_CR103, 0x27 }, { ZYD_CR104, 0x18 }, \
- { ZYD_CR105, 0x12 }, { ZYD_CR109, 0x27 }, { ZYD_CR110, 0x27 }, \
- { ZYD_CR111, 0x27 }, { ZYD_CR112, 0x27 }, { ZYD_CR113, 0x27 }, \
- { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, { ZYD_CR116, 0x24 }, \
- { ZYD_CR117, 0xfc }, { ZYD_CR118, 0xfa }, { ZYD_CR120, 0x4f }, \
- { ZYD_CR125, 0xaa }, { ZYD_CR127, 0x03 }, { ZYD_CR128, 0x14 }, \
- { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, { ZYD_CR131, 0x0C }, \
- { ZYD_CR136, 0xdf }, { ZYD_CR137, 0x40 }, { ZYD_CR138, 0xa0 }, \
- { ZYD_CR139, 0xb0 }, { ZYD_CR140, 0x99 }, { ZYD_CR141, 0x82 }, \
- { ZYD_CR142, 0x54 }, { ZYD_CR143, 0x1c }, { ZYD_CR144, 0x6c }, \
- { ZYD_CR147, 0x07 }, { ZYD_CR148, 0x4c }, { ZYD_CR149, 0x50 }, \
- { ZYD_CR150, 0x0e }, { ZYD_CR151, 0x18 }, { ZYD_CR160, 0xfe }, \
- { ZYD_CR161, 0xee }, { ZYD_CR162, 0xaa }, { ZYD_CR163, 0xfa }, \
- { ZYD_CR164, 0xfa }, { ZYD_CR165, 0xea }, { ZYD_CR166, 0xbe }, \
- { ZYD_CR167, 0xbe }, { ZYD_CR168, 0x6a }, { ZYD_CR169, 0xba }, \
- { ZYD_CR170, 0xba }, { ZYD_CR171, 0xba }, { ZYD_CR204, 0x7d }, \
- { ZYD_CR203, 0x30 }, { 0, 0} \
-}
-
-#define ZYD_DEF_PHYB \
-{ \
- { ZYD_CR0, 0x14 }, { ZYD_CR1, 0x06 }, { ZYD_CR2, 0x26 }, \
- { ZYD_CR3, 0x38 }, { ZYD_CR4, 0x80 }, { ZYD_CR9, 0xe0 }, \
- { ZYD_CR10, 0x81 }, { ZYD_CR11, 0x00 }, { ZYD_CR12, 0xf0 }, \
- { ZYD_CR13, 0x8c }, { ZYD_CR14, 0x80 }, { ZYD_CR15, 0x3d }, \
- { ZYD_CR16, 0x20 }, { ZYD_CR17, 0x1e }, { ZYD_CR18, 0x0a }, \
- { ZYD_CR19, 0x48 }, { ZYD_CR20, 0x10 }, { ZYD_CR21, 0x0e }, \
- { ZYD_CR22, 0x23 }, { ZYD_CR23, 0x90 }, { ZYD_CR24, 0x14 }, \
- { ZYD_CR25, 0x40 }, { ZYD_CR26, 0x10 }, { ZYD_CR27, 0x10 }, \
- { ZYD_CR28, 0x7f }, { ZYD_CR29, 0x80 }, { ZYD_CR30, 0x4b }, \
- { ZYD_CR31, 0x60 }, { ZYD_CR32, 0x43 }, { ZYD_CR33, 0x08 }, \
- { ZYD_CR34, 0x06 }, { ZYD_CR35, 0x0a }, { ZYD_CR36, 0x00 }, \
- { ZYD_CR37, 0x00 }, { ZYD_CR38, 0x38 }, { ZYD_CR39, 0x0c }, \
- { ZYD_CR40, 0x84 }, { ZYD_CR41, 0x2a }, { ZYD_CR42, 0x80 }, \
- { ZYD_CR43, 0x10 }, { ZYD_CR44, 0x33 }, { ZYD_CR46, 0xff }, \
- { ZYD_CR47, 0x1E }, { ZYD_CR48, 0x26 }, { ZYD_CR49, 0x5b }, \
- { ZYD_CR64, 0xd0 }, { ZYD_CR65, 0x04 }, { ZYD_CR66, 0x58 }, \
- { ZYD_CR67, 0xc9 }, { ZYD_CR68, 0x88 }, { ZYD_CR69, 0x41 }, \
- { ZYD_CR70, 0x23 }, { ZYD_CR71, 0x10 }, { ZYD_CR72, 0xff }, \
- { ZYD_CR73, 0x32 }, { ZYD_CR74, 0x30 }, { ZYD_CR75, 0x65 }, \
- { ZYD_CR76, 0x41 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x30 }, \
- { ZYD_CR79, 0xf0 }, { ZYD_CR80, 0x64 }, { ZYD_CR81, 0x64 }, \
- { ZYD_CR82, 0x00 }, { ZYD_CR83, 0x24 }, { ZYD_CR84, 0x04 }, \
- { ZYD_CR85, 0x00 }, { ZYD_CR86, 0x0c }, { ZYD_CR87, 0x12 }, \
- { ZYD_CR88, 0x0c }, { ZYD_CR89, 0x00 }, { ZYD_CR90, 0x58 }, \
- { ZYD_CR91, 0x04 }, { ZYD_CR92, 0x00 }, { ZYD_CR93, 0x00 }, \
- { ZYD_CR94, 0x01 }, { ZYD_CR95, 0x20 }, { ZYD_CR96, 0x50 }, \
- { ZYD_CR97, 0x37 }, { ZYD_CR98, 0x35 }, { ZYD_CR99, 0x00 }, \
- { ZYD_CR100, 0x01 }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR103, 0x27 }, { ZYD_CR104, 0x18 }, { ZYD_CR105, 0x12 }, \
- { ZYD_CR106, 0x04 }, { ZYD_CR107, 0x00 }, { ZYD_CR108, 0x0a }, \
- { ZYD_CR109, 0x27 }, { ZYD_CR110, 0x27 }, { ZYD_CR111, 0x27 }, \
- { ZYD_CR112, 0x27 }, { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, \
- { ZYD_CR115, 0x26 }, { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xfc }, \
- { ZYD_CR118, 0xfa }, { ZYD_CR119, 0x1e }, { ZYD_CR125, 0x90 }, \
- { ZYD_CR126, 0x00 }, { ZYD_CR127, 0x00 }, { ZYD_CR128, 0x14 }, \
- { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, { ZYD_CR131, 0x0c }, \
- { ZYD_CR136, 0xdf }, { ZYD_CR137, 0xa0 }, { ZYD_CR138, 0xa8 }, \
- { ZYD_CR139, 0xb4 }, { ZYD_CR140, 0x98 }, { ZYD_CR141, 0x82 }, \
- { ZYD_CR142, 0x53 }, { ZYD_CR143, 0x1c }, { ZYD_CR144, 0x6c }, \
- { ZYD_CR147, 0x07 }, { ZYD_CR148, 0x40 }, { ZYD_CR149, 0x40 }, \
- { ZYD_CR150, 0x14 }, { ZYD_CR151, 0x18 }, { ZYD_CR159, 0x70 }, \
- { ZYD_CR160, 0xfe }, { ZYD_CR161, 0xee }, { ZYD_CR162, 0xaa }, \
- { ZYD_CR163, 0xfa }, { ZYD_CR164, 0xfa }, { ZYD_CR165, 0xea }, \
- { ZYD_CR166, 0xbe }, { ZYD_CR167, 0xbe }, { ZYD_CR168, 0x6a }, \
- { ZYD_CR169, 0xba }, { ZYD_CR170, 0xba }, { ZYD_CR171, 0xba }, \
- { ZYD_CR204, 0x7d }, { ZYD_CR203, 0x30 }, \
- { 0, 0 } \
-}
-
-#define ZYD_RFMD_PHY \
-{ \
- { ZYD_CR2, 0x1e }, { ZYD_CR9, 0x20 }, { ZYD_CR10, 0x89 }, \
- { ZYD_CR11, 0x00 }, { ZYD_CR15, 0xd0 }, { ZYD_CR17, 0x68 }, \
- { ZYD_CR19, 0x4a }, { ZYD_CR20, 0x0c }, { ZYD_CR21, 0x0e }, \
- { ZYD_CR23, 0x48 }, { ZYD_CR24, 0x14 }, { ZYD_CR26, 0x90 }, \
- { ZYD_CR27, 0x30 }, { ZYD_CR29, 0x20 }, { ZYD_CR31, 0xb2 }, \
- { ZYD_CR32, 0x43 }, { ZYD_CR33, 0x28 }, { ZYD_CR38, 0x30 }, \
- { ZYD_CR34, 0x0f }, { ZYD_CR35, 0xf0 }, { ZYD_CR41, 0x2a }, \
- { ZYD_CR46, 0x7f }, { ZYD_CR47, 0x1e }, { ZYD_CR51, 0xc5 }, \
- { ZYD_CR52, 0xc5 }, { ZYD_CR53, 0xc5 }, { ZYD_CR79, 0x58 }, \
- { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR82, 0x00 }, \
- { ZYD_CR83, 0x24 }, { ZYD_CR84, 0x04 }, { ZYD_CR85, 0x00 }, \
- { ZYD_CR86, 0x10 }, { ZYD_CR87, 0x2a }, { ZYD_CR88, 0x10 }, \
- { ZYD_CR89, 0x24 }, { ZYD_CR90, 0x18 }, { ZYD_CR91, 0x00 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR93, 0x00 }, { ZYD_CR94, 0x01 }, \
- { ZYD_CR95, 0x00 }, { ZYD_CR96, 0x40 }, { ZYD_CR97, 0x37 }, \
- { ZYD_CR98, 0x05 }, { ZYD_CR99, 0x28 }, { ZYD_CR100, 0x00 }, \
- { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, { ZYD_CR103, 0x27 }, \
- { ZYD_CR104, 0x18 }, { ZYD_CR105, 0x12 }, { ZYD_CR106, 0x1a }, \
- { ZYD_CR107, 0x24 }, { ZYD_CR108, 0x0a }, { ZYD_CR109, 0x13 }, \
- { ZYD_CR110, 0x2f }, { ZYD_CR111, 0x27 }, { ZYD_CR112, 0x27 }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x40 }, \
- { ZYD_CR116, 0x40 }, { ZYD_CR117, 0xf0 }, { ZYD_CR118, 0xf0 }, \
- { ZYD_CR119, 0x16 }, { ZYD_CR122, 0x00 }, { ZYD_CR127, 0x03 }, \
- { ZYD_CR131, 0x08 }, { ZYD_CR138, 0x28 }, { ZYD_CR148, 0x44 }, \
- { ZYD_CR150, 0x10 }, { ZYD_CR169, 0xbb }, { ZYD_CR170, 0xbb } \
-}
-
-#define ZYD_RFMD_RF \
-{ \
- 0x000007, 0x07dd43, 0x080959, 0x0e6666, 0x116a57, 0x17dd43, \
- 0x1819f9, 0x1e6666, 0x214554, 0x25e7fa, 0x27fffa, 0x294128, \
- 0x2c0000, 0x300000, 0x340000, 0x381e0f, 0x6c180f \
-}
-
-#define ZYD_RFMD_CHANTABLE \
-{ \
- { 0x181979, 0x1e6666 }, \
- { 0x181989, 0x1e6666 }, \
- { 0x181999, 0x1e6666 }, \
- { 0x1819a9, 0x1e6666 }, \
- { 0x1819b9, 0x1e6666 }, \
- { 0x1819c9, 0x1e6666 }, \
- { 0x1819d9, 0x1e6666 }, \
- { 0x1819e9, 0x1e6666 }, \
- { 0x1819f9, 0x1e6666 }, \
- { 0x181a09, 0x1e6666 }, \
- { 0x181a19, 0x1e6666 }, \
- { 0x181a29, 0x1e6666 }, \
- { 0x181a39, 0x1e6666 }, \
- { 0x181a60, 0x1c0000 } \
-}
-
-#define ZYD_AL2230_PHY \
-{ \
- { ZYD_CR15, 0x20 }, { ZYD_CR23, 0x40 }, { ZYD_CR24, 0x20 }, \
- { ZYD_CR26, 0x11 }, { ZYD_CR28, 0x3e }, { ZYD_CR29, 0x00 }, \
- { ZYD_CR44, 0x33 }, { ZYD_CR106, 0x2a }, { ZYD_CR107, 0x1a }, \
- { ZYD_CR109, 0x09 }, { ZYD_CR110, 0x27 }, { ZYD_CR111, 0x2b }, \
- { ZYD_CR112, 0x2b }, { ZYD_CR119, 0x0a }, { ZYD_CR10, 0x89 }, \
- { ZYD_CR17, 0x28 }, { ZYD_CR26, 0x93 }, { ZYD_CR34, 0x30 }, \
- { ZYD_CR35, 0x3e }, { ZYD_CR41, 0x24 }, { ZYD_CR44, 0x32 }, \
- { ZYD_CR46, 0x96 }, { ZYD_CR47, 0x1e }, { ZYD_CR79, 0x58 }, \
- { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR87, 0x0a }, \
- { ZYD_CR89, 0x04 }, { ZYD_CR92, 0x0a }, { ZYD_CR99, 0x28 }, \
- { ZYD_CR100, 0x00 }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x24 }, { ZYD_CR107, 0x2a }, { ZYD_CR109, 0x09 }, \
- { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x1f }, { ZYD_CR112, 0x1f }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0xfc }, \
- { ZYD_CR119, 0x10 }, { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, \
- { ZYD_CR122, 0xe0 }, { ZYD_CR137, 0x88 }, { ZYD_CR252, 0xff }, \
- { ZYD_CR253, 0xff }, { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x3f }, \
- { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 } \
-}
-
-#define ZYD_AL2230_PHY_B \
-{ \
- { ZYD_CR10, 0x89 }, { ZYD_CR15, 0x20 }, { ZYD_CR17, 0x2B }, \
- { ZYD_CR23, 0x40 }, { ZYD_CR24, 0x20 }, { ZYD_CR26, 0x93 }, \
- { ZYD_CR28, 0x3e }, { ZYD_CR29, 0x00 }, { ZYD_CR33, 0x28 }, \
- { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x3e }, { ZYD_CR41, 0x24 }, \
- { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x99 }, { ZYD_CR47, 0x1e }, \
- { ZYD_CR48, 0x06 }, { ZYD_CR49, 0xf9 }, { ZYD_CR51, 0x01 }, \
- { ZYD_CR52, 0x80 }, { ZYD_CR53, 0x7e }, { ZYD_CR65, 0x00 }, \
- { ZYD_CR66, 0x00 }, { ZYD_CR67, 0x00 }, { ZYD_CR68, 0x00 }, \
- { ZYD_CR69, 0x28 }, { ZYD_CR79, 0x58 }, { ZYD_CR80, 0x30 }, \
- { ZYD_CR81, 0x30 }, { ZYD_CR87, 0x0a }, { ZYD_CR89, 0x04 }, \
- { ZYD_CR91, 0x00 }, { ZYD_CR92, 0x0a }, { ZYD_CR98, 0x8d }, \
- { ZYD_CR99, 0x00 }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x24 }, { ZYD_CR107, 0x2a }, { ZYD_CR109, 0x13 }, \
- { ZYD_CR110, 0x1f }, { ZYD_CR111, 0x1f }, { ZYD_CR112, 0x1f }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xfa }, { ZYD_CR118, 0xfa }, \
- { ZYD_CR119, 0x10 }, { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x6c }, \
- { ZYD_CR122, 0xfc }, { ZYD_CR123, 0x57 }, { ZYD_CR125, 0xad }, \
- { ZYD_CR126, 0x6c }, { ZYD_CR127, 0x03 }, { ZYD_CR137, 0x50 }, \
- { ZYD_CR138, 0xa8 }, { ZYD_CR144, 0xac }, { ZYD_CR150, 0x0d }, \
- { ZYD_CR252, 0x34 }, { ZYD_CR253, 0x34 } \
-}
-
-#define ZYD_AL2230_PHY_PART1 \
-{ \
- { ZYD_CR240, 0x57 }, { ZYD_CR9, 0xe0 } \
-}
-
-#define ZYD_AL2230_PHY_PART2 \
-{ \
- { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x7f }, \
-}
-
-#define ZYD_AL2230_PHY_PART3 \
-{ \
- { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \
-}
-
-#define ZYD_AL2230S_PHY_INIT \
-{ \
- { ZYD_CR47, 0x1e }, { ZYD_CR106, 0x22 }, { ZYD_CR107, 0x2a }, \
- { ZYD_CR109, 0x13 }, { ZYD_CR118, 0xf8 }, { ZYD_CR119, 0x12 }, \
- { ZYD_CR122, 0xe0 }, { ZYD_CR128, 0x10 }, { ZYD_CR129, 0x0e }, \
- { ZYD_CR130, 0x10 } \
-}
-
-#define ZYD_AL2230_PHY_FINI_PART1 \
-{ \
- { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR79, 0x58 }, \
- { ZYD_CR12, 0xf0 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x58 }, \
- { ZYD_CR203, 0x06 }, { ZYD_CR240, 0x80 }, \
-}
-
-#define ZYD_AL2230_RF_PART1 \
-{ \
- 0x03f790, 0x033331, 0x00000d, 0x0b3331, 0x03b812, 0x00fff3 \
-}
-
-#define ZYD_AL2230_RF_PART2 \
-{ \
- 0x000da4, 0x0f4dc5, 0x0805b6, 0x011687, 0x000688, 0x0403b9, \
- 0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00500f \
-}
-
-#define ZYD_AL2230_RF_PART3 \
-{ \
- 0x00d00f, 0x004c0f, 0x00540f, 0x00700f, 0x00500f \
-}
-
-#define ZYD_AL2230_RF_B \
-{ \
- 0x03f790, 0x033331, 0x00000d, 0x0b3331, 0x03b812, 0x00fff3, \
- 0x0005a4, 0x0f4dc5, 0x0805b6, 0x0146c7, 0x000688, 0x0403b9, \
- 0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00580f \
-}
-
-#define ZYD_AL2230_RF_B_PART1 \
-{ \
- 0x8cccd0, 0x481dc0, 0xcfff00, 0x25a000 \
-}
-
-#define ZYD_AL2230_RF_B_PART2 \
-{ \
- 0x25a000, 0xa3b2f0, 0x6da010, 0xe36280, 0x116000, 0x9dc020, \
- 0x5ddb00, 0xd99000, 0x3ffbd0, 0xb00000, 0xf01a00 \
-}
-
-#define ZYD_AL2230_RF_B_PART3 \
-{ \
- 0xf01b00, 0xf01e00, 0xf01a00 \
-}
-
-#define ZYD_AL2230_CHANTABLE \
-{ \
- { 0x03f790, 0x033331, 0x00000d }, \
- { 0x03f790, 0x0b3331, 0x00000d }, \
- { 0x03e790, 0x033331, 0x00000d }, \
- { 0x03e790, 0x0b3331, 0x00000d }, \
- { 0x03f7a0, 0x033331, 0x00000d }, \
- { 0x03f7a0, 0x0b3331, 0x00000d }, \
- { 0x03e7a0, 0x033331, 0x00000d }, \
- { 0x03e7a0, 0x0b3331, 0x00000d }, \
- { 0x03f7b0, 0x033331, 0x00000d }, \
- { 0x03f7b0, 0x0b3331, 0x00000d }, \
- { 0x03e7b0, 0x033331, 0x00000d }, \
- { 0x03e7b0, 0x0b3331, 0x00000d }, \
- { 0x03f7c0, 0x033331, 0x00000d }, \
- { 0x03e7c0, 0x066661, 0x00000d } \
-}
-
-#define ZYD_AL2230_CHANTABLE_B \
-{ \
- { 0x09efc0, 0x8cccc0, 0xb00000 }, \
- { 0x09efc0, 0x8cccd0, 0xb00000 }, \
- { 0x09e7c0, 0x8cccc0, 0xb00000 }, \
- { 0x09e7c0, 0x8cccd0, 0xb00000 }, \
- { 0x05efc0, 0x8cccc0, 0xb00000 }, \
- { 0x05efc0, 0x8cccd0, 0xb00000 }, \
- { 0x05e7c0, 0x8cccc0, 0xb00000 }, \
- { 0x05e7c0, 0x8cccd0, 0xb00000 }, \
- { 0x0defc0, 0x8cccc0, 0xb00000 }, \
- { 0x0defc0, 0x8cccd0, 0xb00000 }, \
- { 0x0de7c0, 0x8cccc0, 0xb00000 }, \
- { 0x0de7c0, 0x8cccd0, 0xb00000 }, \
- { 0x03efc0, 0x8cccc0, 0xb00000 }, \
- { 0x03e7c0, 0x866660, 0xb00000 } \
-}
-
-#define ZYD_AL7230B_PHY_1 \
-{ \
- { ZYD_CR240, 0x57 }, { ZYD_CR15, 0x20 }, { ZYD_CR23, 0x40 }, \
- { ZYD_CR24, 0x20 }, { ZYD_CR26, 0x11 }, { ZYD_CR28, 0x3e }, \
- { ZYD_CR29, 0x00 }, { ZYD_CR44, 0x33 }, { ZYD_CR106, 0x22 }, \
- { ZYD_CR107, 0x1a }, { ZYD_CR109, 0x09 }, { ZYD_CR110, 0x27 }, \
- { ZYD_CR111, 0x2b }, { ZYD_CR112, 0x2b }, { ZYD_CR119, 0x0a }, \
- { ZYD_CR122, 0xfc }, { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x28 }, \
- { ZYD_CR26, 0x93 }, { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x3e }, \
- { ZYD_CR41, 0x24 }, { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x96 }, \
- { ZYD_CR47, 0x1e }, { ZYD_CR79, 0x58 }, { ZYD_CR80, 0x30 }, \
- { ZYD_CR81, 0x30 }, { ZYD_CR87, 0x0a }, { ZYD_CR89, 0x04 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR99, 0x28 }, { ZYD_CR100, 0x02 }, \
- { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, { ZYD_CR106, 0x22 }, \
- { ZYD_CR107, 0x3f }, { ZYD_CR109, 0x09 }, { ZYD_CR110, 0x1f }, \
- { ZYD_CR111, 0x1f }, { ZYD_CR112, 0x1f }, { ZYD_CR113, 0x27 }, \
- { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, { ZYD_CR116, 0x3f }, \
- { ZYD_CR117, 0xfa }, { ZYD_CR118, 0xfc }, { ZYD_CR119, 0x10 }, \
- { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, { ZYD_CR137, 0x88 }, \
- { ZYD_CR138, 0xa8 }, { ZYD_CR252, 0x34 }, { ZYD_CR253, 0x34 }, \
- { ZYD_CR251, 0x2f } \
-}
-
-#define ZYD_AL7230B_PHY_2 \
-{ \
- { ZYD_CR251, 0x3f }, { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, \
- { ZYD_CR130, 0x10 }, { ZYD_CR38, 0x38 }, { ZYD_CR136, 0xdf } \
-}
-
-#define ZYD_AL7230B_PHY_3 \
-{ \
- { ZYD_CR203, 0x06 }, { ZYD_CR240, 0x80 } \
-}
-
-#define ZYD_AL7230B_RF_1 \
-{ \
- 0x09ec04, 0x8cccc8, 0x4ff821, 0xc5fbfc, 0x21ebfe, 0xafd401, \
- 0x6cf56a, 0xe04073, 0x193d76, 0x9dd844, 0x500007, 0xd8c010, \
- 0x3c9000, 0xbfffff, 0x700000, 0xf15d58 \
-}
-
-#define ZYD_AL7230B_RF_2 \
-{ \
- 0xf15d59, 0xf15d5c, 0xf15d58 \
-}
-
-#define ZYD_AL7230B_RF_SETCHANNEL \
-{ \
- 0x4ff821, 0xc5fbfc, 0x21ebfe, 0xafd401, 0x6cf56a, 0xe04073, \
- 0x193d76, 0x9dd844, 0x500007, 0xd8c010, 0x3c9000, 0xf15d58 \
-}
-
-#define ZYD_AL7230B_CHANTABLE \
-{ \
- { 0x09ec00, 0x8cccc8 }, \
- { 0x09ec00, 0x8cccd8 }, \
- { 0x09ec00, 0x8cccc0 }, \
- { 0x09ec00, 0x8cccd0 }, \
- { 0x05ec00, 0x8cccc8 }, \
- { 0x05ec00, 0x8cccd8 }, \
- { 0x05ec00, 0x8cccc0 }, \
- { 0x05ec00, 0x8cccd0 }, \
- { 0x0dec00, 0x8cccc8 }, \
- { 0x0dec00, 0x8cccd8 }, \
- { 0x0dec00, 0x8cccc0 }, \
- { 0x0dec00, 0x8cccd0 }, \
- { 0x03ec00, 0x8cccc8 }, \
- { 0x03ec00, 0x866660 } \
-}
-
-#define ZYD_AL2210_PHY \
-{ \
- { ZYD_CR9, 0xe0 }, { ZYD_CR10, 0x91 }, { ZYD_CR12, 0x90 }, \
- { ZYD_CR15, 0xd0 }, { ZYD_CR16, 0x40 }, { ZYD_CR17, 0x58 }, \
- { ZYD_CR18, 0x04 }, { ZYD_CR23, 0x66 }, { ZYD_CR24, 0x14 }, \
- { ZYD_CR26, 0x90 }, { ZYD_CR31, 0x80 }, { ZYD_CR34, 0x06 }, \
- { ZYD_CR35, 0x3e }, { ZYD_CR38, 0x38 }, { ZYD_CR46, 0x90 }, \
- { ZYD_CR47, 0x1e }, { ZYD_CR64, 0x64 }, { ZYD_CR79, 0xb5 }, \
- { ZYD_CR80, 0x38 }, { ZYD_CR81, 0x30 }, { ZYD_CR113, 0xc0 }, \
- { ZYD_CR127, 0x03 } \
-}
-
-#define ZYD_AL2210_RF \
-{ \
- 0x2396c0, 0x00fcb1, 0x358132, 0x0108b3, 0xc77804, 0x456415, \
- 0xff2226, 0x806667, 0x7860f8, 0xbb01c9, 0x00000a, 0x00000b \
-}
-
-#define ZYD_AL2210_CHANTABLE \
-{ \
- 0x0196c0, 0x019710, 0x019760, 0x0197b0, 0x019800, 0x019850, \
- 0x0198a0, 0x0198f0, 0x019940, 0x019990, 0x0199e0, 0x019a30, \
- 0x019a80, 0x019b40 \
-}
-
-#define ZYD_GCT_PHY \
-{ \
- { ZYD_CR47, 0x1e }, { ZYD_CR15, 0xdc }, { ZYD_CR113, 0xc0 }, \
- { ZYD_CR20, 0x0c }, { ZYD_CR17, 0x65 }, { ZYD_CR34, 0x04 }, \
- { ZYD_CR35, 0x35 }, { ZYD_CR24, 0x20 }, { ZYD_CR9, 0xe0 }, \
- { ZYD_CR127, 0x02 }, { ZYD_CR10, 0x91 }, { ZYD_CR23, 0x7f }, \
- { ZYD_CR27, 0x10 }, { ZYD_CR28, 0x7a }, { ZYD_CR79, 0xb5 }, \
- { ZYD_CR64, 0x80 }, { ZYD_CR33, 0x28 }, { ZYD_CR38, 0x30 } \
-}
-
-#define ZYD_GCT_RF \
-{ \
- 0x1f0000, 0x1f0000, 0x1f0200, 0x1f0600, 0x1f8600, 0x1f8600, \
- 0x002050, 0x1f8000, 0x1f8200, 0x1f8600, 0x1c0000, 0x10c458, \
- 0x088e92, 0x187b82, 0x0401b4, 0x140816, 0x0c7000, 0x1c0000, \
- 0x02ccae, 0x128023, 0x0a0000, 0x1a0000, 0x06e380, 0x16cb94, \
- 0x0e1740, 0x014980, 0x116240, 0x090000, 0x192304, 0x05112f, \
- 0x0d54a8, 0x0f8000, 0x1c0008, 0x1c0000, 0x1a0000, 0x1c0008, \
- 0x150000, 0x0c7000, 0x150800, 0x150000 \
-}
-
-#define ZYD_GCT_CHANTABLE \
-{ \
- 0x1a0000, 0x1a8000, 0x1a4000, 0x1ac000, 0x1a2000, 0x1aa000, \
- 0x1a6000, 0x1ae000, 0x1a1000, 0x1a9000, 0x1a5000, 0x1ad000, \
- 0x1a3000, 0x1ab000 \
-}
-
-#define ZYD_MAXIM_PHY \
-{ \
- { ZYD_CR23, 0x40 }, { ZYD_CR15, 0x20 }, { ZYD_CR28, 0x3e }, \
- { ZYD_CR29, 0x00 }, { ZYD_CR26, 0x11 }, { ZYD_CR44, 0x33 }, \
- { ZYD_CR106, 0x2a }, { ZYD_CR107, 0x1a }, { ZYD_CR109, 0x2b }, \
- { ZYD_CR110, 0x2b }, { ZYD_CR111, 0x2b }, { ZYD_CR112, 0x2b }, \
- { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \
- { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \
- { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR89, 0x18 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x09 }, \
- { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x13 }, { ZYD_CR112, 0x13 }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0xfa }, \
- { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, { ZYD_CR122, 0xfe }, \
- { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \
- { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \
- { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR89, 0x18 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x13 }, \
- { ZYD_CR110, 0x27 }, { ZYD_CR111, 0x27 }, { ZYD_CR112, 0x13 }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0x00 }, \
- { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x06 }, { ZYD_CR122, 0xfe }, \
- { ZYD_CR150, 0x0d } \
-}
-
-#define ZYD_MAXIM_RF \
-{ \
- 0x00ccd4, 0x030a03, 0x000400, 0x000ca1, 0x010072, 0x018645, \
- 0x004006, 0x0000a7, 0x008258, 0x003fc9, 0x00040a, 0x00000b, \
- 0x00026c \
-}
-
-#define ZYD_MAXIM_CHANTABLE \
-{ \
- { 0x0ccd4, 0x30a03 }, \
- { 0x22224, 0x00a13 }, \
- { 0x37774, 0x10a13 }, \
- { 0x0ccd4, 0x30a13 }, \
- { 0x22224, 0x00a23 }, \
- { 0x37774, 0x10a23 }, \
- { 0x0ccd4, 0x30a23 }, \
- { 0x22224, 0x00a33 }, \
- { 0x37774, 0x10a33 }, \
- { 0x0ccd4, 0x30a33 }, \
- { 0x22224, 0x00a43 }, \
- { 0x37774, 0x10a43 }, \
- { 0x0ccd4, 0x30a43 }, \
- { 0x199a4, 0x20a53 } \
-}
-
-#define ZYD_MAXIM2_PHY \
-{ \
- { ZYD_CR23, 0x40 }, { ZYD_CR15, 0x20 }, { ZYD_CR28, 0x3e }, \
- { ZYD_CR29, 0x00 }, { ZYD_CR26, 0x11 }, { ZYD_CR44, 0x33 }, \
- { ZYD_CR106, 0x2a }, { ZYD_CR107, 0x1a }, { ZYD_CR109, 0x2b }, \
- { ZYD_CR110, 0x2b }, { ZYD_CR111, 0x2b }, { ZYD_CR112, 0x2b }, \
- { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \
- { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \
- { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR89, 0x18 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x09 }, \
- { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x13 }, { ZYD_CR112, 0x13 }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0xfa }, \
- { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, { ZYD_CR122, 0xfe }, \
- { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \
- { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \
- { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR79, 0x58 }, \
- { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR89, 0x18 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x09 }, \
- { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x13 }, { ZYD_CR112, 0x13 }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0x00 }, \
- { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x06 }, { ZYD_CR122, 0xfe } \
-}
-
-#define ZYD_MAXIM2_RF \
-{ \
- 0x33334, 0x10a03, 0x00400, 0x00ca1, 0x10072, 0x18645, 0x04006, \
- 0x000a7, 0x08258, 0x03fc9, 0x0040a, 0x0000b, 0x0026c \
-}
-
-#define ZYD_MAXIM2_CHANTABLE_F \
-{ \
- 0x33334, 0x08884, 0x1ddd4, 0x33334, 0x08884, 0x1ddd4, 0x33334, \
- 0x08884, 0x1ddd4, 0x33334, 0x08884, 0x1ddd4, 0x33334, 0x26664 \
-}
-
-#define ZYD_MAXIM2_CHANTABLE \
-{ \
- { 0x33334, 0x10a03 }, \
- { 0x08884, 0x20a13 }, \
- { 0x1ddd4, 0x30a13 }, \
- { 0x33334, 0x10a13 }, \
- { 0x08884, 0x20a23 }, \
- { 0x1ddd4, 0x30a23 }, \
- { 0x33334, 0x10a23 }, \
- { 0x08884, 0x20a33 }, \
- { 0x1ddd4, 0x30a33 }, \
- { 0x33334, 0x10a33 }, \
- { 0x08884, 0x20a43 }, \
- { 0x1ddd4, 0x30a43 }, \
- { 0x33334, 0x10a43 }, \
- { 0x26664, 0x20a53 } \
-}
-
-/*
- * Control pipe requests.
- */
-#define ZYD_DOWNLOADREQ 0x30
-#define ZYD_DOWNLOADSTS 0x31
-#define ZYD_READFWDATAREQ 0x32
-
-/* possible values for register ZYD_CR_INTERRUPT */
-#define ZYD_HWINT_MASK 0x004f0000
-
-/* possible values for register ZYD_MAC_MISC */
-#define ZYD_UNLOCK_PHY_REGS 0x80
-
-/* possible values for register ZYD_MAC_ENCRYPTION_TYPE */
-#define ZYD_ENC_SNIFFER 8
-
-/* flags for register ZYD_MAC_RXFILTER */
-#define ZYD_FILTER_ASS_REQ (1 << 0)
-#define ZYD_FILTER_ASS_RSP (1 << 1)
-#define ZYD_FILTER_REASS_REQ (1 << 2)
-#define ZYD_FILTER_REASS_RSP (1 << 3)
-#define ZYD_FILTER_PRB_REQ (1 << 4)
-#define ZYD_FILTER_PRB_RSP (1 << 5)
-#define ZYD_FILTER_BCN (1 << 8)
-#define ZYD_FILTER_ATIM (1 << 9)
-#define ZYD_FILTER_DEASS (1 << 10)
-#define ZYD_FILTER_AUTH (1 << 11)
-#define ZYD_FILTER_DEAUTH (1 << 12)
-#define ZYD_FILTER_PS_POLL (1 << 26)
-#define ZYD_FILTER_RTS (1 << 27)
-#define ZYD_FILTER_CTS (1 << 28)
-#define ZYD_FILTER_ACK (1 << 29)
-#define ZYD_FILTER_CFE (1 << 30)
-#define ZYD_FILTER_CFE_A (1 << 31)
-
-/* helpers for register ZYD_MAC_RXFILTER */
-#define ZYD_FILTER_MONITOR 0xffffffff
-#define ZYD_FILTER_BSS \
- (ZYD_FILTER_ASS_REQ | ZYD_FILTER_ASS_RSP | \
- ZYD_FILTER_REASS_REQ | ZYD_FILTER_REASS_RSP | \
- ZYD_FILTER_PRB_REQ | ZYD_FILTER_PRB_RSP | \
- (0x3 << 6) | \
- ZYD_FILTER_BCN | ZYD_FILTER_ATIM | ZYD_FILTER_DEASS | \
- ZYD_FILTER_AUTH | ZYD_FILTER_DEAUTH | \
- (0x7 << 13) | \
- ZYD_FILTER_PS_POLL | ZYD_FILTER_ACK)
-#define ZYD_FILTER_HOSTAP \
- (ZYD_FILTER_ASS_REQ | ZYD_FILTER_REASS_REQ | \
- ZYD_FILTER_PRB_REQ | ZYD_FILTER_DEASS | ZYD_FILTER_AUTH | \
- ZYD_FILTER_DEAUTH | ZYD_FILTER_PS_POLL)
-
-struct zyd_tx_desc {
- uint8_t phy;
-#define ZYD_TX_PHY_SIGNAL(x) ((x) & 0xf)
-#define ZYD_TX_PHY_OFDM (1 << 4)
-#define ZYD_TX_PHY_SHPREAMBLE (1 << 5) /* CCK */
-#define ZYD_TX_PHY_5GHZ (1 << 5) /* OFDM */
- uint16_t len;
- uint8_t flags;
-#define ZYD_TX_FLAG_BACKOFF (1 << 0)
-#define ZYD_TX_FLAG_MULTICAST (1 << 1)
-#define ZYD_TX_FLAG_TYPE(x) (((x) & 0x3) << 2)
-#define ZYD_TX_TYPE_DATA 0
-#define ZYD_TX_TYPE_PS_POLL 1
-#define ZYD_TX_TYPE_MGMT 2
-#define ZYD_TX_TYPE_CTL 3
-#define ZYD_TX_FLAG_WAKEUP (1 << 4)
-#define ZYD_TX_FLAG_RTS (1 << 5)
-#define ZYD_TX_FLAG_ENCRYPT (1 << 6)
-#define ZYD_TX_FLAG_CTS_TO_SELF (1 << 7)
- uint16_t pktlen;
- uint16_t plcp_length;
- uint8_t plcp_service;
-#define ZYD_PLCP_LENGEXT 0x80
- uint16_t nextlen;
-} __packed;
-
-struct zyd_plcphdr {
- uint8_t signal;
- uint8_t reserved[2];
- uint16_t service; /* unaligned! */
-} __packed;
-
-struct zyd_rx_stat {
- uint8_t signal_cck;
- uint8_t rssi;
- uint8_t signal_ofdm;
- uint8_t cipher;
-#define ZYD_RX_CIPHER_WEP64 1
-#define ZYD_RX_CIPHER_TKIP 2
-#define ZYD_RX_CIPHER_AES 4
-#define ZYD_RX_CIPHER_WEP128 5
-#define ZYD_RX_CIPHER_WEP256 6
-#define ZYD_RX_CIPHER_WEP \
- (ZYD_RX_CIPHER_WEP64 | ZYD_RX_CIPHER_WEP128 | ZYD_RX_CIPHER_WEP256)
- uint8_t flags;
-#define ZYD_RX_OFDM (1 << 0)
-#define ZYD_RX_TIMEOUT (1 << 1)
-#define ZYD_RX_OVERRUN (1 << 2)
-#define ZYD_RX_DECRYPTERR (1 << 3)
-#define ZYD_RX_BADCRC32 (1 << 4)
-#define ZYD_RX_NOT2ME (1 << 5)
-#define ZYD_RX_BADCRC16 (1 << 6)
-#define ZYD_RX_ERROR (1 << 7)
-} __packed;
-
-/* this structure may be unaligned */
-struct zyd_rx_desc {
-#define ZYD_MAX_RXFRAMECNT 3
- uWord len[ZYD_MAX_RXFRAMECNT];
- uWord tag;
-#define ZYD_TAG_MULTIFRAME 0x697e
-} __packed;
-
-/* I2C bus alike */
-struct zyd_rfwrite_cmd {
- uint16_t code;
- uint16_t width;
- uint16_t bit[32];
-#define ZYD_RF_IF_LE (1 << 1)
-#define ZYD_RF_CLK (1 << 2)
-#define ZYD_RF_DATA (1 << 3)
-} __packed;
-
-struct zyd_cmd {
- uint16_t code;
-#define ZYD_CMD_IOWR 0x0021 /* write HMAC or PHY register */
-#define ZYD_CMD_IORD 0x0022 /* read HMAC or PHY register */
-#define ZYD_CMD_RFCFG 0x0023 /* write RF register */
-#define ZYD_NOTIF_IORD 0x9001 /* response for ZYD_CMD_IORD */
-#define ZYD_NOTIF_MACINTR 0x9001 /* interrupt notification */
-#define ZYD_NOTIF_RETRYSTATUS 0xa001 /* Tx retry notification */
- uint8_t data[64];
-} __packed;
-
-/* structure for command ZYD_CMD_IOWR */
-struct zyd_pair {
- uint16_t reg;
-/* helpers macros to read/write 32-bit registers */
-#define ZYD_REG32_LO(reg) (reg)
-#define ZYD_REG32_HI(reg) \
- ((reg) + ((((reg) & 0xf000) == 0x9000) ? 2 : 1))
- uint16_t val;
-} __packed;
-
-/* structure for notification ZYD_NOTIF_RETRYSTATUS */
-struct zyd_notif_retry {
- uint16_t rate;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
- uint16_t count;
-} __packed;
-
-#define ZYD_CONFIG_INDEX 0
-#define ZYD_IFACE_INDEX 0
-
-#define ZYD_INTR_TIMEOUT 1000
-#define ZYD_TX_TIMEOUT 10000
-
-#define ZYD_MAX_TXBUFSZ \
- (sizeof(struct zyd_tx_desc) + MCLBYTES)
-#define ZYD_MIN_FRAGSZ \
- (sizeof(struct zyd_plcphdr) + IEEE80211_MIN_LEN + \
- sizeof(struct zyd_rx_stat))
-#define ZYD_MIN_RXBUFSZ ZYD_MIN_FRAGSZ
-#define ZYX_MAX_RXBUFSZ \
- ((sizeof (struct zyd_plcphdr) + IEEE80211_MAX_LEN + \
- sizeof (struct zyd_rx_stat)) * ZYD_MAX_RXFRAMECNT + \
- sizeof (struct zyd_rx_desc))
-#define ZYD_TX_DESC_SIZE (sizeof (struct zyd_tx_desc))
-
-#define ZYD_RX_LIST_CNT 1
-#define ZYD_TX_LIST_CNT 5
-#define ZYD_CMD_FLAG_READ (1 << 0)
-#define ZYD_CMD_FLAG_SENT (1 << 1)
-
-/* quickly determine if a given rate is CCK or OFDM */
-#define ZYD_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
-
-struct zyd_phy_pair {
- uint16_t reg;
- uint8_t val;
-};
-
-struct zyd_mac_pair {
- uint16_t reg;
- uint32_t val;
-};
-
-struct zyd_task {
- struct usb2_proc_msg hdr;
- struct zyd_softc *sc;
-};
-
-struct zyd_tx_data {
- STAILQ_ENTRY(zyd_tx_data) next;
- struct zyd_softc *sc;
- struct zyd_tx_desc desc;
- struct mbuf *m;
- struct ieee80211_node *ni;
- int rate;
-};
-typedef STAILQ_HEAD(, zyd_tx_data) zyd_txdhead;
-
-struct zyd_rx_data {
- struct mbuf *m;
- int rssi;
-};
-
-struct zyd_node {
- struct ieee80211_node ni; /* must be the first */
- struct ieee80211_amrr_node amn;
-};
-#define ZYD_NODE(ni) ((struct zyd_node *)(ni))
-
-struct zyd_rx_radiotap_header {
- struct ieee80211_radiotap_header wr_ihdr;
- uint8_t wr_flags;
- uint8_t wr_rate;
- uint16_t wr_chan_freq;
- uint16_t wr_chan_flags;
- int8_t wr_antsignal;
- int8_t wr_antnoise;
-} __packed;
-
-#define ZYD_RX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
- (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL))
-
-struct zyd_tx_radiotap_header {
- struct ieee80211_radiotap_header wt_ihdr;
- uint8_t wt_flags;
- uint8_t wt_rate;
- uint16_t wt_chan_freq;
- uint16_t wt_chan_flags;
-} __packed;
-
-#define ZYD_TX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL))
-
-struct zyd_softc; /* forward declaration */
-
-struct zyd_rf {
- /* RF methods */
- int (*init)(struct zyd_rf *);
- int (*switch_radio)(struct zyd_rf *, int);
- int (*set_channel)(struct zyd_rf *, uint8_t);
- int (*bandedge6)(struct zyd_rf *,
- struct ieee80211_channel *);
- /* RF attributes */
- struct zyd_softc *rf_sc; /* back-pointer */
- int width;
-};
-
-struct zyd_rq {
- struct zyd_cmd *cmd;
- const uint16_t *idata;
- struct zyd_pair *odata;
- int ilen;
- int olen;
- int flags;
- STAILQ_ENTRY(zyd_rq) rq;
-};
-
-struct zyd_vap {
- struct ieee80211vap vap;
- int (*newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
- struct ieee80211_amrr amrr;
-};
-#define ZYD_VAP(vap) ((struct zyd_vap *)(vap))
-
-enum {
- ZYD_BULK_WR,
- ZYD_BULK_RD,
- ZYD_INTR_WR,
- ZYD_INTR_RD,
- ZYD_N_TRANSFER = 4,
-};
-
-struct zyd_softc {
- struct ifnet *sc_ifp;
- device_t sc_dev;
- struct usb2_device *sc_udev;
- struct usb2_process sc_tq;
-
- struct usb2_xfer *sc_xfer[ZYD_N_TRANSFER];
-
- enum ieee80211_state sc_state;
- int sc_arg;
- int sc_flags;
-#define ZYD_FLAG_FWLOADED (1 << 0)
-#define ZYD_FLAG_INITONCE (1 << 1)
-#define ZYD_FLAG_INITDONE (1 << 2)
- int sc_if_flags;
-
- struct zyd_task sc_synctask[2];
- struct zyd_task sc_mcasttask[2];
- struct zyd_task sc_scantask[2];
- int sc_scan_action;
-#define ZYD_SCAN_START 0
-#define ZYD_SCAN_END 1
-#define ZYD_SET_CHANNEL 2
- struct zyd_task sc_task[2];
-
- struct zyd_rf sc_rf;
-
- STAILQ_HEAD(, zyd_rq) sc_rtx;
- STAILQ_HEAD(, zyd_rq) sc_rqh;
-
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
- uint16_t sc_fwbase;
- uint8_t sc_regdomain;
- uint8_t sc_macrev;
- uint16_t sc_fwrev;
- uint8_t sc_rfrev;
- uint8_t sc_parev;
- uint8_t sc_al2230s;
- uint8_t sc_bandedge6;
- uint8_t sc_newphy;
- uint8_t sc_cckgain;
- uint8_t sc_fix_cr157;
- uint8_t sc_ledtype;
- uint8_t sc_txled;
-
- uint32_t sc_atim_wnd;
- uint32_t sc_pre_tbtt;
- uint32_t sc_bcn_int;
-
- uint8_t sc_pwrcal[14];
- uint8_t sc_pwrint[14];
- uint8_t sc_ofdm36_cal[14];
- uint8_t sc_ofdm48_cal[14];
- uint8_t sc_ofdm54_cal[14];
-
- struct mtx sc_mtx;
- struct cv sc_intr_cv;
- struct zyd_tx_data tx_data[ZYD_TX_LIST_CNT];
- zyd_txdhead tx_q;
- zyd_txdhead tx_free;
- int tx_nfree;
- struct zyd_rx_desc sc_rx_desc;
- struct zyd_rx_data sc_rx_data[ZYD_MAX_RXFRAMECNT];
- int sc_rx_count;
-
- struct zyd_cmd sc_ibuf;
-
- struct zyd_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
- struct zyd_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
-};
-
-#define ZYD_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
-#define ZYD_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
-#define ZYD_LOCK_ASSERT(sc, t) mtx_assert(&(sc)->sc_mtx, t)
-
diff --git a/sys/dev/usb2/wlan/usb2_wlan.c b/sys/dev/usb2/wlan/usb2_wlan.c
deleted file mode 100644
index 35c9cbb..0000000
--- a/sys/dev/usb2/wlan/usb2_wlan.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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 <dev/usb2/core/usb2_core.h>
-#include <dev/usb2/wlan/usb2_wlan.h>
-
-MODULE_VERSION(usb2_wlan, 1);
-MODULE_DEPEND(usb2_wlan, usb2_core, 1, 1, 1);
diff --git a/sys/dev/usb2/wlan/usb2_wlan.h b/sys/dev/usb2/wlan/usb2_wlan.h
deleted file mode 100644
index 9db120e..0000000
--- a/sys/dev/usb2/wlan/usb2_wlan.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2008 Hans Petter Selasky. 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.
- */
-
-#ifndef _USB2_WLAN_H_
-#define _USB2_WLAN_H_
-
-#include <sys/param.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-#include <net/if_clone.h>
-
-#include <net80211/ieee80211_var.h>
-#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_regdomain.h>
-#include <net80211/ieee80211_phy.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-
-#endif /* _USB2_WLAN_H_ */
OpenPOWER on IntegriCloud