1 /* $NetBSD: ukyopon.c,v 1.11 2008/06/27 16:05:59 drochner 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 * 23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include <sys/cdefs.h> 37 __KERNEL_RCSID(0, "$NetBSD: ukyopon.c,v 1.11 2008/06/27 16:05:59 drochner Exp $"); 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/kernel.h> 42 #include <sys/ioctl.h> 43 #include <sys/conf.h> 44 #include <sys/tty.h> 45 #include <sys/file.h> 46 #include <sys/select.h> 47 #include <sys/proc.h> 48 #include <sys/vnode.h> 49 #include <sys/device.h> 50 #include <sys/poll.h> 51 52 #include <sys/bus.h> 53 54 #include <dev/usb/usb.h> 55 #include <dev/usb/usbcdc.h> 56 57 #include <dev/usb/usbdi.h> 58 #include <dev/usb/usbdi_util.h> 59 #include <dev/usb/usbdivar.h> 60 #include <dev/usb/usbdevs.h> 61 #include <dev/usb/usb_quirks.h> 62 63 #include <dev/usb/ucomvar.h> 64 #include <dev/usb/umodemvar.h> 65 #include <dev/usb/ukyopon.h> 66 67 #ifdef UKYOPON_DEBUG 68 #define DPRINTFN(n, x) if (ukyopondebug > (n)) logprintf x 69 int ukyopondebug = 0; 70 #else 71 #define DPRINTFN(n, x) 72 #endif 73 #define DPRINTF(x) DPRINTFN(0, x) 74 75 struct ukyopon_softc { 76 /* generic umodem device */ 77 struct umodem_softc sc_umodem; 78 79 /* ukyopon addition */ 80 }; 81 82 #define UKYOPON_MODEM_IFACE_INDEX 0 83 #define UKYOPON_DATA_IFACE_INDEX 3 84 85 Static void ukyopon_get_status(void *, int, u_char *, u_char *); 86 Static int ukyopon_ioctl(void *, int, u_long, void *, int, usb_proc_ptr); 87 88 Static struct ucom_methods ukyopon_methods = { 89 ukyopon_get_status, 90 umodem_set, 91 umodem_param, 92 ukyopon_ioctl, 93 umodem_open, 94 umodem_close, 95 NULL, 96 NULL, 97 }; 98 99 USB_DECLARE_DRIVER(ukyopon); 100 101 USB_MATCH(ukyopon) 102 { 103 USB_IFMATCH_START(ukyopon, uaa); 104 105 if (uaa->vendor == USB_VENDOR_KYOCERA && 106 uaa->product == USB_PRODUCT_KYOCERA_AHK3001V && 107 (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX || 108 uaa->ifaceno == UKYOPON_DATA_IFACE_INDEX)) 109 return (UMATCH_VENDOR_PRODUCT); 110 111 return (UMATCH_NONE); 112 } 113 114 USB_ATTACH(ukyopon) 115 { 116 USB_IFATTACH_START(ukyopon, sc, uaa); 117 struct ucom_attach_args uca; 118 119 uca.portno = (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX) ? 120 UKYOPON_PORT_MODEM : UKYOPON_PORT_DATA; 121 uca.methods = &ukyopon_methods; 122 uca.info = (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX) ? 123 "modem port" : "data transfer port"; 124 125 if (umodem_common_attach(self, &sc->sc_umodem, uaa, &uca)) 126 USB_ATTACH_ERROR_RETURN; 127 USB_ATTACH_SUCCESS_RETURN; 128 } 129 130 Static void 131 ukyopon_get_status(void *addr, int portno, u_char *lsr, u_char *msr) 132 { 133 struct ukyopon_softc *sc = addr; 134 135 /* 136 * The device doesn't set DCD (Data Carrier Detect) bit properly. 137 * Assume DCD is always present. 138 */ 139 if ((sc->sc_umodem.sc_msr & UMSR_DCD) == 0) 140 sc->sc_umodem.sc_msr |= UMSR_DCD; 141 142 return umodem_get_status(addr, portno, lsr, msr); 143 } 144 145 Static int 146 ukyopon_ioctl(void *addr, int portno, u_long cmd, void *data, int flag, 147 usb_proc_ptr p) 148 { 149 struct ukyopon_softc *sc = addr; 150 struct ukyopon_identify *arg_id = (void*)data; 151 int error = 0; 152 153 switch (cmd) { 154 case UKYOPON_IDENTIFY: 155 strncpy(arg_id->ui_name, UKYOPON_NAME, sizeof arg_id->ui_name); 156 arg_id->ui_busno = 157 USBDEVUNIT(sc->sc_umodem.sc_udev->bus->usbctl); 158 arg_id->ui_address = sc->sc_umodem.sc_udev->address; 159 arg_id->ui_model = UKYOPON_MODEL_UNKNOWN; 160 arg_id->ui_porttype = portno; 161 break; 162 163 default: 164 error = umodem_ioctl(addr, portno, cmd, data, flag, p); 165 break; 166 } 167 168 return (error); 169 } 170 171 int 172 ukyopon_activate(device_ptr_t self, enum devact act) 173 { 174 struct ukyopon_softc *sc = device_private(self); 175 176 return umodem_common_activate(&sc->sc_umodem, act); 177 } 178 179 USB_DETACH(ukyopon) 180 { 181 USB_DETACH_START(ukyopon, sc); 182 #ifdef __FreeBSD__ 183 int flags = 0; 184 #endif 185 186 return umodem_common_detach(&sc->sc_umodem, flags); 187 } 188