79#include <sys/stdint.h>
80#include <sys/stddef.h>
85#include <sys/kernel.h>
87#include <sys/module.h>
90#include <sys/condvar.h>
91#include <sys/sysctl.h>
93#include <sys/unistd.h>
94#include <sys/callout.h>
95#include <sys/malloc.h>
105#define USB_DEBUG_VAR usb_debug
119#define UISUBCLASS_MCPC 0x88
121#define UDESC_VS_INTERFACE 0x44
122#define UDESCSUB_MCPC_ACM 0x11
124#define UMCPC_ACM_TYPE_AB1 0x1
125#define UMCPC_ACM_TYPE_AB2 0x2
126#define UMCPC_ACM_TYPE_AB5 0x5
127#define UMCPC_ACM_TYPE_AB6 0x6
129#define UMCPC_ACM_MODE_DEACTIVATED 0x0
130#define UMCPC_ACM_MODE_MODEM 0x1
131#define UMCPC_ACM_MODE_ATCOMMAND 0x2
132#define UMCPC_ACM_MODE_OBEX 0x60
133#define UMCPC_ACM_MODE_VENDOR1 0xc0
134#define UMCPC_ACM_MODE_VENDOR2 0xfe
135#define UMCPC_ACM_MODE_UNLINKED 0xff
137#define UMCPC_CM_MOBILE_ACM 0x0
139#define UMCPC_ACTIVATE_MODE 0x60
140#define UMCPC_GET_MODETABLE 0x61
141#define UMCPC_SET_LINK 0x62
142#define UMCPC_CLEAR_LINK 0x63
144#define UMCPC_REQUEST_ACKNOWLEDGE 0x31
146#define UFOMA_MAX_TIMEOUT 15
147#define UFOMA_CMD_BUF_SIZE 64
149#define UFOMA_BULK_BUF_SIZE 1024
240 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
250 .flags = {.short_xfer_ok = 1,},
272 .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
281 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
349 if (
id == NULL || cd == NULL)
356#ifndef UFOMA_HANDSFREE
361 return (BUS_PROBE_GENERIC);
371 struct sysctl_ctx_list *sctx;
372 struct sysctl_oid *soid;
382 mtx_init(&sc->
sc_mtx,
"ufoma", NULL, MTX_DEF);
384 cv_init(&sc->
sc_cv,
"CWAIT");
402 device_printf(
dev,
"allocating control USB "
403 "transfers failed\n");
411 device_printf(
dev,
"invalid MAD descriptor\n");
428 sc->
sc_modetable = malloc(elements + 1, M_USBDEV, M_WAITOK);
448 DPRINTF(
"ucom_attach failed\n");
454 sctx = device_get_sysctl_ctx(
dev);
455 soid = device_get_sysctl_tree(
dev);
457 SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
"supportmode",
458 CTLFLAG_RD | CTLTYPE_STRING | CTLFLAG_MPSAFE, sc, 0,
461 SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
"currentmode",
462 CTLFLAG_RD | CTLTYPE_STRING | CTLFLAG_MPSAFE, sc, 0,
465 SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
"openmode",
466 CTLFLAG_RW | CTLTYPE_STRING | CTLFLAG_MPSAFE, sc, 0,
468 SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
"comunit",
470 "Unit number as USB serial");
491 cv_destroy(&sc->
sc_cv);
493 device_claim_softc(
dev);
507 device_free_softc(sc);
519 uint8_t type, uint8_t subtype)
528 (
desc->bDescriptorSubtype == subtype)) {
570 &
req, NULL, 0, 1000);
585 int len, aframes, nframes;
592 if (aframes != nframes)
688 DPRINTF(
"too short message\n");
691 if (actlen > (
int)
sizeof(pkt)) {
692 DPRINTF(
"truncating message\n");
693 actlen =
sizeof(pkt);
708 if (!(temp & 0xff)) {
709 DPRINTF(
"Mode change failed!\n");
711 cv_signal(&sc->
sc_cv);
719 DPRINTF(
"Wrong serial state!\n");
730 DPRINTF(
"Wrong serial state!\n");
738 DPRINTF(
"invalid notification "
739 "length, %d bytes!\n", actlen);
742 DPRINTF(
"notify bytes = 0x%02x, 0x%02x\n",
749 mstatus = pkt.
data[0];
892 &
req, NULL, 0, 1000);
922 &
req, NULL, 0, 1000);
976 memset(&ls, 0,
sizeof(ls));
980 if (t->c_cflag & CSTOPB) {
986 if (t->c_cflag & PARENB) {
987 if (t->c_cflag & PARODD) {
996 switch (t->c_cflag & CSIZE) {
1019 &
req, &ls, 0, 1000);
1039 if ((cmd == NULL) ||
1040 (cmd->
bLength <
sizeof(*cmd))) {
1048 if ((acm == NULL) ||
1049 (acm->
bLength <
sizeof(*acm))) {
1054 device_printf(
dev,
"data interface %d, has %sCM over data, "
1074 device_printf(
dev,
"no data interface\n");
1084 device_printf(
dev,
"allocating BULK USB "
1085 "transfers failed\n");
1190 sbuf_new(&sb, NULL, 1, SBUF_AUTOEXTEND);
1194 sbuf_cat(&sb, mode);
1203 sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb),
req);
1212 char subbuf[]=
"(XXX)";
1218 sysctl_handle_string(oidp, mode, strlen(mode),
req);
1234 strncpy(subbuf, mode,
sizeof(subbuf));
1238 error = sysctl_handle_string(oidp, subbuf,
sizeof(subbuf),
req);
1239 if(
error != 0 ||
req->newptr == NULL){
void(* ucom_cfg_get_status)(struct ucom_softc *, uint8_t *plsr, uint8_t *pmsr)
uint8_t bDescriptorSubtype
uint8_t sc_modetoactivate
struct usb_xfer * sc_bulk_xfer[UFOMA_BULK_ENDPT_MAX]
struct ucom_super_softc sc_super_ucom
struct usb_xfer * sc_ctrl_xfer[UFOMA_CTRL_ENDPT_MAX]
struct ucom_softc sc_ucom
uint8_t sc_ctrl_iface_index
struct usb_device * sc_udev
uint8_t sc_data_iface_index
enum usb_hc_mode usb_mode
struct usbd_lookup_info info
struct usb_interface * iface
struct usb_device * device
#define UMCPC_ACM_MODE_UNLINKED
#define UFOMA_CMD_BUF_SIZE
#define UMCPC_ACM_TYPE_AB6
static int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS)
#define UDESCSUB_MCPC_ACM
static usb_callback_t ufoma_ctrl_read_callback
static void ufoma_cfg_set_dtr(struct ucom_softc *, uint8_t)
static void ufoma_start_read(struct ucom_softc *)
#define UFOMA_BULK_BUF_SIZE
static int ufoma_pre_param(struct ucom_softc *, struct termios *)
static usb_callback_t ufoma_bulk_read_callback
static void ufoma_stop_read(struct ucom_softc *)
#define UDESC_VS_INTERFACE
static void ufoma_start_write(struct ucom_softc *)
#define UMCPC_ACM_MODE_VENDOR2
#define UMCPC_CM_MOBILE_ACM
#define UFOMA_MAX_TIMEOUT
#define UMCPC_ACTIVATE_MODE
static void ufoma_cfg_set_break(struct ucom_softc *, uint8_t)
static void ufoma_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *)
static void ufoma_cfg_close(struct ucom_softc *)
static void ufoma_stop_write(struct ucom_softc *)
static void ufoma_free(struct ucom_softc *)
static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS)
DRIVER_MODULE(ufoma, uhub, ufoma_driver, ufoma_devclass, NULL, 0)
static void ufoma_cfg_open(struct ucom_softc *)
#define UMCPC_REQUEST_ACKNOWLEDGE
MODULE_DEPEND(ufoma, ucom, 1, 1, 1)
static const struct ucom_callback ufoma_callback
static device_method_t ufoma_methods[]
static void * ufoma_get_intconf(struct usb_config_descriptor *, struct usb_interface_descriptor *, uint8_t, uint8_t)
static usb_callback_t ufoma_bulk_write_callback
static void ufoma_free_softc(struct ufoma_softc *)
#define UMCPC_ACM_MODE_MODEM
static device_probe_t ufoma_probe
static char * ufoma_mode_to_str(int mode)
static int ufoma_modem_setup(device_t, struct ufoma_softc *, struct usb_attach_arg *)
static void ufoma_cfg_activate_state(struct ufoma_softc *, uint16_t)
static driver_t ufoma_driver
#define UMCPC_ACM_TYPE_AB5
#define UMCPC_ACM_MODE_DEACTIVATED
static int ufoma_str_to_mode(char *str)
static devclass_t ufoma_devclass
static void ufoma_cfg_set_rts(struct ucom_softc *, uint8_t)
static device_detach_t ufoma_detach
static const STRUCT_USB_HOST_ID ufoma_devs[]
#define UMCPC_ACM_MODE_VENDOR1
static const struct usb_config ufoma_bulk_config[UFOMA_BULK_ENDPT_MAX]
static void ufoma_cfg_param(struct ucom_softc *, struct termios *)
static void ufoma_cfg_link_state(struct ufoma_softc *)
static device_attach_t ufoma_attach
static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS)
USB_PNP_HOST_INFO(ufoma_devs)
#define UMCPC_ACM_MODE_OBEX
static void ufoma_cfg_set_line_state(struct ufoma_softc *sc)
static const struct usb_config ufoma_ctrl_config[UFOMA_CTRL_ENDPT_MAX]
#define UMCPC_ACM_MODE_ATCOMMAND
static void ufoma_poll(struct ucom_softc *ucom)
static usb_callback_t ufoma_ctrl_write_callback
static usb_callback_t ufoma_intr_callback
struct ufoma_mobile_acm_descriptor usb_mcpc_acm_descriptor
#define UT_READ_CLASS_INTERFACE
#define UT_READ_VENDOR_INTERFACE
#define UT_WRITE_CLASS_INTERFACE
#define UT_WRITE_VENDOR_INTERFACE
#define UDESC_CS_INTERFACE
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)
#define UCDC_SEND_ENCAPSULATED_COMMAND
#define UCDC_N_SERIAL_STATE
#define UCDC_LINE_STATE_LENGTH
#define UCDC_N_SERIAL_DCD
#define UCDC_SET_LINE_CODING
#define UCDC_N_RESPONSE_AVAILABLE
#define UCDC_SET_CONTROL_LINE_STATE
#define USB_CDC_CM_OVER_DATA
#define UCDC_N_SERIAL_DSR
#define UCDC_GET_ENCAPSULATED_RESPONSE
#define USB_CDC_ACM_HAS_BREAK
#define UCDC_NOTIFICATION
struct usb_interface_descriptor * usbd_get_interface_descriptor(struct usb_interface *iface)
struct usb_config_descriptor * usbd_get_config_descriptor(struct usb_device *udev)
void usbd_set_parent_iface(struct usb_device *udev, uint8_t iface_index, uint8_t parent_index)
struct usb_interface * usbd_get_iface(struct usb_device *udev, uint8_t iface_index)
struct usb_endpoint_descriptor desc
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)
struct usb_descriptor * usb_desc_foreach(struct usb_config_descriptor *cd, struct usb_descriptor *_desc)
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)
usb_frlength_t usbd_xfer_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex)
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_IFACE_CLASS(ic)
#define USB_ST_TRANSFERRED
void() usb_callback_t(struct usb_xfer *, usb_error_t)
#define STRUCT_USB_HOST_ID
#define USB_GET_STATE(xfer)