Commit 901c8159 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.37

parent b6acc3e2
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -11,10 +11,7 @@ To fix:
o Fix sys_idle to exit/enter kernel state and do hlt's.
o Fix scheduler decisions to reschedule. Per cpu reschedule ?
o Scheduler ignores stick to CPU advantage. Critical for P6!
o FPU state save/restore - fault any process on FPU and do a
restore on the fault each context switch, do a save if we
faulted that run of the task when we switch away. [DONE]
o Scheduler ignores stick to CPU advantage. Critical for P6! [Done - FK]
o Clean up message pass.
o Test for B stepping processors.
o Clean up processor specific/independant split.
......@@ -23,12 +20,7 @@ o Find the exception/crash bug.
o Halt other CPU's on reset/panic doesn't always work.
o Dont waste page at 4K - dont need it now.(watch the GDT code).
o Dump bootup pages once booted somehow.
o Verify message pass safe for >2 CPU's - should be now it
is atomic lock based.
o Dont schedule switches between idle tasks (if current->pid==0 &&
next->pid==0 && next!=current) [IN]
o Clean up warnings/volatiles.
o Send CTRL-ALT-DEL to pid 1 not task[1]! [IN]
o Fix load_TR() for non contiguous processor ids
o Iterate over the slave timer requests if one is lost (keep a count per cpu)
o Distribute irq's (locking present just needs the 82489 to be asked
......
This diff is collapsed.
Tips for using cdu31a.c, the driver for Sony CDU-31A and CDU-33A CDROM
drives.
Corey Minyard (minyard@wf-rch.cirr.com)
CDU31A/CDU33A Driver Info
-------------------------
Information on the Sony CDU31A/CDU33A CDROM driver for the Linux
kernel.
Corey Minyard (minyard@metronet.com)
Colossians 3:17
The Sony interface device driver handles Sony interface CDROM
drives and provides a complete block-level interface as well as an
ioctl() interface compatible with the Sun (as specified in
include/linux/cdrom.h). With this interface, CDROMs can be
accessed and standard audio CDs can be played back normally.
WARNING - All autoprobes have been removed from the driver.
You MUST configure the CDU31A via a LILO config
at boot time or in lilo.conf. I have the
following in my lilo.conf:
append="cdu31a=0x1f88,0,PAS"
The first number is the I/O base address of the
card. The second is the interrupt (0 means none).
The third should be "PAS" if on a Pro-Audio
spectrum, or nothing if on something else.
This interface is (unfortunately) a polled interface. This is
because most Sony interfaces are set up with DMA and interrupts
disables. Some (like mine) do not even have the capability to
handle interrupts or DMA. For this reason you will see a lot of
the following:
retry_count = jiffies+ SONY_JIFFIES_TIMEOUT;
while ((retry_count > jiffies) && (! <some condition to wait for))
{
while (handle_sony_cd_attention())
;
sony_sleep();
}
if (the condition not met)
{
return an error;
}
This ugly hack waits for something to happen, sleeping a little
between every try. it also handles attentions, which are
asynchronous events from the drive informing the driver that a disk
has been inserted, removed, etc.
NEWS FLASH - The driver now supports interrupts but they are
turned off by default. Use of interrupts is highly encouraged, it
cuts CPU usage down to a reasonable level. I had DMA in for a while
but PC DMA is just too slow. Better to just insb() it.
One thing about these drives: They talk in MSF (Minute Second Frame) format.
There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
disk. The funny thing is that these are sent to the drive in BCD, but the
interface wants to see them in decimal. A lot of conversion goes on.
DRIVER SPECIAL FEATURES
-----------------------
This section describes features beyond the normal audio and CD-ROM
functions of the drive.
2048 byte buffer mode
If a disk is mounted with -o block=2048, data is copied straight
from the drive data port to the buffer. Otherwise, the readahead
buffer must be involved to hold the other 1K of data when a 1K
block operation is done. Note that with 2048 byte blocks you
cannot execute files from the CD.
XA compatibility
The driver should support XA disks for both the CDU31A and CDU33A.
It does this transparently, the using program doesn't need to set it.
Multi-Session
A multi-session disk looks just like a normal disk to the user.
Just mount one normally, and all the data should be there.
A special thanks to Koen for help with this!
Raw sector I/O
Using the CDROMREADAUDIO it is possible to read raw audio and data
tracks. Both operations return 2352 bytes per sector. On the data
tracks, the first 12 bytes is not returned by the drive and the value
of that data is indeterminate.
Copyright (C) 1993 Corey Minyard
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
/
/*
Crude Table of Contents
-----------------------
Setting Up the Hardware
Configuring the Kernel
Configuring as a Module
Driver Special Features
Setting up the Sony CDU31A/CDU33A drive interface card. If
You have another card, you are on your own.
This device driver handles Sony CDU31A/CDU33A CDROM drives and
provides a complete block-level interface as well as an ioctl()
interface as specified in include/linux/cdrom.h). With this
interface, CDROMs can be accessed, standard audio CDs can be played
back normally, and CD audio information can be read off the drive.
Note that this will only work for CDU31A/CDU33A drives. Some vendors
market their drives as CDU31A compatible. They lie. Their drives are
really CDU31A hardware interface compatible (they can plug into the
same card). They are not software compatible.
Setting Up the Hardware
-----------------------
The CDU31A driver in unable to safely tell if an interface card is
present that it can use because the interface card does not announce
its presence in any way besides placing 4 I/O locations in memory. It
used to just probe memory and attempt commands, but Linus wisely asked
me to remove that because it could really screw up other hardware in
the system.
Because of this, you must tell the kernel where the drive interface
is, what interrupts are used, and possibly if you are on a PAS-16
soundcard.
If you have the Sony CDU31A/CDU33A drive interface card, the following
diagram will help you set it up. If You have another card, you are on
your own. You need to make sure that the I/O address and interrupt is
not used by another card in the system. You will need to know the I/O
address and interrupt you have set. Note that use of interrupts is
highly recommended, if possible, it really cuts down on CPU used.
Unfortunately, most soundcards do not support interrupts for their
CDROM interfaces. By default, the Sony interface card comes with
interrupts disabled.
+----------+-----------------+----------------------+
| JP1 | 34 Pin Conn | |
......@@ -158,3 +98,99 @@
The documentation states to set this for interrupt
4, but I think that is a mistake.
Note that if you have another interface card, you will need to look at
the documentation to find the I/O base address. This is specified to
the SLCD.SYS driver for DOS with the /B: parameter, so you can look at
you DOS driver setup to find the address, if necessary.
Configuring the Kernel
----------------------
You must tell the kernel where the drive is at boot time. This can be
done at the Linux boot prompt, by using LILO, or by using Bootlin.
Note that this is no substitute for HOWTOs and LILO documentation, if
you are confused please read those for info on bootline configuration
and LILO.
At the linux boot prompt, press the ALT key and add the following line
after the boot name (you can let the kernel boot, it will tell you the
default boot name while booting):
cdu31a=<base address>,<interrupt>[,PAS]
The base address needs to have "0x" in front of it, since it is in
hex. For instanc, to configure a drive at address 320 on interrupt 5,
use the following:
cdu31a=0x320,5
I use the following boot line:
cdu31a=0x1f88,0,PAS
because I have a PAS-16 which does not support interrupt for the
CDU31A interface.
Adding this as an append line at the beginning of the /etc/lilo.conf
file will set it for lilo configurations. I have the following as the
first line in my lilo.conf file:
append="cdu31a=0x1f88,0"
I'm not sure how to set up Bootlin (I have never used it), if someone
would like to fill in this section please do.
Configuring as a Module
-----------------------
The driver supports loading as a module. However, you must specify
the boot address and interrupt on the boot line to insmod. You can't
use modprobe to load it, since modprobe doesn't support setting
variables.
Anyway, I use the following line to load my driver as a module
/sbin/insmod /lib/modules/`uname -r`/misc/cdu31a.o cdu31a_port=0x1f88
You can set the following variables in the driver:
cdu31a_port=<I/O address> - sets the base I/O. If hex, put 0x in
front of it. This must be specified.
cdu31a_irq=<interrupt> - Sets the interrupt number. Leaving this
off will turn interrupts off.
Driver Special Features
-----------------------
This section describes features beyond the normal audio and CD-ROM
functions of the drive.
2048 byte buffer mode
If a disk is mounted with -o block=2048, data is copied straight from
the drive data port to the buffer. Otherwise, the readahead buffer
must be involved to hold the other 1K of data when a 1K block
operation is done. Note that with 2048 byte blocks you cannot execute
files from the CD.
XA compatibility
The driver should support XA disks for both the CDU31A and CDU33A. It
does this transparently, the using program doesn't need to set it.
Multi-Session
A multi-session disk looks just like a normal disk to the user. Just
mount one normally, and all the data should be there. A special
thanks to Koen for help with this!
Raw sector I/O
Using the CDROMREADAUDIO it is possible to read raw audio and data
tracks. Both operations return 2352 bytes per sector. On the data
tracks, the first 12 bytes is not returned by the drive and the value
of that data is indeterminate.
This diff is collapsed.
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 36
SUBLEVEL = 37
ARCH = i386
......@@ -251,7 +251,7 @@ mrproper: clean
rm -f drivers/scsi/aic7xxx_asm drivers/scsi/aic7xxx_seq.h
rm -f drivers/char/uni_hash.tbl drivers/char/conmakehash
rm -f .version .config* config.in config.old
rm -f scripts/tkparse scripts/kconfig.tk
rm -f scripts/tkparse scripts/kconfig.tk scripts/kconfig.tmp
rm -f include/asm
rm -f .depend `find . -name .depend -print`
rm -f .hdepend
......
......@@ -24,13 +24,36 @@ extern unsigned long switch_to_osf_pal(unsigned long nr,
int printk(const char * fmt, ...)
{
va_list args;
int i;
int i, j, written, remaining, num_nl;
static char buf[1024];
char * str;
va_start(args, fmt);
i = vsprintf(buf, fmt, args);
va_end(args);
puts(buf,i);
/* expand \n into \r\n: */
num_nl = 0;
for (j = 0; j < i; ++j) {
if (buf[j] == '\n')
++num_nl;
}
remaining = i + num_nl;
for (j = i - 1; j >= 0; --j) {
buf[j + num_nl] = buf[j];
if (buf[j] == '\n') {
--num_nl;
buf[j + num_nl] = '\r';
}
}
str = buf;
do {
written = puts(str, remaining);
remaining -= written;
str += written;
} while (remaining > 0);
return i;
}
......
......@@ -14,7 +14,8 @@ else
fi
choice 'Alpha system type' \
"Jensen CONFIG_ALPHA_JENSEN \
"Avanti CONFIG_ALPHA_AVANTI \
Jensen CONFIG_ALPHA_JENSEN \
Noname CONFIG_ALPHA_NONAME \
Cabriolet CONFIG_ALPHA_CABRIOLET \
EB66 CONFIG_ALPHA_EB66 \
......@@ -87,7 +88,7 @@ mainmenu_option next_comment
comment 'Sound'
tristate 'Sound card support' CONFIG_SOUND
if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
if [ "$CONFIG_SOUND" != "n" ]; then
source drivers/sound/Config.in
fi
......
......@@ -13,7 +13,7 @@ CONFIG_ALPHA_APECS=y
CONFIG_PCI_OPTIMIZE=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_ELF is not set
#
# Loadable module support
......
......@@ -28,7 +28,7 @@ extern int alpha_sys_type;
#ifdef CONFIG_ALPHA_APECS
#ifdef DEBUG
# define DBG(args) printk(args)
# define DBG(args) printk args
#else
# define DBG(args)
#endif
......@@ -120,6 +120,21 @@ static unsigned int conf_read(unsigned long addr, unsigned char type1)
unsigned int stat0, value;
unsigned int haxr2 = 0; /* to keep gcc quiet */
#ifdef CONFIG_ALPHA_AVANTI
register long s0 asm ("9");
register long s1 asm ("10");
register long s2 asm ("11");
register long s3 asm ("12");
register long s4 asm ("13");
register long s5 asm ("14");
asm volatile ("# %0" : "r="(s0));/* SRM X4.2 on Avanti steps on this */
asm volatile ("# %0" : "r="(s1));/* SRM X4.2 on Avanti steps on this */
asm volatile ("# %0" : "r="(s2));/* SRM X4.2 on Avanti steps on this */
asm volatile ("# %0" : "r="(s3));/* SRM X4.2 on Avanti steps on this */
asm volatile ("# %0" : "r="(s4));/* SRM X4.2 on Avanti steps on this */
asm volatile ("# %0" : "r="(s5));/* SRM X4.2 on Avanti steps on this */
#endif
save_flags(flags); /* avoid getting hit by machine check */
cli();
......@@ -185,6 +200,14 @@ static unsigned int conf_read(unsigned long addr, unsigned char type1)
mb();
}
restore_flags(flags);
#ifdef CONFIG_ALPHA_AVANTI
asm volatile ("# %0" :: "r"(s0));/* SRM X4.2 on Avanti steps on this */
asm volatile ("# %0" :: "r"(s1));/* SRM X4.2 on Avanti steps on this */
asm volatile ("# %0" :: "r"(s2));/* SRM X4.2 on Avanti steps on this */
asm volatile ("# %0" :: "r"(s3));/* SRM X4.2 on Avanti steps on this */
asm volatile ("# %0" :: "r"(s4));/* SRM X4.2 on Avanti steps on this */
asm volatile ("# %0" :: "r"(s5));/* SRM X4.2 on Avanti steps on this */
#endif
return value;
}
......@@ -383,8 +406,8 @@ unsigned long apecs_init(unsigned long mem_start, unsigned long mem_end)
#ifdef CONFIG_ALPHA_CABRIOLET
/*
* JAE: HACK!!! for now, hardwire if configured...
* davidm: miniloader doesn't seem to get clockfrequency
* right, so fix for now.
* davidm: Older miniloader versions don't set the clockfrequency
* right, so hardcode it for now.
*/
if (hwrpb->sys_type == ST_DEC_EB64P) {
hwrpb->sys_type = ST_DEC_EBPC64;
......@@ -438,12 +461,14 @@ void apecs_machine_check(unsigned long vector, unsigned long la_ptr,
DBG(("apecs_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
apecs_mcheck_expected, mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear));
#ifdef DEBUG
unsigned long *ptr;
int i;
{
unsigned long *ptr;
int i;
ptr = (unsigned long *)la_ptr;
for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
printk(" +%x %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
ptr = (unsigned long *)la_ptr;
for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
}
}
#endif /* DEBUG */
......
......@@ -541,29 +541,40 @@ static inline void eb66_and_eb64p_fixup(void)
/*
* Fixup configuration for Noname boards (AXPpci33).
* Fixup configuration for Noname (AXPpci33) and Avanti (AlphaStation 240).
*/
static inline void noname_fixup(void)
static inline void avanti_and_noname_fixup(void)
{
struct pci_dev *dev;
/*
* The Noname board has 5 PCI slots with each of the 4
* interrupt pins routed to different pins on the PCI/ISA
* bridge (PIRQ0-PIRQ3). I don't have any information yet as
* to how INTB, INTC, and INTD get routed (4/12/95,
* davidm@cs.arizona.edu). pirq_tab[0] is a fake entry to
* deal with old PCI boards that have the interrupt pin number
* hardwired to 0 (meaning that they use the default INTA
* line, if they are interrupt driven at all).
* bridge (PIRQ0-PIRQ3). The table below is based on
* information available at:
*
* http://ftp.digital.com/pub/DEC/axppci/ref_interrupts.txt
*
* I have no information on the Avanti interrupt routing, but
* the routing seems to be identical to the Noname except
* that the Avanti has an additional slot whose routing I'm
* unsure of.
*
* pirq_tab[0] is a fake entry to deal with old PCI boards
* that have the interrupt pin number hardwired to 0 (meaning
* that they use the default INTA line, if they are interrupt
* driven at all).
*/
static const char pirq_tab[7][5] = {
{ 3, 3, -1, -1, -1}, /* idsel 6 (53c810) */
{-1, -1, -1, -1, -1}, /* idsel 7 (PCI/ISA bridge) */
static const char pirq_tab[][5] = {
{ 3, 3, 3, 3, 3}, /* idsel 6 (53c810) */
{-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */
{ 2, 2, -1, -1, -1}, /* idsel 8 (slot closest to ISA) */
{-1, -1, -1, -1, -1}, /* idsel 9 (unused) */
{-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
{ 0, 0, -1, -1, -1}, /* idsel 11 (slot furthest from ISA) */
{ 1, 1, -1, -1, -1}, /* idsel 12 (middle slot) */
{ 0, 0, 2, 1, 0}, /* idsel 11 (slot furthest from ISA) KN25_PCI_SLOT0 */
{ 1, 1, 0, 2, 1}, /* idsel 12 (middle slot) KN25_PCI_SLOT1 */
#ifdef CONFIG_ALPHA_AVANTI
{ 1, 1, -1, -1, -1}, /* idsel 13 KN25_PCI_SLOT2 ??? */
#endif /* CONFIG_ALPHA_AVANTI */
};
/*
* route_tab selects irq routing in PCI/ISA bridge so that:
......@@ -571,6 +582,9 @@ static inline void noname_fixup(void)
* PIRQ1 -> irq 9
* PIRQ2 -> irq 10
* PIRQ3 -> irq 11
*
* This probably ought to be configurable via MILO. For
* example, sound boards seem to like using IRQ 9.
*/
const unsigned int route_tab = 0x0b0a090f;
unsigned char pin;
......@@ -587,13 +601,13 @@ static inline void noname_fixup(void)
for (dev = pci_devices; dev; dev = dev->next) {
dev->irq = 0;
if (dev->bus->number != 0 ||
PCI_SLOT(dev->devfn) < 6 || PCI_SLOT(dev->devfn) > 12)
PCI_SLOT(dev->devfn) < 6 ||
PCI_SLOT(dev->devfn) >= 6 + sizeof(pirq_tab)/sizeof(pirq_tab[0]))
{
printk("noname_set_irq: no dev on bus %d, slot %d!!\n",
printk("bios32.avanti_and_noname_fixup: no dev on bus %d, slot %d!!\n",
dev->bus->number, PCI_SLOT(dev->devfn));
continue;
}
pcibios_read_config_byte(dev->bus->number, dev->devfn,
PCI_INTERRUPT_PIN, &pin);
pirq = pirq_tab[PCI_SLOT(dev->devfn) - 6][pin];
......@@ -644,8 +658,8 @@ unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
/*
* Now is the time to do all those dirty little deeds...
*/
#if defined(CONFIG_ALPHA_NONAME)
noname_fixup();
#if defined(CONFIG_ALPHA_NONAME) || defined(CONFIG_ALPHA_AVANTI)
avanti_and_noname_fixup();
#elif defined(CONFIG_ALPHA_CABRIOLET)
cabriolet_fixup();
#elif defined(CONFIG_ALPHA_EB66P)
......
......@@ -606,7 +606,7 @@ sys_call_table:
.quad sys_open, do_entSys, sys_getxgid, osf_sigprocmask, do_entSys
/*50*/ .quad do_entSys, sys_acct, do_entSys, do_entSys, sys_ioctl
.quad do_entSys, do_entSys, sys_symlink, sys_readlink, sys_execve
.quad sys_umask, do_entSys, do_entSys, sys_getpgrp, sys_getpagesize
.quad sys_umask, sys_chroot, do_entSys, sys_getpgrp, sys_getpagesize
.quad do_entSys, osf_vfork, sys_newstat, sys_newlstat, do_entSys
.quad do_entSys, osf_mmap, do_entSys, sys_munmap, sys_mprotect
.quad sys_madvise, sys_vhangup, do_entSys, do_entSys, sys_getgroups
......
......@@ -30,11 +30,11 @@ extern void timer_interrupt(struct pt_regs * regs);
static unsigned char cache_21 = 0xff;
static unsigned char cache_A1 = 0xff;
#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P)
#if NR_IRQS == 33
static unsigned char cache_804 = 0xef;
static unsigned char cache_805 = 0xff;
static unsigned char cache_806 = 0xff;
#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
#elif NR_IRQS == 32
static unsigned char cache_26 = 0xdf;
static unsigned char cache_27 = 0xff;
#endif
......@@ -54,7 +54,7 @@ void disable_irq(unsigned int irq_nr)
} else if (irq_nr < 16) {
cache_A1 |= mask;
outb(cache_A1,0xA1);
#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P)
#if NR_IRQS == 33
} else if (irq_nr < 24) {
cache_804 |= mask;
outb(cache_804, 0x804);
......@@ -64,7 +64,7 @@ void disable_irq(unsigned int irq_nr)
} else {
cache_806 |= mask;
outb(cache_806, 0x806);
#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
#elif NR_IRQS == 32
} else if (irq_nr < 24) {
cache_26 |= mask;
outb(cache_26, 0x26);
......@@ -91,7 +91,7 @@ void enable_irq(unsigned int irq_nr)
} else if (irq_nr < 16) {
cache_A1 &= mask;
outb(cache_A1,0xA1);
#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P)
#if NR_IRQS == 33
} else if (irq_nr < 24) {
cache_804 &= mask;
outb(cache_804, 0x804);
......@@ -101,7 +101,7 @@ void enable_irq(unsigned int irq_nr)
} else {
cache_806 &= mask;
outb(cache_806, 0x806);
#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
#elif NR_IRQS == 32
} else if (irq_nr < 24) {
cache_26 &= mask;
outb(cache_26, 0x26);
......@@ -166,7 +166,7 @@ static inline void mask_irq(int irq)
} else if (irq < 16) {
cache_A1 |= mask;
outb(cache_A1, 0xA1);
#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P)
#if NR_IRQS == 33
} else if (irq < 24) {
cache_804 |= mask;
outb(cache_804, 0x804);
......@@ -176,7 +176,7 @@ static inline void mask_irq(int irq)
} else {
cache_806 |= mask;
outb(cache_806, 0x806);
#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB66P)
#elif NR_IRQS == 32
} else if (irq < 24) {
cache_26 |= mask;
outb(cache_26, 0x26);
......@@ -197,7 +197,7 @@ static inline void unmask_irq(unsigned long irq)
} else if (irq < 16) {
cache_A1 &= mask;
outb(cache_A1, 0xA1);
#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P)
#if NR_IRQS == 33
} else if (irq < 24) {
cache_804 &= mask;
outb(cache_804, 0x804);
......@@ -295,8 +295,6 @@ static void unexpected_irq(int irq, struct pt_regs * regs)
outb(0x0c, 0x2fc);
outb(0,0x61);
outb(0,0x461);
#elif defined(CONFIG_ALPHA_NONAME)
printk("61=%02x, 64=%02x, 60=%02x\n", inb(0x61), inb(0x64), inb(0x60));
#endif
}
......@@ -507,11 +505,11 @@ unsigned long probe_irq_on(void)
/* now filter out any obviously spurious interrupts */
irqmask = (((unsigned long)cache_A1)<<8) | (unsigned long) cache_21;
#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P)
#if NR_IRQS == 33
irqmask |= ((((unsigned long)cache_804)<<16) |
(((unsigned long)cache_805)<<24) |
(((unsigned long)cache_806)<<24));
#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
#elif NR_IRQS == 32
irqmask |= ((((unsigned long)cache_26)<<16) |
(((unsigned long)cache_27)<<24));
#endif
......@@ -530,11 +528,11 @@ int probe_irq_off(unsigned long irqs)
int i;
irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P)
#if NR_IRQS == 33
irqmask |= ((((unsigned long)cache_804)<<16) |
(((unsigned long)cache_805)<<24) |
(((unsigned long)cache_806)<<24));
#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
#elif NR_IRQS == 32
irqmask |= ((((unsigned long)cache_26)<<16) |
(((unsigned long)cache_27)<<24));
#endif
......@@ -575,14 +573,14 @@ asmlinkage void do_entInt(unsigned long type, unsigned long vector, unsigned lon
return;
case 2:
machine_check(vector, la_ptr, &regs);
break;
return;
case 3:
#if defined(CONFIG_ALPHA_JENSEN) || defined(CONFIG_ALPHA_NONAME) || \
defined(CONFIG_ALPHA_SRM)
srm_device_interrupt(vector, &regs);
#elif defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P)
#elif NR_IRQS == 33
cabriolet_and_eb66p_device_interrupt(vector, &regs);
#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
#elif NR_IRQS == 32
eb66_and_eb64p_device_interrupt(vector, &regs);
#endif
return;
......@@ -604,11 +602,11 @@ void init_IRQ(void)
dma_outb(0, DMA2_RESET_REG);
dma_outb(0, DMA1_CLR_MASK_REG);
dma_outb(0, DMA2_CLR_MASK_REG);
#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P)
#if NR_IRQS == 33
outb(cache_804, 0x804);
outb(cache_805, 0x805);
outb(cache_806, 0x806);
#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
#elif NR_IRQS == 32
outb(cache_26, 0x26);
outb(cache_27, 0x27);
#endif
......
......@@ -359,21 +359,6 @@ void lca_machine_check (unsigned long vector, unsigned long la, struct pt_regs *
printk(" esr: %lx ear: %lx\n", el.s->esr, el.s->ear);
printk(" dc_stat: %lx ioc_stat0: %lx ioc_stat1: %lx\n",
el.s->dc_stat, el.s->ioc_stat0, el.s->ioc_stat1);
if (el.c->retry &&
(el.s->esr & (ESR_EAV|ESR_CEE|ESR_UEE|ESR_NXM)) == (ESR_EAV|ESR_CEE))
{
unsigned long addr, val;
/* temporarily disable processor/system correctable error logging: */
wrmces(0x18);
addr = el.s->ear & ~ (0x7<<29 | 0x7);
addr += IDENT_ADDR;
printk(" correcting quadword at address %lx\n", addr);
val = *(volatile long *)addr;
*(volatile long *)addr = val;
/* reenable all machine checks: */
wrmces(0x00);
}
break;
case sizeof(struct el_lca_mcheck_long):
......
......@@ -22,7 +22,6 @@
#include <asm/hwrpb.h>
extern void scsi_mem_init(unsigned long);
extern void sound_mem_init(void);
extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void);
......@@ -166,9 +165,6 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
#ifdef CONFIG_SCSI
scsi_mem_init(high_memory);
#endif
#ifdef CONFIG_SOUND
sound_mem_init();
#endif
for (tmp = PAGE_OFFSET ; tmp < high_memory ; tmp += PAGE_SIZE) {
if (mem_map[MAP_NR(tmp)].reserved)
......
......@@ -70,7 +70,7 @@ mainmenu_option next_comment
comment 'Sound'
tristate 'Sound card support' CONFIG_SOUND
if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
if [ "$CONFIG_SOUND" != "n" ]; then
source drivers/sound/Config.in
fi
......
......@@ -11,7 +11,9 @@
* later.
*
* Fixes
* Felix Koop: NR_CPUS used properly
* Felix Koop : NR_CPUS used properly
* Jose Renau : Handle single CPU case.
* Alan Cox : By repeated request 8) - Total BogoMIP report.
*
*/
......@@ -57,7 +59,7 @@ static volatile int smp_msg_id; /* Message being sent */
volatile unsigned long kernel_flag=0; /* Kernel spinlock */
volatile unsigned char active_kernel_processor = NO_PROC_ID; /* Processor holding kernel spinlock */
volatile unsigned long kernel_counter=0; /* Number of times the processor holds the lock */
volatile unsigned long syscall_count=0; /* Number of times the processor holds the syscall lock */
volatile unsigned long syscall_count=0; /* Number of times the processor holds the syscall lock */
volatile unsigned long smp_spins=0; /* Count of cycles wasted to spinning */
volatile unsigned long ipi_count; /* Number of IPI's delivered */
......@@ -560,10 +562,22 @@ void smp_boot_cpus(void)
* Allow the user to impress friends.
*/
if(cpucount==0)
{
printk("Error: only one processor found.\n");
cpu_present_map=(1<<smp_processor_id());
}
else
{
printk("Total of %d processors activated.\n", cpucount+1);
unsigned long bogosum=0;
for(i=0;i<32;i++)
{
if(cpu_present_map&(1<<i))
bogosum+=cpu_data[i].udelay_val;
}
printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
cpucount+1,
(bogosum+2500)/500000,
((bogosum+2500)/5000)%100);
smp_activated=1;
smp_num_cpus=cpucount+1;
}
......
......@@ -213,8 +213,7 @@ static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_s
if (!tested_for_dm6++) { /* only check for DM6 *once* */
extern int ide_xlate_1024(kdev_t, int, const char *);
/* check for various "disk managers" which do strange things */
int ezstring = !strncmp(data+0x1a3, "Micro House", 11);
if (p->sys_ind == EZD_PARTITION || ezstring) {
if (p->sys_ind == EZD_PARTITION) {
/*
* The remainder of the disk must be accessed using
* a translated geometry that reduces the number of
......
......@@ -14,7 +14,7 @@ if [ "$CONFIG_SBPCD" = "y" ]; then
fi
fi
fi
tristate 'Aztech/Orchid/Okano/Wearnes (non IDE) CDROM support' CONFIG_AZTCD
tristate 'Aztech/Orchid/Okano/Wearnes/TXC (non IDE) CDROM support' CONFIG_AZTCD
tristate 'Sony CDU535 CDROM support' CONFIG_CDU535
tristate 'Goldstar R420 CDROM support' CONFIG_GSCD
tristate 'Philips/LMS CM206 CDROM support' CONFIG_CM206
......
#define AZT_VERSION "1.80"
/* $Id: aztcd.c,v 1.80 1995/10/11 19:35:03 root Exp root $
#define AZT_VERSION "1.90"
/* $Id: aztcd.c,v 1.90 1995/10/21 17:51:59 root Exp root $
linux/drivers/block/aztcd.c - AztechCD268 CDROM driver
Copyright (C) 1994,1995 Werner Zimmermann (zimmerma@rz.fht-esslingen.de)
......@@ -134,6 +134,8 @@
with kernel 1.3.33. Will definitely not work with older kernels.
Programming done by Linus himself.
Werner Zimmermann, October 11, 1995
V1.90 Support for Conrad TXC drives, thank's to Jochen and Olaf.
Werner Zimmermann, October 21, 1995
NOTE:
Points marked with ??? are questionable !
*/
......@@ -164,7 +166,8 @@
#include <asm/segment.h>
#define MAJOR_NR AZTECH_CDROM_MAJOR
#include <linux/blk.h>
#include "blk.h"
#ifdef MODULE
#else
......@@ -1538,8 +1541,9 @@ int aztcd_init(void)
printk("aztcd: no Aztech CD-ROM Initialization");
return -EIO;
}
printk("aztcd: Aztech, Orchid, Okano, Wearnes CD-ROM Driver (C) 1994,1995 W.Zimmermann\n");
printk("aztcd: DriverVersion=%s BaseAddress=0x%x \n",AZT_VERSION,azt_port);
printk("aztcd: Aztech,Orchid,Okano,Wearnes,TXC CD-ROM Driver (C) 1994,1995 W.Zimmermann\n");
printk("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",AZT_VERSION,azt_port);
printk("aztcd: If you have problems, read /usr/src/linux/drivers/block/README.aztcd\n");
if (check_region(azt_port, 4)) {
printk("aztcd: conflict, I/O port (%X) already used\n",
......@@ -1645,6 +1649,9 @@ int aztcd_init(void)
else if ((result[2]=='C')&&(result[3]=='D')&&(result[4]=='D'))
{ printk("aztcd: ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES*/
}
else if ((result[1]==0x03)&&(result[2]=='5'))
{ printk("aztcd: TXC drive detected\n"); /*Conrad TXC*/
}
else /*OTHERS or none*/
{ printk("aztcd: : unknown drive or firmware version detected\n");
printk(" azt may not run stable, if you want to try anyhow,\n");
......
/*
* Sony CDU-31A CDROM interface device driver.
*
* Corey Minyard (minyard@wf-rch.cirr.com)
*
* Colossians 3:17
*
* The Sony interface device driver handles Sony interface CDROM
* drives and provides a complete block-level interface as well as an
* ioctl() interface compatible with the Sun (as specified in
* include/linux/cdrom.h). With this interface, CDROMs can be
* accessed and standard audio CDs can be played back normally.
*
* WARNING - All autoprobes have been removed from the driver.
* You MUST configure the CDU31A via a LILO config
* at boot time or in lilo.conf. I have the
* following in my lilo.conf:
*
* append="cdu31a=0x1f88,0,PAS"
*
* The first number is the I/O base address of the
* card. The second is the interrupt (0 means none).
* Sony CDU-31A CDROM interface device driver.
*
* Corey Minyard (minyard@wf-rch.cirr.com)
*
* Colossians 3:17
*
* The Sony interface device driver handles Sony interface CDROM
* drives and provides a complete block-level interface as well as an
* ioctl() interface compatible with the Sun (as specified in
* include/linux/cdrom.h). With this interface, CDROMs can be
* accessed and standard audio CDs can be played back normally.
*
* WARNING - All autoprobes have been removed from the driver.
* You MUST configure the CDU31A via a LILO config
* at boot time or in lilo.conf. I have the
* following in my lilo.conf:
*
* append="cdu31a=0x1f88,0,PAS"
*
* The first number is the I/O base address of the
* card. The second is the interrupt (0 means none).
* The third should be "PAS" if on a Pro-Audio
* spectrum, or nothing if on something else.
*
......@@ -158,6 +158,15 @@
*
* * The documentation states to set this for interrupt
* 4, but I think that is a mistake.
*
* It probably a little late to be adding a history, but I guess I
* will start.
*
* 10/24/95 - Added support for disabling the eject button when the
* drive is open. Note that there is a small problem
* still here, if the eject button is pushed while the
* drive light is flashing, the drive will return a bad
* status and be reset. It recovers, though.
*/
#include <linux/major.h>
......@@ -297,6 +306,8 @@ static struct task_struct *has_cd_task = NULL; /* The task that is currently
static int is_double_speed = 0; /* Is the drive a CDU33A? */
static int is_auto_eject = 1; /* Door has been locked? 1=No/0=Yes */
/*
* The audio status uses the values from read subchannel data as specified
* in include/linux/cdrom.h.
......@@ -454,6 +465,8 @@ static inline void
reset_drive(void)
{
curr_control_reg = 0;
readahead_dataleft = 0;
sony_toc_read = 0;
outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
}
......@@ -581,10 +594,14 @@ set_drive_params(void)
}
params[0] = SONY_SD_MECH_CONTROL;
params[1] = 0x03; /* Set auto spin up and auto eject */
params[1] = SONY_AUTO_SPIN_UP_BIT; /* Set auto spin up */
if (is_auto_eject) params[1] |= SONY_AUTO_EJECT_BIT;
if (is_double_speed)
{
params[1] |= 0x04; /* Set the drive to double speed if possible */
params[1] |= SONY_DOUBLE_SPEED_BIT; /* Set the drive to double speed if
possible */
}
do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
params,
......@@ -626,11 +643,7 @@ restart_on_error(void)
current->timeout = jiffies + 2*HZ;
schedule();
do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
{
printk("cdu31a: Unable to read TOC: 0x%2.2x\n", res_reg[1]);
}
sony_get_toc();
}
/*
......@@ -919,23 +932,7 @@ handle_sony_cd_attention(void)
volatile int val;
if (abort_read_started)
{
while (is_result_reg_not_empty())
{
val = read_result_register();
}
clear_data_ready();
clear_result_ready();
/* Clear out the data */
while (is_data_requested())
{
val = read_data_register();
}
abort_read_started = 0;
return(1);
}
else if (is_attention())
if (is_attention())
{
if (num_consecutive_attentions > CDU31A_MAX_CONSECUTIVE_ATTENTIONS)
{
......@@ -969,7 +966,10 @@ handle_sony_cd_attention(void)
break;
case SONY_EJECT_PUSHED_ATTN:
sony_audio_status = CDROM_AUDIO_INVALID;
if (is_auto_eject)
{
sony_audio_status = CDROM_AUDIO_INVALID;
}
break;
case SONY_LEAD_IN_ERR_ATTN:
......@@ -983,6 +983,22 @@ handle_sony_cd_attention(void)
num_consecutive_attentions++;
return(1);
}
else if (abort_read_started)
{
while (is_result_reg_not_empty())
{
val = read_result_register();
}
clear_data_ready();
clear_result_ready();
/* Clear out the data */
while (is_data_requested())
{
val = read_data_register();
}
abort_read_started = 0;
return(1);
}
num_consecutive_attentions = 0;
return(0);
......@@ -1496,6 +1512,9 @@ do_cdu31a_request(void)
while (handle_sony_cd_attention())
;
/* Make sure we have a valid TOC. */
sony_get_toc();
sti();
/* If the timer is running, cancel it. */
......@@ -1719,14 +1738,49 @@ sony_get_toc(void)
unsigned int res_size;
unsigned char parms[1];
int session;
int num_spin_ups;
#if DEBUG
printk("Entering sony_get_toc\n");
#endif
num_spin_ups = 0;
if (!sony_toc_read)
{
respinup_on_gettoc:
/* Ignore the result, since it might error if spinning already. */
do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
/* The drive sometimes returns error 0. I don't know why, but ignore
it. It seems to mean the drive has already done the operation. */
if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
{
/* If the drive is already playing, it's ok. */
if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) || (res_reg[1] == 0))
{
goto gettoc_drive_spinning;
}
/* If the drive says it is not spun up (even though we just did it!)
then retry the operation at least a few times. */
if ( (res_reg[1] == SONY_NOT_SPIN_ERR)
&& (num_spin_ups < MAX_CDU31A_RETRIES))
{
num_spin_ups++;
goto respinup_on_gettoc;
}
printk("cdu31a: Error reading TOC: %x %x\n",
sony_toc.exec_status[0],
sony_toc.exec_status[1]);
return;
}
gettoc_drive_spinning:
/* The idea here is we keep asking for sessions until the command
fails. Then we know what the last valid session on the disk is.
No need to check session 0, since session 0 is the same as session
......@@ -1761,6 +1815,7 @@ sony_get_toc(void)
/* Let's not get carried away... */
if (session > 20)
{
printk("cdu31a: too many sessions: %d\n", session);
return;
}
}
......@@ -1779,6 +1834,10 @@ sony_get_toc(void)
&res_size);
if ((res_size < 2) || ((sony_toc.exec_status[0] & 0xf0) == 0x20))
{
printk("cdu31a: Error reading session %d: %x %x\n",
session,
sony_toc.exec_status[0],
sony_toc.exec_status[1]);
/* An error reading the TOC. Return without sony_toc_read
set. */
return;
......@@ -2650,6 +2709,12 @@ static int scd_ioctl(struct inode *inode,
return 0;
break;
case CDROMEJECT_SW:
is_auto_eject = arg;
set_drive_params();
return 0;
break;
default:
return -EINVAL;
}
......@@ -2771,6 +2836,10 @@ scd_open(struct inode *inode,
sony_usage++;
MOD_INC_USE_COUNT;
/* If all is OK (until now...), then lock the door */
is_auto_eject = 0;
set_drive_params();
return 0;
}
......@@ -2795,6 +2864,11 @@ scd_release(struct inode *inode,
if (sony_usage == 0)
{
sync_dev(inode->i_rdev);
/* Unlock the door, only if nobody is using the drive */
is_auto_eject = 1;
set_drive_params();
do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
sony_spun_up = 0;
......
......@@ -255,24 +255,31 @@ static void eraser(unsigned char c, struct tty_struct *tty)
tail = (tail+1) & (N_TTY_BUF_SIZE-1);
}
/* should never happen */
if (tty->column > 0x80000000)
tty->column = 0;
/* Now backup to that column. */
while (tty->column > col) {
/* Can't use opost here. */
put_char('\b', tty);
tty->column--;
if (tty->column > 0)
tty->column--;
}
} else {
if (iscntrl(c) && L_ECHOCTL(tty)) {
put_char('\b', tty);
put_char(' ', tty);
put_char('\b', tty);
tty->column--;
if (tty->column > 0)
tty->column--;
}
if (!iscntrl(c) || L_ECHOCTL(tty)) {
put_char('\b', tty);
put_char(' ', tty);
put_char('\b', tty);
tty->column--;
if (tty->column > 0)
tty->column--;
}
}
}
......@@ -696,6 +703,8 @@ static int n_tty_open(struct tty_struct *tty)
}
memset(tty->read_buf, 0, N_TTY_BUF_SIZE);
tty->read_head = tty->read_tail = tty->read_cnt = 0;
tty->canon_head = tty->canon_data = tty->erasing = 0;
tty->column = 0;
memset(tty->read_flags, 0, sizeof(tty->read_flags));
n_tty_set_termios(tty, 0);
tty->minimum_to_wake = 1;
......
......@@ -16,10 +16,16 @@
in programmed-I/O mode.
Sources:
EtherLink II Technical Reference Guide,
EtherLink II Technical Reference Manual,
EtherLink II/16 Technical Reference Manual Supplement,
3Com Corporation, 5400 Bayfront Plaza, Santa Clara CA 95052-8145
The Crynwr 3c503 packet driver.
Changelog:
Paul Gortmaker : add support for the 2nd 8kB of RAM on 16 bit cards.
*/
static const char *version =
......@@ -148,7 +154,7 @@ el2_pio_probe(struct device *dev)
int
el2_probe1(struct device *dev, int ioaddr)
{
int i, iobase_reg, membase_reg, saved_406;
int i, iobase_reg, membase_reg, saved_406, wordlength;
static unsigned version_printed = 0;
unsigned long vendor_id;
......@@ -180,8 +186,6 @@ el2_probe1(struct device *dev, int ioaddr)
return ENODEV;
}
request_region(ioaddr, EL2_IO_EXTENT,"3c503");
if (dev == NULL)
dev = init_etherdev(0, sizeof(struct ei_device));
......@@ -191,7 +195,7 @@ el2_probe1(struct device *dev, int ioaddr)
dev->base_addr = ioaddr;
ethdev_init(dev);
printk("%s: 3c503 at %#3x,", dev->name, ioaddr);
printk("%s: 3c503 at i/o base %#3x, node address", dev->name, ioaddr);
/* Retrieve and print the ethernet address. */
for (i = 0; i < 6; i++)
......@@ -200,6 +204,13 @@ el2_probe1(struct device *dev, int ioaddr)
/* Map the 8390 back into the window. */
outb(ECNTRL_THIN, ioaddr + 0x406);
/* Check for EL2/16 as described in tech. man. */
outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
outb_p(0, ioaddr + EN0_DCFG);
outb_p(E8390_PAGE2, ioaddr + E8390_CMD);
wordlength = inb_p(ioaddr + EN0_DCFG) & ENDCFG_WTS;
outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
/* Probe for, turn on and clear the board's shared memory. */
if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
outb(EGACFR_NORM, ioaddr + 0x405); /* Enable RAM */
......@@ -216,13 +227,16 @@ el2_probe1(struct device *dev, int ioaddr)
if ((membase_reg & 0xf0) == 0) {
dev->mem_start = 0;
ei_status.name = "3c503-PIO";
} else {
dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
((membase_reg & 0xA0) ? 0x4000 : 0);
#define EL2_MEMSIZE (EL2SM_STOP_PG - EL2SM_START_PG)*256
#define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256
#ifdef EL2MEMTEST
/* This has never found an error, but someone might care. */
/* This has never found an error, but someone might care.
Note that it only tests the 2nd 8kB on 16kB 3c503/16
cards between card addr. 0x2000 and 0x3fff. */
{ /* Check the card's memory. */
unsigned long mem_base = dev->mem_start;
unsigned int test_val = 0xbbadf00d;
......@@ -233,6 +247,7 @@ el2_probe1(struct device *dev, int ioaddr)
|| readl(mem_base + i) != test_val) {
printk(" memory failure or memory address conflict.\n");
dev->mem_start = 0;
ei_status.name = "3c503-PIO";
break;
}
test_val += 0x55555555;
......@@ -240,27 +255,48 @@ el2_probe1(struct device *dev, int ioaddr)
}
}
#endif /* EL2MEMTEST */
/* Divide the on-board memory into a single maximum-sized transmit
(double-sized for ping-pong transmit) buffer at the base, and
use the rest as a receive ring. */
dev->mem_end = dev->rmem_end = dev->mem_start + EL2_MEMSIZE;
dev->rmem_start = TX_PAGES*256 + dev->mem_start;
if (wordlength) { /* No Tx pages to skip over to get to Rx */
dev->rmem_start = dev->mem_start;
ei_status.name = "3c503/16";
} else {
dev->rmem_start = TX_PAGES*256 + dev->mem_start;
ei_status.name = "3c503";
}
}
/*
Divide up the memory on the card. This is the same regardless of
whether shared-mem or PIO is used. For 16 bit cards (16kB RAM),
we use the entire 8k of bank1 for an Rx ring. We only use 3k
of the bank0 for 2 full size Tx packet slots. For 8 bit cards,
(8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining
5kB for an Rx ring. */
if (wordlength) {
ei_status.tx_start_page = EL2_MB0_START_PG;
ei_status.rx_start_page = EL2_MB1_START_PG;
} else {
ei_status.tx_start_page = EL2_MB1_START_PG;
ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
}
/* Finish setting the board's parameters. */
ei_status.name = "3C503";
ei_status.tx_start_page = EL2SM_START_PG;
ei_status.rx_start_page = EL2SM_START_PG + TX_PAGES;
ei_status.stop_page = EL2SM_STOP_PG;
ei_status.stop_page = EL2_MB1_STOP_PG;
ei_status.word16 = wordlength;
ei_status.reset_8390 = &el2_reset_8390;
ei_status.get_8390_hdr = &el2_get_8390_hdr;
ei_status.block_input = &el2_block_input;
ei_status.block_output = &el2_block_output;
request_region(ioaddr, EL2_IO_EXTENT, ei_status.name);
if (dev->irq == 2)
dev->irq = 9;
else if (dev->irq > 5 && dev->irq != 9) {
printk("\n3c503: configured interrupt %d invalid, using autoIRQ.\n",
printk("\n3c503: configured interrupt %d invalid, will use autoIRQ.\n",
dev->irq);
dev->irq = 0;
}
......@@ -272,14 +308,13 @@ el2_probe1(struct device *dev, int ioaddr)
dev->stop = &el2_close;
if (dev->mem_start)
printk("\n%s: %s with shared memory at %#6lx-%#6lx.\n",
dev->name, ei_status.name, dev->mem_start, dev->mem_end-1);
else
printk("\n%s: %s using programmed I/O (REJUMPER for SHARED MEMORY).\n",
dev->name, ei_status.name);
printk("\n%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
dev->name, ei_status.name, (wordlength+1)<<3,
dev->mem_start, dev->mem_end-1);
if (ei_debug > 1)
printk(version);
else
printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
dev->name, ei_status.name, (wordlength+1)<<3);
return 0;
}
......@@ -300,7 +335,7 @@ el2_open(struct device *dev)
outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
outb_p(0x00, E33G_IDCFR);
if (*irqp == autoirq_report(0) /* It's a good IRQ line! */
&& request_irq (dev->irq = *irqp, &ei_interrupt, 0, "3c503") == 0)
&& request_irq (dev->irq = *irqp, &ei_interrupt, 0, ei_status.name) == 0)
break;
}
} while (*++irqp);
......@@ -309,7 +344,7 @@ el2_open(struct device *dev)
return -EAGAIN;
}
} else {
if (request_irq(dev->irq, &ei_interrupt, 0, "3c503")) {
if (request_irq(dev->irq, &ei_interrupt, 0, ei_status.name)) {
return -EAGAIN;
}
}
......@@ -388,13 +423,16 @@ el2_block_output(struct device *dev, int count,
int i; /* Buffer index */
int boguscount = 0; /* timeout counter */
/* This should really be set with during an open(). */
outb(EGACFR_NORM, E33G_GACFR); /* Enable RAM and interrupts. */
if (ei_status.word16) /* Tx packets go into bank 0 on EL2/16 card */
outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
else
outb(EGACFR_NORM, E33G_GACFR);
if (dev->mem_start) { /* Shared memory transfer */
unsigned long dest_addr = dev->mem_start +
((start_page - ei_status.tx_start_page) << 8);
memcpy_toio(dest_addr, buf, count);
outb(EGACFR_NORM, E33G_GACFR); /* Back to bank1 in case on bank0 */
return;
}
/* No shared memory, put the packet out the slow way. */
......@@ -413,11 +451,13 @@ el2_block_output(struct device *dev, int count,
if (++boguscount > (i<<3) + 32) {
printk("%s: FIFO blocked in el2_block_output (at %d of %d, bc=%d).\n",
dev->name, i, count, boguscount);
outb(EGACFR_NORM, E33G_GACFR); /* To MB1 for EL2/16 */
return;
}
outb(buf[i], E33G_FIFOH);
}
outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
outb(EGACFR_NORM, E33G_GACFR); /* Back to bank1 in case on bank0 */
return;
}
......@@ -426,7 +466,7 @@ static void
el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
{
unsigned int i;
unsigned long hdr_start = dev->mem_start + ((ring_page - EL2SM_START_PG)<<8);
unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8);
if (dev->mem_start) { /* Use the shared memory. */
memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
......@@ -456,7 +496,7 @@ el2_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_off
/* Maybe enable shared memory just be to be safe... nahh.*/
if (dev->mem_start) { /* Use the shared memory. */
ring_offset -= (EL2SM_START_PG<<8);
ring_offset -= (EL2_MB1_START_PG<<8);
if (dev->mem_start + ring_offset + count > end_of_ring) {
/* We must wrap the input move. */
int semi_count = end_of_ring - (dev->mem_start + ring_offset);
......
......@@ -12,10 +12,14 @@
#define OLD_3COM_ID 0x02608c
#define NEW_3COM_ID 0x0020af
/* Shared memory management parameters */
/* Shared memory management parameters. NB: The 8 bit cards have only
one bank (MB1) which serves both Tx and Rx packet space. The 16bit
cards have 2 banks, MB0 for Tx packets, and MB1 for Rx packets.
You choose which bank appears in the sh. mem window with EGACFR_MBSn */
#define EL2SM_START_PG (0x20) /* First page of TX buffer */
#define EL2SM_STOP_PG (0x40) /* Last page +1 of RX ring */
#define EL2_MB0_START_PG (0x00) /* EL2/16 Tx packets go in bank 0 */
#define EL2_MB1_START_PG (0x20) /* First page of bank 1 */
#define EL2_MB1_STOP_PG (0x40) /* Last page +1 of bank 1 */
/* 3Com 3c503 ASIC registers */
#define E33G_STARTPG (EL2H+0) /* Start page, matching EN0_STARTPG */
......@@ -60,7 +64,28 @@
/* Bits in E33G_GACFR register: */
#define EGACFR_NORM (0x49) /* Enable 8K shared mem, no DMA TC int */
#define EGACFR_IRQOFF (0xc9) /* Above, and disable 8390 IRQ line */
#define EGACFR_NIM (0x80) /* NIC interrupt mask */
#define EGACFR_TCM (0x40) /* DMA term. count interrupt mask */
#define EGACFR_RSEL (0x08) /* Map a bank of card mem into system mem */
#define EGACFR_MBS2 (0x04) /* Memory bank select, bit 2. */
#define EGACFR_MBS1 (0x02) /* Memory bank select, bit 1. */
#define EGACFR_MBS0 (0x01) /* Memory bank select, bit 0. */
#define EGACFR_NORM (0x49) /* TCM | RSEL | MBS0 */
#define EGACFR_IRQOFF (0xc9) /* TCM | RSEL | MBS0 | NIM */
/*
MBS2 MBS1 MBS0 Sh. mem windows card mem at:
---- ---- ---- -----------------------------
0 0 0 0x0000 -- bank 0
0 0 1 0x2000 -- bank 1 (only choice for 8bit card)
0 1 0 0x4000 -- bank 2, not used
0 1 1 0x6000 -- bank 3, not used
There was going to be a 32k card that used bank 2 and 3, but it
never got produced.
*/
/* End of 3C503 parameter definitions */
This diff is collapsed.
......@@ -15,6 +15,8 @@
* Alan Cox : Rejig for NET3.029 snap #3
* Alan Cox : Fixed NET3.029 bugs and sped up
* Larry McVoy : Tiny tweak to double performance
* Alan Cox : Backed out LMV's tweak - the linux mm cant
* take it...
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -125,10 +127,13 @@ static int loopback_open(struct device *dev)
int loopback_init(struct device *dev)
{
int i;
#ifdef CONFIG_SKB_LARGE
#if LINUS_EVER_SOLVES_THE_LARGE_ATOMIC_BUFFER_ISSUE
dev->mtu = 7900; /* MTU */
#else
dev->mtu = 3800;
/*
* If Alpha uses 8K pages then I guess 7K would be good for it.
*/
dev->mtu = 2000; /* Kept under 1 page */
#endif
dev->tbusy = 0;
dev->hard_start_xmit = loopback_xmit;
......
......@@ -247,7 +247,6 @@ int register_netdev(struct device *dev)
for (i = 0; i < MAX_ETH_CARDS; ++i)
if (ethdev_index[i] == NULL) {
sprintf(dev->name, "eth%d", i);
printk("loading device '%s'...\n", dev->name);
ethdev_index[i] = dev;
break;
}
......
......@@ -210,10 +210,10 @@ static int ppp_dev_header (unsigned char *buff, struct device *dev,
unsigned len, struct sk_buff *skb);
#else /* The 1.3.x kernel is here */
#define get_long_user(addr) get_user(((long *) addr))
#define get_long_user(addr) get_user(((int *) addr))
#define get_int_user(addr) ((int) get_user(((int *) addr)))
#define put_byte_user(val,addr) put_user((val),((u_char *) (addr)))
#define put_long_user(val,addr) put_user((val),((long *) (addr)))
#define put_long_user(val,addr) put_user((val),((int *) (addr)))
static int ppp_dev_header (sk_buff *, struct device *, unsigned short,
void *, void *, unsigned);
......
......@@ -15,6 +15,11 @@
This is a driver for WD8003 and WD8013 "compatible" ethercards.
Thanks to Russ Nelson (nelson@crnwyr.com) for loaning me a WD8013.
Changelog:
Paul Gortmaker : multiple card support for module users
*/
static const char *version =
......@@ -110,6 +115,7 @@ int wd_probe1(struct device *dev, int ioaddr)
int ancient = 0; /* An old card without config registers. */
int word16 = 0; /* 0 = 8 bit, 1 = 16 bit */
const char *model_name;
static unsigned version_printed = 0;
for (i = 0; i < 8; i++)
checksum += inb(ioaddr + 8 + i);
......@@ -121,6 +127,9 @@ int wd_probe1(struct device *dev, int ioaddr)
if (dev == NULL)
dev = init_etherdev(0, sizeof(struct ei_device));
if (ei_debug && version_printed++ == 0)
printk(version);
printk("%s: WD80x3 at %#3x, ", dev->name, ioaddr);
for (i = 0; i < 6; i++)
printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
......@@ -257,8 +266,6 @@ int wd_probe1(struct device *dev, int ioaddr)
printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
model_name, dev->irq, dev->mem_start, dev->mem_end-1);
if (ei_debug > 0)
printk(version);
ei_status.reset_8390 = &wd_reset_8390;
ei_status.block_input = &wd_block_input;
......@@ -408,44 +415,61 @@ wd_close_card(struct device *dev)
#ifdef MODULE
#define MAX_WD_MODS 4 /* Max number of wd modules allowed */
#define NAMELEN 9 /* # of chars for storing dev->name */
char kernel_version[] = UTS_RELEASE;
static char devicename[9] = { 0, };
static struct device dev_wd80x3 = {
devicename, /* device name is inserted by linux/drivers/net/net_init.c */
0, 0, 0, 0,
0, 0,
0, 0, 0, NULL, wd_probe };
int io = 0x300;
int irq = 0;
int mem = 0;
int init_module(void)
static char namelist[NAMELEN * MAX_WD_MODS] = { 0, };
static struct device dev_wd80x3[MAX_WD_MODS] = {
{
NULL, /* assign a chunk of namelist[] below */
0, 0, 0, 0,
0, 0,
0, 0, 0, NULL, NULL
},
};
static int io[MAX_WD_MODS] = { 0, };
static int irq[MAX_WD_MODS] = { 0, };
static int mem[MAX_WD_MODS] = { 0, };
/* This is set up so that only a single autoprobe takes place per call.
ISA device autoprobes on a running machine are not recommended. */
int
init_module(void)
{
if (io == 0)
printk("wd: You should not use auto-probing with insmod!\n");
dev_wd80x3.base_addr = io;
dev_wd80x3.irq = irq;
dev_wd80x3.mem_start = mem;
if (register_netdev(&dev_wd80x3) != 0)
return -EIO;
int this_dev;
for (this_dev = 0; this_dev < MAX_WD_MODS; this_dev++) {
dev_wd80x3[this_dev].name = namelist+(NAMELEN*this_dev);
dev_wd80x3[this_dev].irq = irq[this_dev];
dev_wd80x3[this_dev].base_addr = io[this_dev];
dev_wd80x3[this_dev].mem_start = mem[this_dev];
dev_wd80x3[this_dev].init = wd_probe;
if (io[this_dev] == 0) {
if (this_dev != 0) break; /* only autoprobe 1st one */
printk(KERN_NOTICE "wd.c: Presently autoprobing (not recommended) for a single card.\n");
}
if (register_netdev(&dev_wd80x3[this_dev]) != 0) {
printk(KERN_WARNING "modules: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
return -EIO;
}
}
return 0;
}
void
cleanup_module(void)
{
if (MOD_IN_USE)
printk("wd80x3: device busy, remove delayed\n");
else
{
int ioaddr = dev_wd80x3.base_addr - WD_NIC_OFFSET;
unregister_netdev(&dev_wd80x3);
/* If we don't do this, we can't re-insmod it later. */
free_irq(dev_wd80x3.irq);
release_region(ioaddr, WD_IO_EXTENT);
int this_dev;
for (this_dev = 0; this_dev < MAX_WD_MODS; this_dev++) {
if (dev_wd80x3[this_dev].priv != NULL) {
int ioaddr = dev_wd80x3[this_dev].base_addr - WD_NIC_OFFSET;
unregister_netdev(&dev_wd80x3[this_dev]);
free_irq(dev_wd80x3[this_dev].irq);
release_region(ioaddr, WD_IO_EXTENT);
}
}
}
#endif /* MODULE */
......
......@@ -73,6 +73,7 @@ struct pci_dev_info dev_info[] = {
DEVICE( AMD, AMD_SCSI, "53C974"),
DEVICE( TRIDENT, TRIDENT_9420, "TG 9420"),
DEVICE( TRIDENT, TRIDENT_9440, "TG 9440"),
DEVICE( TRIDENT, TRIDENT_9660, "TG 9660"),
DEVICE( AI, AI_M1435, "M1435"),
DEVICE( MATROX, MATROX_MGA_2, "Atlas PX2085"),
DEVICE( MATROX, MATROX_MIL ,"Millenium"),
......@@ -106,6 +107,7 @@ struct pci_dev_info dev_info[] = {
DEVICE( UMC, UMC_UM8886A, "UM8886A"),
BRIDGE( UMC, UMC_UM8881F, "UM8881F", 0x02),
DEVICE( UMC, UMC_UM8886F, "UM8886F"),
DEVICE( UMC, UMC_UM9017F, "UM9017F"),
DEVICE( X, X_AGX016, "ITT AGX016"),
DEVICE( QLOGIC, QLOGIC_ISP1020, "ISP1020"),
DEVICE( QLOGIC, QLOGIC_ISP1022, "ISP1022"),
......@@ -134,11 +136,13 @@ struct pci_dev_info dev_info[] = {
DEVICE( EF, EF_ATM, "155P-MF1"),
DEVICE( IMAGINGTECH, IMAGINGTECH_ICPCI, "MVC IC-PCI"),
DEVICE( PLX, PLX_9060, "PCI9060 i960 bridge"),
DEVICE( ALLIANCE, ALLIANCE_PROVIDEO, "Provideo"),
DEVICE( MUTECH, MUTECH_MV1000, "MV-1000"),
DEVICE( ZEINET, ZEINET_1221, "1221"),
DEVICE( CYCLADES, CYCLADES_Y, "Cyclome-Y"),
DEVICE( SYMPHONY, SYMPHONY_101, "82C101"),
DEVICE( TEKRAM, TEKRAM_DC290, "DC-290"),
DEVICE( AVANCE, AVANCE_2302, "ALG-2302"),
DEVICE( S3, S3_811, "Trio32/Trio64"),
DEVICE( S3, S3_868, "Vision 868"),
DEVICE( S3, S3_928, "Vision 928-P"),
......@@ -153,15 +157,18 @@ struct pci_dev_info dev_info[] = {
DEVICE( INTEL, INTEL_82430, "82430ZX Aries"),
BRIDGE( INTEL, INTEL_82434, "82434LX Mercury/Neptune", 0x00),
DEVICE( INTEL, INTEL_7116, "SAA7116"),
DEVICE( INTEL, INTEL_82596, "82596"),
DEVICE( INTEL, INTEL_82865, "82865"),
DEVICE( INTEL, INTEL_82437, "82437"),
DEVICE( INTEL, INTEL_82371_0, "82371 Triton PIIX"),
DEVICE( INTEL, INTEL_82371_1, "82371 Triton PIIX"),
DEVICE( INTEL, INTEL_P6, "Experimental P6 bridge"),
DEVICE( ADAPTEC, ADAPTEC_7850, "AIC-7850"),
DEVICE( ADAPTEC, ADAPTEC_294x, "294x"),
DEVICE( ADAPTEC, ADAPTEC_2940, "2940"),
DEVICE( ADAPTEC, ADAPTEC_7870, "AIC-7870"),
DEVICE( ADAPTEC, ADAPTEC_7871, "AIC-7871"),
DEVICE( ADAPTEC, ADAPTEC_7872, "AIC-7872"),
DEVICE( ADAPTEC, ADAPTEC_7880, "AIC-7880"),
DEVICE( ADAPTEC, ADAPTEC_7881, "AIC-7881"),
DEVICE( ATRONICS, ATRONICS_2015, "IDE-2015PL"),
DEVICE( HER, HER_STING, "Stingray"),
DEVICE( HER, HER_STINGARK, "Stingray ARK 2000PV")
......@@ -392,7 +399,7 @@ const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_ATI: return "ATI";
case PCI_VENDOR_ID_WEITEK: return "Weitek";
case PCI_VENDOR_ID_CIRRUS: return "Cirrus Logic";
case PCI_VENDOR_ID_BUSLOGIC: return "Bus Logic";
case PCI_VENDOR_ID_BUSLOGIC: return "BusLogic";
case PCI_VENDOR_ID_N9: return "Number Nine";
case PCI_VENDOR_ID_AI: return "Acer Incorporated";
case PCI_VENDOR_ID_AL: return "Acer Labs";
......@@ -427,6 +434,9 @@ const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_IMAGINGTECH: return "Imaging Technology";
case PCI_VENDOR_ID_CYCLADES: return "Cyclades";
case PCI_VENDOR_ID_OLICOM: return "Olicom";
case PCI_VENDOR_ID_IBM: return "IBM";
case PCI_VENDOR_ID_AVANCE: return "Avance";
case PCI_VENDOR_ID_ALLIANCE: return "Alliance";
default: return "Unknown vendor";
}
}
......
......@@ -4,5 +4,5 @@
# This is really ugly: it should probably be changed
# to use the normal config script setup
#
$MAKE -C drivers/sound config || exit 1 ;;
$MAKE -C drivers/sound config || exit 1
......@@ -154,6 +154,20 @@ audio_release (int dev, struct fileinfo *file)
DMAbuf_release (dev, mode);
}
#if !defined(i386)
static void
translate_bytes (const unsigned char *table, unsigned char *buff, int n)
{
unsigned long i;
if (n <= 0)
return;
for (i = 0; i < n; ++i)
buff[i] = table[buff[i]];
}
#else
extern inline void
translate_bytes (const void *table, void *buff, int n)
{
......@@ -168,7 +182,7 @@ translate_bytes (const void *table, void *buff, int n)
: "bx", "cx", "di", "si", "ax");
}
}
#endif
int
audio_write (int dev, struct fileinfo *file, const snd_rw_buf * buf, int count)
......@@ -248,7 +262,7 @@ audio_write (int dev, struct fileinfo *file, const snd_rw_buf * buf, int count)
/*
* This just allows interrupts while the conversion is running
*/
__asm__ ("sti");
sti();
translate_bytes (ulaw_dsp, (unsigned char *) &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
}
......@@ -323,7 +337,7 @@ audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
/*
* This just allows interrupts while the conversion is running
*/
__asm__ ("sti");
sti();
translate_bytes (dsp_ulaw, (unsigned char *) dmabuf, l);
}
......
......@@ -2101,7 +2101,7 @@ sequencer_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
}
int
sequencer_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
sequencer_write (int dev, struct fileinfo *file, const snd_rw_buf * buf, int count)
{
return -EIO;
}
......@@ -2118,7 +2118,7 @@ sequencer_release (int dev, struct fileinfo *file)
}
int
sequencer_ioctl (int dev, struct fileinfo *file,
unsigned int cmd, unsigned int arg)
unsigned int cmd, ioctl_arg arg)
{
return -EIO;
}
......
......@@ -667,7 +667,7 @@ sound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan)
if (((long) start_addr & ~(dma_pagesize - 1))
!= ((long) end_addr & ~(dma_pagesize - 1))
|| end_addr >= (char *) (16 * 1024 * 1024))
|| end_addr >= (char *) MAX_DMA_ADDRESS)
{
printk (
"sound: kmalloc returned invalid address 0x%lx for %ld Bytes DMA-buffer\n",
......@@ -677,7 +677,7 @@ sound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan)
}
}
dmap->raw_buf = start_addr;
dmap->raw_buf_phys = (unsigned long) start_addr;
dmap->raw_buf_phys = virt_to_bus((unsigned long) start_addr);
for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
{
......
......@@ -373,32 +373,65 @@ static int get_arg(int pid, char * buffer)
static unsigned long get_wchan(struct task_struct *p)
{
#ifdef __i386__
unsigned long ebp, eip;
unsigned long stack_page;
int count = 0;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
stack_page = p->kernel_stack_page;
if (!stack_page)
return 0;
ebp = p->tss.ebp;
do {
if (ebp < stack_page || ebp >= 4092+stack_page)
#if defined(__i386__)
{
unsigned long ebp, eip;
unsigned long stack_page;
int count = 0;
stack_page = p->kernel_stack_page;
if (!stack_page)
return 0;
eip = *(unsigned long *) (ebp+4);
if ((void *)eip != sleep_on &&
(void *)eip != interruptible_sleep_on)
return eip;
ebp = *(unsigned long *) ebp;
} while (count++ < 16);
ebp = p->tss.ebp;
do {
if (ebp < stack_page || ebp >= 4092+stack_page)
return 0;
eip = *(unsigned long *) (ebp+4);
if ((void *)eip != sleep_on &&
(void *)eip != interruptible_sleep_on)
return eip;
ebp = *(unsigned long *) ebp;
} while (count++ < 16);
}
#elif defined(__alpha__)
/*
* This one depends on the frame size of schedule(). Do a
* "disass schedule" in gdb to find the frame size. Also, the
* code assumes that sleep_on() follows immediately after
* interruptible_sleep_on() and that add_timer() follows
* immediately after interruptible_sleep(). Ugly, isn't it?
* Maybe adding a wchan field to task_struct would be better,
* after all...
*/
{
unsigned long schedule_frame;
unsigned long pc;
pc = thread_saved_pc(&p->tss);
if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {
schedule_frame = ((unsigned long *)p->tss.ksp)[6];
return ((unsigned long *)schedule_frame)[12];
}
return pc;
}
#endif
return 0;
}
#define KSTK_EIP(stack) (((unsigned long *)stack)[1019])
#define KSTK_ESP(stack) (((unsigned long *)stack)[1022])
#if defined(__i386__)
# define KSTK_EIP(tsk) (((unsigned long *)tsk->kernel_stack_page)[1019])
# define KSTK_ESP(tsk) (((unsigned long *)tsk->kernel_stack_page)[1022])
#elif defined(__alpha__)
/*
* See arch/alpha/kernel/ptrace.c for details.
*/
# define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \
+ (long)&((struct pt_regs *)0)->reg)
# define KSTK_EIP(tsk) (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(pc)))
# define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
#endif
static int get_stat(int pid, char * buffer)
{
......@@ -417,13 +450,15 @@ static int get_stat(int pid, char * buffer)
state = "RSDZTD"[tsk->state];
vsize = eip = esp = 0;
if (tsk->mm) {
vsize = tsk->kernel_stack_page;
if (vsize) {
eip = KSTK_EIP(vsize);
esp = KSTK_ESP(vsize);
vsize = tsk->mm->brk - tsk->mm->start_code + PAGE_SIZE-1;
if (esp)
vsize += TASK_SIZE - esp;
if (tsk->kernel_stack_page) {
eip = KSTK_EIP(tsk);
esp = KSTK_ESP(tsk);
vsize = ( (tsk->mm->end_code - tsk->mm->start_code) /* text */
+ (tsk->mm->end_data - tsk->mm->start_data) /* data */
+ (tsk->mm->brk - tsk->mm->start_brk)); /* bss + heap */
if (esp) {
vsize += tsk->mm->start_stack - esp; /* stack */
}
}
}
wchan = get_wchan(tsk);
......
......@@ -260,7 +260,7 @@ static int umsdos_readdir_x(
/*
Read count directory entries from directory filp
Return a negative value from linux/errno.h.
Return > 0 if success (the amount of byte written to dirent)
Return 0 or positive if successful
*/
static int UMSDOS_readdir(
struct inode *dir, /* Point to a description of the super block */
......@@ -284,7 +284,7 @@ static int UMSDOS_readdir(
}
PRINTK (("UMSDOS_readdir out %d count %d pos %Ld\n",ret,count
,filp->f_pos));
return count == 0 ? -ENOENT : ret;
return count?:ret;
}
/*
Complete the inode content with info from the EMD file
......
#ifndef __ALPHA_A_OUT_H__
#define __ALPHA_A_OUT_H__
#include <linux/types.h>
/*
* OSF/1 ECOFF header structs. ECOFF files consist of:
* - a file header (struct filehdr),
......
......@@ -77,7 +77,7 @@ extern __inline__ unsigned long change_bit(unsigned long nr, void * addr)
return oldbit != 0;
}
extern __inline__ unsigned long test_bit(int nr, void * addr)
extern __inline__ unsigned long test_bit(int nr, const void * addr)
{
return 1UL & (((int *) addr)[nr >> 5] >> (nr & 31));
}
......
......@@ -61,6 +61,8 @@ extern inline void * phys_to_virt(unsigned long address)
* accomodate things like XFree or svgalib that like to define their
* own versions of inb etc.
*/
extern void __sethae (unsigned long addr); /* syscall */
extern void _sethae (unsigned long addr); /* cached version */
extern unsigned int _inb (unsigned long port);
extern unsigned int _inw (unsigned long port);
extern unsigned int _inl (unsigned long port);
......
......@@ -54,4 +54,12 @@
#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
/* ...and for the drivers/sound files... */
#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
#endif
......@@ -344,6 +344,7 @@ struct el_lca_mcheck_long {
struct el_common h; /* common logout header */
unsigned long pt[32]; /* PAL temps (pt[0] is reason) */
unsigned long exc_addr; /* exception address */
unsigned long pad1[3];
unsigned long pal_base; /* PALcode base address */
unsigned long hier; /* hw interrupt enable */
unsigned long hirr; /* hw interrupt request */
......
......@@ -49,10 +49,12 @@ struct thread_struct {
#include <asm/ptrace.h>
/*
* Return saved PC of a blocked thread. This assumes the frame pointer
* is the 6th saved long on the kernel stack and that the saved return
* address is the first long in the frame. This all holds provided the
* thread blocked through a call to schedule().
* Return saved PC of a blocked thread. This assumes the frame
* pointer is the 6th saved long on the kernel stack and that the
* saved return address is the first long in the frame. This all
* holds provided the thread blocked through a call to schedule() ($15
* is the frame pointer in schedule() and $15 is saved at offset 48 by
* entry.S:do_switch_stack).
*/
extern inline unsigned long thread_saved_pc(struct thread_struct *t)
{
......
......@@ -97,6 +97,12 @@ __old_ipl; })
#define save_flags(flags) do { flags = getipl(); } while (0)
#define restore_flags(flags) setipl(flags)
/*
* Give prototypes to shut up gcc.
*/
extern inline unsigned long xchg_u32 (volatile int * m, unsigned long val);
extern inline unsigned long xchg_u64 (volatile long * m, unsigned long val);
extern inline unsigned long xchg_u32(volatile int * m, unsigned long val)
{
unsigned long dummy, dummy2;
......
......@@ -41,6 +41,7 @@
#define __NR_readlink 58
#define __NR_execve 59
#define __NR_umask 60
#define __NR_chroot 61
#define __NR_getpgrp 63
#define __NR_getpagesize 64
#define __NR_stat 67
......
......@@ -64,7 +64,7 @@ extern __inline__ int change_bit(int nr, void * addr)
* This routine doesn't need to be atomic, but it's faster to code it
* this way.
*/
extern __inline__ int test_bit(int nr, void * addr)
extern __inline__ int test_bit(int nr, const void * addr)
{
int oldbit;
......
......@@ -135,7 +135,7 @@ extern __inline__ int change_bit(int nr, void * addr)
#endif /* !defined(__R4000__) */
extern __inline__ int test_bit(int nr, void *addr)
extern __inline__ int test_bit(int nr, const void *addr)
{
int mask;
unsigned long *a;
......
......@@ -72,6 +72,8 @@ struct atalk_sock
#ifdef __KERNEL__
#include <linux/if_ether.h>
struct ddpehdr
{
/* FIXME for bigendians */
......
/* $Id: aztcd.h,v 1.80 1995/10/11 19:39:18 root Exp root $
/* $Id: aztcd.h,v 1.90 1995/10/21 17:52:10 root Exp root $
*
* Definitions for a AztechCD268 CD-ROM interface
* Copyright (C) 1994, 1995 Werner Zimmermann
......@@ -58,7 +58,6 @@
/*---------------------------------------------------------------------------*/
/*-----nothing to be configured for normal applications below this line------*/
/* Increase this if you get lots of timeouts; if you get kernel panic, replace
STEN_LOW_WAIT by STEN_LOW in the source code */
#define AZT_STATUS_DELAY 400 /*for timer wait, STEN_LOW_WAIT*/
......
......@@ -133,6 +133,13 @@
#define SONY_SD_MECH_CONTROL 0x05
#define SONY_SD_AUTO_SPIN_DOWN_TIME 0x06
/*
* The following are parameter bits for the mechanical control command
*/
#define SONY_AUTO_SPIN_UP_BIT 0x01
#define SONY_AUTO_EJECT_BIT 0x02
#define SONY_DOUBLE_SPEED_BIT 0x04
/*
* The following extract information from the drive configuration about
* the drive itself.
......
......@@ -261,6 +261,8 @@
#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
#define PCI_DEVICE_ID_CIRRUS_7542 0x1200
#define PCI_VENDOR_ID_IBM 0x1014
#define PCI_VENDOR_ID_AMD 0x1022
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
#define PCI_DEVICE_ID_AMD_SCSI 0x2020
......@@ -268,6 +270,7 @@
#define PCI_VENDOR_ID_TRIDENT 0x1023
#define PCI_DEVICE_ID_TRIDENT_9420 0x9420
#define PCI_DEVICE_ID_TRIDENT_9440 0x9440
#define PCI_DEVICE_ID_TRIDENT_9660 0x9660
#define PCI_VENDOR_ID_AI 0x1025
#define PCI_DEVICE_ID_AI_M1435 0x1435
......@@ -332,6 +335,7 @@
#define PCI_DEVICE_ID_UMC_UM8886A 0x886a
#define PCI_DEVICE_ID_UMC_UM8881F 0x8881
#define PCI_DEVICE_ID_UMC_UM8886F 0x8886
#define PCI_DEVICE_ID_UMC_UM9017F 0x9017
#define PCI_VENDOR_ID_X 0x1061
#define PCI_DEVICE_ID_X_AGX016 0x0001
......@@ -397,6 +401,9 @@
#define PCI_VENDOR_ID_PLX 0x113c
#define PCI_DEVICE_ID_PLX_9060 0x0001
#define PCI_VENDOR_ID_ALLIANCE 0x1142
#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422
#define PCI_VENDOR_ID_MUTECH 0x1159
#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001
......@@ -412,6 +419,9 @@
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
#define PCI_VENDOR_ID_AVANCE 0x4005
#define PCI_DEVICE_ID_AVANCE_2302 0x2302
#define PCI_VENDOR_ID_S3 0x5333
#define PCI_DEVICE_ID_S3_811 0x8811
#define PCI_DEVICE_ID_S3_868 0x8880
......@@ -429,6 +439,7 @@
#define PCI_DEVICE_ID_INTEL_82430 0x0486
#define PCI_DEVICE_ID_INTEL_82434 0x04a3
#define PCI_DEVICE_ID_INTEL_7116 0x1223
#define PCI_DEVICE_ID_INTEL_82596 0x1226
#define PCI_DEVICE_ID_INTEL_82865 0x1227
#define PCI_DEVICE_ID_INTEL_82437 0x122d
#define PCI_DEVICE_ID_INTEL_82371_0 0x122e
......@@ -437,9 +448,11 @@
#define PCI_VENDOR_ID_ADAPTEC 0x9004
#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078
#define PCI_DEVICE_ID_ADAPTEC_294x 0x7078
#define PCI_DEVICE_ID_ADAPTEC_2940 0x7178
#define PCI_DEVICE_ID_ADAPTEC_7870 0x7078
#define PCI_DEVICE_ID_ADAPTEC_7871 0x7178
#define PCI_DEVICE_ID_ADAPTEC_7872 0x7278
#define PCI_DEVICE_ID_ADAPTEC_7880 0x8078
#define PCI_DEVICE_ID_ADAPTEC_7881 0x8178
#define PCI_VENDOR_ID_ATRONICS 0x907f
#define PCI_DEVICE_ID_ATRONICS_2015 0x2015
......
......@@ -105,6 +105,11 @@
#define PPS_VALID 120 /* pps signal watchdog max (s) */
#define MAXGLITCH 30 /* pps signal glitch max (s) */
#ifndef __alpha__
/*
* This definitively is wrong for the Alpha and none of the
* kernel code seems to reference this anymore.
*/
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */
#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
......@@ -112,6 +117,7 @@
#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
#endif /* !__alpha__ */
/*
* syscall interface - used (mainly by NTP daemon)
......
......@@ -14,4 +14,3 @@ struct datalink_proto {
};
#endif
......@@ -115,7 +115,8 @@ extern int ip_build_xmit(struct sock *sk,
__u32 saddr,
struct options * opt,
int flags,
int type);
int type,
int noblock);
extern struct ip_mib ip_statistics;
......
......@@ -37,6 +37,25 @@
#include <linux/minix_fs.h>
#include <linux/ext2_fs.h>
#ifdef __alpha__
# include <asm/io.h>
# include <asm/hwrpb.h>
extern void bcopy (const char *src, char *dst, int len);
extern struct hwrpb_struct *hwrpb;
/* these are C runtime functions with special calling conventions: */
extern void __divl (void);
extern void __reml (void);
extern void __divq (void);
extern void __remq (void);
extern void __divlu (void);
extern void __remlu (void);
extern void __divqu (void);
extern void __remqu (void);
#endif
#ifdef CONFIG_NET
#include <linux/in.h>
#include <linux/net.h>
......@@ -78,6 +97,13 @@ extern struct file_operations * get_blkfops(unsigned int);
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
#ifdef CONFIG_SCSI
#include "../drivers/scsi/scsi.h"
#include "../drivers/scsi/scsi_ioctl.h"
......@@ -105,6 +131,31 @@ struct symbol_table symbol_table = {
{ (void *)1 /* Version version :-) */,
SYMBOL_NAME_STR (Using_Versions) },
#endif
/* platform dependent support */
#ifdef __alpha__
X(inb),
X(inw),
X(inl),
X(outb),
X(outw),
X(outl),
X(bcopy), /* generated by gcc-2.7.0 for string assignments */
X(hwrpb),
X(__divl),
X(__reml),
X(__divq),
X(__remq),
X(__divlu),
X(__remlu),
X(__divqu),
X(__remqu),
X(strlen), /* used by ftape */
X(memcmp),
X(memmove),
X(__constant_c_memset),
#endif
/* stackable module support */
X(rename_module_symbol),
X(register_symtab),
......@@ -330,6 +381,17 @@ struct symbol_table symbol_table = {
#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_debug),
X(ei_interrupt),
X(ethdev_init),
X(NS8390_init),
#endif
#if defined(CONFIG_PPP) || defined(CONFIG_SLIP)
/* VJ header compression */
X(slhc_init),
......
......@@ -27,8 +27,12 @@ static char buf[1024];
extern void console_print(const char *);
#define DEFAULT_MESSAGE_LOGLEVEL 6 /* KERN_INFO */
#define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything more serious than KERN_DEBUG */
/* printk's without a loglevel use this.. */
#define DEFAULT_MESSAGE_LOGLEVEL 5 /* KERN_NOTICE */
/* We show everything that is more important than this.. */
#define MINIMUM_CONSOLE_LOGLEVEL 6 /* Minimum loglevel we let people use */
#define DEFAULT_CONSOLE_LOGLEVEL 6 /* anything more serious than KERN_INFO */
unsigned long log_size = 0;
struct wait_queue * log_wait = NULL;
......@@ -124,7 +128,7 @@ asmlinkage int sys_syslog(int type, char * buf, int len)
logged_chars = 0;
return 0;
case 6: /* Disable logging to console */
console_loglevel = 1; /* only panic messages shown */
console_loglevel = MINIMUM_CONSOLE_LOGLEVEL;
return 0;
case 7: /* Enable logging to console */
console_loglevel = DEFAULT_CONSOLE_LOGLEVEL;
......@@ -132,6 +136,8 @@ asmlinkage int sys_syslog(int type, char * buf, int len)
case 8:
if (len < 1 || len > 8)
return -EINVAL;
if (len < MINIMUM_CONSOLE_LOGLEVEL)
len = MINIMUM_CONSOLE_LOGLEVEL;
console_loglevel = len;
return 0;
}
......
......@@ -654,11 +654,13 @@ static void second_overflow(void)
time_adj += ltemp >>
(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
#if HZ == 100
/* compensate for (HZ==100) != 128. Add 25% to get 125; => only 3% error */
if (time_adj < 0)
time_adj -= -time_adj >> 2;
else
time_adj += time_adj >> 2;
#endif
}
/*
......
......@@ -109,7 +109,7 @@ static void check_pending(int signum)
}
}
asmlinkage unsigned long sys_signal(int signum, void (*handler)(int))
asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler)
{
int err;
struct sigaction tmp;
......
......@@ -28,8 +28,6 @@ static int C_A_D = 1;
extern void adjust_clock(void);
#define PZERO 15
asmlinkage int sys_ni_syscall(void)
{
return -ENOSYS;
......
......@@ -100,7 +100,6 @@ int unregister_firewall(int pf, struct firewall_ops *fw)
int call_fw_firewall(int pf, struct sk_buff *skb, void *phdr)
{
struct firewall_ops *fw=firewall_chain[pf];
int result=firewall_policy[pf];
while(fw!=NULL)
{
......@@ -109,8 +108,7 @@ int call_fw_firewall(int pf, struct sk_buff *skb, void *phdr)
return rc;
fw=fw->next;
}
/* alan, is this right? */
return result;
return firewall_policy[pf];
}
/*
......@@ -120,7 +118,6 @@ int call_fw_firewall(int pf, struct sk_buff *skb, void *phdr)
int call_in_firewall(int pf, struct sk_buff *skb, void *phdr)
{
struct firewall_ops *fw=firewall_chain[pf];
int result=firewall_policy[pf];
while(fw!=NULL)
{
......@@ -129,14 +126,12 @@ int call_in_firewall(int pf, struct sk_buff *skb, void *phdr)
return rc;
fw=fw->next;
}
/* alan, is this right? */
return result;
return firewall_policy[pf];
}
int call_out_firewall(int pf, struct sk_buff *skb, void *phdr)
{
struct firewall_ops *fw=firewall_chain[pf];
int result=firewall_policy[pf];
while(fw!=NULL)
{
......@@ -146,7 +141,7 @@ int call_out_firewall(int pf, struct sk_buff *skb, void *phdr)
fw=fw->next;
}
/* alan, is this right? */
return result;
return firewall_policy[pf];
}
void fwchain_init(void)
......
......@@ -53,6 +53,8 @@ volatile unsigned long net_allocs = 0;
volatile unsigned long net_fails = 0;
volatile unsigned long net_free_locked = 0;
extern unsigned long ip_frag_mem;
void show_net_buffers(void)
{
printk("Networking buffers in use : %lu\n",net_skbcount);
......@@ -60,6 +62,9 @@ void show_net_buffers(void)
printk("Total network buffer allocations : %lu\n",net_allocs);
printk("Total failed network buffer allocs : %lu\n",net_fails);
printk("Total free while locked events : %lu\n",net_free_locked);
#ifdef CONFIG_INET
printk("IP fragment buffer size : %lu\n",ip_frag_mem);
#endif
}
#if CONFIG_SKB_CHECK
......
......@@ -230,6 +230,7 @@ void put_sock(unsigned short num, struct sock *sk)
while ((tmp = *skp) != NULL) {
if (!(tmp->rcv_saddr & mask))
break;
skp = &tmp->next;
}
sk->next = tmp;
*skp = sk;
......
......@@ -16,6 +16,7 @@
* Fixes:
* Mike Shaver : RFC1122 checks.
* Alan Cox : Multicast ping reply as self.
* Alan Cox : Fix atomicity lockup in ip_build_xmit call
*
*
*
......@@ -235,7 +236,7 @@ static void icmp_build_xmit(struct icmp_bxm *icmp_param, __u32 saddr, __u32 dadd
icmp_out_count(icmp_param->icmph.type);
ip_build_xmit(sk, icmp_glue_bits, icmp_param,
icmp_param->data_len+sizeof(struct icmphdr),
daddr, saddr, &icmp_param->replyopts, 0, IPPROTO_ICMP);
daddr, saddr, &icmp_param->replyopts, 0, IPPROTO_ICMP, 1);
}
......
......@@ -18,6 +18,7 @@
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <linux/netdevice.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/icmp.h>
......
......@@ -19,6 +19,7 @@
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <linux/netdevice.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/icmp.h>
......@@ -28,6 +29,16 @@
#include <linux/ip_fw.h>
#include <net/checksum.h>
/*
* Fragment cache limits. We will commit 256K at one time. Should we
* cross that limit we will prune down to 192K. This should cope with
* even the most extreme cases without allowing an attacker to measurably
* harm machine performance.
*/
#define IPFRAG_HIGH_THRESH (256*1024)
#define IPFRAG_LOW_THRESH (192*1024)
/*
* This fragment handler is a bit of a heap. On the other hand it works quite
* happily and handles things quite well.
......@@ -35,6 +46,45 @@
static struct ipq *ipqueue = NULL; /* IP fragment queue */
unsigned long ip_frag_mem = 0; /* Memory used for fragments */
/*
* Memory Tracking Functions
*/
extern __inline__ void frag_kfree_skb(struct sk_buff *skb, int type)
{
unsigned long flags;
save_flags(flags);
cli();
ip_frag_mem-=skb->truesize;
restore_flags(flags);
kfree_skb(skb,type);
}
extern __inline__ void frag_kfree_s(void *ptr, int len)
{
unsigned long flags;
save_flags(flags);
cli();
ip_frag_mem-=len;
restore_flags(flags);
kfree_s(ptr,len);
}
extern __inline__ void *frag_kmalloc(int size, int pri)
{
unsigned long flags;
void *vp=kmalloc(size,pri);
if(!vp)
return NULL;
save_flags(flags);
cli();
ip_frag_mem+=size;
restore_flags(flags);
return vp;
}
/*
* Create a new fragment entry.
*/
......@@ -42,8 +92,9 @@ static struct ipq *ipqueue = NULL; /* IP fragment queue */
static struct ipfrag *ip_frag_create(int offset, int end, struct sk_buff *skb, unsigned char *ptr)
{
struct ipfrag *fp;
unsigned long flags;
fp = (struct ipfrag *) kmalloc(sizeof(struct ipfrag), GFP_ATOMIC);
fp = (struct ipfrag *) frag_kmalloc(sizeof(struct ipfrag), GFP_ATOMIC);
if (fp == NULL)
{
NETDEBUG(printk("IP: frag_create: no memory left !\n"));
......@@ -57,6 +108,15 @@ static struct ipfrag *ip_frag_create(int offset, int end, struct sk_buff *skb, u
fp->len = end - offset;
fp->skb = skb;
fp->ptr = ptr;
/*
* Charge for the SKB as well.
*/
save_flags(flags);
cli();
ip_frag_mem+=skb->truesize;
restore_flags(flags);
return(fp);
}
......@@ -128,16 +188,16 @@ static void ip_free(struct ipq *qp)
{
xp = fp->next;
IS_SKB(fp->skb);
kfree_skb(fp->skb,FREE_READ);
kfree_s(fp, sizeof(struct ipfrag));
frag_kfree_skb(fp->skb,FREE_READ);
frag_kfree_s(fp, sizeof(struct ipfrag));
fp = xp;
}
/* Release the IP header. */
kfree_s(qp->iph, 64 + 8);
frag_kfree_s(qp->iph, 64 + 8);
/* Finally, release the queue descriptor itself. */
kfree_s(qp, sizeof(struct ipq));
frag_kfree_s(qp, sizeof(struct ipq));
sti();
}
......@@ -169,6 +229,20 @@ static void ip_expire(unsigned long arg)
ip_free(qp);
}
/*
* Memory limiting on fragments. Evictor trashes the oldest
* fragment queue until we are back under the low threshold
*/
static void ip_evictor(void)
{
while(ip_frag_mem>IPFRAG_LOW_THRESH)
{
if(!ipqueue)
panic("ip_evictor: memcount");
ip_free(ipqueue);
}
}
/*
* Add an entry to the 'ipq' queue for a newly received IP datagram.
......@@ -182,7 +256,7 @@ static struct ipq *ip_create(struct sk_buff *skb, struct iphdr *iph, struct devi
struct ipq *qp;
int ihlen;
qp = (struct ipq *) kmalloc(sizeof(struct ipq), GFP_ATOMIC);
qp = (struct ipq *) frag_kmalloc(sizeof(struct ipq), GFP_ATOMIC);
if (qp == NULL)
{
NETDEBUG(printk("IP: create: no memory left !\n"));
......@@ -196,11 +270,11 @@ static struct ipq *ip_create(struct sk_buff *skb, struct iphdr *iph, struct devi
*/
ihlen = iph->ihl * 4;
qp->iph = (struct iphdr *) kmalloc(64 + 8, GFP_ATOMIC);
qp->iph = (struct iphdr *) frag_kmalloc(64 + 8, GFP_ATOMIC);
if (qp->iph == NULL)
{
NETDEBUG(printk("IP: create: no memory left !\n"));
kfree_s(qp, sizeof(struct ipq));
frag_kfree_s(qp, sizeof(struct ipq));
return(NULL);
}
......@@ -306,7 +380,7 @@ static struct sk_buff *ip_glue(struct ipq *qp)
{
NETDEBUG(printk("Invalid fragment list: Fragment over size.\n"));
ip_free(qp);
kfree_skb(skb,FREE_WRITE);
frag_kfree_skb(skb,FREE_WRITE);
ip_statistics.IpReasmFails++;
return NULL;
}
......@@ -342,10 +416,19 @@ struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct device
unsigned char *ptr;
int flags, offset;
int i, ihl, end;
ip_statistics.IpReasmReqds++;
/* Find the entry of this IP datagram in the "incomplete datagrams" queue. */
/*
* Start by cleaning up the memory
*/
if(ip_frag_mem>IPFRAG_HIGH_THRESH)
ip_evictor();
/*
* Find the entry of this IP datagram in the "incomplete datagrams" queue.
*/
qp = ip_find(iph);
/* Is this a non-fragmented datagram? */
......@@ -392,7 +475,7 @@ struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct device
if ((qp = ip_create(skb, iph, dev)) == NULL)
{
skb->sk = NULL;
kfree_skb(skb, FREE_READ);
frag_kfree_skb(skb, FREE_READ);
ip_statistics.IpReasmFails++;
return NULL;
}
......@@ -474,8 +557,8 @@ struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct device
next=tfp; /* We have killed the original next frame */
kfree_skb(tmp->skb,FREE_READ);
kfree_s(tmp, sizeof(struct ipfrag));
frag_kfree_skb(tmp->skb,FREE_READ);
frag_kfree_s(tmp, sizeof(struct ipfrag));
}
}
......@@ -493,7 +576,7 @@ struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct device
if (!tfp)
{
skb->sk = NULL;
kfree_skb(skb, FREE_READ);
frag_kfree_skb(skb, FREE_READ);
return NULL;
}
tfp->prev = prev;
......
......@@ -14,6 +14,7 @@
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <linux/netdevice.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/icmp.h>
......
......@@ -17,6 +17,9 @@
* Arnt Gulbrandsen, <agulbra@nvg.unit.no>
*
* See ip_input.c for original log
*
* Fixes:
* Alan Cox : Missing nonblock feature in ip_build_xmit.
*/
#include <asm/segment.h>
......@@ -551,7 +554,8 @@ int ip_build_xmit(struct sock *sk,
__u32 user_saddr,
struct options * opt,
int flags,
int type)
int type,
int noblock)
{
struct rtable *rt;
unsigned int fraglen, maxfraglen, fragheaderlen;
......@@ -671,7 +675,7 @@ int ip_build_xmit(struct sock *sk,
if(length <= dev->mtu && !MULTICAST(daddr) && daddr!=0xFFFFFFFF && daddr!=dev->pa_brdaddr)
{
int error;
struct sk_buff *skb=sock_alloc_send_skb(sk, length+15+dev->hard_header_len,0, 0,&error);
struct sk_buff *skb=sock_alloc_send_skb(sk, length+15+dev->hard_header_len,0, noblock, &error);
if(skb==NULL)
{
ip_statistics.IpOutDiscards++;
......@@ -822,7 +826,7 @@ int ip_build_xmit(struct sock *sk,
* Get the memory we require with some space left for alignment.
*/
skb = sock_alloc_send_skb(sk, fraglen+15, 0, 0, &error);
skb = sock_alloc_send_skb(sk, fraglen+15, 0, noblock, &error);
if (skb == NULL)
{
ip_statistics.IpOutDiscards++;
......
......@@ -18,6 +18,7 @@
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <linux/netdevice.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/icmp.h>
......
......@@ -223,13 +223,13 @@ static int raw_sendto(struct sock *sk, const unsigned char *from,
{
if(len>65535)
return -EMSGSIZE;
err=ip_build_xmit(sk, raw_getrawfrag, from, len, sin.sin_addr.s_addr, 0, sk->opt, flags, sin.sin_port);
err=ip_build_xmit(sk, raw_getrawfrag, from, len, sin.sin_addr.s_addr, 0, sk->opt, flags, sin.sin_port, noblock);
}
else
{
if(len>65535-sizeof(struct iphdr))
return -EMSGSIZE;
err=ip_build_xmit(sk, raw_getfrag, from, len, sin.sin_addr.s_addr, 0, sk->opt, flags, sin.sin_port);
err=ip_build_xmit(sk, raw_getfrag, from, len, sin.sin_addr.s_addr, 0, sk->opt, flags, sin.sin_port, noblock);
}
return err<0?err:len;
}
......
......@@ -575,16 +575,14 @@ static int rt_kill(struct rtentry *r)
int rt_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
{
struct rtable *r;
int len=0;
int len=128;
off_t pos=0;
off_t begin=0;
char temp[129];
if(offset<128)
{
sprintf(buffer,"%-127s\n","Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU\tWindow\tIRTT");
pos=128;
}
pos=128;
for (r = rt_base; r != NULL; r = r->rt_next)
{
......
......@@ -174,7 +174,8 @@
* change. Doesn't yet cope with MSS shrink right
* but its a start!
* Marc Tamsky : Closing in closing fixes.
* Mike Shaver : RFC1122 verifications
* Mike Shaver : RFC1122 verifications.
* Alan Cox : rcv_saddr errors.
*
*
* To Fix:
......@@ -1816,7 +1817,6 @@ static int tcp_sendmsg(struct sock *sk, struct msghdr *msg,
from += copy;
copied += copy;
len -= copy;
seglen -= copy;
sk->write_seq += copy;
seglen -= copy;
}
......@@ -3053,6 +3053,7 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb,
newsk->daddr = saddr;
newsk->saddr = daddr;
newsk->rcv_saddr = daddr;
put_sock(newsk->num,newsk);
newsk->dummy_th.res1 = 0;
......@@ -4575,7 +4576,7 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
/*
* Put in the IP header and routing stuff.
* Put in the IP header and routing stuff.
*/
if (sk->localroute)
......@@ -4583,6 +4584,12 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
else
rt=ip_rt_route(sk->daddr, NULL, sk->saddr ? NULL : &sk->saddr);
/*
* When we connect we enforce receive requirements too.
*/
sk->rcv_saddr=sk->saddr;
/*
* We need to build the routing stuff from the things saved in skb.
*/
......
......@@ -47,6 +47,7 @@
* Alan Cox : Route cache
* Jon Peatfield : Minor efficientcy fix to sendto().
* Mike Shaver : RFC1122 checks.
* Alan Cox : Nonblocking error fix.
*
*
* This program is free software; you can redistribute it and/or
......@@ -292,7 +293,7 @@ static void udp_getfrag_nosum(const void *p, __u32 saddr, char * to, unsigned in
static int udp_send(struct sock *sk, struct sockaddr_in *sin,
const unsigned char *from, int len, int rt,
__u32 saddr)
__u32 saddr, int noblock)
{
int ulen = len + sizeof(struct udphdr);
int a;
......@@ -310,11 +311,6 @@ static int udp_send(struct sock *sk, struct sockaddr_in *sin,
ufh.from = from;
ufh.wcheck = 0;
/* RFC1122 Violation: there is no provision for passing IP options */
/* from the application layer to the IP one. It's a MUST (4.1.3.2), */
/* but it looks like it'd require some work on ip_build_xmit. */
/* Alan says he's got a Cunning Plan. -- MS */
/* RFC1122: OK. Provides the checksumming facility (MUST) as per */
/* 4.1.3.4. It's configurable by the application via setsockopt() */
/* (MAY) and it defaults to on (MUST). Almost makes up for the */
......@@ -322,10 +318,10 @@ static int udp_send(struct sock *sk, struct sockaddr_in *sin,
if(sk->no_check)
a = ip_build_xmit(sk, udp_getfrag_nosum, &ufh, ulen,
sin->sin_addr.s_addr, saddr, sk->opt, rt, IPPROTO_UDP);
sin->sin_addr.s_addr, saddr, sk->opt, rt, IPPROTO_UDP, noblock);
else
a = ip_build_xmit(sk, udp_getfrag, &ufh, ulen,
sin->sin_addr.s_addr, saddr, sk->opt, rt, IPPROTO_UDP);
sin->sin_addr.s_addr, saddr, sk->opt, rt, IPPROTO_UDP, noblock);
if(a<0)
return a;
udp_statistics.UdpOutDatagrams++;
......@@ -393,7 +389,7 @@ static int udp_sendto(struct sock *sk, const unsigned char *from, int len, int n
sk->inuse = 1;
/* Send the packet. */
tmp = udp_send(sk, usin, from, len, flags, saddr);
tmp = udp_send(sk, usin, from, len, flags, saddr, noblock);
/* The datagram has been sent off. Release the socket. */
release_sock(sk);
......@@ -568,7 +564,10 @@ int udp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
rt=(sk->localroute?ip_rt_local:ip_rt_route)((__u32)usin->sin_addr.s_addr, NULL, &sa);
if(rt==NULL)
return -ENETUNREACH;
sk->saddr = sa; /* Update source address */
if(!sk->saddr)
sk->saddr = sa; /* Update source address */
if(!sk->rcv_saddr)
sk->rcv_saddr = sa;
sk->daddr = usin->sin_addr.s_addr;
sk->dummy_th.dest = usin->sin_port;
sk->state = TCP_ESTABLISHED;
......
......@@ -18,6 +18,7 @@
* Niibe Yutaka : async I/O support.
* Carsten Paeth : PF_UNIX check, address fixes.
* Alan Cox : Limit size of allocated blocks.
* Alan Cox : Fixed the stupid socketpair bug.
*/
#include <linux/config.h>
......@@ -46,7 +47,7 @@
#include <net/af_unix.h>
#include <linux/proc_fs.h>
static unix_socket *volatile unix_socket_list=NULL;
static unix_socket * unix_socket_list=NULL;
#define min(a,b) (((a)<(b))?(a):(b))
......@@ -68,25 +69,19 @@ static inline void unix_mkname(struct sockaddr_un * sun, unsigned long len)
static void unix_remove_socket(unix_socket *sk)
{
unix_socket *s;
unix_socket **s;
cli();
s=unix_socket_list;
if(s==sk)
{
unix_socket_list=s->next;
sti();
return;
}
while(s && s->next)
s = &unix_socket_list;
while(*s!=NULL)
{
if(s->next==sk)
if(*s==sk)
{
s->next=sk->next;
sti();
return;
*s=sk->next;
break;
}
s=s->next;
s=&((*s)->next);
}
sti();
}
......@@ -279,7 +274,7 @@ static int unix_create(struct socket *sock, int protocol)
skb_queue_head_init(&sk->back_log);
sk->protinfo.af_unix.family=AF_UNIX;
sk->protinfo.af_unix.inode=NULL;
sk->protinfo.af_unix.locks=1; /* Us */
sk->protinfo.af_unix.locks=1; /* Us */
sk->protinfo.af_unix.readsem=MUTEX; /* single task reading lock */
sk->protinfo.af_unix.name=NULL;
sk->protinfo.af_unix.other=NULL;
......@@ -540,20 +535,8 @@ static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
static int unix_socketpair(struct socket *a, struct socket *b)
{
int err;
unix_socket *ska,*skb;
err=unix_create(a, 0);
if(err)
return err;
err=unix_create(b, 0);
if(err)
{
unix_release(a, NULL);
a->data=NULL;
return err;
}
ska=a->data;
skb=b->data;
......
......@@ -150,7 +150,7 @@ function tristate () {
#
function dep_tristate () {
def=$(eval echo "\${$2:-'n'}")
if [ "$def" != "m" ]; then
if [ "$3" != "m" ]; then
tristate "$1" "$2"
else
ans=""
......
......@@ -2,7 +2,7 @@ HEADER=header.tk
TAIL=tail.tk
kconfig.tk: ../arch/${ARCH}/config.in tkparse ${HEADER} ${TAIL}
./tkparse < ../arch/${ARCH}/config.in > kconfig.tmp
./tkparse < ../arch/${ARCH}/config.in > kconfig.tmp
cp ${HEADER} ./kconfig.tk
cat kconfig.tmp >> kconfig.tk
rm -f kconfig.tmp
......
......@@ -27,6 +27,8 @@ struct kconfig * clast = NULL;
struct kconfig * koption = NULL;
static int lineno = 0;
static int menus_seen = 0;
static char * current_file = NULL;
static int do_source(char * filename);
/*
* Simple function just to skip over spaces and tabs in config.in.
*/
......@@ -138,7 +140,10 @@ static struct condition * parse_if(char * pnt)
return list;
error:
printf("Bad if clause at line %d:%s\n", lineno, opnt);
if(current_file != NULL)
printf("Bad if clause at line %d(%s):%s\n", lineno, current_file, opnt);
else
printf("Bad if clause at line %d:%s\n", lineno, opnt);
return NULL;
}
......@@ -242,6 +247,13 @@ int parse(char * pnt) {
tok = tok_menuname;
pnt += 13;
}
else if (strncmp(pnt, "source", 6) == 0)
{
pnt += 7;
pnt = skip_whitespace(pnt);
do_source(pnt);
return;
}
else if (strncmp(pnt, "mainmenu_option", 15) == 0)
{
menus_seen++;
......@@ -417,22 +429,49 @@ dump_if(struct condition * cond)
printf("\n");
}
char buffer[1024];
static int do_source(char * filename)
{
char buffer[1024];
int old_lineno;
char * pnt;
FILE * infile;
infile = fopen(filename,"r");
if(!infile) {
fprintf(stderr,"Unable to open file %s\n", filename);
return 1;
}
old_lineno = lineno;
lineno = 0;
current_file = filename;
while (fgets(buffer, sizeof(buffer), infile))
{
/*
* Strip the trailing return character.
*/
pnt = buffer + strlen(buffer) - 1;
if( *pnt == '\n') *pnt = 0;
lineno++;
parse(buffer);
}
fclose(infile);
current_file = NULL;
lineno = old_lineno;
return 0;
}
main(int argc, char * argv[])
{
char * pnt;
struct kconfig * cfg;
char buffer[1024];
int i;
/*
* Loop over every input line, and parse it into the tables.
*/
while(1)
while(fgets(buffer, sizeof(buffer), stdin))
{
fgets(buffer, sizeof(buffer), stdin);
if(feof(stdin)) break;
/*
* Strip the trailing return character.
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment