]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/cmx/cmx.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / 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
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
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/poll.h>
48 #include <sys/conf.h>
49 #include <sys/fcntl.h>
50 #include <sys/uio.h>
51 #include <sys/selinfo.h>
52
53 #include <sys/module.h>
54 #include <sys/bus.h>
55
56 #include <machine/bus.h>
57 #include <machine/resource.h>
58 #include <sys/rman.h>
59
60 #include <dev/cmx/cmxvar.h>
61 #include <dev/cmx/cmxreg.h>
62
63 #ifdef CMX_DEBUG
64 #define DEBUG_printf(dev, fmt, args...) \
65         device_printf(dev, "%s: " fmt, __FUNCTION__, ##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_poll_t         cmx_poll;
132 #ifdef CMX_INTR
133 static void             cmx_intr(void *arg);
134 #endif
135
136 static struct cdevsw cmx_cdevsw = {
137         .d_version =    D_VERSION,
138         .d_open =       cmx_open,
139         .d_close =      cmx_close,
140         .d_read =       cmx_read,
141         .d_write =      cmx_write,
142         .d_poll =       cmx_poll,
143         .d_name =       "cmx",
144 };
145
146 /*
147  * Initialize the softc structure.  Must be called from
148  * the bus specific device allocation routine.
149  */
150 void
151 cmx_init_softc(device_t dev)
152 {
153         struct cmx_softc *sc = device_get_softc(dev);
154         sc->dev = dev;
155         sc->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
156 }
157
158 /*
159  * Allocate driver resources.  Must be called from the
160  * bus specific device allocation routine.  Caller must
161  * ensure to call cmx_release_resources to free the
162  * resources when detaching.
163  * Return zero if successful, and ENOMEM if the resources
164  * could not be allocated.
165  */
166 int
167 cmx_alloc_resources(device_t dev)
168 {
169         struct cmx_softc *sc = device_get_softc(dev);
170 #ifdef CMX_INTR
171         int rv;
172 #endif
173
174         sc->ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
175                         &sc->ioport_rid, RF_ACTIVE);
176         if (!sc->ioport) {
177                 device_printf(dev, "failed to allocate io port\n");
178                 return ENOMEM;
179         }
180         sc->bst = rman_get_bustag(sc->ioport);
181         sc->bsh = rman_get_bushandle(sc->ioport);
182
183 #ifdef CMX_INTR
184         sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
185                         &sc->irq_rid, RF_ACTIVE);
186         if (!sc->irq) {
187                 device_printf(dev, "failed to allocate irq\n");
188                 return ENOMEM;
189         }
190         if ((rv = bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY,
191                         cmx_intr, sc, &sc->ih)) != 0) {
192                 device_printf(dev, "failed to set up irq\n");
193                 return ENOMEM;
194         }
195 #endif
196
197         mtx_init(&sc->mtx, device_get_nameunit(dev),
198                         "cmx softc lock",
199                         MTX_DEF | MTX_RECURSE);
200         callout_init_mtx(&sc->ch, &sc->mtx, 0);
201
202         return 0;
203 }
204
205 /*
206  * Release the resources allocated by cmx_allocate_resources.
207  */
208 void
209 cmx_release_resources(device_t dev)
210 {
211         struct cmx_softc *sc = device_get_softc(dev);
212
213         mtx_destroy(&sc->mtx);
214
215 #ifdef CMX_INTR
216         if (sc->ih) {
217                 bus_teardown_intr(dev, sc->irq, sc->ih);
218                 sc->ih = NULL;
219         }
220         if (sc->irq) {
221                 bus_release_resource(dev, SYS_RES_IRQ,
222                                 sc->irq_rid, sc->irq);
223                 sc->irq = NULL;
224         }
225 #endif
226
227         if (sc->ioport) {
228                 bus_deactivate_resource(dev, SYS_RES_IOPORT,
229                                 sc->ioport_rid, sc->ioport);
230                 bus_release_resource(dev, SYS_RES_IOPORT,
231                                 sc->ioport_rid, sc->ioport);
232                 sc->ioport = NULL;
233         }
234         return;
235 }
236
237 /*
238  * Bus independant device attachment routine.  Creates the
239  * character device node.
240  */
241 int
242 cmx_attach(device_t dev)
243 {
244         struct cmx_softc *sc = device_get_softc(dev);
245
246         if (!sc || sc->dying)
247                 return ENXIO;
248
249         sc->cdev = make_dev(&cmx_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
250                             "cmx%d", device_get_unit(dev));
251         if (!sc->cdev) {
252                 device_printf(dev, "failed to create character device\n");
253                 return ENOMEM;
254         }
255         sc->cdev->si_drv1 = sc;
256
257         return 0;
258 }
259
260 /*
261  * Bus independant device detachment routine.  Makes sure all
262  * allocated resources are freed, callouts disabled and waiting
263  * processes unblocked.
264  */
265 int
266 cmx_detach(device_t dev)
267 {
268         struct cmx_softc *sc = device_get_softc(dev);
269
270         DEBUG_printf(dev, "called\n");
271
272         sc->dying = 1;
273
274         CMX_LOCK(sc);
275         if (sc->polling) {
276                 DEBUG_printf(sc->dev, "disabling polling\n");
277                 callout_stop(&sc->ch);
278                 sc->polling = 0;
279                 CMX_UNLOCK(sc);
280                 callout_drain(&sc->ch);
281                 selwakeuppri(&sc->sel, PZERO);
282         } else {
283                 CMX_UNLOCK(sc);
284         }
285
286         wakeup(sc);
287         destroy_dev(sc->cdev);
288
289         DEBUG_printf(dev, "releasing resources\n");
290         cmx_release_resources(dev);
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, PWAIT|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().
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                         selwakeuppri(&sc->sel, PZERO);
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 cdev *cdev, int flags, int fmt, struct thread *td)
418 {
419         struct cmx_softc *sc = cdev->si_drv1;
420
421         if (sc == NULL || sc->dying)
422                 return ENXIO;
423
424         CMX_LOCK(sc);
425         if (sc->open) {
426                 CMX_UNLOCK(sc);
427                 return EBUSY;
428         }
429         sc->open = 1;
430         CMX_UNLOCK(sc);
431
432         DEBUG_printf(sc->dev, "open (flags=%b thread=%p)\n",
433                         flags, MODEBITS, td);
434         return 0;
435 }
436
437 /*
438  * Close the character device.
439  */
440 static int
441 cmx_close(struct cdev *cdev, int flags, int fmt, struct thread *td)
442 {
443         struct cmx_softc *sc = cdev->si_drv1;
444
445         if (sc == NULL || sc->dying)
446                 return ENXIO;
447
448         CMX_LOCK(sc);
449         if (!sc->open) {
450                 CMX_UNLOCK(sc);
451                 return EINVAL;
452         }
453         if (sc->polling) {
454                 DEBUG_printf(sc->dev, "disabling polling\n");
455                 callout_stop(&sc->ch);
456                 sc->polling = 0;
457                 CMX_UNLOCK(sc);
458                 callout_drain(&sc->ch);
459                 selwakeuppri(&sc->sel, PZERO);
460                 CMX_LOCK(sc);
461         }
462         sc->open = 0;
463         CMX_UNLOCK(sc);
464
465         DEBUG_printf(sc->dev, "close (flags=%b thread=%p)\n",
466                         flags, MODEBITS, td);
467         return 0;
468 }
469
470 /*
471  * Read from the character device.
472  * Returns zero if successful, ENXIO if dying, EINVAL if an attempt
473  * was made to read less than CMX_MIN_RDLEN bytes or less than the
474  * device has available, or any of the errors that cmx_sync_write_SCR
475  * can return.  Partial reads are not supported.
476  */
477 static int
478 cmx_read(struct cdev *cdev, struct uio *uio, int flag)
479 {
480         struct cmx_softc *sc = cdev->si_drv1;
481         unsigned long bytes_left;
482         uint8_t uc;
483         int rv, amnt, offset;
484
485         if (sc == NULL || sc->dying)
486                 return ENXIO;
487
488         DEBUG_printf(sc->dev, "called (len=%d flag=%b)\n",
489                 uio->uio_resid, flag, MODEBITS);
490
491         CMX_LOCK(sc);
492         if (sc->polling) {
493                 DEBUG_printf(sc->dev, "disabling polling\n");
494                 callout_stop(&sc->ch);
495                 sc->polling = 0;
496                 CMX_UNLOCK(sc);
497                 callout_drain(&sc->ch);
498                 selwakeuppri(&sc->sel, PZERO);
499         } else {
500                 CMX_UNLOCK(sc);
501         }
502
503         if (uio->uio_resid == 0) {
504                 return 0;
505         }
506
507         if (uio->uio_resid < CMX_MIN_RDLEN) {
508                 return EINVAL;
509         }
510
511         if (flag & O_NONBLOCK) {
512                 if (cmx_test_BSR(sc, BSR_BULK_IN_FULL, 0)) {
513                         return EAGAIN;
514                 }
515         }
516
517         for (int i = 0; i < 5; i++) {
518                 if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1)) != 0) {
519                         return rv;
520                 }
521                 sc->buf[i] = cmx_read_DTR(sc);
522                 DEBUG_printf(sc->dev, "buf[%02x]=%02x\n", i, sc->buf[i]);
523         }
524
525         bytes_left = CMX_MIN_RDLEN +
526                         (0x000000FF&((char)sc->buf[1])) +
527                         (0x0000FF00&((char)sc->buf[2] << 8)) +
528                         (0x00FF0000&((char)sc->buf[3] << 16)) +
529                         (0xFF000000&((char)sc->buf[4] << 24));
530         DEBUG_printf(sc->dev, "msgsz=%lu\n", bytes_left);
531
532         if (uio->uio_resid < bytes_left) {
533                 return EINVAL;
534         }
535
536         offset = 5; /* prefetched header */
537         while (bytes_left > 0) {
538                 amnt = MIN(bytes_left, sizeof(sc->buf));
539
540                 for (int i = offset; i < amnt; i++) {
541                         if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1))!=0) {
542                                 return rv;
543                         }
544                         sc->buf[i] = cmx_read_DTR(sc);
545                         DEBUG_printf(sc->dev, "buf[%02x]=%02x\n",
546                                         i, sc->buf[i]);
547                 }
548
549                 if ((rv = uiomove(sc->buf, amnt, uio)) != 0) {
550                         DEBUG_printf(sc->dev, "uiomove failed (%d)\n", rv);
551                         return rv;
552                 }
553
554                 if (offset)
555                         offset = 0;
556                 bytes_left -= amnt;
557         }
558
559         if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1)) != 0) {
560                 return rv;
561         }
562
563         if ((rv = cmx_sync_write_SCR(sc, SCR_READER_TO_HOST_DONE)) != 0) {
564                 return rv;
565         }
566
567         uc = cmx_read_DTR(sc);
568         DEBUG_printf(sc->dev, "success (DTR=%02x)\n", uc);
569         return 0;
570 }
571
572 /*
573  * Write to the character device.
574  * Returns zero if successful, NXIO if dying, EINVAL if less data
575  * written than CMX_MIN_WRLEN, or any of the errors that cmx_sync_SCR
576  * can return.
577  */
578 static int
579 cmx_write(struct cdev *cdev, struct uio *uio, int flag)
580 {
581         struct cmx_softc *sc = cdev->si_drv1;
582         int rv, amnt;
583
584         if (sc == NULL || sc->dying)
585                 return ENXIO;
586
587         DEBUG_printf(sc->dev, "called (len=%d flag=%b)\n",
588                         uio->uio_resid, flag, MODEBITS);
589
590         if (uio->uio_resid == 0) {
591                 return 0;
592         }
593
594         if (uio->uio_resid < CMX_MIN_WRLEN) {
595                 return EINVAL;
596         }
597
598         if ((rv = cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_START)) != 0) {
599                 return rv;
600         }
601
602         sc->timeout = 0;
603         while (uio->uio_resid > 0) {
604                 amnt = MIN(uio->uio_resid, sizeof(sc->buf));
605
606                 if ((rv = uiomove(sc->buf, amnt, uio)) != 0) {
607                         DEBUG_printf(sc->dev, "uiomove failed (%d)\n", rv);
608                         /* wildly guessed attempt to notify device */
609                         sc->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
610                         cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_DONE);
611                         return rv;
612                 }
613
614                 if (sc->timeout == 0) {
615                         sc->timeout = cmx_timeout_by_cmd(sc->buf[0]);
616                         DEBUG_printf(sc->dev, "cmd=%02x timeout=%lu\n",
617                                         sc->buf[0], sc->timeout);
618                 }
619
620                 for (int i = 0; i < amnt; i++) {
621                         if ((rv = cmx_wait_BSR(sc, BSR_BULK_OUT_FULL, 0))!=0) {
622                                 return rv;
623                         }
624                         cmx_write_DTR(sc, sc->buf[i]);
625                         DEBUG_printf(sc->dev, "buf[%02x]=%02x\n",
626                                         i, sc->buf[i]);
627                 }
628         }
629
630         if ((rv = cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_DONE)) != 0) {
631                 return rv;
632         }
633
634         DEBUG_printf(sc->dev, "success\n");
635         return 0;
636 }
637
638 /*
639  * Poll handler.  Writing is always possible, reading is only possible
640  * if BSR_BULK_IN_FULL is set.  Will start the cmx_tick callout and
641  * set sc->polling.
642  */
643 static int
644 cmx_poll(struct cdev *cdev, int events, struct thread *td)
645 {
646         struct cmx_softc *sc = cdev->si_drv1;
647         int revents = 0;
648         uint8_t bsr = 0;
649
650         if (sc == NULL || sc->dying)
651                 return ENXIO;
652
653         bsr = cmx_read_BSR(sc);
654         DEBUG_printf(sc->dev, "called (events=%b BSR=%b)\n",
655                         events, POLLBITS, bsr, BSRBITS);
656
657         revents = events & (POLLOUT | POLLWRNORM);
658         if (events & (POLLIN | POLLRDNORM)) {
659                 if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) {
660                         revents |= events & (POLLIN | POLLRDNORM);
661                 } else {
662                         selrecord(td, &sc->sel);
663                         CMX_LOCK(sc);
664                         if (!sc->polling) {
665                                 DEBUG_printf(sc->dev, "enabling polling\n");
666                                 sc->polling = 1;
667                                 callout_reset(&sc->ch, POLL_TICKS,
668                                                 cmx_tick, sc);
669                         } else {
670                                 DEBUG_printf(sc->dev, "already polling\n");
671                         }
672                         CMX_UNLOCK(sc);
673                 }
674         }
675
676         DEBUG_printf(sc->dev, "success (revents=%b)\n", revents, POLLBITS);
677
678         return revents;
679 }
680
681 #ifdef CMX_INTR
682 /*
683  * Interrupt handler.  Currently has no function except to
684  * print register status (if debugging is also enabled).
685  */
686 static void
687 cmx_intr(void *arg)
688 {
689         struct cmx_softc *sc = (struct cmx_softc *)arg;
690
691         if (sc == NULL || sc->dying)
692                 return;
693
694         DEBUG_printf(sc->dev, "received interrupt (SCR=%b BSR=%b)\n",
695                         cmx_read_SCR(sc), SCRBITS,
696                         cmx_read_BSR(sc), BSRBITS);
697
698         return;
699 }
700 #endif
701