28#include <sys/stdint.h>
29#include <sys/stddef.h>
34#include <sys/kernel.h>
36#include <sys/module.h>
39#include <sys/condvar.h>
40#include <sys/sysctl.h>
42#include <sys/unistd.h>
43#include <sys/callout.h>
44#include <sys/malloc.h>
53#define USB_DEBUG_VAR uslcom_debug
60static int uslcom_debug = 0;
62static SYSCTL_NODE(_hw_usb, OID_AUTO, uslcom, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
65 &uslcom_debug, 0,
"Debug level");
68#define USLCOM_BULK_BUF_SIZE 1024
69#define USLCOM_CONFIG_INDEX 0
72#define USLCOM_WRITE 0x41
73#define USLCOM_READ 0xc1
76#define USLCOM_IFC_ENABLE 0x00
77#define USLCOM_SET_BAUDDIV 0x01
78#define USLCOM_SET_LINE_CTL 0x03
79#define USLCOM_SET_BREAK 0x05
80#define USLCOM_SET_MHS 0x07
81#define USLCOM_GET_MDMSTS 0x08
82#define USLCOM_SET_FLOW 0x13
83#define USLCOM_SET_BAUDRATE 0x1e
84#define USLCOM_VENDOR_SPECIFIC 0xff
87#define USLCOM_IFC_ENABLE_DIS 0x00
88#define USLCOM_IFC_ENABLE_EN 0x01
91#define USLCOM_MHS_DTR_ON 0x0001
92#define USLCOM_MHS_DTR_SET 0x0100
93#define USLCOM_MHS_RTS_ON 0x0002
94#define USLCOM_MHS_RTS_SET 0x0200
95#define USLCOM_MHS_CTS 0x0010
96#define USLCOM_MHS_DSR 0x0020
97#define USLCOM_MHS_RI 0x0040
98#define USLCOM_MHS_DCD 0x0080
101#define USLCOM_BAUDDIV_REF 3686400
104#define USLCOM_STOP_BITS_1 0x00
105#define USLCOM_STOP_BITS_2 0x02
106#define USLCOM_PARITY_NONE 0x00
107#define USLCOM_PARITY_ODD 0x10
108#define USLCOM_PARITY_EVEN 0x20
109#define USLCOM_SET_DATA_BITS(x) ((x) << 8)
112#define USLCOM_SET_BREAK_OFF 0x00
113#define USLCOM_SET_BREAK_ON 0x01
116#define USLCOM_FLOW_DTR_ON 0x00000001
117#define USLCOM_FLOW_CTS_HS 0x00000008
119#define USLCOM_FLOW_RTS_ON 0x00000040
120#define USLCOM_FLOW_RTS_HS 0x00000080
123#define USLCOM_GET_PARTNUM 0x370B
124#define USLCOM_WRITE_LATCH 0x37E1
125#define USLCOM_READ_LATCH 0x00C2
128#define USLCOM_PARTNUM_CP2101 1
129#define USLCOM_PARTNUM_CP2102 2
130#define USLCOM_PARTNUM_CP2103 3
131#define USLCOM_PARTNUM_CP2104 4
132#define USLCOM_PARTNUM_CP2105 5
189 .flags = {.pipe_bof = 1,},
198 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
206 .flags = {.pipe_bof = 1,},
231#define USLCOM_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
360 USLCOM_DEV(WESTMOUNTAIN, RIGBLASTER_ADVANTAGE),
394 mtx_assert(&sc->
sc_mtx, MA_OWNED);
428 mtx_init(&sc->
sc_mtx,
"uslcom", NULL, MTX_DEF);
440 DPRINTF(
"one or more missing USB endpoints, "
478 device_claim_softc(
dev);
492 device_free_softc(sc);
515 &
req, NULL, 0, 1000)) {
516 DPRINTF(
"UART enable failed (ignored)\n");
539 &
req, NULL, 0, 1000)) {
540 DPRINTF(
"UART disable failed (ignored)\n");
556 USETW(
req.wLength,
sizeof(partnum));
559 &
req, &partnum, 0, NULL, 1000)) {
560 DPRINTF(
"GET_PARTNUM failed\n");
573 DPRINTF(
"onoff = %d\n", onoff);
585 &
req, NULL, 0, 1000)) {
586 DPRINTF(
"Setting DTR failed (ignored)\n");
597 DPRINTF(
"onoff = %d\n", onoff);
609 &
req, NULL, 0, 1000)) {
610 DPRINTF(
"Setting DTR failed (ignored)\n");
636 if (t->c_ospeed <= 0 || t->c_ospeed > maxspeed)
646 uint32_t baudrate, flowctrl[4];
651 baudrate = t->c_ospeed;
656 USETW(
req.wLength,
sizeof(baudrate));
659 &
req, &baudrate, 0, 1000)) {
660 printf(
"Set baudrate failed (ignored)\n");
663 if (t->c_cflag & CSTOPB)
667 if (t->c_cflag & PARENB) {
668 if (t->c_cflag & PARODD)
674 switch (t->c_cflag & CSIZE) {
696 &
req, NULL, 0, 1000)) {
697 DPRINTF(
"Set format failed (ignored)\n");
700 if (t->c_cflag & CRTSCTS) {
713 USETW(
req.wLength,
sizeof(flowctrl));
716 &
req, flowctrl, 0, 1000)) {
717 DPRINTF(
"Set flowcontrol failed (ignored)\n");
747 &
req, NULL, 0, 1000)) {
748 DPRINTF(
"Set BREAK failed (ignored)\n");
754 int flag,
struct thread *td)
776 &
req, &latch, 0, 1000)) {
780 *(
int *)
data = latch;
795 &
req, NULL, 0, 1000)) {
825 DPRINTF(
"actlen = %d\n", actlen);
895 DPRINTF(
"status change msr=0x%02x "
896 "(was 0x%02x)\n", msr, sc->
sc_msr);
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+")
void(* ucom_cfg_get_status)(struct ucom_softc *, uint8_t *plsr, uint8_t *pmsr)
enum usb_hc_mode usb_mode
struct usbd_lookup_info info
struct usb_device * device
struct ucom_softc sc_ucom
struct usb_callout sc_watchdog
struct ucom_super_softc sc_super_ucom
struct usb_xfer * sc_xfer[USLCOM_N_TRANSFER]
struct usb_device * sc_udev
void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len)
void usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
const char * usbd_errstr(usb_error_t err)
int usbd_lookup_id_by_uaa(const struct usb_device_id *id, usb_size_t sizeof_id, struct usb_attach_arg *uaa)
usb_error_t usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx, struct usb_device_request *req, void *data, uint16_t flags, uint16_t *actlen, usb_timeout_t timeout)
uint8_t ucom_get_data(struct ucom_softc *sc, struct usb_page_cache *pc, uint32_t offset, uint32_t len, uint32_t *actlen)
void ucom_status_change(struct ucom_softc *sc)
int ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc, int subunits, void *parent, const struct ucom_callback *callback, struct mtx *mtx)
int ucom_unref(struct ucom_super_softc *ssc)
void ucom_ref(struct ucom_super_softc *ssc)
void ucom_set_pnpinfo_usb(struct ucom_super_softc *ssc, device_t dev)
void ucom_detach(struct ucom_super_softc *ssc, struct ucom_softc *sc)
void ucom_put_data(struct ucom_softc *sc, struct usb_page_cache *pc, uint32_t offset, uint32_t len)
#define ucom_cfg_do_request(udev, com, req, ptr, flags, timo)
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_xfer_set_frames(struct usb_xfer *xfer, usb_frcount_t n)
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)
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)
#define usb_callout_init_mtx(c, m, f)
#define usb_callout_reset(c,...)
#define usb_callout_drain(c)
#define USB_ST_TRANSFERRED
void() usb_callback_t(struct usb_xfer *, usb_error_t)
#define STRUCT_USB_HOST_ID
#define usb_callout_stop(c)
#define USB_GET_STATE(xfer)
#define USLCOM_IFC_ENABLE
DRIVER_MODULE(uslcom, uhub, uslcom_driver, uslcom_devclass, NULL, 0)
#define USLCOM_CONFIG_INDEX
static void uslcom_cfg_set_rts(struct ucom_softc *, uint8_t)
static void uslcom_free_softc(struct uslcom_softc *)
#define USLCOM_SET_BREAK_OFF
static device_probe_t uslcom_probe
static void uslcom_free(struct ucom_softc *)
#define USLCOM_STOP_BITS_2
#define USLCOM_IFC_ENABLE_EN
static const STRUCT_USB_HOST_ID uslcom_devs[]
static void uslcom_cfg_param(struct ucom_softc *, struct termios *)
static void uslcom_cfg_set_dtr(struct ucom_softc *, uint8_t)
#define USLCOM_PARTNUM_CP2101
#define USLCOM_MHS_RTS_ON
static device_detach_t uslcom_detach
static int uslcom_ioctl(struct ucom_softc *, uint32_t, caddr_t, int, struct thread *)
#define USLCOM_SET_BREAK_ON
static int uslcom_pre_param(struct ucom_softc *, struct termios *)
#define USLCOM_MHS_RTS_SET
static const struct usb_config uslcom_config[USLCOM_N_TRANSFER]
#define USLCOM_PARTNUM_CP2105
#define USLCOM_GET_PARTNUM
static struct ucom_callback uslcom_callback
MODULE_VERSION(uslcom, 1)
#define USLCOM_PARITY_ODD
static uint8_t uslcom_get_partnum(struct uslcom_softc *)
#define USLCOM_PARITY_EVEN
static void uslcom_cfg_open(struct ucom_softc *)
static void uslcom_stop_read(struct ucom_softc *)
#define USLCOM_PARTNUM_CP2103
static usb_callback_t uslcom_write_callback
#define USLCOM_PARTNUM_CP2104
static void uslcom_cfg_set_break(struct ucom_softc *, uint8_t)
#define USLCOM_MHS_DTR_ON
static void uslcom_watchdog(void *arg)
UCOM_UNLOAD_DRAIN(uslcom)
#define USLCOM_FLOW_RTS_HS
static void uslcom_stop_write(struct ucom_softc *)
static void uslcom_poll(struct ucom_softc *ucom)
#define USLCOM_PARTNUM_CP2102
static device_attach_t uslcom_attach
#define USLCOM_PARITY_NONE
#define USLCOM_BULK_BUF_SIZE
#define USLCOM_WRITE_LATCH
#define USLCOM_FLOW_RTS_ON
#define USLCOM_GET_MDMSTS
static device_method_t uslcom_methods[]
USB_PNP_HOST_INFO(uslcom_devs)
static usb_callback_t uslcom_read_callback
#define USLCOM_FLOW_CTS_HS
#define USLCOM_VENDOR_SPECIFIC
#define USLCOM_FLOW_DTR_ON
static driver_t uslcom_driver
#define USLCOM_SET_LINE_CTL
MODULE_DEPEND(uslcom, ucom, 1, 1, 1)
#define USLCOM_SET_DATA_BITS(x)
static usb_callback_t uslcom_control_callback
#define USLCOM_IFC_ENABLE_DIS
#define USLCOM_SET_BAUDRATE
static devclass_t uslcom_devclass
#define USLCOM_READ_LATCH
static void uslcom_start_read(struct ucom_softc *)
static void uslcom_cfg_close(struct ucom_softc *)
#define USLCOM_MHS_DTR_SET
static void uslcom_start_write(struct ucom_softc *)
static void uslcom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *)
#define USLCOM_STOP_BITS_1