diff options
Diffstat (limited to 'freebsd/sys/dev/usb/serial/uslcom.c')
-rw-r--r-- | freebsd/sys/dev/usb/serial/uslcom.c | 126 |
1 files changed, 70 insertions, 56 deletions
diff --git a/freebsd/sys/dev/usb/serial/uslcom.c b/freebsd/sys/dev/usb/serial/uslcom.c index 45835b82..4128802d 100644 --- a/freebsd/sys/dev/usb/serial/uslcom.c +++ b/freebsd/sys/dev/usb/serial/uslcom.c @@ -66,7 +66,7 @@ SYSCTL_INT(_hw_usb_uslcom, OID_AUTO, debug, CTLFLAG_RWTUN, &uslcom_debug, 0, "Debug level"); #endif -#define USLCOM_BULK_BUF_SIZE 1024 +#define USLCOM_BULK_BUF_SIZE 1024 #define USLCOM_CONFIG_INDEX 0 /* Request types */ @@ -75,13 +75,13 @@ SYSCTL_INT(_hw_usb_uslcom, OID_AUTO, debug, CTLFLAG_RWTUN, /* Request codes */ #define USLCOM_IFC_ENABLE 0x00 -#define USLCOM_SET_BAUDDIV 0x01 +#define USLCOM_SET_BAUDDIV 0x01 #define USLCOM_SET_LINE_CTL 0x03 #define USLCOM_SET_BREAK 0x05 #define USLCOM_SET_MHS 0x07 #define USLCOM_GET_MDMSTS 0x08 #define USLCOM_SET_FLOW 0x13 -#define USLCOM_SET_BAUDRATE 0x1e +#define USLCOM_SET_BAUDRATE 0x1e #define USLCOM_VENDOR_SPECIFIC 0xff /* USLCOM_IFC_ENABLE values */ @@ -89,7 +89,7 @@ SYSCTL_INT(_hw_usb_uslcom, OID_AUTO, debug, CTLFLAG_RWTUN, #define USLCOM_IFC_ENABLE_EN 0x01 /* USLCOM_SET_MHS/USLCOM_GET_MDMSTS values */ -#define USLCOM_MHS_DTR_ON 0x0001 +#define USLCOM_MHS_DTR_ON 0x0001 #define USLCOM_MHS_DTR_SET 0x0100 #define USLCOM_MHS_RTS_ON 0x0002 #define USLCOM_MHS_RTS_SET 0x0200 @@ -114,11 +114,11 @@ SYSCTL_INT(_hw_usb_uslcom, OID_AUTO, debug, CTLFLAG_RWTUN, #define USLCOM_SET_BREAK_ON 0x01 /* USLCOM_SET_FLOW values - 1st word */ -#define USLCOM_FLOW_DTR_ON 0x00000001 /* DTR static active */ -#define USLCOM_FLOW_CTS_HS 0x00000008 /* CTS handshake */ +#define USLCOM_FLOW_DTR_ON 0x00000001 /* DTR static active */ +#define USLCOM_FLOW_CTS_HS 0x00000008 /* CTS handshake */ /* USLCOM_SET_FLOW values - 2nd word */ -#define USLCOM_FLOW_RTS_ON 0x00000040 /* RTS static active */ -#define USLCOM_FLOW_RTS_HS 0x00000080 /* RTS handshake */ +#define USLCOM_FLOW_RTS_ON 0x00000040 /* RTS static active */ +#define USLCOM_FLOW_RTS_HS 0x00000080 /* RTS handshake */ /* USLCOM_VENDOR_SPECIFIC values */ #define USLCOM_GET_PARTNUM 0x370B @@ -148,10 +148,10 @@ struct uslcom_softc { struct usb_device *sc_udev; struct mtx sc_mtx; - uint8_t sc_msr; - uint8_t sc_lsr; - uint8_t sc_iface_no; - uint8_t sc_partnum; + uint8_t sc_msr; + uint8_t sc_lsr; + uint8_t sc_iface_no; + uint8_t sc_partnum; }; static device_probe_t uslcom_probe; @@ -163,18 +163,18 @@ static usb_callback_t uslcom_write_callback; static usb_callback_t uslcom_read_callback; static usb_callback_t uslcom_control_callback; -static void uslcom_free(struct ucom_softc *); -static void uslcom_open(struct ucom_softc *); -static void uslcom_close(struct ucom_softc *); +static void uslcom_free(struct ucom_softc *); static uint8_t uslcom_get_partnum(struct uslcom_softc *); -static void uslcom_set_dtr(struct ucom_softc *, uint8_t); -static void uslcom_set_rts(struct ucom_softc *, uint8_t); -static void uslcom_set_break(struct ucom_softc *, uint8_t); +static void uslcom_cfg_open(struct ucom_softc *); +static void uslcom_cfg_close(struct ucom_softc *); +static void uslcom_cfg_set_dtr(struct ucom_softc *, uint8_t); +static void uslcom_cfg_set_rts(struct ucom_softc *, uint8_t); +static void uslcom_cfg_set_break(struct ucom_softc *, uint8_t); +static void uslcom_cfg_param(struct ucom_softc *, struct termios *); +static void uslcom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *); static int uslcom_ioctl(struct ucom_softc *, uint32_t, caddr_t, int, - struct thread *); + struct thread *); static int uslcom_pre_param(struct ucom_softc *, struct termios *); -static void uslcom_param(struct ucom_softc *, struct termios *); -static void uslcom_get_status(struct ucom_softc *, uint8_t *, uint8_t *); static void uslcom_start_read(struct ucom_softc *); static void uslcom_stop_read(struct ucom_softc *); static void uslcom_start_write(struct ucom_softc *); @@ -182,7 +182,6 @@ static void uslcom_stop_write(struct ucom_softc *); static void uslcom_poll(struct ucom_softc *ucom); static const struct usb_config uslcom_config[USLCOM_N_TRANSFER] = { - [USLCOM_BULK_DT_WR] = { .type = UE_BULK, .endpoint = UE_ADDR_ANY, @@ -212,15 +211,15 @@ static const struct usb_config uslcom_config[USLCOM_N_TRANSFER] = { }; static struct ucom_callback uslcom_callback = { - .ucom_cfg_open = &uslcom_open, - .ucom_cfg_close = &uslcom_close, - .ucom_cfg_get_status = &uslcom_get_status, - .ucom_cfg_set_dtr = &uslcom_set_dtr, - .ucom_cfg_set_rts = &uslcom_set_rts, - .ucom_cfg_set_break = &uslcom_set_break, - .ucom_ioctl = &uslcom_ioctl, - .ucom_cfg_param = &uslcom_param, + .ucom_cfg_get_status = &uslcom_cfg_get_status, + .ucom_cfg_set_dtr = &uslcom_cfg_set_dtr, + .ucom_cfg_set_rts = &uslcom_cfg_set_rts, + .ucom_cfg_set_break = &uslcom_cfg_set_break, + .ucom_cfg_open = &uslcom_cfg_open, + .ucom_cfg_close = &uslcom_cfg_close, + .ucom_cfg_param = &uslcom_cfg_param, .ucom_pre_param = &uslcom_pre_param, + .ucom_ioctl = &uslcom_ioctl, .ucom_start_read = &uslcom_start_read, .ucom_stop_read = &uslcom_stop_read, .ucom_start_write = &uslcom_start_write, @@ -501,7 +500,7 @@ uslcom_free(struct ucom_softc *ucom) } static void -uslcom_open(struct ucom_softc *ucom) +uslcom_cfg_open(struct ucom_softc *ucom) { struct uslcom_softc *sc = ucom->sc_parent; struct usb_device_request req; @@ -512,7 +511,7 @@ uslcom_open(struct ucom_softc *ucom) USETW(req.wIndex, sc->sc_iface_no); USETW(req.wLength, 0); - if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, + if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, &req, NULL, 0, 1000)) { DPRINTF("UART enable failed (ignored)\n"); } @@ -522,7 +521,7 @@ uslcom_open(struct ucom_softc *ucom) } static void -uslcom_close(struct ucom_softc *ucom) +uslcom_cfg_close(struct ucom_softc *ucom) { struct uslcom_softc *sc = ucom->sc_parent; struct usb_device_request req; @@ -536,7 +535,7 @@ uslcom_close(struct ucom_softc *ucom) USETW(req.wIndex, sc->sc_iface_no); USETW(req.wLength, 0); - if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, + if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, &req, NULL, 0, 1000)) { DPRINTF("UART disable failed (ignored)\n"); } @@ -565,13 +564,13 @@ uslcom_get_partnum(struct uslcom_softc *sc) } static void -uslcom_set_dtr(struct ucom_softc *ucom, uint8_t onoff) +uslcom_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff) { - struct uslcom_softc *sc = ucom->sc_parent; + struct uslcom_softc *sc = ucom->sc_parent; struct usb_device_request req; uint16_t ctl; - DPRINTF("onoff = %d\n", onoff); + DPRINTF("onoff = %d\n", onoff); ctl = onoff ? USLCOM_MHS_DTR_ON : 0; ctl |= USLCOM_MHS_DTR_SET; @@ -582,20 +581,20 @@ uslcom_set_dtr(struct ucom_softc *ucom, uint8_t onoff) USETW(req.wIndex, sc->sc_iface_no); USETW(req.wLength, 0); - if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, + if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, &req, NULL, 0, 1000)) { DPRINTF("Setting DTR failed (ignored)\n"); } } static void -uslcom_set_rts(struct ucom_softc *ucom, uint8_t onoff) +uslcom_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff) { - struct uslcom_softc *sc = ucom->sc_parent; + struct uslcom_softc *sc = ucom->sc_parent; struct usb_device_request req; uint16_t ctl; - DPRINTF("onoff = %d\n", onoff); + DPRINTF("onoff = %d\n", onoff); ctl = onoff ? USLCOM_MHS_RTS_ON : 0; ctl |= USLCOM_MHS_RTS_SET; @@ -606,7 +605,7 @@ uslcom_set_rts(struct ucom_softc *ucom, uint8_t onoff) USETW(req.wIndex, sc->sc_iface_no); USETW(req.wLength, 0); - if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, + if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, &req, NULL, 0, 1000)) { DPRINTF("Setting DTR failed (ignored)\n"); } @@ -615,13 +614,28 @@ uslcom_set_rts(struct ucom_softc *ucom, uint8_t onoff) static int uslcom_pre_param(struct ucom_softc *ucom, struct termios *t) { - if (t->c_ospeed <= 0 || t->c_ospeed > 921600) + struct uslcom_softc *sc = ucom->sc_parent; + uint32_t maxspeed; + + switch (sc->sc_partnum) { + case USLCOM_PARTNUM_CP2104: + case USLCOM_PARTNUM_CP2105: + maxspeed = 2000000; + break; + case USLCOM_PARTNUM_CP2101: + case USLCOM_PARTNUM_CP2102: + case USLCOM_PARTNUM_CP2103: + default: + maxspeed = 921600; + break; + } + if (t->c_ospeed <= 0 || t->c_ospeed > maxspeed) return (EINVAL); return (0); } static void -uslcom_param(struct ucom_softc *ucom, struct termios *t) +uslcom_cfg_param(struct ucom_softc *ucom, struct termios *t) { struct uslcom_softc *sc = ucom->sc_parent; struct usb_device_request req; @@ -637,9 +651,9 @@ uslcom_param(struct ucom_softc *ucom, struct termios *t) USETW(req.wIndex, sc->sc_iface_no); USETW(req.wLength, sizeof(baudrate)); - if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, + if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, &req, &baudrate, 0, 1000)) { - DPRINTF("Set baudrate failed (ignored)\n"); + printf("Set baudrate failed (ignored)\n"); } if (t->c_cflag & CSTOPB) @@ -674,11 +688,11 @@ uslcom_param(struct ucom_softc *ucom, struct termios *t) USETW(req.wIndex, sc->sc_iface_no); USETW(req.wLength, 0); - if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, + if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, &req, NULL, 0, 1000)) { DPRINTF("Set format failed (ignored)\n"); } - + if (t->c_cflag & CRTSCTS) { flowctrl[0] = htole32(USLCOM_FLOW_DTR_ON | USLCOM_FLOW_CTS_HS); flowctrl[1] = htole32(USLCOM_FLOW_RTS_HS); @@ -694,14 +708,14 @@ uslcom_param(struct ucom_softc *ucom, struct termios *t) USETW(req.wIndex, sc->sc_iface_no); USETW(req.wLength, sizeof(flowctrl)); - if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, + if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, &req, flowctrl, 0, 1000)) { DPRINTF("Set flowcontrol failed (ignored)\n"); } } static void -uslcom_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr) +uslcom_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr) { struct uslcom_softc *sc = ucom->sc_parent; @@ -713,9 +727,9 @@ uslcom_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr) } static void -uslcom_set_break(struct ucom_softc *ucom, uint8_t onoff) +uslcom_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff) { - struct uslcom_softc *sc = ucom->sc_parent; + struct uslcom_softc *sc = ucom->sc_parent; struct usb_device_request req; uint16_t brk = onoff ? USLCOM_SET_BREAK_ON : USLCOM_SET_BREAK_OFF; @@ -725,7 +739,7 @@ uslcom_set_break(struct ucom_softc *ucom, uint8_t onoff) USETW(req.wIndex, sc->sc_iface_no); USETW(req.wLength, 0); - if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, + if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, &req, NULL, 0, 1000)) { DPRINTF("Set BREAK failed (ignored)\n"); } @@ -754,7 +768,7 @@ uslcom_ioctl(struct ucom_softc *ucom, uint32_t cmd, caddr_t data, USETW(req.wIndex, sc->sc_iface_no); USETW(req.wLength, sizeof(latch)); - if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, + if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, &req, &latch, 0, 1000)) { DPRINTF("Get LATCH failed\n"); error = EIO; @@ -773,7 +787,7 @@ uslcom_ioctl(struct ucom_softc *ucom, uint32_t cmd, caddr_t data, USETW(req.wIndex, (*(int *)data)); USETW(req.wLength, 0); - if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, + if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, &req, NULL, 0, 1000)) { DPRINTF("Set LATCH failed\n"); error = EIO; @@ -888,7 +902,7 @@ uslcom_control_callback(struct usb_xfer *xfer, usb_error_t error) USETW(req.wValue, 0); USETW(req.wIndex, sc->sc_iface_no); USETW(req.wLength, sizeof(buf)); - + usbd_xfer_set_frames(xfer, 2); usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); usbd_xfer_set_frame_len(xfer, 1, sizeof(buf)); |