Deleted Added
sdiff udiff text old ( 239180 ) new ( 239260 )
full compact
1/* $OpenBSD: uslcom.c,v 1.17 2007/11/24 10:52:12 jsg Exp $ */
2
3#include <sys/cdefs.h>
4__FBSDID("$FreeBSD: head/sys/dev/usb/serial/uslcom.c 239180 2012-08-10 15:29:41Z hselasky $");
5
6/*
7 * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22#include <sys/stdint.h>
23#include <sys/stddef.h>
24#include <sys/param.h>
25#include <sys/queue.h>
26#include <sys/types.h>
27#include <sys/systm.h>
28#include <sys/kernel.h>
29#include <sys/bus.h>

--- 26 unchanged lines hidden (view full) ---

56static SYSCTL_NODE(_hw_usb, OID_AUTO, uslcom, CTLFLAG_RW, 0, "USB uslcom");
57SYSCTL_INT(_hw_usb_uslcom, OID_AUTO, debug, CTLFLAG_RW,
58 &uslcom_debug, 0, "Debug level");
59#endif
60
61#define USLCOM_BULK_BUF_SIZE 1024
62#define USLCOM_CONFIG_INDEX 0
63
64#define USLCOM_SET_DATA_BITS(x) ((x) << 8)
65
66/* Request types */
67#define USLCOM_WRITE 0x41
68#define USLCOM_READ 0xc1
69
70/* Request codes */
71#define USLCOM_UART 0x00
72#define USLCOM_SET_BAUD_DIV 0x01
73#define USLCOM_DATA 0x03
74#define USLCOM_BREAK 0x05
75#define USLCOM_CTRL 0x07
76#define USLCOM_RCTRL 0x08
77#define USLCOM_SET_FLOWCTRL 0x13
78#define USLCOM_SET_BAUD_RATE 0x1e
79#define USLCOM_VENDOR_SPECIFIC 0xff
80
81/* USLCOM_UART values */
82#define USLCOM_UART_DISABLE 0x00
83#define USLCOM_UART_ENABLE 0x01
84
85/* USLCOM_CTRL/USLCOM_RCTRL values */
86#define USLCOM_CTRL_DTR_ON 0x0001
87#define USLCOM_CTRL_DTR_SET 0x0100
88#define USLCOM_CTRL_RTS_ON 0x0002
89#define USLCOM_CTRL_RTS_SET 0x0200
90#define USLCOM_CTRL_CTS 0x0010
91#define USLCOM_CTRL_DSR 0x0020
92#define USLCOM_CTRL_RI 0x0040
93#define USLCOM_CTRL_DCD 0x0080
94
95/* USLCOM_SET_BAUD_DIV values */
96#define USLCOM_BAUD_REF 3686400 /* 3.6864 MHz */
97
98/* USLCOM_DATA values */
99#define USLCOM_STOP_BITS_1 0x00
100#define USLCOM_STOP_BITS_2 0x02
101#define USLCOM_PARITY_NONE 0x00
102#define USLCOM_PARITY_ODD 0x10
103#define USLCOM_PARITY_EVEN 0x20
104
105/* USLCOM_BREAK values */
106#define USLCOM_BREAK_OFF 0x00
107#define USLCOM_BREAK_ON 0x01
108
109/* USLCOM_SET_FLOWCTRL values - 1st word */
110#define USLCOM_FLOW_DTR_ON 0x00000001 /* DTR static active */
111#define USLCOM_FLOW_CTS_HS 0x00000008 /* CTS handshake */
112/* USLCOM_SET_FLOWCTRL values - 2nd word */
113#define USLCOM_FLOW_RTS_ON 0x00000040 /* RTS static active */
114#define USLCOM_FLOW_RTS_HS 0x00000080 /* RTS handshake */
115
116/* USLCOM_VENDOR_SPECIFIC values */
117#define USLCOM_WRITE_LATCH 0x37E1
118#define USLCOM_READ_LATCH 0x00C2
119
120enum {

--- 334 unchanged lines hidden (view full) ---

455
456static void
457uslcom_open(struct ucom_softc *ucom)
458{
459 struct uslcom_softc *sc = ucom->sc_parent;
460 struct usb_device_request req;
461
462 req.bmRequestType = USLCOM_WRITE;
463 req.bRequest = USLCOM_UART;
464 USETW(req.wValue, USLCOM_UART_ENABLE);
465 USETW(req.wIndex, sc->sc_iface_no);
466 USETW(req.wLength, 0);
467
468 if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
469 &req, NULL, 0, 1000)) {
470 DPRINTF("UART enable failed (ignored)\n");
471 }
472

--- 6 unchanged lines hidden (view full) ---

479{
480 struct uslcom_softc *sc = ucom->sc_parent;
481 struct usb_device_request req;
482
483 /* stop polling status */
484 usb_callout_stop(&sc->sc_watchdog);
485
486 req.bmRequestType = USLCOM_WRITE;
487 req.bRequest = USLCOM_UART;
488 USETW(req.wValue, USLCOM_UART_DISABLE);
489 USETW(req.wIndex, sc->sc_iface_no);
490 USETW(req.wLength, 0);
491
492 if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
493 &req, NULL, 0, 1000)) {
494 DPRINTF("UART disable failed (ignored)\n");
495 }
496}
497
498static void
499uslcom_set_dtr(struct ucom_softc *ucom, uint8_t onoff)
500{
501 struct uslcom_softc *sc = ucom->sc_parent;
502 struct usb_device_request req;
503 uint16_t ctl;
504
505 DPRINTF("onoff = %d\n", onoff);
506
507 ctl = onoff ? USLCOM_CTRL_DTR_ON : 0;
508 ctl |= USLCOM_CTRL_DTR_SET;
509
510 req.bmRequestType = USLCOM_WRITE;
511 req.bRequest = USLCOM_CTRL;
512 USETW(req.wValue, ctl);
513 USETW(req.wIndex, sc->sc_iface_no);
514 USETW(req.wLength, 0);
515
516 if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
517 &req, NULL, 0, 1000)) {
518 DPRINTF("Setting DTR failed (ignored)\n");
519 }
520}
521
522static void
523uslcom_set_rts(struct ucom_softc *ucom, uint8_t onoff)
524{
525 struct uslcom_softc *sc = ucom->sc_parent;
526 struct usb_device_request req;
527 uint16_t ctl;
528
529 DPRINTF("onoff = %d\n", onoff);
530
531 ctl = onoff ? USLCOM_CTRL_RTS_ON : 0;
532 ctl |= USLCOM_CTRL_RTS_SET;
533
534 req.bmRequestType = USLCOM_WRITE;
535 req.bRequest = USLCOM_CTRL;
536 USETW(req.wValue, ctl);
537 USETW(req.wIndex, sc->sc_iface_no);
538 USETW(req.wLength, 0);
539
540 if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
541 &req, NULL, 0, 1000)) {
542 DPRINTF("Setting DTR failed (ignored)\n");
543 }

--- 14 unchanged lines hidden (view full) ---

558 struct usb_device_request req;
559 uint32_t baudrate, flowctrl[4];
560 uint16_t data;
561
562 DPRINTF("\n");
563
564 baudrate = t->c_ospeed;
565 req.bmRequestType = USLCOM_WRITE;
566 req.bRequest = USLCOM_SET_BAUD_RATE;
567 USETW(req.wValue, 0);
568 USETW(req.wIndex, sc->sc_iface_no);
569 USETW(req.wLength, sizeof(baudrate));
570
571 if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
572 &req, &baudrate, 0, 1000)) {
573 DPRINTF("Set baudrate failed (ignored)\n");
574 }

--- 20 unchanged lines hidden (view full) ---

595 data |= USLCOM_SET_DATA_BITS(7);
596 break;
597 case CS8:
598 data |= USLCOM_SET_DATA_BITS(8);
599 break;
600 }
601
602 req.bmRequestType = USLCOM_WRITE;
603 req.bRequest = USLCOM_DATA;
604 USETW(req.wValue, data);
605 USETW(req.wIndex, sc->sc_iface_no);
606 USETW(req.wLength, 0);
607
608 if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
609 &req, NULL, 0, 1000)) {
610 DPRINTF("Set format failed (ignored)\n");
611 }
612
613 if (t->c_cflag & CRTSCTS) {
614 flowctrl[0] = htole32(USLCOM_FLOW_DTR_ON | USLCOM_FLOW_CTS_HS);
615 flowctrl[1] = htole32(USLCOM_FLOW_RTS_HS);
616 flowctrl[2] = 0;
617 flowctrl[3] = 0;
618 } else {
619 flowctrl[0] = htole32(USLCOM_FLOW_DTR_ON);
620 flowctrl[1] = htole32(USLCOM_FLOW_RTS_ON);
621 flowctrl[2] = 0;
622 flowctrl[3] = 0;
623 }
624 req.bmRequestType = USLCOM_WRITE;
625 req.bRequest = USLCOM_SET_FLOWCTRL;
626 USETW(req.wValue, 0);
627 USETW(req.wIndex, sc->sc_iface_no);
628 USETW(req.wLength, sizeof(flowctrl));
629
630 if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
631 &req, flowctrl, 0, 1000)) {
632 DPRINTF("Set flowcontrol failed (ignored)\n");
633 }

--- 10 unchanged lines hidden (view full) ---

644 *msr = sc->sc_msr;
645}
646
647static void
648uslcom_set_break(struct ucom_softc *ucom, uint8_t onoff)
649{
650 struct uslcom_softc *sc = ucom->sc_parent;
651 struct usb_device_request req;
652 uint16_t brk = onoff ? USLCOM_BREAK_ON : USLCOM_BREAK_OFF;
653
654 req.bmRequestType = USLCOM_WRITE;
655 req.bRequest = USLCOM_BREAK;
656 USETW(req.wValue, brk);
657 USETW(req.wIndex, sc->sc_iface_no);
658 USETW(req.wLength, 0);
659
660 if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
661 &req, NULL, 0, 1000)) {
662 DPRINTF("Set BREAK failed (ignored)\n");
663 }

--- 118 unchanged lines hidden (view full) ---

782 struct usb_device_request req;
783 uint8_t msr = 0;
784 uint8_t buf;
785
786 switch (USB_GET_STATE(xfer)) {
787 case USB_ST_TRANSFERRED:
788 pc = usbd_xfer_get_frame(xfer, 1);
789 usbd_copy_out(pc, 0, &buf, sizeof(buf));
790 if (buf & USLCOM_CTRL_CTS)
791 msr |= SER_CTS;
792 if (buf & USLCOM_CTRL_DSR)
793 msr |= SER_DSR;
794 if (buf & USLCOM_CTRL_RI)
795 msr |= SER_RI;
796 if (buf & USLCOM_CTRL_DCD)
797 msr |= SER_DCD;
798
799 if (msr != sc->sc_msr) {
800 DPRINTF("status change msr=0x%02x "
801 "(was 0x%02x)\n", msr, sc->sc_msr);
802 sc->sc_msr = msr;
803 ucom_status_change(&sc->sc_ucom);
804 }
805 break;
806
807 case USB_ST_SETUP:
808 req.bmRequestType = USLCOM_READ;
809 req.bRequest = USLCOM_RCTRL;
810 USETW(req.wValue, 0);
811 USETW(req.wIndex, sc->sc_iface_no);
812 USETW(req.wLength, sizeof(buf));
813
814 usbd_xfer_set_frames(xfer, 2);
815 usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
816 usbd_xfer_set_frame_len(xfer, 1, sizeof(buf));
817

--- 52 unchanged lines hidden ---