1/*- 2 * Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 14 unchanged lines hidden (view full) --- 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * High-level driver for �PD7210 based GPIB cards. 27 * 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/dev/ieee488/ibfoo.c 141777 2005-02-12 23:52:44Z phk $"); |
32 33# define IBDEBUG 34# undef IBDEBUG 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/conf.h> 39#include <sys/malloc.h> --- 16 unchanged lines hidden (view full) --- 56 57static MALLOC_DEFINE(M_IBFOO, "IBFOO", "IBFOO"); 58 59 60/* ibfoo API */ 61 62#include <dev/ieee488/ibfoo_int.h> 63 |
64/* XXX: This is really a bitmap */ 65enum h_kind { 66 H_DEV = 1, 67 H_BOARD = 2, 68 H_EITHER = 3 69}; 70 |
71struct handle { 72 LIST_ENTRY(handle) list; 73 int handle; |
74 enum h_kind kind; |
75 int pad; 76 int sad; 77 struct timeval timeout; 78 int eot; 79 int eos; 80 int dma; 81}; 82 --- 144 unchanged lines hidden (view full) --- 227 struct upd7210 *u; 228 struct ibfoo *ib; 229 struct timeval tv; 230 231 u = arg; 232 ib = u->ibfoo; 233 mtx_lock(&u->mutex); 234 if (ib->mode == DMA_IDATA && isa_dmatc(u->dmachan)) { |
235 KASSERT(u->dmachan >= 0, ("Bogus dmachan = %d", u->dmachan)); |
236 upd7210_wr(u, IMR1, 0); 237 upd7210_wr(u, IMR2, 0); 238 ib->mode = IDLE; 239 wakeup(&ib->buflen); 240 } 241 if (ib->mode > BUSY) { 242 upd7210_rd(u, ISR1); 243 upd7210_rd(u, ISR2); --- 147 unchanged lines hidden (view full) --- 391} 392 393static int 394dma_idata(struct upd7210 *u, u_char *data, int len) 395{ 396 int j; 397 struct ibfoo *ib; 398 |
399 KASSERT(u->dmachan >= 0, ("Bogus dmachan %d", u->dmachan)); |
400 ib = u->ibfoo; 401 ib->mode = DMA_IDATA; 402 mtx_lock(&Giant); 403 isa_dmastart(ISADMA_READ, data, len, u->dmachan); 404 mtx_unlock(&Giant); 405 mtx_lock(&u->mutex); 406 upd7210_wr(u, IMR1, IXR1_ENDRX); 407 upd7210_wr(u, IMR2, IMR2_DMAI); 408 gpib_ib_wait_xfer(u, ib); 409 mtx_unlock(&u->mutex); 410 mtx_lock(&Giant); 411 j = isa_dmastatus(u->dmachan); 412 isa_dmadone(ISADMA_READ, data, len, u->dmachan); 413 mtx_unlock(&Giant); 414 return (len - j); 415} 416 |
417static int 418ib_send_msg(struct ibfoo *ib, int msg) 419{ 420 u_char buf[10]; 421 int i, j; 422 423 i = 0; 424 buf[i++] = UNT; 425 buf[i++] = UNL; 426 buf[i++] = LAD | ib->h->pad; 427 if (ib->h->sad) 428 buf[i++] = LAD | TAD | ib->h->sad; 429 buf[i++] = TAD | 0; 430 buf[i++] = msg; 431 j = pio_cmd(ib->u, buf, i); 432 if (i != j) 433 ib_set_error(ib->ap, EABO); /* XXX ? */ 434 return (0); 435} 436 437static int 438ibask(struct ibfoo *ib) 439{ /* XXX */ 440 441 ibdebug = ib->ap->option; 442 return (0); 443} 444 |
445#define ibbna NULL 446#define ibcac NULL |
447 448static int 449ibclr(struct ibfoo *ib) 450{ 451 452 return (ib_send_msg(ib, SDC)); 453} 454 |
455#define ibcmd NULL 456#define ibcmda NULL 457#define ibconfig NULL 458 459static int 460ibdev(struct ibfoo *ib) |
461{ /* TBD */ |
462 struct handle *h; 463 464 h = malloc(sizeof *h, M_IBFOO, M_ZERO | M_WAITOK); 465 h->handle = alloc_unr(ib->unrhdr); |
466 h->kind = H_DEV; |
467 h->pad = ib->ap->pad; 468 h->sad = ib->ap->sad; 469 h->timeout = timeouts[ib->ap->tmo]; 470 h->eot = ib->ap->eot; 471 h->eos = ib->ap->eos; 472 mtx_lock(&ib->u->mutex); 473 LIST_INSERT_HEAD(&ib->handles, h, list); 474 mtx_unlock(&ib->u->mutex); 475 ib->ap->__retval = h->handle; 476 return (0); 477} 478 479#define ibdiag NULL 480 481static int 482ibdma(struct ibfoo *ib) 483{ 484 |
485 if (ib->u->dmachan < 0 && ib->ap->v) 486 return (ib_set_error(ib->ap, EARG)); |
487 ib->h->dma = ib->ap->v; 488 return (0); 489} 490 491static int 492ibeos(struct ibfoo *ib) 493{ 494 |
495 ib->ap->__iberr = ib->h->eos; |
496 ib->h->eos = ib->ap->eos; 497 if (ib->rdh == ib->h) 498 config_eos(ib->u, ib->h); 499 return (0); 500} 501 502static int 503ibeot(struct ibfoo *ib) --- 5 unchanged lines hidden (view full) --- 509 510#define ibevent NULL 511#define ibfind NULL 512#define ibgts NULL 513#define ibist NULL 514#define iblines NULL 515#define ibllo NULL 516#define ibln NULL |
517 518static int 519ibloc(struct ibfoo *ib) 520{ /* XXX */ 521 522 if (ib->h->kind == H_BOARD) 523 return (EOPNOTSUPP); /* XXX */ 524 return (ib_send_msg(ib, GTL)); 525} 526 527static int 528ibonl(struct ibfoo *ib) 529{ /* XXX */ 530 531 if (ib->ap->v) 532 return (EOPNOTSUPP); /* XXX */ 533 mtx_lock(&ib->u->mutex); 534 LIST_REMOVE(ib->h, list); 535 mtx_unlock(&ib->u->mutex); 536 free(ib->h, M_IBFOO); 537 ib->h = NULL; 538 return (0); 539} 540 541static int 542ibpad(struct ibfoo *ib) 543{ 544 545 ib->h->pad = ib->ap->pad; 546 return (0); 547} 548 |
549#define ibpct NULL 550#define ibpoke NULL 551#define ibppc NULL 552 553static int 554ibrd(struct ibfoo *ib) |
555{ /* TBD */ |
556 u_char buf[10], *bp; 557 int i, j, error, bl, bc; 558 u_char *dp; 559 |
560 if (ib->h->kind == H_BOARD) 561 return (EOPNOTSUPP); /* XXX */ |
562 bl = ib->ap->cnt; 563 if (bl > PAGE_SIZE) 564 bl = PAGE_SIZE; 565 bp = malloc(bl, M_IBFOO, M_WAITOK); 566 567 if (ib->rdh != ib->h) { 568 i = 0; 569 buf[i++] = UNT; --- 12 unchanged lines hidden (view full) --- 582 bc = ib->ap->cnt; 583 error = 0; 584 while (bc > 0 && ib->ap->__iberr == 0) { 585 j = imin(bc, PAGE_SIZE); 586 if (ib->h->dma) 587 i = dma_idata(ib->u, bp, j); 588 else 589 i = pio_idata(ib->u, bp, j); |
590 error = copyout(bp, dp , i); 591 if (error) 592 break; 593 ib->ap->__ibcnt += i; 594 if (i != j) 595 break; 596 bc -= i; 597 dp += i; --- 4 unchanged lines hidden (view full) --- 602 603#define ibrda NULL 604#define ibrdf NULL 605#define ibrdkey NULL 606#define ibrpp NULL 607#define ibrsc NULL 608#define ibrsp NULL 609#define ibrsv NULL |
610 611static int 612ibsad(struct ibfoo *ib) 613{ 614 615 ib->h->sad = ib->ap->sad; 616 return (0); 617} 618 |
619#define ibsgnl NULL |
620 621static int 622ibsic(struct ibfoo *ib) 623{ /* TBD */ 624 625 upd7210_wr(ib->u, AUXMR, AUXMR_SIFC); 626 DELAY(100); 627 upd7210_wr(ib->u, AUXMR, AUXMR_CIFC); 628 return (0); 629} 630 |
631#define ibsre NULL 632#define ibsrq NULL 633#define ibstop NULL 634 635static int 636ibtmo(struct ibfoo *ib) 637{ 638 639 ib->h->timeout = timeouts[ib->ap->tmo]; 640 return (0); 641} 642 643#define ibtrap NULL |
644 645static int 646ibtrg(struct ibfoo *ib) 647{ 648 649 return (ib_send_msg(ib, GET)); 650} 651 |
652#define ibwait NULL 653 654static int 655ibwrt(struct ibfoo *ib) |
656{ /* XXX */ |
657 u_char buf[10], *bp; 658 int i; 659 |
660 if (ib->h->kind == H_BOARD) 661 return (EOPNOTSUPP); |
662 bp = malloc(ib->ap->cnt, M_IBFOO, M_WAITOK); 663 /* XXX: bigger than PAGE_SIZE handling */ 664 i = copyin(ib->ap->buffer, bp, ib->ap->cnt); 665 if (i) { 666 free(bp, M_IBFOO); 667 return (i); 668 } 669 if (ib->wrh != ib->h) { --- 19 unchanged lines hidden (view full) --- 689 690#define ibwrta NULL 691#define ibwrtf NULL 692#define ibwrtkey NULL 693#define ibxtrc NULL 694 695static struct ibhandler { 696 const char *name; |
697 enum h_kind kind; |
698 ibhandler_t *func; 699 u_int args; 700} ibhandlers[] = { |
701 [__ID_IBASK] = { "ibask", H_EITHER, ibask, __F_HANDLE | __F_OPTION | __F_RETVAL }, 702 [__ID_IBBNA] = { "ibbna", H_DEV, ibbna, __F_HANDLE | __F_BDNAME }, 703 [__ID_IBCAC] = { "ibcac", H_BOARD, ibcac, __F_HANDLE | __F_V }, 704 [__ID_IBCLR] = { "ibclr", H_DEV, ibclr, __F_HANDLE }, 705 [__ID_IBCMD] = { "ibcmd", H_BOARD, ibcmd, __F_HANDLE | __F_BUFFER | __F_CNT }, 706 [__ID_IBCMDA] = { "ibcmda", H_BOARD, ibcmda, __F_HANDLE | __F_BUFFER | __F_CNT }, 707 [__ID_IBCONFIG] = { "ibconfig", H_EITHER, ibconfig, __F_HANDLE | __F_OPTION | __F_VALUE }, 708 [__ID_IBDEV] = { "ibdev", 0, ibdev, __F_BOARDID | __F_PAD | __F_SAD | __F_TMO | __F_EOT | __F_EOS }, 709 [__ID_IBDIAG] = { "ibdiag", H_EITHER, ibdiag, __F_HANDLE | __F_BUFFER | __F_CNT }, 710 [__ID_IBDMA] = { "ibdma", H_EITHER, ibdma, __F_HANDLE | __F_V }, 711 [__ID_IBEOS] = { "ibeos", H_EITHER, ibeos, __F_HANDLE | __F_EOS }, 712 [__ID_IBEOT] = { "ibeot", H_EITHER, ibeot, __F_HANDLE | __F_EOT }, 713 [__ID_IBEVENT] = { "ibevent", H_BOARD, ibevent, __F_HANDLE | __F_EVENT }, 714 [__ID_IBFIND] = { "ibfind", 0, ibfind, __F_BDNAME }, 715 [__ID_IBGTS] = { "ibgts", H_BOARD, ibgts, __F_HANDLE | __F_V }, 716 [__ID_IBIST] = { "ibist", H_BOARD, ibist, __F_HANDLE | __F_V }, 717 [__ID_IBLINES] = { "iblines", H_BOARD, iblines, __F_HANDLE | __F_LINES }, 718 [__ID_IBLLO] = { "ibllo", H_EITHER, ibllo, __F_HANDLE }, 719 [__ID_IBLN] = { "ibln", H_BOARD, ibln, __F_HANDLE | __F_PADVAL | __F_SADVAL | __F_LISTENFLAG }, 720 [__ID_IBLOC] = { "ibloc", H_EITHER, ibloc, __F_HANDLE }, 721 [__ID_IBONL] = { "ibonl", H_EITHER, ibonl, __F_HANDLE | __F_V }, 722 [__ID_IBPAD] = { "ibpad", H_EITHER, ibpad, __F_HANDLE | __F_PAD }, 723 [__ID_IBPCT] = { "ibpct", H_DEV, ibpct, __F_HANDLE }, 724 [__ID_IBPOKE] = { "ibpoke", H_EITHER, ibpoke, __F_HANDLE | __F_OPTION | __F_VALUE }, 725 [__ID_IBPPC] = { "ibppc", H_EITHER, ibppc, __F_HANDLE | __F_V }, 726 [__ID_IBRD] = { "ibrd", H_EITHER, ibrd, __F_HANDLE | __F_BUFFER | __F_CNT }, 727 [__ID_IBRDA] = { "ibrda", H_EITHER, ibrda, __F_HANDLE | __F_BUFFER | __F_CNT }, 728 [__ID_IBRDF] = { "ibrdf", H_EITHER, ibrdf, __F_HANDLE | __F_FLNAME }, 729 [__ID_IBRDKEY] = { "ibrdkey", H_EITHER, ibrdkey, __F_HANDLE | __F_BUFFER | __F_CNT }, 730 [__ID_IBRPP] = { "ibrpp", H_EITHER, ibrpp, __F_HANDLE | __F_PPR }, 731 [__ID_IBRSC] = { "ibrsc", H_BOARD, ibrsc, __F_HANDLE | __F_V }, 732 [__ID_IBRSP] = { "ibrsp", H_DEV, ibrsp, __F_HANDLE | __F_SPR }, 733 [__ID_IBRSV] = { "ibrsv", H_EITHER, ibrsv, __F_HANDLE | __F_V }, 734 [__ID_IBSAD] = { "ibsad", H_EITHER, ibsad, __F_HANDLE | __F_SAD }, 735 [__ID_IBSGNL] = { "ibsgnl", H_EITHER, ibsgnl, __F_HANDLE | __F_V }, 736 [__ID_IBSIC] = { "ibsic", H_BOARD, ibsic, __F_HANDLE }, 737 [__ID_IBSRE] = { "ibsre", H_BOARD, ibsre, __F_HANDLE | __F_V }, 738 [__ID_IBSRQ] = { "ibsrq", H_EITHER, ibsrq, __F_FUNC }, 739 [__ID_IBSTOP] = { "ibstop", H_EITHER, ibstop, __F_HANDLE }, 740 [__ID_IBTMO] = { "ibtmo", H_EITHER, ibtmo, __F_HANDLE | __F_TMO }, 741 [__ID_IBTRAP] = { "ibtrap", H_EITHER, ibtrap, __F_MASK | __F_MODE }, 742 [__ID_IBTRG] = { "ibtrg", H_DEV, ibtrg, __F_HANDLE }, 743 [__ID_IBWAIT] = { "ibwait", H_EITHER, ibwait, __F_HANDLE | __F_MASK }, 744 [__ID_IBWRT] = { "ibwrt", H_EITHER, ibwrt, __F_HANDLE | __F_BUFFER | __F_CNT }, 745 [__ID_IBWRTA] = { "ibwrta", H_EITHER, ibwrta, __F_HANDLE | __F_BUFFER | __F_CNT }, 746 [__ID_IBWRTF] = { "ibwrtf", H_EITHER, ibwrtf, __F_HANDLE | __F_FLNAME }, 747 [__ID_IBWRTKEY] = { "ibwrtkey", H_EITHER, ibwrtkey, __F_HANDLE | __F_BUFFER | __F_CNT }, 748 [__ID_IBXTRC] = { "ibxtrc", H_EITHER, ibxtrc, __F_HANDLE | __F_BUFFER | __F_CNT }, |
749}; 750 751static const u_int max_ibhandler = sizeof ibhandlers / sizeof ibhandlers[0]; 752 753static void 754ib_dump_args(struct ibhandler *ih, struct ibarg *ap) 755{ 756 757 if (ih->name != NULL) 758 printf("%s(", ih->name); 759 else 760 printf("ibinvalid("); 761 printf("[0x%x]", ap->__field); 762 if (ap->__field & __F_HANDLE) printf(" handle=%d", ap->handle); |
763 if (ap->__field & __F_EOS) printf(" eos=0x%x", ap->eos); |
764 if (ap->__field & __F_EOT) printf(" eot=%d", ap->eot); 765 if (ap->__field & __F_TMO) printf(" tmo=%d", ap->tmo); |
766 if (ap->__field & __F_PAD) printf(" pad=0x%x", ap->pad); 767 if (ap->__field & __F_SAD) printf(" sad=0x%x", ap->sad); |
768 if (ap->__field & __F_BUFFER) printf(" buffer=%p", ap->buffer); 769 if (ap->__field & __F_CNT) printf(" cnt=%ld", ap->cnt); |
770 if (ap->__field & __F_V) printf(" v=%d/0x%x", ap->v, ap->v); |
771 /* XXX more ... */ 772 printf(")\n"); 773} 774 775static int 776gpib_ib_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 777{ 778 struct upd7210 *u; 779 struct ibfoo *ib; |
780 int error = 0; |
781 782 u = dev->si_drv1; 783 784 mtx_lock(&u->mutex); 785 if (u->busy) { 786 mtx_unlock(&u->mutex); 787 return (EBUSY); 788 } 789 u->busy = 1; 790 mtx_unlock(&u->mutex); 791 |
792 if (u->dmachan >= 0) { 793 mtx_lock(&Giant); 794 error = isa_dma_acquire(u->dmachan); 795 if (!error) { 796 error = isa_dma_init(u->dmachan, PAGE_SIZE, M_WAITOK); 797 if (error) 798 isa_dma_release(u->dmachan); 799 } 800 mtx_unlock(&Giant); |
801 } |
802 |
803 if (error) { 804 mtx_lock(&u->mutex); 805 u->busy = 0; 806 mtx_unlock(&u->mutex); 807 return (error); 808 } 809 810 ib = malloc(sizeof *ib, M_IBFOO, M_WAITOK | M_ZERO); --- 38 unchanged lines hidden (view full) --- 849 ib = dev->si_drv2; 850 /* XXX: assert pointer consistency */ 851 852 u->ibfoo = NULL; 853 /* XXX: free handles */ 854 dev->si_drv2 = NULL; 855 free(ib, M_IBFOO); 856 |
857 if (u->dmachan >= 0) { 858 mtx_lock(&Giant); 859 isa_dma_release(u->dmachan); 860 mtx_unlock(&Giant); 861 } |
862 mtx_lock(&u->mutex); 863 u->busy = 0; |
864 ibdebug = 0; |
865 upd7210_wr(u, IMR1, 0x00); 866 upd7210_wr(u, IMR2, 0x00); 867 upd7210_wr(u, AUXMR, AUXMR_CRST); 868 DELAY(10000); 869 mtx_unlock(&u->mutex); 870 return (0); 871} 872 --- 59 unchanged lines hidden (view full) --- 932 933 /* Find the handle, if any */ 934 h = NULL; 935 if ((ap->__field & __F_HANDLE) && gethandle(u, ap, &h)) { 936 mtx_unlock(&u->mutex); 937 return (0); 938 } 939 |
940 /* Check that the handle is the right kind */ 941 if (h != NULL && !(h->kind & ih->kind)) { 942 mtx_unlock(&u->mutex); 943 return (ib_set_error(ap, EARG)); 944 } 945 |
946 /* Set up handle and deadline */ 947 if (h != NULL && timevalisset(&h->timeout)) { 948 getmicrouptime(&deadline); 949 timevaladd(&deadline, &h->timeout); 950 } else { 951 timevalclear(&deadline); 952 } 953 --- 52 unchanged lines hidden --- |