N: Bjorn Ekwall
E: bj0rn@blox.se
+W: http://www.pi.se/blox/
D: Extended support for loadable modules
D: D-Link pocket adapter drivers
S: Myrstuguv. 83
D: XF86_8514
D: cfdisk (curses based disk partitioning program)
+N: Mike McLagan
+E: mike.mclagan@linux.org
+W: http://www.invlogic.com/~mmclagan
+S: Innovative Logic Corp
+S: P.O. Box 1068
+S: Laurel, MD 20732
+S: USA
+D: DLCI/FRAD drivers for Sangoma SDLAs
+
N: Bradley McLean
E: brad@bradpc.gaylord.com
D: Device driver hacker
later on, such as a user level "beeper" and a generic screen blanker.
The "kerneld" daemon is included in "modules-1.2.8" and later.
+ARP daemon support
+CONFIG_ARPD
+ Normally, the kernel maintains an internal cache which maps IP
+ addresses to hardware addresses on the local network, so that
+ Ethernet/Token Ring/ etc. frames are sent to the proper address
+ on the physical networking layer. For small networks having
+ a few hundred directly connected hosts or less, keeping this
+ address resolution cache (ARP) inside the kernel works well.
+ However, maintaining an internal ARP cache does not work well for
+ very large switched networks, and will use a lot of kernel memory
+ if TCP/IP connections are made to many machines on the network.
+ By enabling this option, the kernel's internal ARP cache will
+ never grow to more than 256 entries (the oldest entries are
+ expired in a LIFO manner) and communication will be attempted
+ with an external ARP daemon, arpd, via the kerneld message
+ queue. This code is still experimental. If you do enable
+ arpd support, you should obtain a copy of arpd from
+ http://www.loran.com/~layes/arpd/index.html. If unsure,
+ say N.
+
TCP/IP networking
CONFIG_INET
These are the protocols used on the Internet and on most local
please drop me a mail.
The support for multisession CDs is in ALPHA stage. If you use it,
-please mail me your experiences. Multisession support can be disables
+please mail me your experiences. Multisession support can be disabled
at compile time.
You can find some older versions of the driver at
\noindent
The loopback devices are used to mount filesystems not associated with
block devices. The binding to the loopback devices is usually handled
-by mount(1).
+by mount(8).
\begin{devicelist}
\major{11}{}{char }{Raw keyboard device}
The loopback devices are used to mount filesystems not
associated with block devices. The binding to the
- loopback devices is usually handled by mount(1).
+ loopback devices is usually handled by mount(8).
8 block SCSI disk devices
0 = /dev/sda First SCSI disk whole disk
--- /dev/null
+Frame Relay (FR) support for linux is built into a two tiered system of device
+drivers. The upper layer implements RFC1490 FR specification, and uses the
+Data Link Connection Identifier (DLCI) as it's hardware address. Usually these
+are assigned by your network supplier, they give you the number/numbers of
+the Virtual Connections (VC) assigned to you.
+
+Each DLCI is a point-to-point link between your machine and a remote one.
+As such, a seperate device is needed to accomodate the routing. Within the
+net-tools archives is 'dlcicfg'. This program will communicate with the
+base "DLCI" device, and create new net devices named 'dlci00', 'dlci01'...
+The configuration script will ask you how many DLCI's you need, as well as
+how many DLCI's you want to assign to each Frame Relay Access Device (FRAD).
+
+The DLCI uses a number of function calls to communicate with the FRAD, all
+of which are stored in the FRAD's private data area. assoc/deassoc,
+activate/deactivate and dlci_config. The DLCI supplies a receive function
+to the FRAD to accept incoming packets.
+
+With this initial offering, only 1 FRAD driver is available. With many thanks
+to Sangoma Technologies, David Mandelstam & Gene Kozin, the S502A, S502E &
+S508 are supported. This driver is currently set up for only FR, but as
+Sangoma makes more firmware modules available, it can be updated to provide
+them as well.
+
+Configuration of the FRAD makes use of another net-tools program, 'fradcfg'.
+This program makes use of a configuration file (which dlcicfg can also read)
+to specify the types of boards to be configured as FRADs, as well as perform
+any board specific configuration. The Sangoma module of fradcfg loads the
+FR firmware into the card, sets the irq/port/memory information, and provides
+an initial configuration.
+
+Additional FRAD device drivers can be added as hardware is available.
+
'f' linux/ext2_fs.h
'm' linux/mtio.h conflict!
'm' linux/soundcard.h conflict!
+'n' linux/ncp_fs.h
's' linux/cdk.h
't' linux/if_ppp.h
'u' linux/smb_fs.h
P: Person
M: Mail patches to
L: Mailing list that is relevant to this area
+W: Web-page with status/info
S: Status
Supported: Someone is actually paid to look after this (wildly
improbable).
L: None
S: Maintained
+FRAME RELAY DLCI/FRAD (Sangoma drivers too)
+P: Mike McLagan
+M: mike.mclagan@linux.org
+L: linux-net@vger.rutgers.edu
+S: Maintained
+
FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
P: Rik Faith
M: faith@cs.unc.edu
MODULE SUPPORT [GENERAL], KERNELD
P: Bjorn Ekwall
M: bj0rn@blox.se
+W: http://www.pi.se/blox/modules/
L: linux-kernel@vger.rutgers.edu
S: Maintained
+ARPD SUPPORT
+P: Jonathan Layes
+M: layes@loran.com
+L: linux-net@vger.rutgers.edu
+S: Maintained
+
NCP FILESYSTEM:
P: Volker Lendecke
M: lendecke@namu01.gwdg.de
VERSION = 1
PATCHLEVEL = 3
-SUBLEVEL = 77
+SUBLEVEL = 78
ARCH = i386
define_bool CONFIG_PCI y
define_bool CONFIG_ALPHA_EV5 y
define_bool CONFIG_ALPHA_ALCOR y
+else
+ # EV5 and newer supports all rounding modes in hw:
+ define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
fi
if [ "$CONFIG_ALPHA_JENSEN" = "y" ]
bool 'Using SRM as bootloader' CONFIG_ALPHA_SRM
fi
-define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
-
bool 'Echo console messages on /dev/ttyS1' CONFIG_SERIAL_ECHO
if [ "$CONFIG_PCI" = "y" ]; then
bool 'TGA Console Support' CONFIG_TGA_CONSOLE
CONFIG_PCI=y
CONFIG_ALPHA_EV5=y
CONFIG_ALPHA_ALCOR=y
-CONFIG_ALPHA_NEED_ROUNDING_EMULATION=y
# CONFIG_SERIAL_ECHO is not set
# CONFIG_TGA_CONSOLE is not set
CONFIG_PCI_OPTIMIZE=y
# CONFIG_SCC is not set
# CONFIG_PLIP is not set
# CONFIG_EQUALIZER is not set
+# CONFIG_FRAD is not set
# CONFIG_NET_ALPHA is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_LANCE is not set
#include <asm/segment.h>
#include <asm/io.h>
+#include <asm/hwrpb.h>
#include <linux/mc146818rtc.h>
#include <linux/timex.h>
#define TIMER_IRQ 0
+extern struct hwrpb_struct *hwrpb;
+
static int set_rtc_mmss(unsigned long);
+
+/*
+ * Shift amount by which scaled_ticks_per_cycle is scaled. Shifting
+ * by 48 gives us 16 bits for HZ while keeping the accuracy good even
+ * for large CPU clock rates.
+ */
+#define FIX_SHIFT 48
+
+/* lump static variables together for more efficient access: */
+static struct {
+ __u32 last_time; /* cycle counter last time it got invoked */
+ __u32 max_cycles_per_tick; /* more makes us think we lost an interrupt */
+ unsigned long scaled_ticks_per_cycle; /* ticks/cycle * 2^48 */
+ long last_rtc_update; /* last time the cmos clock got updated */
+} state;
+
+
+static inline __u32 rpcc(void)
+{
+ __u32 result;
+
+ asm volatile ("rpcc %0" : "r="(result));
+ return result;
+}
+
+
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
*/
void timer_interrupt(struct pt_regs * regs)
{
- /* last time the cmos clock got updated */
- static long last_rtc_update=0;
+ __u32 delta, now;
+
+ now = rpcc();
+ delta = now - state.last_time;
+ state.last_time = now;
+ if (delta > state.max_cycles_per_tick) {
+ int i, missed_ticks;
+ missed_ticks = ((delta * state.scaled_ticks_per_cycle) >> FIX_SHIFT) - 1;
+ for (i = 0; i < missed_ticks; ++i) {
+ do_timer(regs);
+ }
+ }
do_timer(regs);
/*
* CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
* called as close as possible to 500 ms before the new second starts.
*/
- if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
+ if (time_state != TIME_BAD && xtime.tv_sec > state.last_rtc_update + 660 &&
xtime.tv_usec > 500000 - (tick >> 1) &&
xtime.tv_usec < 500000 + (tick >> 1))
if (set_rtc_mmss(xtime.tv_sec) == 0)
- last_rtc_update = xtime.tv_sec;
+ state.last_rtc_update = xtime.tv_sec;
else
- last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+ state.last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
}
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
year += 100;
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_usec = 0;
+
+ if (HZ > (1<<16)) {
+ extern void __you_loose (void);
+ __you_loose();
+ }
+ state.last_time = rpcc();
+ state.scaled_ticks_per_cycle = ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq;
+ state.max_cycles_per_tick = (2 * hwrpb->cycle_freq) / HZ;
+ state.last_rtc_update = 0;
}
/*
insn = get_user((__u32*)pc);
fc = (insn >> 0) & 0x1f; /* destination register */
- func = (insn >> 5) & 0x3ff;
+ func = (insn >> 5) & 0x7ff;
fb = (insn >> 16) & 0x1f;
fa = (insn >> 21) & 0x1f;
opcode = insn >> 26;
static unsigned long
-round_t_ieee (EXTENDED *a, unsigned long *b, int f)
+round_t_ieee (int f, EXTENDED *a, unsigned long *b)
{
unsigned long diff1, diff2, res;
EXTENDED z1, z2;
}
return 0;
}
- return round_s_ieee(f, &temp, b);
+ return round_t_ieee(f, &temp, b);
}
}
op_b.e = 55;
normalize(&op_b);
- return round_t_ieee(&op_b, b, f);
+ return round_t_ieee(f, &op_b, b);
}
if (a_type == ZERO && b_type == ZERO)
op_c.s = op_a.s && op_b.s;
- return round_t_ieee(&op_c, c, f);
+ return round_t_ieee(f, &op_c, c);
}
if (a_type == ZERO && b_type == ZERO)
op_c.s = op_a.s && op_b.s;
- return round_t_ieee(&op_c, c, f);
+ return round_t_ieee(f, &op_c, c);
}
normalize(&op_c);
op_c.e -= 55; /* drop the 55 original bits. */
- return round_t_ieee(&op_c, c, f);
+ return round_t_ieee(f, &op_c, c);
}
op_c.f[0] |= STICKY_T;
normalize(&op_c);
op_c.e -= 9; /* remove excess exp from original shift */
- return round_t_ieee(&op_c, c, f);
+ return round_t_ieee(f, &op_c, c);
}
! Bootlin, SYSLX, bootsect...)
! else it is set by the loader:
! 0xTV: T=0 for LILO
- ! T=1 for Loadlin
- ! T=2 for bootsect-loader
+ ! T=1 for Loadlin
+ ! T=2 for bootsect-loader
+ ! T=3 for SYSLX
+ ! T=4 for ETHERBOOT
! V = version
loadflags: .byte 0 ! unused bits =0 (reserved for future development)
LOADED_HIGH = 1 ! bit within loadflags,
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_BLK_DEV_MD is not set
+
#
# Networking options
#
# CONFIG_SCC is not set
# CONFIG_PLIP is not set
# CONFIG_EQUALIZER is not set
+# CONFIG_FRAD is not set
# CONFIG_NET_ALPHA is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_LANCE is not set
.long SYMBOL_NAME(sys_sched_get_priority_min) /* 160 */
.long SYMBOL_NAME(sys_sched_rr_get_interval)
.long SYMBOL_NAME(sys_nanosleep)
+ .long SYMBOL_NAME(sys_mremap)
.space (NR_syscalls-163)*4
int smp_found_config=0; /* Have we found an SMP box */
unsigned long cpu_present_map = 0; /* Bitmask of existing CPU's */
-int smp_num_cpus; /* Total count of live CPU's */
+int smp_num_cpus = 1; /* Total count of live CPU's */
int smp_threads_ready=0; /* Set when the idlers are all forked */
volatile int cpu_number_map[NR_CPUS]; /* which CPU maps to which logical number */
+volatile int cpu_logical_map[NR_CPUS]; /* which logical number maps to which CPU */
volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; /* We always use 0 the rest is ready for parallel delivery */
volatile unsigned long smp_invalidate_needed; /* Used for the invalidate map thats also checked in the spinlock */
struct cpuinfo_x86 cpu_data[NR_CPUS]; /* Per cpu bogomips and other parameters */
static unsigned int num_processors = 1; /* Internal processor count */
-int smp_top_cpu = 0; /* Highest used APIC id */
static unsigned long io_apic_addr = 0xFEC00000; /* Address of the I/O apic (not yet used) */
unsigned char boot_cpu_id = 0; /* Processor that is doing the boot up */
static unsigned char *kstack_base,*kstack_end; /* Kernel stack list pointers */
{
SMP_PRINTK((" Bootup CPU\n"));
boot_cpu_id=m->mpc_apicid;
- nlong = boot_cpu_id<<24; /* Dummy 'self' for bootup */
}
else /* Boot CPU already counted */
num_processors++;
* Scan the memory blocks for an SMP configuration block.
*/
-void smp_scan_config(unsigned long base, unsigned long length)
+int smp_scan_config(unsigned long base, unsigned long length)
{
unsigned long *bp=(unsigned long *)base;
struct intel_mp_floating *mpf;
* Now see if we need to read further.
*/
if(mpf->mpf_feature1!=0)
- {
- num_processors=2;
- printk("I/O APIC at 0xFEC00000.\n");
- printk("Bus#0 is ");
- }
- switch(mpf->mpf_feature1)
- {
- case 1:
- case 5:
- printk("ISA\n");
- break;
- case 2:
- printk("EISA with no IRQ8 chaining\n");
- break;
- case 6:
- case 3:
- printk("EISA\n");
- break;
- case 4:
- case 7:
- printk("MCA\n");
- break;
- case 0:
- break;
- default:
- printk("???\nUnknown standard configuration %d\n",
- mpf->mpf_feature1);
- return;
- }
- if(mpf->mpf_feature1>4)
- printk("Bus #1 is PCI\n");
- /*
- * Read the physical hardware table.
- */
- if(mpf->mpf_physptr)
- smp_read_mpc((void *)mpf->mpf_physptr);
- else
{
unsigned long cfg;
/*
- * If no table present, determine
- * what the CPU mapping is.
+ * We need to know what the local
+ * APIC id of the boot CPU is!
*/
/*
*
* HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
*
+ * It's not just a crazy hack... ;-)
*/
/*
* Standard page mapping
local_invalidate();
boot_cpu_id = GET_APIC_ID(*((volatile unsigned long *) APIC_ID));
- nlong = boot_cpu_id<<24; /* Dummy 'self' for bootup */
/*
* Give it back
* END OF HACK END OF HACK END OF HACK END OF HACK END OF HACK
*
*/
+ /*
+ * 2 CPUs, numbered 0 & 1.
+ */
+ cpu_present_map=3;
+ num_processors=2;
+ printk("I/O APIC at 0xFEC00000.\n");
+ printk("Bus#0 is ");
+ }
+ switch(mpf->mpf_feature1)
+ {
+ case 1:
+ case 5:
+ printk("ISA\n");
+ break;
+ case 2:
+ printk("EISA with no IRQ8 chaining\n");
+ break;
+ case 6:
+ case 3:
+ printk("EISA\n");
+ break;
+ case 4:
+ case 7:
+ printk("MCA\n");
+ break;
+ case 0:
+ break;
+ default:
+ printk("???\nUnknown standard configuration %d\n",
+ mpf->mpf_feature1);
+ return 1;
+ }
+ if(mpf->mpf_feature1>4)
+ {
+ printk("Bus #1 is PCI\n");
/*
- * If boot CPU != 0, other CPU
- * is 0, else other CPU is 1.
+ * Set local APIC version to
+ * the integrated form.
+ * It's initialized to zero
+ * otherwise, representing
+ * a discrete 82489DX.
*/
- if (boot_cpu_id)
- cpu_present_map=1 | (1 << boot_cpu_id);
- else
- cpu_present_map=3;
+ apic_version[0] = 0x10;
+ apic_version[1] = 0x10;
}
+ /*
+ * Read the physical hardware table.
+ * Anything here will override the
+ * defaults.
+ */
+ if(mpf->mpf_physptr)
+ smp_read_mpc((void *)mpf->mpf_physptr);
+
+ /*
+ * Now that the boot CPU id is known,
+ * set some other information about it.
+ */
+ nlong = boot_cpu_id<<24; /* Dummy 'self' for bootup */
+ cpu_logical_map[0] = boot_cpu_id;
+
printk("Processors: %d\n", num_processors);
/*
- * Only use the first one found.
+ * Only use the first configuration found.
*/
- return;
+ return 1;
}
}
bp+=4;
length-=16;
}
+
+ return 0;
}
/*
void smp_boot_cpus(void)
{
- int i,j;
+ int i;
int cpucount=0;
unsigned long cfg;
void *stack;
* Don't even attempt to start the boot CPU!
*/
if (i == boot_cpu_id)
- {
- smp_top_cpu=max(smp_top_cpu,i);
continue;
- }
if (cpu_present_map & (1 << i))
{
unsigned long send_status, accept_status;
- int timeout, num_starts;
+ int timeout, num_starts, j;
/*
* We need a kernel stack for each processor.
* Be paranoid about clearing APIC errors.
*/
- apic_write(APIC_ESR, 0);
- accept_status = (apic_read(APIC_ESR) & 0xEF);
+ if ( apic_version[i] & 0xF0 )
+ {
+ apic_write(APIC_ESR, 0);
+ accept_status = (apic_read(APIC_ESR) & 0xEF);
+ }
/*
* Status is now clean
* Run STARTUP IPI loop.
*/
- for (j = 0; !(send_status || accept_status)
- && (j < num_starts) ; j++)
+ for (j = 1; !(send_status || accept_status)
+ && (j <= num_starts) ; j++)
{
SMP_PRINTK(("Sending STARTUP #%d.\n",j));
cpucount++;
/* number CPUs logically, starting from 1 (BSP is 0) */
cpu_number_map[i] = cpucount;
- smp_top_cpu=max(smp_top_cpu,i);
-
+ cpu_logical_map[cpucount] = i;
}
else
{
/*
* Sanity check we don't re-enter this across CPU's. Only the kernel
* lock holder may send messages. For a STOP_CPU we are bringing the
- * entire box to the fastest halt we can..
+ * entire box to the fastest halt we can.. A reschedule carries
+ * no data and can occur during an invalidate.. guess what panic
+ * I got to notice this bug...
*/
- if(message_cpu!=NO_PROC_ID && msg!=MSG_STOP_CPU)
+ if(message_cpu!=NO_PROC_ID && msg!=MSG_STOP_CPU && msg!=MSG_RESCHEDULE)
{
panic("CPU #%d: Message pass %d but pass in progress by %d of %d\n",
smp_processor_id(),msg,message_cpu, smp_msg_id);
memset((void *) 0, 0, PAGE_SIZE);
#endif
#ifdef __SMP__
- smp_scan_config(0x0,0x400); /* Scan the bottom 1K for a signature */
- /*
- * FIXME: Linux assumes you have 640K of base ram.. this continues
- * the error...
- */
- smp_scan_config(639*0x400,0x400); /* Scan the top 1K of base RAM */
- smp_scan_config(0xF0000,0x10000); /* Scan the 64K of bios */
+ if (!smp_scan_config(0x0,0x400)) /* Scan the bottom 1K for a signature */
+ {
+ /*
+ * FIXME: Linux assumes you have 640K of base ram.. this continues
+ * the error...
+ */
+ if (!smp_scan_config(639*0x400,0x400)) /* Scan the top 1K of base RAM */
+ smp_scan_config(0xF0000,0x10000); /* Scan the 64K of bios */
+ }
/*
* If it is an SMP machine we should know now, unless the configuration
* is in an EISA/MCA bus machine with an extended bios data area. I don't
}
while(1){
- if (!CURRENT) {
+ if (!CURRENT || CURRENT_PLUGGED) {
CLEAR_INTR;
unlock_fdc();
return;
*/
hwif = hwgroup->next_hwif;
do {
+ if (IS_PLUGGED(blk_dev + hwif->major))
+ continue;
rq = blk_dev[hwif->major].current_request;
if (rq != NULL && rq->rq_status != RQ_INACTIVE)
goto got_rq;
int * hardsect_size[MAX_BLKDEV] = { NULL, NULL, };
/*
- * "plug" the device if there are no outstanding requests: this will
- * force the transfer to start only after we have put all the requests
- * on the list.
+ * remove the plug and let it rip..
*/
-static inline void plug_device(struct blk_dev_struct * dev, struct request * plug)
+static void unplug_device(void * data)
{
+ struct blk_dev_struct * dev = (struct blk_dev_struct *) data;
unsigned long flags;
- plug->rq_status = RQ_INACTIVE;
- plug->cmd = -1;
- plug->next = NULL;
save_flags(flags);
cli();
- if (!dev->current_request)
- dev->current_request = plug;
+ if (dev->current_request)
+ (dev->request_fn)();
restore_flags(flags);
}
/*
- * remove the plug and let it rip..
+ * "plug" the device if there are no outstanding requests: this will
+ * force the transfer to start only after we have put all the requests
+ * on the list.
*/
-static inline void unplug_device(struct blk_dev_struct * dev)
+static inline void plug_device(struct blk_dev_struct * dev)
{
- struct request * req;
- unsigned long flags;
-
- save_flags(flags);
- cli();
- req = dev->current_request;
- if (req && req->rq_status == RQ_INACTIVE && req->cmd == -1) {
- dev->current_request = req->next;
- (dev->request_fn)();
+ if (!dev->current_request && !IS_PLUGGED(dev)) {
+ queue_task_irq_off(&dev->plug_tq, &tq_scheduler);
}
- restore_flags(flags);
}
/*
add_wait_queue(&wait_for_request, &wait);
for (;;) {
- unplug_device(MAJOR(dev)+blk_dev);
current->state = TASK_UNINTERRUPTIBLE;
cli();
req = get_request(n, dev);
if (!(tmp = dev->current_request)) {
dev->current_request = req;
up (&request_lock);
- (dev->request_fn)();
+ if (!IS_PLUGGED(dev))
+ (dev->request_fn)();
sti();
return;
}
up (&request_lock);
/* for SCSI devices, call request_fn unconditionally */
- if (scsi_major(MAJOR(req->rq_dev)) && MAJOR(req->rq_dev)!=MD_MAJOR)
+ if (!IS_PLUGGED(dev) && scsi_major(MAJOR(req->rq_dev)) && MAJOR(req->rq_dev)!=MD_MAJOR)
(dev->request_fn)();
sti();
}
/* look for a free request. */
- cli();
down (&request_lock);
+ cli();
/* The scsi disk and cdrom drivers completely remove the request
* from the queue when they start processing an entry. For this reason
void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
{
unsigned int major;
- struct request plug;
int correct_size;
struct blk_dev_struct * dev;
int i;
from starting until we have shoved all of the blocks into the
queue, and then we let it rip. */
- if (nr > 1)
- plug_device(dev, &plug);
+ plug_device(dev);
for (i = 0; i < nr; i++) {
if (bh[i]) {
set_bit(BH_Req, &bh[i]->b_state);
make_request(major, rw, bh[i]);
}
}
- unplug_device(dev);
return;
sorry:
for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;) {
dev->request_fn = NULL;
dev->current_request = NULL;
+ dev->plug_tq.routine = &unplug_device;
+ dev->plug_tq.data = dev;
}
req = all_requests + NR_REQUEST;
offset -= blksize;
}
len = CURRENT->current_nr_sectors << 9;
- if ((CURRENT->cmd != WRITE) && (CURRENT->cmd != READ)) {
+ if (CURRENT->cmd == WRITE) {
+ if (lo->lo_flags & LO_FLAGS_READ_ONLY)
+ goto error_out;
+ } else if (CURRENT->cmd != READ) {
printk("unknown loop device command (%d)?!?", CURRENT->cmd);
goto error_out;
}
goto repeat;
}
-static int loop_set_fd(struct loop_device *lo, unsigned int arg)
+static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
{
struct file *file;
struct inode *inode;
-
+
if (arg >= NR_OPEN || !(file = current->files->fd[arg]))
return -EBADF;
if (lo->lo_inode)
} else
return -EINVAL;
- invalidate_inode_pages (inode);
+ if (IS_RDONLY (inode) || is_read_only(lo->lo_device)) {
+ lo->lo_flags |= LO_FLAGS_READ_ONLY;
+ set_device_ro(dev, 1);
+ } else {
+ invalidate_inode_pages (inode);
+ set_device_ro(dev, 0);
+ }
+
lo->lo_inode = inode;
lo->lo_inode->i_count++;
lo->transfer = NULL;
{
if (!lo->lo_inode)
return -ENXIO;
- if (lo->lo_refcnt > 1)
+ if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */
return -EBUSY;
if (S_ISBLK(lo->lo_inode->i_mode))
blkdev_release (lo->lo_inode);
lo = &loop_dev[dev];
switch (cmd) {
case LOOP_SET_FD:
- return loop_set_fd(lo, arg);
+ return loop_set_fd(lo, inode->i_rdev, arg);
case LOOP_CLR_FD:
return loop_clr_fd(lo, inode->i_rdev);
case LOOP_SET_STATUS:
lo->lo_refcnt--;
MOD_DEC_USE_COUNT;
}
-
- return;
}
static struct file_operations lo_fops = {
A lot of inspiration came from hd.c ...
+ kerneld support by Boris Tobotras <boris@xtalk.msk.su>
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
#include <linux/proc_fs.h>
#include <linux/blkdev.h>
#include <linux/genhd.h>
+#ifdef CONFIG_KERNELD
+#include <linux/kerneld.h>
+#endif
#include <errno.h>
#define MAJOR_NR MD_MAJOR
/* Picked up from genhd.c */
char *partition_name (kdev_t dev)
{
- static char name[10]; /* This should be long
+ static char name[40]; /* This should be long
enough for a device name ! */
- struct gendisk *hd=find_gendisk (dev);
+ struct gendisk *hd = find_gendisk (dev);
if (!hd)
{
- printk ("No gendisk entry for dev %04x\n", dev);
- sprintf (name, "dev %04x", dev);
+ printk ("No gendisk entry for dev %s\n", kdevname(dev));
+ sprintf (name, "dev %s", kdevname(dev));
return (name);
}
md_dev[minor].repartition=(int) arg;
if ((index=PERSONALITY(md_dev+minor) >> (PERSONALITY_SHIFT))
- >= MAX_PERSONALITY ||
- !pers[index])
+ >= MAX_PERSONALITY)
return -EINVAL;
+ if (!pers[index])
+ {
+#ifdef CONFIG_KERNELD
+ char module_name[80];
+ sprintf (module_name, "md-personality-%d", index);
+ request_module (module_name);
+ if (!pers[index])
+#endif
+ return -EINVAL;
+ }
+
md_dev[minor].pers=pers[index];
if ((err=md_dev[minor].pers->run (minor, md_dev+minor)))
minor = MINOR(req->rq_dev);
if ((MAJOR(req->rq_dev) != MD_MAJOR) || (minor >= MAX_REAL))
{
- printk("md: bad device number: 0x%04x\n", req->rq_dev);
+ printk("md: bad device: %s\n", kdevname(req->rq_dev));
end_request(0, req);
continue;
}
kdev_t dev;
struct buffer_head *bh;
struct request *req;
+ long flags;
down (&request_lock);
+ save_flags (flags);
+ cli();
for (i=0; i<n; i++)
{
if (!pending[i].bh)
continue;
- cli();
-
found=0;
rw=pending[i].cmd;
bh=pending[i].bh;
while (req && !found)
{
- if (req->rq_status!=RQ_INACTIVE && req->rq_status!=RQ_ACTIVE)
+ if (req->rq_status!=RQ_ACTIVE)
printk ("Saw bad status request !\n");
if (req->rq_dev == dev &&
(req->nr_sectors + pending[i].nr_sectors) < 245)
{
req->nr_sectors += pending[i].nr_sectors;
- bh->b_reqnext = req->bh;
+ pending[i].bhtail->b_reqnext = req->bh;
req->buffer = bh->b_data;
req->current_nr_sectors = bh->b_size >> 9;
req->sector = pending[i].sector;
continue;
up (&request_lock);
+ sti ();
req=get_md_request (max_req, dev);
/* Build it up... */
add_request (blk_dev + MAJOR(dev), req);
down (&request_lock);
+ cli ();
}
up (&request_lock);
+ restore_flags (flags);
for (j=0; j<n; j++)
{
if (!pending[j].bh)
pending[j].bh=NULL;
}
-
- sti ();
}
sz+=sprintf (page+sz, "\n");
sz+=md_dev[i].pers->status (page+sz, i, md_dev+i);
}
-
+
return (sz);
}
* The beginning here is stolen from the hard disk driver. I hope
* it's right.
*/
- if (!(CURRENT) || CURRENT->rq_status == RQ_INACTIVE)
+ if (!(CURRENT) || CURRENT_PLUGGED || CURRENT->rq_status == RQ_INACTIVE)
{
goto end_do_cdu31a_request;
}
/*
* The Mitsumi CDROM interface
* Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 1.8
+ * VERSION: 1.9
*
****************** H E L P *********************************
* If you ever plan to update your CD ROM drive and perhaps
#if RCS
static const char *mcdx_c_version
- = "$Id: mcdx.c,v 1.39 1996/03/15 00:00:59 heiko Exp $";
+ = "mcdx.c,v 1.2 1996/03/22 01:14:59 heiko Exp";
#endif
#include <linux/version.h>
I wanna make this independend of cpu speed. [1 jiffie is 1/HZ] sec */
{
unsigned long tout = jiffies + jifs;
- if (jifs < 0) printk ("********\n");
+ if (jifs < 0) return;
/* TRACE((INIT, "mcdx_delay %d\n", jifs)); */
int drive;
#ifdef MODULE
- WARN(("Version 1.8 for %s\n", kernel_version));
+ WARN(("Version 1.9 for %s\n", kernel_version));
#else
- WARN(("Version 1.8\n"));
+ WARN(("Version 1.9\n"));
#endif
- WARN(("$Id: mcdx.c,v 1.39 1996/03/15 00:00:59 heiko Exp $\n"));
+ WARN(("mcdx.c,v 1.2 1996/03/22 01:14:59 heiko Exp\n"));
/* zero the pointer array */
for (drive = 0; drive < MCDX_NDRIVES; drive++)
+++ /dev/null
-/* linux/drivers/cdrom/optcd_isp16.h - ISP16 CDROM interface configuration
- $Id: optcd_isp16.h,v 1.3 1996/01/15 18:43:11 root Exp root $
-
- Extracts from linux/drivers/cdrom/sjcd.c
- For copyrights see linux/drivers/cdrom/optcd.c
-*/
-
-
-/* Some (Media)Magic */
-/* define types of drive the interface on an ISP16 card may be looking at */
-#define ISP16_DRIVE_X 0x00
-#define ISP16_SONY 0x02
-#define ISP16_PANASONIC0 0x02
-#define ISP16_SANYO0 0x02
-#define ISP16_MITSUMI 0x04
-#define ISP16_PANASONIC1 0x06
-#define ISP16_SANYO1 0x06
-#define ISP16_DRIVE_NOT_USED 0x08 /* not used */
-#define ISP16_DRIVE_SET_MASK 0xF1 /* don't change 0-bit or 4-7-bits*/
-/* ...for port */
-#define ISP16_DRIVE_SET_PORT 0xF8D
-/* set io parameters */
-#define ISP16_BASE_340 0x00
-#define ISP16_BASE_330 0x40
-#define ISP16_BASE_360 0x80
-#define ISP16_BASE_320 0xC0
-#define ISP16_IRQ_X 0x00
-#define ISP16_IRQ_5 0x04 /* shouldn't be used due to soundcard conflicts */
-#define ISP16_IRQ_7 0x08 /* shouldn't be used due to soundcard conflicts */
-#define ISP16_IRQ_3 0x0C
-#define ISP16_IRQ_9 0x10
-#define ISP16_IRQ_10 0x14
-#define ISP16_IRQ_11 0x18
-#define ISP16_DMA_X 0x03
-#define ISP16_DMA_3 0x00
-#define ISP16_DMA_5 0x00
-#define ISP16_DMA_6 0x01
-#define ISP16_DMA_7 0x02
-#define ISP16_IO_SET_MASK 0x20 /* don't change 5-bit */
-/* ...for port */
-#define ISP16_IO_SET_PORT 0xF8E
-/* enable the card */
-#define ISP16_C928__ENABLE_PORT 0xF90 /* ISP16 with OPTi 82C928 chip */
-#define ISP16_C929__ENABLE_PORT 0xF91 /* ISP16 with OPTi 82C929 chip */
-#define ISP16_ENABLE_CDROM 0x80 /* seven bit */
-
-/* the magic stuff */
-#define ISP16_CTRL_PORT 0xF8F
-#define ISP16_C928__CTRL 0xE2 /* ISP16 with OPTi 82C928 chip */
-#define ISP16_C929__CTRL 0xE3 /* ISP16 with OPTi 82C929 chip */
-
-static short isp16_detect(void);
-static short isp16_c928__detect(void);
-static short isp16_c929__detect(void);
-static short isp16_cdi_config( int base, u_char drive_type, int irq, int dma );
-static void isp16_sound_config( void );
-static short isp16_type; /* dependent on type of interface card */
-static u_char isp16_ctrl;
-static u_short isp16_enable_port;
-
-/*static int sjcd_present = 0;*/
-static u_char special_mask = 0;
-
-static unsigned char defaults[ 16 ] = {
- 0xA8, 0xA8, 0x18, 0x18, 0x18, 0x18, 0x8E, 0x8E,
- 0x03, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x00
-};
-/* ------------- */
-/*
- * -- ISP16 detection and configuration
- *
- * Copyright (c) 1995, Eric van der Maarel <maarel@marin.nl>
- *
- * Version 0.5
- *
- * Detect cdrom interface on ISP16 soundcard.
- * Configure cdrom interface.
- * Configure sound interface.
- *
- * Algorithm for the card with OPTi 82C928 taken
- * from the CDSETUP.SYS driver for MSDOS,
- * by OPTi Computers, version 2.03.
- * Algorithm for the card with OPTi 82C929 as communicated
- * to me by Vadim Model and Leo Spiekman.
- *
- * Use, modifification or redistribution of this software is
- * allowed under the terms of the GPL.
- *
- */
-
-
-#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
-#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
-
-static short
-isp16_detect(void)
-{
-
- if ( !( isp16_c929__detect() < 0 ) )
- return(2);
- else
- return( isp16_c928__detect() );
-}
-
-static short
-isp16_c928__detect(void)
-{
- u_char ctrl;
- u_char enable_cdrom;
- u_char io;
- short i = -1;
-
- isp16_ctrl = ISP16_C928__CTRL;
- isp16_enable_port = ISP16_C928__ENABLE_PORT;
-
- /* read' and write' are a special read and write, respectively */
-
- /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
- ctrl = ISP16_IN( ISP16_CTRL_PORT ) & 0xFC;
- ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
- /* read' 3,4 and 5-bit from the cdrom enable port */
- enable_cdrom = ISP16_IN( ISP16_C928__ENABLE_PORT ) & 0x38;
-
- if ( !(enable_cdrom & 0x20) ) { /* 5-bit not set */
- /* read' last 2 bits of ISP16_IO_SET_PORT */
- io = ISP16_IN( ISP16_IO_SET_PORT ) & 0x03;
- if ( ((io&0x01)<<1) == (io&0x02) ) { /* bits are the same */
- if ( io == 0 ) { /* ...the same and 0 */
- i = 0;
- enable_cdrom |= 0x20;
- }
- else { /* ...the same and 1 */ /* my card, first time 'round */
- i = 1;
- enable_cdrom |= 0x28;
- }
- ISP16_OUT( ISP16_C928__ENABLE_PORT, enable_cdrom );
- }
- else { /* bits are not the same */
- ISP16_OUT( ISP16_CTRL_PORT, ctrl );
- return(i); /* -> not detected: possibly incorrect conclusion */
- }
- }
- else if ( enable_cdrom == 0x20 )
- i = 0;
- else if ( enable_cdrom == 0x28 ) /* my card, already initialised */
- i = 1;
-
- ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
- return(i);
-}
-
-static short
-isp16_c929__detect(void)
-{
- u_char ctrl;
- u_char tmp;
-
- isp16_ctrl = ISP16_C929__CTRL;
- isp16_enable_port = ISP16_C929__ENABLE_PORT;
-
- /* read' and write' are a special read and write, respectively */
-
- /* read' ISP16_CTRL_PORT and save */
- ctrl = ISP16_IN( ISP16_CTRL_PORT );
-
- /* write' zero to the ctrl port and get response */
- ISP16_OUT( ISP16_CTRL_PORT, 0 );
- tmp = ISP16_IN( ISP16_CTRL_PORT );
-
- if ( tmp != 2 ) /* isp16 with 82C929 not detected */
- return(-1);
-
- /* restore ctrl port value */
- ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
- return(2);
-}
-
-static short
-isp16_cdi_config( int base, u_char drive_type, int irq, int dma )
-{
- u_char base_code;
- u_char irq_code;
- u_char dma_code;
- u_char i;
-
- if ( (drive_type == ISP16_MITSUMI) && (dma != 0) )
- printk( "Mitsumi cdrom drive has no dma support.\n" );
-
- switch (base) {
- case 0x340: base_code = ISP16_BASE_340; break;
- case 0x330: base_code = ISP16_BASE_330; break;
- case 0x360: base_code = ISP16_BASE_360; break;
- case 0x320: base_code = ISP16_BASE_320; break;
- default:
- printk( "Base address 0x%03X not supported by cdrom interface on ISP16.\n", base );
- return(-1);
- }
- switch (irq) {
- case 0: irq_code = ISP16_IRQ_X; break; /* disable irq */
- case 5: irq_code = ISP16_IRQ_5;
- printk( "Irq 5 shouldn't be used by cdrom interface on ISP16,"
- " due to possible conflicts with the soundcard.\n");
- break;
- case 7: irq_code = ISP16_IRQ_7;
- printk( "Irq 7 shouldn't be used by cdrom interface on ISP16,"
- " due to possible conflicts with the soundcard.\n");
- break;
- case 3: irq_code = ISP16_IRQ_3; break;
- case 9: irq_code = ISP16_IRQ_9; break;
- case 10: irq_code = ISP16_IRQ_10; break;
- case 11: irq_code = ISP16_IRQ_11; break;
- default:
- printk( "Irq %d not supported by cdrom interface on ISP16.\n", irq );
- return(-1);
- }
- switch (dma) {
- case 0: dma_code = ISP16_DMA_X; break; /* disable dma */
- case 1: printk( "Dma 1 cannot be used by cdrom interface on ISP16,"
- " due to conflict with the soundcard.\n");
- return(-1); break;
- case 3: dma_code = ISP16_DMA_3; break;
- case 5: dma_code = ISP16_DMA_5; break;
- case 6: dma_code = ISP16_DMA_6; break;
- case 7: dma_code = ISP16_DMA_7; break;
- default:
- printk( "Dma %d not supported by cdrom interface on ISP16.\n", dma );
- return(-1);
- }
-
- if ( drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
- drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
- drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
- drive_type != ISP16_DRIVE_X ) {
- printk( "Drive type (code 0x%02X) not supported by cdrom"
- " interface on ISP16.\n", drive_type );
- return(-1);
- }
-
- /* set type of interface */
- i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK; /* clear some bits */
- ISP16_OUT( ISP16_DRIVE_SET_PORT, i|drive_type );
-
- /* enable cdrom on interface with 82C929 chip */
- if ( isp16_type > 1 )
- ISP16_OUT( isp16_enable_port, ISP16_ENABLE_CDROM );
-
- /* set base address, irq and dma */
- i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK; /* keep some bits */
- ISP16_OUT( ISP16_IO_SET_PORT, i|base_code|irq_code|dma_code );
-
- return(0);
-}
-
-static void isp16_sound_config( void )
-{
- int i;
- u_char saved;
-
- saved = ISP16_IN( 0xF8D ) & 0x8F;
-
- ISP16_OUT( 0xF8D, 0x40 );
-
- /*
- * Now we should wait for a while...
- */
- for( i = 16*1024; i--; );
-
- ISP16_OUT( 0xF8D, saved );
-
- ISP16_OUT( 0xF91, 0x1B );
-
- for( i = 5*64*1024; i != 0; i-- )
- if( !( inb( 0x534 ) & 0x80 ) ) break;
-
- if( i > 0 ) {
- saved = ( inb( 0x534 ) & 0xE0 ) | 0x0A;
- outb( saved, 0x534 );
-
- special_mask = ( inb( 0x535 ) >> 4 ) & 0x08;
-
- saved = ( inb( 0x534 ) & 0xE0 ) | 0x0C;
- outb( saved, 0x534 );
-
- switch( inb( 0x535 ) ) {
- case 0x09:
- case 0x0A:
- special_mask |= 0x05;
- break;
- case 0x8A:
- special_mask = 0x0F;
- break;
- default:
- i = 0;
- }
- }
- if ( i == 0 ) {
- printk( "Strange MediaMagic, but\n" );
- }
- else {
- printk( "Conf:" );
- saved = inb( 0x534 ) & 0xE0;
- for( i = 0; i < 16; i++ ) {
- outb( 0x20 | ( u_char )i, 0x534 );
- outb( defaults[i], 0x535 );
- }
- for ( i = 0; i < 16; i++ ) {
- outb( 0x20 | ( u_char )i, 0x534 );
- saved = inb( 0x535 );
- printk( " %02X", saved );
- }
- printk( "\n" );
- }
-
- ISP16_OUT( 0xF91, 0xA0 | special_mask );
-
- /*
- * The following have no explaination yet.
- */
- ISP16_OUT( 0xF90, 0xA2 );
- ISP16_OUT( 0xF92, 0x03 );
-
- /*
- * Turn general sound on and set total volume.
- */
- ISP16_OUT( 0xF93, 0x0A );
-
-/*
- outb( 0x04, 0x224 );
- saved = inb( 0x225 );
- outb( 0x04, 0x224 );
- outb( saved, 0x225 );
-*/
-
-}
if (info->flags & ASYNC_CALLOUT_ACTIVE)
info->callout_termios = *tty->termios;
if (info->flags & ASYNC_INITIALIZED)
- tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
+ tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */
shutdown(info);
if (tty->driver.flush_buffer)
tty->driver.flush_buffer(tty);
{
int offset = 0;
int count = 0;
+#ifdef MODULE
int failed = 0;
+#endif
if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) {
printk("lp: unable to get major %d\n", LP_MAJOR);
tty->driver_data = pty;
if (!tmp_buf) {
- tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);
- if (!tmp_buf)
- return -ENOMEM;
+ unsigned long page = get_free_page(GFP_KERNEL);
+ if (!tmp_buf) {
+ if (!page)
+ return -ENOMEM;
+ tmp_buf = (unsigned char *) page;
+ } else
+ free_page(page);
}
if (tty->driver.subtype == PTY_TYPE_SLAVE)
{
memcpyw((unsigned short *)vc_scrbuf[currcons],
(unsigned short *)origin, video_screen_size);
- __scrollback_mode = 0 ;
origin = video_mem_start = (unsigned long)vc_scrbuf[currcons];
scr_end = video_mem_end = video_mem_start + video_screen_size;
pos = origin + y*video_size_row + (x<<1);
tristate 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC
tristate 'PLIP (parallel port) support' CONFIG_PLIP
tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
+
+tristate 'FRAD (Frame Relay Access Device) support' CONFIG_FRAD
+if [ "$CONFIG_FRAD" = "y" -o "$CONFIG_FRAD" = "m" ]; then
+ int ' Max open DLCI' CONFIG_DLCI_COUNT 24
+ int ' Max DLCI per device' CONFIG_DLCI_MAX 8
+ tristate ' Sangoma S502A FRAD support' CONFIG_SDLA
+fi
+
bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA
bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC
if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
endif
endif
+ifeq ($(CONFIG_SDLA),y)
+L_OBJS += sdla.o
+else
+ ifeq ($(CONFIG_SDLA),m)
+ M_OBJS += sdla.o
+ endif
+endif
+
+ifeq ($(CONFIG_FRAD),y)
+L_OBJS += dlci.o
+else
+ ifeq ($(CONFIG_FRAD),m)
+ M_OBJS += dlci.o
+ endif
+endif
+
include $(TOPDIR)/Rules.make
clean:
$(CC) $(CPPFLAGS) $(CFLAGS) $(LANCE_OPTS) -c $<
8390.o: 8390.c 8390.h CONFIG
+
+sdla.o: sdla.c CONFIG
+
+dlci.o: dlci.c CONFIG
+
return 0;
}
+#ifdef CONFIG_SDLA
+ extern int sdla_init(struct device *);
+ static struct device sdla0_dev = { "sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, sdla_init, };
+
+# undef NEXT_DEV
+# define NEXT_DEV (&sdla0_dev)
+#endif
+
+/* This must be AFTER the various FRADs so it initializes FIRST! */
+
+#ifdef CONFIG_FRAD
+ extern int dlci_init(struct device *);
+ static struct device dlci_dev = { "dlci", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, dlci_init, };
+# undef NEXT_DEV
+# define NEXT_DEV (&dlci_dev)
+#endif
#ifdef CONFIG_NETROM
extern int nr_init(struct device *);
#endif
#endif
-
+
extern int loopback_init(struct device *dev);
struct device loopback_dev = {
"lo", /* Software Loopback interface */
#include <asm/bitops.h>
#include <asm/segment.h>
-#include <net/if.h>
+#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/netdevice.h>
#include <linux/netprotocol.h>
#endif
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <net/if_arp.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/if_arp.h>
#undef PACKETPTR
#define PACKETPTR 1
Changed driver to autprobe as a module. No irq
checking is done now - assume BIOS is good!
Added SMC9332 detection <manabe@Roy.dsl.tutics.ac.jp>
+ 0.41 21-Mar-96 Don't check for get_hw_addr checksum unless DEC card
+ only <niles@axp745gsfc.nasa.gov>
+ Fix for multiple PCI cards reported by <jos@xos.nl>
+ Duh, put the SA_SHIRQ flag into request_interrupt().
+ Fix SMC ethernet address in enet_det[].
+ Print chip name instead of "UNKNOWN" during boot.
=========================================================================
*/
-static const char *version = "de4x5.c:v0.40 96/3/5 davies@wanton.lkg.dec.com\n";
+static const char *version = "de4x5.c:v0.41 96/3/21 davies@wanton.lkg.dec.com\n";
#include <linux/module.h>
** Define special SROM detection cases
*/
static c_char enet_det[][ETH_ALEN] = {
- {0x00, 0x00, 0x0c, 0x00, 0x00, 0x00}
+ {0x00, 0x00, 0xc0, 0x00, 0x00, 0x00}
};
#define SMC 1
de4x5_dbg_open(dev);
- if (request_irq(dev->irq, (void *)de4x5_interrupt, 0, lp->adapter_name, dev)) {
+ if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ,
+ lp->adapter_name, dev)) {
printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq);
status = -EAGAIN;
} else {
u_int iobase;
struct bus_type *lp = &bus;
- if (!ioaddr && autoprobed) return; /* Been here before ! */
+ if ((!ioaddr || !loading_module) && autoprobed) return;
if (!pcibios_present()) return; /* No PCI bus in this machine! */
if (i == siglen) {
if (dec_only) {
*name = '\0';
- } else {
- strcpy(name, "UNKNOWN");
+ } else { /* Use chip name to avoid confusion */
+ strcpy(name, (((lp->chipset == DC21040) ? "DC21040" :
+ ((lp->chipset == DC21041) ? "DC21041" :
+ ((lp->chipset == DC21140) ? "DC21140" : "UNKNOWN"
+ )))));
}
}
chksum = (u_char) tmp;
while ((tmp = inl(DE4X5_APROM)) < 0);
chksum |= (u_short) (tmp << 8);
- if (k != chksum) status = -1;
+ if ((k != chksum) && (dec_only)) status = -1;
}
} else {
chksum = (u_char) inb(EISA_APROM);
chksum |= (u_short) (inb(EISA_APROM) << 8);
- if (k != chksum) status = -1;
+ if ((k != chksum) && (dec_only)) status = -1;
}
return status;
--- /dev/null
+/*
+ * DLCI Implementation of Frame Relay protocol for Linux, according to
+ * RFC 1490. This generic device provides en/decapsulation for an
+ * underlying hardware driver. Routes & IPs are assigned to these
+ * interfaces. Requires 'dlcicfg' program to create usable
+ * interfaces, the initial one, 'dlci' is for IOCTL use only.
+ *
+ * Version: @(#)dlci.c 0.10 23 Mar 1996
+ *
+ * Author: Mike McLagan <mike.mclagan@linux.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/errno.h>
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/if_frad.h>
+
+#include <net/sock.h>
+
+static const char *devname = "dlci";
+static const char *version = "DLCI driver v0.10, 23 Mar 1996, mike.mclagan@linux.org";
+
+static struct device *open_dev[CONFIG_DLCI_COUNT];
+
+static char *basename[16];
+
+int dlci_init(struct device *dev);
+
+/* allow FRAD's to register their name as a valid FRAD */
+int register_frad(const char *name)
+{
+ int i;
+
+ if (!name)
+ return(-EINVAL);
+
+ for (i=0;i<sizeof(basename) / sizeof(char *);i++)
+ {
+ if (!basename[i])
+ break;
+
+ /* take care of multiple registrations */
+ if (strcmp(basename[i], name) == 0)
+ return(0);
+ }
+
+ if (i == sizeof(basename) / sizeof(char *))
+ return(-ENOMEM);
+
+ basename[i] = (char *) name;
+
+ return(0);
+}
+
+int unregister_frad(const char *name)
+{
+ int i;
+
+ if (!name)
+ return(-EINVAL);
+
+ for (i=0;i<sizeof(basename) / sizeof(char *);i++)
+ if (basename[i] && (strcmp(basename[i], name) == 0))
+ break;
+
+ if (i == sizeof(basename) / sizeof(char *))
+ return(-EINVAL);
+
+ basename[i] = NULL;
+
+ return(0);
+}
+
+/*
+ these encapsulate the RFC 1490 requirements as well as
+ deal with packet transmission and reception, working with
+ the upper network layers
+ */
+
+static int dlci_header(struct sk_buff *skb, struct device *dev,
+ unsigned short type, void *daddr, void *saddr,
+ unsigned len)
+{
+ struct fradhdr hdr;
+ struct dlci_local *dlp;
+ unsigned hlen;
+ char *dest;
+
+ dlp = dev->priv;
+
+ hdr.control = FRAD_I_UI;
+ switch(type)
+ {
+ case ETH_P_IP:
+ hdr.pad = FRAD_P_IP;
+ hlen = sizeof(hdr.control) + sizeof(hdr.pad);
+ break;
+
+ /* feel free to add other types, if necessary */
+
+ default:
+ hdr.pad = FRAD_P_PADDING;
+ hdr.NLPID = FRAD_P_SNAP;
+ memset(hdr.OUI, 0, sizeof(hdr.OUI));
+ hdr.PID = type;
+ hlen = sizeof(hdr);
+ break;
+ }
+
+ dest = skb_push(skb, hlen);
+ if (!dest)
+ return(0);
+
+ memcpy(dest, &hdr, hlen);
+
+ return(hlen);
+}
+
+static void dlci_receive(struct sk_buff *skb, struct device *dev)
+{
+ struct dlci_local *dlp;
+ struct fradhdr *hdr;
+ int process, header;
+
+ dlp = dev->priv;
+ hdr = (struct fradhdr *) skb->data;
+ process = 0;
+ header = 0;
+ skb->dev = dev;
+
+ if (hdr->control != FRAD_I_UI)
+ {
+ printk(KERN_NOTICE "%s: Invalid header flag 0x%02X.\n", dev->name, hdr->control);
+ dlp->stats.rx_errors++;
+ }
+ else
+ switch(hdr->pad)
+ {
+ case FRAD_P_PADDING:
+ if (hdr->NLPID != FRAD_P_SNAP)
+ {
+ printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->NLPID);
+ dlp->stats.rx_errors++;
+ break;
+ }
+
+ if (hdr->OUI[0] + hdr->OUI[1] + hdr->OUI[2] != 0)
+ {
+ printk(KERN_NOTICE "%s: Unsupported organizationally unique identifier 0x%02X-%02X-%02X.\n", dev->name, hdr->OUI[0], hdr->OUI[1], hdr->OUI[2]);
+ dlp->stats.rx_errors++;
+ break;
+ }
+
+ /* at this point, it's an EtherType frame */
+ header = sizeof(struct fradhdr);
+ skb->protocol = htons(hdr->PID);
+ process = 1;
+ break;
+
+ case FRAD_P_IP:
+ header = sizeof(hdr->control) + sizeof(hdr->pad);
+ skb->protocol = htons(ETH_P_IP);
+ process = 1;
+ break;
+
+ case FRAD_P_SNAP:
+ case FRAD_P_Q933:
+ case FRAD_P_CLNP:
+ printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->pad);
+ dlp->stats.rx_errors++;
+ break;
+
+ default:
+ printk(KERN_NOTICE "%s: Invalid pad byte 0x%02X.\n", dev->name, hdr->pad);
+ dlp->stats.rx_errors++;
+ break;
+ }
+
+ if (process)
+ {
+ /* we've set up the protocol, so discard the header */
+ skb->mac.raw = skb->data;
+ skb_pull(skb, header);
+ netif_rx(skb);
+ dlp->stats.rx_packets++;
+ }
+ else
+ dev_kfree_skb(skb, FREE_WRITE);
+}
+
+static int dlci_transmit(struct sk_buff *skb, struct device *dev)
+{
+ struct dlci_local *dlp;
+ int ret;
+
+ ret = 0;
+
+ if (!skb || !dev)
+ return(0);
+
+ if (dev->tbusy)
+ return(1);
+
+ dlp = dev->priv;
+
+ if (set_bit(0, (void*)&dev->tbusy) != 0)
+ printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
+ else
+ {
+ ret = dlp->slave->hard_start_xmit(skb, dlp->slave);
+ if (ret)
+ dlp->stats.tx_errors++;
+ else
+ dlp->stats.tx_packets++;
+
+ /* per Alan Cox, always return 0, let the slave free the packet */
+ ret = 0;
+ dev->tbusy = 0;
+ }
+
+ return(ret);
+}
+
+int dlci_add(struct dlci_add *new)
+{
+ struct device *master, *slave;
+ struct dlci_local *dlp;
+ struct frad_local *flp;
+ struct dlci_add dlci;
+ int err, i;
+ char buf[10];
+
+ err = verify_area(VERIFY_READ, new, sizeof(*new));
+ if (err)
+ return(err);
+
+ memcpy_fromfs(&dlci, new, sizeof(dlci));
+
+ /* validate slave device */
+ slave = dev_get(dlci.devname);
+ if (!slave)
+ return(-ENODEV);
+
+ if (slave->type != ARPHRD_FRAD)
+ return(-EINVAL);
+
+ /* check for registration */
+ for (i=0;i<sizeof(basename) / sizeof(char *); i++)
+ if ((basename[i]) &&
+ (strncmp(dlci.devname, basename[i], strlen(basename[i])) == 0) &&
+ (strlen(dlci.devname) > strlen(basename[i])))
+ break;
+
+ if (i == sizeof(basename) / sizeof(char *))
+ return(-EINVAL);
+
+ /* check for too many open devices : should this be dynamic ? */
+ for(i=0;i<CONFIG_DLCI_COUNT;i++)
+ if (!open_dev[i])
+ break;
+
+ if (i == CONFIG_DLCI_COUNT)
+ return(-ENOSPC); /* #### Alan: Comments on this?? */
+
+ /* create device name */
+ sprintf(buf, "%s%02i", devname, i);
+
+ master = kmalloc(sizeof(*master), GFP_KERNEL);
+ if (!master)
+ return(-ENOMEM);
+
+ memset(master, 0, sizeof(*master));
+ master->name = kmalloc(strlen(buf), GFP_KERNEL);
+
+ if (!master->name)
+ {
+ kfree(master);
+ return(-ENOMEM);
+ }
+
+ strcpy(master->name, buf);
+ master->init = dlci_init;
+ master->flags = 0;
+
+ err = register_netdev(master);
+ if (err < 0)
+ {
+ kfree(master->name);
+ kfree(master);
+ return(err);
+ }
+
+ *(short *)(master->dev_addr) = dlci.dlci;
+
+ dlp = (struct dlci_local *) master->priv;
+ dlp->slave = slave;
+
+ flp = slave->priv;
+ err = flp ? (*flp->assoc)(slave, master) : -EINVAL;
+ if (err < 0)
+ {
+ unregister_netdev(master);
+ kfree(master->priv);
+ kfree(master->name);
+ kfree(master);
+ return(err);
+ }
+
+ memcpy_tofs(new->devname, buf, strlen(buf) + 1);
+ open_dev[i] = master;
+
+ MOD_INC_USE_COUNT;
+
+ return(0);
+}
+
+int dlci_del(struct device *master)
+{
+ struct dlci_local *dlp;
+ struct frad_local *flp;
+ struct device *slave;
+ int i, err;
+
+ if (master->start)
+ return(-EBUSY);
+
+ dlp = master->priv;
+ slave = dlp->slave;
+ flp = slave->priv;
+
+ err = (*flp->deassoc)(slave, master);
+ if (err)
+ return(err);
+
+ unregister_netdev(master);
+
+ for(i=0;i<CONFIG_DLCI_COUNT;i++)
+ if (master == open_dev[i])
+ break;
+
+ if (i<CONFIG_DLCI_COUNT)
+ open_dev[i] = NULL;
+
+ kfree(master->priv);
+ kfree(master->name);
+ kfree(master);
+
+ MOD_DEC_USE_COUNT;
+
+ return(0);
+}
+
+int dlci_config(struct device *dev, struct dlci_conf *conf, int get)
+{
+ struct dlci_conf config;
+ struct dlci_local *dlp;
+ struct frad_local *flp;
+ int err;
+
+ dlp = dev->priv;
+
+ flp = dlp->slave->priv;
+
+ if (!get)
+ {
+ memcpy_fromfs(&config, conf, sizeof(struct dlci_conf));
+ if (config.flags & ~DLCI_VALID_FLAGS)
+ return(-EINVAL);
+ memcpy(&dlp->config, &config, sizeof(struct dlci_conf));
+ dlp->configured = 1;
+ }
+
+ err = (*flp->dlci_conf)(dlp->slave, dev, get);
+ if (err)
+ return(err);
+
+ if (get)
+ memcpy_tofs(conf, &dlp->config, sizeof(struct dlci_conf));
+
+ return(0);
+}
+
+int dlci_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
+{
+ struct dlci_local *dlp;
+
+ if (!suser())
+ return(-EPERM);
+
+ dlp = dev->priv;
+
+ switch(cmd)
+ {
+ case DLCI_GET_SLAVE:
+ if (!*(short *)(dev->dev_addr))
+ return(-EINVAL);
+
+ strcpy(ifr->ifr_slave, dlp->slave->name);
+ break;
+
+ case DLCI_DEVADD:
+ /* can only add on the primary device */
+ if (*(short *)(dev->dev_addr))
+ return(-EINVAL);
+
+ return(dlci_add((struct dlci_add *) ifr->ifr_data));
+ break;
+
+ case DLCI_DEVDEL:
+ /* can't delete the primary device */
+ if (!*(short *)(dev->dev_addr))
+ return(-EINVAL);
+
+ if (dev->start)
+ return(-EBUSY);
+
+ return(dlci_del(dev));
+ break;
+
+ case DLCI_GET_CONF:
+ case DLCI_SET_CONF:
+ if (!*(short *)(dev->dev_addr))
+ return(-EINVAL);
+
+ return(dlci_config(dev, (struct dlci_conf *) ifr->ifr_data, cmd == DLCI_GET_CONF));
+ break;
+
+ default:
+ return(-EOPNOTSUPP);
+ }
+ return(0);
+}
+
+static int dlci_change_mtu(struct device *dev, int new_mtu)
+{
+ struct dlci_local *dlp;
+
+ dlp = dev->priv;
+
+ return((*dlp->slave->change_mtu)(dlp->slave, new_mtu));
+}
+
+static int dlci_open(struct device *dev)
+{
+ struct dlci_local *dlp;
+ struct frad_local *flp;
+ int err;
+
+ dlp = dev->priv;
+
+ if (!*(short *)(dev->dev_addr))
+ return(-EINVAL);
+
+ if (!dlp->slave->start)
+ return(-ENOTCONN);
+
+ dev->flags = 0;
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+
+ flp = dlp->slave->priv;
+ err = (*flp->activate)(dlp->slave, dev);
+ if (err)
+ return(err);
+
+ return 0;
+}
+
+static int dlci_close(struct device *dev)
+{
+ struct dlci_local *dlp;
+ struct frad_local *flp;
+ int err;
+
+ dlp = dev->priv;
+
+ flp = dlp->slave->priv;
+ err = (*flp->deactivate)(dlp->slave, dev);
+
+ dev->start = 0;
+
+ return 0;
+}
+
+static struct enet_statistics *dlci_get_stats(struct device *dev)
+{
+ struct dlci_local *dlp;
+
+ dlp = dev->priv;
+
+ return(&dlp->stats);
+}
+
+int dlci_init(struct device *dev)
+{
+ struct dlci_local *dlp;
+ int i;
+
+ dev->priv = kmalloc(sizeof(struct dlci_local), GFP_KERNEL);
+ if (!dev->priv)
+ return(-ENOMEM);
+
+ memset(dev->priv, 0, sizeof(struct dlci_local));
+ dlp = dev->priv;
+
+ dev->flags = 0;
+ dev->open = dlci_open;
+ dev->stop = dlci_close;
+ dev->do_ioctl = dlci_ioctl;
+ dev->hard_start_xmit = dlci_transmit;
+ dev->hard_header = dlci_header;
+ dev->get_stats = dlci_get_stats;
+ dev->change_mtu = dlci_change_mtu;
+
+ dlp->receive = dlci_receive;
+
+ dev->type = ARPHRD_DLCI;
+ dev->family = AF_INET;
+ dev->hard_header_len = sizeof(struct fradhdr);
+ dev->pa_alen = sizeof(unsigned long);
+
+ memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
+
+ for (i = 0; i < DEV_NUMBUFFS; i++)
+ skb_queue_head_init(&dev->buffs[i]);
+
+ return(0);
+}
+
+int dlci_setup(void)
+{
+ int i;
+
+ printk("%s.\n", version);
+
+ for(i=0;i<CONFIG_DLCI_COUNT;i++)
+ open_dev[i] = NULL;
+
+ for(i=0;i<sizeof(basename) / sizeof(char *);i++)
+ basename[i] = NULL;
+
+ return(0);
+}
+
+#ifdef MODULE
+static struct device dlci = {"dlci", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, dlci_init, };
+
+int init_module(void)
+{
+ dlci_setup();
+ return(register_netdev(&dlci));
+}
+
+void cleanup_module(void)
+{
+ struct dlci_local *dlp;
+ struct frad_local *flp;
+ int i;
+
+ unregister_netdev(&dlci);
+
+ for(i=0;i<CONFIG_DLCI_COUNT;i++)
+ if (open_dev[i])
+ {
+ dlp = open_dev[i]->priv;
+ flp = open_dev[i]->slave->priv;
+
+ if (open_dev[i]->start)
+ {
+ if (flp->deactivate)
+ (*flp->deactivate)(open_dev[i]->slave, open_dev[i]);
+ open_dev[i]->start = 0;
+ }
+
+ (*flp->deassoc)(open_dev[i]->slave, open_dev[i]);
+ kfree(open_dev[i]->priv);
+ kfree(open_dev[i]->name);
+ kfree(open_dev[i]);
+ open_dev[i] = NULL;
+ }
+
+ if (dlci.priv)
+ kfree(dlci.priv);
+}
+#endif /* MODULE */
/* ibmtr.c: A shared-memory IBM Token Ring 16/4 driver for linux */
/*
- Written 1993 by Mark Swanson and Peter De Schrijver.
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
+ Written 1993 by Mark Swanson and Peter De Schrijver.
+ This software may be used and distributed according to the terms
+ of the GNU Public License, incorporated herein by reference.
- This device driver should work with Any IBM Token Ring Card that does
- not use DMA.
+ This device driver should work with Any IBM Token Ring Card that does
+ not use DMA.
- I used Donald Becker's (becker@super.org) device driver work
- as a base for most of my initial work.
+ I used Donald Becker's (becker@super.org) device driver work
+ as a base for most of my initial work.
*/
/*
- removed redundant information display
- some code reworking
+ Changes by Michel Lespinasse (walken@via.ecp.fr),
+ Yann Doussot (doussot@via.ecp.fr) and Pascal Andre (andre@via.ecp.fr)
+ (February 18, 1996) :
+ - modified shared memory and mmio access port the driver to
+ alpha platform (structure access -> readb/writeb)
+
Chagnes by Steve Kipisz (bungy@ibm.net or kipisz@vnet.ibm.com)
(January 18 1996):
- swapped WWOR and WWCR in ibmtr.h
/* changes the output format of driver initialisation */
#define TR_NEWFORMAT 1
+#define TR_VERBOSE 0
/* some 95 OS send many non UI frame; this allow removing the warning */
#define TR_FILTERNONUI 1
/* version and credits */
-static const char *version = "ibmtr.c: v1.3.24 8/7/94 Peter De Schrijver and Mark Swanson\n"
-" modified 10/3/94 DW Morris, 3/9/95 F Farid and P Andre, 9/7/95 P Andre\n";
-
+static const char *version =
+"ibmtr.c: v1.3.57 8/7/94 Peter De Schrijver and Mark Swanson\n"
+" modified 10/3/94 DW Morris, modified at VIA, ECP, France\n"
+" (3/9/95 F Farid and P Andre, 9/7/95 PA and 2/20/95 ML/PA/YD)\n";
+
static char pcchannelid[]={0x05, 0x00, 0x04, 0x09,
- 0x04, 0x03, 0x04, 0x0f,
- 0x03, 0x06, 0x03, 0x01,
- 0x03, 0x01, 0x03, 0x00,
- 0x03, 0x09, 0x03, 0x09,
- 0x03, 0x00, 0x02, 0x00};
+ 0x04, 0x03, 0x04, 0x0f,
+ 0x03, 0x06, 0x03, 0x01,
+ 0x03, 0x01, 0x03, 0x00,
+ 0x03, 0x09, 0x03, 0x09,
+ 0x03, 0x00, 0x02, 0x00};
static char mcchannelid[]={0x04, 0x0d, 0x04, 0x01,
- 0x05, 0x02, 0x05, 0x03,
- 0x03, 0x06, 0x03, 0x03,
- 0x05, 0x08, 0x03, 0x04,
- 0x03, 0x05, 0x03, 0x01,
- 0x03, 0x08, 0x02, 0x00};
+ 0x05, 0x02, 0x05, 0x03,
+ 0x03, 0x06, 0x03, 0x03,
+ 0x05, 0x08, 0x03, 0x04,
+ 0x03, 0x05, 0x03, 0x01,
+ 0x03, 0x08, 0x02, 0x00};
#include <linux/kernel.h>
#include <linux/sched.h>
#define DPRINTK(format, args...) printk("%s: " format, dev->name , ## args)
#define DPRINTD(format, args...) DummyCall("%s: " format, dev->name , ## args)
-#ifdef TR_NEWFORMAT
+#if TR_NEWFORMAT
/* this allows displaying full adapter information */
const char *channel_def[] = { "ISA", "MCA", "ISA P&P" };
+
char *adapter_def(char type)
{
- switch (type)
- {
- case 0xF : return "Adapter/A";
- case 0xE : return "16/4 Adapter/II";
- default : return "adapter";
- };
+ switch (type) {
+ case 0xF : return "Adapter/A";
+ case 0xE : return "16/4 Adapter/II";
+ default : return "adapter";
+ };
};
#endif
-#if 0
-struct tok_info tok_info1; /* WARNING: this area must be replicated
- or 'malloced' to support > 1 adapter */
-
-static struct wait_queue *wait_for_tok_int=NULL, *wait_for_reset;
-void (*do_tok_int)(struct device *dev)=NULL;
-#endif
-
-#ifndef TR_NEWFORMAT
+#if !TR_NEWFORMAT
unsigned char ibmtr_debug_trace=1; /* Patch or otherwise alter to
control tokenring tracing. */
#else
#define TRC_INIT 0x01 /* Trace initialization & PROBEs */
#define TRC_INITV 0x02 /* verbose init trace points */
-static short TokBaseAddrs[]={MMIOStartLocP, /* Addr-s to scan */
- MMIOStartLocA};
+/* addresses to scan */
+static short TokBaseAddrs[] = { MMIOStartLocP, MMIOStartLocA };
int tok_probe(struct device *dev);
static struct timer_list tr_timer={NULL,NULL,0,0L,tok_open_adapter};
+#if 0
int DummyCallCount=0;
/* This routine combined with the #DEFINE DPRINTD serves
to workaround the gcc apparent bug. in tr_tx() */
-static void DummyCall(const char * fmt,...) {DummyCallCount++;return;}
+static void DummyCall(const char * fmt,...)
+{ DummyCallCount++; return; }
+#endif
static void PrtChanID(char *pcid, short stride) {
- short i, j;
- for (i=0,j=0;i<24;i++,j=j+stride) printk("%1x",((int) pcid[j])&0x0f);
- printk("\n");
+ short i, j;
+ for (i=0, j=0; i<24; i++, j+=stride)
+ printk("%1x", ((int) pcid[j]) & 0x0f);
+ printk("\n");
+}
+
+static void HWPrtChanID (__u32 pcid, short stride)
+{
+ short i, j;
+ for (i=0, j=0; i<24; i++, j+=stride)
+ printk("%1x", ((int)readb(pcid + j)) & 0x0f);
+ printk("\n");
}
/* tok_probe(): Routine specified in the network device structure
int tok_probe(struct device *dev)
{
+ unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0;
+ __u32 t_mmio=0;
+ short PIOaddr=0, iAddr;
+ struct tok_info *ti=0;
+ static struct tok_info *badti=0; /* if fail after kmalloc, reuse */
+
+ static unsigned char Shared_Ram_Base = IBMTR_SHARED_RAM_BASE;
+
+ /* this is the major adapter probe loop. For each call to tok_probe,
+ we try each remaining entry in TokBaseAddrs[] as a possible
+ adapter. Once an entry is rejected or assigned, we zero it to
+ avoid duplicate use or worthless trial for the tok probe call*/
+
+ for (iAddr=0;
+ iAddr < (sizeof(TokBaseAddrs)/sizeof(short))&&PIOaddr==0; iAddr++) {
+
+ __u32 cd_chanid;
+ unsigned char *tchanid, ctemp;
+
+ PIOaddr=TokBaseAddrs[iAddr]; /* address to try */
+ TokBaseAddrs[iAddr] = 0; /* (and marked already used */
+ if (PIOaddr == 0) continue; /* already tried this addr */
+
+ /* Make sure PIO address not already assigned
+ elsewhere before we muck with IO address */
+ if (check_region(PIOaddr,TR_IO_EXTENT)) {
+ if (ibmtr_debug_trace & TRC_INIT)
+ DPRINTK("check_region(%4hx,%d) failed.\n", PIOaddr, TR_IO_EXTENT);
+ PIOaddr = 0;
+ continue; /* clear to flag fail and try next */
+ }
+ /* Query the adapter PIO base port which will return
+ indication of where MMIO was placed (per tech ref
+ this assignment is done by BIOS - what is rational for
+ where it is?). We also have a coded interrupt address. */
+
+ segment = inb(PIOaddr);
+ /* out of range values so we'll assume non-existant IO device */
+ if (segment < 0x40 || segment > 0xe0) {
+ PIOaddr = 0;
+ continue; /* clear to flag fail and try next */
+ }
+
+ /* Compute the linear base address of the MMIO area
+ as LINUX doesn't care about segments */
+ t_mmio=(((__u32)(segment & 0xfc) << 11) + 0x80000);
+ intr = segment & 0x03; /* low bits is coded interrupt # */
+ if (ibmtr_debug_trace & TRC_INIT)
+ DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %08X intr: %d\n", PIOaddr, (int)segment, t_mmio, (int)intr);
+
+ /* Now we will compare expected 'channelid' strings with
+ what we is there to learn of ISA/MCA or not TR card */
+ /* !!!WARNING:!!!! It seems pretty silly to blunder ahead
+ w/o verification that the mmio address we have found
+ is valid storage -- perhaps this is tolerable for current
+ hardware state??? */
+
+ cd_chanid = (CHANNEL_ID + t_mmio); /* for efficiency */
+ tchanid=pcchannelid;
+ cardpresent=TR_ISA; /* try ISA */
+
+ /* suboptimize knowing first byte different */
+ ctemp = readb(cd_chanid) & 0x0f;
+ if (ctemp != *tchanid) { /* NOT ISA card, try MCA */
+ tchanid=mcchannelid;
+ cardpresent=TR_MCA;
+ if (ctemp != *tchanid) /* Neither ISA nor MCA */
+ cardpresent=NOTOK;
+ }
+
+ if (cardpresent != NOTOK) { /* know presumed type, try rest of ID */
+ for (i=2,j=1; i<=46; i=i+2,j++) {
+ if ((readb(cd_chanid+i) & 0x0f) != tchanid[j]) {
+ cardpresent=NOTOK; /* match failed, not TR card */
+ break;
+ }
+ }
+ }
+
+ /* If we have an ISA board check for the ISA P&P version,
+ as it has different IRQ settings */
+ if (cardpresent == TR_ISA && (readb(AIPFID + t_mmio)==0x0e))
+ cardpresent=TR_ISAPNP;
+
+ if (cardpresent == NOTOK) { /* "channel_id" did not match, report */
+ if (ibmtr_debug_trace & TRC_INIT) {
+ DPRINTK("Channel ID string not found for PIOaddr: %4hx\n", PIOaddr);
+ DPRINTK("Expected for ISA: "); PrtChanID(pcchannelid,1);
+ DPRINTK(" found: "); HWPrtChanID(cd_chanid,2);
+ DPRINTK("Expected for MCA: "); PrtChanID(mcchannelid,1);
+ }
+ PIOaddr = 0; /* all to know not found yet */
+ continue;
+ }
+
+ /* !!!! we could tighten validation by checking the HW Address
+ against the 1-s complement.. Move the get HW logic to here */
+
+ }
+
+ /* The search loop has either completed with a presumed TR adapter
+ or none found. Check situation ... march on if possible */
+
+ if (PIOaddr == 0) { /* failed to find a valid TR adapter */
+ if (ibmtr_debug_trace & TRC_INIT)
+ DPRINTK("Unable to assign adapter to device.\n");
+ return ENODEV;
+ }
+
+ /*?? Now, allocate some of the pl0 buffers for this driver.. */
+
+ if (!badti) {
+ ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
+ if (ti == NULL) return -ENOMEM;
+ } else {
+ ti = badti;
+ badti = NULL;
+ } /*?? dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); */
+
+ memset(ti, 0, sizeof(struct tok_info));
- unsigned char segment=0, intr=0, irq=0, i=0, j=0,
- cardpresent=NOTOK,temp=0;
- unsigned char *t_mmio=0;
- short PIOaddr=0, iAddr;
- struct tok_info *ti=0;
- static struct tok_info *badti=0; /* if fail after kmalloc, reuse */
-
- static unsigned char Shared_Ram_Base = IBMTR_SHARED_RAM_BASE;
-
- /* this is the major adapter probe loop. For each call to tok_probe,
- we try each remaining entry in TokBaseAddrs[] as a possible
- adapter. Once an entry is rejected or assigned, we zero it to
- avoid duplicate use or worthless trial for the tok probe call*/
-
- for (iAddr=0;
- iAddr < (sizeof(TokBaseAddrs)/sizeof(short))&&PIOaddr==0;
- iAddr++) { char *tchanid, *cd_chanid, ctemp;
- PIOaddr=TokBaseAddrs[iAddr]; /* address to try */
- TokBaseAddrs[iAddr] = 0; /* (and marked already used */
- if (PIOaddr == 0) continue; /* already tried this addr */
- if ( check_region(PIOaddr,TR_IO_EXTENT) ) { /* Make sure PIO address not
- already assigned elsewhere
- before we muck with I/O
- addresses */
- if (ibmtr_debug_trace & TRC_INIT)
- DPRINTK("check_region(%4hx,%d) failed.\n",PIOaddr, TR_IO_EXTENT);
- PIOaddr = 0; continue; /* clear to flag fail and try next */
- }
- /* Query the adapter PIO base port which will return
- indication of where MMIO was placed (per tech ref
- this assignment is done by BIOS - what is rational for
- where it is?). We also have a coded interrupt address.*/
-
- segment = inb(PIOaddr);
- if (segment < 0x40 || segment > 0xe0) { /* out of range values
- so we will assume non-existant IO dev */
- PIOaddr = 0; continue; /* clear to flag fail and try next */
- }
-
- /* Compute the linear base address of the MMIO area
- as LINUX doesn't care about segments */
- t_mmio=(char *) (((segment & 0xfc) << 11) + 0x80000);
- intr = segment & 0x03; /* low bits is coded interrupt # */
- if (ibmtr_debug_trace & TRC_INIT)
- DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %p intr: %d\n",
- PIOaddr, (int) segment,t_mmio,(int) intr);
- /* Now we will compare expected 'channelid' strings with
- what we is there to learn of ISA/MCA or not TR card */
- /* !!!WARNING:!!!! It seems pretty silly to blunder ahead
- w/o verification that the mmio address we have found
- is valid storage -- perhaps this is tolerable for current
- hardware state??? */
- cd_chanid = (char *)(CHANNEL_ID + t_mmio); /* for efficiency */
- tchanid=pcchannelid; cardpresent=TR_ISA; /* try ISA ? */
- /* suboptimize knowing first byte different */
- ctemp = (* cd_chanid) & 0x0f;
- if ( ctemp != *tchanid) { /* NOT ISA card, try MCA */
- tchanid=mcchannelid; cardpresent=TR_MCA;
- if ( ctemp != *tchanid) /* Neither ISA nor MCA */
- cardpresent=NOTOK;
- }
- if (cardpresent != NOTOK) { /* know presumed type, try rest of ID */
- for (i=2,j=1; i<=46; i=i+2,j++) {
- if ( (cd_chanid[i] & 0x0f) != tchanid[j]) {
- cardpresent=NOTOK; /* match failed, not TR card */
- break;
- }
- }
- }
-
- /* If we have an ISA board check for the ISA P&P version, as it has
- different IRQ settings */
- if (cardpresent == TR_ISA && (*(AIPFID + t_mmio)==0x0e))
- cardpresent=TR_ISAPNP;
-
- if (cardpresent == NOTOK) { /* "channel_id" did not match, report */
- if (ibmtr_debug_trace & TRC_INIT) {
- DPRINTK("Channel ID string not found for PIOaddr: %4hx\n",
- PIOaddr);
- DPRINTK("Expected for ISA: "); PrtChanID(pcchannelid,1);
- DPRINTK(" found: "); PrtChanID(cd_chanid,2);
- DPRINTK("Expected for MCA: "); PrtChanID(mcchannelid,1);
- }
- PIOaddr = 0; /* all to know not found yet */
- continue;
- }
-
- /* !!!! we could tighten validation by checking the HW Address
- against the 1-s complement.. Move the get HW logic to here */
-
- }
-
- /* The search loop has either completed with a presumed TR adapter
- or none found. Check situation ... march on if possible */
-
- if (PIOaddr == 0) { /* failed to find a valid TR adapter */
- if (ibmtr_debug_trace & TRC_INIT)
- DPRINTK("Unable to assign adapter to device.\n");
- return ENODEV;
- }
-
- /*?? Now, allocate some of the pl0 buffers for this driver.. */
-
- if (!badti) {
- ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
- if (ti == NULL)
- return -ENOMEM;
- } else {
- ti = badti; badti = NULL;
- }/*?? dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); */
-
- memset(ti,0,sizeof(struct tok_info));
-
- ti->mmio= t_mmio;
-
- dev->priv = ti; /* this seems like the logical use of the
+ ti->mmio= t_mmio;
+
+ dev->priv = ti; /* this seems like the logical use of the
field ... lets try some empirical tests
using the token-info structure -- that
should fit with out future hope of multiple
adapter support as well /dwm */
- switch (cardpresent) {
- case TR_ISA:
- if (intr==0) irq=9; /* irq2 really is irq9 */
- if (intr==1) irq=3;
- if (intr==2) irq=6;
- if (intr==3) irq=7;
- ti->global_int_enable=GLOBAL_INT_ENABLE+((irq==9) ? 2 : irq);
- ti->sram=NULL;
-#ifndef TR_NEWFORMAT
- DPRINTK("ti->global_int_enable: %04X\n",ti->global_int_enable);
+ switch (cardpresent) {
+ case TR_ISA:
+ if (intr==0) irq=9; /* irq2 really is irq9 */
+ if (intr==1) irq=3;
+ if (intr==2) irq=6;
+ if (intr==3) irq=7;
+ ti->global_int_enable=GLOBAL_INT_ENABLE+((irq==9) ? 2 : irq);
+ ti->sram=0;
+#if !TR_NEWFORMAT
+ DPRINTK("ti->global_int_enable: %04X\n",ti->global_int_enable);
#endif
- break;
- case TR_MCA:
- if (intr==0) irq=9;
- if (intr==1) irq=3;
- if (intr==2) irq=10;
- if (intr==3) irq=11;
- ti->global_int_enable=0;
- ti->sram=(unsigned char *)((inb(PIOaddr+ADAPTRESETREL) & 0xfe)
- << 12);
- break;
- case TR_ISAPNP:
- if (intr==0) irq=9;
- if (intr==1) irq=3;
- if (intr==2) irq=10;
- if (intr==3) irq=11;
- while(!(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN));
- ti->sram=(unsigned char *)((unsigned long)(*(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)) <<12);
- ti->global_int_enable=PIOaddr+ADAPTINTREL;
- break;
+ break;
+ case TR_MCA:
+ if (intr==0) irq=9;
+ if (intr==1) irq=3;
+ if (intr==2) irq=10;
+ if (intr==3) irq=11;
+ ti->global_int_enable=0;
+ ti->sram=((__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12);
+ break;
+ case TR_ISAPNP:
+ if (intr==0) irq=9;
+ if (intr==1) irq=3;
+ if (intr==2) irq=10;
+ if (intr==3) irq=11;
+ while(!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN));
+ ti->sram=((__u32)readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)<<12);
+ ti->global_int_enable=PIOaddr+ADAPTINTREL;
+ break;
- }
-
- if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
- DPRINTK("irq=%d",irq);
- if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */
- DPRINTK(", ti->mmio=%p",ti->mmio);
- printk(", segment=%02X",segment);
- }
- printk(".\n");
- }
-
- /* Get hw address of token ring card */
-#ifndef TR_NEWFORMAT
- DPRINTK("hw address: ");
+ }
+
+ if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
+ DPRINTK("irq=%d",irq);
+ if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */
+ DPRINTK(", ti->mmio=%08X",ti->mmio);
+ printk(", segment=%02X",segment);
+ }
+ printk(".\n");
+ }
+
+ /* Get hw address of token ring card */
+#if !TR_NEWFORMAT
+ DPRINTK("hw address: ");
#endif
- j=0;
- for (i=0; i<0x18; i=i+2) {
- temp = *(char *)((ulong)AIP + (ulong)i + ti->mmio) & 0x0f; /* Tech ref states must do this */
-#ifndef TR_NEWFORMAT
- printk("%1X",ti->hw_address[j]=temp);
+ j=0;
+ for (i=0; i<0x18; i=i+2) {
+ /* technical reference states to do this */
+ temp = readb(ti->mmio + AIP + i) & 0x0f;
+#if !TR_NEWFORMAT
+ printk("%1X",ti->hw_address[j]=temp);
#else
- ti->hw_address[j]=temp;
+ ti->hw_address[j]=temp;
#endif
- if(j&1)
- dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4);
- ++j;
- }
+ if(j&1)
+ dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4);
+ ++j;
+ }
#ifndef TR_NEWFORMAT
- printk("\n");
+ printk("\n");
#endif
+ /* get Adapter type: 'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/
+ ti->adapter_type = readb(ti->mmio + AIPADAPTYPE);
- /* get Adapter type: 'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/
- ti->adapter_type = *(char *)(ti->mmio + AIPADAPTYPE);
-
- /* get Data Rate: F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */
- ti->data_rate = *(char *)(ti->mmio + AIPDATARATE);
+ /* get Data Rate: F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */
+ ti->data_rate = readb(ti->mmio + AIPDATARATE);
- /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */
- ti->token_release = *(char *)(ti->mmio + AIPEARLYTOKEN);
+ /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */
+ ti->token_release = readb(ti->mmio + AIPEARLYTOKEN);
- /* How much shared RAM is on adapter ? */
- ti->avail_shared_ram = get_sram_size(ti);
+ /* How much shared RAM is on adapter ? */
+ ti->avail_shared_ram = get_sram_size(ti);
- /* We need to set or do a bunch of work here based on previous results.. */
- /* Support paging? What sizes?: F=no, E=16k, D=32k, C=16 & 32k */
- ti->shared_ram_paging = *(char *)(ti->mmio + AIPSHRAMPAGE);
+ /* We need to set or do a bunch of work here based on previous results.. */
+ /* Support paging? What sizes?: F=no, E=16k, D=32k, C=16 & 32k */
+ ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE);
/* Available DHB 4Mb size: F=2048, E=4096, D=4464 */
- ti->dhb_size4mb = *(char *) (ti->mmio + AIP4MBDHB);
+ ti->dhb_size4mb = readb(ti->mmio + AIP4MBDHB);
- /* Available DHB 16Mb size: F=2048, E=4096, D=8192, C=16384, B=17960 */
- ti->dhb_size16mb = *(char *)(ti->mmio + AIP16MBDHB);
+ /* Available DHB 16Mb size: F=2048, E=4096, D=8192, C=16384, B=17960 */
+ ti->dhb_size16mb = readb(ti->mmio + AIP16MBDHB);
-#ifndef TR_NEWFORMAT
- DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type,
- ti->data_rate, ti->token_release, ti->avail_shared_ram/2, ti->shared_ram_paging,
- ti->dhb_size4mb, ti->dhb_size16mb);
+#if !TR_NEWFORMAT
+ DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, "
+ "dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type,
+ ti->data_rate, ti->token_release, ti->avail_shared_ram/2,
+ ti->shared_ram_paging, ti->dhb_size4mb, ti->dhb_size16mb);
#endif
- /* We must figure out how much shared memory space this adapter
- will occupy so that if there are two adapters we can fit both
- in. Given a choice, we will limit this adapter to 32K. The
- maximum space will will use for two adapters is 64K so if the
- adapter we are working on demands 64K (it also doesn't support
- paging), then only one adapter can be supported. */
-
- /* determine how much of total RAM is mapped into PC space */
- ti->mapped_ram_size=1<<(((*(unsigned char *)
- (ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2)+4);
- ti->page_mask=0;
- if (ti->shared_ram_paging == 0xf) { /* No paging in adapter */
- ti->mapped_ram_size = ti->avail_shared_ram;
- } else {
+ /* We must figure out how much shared memory space this adapter
+ will occupy so that if there are two adapters we can fit both
+ in. Given a choice, we will limit this adapter to 32K. The
+ maximum space will will use for two adapters is 64K so if the
+ adapter we are working on demands 64K (it also doesn't support
+ paging), then only one adapter can be supported. */
+
+ /* determine how much of total RAM is mapped into PC space */
+ ti->mapped_ram_size=1<<(((readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)) >>2) +4);
+ ti->page_mask=0;
+ if (ti->shared_ram_paging == 0xf) { /* No paging in adapter */
+ ti->mapped_ram_size = ti->avail_shared_ram;
+ } else {
#ifdef ENABLE_PAGING
- unsigned char pg_size;
+ unsigned char pg_size;
#endif
-#ifndef TR_NEWFORMAT
- DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2);
+#if !TR_NEWFORMAT
+ DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2);
#endif
#ifdef ENABLE_PAGING
- switch(ti->shared_ram_paging) {
- case 0xf:
- break;
- case 0xe:
- ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
- pg_size=32; /* 16KB page size */
- break;
- case 0xd:
- ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
- pg_size=64; /* 32KB page size */
- break;
- case 0xc:
- ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
- ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
- DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n");
- /* nb/dwm: I did this because RRR (3,2) bits are documented as
- * R/O and I can't find how to select which page size
- * Also, the above conditional statement sequence is invalid
- * as page_mask will always be set by the second stmt
- */
- badti=ti;
- break;
- default:
- DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging);
- badti=ti; /* bail out if bad code */
- break;
- }
- if(ti->page_mask) {
- if(pg_size > ti->mapped_ram_size) {
- DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n",
- pg_size, ti->mapped_ram_size);
- ti->page_mask = 0; /* reset paging */
- } else {
- ti->mapped_ram_size=ti->avail_shared_ram; /****** ?????????? *******/
- DPRINTK("Shared RAM paging enabled. Page size : %uK\n",((ti->page_mask^ 0xff)+1)>>2);
- }
- }
-#else
-#endif
- }
-
- if (cardpresent==TR_ISA) { /* finish figuring the shared RAM address */
- static unsigned char ram_bndry_mask[]={0xfe, 0xfc, 0xf8, 0xf0};
- unsigned char new_base, rrr_32, chk_base, rbm;
- rrr_32 = (*(unsigned char *)
- (ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2;
- rbm = ram_bndry_mask[rrr_32];
- new_base = (Shared_Ram_Base + (~rbm)) & rbm; /* up to boundary */
- chk_base = new_base + (ti->mapped_ram_size>>3);
- if (chk_base > (IBMTR_SHARED_RAM_BASE+IBMTR_SHARED_RAM_SIZE)) {
- DPRINTK("Shared RAM for this adapter (%05x) exceeds driver"
- " limit (%05x), adapter not started.\n",
- chk_base<<12, (IBMTR_SHARED_RAM_BASE+
- IBMTR_SHARED_RAM_SIZE)<<12);
- badti=ti;
- } else { /* seems cool, record what we have figured out */
- ti->sram_base = new_base;
- Shared_Ram_Base = new_base;
- }
- }
-
- /* dwm: irq and other final setup moved here so if we find other
- unrecognized values OR shared ram conflicts, we can still
- bail out in a rather benign fashion. */
-
- if (badti) return ENODEV;
-#ifndef TR_NEWFORMAT
- DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);
+ switch(ti->shared_ram_paging) {
+ case 0xf:
+ break;
+ case 0xe:
+ ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
+ pg_size=32; /* 16KB page size */
+ break;
+ case 0xd:
+ ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
+ pg_size=64; /* 32KB page size */
+ break;
+ case 0xc:
+ ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
+ ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
+ DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n");
+ /* nb/dwm: I did this because RRR (3,2) bits are documented as
+ R/O and I can't find how to select which page size
+ Also, the above conditional statement sequence is invalid
+ as page_mask will always be set by the second stmt */
+ badti=ti;
+ break;
+ default:
+ DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging);
+ badti=ti; /* bail out if bad code */
+ break;
+ }
+ if (ti->page_mask) {
+ if (pg_size > ti->mapped_ram_size) {
+ DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n",
+ pg_size, ti->mapped_ram_size);
+ ti->page_mask = 0; /* reset paging */
+ } else {
+ ti->mapped_ram_size=ti->avail_shared_ram;
+ DPRINTK("Shared RAM paging enabled. Page size : %uK\n",
+ ((ti->page_mask^ 0xff)+1)>>2);
+ }
#endif
+ }
+
+ /* finish figuring the shared RAM address */
+ if (cardpresent==TR_ISA) {
+ static unsigned char ram_bndry_mask[]={0xfe, 0xfc, 0xf8, 0xf0};
+ unsigned char new_base, rrr_32, chk_base, rbm;
+ rrr_32 = (readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2;
+ rbm = ram_bndry_mask[rrr_32];
+ new_base = (Shared_Ram_Base + (~rbm)) & rbm; /* up to boundary */
+ chk_base = new_base + (ti->mapped_ram_size>>3);
+ if (chk_base > (IBMTR_SHARED_RAM_BASE+IBMTR_SHARED_RAM_SIZE)) {
+ DPRINTK("Shared RAM for this adapter (%05x) exceeds driver"
+ " limit (%05x), adapter not started.\n",
+ chk_base<<12, (IBMTR_SHARED_RAM_BASE+
+ IBMTR_SHARED_RAM_SIZE)<<12);
+ badti=ti;
+ } else { /* seems cool, record what we have figured out */
+ ti->sram_base = new_base;
+ Shared_Ram_Base = new_base;
+ }
+ }
- if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR", NULL) != 0) {
- DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n",irq);
- badti = ti; /* keep track of unused tok_info */
- return ENODEV;
- }
- irq2dev_map[irq]=dev;
+ /* dwm: irq and other final setup moved here so if we find other
+ unrecognized values OR shared ram conflicts, we can still
+ bail out in a rather benign fashion. */
- /*?? Now, allocate some of the PIO PORTs for this driver.. */
- request_region(PIOaddr,TR_IO_EXTENT,"ibmtr"); /* record PIOaddr range
- as busy */
-#ifndef TR_NEWFORMAT
- DPRINTK("%s",version); /* As we have passed card identification,
- let the world know we're here! */
-#else
- printk("%s",version);
- DPRINTK("%s %s found using irq %d, PIOaddr %4hx, %dK shared RAM.\n",
- channel_def[cardpresent-1], adapter_def(ti->adapter_type), irq,
- PIOaddr, ti->mapped_ram_size/2);
- DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n",
- dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
- dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+ if (badti) return ENODEV;
+#if !TR_NEWFORMAT
+ DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);
#endif
- dev->base_addr=PIOaddr; /* set the value for device */
-
- trdev_init(dev);
- tok_init_card(dev);
+ if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR", NULL) != 0) {
+ DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n",irq);
+ badti = ti; /* keep track of unused tok_info */
+ return ENODEV;
+ }
+ irq2dev_map[irq]=dev;
+
+ /*?? Now, allocate some of the PIO PORTs for this driver.. */
+ request_region(PIOaddr,TR_IO_EXTENT,"ibmtr"); /* record PIOaddr range
+ as busy */
+#if !TR_NEWFORMAT
+ DPRINTK("%s",version); /* As we have passed card identification,
+ let the world know we're here! */
+#else
+ printk("%s",version);
+ DPRINTK("%s %s found using irq %d, PIOaddr %4hx, %dK shared RAM.\n",
+ channel_def[cardpresent-1], adapter_def(ti->adapter_type), irq,
+ PIOaddr, ti->mapped_ram_size/2);
+ DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n",
+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+#endif
- return 0; /* Return 0 to indicate we have found a Token Ring card. */
+ dev->base_addr=PIOaddr; /* set the value for device */
+
+ dev->open=tok_open;
+ dev->stop=tok_close;
+ dev->hard_start_xmit=tok_send_packet;
+ dev->get_stats = NULL;
+ dev->get_stats = tok_get_stats;
+ dev->set_multicast_list = NULL;
+ tr_setup(dev);
+ tok_init_card((unsigned long)dev);
+
+ return 0; /* Return 0 to indicate we have found a Token Ring card. */
}
/* query the adapter for the size of shared RAM */
-unsigned char get_sram_size(struct tok_info *adapt_info) {
-
+unsigned char get_sram_size(struct tok_info *adapt_info)
+{
+
unsigned char avail_sram_code;
static unsigned char size_code[]={ 0,16,32,64,127,128 };
-
- /* Adapter gives
- 'F' -- use RRR bits 3,2
- 'E' -- 8kb 'D' -- 16kb
- 'C' -- 32kb 'A' -- 64KB
- 'B' - 64KB less 512 bytes at top
- (WARNING ... must zero top bytes in INIT */
-
- avail_sram_code=0xf-*(adapt_info->mmio + AIPAVAILSHRAM);
- if(avail_sram_code)
+
+ /* Adapter gives
+ 'F' -- use RRR bits 3,2
+ 'E' -- 8kb 'D' -- 16kb
+ 'C' -- 32kb 'A' -- 64KB
+ 'B' - 64KB less 512 bytes at top
+ (WARNING ... must zero top bytes in INIT */
+
+ avail_sram_code=0xf-readb(adapt_info->mmio + AIPAVAILSHRAM);
+ if (avail_sram_code)
return size_code[avail_sram_code];
else /* for code 'F', must compute size from RRR(3,2) bits */
-
- return 1<<(((*(unsigned char *)
- (adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2)+4);
+ return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4);
}
-
-int trdev_init(struct device *dev)
+static int tok_open(struct device *dev)
{
- struct tok_info *ti=(struct tok_info *)dev->priv;
-
- ti->open_status=CLOSED;
-
- dev->init=tok_init_card;
- dev->open=tok_open;
- dev->stop=tok_close;
- dev->hard_start_xmit=tok_send_packet;
- dev->get_stats = NULL;
- dev->get_stats = tok_get_stats;
- dev->set_multicast_list = NULL;
- tr_setup(dev);
-
- return 0;
-}
-
-
-static int tok_open(struct device *dev) {
-
- struct tok_info *ti=(struct tok_info *)dev->priv;
-
- if(ti->open_status==CLOSED) {
- tok_init_card(dev);
- }
-
- if(ti->open_status==IN_PROGRESS) {
- sleep_on(&ti->wait_for_reset);
- }
+ struct tok_info *ti=(struct tok_info *)dev->priv;
+
+ if (ti->open_status==CLOSED) tok_init_card((unsigned long)dev);
+
+ if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset);
+
+ if (ti->open_status==SUCCES) {
+ dev->tbusy=0;
+ dev->interrupt=0;
+ dev->start=1;
+ /* NEED to see smem size *AND* reset high 512 bytes if needed */
+
+ MOD_INC_USE_COUNT;
+
+ return 0;
+ } else return -EAGAIN;
- if(ti->open_status==SUCCES) {
- dev->tbusy=0;
- dev->interrupt=0;
- dev->start=1;
- /* NEED to see smem size *AND* reset high 512 bytes if
- needed */
-
- MOD_INC_USE_COUNT;
-
- return 0;
- }
- else
- return -EAGAIN;
-
}
-static int tok_close(struct device *dev) {
-
- struct tok_info *ti=(struct tok_info *) dev->priv;
-
- struct srb_close_adapter *close_adapter=(struct srb_close_adapter *)ti->srb;
-
- close_adapter->command=DIR_CLOSE_ADAPTER;
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
-
- ti->open_status=CLOSED;
-
+static int tok_close(struct device *dev)
+{
+
+ struct tok_info *ti=(struct tok_info *) dev->priv;
+
+ writeb(DIR_CLOSE_ADAPTER,
+ ti->srb + offsetof(struct srb_close_adapter, command));
+ writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+
+ ti->open_status=CLOSED;
+
sleep_on(&ti->wait_for_tok_int);
-
- if(close_adapter->ret_code)
- DPRINTK("close adapter failed: %02X\n",close_adapter->ret_code);
+ if (readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)))
+ DPRINTK("close adapter failed: %02X\n",
+ (int)readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)));
+
MOD_DEC_USE_COUNT;
-
+
return 0;
}
void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
{
-
unsigned char status;
- struct tok_info *ti;
-/* int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); */
- struct device *dev = (struct device *)(irq2dev_map[irq]);
-#if 0
- DPRINTK("Int from tok_driver, dev : %p\n",dev);
-#endif
- ti=(struct tok_info *) dev->priv;
-
- switch (ti->do_tok_int) {
- case NOT_FIRST:
-
- /* Begin the regular interrupt handler HERE inline to avoid
- the extra levels of logic and call depth for the
- original solution. */
-
-
- dev->interrupt=1;
-
- /* Disable interrupts till processing is finished */
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=(~INT_ENABLE);
-
- /* Reset interrupt for ISA boards */
- if(ti->global_int_enable)
- outb(0,ti->global_int_enable);
+ struct tok_info *ti;
+ struct device *dev = (struct device *)(irq2dev_map[irq]);
- status=*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
-
-#ifdef PCMCIA
- /* Check if the PCMCIA card was pulled. */
- if (status == 0xFF)
- {
- DPRINTK("PCMCIA card removed.\n");
- dev->interrupt = 0;
- return;
- }
-
- /* Check ISRP EVEN too. */
- if ( *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) == 0xFF)
- {
- DPRINTK("PCMCIA card removed.\n");
- dev->interrupt = 0;
- return;
- }
+#if TR_VERBOSE
+ DPRINTK("Int from tok_driver, dev : %p\n",dev);
#endif
-
- if(status & ADAP_CHK_INT) {
- int i;
- unsigned char *check_reason=ti->sram + ntohs(*(unsigned short *)(ti->mmio + ACA_OFFSET + ACA_RW +WWCR_EVEN));
-
- DPRINTK("adapter check interrupt\n");
-
- DPRINTK("8 reason bytes follow: ");
- for(i=0;i< 8;i++,check_reason++)
- printk("%02X ",*check_reason);
- printk("\n");
-
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=(~ADAP_CHK_INT);
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
- dev->interrupt=0;
- }
-
- else if((*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)) & (TCR_INT + ERR_INT + ACCESS_INT)) {
-
- DPRINTK("adapter error: ISRP_EVEN : %02x\n",
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN));
+
+ ti=(struct tok_info *) dev->priv;
+
+ switch (ti->do_tok_int) {
+
+ case NOT_FIRST:
+
+ /* Begin the regular interrupt handler HERE inline to avoid
+ the extra levels of logic and call depth for the
+ original solution. */
+
+ dev->interrupt=1;
+
+ /* Disable interrupts till processing is finished */
+ writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+
+ /* Reset interrupt for ISA boards */
+ if (ti->global_int_enable)
+ outb(0, ti->global_int_enable);
+
+ status=readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
+
+ if (status & ADAP_CHK_INT) {
+
+ int i;
+ __u32 check_reason;
+
+ check_reason=ti->mmio + ntohs(readw(ti->mmio + ACA_OFFSET + ACA_RW +WWCR_EVEN));
+
+ DPRINTK("Adapter check interrupt\n");
+ DPRINTK("8 reason bytes follow: ");
+ for(i=0; i<8; i++, check_reason++)
+ printk("%02X ", (int)readb(check_reason));
+ printk("\n");
+
+ writeb((~ADAP_CHK_INT), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+ writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+ dev->interrupt=0;
+
+ } else if (readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)
+ & (TCR_INT | ERR_INT | ACCESS_INT)) {
+
+ DPRINTK("adapter error: ISRP_EVEN : %02x\n",
+ (int)readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN));
+ writeb(~(TCR_INT | ERR_INT | ACCESS_INT),
+ ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+ writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+ dev->interrupt=0;
+
+ } else if (status
+ & (SRB_RESP_INT | ASB_FREE_INT | ARB_CMD_INT | SSB_RESP_INT)) {
+ /* SRB, ASB, ARB or SSB response */
+
+ if (status & SRB_RESP_INT) { /* SRB response */
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=~(TCR_INT + ERR_INT + ACCESS_INT);
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
- dev->interrupt=0;
- }
+ switch(readb(ti->srb)) { /* SRB command check */
- else if(status & (SRB_RESP_INT + ASB_FREE_INT + ARB_CMD_INT + SSB_RESP_INT)) {
-
- if(status & SRB_RESP_INT) {
- switch(*ti->srb) {
- case XMIT_DIR_FRAME: {
- struct srb_xmit *xmit=(struct srb_xmit *)(ti->srb);
- if(xmit->ret_code!=0xff) {
- DPRINTK("error on xmit_dir_frame request: %02X\n",xmit->ret_code);
- if(ti->current_skb) {
- dev_kfree_skb(ti->current_skb, FREE_WRITE);
- ti->current_skb=NULL;
- }
- dev->tbusy=0;
- }
- }
- break;
-
- case XMIT_UI_FRAME: {
- struct srb_xmit *xmit=(struct srb_xmit *)(ti->srb);
- if(xmit->ret_code!=0xff) {
- DPRINTK("error on xmit_ui_frame request: %02X\n",xmit->ret_code);
- if(ti->current_skb) {
- dev_kfree_skb(ti->current_skb, FREE_WRITE);
- ti->current_skb=NULL;
- }
- dev->tbusy=0;
- }
- }
- break;
-
- case DIR_OPEN_ADAPTER: {
- struct srb_open_response *open_response=(struct srb_open_response *)(ti->init_srb);
-
- ti->srb=ti->sram+ntohs(open_response->srb_addr);
- ti->ssb=ti->sram+ntohs(open_response->ssb_addr);
- ti->arb=ti->sram+ntohs(open_response->arb_addr);
- ti->asb=ti->sram+ntohs(open_response->asb_addr);
- ti->current_skb=NULL;
-
- if(open_response->ret_code==7) {
- if(!ti->auto_ringspeedsave && (open_response->error_code==0x24)) {
- DPRINTK("open failed: Adapter speed must match ring speed if Automatic Ring Speed Save is disabled\n");
- ti->open_status=FAILURE;
- wake_up(&ti->wait_for_reset);
- }
- else if(open_response->error_code==0x24)
- DPRINTK("retrying open to adjust to ring speed\n");
-
- else if((open_response->error_code==0x2d) && ti->auto_ringspeedsave)
- DPRINTK("No signal detected for Auto Speed Detection\n");
- else DPRINTK("Unrecoverable error: error code = %02X\n",open_response->error_code);
- }
- else if(!open_response->ret_code) {
-#ifndef TR_NEWFORMAT
- DPRINTK("board opened...\n");
+ case XMIT_DIR_FRAME: {
+ unsigned char xmit_ret_code;
+
+ xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));
+ if (xmit_ret_code != 0xff) {
+ DPRINTK("error on xmit_dir_frame request: %02X\n",
+ xmit_ret_code);
+ if (ti->current_skb) {
+ dev_kfree_skb(ti->current_skb, FREE_WRITE);
+ ti->current_skb=NULL;
+ }
+ dev->tbusy=0;
+ }
+ }
+ break;
+
+ case XMIT_UI_FRAME: {
+ unsigned char xmit_ret_code;
+
+ xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));
+ if (xmit_ret_code != 0xff) {
+ DPRINTK("error on xmit_ui_frame request: %02X\n",
+ xmit_ret_code);
+ if (ti->current_skb) {
+ dev_kfree_skb(ti->current_skb, FREE_WRITE);
+ ti->current_skb=NULL;
+ }
+ dev->tbusy=0;
+ }
+ }
+ break;
+
+ case DIR_OPEN_ADAPTER: {
+ unsigned char open_ret_code;
+ __u16 open_error_code;
+
+ ti->srb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr)));
+ ti->ssb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr)));
+ ti->arb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr)));
+ ti->asb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr)));
+ ti->current_skb=NULL;
+
+ open_ret_code = readb(ti->init_srb +offsetof(struct srb_open_response, ret_code));
+ open_error_code = readw(ti->init_srb +offsetof(struct srb_open_response, error_code));
+
+ if (open_ret_code==7) {
+
+ if (!ti->auto_ringspeedsave && (open_error_code==0x24)) {
+ DPRINTK("open failed: Adapter speed must match ring "
+ "speed if Automatic Ring Speed Save is disabled\n");
+ ti->open_status=FAILURE;
+ wake_up(&ti->wait_for_reset);
+ } else if (open_error_code==0x24)
+ DPRINTK("retrying open to adjust to ring speed\n");
+ else if ((open_error_code==0x2d) && ti->auto_ringspeedsave)
+ DPRINTK("No signal detected for Auto Speed Detection\n");
+ else DPRINTK("Unrecoverable error: error code = %02X\n",
+ open_error_code);
+
+ } else if (!open_ret_code) {
+#if !TR_NEWFORMAT
+ DPRINTK("board opened...\n");
#else
- DPRINTK("Adapter initialized and opened.\n");
+ DPRINTK("Adapter initialized and opened.\n");
#endif
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
- open_sap(EXTENDED_SAP,dev);
-/* YdW probably hates me */
- goto skip_reset;
- }
- else {
- DPRINTK("open failed: ret_code = %02X, retrying\n",open_response->ret_code);
- }
- if(ti->open_status!=FAILURE) {
- tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
- tr_timer.data=(unsigned long)dev;
- tr_timer.next=tr_timer.prev=NULL;
- add_timer(&tr_timer);
- }
- }
- break;
-
- case DIR_CLOSE_ADAPTER:
+ writeb(~(SRB_RESP_INT),
+ ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+ writeb(~(CMD_IN_SRB),
+ ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
+ open_sap(EXTENDED_SAP,dev);
+
+ /* YdW probably hates me */
+ goto skip_reset;
+ } else
+ DPRINTK("open failed: ret_code = %02X, retrying\n",
+ open_ret_code);
+
+ if (ti->open_status != FAILURE) {
+ tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
+ tr_timer.data=(unsigned long)dev;
+ tr_timer.next=tr_timer.prev=NULL;
+ add_timer(&tr_timer);
+ }
+
+ }
+ break;
+
+ case DIR_CLOSE_ADAPTER:
wake_up(&ti->wait_for_tok_int);
break;
- case DLC_OPEN_SAP: {
- struct dlc_open_sap *open_sap=(struct dlc_open_sap *)ti->srb;
- if(open_sap->ret_code) {
- DPRINTK("open_sap failed: ret_code = %02X,retrying\n",open_sap->ret_code);
+
+ case DLC_OPEN_SAP:
+ if (readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) {
+ DPRINTK("open_sap failed: ret_code = %02X,retrying\n",
+ (int)readb(ti->srb+offsetof(struct dlc_open_sap, ret_code)));
tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
tr_timer.data=(unsigned long)dev;
tr_timer.next=tr_timer.prev=NULL;
add_timer(&tr_timer);
- }
- else {
- ti->exsap_station_id=open_sap->station_id;
+ } else {
+ ti->exsap_station_id=
+ readw(ti->srb+offsetof(struct dlc_open_sap, station_id));
ti->open_status=SUCCES; /* TR adapter is now available */
wake_up(&ti->wait_for_reset);
}
- }
- break;
-
- case DIR_INTERRUPT:
- case DIR_MOD_OPEN_PARAMS:
- case DIR_SET_GRP_ADDR:
- case DIR_SET_FUNC_ADDR:
- case DLC_CLOSE_SAP: {
- struct srb_interrupt *intr=(struct srb_interrupt *)(ti->srb);
- if(intr->ret_code)
- DPRINTK("error on %02X: %02X\n",intr->command,intr->ret_code);
- }
- break;
-
- case DIR_READ_LOG: {
- struct srb_read_log *read_log=(struct srb_read_log *)(ti->srb);
- if(read_log->ret_code)
- DPRINTK("error on dir_read_log: %02X\n",read_log->ret_code);
- else {
- DPRINTK("Line errors %02X, Internal errors %02X, Burst errors %02X\n",
- read_log->line_errors,read_log->internal_errors,read_log->burst_errors);
- DPRINTK("A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n",
- read_log->A_C_errors,read_log->abort_delimiters,read_log->lost_frames);
- DPRINTK("Receive congestion count %02X, Frame copied errors %02X, Frequency errors %02X\n",
- read_log->recv_congest_count,read_log->frame_copied_errors,read_log->frequency_errors);
- DPRINTK("Token errors %02X\n",read_log->token_errors);
- }
+ break;
+
+ case DIR_INTERRUPT:
+ case DIR_MOD_OPEN_PARAMS:
+ case DIR_SET_GRP_ADDR:
+ case DIR_SET_FUNC_ADDR:
+ case DLC_CLOSE_SAP:
+ if (readb(ti->srb+offsetof(struct srb_interrupt, ret_code)))
+ DPRINTK("error on %02X: %02X\n",
+ (int)readb(ti->srb+offsetof(struct srb_interrupt, command)),
+ (int)readb(ti->srb+offsetof(struct srb_interrupt, ret_code)));
+ break;
+
+ case DIR_READ_LOG:
+ if (readb(ti->srb+offsetof(struct srb_read_log, ret_code)))
+ DPRINTK("error on dir_read_log: %02X\n",
+ (int)readb(ti->srb+offsetof(struct srb_read_log, ret_code)));
+ else
+ DPRINTK(
+ "Line errors %02X, Internal errors %02X, Burst errors %02X\n"
+ "A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n"
+ "Receive congestion count %02X, Frame copied errors %02X\n"
+ "Frequency errors %02X, Token errors %02X\n",
+ (int)readb(ti->srb+offsetof(struct srb_read_log,
+ line_errors)),
+ (int)readb(ti->srb+offsetof(struct srb_read_log,
+ internal_errors)),
+ (int)readb(ti->srb+offsetof(struct srb_read_log,
+ burst_errors)),
+ (int)readb(ti->srb+offsetof(struct srb_read_log, A_C_errors)),
+ (int)readb(ti->srb+offsetof(struct srb_read_log,
+ abort_delimiters)),
+ (int)readb(ti->srb+offsetof(struct srb_read_log,
+ lost_frames)),
+ (int)readb(ti->srb+offsetof(struct srb_read_log,
+ recv_congest_count)),
+ (int)readb(ti->srb+offsetof(struct srb_read_log,
+ frame_copied_errors)),
+ (int)readb(ti->srb+offsetof(struct srb_read_log,
+ frequency_errors)),
+ (int)readb(ti->srb+offsetof(struct srb_read_log,
+ token_errors)));
dev->tbusy=0;
- }
- break;
-
- default:
- DPRINTK("Unknown command %02X encountered\n",*(ti->srb));
- }
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
-skip_reset:
- }
-
- if(status & ASB_FREE_INT) {
- switch(*ti->asb) {
- case REC_DATA:
- case XMIT_UI_FRAME:
- case XMIT_DIR_FRAME:
- if(*(ti->asb+2)!=0xff)
- DPRINTK("ASB error %02X in cmd %02X\n", *(ti->asb+2),*(ti->asb));
break;
- default:
- DPRINTK("unknown command in asb %02X\n",*ti->asb);
- }
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(ASB_FREE_INT);
- }
-
- if(status & ARB_CMD_INT) {
- switch(*ti->arb) {
- case DLC_STATUS: {
- struct arb_dlc_status *dlc_status=(struct arb_dlc_status *)(ti->arb);
- DPRINTK("DLC_STATUS new status: %02X on station %02X\n",ntohs(dlc_status->status),ntohs(dlc_status->station_id));
- }
- break;
-
- case REC_DATA:
+
+ default:
+ DPRINTK("Unknown command %02X encountered\n",
+ (int)readb(ti->srb));
+
+ } /* SRB command check */
+
+ writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
+ writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+
+ skip_reset:
+ } /* SRB response */
+
+ if (status & ASB_FREE_INT) { /* ASB response */
+
+ switch(readb(ti->asb)) { /* ASB command check */
+
+ case REC_DATA:
+ case XMIT_UI_FRAME:
+ case XMIT_DIR_FRAME:
+ if (readb(ti->asb+2)!=0xff) /* checks ret_code */
+ DPRINTK("ASB error %02X in cmd %02X\n",
+ (int)readb(ti->asb+2),
+ (int)readb(ti->asb));
+ break;
+
+ default:
+ DPRINTK("unknown command in asb %02X\n",
+ (int)readb(ti->asb));
+
+ } /* ASB command check */
+
+ writeb(~ASB_FREE_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+
+ } /* ASB response */
+
+ if (status & ARB_CMD_INT) { /* ARB response */
+
+ switch (readb(ti->arb)) { /* ARB command check */
+
+ case DLC_STATUS:
+ DPRINTK("DLC_STATUS new status: %02X on station %02X\n",
+ ntohs(readw(ti->arb + offsetof(struct arb_dlc_status, status))),
+ ntohs(readw(ti->arb
+ +offsetof(struct arb_dlc_status, station_id))));
+ break;
+
+ case REC_DATA:
tr_rx(dev);
break;
-
- case RING_STAT_CHANGE: {
- struct arb_ring_stat_change *ring_stat_change=(struct arb_ring_stat_change *)(ti->arb);
- unsigned short ring_status=ntohs(ring_stat_change->ring_status);
-
- if(ring_status & (SIGNAL_LOSS + LOBE_FAULT)) {
- DPRINTK("Signal loss/Lobe fault\n");
- DPRINTK("We try to reopen the adapter.\n");
- tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
- tr_timer.data=(unsigned long)dev;
- tr_timer.next=tr_timer.prev=NULL;
- add_timer(&tr_timer);
- } else if (ring_status & (HARD_ERROR + XMIT_BEACON +
- AUTO_REMOVAL + REMOVE_RECV + RING_RECOVER))
- DPRINTK("New ring status: %02X\n",ring_status);
-
- if(ring_status & LOG_OVERFLOW) {
- *(ti->srb)=DIR_READ_LOG;
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
- dev->tbusy=1; /* really srb busy... */
- }
- }
- break;
-
- case XMIT_DATA_REQ:
+
+ case RING_STAT_CHANGE: {
+ unsigned short ring_status;
+
+ ring_status=ntohs(readw(ti->arb
+ +offsetof(struct arb_ring_stat_change, ring_status)));
+
+ if (ring_status & (SIGNAL_LOSS | LOBE_FAULT)) {
+
+ DPRINTK("Signal loss/Lobe fault\n");
+ DPRINTK("We try to reopen the adapter.\n");
+ tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
+ tr_timer.data=(unsigned long)dev;
+ tr_timer.next=tr_timer.prev=NULL;
+ add_timer(&tr_timer);
+
+ } else if (ring_status & (HARD_ERROR | XMIT_BEACON
+ | AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER))
+ DPRINTK("New ring status: %02X\n", ring_status);
+
+ if (ring_status & LOG_OVERFLOW) {
+
+ writeb(DIR_READ_LOG, ti->srb);
+ writeb(INT_ENABLE,
+ ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+ writeb(CMD_IN_SRB,
+ ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+ dev->tbusy=1; /* really srb busy... */
+
+ }
+ }
+ break;
+
+ case XMIT_DATA_REQ:
tr_tx(dev);
break;
-
- default:
- DPRINTK("Unknown command %02X in arb\n",*(ti->arb));
+
+ default:
+ DPRINTK("Unknown command %02X in arb\n",
+ (int)readb(ti->arb));
break;
- }
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(ARB_CMD_INT);
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=ARB_FREE;
- }
-
- if(status & SSB_RESP_INT) {
- switch(*ti->ssb) {
- case XMIT_DIR_FRAME:
- case XMIT_UI_FRAME:
- if(*(ti->ssb+2))
- DPRINTK("xmit ret_code: %02X xmit error code: %02X\n",*(ti->ssb+2),*(ti->ssb+6));
- else
- ti->tr_stats.tx_packets++;
+
+ } /* ARB command check */
+
+ writeb(~ARB_CMD_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+ writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+
+ } /* ARB response */
+
+ if (status & SSB_RESP_INT) { /* SSB response */
+
+ switch (readb(ti->ssb)) { /* SSB command check */
+
+ case XMIT_DIR_FRAME:
+ case XMIT_UI_FRAME:
+ if (readb(ti->ssb+2)) /* checks ret_code */
+ DPRINTK("xmit ret_code: %02X xmit error code: %02X\n",
+ (int)readb(ti->ssb+2), (int)readb(ti->ssb+6));
+ else ti->tr_stats.tx_packets++;
break;
+
+ case XMIT_XID_CMD:
+ DPRINTK("xmit xid ret_code: %02X\n", (int)readb(ti->ssb+2));
+
+ default:
+ DPRINTK("Unknown command %02X in ssb\n", (int)readb(ti->ssb));
+
+ } /* SSB command check */
- case XMIT_XID_CMD:
- DPRINTK("xmit xid ret_code: %02X\n",*(ti->ssb+2));
+ writeb(~SSB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+ writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- default:
- DPRINTK("Unknown command %02X in ssb\n",*(ti->ssb));
- }
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SSB_RESP_INT);
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=SSB_FREE;
- }
- }
-
- dev->interrupt=0;
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
-
- return;
+ } /* SSB response */
+
+ } /* SRB, ARB, ASB or SSB response */
+
+ dev->interrupt=0;
+ writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+ break;
- break;
- case FIRST_INT:
- initial_tok_int(dev);
- break;
- default:
- DPRINTK("Unexpected interrupt from tr adapter\n");
- }
+ case FIRST_INT:
+ initial_tok_int(dev);
+ break;
+
+ default:
+ DPRINTK("Unexpected interrupt from tr adapter\n");
+ }
}
-static void initial_tok_int(struct device *dev) {
-
-#ifndef TR_NEWFORMAT
- int i;
-#endif
- unsigned char *encoded_addr;
- struct tok_info *ti;
-
- ti=(struct tok_info *) dev->priv;
+static void initial_tok_int(struct device *dev)
+{
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=(~INT_ENABLE);
+ __u32 encoded_addr;
+ __u32 hw_encoded_addr;
+ struct tok_info *ti;
+
+ ti=(struct tok_info *) dev->priv;
+
+ writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
/* Reset interrupt for ISA boards */
- if(ti->global_int_enable)
- outb(0,ti->global_int_enable);
-
+ if (ti->global_int_enable) outb(0,ti->global_int_enable);
+
ti->do_tok_int=NOT_FIRST;
-
+
#ifndef TR_NEWFORMAT
DPRINTK("Initial tok int received\n");
#endif
- if(!ti->sram) { /* we assign the address for ISA devices */
- /* set RRR even to D000 for shared ram address */
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)=
- ti->sram_base;
- ti->sram=(char *)(ti->sram_base << 12);
+ /* we assign the address for ISA devices; set RRR even to D000 for
+ shared RAM address */
+ if(!ti->sram) {
+ writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN);
+ ti->sram=((__u32)ti->sram_base << 12);
+ }
+ ti->init_srb=ti->sram
+ +ntohs((unsigned short)readw(ti->mmio+ ACA_OFFSET + WRBR_EVEN));
+ SET_PAGE(ntohs((unsigned short)readw(ti->mmio+ACA_OFFSET + WRBR_EVEN)));
+
+#if TR_VERBOSE
+ {
+ int i;
+ DPRINTK("init_srb(%p):", ti->init_srb);
+ for (i=0;i<17;i++) printk("%02X ", (int)readb(ti->init_srb+i));
+ printk("\n");
}
- ti->init_srb=ti->sram+ntohs(*(unsigned short *)(ti->mmio+ ACA_OFFSET + WRBR_EVEN));
- SET_PAGE(ntohs(*(unsigned short *)(ti->mmio+ ACA_OFFSET + WRBR_EVEN)));
-
-#if 0
- DPRINTK("init_srb(%p):",ti->init_srb);
- for(i=0;i<17;i++)
- printk("%02X ",*(ti->init_srb+i));
- printk("\n");
#endif
-
-#ifndef TR_NEWFORMAT
- DPRINTK("srb_init_response->encoded_address: %04X\n",((struct srb_init_response *)ti->init_srb)->encoded_address);
- DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address));
+
+ hw_encoded_addr = readw(ti->init_srb
+ + offsetof(struct srb_init_response, encoded_address));
+
+#if !TR_NEWFORMAT
+ DPRINTK("srb_init_response->encoded_address: %04X\n", hw_encoded_addr);
+ DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",
+ ntohs(hw_encoded_addr));
#endif
- encoded_addr=(unsigned char *)(ti->sram + ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address));
-
-#ifndef TR_NEWFORMAT
- DPRINTK("encoded addr (%04X,%04X,%p): ",
- ((struct srb_init_response *)ti->init_srb)->encoded_address,
- ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address),
- encoded_addr);
+
+ encoded_addr=(ti->sram + ntohs(hw_encoded_addr));
+
+#if !TR_NEWFORMAT
+ DPRINTK("encoded addr (%04X,%04X,%08X): ", hw_encoded_addr,
+ ntohs(hw_encoded_addr), encoded_addr);
#else
- DPRINTK("Initial interrupt : shared RAM located at %p.\n", encoded_addr);
-#endif
- ti->auto_ringspeedsave=((struct srb_init_response *)ti->init_srb)->init_status_2 & 0x4 ? TRUE : FALSE;
-
-#ifndef TR_NEWFORMAT
- for(i=0;i<TR_ALEN;i++)
- printk("%02X%s",dev->dev_addr[i]=encoded_addr[i],(i==TR_ALEN-1) ? "" : ":" );
+ DPRINTK("Initial interrupt : shared RAM located at %08X.\n", encoded_addr);
+#endif
+
+ ti->auto_ringspeedsave=readb(ti->init_srb
+ +offsetof(struct srb_init_response, init_status_2)) & 0x4 ? TRUE : FALSE;
+
+#if !TR_NEWFORMAT
+ for(i=0;i<TR_ALEN;i++) {
+ dev->dev_addr[i]=readb(encoded_addr + i);
+ printk("%02X%s", dev->dev_addr[i], (i==TR_ALEN-1) ? "" : ":" );
+ }
printk("\n");
#endif
-
+
tok_open_adapter((unsigned long)dev);
-
}
-static int tok_init_card(struct device *dev) {
-
- struct tok_info *ti;
+static void tok_init_card(unsigned long dev_addr)
+{
+ struct tok_info *ti;
short PIOaddr;
- PIOaddr = dev->base_addr;
- ti=(struct tok_info *) dev->priv;
-
- /* Special processing for first interrupt after reset */
+ int i;
+ struct device *dev=(struct device *)dev_addr;
+ PIOaddr = dev->base_addr;
+ ti=(struct tok_info *) dev->priv;
+
+ /* Special processing for first interrupt after reset */
ti->do_tok_int=FIRST_INT;
-
+
/* Reset adapter */
-
dev->tbusy=1; /* nothing can be done before reset and open completed */
-
+
#ifdef ENABLE_PAGING
- if(ti->page_mask) {
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)=SRPR_ENABLE_PAGING;
- }
+ if(ti->page_mask)
+ writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
#endif
-
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=~(INT_ENABLE);
-#ifndef TR_NEWFORMAT
+
+ writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+
+#if !TR_NEWFORMAT
DPRINTK("resetting card\n");
#endif
- outb(0,PIOaddr+ADAPTRESET);
- udelay(50000);
+
+ outb(0, PIOaddr+ADAPTRESET);
+ for (i=jiffies+TR_RESET_INTERVAL; jiffies<=i;); /* wait 50ms */
outb(0,PIOaddr+ADAPTRESETREL);
-#ifndef TR_NEWFORMAT
+
+#if !TR_NEWFORMAT
DPRINTK("card reset\n");
#endif
-
- ti->open_status=IN_PROGRESS;
-
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
- return 0;
+
+ ti->open_status=IN_PROGRESS;
+ writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+
}
-static void open_sap(unsigned char type,struct device *dev) {
-
- struct tok_info *ti=(struct tok_info *) dev->priv;
- struct dlc_open_sap *open_sap=(struct dlc_open_sap *)ti->srb;
-
+static void open_sap(unsigned char type,struct device *dev)
+{
+ int i;
+ struct tok_info *ti=(struct tok_info *) dev->priv;
+
SET_PAGE(ti->srb);
- memset(open_sap,0,sizeof(struct dlc_open_sap));
-
- open_sap->command=DLC_OPEN_SAP;
- open_sap->max_i_field=htons(MAX_I_FIELD);
- open_sap->sap_options=SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY;
- open_sap->station_count=SAP_OPEN_STATION_CNT;
- open_sap->sap_value=type;
-
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
+ for (i=0; i<sizeof(struct dlc_open_sap); i++)
+ writeb(0, ti->srb+i);
+
+ writeb(DLC_OPEN_SAP, ti->srb + offsetof(struct dlc_open_sap, command));
+ writew(htons(MAX_I_FIELD),
+ ti->srb + offsetof(struct dlc_open_sap, max_i_field));
+ writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY,
+ ti->srb + offsetof(struct dlc_open_sap, sap_options));
+ writeb(SAP_OPEN_STATION_CNT,
+ ti->srb + offsetof(struct dlc_open_sap, station_count));
+ writeb(type, ti->srb + offsetof(struct dlc_open_sap, sap_value));
+
+ writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
}
-void tok_open_adapter(unsigned long dev_addr) {
-
+void tok_open_adapter(unsigned long dev_addr)
+{
+
struct device *dev=(struct device *)dev_addr;
- struct dir_open_adapter *open_adapter;
- struct tok_info *ti;
- ti=(struct tok_info *) dev->priv;
-
-#ifndef TR_NEWFORMAT
+ struct tok_info *ti;
+ int i;
+
+ ti=(struct tok_info *) dev->priv;
+
+#if !TR_NEWFORMAT
DPRINTK("now opening the board...\n");
#endif
-
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
-
- open_adapter=(struct dir_open_adapter *)(ti->init_srb);
- memset(open_adapter,0,sizeof(struct dir_open_adapter));
-
- open_adapter->command=DIR_OPEN_ADAPTER;
- open_adapter->open_options=htons(OPEN_PASS_BCON_MAC);
- open_adapter->num_rcv_buf=htons(NUM_RCV_BUF);
- open_adapter->rcv_buf_len=htons(RCV_BUF_LEN);
- open_adapter->dhb_length=htons(DHB_LENGTH);
- open_adapter->num_dhb=NUM_DHB;
- open_adapter->dlc_max_sap=DLC_MAX_SAP;
- open_adapter->dlc_max_sta=DLC_MAX_STA;
-
+
+ writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+ writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
+
+ for (i=0; i<sizeof(struct dir_open_adapter); i++)
+ writeb(0, ti->init_srb+i);
+
+ writeb(DIR_OPEN_ADAPTER,
+ ti->init_srb + offsetof(struct dir_open_adapter, command));
+ writew(htons(OPEN_PASS_BCON_MAC),
+ ti->init_srb + offsetof(struct dir_open_adapter, open_options));
+ writew(htons(NUM_RCV_BUF),
+ ti->init_srb + offsetof(struct dir_open_adapter, num_rcv_buf));
+ writew(htons(RCV_BUF_LEN),
+ ti->init_srb + offsetof(struct dir_open_adapter, rcv_buf_len));
+ writew(htons(DHB_LENGTH),
+ ti->init_srb + offsetof(struct dir_open_adapter, dhb_length));
+ writeb(NUM_DHB,
+ ti->init_srb + offsetof(struct dir_open_adapter, num_dhb));
+ writeb(DLC_MAX_SAP,
+ ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sap));
+ writeb(DLC_MAX_STA,
+ ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sta));
+
ti->srb=ti->init_srb; /* We use this one in the interrupt handler */
-
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
-
+
+ writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+ writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+
}
-static void tr_tx(struct device *dev) {
-
- struct tok_info *ti=(struct tok_info *) dev->priv;
- struct asb_xmit_resp *xmit_resp=(struct asb_xmit_resp *)ti->asb;
- struct arb_xmit_req *xmit_req=(struct arb_xmit_req *)ti->arb;
- struct srb_xmit *xmit=(struct srb_xmit *)ti->srb;
+static void tr_tx(struct device *dev)
+{
+ struct tok_info *ti=(struct tok_info *) dev->priv;
struct trh_hdr *trhdr=(struct trh_hdr *)ti->current_skb->data;
unsigned int hdr_len;
- unsigned char *dhb;
-
-/* */
- DPRINTD("ti=%p asb=(%p,%p) arb=(%p,%p) srb=(%p,%p)\n",
- ti , ti->asb, xmit_resp, ti->arb, xmit_req, ti->srb, xmit);
-/* */
-
-#if 0
-DPRINTK("transmitting...\n");
-#endif
-
- if(xmit_resp->ret_code!=0xff) DPRINTK("ASB not free !!!\n");
-
- /* in providing the transmit interrupts,
- is telling us it is ready for data and
- providing a shared memory address for us
- to stuff with data. Here we compute the
- effective address where we will place data.*/
- dhb=ti->sram+ntohs(xmit_req->dhb_address);
-
- xmit_resp->command=xmit->command;
- xmit_resp->station_id=xmit_req->station_id;
- xmit_resp->rsap_value=EXTENDED_SAP;
- xmit_resp->cmd_corr=xmit_req->cmd_corr;
- xmit_resp->ret_code=0;
-
- if((xmit->command==XMIT_XID_CMD) || (xmit->command==XMIT_TEST_CMD)) {
- xmit_resp->frame_length=htons(0x11);
- xmit_resp->hdr_length=0x0e;
- dhb[0]=AC;
- dhb[1]=LLC_FRAME;
- memset(dhb+2,(int)0x0ff,TR_ALEN);
- memset(dhb+2+TR_ALEN,0,TR_ALEN);
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET
- + ISRA_ODD)=RESP_IN_ASB;
+ __u32 dhb;
+ unsigned char xmit_command;
+ int i;
+
+ if (readb(ti->asb + offsetof(struct asb_xmit_resp, ret_code))!=0xFF)
+ DPRINTK("ASB not free !!!\n");
+
+ /* in providing the transmit interrupts,
+ is telling us it is ready for data and
+ providing a shared memory address for us
+ to stuff with data. Here we compute the
+ effective address where we will place data.*/
+ dhb=ti->sram
+ +ntohs(readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address)));
+
+ xmit_command = readb(ti->srb + offsetof(struct srb_xmit, command));
+
+ writeb(xmit_command, ti->asb + offsetof(struct asb_xmit_resp, command));
+ writew(readb(ti->srb + offsetof(struct srb_xmit, station_id)),
+ ti->asb + offsetof(struct asb_xmit_resp, station_id));
+ writeb(EXTENDED_SAP, ti->asb + offsetof(struct asb_xmit_resp, rsap_value));
+ writeb(readb(ti->srb + offsetof(struct srb_xmit, cmd_corr)),
+ ti->asb + offsetof(struct asb_xmit_resp, cmd_corr));
+ writeb(0, ti->asb + offsetof(struct asb_xmit_resp, ret_code));
+
+ if ((xmit_command==XMIT_XID_CMD) || (xmit_command==XMIT_TEST_CMD)) {
+
+ writew(htons(0x11),
+ ti->asb + offsetof(struct asb_xmit_resp, frame_length));
+ writeb(0x0e, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
+ writeb(AC, dhb);
+ writeb(LLC_FRAME, dhb+1);
+
+ for (i=0; i<TR_ALEN; i++) writeb((int)0x0FF, dhb+i+2);
+ for (i=0; i<TR_ALEN; i++) writeb(0, dhb+i+TR_ALEN+2);
+
+ writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
return;
+
}
-
- /* the token ring packet is copied from sk_buff to the adapter
- buffer identified in the command data received with the
- interrupt. The sk_buff area was set up with a maximum
- sized route information field so here we must compress
- out the extra (all) rif fields. */
- /* nb/dwm .... I re-arranged code here to avoid copy of extra
- bytes, ended up with fewer statements as well */
-
- /* TR arch. identifies if RIF present by high bit of source
- address. So here we check if RIF present */
- if(!(trhdr->saddr[0] & 0x80)) {
- hdr_len=sizeof(struct trh_hdr)-18;
-#if 0
-DPRINTK(("hdr_length: %d, frame length: %ld\n",hdr_len,
- ti->current_skb->len-18));
-#endif
- } /* TR packet includes RIF data ... preserve it */
- else {
- hdr_len=((ntohs(trhdr->rcf)
- & TR_RCF_LEN_MASK)>>8)+sizeof(struct trh_hdr)-18;
-#if 0
-/* rework the following if activated, hdr_len <> rif_len */
-DPRINTK("rcf: %02X rif_len: %d\n", trhdr->rcf,wrk_len);
-DPRINTK("hdr_length: %d, frame length: %ld\n",sizeof(struct trh_hdr)-18+hdr_len,
- ti->current_skb->len-18+hdr_len);
+
+ /* the token ring packet is copied from sk_buff to the adapter
+ buffer identified in the command data received with the
+ interrupt. The sk_buff area was set up with a maximum
+ sized route information field so here we must compress
+ out the extra (all) rif fields. */
+ /* nb/dwm .... I re-arranged code here to avoid copy of extra
+ bytes, ended up with fewer statements as well. */
+
+ /* TR arch. identifies if RIF present by high bit of source
+ address. So here we check if RIF present */
+
+ if (!(trhdr->saddr[0] & 0x80)) { /* RIF present : preserve it */
+ hdr_len=sizeof(struct trh_hdr)-18;
+
+#if TR_VERBOSE
+ DPRINTK("hdr_length: %d, frame length: %ld\n", hdr_len,
+ ti->current_skb->len-18);
#endif
- }
-
- /* header length including rif is computed above, now move the data
- and set fields appropriately. */
-
- memcpy(dhb,ti->current_skb->data,hdr_len);
- dhb+=hdr_len;
- xmit_resp->hdr_length= hdr_len;
- xmit_resp->frame_length=htons(ti->current_skb->len
- -sizeof(struct trh_hdr)+hdr_len);
-
- /* now copy the actual packet data next to hdr */
- memcpy(dhb,ti->current_skb->data+sizeof(struct trh_hdr),
- ti->current_skb->len-sizeof(struct trh_hdr));
-
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)
- =RESP_IN_ASB;
- dev->tbusy=0;
- dev_kfree_skb(ti->current_skb,FREE_WRITE);
- ti->current_skb=NULL;
- mark_bh(NET_BH);
+ } else hdr_len=((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK)>>8)
+ +sizeof(struct trh_hdr)-18;
+
+ /* header length including rif is computed above, now move the data
+ and set fields appropriately. */
+ for (i=0; i<hdr_len; i++)
+ writeb(*(unsigned char *)(ti->current_skb->data +i), dhb++);
+
+ writeb(hdr_len, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
+ writew(htons(ti->current_skb->len-sizeof(struct trh_hdr)+hdr_len),
+ ti->asb + offsetof(struct asb_xmit_resp, frame_length));
+
+ /* now copy the actual packet data next to hdr */
+ for (i=0; i<ti->current_skb->len-sizeof(struct trh_hdr); i++)
+ writeb(*(unsigned char *)(ti->current_skb->data +sizeof(struct trh_hdr)+i),
+ dhb+i);
+
+ writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+ dev->tbusy=0;
+ dev_kfree_skb(ti->current_skb,FREE_WRITE);
+ ti->current_skb=NULL;
+ mark_bh(NET_BH);
}
-static void tr_rx(struct device *dev) {
-
- struct tok_info *ti=(struct tok_info *) dev->priv;
-
- struct arb_rec_req *rec_req=(struct arb_rec_req *)ti->arb;
- struct asb_rec *rec_resp=(struct asb_rec *)ti->asb;
- struct rec_buf *rbuffer;
- struct trllc *llc;
+static void tr_rx(struct device *dev)
+{
+ int i;
+ struct tok_info *ti=(struct tok_info *) dev->priv;
+ __u32 rbuffer;
+ __u32 llc;
unsigned char *data;
- unsigned int rbuffer_len,lan_hdr_len;
+ unsigned int rbuffer_len, lan_hdr_len;
+ unsigned int arb_frame_len;
struct sk_buff *skb;
-
- rbuffer=(struct rec_buf *)(ti->sram+ntohs(rec_req->rec_buf_addr));
-
- if(rec_resp->ret_code!=0xff) DPRINTK("ASB not free !!!\n");
-
- rec_resp->command=REC_DATA;
- rec_resp->station_id=rec_req->station_id;
- rec_resp->rec_buf_addr=rec_req->rec_buf_addr;
-
- lan_hdr_len=rec_req->lan_hdr_len;
-
- llc=(struct trllc *)((unsigned char *)rbuffer+offsetof(struct rec_buf,data)+lan_hdr_len);
-
-#if 0
-DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",offsetof(struct rec_buf,data),lan_hdr_len);
-DPRINTK("llc: %p rec_buf_addr: %04X ti->sram: %p\n",llc,ntohs(rec_req->rec_buf_addr),ti->sram);
-DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, ethertype: %04X\n",
- llc->dsap,llc->ssap,llc->llc,llc->protid[0],llc->protid[1],llc->protid[2],llc->ethertype);
-#endif
-
- if(llc->llc!=UI_CMD) {
-#ifndef TR_FILTERNONUI
- DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",llc->llc);
-#endif
- rec_resp->ret_code=DATA_LOST;
- ti->tr_stats.rx_dropped++;
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
- return;
- }
-
-#if 0
- if((llc->dsap!=0xaa) || (llc->ssap!=0xaa)) {
-
- struct trh_hdr *trhdr=(struct trh_hdr *)((unsigned char *)rbuffer+offsetof(struct rec_buf,data));
-
-DPRINTK("Probably non-IP frame received.\n");
-DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
- llc->ssap,llc->dsap,trhdr->saddr[0],trhdr->saddr[1],trhdr->saddr[2],trhdr->saddr[3],trhdr->saddr[4],trhdr->saddr[5],
- trhdr->daddr[0],trhdr->daddr[1],trhdr->daddr[2],trhdr->daddr[3],trhdr->daddr[4],trhdr->daddr[5]);
- }
+
+ rbuffer=(ti->sram
+ +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))));
+
+ if(readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF)
+ DPRINTK("ASB not free !!!\n");
+
+ writeb(REC_DATA,
+ ti->asb + offsetof(struct asb_rec, command));
+ writew(readw(ti->arb + offsetof(struct arb_rec_req, station_id)),
+ ti->asb + offsetof(struct asb_rec, station_id));
+ writew(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr)),
+ ti->asb + offsetof(struct asb_rec, rec_buf_addr));
+
+ lan_hdr_len=readb(ti->arb + offsetof(struct arb_rec_req, lan_hdr_len));
+
+ llc=(rbuffer+offsetof(struct rec_buf, data) + lan_hdr_len);
+
+#if TR_VERBOSE
+ DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",
+ (unsigned int)offsetof(struct rec_buf,data), (unsigned int)lan_hdr_len);
+ DPRINTK("llc: %08X rec_buf_addr: %04X ti->sram: %p\n", llc,
+ ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))),
+ ti->sram);
+ DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, "
+ "ethertype: %04X\n",
+ (int)readb(llc + offsetof(struct trllc, dsap)),
+ (int)readb(llc + offsetof(struct trllc, ssap)),
+ (int)readb(llc + offsetof(struct trllc, protid)),
+ (int)readb(llc + offsetof(struct trllc, protid)+1),
+ (int)readb(llc + offsetof(struct trllc, protid)+2),
+ (int)readw(llc + offsetof(struct trllc, ethertype)));
#endif
-
-
- if(!(skb=dev_alloc_skb(ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr)))) {
- DPRINTK("out of memory. frame dropped.\n");
- ti->tr_stats.rx_dropped++;
- rec_resp->ret_code=DATA_LOST;
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
- return;
- }
-
- skb_put(skb,ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr));
- skb->dev=dev;
-
-#if 0
-DPRINTK("Now copying data...\n");
+
+ if (readb(llc + offsetof(struct trllc, llc))!=UI_CMD) {
+#if !TR_FILTERNONUI
+ DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",
+ (int)readb(llc + offsetof(struct trllc, llc))
#endif
-
-
- data=skb->data;
- memcpy(data,&(rbuffer->data),lan_hdr_len);
-
-
- if(lan_hdr_len<sizeof(struct trh_hdr))
- memset(data+lan_hdr_len,0,sizeof(struct trh_hdr)-lan_hdr_len);
-
- data+=sizeof(struct trh_hdr);
- rbuffer_len=ntohs(rbuffer->buf_len)-lan_hdr_len;
-#if 0
-DPRINTK("rbuffer_len: %d, data: %p\n",rbuffer_len,data);
+ writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
+ ti->tr_stats.rx_dropped++;
+ writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+ return;
+ }
+
+#if TR_VERBOSE
+ if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
+ (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
+
+ __u32 trhhdr;
+
+ trhhdr=(rbuffer+offsetof(struct rec_buf,data));
+
+ DPRINTK("Probably non-IP frame received.\n");
+ DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X "
+ "daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ (int)readb(llc + offsetof(struct trllc, ssap)),
+ (int)readb(llc + offsetof(struct trllc, dsap)),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+1),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+2),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+3),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+4),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+5),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+1),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+2),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+3),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+4),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+5));
+ }
#endif
- memcpy(data,(unsigned char *)(&(rbuffer->data))+lan_hdr_len,rbuffer_len);
- data+=rbuffer_len;
-
-
- if(rbuffer->buf_ptr)
- for(rbuffer=(struct rec_buf *)(ti->sram+ntohs(rbuffer->buf_ptr)-2);
- memcpy(data,&(rbuffer->data),rbuffer_len=ntohs(rbuffer->buf_len)),rbuffer->buf_ptr;
- data+=rbuffer_len,rbuffer=(struct rec_buf *)(ti->sram+ntohs(rbuffer->buf_ptr)-2))
-#if 0
- DPRINTK("buf_ptr: %d,data =%p\n",ntohs(rbuffer->buf_ptr),data);
+
+ arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len)));
+
+ if (!(skb=dev_alloc_skb(arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr)))) {
+ DPRINTK("out of memory. frame dropped.\n");
+ ti->tr_stats.rx_dropped++;
+ writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
+ writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+ return;
+ }
+
+ skb_put(skb, arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr));
+ skb->dev=dev;
+
+ data=skb->data;
+ for (i=0; i<lan_hdr_len; i++)
+ data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
+
+ if (lan_hdr_len<sizeof(struct trh_hdr))
+ memset(data+lan_hdr_len, 0, sizeof(struct trh_hdr)-lan_hdr_len);
+
+ data+=sizeof(struct trh_hdr);
+ rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)))
+ -lan_hdr_len;
+
+#if TR_VERBOSE
+ DPRINTK("rbuffer_len: %d, data: %p\n", rbuffer_len, data);
#endif
-
- rec_resp->ret_code=0;
-
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
-
- ti->tr_stats.rx_packets++;
-
- skb->protocol=tr_type_trans(skb,dev);
- netif_rx(skb);
-
- return;
-}
-
-static int tok_send_packet(struct sk_buff *skb, struct device *dev) {
-
- struct tok_info *ti=(struct tok_info *) dev->priv;
-
-#if 0
-DPRINTK("tada: sending packet...\n");
+
+ for (i=0; i<rbuffer_len; i++)
+ data[i]=readb(rbuffer+ offsetof(struct rec_buf, data)+lan_hdr_len+i);
+ data+=rbuffer_len;
+
+ while (readw(rbuffer + offsetof(struct rec_buf, buf_ptr))) {
+ rbuffer=(ti->sram
+ +ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_ptr)))-2);
+ rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)));
+ for (i=0; i<rbuffer_len; i++)
+ data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
+ data+=rbuffer_len;
+
+#if TR_VERBOSE
+ DPRINTK("buf_ptr: %d, data =%p\n",
+ ntohs((rbuffer + offsetof(struct rec_buf, buf_ptr))), data);
#endif
+ }
+
+ writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
+
+ writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+
+ ti->tr_stats.rx_packets++;
+
+ skb->protocol=tr_type_trans(skb,dev);
+ netif_rx(skb);
+
+ }
+static int tok_send_packet(struct sk_buff *skb, struct device *dev)
+{
+ struct tok_info *ti;
+ ti=(struct tok_info *) dev->priv;
+
if (dev->tbusy) {
- int ticks_waited=jiffies - dev->trans_start;
- if(ticks_waited<TX_TIMEOUT)
- return 1;
- DPRINTK("Arrg. Transmitter busy for more than 50 msec. Donald resets adapter, but resetting\n \
-the IBM tokenring adapter takes a long time. It might not even help when the\n \
-ring is very busy, so we just wait a little longer and hope for the best.\n");
+ int ticks_waited;
+
+ ticks_waited=jiffies - dev->trans_start;
+ if (ticks_waited<TR_BUSY_INTERVAL) return 1;
+
+ DPRINTK("Arrg. Transmitter busy for more than 50 msec. "
+ "Donald resets adapter, but resetting\n"
+ "the IBM tokenring adapter takes a long time."
+ " It might not even help when the\n"
+ "ring is very busy, so we just wait a little longer "
+ "and hope for the best.\n");
dev->trans_start+=5; /* we fake the transmission start time... */
return 1;
}
-
+
/* Donald does this, so we do too. */
-
- if(skb==NULL) {
+ if (skb==NULL) {
dev_tint(dev);
return 0;
}
-
- if(set_bit(0,(void *)&dev->tbusy)!=0)
+
+ if (set_bit(0,(void *)&dev->tbusy)!=0)
DPRINTK("Transmitter access conflict\n");
else {
- struct srb_xmit *xmit=(struct srb_xmit *)ti->srb;
-
- ti->current_skb=skb; /* save skb. We will need it when the adapter
- asks for the data */
- xmit->command=XMIT_UI_FRAME;
- xmit->station_id=ti->exsap_station_id;
- *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
+ /* Save skb; we'll need it when the adapter asks for the data */
+ ti->current_skb=skb;
+ writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command));
+ writew(ti->exsap_station_id, ti->srb
+ +offsetof(struct srb_xmit, station_id));
+ writeb(CMD_IN_SRB, (ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD));
dev->trans_start=jiffies;
}
-
+
return 0;
}
/* tok_get_stats(): Basically a scaffold routine which will return
- the address of the tr_statistics structure associated with
- this device -- the tr.... structure is a ethnet look-alike
- so at least for this iteration may suffice. */
+ the address of the tr_statistics structure associated with
+ this device -- the tr.... structure is a ethnet look-alike
+ so at least for this iteration may suffice. */
static struct enet_statistics * tok_get_stats(struct device *dev) {
- struct tok_info *toki;
- toki=(struct tok_info *) dev->priv;
- return (struct enet_statistics *) &toki->tr_stats;
+ struct tok_info *toki;
+ toki=(struct tok_info *) dev->priv;
+ return (struct enet_statistics *) &toki->tr_stats;
}
#ifdef MODULE
+
+
static char devicename[9] = { 0, };
static struct device dev_ibmtr = {
devicename, /* device name is inserted by linux/drivers/net/net_init.c */
int init_module(void)
{
- if (io == 0)
+ if (io == 0)
printk("ibmtr: You should not use auto-probing with insmod!\n");
dev_ibmtr.base_addr = io;
dev_ibmtr.irq = 0;
+
if (register_netdev(&dev_ibmtr) != 0) {
printk("ibmtr: register_netdev() returned non-zero.\n");
return -EIO;
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
unregister_netdev(&dev_ibmtr);
-
+
/* If we don't do this, we can't re-insmod it later. */
free_irq(dev_ibmtr.irq, NULL);
irq2dev_map[dev_ibmtr.irq] = NULL;
/* Definitions for an IBM Token Ring card. */
/* This file is distributed under the GNU GPL */
-#define TR_RETRY_INTERVAL 500
+/* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */
+
+#define TR_RETRY_INTERVAL (5*HZ) /* 500 on PC = 5 s */
+#define TR_RESET_INTERVAL (HZ/20) /* 5 on PC = 50 ms */
+#define TR_BUSY_INTERVAL (HZ/5) /* 5 on PC = 200 ms */
+
#define TR_ISA 1
#define TR_MCA 2
#define TR_ISAPNP 3
#define NOTOK 0
#define TOKDEBUG 1
-/* Mike Eckhoff -- 96/02/08 */
-/* This defines the minimum timeout. If a transmission takes */
-/* longer then TX_TIMEOUT to send, we will wait and retry. */
-/* On large networks, this value may need to be increased. */
-/* We will start at .2s because that is what most drivers seem to be doing */
-/* now and the original value of .05s was not nearly enough for large nets. */
-
-#define TX_TIMEOUT (HZ/5)
-
-
#ifndef IBMTR_SHARED_RAM_BASE
#define IBMTR_SHARED_RAM_BASE 0xD0
#define IBMTR_SHARED_RAM_SIZE 0x10
#define ACA_RW 0x00
#ifdef ENABLE_PAGING
-#define SET_PAGE(x) (*(unsigned char *) \
- (ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)\
- = (x>>8)&ti.page_mask)
+#define SET_PAGE(x) (writeb(((x>>8)&ti.page_mask), \
+ ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN))
#else
#define SET_PAGE(x)
#endif
typedef enum { IN_PROGRESS, SUCCES, FAILURE, CLOSED } open_state;
-struct tok_info {
- unsigned char irq;
- unsigned char *mmio;
- unsigned char hw_address[32];
- unsigned char adapter_type;
- unsigned char data_rate;
- unsigned char token_release;
- unsigned char avail_shared_ram;
- unsigned char shared_ram_paging;
- unsigned char dhb_size4mb;
- unsigned char dhb_size16mb;
-/* Additions by David Morris */
- unsigned char do_tok_int;
+/* do_tok_int possible values */
#define FIRST_INT 1
#define NOT_FIRST 2
- struct wait_queue *wait_for_tok_int;
- struct wait_queue *wait_for_reset;
- unsigned char sram_base;
-/* Additions by Peter De Schrijver */
- unsigned char page_mask; /* mask to select RAM page to Map*/
- unsigned char mapped_ram_size; /* size of RAM page */
- unsigned char *sram; /* Shared memory base address */
- unsigned char *init_srb; /* Initial System Request Block address */
- unsigned char *srb; /* System Request Block address */
- unsigned char *ssb; /* System Status Block address */
- unsigned char *arb; /* Adapter Request Block address */
- unsigned char *asb; /* Adapter Status Block address */
- unsigned short exsap_station_id;
- unsigned short global_int_enable;
- struct sk_buff *current_skb;
- struct tr_statistics tr_stats;
- unsigned char auto_ringspeedsave;
- open_state open_status;
-
-};
-struct srb_init_response {
- unsigned char command;
- unsigned char init_status;
- unsigned char init_status_2;
- unsigned char reserved[3];
- unsigned short bring_up_code;
- unsigned short encoded_address;
- unsigned short level_address;
- unsigned short adapter_address;
- unsigned short parms_address;
- unsigned short mac_address;
-};
-
-#define DIR_OPEN_ADAPTER 0x03
-
-struct dir_open_adapter {
- unsigned char command;
- char reserved[7];
- unsigned short open_options;
- unsigned char node_address[6];
- unsigned char group_address[4];
- unsigned char funct_address[4];
- unsigned short num_rcv_buf;
- unsigned short rcv_buf_len;
- unsigned short dhb_length;
- unsigned char num_dhb;
- char reserved2;
- unsigned char dlc_max_sap;
- unsigned char dlc_max_sta;
- unsigned char dlc_max_gsap;
- unsigned char dlc_max_gmem;
- unsigned char dlc_t1_tick_1;
- unsigned char dlc_t2_tick_1;
- unsigned char dlc_ti_tick_1;
- unsigned char dlc_t1_tick_2;
- unsigned char dlc_t2_tick_2;
- unsigned char dlc_ti_tick_2;
- unsigned char product_id[18];
+struct tok_info {
+ unsigned char irq;
+ __u32 mmio;
+ unsigned char hw_address[32];
+ unsigned char adapter_type;
+ unsigned char data_rate;
+ unsigned char token_release;
+ unsigned char avail_shared_ram;
+ unsigned char shared_ram_paging;
+ unsigned char dhb_size4mb;
+ unsigned char dhb_size16mb;
+ /* Additions by David Morris */
+ unsigned char do_tok_int;
+ struct wait_queue *wait_for_tok_int;
+ struct wait_queue *wait_for_reset;
+ unsigned char sram_base;
+ /* Additions by Peter De Schrijver */
+ unsigned char page_mask; /* mask to select RAM page to Map*/
+ unsigned char mapped_ram_size; /* size of RAM page */
+ __u32 sram; /* Shared memory base address */
+ __u32 init_srb; /* Initial System Request Block address */
+ __u32 srb; /* System Request Block address */
+ __u32 ssb; /* System Status Block address */
+ __u32 arb; /* Adapter Request Block address */
+ __u32 asb; /* Adapter Status Block address */
+ unsigned short exsap_station_id;
+ unsigned short global_int_enable;
+ struct sk_buff *current_skb;
+ struct tr_statistics tr_stats;
+ unsigned char auto_ringspeedsave;
+ open_state open_status;
};
-struct srb_open_response {
- unsigned char command;
- unsigned char reserved1;
- unsigned char ret_code;
- unsigned char reserved2[3];
- unsigned short error_code;
- unsigned short asb_addr;
- unsigned short srb_addr;
- unsigned short arb_addr;
- unsigned short ssb_addr;
-};
+/* token ring adapter commands */
+#define DIR_INTERRUPT 0x00 /* struct srb_interrupt */
+#define DIR_MOD_OPEN_PARAMS 0x01
+#define DIR_OPEN_ADAPTER 0x03 /* struct dir_open_adapter */
+#define DIR_CLOSE_ADAPTER 0x04
+#define DIR_SET_GRP_ADDR 0x06
+#define DIR_SET_FUNC_ADDR 0x07
+#define DIR_READ_LOG 0x08 /* struct srb_read_log */
+#define DLC_OPEN_SAP 0x15 /* struct dlc_open_sap */
+#define DLC_CLOSE_SAP 0x16
+#define DATA_LOST 0x20 /* struct asb_rec */
+#define REC_DATA 0x81 /* struct arb_rec_req */
+#define XMIT_DATA_REQ 0x82 /* struct arb_xmit_req */
+#define DLC_STATUS 0x83 /* struct arb_dlc_status */
+#define RING_STAT_CHANGE 0x84 /* struct dlc_open_sap ??? */
/* DIR_OPEN_ADAPTER options */
-
#define OPEN_PASS_BCON_MAC 0x0100
#define NUM_RCV_BUF 16
#define RCV_BUF_LEN 136
#define DLC_MAX_SAP 2
#define DLC_MAX_STA 1
-#define DLC_OPEN_SAP 0x15
-
-struct dlc_open_sap {
- unsigned char command;
- unsigned char reserved1;
- unsigned char ret_code;
- unsigned char reserved2;
- unsigned short station_id;
- unsigned char timer_t1;
- unsigned char timer_t2;
- unsigned char timer_ti;
- unsigned char maxout;
- unsigned char maxin;
- unsigned char maxout_incr;
- unsigned char max_retry_count;
- unsigned char gsap_max_mem;
- unsigned short max_i_field;
- unsigned char sap_value;
- unsigned char sap_options;
- unsigned char station_count;
- unsigned char sap_gsap_mem;
- unsigned char gsap[0];
-};
-
/* DLC_OPEN_SAP options */
-
#define MAX_I_FIELD 0x0088
#define SAP_OPEN_IND_SAP 0x04
#define SAP_OPEN_PRIORITY 0x20
#define SAP_OPEN_STATION_CNT 0x1
-
-#define XMIT_DIR_FRAME 0x0a
+#define XMIT_DIR_FRAME 0x0A
#define XMIT_UI_FRAME 0x0d
#define XMIT_XID_CMD 0x0e
#define XMIT_TEST_CMD 0x11
+/* srb close return code */
+#define SIGNAL_LOSS 0x8000
+#define HARD_ERROR 0x4000
+#define XMIT_BEACON 0x1000
+#define LOBE_FAULT 0x0800
+#define AUTO_REMOVAL 0x0400
+#define REMOVE_RECV 0x0100
+#define LOG_OVERFLOW 0x0080
+#define RING_RECOVER 0x0020
+
+struct srb_init_response {
+ unsigned char command;
+ unsigned char init_status;
+ unsigned char init_status_2;
+ unsigned char reserved[3];
+ __u16 bring_up_code;
+ __u16 encoded_address;
+ __u16 level_address;
+ __u16 adapter_address;
+ __u16 parms_address;
+ __u16 mac_address;
+};
+
+struct dir_open_adapter {
+ unsigned char command;
+ char reserved[7];
+ __u16 open_options;
+ unsigned char node_address[6];
+ unsigned char group_address[4];
+ unsigned char funct_address[4];
+ __u16 num_rcv_buf;
+ __u16 rcv_buf_len;
+ __u16 dhb_length;
+ unsigned char num_dhb;
+ char reserved2;
+ unsigned char dlc_max_sap;
+ unsigned char dlc_max_sta;
+ unsigned char dlc_max_gsap;
+ unsigned char dlc_max_gmem;
+ unsigned char dlc_t1_tick_1;
+ unsigned char dlc_t2_tick_1;
+ unsigned char dlc_ti_tick_1;
+ unsigned char dlc_t1_tick_2;
+ unsigned char dlc_t2_tick_2;
+ unsigned char dlc_ti_tick_2;
+ unsigned char product_id[18];
+};
+
+struct srb_open_response {
+ unsigned char command;
+ unsigned char reserved1;
+ unsigned char ret_code;
+ unsigned char reserved2[3];
+ __u16 error_code;
+ __u16 asb_addr;
+ __u16 srb_addr;
+ __u16 arb_addr;
+ __u16 ssb_addr;
+};
+
+struct dlc_open_sap {
+ unsigned char command;
+ unsigned char reserved1;
+ unsigned char ret_code;
+ unsigned char reserved2;
+ __u16 station_id;
+ unsigned char timer_t1;
+ unsigned char timer_t2;
+ unsigned char timer_ti;
+ unsigned char maxout;
+ unsigned char maxin;
+ unsigned char maxout_incr;
+ unsigned char max_retry_count;
+ unsigned char gsap_max_mem;
+ __u16 max_i_field;
+ unsigned char sap_value;
+ unsigned char sap_options;
+ unsigned char station_count;
+ unsigned char sap_gsap_mem;
+ unsigned char gsap[0];
+};
+
struct srb_xmit {
- unsigned char command;
- unsigned char cmd_corr;
- unsigned char ret_code;
- unsigned char reserved1;
- unsigned short station_id;
+ unsigned char command;
+ unsigned char cmd_corr;
+ unsigned char ret_code;
+ unsigned char reserved1;
+ __u16 station_id;
};
-#define DIR_INTERRUPT 0x00
struct srb_interrupt {
- unsigned char command;
- unsigned char cmd_corr;
- unsigned char ret_code;
+ unsigned char command;
+ unsigned char cmd_corr;
+ unsigned char ret_code;
};
-#define DIR_READ_LOG 0x08
struct srb_read_log {
- unsigned char command;
- unsigned char reserved1;
- unsigned char ret_code;
- unsigned char reserved2;
- unsigned char line_errors;
- unsigned char internal_errors;
- unsigned char burst_errors;
- unsigned char A_C_errors;
- unsigned char abort_delimiters;
- unsigned char reserved3;
- unsigned char lost_frames;
- unsigned char recv_congest_count;
- unsigned char frame_copied_errors;
- unsigned char frequency_errors;
- unsigned char token_errors;
+ unsigned char command;
+ unsigned char reserved1;
+ unsigned char ret_code;
+ unsigned char reserved2;
+ unsigned char line_errors;
+ unsigned char internal_errors;
+ unsigned char burst_errors;
+ unsigned char A_C_errors;
+ unsigned char abort_delimiters;
+ unsigned char reserved3;
+ unsigned char lost_frames;
+ unsigned char recv_congest_count;
+ unsigned char frame_copied_errors;
+ unsigned char frequency_errors;
+ unsigned char token_errors;
};
struct asb_xmit_resp {
- unsigned char command;
- unsigned char cmd_corr;
- unsigned char ret_code;
- unsigned char reserved;
- unsigned short station_id;
- unsigned short frame_length;
- unsigned char hdr_length;
- unsigned char rsap_value;
+ unsigned char command;
+ unsigned char cmd_corr;
+ unsigned char ret_code;
+ unsigned char reserved;
+ __u16 station_id;
+ __u16 frame_length;
+ unsigned char hdr_length;
+ unsigned char rsap_value;
};
-#define XMIT_DATA_REQ 0x82
struct arb_xmit_req {
- unsigned char command;
- unsigned char cmd_corr;
- unsigned char reserved1[2];
- unsigned short station_id;
- unsigned short dhb_address;
+ unsigned char command;
+ unsigned char cmd_corr;
+ unsigned char reserved1[2];
+ __u16 station_id;
+ __u16 dhb_address;
};
-#define REC_DATA 0x81
struct arb_rec_req {
- unsigned char command;
- unsigned char reserved1[3];
- unsigned short station_id;
- unsigned short rec_buf_addr;
- unsigned char lan_hdr_len;
- unsigned char dlc_hdr_len;
- unsigned short frame_len;
- unsigned char msg_type;
+ unsigned char command;
+ unsigned char reserved1[3];
+ __u16 station_id;
+ __u16 rec_buf_addr;
+ unsigned char lan_hdr_len;
+ unsigned char dlc_hdr_len;
+ __u16 frame_len;
+ unsigned char msg_type;
};
-#define DATA_LOST 0x20
struct asb_rec {
- unsigned char command;
- unsigned char reserved1;
- unsigned char ret_code;
- unsigned char reserved2;
- unsigned short station_id;
- unsigned short rec_buf_addr;
+ unsigned char command;
+ unsigned char reserved1;
+ unsigned char ret_code;
+ unsigned char reserved2;
+ __u16 station_id;
+ __u16 rec_buf_addr;
};
struct rec_buf {
- unsigned char reserved1[2];
- unsigned short buf_ptr;
- unsigned char reserved2;
- unsigned short buf_len;
- unsigned char data[0];
+ unsigned char reserved1[2];
+ __u16 buf_ptr;
+ unsigned char reserved2;
+ __u16 buf_len;
+ unsigned char data[0];
};
-#define DLC_STATUS 0x83
struct arb_dlc_status {
- unsigned char command;
- unsigned char reserved1[3];
- unsigned short station_id;
- unsigned short status;
- unsigned char frmr_data[5];
- unsigned char access_prio;
- unsigned char rem_addr[TR_ALEN];
- unsigned char rsap_value;
+ unsigned char command;
+ unsigned char reserved1[3];
+ __u16 station_id;
+ __u16 status;
+ unsigned char frmr_data[5];
+ unsigned char access_prio;
+ unsigned char rem_addr[TR_ALEN];
+ unsigned char rsap_value;
};
-#define RING_STAT_CHANGE 0x84
struct arb_ring_stat_change {
- unsigned char command;
- unsigned char reserved1[5];
- unsigned short ring_status;
+ unsigned char command;
+ unsigned char reserved1[5];
+ __u16 ring_status;
};
-#define DIR_CLOSE_ADAPTER 0x04
struct srb_close_adapter {
- unsigned char command;
- unsigned char reserved1;
- unsigned char ret_code;
+ unsigned char command;
+ unsigned char reserved1;
+ unsigned char ret_code;
};
-#define DIR_MOD_OPEN_PARAMS 0x01
-#define DIR_SET_GRP_ADDR 0x06
-#define DIR_SET_FUNC_ADDR 0x07
-#define DLC_CLOSE_SAP 0x16
-
-
-#define SIGNAL_LOSS 0x8000
-#define HARD_ERROR 0x4000
-#define XMIT_BEACON 0x1000
-#define LOBE_FAULT 0x0800
-#define AUTO_REMOVAL 0x0400
-#define REMOVE_RECV 0x0100
-#define LOG_OVERFLOW 0x0080
-#define RING_RECOVER 0x0020
-
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/in.h>
-#include <linux/if_ether.h> /* For the statistics structure. */
-#include <linux/if_arp.h> /* For ARPHRD_ETHER */
#include <asm/system.h>
#include <asm/segment.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <net/sock.h>
+#include <linux/if_ether.h> /* For the statistics structure. */
+#include <linux/if_arp.h> /* For ARPHRD_ETHER */
#define LOOPBACK_MTU (PAGE_SIZE*7/8)
skb=skb_clone(skb, GFP_ATOMIC); /* Clone the buffer */
if(skb==NULL)
return 1;
- dev_kfree_skb(skb2, FREE_READ);
+ dev_kfree_skb(skb2, FREE_WRITE);
unlock=0;
}
else if(skb->sk)
* Packet sent but looped back around. Cease to charge
* the socket for the frame.
*/
- skb->sk->wmem_alloc-=skb->truesize;
+ atomic_sub(skb->truesize, &skb->sk->wmem_alloc);
skb->sk->write_space(skb->sk);
}
#include <linux/fs.h>
#include <linux/malloc.h>
#include <linux/if_ether.h>
-#include <linux/if_arp.h>
#include <linux/string.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/trdevice.h>
+#include <linux/if_arp.h>
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
/*
* Push down and install the IPIP header.
*/
- iph = skb->h.iph;
- iph->version = 4;
+
+ iph = skb->h.iph;
+ iph->version = 4;
iph->tos = skb->ip_hdr->tos;
iph->ttl = skb->ip_hdr->ttl;
iph->frag_off = 0;
iph->tot_len = htons(skb->len);
iph->id = htons(ip_id_count++); /* Race condition here? */
ip_send_check(iph);
- skb->ip_hdr = skb->h.iph;
-
+ skb->ip_hdr = skb->h.iph;
+ skb->protocol = htons(ETH_P_IP);
#ifdef TUNNEL_DEBUG
printk("New IP Header....\n");
print_ip(iph);
return 0;
}
-static struct enet_statistics *
-tunnel_get_stats(struct device *dev)
+static struct enet_statistics *tunnel_get_stats(struct device *dev)
{
return((struct enet_statistics*) dev->priv);
}
static int tun_msg=0;
if(!tun_msg)
{
- printk ( KERN_INFO "tunnel: version v0.2b\n" );
+ printk ( KERN_INFO "tunnel: version v0.2b2\n" );
tun_msg=1;
}
return 0;
}
-static struct device dev_tunnel = {
+static struct device dev_tunnel =
+{
"tunl0\0 ",
0, 0, 0, 0,
0x0, 0,
- 0, 0, 0, NULL, tunnel_probe };
+ 0, 0, 0, NULL, tunnel_probe
+ };
int init_module(void)
{
--- /dev/null
+/*
+ * SDLA An implementation of a driver for the Sangoma S502/S508 series
+ * multi-protocol PC interface card. Initial offering is with
+ * the DLCI driver, providing Frame Relay support for linux.
+ *
+ * Global definitions for the Frame relay interface.
+ *
+ * Version: @(#)sdla.c 0.10 23 Mar 1996
+ *
+ * Credits: Sangoma Technologies, for the use of 2 cards for an extended
+ * period of time.
+ * David Mandelstam <dm@sangoma.com> for getting me started on
+ * this project, and incentive to complete it.
+ * Gene Kozen <74604.152@compuserve.com> for providing me with
+ * important information about the cards.
+ *
+ * Author: Mike McLagan <mike.mclagan@linux.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/if_frad.h>
+
+#include <linux/sdla.h>
+
+static const char* version = "SDLA driver v0.10, 23 Mar 1996, mike.mclagan@linux.org";
+
+static const char* devname = "sdla";
+
+static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};
+
+static unsigned int valid_mem[] = {0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
+ 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
+ 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
+ 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
+ 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000};
+
+/*********************************************************
+ *
+ * these are the core routines that access the card itself
+ *
+ *********************************************************/
+
+#define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW)
+
+static void sdla_read(struct device *dev, int addr, void *buf, short len)
+{
+ unsigned long flags;
+ char *temp, *base;
+ int offset, bytes;
+
+ temp = buf;
+ while(len)
+ {
+ offset = addr & 0x1FFF;
+ if (offset + len > 0x2000)
+ bytes = 0x2000 - offset;
+ else
+ bytes = len;
+
+ base = (void *) dev->mem_start;
+ base += offset;
+
+ save_flags(flags);
+ cli();
+ SDLA_WINDOW(dev, addr);
+ memcpy(temp, base, bytes);
+ restore_flags(flags);
+
+ addr += bytes;
+ temp += bytes;
+ len -= bytes;
+ }
+}
+
+static void sdla_write(struct device *dev, int addr, void *buf, short len)
+{
+ unsigned long flags;
+ char *temp, *base;
+ int offset, bytes;
+
+ temp = buf;
+ while(len)
+ {
+ offset = addr & 0x1FFF;
+ if (offset + len > 0x2000)
+ bytes = 0x2000 - offset;
+ else
+ bytes = len;
+
+ base = (void *) dev->mem_start;
+ base += offset;
+
+ save_flags(flags);
+ cli();
+ SDLA_WINDOW(dev, addr);
+ memcpy(base, temp, bytes);
+ restore_flags(flags);
+
+ addr += bytes;
+ temp += bytes;
+ len -= bytes;
+ }
+}
+
+static void sdla_clear(struct device *dev)
+{
+ unsigned long flags;
+ char *base;
+ int offset, len, addr, bytes;
+
+ len = 65536;
+ addr = 0;
+ while(len)
+ {
+ offset = addr & 0x1FFF;
+ if (offset + len > 0x2000)
+ bytes = offset + len - 0x2000;
+ else
+ bytes = len;
+
+ base = (void *) dev->mem_start;
+ base += offset;
+
+ save_flags(flags);
+ cli();
+ SDLA_WINDOW(dev, addr);
+ memset(base, 0, bytes);
+ restore_flags(flags);
+
+ addr += bytes;
+ len -= bytes;
+ }
+}
+
+static char sdla_byte(struct device *dev, int addr)
+{
+ unsigned long flags;
+ char byte, *temp;
+
+ temp = (void *) dev->mem_start;
+ temp += addr & 0x1FFF;
+
+ save_flags(flags);
+ cli();
+ SDLA_WINDOW(dev, addr);
+ byte = *temp;
+ restore_flags(flags);
+
+ return(byte);
+}
+
+void sdla_stop(struct device *dev)
+{
+ struct frad_local *flp;
+
+ flp = dev->priv;
+ switch(flp->type)
+ {
+ case SDLA_S502A:
+ outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
+ flp->state = SDLA_HALT;
+ break;
+ case SDLA_S502E:
+ outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
+ outb(SDLA_S502E_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
+ flp->state = SDLA_S502E_ENABLE;
+ break;
+ case SDLA_S507:
+ flp->state &= ~SDLA_CPUEN;
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+ break;
+ case SDLA_S508:
+ flp->state &= ~SDLA_CPUEN;
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+ break;
+ }
+}
+
+void sdla_start(struct device *dev)
+{
+ struct frad_local *flp;
+
+ flp = dev->priv;
+ switch(flp->type)
+ {
+ case SDLA_S502A:
+ outb(SDLA_S502A_NMI, dev->base_addr + SDLA_REG_CONTROL);
+ outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
+ flp->state = SDLA_S502A_START;
+ break;
+ case SDLA_S502E:
+ outb(SDLA_S502E_CPUEN, dev->base_addr + SDLA_REG_Z80_CONTROL);
+ outb(0x00, dev->base_addr + SDLA_REG_CONTROL);
+ flp->state = 0;
+ break;
+ case SDLA_S507:
+ flp->state |= SDLA_CPUEN;
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+ break;
+ case SDLA_S508:
+ flp->state |= SDLA_CPUEN;
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+ break;
+ }
+}
+
+/****************************************************
+ *
+ * this is used for the S502A/E cards to determine
+ * the speed of the onboard CPU. Calibration is
+ * necessary for the Frame Relay code uploaded
+ * later. Incorrect results cause timing problems
+ * with link checks & status messages
+ *
+ ***************************************************/
+
+int sdla_z80_poll(struct device *dev, int z80_addr, int jiffs, char resp1, char resp2)
+{
+ unsigned long start, done, now;
+ char resp, *temp;
+
+ start = now = jiffies;
+ done = jiffies + jiffs;
+
+ temp = (void *)dev->mem_start;
+ temp += z80_addr & 0x1FFF;
+
+ resp = ~resp1;
+ while ((jiffies < done) && (resp != resp1) && (!resp2 || (resp != resp2)))
+ {
+ if (jiffies != now)
+ {
+ SDLA_WINDOW(dev, z80_addr);
+ now = jiffies;
+ resp = *temp;
+ }
+ }
+ return(jiffies < done ? jiffies - start : -1);
+}
+
+/* constants for Z80 CPU speed */
+#define Z80_READY '1' /* Z80 is ready to begin */
+#define LOADER_READY '2' /* driver is ready to begin */
+#define Z80_SCC_OK '3' /* SCC is on board */
+#define Z80_SCC_BAD '4' /* SCC was not found */
+
+static int sdla_cpuspeed(struct device *dev, struct ifreq *ifr)
+{
+ int jiffs;
+ char data;
+
+ sdla_start(dev);
+ if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0)
+ return(-EIO);
+
+ data = LOADER_READY;
+ sdla_write(dev, 0, &data, 1);
+
+ if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0)
+ return(-EIO);
+
+ sdla_stop(dev);
+ sdla_read(dev, 0, &data, 1);
+
+ if (data == Z80_SCC_BAD)
+ return(-EIO);
+
+ if (data != Z80_SCC_OK)
+ return(-EINVAL);
+
+ if (jiffs < 165)
+ ifr->ifr_mtu = SDLA_CPU_16M;
+ else
+ if (jiffs < 220)
+ ifr->ifr_mtu = SDLA_CPU_10M;
+ else
+ if (jiffs < 258)
+ ifr->ifr_mtu = SDLA_CPU_8M;
+ else
+ if (jiffs < 357)
+ ifr->ifr_mtu = SDLA_CPU_7M;
+ else
+ if (jiffs < 467)
+ ifr->ifr_mtu = SDLA_CPU_5M;
+ else
+ ifr->ifr_mtu = SDLA_CPU_3M;
+
+ return(0);
+}
+
+/************************************************
+ *
+ * Direct interaction with the Frame Relay code
+ * starts here.
+ *
+ ************************************************/
+
+struct _dlci_stat {
+ short dlci __attribute__((packed));
+ char flags __attribute__((packed));
+};
+
+struct _frad_stat {
+ char flags;
+ struct _dlci_stat dlcis[SDLA_MAX_DLCI];
+};
+
+static void sdla_errors(struct device *dev, int cmd, int dlci, int ret, int len, void *data)
+{
+ struct _dlci_stat *pstatus;
+ short *pdlci;
+ int i;
+ char *state;
+
+ switch (ret)
+ {
+ case SDLA_RET_MODEM:
+ state = data;
+ if (*state & SDLA_MODEM_DCD_LOW)
+ printk(KERN_NOTICE "%s: Modem DCD unexpectedly low!\n", dev->name);
+ if (*state & SDLA_MODEM_CTS_LOW)
+ printk(KERN_NOTICE "%s: Modem CTS unexpectedly low!\n", dev->name);
+/* I should probably do something about this! */
+ break;
+
+ case SDLA_RET_CHANNEL_OFF:
+ printk(KERN_NOTICE "%s: Channel became inoperative!\n", dev->name);
+/* same here */
+ break;
+
+ case SDLA_RET_CHANNEL_ON:
+ printk(KERN_NOTICE "%s: Channel became operative!\n", dev->name);
+/* same here */
+ break;
+
+ case SDLA_RET_DLCI_STATUS:
+ printk(KERN_NOTICE "%s: Status change reported by Access Node.\n", dev->name);
+ len /= sizeof(struct _dlci_stat);
+ for(pstatus = data, i=0;i < len;i++,pstatus++)
+ {
+ if (pstatus->flags & SDLA_DLCI_NEW)
+ state = "new";
+ else
+ if (pstatus->flags & SDLA_DLCI_DELETED)
+ state = "deleted";
+ else
+ if (pstatus->flags & SDLA_DLCI_ACTIVE)
+ state = "active";
+ else
+ state = "unknown status";
+
+ printk(KERN_NOTICE "%s: DLCI %i: %s.\n", dev->name, pstatus->dlci, state);
+/* same here */
+ }
+ break;
+
+ case SDLA_RET_DLCI_UNKNOWN:
+ printk(KERN_DEBUG "%s: Received unknown DLCIs:", dev->name);
+ len /= 2;
+ for(pdlci = data,i=0;i < len;i++,pdlci++)
+ printk(" %i", *pdlci);
+ printk("\n");
+ break;
+
+ case SDLA_RET_TIMEOUT:
+ printk(KERN_ERR "%s: Command timed out!\n", dev->name);
+ break;
+
+ default:
+ /*
+ * Further processing could be done here
+ * printk(KERN_DEBUG "%s: Unhandled return code 0x%2.2X\n", dev->name, ret);
+ *
+ */
+ }
+}
+
+static int sdla_cmd(struct device *dev, int cmd, short dlci, short flags,
+ void *inbuf, short inlen, void *outbuf, short *outlen)
+{
+ static struct _frad_stat status;
+ struct frad_local *flp;
+ struct sdla_cmd *cmd_buf;
+ unsigned long pflags;
+ int jiffs, ret, waiting, len;
+ long temp, window;
+
+ flp = dev->priv;
+
+ window = flp->type == SDLA_S508 ? SDLA_508_CMD_BUF : SDLA_502_CMD_BUF;
+ temp = (int) dev->mem_start;
+ temp += window & 0x1FFF;
+ cmd_buf = (struct sdla_cmd *)temp;
+ ret = 0;
+ jiffs = jiffies + HZ / 2; /* 1/2 second timeout */
+ save_flags(pflags);
+ cli();
+ SDLA_WINDOW(dev, window);
+ cmd_buf->cmd = cmd;
+ cmd_buf->dlci = dlci;
+ cmd_buf->flags = flags;
+
+ if (inbuf)
+ memcpy(cmd_buf->data, inbuf, inlen);
+
+ cmd_buf->length = inlen;
+
+ cmd_buf->opp_flag = 1;
+ restore_flags(pflags);
+
+ waiting = 1;
+ len = 0;
+ while (waiting && (jiffies <= jiffs))
+ {
+ if (waiting++ % 4)
+ {
+ save_flags(pflags);
+ cli();
+ SDLA_WINDOW(dev, window);
+ waiting = ((volatile)(cmd_buf->opp_flag));
+ restore_flags(pflags);
+ }
+ }
+
+ if (!waiting)
+ {
+ save_flags(pflags);
+ cli();
+ SDLA_WINDOW(dev, window);
+ ret = cmd_buf->retval;
+ len = cmd_buf->length;
+ if (outbuf && len)
+ {
+ *outlen = *outlen >= len ? len : *outlen;
+ memcpy(outbuf, cmd_buf->data, *outlen);
+ }
+ if (ret)
+ memcpy(&status, cmd_buf->data, len);
+ restore_flags(pflags);
+ }
+ else
+ ret = SDLA_RET_TIMEOUT;
+
+ if (ret != SDLA_RET_OK)
+ sdla_errors(dev, cmd, dlci, ret, len, &status);
+
+ return(ret);
+}
+
+/***********************************************
+ *
+ * these functions are called by the DLCI driver
+ *
+ ***********************************************/
+
+static int sdla_reconfig(struct device *dev);
+
+int sdla_activate(struct device *slave, struct device *master)
+{
+ struct frad_local *flp;
+ int i;
+
+ flp = slave->priv;
+
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->master[i] == master)
+ break;
+
+ if (i == CONFIG_DLCI_MAX)
+ return(-ENODEV);
+
+ flp->dlci[i] = abs(flp->dlci[i]);
+
+ if (slave->start && (flp->config.station == FRAD_STATION_NODE))
+ sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
+
+ return(0);
+}
+
+int sdla_deactivate(struct device *slave, struct device *master)
+{
+ struct frad_local *flp;
+ int i;
+
+ flp = slave->priv;
+
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->master[i] == master)
+ break;
+
+ flp->dlci[i] = -abs(flp->dlci[i]);
+
+ if (slave->start && (flp->config.station == FRAD_STATION_NODE))
+ sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
+
+ return(0);
+}
+
+int sdla_assoc(struct device *slave, struct device *master)
+{
+ struct frad_local *flp;
+ int i;
+
+ if (master->type != ARPHRD_DLCI)
+ return(-EINVAL);
+
+ flp = slave->priv;
+
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ {
+ if (!flp->master[i])
+ break;
+ if (abs(flp->dlci[i]) == *(short *)(master->dev_addr))
+ return(-EADDRINUSE);
+ }
+
+ if (i == CONFIG_DLCI_MAX)
+ return(-EMLINK); /* #### Alan: Comments on this ?? */
+
+ MOD_INC_USE_COUNT;
+
+ flp->master[i] = master;
+ flp->dlci[i] = -*(short *)(master->dev_addr);
+ master->mtu = slave->mtu;
+
+ if (slave->start)
+ if (flp->config.station == FRAD_STATION_CPE)
+ sdla_reconfig(slave);
+ else
+ sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
+
+ return(0);
+}
+
+int sdla_deassoc(struct device *slave, struct device *master)
+{
+ struct frad_local *flp;
+ int i;
+
+ flp = slave->priv;
+
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->master[i] == master)
+ break;
+
+ if (i == CONFIG_DLCI_MAX)
+ return(-ENODEV);
+
+ flp->master[i] = NULL;
+ flp->dlci[i] = 0;
+
+ MOD_DEC_USE_COUNT;
+
+ if (slave->start)
+ if (flp->config.station == FRAD_STATION_CPE)
+ sdla_reconfig(slave);
+ else
+ sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
+
+ return(0);
+}
+
+int sdla_dlci_conf(struct device *slave, struct device *master, int get)
+{
+ struct frad_local *flp;
+ struct frad_local *dlp;
+ int i;
+
+ flp = slave->priv;
+
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->master[i] == master)
+ break;
+
+ if (i == CONFIG_DLCI_MAX)
+ return(-ENODEV);
+
+ dlp = master->priv;
+ if (slave->start)
+ sdla_cmd(slave, SDLA_SET_DLCI_CONFIGURATION, flp->dlci[i], 0,
+ &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL);
+
+ return(0);
+}
+
+/**************************
+ *
+ * now for the Linux driver
+ *
+ **************************/
+
+static int sdla_transmit(struct sk_buff *skb, struct device *dev)
+{
+ struct frad_local *flp;
+ int ret, addr;
+ short size;
+ unsigned long flags;
+ struct buf_entry *pbuf;
+
+ flp = dev->priv;
+ ret = 0;
+
+ if (dev->tbusy)
+ return(1);
+
+ if (skb == NULL)
+ return(0);
+
+ if (set_bit(0, (void*)&dev->tbusy) != 0)
+ printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
+ else
+ {
+ switch (flp->type)
+ {
+ case SDLA_S502A:
+ case SDLA_S502E:
+ ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL);
+ break;
+
+ case SDLA_S508:
+ size = sizeof(addr);
+ ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
+ if (ret == SDLA_RET_OK)
+ {
+ save_flags(flags);
+ cli();
+ SDLA_WINDOW(dev, addr);
+ pbuf = (void *)(((int) dev->mem_start) + (addr & 0x1FFF));
+
+ sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
+
+ SDLA_WINDOW(dev, addr);
+ pbuf->opp_flag = 1;
+ restore_flags(flags);
+ }
+ break;
+ }
+
+ switch (ret)
+ {
+ case SDLA_RET_OK:
+ flp->stats.tx_packets++;
+ ret = 0;
+ break;
+
+ default:
+ flp->stats.tx_errors++;
+ ret = 1;
+ }
+
+ /* per Alan Cox, we can drop the packet on the floor if it doesn't go */
+ dev_kfree_skb(skb, FREE_WRITE);
+
+ dev->tbusy = 0;
+ }
+ return(ret);
+}
+
+static void sdla_receive(struct device *dev)
+{
+ struct device *master;
+ struct frad_local *flp;
+ struct dlci_local *dlp;
+ struct sk_buff *skb;
+
+ struct sdla_cmd *cmd;
+ struct buf_info *pbufi;
+ struct buf_entry *pbuf;
+
+ unsigned long flags;
+ int i, received, success, addr;
+ short dlci, len, split;
+ char bogus;
+
+ flp = dev->priv;
+ bogus = 0;
+ success = 0;
+ received = 0;
+ addr = 0;
+ skb = NULL;
+ master = NULL;
+
+ save_flags(flags);
+ cli();
+
+ switch (flp->type)
+ {
+ case SDLA_S502A:
+ case SDLA_S502E:
+ cmd = (void *) (dev->mem_start + (SDLA_502_RCV_BUF & 0x1FFF));
+ SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
+ if (!cmd->opp_flag)
+ break;
+
+ dlci = cmd->dlci;
+ len = cmd->length;
+
+ for (i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->dlci[i] == dlci)
+ break;
+
+ if (i == CONFIG_DLCI_MAX)
+ {
+ printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci);
+ flp->stats.rx_errors++;
+ cmd->opp_flag = 0;
+ break;
+ }
+
+ master = flp->master[i];
+ skb = dev_alloc_skb(len);
+ if (skb == NULL)
+ {
+ printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
+ flp->stats.rx_dropped++;
+ cmd->opp_flag = 0;
+ break;
+ }
+
+ /* pick up the data */
+ sdla_read(dev, dev->mem_start + ((SDLA_502_RCV_BUF + SDLA_502_DATA_OFS) & 0x1FFF), skb_put(skb,len), len);
+ cmd->opp_flag = 0;
+ success = 1;
+ break;
+
+ case SDLA_S508:
+ pbufi = (void *) (dev->mem_start + (SDLA_508_RXBUF_INFO & 0x1FFF));
+ SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
+ pbuf = (void *) (dev->mem_start + ((pbufi->rse_base + flp->buffer * sizeof(struct buf_entry)) & 0x1FFF));
+ if (!pbuf->opp_flag)
+ break;
+
+ dlci = pbuf->dlci;
+ len = pbuf->length;
+ addr = pbuf->buf_addr;
+
+ for (i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->dlci[i] == dlci)
+ break;
+
+ if (i == CONFIG_DLCI_MAX)
+ {
+ printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci);
+ flp->stats.rx_errors++;
+ pbuf->opp_flag = 0;
+ break;
+ }
+
+ master = flp->master[i];
+ skb = dev_alloc_skb(len);
+ if (skb == NULL)
+ {
+ printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
+ flp->stats.rx_dropped++;
+ pbuf->opp_flag = 0;
+ break;
+ }
+
+ /* is this buffer split off the end of the internal ring buffer */
+ split = addr + len > pbufi->buf_top + 1 ? pbufi->buf_top - addr + 1 : 0;
+ len -= split;
+
+ /* lets get the data */
+ sdla_read(dev, addr, skb_put(skb, len), len);
+ if (split)
+ {
+ SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
+ sdla_read(dev, pbufi->buf_base, skb_put(skb, split), split);
+ }
+
+ SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
+ pbuf->opp_flag = 0;
+ success = 1;
+
+ /* increment the buffer we're looking at */
+ flp->buffer = (flp->buffer + 1) % pbufi->rse_num;
+ break;
+ }
+
+ if (success)
+ {
+ flp->stats.rx_packets++;
+ dlp = master->priv;
+ (*dlp->receive)(skb, master);
+ }
+
+ restore_flags(flags);
+}
+
+static void sdla_isr(int irq, void *dev_id, struct pt_regs * regs)
+{
+ struct device *dev;
+ struct frad_local *flp;
+ char byte;
+
+ dev = irq2dev_map[irq];
+
+ if (dev == NULL)
+ {
+ printk(KERN_WARNING "sdla_isr(): irq %d for unknown device.\n", irq);
+ return;
+ }
+
+ flp = dev->priv;
+
+ if (!flp->initialized)
+ {
+ printk(KERN_WARNING "%s: irq %d for unintialiazed device.\n", dev->name, irq);
+ return;
+ }
+
+ dev->interrupt = 1;
+ byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE);
+ switch (byte)
+ {
+ case SDLA_INTR_RX:
+ sdla_receive(dev);
+ break;
+
+ /* the command will get an error return, which is processed above */
+ case SDLA_INTR_MODEM:
+ case SDLA_INTR_STATUS:
+ sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL);
+ break;
+
+ case SDLA_INTR_TX:
+ case SDLA_INTR_COMPLETE:
+ case SDLA_INTR_TIMER:
+ printk(KERN_WARNING "%s: invalid irq flag 0x%02X.\n", dev->name, byte);
+ break;
+ }
+
+ /* the S502E requires a manual acknowledgement of the interrupt */
+ if (flp->type == SDLA_S502E)
+ {
+ flp->state &= ~SDLA_S502E_INTACK;
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+ flp->state |= SDLA_S502E_INTACK;
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+ }
+
+ dev->interrupt = 0;
+ /* this clears the byte, informing the Z80 we're done */
+ byte = 0;
+ sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
+}
+
+static void sdla_poll(unsigned long device)
+{
+ struct device *dev;
+ struct frad_local *flp;
+
+ dev = (struct device *) device;
+ flp = dev->priv;
+
+ if (sdla_byte(dev, SDLA_502_RCV_BUF))
+ sdla_receive(dev);
+
+ flp->timer.expires = 1;
+ add_timer(&flp->timer);
+}
+
+static int sdla_close(struct device *dev)
+{
+ struct frad_local *flp;
+ struct intr_info intr;
+ int len, i;
+ short dlcis[CONFIG_DLCI_MAX];
+
+ flp = dev->priv;
+
+ len = 0;
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->dlci[i])
+ dlcis[len++] = abs(flp->dlci[i]);
+ len *= 2;
+
+ if (flp->config.station == FRAD_STATION_NODE)
+ {
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->dlci[i] > 0)
+ sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL);
+ sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL);
+ }
+
+ memset(&intr, 0, sizeof(intr));
+ /* lets start up the reception */
+ switch(flp->type)
+ {
+ case SDLA_S502A:
+ del_timer(&flp->timer);
+ break;
+
+ case SDLA_S502E:
+ sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
+ flp->state &= ~SDLA_S502E_INTACK;
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+ break;
+
+ case SDLA_S507:
+ break;
+
+ case SDLA_S508:
+ sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
+ flp->state &= ~SDLA_S508_INTEN;
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+ break;
+ }
+
+ sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+ sdla_stop(dev);
+
+ dev->tbusy = 1;
+ dev->start = 0;
+
+ MOD_DEC_USE_COUNT;
+
+ return(0);
+}
+
+struct conf_data {
+ struct frad_conf config;
+ short dlci[CONFIG_DLCI_MAX];
+};
+
+static int sdla_open(struct device *dev)
+{
+ struct frad_local *flp;
+ struct dlci_local *dlp;
+ struct conf_data data;
+ struct intr_info intr;
+ int len, i;
+ char byte;
+
+ flp = dev->priv;
+
+ if (!flp->initialized)
+ return(-EPERM);
+
+ if (!flp->configured)
+ return(-EPERM);
+
+ /* off to the races! */
+ sdla_start(dev);
+
+ /* time to send in the configuration */
+ len = 0;
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->dlci[i])
+ data.dlci[len++] = abs(flp->dlci[i]);
+ len *= 2;
+
+ memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
+ len += sizeof(struct frad_conf);
+
+ sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+ sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
+
+ if (flp->type == SDLA_S508)
+ flp->buffer = 0;
+
+ sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+
+ /* lets start up the reception */
+ memset(&intr, 0, sizeof(intr));
+ switch(flp->type)
+ {
+ case SDLA_S502A:
+ flp->timer.expires = 1;
+ add_timer(&flp->timer);
+ break;
+
+ case SDLA_S502E:
+ flp->state |= SDLA_S502E_ENABLE;
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+ flp->state |= SDLA_S502E_INTACK;
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+ byte = 0;
+ sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
+ intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
+ sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
+ break;
+
+ case SDLA_S507:
+ break;
+
+ case SDLA_S508:
+ flp->state |= SDLA_S508_INTEN;
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+ byte = 0;
+ sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte));
+ intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
+ intr.irq = dev->irq;
+ sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
+ break;
+ }
+
+ if (flp->config.station == FRAD_STATION_CPE)
+ {
+ byte = SDLA_ICS_STATUS_ENQ;
+ sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL);
+ }
+ else
+ {
+ sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL);
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->dlci[i] > 0)
+ sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL);
+ }
+
+ /* configure any specific DLCI settings */
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->dlci[i])
+ {
+ dlp = flp->master[i]->priv;
+ if (dlp->configured)
+ sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
+ }
+
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+
+ MOD_INC_USE_COUNT;
+
+ return(0);
+}
+
+static int sdla_config(struct device *dev, struct frad_conf *conf, int get)
+{
+ struct frad_local *flp;
+ struct conf_data data;
+ int i, err;
+
+ if (dev->type == 0xFFFF)
+ return(-EUNATCH);
+
+ flp = dev->priv;
+
+ if (!get)
+ {
+ if (dev->start)
+ return(-EBUSY);
+
+ err = verify_area(VERIFY_READ, conf, sizeof(struct frad_conf));
+ if (err)
+ return(err);
+
+ memcpy_fromfs(&data.config, conf, sizeof(struct frad_conf));
+
+ if (data.config.station & ~FRAD_STATION_NODE)
+ return(-EINVAL);
+
+ if (data.config.flags & ~FRAD_VALID_FLAGS)
+ return(-EINVAL);
+
+ if ((data.config.kbaud < 0) ||
+ ((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
+ return(-EINVAL);
+
+ if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
+ return(-EINVAL);
+
+ if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
+ return(-EINVAL);
+
+ if ((data.config.T391 < 5) || (data.config.T391 > 30))
+ return(-EINVAL);
+
+ if ((data.config.T392 < 5) || (data.config.T392 > 30))
+ return(-EINVAL);
+
+ if ((data.config.N391 < 1) || (data.config.N391 > 255))
+ return(-EINVAL);
+
+ if ((data.config.N392 < 1) || (data.config.N392 > 10))
+ return(-EINVAL);
+
+ if ((data.config.N393 < 1) || (data.config.N393 > 10))
+ return(-EINVAL);
+
+ memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
+ flp->config.flags |= SDLA_DIRECT_RECV;
+
+ if (dev->mtu != flp->config.mtu)
+ {
+ /* this is required to change the MTU */
+ dev->mtu = flp->config.mtu;
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->master[i])
+ flp->master[i]->mtu = flp->config.mtu;
+ }
+
+ flp->config.mtu += sizeof(struct fradhdr);
+ flp->configured = 1;
+ }
+ else
+ {
+ err = verify_area(VERIFY_WRITE, conf, sizeof(struct frad_conf));
+ if (err)
+ return(err);
+
+ sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, &data, sizeof(data), NULL, NULL);
+ memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
+
+ data.config.flags &= ~SDLA_DIRECT_RECV;
+ data.config.mtu -= sizeof(struct fradhdr);
+ memcpy_tofs(conf, &data.config, sizeof(struct frad_conf));
+ }
+
+ return(0);
+}
+
+static int sdla_xfer(struct device *dev, struct sdla_mem *info, int read)
+{
+ struct sdla_mem mem;
+ int err;
+ char *temp;
+
+ err = verify_area(VERIFY_READ, info, sizeof(struct sdla_mem));
+ if (err)
+ return(err);
+
+ memcpy_fromfs(&mem, info, sizeof(mem));
+ if (read)
+ {
+ err = verify_area(VERIFY_WRITE, mem.data, mem.len);
+ if (err)
+ return(err);
+
+ temp = kmalloc(mem.len, GFP_KERNEL);
+ if (!temp)
+ return(-ENOMEM);
+ sdla_read(dev, mem.addr, temp, mem.len);
+ memcpy_tofs(mem.data, temp, mem.len);
+ kfree(temp);
+ }
+ else
+ {
+ err = verify_area(VERIFY_READ, mem.data, mem.len);
+ if (err)
+ return(err);
+
+ temp = kmalloc(mem.len, GFP_KERNEL);
+ if (!temp)
+ return(-ENOMEM);
+ memcpy_fromfs(temp, mem.data, mem.len);
+ sdla_write(dev, mem.addr, temp, mem.len);
+ kfree(temp);
+ }
+ return(0);
+}
+
+static int sdla_reconfig(struct device *dev)
+{
+ struct frad_local *flp;
+ struct conf_data data;
+ int i, len;
+
+ flp = dev->priv;
+
+ memcpy(&data, &flp->config, sizeof(struct frad_conf));
+
+ len = 0;
+ for(i=0;i<CONFIG_DLCI_MAX;i++)
+ if (flp->dlci[i])
+ data.dlci[len++] = flp->dlci[i];
+ len *= 2;
+ len += sizeof(struct frad_conf);
+
+ sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+ sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
+ sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+
+ return(0);
+}
+
+static int sdla_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
+{
+ struct frad_local *flp;
+
+ flp = dev->priv;
+
+ if (!flp->initialized)
+ return(-EPERM);
+
+ switch (cmd)
+ {
+ case FRAD_GET_CONF:
+ case FRAD_SET_CONF:
+ return(sdla_config(dev, (struct frad_conf *)ifr->ifr_data, cmd == FRAD_GET_CONF));
+
+ case SDLA_IDENTIFY:
+ ifr->ifr_flags = flp->type;
+ break;
+
+ case SDLA_CPUSPEED:
+ return(sdla_cpuspeed(dev, ifr));
+
+/* ==========================================================
+NOTE: This is rather a useless action right now, as the
+ driver does not support protocols other than FR right
+ now. However, Sangoma has modules for a number of
+ other protocols.
+============================================================*/
+ case SDLA_PROTOCOL:
+ if (flp->configured)
+ return(-EALREADY);
+
+ switch (ifr->ifr_flags)
+ {
+ case ARPHRD_FRAD:
+ dev->type = ifr->ifr_flags;
+ dev->family = AF_UNSPEC;
+ break;
+
+ default:
+ return(-ENOPROTOOPT);
+ }
+ break;
+
+ case SDLA_CLEARMEM:
+ sdla_clear(dev);
+ break;
+
+ case SDLA_WRITEMEM:
+ case SDLA_READMEM:
+ return(sdla_xfer(dev, (struct sdla_mem *)ifr->ifr_data, cmd == SDLA_READMEM));
+
+ case SDLA_START:
+ sdla_start(dev);
+ break;
+
+ case SDLA_STOP:
+ sdla_stop(dev);
+ break;
+
+ default:
+ return(-EOPNOTSUPP);
+ }
+ return(0);
+}
+
+int sdla_change_mtu(struct device *dev, int new_mtu)
+{
+ struct frad_local *flp;
+
+ flp = dev->priv;
+
+ if (dev->start)
+ return(-EBUSY);
+
+ /* for now, you can't change the MTU! */
+ return(-EACCES);
+}
+
+int sdla_set_config(struct device *dev, struct ifmap *map)
+{
+ struct frad_local *flp;
+ int i;
+ char byte;
+
+ flp = dev->priv;
+
+ if (flp->initialized)
+ return(-EINVAL);
+
+ for(i=0;i < sizeof(valid_port) / sizeof (int) ; i++)
+ if (valid_port[i] == map->base_addr)
+ break;
+
+ if (i == sizeof(valid_port) / sizeof(int))
+ return(-EINVAL);
+
+ dev->base_addr = map->base_addr;
+ request_region(dev->base_addr, SDLA_IO_EXTENTS, dev->name);
+
+ /* test for card types, S502A, S502E, S507, S508 */
+ /* these tests shut down the card completely, so clear the state */
+ flp->type = SDLA_UNKNOWN;
+ flp->state = 0;
+
+ for(i=1;i<SDLA_IO_EXTENTS;i++)
+ if (inb(dev->base_addr + i) != 0xFF)
+ break;
+
+ if (i == SDLA_IO_EXTENTS)
+ {
+ outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
+ if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x08)
+ {
+ outb(SDLA_S502E_INTACK, dev->base_addr + SDLA_REG_CONTROL);
+ if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x0C)
+ {
+ outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+ flp->type = SDLA_S502E;
+ }
+ }
+ }
+
+ if (flp->type == SDLA_UNKNOWN)
+ {
+ for(byte=inb(dev->base_addr),i=0;i<SDLA_IO_EXTENTS;i++)
+ if (inb(dev->base_addr + i) != byte)
+ break;
+
+ if (i == SDLA_IO_EXTENTS)
+ {
+ outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+ if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x30)
+ {
+ outb(SDLA_S507_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
+ if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x32)
+ {
+ outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+ flp->type = SDLA_S507;
+ }
+ }
+ }
+ }
+
+ if (flp->type == SDLA_UNKNOWN)
+ {
+ outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+ if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x00)
+ {
+ outb(SDLA_S508_INTEN, dev->base_addr + SDLA_REG_CONTROL);
+ if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x10)
+ {
+ outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+ flp->type = SDLA_S508;
+ }
+ }
+ }
+
+ if (flp->type == SDLA_UNKNOWN)
+ {
+ outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
+ if (inb(dev->base_addr + SDLA_S502_STS) == 0x40)
+ {
+ outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
+ if (inb(dev->base_addr + SDLA_S502_STS) == 0x40)
+ {
+ outb(SDLA_S502A_INTEN, dev->base_addr + SDLA_REG_CONTROL);
+ if (inb(dev->base_addr + SDLA_S502_STS) == 0x44)
+ {
+ outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
+ flp->type = SDLA_S502A;
+ }
+ }
+ }
+ }
+
+ if (flp->type == SDLA_UNKNOWN)
+ {
+ printk(KERN_NOTICE "%s: Unknown card type\n", dev->name);
+ return(-ENODEV);
+ }
+
+ switch(dev->base_addr)
+ {
+ case 0x270:
+ case 0x280:
+ case 0x380:
+ case 0x390:
+ if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507))
+ return(-EINVAL);
+ }
+
+ switch (map->irq)
+ {
+ case 2:
+ if (flp->type != SDLA_S502E)
+ return(-EINVAL);
+ break;
+
+ case 10:
+ case 11:
+ case 12:
+ case 15:
+ case 4:
+ if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507))
+ return(-EINVAL);
+
+ case 3:
+ case 5:
+ case 7:
+ if (flp->type == SDLA_S502A)
+ return(-EINVAL);
+ break;
+
+ default:
+ return(-EINVAL);
+ }
+ dev->irq = map->irq;
+
+ if (request_irq(dev->irq, &sdla_isr, 0, dev->name, NULL))
+ return(-EADDRINUSE);
+
+ irq2dev_map[dev->irq] = dev;
+
+ if (flp->type == SDLA_S507)
+ {
+ switch(dev->irq)
+ {
+ case 3:
+ flp->state = SDLA_S507_IRQ3;
+ break;
+ case 4:
+ flp->state = SDLA_S507_IRQ4;
+ break;
+ case 5:
+ flp->state = SDLA_S507_IRQ5;
+ break;
+ case 7:
+ flp->state = SDLA_S507_IRQ7;
+ break;
+ case 10:
+ flp->state = SDLA_S507_IRQ10;
+ break;
+ case 11:
+ flp->state = SDLA_S507_IRQ11;
+ break;
+ case 12:
+ flp->state = SDLA_S507_IRQ12;
+ break;
+ case 15:
+ flp->state = SDLA_S507_IRQ15;
+ break;
+ }
+ }
+
+ for(i=0;i < sizeof(valid_mem) / sizeof (int) ; i++)
+ if (valid_mem[i] == map->mem_start)
+ break;
+
+ if (i == sizeof(valid_mem) / sizeof(int))
+ return(-EINVAL);
+
+ if ((flp->type == SDLA_S502A) && (((map->mem_start & 0xF000) >> 12) == 0x0E))
+ return(-EINVAL);
+
+ if ((flp->type != SDLA_S507) && ((map->mem_start >> 16) == 0x0B))
+ return(-EINVAL);
+
+ if ((flp->type == SDLA_S507) && ((map->mem_start >> 16) == 0x0D))
+ return(-EINVAL);
+
+ dev->mem_start = map->mem_start;
+ dev->mem_end = dev->mem_start + 0x2000;
+
+ byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0;
+ byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0));
+ switch(flp->type)
+ {
+ case SDLA_S502A:
+ case SDLA_S502E:
+ switch (map->mem_start >> 16)
+ {
+ case 0x0A:
+ byte |= SDLA_S502_SEG_A;
+ break;
+ case 0x0C:
+ byte |= SDLA_S502_SEG_C;
+ break;
+ case 0x0D:
+ byte |= SDLA_S502_SEG_D;
+ break;
+ case 0x0E:
+ byte |= SDLA_S502_SEG_E;
+ break;
+ }
+ break;
+ case SDLA_S507:
+ switch (map->mem_start >> 16)
+ {
+ case 0x0A:
+ byte |= SDLA_S507_SEG_A;
+ break;
+ case 0x0B:
+ byte |= SDLA_S507_SEG_B;
+ break;
+ case 0x0C:
+ byte |= SDLA_S507_SEG_C;
+ break;
+ case 0x0E:
+ byte |= SDLA_S507_SEG_E;
+ break;
+ }
+ break;
+ case SDLA_S508:
+ switch (map->mem_start >> 16)
+ {
+ case 0x0A:
+ byte |= SDLA_S508_SEG_A;
+ break;
+ case 0x0C:
+ byte |= SDLA_S508_SEG_C;
+ break;
+ case 0x0D:
+ byte |= SDLA_S508_SEG_D;
+ break;
+ case 0x0E:
+ byte |= SDLA_S508_SEG_E;
+ break;
+ }
+ break;
+ }
+
+ /* set the memory bits, and enable access */
+ outb(byte, dev->base_addr + SDLA_REG_PC_WINDOW);
+ switch(flp->type)
+ {
+ case SDLA_S502E:
+ flp->state = SDLA_S502E_ENABLE;
+ break;
+ case SDLA_S507:
+ flp->state |= SDLA_MEMEN;
+ break;
+ case SDLA_S508:
+ flp->state = SDLA_MEMEN;
+ break;
+ }
+ outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+
+ flp->initialized = 1;
+ return(0);
+}
+
+static struct enet_statistics *sdla_stats(struct device *dev)
+{
+ struct frad_local *flp;
+
+ flp = dev->priv;
+
+ return(&flp->stats);
+}
+
+int sdla_init(struct device *dev)
+{
+ struct frad_local *flp;
+ int i;
+
+ /* allocate the private data structure */
+ flp = kmalloc(sizeof(struct frad_local), GFP_KERNEL);
+ if (!flp)
+ return(-ENOMEM);
+
+ memset(flp, 0, sizeof(struct frad_local));
+ dev->priv = flp;
+
+ dev->flags = 0;
+ dev->open = sdla_open;
+ dev->stop = sdla_close;
+ dev->do_ioctl = sdla_ioctl;
+ dev->set_config = sdla_set_config;
+ dev->get_stats = sdla_stats;
+ dev->hard_start_xmit = sdla_transmit;
+ dev->change_mtu = sdla_change_mtu;
+
+ dev->type = 0xFFFF;
+ dev->family = AF_UNSPEC;
+ dev->pa_alen = sizeof(unsigned long);
+ dev->hard_header_len = 0;
+ dev->mtu = SDLA_MAX_MTU;
+
+ for (i = 0; i < DEV_NUMBUFFS; i++)
+ skb_queue_head_init(&dev->buffs[i]);
+
+ flp->activate = sdla_activate;
+ flp->deactivate = sdla_deactivate;
+ flp->assoc = sdla_assoc;
+ flp->deassoc = sdla_deassoc;
+ flp->dlci_conf = sdla_dlci_conf;
+
+ init_timer(&flp->timer);
+ flp->timer.expires = 1;
+ flp->timer.data = (unsigned long) dev;
+ flp->timer.function = sdla_poll;
+
+ return(0);
+}
+
+void sdla_setup(void)
+{
+ printk("%s.\n", version);
+ register_frad(devname);
+}
+
+#ifdef MODULE
+static struct device sdla0 = {"sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, sdla_init};
+
+int init_module(void)
+{
+ int result;
+
+ sdla_setup();
+ if ((result = register_netdev(&sdla0)) != 0)
+ return result;
+
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ unregister_netdev(&sdla0);
+ if (sdla0.priv)
+ kfree(sdla0.priv);
+ if (sdla0.irq)
+ free_irq(sdla0.irq, NULL);
+}
+#endif /* MODULE */
DEVICE( CIRRUS, CIRRUS_5434_4, "GD 5434"),
DEVICE( CIRRUS, CIRRUS_5434_8, "GD 5434"),
DEVICE( CIRRUS, CIRRUS_5436, "GD 5436"),
- DEVICE( CIRRUS, CIRRUS_6205, "GD 6205"),
DEVICE( CIRRUS, CIRRUS_6729, "CL 6729"),
DEVICE( CIRRUS, CIRRUS_7542, "CL 7542"),
DEVICE( CIRRUS, CIRRUS_7543, "CL 7543"),
DEVICE( MATROX, MATROX_MGA_IMP, "MGA Impression"),
DEVICE( CT, CT_65545, "65545"),
DEVICE( CT, CT_65548, "65548"),
+ DEVICE( MIRO, MIRO_36050, "ZR36050"),
DEVICE( FD, FD_36C70, "TMC-18C30"),
DEVICE( SI, SI_6201, "6201"),
DEVICE( SI, SI_6202, "6202"),
+ DEVICE( SI, SI_6205, "6205"),
DEVICE( SI, SI_503, "85C503"),
DEVICE( SI, SI_501, "85C501"),
DEVICE( SI, SI_496, "85C496"),
DEVICE( VIA, VIA_82C561, "VT 82C561"),
DEVICE( VIA, VIA_82C576, "VT 82C576 3V"),
DEVICE( VIA, VIA_82C416, "VT 82C416MV"),
- DEVICE( VORTEX, VORTEX_GDT, "GDT 6000b"),
+ DEVICE( VORTEX, VORTEX_GDT60x0, "GDT 60x0"),
+ DEVICE( VORTEX, VORTEX_GDT6000B,"GDT 6000b"),
+ DEVICE( VORTEX, VORTEX_GDT6x10, "GDT 6110/6510"),
+ DEVICE( VORTEX, VORTEX_GDT6x20, "GDT 6120/6520"),
+ DEVICE( VORTEX, VORTEX_GDT6530, "GDT 6530"),
+ DEVICE( VORTEX, VORTEX_GDT6550, "GDT 6550"),
+ DEVICE( VORTEX, VORTEX_GDT6x17, "GDT 6117/6517"),
+ DEVICE( VORTEX, VORTEX_GDT6x27, "GDT 6127/6527"),
+ DEVICE( VORTEX, VORTEX_GDT6537, "GDT 6537"),
+ DEVICE( VORTEX, VORTEX_GDT6557, "GDT 6557"),
+ DEVICE( VORTEX, VORTEX_GDT6x15, "GDT 6115/6515"),
+ DEVICE( VORTEX, VORTEX_GDT6x25, "GDT 6125/6525"),
+ DEVICE( VORTEX, VORTEX_GDT6535, "GDT 6535"),
+ DEVICE( VORTEX, VORTEX_GDT6555, "GDT 6555"),
DEVICE( EF, EF_ATM_FPGA, "155P-MF1 (FPGA)"),
DEVICE( EF, EF_ATM_ASIC, "155P-MF1 (ASIC)"),
DEVICE( IMAGINGTECH, IMAGINGTECH_ICPCI, "MVC IC-PCI"),
DEVICE( FORE, FORE_PCA200PC, "PCA-200PC"),
+ DEVICE( FORE, FORE_PCA200E, "PCA-200E"),
DEVICE( PLX, PLX_9060, "PCI9060 i960 bridge"),
DEVICE( ALLIANCE, ALLIANCE_PROMOTIO, "Promotion-6410"),
DEVICE( ALLIANCE, ALLIANCE_PROVIDEO, "Provideo"),
*data = d + c;
*count = 0;
- *phase = (NCR5380_read(STATUS_REG & PHASE_MASK));
+ *phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
#if 0
NCR5380_print_phase(instance);
#endif
-REAME file for the Linux g_NCR5380 driver.
+README file for the Linux g_NCR5380 driver.
(c) 1993 Drew Eckhard
NCR53c400 extensions (c) 1994,1995,1996 Kevin Lentin
get resources. */
shpnt = scsi_register( tpnt, 0 );
+ shpnt->irq = interrupt_level;
+ shpnt->io_port = port_base;
+ shpnt->n_io_port = 0x10;
print_banner( shpnt );
/* Log IRQ with kernel */
if(SCset){
oldto = SCset->timeout - used;
- SCset->timeout = timeout + used;
+ SCset->timeout = timeout;
}
least = 0xffffffff;
for(host = scsi_hostlist; host; host = host->next)
for(SCpnt = host->host_queue; SCpnt; SCpnt = SCpnt->next)
if (SCpnt->timeout > 0) {
- SCpnt->timeout -= used;
+ if (SCpnt != SCset)
+ SCpnt->timeout -= used;
if(SCpnt->timeout <= 0) SCpnt->timeout = -1;
if(SCpnt->timeout > 0 && SCpnt->timeout < least)
least = SCpnt->timeout;
* turned off
*/
#define INIT_SCSI_REQUEST \
- if (!CURRENT) { \
+ if (!CURRENT || CURRENT_PLUGGED) { \
CLEAR_INTR; \
restore_flags(flags); \
return; \
#include "scsi_ioctl.h"
#include "hosts.h"
#include "sd.h"
+#include <linux/scsicam.h> /* must follow "hosts.h" */
int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{
-Changelog for version 3.5
--------------------------
+Changelog for version 3.5.1
+---------------------------
Since 3.5
- Improved handling of playback underrunt situations.
endif
+ifndef HOSTCC
build:
@echo Compiling modularized sound driver
@make sound.o
install: sound.o
cp sound.o $(MODULEDIR)
+endif
.c.o:
$(CC) $(CFLAGS) -c $<
-Version 3.5-beta11 release notes
---------------------------------
+Version 3.5.1 release notes
+---------------------------
Most up to date information about this driver is available from
http://personal.eunet.fi/pp/voxware.
partition containing the file with Linux.
It's possible to load your own DSP algorithms and run them with the card.
-Look at the directory pss_test of snd-util-3.0.tar.gz for more info.§
-package.
+Look at the directory pss_test of snd-util-3.0.tar.gz for more info.
AudioTriX Pro
-------------
again. It's possible to use an earlier version of sndscape.co[01] but it
may sound wierd.
-Btw, The driver may complain something about "sscapeintr()" after
-running ssinit. You should just ignore these messages.
-
MAD16 (Pro) and Mozart
----------------------
{
unsigned char tmp;
- int i;
ad1848_info *devc = &dev_info[nr_ad1848_devs];
unsigned char tmp1 = 0xff, tmp2 = 0xff;
+ int i;
DDB (printk ("ad1848_detect(%x)\n", io_base));
return 0;
}
+ DDB (printk ("ad1848: regs: "));
+ for (i = 0; i < 32; i++)
+ DDB (printk ("%02x ", ad_read (devc, i)));
+ DDB (printk ("\n"));
+
/*
* Test if it's possible to change contents of the indirect registers.
* Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only
* with CS4231.
*/
- DDB (printk ("ad1848_detect() - step F\n"));
- ad_write (devc, 12, 0); /* Mode2=disabled */
-
- for (i = 0; i < 16; i++)
- if ((tmp1 = ad_read (devc, i)) != (tmp2 = ad_read (devc, i + 16)))
- {
- DDB (printk ("ad1848 detect error - step F(%d/%x/%x)\n", i, tmp1, tmp2));
- return 0;
- }
/*
* Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit (0x40).
static int local_conversion[MAX_AUDIO_DEV];
static int
-set_format (int dev, int fmt)
+set_format (int dev, long fmt)
{
if (fmt != AFMT_QUERY)
{
audio_open (int dev, struct fileinfo *file)
{
int ret;
- int bits;
+ long bits;
int dev_type = dev & 0x0f;
int mode = file->mode & O_ACCMODE;
void
sync_output (int dev)
{
- int buf_no, buf_ptr, buf_size;
+ int buf_no, buf_ptr, buf_size, p, i;
char *dma_buf;
+ struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
{
DMAbuf_start_output (dev, buf_no, buf_ptr);
}
+
+/*
+ * Clean all unused buffer fragments.
+ */
+
+ p = dmap->qtail;
+
+ for (i = dmap->qlen; i < dmap->nbufs; i++)
+ {
+ memset (dmap->raw_buf + p * dmap->fragment_size,
+ dmap->neutral_byte,
+ dmap->fragment_size);
+
+ p = (p + 1) % dmap->nbufs;
+ }
+
+ dmap->flags |= DMA_CLEAN;
}
void
/*
- * PnP soundcard support is not included in this version.
+ * PnP soundcard support is not included in this version.
*
- * AEDSP16 will not work without significant changes.
+ * AEDSP16 will not work without significant changes.
*/
#define DISABLED_OPTIONS (B(OPT_SPNP)|B(OPT_AEDSP16)|B(OPT_UNUSED1)|B(OPT_UNUSED2))
/*
* sound/configure.c - Configuration program for the Linux Sound Driver
*/
-#define COPYING2
+/*
+ * Copyright by Hannu Savolainen 1993-1996
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+
#include <stdio.h>
#include <unistd.h>
#define ANY_DEVS (B(OPT_AUDIO)|B(OPT_MIDI)|B(OPT_GUS)| \
B(OPT_MPU401)|B(OPT_PSS)|B(OPT_GUS16)|B(OPT_GUSMAX)| \
B(OPT_MSS)|B(OPT_SSCAPE)|B(OPT_UART6850)|B(OPT_TRIX)| \
- B(OPT_MAD16)|B(OPT_CS4232)|B(OPT_MAUI))
+ B(OPT_MAD16)|B(OPT_CS4232)|B(OPT_MAUI)|B(OPT_ADLIB))
#define AUDIO_CARDS (B (OPT_PSS) | B (OPT_SB) | B (OPT_PAS) | B (OPT_GUS) | \
B (OPT_MSS) | B (OPT_GUS16) | B (OPT_GUSMAX) | B (OPT_TRIX) | \
B (OPT_SSCAPE)| B(OPT_MAD16) | B(OPT_CS4232))
"them. In addition the MAD16 chip is used in some cards made by known\n"
"manufacturers such as Turtle Beach (Tropez), Reveal (some models) and\n"
"Diamond (latest ones).\n",
-
+
"Enable this if you have a card based on the Crystal CS4232 chip set.\n",
"Enable this option if you have a Turtle Beach Wave Front, Maui,\n"
"This enables the dev/midixx devices and access to any MIDI ports\n"
"using /dev/sequencer and /dev/music. This option also affects any\n"
"MPU401 and/or General MIDI compatible devices.\n",
-
+
"This should not be asked",
"This enables the Yamaha FM synthesizer chip used on many sound\n"
int
can_select_option (int nr)
{
-#if 0
- switch (nr)
- {
- case OPT_LAST_MUTUAL + 1:
- fprintf (stderr, "\nThe following cards should work with any other cards.\n"
- "CAUTION! Don't enable MPU-401 if you don't have it.\n");
- break;
-
- case OPT_HIGHLEVEL:
- fprintf (stderr, "\nSelect one or more of the following options\n");
- break;
-
-
- }
-#endif
if (hw_table[nr].conditions)
if (!(hw_table[nr].conditions & selected_options))
char answ[512];
int len;
- response:
- fprintf(stderr, prompt);
+response:
+ fprintf (stderr, prompt);
if (def_answ)
- fprintf(stderr, " [Y/n/?] ");
+ fprintf (stderr, " [Y/n/?] ");
else
- fprintf(stderr, " [N/y/?] ");
+ fprintf (stderr, " [N/y/?] ");
if ((len = read (0, answ, sizeof (answ))) < 1)
{
*/
return def_answ;
- if (answ[0] == '?') { /* display help message */
- fprintf(stderr, "\n");
- fprintf(stderr, help);
- fprintf(stderr, "\n");
- goto response;
- }
+ if (answ[0] == '?')
+ { /* display help message */
+ fprintf (stderr, "\n");
+ fprintf (stderr, help);
+ fprintf (stderr, "\n");
+ goto response;
+ }
answ[len - 1] = 0;
for (i = 0; i < OPT_LAST; i++)
if (mask == B (i))
{
- unsigned int j;
+ unsigned int j;
for (j = 0; j < strlen (choices); j++)
if (choices[j] == '\'')
return;
fprintf (stderr, "\n%s\n", question);
- if (strcmp(choices, ""))
+ if (strcmp (choices, ""))
fprintf (stderr, "Possible values are: %s\n", choices);
if (format == FMT_INT)
continue;
if (strcmp (tmp, "JAZZ_DMA16") == 0) /* Rename it (hack) */
- {
- printf("#define SB_DMA2 %s\n",
- &buf[18]);
- continue;
- }
+ {
+ printf ("#define SB_DMA2 %s\n",
+ &buf[18]);
+ continue;
+ }
if (strcmp (tmp, "SB16_DMA") == 0) /* Rename it (hack) */
- {
- printf("#define SB_DMA2 %s\n",
- &buf[16]);
- continue;
- }
+ {
+ printf ("#define SB_DMA2 %s\n",
+ &buf[16]);
+ continue;
+ }
tmp[8] = 0; /* Truncate the string */
if (strcmp (tmp, "EXCLUDE_") == 0)
printf ("#define SELECTED_SOUND_OPTIONS\t0x%08x\n", selected_options);
fprintf (stderr, "Old configuration copied.\n");
-#ifdef linux
build_defines ();
-#endif
old_config_used = 1;
return 1;
}
-#ifdef linux
void
build_defines (void)
{
if (!hw_table[i].alias)
if (selected_options & B (i))
fprintf (optf, "CONFIG_%s=y\n", hw_table[i].macro);
-#if 0
- else
- fprintf (optf, "CONFIG_%s=n\n", hw_table[i].macro);
-#endif
fprintf (optf, "\n");
{
if (selected_options & extra_options[i].mask)
fprintf (optf, "CONFIG_%s=y\n", extra_options[i].name);
-#if 0
- else
- fprintf (optf, "CONFIG_%s=n\n", extra_options[i].name);
-#endif
i++;
}
fprintf (optf, "\n");
fclose (optf);
}
-#endif
void
ask_parameters (void)
{
-#ifdef linux
int num;
build_defines ();
"0, 1 or 3");
ask_int_choice (B (OPT_SB), "SB_DMA2",
- "SoundBlaster 16 bit DMA (_REQUIRED_for SB16, Jazz16, SMW)",
+ "SoundBlaster 16 bit DMA (_REQUIRED_for SB16, Jazz16, SMW)",
FMT_INT,
5,
"5, 6 or 7");
if (selected_options & B (OPT_PAS))
{
if (think_positively ("Enable Joystick port on ProAudioSpectrum", 0,
- "Enable this option if you want to use the joystick port provided\n"
- "on the PAS sound card.\n"))
- printf ("#define PAS_JOYSTICK_ENABLE\n");
+ "Enable this option if you want to use the joystick port provided\n"
+ "on the PAS sound card.\n"))
+ printf ("#define PAS_JOYSTICK_ENABLE\n");
if (think_positively ("Enable PAS16 bus clock option", 0,
- "The PAS16 can be noisy with some motherboards. There is a command\n"
- "line switch (:T?) in the DOS driver for PAS16 which solves this.\n"
+ "The PAS16 can be noisy with some motherboards. There is a command\n"
+ "line switch (:T?) in the DOS driver for PAS16 which solves this.\n"
"Don't enable this feature unless you have problems and have to use\n"
- "this switch with DOS\n"))
+ "this switch with DOS\n"))
printf ("#define BROKEN_BUS_CLOCK\n");
if (think_positively ("Disable SB mode of PAS16", 0,
- "You should disable SB emulation of PAS16 if you want to use\n"
- "Another SB compatible card in the same system\n"))
- printf ("#define DISABLE_SB_EMULATION\n");
+ "You should disable SB emulation of PAS16 if you want to use\n"
+ "Another SB compatible card in the same system\n"))
+ printf ("#define DISABLE_SB_EMULATION\n");
}
ask_int_choice (B (OPT_GUS), "GUS_BASE",
int reveal_spea;
reveal_spea = think_positively (
- "Is your SoundScape card made/marketed by Reveal or Spea",
- 0,
- "Enable if you have a SoundScape card with the Reveal or\n"
- "Spea name on it.\n");
+ "Is your SoundScape card made/marketed by Reveal or Spea",
+ 0,
+ "Enable if you have a SoundScape card with the Reveal or\n"
+ "Spea name on it.\n");
if (reveal_spea)
printf ("#define REVEAL_SPEA\n");
FMT_INT,
9,
"5, 7, 9 or 10");
-#endif
ask_int_choice (B (OPT_AUDIO), "DSP_BUFFSIZE",
"Audio DMA buffer size",
FMT_INT,
selected_options = 0;
ask_parameters ();
-#if 1
printf ("#\n$MAKE -C drivers/sound kernelconfig || exit 1\n");
-#endif
}
void
if (access (oldconf, R_OK) == 0)
{
- char str[255];
- sprintf(str, "Old configuration exists in `%s'. Use it", oldconf);
+ char str[255];
+
+ sprintf (str, "Old configuration exists in `%s'. Use it", oldconf);
if (think_positively (str, 1,
-"Enable this option to load the previously saved configuration file\n"
-"for all of the sound driver parameters.\n"))
+ "Enable this option to load the previously saved configuration file\n"
+ "for all of the sound driver parameters.\n"))
if (use_old_config (oldconf))
exit (0);
}
if (selected_options & B (OPT_SB))
{
if (think_positively (
- "Support for the SG NX Pro mixer", 0,
- "Enable this if you want to support the additional mixer functions\n"
- "provided on Sound Galaxy NX Pro sound cards.\n"))
+ "Support for the SG NX Pro mixer", 0,
+ "Enable this if you want to support the additional mixer functions\n"
+ "provided on Sound Galaxy NX Pro sound cards.\n"))
printf ("#define __SGNXPRO__\n");
}
if (selected_options & B (OPT_SB))
{
if (think_positively ("Support for the MV Jazz16 (ProSonic etc.)", 0,
- "Enable this if you have an MV Jazz16 or ProSonic sound card.\n"))
+ "Enable this if you have an MV Jazz16 or ProSonic sound card.\n"))
{
if (think_positively ("Do you have SoundMan Wave", 0,
- "Enable this option of you have the Logitech SoundMan Wave sound card.\n"))
+ "Enable this option of you have the Logitech SoundMan Wave sound card.\n"))
{
printf ("#define SM_WAVE\n");
midi0001_again:
if (think_positively (
-"Do you have access to the MIDI0001.BIN file", 1,
-"The Logitech SoundMan Wave has a microcontroller which must be\n"
-"initialized before MIDI emulation works. This is possible only if the\n"
-"microcode file is compiled into the driver.\n"))
+ "Do you have access to the MIDI0001.BIN file", 1,
+ "The Logitech SoundMan Wave has a microcontroller which must be\n"
+ "initialized before MIDI emulation works. This is possible only if the\n"
+ "microcode file is compiled into the driver.\n"))
{
char path[512];
fprintf (stderr, "Couldn't open file %s\n",
path);
if (think_positively ("Try again with correct path", 1,
-"The specified file could not be opened. Enter the correct path to the\n"
-"file.\n"))
+ "The specified file could not be opened. Enter the correct path to the\n"
+ "file.\n"))
goto midi0001_again;
}
else
if (selected_options & B (OPT_SB))
{
if (think_positively ("Do you have a Logitech SoundMan Games", 0,
-"The Logitech SoundMan Games supports 44 kHz in stereo while the\n"
-"standard SB Pro supports just 22 kHz stereo. You have the option of\n"
-"enabling SM Games mode. However, enable it only if you are sure that\n"
-"your card is an SM Games. Enabling this feature with a plain old SB\n"
-"Pro will cause troubles with stereo mode.\n\n"
-"DANGER! Read the above once again before answering 'y'\n"
-"Answer 'n' if you are unsure what to do!\n"))
+ "The Logitech SoundMan Games supports 44 kHz in stereo while the\n"
+ "standard SB Pro supports just 22 kHz stereo. You have the option of\n"
+ "enabling SM Games mode. However, enable it only if you are sure that\n"
+ "your card is an SM Games. Enabling this feature with a plain old SB\n"
+ "Pro will cause troubles with stereo mode.\n\n"
+ "DANGER! Read the above once again before answering 'y'\n"
+ "Answer 'n' if you are unsure what to do!\n"))
printf ("#define SM_GAMES\n");
}
{
if (think_positively (
-"Do you want support for the Audio Excel SoundBlaster Pro mode",
-1,
-"Enable this option if you want the Audio Excel sound card to operate\n"
-"in SoundBlaster Pro mode.\n"))
+ "Do you want support for the Audio Excel SoundBlaster Pro mode",
+ 1,
+ "Enable this option if you want the Audio Excel sound card to operate\n"
+ "in SoundBlaster Pro mode.\n"))
{
printf ("#define AEDSP16_SBPRO\n");
sel1 = 1;
if ((selected_options & B (OPT_MSS)) && (sel1 == 0))
{
-
+
if (think_positively (
-"Do you want support for the Audio Excel Microsoft Sound System mode",
-1,
-"Enable this option if you want the Audio Excel sound card to operate\n"
-"in Microsoft Sound System mode.\n"))
+ "Do you want support for the Audio Excel Microsoft Sound System mode",
+ 1,
+ "Enable this option if you want the Audio Excel sound card to operate\n"
+ "in Microsoft Sound System mode.\n"))
{
printf ("#define AEDSP16_MSS\n");
sel1 = 1;
{
genld_again:
if (think_positively ("Do you wish to include an LD file", 1,
- "If you want to emulate the SoundBlaster card and you have a DSPxxx.LD\n"
- "file then you must include the LD in the kernel.\n"))
+ "If you want to emulate the SoundBlaster card and you have a DSPxxx.LD\n"
+ "file then you must include the LD in the kernel.\n"))
{
char path[512];
if (!bin2hex (path, "synth-ld.h", "pss_synth"))
{
- fprintf (stderr, "couldn't open `%s' as the LD file\n", path);
+ fprintf (stderr, "couldn't open `%s' as the LD file\n", path);
if (think_positively ("try again with correct path", 1,
- "The given LD file could not opened.\n"))
+ "The given LD file could not opened.\n"))
goto genld_again;
}
else
hex2hex_again:
if (think_positively ("Do you want to include TRXPRO.HEX in your kernel",
- 1,
-"The MediaTriX AudioTrix Pro has an onboard microcontroller which\n"
-"needs to be initialized by downloading the code from the file TRXPRO.HEX\n"
-"in the DOS driver directory. If you don't have the TRXPRO.HEX file handy\n"
-"you may skip this step. However, the SB and MPU-401 modes of AudioTriX\n"
-"Pro will not work without this file!\n"))
+ 1,
+ "The MediaTriX AudioTrix Pro has an onboard microcontroller which\n"
+ "needs to be initialized by downloading the code from the file TRXPRO.HEX\n"
+ "in the DOS driver directory. If you don't have the TRXPRO.HEX file handy\n"
+ "you may skip this step. However, the SB and MPU-401 modes of AudioTriX\n"
+ "Pro will not work without this file!\n"))
{
char path[512];
if (!(selected_options & ANY_DEVS))
{
printf ("invalid_configuration__run_make_config_again\n");
- fprintf (stderr,"\n*** This combination is useless. Sound driver disabled!!! ***\n*** You need to enable support for at least one device ***\n\n");
+ fprintf (stderr, "\n*** This combination is useless. Sound driver disabled!!! ***\n*** You need to enable support for at least one device ***\n\n");
exit (0);
}
if (!old_config_used)
{
- char str[255];
- sprintf(str, "Save copy of this configuration to `%s'", oldconf);
- if (think_positively (str, 1,
-"If you enable this option then the sound driver configuration is\n"
-"saved to a file. If you later need to recompile the kernel you have\n"
-"the option of using the saved configuration.\n"))
+ char str[255];
+
+ sprintf (str, "Save copy of this configuration to `%s'", oldconf);
+ if (think_positively (str, 1,
+ "If you enable this option then the sound driver configuration is\n"
+ "saved to a file. If you later need to recompile the kernel you have\n"
+ "the option of using the saved configuration.\n"))
{
char cmd[200];
#define MAX_SUB_BUFFERS (32*MAX_REALTIME_FACTOR)
#define DMODE_NONE 0
-#define DMODE_OUTPUT 1
-#define DMODE_INPUT 2
+#define DMODE_OUTPUT PCM_ENABLE_OUTPUT
+#define DMODE_INPUT PCM_ENABLE_INPUT
struct dma_buffparms {
int dma_mode; /* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */
#define DMA_STARTED 0x00000008
#define DMA_EMPTY 0x00000010
#define DMA_ALLOC_DONE 0x00000020
+#define DMA_SYNCING 0x00000040
+#define DMA_CLEAN 0x00000080
int open_mode;
save_flags (flags);
cli ();
+ audio_devs[dev]->flags |= DMA_SYNCING;
+
audio_devs[dev]->dmap_out->underrun_count = 0;
while (!current_got_fatal_signal ()
&& audio_devs[dev]->dmap_out->qlen
};
if ((out_sleep_flag[dev].mode & WK_TIMEOUT))
{
+ audio_devs[dev]->flags &= ~DMA_SYNCING;
restore_flags (flags);
return audio_devs[dev]->dmap_out->qlen;
}
}
+ audio_devs[dev]->flags &= ~DMA_SYNCING;
restore_flags (flags);
/*
int abort, err = EIO;
struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
+ dmap->flags &= ~DMA_CLEAN;
+
if (audio_devs[dev]->dmap_out->mapping_flags & DMA_MAP_MAPPED)
{
printk ("Sound: Can't write to mmapped device (3)\n");
struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
dmap->cfrag = -1;
+
/*
* Bypass buffering if using mmaped access
*/
{
dmap->underrun_count++;
- if (dmap->underrun_count > 5 || dmap->flags & DMA_EMPTY)
+ if (!(dmap->flags & DMA_CLEAN) &&
+ (audio_devs[dev]->flags & DMA_SYNCING || dmap->underrun_count > 5 || dmap->flags & DMA_EMPTY))
{
dmap->qlen = 0;
force_restart (dev, dmap);
save_flags (flags);
cli ();
+
in_sleep_flag[dev].mode = WK_SLEEP;
module_select_wait (&in_sleeper[dev], wait);
restore_flags (flags);
{
save_flags (flags);
cli ();
+
in_sleep_flag[dev].mode = WK_SLEEP;
module_select_wait (&in_sleeper[dev], wait);
restore_flags (flags);
save_flags (flags);
cli ();
+
out_sleep_flag[dev].mode = WK_SLEEP;
module_select_wait (&out_sleeper[dev], wait);
restore_flags (flags);
{
save_flags (flags);
cli ();
+
out_sleep_flag[dev].mode = WK_SLEEP;
module_select_wait (&out_sleeper[dev], wait);
restore_flags (flags);
irq_image = 0;
tmp = gus_irq_map[gus_irq];
- if (!tmp)
+ if (!gus_pnp_flag && !tmp)
printk ("Warning! GUS IRQ not selected\n");
irq_image |= tmp;
irq_image |= 0x40; /* Combine IRQ1 (GF1) and IRQ2 (Midi) */
blk_sz = blk_end - target;
}
- if (gus_no_dma)
+ if (gus_pnp_flag || gus_no_dma)
{
/*
* For some reason the DMA is not possible. We have to use PIO.
*/
#include <linux/config.h>
-
/*
* sound/mad16.c
*
* OPTi 82C928 MAD16 (replaced by C929)
* OAK OTI-601D Mozart
* OPTi 82C929 MAD16 Pro
+ * OPTi 82C930 (Not supported yet)
*
* These audio interface chips don't prduce sound themselves. They just
* connect some other components (OPL-[234] and a WSS compatible codec)
#define C928 1
#define MOZART 2
#define C929 3
+#define C930 4
/*
* Registers
* only until the next I/O read or write.
*/
+#define MC0_PORT 0xf8c /* Dummy port */
#define MC1_PORT 0xf8d /* SB address, CDROM interface type, joystick */
#define MC2_PORT 0xf8e /* CDROM address, IRQ, DMA, plus OPL4 bit */
#define MC3_PORT 0xf8f
#define MC5_PORT 0xf91
#define MC6_PORT 0xf92
#define MC7_PORT 0xf93
+#define MC8_PORT 0xf94
+#define MC9_PORT 0xf95
+#define MC10_PORT 0xf96
+#define MC11_PORT 0xf97
+#define MC12_PORT 0xf98
static int board_type = C928;
case C929:
outb (0xE3, PASSWD_REG);
break;
+
}
tmp = inb (port);
case C929:
outb (0xE3, PASSWD_REG);
break;
+
}
outb ((unsigned char) (value & 0xff), port);
detect_mad16 (void)
{
unsigned char tmp, tmp2;
+ int i;
/*
* Check that reading a register doesn't return bus float (0xff)
DDB (printk ("MC1_PORT returned 0xff\n"));
return 0;
}
+
+ for (i = 0xf8d; i <= 0xf98; i++)
+ DDB (printk ("Port %0x (init value) = %0x\n", i, mad_read (i)));
+
/*
* Now check that the gate is closed on first I/O after writing
* the password. (This is how a MAD16 compatible card works).
}
mad_write (MC1_PORT, tmp ^ 0x80); /* Togge a bit */
-
if ((tmp2 = mad_read (MC1_PORT)) != (tmp ^ 0x80)) /* Compare the bit */
{
mad_write (MC1_PORT, tmp); /* Restore */
}
+static int
+wss_init (struct address_info *hw_config)
+{
+ int ad_flags = 0;
+
+/*
+ * Verify the WSS parameters
+ */
+
+ if (check_region (hw_config->io_base, 8))
+ {
+ printk ("MSS: I/O port conflict\n");
+ return 0;
+ }
+
+ if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
+ return 0;
+ /*
+ * Check if the IO port returns valid signature. The original MS Sound
+ * system returns 0x04 while some cards (AudioTriX Pro for example)
+ * return 0x00.
+ */
+
+ if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 &&
+ (inb (hw_config->io_base + 3) & 0x3f) != 0x00)
+ {
+ DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n",
+ hw_config->io_base, inb (hw_config->io_base + 3)));
+ return 0;
+ }
+
+ if (hw_config->irq > 11)
+ {
+ printk ("MSS: Bad IRQ %d\n", hw_config->irq);
+ return 0;
+ }
+
+ if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
+ {
+ printk ("MSS: Bad DMA %d\n", hw_config->dma);
+ return 0;
+ }
+
+ /*
+ * Check that DMA0 is not in use with a 8 bit board.
+ */
+
+ if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80)
+ {
+ printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
+ return 0;
+ }
+
+ if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80)
+ {
+ printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
+ }
+
+ return 1;
+}
+
int
probe_mad16 (struct address_info *hw_config)
{
DDB (printk ("Detect using password = 0xE3\n"));
if (!detect_mad16 ())
- return 0;
-
- DDB (printk ("mad16.c: 82C929 detected\n"));
+ {
+ return 0;
+ }
+ else
+ {
+ DDB (printk ("mad16.c: 82C929 detected\n"));
+ }
}
else
{
}
for (i = 0xf8d; i <= 0xf93; i++)
- DDB (printk ("port %03x = %03x\n", i, mad_read (i)));
+ DDB (printk ("port %03x = %02x\n", i, mad_read (i)));
/*
* Set the WSS address
}
for (i = 0xf8d; i <= 0xf93; i++)
- DDB (printk ("port %03x after init = %03x\n", i, mad_read (i)));
-
-/*
- * Verify the WSS parameters
- */
-
- if (check_region (hw_config->io_base, 8))
- {
- printk ("MSS: I/O port conflict\n");
- return 0;
- }
-
- /*
- * Check if the IO port returns valid signature. The original MS Sound
- * system returns 0x04 while some cards (AudioTriX Pro for example)
- * return 0x00.
- */
-
- if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 &&
- (inb (hw_config->io_base + 3) & 0x3f) != 0x00)
- {
- DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n",
- hw_config->io_base, inb (hw_config->io_base + 3)));
- return 0;
- }
-
- if (hw_config->irq > 11)
- {
- printk ("MSS: Bad IRQ %d\n", hw_config->irq);
- return 0;
- }
-
- if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
- {
- printk ("MSS: Bad DMA %d\n", hw_config->dma);
- return 0;
- }
+ DDB (printk ("port %03x after init = %02x\n", i, mad_read (i)));
- /*
- * Check that DMA0 is not in use with a 8 bit board.
- */
-
- if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80)
- {
- printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
- return 0;
- }
-
- if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80)
- {
- printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
- return 0;
- }
+ wss_init (hw_config);
return 1;
}
case SEL_IN:
if (!DATA_AVAIL (midi_in_buf[dev]))
{
+
input_sleep_flag[dev].mode = WK_SLEEP;
module_select_wait (&input_sleeper[dev], wait);
return 0;
case SEL_OUT:
if (SPACE_AVAIL (midi_out_buf[dev]))
{
+
midi_sleep_flag[dev].mode = WK_SLEEP;
module_select_wait (&midi_sleeper[dev], wait);
return 0;
{
case SOUND_PCM_WRITE_RATE:
if (local)
- return dsp_set_speed ((int) arg);
+ return dsp_set_speed ((long) arg);
return snd_ioctl_return ((int *) arg, dsp_set_speed (get_fs_long ((long *) arg)));
case SOUND_PCM_READ_RATE:
case SNDCTL_DSP_STEREO:
if (local)
- return dsp_set_stereo ((int) arg);
+ return dsp_set_stereo ((long) arg);
return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg)));
case SOUND_PCM_WRITE_CHANNELS:
if (local)
- return dsp_set_stereo ((int) arg - 1) + 1;
+ return dsp_set_stereo ((long) arg - 1) + 1;
return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg) - 1) + 1);
case SOUND_PCM_READ_CHANNELS:
case SNDCTL_DSP_SETFMT:
if (local)
- return dsp_set_bits ((int) arg);
+ return dsp_set_bits ((long) arg);
return snd_ioctl_return ((int *) arg, dsp_set_bits (get_fs_long ((long *) arg)));
case SOUND_PCM_READ_BITS:
if (sb_intr_active || (sb_midi_busy && sb_midi_mode == UART_MIDI))
{
- printk ("SB: Audio device or MIDI already in use\n");
+ printk ("SB: Audio device or MIDI already in use.\n");
return -EBUSY;
}
{
case SOUND_PCM_WRITE_RATE:
if (local)
- return dsp_speed ((int) arg);
+ return dsp_speed ((long) arg);
return snd_ioctl_return ((int *) arg, dsp_speed (get_fs_long ((long *) arg)));
break;
case SOUND_PCM_WRITE_CHANNELS:
if (local)
- return dsp_set_stereo ((int) arg - 1) + 1;
+ return dsp_set_stereo ((long) arg - 1) + 1;
return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg) - 1) + 1);
break;
case SNDCTL_DSP_STEREO:
if (local)
- return dsp_set_stereo ((int) arg);
+ return dsp_set_stereo ((long) arg);
return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg)));
break;
*/
case SNDCTL_DSP_SETFMT:
if (local)
- return dsp_set_bits ((int) arg);
+ return dsp_set_bits ((long) arg);
return snd_ioctl_return ((int *) arg, dsp_set_bits (get_fs_long ((long *) arg)));
break;
cli ();
if (!iqlen)
{
+
midi_sleep_flag.mode = WK_SLEEP;
module_select_wait (&midi_sleeper, wait);
restore_flags (flags);
return 0;
}
- midi_sleep_flag.mode &= ~WK_SLEEP;
restore_flags (flags);
return 1;
break;
cli ();
if ((SEQ_MAX_QUEUE - qlen) < output_treshold)
{
+
seq_sleep_flag.mode = WK_SLEEP;
module_select_wait (&seq_sleeper, wait);
restore_flags (flags);
return 0;
}
- seq_sleep_flag.mode &= ~WK_SLEEP;
restore_flags (flags);
return 1;
break;
#define WK_TIMEOUT 0x02
#define WK_SIGNAL 0x04
#define WK_SLEEP 0x08
+#define WK_SELECT 0x10
#define OPEN_READ PCM_ENABLE_INPUT
#define OPEN_WRITE PCM_ENABLE_OUTPUT
if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0) /* Mixer ioctl */
if ((dev & 0x0f) != SND_DEV_CTL)
{
+#ifdef CONFIG_AUDIO
int dtype = dev & 0x0f;
int mixdev;
switch (dtype)
{
-#ifdef CONFIG_AUDIO
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
if (mixdev < 0 || mixdev >= num_mixers)
return -ENXIO;
return mixer_devs[mixdev]->ioctl (mixdev, cmd, arg);
- break;
-#endif
-
- default:
- return mixer_devs[0]->ioctl (0, cmd, arg);
}
+#endif
+ return mixer_devs[0]->ioctl (0, cmd, arg);
}
switch (dev & 0x0f)
#endif
-static int debugmem = 0; /* switched off by default */
-
static int sound[20] =
{0};
{
int i;
+ if (MOD_IN_USE)
+ {
+ return;
+ }
+
if (chrdev_registered)
module_unregister_chrdev (sound_major, "sound");
printk ("Sound: Hmm, DMA%d was left allocated - fixed\n", i);
sound_free_dma (i);
}
+
}
#endif
fatal_error__This_version_is_not_compatible_with_this_kernel;
#endif
+static int debugmem = 0; /* switched off by default */
+
static int dma_buffsize = DSP_BUFFSIZE;
int
audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz);
- if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, 1)) == NULL)
+ if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL)
audio_devs[dev]->buffsize /= 2;
}
printk ("Exited sound_map_buffer()\n");
return -EINVAL;
}
+#endif
void
conf_printf (char *name, struct address_info *hw_config)
printk ("\n");
}
-#endif
-#define SOUND_VERSION_STRING "3.5-960313"
+#define SOUND_VERSION_STRING "3.5.1-960324"
#define SOUND_INTERNAL_VERSION 0x030500
unsigned char bits, tmp;
static int debug = 0;
- printk ("sscapeintr(0x%02x)\n", (bits = sscape_read (devc, GA_INTSTAT_REG)));
+ bits = sscape_read (devc, GA_INTSTAT_REG);
if ((sscape_sleep_flag.mode & WK_SLEEP))
{
{
static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
{
- char *cp, *interp, *i_name, *i_arg, *page;
- int retval, offset;
+ char *cp, *interp, *i_name, *i_arg;
+ int retval;
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang))
return -ENOEXEC;
/*
* This is done in reverse order, because of how the
* user environment and arguments are stored.
*/
- if (bprm->argc) {
- offset = bprm->p % PAGE_SIZE;
- page = (char*)bprm->page[bprm->p/PAGE_SIZE];
- while(bprm->p++,*(page+offset++))
- if(offset==PAGE_SIZE){
- offset=0;
- page = (char*)bprm->page[bprm->p/PAGE_SIZE];
- }
- bprm->argc--;
- }
+ remove_arg_zero(bprm);
bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
bprm->argc++;
if (i_arg) {
* string-hash computed over the name.
*/
-#include <stddef.h>
-
#include <linux/fs.h>
#include <linux/string.h>
struct dir_cache_entry * next_lru, * prev_lru;
};
+#define dcache_offset(x) ((unsigned long)&((struct dir_cache_entry*)0)->x)
+#define dcache_datalen (dcache_offset(lru_head) - dcache_offset(dc_dev))
+
#define COPYDATA(de, newde) \
-memcpy((void *) &newde->dc_dev, (void *) &de->dc_dev, \
-sizeof(kdev_t) + 3*sizeof(unsigned long) + 1 + DCACHE_NAME_LEN)
+memcpy((void *) &newde->dc_dev, (void *) &de->dc_dev, dcache_datalen)
static struct dir_cache_entry level1_cache[DCACHE_SIZE];
static struct dir_cache_entry level2_cache[DCACHE_SIZE];
* The hash-queues are also doubly-linked circular lists, but the head is
* itself on the doubly-linked list, not just a pointer to the first entry.
*/
-#define DCACHE_HASH_QUEUES 19
+#define DCACHE_HASH_QUEUES 32
#define hash_fn(dev,dir,namehash) ((HASHDEV(dev) ^ (dir) ^ (namehash)) % DCACHE_HASH_QUEUES)
static struct hash_list hash_table[DCACHE_HASH_QUEUES];
static inline void remove_lru(struct dir_cache_entry * de)
{
- de->next_lru->prev_lru = de->prev_lru;
- de->prev_lru->next_lru = de->next_lru;
+ struct dir_cache_entry * next = de->next_lru;
+ struct dir_cache_entry * prev = de->prev_lru;
+
+ next->prev_lru = prev;
+ prev->next_lru = next;
}
static inline void add_lru(struct dir_cache_entry * de, struct dir_cache_entry *head)
{
+ struct dir_cache_entry * prev = head->prev_lru;
+
de->next_lru = head;
- de->prev_lru = head->prev_lru;
- de->prev_lru->next_lru = de;
+ de->prev_lru = prev;
+ prev->next_lru = de;
head->prev_lru = de;
}
*/
static inline unsigned long namehash(const char * name, int len)
{
- return len * *(const unsigned char *) name;
+ return len +
+ ((const unsigned char *) name)[0]+
+ ((const unsigned char *) name)[len-1];
}
/*
*/
static inline void remove_hash(struct dir_cache_entry * de)
{
- if (de->h.next) {
- de->h.next->h.prev = de->h.prev;
- de->h.prev->h.next = de->h.next;
+ struct dir_cache_entry * next = de->h.next;
+
+ if (next) {
+ struct dir_cache_entry * prev = de->h.prev;
+ next->h.prev = prev;
+ prev->h.next = next;
de->h.next = NULL;
}
}
static inline void add_hash(struct dir_cache_entry * de, struct hash_list * hash)
{
- de->h.next = hash->next;
+ struct dir_cache_entry * next = hash->next;
+ de->h.next = next;
de->h.prev = (struct dir_cache_entry *) hash;
- hash->next->h.prev = de;
+ next->h.prev = de;
hash->next = de;
}
if (*vpnt) return 0;
switch(*this_char) {
case 'b':
- if (ivalue != 1024 && ivalue != 2048) return 0;
+ if ( ivalue != 512
+ && ivalue != 1024
+ && ivalue != 2048) return 0;
popt->blocksize = ivalue;
break;
case 'u':
int high_sierra;
kdev_t dev = s->s_dev;
unsigned int vol_desc_start;
+ int orig_zonesize;
struct iso_volume_descriptor *vdp;
struct hs_volume_descriptor *hdp;
/* RDE: convert log zone size to bit shift */
+ orig_zonesize = s -> u.isofs_sb.s_log_zone_size;
switch (s -> u.isofs_sb.s_log_zone_size)
{ case 512: s -> u.isofs_sb.s_log_zone_size = 9; break;
case 1024: s -> u.isofs_sb.s_log_zone_size = 10; break;
/* RDE: data zone now byte offset! */
- s->u.isofs_sb.s_firstdatazone = (isonum_733( rootp->extent)
+ s->u.isofs_sb.s_firstdatazone = ((isonum_733 (rootp->extent) +
+ isonum_711 (rootp->ext_attr_length))
<< s -> u.isofs_sb.s_log_zone_size);
s->s_magic = ISOFS_SUPER_MAGIC;
1UL << s->u.isofs_sb.s_log_zone_size);
printk(KERN_DEBUG "First datazone:%ld Root inode number %d\n",
s->u.isofs_sb.s_firstdatazone >> s -> u.isofs_sb.s_log_zone_size,
- isonum_733 (rootp->extent) << s -> u.isofs_sb.s_log_zone_size);
+ (isonum_733(rootp->extent) + isonum_711(rootp->ext_attr_length))
+ << s -> u.isofs_sb.s_log_zone_size);
if(high_sierra) printk(KERN_DEBUG "Disc in High Sierra format.\n");
unlock_super(s);
/* set up enough so that it can read an inode */
+ /*
+ * Force the blocksize to 512 for 512 byte sectors. The file
+ * read primitives really get it wrong in a bad way if we don't
+ * do this.
+ */
+ if( orig_zonesize < opt.blocksize )
+ {
+ opt.blocksize = orig_zonesize;
+ blocksize_bits = 0;
+ {
+ int i = opt.blocksize;
+ while (i != 1){
+ blocksize_bits++;
+ i >>=1;
+ }
+ }
+ set_blocksize(dev, opt.blocksize);
+ printk(KERN_DEBUG "Forcing new log zone size:%d\n", opt.blocksize);
+ }
+
s->s_dev = dev;
s->s_op = &isofs_sops;
s->u.isofs_sb.s_mapping = opt.map;
s->u.isofs_sb.s_mode = opt.mode & 0777;
s->s_blocksize = opt.blocksize;
s->s_blocksize_bits = blocksize_bits;
- s->s_mounted = iget(s, isonum_733 (rootp->extent) << s -> u.isofs_sb.s_log_zone_size);
+ s->s_mounted = iget(s, (isonum_733(rootp->extent) +
+ isonum_711(rootp->ext_attr_length))
+ << s -> u.isofs_sb.s_log_zone_size);
unlock_super(s);
if (!(s->s_mounted)) {
struct ncp_fs_info info;
struct ncp_server *server = NCP_SERVER(inode);
+ /*
+ * Binary compatible with 1.3.XX releases.
+ * Take this out in 2.1.0 development series.
+ * <mec@duracef.shout.net> 12 Mar 1996
+ */
+ switch(cmd) {
+ case _IOR('n', 1, unsigned char *):
+ cmd = NCP_IOC_NCPREQUEST;
+ break;
+ case _IOR('u', 1, uid_t):
+ cmd = NCP_IOC_GETMOUNTUID;
+ break;
+ case _IO('l', 1):
+ cmd = NCP_IOC_CONN_LOGGED_IN;
+ break;
+ case _IOWR('i', 1, unsigned char *):
+ cmd = NCP_IOC_GET_FS_INFO;
+ break;
+ }
+
switch(cmd) {
case NCP_IOC_NCPREQUEST:
return -EINVAL;
}
- info.addr = server->m.serv_addr;
- info.mounted_uid = server->m.mounted_uid;
- info.connection = server->connection;
- info.buffer_size = server->buffer_size;
+ info.addr = server->m.serv_addr;
+ info.mounted_uid = server->m.mounted_uid;
+ info.connection = server->connection;
+ info.buffer_size = server->buffer_size;
+ info.volume_number = NCP_ISTRUCT(inode)->volNumber;
+ info.directory_id = NCP_ISTRUCT(inode)->DosDirNum;
memcpy_tofs((struct ncp_fs_info *)arg, &info, sizeof(info));
return 0;
ncp_add_byte(server, 0);
ncp_add_mem(server, file_id, 6);
- if ((result = ncp_request(server, 66)) != 0)
- {
- ncp_unlock_server(server);
- return result;
- }
-
+ result = ncp_request(server, 66);
ncp_unlock_server(server);
- return 0;
+ return result;
}
static void
ncp_add_handle_path(server, file->volNumber,
file->DosDirNum, 1, NULL);
- if ((result = ncp_request(server, 87)) != 0)
- {
- ncp_unlock_server(server);
- return result;
- }
-
+ result = ncp_request(server, 87);
ncp_unlock_server(server);
- return 0;
+ return result;
}
int
ncp_add_handle_path(server, dir->volNumber,
dir->DosDirNum, 1, name);
- if ((result = ncp_request(server, 87)) != 0)
- {
- ncp_unlock_server(server);
- return result;
- }
-
+ result = ncp_request(server, 87);
ncp_unlock_server(server);
- return 0;
+ return result;
}
static inline void
* The way this works is that the mount process passes a structure
* in the data argument which contains an open socket to the NFS
* server and the root file handle obtained from the server's mount
- * daemon. We stash theses away in the private superblock fields.
+ * daemon. We stash these away in the private superblock fields.
* Later we can add other mount parameters like caching values.
*/
sock->ops->getname(sock, &(server->toaddr), &dummylen, 1) ;
}
} else {
- /* printk("NFS: coppying passed addr to server->toaddr\n") ;*/
+ /* printk("NFS: copying passed addr to server->toaddr\n") ;*/
memcpy((char *)&(server->toaddr),(char *)(&data->addr),sizeof(server->toaddr));
}
/* End of JSP NFS patch */
struct vfsmount *vfsmnt;
int error;
+ if (!(flags & MS_RDONLY) && dev && is_read_only(dev))
+ return -EACCES;
+ /*flags |= MS_RDONLY;*/
error = namei(dir_name, &dir_i);
if (error)
return error;
static int do_remount_sb(struct super_block *sb, int flags, char *data)
{
int retval;
+ struct vfsmount *vfsmnt;
if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
return -EACCES;
}
sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
(flags & MS_RMT_MASK);
+ vfsmnt = lookup_vfsmnt(sb->s_dev);
+ if (vfsmnt)
+ vfsmnt->mnt_flags = sb->s_flags;
return 0;
}
in UMSDOS. EPERM is returned for other user.
*/
/*
- Well, not all case require write access, but it simplify the code
- and let's face it, there is only one client (umssync) for all this
+ Well, not all cases require write access, but it simplifies
+ the code, and let's face it, there is only one client (umssync)
+ for all this.
*/
if ((err = verify_area(VERIFY_WRITE,(void*)data,sizeof(struct umsdos_ioctl))) < 0) {
ret = err;
* Data structure for handling APECS machine checks:
*/
struct el_apecs_sysdata_mcheck {
- u_long coma_gcr;
- u_long coma_edsr;
- u_long coma_ter;
- u_long coma_elar;
- u_long coma_ehar;
- u_long coma_ldlr;
- u_long coma_ldhr;
- u_long coma_base0;
- u_long coma_base1;
- u_long coma_base2;
- u_long coma_cnfg0;
- u_long coma_cnfg1;
- u_long coma_cnfg2;
- u_long epic_dcsr;
- u_long epic_pear;
- u_long epic_sear;
- u_long epic_tbr1;
- u_long epic_tbr2;
- u_long epic_pbr1;
- u_long epic_pbr2;
- u_long epic_pmr1;
- u_long epic_pmr2;
- u_long epic_harx1;
- u_long epic_harx2;
- u_long epic_pmlt;
- u_long epic_tag0;
- u_long epic_tag1;
- u_long epic_tag2;
- u_long epic_tag3;
- u_long epic_tag4;
- u_long epic_tag5;
- u_long epic_tag6;
- u_long epic_tag7;
- u_long epic_data0;
- u_long epic_data1;
- u_long epic_data2;
- u_long epic_data3;
- u_long epic_data4;
- u_long epic_data5;
- u_long epic_data6;
- u_long epic_data7;
+ unsigned long coma_gcr;
+ unsigned long coma_edsr;
+ unsigned long coma_ter;
+ unsigned long coma_elar;
+ unsigned long coma_ehar;
+ unsigned long coma_ldlr;
+ unsigned long coma_ldhr;
+ unsigned long coma_base0;
+ unsigned long coma_base1;
+ unsigned long coma_base2;
+ unsigned long coma_cnfg0;
+ unsigned long coma_cnfg1;
+ unsigned long coma_cnfg2;
+ unsigned long epic_dcsr;
+ unsigned long epic_pear;
+ unsigned long epic_sear;
+ unsigned long epic_tbr1;
+ unsigned long epic_tbr2;
+ unsigned long epic_pbr1;
+ unsigned long epic_pbr2;
+ unsigned long epic_pmr1;
+ unsigned long epic_pmr2;
+ unsigned long epic_harx1;
+ unsigned long epic_harx2;
+ unsigned long epic_pmlt;
+ unsigned long epic_tag0;
+ unsigned long epic_tag1;
+ unsigned long epic_tag2;
+ unsigned long epic_tag3;
+ unsigned long epic_tag4;
+ unsigned long epic_tag5;
+ unsigned long epic_tag6;
+ unsigned long epic_tag7;
+ unsigned long epic_data0;
+ unsigned long epic_data1;
+ unsigned long epic_data2;
+ unsigned long epic_data3;
+ unsigned long epic_data4;
+ unsigned long epic_data5;
+ unsigned long epic_data6;
+ unsigned long epic_data7;
};
#define RTC_PORT(x) (0x70 + (x))
-#ifndef __ARCH_I386_ATOMIC__
-#define __ARCH_I386_ATOMIC__
+#ifndef __ARCH_ALPHA_ATOMIC__
+#define __ARCH_ALPHA_ATOMIC__
/*
* Atomic operations that C can't guarantee us. Useful for
- * resource counting etc..
+ * resource counting etc...
+ *
+ * But use these as seldom as possible since they are much more slower
+ * than regular operations.
*/
/*
#define _IOC_WRITE 4U
#define _IOC(dir,type,nr,size) \
- ((__u32) \
+ ((unsigned int) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
-#endif
+#endif /* _ALPHA_IOCTL_H */
--- /dev/null
+#ifndef _ASM_ALPHA_IOCTLS_H
+#define _ASM_ALPHA_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+#define FIOCLEX _IO('f', 1)
+#define FIONCLEX _IO('f', 2)
+#define FIOASYNC _IOW('f', 125, int)
+#define FIONBIO _IOW('f', 126, int)
+#define FIONREAD _IOR('f', 127, int)
+#define TIOCINQ FIONREAD
+
+#define TIOCGETP _IOR('t', 8, struct sgttyb)
+#define TIOCSETP _IOW('t', 9, struct sgttyb)
+#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */
+
+#define TIOCSETC _IOW('t', 17, struct tchars)
+#define TIOCGETC _IOR('t', 18, struct tchars)
+#define TCGETS _IOR('t', 19, struct termios)
+#define TCSETS _IOW('t', 20, struct termios)
+#define TCSETSW _IOW('t', 21, struct termios)
+#define TCSETSF _IOW('t', 22, struct termios)
+
+#define TCGETA _IOR('t', 23, struct termio)
+#define TCSETA _IOW('t', 24, struct termio)
+#define TCSETAW _IOW('t', 25, struct termio)
+#define TCSETAF _IOW('t', 28, struct termio)
+
+#define TCSBRK _IO('t', 29)
+#define TCXONC _IO('t', 30)
+#define TCFLSH _IO('t', 31)
+
+#define TIOCSWINSZ _IOW('t', 103, struct winsize)
+#define TIOCGWINSZ _IOR('t', 104, struct winsize)
+#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
+#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
+#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
+
+#define TIOCGLTC _IOR('t', 116, struct ltchars)
+#define TIOCSLTC _IOW('t', 117, struct ltchars)
+#define TIOCSPGRP _IOW('t', 118, int)
+#define TIOCGPGRP _IOR('t', 119, int)
+
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+
+#define TIOCSTI 0x5412
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+# define TIOCM_LE 0x001
+# define TIOCM_DTR 0x002
+# define TIOCM_RTS 0x004
+# define TIOCM_ST 0x008
+# define TIOCM_SR 0x010
+# define TIOCM_CTS 0x020
+# define TIOCM_CAR 0x040
+# define TIOCM_RNG 0x080
+# define TIOCM_DSR 0x100
+# define TIOCM_CD TIOCM_CAR
+# define TIOCM_RI TIOCM_RNG
+
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+# define TIOCPKT_DATA 0
+# define TIOCPKT_FLUSHREAD 1
+# define TIOCPKT_FLUSHWRITE 2
+# define TIOCPKT_STOP 4
+# define TIOCPKT_START 8
+# define TIOCPKT_NOSTOP 16
+# define TIOCPKT_DOSTOP 32
+
+
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
+
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
+#define TIOCSERGETLSR 0x5459 /* Get line status register */
+ /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
+
+#endif /* _ASM_ALPHA_IOCTLS_H */
-#ifndef _ASMAXP_PARAM_H
-#define _ASMAXP_PARAM_H
-
-#include <linux/config.h>
+#ifndef _ASM_ALPHA_PARAM_H
+#define _ASM_ALPHA_PARAM_H
#ifndef HZ
-# if defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB66P)
-# define HZ 977 /* Evaluation Boards seem to be a little odd */
-# else
-# define HZ 1024 /* normal value for Alpha systems */
-# endif
+# define HZ 1024
#endif
#define EXEC_PAGESIZE 8192
#define MAXHOSTNAMELEN 64 /* max length of hostname */
-#endif
+#endif /* _ASM_ALPHA_PARAM_H */
--- /dev/null
+#ifndef _ALPHA_POSIX_TYPES_H
+#define _ALPHA_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc. Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned int __dev_t;
+typedef unsigned int __ino_t;
+typedef unsigned int __mode_t;
+typedef unsigned short __nlink_t;
+typedef long __off_t;
+typedef int __pid_t;
+typedef unsigned int __uid_t;
+typedef unsigned int __gid_t;
+typedef unsigned long __size_t;
+typedef long __ssize_t;
+typedef long __ptrdiff_t;
+typedef long __time_t;
+typedef long __clock_t;
+typedef int __daddr_t;
+typedef char * __caddr_t;
+
+typedef struct {
+ int val[2];
+} __fsid_t;
+
+#ifndef __GNUC__
+
+#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+#define __FD_ZERO(set) \
+ ((void) memset ((__ptr_t) (set), 0, sizeof (__fd_set)))
+
+#else /* __GNUC__ */
+
+/* With GNU C, use inline functions instead so args are evaluated only once: */
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, __fd_set *fdsetp)
+{
+ unsigned long _tmp = fd / __NFDBITS;
+ unsigned long _rem = fd % __NFDBITS;
+ fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long fd, __fd_set *fdsetp)
+{
+ unsigned long _tmp = fd / __NFDBITS;
+ unsigned long _rem = fd % __NFDBITS;
+ fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long fd, __fd_set *p)
+{
+ unsigned long _tmp = fd / __NFDBITS;
+ unsigned long _rem = fd % __NFDBITS;
+ return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__fd_set *p)
+{
+ unsigned int *tmp = p->fds_bits;
+ int i;
+
+ if (__builtin_constant_p(__FDSET_INTS)) {
+ switch (__FDSET_INTS) {
+ case 8:
+ tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
+ tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
+ return;
+ }
+ }
+ i = __FDSET_INTS;
+ while (i) {
+ i--;
+ *tmp = 0;
+ tmp++;
+ }
+}
+
+#endif /* __GNUC__ */
+
+#endif /* _ALPHA_POSIX_TYPES_H */
#include <linux/types.h>
#include <asm/ioctl.h>
-
-/* Socket-level I/O control calls. */
-#define FIOGETOWN _IOR('f', 123, int)
-#define FIOSETOWN _IOW('f', 124, int)
-
-#define SIOCATMARK _IOR('s', 7, int)
-#define SIOCSPGRP _IOW('s', 8, pid_t)
-#define SIOCGPGRP _IOR('s', 9, pid_t)
-
-#define SIOCGSTAMP 0x8906 /* Get stamp - linux-specific */
+#include <asm/sockios.h>
/* For setsockoptions(2) */
/*
--- /dev/null
+#ifndef _ASM_ALPHA_SOCKIOS_H
+#define _ASM_ALPHA_SOCKIOS_H
+
+/* Socket-level I/O control calls. */
+
+#define FIOGETOWN _IOR('f', 123, int)
+#define FIOSETOWN _IOW('f', 124, int)
+
+#define SIOCATMARK _IOR('s', 7, int)
+#define SIOCSPGRP _IOW('s', 8, pid_t)
+#define SIOCGPGRP _IOR('s', 9, pid_t)
+
+#define SIOCGSTAMP 0x8906 /* Get stamp - linux-specific */
+
+#endif /* _ASM_ALPHA_SOCKIOS_H */
#ifndef _ALPHA_STATFS_H
#define _ALPHA_STATFS_H
-typedef struct {
- int val[2];
-} fsid_t;
+#ifndef _LINUX_TYPES_DONT_EXPORT
+
+#include <linux/posix_types.h>
+
+typedef __fsid_t fsid_t;
+
+#endif
/*
* The OSF/1 statfs structure is much larger, but this should
int f_bavail;
int f_files;
int f_ffree;
- fsid_t f_fsid;
+ __fsid_t f_fsid;
/* linux-specific entries start here.. */
int f_namelen;
};
--- /dev/null
+#ifndef _ALPHA_TERMBITS_H
+#define _ALPHA_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+/*
+ * termios type and macro definitions. Be careful about adding stuff
+ * to this file since it's used in GNU libc and there are strict rules
+ * concerning namespace pollution.
+ */
+
+#define NCCS 19
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_cc[NCCS]; /* control characters */
+ cc_t c_line; /* line discipline (== c_cc[19]) */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+/* c_cc characters */
+#define VEOF 0
+#define VEOL 1
+#define VEOL2 2
+#define VERASE 3
+#define VWERASE 4
+#define VKILL 5
+#define VREPRINT 6
+#define VSWTC 7
+#define VINTR 8
+#define VQUIT 9
+#define VSUSP 10
+#define VSTART 12
+#define VSTOP 13
+#define VLNEXT 14
+#define VDISCARD 15
+#define VMIN 16
+#define VTIME 17
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IXON 0001000
+#define IXOFF 0002000
+#if !defined(KERNEL) || defined(__USE_BSD)
+ /* POSIX.1 doesn't want these... */
+# define IXANY 0004000
+# define IUCLC 0010000
+# define IMAXBEL 0020000
+#endif
+
+/* c_oflag bits */
+#define OPOST 0000001
+#define ONLCR 0000002
+#define OLCUC 0000004
+
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+
+#define OFILL 00000100
+#define OFDEL 00000200
+#define NLDLY 00001400
+#define NL0 00000000
+#define NL1 00000400
+#define NL2 00001000
+#define NL3 00001400
+#define TABDLY 00006000
+#define TAB0 00000000
+#define TAB1 00002000
+#define TAB2 00004000
+#define TAB3 00006000
+#define CRDLY 00030000
+#define CR0 00000000
+#define CR1 00010000
+#define CR2 00020000
+#define CR3 00030000
+#define FFDLY 00040000
+#define FF0 00000000
+#define FF1 00040000
+#define BSDLY 00100000
+#define BS0 00000000
+#define BS1 00100000
+#define VTDLY 00200000
+#define VT0 00000000
+#define VT1 00200000
+#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
+
+/* c_cflag bit meaning */
+#define CBAUD 0000017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CBAUDEX 0000020
+#define B57600 00020
+#define B115200 00021
+#define B230400 00022
+
+#define CSIZE 00001400
+#define CS5 00000000
+#define CS6 00000400
+#define CS7 00001000
+#define CS8 00001400
+
+#define CSTOPB 00002000
+#define CREAD 00004000
+#define PARENB 00010000
+#define PARODD 00020000
+#define HUPCL 00040000
+
+#define CLOCAL 00100000
+#define CRTSCTS 020000000000 /* flow control */
+
+/* c_lflag bits */
+#define ISIG 0x00000080
+#define ICANON 0x00000100
+#define XCASE 0x00004000
+#define ECHO 0x00000008
+#define ECHOE 0x00000002
+#define ECHOK 0x00000004
+#define ECHONL 0x00000010
+#define NOFLSH 0x80000000
+#define TOSTOP 0x00400000
+#define ECHOCTL 0x00000040
+#define ECHOPRT 0x00000020
+#define ECHOKE 0x00000001
+#define FLUSHO 0x00800000
+#define PENDIN 0x20000000
+#define IEXTEN 0x00000400
+
+/* Values for the ACTION argument to `tcflow'. */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* Values for the QUEUE_SELECTOR argument to `tcflush'. */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#endif /* _ALPHA_TERMBITS_H */
#ifndef _ALPHA_TERMIOS_H
#define _ALPHA_TERMIOS_H
-#include <linux/types.h>
-
-#include <asm/ioctl.h>
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
struct sgttyb {
char sg_ispeed;
char t_lnextc;
};
-#define FIOCLEX _IO('f', 1)
-#define FIONCLEX _IO('f', 2)
-#define FIOASYNC _IOW('f', 125, int)
-#define FIONBIO _IOW('f', 126, int)
-#define FIONREAD _IOR('f', 127, int)
-#define TIOCINQ FIONREAD
-
-#define TIOCGETP _IOR('t', 8, struct sgttyb)
-#define TIOCSETP _IOW('t', 9, struct sgttyb)
-#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */
-
-#define TIOCSETC _IOW('t', 17, struct tchars)
-#define TIOCGETC _IOR('t', 18, struct tchars)
-#define TCGETS _IOR('t', 19, struct termios)
-#define TCSETS _IOW('t', 20, struct termios)
-#define TCSETSW _IOW('t', 21, struct termios)
-#define TCSETSF _IOW('t', 22, struct termios)
-
-#define TCGETA _IOR('t', 23, struct termio)
-#define TCSETA _IOW('t', 24, struct termio)
-#define TCSETAW _IOW('t', 25, struct termio)
-#define TCSETAF _IOW('t', 28, struct termio)
-
-#define TCSBRK _IO('t', 29)
-#define TCXONC _IO('t', 30)
-#define TCFLSH _IO('t', 31)
-
-#define TIOCSWINSZ _IOW('t', 103, struct winsize)
-#define TIOCGWINSZ _IOR('t', 104, struct winsize)
-#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
-#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
-#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
-
-#define TIOCGLTC _IOR('t', 116, struct ltchars)
-#define TIOCSLTC _IOW('t', 117, struct ltchars)
-#define TIOCSPGRP _IOW('t', 118, int)
-#define TIOCGPGRP _IOR('t', 119, int)
-
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-
-#define TIOCSTI 0x5412
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
-
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-
struct winsize {
unsigned short ws_row;
unsigned short ws_col;
unsigned char c_cc[NCC]; /* control characters */
};
-#define NCCS 19
-struct termios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_cc[NCCS]; /* control characters */
- cc_t c_line; /* line discipline (== c_cc[19]) */
- int c_ispeed; /* input speed */
- int c_ospeed; /* output speed */
-};
-
-/* c_cc characters */
-#define VEOF 0
-#define VEOL 1
-#define VEOL2 2
-#define VERASE 3
-#define VWERASE 4
-#define VKILL 5
-#define VREPRINT 6
-#define VSWTC 7
-#define VINTR 8
-#define VQUIT 9
-#define VSUSP 10
-#define VSTART 12
-#define VSTOP 13
-#define VLNEXT 14
-#define VDISCARD 15
-#define VMIN 16
-#define VTIME 17
-
/*
- * ..and the same for c_cc in the termio structure..
- * Oh, how I love being backwardly compatible.
+ * c_cc characters in the termio structure. Oh, how I love being
+ * backwardly compatible. Notice that character 4 and 5 are
+ * interpreted differently depending on whether ICANON is set in
+ * c_lflag. If it's set, they are used as _VEOF and _VEOL, otherwise
+ * as _VMIN and V_TIME. This is for compatibility with OSF/1 (which
+ * is compatible with sysV)...
*/
#define _VINTR 0
#define _VQUIT 1
#define _VEOL2 6
#define _VSWTC 7
+/* line disciplines */
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+
#ifdef __KERNEL__
/* eof=^D eol=\0 eol2=\0 erase=del
werase=^W kill=^U reprint=^R sxtc=\0
vmin=\1 vtime=\0
*/
#define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000"
-#endif
-
-/* c_iflag bits */
-#define IGNBRK 0000001
-#define BRKINT 0000002
-#define IGNPAR 0000004
-#define PARMRK 0000010
-#define INPCK 0000020
-#define ISTRIP 0000040
-#define INLCR 0000100
-#define IGNCR 0000200
-#define ICRNL 0000400
-#define IXON 0001000
-#define IXOFF 0002000
-#define IXANY 0004000
-#define IUCLC 0010000
-#define IMAXBEL 0020000
-
-/* c_oflag bits */
-#define OPOST 0000001
-#define ONLCR 0000002
-#define OLCUC 0000004
-
-#define OCRNL 0000010
-#define ONOCR 0000020
-#define ONLRET 0000040
-
-#define OFILL 00000100
-#define OFDEL 00000200
-#define NLDLY 00001400
-#define NL0 00000000
-#define NL1 00000400
-#define NL2 00001000
-#define NL3 00001400
-#define TABDLY 00006000
-#define TAB0 00000000
-#define TAB1 00002000
-#define TAB2 00004000
-#define TAB3 00006000
-#define CRDLY 00030000
-#define CR0 00000000
-#define CR1 00010000
-#define CR2 00020000
-#define CR3 00030000
-#define FFDLY 00040000
-#define FF0 00000000
-#define FF1 00040000
-#define BSDLY 00100000
-#define BS0 00000000
-#define BS1 00100000
-#define VTDLY 00200000
-#define VT0 00000000
-#define VT1 00200000
-#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
-
-/* c_cflag bit meaning */
-#define CBAUD 0000017
-#define B0 0000000 /* hang up */
-#define B50 0000001
-#define B75 0000002
-#define B110 0000003
-#define B134 0000004
-#define B150 0000005
-#define B200 0000006
-#define B300 0000007
-#define B600 0000010
-#define B1200 0000011
-#define B1800 0000012
-#define B2400 0000013
-#define B4800 0000014
-#define B9600 0000015
-#define B19200 0000016
-#define B38400 0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CBAUDEX 0000020
-#define B57600 00020
-#define B115200 00021
-#define B230400 00022
-
-#define CSIZE 00001400
-#define CS5 00000000
-#define CS6 00000400
-#define CS7 00001000
-#define CS8 00001400
-
-#define CSTOPB 00002000
-#define CREAD 00004000
-#define PARENB 00010000
-#define PARODD 00020000
-#define HUPCL 00040000
-
-#define CLOCAL 00100000
-#define CRTSCTS 020000000000 /* flow control */
-
-/* c_lflag bits */
-#define ISIG 0x00000080
-#define ICANON 0x00000100
-#define XCASE 0x00004000
-#define ECHO 0x00000008
-#define ECHOE 0x00000002
-#define ECHOK 0x00000004
-#define ECHONL 0x00000010
-#define NOFLSH 0x80000000
-#define TOSTOP 0x00400000
-#define ECHOCTL 0x00000040
-#define ECHOPRT 0x00000020
-#define ECHOKE 0x00000001
-#define FLUSHO 0x00800000
-#define PENDIN 0x20000000
-#define IEXTEN 0x00000400
-
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
-
-/* tcflow() and TCXONC use these */
-#define TCOOFF 0
-#define TCOON 1
-#define TCIOFF 2
-#define TCION 3
-
-/* tcflush() and TCFLSH use these */
-#define TCIFLUSH 0
-#define TCOFLUSH 1
-#define TCIOFLUSH 2
-
-/* tcsetattr uses these */
-#define TCSANOW 0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-/* line disciplines */
-#define N_TTY 0
-#define N_SLIP 1
-#define N_MOUSE 2
-#define N_PPP 3
-
-#ifdef __KERNEL__
/*
* Translate a "termio" structure into a "termios". Ugh.
#ifndef _ALPHA_TYPES_H
#define _ALPHA_TYPES_H
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned long size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef long ssize_t;
-#endif
-
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef long ptrdiff_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue. However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
-typedef int pid_t;
-typedef unsigned int uid_t;
-typedef unsigned int gid_t;
-typedef unsigned int dev_t;
-typedef unsigned int ino_t;
-typedef unsigned int mode_t;
typedef unsigned int umode_t;
-typedef unsigned short nlink_t;
-typedef int daddr_t;
-typedef long off_t;
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
#endif
#endif /* __KERNEL__ */
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, fd_set *fdsetp)
-{
- unsigned long _tmp = fd / __NFDBITS;
- unsigned long _rem = fd % __NFDBITS;
- fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, fd_set *fdsetp)
-{
- unsigned long _tmp = fd / __NFDBITS;
- unsigned long _rem = fd % __NFDBITS;
- fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, fd_set *p)
-{
- unsigned long _tmp = fd / __NFDBITS;
- unsigned long _rem = fd % __NFDBITS;
- return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(fd_set *p)
-{
- unsigned int *tmp = p->fds_bits;
- int i;
-
- if (__builtin_constant_p(__FDSET_INTS)) {
- switch (__FDSET_INTS) {
- case 8:
- tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
- tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
- return;
- }
- }
- i = __FDSET_INTS;
- while (i) {
- i--;
- *tmp = 0;
- tmp++;
- }
-}
-
-#endif
+#endif /* _ALPHA_TYPES_H */
--- /dev/null
+#ifndef __ARCH_I386_IOCTLS_H__
+#define __ARCH_I386_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402
+#define TCSETSW 0x5403
+#define TCSETSF 0x5404
+#define TCGETA 0x5405
+#define TCSETA 0x5406
+#define TCSETAW 0x5407
+#define TCSETAF 0x5408
+#define TCSBRK 0x5409
+#define TCXONC 0x540A
+#define TCFLSH 0x540B
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+#define TIOCGPGRP 0x540F
+#define TIOCSPGRP 0x5410
+#define TIOCOUTQ 0x5411
+#define TIOCSTI 0x5412
+#define TIOCGWINSZ 0x5413
+#define TIOCSWINSZ 0x5414
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define FIONREAD 0x541B
+#define TIOCINQ FIONREAD
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
+#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
+#define FIOCLEX 0x5451
+#define FIOASYNC 0x5452
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
+#define TIOCSERGETLSR 0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
+
+/* Used for packet mode */
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
+#endif
--- /dev/null
+#ifndef __ARCH_I386_POSIX_TYPES_H
+#define __ARCH_I386_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc. Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned short __dev_t;
+typedef unsigned long __ino_t;
+typedef unsigned short __mode_t;
+typedef unsigned short __nlink_t;
+typedef long __off_t;
+typedef int __pid_t;
+typedef unsigned short __uid_t;
+typedef unsigned short __gid_t;
+typedef unsigned int __size_t;
+typedef int __ssize_t;
+typedef int __ptrdiff_t;
+typedef long __time_t;
+typedef long __clock_t;
+typedef int __daddr_t;
+typedef char * __caddr_t;
+
+#undef __FD_SET
+#define __FD_SET(fd,fdsetp) \
+ __asm__ __volatile__("btsl %1,%0": \
+ "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
+
+#undef __FD_CLR
+#define __FD_CLR(fd,fdsetp) \
+ __asm__ __volatile__("btrl %1,%0": \
+ "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
+
+#undef __FD_ISSET
+#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \
+ unsigned char __result; \
+ __asm__ __volatile__("btl %1,%2 ; setb %0" \
+ :"=q" (__result) :"r" ((int) (fd)), \
+ "m" (*(fd_set *) (fdsetp))); \
+ __result; }))
+
+#undef __FD_ZERO
+#define __FD_ZERO(fdsetp) \
+ __asm__ __volatile__("cld ; rep ; stosl" \
+ :"=m" (*(fd_set *) (fdsetp)) \
+ :"a" (0), "c" (__FDSET_INTS), \
+ "D" ((fd_set *) (fdsetp)) :"cx","di")
+
+#endif
*/
extern int smp_found_config;
-extern void smp_scan_config(unsigned long, unsigned long);
+extern int smp_scan_config(unsigned long, unsigned long);
extern unsigned long smp_alloc_memory(unsigned long mem_base);
extern unsigned char *apic_reg;
extern unsigned char *kernel_stacks[NR_CPUS];
extern unsigned char boot_cpu_id;
extern unsigned long cpu_present_map;
extern volatile int cpu_number_map[NR_CPUS];
+extern volatile int cpu_logical_map[NR_CPUS];
extern volatile unsigned long smp_invalidate_needed;
extern void smp_invalidate(void);
extern volatile unsigned long kernel_flag, kernel_counter;
#ifndef _ASM_SOCKET_H
#define _ASM_SOCKET_H
-/* Socket-level I/O control calls. */
-#define FIOSETOWN 0x8901
-#define SIOCSPGRP 0x8902
-#define FIOGETOWN 0x8903
-#define SIOCGPGRP 0x8904
-#define SIOCATMARK 0x8905
-#define SIOCGSTAMP 0x8906 /* Get stamp */
+#include <asm/sockios.h>
/* For setsockoptions(2) */
#define SOL_SOCKET 1
--- /dev/null
+#ifndef __ARCH_I386_SOCKIOS__
+#define __ARCH_I386_SOCKIOS__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906 /* Get stamp */
+
+#endif
case 4:
*(unsigned long *)to = *(const unsigned long *)from;
return to;
+ case 8:
+ *(unsigned long *)to = *(const unsigned long *)from;
+ *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+ return to;
}
#define COMMON(x) \
__asm__("cld\n\t" \
--- /dev/null
+#ifndef __ARCH_I386_TERMBITS_H__
+#define __ARCH_I386_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 19
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+
+/* c_oflag bits */
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+/* c_cflag bit meaning */
+#define CBAUD 0010017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define CIBAUD 002003600000 /* input baud rate (not used) */
+#define CRTSCTS 020000000000 /* flow control */
+
+/* c_lflag bits */
+#define ISIG 0000001
+#define ICANON 0000002
+#define XCASE 0000004
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#endif
#ifndef _I386_TERMIOS_H
#define _I386_TERMIOS_H
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
-#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
struct winsize {
unsigned short ws_row;
unsigned char c_cc[NCC]; /* control characters */
};
-#define NCCS 19
-struct termios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
-};
-
-/* c_cc characters */
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VTIME 5
-#define VMIN 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-#define VSUSP 10
-#define VEOL 11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-#define VEOL2 16
-
#ifdef __KERNEL__
/* intr=^C quit=^\ erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
#endif
-/* c_iflag bits */
-#define IGNBRK 0000001
-#define BRKINT 0000002
-#define IGNPAR 0000004
-#define PARMRK 0000010
-#define INPCK 0000020
-#define ISTRIP 0000040
-#define INLCR 0000100
-#define IGNCR 0000200
-#define ICRNL 0000400
-#define IUCLC 0001000
-#define IXON 0002000
-#define IXANY 0004000
-#define IXOFF 0010000
-#define IMAXBEL 0020000
-
-/* c_oflag bits */
-#define OPOST 0000001
-#define OLCUC 0000002
-#define ONLCR 0000004
-#define OCRNL 0000010
-#define ONOCR 0000020
-#define ONLRET 0000040
-#define OFILL 0000100
-#define OFDEL 0000200
-#define NLDLY 0000400
-#define NL0 0000000
-#define NL1 0000400
-#define CRDLY 0003000
-#define CR0 0000000
-#define CR1 0001000
-#define CR2 0002000
-#define CR3 0003000
-#define TABDLY 0014000
-#define TAB0 0000000
-#define TAB1 0004000
-#define TAB2 0010000
-#define TAB3 0014000
-#define XTABS 0014000
-#define BSDLY 0020000
-#define BS0 0000000
-#define BS1 0020000
-#define VTDLY 0040000
-#define VT0 0000000
-#define VT1 0040000
-#define FFDLY 0100000
-#define FF0 0000000
-#define FF1 0100000
-
-/* c_cflag bit meaning */
-#define CBAUD 0010017
-#define B0 0000000 /* hang up */
-#define B50 0000001
-#define B75 0000002
-#define B110 0000003
-#define B134 0000004
-#define B150 0000005
-#define B200 0000006
-#define B300 0000007
-#define B600 0000010
-#define B1200 0000011
-#define B1800 0000012
-#define B2400 0000013
-#define B4800 0000014
-#define B9600 0000015
-#define B19200 0000016
-#define B38400 0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE 0000060
-#define CS5 0000000
-#define CS6 0000020
-#define CS7 0000040
-#define CS8 0000060
-#define CSTOPB 0000100
-#define CREAD 0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL 0002000
-#define CLOCAL 0004000
-#define CBAUDEX 0010000
-#define B57600 0010001
-#define B115200 0010002
-#define B230400 0010003
-#define CIBAUD 002003600000 /* input baud rate (not used) */
-#define CRTSCTS 020000000000 /* flow control */
-
-/* c_lflag bits */
-#define ISIG 0000001
-#define ICANON 0000002
-#define XCASE 0000004
-#define ECHO 0000010
-#define ECHOE 0000020
-#define ECHOK 0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-#define IEXTEN 0100000
-
/* modem lines */
#define TIOCM_LE 0x001
#define TIOCM_DTR 0x002
#define TIOCM_RI TIOCM_RNG
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
-
-/* tcflow() and TCXONC use these */
-#define TCOOFF 0
-#define TCOON 1
-#define TCIOFF 2
-#define TCION 3
-
-/* tcflush() and TCFLSH use these */
-#define TCIFLUSH 0
-#define TCOFLUSH 1
-#define TCIOFLUSH 2
-
-/* tcsetattr uses these */
-#define TCSANOW 0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
/* line disciplines */
#define N_TTY 0
extern inline void trans_from_termio(struct termio * termio,
struct termios * termios)
{
-#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y))
+#define SET_LOW_BITS(x,y) (*(unsigned short *)(&x) = (y))
SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
#ifndef _I386_TYPES_H
#define _I386_TYPES_H
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef int ssize_t;
-#endif
-
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef int ptrdiff_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-
-typedef int pid_t;
-typedef unsigned short uid_t;
-typedef unsigned short gid_t;
-typedef unsigned short dev_t;
-typedef unsigned long ino_t;
-typedef unsigned short mode_t;
typedef unsigned short umode_t;
-typedef unsigned short nlink_t;
-typedef int daddr_t;
-typedef long off_t;
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
#endif /* __KERNEL__ */
-#undef __FD_SET
-#define __FD_SET(fd,fdsetp) \
- __asm__ __volatile__("btsl %1,%0": \
- "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef __FD_CLR
-#define __FD_CLR(fd,fdsetp) \
- __asm__ __volatile__("btrl %1,%0": \
- "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef __FD_ISSET
-#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \
- unsigned char __result; \
- __asm__ __volatile__("btl %1,%2 ; setb %0" \
- :"=q" (__result) :"r" ((int) (fd)), \
- "m" (*(fd_set *) (fdsetp))); \
- __result; }))
-
-#undef __FD_ZERO
-#define __FD_ZERO(fdsetp) \
- __asm__ __volatile__("cld ; rep ; stosl" \
- :"=m" (*(fd_set *) (fdsetp)) \
- :"a" (0), "c" (__FDSET_INTS), \
- "D" ((fd_set *) (fdsetp)) :"cx","di")
-
#endif
#define __NR_sched_get_priority_min 160
#define __NR_sched_rr_get_interval 161
#define __NR_nanosleep 162
+#define __NR_mremap 163
/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define _syscall0(type,name) \
extern struct at_addr *atalk_find_dev_addr(struct device *dev);
extern int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr);
extern void aarp_send_probe(struct device *dev, struct at_addr *addr);
+#ifdef MODULE
+extern void aarp_cleanup_module(void);
+#endif
+
#endif
#endif
extern int init_script_binfmt(void);
extern int prepare_binprm(struct linux_binprm *);
+extern void remove_arg_zero(struct linux_binprm *);
extern int search_binary_handler(struct linux_binprm *,struct pt_regs *);
extern void flush_old_exec(struct linux_binprm * bprm);
extern unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm);
#define CURRENT (blk_dev[MAJOR_NR].current_request)
#endif
+#define CURRENT_PLUGGED IS_PLUGGED(blk_dev+MAJOR_NR)
+
#define CURRENT_DEV DEVICE_NR(CURRENT->rq_dev)
#ifdef DEVICE_INTR
#endif
#define INIT_REQUEST \
- if (!CURRENT) {\
+ if (!CURRENT || CURRENT_PLUGGED) {\
CLEAR_INTR; \
return; \
} \
#include <linux/major.h>
#include <linux/sched.h>
#include <linux/genhd.h>
+#include <linux/tqueue.h>
/*
* Ok, this is an expanded form so that we can use the same
struct blk_dev_struct {
void (*request_fn)(void);
struct request * current_request;
+ struct tq_struct plug_tq;
};
+#define IS_PLUGGED(dev) ((dev)->plug_tq.sync)
+
struct sec_size {
unsigned block_size;
unsigned block_size_bits;
extern int register_blkdev(unsigned int, const char *, struct file_operations *);
extern int unregister_blkdev(unsigned int major, const char * name);
extern int blkdev_open(struct inode * inode, struct file * filp);
+extern void blkdev_release (struct inode * inode);
extern struct file_operations def_blk_fops;
extern struct inode_operations blkdev_inode_operations;
* Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source.
* Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Florian La Roche.
+ * Florian La Roche,
+ * Jonathan Layes <layes@loran.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
#define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB */
#define ARPHRD_ARCNET 7 /* ARCnet */
#define ARPHRD_APPLETLK 8 /* APPLEtalk */
+#define ARPHRD_DLCI 15 /* Frame Relay DLCI */
+
/* Dummy types for non ARP hardware */
#define ARPHRD_SLIP 256
#define ARPHRD_CSLIP 257
#define ARPHRD_RSRVD 260 /* Notional KISS type */
#define ARPHRD_ADAPT 264
#define ARPHRD_PPP 512
+
#define ARPHRD_TUNNEL 768 /* IPIP tunnel */
#define ARPHRD_TUNNEL6 769 /* IPIP6 tunnel */
-#define ARPHRD_FRAD 770 /* Frame Relay */
+#define ARPHRD_FRAD 770 /* Frame Relay Access Device */
#define ARPHRD_SKIP 771 /* SKIP vif */
#define ARPHRD_LOOPBACK 772 /* Loopback device */
#define ARPHRD_LOCALTLK 773 /* Localtalk device */
};
+/* Support for the user space arp daemon, arpd */
+
+#define ARPD_UPDATE 0x01
+#define ARPD_LOOKUP 0x02
+
+struct arpd_request
+{
+ unsigned short req; /* request type */
+ __u32 ip; /* ip address of entry */
+ __u32 mask; /* netmask - used for proxy */
+ unsigned char ha[MAX_ADDR_LEN]; /* Hardware address */
+ unsigned long last_used; /* For expiry */
+ unsigned long last_updated; /* For expiry */
+ unsigned int flags; /* Control status */
+ struct device *dev; /* Device entry is tied to */
+ int loc; /* Debugging call location */
+};
+
#endif /* _LINUX_IF_ARP_H */
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+
#ifndef _LINUX_IF_ETHER_H
#define _LINUX_IF_ETHER_H
-/* IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
- and FCS/CRC (frame check sequence). */
+/*
+ * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
+ * and FCS/CRC (frame check sequence).
+ */
+
#define ETH_ALEN 6 /* Octets in one ethernet addr */
#define ETH_HLEN 14 /* Total octets in header. */
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
#define ETH_DATA_LEN 1500 /* Max. octets in payload */
#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
+/*
+ * These are the defined Ethernet Protocol ID's.
+ */
-/* These are the defined Ethernet Protocol ID's. */
#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
#define ETH_P_ECHO 0x0200 /* Ethernet Echo packet */
#define ETH_P_PUP 0x0400 /* Xerox PUP packet */
#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudeo type */
+#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
-/* This is an Ethernet frame header. */
-struct ethhdr {
- unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
- unsigned char h_source[ETH_ALEN]; /* source ether addr */
- unsigned short h_proto; /* packet type ID field */
+/*
+ * This is an Ethernet frame header.
+ */
+
+struct ethhdr
+{
+ unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
+ unsigned char h_source[ETH_ALEN]; /* source ether addr */
+ unsigned short h_proto; /* packet type ID field */
};
-/* Ethernet statistics collection data. */
-struct enet_statistics{
- int rx_packets; /* total packets received */
- int tx_packets; /* total packets transmitted */
- int rx_errors; /* bad packets received */
- int tx_errors; /* packet transmit problems */
- int rx_dropped; /* no space in linux buffers */
- int tx_dropped; /* no space available in linux */
- int multicast; /* multicast packets received */
- int collisions;
+/*
+ * Ethernet statistics collection data.
+ */
+
+struct enet_statistics
+{
+ int rx_packets; /* total packets received */
+ int tx_packets; /* total packets transmitted */
+ int rx_errors; /* bad packets received */
+ int tx_errors; /* packet transmit problems */
+ int rx_dropped; /* no space in linux buffers */
+ int tx_dropped; /* no space available in linux */
+ int multicast; /* multicast packets received */
+ int collisions;
- /* detailed rx_errors: */
- int rx_length_errors;
- int rx_over_errors; /* receiver ring buff overflow */
- int rx_crc_errors; /* recved pkt with crc error */
- int rx_frame_errors; /* recv'd frame alignment error */
- int rx_fifo_errors; /* recv'r fifo overrun */
- int rx_missed_errors; /* receiver missed packet */
+ /* detailed rx_errors: */
+ int rx_length_errors;
+ int rx_over_errors; /* receiver ring buff overflow */
+ int rx_crc_errors; /* recved pkt with crc error */
+ int rx_frame_errors; /* recv'd frame alignment error */
+ int rx_fifo_errors; /* recv'r fifo overrun */
+ int rx_missed_errors; /* receiver missed packet */
- /* detailed tx_errors */
- int tx_aborted_errors;
- int tx_carrier_errors;
- int tx_fifo_errors;
- int tx_heartbeat_errors;
- int tx_window_errors;
+ /* detailed tx_errors */
+ int tx_aborted_errors;
+ int tx_carrier_errors;
+ int tx_fifo_errors;
+ int tx_heartbeat_errors;
+ int tx_window_errors;
};
+
#endif /* _LINUX_IF_ETHER_H */
--- /dev/null
+/*
+ * DLCI/FRAD Definitions for Frame Relay Access Devices. DLCI devices are
+ * created for each DLCI associated with a FRAD. The FRAD driver
+ * is not truely a network device, but the lower level device
+ * handler. This allows other FRAD manufacturers to use the DLCI
+ * code, including it's RFC1490 encapsulation along side the current
+ * implementation for the Sangoma cards.
+ *
+ * Version: @(#)if_ifrad.h 0.10 23 Mar 96
+ *
+ * Author: Mike McLagan <mike.mclagan@linux.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _FRAD_H_
+#define _FRAD_H_
+
+/* Stuctures and constants associated with the DLCI device driver */
+
+#define DLCI_DEVADD (SIOCDEVPRIVATE)
+#define DLCI_DEVDEL (SIOCDEVPRIVATE + 1)
+
+struct dlci_add
+{
+ char devname[IFNAMSIZ];
+ short dlci;
+};
+
+#define DLCI_GET_CONF (SIOCDEVPRIVATE + 2)
+#define DLCI_SET_CONF (SIOCDEVPRIVATE + 3)
+
+/* These are related to the Sangoma FRAD */
+struct dlci_conf {
+ short flags;
+ short CIR_fwd;
+ short Bc_fwd;
+ short Be_fwd;
+ short CIR_bwd;
+ short Bc_bwd;
+ short Be_bwd;
+
+/* these are part of the status read */
+ short Tc_fwd;
+ short Tc_bwd;
+ short Tf_max;
+ short Tb_max;
+};
+
+#define DLCI_GET_SLAVE (SIOCDEVPRIVATE + 4)
+
+/* configuration flags for DLCI */
+#define DLCI_IGNORE_CIR_OUT 0x0001
+#define DLCI_ACCOUNT_CIR_IN 0x0002
+#define DLCI_BUFFER_IF 0x0008
+
+#define DLCI_VALID_FLAGS 0x000B
+
+
+/* defines for the actual Frame Relay hardware */
+#define FRAD_GET_CONF (SIOCDEVPRIVATE)
+#define FRAD_SET_CONF (SIOCDEVPRIVATE + 1)
+
+#define FRAD_LAST_IOCTL FRAD_SET_CONF
+
+struct frad_conf
+{
+ short station;
+ short flags;
+ short kbaud;
+ short clocking;
+ short mtu;
+ short T391;
+ short T392;
+ short N391;
+ short N392;
+ short N393;
+ short CIR_fwd;
+ short Bc_fwd;
+ short Be_fwd;
+ short CIR_bwd;
+ short Bc_bwd;
+ short Be_bwd;
+
+/* Add new fields here, above is a mirror of the sangoma_conf */
+
+};
+
+#define FRAD_STATION_CPE 0x0000
+#define FRAD_STATION_NODE 0x0001
+
+#define FRAD_TX_IGNORE_CIR 0x0001
+#define FRAD_RX_ACCOUNT_CIR 0x0002
+#define FRAD_DROP_ABORTED 0x0004
+#define FRAD_BUFFERIF 0x0008
+#define FRAD_STATS 0x0010
+#define FRAD_MCI 0x0100
+#define FRAD_AUTODLCI 0x8000
+#define FRAD_VALID_FLAGS 0x811F
+
+#define FRAD_CLOCK_INT 0x0001
+#define FRAD_CLOCK_EXT 0x0000
+
+#ifdef __KERNEL__
+
+struct fradhdr
+{
+ /* these are the fields of an RFC 1490 header */
+ unsigned char control;
+ unsigned char pad; /* for IP packets, this can be the NLPID */
+ unsigned char NLPID;
+ unsigned char OUI[3];
+ unsigned short PID;
+};
+
+/* see RFC 1490 for the definition of the following */
+#define FRAD_I_UI 0x03
+
+#define FRAD_P_PADDING 0x00
+#define FRAD_P_Q933 0x08
+#define FRAD_P_SNAP 0x80
+#define FRAD_P_CLNP 0x81
+#define FRAD_P_IP 0xCC
+
+struct dlci_local
+{
+ struct enet_statistics stats;
+ struct device *slave;
+ struct dlci_conf config;
+ int configured;
+
+ /* callback function */
+ void (*receive)(struct sk_buff *skb, struct device *);
+};
+
+struct frad_local
+{
+ struct enet_statistics stats;
+ struct timer_list timer;
+
+ /* devices which this FRAD is slaved to */
+ struct device *master[CONFIG_DLCI_MAX];
+ short dlci[CONFIG_DLCI_MAX];
+
+ /* callback functions */
+ int (*activate)(struct device *, struct device *);
+ int (*deactivate)(struct device *, struct device *);
+ int (*assoc)(struct device *, struct device *);
+ int (*deassoc)(struct device *, struct device *);
+ int (*dlci_conf)(struct device *, struct device *, int get);
+
+ int initialized; /* mem_start, port, irq set ? */
+ int configured; /* has this device been configured */
+ int type; /* adapter type */
+ int state; /* state of the S502/8 control latch */
+ int buffer; /* current buffer for S508 firmware */
+ struct frad_conf config;
+};
+
+int register_frad(const char *name);
+int unregister_frad(const char *name);
+
+#endif __KERNEL__
+
+#endif
/* This is an Token-Ring frame header. */
struct trh_hdr {
- unsigned char ac; /* access control field */
- unsigned char fc; /* frame control field */
- unsigned char daddr[TR_ALEN]; /* destination address */
- unsigned char saddr[TR_ALEN]; /* source address */
- unsigned short rcf; /* route control field */
- unsigned short rseg[8];/* routing registers */
+ __u8 ac; /* access control field */
+ __u8 fc; /* frame control field */
+ __u8 daddr[TR_ALEN]; /* destination address */
+ __u8 saddr[TR_ALEN]; /* source address */
+ __u16 rcf; /* route control field */
+ __u16 rseg[8]; /* routing registers */
};
/* This is an Token-Ring LLC structure */
struct trllc {
- unsigned char dsap; /* destination SAP */
- unsigned char ssap; /* source SAP */
- unsigned char llc; /* LLC control field */
- unsigned char protid[3]; /* protocol id */
- unsigned short ethertype; /* ether type field */
+ __u8 dsap; /* destination SAP */
+ __u8 ssap; /* source SAP */
+ __u8 llc; /* LLC control field */
+ __u8 protid[3]; /* protocol id */
+ __u16 ethertype; /* ether type field */
};
-
/* Token-Ring statistics collection data. */
-struct tr_statistics{
- int rx_packets; /* total packets received */
- int tx_packets; /* total packets transmitted */
- int rx_errors; /* bad packets received */
- int tx_errors; /* packet transmit problems */
- int rx_dropped; /* no space in linux buffers */
- int tx_dropped; /* no space available in linux */
- int multicast; /* multicast packets received */
- int transmit_collision;
+struct tr_statistics {
+ int rx_packets; /* total packets received */
+ int tx_packets; /* total packets transmitted */
+ int rx_errors; /* bad packets received */
+ int tx_errors; /* packet transmit problems */
+ int rx_dropped; /* no space in linux buffers */
+ int tx_dropped; /* no space available in linux */
+ int multicast; /* multicast packets received */
+ int transmit_collision;
- /* detailed Token-Ring errors. See IBM Token-Ring Network Architecture
- for more info */
+ /* detailed Token-Ring errors. See IBM Token-Ring Network
+ Architecture for more info */
int line_errors;
int internal_errors;
int frequency_errors;
int token_errors;
int dummy1;
-
};
/* source routing stuff */
#define GIO_FONTX 0x4B6B /* get font using struct consolefontdesc */
#define PIO_FONTX 0x4B6C /* set font using struct consolefontdesc */
struct consolefontdesc {
- u_short charcount; /* characters in font (256 or 512) */
- u_short charheight; /* scan lines per character (1-32) */
+ unsigned short charcount; /* characters in font (256 or 512) */
+ unsigned short charheight; /* scan lines per character (1-32) */
char *chardata; /* font data in expanded form */
};
#define GIO_UNIMAP 0x4B66 /* get unicode-to-font mapping from kernel */
struct unipair {
- u_short unicode;
- u_short fontpos;
+ unsigned short unicode;
+ unsigned short fontpos;
};
struct unimapdesc {
- u_short entry_ct;
+ unsigned short entry_ct;
struct unipair *entries;
};
#define PIO_UNIMAP 0x4B67 /* put unicode-to-font mapping in kernel */
#define PIO_UNIMAPCLR 0x4B68 /* clear table, possibly advise hash algorithm */
struct unimapinit {
- u_short advised_hashsize; /* 0 if no opinion */
- u_short advised_hashstep; /* 0 if no opinion */
- u_short advised_hashlevel; /* 0 if no opinion */
+ unsigned short advised_hashsize; /* 0 if no opinion */
+ unsigned short advised_hashstep; /* 0 if no opinion */
+ unsigned short advised_hashlevel; /* 0 if no opinion */
};
#define UNI_DIRECT_BASE 0xF000 /* start of Direct Font Region */
#define KDSKBLED 0x4B65 /* set led flags (not lights) */
struct kbentry {
- u_char kb_table;
- u_char kb_index;
- u_short kb_value;
+ unsigned char kb_table;
+ unsigned char kb_index;
+ unsigned short kb_value;
};
#define K_NORMTAB 0x00
#define K_SHIFTTAB 0x01
#define KDSKBENT 0x4B47 /* sets one entry in translation table */
struct kbsentry {
- u_char kb_func;
- u_char kb_string[512];
+ unsigned char kb_func;
+ unsigned char kb_string[512];
};
#define KDGKBSENT 0x4B48 /* gets one function key string entry */
#define KDSKBSENT 0x4B49 /* sets one function key string entry */
struct kbdiacr {
- u_char diacr, base, result;
+ unsigned char diacr, base, result;
};
struct kbdiacrs {
unsigned int kb_cnt; /* number of entries in following array */
#define KERNELD_CANCEL_RELEASE_MODULE 5 /* "rmmod" */
#define KERNELD_REQUEST_ROUTE 6 /* from net/ipv4/route.c */
#define KERNELD_BLANKER 7 /* from drivers/char/console.c */
+#define KERNELD_ARP 256 /* from net/ipv4/arp.c */
#define IPC_KERNELD 00040000 /* use the kerneld message channel */
#define KERNELD_MAXCMD 0x7ffeffff
#define LO_NAME_SIZE 64
#define LO_KEY_SIZE 32
+
+#ifdef __KERNEL__
struct loop_device {
int lo_number;
* Loop flags
*/
#define LO_FLAGS_DO_BMAP 0x00000001
+#define LO_FLAGS_READ_ONLY 0x00000002
+
+#endif /* __KERNEL__ */
struct loop_info {
int lo_number; /* ioctl r/o */
/*
* Definitions for the Mitsumi CDROM interface
* Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 1.8
+ * VERSION: 1.9
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
int buffer_size; /* The negotiated buffer size, to be
used for read/write requests! */
- /* Not used yet, but here some day the namespace numbers will be
- stored. */
int volume_number;
__u32 directory_id;
};
-#define NCP_IOC_NCPREQUEST _IOR('n', 1, unsigned char *)
-#define NCP_IOC_GETMOUNTUID _IOR('u', 1, uid_t)
-#define NCP_IOC_CONN_LOGGED_IN _IO('l', 1)
+#define NCP_IOC_NCPREQUEST _IOR('n', 1, struct ncp_ioctl_request)
+#define NCP_IOC_GETMOUNTUID _IOW('n', 2, uid_t)
+#define NCP_IOC_CONN_LOGGED_IN _IO('n', 3)
#define NCP_GET_FS_INFO_VERSION (1)
-#define NCP_IOC_GET_FS_INFO _IOWR('i', 1, unsigned char *)
+#define NCP_IOC_GET_FS_INFO _IOWR('n', 4, struct ncp_fs_info)
/*
* The packet size to allocate. One page should be enough.
struct wait_queue **wait; /* ptr to place to wait on */
struct inode *inode;
struct fasync_struct *fasync_list; /* Asynchronous wake up list */
+ struct file *file; /* File back pointer for gc */
};
#define SOCK_INODE(S) ((S)->inode)
#define HAVE_HEADER_CACHE
void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev, unsigned short htype, __u32 daddr);
void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char * haddr);
+#define HAVE_CHANGE_MTU
+ int (*change_mtu)(struct device *dev, int new_mtu);
};
#define STOP_TIMEOUT 1000 /* for poll wait */
#define RESET_WAIT 1000 /* busy wait at drive reset */
-/* # of buffer for block size conversion. 6 is optimal for my setup (P75),
+/* # of buffers for block size conversion. 6 is optimal for my setup (P75),
giving 280 kb/s, with 0.4% CPU usage. Experiment to find your optimal
setting */
#define N_BUFS 6
* PCI-CPU bridge or PCI-ISA bridge.
* - If you can't find the actual information in your hardware
* booklet, try to read the references of the chip on the board.
- * - Send all that, with the word PCIPROBE in the subject,
- * to frederic@cao-vlsi.ibp.fr, and I'll add your device to
- * the list as soon as possible
- * fred.
+ * - Send all that to linux-pcisupport@cao-vlsi.ibp.fr,
+ * and I'll add your device to the list as soon as possible
+ *
+ * BEFORE you send a mail, please check the latest linux releases
+ * to be sure it has not been recently added.
+ *
+ * Thanks
+ * Frederic Potter.
*/
#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4
#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8
#define PCI_DEVICE_ID_CIRRUS_5436 0x00ac
-#define PCI_DEVICE_ID_CIRRUS_6205 0x0205
#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
#define PCI_DEVICE_ID_CIRRUS_7542 0x1200
#define PCI_DEVICE_ID_CIRRUS_7543 0x1202
#define PCI_DEVICE_ID_CT_65548 0x00dc
#define PCI_VENDOR_ID_MIRO 0x1031
+#define PCI_DEVICE_ID_MIRO_36050 0x5601
#define PCI_VENDOR_ID_FD 0x1036
#define PCI_DEVICE_ID_FD_36C70 0x0000
#define PCI_VENDOR_ID_SI 0x1039
#define PCI_DEVICE_ID_SI_6201 0x0001
#define PCI_DEVICE_ID_SI_6202 0x0002
+#define PCI_DEVICE_ID_SI_6205 0x0205
#define PCI_DEVICE_ID_SI_503 0x0008
#define PCI_DEVICE_ID_SI_501 0x0406
#define PCI_DEVICE_ID_SI_496 0x0496
#define PCI_DEVICE_ID_VIA_82C416 0x1571
#define PCI_VENDOR_ID_VORTEX 0x1119
-#define PCI_DEVICE_ID_VORTEX_GDT 0x0001
+#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000
+#define PCI_DEVICE_ID_VORTEX_GDT6000B 0x0001
+#define PCI_DEVICE_ID_VORTEX_GDT6x10 0x0002
+#define PCI_DEVICE_ID_VORTEX_GDT6x20 0x0003
+#define PCI_DEVICE_ID_VORTEX_GDT6530 0x0004
+#define PCI_DEVICE_ID_VORTEX_GDT6550 0x0005
+#define PCI_DEVICE_ID_VORTEX_GDT6x17 0x0006
+#define PCI_DEVICE_ID_VORTEX_GDT6x27 0x0007
+#define PCI_DEVICE_ID_VORTEX_GDT6537 0x0008
+#define PCI_DEVICE_ID_VORTEX_GDT6557 0x0009
+#define PCI_DEVICE_ID_VORTEX_GDT6x15 0x000a
+#define PCI_DEVICE_ID_VORTEX_GDT6x25 0x000b
+#define PCI_DEVICE_ID_VORTEX_GDT6535 0x000c
+#define PCI_DEVICE_ID_VORTEX_GDT6555 0x000d
#define PCI_VENDOR_ID_EF 0x111a
#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000
#define PCI_VENDOR_ID_FORE 0x1127
#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210
+#define PCI_DEVICE_ID_FORE_PCA200E 0x0300
#define PCI_VENDOR_ID_IMAGINGTECH 0x112f
#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000
--- /dev/null
+#ifndef _LINUX_POSIX_TYPES_H
+#define _LINUX_POSIX_TYPES_H
+
+#define _GNU_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc. Also, we cannot
+ * assume GCC is being used.
+ */
+
+#ifndef NULL
+# define NULL ((void *) 0)
+#endif
+
+/*
+ * This allows for 256 file descriptors: if NR_OPEN is ever grown
+ * beyond that you'll have to change this too. But 256 fd's seem to be
+ * enough even for such "real" unices like SunOS, so hopefully this is
+ * one limit that doesn't have to be changed.
+ *
+ * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in
+ * <sys/time.h> (and thus <linux/time.h>) - but this is a more logical
+ * place for them. Solved by having dummy defines in <sys/time.h>.
+ */
+
+/*
+ * Those macros may have been defined in <gnu/types.h>. But we always
+ * use the ones here.
+ */
+#undef __NFDBITS
+#define __NFDBITS (8 * sizeof(unsigned int))
+
+#undef __FD_SETSIZE
+#define __FD_SETSIZE 256
+
+#undef __FDSET_INTS
+#define __FDSET_INTS (__FD_SETSIZE/__NFDBITS)
+
+#undef __FDELT
+#define __FDELT(d) ((d) / __NFDBITS)
+
+#undef __FDMASK
+#define __FDMASK(d) (1 << ((d) % __NFDBITS))
+
+typedef struct fd_set {
+ unsigned int fds_bits [__FDSET_INTS];
+} __fd_set;
+
+#include <asm/posix_types.h>
+
+/* bsd */
+
+typedef unsigned char __u_char;
+typedef unsigned short __u_short;
+typedef unsigned int __u_int;
+typedef unsigned long __u_long;
+
+#endif /* _LINUX_POSIX_TYPES_H */
#define PF_PTRACED 0x00000010 /* set if ptrace (0) has been called. */
#define PF_TRACESYS 0x00000020 /* tracing system calls */
#define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */
-#define PF_SUPERPREV 0x00000100 /* used super-user privileges */
+#define PF_SUPERPRIV 0x00000100 /* used super-user privileges */
#define PF_DUMPCORE 0x00000200 /* dumped core */
#define PF_SIGNALED 0x00000400 /* killed by a signal */
extern inline int suser(void)
{
if (current->euid == 0)
- current->flags |= PF_SUPERPREV;
+ current->flags |= PF_SUPERPRIV;
return (current->euid == 0);
}
--- /dev/null
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Global definitions for the Frame relay interface.
+ *
+ * Version: @(#)if_ifrad.h 0.10 23 Mar 96
+ *
+ * Author: Mike McLagan <mike.mclagan@linux.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef SDLA_H
+#define SDLA_H
+
+/* adapter type */
+#define SDLA_TYPES
+#define SDLA_S502A 5020
+#define SDLA_S502E 5021
+#define SDLA_S503 5030
+#define SDLA_S507 5070
+#define SDLA_S508 5080
+#define SDLA_S509 5090
+#define SDLA_UNKNOWN -1
+
+/* port selection flags for the S508 */
+#define SDLA_S508_PORT_V35 0x00
+#define SDLA_S508_PORT_RS232 0x02
+
+/* Z80 CPU speeds */
+#define SDLA_CPU_3M 0x00
+#define SDLA_CPU_5M 0x01
+#define SDLA_CPU_7M 0x02
+#define SDLA_CPU_8M 0x03
+#define SDLA_CPU_10M 0x04
+#define SDLA_CPU_16M 0x05
+#define SDLA_CPU_12M 0x06
+
+/* some private IOCTLs */
+#define SDLA_IDENTIFY (FRAD_LAST_IOCTL + 1)
+#define SDLA_CPUSPEED (FRAD_LAST_IOCTL + 2)
+#define SDLA_PROTOCOL (FRAD_LAST_IOCTL + 3)
+
+#define SDLA_CLEARMEM (FRAD_LAST_IOCTL + 4)
+#define SDLA_WRITEMEM (FRAD_LAST_IOCTL + 5)
+#define SDLA_READMEM (FRAD_LAST_IOCTL + 6)
+
+struct sdla_mem {
+ int addr;
+ int len;
+ void *data;
+};
+
+#define SDLA_START (FRAD_LAST_IOCTL + 7)
+#define SDLA_STOP (FRAD_LAST_IOCTL + 8)
+
+/* some offsets in the Z80's memory space */
+#define SDLA_NMIADDR 0x0000
+#define SDLA_CONF_ADDR 0x0010
+#define SDLA_S502A_NMIADDR 0x0066
+#define SDLA_CODE_BASEADDR 0x0100
+
+/* largest handlable block of data */
+#define SDLA_MAX_DATA 4080
+#define SDLA_MAX_MTU 4072 /* MAX_DATA - sizeof(fradhdr) */
+#define SDLA_MAX_DLCI 24
+
+struct sdla_conf {
+ short station;
+ short config;
+ short kbaud;
+ short clocking;
+ short max_frm;
+ short T391;
+ short T392;
+ short N391;
+ short N392;
+ short N393;
+ short CIR_fwd;
+ short Bc_fwd;
+ short Be_fwd;
+ short CIR_bwd;
+ short Bc_bwd;
+ short Be_bwd;
+};
+
+struct sdla_dlci {
+ short config;
+ short CIR_fwd;
+ short Bc_fwd;
+ short Be_fwd;
+ short CIR_bwd;
+ short Bc_bwd;
+ short Be_bwd;
+
+/* these are part of the status READ */
+ short Tc_fwd;
+ short Tc_bwd;
+ short Tf_max;
+ short Tb_max;
+};
+
+#ifndef __KERNEL__
+
+void sdla(void *cfg_info, char *dev, struct frad_conf *conf, int quiet);
+
+#else
+
+/* important Z80 window addresses */
+#define SDLA_CONTROL_WND 0xE000
+
+#define SDLA_502_CMD_BUF 0xEF60
+#define SDLA_502_RCV_BUF 0xA900
+#define SDLA_502_TXN_AVAIL 0xFFF1
+#define SDLA_502_RCV_AVAIL 0xFFF2
+#define SDLA_502_EVENT_FLAGS 0xFFF3
+#define SDLA_502_MDM_STATUS 0xFFF4
+#define SDLA_502_IRQ_INTERFACE 0xFFFD
+#define SDLA_502_IRQ_PERMISSION 0xFFFE
+#define SDLA_502_DATA_OFS 0x0010
+
+#define SDLA_508_CMD_BUF 0xE000
+#define SDLA_508_TXBUF_INFO 0xF100
+#define SDLA_508_RXBUF_INFO 0xF120
+#define SDLA_508_EVENT_FLAGS 0xF003
+#define SDLA_508_MDM_STATUS 0xF004
+#define SDLA_508_IRQ_INTERFACE 0xF010
+#define SDLA_508_IRQ_PERMISSION 0xF011
+#define SDLA_508_TSE_OFFSET 0xF012
+
+/* Event flags */
+#define SDLA_EVENT_STATUS 0x01
+#define SDLA_EVENT_DLCI_STATUS 0x02
+#define SDLA_EVENT_BAD_DLCI 0x04
+#define SDLA_EVENT_LINK_DOWN 0x40
+
+/* IRQ Trigger flags */
+#define SDLA_INTR_RX 0x01
+#define SDLA_INTR_TX 0x02
+#define SDLA_INTR_MODEM 0x04
+#define SDLA_INTR_COMPLETE 0x08
+#define SDLA_INTR_STATUS 0x10
+#define SDLA_INTR_TIMER 0x20
+
+/* DLCI status bits */
+#define SDLA_DLCI_DELETED 0x01
+#define SDLA_DLCI_ACTIVE 0x02
+#define SDLA_DLCI_WAITING 0x04
+#define SDLA_DLCI_NEW 0x08
+#define SDLA_DLCI_INCLUDED 0x40
+
+/* valid command codes */
+#define SDLA_INFORMATION_WRITE 0x01
+#define SDLA_INFORMATION_READ 0x02
+#define SDLA_ISSUE_IN_CHANNEL_SIGNAL 0x03
+#define SDLA_SET_DLCI_CONFIGURATION 0x10
+#define SDLA_READ_DLCI_CONFIGURATION 0x11
+#define SDLA_DISABLE_COMMUNICATIONS 0x12
+#define SDLA_ENABLE_COMMUNICATIONS 0x13
+#define SDLA_READ_DLC_STATUS 0x14
+#define SDLA_READ_DLC_STATISTICS 0x15
+#define SDLA_FLUSH_DLC_STATISTICS 0x16
+#define SDLA_LIST_ACTIVE_DLCI 0x17
+#define SDLA_FLUSH_INFORMATION_BUFFERS 0x18
+#define SDLA_ADD_DLCI 0x20
+#define SDLA_DELETE_DLCI 0x21
+#define SDLA_ACTIVATE_DLCI 0x22
+#define SDLA_DEACTIVATE_DLCI 0x23
+#define SDLA_READ_MODEM_STATUS 0x30
+#define SDLA_SET_MODEM_STATUS 0x31
+#define SDLA_READ_COMMS_ERR_STATS 0x32
+#define SDLA_FLUSH_COMMS_ERR_STATS 0x33
+#define SDLA_READ_CODE_VERSION 0x40
+#define SDLA_SET_IRQ_TRIGGER 0x50
+#define SDLA_GET_IRQ_TRIGGER 0x51
+
+/* In channel signal types */
+#define SDLA_ICS_LINK_VERIFY 0x02
+#define SDLA_ICS_STATUS_ENQ 0x03
+
+/* modem status flags */
+#define SDLA_MODEM_DTR_HIGH 0x01
+#define SDLA_MODEM_RTS_HIGH 0x02
+#define SDLA_MODEM_DCD_HIGH 0x08
+#define SDLA_MODEM_CTS_HIGH 0x20
+
+/* used for RET_MODEM interpretation */
+#define SDLA_MODEM_DCD_LOW 0x01
+#define SDLA_MODEM_CTS_LOW 0x02
+
+/* return codes */
+#define SDLA_RET_OK 0x00
+#define SDLA_RET_COMMUNICATIONS 0x01
+#define SDLA_RET_CHANNEL_INACTIVE 0x02
+#define SDLA_RET_DLCI_INACTIVE 0x03
+#define SDLA_RET_DLCI_CONFIG 0x04
+#define SDLA_RET_BUF_TOO_BIG 0x05
+#define SDLA_RET_NO_DATA 0x05
+#define SDLA_RET_BUF_OVERSIZE 0x06
+#define SDLA_RET_CIR_OVERFLOW 0x07
+#define SDLA_RET_NO_BUFF 0x08
+#define SDLA_RET_TIMEOUT 0x0A
+#define SDLA_RET_MODEM 0x10
+#define SDLA_RET_CHANNEL_OFF 0x11
+#define SDLA_RET_CHANNEL_ON 0x12
+#define SDLA_RET_DLCI_STATUS 0x13
+#define SDLA_RET_DLCI_UNKNOWN 0x14
+#define SDLA_RET_COMMAND_INVALID 0x1F
+
+/* Configuration flags */
+#define SDLA_DIRECT_RECV 0x0080
+
+/* IRQ selection flags */
+#define SDLA_IRQ_RECEIVE 0x01
+#define SDLA_IRQ_TRANSMIT 0x02
+#define SDLA_IRQ_MODEM_STAT 0x04
+#define SDLA_IRQ_COMMAND 0x08
+#define SDLA_IRQ_CHANNEL 0x10
+#define SDLA_IRQ_TIMER 0x20
+
+/* definitions for PC memory mapping */
+#define SDLA_8K_WINDOW 0x01
+#define SDLA_S502_SEG_A 0x10
+#define SDLA_S502_SEG_C 0x20
+#define SDLA_S502_SEG_D 0x00
+#define SDLA_S502_SEG_E 0x30
+#define SDLA_S507_SEG_A 0x00
+#define SDLA_S507_SEG_B 0x40
+#define SDLA_S507_SEG_C 0x80
+#define SDLA_S507_SEG_E 0xC0
+#define SDLA_S508_SEG_A 0x00
+#define SDLA_S508_SEG_C 0x10
+#define SDLA_S508_SEG_D 0x08
+#define SDLA_S508_SEG_E 0x18
+
+/* SDLA adapter port constants */
+#define SDLA_IO_EXTENTS 0x04
+
+#define SDLA_REG_CONTROL 0x00
+#define SDLA_REG_PC_WINDOW 0x01 /* offset for PC window select latch */
+#define SDLA_REG_Z80_WINDOW 0x02 /* offset for Z80 window select latch */
+#define SDLA_REG_Z80_CONTROL 0x03 /* offset for Z80 control latch */
+
+#define SDLA_S502_STS 0x00 /* status reg for 502, 502E, 507 */
+#define SDLA_S508_GNRL 0x00 /* general purp. reg for 508 */
+#define SDLA_S508_STS 0x01 /* status reg for 508 */
+#define SDLA_S508_IDR 0x02 /* ID reg for 508 */
+
+/* control register flags */
+#define SDLA_S502A_START 0x00 /* start the CPU */
+#define SDLA_S502A_INTREQ 0x02
+#define SDLA_S502A_INTEN 0x04
+#define SDLA_S502A_HALT 0x08 /* halt the CPU */
+#define SDLA_S502A_NMI 0x10 /* issue an NMI to the CPU */
+
+#define SDLA_S502E_CPUEN 0x01
+#define SDLA_S502E_ENABLE 0x02
+#define SDLA_S502E_INTACK 0x04
+
+#define SDLA_S507_ENABLE 0x01
+#define SDLA_S507_IRQ3 0x00
+#define SDLA_S507_IRQ4 0x20
+#define SDLA_S507_IRQ5 0x40
+#define SDLA_S507_IRQ7 0x60
+#define SDLA_S507_IRQ10 0x80
+#define SDLA_S507_IRQ11 0xA0
+#define SDLA_S507_IRQ12 0xC0
+#define SDLA_S507_IRQ15 0xE0
+
+#define SDLA_HALT 0x00
+#define SDLA_CPUEN 0x02
+#define SDLA_MEMEN 0x04
+#define SDLA_S507_EPROMWR 0x08
+#define SDLA_S507_EPROMCLK 0x10
+#define SDLA_S508_INTRQ 0x08
+#define SDLA_S508_INTEN 0x10
+
+struct sdla_cmd {
+ char opp_flag __attribute__((packed));
+ char cmd __attribute__((packed));
+ short length __attribute__((packed));
+ char retval __attribute__((packed));
+ short dlci __attribute__((packed));
+ char flags __attribute__((packed));
+ short rxlost_int __attribute__((packed));
+ long rxlost_app __attribute__((packed));
+ char reserve[2] __attribute__((packed));
+ char data[SDLA_MAX_DATA] __attribute__((packed)); /* transfer data buffer */
+};
+
+struct intr_info {
+ char flags __attribute__((packed));
+ short txlen __attribute__((packed));
+ char irq __attribute__((packed));
+ char flags2 __attribute__((packed));
+ short timeout __attribute__((packed));
+};
+
+/* found in the 508's control window at RXBUF_INFO */
+struct buf_info {
+ unsigned short rse_num __attribute__((packed));
+ unsigned long rse_base __attribute__((packed));
+ unsigned long rse_next __attribute__((packed));
+ unsigned long buf_base __attribute__((packed));
+ unsigned short reserved __attribute__((packed));
+ unsigned long buf_top __attribute__((packed));
+};
+
+/* structure pointed to by rse_base in RXBUF_INFO struct */
+struct buf_entry {
+ char opp_flag __attribute__((packed));
+ short length __attribute__((packed));
+ short dlci __attribute__((packed));
+ char flags __attribute__((packed));
+ short timestamp __attribute__((packed));
+ short reserved[2] __attribute__((packed));
+ long buf_addr __attribute__((packed));
+};
+
+#endif
+
+#endif
extern void smp_callin(void); /* Processor call in. Must hold processors until .. */
extern void smp_commence(void); /* Multiprocessors may now schedule */
extern int smp_num_cpus;
-extern int smp_top_cpu; /* Top CPU number */
extern int smp_threads_ready; /* True once the per process idle is forked */
#ifdef __SMP_PROF__
extern volatile unsigned long smp_spins[NR_CPUS]; /* count of interrupt spins */
#define smp_num_cpus 1
#define smp_processor_id() 0
-#define smp_top_cpu 0
#define smp_message_pass(t,m,d,w)
#define smp_threads_ready 1
#define kernel_lock()
#define SOL_TCP 6
#define SOL_UDP 17
+#ifdef __KERNEL__
+
/* IP options */
#define IP_TOS 1
#define IPTOS_LOWDELAY 0x10
#define IP_ADD_MEMBERSHIP 35
#define IP_DROP_MEMBERSHIP 36
+#endif /* __KERNEL__ */
/* These need to appear somewhere around here */
#define IP_DEFAULT_MULTICAST_TTL 1
#ifndef _LINUX_SOCKIOS_H
#define _LINUX_SOCKIOS_H
+#include <asm/sockios.h>
+
/* Routing table calls. */
#define SIOCADDRT 0x890B /* add routing table entry */
#define SIOCDELRT 0x890C /* delete routing table entry */
* 'tty.h' defines some structures used by tty_io.c and some defines.
*/
+/*
+ * These constants are also useful for user-level apps (e.g., VC
+ * resizing).
+ */
+#define MIN_NR_CONSOLES 1 /* must be at least 1 */
+#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */
+#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */
+ /* Note: the ioctl VT_GETSTATE does not work for
+ consoles 16 and higher (since it returns a short) */
+
#ifdef __KERNEL__
#include <linux/fs.h>
#include <linux/termios.h>
* (Note: the *_driver.minor_start values 1, 64, 128, 192 are
* hardcoded at present.)
*/
-#define MIN_NR_CONSOLES 1 /* must be at least 1 */
-#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */
-#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */
- /* Note: the ioctl VT_GETSTATE does not work for
- consoles 16 and higher (since it returns a short) */
#define NR_PTYS 256
#define NR_LDISCS 16
#ifndef _LINUX_TYPES_H
#define _LINUX_TYPES_H
-/*
- * This allows for 256 file descriptors: if NR_OPEN is ever grown beyond that
- * you'll have to change this too. But 256 fd's seem to be enough even for such
- * "real" unices like SunOS, so hopefully this is one limit that doesn't have
- * to be changed.
- *
- * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in <sys/time.h>
- * (and thus <linux/time.h>) - but this is a more logical place for them. Solved
- * by having dummy defines in <sys/time.h>.
- */
+#include <linux/posix_types.h>
+#include <asm/types.h>
-/*
- * Those macros may have been defined in <gnu/types.h>. But we always
- * use the ones here.
- */
-#undef __NFDBITS
-#define __NFDBITS (8 * sizeof(unsigned int))
+#ifndef _LINUX_TYPES_DONT_EXPORT
-#undef __FD_SETSIZE
-#define __FD_SETSIZE 256
+typedef __fd_set fd_set;
+typedef __dev_t dev_t;
+typedef __ino_t ino_t;
+typedef __mode_t mode_t;
+typedef __nlink_t nlink_t;
+typedef __off_t off_t;
+typedef __pid_t pid_t;
+typedef __uid_t uid_t;
+typedef __gid_t gid_t;
+typedef __daddr_t daddr_t;
-#undef __FDSET_INTS
-#define __FDSET_INTS (__FD_SETSIZE/__NFDBITS)
+/* bsd */
-typedef struct fd_set {
- unsigned int fds_bits [__FDSET_INTS];
-} fd_set;
+typedef __u_char u_char;
+typedef __u_short u_short;
+typedef __u_int u_int;
+typedef __u_long u_long;
-#include <asm/types.h>
+/*
+ * The following typedefs are also protected by individual ifdefs for
+ * historical reasons:
+ */
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef __size_t size_t;
+#endif
-#ifndef NULL
-#define NULL ((void *) 0)
+#ifndef _SSIZE_T
+#define _SSIZE_T
+typedef __ssize_t ssize_t;
#endif
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-#define _LOFF_T
-typedef long long loff_t;
+#ifndef _PTRDIFF_T
+#define _PTRDIFF_T
+typedef __ptrdiff_t ptrdiff_t;
#endif
-/* bsd */
-typedef unsigned char u_char;
-typedef unsigned short u_short;
-typedef unsigned int u_int;
-typedef unsigned long u_long;
+#ifndef _TIME_T
+#define _TIME_T
+typedef __time_t time_t;
+#endif
+
+#ifndef _CLOCK_T
+#define _CLOCK_T
+typedef __clock_t clock_t;
+#endif
+
+#ifndef _CADDR_T
+#define _CADDR_T
+typedef __caddr_t caddr_t;
+#endif
/* sysv */
-typedef unsigned char unchar;
-typedef unsigned short ushort;
-typedef unsigned int uint;
-typedef unsigned long ulong;
+typedef unsigned char unchar;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+#endif /* _LINUX_TYPES_DONT_EXPORT */
+
+/*
+ * Below are truly Linux-specific types that should never collide with
+ * any application/library that wants linux/types.h.
+ */
-typedef char *caddr_t;
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+
+typedef long long __loff_t;
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
-typedef unsigned int tcflag_t;
+#ifndef _LINUX_TYPES_DONT_EXPORT
+#define _LOFF_T
+typedef __loff_t loff_t;
+#endif
+
+#endif
struct ustat {
- daddr_t f_tfree;
- ino_t f_tinode;
- char f_fname[6];
- char f_fpack[6];
+ __daddr_t f_tfree;
+ __ino_t f_tinode;
+ char f_fname[6];
+ char f_fpack[6];
};
-#endif
+#endif /* _LINUX_TYPES_H */
#define VT_ACKACQ 0x02 /* acknowledge switch */
struct vt_stat {
- ushort v_active; /* active vt */
- ushort v_signal; /* signal to send */
- ushort v_state; /* vt bitmask */
+ unsigned short v_active; /* active vt */
+ unsigned short v_signal; /* signal to send */
+ unsigned short v_state; /* vt bitmask */
};
#define VT_GETSTATE 0x5603 /* get global vt state info */
#define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */
#define VT_DISALLOCATE 0x5608 /* free memory associated to vt */
struct vt_sizes {
- ushort v_rows; /* number of rows */
- ushort v_cols; /* number of columns */
- ushort v_scrollsize; /* number of lines of scrollback */
+ unsigned short v_rows; /* number of rows */
+ unsigned short v_cols; /* number of columns */
+ unsigned short v_scrollsize; /* number of lines of scrollback */
};
#define VT_RESIZE 0x5609 /* set kernel's idea of screensize */
struct vt_consize {
- ushort v_rows; /* number of rows */
- ushort v_cols; /* number of columns */
- ushort v_vlin; /* number of pixel rows on screen */
- ushort v_clin; /* number of pixel rows per character */
- ushort v_vcol; /* number of pixel columns on screen */
- ushort v_ccol; /* number of pixel columns per character */
+ unsigned short v_rows; /* number of rows */
+ unsigned short v_cols; /* number of columns */
+ unsigned short v_vlin; /* number of pixel rows on screen */
+ unsigned short v_clin; /* number of pixel rows per character */
+ unsigned short v_vcol; /* number of pixel columns on screen */
+ unsigned short v_ccol; /* number of pixel columns per character */
};
#define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */
#define VT_LOCKSWITCH 0x560B /* disallow vt switching */
extern void unix_proto_init(struct net_proto *pro);
-
+extern struct proto_ops unix_proto_ops;
+extern void unix_inflight(struct file *fp);
+extern void unix_notinflight(struct file *fp);
typedef struct sock unix_socket;
-extern int unix_gc_free;
-extern void unix_gc_add(struct sock *sk, struct file *fp);
-extern void unix_gc_remove(struct file *fp);
+unix_socket *unix_socket_list;
#define UNIX_MAX_FD 8
--- /dev/null
+/*
+ * Interface routines assumed by gc()
+ *
+ * Copyright (C) Barak A. Pearlmutter.
+ * Released under the GPL version 2 or later.
+ *
+ */
+
+typedef struct object *pobj; /* pointer to a guy of the type we gc */
+
+/*
+ * How to mark and unmark objects
+ */
+
+extern void gc_mark(pobj);
+extern void gc_unmark(pobj);
+extern int gc_marked(pobj);
+
+/*
+ * How to count and access an object's children
+ */
+
+extern int n_children(pobj); /* how many children */
+extern pobj child_n(pobj, int); /* child i, numbered 0..n-1 */
+
+/*
+ * How to access the root set
+ */
+
+extern int root_size(void); /* number of things in root set */
+extern pobj root_elt(int); /* element i of root set, numbered 0..n-1 */
+
+/*
+ * How to access the free list
+ */
+
+extern void clear_freelist(void);
+extern void add_to_free_list(pobj);
+
+/*
+ * How to iterate through all objects in memory
+ */
+
+extern int N_OBJS;
+extern pobj obj_number(int);
+
#ifndef _NET_INET_IPX_H_
#define _NET_INET_IPX_H_
+#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <net/datalink.h>
#include <linux/ipx.h>
-struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+#ifndef _NET_P8022_H
+#define _NET_P8022_H
+extern struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+extern void unregister_8022_client(unsigned char type);
+
+#endif
-struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+#ifndef _NET_PSNAP_H
+#define _NET_PSNAP_H
+extern struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+extern void unregister_snap_client(unsigned char *desc);
+
+#endif
#include <net/netrom.h>
#endif
#endif
-#ifdef CONFIG_IPX
+
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
#include <net/ipx.h>
#endif
-#ifdef CONFIG_ATALK
+
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
#include <linux/atalk.h>
#endif
struct inode * inode;
struct semaphore readsem;
struct sock * other;
+ int marksweep;
+#define MARKED 1
+ int inflight;
};
/*
* Once the IPX ncpd patches are in these are going into protinfo
*/
-#ifdef CONFIG_IPX
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
struct ipx_opt
{
ipx_address dest_addr;
union
{
struct unix_opt af_unix;
-#ifdef CONFIG_ATALK
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
struct atalk_sock af_at;
#endif
-#ifdef CONFIG_IPX
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
struct ipx_opt af_ipx;
-#endif
+#endif
#ifdef CONFIG_INET
struct inet_packet_opt af_packet;
#ifdef CONFIG_NUTCP
static void smp_init(void)
{
- int i=0;
+ int i, j;
smp_boot_cpus();
/*
* Create the slave init tasks as sharing pid 0.
+ *
+ * This should only happen if we have virtual CPU numbers
+ * higher than 0.
*/
- for (i=0; i<NR_CPUS; i++)
+ for (i=1; i<smp_num_cpus; i++)
{
+ j = cpu_logical_map[i];
/*
- * This should only do anything if the mapping
- * corresponds to a live CPU which is not the boot CPU.
+ * We use kernel_thread for the idlers which are
+ * unlocked tasks running in kernel space.
*/
- if (cpu_number_map[i] > 0)
- {
- /*
- * We use kernel_thread for the idlers which are
- * unlocked tasks running in kernel space.
- */
- kernel_thread(cpu_idle, NULL, CLONE_PID);
- /*
- * Don't assume linear processor numbering
- */
- current_set[i]=task[cpu_number_map[i]];
- current_set[i]->processor=i;
- }
+ kernel_thread(cpu_idle, NULL, CLONE_PID);
+ /*
+ * Don't assume linear processor numbering
+ */
+ current_set[j]=task[i];
+ current_set[j]->processor=j;
}
}
if (!p || sig > 32)
return -EINVAL;
if (!priv && ((sig != SIGCONT) || (current->session != p->session)) &&
- (current->euid != p->euid) && (current->euid != p->uid) && !suser())
+ (current->euid ^ p->euid) && (current->euid ^ p->uid) &&
+ (current->uid ^ p->euid) && (current->uid ^ p->uid) &&
+ !suser())
return -EPERM;
if (!sig)
return 0;
p->kernel_stack_page = new_stack;
*(unsigned long *) p->kernel_stack_page = STACK_MAGIC;
p->state = TASK_UNINTERRUPTIBLE;
- p->flags &= ~(PF_PTRACED|PF_TRACESYS|PF_SUPERPREV);
+ p->flags &= ~(PF_PTRACED|PF_TRACESYS|PF_SUPERPRIV);
p->flags |= PF_FORKNOEXEC;
p->pid = get_pid(clone_flags);
p->next_run = NULL;
extern unsigned char aux_device_present, kbd_read_mask;
-#ifdef CONFIG_NET
-#include <linux/in.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/firewall.h>
-#include <linux/trdevice.h>
-
-#ifdef CONFIG_AX25
-#include <net/ax25.h>
-#endif
-#ifdef CONFIG_INET
-#include <linux/ip.h>
-#include <linux/etherdevice.h>
-#include <net/protocol.h>
-#include <net/arp.h>
-#include <net/ip.h>
-#include <net/udp.h>
-#include <net/tcp.h>
-#include <net/icmp.h>
-#include <net/route.h>
-#include <linux/net_alias.h>
-#endif
-#ifdef CONFIG_NET_ALIAS
-#include <linux/net_alias.h>
-#endif
-#endif
#ifdef CONFIG_PCI
#include <linux/bios32.h>
#include <linux/pci.h>
extern void *sys_call_table;
-#if defined(CONFIG_ULTRA) || defined(CONFIG_WD80x3) || \
- defined(CONFIG_EL2) || defined(CONFIG_NE2000) || \
- defined(CONFIG_E2100) || defined(CONFIG_HPLAN_PLUS) || \
- defined(CONFIG_HPLAN) || defined(CONFIG_AC3200)
-#include "../drivers/net/8390.h"
-#endif
-
extern int sys_tz;
extern int request_dma(unsigned int dmanr, char * deviceID);
extern void free_dma(unsigned int dmanr);
-extern int (*rarp_ioctl_hook)(int,void*);
struct symbol_table symbol_table = {
#include <linux/symtab_begin.h>
X(unregister_binfmt),
X(search_binary_handler),
X(prepare_binprm),
+ X(remove_arg_zero),
/* execution environment registration */
X(lookup_exec_domain),
/* Miscellaneous access points */
X(si_meminfo),
-#ifdef CONFIG_NET
- /* Socket layer registration */
- X(sock_register),
- X(sock_unregister),
- /* Socket layer support routines */
- X(skb_recv_datagram),
- X(skb_free_datagram),
- X(skb_copy_datagram),
- X(skb_copy_datagram_iovec),
- X(datagram_select),
-#ifdef CONFIG_FIREWALL
- /* Firewall registration */
- X(register_firewall),
- X(unregister_firewall),
-#endif
-#ifdef CONFIG_INET
- /* Internet layer registration */
- X(inet_add_protocol),
- X(inet_del_protocol),
- X(rarp_ioctl_hook),
- X(init_etherdev),
- X(ip_rt_route),
- X(icmp_send),
- X(ip_options_compile),
- X(ip_rt_put),
- X(arp_send),
-#ifdef CONFIG_IP_FORWARD
- X(ip_forward),
-#endif
-#if defined(CONFIG_ULTRA) || defined(CONFIG_WD80x3) || \
- defined(CONFIG_EL2) || defined(CONFIG_NE2000) || \
- defined(CONFIG_E2100) || defined(CONFIG_HPLAN_PLUS) || \
- defined(CONFIG_HPLAN) || defined(CONFIG_AC3200)
- /* If 8390 NIC support is built in, we will need these. */
- X(ei_open),
- X(ei_close),
- X(ei_debug),
- X(ei_interrupt),
- X(ethdev_init),
- X(NS8390_init),
-#endif
-#ifdef CONFIG_NET_ALIAS
-#include <linux/net_alias.h>
-#endif
-#endif
- /* Device callback registration */
- X(register_netdevice_notifier),
- X(unregister_netdevice_notifier),
-#ifdef CONFIG_NET_ALIAS
- X(register_net_alias_type),
- X(unregister_net_alias_type),
-#endif
-#endif
- /* support for loadable net drivers */
-#ifdef CONFIG_AX25
- X(ax25_encapsulate),
- X(ax25_rebuild_header),
-#endif
-#ifdef CONFIG_INET
- X(register_netdev),
- X(unregister_netdev),
- X(ether_setup),
- X(eth_type_trans),
- X(eth_copy_and_sum),
- X(alloc_skb),
- X(kfree_skb),
- X(skb_clone),
- X(dev_alloc_skb),
- X(dev_kfree_skb),
- X(netif_rx),
- X(dev_tint),
- X(irq2dev_map),
- X(dev_add_pack),
- X(dev_remove_pack),
- X(dev_get),
- X(dev_ioctl),
- X(dev_queue_xmit),
- X(dev_base),
- X(dev_close),
- X(arp_find),
- X(n_tty_ioctl),
- X(tty_register_ldisc),
- X(kill_fasync),
-#ifdef CONFIG_FIREWALL
- X(call_in_firewall),
-#endif
-#endif
#ifndef CONFIG_SCSI
/*
* With no scsi configured, we still need to export a few
*
* On 1-Aug-95: <Matti.Aarnio@utu.fi> altered code to use same style as
* do /proc/net/XXX "files". Namely allow more than 4kB
- * (or what the block size if) output.
+ * (or what the block size is) output.
*
* - Use dummy syscall functions for users who disable all
* module support. Similar to kernel/sys.c (Paul Gortmaker)
/*
* 'sched.c' is the main kernel file. It contains scheduling primitives
* (sleep_on, wakeup, schedule etc) as well as a number of simple system
- * call functions (type getpid(), which just extracts a field from
+ * call functions (type getpid()), which just extract a field from
* current-task
*/
if ((0!=p->pid) && smp_threads_ready)
{
int i;
- for (i=0;i<=smp_top_cpu;i++)
+ for (i=0;i<smp_num_cpus;i++)
{
- if (cpu_number_map[i]==-1)
- continue;
- if (0==current_set[i]->pid)
+ if (0==current_set[cpu_logical_map[i]]->pid)
{
- smp_message_pass(i, MSG_RESCHEDULE, 0L, 0);
+ smp_message_pass(cpu_logical_map[i], MSG_RESCHEDULE, 0L, 0);
break;
}
}
update_one_process(p, ticks, ticks-system, system);
}
#else
- int cpu,i;
+ int cpu,j;
cpu = smp_processor_id();
- for (i=0;i<=smp_top_cpu;i++)
+ for (j=0;j<smp_num_cpus;j++)
{
+ int i = cpu_logical_map[j];
struct task_struct *p;
- if(cpu_number_map[i]==-1)
- continue;
#ifdef __SMP_PROF__
if (test_bit(i,&smp_idle_map))
smp_idle_count[i]++;
#include <linux/fcntl.h>
#include <linux/acct.h>
#include <linux/tty.h>
-#include <sys/sysmacros.h>
#include <asm/segment.h>
#include <asm/io.h>
ac.ac_etime = CURRENT_TIME - ac.ac_btime;
ac.ac_uid = current->uid;
ac.ac_gid = current->gid;
- ac.ac_tty = (current)->tty == NULL ? -1 :
- makedev (4, current->tty->device);
+ ac.ac_tty = (current)->tty == NULL ? -1 :
+ MKDEV(4, current->tty->device);
ac.ac_flag = 0;
if (current->flags & PF_FORKNOEXEC)
ac.ac_flag |= AFORK;
- if (current->flags & PF_SUPERPREV)
+ if (current->flags & PF_SUPERPRIV)
ac.ac_flag |= ASU;
if (current->flags & PF_DUMPCORE)
ac.ac_flag |= ACORE;
# Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := mm.o
-O_OBJS := memory.o mmap.o filemap.o mprotect.o mlock.o \
+O_OBJS := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
kmalloc.o vmalloc.o \
swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o
return -EFAULT;
}
-static inline void get_empty_page(struct task_struct * tsk, struct vm_area_struct * vma, pte_t * page_table)
+static inline void get_empty_page(struct task_struct * tsk, struct vm_area_struct * vma,
+ pte_t * page_table, int write_access)
{
- unsigned long tmp;
+ pte_t pte;
- if (!(tmp = get_free_page(GFP_KERNEL))) {
- oom(tsk);
- put_page(page_table, BAD_PAGE);
- return;
+ pte = pte_wrprotect(mk_pte(ZERO_PAGE, vma->vm_page_prot));
+ if (write_access) {
+ unsigned long page = get_free_page(GFP_KERNEL);
+ pte = pte_mkwrite(mk_pte(page, vma->vm_page_prot));
+ vma->vm_mm->rss++;
+ tsk->min_flt++;
+ if (!page) {
+ oom(tsk);
+ pte = BAD_PAGE;
+ }
}
- put_page(page_table, pte_mkwrite(mk_pte(tmp, vma->vm_page_prot)));
+ put_page(page_table, pte);
}
/*
}
address &= PAGE_MASK;
if (!vma->vm_ops || !vma->vm_ops->nopage) {
- ++vma->vm_mm->rss;
- ++tsk->min_flt;
- get_empty_page(tsk, vma, page_table);
+ get_empty_page(tsk, vma, page_table, write_access);
return;
}
++tsk->maj_flt;
#include <asm/system.h>
#include <asm/pgtable.h>
-/*
- * Map memory not associated with any file into a process
- * address space. Adjacent memory is merged.
- */
-static inline int anon_map(struct inode *ino, struct file * file, struct vm_area_struct * vma)
-{
- if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
- return -ENOMEM;
- return 0;
-}
-
/*
* description of effects of mapping type and prot in current implementation.
* this is due to the limited x86 page protection hardware. The expected
unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long off)
{
- int error;
struct vm_area_struct * vma;
if ((len = PAGE_ALIGN(len)) == 0)
do_munmap(addr, len); /* Clear old maps */
- if (file)
- error = file->f_op->mmap(file->f_inode, file, vma);
- else
- error = anon_map(NULL, NULL, vma);
+ if (file) {
+ int error = file->f_op->mmap(file->f_inode, file, vma);
- if (error) {
- kfree(vma);
- return error;
+ if (error) {
+ kfree(vma);
+ return error;
+ }
}
+
flags = vma->vm_flags;
insert_vm_struct(current, vma);
merge_segments(current, vma->vm_start, vma->vm_end);
--- /dev/null
+/*
+ * linux/mm/remap.c
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ */
+
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/shm.h>
+#include <linux/errno.h>
+#include <linux/mman.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+#include <linux/swap.h>
+
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+static inline pte_t *get_one_pte(struct mm_struct *mm, unsigned long addr)
+{
+ pgd_t * pgd;
+ pmd_t * pmd;
+ pte_t * pte = NULL;
+
+ pgd = pgd_offset(mm, addr);
+ if (pgd_none(*pgd))
+ goto end;
+ if (pgd_bad(*pgd)) {
+ printk("move_one_page: bad source pgd (%08lx)\n", pgd_val(*pgd));
+ pgd_clear(pgd);
+ goto end;
+ }
+
+ pmd = pmd_offset(pgd, addr);
+ if (pmd_none(*pmd))
+ goto end;
+ if (pmd_bad(*pmd)) {
+ printk("move_one_page: bad source pmd (%08lx)\n", pmd_val(*pmd));
+ pmd_clear(pmd);
+ goto end;
+ }
+
+ pte = pte_offset(pmd, addr);
+ if (pte_none(*pte))
+ pte = NULL;
+end:
+ return pte;
+}
+
+static inline pte_t *alloc_one_pte(struct mm_struct *mm, unsigned long addr)
+{
+ pmd_t * pmd;
+ pte_t * pte = NULL;
+
+ pmd = pmd_alloc(pgd_offset(mm, addr), addr);
+ if (pmd)
+ pte = pte_alloc(pmd, addr);
+ return pte;
+}
+
+static inline int copy_one_pte(pte_t * src, pte_t * dst)
+{
+ int error = 0;
+ pte_t pte = *src;
+
+ if (!pte_none(pte)) {
+ error++;
+ if (dst) {
+ pte_clear(src);
+ set_pte(dst, pte);
+ error--;
+ }
+ }
+ return error;
+}
+
+static int move_one_page(struct mm_struct *mm, unsigned long old_addr, unsigned long new_addr)
+{
+ int error = 0;
+ pte_t * src;
+
+ src = get_one_pte(mm, old_addr);
+ if (src)
+ error = copy_one_pte(src, alloc_one_pte(mm, new_addr));
+ return error;
+}
+
+static int move_page_tables(struct mm_struct * mm,
+ unsigned long new_addr, unsigned long old_addr, unsigned long len)
+{
+ unsigned long offset = len;
+
+ invalidate_range(mm, old_addr, old_addr + len);
+
+ /*
+ * This is not the clever way to do this, but we're taking the
+ * easy way out on the assumption that most remappings will be
+ * only a few pages.. This also makes error recovery easier.
+ */
+ while (offset) {
+ offset -= PAGE_SIZE;
+ if (move_one_page(mm, old_addr + offset, new_addr + offset))
+ goto oops_we_failed;
+ }
+ return 0;
+
+ /*
+ * Ok, the move failed because we didn't have enough pages for
+ * the new page table tree. This is unlikely, but we have to
+ * take the possibility into account. In that case we just move
+ * all the pages back (this will work, because we still have
+ * the old page tables)
+ */
+oops_we_failed:
+ while ((offset += PAGE_SIZE) < len)
+ move_one_page(mm, new_addr + offset, old_addr + offset);
+ invalidate_range(mm, new_addr, new_addr + len);
+ zap_page_range(mm, new_addr, new_addr + len);
+ return -1;
+}
+
+static inline unsigned long move_vma(struct vm_area_struct * vma,
+ unsigned long addr, unsigned long old_len, unsigned long new_len)
+{
+ struct vm_area_struct * new_vma;
+
+ new_vma = (struct vm_area_struct *)
+ kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+ if (new_vma) {
+ unsigned long new_addr = get_unmapped_area(addr, new_len);
+
+ if (new_addr && !move_page_tables(current->mm, new_addr, addr, old_len)) {
+ *new_vma = *vma;
+ new_vma->vm_start = new_addr;
+ new_vma->vm_end = new_addr+new_len;
+ new_vma->vm_offset = vma->vm_offset + (addr - vma->vm_start);
+ if (new_vma->vm_inode)
+ new_vma->vm_inode->i_count++;
+ if (new_vma->vm_ops && new_vma->vm_ops->open)
+ new_vma->vm_ops->open(new_vma);
+ insert_vm_struct(current, new_vma);
+ merge_segments(current, new_vma->vm_start, new_vma->vm_end);
+ do_munmap(addr, old_len);
+ return new_addr;
+ }
+ kfree(new_vma);
+ }
+ return -ENOMEM;
+}
+
+/*
+ * Expand (or shrink) an existing mapping, potentially moving it at the
+ * same time (controlled by the "may_move" flag and available VM space)
+ */
+asmlinkage unsigned long sys_mremap(unsigned long addr,
+ unsigned long old_len, unsigned long new_len,
+ int may_move)
+{
+ struct vm_area_struct *vma;
+
+ if (addr & ~PAGE_MASK)
+ return -EINVAL;
+ old_len = PAGE_ALIGN(old_len);
+ new_len = PAGE_ALIGN(new_len);
+ if (old_len == new_len)
+ return addr;
+
+ /*
+ * Always allow a shrinking remap: that just unmaps
+ * the unnecessary pages..
+ */
+ if (old_len > new_len) {
+ do_munmap(addr+new_len, old_len - new_len);
+ return addr;
+ }
+
+ /*
+ * Ok, we need to grow..
+ */
+ vma = find_vma(current, addr);
+ if (!vma || vma->vm_start > addr)
+ return -EFAULT;
+ /* We can't remap across vm area boundaries */
+ if (old_len > vma->vm_end - addr)
+ return -EFAULT;
+ if (vma->vm_flags & VM_LOCKED) {
+ unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
+ locked += new_len - old_len;
+ if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+ return -EAGAIN;
+ }
+
+ /* old_len exactly to the end of the area.. */
+ if (old_len == vma->vm_end - addr) {
+ unsigned long max_addr = TASK_SIZE;
+ if (vma->vm_next)
+ max_addr = vma->vm_next->vm_start;
+ /* can we just expand the current mapping? */
+ if (max_addr - addr >= new_len) {
+ int pages = (new_len - old_len) >> PAGE_SHIFT;
+ vma->vm_end = addr + new_len;
+ current->mm->total_vm += pages;
+ if (vma->vm_flags & VM_LOCKED)
+ current->mm->locked_vm += pages;
+ return addr;
+ }
+ }
+
+ /*
+ * We weren't able to just expand or shrink the area,
+ * we need to create a new one and move it..
+ */
+ if (!may_move)
+ return -ENOMEM;
+ return move_vma(vma, addr, old_len, new_len);
+}
endif
ifdef CONFIG_IPX
-O_OBJS += p8022.o psnap.o
+OX_OBJS += p8022.o psnap.o
endif
ifdef CONFIG_ATALK
ifndef CONFIG_IPX
-O_OBJS += p8022.o psnap.o
+OX_OBJS += p8022.o psnap.o
endif
endif
+#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <net/datalink.h>
#include <linux/mm.h>
#include <linux/in.h>
+#include <net/p8022.h>
static struct datalink_proto *p8022_list = NULL;
NULL,
NULL,
};
+
+static struct symbol_table p8022_proto_syms = {
+#include <linux/symtab_begin.h>
+ X(register_8022_client),
+ X(unregister_8022_client),
+#include <linux/symtab_end.h>
+};
void p8022_proto_init(struct net_proto *pro)
{
p8022_packet_type.type=htons(ETH_P_802_2);
dev_add_pack(&p8022_packet_type);
+ register_symtab(&p8022_proto_syms);
}
struct datalink_proto *
return proto;
}
+void unregister_8022_client(unsigned char type)
+{
+ struct datalink_proto *tmp, **clients = &p8022_list;
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+
+ while ((tmp = *clients) != NULL)
+ {
+ if (tmp->type[0] == type) {
+ *clients = tmp->next;
+ kfree_s(tmp, sizeof(struct datalink_proto));
+ break;
+ } else {
+ clients = &tmp->next;
+ }
+ }
+
+ restore_flags(flags);
+}
return proto;
}
+void destroy_8023_client(struct datalink_proto *dl)
+{
+ if (dl)
+ kfree_s(dl,sizeof(struct datalink_proto));
+}
+
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <net/datalink.h>
/*
* Set up the SNAP layer
*/
+
+static struct symbol_table snap_proto_syms = {
+#include <linux/symtab_begin.h>
+ X(register_snap_client),
+ X(unregister_snap_client),
+#include <linux/symtab_end.h>
+};
void snap_proto_init(struct net_proto *pro)
{
snap_dl=register_8022_client(0xAA, snap_rcv);
if(snap_dl==NULL)
printk("SNAP - unable to register with 802.2\n");
+ register_symtab(&snap_proto_syms);
}
/*
return proto;
}
+/*
+ * Unregister SNAP clients. Protocols no longer want to play with us ...
+ */
+
+void unregister_snap_client(unsigned char *desc)
+{
+ struct datalink_proto **clients = &snap_list;
+ struct datalink_proto *tmp;
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+
+ while ((tmp = *clients) != NULL)
+ {
+ if (memcmp(tmp->type,desc,5) == 0)
+ {
+ *clients = tmp->next;
+ kfree_s(tmp, sizeof(struct datalink_proto));
+ break;
+ }
+ else
+ clients = &tmp->next;
+ }
+
+ restore_flags(flags);
+}
+
source net/ipv4/Config.in
fi
comment ' '
-bool 'The IPX protocol' CONFIG_IPX
-if [ "$CONFIG_IPX" = "y" ]; then
+tristate 'The IPX protocol' CONFIG_IPX
+if [ ! "$CONFIG_IPX" = "n" ]; then
bool 'Full internal IPX network' CONFIG_IPX_INTERN
fi
-bool 'Appletalk DDP' CONFIG_ATALK
+tristate 'Appletalk DDP' CONFIG_ATALK
bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25
if [ "$CONFIG_AX25" = "y" ]; then
bool 'AX.25 over Ethernet' CONFIG_BPQETHER
MOD_SUB_DIRS := ipv4
ALL_SUB_DIRS := 802 ax25 core ethernet ipv4 ipx unix appletalk netrom
SUB_DIRS := 802 core ethernet unix
+MOD_LIST_NAME := NET_MISC_MODULES
ifeq ($(CONFIG_INET),y)
SUB_DIRS += ipv4
ifeq ($(CONFIG_IPX),y)
SUB_DIRS += ipx
+else
+ ifeq ($(CONFIG_IPX),m)
+ MOD_SUB_DIRS += ipx
+ endif
endif
ifeq ($(CONFIG_ATALK),y)
SUB_DIRS += appletalk
+else
+ ifeq ($(CONFIG_ATALK),m)
+ MOD_SUB_DIRS += appletalk
+ endif
endif
ifeq ($(CONFIG_NETROM),y)
L_TARGET := network.a
L_OBJS := socket.o protocols.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o))
+ifeq ($(CONFIG_MODULES),y)
+LX_OBJS = netsyms.o
+endif
+
M_OBJS :=
ifeq ($(CONFIG_NETLINK),y)
O_TARGET := appletalk.o
O_OBJS := aarp.o ddp.o
+M_OBJS := $(O_TARGET)
include $(TOPDIR)/Rules.make
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/bitops.h>
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/if_ether.h>
-#include <linux/if_arp.h>
#include <linux/inet.h>
#include <linux/notifier.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/datalink.h>
#include <net/psnap.h>
#include <linux/atalk.h>
-#ifdef CONFIG_ATALK
/*
* Lists of aarp entries
*/
0
};
+static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3};
+
void aarp_proto_init(void)
{
- static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3};
if((aarp_dl=register_snap_client(aarp_snap_id, aarp_rcv))==NULL)
printk("Unable to register AARP with SNAP.\n");
init_timer(&aarp_timer);
add_timer(&aarp_timer);
register_netdevice_notifier(&aarp_notifier);
}
-#endif
+
+
+#ifdef MODULE
+
+/* Free all the entries in an aarp list. Caller should turn off interrupts. */
+static void free_entry_list(struct aarp_entry *list)
+{
+ struct aarp_entry *tmp;
+
+ while (list != NULL)
+ {
+ tmp = list->next;
+ aarp_expire(list);
+ list = tmp;
+ }
+}
+
+/* General module cleanup. Called from cleanup_module() in ddp.c. */
+void aarp_cleanup_module(void)
+{
+ unsigned long flags;
+ int i;
+
+ save_flags(flags);
+ cli();
+
+ del_timer(&aarp_timer);
+ unregister_netdevice_notifier(&aarp_notifier);
+ unregister_snap_client(aarp_snap_id);
+
+ for (i = 0; i < AARP_HASH_SIZE; i++)
+ {
+ free_entry_list(resolved[i]);
+ free_entry_list(unresolved[i]);
+ }
+
+ restore_flags(flags);
+}
+
+#endif /* MODULE */
* Alan Cox : Supports new ARPHRD_LOOPBACK
* Christer Weinigel : Routing and /proc fixes.
* Bradford Johnson : Locatalk.
+ * Tom Dyas : Module support.
+ * Alan Cox : Hooks for PPP (based on the
+ * localtalk hook).
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* ASYNC I/O
*/
+#include <linux/config.h>
+#include <linux/module.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/bitops.h>
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/if_ether.h>
-#include <linux/if_arp.h>
#include <linux/route.h>
#include <linux/inet.h>
#include <linux/notifier.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <linux/termios.h> /* For TIOCOUTQ/INQ */
#include <net/datalink.h>
#include <linux/stat.h>
#include <linux/firewall.h>
-#ifdef CONFIG_ATALK
#undef APPLETALK_DEBUG
}
if(sk->wmem_alloc == 0 && sk->rmem_alloc == 0 && sk->dead)
+ {
kfree_s(sk,sizeof(*sk));
+ MOD_DEC_USE_COUNT;
+ }
else
{
/*
ntohs(s->protinfo.af_at.dest_net),
s->protinfo.af_at.dest_node,
s->protinfo.af_at.dest_port);
- len += sprintf (buffer+len,"%08lX:%08lX ", s->wmem_alloc, s->rmem_alloc);
+ len += sprintf (buffer+len,"%08X:%08X ", s->wmem_alloc, s->rmem_alloc);
len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid);
/* Are we still dumping unwanted data then discard the record */
* now for the 1.4 release as is.
*
*/
- if(atif->dev->type == ARPHRD_LOCALTLK &&
- atif->dev->do_ioctl)
+ if((atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP)
+ && atif->dev->do_ioctl)
{
/* fake up the request and pass it down */
sa = (struct sockaddr_at*)&atreq.ifr_addr;
if(sa->sat_family!=AF_APPLETALK)
return -EINVAL;
if(dev->type!=ARPHRD_ETHER&&dev->type!=ARPHRD_LOOPBACK
- &&dev->type!=ARPHRD_LOCALTLK)
+ &&dev->type!=ARPHRD_LOCALTLK && dev->type!=ARPHRD_PPP)
return -EPROTONOSUPPORT;
nr=(struct netrange *)&sa->sat_zero[0];
/*
kfree_s((void *)sk,sizeof(*sk));
return(-ESOCKTNOSUPPORT);
}
+
+ MOD_INC_USE_COUNT;
+
sk->dead=0;
sk->next=NULL;
sk->broadcast=0;
/*
* Receive a packet (in skb) from device dev. This has come from the SNAP decoder, and on entry
* skb->h.raw is the DDP header, skb->len is the DDP length. The physical headers have been
- * extracted.
+ * extracted. PPP should probably pass frames marked as for this layer
+ * [ie ARPHRD_ETHERTALK]
*/
static int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
NULL
};
+struct packet_type ppptalk_packet_type=
+{
+ 0,
+ NULL,
+ atalk_rcv,
+ NULL,
+ NULL
+};
+
+static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B};
+
+
/* Called by proto.c on kernel start up */
void atalk_proto_init(struct net_proto *pro)
{
- static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B};
(void) sock_register(atalk_proto_ops.family, &atalk_proto_ops);
if ((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL)
printk("Unable to register DDP with SNAP.\n");
ltalk_packet_type.type=htons(ETH_P_LOCALTALK);
dev_add_pack(<alk_packet_type);
+ ppptalk_packet_type.type=htons(ETH_P_PPPTALK);
+ dev_add_pack(&ppptalk_packet_type);
+
register_netdevice_notifier(&ddp_notifier);
aarp_proto_init();
atalk_if_get_info
});
- printk("Appletalk 0.16 for Linux NET3.033\n");
+ printk("Appletalk 0.17 for Linux NET3.034\n");
}
-#endif
+
+#ifdef MODULE
+
+int init_module(void)
+{
+ atalk_proto_init(NULL);
+ register_symtab(0);
+ return 0;
+}
+
+/*
+ * FIX THIS: If there are any routes/devices configured
+ * for appletalk we must not be unloaded.
+ */
+
+/* Remove all route entries. Interrupts must be off. */
+extern inline void free_route_list(void)
+{
+ struct atalk_route *list = atalk_router_list, *tmp;
+
+ while (list != NULL)
+ {
+ tmp = list->next;
+ kfree_s(list, sizeof(struct atalk_route));
+ list = tmp;
+ }
+}
+
+/* Remove all interface entries. Interrupts must be off. */
+extern inline void free_interface_list(void)
+{
+ struct atalk_iface *list = atalk_iface_list, *tmp;
+
+ while (list != NULL)
+ {
+ tmp = list->next;
+ kfree_s(list, sizeof(struct atalk_iface));
+ list = tmp;
+ }
+}
+
+void cleanup_module(void)
+{
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+
+ aarp_cleanup_module();
+
+ proc_net_unregister(PROC_NET_ATALK);
+ proc_net_unregister(PROC_NET_AT_ROUTE);
+ proc_net_unregister(PROC_NET_ATIF);
+ unregister_netdevice_notifier(&ddp_notifier);
+ dev_remove_pack(<alk_packet_type);
+ dev_remove_pack(&ppptalk_packet_type);
+ unregister_snap_client(ddp_snap_id);
+ sock_unregister(atalk_proto_ops.family);
+
+ free_route_list();
+ free_interface_list();
+
+ restore_flags(flags);
+}
+
+#endif /* MODULE */
len += sprintf(buffer + len, " %s", ax25->dama_slave? " slave" : " no");
if (ax25->sk != NULL) {
- len += sprintf(buffer + len, " %5ld %5ld\n",
+ len += sprintf(buffer + len, " %5d %5d\n",
ax25->sk->wmem_alloc,
ax25->sk->rmem_alloc);
} else {
ax25_cs_get_info
});
- printk("G4KLX/GW4PTS AX.25 for Linux. Version 0.31 BETA for Linux NET3.032 (Linux 1.3.53)\n");
+ printk("G4KLX/GW4PTS AX.25 for Linux. Version 0.32 BETA for Linux NET3.034 (Linux 1.3.77)\n");
#ifdef CONFIG_BPQETHER
proc_net_register(&(struct proc_dir_entry) {
* freeing it).
*/
struct sk_buff *ourskb=skb_clone(skb, GFP_ATOMIC);
- dev_kfree_skb(skb, FREE_READ);
+ dev_kfree_skb(skb, FREE_WRITE);
if(ourskb==NULL)
return 1;
skb_pull(ourskb, AX25_HEADER_LEN - 1); /* Keep PID */
else
kfree_skb(skb, FREE_WRITE);
-
/*
* Again, see if we can transmit anything now.
* [Ought to take this out judging by tests it slows
if(ifr.ifr_mtu<68)
return -EINVAL;
- dev->mtu = ifr.ifr_mtu;
- ret = 0;
+
+ if (dev->change_mtu)
+ ret = (*dev->change_mtu)(dev, ifr.ifr_mtu);
+ else
+ {
+ dev->mtu = ifr.ifr_mtu;
+ ret = 0;
+ }
break;
case SIOCGIFMEM: /* Get the per device memory space. We can add this but currently
extern int ni65_init(void);
extern int pi_init(void);
extern int dec21040_init(void);
+extern void sdla_setup(void);
+extern void dlci_setup(void);
int net_dev_init(void)
{
#if defined(CONFIG_DEC_ELCP)
dec21040_init();
#endif
+#if defined(CONFIG_DLCI)
+ dlci_setup();
+#endif
+#if defined(CONFIG_SDLA)
+ sdla_setup();
+#endif
/*
* SLHC if present needs attaching so other people see it
* even if not opened.
return proto;
}
+void destroy_EII_client(struct datalink_proto *dl)
+{
+ if (dl)
+ kfree_s(dl, sizeof(struct datalink_proto));
+}
if [ "$CONFIG_NET_ALIAS" = "y" ]; then
tristate 'IP: aliasing support' CONFIG_IP_ALIAS
fi
+if [ "$CONFIG_KERNELD" = "y" ]; then
+ bool 'IP: ARP daemon support (experimental)' CONFIG_ARPD
+fi
comment '(it is safe to leave these untouched)'
bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP
tristate 'IP: Reverse ARP' CONFIG_INET_RARP
int i;
- printk("Swansea University Computer Society TCP/IP for NET3.033\n");
+ printk("Swansea University Computer Society TCP/IP for NET3.034\n");
/*
* Tell SOCKET that we are alive...
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- *
* Fixes:
* Alan Cox : Removed the ethernet assumptions in Florian's code
* Alan Cox : Fixed some small errors in the ARP logic
* Eckes : ARP ioctl control errors.
* Alexey Kuznetsov: Arp free fix.
* Manuel Rodriguez: Gratutious ARP.
+ * Jonathan Layes : Added arpd support through kerneld
+ * message queue (960314)
*/
/* RFC1122 Status:
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/errno.h>
-#include <linux/if_arp.h>
#include <linux/in.h>
#include <linux/mm.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
#include <linux/trdevice.h>
#include <linux/skbuff.h>
#include <linux/proc_fs.h>
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
+#ifdef CONFIG_ARPD
+#include <linux/kerneld.h>
+#endif /* CONFIG_ARPD */
#include <asm/system.h>
#include <asm/segment.h>
static struct arp_table *arp_backlog;
+/* If we have arpd configured, assume that we will be running arpd and keep
+ the internal cache small */
+#ifdef CONFIG_ARPD
+#define ARP_MAXSIZE 256
+#endif /* CONFIG_ARPD */
+
+static unsigned int arp_size = 0;
+
static void arp_run_bh(void);
static void arp_check_expire (unsigned long);
restore_flags(flags);
kfree_s(entry, sizeof(struct arp_table));
+ --arp_size;
return;
}
return count;
}
+
+/*
+ * Force the expiry of an entry in the internal cache so the memory
+ * can be used for a new request or for loading a query from arpd.
+ * I'm not really sure what the best algorithm should be, so I just
+ * search for the oldest. NOTE: make sure the cache is locked before
+ * jumping into this function! If someone wants to do something
+ * other than searching the whole cache, by all means do so!
+ */
+
+#ifdef CONFIG_ARPD
+static int arp_force_expire(void)
+{
+ int i;
+ struct arp_table *entry = NULL;
+ struct arp_table **pentry = NULL;
+ struct arp_table **oldest_entry = NULL, **last_resort = NULL;
+ unsigned long oldest_used = ~0;
+
+#if RT_CACHE_DEBUG >= 2
+ printk("Looking for something to force expire.\n");
+#endif
+ for (i = 0; i < ARP_TABLE_SIZE; i++)
+ {
+ pentry = &arp_tables[i];
+
+ while ((entry = *pentry) != NULL)
+ {
+ if (entry->last_used < oldest_used)
+ {
+ if (arp_count_hhs(entry) == 0)
+ {
+ oldest_entry = pentry;
+ }
+ last_resort = pentry;
+ oldest_used = entry->last_used;
+ }
+ pentry = &entry->next; /* go to next entry */
+ }
+ }
+ if (oldest_entry == NULL)
+ {
+ if (last_resort == NULL)
+ return -1;
+ oldest_entry = last_resort;
+ }
+
+ entry = *oldest_entry;
+ *oldest_entry = (*oldest_entry)->next;
+#if RT_CACHE_DEBUG >= 2
+ printk("Force expiring %08x\n", entry->ip);
+#endif
+ arp_free_entry(entry);
+ return 0;
+}
+#endif /* CONFIG_ARPD */
+
+
+static void arpd_update(struct arp_table * entry, int loc)
+{
+#ifdef CONFIG_ARPD
+ static struct arpd_request arpreq;
+
+ arpreq.req = ARPD_UPDATE;
+ arpreq.ip = entry->ip;
+ arpreq.mask = entry->mask;
+ memcpy (arpreq.ha, entry->ha, MAX_ADDR_LEN);
+ arpreq.loc = loc;
+ arpreq.last_used = entry->last_used;
+ arpreq.last_updated = entry->last_updated;
+ arpreq.flags = entry->flags;
+ arpreq.dev = entry->dev;
+
+ kerneld_send(KERNELD_ARP, 0, sizeof(arpreq),
+ (char *) &arpreq, NULL);
+#endif /* CONFIG_ARPD */
+}
+
+/*
+ * Allocate memory for a new entry. If we are at the maximum limit
+ * of the internal ARP cache, arp_force_expire() an entry. NOTE:
+ * arp_force_expire() needs the cache to be locked, so therefore
+ * arp_add_entry() should only be called with the cache locked too!
+ */
+
+static struct arp_table * arp_add_entry(void)
+{
+ struct arp_table * entry;
+
+#ifdef CONFIG_ARPD
+ if (arp_size >= ARP_MAXSIZE)
+ {
+ if (arp_force_expire() < 0)
+ return NULL;
+ }
+#endif /* CONFIG_ARPD */
+
+ entry = (struct arp_table *)
+ kmalloc(sizeof(struct arp_table),GFP_ATOMIC);
+
+ if (entry != NULL)
+ ++arp_size;
+ return entry;
+}
+
+
+/*
+ * Lookup ARP entry by (addr, dev) pair in the arpd.
+ */
+
+static struct arp_table * arpd_lookup(u32 addr, unsigned short flags,
+ struct device * dev,
+ int loc)
+{
+#ifdef CONFIG_ARPD
+ static struct arpd_request arpreq, retreq;
+ struct arp_table * entry;
+ int rv, i;
+
+ arpreq.req = ARPD_LOOKUP;
+ arpreq.ip = addr;
+ arpreq.loc = loc;
+
+ rv = kerneld_send(KERNELD_ARP,
+ sizeof(retreq) | KERNELD_WAIT,
+ sizeof(arpreq),
+ (char *) &arpreq,
+ (char *) &retreq);
+ /* don't worry about rv != 0 too much, it's probably
+ because arpd isn't running or an entry couldn't
+ be found */
+
+ if (rv != 0)
+ return NULL;
+ if (dev != retreq.dev)
+ return NULL;
+ if (! memcmp (retreq.ha, "\0\0\0\0\0\0", 6))
+ return NULL;
+
+ arp_fast_lock();
+ entry = arp_add_entry();
+ arp_unlock();
+
+ if (entry == NULL)
+ return NULL;
+
+ entry->next = NULL;
+ entry->last_used = retreq.last_used;
+ entry->last_updated = retreq.last_updated;
+ entry->flags = retreq.flags;
+ entry->ip = retreq.ip;
+ entry->mask = retreq.mask;
+ memcpy (entry->ha, retreq.ha, MAX_ADDR_LEN);
+ arpreq.dev = entry->dev;
+
+ skb_queue_head_init(&entry->skb);
+ entry->hh = NULL;
+ entry->retries = 0;
+
+#if RT_CACHE_DEBUG >= 2
+ printk("Inserting arpd entry %08x\n in local cache.", entry->ip);
+#endif
+ i = HASH(entry->ip);
+ arp_fast_lock();
+ entry->next = arp_tables[i]->next;
+ arp_tables[i]->next = entry;
+ arp_unlock();
+ return entry;
+#endif /* CONFIG_ARPD */
+ return NULL;
+}
+
+
/*
* Invalidate all hh's, so that higher level will not try to use it.
*/
if (!(entry->flags & ATF_PERM)) {
memcpy(entry->ha, sha, dev->addr_len);
entry->last_updated = jiffies;
+ arpd_update(entry, __LINE__);
}
if (!(entry->flags & ATF_COM))
{
if (grat)
goto end;
- entry = (struct arp_table *)kmalloc(sizeof(struct arp_table),GFP_ATOMIC);
+ entry = arp_add_entry();
if(entry == NULL)
{
arp_unlock();
+#if RT_CACHE_DEBUG >= 2
printk("ARP: no memory for new arp entry\n");
+#endif
kfree_skb(skb, FREE_READ);
return 0;
}
entry->timer.data = (unsigned long)entry;
memcpy(entry->ha, sha, dev->addr_len);
entry->last_updated = entry->last_used = jiffies;
+ arpd_update(entry, __LINE__);
/*
* make entry point to 'correct' device
*/
}
else
{
-#if RT_CACHE_DEBUG >= 1
+#if RT_CACHE_DEBUG >= 2
printk("arp_rcv: %08x backlogged\n", entry->ip);
#endif
arp_enqueue(&arp_backlog, entry);
arp_fast_lock();
entry = arp_lookup(paddr, 0, dev);
+ if (entry == NULL)
+ entry = arpd_lookup(paddr, 0, dev, __LINE__);
if (entry != NULL)
{
if (entry->flags & ATF_COM)
{
memcpy(haddr, entry->ha, dev->addr_len);
+ arpd_update(entry, __LINE__);
arp_unlock();
return 1;
}
}
+ arpd_update(entry, __LINE__);
arp_unlock();
return 0;
}
* Find an entry
*/
entry = arp_lookup(paddr, 0, dev);
+ if (entry == NULL)
+ entry = arpd_lookup(paddr, 0, dev, __LINE__);
if (entry != NULL) /* It exists */
{
entry->last_used = jiffies;
memcpy(haddr, entry->ha, dev->addr_len);
+ arpd_update(entry, __LINE__);
if (skb)
skb->arp = 1;
arp_unlock();
* Create a new unresolved entry.
*/
- entry = (struct arp_table *) kmalloc(sizeof(struct arp_table),
- GFP_ATOMIC);
+ entry = arp_add_entry();
if (entry != NULL)
{
entry->last_updated = entry->last_used = jiffies;
memset(entry->ha, 0, dev->addr_len);
entry->dev = dev;
entry->hh = NULL;
+ arpd_update(entry, __LINE__);
init_timer(&entry->timer);
entry->timer.function = arp_expire_request;
entry->timer.data = (unsigned long)entry;
}
else
{
-#if RT_CACHE_DEBUG >= 1
+#if RT_CACHE_DEBUG >= 2
printk("arp_find: %08x backlogged\n", entry->ip);
#endif
arp_enqueue(&arp_backlog, entry);
arp_fast_lock();
entry = arp_lookup(paddr, 0, dev);
+ if (entry == NULL)
+ entry = arpd_lookup(paddr, 0, dev, __LINE__);
if (entry)
{
hh->hh_refcnt++;
restore_flags(flags);
entry->last_used = jiffies;
+ arpd_update(entry, __LINE__);
arp_unlock();
return 0;
}
* Create a new unresolved entry.
*/
- entry = (struct arp_table *) kmalloc(sizeof(struct arp_table),
- GFP_ATOMIC);
+ entry = arp_add_entry();
if (entry == NULL)
{
kfree_s(hh, sizeof(struct hh_cache));
memset(entry->ha, 0, dev->addr_len);
entry->dev = dev;
entry->hh = hh;
+ arpd_update(entry, __LINE__);
ATOMIC_INCR(&hh->hh_refcnt);
init_timer(&entry->timer);
entry->timer.function = arp_expire_request;
*/
entry = arp_lookup(ip, r->arp_flags & ~ATF_NETMASK, dev);
+ if (entry == NULL)
+ entry = arpd_lookup(ip, r->arp_flags & ~ATF_NETMASK, dev, __LINE__);
if (entry)
{
if (entry == NULL)
{
- entry = (struct arp_table *) kmalloc(sizeof(struct arp_table),
- GFP_ATOMIC);
+ entry = arp_add_entry();
if (entry == NULL)
{
arp_unlock();
ha = dev->dev_addr;
memcpy(entry->ha, ha, dev->addr_len);
entry->last_updated = entry->last_used = jiffies;
+ arpd_update(entry, __LINE__);
entry->flags = r->arp_flags | ATF_COM;
if ((entry->flags & ATF_PUBL) && (entry->flags & ATF_NETMASK))
{
arp_fast_lock();
entry = arp_lookup(si->sin_addr.s_addr, r->arp_flags|ATF_NETMASK, dev);
+ if (entry == NULL)
+ entry = arpd_lookup(si->sin_addr.s_addr,
+ r->arp_flags|ATF_NETMASK, dev, __LINE__);
if (entry == NULL)
{
#include <net/ip_alias.h>
/*
- * AF_INET alias init
+ * AF_INET alias init
*/
-static int
-ip_alias_init_1(struct net_alias_type *this, struct net_alias *alias, struct sockaddr *sa)
+
+static int ip_alias_init_1(struct net_alias_type *this, struct net_alias *alias, struct sockaddr *sa)
{
#ifdef ALIAS_USER_LAND_DEBUG
- printk("alias_init(%s) called.\n", alias->name);
+ printk("alias_init(%s) called.\n", alias->name);
#endif
- MOD_INC_USE_COUNT;
- return 0;
+ MOD_INC_USE_COUNT;
+ return 0;
}
/*
- * AF_INET alias done
+ * AF_INET alias done
*/
-static int
-ip_alias_done_1(struct net_alias_type *this, struct net_alias *alias)
+
+static int ip_alias_done_1(struct net_alias_type *this, struct net_alias *alias)
{
#ifdef ALIAS_USER_LAND_DEBUG
- printk("alias_done(%s) called.\n", alias->name);
+ printk("alias_done(%s) called.\n", alias->name);
#endif
- MOD_DEC_USE_COUNT;
- return 0;
+ MOD_DEC_USE_COUNT;
+ return 0;
}
/*
- * print alias address info
+ * Print alias address info
*/
-int
-ip_alias_print_1(struct net_alias_type *this, struct net_alias *alias, char *buf, int len)
+int ip_alias_print_1(struct net_alias_type *this, struct net_alias *alias, char *buf, int len)
{
- char *p;
+ char *p;
- p = (char *) &alias->dev.pa_addr;
- return sprintf(buf, "%d.%d.%d.%d",
- (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
+ p = (char *) &alias->dev.pa_addr;
+ return sprintf(buf, "%d.%d.%d.%d",
+ (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
}
-struct device *
-ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct sockaddr *sa)
+struct device *ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct sockaddr *sa)
{
- __u32 addr;
- struct rtable *rt;
+ __u32 addr;
+ struct rtable *rt;
+ struct device *dev=NULL;
- /*
- * defensive...
- */
+ /*
+ * Defensive...
+ */
- if (main_dev == NULL) return NULL;
-
- /*
- * get u32 address.
- */
-
- addr = (sa)? (*(struct sockaddr_in *)sa).sin_addr.s_addr : 0;
-
- if (addr == 0) return NULL;
-
- /*
- * find 'closest' device to address given. any other suggestions? ...
- * net_alias module will check if returned device is main_dev's alias
- */
-
- rt = ip_rt_route(addr, 0);
-
- return (rt)? rt->rt_dev : NULL;
-
+ if (main_dev == NULL)
+ return NULL;
+
+ /*
+ * Get u32 address.
+ */
+
+ addr = (sa)? (*(struct sockaddr_in *)sa).sin_addr.s_addr : 0;
+ if (addr == 0)
+ return NULL;
+
+ /*
+ * Find 'closest' device to address given. any other suggestions? ...
+ * net_alias module will check if returned device is main_dev's alias
+ */
+
+ rt = ip_rt_route(addr, 0);
+ if(rt)
+ {
+ dev=rt->rt_dev;
+ ip_rt_put(rt);
+ }
+ return dev;
}
/*
struct net_alias_type ip_alias_type =
{
- AF_INET, /* type */
- 0, /* n_attach */
- "ip", /* name */
- NULL, /* get_addr32() */
- NULL, /* dev_addr_chk() */
- ip_alias_dev_select, /* dev_select() */
- ip_alias_init_1, /* alias_init_1() */
- ip_alias_done_1, /* alias_done_1() */
- ip_alias_print_1, /* alias_print_1() */
- NULL /* next */
+ AF_INET, /* type */
+ 0, /* n_attach */
+ "ip", /* name */
+ NULL, /* get_addr32() */
+ NULL, /* dev_addr_chk() */
+ ip_alias_dev_select, /* dev_select() */
+ ip_alias_init_1, /* alias_init_1() */
+ ip_alias_done_1, /* alias_done_1() */
+ ip_alias_print_1, /* alias_print_1() */
+ NULL /* next */
};
/*
int ip_alias_init(void)
{
- return register_net_alias_type(&ip_alias_type, AF_INET);
+ return register_net_alias_type(&ip_alias_type, AF_INET);
}
/*
int ip_alias_done(void)
{
- return unregister_net_alias_type(&ip_alias_type);
+ return unregister_net_alias_type(&ip_alias_type);
}
#ifdef MODULE
int init_module(void)
{
- if (ip_alias_init() != 0)
- return -EIO;
- return 0;
+ if (ip_alias_init() != 0)
+ return -EIO;
+ return 0;
}
void cleanup_module(void)
{
- if (ip_alias_done() != 0)
- printk("ip_alias: can't remove module");
+ if (ip_alias_done() != 0)
+ printk("ip_alias: can't remove module");
}
#endif /* MODULE */
* we calculated.
*/
#ifndef CONFIG_IP_NO_ICMP_REDIRECT
- if (dev == dev2 && !((iph->saddr^iph->daddr)&dev->pa_mask) &&
- (rt->rt_flags&RTF_MODIFIED) && !opt->srr)
- icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
+ if (dev == dev2 &&
+ !((iph->saddr^dev->pa_addr)&dev->pa_mask) &&
+ (rt->rt_flags&RTF_MODIFIED) && !opt->srr)
+ icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
#endif
#ifdef CONFIG_IP_MROUTE
}
if (ntohs(iph->frag_off) & IP_DF)
{
ip_statistics.IpFragFails++;
- printk("ip_queue_xmit: frag needed\n");
+ NETDEBUG(printk("ip_queue_xmit: frag needed\n"));
return;
}
skb_trim(skb,ntohs(iph->tot_len));
+ /*
+ * Try to select closest <src,dst> alias device, if any.
+ * net_alias_dev_rcv_sel32 returns main device if it
+ * fails to found other.
+ */
+
+#ifdef CONFIG_NET_ALIAS
+ if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev))
+ skb->dev = dev = net_alias_dev_rcv_sel32(skb->dev, AF_INET, iph->saddr, iph->daddr);
+#endif
+
if (iph->ihl > 5)
{
skb->ip_summed = 0;
#endif
}
- /*
- * Try to select closest <src,dst> alias device, if any.
- * net_alias_dev_rcv_sel32 returns main device if it
- * fails to found other.
- */
-
-#ifdef CONFIG_NET_ALIAS
- if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev))
- skb->dev = dev = net_alias_dev_rcv_sel32(skb->dev, AF_INET, iph->saddr, iph->daddr);
-#endif
-
/*
* Account for the packet (even if the packet is
* not accepted by the firewall!).
off_t begin=0;
s_array = pro->sock_array;
- len += sprintf(buffer, "sl local_address rem_address st tx_queue rx_queue tr tm->when uid\n");
+ len += sprintf(buffer, "sl local_address rem_address st tx_queue "
+ "rx_queue tr tm->when uid inode\n");
/*
* This was very pretty but didn't work when a socket is destroyed
* at the wrong moment (eg a syn recv socket getting a reset), or
timer_active=timer_active2;
timer_expires=sp->timer.expires;
}
- len += sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08X:%08X %02X:%08lX %08X %d %d\n",
+ len += sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X"
+ " %02X %08X:%08X %02X:%08lX %08X %d %d %ld\n",
i, src, srcp, dest, destp, sp->state,
format==0?sp->write_seq-sp->rcv_ack_seq:sp->wmem_alloc,
format==0?sp->acked_seq-sp->copied_seq:sp->rmem_alloc,
timer_active, timer_expires-jiffies, (unsigned) sp->retransmits,
(sp->socket&&SOCK_INODE(sp->socket))?SOCK_INODE(sp->socket)->i_uid:0,
- timer_active?sp->timeout:0);
+ timer_active?sp->timeout:0,
+ sp->socket && SOCK_INODE(sp->socket) ?
+ SOCK_INODE(sp->socket)->i_ino : 0);
if (timer_active1) add_timer(&sp->retransmit_timer);
if (timer_active2) add_timer(&sp->timer);
/*
O_TARGET := ipx.o
O_OBJS := af_ipx.o
+M_OBJS := $(O_TARGET)
include $(TOPDIR)/Rules.make
* Supports sendmsg/recvmsg
* Revision 0.33: Internal network support, routing changes, uses a
* protocol private area for ipx data.
+ * Revision 0.34: Module support. <Jim Freeman>
*
* Portions Copyright (c) 1995 Caldera, Inc. <greg@caldera.com>
* Neither Greg Page nor Caldera, Inc. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.
*/
-
+
+#include <linux/module.h>
+
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
-#include <linux/ipx.h>
-#include <linux/inet.h>
#include <linux/netdevice.h>
+#include <net/ipx.h>
+#include <linux/inet.h>
#include <linux/route.h>
-#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <linux/stat.h>
#include <linux/firewall.h>
-#ifdef CONFIG_IPX
+#ifdef MODULE
+static void ipx_proto_finito(void);
+#endif /* def MODULE */
+
/* Configuration Variables */
static unsigned char ipxcfg_max_hops = 16;
static char ipxcfg_auto_select_primary = 0;
static struct datalink_proto *p8023_datalink = NULL;
static struct datalink_proto *pSNAP_datalink = NULL;
-static ipx_interface *ipx_interfaces = NULL;
static ipx_route *ipx_routes = NULL;
-static ipx_interface *ipx_internal_net = NULL;
+static ipx_interface *ipx_interfaces = NULL;
static ipx_interface *ipx_primary_net = NULL;
+static ipx_interface *ipx_internal_net = NULL;
static int
ipxcfg_set_auto_create(char val)
}
kfree_s(sk,sizeof(*sk));
+ MOD_DEC_USE_COUNT;
}
/* The following code is used to support IPX Interfaces (IPXITF). An
*/
static ipx_route * ipxrtr_lookup(unsigned long);
-
+
static void
ipxitf_clear_primary_net(void)
{
ipx_internal_net = NULL;
kfree_s(intrfc, sizeof(*intrfc));
+ /* sockets still dangling
+ * - must be closed from user space
+ */
+ return;
}
static int
if (ipxcfg_auto_select_primary && (ipx_primary_net == NULL))
ipx_primary_net = intrfc;
+ return;
}
static int
/*
* Route an outgoing frame from a socket.
*/
-
+
static int ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len)
{
struct sk_buff *skb;
/*
* We use a normal struct rtentry for route handling
*/
-
+
static int ipxrtr_ioctl(unsigned int cmd, void *arg)
{
int err;
* Handling for system calls applied via the various interfaces to an IPX socket object *
* *
\*******************************************************************************************************************/
-
+
static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
switch(cmd)
sk->error_report=def_callback1;
sk->zapped=1;
+ MOD_INC_USE_COUNT;
return 0;
}
static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
{
- if(newsock->data)
+ if(newsock->data) {
kfree_s(newsock->data,sizeof(ipx_socket));
+ MOD_DEC_USE_COUNT;
+ }
return -EOPNOTSUPP;
}
NULL,
NULL,
};
-
+
static struct packet_type ipx_dix_packet_type =
{
0, /* MUTTER ntohs(ETH_P_IPX),*/
NULL,
NULL,
};
-
+
static struct notifier_block ipx_dev_notifier={
ipxitf_device_event,
NULL,
extern struct datalink_proto *make_EII_client(void);
extern struct datalink_proto *make_8023_client(void);
+extern void destroy_EII_client(struct datalink_proto *);
+extern void destroy_8023_client(struct datalink_proto *);
-void ipx_proto_init(struct net_proto *pro)
-{
- unsigned char val = 0xE0;
- unsigned char snapval[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 };
+struct proc_dir_entry ipx_procinfo = {
+ PROC_NET_IPX, 3, "ipx", S_IFREG | S_IRUGO,
+ 1, 0, 0, 0, &proc_net_inode_operations, ipx_get_info
+};
+struct proc_dir_entry ipx_if_procinfo = {
+ PROC_NET_IPX_INTERFACE, 13, "ipx_interface", S_IFREG | S_IRUGO,
+ 1, 0, 0, 0, &proc_net_inode_operations, ipx_interface_get_info
+};
+
+struct proc_dir_entry ipx_rt_procinfo = {
+ PROC_NET_IPX_ROUTE, 9, "ipx_route", S_IFREG | S_IRUGO,
+ 1, 0, 0, 0, &proc_net_inode_operations, ipx_rt_get_info
+};
+
+static unsigned char ipx_8022_type = 0xE0;
+static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 };
+
+void
+ipx_proto_init(struct net_proto *pro)
+{
(void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
pEII_datalink = make_EII_client();
ipx_8023_packet_type.type=htons(ETH_P_802_3);
dev_add_pack(&ipx_8023_packet_type);
- if ((p8022_datalink = register_8022_client(val, ipx_rcv)) == NULL)
+ if ((p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv)) == NULL)
printk("IPX: Unable to register with 802.2\n");
- if ((pSNAP_datalink = register_snap_client(snapval, ipx_rcv)) == NULL)
+ if ((pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv)) == NULL)
printk("IPX: Unable to register with SNAP\n");
register_netdevice_notifier(&ipx_dev_notifier);
- proc_net_register(&(struct proc_dir_entry) {
- PROC_NET_IPX, 3, "ipx",
- S_IFREG | S_IRUGO, 1, 0, 0,
- 0, &proc_net_inode_operations,
- ipx_get_info
- });
- proc_net_register(&(struct proc_dir_entry) {
- PROC_NET_IPX_INTERFACE, 13, "ipx_interface",
- S_IFREG | S_IRUGO, 1, 0, 0,
- 0, &proc_net_inode_operations,
- ipx_interface_get_info
- });
- proc_net_register(&(struct proc_dir_entry) {
- PROC_NET_IPX_ROUTE, 9, "ipx_route",
- S_IFREG | S_IRUGO, 1, 0, 0,
- 0, &proc_net_inode_operations,
- ipx_rt_get_info
- });
+ proc_net_register(&ipx_procinfo);
+ proc_net_register(&ipx_if_procinfo);
+ proc_net_register(&ipx_rt_procinfo);
- printk("Swansea University Computer Society IPX 0.33 for NET3.032\n");
+ printk("Swansea University Computer Society IPX 0.34 for NET3.034\n");
printk("IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
}
-#endif
+
+#ifdef MODULE
+/* Note on MOD_{INC,DEC}_USE_COUNT:
+ *
+ * Use counts are incremented/decremented when
+ * sockets are created/deleted.
+ *
+ * Routes are always associated with an interface, and
+ * allocs/frees will remain properly accounted for by
+ * their associated interfaces.
+ *
+ * Ergo, before the ipx module can be removed, all IPX
+ * sockets be closed from user space.
+ */
+
+static void
+ipx_proto_finito(void)
+{ ipx_interface *ifc;
+
+ while (ipx_interfaces) {
+ ifc = ipx_interfaces;
+ ipx_interfaces = ifc->if_next;
+ ifc->if_next = NULL;
+ ipxitf_down(ifc);
+ }
+
+ proc_net_unregister(PROC_NET_IPX_ROUTE);
+ proc_net_unregister(PROC_NET_IPX_INTERFACE);
+ proc_net_unregister(PROC_NET_IPX);
+
+ unregister_netdevice_notifier(&ipx_dev_notifier);
+
+ unregister_snap_client(ipx_snap_id);
+ pSNAP_datalink = NULL;
+
+ unregister_8022_client(ipx_8022_type);
+ p8022_datalink = NULL;
+
+ dev_remove_pack(&ipx_8023_packet_type);
+ destroy_8023_client(p8023_datalink);
+ p8023_datalink = NULL;
+
+ dev_remove_pack(&ipx_dix_packet_type);
+ destroy_EII_client(pEII_datalink);
+ pEII_datalink = NULL;
+
+ (void) sock_unregister(ipx_proto_ops.family);
+
+ return;
+}
+
+int init_module(void)
+{
+ ipx_proto_init(NULL);
+ register_symtab(0);
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ ipx_proto_finito();
+ return;
+}
+#endif /* def MODULE */
ax2asc(&s->nr->user_addr));
len += sprintf(buffer + len, "%-9s ",
ax2asc(&s->nr->dest_addr));
- len += sprintf(buffer + len, "%-9s %-3s %02X/%02X %02X/%02X %2d %2d %2d %2d %3d/%03d %2d/%02d %2d/%02d %3d %3d %5ld %5ld\n",
+ len += sprintf(buffer + len, "%-9s %-3s %02X/%02X %02X/%02X %2d %2d %2d %2d %3d/%03d %2d/%02d %2d/%02d %3d %3d %5d %5d\n",
ax2asc(&s->nr->source_addr),
devname, s->nr->my_index, s->nr->my_id,
s->nr->your_index, s->nr->your_id,
{
sock_register(nr_proto_ops.family, &nr_proto_ops);
register_netdevice_notifier(&nr_dev_notifier);
- printk("G4KLX NET/ROM for Linux. Version 0.4 ALPHA for AX25.030 Linux 1.3.45\n");
+ printk("G4KLX NET/ROM for Linux. Version 0.4 ALPHA for AX25.032 Linux 1.3.77\n");
nr_default.quality = NR_DEFAULT_QUAL;
nr_default.obs_count = NR_DEFAULT_OBS;
#include <linux/fcntl.h>
#include <linux/in.h>
#include <linux/if_ether.h> /* For the statistics structure. */
-#include <linux/if_arp.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <net/ip.h>
--- /dev/null
+/*
+ * linux/net/netsyms.c
+ *
+ * Symbol table for the linux networking subsystem. Moved here to
+ * make life simpler in ksyms.c.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/in.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/firewall.h>
+#include <linux/trdevice.h>
+#include <linux/ioport.h>
+
+#ifdef CONFIG_AX25
+#include <net/ax25.h>
+#endif
+
+#ifdef CONFIG_INET
+#include <linux/ip.h>
+#include <linux/etherdevice.h>
+#include <net/protocol.h>
+#include <net/arp.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <net/tcp.h>
+#include <net/icmp.h>
+#include <net/route.h>
+#include <linux/net_alias.h>
+#endif
+
+#ifdef CONFIG_NET_ALIAS
+#include <linux/net_alias.h>
+#endif
+
+#if defined(CONFIG_ULTRA) || defined(CONFIG_WD80x3) || \
+ defined(CONFIG_EL2) || defined(CONFIG_NE2000) || \
+ defined(CONFIG_E2100) || defined(CONFIG_HPLAN_PLUS) || \
+ defined(CONFIG_HPLAN) || defined(CONFIG_AC3200)
+#include "../drivers/net/8390.h"
+#endif
+
+extern int (*rarp_ioctl_hook)(int,void*);
+
+#ifdef CONFIG_IPX_MODULE
+extern struct datalink_proto *make_EII_client(void);
+extern struct datalink_proto *make_8023_client(void);
+extern void destroy_EII_client(struct datalink_proto *);
+extern void destroy_8023_client(struct datalink_proto *);
+#endif
+
+
+static struct symbol_table net_syms = {
+#include <linux/symtab_begin.h>
+
+ /* Socket layer registration */
+ X(sock_register),
+ X(sock_unregister),
+
+ /* Socket layer support routines */
+ X(memcpy_fromiovec),
+ X(sock_setsockopt),
+ X(sock_getsockopt),
+ X(sock_wake_async),
+ X(sock_alloc_send_skb),
+ X(skb_recv_datagram),
+ X(skb_free_datagram),
+ X(skb_copy_datagram),
+ X(skb_copy_datagram_iovec),
+ X(datagram_select),
+
+#ifdef CONFIG_IPX_MODULE
+ X(make_8023_client),
+ X(destroy_8023_client),
+ X(make_EII_client),
+ X(destroy_EII_client),
+#endif
+
+#ifdef CONFIG_FIREWALL
+ /* Firewall registration */
+ X(register_firewall),
+ X(unregister_firewall),
+#endif
+
+#ifdef CONFIG_INET
+ /* Internet layer registration */
+ X(inet_add_protocol),
+ X(inet_del_protocol),
+ X(rarp_ioctl_hook),
+ X(init_etherdev),
+ X(ip_rt_route),
+ X(icmp_send),
+ X(ip_options_compile),
+ X(ip_rt_put),
+ X(arp_send),
+#ifdef CONFIG_IP_FORWARD
+ X(ip_forward),
+#endif
+
+#if defined(CONFIG_ULTRA) || defined(CONFIG_WD80x3) || \
+ defined(CONFIG_EL2) || defined(CONFIG_NE2000) || \
+ defined(CONFIG_E2100) || defined(CONFIG_HPLAN_PLUS) || \
+ defined(CONFIG_HPLAN) || defined(CONFIG_AC3200)
+ /* If 8390 NIC support is built in, we will need these. */
+ X(ei_open),
+ X(ei_close),
+ X(ei_debug),
+ X(ei_interrupt),
+ X(ethdev_init),
+ X(NS8390_init),
+#endif
+
+#ifdef CONFIG_NET_ALIAS
+#include <linux/net_alias.h>
+#endif
+
+#endif /* CONFIG_INET */
+
+ /* Device callback registration */
+ X(register_netdevice_notifier),
+ X(unregister_netdevice_notifier),
+
+#ifdef CONFIG_NET_ALIAS
+ X(register_net_alias_type),
+ X(unregister_net_alias_type),
+#endif
+
+ /* support for loadable net drivers */
+#ifdef CONFIG_AX25
+ X(ax25_encapsulate),
+ X(ax25_rebuild_header),
+#endif
+#ifdef CONFIG_INET
+ X(register_netdev),
+ X(unregister_netdev),
+ X(ether_setup),
+ X(eth_type_trans),
+ X(eth_copy_and_sum),
+ X(alloc_skb),
+ X(kfree_skb),
+ X(skb_clone),
+ X(dev_alloc_skb),
+ X(dev_kfree_skb),
+ X(netif_rx),
+ X(dev_tint),
+ X(irq2dev_map),
+ X(dev_add_pack),
+ X(dev_remove_pack),
+ X(dev_get),
+ X(dev_ioctl),
+ X(dev_queue_xmit),
+ X(dev_base),
+ X(dev_close),
+ X(dev_mc_add),
+ X(arp_find),
+ X(n_tty_ioctl),
+ X(tty_register_ldisc),
+ X(kill_fasync),
+#ifdef CONFIG_FIREWALL
+ X(call_in_firewall),
+#endif
+#endif /* CONFIG_INET */
+
+#include <linux/symtab_end.h>
+};
+
+void export_net_symbols(void)
+{
+ register_symtab(&net_syms);
+}
#ifdef CONFIG_INET
#include <linux/inet.h>
#endif
-#ifdef CONFIG_IPX
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
#include <net/ipxcall.h>
#include <net/p8022call.h>
#endif
#include <net/nrcall.h>
#endif
#endif
-#ifdef CONFIG_ATALK
-#ifndef CONFIG_IPX
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
+#if ! ( defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) )
#include <net/p8022call.h>
#endif
#include <net/atalkcall.h>
#ifdef CONFIG_UNIX
{ "UNIX", unix_proto_init }, /* Unix domain socket family */
#endif
-#if defined(CONFIG_IPX)||defined(CONFIG_ATALK)
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) || \
+ defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
{ "802.2", p8022_proto_init }, /* 802.2 demultiplexor */
{ "SNAP", snap_proto_init }, /* SNAP demultiplexor */
#endif
#endif
{ NULL, NULL } /* End marker */
};
-
-
* for NetROM and future kernel nfsd type
* stuff.
* Alan Cox : sendmsg/recvmsg basics.
+ * Tom Dyas : Export net symbols.
*
*
* This program is free software; you can redistribute it and/or
#include <linux/netdevice.h>
#include <linux/proc_fs.h>
#include <linux/firewall.h>
+#include <linux/kerneld.h>
#include <net/netlink.h>
#include <asm/system.h>
#include <asm/segment.h>
+#ifdef CONFIG_MODULES
+extern void export_net_symbols(void);
+#endif
+
static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
int whence);
static int sock_read(struct inode *inode, struct file *file, char *buf,
sock->conn = NULL;
sock->iconn = NULL;
sock->next = NULL;
+ sock->file = NULL;
sock->wait = &inode->i_wait;
sock->inode = inode; /* "backlink": we could use pointer arithmetic instead */
sock->fasync_list = NULL;
if (peersock)
sock_release_peer(peersock);
--sockets_in_use; /* Bookkeeping.. */
+ sock->file=NULL;
iput(SOCK_INODE(sock));
}
* family, then create a fresh socket.
*/
+static int find_protocol_family(int family)
+{
+ register int i;
+ for (i = 0; i < NPROTO; i++)
+ {
+ if (pops[i] == NULL)
+ continue;
+ if (pops[i]->family == family)
+ return i;
+ }
+ return -1;
+}
+
asmlinkage int sys_socket(int family, int type, int protocol)
{
int i, fd;
struct proto_ops *ops;
/* Locate the correct protocol family. */
- for (i = 0; i < NPROTO; ++i)
+ i = find_protocol_family(family);
+
+#ifdef CONFIG_KERNELD
+ /* Attempt to load a protocol module if the find failed. */
+ if (i < 0)
{
- if (pops[i] == NULL) continue;
- if (pops[i]->family == family)
- break;
+ char module_name[30];
+ sprintf(module_name,"net-pf-%d",family);
+ request_module(module_name);
+ i = find_protocol_family(family);
}
+#endif
- if (i == NPROTO)
+ if (i < 0)
{
return -EINVAL;
}
return(-EINVAL);
}
+ sock->file=current->files->fd[fd];
+
return(fd);
}
sock_release(newsock);
return(-EINVAL);
}
-
+ sock->file=current->files->fd[fd];
+
if (upeer_sockaddr)
{
newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 1);
{
int i;
- printk("Swansea University Computer Society NET3.033 for Linux 1.3.50\n");
+ printk("Swansea University Computer Society NET3.034 for Linux 1.3.77\n");
/*
* Initialize all address (protocol) families.
*/
proto_init();
+
+ /*
+ * Export networking symbols to the world.
+ */
+
+#ifdef CONFIG_MODULES
+ export_net_symbols();
+#endif
}
int socket_get_info(char *buffer, char **start, off_t offset, int length)
* Mike Shaver's work.
* Marty Leisner : Fixes to fd passing
* Nick Nevin : recvmsg bugfix.
+ * Alan Cox : Started proper garbage collector
*
* Known differences from reference BSD that was tested:
*
#include <net/af_unix.h>
#include <linux/proc_fs.h>
-static unix_socket *unix_socket_list=NULL;
+unix_socket *unix_socket_list=NULL;
#define min(a,b) (((a)<(b))?(a):(b))
return -EBADF;
}
- /*
- * Make sure the garbage collector can cope.
- */
-
- if(unix_gc_free<num)
- return -ENOBUFS;
-
/* add another reference to these files */
for(i=0; i< num; i++)
{
fp[i]=current->files->fd[fdp[i]];
fp[i]->f_count++;
- unix_gc_add(sk, fp[i]);
+ unix_inflight(fp[i]);
}
return num;
for(i=0;i<num;i++)
{
close_fp(fp[i]);
- unix_gc_remove(fp[i]);
+ unix_notinflight(fp[i]);
}
}
ufp[ufn]=fp[i];
*cmfptr++=ufn;
FD_CLR(ufn,¤t->files->close_on_exec);
- unix_gc_remove(fp[i]);
+ unix_notinflight(fp[i]);
}
/*
* Dump those that don't
for(;i<fdnum;i++)
{
close_fp(fp[i]);
- unix_gc_remove(fp[i]);
+ unix_notinflight(fp[i]);
}
kfree(skb->h.filp);
skb->h.filp=NULL;
int len=0;
unix_socket *s=unix_socket_list;
- len+= sprintf(buffer,"Num RefCount Protocol Flags Type St Path\n");
+ len+= sprintf(buffer,"Num RefCount Protocol Flags Type St "
+ "Inode Path\n");
while(s!=NULL)
{
- len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X",
+ len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X %5ld",
s,
s->protinfo.af_unix.locks,
0,
s->socket->flags,
s->socket->type,
- s->socket->state);
+ s->socket->state,
+ s->socket->inode ? s->socket->inode->i_ino : 0);
if(s->protinfo.af_unix.name!=NULL)
len+=sprintf(buffer+len, " %s\n", s->protinfo.af_unix.name);
else
}
#endif
-static struct proto_ops unix_proto_ops = {
+struct proto_ops unix_proto_ops = {
AF_UNIX,
unix_create,
/*
- * NET3: Garbage Collector For AF_UNIX sockets (STUB)
+ * NET3: Garbage Collector For AF_UNIX sockets (STUBS)
*
- * Authors:
+ * Garbage Collector:
+ * Copyright (C) Barak A. Pearlmutter.
+ * Released under the GPL version 2 or later.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- * Fixes:
+ * NOTE:
+ * We don't actually call this yet. I'm finishing some tests before I
+ * enable it. The bold can add it in themselves.
+ *
+ * Chopped about by Alan Cox 22/3/96 to make it fit the AF_UNIX socket problem.
+ * If it doesnt work blame me, it worked when Barak sent it.
+ *
+ * Assumptions:
+ *
+ * - object w/ a bit
+ * - free list
+ *
+ * Current optimizations:
+ *
+ * - explicit stack instead of recursion
+ * - tail recurse on first born instead of immediate push/pop
+ *
+ * Future optimizations:
+ *
+ * - don't just push entire root set; process in place
+ * - use linked list for internal stack
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Fixes:
*
*/
#include <net/tcp.h>
#include <net/af_unix.h>
#include <linux/proc_fs.h>
+
+/* Internal data structures and random procedures: */
+
+#define MAX_STACK 1000 /* Maximum depth of tree (about 1 page) */
+static unix_socket **stack; /* stack of objects to mark */
+static int in_stack = 0; /* first free entry in stack */
+
+
+extern inline unix_socket *unix_get_socket(struct file *filp)
+{
+ struct socket *s;
+ /*
+ * Socket ?
+ */
+ if(filp->f_inode->i_mode!=S_IFSOCK)
+ return NULL;
+ s=&(filp->f_inode->u.socket_i);
+ /*
+ * AF_UNIX ?
+ */
+ if(s->ops!=&unix_proto_ops)
+ return NULL;
+ /*
+ * Got one.
+ */
+ return s->data;
+}
+
+/*
+ * Keep the number of times in flight count for the file
+ * descriptor if it is for an AF_UNIX socket.
+ */
+
+void unix_inflight(struct file *fp)
+{
+ unix_socket *s=unix_get_socket(fp);
+ if(s)
+ s->protinfo.af_unix.inflight++;
+}
+
+void unix_notinflight(struct file *fp)
+{
+ unix_socket *s=unix_get_socket(fp);
+ if(s)
+ s->protinfo.af_unix.inflight--;
+}
+
+
/*
- * Garbage Collector Stubs
+ * Garbage Collector Support Functions
*/
+extern inline void push_stack(unix_socket *x)
+{
+ if (in_stack == MAX_STACK)
+ panic("can't push onto full stack");
+ stack[in_stack++] = x;
+}
-int unix_gc_free=128; /* GC slots free */
+extern inline unix_socket *pop_stack(void)
+{
+ if (in_stack == 0)
+ panic("can't pop empty gc stack");
+ return stack[--in_stack];
+}
+
+extern inline int empty_stack(void)
+{
+ return in_stack == 0;
+}
-void unix_gc_remove(struct file *fp)
+extern inline void maybe_mark_and_push(unix_socket *x)
{
- ;
+ if (x->protinfo.af_unix.marksweep&MARKED)
+ return;
+ x->protinfo.af_unix.marksweep|=MARKED;
+ push_stack(x);
}
-void unix_gc_add(struct sock *sk, struct file *fp)
+
+/* The external entry point: unix_gc() */
+
+void unix_gc(void)
{
- ;
+ static int in_unix_gc=0;
+ unix_socket *s;
+ unix_socket *next;
+
+ /*
+ * Avoid a recursive GC.
+ */
+
+ if(in_unix_gc)
+ return;
+ in_unix_gc=1;
+
+ stack=(unix_socket **)get_free_page(GFP_KERNEL);
+
+ /*
+ * Assume everything is now unmarked
+ */
+
+ /* Invariant to be maintained:
+ - everything marked is either:
+ -- (a) on the stack, or
+ -- (b) has all of its children marked
+ - everything on the stack is always marked
+ - nothing is ever pushed onto the stack twice, because:
+ -- nothing previously marked is ever pushed on the stack
+ */
+
+ /*
+ * Push root set
+ */
+
+ for(s=unix_socket_list;s!=NULL;s=s->next)
+ {
+ /*
+ * If all instances of the descriptor are not
+ * in flight we are in use.
+ */
+ if(s->socket && s->socket->file && s->socket->file->f_count > s->protinfo.af_unix.inflight)
+ maybe_mark_and_push(s);
+ }
+
+ /*
+ * Mark phase
+ */
+
+ while (!empty_stack())
+ {
+ unix_socket *x = pop_stack();
+ unix_socket *f=NULL,*sk;
+ struct sk_buff *skb;
+tail:
+ skb=skb_peek(&x->receive_queue);
+
+ /*
+ * Loop through all but first born
+ */
+
+ while(skb && skb != (struct sk_buff *)&x->receive_queue)
+ {
+ /*
+ * Do we have file descriptors ?
+ */
+ if(skb->h.filp)
+ {
+ /*
+ * Process the descriptors of this socket
+ */
+ int nfd=*(int *)skb->h.filp;
+ struct file **fp=(struct file **)(skb->h.filp+sizeof(int));
+ while(nfd--)
+ {
+ /*
+ * Get the socket the fd matches if
+ * it indeed does so
+ */
+ if((sk=unix_get_socket(*fp++))!=NULL)
+ {
+ /*
+ * Remember the first, mark the
+ * rest.
+ */
+ if(f==NULL)
+ f=sk;
+ else
+ maybe_mark_and_push(sk);
+ }
+ }
+ }
+ skb=skb->next;
+ }
+ /*
+ * Handle first born specially
+ */
+
+ if (f)
+ {
+ if (!(f->protinfo.af_unix.marksweep&MARKED))
+ {
+ f->protinfo.af_unix.marksweep|=MARKED;
+ x=f;
+ f=NULL;
+ goto tail;
+ }
+ }
+ }
+
+ /*
+ * Sweep phase. NOTE: this part dominates the time complexity
+ */
+
+ for(s=unix_socket_list;s!=NULL;s=next)
+ {
+ next=s->next;
+ if (!(s->protinfo.af_unix.marksweep&MARKED))
+ {
+ /*
+ * We exist only in the passing tree of sockets
+ * that is no longer connected to active descriptors
+ * Time to die..
+ */
+ if(s->socket && s->socket->file)
+ close_fp(s->socket->file);
+ }
+ else
+ s->protinfo.af_unix.marksweep&=~MARKED; /* unmark everything for next collection */
+ }
+
+ in_unix_gc=0;
+
+ free_page((long)stack);
}
#
# Please send comments / questions / bug fixes to raymondc@microsoft.com.
#
-# ***** IMPORTANT COMPATABILITY NOTE ****
+# ***** IMPORTANT COMPATIBILITY NOTE ****
# If configuration changes are made which might adversely effect
# Menuconfig or xconfig, please notify the respective authors so that
# those utilities can be updated in parallel.
#
# 150296 Dick Streefland (dicks@tasking.nl) - report new configuration
# items and ask for a value even when doing a "make oldconfig"
+#
+# 200396 Tom Dyas (tdyas@eden.rutgers.edu) - when the module option is
+# chosen for an item, define the macro <option_name>_MODULE
#
# Make sure we're really running bash.
"m")
echo "$1=m" >>$CONFIG
echo "#undef $1" >>$CONFIG_H
+ echo "#define $1_MODULE 1" >>$CONFIG_H
;;
"n")
#
set -h
+
+
+
+
+#
+# Load the functions used by the config.in files.
+#
+# I do this because these functions must be redefined depending
+# on whether they are being called for interactive use or for
+# saving a configuration to a file.
+#
+# Thank the heavens bash supports nesting function definitions.
+#
+load_functions () {
+
+#
+# Additional comments
+#
+function comment () {
+ comment_ctr=$[ comment_ctr + 1 ]
+ echo -ne "': $comment_ctr' '--- $1' " >>MCmenu
+}
+
+#
+# Don't need this yet, but we don't want to puke either.
+#
+function define_bool () {
+ :
+}
+
+#
+# Create a boolean (Yes/No) function for our current menu
+# which calls our local bool function.
+#
+function bool () {
+ eval $2=\${$2:-'n'} x=\$$2
+
+ case $x in
+ y|m) yes='ON' no='OFF' flag="*"
+ ;;
+ n) yes='OFF' no='ON' flag=" "
+ ;;
+ esac
+
+ echo -ne "'$2' '($flag) $1' " >>MCmenu
+
+ echo -e "function $2 () { l_bool '$1' '$yes' '$no' '$2' }\n" \
+ >>MCradiolists
+}
+
+#
+# Create a tristate (Yes/No/Module) radiolist function
+# which calls our local tristate function.
+#
+# Collapses to a boolean (Yes/No) if module support is disabled.
+#
+function tristate () {
+ if [ "$CONFIG_MODULES" != "y" ]
+ then
+ bool "$1" "$2"
+ else
+ eval $2=\${$2:-'n'} x=\$$2
+
+ case $x in
+ y) yes='ON' no='OFF' module='OFF' flag="*"
+ ;;
+ m) yes='OFF' no='OFF' module='ON' flag="M"
+ ;;
+ *) yes='OFF' no='ON' module='OFF' flag=" "
+ ;;
+ esac
+
+ echo -ne "'$2' '<$flag> $1' " >>MCmenu
+
+ echo -e "
+ function $2 () { \
+ l_tristate '$1' '$yes' '$no' '$module' '$2'
+ }" >>MCradiolists
+ fi
+}
+
+#
+# Create a tristate radiolist function which is dependent on
+# another kernel configuration option.
+#
+# Quote from the original configure script:
+#
+# If the option we depend upon is a module,
+# then the only allowable options are M or N. If Y, then
+# this is a normal tristate. This is used in cases where modules
+# are nested, and one module requires the presence of something
+# else in the kernel.
+#
+function dep_tristate () {
+ if [ "$CONFIG_MODULES" != "y" ]
+ then
+ bool "$1" "$2"
+ else
+ if eval [ "_$3" != "_m" ]
+ then
+ tristate "$1" "$2" $3
+ else
+ mod_bool "$1" "$2"
+ fi
+ fi
+}
+
+#
+# Add a menu item which will call our local int function.
+#
+function int () {
+ eval $2=\${$2:-"$3"} x=\$$2
+
+ echo -ne "'$2' '($x) $1' " >>MCmenu
+
+ echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' }\n" >>MCradiolists
+}
+
+#
+# Add a menu item which will call our local int function.
+#
+function hex () {
+ eval $2=\${$2:-"$3"} x=\${$2##*[x,X]}
+
+ echo -ne "'$2' '($x) $1' " >>MCmenu
+
+ echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' }\n" >>MCradiolists
+}
+
+#
+# Add a menu item which will call our local One-of-Many choice list.
+#
+function choice () {
+ #
+ # Need to remember params cause the're gonna get reset.
+ #
+ title=$1
+ choices=$2
+ default=$3
+ current=
+
+ #
+ # Find out if one of the choices is already set.
+ # If it's not then make it the default.
+ #
+ set -- $choices
+ firstchoice=$2
+
+ while [ -n "$2" ]
+ do
+ if eval [ "_\$$2" = "_y" ]
+ then
+ current=$1
+ break
+ fi
+ shift ; shift
+ done
+
+ : ${current:=$default}
+
+ echo -ne "'$firstchoice' '($current) $title' " >>MCmenu
+
+ echo -e "
+ function $firstchoice () {
+ l_choice '$title' \"$choices\" $current
+ }\n" >>MCradiolists
+}
+
+} # END load_functions()
+
+
+
+
+
#
# Extract available help for an option from Configure.help
# and send it to standard output.
>MCradiolists
}
-#
-# Additional comments
-#
-function comment () {
- comment_ctr=$[ comment_ctr + 1 ]
- echo -ne "': $comment_ctr' '--- $1' " >>MCmenu
-}
-
-#
-# Don't need this yet, but we don't want to puke either.
-#
-function define_bool () {
- :
-}
-
#
# Add a submenu option to the menu currently under construction.
#
$MAKE -C drivers/sound config
}
-
-#
-# Create a boolean (Yes/No) function for our current menu
-# which calls our local bool function.
-#
-function bool () {
- eval $2=\${$2:-'n'} x=\$$2
-
- case $x in
- y|m) yes='ON' no='OFF' flag="*"
- ;;
- n) yes='OFF' no='ON' flag=" "
- ;;
- esac
-
- echo -ne "'$2' '($flag) $1' " >>MCmenu
-
- echo -e "function $2 () { l_bool '$1' '$yes' '$no' '$2' }\n" \
- >>MCradiolists
-}
-
#
# Handle a boolean (Yes/No) option.
#
;;
esac
- echo -ne "'$2' '($flag) $1' " >>MCmenu
+ echo -ne "'$2' '<$flag> $1' " >>MCmenu
echo -e "function $2 () { l_mod_bool '$1' '$module' '$no' '$2' }\n" \
>>MCradiolists
done
}
-#
-# Create a tristate (Yes/No/Module) radiolist function
-# which calls our local tristate function.
-#
-# Collapses to a boolean (Yes/No) if module support is disabled.
-#
-function tristate () {
- if [ "$CONFIG_MODULES" != "y" ]
- then
- bool "$1" "$2"
- else
- eval $2=\${$2:-'n'} x=\$$2
-
- case $x in
- y) yes='ON' no='OFF' module='OFF' flag="*"
- ;;
- m) yes='OFF' no='OFF' module='ON' flag="M"
- ;;
- *) yes='OFF' no='ON' module='OFF' flag=" "
- ;;
- esac
-
- echo -ne "'$2' '($flag) $1' " >>MCmenu
-
- echo -e "
- function $2 () { \
- l_tristate '$1' '$yes' '$no' '$module' '$2'
- }" >>MCradiolists
- fi
-}
-
#
# Handle a tristate (Yes/No/Module) option.
#
done
}
-#
-# Create a tristate radiolist function which is dependent on
-# another kernel configuration option.
-#
-# Quote from the original configure script:
-#
-# If the option we depend upon is a module,
-# then the only allowable options are M or N. If Y, then
-# this is a normal tristate. This is used in cases where modules
-# are nested, and one module requires the presence of something
-# else in the kernel.
-#
-function dep_tristate () {
- if [ "$CONFIG_MODULES" != "y" ]
- then
- bool "$1" "$2"
- else
- if eval [ "_$3" != "_m" ]
- then
- tristate "$1" "$2" $3
- else
- mod_bool "$1" "$2"
- fi
- fi
-}
-
-#
-# Add a menu item which will call our local int function.
-#
-function int () {
- eval $2=\${$2:-"$3"} x=\$$2
-
- echo -ne "'$2' '($x) $1' " >>MCmenu
-
- echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' }\n" >>MCradiolists
-}
-
#
# Create a dialog for entering an integer into a kernel option.
#
done
}
-
-#
-# Add a menu item which will call our local int function.
-#
-function hex () {
- eval $2=\${$2:-"$3"} x=\${$2##*[x,X]}
-
- echo -ne "'$2' '($x) $1' " >>MCmenu
-
- echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' }\n" >>MCradiolists
-}
-
#
# Create a dialog for entering a hexidecimal into a kernel option.
#
}
#
-# Add a menu item which will call our local One-of-Many choice list.
+# Handle a on-of-many choice list.
#
-function choice () {
- #
- # Need to remember params cause the're gonna get reset.
- #
- title=$1
- choices=$2
- default=$3
- current=
-
- #
- # Find out if one of the choices is already set.
- # If it's not then make it the default.
- #
- set -- $choices
- firstchoice=$2
-
- while [ -n "$2" ]
- do
- if eval [ "_\$$2" = "_y" ]
- then
- current=$1
- break
- fi
- shift ; shift
- done
-
- : ${current:=$default}
-
- echo -ne "'$firstchoice' '($current) $title' " >>MCmenu
-
- echo -e "
- function $firstchoice () {
- l_choice '$title' \"$choices\" $current
- }\n" >>MCradiolists
-}
-
-
function l_choice () {
#
# Need to remember params cause the're gonna get reset.
echo 'default=$1' >>MCmenu0
echo "menu_name 'Main Menu'" >>MCmenu0
-
if [ "_$single_menu_mode" = "_TRUE" ]
then
parser2
parser1
fi
+ echo "comment ''" >>MCmenu0
+ echo "g_alt_config" >>MCmenu0
+ echo "s_alt_config" >>MCmenu0
+
echo "}" >>MCmenu0
#
default="${selection%% *}"
case "$selection" in
- *"-->"*) show_readme ;;
+ *"-->"*|\
+ *"alt_config"*) show_readme ;;
*) eval help $selection ;;
esac
;;
done
}
+#
+# Create a menu item to load an alternate configuration file.
+#
+g_alt_config () {
+ echo -n "get_alt_config 'Load an Alternate Configuration File' "\
+ >>MCmenu
+}
+
+#
+# Get alternate config file name and load the
+# configuration from it.
+#
+get_alt_config () {
+ while true
+ do
+ ALT_CONFIG="${ALT_CONFIG:-$DEFAULTS}"
+
+ $DIALOG --backtitle "$backtitle" \
+ --inputbox "\
+Enter the name of the configuration file you wish to load. \
+Accept the name shown to restore the configuration you \
+last retrieved. Leave blank to abort."\
+ 11 55 "$ALT_CONFIG" 2>MCdialog.out
+
+ if [ "$?" = "0" ]
+ then
+ ALT_CONFIG=`cat MCdialog.out`
+
+ [ "_" = "_$ALT_CONFIG" ] && break
+
+ if [ -r "$ALT_CONFIG" ]
+ then
+ load_config_file "$ALT_CONFIG"
+ break
+ else
+ echo -ne "\007"
+ $DIALOG --backtitle "$backtitle" \
+ --infobox "File does not exit!" 3 38
+ sleep 2
+ fi
+ else
+ cat <<EOM >help.out
+
+For various reasons, one may wish to keep several different kernel
+configurations available on a single machine.
+
+If you have saved a previous configuration in a file other than the
+kernel's default, entering the name of the file here will allow you
+to modify that configuration.
+
+If you are uncertain, then you have probably never used alternate
+configuration files. You should therefor leave this blank to abort.
+
+EOM
+ $DIALOG --backtitle "$backtitle"\
+ --title "Load Alternate Configuration"\
+ --textbox help.out $LINES $COLS
+ fi
+ done
+
+ rm -f help.out MCdialog.out
+}
+
+#
+# Create a menu item to store an alternate config file.
+#
+s_alt_config () {
+ echo -n "save_alt_config 'Store an Alternate Configuration File' "\
+ >>MCmenu
+}
+
+#
+# Get an alternate config file name and save the current
+# configuration to it.
+#
+save_alt_config () {
+ while true
+ do
+ $DIALOG --backtitle "$backtitle" \
+ --inputbox "\
+Enter a filename to which this configuration should be saved \
+as an alternate. Leave blank to abort."\
+ 10 55 "$ALT_CONFIG" 2>MCdialog.out
+
+ if [ "$?" = "0" ]
+ then
+ ALT_CONFIG=`cat MCdialog.out`
+
+ [ "_" = "_$ALT_CONFIG" ] && break
+
+ if touch $ALT_CONFIG 2>/dev/null
+ then
+ save_configuration $ALT_CONFIG
+ load_functions ## RELOAD
+ break
+ else
+ echo -ne "\007"
+ $DIALOG --backtitle "$backtitle" \
+ --infobox "Can't create file! Probably a nonexistent directory." 3 60
+ sleep 2
+ fi
+ else
+ cat <<EOM >help.out
+
+For various reasons, one may wish to keep different kernel
+configurations available on a single machine.
+
+Entering a file name here will allow you to later retrieve, modify
+and use the current configuration as an alternate to whatever
+configuration options you have selected at that time.
+
+If you are uncertain what all this means then you should probably
+leave this blank.
+EOM
+ $DIALOG --backtitle "$backtitle"\
+ --title "Store Alternate Configuration"\
+ --textbox help.out $LINES $COLS
+ fi
+ done
+
+ rm -f help.out MCdialog.out
+}
+
+#
+# Load config options from a file.
+# Converts all "# OPTION is not set" lines to "OPTION=" lines
+#
+function load_config_file () {
+ awk '
+ /# .* is not set.*/ { printf("%s=\n", $2) }
+ ! /# .* is not set.*/ { print }
+ ' $1 >.tmpconfig
+
+ source .tmpconfig
+ rm -f .tmpconfig
+}
+
#
# Just what it says.
#
save_configuration () {
${DIALOG} --backtitle "$backtitle" \
- --infobox "Saving your new kernel configuration..." 3 43
+ --infobox "Saving your kernel configuration..." 3 40
#
# Now, let's redefine the configuration functions for final
# output to the config files.
#
+ # Nested function definitions, YIPEE!
+ #
function bool () {
eval define_bool "$2" "\${$2:-n}"
}
;;
n)
- echo "# $1 is not set" >>$CONFIG
+ echo "# $1 is not set" >>$CONFIG
echo "#undef $1" >>$CONFIG_H
;;
esac
fi
}
+ DEF_CONFIG="${1:-.config}"
+ DEF_CONFIG_H="include/linux/autoconf.h"
+
CONFIG=.tmpconfig
CONFIG_H=.tmpconfig.h
if . $CONFIG_IN >>.menuconfig.log 2>&1
then
- #
- # Create the sound driver's config files for cards
- # Which are compatible with the new config method.
- #
- if [ "_$CONFIG_TRIX" != "_y" -a\
- "_$CONFIG_PSS" != "_y" -a\
- "_$CONFIG_SMWAVE" != "_y" ]
+ if [ "$DEF_CONFIG" = ".config" ]
then
- make -C drivers/sound kernelconfig >>.menuconfig.log 2>&1
+ #
+ # Create the sound driver's config files for cards
+ # Which are compatible with the new config method.
+ #
+ if [ "_$CONFIG_TRIX" != "_y" -a\
+ "_$CONFIG_PSS" != "_y" -a\
+ "_$CONFIG_SMWAVE" != "_y" ]
+ then
+ make -C drivers/sound kernelconfig >>.menuconfig.log 2>&1
+ fi
+
+ mv $CONFIG_H $DEF_CONFIG_H
fi
- if [ -f .config ]
+ if [ -f "$DEF_CONFIG" ]
then
- rm -f .config.old
- mv .config .config.old
+ rm -f ${DEF_CONFIG}.old
+ mv $DEF_CONFIG ${DEF_CONFIG}.old
fi
- mv .tmpconfig .config
- mv .tmpconfig.h include/linux/autoconf.h
+
+ mv $CONFIG $DEF_CONFIG
+
return 0
else
return 1
menu_instructions="\
-Arrow keys navigate the menu. \
+The Arrow keys navigate the menu. \
Highlighted letters are hotkeys. \
-Select an item with <Space Bar> or <Enter>. \
-When finished press <Esc><Esc> or <X>. \
-A (*) marks an option to be compiled into the kernel. \
-An (M) marks an option to be compiled as a module."
+Press the <Space Bar> to select an item. \
+Press <Esc><Esc> to exit. \
+Press <?> for Help. \
+(*) options will be compiled into the kernel. \
+(M) options will be modules. \
+< > marks module capable options."
radiolist_instructions="\
Use the arrow keys to navigate this window or \
press the hotkey of the item you wish to select \
followed by the <SPACE BAR>.
-Press <H> for additional information about this option."
+Press <?> for additional information about this option."
inputbox_instructions_int="\
Please enter a decimal value between 1 and 9999. \
trap "cleanup ; rm -f .menuconfig ; exit 1" 1 2 15
+
#
# Locate default files.
#
-DEFAULT=""
-if [ "$1" = "-d" ] ; then
- DEFAULT="-d"
- shift
-fi
-
CONFIG_IN=./config.in
if [ "$1" != "" ] ; then
CONFIG_IN=$1
DEFAULTS=.config
fi
-if [ -f $DEFAULTS ]; then
+if [ -f $DEFAULTS ]
+then
echo "#"
echo "# Using defaults found in" $DEFAULTS
echo "#"
echo "#"
fi
+
# Fresh new log.
>.menuconfig.log
-
$DIALOG --backtitle "$backtitle" \
--infobox "Preparing configuration scripts..." 3 40
echo "# $kernel_version" >.menuconfig
fi
+# Load the functions used by the config.in files.
+load_functions
+
#
# Read config.in files and parse them into one shell function per menu.
#
you may look in the file /usr/src/linux/.menuconfig.log for
information which may help you determine the cause.
+Alternate Configuration Files
+-----------------------------
+Menuconfig supports the use of alternate configuration files for
+those who, for various reasons, find it necessary to switch
+between different kernel configurations.
+
+At the end of the main menu you will find two options. One is
+for saving the current configuration to a file of your choosing.
+The other option is for loading a previously saved alternate
+configuration.
+
+Even if you don't use alternate configuration files, but you
+find during a Menuconfig session that you have completely messed
+up your settings, you may use the "Load Alternate..." option to
+restore your previously saved settings from ".config" without
+restarting Menuconfig.
Other information
-----------------
* Print the termination buttons
*/
static void
-print_buttons(WINDOW *dialog, int height, int width, int okval, int cancelval)
+print_buttons(WINDOW *dialog, int height, int width, int selected)
{
int x = width / 2 - 11;
int y = height - 2;
- print_button (dialog, " Ok ", y, x, okval);
- print_button (dialog, " Help ", y, x + 14, cancelval);
+ print_button (dialog, " Ok ", y, x, selected==0);
+ print_button (dialog, " Help ", y, x + 14, selected==1);
+ wmove(dialog, y, x+1+14*selected);
wrefresh(dialog);
}
draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
border_attr, dialog_attr);
- print_buttons(dialog, height, width, TRUE, FALSE);
+ print_buttons(dialog, height, width, 0);
/* Set up the initial value */
wmove (dialog, box_y, box_x);
switch (button) {
case -1:
button = 1; /* Indicates "Cancel" button is selected */
- print_buttons(dialog, height, width, FALSE, TRUE);
+ print_buttons(dialog, height, width, 1);
break;
case 0:
button = -1; /* Indicates input box is selected */
- print_buttons(dialog, height, width, TRUE, FALSE);
+ print_buttons(dialog, height, width, 0);
wmove (dialog, box_y, box_x + input_x);
wrefresh (dialog);
break;
case 1:
button = 0; /* Indicates "OK" button is selected */
- print_buttons(dialog, height, width, TRUE, FALSE);
+ print_buttons(dialog, height, width, 0);
break;
}
break;
switch (button) {
case -1:
button = 0; /* Indicates "OK" button is selected */
- print_buttons(dialog, height, width, TRUE, FALSE);
+ print_buttons(dialog, height, width, 0);
break;
case 0:
button = 1; /* Indicates "Cancel" button is selected */
- print_buttons(dialog, height, width, FALSE, TRUE);
+ print_buttons(dialog, height, width, 1);
break;
case 1:
button = -1; /* Indicates input box is selected */
- print_buttons(dialog, height, width, TRUE, FALSE);
+ print_buttons(dialog, height, width, 0);
wmove (dialog, box_y, box_x + input_x);
wrefresh (dialog);
break;
(items[(scroll+choice)*2][0] != ':'));
if (key == KEY_UP || key == '-') {
- if (choice < 6 && scroll) {
+ if (choice < 2 && scroll) {
/* Scroll menu down */
scrollok (menu, TRUE);
wscrl (menu, -1);
print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
(items[(scroll+choice)*2][0] != ':'));
- if ((choice > 4) && (scroll + max_choice < item_no)) {
+ if ((choice > max_choice-3) &&
+ (scroll + max_choice < item_no)
+ ) {
/* Scroll menu up */
scrollok (menu, TRUE);
scroll (menu);