xref: /dragonfly/sys/dev/misc/cmx/cmx.c (revision dcd37f7d)
1 /*-
2  * Copyright (c) 2006-2007 Daniel Roethlisberger <daniel@roe.ch>
3  * Copyright (c) 2000-2004 OMNIKEY GmbH (www.omnikey.com)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD: src/sys/dev/cmx/cmx.c,v 1.1 2008/03/06 08:09:45 rink Exp $
29  * $DragonFly: src/sys/dev/misc/cmx/cmx.c,v 1.2 2008/08/08 18:33:11 hasso Exp $
30  */
31 
32 /*
33  * OMNIKEY CardMan 4040 a.k.a. CardMan eXtended (cmx) driver.
34  * This is a PCMCIA based smartcard reader which seems to work
35  * like an I/O port mapped USB CCID smartcard device.
36  *
37  * I/O originally based on Linux driver version 1.1.0 by OMNIKEY.
38  * Dual GPL/BSD.  Almost all of the code has been rewritten.
39  * $Omnikey: cm4040_cs.c,v 1.7 2004/10/04 09:08:50 jp Exp $
40  */
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/sockio.h>
46 #include <sys/mbuf.h>
47 #include <sys/event.h>
48 #include <sys/conf.h>
49 #include <sys/fcntl.h>
50 #include <sys/uio.h>
51 #include <sys/types.h>
52 #include <sys/lock.h>
53 #include <sys/device.h>
54 #include <sys/thread2.h>
55 
56 #include <sys/module.h>
57 #include <sys/bus.h>
58 #include <sys/resource.h>
59 #include <sys/rman.h>
60 
61 #include "cmxvar.h"
62 #include "cmxreg.h"
63 
64 #ifdef CMX_DEBUG
65 #define	DEBUG_printf(dev, fmt, args...) \
66 	device_printf(dev, "%s: " fmt, __FUNCTION__, ##args)
67 #else
68 #define	DEBUG_printf(dev, fmt, args...)
69 #endif
70 
71 #define	SPIN_COUNT				1000
72 #define	WAIT_TICKS				(hz/100)
73 #define	POLL_TICKS				(hz/10)
74 
75 /* possibly bogus */
76 #define	CCID_DRIVER_BULK_DEFAULT_TIMEOUT	(150*hz)
77 #define	CCID_DRIVER_ASYNC_POWERUP_TIMEOUT	(35*hz)
78 #define	CCID_DRIVER_MINIMUM_TIMEOUT		(3*hz)
79 
80 #ifdef CMX_DEBUG
81 static char	BSRBITS[] = "\020"
82 	"\01BULK_OUT_FULL"		/* 0x01 */
83 	"\02BULK_IN_FULL"		/* 0x02 */
84 	"\03(0x04)";			/* 0x04 */
85 #ifdef CMX_INTR
86 static char	SCRBITS[] = "\020"
87 	"\01POWER_DOWN"			/* 0x01 */
88 	"\02PULSE_INTERRUPT"		/* 0x02 */
89 	"\03HOST_TO_READER_DONE"	/* 0x04 */
90 	"\04READER_TO_HOST_DONE"	/* 0x08 */
91 	"\05ACK_NOTIFY"			/* 0x10 */
92 	"\06EN_NOTIFY"			/* 0x20 */
93 	"\07ABORT"			/* 0x40 */
94 	"\10HOST_TO_READER_START";	/* 0x80 */
95 #endif /* CMX_INTR */
96 static char	POLLBITS[] = "\020"
97 	"\01POLLIN"			/* 0x0001 */
98 	"\02POLLPRI"			/* 0x0002 */
99 	"\03POLLOUT"			/* 0x0004 */
100 	"\04POLLERR"			/* 0x0008 */
101 	"\05POLLHUP"			/* 0x0010 */
102 	"\06POLLINVAL"			/* 0x0020 */
103 	"\07POLLRDNORM"			/* 0x0040 */
104 	"\10POLLRDBAND"			/* 0x0080 */
105 	"\11POLLWRBAND";		/* 0x0100 */
106 static char	MODEBITS[] = "\020"
107 	"\01READ"			/* 0x0001 */
108 	"\02WRITE"			/* 0x0002 */
109 	"\03NONBLOCK"			/* 0x0004 */
110 	"\04APPEND"			/* 0x0008 */
111 	"\05SHLOCK"			/* 0x0010 */
112 	"\06EXLOCK"			/* 0x0020 */
113 	"\07ASYNC"			/* 0x0040 */
114 	"\10FSYNC"			/* 0x0080 */
115 	"\11NOFOLLOW"			/* 0x0100 */
116 	"\12CREAT"			/* 0x0200 */
117 	"\13TRUNK"			/* 0x0400 */
118 	"\14EXCL"			/* 0x0800 */
119 	"\15(0x1000)"			/* 0x1000 */
120 	"\16(0x2000)"			/* 0x2000 */
121 	"\17HASLOCK"			/* 0x4000 */
122 	"\20NOCTTY"			/* 0x8000 */
123 	"\21DIRECT";			/* 0x00010000 */
124 #endif /* CMX_DEBUG */
125 
126 devclass_t cmx_devclass;
127 
128 static d_open_t		cmx_open;
129 static d_close_t	cmx_close;
130 static d_read_t		cmx_read;
131 static d_write_t	cmx_write;
132 static d_kqfilter_t	cmx_kqfilter;
133 #ifdef CMX_INTR
134 static void		cmx_intr(void *arg);
135 #endif
136 
137 static void cmx_filter_detach(struct knote *);
138 static int cmx_filter_read(struct knote *, long);
139 static int cmx_filter_write(struct knote *, long);
140 
141 #define CDEV_MAJOR	185
142 static struct dev_ops cmx_ops = {
143 	{ "cmx", CDEV_MAJOR, D_KQFILTER },
144 	.d_open =	cmx_open,
145 	.d_close =	cmx_close,
146 	.d_read =	cmx_read,
147 	.d_write =	cmx_write,
148 	.d_kqfilter =	cmx_kqfilter
149 };
150 
151 /*
152  * Initialize the softc structure.  Must be called from
153  * the bus specific device allocation routine.
154  */
155 void
156 cmx_init_softc(device_t dev)
157 {
158 	struct cmx_softc *sc = device_get_softc(dev);
159 	sc->dev = dev;
160 	sc->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
161 }
162 
163 /*
164  * Allocate driver resources.  Must be called from the
165  * bus specific device allocation routine.  Caller must
166  * ensure to call cmx_release_resources to free the
167  * resources when detaching.
168  * Return zero if successful, and ENOMEM if the resources
169  * could not be allocated.
170  */
171 int
172 cmx_alloc_resources(device_t dev)
173 {
174 	struct cmx_softc *sc = device_get_softc(dev);
175 #ifdef CMX_INTR
176 	int rv;
177 #endif
178 
179 	sc->ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
180 			&sc->ioport_rid, RF_ACTIVE);
181 	if (!sc->ioport) {
182 		device_printf(dev, "failed to allocate io port\n");
183 		return ENOMEM;
184 	}
185 	sc->bst = rman_get_bustag(sc->ioport);
186 	sc->bsh = rman_get_bushandle(sc->ioport);
187 
188 #ifdef CMX_INTR
189 	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
190 			&sc->irq_rid, RF_ACTIVE);
191 	if (!sc->irq) {
192 		device_printf(dev, "failed to allocate irq\n");
193 		return ENOMEM;
194 	}
195 	if ((rv = bus_setup_intr(dev, sc->irq, 0, cmx_intr, sc,
196 			&sc->ih, NULL)) != 0) {
197 		device_printf(dev, "failed to set up irq\n");
198 		return ENOMEM;
199 	}
200 #endif
201 
202 	lockinit(&sc->mtx, "cmx softc lock", 0, LK_CANRECURSE);
203 	callout_init(&sc->ch);
204 
205 	return 0;
206 }
207 
208 /*
209  * Release the resources allocated by cmx_allocate_resources.
210  */
211 void
212 cmx_release_resources(device_t dev)
213 {
214 	struct cmx_softc *sc = device_get_softc(dev);
215 
216 	lockuninit(&sc->mtx);
217 
218 #ifdef CMX_INTR
219 	if (sc->ih) {
220 		bus_teardown_intr(dev, sc->irq, sc->ih);
221 		sc->ih = NULL;
222 	}
223 	if (sc->irq) {
224 		bus_release_resource(dev, SYS_RES_IRQ,
225 				sc->irq_rid, sc->irq);
226 		sc->irq = NULL;
227 	}
228 #endif
229 
230 	if (sc->ioport) {
231 		bus_deactivate_resource(dev, SYS_RES_IOPORT,
232 				sc->ioport_rid, sc->ioport);
233 		bus_release_resource(dev, SYS_RES_IOPORT,
234 				sc->ioport_rid, sc->ioport);
235 		sc->ioport = NULL;
236 	}
237 	return;
238 }
239 
240 /*
241  * Bus independant device attachment routine.  Creates the
242  * character device node.
243  */
244 int
245 cmx_attach(device_t dev)
246 {
247 	struct cmx_softc *sc = device_get_softc(dev);
248 
249 	if (!sc || sc->dying)
250 		return ENXIO;
251 
252 	sc->cdev = make_dev(&cmx_ops, 0, UID_ROOT, GID_WHEEL, 0600,
253 	                    "cmx%d", device_get_unit(dev));
254 	if (!sc->cdev) {
255 		device_printf(dev, "failed to create character device\n");
256 		return ENOMEM;
257 	}
258 	sc->cdev->si_drv1 = sc;
259 
260 	return 0;
261 }
262 
263 /*
264  * Bus independant device detachment routine.  Makes sure all
265  * allocated resources are freed, callouts disabled and waiting
266  * processes unblocked.
267  */
268 int
269 cmx_detach(device_t dev)
270 {
271 	struct cmx_softc *sc = device_get_softc(dev);
272 
273 	DEBUG_printf(dev, "called\n");
274 
275 	sc->dying = 1;
276 
277 	CMX_LOCK(sc);
278 	if (sc->polling) {
279 		DEBUG_printf(sc->dev, "disabling polling\n");
280 		callout_stop(&sc->ch);
281 		sc->polling = 0;
282 		CMX_UNLOCK(sc);
283 		KNOTE(&sc->kq.ki_note, 0);
284 	} else {
285 		CMX_UNLOCK(sc);
286 	}
287 
288 	wakeup(sc);
289 	DEBUG_printf(dev, "releasing resources\n");
290 	cmx_release_resources(dev);
291 	dev_ops_remove_minor(&cmx_ops, device_get_unit(dev));
292 
293 	return 0;
294 }
295 
296 /*
297  * Wait for buffer status register events.  If test is non-zero,
298  * wait until flags are set, otherwise wait until flags are unset.
299  * Will spin SPIN_COUNT times, then sleep until timeout is reached.
300  * Returns zero if event happened, EIO if the timeout was reached,
301  * and ENXIO if the device was detached in the meantime.  When that
302  * happens, the caller must quit immediately, since a detach is
303  * in progress.
304  */
305 static inline int
306 cmx_wait_BSR(struct cmx_softc *sc, uint8_t flags, int test)
307 {
308 	int rv;
309 
310 	for (int i = 0; i < SPIN_COUNT; i++) {
311 		if (cmx_test_BSR(sc, flags, test))
312 			return 0;
313 	}
314 
315 	for (int i = 0; i * WAIT_TICKS < sc->timeout; i++) {
316 		if (cmx_test_BSR(sc, flags, test))
317 			return 0;
318 		rv = tsleep(sc, PCATCH, "cmx", WAIT_TICKS);
319 		/*
320 		 * Currently, the only reason for waking up with
321 		 * rv == 0 is when we are detaching, in which
322 		 * case sc->dying is always 1.
323 		 */
324 		if (sc->dying)
325 			return ENXIO;
326 		if (rv != EAGAIN)
327 			return rv;
328 	}
329 
330 	/* timeout */
331 	return EIO;
332 }
333 
334 /*
335  * Set the sync control register to val.  Before and after writing
336  * to the SCR, we wait for the BSR to not signal BULK_OUT_FULL.
337  * Returns zero if successful, or whatever errors cmx_wait_BSR can
338  * return.  ENXIO signals that the device has been detached in the
339  * meantime, and that we should leave the kernel immediately.
340  */
341 static inline int
342 cmx_sync_write_SCR(struct cmx_softc *sc, uint8_t val)
343 {
344 	int rv = 0;
345 
346 	if ((rv = cmx_wait_BSR(sc, BSR_BULK_OUT_FULL, 0)) != 0) {
347 		return rv;
348 	}
349 
350 	cmx_write_SCR(sc, val);
351 
352 	if ((rv = cmx_wait_BSR(sc, BSR_BULK_OUT_FULL, 0)) != 0) {
353 		return rv;
354 	}
355 
356 	return 0;
357 }
358 
359 /*
360  * Returns a suitable timeout value based on the given command byte.
361  * Some commands appear to need longer timeout values than others.
362  */
363 static inline unsigned long
364 cmx_timeout_by_cmd(uint8_t cmd)
365 {
366 	switch (cmd) {
367 	case CMD_PC_TO_RDR_XFRBLOCK:
368 	case CMD_PC_TO_RDR_SECURE:
369 	case CMD_PC_TO_RDR_TEST_SECURE:
370 	case CMD_PC_TO_RDR_OK_SECURE:
371 		return CCID_DRIVER_BULK_DEFAULT_TIMEOUT;
372 
373 	case CMD_PC_TO_RDR_ICCPOWERON:
374 		return CCID_DRIVER_ASYNC_POWERUP_TIMEOUT;
375 
376 	case CMD_PC_TO_RDR_GETSLOTSTATUS:
377 	case CMD_PC_TO_RDR_ICCPOWEROFF:
378 	case CMD_PC_TO_RDR_GETPARAMETERS:
379 	case CMD_PC_TO_RDR_RESETPARAMETERS:
380 	case CMD_PC_TO_RDR_SETPARAMETERS:
381 	case CMD_PC_TO_RDR_ESCAPE:
382 	case CMD_PC_TO_RDR_ICCCLOCK:
383 	default:
384 		return CCID_DRIVER_MINIMUM_TIMEOUT;
385 	}
386 }
387 
388 /*
389  * Periodical callout routine, polling the reader for data
390  * availability.  If the reader signals data ready for reading,
391  * wakes up the processes which are waiting in select()/poll()/kevent().
392  * Otherwise, reschedules itself with a delay of POLL_TICKS.
393  */
394 static void
395 cmx_tick(void *xsc)
396 {
397 	struct cmx_softc *sc = xsc;
398 	uint8_t bsr;
399 
400 	CMX_LOCK(sc);
401 	if (sc->polling && !sc->dying) {
402 		bsr = cmx_read_BSR(sc);
403 		DEBUG_printf(sc->dev, "BSR=%b\n", bsr, BSRBITS);
404 		if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) {
405 			sc->polling = 0;
406 			KNOTE(&sc->kq.ki_note, 0);
407 		} else {
408 			callout_reset(&sc->ch, POLL_TICKS, cmx_tick, sc);
409 		}
410 	}
411 	CMX_UNLOCK(sc);
412 }
413 
414 /*
415  * Open the character device.  Only a single process may open the
416  * device at a time.
417  */
418 static int
419 cmx_open(struct dev_open_args *ap)
420 {
421 	cdev_t dev = ap->a_head.a_dev;
422 	struct cmx_softc *sc;
423 
424 	sc = devclass_get_softc(cmx_devclass, minor(dev));
425 	if (sc == NULL || sc->dying)
426 		return ENXIO;
427 
428 	CMX_LOCK(sc);
429 	if (sc->open) {
430 		CMX_UNLOCK(sc);
431 		return EBUSY;
432 	}
433 	sc->open = 1;
434 	CMX_UNLOCK(sc);
435 
436 	DEBUG_printf(sc->dev, "open (flags=%b thread=%p)\n",
437 			ap->a_oflags, MODEBITS, curthread);
438 	return 0;
439 }
440 
441 /*
442  * Close the character device.
443  */
444 static int
445 cmx_close(struct dev_close_args *ap)
446 {
447 	cdev_t dev = ap->a_head.a_dev;
448 	struct cmx_softc *sc;
449 
450 	sc = devclass_get_softc(cmx_devclass, minor(dev));
451 	if (sc == NULL || sc->dying)
452 		return ENXIO;
453 
454 	CMX_LOCK(sc);
455 	if (!sc->open) {
456 		CMX_UNLOCK(sc);
457 		return EINVAL;
458 	}
459 	if (sc->polling) {
460 		DEBUG_printf(sc->dev, "disabling polling\n");
461 		callout_stop(&sc->ch);
462 		sc->polling = 0;
463 		CMX_UNLOCK(sc);
464 		KNOTE(&sc->kq.ki_note, 0);
465 		CMX_LOCK(sc);
466 	}
467 	sc->open = 0;
468 	CMX_UNLOCK(sc);
469 
470 	DEBUG_printf(sc->dev, "close (flags=%b thread=%p)\n",
471 			ap->a_fflag, MODEBITS, curthread);
472 	return 0;
473 }
474 
475 /*
476  * Read from the character device.
477  * Returns zero if successful, ENXIO if dying, EINVAL if an attempt
478  * was made to read less than CMX_MIN_RDLEN bytes or less than the
479  * device has available, or any of the errors that cmx_sync_write_SCR
480  * can return.  Partial reads are not supported.
481  */
482 static int
483 cmx_read(struct dev_read_args *ap)
484 {
485 	cdev_t dev = ap->a_head.a_dev;
486 	struct cmx_softc *sc;
487 	struct uio *uio = ap->a_uio;
488 	unsigned long bytes_left;
489 	uint8_t uc;
490 	int rv, amnt, offset;
491 
492 	sc = devclass_get_softc(cmx_devclass, minor(dev));
493 	if (sc == NULL || sc->dying)
494 		return ENXIO;
495 
496 	DEBUG_printf(sc->dev, "called (len=%d flag=%b)\n",
497 		uio->uio_resid, ap->a_ioflag, MODEBITS);
498 
499 	CMX_LOCK(sc);
500 	if (sc->polling) {
501 		DEBUG_printf(sc->dev, "disabling polling\n");
502 		callout_stop(&sc->ch);
503 		sc->polling = 0;
504 		CMX_UNLOCK(sc);
505 		KNOTE(&sc->kq.ki_note, 0);
506 	} else {
507 		CMX_UNLOCK(sc);
508 	}
509 
510 	if (uio->uio_resid == 0) {
511 		return 0;
512 	}
513 
514 	if (uio->uio_resid < CMX_MIN_RDLEN) {
515 		return EINVAL;
516 	}
517 
518 	if (ap->a_ioflag & O_NONBLOCK) {
519 		if (cmx_test_BSR(sc, BSR_BULK_IN_FULL, 0)) {
520 			return EAGAIN;
521 		}
522 	}
523 
524 	for (int i = 0; i < 5; i++) {
525 		if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1)) != 0) {
526 			return rv;
527 		}
528 		sc->buf[i] = cmx_read_DTR(sc);
529 		DEBUG_printf(sc->dev, "buf[%02x]=%02x\n", i, sc->buf[i]);
530 	}
531 
532 	bytes_left = CMX_MIN_RDLEN +
533 	                (0x000000FF&((char)sc->buf[1])) +
534 	                (0x0000FF00&((char)sc->buf[2] << 8)) +
535 	                (0x00FF0000&((char)sc->buf[3] << 16)) +
536 	                (0xFF000000&((char)sc->buf[4] << 24));
537 	DEBUG_printf(sc->dev, "msgsz=%lu\n", bytes_left);
538 
539 	if (uio->uio_resid < bytes_left) {
540 		return EINVAL;
541 	}
542 
543 	offset = 5; /* prefetched header */
544 	while (bytes_left > 0) {
545 		amnt = MIN(bytes_left, sizeof(sc->buf));
546 
547 		for (int i = offset; i < amnt; i++) {
548 			if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1))!=0) {
549 				return rv;
550 			}
551 			sc->buf[i] = cmx_read_DTR(sc);
552 			DEBUG_printf(sc->dev, "buf[%02x]=%02x\n",
553 					i, sc->buf[i]);
554 		}
555 
556 		if ((rv = uiomove(sc->buf, amnt, uio)) != 0) {
557 			DEBUG_printf(sc->dev, "uiomove failed (%d)\n", rv);
558 			return rv;
559 		}
560 
561 		if (offset)
562 			offset = 0;
563 		bytes_left -= amnt;
564 	}
565 
566 	if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1)) != 0) {
567 		return rv;
568 	}
569 
570 	if ((rv = cmx_sync_write_SCR(sc, SCR_READER_TO_HOST_DONE)) != 0) {
571 		return rv;
572 	}
573 
574 	uc = cmx_read_DTR(sc);
575 	DEBUG_printf(sc->dev, "success (DTR=%02x)\n", uc);
576 	return 0;
577 }
578 
579 /*
580  * Write to the character device.
581  * Returns zero if successful, NXIO if dying, EINVAL if less data
582  * written than CMX_MIN_WRLEN, or any of the errors that cmx_sync_SCR
583  * can return.
584  */
585 static int
586 cmx_write(struct dev_write_args *ap)
587 {
588 	cdev_t dev = ap->a_head.a_dev;
589 	struct cmx_softc *sc;
590 	struct uio *uio = ap->a_uio;
591 	int rv, amnt;
592 
593 	sc = devclass_get_softc(cmx_devclass, minor(dev));
594 	if (sc == NULL || sc->dying)
595 		return ENXIO;
596 
597 	DEBUG_printf(sc->dev, "called (len=%d flag=%b)\n",
598 			uio->uio_resid, ap->a_ioflag, MODEBITS);
599 
600 	if (uio->uio_resid == 0) {
601 		return 0;
602 	}
603 
604 	if (uio->uio_resid < CMX_MIN_WRLEN) {
605 		return EINVAL;
606 	}
607 
608 	if ((rv = cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_START)) != 0) {
609 		return rv;
610 	}
611 
612 	sc->timeout = 0;
613 	while (uio->uio_resid > 0) {
614 		amnt = MIN(uio->uio_resid, sizeof(sc->buf));
615 
616 		if ((rv = uiomove(sc->buf, amnt, uio)) != 0) {
617 			DEBUG_printf(sc->dev, "uiomove failed (%d)\n", rv);
618 			/* wildly guessed attempt to notify device */
619 			sc->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
620 			cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_DONE);
621 			return rv;
622 		}
623 
624 		if (sc->timeout == 0) {
625 			sc->timeout = cmx_timeout_by_cmd(sc->buf[0]);
626 			DEBUG_printf(sc->dev, "cmd=%02x timeout=%lu\n",
627 					sc->buf[0], sc->timeout);
628 		}
629 
630 		for (int i = 0; i < amnt; i++) {
631 			if ((rv = cmx_wait_BSR(sc, BSR_BULK_OUT_FULL, 0))!=0) {
632 				return rv;
633 			}
634 			cmx_write_DTR(sc, sc->buf[i]);
635 			DEBUG_printf(sc->dev, "buf[%02x]=%02x\n",
636 					i, sc->buf[i]);
637 		}
638 	}
639 
640 	if ((rv = cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_DONE)) != 0) {
641 		return rv;
642 	}
643 
644 	DEBUG_printf(sc->dev, "success\n");
645 	return 0;
646 }
647 
648 static struct filterops cmx_read_filterops =
649 	{ FILTEROP_ISFD, NULL, cmx_filter_detach, cmx_filter_read };
650 static struct filterops cmx_write_filterops =
651 	{ FILTEROP_ISFD, NULL, cmx_filter_detach, cmx_filter_write };
652 
653 /*
654  * Kevent handler.  Writing is always possible, reading is only possible
655  * if BSR_BULK_IN_FULL is set.  Will start the cmx_tick callout and
656  * set sc->polling.
657  */
658 static int
659 cmx_kqfilter(struct dev_kqfilter_args *ap)
660 {
661 	cdev_t dev = ap->a_head.a_dev;
662 	struct knote *kn = ap->a_kn;
663 	struct cmx_softc *sc;
664 	struct klist *klist;
665 
666 	ap->a_result = 0;
667 
668 	sc = devclass_get_softc(cmx_devclass, minor(dev));
669 
670 	switch (kn->kn_filter) {
671 	case EVFILT_READ:
672 		kn->kn_fop = &cmx_read_filterops;
673 		kn->kn_hook = (caddr_t)sc;
674 		break;
675 	case EVFILT_WRITE:
676 		kn->kn_fop = &cmx_write_filterops;
677 		kn->kn_hook = (caddr_t)sc;
678 		break;
679 	default:
680 		ap->a_result = EOPNOTSUPP;
681 		return (0);
682 	}
683 
684 	klist = &sc->kq.ki_note;
685 	knote_insert(klist, kn);
686 
687 	return (0);
688 }
689 
690 static void
691 cmx_filter_detach(struct knote *kn)
692 {
693 	struct cmx_softc *sc = (struct cmx_softc *)kn->kn_hook;
694 	struct klist *klist = &sc->kq.ki_note;
695 
696 	knote_remove(klist, kn);
697 }
698 
699 static int
700 cmx_filter_read(struct knote *kn, long hint)
701 {
702 	struct cmx_softc *sc = (struct cmx_softc *)kn->kn_hook;
703 	int ready = 0;
704         uint8_t bsr = 0;
705 
706         if (sc == NULL || sc->dying) {
707 		kn->kn_flags |= EV_EOF;
708                 return (1);
709 	}
710 
711         bsr = cmx_read_BSR(sc);
712 	if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) {
713 		ready = 1;
714 	} else {
715 		CMX_LOCK(sc);
716 		if (!sc->polling) {
717 			sc->polling = 1;
718 			callout_reset(&sc->ch, POLL_TICKS,
719 				      cmx_tick, sc);
720 		}
721 		CMX_UNLOCK(sc);
722 	}
723 
724 	return (ready);
725 }
726 
727 static int
728 cmx_filter_write(struct knote *kn, long hint)
729 {
730 	return (1);
731 }
732 
733 #ifdef CMX_INTR
734 /*
735  * Interrupt handler.  Currently has no function except to
736  * print register status (if debugging is also enabled).
737  */
738 static void
739 cmx_intr(void *arg)
740 {
741 	struct cmx_softc *sc = (struct cmx_softc *)arg;
742 
743 	if (sc == NULL || sc->dying)
744 		return;
745 
746 	DEBUG_printf(sc->dev, "received interrupt (SCR=%b BSR=%b)\n",
747 			cmx_read_SCR(sc), SCRBITS,
748 			cmx_read_BSR(sc), BSRBITS);
749 
750 	return;
751 }
752 #endif
753 
754