1 1.51 riastrad /* $NetBSD: ustir.c,v 1.51 2022/03/12 21:15:25 riastradh Exp $ */ 2 1.1 augustss 3 1.1 augustss /* 4 1.1 augustss * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 1.1 augustss * All rights reserved. 6 1.1 augustss * 7 1.1 augustss * This code is derived from software contributed to The NetBSD Foundation 8 1.42 dsainty * by David Sainty <dsainty (at) NetBSD.org> 9 1.1 augustss * 10 1.1 augustss * Redistribution and use in source and binary forms, with or without 11 1.1 augustss * modification, are permitted provided that the following conditions 12 1.1 augustss * are met: 13 1.1 augustss * 1. Redistributions of source code must retain the above copyright 14 1.1 augustss * notice, this list of conditions and the following disclaimer. 15 1.1 augustss * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 augustss * notice, this list of conditions and the following disclaimer in the 17 1.1 augustss * documentation and/or other materials provided with the distribution. 18 1.1 augustss * 19 1.1 augustss * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 augustss * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 augustss * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 augustss * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 augustss * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 augustss * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 augustss * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 augustss * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 augustss * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 augustss * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 augustss * POSSIBILITY OF SUCH DAMAGE. 30 1.1 augustss */ 31 1.1 augustss 32 1.1 augustss #include <sys/cdefs.h> 33 1.51 riastrad __KERNEL_RCSID(0, "$NetBSD: ustir.c,v 1.51 2022/03/12 21:15:25 riastradh Exp $"); 34 1.36 skrll 35 1.36 skrll #ifdef _KERNEL_OPT 36 1.36 skrll #include "opt_usb.h" 37 1.36 skrll #endif 38 1.1 augustss 39 1.1 augustss #include <sys/param.h> 40 1.1 augustss #include <sys/systm.h> 41 1.1 augustss #include <sys/kernel.h> 42 1.1 augustss #include <sys/device.h> 43 1.34 skrll #include <sys/kmem.h> 44 1.1 augustss #include <sys/conf.h> 45 1.1 augustss #include <sys/file.h> 46 1.1 augustss #include <sys/poll.h> 47 1.1 augustss #include <sys/select.h> 48 1.1 augustss #include <sys/proc.h> 49 1.1 augustss #include <sys/kthread.h> 50 1.1 augustss 51 1.1 augustss #ifdef USTIR_DEBUG_IOCTLS 52 1.1 augustss #include <sys/ioctl.h> 53 1.1 augustss #include <dev/usb/ustir.h> 54 1.1 augustss #endif 55 1.1 augustss 56 1.1 augustss #include <dev/usb/usb.h> 57 1.1 augustss #include <dev/usb/usbdevs.h> 58 1.1 augustss #include <dev/usb/usbdi.h> 59 1.1 augustss #include <dev/usb/usbdi_util.h> 60 1.1 augustss #include <dev/usb/ustirreg.h> 61 1.1 augustss 62 1.1 augustss #include <dev/ir/ir.h> 63 1.1 augustss #include <dev/ir/irdaio.h> 64 1.1 augustss #include <dev/ir/irframevar.h> 65 1.1 augustss #include <dev/ir/sir.h> 66 1.1 augustss 67 1.1 augustss #ifdef USTIR_DEBUG 68 1.29 dyoung #define DPRINTFN(n,x) if (ustirdebug>(n)) printf x 69 1.1 augustss int ustirdebug = 0; 70 1.1 augustss #else 71 1.1 augustss #define DPRINTFN(n,x) 72 1.1 augustss #endif 73 1.1 augustss 74 1.1 augustss /* Max size with framing. */ 75 1.1 augustss #define MAX_USTIR_OUTPUT_FRAME (2*IRDA_MAX_FRAME_SIZE + IRDA_MAX_EBOFS + STIR_OUTPUT_HEADER_SIZE + 4) 76 1.1 augustss 77 1.1 augustss #define USTIR_NSPEEDS 9 78 1.1 augustss struct ustir_speedrec { 79 1.1 augustss unsigned int speed; 80 1.1 augustss unsigned int config; 81 1.1 augustss }; 82 1.1 augustss 83 1.1 augustss Static struct ustir_speedrec const ustir_speeds[USTIR_NSPEEDS] = { 84 1.1 augustss { 4000000, STIR_BRMODE_4000000 }, 85 1.1 augustss { 1152000, STIR_BRMODE_1152000 }, 86 1.1 augustss { 576000, STIR_BRMODE_576000 }, 87 1.1 augustss { 115200, STIR_BRMODE_115200 }, 88 1.1 augustss { 57600, STIR_BRMODE_57600 }, 89 1.1 augustss { 38400, STIR_BRMODE_38400 }, 90 1.1 augustss { 19200, STIR_BRMODE_19200 }, 91 1.1 augustss { 9600, STIR_BRMODE_9600 }, 92 1.1 augustss { 2400, STIR_BRMODE_2400 } 93 1.1 augustss }; 94 1.1 augustss 95 1.1 augustss struct ustir_softc { 96 1.29 dyoung device_t sc_dev; 97 1.34 skrll struct usbd_device *sc_udev; 98 1.34 skrll struct usbd_interface *sc_iface; 99 1.41 maxv enum { 100 1.41 maxv USTIR_INIT_NONE, 101 1.41 maxv USTIR_INIT_INITED 102 1.41 maxv } sc_init_state; 103 1.1 augustss 104 1.34 skrll uint8_t *sc_ur_buf; /* Unencapsulated frame */ 105 1.1 augustss u_int sc_ur_framelen; 106 1.1 augustss 107 1.34 skrll uint8_t *sc_rd_buf; /* Raw incoming data stream */ 108 1.1 augustss size_t sc_rd_index; 109 1.1 augustss int sc_rd_addr; 110 1.34 skrll struct usbd_pipe *sc_rd_pipe; 111 1.34 skrll struct usbd_xfer *sc_rd_xfer; 112 1.1 augustss u_int sc_rd_count; 113 1.1 augustss int sc_rd_readinprogress; 114 1.1 augustss u_int sc_rd_expectdataticks; 115 1.1 augustss u_char sc_rd_err; 116 1.1 augustss struct framestate sc_framestate; 117 1.20 ad struct lwp *sc_thread; 118 1.1 augustss struct selinfo sc_rd_sel; 119 1.1 augustss 120 1.34 skrll uint8_t *sc_wr_buf; 121 1.1 augustss int sc_wr_addr; 122 1.10 dsainty int sc_wr_stalewrite; 123 1.34 skrll struct usbd_xfer *sc_wr_xfer; 124 1.34 skrll struct usbd_pipe *sc_wr_pipe; 125 1.1 augustss struct selinfo sc_wr_sel; 126 1.1 augustss 127 1.1 augustss enum { 128 1.1 augustss udir_input, /* Receiving data */ 129 1.1 augustss udir_output, /* Transmitting data */ 130 1.1 augustss udir_stalled, /* Error preventing data flow */ 131 1.1 augustss udir_idle /* Neither receiving nor transmitting */ 132 1.1 augustss } sc_direction; 133 1.1 augustss 134 1.1 augustss struct ustir_speedrec const *sc_speedrec; 135 1.1 augustss 136 1.26 cube device_t sc_child; 137 1.1 augustss struct irda_params sc_params; 138 1.1 augustss 139 1.1 augustss int sc_refcnt; 140 1.1 augustss char sc_closing; 141 1.1 augustss char sc_dying; 142 1.1 augustss }; 143 1.1 augustss 144 1.1 augustss /* True if we cannot safely read data from the device */ 145 1.1 augustss #define USTIR_BLOCK_RX_DATA(sc) ((sc)->sc_ur_framelen != 0) 146 1.1 augustss 147 1.1 augustss #define USTIR_WR_TIMEOUT 200 148 1.1 augustss 149 1.34 skrll Static int ustir_open(void *, int, int, struct lwp *); 150 1.34 skrll Static int ustir_close(void *, int, int, struct lwp *); 151 1.34 skrll Static int ustir_read(void *, struct uio *, int); 152 1.34 skrll Static int ustir_write(void *, struct uio *, int); 153 1.34 skrll Static int ustir_set_params(void *, struct irda_params *); 154 1.34 skrll Static int ustir_get_speeds(void *, int *); 155 1.34 skrll Static int ustir_get_turnarounds(void *, int *); 156 1.34 skrll Static int ustir_poll(void *, int, struct lwp *); 157 1.34 skrll Static int ustir_kqfilter(void *, struct knote *); 158 1.1 augustss 159 1.1 augustss #ifdef USTIR_DEBUG_IOCTLS 160 1.34 skrll Static int ustir_ioctl(void *, u_long, void *, int, struct lwp *); 161 1.1 augustss #endif 162 1.1 augustss 163 1.1 augustss Static struct irframe_methods const ustir_methods = { 164 1.1 augustss ustir_open, ustir_close, ustir_read, ustir_write, ustir_poll, 165 1.4 jdolecek ustir_kqfilter, ustir_set_params, ustir_get_speeds, 166 1.4 jdolecek ustir_get_turnarounds, 167 1.1 augustss #ifdef USTIR_DEBUG_IOCTLS 168 1.1 augustss ustir_ioctl 169 1.1 augustss #endif 170 1.1 augustss }; 171 1.1 augustss 172 1.34 skrll Static void ustir_rd_cb(struct usbd_xfer *, void *, usbd_status); 173 1.2 augustss Static usbd_status ustir_start_read(struct ustir_softc *); 174 1.2 augustss Static void ustir_periodic(struct ustir_softc *); 175 1.2 augustss Static void ustir_thread(void *); 176 1.1 augustss 177 1.1 augustss static usbd_status 178 1.34 skrll ustir_read_reg(struct ustir_softc *sc, unsigned int reg, uint8_t *data) 179 1.1 augustss { 180 1.1 augustss usb_device_request_t req; 181 1.1 augustss 182 1.1 augustss req.bmRequestType = UT_READ_VENDOR_DEVICE; 183 1.1 augustss req.bRequest = STIR_CMD_READMULTIREG; 184 1.1 augustss USETW(req.wValue, 0); 185 1.1 augustss USETW(req.wIndex, reg); 186 1.1 augustss USETW(req.wLength, 1); 187 1.1 augustss 188 1.1 augustss return usbd_do_request(sc->sc_udev, &req, data); 189 1.1 augustss } 190 1.1 augustss 191 1.1 augustss static usbd_status 192 1.34 skrll ustir_write_reg(struct ustir_softc *sc, unsigned int reg, uint8_t data) 193 1.1 augustss { 194 1.1 augustss usb_device_request_t req; 195 1.1 augustss 196 1.1 augustss req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 197 1.1 augustss req.bRequest = STIR_CMD_WRITESINGLEREG; 198 1.1 augustss USETW(req.wValue, data); 199 1.1 augustss USETW(req.wIndex, reg); 200 1.1 augustss USETW(req.wLength, 0); 201 1.1 augustss 202 1.1 augustss return usbd_do_request(sc->sc_udev, &req, NULL); 203 1.1 augustss } 204 1.1 augustss 205 1.1 augustss #ifdef USTIR_DEBUG 206 1.1 augustss static void 207 1.34 skrll ustir_dumpdata(uint8_t const *data, size_t dlen, char const *desc) 208 1.1 augustss { 209 1.1 augustss size_t bdindex; 210 1.1 augustss printf("%s: (%lx)", desc, (unsigned long)dlen); 211 1.1 augustss for (bdindex = 0; bdindex < dlen; bdindex++) 212 1.9 dsainty printf(" %02x", (unsigned int)data[bdindex]); 213 1.1 augustss printf("\n"); 214 1.1 augustss } 215 1.1 augustss #endif 216 1.1 augustss 217 1.43 maxv static int ustir_match(device_t, cfdata_t, void *); 218 1.43 maxv static void ustir_attach(device_t, device_t, void *); 219 1.43 maxv static void ustir_childdet(device_t, device_t); 220 1.43 maxv static int ustir_detach(device_t, int); 221 1.43 maxv static int ustir_activate(device_t, enum devact); 222 1.40 mrg 223 1.26 cube CFATTACH_DECL2_NEW(ustir, sizeof(struct ustir_softc), ustir_match, 224 1.22 dyoung ustir_attach, ustir_detach, ustir_activate, NULL, ustir_childdet); 225 1.1 augustss 226 1.43 maxv static int 227 1.29 dyoung ustir_match(device_t parent, cfdata_t match, void *aux) 228 1.1 augustss { 229 1.29 dyoung struct usb_attach_arg *uaa = aux; 230 1.1 augustss 231 1.1 augustss DPRINTFN(50,("ustir_match\n")); 232 1.1 augustss 233 1.34 skrll if (uaa->uaa_vendor == USB_VENDOR_SIGMATEL && 234 1.34 skrll uaa->uaa_product == USB_PRODUCT_SIGMATEL_IRDA) 235 1.1 augustss return UMATCH_VENDOR_PRODUCT; 236 1.1 augustss 237 1.1 augustss return UMATCH_NONE; 238 1.1 augustss } 239 1.1 augustss 240 1.43 maxv static void 241 1.29 dyoung ustir_attach(device_t parent, device_t self, void *aux) 242 1.1 augustss { 243 1.29 dyoung struct ustir_softc *sc = device_private(self); 244 1.29 dyoung struct usb_attach_arg *uaa = aux; 245 1.34 skrll struct usbd_device *dev = uaa->uaa_device; 246 1.34 skrll struct usbd_interface *iface; 247 1.14 augustss char *devinfop; 248 1.1 augustss usb_endpoint_descriptor_t *ed; 249 1.34 skrll uint8_t epcount; 250 1.1 augustss int i; 251 1.1 augustss struct ir_attach_args ia; 252 1.1 augustss 253 1.1 augustss DPRINTFN(10,("ustir_attach: sc=%p\n", sc)); 254 1.1 augustss 255 1.26 cube sc->sc_dev = self; 256 1.41 maxv sc->sc_init_state = USTIR_INIT_NONE; 257 1.26 cube 258 1.27 plunky aprint_naive("\n"); 259 1.27 plunky aprint_normal("\n"); 260 1.27 plunky 261 1.14 augustss devinfop = usbd_devinfo_alloc(dev, 0); 262 1.26 cube aprint_normal_dev(self, "%s\n", devinfop); 263 1.14 augustss usbd_devinfo_free(devinfop); 264 1.1 augustss 265 1.19 drochner if (usbd_set_config_index(dev, 0, 1) 266 1.19 drochner || usbd_device2interface_handle(dev, 0, &iface)) { 267 1.26 cube aprint_error_dev(self, "Configuration failed\n"); 268 1.29 dyoung return; 269 1.19 drochner } 270 1.19 drochner 271 1.1 augustss sc->sc_udev = dev; 272 1.1 augustss sc->sc_iface = iface; 273 1.1 augustss 274 1.1 augustss epcount = 0; 275 1.1 augustss (void)usbd_endpoint_count(iface, &epcount); 276 1.1 augustss 277 1.1 augustss sc->sc_rd_addr = -1; 278 1.1 augustss sc->sc_wr_addr = -1; 279 1.1 augustss for (i = 0; i < epcount; i++) { 280 1.1 augustss ed = usbd_interface2endpoint_descriptor(iface, i); 281 1.1 augustss if (ed == NULL) { 282 1.26 cube aprint_error_dev(self, "couldn't get ep %d\n", i); 283 1.29 dyoung return; 284 1.1 augustss } 285 1.1 augustss if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 286 1.1 augustss UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 287 1.1 augustss sc->sc_rd_addr = ed->bEndpointAddress; 288 1.1 augustss } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 289 1.1 augustss UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 290 1.1 augustss sc->sc_wr_addr = ed->bEndpointAddress; 291 1.1 augustss } 292 1.1 augustss } 293 1.1 augustss if (sc->sc_rd_addr == -1 || sc->sc_wr_addr == -1) { 294 1.26 cube aprint_error_dev(self, "missing endpoint\n"); 295 1.29 dyoung return; 296 1.1 augustss } 297 1.1 augustss 298 1.1 augustss DPRINTFN(10, ("ustir_attach: %p\n", sc->sc_udev)); 299 1.1 augustss 300 1.35 msaitoh usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 301 1.1 augustss 302 1.1 augustss ia.ia_type = IR_TYPE_IRFRAME; 303 1.1 augustss ia.ia_methods = &ustir_methods; 304 1.1 augustss ia.ia_handle = sc; 305 1.1 augustss 306 1.49 thorpej sc->sc_child = config_found(self, &ia, ir_print, CFARGS_NONE); 307 1.23 rmind selinit(&sc->sc_rd_sel); 308 1.23 rmind selinit(&sc->sc_wr_sel); 309 1.41 maxv sc->sc_init_state = USTIR_INIT_INITED; 310 1.1 augustss 311 1.29 dyoung return; 312 1.1 augustss } 313 1.1 augustss 314 1.43 maxv static void 315 1.22 dyoung ustir_childdet(device_t self, device_t child) 316 1.22 dyoung { 317 1.22 dyoung struct ustir_softc *sc = device_private(self); 318 1.22 dyoung 319 1.22 dyoung KASSERT(sc->sc_child == child); 320 1.22 dyoung sc->sc_child = NULL; 321 1.22 dyoung } 322 1.22 dyoung 323 1.43 maxv static int 324 1.29 dyoung ustir_detach(device_t self, int flags) 325 1.1 augustss { 326 1.29 dyoung struct ustir_softc *sc = device_private(self); 327 1.1 augustss int s; 328 1.1 augustss int rv = 0; 329 1.1 augustss 330 1.1 augustss DPRINTFN(0, ("ustir_detach: sc=%p flags=%d\n", sc, flags)); 331 1.1 augustss 332 1.1 augustss sc->sc_closing = sc->sc_dying = 1; 333 1.1 augustss 334 1.1 augustss wakeup(&sc->sc_thread); 335 1.1 augustss 336 1.1 augustss while (sc->sc_thread != NULL) 337 1.1 augustss tsleep(&sc->sc_closing, PWAIT, "usircl", 0); 338 1.1 augustss 339 1.1 augustss /* Abort all pipes. Causes processes waiting for transfer to wake. */ 340 1.1 augustss if (sc->sc_rd_pipe != NULL) { 341 1.1 augustss usbd_abort_pipe(sc->sc_rd_pipe); 342 1.34 skrll } 343 1.34 skrll if (sc->sc_wr_pipe != NULL) { 344 1.34 skrll usbd_abort_pipe(sc->sc_wr_pipe); 345 1.34 skrll } 346 1.34 skrll if (sc->sc_rd_xfer != NULL) { 347 1.34 skrll usbd_destroy_xfer(sc->sc_rd_xfer); 348 1.34 skrll sc->sc_rd_xfer = NULL; 349 1.34 skrll sc->sc_rd_buf = NULL; 350 1.34 skrll } 351 1.34 skrll if (sc->sc_wr_xfer != NULL) { 352 1.34 skrll usbd_destroy_xfer(sc->sc_wr_xfer); 353 1.34 skrll sc->sc_wr_xfer = NULL; 354 1.34 skrll sc->sc_wr_buf = NULL; 355 1.34 skrll } 356 1.34 skrll if (sc->sc_rd_pipe != NULL) { 357 1.1 augustss usbd_close_pipe(sc->sc_rd_pipe); 358 1.1 augustss sc->sc_rd_pipe = NULL; 359 1.1 augustss } 360 1.1 augustss if (sc->sc_wr_pipe != NULL) { 361 1.1 augustss usbd_close_pipe(sc->sc_wr_pipe); 362 1.1 augustss sc->sc_wr_pipe = NULL; 363 1.1 augustss } 364 1.1 augustss wakeup(&sc->sc_ur_framelen); 365 1.1 augustss wakeup(&sc->sc_wr_buf); 366 1.1 augustss 367 1.1 augustss s = splusb(); 368 1.1 augustss if (--sc->sc_refcnt >= 0) { 369 1.1 augustss /* Wait for processes to go away. */ 370 1.32 mrg usb_detach_waitold(sc->sc_dev); 371 1.1 augustss } 372 1.1 augustss splx(s); 373 1.1 augustss 374 1.22 dyoung if (sc->sc_child != NULL) 375 1.1 augustss rv = config_detach(sc->sc_child, flags); 376 1.1 augustss 377 1.41 maxv if (sc->sc_init_state >= USTIR_INIT_INITED) { 378 1.41 maxv usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 379 1.41 maxv sc->sc_dev); 380 1.41 maxv seldestroy(&sc->sc_rd_sel); 381 1.41 maxv seldestroy(&sc->sc_wr_sel); 382 1.41 maxv } 383 1.23 rmind 384 1.1 augustss return rv; 385 1.1 augustss } 386 1.1 augustss 387 1.1 augustss /* Returns 0 if more data required, 1 if a complete frame was extracted */ 388 1.1 augustss static int 389 1.1 augustss deframe_rd_ur(struct ustir_softc *sc) 390 1.1 augustss { 391 1.1 augustss while (sc->sc_rd_index < sc->sc_rd_count) { 392 1.34 skrll uint8_t const *buf; 393 1.1 augustss size_t buflen; 394 1.1 augustss enum frameresult fresult; 395 1.1 augustss 396 1.1 augustss buf = &sc->sc_rd_buf[sc->sc_rd_index]; 397 1.1 augustss buflen = sc->sc_rd_count - sc->sc_rd_index; 398 1.1 augustss 399 1.1 augustss fresult = deframe_process(&sc->sc_framestate, &buf, &buflen); 400 1.1 augustss 401 1.1 augustss sc->sc_rd_index = sc->sc_rd_count - buflen; 402 1.1 augustss 403 1.3 augustss DPRINTFN(1,("%s: result=%d\n", __func__, (int)fresult)); 404 1.1 augustss 405 1.1 augustss switch (fresult) { 406 1.1 augustss case FR_IDLE: 407 1.1 augustss case FR_INPROGRESS: 408 1.1 augustss case FR_FRAMEBADFCS: 409 1.1 augustss case FR_FRAMEMALFORMED: 410 1.1 augustss case FR_BUFFEROVERRUN: 411 1.1 augustss break; 412 1.1 augustss case FR_FRAMEOK: 413 1.1 augustss sc->sc_ur_framelen = sc->sc_framestate.bufindex; 414 1.1 augustss wakeup(&sc->sc_ur_framelen); /* XXX should use flag */ 415 1.23 rmind selnotify(&sc->sc_rd_sel, 0, 0); 416 1.1 augustss return 1; 417 1.1 augustss } 418 1.1 augustss } 419 1.1 augustss 420 1.1 augustss /* Reset indices into USB-side buffer */ 421 1.1 augustss sc->sc_rd_index = sc->sc_rd_count = 0; 422 1.1 augustss 423 1.1 augustss return 0; 424 1.1 augustss } 425 1.1 augustss 426 1.1 augustss /* 427 1.1 augustss * Direction transitions: 428 1.1 augustss * 429 1.1 augustss * ustir_periodic() can switch the direction from: 430 1.1 augustss * 431 1.1 augustss * output -> idle 432 1.1 augustss * output -> stalled 433 1.1 augustss * stalled -> idle 434 1.1 augustss * idle -> input 435 1.1 augustss * 436 1.1 augustss * ustir_rd_cb() can switch the direction from: 437 1.1 augustss * 438 1.1 augustss * input -> stalled 439 1.1 augustss * input -> idle 440 1.1 augustss * 441 1.1 augustss * ustir_write() can switch the direction from: 442 1.1 augustss * 443 1.1 augustss * idle -> output 444 1.1 augustss */ 445 1.1 augustss Static void 446 1.1 augustss ustir_periodic(struct ustir_softc *sc) 447 1.1 augustss { 448 1.1 augustss DPRINTFN(60, ("%s: direction = %d\n", 449 1.3 augustss __func__, sc->sc_direction)); 450 1.1 augustss 451 1.1 augustss if (sc->sc_direction == udir_output || 452 1.1 augustss sc->sc_direction == udir_stalled) { 453 1.1 augustss usbd_status err; 454 1.34 skrll uint8_t regval; 455 1.1 augustss 456 1.1 augustss DPRINTFN(60, ("%s: reading status register\n", 457 1.3 augustss __func__)); 458 1.1 augustss 459 1.1 augustss err = ustir_read_reg(sc, STIR_REG_STATUS, 460 1.1 augustss ®val); 461 1.8 dsainty if (err != USBD_NORMAL_COMPLETION) { 462 1.26 cube aprint_error_dev(sc->sc_dev, 463 1.26 cube "status register read failed: %s\n", 464 1.26 cube usbd_errstr(err)); 465 1.1 augustss } else { 466 1.45 christos DPRINTFN(10, ("%s: status register = %#x\n", 467 1.3 augustss __func__, 468 1.1 augustss (unsigned int)regval)); 469 1.1 augustss if (sc->sc_direction == udir_output && 470 1.1 augustss !(regval & STIR_RSTATUS_FFDIR)) 471 1.1 augustss /* Output has completed */ 472 1.1 augustss sc->sc_direction = udir_idle; 473 1.1 augustss if (regval & STIR_RSTATUS_FFOVER) { 474 1.1 augustss /* 475 1.1 augustss * On an overrun the FIFO hangs, and 476 1.1 augustss * any data bulk transfers will stall. 477 1.1 augustss * Reset the FIFO. 478 1.1 augustss */ 479 1.1 augustss sc->sc_direction = udir_stalled; 480 1.1 augustss 481 1.1 augustss DPRINTFN(10, ("%s: clearing FIFO error\n", 482 1.3 augustss __func__)); 483 1.1 augustss 484 1.1 augustss err = ustir_write_reg(sc, STIR_REG_STATUS, 485 1.1 augustss STIR_RSTATUS_FFCLR); 486 1.1 augustss /* XXX if we fail partway through 487 1.1 augustss * this, we may not recover? */ 488 1.8 dsainty if (err == USBD_NORMAL_COMPLETION) 489 1.1 augustss err = ustir_write_reg(sc, 490 1.1 augustss STIR_REG_STATUS, 491 1.1 augustss 0); 492 1.8 dsainty if (err != USBD_NORMAL_COMPLETION) { 493 1.26 cube aprint_error_dev(sc->sc_dev, 494 1.26 cube "FIFO reset failed: %s\n", 495 1.26 cube usbd_errstr(err)); 496 1.1 augustss } else { 497 1.1 augustss /* FIFO reset */ 498 1.1 augustss sc->sc_direction = udir_idle; 499 1.1 augustss } 500 1.1 augustss } 501 1.1 augustss } 502 1.1 augustss } 503 1.1 augustss 504 1.10 dsainty if (sc->sc_wr_stalewrite && sc->sc_direction == udir_idle) { 505 1.10 dsainty /* 506 1.10 dsainty * In a stale write case, we need to check if the 507 1.10 dsainty * write has completed. Once that has happened, the 508 1.10 dsainty * write is no longer stale. 509 1.10 dsainty * 510 1.10 dsainty * But note that we may immediately start a read poll... 511 1.10 dsainty */ 512 1.10 dsainty sc->sc_wr_stalewrite = 0; 513 1.10 dsainty wakeup(&sc->sc_wr_buf); 514 1.10 dsainty } 515 1.10 dsainty 516 1.1 augustss if (!sc->sc_rd_readinprogress && 517 1.1 augustss (sc->sc_direction == udir_idle || 518 1.1 augustss sc->sc_direction == udir_input)) 519 1.1 augustss /* Do a read poll if appropriate... */ 520 1.1 augustss ustir_start_read(sc); 521 1.1 augustss } 522 1.1 augustss 523 1.1 augustss Static void 524 1.1 augustss ustir_thread(void *arg) 525 1.1 augustss { 526 1.1 augustss struct ustir_softc *sc = arg; 527 1.1 augustss 528 1.3 augustss DPRINTFN(20, ("%s: starting polling thread\n", __func__)); 529 1.1 augustss 530 1.1 augustss while (!sc->sc_closing) { 531 1.1 augustss if (!sc->sc_rd_readinprogress && !USTIR_BLOCK_RX_DATA(sc)) 532 1.1 augustss ustir_periodic(sc); 533 1.1 augustss 534 1.1 augustss if (!sc->sc_closing) { 535 1.1 augustss int error; 536 1.1 augustss error = tsleep(&sc->sc_thread, PWAIT, 537 1.1 augustss "ustir", hz / 10); 538 1.1 augustss if (error == EWOULDBLOCK && 539 1.1 augustss sc->sc_rd_expectdataticks > 0) 540 1.1 augustss /* 541 1.1 augustss * After a timeout decrement the tick 542 1.1 augustss * counter within which time we expect 543 1.1 augustss * data to arrive if we are receiving 544 1.1 augustss * data... 545 1.1 augustss */ 546 1.1 augustss sc->sc_rd_expectdataticks--; 547 1.1 augustss } 548 1.1 augustss } 549 1.1 augustss 550 1.3 augustss DPRINTFN(20, ("%s: exiting polling thread\n", __func__)); 551 1.1 augustss 552 1.1 augustss sc->sc_thread = NULL; 553 1.1 augustss 554 1.1 augustss wakeup(&sc->sc_closing); 555 1.1 augustss 556 1.1 augustss if (--sc->sc_refcnt < 0) 557 1.32 mrg usb_detach_wakeupold(sc->sc_dev); 558 1.1 augustss 559 1.1 augustss kthread_exit(0); 560 1.1 augustss } 561 1.1 augustss 562 1.1 augustss Static void 563 1.34 skrll ustir_rd_cb(struct usbd_xfer *xfer, void *priv, 564 1.1 augustss usbd_status status) 565 1.1 augustss { 566 1.1 augustss struct ustir_softc *sc = priv; 567 1.34 skrll uint32_t size; 568 1.1 augustss 569 1.3 augustss DPRINTFN(60, ("%s: sc=%p\n", __func__, sc)); 570 1.1 augustss 571 1.1 augustss /* Read is no longer in progress */ 572 1.1 augustss sc->sc_rd_readinprogress = 0; 573 1.1 augustss 574 1.1 augustss if (status == USBD_CANCELLED || sc->sc_closing) /* this is normal */ 575 1.1 augustss return; 576 1.1 augustss if (status) { 577 1.1 augustss size = 0; 578 1.1 augustss sc->sc_rd_err = 1; 579 1.1 augustss 580 1.1 augustss if (sc->sc_direction == udir_input || 581 1.1 augustss sc->sc_direction == udir_idle) { 582 1.1 augustss /* 583 1.1 augustss * Receive error, probably need to clear error 584 1.1 augustss * condition. 585 1.1 augustss */ 586 1.1 augustss sc->sc_direction = udir_stalled; 587 1.1 augustss } 588 1.1 augustss } else { 589 1.1 augustss usbd_get_xfer_status(xfer, NULL, NULL, &size, NULL); 590 1.1 augustss } 591 1.1 augustss 592 1.1 augustss sc->sc_rd_index = 0; 593 1.1 augustss sc->sc_rd_count = size; 594 1.1 augustss 595 1.1 augustss DPRINTFN(((size > 0 || sc->sc_rd_err != 0) ? 20 : 60), 596 1.3 augustss ("%s: sc=%p size=%u, err=%d\n", __func__, 597 1.1 augustss sc, size, sc->sc_rd_err)); 598 1.1 augustss 599 1.1 augustss #ifdef USTIR_DEBUG 600 1.1 augustss if (ustirdebug >= 20 && size > 0) 601 1.3 augustss ustir_dumpdata(sc->sc_rd_buf, size, __func__); 602 1.1 augustss #endif 603 1.1 augustss 604 1.1 augustss if (!deframe_rd_ur(sc)) { 605 1.1 augustss if (!deframe_isclear(&sc->sc_framestate) && size == 0 && 606 1.1 augustss sc->sc_rd_expectdataticks == 0) { 607 1.1 augustss /* 608 1.1 augustss * Expected data, but didn't get it 609 1.1 augustss * within expected time... 610 1.1 augustss */ 611 1.1 augustss DPRINTFN(5,("%s: incoming packet timeout\n", 612 1.3 augustss __func__)); 613 1.1 augustss deframe_clear(&sc->sc_framestate); 614 1.1 augustss } else if (size > 0) { 615 1.1 augustss /* 616 1.1 augustss * If we also received actual data, reset the 617 1.1 augustss * data read timeout and wake up the possibly 618 1.1 augustss * sleeping thread... 619 1.1 augustss */ 620 1.1 augustss sc->sc_rd_expectdataticks = 2; 621 1.1 augustss wakeup(&sc->sc_thread); 622 1.1 augustss } 623 1.1 augustss } 624 1.1 augustss 625 1.1 augustss /* 626 1.1 augustss * Check if incoming data has stopped, or that we cannot 627 1.1 augustss * safely read any more data. In the case of the latter we 628 1.1 augustss * must switch to idle so that a write will not block... 629 1.1 augustss */ 630 1.1 augustss if (sc->sc_direction == udir_input && 631 1.1 augustss ((size == 0 && sc->sc_rd_expectdataticks == 0) || 632 1.1 augustss USTIR_BLOCK_RX_DATA(sc))) { 633 1.10 dsainty DPRINTFN(8,("%s: idling on packet timeout, " 634 1.10 dsainty "complete frame, or no data\n", __func__)); 635 1.1 augustss sc->sc_direction = udir_idle; 636 1.1 augustss 637 1.1 augustss /* Wake up for possible output */ 638 1.1 augustss wakeup(&sc->sc_wr_buf); 639 1.23 rmind selnotify(&sc->sc_wr_sel, 0, 0); 640 1.1 augustss } 641 1.1 augustss } 642 1.1 augustss 643 1.1 augustss Static usbd_status 644 1.1 augustss ustir_start_read(struct ustir_softc *sc) 645 1.1 augustss { 646 1.1 augustss usbd_status err; 647 1.1 augustss 648 1.3 augustss DPRINTFN(60,("%s: sc=%p, size=%d\n", __func__, sc, 649 1.1 augustss sc->sc_params.maxsize)); 650 1.1 augustss 651 1.1 augustss if (sc->sc_dying) 652 1.1 augustss return USBD_IOERROR; 653 1.1 augustss 654 1.1 augustss if (USTIR_BLOCK_RX_DATA(sc) || deframe_rd_ur(sc)) { 655 1.1 augustss /* 656 1.1 augustss * Can't start reading just yet. Since we aren't 657 1.1 augustss * going to start a read, have to switch direction to 658 1.1 augustss * idle. 659 1.1 augustss */ 660 1.1 augustss sc->sc_direction = udir_idle; 661 1.1 augustss return USBD_NORMAL_COMPLETION; 662 1.1 augustss } 663 1.1 augustss 664 1.1 augustss /* Starting a read... */ 665 1.1 augustss sc->sc_rd_readinprogress = 1; 666 1.1 augustss sc->sc_direction = udir_input; 667 1.1 augustss 668 1.1 augustss if (sc->sc_rd_err) { 669 1.1 augustss sc->sc_rd_err = 0; 670 1.3 augustss DPRINTFN(0, ("%s: clear stall\n", __func__)); 671 1.1 augustss usbd_clear_endpoint_stall(sc->sc_rd_pipe); 672 1.1 augustss } 673 1.1 augustss 674 1.34 skrll usbd_setup_xfer(sc->sc_rd_xfer, sc, sc->sc_rd_buf, 675 1.34 skrll sc->sc_params.maxsize, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, 676 1.34 skrll ustir_rd_cb); 677 1.1 augustss err = usbd_transfer(sc->sc_rd_xfer); 678 1.1 augustss if (err != USBD_IN_PROGRESS) { 679 1.8 dsainty DPRINTFN(0, ("%s: err=%d\n", __func__, (int)err)); 680 1.1 augustss return err; 681 1.1 augustss } 682 1.1 augustss return USBD_NORMAL_COMPLETION; 683 1.1 augustss } 684 1.1 augustss 685 1.1 augustss Static int 686 1.22 dyoung ustir_activate(device_t self, enum devact act) 687 1.1 augustss { 688 1.22 dyoung struct ustir_softc *sc = device_private(self); 689 1.1 augustss 690 1.1 augustss switch (act) { 691 1.1 augustss case DVACT_DEACTIVATE: 692 1.1 augustss sc->sc_dying = 1; 693 1.28 dyoung return 0; 694 1.28 dyoung default: 695 1.28 dyoung return EOPNOTSUPP; 696 1.1 augustss } 697 1.1 augustss } 698 1.1 augustss 699 1.5 dsainty /* ARGSUSED */ 700 1.1 augustss Static int 701 1.17 christos ustir_open(void *h, int flag, int mode, 702 1.17 christos struct lwp *l) 703 1.1 augustss { 704 1.1 augustss struct ustir_softc *sc = h; 705 1.1 augustss int error; 706 1.1 augustss usbd_status err; 707 1.1 augustss 708 1.3 augustss DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 709 1.1 augustss 710 1.1 augustss err = usbd_open_pipe(sc->sc_iface, sc->sc_rd_addr, 0, &sc->sc_rd_pipe); 711 1.8 dsainty if (err != USBD_NORMAL_COMPLETION) { 712 1.1 augustss error = EIO; 713 1.1 augustss goto bad1; 714 1.1 augustss } 715 1.1 augustss err = usbd_open_pipe(sc->sc_iface, sc->sc_wr_addr, 0, &sc->sc_wr_pipe); 716 1.8 dsainty if (err != USBD_NORMAL_COMPLETION) { 717 1.1 augustss error = EIO; 718 1.1 augustss goto bad2; 719 1.1 augustss } 720 1.34 skrll error = usbd_create_xfer(sc->sc_rd_pipe, IRDA_MAX_FRAME_SIZE, 721 1.39 skrll 0, 0, &sc->sc_rd_xfer); 722 1.34 skrll if (error) 723 1.1 augustss goto bad3; 724 1.34 skrll sc->sc_rd_buf = usbd_get_buffer(sc->sc_rd_xfer); 725 1.34 skrll 726 1.34 skrll error = usbd_create_xfer(sc->sc_wr_pipe, 727 1.34 skrll IRDA_MAX_FRAME_SIZE + STIR_OUTPUT_HEADER_SIZE, 728 1.34 skrll USBD_FORCE_SHORT_XFER, 0, &sc->sc_wr_xfer); 729 1.34 skrll if (error) 730 1.1 augustss goto bad4; 731 1.34 skrll sc->sc_wr_buf = usbd_get_buffer(sc->sc_wr_xfer); 732 1.34 skrll 733 1.34 skrll sc->sc_ur_buf = kmem_alloc(IRDA_MAX_FRAME_SIZE, KM_SLEEP); 734 1.1 augustss sc->sc_rd_index = sc->sc_rd_count = 0; 735 1.1 augustss sc->sc_closing = 0; 736 1.1 augustss sc->sc_rd_readinprogress = 0; 737 1.1 augustss sc->sc_rd_expectdataticks = 0; 738 1.1 augustss sc->sc_ur_framelen = 0; 739 1.1 augustss sc->sc_rd_err = 0; 740 1.10 dsainty sc->sc_wr_stalewrite = 0; 741 1.1 augustss sc->sc_speedrec = NULL; 742 1.1 augustss sc->sc_direction = udir_idle; 743 1.1 augustss sc->sc_params.speed = 0; 744 1.1 augustss sc->sc_params.ebofs = 0; 745 1.1 augustss sc->sc_params.maxsize = IRDA_MAX_FRAME_SIZE; 746 1.1 augustss 747 1.33 kiyohara deframe_init(&sc->sc_framestate, sc->sc_ur_buf, IRDA_MAX_FRAME_SIZE); 748 1.1 augustss 749 1.1 augustss /* Increment reference for thread */ 750 1.1 augustss sc->sc_refcnt++; 751 1.1 augustss 752 1.20 ad error = kthread_create(PRI_NONE, 0, NULL, ustir_thread, sc, 753 1.26 cube &sc->sc_thread, "%s", device_xname(sc->sc_dev)); 754 1.20 ad if (error) { 755 1.20 ad sc->sc_refcnt--; 756 1.20 ad goto bad5; 757 1.20 ad } 758 1.20 ad 759 1.1 augustss return 0; 760 1.1 augustss 761 1.1 augustss bad5: 762 1.34 skrll usbd_destroy_xfer(sc->sc_wr_xfer); 763 1.1 augustss sc->sc_wr_xfer = NULL; 764 1.1 augustss bad4: 765 1.34 skrll usbd_destroy_xfer(sc->sc_rd_xfer); 766 1.1 augustss sc->sc_rd_xfer = NULL; 767 1.1 augustss bad3: 768 1.1 augustss usbd_close_pipe(sc->sc_wr_pipe); 769 1.1 augustss sc->sc_wr_pipe = NULL; 770 1.1 augustss bad2: 771 1.1 augustss usbd_close_pipe(sc->sc_rd_pipe); 772 1.1 augustss sc->sc_rd_pipe = NULL; 773 1.1 augustss bad1: 774 1.1 augustss return error; 775 1.1 augustss } 776 1.1 augustss 777 1.5 dsainty /* ARGSUSED */ 778 1.1 augustss Static int 779 1.17 christos ustir_close(void *h, int flag, int mode, 780 1.17 christos struct lwp *l) 781 1.1 augustss { 782 1.1 augustss struct ustir_softc *sc = h; 783 1.1 augustss 784 1.3 augustss DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 785 1.1 augustss 786 1.1 augustss sc->sc_refcnt++; 787 1.1 augustss 788 1.1 augustss sc->sc_rd_readinprogress = 1; 789 1.1 augustss sc->sc_closing = 1; 790 1.1 augustss 791 1.1 augustss wakeup(&sc->sc_thread); 792 1.1 augustss 793 1.1 augustss while (sc->sc_thread != NULL) 794 1.1 augustss tsleep(&sc->sc_closing, PWAIT, "usircl", 0); 795 1.1 augustss 796 1.1 augustss if (sc->sc_rd_pipe != NULL) { 797 1.1 augustss usbd_abort_pipe(sc->sc_rd_pipe); 798 1.1 augustss sc->sc_rd_pipe = NULL; 799 1.1 augustss } 800 1.1 augustss if (sc->sc_wr_pipe != NULL) { 801 1.1 augustss usbd_abort_pipe(sc->sc_wr_pipe); 802 1.1 augustss sc->sc_wr_pipe = NULL; 803 1.1 augustss } 804 1.1 augustss if (sc->sc_rd_xfer != NULL) { 805 1.34 skrll usbd_destroy_xfer(sc->sc_rd_xfer); 806 1.1 augustss sc->sc_rd_xfer = NULL; 807 1.1 augustss sc->sc_rd_buf = NULL; 808 1.1 augustss } 809 1.1 augustss if (sc->sc_wr_xfer != NULL) { 810 1.34 skrll usbd_destroy_xfer(sc->sc_wr_xfer); 811 1.1 augustss sc->sc_wr_xfer = NULL; 812 1.1 augustss sc->sc_wr_buf = NULL; 813 1.1 augustss } 814 1.1 augustss if (sc->sc_ur_buf != NULL) { 815 1.34 skrll kmem_free(sc->sc_ur_buf, IRDA_MAX_FRAME_SIZE); 816 1.1 augustss sc->sc_ur_buf = NULL; 817 1.1 augustss } 818 1.34 skrll if (sc->sc_rd_pipe != NULL) { 819 1.34 skrll usbd_close_pipe(sc->sc_rd_pipe); 820 1.34 skrll sc->sc_rd_pipe = NULL; 821 1.34 skrll } 822 1.34 skrll if (sc->sc_wr_pipe != NULL) { 823 1.34 skrll usbd_close_pipe(sc->sc_wr_pipe); 824 1.34 skrll sc->sc_wr_pipe = NULL; 825 1.34 skrll } 826 1.1 augustss 827 1.1 augustss if (--sc->sc_refcnt < 0) 828 1.32 mrg usb_detach_wakeupold(sc->sc_dev); 829 1.1 augustss 830 1.1 augustss return 0; 831 1.1 augustss } 832 1.1 augustss 833 1.7 dsainty /* ARGSUSED */ 834 1.1 augustss Static int 835 1.17 christos ustir_read(void *h, struct uio *uio, int flag) 836 1.1 augustss { 837 1.1 augustss struct ustir_softc *sc = h; 838 1.1 augustss int s; 839 1.1 augustss int error; 840 1.1 augustss u_int uframelen; 841 1.1 augustss 842 1.3 augustss DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 843 1.1 augustss 844 1.1 augustss if (sc->sc_dying) 845 1.1 augustss return EIO; 846 1.1 augustss 847 1.1 augustss #ifdef DIAGNOSTIC 848 1.1 augustss if (sc->sc_rd_buf == NULL) 849 1.1 augustss return EINVAL; 850 1.1 augustss #endif 851 1.1 augustss 852 1.1 augustss sc->sc_refcnt++; 853 1.1 augustss 854 1.1 augustss if (!sc->sc_rd_readinprogress && !USTIR_BLOCK_RX_DATA(sc)) 855 1.1 augustss /* Possibly wake up polling thread */ 856 1.1 augustss wakeup(&sc->sc_thread); 857 1.1 augustss 858 1.1 augustss do { 859 1.1 augustss s = splusb(); 860 1.1 augustss while (sc->sc_ur_framelen == 0) { 861 1.3 augustss DPRINTFN(5,("%s: calling tsleep()\n", __func__)); 862 1.1 augustss error = tsleep(&sc->sc_ur_framelen, PZERO | PCATCH, 863 1.1 augustss "usirrd", 0); 864 1.1 augustss if (sc->sc_dying) 865 1.1 augustss error = EIO; 866 1.1 augustss if (error) { 867 1.1 augustss splx(s); 868 1.1 augustss DPRINTFN(0, ("%s: tsleep() = %d\n", 869 1.3 augustss __func__, error)); 870 1.1 augustss goto ret; 871 1.1 augustss } 872 1.1 augustss } 873 1.1 augustss splx(s); 874 1.1 augustss 875 1.1 augustss uframelen = sc->sc_ur_framelen; 876 1.46 christos DPRINTFN(1,("%s: sc=%p framelen=%u, hdr=0x%02x\n", 877 1.3 augustss __func__, sc, uframelen, sc->sc_ur_buf[0])); 878 1.1 augustss if (uframelen > uio->uio_resid) 879 1.1 augustss error = EINVAL; 880 1.1 augustss else 881 1.1 augustss error = uiomove(sc->sc_ur_buf, uframelen, uio); 882 1.1 augustss sc->sc_ur_framelen = 0; 883 1.1 augustss 884 1.1 augustss if (!deframe_rd_ur(sc) && uframelen > 0) { 885 1.1 augustss /* 886 1.1 augustss * Need to wait for another read to obtain a 887 1.1 augustss * complete frame... If we also obtained 888 1.1 augustss * actual data, wake up the possibly sleeping 889 1.1 augustss * thread immediately... 890 1.1 augustss */ 891 1.1 augustss wakeup(&sc->sc_thread); 892 1.1 augustss } 893 1.1 augustss } while (uframelen == 0); 894 1.1 augustss 895 1.3 augustss DPRINTFN(1,("%s: return %d\n", __func__, error)); 896 1.1 augustss 897 1.1 augustss ret: 898 1.1 augustss if (--sc->sc_refcnt < 0) 899 1.32 mrg usb_detach_wakeupold(sc->sc_dev); 900 1.1 augustss return error; 901 1.1 augustss } 902 1.1 augustss 903 1.7 dsainty /* ARGSUSED */ 904 1.1 augustss Static int 905 1.17 christos ustir_write(void *h, struct uio *uio, int flag) 906 1.1 augustss { 907 1.1 augustss struct ustir_softc *sc = h; 908 1.1 augustss usbd_status err; 909 1.34 skrll uint32_t wrlen; 910 1.1 augustss int error, sirlength; 911 1.34 skrll uint8_t *wrbuf; 912 1.1 augustss int s; 913 1.1 augustss 914 1.3 augustss DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 915 1.1 augustss 916 1.1 augustss if (sc->sc_dying) 917 1.1 augustss return EIO; 918 1.1 augustss 919 1.1 augustss #ifdef DIAGNOSTIC 920 1.1 augustss if (sc->sc_wr_buf == NULL) 921 1.1 augustss return EINVAL; 922 1.1 augustss #endif 923 1.1 augustss 924 1.1 augustss wrlen = uio->uio_resid; 925 1.1 augustss if (wrlen > sc->sc_params.maxsize) 926 1.1 augustss return EINVAL; 927 1.1 augustss 928 1.1 augustss sc->sc_refcnt++; 929 1.1 augustss 930 1.10 dsainty if (!USTIR_BLOCK_RX_DATA(sc)) { 931 1.10 dsainty /* 932 1.10 dsainty * If reads are not blocked, determine what action we 933 1.10 dsainty * should potentially take... 934 1.10 dsainty */ 935 1.10 dsainty if (sc->sc_direction == udir_output) { 936 1.10 dsainty /* 937 1.10 dsainty * If the last operation was an output, wait for the 938 1.10 dsainty * polling thread to check for incoming data. 939 1.10 dsainty */ 940 1.10 dsainty sc->sc_wr_stalewrite = 1; 941 1.10 dsainty wakeup(&sc->sc_thread); 942 1.10 dsainty } else if (!sc->sc_rd_readinprogress && 943 1.10 dsainty (sc->sc_direction == udir_idle || 944 1.10 dsainty sc->sc_direction == udir_input)) { 945 1.10 dsainty /* If idle, check for input before outputting */ 946 1.10 dsainty ustir_start_read(sc); 947 1.10 dsainty } 948 1.10 dsainty } 949 1.1 augustss 950 1.1 augustss s = splusb(); 951 1.10 dsainty while (sc->sc_wr_stalewrite || 952 1.10 dsainty (sc->sc_direction != udir_output && 953 1.10 dsainty sc->sc_direction != udir_idle)) { 954 1.10 dsainty DPRINTFN(5, ("%s: sc=%p stalewrite=%d direction=%d, " 955 1.10 dsainty "calling tsleep()\n", __func__, 956 1.10 dsainty sc, sc->sc_wr_stalewrite, sc->sc_direction)); 957 1.1 augustss error = tsleep(&sc->sc_wr_buf, PZERO | PCATCH, 958 1.1 augustss "usirwr", 0); 959 1.1 augustss if (sc->sc_dying) 960 1.1 augustss error = EIO; 961 1.1 augustss if (error) { 962 1.1 augustss splx(s); 963 1.3 augustss DPRINTFN(0, ("%s: tsleep() = %d\n", __func__, 964 1.1 augustss error)); 965 1.1 augustss goto ret; 966 1.1 augustss } 967 1.1 augustss } 968 1.1 augustss splx(s); 969 1.1 augustss 970 1.1 augustss wrbuf = sc->sc_wr_buf; 971 1.1 augustss 972 1.1 augustss /* Build header */ 973 1.1 augustss wrbuf[0] = STIR_OUTPUT_HEADER_BYTE0; 974 1.1 augustss wrbuf[1] = STIR_OUTPUT_HEADER_BYTE1; 975 1.1 augustss 976 1.1 augustss sirlength = irda_sir_frame(&wrbuf[STIR_OUTPUT_HEADER_SIZE], 977 1.1 augustss MAX_USTIR_OUTPUT_FRAME - 978 1.1 augustss STIR_OUTPUT_HEADER_SIZE, 979 1.1 augustss uio, sc->sc_params.ebofs); 980 1.1 augustss if (sirlength < 0) { 981 1.1 augustss error = -sirlength; 982 1.1 augustss } else { 983 1.34 skrll uint32_t btlen; 984 1.1 augustss 985 1.3 augustss DPRINTFN(1, ("%s: transfer %u bytes\n", __func__, 986 1.1 augustss (unsigned int)wrlen)); 987 1.1 augustss 988 1.1 augustss wrbuf[2] = sirlength & 0xff; 989 1.1 augustss wrbuf[3] = (sirlength >> 8) & 0xff; 990 1.1 augustss 991 1.1 augustss btlen = STIR_OUTPUT_HEADER_SIZE + sirlength; 992 1.1 augustss 993 1.1 augustss sc->sc_direction = udir_output; 994 1.1 augustss 995 1.1 augustss #ifdef USTIR_DEBUG 996 1.1 augustss if (ustirdebug >= 20) 997 1.3 augustss ustir_dumpdata(wrbuf, btlen, __func__); 998 1.1 augustss #endif 999 1.1 augustss 1000 1.1 augustss err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, 1001 1.34 skrll USBD_FORCE_SHORT_XFER, USTIR_WR_TIMEOUT, wrbuf, &btlen); 1002 1.3 augustss DPRINTFN(2, ("%s: err=%d\n", __func__, err)); 1003 1.8 dsainty if (err != USBD_NORMAL_COMPLETION) { 1004 1.1 augustss if (err == USBD_INTERRUPTED) 1005 1.1 augustss error = EINTR; 1006 1.1 augustss else if (err == USBD_TIMEOUT) 1007 1.1 augustss error = ETIMEDOUT; 1008 1.1 augustss else 1009 1.1 augustss error = EIO; 1010 1.1 augustss } else { 1011 1.1 augustss error = 0; 1012 1.1 augustss } 1013 1.1 augustss } 1014 1.1 augustss 1015 1.1 augustss ret: 1016 1.1 augustss if (--sc->sc_refcnt < 0) 1017 1.32 mrg usb_detach_wakeupold(sc->sc_dev); 1018 1.1 augustss 1019 1.3 augustss DPRINTFN(1,("%s: sc=%p done\n", __func__, sc)); 1020 1.1 augustss return error; 1021 1.1 augustss } 1022 1.1 augustss 1023 1.1 augustss Static int 1024 1.15 christos ustir_poll(void *h, int events, struct lwp *l) 1025 1.1 augustss { 1026 1.1 augustss struct ustir_softc *sc = h; 1027 1.1 augustss int revents = 0; 1028 1.1 augustss 1029 1.3 augustss DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 1030 1.1 augustss 1031 1.1 augustss if (events & (POLLOUT | POLLWRNORM)) { 1032 1.1 augustss if (sc->sc_direction != udir_input) { 1033 1.1 augustss revents |= events & (POLLOUT | POLLWRNORM); 1034 1.1 augustss } else { 1035 1.1 augustss DPRINTFN(2,("%s: recording write select\n", 1036 1.3 augustss __func__)); 1037 1.15 christos selrecord(l, &sc->sc_wr_sel); 1038 1.1 augustss } 1039 1.1 augustss } 1040 1.1 augustss 1041 1.1 augustss if (events & (POLLIN | POLLRDNORM)) { 1042 1.1 augustss if (sc->sc_ur_framelen != 0) { 1043 1.3 augustss DPRINTFN(2,("%s: have data\n", __func__)); 1044 1.1 augustss revents |= events & (POLLIN | POLLRDNORM); 1045 1.1 augustss } else { 1046 1.1 augustss DPRINTFN(2,("%s: recording read select\n", 1047 1.3 augustss __func__)); 1048 1.15 christos selrecord(l, &sc->sc_rd_sel); 1049 1.1 augustss } 1050 1.1 augustss } 1051 1.1 augustss 1052 1.1 augustss return revents; 1053 1.4 jdolecek } 1054 1.4 jdolecek 1055 1.4 jdolecek static void 1056 1.4 jdolecek filt_ustirrdetach(struct knote *kn) 1057 1.4 jdolecek { 1058 1.4 jdolecek struct ustir_softc *sc = kn->kn_hook; 1059 1.4 jdolecek int s; 1060 1.4 jdolecek 1061 1.4 jdolecek s = splusb(); 1062 1.47 thorpej selremove_knote(&sc->sc_rd_sel, kn); 1063 1.4 jdolecek splx(s); 1064 1.4 jdolecek } 1065 1.4 jdolecek 1066 1.7 dsainty /* ARGSUSED */ 1067 1.4 jdolecek static int 1068 1.17 christos filt_ustirread(struct knote *kn, long hint) 1069 1.4 jdolecek { 1070 1.4 jdolecek struct ustir_softc *sc = kn->kn_hook; 1071 1.4 jdolecek 1072 1.4 jdolecek kn->kn_data = sc->sc_ur_framelen; 1073 1.34 skrll return kn->kn_data > 0; 1074 1.4 jdolecek } 1075 1.4 jdolecek 1076 1.4 jdolecek static void 1077 1.4 jdolecek filt_ustirwdetach(struct knote *kn) 1078 1.4 jdolecek { 1079 1.4 jdolecek struct ustir_softc *sc = kn->kn_hook; 1080 1.4 jdolecek int s; 1081 1.4 jdolecek 1082 1.4 jdolecek s = splusb(); 1083 1.47 thorpej selremove_knote(&sc->sc_wr_sel, kn); 1084 1.4 jdolecek splx(s); 1085 1.4 jdolecek } 1086 1.4 jdolecek 1087 1.7 dsainty /* ARGSUSED */ 1088 1.4 jdolecek static int 1089 1.17 christos filt_ustirwrite(struct knote *kn, long hint) 1090 1.4 jdolecek { 1091 1.4 jdolecek struct ustir_softc *sc = kn->kn_hook; 1092 1.4 jdolecek 1093 1.4 jdolecek kn->kn_data = 0; 1094 1.34 skrll return sc->sc_direction != udir_input; 1095 1.4 jdolecek } 1096 1.4 jdolecek 1097 1.38 maya static const struct filterops ustirread_filtops = { 1098 1.50 thorpej .f_flags = FILTEROP_ISFD, 1099 1.38 maya .f_attach = NULL, 1100 1.38 maya .f_detach = filt_ustirrdetach, 1101 1.38 maya .f_event = filt_ustirread, 1102 1.38 maya }; 1103 1.38 maya 1104 1.38 maya static const struct filterops ustirwrite_filtops = { 1105 1.50 thorpej .f_flags = FILTEROP_ISFD, 1106 1.38 maya .f_attach = NULL, 1107 1.38 maya .f_detach = filt_ustirwdetach, 1108 1.38 maya .f_event = filt_ustirwrite, 1109 1.38 maya }; 1110 1.4 jdolecek 1111 1.4 jdolecek Static int 1112 1.4 jdolecek ustir_kqfilter(void *h, struct knote *kn) 1113 1.4 jdolecek { 1114 1.4 jdolecek struct ustir_softc *sc = h; 1115 1.47 thorpej struct selinfo *sip; 1116 1.4 jdolecek int s; 1117 1.4 jdolecek 1118 1.4 jdolecek switch (kn->kn_filter) { 1119 1.4 jdolecek case EVFILT_READ: 1120 1.47 thorpej sip = &sc->sc_rd_sel; 1121 1.4 jdolecek kn->kn_fop = &ustirread_filtops; 1122 1.4 jdolecek break; 1123 1.4 jdolecek case EVFILT_WRITE: 1124 1.47 thorpej sip = &sc->sc_wr_sel; 1125 1.4 jdolecek kn->kn_fop = &ustirwrite_filtops; 1126 1.4 jdolecek break; 1127 1.4 jdolecek default: 1128 1.34 skrll return EINVAL; 1129 1.4 jdolecek } 1130 1.4 jdolecek 1131 1.4 jdolecek kn->kn_hook = sc; 1132 1.4 jdolecek 1133 1.4 jdolecek s = splusb(); 1134 1.47 thorpej selrecord_knote(sip, kn); 1135 1.4 jdolecek splx(s); 1136 1.4 jdolecek 1137 1.34 skrll return 0; 1138 1.1 augustss } 1139 1.1 augustss 1140 1.1 augustss #ifdef USTIR_DEBUG_IOCTLS 1141 1.18 christos Static int ustir_ioctl(void *h, u_long cmd, void *addr, int flag, struct lwp *l) 1142 1.1 augustss { 1143 1.1 augustss struct ustir_softc *sc = h; 1144 1.1 augustss int error; 1145 1.1 augustss unsigned int regnum; 1146 1.1 augustss usbd_status err; 1147 1.51 riastrad uint8_t regdata = 0; 1148 1.1 augustss 1149 1.1 augustss if (sc->sc_dying) 1150 1.1 augustss return EIO; 1151 1.1 augustss 1152 1.1 augustss sc->sc_refcnt++; 1153 1.1 augustss 1154 1.1 augustss error = 0; 1155 1.1 augustss switch (cmd) { 1156 1.1 augustss case USTIR_READ_REGISTER: 1157 1.2 augustss regnum = *(unsigned int *)addr; 1158 1.1 augustss 1159 1.1 augustss if (regnum > STIR_MAX_REG) { 1160 1.1 augustss error = EINVAL; 1161 1.1 augustss break; 1162 1.1 augustss } 1163 1.1 augustss 1164 1.1 augustss err = ustir_read_reg(sc, regnum, ®data); 1165 1.1 augustss 1166 1.45 christos DPRINTFN(10, ("%s: regget(%u) = %#x\n", __func__, 1167 1.1 augustss regnum, (unsigned int)regdata)); 1168 1.1 augustss 1169 1.2 augustss *(unsigned int *)addr = regdata; 1170 1.8 dsainty if (err != USBD_NORMAL_COMPLETION) { 1171 1.1 augustss printf("%s: register read failed: %s\n", 1172 1.29 dyoung device_xname(sc->sc_dev), 1173 1.1 augustss usbd_errstr(err)); 1174 1.1 augustss error = EIO; 1175 1.1 augustss } 1176 1.1 augustss break; 1177 1.1 augustss 1178 1.1 augustss case USTIR_WRITE_REGISTER: 1179 1.2 augustss regnum = *(unsigned int *)addr; 1180 1.1 augustss regdata = (regnum >> 8) & 0xff; 1181 1.1 augustss regnum = regnum & 0xff; 1182 1.1 augustss 1183 1.1 augustss if (regnum > STIR_MAX_REG) { 1184 1.1 augustss error = EINVAL; 1185 1.1 augustss break; 1186 1.1 augustss } 1187 1.1 augustss 1188 1.45 christos DPRINTFN(10, ("%s: regset(%u, %#x)\n", __func__, 1189 1.1 augustss regnum, (unsigned int)regdata)); 1190 1.1 augustss 1191 1.1 augustss err = ustir_write_reg(sc, regnum, regdata); 1192 1.8 dsainty if (err != USBD_NORMAL_COMPLETION) { 1193 1.1 augustss printf("%s: register write failed: %s\n", 1194 1.29 dyoung device_xname(sc->sc_dev), 1195 1.1 augustss usbd_errstr(err)); 1196 1.1 augustss error = EIO; 1197 1.1 augustss } 1198 1.1 augustss break; 1199 1.1 augustss 1200 1.1 augustss case USTIR_DEBUG_LEVEL: 1201 1.1 augustss #ifdef USTIR_DEBUG 1202 1.2 augustss ustirdebug = *(int *)addr; 1203 1.1 augustss #endif 1204 1.1 augustss break; 1205 1.1 augustss 1206 1.1 augustss case USTIR_DEBUG_OPERATION: 1207 1.1 augustss break; 1208 1.1 augustss 1209 1.1 augustss default: 1210 1.1 augustss error = EINVAL; 1211 1.1 augustss break; 1212 1.1 augustss } 1213 1.1 augustss 1214 1.1 augustss if (--sc->sc_refcnt < 0) 1215 1.32 mrg usb_detach_wakeupold(sc->sc_dev); 1216 1.1 augustss 1217 1.1 augustss return error; 1218 1.1 augustss } 1219 1.1 augustss #endif 1220 1.1 augustss 1221 1.1 augustss Static int 1222 1.1 augustss ustir_set_params(void *h, struct irda_params *p) 1223 1.1 augustss { 1224 1.1 augustss struct ustir_softc *sc = h; 1225 1.1 augustss struct ustir_speedrec const *speedblk; 1226 1.1 augustss int i; 1227 1.1 augustss 1228 1.3 augustss DPRINTFN(0, ("%s: sc=%p, speed=%d ebofs=%d maxsize=%d\n", __func__, 1229 1.1 augustss sc, p->speed, p->ebofs, p->maxsize)); 1230 1.1 augustss 1231 1.1 augustss if (sc->sc_dying) 1232 1.1 augustss return EIO; 1233 1.1 augustss 1234 1.1 augustss speedblk = NULL; 1235 1.1 augustss 1236 1.1 augustss if (sc->sc_speedrec == NULL || p->speed != sc->sc_speedrec->speed) { 1237 1.1 augustss /* find speed */ 1238 1.1 augustss for (i = 0; i < USTIR_NSPEEDS; i++) { 1239 1.1 augustss if (ustir_speeds[i].speed == p->speed) { 1240 1.1 augustss speedblk = &ustir_speeds[i]; 1241 1.1 augustss goto found2; 1242 1.1 augustss } 1243 1.1 augustss } 1244 1.1 augustss /* no good value found */ 1245 1.1 augustss return EINVAL; 1246 1.1 augustss found2: 1247 1.1 augustss ; 1248 1.1 augustss } 1249 1.1 augustss if (p->maxsize != sc->sc_params.maxsize) { 1250 1.1 augustss if (p->maxsize > IRDA_MAX_FRAME_SIZE) 1251 1.1 augustss return EINVAL; 1252 1.1 augustss sc->sc_params.maxsize = p->maxsize; 1253 1.1 augustss } 1254 1.1 augustss 1255 1.1 augustss sc->sc_params = *p; 1256 1.1 augustss 1257 1.1 augustss if (speedblk != NULL) { 1258 1.1 augustss usbd_status err; 1259 1.34 skrll uint8_t regmode; 1260 1.34 skrll uint8_t regbrate; 1261 1.1 augustss 1262 1.1 augustss sc->sc_speedrec = speedblk; 1263 1.1 augustss 1264 1.1 augustss regmode = STIR_BRMODE_MODEREG(speedblk->config); 1265 1.1 augustss regbrate = STIR_BRMODE_BRATEREG(speedblk->config); 1266 1.1 augustss 1267 1.1 augustss /* 1268 1.1 augustss * FFSPRST must be set to enable the FIFO. 1269 1.1 augustss */ 1270 1.1 augustss regmode |= STIR_RMODE_FFSPRST; 1271 1.1 augustss 1272 1.3 augustss DPRINTFN(10, ("%s: setting BRATE = %x\n", __func__, 1273 1.1 augustss (unsigned int)regbrate)); 1274 1.1 augustss err = ustir_write_reg(sc, STIR_REG_BRATE, regbrate); 1275 1.8 dsainty if (err == USBD_NORMAL_COMPLETION) { 1276 1.3 augustss DPRINTFN(10, ("%s: setting MODE = %x\n", __func__, 1277 1.1 augustss (unsigned int)regmode)); 1278 1.1 augustss err = ustir_write_reg(sc, STIR_REG_MODE, regmode); 1279 1.1 augustss } 1280 1.8 dsainty if (err != USBD_NORMAL_COMPLETION) { 1281 1.1 augustss DPRINTFN(10, ("%s: error setting register: %s\n", 1282 1.3 augustss __func__, usbd_errstr(err))); 1283 1.1 augustss return EIO; 1284 1.1 augustss } 1285 1.1 augustss } 1286 1.1 augustss 1287 1.1 augustss return 0; 1288 1.1 augustss } 1289 1.1 augustss 1290 1.1 augustss Static int 1291 1.1 augustss ustir_get_speeds(void *h, int *speeds) 1292 1.1 augustss { 1293 1.1 augustss struct ustir_softc *sc = h; 1294 1.1 augustss 1295 1.3 augustss DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 1296 1.1 augustss 1297 1.1 augustss if (sc->sc_dying) 1298 1.1 augustss return EIO; 1299 1.1 augustss 1300 1.1 augustss /* All these speeds are supported */ 1301 1.1 augustss *speeds = IRDA_SPEED_4000000 | 1302 1.1 augustss IRDA_SPEED_1152000 | 1303 1.1 augustss IRDA_SPEED_576000 | 1304 1.1 augustss IRDA_SPEED_115200 | 1305 1.1 augustss IRDA_SPEED_57600 | 1306 1.1 augustss IRDA_SPEED_38400 | 1307 1.1 augustss IRDA_SPEED_19200 | 1308 1.1 augustss IRDA_SPEED_9600 | 1309 1.1 augustss IRDA_SPEED_2400; 1310 1.1 augustss 1311 1.1 augustss return 0; 1312 1.1 augustss } 1313 1.1 augustss 1314 1.1 augustss Static int 1315 1.1 augustss ustir_get_turnarounds(void *h, int *turnarounds) 1316 1.1 augustss { 1317 1.1 augustss struct ustir_softc *sc = h; 1318 1.1 augustss 1319 1.3 augustss DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 1320 1.1 augustss 1321 1.1 augustss if (sc->sc_dying) 1322 1.1 augustss return EIO; 1323 1.1 augustss 1324 1.1 augustss /* 1325 1.1 augustss * Documentation is on the light side with respect to 1326 1.1 augustss * turnaround time for this device. 1327 1.1 augustss */ 1328 1.1 augustss *turnarounds = IRDA_TURNT_10000; 1329 1.1 augustss 1330 1.1 augustss return 0; 1331 1.1 augustss } 1332