summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pccard
diff options
context:
space:
mode:
authornate <nate@FreeBSD.org>1996-04-09 23:29:07 +0000
committernate <nate@FreeBSD.org>1996-04-09 23:29:07 +0000
commit3e7be51ef5f0abc33bc64ea415519727d035a98a (patch)
treebf6009189a979be421afafcbd9771b8c74c193c2 /usr.sbin/pccard
parent35083944793f0f487353b293d1994f42e8f5550d (diff)
downloadFreeBSD-src-3e7be51ef5f0abc33bc64ea415519727d035a98a.zip
FreeBSD-src-3e7be51ef5f0abc33bc64ea415519727d035a98a.tar.gz
Removed original distribution files that are no longer valid.
Diffstat (limited to 'usr.sbin/pccard')
-rw-r--r--usr.sbin/pccard/misc/COPYRIGHT11
-rw-r--r--usr.sbin/pccard/misc/FILES12
-rw-r--r--usr.sbin/pccard/misc/INSTALL34
-rw-r--r--usr.sbin/pccard/misc/Makefile32
-rw-r--r--usr.sbin/pccard/misc/README.old62
-rw-r--r--usr.sbin/pccard/misc/rpti.c113
-rw-r--r--usr.sbin/pccard/misc/skeldrv.c37
-rw-r--r--usr.sbin/pccard/misc/sys/i386/conf/LAPTOP63
-rw-r--r--usr.sbin/pccard/misc/sys/pccard/Makefile25
-rw-r--r--usr.sbin/pccard/misc/sys/pccard/README13
-rw-r--r--usr.sbin/pccard/misc/sys/pccard/bpfilter.h1
-rw-r--r--usr.sbin/pccard/misc/sys/pccard/ed.h1
-rw-r--r--usr.sbin/pccard/misc/sys/pccard/if_ed.c1997
-rw-r--r--usr.sbin/pccard/misc/sys/pccard/if_edreg.h989
-rw-r--r--usr.sbin/pccard/misc/sys/pccard/lkm_ed.c143
-rw-r--r--usr.sbin/pccard/misc/sys/pccard/sio.c2463
16 files changed, 0 insertions, 5996 deletions
diff --git a/usr.sbin/pccard/misc/COPYRIGHT b/usr.sbin/pccard/misc/COPYRIGHT
deleted file mode 100644
index 4f8c550..0000000
--- a/usr.sbin/pccard/misc/COPYRIGHT
+++ /dev/null
@@ -1,11 +0,0 @@
-Original work is copyright (C) Andrew McRae 1994,1995
-Permission is granted to freely copy as long as
-all attribution remains and copyright notices are
-included, and source made available upon request.
-
-Parts of this distribution is derived from work
-by Barry Jaspan and Keith Moore.
-
-DISCLAIMER:
-There is no warranty for this software.
-All responsibility is your own.
diff --git a/usr.sbin/pccard/misc/FILES b/usr.sbin/pccard/misc/FILES
deleted file mode 100644
index dcb097a..0000000
--- a/usr.sbin/pccard/misc/FILES
+++ /dev/null
@@ -1,12 +0,0 @@
-The files are:
-
- enabler Sample enabler for connecting drivers
- dumpcis Reads and dumps CIS of card.
- pccardmem Sets a memory area for use by the driver
- rdmap Dumps the current memory and I/O card contexts
- rdreg reads a PCIC register
- wrreg Writes a PCIC register
- wrattr Writes a byte into the card's attribute area.
-
-The cardd stuff has been updated for the new interfaces, but
-hasn't been tested to any real extent.
diff --git a/usr.sbin/pccard/misc/INSTALL b/usr.sbin/pccard/misc/INSTALL
deleted file mode 100644
index c9f3659..0000000
--- a/usr.sbin/pccard/misc/INSTALL
+++ /dev/null
@@ -1,34 +0,0 @@
-INSTALLATION
-------------
-
-1. Copy the source files from the sys directory into your
- /sys (or where-ever) tree. There are a number of .diff files
- that can be used to modify the following files:
- sys/conf/files
- sys/i386/i386/autoconf.c
- sys/i386/i386/conf.c
- There is also a sys/pccard directory that should reside in
- /sys/pccard
-
-2. Make a symbolic link like:
- ln -s /sys/pccard /usr/include/pccard
-
-3. Add a line in the kernel config file:
-
- controller crd0
-
- and rebuild the kernel. Optionally, the PCIC slot driver can
- and also built into the kernel by adding the line:
-
- device pcic0
-
-4. Create a device for each slot e.g.
-
- foreach i (0 1)
- mknod /dev/card$i c 50 $i
- end
-
-5. You can use lkm to load the PCIC controller. It can
- be unloaded at will. Once loaded, you should assign
- some memory via pccardmem for use with read/write.
- Normally cardd does this, but I haven't quite finished yet.
diff --git a/usr.sbin/pccard/misc/Makefile b/usr.sbin/pccard/misc/Makefile
deleted file mode 100644
index 37d953b..0000000
--- a/usr.sbin/pccard/misc/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Makefile for PCMCIA card programs.
-#
-CFLAGS = -m486 -g # -DDEBUG
-
-PROGS = dumpcis rdmap rdreg wrreg pccardmem wrattr enabler
-
-all: $(PROGS)
-
-clean:
- rm -f *.core core *.o $(PROGS)
-
-dumpcis: dumpcis.o readcis.o printcis.o
- cc -o dumpcis -static dumpcis.o readcis.o printcis.o
-
-wrattr: wrattr.c
- cc $(CFLAGS) -o wrattr wrattr.c
-
-pccardmem: pccardmem.c
- cc $(CFLAGS) -o pccardmem pccardmem.c
-
-enabler: enabler.c
- cc $(CFLAGS) -o enabler enabler.c
-
-rdmap: rdmap.c
- cc $(CFLAGS) -o rdmap rdmap.c
-
-rdreg: rdreg.c
- cc $(CFLAGS) -o rdreg rdreg.c
-
-wrreg: wrreg.c
- cc $(CFLAGS) -o wrreg wrreg.c
diff --git a/usr.sbin/pccard/misc/README.old b/usr.sbin/pccard/misc/README.old
deleted file mode 100644
index 76e005a..0000000
--- a/usr.sbin/pccard/misc/README.old
+++ /dev/null
@@ -1,62 +0,0 @@
-PCMCIA Support for FreeBSD 2.0
-------------------------------
-
-This package contains the following:
-
- - Driver for Intel 83265 PCIC PCMCIA controller
- - A PCMCIA daemon for managing card insertions/removals
- - Diffs to various source files for adding PCMCIA support
- - A sample config file
- - Some utility programs for reading card data tuples
- - Some documentation.
-
-What it doesn't include is:
-
- - Configuration for brand XYZ PCMCIA cards
- - Drivers for brand XYZ PCMCIA cards
- - Diffs to modify standard drivers to handle card events
-
-Essentially, this package contains everything required to
-add PCMCIA support to FreeBSD 2.0. It does this via a
-daemon that manages the PCMCIA slots via a PCIC driver. A configuration
-file provides the daemon with the information required to setup
-the specific cards, and to manage card insertion and removal.
-
-This package has been tested on a NEC Versa Laptop.
-The first version was developed on FreeBSD 1.1.5.1.
-
-The main idea behind the package is for pcmciad to detect
-inserted cards and match to a card ID in the config file,
-then set up the I/O ports and memory window to the card
-according to the data for the driver associated with the
-card, then attach the kernel driver to the device. Shell
-commands can be executed for both insertion and removal of cards,
-and different commands can be executed for different cards,
-drivers and devices.
-
-Different kernel drivers may have to have some mods
-done to recognise the card once installed; I have included
-some diffs to `ed' that allows recognition of a `generic'
-NS8390 card.
-
-Some minor changes were made to ifconfig(8) to allow a
-different ethernet address to be assigned to a network
-interface, since each card may have different locations
-the ethernet address is stored in.
-
-This is a snapshot of a release for FreeBSD 2.0. It is
-basically the 1.1.5.1 release ported for 2.0. I have only
-just received a developer's guide for PCMCIA, so I should
-have some more stable support soon.
-
-For instructions on installation, see INSTALL.
-There is a man entry on the daemon (pcmciad.8),
-and the config file (pcmcia.conf.5).
-
-Please send mail with any bugs or new card descriptions.
-
-Enjoy!
-Andrew McRae inet: andrew@mega.com.au
-MITS Real Time Ltd, uucp: ..!uunet!mega.com.au!andrew
-North Ryde 2113 Phone: +61 2 805 0899
-NSW AUSTRALIA Fax: +61 2 887 4847
diff --git a/usr.sbin/pccard/misc/rpti.c b/usr.sbin/pccard/misc/rpti.c
deleted file mode 100644
index d97c490..0000000
--- a/usr.sbin/pccard/misc/rpti.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Enabler for PCCARD. Used for testing drivers etc.
- * Options:
- * enabler slot driver [ -m card addr size ] [ -i iobase ] [ -q irq ]
- */
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-
-#include <pccard/card.h>
-#include <pccard/cis.h>
-
-void usage();
-
-
-main(argc, argv)
-int argc;
-char *argv[];
-{
-struct drv_desc drv;
-struct mem_desc mem;
-struct io_desc io;
-int fd, err, slot, i, card_addr;
-char name[32], cmd[256];
-char *p;
-
- if (argc == 2)
- slot = atoi(argv[1]);
- else
- slot = 0;
- if (slot < 0 || slot >= MAXSLOT)
- usage("Illegal slot number");
- sprintf(cmd, "util/wrattr %d 100 80", slot);
- printf("%s\n", cmd);
- system(cmd);
- usleep(200*1000);
- sprintf(cmd, "util/wrattr %d 100 0", slot);
- printf("%s\n", cmd);
- system(cmd);
- usleep(200*1000);
- sprintf(cmd, "util/wrattr %d 100 30", slot);
- printf("%s\n", cmd);
- system(cmd);
- usleep(200*1000);
- bzero(&drv, sizeof(drv));
- drv.unit = 0;
- strcpy(drv.name, "ed");
- drv.irqmask = 1 << 5;
- sprintf(name, "/dev/card%d", slot);
- fd = open(name, 2);
- if (fd < 0)
- {
- perror(name);
- exit(1);
- }
-/*
- * Map the memory and I/O contexts.
- */
- drv.mem = 0xD4000;
- if (drv.mem)
- {
- mem.window = 0;
- mem.flags = MDF_ACTIVE;
- mem.start = (caddr_t)drv.mem;
- mem.size = 16*1024;
- mem.card = 0x4000;
- if (ioctl(fd, PIOCSMEM, &mem))
- {
- perror("Set memory context");
- exit(1);
- }
- }
- drv.iobase = 0x300;
- if (drv.iobase)
- {
- io.window = 0;
- io.flags = IODF_ACTIVE|IODF_CS16|IODF_WS;
- io.start = drv.iobase;
- io.size = 32; /* Blah... */
- if (ioctl(fd, PIOCSIO, &io))
- {
- perror("Set I/O context");
- exit(1);
- }
-#ifdef 0
- io.window = 1;
- io.flags = IODF_ACTIVE|IODF_16BIT;
- io.start = drv.iobase+16;
- io.size = 16; /* Blah... */
- if (ioctl(fd, PIOCSIO, &io))
- {
- perror("Set I/O context");
- exit(1);
- }
-#endif
- }
- if (ioctl(fd, PIOCSDRV, &drv))
- perror("set driver");
- close(fd);
-}
-/*
- * usage - print usage and exit
- */
-void
-usage(msg)
-char *msg;
-{
- fprintf(stderr, "rpti: %s\n", msg);
- fprintf(stderr, "Usage: rpti slot driver\n");
- exit(1);
-}
diff --git a/usr.sbin/pccard/misc/skeldrv.c b/usr.sbin/pccard/misc/skeldrv.c
deleted file mode 100644
index ba43861..0000000
--- a/usr.sbin/pccard/misc/skeldrv.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-
-#include <pccard/card.h>
-#include <pccard/cis.h>
-
-
-main(argc, argv)
-int argc;
-char *argv[];
-{
-struct drv_desc drv;
-int fd, err;
-
- fd = open("/dev/card0", 0);
- if (fd < 0)
- {
- perror("/dev/card0");
- exit(1);
- }
- strcpy(drv.name, "skel");
- if (argc == 2)
- drv.unit = atoi(argv[1]);
- else
- drv.unit = 0;
- drv.iobase = 0x300;
- drv.mem = 0xD4000;
- drv.memsize = 16*1024;
- drv.irq = 0xFFFF;
- drv.flags = 0x1234;
- if (ioctl(fd, PIOCSDRV, &drv))
- perror("set driver");
- close(fd);
-}
diff --git a/usr.sbin/pccard/misc/sys/i386/conf/LAPTOP b/usr.sbin/pccard/misc/sys/i386/conf/LAPTOP
deleted file mode 100644
index 9b26789..0000000
--- a/usr.sbin/pccard/misc/sys/i386/conf/LAPTOP
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
-#
-# GENERIC,v 1.20 1994/11/18 19:10:25 jkh Exp
-#
-
-machine "i386"
-cpu "I386_CPU"
-cpu "I486_CPU"
-cpu "I586_CPU"
-ident LAPTOP
-maxusers 4
-
-options MATH_EMULATE #Support for x87 emulation
-options INET #InterNETworking
-options FFS #Berkeley Fast Filesystem
-options NFS #Network Filesystem
-options MSDOSFS #MSDOS Filesystem
-options PROCFS #Process filesystem
-options "COMPAT_43" #Compatible with BSD 4.3
-options UCONSOLE #X Console support
-options "FAT_CURSOR" #block cursor in syscons or pccons
-options "NCONS=4" #4 virtual consoles
-options ALLOW_CONFLICT_IOADDR
-options PSM_NO_RESET
-
-config kernel root on wd0 swap on wd0 and wd1 and sd0 and sd1 dumps on wd0
-
-controller crd0
-#device pcic0
-
-
-controller isa0
-
-controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
-disk fd0 at fdc0 drive 0
-
-controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
-disk wd0 at wdc0 drive 0
-
-device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
-device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
-device psm0 at isa? port "IO_KBD" tty irq 12 vector psmintr
-
-#device pcic0 at isa? port 0x3E0 tty irq 3 iomem 0xd0000
-
-device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
-device sio1 at isa? port "IO_COM2" tty irq 10 vector siointr
-#device sio1 at isa? port "IO_COM2" tty flags 0x80 irq 10 vector siointr
-
-device lpt0 at isa? port? tty irq 7 vector lptintr
-
-#device ed0 at isa? port 0x300 net flags 0x20 irq 5 iomem 0xd4000 vector edintr
-
-device apm0 at isa?
-
-pseudo-device loop
-pseudo-device ether
-pseudo-device log
-pseudo-device sl 2
-pseudo-device pty 16
-pseudo-device speaker
-pseudo-device gzip # Exec gzipped a.out's
diff --git a/usr.sbin/pccard/misc/sys/pccard/Makefile b/usr.sbin/pccard/misc/sys/pccard/Makefile
deleted file mode 100644
index e78a156..0000000
--- a/usr.sbin/pccard/misc/sys/pccard/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-all: pcic.o ed.o
-
-CFLAGS = -O -DINET -DKERNEL -DLKM -I/sys
-
-pcic.o: pcic.c
- cc -c $(CFLAGS) pcic.c
-
-load: pcic.o
- modload -e lkm_pcic pcic.o
- pccardmem d0000
-
-unload:
- modunload -n pcic
-
-skel.o: skel.c
- cc -c $(CFLAGS) skel.c
-
-ldskel: skel.o
- modload -e lkm_skel skel.o
-
-ed.o: if_ed.o lkm_ed.o
- ld -r -o ed.o if_ed.o lkm_ed.o
-
-lded: ed.o
- modload -e lkm_ed ed.o
diff --git a/usr.sbin/pccard/misc/sys/pccard/README b/usr.sbin/pccard/misc/sys/pccard/README
deleted file mode 100644
index cc1ea70..0000000
--- a/usr.sbin/pccard/misc/sys/pccard/README
+++ /dev/null
@@ -1,13 +0,0 @@
-
-This directory contains:
-
- card.h Include file for driver interface
- cis.h CIS defines
- slot.h Kernel interface for card/slot driver/devices interface
- i82365.h Defines for PCIC device
-
- pccard.c Mainline PC-Card support functions (card services).
- pcic.c PCIC or compatible slot driver (loadable).
- skel.c Skeleton loadable driver interfacing to card services.
-
-The other files are working copies of drivers.
diff --git a/usr.sbin/pccard/misc/sys/pccard/bpfilter.h b/usr.sbin/pccard/misc/sys/pccard/bpfilter.h
deleted file mode 100644
index 21d2ed8..0000000
--- a/usr.sbin/pccard/misc/sys/pccard/bpfilter.h
+++ /dev/null
@@ -1 +0,0 @@
-#define NBPFILTER 0
diff --git a/usr.sbin/pccard/misc/sys/pccard/ed.h b/usr.sbin/pccard/misc/sys/pccard/ed.h
deleted file mode 100644
index d2d7bac..0000000
--- a/usr.sbin/pccard/misc/sys/pccard/ed.h
+++ /dev/null
@@ -1 +0,0 @@
-#define NED 2
diff --git a/usr.sbin/pccard/misc/sys/pccard/if_ed.c b/usr.sbin/pccard/misc/sys/pccard/if_ed.c
deleted file mode 100644
index f2c134f..0000000
--- a/usr.sbin/pccard/misc/sys/pccard/if_ed.c
+++ /dev/null
@@ -1,1997 +0,0 @@
-/*
- * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
- * adapters. By David Greenman, 29-April-1993
- *
- * Copied 3 July 1995 from if_ed.c
- *
- *-------------------------------------------------------------------------
- *
- * Copyright (c) 1995 Andrew McRae. All rights reserved.
- *
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
- *
- * Copyright (C) 1993, David Greenman. This software may be used, modified,
- * copied, distributed, and sold, in both source and binary form provided
- * that the above copyright and these terms are retained. Under no
- * circumstances is the author responsible for the proper functioning
- * of this software, nor does the author assume any responsibility
- * for damages incurred with its use.
- *
- * $Id: if_ed.c,v 1.69 1995/04/12 20:47:45 wollman Exp $
- */
-
-#include "ed.h"
-#include "bpfilter.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/errno.h>
-#include <sys/ioctl.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/syslog.h>
-#include <sys/devconf.h>
-#include <sys/proc.h>
-
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/if_types.h>
-
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#endif
-
-#ifdef NS
-#include <netns/ns.h>
-#include <netns/ns_if.h>
-#endif
-
-#if NBPFILTER > 0
-#include <net/bpf.h>
-#include <net/bpfdesc.h>
-#endif
-
-#include <machine/clock.h>
-
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-
-#include <pccard/card.h>
-#include <pccard/slot.h>
-#include <pccard/if_edreg.h>
-
-/* For backwards compatibility */
-#ifndef IFF_ALTPHYS
-#define IFF_ALTPHYS IFF_LINK0
-#endif
-
-/*
- * ed_softc: per line info and status
- */
-static struct ed_softc {
- struct arpcom arpcom; /* ethernet common */
-
- char *type_str; /* pointer to type string */
- u_char vendor; /* interface vendor */
- u_char type; /* interface type code */
-
- u_short asic_addr; /* ASIC I/O bus address */
- u_short nic_addr; /* NIC (DS8390) I/O bus address */
-
-/*
- * The following 'proto' variable is part of a work-around for 8013EBT asics
- * being write-only. It's sort of a prototype/shadow of the real thing.
- */
- u_char wd_laar_proto;
- u_char cr_proto;
- u_char isa16bit; /* width of access to card 0=8 or 1=16 */
- int is790; /* set by the probe code if the card is 790
- * based */
-
- caddr_t bpf; /* BPF "magic cookie" */
- caddr_t mem_start; /* NIC memory start address */
- caddr_t mem_end; /* NIC memory end address */
- u_long mem_size; /* total NIC memory size */
- caddr_t mem_ring; /* start of RX ring-buffer (in NIC mem) */
-
- u_char mem_shared; /* NIC memory is shared with host */
- u_char xmit_busy; /* transmitter is busy */
- u_char txb_cnt; /* number of transmit buffers */
- u_char txb_inuse; /* number of TX buffers currently in-use */
-
- u_char txb_new; /* pointer to where new buffer will be added */
- u_char txb_next_tx; /* pointer to next buffer ready to xmit */
- u_short txb_len[8]; /* buffered xmit buffer lengths */
- u_char tx_page_start; /* first page of TX buffer area */
- u_char rec_page_start; /* first page of RX ring-buffer */
- u_char rec_page_stop; /* last page of RX ring-buffer */
- u_char next_packet; /* pointer to next unread RX packet */
- struct kern_devconf kdc; /* kernel configuration database info */
-} ed_softc[NED];
-
-int ed_attach(struct isa_device *);
-void ed_init(int);
-int edintr(struct pccard_dev *);
-int ed_ioctl(struct ifnet *, int, caddr_t);
-int ed_probe(struct isa_device *);
-void ed_start(struct ifnet *);
-void ed_reset(int);
-void ed_watchdog(int);
-int ed_probe_generic8390(struct ed_softc *);
-int ed_probe_Novell(struct isa_device *);
-
-void ds_getmcaf();
-
-static void ed_get_packet(struct ed_softc *, char *, int /* u_short */ , int);
-static void ed_stop(int);
-
-static inline void ed_rint();
-static inline void ed_xmit();
-static inline char *ed_ring_copy();
-
-void ed_pio_readmem(), ed_pio_writemem();
-u_short ed_pio_write_mbufs();
-
-void ed_setrcr(struct ifnet *, struct ed_softc *);
-
-#define ETHER_MIN_LEN 64
-#define ETHER_MAX_LEN 1518
-#define ETHER_ADDR_LEN 6
-#define ETHER_HDR_SIZE 14
-
-/*
- * The device entry is being removed. Shut it down,
- * and turn off interrupts etc. Not called unless
- * the device was successfully installed.
- */
-void
-edunload(struct pccard_dev *dp)
-{
- printf("ed%d: unload\n", dp->isahd.id_unit);
- ed_stop(dp->isahd.id_unit);
-}
-/*
- * Called when a power down is wanted. Shuts down the
- * device and configures the device as unavailable (but
- * still loaded...). A resume is done by calling
- * edinit with first=0.
- */
-void
-edsuspend(struct pccard_dev *dp)
-{
- printf("ed%d: suspending\n", dp->isahd.id_unit);
-}
-/*
- * Initialize the device.
- * if first is set, then initially check for
- * the device's existence before initialising it.
- * Once initialised, the device table may be set up.
- */
-int
-edinit(struct pccard_dev *dp, int first)
-{
- if (first)
- return(ed_probe(&dp->isahd));
- return(0);
-}
-/*
- * Determine if the device is present
- *
- * on entry:
- * a point to a pccard_dev structure
- * on exit:
- * NULL if device not found
- * or # of i/o addresses used (if found)
- */
-int
-ed_probe(struct isa_device *pdev)
-{
-int nports;
-
- nports = ed_probe_pccard(pdev);
- if (nports == 0)
- {
- nports = ed_probe_Novell(pdev);
- }
- if (nports)
- {
- (void)ed_attach(pdev);
- return (0);
- }
- return(ENODEV);
-}
-int
-ed_probe_pccard(struct isa_device *pdev)
-{
- struct ed_softc *sc = &ed_softc[pdev->id_unit];
- int n, memsize;
- unsigned int *p;
- unsigned char tmp;
-
- sc->asic_addr = pdev->id_iobase + 0x10;
- sc->nic_addr = pdev->id_iobase;
- printf("Probing at 0x%x, mem 0x%x\n", pdev->id_iobase,
- pdev->id_maddr);
-/*
- * Reset the board by reading/writing a location.
- * This may not exist on all boards, but hopefully
- * is not invasive.
- */
-#if 1
- tmp = inb(sc->asic_addr + ED_PCMCIA_RESET);
- DELAY(5000);
- outb(sc->asic_addr + ED_PCMCIA_RESET, tmp);
- DELAY(5000);
-#endif
-
- /* Make sure that we really have an 8390 based board */
- if (!ed_probe_generic8390(sc))
- return (0);
-/*
- * Check for shared memory. If we can write to it, then
- * set up this as a generic controller with shared memory.
- */
- memsize = 0;
- if (pdev->id_maddr == 0)
- return(0);
-/*
- * Write a bit pattern to memory.
- */
- p = (unsigned int *)pdev->id_maddr;
- for (n = 0; n < pdev->id_msize; p++, n += sizeof(*p))
- *p = 0xAA5500FF;
-/*
- * If it verifies, then shared memory is OK.
- * Clear memory after check.
- */
- p = (unsigned int *)pdev->id_maddr;
- for (n = 0; n < pdev->id_msize; n += sizeof(*p)) {
- if (*p != 0xAA5500FF)
- break;
- *p++ = 0;
- }
-/*
- * If no memory, then can't be a shared memory card.
- */
- if (n < 8*1024)
- return(0);
- if (n < 16*1024)
- memsize = 8*1024;
- else
- memsize = 16*1024;
- sc->mem_start = (caddr_t) pdev->id_maddr;
- sc->mem_shared = 1;
- /*
- * allocate one xmit buffer if < 16k, two buffers otherwise
- */
- if ((memsize < 16384) || (pdev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING)) {
- sc->mem_ring = sc->mem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE);
- sc->txb_cnt = 1;
- sc->rec_page_start = ED_TXBUF_SIZE + ED_PCMCIA_PAGE_OFFSET;
- } else {
- sc->mem_ring = sc->mem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE * 2);
- sc->txb_cnt = 2;
- sc->rec_page_start = ED_TXBUF_SIZE * 2 + ED_PCMCIA_PAGE_OFFSET;
- }
- sc->mem_size = memsize;
- sc->mem_end = sc->mem_start + memsize;
- sc->rec_page_stop = memsize / ED_PAGE_SIZE;
- sc->tx_page_start = ED_PCMCIA_PAGE_OFFSET;
-/*
- * Run 16 bit by default, but allow override.
- */
- sc->isa16bit = 1;
- if (pdev->id_flags & ED_FLAGS_FORCE_8BIT_MODE)
- sc->isa16bit = 0;
-
-#if 0
- sc->vendor = ED_VENDOR_PCMCIA;
-#endif
- sc->type_str = "PCMCIA";
- sc->type = ED_TYPE_PCMCIA;
- return (4);
-}
-/*
- * Probe and vendor-specific initialization routine for NE1000/2000 boards
- */
-int
-ed_probe_Novell(isa_dev)
- struct isa_device *isa_dev;
-{
- struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
- u_int memsize, n;
- u_char romdata[16], tmp;
- static char test_pattern[32] = "THIS is A memory TEST pattern";
- char test_buffer[32];
-
- sc->asic_addr = isa_dev->id_iobase + ED_NOVELL_ASIC_OFFSET;
- sc->nic_addr = isa_dev->id_iobase + ED_NOVELL_NIC_OFFSET;
-
- /* XXX - do Novell-specific probe here */
-
- /* Reset the board */
-#ifdef GWETHER
- outb(sc->asic_addr + ED_NOVELL_RESET, 0);
- DELAY(200);
-#endif /* GWETHER */
- tmp = inb(sc->asic_addr + ED_NOVELL_RESET);
-
- /*
- * I don't know if this is necessary; probably cruft leftover from
- * Clarkson packet driver code. Doesn't do a thing on the boards I've
- * tested. -DG [note that a outb(0x84, 0) seems to work here, and is
- * non-invasive...but some boards don't seem to reset and I don't have
- * complete documentation on what the 'right' thing to do is...so we
- * do the invasive thing for now. Yuck.]
- */
- outb(sc->asic_addr + ED_NOVELL_RESET, tmp);
- DELAY(5000);
-
- /*
- * This is needed because some NE clones apparently don't reset the
- * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
- * - this makes the probe invasive! ...Done against my better
- * judgement. -DLG
- */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
-
- DELAY(5000);
-
- /* Make sure that we really have an 8390 based board */
- if (!ed_probe_generic8390(sc))
- return (0);
-
- sc->vendor = ED_VENDOR_NOVELL;
- sc->mem_shared = 0;
- sc->cr_proto = ED_CR_RD2;
- isa_dev->id_maddr = 0;
-
- /*
- * Test the ability to read and write to the NIC memory. This has the
- * side affect of determining if this is an NE1000 or an NE2000.
- */
-
- /*
- * This prevents packets from being stored in the NIC memory when the
- * readmem routine turns on the start bit in the CR.
- */
- outb(sc->nic_addr + ED_P0_RCR, ED_RCR_MON);
-
- /* Temporarily initialize DCR for byte operations */
- outb(sc->nic_addr + ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
-
- outb(sc->nic_addr + ED_P0_PSTART, 8192 / ED_PAGE_SIZE);
- outb(sc->nic_addr + ED_P0_PSTOP, 16384 / ED_PAGE_SIZE);
-
- sc->isa16bit = 0;
-
- /*
- * Write a test pattern in byte mode. If this fails, then there
- * probably isn't any memory at 8k - which likely means that the board
- * is an NE2000.
- */
- ed_pio_writemem(sc, test_pattern, 8192, sizeof(test_pattern));
- ed_pio_readmem(sc, 8192, test_buffer, sizeof(test_pattern));
-
- if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
- /* not an NE1000 - try NE2000 */
-
- outb(sc->nic_addr + ED_P0_RCR, ED_RCR_MON);
- outb(sc->nic_addr + ED_P0_PSTART, 16384 / ED_PAGE_SIZE);
- outb(sc->nic_addr + ED_P0_PSTOP, 32768 / ED_PAGE_SIZE);
-
- if (isa_dev->id_flags & ED_FLAGS_FORCE_8BIT_MODE)
- {
- sc->isa16bit = 0;
- outb(sc->nic_addr + ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
- }
- else
- {
- sc->isa16bit = 1;
- outb(sc->nic_addr + ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
- }
-
- /*
- * Write a test pattern in word mode. If this also fails, then
- * we don't know what this board is.
- */
- ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern));
- ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern));
-
- if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)))
- return (0); /* not an NE2000 either */
-
- sc->type = ED_TYPE_NE2000;
- sc->type_str = "NE2000";
- sc->kdc.kdc_description = "Ethernet adapter: NE2000";
- } else {
- sc->type = ED_TYPE_NE1000;
- sc->type_str = "NE1000";
- sc->kdc.kdc_description = "Ethernet adapter: NE1000";
- }
-
- /* 8k of memory plus an additional 8k if 16bit */
- memsize = 8192 + sc->isa16bit * 8192;
-
-#if 0 /* probably not useful - NE boards only come two ways */
- /* allow kernel config file overrides */
- if (isa_dev->id_msize)
- memsize = isa_dev->id_msize;
-#endif
-
- sc->mem_size = memsize;
-
- /* NIC memory doesn't start at zero on an NE board */
- /* The start address is tied to the bus width */
- sc->mem_start = (char *) 8192 + sc->isa16bit * 8192;
- sc->mem_end = sc->mem_start + memsize;
- sc->tx_page_start = memsize / ED_PAGE_SIZE;
-
-#ifdef GWETHER
- {
- int x, i, mstart = 0, msize = 0;
- char pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE], tbuf[ED_PAGE_SIZE];
-
- for (i = 0; i < ED_PAGE_SIZE; i++)
- pbuf0[i] = 0;
-
- /* Clear all the memory. */
- for (x = 1; x < 256; x++)
- ed_pio_writemem(sc, pbuf0, x * 256, ED_PAGE_SIZE);
-
- /* Search for the start of RAM. */
- for (x = 1; x < 256; x++) {
- ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
- if (memcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
- for (i = 0; i < ED_PAGE_SIZE; i++)
- pbuf[i] = 255 - x;
- ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE);
- ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
- if (memcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) {
- mstart = x * ED_PAGE_SIZE;
- msize = ED_PAGE_SIZE;
- break;
- }
- }
- }
-
- if (mstart == 0) {
- printf("ed%d: Cannot find start of RAM.\n", isa_dev->id_unit);
- return 0;
- }
- /* Search for the start of RAM. */
- for (x = (mstart / ED_PAGE_SIZE) + 1; x < 256; x++) {
- ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
- if (memcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
- for (i = 0; i < ED_PAGE_SIZE; i++)
- pbuf[i] = 255 - x;
- ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE);
- ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
- if (memcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0)
- msize += ED_PAGE_SIZE;
- else {
- break;
- }
- } else {
- break;
- }
- }
-
- if (msize == 0) {
- printf("ed%d: Cannot find any RAM, start : %d, x = %d.\n", isa_dev->id_unit, mstart, x);
- return 0;
- }
- printf("ed%d: RAM start at %d, size : %d.\n", isa_dev->id_unit, mstart, msize);
-
- sc->mem_size = msize;
- sc->mem_start = (char *) mstart;
- sc->mem_end = (char *) (msize + mstart);
- sc->tx_page_start = mstart / ED_PAGE_SIZE;
- }
-#endif /* GWETHER */
-
- /*
- * Use one xmit buffer if < 16k, two buffers otherwise (if not told
- * otherwise).
- */
- if ((memsize < 16384) || (isa_dev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING))
- sc->txb_cnt = 1;
- else
- sc->txb_cnt = 2;
-
- sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
- sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE;
-
- sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
-
- ed_pio_readmem(sc, 0, romdata, 16);
- for (n = 0; n < ETHER_ADDR_LEN; n++)
- sc->arpcom.ac_enaddr[n] = romdata[n * (sc->isa16bit + 1)];
-
-#ifdef GWETHER
- if (sc->arpcom.ac_enaddr[2] == 0x86) {
- sc->type_str = "Gateway AT";
- sc->kdc.kdc_description = "Ethernet adapter: Gateway AT";
- }
-#endif /* GWETHER */
-
- /* clear any pending interrupts that might have occurred above */
- outb(sc->nic_addr + ED_P0_ISR, 0xff);
-
- return (ED_NOVELL_IO_PORTS);
-}
-
-
-/*
- * Generic probe routine for testing for the existance of a DS8390.
- * Must be called after the NIC has just been reset. This routine
- * works by looking at certain register values that are guaranteed
- * to be initialized a certain way after power-up or reset. Seems
- * not to currently work on the 83C690.
- *
- * Specifically:
- *
- * Register reset bits set bits
- * Command Register (CR) TXP, STA RD2, STP
- * Interrupt Status (ISR) RST
- * Interrupt Mask (IMR) All bits
- * Data Control (DCR) LAS
- * Transmit Config. (TCR) LB1, LB0
- *
- * We only look at the CR and ISR registers, however, because looking at
- * the others would require changing register pages (which would be
- * intrusive if this isn't an 8390).
- *
- * Return 1 if 8390 was found, 0 if not.
- */
-
-int
-ed_probe_generic8390(sc)
- struct ed_softc *sc;
-{
- if ((inb(sc->nic_addr + ED_P0_CR) &
- (ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
- (ED_CR_RD2 | ED_CR_STP))
- return (0);
- if ((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RST) != ED_ISR_RST)
- return (0);
-
- return (1);
-}
-/*
- * Install interface into kernel networking data structures
- */
-int
-ed_attach(struct isa_device *pdev)
-{
- struct ed_softc *sc = &ed_softc[pdev->id_unit];
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- /*
- * Set interface to stopped condition (reset)
- */
- ed_stop(pdev->id_unit);
-
- /*
- * Initialize ifnet structure
- */
- ifp->if_unit = pdev->id_unit;
- ifp->if_name = "ed";
- ifp->if_init = ed_init;
- ifp->if_output = ether_output;
- ifp->if_start = ed_start;
- ifp->if_ioctl = ed_ioctl;
- ifp->if_reset = ed_reset;
- ifp->if_watchdog = ed_watchdog;
-
- /*
- * Set default state for ALTPHYS flag (used to disable the tranceiver
- * for AUI operation), based on compile-time config option.
- */
- if (pdev->id_flags & ED_FLAGS_DISABLE_TRANCEIVER)
- ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS |
- IFF_MULTICAST | IFF_ALTPHYS);
- else
- ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS |
- IFF_MULTICAST);
-
- /*
- * Attach the interface
- */
- if_attach(ifp);
-
- /*
- * Print additional info when attached
- */
- printf("ed%d: address %s, ", pdev->id_unit,
- ether_sprintf(sc->arpcom.ac_enaddr));
-
- if (sc->type_str && (*sc->type_str != 0))
- printf("type %s ", sc->type_str);
- else
- printf("type unknown (0x%x) ", sc->type);
-
- printf("%s ", sc->isa16bit ? "(16 bit)" : "(8 bit)");
-
- printf("%s\n", ((sc->vendor == ED_VENDOR_3COM) &&
- (ifp->if_flags & IFF_ALTPHYS)) ? " tranceiver disabled" : "");
-
- /*
- * If BPF is in the kernel, call the attach for it
- */
-#if NBPFILTER > 0
- bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
-#endif
- return 1;
-}
-
-/*
- * Reset interface.
- */
-void
-ed_reset(unit)
- int unit;
-{
- int s;
-
- s = splimp();
-
- /*
- * Stop interface and re-initialize.
- */
- ed_stop(unit);
- ed_init(unit);
-
- (void) splx(s);
-}
-
-/*
- * Take interface offline.
- */
-void
-ed_stop(unit)
- int unit;
-{
- struct ed_softc *sc = &ed_softc[unit];
- int n = 5000;
-
- /*
- * Stop everything on the interface, and select page 0 registers.
- */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STP);
-
- /*
- * Wait for interface to enter stopped state, but limit # of checks to
- * 'n' (about 5ms). It shouldn't even take 5us on modern DS8390's, but
- * just in case it's an old one.
- */
- while (((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RST) == 0) && --n);
-}
-
-/*
- * Device timeout/watchdog routine. Entered if the device neglects to
- * generate an interrupt after a transmit has been started on it.
- */
-void
-ed_watchdog(unit)
- int unit;
-{
- struct ed_softc *sc = &ed_softc[unit];
-
- log(LOG_ERR, "ed%d: device timeout\n", unit);
- ++sc->arpcom.ac_if.if_oerrors;
-
- ed_reset(unit);
-}
-
-/*
- * Initialize device.
- */
-void
-ed_init(unit)
- int unit;
-{
- struct ed_softc *sc = &ed_softc[unit];
- struct ifnet *ifp = &sc->arpcom.ac_if;
- int i, s;
-
-
- /* address not known */
- if (ifp->if_addrlist == (struct ifaddr *) 0)
- return;
-
- /*
- * Initialize the NIC in the exact order outlined in the NS manual.
- * This init procedure is "mandatory"...don't change what or when
- * things happen.
- */
- s = splimp();
-
- /* reset transmitter flags */
- sc->xmit_busy = 0;
- sc->arpcom.ac_if.if_timer = 0;
-
- sc->txb_inuse = 0;
- sc->txb_new = 0;
- sc->txb_next_tx = 0;
-
- /* This variable is used below - don't move this assignment */
- sc->next_packet = sc->rec_page_start + 1;
-
- /*
- * Set interface for page 0, Remote DMA complete, Stopped
- */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STP);
-
- if (sc->isa16bit) {
-
- /*
- * Set FIFO threshold to 8, No auto-init Remote DMA, byte
- * order=80x86, word-wide DMA xfers,
- */
- outb(sc->nic_addr + ED_P0_DCR, ED_DCR_FT1 | ED_DCR_WTS | ED_DCR_LS);
- } else {
-
- /*
- * Same as above, but byte-wide DMA xfers
- */
- outb(sc->nic_addr + ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
- }
-
- /*
- * Clear Remote Byte Count Registers
- */
- outb(sc->nic_addr + ED_P0_RBCR0, 0);
- outb(sc->nic_addr + ED_P0_RBCR1, 0);
-
- /*
- * For the moment, don't store incoming packets in memory.
- */
- outb(sc->nic_addr + ED_P0_RCR, ED_RCR_MON);
-
- /*
- * Place NIC in internal loopback mode
- */
- outb(sc->nic_addr + ED_P0_TCR, ED_TCR_LB0);
-
- /*
- * Initialize transmit/receive (ring-buffer) Page Start
- */
- outb(sc->nic_addr + ED_P0_TPSR, sc->tx_page_start);
- outb(sc->nic_addr + ED_P0_PSTART, sc->rec_page_start);
- /* Set lower bits of byte addressable framing to 0 */
- if (sc->is790)
- outb(sc->nic_addr + 0x09, 0);
-
- /*
- * Initialize Receiver (ring-buffer) Page Stop and Boundry
- */
- outb(sc->nic_addr + ED_P0_PSTOP, sc->rec_page_stop);
- outb(sc->nic_addr + ED_P0_BNRY, sc->rec_page_start);
-
- /*
- * Clear all interrupts. A '1' in each bit position clears the
- * corresponding flag.
- */
- outb(sc->nic_addr + ED_P0_ISR, 0xff);
-
- /*
- * Enable the following interrupts: receive/transmit complete,
- * receive/transmit error, and Receiver OverWrite.
- *
- * Counter overflow and Remote DMA complete are *not* enabled.
- */
- outb(sc->nic_addr + ED_P0_IMR,
- ED_IMR_PRXE | ED_IMR_PTXE | ED_IMR_RXEE | ED_IMR_TXEE | ED_IMR_OVWE);
-
- /*
- * Program Command Register for page 1
- */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
-
- /*
- * Copy out our station address
- */
- for (i = 0; i < ETHER_ADDR_LEN; ++i)
- outb(sc->nic_addr + ED_P1_PAR0 + i, sc->arpcom.ac_enaddr[i]);
-
- /*
- * Set Current Page pointer to next_packet (initialized above)
- */
- outb(sc->nic_addr + ED_P1_CURR, sc->next_packet);
-
- /*
- * Program Receiver Configuration Register and multicast filter. CR is
- * set to page 0 on return.
- */
- ed_setrcr(ifp, sc);
-
- /*
- * Take interface out of loopback
- */
- outb(sc->nic_addr + ED_P0_TCR, 0);
-
- /*
- * If this is a 3Com board, the tranceiver must be software enabled
- * (there is no settable hardware default).
- */
- if (sc->vendor == ED_VENDOR_3COM) {
- if (ifp->if_flags & IFF_ALTPHYS) {
- outb(sc->asic_addr + ED_3COM_CR, 0);
- } else {
- outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL);
- }
- }
-
- /*
- * Set 'running' flag, and clear output active flag.
- */
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
-
- /*
- * ...and attempt to start output
- */
- ed_start(ifp);
-
- (void) splx(s);
-}
-
-/*
- * This routine actually starts the transmission on the interface
- */
-static inline void
-ed_xmit(ifp)
- struct ifnet *ifp;
-{
- struct ed_softc *sc = &ed_softc[ifp->if_unit];
- unsigned short len;
-
- len = sc->txb_len[sc->txb_next_tx];
-
- /*
- * Set NIC for page 0 register access
- */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STA);
-
- /*
- * Set TX buffer start page
- */
- outb(sc->nic_addr + ED_P0_TPSR, sc->tx_page_start +
- sc->txb_next_tx * ED_TXBUF_SIZE);
-
- /*
- * Set TX length
- */
- outb(sc->nic_addr + ED_P0_TBCR0, len);
- outb(sc->nic_addr + ED_P0_TBCR1, len >> 8);
-
- /*
- * Set page 0, Remote DMA complete, Transmit Packet, and *Start*
- */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_TXP | ED_CR_STA);
- sc->xmit_busy = 1;
-
- /*
- * Point to next transmit buffer slot and wrap if necessary.
- */
- sc->txb_next_tx++;
- if (sc->txb_next_tx == sc->txb_cnt)
- sc->txb_next_tx = 0;
-
- /*
- * Set a timer just in case we never hear from the board again
- */
- ifp->if_timer = 2;
-}
-
-/*
- * Start output on interface.
- * We make two assumptions here:
- * 1) that the current priority is set to splimp _before_ this code
- * is called *and* is returned to the appropriate priority after
- * return
- * 2) that the IFF_OACTIVE flag is checked before this code is called
- * (i.e. that the output part of the interface is idle)
- */
-void
-ed_start(ifp)
- struct ifnet *ifp;
-{
- struct ed_softc *sc = &ed_softc[ifp->if_unit];
- struct mbuf *m0, *m;
- caddr_t buffer;
- int len;
-
-outloop:
-
- /*
- * First, see if there are buffered packets and an idle transmitter -
- * should never happen at this point.
- */
- if (sc->txb_inuse && (sc->xmit_busy == 0)) {
- printf("ed: packets buffered, but transmitter idle\n");
- ed_xmit(ifp);
- }
-
- /*
- * See if there is room to put another packet in the buffer.
- */
- if (sc->txb_inuse == sc->txb_cnt) {
-
- /*
- * No room. Indicate this to the outside world and exit.
- */
- ifp->if_flags |= IFF_OACTIVE;
- return;
- }
- IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
- if (m == 0) {
-
- /*
- * We are using the !OACTIVE flag to indicate to the outside
- * world that we can accept an additional packet rather than
- * that the transmitter is _actually_ active. Indeed, the
- * transmitter may be active, but if we haven't filled all the
- * buffers with data then we still want to accept more.
- */
- ifp->if_flags &= ~IFF_OACTIVE;
- return;
- }
-
- /*
- * Copy the mbuf chain into the transmit buffer
- */
-
- m0 = m;
-
- /* txb_new points to next open buffer slot */
- buffer = sc->mem_start + (sc->txb_new * ED_TXBUF_SIZE * ED_PAGE_SIZE);
-
- if (sc->mem_shared) {
-
- /*
- * Special case setup for 16 bit boards...
- */
- if (sc->isa16bit) {
- switch (sc->vendor) {
-
- /*
- * For 16bit 3Com boards (which have 16k of
- * memory), we have the xmit buffers in a
- * different page of memory ('page 0') - so
- * change pages.
- */
- case ED_VENDOR_3COM:
- outb(sc->asic_addr + ED_3COM_GACFR,
- ED_3COM_GACFR_RSEL);
- break;
-
- /*
- * Enable 16bit access to shared memory on
- * WD/SMC boards.
- */
- case ED_VENDOR_WD_SMC:{
- outb(sc->asic_addr + ED_WD_LAAR,
- (sc->wd_laar_proto | ED_WD_LAAR_M16EN));
- if (sc->is790) {
- outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_MENB);
- }
- break;
- }
- }
- }
- for (len = 0; m != 0; m = m->m_next) {
- bcopy(mtod(m, caddr_t), buffer, m->m_len);
- buffer += m->m_len;
- len += m->m_len;
- }
-
- /*
- * Restore previous shared memory access
- */
- if (sc->isa16bit) {
- switch (sc->vendor) {
- case ED_VENDOR_3COM:
- outb(sc->asic_addr + ED_3COM_GACFR,
- ED_3COM_GACFR_RSEL | ED_3COM_GACFR_MBS0);
- break;
- case ED_VENDOR_WD_SMC:{
- if (sc->is790) {
- outb(sc->asic_addr + ED_WD_MSR, 0x00);
- }
- outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto);
- break;
- }
- }
- }
- } else {
- len = ed_pio_write_mbufs(sc, m, buffer);
- if (len == 0)
- goto outloop;
- }
-
- sc->txb_len[sc->txb_new] = max(len, ETHER_MIN_LEN);
-
- sc->txb_inuse++;
-
- /*
- * Point to next buffer slot and wrap if necessary.
- */
- sc->txb_new++;
- if (sc->txb_new == sc->txb_cnt)
- sc->txb_new = 0;
-
- if (sc->xmit_busy == 0)
- ed_xmit(ifp);
-
- /*
- * Tap off here if there is a bpf listener.
- */
-#if NBPFILTER > 0
- if (sc->bpf) {
- bpf_mtap(sc->bpf, m0);
- }
-#endif
-
- m_freem(m0);
-
- /*
- * Loop back to the top to possibly buffer more packets
- */
- goto outloop;
-}
-
-/*
- * Ethernet interface receiver interrupt.
- */
-static inline void
-ed_rint(unit)
- int unit;
-{
- register struct ed_softc *sc = &ed_softc[unit];
- u_char boundry;
- u_short len;
- struct ed_ring packet_hdr;
- char *packet_ptr;
-
- /*
- * Set NIC to page 1 registers to get 'current' pointer
- */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
-
- /*
- * 'sc->next_packet' is the logical beginning of the ring-buffer -
- * i.e. it points to where new data has been buffered. The 'CURR'
- * (current) register points to the logical end of the ring-buffer -
- * i.e. it points to where additional new data will be added. We loop
- * here until the logical beginning equals the logical end (or in
- * other words, until the ring-buffer is empty).
- */
- while (sc->next_packet != inb(sc->nic_addr + ED_P1_CURR)) {
-
- /* get pointer to this buffer's header structure */
- packet_ptr = sc->mem_ring +
- (sc->next_packet - sc->rec_page_start) * ED_PAGE_SIZE;
-
- /*
- * The byte count includes a 4 byte header that was added by
- * the NIC.
- */
- if (sc->mem_shared)
- packet_hdr = *(struct ed_ring *) packet_ptr;
- else
- ed_pio_readmem(sc, packet_ptr, (char *) &packet_hdr,
- sizeof(packet_hdr));
- len = packet_hdr.count;
- if (len > ETHER_MAX_LEN) {
- /*
- * Length is a wild value. There's a good chance that
- * this was caused by the NIC being old and buggy.
- * The bug is that the length low byte is duplicated in
- * the high byte. Try to recalculate the length based on
- * the pointer to the next packet.
- */
- /*
- * NOTE: sc->next_packet is pointing at the current packet.
- */
- len &= ED_PAGE_SIZE - 1; /* preserve offset into page */
- if (packet_hdr.next_packet >= sc->next_packet) {
- len += (packet_hdr.next_packet - sc->next_packet) * ED_PAGE_SIZE;
- } else {
- len += ((packet_hdr.next_packet - sc->rec_page_start) +
- (sc->rec_page_stop - sc->next_packet)) * ED_PAGE_SIZE;
- }
- }
- /*
- * Be fairly liberal about what we allow as a "reasonable" length
- * so that a [crufty] packet will make it to BPF (and can thus
- * be analyzed). Note that all that is really important is that
- * we have a length that will fit into one mbuf cluster or less;
- * the upper layer protocols can then figure out the length from
- * their own length field(s).
- */
- if ((len <= MCLBYTES) &&
- (packet_hdr.next_packet >= sc->rec_page_start) &&
- (packet_hdr.next_packet < sc->rec_page_stop)) {
- /*
- * Go get packet.
- */
- ed_get_packet(sc, packet_ptr + sizeof(struct ed_ring),
- len - sizeof(struct ed_ring), packet_hdr.rsr & ED_RSR_PHY);
- ++sc->arpcom.ac_if.if_ipackets;
- } else {
- /*
- * Really BAD. The ring pointers are corrupted.
- */
- log(LOG_ERR,
- "ed%d: NIC memory corrupt - invalid packet length %d\n",
- unit, len);
- ++sc->arpcom.ac_if.if_ierrors;
- ed_reset(unit);
- return;
- }
-
- /*
- * Update next packet pointer
- */
- sc->next_packet = packet_hdr.next_packet;
-
- /*
- * Update NIC boundry pointer - being careful to keep it one
- * buffer behind. (as recommended by NS databook)
- */
- boundry = sc->next_packet - 1;
- if (boundry < sc->rec_page_start)
- boundry = sc->rec_page_stop - 1;
-
- /*
- * Set NIC to page 0 registers to update boundry register
- */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STA);
-
- outb(sc->nic_addr + ED_P0_BNRY, boundry);
-
- /*
- * Set NIC to page 1 registers before looping to top (prepare
- * to get 'CURR' current pointer)
- */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
- }
-}
-
-/*
- * Ethernet interface interrupt processor
- */
-int
-edintr(struct pccard_dev *pdev)
-{
- struct ed_softc *sc = &ed_softc[pdev->isahd.id_unit];
- u_char isr;
- int ret = 0;
-
- /*
- * Set NIC to page 0 registers
- */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STA);
-
- /*
- * loop until there are no more new interrupts
- */
- while ((isr = inb(sc->nic_addr + ED_P0_ISR)) != 0) {
-
- ret = 1;
- /*
- * reset all the bits that we are 'acknowledging' by writing a
- * '1' to each bit position that was set (writing a '1'
- * *clears* the bit)
- */
- outb(sc->nic_addr + ED_P0_ISR, isr);
-
- /*
- * Handle transmitter interrupts. Handle these first because
- * the receiver will reset the board under some conditions.
- */
- if (isr & (ED_ISR_PTX | ED_ISR_TXE)) {
- u_char collisions = inb(sc->nic_addr + ED_P0_NCR) & 0x0f;
-
- /*
- * Check for transmit error. If a TX completed with an
- * error, we end up throwing the packet away. Really
- * the only error that is possible is excessive
- * collisions, and in this case it is best to allow
- * the automatic mechanisms of TCP to backoff the
- * flow. Of course, with UDP we're screwed, but this
- * is expected when a network is heavily loaded.
- */
- (void) inb(sc->nic_addr + ED_P0_TSR);
- if (isr & ED_ISR_TXE) {
-
- /*
- * Excessive collisions (16)
- */
- if ((inb(sc->nic_addr + ED_P0_TSR) & ED_TSR_ABT)
- && (collisions == 0)) {
-
- /*
- * When collisions total 16, the
- * P0_NCR will indicate 0, and the
- * TSR_ABT is set.
- */
- collisions = 16;
- }
-
- /*
- * update output errors counter
- */
- ++sc->arpcom.ac_if.if_oerrors;
- } else {
-
- /*
- * Update total number of successfully
- * transmitted packets.
- */
- ++sc->arpcom.ac_if.if_opackets;
- }
-
- /*
- * reset tx busy and output active flags
- */
- sc->xmit_busy = 0;
- sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
-
- /*
- * clear watchdog timer
- */
- sc->arpcom.ac_if.if_timer = 0;
-
- /*
- * Add in total number of collisions on last
- * transmission.
- */
- sc->arpcom.ac_if.if_collisions += collisions;
-
- /*
- * Decrement buffer in-use count if not zero (can only
- * be zero if a transmitter interrupt occured while
- * not actually transmitting). If data is ready to
- * transmit, start it transmitting, otherwise defer
- * until after handling receiver
- */
- if (sc->txb_inuse && --sc->txb_inuse)
- ed_xmit(&sc->arpcom.ac_if);
- }
-
- /*
- * Handle receiver interrupts
- */
- if (isr & (ED_ISR_PRX | ED_ISR_RXE | ED_ISR_OVW)) {
-
- /*
- * Overwrite warning. In order to make sure that a
- * lockup of the local DMA hasn't occurred, we reset
- * and re-init the NIC. The NSC manual suggests only a
- * partial reset/re-init is necessary - but some chips
- * seem to want more. The DMA lockup has been seen
- * only with early rev chips - Methinks this bug was
- * fixed in later revs. -DG
- */
- if (isr & ED_ISR_OVW) {
- ++sc->arpcom.ac_if.if_ierrors;
-#ifdef DIAGNOSTIC
- log(LOG_WARNING,
- "ed%d: warning - receiver ring buffer overrun\n",
- pdev->isahd.id_unit);
-#endif
-
- /*
- * Stop/reset/re-init NIC
- */
- ed_reset(pdev->isahd.id_unit);
- } else {
-
- /*
- * Receiver Error. One or more of: CRC error,
- * frame alignment error FIFO overrun, or
- * missed packet.
- */
- if (isr & ED_ISR_RXE) {
- ++sc->arpcom.ac_if.if_ierrors;
-#ifdef ED_DEBUG
- printf("ed%d: receive error %x\n", pdev->isahd.id_unit,
- inb(sc->nic_addr + ED_P0_RSR));
-#endif
- }
-
- /*
- * Go get the packet(s) XXX - Doing this on an
- * error is dubious because there shouldn't be
- * any data to get (we've configured the
- * interface to not accept packets with
- * errors).
- */
-
- /*
- * Enable 16bit access to shared memory first
- * on WD/SMC boards.
- */
- if (sc->isa16bit &&
- (sc->vendor == ED_VENDOR_WD_SMC)) {
-
- outb(sc->asic_addr + ED_WD_LAAR,
- (sc->wd_laar_proto |=
- ED_WD_LAAR_M16EN));
- if (sc->is790) {
- outb(sc->asic_addr + ED_WD_MSR,
- ED_WD_MSR_MENB);
- }
- }
- ed_rint(pdev->isahd.id_unit);
-
- /* disable 16bit access */
- if (sc->isa16bit &&
- (sc->vendor == ED_VENDOR_WD_SMC)) {
-
- if (sc->is790) {
- outb(sc->asic_addr + ED_WD_MSR, 0x00);
- }
- outb(sc->asic_addr + ED_WD_LAAR,
- (sc->wd_laar_proto &=
- ~ED_WD_LAAR_M16EN));
- }
- }
- }
-
- /*
- * If it looks like the transmitter can take more data,
- * attempt to start output on the interface. This is done
- * after handling the receiver to give the receiver priority.
- */
- if ((sc->arpcom.ac_if.if_flags & IFF_OACTIVE) == 0)
- ed_start(&sc->arpcom.ac_if);
-
- /*
- * return NIC CR to standard state: page 0, remote DMA
- * complete, start (toggling the TXP bit off, even if was just
- * set in the transmit routine, is *okay* - it is 'edge'
- * triggered from low to high)
- */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STA);
-
- /*
- * If the Network Talley Counters overflow, read them to reset
- * them. It appears that old 8390's won't clear the ISR flag
- * otherwise - resulting in an infinite loop.
- */
- if (isr & ED_ISR_CNT) {
- (void) inb(sc->nic_addr + ED_P0_CNTR0);
- (void) inb(sc->nic_addr + ED_P0_CNTR1);
- (void) inb(sc->nic_addr + ED_P0_CNTR2);
- }
- }
- return(ret);
-}
-
-/*
- * Process an ioctl request. This code needs some work - it looks
- * pretty ugly.
- */
-int
-ed_ioctl(ifp, command, data)
- register struct ifnet *ifp;
- int command;
- caddr_t data;
-{
- register struct ifaddr *ifa = (struct ifaddr *) data;
- struct ed_softc *sc = &ed_softc[ifp->if_unit];
- struct ifreq *ifr = (struct ifreq *) data;
- int s, error = 0;
-
- s = splimp();
-
- switch (command) {
-
- case SIOCSIFADDR:
- ifp->if_flags |= IFF_UP;
- /* netifs are BUSY when UP */
-
- switch (ifa->ifa_addr->sa_family) {
-#ifdef INET
- case AF_INET:
- ed_init(ifp->if_unit); /* before arpwhohas */
- arp_ifinit((struct arpcom *)ifp, ifa);
- break;
-#endif
-#ifdef NS
-
- /*
- * XXX - This code is probably wrong
- */
- case AF_NS:
- {
- register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
-
- if (ns_nullhost(*ina))
- ina->x_host =
- *(union ns_host *) (sc->arpcom.ac_enaddr);
- else {
- bcopy((caddr_t) ina->x_host.c_host,
- (caddr_t) sc->arpcom.ac_enaddr,
- sizeof(sc->arpcom.ac_enaddr));
- }
-
- /*
- * Set new address
- */
- ed_init(ifp->if_unit);
- break;
- }
-#endif
- default:
- ed_init(ifp->if_unit);
- break;
- }
- break;
-
- case SIOCGIFADDR:
- {
- struct sockaddr *sa;
-
- sa = (struct sockaddr *) & ifr->ifr_data;
- bcopy((caddr_t) sc->arpcom.ac_enaddr,
- (caddr_t) sa->sa_data, ETHER_ADDR_LEN);
- }
- break;
-
- case SIOCSIFFLAGS:
-
- /*
- * If interface is marked down and it is running, then stop it
- */
- if (((ifp->if_flags & IFF_UP) == 0) &&
- (ifp->if_flags & IFF_RUNNING)) {
- ed_stop(ifp->if_unit);
- ifp->if_flags &= ~IFF_RUNNING;
- } else {
-
- /*
- * If interface is marked up and it is stopped, then
- * start it
- */
- if ((ifp->if_flags & IFF_UP) &&
- ((ifp->if_flags & IFF_RUNNING) == 0))
- ed_init(ifp->if_unit);
- }
-
-#if NBPFILTER > 0
-
- /*
- * Promiscuous flag may have changed, so reprogram the RCR.
- */
- ed_setrcr(ifp, sc);
-#endif
-
- /*
- * An unfortunate hack to provide the (required) software
- * control of the tranceiver for 3Com boards. The ALTPHYS flag
- * disables the tranceiver if set.
- */
- if (sc->vendor == ED_VENDOR_3COM) {
- if (ifp->if_flags & IFF_ALTPHYS) {
- outb(sc->asic_addr + ED_3COM_CR, 0);
- } else {
- outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL);
- }
- }
- break;
-
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- /*
- * Update out multicast list.
- */
- error = (command == SIOCADDMULTI) ?
- ether_addmulti(ifr, &sc->arpcom) :
- ether_delmulti(ifr, &sc->arpcom);
-
- if (error == ENETRESET) {
-
- /*
- * Multicast list has changed; set the hardware filter
- * accordingly.
- */
- ed_setrcr(ifp, sc);
- error = 0;
- }
- break;
-
- case SIOCSIFMTU:
- /*
- * Set the interface MTU.
- */
- if (ifr->ifr_mtu > ETHERMTU) {
- error = EINVAL;
- } else {
- ifp->if_mtu = ifr->ifr_mtu;
- }
- break;
-
- default:
- error = EINVAL;
- }
- (void) splx(s);
- return (error);
-}
-
-/*
- * Retreive packet from shared memory and send to the next level up via
- * ether_input(). If there is a BPF listener, give a copy to BPF, too.
- */
-static void
-ed_get_packet(sc, buf, len, multicast)
- struct ed_softc *sc;
- char *buf;
- u_short len;
- int multicast;
-{
- struct ether_header *eh;
- struct mbuf *m;
-
- /* Allocate a header mbuf */
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return;
- m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
- m->m_pkthdr.len = m->m_len = len;
-
- /* Attach an mbuf cluster */
- MCLGET(m, M_DONTWAIT);
-
- /* Insist on getting a cluster */
- if ((m->m_flags & M_EXT) == 0) {
- m_freem(m);
- return;
- }
-
- /*
- * The +2 is to longword align the start of the real packet.
- * This is important for NFS.
- */
- m->m_data += 2;
- eh = mtod(m, struct ether_header *);
-
- /*
- * Get packet, including link layer address, from interface.
- */
- ed_ring_copy(sc, buf, (char *)eh, len);
-
-#if NBPFILTER > 0
-
- /*
- * Check if there's a BPF listener on this interface. If so, hand off
- * the raw packet to bpf.
- */
- if (sc->bpf) {
- bpf_mtap(sc->bpf, m);
-
- /*
- * Note that the interface cannot be in promiscuous mode if
- * there are no BPF listeners. And if we are in promiscuous
- * mode, we have to check if this packet is really ours.
- */
- if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
- bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
- sizeof(eh->ether_dhost)) != 0 && multicast == 0) {
- m_freem(m);
- return;
- }
- }
-#endif
-
- /*
- * Remove link layer address.
- */
- m->m_pkthdr.len = m->m_len = len - sizeof(struct ether_header);
- m->m_data += sizeof(struct ether_header);
-
- ether_input(&sc->arpcom.ac_if, eh, m);
- return;
-}
-
-/*
- * Supporting routines
- */
-
-/*
- * Given a NIC memory source address and a host memory destination
- * address, copy 'amount' from NIC to host using Programmed I/O.
- * The 'amount' is rounded up to a word - okay as long as mbufs
- * are word sized.
- * This routine is currently Novell-specific.
- */
-void
-ed_pio_readmem(sc, src, dst, amount)
- struct ed_softc *sc;
- unsigned short src;
- unsigned char *dst;
- unsigned short amount;
-{
- /* select page 0 registers */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STA);
-
- /* round up to a word */
- if (amount & 1)
- ++amount;
-
- /* set up DMA byte count */
- outb(sc->nic_addr + ED_P0_RBCR0, amount);
- outb(sc->nic_addr + ED_P0_RBCR1, amount >> 8);
-
- /* set up source address in NIC mem */
- outb(sc->nic_addr + ED_P0_RSAR0, src);
- outb(sc->nic_addr + ED_P0_RSAR1, src >> 8);
-
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD0 | ED_CR_STA);
-
- if (sc->isa16bit) {
- insw(sc->asic_addr + ED_NOVELL_DATA, dst, amount / 2);
- } else
- insb(sc->asic_addr + ED_NOVELL_DATA, dst, amount);
-
-}
-
-/*
- * Stripped down routine for writing a linear buffer to NIC memory.
- * Only used in the probe routine to test the memory. 'len' must
- * be even.
- */
-void
-ed_pio_writemem(sc, src, dst, len)
- struct ed_softc *sc;
- char *src;
- unsigned short dst;
- unsigned short len;
-{
- int maxwait = 200; /* about 240us */
-
- /* select page 0 registers */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STA);
-
- /* reset remote DMA complete flag */
- outb(sc->nic_addr + ED_P0_ISR, ED_ISR_RDC);
-
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD0 | ED_CR_STA);
- /* set up DMA byte count */
- outb(sc->nic_addr + ED_P0_RBCR0, len);
- outb(sc->nic_addr + ED_P0_RBCR1, len >> 8);
-
- /* set up destination address in NIC mem */
- outb(sc->nic_addr + ED_P0_RSAR0, dst);
- outb(sc->nic_addr + ED_P0_RSAR1, dst >> 8);
-
- /* set remote DMA write */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD1 | ED_CR_STA);
-
- if (sc->isa16bit)
- outsw(sc->asic_addr + ED_NOVELL_DATA, src, len / 2);
- else
- outsb(sc->asic_addr + ED_NOVELL_DATA, src, len);
-
- /*
- * Wait for remote DMA complete. This is necessary because on the
- * transmit side, data is handled internally by the NIC in bursts and
- * we can't start another remote DMA until this one completes. Not
- * waiting causes really bad things to happen - like the NIC
- * irrecoverably jamming the ISA bus.
- */
- while (((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RDC) != ED_ISR_RDC) && --maxwait);
-}
-my_outsw(int ad, unsigned short *src, int len)
-{
- while(--len >= 0)
- {
- outw(ad, *src++);
- printf("*");
- }
- printf("<\n");
-}
-
-/*
- * Write an mbuf chain to the destination NIC memory address using
- * programmed I/O.
- */
-u_short
-ed_pio_write_mbufs(sc, m, dst)
- struct ed_softc *sc;
- struct mbuf *m;
- unsigned short dst;
-{
- unsigned short total_len, dma_len;
- struct mbuf *mp;
- int maxwait = 200; /* about 240us */
-
- /* First, count up the total number of bytes to copy */
- for (total_len = 0, mp = m; mp; mp = mp->m_next)
- total_len += mp->m_len;
-
- dma_len = total_len;
- if (sc->isa16bit && (dma_len & 1))
- dma_len++;
-
- /* select page 0 registers */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STA);
-
- /* reset remote DMA complete flag */
- outb(sc->nic_addr + ED_P0_ISR, ED_ISR_RDC);
-
- /* set up DMA byte count */
- outb(sc->nic_addr + ED_P0_RBCR0, dma_len);
- outb(sc->nic_addr + ED_P0_RBCR1, dma_len >> 8);
-
- /* set up destination address in NIC mem */
- outb(sc->nic_addr + ED_P0_RSAR0, dst);
- outb(sc->nic_addr + ED_P0_RSAR1, dst >> 8);
-
- /* set remote DMA write */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD1 | ED_CR_STA);
-
- /*
- * Transfer the mbuf chain to the NIC memory.
- * 16-bit cards require that data be transferred as words, and only words.
- * So that case requires some extra code to patch over odd-length mbufs.
- */
-
- if (!sc->isa16bit) {
- /* NE1000s are easy */
- while (m) {
- if (m->m_len) {
- outsb(sc->asic_addr + ED_NOVELL_DATA,
- m->m_data, m->m_len);
- }
- m = m->m_next;
- }
- } else {
- /* NE2000s are a pain */
- unsigned char *data;
- int len, wantbyte;
- unsigned char savebyte[2];
-
- wantbyte = 0;
-
- while (m) {
- len = m->m_len;
- if (len) {
- data = mtod(m, caddr_t);
- /* finish the last word */
- if (wantbyte) {
- savebyte[1] = *data;
- outw(sc->asic_addr + ED_NOVELL_DATA, *(u_short *)savebyte);
- data++;
- len--;
- wantbyte = 0;
- }
- /* output contiguous words */
- if (len > 1) {
- outsw(sc->asic_addr + ED_NOVELL_DATA,
- data, len >> 1);
- data += len & ~1;
- len &= 1;
- }
- /* save last byte, if necessary */
- if (len == 1) {
- savebyte[0] = *data;
- wantbyte = 1;
- }
- }
- m = m->m_next;
- }
- /* spit last byte */
- if (wantbyte) {
- outw(sc->asic_addr + ED_NOVELL_DATA, *(u_short *)savebyte);
- }
- }
-
- /*
- * Wait for remote DMA complete. This is necessary because on the
- * transmit side, data is handled internally by the NIC in bursts and
- * we can't start another remote DMA until this one completes. Not
- * waiting causes really bad things to happen - like the NIC
- * irrecoverably jamming the ISA bus.
- */
- while (((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RDC) != ED_ISR_RDC) && --maxwait);
-
- if (!maxwait) {
- log(LOG_WARNING, "ed%d: remote transmit DMA failed to complete\n",
- sc->arpcom.ac_if.if_unit);
- ed_reset(sc->arpcom.ac_if.if_unit);
- return(0);
- }
- return (total_len);
-}
-
-/*
- * Given a source and destination address, copy 'amount' of a packet from
- * the ring buffer into a linear destination buffer. Takes into account
- * ring-wrap.
- */
-static inline char *
-ed_ring_copy(sc, src, dst, amount)
- struct ed_softc *sc;
- char *src;
- char *dst;
- u_short amount;
-{
- u_short tmp_amount;
-
- /* does copy wrap to lower addr in ring buffer? */
- if (src + amount > sc->mem_end) {
- tmp_amount = sc->mem_end - src;
-
- /* copy amount up to end of NIC memory */
- if (sc->mem_shared)
- bcopy(src, dst, tmp_amount);
- else
- ed_pio_readmem(sc, src, dst, tmp_amount);
-
- amount -= tmp_amount;
- src = sc->mem_ring;
- dst += tmp_amount;
- }
- if (sc->mem_shared)
- bcopy(src, dst, amount);
- else
- ed_pio_readmem(sc, src, dst, amount);
-
- return (src + amount);
-}
-
-void
-ed_setrcr(ifp, sc)
- struct ifnet *ifp;
- struct ed_softc *sc;
-{
- int i;
-
- /* set page 1 registers */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
-
- if (ifp->if_flags & IFF_PROMISC) {
-
- /*
- * Reconfigure the multicast filter.
- */
- for (i = 0; i < 8; i++)
- outb(sc->nic_addr + ED_P1_MAR0 + i, 0xff);
-
- /*
- * And turn on promiscuous mode. Also enable reception of
- * runts and packets with CRC & alignment errors.
- */
- /* Set page 0 registers */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STP);
-
- outb(sc->nic_addr + ED_P0_RCR, ED_RCR_PRO | ED_RCR_AM |
- ED_RCR_AB | ED_RCR_AR | ED_RCR_SEP);
- } else {
- /* set up multicast addresses and filter modes */
- if (ifp->if_flags & IFF_MULTICAST) {
- u_long mcaf[2];
-
- if (ifp->if_flags & IFF_ALLMULTI) {
- mcaf[0] = 0xffffffff;
- mcaf[1] = 0xffffffff;
- } else
- ds_getmcaf(sc, mcaf);
-
- /*
- * Set multicast filter on chip.
- */
- for (i = 0; i < 8; i++)
- outb(sc->nic_addr + ED_P1_MAR0 + i, ((u_char *) mcaf)[i]);
-
- /* Set page 0 registers */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STP);
-
- outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AM | ED_RCR_AB);
- } else {
-
- /*
- * Initialize multicast address hashing registers to
- * not accept multicasts.
- */
- for (i = 0; i < 8; ++i)
- outb(sc->nic_addr + ED_P1_MAR0 + i, 0x00);
-
- /* Set page 0 registers */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STP);
-
- outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AB);
- }
- }
-
- /*
- * Start interface.
- */
- outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STA);
-}
-
-/*
- * Compute crc for ethernet address
- */
-u_long
-ds_crc(ep)
- u_char *ep;
-{
-#define POLYNOMIAL 0x04c11db6
- register u_long crc = 0xffffffffL;
- register int carry, i, j;
- register u_char b;
-
- for (i = 6; --i >= 0;) {
- b = *ep++;
- for (j = 8; --j >= 0;) {
- carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
- crc <<= 1;
- b >>= 1;
- if (carry)
- crc = ((crc ^ POLYNOMIAL) | carry);
- }
- }
- return crc;
-#undef POLYNOMIAL
-}
-
-/*
- * Compute the multicast address filter from the
- * list of multicast addresses we need to listen to.
- */
-void
-ds_getmcaf(sc, mcaf)
- struct ed_softc *sc;
- u_long *mcaf;
-{
- register u_int index;
- register u_char *af = (u_char *) mcaf;
- register struct ether_multi *enm;
- register struct ether_multistep step;
-
- mcaf[0] = 0;
- mcaf[1] = 0;
-
- ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
- while (enm != NULL) {
- if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
- mcaf[0] = 0xffffffff;
- mcaf[1] = 0xffffffff;
- return;
- }
- index = ds_crc(enm->enm_addrlo, 6) >> 26;
- af[index >> 3] |= 1 << (index & 7);
-
- ETHER_NEXT_MULTI(step, enm);
- }
-}
diff --git a/usr.sbin/pccard/misc/sys/pccard/if_edreg.h b/usr.sbin/pccard/misc/sys/pccard/if_edreg.h
deleted file mode 100644
index 9644aaf..0000000
--- a/usr.sbin/pccard/misc/sys/pccard/if_edreg.h
+++ /dev/null
@@ -1,989 +0,0 @@
-/*
- * Copyright (C) 1993, David Greenman. This software may be used, modified,
- * copied, distributed, and sold, in both source and binary form provided
- * that the above copyright and these terms are retained. Under no
- * circumstances is the author responsible for the proper functioning
- * of this software, nor does the author assume any responsibility
- * for damages incurred with its use.
- *
- * $Id: if_edreg.h,v 1.17 1995/01/23 19:06:08 davidg Exp $
- */
-/*
- * National Semiconductor DS8390 NIC register definitions
- *
- *
- * Modification history
- *
- * Revision 2.2 1993/11/29 16:33:39 davidg
- * From Thomas Sandford <t.d.g.sandford@comp.brad.ac.uk>
- * Add support for the 8013W board type
- *
- * Revision 2.1 1993/11/22 10:52:33 davidg
- * patch to add support for SMC8216 (Elite-Ultra) boards
- * from Glen H. Lowe
- *
- * Revision 2.0 93/09/29 00:37:15 davidg
- * changed double buffering flag to multi buffering
- * made changes/additions for 3c503 multi-buffering
- * ...companion to Rev. 2.0 of 'ed' driver.
- *
- * Revision 1.1 93/06/23 03:01:07 davidg
- * Initial revision
- *
- */
-
-/*
- * Page 0 register offsets
- */
-#define ED_P0_CR 0x00 /* Command Register */
-
-#define ED_P0_CLDA0 0x01 /* Current Local DMA Addr low (read) */
-#define ED_P0_PSTART 0x01 /* Page Start register (write) */
-
-#define ED_P0_CLDA1 0x02 /* Current Local DMA Addr high (read) */
-#define ED_P0_PSTOP 0x02 /* Page Stop register (write) */
-
-#define ED_P0_BNRY 0x03 /* Boundary Pointer */
-
-#define ED_P0_TSR 0x04 /* Transmit Status Register (read) */
-#define ED_P0_TPSR 0x04 /* Transmit Page Start (write) */
-
-#define ED_P0_NCR 0x05 /* Number of Collisions Reg (read) */
-#define ED_P0_TBCR0 0x05 /* Transmit Byte count, low (write) */
-
-#define ED_P0_FIFO 0x06 /* FIFO register (read) */
-#define ED_P0_TBCR1 0x06 /* Transmit Byte count, high (write) */
-
-#define ED_P0_ISR 0x07 /* Interrupt Status Register */
-
-#define ED_P0_CRDA0 0x08 /* Current Remote DMA Addr low (read) */
-#define ED_P0_RSAR0 0x08 /* Remote Start Address low (write) */
-
-#define ED_P0_CRDA1 0x09 /* Current Remote DMA Addr high (read) */
-#define ED_P0_RSAR1 0x09 /* Remote Start Address high (write) */
-
-#define ED_P0_RBCR0 0x0a /* Remote Byte Count low (write) */
-
-#define ED_P0_RBCR1 0x0b /* Remote Byte Count high (write) */
-
-#define ED_P0_RSR 0x0c /* Receive Status (read) */
-#define ED_P0_RCR 0x0c /* Receive Configuration Reg (write) */
-
-#define ED_P0_CNTR0 0x0d /* frame alignment error counter (read) */
-#define ED_P0_TCR 0x0d /* Transmit Configuration Reg (write) */
-
-#define ED_P0_CNTR1 0x0e /* CRC error counter (read) */
-#define ED_P0_DCR 0x0e /* Data Configuration Reg (write) */
-
-#define ED_P0_CNTR2 0x0f /* missed packet counter (read) */
-#define ED_P0_IMR 0x0f /* Interrupt Mask Register (write) */
-
-/*
- * Page 1 register offsets
- */
-#define ED_P1_CR 0x00 /* Command Register */
-#define ED_P1_PAR0 0x01 /* Physical Address Register 0 */
-#define ED_P1_PAR1 0x02 /* Physical Address Register 1 */
-#define ED_P1_PAR2 0x03 /* Physical Address Register 2 */
-#define ED_P1_PAR3 0x04 /* Physical Address Register 3 */
-#define ED_P1_PAR4 0x05 /* Physical Address Register 4 */
-#define ED_P1_PAR5 0x06 /* Physical Address Register 5 */
-#define ED_P1_CURR 0x07 /* Current RX ring-buffer page */
-#define ED_P1_MAR0 0x08 /* Multicast Address Register 0 */
-#define ED_P1_MAR1 0x09 /* Multicast Address Register 1 */
-#define ED_P1_MAR2 0x0a /* Multicast Address Register 2 */
-#define ED_P1_MAR3 0x0b /* Multicast Address Register 3 */
-#define ED_P1_MAR4 0x0c /* Multicast Address Register 4 */
-#define ED_P1_MAR5 0x0d /* Multicast Address Register 5 */
-#define ED_P1_MAR6 0x0e /* Multicast Address Register 6 */
-#define ED_P1_MAR7 0x0f /* Multicast Address Register 7 */
-
-/*
- * Page 2 register offsets
- */
-#define ED_P2_CR 0x00 /* Command Register */
-#define ED_P2_PSTART 0x01 /* Page Start (read) */
-#define ED_P2_CLDA0 0x01 /* Current Local DMA Addr 0 (write) */
-#define ED_P2_PSTOP 0x02 /* Page Stop (read) */
-#define ED_P2_CLDA1 0x02 /* Current Local DMA Addr 1 (write) */
-#define ED_P2_RNPP 0x03 /* Remote Next Packet Pointer */
-#define ED_P2_TPSR 0x04 /* Transmit Page Start (read) */
-#define ED_P2_LNPP 0x05 /* Local Next Packet Pointer */
-#define ED_P2_ACU 0x06 /* Address Counter Upper */
-#define ED_P2_ACL 0x07 /* Address Counter Lower */
-#define ED_P2_RCR 0x0c /* Receive Configuration Register (read) */
-#define ED_P2_TCR 0x0d /* Transmit Configuration Register (read) */
-#define ED_P2_DCR 0x0e /* Data Configuration Register (read) */
-#define ED_P2_IMR 0x0f /* Interrupt Mask Register (read) */
-
-/*
- * Command Register (CR) definitions
- */
-
-/*
- * STP: SToP. Software reset command. Takes the controller offline. No
- * packets will be received or transmitted. Any reception or
- * transmission in progress will continue to completion before
- * entering reset state. To exit this state, the STP bit must
- * reset and the STA bit must be set. The software reset has
- * executed only when indicated by the RST bit in the ISR being
- * set.
- */
-#define ED_CR_STP 0x01
-
-/*
- * STA: STArt. This bit is used to activate the NIC after either power-up,
- * or when the NIC has been put in reset mode by software command
- * or error.
- */
-#define ED_CR_STA 0x02
-
-/*
- * TXP: Transmit Packet. This bit must be set to indicate transmission of
- * a packet. TXP is internally reset either after the transmission is
- * completed or aborted. This bit should be set only after the Transmit
- * Byte Count and Transmit Page Start register have been programmed.
- */
-#define ED_CR_TXP 0x04
-
-/*
- * RD0, RD1, RD2: Remote DMA Command. These three bits control the operation
- * of the remote DMA channel. RD2 can be set to abort any remote DMA
- * command in progress. The Remote Byte Count registers should be cleared
- * when a remote DMA has been aborted. The Remote Start Addresses are not
- * restored to the starting address if the remote DMA is aborted.
- *
- * RD2 RD1 RD0 function
- * 0 0 0 not allowed
- * 0 0 1 remote read
- * 0 1 0 remote write
- * 0 1 1 send packet
- * 1 X X abort
- */
-#define ED_CR_RD0 0x08
-#define ED_CR_RD1 0x10
-#define ED_CR_RD2 0x20
-
-/*
- * PS0, PS1: Page Select. The two bits select which register set or 'page' to
- * access.
- *
- * PS1 PS0 page
- * 0 0 0
- * 0 1 1
- * 1 0 2
- * 1 1 reserved
- */
-#define ED_CR_PS0 0x40
-#define ED_CR_PS1 0x80
-/* bit encoded aliases */
-#define ED_CR_PAGE_0 0x00 /* (for consistency) */
-#define ED_CR_PAGE_1 0x40
-#define ED_CR_PAGE_2 0x80
-
-/*
- * Interrupt Status Register (ISR) definitions
- */
-
-/*
- * PRX: Packet Received. Indicates packet received with no errors.
- */
-#define ED_ISR_PRX 0x01
-
-/*
- * PTX: Packet Transmitted. Indicates packet transmitted with no errors.
- */
-#define ED_ISR_PTX 0x02
-
-/*
- * RXE: Receive Error. Indicates that a packet was received with one or more
- * the following errors: CRC error, frame alignment error, FIFO overrun,
- * missed packet.
- */
-#define ED_ISR_RXE 0x04
-
-/*
- * TXE: Transmission Error. Indicates that an attempt to transmit a packet
- * resulted in one or more of the following errors: excessive
- * collisions, FIFO underrun.
- */
-#define ED_ISR_TXE 0x08
-
-/*
- * OVW: OverWrite. Indicates a receive ring-buffer overrun. Incoming network
- * would exceed (has exceeded?) the boundry pointer, resulting in data
- * that was previously received and not yet read from the buffer to be
- * overwritten.
- */
-#define ED_ISR_OVW 0x10
-
-/*
- * CNT: Counter Overflow. Set when the MSB of one or more of the Network Talley
- * Counters has been set.
- */
-#define ED_ISR_CNT 0x20
-
-/*
- * RDC: Remote Data Complete. Indicates that a Remote DMA operation has completed.
- */
-#define ED_ISR_RDC 0x40
-
-/*
- * RST: Reset status. Set when the NIC enters the reset state and cleared when a
- * Start Command is issued to the CR. This bit is also set when a receive
- * ring-buffer overrun (OverWrite) occurs and is cleared when one or more
- * packets have been removed from the ring. This is a read-only bit.
- */
-#define ED_ISR_RST 0x80
-
-/*
- * Interrupt Mask Register (IMR) definitions
- */
-
-/*
- * PRXE: Packet Received interrupt Enable. If set, a received packet will cause
- * an interrupt.
- */
-#define ED_IMR_PRXE 0x01
-
-/*
- * PTXE: Packet Transmit interrupt Enable. If set, an interrupt is generated when
- * a packet transmission completes.
- */
-#define ED_IMR_PTXE 0x02
-
-/*
- * RXEE: Receive Error interrupt Enable. If set, an interrupt will occur whenever a
- * packet is received with an error.
- */
-#define ED_IMR_RXEE 0x04
-
-/*
- * TXEE: Transmit Error interrupt Enable. If set, an interrupt will occur whenever
- * a transmission results in an error.
- */
-#define ED_IMR_TXEE 0x08
-
-/*
- * OVWE: OverWrite error interrupt Enable. If set, an interrupt is generated whenever
- * the receive ring-buffer is overrun. i.e. when the boundry pointer is exceeded.
- */
-#define ED_IMR_OVWE 0x10
-
-/*
- * CNTE: Counter overflow interrupt Enable. If set, an interrupt is generated whenever
- * the MSB of one or more of the Network Statistics counters has been set.
- */
-#define ED_IMR_CNTE 0x20
-
-/*
- * RDCE: Remote DMA Complete interrupt Enable. If set, an interrupt is generated
- * when a remote DMA transfer has completed.
- */
-#define ED_IMR_RDCE 0x40
-
-/*
- * bit 7 is unused/reserved
- */
-
-/*
- * Data Configuration Register (DCR) definitions
- */
-
-/*
- * WTS: Word Transfer Select. WTS establishes byte or word transfers for
- * both remote and local DMA transfers
- */
-#define ED_DCR_WTS 0x01
-
-/*
- * BOS: Byte Order Select. BOS sets the byte order for the host.
- * Should be 0 for 80x86, and 1 for 68000 series processors
- */
-#define ED_DCR_BOS 0x02
-
-/*
- * LAS: Long Address Select. When LAS is 1, the contents of the remote
- * DMA registers RSAR0 and RSAR1 are used to provide A16-A31
- */
-#define ED_DCR_LAS 0x04
-
-/*
- * LS: Loopback Select. When 0, loopback mode is selected. Bits D1 and D2
- * of the TCR must also be programmed for loopback operation.
- * When 1, normal operation is selected.
- */
-#define ED_DCR_LS 0x08
-
-/*
- * AR: Auto-initialize Remote. When 0, data must be removed from ring-buffer
- * under program control. When 1, remote DMA is automatically initiated
- * and the boundry pointer is automatically updated
- */
-#define ED_DCR_AR 0x10
-
-/*
- * FT0, FT1: Fifo Threshold select.
- * FT1 FT0 Word-width Byte-width
- * 0 0 1 word 2 bytes
- * 0 1 2 words 4 bytes
- * 1 0 4 words 8 bytes
- * 1 1 8 words 12 bytes
- *
- * During transmission, the FIFO threshold indicates the number of bytes
- * or words that the FIFO has filled from the local DMA before BREQ is
- * asserted. The transmission threshold is 16 bytes minus the receiver
- * threshold.
- */
-#define ED_DCR_FT0 0x20
-#define ED_DCR_FT1 0x40
-
-/*
- * bit 7 (0x80) is unused/reserved
- */
-
-/*
- * Transmit Configuration Register (TCR) definitions
- */
-
-/*
- * CRC: Inhibit CRC. If 0, CRC will be appended by the transmitter, if 0, CRC
- * is not appended by the transmitter.
- */
-#define ED_TCR_CRC 0x01
-
-/*
- * LB0, LB1: Loopback control. These two bits set the type of loopback that is
- * to be performed.
- *
- * LB1 LB0 mode
- * 0 0 0 - normal operation (DCR_LS = 0)
- * 0 1 1 - internal loopback (DCR_LS = 0)
- * 1 0 2 - external loopback (DCR_LS = 1)
- * 1 1 3 - external loopback (DCR_LS = 0)
- */
-#define ED_TCR_LB0 0x02
-#define ED_TCR_LB1 0x04
-
-/*
- * ATD: Auto Transmit Disable. Clear for normal operation. When set, allows
- * another station to disable the NIC's transmitter by transmitting to
- * a multicast address hashing to bit 62. Reception of a multicast address
- * hashing to bit 63 enables the transmitter.
- */
-#define ED_TCR_ATD 0x08
-
-/*
- * OFST: Collision Offset enable. This bit when set modifies the backoff
- * algorithm to allow prioritization of nodes.
- */
-#define ED_TCR_OFST 0x10
-
-/*
- * bits 5, 6, and 7 are unused/reserved
- */
-
-/*
- * Transmit Status Register (TSR) definitions
- */
-
-/*
- * PTX: Packet Transmitted. Indicates successful transmission of packet.
- */
-#define ED_TSR_PTX 0x01
-
-/*
- * bit 1 (0x02) is unused/reserved
- */
-
-/*
- * COL: Transmit Collided. Indicates that the transmission collided at least
- * once with another station on the network.
- */
-#define ED_TSR_COL 0x04
-
-/*
- * ABT: Transmit aborted. Indicates that the transmission was aborted due to
- * excessive collisions.
- */
-#define ED_TSR_ABT 0x08
-
-/*
- * CRS: Carrier Sense Lost. Indicates that carrier was lost during the
- * transmission of the packet. (Transmission is not aborted because
- * of a loss of carrier)
- */
-#define ED_TSR_CRS 0x10
-
-/*
- * FU: FIFO Underrun. Indicates that the NIC wasn't able to access bus/
- * transmission memory before the FIFO emptied. Transmission of the
- * packet was aborted.
- */
-#define ED_TSR_FU 0x20
-
-/*
- * CDH: CD Heartbeat. Indicates that the collision detection circuitry
- * isn't working correctly during a collision heartbeat test.
- */
-#define ED_TSR_CDH 0x40
-
-/*
- * OWC: Out of Window Collision: Indicates that a collision occurred after
- * a slot time (51.2us). The transmission is rescheduled just as in
- * normal collisions.
- */
-#define ED_TSR_OWC 0x80
-
-/*
- * Receiver Configuration Register (RCR) definitions
- */
-
-/*
- * SEP: Save Errored Packets. If 0, error packets are discarded. If set to 1,
- * packets with CRC and frame errors are not discarded.
- */
-#define ED_RCR_SEP 0x01
-
-/*
- * AR: Accept Runt packet. If 0, packet with less than 64 byte are discarded.
- * If set to 1, packets with less than 64 byte are not discarded.
- */
-#define ED_RCR_AR 0x02
-
-/*
- * AB: Accept Broadcast. If set, packets sent to the broadcast address will be
- * accepted.
- */
-#define ED_RCR_AB 0x04
-
-/*
- * AM: Accept Multicast. If set, packets sent to a multicast address are checked
- * for a match in the hashing array. If clear, multicast packets are ignored.
- */
-#define ED_RCR_AM 0x08
-
-/*
- * PRO: Promiscuous Physical. If set, all packets with a physical addresses are
- * accepted. If clear, a physical destination address must match this
- * station's address. Note: for full promiscuous mode, RCR_AB and RCR_AM
- * must also be set. In addition, the multicast hashing array must be set
- * to all 1's so that all multicast addresses are accepted.
- */
-#define ED_RCR_PRO 0x10
-
-/*
- * MON: Monitor Mode. If set, packets will be checked for good CRC and framing,
- * but are not stored in the ring-buffer. If clear, packets are stored (normal
- * operation).
- */
-#define ED_RCR_MON 0x20
-
-/*
- * bits 6 and 7 are unused/reserved.
- */
-
-/*
- * Receiver Status Register (RSR) definitions
- */
-
-/*
- * PRX: Packet Received without error.
- */
-#define ED_RSR_PRX 0x01
-
-/*
- * CRC: CRC error. Indicates that a packet has a CRC error. Also set for frame
- * alignment errors.
- */
-#define ED_RSR_CRC 0x02
-
-/*
- * FAE: Frame Alignment Error. Indicates that the incoming packet did not end on
- * a byte boundry and the CRC did not match at the last byte boundry.
- */
-#define ED_RSR_FAE 0x04
-
-/*
- * FO: FIFO Overrun. Indicates that the FIFO was not serviced (during local DMA)
- * causing it to overrun. Reception of the packet is aborted.
- */
-#define ED_RSR_FO 0x08
-
-/*
- * MPA: Missed Packet. Indicates that the received packet couldn't be stored in
- * the ring-buffer because of insufficient buffer space (exceeding the
- * boundry pointer), or because the transfer to the ring-buffer was inhibited
- * by RCR_MON - monitor mode.
- */
-#define ED_RSR_MPA 0x10
-
-/*
- * PHY: Physical address. If 0, the packet received was sent to a physical address.
- * If 1, the packet was accepted because of a multicast/broadcast address
- * match.
- */
-#define ED_RSR_PHY 0x20
-
-/*
- * DIS: Receiver Disabled. Set to indicate that the receiver has enetered monitor
- * mode. Cleared when the receiver exits monitor mode.
- */
-#define ED_RSR_DIS 0x40
-
-/*
- * DFR: Deferring. Set to indicate a 'jabber' condition. The CRS and COL inputs
- * are active, and the transceiver has set the CD line as a result of the
- * jabber.
- */
-#define ED_RSR_DFR 0x80
-
-/*
- * receive ring discriptor
- *
- * The National Semiconductor DS8390 Network interface controller uses
- * the following receive ring headers. The way this works is that the
- * memory on the interface card is chopped up into 256 bytes blocks.
- * A contiguous portion of those blocks are marked for receive packets
- * by setting start and end block #'s in the NIC. For each packet that
- * is put into the receive ring, one of these headers (4 bytes each) is
- * tacked onto the front. The first byte is a copy of the receiver status
- * register at the time the packet was received.
- */
-struct ed_ring {
- u_char rsr; /* receiver status */
- u_char next_packet; /* pointer to next packet */
- u_short count; /* bytes in packet (length + 4) */
-};
-
-/*
- * Common constants
- */
-#define ED_PAGE_SIZE 256 /* Size of RAM pages in bytes */
-#define ED_TXBUF_SIZE 6 /* Size of TX buffer in pages */
-
-/*
- * Vendor types
- */
-#define ED_VENDOR_WD_SMC 0x00 /* Western Digital/SMC */
-#define ED_VENDOR_3COM 0x01 /* 3Com */
-#define ED_VENDOR_NOVELL 0x02 /* Novell */
-#define ED_VENDOR_PCMCIA 0x03 /* Generic pcmcia */
-
-/*
- * Compile-time config flags
- */
-/*
- * this sets the default for enabling/disablng the tranceiver
- */
-#define ED_FLAGS_DISABLE_TRANCEIVER 0x0001
-
-/*
- * This forces the board to be used in 8/16bit mode even if it
- * autoconfigs differently
- */
-#define ED_FLAGS_FORCE_8BIT_MODE 0x0002
-#define ED_FLAGS_FORCE_16BIT_MODE 0x0004
-
-/*
- * This disables the use of double transmit buffers.
- */
-#define ED_FLAGS_NO_MULTI_BUFFERING 0x0008
-
-/*
- * This forces all operations with the NIC memory to use Programmed
- * I/O (i.e. not via shared memory)
- */
-#define ED_FLAGS_FORCE_PIO 0x0010
-
-/*
- * Definitions for Western digital/SMC WD80x3 series ASIC
- */
-/*
- * Memory Select Register (MSR)
- */
-#define ED_WD_MSR 0
-
-/* next three definitions for Toshiba */
-#define ED_WD_MSR_POW 0x02 /* 0 = power save, 1 = normal (R/W) */
-#define ED_WD_MSR_BSY 0x04 /* gate array busy (R) */
-#define ED_WD_MSR_LEN 0x20 /* data bus width, 0 = 16 bits,
- 1 = 8 bits (R/W) */
-#define ED_WD_MSR_ADDR 0x3f /* Memory decode bits 18-13 */
-#define ED_WD_MSR_MENB 0x40 /* Memory enable */
-#define ED_WD_MSR_RST 0x80 /* Reset board */
-
-/*
- * Interface Configuration Register (ICR)
- */
-#define ED_WD_ICR 1
-
-#define ED_WD_ICR_16BIT 0x01 /* 16-bit interface */
-#define ED_WD_ICR_OAR 0x02 /* select register. 0=BIO 1=EAR */
-#define ED_WD_ICR_IR2 0x04 /* high order bit of encoded IRQ */
-#define ED_WD_ICR_MSZ 0x08 /* memory size (0=8k 1=32k) */
-#define ED_WD_ICR_RLA 0x10 /* recall LAN address */
-#define ED_WD_ICR_RX7 0x20 /* recall all but i/o and LAN address */
-#define ED_WD_ICR_RIO 0x40 /* recall i/o address */
-#define ED_WD_ICR_STO 0x80 /* store to non-volatile memory */
-#ifdef TOSH_ETHER
-#define ED_WD_ICR_MEM 0xe0 /* shared mem address A15-A13 (R/W) */
-#define ED_WD_ICR_MSZ1 0x0f /* memory size, 0x08 = 64K, 0x04 = 32K,
- 0x02 = 16K, 0x01 = 8K */
- /* 64K can only be used if mem address
- above 1Mb */
- /* IAR holds address A23-A16 (R/W) */
-#endif
-
-/*
- * IO Address Register (IAR)
- */
-#define ED_WD_IAR 2
-
-/*
- * EEROM Address Register
- */
-#define ED_WD_EAR 3
-
-/*
- * Interrupt Request Register (IRR)
- */
-#define ED_WD_IRR 4
-
-#define ED_WD_IRR_0WS 0x01 /* use 0 wait-states on 8 bit bus */
-#define ED_WD_IRR_OUT1 0x02 /* WD83C584 pin 1 output */
-#define ED_WD_IRR_OUT2 0x04 /* WD83C584 pin 2 output */
-#define ED_WD_IRR_OUT3 0x08 /* WD83C584 pin 3 output */
-#define ED_WD_IRR_FLASH 0x10 /* Flash RAM is in the ROM socket */
-
-/*
- * The three bits of the encoded IRQ are decoded as follows:
- *
- * IR2 IR1 IR0 IRQ
- * 0 0 0 2/9
- * 0 0 1 3
- * 0 1 0 5
- * 0 1 1 7
- * 1 0 0 10
- * 1 0 1 11
- * 1 1 0 15
- * 1 1 1 4
- */
-#define ED_WD_IRR_IR0 0x20 /* bit 0 of encoded IRQ */
-#define ED_WD_IRR_IR1 0x40 /* bit 1 of encoded IRQ */
-#define ED_WD_IRR_IEN 0x80 /* Interrupt enable */
-
-/*
- * LA Address Register (LAAR)
- */
-#define ED_WD_LAAR 5
-
-#define ED_WD_LAAR_ADDRHI 0x1f /* bits 23-19 of RAM address */
-#define ED_WD_LAAR_0WS16 0x20 /* enable 0 wait-states on 16 bit bus */
-#define ED_WD_LAAR_L16EN 0x40 /* enable 16-bit operation */
-#define ED_WD_LAAR_M16EN 0x80 /* enable 16-bit memory access */
-
-/* i/o base offset to station address/card-ID PROM */
-#define ED_WD_PROM 8
-
-/*
- * 83C790 specific registers
- */
-/*
- * Hardware Support Register (HWR) ('790)
- */
-#define ED_WD790_HWR 4
-
-#define WD_WD790_HWR_NUKE 0x10 /* hardware reset */
-#define ED_WD790_HWR_LPRM 0x40 /* LAN PROM select */
-#define ED_WD790_HWR_SWH 0x80 /* switch register set */
-
-/*
- * ICR790 Interrupt Control Register for the 83C790
- */
-#define ED_WD790_ICR 6
-
-#define ED_WD790_ICR_EIL 0x01 /* enable interrupts */
-
-/*
- * REV/IOPA Revision / I/O Pipe register for the 83C79X
- */
-#define ED_WD790_REV 7
-
-#define ED_WD790 0x20
-#define ED_WD795 0x40
-
-/*
- * 79X RAM Address Register (RAR)
- * Enabled with SWH bit=1 in HWR register
- */
-#define ED_WD790_RAR 0x0b
-
-#define ED_WD790_RAR_SZ8 0x00 /* 8k memory buffer */
-#define ED_WD790_RAR_SZ16 0x10 /* 16k memory buffer */
-#define ED_WD790_RAR_SZ32 0x20 /* 32k memory buffer */
-#define ED_WD790_RAR_SZ64 0x30 /* 64k memory buffer */
-
-/*
- * General Control Register (GCR)
- * Enabled with SWH bit=1 in HWR register
- */
-#define ED_WD790_GCR 0x0d
-
-#define ED_WD790_GCR_IR0 0x04 /* bit 0 of encoded IRQ */
-#define ED_WD790_GCR_IR1 0x08 /* bit 1 of encoded IRQ */
-#define ED_WD790_GCR_ZWSEN 0x20 /* zero wait state enable */
-#define ED_WD790_GCR_IR2 0x40 /* bit 2 of encoded IRQ */
-#define ED_WD790_GCR_LIT 0x01 /* Link Integrity Test Enable */
-/*
- * The three bits of the encoded IRQ are decoded as follows:
- *
- * IR2 IR1 IR0 IRQ
- * 0 0 0 none
- * 0 0 1 9
- * 0 1 0 3
- * 0 1 1 5
- * 1 0 0 7
- * 1 0 1 10
- * 1 1 0 11
- * 1 1 1 15
- */
-
-/* i/o base offset to CARD ID */
-#define ED_WD_CARD_ID ED_WD_PROM+6
-
-/* Board type codes in card ID */
-#define ED_TYPE_WD8003S 0x02
-#define ED_TYPE_WD8003E 0x03
-#define ED_TYPE_WD8013EBT 0x05
-#define ED_TYPE_TOSHIBA1 0x11 /* named PCETA1 */
-#define ED_TYPE_TOSHIBA2 0x12 /* named PCETA2 */
-#define ED_TYPE_TOSHIBA3 0x13 /* named PCETB */
-#define ED_TYPE_TOSHIBA4 0x14 /* named PCETC */
-#define ED_TYPE_WD8003W 0x24
-#define ED_TYPE_WD8003EB 0x25
-#define ED_TYPE_WD8013W 0x26
-#define ED_TYPE_WD8013EP 0x27
-#define ED_TYPE_WD8013WC 0x28
-#define ED_TYPE_WD8013EPC 0x29
-#define ED_TYPE_SMC8216T 0x2a
-#define ED_TYPE_SMC8216C 0x2b
-#define ED_TYPE_WD8013EBP 0x2c
-
-/* Bit definitions in card ID */
-#define ED_WD_REV_MASK 0x1f /* Revision mask */
-#define ED_WD_SOFTCONFIG 0x20 /* Soft config */
-#define ED_WD_LARGERAM 0x40 /* Large RAM */
-#define ED_MICROCHANEL 0x80 /* Microchannel bus (vs. isa) */
-
-/*
- * Checksum total. All 8 bytes in station address PROM will add up to this
- */
-#ifdef TOSH_ETHER
-#define ED_WD_ROM_CHECKSUM_TOTAL 0xA5
-#else
-#define ED_WD_ROM_CHECKSUM_TOTAL 0xFF
-#endif
-
-#define ED_WD_NIC_OFFSET 0x10 /* I/O base offset to NIC */
-#define ED_WD_ASIC_OFFSET 0 /* I/O base offset to ASIC */
-#define ED_WD_IO_PORTS 32 /* # of i/o addresses used */
-
-#define ED_WD_PAGE_OFFSET 0 /* page offset for NIC access to mem */
-
-/*
- * Definitions for 3Com 3c503
- */
-#define ED_3COM_NIC_OFFSET 0
-#define ED_3COM_ASIC_OFFSET 0x400 /* offset to nic i/o regs */
-
-/*
- * XXX - The I/O address range is fragmented in the 3c503; this is the
- * number of regs at iobase.
- */
-#define ED_3COM_IO_PORTS 16 /* # of i/o addresses used */
-
-/* tx memory starts in second bank on 8bit cards */
-#define ED_3COM_TX_PAGE_OFFSET_8BIT 0x20
-
-/* tx memory starts in first bank on 16bit cards */
-#define ED_3COM_TX_PAGE_OFFSET_16BIT 0x0
-
-/* ...and rx memory starts in second bank */
-#define ED_3COM_RX_PAGE_OFFSET_16BIT 0x20
-
-
-/*
- * Page Start Register. Must match PSTART in NIC
- */
-#define ED_3COM_PSTR 0
-
-/*
- * Page Stop Register. Must match PSTOP in NIC
- */
-#define ED_3COM_PSPR 1
-
-/*
- * Drq Timer Register. Determines number of bytes to be transfered during
- * a DMA burst.
- */
-#define ED_3COM_DQTR 2
-
-/*
- * Base Configuration Register. Read-only register which contains the
- * board-configured I/O base address of the adapter. Bit encoded.
- */
-#define ED_3COM_BCFR 3
-
-#define ED_3COM_BCFR_2E0 0x01
-#define ED_3COM_BCFR_2A0 0x02
-#define ED_3COM_BCFR_280 0x04
-#define ED_3COM_BCFR_250 0x08
-#define ED_3COM_BCFR_350 0x10
-#define ED_3COM_BCFR_330 0x20
-#define ED_3COM_BCFR_310 0x40
-#define ED_3COM_BCFR_300 0x80
-
-/*
- * EPROM Configuration Register. Read-only register which contains the
- * board-configured memory base address. Bit encoded.
- */
-#define ED_3COM_PCFR 4
-
-#define ED_3COM_PCFR_C8000 0x10
-#define ED_3COM_PCFR_CC000 0x20
-#define ED_3COM_PCFR_D8000 0x40
-#define ED_3COM_PCFR_DC000 0x80
-
-/*
- * GA Configuration Register. Gate-Array Configuration Register.
- */
-#define ED_3COM_GACFR 5
-
-/*
- * mbs2 mbs1 mbs0 start address
- * 0 0 0 0x0000
- * 0 0 1 0x2000
- * 0 1 0 0x4000
- * 0 1 1 0x6000
- *
- * Note that with adapters with only 8K, the setting for 0x2000 must
- * always be used.
- */
-#define ED_3COM_GACFR_MBS0 0x01
-#define ED_3COM_GACFR_MBS1 0x02
-#define ED_3COM_GACFR_MBS2 0x04
-
-#define ED_3COM_GACFR_RSEL 0x08 /* enable shared memory */
-#define ED_3COM_GACFR_TEST 0x10 /* for GA testing */
-#define ED_3COM_GACFR_OWS 0x20 /* select 0WS access to GA */
-#define ED_3COM_GACFR_TCM 0x40 /* Mask DMA interrupts */
-#define ED_3COM_GACFR_NIM 0x80 /* Mask NIC interrupts */
-
-/*
- * Control Register. Miscellaneous control functions.
- */
-#define ED_3COM_CR 6
-
-#define ED_3COM_CR_RST 0x01 /* Reset GA and NIC */
-#define ED_3COM_CR_XSEL 0x02 /* Transceiver select. BNC=1(def) AUI=0 */
-#define ED_3COM_CR_EALO 0x04 /* window EA PROM 0-15 to I/O base */
-#define ED_3COM_CR_EAHI 0x08 /* window EA PROM 16-31 to I/O base */
-#define ED_3COM_CR_SHARE 0x10 /* select interrupt sharing option */
-#define ED_3COM_CR_DBSEL 0x20 /* Double buffer select */
-#define ED_3COM_CR_DDIR 0x40 /* DMA direction select */
-#define ED_3COM_CR_START 0x80 /* Start DMA controller */
-
-/*
- * Status Register. Miscellaneous status information.
- */
-#define ED_3COM_STREG 7
-
-#define ED_3COM_STREG_REV 0x07 /* GA revision */
-#define ED_3COM_STREG_DIP 0x08 /* DMA in progress */
-#define ED_3COM_STREG_DTC 0x10 /* DMA terminal count */
-#define ED_3COM_STREG_OFLW 0x20 /* Overflow */
-#define ED_3COM_STREG_UFLW 0x40 /* Underflow */
-#define ED_3COM_STREG_DPRDY 0x80 /* Data port ready */
-
-/*
- * Interrupt/DMA Configuration Register
- */
-#define ED_3COM_IDCFR 8
-
-#define ED_3COM_IDCFR_DRQ0 0x01 /* DMA request 1 select */
-#define ED_3COM_IDCFR_DRQ1 0x02 /* DMA request 2 select */
-#define ED_3COM_IDCFR_DRQ2 0x04 /* DMA request 3 select */
-#define ED_3COM_IDCFR_UNUSED 0x08 /* not used */
-#define ED_3COM_IDCFR_IRQ2 0x10 /* Interrupt request 2 select */
-#define ED_3COM_IDCFR_IRQ3 0x20 /* Interrupt request 3 select */
-#define ED_3COM_IDCFR_IRQ4 0x40 /* Interrupt request 4 select */
-#define ED_3COM_IDCFR_IRQ5 0x80 /* Interrupt request 5 select */
-
-/*
- * DMA Address Register MSB
- */
-#define ED_3COM_DAMSB 9
-
-/*
- * DMA Address Register LSB
- */
-#define ED_3COM_DALSB 0x0a
-
-/*
- * Vector Pointer Register 2
- */
-#define ED_3COM_VPTR2 0x0b
-
-/*
- * Vector Pointer Register 1
- */
-#define ED_3COM_VPTR1 0x0c
-
-/*
- * Vector Pointer Register 0
- */
-#define ED_3COM_VPTR0 0x0d
-
-/*
- * Register File Access MSB
- */
-#define ED_3COM_RFMSB 0x0e
-
-/*
- * Register File Access LSB
- */
-#define ED_3COM_RFLSB 0x0f
-
-/*
- * Definitions for Novell NE1000/2000 boards
- */
-
-/*
- * Board type codes
- */
-#define ED_TYPE_NE1000 0x01
-#define ED_TYPE_NE2000 0x02
-
-/*
- * Register offsets/total
- */
-#define ED_NOVELL_NIC_OFFSET 0x00
-#define ED_NOVELL_ASIC_OFFSET 0x10
-#define ED_NOVELL_IO_PORTS 32
-
-/*
- * Remote DMA data register; for reading or writing to the NIC mem
- * via programmed I/O (offset from ASIC base)
- */
-#define ED_NOVELL_DATA 0x00
-
-/*
- * Reset register; reading from this register causes a board reset
- */
-#define ED_NOVELL_RESET 0x0f
-
-#define ED_TYPE_PCMCIA 0x01
-#define ED_PCMCIA_PAGE_OFFSET 0x40 /* True for all cards I have seen */
-#define ED_PCMCIA_IO_PORTS 32
-#define ED_PCMCIA_RESET 0xF /* Reset port */
diff --git a/usr.sbin/pccard/misc/sys/pccard/lkm_ed.c b/usr.sbin/pccard/misc/sys/pccard/lkm_ed.c
deleted file mode 100644
index 7bc1ec7..0000000
--- a/usr.sbin/pccard/misc/sys/pccard/lkm_ed.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Loadable kernel module if_ed driver
- * 11 July 1995 Andrew McRae
- *
- *-------------------------------------------------------------------------
- *
- * Copyright (c) 1995 Andrew McRae. All rights reserved.
- *
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
- */
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/conf.h>
-#include <sys/mount.h>
-#include <sys/sysent.h>
-#include <sys/exec.h>
-#include <sys/lkm.h>
-#include <sys/errno.h>
-
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-
-#include <pccard/card.h>
-#include <pccard/slot.h>
-
-/*
- * This defines the lkm_misc module use by modload
- * to define the module name.
- */
- MOD_MISC( "ed")
-
-
-int edintr(struct pccard_dev *); /* Interrupt handler */
-void edunload(struct pccard_dev *); /* Disable driver */
-void edsuspend(struct pccard_dev *); /* Suspend driver */
-int edinit(struct pccard_dev *, int); /* init device */
-
-static struct pccard_drv ed_info =
- {
- "ed",
- edintr,
- edunload,
- edsuspend,
- edinit,
- 0,
- &net_imask
- };
-static int opened; /* Rather minimal device state... */
-
-/*
- * Module handler that processes loads and unloads.
- * Once the module is loaded, the add driver routine is called
- * to register the driver.
- * If an unload is requested the remove driver routine is
- * called to deregister the driver before unloading.
- */
-static int
-ed_handle( lkmtp, cmd)
-struct lkm_table *lkmtp;
-int cmd;
-{
- int i;
- struct lkm_misc *args = lkmtp->private.lkm_misc;
- int err = 0; /* default = success*/
-
- switch( cmd) {
- case LKM_E_LOAD:
-
- /*
- * Don't load twice! (lkmexists() is exported by kern_lkm.c)
- */
- if( lkmexists( lkmtp))
- return( EEXIST);
-/*
- * Now register the driver
- */
- pccard_add_driver(&ed_info);
- break; /* Success*/
-/*
- * Attempt to deregister the driver.
- */
- case LKM_E_UNLOAD:
- pccard_remove_driver(&ed_info);
- break; /* Success*/
-
- default: /* we only understand load/unload*/
- err = EINVAL;
- break;
- }
-
- return( err);
-}
-
-
-/*
- * External entry point; should generally match name of .o file. The
- * arguments are always the same for all loaded modules. The "load",
- * "unload", and "stat" functions in "DISPATCH" will be called under
- * their respective circumstances unless their value is "nosys". If
- * called, they are called with the same arguments (cmd is included to
- * allow the use of a single function, ver is included for version
- * matching between modules and the kernel loader for the modules).
- *
- * Since we expect to link in the kernel and add external symbols to
- * the kernel symbol name space in a future version, generally all
- * functions used in the implementation of a particular module should
- * be static unless they are expected to be seen in other modules or
- * to resolve unresolved symbols alread existing in the kernel (the
- * second case is not likely to ever occur).
- *
- * The entry point should return 0 unless it is refusing load (in which
- * case it should return an errno from errno.h).
- */
-int
-lkm_ed(lkmtp, cmd, ver)
-struct lkm_table *lkmtp;
-int cmd;
-int ver;
-{
- DISPATCH(lkmtp,cmd,ver,ed_handle,ed_handle,nosys)
-}
diff --git a/usr.sbin/pccard/misc/sys/pccard/sio.c b/usr.sbin/pccard/misc/sys/pccard/sio.c
deleted file mode 100644
index 73d0da2..0000000
--- a/usr.sbin/pccard/misc/sys/pccard/sio.c
+++ /dev/null
@@ -1,2463 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * 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 the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND 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 REGENTS OR 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.
- *
- * from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.95 1995/04/15 21:45:16 bde Exp $
- */
-
-#include "sio.h"
-#if NSIO > 0
-/*
- * Serial driver, based on 386BSD-0.1 com driver.
- * Mostly rewritten to use pseudo-DMA.
- * Works for National Semiconductor NS8250-NS16550AF UARTs.
- * COM driver, based on HP dca driver.
- *
- * Changes for PC-Card integration:
- * - Added PC-Card driver table and handlers
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/reboot.h>
-#include <sys/ioctl.h>
-#define TTYDEFCHARS /* XXX TK2.0 */
-#include <sys/tty.h>
-#undef TTYDEFCHARS
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/conf.h>
-#include <sys/dkstat.h>
-#include <sys/file.h>
-#include <sys/uio.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/syslog.h>
-#include <sys/devconf.h>
-
-#include <machine/clock.h>
-
-#include <i386/isa/icu.h> /* XXX just to get at `imen' */
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/sioreg.h>
-#include <i386/isa/ic/ns16550.h>
-
-#include "crd.h"
-#if NCRD > 0
-#include <pccard/card.h>
-#include <pccard/slot.h>
-#endif /* NCRD > 0 */
-
-/*
- * XXX temporary kludges for 2.0 (XXX TK2.0).
- */
-#define TSA_CARR_ON(tp) ((void *)&(tp)->t_rawq)
-#define TSA_OCOMPLETE(tp) ((void *)&(tp)->t_outq)
-#define TSA_OLOWAT(tp) ((void *)&(tp)->t_outq)
-void
-termioschars(t)
- struct termios *t;
-{
-
- bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
-}
-
-#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
-#define RB_I_HIGH_WATER (TTYHOG - 2 * RS_IBUFSIZE)
-#define RS_IBUFSIZE 256
-
-#define CALLOUT_MASK 0x80
-#define CONTROL_MASK 0x60
-#define CONTROL_INIT_STATE 0x20
-#define CONTROL_LOCK_STATE 0x40
-#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
-#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK)
-#define MINOR_TO_UNIT(mynor) ((mynor) & ~MINOR_MAGIC_MASK)
-
-#ifdef COM_MULTIPORT
-/* checks in flags for multiport and which is multiport "master chip"
- * for a given card
- */
-#define COM_ISMULTIPORT(dev) ((dev)->id_flags & 0x01)
-#define COM_MPMASTER(dev) (((dev)->id_flags >> 8) & 0x0ff)
-#define COM_NOTAST4(dev) ((dev)->id_flags & 0x04)
-#endif /* COM_MULTIPORT */
-
-#define COM_NOFIFO(dev) ((dev)->id_flags & 0x02)
-#define COM_VERBOSE(dev) ((dev)->id_flags & 0x80)
-
-#define com_scr 7 /* scratch register for 16450-16550 (R/W) */
-
-/*
- * Input buffer watermarks.
- * The external device is asked to stop sending when the buffer exactly reaches
- * high water, or when the high level requests it.
- * The high level is notified immediately (rather than at a later clock tick)
- * when this watermark is reached.
- * The buffer size is chosen so the watermark should almost never be reached.
- * The low watermark is invisibly 0 since the buffer is always emptied all at
- * once.
- */
-#define RS_IHIGHWATER (3 * RS_IBUFSIZE / 4)
-
-/*
- * com state bits.
- * (CS_BUSY | CS_TTGO) and (CS_BUSY | CS_TTGO | CS_ODEVREADY) must be higher
- * than the other bits so that they can be tested as a group without masking
- * off the low bits.
- *
- * The following com and tty flags correspond closely:
- * CS_BUSY = TS_BUSY (maintained by comstart() and comflush())
- * CS_TTGO = ~TS_TTSTOP (maintained by comstart() and siostop())
- * CS_CTS_OFLOW = CCTS_OFLOW (maintained by comparam())
- * CS_RTS_IFLOW = CRTS_IFLOW (maintained by comparam())
- * TS_FLUSH is not used.
- * XXX I think TIOCSETA doesn't clear TS_TTSTOP when it clears IXON.
- * XXX CS_*FLOW should be CF_*FLOW in com->flags (control flags not state).
- */
-#define CS_BUSY 0x80 /* output in progress */
-#define CS_TTGO 0x40 /* output not stopped by XOFF */
-#define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */
-#define CS_CHECKMSR 1 /* check of MSR scheduled */
-#define CS_CTS_OFLOW 2 /* use CTS output flow control */
-#define CS_DTR_OFF 0x10 /* DTR held off */
-#define CS_ODONE 4 /* output completed */
-#define CS_RTS_IFLOW 8 /* use RTS input flow control */
-
-static char const * const error_desc[] = {
-#define CE_OVERRUN 0
- "silo overflow",
-#define CE_INTERRUPT_BUF_OVERFLOW 1
- "interrupt-level buffer overflow",
-#define CE_TTY_BUF_OVERFLOW 2
- "tty-level buffer overflow",
-};
-
-#define CE_NTYPES 3
-#define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum])
-
-/* types. XXX - should be elsewhere */
-typedef u_int Port_t; /* hardware port */
-typedef u_char bool_t; /* boolean */
-
-/* com device structure */
-struct com_s {
- u_char state; /* miscellaneous flag bits */
- bool_t active_out; /* nonzero if the callout device is open */
- u_char cfcr_image; /* copy of value written to CFCR */
- u_char ftl; /* current rx fifo trigger level */
- u_char ftl_init; /* ftl_max for next open() */
- u_char ftl_max; /* maximum ftl for curent open() */
- bool_t hasfifo; /* nonzero for 16550 UARTs */
- u_char mcr_image; /* copy of value written to MCR */
-#ifdef COM_MULTIPORT
- bool_t multiport; /* is this unit part of a multiport device? */
-#endif /* COM_MULTIPORT */
- bool_t no_irq; /* nonzero if irq is not attached */
- bool_t poll; /* nonzero if polling is required */
- int unit; /* unit number */
- int dtr_wait; /* time to hold DTR down on close (* 1/hz) */
- u_int tx_fifo_size;
- u_int wopeners; /* # processes waiting for DCD in open() */
-
- /*
- * The high level of the driver never reads status registers directly
- * because there would be too many side effects to handle conveniently.
- * Instead, it reads copies of the registers stored here by the
- * interrupt handler.
- */
- u_char last_modem_status; /* last MSR read by intr handler */
- u_char prev_modem_status; /* last MSR handled by high level */
-
- u_char hotchar; /* ldisc-specific char to be handled ASAP */
- u_char *ibuf; /* start of input buffer */
- u_char *ibufend; /* end of input buffer */
- u_char *ihighwater; /* threshold in input buffer */
- u_char *iptr; /* next free spot in input buffer */
-
- u_char *obufend; /* end of output buffer */
- u_char *optr; /* next char to output */
-
- Port_t data_port; /* i/o ports */
- Port_t int_id_port;
- Port_t iobase;
- Port_t modem_ctl_port;
- Port_t line_status_port;
- Port_t modem_status_port;
-
- struct tty *tp; /* cross reference */
-
- /* Initial state. */
- struct termios it_in; /* should be in struct tty */
- struct termios it_out;
-
- /* Lock state. */
- struct termios lt_in; /* should be in struct tty */
- struct termios lt_out;
-
- bool_t do_timestamp;
- struct timeval timestamp;
-
- u_long bytes_in; /* statistics */
- u_long bytes_out;
- u_int delta_error_counts[CE_NTYPES];
- u_long error_counts[CE_NTYPES];
-
- /*
- * Ping-pong input buffers. The extra factor of 2 in the sizes is
- * to allow for an error byte for each input byte.
- */
-#define CE_INPUT_OFFSET RS_IBUFSIZE
- u_char ibuf1[2 * RS_IBUFSIZE];
- u_char ibuf2[2 * RS_IBUFSIZE];
-
- /*
- * Output buffer. Someday we should avoid copying. Twice.
- */
- u_char obuf[256];
-};
-
-/*
- * The public functions in the com module ought to be declared in a com-driver
- * system header.
- */
-
-/* Interrupt handling entry points. */
-void siointr __P((int unit));
-void siopoll __P((void));
-
-/* Device switch entry points. */
-int sioopen __P((dev_t dev, int oflags, int devtype,
- struct proc *p));
-int sioclose __P((dev_t dev, int fflag, int devtype,
- struct proc *p));
-int sioread __P((dev_t dev, struct uio *uio, int ioflag));
-int siowrite __P((dev_t dev, struct uio *uio, int ioflag));
-int sioioctl __P((dev_t dev, int cmd, caddr_t data,
- int fflag, struct proc *p));
-void siostop __P((struct tty *tp, int rw));
-#define sioreset noreset
-int sioselect __P((dev_t dev, int rw, struct proc *p));
-#define siommap nommap
-#define siostrategy nostrategy
-
-/* Console device entry points. */
-int siocncheckc __P((dev_t dev));
-int siocngetc __P((dev_t dev));
-struct consdev;
-void siocninit __P((struct consdev *cp));
-void siocnprobe __P((struct consdev *cp));
-void siocnputc __P((dev_t dev, int c));
-
-static int sioattach __P((struct isa_device *dev));
-static timeout_t siodtrwakeup;
-static void comflush __P((struct com_s *com));
-static void comhardclose __P((struct com_s *com));
-static void siointr1 __P((struct com_s *com));
-static void commctl __P((struct com_s *com, int bits, int how));
-static int comparam __P((struct tty *tp, struct termios *t));
-static int sioprobe __P((struct isa_device *dev));
-static void sioregisterdev __P((struct isa_device *id));
-static void comstart __P((struct tty *tp));
-static timeout_t comwakeup;
-static int tiocm_xxx2mcr __P((int tiocm_xxx));
-static void disc_optim __P((struct tty *tp, struct termios *t, struct com_s *com));
-
-#ifdef DSI_SOFT_MODEM
-static int LoadSoftModem __P((int unit,int base_io, u_long size, u_char *ptr));
-#endif /* DSI_SOFT_MODEM */
-
-/* table and macro for fast conversion from a unit number to its com struct */
-static struct com_s *p_com_addr[NSIO];
-#define com_addr(unit) (p_com_addr[unit])
-
-static struct timeval intr_timestamp;
-
-struct isa_driver siodriver = {
- sioprobe, sioattach, "sio"
-};
-
-#ifdef COMCONSOLE
-#undef COMCONSOLE
-#define COMCONSOLE 1
-#else
-#define COMCONSOLE 0
-#endif
-
-static int comconsole = CONUNIT;
-static speed_t comdefaultrate = TTYDEF_SPEED;
-static u_int com_events; /* input chars + weighted output completions */
-static int commajor;
-#if 0 /* XXX TK2.0 */
-struct tty *sio_tty[NSIO];
-#else
-struct tty sio_tty[NSIO];
-#endif
-
-#ifdef KGDB
-#include <machine/remote-sl.h>
-
-extern int kgdb_dev;
-extern int kgdb_rate;
-extern int kgdb_debug_init;
-#endif
-
-static struct speedtab comspeedtab[] = {
- 0, 0,
- 50, COMBRD(50),
- 75, COMBRD(75),
- 110, COMBRD(110),
- 134, COMBRD(134),
- 150, COMBRD(150),
- 200, COMBRD(200),
- 300, COMBRD(300),
- 600, COMBRD(600),
- 1200, COMBRD(1200),
- 1800, COMBRD(1800),
- 2400, COMBRD(2400),
- 4800, COMBRD(4800),
- 9600, COMBRD(9600),
- 19200, COMBRD(19200),
- 38400, COMBRD(38400),
- 57600, COMBRD(57600),
- 115200, COMBRD(115200),
- -1, -1
-};
-
-/* XXX - configure this list */
-static Port_t likely_com_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, };
-
-static struct kern_devconf kdc_sio[NSIO] = { {
- 0, 0, 0, /* filled in by dev_attach */
- "sio", 0, { MDDT_ISA, 0, "tty" },
- isa_generic_externalize, 0, 0, ISA_EXTERNALLEN,
- &kdc_isa0, /* parent */
- 0, /* parentdata */
- DC_UNCONFIGURED, /* state */
- "RS-232 serial port",
- DC_CLS_SERIAL /* class */
-} };
-#if NCRD > 0
-/*
- * PC-Card (PCMCIA) specific code.
- */
-static int card_intr(struct pccard_dev *); /* Interrupt handler */
-void siounload(struct pccard_dev *); /* Disable driver */
-void siosuspend(struct pccard_dev *); /* Suspend driver */
-static int sioinit(struct pccard_dev *, int); /* init device */
-
-static struct pccard_drv sio_info =
- {
- "sio",
- card_intr,
- siounload,
- siosuspend,
- sioinit,
- 0, /* Attributes - presently unused */
- &tty_imask /* Interrupt mask for device */
- /* This should also include net_imask?? */
- };
-/*
- * Called when a power down is wanted. Shuts down the
- * device and configures the device as unavailable (but
- * still loaded...). A resume is done by calling
- * sioinit with first=0. This is called when the user suspends
- * the system, or the APM code suspends the system.
- */
-void
-siosuspend(struct pccard_dev *dp)
-{
- printf("sio%d: suspending\n", dp->isahd.id_unit);
-}
-/*
- * Initialize the device - called from Slot manager.
- * if first is set, then initially check for
- * the device's existence before initialising it.
- * Once initialised, the device table may be set up.
- */
-int
-sioinit(struct pccard_dev *dp, int first)
-{
-/*
- * validate unit number.
- */
- if (first)
- {
- if (dp->isahd.id_unit >= NSIO)
- return(ENODEV);
-/*
- * Make sure it isn't already probed.
- */
- if (com_addr(dp->isahd.id_unit))
- return(EBUSY);
-/*
- * Probe the device. If a value is returned, the
- * device was found at the location.
- */
- if (sioprobe(&dp->isahd)==0)
- return(ENXIO);
- if (sioattach(&dp->isahd)==0)
- return(ENXIO);
- }
-/*
- * XXX TODO:
- * If it was already inited before, the device structure
- * should be already initialised. Here we should
- * reset (and possibly restart) the hardware, but
- * I am not sure of the best way to do this...
- */
- return(0);
-}
-/*
- * siounload - unload the driver and clear the table.
- * XXX TODO:
- * This is called usually when the card is ejected, but
- * can be caused by the modunload of a controller driver.
- * The idea is reset the driver's view of the device
- * and ensure that any driver entry points such as
- * read and write do not hang.
- */
-void
-siounload(struct pccard_dev *dp)
-{
- printf("sio%d: unload\n", dp->isahd.id_unit);
-}
-
-/*
- * card_intr - Shared interrupt called from
- * front end of PC-Card handler.
- */
-static int
-card_intr(struct pccard_dev *dp)
-{
- siointr1(com_addr(dp->isahd.id_unit));
- return(1);
-}
-#endif /* NCRD > 0 */
-
-static void
-sioregisterdev(id)
- struct isa_device *id;
-{
- int unit;
-
- unit = id->id_unit;
-/*
- * If already registered, don't try to re-register.
- */
- if (kdc_sio[unit].kdc_isa)
- return;
- if (unit != 0)
- kdc_sio[unit] = kdc_sio[0];
- kdc_sio[unit].kdc_unit = unit;
- kdc_sio[unit].kdc_isa = id;
- dev_attach(&kdc_sio[unit]);
-}
-
-static int
-sioprobe(dev)
- struct isa_device *dev;
-{
- static bool_t already_init;
- Port_t *com_ptr;
- bool_t failures[10];
- int fn;
- struct isa_device *idev;
- Port_t iobase;
- u_char mcr_image;
- int result;
-
- sioregisterdev(dev);
-
- if (!already_init) {
- /*
- * Turn off MCR_IENABLE for all likely serial ports. An unused
- * port with its MCR_IENABLE gate open will inhibit interrupts
- * from any used port that shares the interrupt vector.
- * XXX the gate enable is elsewhere for some multiports.
- */
- for (com_ptr = likely_com_ports;
- com_ptr < &likely_com_ports[sizeof likely_com_ports
- / sizeof likely_com_ports[0]];
- ++com_ptr)
- outb(*com_ptr + com_mcr, 0);
-#if NCRD > 0
-/*
- * If PC-Card probe required, then register driver with
- * slot manager.
- */
- pccard_add_driver(&sio_info);
-#endif /* NCRD > 0 */
- already_init = TRUE;
- }
-
- /*
- * If the device is on a multiport card and has an AST/4
- * compatible interrupt control register, initialize this
- * register and prepare to leave MCR_IENABLE clear in the mcr.
- * Otherwise, prepare to set MCR_IENABLE in the mcr.
- * Point idev to the device struct giving the correct id_irq.
- * This is the struct for the master device if there is one.
- */
- idev = dev;
- mcr_image = MCR_IENABLE;
-#ifdef COM_MULTIPORT
- if (COM_ISMULTIPORT(dev)) {
- idev = find_isadev(isa_devtab_tty, &siodriver,
- COM_MPMASTER(dev));
- if (idev == NULL) {
- printf("sio%d: master device %d not configured\n",
- dev->id_unit, COM_MPMASTER(dev));
- return (0);
- }
- if (!COM_NOTAST4(dev)) {
- outb(idev->id_iobase + com_scr,
- idev->id_irq ? 0x80 : 0);
- mcr_image = 0;
- }
- }
-#endif /* COM_MULTIPORT */
- if (idev->id_irq == 0)
- mcr_image = 0;
-
- bzero(failures, sizeof failures);
- iobase = dev->id_iobase;
-
- /*
- * We don't want to get actual interrupts, just masked ones.
- * Interrupts from this line should already be masked in the ICU,
- * but mask them in the processor as well in case there are some
- * (misconfigured) shared interrupts.
- */
- disable_intr();
-/* EXTRA DELAY? */
-
- /*
- * XXX DELAY() reenables CPU interrupts. This is a problem for
- * shared interrupts after the first device using one has been
- * successfully probed - config_isadev() has enabled the interrupt
- * in the ICU.
- */
- outb(IO_ICU1 + 1, 0xff);
-
- /*
- * Initialize the speed and the word size and wait long enough to
- * drain the maximum of 16 bytes of junk in device output queues.
- * The speed is undefined after a master reset and must be set
- * before relying on anything related to output. There may be
- * junk after a (very fast) soft reboot and (apparently) after
- * master reset.
- * XXX what about the UART bug avoided by waiting in comparam()?
- * We don't want to to wait long enough to drain at 2 bps.
- */
- outb(iobase + com_cfcr, CFCR_DLAB);
- outb(iobase + com_dlbl, COMBRD(9600) & 0xff);
- outb(iobase + com_dlbh, (u_int) COMBRD(9600) >> 8);
- outb(iobase + com_cfcr, CFCR_8BITS);
- DELAY((16 + 1) * 1000000 / (9600 / 10));
-
- /*
- * Enable the interrupt gate and disable device interupts. This
- * should leave the device driving the interrupt line low and
- * guarantee an edge trigger if an interrupt can be generated.
- */
-/* EXTRA DELAY? */
- outb(iobase + com_mcr, mcr_image);
- outb(iobase + com_ier, 0);
-
- /*
- * Attempt to set loopback mode so that we can send a null byte
- * without annoying any external device.
- */
-/* EXTRA DELAY? */
- outb(iobase + com_mcr, mcr_image | MCR_LOOPBACK);
-
- /*
- * Attempt to generate an output interrupt. On 8250's, setting
- * IER_ETXRDY generates an interrupt independent of the current
- * setting and independent of whether the THR is empty. On 16450's,
- * setting IER_ETXRDY generates an interrupt independent of the
- * current setting. On 16550A's, setting IER_ETXRDY only
- * generates an interrupt when IER_ETXRDY is not already set.
- */
- outb(iobase + com_ier, IER_ETXRDY);
-
- /*
- * On some 16x50 incompatibles, setting IER_ETXRDY doesn't generate
- * an interrupt. They'd better generate one for actually doing
- * output. Loopback may be broken on the same incompatibles but
- * it's unlikely to do more than allow the null byte out.
- */
- outb(iobase + com_data, 0);
- DELAY((1 + 2) * 1000000 / (9600 / 10));
-
- /*
- * Turn off loopback mode so that the interrupt gate works again
- * (MCR_IENABLE was hidden). This should leave the device driving
- * an interrupt line high. It doesn't matter if the interrupt
- * line oscillates while we are not looking at it, since interrupts
- * are disabled.
- */
-/* EXTRA DELAY? */
- outb(iobase + com_mcr, mcr_image);
-
- /*
- * Check that
- * o the CFCR, IER and MCR in UART hold the values written to them
- * (the values happen to be all distinct - this is good for
- * avoiding false positive tests from bus echoes).
- * o an output interrupt is generated and its vector is correct.
- * o the interrupt goes away when the IIR in the UART is read.
- */
-/* EXTRA DELAY? */
- failures[0] = inb(iobase + com_cfcr) - CFCR_8BITS;
- failures[1] = inb(iobase + com_ier) - IER_ETXRDY;
- failures[2] = inb(iobase + com_mcr) - mcr_image;
- if (idev->id_irq != 0)
- failures[3] = isa_irq_pending(idev) ? 0 : 1;
- failures[4] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_TXRDY;
- if (idev->id_irq != 0)
- failures[5] = isa_irq_pending(idev) ? 1 : 0;
- failures[6] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
-
- /*
- * Turn off all device interrupts and check that they go off properly.
- * Leave MCR_IENABLE alone. For ports without a master port, it gates
- * the OUT2 output of the UART to
- * the ICU input. Closing the gate would give a floating ICU input
- * (unless there is another device driving at) and spurious interrupts.
- * (On the system that this was first tested on, the input floats high
- * and gives a (masked) interrupt as soon as the gate is closed.)
- */
- outb(iobase + com_ier, 0);
- outb(iobase + com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */
- failures[7] = inb(iobase + com_ier);
- if (idev->id_irq != 0)
- failures[8] = isa_irq_pending(idev) ? 1 : 0;
- failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
-
- outb(IO_ICU1 + 1, imen); /* XXX */
- enable_intr();
-
- result = IO_COMSIZE;
- for (fn = 0; fn < sizeof failures; ++fn)
- if (failures[fn]) {
- outb(iobase + com_mcr, 0);
- result = 0;
- if (COM_VERBOSE(dev))
- printf("sio%d: probe test %d failed\n",
- dev->id_unit, fn);
- }
- return (result);
-}
-
-static int
-sioattach(isdp)
- struct isa_device *isdp;
-{
- struct com_s *com;
- static bool_t comwakeup_started = FALSE;
- Port_t iobase;
- int s;
- int unit;
-
- isdp->id_ri_flags |= RI_FAST;
- iobase = isdp->id_iobase;
- unit = isdp->id_unit;
- com = malloc(sizeof *com, M_TTYS, M_NOWAIT);
- if (com == NULL)
- return (0);
-
- /*
- * sioprobe() has initialized the device registers as follows:
- * o cfcr = CFCR_8BITS.
- * It is most important that CFCR_DLAB is off, so that the
- * data port is not hidden when we enable interrupts.
- * o ier = 0.
- * Interrupts are only enabled when the line is open.
- * o mcr = MCR_IENABLE, or 0 if the port has AST/4 compatible
- * interrupt control register or the config specifies no irq.
- * Keeping MCR_DTR and MCR_RTS off might stop the external
- * device from sending before we are ready.
- */
- bzero(com, sizeof *com);
- com->unit = unit;
- com->cfcr_image = CFCR_8BITS;
- com->dtr_wait = 3 * hz;
- com->no_irq = isdp->id_irq == 0;
- com->tx_fifo_size = 1;
- com->iptr = com->ibuf = com->ibuf1;
- com->ibufend = com->ibuf1 + RS_IBUFSIZE;
- com->ihighwater = com->ibuf1 + RS_IHIGHWATER;
- com->iobase = iobase;
- com->data_port = iobase + com_data;
- com->int_id_port = iobase + com_iir;
- com->modem_ctl_port = iobase + com_mcr;
- com->mcr_image = inb(com->modem_ctl_port);
- com->line_status_port = iobase + com_lsr;
- com->modem_status_port = iobase + com_msr;
-
- /*
- * We don't use all the flags from <sys/ttydefaults.h> since they
- * are only relevant for logins. It's important to have echo off
- * initially so that the line doesn't start blathering before the
- * echo flag can be turned off.
- */
- com->it_in.c_iflag = 0;
- com->it_in.c_oflag = 0;
- com->it_in.c_cflag = TTYDEF_CFLAG;
- com->it_in.c_lflag = 0;
- if (unit == comconsole && (COMCONSOLE || boothowto & RB_SERIAL)) {
- com->it_in.c_iflag = TTYDEF_IFLAG;
- com->it_in.c_oflag = TTYDEF_OFLAG;
- com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL;
- com->it_in.c_lflag = TTYDEF_LFLAG;
- com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
- }
- termioschars(&com->it_in);
- com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
- com->it_out = com->it_in;
-
- /* attempt to determine UART type */
- printf("sio%d: type", unit);
-
-#ifdef DSI_SOFT_MODEM
- if((inb(iobase+7) ^ inb(iobase+7)) & 0x80) {
- printf(" Digicom Systems, Inc. SoftModem");
- kdc_sio[unit].kdc_description =
- "Serial port: Digicom Systems SoftModem";
- goto determined_type;
- }
-#endif /* DSI_SOFT_MODEM */
-
-#ifdef COM_MULTIPORT
- if (!COM_ISMULTIPORT(isdp))
-#endif
- {
- u_char scr;
- u_char scr1;
- u_char scr2;
-
- scr = inb(iobase + com_scr);
- outb(iobase + com_scr, 0xa5);
- scr1 = inb(iobase + com_scr);
- outb(iobase + com_scr, 0x5a);
- scr2 = inb(iobase + com_scr);
- outb(iobase + com_scr, scr);
- if (scr1 != 0xa5 || scr2 != 0x5a) {
- printf(" 8250");
- kdc_sio[unit].kdc_description =
- "Serial port: National 8250 or compatible";
- goto determined_type;
- }
- }
- outb(iobase + com_fifo, FIFO_ENABLE | FIFO_TRIGGER_14);
- DELAY(100);
- switch (inb(com->int_id_port) & IIR_FIFO_MASK) {
- case FIFO_TRIGGER_1:
- printf(" 16450");
- kdc_sio[unit].kdc_description =
- "Serial port: National 16450 or compatible";
- break;
- case FIFO_TRIGGER_4:
- printf(" 16450?");
- kdc_sio[unit].kdc_description =
- "Serial port: maybe National 16450";
- break;
- case FIFO_TRIGGER_8:
- printf(" 16550?");
- kdc_sio[unit].kdc_description =
- "Serial port: maybe National 16550";
- break;
- case FIFO_TRIGGER_14:
- printf(" 16550A");
- if (COM_NOFIFO(isdp)) {
- printf(" fifo disabled");
- kdc_sio[unit].kdc_description =
- "Serial port: National 16550A, FIFO disabled";
- } else {
- com->hasfifo = TRUE;
- com->ftl_init = FIFO_TRIGGER_14;
- com->tx_fifo_size = 16;
- kdc_sio[unit].kdc_description =
- "Serial port: National 16550A or compatible";
- }
- break;
- }
- outb(iobase + com_fifo, 0);
-determined_type: ;
-
-#ifdef COM_MULTIPORT
- if (COM_ISMULTIPORT(isdp)) {
- com->multiport = TRUE;
- printf(" (multiport");
- if (unit == COM_MPMASTER(isdp))
- printf(" master");
- printf(")");
- com->no_irq = find_isadev(isa_devtab_tty, &siodriver,
- COM_MPMASTER(isdp))->id_irq == 0;
- }
-#endif /* COM_MULTIPORT */
- printf("\n");
-
- kdc_sio[unit].kdc_state =
- (unit == comconsole && (COMCONSOLE || boothowto & RB_SERIAL))
- ? DC_BUSY : DC_IDLE;
-
-#ifdef KGDB
- if (kgdb_dev == makedev(commajor, unit)) {
- if (unit == comconsole && (COMCONSOLE || boothowto & RB_SERIAL))
- kgdb_dev = -1; /* can't debug over console port */
- else {
- int divisor;
-
- /*
- * XXX now unfinished and broken. Need to do
- * something more like a full open(). There's no
- * suitable interrupt handler so don't enable device
- * interrupts. Watch out for null tp's.
- */
- outb(iobase + com_cfcr, CFCR_DLAB);
- divisor = ttspeedtab(kgdb_rate, comspeedtab);
- outb(iobase + com_dlbl, divisor & 0xFF);
- outb(iobase + com_dlbh, (u_int) divisor >> 8);
- outb(iobase + com_cfcr, CFCR_8BITS);
- outb(com->modem_status_port,
- com->mcr_image |= MCR_DTR | MCR_RTS);
-
- if (kgdb_debug_init) {
- /*
- * Print prefix of device name,
- * let kgdb_connect print the rest.
- */
- printf("sio%d: ", unit);
- kgdb_connect(1);
- } else
- printf("sio%d: kgdb enabled\n", unit);
- }
- }
-#endif
-
- s = spltty();
- com_addr(unit) = com;
- splx(s);
- if (!comwakeup_started) {
- comwakeup((void *)NULL);
- comwakeup_started = TRUE;
- }
- return (1);
-}
-
-/* ARGSUSED */
-int
-sioopen(dev, flag, mode, p)
- dev_t dev;
- int flag;
- int mode;
- struct proc *p;
-{
- struct com_s *com;
- int error;
- Port_t iobase;
- int mynor;
- int s;
- struct tty *tp;
- int unit;
-
- mynor = minor(dev);
- unit = MINOR_TO_UNIT(mynor);
- if ((u_int) unit >= NSIO || (com = com_addr(unit)) == NULL)
- return (ENXIO);
- if (mynor & CONTROL_MASK)
- return (0);
-#if 0 /* XXX TK2.0 */
- tp = com->tp = sio_tty[unit] = ttymalloc(sio_tty[unit]);
-#else
- tp = com->tp = &sio_tty[unit];
-#endif
- s = spltty();
- /*
- * We jump to this label after all non-interrupted sleeps to pick
- * up any changes of the device state.
- */
-open_top:
- while (com->state & CS_DTR_OFF) {
- error = tsleep(&com->dtr_wait, TTIPRI | PCATCH, "siodtr", 0);
- if (error != 0)
- goto out;
- }
- kdc_sio[unit].kdc_state = DC_BUSY;
- if (tp->t_state & TS_ISOPEN) {
- /*
- * The device is open, so everything has been initialized.
- * Handle conflicts.
- */
- if (mynor & CALLOUT_MASK) {
- if (!com->active_out) {
- error = EBUSY;
- goto out;
- }
- } else {
- if (com->active_out) {
- if (flag & O_NONBLOCK) {
- error = EBUSY;
- goto out;
- }
- error = tsleep(&com->active_out,
- TTIPRI | PCATCH, "siobi", 0);
- if (error != 0)
- goto out;
- goto open_top;
- }
- }
- if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
- error = EBUSY;
- goto out;
- }
- } else {
- /*
- * The device isn't open, so there are no conflicts.
- * Initialize it. Initialization is done twice in many
- * cases: to preempt sleeping callin opens if we are
- * callout, and to complete a callin open after DCD rises.
- */
- tp->t_oproc = comstart;
- tp->t_param = comparam;
- tp->t_dev = dev;
- tp->t_termios = mynor & CALLOUT_MASK
- ? com->it_out : com->it_in;
- commctl(com, MCR_DTR | MCR_RTS, DMSET);
- com->ftl_max = com->ftl_init;
- com->poll = com->no_irq;
- ++com->wopeners;
- error = comparam(tp, &tp->t_termios);
- --com->wopeners;
- if (error != 0)
- goto out;
- /*
- * XXX we should goto open_top if comparam() slept.
- */
- ttsetwater(tp);
- iobase = com->iobase;
- if (com->hasfifo) {
- /*
- * (Re)enable and drain fifos.
- *
- * Certain SMC chips cause problems if the fifos
- * are enabled while input is ready. Turn off the
- * fifo if necessary to clear the input. We test
- * the input ready bit after enabling the fifos
- * since we've already enabled them in comparam()
- * and to handle races between enabling and fresh
- * input.
- */
- while (TRUE) {
- outb(iobase + com_fifo,
- FIFO_RCV_RST | FIFO_XMT_RST
- | FIFO_ENABLE | com->ftl);
- DELAY(100);
- if (!(inb(com->line_status_port) & LSR_RXRDY))
- break;
- outb(iobase + com_fifo, 0);
- DELAY(100);
- (void) inb(com->data_port);
- }
- }
-
- disable_intr();
- (void) inb(com->line_status_port);
- (void) inb(com->data_port);
- com->prev_modem_status =
- com->last_modem_status = inb(com->modem_status_port);
- outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS
- | IER_EMSC);
- enable_intr();
- /*
- * Handle initial DCD. Callout devices get a fake initial
- * DCD (trapdoor DCD). If we are callout, then any sleeping
- * callin opens get woken up and resume sleeping on "siobi"
- * instead of "siodcd".
- */
- if (com->prev_modem_status & MSR_DCD || mynor & CALLOUT_MASK)
- (*linesw[tp->t_line].l_modem)(tp, 1);
- }
- /*
- * Wait for DCD if necessary.
- */
- if (!(tp->t_state & TS_CARR_ON) && !(mynor & CALLOUT_MASK)
- && !(tp->t_cflag & CLOCAL) && !(flag & O_NONBLOCK)) {
- ++com->wopeners;
- error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH, "siodcd", 0);
- --com->wopeners;
- if (error != 0)
- goto out;
- goto open_top;
- }
- error = (*linesw[tp->t_line].l_open)(dev, tp);
- disc_optim(tp, &(tp->t_termios), com);
- if (tp->t_state & TS_ISOPEN && mynor & CALLOUT_MASK)
- com->active_out = TRUE;
-out:
- splx(s);
- if (!(tp->t_state & TS_ISOPEN) && com->wopeners == 0)
- comhardclose(com);
- return (error);
-}
-
-/*ARGSUSED*/
-int
-sioclose(dev, flag, mode, p)
- dev_t dev;
- int flag;
- int mode;
- struct proc *p;
-{
- struct com_s *com;
- int mynor;
- int s;
- struct tty *tp;
-
- mynor = minor(dev);
- if (mynor & CONTROL_MASK)
- return (0);
- com = com_addr(MINOR_TO_UNIT(mynor));
- tp = com->tp;
- s = spltty();
- (*linesw[tp->t_line].l_close)(tp, flag);
- disc_optim(tp, &(tp->t_termios), com);
- siostop(tp, FREAD | FWRITE);
- comhardclose(com);
- ttyclose(tp);
- splx(s);
- return (0);
-}
-
-static void
-comhardclose(com)
- struct com_s *com;
-{
- Port_t iobase;
- int s;
- struct tty *tp;
- int unit;
-
- unit = com->unit;
- iobase = com->iobase;
- s = spltty();
- com->poll = FALSE;
- com->do_timestamp = 0;
- outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
-#ifdef KGDB
- /* do not disable interrupts or hang up if debugging */
- if (kgdb_dev != makedev(commajor, unit))
-#endif
- {
- outb(iobase + com_ier, 0);
- tp = com->tp;
- if (tp->t_cflag & HUPCL
- /*
- * XXX we will miss any carrier drop between here and the
- * next open. Perhaps we should watch DCD even when the
- * port is closed; it is not sufficient to check it at
- * the next open because it might go up and down while
- * we're not watching.
- */
- || !com->active_out
- && !(com->prev_modem_status & MSR_DCD)
- && !(com->it_in.c_cflag & CLOCAL)
- || !(tp->t_state & TS_ISOPEN)) {
- commctl(com, MCR_RTS, DMSET);
- if (com->dtr_wait != 0) {
- timeout(siodtrwakeup, com, com->dtr_wait);
- com->state |= CS_DTR_OFF;
- }
- }
- }
- com->active_out = FALSE;
- wakeup(&com->active_out);
- wakeup(TSA_CARR_ON(tp)); /* restart any wopeners */
- if (!(com->state & CS_DTR_OFF)
- && !(unit == comconsole && (COMCONSOLE || boothowto & RB_SERIAL)))
- kdc_sio[unit].kdc_state = DC_IDLE;
- splx(s);
-}
-
-int
-sioread(dev, uio, flag)
- dev_t dev;
- struct uio *uio;
- int flag;
-{
- int mynor;
- struct tty *tp;
-
- mynor = minor(dev);
- if (mynor & CONTROL_MASK)
- return (ENODEV);
- tp = com_addr(MINOR_TO_UNIT(mynor))->tp;
- return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
-}
-
-int
-siowrite(dev, uio, flag)
- dev_t dev;
- struct uio *uio;
- int flag;
-{
- int mynor;
- struct tty *tp;
- int unit;
-
- mynor = minor(dev);
- if (mynor & CONTROL_MASK)
- return (ENODEV);
-
- unit = MINOR_TO_UNIT(mynor);
- tp = com_addr(unit)->tp;
- /*
- * (XXX) We disallow virtual consoles if the physical console is
- * a serial port. This is in case there is a display attached that
- * is not the console. In that situation we don't need/want the X
- * server taking over the console.
- */
- if (constty && unit == comconsole
- && (COMCONSOLE || boothowto & RB_SERIAL))
- constty = NULL;
- return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
-}
-
-static void
-siodtrwakeup(chan)
- void *chan;
-{
- struct com_s *com;
-
- com = (struct com_s *)chan;
- com->state &= ~CS_DTR_OFF;
- if (!(com->unit == comconsole && (COMCONSOLE || boothowto & RB_SERIAL)))
- kdc_sio[com->unit].kdc_state = DC_IDLE;
- wakeup(&com->dtr_wait);
-}
-
-/* Interrupt routine for timekeeping purposes */
-void
-siointrts(unit)
- int unit;
-{
- /*
- * XXX microtime() reenables CPU interrupts. We can't afford to
- * be interrupted and don't want to slow down microtime(), so lock
- * out interrupts in another way.
- */
- outb(IO_ICU1 + 1, 0xff);
- microtime(&intr_timestamp);
- disable_intr();
- outb(IO_ICU1 + 1, imen);
-
- siointr(unit);
-}
-
-void
-siointr(unit)
- int unit;
-{
-#ifndef COM_MULTIPORT
- siointr1(com_addr(unit));
-#else /* COM_MULTIPORT */
- struct com_s *com;
- bool_t possibly_more_intrs;
-
- /*
- * Loop until there is no activity on any port. This is necessary
- * to get an interrupt edge more than to avoid another interrupt.
- * If the IRQ signal is just an OR of the IRQ signals from several
- * devices, then the edge from one may be lost because another is
- * on.
- */
- do {
- possibly_more_intrs = FALSE;
- for (unit = 0; unit < NSIO; ++unit) {
- com = com_addr(unit);
- if (com != NULL
- && (inb(com->int_id_port) & IIR_IMASK)
- != IIR_NOPEND) {
- siointr1(com);
- possibly_more_intrs = TRUE;
- }
- }
- } while (possibly_more_intrs);
-#endif /* COM_MULTIPORT */
-}
-
-static void
-siointr1(com)
- struct com_s *com;
-{
- u_char line_status;
- u_char modem_status;
- u_char *ioptr;
- u_char recv_data;
-
- if (com->do_timestamp)
- /* XXX a little bloat here... */
- com->timestamp = intr_timestamp;
- while (TRUE) {
- line_status = inb(com->line_status_port);
-
- /* input event? (check first to help avoid overruns) */
- while (line_status & LSR_RCV_MASK) {
- /* break/unnattached error bits or real input? */
- if (!(line_status & LSR_RXRDY))
- recv_data = 0;
- else
- recv_data = inb(com->data_port);
- if (line_status & (LSR_PE|LSR_FE|LSR_BI)) {
-#ifdef DDB
-#ifdef BREAK_TO_DEBUGGER
- if ( (line_status & LSR_BI)
- && (COMCONSOLE || boothowto & RB_SERIAL)
- && com->unit == comconsole) {
- Debugger("serial console break");
- goto cont;
- }
-#endif
-#endif
- /*
- Don't store PE if IGNPAR and BI if IGNBRK,
- this hack allows "raw" tty optimization
- works even if IGN* is set.
- */
- if ( com->tp == NULL
- || !(com->tp->t_state & TS_ISOPEN)
- || (line_status & (LSR_PE|LSR_FE))
- && (com->tp->t_iflag & IGNPAR)
- || (line_status & LSR_BI)
- && (com->tp->t_iflag & IGNBRK))
- goto cont;
- if ( (line_status & (LSR_PE|LSR_FE))
- && (com->tp->t_state & TS_CAN_BYPASS_L_RINT)
- && ((line_status & LSR_FE)
- || (line_status & LSR_PE)
- && (com->tp->t_iflag & INPCK)))
- recv_data = 0;
- }
- ++com->bytes_in;
- if (com->hotchar != 0 && recv_data == com->hotchar)
- setsofttty();
-#ifdef KGDB
- /* trap into kgdb? (XXX - needs testing and optim) */
- if (recv_data == FRAME_END
- && ( com->tp == NULL
- || !(com->tp->t_state & TS_ISOPEN))
- && kgdb_dev == makedev(commajor, unit)) {
- kgdb_connect(0);
- continue;
- }
-#endif /* KGDB */
- ioptr = com->iptr;
- if (ioptr >= com->ibufend)
- CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
- else {
- ++com_events;
-#if 0 /* for testing input latency vs efficiency */
-if (com->iptr - com->ibuf == 8)
- setsofttty();
-#endif
- ioptr[0] = recv_data;
- ioptr[CE_INPUT_OFFSET] = line_status;
- com->iptr = ++ioptr;
- if (ioptr == com->ihighwater
- && com->state & CS_RTS_IFLOW)
- outb(com->modem_ctl_port,
- com->mcr_image &= ~MCR_RTS);
- if (line_status & LSR_OE)
- CE_RECORD(com, CE_OVERRUN);
- }
- cont:
- /*
- * "& 0x7F" is to avoid the gcc-1.40 generating a slow
- * jump from the top of the loop to here
- */
- line_status = inb(com->line_status_port) & 0x7F;
- }
-
- /* modem status change? (always check before doing output) */
- modem_status = inb(com->modem_status_port);
- if (modem_status != com->last_modem_status) {
- /*
- * Schedule high level to handle DCD changes. Note
- * that we don't use the delta bits anywhere. Some
- * UARTs mess them up, and it's easy to remember the
- * previous bits and calculate the delta.
- */
- com->last_modem_status = modem_status;
- if (!(com->state & CS_CHECKMSR)) {
- com_events += LOTS_OF_EVENTS;
- com->state |= CS_CHECKMSR;
- setsofttty();
- }
-
- /* handle CTS change immediately for crisp flow ctl */
- if (com->state & CS_CTS_OFLOW) {
- if (modem_status & MSR_CTS)
- com->state |= CS_ODEVREADY;
- else
- com->state &= ~CS_ODEVREADY;
- }
- }
-
- /* output queued and everything ready? */
- if (line_status & LSR_TXRDY
- && com->state >= (CS_ODEVREADY | CS_BUSY | CS_TTGO)) {
- ioptr = com->optr;
- if (com->tx_fifo_size > 1) {
- u_int ocount;
-
- ocount = com->obufend - ioptr;
- if (ocount > com->tx_fifo_size)
- ocount = com->tx_fifo_size;
- com->bytes_out += ocount;
- do
- outb(com->data_port, *ioptr++);
- while (--ocount != 0);
- } else {
- outb(com->data_port, *ioptr++);
- ++com->bytes_out;
- }
- com->optr = ioptr;
- if (ioptr >= com->obufend) {
- /* output just completed */
- com_events += LOTS_OF_EVENTS;
- com->state ^= (CS_ODONE | CS_BUSY);
- setsofttty(); /* handle at high level ASAP */
- }
- }
-
- /* finished? */
-#ifndef COM_MULTIPORT
- if ((inb(com->int_id_port) & IIR_IMASK) == IIR_NOPEND)
-#endif /* COM_MULTIPORT */
- return;
- }
-}
-
-static int
-tiocm_xxx2mcr(tiocm_xxx)
- int tiocm_xxx;
-{
- int mcr;
-
- mcr = 0;
- if (tiocm_xxx & TIOCM_DTR)
- mcr |= MCR_DTR;
- if (tiocm_xxx & TIOCM_RTS)
- mcr |= MCR_RTS;
- return (mcr);
-}
-
-int
-sioioctl(dev, cmd, data, flag, p)
- dev_t dev;
- int cmd;
- caddr_t data;
- int flag;
- struct proc *p;
-{
- struct com_s *com;
- int error;
- Port_t iobase;
- int mcr;
- int msr;
- int mynor;
- int s;
- int tiocm_xxx;
- struct tty *tp;
-#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
- int oldcmd;
- struct termios term;
-#endif
-
- mynor = minor(dev);
- com = com_addr(MINOR_TO_UNIT(mynor));
- iobase = com->iobase;
- if (mynor & CONTROL_MASK) {
- struct termios *ct;
-
- switch (mynor & CONTROL_MASK) {
- case CONTROL_INIT_STATE:
- ct = mynor & CALLOUT_MASK ? &com->it_out : &com->it_in;
- break;
- case CONTROL_LOCK_STATE:
- ct = mynor & CALLOUT_MASK ? &com->lt_out : &com->lt_in;
- break;
- default:
- return (ENODEV); /* /dev/nodev */
- }
- switch (cmd) {
- case TIOCSETA:
- error = suser(p->p_ucred, &p->p_acflag);
- if (error != 0)
- return (error);
- *ct = *(struct termios *)data;
- return (0);
- case TIOCGETA:
- *(struct termios *)data = *ct;
- return (0);
- case TIOCGETD:
- *(int *)data = TTYDISC;
- return (0);
- case TIOCGWINSZ:
- bzero(data, sizeof(struct winsize));
- return (0);
-#ifdef DSI_SOFT_MODEM
- /*
- * Download micro-code to Digicom modem.
- */
- case TIOCDSIMICROCODE:
- {
- u_long l;
- u_char *p,*pi;
-
- pi = (u_char*)(*(caddr_t*)data);
- error = copyin(pi,&l,sizeof l);
- if(error)
- {return error;};
- pi += sizeof l;
-
- p = malloc(l,M_TEMP,M_NOWAIT);
- if(!p)
- {return ENOBUFS;}
- error = copyin(pi,p,l);
- if(error)
- {free(p,M_TEMP); return error;};
- if(error = LoadSoftModem(
- MINOR_TO_UNIT(mynor),iobase,l,p))
- {free(p,M_TEMP); return error;}
- free(p,M_TEMP);
- return(0);
- }
-#endif /* DSI_SOFT_MODEM */
- default:
- return (ENOTTY);
- }
- }
- tp = com->tp;
-#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
- term = tp->t_termios;
- oldcmd = cmd;
- error = ttsetcompat(tp, &cmd, data, &term);
- if (error != 0)
- return (error);
- if (cmd != oldcmd)
- data = (caddr_t)&term;
-#endif
- if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {
- int cc;
- struct termios *dt = (struct termios *)data;
- struct termios *lt = mynor & CALLOUT_MASK
- ? &com->lt_out : &com->lt_in;
-
- dt->c_iflag = (tp->t_iflag & lt->c_iflag)
- | (dt->c_iflag & ~lt->c_iflag);
- dt->c_oflag = (tp->t_oflag & lt->c_oflag)
- | (dt->c_oflag & ~lt->c_oflag);
- dt->c_cflag = (tp->t_cflag & lt->c_cflag)
- | (dt->c_cflag & ~lt->c_cflag);
- dt->c_lflag = (tp->t_lflag & lt->c_lflag)
- | (dt->c_lflag & ~lt->c_lflag);
- for (cc = 0; cc < NCCS; ++cc)
- if (lt->c_cc[cc] != 0)
- dt->c_cc[cc] = tp->t_cc[cc];
- if (lt->c_ispeed != 0)
- dt->c_ispeed = tp->t_ispeed;
- if (lt->c_ospeed != 0)
- dt->c_ospeed = tp->t_ospeed;
- }
- error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
- if (error >= 0)
- return (error);
- s = spltty();
- error = ttioctl(tp, cmd, data, flag);
- disc_optim(tp, &(tp->t_termios), com);
- if (error >= 0) {
- splx(s);
- return (error);
- }
- switch (cmd) {
- case TIOCSBRK:
- outb(iobase + com_cfcr, com->cfcr_image |= CFCR_SBREAK);
- break;
- case TIOCCBRK:
- outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
- break;
- case TIOCSDTR:
- commctl(com, MCR_DTR, DMBIS);
- break;
- case TIOCCDTR:
- commctl(com, MCR_DTR, DMBIC);
- break;
- case TIOCMSET:
- commctl(com, tiocm_xxx2mcr(*(int *)data), DMSET);
- break;
- case TIOCMBIS:
- commctl(com, tiocm_xxx2mcr(*(int *)data), DMBIS);
- break;
- case TIOCMBIC:
- commctl(com, tiocm_xxx2mcr(*(int *)data), DMBIC);
- break;
- case TIOCMGET:
- tiocm_xxx = TIOCM_LE; /* XXX - always enabled while open */
- mcr = com->mcr_image;
- if (mcr & MCR_DTR)
- tiocm_xxx |= TIOCM_DTR;
- if (mcr & MCR_RTS)
- tiocm_xxx |= TIOCM_RTS;
- msr = com->prev_modem_status;
- if (msr & MSR_CTS)
- tiocm_xxx |= TIOCM_CTS;
- if (msr & MSR_DCD)
- tiocm_xxx |= TIOCM_CD;
- if (msr & MSR_DSR)
- tiocm_xxx |= TIOCM_DSR;
- /*
- * XXX - MSR_RI is naturally volatile, and we make MSR_TERI
- * more volatile by reading the modem status a lot. Perhaps
- * we should latch both bits until the status is read here.
- */
- if (msr & (MSR_RI | MSR_TERI))
- tiocm_xxx |= TIOCM_RI;
- *(int *)data = tiocm_xxx;
- break;
- case TIOCMSDTRWAIT:
- /* must be root since the wait applies to following logins */
- error = suser(p->p_ucred, &p->p_acflag);
- if (error != 0) {
- splx(s);
- return (error);
- }
- com->dtr_wait = *(int *)data * hz / 100;
- break;
- case TIOCMGDTRWAIT:
- *(int *)data = com->dtr_wait * 100 / hz;
- break;
- case TIOCTIMESTAMP:
- com->do_timestamp = TRUE;
- *(struct timeval *)data = com->timestamp;
- break;
- default:
- splx(s);
- return (ENOTTY);
- }
- splx(s);
- return (0);
-}
-
-/* cancel pending output */
-static void
-comflush(com)
- struct com_s *com;
-{
- disable_intr();
- if (com->state & CS_ODONE)
- com_events -= LOTS_OF_EVENTS;
- com->state &= ~(CS_ODONE | CS_BUSY);
- enable_intr();
- com->tp->t_state &= ~TS_BUSY;
-}
-
-void
-siopoll()
-{
- int unit;
-
- if (com_events == 0)
- return;
-repeat:
- for (unit = 0; unit < NSIO; ++unit) {
- u_char *buf;
- struct com_s *com;
- u_char *ibuf;
- int incc;
- struct tty *tp;
-
- com = com_addr(unit);
- if (com == NULL)
- continue;
- tp = com->tp;
- if (tp == NULL) {
- /*
- * XXX forget any events related to closed devices
- * (actually never opened devices) so that we don't
- * loop.
- */
- disable_intr();
- incc = com->iptr - com->ibuf;
- com->iptr = com->ibuf;
- if (com->state & CS_CHECKMSR) {
- incc += LOTS_OF_EVENTS;
- com->state &= ~CS_CHECKMSR;
- }
- com_events -= incc;
- enable_intr();
- if (incc != 0)
- log(LOG_DEBUG,
- "sio%d: %d events for device with no tp\n",
- unit, incc);
- continue;
- }
-
- /* switch the role of the low-level input buffers */
- if (com->iptr == (ibuf = com->ibuf)) {
- buf = NULL; /* not used, but compiler can't tell */
- incc = 0;
- } else {
- buf = ibuf;
- disable_intr();
- incc = com->iptr - buf;
- com_events -= incc;
- if (ibuf == com->ibuf1)
- ibuf = com->ibuf2;
- else
- ibuf = com->ibuf1;
- com->ibufend = ibuf + RS_IBUFSIZE;
- com->ihighwater = ibuf + RS_IHIGHWATER;
- com->iptr = ibuf;
-
- /*
- * There is now room for another low-level buffer full
- * of input, so enable RTS if it is now disabled and
- * there is room in the high-level buffer.
- */
- /*
- * XXX this used not to look at CS_RTS_IFLOW. The
- * change is to allow full control of MCR_RTS via
- * ioctls after turning CS_RTS_IFLOW off. Check
- * for races. We shouldn't allow the ioctls while
- * CS_RTS_IFLOW is on.
- */
- if ((com->state & CS_RTS_IFLOW)
- && !(com->mcr_image & MCR_RTS)
- && !(tp->t_state & TS_TBLOCK))
- outb(com->modem_ctl_port,
- com->mcr_image |= MCR_RTS);
- enable_intr();
- com->ibuf = ibuf;
- }
-
- if (com->state & CS_CHECKMSR) {
- u_char delta_modem_status;
-
- disable_intr();
- delta_modem_status = com->last_modem_status
- ^ com->prev_modem_status;
- com->prev_modem_status = com->last_modem_status;
- com_events -= LOTS_OF_EVENTS;
- com->state &= ~CS_CHECKMSR;
- enable_intr();
- if (delta_modem_status & MSR_DCD)
- (*linesw[tp->t_line].l_modem)
- (tp, com->prev_modem_status & MSR_DCD);
- }
- if (com->state & CS_ODONE) {
- comflush(com);
- (*linesw[tp->t_line].l_start)(tp);
- }
- if (incc <= 0 || !(tp->t_state & TS_ISOPEN))
- continue;
- /*
- * XXX only do this when we bypass ttyinput.
- */
- if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
- && (com->state & CS_RTS_IFLOW || tp->t_iflag & IXOFF)
- && !(tp->t_state & TS_TBLOCK)
- /*
- * XXX - need flow control for all line disciplines.
- * Only have it in standard one now.
- */
- && linesw[tp->t_line].l_rint == ttyinput) {
- int putc_status = FALSE;
-
- if ((tp->t_iflag & IXOFF
- && tp->t_cc[VSTOP] != _POSIX_VDISABLE
- && (putc_status = putc(tp->t_cc[VSTOP],
- &tp->t_outq)) == 0)
- || com->state & CS_RTS_IFLOW) {
- tp->t_state |= TS_TBLOCK;
- ttstart(tp);
- if (putc_status != 0)
- /* Try again later. */
- tp->t_state &= ~TS_TBLOCK;
- }
- }
- /*
- * Avoid the grotesquely inefficient lineswitch routine
- * (ttyinput) in "raw" mode. It usually takes about 450
- * instructions (that's without canonical processing or echo!).
- * slinput is reasonably fast (usually 40 instructions plus
- * call overhead).
- */
- if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
- tk_nin += incc;
- tk_rawcc += incc;
- tp->t_rawcc += incc;
- com->delta_error_counts[CE_TTY_BUF_OVERFLOW]
- += b_to_q((char *)buf, incc, &tp->t_rawq);
- ttwakeup(tp);
- if (tp->t_state & TS_TTSTOP
- && (tp->t_iflag & IXANY
- || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
- tp->t_state &= ~TS_TTSTOP;
- tp->t_lflag &= ~FLUSHO;
- ttstart(tp);
- }
- } else {
- do {
- u_char line_status;
- int recv_data;
-
- line_status = (u_char) buf[CE_INPUT_OFFSET];
- recv_data = (u_char) *buf++;
- if (line_status
- & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) {
- if (line_status & LSR_BI)
- recv_data |= TTY_BI;
- if (line_status & LSR_FE)
- recv_data |= TTY_FE;
- if (line_status & LSR_OE)
- recv_data |= TTY_OE;
- if (line_status & LSR_PE)
- recv_data |= TTY_PE;
- }
- (*linesw[tp->t_line].l_rint)(recv_data, tp);
- } while (--incc > 0);
- }
- if (com_events == 0)
- break;
- }
- if (com_events >= LOTS_OF_EVENTS)
- goto repeat;
-}
-
-static int
-comparam(tp, t)
- struct tty *tp;
- struct termios *t;
-{
- u_int cfcr;
- int cflag;
- struct com_s *com;
- int divisor;
- int error;
- Port_t iobase;
- int s;
- int unit;
-
- /* check requested parameters */
- divisor = ttspeedtab(t->c_ospeed, comspeedtab);
- if (t->c_ispeed == 0)
- t->c_ispeed = t->c_ospeed;
- if (divisor < 0 || divisor > 0 && t->c_ispeed != t->c_ospeed)
- return (EINVAL);
-
- /* parameters are OK, convert them to the com struct and the device */
- unit = DEV_TO_UNIT(tp->t_dev);
- com = com_addr(unit);
- iobase = com->iobase;
- s = spltty();
- if (divisor == 0)
- commctl(com, MCR_DTR, DMBIC); /* hang up line */
- else
- commctl(com, MCR_DTR, DMBIS);
- cflag = t->c_cflag;
- switch (cflag & CSIZE) {
- case CS5:
- cfcr = CFCR_5BITS;
- break;
- case CS6:
- cfcr = CFCR_6BITS;
- break;
- case CS7:
- cfcr = CFCR_7BITS;
- break;
- default:
- cfcr = CFCR_8BITS;
- break;
- }
- if (cflag & PARENB) {
- cfcr |= CFCR_PENAB;
- if (!(cflag & PARODD))
- cfcr |= CFCR_PEVEN;
- }
- if (cflag & CSTOPB)
- cfcr |= CFCR_STOPB;
-
- if (com->hasfifo) {
- /*
- * Use a fifo trigger level low enough so that the input
- * latency from the fifo is less than about 16 msec and
- * the total latency is less than about 30 msec. These
- * latencies are reasonable for humans. Serial comms
- * protocols shouldn't expect anything better since modem
- * latencies are larger.
- */
- com->ftl = t->c_ospeed <= 4800
- ? FIFO_TRIGGER_1 : FIFO_TRIGGER_14;
- if (com->ftl > com->ftl_max)
- com->ftl = com->ftl_max;
- outb(iobase + com_fifo, FIFO_ENABLE | com->ftl);
- }
-
- /*
- * Some UARTs lock up if the divisor latch registers are selected
- * while the UART is doing output (they refuse to transmit anything
- * more until given a hard reset). Fix this by stopping filling
- * the device buffers and waiting for them to drain. Reading the
- * line status port outside of siointr1() might lose some receiver
- * error bits, but that is acceptable here.
- */
- disable_intr();
-retry:
- com->state &= ~CS_TTGO;
- enable_intr();
- while ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY))
- != (LSR_TSRE | LSR_TXRDY)) {
- error = ttysleep(tp, TSA_OCOMPLETE(tp), TTIPRI | PCATCH,
- "siotx", hz / 100);
- if (error != 0 && error != EAGAIN) {
- if (!(tp->t_state & TS_TTSTOP)) {
- disable_intr();
- com->state |= CS_TTGO;
- enable_intr();
- }
- splx(s);
- return (error);
- }
- }
-
- disable_intr(); /* very important while com_data is hidden */
-
- /*
- * XXX - clearing CS_TTGO is not sufficient to stop further output,
- * because siopoll() calls comstart() which usually sets it again
- * because TS_TTSTOP is clear. Setting TS_TTSTOP would not be
- * sufficient, for similar reasons.
- */
- if ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY))
- != (LSR_TSRE | LSR_TXRDY))
- goto retry;
-
- if (divisor != 0) {
- outb(iobase + com_cfcr, cfcr | CFCR_DLAB);
- outb(iobase + com_dlbl, divisor & 0xFF);
- outb(iobase + com_dlbh, (u_int) divisor >> 8);
- }
- outb(iobase + com_cfcr, com->cfcr_image = cfcr);
- if (!(tp->t_state & TS_TTSTOP))
- com->state |= CS_TTGO;
- if (cflag & CRTS_IFLOW)
- com->state |= CS_RTS_IFLOW; /* XXX - secondary changes? */
- else
- com->state &= ~CS_RTS_IFLOW;
-
- /*
- * Set up state to handle output flow control.
- * XXX - worth handling MDMBUF (DCD) flow control at the lowest level?
- * Now has 10+ msec latency, while CTS flow has 50- usec latency.
- */
- com->state &= ~CS_CTS_OFLOW;
- com->state |= CS_ODEVREADY;
- if (cflag & CCTS_OFLOW) {
- com->state |= CS_CTS_OFLOW;
- if (!(com->last_modem_status & MSR_CTS))
- com->state &= ~CS_ODEVREADY;
- }
- disc_optim(tp, t, com);
- /*
- * Recover from fiddling with CS_TTGO. We used to call siointr1()
- * unconditionally, but that defeated the careful discarding of
- * stale input in sioopen().
- */
- if (com->state >= (CS_BUSY | CS_TTGO))
- siointr1(com);
-
- enable_intr();
- splx(s);
- return (0);
-}
-
-static void
-comstart(tp)
- struct tty *tp;
-{
- struct com_s *com;
- int s;
- int unit;
-
- unit = DEV_TO_UNIT(tp->t_dev);
- com = com_addr(unit);
- s = spltty();
- disable_intr();
- if (tp->t_state & TS_TTSTOP)
- com->state &= ~CS_TTGO;
- else
- com->state |= CS_TTGO;
- if (tp->t_state & TS_TBLOCK) {
- if (com->mcr_image & MCR_RTS && com->state & CS_RTS_IFLOW)
- outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
- } else {
- /*
- * XXX don't raise MCR_RTS if CTS_RTS_IFLOW is off. Set it
- * appropriately in comparam() if RTS-flow is being changed.
- * Check for races.
- */
- if (!(com->mcr_image & MCR_RTS) && com->iptr < com->ihighwater)
- outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
- }
- enable_intr();
- if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP))
- goto out;
-#if 0 /* XXX TK2.0 */
- if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT) || tp->t_wsel)
- ttwwakeup(tp);
-#else
- if (tp->t_outq.c_cc <= tp->t_lowat) {
- if (tp->t_state & TS_ASLEEP) {
- tp->t_state &= ~TS_ASLEEP;
- wakeup(TSA_OLOWAT(tp));
- }
- selwakeup(&tp->t_wsel);
- }
-#endif
- if (tp->t_state & TS_BUSY) {
- disable_intr();
- siointr1(com);
- enable_intr();
- } else if (tp->t_outq.c_cc != 0) {
- u_int ocount;
-
- tp->t_state |= TS_BUSY;
- ocount = q_to_b(&tp->t_outq, com->obuf, sizeof com->obuf);
- disable_intr();
- com->obufend = (com->optr = com->obuf) + ocount;
- com->state |= CS_BUSY;
- siointr1(com); /* fake interrupt to start output */
- enable_intr();
- }
-out:
- splx(s);
-}
-
-void
-siostop(tp, rw)
- struct tty *tp;
- int rw;
-{
- struct com_s *com;
-
- com = com_addr(DEV_TO_UNIT(tp->t_dev));
- if (rw & FWRITE)
- comflush(com);
- disable_intr();
- if (rw & FREAD) {
- com_events -= (com->iptr - com->ibuf);
- com->iptr = com->ibuf;
- }
- if (tp->t_state & TS_TTSTOP)
- com->state &= ~CS_TTGO;
- else
- com->state |= CS_TTGO;
- enable_intr();
-}
-
-struct tty *
-siodevtotty(dev)
- dev_t dev;
-{
- int mynor;
- int unit;
-
- mynor = minor(dev);
- if (mynor & CONTROL_MASK)
- return (NULL);
- unit = MINOR_TO_UNIT(mynor);
- if ((u_int) unit >= NSIO)
- return (NULL);
- return (&sio_tty[unit]);
-}
-
-static void
-commctl(com, bits, how)
- struct com_s *com;
- int bits;
- int how;
-{
- disable_intr();
- switch (how) {
- case DMSET:
- outb(com->modem_ctl_port,
- com->mcr_image = bits | (com->mcr_image & MCR_IENABLE));
- break;
- case DMBIS:
- outb(com->modem_ctl_port, com->mcr_image |= bits);
- break;
- case DMBIC:
- outb(com->modem_ctl_port, com->mcr_image &= ~bits);
- break;
- }
- enable_intr();
-}
-
-static void
-comwakeup(chan)
- void *chan;
-{
- struct com_s *com;
- static int log_countdown = 1;
- int unit;
-
- timeout(comwakeup, (caddr_t)NULL, hz > 200 ? hz / 200 : 1);
-
- if (com_events != 0) {
- int s;
-
- s = splsofttty();
- siopoll();
- splx(s);
- }
-
- /*
- * Recover from lost output interrupts.
- * Poll any lines that don't use interrupts.
- */
- for (unit = 0; unit < NSIO; ++unit) {
- com = com_addr(unit);
- if (com != NULL
- && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) {
- disable_intr();
- siointr1(com);
- enable_intr();
- }
- }
-
- /*
- * Check for and log errors, but not too often.
- */
- if (--log_countdown > 0)
- return;
- log_countdown = hz > 200 ? 200 : hz;
- for (unit = 0; unit < NSIO; ++unit) {
- int errnum;
-
- com = com_addr(unit);
- if (com == NULL)
- continue;
- for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
- u_int delta;
- u_long total;
-
- disable_intr();
- delta = com->delta_error_counts[errnum];
- com->delta_error_counts[errnum] = 0;
- enable_intr();
- if (delta == 0)
- continue;
- total = com->error_counts[errnum] += delta;
- log(LOG_ERR, "sio%d: %u more %s%s (total %lu)\n",
- unit, delta, error_desc[errnum],
- delta == 1 ? "" : "s", total);
-#if 0
- /*
- * XXX if we resurrect this then we should move
- * the dropping of the ftl to somewhere with less
- * latency.
- */
- if (errnum == CE_OVERRUN && com->hasfifo
- && com->ftl > FIFO_TRIGGER_1) {
- static u_char ftl_in_bytes[] =
- { 1, 4, 8, 14, };
-
- com->ftl_init = FIFO_TRIGGER_8;
-#define FIFO_TRIGGER_DELTA FIFO_TRIGGER_4
- com->ftl_max =
- com->ftl -= FIFO_TRIGGER_DELTA;
- outb(com->iobase + com_fifo,
- FIFO_ENABLE | com->ftl);
- log(LOG_DEBUG,
- "sio%d: reduced fifo trigger level to %d\n",
- unit,
- ftl_in_bytes[com->ftl
- / FIFO_TRIGGER_DELTA]);
- }
-#endif
- }
- }
-}
-
-static void
-disc_optim(tp, t, com)
- struct tty *tp;
- struct termios *t;
- struct com_s *com;
-{
-
- if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP
- | IXOFF | IXON))
- && (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK))
- && (!(t->c_iflag & PARMRK) ||
- (t->c_iflag & (IGNPAR|IGNBRK)) == (IGNPAR|IGNBRK))
- && !(t->c_lflag & (ECHO | ECHONL | ICANON | IEXTEN | ISIG
- | PENDIN))
- && linesw[tp->t_line].l_rint == ttyinput)
- tp->t_state |= TS_CAN_BYPASS_L_RINT;
- else
- tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
- /*
- * Prepare to reduce input latency for packet
- * discplines with a end of packet character.
- */
- if (tp->t_line == SLIPDISC)
- com->hotchar = 0xc0;
- else if (tp->t_line == PPPDISC)
- com->hotchar = 0x7e;
- else
- com->hotchar = 0;
-}
-
-/*
- * Following are all routines needed for SIO to act as console
- */
-#include <i386/i386/cons.h>
-
-struct siocnstate {
- u_char dlbl;
- u_char dlbh;
- u_char ier;
- u_char cfcr;
- u_char mcr;
-};
-
-static Port_t siocniobase;
-
-static void siocnclose __P((struct siocnstate *sp));
-static void siocnopen __P((struct siocnstate *sp));
-static void siocntxwait __P((void));
-
-static void
-siocntxwait()
-{
- int timo;
-
- /*
- * Wait for any pending transmission to finish. Required to avoid
- * the UART lockup bug when the speed is changed, and for normal
- * transmits.
- */
- timo = 100000;
- while ((inb(siocniobase + com_lsr) & (LSR_TSRE | LSR_TXRDY))
- != (LSR_TSRE | LSR_TXRDY) && --timo != 0)
- ;
-}
-
-static void
-siocnopen(sp)
- struct siocnstate *sp;
-{
- int divisor;
- Port_t iobase;
-
- /*
- * Save all the device control registers except the fifo register
- * and set our default ones (cs8 -parenb speed=comdefaultrate).
- * We can't save the fifo register since it is read-only.
- */
- iobase = siocniobase;
- sp->ier = inb(iobase + com_ier);
- outb(iobase + com_ier, 0); /* spltty() doesn't stop siointr() */
- siocntxwait();
- sp->cfcr = inb(iobase + com_cfcr);
- outb(iobase + com_cfcr, CFCR_DLAB);
- sp->dlbl = inb(iobase + com_dlbl);
- sp->dlbh = inb(iobase + com_dlbh);
- divisor = ttspeedtab(comdefaultrate, comspeedtab);
- outb(iobase + com_dlbl, divisor & 0xFF);
- outb(iobase + com_dlbh, (u_int) divisor >> 8);
- outb(iobase + com_cfcr, CFCR_8BITS);
- sp->mcr = inb(iobase + com_mcr);
- /*
- * We don't want interrupts, but must be careful not to "disable"
- * them by clearing the MCR_IENABLE bit, since that might cause
- * an interrupt by floating the IRQ line.
- */
- outb(iobase + com_mcr, (sp->mcr & MCR_IENABLE) | MCR_DTR | MCR_RTS);
-}
-
-static void
-siocnclose(sp)
- struct siocnstate *sp;
-{
- Port_t iobase;
-
- /*
- * Restore the device control registers.
- */
- siocntxwait();
- iobase = siocniobase;
- outb(iobase + com_cfcr, CFCR_DLAB);
- outb(iobase + com_dlbl, sp->dlbl);
- outb(iobase + com_dlbh, sp->dlbh);
- outb(iobase + com_cfcr, sp->cfcr);
- /*
- * XXX damp oscillations of MCR_DTR and MCR_RTS by not restoring them.
- */
- outb(iobase + com_mcr, sp->mcr | MCR_DTR | MCR_RTS);
- outb(iobase + com_ier, sp->ier);
-}
-
-void
-siocnprobe(cp)
- struct consdev *cp;
-{
- int unit;
-
- /* locate the major number */
- /* XXX - should be elsewhere since KGDB uses it */
- for (commajor = 0; commajor < nchrdev; commajor++)
- if (cdevsw[commajor].d_open == sioopen)
- break;
-
- /* XXX: ick */
- unit = DEV_TO_UNIT(CONUNIT);
- siocniobase = CONADDR;
-
- /* make sure hardware exists? XXX */
-
- /* initialize required fields */
- cp->cn_dev = makedev(commajor, unit);
-
- if (COMCONSOLE || boothowto & RB_SERIAL)
- cp->cn_pri = CN_REMOTE; /* Force a serial port console */
- else
- cp->cn_pri = CN_NORMAL;
-
-}
-
-void
-siocninit(cp)
- struct consdev *cp;
-{
- /*
- * XXX can delete more comconsole stuff now that i/o routines are
- * fairly reentrant.
- */
- comconsole = DEV_TO_UNIT(cp->cn_dev);
-}
-
-int
-siocncheckc(dev)
- dev_t dev;
-{
- int c;
- Port_t iobase;
- int s;
- struct siocnstate sp;
-
- iobase = siocniobase;
- s = spltty();
- siocnopen(&sp);
- if (inb(iobase + com_lsr) & LSR_RXRDY)
- c = inb(iobase + com_data);
- else
- c = 0;
- siocnclose(&sp);
- splx(s);
- return (c);
-}
-
-
-int
-siocngetc(dev)
- dev_t dev;
-{
- int c;
- Port_t iobase;
- int s;
- struct siocnstate sp;
-
- iobase = siocniobase;
- s = spltty();
- siocnopen(&sp);
- while (!(inb(iobase + com_lsr) & LSR_RXRDY))
- ;
- c = inb(iobase + com_data);
- siocnclose(&sp);
- splx(s);
- return (c);
-}
-
-void
-siocnputc(dev, c)
- dev_t dev;
- int c;
-{
- int s;
- struct siocnstate sp;
-
- s = spltty();
- siocnopen(&sp);
- siocntxwait();
- outb(siocniobase + com_data, c);
- siocnclose(&sp);
- splx(s);
-}
-
-#ifdef DSI_SOFT_MODEM
-/*
- * The magic code to download microcode to a "Connection 14.4+Fax"
- * modem from Digicom Systems Inc. Very magic.
- */
-
-#define DSI_ERROR(str) { ptr = str; goto error; }
-static int
-LoadSoftModem(int unit, int base_io, u_long size, u_char *ptr)
-{
- int int_c,int_k;
- int data_0188, data_0187;
-
- /*
- * First see if it is a DSI SoftModem
- */
- if(!((inb(base_io+7) ^ inb(base_io+7) & 0x80)))
- return ENODEV;
-
- data_0188 = inb(base_io+4);
- data_0187 = inb(base_io+3);
- outb(base_io+3,0x80);
- outb(base_io+4,0x0C);
- outb(base_io+0,0x31);
- outb(base_io+1,0x8C);
- outb(base_io+7,0x10);
- outb(base_io+7,0x19);
-
- if(0x18 != (inb(base_io+7) & 0x1A))
- DSI_ERROR("dsp bus not granted");
-
- if(0x01 != (inb(base_io+7) & 0x01)) {
- outb(base_io+7,0x18);
- outb(base_io+7,0x19);
- if(0x01 != (inb(base_io+7) & 0x01))
- DSI_ERROR("program mem not granted");
- }
-
- int_c = 0;
-
- while(1) {
- if(int_c >= 7 || size <= 0x1800)
- break;
-
- for(int_k = 0 ; int_k < 0x800; int_k++) {
- outb(base_io+0,*ptr++);
- outb(base_io+1,*ptr++);
- outb(base_io+2,*ptr++);
- }
-
- size -= 0x1800;
- int_c++;
- }
-
- if(size > 0x1800) {
- outb(base_io+7,0x18);
- outb(base_io+7,0x19);
- if(0x00 != (inb(base_io+7) & 0x01))
- DSI_ERROR("program data not granted");
-
- for(int_k = 0 ; int_k < 0x800; int_k++) {
- outb(base_io+1,*ptr++);
- outb(base_io+2,0);
- outb(base_io+1,*ptr++);
- outb(base_io+2,*ptr++);
- }
-
- size -= 0x1800;
-
- while(size > 0x1800) {
- for(int_k = 0 ; int_k < 0xC00; int_k++) {
- outb(base_io+1,*ptr++);
- outb(base_io+2,*ptr++);
- }
- size -= 0x1800;
- }
-
- if(size < 0x1800) {
- for(int_k=0;int_k<size/2;int_k++) {
- outb(base_io+1,*ptr++);
- outb(base_io+2,*ptr++);
- }
- }
-
- } else if (size > 0) {
- if(int_c == 7) {
- outb(base_io+7,0x18);
- outb(base_io+7,0x19);
- if(0x00 != (inb(base_io+7) & 0x01))
- DSI_ERROR("program data not granted");
- for(int_k = 0 ; int_k < size/3; int_k++) {
- outb(base_io+1,*ptr++);
- outb(base_io+2,0);
- outb(base_io+1,*ptr++);
- outb(base_io+2,*ptr++);
- }
- } else {
- for(int_k = 0 ; int_k < size/3; int_k++) {
- outb(base_io+0,*ptr++);
- outb(base_io+1,*ptr++);
- outb(base_io+2,*ptr++);
- }
- }
- }
- outb(base_io+7,0x11);
- outb(base_io+7,3);
-
- outb(base_io+4,data_0188 & 0xfb);
-
- outb(base_io+3,data_0187);
-
- return 0;
-error:
- printf("sio%d: DSI SoftModem microcode load failed: <%s>\n",ptr);
- outb(base_io+7,0x00); \
- outb(base_io+3,data_0187); \
- outb(base_io+4,data_0188); \
- return EIO;
-}
-#endif /* DSI_SOFT_MODEM */
-
-#endif /* NSIO > 0 */
OpenPOWER on IntegriCloud