The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/b004.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * FreeBSD device driver for B004-compatible Transputer boards.
    3  *
    4  * based on Linux version Copyright (C) 1993 by Christoph Niemann
    5  *
    6  * Rewritten for FreeBSD by
    7  * Luigi Rizzo (luigi@iet.unipi.it) and
    8  * Lorenzo Vicisano (l.vicisano@iet.unipi.it)
    9  *    Dipartimento di Ingegneria dell'Informazione
   10  *    Universita` di Pisa
   11  *    via Diotisalvi 2, 56126 Pisa, ITALY
   12  * 14 september 1994
   13  *
   14  * Redistribution and use in source and binary forms, with or without
   15  * modification, are permitted provided that the following conditions
   16  * are met:
   17  * 1. Redistributions of source code must retain the above copyright
   18  *    notice, this list of conditions and the following disclaimer.
   19  * 2. Redistributions in binary form must reproduce the above copyright
   20  *    notice, this list of conditions and the following disclaimer in the
   21  *    documentation and/or other materials provided with the distribution.
   22  * 3. All advertising materials mentioning features or use of this software
   23  *    must display the following acknowledgement:
   24  *      This product includes software developed by Christoph Niemann,
   25  *      Luigi Rizzo and Lorenzo Vicisano - Dipartimento di Ingegneria
   26  *              dell'Informazione
   27  * 4. The names of these contributors may not be used to endorse or promote
   28  *  products derived from this software without specific prior written
   29  *  permission.
   30  *
   31  * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
   32  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   33  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   34  * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   35  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   36  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   37  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   38  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   40  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   41  *
   42  * NOTE NOTE NOTE
   43  * The assembler version is still under development.
   44  */
   45 
   46 /* #define USE_ASM */
   47 
   48 #include "bqu.h"
   49 #if NBQU > 0
   50 
   51 #include <sys/param.h>
   52 #include <sys/systm.h>
   53 #include <sys/proc.h>
   54 #include <sys/uio.h>
   55 #include <sys/conf.h>
   56 #include <sys/kernel.h>
   57 #ifdef DEVFS
   58 #include <sys/devfsext.h>
   59 #endif /*DEVFS*/
   60 
   61 #include <machine/clock.h>
   62 
   63 #include <i386/isa/b004.h>
   64 #include <i386/isa/isa_device.h>
   65 
   66 #define IOCTL_OUT(arg, ret)             *(int*)arg = ret
   67 
   68 #define B004PRI (PZERO+8)
   69 
   70 #define B004_CHANCE     8
   71 
   72 /*
   73  * Define these symbols if you want to debug the code.
   74  */
   75 #undef B004_DEBUG
   76 #undef B004_DEBUG_2
   77 
   78 #ifdef B004_DEBUG
   79 static u_char d_inb(u_int port);
   80 static void d_outb(u_int port, u_char data);
   81 
   82 #define out(port,data)  d_outb(port, data)
   83 #define in(a)           d_inb(((u_int)a))
   84 #else
   85 #define out(port, data)         outb(port,data)
   86 #define in(port)                inb(((u_int)port))
   87 #endif B004_DEBUG
   88 
   89 #ifdef B004_DEBUG
   90 #define DEB(x) x
   91 #define NO_DEB(x) /* */
   92 #else
   93 #define DEB(x) /* */
   94 #define NO_DEB(x) x
   95 #endif
   96 
   97 #ifdef B004_DEBUG_2
   98 #define DEB2(x) x
   99 #else
  100 #define DEB2(x)
  101 #endif
  102 
  103 static int bquprobe(struct isa_device *idp);
  104 static int bquattach(struct isa_device *idp);
  105 
  106 
  107 struct isa_driver bqudriver = {
  108    bquprobe, bquattach, "bqu"
  109 };
  110 
  111 static  d_open_t        bquopen;
  112 static  d_close_t       bquclose;
  113 static  d_read_t        bquread;
  114 static  d_write_t       bquwrite;
  115 static  d_ioctl_t       bquioctl;
  116 static  d_select_t      bquselect;
  117 
  118 #define CDEV_MAJOR 8
  119 static struct cdevsw bqu_cdevsw = 
  120         { bquopen,      bquclose,       bquread,        bquwrite,       /*8*/
  121           bquioctl,     nostop,         nullreset,      nodevtotty,/* tputer */
  122           bquselect,    nommap,         NULL,   "bqu",  NULL,   -1 };
  123 
  124 static int b004_sleep; /* wait address */
  125 
  126 static struct b004_struct b004_table[NBQU];
  127 
  128 static int first_time=1;
  129 
  130 /*
  131  * At these addresses the driver will search for B004-compatible boards
  132  */
  133 static int
  134 b004_base_addresses[B004_CHANCE] = {
  135     /* 0x150, 0x170, 0x190, 0x200, 0x300, 0x320, 0x340, 0x360 */
  136     0x150, 0x190, 0, 0, 0, 0, 0, 0
  137 };
  138 
  139 #ifdef B004_DEBUG
  140 static void
  141 d_outb(u_int port, u_char data)
  142 {
  143 
  144         printf("OUT 0x%x TO 0x%x\n",data,port);
  145         outb(port,data);
  146 }
  147 
  148 static u_char
  149 d_inb(u_int port)
  150 {
  151 u_char ap;
  152         ap=inb(port);
  153         printf("INPUT 0x%x FROM 0x%x\n",ap,port);
  154         return(ap);
  155 }
  156 #endif
  157 
  158 static int
  159 detected(int base)
  160 {
  161     int i;
  162     for(i=0;i<NBQU;i++)
  163         if ((B004_F(i) & B004_EXIST) && (B004_BASE(i)==base)) return 1;
  164     return (0);
  165 }
  166 
  167 #define b004_delay(a)   DELAY(10000)
  168 
  169 /*
  170  * static void bqureset(): reset transputer network.
  171  *
  172  */
  173 
  174 static void
  175 bqureset( const int dev_min )
  176 {
  177     DEB(printf("B004 resetting transputer at link %d.\n", dev_min);)
  178     out(B004_BASE(dev_min)+B004_ANALYSE_OFFSET, B004_DEASSERT_ANALYSE);
  179     b004_delay(dev_min);
  180 
  181     out(B004_BASE(dev_min) + B004_RESET_OFFSET, B004_DEASSERT_RESET);
  182     b004_delay(dev_min);
  183 
  184     out(B004_BASE(dev_min) + B004_RESET_OFFSET, B004_ASSERT_RESET);
  185     b004_delay(dev_min);
  186 
  187     out(B004_BASE(dev_min) + B004_RESET_OFFSET, B004_DEASSERT_RESET);
  188     b004_delay(dev_min);
  189 
  190     DEB(printf("B004 reset done.\n");)
  191 }
  192 
  193 /*
  194  * static void bquanalyse(): switch transputer network to analyse mode.
  195  *
  196  */
  197 
  198 static void
  199 bquanalyse( const int dev_min )
  200 {
  201     DEB(printf("B004 analysing transputer at link %d.\n", dev_min);)
  202 
  203     out(B004_BASE(dev_min) + B004_ANALYSE_OFFSET, B004_DEASSERT_ANALYSE);
  204     b004_delay(dev_min);
  205 
  206     out(B004_BASE(dev_min) + B004_ANALYSE_OFFSET, B004_ASSERT_ANALYSE);
  207     b004_delay(dev_min);
  208 
  209     out(B004_BASE(dev_min) + B004_RESET_OFFSET, B004_ASSERT_RESET);
  210     b004_delay(dev_min);
  211 
  212     out(B004_BASE(dev_min) + B004_RESET_OFFSET, B004_DEASSERT_RESET);
  213     b004_delay(dev_min);
  214 
  215     out(B004_BASE(dev_min) + B004_ANALYSE_OFFSET, B004_DEASSERT_ANALYSE);
  216     b004_delay(dev_min);
  217 
  218     DEB(printf("B004 switching to analyse-mode done.\n");)
  219 }
  220 
  221 
  222 /****************************************************************************
  223  *
  224  * int bquread() - read bytes from the link interface.
  225  *
  226  * At first, the driver checks if the link-interface is ready to send a byte
  227  * to the PC. If not, this check is repeated up to B004_MAXTRY times.
  228  * If the link-interface is not ready after this loop, the driver sleeps for
  229  * an NO=1 ticks and then checks the link-interface again.
  230  * If the interface is still not ready, repeats as above incrementing NO.
  231  * Once almost one byte is read N0 is set to 1.
  232  * If B004_TIMEOUT != 0 and the link-interface is not ready for more than
  233  * B004_TIMEOUT ticks read aborts returnig with the number of bytes read
  234  * or with an error if no byte was read.
  235  *
  236  * By default, B004_TIMEOUT is = 0 (read is blocking)
  237  *
  238  *****************************************************************************/
  239 
  240 static int
  241 bquread(dev_t dev, struct uio *uio, int flag)
  242 {
  243     unsigned int dev_min = minor(dev) & 7;
  244 
  245     int timeout=B004_TIMEOUT(dev_min);
  246     int Timeout=timeout;
  247     int idr=B004_IDR(dev_min);
  248     int isr=B004_ISR(dev_min);
  249     char        buffer[B004_MAX_BYTES];
  250 
  251     if ( uio->uio_resid < 0) {
  252         DEB(printf("B004: invalid count for reading = %d.\n", uio->uio_resid);)
  253         return EINVAL;
  254     }
  255 
  256     while ( uio->uio_resid ) {
  257         int sleep_ticks=0;
  258         char *p, *last, *lim;
  259         int i, end = min(B004_MAX_BYTES,uio->uio_resid);
  260         lim= &buffer[end];
  261         for (p= buffer; p<lim;) {
  262             last=p;
  263             /*** try to read as much as possible ***/
  264 #ifdef USE_ASM
  265         /* assembly code uses a very tight loop, with
  266          * BX= data port, DX= address port, CX=count, ES:DI=p, AL=data, AH=1
  267          * SI=retry counter
  268          */
  269         __asm__ (
  270             "movl %1, %%edx\n\t" /* isr */
  271             "movl %2, %%ebx\n\t" /* idr */
  272             "movl %3, %%edi\n" /* p */
  273             "movl %4, %%ecx\n\t" /* lim */
  274             "subl %%edi, %%ecx\n\t"
  275 
  276             "push %%es\n\t"
  277             "movw %%ss, %%ax\n\t" /** prepare ES, DF for transfer */
  278             "movw %%ax, %%es\n\t"
  279             "cld\n\t"
  280             "movb $1, %%ah\n\t"
  281 
  282             "1:\tinb %%dx, %%al\n\t"
  283             "testb %%ah, %%al\n\t"
  284             "jz 2f\n\t"
  285             "xchgl %%edx, %%ebx\n\t"
  286             "insb\n\t"
  287             "xchgl %%edx, %%ebx\n"
  288             "2:\tloop 1b\n\t"
  289 
  290             "pop %%es\n\t"
  291             "movl %%edi, %0\n\t" /* store p */
  292                 : /* out */ "=g" (p)
  293                 : /* in */ "g" (isr), "g" (idr), "g" (p), "g" (lim)
  294                 : /* regs */ "eax", "ebx", "edx", "ecx", "edi");
  295 #else
  296             for (i=lim - p; i-- ;)
  297                 if (inb(isr)&B004_READBYTE) *p++ =(char) inb(idr);
  298 #endif
  299             if (last!=p) {
  300                 sleep_ticks = 0;
  301             } else {
  302                 /*** no new data read, must sleep ***/
  303                 sleep_ticks= (sleep_ticks<20 ? sleep_ticks+1 : sleep_ticks);
  304                 if (Timeout) {
  305                     if (timeout <=0) {
  306                         DEB2(printf("Read : TIMEOUT OCCURRED XXXXXXXXXXX\n");)
  307                         break;
  308                     }
  309                     if (timeout < sleep_ticks) sleep_ticks=timeout;
  310                     timeout -= sleep_ticks;
  311                 }
  312                 DEB2(printf("Read: SLEEPING FOR %d TICKS XXXXX\n",sleep_ticks);)
  313                 if (tsleep((caddr_t)&b004_sleep, B004PRI | PCATCH,
  314                     "b004_rd", sleep_ticks)!=EWOULDBLOCK) return 1;
  315             }
  316         }
  317         if (p != buffer) {
  318             uiomove((caddr_t)buffer, p - buffer, uio);
  319         }
  320         if( (Timeout) && (timeout <= 0) )
  321             break;
  322     }
  323     return 0;
  324 } /* bquread() */
  325 
  326 
  327 /*
  328  * int bquwrite() - write to the link interface.
  329  */
  330 
  331 static int
  332 bquwrite(dev_t dev, struct uio *uio, int flag)
  333 {
  334     unsigned int dev_min = minor(dev) & 7;
  335 
  336     int i, end;
  337     int timeout=B004_TIMEOUT(dev_min);
  338     int Timeout=timeout;
  339     int odr=B004_ODR(dev_min);
  340     int osr=B004_OSR(dev_min);
  341     char        buffer[B004_MAX_BYTES];
  342 
  343     if ( uio->uio_resid < 0) {
  344         DEB(printf("B004 invalid argument for writing: count = %d.\n", uio->uio_resid);)
  345         return EINVAL;
  346     }
  347 
  348     while ( uio->uio_resid ) {
  349         int sleep_ticks=0;
  350         char *p, *last, *lim;
  351         end = min(B004_MAX_BYTES,uio->uio_resid);
  352         uiomove((caddr_t)buffer, end, uio);
  353 
  354         lim= &buffer[end];
  355         for (p= &buffer[0]; p<lim;) {
  356             last=p;
  357 #ifdef USE_ASM
  358         /* assembly code uses a very tight loop, with
  359          * BX= data port, DX= address port, CX=count, DS:SI=p, AL=data, AH=1
  360          * DI= retry counter
  361          * Unfortunately, C is almost as fast as this!
  362          */
  363         __asm__ (
  364             "movl %1, %%edx\n\t" /* osr */
  365             "movl %2, %%ebx\n\t" /* odr */
  366             "movl %3, %%esi\n" /* p */
  367             "movl %4, %%ecx\n\t" /* lim */
  368             "subl %%esi, %%ecx\n\t"
  369 
  370             "push %%ds\n\t"
  371             "movw %%ss, %%ax\n\t" /** prepare DS, DF for transfer */
  372             "movw %%ax, %%ds\n\t"
  373             "cld\n\t"
  374             "movb $1, %%ah\n\t"
  375             "movw $100, %%di\n\t"
  376 
  377             "1:\tinb %%dx, %%al\n\t"
  378             "testb %%ah, %%al\n\t"
  379             "jz 2f\n\t"
  380             "xchgl %%edx, %%ebx\n\t"
  381             "outsb\n\t"
  382             "xchgl %%edx, %%ebx\n\t"
  383             "loop 1b\n\t"
  384             "jmp 3f\n"
  385 
  386         "2:\tdec %%di\n\t"
  387         "jnc 1b\n\t"
  388 
  389             "3:\tpop %%ds\n"
  390             "movl %%esi, %0\n\t" /* store p */
  391                 : /* out */ "=g" (p)
  392                 : /* in */ "g" (osr), "g" (odr), "g" (p), "g" (lim)
  393                 : /* regs */ "eax", "ebx", "edx", "ecx", "esi", "edi");
  394 #else
  395             for (i=lim - p; i-- ; ) {
  396                 if (inb(osr)&B004_WRITEBYTE) outb(odr, *p++);
  397             }
  398 #endif
  399             if (p != last ) {
  400                 sleep_ticks=0;
  401             } else {
  402                 sleep_ticks= (sleep_ticks<20 ? sleep_ticks+1 : sleep_ticks);
  403                 if (Timeout) {
  404                     if (timeout <=0) {
  405                         DEB2(printf("Write : TIMEOUT OCCURRED XXXXXXXXXXX\n");)
  406                         uio->uio_resid += (lim - p);
  407                         break;
  408                     }
  409                     if (timeout < sleep_ticks) sleep_ticks=timeout;
  410                     timeout -= sleep_ticks;
  411                 }
  412                 DEB2(printf("Write: SLEEPING FOR %d TICKS XXXXXXX\n",sleep_ticks);)
  413                 if (tsleep((caddr_t)&b004_sleep, B004PRI | PCATCH,
  414                     "b004_rd", sleep_ticks)!=EWOULDBLOCK) return 1;
  415             }
  416         }
  417         if( (Timeout) && (timeout <= 0) )
  418             break;
  419     }
  420     return 0;
  421 } /* bquwrite() */
  422 
  423 /*
  424  * int bquopen() -- open the link-device.
  425  *
  426  */
  427 
  428 static int
  429 bquopen(dev_t dev, int flags, int fmt, struct proc *p)
  430 {
  431     unsigned int dev_min = minor(dev) & 7;
  432 
  433     if (dev_min >= NBQU) {
  434         DEB(printf("B004 not opened, minor number >= %d.\n", NBQU);)
  435         return ENXIO;
  436     }
  437     if ((B004_F(dev_min) & B004_EXIST) == 0) {
  438         DEB(printf("B004 not opened, board %d does not exist.\n", dev_min);)
  439         return ENXIO;
  440     }
  441     if (B004_F(dev_min) & B004_BUSY) {
  442         DEB(printf("B004 not opened, board busy (minor = %d).\n", dev_min);)
  443         return EBUSY;
  444     }
  445     B004_F(dev_min) |= B004_BUSY;
  446     B004_TIMEOUT(dev_min) = 0;
  447     DEB(printf( "B004 opened, minor = %d.\n", dev_min );)
  448     return 0;
  449 } /* bquopen() */
  450 
  451 
  452 /*
  453  * int b004close() -- close the link device.
  454  */
  455 
  456 static int
  457 bquclose(dev_t dev, int flags, int fmt, struct proc *p)
  458 {
  459     unsigned int dev_min = minor(dev) & 7;
  460 
  461     if (dev_min >= NBQU) {
  462         DEB(printf("B004 not released, minor number >= %d.\n", NBQU);)
  463         return ENXIO;
  464     }
  465     B004_F(dev_min) &= ~B004_BUSY;
  466     DEB(printf("B004(%d) released.\n", dev_min );)
  467     return 0;
  468 }
  469 
  470 static int
  471 bquselect(dev_t dev, int rw, struct proc *p)
  472 {
  473     /* still unimplemented */
  474     return(1);
  475 }
  476 
  477 /*
  478  * int bquioctl()
  479  *
  480  * Supported functions:
  481  * - reset
  482  * - analyse
  483  * - test error flag
  484  * - set timeout
  485  */
  486 
  487 static int
  488 bquioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
  489 {
  490     unsigned int dev_min = minor(dev) & 7;
  491     int result = 0;
  492 
  493     if (dev_min >= NBQU) {
  494         DEB(printf("B004 ioctl exit, minor >= %d.\n", NBQU );)
  495         return ENODEV;
  496     }
  497 
  498     if ((B004_F(dev_min) & B004_EXIST) == 0) {
  499         DEB(printf("B004 ioctl exit, (B004_F & B004_EXIST) == 0.\n" );)
  500         return ENODEV;
  501     }
  502 
  503     switch ( cmd ) {
  504         case B004RESET:         /* reset transputer */
  505             bqureset(dev_min);
  506         DEB(printf("B004 ioctl B004RESET, done\n" );)
  507             break;
  508         case B004WRITEABLE:     /* can we write a byte to the C012 ? */
  509             IOCTL_OUT (addr, ((in(B004_OSR(dev_min))&B004_WRITEBYTE) != 0 ));
  510             break;
  511         case B004READABLE:      /* can we read a byte from C012 ? */
  512             IOCTL_OUT (addr, ((in(B004_ISR(dev_min)) & B004_READBYTE) != 0 ));
  513             break;
  514         case B004ANALYSE:       /* switch transputer to analyse mode */
  515             bquanalyse(dev_min);
  516             break;
  517         case B004ERROR:         /* test error-flag */
  518             IOCTL_OUT (addr,
  519                 ((inb(B004_BASE(dev_min)+B004_ERROR_OFFSET) &
  520                 B004_TEST_ERROR) ? 0 : 1));
  521             break;
  522         case B004TIMEOUT:       /* set, retrieve timeout for writing & reading*/
  523             B004_TIMEOUT(dev_min) = *((int *)addr);
  524             break;
  525         default: result = EINVAL;
  526     }
  527     return result;
  528 } /* bquioctl() */
  529 
  530 
  531 static int
  532 bquattach(struct isa_device *idp)
  533 {
  534         int unit = idp->id_unit;
  535         struct b004_struct *bp;
  536         int     i;
  537 
  538 #ifdef DEVFS
  539 #define BQU_UID 66
  540 #define BQU_GID 66
  541 #define BQU_PERM 0600
  542         bp = &b004_table[unit];
  543         for ( i = 0; i < 8; i++) {
  544 #ifdef NOTYET
  545         /*      if (we've done all the ports found) break; */
  546 #endif
  547                 bp->devfs_token[i][0]=
  548                         devfs_add_devswf(&bqu_cdevsw, i, DV_CHR, BQU_UID, 
  549                                          BQU_GID, BQU_PERM, "ttyba%d", i);
  550                 bp->devfs_token[i][0]=
  551                         devfs_add_devswf(&bqu_cdevsw, i+64, DV_CHR, BQU_UID, 
  552                                          BQU_GID, BQU_PERM, "ttybb%d", i);
  553                 bp->devfs_token[i][0]=
  554                         devfs_add_devswf(&bqu_cdevsw, i+128, DV_CHR, BQU_UID, 
  555                                          BQU_GID, BQU_PERM, "ttybc%d", i);
  556                 bp->devfs_token[i][0]=
  557                         devfs_add_devswf(&bqu_cdevsw, i+192, DV_CHR, BQU_UID, 
  558                                          BQU_GID, BQU_PERM, "ttybd%d", unit);
  559         }
  560 #endif
  561         return 1;
  562 }
  563 
  564 /*
  565  * int bquprobe
  566  *
  567  * Initializes the driver. It tries to detect the hardware
  568  * and sets up all relevant data-structures.
  569  */
  570 
  571 static int
  572 bquprobe(struct isa_device *idp)
  573 {
  574     unsigned int test;
  575     unsigned int dev_min = idp->id_unit;
  576     int i,found = 0;
  577     /* After a reset it should be possible to write a byte to
  578        the B004. So let'S do a reset and then test the output status
  579        register
  580     */
  581 #ifdef undef
  582         printf(
  583           "bquprobe::\nIOBASE 0x%x\nIRQ %d\nDRQ %d\nMSIZE %d\nUNIT %d\nFLAGS"
  584           "x0%x\nALIVE %d\n",idp->id_iobase,idp->id_irq,
  585           idp->id_drq,idp->id_msize,idp->id_unit,idp->id_flags,idp->id_alive);
  586 #endif
  587     if(first_time){
  588         for(i=0;i<NBQU;i++) B004_F(i) &= ~B004_EXIST;
  589         first_time=0;
  590     }
  591 
  592     if(dev_min >= NBQU) return (0);     /* No more descriptors */
  593     if ((idp->id_iobase < 0x100) || (idp->id_iobase >= 0x1000))
  594         idp->id_iobase=0;               /* Dangerous isa addres ) */
  595 
  596     for (test = 0; (test < B004_CHANCE); test++) {
  597         if((idp->id_iobase==0)&&((!b004_base_addresses[test])||
  598            detected(b004_base_addresses[test])))
  599             continue;
  600         idp->id_iobase=b004_base_addresses[test];
  601 
  602         DEB(printf("Probing device %d at address 0x%x\n",dev_min,
  603                 idp->id_iobase);
  604         )
  605         b004_delay(test);
  606         B004_F(dev_min) = 0;
  607         B004_TIMEOUT(dev_min) = B004_INIT_TIMEOUT;
  608         B004_BASE(dev_min) = idp->id_iobase;
  609         B004_ODR(dev_min) = B004_BASE(dev_min) + B004_ODR_OFFSET;
  610         B004_ISR(dev_min) = B004_BASE(dev_min) + B004_ISR_OFFSET;
  611         B004_OSR(dev_min) = B004_BASE(dev_min) + B004_OSR_OFFSET;
  612         bqureset(dev_min);
  613 
  614         for (i = 0; i < B004_MAXTRY; i++)
  615             if ( in(B004_OSR(dev_min))  == B004_WRITEBYTE) {
  616                 B004_F(dev_min) |= B004_EXIST;
  617                 out(B004_BASE(dev_min) + B008_INT_OFFSET, 0);
  618                 b004_delay(test);
  619                 if (in(B004_BASE(dev_min) + B008_INT_OFFSET) & 0x0f == 0)
  620                     B004_BOARDTYPE(dev_min) = B008;
  621                 else
  622                     B004_BOARDTYPE(dev_min) = B004;
  623                 printf("bqu%d at 0x0%x (polling) is a B00%s\n",
  624                     dev_min,B004_IDR(dev_min),
  625                     (B004_BOARDTYPE(dev_min) == B004) ? "4" : "8");
  626                 found = 1;
  627                 break;
  628             }
  629         if(!found) {
  630             idp->id_iobase=0;
  631         }
  632         else break;
  633 
  634     }
  635 
  636     if (!found){
  637         DEB(printf("b004probe(): no B004-board found.\n"));
  638         return (0);
  639     }
  640 
  641     idp->id_maddr=NULL;
  642     idp->id_irq=0;
  643     if(B004_BOARDTYPE(dev_min) == B004)
  644         return(18);
  645     else
  646         return(20);
  647 } /* bquprobe() */
  648 
  649 
  650 static bqu_devsw_installed = 0;
  651 
  652 static void
  653 bqu_drvinit(void *unused)
  654 {
  655         dev_t dev;
  656 
  657         if( ! bqu_devsw_installed ) {
  658                 dev = makedev(CDEV_MAJOR, 0);
  659                 cdevsw_add(&dev,&bqu_cdevsw, NULL);
  660                 bqu_devsw_installed = 1;
  661         }
  662 }
  663 
  664 SYSINIT(bqudev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bqu_drvinit,NULL)
  665 
  666 
  667 #endif /* NBQU */

Cache object: d0aaad90d48808f0d68d82dafa356c15


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.