Pre 3.0 branch cleanup casualty #2: Transputer support
This commit is contained in:
parent
65d9f1deb2
commit
36b2d2c26c
@ -2,7 +2,7 @@
|
||||
# LINT -- config file for checking all the sources, tries to pull in
|
||||
# as much of the source tree as it can.
|
||||
#
|
||||
# $Id: LINT,v 1.511 1998/12/22 20:44:13 luigi Exp $
|
||||
# $Id: LINT,v 1.512 1998/12/27 12:35:35 phk Exp $
|
||||
#
|
||||
# NB: You probably don't want to try running a kernel built from this
|
||||
# file. Instead, you should start from GENERIC, and add options from
|
||||
@ -1386,7 +1386,6 @@ device rp0 at isa? port 0x280 tty
|
||||
device tw0 at isa? port 0x380 tty irq 11
|
||||
device si0 at isa? iomem 0xd0000 tty irq 12
|
||||
device asc0 at isa? port "IO_ASC1" tty drq 3 irq 10
|
||||
device bqu0 at isa? port 0x150
|
||||
device stl0 at isa? port 0x2a0 tty irq 10
|
||||
device stli0 at isa? port 0x2a0 tty iomem 0xcc000 flags 23 iosiz 0x1000
|
||||
# You are unlikely to have the hardware for loran0 <phk@FreeBSD.org>
|
||||
|
@ -1,7 +1,7 @@
|
||||
# This file tells config what files go into building a kernel,
|
||||
# files marked standard are always included.
|
||||
#
|
||||
# $Id: files.i386,v 1.206 1998/10/09 23:08:14 peter Exp $
|
||||
# $Id: files.i386,v 1.207 1998/12/21 18:04:20 joerg Exp $
|
||||
#
|
||||
# The long compile-with and dependency lines are required because of
|
||||
# limitations in config: backslash-newline doesn't work in strings, and
|
||||
@ -98,7 +98,6 @@ i386/isa/aha_isa.c optional aha device-driver
|
||||
#i386/isa/aic6360.c optional aic device-driver
|
||||
i386/isa/aic_isa.c optional aic device-driver
|
||||
i386/isa/alog.c optional alog device-driver
|
||||
i386/isa/b004.c optional bqu device-driver
|
||||
i386/isa/bt_isa.c optional bt device-driver
|
||||
i386/isa/clock.c standard
|
||||
i386/isa/cronyx.c optional cx device-driver
|
||||
|
@ -2,7 +2,7 @@
|
||||
# LINT -- config file for checking all the sources, tries to pull in
|
||||
# as much of the source tree as it can.
|
||||
#
|
||||
# $Id: LINT,v 1.511 1998/12/22 20:44:13 luigi Exp $
|
||||
# $Id: LINT,v 1.512 1998/12/27 12:35:35 phk Exp $
|
||||
#
|
||||
# NB: You probably don't want to try running a kernel built from this
|
||||
# file. Instead, you should start from GENERIC, and add options from
|
||||
@ -1386,7 +1386,6 @@ device rp0 at isa? port 0x280 tty
|
||||
device tw0 at isa? port 0x380 tty irq 11
|
||||
device si0 at isa? iomem 0xd0000 tty irq 12
|
||||
device asc0 at isa? port "IO_ASC1" tty drq 3 irq 10
|
||||
device bqu0 at isa? port 0x150
|
||||
device stl0 at isa? port 0x2a0 tty irq 10
|
||||
device stli0 at isa? port 0x2a0 tty iomem 0xcc000 flags 23 iosiz 0x1000
|
||||
# You are unlikely to have the hardware for loran0 <phk@FreeBSD.org>
|
||||
|
@ -2,7 +2,7 @@
|
||||
# LINT -- config file for checking all the sources, tries to pull in
|
||||
# as much of the source tree as it can.
|
||||
#
|
||||
# $Id: LINT,v 1.511 1998/12/22 20:44:13 luigi Exp $
|
||||
# $Id: LINT,v 1.512 1998/12/27 12:35:35 phk Exp $
|
||||
#
|
||||
# NB: You probably don't want to try running a kernel built from this
|
||||
# file. Instead, you should start from GENERIC, and add options from
|
||||
@ -1386,7 +1386,6 @@ device rp0 at isa? port 0x280 tty
|
||||
device tw0 at isa? port 0x380 tty irq 11
|
||||
device si0 at isa? iomem 0xd0000 tty irq 12
|
||||
device asc0 at isa? port "IO_ASC1" tty drq 3 irq 10
|
||||
device bqu0 at isa? port 0x150
|
||||
device stl0 at isa? port 0x2a0 tty irq 10
|
||||
device stli0 at isa? port 0x2a0 tty iomem 0xcc000 flags 23 iosiz 0x1000
|
||||
# You are unlikely to have the hardware for loran0 <phk@FreeBSD.org>
|
||||
|
@ -1,7 +1,7 @@
|
||||
# This file tells config what files go into building a kernel,
|
||||
# files marked standard are always included.
|
||||
#
|
||||
# $Id: files.i386,v 1.206 1998/10/09 23:08:14 peter Exp $
|
||||
# $Id: files.i386,v 1.207 1998/12/21 18:04:20 joerg Exp $
|
||||
#
|
||||
# The long compile-with and dependency lines are required because of
|
||||
# limitations in config: backslash-newline doesn't work in strings, and
|
||||
@ -98,7 +98,6 @@ i386/isa/aha_isa.c optional aha device-driver
|
||||
#i386/isa/aic6360.c optional aic device-driver
|
||||
i386/isa/aic_isa.c optional aic device-driver
|
||||
i386/isa/alog.c optional alog device-driver
|
||||
i386/isa/b004.c optional bqu device-driver
|
||||
i386/isa/bt_isa.c optional bt device-driver
|
||||
i386/isa/clock.c standard
|
||||
i386/isa/cronyx.c optional cx device-driver
|
||||
|
@ -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 */
|
@ -1,154 +0,0 @@
|
||||
/*
|
||||
* b004.h
|
||||
*
|
||||
* Based on the Linux driver, by
|
||||
* Christoph Niemann (niemann@swt.ruhr-uni-bochum.de)
|
||||
*
|
||||
* Ported to FreeBSD by Luigi Rizzo (luigi@iet.unipi.it)
|
||||
* and Lorenzo Vicisano (l.vicisano@iet.unipi.it)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Works for FreeBSD 1.1.5
|
||||
*/
|
||||
|
||||
#ifndef _I386_ISA_B004_H_
|
||||
#define _I386_ISA_B004_H_
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
/*
|
||||
* device status FLAGS
|
||||
*/
|
||||
#define B004_EXIST 0x0001 /* Is a B004-Board with at least one
|
||||
Transputer present ? */
|
||||
#define B004_BUSY 0x0002 /* Is the B004-board in use ? */
|
||||
|
||||
/*
|
||||
* IOCTL numbers
|
||||
*/
|
||||
#define B004RESET _IO ('Q', 0)
|
||||
/* Reset transputer(s) */
|
||||
#define B004WRITEABLE _IOR ('Q', 1, int)
|
||||
/* Return C012 Output Ready */
|
||||
#define B004READABLE _IOR ('Q', 2, int)
|
||||
/* Return C012 Data Present */
|
||||
#define B004ANALYSE _IO ('Q', 3)
|
||||
/* Switch transputer(s) to ANALYSE mode */
|
||||
#define B004ERROR _IOR ('Q', 4, int)
|
||||
/* Return 1 on ERROR set */
|
||||
#define B004TIMEOUT _IOW ('Q', 5, int)
|
||||
/* Set TIMEOUT for subsequent writing or
|
||||
reading call, value in ticks, initial
|
||||
0 = no timeout (read/write blocking)
|
||||
"open" sets timeout to 0 */
|
||||
|
||||
|
||||
#define B004_INIT_TIMEOUT 0 /* No timeout yet */
|
||||
|
||||
/*
|
||||
* Registers DISPLACEMENT
|
||||
*/
|
||||
#define B004_IDR_OFFSET 0 /* Input Data Register */
|
||||
#define B004_ODR_OFFSET 1 /* Output Data Register */
|
||||
#define B004_ISR_OFFSET 2 /* Input Status Register */
|
||||
#define B004_OSR_OFFSET 3 /* Output Status Register */
|
||||
#define B004_RESET_OFFSET 16 /* Reset/Error Register */
|
||||
#define B004_ERROR_OFFSET B004_RESET_OFFSET
|
||||
#define B004_ANALYSE_OFFSET 17 /* Analyse Register */
|
||||
#define B008_DMA_OFFSET 18 /* B008: DMA request register */
|
||||
#define B008_INT_OFFSET 19 /* B008: Interrupt control reg */
|
||||
|
||||
struct b004_struct {
|
||||
int flags; /* various flags */
|
||||
int idr; /* address of the input data register */
|
||||
int odr; /* address if the output data register */
|
||||
int isr; /* address of the input status register */
|
||||
int osr; /* address of the output status register */
|
||||
unsigned int timeout; /* timeout for writing/reading the link */
|
||||
int boardtype; /* what kind of board is installed */
|
||||
void *devfs_token[8][4]; /* tokens for 4 types for 8 ports */
|
||||
};
|
||||
|
||||
/*
|
||||
* Id's for the supported boards
|
||||
*/
|
||||
#define B004 1
|
||||
#define B008 2
|
||||
|
||||
/*
|
||||
* Defines for easier access to the b004_table.
|
||||
*/
|
||||
#define B004_F(minor) b004_table[minor].flags
|
||||
#define B004_TIMEOUT(minor) b004_table[minor].timeout
|
||||
#define B004_BASE(minor) B004_IDR(minor)
|
||||
#define B004_IDR(minor) b004_table[minor].idr
|
||||
#define B004_ODR(minor) b004_table[minor].odr
|
||||
#define B004_ISR(minor) b004_table[minor].isr
|
||||
#define B004_OSR(minor) b004_table[minor].osr
|
||||
#define B004_WAIT(minor) b004_table[minor].wait
|
||||
#define B004_BOARDTYPE(minor) b004_table[minor].boardtype
|
||||
|
||||
/*
|
||||
* Additional defines for B008-boards
|
||||
*/
|
||||
#define B008_DMA(minor) b004_table[minor].int
|
||||
#define B008_INT(minor) b004_table[minor].dma
|
||||
|
||||
/*
|
||||
* Number of tries to access isr or osr before reading or writing sleeps
|
||||
*/
|
||||
#define B004_MAXTRY 200
|
||||
|
||||
/*
|
||||
* Maximum number of bytes to transfer at once
|
||||
*/
|
||||
#define B004_MAX_BYTES 2048
|
||||
|
||||
/*
|
||||
* bit defines for C012 status ports at base + 2/3
|
||||
* accessed with B004_IS, B004_OS, which gets the byte...
|
||||
*/
|
||||
#define B004_READBYTE 1
|
||||
#define B004_WRITEBYTE 1
|
||||
|
||||
/*
|
||||
* bit defines for C012 reset/error port at base + 16
|
||||
*/
|
||||
#define B004_ASSERT_RESET 0x01 /* resetting the transputer */
|
||||
#define B004_DEASSERT_RESET 0x00
|
||||
#define B004_TEST_ERROR 0x01 /* for testing the transputer's error flag */
|
||||
|
||||
/*
|
||||
* bit defines for C012 analyse port at base + 17
|
||||
*/
|
||||
#define B004_ASSERT_ANALYSE 0x01 /* switch transputer to analyse-mode */
|
||||
#define B004_DEASSERT_ANALYSE 0x00
|
||||
|
||||
#endif /* !_I386_ISA_B004_H_ */
|
Loading…
Reference in New Issue
Block a user