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