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