77#include <sys/stdint.h>
78#include <sys/stddef.h>
83#include <sys/kernel.h>
85#include <sys/module.h>
88#include <sys/condvar.h>
89#include <sys/sysctl.h>
91#include <sys/unistd.h>
92#include <sys/callout.h>
93#include <sys/malloc.h>
106#define USB_DEBUG_VAR umodem_debug
114static int umodem_debug = 0;
116static SYSCTL_NODE(_hw_usb, OID_AUTO, umodem, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
119 &umodem_debug, 0,
"Debug level");
152 {
USB_VPI(USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_AHK3001V, 1)},
153 {
USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, 1)},
154 {
USB_VPI(USB_VENDOR_CURITEL, USB_PRODUCT_CURITEL_PC5740, 1)},
165#define UMODEM_BUF_SIZE 1024
175#define UMODEM_MODVER 1
231 uint8_t, uint8_t *, uint8_t *);
240 .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
251 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
261 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,},
272 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,},
337 return (BUS_PROBE_GENERIC);
351 mtx_init(&sc->
sc_mtx,
"umodem", NULL, MTX_DEF);
364 if ((cmd == NULL) || (cmd->
bLength <
sizeof(*cmd))) {
369 if ((cud == NULL) || (cud->
bLength <
sizeof(*cud))) {
371 "Assuming data interface is next.\n");
375 uint8_t class_match = 0;
401 device_printf(
dev,
"data interface %d, has %sCM over "
402 "data, has %sbreak\n",
424 device_printf(
dev,
"no data interface\n");
448 device_printf(
dev,
"Can't setup transfer\n");
465 device_printf(
dev,
"Can't attach com\n");
479 uint8_t iface_index, uint8_t *p_data_no, uint8_t *p_match_class)
502 DPRINTFN(11,
"Match at index %u\n", iface_index);
504 *p_data_no =
id->bInterfaceNumber;
556 if ((cmd == NULL) || (cmd->
bLength <
sizeof(*cmd))) {
557 DPRINTF(
"no CM desc (faking one)\n");
563 if ((cad == NULL) || (cad->
bLength <
sizeof(*cad))) {
597 memset(&ls, 0,
sizeof(ls));
605 ((t->c_cflag & PARODD) ?
608 switch (t->c_cflag & CSIZE) {
623 DPRINTF(
"rate=%d fmt=%d parity=%d bits=%d\n",
640 int flag,
struct thread *td)
688 &
req, NULL, 0, 1000);
712 &
req, NULL, 0, 1000);
735 &
req, NULL, 0, 1000);
749 DPRINTF(
"Transferred %d bytes\n", actlen);
781 DPRINTF(
"received short packet, "
782 "%d bytes\n", actlen);
785 if (actlen > (
int)
sizeof(pkt)) {
786 DPRINTF(
"truncating message\n");
787 actlen =
sizeof(pkt);
799 DPRINTF(
"unknown message type, "
800 "0x%02x, on notify pipe!\n",
811 DPRINTF(
"invalid notification "
812 "length, %d bytes!\n", actlen);
815 DPRINTF(
"notify bytes = %02x%02x\n",
836 DPRINTF(
"unknown notify message: 0x%02x\n",
898 DPRINTF(
"actlen=%d\n", actlen);
923 type, 0xFF, subtype, 0xFF));
928 uint16_t feature, uint16_t state)
933 DPRINTF(
"feature=%d state=%d\n",
939 req.wIndex[0] = iface_no;
957 device_claim_softc(
dev);
971 device_free_softc(sc);
990 const void *preq,
void **
pptr, uint16_t *
plen,
995 uint8_t is_complete = *
pstate;
1003 (
req->wIndex[1] == 0x00) &&
1004 (
req->wValue[0] == 0x00) &&
1005 (
req->wValue[1] == 0x00)) {
1015 (
req->wIndex[1] == 0x00) &&
1026 (
req->wIndex[1] == 0x00) &&
1032 (
req->wIndex[1] == 0x00) &&
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)
uint8_t sc_abstract_state[32]
struct usb_xfer * sc_xfer[UMODEM_N_TRANSFER]
struct usb_device * sc_udev
struct ucom_super_softc sc_super_ucom
uint8_t sc_iface_index[2]
struct ucom_softc sc_ucom
uint8_t sc_line_coding[32]
enum usb_hc_mode usb_mode
struct usbd_lookup_info info
struct usb_device * device
static void umodem_cfg_set_dtr(struct ucom_softc *, uint8_t)
static int umodem_ioctl(struct ucom_softc *, uint32_t, caddr_t, int, struct thread *)
static void umodem_start_read(struct ucom_softc *)
static void umodem_cfg_set_break(struct ucom_softc *, uint8_t)
static driver_t umodem_driver
MODULE_DEPEND(umodem, ucom, 1, 1, 1)
static devclass_t umodem_devclass
static usb_callback_t umodem_write_callback
static void umodem_find_data_iface(struct usb_attach_arg *uaa, uint8_t, uint8_t *, uint8_t *)
USB_PNP_HOST_INFO(umodem_host_devs)
static int umodem_pre_param(struct ucom_softc *, struct termios *)
static void umodem_stop_write(struct ucom_softc *)
static void umodem_cfg_param(struct ucom_softc *, struct termios *)
static const struct usb_config umodem_config[UMODEM_N_TRANSFER]
static const STRUCT_USB_DUAL_ID umodem_dual_devs[]
static device_probe_t umodem_probe
static usb_error_t umodem_set_comm_feature(struct usb_device *, uint8_t, uint16_t, uint16_t)
static void * umodem_get_desc(struct usb_attach_arg *, uint8_t, uint8_t)
static void umodem_cfg_set_rts(struct ucom_softc *, uint8_t)
static usb_handle_request_t umodem_handle_request
static void umodem_stop_read(struct ucom_softc *)
static device_method_t umodem_methods[]
static void umodem_free(struct ucom_softc *)
DRIVER_MODULE(umodem, uhub, umodem_driver, umodem_devclass, NULL, 0)
static device_attach_t umodem_attach
static void umodem_poll(struct ucom_softc *ucom)
static device_detach_t umodem_detach
static void umodem_start_write(struct ucom_softc *)
static usb_callback_t umodem_intr_write_callback
static const struct ucom_callback umodem_callback
MODULE_VERSION(umodem, UMODEM_MODVER)
static void umodem_free_softc(struct umodem_softc *)
static usb_callback_t umodem_intr_read_callback
UCOM_UNLOAD_DRAIN(umodem)
static void umodem_get_caps(struct usb_attach_arg *, uint8_t *, uint8_t *)
static usb_callback_t umodem_read_callback
static void umodem_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *)
static const STRUCT_USB_HOST_ID umodem_host_devs[]
USB_PNP_DUAL_INFO(umodem_dual_devs)
#define UT_WRITE_CLASS_INTERFACE
#define UISUBCLASS_ABSTRACT_CONTROL_MODEL
#define UDESC_CS_INTERFACE
void usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
#define UCDC_DATA_MULTIPLEXED
#define UCDC_ABSTRACT_STATE
#define UCDC_N_SERIAL_STATE
#define UCDC_N_SERIAL_DCD
#define USB_CDC_ACM_HAS_FEATURE
#define UCDC_SET_LINE_CODING
#define UCDC_SET_CONTROL_LINE_STATE
#define USB_CDC_CM_OVER_DATA
#define UCDC_ABSTRACT_STATE_LENGTH
#define UDESCSUB_CDC_UNION
#define UCDC_N_SERIAL_DSR
#define USB_CDC_ACM_HAS_BREAK
#define UCDC_SET_COMM_FEATURE
#define USB_CDC_CM_DOES_CM
#define UCDC_NOTIFICATION
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)
void * usbd_find_descriptor(struct usb_device *udev, void *id, uint8_t iface_index, uint8_t type, uint8_t type_mask, uint8_t subtype, uint8_t subtype_mask)
struct usb_interface * usbd_get_iface(struct usb_device *udev, uint8_t iface_index)
static usb_error_t usb_handle_request(struct usb_xfer *)
#define USB_GET_CM_OVER_DATA
#define USB_SET_CM_OVER_DATA
int usbd_lookup_id_by_uaa(const struct usb_device_id *id, usb_size_t sizeof_id, struct usb_attach_arg *uaa)
uint8_t usb_test_quirk(const struct usb_attach_arg *uaa, uint16_t quirk)
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_set_usb_mode(struct ucom_super_softc *ssc, enum usb_hc_mode usb_mode)
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_IFACE_SUBCLASS(isc)
#define USB_PRODUCT(prod)
#define USB_IFACE_CLASS(ic)
#define USB_ST_TRANSFERRED
#define USB_IFACE_PROTOCOL(ip)
void() usb_callback_t(struct usb_xfer *, usb_error_t)
#define USB_VPI(vend, prod, info)
#define STRUCT_USB_HOST_ID
#define USB_GET_STATE(xfer)
#define usbd_do_request(u, m, r, d)
#define STRUCT_USB_DUAL_ID