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