xref: /netbsd-src/sys/dev/usb/ustir.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /*	$NetBSD: ustir.c,v 1.33 2013/05/27 16:23:20 kiyohara 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.33 2013/05/27 16:23:20 kiyohara 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/malloc.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
65 int	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
74 struct ustir_speedrec {
75 	unsigned int speed;
76 	unsigned int config;
77 };
78 
79 Static 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 
91 struct ustir_softc {
92 	device_t		sc_dev;
93 	usbd_device_handle	sc_udev;
94 	usbd_interface_handle	sc_iface;
95 
96 	u_int8_t		*sc_ur_buf; /* Unencapsulated frame */
97 	u_int			sc_ur_framelen;
98 
99 	u_int8_t		*sc_rd_buf; /* Raw incoming data stream */
100 	size_t			sc_rd_index;
101 	int			sc_rd_addr;
102 	usbd_pipe_handle	sc_rd_pipe;
103 	usbd_xfer_handle	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 	u_int8_t		*sc_wr_buf;
113 	int			sc_wr_addr;
114 	int			sc_wr_stalewrite;
115 	usbd_xfer_handle	sc_wr_xfer;
116 	usbd_pipe_handle	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 
141 Static int ustir_activate(device_t self, enum devact act);
142 Static int ustir_open(void *h, int flag, int mode, struct lwp *l);
143 Static int ustir_close(void *h, int flag, int mode, struct lwp *l);
144 Static int ustir_read(void *h, struct uio *uio, int flag);
145 Static int ustir_write(void *h, struct uio *uio, int flag);
146 Static int ustir_set_params(void *h, struct irda_params *params);
147 Static int ustir_get_speeds(void *h, int *speeds);
148 Static int ustir_get_turnarounds(void *h, int *times);
149 Static int ustir_poll(void *h, int events, struct lwp *l);
150 Static int ustir_kqfilter(void *h, struct knote *kn);
151 
152 #ifdef USTIR_DEBUG_IOCTLS
153 Static int ustir_ioctl(void *h, u_long cmd, void *addr, int flag, struct lwp *l);
154 #endif
155 
156 Static 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 
165 Static void ustir_rd_cb(usbd_xfer_handle, usbd_private_handle, usbd_status);
166 Static usbd_status ustir_start_read(struct ustir_softc *);
167 Static void ustir_periodic(struct ustir_softc *);
168 Static void ustir_thread(void *);
169 
170 static usbd_status
171 ustir_read_reg(struct ustir_softc *sc, unsigned int reg, u_int8_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 
184 static usbd_status
185 ustir_write_reg(struct ustir_softc *sc, unsigned int reg, u_int8_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
199 static void
200 ustir_dumpdata(u_int8_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 
210 int ustir_match(device_t, cfdata_t, void *);
211 void ustir_attach(device_t, device_t, void *);
212 void ustir_childdet(device_t, device_t);
213 int ustir_detach(device_t, int);
214 int ustir_activate(device_t, enum devact);
215 extern struct cfdriver ustir_cd;
216 CFATTACH_DECL2_NEW(ustir, sizeof(struct ustir_softc), ustir_match,
217     ustir_attach, ustir_detach, ustir_activate, NULL, ustir_childdet);
218 
219 int
220 ustir_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->vendor == USB_VENDOR_SIGMATEL &&
227 	    uaa->product == USB_PRODUCT_SIGMATEL_IRDA)
228 		return UMATCH_VENDOR_PRODUCT;
229 
230 	return UMATCH_NONE;
231 }
232 
233 void
234 ustir_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 	usbd_device_handle dev = uaa->device;
239 	usbd_interface_handle iface;
240 	char *devinfop;
241 	usb_endpoint_descriptor_t *ed;
242 	u_int8_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,
293 			   sc->sc_dev);
294 
295 	ia.ia_type = IR_TYPE_IRFRAME;
296 	ia.ia_methods = &ustir_methods;
297 	ia.ia_handle = sc;
298 
299 	sc->sc_child = config_found(self, &ia, ir_print);
300 	selinit(&sc->sc_rd_sel);
301 	selinit(&sc->sc_wr_sel);
302 
303 	return;
304 }
305 
306 void
307 ustir_childdet(device_t self, device_t child)
308 {
309 	struct ustir_softc *sc = device_private(self);
310 
311 	KASSERT(sc->sc_child == child);
312 	sc->sc_child = NULL;
313 }
314 
315 int
316 ustir_detach(device_t self, int flags)
317 {
318 	struct ustir_softc *sc = device_private(self);
319 	int s;
320 	int rv = 0;
321 
322 	DPRINTFN(0, ("ustir_detach: sc=%p flags=%d\n", sc, flags));
323 
324 	sc->sc_closing = sc->sc_dying = 1;
325 
326 	wakeup(&sc->sc_thread);
327 
328 	while (sc->sc_thread != NULL)
329 		tsleep(&sc->sc_closing, PWAIT, "usircl", 0);
330 
331 	/* Abort all pipes.  Causes processes waiting for transfer to wake. */
332 	if (sc->sc_rd_pipe != NULL) {
333 		usbd_abort_pipe(sc->sc_rd_pipe);
334 		usbd_close_pipe(sc->sc_rd_pipe);
335 		sc->sc_rd_pipe = NULL;
336 	}
337 	if (sc->sc_wr_pipe != NULL) {
338 		usbd_abort_pipe(sc->sc_wr_pipe);
339 		usbd_close_pipe(sc->sc_wr_pipe);
340 		sc->sc_wr_pipe = NULL;
341 	}
342 	wakeup(&sc->sc_ur_framelen);
343 	wakeup(&sc->sc_wr_buf);
344 
345 	s = splusb();
346 	if (--sc->sc_refcnt >= 0) {
347 		/* Wait for processes to go away. */
348 		usb_detach_waitold(sc->sc_dev);
349 	}
350 	splx(s);
351 
352 	if (sc->sc_child != NULL)
353 		rv = config_detach(sc->sc_child, flags);
354 
355 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
356 			   sc->sc_dev);
357 
358 	seldestroy(&sc->sc_rd_sel);
359 	seldestroy(&sc->sc_wr_sel);
360 
361 	return rv;
362 }
363 
364 /* Returns 0 if more data required, 1 if a complete frame was extracted */
365 static int
366 deframe_rd_ur(struct ustir_softc *sc)
367 {
368 	while (sc->sc_rd_index < sc->sc_rd_count) {
369 		u_int8_t const *buf;
370 		size_t buflen;
371 		enum frameresult fresult;
372 
373 		buf = &sc->sc_rd_buf[sc->sc_rd_index];
374 		buflen = sc->sc_rd_count - sc->sc_rd_index;
375 
376 		fresult = deframe_process(&sc->sc_framestate, &buf, &buflen);
377 
378 		sc->sc_rd_index = sc->sc_rd_count - buflen;
379 
380 		DPRINTFN(1,("%s: result=%d\n", __func__, (int)fresult));
381 
382 		switch (fresult) {
383 		case FR_IDLE:
384 		case FR_INPROGRESS:
385 		case FR_FRAMEBADFCS:
386 		case FR_FRAMEMALFORMED:
387 		case FR_BUFFEROVERRUN:
388 			break;
389 		case FR_FRAMEOK:
390 			sc->sc_ur_framelen = sc->sc_framestate.bufindex;
391 			wakeup(&sc->sc_ur_framelen); /* XXX should use flag */
392 			selnotify(&sc->sc_rd_sel, 0, 0);
393 			return 1;
394 		}
395 	}
396 
397 	/* Reset indices into USB-side buffer */
398 	sc->sc_rd_index = sc->sc_rd_count = 0;
399 
400 	return 0;
401 }
402 
403 /*
404  * Direction transitions:
405  *
406  * ustir_periodic() can switch the direction from:
407  *
408  *	output -> idle
409  *	output -> stalled
410  *	stalled -> idle
411  *	idle -> input
412  *
413  * ustir_rd_cb() can switch the direction from:
414  *
415  *	input -> stalled
416  *	input -> idle
417  *
418  * ustir_write() can switch the direction from:
419  *
420  *	idle -> output
421  */
422 Static void
423 ustir_periodic(struct ustir_softc *sc)
424 {
425 	DPRINTFN(60, ("%s: direction = %d\n",
426 		      __func__, sc->sc_direction));
427 
428 	if (sc->sc_direction == udir_output ||
429 	    sc->sc_direction == udir_stalled) {
430 		usbd_status err;
431 		u_int8_t regval;
432 
433 		DPRINTFN(60, ("%s: reading status register\n",
434 			      __func__));
435 
436 		err = ustir_read_reg(sc, STIR_REG_STATUS,
437 				     &regval);
438 		if (err != USBD_NORMAL_COMPLETION) {
439 			aprint_error_dev(sc->sc_dev,
440 			    "status register read failed: %s\n",
441 			     usbd_errstr(err));
442 		} else {
443 			DPRINTFN(10, ("%s: status register = 0x%x\n",
444 				      __func__,
445 				      (unsigned int)regval));
446 			if (sc->sc_direction == udir_output &&
447 			    !(regval & STIR_RSTATUS_FFDIR))
448 				/* Output has completed */
449 				sc->sc_direction = udir_idle;
450 			if (regval & STIR_RSTATUS_FFOVER) {
451 				/*
452 				 * On an overrun the FIFO hangs, and
453 				 * any data bulk transfers will stall.
454 				 * Reset the FIFO.
455 				 */
456 				sc->sc_direction = udir_stalled;
457 
458 				DPRINTFN(10, ("%s: clearing FIFO error\n",
459 					      __func__));
460 
461 				err = ustir_write_reg(sc, STIR_REG_STATUS,
462 						      STIR_RSTATUS_FFCLR);
463 				/* XXX if we fail partway through
464 				 * this, we may not recover? */
465 				if (err == USBD_NORMAL_COMPLETION)
466 					err = ustir_write_reg(sc,
467 							      STIR_REG_STATUS,
468 							      0);
469 				if (err != USBD_NORMAL_COMPLETION) {
470 					aprint_error_dev(sc->sc_dev,
471 					    "FIFO reset failed: %s\n",
472 					    usbd_errstr(err));
473 				} else {
474 					/* FIFO reset */
475 					sc->sc_direction = udir_idle;
476 				}
477 			}
478 		}
479 	}
480 
481 	if (sc->sc_wr_stalewrite && sc->sc_direction == udir_idle) {
482 		/*
483 		 * In a stale write case, we need to check if the
484 		 * write has completed.  Once that has happened, the
485 		 * write is no longer stale.
486 		 *
487 		 * But note that we may immediately start a read poll...
488 		 */
489 		sc->sc_wr_stalewrite = 0;
490 		wakeup(&sc->sc_wr_buf);
491 	}
492 
493 	if (!sc->sc_rd_readinprogress &&
494 	    (sc->sc_direction == udir_idle ||
495 	     sc->sc_direction == udir_input))
496 		/* Do a read poll if appropriate... */
497 		ustir_start_read(sc);
498 }
499 
500 Static void
501 ustir_thread(void *arg)
502 {
503 	struct ustir_softc *sc = arg;
504 
505 	DPRINTFN(20, ("%s: starting polling thread\n", __func__));
506 
507 	while (!sc->sc_closing) {
508 		if (!sc->sc_rd_readinprogress && !USTIR_BLOCK_RX_DATA(sc))
509 			ustir_periodic(sc);
510 
511 		if (!sc->sc_closing) {
512 			int error;
513 			error = tsleep(&sc->sc_thread, PWAIT,
514 				       "ustir", hz / 10);
515 			if (error == EWOULDBLOCK &&
516 			    sc->sc_rd_expectdataticks > 0)
517 				/*
518 				 * After a timeout decrement the tick
519 				 * counter within which time we expect
520 				 * data to arrive if we are receiving
521 				 * data...
522 				 */
523 				sc->sc_rd_expectdataticks--;
524 		}
525 	}
526 
527 	DPRINTFN(20, ("%s: exiting polling thread\n", __func__));
528 
529 	sc->sc_thread = NULL;
530 
531 	wakeup(&sc->sc_closing);
532 
533 	if (--sc->sc_refcnt < 0)
534 		usb_detach_wakeupold(sc->sc_dev);
535 
536 	kthread_exit(0);
537 }
538 
539 Static void
540 ustir_rd_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
541 	    usbd_status status)
542 {
543 	struct ustir_softc *sc = priv;
544 	u_int32_t size;
545 
546 	DPRINTFN(60, ("%s: sc=%p\n", __func__, sc));
547 
548 	/* Read is no longer in progress */
549 	sc->sc_rd_readinprogress = 0;
550 
551 	if (status == USBD_CANCELLED || sc->sc_closing) /* this is normal */
552 		return;
553 	if (status) {
554 		size = 0;
555 		sc->sc_rd_err = 1;
556 
557 		if (sc->sc_direction == udir_input ||
558 		    sc->sc_direction == udir_idle) {
559 			/*
560 			 * Receive error, probably need to clear error
561 			 * condition.
562 			 */
563 			sc->sc_direction = udir_stalled;
564 		}
565 	} else {
566 		usbd_get_xfer_status(xfer, NULL, NULL, &size, NULL);
567 	}
568 
569 	sc->sc_rd_index = 0;
570 	sc->sc_rd_count = size;
571 
572 	DPRINTFN(((size > 0 || sc->sc_rd_err != 0) ? 20 : 60),
573 		 ("%s: sc=%p size=%u, err=%d\n", __func__,
574 		  sc, size, sc->sc_rd_err));
575 
576 #ifdef USTIR_DEBUG
577 	if (ustirdebug >= 20 && size > 0)
578 		ustir_dumpdata(sc->sc_rd_buf, size, __func__);
579 #endif
580 
581 	if (!deframe_rd_ur(sc)) {
582 		if (!deframe_isclear(&sc->sc_framestate) && size == 0 &&
583 		    sc->sc_rd_expectdataticks == 0) {
584 			/*
585 			 * Expected data, but didn't get it
586 			 * within expected time...
587 			 */
588 			DPRINTFN(5,("%s: incoming packet timeout\n",
589 				    __func__));
590 			deframe_clear(&sc->sc_framestate);
591 		} else if (size > 0) {
592 			/*
593 			 * If we also received actual data, reset the
594 			 * data read timeout and wake up the possibly
595 			 * sleeping thread...
596 			 */
597 			sc->sc_rd_expectdataticks = 2;
598 			wakeup(&sc->sc_thread);
599 		}
600 	}
601 
602 	/*
603 	 * Check if incoming data has stopped, or that we cannot
604 	 * safely read any more data.  In the case of the latter we
605 	 * must switch to idle so that a write will not block...
606 	 */
607 	if (sc->sc_direction == udir_input &&
608 	    ((size == 0 && sc->sc_rd_expectdataticks == 0) ||
609 	     USTIR_BLOCK_RX_DATA(sc))) {
610 		DPRINTFN(8,("%s: idling on packet timeout, "
611 			    "complete frame, or no data\n", __func__));
612 		sc->sc_direction = udir_idle;
613 
614 		/* Wake up for possible output */
615 		wakeup(&sc->sc_wr_buf);
616 		selnotify(&sc->sc_wr_sel, 0, 0);
617 	}
618 }
619 
620 Static usbd_status
621 ustir_start_read(struct ustir_softc *sc)
622 {
623 	usbd_status err;
624 
625 	DPRINTFN(60,("%s: sc=%p, size=%d\n", __func__, sc,
626 		     sc->sc_params.maxsize));
627 
628 	if (sc->sc_dying)
629 		return USBD_IOERROR;
630 
631 	if (USTIR_BLOCK_RX_DATA(sc) || deframe_rd_ur(sc)) {
632 		/*
633 		 * Can't start reading just yet.  Since we aren't
634 		 * going to start a read, have to switch direction to
635 		 * idle.
636 		 */
637 		sc->sc_direction = udir_idle;
638 		return USBD_NORMAL_COMPLETION;
639 	}
640 
641 	/* Starting a read... */
642 	sc->sc_rd_readinprogress = 1;
643 	sc->sc_direction = udir_input;
644 
645 	if (sc->sc_rd_err) {
646 		sc->sc_rd_err = 0;
647 		DPRINTFN(0, ("%s: clear stall\n", __func__));
648 		usbd_clear_endpoint_stall(sc->sc_rd_pipe);
649 	}
650 
651 	usbd_setup_xfer(sc->sc_rd_xfer, sc->sc_rd_pipe, sc, sc->sc_rd_buf,
652 			sc->sc_params.maxsize,
653 			USBD_SHORT_XFER_OK | USBD_NO_COPY,
654 			USBD_NO_TIMEOUT, ustir_rd_cb);
655 	err = usbd_transfer(sc->sc_rd_xfer);
656 	if (err != USBD_IN_PROGRESS) {
657 		DPRINTFN(0, ("%s: err=%d\n", __func__, (int)err));
658 		return err;
659 	}
660 	return USBD_NORMAL_COMPLETION;
661 }
662 
663 Static int
664 ustir_activate(device_t self, enum devact act)
665 {
666 	struct ustir_softc *sc = device_private(self);
667 
668 	switch (act) {
669 	case DVACT_DEACTIVATE:
670 		sc->sc_dying = 1;
671 		return 0;
672 	default:
673 		return EOPNOTSUPP;
674 	}
675 }
676 
677 /* ARGSUSED */
678 Static int
679 ustir_open(void *h, int flag, int mode,
680     struct lwp *l)
681 {
682 	struct ustir_softc *sc = h;
683 	int error;
684 	usbd_status err;
685 
686 	DPRINTFN(0, ("%s: sc=%p\n", __func__, sc));
687 
688 	err = usbd_open_pipe(sc->sc_iface, sc->sc_rd_addr, 0, &sc->sc_rd_pipe);
689 	if (err != USBD_NORMAL_COMPLETION) {
690 		error = EIO;
691 		goto bad1;
692 	}
693 	err = usbd_open_pipe(sc->sc_iface, sc->sc_wr_addr, 0, &sc->sc_wr_pipe);
694 	if (err != USBD_NORMAL_COMPLETION) {
695 		error = EIO;
696 		goto bad2;
697 	}
698 	sc->sc_rd_xfer = usbd_alloc_xfer(sc->sc_udev);
699 	if (sc->sc_rd_xfer == NULL) {
700 		error = ENOMEM;
701 		goto bad3;
702 	}
703 	sc->sc_wr_xfer = usbd_alloc_xfer(sc->sc_udev);
704 	if (sc->sc_wr_xfer == NULL) {
705 		error = ENOMEM;
706 		goto bad4;
707 	}
708 	sc->sc_rd_buf = usbd_alloc_buffer(sc->sc_rd_xfer,
709 			    IRDA_MAX_FRAME_SIZE);
710 	if (sc->sc_rd_buf == NULL) {
711 		error = ENOMEM;
712 		goto bad5;
713 	}
714 	sc->sc_wr_buf = usbd_alloc_buffer(sc->sc_wr_xfer,
715 			    IRDA_MAX_FRAME_SIZE + STIR_OUTPUT_HEADER_SIZE);
716 	if (sc->sc_wr_buf == NULL) {
717 		error = ENOMEM;
718 		goto bad5;
719 	}
720 	sc->sc_ur_buf = malloc(IRDA_MAX_FRAME_SIZE, M_USBDEV, M_NOWAIT);
721 	if (sc->sc_ur_buf == NULL) {
722 		error = ENOMEM;
723 		goto bad5;
724 	}
725 
726 	sc->sc_rd_index = sc->sc_rd_count = 0;
727 	sc->sc_closing = 0;
728 	sc->sc_rd_readinprogress = 0;
729 	sc->sc_rd_expectdataticks = 0;
730 	sc->sc_ur_framelen = 0;
731 	sc->sc_rd_err = 0;
732 	sc->sc_wr_stalewrite = 0;
733 	sc->sc_speedrec = NULL;
734 	sc->sc_direction = udir_idle;
735 	sc->sc_params.speed = 0;
736 	sc->sc_params.ebofs = 0;
737 	sc->sc_params.maxsize = IRDA_MAX_FRAME_SIZE;
738 
739 	deframe_init(&sc->sc_framestate, sc->sc_ur_buf, IRDA_MAX_FRAME_SIZE);
740 
741 	/* Increment reference for thread */
742 	sc->sc_refcnt++;
743 
744 	error = kthread_create(PRI_NONE, 0, NULL, ustir_thread, sc,
745 	    &sc->sc_thread, "%s", device_xname(sc->sc_dev));
746 	if (error) {
747 		sc->sc_refcnt--;
748 		goto bad5;
749 	}
750 
751 	return 0;
752 
753  bad5:
754 	usbd_free_xfer(sc->sc_wr_xfer);
755 	sc->sc_wr_xfer = NULL;
756  bad4:
757 	usbd_free_xfer(sc->sc_rd_xfer);
758 	sc->sc_rd_xfer = NULL;
759  bad3:
760 	usbd_close_pipe(sc->sc_wr_pipe);
761 	sc->sc_wr_pipe = NULL;
762  bad2:
763 	usbd_close_pipe(sc->sc_rd_pipe);
764 	sc->sc_rd_pipe = NULL;
765  bad1:
766 	return error;
767 }
768 
769 /* ARGSUSED */
770 Static int
771 ustir_close(void *h, int flag, int mode,
772     struct lwp *l)
773 {
774 	struct ustir_softc *sc = h;
775 
776 	DPRINTFN(0, ("%s: sc=%p\n", __func__, sc));
777 
778 	sc->sc_refcnt++;
779 
780 	sc->sc_rd_readinprogress = 1;
781 	sc->sc_closing = 1;
782 
783 	wakeup(&sc->sc_thread);
784 
785 	while (sc->sc_thread != NULL)
786 		tsleep(&sc->sc_closing, PWAIT, "usircl", 0);
787 
788 	if (sc->sc_rd_pipe != NULL) {
789 		usbd_abort_pipe(sc->sc_rd_pipe);
790 		usbd_close_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 		usbd_close_pipe(sc->sc_wr_pipe);
796 		sc->sc_wr_pipe = NULL;
797 	}
798 	if (sc->sc_rd_xfer != NULL) {
799 		usbd_free_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_free_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 		free(sc->sc_ur_buf, M_USBDEV);
810 		sc->sc_ur_buf = NULL;
811 	}
812 
813 	if (--sc->sc_refcnt < 0)
814 		usb_detach_wakeupold(sc->sc_dev);
815 
816 	return 0;
817 }
818 
819 /* ARGSUSED */
820 Static int
821 ustir_read(void *h, struct uio *uio, int flag)
822 {
823 	struct ustir_softc *sc = h;
824 	int s;
825 	int error;
826 	u_int uframelen;
827 
828 	DPRINTFN(1,("%s: sc=%p\n", __func__, sc));
829 
830 	if (sc->sc_dying)
831 		return EIO;
832 
833 #ifdef DIAGNOSTIC
834 	if (sc->sc_rd_buf == NULL)
835 		return EINVAL;
836 #endif
837 
838 	sc->sc_refcnt++;
839 
840 	if (!sc->sc_rd_readinprogress && !USTIR_BLOCK_RX_DATA(sc))
841 		/* Possibly wake up polling thread */
842 		wakeup(&sc->sc_thread);
843 
844 	do {
845 		s = splusb();
846 		while (sc->sc_ur_framelen == 0) {
847 			DPRINTFN(5,("%s: calling tsleep()\n", __func__));
848 			error = tsleep(&sc->sc_ur_framelen, PZERO | PCATCH,
849 				       "usirrd", 0);
850 			if (sc->sc_dying)
851 				error = EIO;
852 			if (error) {
853 				splx(s);
854 				DPRINTFN(0, ("%s: tsleep() = %d\n",
855 					     __func__, error));
856 				goto ret;
857 			}
858 		}
859 		splx(s);
860 
861 		uframelen = sc->sc_ur_framelen;
862 		DPRINTFN(1,("%s: sc=%p framelen=%u, hdr=0x%02x\n",
863 			    __func__, sc, uframelen, sc->sc_ur_buf[0]));
864 		if (uframelen > uio->uio_resid)
865 			error = EINVAL;
866 		else
867 			error = uiomove(sc->sc_ur_buf, uframelen, uio);
868 		sc->sc_ur_framelen = 0;
869 
870 		if (!deframe_rd_ur(sc) && uframelen > 0) {
871 			/*
872 			 * Need to wait for another read to obtain a
873 			 * complete frame...  If we also obtained
874 			 * actual data, wake up the possibly sleeping
875 			 * thread immediately...
876 			 */
877 			wakeup(&sc->sc_thread);
878 		}
879 	} while (uframelen == 0);
880 
881 	DPRINTFN(1,("%s: return %d\n", __func__, error));
882 
883  ret:
884 	if (--sc->sc_refcnt < 0)
885 		usb_detach_wakeupold(sc->sc_dev);
886 	return error;
887 }
888 
889 /* ARGSUSED */
890 Static int
891 ustir_write(void *h, struct uio *uio, int flag)
892 {
893 	struct ustir_softc *sc = h;
894 	usbd_status err;
895 	u_int32_t wrlen;
896 	int error, sirlength;
897 	u_int8_t *wrbuf;
898 	int s;
899 
900 	DPRINTFN(1,("%s: sc=%p\n", __func__, sc));
901 
902 	if (sc->sc_dying)
903 		return EIO;
904 
905 #ifdef DIAGNOSTIC
906 	if (sc->sc_wr_buf == NULL)
907 		return EINVAL;
908 #endif
909 
910 	wrlen = uio->uio_resid;
911 	if (wrlen > sc->sc_params.maxsize)
912 		return EINVAL;
913 
914 	sc->sc_refcnt++;
915 
916 	if (!USTIR_BLOCK_RX_DATA(sc)) {
917 		/*
918 		 * If reads are not blocked, determine what action we
919 		 * should potentially take...
920 		 */
921 		if (sc->sc_direction == udir_output) {
922 			/*
923 			 * If the last operation was an output, wait for the
924 			 * polling thread to check for incoming data.
925 			 */
926 			sc->sc_wr_stalewrite = 1;
927 			wakeup(&sc->sc_thread);
928 		} else if (!sc->sc_rd_readinprogress &&
929 			   (sc->sc_direction == udir_idle ||
930 			    sc->sc_direction == udir_input)) {
931 			/* If idle, check for input before outputting */
932 			ustir_start_read(sc);
933 		}
934 	}
935 
936 	s = splusb();
937 	while (sc->sc_wr_stalewrite ||
938 	       (sc->sc_direction != udir_output &&
939 		sc->sc_direction != udir_idle)) {
940 		DPRINTFN(5, ("%s: sc=%p stalewrite=%d direction=%d, "
941 			     "calling tsleep()\n", __func__,
942 			     sc, sc->sc_wr_stalewrite, sc->sc_direction));
943 		error = tsleep(&sc->sc_wr_buf, PZERO | PCATCH,
944 			       "usirwr", 0);
945 		if (sc->sc_dying)
946 			error = EIO;
947 		if (error) {
948 			splx(s);
949 			DPRINTFN(0, ("%s: tsleep() = %d\n", __func__,
950 				     error));
951 			goto ret;
952 		}
953 	}
954 	splx(s);
955 
956 	wrbuf = sc->sc_wr_buf;
957 
958 	/* Build header */
959 	wrbuf[0] = STIR_OUTPUT_HEADER_BYTE0;
960 	wrbuf[1] = STIR_OUTPUT_HEADER_BYTE1;
961 
962 	sirlength = irda_sir_frame(&wrbuf[STIR_OUTPUT_HEADER_SIZE],
963 				   MAX_USTIR_OUTPUT_FRAME -
964 				   STIR_OUTPUT_HEADER_SIZE,
965 				   uio, sc->sc_params.ebofs);
966 	if (sirlength < 0) {
967 		error = -sirlength;
968 	} else {
969 		u_int32_t btlen;
970 
971 		DPRINTFN(1, ("%s: transfer %u bytes\n", __func__,
972 			     (unsigned int)wrlen));
973 
974 		wrbuf[2] = sirlength & 0xff;
975 		wrbuf[3] = (sirlength >> 8) & 0xff;
976 
977 		btlen = STIR_OUTPUT_HEADER_SIZE + sirlength;
978 
979 		sc->sc_direction = udir_output;
980 
981 #ifdef USTIR_DEBUG
982 		if (ustirdebug >= 20)
983 			ustir_dumpdata(wrbuf, btlen, __func__);
984 #endif
985 
986 		err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe,
987 					 USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
988 					 USTIR_WR_TIMEOUT,
989 					 wrbuf, &btlen, "ustiwr");
990 		DPRINTFN(2, ("%s: err=%d\n", __func__, err));
991 		if (err != USBD_NORMAL_COMPLETION) {
992 			if (err == USBD_INTERRUPTED)
993 				error = EINTR;
994 			else if (err == USBD_TIMEOUT)
995 				error = ETIMEDOUT;
996 			else
997 				error = EIO;
998 		} else {
999 			error = 0;
1000 		}
1001 	}
1002 
1003  ret:
1004 	if (--sc->sc_refcnt < 0)
1005 		usb_detach_wakeupold(sc->sc_dev);
1006 
1007 	DPRINTFN(1,("%s: sc=%p done\n", __func__, sc));
1008 	return error;
1009 }
1010 
1011 Static int
1012 ustir_poll(void *h, int events, struct lwp *l)
1013 {
1014 	struct ustir_softc *sc = h;
1015 	int revents = 0;
1016 
1017 	DPRINTFN(1,("%s: sc=%p\n", __func__, sc));
1018 
1019 	if (events & (POLLOUT | POLLWRNORM)) {
1020 		if (sc->sc_direction != udir_input) {
1021 			revents |= events & (POLLOUT | POLLWRNORM);
1022 		} else {
1023 			DPRINTFN(2,("%s: recording write select\n",
1024 				    __func__));
1025 			selrecord(l, &sc->sc_wr_sel);
1026 		}
1027 	}
1028 
1029 	if (events & (POLLIN | POLLRDNORM)) {
1030 		if (sc->sc_ur_framelen != 0) {
1031 			DPRINTFN(2,("%s: have data\n", __func__));
1032 			revents |= events & (POLLIN | POLLRDNORM);
1033 		} else {
1034 			DPRINTFN(2,("%s: recording read select\n",
1035 				    __func__));
1036 			selrecord(l, &sc->sc_rd_sel);
1037 		}
1038 	}
1039 
1040 	return revents;
1041 }
1042 
1043 static void
1044 filt_ustirrdetach(struct knote *kn)
1045 {
1046 	struct ustir_softc *sc = kn->kn_hook;
1047 	int s;
1048 
1049 	s = splusb();
1050 	SLIST_REMOVE(&sc->sc_rd_sel.sel_klist, kn, knote, kn_selnext);
1051 	splx(s);
1052 }
1053 
1054 /* ARGSUSED */
1055 static int
1056 filt_ustirread(struct knote *kn, long hint)
1057 {
1058 	struct ustir_softc *sc = kn->kn_hook;
1059 
1060 	kn->kn_data = sc->sc_ur_framelen;
1061 	return (kn->kn_data > 0);
1062 }
1063 
1064 static void
1065 filt_ustirwdetach(struct knote *kn)
1066 {
1067 	struct ustir_softc *sc = kn->kn_hook;
1068 	int s;
1069 
1070 	s = splusb();
1071 	SLIST_REMOVE(&sc->sc_wr_sel.sel_klist, kn, knote, kn_selnext);
1072 	splx(s);
1073 }
1074 
1075 /* ARGSUSED */
1076 static int
1077 filt_ustirwrite(struct knote *kn, long hint)
1078 {
1079 	struct ustir_softc *sc = kn->kn_hook;
1080 
1081 	kn->kn_data = 0;
1082 	return (sc->sc_direction != udir_input);
1083 }
1084 
1085 static const struct filterops ustirread_filtops =
1086 	{ 1, NULL, filt_ustirrdetach, filt_ustirread };
1087 static const struct filterops ustirwrite_filtops =
1088 	{ 1, NULL, filt_ustirwdetach, filt_ustirwrite };
1089 
1090 Static int
1091 ustir_kqfilter(void *h, struct knote *kn)
1092 {
1093 	struct ustir_softc *sc = h;
1094 	struct klist *klist;
1095 	int s;
1096 
1097 	switch (kn->kn_filter) {
1098 	case EVFILT_READ:
1099 		klist = &sc->sc_rd_sel.sel_klist;
1100 		kn->kn_fop = &ustirread_filtops;
1101 		break;
1102 	case EVFILT_WRITE:
1103 		klist = &sc->sc_wr_sel.sel_klist;
1104 		kn->kn_fop = &ustirwrite_filtops;
1105 		break;
1106 	default:
1107 		return (EINVAL);
1108 	}
1109 
1110 	kn->kn_hook = sc;
1111 
1112 	s = splusb();
1113 	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1114 	splx(s);
1115 
1116 	return (0);
1117 }
1118 
1119 #ifdef USTIR_DEBUG_IOCTLS
1120 Static int ustir_ioctl(void *h, u_long cmd, void *addr, int flag, struct lwp *l)
1121 {
1122 	struct ustir_softc *sc = h;
1123 	int error;
1124 	unsigned int regnum;
1125 	usbd_status err;
1126 	u_int8_t regdata;
1127 
1128 	if (sc->sc_dying)
1129 		return EIO;
1130 
1131 	sc->sc_refcnt++;
1132 
1133 	error = 0;
1134 	switch (cmd) {
1135 	case USTIR_READ_REGISTER:
1136 		regnum = *(unsigned int *)addr;
1137 
1138 		if (regnum > STIR_MAX_REG) {
1139 			error = EINVAL;
1140 			break;
1141 		}
1142 
1143 		err = ustir_read_reg(sc, regnum, &regdata);
1144 
1145 		DPRINTFN(10, ("%s: regget(%u) = 0x%x\n", __func__,
1146 			      regnum, (unsigned int)regdata));
1147 
1148 		*(unsigned int *)addr = regdata;
1149 		if (err != USBD_NORMAL_COMPLETION) {
1150 			printf("%s: register read failed: %s\n",
1151 			       device_xname(sc->sc_dev),
1152 			       usbd_errstr(err));
1153 			error = EIO;
1154 		}
1155 		break;
1156 
1157 	case USTIR_WRITE_REGISTER:
1158 		regnum = *(unsigned int *)addr;
1159 		regdata = (regnum >> 8) & 0xff;
1160 		regnum = regnum & 0xff;
1161 
1162 		if (regnum > STIR_MAX_REG) {
1163 			error = EINVAL;
1164 			break;
1165 		}
1166 
1167 		DPRINTFN(10, ("%s: regset(%u, 0x%x)\n", __func__,
1168 			      regnum, (unsigned int)regdata));
1169 
1170 		err = ustir_write_reg(sc, regnum, regdata);
1171 		if (err != USBD_NORMAL_COMPLETION) {
1172 			printf("%s: register write failed: %s\n",
1173 			       device_xname(sc->sc_dev),
1174 			       usbd_errstr(err));
1175 			error = EIO;
1176 		}
1177 		break;
1178 
1179 	case USTIR_DEBUG_LEVEL:
1180 #ifdef USTIR_DEBUG
1181 		ustirdebug = *(int *)addr;
1182 #endif
1183 		break;
1184 
1185 	case USTIR_DEBUG_OPERATION:
1186 		break;
1187 
1188 	default:
1189 		error = EINVAL;
1190 		break;
1191 	}
1192 
1193 	if (--sc->sc_refcnt < 0)
1194 		usb_detach_wakeupold(sc->sc_dev);
1195 
1196 	return error;
1197 }
1198 #endif
1199 
1200 Static int
1201 ustir_set_params(void *h, struct irda_params *p)
1202 {
1203 	struct ustir_softc *sc = h;
1204 	struct ustir_speedrec const *speedblk;
1205 	int i;
1206 
1207 	DPRINTFN(0, ("%s: sc=%p, speed=%d ebofs=%d maxsize=%d\n", __func__,
1208 		     sc, p->speed, p->ebofs, p->maxsize));
1209 
1210 	if (sc->sc_dying)
1211 		return EIO;
1212 
1213 	speedblk = NULL;
1214 
1215 	if (sc->sc_speedrec == NULL || p->speed != sc->sc_speedrec->speed) {
1216 		/* find speed */
1217 		for (i = 0; i < USTIR_NSPEEDS; i++) {
1218 			if (ustir_speeds[i].speed == p->speed) {
1219 				speedblk = &ustir_speeds[i];
1220 				goto found2;
1221 			}
1222 		}
1223 		/* no good value found */
1224 		return EINVAL;
1225 	found2:
1226 		;
1227 	}
1228 	if (p->maxsize != sc->sc_params.maxsize) {
1229 		if (p->maxsize > IRDA_MAX_FRAME_SIZE)
1230 			return EINVAL;
1231 		sc->sc_params.maxsize = p->maxsize;
1232 	}
1233 
1234 	sc->sc_params = *p;
1235 
1236 	if (speedblk != NULL) {
1237 		usbd_status err;
1238 		u_int8_t regmode;
1239 		u_int8_t regbrate;
1240 
1241 		sc->sc_speedrec = speedblk;
1242 
1243 		regmode = STIR_BRMODE_MODEREG(speedblk->config);
1244 		regbrate = STIR_BRMODE_BRATEREG(speedblk->config);
1245 
1246 		/*
1247 		 * FFSPRST must be set to enable the FIFO.
1248 		 */
1249 		regmode |= STIR_RMODE_FFSPRST;
1250 
1251 		DPRINTFN(10, ("%s: setting BRATE = %x\n", __func__,
1252 			      (unsigned int)regbrate));
1253 		err = ustir_write_reg(sc, STIR_REG_BRATE, regbrate);
1254 		if (err == USBD_NORMAL_COMPLETION) {
1255 			DPRINTFN(10, ("%s: setting MODE = %x\n", __func__,
1256 				      (unsigned int)regmode));
1257 			err = ustir_write_reg(sc, STIR_REG_MODE, regmode);
1258 		}
1259 		if (err != USBD_NORMAL_COMPLETION) {
1260 			DPRINTFN(10, ("%s: error setting register: %s\n",
1261 				      __func__, usbd_errstr(err)));
1262 			return EIO;
1263 		}
1264 	}
1265 
1266 	return 0;
1267 }
1268 
1269 Static int
1270 ustir_get_speeds(void *h, int *speeds)
1271 {
1272 	struct ustir_softc *sc = h;
1273 
1274 	DPRINTFN(0, ("%s: sc=%p\n", __func__, sc));
1275 
1276 	if (sc->sc_dying)
1277 		return EIO;
1278 
1279 	/* All these speeds are supported */
1280 	*speeds = IRDA_SPEED_4000000 |
1281 		IRDA_SPEED_1152000 |
1282 		IRDA_SPEED_576000 |
1283 		IRDA_SPEED_115200 |
1284 		IRDA_SPEED_57600 |
1285 		IRDA_SPEED_38400 |
1286 		IRDA_SPEED_19200 |
1287 		IRDA_SPEED_9600 |
1288 		IRDA_SPEED_2400;
1289 
1290 	return 0;
1291 }
1292 
1293 Static int
1294 ustir_get_turnarounds(void *h, int *turnarounds)
1295 {
1296 	struct ustir_softc *sc = h;
1297 
1298 	DPRINTFN(0, ("%s: sc=%p\n", __func__, sc));
1299 
1300 	if (sc->sc_dying)
1301 		return EIO;
1302 
1303 	/*
1304 	 * Documentation is on the light side with respect to
1305 	 * turnaround time for this device.
1306 	 */
1307 	*turnarounds = IRDA_TURNT_10000;
1308 
1309 	return 0;
1310 }
1311