82#include <sys/stdint.h>
83#include <sys/stddef.h>
88#include <sys/kernel.h>
90#include <sys/module.h>
93#include <sys/condvar.h>
94#include <sys/sysctl.h>
96#include <sys/unistd.h>
97#include <sys/callout.h>
98#include <sys/malloc.h>
107#define USB_DEBUG_VAR uplcom_debug
114static int uplcom_debug = 0;
116static SYSCTL_NODE(_hw_usb, OID_AUTO, uplcom, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
119 &uplcom_debug, 0,
"Debug level");
122#define UPLCOM_MODVER 1
124#define UPLCOM_CONFIG_INDEX 0
125#define UPLCOM_IFACE_INDEX 0
126#define UPLCOM_SECOND_IFACE_INDEX 1
128#ifndef UPLCOM_INTR_INTERVAL
129#define UPLCOM_INTR_INTERVAL 0
132#define UPLCOM_BULK_BUF_SIZE 1024
134#define UPLCOM_SET_REQUEST 0x01
135#define UPLCOM_SET_REQUEST_PL2303HXN 0x80
136#define UPLCOM_SET_CRTSCTS 0x41
137#define UPLCOM_SET_CRTSCTS_PL2303X 0x61
138#define UPLCOM_SET_CRTSCTS_PL2303HXN 0xFA
139#define UPLCOM_CLEAR_CRTSCTS_PL2303HXN 0xFF
140#define UPLCOM_CRTSCTS_REG_PL2303HXN 0x0A
141#define UPLCOM_STATUS_REG_PL2303HX 0x8080
142#define RSAQ_STATUS_CTS 0x80
143#define RSAQ_STATUS_OVERRUN_ERROR 0x40
144#define RSAQ_STATUS_PARITY_ERROR 0x20
145#define RSAQ_STATUS_FRAME_ERROR 0x10
146#define RSAQ_STATUS_RING 0x08
147#define RSAQ_STATUS_BREAK_ERROR 0x04
148#define RSAQ_STATUS_DSR 0x02
149#define RSAQ_STATUS_DCD 0x01
152#define TYPE_PL2303HX 1
153#define TYPE_PL2303HXD 2
154#define TYPE_PL2303HXN 3
156#define UPLCOM_STATE_INDEX 8
187 uint16_t, uint16_t, uint16_t);
218 .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
228 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
237 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
259#define UPLCOM_DEV(v,p) \
260 { USB_VENDOR(USB_VENDOR_##v), USB_PRODUCT(USB_PRODUCT_##v##_##p) }
390 mtx_init(&sc->
sc_mtx,
"uplcom", NULL, MTX_DEF);
450 DPRINTF(
"chiptype: 2303HX/TA\n");
453 DPRINTF(
"chiptype: 2303HXN\n");
456 DPRINTF(
"chiptype: 2303HXD/TB/RA/EA\n");
483 device_printf(
dev,
"no interface descriptor (2)\n");
499 DPRINTF(
"one or more missing USB endpoints, "
505 device_printf(
dev,
"reset failed, error=%s\n",
543 device_printf(
dev,
"init failed\n");
565 device_claim_softc(
dev);
579 device_free_softc(sc);
611 uint16_t value, uint16_t index, uint16_t length)
617 req.bmRequestType = req_type;
618 req.bRequest = request;
669 DPRINTF(
"onoff = %d\n", onoff);
684 &
req, NULL, 0, 1000);
693 DPRINTF(
"onoff = %d\n", onoff);
708 &
req, NULL, 0, 1000);
718 DPRINTF(
"onoff = %d\n", onoff);
730 &
req, NULL, 0, 1000);
748 75, 150, 300, 600, 900, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 14400,
749 19200, 28800, 38400, 56000, 57600, 115200,
754 128000, 134400, 161280, 201600, 230400, 268800, 403200, 460800, 614400,
755 806400, 921600, 1228800, 2457600, 3000000, 6000000,
762#define N_UPLCOM_RATES nitems(uplcom_rates)
792 if (t->c_ospeed & 0x80000000)
796 if (t->c_ospeed <= 12000000)
800 if (t->c_ospeed <= 12000000)
804 if (t->c_ospeed <= 6000000)
813 DPRINTF(
"uplcom_param: bad baud rate (%d)\n", t->c_ospeed);
820 unsigned int baseline, mantissa, exponent;
832 baseline = 383385600;
833 mantissa = baseline / baud;
837 while (mantissa >= 512) {
850 buf[1] = exponent << 1 | mantissa >> 8;
851 buf[0] = mantissa & 0xff;
854 baud = (baseline / mantissa) >> (exponent << 1);
855 DPRINTF(
"real baud rate will be %u\n", baud);
868 memset(&ls, 0,
sizeof(ls));
878 if (t->c_cflag & CSTOPB) {
879 if ((t->c_cflag & CSIZE) == CS5) {
892 if (t->c_cflag & PARENB) {
893 if (t->c_cflag & PARODD) {
902 switch (t->c_cflag & CSIZE) {
917 DPRINTF(
"rate=0x%08x fmt=%d parity=%d bits=%d\n",
931 if (t->c_cflag & CRTSCTS) {
950 &
req, NULL, 0, 1000);
965 &
req, NULL, 0, 1000);
1033 DPRINTF(
"actlen = %u\n", actlen);
1100 DPRINTF(
"actlen = %d\n", actlen);
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)
struct ucom_super_softc sc_super_ucom
struct usb_device * sc_udev
uint8_t sc_iface_index[2]
struct usb_xfer * sc_xfer[UPLCOM_N_TRANSFER]
struct ucom_softc sc_ucom
enum usb_hc_mode usb_mode
struct usbd_lookup_info info
struct usb_device * device
#define RSAQ_STATUS_BREAK_ERROR
static usb_callback_t uplcom_intr_callback
static driver_t uplcom_driver
static unsigned int uplcom_encode_baud_rate_divisor(uint8_t *buf, unsigned int baud)
static void uplcom_poll(struct ucom_softc *ucom)
static const struct usb_config uplcom_config_data[UPLCOM_N_TRANSFER]
static int uplcom_pre_param(struct ucom_softc *, struct termios *)
#define UPLCOM_STATE_INDEX
static int uplcom_pl2303_init(struct usb_device *, uint8_t)
static void uplcom_start_write(struct ucom_softc *)
#define UPLCOM_CONFIG_INDEX
#define RSAQ_STATUS_OVERRUN_ERROR
static void uplcom_stop_read(struct ucom_softc *)
static void uplcom_cfg_set_rts(struct ucom_softc *, uint8_t)
#define UPLCOM_SET_CRTSCTS_PL2303X
static device_method_t uplcom_methods[]
#define UPLCOM_BULK_BUF_SIZE
static struct ucom_callback uplcom_callback
#define UPLCOM_CRTSCTS_REG_PL2303HXN
#define UPLCOM_SET_CRTSCTS_PL2303HXN
DRIVER_MODULE(uplcom, uhub, uplcom_driver, uplcom_devclass, NULL, 0)
static usb_callback_t uplcom_read_callback
static const STRUCT_USB_HOST_ID uplcom_devs[]
#define UPLCOM_IFACE_INDEX
static devclass_t uplcom_devclass
static void uplcom_free_softc(struct uplcom_softc *)
static void uplcom_stop_write(struct ucom_softc *)
static usb_error_t uplcom_reset(struct uplcom_softc *, struct usb_device *)
#define UPLCOM_STATUS_REG_PL2303HX
MODULE_VERSION(uplcom, UPLCOM_MODVER)
static device_probe_t uplcom_probe
static void uplcom_cfg_set_break(struct ucom_softc *, uint8_t)
MODULE_DEPEND(uplcom, ucom, 1, 1, 1)
USB_PNP_HOST_INFO(uplcom_devs)
static void uplcom_free(struct ucom_softc *)
#define UPLCOM_SET_CRTSCTS
static usb_error_t uplcom_pl2303_do(struct usb_device *, uint8_t, uint8_t, uint16_t, uint16_t, uint16_t)
static usb_callback_t uplcom_write_callback
static device_detach_t uplcom_detach
static int uplcom_baud_supported(unsigned int speed)
#define RSAQ_STATUS_FRAME_ERROR
static void uplcom_start_read(struct ucom_softc *)
#define UPLCOM_CLEAR_CRTSCTS_PL2303HXN
static void uplcom_cfg_set_dtr(struct ucom_softc *, uint8_t)
#define UPLCOM_SET_REQUEST
static void uplcom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *)
#define UPLCOM_SECOND_IFACE_INDEX
static const uint32_t uplcom_rates[]
static device_attach_t uplcom_attach
#define RSAQ_STATUS_PARITY_ERROR
#define UPLCOM_SET_REQUEST_PL2303HXN
static void uplcom_cfg_param(struct ucom_softc *, struct termios *)
UCOM_UNLOAD_DRAIN(uplcom)
#define UT_WRITE_VENDOR_DEVICE
#define UT_READ_VENDOR_DEVICE
#define UT_WRITE_CLASS_INTERFACE
void usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
#define UCDC_LINE_STATE_LENGTH
#define UCDC_SET_LINE_CODING
#define UCDC_SET_CONTROL_LINE_STATE
#define UCDC_STOP_BIT_1_5
struct usb_interface_descriptor * usbd_get_interface_descriptor(struct usb_interface *iface)
void usbd_set_parent_iface(struct usb_device *udev, uint8_t iface_index, uint8_t parent_index)
struct usb_device_descriptor * usbd_get_device_descriptor(struct usb_device *udev)
struct usb_interface * usbd_get_iface(struct usb_device *udev, uint8_t iface_index)
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)
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_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_ST_TRANSFERRED
void() usb_callback_t(struct usb_xfer *, usb_error_t)
#define STRUCT_USB_HOST_ID
#define USB_GET_STATE(xfer)
#define usbd_do_request(u, m, r, d)