1 /* $NetBSD: ukyopon.c,v 1.4 2005/12/11 12:24:01 christos 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.4 2005/12/11 12:24:01 christos 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 <machine/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/usbdevs.h> 71 #include <dev/usb/ucomvar.h> 72 #include <dev/usb/umodemvar.h> 73 #include <dev/usb/ukyopon.h> 74 75 #ifdef UKYOPON_DEBUG 76 #define DPRINTFN(n, x) if (ukyopondebug > (n)) logprintf x 77 int ukyopondebug = 0; 78 #else 79 #define DPRINTFN(n, x) 80 #endif 81 #define DPRINTF(x) DPRINTFN(0, x) 82 83 struct ukyopon_softc { 84 /* generic umodem device */ 85 struct umodem_softc sc_umodem; 86 87 /* ukyopon addition */ 88 }; 89 90 #define UKYOPON_MODEM_IFACE_INDEX 0 91 #define UKYOPON_DATA_IFACE_INDEX 3 92 93 Static void ukyopon_get_status(void *, int, u_char *, u_char *); 94 Static int ukyopon_ioctl(void *, int, u_long, caddr_t, int, usb_proc_ptr); 95 96 Static struct ucom_methods ukyopon_methods = { 97 ukyopon_get_status, 98 umodem_set, 99 umodem_param, 100 ukyopon_ioctl, 101 umodem_open, 102 umodem_close, 103 NULL, 104 NULL, 105 }; 106 107 USB_DECLARE_DRIVER(ukyopon); 108 109 USB_MATCH(ukyopon) 110 { 111 USB_MATCH_START(ukyopon, uaa); 112 usb_device_descriptor_t *dd; 113 usb_interface_descriptor_t *id; 114 115 if (uaa->iface == NULL) 116 return (UMATCH_NONE); 117 118 id = usbd_get_interface_descriptor(uaa->iface); 119 dd = usbd_get_device_descriptor(uaa->device); 120 if (id == NULL || dd == NULL) 121 return (UMATCH_NONE); 122 123 if (UGETW(dd->idVendor) == USB_VENDOR_KYOCERA && 124 UGETW(dd->idProduct) == USB_PRODUCT_KYOCERA_AHK3001V && 125 (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX || 126 uaa->ifaceno == UKYOPON_DATA_IFACE_INDEX)) 127 return (UMATCH_VENDOR_PRODUCT); 128 129 return (UMATCH_NONE); 130 } 131 132 USB_ATTACH(ukyopon) 133 { 134 USB_ATTACH_START(ukyopon, sc, uaa); 135 struct ucom_attach_args uca; 136 137 uca.portno = (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX) ? 138 UKYOPON_PORT_MODEM : UKYOPON_PORT_DATA; 139 uca.methods = &ukyopon_methods; 140 uca.info = (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX) ? 141 "modem port" : "data transfer port"; 142 143 if (umodem_common_attach(self, &sc->sc_umodem, uaa, &uca)) 144 USB_ATTACH_ERROR_RETURN; 145 USB_ATTACH_SUCCESS_RETURN; 146 } 147 148 Static void 149 ukyopon_get_status(void *addr, int portno, u_char *lsr, u_char *msr) 150 { 151 struct ukyopon_softc *sc = addr; 152 153 /* 154 * The device doesn't set DCD (Data Carrier Detect) bit properly. 155 * Assume DCD is always present. 156 */ 157 if ((sc->sc_umodem.sc_msr & UMSR_DCD) == 0) 158 sc->sc_umodem.sc_msr |= UMSR_DCD; 159 160 return umodem_get_status(addr, portno, lsr, msr); 161 } 162 163 Static int 164 ukyopon_ioctl(void *addr, int portno, u_long cmd, caddr_t data, int flag, 165 usb_proc_ptr p) 166 { 167 struct ukyopon_softc *sc = addr; 168 struct ukyopon_identify *arg_id = (void*)data; 169 int error = 0; 170 171 switch (cmd) { 172 case UKYOPON_IDENTIFY: 173 strncpy(arg_id->ui_name, UKYOPON_NAME, sizeof arg_id->ui_name); 174 arg_id->ui_busno = 175 USBDEVUNIT(*(device_ptr_t)sc->sc_umodem.sc_udev->bus->usbctl); 176 arg_id->ui_address = sc->sc_umodem.sc_udev->address; 177 arg_id->ui_model = UKYOPON_MODEL_UNKNOWN; 178 arg_id->ui_porttype = portno; 179 break; 180 181 default: 182 error = umodem_ioctl(addr, portno, cmd, data, flag, p); 183 break; 184 } 185 186 return (error); 187 } 188 189 #ifdef __strong_alias 190 __strong_alias(ukyopon_activate,umodem_common_activate) 191 #else 192 int 193 ukyopon_activate(device_ptr_t self, enum devact act) 194 { 195 struct ukyopon_softc *sc = (struct ukyopon_softc *)self; 196 197 return umodem_common_activate(&sc->sc_umodem, act); 198 } 199 #endif 200 201 USB_DETACH(ukyopon) 202 { 203 USB_DETACH_START(ukyopon, sc); 204 #ifdef __FreeBSD__ 205 int flags = 0; 206 #endif 207 208 return umodem_common_detach(&sc->sc_umodem, flags); 209 } 210