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