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