summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/b004.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/isa/b004.c')
-rw-r--r--sys/i386/isa/b004.c669
1 files changed, 0 insertions, 669 deletions
diff --git a/sys/i386/isa/b004.c b/sys/i386/isa/b004.c
deleted file mode 100644
index 5a9357d..0000000
--- a/sys/i386/isa/b004.c
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- * FreeBSD device driver for B004-compatible Transputer boards.
- *
- * based on Linux version Copyright (C) 1993 by Christoph Niemann
- *
- * Rewritten for FreeBSD by
- * Luigi Rizzo (luigi@iet.unipi.it) and
- * Lorenzo Vicisano (l.vicisano@iet.unipi.it)
- * Dipartimento di Ingegneria dell'Informazione
- * Universita` di Pisa
- * via Diotisalvi 2, 56126 Pisa, ITALY
- * 14 september 1994
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Christoph Niemann,
- * Luigi Rizzo and Lorenzo Vicisano - Dipartimento di Ingegneria
- * dell'Informazione
- * 4. The names of these contributors may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * NOTE NOTE NOTE
- * The assembler version is still under development.
- */
-
-/* #define USE_ASM */
-
-#include "bqu.h"
-#if NBQU > 0
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/uio.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-
-#include "opt_devfs.h"
-
-#ifdef DEVFS
-#include <sys/devfsext.h>
-#endif /*DEVFS*/
-
-#include <machine/clock.h>
-
-#include <i386/isa/b004.h>
-#include <i386/isa/isa_device.h>
-
-#define IOCTL_OUT(arg, ret) *(int*)arg = ret
-
-#define B004PRI (PZERO+8)
-
-#define B004_CHANCE 8
-
-/*
- * Define these symbols if you want to debug the code.
- */
-#undef B004_DEBUG
-#undef B004_DEBUG_2
-
-#ifdef B004_DEBUG
-static u_char d_inb(u_int port);
-static void d_outb(u_int port, u_char data);
-
-#define out(port,data) d_outb(port, data)
-#define in(a) d_inb(((u_int)a))
-#else
-#define out(port, data) outb(port,data)
-#define in(port) inb(((u_int)port))
-#endif B004_DEBUG
-
-#ifdef B004_DEBUG
-#define DEB(x) x
-#define NO_DEB(x) /* */
-#else
-#define DEB(x) /* */
-#define NO_DEB(x) x
-#endif
-
-#ifdef B004_DEBUG_2
-#define DEB2(x) x
-#else
-#define DEB2(x)
-#endif
-
-static int bquprobe(struct isa_device *idp);
-static int bquattach(struct isa_device *idp);
-
-
-struct isa_driver bqudriver = {
- bquprobe, bquattach, "bqu"
-};
-
-static d_open_t bquopen;
-static d_close_t bquclose;
-static d_read_t bquread;
-static d_write_t bquwrite;
-static d_ioctl_t bquioctl;
-static d_poll_t bqupoll;
-
-#define CDEV_MAJOR 8
-static struct cdevsw bqu_cdevsw =
- { bquopen, bquclose, bquread, bquwrite, /*8*/
- bquioctl, nostop, nullreset, nodevtotty,/* tputer */
- bqupoll, nommap, NULL, "bqu", NULL, -1 };
-
-static int b004_sleep; /* wait address */
-
-static struct b004_struct b004_table[NBQU];
-
-static int first_time=1;
-
-/*
- * At these addresses the driver will search for B004-compatible boards
- */
-static int
-b004_base_addresses[B004_CHANCE] = {
- /* 0x150, 0x170, 0x190, 0x200, 0x300, 0x320, 0x340, 0x360 */
- 0x150, 0x190, 0, 0, 0, 0, 0, 0
-};
-
-#ifdef B004_DEBUG
-static void
-d_outb(u_int port, u_char data)
-{
-
- printf("OUT 0x%x TO 0x%x\n",data,port);
- outb(port,data);
-}
-
-static u_char
-d_inb(u_int port)
-{
-u_char ap;
- ap=inb(port);
- printf("INPUT 0x%x FROM 0x%x\n",ap,port);
- return(ap);
-}
-#endif
-
-static int
-detected(int base)
-{
- int i;
- for(i=0;i<NBQU;i++)
- if ((B004_F(i) & B004_EXIST) && (B004_BASE(i)==base)) return 1;
- return (0);
-}
-
-#define b004_delay(a) DELAY(10000)
-
-/*
- * static void bqureset(): reset transputer network.
- *
- */
-
-static void
-bqureset( const int dev_min )
-{
- DEB(printf("B004 resetting transputer at link %d.\n", dev_min);)
- out(B004_BASE(dev_min)+B004_ANALYSE_OFFSET, B004_DEASSERT_ANALYSE);
- b004_delay(dev_min);
-
- out(B004_BASE(dev_min) + B004_RESET_OFFSET, B004_DEASSERT_RESET);
- b004_delay(dev_min);
-
- out(B004_BASE(dev_min) + B004_RESET_OFFSET, B004_ASSERT_RESET);
- b004_delay(dev_min);
-
- out(B004_BASE(dev_min) + B004_RESET_OFFSET, B004_DEASSERT_RESET);
- b004_delay(dev_min);
-
- DEB(printf("B004 reset done.\n");)
-}
-
-/*
- * static void bquanalyse(): switch transputer network to analyse mode.
- *
- */
-
-static void
-bquanalyse( const int dev_min )
-{
- DEB(printf("B004 analysing transputer at link %d.\n", dev_min);)
-
- out(B004_BASE(dev_min) + B004_ANALYSE_OFFSET, B004_DEASSERT_ANALYSE);
- b004_delay(dev_min);
-
- out(B004_BASE(dev_min) + B004_ANALYSE_OFFSET, B004_ASSERT_ANALYSE);
- b004_delay(dev_min);
-
- out(B004_BASE(dev_min) + B004_RESET_OFFSET, B004_ASSERT_RESET);
- b004_delay(dev_min);
-
- out(B004_BASE(dev_min) + B004_RESET_OFFSET, B004_DEASSERT_RESET);
- b004_delay(dev_min);
-
- out(B004_BASE(dev_min) + B004_ANALYSE_OFFSET, B004_DEASSERT_ANALYSE);
- b004_delay(dev_min);
-
- DEB(printf("B004 switching to analyse-mode done.\n");)
-}
-
-
-/****************************************************************************
- *
- * int bquread() - read bytes from the link interface.
- *
- * At first, the driver checks if the link-interface is ready to send a byte
- * to the PC. If not, this check is repeated up to B004_MAXTRY times.
- * If the link-interface is not ready after this loop, the driver sleeps for
- * an NO=1 ticks and then checks the link-interface again.
- * If the interface is still not ready, repeats as above incrementing NO.
- * Once almost one byte is read N0 is set to 1.
- * If B004_TIMEOUT != 0 and the link-interface is not ready for more than
- * B004_TIMEOUT ticks read aborts returnig with the number of bytes read
- * or with an error if no byte was read.
- *
- * By default, B004_TIMEOUT is = 0 (read is blocking)
- *
- *****************************************************************************/
-
-static int
-bquread(dev_t dev, struct uio *uio, int flag)
-{
- unsigned int dev_min = minor(dev) & 7;
-
- int timeout=B004_TIMEOUT(dev_min);
- int Timeout=timeout;
- int idr=B004_IDR(dev_min);
- int isr=B004_ISR(dev_min);
- char buffer[B004_MAX_BYTES];
-
- if ( uio->uio_resid < 0) {
- DEB(printf("B004: invalid count for reading = %d.\n", uio->uio_resid);)
- return EINVAL;
- }
-
- while ( uio->uio_resid ) {
- int sleep_ticks=0;
- char *p, *last, *lim;
- int i, end = min(B004_MAX_BYTES,uio->uio_resid);
- lim= &buffer[end];
- for (p= buffer; p<lim;) {
- last=p;
- /*** try to read as much as possible ***/
-#ifdef USE_ASM
- /* assembly code uses a very tight loop, with
- * BX= data port, DX= address port, CX=count, ES:DI=p, AL=data, AH=1
- * SI=retry counter
- */
- __asm__ (
- "movl %1, %%edx\n\t" /* isr */
- "movl %2, %%ebx\n\t" /* idr */
- "movl %3, %%edi\n" /* p */
- "movl %4, %%ecx\n\t" /* lim */
- "subl %%edi, %%ecx\n\t"
-
- "push %%es\n\t"
- "movw %%ss, %%ax\n\t" /** prepare ES, DF for transfer */
- "movw %%ax, %%es\n\t"
- "cld\n\t"
- "movb $1, %%ah\n\t"
-
- "1:\tinb %%dx, %%al\n\t"
- "testb %%ah, %%al\n\t"
- "jz 2f\n\t"
- "xchgl %%edx, %%ebx\n\t"
- "insb\n\t"
- "xchgl %%edx, %%ebx\n"
- "2:\tloop 1b\n\t"
-
- "pop %%es\n\t"
- "movl %%edi, %0\n\t" /* store p */
- : /* out */ "=g" (p)
- : /* in */ "g" (isr), "g" (idr), "g" (p), "g" (lim)
- : /* regs */ "eax", "ebx", "edx", "ecx", "edi");
-#else
- for (i=lim - p; i-- ;)
- if (inb(isr)&B004_READBYTE) *p++ =(char) inb(idr);
-#endif
- if (last!=p) {
- sleep_ticks = 0;
- } else {
- /*** no new data read, must sleep ***/
- sleep_ticks= (sleep_ticks<20 ? sleep_ticks+1 : sleep_ticks);
- if (Timeout) {
- if (timeout <=0) {
- DEB2(printf("Read : TIMEOUT OCCURRED XXXXXXXXXXX\n");)
- break;
- }
- if (timeout < sleep_ticks) sleep_ticks=timeout;
- timeout -= sleep_ticks;
- }
- DEB2(printf("Read: SLEEPING FOR %d TICKS XXXXX\n",sleep_ticks);)
- if (tsleep((caddr_t)&b004_sleep, B004PRI | PCATCH,
- "b004_rd", sleep_ticks)!=EWOULDBLOCK) return 1;
- }
- }
- if (p != buffer) {
- uiomove((caddr_t)buffer, p - buffer, uio);
- }
- if( (Timeout) && (timeout <= 0) )
- break;
- }
- return 0;
-} /* bquread() */
-
-
-/*
- * int bquwrite() - write to the link interface.
- */
-
-static int
-bquwrite(dev_t dev, struct uio *uio, int flag)
-{
- unsigned int dev_min = minor(dev) & 7;
-
- int i, end;
- int timeout=B004_TIMEOUT(dev_min);
- int Timeout=timeout;
- int odr=B004_ODR(dev_min);
- int osr=B004_OSR(dev_min);
- char buffer[B004_MAX_BYTES];
-
- if ( uio->uio_resid < 0) {
- DEB(printf("B004 invalid argument for writing: count = %d.\n", uio->uio_resid);)
- return EINVAL;
- }
-
- while ( uio->uio_resid ) {
- int sleep_ticks=0;
- char *p, *last, *lim;
- end = min(B004_MAX_BYTES,uio->uio_resid);
- uiomove((caddr_t)buffer, end, uio);
-
- lim= &buffer[end];
- for (p= &buffer[0]; p<lim;) {
- last=p;
-#ifdef USE_ASM
- /* assembly code uses a very tight loop, with
- * BX= data port, DX= address port, CX=count, DS:SI=p, AL=data, AH=1
- * DI= retry counter
- * Unfortunately, C is almost as fast as this!
- */
- __asm__ (
- "movl %1, %%edx\n\t" /* osr */
- "movl %2, %%ebx\n\t" /* odr */
- "movl %3, %%esi\n" /* p */
- "movl %4, %%ecx\n\t" /* lim */
- "subl %%esi, %%ecx\n\t"
-
- "push %%ds\n\t"
- "movw %%ss, %%ax\n\t" /** prepare DS, DF for transfer */
- "movw %%ax, %%ds\n\t"
- "cld\n\t"
- "movb $1, %%ah\n\t"
- "movw $100, %%di\n\t"
-
- "1:\tinb %%dx, %%al\n\t"
- "testb %%ah, %%al\n\t"
- "jz 2f\n\t"
- "xchgl %%edx, %%ebx\n\t"
- "outsb\n\t"
- "xchgl %%edx, %%ebx\n\t"
- "loop 1b\n\t"
- "jmp 3f\n"
-
- "2:\tdec %%di\n\t"
- "jnc 1b\n\t"
-
- "3:\tpop %%ds\n"
- "movl %%esi, %0\n\t" /* store p */
- : /* out */ "=g" (p)
- : /* in */ "g" (osr), "g" (odr), "g" (p), "g" (lim)
- : /* regs */ "eax", "ebx", "edx", "ecx", "esi", "edi");
-#else
- for (i=lim - p; i-- ; ) {
- if (inb(osr)&B004_WRITEBYTE) outb(odr, *p++);
- }
-#endif
- if (p != last ) {
- sleep_ticks=0;
- } else {
- sleep_ticks= (sleep_ticks<20 ? sleep_ticks+1 : sleep_ticks);
- if (Timeout) {
- if (timeout <=0) {
- DEB2(printf("Write : TIMEOUT OCCURRED XXXXXXXXXXX\n");)
- uio->uio_resid += (lim - p);
- break;
- }
- if (timeout < sleep_ticks) sleep_ticks=timeout;
- timeout -= sleep_ticks;
- }
- DEB2(printf("Write: SLEEPING FOR %d TICKS XXXXXXX\n",sleep_ticks);)
- if (tsleep((caddr_t)&b004_sleep, B004PRI | PCATCH,
- "b004_rd", sleep_ticks)!=EWOULDBLOCK) return 1;
- }
- }
- if( (Timeout) && (timeout <= 0) )
- break;
- }
- return 0;
-} /* bquwrite() */
-
-/*
- * int bquopen() -- open the link-device.
- *
- */
-
-static int
-bquopen(dev_t dev, int flags, int fmt, struct proc *p)
-{
- unsigned int dev_min = minor(dev) & 7;
-
- if (dev_min >= NBQU) {
- DEB(printf("B004 not opened, minor number >= %d.\n", NBQU);)
- return ENXIO;
- }
- if ((B004_F(dev_min) & B004_EXIST) == 0) {
- DEB(printf("B004 not opened, board %d does not exist.\n", dev_min);)
- return ENXIO;
- }
- if (B004_F(dev_min) & B004_BUSY) {
- DEB(printf("B004 not opened, board busy (minor = %d).\n", dev_min);)
- return EBUSY;
- }
- B004_F(dev_min) |= B004_BUSY;
- B004_TIMEOUT(dev_min) = 0;
- DEB(printf( "B004 opened, minor = %d.\n", dev_min );)
- return 0;
-} /* bquopen() */
-
-
-/*
- * int b004close() -- close the link device.
- */
-
-static int
-bquclose(dev_t dev, int flags, int fmt, struct proc *p)
-{
- unsigned int dev_min = minor(dev) & 7;
-
- if (dev_min >= NBQU) {
- DEB(printf("B004 not released, minor number >= %d.\n", NBQU);)
- return ENXIO;
- }
- B004_F(dev_min) &= ~B004_BUSY;
- DEB(printf("B004(%d) released.\n", dev_min );)
- return 0;
-}
-
-static int
-bqupoll(dev_t dev, int events, struct proc *p)
-{
- /* still unimplemented */
- return(seltrue(dev, events, p));
-}
-
-/*
- * int bquioctl()
- *
- * Supported functions:
- * - reset
- * - analyse
- * - test error flag
- * - set timeout
- */
-
-static int
-bquioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
-{
- unsigned int dev_min = minor(dev) & 7;
- int result = 0;
-
- if (dev_min >= NBQU) {
- DEB(printf("B004 ioctl exit, minor >= %d.\n", NBQU );)
- return ENODEV;
- }
-
- if ((B004_F(dev_min) & B004_EXIST) == 0) {
- DEB(printf("B004 ioctl exit, (B004_F & B004_EXIST) == 0.\n" );)
- return ENODEV;
- }
-
- switch ( cmd ) {
- case B004RESET: /* reset transputer */
- bqureset(dev_min);
- DEB(printf("B004 ioctl B004RESET, done\n" );)
- break;
- case B004WRITEABLE: /* can we write a byte to the C012 ? */
- IOCTL_OUT (addr, ((in(B004_OSR(dev_min))&B004_WRITEBYTE) != 0 ));
- break;
- case B004READABLE: /* can we read a byte from C012 ? */
- IOCTL_OUT (addr, ((in(B004_ISR(dev_min)) & B004_READBYTE) != 0 ));
- break;
- case B004ANALYSE: /* switch transputer to analyse mode */
- bquanalyse(dev_min);
- break;
- case B004ERROR: /* test error-flag */
- IOCTL_OUT (addr,
- ((inb(B004_BASE(dev_min)+B004_ERROR_OFFSET) &
- B004_TEST_ERROR) ? 0 : 1));
- break;
- case B004TIMEOUT: /* set, retrieve timeout for writing & reading*/
- B004_TIMEOUT(dev_min) = *((int *)addr);
- break;
- default: result = EINVAL;
- }
- return result;
-} /* bquioctl() */
-
-
-static int
-bquattach(struct isa_device *idp)
-{
- int unit = idp->id_unit;
- struct b004_struct *bp;
- int i;
-
-#ifdef DEVFS
-#define BQU_UID 66
-#define BQU_GID 66
-#define BQU_PERM 0600
- bp = &b004_table[unit];
- for ( i = 0; i < 8; i++) {
-#ifdef NOTYET
- /* if (we've done all the ports found) break; */
-#endif
- bp->devfs_token[i][0]=
- devfs_add_devswf(&bqu_cdevsw, i, DV_CHR, BQU_UID,
- BQU_GID, BQU_PERM, "ttyba%d", i);
- bp->devfs_token[i][0]=
- devfs_add_devswf(&bqu_cdevsw, i+64, DV_CHR, BQU_UID,
- BQU_GID, BQU_PERM, "ttybb%d", i);
- bp->devfs_token[i][0]=
- devfs_add_devswf(&bqu_cdevsw, i+128, DV_CHR, BQU_UID,
- BQU_GID, BQU_PERM, "ttybc%d", i);
- bp->devfs_token[i][0]=
- devfs_add_devswf(&bqu_cdevsw, i+192, DV_CHR, BQU_UID,
- BQU_GID, BQU_PERM, "ttybd%d", unit);
- }
-#endif
- return 1;
-}
-
-/*
- * int bquprobe
- *
- * Initializes the driver. It tries to detect the hardware
- * and sets up all relevant data-structures.
- */
-
-static int
-bquprobe(struct isa_device *idp)
-{
- unsigned int test;
- unsigned int dev_min = idp->id_unit;
- int i,found = 0;
- /* After a reset it should be possible to write a byte to
- the B004. So let'S do a reset and then test the output status
- register
- */
-#ifdef undef
- printf(
- "bquprobe::\nIOBASE 0x%x\nIRQ %d\nDRQ %d\nMSIZE %d\nUNIT %d\nFLAGS"
- "x0%x\nALIVE %d\n",idp->id_iobase,idp->id_irq,
- idp->id_drq,idp->id_msize,idp->id_unit,idp->id_flags,idp->id_alive);
-#endif
- if(first_time){
- for(i=0;i<NBQU;i++) B004_F(i) &= ~B004_EXIST;
- first_time=0;
- }
-
- if(dev_min >= NBQU) return (0); /* No more descriptors */
- if ((idp->id_iobase < 0x100) || (idp->id_iobase >= 0x1000))
- idp->id_iobase=0; /* Dangerous isa addres ) */
-
- for (test = 0; (test < B004_CHANCE); test++) {
- if((idp->id_iobase==0)&&((!b004_base_addresses[test])||
- detected(b004_base_addresses[test])))
- continue;
- idp->id_iobase=b004_base_addresses[test];
-
- DEB(printf("Probing device %d at address 0x%x\n",dev_min,
- idp->id_iobase);
- )
- b004_delay(test);
- B004_F(dev_min) = 0;
- B004_TIMEOUT(dev_min) = B004_INIT_TIMEOUT;
- B004_BASE(dev_min) = idp->id_iobase;
- B004_ODR(dev_min) = B004_BASE(dev_min) + B004_ODR_OFFSET;
- B004_ISR(dev_min) = B004_BASE(dev_min) + B004_ISR_OFFSET;
- B004_OSR(dev_min) = B004_BASE(dev_min) + B004_OSR_OFFSET;
- bqureset(dev_min);
-
- for (i = 0; i < B004_MAXTRY; i++)
- if ( in(B004_OSR(dev_min)) == B004_WRITEBYTE) {
- B004_F(dev_min) |= B004_EXIST;
- out(B004_BASE(dev_min) + B008_INT_OFFSET, 0);
- b004_delay(test);
- if (in(B004_BASE(dev_min) + B008_INT_OFFSET) & 0x0f == 0)
- B004_BOARDTYPE(dev_min) = B008;
- else
- B004_BOARDTYPE(dev_min) = B004;
- printf("bqu%d at 0x0%x (polling) is a B00%s\n",
- dev_min,B004_IDR(dev_min),
- (B004_BOARDTYPE(dev_min) == B004) ? "4" : "8");
- found = 1;
- break;
- }
- if(!found) {
- idp->id_iobase=0;
- }
- else break;
-
- }
-
- if (!found){
- DEB(printf("b004probe(): no B004-board found.\n"));
- return (0);
- }
-
- idp->id_maddr=NULL;
- idp->id_irq=0;
- if(B004_BOARDTYPE(dev_min) == B004)
- return(18);
- else
- return(20);
-} /* bquprobe() */
-
-
-static bqu_devsw_installed = 0;
-
-static void
-bqu_drvinit(void *unused)
-{
- dev_t dev;
-
- if( ! bqu_devsw_installed ) {
- dev = makedev(CDEV_MAJOR, 0);
- cdevsw_add(&dev,&bqu_cdevsw, NULL);
- bqu_devsw_installed = 1;
- }
-}
-
-SYSINIT(bqudev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bqu_drvinit,NULL)
-
-
-#endif /* NBQU */
OpenPOWER on IntegriCloud