2 * Copyright (c) 2006-2007 Daniel Roethlisberger <daniel@roe.ch>
3 * Copyright (c) 2000-2004 OMNIKEY GmbH (www.omnikey.com)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
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.
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
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 $
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.
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 $
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/sockio.h>
48 #include <sys/event.h>
50 #include <sys/fcntl.h>
52 #include <sys/selinfo.h>
53 #include <sys/types.h>
55 #include <sys/device.h>
56 #include <sys/thread2.h>
58 #include <sys/module.h>
60 #include <sys/resource.h>
67 #define DEBUG_printf(dev, fmt, args...) \
68 device_printf(dev, "%s: " fmt, __FUNCTION__, ##args)
70 #define DEBUG_printf(dev, fmt, args...)
73 #define SPIN_COUNT 1000
74 #define WAIT_TICKS (hz/100)
75 #define POLL_TICKS (hz/10)
78 #define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*hz)
79 #define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*hz)
80 #define CCID_DRIVER_MINIMUM_TIMEOUT (3*hz)
83 static char BSRBITS[] = "\020"
84 "\01BULK_OUT_FULL" /* 0x01 */
85 "\02BULK_IN_FULL" /* 0x02 */
86 "\03(0x04)"; /* 0x04 */
88 static char SCRBITS[] = "\020"
89 "\01POWER_DOWN" /* 0x01 */
90 "\02PULSE_INTERRUPT" /* 0x02 */
91 "\03HOST_TO_READER_DONE" /* 0x04 */
92 "\04READER_TO_HOST_DONE" /* 0x08 */
93 "\05ACK_NOTIFY" /* 0x10 */
94 "\06EN_NOTIFY" /* 0x20 */
96 "\10HOST_TO_READER_START"; /* 0x80 */
98 static char POLLBITS[] = "\020"
99 "\01POLLIN" /* 0x0001 */
100 "\02POLLPRI" /* 0x0002 */
101 "\03POLLOUT" /* 0x0004 */
102 "\04POLLERR" /* 0x0008 */
103 "\05POLLHUP" /* 0x0010 */
104 "\06POLLINVAL" /* 0x0020 */
105 "\07POLLRDNORM" /* 0x0040 */
106 "\10POLLRDBAND" /* 0x0080 */
107 "\11POLLWRBAND"; /* 0x0100 */
108 static char MODEBITS[] = "\020"
109 "\01READ" /* 0x0001 */
110 "\02WRITE" /* 0x0002 */
111 "\03NONBLOCK" /* 0x0004 */
112 "\04APPEND" /* 0x0008 */
113 "\05SHLOCK" /* 0x0010 */
114 "\06EXLOCK" /* 0x0020 */
115 "\07ASYNC" /* 0x0040 */
116 "\10FSYNC" /* 0x0080 */
117 "\11NOFOLLOW" /* 0x0100 */
118 "\12CREAT" /* 0x0200 */
119 "\13TRUNK" /* 0x0400 */
120 "\14EXCL" /* 0x0800 */
121 "\15(0x1000)" /* 0x1000 */
122 "\16(0x2000)" /* 0x2000 */
123 "\17HASLOCK" /* 0x4000 */
124 "\20NOCTTY" /* 0x8000 */
125 "\21DIRECT"; /* 0x00010000 */
126 #endif /* CMX_DEBUG */
128 devclass_t cmx_devclass;
130 static d_open_t cmx_open;
131 static d_close_t cmx_close;
132 static d_read_t cmx_read;
133 static d_write_t cmx_write;
134 static d_poll_t cmx_poll;
135 static d_kqfilter_t cmx_kqfilter;
137 static void cmx_intr(void *arg);
140 static void cmx_filter_detach(struct knote *);
141 static int cmx_filter_read(struct knote *, long);
142 static int cmx_filter_write(struct knote *, long);
144 #define CDEV_MAJOR 185
145 static struct dev_ops cmx_ops = {
146 { "cmx", CDEV_MAJOR, D_KQFILTER },
148 .d_close = cmx_close,
150 .d_write = cmx_write,
152 .d_kqfilter = cmx_kqfilter
156 * Initialize the softc structure. Must be called from
157 * the bus specific device allocation routine.
160 cmx_init_softc(device_t dev)
162 struct cmx_softc *sc = device_get_softc(dev);
164 sc->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
168 * Allocate driver resources. Must be called from the
169 * bus specific device allocation routine. Caller must
170 * ensure to call cmx_release_resources to free the
171 * resources when detaching.
172 * Return zero if successful, and ENOMEM if the resources
173 * could not be allocated.
176 cmx_alloc_resources(device_t dev)
178 struct cmx_softc *sc = device_get_softc(dev);
183 sc->ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
184 &sc->ioport_rid, RF_ACTIVE);
186 device_printf(dev, "failed to allocate io port\n");
189 sc->bst = rman_get_bustag(sc->ioport);
190 sc->bsh = rman_get_bushandle(sc->ioport);
193 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
194 &sc->irq_rid, RF_ACTIVE);
196 device_printf(dev, "failed to allocate irq\n");
199 if ((rv = bus_setup_intr(dev, sc->irq, 0, cmx_intr, sc,
200 &sc->ih, NULL)) != 0) {
201 device_printf(dev, "failed to set up irq\n");
206 lockinit(&sc->mtx, "cmx softc lock", 0, LK_CANRECURSE);
207 callout_init(&sc->ch);
213 * Release the resources allocated by cmx_allocate_resources.
216 cmx_release_resources(device_t dev)
218 struct cmx_softc *sc = device_get_softc(dev);
220 lockuninit(&sc->mtx);
224 bus_teardown_intr(dev, sc->irq, sc->ih);
228 bus_release_resource(dev, SYS_RES_IRQ,
229 sc->irq_rid, sc->irq);
235 bus_deactivate_resource(dev, SYS_RES_IOPORT,
236 sc->ioport_rid, sc->ioport);
237 bus_release_resource(dev, SYS_RES_IOPORT,
238 sc->ioport_rid, sc->ioport);
245 * Bus independant device attachment routine. Creates the
246 * character device node.
249 cmx_attach(device_t dev)
251 struct cmx_softc *sc = device_get_softc(dev);
253 if (!sc || sc->dying)
256 sc->cdev = make_dev(&cmx_ops, 0, UID_ROOT, GID_WHEEL, 0600,
257 "cmx%d", device_get_unit(dev));
259 device_printf(dev, "failed to create character device\n");
262 sc->cdev->si_drv1 = sc;
268 * Bus independant device detachment routine. Makes sure all
269 * allocated resources are freed, callouts disabled and waiting
270 * processes unblocked.
273 cmx_detach(device_t dev)
275 struct cmx_softc *sc = device_get_softc(dev);
277 DEBUG_printf(dev, "called\n");
283 DEBUG_printf(sc->dev, "disabling polling\n");
284 callout_stop(&sc->ch);
293 DEBUG_printf(dev, "releasing resources\n");
294 cmx_release_resources(dev);
295 dev_ops_remove_minor(&cmx_ops, device_get_unit(dev));
301 * Wait for buffer status register events. If test is non-zero,
302 * wait until flags are set, otherwise wait until flags are unset.
303 * Will spin SPIN_COUNT times, then sleep until timeout is reached.
304 * Returns zero if event happened, EIO if the timeout was reached,
305 * and ENXIO if the device was detached in the meantime. When that
306 * happens, the caller must quit immediately, since a detach is
310 cmx_wait_BSR(struct cmx_softc *sc, uint8_t flags, int test)
314 for (int i = 0; i < SPIN_COUNT; i++) {
315 if (cmx_test_BSR(sc, flags, test))
319 for (int i = 0; i * WAIT_TICKS < sc->timeout; i++) {
320 if (cmx_test_BSR(sc, flags, test))
322 rv = tsleep(sc, PCATCH, "cmx", WAIT_TICKS);
324 * Currently, the only reason for waking up with
325 * rv == 0 is when we are detaching, in which
326 * case sc->dying is always 1.
339 * Set the sync control register to val. Before and after writing
340 * to the SCR, we wait for the BSR to not signal BULK_OUT_FULL.
341 * Returns zero if successful, or whatever errors cmx_wait_BSR can
342 * return. ENXIO signals that the device has been detached in the
343 * meantime, and that we should leave the kernel immediately.
346 cmx_sync_write_SCR(struct cmx_softc *sc, uint8_t val)
350 if ((rv = cmx_wait_BSR(sc, BSR_BULK_OUT_FULL, 0)) != 0) {
354 cmx_write_SCR(sc, val);
356 if ((rv = cmx_wait_BSR(sc, BSR_BULK_OUT_FULL, 0)) != 0) {
364 * Returns a suitable timeout value based on the given command byte.
365 * Some commands appear to need longer timeout values than others.
367 static inline unsigned long
368 cmx_timeout_by_cmd(uint8_t cmd)
371 case CMD_PC_TO_RDR_XFRBLOCK:
372 case CMD_PC_TO_RDR_SECURE:
373 case CMD_PC_TO_RDR_TEST_SECURE:
374 case CMD_PC_TO_RDR_OK_SECURE:
375 return CCID_DRIVER_BULK_DEFAULT_TIMEOUT;
377 case CMD_PC_TO_RDR_ICCPOWERON:
378 return CCID_DRIVER_ASYNC_POWERUP_TIMEOUT;
380 case CMD_PC_TO_RDR_GETSLOTSTATUS:
381 case CMD_PC_TO_RDR_ICCPOWEROFF:
382 case CMD_PC_TO_RDR_GETPARAMETERS:
383 case CMD_PC_TO_RDR_RESETPARAMETERS:
384 case CMD_PC_TO_RDR_SETPARAMETERS:
385 case CMD_PC_TO_RDR_ESCAPE:
386 case CMD_PC_TO_RDR_ICCCLOCK:
388 return CCID_DRIVER_MINIMUM_TIMEOUT;
393 * Periodical callout routine, polling the reader for data
394 * availability. If the reader signals data ready for reading,
395 * wakes up the processes which are waiting in select()/poll().
396 * Otherwise, reschedules itself with a delay of POLL_TICKS.
401 struct cmx_softc *sc = xsc;
405 if (sc->polling && !sc->dying) {
406 bsr = cmx_read_BSR(sc);
407 DEBUG_printf(sc->dev, "BSR=%b\n", bsr, BSRBITS);
408 if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) {
412 callout_reset(&sc->ch, POLL_TICKS, cmx_tick, sc);
419 * Open the character device. Only a single process may open the
423 cmx_open(struct dev_open_args *ap)
425 cdev_t dev = ap->a_head.a_dev;
426 struct cmx_softc *sc;
428 sc = devclass_get_softc(cmx_devclass, minor(dev));
429 if (sc == NULL || sc->dying)
440 DEBUG_printf(sc->dev, "open (flags=%b thread=%p)\n",
441 ap->a_oflags, MODEBITS, curthread);
446 * Close the character device.
449 cmx_close(struct dev_close_args *ap)
451 cdev_t dev = ap->a_head.a_dev;
452 struct cmx_softc *sc;
454 sc = devclass_get_softc(cmx_devclass, minor(dev));
455 if (sc == NULL || sc->dying)
464 DEBUG_printf(sc->dev, "disabling polling\n");
465 callout_stop(&sc->ch);
474 DEBUG_printf(sc->dev, "close (flags=%b thread=%p)\n",
475 ap->a_fflag, MODEBITS, curthread);
480 * Read from the character device.
481 * Returns zero if successful, ENXIO if dying, EINVAL if an attempt
482 * was made to read less than CMX_MIN_RDLEN bytes or less than the
483 * device has available, or any of the errors that cmx_sync_write_SCR
484 * can return. Partial reads are not supported.
487 cmx_read(struct dev_read_args *ap)
489 cdev_t dev = ap->a_head.a_dev;
490 struct cmx_softc *sc;
491 struct uio *uio = ap->a_uio;
492 unsigned long bytes_left;
494 int rv, amnt, offset;
496 sc = devclass_get_softc(cmx_devclass, minor(dev));
497 if (sc == NULL || sc->dying)
500 DEBUG_printf(sc->dev, "called (len=%d flag=%b)\n",
501 uio->uio_resid, ap->a_ioflag, MODEBITS);
505 DEBUG_printf(sc->dev, "disabling polling\n");
506 callout_stop(&sc->ch);
514 if (uio->uio_resid == 0) {
518 if (uio->uio_resid < CMX_MIN_RDLEN) {
522 if (ap->a_ioflag & O_NONBLOCK) {
523 if (cmx_test_BSR(sc, BSR_BULK_IN_FULL, 0)) {
528 for (int i = 0; i < 5; i++) {
529 if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1)) != 0) {
532 sc->buf[i] = cmx_read_DTR(sc);
533 DEBUG_printf(sc->dev, "buf[%02x]=%02x\n", i, sc->buf[i]);
536 bytes_left = CMX_MIN_RDLEN +
537 (0x000000FF&((char)sc->buf[1])) +
538 (0x0000FF00&((char)sc->buf[2] << 8)) +
539 (0x00FF0000&((char)sc->buf[3] << 16)) +
540 (0xFF000000&((char)sc->buf[4] << 24));
541 DEBUG_printf(sc->dev, "msgsz=%lu\n", bytes_left);
543 if (uio->uio_resid < bytes_left) {
547 offset = 5; /* prefetched header */
548 while (bytes_left > 0) {
549 amnt = MIN(bytes_left, sizeof(sc->buf));
551 for (int i = offset; i < amnt; i++) {
552 if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1))!=0) {
555 sc->buf[i] = cmx_read_DTR(sc);
556 DEBUG_printf(sc->dev, "buf[%02x]=%02x\n",
560 if ((rv = uiomove(sc->buf, amnt, uio)) != 0) {
561 DEBUG_printf(sc->dev, "uiomove failed (%d)\n", rv);
570 if ((rv = cmx_wait_BSR(sc, BSR_BULK_IN_FULL, 1)) != 0) {
574 if ((rv = cmx_sync_write_SCR(sc, SCR_READER_TO_HOST_DONE)) != 0) {
578 uc = cmx_read_DTR(sc);
579 DEBUG_printf(sc->dev, "success (DTR=%02x)\n", uc);
584 * Write to the character device.
585 * Returns zero if successful, NXIO if dying, EINVAL if less data
586 * written than CMX_MIN_WRLEN, or any of the errors that cmx_sync_SCR
590 cmx_write(struct dev_write_args *ap)
592 cdev_t dev = ap->a_head.a_dev;
593 struct cmx_softc *sc;
594 struct uio *uio = ap->a_uio;
597 sc = devclass_get_softc(cmx_devclass, minor(dev));
598 if (sc == NULL || sc->dying)
601 DEBUG_printf(sc->dev, "called (len=%d flag=%b)\n",
602 uio->uio_resid, ap->a_ioflag, MODEBITS);
604 if (uio->uio_resid == 0) {
608 if (uio->uio_resid < CMX_MIN_WRLEN) {
612 if ((rv = cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_START)) != 0) {
617 while (uio->uio_resid > 0) {
618 amnt = MIN(uio->uio_resid, sizeof(sc->buf));
620 if ((rv = uiomove(sc->buf, amnt, uio)) != 0) {
621 DEBUG_printf(sc->dev, "uiomove failed (%d)\n", rv);
622 /* wildly guessed attempt to notify device */
623 sc->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
624 cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_DONE);
628 if (sc->timeout == 0) {
629 sc->timeout = cmx_timeout_by_cmd(sc->buf[0]);
630 DEBUG_printf(sc->dev, "cmd=%02x timeout=%lu\n",
631 sc->buf[0], sc->timeout);
634 for (int i = 0; i < amnt; i++) {
635 if ((rv = cmx_wait_BSR(sc, BSR_BULK_OUT_FULL, 0))!=0) {
638 cmx_write_DTR(sc, sc->buf[i]);
639 DEBUG_printf(sc->dev, "buf[%02x]=%02x\n",
644 if ((rv = cmx_sync_write_SCR(sc, SCR_HOST_TO_READER_DONE)) != 0) {
648 DEBUG_printf(sc->dev, "success\n");
653 * Poll handler. Writing is always possible, reading is only possible
654 * if BSR_BULK_IN_FULL is set. Will start the cmx_tick callout and
658 cmx_poll(struct dev_poll_args *ap)
660 cdev_t dev = ap->a_head.a_dev;
661 struct cmx_softc *sc;
665 sc = devclass_get_softc(cmx_devclass, minor(dev));
666 if (sc == NULL || sc->dying)
669 bsr = cmx_read_BSR(sc);
670 DEBUG_printf(sc->dev, "called (events=%b BSR=%b)\n",
671 ap->a_events, POLLBITS, bsr, BSRBITS);
673 revents = ap->a_events & (POLLOUT | POLLWRNORM);
674 if (ap->a_events & (POLLIN | POLLRDNORM)) {
675 if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) {
676 revents |= ap->a_events & (POLLIN | POLLRDNORM);
678 selrecord(curthread, &sc->sel);
681 DEBUG_printf(sc->dev, "enabling polling\n");
683 callout_reset(&sc->ch, POLL_TICKS,
686 DEBUG_printf(sc->dev, "already polling\n");
692 DEBUG_printf(sc->dev, "success (revents=%b)\n", revents, POLLBITS);
697 static struct filterops cmx_read_filterops =
698 { 1, NULL, cmx_filter_detach, cmx_filter_read };
699 static struct filterops cmx_write_filterops =
700 { 1, NULL, cmx_filter_detach, cmx_filter_write };
703 * Kevent handler. Writing is always possible, reading is only possible
704 * if BSR_BULK_IN_FULL is set. Will start the cmx_tick callout and
708 cmx_kqfilter(struct dev_kqfilter_args *ap)
710 cdev_t dev = ap->a_head.a_dev;
711 struct knote *kn = ap->a_kn;
712 struct cmx_softc *sc;
717 sc = devclass_get_softc(cmx_devclass, minor(dev));
719 switch (kn->kn_filter) {
721 kn->kn_fop = &cmx_read_filterops;
722 kn->kn_hook = (caddr_t)sc;
725 kn->kn_fop = &cmx_write_filterops;
726 kn->kn_hook = (caddr_t)sc;
729 ap->a_result = EOPNOTSUPP;
734 klist = &sc->sel.si_note;
735 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
742 cmx_filter_detach(struct knote *kn)
744 struct cmx_softc *sc = (struct cmx_softc *)kn->kn_hook;
748 klist = &sc->sel.si_note;
749 SLIST_REMOVE(klist, kn, knote, kn_selnext);
754 cmx_filter_read(struct knote *kn, long hint)
756 struct cmx_softc *sc = (struct cmx_softc *)kn->kn_hook;
760 if (sc == NULL || sc->dying) {
761 kn->kn_flags |= EV_EOF;
765 bsr = cmx_read_BSR(sc);
766 if (cmx_test(bsr, BSR_BULK_IN_FULL, 1)) {
772 callout_reset(&sc->ch, POLL_TICKS,
782 cmx_filter_write(struct knote *kn, long hint)
789 * Interrupt handler. Currently has no function except to
790 * print register status (if debugging is also enabled).
795 struct cmx_softc *sc = (struct cmx_softc *)arg;
797 if (sc == NULL || sc->dying)
800 DEBUG_printf(sc->dev, "received interrupt (SCR=%b BSR=%b)\n",
801 cmx_read_SCR(sc), SCRBITS,
802 cmx_read_BSR(sc), BSRBITS);