Some devices have a dual mode such as Tenda W326U and ZyXEL NWD2705,

add the product id and use a standard scsi eject.

Tested on the ZyXEL NWD2705 wlan dongle.
This commit is contained in:
kevlo 2013-12-24 07:02:05 +00:00
parent b045f69bf5
commit 4cebeb74ee
2 changed files with 53 additions and 1 deletions

View File

@ -3601,6 +3601,7 @@ product RALINK RT2573 0x2573 RT2501USB Wireless Adapter
product RALINK RT2671 0x2671 RT2601USB Wireless Adapter product RALINK RT2671 0x2671 RT2601USB Wireless Adapter
product RALINK RT2770 0x2770 RT2770 product RALINK RT2770 0x2770 RT2770
product RALINK RT2870 0x2870 RT2870 product RALINK RT2870 0x2870 RT2870
product RALINK RT_STOR 0x2878 USB Storage
product RALINK RT3070 0x3070 RT3070 product RALINK RT3070 0x3070 RT3070
product RALINK RT3071 0x3071 RT3071 product RALINK RT3071 0x3071 RT3071
product RALINK RT3072 0x3072 RT3072 product RALINK RT3072 0x3072 RT3072
@ -4480,3 +4481,4 @@ product ZYXEL G202 0x3410 G-202
product ZYXEL RT2870_1 0x3416 RT2870 product ZYXEL RT2870_1 0x3416 RT2870
product ZYXEL RT2870_2 0x341a RT2870 product ZYXEL RT2870_2 0x341a RT2870
product ZYXEL RTL8192CU 0x341f RTL8192CU product ZYXEL RTL8192CU 0x341f RTL8192CU
product ZYXEL NWD2705 0x3421 NWD2705

View File

@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
#define USB_DEBUG_VAR run_debug #define USB_DEBUG_VAR run_debug
#include <dev/usb/usb_debug.h> #include <dev/usb/usb_debug.h>
#include <dev/usb/usb_msctest.h>
#include <dev/usb/wlan/if_runreg.h> #include <dev/usb/wlan/if_runreg.h>
#include <dev/usb/wlan/if_runvar.h> #include <dev/usb/wlan/if_runvar.h>
@ -98,6 +99,8 @@ SYSCTL_INT(_hw_usb_run, OID_AUTO, debug, CTLFLAG_RW, &run_debug, 0,
static const STRUCT_USB_HOST_ID run_devs[] = { static const STRUCT_USB_HOST_ID run_devs[] = {
#define RUN_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } #define RUN_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
#define RUN_DEV_EJECT(v,p) \
{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, 0) }
RUN_DEV(ABOCOM, RT2770), RUN_DEV(ABOCOM, RT2770),
RUN_DEV(ABOCOM, RT2870), RUN_DEV(ABOCOM, RT2870),
RUN_DEV(ABOCOM, RT3070), RUN_DEV(ABOCOM, RT3070),
@ -307,6 +310,8 @@ static const STRUCT_USB_HOST_ID run_devs[] = {
RUN_DEV(ZINWELL, RT3072_2), RUN_DEV(ZINWELL, RT3072_2),
RUN_DEV(ZYXEL, RT2870_1), RUN_DEV(ZYXEL, RT2870_1),
RUN_DEV(ZYXEL, RT2870_2), RUN_DEV(ZYXEL, RT2870_2),
RUN_DEV_EJECT(RALINK, RT_STOR),
#undef RUN_DEV_EJECT
#undef RUN_DEV #undef RUN_DEV
}; };
@ -322,6 +327,9 @@ static usb_callback_t run_bulk_tx_callback3;
static usb_callback_t run_bulk_tx_callback4; static usb_callback_t run_bulk_tx_callback4;
static usb_callback_t run_bulk_tx_callback5; static usb_callback_t run_bulk_tx_callback5;
static void run_autoinst(void *, struct usb_device *,
struct usb_attach_arg *);
static int run_driver_loaded(struct module *, int, void *);
static void run_bulk_tx_callbackN(struct usb_xfer *xfer, static void run_bulk_tx_callbackN(struct usb_xfer *xfer,
usb_error_t error, u_int index); usb_error_t error, u_int index);
static struct ieee80211vap *run_vap_create(struct ieee80211com *, static struct ieee80211vap *run_vap_create(struct ieee80211com *,
@ -438,6 +446,8 @@ static void run_init_locked(struct run_softc *);
static void run_stop(void *); static void run_stop(void *);
static void run_delay(struct run_softc *, u_int); static void run_delay(struct run_softc *, u_int);
static eventhandler_tag run_etag;
static const struct rt2860_rate { static const struct rt2860_rate {
uint8_t rate; uint8_t rate;
uint8_t mcs; uint8_t mcs;
@ -614,6 +624,46 @@ static const struct usb_config run_config[RUN_N_XFER] = {
} }
}; };
static void
run_autoinst(void *arg, struct usb_device *udev,
struct usb_attach_arg *uaa)
{
struct usb_interface *iface;
struct usb_interface_descriptor *id;
if (uaa->dev_state != UAA_DEV_READY)
return;
iface = usbd_get_iface(udev, 0);
if (iface == NULL)
return;
id = iface->idesc;
if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
return;
if (usbd_lookup_id_by_uaa(run_devs, sizeof(run_devs), uaa))
return;
if (usb_msc_eject(udev, 0, MSC_EJECT_STOPUNIT) == 0)
uaa->dev_state = UAA_DEV_EJECTING;
}
static int
run_driver_loaded(struct module *mod, int what, void *arg)
{
switch (what) {
case MOD_LOAD:
run_etag = EVENTHANDLER_REGISTER(usb_dev_configured,
run_autoinst, NULL, EVENTHANDLER_PRI_ANY);
break;
case MOD_UNLOAD:
EVENTHANDLER_DEREGISTER(usb_dev_configured, run_etag);
break;
default:
return (EOPNOTSUPP);
}
return (0);
}
static int static int
run_match(device_t self) run_match(device_t self)
{ {
@ -5793,7 +5843,7 @@ static driver_t run_driver = {
static devclass_t run_devclass; static devclass_t run_devclass;
DRIVER_MODULE(run, uhub, run_driver, run_devclass, NULL, NULL); DRIVER_MODULE(run, uhub, run_driver, run_devclass, run_driver_loaded, NULL);
MODULE_DEPEND(run, wlan, 1, 1, 1); MODULE_DEPEND(run, wlan, 1, 1, 1);
MODULE_DEPEND(run, usb, 1, 1, 1); MODULE_DEPEND(run, usb, 1, 1, 1);
MODULE_DEPEND(run, firmware, 1, 1, 1); MODULE_DEPEND(run, firmware, 1, 1, 1);