kernel - Tear out device polling
[dragonfly.git] / sys / dev / misc / cmx / cmx.c
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         } 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                         selwakeup(&sc->sel);
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                 selwakeup(&sc->sel);
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                 selwakeup(&sc->sel);
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