Home | History | Annotate | Line # | Download | only in usb
      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