1 /* $NetBSD: ukyopon.c,v 1.8 2007/10/19 12:01:22 ad Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 2005 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (lennart@augustsson.net) at 9 * Carlstedt Research & Technology. 10 * 11 * This code is derived from software contributed to The NetBSD Foundation 12 * by ITOH Yasufumi. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. All advertising materials mentioning features or use of this software 23 * must display the following acknowledgement: 24 * This product includes software developed by the NetBSD 25 * Foundation, Inc. and its contributors. 26 * 4. Neither the name of The NetBSD Foundation nor the names of its 27 * contributors may be used to endorse or promote products derived 28 * from this software without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 31 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 32 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 33 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 34 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 38 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 40 * POSSIBILITY OF SUCH DAMAGE. 41 */ 42 43 #include <sys/cdefs.h> 44 __KERNEL_RCSID(0, "$NetBSD: ukyopon.c,v 1.8 2007/10/19 12:01:22 ad Exp $"); 45 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/kernel.h> 49 #include <sys/ioctl.h> 50 #include <sys/conf.h> 51 #include <sys/tty.h> 52 #include <sys/file.h> 53 #include <sys/select.h> 54 #include <sys/proc.h> 55 #include <sys/vnode.h> 56 #include <sys/device.h> 57 #include <sys/poll.h> 58 59 #include <sys/bus.h> 60 61 #include <dev/usb/usb.h> 62 #include <dev/usb/usbcdc.h> 63 64 #include <dev/usb/usbdi.h> 65 #include <dev/usb/usbdi_util.h> 66 #include <dev/usb/usbdivar.h> 67 #include <dev/usb/usbdevs.h> 68 #include <dev/usb/usb_quirks.h> 69 70 #include <dev/usb/ucomvar.h> 71 #include <dev/usb/umodemvar.h> 72 #include <dev/usb/ukyopon.h> 73 74 #ifdef UKYOPON_DEBUG 75 #define DPRINTFN(n, x) if (ukyopondebug > (n)) logprintf x 76 int ukyopondebug = 0; 77 #else 78 #define DPRINTFN(n, x) 79 #endif 80 #define DPRINTF(x) DPRINTFN(0, x) 81 82 struct ukyopon_softc { 83 /* generic umodem device */ 84 struct umodem_softc sc_umodem; 85 86 /* ukyopon addition */ 87 }; 88 89 #define UKYOPON_MODEM_IFACE_INDEX 0 90 #define UKYOPON_DATA_IFACE_INDEX 3 91 92 Static void ukyopon_get_status(void *, int, u_char *, u_char *); 93 Static int ukyopon_ioctl(void *, int, u_long, void *, int, usb_proc_ptr); 94 95 Static struct ucom_methods ukyopon_methods = { 96 ukyopon_get_status, 97 umodem_set, 98 umodem_param, 99 ukyopon_ioctl, 100 umodem_open, 101 umodem_close, 102 NULL, 103 NULL, 104 }; 105 106 USB_DECLARE_DRIVER(ukyopon); 107 108 USB_MATCH(ukyopon) 109 { 110 USB_IFMATCH_START(ukyopon, uaa); 111 112 if (uaa->vendor == USB_VENDOR_KYOCERA && 113 uaa->product == USB_PRODUCT_KYOCERA_AHK3001V && 114 (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX || 115 uaa->ifaceno == UKYOPON_DATA_IFACE_INDEX)) 116 return (UMATCH_VENDOR_PRODUCT); 117 118 return (UMATCH_NONE); 119 } 120 121 USB_ATTACH(ukyopon) 122 { 123 USB_IFATTACH_START(ukyopon, sc, uaa); 124 struct ucom_attach_args uca; 125 126 uca.portno = (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX) ? 127 UKYOPON_PORT_MODEM : UKYOPON_PORT_DATA; 128 uca.methods = &ukyopon_methods; 129 uca.info = (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX) ? 130 "modem port" : "data transfer port"; 131 132 if (umodem_common_attach(self, &sc->sc_umodem, uaa, &uca)) 133 USB_ATTACH_ERROR_RETURN; 134 USB_ATTACH_SUCCESS_RETURN; 135 } 136 137 Static void 138 ukyopon_get_status(void *addr, int portno, u_char *lsr, u_char *msr) 139 { 140 struct ukyopon_softc *sc = addr; 141 142 /* 143 * The device doesn't set DCD (Data Carrier Detect) bit properly. 144 * Assume DCD is always present. 145 */ 146 if ((sc->sc_umodem.sc_msr & UMSR_DCD) == 0) 147 sc->sc_umodem.sc_msr |= UMSR_DCD; 148 149 return umodem_get_status(addr, portno, lsr, msr); 150 } 151 152 Static int 153 ukyopon_ioctl(void *addr, int portno, u_long cmd, void *data, int flag, 154 usb_proc_ptr p) 155 { 156 struct ukyopon_softc *sc = addr; 157 struct ukyopon_identify *arg_id = (void*)data; 158 int error = 0; 159 160 switch (cmd) { 161 case UKYOPON_IDENTIFY: 162 strncpy(arg_id->ui_name, UKYOPON_NAME, sizeof arg_id->ui_name); 163 arg_id->ui_busno = 164 USBDEVUNIT(*(device_ptr_t)sc->sc_umodem.sc_udev->bus->usbctl); 165 arg_id->ui_address = sc->sc_umodem.sc_udev->address; 166 arg_id->ui_model = UKYOPON_MODEL_UNKNOWN; 167 arg_id->ui_porttype = portno; 168 break; 169 170 default: 171 error = umodem_ioctl(addr, portno, cmd, data, flag, p); 172 break; 173 } 174 175 return (error); 176 } 177 178 #ifdef __strong_alias 179 __strong_alias(ukyopon_activate,umodem_common_activate) 180 #else 181 int 182 ukyopon_activate(device_ptr_t self, enum devact act) 183 { 184 struct ukyopon_softc *sc = (struct ukyopon_softc *)self; 185 186 return umodem_common_activate(&sc->sc_umodem, act); 187 } 188 #endif 189 190 USB_DETACH(ukyopon) 191 { 192 USB_DETACH_START(ukyopon, sc); 193 #ifdef __FreeBSD__ 194 int flags = 0; 195 #endif 196 197 return umodem_common_detach(&sc->sc_umodem, flags); 198 } 199