more ACSI removal
This patch removes some code that became dead code after the ATARI_ACSI
removal.
It also indirectly fixes the following bug introduced by
commit c2bcf3b897
:
config ATARI_SLM
tristate "Atari SLM laser printer support"
- depends on ATARI && ATARI_ACSI!=n
+ depends on ATARI
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
parent
5874c18b10
commit
56a68a500f
12 changed files with 0 additions and 2701 deletions
|
@ -82,13 +82,6 @@ Valid names are:
|
|||
/dev/fd : -> 0x0200 (floppy disk)
|
||||
/dev/xda: -> 0x0c00 (first XT disk, unused in Linux/m68k)
|
||||
/dev/xdb: -> 0x0c40 (second XT disk, unused in Linux/m68k)
|
||||
/dev/ada: -> 0x1c00 (first ACSI device)
|
||||
/dev/adb: -> 0x1c10 (second ACSI device)
|
||||
/dev/adc: -> 0x1c20 (third ACSI device)
|
||||
/dev/add: -> 0x1c30 (forth ACSI device)
|
||||
|
||||
The last four names are available only if the kernel has been compiled
|
||||
with Atari and ACSI support.
|
||||
|
||||
The name must be followed by a decimal number, that stands for the
|
||||
partition number. Internally, the value of the number is just
|
||||
|
|
|
@ -146,12 +146,6 @@ at1700.c:
|
|||
irq = 0
|
||||
(Probes ports: 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300)
|
||||
|
||||
atari_bionet.c:
|
||||
Supports full autoprobing. (m68k/Atari)
|
||||
|
||||
atari_pamsnet.c:
|
||||
Supports full autoprobing. (m68k/Atari)
|
||||
|
||||
atarilance.c:
|
||||
Supports full autoprobing. (m68k/Atari)
|
||||
|
||||
|
|
|
@ -59,17 +59,6 @@ config AMIGA_Z2RAM
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called z2ram.
|
||||
|
||||
config ATARI_SLM
|
||||
tristate "Atari SLM laser printer support"
|
||||
depends on ATARI
|
||||
help
|
||||
If you have an Atari SLM laser printer, say Y to include support for
|
||||
it in the kernel. Otherwise, say N. This driver is also available as
|
||||
a module ( = code which can be inserted in and removed from the
|
||||
running kernel whenever you want). The module will be called
|
||||
acsi_slm. Be warned: the driver needs much ST-RAM and can cause
|
||||
problems due to that fact!
|
||||
|
||||
config BLK_DEV_XD
|
||||
tristate "XT hard disk support"
|
||||
depends on ISA && ISA_DMA_API
|
||||
|
|
|
@ -9,7 +9,6 @@ obj-$(CONFIG_MAC_FLOPPY) += swim3.o
|
|||
obj-$(CONFIG_BLK_DEV_FD) += floppy.o
|
||||
obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
|
||||
obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o
|
||||
obj-$(CONFIG_ATARI_SLM) += acsi_slm.o
|
||||
obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o
|
||||
obj-$(CONFIG_BLK_DEV_RAM) += rd.o
|
||||
obj-$(CONFIG_BLK_DEV_LOOP) += loop.o
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -405,22 +405,6 @@ config ATARILANCE
|
|||
on the AMD Lance chipset: RieblCard (with or without battery), or
|
||||
PAMCard VME (also the version by Rhotron, with different addresses).
|
||||
|
||||
config ATARI_BIONET
|
||||
tristate "BioNet-100 support"
|
||||
depends on ATARI && ATARI_ACSI && BROKEN
|
||||
help
|
||||
Say Y to include support for BioData's BioNet-100 Ethernet adapter
|
||||
for the ACSI port. The driver works (has to work...) with a polled
|
||||
I/O scheme, so it's rather slow :-(
|
||||
|
||||
config ATARI_PAMSNET
|
||||
tristate "PAMsNet support"
|
||||
depends on ATARI && ATARI_ACSI && BROKEN
|
||||
help
|
||||
Say Y to include support for the PAMsNet Ethernet adapter for the
|
||||
ACSI port ("ACSI node"). The driver works (has to work...) with a
|
||||
polled I/O scheme, so it's rather slow :-(
|
||||
|
||||
config SUN3LANCE
|
||||
tristate "Sun3/Sun3x on-board LANCE support"
|
||||
depends on SUN3 || SUN3X
|
||||
|
|
|
@ -180,8 +180,6 @@ obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
|
|||
obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
|
||||
obj-$(CONFIG_DECLANCE) += declance.o
|
||||
obj-$(CONFIG_ATARILANCE) += atarilance.o
|
||||
obj-$(CONFIG_ATARI_BIONET) += atari_bionet.o
|
||||
obj-$(CONFIG_ATARI_PAMSNET) += atari_pamsnet.o
|
||||
obj-$(CONFIG_A2065) += a2065.o
|
||||
obj-$(CONFIG_HYDRA) += hydra.o
|
||||
obj-$(CONFIG_ARIADNE) += ariadne.o
|
||||
|
|
|
@ -75,8 +75,6 @@ extern struct net_device *atarilance_probe(int unit);
|
|||
extern struct net_device *sun3lance_probe(int unit);
|
||||
extern struct net_device *sun3_82586_probe(int unit);
|
||||
extern struct net_device *apne_probe(int unit);
|
||||
extern struct net_device *bionet_probe(int unit);
|
||||
extern struct net_device *pamsnet_probe(int unit);
|
||||
extern struct net_device *cs89x0_probe(int unit);
|
||||
extern struct net_device *hplance_probe(int unit);
|
||||
extern struct net_device *bagetlance_probe(int unit);
|
||||
|
@ -264,12 +262,6 @@ static struct devprobe2 m68k_probes[] __initdata = {
|
|||
#ifdef CONFIG_APNE /* A1200 PCMCIA NE2000 */
|
||||
{apne_probe, 0},
|
||||
#endif
|
||||
#ifdef CONFIG_ATARI_BIONET /* Atari Bionet Ethernet board */
|
||||
{bionet_probe, 0},
|
||||
#endif
|
||||
#ifdef CONFIG_ATARI_PAMSNET /* Atari PAMsNet Ethernet board */
|
||||
{pamsnet_probe, 0},
|
||||
#endif
|
||||
#ifdef CONFIG_MVME147_NET /* MVME147 internal Ethernet */
|
||||
{mvme147lance_probe, 0},
|
||||
#endif
|
||||
|
|
|
@ -1,675 +0,0 @@
|
|||
/* bionet.c BioNet-100 device driver for linux68k.
|
||||
*
|
||||
* Version: @(#)bionet.c 1.0 02/06/96
|
||||
*
|
||||
* Author: Hartmut Laue <laue@ifk-mp.uni-kiel.de>
|
||||
* and Torsten Narjes <narjes@ifk-mp.uni-kiel.de>
|
||||
*
|
||||
* Little adaptions for integration into pl7 by Roman Hodek
|
||||
*
|
||||
* Some changes in bionet_poll_rx by Karl-Heinz Lohner
|
||||
*
|
||||
What is it ?
|
||||
------------
|
||||
This driver controls the BIONET-100 LAN-Adapter which connects
|
||||
an ATARI ST/TT via the ACSI-port to an Ethernet-based network.
|
||||
|
||||
This version can be compiled as a loadable module (See the
|
||||
compile command at the bottom of this file).
|
||||
At load time, you can optionally set the debugging level and the
|
||||
fastest response time on the command line of 'insmod'.
|
||||
|
||||
'bionet_debug'
|
||||
controls the amount of diagnostic messages:
|
||||
0 : no messages
|
||||
>0 : see code for meaning of printed messages
|
||||
|
||||
'bionet_min_poll_time' (always >=1)
|
||||
gives the time (in jiffies) between polls. Low values
|
||||
increase the system load (beware!)
|
||||
|
||||
When loaded, a net device with the name 'bio0' becomes available,
|
||||
which can be controlled with the usual 'ifconfig' command.
|
||||
|
||||
It is possible to compile this driver into the kernel like other
|
||||
(net) drivers. For this purpose, some source files (e.g. config-files
|
||||
makefiles, Space.c) must be changed accordingly. (You may refer to
|
||||
other drivers how to do it.) In this case, the device will be detected
|
||||
at boot time and (probably) appear as 'eth0'.
|
||||
|
||||
This code is based on several sources:
|
||||
- The driver code for a parallel port ethernet adapter by
|
||||
Donald Becker (see file 'atp.c' from the PC linux distribution)
|
||||
- The ACSI code by Roman Hodek for the ATARI-ACSI harddisk support
|
||||
and DMA handling.
|
||||
- Very limited information about moving packets in and out of the
|
||||
BIONET-adapter from the TCP package for TOS by BioData GmbH.
|
||||
|
||||
Theory of Operation
|
||||
-------------------
|
||||
Because the ATARI DMA port is usually shared between several
|
||||
devices (eg. harddisk, floppy) we cannot block the ACSI bus
|
||||
while waiting for interrupts. Therefore we use a polling mechanism
|
||||
to fetch packets from the adapter. For the same reason, we send
|
||||
packets without checking that the previous packet has been sent to
|
||||
the LAN. We rely on the higher levels of the networking code to detect
|
||||
missing packets and resend them.
|
||||
|
||||
Before we access the ATARI DMA controller, we check if another
|
||||
process is using the DMA. If not, we lock the DMA, perform one or
|
||||
more packet transfers and unlock the DMA before returning.
|
||||
We do not use 'stdma_lock' unconditionally because it is unclear
|
||||
if the networking code can be set to sleep, which will happen if
|
||||
another (possibly slow) device is using the DMA controller.
|
||||
|
||||
The polling is done via timer interrupts which periodically
|
||||
'simulate' an interrupt from the Ethernet adapter. The time (in jiffies)
|
||||
between polls varies depending on an estimate of the net activity.
|
||||
The allowed range is given by the variable 'bionet_min_poll_time'
|
||||
for the lower (fastest) limit and the constant 'MAX_POLL_TIME'
|
||||
for the higher (slowest) limit.
|
||||
|
||||
Whenever a packet arrives, we switch to fastest response by setting
|
||||
the polling time to its lowest limit. If the following poll fails,
|
||||
because no packets have arrived, we increase the time for the next
|
||||
poll. When the net activity is low, the polling time effectively
|
||||
stays at its maximum value, resulting in the lowest load for the
|
||||
machine.
|
||||
*/
|
||||
|
||||
#define MAX_POLL_TIME 10
|
||||
|
||||
static char version[] =
|
||||
"bionet.c:v1.0 06-feb-96 (c) Hartmut Laue.\n";
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/atarihw.h>
|
||||
#include <asm/atariints.h>
|
||||
#include <asm/atari_acsi.h>
|
||||
#include <asm/atari_stdma.h>
|
||||
|
||||
|
||||
/* use 0 for production, 1 for verification, >2 for debug
|
||||
*/
|
||||
#ifndef NET_DEBUG
|
||||
#define NET_DEBUG 0
|
||||
#endif
|
||||
/*
|
||||
* Global variable 'bionet_debug'. Can be set at load time by 'insmod'
|
||||
*/
|
||||
unsigned int bionet_debug = NET_DEBUG;
|
||||
module_param(bionet_debug, int, 0);
|
||||
MODULE_PARM_DESC(bionet_debug, "bionet debug level (0-2)");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static unsigned int bionet_min_poll_time = 2;
|
||||
|
||||
|
||||
/* Information that need to be kept for each board.
|
||||
*/
|
||||
struct net_local {
|
||||
struct net_device_stats stats;
|
||||
long open_time; /* for debugging */
|
||||
int poll_time; /* polling time varies with net load */
|
||||
};
|
||||
|
||||
static struct nic_pkt_s { /* packet format */
|
||||
unsigned char status;
|
||||
unsigned char dummy;
|
||||
unsigned char l_lo, l_hi;
|
||||
unsigned char buffer[3000];
|
||||
} *nic_packet;
|
||||
unsigned char *phys_nic_packet;
|
||||
|
||||
/* Index to functions, as function prototypes.
|
||||
*/
|
||||
static int bionet_open(struct net_device *dev);
|
||||
static int bionet_send_packet(struct sk_buff *skb, struct net_device *dev);
|
||||
static void bionet_poll_rx(struct net_device *);
|
||||
static int bionet_close(struct net_device *dev);
|
||||
static struct net_device_stats *net_get_stats(struct net_device *dev);
|
||||
static void bionet_tick(unsigned long);
|
||||
|
||||
static DEFINE_TIMER(bionet_timer, bionet_tick, 0, 0);
|
||||
|
||||
#define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
|
||||
|
||||
/* The following routines access the ethernet board connected to the
|
||||
* ACSI port via the st_dma chip.
|
||||
*/
|
||||
#define NODE_ADR 0x60
|
||||
|
||||
#define C_READ 8
|
||||
#define C_WRITE 0x0a
|
||||
#define C_GETEA 0x0f
|
||||
#define C_SETCR 0x0e
|
||||
|
||||
static int
|
||||
sendcmd(unsigned int a0, unsigned int mod, unsigned int cmd) {
|
||||
unsigned int c;
|
||||
|
||||
dma_wd.dma_mode_status = (mod | ((a0) ? 2 : 0) | 0x88);
|
||||
dma_wd.fdc_acces_seccount = cmd;
|
||||
dma_wd.dma_mode_status = (mod | 0x8a);
|
||||
|
||||
if( !acsi_wait_for_IRQ(HZ/2) ) /* wait for cmd ack */
|
||||
return -1; /* timeout */
|
||||
|
||||
c = dma_wd.fdc_acces_seccount;
|
||||
return (c & 0xff);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_status(int cr) {
|
||||
sendcmd(0,0x100,NODE_ADR | C_SETCR); /* CMD: SET CR */
|
||||
sendcmd(1,0x100,cr);
|
||||
|
||||
dma_wd.dma_mode_status = 0x80;
|
||||
}
|
||||
|
||||
static int
|
||||
get_status(unsigned char *adr) {
|
||||
int i,c;
|
||||
|
||||
DISABLE_IRQ();
|
||||
c = sendcmd(0,0x00,NODE_ADR | C_GETEA); /* CMD: GET ETH ADR*/
|
||||
if( c < 0 ) goto gsend;
|
||||
|
||||
/* now read status bytes */
|
||||
|
||||
for (i=0; i<6; i++) {
|
||||
dma_wd.fdc_acces_seccount = 0; /* request next byte */
|
||||
|
||||
if( !acsi_wait_for_IRQ(HZ/2) ) { /* wait for cmd ack */
|
||||
c = -1;
|
||||
goto gsend; /* timeout */
|
||||
}
|
||||
c = dma_wd.fdc_acces_seccount;
|
||||
*adr++ = (unsigned char)c;
|
||||
}
|
||||
c = 1;
|
||||
gsend:
|
||||
dma_wd.dma_mode_status = 0x80;
|
||||
return c;
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
bionet_intr(int irq, void *data) {
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_frame(unsigned long paddr, int odd) {
|
||||
int c;
|
||||
unsigned long flags;
|
||||
|
||||
DISABLE_IRQ();
|
||||
local_irq_save(flags);
|
||||
|
||||
dma_wd.dma_mode_status = 0x9a;
|
||||
dma_wd.dma_mode_status = 0x19a;
|
||||
dma_wd.dma_mode_status = 0x9a;
|
||||
dma_wd.fdc_acces_seccount = 0x04; /* sector count (was 5) */
|
||||
dma_wd.dma_lo = (unsigned char)paddr;
|
||||
paddr >>= 8;
|
||||
dma_wd.dma_md = (unsigned char)paddr;
|
||||
paddr >>= 8;
|
||||
dma_wd.dma_hi = (unsigned char)paddr;
|
||||
local_irq_restore(flags);
|
||||
|
||||
c = sendcmd(0,0x00,NODE_ADR | C_READ); /* CMD: READ */
|
||||
if( c < 128 ) goto rend;
|
||||
|
||||
/* now read block */
|
||||
|
||||
c = sendcmd(1,0x00,odd); /* odd flag for address shift */
|
||||
dma_wd.dma_mode_status = 0x0a;
|
||||
|
||||
if( !acsi_wait_for_IRQ(100) ) { /* wait for DMA to complete */
|
||||
c = -1;
|
||||
goto rend;
|
||||
}
|
||||
dma_wd.dma_mode_status = 0x8a;
|
||||
dma_wd.dma_mode_status = 0x18a;
|
||||
dma_wd.dma_mode_status = 0x8a;
|
||||
c = dma_wd.fdc_acces_seccount;
|
||||
|
||||
dma_wd.dma_mode_status = 0x88;
|
||||
c = dma_wd.fdc_acces_seccount;
|
||||
c = 1;
|
||||
|
||||
rend:
|
||||
dma_wd.dma_mode_status = 0x80;
|
||||
udelay(40);
|
||||
acsi_wait_for_noIRQ(20);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
hardware_send_packet(unsigned long paddr, int cnt) {
|
||||
unsigned int c;
|
||||
unsigned long flags;
|
||||
|
||||
DISABLE_IRQ();
|
||||
local_irq_save(flags);
|
||||
|
||||
dma_wd.dma_mode_status = 0x19a;
|
||||
dma_wd.dma_mode_status = 0x9a;
|
||||
dma_wd.dma_mode_status = 0x19a;
|
||||
dma_wd.dma_lo = (unsigned char)paddr;
|
||||
paddr >>= 8;
|
||||
dma_wd.dma_md = (unsigned char)paddr;
|
||||
paddr >>= 8;
|
||||
dma_wd.dma_hi = (unsigned char)paddr;
|
||||
|
||||
dma_wd.fdc_acces_seccount = 0x4; /* sector count */
|
||||
local_irq_restore(flags);
|
||||
|
||||
c = sendcmd(0,0x100,NODE_ADR | C_WRITE); /* CMD: WRITE */
|
||||
c = sendcmd(1,0x100,cnt&0xff);
|
||||
c = sendcmd(1,0x100,cnt>>8);
|
||||
|
||||
/* now write block */
|
||||
|
||||
dma_wd.dma_mode_status = 0x10a; /* DMA enable */
|
||||
if( !acsi_wait_for_IRQ(100) ) /* wait for DMA to complete */
|
||||
goto end;
|
||||
|
||||
dma_wd.dma_mode_status = 0x19a; /* DMA disable ! */
|
||||
c = dma_wd.fdc_acces_seccount;
|
||||
|
||||
end:
|
||||
c = sendcmd(1,0x100,0);
|
||||
c = sendcmd(1,0x100,0);
|
||||
|
||||
dma_wd.dma_mode_status = 0x180;
|
||||
udelay(40);
|
||||
acsi_wait_for_noIRQ(20);
|
||||
return( c & 0x02);
|
||||
}
|
||||
|
||||
|
||||
/* Check for a network adaptor of this type, and return '0' if one exists.
|
||||
*/
|
||||
struct net_device * __init bionet_probe(int unit)
|
||||
{
|
||||
struct net_device *dev;
|
||||
unsigned char station_addr[6];
|
||||
static unsigned version_printed;
|
||||
static int no_more_found; /* avoid "Probing for..." printed 4 times */
|
||||
int i;
|
||||
int err;
|
||||
|
||||
if (!MACH_IS_ATARI || no_more_found)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
dev = alloc_etherdev(sizeof(struct net_local));
|
||||
if (!dev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (unit >= 0) {
|
||||
sprintf(dev->name, "eth%d", unit);
|
||||
netdev_boot_setup_check(dev);
|
||||
}
|
||||
SET_MODULE_OWNER(dev);
|
||||
|
||||
printk("Probing for BioNet 100 Adapter...\n");
|
||||
|
||||
stdma_lock(bionet_intr, NULL);
|
||||
i = get_status(station_addr); /* Read the station address PROM. */
|
||||
ENABLE_IRQ();
|
||||
stdma_release();
|
||||
|
||||
/* Check the first three octets of the S.A. for the manufactor's code.
|
||||
*/
|
||||
|
||||
if( i < 0
|
||||
|| station_addr[0] != 'B'
|
||||
|| station_addr[1] != 'I'
|
||||
|| station_addr[2] != 'O' ) {
|
||||
no_more_found = 1;
|
||||
printk( "No BioNet 100 found.\n" );
|
||||
free_netdev(dev);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
if (bionet_debug > 0 && version_printed++ == 0)
|
||||
printk(version);
|
||||
|
||||
printk("%s: %s found, eth-addr: %02x-%02x-%02x:%02x-%02x-%02x.\n",
|
||||
dev->name, "BioNet 100",
|
||||
station_addr[0], station_addr[1], station_addr[2],
|
||||
station_addr[3], station_addr[4], station_addr[5]);
|
||||
|
||||
/* Initialize the device structure. */
|
||||
|
||||
nic_packet = (struct nic_pkt_s *)acsi_buffer;
|
||||
phys_nic_packet = (unsigned char *)phys_acsi_buffer;
|
||||
if (bionet_debug > 0) {
|
||||
printk("nic_packet at 0x%p, phys at 0x%p\n",
|
||||
nic_packet, phys_nic_packet );
|
||||
}
|
||||
|
||||
dev->open = bionet_open;
|
||||
dev->stop = bionet_close;
|
||||
dev->hard_start_xmit = bionet_send_packet;
|
||||
dev->get_stats = net_get_stats;
|
||||
|
||||
/* Fill in the fields of the device structure with ethernet-generic
|
||||
* values. This should be in a common file instead of per-driver.
|
||||
*/
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
#if 0
|
||||
dev->broadcast[i] = 0xff;
|
||||
#endif
|
||||
dev->dev_addr[i] = station_addr[i];
|
||||
}
|
||||
err = register_netdev(dev);
|
||||
if (!err)
|
||||
return dev;
|
||||
free_netdev(dev);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/* Open/initialize the board. This is called (in the current kernel)
|
||||
sometime after booting when the 'ifconfig' program is run.
|
||||
|
||||
This routine should set everything up anew at each open, even
|
||||
registers that "should" only need to be set once at boot, so that
|
||||
there is non-reboot way to recover if something goes wrong.
|
||||
*/
|
||||
static int
|
||||
bionet_open(struct net_device *dev) {
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
|
||||
if (bionet_debug > 0)
|
||||
printk("bionet_open\n");
|
||||
stdma_lock(bionet_intr, NULL);
|
||||
|
||||
/* Reset the hardware here.
|
||||
*/
|
||||
set_status(4);
|
||||
lp->open_time = 0; /*jiffies*/
|
||||
lp->poll_time = MAX_POLL_TIME;
|
||||
|
||||
dev->tbusy = 0;
|
||||
dev->interrupt = 0;
|
||||
dev->start = 1;
|
||||
|
||||
stdma_release();
|
||||
bionet_timer.data = (long)dev;
|
||||
bionet_timer.expires = jiffies + lp->poll_time;
|
||||
add_timer(&bionet_timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bionet_send_packet(struct sk_buff *skb, struct net_device *dev) {
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
unsigned long flags;
|
||||
|
||||
/* Block a timer-based transmit from overlapping. This could better be
|
||||
* done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
|
||||
if (stdma_islocked()) {
|
||||
local_irq_restore(flags);
|
||||
lp->stats.tx_errors++;
|
||||
}
|
||||
else {
|
||||
int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
|
||||
unsigned long buf = virt_to_phys(skb->data);
|
||||
int stat;
|
||||
|
||||
stdma_lock(bionet_intr, NULL);
|
||||
local_irq_restore(flags);
|
||||
if( !STRAM_ADDR(buf+length-1) ) {
|
||||
skb_copy_from_linear_data(skb, nic_packet->buffer,
|
||||
length);
|
||||
buf = (unsigned long)&((struct nic_pkt_s *)phys_nic_packet)->buffer;
|
||||
}
|
||||
|
||||
if (bionet_debug >1) {
|
||||
u_char *data = nic_packet->buffer, *p;
|
||||
int i;
|
||||
|
||||
printk( "%s: TX pkt type 0x%4x from ", dev->name,
|
||||
((u_short *)data)[6]);
|
||||
|
||||
for( p = &data[6], i = 0; i < 6; i++ )
|
||||
printk("%02x%s", *p++,i != 5 ? ":" : "" );
|
||||
printk(" to ");
|
||||
|
||||
for( p = data, i = 0; i < 6; i++ )
|
||||
printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" );
|
||||
|
||||
printk( "%s: ", dev->name );
|
||||
printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x"
|
||||
" %02x%02x%02x%02x len %d\n",
|
||||
data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19],
|
||||
data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27],
|
||||
data[28], data[29], data[30], data[31], data[32], data[33],
|
||||
length );
|
||||
}
|
||||
dma_cache_maintenance(buf, length, 1);
|
||||
|
||||
stat = hardware_send_packet(buf, length);
|
||||
ENABLE_IRQ();
|
||||
stdma_release();
|
||||
|
||||
dev->trans_start = jiffies;
|
||||
dev->tbusy = 0;
|
||||
lp->stats.tx_packets++;
|
||||
lp->stats.tx_bytes+=length;
|
||||
}
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We have a good packet(s), get it/them out of the buffers.
|
||||
*/
|
||||
static void
|
||||
bionet_poll_rx(struct net_device *dev) {
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
int boguscount = 10;
|
||||
int pkt_len, status;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
/* ++roman: Take care at locking the ST-DMA... This must be done with ints
|
||||
* off, since otherwise an int could slip in between the question and the
|
||||
* locking itself, and then we'd go to sleep... And locking itself is
|
||||
* necessary to keep the floppy_change timer from working with ST-DMA
|
||||
* registers. */
|
||||
if (stdma_islocked()) {
|
||||
local_irq_restore(flags);
|
||||
return;
|
||||
}
|
||||
stdma_lock(bionet_intr, NULL);
|
||||
DISABLE_IRQ();
|
||||
local_irq_restore(flags);
|
||||
|
||||
if( lp->poll_time < MAX_POLL_TIME ) lp->poll_time++;
|
||||
|
||||
while(boguscount--) {
|
||||
status = get_frame((unsigned long)phys_nic_packet, 0);
|
||||
|
||||
if( status == 0 ) break;
|
||||
|
||||
/* Good packet... */
|
||||
|
||||
dma_cache_maintenance((unsigned long)phys_nic_packet, 1520, 0);
|
||||
|
||||
pkt_len = (nic_packet->l_hi << 8) | nic_packet->l_lo;
|
||||
|
||||
lp->poll_time = bionet_min_poll_time; /* fast poll */
|
||||
if( pkt_len >= 60 && pkt_len <= 1520 ) {
|
||||
/* ^^^^ war 1514 KHL */
|
||||
/* Malloc up new buffer.
|
||||
*/
|
||||
struct sk_buff *skb = dev_alloc_skb( pkt_len + 2 );
|
||||
if (skb == NULL) {
|
||||
printk("%s: Memory squeeze, dropping packet.\n",
|
||||
dev->name);
|
||||
lp->stats.rx_dropped++;
|
||||
break;
|
||||
}
|
||||
|
||||
skb_reserve( skb, 2 ); /* 16 Byte align */
|
||||
skb_put( skb, pkt_len ); /* make room */
|
||||
|
||||
/* 'skb->data' points to the start of sk_buff data area.
|
||||
*/
|
||||
skb_copy_to_linear_data(skb, nic_packet->buffer,
|
||||
pkt_len);
|
||||
skb->protocol = eth_type_trans( skb, dev );
|
||||
netif_rx(skb);
|
||||
dev->last_rx = jiffies;
|
||||
lp->stats.rx_packets++;
|
||||
lp->stats.rx_bytes+=pkt_len;
|
||||
|
||||
/* If any worth-while packets have been received, dev_rint()
|
||||
has done a mark_bh(INET_BH) for us and will work on them
|
||||
when we get to the bottom-half routine.
|
||||
*/
|
||||
|
||||
if (bionet_debug >1) {
|
||||
u_char *data = nic_packet->buffer, *p;
|
||||
int i;
|
||||
|
||||
printk( "%s: RX pkt type 0x%4x from ", dev->name,
|
||||
((u_short *)data)[6]);
|
||||
|
||||
|
||||
for( p = &data[6], i = 0; i < 6; i++ )
|
||||
printk("%02x%s", *p++,i != 5 ? ":" : "" );
|
||||
printk(" to ");
|
||||
for( p = data, i = 0; i < 6; i++ )
|
||||
printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" );
|
||||
|
||||
printk( "%s: ", dev->name );
|
||||
printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x"
|
||||
" %02x%02x%02x%02x len %d\n",
|
||||
data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19],
|
||||
data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27],
|
||||
data[28], data[29], data[30], data[31], data[32], data[33],
|
||||
pkt_len );
|
||||
}
|
||||
}
|
||||
else {
|
||||
printk(" Packet has wrong length: %04d bytes\n", pkt_len);
|
||||
lp->stats.rx_errors++;
|
||||
}
|
||||
}
|
||||
stdma_release();
|
||||
ENABLE_IRQ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* bionet_tick: called by bionet_timer. Reads packets from the adapter,
|
||||
* passes them to the higher layers and restarts the timer.
|
||||
*/
|
||||
static void
|
||||
bionet_tick(unsigned long data) {
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
|
||||
if( bionet_debug > 0 && (lp->open_time++ & 7) == 8 )
|
||||
printk("bionet_tick: %ld\n", lp->open_time);
|
||||
|
||||
if( !stdma_islocked() ) bionet_poll_rx(dev);
|
||||
|
||||
bionet_timer.expires = jiffies + lp->poll_time;
|
||||
add_timer(&bionet_timer);
|
||||
}
|
||||
|
||||
/* The inverse routine to bionet_open().
|
||||
*/
|
||||
static int
|
||||
bionet_close(struct net_device *dev) {
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
|
||||
if (bionet_debug > 0)
|
||||
printk("bionet_close, open_time=%ld\n", lp->open_time);
|
||||
del_timer(&bionet_timer);
|
||||
stdma_lock(bionet_intr, NULL);
|
||||
|
||||
set_status(0);
|
||||
lp->open_time = 0;
|
||||
|
||||
dev->tbusy = 1;
|
||||
dev->start = 0;
|
||||
|
||||
stdma_release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the current statistics.
|
||||
This may be called with the card open or closed.
|
||||
*/
|
||||
static struct net_device_stats *net_get_stats(struct net_device *dev)
|
||||
{
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
return &lp->stats;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MODULE
|
||||
|
||||
static struct net_device *bio_dev;
|
||||
|
||||
int init_module(void)
|
||||
{
|
||||
bio_dev = bionet_probe(-1);
|
||||
if (IS_ERR(bio_dev))
|
||||
return PTR_ERR(bio_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanup_module(void)
|
||||
{
|
||||
unregister_netdev(bio_dev);
|
||||
free_netdev(bio_dev);
|
||||
}
|
||||
|
||||
#endif /* MODULE */
|
||||
|
||||
/* Local variables:
|
||||
* compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include
|
||||
-b m68k-linuxaout -Wall -Wstrict-prototypes -O2
|
||||
-fomit-frame-pointer -pipe -DMODULE -I../../net/inet -c bionet.c"
|
||||
* version-control: t
|
||||
* kept-new-versions: 5
|
||||
* tab-width: 8
|
||||
* End:
|
||||
*/
|
|
@ -1,878 +0,0 @@
|
|||
/* atari_pamsnet.c PAMsNet device driver for linux68k.
|
||||
*
|
||||
* Version: @(#)PAMsNet.c 0.2ß 03/31/96
|
||||
*
|
||||
* Author: Torsten Lang <Torsten.Lang@ap.physik.uni-giessen.de>
|
||||
* <Torsten.Lang@jung.de>
|
||||
*
|
||||
* This driver is based on my driver PAMSDMA.c for MiNT-Net and
|
||||
* on the driver bionet.c written by
|
||||
* Hartmut Laue <laue@ifk-mp.uni-kiel.de>
|
||||
* and Torsten Narjes <narjes@ifk-mp.uni-kiel.de>
|
||||
*
|
||||
* Little adaptions for integration into pl7 by Roman Hodek
|
||||
*
|
||||
What is it ?
|
||||
------------
|
||||
This driver controls the PAMsNet LAN-Adapter which connects
|
||||
an ATARI ST/TT via the ACSI-port to an Ethernet-based network.
|
||||
|
||||
This version can be compiled as a loadable module (See the
|
||||
compile command at the bottom of this file).
|
||||
At load time, you can optionally set the debugging level and the
|
||||
fastest response time on the command line of 'insmod'.
|
||||
|
||||
'pamsnet_debug'
|
||||
controls the amount of diagnostic messages:
|
||||
0 : no messages
|
||||
>0 : see code for meaning of printed messages
|
||||
|
||||
'pamsnet_min_poll_time' (always >=1)
|
||||
gives the time (in jiffies) between polls. Low values
|
||||
increase the system load (beware!)
|
||||
|
||||
When loaded, a net device with the name 'eth?' becomes available,
|
||||
which can be controlled with the usual 'ifconfig' command.
|
||||
|
||||
It is possible to compile this driver into the kernel like other
|
||||
(net) drivers. For this purpose, some source files (e.g. config-files
|
||||
makefiles, Space.c) must be changed accordingly. (You may refer to
|
||||
other drivers how to do it.) In this case, the device will be detected
|
||||
at boot time and (probably) appear as 'eth0'.
|
||||
|
||||
Theory of Operation
|
||||
-------------------
|
||||
Because the ATARI DMA port is usually shared between several
|
||||
devices (eg. harddisk, floppy) we cannot block the ACSI bus
|
||||
while waiting for interrupts. Therefore we use a polling mechanism
|
||||
to fetch packets from the adapter. For the same reason, we send
|
||||
packets without checking that the previous packet has been sent to
|
||||
the LAN. We rely on the higher levels of the networking code to detect
|
||||
missing packets and resend them.
|
||||
|
||||
Before we access the ATARI DMA controller, we check if another
|
||||
process is using the DMA. If not, we lock the DMA, perform one or
|
||||
more packet transfers and unlock the DMA before returning.
|
||||
We do not use 'stdma_lock' unconditionally because it is unclear
|
||||
if the networking code can be set to sleep, which will happen if
|
||||
another (possibly slow) device is using the DMA controller.
|
||||
|
||||
The polling is done via timer interrupts which periodically
|
||||
'simulate' an interrupt from the Ethernet adapter. The time (in jiffies)
|
||||
between polls varies depending on an estimate of the net activity.
|
||||
The allowed range is given by the variable 'bionet_min_poll_time'
|
||||
for the lower (fastest) limit and the constant 'MAX_POLL_TIME'
|
||||
for the higher (slowest) limit.
|
||||
|
||||
Whenever a packet arrives, we switch to fastest response by setting
|
||||
the polling time to its lowest limit. If the following poll fails,
|
||||
because no packets have arrived, we increase the time for the next
|
||||
poll. When the net activity is low, the polling time effectively
|
||||
stays at its maximum value, resulting in the lowest load for the
|
||||
machine.
|
||||
*/
|
||||
|
||||
#define MAX_POLL_TIME 10
|
||||
|
||||
static char *version =
|
||||
"pamsnet.c:v0.2beta 30-mar-96 (c) Torsten Lang.\n";
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/dma.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/atarihw.h>
|
||||
#include <asm/atariints.h>
|
||||
#include <asm/atari_stdma.h>
|
||||
#include <asm/atari_acsi.h>
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#undef READ
|
||||
#undef WRITE
|
||||
|
||||
/* use 0 for production, 1 for verification, >2 for debug
|
||||
*/
|
||||
#ifndef NET_DEBUG
|
||||
#define NET_DEBUG 0
|
||||
#endif
|
||||
/*
|
||||
* Global variable 'pamsnet_debug'. Can be set at load time by 'insmod'
|
||||
*/
|
||||
unsigned int pamsnet_debug = NET_DEBUG;
|
||||
module_param(pamsnet_debug, int, 0);
|
||||
MODULE_PARM_DESC(pamsnet_debug, "pamsnet debug enable (0-1)");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static unsigned int pamsnet_min_poll_time = 2;
|
||||
|
||||
|
||||
/* Information that need to be kept for each board.
|
||||
*/
|
||||
struct net_local {
|
||||
struct net_device_stats stats;
|
||||
long open_time; /* for debugging */
|
||||
int poll_time; /* polling time varies with net load */
|
||||
};
|
||||
|
||||
static struct nic_pkt_s { /* packet format */
|
||||
unsigned char buffer[2048];
|
||||
} *nic_packet = 0;
|
||||
unsigned char *phys_nic_packet;
|
||||
|
||||
typedef unsigned char HADDR[6]; /* 6-byte hardware address of lance */
|
||||
|
||||
/* Index to functions, as function prototypes.
|
||||
*/
|
||||
static void start (int target);
|
||||
static int stop (int target);
|
||||
static int testpkt (int target);
|
||||
static int sendpkt (int target, unsigned char *buffer, int length);
|
||||
static int receivepkt (int target, unsigned char *buffer);
|
||||
static int inquiry (int target, unsigned char *buffer);
|
||||
static HADDR *read_hw_addr(int target, unsigned char *buffer);
|
||||
static void setup_dma (void *address, unsigned rw_flag, int num_blocks);
|
||||
static int send_first (int target, unsigned char byte);
|
||||
static int send_1_5 (int lun, unsigned char *command, int dma);
|
||||
static int get_status (void);
|
||||
static int calc_received (void *start_address);
|
||||
|
||||
static int pamsnet_open(struct net_device *dev);
|
||||
static int pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev);
|
||||
static void pamsnet_poll_rx(struct net_device *);
|
||||
static int pamsnet_close(struct net_device *dev);
|
||||
static struct net_device_stats *net_get_stats(struct net_device *dev);
|
||||
static void pamsnet_tick(unsigned long);
|
||||
|
||||
static irqreturn_t pamsnet_intr(int irq, void *data);
|
||||
|
||||
static DEFINE_TIMER(pamsnet_timer, pamsnet_tick, 0, 0);
|
||||
|
||||
#define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char reserved1[0x38];
|
||||
HADDR hwaddr;
|
||||
unsigned char reserved2[0x1c2];
|
||||
} DMAHWADDR;
|
||||
|
||||
/*
|
||||
* Definitions of commands understood by the PAMs DMA adaptor.
|
||||
*
|
||||
* In general the DMA adaptor uses LUN 0, 5, 6 and 7 on one ID changeable
|
||||
* by the PAM's Net software.
|
||||
*
|
||||
* LUN 0 works as a harddisk. You can boot the PAM's Net driver there.
|
||||
* LUN 5 works as a harddisk and lets you access the RAM and some I/O HW
|
||||
* area. In sector 0, bytes 0x38-0x3d you find the ethernet HW address
|
||||
* of the adaptor.
|
||||
* LUN 6 works as a harddisk and lets you access the firmware ROM.
|
||||
* LUN 7 lets you send and receive packets.
|
||||
*
|
||||
* Some commands like the INQUIRY command work identical on all used LUNs.
|
||||
*
|
||||
* UNKNOWN1 seems to read some data.
|
||||
* Command length is 6 bytes.
|
||||
* UNKNOWN2 seems to read some data (command byte 1 must be !=0). The
|
||||
* following bytes seem to be something like an allocation length.
|
||||
* Command length is 6 bytes.
|
||||
* READPKT reads a packet received by the DMA adaptor.
|
||||
* Command length is 6 bytes.
|
||||
* WRITEPKT sends a packet transferred by the following DMA phase. The length
|
||||
* of the packet is transferred in command bytes 3 and 4.
|
||||
* The adaptor automatically replaces the src hw address in an ethernet
|
||||
* packet by its own hw address.
|
||||
* Command length is 6 bytes.
|
||||
* INQUIRY has the same function as the INQUIRY command supported by harddisks
|
||||
* and other SCSI devices. It lets you detect which device you found
|
||||
* at a given address.
|
||||
* Command length is 6 bytes.
|
||||
* START initializes the DMA adaptor. After this command it is able to send
|
||||
* and receive packets. There is no status byte returned!
|
||||
* Command length is 1 byte.
|
||||
* NUMPKTS gives back the number of received packets waiting in the queue in
|
||||
* the status byte.
|
||||
* Command length is 1 byte.
|
||||
* UNKNOWN3
|
||||
* UNKNOWN4 Function of these three commands is unknown.
|
||||
* UNKNOWN5 The command length of these three commands is 1 byte.
|
||||
* DESELECT immediately deselects the DMA adaptor. May important with interrupt
|
||||
* driven operation.
|
||||
* Command length is 1 byte.
|
||||
* STOP resets the DMA adaptor. After this command packets can no longer
|
||||
* be received or transferred.
|
||||
* Command length is 6 byte.
|
||||
*/
|
||||
|
||||
enum {UNKNOWN1=3, READPKT=8, UNKNOWN2, WRITEPKT=10, INQUIRY=18, START,
|
||||
NUMPKTS=22, UNKNOWN3, UNKNOWN4, UNKNOWN5, DESELECT, STOP};
|
||||
|
||||
#define READSECTOR READPKT
|
||||
#define WRITESECTOR WRITEPKT
|
||||
|
||||
u_char *inquire8="MV PAM's NET/GK";
|
||||
|
||||
#define DMALOW dma_wd.dma_lo
|
||||
#define DMAMID dma_wd.dma_md
|
||||
#define DMAHIGH dma_wd.dma_hi
|
||||
#define DACCESS dma_wd.fdc_acces_seccount
|
||||
|
||||
#define MFP_GPIP mfp.par_dt_reg
|
||||
|
||||
/* Some useful functions */
|
||||
|
||||
#define INT (!(MFP_GPIP & 0x20))
|
||||
#define DELAY ({MFP_GPIP; MFP_GPIP; MFP_GPIP;})
|
||||
#define WRITEMODE(value) \
|
||||
({ u_short dummy = value; \
|
||||
__asm__ volatile("movew %0, 0xFFFF8606" : : "d"(dummy)); \
|
||||
DELAY; \
|
||||
})
|
||||
#define WRITEBOTH(value1, value2) \
|
||||
({ u_long dummy = (u_long)(value1)<<16 | (u_short)(value2); \
|
||||
__asm__ volatile("movel %0, 0xFFFF8604" : : "d"(dummy)); \
|
||||
DELAY; \
|
||||
})
|
||||
|
||||
/* Definitions for DMODE */
|
||||
|
||||
#define READ 0x000
|
||||
#define WRITE 0x100
|
||||
|
||||
#define DMA_FDC 0x080
|
||||
#define DMA_ACSI 0x000
|
||||
|
||||
#define DMA_DISABLE 0x040
|
||||
|
||||
#define SEC_COUNT 0x010
|
||||
#define DMA_WINDOW 0x000
|
||||
|
||||
#define REG_ACSI 0x008
|
||||
#define REG_FDC 0x000
|
||||
|
||||
#define A1 0x002
|
||||
|
||||
/* Timeout constants */
|
||||
|
||||
#define TIMEOUTCMD HZ/2 /* ca. 500ms */
|
||||
#define TIMEOUTDMA HZ /* ca. 1s */
|
||||
#define COMMAND_DELAY 500 /* ca. 0.5ms */
|
||||
|
||||
unsigned rw;
|
||||
int lance_target = -1;
|
||||
int if_up = 0;
|
||||
|
||||
/* The following routines access the ethernet board connected to the
|
||||
* ACSI port via the st_dma chip.
|
||||
*/
|
||||
|
||||
/* The following lowlevel routines work on physical addresses only and assume
|
||||
* that eventually needed buffers are
|
||||
* - completely located in ST RAM
|
||||
* - are contigous in the physical address space
|
||||
*/
|
||||
|
||||
/* Setup the DMA counter */
|
||||
|
||||
static void
|
||||
setup_dma (void *address, unsigned rw_flag, int num_blocks)
|
||||
{
|
||||
WRITEMODE((unsigned) rw_flag | DMA_FDC | SEC_COUNT | REG_ACSI |
|
||||
A1);
|
||||
WRITEMODE((unsigned)(rw_flag ^ WRITE) | DMA_FDC | SEC_COUNT | REG_ACSI |
|
||||
A1);
|
||||
WRITEMODE((unsigned) rw_flag | DMA_FDC | SEC_COUNT | REG_ACSI |
|
||||
A1);
|
||||
DMALOW = (unsigned char)((unsigned long)address & 0xFF);
|
||||
DMAMID = (unsigned char)(((unsigned long)address >> 8) & 0xFF);
|
||||
DMAHIGH = (unsigned char)(((unsigned long)address >> 16) & 0xFF);
|
||||
WRITEBOTH((unsigned)num_blocks & 0xFF,
|
||||
rw_flag | DMA_FDC | DMA_WINDOW | REG_ACSI | A1);
|
||||
rw = rw_flag;
|
||||
}
|
||||
|
||||
/* Send the first byte of an command block */
|
||||
|
||||
static int
|
||||
send_first (int target, unsigned char byte)
|
||||
{
|
||||
rw = READ;
|
||||
acsi_delay_end(COMMAND_DELAY);
|
||||
/*
|
||||
* wake up ACSI
|
||||
*/
|
||||
WRITEMODE(DMA_FDC | DMA_WINDOW | REG_ACSI);
|
||||
/*
|
||||
* write command byte
|
||||
*/
|
||||
WRITEBOTH((target << 5) | (byte & 0x1F), DMA_FDC |
|
||||
DMA_WINDOW | REG_ACSI | A1);
|
||||
return (!acsi_wait_for_IRQ(TIMEOUTCMD));
|
||||
}
|
||||
|
||||
/* Send the rest of an command block */
|
||||
|
||||
static int
|
||||
send_1_5 (int lun, unsigned char *command, int dma)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<5; i++) {
|
||||
WRITEBOTH((!i ? (((lun & 0x7) << 5) | (command[i] & 0x1F))
|
||||
: command[i]),
|
||||
rw | REG_ACSI | DMA_WINDOW |
|
||||
((i < 4) ? DMA_FDC
|
||||
: (dma ? DMA_ACSI
|
||||
: DMA_FDC)) | A1);
|
||||
if (i < 4 && (j = !acsi_wait_for_IRQ(TIMEOUTCMD)))
|
||||
return (j);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Read a status byte */
|
||||
|
||||
static int
|
||||
get_status (void)
|
||||
{
|
||||
WRITEMODE(DMA_FDC | DMA_WINDOW | REG_ACSI | A1);
|
||||
acsi_delay_start();
|
||||
return ((int)(DACCESS & 0xFF));
|
||||
}
|
||||
|
||||
/* Calculate the number of received bytes */
|
||||
|
||||
static int
|
||||
calc_received (void *start_address)
|
||||
{
|
||||
return (int)(
|
||||
(((unsigned long)DMAHIGH << 16) | ((unsigned)DMAMID << 8) | DMALOW)
|
||||
- (unsigned long)start_address);
|
||||
}
|
||||
|
||||
/* The following midlevel routines still work on physical addresses ... */
|
||||
|
||||
/* start() starts the PAM's DMA adaptor */
|
||||
|
||||
static void
|
||||
start (int target)
|
||||
{
|
||||
send_first(target, START);
|
||||
}
|
||||
|
||||
/* stop() stops the PAM's DMA adaptor and returns a value of zero in case of success */
|
||||
|
||||
static int
|
||||
stop (int target)
|
||||
{
|
||||
int ret = -1;
|
||||
unsigned char cmd_buffer[5];
|
||||
|
||||
if (send_first(target, STOP))
|
||||
goto bad;
|
||||
cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[2] =
|
||||
cmd_buffer[3] = cmd_buffer[4] = 0;
|
||||
if (send_1_5(7, cmd_buffer, 0) ||
|
||||
!acsi_wait_for_IRQ(TIMEOUTDMA) ||
|
||||
get_status())
|
||||
goto bad;
|
||||
ret = 0;
|
||||
bad:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* testpkt() returns the number of received packets waiting in the queue */
|
||||
|
||||
static int
|
||||
testpkt(int target)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (send_first(target, NUMPKTS))
|
||||
goto bad;
|
||||
ret = get_status();
|
||||
bad:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* inquiry() returns 0 when PAM's DMA found, -1 when timeout, -2 otherwise */
|
||||
/* Please note: The buffer is for internal use only but must be defined! */
|
||||
|
||||
static int
|
||||
inquiry (int target, unsigned char *buffer)
|
||||
{
|
||||
int ret = -1;
|
||||
unsigned char *vbuffer = phys_to_virt((unsigned long)buffer);
|
||||
unsigned char cmd_buffer[5];
|
||||
|
||||
if (send_first(target, INQUIRY))
|
||||
goto bad;
|
||||
setup_dma(buffer, READ, 1);
|
||||
vbuffer[8] = vbuffer[27] = 0; /* Avoid confusion with previous read data */
|
||||
cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[2] = cmd_buffer[4] = 0;
|
||||
cmd_buffer[3] = 48;
|
||||
if (send_1_5(5, cmd_buffer, 1) ||
|
||||
!acsi_wait_for_IRQ(TIMEOUTDMA) ||
|
||||
get_status() ||
|
||||
(calc_received(buffer) < 32))
|
||||
goto bad;
|
||||
dma_cache_maintenance((unsigned long)(buffer+8), 20, 0);
|
||||
if (memcmp(inquire8, vbuffer+8, 20))
|
||||
goto bad;
|
||||
ret = 0;
|
||||
bad:
|
||||
if (!!NET_DEBUG) {
|
||||
vbuffer[8+20]=0;
|
||||
printk("inquiry of target %d: %s\n", target, vbuffer+8);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* read_hw_addr() reads the sector containing the hwaddr and returns
|
||||
* a pointer to it (virtual address!) or 0 in case of an error
|
||||
*/
|
||||
|
||||
static HADDR
|
||||
*read_hw_addr(int target, unsigned char *buffer)
|
||||
{
|
||||
HADDR *ret = 0;
|
||||
unsigned char cmd_buffer[5];
|
||||
|
||||
if (send_first(target, READSECTOR))
|
||||
goto bad;
|
||||
setup_dma(buffer, READ, 1);
|
||||
cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[2] = cmd_buffer[4] = 0;
|
||||
cmd_buffer[3] = 1;
|
||||
if (send_1_5(5, cmd_buffer, 1) ||
|
||||
!acsi_wait_for_IRQ(TIMEOUTDMA) ||
|
||||
get_status())
|
||||
goto bad;
|
||||
ret = phys_to_virt((unsigned long)&(((DMAHWADDR *)buffer)->hwaddr));
|
||||
dma_cache_maintenance((unsigned long)buffer, 512, 0);
|
||||
bad:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
pamsnet_intr(int irq, void *data)
|
||||
{
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* receivepkt() loads a packet to a given buffer and returns its length */
|
||||
|
||||
static int
|
||||
receivepkt (int target, unsigned char *buffer)
|
||||
{
|
||||
int ret = -1;
|
||||
unsigned char cmd_buffer[5];
|
||||
|
||||
if (send_first(target, READPKT))
|
||||
goto bad;
|
||||
setup_dma(buffer, READ, 3);
|
||||
cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[2] = cmd_buffer[4] = 0;
|
||||
cmd_buffer[3] = 3;
|
||||
if (send_1_5(7, cmd_buffer, 1) ||
|
||||
!acsi_wait_for_IRQ(TIMEOUTDMA) ||
|
||||
get_status())
|
||||
goto bad;
|
||||
ret = calc_received(buffer);
|
||||
bad:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* sendpkt() sends a packet and returns a value of zero when the packet was sent
|
||||
successfully */
|
||||
|
||||
static int
|
||||
sendpkt (int target, unsigned char *buffer, int length)
|
||||
{
|
||||
int ret = -1;
|
||||
unsigned char cmd_buffer[5];
|
||||
|
||||
if (send_first(target, WRITEPKT))
|
||||
goto bad;
|
||||
setup_dma(buffer, WRITE, 3);
|
||||
cmd_buffer[0] = cmd_buffer[1] = cmd_buffer[4] = 0;
|
||||
cmd_buffer[2] = length >> 8;
|
||||
cmd_buffer[3] = length & 0xFF;
|
||||
if (send_1_5(7, cmd_buffer, 1) ||
|
||||
!acsi_wait_for_IRQ(TIMEOUTDMA) ||
|
||||
get_status())
|
||||
goto bad;
|
||||
ret = 0;
|
||||
bad:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* The following higher level routines work on virtual addresses and convert them to
|
||||
* physical addresses when passed to the lowlevel routines. It's up to the higher level
|
||||
* routines to copy data from Alternate RAM to ST RAM if neccesary!
|
||||
*/
|
||||
|
||||
/* Check for a network adaptor of this type, and return '0' if one exists.
|
||||
*/
|
||||
|
||||
struct net_device * __init pamsnet_probe (int unit)
|
||||
{
|
||||
struct net_device *dev;
|
||||
int i;
|
||||
HADDR *hwaddr;
|
||||
int err;
|
||||
|
||||
unsigned char station_addr[6];
|
||||
static unsigned version_printed;
|
||||
/* avoid "Probing for..." printed 4 times - the driver is supporting only one adapter now! */
|
||||
static int no_more_found;
|
||||
|
||||
if (no_more_found)
|
||||
return ERR_PTR(-ENODEV);
|
||||
no_more_found = 1;
|
||||
|
||||
dev = alloc_etherdev(sizeof(struct net_local));
|
||||
if (!dev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (unit >= 0) {
|
||||
sprintf(dev->name, "eth%d", unit);
|
||||
netdev_boot_setup_check(dev);
|
||||
}
|
||||
SET_MODULE_OWNER(dev);
|
||||
|
||||
printk("Probing for PAM's Net/GK Adapter...\n");
|
||||
|
||||
/* Allocate the DMA buffer here since we need it for probing! */
|
||||
|
||||
nic_packet = (struct nic_pkt_s *)acsi_buffer;
|
||||
phys_nic_packet = (unsigned char *)phys_acsi_buffer;
|
||||
if (pamsnet_debug > 0) {
|
||||
printk("nic_packet at 0x%p, phys at 0x%p\n",
|
||||
nic_packet, phys_nic_packet );
|
||||
}
|
||||
|
||||
stdma_lock(pamsnet_intr, NULL);
|
||||
DISABLE_IRQ();
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
/* Do two inquiries to cover cases with strange equipment on previous ID */
|
||||
/* blocking the ACSI bus (like the SLMC804 laser printer controller... */
|
||||
inquiry(i, phys_nic_packet);
|
||||
if (!inquiry(i, phys_nic_packet)) {
|
||||
lance_target = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!!NET_DEBUG)
|
||||
printk("ID: %d\n",i);
|
||||
|
||||
if (lance_target >= 0) {
|
||||
if (!(hwaddr = read_hw_addr(lance_target, phys_nic_packet)))
|
||||
lance_target = -1;
|
||||
else
|
||||
memcpy (station_addr, hwaddr, ETH_ALEN);
|
||||
}
|
||||
|
||||
ENABLE_IRQ();
|
||||
stdma_release();
|
||||
|
||||
if (lance_target < 0) {
|
||||
printk("No PAM's Net/GK found.\n");
|
||||
free_netdev(dev);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
if (pamsnet_debug > 0 && version_printed++ == 0)
|
||||
printk(version);
|
||||
|
||||
printk("%s: %s found on target %01d, eth-addr: %02x:%02x:%02x:%02x:%02x:%02x.\n",
|
||||
dev->name, "PAM's Net/GK", lance_target,
|
||||
station_addr[0], station_addr[1], station_addr[2],
|
||||
station_addr[3], station_addr[4], station_addr[5]);
|
||||
|
||||
/* Initialize the device structure. */
|
||||
dev->open = pamsnet_open;
|
||||
dev->stop = pamsnet_close;
|
||||
dev->hard_start_xmit = pamsnet_send_packet;
|
||||
dev->get_stats = net_get_stats;
|
||||
|
||||
/* Fill in the fields of the device structure with ethernet-generic
|
||||
* values. This should be in a common file instead of per-driver.
|
||||
*/
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
#if 0
|
||||
dev->broadcast[i] = 0xff;
|
||||
#endif
|
||||
dev->dev_addr[i] = station_addr[i];
|
||||
}
|
||||
err = register_netdev(dev);
|
||||
if (!err)
|
||||
return dev;
|
||||
|
||||
free_netdev(dev);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/* Open/initialize the board. This is called (in the current kernel)
|
||||
sometime after booting when the 'ifconfig' program is run.
|
||||
|
||||
This routine should set everything up anew at each open, even
|
||||
registers that "should" only need to be set once at boot, so that
|
||||
there is non-reboot way to recover if something goes wrong.
|
||||
*/
|
||||
static int
|
||||
pamsnet_open(struct net_device *dev)
|
||||
{
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
|
||||
if (pamsnet_debug > 0)
|
||||
printk("pamsnet_open\n");
|
||||
stdma_lock(pamsnet_intr, NULL);
|
||||
DISABLE_IRQ();
|
||||
|
||||
/* Reset the hardware here.
|
||||
*/
|
||||
if (!if_up)
|
||||
start(lance_target);
|
||||
if_up = 1;
|
||||
lp->open_time = 0; /*jiffies*/
|
||||
lp->poll_time = MAX_POLL_TIME;
|
||||
|
||||
dev->tbusy = 0;
|
||||
dev->interrupt = 0;
|
||||
dev->start = 1;
|
||||
|
||||
ENABLE_IRQ();
|
||||
stdma_release();
|
||||
pamsnet_timer.data = (long)dev;
|
||||
pamsnet_timer.expires = jiffies + lp->poll_time;
|
||||
add_timer(&pamsnet_timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
unsigned long flags;
|
||||
|
||||
/* Block a timer-based transmit from overlapping. This could better be
|
||||
* done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
|
||||
if (stdma_islocked()) {
|
||||
local_irq_restore(flags);
|
||||
lp->stats.tx_errors++;
|
||||
}
|
||||
else {
|
||||
int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
|
||||
unsigned long buf = virt_to_phys(skb->data);
|
||||
int stat;
|
||||
|
||||
stdma_lock(pamsnet_intr, NULL);
|
||||
DISABLE_IRQ();
|
||||
|
||||
local_irq_restore(flags);
|
||||
if( !STRAM_ADDR(buf+length-1) ) {
|
||||
skb_copy_from_linear_data(skb, nic_packet->buffer,
|
||||
length);
|
||||
buf = (unsigned long)phys_nic_packet;
|
||||
}
|
||||
|
||||
dma_cache_maintenance(buf, length, 1);
|
||||
|
||||
stat = sendpkt(lance_target, (unsigned char *)buf, length);
|
||||
ENABLE_IRQ();
|
||||
stdma_release();
|
||||
|
||||
dev->trans_start = jiffies;
|
||||
dev->tbusy = 0;
|
||||
lp->stats.tx_packets++;
|
||||
lp->stats.tx_bytes+=length;
|
||||
}
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We have a good packet(s), get it/them out of the buffers.
|
||||
*/
|
||||
static void
|
||||
pamsnet_poll_rx(struct net_device *dev)
|
||||
{
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
int boguscount;
|
||||
int pkt_len;
|
||||
struct sk_buff *skb;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
/* ++roman: Take care at locking the ST-DMA... This must be done with ints
|
||||
* off, since otherwise an int could slip in between the question and the
|
||||
* locking itself, and then we'd go to sleep... And locking itself is
|
||||
* necessary to keep the floppy_change timer from working with ST-DMA
|
||||
* registers. */
|
||||
if (stdma_islocked()) {
|
||||
local_irq_restore(flags);
|
||||
return;
|
||||
}
|
||||
stdma_lock(pamsnet_intr, NULL);
|
||||
DISABLE_IRQ();
|
||||
local_irq_restore(flags);
|
||||
|
||||
boguscount = testpkt(lance_target);
|
||||
if( lp->poll_time < MAX_POLL_TIME ) lp->poll_time++;
|
||||
|
||||
while(boguscount--) {
|
||||
pkt_len = receivepkt(lance_target, phys_nic_packet);
|
||||
|
||||
if( pkt_len < 60 ) break;
|
||||
|
||||
/* Good packet... */
|
||||
|
||||
dma_cache_maintenance((unsigned long)phys_nic_packet, pkt_len, 0);
|
||||
|
||||
lp->poll_time = pamsnet_min_poll_time; /* fast poll */
|
||||
if( pkt_len >= 60 && pkt_len <= 2048 ) {
|
||||
if (pkt_len > 1514)
|
||||
pkt_len = 1514;
|
||||
|
||||
/* Malloc up new buffer.
|
||||
*/
|
||||
skb = alloc_skb(pkt_len, GFP_ATOMIC);
|
||||
if (skb == NULL) {
|
||||
printk("%s: Memory squeeze, dropping packet.\n",
|
||||
dev->name);
|
||||
lp->stats.rx_dropped++;
|
||||
break;
|
||||
}
|
||||
skb->len = pkt_len;
|
||||
skb->dev = dev;
|
||||
|
||||
/* 'skb->data' points to the start of sk_buff data area.
|
||||
*/
|
||||
skb_copy_to_linear_data(skb, nic_packet->buffer,
|
||||
pkt_len);
|
||||
netif_rx(skb);
|
||||
dev->last_rx = jiffies;
|
||||
lp->stats.rx_packets++;
|
||||
lp->stats.rx_bytes+=pkt_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* If any worth-while packets have been received, dev_rint()
|
||||
has done a mark_bh(INET_BH) for us and will work on them
|
||||
when we get to the bottom-half routine.
|
||||
*/
|
||||
|
||||
ENABLE_IRQ();
|
||||
stdma_release();
|
||||
return;
|
||||
}
|
||||
|
||||
/* pamsnet_tick: called by pamsnet_timer. Reads packets from the adapter,
|
||||
* passes them to the higher layers and restarts the timer.
|
||||
*/
|
||||
static void
|
||||
pamsnet_tick(unsigned long data)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
|
||||
if( pamsnet_debug > 0 && (lp->open_time++ & 7) == 8 )
|
||||
printk("pamsnet_tick: %ld\n", lp->open_time);
|
||||
|
||||
pamsnet_poll_rx(dev);
|
||||
|
||||
pamsnet_timer.expires = jiffies + lp->poll_time;
|
||||
add_timer(&pamsnet_timer);
|
||||
}
|
||||
|
||||
/* The inverse routine to pamsnet_open().
|
||||
*/
|
||||
static int
|
||||
pamsnet_close(struct net_device *dev)
|
||||
{
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
|
||||
if (pamsnet_debug > 0)
|
||||
printk("pamsnet_close, open_time=%ld\n", lp->open_time);
|
||||
del_timer(&pamsnet_timer);
|
||||
stdma_lock(pamsnet_intr, NULL);
|
||||
DISABLE_IRQ();
|
||||
|
||||
if (if_up)
|
||||
stop(lance_target);
|
||||
if_up = 0;
|
||||
|
||||
lp->open_time = 0;
|
||||
|
||||
dev->tbusy = 1;
|
||||
dev->start = 0;
|
||||
|
||||
ENABLE_IRQ();
|
||||
stdma_release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the current statistics.
|
||||
This may be called with the card open or closed.
|
||||
*/
|
||||
static struct net_device_stats *net_get_stats(struct net_device *dev)
|
||||
{
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
return &lp->stats;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MODULE
|
||||
|
||||
static struct net_device *pam_dev;
|
||||
|
||||
int init_module(void)
|
||||
{
|
||||
pam_dev = pamsnet_probe(-1);
|
||||
if (IS_ERR(pam_dev))
|
||||
return PTR_ERR(pam_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanup_module(void)
|
||||
{
|
||||
unregister_netdev(pam_dev);
|
||||
free_netdev(pam_dev);
|
||||
}
|
||||
|
||||
#endif /* MODULE */
|
||||
|
||||
/* Local variables:
|
||||
* compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include
|
||||
-b m68k-linuxaout -Wall -Wstrict-prototypes -O2
|
||||
-fomit-frame-pointer -pipe -DMODULE -I../../net/inet -c atari_pamsnet.c"
|
||||
* version-control: t
|
||||
* kept-new-versions: 5
|
||||
* tab-width: 8
|
||||
* End:
|
||||
*/
|
|
@ -1,28 +0,0 @@
|
|||
|
||||
#ifndef _ATARI_SLM_H
|
||||
#define _ATARI_SLM_H
|
||||
|
||||
/* Atari SLM laser printer specific ioctls */
|
||||
|
||||
#define SLMIOGSTAT 0xa100
|
||||
#define SLMIOGPSIZE 0xa101
|
||||
#define SLMIOGMFEED 0xa102
|
||||
|
||||
#define SLMIORESET 0xa140
|
||||
|
||||
#define SLMIOSPSIZE 0xa181
|
||||
#define SLMIOSMFEED 0xa182
|
||||
|
||||
/* Status returning structure (SLMIOGSTAT) */
|
||||
struct SLM_status {
|
||||
int stat; /* numeric status code */
|
||||
char str[40]; /* status string */
|
||||
};
|
||||
|
||||
/* Paper size structure (SLMIO[GS]PSIZE) */
|
||||
struct SLM_paper_size {
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
#endif /* _ATARI_SLM_H */
|
|
@ -1,37 +0,0 @@
|
|||
#ifndef _ASM_ATARI_ACSI_H
|
||||
#define _ASM_ATARI_ACSI_H
|
||||
|
||||
/* Functions exported by drivers/block/acsi.c */
|
||||
|
||||
void acsi_delay_start( void );
|
||||
void acsi_delay_end( long usec );
|
||||
int acsi_wait_for_IRQ( unsigned timeout );
|
||||
int acsi_wait_for_noIRQ( unsigned timeout );
|
||||
int acsicmd_nodma( const char *cmd, int enable);
|
||||
int acsi_getstatus( void );
|
||||
int acsi_extstatus( char *buffer, int cnt );
|
||||
void acsi_end_extstatus( void );
|
||||
int acsi_extcmd( unsigned char *buffer, int cnt );
|
||||
|
||||
/* The ACSI buffer is guarantueed to reside in ST-RAM and may be used by other
|
||||
* drivers that work on the ACSI bus, too. It's data are valid only as long as
|
||||
* the ST-DMA is locked. */
|
||||
extern char *acsi_buffer;
|
||||
extern unsigned long phys_acsi_buffer;
|
||||
|
||||
/* Utility macros */
|
||||
|
||||
/* Send one data byte over the bus and set mode for next operation
|
||||
* with one move.l -- Atari recommends this...
|
||||
*/
|
||||
|
||||
#define DMA_LONG_WRITE(data,mode) \
|
||||
do { \
|
||||
*((unsigned long *)&dma_wd.fdc_acces_seccount) = \
|
||||
((data)<<16) | (mode); \
|
||||
} while(0)
|
||||
|
||||
#define ENABLE_IRQ() atari_turnon_irq( IRQ_MFP_ACSI )
|
||||
#define DISABLE_IRQ() atari_turnoff_irq( IRQ_MFP_ACSI )
|
||||
|
||||
#endif /* _ASM_ATARI_ACSI_H */
|
Loading…
Reference in a new issue