Date: Thu, 8 Jan 2009 05:10:03 +0000 (UTC) From: Takanori Watanabe <takawata@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r186885 - head/sys/dev/usb2/serial Message-ID: <200901080510.n085A3eO009494@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: takawata Date: Thu Jan 8 05:10:03 2009 New Revision: 186885 URL: http://svn.freebsd.org/changeset/base/186885 Log: Make ufoma2 driver work. 1.Sync TD on close to ensure USB request in close callback issued. 2.Add sysctls to indicate device role. 3.Enable handsfree port support. Now modem port and obex port works well. Handsfree port works but not with good response. Modified: head/sys/dev/usb2/serial/ufoma2.c head/sys/dev/usb2/serial/usb2_serial.c Modified: head/sys/dev/usb2/serial/ufoma2.c ============================================================================== --- head/sys/dev/usb2/serial/ufoma2.c Thu Jan 8 04:26:44 2009 (r186884) +++ head/sys/dev/usb2/serial/ufoma2.c Thu Jan 8 05:10:03 2009 (r186885) @@ -2,6 +2,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#define UFOMA_HANDSFREE /*- * Copyright (c) 2005, Takanori Watanabe @@ -101,6 +102,8 @@ __FBSDID("$FreeBSD$"); #include <dev/usb2/core/usb2_busdma.h> #include <dev/usb2/serial/usb2_serial.h> +#include <sys/sysctl.h> +#include <sys/sbuf.h> typedef struct ufoma_mobile_acm_descriptor { uint8_t bFunctionLength; @@ -217,6 +220,12 @@ static void ufoma_stop_read(struct usb2_ static void ufoma_start_write(struct usb2_com_softc *); static void ufoma_stop_write(struct usb2_com_softc *); +/*sysctl stuff*/ +static int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS); +static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS); +static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS); + + static const struct usb2_config ufoma_ctrl_config[UFOMA_CTRL_ENDPT_MAX] = { @@ -380,6 +389,9 @@ ufoma_attach(device_t dev) struct ufoma_softc *sc = device_get_softc(dev); struct usb2_config_descriptor *cd; struct usb2_interface_descriptor *id; + struct sysctl_ctx_list *sctx; + struct sysctl_oid *soid; + usb2_mcpc_acm_descriptor *mad; uint8_t elements; int32_t error; @@ -459,6 +471,23 @@ ufoma_attach(device_t dev) DPRINTF("usb2_com_attach failed\n"); goto detach; } + /*Sysctls*/ + sctx = device_get_sysctl_ctx(dev); + soid = device_get_sysctl_tree(dev); + + SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "supportmode", + CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_support, + "A", "Supporting port role"); + + SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "currentmode", + CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_current, + "A", "Current port role"); + + SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "openmode", + CTLFLAG_RW|CTLTYPE_STRING, sc, 0, ufoma_sysctl_open, + "A", "Mode to transit when port is opened"); + + return (0); /* success */ detach: @@ -910,7 +939,8 @@ ufoma_cfg_set_break(struct usb2_com_soft struct usb2_device_request req; uint16_t wValue; - if (sc->sc_is_pseudo) { + if (sc->sc_is_pseudo || + (sc->sc_currentmode == UMCPC_ACM_MODE_OBEX)) { return; } if (!(sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK)) { @@ -1181,3 +1211,113 @@ ufoma_stop_write(struct usb2_com_softc * usb2_transfer_stop(sc->sc_bulk_xfer[0]); } } + +struct umcpc_modetostr_tab{ + int mode; + char *str; +}umcpc_modetostr_tab[]={ + {UMCPC_ACM_MODE_DEACTIVATED, "deactivated"}, + {UMCPC_ACM_MODE_MODEM, "modem"}, + {UMCPC_ACM_MODE_ATCOMMAND, "handsfree"}, + {UMCPC_ACM_MODE_OBEX, "obex"}, + {UMCPC_ACM_MODE_VENDOR1, "vendor1"}, + {UMCPC_ACM_MODE_VENDOR2, "vendor2"}, + {UMCPC_ACM_MODE_UNLINKED, "unlinked"}, + {0, NULL} +}; + +static char *ufoma_mode_to_str(int mode) +{ + int i; + for(i = 0 ;umcpc_modetostr_tab[i].str != NULL; i++){ + if(umcpc_modetostr_tab[i].mode == mode){ + return umcpc_modetostr_tab[i].str; + } + } + return NULL; +} + +static int ufoma_str_to_mode(char *str) +{ + int i; + for(i = 0 ;umcpc_modetostr_tab[i].str != NULL; i++){ + if(strcmp(str, umcpc_modetostr_tab[i].str)==0){ + return umcpc_modetostr_tab[i].mode; + } + } + return -1; +} + +static int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS) +{ + struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1; + struct sbuf sb; + int i; + char *mode; + + sbuf_new(&sb, NULL, 1, SBUF_AUTOEXTEND); + for(i = 1; i < sc->sc_modetable[0]; i++){ + mode = ufoma_mode_to_str(sc->sc_modetable[i]); + if(mode !=NULL){ + sbuf_cat(&sb, mode); + }else{ + sbuf_printf(&sb, "(%02x)", sc->sc_modetable[i]); + } + if(i < (sc->sc_modetable[0]-1)) + sbuf_cat(&sb, ","); + } + sbuf_trim(&sb); + sbuf_finish(&sb); + sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req); + sbuf_delete(&sb); + + return 0; +} +static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS) +{ + struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1; + char *mode; + char subbuf[]="(XXX)"; + mode = ufoma_mode_to_str(sc->sc_currentmode); + if(!mode){ + mode = subbuf; + snprintf(subbuf, sizeof(subbuf), "(%02x)", sc->sc_currentmode); + } + sysctl_handle_string(oidp, mode, strlen(mode), req); + + return 0; + +} +static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS) +{ + struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1; + char *mode; + char subbuf[40]; + int newmode; + int error; + int i; + + mode = ufoma_mode_to_str(sc->sc_modetoactivate); + if(mode){ + strncpy(subbuf, mode, sizeof(subbuf)); + }else{ + snprintf(subbuf, sizeof(subbuf), "(%02x)", sc->sc_modetoactivate); + } + error = sysctl_handle_string(oidp, subbuf, sizeof(subbuf), req); + if(error != 0 || req->newptr == NULL){ + return error; + } + + if((newmode = ufoma_str_to_mode(subbuf)) == -1){ + return EINVAL; + } + + for(i = 1 ; i < sc->sc_modetable[0] ; i++){ + if(sc->sc_modetable[i] == newmode){ + sc->sc_modetoactivate = newmode; + return 0; + } + } + + return EINVAL; +} Modified: head/sys/dev/usb2/serial/usb2_serial.c ============================================================================== --- head/sys/dev/usb2/serial/usb2_serial.c Thu Jan 8 04:26:44 2009 (r186884) +++ head/sys/dev/usb2/serial/usb2_serial.c Thu Jan 8 05:10:03 2009 (r186885) @@ -588,7 +588,8 @@ static void usb2_com_close(struct tty *tp) { struct usb2_com_softc *sc = tty_softc(tp); - + struct usb2_com_super_softc *ssc = sc->sc_super; + mtx_assert(sc->sc_parent_mtx, MA_OWNED); DPRINTF("tp=%p\n", tp); @@ -600,6 +601,7 @@ usb2_com_close(struct tty *tp) usb2_com_shutdown(sc); usb2_com_queue_command(sc, &usb2_com_cfg_close, 0); + usb2_config_td_sync(&ssc->sc_config_td); sc->sc_flag &= ~(UCOM_FLAG_HL_READY | UCOM_FLAG_WR_START |
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901080510.n085A3eO009494>