1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2010 Fredrik Lindberg <fli@shapeshifter.se>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD$");
30
31#include <sys/param.h>
32#include <sys/eventhandler.h>
33#include <sys/sockio.h>
34#include <sys/mbuf.h>
35#include <sys/malloc.h>
36#include <sys/kernel.h>
37#include <sys/module.h>
38#include <sys/socket.h>
39#include <sys/tty.h>
40#include <sys/sysctl.h>
41#include <sys/condvar.h>
42#include <sys/sx.h>
43#include <sys/proc.h>
44#include <sys/conf.h>
45#include <sys/bus.h>
46#include <sys/systm.h>
47#include <sys/limits.h>
48
49#include <machine/bus.h>
50
51#include <net/if.h>
52#include <net/if_var.h>
53#include <net/if_types.h>
54#include <net/netisr.h>
55#include <net/bpf.h>
56#include <netinet/in.h>
57#include <netinet/ip.h>
58#include <netinet/ip6.h>
59
60#include <dev/usb/usb.h>
61#include <dev/usb/usbdi.h>
62#include <dev/usb/usbdi_util.h>
63#include <dev/usb/usb_cdc.h>
64#include "usbdevs.h"
65#define USB_DEBUG_VAR uhso_debug
66#include <dev/usb/usb_debug.h>
67#include <dev/usb/usb_process.h>
68#include <dev/usb/usb_busdma.h>
69#include <dev/usb/usb_msctest.h>
70
71#include <dev/usb/serial/usb_serial.h>
72
73struct uhso_tty {
74	struct uhso_softc *ht_sc;
75	struct usb_xfer	*ht_xfer[3];
76	int		ht_muxport; /* Mux. port no */
77	int		ht_open;
78	char		ht_name[32];
79};
80
81struct uhso_softc {
82	device_t		sc_dev;
83	struct usb_device	*sc_udev;
84	struct mtx		sc_mtx;
85	uint32_t		sc_type;	/* Interface definition */
86	int			sc_radio;
87
88	struct usb_xfer		*sc_xfer[3];
89	uint8_t			sc_iface_no;
90	uint8_t			sc_iface_index;
91
92	/* Control pipe */
93	struct usb_xfer	*	sc_ctrl_xfer[2];
94	uint8_t			sc_ctrl_iface_no;
95
96	/* Network */
97	struct usb_xfer		*sc_if_xfer[2];
98	struct ifnet		*sc_ifp;
99	struct mbuf		*sc_mwait;	/* Partial packet */
100	size_t			sc_waitlen;	/* No. of outstanding bytes */
101	struct mbufq		sc_rxq;
102	struct callout		sc_c;
103
104	/* TTY related structures */
105	struct ucom_super_softc sc_super_ucom;
106	int			sc_ttys;
107	struct uhso_tty		*sc_tty;
108	struct ucom_softc	*sc_ucom;
109	int			sc_msr;
110	int			sc_lsr;
111	int			sc_line;
112};
113
114#define UHSO_MAX_MTU		2048
115
116/*
117 * There are mainly two type of cards floating around.
118 * The first one has 2,3 or 4 interfaces with a multiplexed serial port
119 * and packet interface on the first interface and bulk serial ports
120 * on the others.
121 * The second type of card has several other interfaces, their purpose
122 * can be detected during run-time.
123 */
124#define UHSO_IFACE_SPEC(usb_type, port, port_type) \
125	(((usb_type) << 24) | ((port) << 16) | (port_type))
126
127#define UHSO_IFACE_USB_TYPE(x) ((x >> 24) & 0xff)
128#define UHSO_IFACE_PORT(x) ((x >> 16) & 0xff)
129#define UHSO_IFACE_PORT_TYPE(x) (x & 0xff)
130
131/*
132 * USB interface types
133 */
134#define UHSO_IF_NET		0x01	/* Network packet interface */
135#define UHSO_IF_MUX		0x02	/* Multiplexed serial port */
136#define UHSO_IF_BULK		0x04	/* Bulk interface */
137
138/*
139 * Port types
140 */
141#define UHSO_PORT_UNKNOWN	0x00
142#define UHSO_PORT_SERIAL	0x01	/* Serial port */
143#define UHSO_PORT_NETWORK	0x02	/* Network packet interface */
144
145/*
146 * Multiplexed serial port destination sub-port names
147 */
148#define UHSO_MPORT_TYPE_CTL	0x00	/* Control port */
149#define UHSO_MPORT_TYPE_APP	0x01	/* Application */
150#define UHSO_MPORT_TYPE_PCSC	0x02
151#define UHSO_MPORT_TYPE_GPS	0x03
152#define UHSO_MPORT_TYPE_APP2	0x04	/* Secondary application */
153#define UHSO_MPORT_TYPE_MAX	UHSO_MPORT_TYPE_APP2
154#define UHSO_MPORT_TYPE_NOMAX	8	/* Max number of mux ports */
155
156/*
157 * Port definitions
158 * Note that these definitions are arbitrary and do not match the values
159 * returned by the auto config descriptor.
160 */
161#define UHSO_PORT_TYPE_UNKNOWN	0x00
162#define UHSO_PORT_TYPE_CTL	0x01
163#define UHSO_PORT_TYPE_APP	0x02
164#define UHSO_PORT_TYPE_APP2	0x03
165#define UHSO_PORT_TYPE_MODEM	0x04
166#define UHSO_PORT_TYPE_NETWORK	0x05
167#define UHSO_PORT_TYPE_DIAG	0x06
168#define UHSO_PORT_TYPE_DIAG2	0x07
169#define UHSO_PORT_TYPE_GPS	0x08
170#define UHSO_PORT_TYPE_GPSCTL	0x09
171#define UHSO_PORT_TYPE_PCSC	0x0a
172#define UHSO_PORT_TYPE_MSD	0x0b
173#define UHSO_PORT_TYPE_VOICE	0x0c
174#define UHSO_PORT_TYPE_MAX	0x0c
175
176static eventhandler_tag uhso_etag;
177
178/* Overall port type */
179static char *uhso_port[] = {
180	"Unknown",
181	"Serial",
182	"Network",
183	"Network/Serial"
184};
185
186/*
187 * Map between interface port type read from device and description type.
188 * The position in this array is a direct map to the auto config
189 * descriptor values.
190 */
191static unsigned char uhso_port_map[] = {
192	UHSO_PORT_TYPE_UNKNOWN,
193	UHSO_PORT_TYPE_DIAG,
194	UHSO_PORT_TYPE_GPS,
195	UHSO_PORT_TYPE_GPSCTL,
196	UHSO_PORT_TYPE_APP,
197	UHSO_PORT_TYPE_APP2,
198	UHSO_PORT_TYPE_CTL,
199	UHSO_PORT_TYPE_NETWORK,
200	UHSO_PORT_TYPE_MODEM,
201	UHSO_PORT_TYPE_MSD,
202	UHSO_PORT_TYPE_PCSC,
203	UHSO_PORT_TYPE_VOICE
204};
205static char uhso_port_map_max = sizeof(uhso_port_map) / sizeof(char);
206
207static unsigned char uhso_mux_port_map[] = {
208	UHSO_PORT_TYPE_CTL,
209	UHSO_PORT_TYPE_APP,
210	UHSO_PORT_TYPE_PCSC,
211	UHSO_PORT_TYPE_GPS,
212	UHSO_PORT_TYPE_APP2
213};
214
215static char *uhso_port_type[] = {
216	"Unknown",  /* Not a valid port */
217	"Control",
218	"Application",
219	"Application (Secondary)",
220	"Modem",
221	"Network",
222	"Diagnostic",
223	"Diagnostic (Secondary)",
224	"GPS",
225	"GPS Control",
226	"PC Smartcard",
227	"MSD",
228	"Voice",
229};
230
231static char *uhso_port_type_sysctl[] = {
232	"unknown",
233	"control",
234	"application",
235	"application",
236	"modem",
237	"network",
238	"diagnostic",
239	"diagnostic",
240	"gps",
241	"gps_control",
242	"pcsc",
243	"msd",
244	"voice",
245};
246
247#define UHSO_STATIC_IFACE	0x01
248#define UHSO_AUTO_IFACE		0x02
249
250/* ifnet device unit allocations */
251static struct unrhdr *uhso_ifnet_unit = NULL;
252
253static const STRUCT_USB_HOST_ID uhso_devs[] = {
254#define	UHSO_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
255	/* Option GlobeTrotter MAX 7.2 with upgraded firmware */
256	UHSO_DEV(OPTION, GTMAX72, UHSO_STATIC_IFACE),
257	/* Option GlobeSurfer iCON 7.2 */
258	UHSO_DEV(OPTION, GSICON72, UHSO_STATIC_IFACE),
259	/* Option iCON 225 */
260	UHSO_DEV(OPTION, GTHSDPA, UHSO_STATIC_IFACE),
261	/* Option GlobeSurfer iCON HSUPA */
262	UHSO_DEV(OPTION, GSICONHSUPA, UHSO_STATIC_IFACE),
263	/* Option GlobeTrotter HSUPA */
264	UHSO_DEV(OPTION, GTHSUPA, UHSO_STATIC_IFACE),
265	/* GE40x */
266	UHSO_DEV(OPTION, GE40X, UHSO_AUTO_IFACE),
267	UHSO_DEV(OPTION, GE40X_1, UHSO_AUTO_IFACE),
268	UHSO_DEV(OPTION, GE40X_2, UHSO_AUTO_IFACE),
269	UHSO_DEV(OPTION, GE40X_3, UHSO_AUTO_IFACE),
270	/* Option GlobeSurfer iCON 401 */
271	UHSO_DEV(OPTION, ICON401, UHSO_AUTO_IFACE),
272	/* Option GlobeTrotter Module 382 */
273	UHSO_DEV(OPTION, GMT382, UHSO_AUTO_IFACE),
274	/* Option GTM661W */
275	UHSO_DEV(OPTION, GTM661W, UHSO_AUTO_IFACE),
276	/* Option iCON EDGE */
277	UHSO_DEV(OPTION, ICONEDGE, UHSO_STATIC_IFACE),
278	/* Option Module HSxPA */
279	UHSO_DEV(OPTION, MODHSXPA, UHSO_STATIC_IFACE),
280	/* Option iCON 321 */
281	UHSO_DEV(OPTION, ICON321, UHSO_STATIC_IFACE),
282	/* Option iCON 322 */
283	UHSO_DEV(OPTION, GTICON322, UHSO_STATIC_IFACE),
284	/* Option iCON 505 */
285	UHSO_DEV(OPTION, ICON505, UHSO_AUTO_IFACE),
286	/* Option iCON 452 */
287	UHSO_DEV(OPTION, ICON505, UHSO_AUTO_IFACE),
288#undef UHSO_DEV
289};
290
291static SYSCTL_NODE(_hw_usb, OID_AUTO, uhso, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
292    "USB uhso");
293static int uhso_autoswitch = 1;
294SYSCTL_INT(_hw_usb_uhso, OID_AUTO, auto_switch, CTLFLAG_RWTUN,
295    &uhso_autoswitch, 0, "Automatically switch to modem mode");
296
297#ifdef USB_DEBUG
298#ifdef UHSO_DEBUG
299static int uhso_debug = UHSO_DEBUG;
300#else
301static int uhso_debug = -1;
302#endif
303
304SYSCTL_INT(_hw_usb_uhso, OID_AUTO, debug, CTLFLAG_RWTUN,
305    &uhso_debug, 0, "Debug level");
306
307#define UHSO_DPRINTF(n, x, ...) {\
308	if (uhso_debug >= n) {\
309		printf("%s: " x, __func__, ##__VA_ARGS__);\
310	}\
311}
312#else
313#define UHSO_DPRINTF(n, x, ...)
314#endif
315
316#ifdef UHSO_DEBUG_HEXDUMP
317# define UHSO_HEXDUMP(_buf, _len) do { \
318  { \
319        size_t __tmp; \
320        const char *__buf = (const char *)_buf; \
321        for (__tmp = 0; __tmp < _len; __tmp++) \
322                printf("%02hhx ", *__buf++); \
323    printf("\n"); \
324  } \
325} while(0)
326#else
327# define UHSO_HEXDUMP(_buf, _len)
328#endif
329
330enum {
331	UHSO_MUX_ENDPT_INTR = 0,
332	UHSO_MUX_ENDPT_MAX
333};
334
335enum {
336	UHSO_CTRL_READ = 0,
337	UHSO_CTRL_WRITE,
338	UHSO_CTRL_MAX
339};
340
341enum {
342	UHSO_IFNET_READ = 0,
343	UHSO_IFNET_WRITE,
344	UHSO_IFNET_MAX
345};
346
347enum {
348	UHSO_BULK_ENDPT_READ = 0,
349	UHSO_BULK_ENDPT_WRITE,
350	UHSO_BULK_ENDPT_INTR,
351	UHSO_BULK_ENDPT_MAX
352};
353
354static usb_callback_t uhso_mux_intr_callback;
355static usb_callback_t uhso_mux_read_callback;
356static usb_callback_t uhso_mux_write_callback;
357static usb_callback_t uhso_bs_read_callback;
358static usb_callback_t uhso_bs_write_callback;
359static usb_callback_t uhso_bs_intr_callback;
360static usb_callback_t uhso_ifnet_read_callback;
361static usb_callback_t uhso_ifnet_write_callback;
362
363/* Config used for the default control pipes */
364static const struct usb_config uhso_ctrl_config[UHSO_CTRL_MAX] = {
365	[UHSO_CTRL_READ] = {
366		.type = UE_CONTROL,
367		.endpoint = 0x00,
368		.direction = UE_DIR_ANY,
369		.flags = { .pipe_bof = 1, .short_xfer_ok = 1 },
370		.bufsize = sizeof(struct usb_device_request) + 1024,
371		.callback = &uhso_mux_read_callback
372	},
373
374	[UHSO_CTRL_WRITE] = {
375		.type = UE_CONTROL,
376		.endpoint = 0x00,
377		.direction = UE_DIR_ANY,
378		.flags = { .pipe_bof = 1, .force_short_xfer = 1 },
379		.bufsize = sizeof(struct usb_device_request) + 1024,
380		.timeout = 1000,
381		.callback = &uhso_mux_write_callback
382	}
383};
384
385/* Config for the multiplexed serial ports */
386static const struct usb_config uhso_mux_config[UHSO_MUX_ENDPT_MAX] = {
387	[UHSO_MUX_ENDPT_INTR] = {
388		.type = UE_INTERRUPT,
389		.endpoint = UE_ADDR_ANY,
390		.direction = UE_DIR_IN,
391		.flags = { .short_xfer_ok = 1 },
392		.bufsize = 0,
393		.callback = &uhso_mux_intr_callback,
394	}
395};
396
397/* Config for the raw IP-packet interface */
398static const struct usb_config uhso_ifnet_config[UHSO_IFNET_MAX] = {
399	[UHSO_IFNET_READ] = {
400		.type = UE_BULK,
401		.endpoint = UE_ADDR_ANY,
402		.direction = UE_DIR_IN,
403		.flags = { .pipe_bof = 1, .short_xfer_ok = 1 },
404		.bufsize = MCLBYTES,
405		.callback = &uhso_ifnet_read_callback
406	},
407	[UHSO_IFNET_WRITE] = {
408		.type = UE_BULK,
409		.endpoint = UE_ADDR_ANY,
410		.direction = UE_DIR_OUT,
411		.flags = { .pipe_bof = 1, .force_short_xfer = 1 },
412		.bufsize = MCLBYTES,
413		.timeout = 5 * USB_MS_HZ,
414		.callback = &uhso_ifnet_write_callback
415	}
416};
417
418/* Config for interfaces with normal bulk serial ports */
419static const struct usb_config uhso_bs_config[UHSO_BULK_ENDPT_MAX] = {
420	[UHSO_BULK_ENDPT_READ] = {
421		.type = UE_BULK,
422		.endpoint = UE_ADDR_ANY,
423		.direction = UE_DIR_IN,
424		.flags = { .pipe_bof = 1, .short_xfer_ok = 1 },
425		.bufsize = 4096,
426		.callback = &uhso_bs_read_callback
427	},
428
429	[UHSO_BULK_ENDPT_WRITE] = {
430		.type = UE_BULK,
431		.endpoint = UE_ADDR_ANY,
432		.direction = UE_DIR_OUT,
433		.flags = { .pipe_bof = 1, .force_short_xfer = 1 },
434		.bufsize = 8192,
435		.callback = &uhso_bs_write_callback
436	},
437
438	[UHSO_BULK_ENDPT_INTR] = {
439		.type = UE_INTERRUPT,
440		.endpoint = UE_ADDR_ANY,
441		.direction = UE_DIR_IN,
442		.flags = { .short_xfer_ok = 1 },
443		.bufsize = 0,
444		.callback = &uhso_bs_intr_callback,
445	}
446};
447
448static int  uhso_probe_iface(struct uhso_softc *, int,
449    int (*probe)(struct usb_device *, int));
450static int  uhso_probe_iface_auto(struct usb_device *, int);
451static int  uhso_probe_iface_static(struct usb_device *, int);
452static int  uhso_attach_muxserial(struct uhso_softc *, struct usb_interface *,
453    int type);
454static int  uhso_attach_bulkserial(struct uhso_softc *, struct usb_interface *,
455    int type);
456static int  uhso_attach_ifnet(struct uhso_softc *, struct usb_interface *,
457    int type);
458static void uhso_test_autoinst(void *, struct usb_device *,
459		struct usb_attach_arg *);
460static int  uhso_driver_loaded(struct module *, int, void *);
461static int uhso_radio_sysctl(SYSCTL_HANDLER_ARGS);
462static int uhso_radio_ctrl(struct uhso_softc *, int);
463
464static void uhso_free(struct ucom_softc *);
465static void uhso_ucom_start_read(struct ucom_softc *);
466static void uhso_ucom_stop_read(struct ucom_softc *);
467static void uhso_ucom_start_write(struct ucom_softc *);
468static void uhso_ucom_stop_write(struct ucom_softc *);
469static void uhso_ucom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *);
470static void uhso_ucom_cfg_set_dtr(struct ucom_softc *, uint8_t);
471static void uhso_ucom_cfg_set_rts(struct ucom_softc *, uint8_t);
472static void uhso_if_init(void *);
473static void uhso_if_start(struct ifnet *);
474static void uhso_if_stop(struct uhso_softc *);
475static int  uhso_if_ioctl(struct ifnet *, u_long, caddr_t);
476static int  uhso_if_output(struct ifnet *, struct mbuf *,
477    const struct sockaddr *, struct route *);
478static void uhso_if_rxflush(void *);
479
480static device_probe_t uhso_probe;
481static device_attach_t uhso_attach;
482static device_detach_t uhso_detach;
483static void uhso_free_softc(struct uhso_softc *);
484
485static device_method_t uhso_methods[] = {
486	DEVMETHOD(device_probe,		uhso_probe),
487	DEVMETHOD(device_attach,	uhso_attach),
488	DEVMETHOD(device_detach,	uhso_detach),
489	{ 0, 0 }
490};
491
492static driver_t uhso_driver = {
493	.name = "uhso",
494	.methods = uhso_methods,
495	.size = sizeof(struct uhso_softc)
496};
497
498static devclass_t uhso_devclass;
499DRIVER_MODULE(uhso, uhub, uhso_driver, uhso_devclass, uhso_driver_loaded, 0);
500MODULE_DEPEND(uhso, ucom, 1, 1, 1);
501MODULE_DEPEND(uhso, usb, 1, 1, 1);
502MODULE_VERSION(uhso, 1);
503USB_PNP_HOST_INFO(uhso_devs);
504
505static struct ucom_callback uhso_ucom_callback = {
506	.ucom_cfg_get_status = &uhso_ucom_cfg_get_status,
507	.ucom_cfg_set_dtr = &uhso_ucom_cfg_set_dtr,
508	.ucom_cfg_set_rts = &uhso_ucom_cfg_set_rts,
509	.ucom_start_read = uhso_ucom_start_read,
510	.ucom_stop_read = uhso_ucom_stop_read,
511	.ucom_start_write = uhso_ucom_start_write,
512	.ucom_stop_write = uhso_ucom_stop_write,
513	.ucom_free = &uhso_free,
514};
515
516static int
517uhso_probe(device_t self)
518{
519	struct usb_attach_arg *uaa = device_get_ivars(self);
520	int error;
521
522	if (uaa->usb_mode != USB_MODE_HOST)
523		return (ENXIO);
524	if (uaa->info.bConfigIndex != 0)
525		return (ENXIO);
526	if (uaa->info.bDeviceClass != 0xff)
527		return (ENXIO);
528
529	error = usbd_lookup_id_by_uaa(uhso_devs, sizeof(uhso_devs), uaa);
530	if (error != 0)
531		return (error);
532
533	/*
534	 * Probe device to see if we are able to attach
535	 * to this interface or not.
536	 */
537	if (USB_GET_DRIVER_INFO(uaa) == UHSO_AUTO_IFACE) {
538		if (uhso_probe_iface_auto(uaa->device,
539		    uaa->info.bIfaceNum) == 0)
540			return (ENXIO);
541	}
542	return (error);
543}
544
545static int
546uhso_attach(device_t self)
547{
548	struct uhso_softc *sc = device_get_softc(self);
549	struct usb_attach_arg *uaa = device_get_ivars(self);
550	struct usb_interface_descriptor *id;
551	struct sysctl_ctx_list *sctx;
552	struct sysctl_oid *soid;
553	struct sysctl_oid *tree = NULL, *tty_node;
554	struct ucom_softc *ucom;
555	struct uhso_tty *ht;
556	int i, error, port;
557	void *probe_f;
558	usb_error_t uerr;
559	char *desc;
560
561	sc->sc_dev = self;
562	sc->sc_udev = uaa->device;
563	mtx_init(&sc->sc_mtx, "uhso", NULL, MTX_DEF);
564	mbufq_init(&sc->sc_rxq, INT_MAX);	/* XXXGL: sane maximum */
565	ucom_ref(&sc->sc_super_ucom);
566
567	sc->sc_radio = 1;
568
569	id = usbd_get_interface_descriptor(uaa->iface);
570	sc->sc_ctrl_iface_no = id->bInterfaceNumber;
571
572	sc->sc_iface_no = uaa->info.bIfaceNum;
573	sc->sc_iface_index = uaa->info.bIfaceIndex;
574
575	/* Setup control pipe */
576	uerr = usbd_transfer_setup(uaa->device,
577	    &sc->sc_iface_index, sc->sc_ctrl_xfer,
578	    uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx);
579	if (uerr) {
580		device_printf(self, "Failed to setup control pipe: %s\n",
581		    usbd_errstr(uerr));
582		goto out;
583	}
584
585	if (USB_GET_DRIVER_INFO(uaa) == UHSO_STATIC_IFACE)
586		probe_f = uhso_probe_iface_static;
587	else if (USB_GET_DRIVER_INFO(uaa) == UHSO_AUTO_IFACE)
588		probe_f = uhso_probe_iface_auto;
589	else
590		goto out;
591
592	error = uhso_probe_iface(sc, uaa->info.bIfaceNum, probe_f);
593	if (error != 0)
594		goto out;
595
596	sctx = device_get_sysctl_ctx(sc->sc_dev);
597	soid = device_get_sysctl_tree(sc->sc_dev);
598
599	SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "type",
600	    CTLFLAG_RD, uhso_port[UHSO_IFACE_PORT(sc->sc_type)], 0,
601	    "Port available at this interface");
602	SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "radio",
603	    CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, sc, 0,
604	    uhso_radio_sysctl, "I", "Enable radio");
605
606	/*
607	 * The default interface description on most Option devices isn't
608	 * very helpful. So we skip device_set_usb_desc and set the
609	 * device description manually.
610	 */
611	device_set_desc_copy(self, uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)]);
612	/* Announce device */
613	device_printf(self, "<%s port> at <%s %s> on %s\n",
614	    uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)],
615	    usb_get_manufacturer(uaa->device),
616	    usb_get_product(uaa->device),
617	    device_get_nameunit(device_get_parent(self)));
618
619	if (sc->sc_ttys > 0) {
620		SYSCTL_ADD_INT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "ports",
621		    CTLFLAG_RD, &sc->sc_ttys, 0, "Number of attached serial ports");
622
623		tree = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
624		    "port", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Serial ports");
625	}
626
627	/*
628	 * Loop through the number of found TTYs and create sysctl
629	 * nodes for them.
630	 */
631	for (i = 0; i < sc->sc_ttys; i++) {
632		ht = &sc->sc_tty[i];
633		ucom = &sc->sc_ucom[i];
634
635		if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX)
636			port = uhso_mux_port_map[ht->ht_muxport];
637		else
638			port = UHSO_IFACE_PORT_TYPE(sc->sc_type);
639
640		desc = uhso_port_type_sysctl[port];
641
642		tty_node = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(tree), OID_AUTO,
643		    desc, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "");
644
645		ht->ht_name[0] = 0;
646		if (sc->sc_ttys == 1)
647			snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_super->sc_unit);
648		else {
649			snprintf(ht->ht_name, 32, "cuaU%d.%d",
650			    ucom->sc_super->sc_unit, ucom->sc_subunit);
651		}
652
653		desc = uhso_port_type[port];
654		SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO,
655		    "tty", CTLFLAG_RD, ht->ht_name, 0, "");
656		SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO,
657		    "desc", CTLFLAG_RD, desc, 0, "");
658
659		if (bootverbose)
660			device_printf(sc->sc_dev,
661			    "\"%s\" port at %s\n", desc, ht->ht_name);
662	}
663
664	return (0);
665out:
666	uhso_detach(sc->sc_dev);
667	return (ENXIO);
668}
669
670static int
671uhso_detach(device_t self)
672{
673	struct uhso_softc *sc = device_get_softc(self);
674	int i;
675
676	usbd_transfer_unsetup(sc->sc_xfer, 3);
677	usbd_transfer_unsetup(sc->sc_ctrl_xfer, UHSO_CTRL_MAX);
678	if (sc->sc_ttys > 0) {
679		ucom_detach(&sc->sc_super_ucom, sc->sc_ucom);
680
681		for (i = 0; i < sc->sc_ttys; i++) {
682			if (sc->sc_tty[i].ht_muxport != -1) {
683				usbd_transfer_unsetup(sc->sc_tty[i].ht_xfer,
684				    UHSO_CTRL_MAX);
685			}
686		}
687	}
688
689	if (sc->sc_ifp != NULL) {
690		callout_drain(&sc->sc_c);
691		free_unr(uhso_ifnet_unit, sc->sc_ifp->if_dunit);
692		mtx_lock(&sc->sc_mtx);
693		uhso_if_stop(sc);
694		mtx_unlock(&sc->sc_mtx);
695		bpfdetach(sc->sc_ifp);
696		if_detach(sc->sc_ifp);
697		if_free(sc->sc_ifp);
698		usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX);
699	}
700
701	device_claim_softc(self);
702
703	uhso_free_softc(sc);
704
705	return (0);
706}
707
708UCOM_UNLOAD_DRAIN(uhso);
709
710static void
711uhso_free_softc(struct uhso_softc *sc)
712{
713	if (ucom_unref(&sc->sc_super_ucom)) {
714		free(sc->sc_tty, M_USBDEV);
715		free(sc->sc_ucom, M_USBDEV);
716		mtx_destroy(&sc->sc_mtx);
717		device_free_softc(sc);
718	}
719}
720
721static void
722uhso_free(struct ucom_softc *ucom)
723{
724	uhso_free_softc(ucom->sc_parent);
725}
726
727static void
728uhso_test_autoinst(void *arg, struct usb_device *udev,
729    struct usb_attach_arg *uaa)
730{
731	struct usb_interface *iface;
732	struct usb_interface_descriptor *id;
733
734	if (uaa->dev_state != UAA_DEV_READY || !uhso_autoswitch)
735		return;
736
737	iface = usbd_get_iface(udev, 0);
738	if (iface == NULL)
739		return;
740	id = iface->idesc;
741	if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
742		return;
743	if (usbd_lookup_id_by_uaa(uhso_devs, sizeof(uhso_devs), uaa))
744		return;		/* no device match */
745
746	if (usb_msc_eject(udev, 0, MSC_EJECT_REZERO) == 0) {
747		/* success, mark the udev as disappearing */
748		uaa->dev_state = UAA_DEV_EJECTING;
749	}
750}
751
752static int
753uhso_driver_loaded(struct module *mod, int what, void *arg)
754{
755	switch (what) {
756	case MOD_LOAD:
757		/* register our autoinstall handler */
758		uhso_etag = EVENTHANDLER_REGISTER(usb_dev_configured,
759		    uhso_test_autoinst, NULL, EVENTHANDLER_PRI_ANY);
760		/* create our unit allocator for inet devs */
761		uhso_ifnet_unit = new_unrhdr(0, INT_MAX, NULL);
762		break;
763	case MOD_UNLOAD:
764		EVENTHANDLER_DEREGISTER(usb_dev_configured, uhso_etag);
765		delete_unrhdr(uhso_ifnet_unit);
766		break;
767	default:
768		return (EOPNOTSUPP);
769	}
770	return (0);
771}
772
773/*
774 * Probe the interface type by querying the device. The elements
775 * of an array indicates the capabilities of a particular interface.
776 * Returns a bit mask with the interface capabilities.
777 */
778static int
779uhso_probe_iface_auto(struct usb_device *udev, int index)
780{
781	struct usb_device_request req;
782	usb_error_t uerr;
783	uint16_t actlen = 0;
784	char port;
785	char buf[17] = {0};
786
787	req.bmRequestType = UT_READ_VENDOR_DEVICE;
788	req.bRequest = 0x86;
789	USETW(req.wValue, 0);
790	USETW(req.wIndex, 0);
791	USETW(req.wLength, 17);
792
793	uerr = usbd_do_request_flags(udev, NULL, &req, buf,
794	    0, &actlen, USB_MS_HZ);
795	if (uerr != 0) {
796		printf("%s: usbd_do_request_flags failed, %s\n",
797		    __func__, usbd_errstr(uerr));
798		return (0);
799	}
800
801	UHSO_DPRINTF(1, "actlen=%d\n", actlen);
802	UHSO_HEXDUMP(buf, 17);
803
804	if (index < 0 || index > 16) {
805		UHSO_DPRINTF(0, "Index %d out of range\n", index);
806		return (0);
807	}
808
809	UHSO_DPRINTF(1, "index=%d, type=%x[%s]\n", index, buf[index],
810	    uhso_port_type[(int)uhso_port_map[(int)buf[index]]]);
811
812	if (buf[index] >= uhso_port_map_max)
813		port = 0;
814	else
815		port = uhso_port_map[(int)buf[index]];
816
817	switch (port) {
818	case UHSO_PORT_TYPE_NETWORK:
819		return (UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
820		    UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, port));
821	case UHSO_PORT_TYPE_DIAG:
822	case UHSO_PORT_TYPE_DIAG2:
823	case UHSO_PORT_TYPE_GPS:
824	case UHSO_PORT_TYPE_GPSCTL:
825	case UHSO_PORT_TYPE_CTL:
826	case UHSO_PORT_TYPE_APP:
827	case UHSO_PORT_TYPE_APP2:
828	case UHSO_PORT_TYPE_MODEM:
829		return (UHSO_IFACE_SPEC(UHSO_IF_BULK,
830		    UHSO_PORT_SERIAL, port));
831	case UHSO_PORT_TYPE_MSD:
832		return (0);
833	case UHSO_PORT_TYPE_UNKNOWN:
834	default:
835		return (0);
836	}
837
838	return (0);
839}
840
841/*
842 * Returns the capabilities of interfaces for devices that don't
843 * support the automatic query.
844 * Returns a bit mask with the interface capabilities.
845 */
846static int
847uhso_probe_iface_static(struct usb_device *udev, int index)
848{
849	struct usb_config_descriptor *cd;
850
851	cd = usbd_get_config_descriptor(udev);
852	if (cd->bNumInterface <= 3) {
853		/* Cards with 3 or less interfaces */
854		switch (index) {
855		case 0:
856			return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
857			    UHSO_PORT_SERIAL | UHSO_PORT_NETWORK,
858			    UHSO_PORT_TYPE_NETWORK);
859		case 1:
860			return UHSO_IFACE_SPEC(UHSO_IF_BULK,
861			    UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG);
862		case 2:
863			return UHSO_IFACE_SPEC(UHSO_IF_BULK,
864			    UHSO_PORT_SERIAL, UHSO_PORT_TYPE_MODEM);
865		}
866	} else {
867		/* Cards with 4 interfaces */
868		switch (index) {
869		case 0:
870			return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
871			    UHSO_PORT_SERIAL | UHSO_PORT_NETWORK,
872			    UHSO_PORT_TYPE_NETWORK);
873		case 1:
874			return UHSO_IFACE_SPEC(UHSO_IF_BULK,
875			    UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG2);
876		case 2:
877			return UHSO_IFACE_SPEC(UHSO_IF_BULK,
878			    UHSO_PORT_SERIAL, UHSO_PORT_TYPE_MODEM);
879		case 3:
880			return UHSO_IFACE_SPEC(UHSO_IF_BULK,
881			    UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG);
882		}
883	}
884	return (0);
885}
886
887/*
888 * Probes an interface for its particular capabilities and attaches if
889 * it's a supported interface.
890 */
891static int
892uhso_probe_iface(struct uhso_softc *sc, int index,
893    int (*probe)(struct usb_device *, int))
894{
895	struct usb_interface *iface;
896	int type, error;
897
898	UHSO_DPRINTF(1, "Probing for interface %d, probe_func=%p\n", index, probe);
899
900	type = probe(sc->sc_udev, index);
901	UHSO_DPRINTF(1, "Probe result %x\n", type);
902	if (type <= 0)
903		return (ENXIO);
904
905	sc->sc_type = type;
906	iface = usbd_get_iface(sc->sc_udev, index);
907
908	if (UHSO_IFACE_PORT_TYPE(type) == UHSO_PORT_TYPE_NETWORK) {
909		error = uhso_attach_ifnet(sc, iface, type);
910		if (error) {
911			UHSO_DPRINTF(1, "uhso_attach_ifnet failed");
912			return (ENXIO);
913		}
914
915		/*
916		 * If there is an additional interrupt endpoint on this
917		 * interface then we most likely have a multiplexed serial port
918		 * available.
919		 */
920		if (iface->idesc->bNumEndpoints < 3) {
921			sc->sc_type = UHSO_IFACE_SPEC(
922			    UHSO_IFACE_USB_TYPE(type) & ~UHSO_IF_MUX,
923			    UHSO_IFACE_PORT(type) & ~UHSO_PORT_SERIAL,
924			    UHSO_IFACE_PORT_TYPE(type));
925			return (0);
926		}
927
928		UHSO_DPRINTF(1, "Trying to attach mux. serial\n");
929		error = uhso_attach_muxserial(sc, iface, type);
930		if (error == 0 && sc->sc_ttys > 0) {
931			error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom,
932			    sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx);
933			if (error) {
934				device_printf(sc->sc_dev, "ucom_attach failed\n");
935				return (ENXIO);
936			}
937			ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev);
938
939			mtx_lock(&sc->sc_mtx);
940			usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
941			mtx_unlock(&sc->sc_mtx);
942		}
943	} else if ((UHSO_IFACE_USB_TYPE(type) & UHSO_IF_BULK) &&
944	    UHSO_IFACE_PORT(type) & UHSO_PORT_SERIAL) {
945		error = uhso_attach_bulkserial(sc, iface, type);
946		if (error)
947			return (ENXIO);
948
949		error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom,
950		    sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx);
951		if (error) {
952			device_printf(sc->sc_dev, "ucom_attach failed\n");
953			return (ENXIO);
954		}
955		ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev);
956	}
957	else {
958		UHSO_DPRINTF(0, "Unknown type %x\n", type);
959		return (ENXIO);
960	}
961
962	return (0);
963}
964
965static int
966uhso_radio_ctrl(struct uhso_softc *sc, int onoff)
967{
968	struct usb_device_request req;
969	usb_error_t uerr;
970
971	req.bmRequestType = UT_VENDOR;
972	req.bRequest = onoff ? 0x82 : 0x81;
973	USETW(req.wValue, 0);
974	USETW(req.wIndex, 0);
975	USETW(req.wLength, 0);
976
977	uerr = usbd_do_request(sc->sc_udev, NULL, &req, NULL);
978	if (uerr != 0) {
979		device_printf(sc->sc_dev, "usbd_do_request_flags failed: %s\n",
980		    usbd_errstr(uerr));
981		return (-1);
982	}
983	return (onoff);
984}
985
986static int
987uhso_radio_sysctl(SYSCTL_HANDLER_ARGS)
988{
989	struct uhso_softc *sc = arg1;
990	int error, radio;
991
992	radio = sc->sc_radio;
993	error = sysctl_handle_int(oidp, &radio, 0, req);
994	if (error)
995		return (error);
996	if (radio != sc->sc_radio) {
997		radio = radio != 0 ? 1 : 0;
998		error = uhso_radio_ctrl(sc, radio);
999		if (error != -1)
1000			sc->sc_radio = radio;
1001
1002	}
1003	return (0);
1004}
1005
1006/*
1007 * Expands allocated memory to fit an additional TTY.
1008 * Two arrays are kept with matching indexes, one for ucom and one
1009 * for our private data.
1010 */
1011static int
1012uhso_alloc_tty(struct uhso_softc *sc)
1013{
1014
1015	sc->sc_ttys++;
1016	sc->sc_tty = reallocf(sc->sc_tty, sizeof(struct uhso_tty) * sc->sc_ttys,
1017	    M_USBDEV, M_WAITOK | M_ZERO);
1018	if (sc->sc_tty == NULL)
1019		return (-1);
1020
1021	sc->sc_ucom = reallocf(sc->sc_ucom,
1022	    sizeof(struct ucom_softc) * sc->sc_ttys, M_USBDEV, M_WAITOK | M_ZERO);
1023	if (sc->sc_ucom == NULL)
1024		return (-1);
1025
1026	sc->sc_tty[sc->sc_ttys - 1].ht_sc = sc;
1027
1028	UHSO_DPRINTF(1, "Allocated TTY %d\n", sc->sc_ttys - 1);
1029	return (sc->sc_ttys - 1);
1030}
1031
1032/*
1033 * Attach a multiplexed serial port
1034 * Data is read/written with requests on the default control pipe. An interrupt
1035 * endpoint returns when there is new data to be read.
1036 */
1037static int
1038uhso_attach_muxserial(struct uhso_softc *sc, struct usb_interface *iface,
1039    int type)
1040{
1041	struct usb_descriptor *desc;
1042	int i, port, tty;
1043	usb_error_t uerr;
1044
1045	/*
1046	 * The class specific interface (type 0x24) descriptor subtype field
1047	 * contains a bitmask that specifies which (and how many) ports that
1048	 * are available through this multiplexed serial port.
1049 	 */
1050	desc = usbd_find_descriptor(sc->sc_udev, NULL,
1051	    iface->idesc->bInterfaceNumber, UDESC_CS_INTERFACE, 0xff, 0, 0);
1052	if (desc == NULL) {
1053		UHSO_DPRINTF(0, "Failed to find UDESC_CS_INTERFACE\n");
1054		return (ENXIO);
1055	}
1056
1057	UHSO_DPRINTF(1, "Mux port mask %x\n", desc->bDescriptorSubtype);
1058	if (desc->bDescriptorSubtype == 0)
1059		return (ENXIO);
1060
1061	/*
1062	 * The bitmask is one octet, loop through the number of
1063	 * bits that are set and create a TTY for each.
1064	 */
1065	for (i = 0; i < 8; i++) {
1066		port = (1 << i);
1067		if ((port & desc->bDescriptorSubtype) == port) {
1068			UHSO_DPRINTF(2, "Found mux port %x (%d)\n", port, i);
1069			tty = uhso_alloc_tty(sc);
1070			if (tty < 0)
1071				return (ENOMEM);
1072			sc->sc_tty[tty].ht_muxport = i;
1073			uerr = usbd_transfer_setup(sc->sc_udev,
1074			    &sc->sc_iface_index, sc->sc_tty[tty].ht_xfer,
1075			    uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx);
1076			if (uerr) {
1077				device_printf(sc->sc_dev,
1078				    "Failed to setup control pipe: %s\n",
1079				    usbd_errstr(uerr));
1080				return (ENXIO);
1081			}
1082		}
1083	}
1084
1085	/* Setup the intr. endpoint */
1086	uerr = usbd_transfer_setup(sc->sc_udev,
1087	    &iface->idesc->bInterfaceNumber, sc->sc_xfer,
1088	    uhso_mux_config, 1, sc, &sc->sc_mtx);
1089	if (uerr)
1090		return (ENXIO);
1091
1092	return (0);
1093}
1094
1095/*
1096 * Interrupt callback for the multiplexed serial port. Indicates
1097 * which serial port has data waiting.
1098 */
1099static void
1100uhso_mux_intr_callback(struct usb_xfer *xfer, usb_error_t error)
1101{
1102	struct usb_page_cache *pc;
1103	struct usb_page_search res;
1104	struct uhso_softc *sc = usbd_xfer_softc(xfer);
1105	unsigned int i, mux;
1106
1107	UHSO_DPRINTF(3, "status %d\n", USB_GET_STATE(xfer));
1108
1109	switch (USB_GET_STATE(xfer)) {
1110	case USB_ST_TRANSFERRED:
1111		/*
1112		 * The multiplexed port number can be found at the first byte.
1113		 * It contains a bit mask, we transform this in to an integer.
1114		 */
1115		pc = usbd_xfer_get_frame(xfer, 0);
1116		usbd_get_page(pc, 0, &res);
1117
1118		i = *((unsigned char *)res.buffer);
1119		mux = 0;
1120		while (i >>= 1) {
1121			mux++;
1122		}
1123
1124		UHSO_DPRINTF(3, "mux port %d (%d)\n", mux, i);
1125		if (mux > UHSO_MPORT_TYPE_NOMAX)
1126			break;
1127
1128		/* Issue a read for this serial port */
1129		usbd_xfer_set_priv(
1130		    sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ],
1131		    &sc->sc_tty[mux]);
1132		usbd_transfer_start(sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ]);
1133
1134		break;
1135	case USB_ST_SETUP:
1136tr_setup:
1137		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
1138		usbd_transfer_submit(xfer);
1139		break;
1140	default:
1141		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
1142		if (error == USB_ERR_CANCELLED)
1143			break;
1144
1145		usbd_xfer_set_stall(xfer);
1146		goto tr_setup;
1147	}
1148}
1149
1150static void
1151uhso_mux_read_callback(struct usb_xfer *xfer, usb_error_t error)
1152{
1153	struct uhso_softc *sc = usbd_xfer_softc(xfer);
1154	struct usb_page_cache *pc;
1155	struct usb_device_request req;
1156	struct uhso_tty *ht;
1157	int actlen, len;
1158
1159	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
1160
1161	UHSO_DPRINTF(3, "status %d\n", USB_GET_STATE(xfer));
1162
1163	ht = usbd_xfer_get_priv(xfer);
1164	UHSO_DPRINTF(3, "ht=%p open=%d\n", ht, ht->ht_open);
1165
1166	switch (USB_GET_STATE(xfer)) {
1167	case USB_ST_TRANSFERRED:
1168		/* Got data, send to ucom */
1169		pc = usbd_xfer_get_frame(xfer, 1);
1170		len = usbd_xfer_frame_len(xfer, 1);
1171
1172		UHSO_DPRINTF(3, "got %d bytes on mux port %d\n", len,
1173		    ht->ht_muxport);
1174		if (len <= 0) {
1175			usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
1176			break;
1177		}
1178
1179		/* Deliver data if the TTY is open, discard otherwise */
1180		if (ht->ht_open)
1181			ucom_put_data(&sc->sc_ucom[ht->ht_muxport], pc, 0, len);
1182		/* FALLTHROUGH */
1183	case USB_ST_SETUP:
1184tr_setup:
1185		memset(&req, 0, sizeof(struct usb_device_request));
1186		req.bmRequestType = UT_READ_CLASS_INTERFACE;
1187		req.bRequest = UCDC_GET_ENCAPSULATED_RESPONSE;
1188		USETW(req.wValue, 0);
1189		USETW(req.wIndex, ht->ht_muxport);
1190		USETW(req.wLength, 1024);
1191
1192		pc = usbd_xfer_get_frame(xfer, 0);
1193		usbd_copy_in(pc, 0, &req, sizeof(req));
1194
1195		usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
1196		usbd_xfer_set_frame_len(xfer, 1, 1024);
1197		usbd_xfer_set_frames(xfer, 2);
1198		usbd_transfer_submit(xfer);
1199		break;
1200	default:
1201		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
1202		if (error == USB_ERR_CANCELLED)
1203			break;
1204		usbd_xfer_set_stall(xfer);
1205		goto tr_setup;
1206	}
1207}
1208
1209static void
1210uhso_mux_write_callback(struct usb_xfer *xfer, usb_error_t error)
1211{
1212	struct uhso_softc *sc = usbd_xfer_softc(xfer);
1213	struct uhso_tty *ht;
1214	struct usb_page_cache *pc;
1215	struct usb_device_request req;
1216	int actlen;
1217	struct usb_page_search res;
1218
1219	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
1220
1221	ht = usbd_xfer_get_priv(xfer);
1222	UHSO_DPRINTF(3, "status=%d, using mux port %d\n",
1223	    USB_GET_STATE(xfer), ht->ht_muxport);
1224
1225	switch (USB_GET_STATE(xfer)) {
1226	case USB_ST_TRANSFERRED:
1227		UHSO_DPRINTF(3, "wrote %zd data bytes to muxport %d\n",
1228		    actlen - sizeof(struct usb_device_request) ,
1229		    ht->ht_muxport);
1230		/* FALLTHROUGH */
1231	case USB_ST_SETUP:
1232tr_setup:
1233		pc = usbd_xfer_get_frame(xfer, 1);
1234		if (ucom_get_data(&sc->sc_ucom[ht->ht_muxport], pc,
1235		    0, 32, &actlen)) {
1236			usbd_get_page(pc, 0, &res);
1237
1238			memset(&req, 0, sizeof(struct usb_device_request));
1239			req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
1240			req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND;
1241			USETW(req.wValue, 0);
1242			USETW(req.wIndex, ht->ht_muxport);
1243			USETW(req.wLength, actlen);
1244
1245			pc = usbd_xfer_get_frame(xfer, 0);
1246			usbd_copy_in(pc, 0, &req, sizeof(req));
1247
1248			usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
1249			usbd_xfer_set_frame_len(xfer, 1, actlen);
1250			usbd_xfer_set_frames(xfer, 2);
1251
1252			UHSO_DPRINTF(3, "Prepared %d bytes for transmit "
1253			    "on muxport %d\n", actlen, ht->ht_muxport);
1254
1255			usbd_transfer_submit(xfer);
1256		}
1257		break;
1258	default:
1259		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
1260		if (error == USB_ERR_CANCELLED)
1261			break;
1262		usbd_xfer_set_stall(xfer);
1263		goto tr_setup;
1264	}
1265}
1266
1267static int
1268uhso_attach_bulkserial(struct uhso_softc *sc, struct usb_interface *iface,
1269    int type)
1270{
1271	usb_error_t uerr;
1272	int tty;
1273
1274	/* Try attaching RD/WR/INTR first */
1275	uerr = usbd_transfer_setup(sc->sc_udev,
1276	    &iface->idesc->bInterfaceNumber, sc->sc_xfer,
1277	    uhso_bs_config, UHSO_BULK_ENDPT_MAX, sc, &sc->sc_mtx);
1278	if (uerr) {
1279		/* Try only RD/WR */
1280		uerr = usbd_transfer_setup(sc->sc_udev,
1281		    &iface->idesc->bInterfaceNumber, sc->sc_xfer,
1282		    uhso_bs_config, UHSO_BULK_ENDPT_MAX - 1, sc, &sc->sc_mtx);
1283	}
1284	if (uerr) {
1285		UHSO_DPRINTF(0, "usbd_transfer_setup failed");
1286		return (-1);
1287	}
1288
1289	tty = uhso_alloc_tty(sc);
1290	if (tty < 0) {
1291		usbd_transfer_unsetup(sc->sc_xfer, UHSO_BULK_ENDPT_MAX);
1292		return (ENOMEM);
1293	}
1294
1295	sc->sc_tty[tty].ht_muxport = -1;
1296	return (0);
1297}
1298
1299static void
1300uhso_bs_read_callback(struct usb_xfer *xfer, usb_error_t error)
1301{
1302	struct uhso_softc *sc = usbd_xfer_softc(xfer);
1303	struct usb_page_cache *pc;
1304	int actlen;
1305
1306	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
1307
1308	UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
1309
1310	switch (USB_GET_STATE(xfer)) {
1311	case USB_ST_TRANSFERRED:
1312		pc = usbd_xfer_get_frame(xfer, 0);
1313		ucom_put_data(&sc->sc_ucom[0], pc, 0, actlen);
1314		/* FALLTHROUGH */
1315	case USB_ST_SETUP:
1316tr_setup:
1317		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
1318		usbd_transfer_submit(xfer);
1319	break;
1320	default:
1321		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
1322		if (error == USB_ERR_CANCELLED)
1323			break;
1324		usbd_xfer_set_stall(xfer);
1325		goto tr_setup;
1326	}
1327}
1328
1329static void
1330uhso_bs_write_callback(struct usb_xfer *xfer, usb_error_t error)
1331{
1332	struct uhso_softc *sc = usbd_xfer_softc(xfer);
1333	struct usb_page_cache *pc;
1334	int actlen;
1335
1336	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
1337
1338	UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
1339
1340	switch (USB_GET_STATE(xfer)) {
1341	case USB_ST_TRANSFERRED:
1342	case USB_ST_SETUP:
1343tr_setup:
1344		pc = usbd_xfer_get_frame(xfer, 0);
1345		if (ucom_get_data(&sc->sc_ucom[0], pc, 0, 8192, &actlen)) {
1346			usbd_xfer_set_frame_len(xfer, 0, actlen);
1347			usbd_transfer_submit(xfer);
1348		}
1349		break;
1350	break;
1351	default:
1352		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
1353		if (error == USB_ERR_CANCELLED)
1354			break;
1355		usbd_xfer_set_stall(xfer);
1356		goto tr_setup;
1357	}
1358}
1359
1360static void
1361uhso_bs_cfg(struct uhso_softc *sc)
1362{
1363	struct usb_device_request req;
1364	usb_error_t uerr;
1365
1366	if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK))
1367		return;
1368
1369	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
1370	req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
1371	USETW(req.wValue, sc->sc_line);
1372	USETW(req.wIndex, sc->sc_iface_no);
1373	USETW(req.wLength, 0);
1374
1375	uerr = ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom[0], &req, NULL, 0, 1000);
1376	if (uerr != 0) {
1377		device_printf(sc->sc_dev, "failed to set ctrl line state to "
1378		    "0x%02x: %s\n", sc->sc_line, usbd_errstr(uerr));
1379	}
1380}
1381
1382static void
1383uhso_bs_intr_callback(struct usb_xfer *xfer, usb_error_t error)
1384{
1385	struct uhso_softc *sc = usbd_xfer_softc(xfer);
1386	struct usb_page_cache *pc;
1387	int actlen;
1388	struct usb_cdc_notification cdc;
1389
1390	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
1391	UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
1392
1393	switch (USB_GET_STATE(xfer)) {
1394	case USB_ST_TRANSFERRED:
1395		if (actlen < UCDC_NOTIFICATION_LENGTH) {
1396			UHSO_DPRINTF(0, "UCDC notification too short: %d\n", actlen);
1397			goto tr_setup;
1398		}
1399		else if (actlen > (int)sizeof(struct usb_cdc_notification)) {
1400			UHSO_DPRINTF(0, "UCDC notification too large: %d\n", actlen);
1401			actlen = sizeof(struct usb_cdc_notification);
1402		}
1403
1404		pc = usbd_xfer_get_frame(xfer, 0);
1405		usbd_copy_out(pc, 0, &cdc, actlen);
1406
1407		if (UGETW(cdc.wIndex) != sc->sc_iface_no) {
1408			UHSO_DPRINTF(0, "Interface mismatch, got %d expected %d\n",
1409			    UGETW(cdc.wIndex), sc->sc_iface_no);
1410			goto tr_setup;
1411		}
1412
1413		if (cdc.bmRequestType == UCDC_NOTIFICATION &&
1414		    cdc.bNotification == UCDC_N_SERIAL_STATE) {
1415			UHSO_DPRINTF(2, "notify = 0x%02x\n", cdc.data[0]);
1416
1417			sc->sc_msr = 0;
1418			sc->sc_lsr = 0;
1419			if (cdc.data[0] & UCDC_N_SERIAL_RI)
1420				sc->sc_msr |= SER_RI;
1421			if (cdc.data[0] & UCDC_N_SERIAL_DSR)
1422				sc->sc_msr |= SER_DSR;
1423			if (cdc.data[0] & UCDC_N_SERIAL_DCD)
1424				sc->sc_msr |= SER_DCD;
1425
1426			ucom_status_change(&sc->sc_ucom[0]);
1427		}
1428	case USB_ST_SETUP:
1429tr_setup:
1430	default:
1431		if (error == USB_ERR_CANCELLED)
1432			break;
1433		usbd_xfer_set_stall(xfer);
1434		goto tr_setup;
1435	}
1436}
1437
1438static void
1439uhso_ucom_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr)
1440{
1441	struct uhso_softc *sc = ucom->sc_parent;
1442
1443	*lsr = sc->sc_lsr;
1444	*msr = sc->sc_msr;
1445}
1446
1447static void
1448uhso_ucom_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff)
1449{
1450	struct uhso_softc *sc = ucom->sc_parent;
1451
1452	if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK))
1453		return;
1454
1455	if (onoff)
1456		sc->sc_line |= UCDC_LINE_DTR;
1457	else
1458		sc->sc_line &= ~UCDC_LINE_DTR;
1459
1460	uhso_bs_cfg(sc);
1461}
1462
1463static void
1464uhso_ucom_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff)
1465{
1466	struct uhso_softc *sc = ucom->sc_parent;
1467
1468	if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK))
1469		return;
1470
1471	if (onoff)
1472		sc->sc_line |= UCDC_LINE_RTS;
1473	else
1474		sc->sc_line &= ~UCDC_LINE_RTS;
1475
1476	uhso_bs_cfg(sc);
1477}
1478
1479static void
1480uhso_ucom_start_read(struct ucom_softc *ucom)
1481{
1482	struct uhso_softc *sc = ucom->sc_parent;
1483
1484	UHSO_DPRINTF(3, "unit=%d, subunit=%d\n",
1485	    ucom->sc_super->sc_unit, ucom->sc_subunit);
1486
1487	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
1488		sc->sc_tty[ucom->sc_subunit].ht_open = 1;
1489		usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
1490	}
1491	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
1492		sc->sc_tty[0].ht_open = 1;
1493		usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]);
1494		if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL)
1495			usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]);
1496	}
1497}
1498
1499static void
1500uhso_ucom_stop_read(struct ucom_softc *ucom)
1501{
1502
1503	struct uhso_softc *sc = ucom->sc_parent;
1504
1505	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
1506		sc->sc_tty[ucom->sc_subunit].ht_open = 0;
1507		usbd_transfer_stop(
1508		    sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_READ]);
1509	}
1510	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
1511		sc->sc_tty[0].ht_open = 0;
1512		usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]);
1513		if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL)
1514			usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]);
1515	}
1516}
1517
1518static void
1519uhso_ucom_start_write(struct ucom_softc *ucom)
1520{
1521	struct uhso_softc *sc = ucom->sc_parent;
1522
1523	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
1524		UHSO_DPRINTF(3, "local unit %d\n", ucom->sc_subunit);
1525
1526		usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
1527
1528		usbd_xfer_set_priv(
1529		    sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE],
1530		    &sc->sc_tty[ucom->sc_subunit]);
1531		usbd_transfer_start(
1532		    sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]);
1533	}
1534	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
1535		usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]);
1536	}
1537}
1538
1539static void
1540uhso_ucom_stop_write(struct ucom_softc *ucom)
1541{
1542	struct uhso_softc *sc = ucom->sc_parent;
1543
1544	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
1545		usbd_transfer_stop(
1546		    sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]);
1547	}
1548	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
1549		usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]);
1550	}
1551}
1552
1553static int
1554uhso_attach_ifnet(struct uhso_softc *sc, struct usb_interface *iface, int type)
1555{
1556	struct ifnet *ifp;
1557	usb_error_t uerr;
1558	struct sysctl_ctx_list *sctx;
1559	struct sysctl_oid *soid;
1560	unsigned int devunit;
1561
1562	uerr = usbd_transfer_setup(sc->sc_udev,
1563	    &iface->idesc->bInterfaceNumber, sc->sc_if_xfer,
1564	    uhso_ifnet_config, UHSO_IFNET_MAX, sc, &sc->sc_mtx);
1565	if (uerr) {
1566		UHSO_DPRINTF(0, "usbd_transfer_setup failed: %s\n",
1567		    usbd_errstr(uerr));
1568		return (-1);
1569	}
1570
1571	sc->sc_ifp = ifp = if_alloc(IFT_OTHER);
1572	if (sc->sc_ifp == NULL) {
1573		device_printf(sc->sc_dev, "if_alloc() failed\n");
1574		return (-1);
1575	}
1576
1577	callout_init_mtx(&sc->sc_c, &sc->sc_mtx, 0);
1578	mtx_lock(&sc->sc_mtx);
1579	callout_reset(&sc->sc_c, 1, uhso_if_rxflush, sc);
1580	mtx_unlock(&sc->sc_mtx);
1581
1582	/*
1583	 * We create our own unit numbers for ifnet devices because the
1584	 * USB interface unit numbers can be at arbitrary positions yielding
1585	 * odd looking device names.
1586	 */
1587	devunit = alloc_unr(uhso_ifnet_unit);
1588
1589	if_initname(ifp, device_get_name(sc->sc_dev), devunit);
1590	ifp->if_mtu = UHSO_MAX_MTU;
1591	ifp->if_ioctl = uhso_if_ioctl;
1592	ifp->if_init = uhso_if_init;
1593	ifp->if_start = uhso_if_start;
1594	ifp->if_output = uhso_if_output;
1595	ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOARP;
1596	ifp->if_softc = sc;
1597	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
1598	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
1599	IFQ_SET_READY(&ifp->if_snd);
1600
1601	if_attach(ifp);
1602	bpfattach(ifp, DLT_RAW, 0);
1603
1604	sctx = device_get_sysctl_ctx(sc->sc_dev);
1605	soid = device_get_sysctl_tree(sc->sc_dev);
1606	/* Unlocked read... */
1607	SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "netif",
1608	    CTLFLAG_RD, ifp->if_xname, 0, "Attached network interface");
1609
1610	return (0);
1611}
1612
1613static void
1614uhso_ifnet_read_callback(struct usb_xfer *xfer, usb_error_t error)
1615{
1616	struct uhso_softc *sc = usbd_xfer_softc(xfer);
1617	struct mbuf *m;
1618	struct usb_page_cache *pc;
1619	int actlen;
1620
1621	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
1622
1623	UHSO_DPRINTF(3, "status=%d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
1624
1625	switch (USB_GET_STATE(xfer)) {
1626	case USB_ST_TRANSFERRED:
1627		if (actlen > 0 && (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1628			pc = usbd_xfer_get_frame(xfer, 0);
1629			if (mbufq_full(&sc->sc_rxq))
1630				break;
1631			m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1632			usbd_copy_out(pc, 0, mtod(m, uint8_t *), actlen);
1633			m->m_pkthdr.len = m->m_len = actlen;
1634			/* Enqueue frame for further processing */
1635			mbufq_enqueue(&sc->sc_rxq, m);
1636			if (!callout_pending(&sc->sc_c) ||
1637			    !callout_active(&sc->sc_c)) {
1638				callout_schedule(&sc->sc_c, 1);
1639			}
1640		}
1641	/* FALLTHROUGH */
1642	case USB_ST_SETUP:
1643tr_setup:
1644		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
1645		usbd_transfer_submit(xfer);
1646		break;
1647	default:
1648		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
1649		if (error == USB_ERR_CANCELLED)
1650			break;
1651		usbd_xfer_set_stall(xfer);
1652		goto tr_setup;
1653	}
1654}
1655
1656/*
1657 * Deferred RX processing, called with mutex locked.
1658 *
1659 * Each frame we receive might contain several small ip-packets as well
1660 * as partial ip-packets. We need to separate/assemble them into individual
1661 * packets before sending them to the ip-layer.
1662 */
1663static void
1664uhso_if_rxflush(void *arg)
1665{
1666	struct epoch_tracker et;
1667	struct uhso_softc *sc = arg;
1668	struct ifnet *ifp = sc->sc_ifp;
1669	uint8_t *cp;
1670	struct mbuf *m, *m0, *mwait;
1671	struct ip *ip;
1672#ifdef INET6
1673	struct ip6_hdr *ip6;
1674#endif
1675	uint16_t iplen;
1676	int isr;
1677
1678	m = NULL;
1679	mwait = sc->sc_mwait;
1680	NET_EPOCH_ENTER(et);
1681	for (;;) {
1682		if (m == NULL) {
1683			if ((m = mbufq_dequeue(&sc->sc_rxq)) == NULL)
1684				break;
1685			UHSO_DPRINTF(3, "dequeue m=%p, len=%d\n", m, m->m_len);
1686		}
1687		mtx_unlock(&sc->sc_mtx);
1688
1689		/* Do we have a partial packet waiting? */
1690		if (mwait != NULL) {
1691			m0 = mwait;
1692			mwait = NULL;
1693
1694			UHSO_DPRINTF(3, "partial m0=%p(%d), concat w/ m=%p(%d)\n",
1695			    m0, m0->m_len, m, m->m_len);
1696
1697			m_catpkt(m0, m);
1698			m = m_pullup(m0, sizeof(struct ip));
1699			if (m == NULL) {
1700				if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
1701				UHSO_DPRINTF(0, "m_pullup failed\n");
1702				mtx_lock(&sc->sc_mtx);
1703				continue;
1704			}
1705			UHSO_DPRINTF(3, "Constructed mbuf=%p, len=%d\n",
1706			    m, m->m_pkthdr.len);
1707		}
1708
1709		cp = mtod(m, uint8_t *);
1710		ip = (struct ip *)cp;
1711#ifdef INET6
1712		ip6 = (struct ip6_hdr *)cp;
1713#endif
1714
1715		/* Check for IPv4 */
1716		if (ip->ip_v == IPVERSION) {
1717			iplen = htons(ip->ip_len);
1718			isr = NETISR_IP;
1719		}
1720#ifdef INET6
1721		/* Check for IPv6 */
1722		else if ((ip6->ip6_vfc & IPV6_VERSION_MASK) == IPV6_VERSION) {
1723			iplen = htons(ip6->ip6_plen);
1724			isr = NETISR_IPV6;
1725		}
1726#endif
1727		else {
1728			UHSO_DPRINTF(0, "got unexpected ip version %d, "
1729			    "m=%p, len=%d\n", (*cp & 0xf0) >> 4, m, m->m_len);
1730			if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
1731			UHSO_HEXDUMP(cp, 4);
1732			m_freem(m);
1733			m = NULL;
1734			mtx_lock(&sc->sc_mtx);
1735			continue;
1736		}
1737
1738		if (iplen == 0) {
1739			UHSO_DPRINTF(0, "Zero IP length\n");
1740			if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
1741			m_freem(m);
1742			m = NULL;
1743			mtx_lock(&sc->sc_mtx);
1744			continue;
1745		}
1746
1747		UHSO_DPRINTF(3, "m=%p, len=%d, cp=%p, iplen=%d\n",
1748		    m, m->m_pkthdr.len, cp, iplen);
1749
1750		m0 = NULL;
1751
1752		/* More IP packets in this mbuf */
1753		if (iplen < m->m_pkthdr.len) {
1754			m0 = m;
1755
1756			/*
1757			 * Allocate a new mbuf for this IP packet and
1758			 * copy the IP-packet into it.
1759			 */
1760			m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR);
1761			memcpy(mtod(m, uint8_t *), mtod(m0, uint8_t *), iplen);
1762			m->m_pkthdr.len = m->m_len = iplen;
1763
1764			/* Adjust the size of the original mbuf */
1765			m_adj(m0, iplen);
1766			m0 = m_defrag(m0, M_WAITOK);
1767
1768			UHSO_DPRINTF(3, "New mbuf=%p, len=%d/%d, m0=%p, "
1769			    "m0_len=%d/%d\n", m, m->m_pkthdr.len, m->m_len,
1770			    m0, m0->m_pkthdr.len, m0->m_len);
1771		}
1772		else if (iplen > m->m_pkthdr.len) {
1773			UHSO_DPRINTF(3, "Deferred mbuf=%p, len=%d\n",
1774			    m, m->m_pkthdr.len);
1775			mwait = m;
1776			m = NULL;
1777			mtx_lock(&sc->sc_mtx);
1778			continue;
1779		}
1780
1781		if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
1782		m->m_pkthdr.rcvif = ifp;
1783
1784		/* Dispatch to IP layer */
1785		BPF_MTAP(sc->sc_ifp, m);
1786		M_SETFIB(m, ifp->if_fib);
1787		netisr_dispatch(isr, m);
1788		m = m0 != NULL ? m0 : NULL;
1789		mtx_lock(&sc->sc_mtx);
1790	}
1791	NET_EPOCH_EXIT(et);
1792	sc->sc_mwait = mwait;
1793}
1794
1795static void
1796uhso_ifnet_write_callback(struct usb_xfer *xfer, usb_error_t error)
1797{
1798	struct uhso_softc *sc = usbd_xfer_softc(xfer);
1799	struct ifnet *ifp = sc->sc_ifp;
1800	struct usb_page_cache *pc;
1801	struct mbuf *m;
1802	int actlen;
1803
1804	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
1805
1806	UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
1807
1808	switch (USB_GET_STATE(xfer)) {
1809	case USB_ST_TRANSFERRED:
1810		if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
1811		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1812	case USB_ST_SETUP:
1813tr_setup:
1814		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1815		if (m == NULL)
1816			break;
1817
1818		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1819
1820		if (m->m_pkthdr.len > MCLBYTES)
1821			m->m_pkthdr.len = MCLBYTES;
1822
1823		usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len);
1824		pc = usbd_xfer_get_frame(xfer, 0);
1825		usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len);
1826		usbd_transfer_submit(xfer);
1827
1828		BPF_MTAP(ifp, m);
1829		m_freem(m);
1830		break;
1831	default:
1832		UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error));
1833		if (error == USB_ERR_CANCELLED)
1834			break;
1835		usbd_xfer_set_stall(xfer);
1836		goto tr_setup;
1837	}
1838}
1839
1840static int
1841uhso_if_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1842{
1843	struct uhso_softc *sc;
1844
1845	sc = ifp->if_softc;
1846
1847	switch (cmd) {
1848	case SIOCSIFFLAGS:
1849		if (ifp->if_flags & IFF_UP) {
1850			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1851				uhso_if_init(sc);
1852			}
1853		}
1854		else {
1855			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1856				mtx_lock(&sc->sc_mtx);
1857				uhso_if_stop(sc);
1858				mtx_unlock(&sc->sc_mtx);
1859			}
1860		}
1861		break;
1862	case SIOCSIFADDR:
1863	case SIOCADDMULTI:
1864	case SIOCDELMULTI:
1865		break;
1866	default:
1867		return (EINVAL);
1868	}
1869	return (0);
1870}
1871
1872static void
1873uhso_if_init(void *priv)
1874{
1875	struct uhso_softc *sc = priv;
1876	struct ifnet *ifp = sc->sc_ifp;
1877
1878	mtx_lock(&sc->sc_mtx);
1879	uhso_if_stop(sc);
1880	ifp = sc->sc_ifp;
1881	ifp->if_flags |= IFF_UP;
1882	ifp->if_drv_flags |= IFF_DRV_RUNNING;
1883	mtx_unlock(&sc->sc_mtx);
1884
1885	UHSO_DPRINTF(2, "ifnet initialized\n");
1886}
1887
1888static int
1889uhso_if_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,
1890    struct route *ro)
1891{
1892	int error;
1893
1894	/* Only IPv4/6 support */
1895	if (dst->sa_family != AF_INET
1896#ifdef INET6
1897	   && dst->sa_family != AF_INET6
1898#endif
1899	 ) {
1900		return (EAFNOSUPPORT);
1901	}
1902
1903	error = (ifp->if_transmit)(ifp, m0);
1904	if (error) {
1905		if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1906		return (ENOBUFS);
1907	}
1908	if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
1909	return (0);
1910}
1911
1912static void
1913uhso_if_start(struct ifnet *ifp)
1914{
1915	struct uhso_softc *sc = ifp->if_softc;
1916
1917	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1918		UHSO_DPRINTF(1, "Not running\n");
1919		return;
1920	}
1921
1922	mtx_lock(&sc->sc_mtx);
1923	usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_READ]);
1924	usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_WRITE]);
1925	mtx_unlock(&sc->sc_mtx);
1926	UHSO_DPRINTF(3, "interface started\n");
1927}
1928
1929static void
1930uhso_if_stop(struct uhso_softc *sc)
1931{
1932
1933	usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_READ]);
1934	usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_WRITE]);
1935	sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1936}
1937