FreeBSD kernel usb device Code
umcs.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2010 Lev Serebryakov <lev@FreeBSD.org>.
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 AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29/*
30 * This driver supports several multiport USB-to-RS232 serial adapters driven
31 * by MosChip mos7820 and mos7840, bridge chips.
32 * The adapters are sold under many different brand names.
33 *
34 * Datasheets are available at MosChip www site at
35 * http://www.moschip.com. The datasheets don't contain full
36 * programming information for the chip.
37 *
38 * It is nornal to have only two enabled ports in devices, based on
39 * quad-port mos7840.
40 *
41 */
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD$");
44
45#include <sys/stdint.h>
46#include <sys/stddef.h>
47#include <sys/param.h>
48#include <sys/queue.h>
49#include <sys/types.h>
50#include <sys/systm.h>
51#include <sys/kernel.h>
52#include <sys/bus.h>
53#include <sys/linker_set.h>
54#include <sys/module.h>
55#include <sys/lock.h>
56#include <sys/mutex.h>
57#include <sys/condvar.h>
58#include <sys/sysctl.h>
59#include <sys/sx.h>
60#include <sys/unistd.h>
61#include <sys/callout.h>
62#include <sys/malloc.h>
63#include <sys/priv.h>
64
65#include <dev/usb/usb.h>
66#include <dev/usb/usbdi.h>
67#include <dev/usb/usbdi_util.h>
68#include <dev/usb/usb_cdc.h>
69#include "usbdevs.h"
70
71#define USB_DEBUG_VAR umcs_debug
72#include <dev/usb/usb_debug.h>
73#include <dev/usb/usb_process.h>
74
76
77#include <dev/usb/serial/umcs.h>
78
79#define UMCS7840_MODVER 1
80
81#ifdef USB_DEBUG
82static int umcs_debug = 0;
83
84static SYSCTL_NODE(_hw_usb, OID_AUTO, umcs, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
85 "USB umcs quadport serial adapter");
86SYSCTL_INT(_hw_usb_umcs, OID_AUTO, debug, CTLFLAG_RWTUN, &umcs_debug, 0, "Debug level");
87#endif /* USB_DEBUG */
88
89/*
90 * Two-port devices (both with 7820 chip and 7840 chip configured as two-port)
91 * have ports 0 and 2, with ports 1 and 3 omitted.
92 * So,PHYSICAL port numbers (indexes) on two-port device will be 0 and 2.
93 * This driver trys to use physical numbers as much as possible.
94 */
95
96/*
97 * Indexed by PHYSICAL port number.
98 * Pack non-regular registers to array to easier if-less access.
99 */
101 uint8_t reg_sp; /* SP register. */
102 uint8_t reg_control; /* CONTROL register. */
103 uint8_t reg_dcr; /* DCR0 register. DCR1 & DCR2 can be
104 * calculated */
105};
106
109 {.reg_sp = MCS7840_DEV_REG_SP2,.reg_control = MCS7840_DEV_REG_CONTROL2,.reg_dcr = MCS7840_DEV_REG_DCR0_2},
110 {.reg_sp = MCS7840_DEV_REG_SP3,.reg_control = MCS7840_DEV_REG_CONTROL3,.reg_dcr = MCS7840_DEV_REG_DCR0_3},
111 {.reg_sp = MCS7840_DEV_REG_SP4,.reg_control = MCS7840_DEV_REG_CONTROL4,.reg_dcr = MCS7840_DEV_REG_DCR0_4},
112};
113
114enum {
119
121 struct usb_xfer *sc_xfer[UMCS7840_N_TRANSFERS]; /* Control structures
122 * for two transfers */
123
124 uint8_t sc_lcr; /* local line control register */
125 uint8_t sc_mcr; /* local modem control register */
126};
127
130 struct ucom_softc sc_ucom[UMCS7840_MAX_PORTS]; /* Need to be continuous
131 * array, so indexed by
132 * LOGICAL port
133 * (subunit) number */
134
135 struct usb_xfer *sc_intr_xfer; /* Interrupt endpoint */
136
137 device_t sc_dev; /* Device for error prints */
138 struct usb_device *sc_udev; /* USB Device for all operations */
139 struct mtx sc_mtx; /* ucom requires this */
140
141 uint8_t sc_driver_done; /* Flag when enumeration is finished */
142
143 uint8_t sc_numports; /* Number of ports (subunits) */
144 struct umcs7840_softc_oneport sc_ports[UMCS7840_MAX_PORTS]; /* Indexed by PHYSICAL
145 * port number. */
146};
147
148/* prototypes */
149static usb_error_t umcs7840_get_reg_sync(struct umcs7840_softc *, uint8_t, uint8_t *);
150static usb_error_t umcs7840_set_reg_sync(struct umcs7840_softc *, uint8_t, uint8_t);
151static usb_error_t umcs7840_get_UART_reg_sync(struct umcs7840_softc *, uint8_t, uint8_t, uint8_t *);
152static usb_error_t umcs7840_set_UART_reg_sync(struct umcs7840_softc *, uint8_t, uint8_t, uint8_t);
153
154static usb_error_t umcs7840_set_baudrate(struct umcs7840_softc *, uint8_t, uint32_t);
155static usb_error_t umcs7840_calc_baudrate(uint32_t rate, uint16_t *, uint8_t *);
156
157static void umcs7840_free(struct ucom_softc *);
158static void umcs7840_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *);
159static void umcs7840_cfg_set_dtr(struct ucom_softc *, uint8_t);
160static void umcs7840_cfg_set_rts(struct ucom_softc *, uint8_t);
161static void umcs7840_cfg_set_break(struct ucom_softc *, uint8_t);
162static void umcs7840_cfg_param(struct ucom_softc *, struct termios *);
163static void umcs7840_cfg_open(struct ucom_softc *);
164static void umcs7840_cfg_close(struct ucom_softc *);
165
166static int umcs7840_pre_param(struct ucom_softc *, struct termios *);
167
168static void umcs7840_start_read(struct ucom_softc *);
169static void umcs7840_stop_read(struct ucom_softc *);
170
171static void umcs7840_start_write(struct ucom_softc *);
172static void umcs7840_stop_write(struct ucom_softc *);
173
174static void umcs7840_poll(struct ucom_softc *ucom);
175
176static device_probe_t umcs7840_probe;
177static device_attach_t umcs7840_attach;
178static device_detach_t umcs7840_detach;
179static void umcs7840_free_softc(struct umcs7840_softc *);
180
190
191static void umcs7840_read_callbackN(struct usb_xfer *, usb_error_t, uint8_t);
192static void umcs7840_write_callbackN(struct usb_xfer *, usb_error_t, uint8_t);
193
194/* Indexed by LOGICAL port number (subunit), so two-port device uses 0 & 1 */
200};
201
204 .type = UE_BULK,
205 .endpoint = 0x01,
206 .direction = UE_DIR_IN,
207 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
208 .bufsize = 0, /* use wMaxPacketSize */
209 .callback = &umcs7840_read_callback1,
210 .if_index = 0,
211 },
212
214 .type = UE_BULK,
215 .endpoint = 0x02,
216 .direction = UE_DIR_OUT,
217 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
218 .bufsize = 0, /* use wMaxPacketSize */
219 .callback = &umcs7840_write_callback1,
220 .if_index = 0,
221 },
222};
223
224static const struct usb_config umcs7840_intr_config_data[1] = {
225 [0] = {
227 .endpoint = 0x09,
228 .direction = UE_DIR_IN,
229 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
230 .bufsize = 0, /* use wMaxPacketSize */
231 .callback = &umcs7840_intr_callback,
232 .if_index = 0,
233 },
234};
235
238
239 .ucom_cfg_set_dtr = &umcs7840_cfg_set_dtr,
240 .ucom_cfg_set_rts = &umcs7840_cfg_set_rts,
241 .ucom_cfg_set_break = &umcs7840_cfg_set_break,
242
243 .ucom_cfg_param = &umcs7840_cfg_param,
244 .ucom_cfg_open = &umcs7840_cfg_open,
245 .ucom_cfg_close = &umcs7840_cfg_close,
246
247 .ucom_pre_param = &umcs7840_pre_param,
248
249 .ucom_start_read = &umcs7840_start_read,
250 .ucom_stop_read = &umcs7840_stop_read,
251
252 .ucom_start_write = &umcs7840_start_write,
253 .ucom_stop_write = &umcs7840_stop_write,
254
255 .ucom_poll = &umcs7840_poll,
256 .ucom_free = &umcs7840_free,
257};
258
260 {USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7820, 0)},
261 {USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7840, 0)},
262};
263
264static device_method_t umcs7840_methods[] = {
265 DEVMETHOD(device_probe, umcs7840_probe),
266 DEVMETHOD(device_attach, umcs7840_attach),
267 DEVMETHOD(device_detach, umcs7840_detach),
268 DEVMETHOD_END
269};
270
271static devclass_t umcs7840_devclass;
272
273static driver_t umcs7840_driver = {
274 .name = "umcs7840",
275 .methods = umcs7840_methods,
276 .size = sizeof(struct umcs7840_softc),
277};
278
280MODULE_DEPEND(umcs7840, ucom, 1, 1, 1);
281MODULE_DEPEND(umcs7840, usb, 1, 1, 1);
284
285static int
286umcs7840_probe(device_t dev)
287{
288 struct usb_attach_arg *uaa = device_get_ivars(dev);
289
290 if (uaa->usb_mode != USB_MODE_HOST)
291 return (ENXIO);
293 return (ENXIO);
295 return (ENXIO);
296 return (usbd_lookup_id_by_uaa(umcs7840_devs, sizeof(umcs7840_devs), uaa));
297}
298
299static int
300umcs7840_attach(device_t dev)
301{
302 struct usb_config umcs7840_config_tmp[UMCS7840_N_TRANSFERS];
303 struct usb_attach_arg *uaa = device_get_ivars(dev);
304 struct umcs7840_softc *sc = device_get_softc(dev);
305
306 uint8_t iface_index = MCS7840_IFACE_INDEX;
307 int error;
308 int subunit;
309 int n;
310 uint8_t data;
311
312 for (n = 0; n < UMCS7840_N_TRANSFERS; ++n)
313 umcs7840_config_tmp[n] = umcs7840_bulk_config_data[n];
314
316 mtx_init(&sc->sc_mtx, "umcs7840", NULL, MTX_DEF);
318
319 sc->sc_dev = dev;
320 sc->sc_udev = uaa->device;
321
322 /*
323 * Get number of ports
324 * Documentation (full datasheet) says, that number of ports is
325 * set as MCS7840_DEV_MODE_SELECT24S bit in MODE R/Only
326 * register. But vendor driver uses these undocumented
327 * register & bit.
328 *
329 * Experiments show, that MODE register can have `0'
330 * (4 ports) bit on 2-port device, so use vendor driver's way.
331 *
332 * Also, see notes in header file for these constants.
333 */
336 sc->sc_numports = 4;
337 /* Store physical port numbers in sc_portno */
338 sc->sc_ucom[0].sc_portno = 0;
339 sc->sc_ucom[1].sc_portno = 1;
340 sc->sc_ucom[2].sc_portno = 2;
341 sc->sc_ucom[3].sc_portno = 3;
342 } else {
343 sc->sc_numports = 2;
344 /* Store physical port numbers in sc_portno */
345 sc->sc_ucom[0].sc_portno = 0;
346 sc->sc_ucom[1].sc_portno = 2; /* '1' is skipped */
347 }
348 device_printf(dev, "Chip mcs%04x, found %d active ports\n", uaa->info.idProduct, sc->sc_numports);
350 device_printf(dev, "On-die confguration: RST: active %s, HRD: %s, PLL: %s, POR: %s, Ports: %s, EEPROM write %s, IrDA is %savailable\n",
351 (data & MCS7840_DEV_MODE_RESET) ? "low" : "high",
352 (data & MCS7840_DEV_MODE_SER_PRSNT) ? "yes" : "no",
353 (data & MCS7840_DEV_MODE_PLLBYPASS) ? "bypassed" : "avail",
354 (data & MCS7840_DEV_MODE_PORBYPASS) ? "bypassed" : "avail",
355 (data & MCS7840_DEV_MODE_SELECT24S) ? "2" : "4",
356 (data & MCS7840_DEV_MODE_EEPROMWR) ? "enabled" : "disabled",
357 (data & MCS7840_DEV_MODE_IRDA) ? "" : "not ");
358 }
359 /* Setup all transfers */
360 for (subunit = 0; subunit < sc->sc_numports; ++subunit) {
361 for (n = 0; n < UMCS7840_N_TRANSFERS; ++n) {
362 /* Set endpoint address */
363 umcs7840_config_tmp[n].endpoint = umcs7840_bulk_config_data[n].endpoint + 2 * sc->sc_ucom[subunit].sc_portno;
364 umcs7840_config_tmp[n].callback = umcs7840_rw_callbacks[subunit][n];
365 }
367 &iface_index, sc->sc_ports[sc->sc_ucom[subunit].sc_portno].sc_xfer, umcs7840_config_tmp,
368 UMCS7840_N_TRANSFERS, sc, &sc->sc_mtx);
369 if (error) {
370 device_printf(dev, "allocating USB transfers failed for subunit %d of %d\n",
371 subunit + 1, sc->sc_numports);
372 goto detach;
373 }
374 }
376 &iface_index, &sc->sc_intr_xfer, umcs7840_intr_config_data,
377 1, sc, &sc->sc_mtx);
378 if (error) {
379 device_printf(dev, "allocating USB transfers failed for interrupt\n");
380 goto detach;
381 }
382 /* clear stall at first run */
383 mtx_lock(&sc->sc_mtx);
384 for (subunit = 0; subunit < sc->sc_numports; ++subunit) {
387 }
388 mtx_unlock(&sc->sc_mtx);
389
392 if (error)
393 goto detach;
394
396
397 return (0);
398
399detach:
401 return (ENXIO);
402}
403
404static int
405umcs7840_detach(device_t dev)
406{
407 struct umcs7840_softc *sc = device_get_softc(dev);
408 int subunit;
409
411
412 for (subunit = 0; subunit < sc->sc_numports; ++subunit)
415
416 device_claim_softc(dev);
417
419
420 return (0);
421}
422
424
425static void
427{
428 if (ucom_unref(&sc->sc_super_ucom)) {
429 mtx_destroy(&sc->sc_mtx);
430 device_free_softc(sc);
431 }
432}
433
434static void
436{
438}
439
440static void
442{
443 struct umcs7840_softc *sc = ucom->sc_parent;
444 uint16_t pn = ucom->sc_portno;
445 uint8_t data;
446
447 /* If it very first open, finish global configuration */
448 if (!sc->sc_driver_done) {
449 /*
450 * USB enumeration is finished, pass internal memory to FIFOs
451 * If it is done in the end of "attach", kernel panics.
452 */
454 return;
457 return;
458 sc->sc_driver_done = 1;
459 }
460 /* Toggle reset bit on-off */
462 return;
465 return;
466 data &= ~MCS7840_DEV_SPx_UART_RESET;
468 return;
469
470 /* Set RS-232 mode */
472 return;
473
474 /* Disable RX on time of initialization */
475 if (umcs7840_get_reg_sync(sc, umcs7840_port_registers[pn].reg_control, &data))
476 return;
478 if (umcs7840_set_reg_sync(sc, umcs7840_port_registers[pn].reg_control, data))
479 return;
480
481 /* Disable all interrupts */
483 return;
484
485 /* Reset FIFO -- documented */
487 return;
491 return;
492
493 /* Set 8 bit, no parity, 1 stop bit -- documented */
496 return;
497
498 /*
499 * Enable DTR/RTS on modem control, enable modem interrupts --
500 * documented
501 */
503 if (ucom->sc_tty == NULL || (ucom->sc_tty->t_termios.c_cflag & CNO_RTSDTR) == 0)
506 return;
507
508 /* Clearing Bulkin and Bulkout FIFO */
510 return;
513 return;
516 return;
517
518 /* Set speed 9600 */
519 if (umcs7840_set_baudrate(sc, pn, 9600))
520 return;
521
522 /* Finally enable all interrupts -- documented */
523 /*
524 * Copied from vendor driver, I don't know why we should read LCR
525 * here
526 */
528 return;
531 return;
532
533 /* Enable RX */
534 if (umcs7840_get_reg_sync(sc, umcs7840_port_registers[pn].reg_control, &data))
535 return;
536 data &= ~MCS7840_DEV_CONTROLx_RX_DISABLE;
537 if (umcs7840_set_reg_sync(sc, umcs7840_port_registers[pn].reg_control, data))
538 return;
539
540 DPRINTF("Port %d has been opened\n", pn);
541}
542
543static void
545{
546 struct umcs7840_softc *sc = ucom->sc_parent;
547 uint16_t pn = ucom->sc_portno;
548 uint8_t data;
549
550 umcs7840_stop_read(ucom);
552
555
556 /* Disable RX */
557 if (umcs7840_get_reg_sync(sc, umcs7840_port_registers[pn].reg_control, &data))
558 return;
560 if (umcs7840_set_reg_sync(sc, umcs7840_port_registers[pn].reg_control, data))
561 return;
562 DPRINTF("Port %d has been closed\n", pn);
563}
564
565static void
566umcs7840_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff)
567{
568 struct umcs7840_softc *sc = ucom->sc_parent;
569 uint8_t pn = ucom->sc_portno;
570
571 if (onoff)
573 else
574 sc->sc_ports[pn].sc_mcr &= ~MCS7840_UART_MCR_DTR;
575
577 DPRINTF("Port %d DTR set to: %s\n", pn, onoff ? "on" : "off");
578}
579
580static void
581umcs7840_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff)
582{
583 struct umcs7840_softc *sc = ucom->sc_parent;
584 uint8_t pn = ucom->sc_portno;
585
586 if (onoff)
588 else
589 sc->sc_ports[pn].sc_mcr &= ~MCS7840_UART_MCR_RTS;
590
592 DPRINTF("Port %d RTS set to: %s\n", pn, onoff ? "on" : "off");
593}
594
595static void
596umcs7840_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff)
597{
598 struct umcs7840_softc *sc = ucom->sc_parent;
599 uint8_t pn = ucom->sc_portno;
600
601 if (onoff)
603 else
604 sc->sc_ports[pn].sc_lcr &= ~MCS7840_UART_LCR_BREAK;
605
607 DPRINTF("Port %d BREAK set to: %s\n", pn, onoff ? "on" : "off");
608}
609
610static void
611umcs7840_cfg_param(struct ucom_softc *ucom, struct termios *t)
612{
613 struct umcs7840_softc *sc = ucom->sc_parent;
614 uint8_t pn = ucom->sc_portno;
615 uint8_t lcr = sc->sc_ports[pn].sc_lcr;
616 uint8_t mcr = sc->sc_ports[pn].sc_mcr;
617
618 DPRINTF("Port %d config:\n", pn);
619 if (t->c_cflag & CSTOPB) {
620 DPRINTF(" 2 stop bits\n");
622 } else {
624 DPRINTF(" 1 stop bit\n");
625 }
626
627 lcr &= ~MCS7840_UART_LCR_PARITYMASK;
628 if (t->c_cflag & PARENB) {
630 if (t->c_cflag & PARODD) {
632 DPRINTF(" parity on - odd\n");
633 } else {
635 DPRINTF(" parity on - even\n");
636 }
637 } else {
638 lcr &= ~MCS7840_UART_LCR_PARITYON;
639 DPRINTF(" parity off\n");
640 }
641
642 lcr &= ~MCS7840_UART_LCR_DATALENMASK;
643 switch (t->c_cflag & CSIZE) {
644 case CS5:
646 DPRINTF(" 5 bit\n");
647 break;
648 case CS6:
650 DPRINTF(" 6 bit\n");
651 break;
652 case CS7:
654 DPRINTF(" 7 bit\n");
655 break;
656 case CS8:
658 DPRINTF(" 8 bit\n");
659 break;
660 }
661
662 if (t->c_cflag & CRTSCTS) {
664 DPRINTF(" CTS/RTS\n");
665 } else
666 mcr &= ~MCS7840_UART_MCR_CTSRTS;
667
668 if (t->c_cflag & (CDTR_IFLOW | CDSR_OFLOW)) {
670 DPRINTF(" DTR/DSR\n");
671 } else
672 mcr &= ~MCS7840_UART_MCR_DTRDSR;
673
674 sc->sc_ports[pn].sc_lcr = lcr;
676 DPRINTF("Port %d LCR=%02x\n", pn, sc->sc_ports[pn].sc_lcr);
677
678 sc->sc_ports[pn].sc_mcr = mcr;
680 DPRINTF("Port %d MCR=%02x\n", pn, sc->sc_ports[pn].sc_mcr);
681
682 umcs7840_set_baudrate(sc, pn, t->c_ospeed);
683}
684
685static int
686umcs7840_pre_param(struct ucom_softc *ucom, struct termios *t)
687{
688 uint8_t clk;
689 uint16_t divisor;
690
691 if (umcs7840_calc_baudrate(t->c_ospeed, &divisor, &clk) || !divisor)
692 return (EINVAL);
693 return (0);
694}
695
696static void
698{
699 struct umcs7840_softc *sc = ucom->sc_parent;
700 uint8_t pn = ucom->sc_portno;
701
702 /* Start interrupt transfer */
704
705 /* Start read transfer */
707}
708
709static void
711{
712 struct umcs7840_softc *sc = ucom->sc_parent;
713 uint8_t pn = ucom->sc_portno;
714
715 /* Stop read transfer */
717}
718
719static void
721{
722 struct umcs7840_softc *sc = ucom->sc_parent;
723 uint8_t pn = ucom->sc_portno;
724
725 /* Start interrupt transfer */
727
728 /* Start write transfer */
730}
731
732static void
734{
735 struct umcs7840_softc *sc = ucom->sc_parent;
736 uint8_t pn = ucom->sc_portno;
737
738 /* Stop write transfer */
740}
741
742static void
743umcs7840_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr)
744{
745 struct umcs7840_softc *sc = ucom->sc_parent;
746 uint8_t pn = ucom->sc_portno;
747 uint8_t hw_msr = 0; /* local modem status register */
748
749 /*
750 * Read status registers. MSR bits need translation from ns16550 to
751 * SER_* values. LSR bits are ns16550 in hardware and ucom.
752 */
755
756 if (hw_msr & MCS7840_UART_MSR_NEGCTS)
757 *msr |= SER_CTS;
758
759 if (hw_msr & MCS7840_UART_MSR_NEGDCD)
760 *msr |= SER_DCD;
761
762 if (hw_msr & MCS7840_UART_MSR_NEGRI)
763 *msr |= SER_RI;
764
765 if (hw_msr & MCS7840_UART_MSR_NEGDSR)
766 *msr |= SER_DSR;
767
768 DPRINTF("Port %d status: LSR=%02x MSR=%02x\n", ucom->sc_portno, *lsr, *msr);
769}
770
771static void
773{
774 struct umcs7840_softc *sc = usbd_xfer_softc(xfer);
775 struct usb_page_cache *pc;
776 uint8_t buf[13];
777 int actlen;
778 int subunit;
779
780 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
781
782 switch (USB_GET_STATE(xfer)) {
784 if (actlen == 5 || actlen == 13) {
785 pc = usbd_xfer_get_frame(xfer, 0);
786 usbd_copy_out(pc, 0, buf, actlen);
787 /* Check status of all ports */
788 for (subunit = 0; subunit < sc->sc_numports; ++subunit) {
789 uint8_t pn = sc->sc_ucom[subunit].sc_portno;
790
791 if (buf[pn] & MCS7840_UART_ISR_NOPENDING)
792 continue;
793 DPRINTF("Port %d has pending interrupt: %02x (FIFO: %02x)\n", pn, buf[pn] & MCS7840_UART_ISR_INTMASK, buf[pn] & (~MCS7840_UART_ISR_INTMASK));
794 switch (buf[pn] & MCS7840_UART_ISR_INTMASK) {
799 ucom_status_change(&sc->sc_ucom[subunit]);
800 break;
801 default:
802 /* Do nothing */
803 break;
804 }
805 }
806 } else
807 device_printf(sc->sc_dev, "Invalid interrupt data length %d", actlen);
808 /* FALLTHROUGH */
809 case USB_ST_SETUP:
810tr_setup:
813 return;
814
815 default: /* Error */
816 if (error != USB_ERR_CANCELLED) {
817 /* try to clear stall first */
819 goto tr_setup;
820 }
821 return;
822 }
823}
824
825static void
827{
829}
830
831static void
833{
835}
836static void
838{
840}
841
842static void
844{
846}
847
848static void
849umcs7840_read_callbackN(struct usb_xfer *xfer, usb_error_t error, uint8_t subunit)
850{
851 struct umcs7840_softc *sc = usbd_xfer_softc(xfer);
852 struct ucom_softc *ucom = &sc->sc_ucom[subunit];
853 struct usb_page_cache *pc;
854 int actlen;
855
856 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
857
858 DPRINTF("Port %d read, state = %d, data length = %d\n", ucom->sc_portno, USB_GET_STATE(xfer), actlen);
859
860 switch (USB_GET_STATE(xfer)) {
862 pc = usbd_xfer_get_frame(xfer, 0);
863 ucom_put_data(ucom, pc, 0, actlen);
864 /* FALLTHROUGH */
865 case USB_ST_SETUP:
866tr_setup:
869 return;
870
871 default: /* Error */
872 if (error != USB_ERR_CANCELLED) {
873 /* try to clear stall first */
875 goto tr_setup;
876 }
877 return;
878 }
879}
880
881static void
883{
885}
886
887static void
889{
891}
892
893static void
895{
897}
898
899static void
901{
903}
904
905static void
906umcs7840_write_callbackN(struct usb_xfer *xfer, usb_error_t error, uint8_t subunit)
907{
908 struct umcs7840_softc *sc = usbd_xfer_softc(xfer);
909 struct ucom_softc *ucom = &sc->sc_ucom[subunit];
910 struct usb_page_cache *pc;
911 uint32_t actlen;
912
913 DPRINTF("Port %d write, state = %d\n", ucom->sc_portno, USB_GET_STATE(xfer));
914
915 switch (USB_GET_STATE(xfer)) {
916 case USB_ST_SETUP:
918tr_setup:
919 pc = usbd_xfer_get_frame(xfer, 0);
920 if (ucom_get_data(ucom, pc, 0, usbd_xfer_max_len(xfer), &actlen)) {
921 DPRINTF("Port %d write, has %d bytes\n", ucom->sc_portno, actlen);
922 usbd_xfer_set_frame_len(xfer, 0, actlen);
924 }
925 return;
926
927 default: /* Error */
928 if (error != USB_ERR_CANCELLED) {
929 /* try to clear stall first */
931 goto tr_setup;
932 }
933 return;
934 }
935}
936
937static void
939{
940 struct umcs7840_softc *sc = ucom->sc_parent;
941
942 DPRINTF("Port %d poll\n", ucom->sc_portno);
945}
946
947static usb_error_t
948umcs7840_get_reg_sync(struct umcs7840_softc *sc, uint8_t reg, uint8_t *data)
949{
950 struct usb_device_request req;
951 usb_error_t err;
952 uint16_t len;
953
954 req.bmRequestType = UT_READ_VENDOR_DEVICE;
955 req.bRequest = MCS7840_RDREQ;
956 USETW(req.wValue, 0);
957 USETW(req.wIndex, reg);
959
961 if (err == USB_ERR_NORMAL_COMPLETION && len != 1) {
962 device_printf(sc->sc_dev, "Reading register %d failed: invalid length %d\n", reg, len);
963 return (USB_ERR_INVAL);
964 } else if (err)
965 device_printf(sc->sc_dev, "Reading register %d failed: %s\n", reg, usbd_errstr(err));
966 return (err);
967}
968
969static usb_error_t
970umcs7840_set_reg_sync(struct umcs7840_softc *sc, uint8_t reg, uint8_t data)
971{
972 struct usb_device_request req;
973 usb_error_t err;
974
975 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
976 req.bRequest = MCS7840_WRREQ;
977 USETW(req.wValue, data);
978 USETW(req.wIndex, reg);
979 USETW(req.wLength, 0);
980
981 err = usbd_do_request_proc(sc->sc_udev, &sc->sc_super_ucom.sc_tq, &req, NULL, 0, NULL, UMCS7840_CTRL_TIMEOUT);
982 if (err)
983 device_printf(sc->sc_dev, "Writing register %d failed: %s\n", reg, usbd_errstr(err));
984
985 return (err);
986}
987
988static usb_error_t
989umcs7840_get_UART_reg_sync(struct umcs7840_softc *sc, uint8_t portno, uint8_t reg, uint8_t *data)
990{
991 struct usb_device_request req;
992 uint16_t wVal;
993 usb_error_t err;
994 uint16_t len;
995
996 /* portno is port number */
997 wVal = ((uint16_t)(portno + 1)) << 8;
998
999 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1000 req.bRequest = MCS7840_RDREQ;
1001 USETW(req.wValue, wVal);
1002 USETW(req.wIndex, reg);
1003 USETW(req.wLength, UMCS7840_READ_LENGTH);
1004
1006 if (err == USB_ERR_NORMAL_COMPLETION && len != 1) {
1007 device_printf(sc->sc_dev, "Reading UART%d register %d failed: invalid length %d\n", portno, reg, len);
1008 return (USB_ERR_INVAL);
1009 } else if (err)
1010 device_printf(sc->sc_dev, "Reading UART%d register %d failed: %s\n", portno, reg, usbd_errstr(err));
1011 return (err);
1012}
1013
1014static usb_error_t
1015umcs7840_set_UART_reg_sync(struct umcs7840_softc *sc, uint8_t portno, uint8_t reg, uint8_t data)
1016{
1017 struct usb_device_request req;
1018 usb_error_t err;
1019 uint16_t wVal;
1020
1021 /* portno is port number */
1022 wVal = ((uint16_t)(portno + 1)) << 8 | data;
1023
1024 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1025 req.bRequest = MCS7840_WRREQ;
1026 USETW(req.wValue, wVal);
1027 USETW(req.wIndex, reg);
1028 USETW(req.wLength, 0);
1029
1030 err = usbd_do_request_proc(sc->sc_udev, &sc->sc_super_ucom.sc_tq, &req, NULL, 0, NULL, UMCS7840_CTRL_TIMEOUT);
1031 if (err)
1032 device_printf(sc->sc_dev, "Writing UART%d register %d failed: %s\n", portno, reg, usbd_errstr(err));
1033 return (err);
1034}
1035
1036static usb_error_t
1037umcs7840_set_baudrate(struct umcs7840_softc *sc, uint8_t portno, uint32_t rate)
1038{
1039 usb_error_t err;
1040 uint16_t divisor;
1041 uint8_t clk;
1042 uint8_t data;
1043
1044 if (umcs7840_calc_baudrate(rate, &divisor, &clk)) {
1045 DPRINTF("Port %d bad speed: %d\n", portno, rate);
1046 return (-1);
1047 }
1048 if (divisor == 0 || (clk & MCS7840_DEV_SPx_CLOCK_MASK) != clk) {
1049 DPRINTF("Port %d bad speed calculation: %d\n", portno, rate);
1050 return (-1);
1051 }
1052 DPRINTF("Port %d set speed: %d (%02x / %d)\n", portno, rate, clk, divisor);
1053
1054 /* Set clock source for standard BAUD frequences */
1055 err = umcs7840_get_reg_sync(sc, umcs7840_port_registers[portno].reg_sp, &data);
1056 if (err)
1057 return (err);
1059 data |= clk;
1060 err = umcs7840_set_reg_sync(sc, umcs7840_port_registers[portno].reg_sp, data);
1061 if (err)
1062 return (err);
1063
1064 /* Set divider */
1066 err = umcs7840_set_UART_reg_sync(sc, portno, MCS7840_UART_REG_LCR, sc->sc_ports[portno].sc_lcr);
1067 if (err)
1068 return (err);
1069
1070 err = umcs7840_set_UART_reg_sync(sc, portno, MCS7840_UART_REG_DLL, (uint8_t)(divisor & 0xff));
1071 if (err)
1072 return (err);
1073 err = umcs7840_set_UART_reg_sync(sc, portno, MCS7840_UART_REG_DLM, (uint8_t)((divisor >> 8) & 0xff));
1074 if (err)
1075 return (err);
1076
1077 /* Turn off access to DLL/DLM registers of UART */
1078 sc->sc_ports[portno].sc_lcr &= ~MCS7840_UART_LCR_DIVISORS;
1079 err = umcs7840_set_UART_reg_sync(sc, portno, MCS7840_UART_REG_LCR, sc->sc_ports[portno].sc_lcr);
1080 if (err)
1081 return (err);
1082 return (0);
1083}
1084
1085/* Maximum speeds for standard frequences, when PLL is not used */
1086static const uint32_t umcs7840_baudrate_divisors[] = {0, 115200, 230400, 403200, 460800, 806400, 921600, 1572864, 3145728,};
1088
1089static usb_error_t
1090umcs7840_calc_baudrate(uint32_t rate, uint16_t *divisor, uint8_t *clk)
1091{
1092 uint8_t i = 0;
1093
1095 return (-1);
1096
1097 for (i = 0; i < umcs7840_baudrate_divisors_len - 1 &&
1098 !(rate > umcs7840_baudrate_divisors[i] && rate <= umcs7840_baudrate_divisors[i + 1]); ++i);
1099 if (rate == 0)
1100 *divisor = 1; /* XXX */
1101 else
1102 *divisor = umcs7840_baudrate_divisors[i + 1] / rate;
1103 /* 0x00 .. 0x70 */
1104 *clk = i << MCS7840_DEV_SPx_CLOCK_SHIFT;
1105 return (0);
1106}
static int debug
Definition: cfumass.c:73
static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "USB DWC OTG")
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, phy_type, CTLFLAG_RDTUN, &dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2/3 - ULPI/HSIC/INTERNAL/UTMI+")
uint16_t len
Definition: ehci.h:41
uint32_t reg
Definition: if_rum.c:283
uint8_t n
Definition: if_run.c:612
struct @109 error
uint16_t data
device_t dev
void(* ucom_cfg_get_status)(struct ucom_softc *, uint8_t *plsr, uint8_t *pmsr)
Definition: usb_serial.h:90
uint16_t sc_portno
Definition: usb_serial.h:174
struct tty * sc_tty
Definition: usb_serial.h:167
void * sc_parent
Definition: usb_serial.h:170
struct usb_process sc_tq
Definition: usb_serial.h:133
uint8_t reg_control
Definition: umcs.c:102
struct usb_xfer * sc_xfer[UMCS7840_N_TRANSFERS]
Definition: umcs.c:121
uint8_t sc_driver_done
Definition: umcs.c:141
struct mtx sc_mtx
Definition: umcs.c:139
struct ucom_super_softc sc_super_ucom
Definition: umcs.c:129
struct usb_device * sc_udev
Definition: umcs.c:138
struct umcs7840_softc_oneport sc_ports[UMCS7840_MAX_PORTS]
Definition: umcs.c:144
uint8_t sc_numports
Definition: umcs.c:143
struct usb_xfer * sc_intr_xfer
Definition: umcs.c:135
struct ucom_softc sc_ucom[UMCS7840_MAX_PORTS]
Definition: umcs.c:130
device_t sc_dev
Definition: umcs.c:137
enum usb_hc_mode usb_mode
Definition: usbdi.h:432
struct usbd_lookup_info info
Definition: usbdi.h:426
struct usb_device * device
Definition: usbdi.h:430
uint8_t type
Definition: usbdi.h:238
uint8_t endpoint
Definition: usbdi.h:239
usb_callback_t * callback
Definition: usbdi.h:229
uint16_t idProduct
Definition: usbdi.h:409
uint8_t bIfaceIndex
Definition: usbdi.h:417
uint8_t bConfigIndex
Definition: usbdi.h:419
#define DPRINTF(...)
Definition: umass.c:179
static usb_callback_t umcs7840_intr_callback
Definition: umcs.c:181
static void umcs7840_read_callbackN(struct usb_xfer *, usb_error_t, uint8_t)
Definition: umcs.c:849
static struct ucom_callback umcs7840_callback
Definition: umcs.c:236
static usb_error_t umcs7840_set_UART_reg_sync(struct umcs7840_softc *, uint8_t, uint8_t, uint8_t)
Definition: umcs.c:1015
static const struct usb_config umcs7840_bulk_config_data[UMCS7840_N_TRANSFERS]
Definition: umcs.c:202
static device_detach_t umcs7840_detach
Definition: umcs.c:178
static usb_callback_t umcs7840_write_callback1
Definition: umcs.c:186
static void umcs7840_cfg_set_break(struct ucom_softc *, uint8_t)
Definition: umcs.c:596
static void umcs7840_stop_read(struct ucom_softc *)
Definition: umcs.c:710
DRIVER_MODULE(umcs7840, uhub, umcs7840_driver, umcs7840_devclass, 0, 0)
static usb_callback_t umcs7840_write_callback3
Definition: umcs.c:188
static void umcs7840_cfg_open(struct ucom_softc *)
Definition: umcs.c:441
static const uint32_t umcs7840_baudrate_divisors[]
Definition: umcs.c:1086
static usb_error_t umcs7840_set_reg_sync(struct umcs7840_softc *, uint8_t, uint8_t)
Definition: umcs.c:970
static void umcs7840_cfg_set_dtr(struct ucom_softc *, uint8_t)
Definition: umcs.c:566
static const uint8_t umcs7840_baudrate_divisors_len
Definition: umcs.c:1087
static usb_error_t umcs7840_get_reg_sync(struct umcs7840_softc *, uint8_t, uint8_t *)
Definition: umcs.c:948
static usb_error_t umcs7840_set_baudrate(struct umcs7840_softc *, uint8_t, uint32_t)
Definition: umcs.c:1037
MODULE_VERSION(umcs7840, UMCS7840_MODVER)
MODULE_DEPEND(umcs7840, ucom, 1, 1, 1)
static const STRUCT_USB_HOST_ID umcs7840_devs[]
Definition: umcs.c:259
static void umcs7840_cfg_close(struct ucom_softc *)
Definition: umcs.c:544
@ UMCS7840_BULK_WR_EP
Definition: umcs.c:116
@ UMCS7840_N_TRANSFERS
Definition: umcs.c:117
@ UMCS7840_BULK_RD_EP
Definition: umcs.c:115
static void umcs7840_free_softc(struct umcs7840_softc *)
Definition: umcs.c:426
static void umcs7840_cfg_param(struct ucom_softc *, struct termios *)
Definition: umcs.c:611
static usb_error_t umcs7840_calc_baudrate(uint32_t rate, uint16_t *, uint8_t *)
Definition: umcs.c:1090
static usb_callback_t umcs7840_read_callback2
Definition: umcs.c:183
static devclass_t umcs7840_devclass
Definition: umcs.c:271
USB_PNP_HOST_INFO(umcs7840_devs)
static void umcs7840_start_write(struct ucom_softc *)
Definition: umcs.c:720
static usb_callback_t umcs7840_write_callback4
Definition: umcs.c:189
__FBSDID("$FreeBSD$")
static usb_callback_t umcs7840_read_callback3
Definition: umcs.c:184
static int umcs7840_pre_param(struct ucom_softc *, struct termios *)
Definition: umcs.c:686
static device_method_t umcs7840_methods[]
Definition: umcs.c:264
static usb_callback_t * umcs7840_rw_callbacks[UMCS7840_MAX_PORTS][UMCS7840_N_TRANSFERS]
Definition: umcs.c:195
static void umcs7840_stop_write(struct ucom_softc *)
Definition: umcs.c:733
static void umcs7840_start_read(struct ucom_softc *)
Definition: umcs.c:697
static usb_callback_t umcs7840_write_callback2
Definition: umcs.c:187
static void umcs7840_write_callbackN(struct usb_xfer *, usb_error_t, uint8_t)
Definition: umcs.c:906
UCOM_UNLOAD_DRAIN(umcs7840)
static usb_callback_t umcs7840_read_callback1
Definition: umcs.c:182
static void umcs7840_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *)
Definition: umcs.c:743
static usb_callback_t umcs7840_read_callback4
Definition: umcs.c:185
static usb_error_t umcs7840_get_UART_reg_sync(struct umcs7840_softc *, uint8_t, uint8_t, uint8_t *)
Definition: umcs.c:989
static device_probe_t umcs7840_probe
Definition: umcs.c:176
static void umcs7840_cfg_set_rts(struct ucom_softc *, uint8_t)
Definition: umcs.c:581
static const struct usb_config umcs7840_intr_config_data[1]
Definition: umcs.c:224
#define UMCS7840_MODVER
Definition: umcs.c:79
static device_attach_t umcs7840_attach
Definition: umcs.c:177
static driver_t umcs7840_driver
Definition: umcs.c:273
static void umcs7840_poll(struct ucom_softc *ucom)
Definition: umcs.c:938
static void umcs7840_free(struct ucom_softc *)
Definition: umcs.c:435
#define MCS7840_DEV_SPx_CLOCK_SHIFT
Definition: umcs.h:124
#define MCS7840_DEV_REG_SP2
Definition: umcs.h:54
#define MCS7840_UART_LCR_PARITYEVEN
Definition: umcs.h:378
#define UMCS7840_CTRL_TIMEOUT
Definition: umcs.h:35
#define MCS7840_DEV_SPx_RESET_IN_FIFO
Definition: umcs.h:114
#define UMCS7840_MAX_PORTS
Definition: umcs.h:32
#define MCS7840_UART_REG_FCR
Definition: umcs.h:327
#define MCS7840_DEV_REG_CONTROL2
Definition: umcs.h:55
#define MCS7840_DEV_SPx_UART_RESET
Definition: umcs.h:125
#define MCS7840_UART_FCR_RTL_1_14
Definition: umcs.h:353
#define MCS7840_UART_REG_DLL
Definition: umcs.h:335
#define MCS7840_DEV_REG_CONTROL1
Definition: umcs.h:49
#define MCS7840_UART_REG_IER
Definition: umcs.h:326
#define MCS7840_UART_FCR_ENABLE
Definition: umcs.h:346
#define MCS7840_IFACE_INDEX
Definition: umcs.h:419
#define MCS7840_UART_IER_RXSTAT
Definition: umcs.h:341
#define MCS7840_DEV_CONTROLx_RX_DISABLE
Definition: umcs.h:134
#define MCS7840_UART_LCR_PARITYODD
Definition: umcs.h:379
#define MCS7840_UART_MCR_IE
Definition: umcs.h:397
#define MCS7840_WRREQ
Definition: umcs.h:39
#define MCS7840_DEV_MODE_IRDA
Definition: umcs.h:215
#define MCS7840_DEV_REG_MODE
Definition: umcs.h:81
#define MCS7840_UART_REG_LSR
Definition: umcs.h:331
#define MCS7840_RDREQ
Definition: umcs.h:38
#define MCS7840_DEV_MODE_SER_PRSNT
Definition: umcs.h:210
#define MCS7840_DEV_MODE_EEPROMWR
Definition: umcs.h:214
#define MCS7840_UART_REG_MSR
Definition: umcs.h:332
#define MCS7840_UART_LCR_STOPB2
Definition: umcs.h:373
#define MCS7840_UART_MCR_DTR
Definition: umcs.h:395
#define MCS7840_UART_MSR_NEGDCD
Definition: umcs.h:411
#define MCS7840_UART_ISR_NOPENDING
Definition: umcs.h:356
#define MCS7840_UART_LCR_DATALEN6
Definition: umcs.h:367
#define MCS7840_DEV_MODE_RESET
Definition: umcs.h:209
#define MCS7840_UART_ISR_INTMASK
Definition: umcs.h:357
#define MCS7840_UART_MSR_NEGRI
Definition: umcs.h:410
#define MCS7840_UART_LCR_BREAK
Definition: umcs.h:382
#define MCS7840_UART_LCR_DATALEN8
Definition: umcs.h:369
#define MCS7840_DEV_REG_SP3
Definition: umcs.h:56
#define MCS7840_DEV_CONTROL1_DRIVER_DONE
Definition: umcs.h:132
#define MCS7840_DEV_REG_CONTROL4
Definition: umcs.h:59
#define MCS7840_UART_FCR_FLUSHTHR
Definition: umcs.h:348
#define MCS7840_UART_MSR_NEGCTS
Definition: umcs.h:408
#define MCS7840_DEV_REG_GPIO
Definition: umcs.h:53
#define MCS7840_UART_ISR_RXHASDATA
Definition: umcs.h:359
#define MCS7840_UART_MCR_RTS
Definition: umcs.h:396
#define MCS7840_UART_ISR_RXERR
Definition: umcs.h:358
#define MCS7840_UART_MCR_DTRDSR
Definition: umcs.h:400
#define MCS7840_UART_REG_LCR
Definition: umcs.h:329
#define MCS7840_UART_MCR_CTSRTS
Definition: umcs.h:399
#define MCS7840_UART_MSR_NEGDSR
Definition: umcs.h:409
#define MCS7840_UART_LCR_DIVISORS
Definition: umcs.h:383
#define MCS7840_DEV_REG_CONTROL3
Definition: umcs.h:57
#define MCS7840_UART_REG_MCR
Definition: umcs.h:330
#define MCS7840_UART_LCR_DATALEN5
Definition: umcs.h:366
#define MCS7840_UART_LCR_PARITYON
Definition: umcs.h:376
#define MCS7840_DEV_GPIO_4PORTS
Definition: umcs.h:155
#define MCS7840_UART_ISR_RXTIMEOUT
Definition: umcs.h:360
#define MCS7840_DEV_MODE_PLLBYPASS
Definition: umcs.h:211
#define MCS7840_DEV_REG_DCR0_4
Definition: umcs.h:263
#define MCS7840_UART_IER_MODEM
Definition: umcs.h:342
#define MCS7840_UART_LCR_DATALEN7
Definition: umcs.h:368
#define MCS7840_UART_LCR_STOPB1
Definition: umcs.h:372
#define MCS7840_DEV_MODE_SELECT24S
Definition: umcs.h:213
#define MCS7840_DEV_REG_DCR0_2
Definition: umcs.h:257
#define UMCS7840_READ_LENGTH
Definition: umcs.h:34
#define MCS7840_DEV_SPx_RESET_OUT_FIFO
Definition: umcs.h:113
#define MCS7840_DEV_REG_DCR0_1
Definition: umcs.h:254
#define MCS7840_DEV_REG_SP1
Definition: umcs.h:48
#define MCS7840_DEV_MODE_PORBYPASS
Definition: umcs.h:212
#define MCS7840_DEV_REG_SP4
Definition: umcs.h:58
#define MCS7840_DEV_SPx_CLOCK_MASK
Definition: umcs.h:115
#define MCS7840_UART_REG_SCRATCHPAD
Definition: umcs.h:333
#define MCS7840_UART_FCR_FLUSHRHR
Definition: umcs.h:347
#define MCS7840_UART_ISR_MSCHANGE
Definition: umcs.h:362
#define MCS7840_UART_REG_DLM
Definition: umcs.h:336
#define MCS7840_CONFIG_INDEX
Definition: umcs.h:418
#define MCS7840_DEV_REG_DCR0_3
Definition: umcs.h:260
#define MCS7840_UART_SCRATCHPAD_RS232
Definition: umcs.h:414
#define UE_INTERRUPT
Definition: usb.h:544
#define UE_BULK
Definition: usb.h:543
#define UT_WRITE_VENDOR_DEVICE
Definition: usb.h:184
#define UT_READ_VENDOR_DEVICE
Definition: usb.h:180
#define UE_DIR_IN
Definition: usb.h:531
#define UE_DIR_OUT
Definition: usb.h:532
@ USB_MODE_HOST
Definition: usb.h:778
void usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
Definition: usb_busdma.c:283
#define USETW(w, v)
Definition: usb_endian.h:77
const char * usbd_errstr(usb_error_t err)
Definition: usb_error.c:93
const void * req
Definition: usb_if.m:51
INTERFACE usb
Definition: usb_if.m:35
int usbd_lookup_id_by_uaa(const struct usb_device_id *id, usb_size_t sizeof_id, struct usb_attach_arg *uaa)
Definition: usb_lookup.c:143
usb_error_t usbd_do_request_proc(struct usb_device *udev, struct usb_process *pproc, struct usb_device_request *req, void *data, uint16_t flags, uint16_t *actlen, usb_timeout_t timeout)
Definition: usb_request.c:742
uint8_t ucom_get_data(struct ucom_softc *sc, struct usb_page_cache *pc, uint32_t offset, uint32_t len, uint32_t *actlen)
Definition: usb_serial.c:1384
void ucom_status_change(struct ucom_softc *sc)
Definition: usb_serial.c:1229
int ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc, int subunits, void *parent, const struct ucom_callback *callback, struct mtx *mtx)
Definition: usb_serial.c:267
int ucom_unref(struct ucom_super_softc *ssc)
Definition: usb_serial.c:1730
void ucom_ref(struct ucom_super_softc *ssc)
Definition: usb_serial.c:1695
void ucom_set_pnpinfo_usb(struct ucom_super_softc *ssc, device_t dev)
Definition: usb_serial.c:549
void ucom_detach(struct ucom_super_softc *ssc, struct ucom_softc *sc)
Definition: usb_serial.c:336
void ucom_put_data(struct ucom_softc *sc, struct usb_page_cache *pc, uint32_t offset, uint32_t len)
Definition: usb_serial.c:1462
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup)
void usbd_xfer_set_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex, usb_frlength_t len)
struct usb_page_cache * usbd_xfer_get_frame(struct usb_xfer *xfer, usb_frcount_t frindex)
usb_error_t usbd_transfer_setup(struct usb_device *udev, const uint8_t *ifaces, struct usb_xfer **ppxfer, const struct usb_config *setup_start, uint16_t n_setup, void *priv_sc, struct mtx *xfer_mtx)
Definition: usb_transfer.c:987
void usbd_transfer_start(struct usb_xfer *xfer)
void usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
void * usbd_xfer_softc(struct usb_xfer *xfer)
void usbd_xfer_set_stall(struct usb_xfer *xfer)
void usbd_transfer_stop(struct usb_xfer *xfer)
void usbd_xfer_status(struct usb_xfer *xfer, int *actlen, int *sumlen, int *aframes, int *nframes)
usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer)
void device_set_usb_desc(device_t dev)
Definition: usb_util.c:73
#define USB_ST_SETUP
Definition: usbdi.h:502
usb_error_t
Definition: usbdi.h:45
@ USB_ERR_NORMAL_COMPLETION
Definition: usbdi.h:46
@ USB_ERR_CANCELLED
Definition: usbdi.h:51
@ USB_ERR_INVAL
Definition: usbdi.h:49
#define USB_ST_TRANSFERRED
Definition: usbdi.h:503
void() usb_callback_t(struct usb_xfer *, usb_error_t)
Definition: usbdi.h:94
#define USB_VPI(vend, prod, info)
Definition: usbdi.h:367
#define STRUCT_USB_HOST_ID
Definition: usbdi.h:258
#define USB_GET_STATE(xfer)
Definition: usbdi.h:515