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