Deleted Added
full compact
if_uath.c (243857) if_uath.c (244503)
1/*-
2 * Copyright (c) 2006 Sam Leffler, Errno Consulting
3 * Copyright (c) 2008-2009 Weongyo Jeong <weongyo@freebsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 35 unchanged lines hidden (view full) ---

44 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
45 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
46 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
47 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
48 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
49 */
50
51#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2006 Sam Leffler, Errno Consulting
3 * Copyright (c) 2008-2009 Weongyo Jeong <weongyo@freebsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 35 unchanged lines hidden (view full) ---

44 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
45 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
46 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
47 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
48 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
49 */
50
51#include <sys/cdefs.h>
52__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_uath.c 243857 2012-12-04 09:32:43Z glebius $");
52__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_uath.c 244503 2012-12-20 18:38:02Z hselasky $");
53
54/*-
55 * Driver for Atheros AR5523 USB parts.
56 *
57 * The driver requires firmware to be loaded into the device. This
58 * is done on device discovery from a user application (uathload)
59 * that is launched by devd when a device with suitable product ID
60 * is recognized. Once firmware has been loaded the device will

--- 151 unchanged lines hidden (view full) ---

212 .short_xfer_ok = 1
213 },
214 .callback = uath_intr_rx_callback
215 },
216 [UATH_INTR_TX] = {
217 .type = UE_BULK,
218 .endpoint = 0x1,
219 .direction = UE_DIR_OUT,
53
54/*-
55 * Driver for Atheros AR5523 USB parts.
56 *
57 * The driver requires firmware to be loaded into the device. This
58 * is done on device discovery from a user application (uathload)
59 * that is launched by devd when a device with suitable product ID
60 * is recognized. Once firmware has been loaded the device will

--- 151 unchanged lines hidden (view full) ---

212 .short_xfer_ok = 1
213 },
214 .callback = uath_intr_rx_callback
215 },
216 [UATH_INTR_TX] = {
217 .type = UE_BULK,
218 .endpoint = 0x1,
219 .direction = UE_DIR_OUT,
220 .bufsize = UATH_MAX_CMDSZ,
220 .bufsize = UATH_MAX_CMDSZ * UATH_CMD_LIST_COUNT,
221 .flags = {
221 .flags = {
222 .ext_buffer = 1,
223 .force_short_xfer = 1,
224 .pipe_bof = 1,
225 },
226 .callback = uath_intr_tx_callback,
227 .timeout = UATH_CMD_TIMEOUT
228 },
229 [UATH_BULK_RX] = {
230 .type = UE_BULK,

--- 6 unchanged lines hidden (view full) ---

237 .short_xfer_ok = 1
238 },
239 .callback = uath_bulk_rx_callback
240 },
241 [UATH_BULK_TX] = {
242 .type = UE_BULK,
243 .endpoint = 0x2,
244 .direction = UE_DIR_OUT,
222 .force_short_xfer = 1,
223 .pipe_bof = 1,
224 },
225 .callback = uath_intr_tx_callback,
226 .timeout = UATH_CMD_TIMEOUT
227 },
228 [UATH_BULK_RX] = {
229 .type = UE_BULK,

--- 6 unchanged lines hidden (view full) ---

236 .short_xfer_ok = 1
237 },
238 .callback = uath_bulk_rx_callback
239 },
240 [UATH_BULK_TX] = {
241 .type = UE_BULK,
242 .endpoint = 0x2,
243 .direction = UE_DIR_OUT,
245 .bufsize = UATH_MAX_TXBUFSZ,
244 .bufsize = UATH_MAX_TXBUFSZ * UATH_TX_DATA_LIST_COUNT,
246 .flags = {
245 .flags = {
247 .ext_buffer = 1,
248 .force_short_xfer = 1,
249 .pipe_bof = 1
250 },
251 .callback = uath_bulk_tx_callback,
252 .timeout = UATH_DATA_TIMEOUT
253 }
254};
255
256static struct ieee80211vap *uath_vap_create(struct ieee80211com *,
257 const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
258 const uint8_t [IEEE80211_ADDR_LEN],
259 const uint8_t [IEEE80211_ADDR_LEN]);
260static void uath_vap_delete(struct ieee80211vap *);
246 .force_short_xfer = 1,
247 .pipe_bof = 1
248 },
249 .callback = uath_bulk_tx_callback,
250 .timeout = UATH_DATA_TIMEOUT
251 }
252};
253
254static struct ieee80211vap *uath_vap_create(struct ieee80211com *,
255 const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
256 const uint8_t [IEEE80211_ADDR_LEN],
257 const uint8_t [IEEE80211_ADDR_LEN]);
258static void uath_vap_delete(struct ieee80211vap *);
261static int uath_alloc_cmd_list(struct uath_softc *, struct uath_cmd [],
262 int, int);
263static void uath_free_cmd_list(struct uath_softc *, struct uath_cmd [],
264 int);
259static int uath_alloc_cmd_list(struct uath_softc *, struct uath_cmd []);
260static void uath_free_cmd_list(struct uath_softc *, struct uath_cmd []);
265static int uath_host_available(struct uath_softc *);
266static int uath_get_capability(struct uath_softc *, uint32_t, uint32_t *);
267static int uath_get_devcap(struct uath_softc *);
268static struct uath_cmd *
269 uath_get_cmdbuf(struct uath_softc *);
270static int uath_cmd_read(struct uath_softc *, uint32_t, const void *,
271 int, void *, int, int);
272static int uath_cmd_write(struct uath_softc *, uint32_t, const void *,

--- 87 unchanged lines hidden (view full) ---

360 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
361 MTX_DEF);
362 callout_init(&sc->stat_ch, 0);
363 callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
364
365 /*
366 * Allocate xfers for firmware commands.
367 */
261static int uath_host_available(struct uath_softc *);
262static int uath_get_capability(struct uath_softc *, uint32_t, uint32_t *);
263static int uath_get_devcap(struct uath_softc *);
264static struct uath_cmd *
265 uath_get_cmdbuf(struct uath_softc *);
266static int uath_cmd_read(struct uath_softc *, uint32_t, const void *,
267 int, void *, int, int);
268static int uath_cmd_write(struct uath_softc *, uint32_t, const void *,

--- 87 unchanged lines hidden (view full) ---

356 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
357 MTX_DEF);
358 callout_init(&sc->stat_ch, 0);
359 callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
360
361 /*
362 * Allocate xfers for firmware commands.
363 */
368 error = uath_alloc_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT,
369 UATH_MAX_CMDSZ);
364 error = uath_alloc_cmd_list(sc, sc->sc_cmd);
370 if (error != 0) {
371 device_printf(sc->sc_dev,
372 "could not allocate Tx command list\n");
373 goto fail;
374 }
375
376 error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
377 uath_usbconfig, UATH_N_XFERS, sc, &sc->sc_mtx);
378 if (error) {
379 device_printf(dev, "could not allocate USB transfers, "
380 "err=%s\n", usbd_errstr(error));
381 goto fail1;
382 }
383
365 if (error != 0) {
366 device_printf(sc->sc_dev,
367 "could not allocate Tx command list\n");
368 goto fail;
369 }
370
371 error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
372 uath_usbconfig, UATH_N_XFERS, sc, &sc->sc_mtx);
373 if (error) {
374 device_printf(dev, "could not allocate USB transfers, "
375 "err=%s\n", usbd_errstr(error));
376 goto fail1;
377 }
378
379 sc->sc_cmd_dma_buf =
380 usbd_xfer_get_frame_buffer(sc->sc_xfer[UATH_INTR_TX], 0);
381 sc->sc_tx_dma_buf =
382 usbd_xfer_get_frame_buffer(sc->sc_xfer[UATH_BULK_TX], 0);
383
384 /*
385 * We're now ready to send+receive firmware commands.
386 */
387 UATH_LOCK(sc);
388 error = uath_host_available(sc);
389 if (error != 0) {
390 device_printf(sc->sc_dev, "could not initialize adapter\n");
391 goto fail3;

--- 96 unchanged lines hidden (view full) ---

488 if (bootverbose)
489 ieee80211_announce(ic);
490
491 return (0);
492
493fail4: if_free(ifp);
494fail3: UATH_UNLOCK(sc);
495fail2: usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS);
384 /*
385 * We're now ready to send+receive firmware commands.
386 */
387 UATH_LOCK(sc);
388 error = uath_host_available(sc);
389 if (error != 0) {
390 device_printf(sc->sc_dev, "could not initialize adapter\n");
391 goto fail3;

--- 96 unchanged lines hidden (view full) ---

488 if (bootverbose)
489 ieee80211_announce(ic);
490
491 return (0);
492
493fail4: if_free(ifp);
494fail3: UATH_UNLOCK(sc);
495fail2: usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS);
496fail1: uath_free_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT);
496fail1: uath_free_cmd_list(sc, sc->sc_cmd);
497fail:
498 return (error);
499}
500
501static int
502uath_detach(device_t dev)
503{
504 struct uath_softc *sc = device_get_softc(dev);

--- 14 unchanged lines hidden (view full) ---

519 callout_drain(&sc->watchdog_ch);
520
521 usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS);
522
523 /* free buffers */
524 UATH_LOCK(sc);
525 uath_free_rx_data_list(sc);
526 uath_free_tx_data_list(sc);
497fail:
498 return (error);
499}
500
501static int
502uath_detach(device_t dev)
503{
504 struct uath_softc *sc = device_get_softc(dev);

--- 14 unchanged lines hidden (view full) ---

519 callout_drain(&sc->watchdog_ch);
520
521 usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS);
522
523 /* free buffers */
524 UATH_LOCK(sc);
525 uath_free_rx_data_list(sc);
526 uath_free_tx_data_list(sc);
527 uath_free_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT);
527 uath_free_cmd_list(sc, sc->sc_cmd);
528 UATH_UNLOCK(sc);
529
530 if_free(ifp);
531 mtx_destroy(&sc->sc_mtx);
532 return (0);
533}
534
535static void
528 UATH_UNLOCK(sc);
529
530 if_free(ifp);
531 mtx_destroy(&sc->sc_mtx);
532 return (0);
533}
534
535static void
536uath_free_cmd_list(struct uath_softc *sc, struct uath_cmd cmds[], int ncmd)
536uath_free_cmd_list(struct uath_softc *sc, struct uath_cmd cmds[])
537{
538 int i;
539
537{
538 int i;
539
540 for (i = 0; i < ncmd; i++)
541 if (cmds[i].buf != NULL)
542 free(cmds[i].buf, M_USBDEV);
540 for (i = 0; i != UATH_CMD_LIST_COUNT; i++)
541 cmds[i].buf = NULL;
543}
544
545static int
542}
543
544static int
546uath_alloc_cmd_list(struct uath_softc *sc, struct uath_cmd cmds[],
547 int ncmd, int maxsz)
545uath_alloc_cmd_list(struct uath_softc *sc, struct uath_cmd cmds[])
548{
546{
549 int i, error;
547 int i;
550
551 STAILQ_INIT(&sc->sc_cmd_active);
552 STAILQ_INIT(&sc->sc_cmd_pending);
553 STAILQ_INIT(&sc->sc_cmd_waiting);
554 STAILQ_INIT(&sc->sc_cmd_inactive);
555
548
549 STAILQ_INIT(&sc->sc_cmd_active);
550 STAILQ_INIT(&sc->sc_cmd_pending);
551 STAILQ_INIT(&sc->sc_cmd_waiting);
552 STAILQ_INIT(&sc->sc_cmd_inactive);
553
556 for (i = 0; i < ncmd; i++) {
554 for (i = 0; i != UATH_CMD_LIST_COUNT; i++) {
557 struct uath_cmd *cmd = &cmds[i];
558
559 cmd->sc = sc; /* backpointer for callbacks */
560 cmd->msgid = i;
555 struct uath_cmd *cmd = &cmds[i];
556
557 cmd->sc = sc; /* backpointer for callbacks */
558 cmd->msgid = i;
561 cmd->buf = malloc(maxsz, M_USBDEV, M_NOWAIT);
562 if (cmd->buf == NULL) {
563 device_printf(sc->sc_dev,
564 "could not allocate xfer buffer\n");
565 error = ENOMEM;
566 goto fail;
567 }
559 cmd->buf = ((uint8_t *)sc->sc_cmd_dma_buf) +
560 (i * UATH_MAX_CMDSZ);
568 STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, cmd, next);
569 UATH_STAT_INC(sc, st_cmd_inactive);
570 }
571 return (0);
561 STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, cmd, next);
562 UATH_STAT_INC(sc, st_cmd_inactive);
563 }
564 return (0);
572
573fail: uath_free_cmd_list(sc, cmds, ncmd);
574 return (error);
575}
576
577static int
578uath_host_available(struct uath_softc *sc)
579{
580 struct uath_cmd_host_available setup;
581
582 UATH_ASSERT_LOCKED(sc);

--- 354 unchanged lines hidden (view full) ---

937
938 if (fillmbuf == 1) {
939 if (dp->m != NULL) {
940 m_freem(dp->m);
941 dp->m = NULL;
942 dp->buf = NULL;
943 }
944 } else {
565}
566
567static int
568uath_host_available(struct uath_softc *sc)
569{
570 struct uath_cmd_host_available setup;
571
572 UATH_ASSERT_LOCKED(sc);

--- 354 unchanged lines hidden (view full) ---

927
928 if (fillmbuf == 1) {
929 if (dp->m != NULL) {
930 m_freem(dp->m);
931 dp->m = NULL;
932 dp->buf = NULL;
933 }
934 } else {
945 if (dp->buf != NULL) {
946 free(dp->buf, M_USBDEV);
947 dp->buf = NULL;
948 }
935 dp->buf = NULL;
949 }
950#ifdef UATH_DEBUG
951 if (dp->ni != NULL)
952 device_printf(sc->sc_dev, "Node isn't NULL\n");
953#endif
954 }
955}
956
957static int
958uath_alloc_data_list(struct uath_softc *sc, struct uath_data data[],
936 }
937#ifdef UATH_DEBUG
938 if (dp->ni != NULL)
939 device_printf(sc->sc_dev, "Node isn't NULL\n");
940#endif
941 }
942}
943
944static int
945uath_alloc_data_list(struct uath_softc *sc, struct uath_data data[],
959 int ndata, int maxsz, int fillmbuf)
946 int ndata, int maxsz, void *dma_buf)
960{
961 int i, error;
962
963 for (i = 0; i < ndata; i++) {
964 struct uath_data *dp = &data[i];
965
966 dp->sc = sc;
947{
948 int i, error;
949
950 for (i = 0; i < ndata; i++) {
951 struct uath_data *dp = &data[i];
952
953 dp->sc = sc;
967 if (fillmbuf) {
954 if (dma_buf == NULL) {
968 /* XXX check maxsz */
969 dp->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
970 if (dp->m == NULL) {
971 device_printf(sc->sc_dev,
972 "could not allocate rx mbuf\n");
973 error = ENOMEM;
974 goto fail;
975 }
976 dp->buf = mtod(dp->m, uint8_t *);
977 } else {
978 dp->m = NULL;
955 /* XXX check maxsz */
956 dp->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
957 if (dp->m == NULL) {
958 device_printf(sc->sc_dev,
959 "could not allocate rx mbuf\n");
960 error = ENOMEM;
961 goto fail;
962 }
963 dp->buf = mtod(dp->m, uint8_t *);
964 } else {
965 dp->m = NULL;
979 dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT);
980 if (dp->buf == NULL) {
981 device_printf(sc->sc_dev,
982 "could not allocate buffer\n");
983 error = ENOMEM;
984 goto fail;
985 }
966 dp->buf = ((uint8_t *)dma_buf) + (i * maxsz);
986 }
987 dp->ni = NULL;
988 }
989
990 return (0);
991
967 }
968 dp->ni = NULL;
969 }
970
971 return (0);
972
992fail: uath_free_data_list(sc, data, ndata, fillmbuf);
973fail: uath_free_data_list(sc, data, ndata, 1 /* free mbufs */);
993 return (error);
994}
995
996static int
997uath_alloc_rx_data_list(struct uath_softc *sc)
998{
999 int error, i;
1000
1001 /* XXX is it enough to store the RX packet with MCLBYTES bytes? */
1002 error = uath_alloc_data_list(sc,
1003 sc->sc_rx, UATH_RX_DATA_LIST_COUNT, MCLBYTES,
974 return (error);
975}
976
977static int
978uath_alloc_rx_data_list(struct uath_softc *sc)
979{
980 int error, i;
981
982 /* XXX is it enough to store the RX packet with MCLBYTES bytes? */
983 error = uath_alloc_data_list(sc,
984 sc->sc_rx, UATH_RX_DATA_LIST_COUNT, MCLBYTES,
1004 1 /* setup mbufs */);
985 NULL /* setup mbufs */);
1005 if (error != 0)
1006 return (error);
1007
1008 STAILQ_INIT(&sc->sc_rx_active);
1009 STAILQ_INIT(&sc->sc_rx_inactive);
1010
1011 for (i = 0; i < UATH_RX_DATA_LIST_COUNT; i++) {
1012 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i],

--- 6 unchanged lines hidden (view full) ---

1019
1020static int
1021uath_alloc_tx_data_list(struct uath_softc *sc)
1022{
1023 int error, i;
1024
1025 error = uath_alloc_data_list(sc,
1026 sc->sc_tx, UATH_TX_DATA_LIST_COUNT, UATH_MAX_TXBUFSZ,
986 if (error != 0)
987 return (error);
988
989 STAILQ_INIT(&sc->sc_rx_active);
990 STAILQ_INIT(&sc->sc_rx_inactive);
991
992 for (i = 0; i < UATH_RX_DATA_LIST_COUNT; i++) {
993 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i],

--- 6 unchanged lines hidden (view full) ---

1000
1001static int
1002uath_alloc_tx_data_list(struct uath_softc *sc)
1003{
1004 int error, i;
1005
1006 error = uath_alloc_data_list(sc,
1007 sc->sc_tx, UATH_TX_DATA_LIST_COUNT, UATH_MAX_TXBUFSZ,
1027 0 /* no mbufs */);
1008 sc->sc_tx_dma_buf);
1028 if (error != 0)
1029 return (error);
1030
1031 STAILQ_INIT(&sc->sc_tx_active);
1032 STAILQ_INIT(&sc->sc_tx_inactive);
1033 STAILQ_INIT(&sc->sc_tx_pending);
1034
1035 for (i = 0; i < UATH_TX_DATA_LIST_COUNT; i++) {

--- 1700 unchanged lines hidden (view full) ---

2736setup:
2737 data = STAILQ_FIRST(&sc->sc_rx_inactive);
2738 if (data == NULL)
2739 return;
2740 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
2741 UATH_STAT_DEC(sc, st_rx_inactive);
2742 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
2743 UATH_STAT_INC(sc, st_rx_active);
1009 if (error != 0)
1010 return (error);
1011
1012 STAILQ_INIT(&sc->sc_tx_active);
1013 STAILQ_INIT(&sc->sc_tx_inactive);
1014 STAILQ_INIT(&sc->sc_tx_pending);
1015
1016 for (i = 0; i < UATH_TX_DATA_LIST_COUNT; i++) {

--- 1700 unchanged lines hidden (view full) ---

2717setup:
2718 data = STAILQ_FIRST(&sc->sc_rx_inactive);
2719 if (data == NULL)
2720 return;
2721 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
2722 UATH_STAT_DEC(sc, st_rx_inactive);
2723 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
2724 UATH_STAT_INC(sc, st_rx_active);
2744 usbd_xfer_set_frame_data(xfer, 0, data->buf,
2745 usbd_xfer_max_len(xfer));
2725 usbd_xfer_set_frame_data(xfer, 0, data->buf, MCLBYTES);
2746 usbd_transfer_submit(xfer);
2747
2748 /*
2749 * To avoid LOR we should unlock our private mutex here to call
2750 * ieee80211_input() because here is at the end of a USB
2751 * callback and safe to unlock.
2752 */
2753 if (sc->sc_flags & UATH_FLAG_INVALID) {

--- 131 unchanged lines hidden (view full) ---

2885 break;
2886 }
2887}
2888
2889static device_method_t uath_methods[] = {
2890 DEVMETHOD(device_probe, uath_match),
2891 DEVMETHOD(device_attach, uath_attach),
2892 DEVMETHOD(device_detach, uath_detach),
2726 usbd_transfer_submit(xfer);
2727
2728 /*
2729 * To avoid LOR we should unlock our private mutex here to call
2730 * ieee80211_input() because here is at the end of a USB
2731 * callback and safe to unlock.
2732 */
2733 if (sc->sc_flags & UATH_FLAG_INVALID) {

--- 131 unchanged lines hidden (view full) ---

2865 break;
2866 }
2867}
2868
2869static device_method_t uath_methods[] = {
2870 DEVMETHOD(device_probe, uath_match),
2871 DEVMETHOD(device_attach, uath_attach),
2872 DEVMETHOD(device_detach, uath_detach),
2893 { 0, 0 }
2873 DEVMETHOD_END
2894};
2895static driver_t uath_driver = {
2896 .name = "uath",
2897 .methods = uath_methods,
2898 .size = sizeof(struct uath_softc)
2899};
2900static devclass_t uath_devclass;
2901
2902DRIVER_MODULE(uath, uhub, uath_driver, uath_devclass, NULL, 0);
2903MODULE_DEPEND(uath, wlan, 1, 1, 1);
2904MODULE_DEPEND(uath, usb, 1, 1, 1);
2905MODULE_VERSION(uath, 1);
2874};
2875static driver_t uath_driver = {
2876 .name = "uath",
2877 .methods = uath_methods,
2878 .size = sizeof(struct uath_softc)
2879};
2880static devclass_t uath_devclass;
2881
2882DRIVER_MODULE(uath, uhub, uath_driver, uath_devclass, NULL, 0);
2883MODULE_DEPEND(uath, wlan, 1, 1, 1);
2884MODULE_DEPEND(uath, usb, 1, 1, 1);
2885MODULE_VERSION(uath, 1);