[Midnightbsd-cvs] src: dev/usb: merge enhancements
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat Nov 29 11:16:10 EST 2008
Log Message:
-----------
merge enhancements
Modified Files:
--------------
src/sys/dev/usb:
if_aue.c (r1.2 -> r1.3)
if_ural.c (r1.3 -> r1.4)
ohci.c (r1.4 -> r1.5)
umass.c (r1.2 -> r1.3)
-------------- next part --------------
Index: if_aue.c
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/if_aue.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/usb/if_aue.c -L sys/dev/usb/if_aue.c -u -r1.2 -r1.3
--- sys/dev/usb/if_aue.c
+++ sys/dev/usb/if_aue.c
@@ -2,6 +2,9 @@
* Copyright (c) 1997, 1998, 1999, 2000
* Bill Paul <wpaul at ee.columbia.edu>. All rights reserved.
*
+ * Copyright (c) 2006
+ * Alfred Perlstein <alfred at 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:
@@ -31,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/usb/if_aue.c,v 1.90.2.3 2005/10/09 03:59:36 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/usb/if_aue.c,v 1.117 2007/06/23 05:59:53 imp Exp $");
/*
* ADMtek AN986 Pegasus and AN8511 Pegasus II USB to ethernet driver.
@@ -40,6 +43,9 @@
* Written by Bill Paul <wpaul at ee.columbia.edu>
* Electrical Engineering Department
* Columbia University, New York City
+ *
+ * SMP locking by Alfred Perlstein <alfred at freebsd.org>.
+ * RED Inc.
*/
/*
@@ -68,8 +74,12 @@
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
+#include <sys/kdb.h>
+#include <sys/lock.h>
#include <sys/module.h>
#include <sys/socket.h>
+#include <sys/sx.h>
+#include <sys/taskqueue.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -82,9 +92,6 @@
#include <sys/bus.h>
#include <machine/bus.h>
-#if __FreeBSD_version < 500000
-#include <machine/clock.h>
-#endif
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -102,7 +109,7 @@
MODULE_DEPEND(aue, ether, 1, 1, 1);
MODULE_DEPEND(aue, miibus, 1, 1, 1);
-/* "controller miibus0" required. See GENERIC if you get errors here. */
+/* "device miibus" required. See GENERIC if you get errors here. */
#include "miibus_if.h"
/*
@@ -116,7 +123,7 @@
#define PII 0x0004 /* Pegasus II chip */
};
-Static const struct aue_type aue_devs[] = {
+static const struct aue_type aue_devs[] = {
{{ USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460B}, PII },
{{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1}, PNA|PII },
{{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX2}, PII },
@@ -134,6 +141,11 @@
{{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS}, PNA },
{{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII}, PII },
{{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_2}, PII },
+ {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_3}, PII },
+ {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_4}, PII },
+ {{ USB_VENDOR_AEI, USB_PRODUCT_AEI_FASTETHERNET}, PII },
+ {{ USB_VENDOR_ALLIEDTELESYN, USB_PRODUCT_ALLIEDTELESYN_ATUSB100}, PII },
+ {{ USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC110T}, PII },
{{ USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2LAN}, PII },
{{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100}, 0 },
{{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBLP100}, PNA },
@@ -148,12 +160,15 @@
{{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX3}, LSYS|PII },
{{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX2}, LSYS|PII },
{{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650}, LSYS },
+ {{ USB_VENDOR_ELCON, USB_PRODUCT_ELCON_PLAN}, PNA|PII },
+ {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSB20}, PII },
{{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX0}, 0 },
{{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX1}, LSYS },
{{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2}, 0 },
{{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX3}, LSYS },
{{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBLTX}, PII },
{{ USB_VENDOR_ELSA, USB_PRODUCT_ELSA_USB2ETHERNET}, 0 },
+ {{ USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNBR402W}, 0 },
{{ USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100}, PII },
{{ USB_VENDOR_HP, USB_PRODUCT_HP_HN210E}, PII },
{{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX}, 0 },
@@ -165,55 +180,65 @@
{{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100H1}, LSYS|PNA },
{{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TA}, LSYS },
{{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX2}, LSYS|PII },
- {{ USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110}, PII },
{{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1}, 0 },
{{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX5}, 0 },
{{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUA2TX5}, PII },
+ {{ USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110}, PII },
+ {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA101}, PII },
{{ USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM}, PII },
+ {{ USB_VENDOR_SIIG2, USB_PRODUCT_SIIG2_USBTOETHER}, PII },
{{ USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTNIC},PII },
{{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB}, 0 },
{{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2206USB}, PII },
{{ USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100}, 0 },
+ {{ USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB110}, PII },
};
#define aue_lookup(v, p) ((const struct aue_type *)usb_lookup(aue_devs, v, p))
-Static int aue_match(device_ptr_t);
-Static int aue_attach(device_ptr_t);
-Static int aue_detach(device_ptr_t);
+static device_probe_t aue_match;
+static device_attach_t aue_attach;
+static device_detach_t aue_detach;
+static device_shutdown_t aue_shutdown;
+static miibus_readreg_t aue_miibus_readreg;
+static miibus_writereg_t aue_miibus_writereg;
+static miibus_statchg_t aue_miibus_statchg;
-Static void aue_reset_pegasus_II(struct aue_softc *sc);
-Static int aue_encap(struct aue_softc *, struct mbuf *, int);
+static void aue_reset_pegasus_II(struct aue_softc *sc);
+static int aue_encap(struct aue_softc *, struct mbuf *, int);
#ifdef AUE_INTR_PIPE
-Static void aue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
+static void aue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
#endif
-Static void aue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-Static void aue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-Static void aue_tick(void *);
-Static void aue_rxstart(struct ifnet *);
-Static void aue_start(struct ifnet *);
-Static int aue_ioctl(struct ifnet *, u_long, caddr_t);
-Static void aue_init(void *);
-Static void aue_stop(struct aue_softc *);
-Static void aue_watchdog(struct ifnet *);
-Static void aue_shutdown(device_ptr_t);
-Static int aue_ifmedia_upd(struct ifnet *);
-Static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-
-Static void aue_eeprom_getword(struct aue_softc *, int, u_int16_t *);
-Static void aue_read_eeprom(struct aue_softc *, caddr_t, int, int, int);
-Static int aue_miibus_readreg(device_ptr_t, int, int);
-Static int aue_miibus_writereg(device_ptr_t, int, int, int);
-Static void aue_miibus_statchg(device_ptr_t);
-
-Static void aue_setmulti(struct aue_softc *);
-Static void aue_reset(struct aue_softc *);
-
-Static int aue_csr_read_1(struct aue_softc *, int);
-Static int aue_csr_write_1(struct aue_softc *, int, int);
-Static int aue_csr_read_2(struct aue_softc *, int);
-Static int aue_csr_write_2(struct aue_softc *, int, int);
+static void aue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
+static void aue_rxeof_thread(struct aue_softc *sc);
+static void aue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
+static void aue_txeof_thread(struct aue_softc *);
+static void aue_task_sched(struct aue_softc *, int);
+static void aue_task(void *xsc, int pending);
+static void aue_tick(void *);
+static void aue_rxstart(struct ifnet *);
+static void aue_rxstart_thread(struct aue_softc *);
+static void aue_start(struct ifnet *);
+static void aue_start_thread(struct aue_softc *);
+static int aue_ioctl(struct ifnet *, u_long, caddr_t);
+static void aue_init(void *);
+static void aue_init_body(struct aue_softc *);
+static void aue_stop(struct aue_softc *);
+static void aue_watchdog(struct aue_softc *);
+static int aue_ifmedia_upd(struct ifnet *);
+static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+
+static void aue_eeprom_getword(struct aue_softc *, int, u_int16_t *);
+static void aue_read_eeprom(struct aue_softc *, caddr_t, int, int, int);
+
+static void aue_setmulti(struct aue_softc *);
+static void aue_reset(struct aue_softc *);
+
+static int aue_csr_read_1(struct aue_softc *, int);
+static int aue_csr_write_1(struct aue_softc *, int, int);
+static int aue_csr_read_2(struct aue_softc *, int);
+static int aue_csr_write_2(struct aue_softc *, int, int);
-Static device_method_t aue_methods[] = {
+static device_method_t aue_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, aue_match),
DEVMETHOD(device_attach, aue_attach),
@@ -232,13 +257,13 @@
{ 0, 0 }
};
-Static driver_t aue_driver = {
+static driver_t aue_driver = {
"aue",
aue_methods,
sizeof(struct aue_softc)
};
-Static devclass_t aue_devclass;
+static devclass_t aue_devclass;
DRIVER_MODULE(aue, uhub, aue_driver, aue_devclass, usbd_driver_load, 0);
DRIVER_MODULE(miibus, aue, miibus_driver, miibus_devclass, 0, 0);
@@ -249,17 +274,14 @@
#define AUE_CLRBIT(sc, reg, x) \
aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x))
-Static int
+static int
aue_csr_read_1(struct aue_softc *sc, int reg)
{
usb_device_request_t req;
usbd_status err;
u_int8_t val = 0;
- if (sc->aue_dying)
- return (0);
-
- AUE_LOCK(sc);
+ AUE_SXASSERTLOCKED(sc);
req.bmRequestType = UT_READ_VENDOR_DEVICE;
req.bRequest = AUE_UR_READREG;
@@ -269,8 +291,6 @@
err = usbd_do_request(sc->aue_udev, &req, &val);
- AUE_UNLOCK(sc);
-
if (err) {
return (0);
}
@@ -278,17 +298,14 @@
return (val);
}
-Static int
+static int
aue_csr_read_2(struct aue_softc *sc, int reg)
{
usb_device_request_t req;
usbd_status err;
u_int16_t val = 0;
- if (sc->aue_dying)
- return (0);
-
- AUE_LOCK(sc);
+ AUE_SXASSERTLOCKED(sc);
req.bmRequestType = UT_READ_VENDOR_DEVICE;
req.bRequest = AUE_UR_READREG;
@@ -298,8 +315,6 @@
err = usbd_do_request(sc->aue_udev, &req, &val);
- AUE_UNLOCK(sc);
-
if (err) {
return (0);
}
@@ -307,16 +322,13 @@
return (val);
}
-Static int
+static int
aue_csr_write_1(struct aue_softc *sc, int reg, int val)
{
usb_device_request_t req;
usbd_status err;
- if (sc->aue_dying)
- return (0);
-
- AUE_LOCK(sc);
+ AUE_SXASSERTLOCKED(sc);
req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
req.bRequest = AUE_UR_WRITEREG;
@@ -326,8 +338,6 @@
err = usbd_do_request(sc->aue_udev, &req, &val);
- AUE_UNLOCK(sc);
-
if (err) {
return (-1);
}
@@ -335,16 +345,13 @@
return (0);
}
-Static int
+static int
aue_csr_write_2(struct aue_softc *sc, int reg, int val)
{
usb_device_request_t req;
usbd_status err;
- if (sc->aue_dying)
- return (0);
-
- AUE_LOCK(sc);
+ AUE_SXASSERTLOCKED(sc);
req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
req.bRequest = AUE_UR_WRITEREG;
@@ -354,8 +361,6 @@
err = usbd_do_request(sc->aue_udev, &req, &val);
- AUE_UNLOCK(sc);
-
if (err) {
return (-1);
}
@@ -366,7 +371,7 @@
/*
* Read a word of data stored in the EEPROM at address 'addr.'
*/
-Static void
+static void
aue_eeprom_getword(struct aue_softc *sc, int addr, u_int16_t *dest)
{
int i;
@@ -394,7 +399,7 @@
/*
* Read a sequence of words from the EEPROM.
*/
-Static void
+static void
aue_read_eeprom(struct aue_softc *sc, caddr_t dest, int off, int cnt, int swap)
{
int i;
@@ -412,10 +417,10 @@
return;
}
-Static int
-aue_miibus_readreg(device_ptr_t dev, int phy, int reg)
+static int
+aue_miibus_readreg(device_t dev, int phy, int reg)
{
- struct aue_softc *sc = USBGETSOFTC(dev);
+ struct aue_softc *sc = device_get_softc(dev);
int i;
u_int16_t val = 0;
@@ -456,10 +461,10 @@
return (val);
}
-Static int
-aue_miibus_writereg(device_ptr_t dev, int phy, int reg, int data)
+static int
+aue_miibus_writereg(device_t dev, int phy, int reg, int data)
{
- struct aue_softc *sc = USBGETSOFTC(dev);
+ struct aue_softc *sc = device_get_softc(dev);
int i;
if (phy == 3)
@@ -482,10 +487,10 @@
return(0);
}
-Static void
-aue_miibus_statchg(device_ptr_t dev)
+static void
+aue_miibus_statchg(device_t dev)
{
- struct aue_softc *sc = USBGETSOFTC(dev);
+ struct aue_softc *sc = device_get_softc(dev);
struct mii_data *mii = GET_MII(sc);
AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
@@ -518,13 +523,15 @@
#define AUE_BITS 6
-Static void
+static void
aue_setmulti(struct aue_softc *sc)
{
struct ifnet *ifp;
struct ifmultiaddr *ifma;
u_int32_t h = 0, i;
+ u_int8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ AUE_SXASSERTLOCKED(sc);
ifp = sc->aue_ifp;
if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
@@ -534,30 +541,26 @@
AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
- /* first, zot all the existing hash bits */
- for (i = 0; i < 8; i++)
- aue_csr_write_1(sc, AUE_MAR0 + i, 0);
-
/* now program new ones */
IF_ADDR_LOCK(ifp);
-#if __FreeBSD_version >= 500000
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
-#else
- LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
-#endif
{
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);
- AUE_SETBIT(sc, AUE_MAR + (h >> 3), 1 << (h & 0x7));
+ hashtbl[(h >> 3)] |= 1 << (h & 0x7);
}
IF_ADDR_UNLOCK(ifp);
+ /* write the hashtable */
+ for (i = 0; i < 8; i++)
+ aue_csr_write_1(sc, AUE_MAR0 + i, hashtbl[i]);
+
return;
}
-Static void
+static void
aue_reset_pegasus_II(struct aue_softc *sc)
{
/* Magic constants taken from Linux driver. */
@@ -571,11 +574,12 @@
aue_csr_write_1(sc, AUE_REG_81, 2);
}
-Static void
+static void
aue_reset(struct aue_softc *sc)
{
int i;
+ AUE_SXASSERTLOCKED(sc);
AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC);
for (i = 0; i < AUE_TIMEOUT; i++) {
@@ -618,9 +622,10 @@
/*
* Probe for a Pegasus chip.
*/
-USB_MATCH(aue)
+static int
+aue_match(device_t self)
{
- USB_MATCH_START(aue, uaa);
+ struct usb_attach_arg *uaa = device_get_ivars(self);
if (uaa->iface != NULL)
return (UMATCH_NONE);
@@ -633,10 +638,11 @@
* Attach the interface. Allocate softc structures, do ifmedia
* setup and ethernet/BPF attach.
*/
-USB_ATTACH(aue)
+static int
+aue_attach(device_t self)
{
- USB_ATTACH_START(aue, sc, uaa);
- char devinfo[1024];
+ struct aue_softc *sc = device_get_softc(self);
+ struct usb_attach_arg *uaa = device_get_ivars(self);
u_char eaddr[ETHER_ADDR_LEN];
struct ifnet *ifp;
usbd_interface_handle iface;
@@ -645,25 +651,19 @@
usb_endpoint_descriptor_t *ed;
int i;
- bzero(sc, sizeof(struct aue_softc));
-
- usbd_devinfo(uaa->device, 0, devinfo);
-
sc->aue_dev = self;
sc->aue_udev = uaa->device;
sc->aue_unit = device_get_unit(self);
if (usbd_set_config_no(sc->aue_udev, AUE_CONFIG_NO, 0)) {
- printf("aue%d: getting interface handle failed\n",
- sc->aue_unit);
- USB_ATTACH_ERROR_RETURN;
+ device_printf(self, "getting interface handle failed\n");
+ return ENXIO;
}
err = usbd_device2interface_handle(uaa->device, AUE_IFACE_IDX, &iface);
if (err) {
- printf("aue%d: getting interface handle failed\n",
- sc->aue_unit);
- USB_ATTACH_ERROR_RETURN;
+ device_printf(self, "getting interface handle failed\n");
+ return ENXIO;
}
sc->aue_iface = iface;
@@ -674,17 +674,12 @@
id = usbd_get_interface_descriptor(sc->aue_iface);
- usbd_devinfo(uaa->device, 0, devinfo);
- device_set_desc_copy(self, devinfo);
- printf("%s: %s\n", USBDEVNAME(self), devinfo);
-
/* Find endpoints. */
for (i = 0; i < id->bNumEndpoints; i++) {
ed = usbd_interface2endpoint_descriptor(iface, i);
if (ed == NULL) {
- printf("aue%d: couldn't get ep %d\n",
- sc->aue_unit, i);
- USB_ATTACH_ERROR_RETURN;
+ device_printf(self, "couldn't get ep %d\n", i);
+ return ENXIO;
}
if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
@@ -698,11 +693,12 @@
}
}
-#if __FreeBSD_version >= 500000
mtx_init(&sc->aue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
-#endif
- AUE_LOCK(sc);
+ sx_init(&sc->aue_sx, device_get_nameunit(self));
+ TASK_INIT(&sc->aue_task, 0, aue_task, sc);
+ usb_ether_task_init(self, 0, &sc->aue_taskqueue);
+ AUE_SXLOCK(sc);
/* Reset the adapter. */
aue_reset(sc);
@@ -714,23 +710,23 @@
ifp = sc->aue_ifp = if_alloc(IFT_ETHER);
if (ifp == NULL) {
- printf("aue%d: can not if_alloc()\n", sc->aue_unit);
- AUE_UNLOCK(sc);
-#if __FreeBSD_version >= 500000
+ device_printf(self, "can not if_alloc()\n");
+ AUE_SXUNLOCK(sc);
mtx_destroy(&sc->aue_mtx);
-#endif
- USB_ATTACH_ERROR_RETURN;
+ sx_destroy(&sc->aue_sx);
+ usb_ether_task_destroy(&sc->aue_taskqueue);
+ return ENXIO;
}
ifp->if_softc = sc;
if_initname(ifp, "aue", sc->aue_unit);
ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = aue_ioctl;
ifp->if_start = aue_start;
- ifp->if_watchdog = aue_watchdog;
ifp->if_init = aue_init;
- ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
+ IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+ ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
+ IFQ_SET_READY(&ifp->if_snd);
/*
* Do MII setup.
@@ -747,13 +743,13 @@
*/
if (mii_phy_probe(self, &sc->aue_miibus,
aue_ifmedia_upd, aue_ifmedia_sts)) {
- printf("aue%d: MII without any PHY!\n", sc->aue_unit);
+ device_printf(self, "MII without any PHY!\n");
if_free(ifp);
- AUE_UNLOCK(sc);
-#if __FreeBSD_version >= 500000
+ AUE_SXUNLOCK(sc);
mtx_destroy(&sc->aue_mtx);
-#endif
- USB_ATTACH_ERROR_RETURN;
+ sx_destroy(&sc->aue_sx);
+ usb_ether_task_destroy(&sc->aue_taskqueue);
+ return ENXIO;
}
sc->aue_qdat.ifp = ifp;
@@ -762,37 +758,31 @@
/*
* Call MI attach routine.
*/
-#if __FreeBSD_version >= 500000
ether_ifattach(ifp, eaddr);
-#else
- ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
-#endif
- callout_handle_init(&sc->aue_stat_ch);
usb_register_netisr();
sc->aue_dying = 0;
+ sc->aue_link = 1;
- AUE_UNLOCK(sc);
- USB_ATTACH_SUCCESS_RETURN;
+ AUE_SXUNLOCK(sc);
+ return 0;
}
-Static int
-aue_detach(device_ptr_t dev)
+static int
+aue_detach(device_t dev)
{
struct aue_softc *sc;
struct ifnet *ifp;
sc = device_get_softc(dev);
- AUE_LOCK(sc);
+ AUE_SXLOCK(sc);
ifp = sc->aue_ifp;
-
- sc->aue_dying = 1;
- untimeout(aue_tick, sc, sc->aue_stat_ch);
-#if __FreeBSD_version >= 500000
ether_ifdetach(ifp);
+ sc->aue_dying = 1;
+ AUE_SXUNLOCK(sc);
+ callout_drain(&sc->aue_tick_callout);
+ usb_ether_task_drain(&sc->aue_taskqueue, &sc->aue_task);
+ usb_ether_task_destroy(&sc->aue_taskqueue);
if_free(ifp);
-#else
- ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
-#endif
if (sc->aue_ep[AUE_ENDPT_TX] != NULL)
usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_TX]);
@@ -803,70 +793,35 @@
usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]);
#endif
- AUE_UNLOCK(sc);
-#if __FreeBSD_version >= 500000
mtx_destroy(&sc->aue_mtx);
-#endif
+ sx_destroy(&sc->aue_sx);
return (0);
}
-#ifdef AUE_INTR_PIPE
-Static void
-aue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
+static void
+aue_rxstart(struct ifnet *ifp)
{
- struct aue_softc *sc = priv;
- struct ifnet *ifp;
- struct aue_intrpkt *p;
-
- AUE_LOCK(sc);
- ifp = sc->aue_ifp;
-
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- AUE_UNLOCK(sc);
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- AUE_UNLOCK(sc);
- return;
- }
- printf("aue%d: usb error on intr: %s\n", sc->aue_unit,
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);
- AUE_UNLOCK(sc);
- return;
- }
-
- usbd_get_xfer_status(xfer, NULL, (void **)&p, NULL, NULL);
-
- if (p->aue_txstat0)
- ifp->if_oerrors++;
-
- if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL & AUE_TXSTAT0_EXCESSCOLL))
- ifp->if_collisions++;
-
- AUE_UNLOCK(sc);
- return;
+ struct aue_softc *sc = ifp->if_softc;
+ aue_task_sched(sc, AUE_TASK_RXSTART);
}
-#endif
-Static void
-aue_rxstart(struct ifnet *ifp)
+static void
+aue_rxstart_thread(struct aue_softc *sc)
{
- struct aue_softc *sc;
struct ue_chain *c;
+ struct ifnet *ifp;
+
+ ifp = sc->aue_ifp;
sc = ifp->if_softc;
- AUE_LOCK(sc);
+ AUE_SXASSERTLOCKED(sc);
c = &sc->aue_cdata.ue_rx_chain[sc->aue_cdata.ue_rx_prod];
c->ue_mbuf = usb_ether_newbuf();
if (c->ue_mbuf == NULL) {
- printf("%s: no memory for rx list "
- "-- packet dropped!\n", USBDEVNAME(sc->aue_dev));
+ device_printf(sc->aue_dev, "no memory for rx list -- packet "
+ "dropped!\n");
ifp->if_ierrors++;
AUE_UNLOCK(sc);
return;
@@ -878,7 +833,6 @@
USBD_NO_TIMEOUT, aue_rxeof);
usbd_transfer(c->ue_xfer);
- AUE_UNLOCK(sc);
return;
}
@@ -886,40 +840,45 @@
* A frame has been uploaded: pass the resulting mbuf chain up to
* the higher level protocols.
*/
-Static void
+static void
aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct ue_chain *c = priv;
- struct aue_softc *sc = c->ue_sc;
+ c->ue_status = status;
+ aue_task_sched(c->ue_sc, AUE_TASK_RXEOF);
+}
+
+static void
+aue_rxeof_thread(struct aue_softc *sc)
+{
+ struct ue_chain *c = &(sc->aue_cdata.ue_rx_chain[0]);
struct mbuf *m;
struct ifnet *ifp;
int total_len = 0;
struct aue_rxpkt r;
+ usbd_status status = c->ue_status;
- if (sc->aue_dying)
- return;
- AUE_LOCK(sc);
+
+ AUE_SXASSERTLOCKED(sc);
ifp = sc->aue_ifp;
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- AUE_UNLOCK(sc);
return;
}
if (status != USBD_NORMAL_COMPLETION) {
if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- AUE_UNLOCK(sc);
return;
}
if (usbd_ratecheck(&sc->aue_rx_notice))
- printf("aue%d: usb error on rx: %s\n", sc->aue_unit,
+ device_printf(sc->aue_dev, "usb error on rx: %s\n",
usbd_errstr(status));
if (status == USBD_STALLED)
usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);
goto done;
}
- usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
+ usbd_get_xfer_status(c->ue_xfer, NULL, NULL, &total_len, NULL);
if (total_len <= 4 + ETHER_CRC_LEN) {
ifp->if_ierrors++;
@@ -946,17 +905,15 @@
/* Put the packet on the special USB input queue. */
usb_ether_input(m);
- AUE_UNLOCK(sc);
return;
done:
/* Setup new transfer. */
- usbd_setup_xfer(xfer, sc->aue_ep[AUE_ENDPT_RX],
+ usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, aue_rxeof);
- usbd_transfer(xfer);
+ usbd_transfer(c->ue_xfer);
- AUE_UNLOCK(sc);
return;
}
@@ -965,31 +922,37 @@
* the list buffers.
*/
-Static void
+static void
aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct ue_chain *c = priv;
- struct aue_softc *sc = c->ue_sc;
+ c->ue_status = status;
+ aue_task_sched(c->ue_sc, AUE_TASK_TXEOF);
+}
+
+static void
+aue_txeof_thread(struct aue_softc *sc)
+{
+ struct ue_chain *c = &(sc->aue_cdata.ue_tx_chain[0]);
struct ifnet *ifp;
- usbd_status err;
+ usbd_status err, status;
- AUE_LOCK(sc);
+ AUE_SXASSERTLOCKED(sc);
+ status = c->ue_status;
ifp = sc->aue_ifp;
if (status != USBD_NORMAL_COMPLETION) {
if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- AUE_UNLOCK(sc);
return;
}
- printf("aue%d: usb error on tx: %s\n", sc->aue_unit,
+ device_printf(sc->aue_dev, "usb error on tx: %s\n",
usbd_errstr(status));
if (status == USBD_STALLED)
usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_TX]);
- AUE_UNLOCK(sc);
return;
}
- ifp->if_timer = 0;
+ sc->aue_timer = 0;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
@@ -1004,52 +967,62 @@
else
ifp->if_opackets++;
- AUE_UNLOCK(sc);
-
return;
}
-Static void
+static void
aue_tick(void *xsc)
{
struct aue_softc *sc = xsc;
+
+ aue_task_sched(sc, AUE_TASK_TICK);
+}
+
+static void
+aue_tick_thread(struct aue_softc *sc)
+{
struct ifnet *ifp;
struct mii_data *mii;
- if (sc == NULL)
+ AUE_SXASSERTLOCKED(sc);
+ ifp = sc->aue_ifp;
+ /*
+ * If a timer is set (non-zero) then decrement it
+ * and if it hits zero, then call the watchdog routine.
+ */
+ if (sc->aue_timer != 0 && --sc->aue_timer == 0) {
+ aue_watchdog(sc);
+ }
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
return;
+ }
- AUE_LOCK(sc);
-
- ifp = sc->aue_ifp;
mii = GET_MII(sc);
if (mii == NULL) {
- AUE_UNLOCK(sc);
- return;
+ goto resched;
}
mii_tick(mii);
if (!sc->aue_link && mii->mii_media_status & IFM_ACTIVE &&
IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
sc->aue_link++;
- if (ifp->if_snd.ifq_head != NULL)
- aue_start(ifp);
+ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ aue_start_thread(sc);
}
-
- sc->aue_stat_ch = timeout(aue_tick, sc, hz);
-
- AUE_UNLOCK(sc);
-
+resched:
+ (void) callout_reset(&sc->aue_tick_callout, hz, aue_tick, sc);
return;
}
-Static int
+static int
aue_encap(struct aue_softc *sc, struct mbuf *m, int idx)
{
int total_len;
struct ue_chain *c;
usbd_status err;
+ AUE_SXASSERTLOCKED(sc);
+
c = &sc->aue_cdata.ue_tx_chain[idx];
/*
@@ -1086,34 +1059,38 @@
return (0);
}
-Static void
+
+static void
aue_start(struct ifnet *ifp)
{
struct aue_softc *sc = ifp->if_softc;
+ aue_task_sched(sc, AUE_TASK_START);
+}
+
+static void
+aue_start_thread(struct aue_softc *sc)
+{
+ struct ifnet *ifp = sc->aue_ifp;
struct mbuf *m_head = NULL;
- AUE_LOCK(sc);
+ AUE_SXASSERTLOCKED(sc);
if (!sc->aue_link) {
- AUE_UNLOCK(sc);
return;
}
if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
- AUE_UNLOCK(sc);
return;
}
- IF_DEQUEUE(&ifp->if_snd, m_head);
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
if (m_head == NULL) {
- AUE_UNLOCK(sc);
return;
}
if (aue_encap(sc, m_head, 0)) {
- IF_PREPEND(&ifp->if_snd, m_head);
+ IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- AUE_UNLOCK(sc);
return;
}
@@ -1128,26 +1105,33 @@
/*
* Set a timeout in case the chip goes out to lunch.
*/
- ifp->if_timer = 5;
- AUE_UNLOCK(sc);
+ sc->aue_timer = 5;
return;
}
-Static void
+static void
aue_init(void *xsc)
{
struct aue_softc *sc = xsc;
+
+ AUE_SXLOCK(sc);
+ aue_init_body(sc);
+ AUE_SXUNLOCK(sc);
+}
+
+static void
+aue_init_body(struct aue_softc *sc)
+{
struct ifnet *ifp = sc->aue_ifp;
struct mii_data *mii = GET_MII(sc);
struct ue_chain *c;
usbd_status err;
int i;
- AUE_LOCK(sc);
+ AUE_SXASSERTLOCKED(sc);
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- AUE_UNLOCK(sc);
return;
}
@@ -1158,7 +1142,7 @@
/* Set MAC address */
for (i = 0; i < ETHER_ADDR_LEN; i++)
- aue_csr_write_1(sc, AUE_PAR0 + i, IFP2ENADDR(sc->aue_ifp)[i]);
+ aue_csr_write_1(sc, AUE_PAR0 + i, IF_LLADDR(sc->aue_ifp)[i]);
/* If we want promiscuous mode, set the allframes bit. */
if (ifp->if_flags & IFF_PROMISC)
@@ -1169,22 +1153,17 @@
/* Init TX ring. */
if (usb_ether_tx_list_init(sc, &sc->aue_cdata,
sc->aue_udev) == ENOBUFS) {
- printf("aue%d: tx list init failed\n", sc->aue_unit);
- AUE_UNLOCK(sc);
+ device_printf(sc->aue_dev, "tx list init failed\n");
return;
}
/* Init RX ring. */
if (usb_ether_rx_list_init(sc, &sc->aue_cdata,
sc->aue_udev) == ENOBUFS) {
- printf("aue%d: rx list init failed\n", sc->aue_unit);
- AUE_UNLOCK(sc);
+ device_printf(sc->aue_dev, "rx list init failed\n");
return;
}
-#ifdef AUE_INTR_PIPE
- sc->aue_cdata.ue_ibuf = malloc(AUE_INTR_PKTLEN, M_USBDEV, M_NOWAIT);
-#endif
/* Load the multicast filter. */
aue_setmulti(sc);
@@ -1200,32 +1179,18 @@
err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_RX],
USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_RX]);
if (err) {
- printf("aue%d: open rx pipe failed: %s\n",
- sc->aue_unit, usbd_errstr(err));
- AUE_UNLOCK(sc);
+ device_printf(sc->aue_dev, "open rx pipe failed: %s\n",
+ usbd_errstr(err));
return;
}
err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_TX],
USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_TX]);
if (err) {
- printf("aue%d: open tx pipe failed: %s\n",
- sc->aue_unit, usbd_errstr(err));
- AUE_UNLOCK(sc);
+ device_printf(sc->aue_dev, "open tx pipe failed: %s\n",
+ usbd_errstr(err));
return;
}
-#ifdef AUE_INTR_PIPE
- err = usbd_open_pipe_intr(sc->aue_iface, sc->aue_ed[AUE_ENDPT_INTR],
- USBD_SHORT_XFER_OK, &sc->aue_ep[AUE_ENDPT_INTR], sc,
- sc->aue_cdata.ue_ibuf, AUE_INTR_PKTLEN, aue_intr,
- AUE_INTR_INTERVAL);
- if (err) {
- printf("aue%d: open intr pipe failed: %s\n",
- sc->aue_unit, usbd_errstr(err));
- AUE_UNLOCK(sc);
- return;
- }
-#endif
/* Start up the receive pipe. */
for (i = 0; i < UE_RX_LIST_CNT; i++) {
@@ -1239,17 +1204,15 @@
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- sc->aue_stat_ch = timeout(aue_tick, sc, hz);
-
- AUE_UNLOCK(sc);
-
+ callout_init(&sc->aue_tick_callout, 1);
+ (void) callout_reset(&sc->aue_tick_callout, hz, aue_tick, sc);
return;
}
/*
* Set media options.
*/
-Static int
+static int
aue_ifmedia_upd(struct ifnet *ifp)
{
struct aue_softc *sc = ifp->if_softc;
@@ -1262,6 +1225,7 @@
mii_phy_reset(miisc);
}
mii_mediachg(mii);
+ sc->aue_link = 1;
return (0);
}
@@ -1269,7 +1233,7 @@
/*
* Report current media status.
*/
-Static void
+static void
aue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
{
struct aue_softc *sc = ifp->if_softc;
@@ -1282,7 +1246,7 @@
return;
}
-Static int
+static int
aue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
{
struct aue_softc *sc = ifp->if_softc;
@@ -1290,10 +1254,18 @@
struct mii_data *mii;
int error = 0;
- AUE_LOCK(sc);
+ /*
+ * This prevents recursion in the interface while it's
+ * being torn down.
+ */
+ if (sc->aue_dying)
+ return(0);
+
+ AUE_GIANTLOCK();
switch(command) {
case SIOCSIFFLAGS:
+ AUE_SXLOCK(sc);
if (ifp->if_flags & IFF_UP) {
if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
ifp->if_flags & IFF_PROMISC &&
@@ -1303,54 +1275,58 @@
!(ifp->if_flags & IFF_PROMISC) &&
sc->aue_if_flags & IFF_PROMISC) {
AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
- } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- aue_init(sc);
+ } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ aue_init_body(sc);
+ }
+ sc->aue_dying = 0;
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
aue_stop(sc);
}
sc->aue_if_flags = ifp->if_flags;
- error = 0;
+ AUE_SXUNLOCK(sc);
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
+ AUE_SXLOCK(sc);
aue_setmulti(sc);
- error = 0;
+ AUE_SXUNLOCK(sc);
break;
case SIOCGIFMEDIA:
case SIOCSIFMEDIA:
+ AUE_SXLOCK(sc);
mii = GET_MII(sc);
error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
+ AUE_SXUNLOCK(sc);
break;
default:
error = ether_ioctl(ifp, command, data);
break;
}
- AUE_UNLOCK(sc);
+ AUE_GIANTUNLOCK();
return (error);
}
-Static void
-aue_watchdog(struct ifnet *ifp)
+static void
+aue_watchdog(struct aue_softc *sc)
{
- struct aue_softc *sc = ifp->if_softc;
+ struct ifnet *ifp = sc->aue_ifp;
struct ue_chain *c;
usbd_status stat;
- AUE_LOCK(sc);
-
+ AUE_SXASSERTLOCKED(sc);
ifp->if_oerrors++;
- printf("aue%d: watchdog timeout\n", sc->aue_unit);
+ device_printf(sc->aue_dev, "watchdog timeout\n");
c = &sc->aue_cdata.ue_tx_chain[0];
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
- aue_txeof(c->ue_xfer, c, stat);
+ c->ue_status = stat;
+ aue_txeof_thread(sc);
- if (ifp->if_snd.ifq_head != NULL)
- aue_start(ifp);
- AUE_UNLOCK(sc);
+ if (!IFQ_IS_EMPTY(&ifp->if_snd))
+ aue_start_thread(sc);
return;
}
@@ -1358,32 +1334,32 @@
* Stop the adapter and free any mbufs allocated to the
* RX and TX lists.
*/
-Static void
+static void
aue_stop(struct aue_softc *sc)
{
usbd_status err;
struct ifnet *ifp;
- AUE_LOCK(sc);
+ AUE_SXASSERTLOCKED(sc);
ifp = sc->aue_ifp;
- ifp->if_timer = 0;
+ sc->aue_timer = 0;
aue_csr_write_1(sc, AUE_CTL0, 0);
aue_csr_write_1(sc, AUE_CTL1, 0);
aue_reset(sc);
- untimeout(aue_tick, sc, sc->aue_stat_ch);
+ sc->aue_dying = 1;
/* Stop transfers. */
if (sc->aue_ep[AUE_ENDPT_RX] != NULL) {
err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_RX]);
if (err) {
- printf("aue%d: abort rx pipe failed: %s\n",
- sc->aue_unit, usbd_errstr(err));
+ device_printf(sc->aue_dev,
+ "abort rx pipe failed: %s\n", usbd_errstr(err));
}
err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_RX]);
if (err) {
- printf("aue%d: close rx pipe failed: %s\n",
- sc->aue_unit, usbd_errstr(err));
+ device_printf(sc->aue_dev,
+ "close rx pipe failed: %s\n", usbd_errstr(err));
}
sc->aue_ep[AUE_ENDPT_RX] = NULL;
}
@@ -1391,13 +1367,13 @@
if (sc->aue_ep[AUE_ENDPT_TX] != NULL) {
err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_TX]);
if (err) {
- printf("aue%d: abort tx pipe failed: %s\n",
- sc->aue_unit, usbd_errstr(err));
+ device_printf(sc->aue_dev,
+ "abort tx pipe failed: %s\n", usbd_errstr(err));
}
err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_TX]);
if (err) {
- printf("aue%d: close tx pipe failed: %s\n",
- sc->aue_unit, usbd_errstr(err));
+ device_printf(sc->aue_dev,
+ "close tx pipe failed: %s\n", usbd_errstr(err));
}
sc->aue_ep[AUE_ENDPT_TX] = NULL;
}
@@ -1406,13 +1382,13 @@
if (sc->aue_ep[AUE_ENDPT_INTR] != NULL) {
err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]);
if (err) {
- printf("aue%d: abort intr pipe failed: %s\n",
- sc->aue_unit, usbd_errstr(err));
+ device_printf(sc->aue_dev,
+ "abort intr pipe failed: %s\n", usbd_errstr(err));
}
err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_INTR]);
if (err) {
- printf("aue%d: close intr pipe failed: %s\n",
- sc->aue_unit, usbd_errstr(err));
+ device_printf(sc->aue_dev,
+ "close intr pipe failed: %s\n", usbd_errstr(err));
}
sc->aue_ep[AUE_ENDPT_INTR] = NULL;
}
@@ -1431,7 +1407,6 @@
sc->aue_link = 0;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- AUE_UNLOCK(sc);
return;
}
@@ -1440,17 +1415,75 @@
* Stop all chip I/O so that the kernel's probe routines don't
* get confused by errant DMAs when rebooting.
*/
-Static void
-aue_shutdown(device_ptr_t dev)
+static int
+aue_shutdown(device_t dev)
{
struct aue_softc *sc;
sc = device_get_softc(dev);
+ AUE_SXLOCK(sc);
sc->aue_dying++;
- AUE_LOCK(sc);
aue_reset(sc);
aue_stop(sc);
+ AUE_SXUNLOCK(sc);
+
+ return (0);
+}
+
+static void
+aue_task_sched(struct aue_softc *sc, int task)
+{
+
+ AUE_LOCK(sc);
+ sc->aue_deferedtasks |= task;
+ usb_ether_task_enqueue(&sc->aue_taskqueue, &sc->aue_task);
AUE_UNLOCK(sc);
+}
- return;
+/*
+ * We defer all interrupt operations to this function.
+ *
+ * This allows us to do more complex operations, such as synchronous
+ * usb io that normally would not be allowed from interrupt context.
+ */
+static void
+aue_task(void *arg, int pending)
+{
+ struct aue_softc *sc = arg;
+ int tasks;
+
+ for ( ;; ) {
+ AUE_LOCK(sc);
+ tasks = sc->aue_deferedtasks;
+ sc->aue_deferedtasks = 0;
+ AUE_UNLOCK(sc);
+
+ if (tasks == 0)
+ break;
+
+ AUE_GIANTLOCK(); // XXX: usb not giant safe
+ AUE_SXLOCK(sc);
+ if (sc->aue_dying) {
+ AUE_SXUNLOCK(sc);
+ break;
+ }
+ if ((tasks & AUE_TASK_TICK) != 0) {
+ aue_tick_thread(sc);
+ }
+ if ((tasks & AUE_TASK_START) != 0) {
+ aue_start_thread(sc);
+ }
+ if ((tasks & AUE_TASK_RXSTART) != 0) {
+ aue_rxstart_thread(sc);
+ }
+ if ((tasks & AUE_TASK_RXEOF) != 0) {
+ aue_rxeof_thread(sc);
+ }
+ if ((tasks & AUE_TASK_TXEOF) != 0) {
+ aue_txeof_thread(sc);
+ }
+ AUE_SXUNLOCK(sc);
+ AUE_GIANTUNLOCK(); // XXX: usb not giant safe
+ }
}
+
Index: ohci.c
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/ohci.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L sys/dev/usb/ohci.c -L sys/dev/usb/ohci.c -u -r1.4 -r1.5
--- sys/dev/usb/ohci.c
+++ sys/dev/usb/ohci.c
@@ -13,7 +13,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/usb/ohci.c,v 1.154.2.3 2006/03/01 01:59:04 iedowse Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/usb/ohci.c,v 1.170 2007/06/20 05:10:52 imp Exp $");
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -63,17 +63,12 @@
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-#include <sys/device.h>
-#include <sys/select.h>
-#elif defined(__FreeBSD__)
#include <sys/endian.h>
#include <sys/module.h>
#include <sys/bus.h>
#if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
#include <machine/cpu.h>
#endif
-#endif
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
@@ -90,157 +85,133 @@
#include <dev/usb/ohcireg.h>
#include <dev/usb/ohcivar.h>
-#if defined(__FreeBSD__)
-#include <machine/clock.h>
-
#define delay(d) DELAY(d)
-#endif
-
-#if defined(__OpenBSD__)
-struct cfdriver ohci_cd = {
- NULL, "ohci", DV_DULL
-};
-#endif
#ifdef USB_DEBUG
-#define DPRINTF(x) if (ohcidebug) logprintf x
-#define DPRINTFN(n,x) if (ohcidebug>(n)) logprintf x
+#define DPRINTF(x) if (ohcidebug) printf x
+#define DPRINTFN(n,x) if (ohcidebug>(n)) printf x
int ohcidebug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ohci, CTLFLAG_RW, 0, "USB ohci");
SYSCTL_INT(_hw_usb_ohci, OID_AUTO, debug, CTLFLAG_RW,
&ohcidebug, 0, "ohci debug level");
-#ifndef __NetBSD__
#define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
-#endif
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
#endif
-/*
- * The OHCI controller is little endian, so on big endian machines
- * the data strored in memory needs to be swapped.
- */
-#if defined(__OpenBSD__)
-#if BYTE_ORDER == BIG_ENDIAN
-#define htole32(x) (bswap32(x))
-#define le32toh(x) (bswap32(x))
-#else
-#define htole32(x) (x)
-#define le32toh(x) (x)
-#endif
-#endif
-
struct ohci_pipe;
-Static ohci_soft_ed_t *ohci_alloc_sed(ohci_softc_t *);
-Static void ohci_free_sed(ohci_softc_t *, ohci_soft_ed_t *);
+static ohci_soft_ed_t *ohci_alloc_sed(ohci_softc_t *);
+static void ohci_free_sed(ohci_softc_t *, ohci_soft_ed_t *);
-Static ohci_soft_td_t *ohci_alloc_std(ohci_softc_t *);
-Static void ohci_free_std(ohci_softc_t *, ohci_soft_td_t *);
+static ohci_soft_td_t *ohci_alloc_std(ohci_softc_t *);
+static void ohci_free_std(ohci_softc_t *, ohci_soft_td_t *);
-Static ohci_soft_itd_t *ohci_alloc_sitd(ohci_softc_t *);
-Static void ohci_free_sitd(ohci_softc_t *,ohci_soft_itd_t *);
+static ohci_soft_itd_t *ohci_alloc_sitd(ohci_softc_t *);
+static void ohci_free_sitd(ohci_softc_t *,ohci_soft_itd_t *);
#if 0
-Static void ohci_free_std_chain(ohci_softc_t *, ohci_soft_td_t *,
+static void ohci_free_std_chain(ohci_softc_t *, ohci_soft_td_t *,
ohci_soft_td_t *);
#endif
-Static usbd_status ohci_alloc_std_chain(struct ohci_pipe *,
+static usbd_status ohci_alloc_std_chain(struct ohci_pipe *,
ohci_softc_t *, int, int, usbd_xfer_handle,
ohci_soft_td_t *, ohci_soft_td_t **);
#if defined(__NetBSD__) || defined(__OpenBSD__)
-Static void ohci_shutdown(void *v);
-Static void ohci_power(int, void *);
+static void ohci_shutdown(void *v);
+static void ohci_power(int, void *);
#endif
-Static usbd_status ohci_open(usbd_pipe_handle);
-Static void ohci_poll(struct usbd_bus *);
-Static void ohci_softintr(void *);
-Static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle);
-Static void ohci_add_done(ohci_softc_t *, ohci_physaddr_t);
-Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle);
-
-Static usbd_status ohci_device_request(usbd_xfer_handle xfer);
-Static void ohci_add_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
-Static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
-Static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *);
-Static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *);
-Static ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t);
-Static void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *);
-Static void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *);
-Static ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t);
-
-Static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe);
-Static void ohci_device_isoc_enter(usbd_xfer_handle);
-
-Static usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
-Static void ohci_freem(struct usbd_bus *, usb_dma_t *);
-
-Static usbd_xfer_handle ohci_allocx(struct usbd_bus *);
-Static void ohci_freex(struct usbd_bus *, usbd_xfer_handle);
-
-Static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle);
-Static usbd_status ohci_root_ctrl_start(usbd_xfer_handle);
-Static void ohci_root_ctrl_abort(usbd_xfer_handle);
-Static void ohci_root_ctrl_close(usbd_pipe_handle);
-Static void ohci_root_ctrl_done(usbd_xfer_handle);
-
-Static usbd_status ohci_root_intr_transfer(usbd_xfer_handle);
-Static usbd_status ohci_root_intr_start(usbd_xfer_handle);
-Static void ohci_root_intr_abort(usbd_xfer_handle);
-Static void ohci_root_intr_close(usbd_pipe_handle);
-Static void ohci_root_intr_done(usbd_xfer_handle);
-
-Static usbd_status ohci_device_ctrl_transfer(usbd_xfer_handle);
-Static usbd_status ohci_device_ctrl_start(usbd_xfer_handle);
-Static void ohci_device_ctrl_abort(usbd_xfer_handle);
-Static void ohci_device_ctrl_close(usbd_pipe_handle);
-Static void ohci_device_ctrl_done(usbd_xfer_handle);
-
-Static usbd_status ohci_device_bulk_transfer(usbd_xfer_handle);
-Static usbd_status ohci_device_bulk_start(usbd_xfer_handle);
-Static void ohci_device_bulk_abort(usbd_xfer_handle);
-Static void ohci_device_bulk_close(usbd_pipe_handle);
-Static void ohci_device_bulk_done(usbd_xfer_handle);
-
-Static usbd_status ohci_device_intr_transfer(usbd_xfer_handle);
-Static usbd_status ohci_device_intr_start(usbd_xfer_handle);
-Static void ohci_device_intr_abort(usbd_xfer_handle);
-Static void ohci_device_intr_close(usbd_pipe_handle);
-Static void ohci_device_intr_done(usbd_xfer_handle);
-
-Static usbd_status ohci_device_isoc_transfer(usbd_xfer_handle);
-Static usbd_status ohci_device_isoc_start(usbd_xfer_handle);
-Static void ohci_device_isoc_abort(usbd_xfer_handle);
-Static void ohci_device_isoc_close(usbd_pipe_handle);
-Static void ohci_device_isoc_done(usbd_xfer_handle);
+static usbd_status ohci_open(usbd_pipe_handle);
+static void ohci_poll(struct usbd_bus *);
+static void ohci_softintr(void *);
+static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle);
+static void ohci_add_done(ohci_softc_t *, ohci_physaddr_t);
+static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle);
+
+static usbd_status ohci_device_request(usbd_xfer_handle xfer);
+static void ohci_add_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
+static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
+static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *);
+static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *);
+static ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t);
+static void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *);
+static void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *);
+static ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t);
+
+static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe);
+static void ohci_device_isoc_enter(usbd_xfer_handle);
+
+static usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
+static void ohci_freem(struct usbd_bus *, usb_dma_t *);
+
+static usbd_xfer_handle ohci_allocx(struct usbd_bus *);
+static void ohci_freex(struct usbd_bus *, usbd_xfer_handle);
+
+static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle);
+static usbd_status ohci_root_ctrl_start(usbd_xfer_handle);
+static void ohci_root_ctrl_abort(usbd_xfer_handle);
+static void ohci_root_ctrl_close(usbd_pipe_handle);
+static void ohci_root_ctrl_done(usbd_xfer_handle);
+
+static usbd_status ohci_root_intr_transfer(usbd_xfer_handle);
+static usbd_status ohci_root_intr_start(usbd_xfer_handle);
+static void ohci_root_intr_abort(usbd_xfer_handle);
+static void ohci_root_intr_close(usbd_pipe_handle);
+static void ohci_root_intr_done(usbd_xfer_handle);
+
+static usbd_status ohci_device_ctrl_transfer(usbd_xfer_handle);
+static usbd_status ohci_device_ctrl_start(usbd_xfer_handle);
+static void ohci_device_ctrl_abort(usbd_xfer_handle);
+static void ohci_device_ctrl_close(usbd_pipe_handle);
+static void ohci_device_ctrl_done(usbd_xfer_handle);
+
+static usbd_status ohci_device_bulk_transfer(usbd_xfer_handle);
+static usbd_status ohci_device_bulk_start(usbd_xfer_handle);
+static void ohci_device_bulk_abort(usbd_xfer_handle);
+static void ohci_device_bulk_close(usbd_pipe_handle);
+static void ohci_device_bulk_done(usbd_xfer_handle);
+
+static usbd_status ohci_device_intr_transfer(usbd_xfer_handle);
+static usbd_status ohci_device_intr_start(usbd_xfer_handle);
+static void ohci_device_intr_abort(usbd_xfer_handle);
+static void ohci_device_intr_close(usbd_pipe_handle);
+static void ohci_device_intr_done(usbd_xfer_handle);
+
+static usbd_status ohci_device_isoc_transfer(usbd_xfer_handle);
+static usbd_status ohci_device_isoc_start(usbd_xfer_handle);
+static void ohci_device_isoc_abort(usbd_xfer_handle);
+static void ohci_device_isoc_close(usbd_pipe_handle);
+static void ohci_device_isoc_done(usbd_xfer_handle);
-Static usbd_status ohci_device_setintr(ohci_softc_t *sc,
+static usbd_status ohci_device_setintr(ohci_softc_t *sc,
struct ohci_pipe *pipe, int ival);
+static usbd_status ohci_device_intr_insert(ohci_softc_t *sc,
+ usbd_xfer_handle xfer);
-Static int ohci_str(usb_string_descriptor_t *, int, const char *);
+static int ohci_str(usb_string_descriptor_t *, int, const char *);
-Static void ohci_timeout(void *);
-Static void ohci_timeout_task(void *);
-Static void ohci_rhsc_able(ohci_softc_t *, int);
-Static void ohci_rhsc_enable(void *);
+static void ohci_timeout(void *);
+static void ohci_timeout_task(void *);
+static void ohci_rhsc_able(ohci_softc_t *, int);
+static void ohci_rhsc_enable(void *);
-Static void ohci_close_pipe(usbd_pipe_handle, ohci_soft_ed_t *);
-Static void ohci_abort_xfer(usbd_xfer_handle, usbd_status);
+static void ohci_close_pipe(usbd_pipe_handle, ohci_soft_ed_t *);
+static void ohci_abort_xfer(usbd_xfer_handle, usbd_status);
-Static void ohci_device_clear_toggle(usbd_pipe_handle pipe);
-Static void ohci_noop(usbd_pipe_handle pipe);
+static void ohci_device_clear_toggle(usbd_pipe_handle pipe);
+static void ohci_noop(usbd_pipe_handle pipe);
-Static usbd_status ohci_controller_init(ohci_softc_t *sc);
+static usbd_status ohci_controller_init(ohci_softc_t *sc);
#ifdef USB_DEBUG
-Static void ohci_dumpregs(ohci_softc_t *);
-Static void ohci_dump_tds(ohci_soft_td_t *);
-Static void ohci_dump_td(ohci_soft_td_t *);
-Static void ohci_dump_ed(ohci_soft_ed_t *);
-Static void ohci_dump_itd(ohci_soft_itd_t *);
-Static void ohci_dump_itds(ohci_soft_itd_t *);
+static void ohci_dumpregs(ohci_softc_t *);
+static void ohci_dump_tds(ohci_soft_td_t *);
+static void ohci_dump_td(ohci_soft_td_t *);
+static void ohci_dump_ed(ohci_soft_ed_t *);
+static void ohci_dump_itd(ohci_soft_itd_t *);
+static void ohci_dump_itds(ohci_soft_itd_t *);
#endif
#define OBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
@@ -256,7 +227,7 @@
#define OREAD4(sc, r) (OBARR(sc), bus_space_read_4((sc)->iot, (sc)->ioh, (r)))
/* Reverse the bits in a value 0 .. 31 */
-Static u_int8_t revbits[OHCI_NO_INTRS] =
+static u_int8_t revbits[OHCI_NO_INTRS] =
{ 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c,
0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e,
0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d,
@@ -297,7 +268,7 @@
#define OHCI_INTR_ENDPT 1
-Static struct usbd_bus_methods ohci_bus_methods = {
+static struct usbd_bus_methods ohci_bus_methods = {
ohci_open,
ohci_softintr,
ohci_poll,
@@ -307,7 +278,7 @@
ohci_freex,
};
-Static struct usbd_pipe_methods ohci_root_ctrl_methods = {
+static struct usbd_pipe_methods ohci_root_ctrl_methods = {
ohci_root_ctrl_transfer,
ohci_root_ctrl_start,
ohci_root_ctrl_abort,
@@ -316,7 +287,7 @@
ohci_root_ctrl_done,
};
-Static struct usbd_pipe_methods ohci_root_intr_methods = {
+static struct usbd_pipe_methods ohci_root_intr_methods = {
ohci_root_intr_transfer,
ohci_root_intr_start,
ohci_root_intr_abort,
@@ -325,7 +296,7 @@
ohci_root_intr_done,
};
-Static struct usbd_pipe_methods ohci_device_ctrl_methods = {
+static struct usbd_pipe_methods ohci_device_ctrl_methods = {
ohci_device_ctrl_transfer,
ohci_device_ctrl_start,
ohci_device_ctrl_abort,
@@ -334,7 +305,7 @@
ohci_device_ctrl_done,
};
-Static struct usbd_pipe_methods ohci_device_intr_methods = {
+static struct usbd_pipe_methods ohci_device_intr_methods = {
ohci_device_intr_transfer,
ohci_device_intr_start,
ohci_device_intr_abort,
@@ -343,7 +314,7 @@
ohci_device_intr_done,
};
-Static struct usbd_pipe_methods ohci_device_bulk_methods = {
+static struct usbd_pipe_methods ohci_device_bulk_methods = {
ohci_device_bulk_transfer,
ohci_device_bulk_start,
ohci_device_bulk_abort,
@@ -352,7 +323,7 @@
ohci_device_bulk_done,
};
-Static struct usbd_pipe_methods ohci_device_isoc_methods = {
+static struct usbd_pipe_methods ohci_device_isoc_methods = {
ohci_device_isoc_transfer,
ohci_device_isoc_start,
ohci_device_isoc_abort,
@@ -361,43 +332,13 @@
ohci_device_isoc_done,
};
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-int
-ohci_activate(device_ptr_t self, enum devact act)
-{
- struct ohci_softc *sc = (struct ohci_softc *)self;
- int rv = 0;
-
- switch (act) {
- case DVACT_ACTIVATE:
- return (EOPNOTSUPP);
-
- case DVACT_DEACTIVATE:
- if (sc->sc_child != NULL)
- rv = config_deactivate(sc->sc_child);
- sc->sc_dying = 1;
- break;
- }
- return (rv);
-}
-#endif
-
int
ohci_detach(struct ohci_softc *sc, int flags)
{
int i, rv = 0;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- if (sc->sc_child != NULL)
- rv = config_detach(sc->sc_child, flags);
-
- if (rv != 0)
- return (rv);
-#else
sc->sc_dying = 1;
-#endif
-
- usb_uncallout(sc->sc_tmo_rhsc, ohci_rhsc_enable, sc);
+ callout_stop(&sc->sc_tmo_rhsc);
#if defined(__NetBSD__) || defined(__OpenBSD__)
powerhook_disestablish(sc->sc_powerhook);
@@ -510,35 +451,36 @@
int alen, int rd, usbd_xfer_handle xfer,
ohci_soft_td_t *sp, ohci_soft_td_t **ep)
{
- ohci_soft_td_t *next, *cur;
- ohci_physaddr_t dataphys;
+ ohci_soft_td_t *next, *cur, *end;
+ ohci_physaddr_t dataphys, physend;
u_int32_t tdflags;
int offset = 0;
- int len, curlen;
- usb_dma_t *dma = &xfer->dmabuf;
+ int len, maxp, curlen, curlen2, seg, segoff;
+ struct usb_dma_mapping *dma = &xfer->dmamap;
u_int16_t flags = xfer->flags;
DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen));
len = alen;
cur = sp;
+ end = NULL;
+ maxp = UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize);
tdflags = htole32(
(rd ? OHCI_TD_IN : OHCI_TD_OUT) |
(flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) |
OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_SET_DI(6));
- for (;;) {
+ seg = 0;
+ segoff = 0;
+ while (len > 0) {
next = ohci_alloc_std(sc);
if (next == NULL)
goto nomem;
- dataphys = DMAADDR(dma, offset);
-
/*
* The OHCI hardware can handle at most one 4k crossing.
- * XXX - currently we only allocate contigous buffers, but
- * the OHCI spec says: If during the data transfer the buffer
+ * The OHCI spec says: If during the data transfer the buffer
* address contained in the HC's working copy of
* CurrentBufferPointer crosses a 4K boundary, the upper 20
* bits of Buffer End are copied to the working value of
@@ -546,34 +488,67 @@
* be the 0th byte in the same 4K page that contains the
* last byte of the buffer (the 4K boundary crossing may
* occur within a data packet transfer.)
- *
- * If/when dma has multiple segments, this will need to
- * properly handle fragmenting TD's.
- *
- * Note that if we are gathering data from multiple SMALL
- * segments, e.g. mbufs, we need to do special gymnastics,
- * e.g. bounce buffering or data aggregation,
- * BEFORE WE GET HERE because a bulk USB transfer must
- * consist of maximally sized packets right up to the end.
- * A shorter than maximal packet means that it is the end
- * of the transfer. If the data transfer length is a
- * multiple of the packet size, then a 0 byte
- * packet will be the signal of the end of transfer.
- * Since packets can't cross TDs this means that
- * each TD except the last one must cover an exact multiple
- * of the maximal packet length.
*/
- if (OHCI_PAGE_OFFSET(dataphys) + len <= (2 * OHCI_PAGE_SIZE)) {
- /* We can handle all that remains in this TD */
+ KASSERT(seg < dma->nsegs, ("ohci_alloc_std_chain: overrun"));
+ dataphys = dma->segs[seg].ds_addr + segoff;
+ curlen = dma->segs[seg].ds_len - segoff;
+ if (curlen > len)
curlen = len;
+ physend = dataphys + curlen - 1;
+ if (OHCI_PAGE(dataphys) != OHCI_PAGE(physend)) {
+ /* Truncate to two OHCI pages if there are more. */
+ if (curlen > 2 * OHCI_PAGE_SIZE -
+ OHCI_PAGE_OFFSET(dataphys))
+ curlen = 2 * OHCI_PAGE_SIZE -
+ OHCI_PAGE_OFFSET(dataphys);
+ if (curlen < len)
+ curlen -= curlen % maxp;
+ physend = dataphys + curlen - 1;
+ } else if (OHCI_PAGE_OFFSET(physend + 1) == 0 && curlen < len &&
+ curlen + segoff == dma->segs[seg].ds_len) {
+ /* We can possibly include another segment. */
+ KASSERT(seg + 1 < dma->nsegs,
+ ("ohci_alloc_std_chain: overrun2"));
+ seg++;
+
+ /* Determine how much of the second segment to use. */
+ curlen2 = dma->segs[seg].ds_len;
+ if (curlen + curlen2 > len)
+ curlen2 = len - curlen;
+ if (OHCI_PAGE(dma->segs[seg].ds_addr) !=
+ OHCI_PAGE(dma->segs[seg].ds_addr + curlen2 - 1))
+ curlen2 = OHCI_PAGE_SIZE -
+ OHCI_PAGE_OFFSET(dma->segs[seg].ds_addr);
+ if (curlen + curlen2 < len)
+ curlen2 -= (curlen + curlen2) % maxp;
+
+ if (curlen2 > 0) {
+ /* We can include a second segment */
+ segoff = curlen2;
+ physend = dma->segs[seg].ds_addr + curlen2 - 1;
+ curlen += curlen2;
+ } else {
+ /* Second segment not usable now. */
+ seg--;
+ segoff += curlen;
+ }
} else {
- /* must use multiple TDs, fill as much as possible. */
- curlen = 2 * OHCI_PAGE_SIZE -
- OHCI_PAGE_OFFSET(dataphys);
- /* the length must be a multiple of the max size */
- curlen -= curlen %
- UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize);
- KASSERT((curlen != 0), ("ohci_alloc_std: curlen == 0"));
+ /* Simple case where there is just one OHCI page. */
+ segoff += curlen;
+ }
+ if (curlen == 0 && len != 0) {
+ /*
+ * A maxp length packet would need to be split.
+ * This shouldn't be possible if PAGE_SIZE >= 4k
+ * and the buffer is contiguous in virtual memory.
+ */
+ panic("ohci_alloc_std_chain: XXX need to copy");
+ }
+ if (segoff >= dma->segs[seg].ds_len) {
+ KASSERT(segoff == dma->segs[seg].ds_len,
+ ("ohci_alloc_std_chain: overlap"));
+ seg++;
+ segoff = 0;
}
DPRINTFN(4,("ohci_alloc_std_chain: dataphys=0x%08x "
"len=%d curlen=%d\n",
@@ -584,27 +559,23 @@
cur->td.td_cbp = htole32(dataphys);
cur->nexttd = next;
cur->td.td_nexttd = htole32(next->physaddr);
- cur->td.td_be = htole32(DMAADDR(dma, offset + curlen - 1));
+ cur->td.td_be = htole32(physend);
cur->len = curlen;
cur->flags = OHCI_ADD_LEN;
cur->xfer = xfer;
DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n",
dataphys, dataphys + curlen - 1));
- if (len == 0)
- break;
if (len < 0)
panic("Length went negative: %d curlen %d dma %p offset %08x", len, curlen, dma, (int)0);
DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n"));
offset += curlen;
+ end = cur;
cur = next;
}
- if ((flags & USBD_FORCE_SHORT_XFER) &&
+ if (((flags & USBD_FORCE_SHORT_XFER) || alen == 0) &&
alen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize) == 0) {
/* Force a 0 length transfer at the end. */
-
- cur = next;
-
next = ohci_alloc_std(sc);
if (next == NULL)
goto nomem;
@@ -618,8 +589,9 @@
cur->flags = 0;
cur->xfer = xfer;
DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n"));
+ end = cur;
}
- *ep = cur;
+ *ep = end;
return (USBD_NORMAL_COMPLETION);
@@ -629,7 +601,7 @@
}
#if 0
-Static void
+static void
ohci_free_std_chain(ohci_softc_t *sc, ohci_soft_td_t *std,
ohci_soft_td_t *stdend)
{
@@ -715,18 +687,14 @@
u_int32_t rev;
DPRINTF(("ohci_init: start\n"));
-#if defined(__OpenBSD__)
- printf(",");
-#else
- printf("%s:", USBDEVNAME(sc->sc_bus.bdev));
-#endif
+ printf("%s:", device_get_nameunit(sc->sc_bus.bdev));
rev = OREAD4(sc, OHCI_REVISION);
printf(" OHCI version %d.%d%s\n", OHCI_REV_HI(rev), OHCI_REV_LO(rev),
OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) {
printf("%s: unsupported OHCI revision\n",
- USBDEVNAME(sc->sc_bus.bdev));
+ device_get_nameunit(sc->sc_bus.bdev));
sc->sc_bus.usbrev = USBREV_UNKNOWN;
return (USBD_INVAL);
}
@@ -737,7 +705,7 @@
for (i = 0; i < OHCI_HASH_SIZE; i++)
LIST_INIT(&sc->sc_hash_itds[i]);
- SIMPLEQ_INIT(&sc->sc_free_xfers);
+ STAILQ_INIT(&sc->sc_free_xfers);
/* XXX determine alignment by R/W */
/* Allocate the HCCA area. */
@@ -821,12 +789,11 @@
sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
#if defined(__NetBSD__) || defined(__OpenBSD__)
- sc->sc_control = sc->sc_intre = 0;
sc->sc_powerhook = powerhook_establish(ohci_power, sc);
sc->sc_shutdownhook = shutdownhook_establish(ohci_shutdown, sc);
#endif
- usb_callout_init(sc->sc_tmo_rhsc);
+ callout_init(&sc->sc_tmo_rhsc, 0);
return (USBD_NORMAL_COMPLETION);
@@ -844,7 +811,7 @@
return (err);
}
-Static usbd_status
+static usbd_status
ohci_controller_init(ohci_softc_t *sc)
{
int i;
@@ -863,7 +830,7 @@
}
if ((ctl & OHCI_IR) == 0) {
printf("%s: SMM does not respond, resetting\n",
- USBDEVNAME(sc->sc_bus.bdev));
+ device_get_nameunit(sc->sc_bus.bdev));
OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
goto reset;
}
@@ -888,7 +855,7 @@
* This reset should not be necessary according to the OHCI spec, but
* without it some controllers do not start.
*/
- DPRINTF(("%s: resetting\n", USBDEVNAME(sc->sc_bus.bdev)));
+ DPRINTF(("%s: resetting\n", device_get_nameunit(sc->sc_bus.bdev)));
OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
@@ -904,7 +871,7 @@
break;
}
if (hcr) {
- printf("%s: reset timeout\n", USBDEVNAME(sc->sc_bus.bdev));
+ printf("%s: reset timeout\n", device_get_nameunit(sc->sc_bus.bdev));
return (USBD_IOERROR);
}
#ifdef USB_DEBUG
@@ -982,9 +949,9 @@
struct ohci_softc *sc = (struct ohci_softc *)bus;
usbd_xfer_handle xfer;
- xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
+ xfer = STAILQ_FIRST(&sc->sc_free_xfers);
if (xfer != NULL) {
- SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
+ STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
#ifdef DIAGNOSTIC
if (xfer->busy_free != XFER_FREE) {
printf("ohci_allocx: xfer=%p not free, 0x%08x\n", xfer,
@@ -1010,14 +977,6 @@
ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
{
struct ohci_softc *sc = (struct ohci_softc *)bus;
- struct ohci_xfer *oxfer = (struct ohci_xfer *)xfer;
- ohci_soft_itd_t *sitd;
-
- if (oxfer->ohci_xfer_flags & OHCI_ISOC_DIRTY) {
- for (sitd = xfer->hcpriv; sitd != NULL && sitd->xfer == xfer;
- sitd = sitd->nextitd)
- ohci_free_sitd(sc, sitd);
- }
#ifdef DIAGNOSTIC
if (xfer->busy_free != XFER_BUSY) {
@@ -1027,7 +986,7 @@
}
xfer->busy_free = XFER_FREE;
#endif
- SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
+ STAILQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
}
/*
@@ -1143,28 +1102,28 @@
}
#endif
-Static int ohci_intr1(ohci_softc_t *);
+static int ohci_intr1(ohci_softc_t *);
-int
+void
ohci_intr(void *p)
{
ohci_softc_t *sc = p;
if (sc == NULL || sc->sc_dying)
- return (0);
+ return;
/* If we get an interrupt while polling, then just ignore it. */
if (sc->sc_bus.use_polling) {
#ifdef DIAGNOSTIC
printf("ohci_intr: ignored interrupt while polling\n");
#endif
- return (0);
+ return;
}
- return (ohci_intr1(sc));
+ ohci_intr1(sc);
}
-Static int
+static int
ohci_intr1(ohci_softc_t *sc)
{
u_int32_t intrs, eintrs;
@@ -1224,7 +1183,7 @@
sc->sc_overrun_cnt++;
if (usbd_ratecheck(&sc->sc_overrun_ntc)) {
printf("%s: %u scheduling overruns\n",
- USBDEVNAME(sc->sc_bus.bdev), sc->sc_overrun_cnt);
+ device_get_nameunit(sc->sc_bus.bdev), sc->sc_overrun_cnt);
sc->sc_overrun_cnt = 0;
}
/* XXX do what */
@@ -1236,12 +1195,12 @@
eintrs &= ~OHCI_WDH;
}
if (eintrs & OHCI_RD) {
- printf("%s: resume detect\n", USBDEVNAME(sc->sc_bus.bdev));
+ printf("%s: resume detect\n", device_get_nameunit(sc->sc_bus.bdev));
/* XXX process resume detect */
}
if (eintrs & OHCI_UE) {
printf("%s: unrecoverable error, controller halted\n",
- USBDEVNAME(sc->sc_bus.bdev));
+ device_get_nameunit(sc->sc_bus.bdev));
OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
/* XXX what else */
}
@@ -1253,7 +1212,7 @@
*/
ohci_rhsc_able(sc, 0);
/* Do not allow RHSC interrupts > 1 per second */
- usb_callout(sc->sc_tmo_rhsc, hz, ohci_rhsc_enable, sc);
+ callout_reset(&sc->sc_tmo_rhsc, hz, ohci_rhsc_enable, sc);
eintrs &= ~OHCI_RHSC;
}
@@ -1264,7 +1223,7 @@
OWRITE4(sc, OHCI_INTERRUPT_DISABLE, eintrs);
sc->sc_eintrs &= ~eintrs;
printf("%s: blocking intrs 0x%x\n",
- USBDEVNAME(sc->sc_bus.bdev), eintrs);
+ device_get_nameunit(sc->sc_bus.bdev), eintrs);
}
return (1);
@@ -1425,7 +1384,7 @@
DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n",
OHCI_TD_GET_CC(le32toh(std->td.td_flags)),
ohci_cc_strs[OHCI_TD_GET_CC(le32toh(std->td.td_flags))]));
- usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
+ callout_stop(&xfer->timeout_handle);
usb_rem_task(OXFER(xfer)->xfer.pipe->device,
&OXFER(xfer)->abort_task);
@@ -1465,7 +1424,7 @@
continue;
/* Normal transfer completion */
- usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
+ callout_stop(&xfer->timeout_handle);
usb_rem_task(OXFER(xfer)->xfer.pipe->device,
&OXFER(xfer)->abort_task);
for (p = xfer->hcpriv; p->xfer == xfer; p = n) {
@@ -1536,6 +1495,11 @@
if (sitd->flags & OHCI_CALL_DONE)
break;
}
+ for (sitd = xfer->hcpriv; sitd->xfer == xfer;
+ sitd = next) {
+ next = sitd->nextitd;
+ ohci_free_sitd(sc, sitd);
+ }
s = splusb();
usb_transfer_complete(xfer);
@@ -1572,42 +1536,18 @@
{
struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
- ohci_soft_ed_t *sed = opipe->sed;
- ohci_soft_td_t *data, *tail;
-
+ usbd_status err;
DPRINTFN(10,("ohci_device_intr_done: xfer=%p, actlen=%d\n",
xfer, xfer->actlen));
xfer->hcpriv = NULL;
-
if (xfer->pipe->repeat) {
- data = opipe->tail.td;
- tail = ohci_alloc_std(sc); /* XXX should reuse TD */
- if (tail == NULL) {
- xfer->status = USBD_NOMEM;
+ err = ohci_device_intr_insert(sc, xfer);
+ if (err) {
+ xfer->status = err;
return;
}
- tail->xfer = NULL;
-
- data->td.td_flags = htole32(
- OHCI_TD_IN | OHCI_TD_NOCC |
- OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
- if (xfer->flags & USBD_SHORT_XFER_OK)
- data->td.td_flags |= htole32(OHCI_TD_R);
- data->td.td_cbp = htole32(DMAADDR(&xfer->dmabuf, 0));
- data->nexttd = tail;
- data->td.td_nexttd = htole32(tail->physaddr);
- data->td.td_be = htole32(le32toh(data->td.td_cbp) +
- xfer->length - 1);
- data->len = xfer->length;
- data->xfer = xfer;
- data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
- xfer->hcpriv = data;
- xfer->actlen = 0;
-
- sed->ed.ed_tailp = htole32(tail->physaddr);
- opipe->tail.td = tail;
}
}
@@ -1639,7 +1579,7 @@
pipe = xfer->pipe;
- p = KERNADDR(&xfer->dmabuf, 0);
+ p = xfer->buffer;
m = min(sc->sc_noport, xfer->length * 8 - 1);
memset(p, 0, xfer->length);
for (i = 1; i <= m; i++) {
@@ -1728,7 +1668,6 @@
usb_device_request_t *req = &xfer->request;
usbd_device_handle dev = opipe->pipe.device;
ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
- int addr = dev->address;
ohci_soft_td_t *setup, *stat, *next, *tail;
ohci_soft_ed_t *sed;
int isread;
@@ -1742,7 +1681,7 @@
DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, "
"wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
req->bmRequestType, req->bRequest, UGETW(req->wValue),
- UGETW(req->wIndex), len, addr,
+ UGETW(req->wIndex), len, dev->address,
opipe->pipe.endpoint->edesc->bEndpointAddress));
setup = opipe->tail.td;
@@ -1760,16 +1699,6 @@
sed = opipe->sed;
opipe->u.ctl.length = len;
-
- /* Update device address and length since they may have changed
- during the setup of the control pipe in usbd_new_device(). */
- /* XXX This only needs to be done once, but it's too early in open. */
- /* XXXX Should not touch ED here! */
- sed->ed.ed_flags = htole32(
- (le32toh(sed->ed.ed_flags) & ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) |
- OHCI_ED_SET_FA(addr) |
- OHCI_ED_SET_MAXP(UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize)));
-
next = stat;
/* Set up data transaction */
@@ -1824,8 +1753,8 @@
opipe->tail.td = tail;
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
if (xfer->timeout && !sc->sc_bus.use_polling) {
- usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ohci_timeout, xfer);
+ callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
+ ohci_timeout, xfer);
}
splx(s);
@@ -1928,7 +1857,7 @@
* stage.
*/
KASSERT((a&~OHCI_HEADMASK) == 0, ("%s: 0x%b has lower bits set\n",
- USBDEVNAME(sc->sc_bus.bdev),
+ device_get_nameunit(sc->sc_bus.bdev),
(int) a, "\20\1HALT\2TOGGLE"));
for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
@@ -1938,7 +1867,7 @@
return (std);
DPRINTF(("%s: ohci_hash_find_td: addr 0x%08lx not found\n",
- USBDEVNAME(sc->sc_bus.bdev), (u_long) a));
+ device_get_nameunit(sc->sc_bus.bdev), (u_long) a));
return (NULL);
}
@@ -1997,7 +1926,8 @@
}
/* Execute the abort in a process context. */
- usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task);
+ usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task,
+ USB_TASKQ_HC);
}
void
@@ -2281,10 +2211,11 @@
/* If we're dying, just do the software part. */
s = splusb();
xfer->status = status; /* make software ignore it */
- usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
+ callout_stop(&xfer->timeout_handle);
usb_rem_task(xfer->pipe->device, &OXFER(xfer)->abort_task);
usb_transfer_complete(xfer);
splx(s);
+ return;
}
if (xfer->device->bus->intr_context || !curproc)
@@ -2314,7 +2245,7 @@
s = splusb();
oxfer->ohci_xfer_flags |= OHCI_XFER_ABORTING;
xfer->status = status; /* make software ignore it */
- usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
+ callout_stop(&xfer->timeout_handle);
usb_rem_task(xfer->pipe->device, &OXFER(xfer)->abort_task);
splx(s);
DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
@@ -2398,7 +2329,7 @@
/*
* Data structures and routines to emulate the root hub.
*/
-Static usb_device_descriptor_t ohci_devd = {
+static usb_device_descriptor_t ohci_devd = {
USB_DEVICE_DESCRIPTOR_SIZE,
UDESC_DEVICE, /* type */
{0x00, 0x01}, /* USB version */
@@ -2411,7 +2342,7 @@
1 /* # of configurations */
};
-Static usb_config_descriptor_t ohci_confd = {
+static usb_config_descriptor_t ohci_confd = {
USB_CONFIG_DESCRIPTOR_SIZE,
UDESC_CONFIG,
{USB_CONFIG_DESCRIPTOR_SIZE +
@@ -2424,7 +2355,7 @@
0 /* max power */
};
-Static usb_interface_descriptor_t ohci_ifcd = {
+static usb_interface_descriptor_t ohci_ifcd = {
USB_INTERFACE_DESCRIPTOR_SIZE,
UDESC_INTERFACE,
0,
@@ -2436,7 +2367,7 @@
0
};
-Static usb_endpoint_descriptor_t ohci_endpd = {
+static usb_endpoint_descriptor_t ohci_endpd = {
USB_ENDPOINT_DESCRIPTOR_SIZE,
UDESC_ENDPOINT,
UE_DIR_IN | OHCI_INTR_ENDPT,
@@ -2445,7 +2376,7 @@
255
};
-Static usb_hub_descriptor_t ohci_hubd = {
+static usb_hub_descriptor_t ohci_hubd = {
USB_HUB_DESCRIPTOR_SIZE,
UDESC_HUB,
0,
@@ -2455,7 +2386,7 @@
{0},
};
-Static int
+static int
ohci_str(usb_string_descriptor_t *p, int l, const char *s)
{
int i;
@@ -2475,7 +2406,7 @@
/*
* Simulate a hardware hub by handling all the necessary requests.
*/
-Static usbd_status
+static usbd_status
ohci_root_ctrl_transfer(usbd_xfer_handle xfer)
{
usbd_status err;
@@ -2486,10 +2417,10 @@
return (err);
/* Pipe isn't running, start first */
- return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
+ return (ohci_root_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
}
-Static usbd_status
+static usbd_status
ohci_root_ctrl_start(usbd_xfer_handle xfer)
{
ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
@@ -2520,7 +2451,7 @@
index = UGETW(req->wIndex);
if (len != 0)
- buf = KERNADDR(&xfer->dmabuf, 0);
+ buf = xfer->buffer;
#define C(x,y) ((x) | ((y) << 8))
switch(C(req->bRequest, req->bmRequestType)) {
@@ -2797,21 +2728,21 @@
}
/* Abort a root control request. */
-Static void
+static void
ohci_root_ctrl_abort(usbd_xfer_handle xfer)
{
/* Nothing to do, all transfers are synchronous. */
}
/* Close the root pipe. */
-Static void
+static void
ohci_root_ctrl_close(usbd_pipe_handle pipe)
{
DPRINTF(("ohci_root_ctrl_close\n"));
/* Nothing to do. */
}
-Static usbd_status
+static usbd_status
ohci_root_intr_transfer(usbd_xfer_handle xfer)
{
usbd_status err;
@@ -2822,10 +2753,10 @@
return (err);
/* Pipe isn't running, start first */
- return (ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
+ return (ohci_root_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
}
-Static usbd_status
+static usbd_status
ohci_root_intr_start(usbd_xfer_handle xfer)
{
usbd_pipe_handle pipe = xfer->pipe;
@@ -2840,7 +2771,7 @@
}
/* Abort a root interrupt request. */
-Static void
+static void
ohci_root_intr_abort(usbd_xfer_handle xfer)
{
int s;
@@ -2856,7 +2787,7 @@
}
/* Close the root pipe. */
-Static void
+static void
ohci_root_intr_close(usbd_pipe_handle pipe)
{
ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
@@ -2868,7 +2799,7 @@
/************************/
-Static usbd_status
+static usbd_status
ohci_device_ctrl_transfer(usbd_xfer_handle xfer)
{
usbd_status err;
@@ -2879,10 +2810,10 @@
return (err);
/* Pipe isn't running, start first */
- return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
+ return (ohci_device_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
}
-Static usbd_status
+static usbd_status
ohci_device_ctrl_start(usbd_xfer_handle xfer)
{
ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
@@ -2909,7 +2840,7 @@
}
/* Abort a device control request. */
-Static void
+static void
ohci_device_ctrl_abort(usbd_xfer_handle xfer)
{
DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer));
@@ -2917,7 +2848,7 @@
}
/* Close a device control pipe. */
-Static void
+static void
ohci_device_ctrl_close(usbd_pipe_handle pipe)
{
struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
@@ -2930,7 +2861,7 @@
/************************/
-Static void
+static void
ohci_device_clear_toggle(usbd_pipe_handle pipe)
{
struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
@@ -2938,12 +2869,12 @@
opipe->sed->ed.ed_headp &= htole32(~OHCI_TOGGLECARRY);
}
-Static void
+static void
ohci_noop(usbd_pipe_handle pipe)
{
}
-Static usbd_status
+static usbd_status
ohci_device_bulk_transfer(usbd_xfer_handle xfer)
{
usbd_status err;
@@ -2954,10 +2885,10 @@
return (err);
/* Pipe isn't running, start first */
- return (ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
+ return (ohci_device_bulk_start(STAILQ_FIRST(&xfer->pipe->queue)));
}
-Static usbd_status
+static usbd_status
ohci_device_bulk_start(usbd_xfer_handle xfer)
{
struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
@@ -3036,8 +2967,8 @@
sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
if (xfer->timeout && !sc->sc_bus.use_polling) {
- usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ohci_timeout, xfer);
+ callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
+ ohci_timeout, xfer);
}
#if 0
@@ -3059,7 +2990,7 @@
return (USBD_IN_PROGRESS);
}
-Static void
+static void
ohci_device_bulk_abort(usbd_xfer_handle xfer)
{
DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer));
@@ -3069,7 +3000,7 @@
/*
* Close a device bulk pipe.
*/
-Static void
+static void
ohci_device_bulk_close(usbd_pipe_handle pipe)
{
struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
@@ -3082,7 +3013,7 @@
/************************/
-Static usbd_status
+static usbd_status
ohci_device_intr_transfer(usbd_xfer_handle xfer)
{
usbd_status err;
@@ -3093,33 +3024,51 @@
return (err);
/* Pipe isn't running, start first */
- return (ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
+ return (ohci_device_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
}
-Static usbd_status
+static usbd_status
ohci_device_intr_start(usbd_xfer_handle xfer)
{
struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- usbd_device_handle dev = opipe->pipe.device;
- ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
+ ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
ohci_soft_ed_t *sed = opipe->sed;
- ohci_soft_td_t *data, *tail;
- int len;
- int s;
+ usbd_status err;
if (sc->sc_dying)
return (USBD_IOERROR);
- DPRINTFN(3, ("ohci_device_intr_transfer: xfer=%p len=%d "
+ DPRINTFN(3, ("ohci_device_intr_start: xfer=%p len=%d "
"flags=%d priv=%p\n",
xfer, xfer->length, xfer->flags, xfer->priv));
#ifdef DIAGNOSTIC
if (xfer->rqflags & URQ_REQUEST)
- panic("ohci_device_intr_transfer: a request");
+ panic("ohci_device_intr_start: a request");
#endif
- len = xfer->length;
+ err = ohci_device_intr_insert(sc, xfer);
+ if (err)
+ return (err);
+
+ sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
+
+ return (USBD_IN_PROGRESS);
+}
+
+/*
+ * Insert an interrupt transfer into an endpoint descriptor list
+ */
+static usbd_status
+ohci_device_intr_insert(ohci_softc_t *sc, usbd_xfer_handle xfer)
+{
+ struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
+ ohci_soft_ed_t *sed = opipe->sed;
+ ohci_soft_td_t *data, *tail;
+ ohci_physaddr_t dataphys, physend;
+ int s;
+
+ DPRINTFN(4, ("ohci_device_intr_insert: xfer=%p", xfer));
data = opipe->tail.td;
tail = ohci_alloc_std(sc);
@@ -3132,18 +3081,43 @@
OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
if (xfer->flags & USBD_SHORT_XFER_OK)
data->td.td_flags |= htole32(OHCI_TD_R);
- data->td.td_cbp = htole32(DMAADDR(&xfer->dmabuf, 0));
+ /*
+ * Assume a short mapping with no complications, which
+ * should always be true for <= 4k buffers in contiguous
+ * virtual memory. The data can take the following forms:
+ * 1 segment in 1 OHCI page
+ * 1 segment in 2 OHCI pages
+ * 2 segments in 2 OHCI pages
+ * (see comment in ohci_alloc_std_chain() for details)
+ */
+ KASSERT(xfer->length > 0 && xfer->length <= OHCI_PAGE_SIZE,
+ ("ohci_device_intr_insert: bad length %d", xfer->length));
+ dataphys = xfer->dmamap.segs[0].ds_addr;
+ physend = dataphys + xfer->length - 1;
+ if (xfer->dmamap.nsegs == 2) {
+ KASSERT(OHCI_PAGE_OFFSET(dataphys +
+ xfer->dmamap.segs[0].ds_len) == 0,
+ ("ohci_device_intr_insert: bad seg 0 termination"));
+ physend = xfer->dmamap.segs[1].ds_addr + xfer->length -
+ xfer->dmamap.segs[0].ds_len - 1;
+ } else {
+ KASSERT(xfer->dmamap.nsegs == 1,
+ ("ohci_device_intr_insert: bad seg count %d",
+ (u_int)xfer->dmamap.nsegs));
+ }
+ data->td.td_cbp = htole32(dataphys);
data->nexttd = tail;
data->td.td_nexttd = htole32(tail->physaddr);
- data->td.td_be = htole32(le32toh(data->td.td_cbp) + len - 1);
- data->len = len;
+ data->td.td_be = htole32(physend);
+ data->len = xfer->length;
data->xfer = xfer;
data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
xfer->hcpriv = data;
+ xfer->actlen = 0;
#ifdef USB_DEBUG
if (ohcidebug > 5) {
- DPRINTF(("ohci_device_intr_transfer:\n"));
+ DPRINTF(("ohci_device_intr_insert:\n"));
ohci_dump_ed(sed);
ohci_dump_tds(data);
}
@@ -3153,29 +3127,13 @@
s = splusb();
sed->ed.ed_tailp = htole32(tail->physaddr);
opipe->tail.td = tail;
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
-
-#if 0
-/*
- * This goes horribly wrong, printing thousands of descriptors,
- * because false references are followed due to the fact that the
- * TD is gone.
- */
- if (ohcidebug > 5) {
- usb_delay_ms(&sc->sc_bus, 5);
- DPRINTF(("ohci_device_intr_transfer: status=%x\n",
- OREAD4(sc, OHCI_COMMAND_STATUS)));
- ohci_dump_ed(sed);
- ohci_dump_tds(data);
- }
-#endif
splx(s);
- return (USBD_IN_PROGRESS);
+ return (USBD_NORMAL_COMPLETION);
}
/* Abort a device control request. */
-Static void
+static void
ohci_device_intr_abort(usbd_xfer_handle xfer)
{
if (xfer->pipe->intrxfer == xfer) {
@@ -3186,7 +3144,7 @@
}
/* Close a device interrupt pipe. */
-Static void
+static void
ohci_device_intr_close(usbd_pipe_handle pipe)
{
struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
@@ -3208,7 +3166,7 @@
if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
(le32toh(sed->ed.ed_headp) & OHCI_HEADMASK))
panic("%s: Intr pipe %p still has TDs queued",
- USBDEVNAME(sc->sc_bus.bdev), pipe);
+ device_get_nameunit(sc->sc_bus.bdev), pipe);
#endif
for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
@@ -3228,7 +3186,7 @@
ohci_free_sed(sc, opipe->sed);
}
-Static usbd_status
+static usbd_status
ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival)
{
int i, j, s, best;
@@ -3313,7 +3271,7 @@
/* and start if the pipe wasn't running */
if (!err)
- ohci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
+ ohci_device_isoc_start(STAILQ_FIRST(&xfer->pipe->queue));
return (err);
}
@@ -3326,10 +3284,10 @@
ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
ohci_soft_ed_t *sed = opipe->sed;
struct iso *iso = &opipe->u.iso;
- struct ohci_xfer *oxfer = (struct ohci_xfer *)xfer;
+ struct usb_dma_mapping *dma = &xfer->dmamap;
ohci_soft_itd_t *sitd, *nsitd;
- ohci_physaddr_t buf, offs, noffs, bp0, tdphys;
- int i, ncur, nframes;
+ ohci_physaddr_t dataphys, bp0, physend, prevpage;
+ int curlen, i, len, ncur, nframes, npages, seg, segoff;
int s;
DPRINTFN(1,("ohci_device_isoc_enter: used=%d next=%d xfer=%p "
@@ -3346,94 +3304,115 @@
iso->next));
}
- if (xfer->hcpriv) {
- for (sitd = xfer->hcpriv; sitd != NULL && sitd->xfer == xfer;
- sitd = sitd->nextitd)
- ohci_free_sitd(sc, sitd); /* Free ITDs in prev xfer*/
-
- if (sitd == NULL) {
- sitd = ohci_alloc_sitd(sc);
- if (sitd == NULL)
- panic("cant alloc isoc");
- opipe->tail.itd = sitd;
- tdphys = sitd->physaddr;
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* Stop*/
- sed->ed.ed_headp =
- sed->ed.ed_tailp = htole32(tdphys);
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* Start.*/
- }
- }
-
sitd = opipe->tail.itd;
- buf = DMAADDR(&xfer->dmabuf, 0);
- bp0 = OHCI_PAGE(buf);
- offs = OHCI_PAGE_OFFSET(buf);
nframes = xfer->nframes;
xfer->hcpriv = sitd;
- for (i = ncur = 0; i < nframes; i++, ncur++) {
- noffs = offs + xfer->frlengths[i];
- if (ncur == OHCI_ITD_NOFFSET || /* all offsets used */
- OHCI_PAGE(buf + noffs) > bp0 + OHCI_PAGE_SIZE) { /* too many page crossings */
-
- /* Allocate next ITD */
- nsitd = ohci_alloc_sitd(sc);
- if (nsitd == NULL) {
- /* XXX what now? */
- printf("%s: isoc TD alloc failed\n",
- USBDEVNAME(sc->sc_bus.bdev));
- return;
+ seg = 0;
+ segoff = 0;
+ i = 0;
+ while (i < nframes) {
+ /*
+ * Fill in as many ITD frames as possible.
+ */
+ KASSERT(seg < dma->nsegs, ("ohci_device_isoc_enter: overrun"));
+ bp0 = dma->segs[seg].ds_addr + segoff;
+ sitd->itd.itd_bp0 = htole32(bp0);
+ prevpage = OHCI_PAGE(bp0);
+ npages = 1;
+
+ ncur = 0;
+ while (ncur < OHCI_ITD_NOFFSET && i < nframes) {
+ /* Find the frame start and end physical addresses. */
+ len = xfer->frlengths[i];
+ dataphys = dma->segs[seg].ds_addr + segoff;
+ curlen = dma->segs[seg].ds_len - segoff;
+ if (len > curlen) {
+ KASSERT(seg + 1 < dma->nsegs,
+ ("ohci_device_isoc_enter: overrun2"));
+ seg++;
+ segoff = len - curlen;
+ } else {
+ segoff += len;
+ }
+ KASSERT(segoff <= dma->segs[seg].ds_len,
+ ("ohci_device_isoc_enter: overrun3"));
+ physend = dma->segs[seg].ds_addr + segoff - 1;
+
+ /* Check if there would be more than 2 pages . */
+ if (OHCI_PAGE(dataphys) != prevpage) {
+ prevpage = OHCI_PAGE(dataphys);
+ npages++;
+ }
+ if (OHCI_PAGE(physend) != prevpage) {
+ prevpage = OHCI_PAGE(physend);
+ npages++;
+ }
+ if (npages > 2) {
+ /* We cannot fit this frame now. */
+ segoff -= len;
+ if (segoff < 0) {
+ seg--;
+ segoff += dma->segs[seg].ds_len;
+ }
+ break;
}
- /* Fill current ITD */
+ sitd->itd.itd_be = htole32(physend);
+ sitd->itd.itd_offset[ncur] =
+ htole16(OHCI_ITD_MK_OFFS(OHCI_PAGE(dataphys) ==
+ OHCI_PAGE(bp0) ? 0 : 1, dataphys));
+ i++;
+ ncur++;
+ }
+ if (segoff >= dma->segs[seg].ds_len) {
+ KASSERT(segoff == dma->segs[seg].ds_len,
+ ("ohci_device_isoc_enter: overlap"));
+ seg++;
+ segoff = 0;
+ }
+
+ /* Allocate next ITD */
+ nsitd = ohci_alloc_sitd(sc);
+ if (nsitd == NULL) {
+ /* XXX what now? */
+ printf("%s: isoc TD alloc failed\n",
+ device_get_nameunit(sc->sc_bus.bdev));
+ return;
+ }
+
+ /* Fill out remaining fields of current ITD */
+ sitd->nextitd = nsitd;
+ sitd->itd.itd_nextitd = htole32(nsitd->physaddr);
+ sitd->xfer = xfer;
+ if (i < nframes) {
sitd->itd.itd_flags = htole32(
OHCI_ITD_NOCC |
OHCI_ITD_SET_SF(iso->next) |
OHCI_ITD_SET_DI(6) | /* delay intr a little */
OHCI_ITD_SET_FC(ncur));
- sitd->itd.itd_bp0 = htole32(bp0);
- sitd->nextitd = nsitd;
- sitd->itd.itd_nextitd = htole32(nsitd->physaddr);
- sitd->itd.itd_be = htole32(bp0 + offs - 1);
- sitd->xfer = xfer;
sitd->flags = OHCI_ITD_ACTIVE;
+ } else {
+ sitd->itd.itd_flags = htole32(
+ OHCI_ITD_NOCC |
+ OHCI_ITD_SET_SF(iso->next) |
+ OHCI_ITD_SET_DI(0) |
+ OHCI_ITD_SET_FC(ncur));
+ sitd->flags = OHCI_CALL_DONE | OHCI_ITD_ACTIVE;
+ }
+ iso->next += ncur;
- sitd = nsitd;
- iso->next = iso->next + ncur;
- bp0 = OHCI_PAGE(buf + offs);
- ncur = 0;
- }
- sitd->itd.itd_offset[ncur] = htole16(OHCI_ITD_MK_OFFS(offs));
- offs = noffs;
- }
- nsitd = ohci_alloc_sitd(sc);
- if (nsitd == NULL) {
- /* XXX what now? */
- printf("%s: isoc TD alloc failed\n",
- USBDEVNAME(sc->sc_bus.bdev));
- return;
+ sitd = nsitd;
}
- /* Fixup last used ITD */
- sitd->itd.itd_flags = htole32(
- OHCI_ITD_NOCC |
- OHCI_ITD_SET_SF(iso->next) |
- OHCI_ITD_SET_DI(0) |
- OHCI_ITD_SET_FC(ncur));
- sitd->itd.itd_bp0 = htole32(bp0);
- sitd->nextitd = nsitd;
- sitd->itd.itd_nextitd = htole32(nsitd->physaddr);
- sitd->itd.itd_be = htole32(bp0 + offs - 1);
- sitd->xfer = xfer;
- sitd->flags = OHCI_CALL_DONE | OHCI_ITD_ACTIVE;
- iso->next = iso->next + ncur;
iso->inuse += nframes;
- xfer->actlen = offs; /* XXX pretend we did it all */
+ /* XXX pretend we did it all */
+ xfer->actlen = 0;
+ for (i = 0; i < nframes; i++)
+ xfer->actlen += xfer->frlengths[i];
xfer->status = USBD_IN_PROGRESS;
- oxfer->ohci_xfer_flags |= OHCI_ISOC_DIRTY;
-
#ifdef USB_DEBUG
if (ohcidebug > 5) {
DPRINTF(("ohci_device_isoc_enter: frame=%d\n",
@@ -3444,9 +3423,9 @@
#endif
s = splusb();
- opipe->tail.itd = nsitd;
+ opipe->tail.itd = sitd;
sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
- sed->ed.ed_tailp = htole32(nsitd->physaddr);
+ sed->ed.ed_tailp = htole32(sitd->physaddr);
splx(s);
#ifdef USB_DEBUG
@@ -3494,7 +3473,7 @@
struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
ohci_soft_ed_t *sed;
- ohci_soft_itd_t *sitd, *tmp_sitd;
+ ohci_soft_itd_t *sitd, *sitdnext, *tmp_sitd;
int s,undone,num_sitds;
s = splusb();
@@ -3557,20 +3536,20 @@
}
} while( undone != 0 );
+ /* Free the sitds */
+ for (sitd = xfer->hcpriv; sitd->xfer == xfer;
+ sitd = sitdnext) {
+ sitdnext = sitd->nextitd;
+ ohci_free_sitd(sc, sitd);
+ }
s = splusb();
/* Run callback. */
usb_transfer_complete(xfer);
- if (sitd != NULL)
- /*
- * Only if there is a `next' sitd in next xfer...
- * unlink this xfer's sitds.
- */
- sed->ed.ed_headp = htole32(sitd->physaddr);
- else
- sed->ed.ed_headp = 0;
+ /* There is always a `next' sitd so link it up. */
+ sed->ed.ed_headp = htole32(sitd->physaddr);
sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */
Index: if_ural.c
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/if_ural.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -L sys/dev/usb/if_ural.c -L sys/dev/usb/if_ural.c -u -r1.3 -r1.4
--- sys/dev/usb/if_ural.c
+++ sys/dev/usb/if_ural.c
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/usb/if_ural.c,v 1.10.2.5 2006/01/29 14:16:36 damien Exp $ */
+/* $FreeBSD: src/sys/dev/usb/if_ural.c,v 1.69 2007/09/17 19:07:24 sam Exp $ */
/*-
* Copyright (c) 2005, 2006
@@ -18,7 +18,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/usb/if_ural.c,v 1.10.2.5 2006/01/29 14:16:36 damien Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/usb/if_ural.c,v 1.69 2007/09/17 19:07:24 sam Exp $");
/*-
* Ralink Technology RT2500USB chipset driver
@@ -39,7 +39,6 @@
#include <machine/bus.h>
#include <machine/resource.h>
-#include <machine/clock.h>
#include <sys/rman.h>
#include <net/bpf.h>
@@ -51,13 +50,9 @@
#include <net/if_types.h>
#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_radiotap.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
+#include <net80211/ieee80211_regdomain.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -68,8 +63,8 @@
#include <dev/usb/if_uralvar.h>
#ifdef USB_DEBUG
-#define DPRINTF(x) do { if (uraldebug > 0) logprintf x; } while (0)
-#define DPRINTFN(n, x) do { if (uraldebug >= (n)) logprintf x; } while (0)
+#define DPRINTF(x) do { if (uraldebug > 0) printf x; } while (0)
+#define DPRINTFN(n, x) do { if (uraldebug >= (n)) printf x; } while (0)
int uraldebug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ural, CTLFLAG_RW, 0, "USB ural");
SYSCTL_INT(_hw_usb_ural, OID_AUTO, debug, CTLFLAG_RW, &uraldebug, 0,
@@ -79,18 +74,24 @@
#define DPRINTFN(n, x)
#endif
+#define URAL_RSSI(rssi) \
+ ((rssi) > (RAL_NOISE_FLOOR + RAL_RSSI_CORR) ? \
+ ((rssi) - (RAL_NOISE_FLOOR + RAL_RSSI_CORR)) : 0)
+
/* various supported device vendors/products */
static const struct usb_devno ural_devs[] = {
{ USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL167G },
{ USB_VENDOR_ASUS, USB_PRODUCT_RALINK_RT2570 },
{ USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050 },
- { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C54U },
+ { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7051 },
+ { USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU },
{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122 },
{ USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWBKG },
+ { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GN54G },
{ USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254 },
- { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB54G },
- { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB54GP },
- { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_HU200TS },
+ { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54G },
+ { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GP },
+ { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_HU200TS },
{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54 },
{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54AI },
{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54YB },
@@ -98,91 +99,90 @@
{ USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570 },
{ USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_2 },
{ USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_3 },
+ { USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_NV902 },
{ USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570 },
{ USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_2 },
+ { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_3 },
+ { USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WL54G },
+ { USB_VENDOR_SMC, USB_PRODUCT_SMC_2862WG },
+ { USB_VENDOR_SPHAIRON, USB_PRODUCT_SPHAIRON_UB801R},
+ { USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2570 },
{ USB_VENDOR_VTECH, USB_PRODUCT_VTECH_RT2570 },
{ USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2570 }
};
MODULE_DEPEND(ural, wlan, 1, 1, 1);
+MODULE_DEPEND(ural, wlan_amrr, 1, 1, 1);
+MODULE_DEPEND(ural, usb, 1, 1, 1);
-Static int ural_alloc_tx_list(struct ural_softc *);
-Static void ural_free_tx_list(struct ural_softc *);
-Static int ural_alloc_rx_list(struct ural_softc *);
-Static void ural_free_rx_list(struct ural_softc *);
-Static int ural_media_change(struct ifnet *);
-Static void ural_next_scan(void *);
-Static void ural_task(void *);
-Static int ural_newstate(struct ieee80211com *,
+static int ural_alloc_tx_list(struct ural_softc *);
+static void ural_free_tx_list(struct ural_softc *);
+static int ural_alloc_rx_list(struct ural_softc *);
+static void ural_free_rx_list(struct ural_softc *);
+static int ural_media_change(struct ifnet *);
+static void ural_task(void *);
+static void ural_scantask(void *);
+static int ural_newstate(struct ieee80211com *,
enum ieee80211_state, int);
-Static int ural_rxrate(struct ural_rx_desc *);
-Static void ural_txeof(usbd_xfer_handle, usbd_private_handle,
+static int ural_rxrate(struct ural_rx_desc *);
+static void ural_txeof(usbd_xfer_handle, usbd_private_handle,
usbd_status);
-Static void ural_rxeof(usbd_xfer_handle, usbd_private_handle,
+static void ural_rxeof(usbd_xfer_handle, usbd_private_handle,
usbd_status);
-Static int ural_ack_rate(struct ieee80211com *, int);
-Static uint16_t ural_txtime(int, int, uint32_t);
-Static uint8_t ural_plcp_signal(int);
-Static void ural_setup_tx_desc(struct ural_softc *,
+static int ural_ack_rate(struct ieee80211com *, int);
+static uint16_t ural_txtime(int, int, uint32_t);
+static uint8_t ural_plcp_signal(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 *,
+static int ural_tx_bcn(struct ural_softc *, struct mbuf *,
struct ieee80211_node *);
-Static int ural_tx_mgt(struct ural_softc *, struct mbuf *,
+static int ural_tx_mgt(struct ural_softc *, struct mbuf *,
struct ieee80211_node *);
-Static int ural_tx_data(struct ural_softc *, struct mbuf *,
+static int ural_tx_data(struct ural_softc *, struct mbuf *,
struct ieee80211_node *);
-Static void ural_start(struct ifnet *);
-Static void ural_watchdog(struct ifnet *);
-Static int ural_reset(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 *,
+static void ural_start(struct ifnet *);
+static void ural_watchdog(void *);
+static int ural_reset(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 *,
+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);
-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 void ural_set_chan(struct ural_softc *,
+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 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 *);
-Static void ural_set_bssid(struct ural_softc *, uint8_t *);
-Static void ural_set_macaddr(struct ural_softc *, uint8_t *);
-Static void ural_update_promisc(struct ural_softc *);
-Static const char *ural_get_rf(int);
-Static void ural_read_eeprom(struct ural_softc *);
-Static int ural_bbp_init(struct ural_softc *);
-Static void ural_set_txantenna(struct ural_softc *, int);
-Static void ural_set_rxantenna(struct ural_softc *, int);
-Static void ural_init(void *);
-Static void ural_stop(void *);
-Static void ural_amrr_start(struct ural_softc *,
+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 *);
+static void ural_set_bssid(struct ural_softc *, const uint8_t *);
+static void ural_set_macaddr(struct ural_softc *, uint8_t *);
+static void ural_update_promisc(struct ural_softc *);
+static const char *ural_get_rf(int);
+static void ural_read_eeprom(struct ural_softc *);
+static int ural_bbp_init(struct ural_softc *);
+static void ural_set_txantenna(struct ural_softc *, int);
+static void ural_set_rxantenna(struct ural_softc *, int);
+static void ural_init(void *);
+static void ural_stop(void *);
+static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *,
+ const struct ieee80211_bpf_params *);
+static void ural_amrr_start(struct ural_softc *,
struct ieee80211_node *);
-Static void ural_amrr_timeout(void *);
-Static void ural_amrr_update(usbd_xfer_handle, usbd_private_handle,
+static void ural_amrr_timeout(void *);
+static void ural_amrr_update(usbd_xfer_handle, usbd_private_handle,
usbd_status status);
-Static void ural_ratectl(struct ural_amrr *,
- struct ieee80211_node *);
-
-/*
- * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
- */
-static const struct ieee80211_rateset ural_rateset_11a =
- { 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
-
-static const struct ieee80211_rateset ural_rateset_11b =
- { 4, { 2, 4, 11, 22 } };
-
-static const struct ieee80211_rateset ural_rateset_11g =
- { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
/*
* Default values for MAC registers; values taken from the reference driver.
@@ -346,11 +346,33 @@
{ 161, 0x08808, 0x0242f, 0x00281 }
};
-USB_DECLARE_DRIVER(ural);
+static device_probe_t ural_match;
+static device_attach_t ural_attach;
+static device_detach_t ural_detach;
+
+static device_method_t ural_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ural_match),
+ DEVMETHOD(device_attach, ural_attach),
+ DEVMETHOD(device_detach, ural_detach),
+
+ { 0, 0 }
+};
+
+static driver_t ural_driver = {
+ "ural",
+ ural_methods,
+ sizeof(struct ural_softc)
+};
+
+static devclass_t ural_devclass;
-USB_MATCH(ural)
+DRIVER_MODULE(ural, uhub, ural_driver, ural_devclass, usbd_driver_load, 0);
+
+static int
+ural_match(device_t self)
{
- USB_MATCH_START(ural, uaa);
+ struct usb_attach_arg *uaa = device_get_ivars(self);
if (uaa->iface != NULL)
return UMATCH_NONE;
@@ -359,26 +381,25 @@
UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
}
-USB_ATTACH(ural)
+static int
+ural_attach(device_t self)
{
- USB_ATTACH_START(ural, sc, uaa);
+ struct ural_softc *sc = device_get_softc(self);
+ struct usb_attach_arg *uaa = device_get_ivars(self);
struct ifnet *ifp;
struct ieee80211com *ic = &sc->sc_ic;
usb_interface_descriptor_t *id;
usb_endpoint_descriptor_t *ed;
usbd_status error;
- char devinfo[1024];
- int i;
+ int i, bands;
sc->sc_udev = uaa->device;
-
- usbd_devinfo(sc->sc_udev, 0, devinfo);
- USB_ATTACH_SETUP;
+ sc->sc_dev = self;
if (usbd_set_config_no(sc->sc_udev, RAL_CONFIG_NO, 0) != 0) {
printf("%s: could not set configuration no\n",
- USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
+ device_get_nameunit(sc->sc_dev));
+ return ENXIO;
}
/* get the first interface handle */
@@ -386,8 +407,8 @@
&sc->sc_iface);
if (error != 0) {
printf("%s: could not get interface handle\n",
- USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
+ device_get_nameunit(sc->sc_dev));
+ return ENXIO;
}
/*
@@ -400,8 +421,8 @@
ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
if (ed == NULL) {
printf("%s: no endpoint descriptor for %d\n",
- USBDEVNAME(sc->sc_dev), i);
- USB_ATTACH_ERROR_RETURN;
+ device_get_nameunit(sc->sc_dev), i);
+ return ENXIO;
}
if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
@@ -412,15 +433,17 @@
sc->sc_tx_no = ed->bEndpointAddress;
}
if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) {
- printf("%s: missing endpoint\n", USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
+ printf("%s: missing endpoint\n",
+ device_get_nameunit(sc->sc_dev));
+ return ENXIO;
}
- mtx_init(&sc->sc_mtx, USBDEVNAME(sc->sc_dev), MTX_NETWORK_LOCK,
+ mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
usb_init_task(&sc->sc_task, ural_task, sc);
- callout_init(&sc->scan_ch, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
+ usb_init_task(&sc->sc_scantask, ural_scantask, sc);
+ callout_init(&sc->watchdog_ch, 0);
callout_init(&sc->amrr_ch, 0);
/* retrieve RT2570 rev. no */
@@ -430,22 +453,23 @@
ural_read_eeprom(sc);
printf("%s: MAC/BBP RT2570 (rev 0x%02x), RF %s\n",
- USBDEVNAME(sc->sc_dev), sc->asic_rev, ural_get_rf(sc->rf_rev));
+ device_get_nameunit(sc->sc_dev), sc->asic_rev,
+ ural_get_rf(sc->rf_rev));
ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
if (ifp == NULL) {
- printf("%s: can not if_alloc()\n", USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
+ printf("%s: can not if_alloc()\n",
+ device_get_nameunit(sc->sc_dev));
+ return ENXIO;
}
ifp->if_softc = sc;
- if_initname(ifp, "ural", USBDEVUNIT(sc->sc_dev));
+ if_initname(ifp, "ural", device_get_unit(sc->sc_dev));
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
IFF_NEEDSGIANT; /* USB stack is still under Giant lock */
ifp->if_init = ural_init;
ifp->if_ioctl = ural_ioctl;
ifp->if_start = ural_start;
- ifp->if_watchdog = ural_watchdog;
IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
IFQ_SET_READY(&ifp->if_snd);
@@ -457,59 +481,41 @@
/* set device capabilities */
ic->ic_caps =
- 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_WPA; /* 802.11i */
-
- if (sc->rf_rev == RAL_RF_5222) {
- /* set supported .11a rates */
- ic->ic_sup_rates[IEEE80211_MODE_11A] = ural_rateset_11a;
-
- /* set supported .11a channels */
- for (i = 36; i <= 64; i += 4) {
- ic->ic_channels[i].ic_freq =
- ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
- ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
- }
- for (i = 100; i <= 140; i += 4) {
- ic->ic_channels[i].ic_freq =
- ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
- ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
- }
- for (i = 149; i <= 161; i += 4) {
- ic->ic_channels[i].ic_freq =
- ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
- ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
- }
- }
-
- /* set supported .11b and .11g rates */
- ic->ic_sup_rates[IEEE80211_MODE_11B] = ural_rateset_11b;
- ic->ic_sup_rates[IEEE80211_MODE_11G] = ural_rateset_11g;
-
- /* set supported .11b and .11g channels (1 through 14) */
- for (i = 1; i <= 14; i++) {
- ic->ic_channels[i].ic_freq =
- ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
- ic->ic_channels[i].ic_flags =
- IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
- IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
- }
+ 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, 0, CTRY_DEFAULT, bands, 0, 1);
ieee80211_ifattach(ic);
ic->ic_reset = ural_reset;
/* enable s/w bmiss handling in sta mode */
ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;
+ ic->ic_scan_start = ural_scan_start;
+ ic->ic_scan_end = ural_scan_end;
+ ic->ic_set_channel = ural_set_channel;
/* override state transition machine */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = ural_newstate;
+ ic->ic_raw_xmit = ural_raw_xmit;
ieee80211_media_init(ic, ural_media_change, ieee80211_media_status);
+ ieee80211_amrr_init(&sc->amrr, ic,
+ IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
+ IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD);
+
bpfattach2(ifp, DLT_IEEE802_11_RADIO,
sizeof (struct ieee80211_frame) + 64, &sc->sc_drvbpf);
@@ -524,18 +530,19 @@
if (bootverbose)
ieee80211_announce(ic);
- USB_ATTACH_SUCCESS_RETURN;
+ return 0;
}
-USB_DETACH(ural)
+static int
+ural_detach(device_t self)
{
- USB_DETACH_START(ural, sc);
+ struct ural_softc *sc = device_get_softc(self);
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = ic->ic_ifp;
ural_stop(sc);
usb_rem_task(sc->sc_udev, &sc->sc_task);
- callout_stop(&sc->scan_ch);
+ callout_stop(&sc->watchdog_ch);
callout_stop(&sc->amrr_ch);
if (sc->amrr_xfer != NULL) {
@@ -565,7 +572,7 @@
return 0;
}
-Static int
+static int
ural_alloc_tx_list(struct ural_softc *sc)
{
struct ural_tx_data *data;
@@ -581,7 +588,7 @@
data->xfer = usbd_alloc_xfer(sc->sc_udev);
if (data->xfer == NULL) {
printf("%s: could not allocate tx xfer\n",
- USBDEVNAME(sc->sc_dev));
+ device_get_nameunit(sc->sc_dev));
error = ENOMEM;
goto fail;
}
@@ -590,7 +597,7 @@
RAL_TX_DESC_SIZE + MCLBYTES);
if (data->buf == NULL) {
printf("%s: could not allocate tx buffer\n",
- USBDEVNAME(sc->sc_dev));
+ device_get_nameunit(sc->sc_dev));
error = ENOMEM;
goto fail;
}
@@ -602,7 +609,7 @@
return error;
}
-Static void
+static void
ural_free_tx_list(struct ural_softc *sc)
{
struct ural_tx_data *data;
@@ -623,7 +630,7 @@
}
}
-Static int
+static int
ural_alloc_rx_list(struct ural_softc *sc)
{
struct ural_rx_data *data;
@@ -637,14 +644,14 @@
data->xfer = usbd_alloc_xfer(sc->sc_udev);
if (data->xfer == NULL) {
printf("%s: could not allocate rx xfer\n",
- USBDEVNAME(sc->sc_dev));
+ device_get_nameunit(sc->sc_dev));
error = ENOMEM;
goto fail;
}
if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) {
printf("%s: could not allocate rx buffer\n",
- USBDEVNAME(sc->sc_dev));
+ device_get_nameunit(sc->sc_dev));
error = ENOMEM;
goto fail;
}
@@ -652,7 +659,7 @@
data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
if (data->m == NULL) {
printf("%s: could not allocate rx mbuf\n",
- USBDEVNAME(sc->sc_dev));
+ device_get_nameunit(sc->sc_dev));
error = ENOMEM;
goto fail;
}
@@ -666,7 +673,7 @@
return error;
}
-Static void
+static void
ural_free_rx_list(struct ural_softc *sc)
{
struct ural_rx_data *data;
@@ -687,7 +694,7 @@
}
}
-Static int
+static int
ural_media_change(struct ifnet *ifp)
{
struct ural_softc *sc = ifp->if_softc;
@@ -710,24 +717,10 @@
return 0;
}
-/*
- * This function is called periodically (every 200ms) during scanning to
- * switch from one channel to another.
- */
-Static void
-ural_next_scan(void *arg)
+static void
+ural_task(void *xarg)
{
- struct ural_softc *sc = arg;
- struct ieee80211com *ic = &sc->sc_ic;
-
- if (ic->ic_state == IEEE80211_S_SCAN)
- ieee80211_next_scan(ic);
-}
-
-Static void
-ural_task(void *arg)
-{
- struct ural_softc *sc = arg;
+ struct ural_softc *sc = xarg;
struct ieee80211com *ic = &sc->sc_ic;
enum ieee80211_state ostate;
struct ieee80211_node *ni;
@@ -735,6 +728,7 @@
ostate = ic->ic_state;
+ RAL_LOCK(sc);
switch (sc->sc_state) {
case IEEE80211_S_INIT:
if (ostate == IEEE80211_S_RUN) {
@@ -746,22 +740,7 @@
}
break;
- case IEEE80211_S_SCAN:
- ural_set_chan(sc, ic->ic_curchan);
- callout_reset(&sc->scan_ch, hz / 5, ural_next_scan, sc);
- break;
-
- case IEEE80211_S_AUTH:
- ural_set_chan(sc, ic->ic_curchan);
- break;
-
- case IEEE80211_S_ASSOC:
- ural_set_chan(sc, ic->ic_curchan);
- break;
-
case IEEE80211_S_RUN:
- ural_set_chan(sc, ic->ic_curchan);
-
ni = ic->ic_bss;
if (ic->ic_opmode != IEEE80211_M_MONITOR) {
@@ -773,16 +752,16 @@
if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
ic->ic_opmode == IEEE80211_M_IBSS) {
- m = ieee80211_beacon_alloc(ic, ni, &sc->sc_bo);
+ m = ieee80211_beacon_alloc(ni, &sc->sc_bo);
if (m == NULL) {
printf("%s: could not allocate beacon\n",
- USBDEVNAME(sc->sc_dev));
+ device_get_nameunit(sc->sc_dev));
return;
}
if (ural_tx_bcn(sc, m, ni) != 0) {
printf("%s: could not send beacon\n",
- USBDEVNAME(sc->sc_dev));
+ device_get_nameunit(sc->sc_dev));
return;
}
}
@@ -799,24 +778,55 @@
ural_amrr_start(sc, ni);
break;
+
+ default:
+ break;
}
- sc->sc_newstate(ic, sc->sc_state, -1);
+ RAL_UNLOCK(sc);
+ sc->sc_newstate(ic, sc->sc_state, sc->sc_arg);
}
-Static int
+static void
+ural_scantask(void *arg)
+{
+ struct ural_softc *sc = arg;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = ic->ic_ifp;
+
+ RAL_LOCK(sc);
+ if (sc->sc_scan_action == URAL_SCAN_START) {
+ /* abort TSF synchronization */
+ ural_write(sc, RAL_TXRX_CSR19, 0);
+ ural_set_bssid(sc, ifp->if_broadcastaddr);
+ } else if (sc->sc_scan_action == URAL_SET_CHANNEL) {
+ mtx_lock(&Giant);
+ ural_set_chan(sc, ic->ic_curchan);
+ mtx_unlock(&Giant);
+ } else {
+ ural_enable_tsf_sync(sc);
+ /* XXX keep local copy */
+ ural_set_bssid(sc, ic->ic_bss->ni_bssid);
+ }
+ RAL_UNLOCK(sc);
+}
+
+static int
ural_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
{
struct ural_softc *sc = ic->ic_ifp->if_softc;
- usb_rem_task(sc->sc_udev, &sc->sc_task);
- callout_stop(&sc->scan_ch);
callout_stop(&sc->amrr_ch);
/* do it in a process context */
sc->sc_state = nstate;
- usb_add_task(sc->sc_udev, &sc->sc_task);
+ sc->sc_arg = arg;
+ usb_rem_task(sc->sc_udev, &sc->sc_task);
+ if (nstate == IEEE80211_S_INIT)
+ sc->sc_newstate(ic, nstate, arg);
+ else
+ usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
return 0;
}
@@ -833,7 +843,7 @@
/*
* This function is only used by the Rx radiotap code.
*/
-Static int
+static int
ural_rxrate(struct ural_rx_desc *desc)
{
if (le32toh(desc->flags) & RAL_RX_OFDM) {
@@ -861,24 +871,28 @@
return 2; /* should not get there */
}
-Static void
+static void
ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct ural_tx_data *data = priv;
struct ural_softc *sc = data->sc;
struct ifnet *ifp = sc->sc_ic.ic_ifp;
+ if (data->m->m_flags & M_TXCB)
+ ieee80211_process_callback(data->ni, data->m,
+ status == USBD_NORMAL_COMPLETION ? 0 : ETIMEDOUT);
if (status != USBD_NORMAL_COMPLETION) {
if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
return;
printf("%s: could not transmit buffer: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(status));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(status));
if (status == USBD_STALLED)
usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
ifp->if_oerrors++;
+ /* XXX mbuf leak? */
return;
}
@@ -897,7 +911,7 @@
ural_start(ifp);
}
-Static void
+static void
ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct ural_rx_data *data = priv;
@@ -922,7 +936,7 @@
usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
if (len < RAL_RX_DESC_SIZE + IEEE80211_MIN_LEN) {
- DPRINTF(("%s: xfer too short %d\n", USBDEVNAME(sc->sc_dev),
+ DPRINTF(("%s: xfer too short %d\n", device_get_nameunit(sc->sc_dev),
len));
ifp->if_ierrors++;
goto skip;
@@ -955,9 +969,8 @@
/* finalize mbuf */
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff;
- m->m_flags |= M_HASFCS; /* h/w leaves FCS */
- if (sc->sc_drvbpf != NULL) {
+ if (bpf_peers_present(sc->sc_drvbpf)) {
struct ural_rx_radiotap_header *tap = &sc->sc_rxtap;
tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
@@ -965,16 +978,19 @@
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 = desc->rssi;
+ tap->wr_antsignal = URAL_RSSI(desc->rssi);
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
}
+ /* Strip trailing 802.11 MAC FCS. */
+ m_adj(m, -IEEE80211_CRC_LEN);
+
wh = mtod(m, struct ieee80211_frame *);
ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
/* send the frame to the 802.11 layer */
- ieee80211_input(ic, m, ni, desc->rssi, 0);
+ ieee80211_input(ic, m, ni, URAL_RSSI(desc->rssi), RAL_NOISE_FLOOR, 0);
/* node is no longer needed */
ieee80211_free_node(ni);
@@ -991,7 +1007,7 @@
* Return the expected ack rate for a frame transmitted at rate `rate'.
* XXX: this should depend on the destination node basic rate set.
*/
-Static int
+static int
ural_ack_rate(struct ieee80211com *ic, int rate)
{
switch (rate) {
@@ -1026,7 +1042,7 @@
* The function automatically determines the operating mode depending on the
* given rate. `flags' indicates whether short preamble is in use or not.
*/
-Static uint16_t
+static uint16_t
ural_txtime(int len, int rate, uint32_t flags)
{
uint16_t txtime;
@@ -1046,7 +1062,7 @@
return txtime;
}
-Static uint8_t
+static uint8_t
ural_plcp_signal(int rate)
{
switch (rate) {
@@ -1071,7 +1087,7 @@
}
}
-Static void
+static void
ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc,
uint32_t flags, int len, int rate)
{
@@ -1117,7 +1133,7 @@
#define RAL_TX_TIMEOUT 5000
-Static int
+static int
ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ural_tx_desc *desc;
@@ -1169,7 +1185,7 @@
return error;
}
-Static int
+static int
ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1205,7 +1221,7 @@
flags |= RAL_TX_TIMESTAMP;
}
- if (sc->sc_drvbpf != NULL) {
+ if (bpf_peers_present(sc->sc_drvbpf)) {
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
@@ -1238,15 +1254,93 @@
ural_txeof);
error = usbd_transfer(data->xfer);
- if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS)
+ if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
+ m_freem(m0);
+ data->m = NULL;
+ data->ni = NULL;
return error;
+ }
sc->tx_queued++;
return 0;
}
-Static int
+static int
+ural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
+ const struct ieee80211_bpf_params *params)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ural_tx_desc *desc;
+ struct ural_tx_data *data;
+ uint32_t flags;
+ usbd_status error;
+ int xferlen, rate;
+
+ data = &sc->tx_data[0];
+ desc = (struct ural_tx_desc *)data->buf;
+
+ rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
+ /* XXX validate */
+ if (rate == 0) {
+ m_freem(m0);
+ return EINVAL;
+ }
+
+ if (bpf_peers_present(sc->sc_drvbpf)) {
+ struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
+
+ tap->wt_flags = 0;
+ tap->wt_rate = rate;
+ tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+ tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
+ tap->wt_antenna = sc->tx_ant;
+
+ bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
+ }
+
+ data->m = m0;
+ data->ni = ni;
+
+ flags = 0;
+ if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
+ flags |= RAL_TX_ACK;
+
+ m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE);
+ /* XXX need to setup descriptor ourself */
+ ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate);
+
+ /* align end on a 2-bytes boundary */
+ xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1;
+
+ /*
+ * No space left in the last URB to store the extra 2 bytes, force
+ * sending of another URB.
+ */
+ if ((xferlen % 64) == 0)
+ xferlen += 2;
+
+ DPRINTFN(10, ("sending raw frame len=%u rate=%u xfer len=%u\n",
+ m0->m_pkthdr.len, rate, xferlen));
+
+ usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf,
+ xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT,
+ ural_txeof);
+
+ error = usbd_transfer(data->xfer);
+ if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
+ m_freem(m0);
+ data->m = NULL;
+ data->ni = NULL;
+ return error;
+ }
+
+ sc->tx_queued++;
+
+ return 0;
+}
+
+static int
ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1262,7 +1356,7 @@
wh = mtod(m0, struct ieee80211_frame *);
if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
- rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_fixed_rate];
+ rate = ic->ic_fixed_rate;
else
rate = ni->ni_rates.rs_rates[ni->ni_txrate];
@@ -1294,7 +1388,7 @@
*(uint16_t *)wh->i_dur = htole16(dur);
}
- if (sc->sc_drvbpf != NULL) {
+ if (bpf_peers_present(sc->sc_drvbpf)) {
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
@@ -1327,15 +1421,19 @@
ural_txeof);
error = usbd_transfer(data->xfer);
- if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS)
+ if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
+ m_freem(m0);
+ data->m = NULL;
+ data->ni = NULL;
return error;
+ }
sc->tx_queued++;
return 0;
}
-Static void
+static void
ural_start(struct ifnet *ifp)
{
struct ural_softc *sc = ifp->if_softc;
@@ -1356,12 +1454,13 @@
ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
m0->m_pkthdr.rcvif = NULL;
- if (ic->ic_rawbpf != NULL)
+ if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
- if (ural_tx_mgt(sc, m0, ni) != 0)
+ if (ural_tx_mgt(sc, m0, ni) != 0) {
+ ieee80211_free_node(ni);
break;
-
+ }
} else {
if (ic->ic_state != IEEE80211_S_RUN)
break;
@@ -1373,6 +1472,11 @@
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
+ /*
+ * Cancel any background scan.
+ */
+ if (ic->ic_flags & IEEE80211_F_SCAN)
+ ieee80211_cancel_scan(ic);
if (m0->m_len < sizeof (struct ether_header) &&
!(m0 = m_pullup(m0, sizeof (struct ether_header))))
@@ -1392,7 +1496,7 @@
continue;
}
- if (ic->ic_rawbpf != NULL)
+ if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
if (ural_tx_data(sc, m0, ni) != 0) {
@@ -1403,33 +1507,29 @@
}
sc->sc_tx_timer = 5;
- ifp->if_timer = 1;
+ ic->ic_lastdata = ticks;
+ callout_reset(&sc->watchdog_ch, hz, ural_watchdog, sc);
}
}
-Static void
-ural_watchdog(struct ifnet *ifp)
+static void
+ural_watchdog(void *arg)
{
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ural_softc *sc = (struct ural_softc *)arg;
RAL_LOCK(sc);
- ifp->if_timer = 0;
-
if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) {
device_printf(sc->sc_dev, "device timeout\n");
/*ural_init(sc); XXX needs a process context! */
- ifp->if_oerrors++;
+ sc->sc_ifp->if_oerrors++;
RAL_UNLOCK(sc);
return;
}
- ifp->if_timer = 1;
+ callout_reset(&sc->watchdog_ch, hz, ural_watchdog, sc);
}
- ieee80211_watchdog(ic);
-
RAL_UNLOCK(sc);
}
@@ -1438,7 +1538,7 @@
* net-mgmt/kismet). In IBSS mode, we must explicitly reset the interface to
* generate a new beacon frame.
*/
-Static int
+static int
ural_reset(struct ifnet *ifp)
{
struct ural_softc *sc = ifp->if_softc;
@@ -1452,7 +1552,7 @@
return 0;
}
-Static int
+static int
ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
struct ural_softc *sc = ifp->if_softc;
@@ -1491,7 +1591,7 @@
return error;
}
-Static void
+static void
ural_set_testmode(struct ural_softc *sc)
{
usb_device_request_t req;
@@ -1506,11 +1606,11 @@
error = usbd_do_request(sc->sc_udev, &req, NULL);
if (error != 0) {
printf("%s: could not set test mode: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(error));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(error));
}
}
-Static void
+static void
ural_eeprom_read(struct ural_softc *sc, uint16_t addr, void *buf, int len)
{
usb_device_request_t req;
@@ -1525,11 +1625,11 @@
error = usbd_do_request(sc->sc_udev, &req, buf);
if (error != 0) {
printf("%s: could not read EEPROM: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(error));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(error));
}
}
-Static uint16_t
+static uint16_t
ural_read(struct ural_softc *sc, uint16_t reg)
{
usb_device_request_t req;
@@ -1545,14 +1645,14 @@
error = usbd_do_request(sc->sc_udev, &req, &val);
if (error != 0) {
printf("%s: could not read MAC register: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(error));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(error));
return 0;
}
return le16toh(val);
}
-Static void
+static void
ural_read_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len)
{
usb_device_request_t req;
@@ -1567,11 +1667,11 @@
error = usbd_do_request(sc->sc_udev, &req, buf);
if (error != 0) {
printf("%s: could not read MAC register: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(error));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(error));
}
}
-Static void
+static void
ural_write(struct ural_softc *sc, uint16_t reg, uint16_t val)
{
usb_device_request_t req;
@@ -1586,11 +1686,11 @@
error = usbd_do_request(sc->sc_udev, &req, NULL);
if (error != 0) {
printf("%s: could not write MAC register: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(error));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(error));
}
}
-Static void
+static void
ural_write_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len)
{
usb_device_request_t req;
@@ -1605,11 +1705,11 @@
error = usbd_do_request(sc->sc_udev, &req, buf);
if (error != 0) {
printf("%s: could not write MAC register: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(error));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(error));
}
}
-Static void
+static void
ural_bbp_write(struct ural_softc *sc, uint8_t reg, uint8_t val)
{
uint16_t tmp;
@@ -1620,7 +1720,7 @@
break;
}
if (ntries == 5) {
- printf("%s: could not write to BBP\n", USBDEVNAME(sc->sc_dev));
+ printf("%s: could not write to BBP\n", device_get_nameunit(sc->sc_dev));
return;
}
@@ -1628,7 +1728,7 @@
ural_write(sc, RAL_PHY_CSR7, tmp);
}
-Static uint8_t
+static uint8_t
ural_bbp_read(struct ural_softc *sc, uint8_t reg)
{
uint16_t val;
@@ -1642,14 +1742,14 @@
break;
}
if (ntries == 5) {
- printf("%s: could not read BBP\n", USBDEVNAME(sc->sc_dev));
+ printf("%s: could not read BBP\n", device_get_nameunit(sc->sc_dev));
return 0;
}
return ural_read(sc, RAL_PHY_CSR7) & 0xff;
}
-Static void
+static void
ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val)
{
uint32_t tmp;
@@ -1660,7 +1760,7 @@
break;
}
if (ntries == 5) {
- printf("%s: could not write to RF\n", USBDEVNAME(sc->sc_dev));
+ printf("%s: could not write to RF\n", device_get_nameunit(sc->sc_dev));
return;
}
@@ -1674,7 +1774,46 @@
DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff));
}
-Static void
+static void
+ural_scan_start(struct ieee80211com *ic)
+{
+ struct ural_softc *sc = ic->ic_ifp->if_softc;
+
+ usb_rem_task(sc->sc_udev, &sc->sc_scantask);
+
+ /* do it in a process context */
+ sc->sc_scan_action = URAL_SCAN_START;
+ usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
+
+}
+
+static void
+ural_scan_end(struct ieee80211com *ic)
+{
+ struct ural_softc *sc = ic->ic_ifp->if_softc;
+
+ usb_rem_task(sc->sc_udev, &sc->sc_scantask);
+
+ /* do it in a process context */
+ sc->sc_scan_action = URAL_SCAN_END;
+ usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
+
+}
+
+static void
+ural_set_channel(struct ieee80211com *ic)
+{
+
+ struct ural_softc *sc = ic->ic_ifp->if_softc;
+
+ usb_rem_task(sc->sc_udev, &sc->sc_scantask);
+
+ /* do it in a process context */
+ sc->sc_scan_action = URAL_SET_CHANNEL;
+ usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
+}
+
+static void
ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1747,7 +1886,7 @@
/* dual-band RF */
case RAL_RF_5222:
- for (i = 0; i < ural_rf5222[i].chan != chan; i++);
+ 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);
@@ -1757,7 +1896,7 @@
}
if (ic->ic_opmode != IEEE80211_M_MONITOR &&
- ic->ic_state != IEEE80211_S_SCAN) {
+ (ic->ic_flags & IEEE80211_F_SCAN) == 0) {
/* set Japan filter bit for channel 14 */
tmp = ural_bbp_read(sc, 70);
@@ -1773,12 +1912,24 @@
DELAY(10000);
ural_disable_rf_tune(sc);
}
+
+ /* update basic rate set */
+ if (IEEE80211_IS_CHAN_B(c)) {
+ /* 11b basic rates: 1, 2Mbps */
+ ural_write(sc, RAL_TXRX_CSR11, 0x3);
+ } else if (IEEE80211_IS_CHAN_A(c)) {
+ /* 11a basic rates: 6, 12, 24Mbps */
+ ural_write(sc, RAL_TXRX_CSR11, 0x150);
+ } else {
+ /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
+ ural_write(sc, RAL_TXRX_CSR11, 0x15f);
+ }
}
/*
* Disable RF auto-tuning.
*/
-Static void
+static void
ural_disable_rf_tune(struct ural_softc *sc)
{
uint32_t tmp;
@@ -1798,7 +1949,7 @@
* Refer to IEEE Std 802.11-1999 pp. 123 for more information on TSF
* synchronization.
*/
-Static void
+static void
ural_enable_tsf_sync(struct ural_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1826,7 +1977,7 @@
DPRINTF(("enabling TSF synchronization\n"));
}
-Static void
+static void
ural_update_slot(struct ifnet *ifp)
{
struct ural_softc *sc = ifp->if_softc;
@@ -1852,7 +2003,7 @@
ural_write(sc, RAL_MAC_CSR12, eifs);
}
-Static void
+static void
ural_set_txpreamble(struct ural_softc *sc)
{
uint16_t tmp;
@@ -1866,7 +2017,7 @@
ural_write(sc, RAL_TXRX_CSR10, tmp);
}
-Static void
+static void
ural_set_basicrates(struct ural_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1884,8 +2035,8 @@
}
}
-Static void
-ural_set_bssid(struct ural_softc *sc, uint8_t *bssid)
+static void
+ural_set_bssid(struct ural_softc *sc, const uint8_t *bssid)
{
uint16_t tmp;
@@ -1901,7 +2052,7 @@
DPRINTF(("setting BSSID to %6D\n", bssid, ":"));
}
-Static void
+static void
ural_set_macaddr(struct ural_softc *sc, uint8_t *addr)
{
uint16_t tmp;
@@ -1918,7 +2069,7 @@
DPRINTF(("setting MAC address to %6D\n", addr, ":"));
}
-Static void
+static void
ural_update_promisc(struct ural_softc *sc)
{
struct ifnet *ifp = sc->sc_ic.ic_ifp;
@@ -1936,7 +2087,7 @@
"entering" : "leaving"));
}
-Static const char *
+static const char *
ural_get_rf(int rev)
{
switch (rev) {
@@ -1951,7 +2102,7 @@
}
}
-Static void
+static void
ural_read_eeprom(struct ural_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1976,7 +2127,7 @@
ural_eeprom_read(sc, RAL_EEPROM_TXPOWER, sc->txpow, 14);
}
-Static int
+static int
ural_bbp_init(struct ural_softc *sc)
{
#define N(a) (sizeof (a) / sizeof ((a)[0]))
@@ -2010,7 +2161,7 @@
#undef N
}
-Static void
+static void
ural_set_txantenna(struct ural_softc *sc, int antenna)
{
uint16_t tmp;
@@ -2039,7 +2190,7 @@
ural_write(sc, RAL_PHY_CSR6, tmp | (tx & 0x7));
}
-Static void
+static void
ural_set_rxantenna(struct ural_softc *sc, int antenna)
{
uint8_t rx;
@@ -2059,14 +2210,13 @@
ural_bbp_write(sc, RAL_BBP_RX, rx);
}
-Static void
+static void
ural_init(void *priv)
{
#define N(a) (sizeof (a) / sizeof ((a)[0]))
struct ural_softc *sc = priv;
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = ic->ic_ifp;
- struct ieee80211_key *wk;
struct ural_rx_data *data;
uint16_t tmp;
usbd_status error;
@@ -2091,7 +2241,7 @@
}
if (ntries == 100) {
printf("%s: timeout waiting for BBP/RF to wakeup\n",
- USBDEVNAME(sc->sc_dev));
+ device_get_nameunit(sc->sc_dev));
goto fail;
}
@@ -2104,7 +2254,6 @@
if (ural_bbp_init(sc) != 0)
goto fail;
- /* set default BSS channel */
ural_set_chan(sc, ic->ic_curchan);
/* clear statistic registers (STA_CSR0 to STA_CSR10) */
@@ -2117,21 +2266,12 @@
ural_set_macaddr(sc, ic->ic_myaddr);
/*
- * Copy WEP keys into adapter's memory (SEC_CSR0 to SEC_CSR31).
- */
- for (i = 0; i < IEEE80211_WEP_NKID; i++) {
- wk = &ic->ic_crypto.cs_nw_keys[i];
- ural_write_multi(sc, wk->wk_keyix * IEEE80211_KEYBUF_SIZE +
- RAL_SEC_CSR0, wk->wk_key, IEEE80211_KEYBUF_SIZE);
- }
-
- /*
* Allocate xfer for AMRR statistics requests.
*/
sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev);
if (sc->amrr_xfer == NULL) {
printf("%s: could not allocate AMRR xfer\n",
- USBDEVNAME(sc->sc_dev));
+ device_get_nameunit(sc->sc_dev));
goto fail;
}
@@ -2142,7 +2282,7 @@
&sc->sc_tx_pipeh);
if (error != 0) {
printf("%s: could not open Tx pipe: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(error));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(error));
goto fail;
}
@@ -2150,7 +2290,7 @@
&sc->sc_rx_pipeh);
if (error != 0) {
printf("%s: could not open Rx pipe: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(error));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(error));
goto fail;
}
@@ -2160,14 +2300,14 @@
error = ural_alloc_tx_list(sc);
if (error != 0) {
printf("%s: could not allocate Tx list\n",
- USBDEVNAME(sc->sc_dev));
+ device_get_nameunit(sc->sc_dev));
goto fail;
}
error = ural_alloc_rx_list(sc);
if (error != 0) {
printf("%s: could not allocate Rx list\n",
- USBDEVNAME(sc->sc_dev));
+ device_get_nameunit(sc->sc_dev));
goto fail;
}
@@ -2208,19 +2348,18 @@
#undef N
}
-Static void
+static void
ural_stop(void *priv)
{
struct ural_softc *sc = priv;
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = ic->ic_ifp;
- ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
-
sc->sc_tx_timer = 0;
- ifp->if_timer = 0;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
+
/* disable Rx */
ural_write(sc, RAL_TXRX_CSR2, RAL_DISABLE_RX);
@@ -2249,22 +2388,66 @@
ural_free_tx_list(sc);
}
-#define URAL_AMRR_MIN_SUCCESS_THRESHOLD 1
-#define URAL_AMRR_MAX_SUCCESS_THRESHOLD 10
+static int
+ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_bpf_params *params)
+{
+ struct ieee80211com *ic = ni->ni_ic;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct ural_softc *sc = ifp->if_softc;
+
+ /* prevent management frames from being sent if we're not ready */
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ m_freem(m);
+ ieee80211_free_node(ni);
+ return ENETDOWN;
+ }
+ if (sc->tx_queued >= RAL_TX_LIST_COUNT) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ m_freem(m);
+ ieee80211_free_node(ni);
+ return EIO;
+ }
+
+ if (bpf_peers_present(ic->ic_rawbpf))
+ bpf_mtap(ic->ic_rawbpf, m);
+
+ ifp->if_opackets++;
+
+ if (params == NULL) {
+ /*
+ * Legacy path; interpret frame contents to decide
+ * precisely how to send the frame.
+ */
+ if (ural_tx_mgt(sc, m, ni) != 0)
+ goto bad;
+ } else {
+ /*
+ * Caller supplied explicit parameters to use in
+ * sending the frame.
+ */
+ if (ural_tx_raw(sc, m, ni, params) != 0)
+ goto bad;
+ }
+ sc->sc_tx_timer = 5;
+ callout_reset(&sc->watchdog_ch, hz, ural_watchdog, sc);
-Static void
+ return 0;
+bad:
+ ifp->if_oerrors++;
+ ieee80211_free_node(ni);
+ return EIO; /* XXX */
+}
+
+static void
ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni)
{
- struct ural_amrr *amrr = &sc->amrr;
int i;
/* clear statistic registers (STA_CSR0 to STA_CSR10) */
ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta);
- amrr->success = 0;
- amrr->recovery = 0;
- amrr->txcnt = amrr->retrycnt = 0;
- amrr->success_threshold = URAL_AMRR_MIN_SUCCESS_THRESHOLD;
+ ieee80211_amrr_node_init(&sc->amrr, &sc->amn);
/* set rate to some reasonable initial value */
for (i = ni->ni_rates.rs_nrates - 1;
@@ -2276,14 +2459,11 @@
callout_reset(&sc->amrr_ch, hz, ural_amrr_timeout, sc);
}
-Static void
+static void
ural_amrr_timeout(void *arg)
{
struct ural_softc *sc = (struct ural_softc *)arg;
usb_device_request_t req;
- int s;
-
- s = splusb();
/*
* Asynchronously read statistic registers (cleared by read).
@@ -2298,16 +2478,13 @@
USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0,
ural_amrr_update);
(void)usbd_transfer(sc->amrr_xfer);
-
- splx(s);
}
-Static void
+static void
ural_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv,
usbd_status status)
{
struct ural_softc *sc = (struct ural_softc *)priv;
- struct ural_amrr *amrr = &sc->amrr;
struct ifnet *ifp = sc->sc_ic.ic_ifp;
if (status != USBD_NORMAL_COMPLETION) {
@@ -2319,85 +2496,16 @@
/* count TX retry-fail as Tx errors */
ifp->if_oerrors += sc->sta[9];
- amrr->retrycnt =
+ sc->amn.amn_retrycnt =
sc->sta[7] + /* TX one-retry ok count */
sc->sta[8] + /* TX more-retry ok count */
sc->sta[9]; /* TX retry-fail count */
- amrr->txcnt =
- amrr->retrycnt +
+ sc->amn.amn_txcnt =
+ sc->amn.amn_retrycnt +
sc->sta[6]; /* TX no-retry ok count */
- ural_ratectl(amrr, sc->sc_ic.ic_bss);
+ ieee80211_amrr_choose(&sc->amrr, sc->sc_ic.ic_bss, &sc->amn);
callout_reset(&sc->amrr_ch, hz, ural_amrr_timeout, sc);
}
-
-/*-
- * Naive implementation of the Adaptive Multi Rate Retry algorithm:
- * "IEEE 802.11 Rate Adaptation: A Practical Approach"
- * Mathieu Lacage, Hossein Manshaei, Thierry Turletti
- * INRIA Sophia - Projet Planete
- * http://www-sop.inria.fr/rapports/sophia/RR-5208.html
- *
- * This algorithm is particularly well suited for ural since it does not
- * require per-frame retry statistics. Note however that since h/w does
- * not provide per-frame stats, we can't do per-node rate adaptation and
- * thus automatic rate adaptation is only enabled in STA operating mode.
- */
-#define is_success(amrr) \
- ((amrr)->retrycnt < (amrr)->txcnt / 10)
-#define is_failure(amrr) \
- ((amrr)->retrycnt > (amrr)->txcnt / 3)
-#define is_enough(amrr) \
- ((amrr)->txcnt > 10)
-#define is_min_rate(ni) \
- ((ni)->ni_txrate == 0)
-#define is_max_rate(ni) \
- ((ni)->ni_txrate == (ni)->ni_rates.rs_nrates - 1)
-#define increase_rate(ni) \
- ((ni)->ni_txrate++)
-#define decrease_rate(ni) \
- ((ni)->ni_txrate--)
-#define reset_cnt(amrr) \
- do { (amrr)->txcnt = (amrr)->retrycnt = 0; } while (0)
-Static void
-ural_ratectl(struct ural_amrr *amrr, struct ieee80211_node *ni)
-{
- int need_change = 0;
-
- if (is_success(amrr) && is_enough(amrr)) {
- amrr->success++;
- if (amrr->success >= amrr->success_threshold &&
- !is_max_rate(ni)) {
- amrr->recovery = 1;
- amrr->success = 0;
- increase_rate(ni);
- need_change = 1;
- } else {
- amrr->recovery = 0;
- }
- } else if (is_failure(amrr)) {
- amrr->success = 0;
- if (!is_min_rate(ni)) {
- if (amrr->recovery) {
- amrr->success_threshold *= 2;
- if (amrr->success_threshold >
- URAL_AMRR_MAX_SUCCESS_THRESHOLD)
- amrr->success_threshold =
- URAL_AMRR_MAX_SUCCESS_THRESHOLD;
- } else {
- amrr->success_threshold =
- URAL_AMRR_MIN_SUCCESS_THRESHOLD;
- }
- decrease_rate(ni);
- need_change = 1;
- }
- amrr->recovery = 0; /* original paper was incorrect */
- }
-
- if (is_enough(amrr) || need_change)
- reset_cnt(amrr);
-}
-
-DRIVER_MODULE(ural, uhub, ural_driver, ural_devclass, usbd_driver_load, 0);
Index: umass.c
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/umass.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/usb/umass.c -L sys/dev/usb/umass.c -u -r1.2 -r1.3
--- sys/dev/usb/umass.c
+++ sys/dev/usb/umass.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/sys/dev/usb/umass.c,v 1.122.2.8 2006/03/24 21:42:02 iedowse Exp $
+ * $FreeBSD: src/sys/dev/usb/umass.c,v 1.160 2007/07/05 05:26:08 imp Exp $
* $NetBSD: umass.c,v 1.28 2000/04/02 23:46:53 augustss Exp $
*/
@@ -110,6 +110,8 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/bus.h>
#include <sys/sysctl.h>
@@ -129,7 +131,7 @@
#ifdef USB_DEBUG
#define DIF(m, x) if (umassdebug & (m)) do { x ; } while (0)
-#define DPRINTF(m, x) if (umassdebug & (m)) logprintf x
+#define DPRINTF(m, x) if (umassdebug & (m)) printf x
#define UDMASS_GEN 0x00010000 /* general */
#define UDMASS_SCSI 0x00020000 /* scsi */
#define UDMASS_UFI 0x00040000 /* ufi command set */
@@ -317,13 +319,85 @@
# 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
};
-Static struct umass_devdescr_t umass_devdescrs[] = {
+static struct umass_devdescr_t umass_devdescrs[] = {
+ { USB_VENDOR_ADDONICS2, USB_PRODUCT_ADDONICS2_CABLE_205, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_AIPTEK, USB_PRODUCT_AIPTEK_POCKETCAM3M, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO230, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY
+ },
+ { USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO330, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY
+ },
{ USB_VENDOR_ASAHIOPTICAL, PID_WILDCARD, RID_WILDCARD,
UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
RS_NO_CLEAR_UA
},
+ { USB_VENDOR_ADDON, USB_PRODUCT_ADDON_ATTACHE, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ IGNORE_RESIDUE
+ },
+ { USB_VENDOR_ADDON, USB_PRODUCT_ADDON_A256MB, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ IGNORE_RESIDUE
+ },
+ { USB_VENDOR_ADDON, USB_PRODUCT_ADDON_DISKPRO512, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ IGNORE_RESIDUE
+ },
+ { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2SCSI, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_CASIO, USB_PRODUCT_CASIO_QV_DIGICAM, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
+ NO_INQUIRY
+ },
+ { USB_VENDOR_CCYU, USB_PRODUCT_CCYU_ED1064, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_CENTURY, USB_PRODUCT_CENTURY_EX35QUAT, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
+ },
+ { USB_VENDOR_DESKNOTE, USB_PRODUCT_DESKNOTE_UCR_61S2B, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_DMI, USB_PRODUCT_DMI_CFSM_RW, RID_WILDCARD,
+ UMASS_PROTO_SCSI,
+ NO_GETMAXLUN
+ },
+ { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_875DC, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
+ NO_INQUIRY
+ },
+ { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_895, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_GETMAXLUN
+ },
+ { USB_VENDOR_FEIYA, USB_PRODUCT_FEIYA_5IN1, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_FREECOM, USB_PRODUCT_FREECOM_DVD, RID_WILDCARD,
+ UMASS_PROTO_SCSI,
+ NO_QUIRKS
+ },
{ USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100, RID_WILDCARD,
UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
RS_NO_CLEAR_UA
@@ -344,10 +418,26 @@
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
WRONG_CSWSIG
},
+ { USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FG, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_QUIRKS
+ },
{ USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_USB, RID_WILDCARD,
UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
NO_INQUIRY
},
+ { USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_DZ_MV100A, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
+ NO_GETMAXLUN
+ },
+ { USB_VENDOR_HP, USB_PRODUCT_HP_CDW4E, RID_WILDCARD,
+ UMASS_PROTO_ATAPI,
+ NO_QUIRKS
+ },
{ USB_VENDOR_HP, USB_PRODUCT_HP_CDW8200, RID_WILDCARD,
UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
NO_TEST_UNIT_READY | NO_START_STOP
@@ -356,6 +446,14 @@
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
WRONG_CSWSIG
},
+ { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI, RID_WILDCARD,
+ UMASS_PROTO_RBC | UMASS_PROTO_CBI,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_STORAGE_V2, RID_WILDCARD,
+ UMASS_PROTO_RBC | UMASS_PROTO_CBI,
+ NO_QUIRKS
+ },
{ USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE, RID_WILDCARD,
UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
NO_TEST_UNIT_READY | NO_START_STOP | ALT_IFACE_1
@@ -374,6 +472,34 @@
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
@@ -390,6 +516,30 @@
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
@@ -402,18 +552,70 @@
UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
NO_QUIRKS
},
+ { USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY | IGNORE_RESIDUE
+ },
{ USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260, RID_WILDCARD,
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
FORCE_SHORT_INQUIRY
},
+ { USB_VENDOR_NETAC, USB_PRODUCT_NETAC_CF_CARD, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY
+ },
+ { USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_CLIK_40, RID_WILDCARD,
+ UMASS_PROTO_ATAPI,
+ NO_INQUIRY
+ },
{ USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1, RID_WILDCARD,
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
WRONG_CSWSIG
},
+ { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700, RID_WILDCARD,
+ UMASS_PROTO_SCSI,
+ NO_GETMAXLUN
+ },
+ { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFMS_RW, RID_WILDCARD,
+ UMASS_PROTO_SCSI,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_COMBO, RID_WILDCARD,
+ UMASS_PROTO_SCSI,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER, RID_WILDCARD,
+ UMASS_PROTO_SCSI,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER2, RID_WILDCARD,
+ UMASS_PROTO_SCSI,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_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
@@ -422,21 +624,41 @@
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_ATTACHE, RID_WILDCARD,
+ { USB_VENDOR_PNY, USB_PRODUCT_PNY_ATTACHE2, RID_WILDCARD,
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
+ IGNORE_RESIDUE | NO_START_STOP
},
- { USB_VENDOR_PNY, USB_PRODUCT_PNY_A256MB, RID_WILDCARD,
+ { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_YP_U2, RID_WILDCARD,
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
+ SHUTTLE_INIT | NO_GETMAXLUN
},
- { USB_VENDOR_PNY, USB_PRODUCT_PNY_DISKPRO512, RID_WILDCARD,
+ { USB_VENDOR_SAMSUNG_TECHWIN, USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410, RID_WILDCARD,
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
+ NO_INQUIRY
+ },
+ { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05A, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
+ READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
+ },
+ { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR09, RID_WILDCARD,
+ UMASS_PROTO_SCSI,
+ READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
+ },
+ { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR12, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
+ READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
+ },
+ { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR31, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ READ_CAPACITY_OFFBY1
},
{ USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_256, RID_WILDCARD,
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
@@ -454,10 +676,42 @@
UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
NO_INQUIRY
},
+ { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CDRW, RID_WILDCARD,
+ UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CF, RID_WILDCARD,
+ UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
+ NO_QUIRKS
+ },
{ USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB, RID_WILDCARD,
UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
NO_TEST_UNIT_READY | NO_START_STOP | SHUTTLE_INIT
},
+ { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBATAPI, RID_WILDCARD,
+ UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBCFSM, RID_WILDCARD,
+ UMASS_PROTO_SCSI,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_HIFD, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
+ NO_GETMAXLUN
+ },
+ { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SDDR09, RID_WILDCARD,
+ UMASS_PROTO_SCSI,
+ NO_GETMAXLUN
+ },
+ { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
+ NO_GETMAXLUN
+ },
{ USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100, RID_WILDCARD,
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
SHUTTLE_INIT
@@ -466,6 +720,18 @@
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
IGNORE_RESIDUE
},
+ { USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_MD_7425, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY
+ },
+ { USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_SX_520Z, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY
+ },
+ { USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY
+ },
{ USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, 0x0500,
UMASS_PROTO_RBC | UMASS_PROTO_CBI,
RBC_PAD_TO_12
@@ -482,10 +748,42 @@
UMASS_PROTO_RBC | UMASS_PROTO_CBI,
NO_QUIRKS
},
+ { USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_MSC_U03, RID_WILDCARD,
+ UMASS_PROTO_UFI | UMASS_PROTO_CBI,
+ NO_GETMAXLUN
+ },
+ { USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_NW_MS7, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_GETMAXLUN
+ },
+ { USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_PEG_N760C, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY
+ },
+ { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSACUS1, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_GETMAXLUN
+ },
{ USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC, RID_WILDCARD,
UMASS_PROTO_RBC | UMASS_PROTO_CBI,
NO_QUIRKS
},
+ { USB_VENDOR_SONY, USB_PRODUCT_SONY_PORTABLE_HDD_V2, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_TAUGA, USB_PRODUCT_TAUGA_CAMERAMATE, RID_WILDCARD,
+ UMASS_PROTO_SCSI,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB, RID_WILDCARD,
+ UMASS_PROTO_UFI | UMASS_PROTO_CBI,
+ NO_QUIRKS
+ },
+ { USB_VENDOR_TREK, USB_PRODUCT_TREK_MEMKEY, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY
+ },
{ USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB, RID_WILDCARD,
UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
IGNORE_RESIDUE
@@ -494,25 +792,61 @@
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_VIVITAR, USB_PRODUCT_VIVITAR_35XX, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY
+ },
+ { USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_COMBO, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
+ },
{ USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_EXTHDD, RID_WILDCARD,
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
},
+ { USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYBOOK, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY_EVPD
+ },
+ { USB_VENDOR_WINMAXGROUP, USB_PRODUCT_WINMAXGROUP_FLASH64MC, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ NO_INQUIRY
+ },
+ { USB_VENDOR_YANO, USB_PRODUCT_YANO_FW800HD, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
+ FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
+ },
{ USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO, RID_WILDCARD,
UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
FORCE_SHORT_INQUIRY
},
+ { USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU, RID_WILDCARD,
+ UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
+ NO_GETMAXLUN
+ },
+ { USB_VENDOR_ZORAN, USB_PRODUCT_ZORAN_EX20DSC, RID_WILDCARD,
+ UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
+ NO_QUIRKS
+ },
{ VID_EOT, PID_EOT, RID_EOT, 0, 0 }
};
/* the per device structure */
struct umass_softc {
- USBBASEDEVICE sc_dev; /* base device */
+ device_t sc_dev; /* base device */
usbd_device_handle sc_udev; /* USB device */
struct cam_sim *umass_sim; /* SCSI Interface Module */
@@ -626,7 +960,7 @@
unsigned char cam_scsi_command2[CAM_MAX_CDBLEN];
struct scsi_sense cam_scsi_sense;
struct scsi_sense cam_scsi_test_unit_ready;
- usb_callout_t cam_scsi_rescan_ch;
+ struct callout cam_scsi_rescan_ch;
int timeout; /* in msecs */
@@ -660,114 +994,133 @@
#endif
/* If device cannot return valid inquiry data, fake it */
-Static uint8_t fake_inq_data[SHORT_INQUIRY_LENGTH] = {
+static uint8_t fake_inq_data[SHORT_INQUIRY_LENGTH] = {
0, /*removable*/ 0x80, SCSI_REV_2, SCSI_REV_2,
/*additional_length*/ 31, 0, 0, 0
};
/* USB device probe/attach/detach functions */
-USB_DECLARE_DRIVER(umass);
-Static int umass_match_proto (struct umass_softc *sc,
+static device_probe_t umass_match;
+static device_attach_t umass_attach;
+static device_detach_t umass_detach;
+
+static device_method_t umass_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, umass_match),
+ DEVMETHOD(device_attach, umass_attach),
+ DEVMETHOD(device_detach, umass_detach),
+
+ { 0, 0 }
+};
+
+static driver_t umass_driver = {
+ "umass",
+ umass_methods,
+ sizeof(struct umass_softc)
+};
+
+static devclass_t umass_devclass;
+
+static int umass_match_proto (struct umass_softc *sc,
usbd_interface_handle iface,
usbd_device_handle udev);
/* quirk functions */
-Static void umass_init_shuttle (struct umass_softc *sc);
+static void umass_init_shuttle (struct umass_softc *sc);
/* generic transfer functions */
-Static usbd_status umass_setup_transfer (struct umass_softc *sc,
+static usbd_status umass_setup_transfer (struct umass_softc *sc,
usbd_pipe_handle pipe,
void *buffer, int buflen, int flags,
usbd_xfer_handle xfer);
-Static usbd_status umass_setup_ctrl_transfer (struct umass_softc *sc,
+static usbd_status umass_setup_ctrl_transfer (struct umass_softc *sc,
usbd_device_handle udev,
usb_device_request_t *req,
void *buffer, int buflen, int flags,
usbd_xfer_handle xfer);
-Static void umass_clear_endpoint_stall (struct umass_softc *sc,
+static void umass_clear_endpoint_stall (struct umass_softc *sc,
u_int8_t endpt, usbd_pipe_handle pipe,
int state, usbd_xfer_handle xfer);
-Static void umass_reset (struct umass_softc *sc,
+static void umass_reset (struct umass_softc *sc,
transfer_cb_f cb, void *priv);
/* Bulk-Only related functions */
-Static void umass_bbb_reset (struct umass_softc *sc, int status);
-Static void umass_bbb_transfer (struct umass_softc *sc, int lun,
+static void umass_bbb_reset (struct umass_softc *sc, int status);
+static void umass_bbb_transfer (struct umass_softc *sc, int lun,
void *cmd, int cmdlen,
void *data, int datalen, int dir, u_int timeout,
transfer_cb_f cb, void *priv);
-Static void umass_bbb_state (usbd_xfer_handle xfer,
+static void umass_bbb_state (usbd_xfer_handle xfer,
usbd_private_handle priv,
usbd_status err);
-Static int umass_bbb_get_max_lun
+static int umass_bbb_get_max_lun
(struct umass_softc *sc);
/* CBI related functions */
-Static int umass_cbi_adsc (struct umass_softc *sc,
+static int umass_cbi_adsc (struct umass_softc *sc,
char *buffer, int buflen,
usbd_xfer_handle xfer);
-Static void umass_cbi_reset (struct umass_softc *sc, int status);
-Static void umass_cbi_transfer (struct umass_softc *sc, int lun,
+static void umass_cbi_reset (struct umass_softc *sc, int status);
+static void umass_cbi_transfer (struct umass_softc *sc, int lun,
void *cmd, int cmdlen,
void *data, int datalen, int dir, u_int timeout,
transfer_cb_f cb, void *priv);
-Static void umass_cbi_state (usbd_xfer_handle xfer,
+static void umass_cbi_state (usbd_xfer_handle xfer,
usbd_private_handle priv, usbd_status err);
/* CAM related functions */
-Static void umass_cam_action (struct cam_sim *sim, union ccb *ccb);
-Static void umass_cam_poll (struct cam_sim *sim);
+static void umass_cam_action (struct cam_sim *sim, union ccb *ccb);
+static void umass_cam_poll (struct cam_sim *sim);
-Static void umass_cam_cb (struct umass_softc *sc, void *priv,
+static void umass_cam_cb (struct umass_softc *sc, void *priv,
int residue, int status);
-Static void umass_cam_sense_cb (struct umass_softc *sc, void *priv,
+static void umass_cam_sense_cb (struct umass_softc *sc, void *priv,
int residue, int status);
-Static void umass_cam_quirk_cb (struct umass_softc *sc, void *priv,
+static void umass_cam_quirk_cb (struct umass_softc *sc, void *priv,
int residue, int status);
-Static void umass_cam_rescan_callback
+static void umass_cam_rescan_callback
(struct cam_periph *periph,union ccb *ccb);
-Static void umass_cam_rescan (void *addr);
+static void umass_cam_rescan (void *addr);
-Static int umass_cam_attach_sim (struct umass_softc *sc);
-Static int umass_cam_attach (struct umass_softc *sc);
-Static int umass_cam_detach_sim (struct umass_softc *sc);
+static int umass_cam_attach_sim (struct umass_softc *sc);
+static int umass_cam_attach (struct umass_softc *sc);
+static int umass_cam_detach_sim (struct umass_softc *sc);
/* SCSI specific functions */
-Static int umass_scsi_transform (struct umass_softc *sc,
+static int umass_scsi_transform (struct umass_softc *sc,
unsigned char *cmd, int cmdlen,
unsigned char **rcmd, int *rcmdlen);
/* UFI specific functions */
#define UFI_COMMAND_LENGTH 12 /* UFI commands are always 12 bytes */
-Static int umass_ufi_transform (struct umass_softc *sc,
+static int umass_ufi_transform (struct umass_softc *sc,
unsigned char *cmd, int cmdlen,
unsigned char **rcmd, int *rcmdlen);
/* ATAPI (8070i) specific functions */
#define ATAPI_COMMAND_LENGTH 12 /* ATAPI commands are always 12 bytes */
-Static int umass_atapi_transform (struct umass_softc *sc,
+static int umass_atapi_transform (struct umass_softc *sc,
unsigned char *cmd, int cmdlen,
unsigned char **rcmd, int *rcmdlen);
/* RBC specific functions */
-Static int umass_rbc_transform (struct umass_softc *sc,
+static int umass_rbc_transform (struct umass_softc *sc,
unsigned char *cmd, int cmdlen,
unsigned char **rcmd, int *rcmdlen);
#ifdef USB_DEBUG
/* General debugging functions */
-Static void umass_bbb_dump_cbw (struct umass_softc *sc, umass_bbb_cbw_t *cbw);
-Static void umass_bbb_dump_csw (struct umass_softc *sc, umass_bbb_csw_t *csw);
-Static void umass_cbi_dump_cmd (struct umass_softc *sc, void *cmd, int cmdlen);
-Static void umass_dump_buffer (struct umass_softc *sc, u_int8_t *buffer,
+static void umass_bbb_dump_cbw (struct umass_softc *sc, umass_bbb_cbw_t *cbw);
+static void umass_bbb_dump_csw (struct umass_softc *sc, umass_bbb_csw_t *csw);
+static void umass_cbi_dump_cmd (struct umass_softc *sc, void *cmd, int cmdlen);
+static void umass_dump_buffer (struct umass_softc *sc, u_int8_t *buffer,
int buflen, int printlen);
#endif
-#if defined(__FreeBSD__)
-MODULE_DEPEND(umass, cam, 1,1,1);
-#endif
+MODULE_DEPEND(umass, cam, 1, 1, 1);
+MODULE_DEPEND(umass, usb, 1, 1, 1);
/*
* USB device probe/attach/detach
@@ -779,7 +1132,7 @@
* probe and attach.
*/
-Static int
+static int
umass_match_proto(struct umass_softc *sc, usbd_interface_handle iface,
usbd_device_handle udev)
{
@@ -868,7 +1221,7 @@
break;
default:
DPRINTF(UDMASS_GEN, ("%s: Unsupported command protocol %d\n",
- USBDEVNAME(sc->sc_dev), id->bInterfaceSubClass));
+ device_get_nameunit(sc->sc_dev), id->bInterfaceSubClass));
return(UMATCH_NONE);
}
@@ -885,32 +1238,32 @@
break;
default:
DPRINTF(UDMASS_GEN, ("%s: Unsupported wire protocol %d\n",
- USBDEVNAME(sc->sc_dev), id->bInterfaceProtocol));
+ device_get_nameunit(sc->sc_dev), id->bInterfaceProtocol));
return(UMATCH_NONE);
}
return(UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO);
}
-USB_MATCH(umass)
+static int
+umass_match(device_t self)
{
- USB_MATCH_START(umass, uaa);
+ struct usb_attach_arg *uaa = device_get_ivars(self);
struct umass_softc *sc = device_get_softc(self);
- USB_MATCH_SETUP;
-
+ sc->sc_dev = self;
if (uaa->iface == NULL)
return(UMATCH_NONE);
-
return(umass_match_proto(sc, uaa->iface, uaa->device));
}
-USB_ATTACH(umass)
+static int
+umass_attach(device_t self)
{
- USB_ATTACH_START(umass, sc, uaa);
+ struct umass_softc *sc = device_get_softc(self);
+ struct usb_attach_arg *uaa = device_get_ivars(self);
usb_interface_descriptor_t *id;
usb_endpoint_descriptor_t *ed;
- char devinfo[1024];
int i;
int err;
@@ -918,20 +1271,17 @@
* the softc struct is bzero-ed in device_set_driver. We can safely
* call umass_detach without specifically initialising the struct.
*/
-
- usbd_devinfo(uaa->device, 0, devinfo);
- USB_ATTACH_SETUP;
-
+ sc->sc_dev = self;
sc->iface = uaa->iface;
sc->ifaceno = uaa->ifaceno;
- usb_callout_init(sc->cam_scsi_rescan_ch);
+ callout_init(&sc->cam_scsi_rescan_ch, 0);
/* initialise the proto and drive values in the umass_softc (again) */
(void) umass_match_proto(sc, sc->iface, uaa->device);
id = usbd_get_interface_descriptor(sc->iface);
#ifdef USB_DEBUG
- printf("%s: ", USBDEVNAME(sc->sc_dev));
+ printf("%s: ", device_get_nameunit(sc->sc_dev));
switch (sc->proto&UMASS_PROTO_COMMAND) {
case UMASS_PROTO_SCSI:
printf("SCSI");
@@ -981,9 +1331,9 @@
if (err) {
DPRINTF(UDMASS_USB, ("%s: could not switch to "
"Alt Interface %d\n",
- USBDEVNAME(sc->sc_dev), 1));
+ device_get_nameunit(sc->sc_dev), 1));
umass_detach(self);
- USB_ATTACH_ERROR_RETURN;
+ return ENXIO;
}
}
@@ -1002,8 +1352,8 @@
ed = usbd_interface2endpoint_descriptor(sc->iface, i);
if (!ed) {
printf("%s: could not read endpoint descriptor\n",
- USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
+ device_get_nameunit(sc->sc_dev));
+ return ENXIO;
}
if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
&& (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
@@ -1018,7 +1368,7 @@
#ifdef USB_DEBUG
if (UGETW(ed->wMaxPacketSize) > 2) {
DPRINTF(UDMASS_CBI, ("%s: intr size is %d\n",
- USBDEVNAME(sc->sc_dev),
+ device_get_nameunit(sc->sc_dev),
UGETW(ed->wMaxPacketSize)));
}
#endif
@@ -1029,10 +1379,10 @@
if (!sc->bulkin || !sc->bulkout
|| (sc->proto & UMASS_PROTO_CBI_I && !sc->intrin) ) {
DPRINTF(UDMASS_USB, ("%s: endpoint not found %d/%d/%d\n",
- USBDEVNAME(sc->sc_dev),
+ device_get_nameunit(sc->sc_dev),
sc->bulkin, sc->bulkout, sc->intrin));
umass_detach(self);
- USB_ATTACH_ERROR_RETURN;
+ return ENXIO;
}
/* Open the bulk-in and -out pipe */
@@ -1040,17 +1390,17 @@
USBD_EXCLUSIVE_USE, &sc->bulkout_pipe);
if (err) {
DPRINTF(UDMASS_USB, ("%s: cannot open %d-out pipe (bulk)\n",
- USBDEVNAME(sc->sc_dev), sc->bulkout));
+ device_get_nameunit(sc->sc_dev), sc->bulkout));
umass_detach(self);
- USB_ATTACH_ERROR_RETURN;
+ return ENXIO;
}
err = usbd_open_pipe(sc->iface, sc->bulkin,
USBD_EXCLUSIVE_USE, &sc->bulkin_pipe);
if (err) {
DPRINTF(UDMASS_USB, ("%s: could not open %d-in pipe (bulk)\n",
- USBDEVNAME(sc->sc_dev), sc->bulkin));
+ device_get_nameunit(sc->sc_dev), sc->bulkin));
umass_detach(self);
- USB_ATTACH_ERROR_RETURN;
+ return ENXIO;
}
/* Open the intr-in pipe if the protocol is CBI with CCI.
* Note: early versions of the Zip drive do have an interrupt pipe, but
@@ -1068,9 +1418,9 @@
USBD_EXCLUSIVE_USE, &sc->intrin_pipe);
if (err) {
DPRINTF(UDMASS_USB, ("%s: couldn't open %d-in (intr)\n",
- USBDEVNAME(sc->sc_dev), sc->intrin));
+ device_get_nameunit(sc->sc_dev), sc->intrin));
umass_detach(self);
- USB_ATTACH_ERROR_RETURN;
+ return ENXIO;
}
}
@@ -1082,9 +1432,9 @@
sc->transfer_xfer[i] = usbd_alloc_xfer(uaa->device);
if (!sc->transfer_xfer[i]) {
DPRINTF(UDMASS_USB, ("%s: Out of memory\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
umass_detach(self);
- USB_ATTACH_ERROR_RETURN;
+ return ENXIO;
}
}
@@ -1143,14 +1493,14 @@
err = umass_cam_attach_sim(sc);
if (err) {
umass_detach(self);
- USB_ATTACH_ERROR_RETURN;
+ return ENXIO;
}
/* scan the new sim */
err = umass_cam_attach(sc);
if (err) {
umass_cam_detach_sim(sc);
umass_detach(self);
- USB_ATTACH_ERROR_RETURN;
+ return ENXIO;
}
} else {
panic("%s:%d: Unknown proto 0x%02x",
@@ -1158,18 +1508,19 @@
}
sc->transfer_state = TSTATE_IDLE;
- DPRINTF(UDMASS_GEN, ("%s: Attach finished\n", USBDEVNAME(sc->sc_dev)));
+ DPRINTF(UDMASS_GEN, ("%s: Attach finished\n", device_get_nameunit(sc->sc_dev)));
- USB_ATTACH_SUCCESS_RETURN;
+ return 0;
}
-USB_DETACH(umass)
+static int
+umass_detach(device_t self)
{
- USB_DETACH_START(umass, sc);
+ struct umass_softc *sc = device_get_softc(self);
int err = 0;
int i;
- DPRINTF(UDMASS_USB, ("%s: detached\n", USBDEVNAME(sc->sc_dev)));
+ DPRINTF(UDMASS_USB, ("%s: detached\n", device_get_nameunit(sc->sc_dev)));
sc->flags |= UMASS_FLAGS_GONE;
@@ -1182,7 +1533,7 @@
if (sc->intrin_pipe)
usbd_abort_pipe(sc->intrin_pipe);
- usb_uncallout_drain(sc->cam_scsi_rescan_ch, umass_cam_rescan, sc);
+ callout_drain(&sc->cam_scsi_rescan_ch);
if ((sc->proto & UMASS_PROTO_SCSI) ||
(sc->proto & UMASS_PROTO_ATAPI) ||
(sc->proto & UMASS_PROTO_UFI) ||
@@ -1205,7 +1556,7 @@
return(err);
}
-Static void
+static void
umass_init_shuttle(struct umass_softc *sc)
{
usb_device_request_t req;
@@ -1222,14 +1573,14 @@
(void) usbd_do_request(sc->sc_udev, &req, &status);
DPRINTF(UDMASS_GEN, ("%s: Shuttle init returned 0x%02x%02x\n",
- USBDEVNAME(sc->sc_dev), status[0], status[1]));
+ device_get_nameunit(sc->sc_dev), status[0], status[1]));
}
/*
* Generic functions to handle transfers
*/
-Static usbd_status
+static usbd_status
umass_setup_transfer(struct umass_softc *sc, usbd_pipe_handle pipe,
void *buffer, int buflen, int flags,
usbd_xfer_handle xfer)
@@ -1244,7 +1595,7 @@
err = usbd_transfer(xfer);
if (err && err != USBD_IN_PROGRESS) {
DPRINTF(UDMASS_BBB, ("%s: failed to setup transfer, %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err)));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
return(err);
}
@@ -1252,7 +1603,7 @@
}
-Static usbd_status
+static usbd_status
umass_setup_ctrl_transfer(struct umass_softc *sc, usbd_device_handle udev,
usb_device_request_t *req,
void *buffer, int buflen, int flags,
@@ -1268,7 +1619,7 @@
err = usbd_transfer(xfer);
if (err && err != USBD_IN_PROGRESS) {
DPRINTF(UDMASS_BBB, ("%s: failed to setup ctrl transfer, %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err)));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
/* do not reset, as this would make us loop */
return(err);
@@ -1277,7 +1628,7 @@
return (USBD_NORMAL_COMPLETION);
}
-Static void
+static void
umass_clear_endpoint_stall(struct umass_softc *sc,
u_int8_t endpt, usbd_pipe_handle pipe,
int state, usbd_xfer_handle xfer)
@@ -1285,7 +1636,7 @@
usbd_device_handle udev;
DPRINTF(UDMASS_BBB, ("%s: Clear endpoint 0x%02x stall\n",
- USBDEVNAME(sc->sc_dev), endpt));
+ device_get_nameunit(sc->sc_dev), endpt));
usbd_interface2device_handle(sc->iface, &udev);
@@ -1301,7 +1652,7 @@
umass_setup_ctrl_transfer(sc, udev, &sc->request, NULL, 0, 0, xfer);
}
-Static void
+static void
umass_reset(struct umass_softc *sc, transfer_cb_f cb, void *priv)
{
sc->transfer_cb = cb;
@@ -1315,14 +1666,14 @@
* Bulk protocol specific functions
*/
-Static void
+static void
umass_bbb_reset(struct umass_softc *sc, int status)
{
usbd_device_handle udev;
KASSERT(sc->proto & UMASS_PROTO_BBB,
("%s: umass_bbb_reset: wrong sc->proto 0x%02x\n",
- USBDEVNAME(sc->sc_dev), sc->proto));
+ device_get_nameunit(sc->sc_dev), sc->proto));
/*
* Reset recovery (5.3.4 in Universal Serial Bus Mass Storage Class)
@@ -1341,7 +1692,7 @@
*/
DPRINTF(UDMASS_BBB, ("%s: Bulk Reset\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
sc->transfer_state = TSTATE_BBB_RESET1;
sc->transfer_status = status;
@@ -1358,14 +1709,14 @@
sc->transfer_xfer[XFER_BBB_RESET1]);
}
-Static void
+static void
umass_bbb_transfer(struct umass_softc *sc, int lun, void *cmd, int cmdlen,
void *data, int datalen, int dir, u_int timeout,
transfer_cb_f cb, void *priv)
{
KASSERT(sc->proto & UMASS_PROTO_BBB,
("%s: umass_bbb_transfer: wrong sc->proto 0x%02x\n",
- USBDEVNAME(sc->sc_dev), sc->proto));
+ device_get_nameunit(sc->sc_dev), sc->proto));
/* Be a little generous. */
sc->timeout = timeout + UMASS_TIMEOUT;
@@ -1392,23 +1743,23 @@
/* check the given arguments */
KASSERT(datalen == 0 || data != NULL,
- ("%s: datalen > 0, but no buffer",USBDEVNAME(sc->sc_dev)));
+ ("%s: datalen > 0, but no buffer",device_get_nameunit(sc->sc_dev)));
KASSERT(cmdlen <= CBWCDBLENGTH,
("%s: cmdlen exceeds CDB length in CBW (%d > %d)",
- USBDEVNAME(sc->sc_dev), cmdlen, CBWCDBLENGTH));
+ device_get_nameunit(sc->sc_dev), cmdlen, CBWCDBLENGTH));
KASSERT(dir == DIR_NONE || datalen > 0,
("%s: datalen == 0 while direction is not NONE\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
KASSERT(datalen == 0 || dir != DIR_NONE,
("%s: direction is NONE while datalen is not zero\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
KASSERT(sizeof(umass_bbb_cbw_t) == UMASS_BBB_CBW_SIZE,
("%s: CBW struct does not have the right size (%ld vs. %d)\n",
- USBDEVNAME(sc->sc_dev),
+ device_get_nameunit(sc->sc_dev),
(long)sizeof(umass_bbb_cbw_t), UMASS_BBB_CBW_SIZE));
KASSERT(sizeof(umass_bbb_csw_t) == UMASS_BBB_CSW_SIZE,
("%s: CSW struct does not have the right size (%ld vs. %d)\n",
- USBDEVNAME(sc->sc_dev),
+ device_get_nameunit(sc->sc_dev),
(long)sizeof(umass_bbb_csw_t), UMASS_BBB_CSW_SIZE));
/*
@@ -1467,7 +1818,7 @@
}
-Static void
+static void
umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
usbd_status err)
{
@@ -1476,7 +1827,7 @@
KASSERT(sc->proto & UMASS_PROTO_BBB,
("%s: umass_bbb_state: wrong sc->proto 0x%02x\n",
- USBDEVNAME(sc->sc_dev), sc->proto));
+ device_get_nameunit(sc->sc_dev), sc->proto));
/*
* State handling for BBB transfers.
@@ -1490,7 +1841,7 @@
*/
DPRINTF(UDMASS_BBB, ("%s: Handling BBB state %d (%s), xfer=%p, %s\n",
- USBDEVNAME(sc->sc_dev), sc->transfer_state,
+ device_get_nameunit(sc->sc_dev), sc->transfer_state,
states[sc->transfer_state], xfer, usbd_errstr(err)));
/* Give up if the device has detached. */
@@ -1508,7 +1859,7 @@
/* Command transport phase, error handling */
if (err) {
DPRINTF(UDMASS_BBB, ("%s: failed to send CBW\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
/* If the device detects that the CBW is invalid, then
* the device may STALL both bulk endpoints and require
* a Bulk-Reset
@@ -1537,7 +1888,7 @@
return;
} else {
DPRINTF(UDMASS_BBB, ("%s: no data phase\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
}
/* FALLTHROUGH if no data phase, err == 0 */
@@ -1551,7 +1902,7 @@
if (err) {
DPRINTF(UDMASS_BBB, ("%s: Data-%s %db failed, "
- "%s\n", USBDEVNAME(sc->sc_dev),
+ "%s\n", device_get_nameunit(sc->sc_dev),
(sc->transfer_dir == DIR_IN?"in":"out"),
sc->transfer_datalen,usbd_errstr(err)));
@@ -1592,7 +1943,7 @@
if (err) { /* should not occur */
/* try the transfer below, even if clear stall failed */
DPRINTF(UDMASS_BBB, ("%s: bulk-%s stall clear failed"
- ", %s\n", USBDEVNAME(sc->sc_dev),
+ ", %s\n", device_get_nameunit(sc->sc_dev),
(sc->transfer_dir == DIR_IN? "in":"out"),
usbd_errstr(err)));
umass_bbb_reset(sc, STATUS_WIRE_FAILED);
@@ -1628,7 +1979,7 @@
/* Status transfer, error handling */
if (err) {
DPRINTF(UDMASS_BBB, ("%s: Failed to read CSW, %s%s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err),
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err),
(sc->transfer_state == TSTATE_BBB_STATUS1?
", retrying":"")));
@@ -1669,7 +2020,7 @@
* indicate that the device is confused -> reset it.
*/
printf("%s: Invalid CSW: sig 0x%08x should be 0x%08x\n",
- USBDEVNAME(sc->sc_dev),
+ device_get_nameunit(sc->sc_dev),
UGETDW(sc->csw.dCSWSignature),
CSWSIGNATURE);
@@ -1678,7 +2029,7 @@
} else if (UGETDW(sc->csw.dCSWTag)
!= UGETDW(sc->cbw.dCBWTag)) {
printf("%s: Invalid CSW: tag %d should be %d\n",
- USBDEVNAME(sc->sc_dev),
+ device_get_nameunit(sc->sc_dev),
UGETDW(sc->csw.dCSWTag),
UGETDW(sc->cbw.dCBWTag));
@@ -1688,7 +2039,7 @@
/* CSW is valid here */
} else if (sc->csw.bCSWStatus > CSWSTATUS_PHASE) {
printf("%s: Invalid CSW: status %d > %d\n",
- USBDEVNAME(sc->sc_dev),
+ device_get_nameunit(sc->sc_dev),
sc->csw.bCSWStatus,
CSWSTATUS_PHASE);
@@ -1696,7 +2047,7 @@
return;
} else if (sc->csw.bCSWStatus == CSWSTATUS_PHASE) {
printf("%s: Phase Error, residue = %d\n",
- USBDEVNAME(sc->sc_dev), Residue);
+ device_get_nameunit(sc->sc_dev), Residue);
umass_bbb_reset(sc, STATUS_WIRE_FAILED);
return;
@@ -1704,12 +2055,12 @@
} else if (sc->transfer_actlen > sc->transfer_datalen) {
/* Buffer overrun! Don't let this go by unnoticed */
panic("%s: transferred %db instead of %db",
- USBDEVNAME(sc->sc_dev),
+ device_get_nameunit(sc->sc_dev),
sc->transfer_actlen, sc->transfer_datalen);
} else if (sc->csw.bCSWStatus == CSWSTATUS_FAILED) {
DPRINTF(UDMASS_BBB, ("%s: Command Failed, res = %d\n",
- USBDEVNAME(sc->sc_dev), Residue));
+ device_get_nameunit(sc->sc_dev), Residue));
/* SCSI command failed but transfer was succesful */
sc->transfer_state = TSTATE_IDLE;
@@ -1729,7 +2080,7 @@
case TSTATE_BBB_RESET1:
if (err)
printf("%s: BBB reset failed, %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err));
umass_clear_endpoint_stall(sc,
sc->bulkin, sc->bulkin_pipe, TSTATE_BBB_RESET2,
@@ -1739,7 +2090,7 @@
case TSTATE_BBB_RESET2:
if (err) /* should not occur */
printf("%s: BBB bulk-in clear stall failed, %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err));
/* no error recovery, otherwise we end up in a loop */
umass_clear_endpoint_stall(sc,
@@ -1750,7 +2101,7 @@
case TSTATE_BBB_RESET3:
if (err) /* should not occur */
printf("%s: BBB bulk-out clear stall failed, %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err));
/* no error recovery, otherwise we end up in a loop */
sc->transfer_state = TSTATE_IDLE;
@@ -1765,11 +2116,11 @@
/***** Default *****/
default:
panic("%s: Unknown state %d",
- USBDEVNAME(sc->sc_dev), sc->transfer_state);
+ device_get_nameunit(sc->sc_dev), sc->transfer_state);
}
}
-Static int
+static int
umass_bbb_get_max_lun(struct umass_softc *sc)
{
usbd_device_handle udev;
@@ -1794,14 +2145,14 @@
case USBD_NORMAL_COMPLETION:
maxlun = buf;
DPRINTF(UDMASS_BBB, ("%s: Max Lun is %d\n",
- USBDEVNAME(sc->sc_dev), maxlun));
+ device_get_nameunit(sc->sc_dev), maxlun));
break;
case USBD_STALLED:
case USBD_SHORT_XFER:
default:
/* Device doesn't support Get Max Lun request. */
printf("%s: Get Max Lun not supported (%s)\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err));
/* XXX Should we port_reset the device? */
break;
}
@@ -1813,7 +2164,7 @@
* Command/Bulk/Interrupt (CBI) specific functions
*/
-Static int
+static int
umass_cbi_adsc(struct umass_softc *sc, char *buffer, int buflen,
usbd_xfer_handle xfer)
{
@@ -1821,7 +2172,7 @@
KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
("%s: umass_cbi_adsc: wrong sc->proto 0x%02x\n",
- USBDEVNAME(sc->sc_dev), sc->proto));
+ device_get_nameunit(sc->sc_dev), sc->proto));
usbd_interface2device_handle(sc->iface, &udev);
@@ -1835,7 +2186,7 @@
}
-Static void
+static void
umass_cbi_reset(struct umass_softc *sc, int status)
{
int i;
@@ -1843,7 +2194,7 @@
KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
("%s: umass_cbi_reset: wrong sc->proto 0x%02x\n",
- USBDEVNAME(sc->sc_dev), sc->proto));
+ device_get_nameunit(sc->sc_dev), sc->proto));
/*
* Command Block Reset Protocol
@@ -1860,11 +2211,11 @@
*/
DPRINTF(UDMASS_CBI, ("%s: CBI Reset\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
KASSERT(sizeof(sc->cbl) >= SEND_DIAGNOSTIC_CMDLEN,
("%s: CBL struct is too small (%ld < %d)\n",
- USBDEVNAME(sc->sc_dev),
+ device_get_nameunit(sc->sc_dev),
(long)sizeof(sc->cbl), SEND_DIAGNOSTIC_CMDLEN));
sc->transfer_state = TSTATE_CBI_RESET1;
@@ -1884,14 +2235,14 @@
/* XXX if the command fails we should reset the port on the hub */
}
-Static void
+static void
umass_cbi_transfer(struct umass_softc *sc, int lun,
void *cmd, int cmdlen, void *data, int datalen, int dir,
u_int timeout, transfer_cb_f cb, void *priv)
{
KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
("%s: umass_cbi_transfer: wrong sc->proto 0x%02x\n",
- USBDEVNAME(sc->sc_dev), sc->proto));
+ device_get_nameunit(sc->sc_dev), sc->proto));
/* Be a little generous. */
sc->timeout = timeout + UMASS_TIMEOUT;
@@ -1915,10 +2266,10 @@
/* check the given arguments */
KASSERT(datalen == 0 || data != NULL,
- ("%s: datalen > 0, but no buffer",USBDEVNAME(sc->sc_dev)));
+ ("%s: datalen > 0, but no buffer",device_get_nameunit(sc->sc_dev)));
KASSERT(datalen == 0 || dir != DIR_NONE,
("%s: direction is NONE while datalen is not zero\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
/* store the details for the data transfer phase */
sc->transfer_dir = dir;
@@ -1939,7 +2290,7 @@
umass_cbi_reset(sc, STATUS_WIRE_FAILED);
}
-Static void
+static void
umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
usbd_status err)
{
@@ -1947,14 +2298,14 @@
KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
("%s: umass_cbi_state: wrong sc->proto 0x%02x\n",
- USBDEVNAME(sc->sc_dev), sc->proto));
+ device_get_nameunit(sc->sc_dev), sc->proto));
/*
* State handling for CBI transfers.
*/
DPRINTF(UDMASS_CBI, ("%s: Handling CBI state %d (%s), xfer=%p, %s\n",
- USBDEVNAME(sc->sc_dev), sc->transfer_state,
+ device_get_nameunit(sc->sc_dev), sc->transfer_state,
states[sc->transfer_state], xfer, usbd_errstr(err)));
/* Give up if the device has detached. */
@@ -1971,7 +2322,7 @@
case TSTATE_CBI_COMMAND:
if (err == USBD_STALLED) {
DPRINTF(UDMASS_CBI, ("%s: Command Transport failed\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
/* Status transport by control pipe (section 2.3.2.1).
* The command contained in the command block failed.
*
@@ -1989,7 +2340,7 @@
return;
} else if (err) {
DPRINTF(UDMASS_CBI, ("%s: failed to send ADSC\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
umass_cbi_reset(sc, STATUS_WIRE_FAILED);
return;
@@ -2012,7 +2363,7 @@
} else if (sc->proto & UMASS_PROTO_CBI_I) {
DPRINTF(UDMASS_CBI, ("%s: no data phase\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
sc->transfer_state = TSTATE_CBI_STATUS;
if (umass_setup_transfer(sc, sc->intrin_pipe,
&sc->sbl, sizeof(sc->sbl),
@@ -2022,7 +2373,7 @@
}
} else {
DPRINTF(UDMASS_CBI, ("%s: no data phase\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
/* No command completion interrupt. Request
* sense data.
*/
@@ -2039,7 +2390,7 @@
if (err) {
DPRINTF(UDMASS_CBI, ("%s: Data-%s %db failed, "
- "%s\n", USBDEVNAME(sc->sc_dev),
+ "%s\n", device_get_nameunit(sc->sc_dev),
(sc->transfer_dir == DIR_IN?"in":"out"),
sc->transfer_datalen,usbd_errstr(err)));
@@ -2080,7 +2431,7 @@
case TSTATE_CBI_STATUS:
if (err) {
DPRINTF(UDMASS_CBI, ("%s: Status Transport failed\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
/* Status transport by interrupt pipe (section 2.3.2.2).
*/
@@ -2107,7 +2458,7 @@
DPRINTF(UDMASS_CBI, ("%s: UFI CCI, ASC = 0x%02x, "
"ASCQ = 0x%02x\n",
- USBDEVNAME(sc->sc_dev),
+ device_get_nameunit(sc->sc_dev),
sc->sbl.ufi.asc, sc->sbl.ufi.ascq));
if (sc->sbl.ufi.asc == 0 && sc->sbl.ufi.ascq == 0)
@@ -2122,7 +2473,7 @@
} else {
/* Command Interrupt Data Block */
DPRINTF(UDMASS_CBI, ("%s: type=0x%02x, value=0x%02x\n",
- USBDEVNAME(sc->sc_dev),
+ device_get_nameunit(sc->sc_dev),
sc->sbl.common.type, sc->sbl.common.value));
if (sc->sbl.common.type == IDB_TYPE_CCI) {
@@ -2151,7 +2502,7 @@
case TSTATE_CBI_DCLEAR:
if (err) { /* should not occur */
printf("%s: CBI bulk-in/out stall clear failed, %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err));
umass_cbi_reset(sc, STATUS_WIRE_FAILED);
}
@@ -2164,7 +2515,7 @@
case TSTATE_CBI_SCLEAR:
if (err) /* should not occur */
printf("%s: CBI intr-in stall clear failed, %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err));
/* Something really bad is going on. Reset the device */
umass_cbi_reset(sc, STATUS_CMD_FAILED);
@@ -2174,7 +2525,7 @@
case TSTATE_CBI_RESET1:
if (err)
printf("%s: CBI reset failed, %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err));
umass_clear_endpoint_stall(sc,
sc->bulkin, sc->bulkin_pipe, TSTATE_CBI_RESET2,
@@ -2184,7 +2535,7 @@
case TSTATE_CBI_RESET2:
if (err) /* should not occur */
printf("%s: CBI bulk-in stall clear failed, %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err));
/* no error recovery, otherwise we end up in a loop */
umass_clear_endpoint_stall(sc,
@@ -2195,7 +2546,7 @@
case TSTATE_CBI_RESET3:
if (err) /* should not occur */
printf("%s: CBI bulk-out stall clear failed, %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
+ device_get_nameunit(sc->sc_dev), usbd_errstr(err));
/* no error recovery, otherwise we end up in a loop */
sc->transfer_state = TSTATE_IDLE;
@@ -2211,7 +2562,7 @@
/***** Default *****/
default:
panic("%s: Unknown state %d",
- USBDEVNAME(sc->sc_dev), sc->transfer_state);
+ device_get_nameunit(sc->sc_dev), sc->transfer_state);
}
}
@@ -2222,7 +2573,7 @@
* CAM specific functions (used by SCSI, UFI, 8070i (ATAPI))
*/
-Static int
+static int
umass_cam_attach_sim(struct umass_softc *sc)
{
struct cam_devq *devq; /* Per device Queue */
@@ -2240,7 +2591,8 @@
sc->umass_sim = cam_sim_alloc(umass_cam_action, umass_cam_poll,
DEVNAME_SIM,
sc /*priv*/,
- USBDEVUNIT(sc->sc_dev) /*unit number*/,
+ device_get_unit(sc->sc_dev) /*unit number*/,
+ &Giant,
1 /*maximum device openings*/,
0 /*maximum tagged device openings*/,
devq);
@@ -2249,14 +2601,14 @@
return(ENOMEM);
}
- if(xpt_bus_register(sc->umass_sim, USBDEVUNIT(sc->sc_dev)) !=
+ if(xpt_bus_register(sc->umass_sim, NULL, device_get_unit(sc->sc_dev)) !=
CAM_SUCCESS)
return(ENOMEM);
return(0);
}
-Static void
+static void
umass_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
{
#ifdef USB_DEBUG
@@ -2274,7 +2626,7 @@
free(ccb, M_USBDEV);
}
-Static void
+static void
umass_cam_rescan(void *addr)
{
struct umass_softc *sc = (struct umass_softc *) addr;
@@ -2283,14 +2635,14 @@
DPRINTF(UDMASS_SCSI, ("scbus%d: scanning for %s:%d:%d:%d\n",
cam_sim_path(sc->umass_sim),
- USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
- USBDEVUNIT(sc->sc_dev), CAM_LUN_WILDCARD));
+ device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
+ device_get_unit(sc->sc_dev), CAM_LUN_WILDCARD));
ccb = malloc(sizeof(union ccb), M_USBDEV, M_NOWAIT | M_ZERO);
if (ccb == NULL)
return;
if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->umass_sim),
- CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)
+ device_get_unit(sc->sc_dev), CAM_LUN_WILDCARD)
!= CAM_REQ_CMP) {
free(ccb, M_USBDEV);
return;
@@ -2305,15 +2657,15 @@
/* The scan is in progress now. */
}
-Static int
+static int
umass_cam_attach(struct umass_softc *sc)
{
#ifndef USB_DEBUG
if (bootverbose)
#endif
printf("%s:%d:%d:%d: Attached to scbus%d\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
- USBDEVUNIT(sc->sc_dev), CAM_LUN_WILDCARD,
+ device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
+ device_get_unit(sc->sc_dev), CAM_LUN_WILDCARD,
cam_sim_path(sc->umass_sim));
if (!cold) {
@@ -2324,7 +2676,7 @@
* completed, when interrupts have been enabled.
*/
- usb_callout(sc->cam_scsi_rescan_ch, MS_TO_TICKS(200),
+ callout_reset(&sc->cam_scsi_rescan_ch, MS_TO_TICKS(200),
umass_cam_rescan, sc);
}
@@ -2335,7 +2687,7 @@
* detach from the CAM layer
*/
-Static int
+static int
umass_cam_detach_sim(struct umass_softc *sc)
{
if (sc->umass_sim) {
@@ -2354,7 +2706,7 @@
* CAM requests for action come through here
*/
-Static void
+static void
umass_cam_action(struct cam_sim *sim, union ccb *ccb)
{
struct umass_softc *sc = (struct umass_softc *)sim->softc;
@@ -2365,7 +2717,7 @@
if (sc && (sc->flags & UMASS_FLAGS_GONE)) {
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
"Invalid target (gone)\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
+ device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
ccb->ccb_h.func_code));
ccb->ccb_h.status = CAM_TID_INVALID;
@@ -2436,7 +2788,7 @@
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SCSI_IO: "
"cmd: 0x%02x, flags: 0x%02x, "
"%db cmd/%db data/%db sense\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
+ device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
csio->cdb_io.cdb_bytes[0],
ccb->ccb_h.flags & CAM_DIR_MASK,
@@ -2454,7 +2806,7 @@
if (sc->transfer_state != TSTATE_IDLE) {
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SCSI_IO: "
"I/O in progress, deferring (state %d, %s)\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
+ device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
sc->transfer_state,states[sc->transfer_state]));
ccb->ccb_h.status = CAM_SCSI_BUSY;
@@ -2493,7 +2845,8 @@
* buffer (see umass_scsi_transform).
*/
- if (sc->transform(sc, cmd, cmdlen, &rcmd, &rcmdlen)) {
+ switch (sc->transform(sc, cmd, cmdlen, &rcmd, &rcmdlen)) {
+ case 1:
/*
* Handle EVPD inquiry for broken devices first
* NO_INQUIRY also implies NO_INQUIRY_EVPD
@@ -2533,9 +2886,15 @@
csio->data_ptr,
csio->dxfer_len, dir, ccb->ccb_h.timeout,
umass_cam_cb, (void *) ccb);
- } else {
+ break;
+ case 0:
ccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(ccb);
+ break;
+ case 2:
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ break;
}
break;
@@ -2545,7 +2904,7 @@
struct ccb_pathinq *cpi = &ccb->cpi;
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_PATH_INQ:.\n",
- (sc == NULL? DEVNAME_SIM:USBDEVNAME(sc->sc_dev)),
+ (sc == NULL? DEVNAME_SIM:device_get_nameunit(sc->sc_dev)),
cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
@@ -2561,7 +2920,11 @@
strncpy(cpi->hba_vid, "USB SCSI", HBA_IDLEN);
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
cpi->unit_number = cam_sim_unit(sim);
- cpi->bus_id = USBDEVUNIT(sc->sc_dev);
+ cpi->bus_id = device_get_unit(sc->sc_dev);
+ cpi->protocol = PROTO_SCSI;
+ cpi->protocol_version = SCSI_REV_2;
+ cpi->transport = XPORT_USB;
+ cpi->transport_version = 0;
if (sc == NULL) {
cpi->base_transfer_speed = 0;
@@ -2588,7 +2951,7 @@
case XPT_RESET_DEV:
{
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_RESET_DEV:.\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
+ device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
ccb->ccb_h.status = CAM_REQ_INPROG;
@@ -2598,13 +2961,12 @@
case XPT_GET_TRAN_SETTINGS:
{
struct ccb_trans_settings *cts = &ccb->cts;
+ cts->protocol = PROTO_SCSI;
+ cts->protocol_version = SCSI_REV_2;
+ cts->transport = XPORT_USB;
+ cts->transport_version = 0;
+ cts->xport_specific.valid = 0;
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_GET_TRAN_SETTINGS:.\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
-
- cts->valid = 0;
- cts->flags = 0; /* no disconnection, tagging */
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
@@ -2613,7 +2975,7 @@
case XPT_SET_TRAN_SETTINGS:
{
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SET_TRAN_SETTINGS:.\n",
- USBDEVNAME(sc->sc_dev), cam_sim_path(sc->umass_sim),
+ device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
@@ -2629,7 +2991,7 @@
case XPT_NOOP:
{
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_NOOP:.\n",
- (sc == NULL? DEVNAME_SIM:USBDEVNAME(sc->sc_dev)),
+ (sc == NULL? DEVNAME_SIM:device_get_nameunit(sc->sc_dev)),
cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
@@ -2640,7 +3002,7 @@
default:
DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
"Not implemented\n",
- (sc == NULL? DEVNAME_SIM:USBDEVNAME(sc->sc_dev)),
+ (sc == NULL? DEVNAME_SIM:device_get_nameunit(sc->sc_dev)),
cam_sim_path(sc->umass_sim),
ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
ccb->ccb_h.func_code));
@@ -2651,21 +3013,17 @@
}
}
-/* umass_cam_poll
- * all requests are handled through umass_cam_action, requests
- * are never pending. So, nothing to do here.
- */
-Static void
+static void
umass_cam_poll(struct cam_sim *sim)
{
-#ifdef USB_DEBUG
struct umass_softc *sc = (struct umass_softc *) sim->softc;
DPRINTF(UDMASS_SCSI, ("%s: CAM poll\n",
- USBDEVNAME(sc->sc_dev)));
-#endif
+ device_get_nameunit(sc->sc_dev)));
- /* nop */
+ usbd_set_polling(sc->sc_udev, 1);
+ usbd_dopoll(sc->iface);
+ usbd_set_polling(sc->sc_udev, 0);
}
@@ -2673,7 +3031,7 @@
* finalise a completed CAM command
*/
-Static void
+static void
umass_cam_cb(struct umass_softc *sc, void *priv, int residue, int status)
{
union ccb *ccb = (union ccb *) priv;
@@ -2691,6 +3049,16 @@
switch (status) {
case STATUS_CMD_OK:
ccb->ccb_h.status = CAM_REQ_CMP;
+ if ((sc->quirks & READ_CAPACITY_OFFBY1) &&
+ (ccb->ccb_h.func_code == XPT_SCSI_IO) &&
+ (csio->cdb_io.cdb_bytes[0] == READ_CAPACITY)) {
+ struct scsi_read_capacity_data *rcap;
+ uint32_t maxsector;
+
+ rcap = (struct scsi_read_capacity_data *)csio->data_ptr;
+ maxsector = scsi_4btoul(rcap->addr) - 1;
+ scsi_ulto4b(maxsector, rcap->addr);
+ }
xpt_done(ccb);
break;
@@ -2707,7 +3075,7 @@
sc->cam_scsi_sense.length = csio->sense_len;
DPRINTF(UDMASS_SCSI,("%s: Fetching %db sense data\n",
- USBDEVNAME(sc->sc_dev), csio->sense_len));
+ device_get_nameunit(sc->sc_dev), csio->sense_len));
rcmd = (unsigned char *) &sc->cam_scsi_command;
rcmdlen = sizeof(sc->cam_scsi_command);
@@ -2715,7 +3083,7 @@
if (sc->transform(sc,
(unsigned char *) &sc->cam_scsi_sense,
sizeof(sc->cam_scsi_sense),
- &rcmd, &rcmdlen)) {
+ &rcmd, &rcmdlen) == 1) {
if ((sc->quirks & FORCE_SHORT_INQUIRY) && (rcmd[0] == INQUIRY)) {
csio->sense_len = SHORT_INQUIRY_LENGTH;
}
@@ -2749,13 +3117,13 @@
break;
default:
panic("%s: Unknown status %d in umass_cam_cb",
- USBDEVNAME(sc->sc_dev), status);
+ device_get_nameunit(sc->sc_dev), status);
}
}
/* Finalise a completed autosense operation
*/
-Static void
+static void
umass_cam_sense_cb(struct umass_softc *sc, void *priv, int residue, int status)
{
union ccb *ccb = (union ccb *) priv;
@@ -2814,7 +3182,7 @@
DPRINTF(UDMASS_SCSI,("%s: Doing a sneaky"
"TEST_UNIT_READY\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
/* the rest of the command was filled in at attach */
@@ -2825,7 +3193,7 @@
(unsigned char *)
&sc->cam_scsi_test_unit_ready,
sizeof(sc->cam_scsi_test_unit_ready),
- &rcmd, &rcmdlen)) {
+ &rcmd, &rcmdlen) == 1) {
sc->transfer(sc, ccb->ccb_h.target_lun,
rcmd, rcmdlen,
NULL, 0, DIR_NONE, ccb->ccb_h.timeout,
@@ -2844,7 +3212,7 @@
default:
DPRINTF(UDMASS_SCSI, ("%s: Autosense failed, status %d\n",
- USBDEVNAME(sc->sc_dev), status));
+ device_get_nameunit(sc->sc_dev), status));
ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
xpt_done(ccb);
}
@@ -2855,13 +3223,13 @@
* after having previously failed a READ CAPACITY with CHECK_COND. Even
* though this command succeeded, we have to tell CAM to retry.
*/
-Static void
+static void
umass_cam_quirk_cb(struct umass_softc *sc, void *priv, int residue, int status)
{
union ccb *ccb = (union ccb *) priv;
DPRINTF(UDMASS_SCSI, ("%s: Test unit ready returned status %d\n",
- USBDEVNAME(sc->sc_dev), status));
+ device_get_nameunit(sc->sc_dev), status));
if (sc->flags & UMASS_FLAGS_GONE) {
ccb->ccb_h.status = CAM_TID_INVALID;
@@ -2877,7 +3245,7 @@
xpt_done(ccb);
}
-Static int
+static int
umass_driver_load(module_t mod, int what, void *arg)
{
switch (what) {
@@ -2892,7 +3260,7 @@
* SCSI specific functions
*/
-Static int
+static int
umass_scsi_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
unsigned char **rcmd, int *rcmdlen)
{
@@ -2904,7 +3272,7 @@
*rcmdlen,
(long)sizeof(struct scsi_start_stop_unit)));
DPRINTF(UDMASS_SCSI, ("%s: Converted TEST_UNIT_READY "
- "to START_UNIT\n", USBDEVNAME(sc->sc_dev)));
+ "to START_UNIT\n", device_get_nameunit(sc->sc_dev)));
memset(*rcmd, 0, *rcmdlen);
(*rcmd)[0] = START_STOP_UNIT;
(*rcmd)[4] = SSS_START;
@@ -2928,7 +3296,7 @@
return 1;
}
/* RBC specific functions */
-Static int
+static int
umass_rbc_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
unsigned char **rcmd, int *rcmdlen)
{
@@ -2962,7 +3330,7 @@
/* All other commands are not legal in RBC */
default:
printf("%s: Unsupported RBC command 0x%02x",
- USBDEVNAME(sc->sc_dev), cmd[0]);
+ device_get_nameunit(sc->sc_dev), cmd[0]);
printf("\n");
return 0; /* failure */
}
@@ -2971,7 +3339,7 @@
/*
* UFI specific functions
*/
-Static int
+static int
umass_ufi_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
unsigned char **rcmd, int *rcmdlen)
{
@@ -2993,7 +3361,7 @@
* Start Stop Unit should give the same results
*/
DPRINTF(UDMASS_UFI, ("%s: Converted TEST_UNIT_READY "
- "to START_UNIT\n", USBDEVNAME(sc->sc_dev)));
+ "to START_UNIT\n", device_get_nameunit(sc->sc_dev)));
(*rcmd)[0] = START_STOP_UNIT;
(*rcmd)[4] = SSS_START;
} else {
@@ -3022,9 +3390,17 @@
memcpy(*rcmd, cmd, cmdlen);
return 1;
+ /*
+ * SYNCHRONIZE_CACHE isn't supported by UFI, nor should it be
+ * required for UFI devices, so it is appropriate to fake
+ * success.
+ */
+ case SYNCHRONIZE_CACHE:
+ return 2;
+
default:
printf("%s: Unsupported UFI command 0x%02x\n",
- USBDEVNAME(sc->sc_dev), cmd[0]);
+ device_get_nameunit(sc->sc_dev), cmd[0]);
return 0; /* failure */
}
}
@@ -3032,7 +3408,7 @@
/*
* 8070i (ATAPI) specific functions
*/
-Static int
+static int
umass_atapi_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
unsigned char **rcmd, int *rcmdlen)
{
@@ -3062,7 +3438,7 @@
*rcmdlen,
(long)sizeof(struct scsi_start_stop_unit)));
DPRINTF(UDMASS_SCSI, ("%s: Converted TEST_UNIT_READY "
- "to START_UNIT\n", USBDEVNAME(sc->sc_dev)));
+ "to START_UNIT\n", device_get_nameunit(sc->sc_dev)));
memset(*rcmd, 0, *rcmdlen);
(*rcmd)[0] = START_STOP_UNIT;
(*rcmd)[4] = SSS_START;
@@ -3108,9 +3484,11 @@
case READ_12:
case WRITE_12:
default:
- printf("%s: Unsupported ATAPI command 0x%02x\n",
- USBDEVNAME(sc->sc_dev), cmd[0]);
- return 0; /* failure */
+ printf("%s: Unsupported ATAPI command 0x%02x"
+ " - trying anyway\n",
+ device_get_nameunit(sc->sc_dev), cmd[0]);
+ memcpy(*rcmd, cmd, cmdlen);
+ return 1;
}
}
@@ -3122,7 +3500,7 @@
#ifdef USB_DEBUG
-Static void
+static void
umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw)
{
int clen = cbw->bCDBLength;
@@ -3134,13 +3512,13 @@
DPRINTF(UDMASS_BBB, ("%s: CBW %d: cmd = %db "
"(0x%02x%02x%02x%02x%02x%02x%s), "
"data = %db, dir = %s\n",
- USBDEVNAME(sc->sc_dev), tag, clen,
+ device_get_nameunit(sc->sc_dev), tag, clen,
c[0], c[1], c[2], c[3], c[4], c[5], (clen > 6? "...":""),
dlen, (flags == CBWFLAGS_IN? "in":
(flags == CBWFLAGS_OUT? "out":"<invalid>"))));
}
-Static void
+static void
umass_bbb_dump_csw(struct umass_softc *sc, umass_bbb_csw_t *csw)
{
int sig = UGETDW(csw->dCSWSignature);
@@ -3149,7 +3527,7 @@
int status = csw->bCSWStatus;
DPRINTF(UDMASS_BBB, ("%s: CSW %d: sig = 0x%08x (%s), tag = %d, "
- "res = %d, status = 0x%02x (%s)\n", USBDEVNAME(sc->sc_dev),
+ "res = %d, status = 0x%02x (%s)\n", device_get_nameunit(sc->sc_dev),
tag, sig, (sig == CSWSIGNATURE? "valid":"invalid"),
tag, res,
status, (status == CSWSTATUS_GOOD? "good":
@@ -3157,7 +3535,7 @@
(status == CSWSTATUS_PHASE? "phase":"<invalid>")))));
}
-Static void
+static void
umass_cbi_dump_cmd(struct umass_softc *sc, void *cmd, int cmdlen)
{
u_int8_t *c = cmd;
@@ -3166,7 +3544,7 @@
DPRINTF(UDMASS_BBB, ("%s: cmd = %db "
"(0x%02x%02x%02x%02x%02x%02x%s), "
"data = %db, dir = %s\n",
- USBDEVNAME(sc->sc_dev), cmdlen,
+ device_get_nameunit(sc->sc_dev), cmdlen,
c[0], c[1], c[2], c[3], c[4], c[5], (cmdlen > 6? "...":""),
sc->transfer_datalen,
(dir == DIR_IN? "in":
@@ -3174,7 +3552,7 @@
(dir == DIR_NONE? "no data phase": "<invalid>")))));
}
-Static void
+static void
umass_dump_buffer(struct umass_softc *sc, u_int8_t *buffer, int buflen,
int printlen)
{
@@ -3191,7 +3569,7 @@
j = i % 16;
if (j == 0 && i != 0) {
DPRINTF(UDMASS_GEN, ("%s: 0x %s%s\n",
- USBDEVNAME(sc->sc_dev), s1, s2));
+ device_get_nameunit(sc->sc_dev), s1, s2));
s2[0] = '\0';
}
sprintf(&s1[j*2], "%02x", buffer[i] & 0xff);
@@ -3199,6 +3577,6 @@
if (buflen > printlen)
sprintf(s3, " ...");
DPRINTF(UDMASS_GEN, ("%s: 0x %s%s%s\n",
- USBDEVNAME(sc->sc_dev), s1, s2, s3));
+ device_get_nameunit(sc->sc_dev), s1, s2, s3));
}
#endif
More information about the Midnightbsd-cvs
mailing list