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); |