xref: /dflybsd-src/sys/dev/misc/cmx/cmx.c (revision 468b4ddebc1eadd839e8e52d766c331a99af364c)
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 		KNOTE(&sc->sel.si_note, 0);
285 	} else {
286 		CMX_UNLOCK(sc);
287 	}
288 
289 	wakeup(sc);
290 	DEBUG_printf(dev, "releasing resources\n");
291 	cmx_release_resources(dev);
292 	dev_ops_remove_minor(&cmx_ops, device_get_unit(dev));
293 
294 	return 0;
295 }
296 
297 /*
298  * Wait for buffer status register events.  If test is non-zero,
299  * wait until flags are set, otherwise wait until flags are unset.
300  * Will spin SPIN_COUNT times, then sleep until timeout is reached.
301  * Returns zero if event happened, EIO if the timeout was reached,
302  * and ENXIO if the device was detached in the meantime.  When that
303  * happens, the caller must quit immediately, since a detach is
304  * in progress.
305  */
306 static inline int
307 cmx_wait_BSR(struct cmx_softc *sc, uint8_t flags, int test)
308 {
309 	int rv;
310 
311 	for (int i = 0; i < SPIN_COUNT; i++) {
312 		if (cmx_test_BSR(sc, flags, test))
313 			return 0;
314 	}
315 
316 	for (int i = 0; i * WAIT_TICKS < sc->timeout; i++) {
317 		if (cmx_test_BSR(sc, flags, test))
318 			return 0;
319 		rv = tsleep(sc, PCATCH, "cmx", WAIT_TICKS);
320 		/*
321 		 * Currently, the only reason for waking up with
322 		 * rv == 0 is when we are detaching, in which
323 		 * case sc->dying is always 1.
324 		 */
325 		if (sc->dying)
326 			return ENXIO;
327 		if (rv != EAGAIN)
328 			return rv;
329 	}
330 
331 	/* timeout */
332 	return EIO;
333 }
334 
335 /*
336  * Set the sync control register to val.  Before and after writing
337  * to the SCR, we wait for the BSR to not signal BULK_OUT_FULL.
338  * Returns zero if successful, or whatever errors cmx_wait_BSR can
339  * return.  ENXIO signals that the device has been detached in the
340  * meantime, and that we should leave the kernel immediately.
341  */
342 static inline int
343 cmx_sync_write_SCR(struct cmx_softc *sc, uint8_t val)
344 {
345 	int rv = 0;
346 
347 	if ((rv = cmx_wait_BSR(sc, BSR_BULK_OUT_FULL, 0)) != 0) {
348 		return rv;
349 	}
350 
351 	cmx_write_SCR(sc, val);
352 
353 	if ((rv = cmx_wait_BSR(sc, BSR_BULK_OUT_FULL, 0)) != 0) {
354 		return rv;
355 	}
356 
357 	return 0;
358 }
359 
360 /*
361  * Returns a suitable timeout value based on the given command byte.
362  * Some commands appear to need longer timeout values than others.
363  */
364 static inline unsigned long
365 cmx_timeout_by_cmd(uint8_t cmd)
366 {
367 	switch (cmd) {
368 	case CMD_PC_TO_RDR_XFRBLOCK:
369 	case CMD_PC_TO_RDR_SECURE:
370 	case CMD_PC_TO_RDR_TEST_SECURE:
371 	case CMD_PC_TO_RDR_OK_SECURE:
372 		return CCID_DRIVER_BULK_DEFAULT_TIMEOUT;
373 
374 	case CMD_PC_TO_RDR_ICCPOWERON:
375 		return CCID_DRIVER_ASYNC_POWERUP_TIMEOUT;
376 
377 	case CMD_PC_TO_RDR_GETSLOTSTATUS:
378 	case CMD_PC_TO_RDR_ICCPOWEROFF:
379 	case CMD_PC_TO_RDR_GETPARAMETERS:
380 	case CMD_PC_TO_RDR_RESETPARAMETERS:
381 	case CMD_PC_TO_RDR_SETPARAMETERS:
382 	case CMD_PC_TO_RDR_ESCAPE:
383 	case CMD_PC_TO_RDR_ICCCLOCK:
384 	default:
385 		return CCID_DRIVER_MINIMUM_TIMEOUT;
386 	}
387 }
388 
389 /*
390  * Periodical callout routine, polling the reader for data
391  * availability.  If the reader signals data ready for reading,
392  * wakes up the processes which are waiting in select()/poll().
393  * Otherwise, reschedules itself with a delay of POLL_TICKS.
394  */
395 static void
396 cmx_tick(void *xsc)
397 {
398 	struct cmx_softc *sc = xsc;
399 	uint8_t bsr;
400 
401 	CMX_LOCK(sc);
402 	if (sc->polling && !sc->dying) {
403 		bsr = cmx_read_BSR(sc);
404 		DEBUG_printf(sc->dev, "BSR=%b\n", bsr, BSRBITS);
405 		if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) {
406 			sc->polling = 0;
407 			KNOTE(&sc->sel.si_note, 0);
408 		} else {
409 			callout_reset(&sc->ch, POLL_TICKS, cmx_tick, sc);
410 		}
411 	}
412 	CMX_UNLOCK(sc);
413 }
414 
415 /*
416  * Open the character device.  Only a single process may open the
417  * device at a time.
418  */
419 static int
420 cmx_open(struct dev_open_args *ap)
421 {
422 	cdev_t dev = ap->a_head.a_dev;
423 	struct cmx_softc *sc;
424 
425 	sc = devclass_get_softc(cmx_devclass, minor(dev));
426 	if (sc == NULL || sc->dying)
427 		return ENXIO;
428 
429 	CMX_LOCK(sc);
430 	if (sc->open) {
431 		CMX_UNLOCK(sc);
432 		return EBUSY;
433 	}
434 	sc->open = 1;
435 	CMX_UNLOCK(sc);
436 
437 	DEBUG_printf(sc->dev, "open (flags=%b thread=%p)\n",
438 			ap->a_oflags, MODEBITS, curthread);
439 	return 0;
440 }
441 
442 /*
443  * Close the character device.
444  */
445 static int
446 cmx_close(struct dev_close_args *ap)
447 {
448 	cdev_t dev = ap->a_head.a_dev;
449 	struct cmx_softc *sc;
450 
451 	sc = devclass_get_softc(cmx_devclass, minor(dev));
452 	if (sc == NULL || sc->dying)
453 		return ENXIO;
454 
455 	CMX_LOCK(sc);
456 	if (!sc->open) {
457 		CMX_UNLOCK(sc);
458 		return EINVAL;
459 	}
460 	if (sc->polling) {
461 		DEBUG_printf(sc->dev, "disabling polling\n");
462 		callout_stop(&sc->ch);
463 		sc->polling = 0;
464 		CMX_UNLOCK(sc);
465 		KNOTE(&sc->sel.si_note, 0);
466 		CMX_LOCK(sc);
467 	}
468 	sc->open = 0;
469 	CMX_UNLOCK(sc);
470 
471 	DEBUG_printf(sc->dev, "close (flags=%b thread=%p)\n",
472 			ap->a_fflag, MODEBITS, curthread);
473 	return 0;
474 }
475 
476 /*
477  * Read from the character device.
478  * Returns zero if successful, ENXIO if dying, EINVAL if an attempt
479  * was made to read less than CMX_MIN_RDLEN bytes or less than the
480  * device has available, or any of the errors that cmx_sync_write_SCR
481  * can return.  Partial reads are not supported.
482  */
483 static int
484 cmx_read(struct dev_read_args *ap)
485 {
486 	cdev_t dev = ap->a_head.a_dev;
487 	struct cmx_softc *sc;
488 	struct uio *uio = ap->a_uio;
489 	unsigned long bytes_left;
490 	uint8_t uc;
491 	int rv, amnt, offset;
492 
493 	sc = devclass_get_softc(cmx_devclass, minor(dev));
494 	if (sc == NULL || sc->dying)
495 		return ENXIO;
496 
497 	DEBUG_printf(sc->dev, "called (len=%d flag=%b)\n",
498 		uio->uio_resid, ap->a_ioflag, MODEBITS);
499 
500 	CMX_LOCK(sc);
501 	if (sc->polling) {
502 		DEBUG_printf(sc->dev, "disabling polling\n");
503 		callout_stop(&sc->ch);
504 		sc->polling = 0;
505 		CMX_UNLOCK(sc);
506 		KNOTE(&sc->sel.si_note, 0);
507 	} else {
508 		CMX_UNLOCK(sc);
509 	}
510 
511 	if (uio->uio_resid == 0) {
512 		return 0;
513 	}
514 
515 	if (uio->uio_resid < CMX_MIN_RDLEN) {
516 		return EINVAL;
517 	}
518 
519 	if (ap->a_ioflag & O_NONBLOCK) {
520 		if (cmx_test_BSR(sc, BSR_BULK_IN_FULL, 0)) {
521 			return EAGAIN;
522 		}
523 	}
524 
525 	for (int i = 0; i < 5; i++) {
526 		if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1)) != 0) {
527 			return rv;
528 		}
529 		sc->buf[i] = cmx_read_DTR(sc);
530 		DEBUG_printf(sc->dev, "buf[%02x]=%02x\n", i, sc->buf[i]);
531 	}
532 
533 	bytes_left = CMX_MIN_RDLEN +
534 	                (0x000000FF&((char)sc->buf[1])) +
535 	                (0x0000FF00&((char)sc->buf[2] << 8)) +
536 	                (0x00FF0000&((char)sc->buf[3] << 16)) +
537 	                (0xFF000000&((char)sc->buf[4] << 24));
538 	DEBUG_printf(sc->dev, "msgsz=%lu\n", bytes_left);
539 
540 	if (uio->uio_resid < bytes_left) {
541 		return EINVAL;
542 	}
543 
544 	offset = 5; /* prefetched header */
545 	while (bytes_left > 0) {
546 		amnt = MIN(bytes_left, sizeof(sc->buf));
547 
548 		for (int i = offset; i < amnt; i++) {
549 			if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1))!=0) {
550 				return rv;
551 			}
552 			sc->buf[i] = cmx_read_DTR(sc);
553 			DEBUG_printf(sc->dev, "buf[%02x]=%02x\n",
554 					i, sc->buf[i]);
555 		}
556 
557 		if ((rv = uiomove(sc->buf, amnt, uio)) != 0) {
558 			DEBUG_printf(sc->dev, "uiomove failed (%d)\n", rv);
559 			return rv;
560 		}
561 
562 		if (offset)
563 			offset = 0;
564 		bytes_left -= amnt;
565 	}
566 
567 	if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1)) != 0) {
568 		return rv;
569 	}
570 
571 	if ((rv = cmx_sync_write_SCR(sc, SCR_READER_TO_HOST_DONE)) != 0) {
572 		return rv;
573 	}
574 
575 	uc = cmx_read_DTR(sc);
576 	DEBUG_printf(sc->dev, "success (DTR=%02x)\n", uc);
577 	return 0;
578 }
579 
580 /*
581  * Write to the character device.
582  * Returns zero if successful, NXIO if dying, EINVAL if less data
583  * written than CMX_MIN_WRLEN, or any of the errors that cmx_sync_SCR
584  * can return.
585  */
586 static int
587 cmx_write(struct dev_write_args *ap)
588 {
589 	cdev_t dev = ap->a_head.a_dev;
590 	struct cmx_softc *sc;
591 	struct uio *uio = ap->a_uio;
592 	int rv, amnt;
593 
594 	sc = devclass_get_softc(cmx_devclass, minor(dev));
595 	if (sc == NULL || sc->dying)
596 		return ENXIO;
597 
598 	DEBUG_printf(sc->dev, "called (len=%d flag=%b)\n",
599 			uio->uio_resid, ap->a_ioflag, MODEBITS);
600 
601 	if (uio->uio_resid == 0) {
602 		return 0;
603 	}
604 
605 	if (uio->uio_resid < CMX_MIN_WRLEN) {
606 		return EINVAL;
607 	}
608 
609 	if ((rv = cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_START)) != 0) {
610 		return rv;
611 	}
612 
613 	sc->timeout = 0;
614 	while (uio->uio_resid > 0) {
615 		amnt = MIN(uio->uio_resid, sizeof(sc->buf));
616 
617 		if ((rv = uiomove(sc->buf, amnt, uio)) != 0) {
618 			DEBUG_printf(sc->dev, "uiomove failed (%d)\n", rv);
619 			/* wildly guessed attempt to notify device */
620 			sc->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
621 			cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_DONE);
622 			return rv;
623 		}
624 
625 		if (sc->timeout == 0) {
626 			sc->timeout = cmx_timeout_by_cmd(sc->buf[0]);
627 			DEBUG_printf(sc->dev, "cmd=%02x timeout=%lu\n",
628 					sc->buf[0], sc->timeout);
629 		}
630 
631 		for (int i = 0; i < amnt; i++) {
632 			if ((rv = cmx_wait_BSR(sc, BSR_BULK_OUT_FULL, 0))!=0) {
633 				return rv;
634 			}
635 			cmx_write_DTR(sc, sc->buf[i]);
636 			DEBUG_printf(sc->dev, "buf[%02x]=%02x\n",
637 					i, sc->buf[i]);
638 		}
639 	}
640 
641 	if ((rv = cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_DONE)) != 0) {
642 		return rv;
643 	}
644 
645 	DEBUG_printf(sc->dev, "success\n");
646 	return 0;
647 }
648 
649 static struct filterops cmx_read_filterops =
650 	{ 1, NULL, cmx_filter_detach, cmx_filter_read };
651 static struct filterops cmx_write_filterops =
652 	{ 1, NULL, cmx_filter_detach, cmx_filter_write };
653 
654 /*
655  * Kevent handler.  Writing is always possible, reading is only possible
656  * if BSR_BULK_IN_FULL is set.  Will start the cmx_tick callout and
657  * set sc->polling.
658  */
659 static int
660 cmx_kqfilter(struct dev_kqfilter_args *ap)
661 {
662 	cdev_t dev = ap->a_head.a_dev;
663 	struct knote *kn = ap->a_kn;
664 	struct cmx_softc *sc;
665 	struct klist *klist;
666 
667 	ap->a_result = 0;
668 
669 	sc = devclass_get_softc(cmx_devclass, minor(dev));
670 
671 	switch (kn->kn_filter) {
672 	case EVFILT_READ:
673 		kn->kn_fop = &cmx_read_filterops;
674 		kn->kn_hook = (caddr_t)sc;
675 		break;
676 	case EVFILT_WRITE:
677 		kn->kn_fop = &cmx_write_filterops;
678 		kn->kn_hook = (caddr_t)sc;
679 		break;
680 	default:
681 		ap->a_result = EOPNOTSUPP;
682 		return (0);
683 	}
684 
685 	crit_enter();
686 	klist = &sc->sel.si_note;
687 	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
688 	crit_exit();
689 
690 	return (0);
691 }
692 
693 static void
694 cmx_filter_detach(struct knote *kn)
695 {
696 	struct cmx_softc *sc = (struct cmx_softc *)kn->kn_hook;
697 	struct klist *klist;
698 
699 	crit_enter();
700 	klist = &sc->sel.si_note;
701 	SLIST_REMOVE(klist, kn, knote, kn_selnext);
702 	crit_exit();
703 }
704 
705 static int
706 cmx_filter_read(struct knote *kn, long hint)
707 {
708 	struct cmx_softc *sc = (struct cmx_softc *)kn->kn_hook;
709 	int ready = 0;
710         uint8_t bsr = 0;
711 
712         if (sc == NULL || sc->dying) {
713 		kn->kn_flags |= EV_EOF;
714                 return (1);
715 	}
716 
717         bsr = cmx_read_BSR(sc);
718 	if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) {
719 		ready = 1;
720 	} else {
721 		CMX_LOCK(sc);
722 		if (!sc->polling) {
723 			sc->polling = 1;
724 			callout_reset(&sc->ch, POLL_TICKS,
725 				      cmx_tick, sc);
726 		}
727 		CMX_UNLOCK(sc);
728 	}
729 
730 	return (ready);
731 }
732 
733 static int
734 cmx_filter_write(struct knote *kn, long hint)
735 {
736 	return (1);
737 }
738 
739 #ifdef CMX_INTR
740 /*
741  * Interrupt handler.  Currently has no function except to
742  * print register status (if debugging is also enabled).
743  */
744 static void
745 cmx_intr(void *arg)
746 {
747 	struct cmx_softc *sc = (struct cmx_softc *)arg;
748 
749 	if (sc == NULL || sc->dying)
750 		return;
751 
752 	DEBUG_printf(sc->dev, "received interrupt (SCR=%b BSR=%b)\n",
753 			cmx_read_SCR(sc), SCRBITS,
754 			cmx_read_BSR(sc), BSRBITS);
755 
756 	return;
757 }
758 #endif
759 
760