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.1.2.1 2008/08/09 09:15:05 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>
49 #include <sys/fcntl.h>
51 #include <sys/selinfo.h>
52 #include <sys/types.h>
54 #include <sys/device.h>
55 #include <sys/thread2.h>
57 #include <sys/module.h>
59 #include <sys/resource.h>
66 #define DEBUG_printf(dev, fmt, args...) \
67 device_printf(dev, "%s: " fmt, __FUNCTION__, ##args)
69 #define DEBUG_printf(dev, fmt, args...)
72 #define SPIN_COUNT 1000
73 #define WAIT_TICKS (hz/100)
74 #define POLL_TICKS (hz/10)
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)
82 static char BSRBITS
[] = "\020"
83 "\01BULK_OUT_FULL" /* 0x01 */
84 "\02BULK_IN_FULL" /* 0x02 */
85 "\03(0x04)"; /* 0x04 */
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 */
95 "\10HOST_TO_READER_START"; /* 0x80 */
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 */
127 devclass_t cmx_devclass
;
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_poll_t cmx_poll
;
135 static void cmx_intr(void *arg
);
138 #define CDEV_MAJOR 185
139 static struct dev_ops cmx_ops
= {
140 { "cmx", CDEV_MAJOR
, 0 },
142 .d_close
= cmx_close
,
144 .d_write
= cmx_write
,
149 * Initialize the softc structure. Must be called from
150 * the bus specific device allocation routine.
153 cmx_init_softc(device_t dev
)
155 struct cmx_softc
*sc
= device_get_softc(dev
);
157 sc
->timeout
= CCID_DRIVER_MINIMUM_TIMEOUT
;
161 * Allocate driver resources. Must be called from the
162 * bus specific device allocation routine. Caller must
163 * ensure to call cmx_release_resources to free the
164 * resources when detaching.
165 * Return zero if successful, and ENOMEM if the resources
166 * could not be allocated.
169 cmx_alloc_resources(device_t dev
)
171 struct cmx_softc
*sc
= device_get_softc(dev
);
176 sc
->ioport
= bus_alloc_resource_any(dev
, SYS_RES_IOPORT
,
177 &sc
->ioport_rid
, RF_ACTIVE
);
179 device_printf(dev
, "failed to allocate io port\n");
182 sc
->bst
= rman_get_bustag(sc
->ioport
);
183 sc
->bsh
= rman_get_bushandle(sc
->ioport
);
186 sc
->irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
,
187 &sc
->irq_rid
, RF_ACTIVE
);
189 device_printf(dev
, "failed to allocate irq\n");
192 if ((rv
= bus_setup_intr(dev
, sc
->irq
, 0, cmx_intr
, sc
,
193 &sc
->ih
, NULL
)) != 0) {
194 device_printf(dev
, "failed to set up irq\n");
199 lockinit(&sc
->mtx
, "cmx softc lock", 0, LK_CANRECURSE
);
200 callout_init(&sc
->ch
);
206 * Release the resources allocated by cmx_allocate_resources.
209 cmx_release_resources(device_t dev
)
211 struct cmx_softc
*sc
= device_get_softc(dev
);
213 lockuninit(&sc
->mtx
);
217 bus_teardown_intr(dev
, sc
->irq
, sc
->ih
);
221 bus_release_resource(dev
, SYS_RES_IRQ
,
222 sc
->irq_rid
, sc
->irq
);
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
);
238 * Bus independant device attachment routine. Creates the
239 * character device node.
242 cmx_attach(device_t dev
)
244 struct cmx_softc
*sc
= device_get_softc(dev
);
246 if (!sc
|| sc
->dying
)
249 dev_ops_add(&cmx_ops
, -1, device_get_unit(dev
));
250 sc
->cdev
= make_dev(&cmx_ops
, 0, UID_ROOT
, GID_WHEEL
, 0600,
251 "cmx%d", device_get_unit(dev
));
253 device_printf(dev
, "failed to create character device\n");
256 sc
->cdev
->si_drv1
= sc
;
262 * Bus independant device detachment routine. Makes sure all
263 * allocated resources are freed, callouts disabled and waiting
264 * processes unblocked.
267 cmx_detach(device_t dev
)
269 struct cmx_softc
*sc
= device_get_softc(dev
);
271 DEBUG_printf(dev
, "called\n");
277 DEBUG_printf(sc
->dev
, "disabling polling\n");
278 callout_stop(&sc
->ch
);
287 DEBUG_printf(dev
, "releasing resources\n");
288 cmx_release_resources(dev
);
289 dev_ops_remove(&cmx_ops
, -1, device_get_unit(dev
));
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
304 cmx_wait_BSR(struct cmx_softc
*sc
, uint8_t flags
, int test
)
308 for (int i
= 0; i
< SPIN_COUNT
; i
++) {
309 if (cmx_test_BSR(sc
, flags
, test
))
313 for (int i
= 0; i
* WAIT_TICKS
< sc
->timeout
; i
++) {
314 if (cmx_test_BSR(sc
, flags
, test
))
316 rv
= tsleep(sc
, PCATCH
, "cmx", WAIT_TICKS
);
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.
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.
340 cmx_sync_write_SCR(struct cmx_softc
*sc
, uint8_t val
)
344 if ((rv
= cmx_wait_BSR(sc
, BSR_BULK_OUT_FULL
, 0)) != 0) {
348 cmx_write_SCR(sc
, val
);
350 if ((rv
= cmx_wait_BSR(sc
, BSR_BULK_OUT_FULL
, 0)) != 0) {
358 * Returns a suitable timeout value based on the given command byte.
359 * Some commands appear to need longer timeout values than others.
361 static inline unsigned long
362 cmx_timeout_by_cmd(uint8_t 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
;
371 case CMD_PC_TO_RDR_ICCPOWERON
:
372 return CCID_DRIVER_ASYNC_POWERUP_TIMEOUT
;
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
:
382 return CCID_DRIVER_MINIMUM_TIMEOUT
;
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.
395 struct cmx_softc
*sc
= xsc
;
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)) {
406 callout_reset(&sc
->ch
, POLL_TICKS
, cmx_tick
, sc
);
413 * Open the character device. Only a single process may open the
417 cmx_open(struct dev_open_args
*ap
)
419 cdev_t dev
= ap
->a_head
.a_dev
;
420 struct cmx_softc
*sc
;
422 sc
= devclass_get_softc(cmx_devclass
, minor(dev
));
423 if (sc
== NULL
|| sc
->dying
)
434 DEBUG_printf(sc
->dev
, "open (flags=%b thread=%p)\n",
435 ap
->a_oflags
, MODEBITS
, curthread
);
440 * Close the character device.
443 cmx_close(struct dev_close_args
*ap
)
445 cdev_t dev
= ap
->a_head
.a_dev
;
446 struct cmx_softc
*sc
;
448 sc
= devclass_get_softc(cmx_devclass
, minor(dev
));
449 if (sc
== NULL
|| sc
->dying
)
458 DEBUG_printf(sc
->dev
, "disabling polling\n");
459 callout_stop(&sc
->ch
);
468 DEBUG_printf(sc
->dev
, "close (flags=%b thread=%p)\n",
469 ap
->a_fflag
, MODEBITS
, curthread
);
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.
481 cmx_read(struct dev_read_args
*ap
)
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
;
488 int rv
, amnt
, offset
;
490 sc
= devclass_get_softc(cmx_devclass
, minor(dev
));
491 if (sc
== NULL
|| sc
->dying
)
494 DEBUG_printf(sc
->dev
, "called (len=%d flag=%b)\n",
495 uio
->uio_resid
, ap
->a_ioflag
, MODEBITS
);
499 DEBUG_printf(sc
->dev
, "disabling polling\n");
500 callout_stop(&sc
->ch
);
508 if (uio
->uio_resid
== 0) {
512 if (uio
->uio_resid
< CMX_MIN_RDLEN
) {
516 if (ap
->a_ioflag
& O_NONBLOCK
) {
517 if (cmx_test_BSR(sc
, BSR_BULK_IN_FULL
, 0)) {
522 for (int i
= 0; i
< 5; i
++) {
523 if ((rv
= cmx_wait_BSR(sc
, BSR_BULK_IN_FULL
, 1)) != 0) {
526 sc
->buf
[i
] = cmx_read_DTR(sc
);
527 DEBUG_printf(sc
->dev
, "buf[%02x]=%02x\n", i
, sc
->buf
[i
]);
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
);
537 if (uio
->uio_resid
< bytes_left
) {
541 offset
= 5; /* prefetched header */
542 while (bytes_left
> 0) {
543 amnt
= MIN(bytes_left
, sizeof(sc
->buf
));
545 for (int i
= offset
; i
< amnt
; i
++) {
546 if ((rv
= cmx_wait_BSR(sc
, BSR_BULK_IN_FULL
, 1))!=0) {
549 sc
->buf
[i
] = cmx_read_DTR(sc
);
550 DEBUG_printf(sc
->dev
, "buf[%02x]=%02x\n",
554 if ((rv
= uiomove(sc
->buf
, amnt
, uio
)) != 0) {
555 DEBUG_printf(sc
->dev
, "uiomove failed (%d)\n", rv
);
564 if ((rv
= cmx_wait_BSR(sc
, BSR_BULK_IN_FULL
, 1)) != 0) {
568 if ((rv
= cmx_sync_write_SCR(sc
, SCR_READER_TO_HOST_DONE
)) != 0) {
572 uc
= cmx_read_DTR(sc
);
573 DEBUG_printf(sc
->dev
, "success (DTR=%02x)\n", uc
);
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
584 cmx_write(struct dev_write_args
*ap
)
586 cdev_t dev
= ap
->a_head
.a_dev
;
587 struct cmx_softc
*sc
;
588 struct uio
*uio
= ap
->a_uio
;
591 sc
= devclass_get_softc(cmx_devclass
, minor(dev
));
592 if (sc
== NULL
|| sc
->dying
)
595 DEBUG_printf(sc
->dev
, "called (len=%d flag=%b)\n",
596 uio
->uio_resid
, ap
->a_ioflag
, MODEBITS
);
598 if (uio
->uio_resid
== 0) {
602 if (uio
->uio_resid
< CMX_MIN_WRLEN
) {
606 if ((rv
= cmx_sync_write_SCR(sc
, SCR_HOST_TO_READER_START
)) != 0) {
611 while (uio
->uio_resid
> 0) {
612 amnt
= MIN(uio
->uio_resid
, sizeof(sc
->buf
));
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
);
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
);
628 for (int i
= 0; i
< amnt
; i
++) {
629 if ((rv
= cmx_wait_BSR(sc
, BSR_BULK_OUT_FULL
, 0))!=0) {
632 cmx_write_DTR(sc
, sc
->buf
[i
]);
633 DEBUG_printf(sc
->dev
, "buf[%02x]=%02x\n",
638 if ((rv
= cmx_sync_write_SCR(sc
, SCR_HOST_TO_READER_DONE
)) != 0) {
642 DEBUG_printf(sc
->dev
, "success\n");
647 * Poll handler. Writing is always possible, reading is only possible
648 * if BSR_BULK_IN_FULL is set. Will start the cmx_tick callout and
652 cmx_poll(struct dev_poll_args
*ap
)
654 cdev_t dev
= ap
->a_head
.a_dev
;
655 struct cmx_softc
*sc
;
659 sc
= devclass_get_softc(cmx_devclass
, minor(dev
));
660 if (sc
== NULL
|| sc
->dying
)
663 bsr
= cmx_read_BSR(sc
);
664 DEBUG_printf(sc
->dev
, "called (events=%b BSR=%b)\n",
665 ap
->a_events
, POLLBITS
, bsr
, BSRBITS
);
667 revents
= ap
->a_events
& (POLLOUT
| POLLWRNORM
);
668 if (ap
->a_events
& (POLLIN
| POLLRDNORM
)) {
669 if (cmx_test(bsr
, BSR_BULK_IN_FULL
, 1)) {
670 revents
|= ap
->a_events
& (POLLIN
| POLLRDNORM
);
672 selrecord(curthread
, &sc
->sel
);
675 DEBUG_printf(sc
->dev
, "enabling polling\n");
677 callout_reset(&sc
->ch
, POLL_TICKS
,
680 DEBUG_printf(sc
->dev
, "already polling\n");
686 DEBUG_printf(sc
->dev
, "success (revents=%b)\n", revents
, POLLBITS
);
693 * Interrupt handler. Currently has no function except to
694 * print register status (if debugging is also enabled).
699 struct cmx_softc
*sc
= (struct cmx_softc
*)arg
;
701 if (sc
== NULL
|| sc
->dying
)
704 DEBUG_printf(sc
->dev
, "received interrupt (SCR=%b BSR=%b)\n",
705 cmx_read_SCR(sc
), SCRBITS
,
706 cmx_read_BSR(sc
), BSRBITS
);