1 1.3 skrll /* $NetBSD: if_gscan.c,v 1.3 2025/04/26 07:09:13 skrll Exp $ */ 2 1.1 bouyer 3 1.1 bouyer /* 4 1.1 bouyer * Copyright (c) 2025 The NetBSD Foundation, Inc. 5 1.1 bouyer * All rights reserved. 6 1.1 bouyer * 7 1.1 bouyer * This code is derived from software contributed to The NetBSD Foundation 8 1.1 bouyer * by Manuel Bouyer. 9 1.1 bouyer * 10 1.1 bouyer * Redistribution and use in source and binary forms, with or without 11 1.1 bouyer * modification, are permitted provided that the following conditions 12 1.1 bouyer * are met: 13 1.1 bouyer * 1. Redistributions of source code must retain the above copyright 14 1.1 bouyer * notice, this list of conditions and the following disclaimer. 15 1.1 bouyer * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 bouyer * notice, this list of conditions and the following disclaimer in the 17 1.1 bouyer * documentation and/or other materials provided with the distribution. 18 1.1 bouyer * 19 1.1 bouyer * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 bouyer * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 bouyer * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 bouyer * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 bouyer * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 bouyer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 bouyer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 bouyer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 bouyer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 bouyer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 bouyer * POSSIBILITY OF SUCH DAMAGE. 30 1.1 bouyer */ 31 1.1 bouyer 32 1.1 bouyer 33 1.1 bouyer #include <sys/cdefs.h> 34 1.3 skrll __KERNEL_RCSID(0, "$NetBSD: if_gscan.c,v 1.3 2025/04/26 07:09:13 skrll Exp $"); 35 1.1 bouyer 36 1.1 bouyer #ifdef _KERNEL_OPT 37 1.1 bouyer #include "opt_usb.h" 38 1.1 bouyer #include "opt_net_mpsafe.h" 39 1.1 bouyer #include "opt_can.h" 40 1.1 bouyer #endif 41 1.1 bouyer 42 1.1 bouyer #include <sys/param.h> 43 1.1 bouyer 44 1.1 bouyer #include <sys/device.h> 45 1.1 bouyer #include <sys/mbuf.h> 46 1.1 bouyer #include <sys/rndsource.h> 47 1.1 bouyer #include <sys/mutex.h> 48 1.1 bouyer #include <sys/module.h> 49 1.1 bouyer #include <sys/syslog.h> 50 1.1 bouyer 51 1.1 bouyer #include <net/bpf.h> 52 1.1 bouyer #include <net/if.h> 53 1.1 bouyer #include <net/if_types.h> 54 1.1 bouyer 55 1.1 bouyer #include <netcan/can.h> 56 1.1 bouyer #include <netcan/can_var.h> 57 1.1 bouyer 58 1.1 bouyer #include <dev/usb/usb.h> 59 1.1 bouyer #include <dev/usb/usbdi.h> 60 1.1 bouyer #include <dev/usb/usbdivar.h> 61 1.1 bouyer #include <dev/usb/usbdi_util.h> 62 1.1 bouyer #include <dev/usb/usbdevs.h> 63 1.1 bouyer 64 1.1 bouyer #include <dev/usb/usbhist.h> 65 1.1 bouyer #include <dev/usb/if_gscanreg.h> 66 1.1 bouyer 67 1.1 bouyer #ifdef USB_DEBUG 68 1.1 bouyer #ifndef GSCAN_DEBUG 69 1.1 bouyer #define gscandebug 0 70 1.1 bouyer #else 71 1.1 bouyer static int gscandebug = 0; 72 1.1 bouyer SYSCTL_SETUP(sysctl_hw_gscan_setup, "sysctl hw.gscan setup") 73 1.1 bouyer { 74 1.1 bouyer int err; 75 1.1 bouyer const struct sysctlnode *rnode; 76 1.1 bouyer const struct sysctlnode *cnode; 77 1.1 bouyer 78 1.1 bouyer err = sysctl_createv(clog, 0, NULL, &rnode, 79 1.1 bouyer CTLFLAG_PERMANENT, CTLTYPE_NODE, "gscan", 80 1.1 bouyer SYSCTL_DESCR("gscan global controls"), 81 1.1 bouyer NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 82 1.1 bouyer 83 1.1 bouyer if (err) 84 1.1 bouyer goto fail; 85 1.1 bouyer /* control debugging printfs */ 86 1.1 bouyer err = sysctl_createv(clog, 0, &rnode, &cnode, 87 1.1 bouyer CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 88 1.1 bouyer "debug", SYSCTL_DESCR("Enable debugging output"), 89 1.1 bouyer NULL, 0, &gscandebug, sizeof(gscandebug), CTL_CREATE, CTL_EOL); 90 1.1 bouyer if (err) 91 1.1 bouyer goto fail; 92 1.1 bouyer 93 1.1 bouyer return; 94 1.1 bouyer fail: 95 1.1 bouyer aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 96 1.1 bouyer } 97 1.1 bouyer 98 1.1 bouyer #endif /* GSCAN_DEBUG */ 99 1.1 bouyer #endif /* USB_DEBUG */ 100 1.1 bouyer 101 1.1 bouyer #define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(gscandebug,1,FMT,A,B,C,D) 102 1.1 bouyer #define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(gscandebug,N,FMT,A,B,C,D) 103 1.1 bouyer #define GSCANHIST_FUNC() USBHIST_FUNC() 104 1.1 bouyer #define GSCANHIST_CALLED(name) USBHIST_CALLED(gscandebug) 105 1.1 bouyer #define GSCANHIST_CALLARGS(FMT,A,B,C,D) \ 106 1.1 bouyer USBHIST_CALLARGS(gscandebug,FMT,A,B,C,D) 107 1.1 bouyer 108 1.1 bouyer struct gscan_softc { 109 1.1 bouyer struct canif_softc sc_cansc; 110 1.1 bouyer struct usbd_interface *sc_iface; 111 1.1 bouyer struct usbd_device *sc_udev; 112 1.1 bouyer uByte sc_ed_tx; 113 1.1 bouyer uByte sc_ed_rx; 114 1.1 bouyer struct usbd_pipe *sc_tx_pipe; 115 1.1 bouyer struct usbd_pipe *sc_rx_pipe; 116 1.1 bouyer struct usbd_xfer *sc_tx_xfer; 117 1.1 bouyer struct usbd_xfer *sc_rx_xfer; 118 1.1 bouyer struct gscan_frame *sc_tx_frame; 119 1.1 bouyer struct gscan_frame *sc_rx_frame; 120 1.1 bouyer kmutex_t sc_txlock; 121 1.1 bouyer kmutex_t sc_rxlock; 122 1.1 bouyer bool sc_txstopped; 123 1.1 bouyer bool sc_rxstopped; 124 1.1 bouyer int sc_rx_nerr; 125 1.1 bouyer struct ifnet *sc_ifp; 126 1.1 bouyer struct if_percpuq *sc_ipq; 127 1.1 bouyer volatile bool sc_dying; 128 1.1 bouyer krndsource_t sc_rnd_source; 129 1.1 bouyer struct mbuf *sc_m_transmit; /* mbuf being transmitted */ 130 1.1 bouyer }; 131 1.1 bouyer 132 1.1 bouyer #define sc_dev sc_cansc.csc_dev 133 1.1 bouyer #define sc_timecaps sc_cansc.csc_timecaps 134 1.1 bouyer #define sc_timings sc_cansc.csc_timings 135 1.1 bouyer #define sc_linkmodes sc_cansc.csc_linkmodes 136 1.1 bouyer 137 1.1 bouyer static bool 138 1.1 bouyer gscan_isdying(struct gscan_softc *sc) 139 1.1 bouyer { 140 1.1 bouyer return atomic_load_relaxed(&sc->sc_dying); 141 1.1 bouyer } 142 1.1 bouyer 143 1.1 bouyer static int 144 1.1 bouyer gscan_write_device(struct gscan_softc *sc, int breq, void *v, int len) 145 1.1 bouyer { 146 1.1 bouyer usb_device_request_t req; 147 1.1 bouyer req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 148 1.1 bouyer req.bRequest = breq; 149 1.1 bouyer USETW(req.wValue, 0); 150 1.1 bouyer USETW(req.wIndex, 0); 151 1.1 bouyer USETW(req.wLength, len); 152 1.1 bouyer return usbd_do_request(sc->sc_udev, &req, v); 153 1.1 bouyer } 154 1.1 bouyer 155 1.1 bouyer static int 156 1.1 bouyer gscan_read_device(struct gscan_softc *sc, int breq, void *v, int len) 157 1.1 bouyer { 158 1.1 bouyer usb_device_request_t req; 159 1.1 bouyer req.bmRequestType = UT_READ_VENDOR_DEVICE; 160 1.1 bouyer req.bRequest = breq; 161 1.1 bouyer USETW(req.wValue, 0); 162 1.1 bouyer USETW(req.wIndex, 0); 163 1.1 bouyer USETW(req.wLength, len); 164 1.1 bouyer return usbd_do_request(sc->sc_udev, &req, v); 165 1.1 bouyer } 166 1.1 bouyer 167 1.1 bouyer static int gscan_match(device_t, cfdata_t, void *); 168 1.1 bouyer static void gscan_attach(device_t, device_t, void *); 169 1.1 bouyer static int gscan_detach(device_t, int); 170 1.1 bouyer static int gscan_activate(device_t, devact_t); 171 1.1 bouyer 172 1.1 bouyer static void gscan_ifstart(struct ifnet *); 173 1.1 bouyer static int gscan_ifioctl(struct ifnet *, u_long, void *); 174 1.1 bouyer static void gscan_ifwatchdog(struct ifnet *); 175 1.1 bouyer 176 1.1 bouyer static int gscan_ifup(struct gscan_softc * const); 177 1.1 bouyer static void gscan_stop(struct gscan_softc * const, struct ifnet *, int); 178 1.1 bouyer static void gscan_startrx(struct gscan_softc * const); 179 1.1 bouyer 180 1.1 bouyer CFATTACH_DECL_NEW(gscan, sizeof(struct gscan_softc), 181 1.1 bouyer gscan_match, gscan_attach, gscan_detach, gscan_activate); 182 1.1 bouyer 183 1.1 bouyer static void 184 1.1 bouyer gscan_rx(struct usbd_xfer *xfer, void *priv, usbd_status status) 185 1.1 bouyer { 186 1.1 bouyer GSCANHIST_FUNC(); 187 1.1 bouyer struct gscan_softc *sc = priv; 188 1.1 bouyer struct gscan_frame *gsframe; 189 1.1 bouyer struct can_frame *cf; 190 1.1 bouyer uint32_t len, dlc, can_id; 191 1.1 bouyer int32_t echo_id; 192 1.1 bouyer struct ifnet *ifp = sc->sc_ifp; 193 1.1 bouyer struct mbuf *m; 194 1.1 bouyer 195 1.1 bouyer GSCANHIST_CALLARGS("status: %d", status, 0, 0, 0); 196 1.1 bouyer 197 1.1 bouyer mutex_enter(&sc->sc_rxlock); 198 1.1 bouyer if (sc->sc_rxstopped || gscan_isdying(sc) || 199 1.1 bouyer status == USBD_NOT_STARTED || status == USBD_CANCELLED || 200 1.1 bouyer status == USBD_INVAL) { 201 1.1 bouyer mutex_exit(&sc->sc_rxlock); 202 1.1 bouyer return; 203 1.1 bouyer } 204 1.1 bouyer if (status != USBD_NORMAL_COMPLETION) { 205 1.3 skrll DPRINTF("rx error: %jd", status, 0, 0, 0); 206 1.1 bouyer if (status == USBD_STALLED) 207 1.1 bouyer usbd_clear_endpoint_stall_async(sc->sc_rx_pipe); 208 1.1 bouyer if (++sc->sc_rx_nerr > 100) { 209 1.1 bouyer log(LOG_ERR, "%s: too many rx errors, disabling\n", 210 1.1 bouyer device_xname(sc->sc_dev)); 211 1.2 riastrad gscan_activate(sc->sc_dev, DVACT_DEACTIVATE); 212 1.1 bouyer } 213 1.1 bouyer goto out; 214 1.1 bouyer } 215 1.1 bouyer sc->sc_rx_nerr = 0; 216 1.1 bouyer usbd_get_xfer_status(xfer, NULL, (void **)&gsframe, &len, NULL); 217 1.1 bouyer if (len < sizeof(struct gscan_frame) - 8) { 218 1.1 bouyer if_statinc(ifp, if_ierrors); 219 1.1 bouyer goto out; 220 1.1 bouyer } 221 1.1 bouyer if (gsframe->gsframe_flags & GSFRAME_FLAG_OVER) { 222 1.1 bouyer if_statinc(ifp, if_ierrors); 223 1.1 bouyer goto out; 224 1.1 bouyer } 225 1.1 bouyer dlc = le32toh(gsframe->gsframe_can_dlc); 226 1.1 bouyer if (dlc > CAN_MAX_DLC) { 227 1.1 bouyer if_statinc(ifp, if_ierrors); 228 1.1 bouyer goto out; 229 1.1 bouyer } 230 1.1 bouyer echo_id = le32toh(gsframe->gsframe_echo_id); 231 1.1 bouyer if (echo_id != -1) { 232 1.1 bouyer /* echo of a frame we sent */ 233 1.1 bouyer goto out; 234 1.1 bouyer } 235 1.1 bouyer can_id = le32toh(gsframe->gsframe_can_id); 236 1.1 bouyer /* for now ignore error frames */ 237 1.1 bouyer if (can_id & CAN_ERR_FLAG) { 238 1.1 bouyer goto out; 239 1.1 bouyer } 240 1.1 bouyer m = m_gethdr(M_NOWAIT, MT_HEADER); 241 1.1 bouyer if (m == NULL) { 242 1.1 bouyer if_statinc(ifp, if_ierrors); 243 1.1 bouyer goto out; 244 1.1 bouyer } 245 1.1 bouyer cf = mtod(m, struct can_frame *); 246 1.1 bouyer memset(cf, 0, sizeof(struct can_frame)); 247 1.1 bouyer cf->can_id = can_id; 248 1.1 bouyer cf->can_dlc = dlc; 249 1.1 bouyer memcpy(&cf->data[0], &gsframe->gsframe_can_data[0], 8); 250 1.1 bouyer /* done with the buffer, get next frame */ 251 1.1 bouyer mutex_exit(&sc->sc_rxlock); 252 1.1 bouyer gscan_startrx(sc); 253 1.1 bouyer 254 1.1 bouyer m->m_len = m->m_pkthdr.len = CAN_MTU; 255 1.1 bouyer m_set_rcvif(m, ifp); 256 1.1 bouyer if_statadd(ifp, if_ibytes, m->m_len); 257 1.2 riastrad can_bpf_mtap(ifp, m, 1); 258 1.1 bouyer can_input(ifp, m); 259 1.1 bouyer return; 260 1.1 bouyer 261 1.1 bouyer out: 262 1.1 bouyer mutex_exit(&sc->sc_rxlock); 263 1.1 bouyer gscan_startrx(sc); 264 1.1 bouyer } 265 1.1 bouyer 266 1.1 bouyer static void 267 1.1 bouyer gscan_startrx(struct gscan_softc * const sc) 268 1.1 bouyer { 269 1.1 bouyer usbd_setup_xfer(sc->sc_rx_xfer, sc, sc->sc_rx_frame, 270 1.1 bouyer sizeof(struct gscan_frame), USBD_SHORT_XFER_OK, 271 1.1 bouyer USBD_NO_TIMEOUT, gscan_rx); 272 1.1 bouyer usbd_transfer(sc->sc_rx_xfer); 273 1.1 bouyer } 274 1.1 bouyer 275 1.1 bouyer static void 276 1.1 bouyer gscan_tx(struct usbd_xfer *xfer, void *priv, usbd_status status) 277 1.1 bouyer { 278 1.1 bouyer GSCANHIST_FUNC(); 279 1.1 bouyer struct gscan_softc *sc = priv; 280 1.1 bouyer struct ifnet *ifp = sc->sc_ifp; 281 1.1 bouyer struct mbuf *m; 282 1.1 bouyer 283 1.1 bouyer GSCANHIST_CALLARGS("status: %d", status, 0, 0, 0); 284 1.1 bouyer mutex_enter(&sc->sc_txlock); 285 1.1 bouyer if (sc->sc_txstopped || gscan_isdying(sc)) { 286 1.1 bouyer mutex_exit(&sc->sc_txlock); 287 1.1 bouyer return; 288 1.1 bouyer } 289 1.1 bouyer ifp->if_timer = 0; 290 1.1 bouyer m = sc->sc_m_transmit; 291 1.1 bouyer sc->sc_m_transmit = NULL; 292 1.1 bouyer if (m != NULL) { 293 1.1 bouyer if (status == USBD_NORMAL_COMPLETION) 294 1.1 bouyer if_statadd2(ifp, if_obytes, m->m_len, if_opackets, 1); 295 1.1 bouyer can_mbuf_tag_clean(m); 296 1.1 bouyer m_set_rcvif(m, ifp); 297 1.1 bouyer can_input(ifp, m); /* loopback */ 298 1.1 bouyer } 299 1.1 bouyer if (status != USBD_NORMAL_COMPLETION) { 300 1.1 bouyer if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 301 1.1 bouyer mutex_exit(&sc->sc_txlock); 302 1.2 riastrad return; 303 1.1 bouyer } 304 1.3 skrll DPRINTF("rx error: %jd", status, 0, 0, 0); 305 1.1 bouyer if (status == USBD_STALLED) 306 1.1 bouyer usbd_clear_endpoint_stall_async(sc->sc_rx_pipe); 307 1.1 bouyer } 308 1.1 bouyer if_schedule_deferred_start(ifp); 309 1.1 bouyer mutex_exit(&sc->sc_txlock); 310 1.1 bouyer } 311 1.1 bouyer 312 1.1 bouyer static void 313 1.1 bouyer gscan_ifstart(struct ifnet *ifp) 314 1.1 bouyer { 315 1.1 bouyer GSCANHIST_FUNC(); 316 1.1 bouyer struct gscan_softc * const sc = ifp->if_softc; 317 1.1 bouyer struct mbuf *m; 318 1.1 bouyer struct can_frame *cf; 319 1.1 bouyer int err; 320 1.1 bouyer GSCANHIST_CALLED(); 321 1.1 bouyer 322 1.1 bouyer mutex_enter(&sc->sc_txlock); 323 1.1 bouyer if (sc->sc_txstopped || gscan_isdying(sc)) 324 1.1 bouyer goto out; 325 1.1 bouyer 326 1.1 bouyer if (sc->sc_m_transmit != NULL) 327 1.1 bouyer goto out; 328 1.1 bouyer IF_DEQUEUE(&ifp->if_snd, m); 329 1.1 bouyer if (m == NULL) 330 1.1 bouyer goto out; 331 1.1 bouyer 332 1.1 bouyer MCLAIM(m, ifp->if_mowner); 333 1.1 bouyer 334 1.1 bouyer KASSERT((m->m_flags & M_PKTHDR) != 0); 335 1.1 bouyer KASSERT(m->m_len == m->m_pkthdr.len); 336 1.1 bouyer 337 1.1 bouyer cf = mtod(m, struct can_frame *); 338 1.1 bouyer memset(sc->sc_tx_frame, 0, sizeof(struct gscan_frame)); 339 1.1 bouyer sc->sc_tx_frame->gsframe_echo_id = 0; 340 1.1 bouyer sc->sc_tx_frame->gsframe_can_id = htole32(cf->can_id); 341 1.1 bouyer sc->sc_tx_frame->gsframe_can_dlc = htole32(cf->can_dlc); 342 1.1 bouyer memcpy(&sc->sc_tx_frame->gsframe_can_data[0], &cf->data[0], 8); 343 1.1 bouyer 344 1.1 bouyer usbd_setup_xfer(sc->sc_tx_xfer, sc, sc->sc_tx_frame, 345 1.1 bouyer sizeof(struct gscan_frame), 0, 10000, gscan_tx); 346 1.1 bouyer err = usbd_transfer(sc->sc_tx_xfer); 347 1.1 bouyer if (err != USBD_IN_PROGRESS) { 348 1.3 skrll DPRINTF("start tx error: %jd", err, 0, 0, 0); 349 1.1 bouyer if_statadd(ifp, if_oerrors, 1); 350 1.1 bouyer } else { 351 1.1 bouyer sc->sc_m_transmit = m; 352 1.1 bouyer ifp->if_timer = 5; 353 1.1 bouyer } 354 1.1 bouyer can_bpf_mtap(ifp, m, 0); 355 1.1 bouyer out: 356 1.1 bouyer mutex_exit(&sc->sc_txlock); 357 1.1 bouyer } 358 1.1 bouyer 359 1.1 bouyer static int 360 1.1 bouyer gscan_ifup(struct gscan_softc * const sc) 361 1.1 bouyer { 362 1.1 bouyer struct gscan_bt gscan_bt; 363 1.1 bouyer struct gscan_set_mode gscan_set_mode; 364 1.1 bouyer int err; 365 1.1 bouyer struct ifnet * const ifp = sc->sc_ifp; 366 1.1 bouyer 367 1.1 bouyer KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname); 368 1.1 bouyer 369 1.1 bouyer gscan_set_mode.mode_mode = MODE_START; 370 1.1 bouyer gscan_set_mode.mode_flags = 0; 371 1.1 bouyer 372 1.1 bouyer if (sc->sc_linkmodes & CAN_LINKMODE_LISTENONLY) { 373 1.1 bouyer if ((sc->sc_timecaps.cltc_linkmode_caps & CAN_LINKMODE_LISTENONLY) == 0) 374 1.1 bouyer return EINVAL; 375 1.1 bouyer gscan_set_mode.mode_flags |= FLAGS_LISTEN_ONLY; 376 1.1 bouyer } 377 1.1 bouyer if (sc->sc_linkmodes & CAN_LINKMODE_LOOPBACK) { 378 1.1 bouyer if ((sc->sc_timecaps.cltc_linkmode_caps & CAN_LINKMODE_LOOPBACK) == 0) 379 1.1 bouyer return EINVAL; 380 1.1 bouyer gscan_set_mode.mode_flags |= FLAGS_LOOPBACK; 381 1.1 bouyer } 382 1.1 bouyer if (sc->sc_linkmodes & CAN_LINKMODE_3SAMPLES) { 383 1.1 bouyer if ((sc->sc_timecaps.cltc_linkmode_caps & CAN_LINKMODE_3SAMPLES) == 0) 384 1.1 bouyer return EINVAL; 385 1.1 bouyer gscan_set_mode.mode_flags |= FLAGS_TRIPLE_SAMPLE; 386 1.1 bouyer } 387 1.1 bouyer if (sc->sc_timings.clt_prop != 0) 388 1.1 bouyer return EINVAL; 389 1.1 bouyer gscan_bt.bt_prop_seg = 0; 390 1.1 bouyer 391 1.1 bouyer if (sc->sc_timings.clt_brp > sc->sc_timecaps.cltc_brp_max || 392 1.1 bouyer sc->sc_timings.clt_brp < sc->sc_timecaps.cltc_brp_min) 393 1.1 bouyer return EINVAL; 394 1.1 bouyer gscan_bt.bt_brp = sc->sc_timings.clt_brp; 395 1.1 bouyer 396 1.1 bouyer if (sc->sc_timings.clt_ps1 > sc->sc_timecaps.cltc_ps1_max || 397 1.2 riastrad sc->sc_timings.clt_ps1 < sc->sc_timecaps.cltc_ps1_min) 398 1.1 bouyer return EINVAL; 399 1.1 bouyer gscan_bt.bt_phase_seg1 = sc->sc_timings.clt_ps1; 400 1.1 bouyer if (sc->sc_timings.clt_ps2 > sc->sc_timecaps.cltc_ps2_max || 401 1.2 riastrad sc->sc_timings.clt_ps2 < sc->sc_timecaps.cltc_ps2_min) 402 1.1 bouyer return EINVAL; 403 1.1 bouyer gscan_bt.bt_phase_seg2 = sc->sc_timings.clt_ps2; 404 1.2 riastrad if (sc->sc_timings.clt_sjw > sc->sc_timecaps.cltc_sjw_max || 405 1.1 bouyer sc->sc_timings.clt_sjw < 1) 406 1.1 bouyer return EINVAL; 407 1.1 bouyer gscan_bt.bt_swj = sc->sc_timings.clt_sjw; 408 1.1 bouyer 409 1.1 bouyer err = gscan_write_device(sc, GSCAN_SET_BITTIMING, 410 1.1 bouyer &gscan_bt, sizeof(gscan_bt)); 411 1.1 bouyer if (err) { 412 1.1 bouyer aprint_error_dev(sc->sc_dev, "SET_BITTIMING: %s\n", 413 1.1 bouyer usbd_errstr(err)); 414 1.1 bouyer return EIO; 415 1.1 bouyer } 416 1.1 bouyer err = gscan_write_device(sc, GSCAN_SET_MODE, 417 1.1 bouyer &gscan_set_mode, sizeof(gscan_set_mode)); 418 1.1 bouyer if (err) { 419 1.1 bouyer aprint_error_dev(sc->sc_dev, "SET_MODE start: %s\n", 420 1.1 bouyer usbd_errstr(err)); 421 1.1 bouyer return EIO; 422 1.1 bouyer } 423 1.1 bouyer 424 1.1 bouyer if ((err = usbd_open_pipe(sc->sc_iface, sc->sc_ed_rx, 425 1.1 bouyer USBD_EXCLUSIVE_USE | USBD_MPSAFE, &sc->sc_rx_pipe)) != 0) { 426 1.1 bouyer aprint_error_dev(sc->sc_dev, "open rx pipe: %s\n", 427 1.1 bouyer usbd_errstr(err)); 428 1.1 bouyer goto fail; 429 1.1 bouyer } 430 1.1 bouyer if ((err = usbd_open_pipe(sc->sc_iface, sc->sc_ed_tx, 431 1.1 bouyer USBD_EXCLUSIVE_USE | USBD_MPSAFE, &sc->sc_tx_pipe)) != 0) { 432 1.1 bouyer aprint_error_dev(sc->sc_dev, "open tx pipe: %s\n", 433 1.1 bouyer usbd_errstr(err)); 434 1.1 bouyer goto fail; 435 1.1 bouyer } 436 1.1 bouyer 437 1.1 bouyer if ((err = usbd_create_xfer(sc->sc_rx_pipe, sizeof(struct gscan_frame), 438 1.1 bouyer 0, 0, &sc->sc_rx_xfer)) != 0) { 439 1.1 bouyer aprint_error_dev(sc->sc_dev, "create rx xfer: %s\n", 440 1.1 bouyer usbd_errstr(err)); 441 1.1 bouyer goto fail; 442 1.1 bouyer } 443 1.1 bouyer if ((err = usbd_create_xfer(sc->sc_tx_pipe, sizeof(struct gscan_frame), 444 1.1 bouyer 0, 0, &sc->sc_tx_xfer)) != 0) { 445 1.1 bouyer aprint_error_dev(sc->sc_dev, "create tx xfer: %s\n", 446 1.1 bouyer usbd_errstr(err)); 447 1.1 bouyer goto fail; 448 1.1 bouyer } 449 1.1 bouyer 450 1.1 bouyer sc->sc_rx_frame = usbd_get_buffer(sc->sc_rx_xfer); 451 1.1 bouyer sc->sc_tx_frame = usbd_get_buffer(sc->sc_tx_xfer); 452 1.1 bouyer sc->sc_ifp->if_flags |= IFF_RUNNING; 453 1.1 bouyer 454 1.1 bouyer mutex_enter(&sc->sc_rxlock); 455 1.1 bouyer sc->sc_rxstopped = false; 456 1.1 bouyer sc->sc_rx_nerr = 0; 457 1.1 bouyer mutex_exit(&sc->sc_rxlock); 458 1.1 bouyer gscan_startrx(sc); 459 1.1 bouyer mutex_enter(&sc->sc_txlock); 460 1.1 bouyer sc->sc_txstopped = false; 461 1.1 bouyer mutex_exit(&sc->sc_txlock); 462 1.1 bouyer return 0; 463 1.1 bouyer 464 1.1 bouyer fail: 465 1.1 bouyer gscan_stop(sc, ifp, 1); 466 1.1 bouyer return EIO; 467 1.1 bouyer } 468 1.1 bouyer 469 1.1 bouyer static void 470 1.1 bouyer gscan_stop(struct gscan_softc * const sc, struct ifnet *ifp, int disable) 471 1.1 bouyer { 472 1.1 bouyer struct gscan_set_mode gscan_set_mode; 473 1.1 bouyer int err; 474 1.1 bouyer 475 1.1 bouyer KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname); 476 1.1 bouyer mutex_enter(&sc->sc_txlock); 477 1.1 bouyer sc->sc_txstopped = true; 478 1.1 bouyer ifp->if_timer = 0; 479 1.1 bouyer if (sc->sc_m_transmit != NULL) { 480 1.1 bouyer m_freem(sc->sc_m_transmit); 481 1.1 bouyer sc->sc_m_transmit = NULL; 482 1.1 bouyer } 483 1.1 bouyer mutex_exit(&sc->sc_txlock); 484 1.1 bouyer mutex_enter(&sc->sc_rxlock); 485 1.1 bouyer sc->sc_rxstopped = true; 486 1.1 bouyer mutex_exit(&sc->sc_rxlock); 487 1.1 bouyer if (ifp->if_flags & IFF_RUNNING) { 488 1.1 bouyer if (sc->sc_tx_pipe) 489 1.1 bouyer usbd_abort_pipe(sc->sc_tx_pipe); 490 1.1 bouyer if (sc->sc_rx_pipe) 491 1.1 bouyer usbd_abort_pipe(sc->sc_rx_pipe); 492 1.1 bouyer } 493 1.1 bouyer if (sc->sc_rx_pipe) { 494 1.1 bouyer usbd_close_pipe(sc->sc_rx_pipe); 495 1.1 bouyer sc->sc_rx_pipe = NULL; 496 1.1 bouyer } 497 1.1 bouyer if (sc->sc_tx_pipe) { 498 1.1 bouyer usbd_close_pipe(sc->sc_tx_pipe); 499 1.1 bouyer sc->sc_tx_pipe = NULL; 500 1.1 bouyer } 501 1.1 bouyer if (sc->sc_rx_xfer != NULL) { 502 1.1 bouyer usbd_destroy_xfer(sc->sc_rx_xfer); 503 1.1 bouyer sc->sc_rx_xfer = NULL; 504 1.1 bouyer sc->sc_rx_pipe = NULL; 505 1.1 bouyer } 506 1.1 bouyer if (sc->sc_tx_xfer != NULL) { 507 1.1 bouyer usbd_destroy_xfer(sc->sc_tx_xfer); 508 1.1 bouyer sc->sc_tx_xfer = NULL; 509 1.1 bouyer sc->sc_tx_pipe = NULL; 510 1.1 bouyer } 511 1.2 riastrad 512 1.1 bouyer gscan_set_mode.mode_mode = MODE_RESET; 513 1.1 bouyer gscan_set_mode.mode_flags = 0; 514 1.1 bouyer err = gscan_write_device(sc, GSCAN_SET_MODE, 515 1.1 bouyer &gscan_set_mode, sizeof(gscan_set_mode)); 516 1.1 bouyer if (err != 0 && err != USBD_CANCELLED) { 517 1.1 bouyer aprint_error_dev(sc->sc_dev, "SET_MODE stop: %s\n", 518 1.1 bouyer usbd_errstr(err)); 519 1.1 bouyer } 520 1.1 bouyer KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname); 521 1.1 bouyer ifp->if_flags &= ~IFF_RUNNING; 522 1.1 bouyer } 523 1.1 bouyer 524 1.2 riastrad static void 525 1.1 bouyer gscan_ifstop(struct ifnet *ifp, int disable) 526 1.1 bouyer { 527 1.1 bouyer struct gscan_softc * const sc = ifp->if_softc; 528 1.1 bouyer KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname); 529 1.1 bouyer gscan_stop(sc, ifp, disable); 530 1.1 bouyer } 531 1.1 bouyer 532 1.1 bouyer 533 1.1 bouyer static int 534 1.1 bouyer gscan_ifioctl(struct ifnet *ifp, u_long cmd, void *data) 535 1.2 riastrad { 536 1.1 bouyer struct gscan_softc * const sc = ifp->if_softc; 537 1.1 bouyer struct ifreq *ifr = (struct ifreq *)data; 538 1.1 bouyer int error = 0; 539 1.1 bouyer 540 1.1 bouyer KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname); 541 1.1 bouyer if (gscan_isdying(sc)) 542 1.1 bouyer return EIO; 543 1.1 bouyer 544 1.1 bouyer switch (cmd) { 545 1.1 bouyer case SIOCINITIFADDR: 546 1.1 bouyer error = EAFNOSUPPORT; 547 1.1 bouyer break; 548 1.1 bouyer case SIOCSIFMTU: 549 1.1 bouyer if ((unsigned)ifr->ifr_mtu != sizeof(struct can_frame)) 550 1.1 bouyer error = EINVAL; 551 1.1 bouyer break; 552 1.1 bouyer case SIOCADDMULTI: 553 1.1 bouyer case SIOCDELMULTI: 554 1.1 bouyer error = EAFNOSUPPORT; 555 1.1 bouyer break; 556 1.1 bouyer default: 557 1.1 bouyer error = ifioctl_common(ifp, cmd, data); 558 1.1 bouyer if (error == 0) { 559 1.1 bouyer if ((ifp->if_flags & IFF_UP) != 0 && 560 1.1 bouyer (ifp->if_flags & IFF_RUNNING) == 0) { 561 1.1 bouyer error = gscan_ifup(sc); 562 1.1 bouyer if (error) { 563 1.1 bouyer ifp->if_flags &= ~IFF_UP; 564 1.1 bouyer } 565 1.1 bouyer } else if ((ifp->if_flags & IFF_UP) == 0 && 566 1.1 bouyer (ifp->if_flags & IFF_RUNNING) != 0) { 567 1.1 bouyer gscan_stop(sc, sc->sc_ifp, 1); 568 1.1 bouyer } 569 1.1 bouyer } 570 1.1 bouyer break; 571 1.1 bouyer } 572 1.1 bouyer return error; 573 1.1 bouyer } 574 1.1 bouyer 575 1.1 bouyer static void 576 1.1 bouyer gscan_ifwatchdog(struct ifnet *ifp) 577 1.1 bouyer { 578 1.1 bouyer struct gscan_softc * const sc = ifp->if_softc; 579 1.1 bouyer printf("%s: watchdog timeout\n", device_xname(sc->sc_dev)); 580 1.1 bouyer #if 0 581 1.1 bouyer /* if there is a transmit in progress abort */ 582 1.1 bouyer if (gscan_tx_abort(sc)) { 583 1.1 bouyer if_statinc(ifp, if_oerrors); 584 1.1 bouyer } 585 1.1 bouyer #endif 586 1.1 bouyer } 587 1.1 bouyer 588 1.1 bouyer static const struct usb_devno gscan_devs[] = { 589 1.1 bouyer {USB_VENDOR_FUTUREBITS, USB_PRODUCT_FUTUREBITS_CDL_CAN}, 590 1.1 bouyer {USB_VENDOR_INTERBIO, USB_PRODUCT_INTERBIO_CDL_CAN}, 591 1.1 bouyer }; 592 1.1 bouyer 593 1.1 bouyer static int 594 1.1 bouyer gscan_match(device_t parent, cfdata_t match, void *aux) 595 1.1 bouyer { 596 1.1 bouyer struct usb_attach_arg *uaa = aux; 597 1.1 bouyer 598 1.1 bouyer return 599 1.1 bouyer (usb_lookup(gscan_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ? 600 1.1 bouyer UMATCH_VENDOR_PRODUCT : UMATCH_NONE); 601 1.1 bouyer } 602 1.1 bouyer 603 1.1 bouyer static void 604 1.1 bouyer gscan_attach(device_t parent, device_t self, void *aux) 605 1.1 bouyer { 606 1.1 bouyer GSCANHIST_FUNC(); GSCANHIST_CALLED(); 607 1.1 bouyer struct gscan_softc *sc = device_private(self); 608 1.1 bouyer struct usb_attach_arg *uaa = aux; 609 1.1 bouyer struct usbd_device *dev = uaa->uaa_device; 610 1.1 bouyer usbd_status err; 611 1.1 bouyer usb_interface_descriptor_t *id; 612 1.1 bouyer usb_endpoint_descriptor_t *ed; 613 1.1 bouyer char *devinfop; 614 1.1 bouyer uint32_t val32; 615 1.1 bouyer struct gscan_config gscan_config; 616 1.1 bouyer struct gscan_bt_const gscan_bt_const; 617 1.1 bouyer struct ifnet *ifp; 618 1.1 bouyer 619 1.1 bouyer aprint_naive("\n"); 620 1.1 bouyer aprint_normal("\n"); 621 1.1 bouyer devinfop = usbd_devinfo_alloc(dev, 0); 622 1.1 bouyer aprint_normal_dev(self, "%s\n", devinfop); 623 1.1 bouyer usbd_devinfo_free(devinfop); 624 1.1 bouyer 625 1.1 bouyer sc->sc_dev = self; 626 1.1 bouyer sc->sc_udev = dev; 627 1.1 bouyer 628 1.1 bouyer err = usbd_set_config_no(dev, 1, 0); 629 1.1 bouyer if (err) { 630 1.1 bouyer aprint_error_dev(self, "failed to set configuration" 631 1.1 bouyer ", err=%s\n", usbd_errstr(err)); 632 1.1 bouyer return; 633 1.1 bouyer } 634 1.1 bouyer 635 1.1 bouyer err = usbd_device2interface_handle(dev, 0, &sc->sc_iface); 636 1.1 bouyer if (err) { 637 1.1 bouyer aprint_error_dev(self, "getting interface handle failed\n"); 638 1.1 bouyer return; 639 1.1 bouyer } 640 1.1 bouyer 641 1.1 bouyer id = usbd_get_interface_descriptor(sc->sc_iface); 642 1.1 bouyer if (id->bNumEndpoints < 2) { 643 1.1 bouyer aprint_error_dev(self, "%d endpoints < 2\n", id->bNumEndpoints); 644 1.1 bouyer return; 645 1.1 bouyer } 646 1.1 bouyer 647 1.1 bouyer val32 = htole32(0x0000beef); 648 1.1 bouyer err = gscan_write_device(sc, GSCAN_SET_HOST_FORMAT, 649 1.1 bouyer &val32, sizeof(val32)); 650 1.1 bouyer 651 1.1 bouyer if (err) { 652 1.1 bouyer aprint_error_dev(self, "SET_HOST_FORMAT: %s\n", 653 1.1 bouyer usbd_errstr(err)); 654 1.1 bouyer return; 655 1.1 bouyer } 656 1.1 bouyer 657 1.1 bouyer err = gscan_read_device(sc, GSCAN_GET_DEVICE_CONFIG, 658 1.1 bouyer &gscan_config, sizeof(struct gscan_config)); 659 1.1 bouyer if (err) { 660 1.1 bouyer aprint_error_dev(self, "GET_DEVICE_CONFIG: %s\n", 661 1.1 bouyer usbd_errstr(err)); 662 1.1 bouyer return; 663 1.1 bouyer } 664 1.1 bouyer aprint_normal_dev(self, "%d port%s, sw version %d, hw version %d\n", 665 1.1 bouyer gscan_config.conf_count + 1, gscan_config.conf_count ? "s" : "", 666 1.1 bouyer le32toh(gscan_config.sw_version), le32toh(gscan_config.hw_version)); 667 1.1 bouyer 668 1.1 bouyer err = gscan_read_device(sc, GSCAN_GET_BT_CONST, 669 1.1 bouyer &gscan_bt_const, sizeof(struct gscan_bt_const)); 670 1.1 bouyer if (err) { 671 1.1 bouyer aprint_error_dev(self, "GET_BT_CONST: %s\n", 672 1.1 bouyer usbd_errstr(err)); 673 1.1 bouyer return; 674 1.1 bouyer } 675 1.1 bouyer aprint_debug_dev(self, "feat 0x%x clk %dHz tseg1 %d -> %d tseg2 %d -> %d max swj %d brp %d -> %d/%d\n", 676 1.1 bouyer le32toh(gscan_bt_const.btc_features), 677 1.1 bouyer le32toh(gscan_bt_const.btc_fclk), 678 1.1 bouyer le32toh(gscan_bt_const.btc_tseg1_min), 679 1.1 bouyer le32toh(gscan_bt_const.btc_tseg1_max), 680 1.1 bouyer le32toh(gscan_bt_const.btc_tseg2_min), 681 1.1 bouyer le32toh(gscan_bt_const.btc_tseg2_max), 682 1.1 bouyer le32toh(gscan_bt_const.btc_swj_max), 683 1.1 bouyer le32toh(gscan_bt_const.btc_brp_min), 684 1.1 bouyer le32toh(gscan_bt_const.btc_brp_max), 685 1.1 bouyer le32toh(gscan_bt_const.btc_brp_inc)); 686 1.1 bouyer 687 1.1 bouyer sc->sc_timecaps.cltc_prop_min = 0; 688 1.1 bouyer sc->sc_timecaps.cltc_prop_max = 0; 689 1.1 bouyer sc->sc_timecaps.cltc_ps1_min = le32toh(gscan_bt_const.btc_tseg1_min); 690 1.1 bouyer sc->sc_timecaps.cltc_ps1_max = le32toh(gscan_bt_const.btc_tseg1_max); 691 1.1 bouyer sc->sc_timecaps.cltc_ps2_min = le32toh(gscan_bt_const.btc_tseg2_min); 692 1.1 bouyer sc->sc_timecaps.cltc_ps2_max = le32toh(gscan_bt_const.btc_tseg2_max); 693 1.1 bouyer sc->sc_timecaps.cltc_sjw_max = le32toh(gscan_bt_const.btc_swj_max); 694 1.1 bouyer sc->sc_timecaps.cltc_brp_min = le32toh(gscan_bt_const.btc_brp_min); 695 1.1 bouyer sc->sc_timecaps.cltc_brp_max = le32toh(gscan_bt_const.btc_brp_max); 696 1.1 bouyer sc->sc_timecaps.cltc_brp_inc = le32toh(gscan_bt_const.btc_brp_inc); 697 1.1 bouyer sc->sc_timecaps.cltc_clock_freq = le32toh(gscan_bt_const.btc_fclk); 698 1.1 bouyer sc->sc_timecaps.cltc_linkmode_caps = 0; 699 1.1 bouyer if (le32toh(gscan_bt_const.btc_features) & FEAT_LISTEN_ONLY) 700 1.1 bouyer sc->sc_timecaps.cltc_linkmode_caps |= CAN_LINKMODE_LISTENONLY; 701 1.1 bouyer if (le32toh(gscan_bt_const.btc_features) & FEAT_LOOPBACK) 702 1.1 bouyer sc->sc_timecaps.cltc_linkmode_caps |= CAN_LINKMODE_LOOPBACK; 703 1.1 bouyer if (le32toh(gscan_bt_const.btc_features) & FEAT_TRIPLE_SAMPLE) 704 1.1 bouyer sc->sc_timecaps.cltc_linkmode_caps |= CAN_LINKMODE_3SAMPLES; 705 1.1 bouyer 706 1.1 bouyer can_ifinit_timings(&sc->sc_cansc); 707 1.1 bouyer sc->sc_timings.clt_prop = 0; 708 1.1 bouyer sc->sc_timings.clt_sjw = 1; 709 1.1 bouyer 710 1.1 bouyer /* Find endpoints. */ 711 1.1 bouyer ed = usbd_interface2endpoint_descriptor(sc->sc_iface, 0); 712 1.1 bouyer if (ed == NULL) { 713 1.1 bouyer aprint_error_dev(self, "couldn't get ep 1\n"); 714 1.1 bouyer return; 715 1.1 bouyer } 716 1.1 bouyer const uint8_t xt1 = UE_GET_XFERTYPE(ed->bmAttributes); 717 1.1 bouyer const uint8_t dir1 = UE_GET_DIR(ed->bEndpointAddress); 718 1.1 bouyer 719 1.1 bouyer if (dir1 != UE_DIR_IN || xt1 != UE_BULK) { 720 1.1 bouyer aprint_error_dev(self, 721 1.1 bouyer "ep 1 wrong dir %d or xt %d\n", dir1, xt1); 722 1.1 bouyer return; 723 1.1 bouyer } 724 1.1 bouyer sc->sc_ed_rx = ed->bEndpointAddress; 725 1.1 bouyer 726 1.1 bouyer ed = usbd_interface2endpoint_descriptor(sc->sc_iface, 1); 727 1.1 bouyer if (ed == NULL) { 728 1.1 bouyer aprint_error_dev(self, "couldn't get ep 2\n"); 729 1.1 bouyer return; 730 1.1 bouyer } 731 1.1 bouyer const uint8_t xt2 = UE_GET_XFERTYPE(ed->bmAttributes); 732 1.1 bouyer const uint8_t dir2 = UE_GET_DIR(ed->bEndpointAddress); 733 1.1 bouyer 734 1.1 bouyer if (dir2 != UE_DIR_OUT || xt2 != UE_BULK) { 735 1.1 bouyer aprint_error_dev(self, 736 1.1 bouyer "ep 2 wrong dir %d or xt %d\n", dir2, xt2); 737 1.1 bouyer return; 738 1.1 bouyer } 739 1.1 bouyer sc->sc_ed_tx = ed->bEndpointAddress; 740 1.1 bouyer 741 1.1 bouyer mutex_init(&sc->sc_txlock, MUTEX_DEFAULT, IPL_SOFTUSB); 742 1.1 bouyer mutex_init(&sc->sc_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB); 743 1.1 bouyer sc->sc_rxstopped = true; 744 1.1 bouyer sc->sc_txstopped = true; 745 1.1 bouyer 746 1.1 bouyer 747 1.1 bouyer ifp = if_alloc(IFT_OTHER); 748 1.1 bouyer strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); 749 1.1 bouyer ifp->if_softc = sc; 750 1.1 bouyer ifp->if_capabilities = 0; 751 1.1 bouyer ifp->if_flags = 0; 752 1.1 bouyer ifp->if_extflags = IFEF_MPSAFE; 753 1.1 bouyer ifp->if_start = gscan_ifstart; 754 1.1 bouyer ifp->if_ioctl = gscan_ifioctl; 755 1.1 bouyer ifp->if_stop = gscan_ifstop; 756 1.1 bouyer ifp->if_watchdog = gscan_ifwatchdog; 757 1.1 bouyer IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 758 1.1 bouyer 759 1.1 bouyer sc->sc_ifp = ifp; 760 1.1 bouyer can_ifattach(ifp); 761 1.1 bouyer if_deferred_start_init(ifp, NULL); 762 1.1 bouyer bpf_mtap_softint_init(ifp); 763 1.1 bouyer rnd_attach_source(&sc->sc_rnd_source, device_xname(self), 764 1.1 bouyer RND_TYPE_NET, RND_FLAG_DEFAULT); 765 1.1 bouyer #ifdef MBUFTRACE 766 1.1 bouyer ifp->if_mowner = kmem_zalloc(sizeof(*ifp->if_mowner), KM_SLEEP); 767 1.1 bouyer strlcpy(ifp->if_mowner->mo_name, ifp->if_xname, 768 1.1 bouyer sizeof(ifp->if_mowner->mo_name)); 769 1.1 bouyer MOWNER_ATTACH(ifp->if_mowner); 770 1.1 bouyer #endif 771 1.1 bouyer usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 772 1.1 bouyer }; 773 1.1 bouyer 774 1.1 bouyer static int 775 1.1 bouyer gscan_detach(device_t self, int flags) 776 1.1 bouyer { 777 1.1 bouyer GSCANHIST_FUNC(); GSCANHIST_CALLED(); 778 1.1 bouyer struct gscan_softc * const sc = device_private(self); 779 1.1 bouyer 780 1.1 bouyer struct ifnet * const ifp = sc->sc_ifp; 781 1.1 bouyer /* 782 1.1 bouyer * Prevent new activity. After we stop the interface, it 783 1.1 bouyer * cannot be brought back up. 784 1.1 bouyer */ 785 1.1 bouyer atomic_store_relaxed(&sc->sc_dying, true); 786 1.1 bouyer 787 1.1 bouyer /* 788 1.1 bouyer * If we're still running on the network, stop and wait for all 789 1.1 bouyer * asynchronous activity to finish. 790 1.1 bouyer * 791 1.1 bouyer * If _attach_ifp never ran, IFNET_LOCK won't work, but 792 1.1 bouyer * no activity is possible, so just skip this part. 793 1.1 bouyer */ 794 1.1 bouyer if (ifp != NULL) { 795 1.1 bouyer IFNET_LOCK(ifp); 796 1.1 bouyer if (ifp->if_flags & IFF_RUNNING) { 797 1.1 bouyer gscan_stop(sc, ifp, 1); 798 1.1 bouyer } 799 1.1 bouyer IFNET_UNLOCK(ifp); 800 1.1 bouyer bpf_detach(ifp); 801 1.1 bouyer if_detach(ifp); 802 1.1 bouyer } 803 1.1 bouyer rnd_detach_source(&sc->sc_rnd_source); 804 1.1 bouyer mutex_destroy(&sc->sc_txlock); 805 1.1 bouyer mutex_destroy(&sc->sc_rxlock); 806 1.1 bouyer 807 1.1 bouyer pmf_device_deregister(sc->sc_dev); 808 1.1 bouyer if (ifp != NULL) { 809 1.1 bouyer usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 810 1.1 bouyer sc->sc_dev); 811 1.1 bouyer } 812 1.1 bouyer return 0; 813 1.1 bouyer } 814 1.1 bouyer 815 1.1 bouyer static int 816 1.1 bouyer gscan_activate(device_t self, devact_t act) 817 1.1 bouyer { 818 1.1 bouyer GSCANHIST_FUNC(); GSCANHIST_CALLED(); 819 1.1 bouyer struct gscan_softc * const sc = device_private(self); 820 1.1 bouyer struct ifnet * const ifp = sc->sc_ifp; 821 1.1 bouyer 822 1.1 bouyer switch (act) { 823 1.1 bouyer case DVACT_DEACTIVATE: 824 1.1 bouyer if_deactivate(ifp); 825 1.1 bouyer atomic_store_relaxed(&sc->sc_dying, true); 826 1.1 bouyer mutex_enter(&sc->sc_txlock); 827 1.1 bouyer sc->sc_txstopped = true; 828 1.1 bouyer if (sc->sc_m_transmit != NULL) { 829 1.1 bouyer m_freem(sc->sc_m_transmit); 830 1.1 bouyer sc->sc_m_transmit = NULL; 831 1.1 bouyer } 832 1.1 bouyer mutex_exit(&sc->sc_txlock); 833 1.1 bouyer mutex_enter(&sc->sc_rxlock); 834 1.1 bouyer sc->sc_rxstopped = true; 835 1.1 bouyer mutex_exit(&sc->sc_rxlock); 836 1.1 bouyer return 0; 837 1.1 bouyer default: 838 1.1 bouyer return EOPNOTSUPP; 839 1.1 bouyer } 840 1.1 bouyer } 841 1.1 bouyer 842 1.1 bouyer #ifdef _MODULE 843 1.1 bouyer #include "ioconf.c" 844 1.1 bouyer #endif 845 1.1 bouyer 846 1.1 bouyer MODULE(MODULE_CLASS_DRIVER, gscan, NULL); 847 1.1 bouyer 848 1.1 bouyer static int 849 1.1 bouyer gscan_modcmd(modcmd_t cmd, void *aux) 850 1.1 bouyer { 851 1.1 bouyer int error = 0; 852 1.1 bouyer 853 1.1 bouyer switch (cmd) { 854 1.1 bouyer case MODULE_CMD_INIT: 855 1.1 bouyer #ifdef _MODULE 856 1.1 bouyer error = config_init_component(cfdriver_ioconf_gscan, 857 1.1 bouyer cfattach_ioconf_gscan, cfdata_ioconf_gscan); 858 1.1 bouyer #endif 859 1.1 bouyer return error; 860 1.1 bouyer case MODULE_CMD_FINI: 861 1.1 bouyer #ifdef _MODULE 862 1.1 bouyer error = config_fini_component(cfdriver_ioconf_gscan, 863 1.1 bouyer cfattach_ioconf_gscan, cfdata_ioconf_gscan); 864 1.1 bouyer #endif 865 1.1 bouyer return error; 866 1.1 bouyer default: 867 1.1 bouyer return ENOTTY; 868 1.1 bouyer } 869 1.1 bouyer } 870