Commit 57afa237 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.100pre2

parent 5892de9e
This source diff could not be displayed because it is too large. You can view the blob instead.
MTRR (Memory Type Range Register) control
17 Dec 1997
2 May 1998
Richard Gooch
<rgooch@atnf.csiro.au>
On Intel Pentium Pro systems the Memory Type Range Registers (MTRRs)
may be used to control processor access to memory ranges. This is
most useful when you have a video (VGA) card on the PCI
bus. Enabling write-combining allows PCI write transfers to be
combined into a larger transfer before bursting over the PCI
bus. This can increase performance of image write operations 2.5
times or more.
On Intel Pentium Pro/Pentium II systems the Memory Type Range
Registers (MTRRs) may be used to control processor access to memory
ranges. This is most useful when you have a video (VGA) card on a
PCI or AGP bus. Enabling write-combining allows bus write transfers
to be combined into a larger transfer before bursting over the
PCI/AGP bus. This can increase performance of image write operations
2.5 times or more.
The CONFIG_MTRR option creates a /proc/mtrr file which may be used
to manipulate your MTRRs. Typically the X server should use
......@@ -30,13 +30,40 @@ Reading MTRRs from the shell:
% cat /proc/mtrr
reg00: base=0x00000000 ( 0MB), size= 128MB: write-back, count=1
reg01: base=0x08000000 ( 128MB), size= 64MB: write-back, count=1
reg05: base=0x80000000 (2048MB), size= 4MB: write-combining, count=1
===============================================================================
Creating MTRRs from the shell:
% echo "base=0x80000000 size=0x400000 type=write-combining" >! /proc/mtrr
# echo "base=0xf8000000 size=0x400000 type=write-combining" >! /proc/mtrr
And the result thereof:
% cat /proc/mtrr
reg00: base=0x00000000 ( 0MB), size= 128MB: write-back, count=1
reg01: base=0x08000000 ( 128MB), size= 64MB: write-back, count=1
reg02: base=0xf8000000 (3968MB), size= 4MB: write-combining, count=1
This is for videoram at base address 0xf8000000 and size 4 MBytes. To
find out your base address, you need to look at the output of your X
server, which tells you where the linear framebuffer address is. A
typical line that you may get is:
(--) S3: PCI: 968 rev 0, Linear FB @ 0xf8000000
Note that you should only use the value from the X server, as it may
move the framebuffer base address, so the only value you can trust is
that reported by the X server.
To find out the size of your framebuffer (what, you don't actually
know?), the following line will tell you:
(--) S3: videoram: 4096k
That's 4 MBytes, which is 0x400000 bytes (in hexadecimal).
A patch is being written for XFree86 which will make this automatic:
in other words the X server will manipulate /proc/mtrr using the
ioctl() interface, so users won't have to do anything. If you use a
commercial X server, lobby your vendor to add support for MTRRs.
===============================================================================
Removing MTRRs from the shell:
% echo "disable=5" >! /proc/mtrr
% echo "disable=2" >! /proc/mtrr
===============================================================================
Reading MTRRs from a C programme using ioctl()'s:
......@@ -44,7 +71,7 @@ Reading MTRRs from a C programme using ioctl()'s:
Source file for mtrr-show (example programme to show MTRRs using ioctl()'s)
Copyright (C) 1997 Richard Gooch
Copyright (C) 1997-1998 Richard Gooch
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
......@@ -72,7 +99,7 @@ Reading MTRRs from a C programme using ioctl()'s:
Written by Richard Gooch 17-DEC-1997
Last updated by Richard Gooch 17-DEC-1997
Last updated by Richard Gooch 2-MAY-1998
*/
......@@ -84,7 +111,7 @@ Reading MTRRs from a C programme using ioctl()'s:
#include <sys/ioctl.h>
#include <errno.h>
#define MTRR_NEED_STRINGS
#include <linux/mtrr.h>
#include <asm/mtrr.h>
#define TRUE 1
#define FALSE 0
......@@ -130,7 +157,7 @@ Creating MTRRs from a C programme using ioctl()'s:
Source file for mtrr-add (example programme to add an MTRRs using ioctl())
Copyright (C) 1997 Richard Gooch
Copyright (C) 1997-1998 Richard Gooch
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
......@@ -158,7 +185,7 @@ Creating MTRRs from a C programme using ioctl()'s:
Written by Richard Gooch 17-DEC-1997
Last updated by Richard Gooch 17-DEC-1997
Last updated by Richard Gooch 2-MAY-1998
*/
......@@ -172,7 +199,7 @@ Creating MTRRs from a C programme using ioctl()'s:
#include <sys/ioctl.h>
#include <errno.h>
#define MTRR_NEED_STRINGS
#include <linux/mtrr.h>
#include <asm/mtrr.h>
#define TRUE 1
#define FALSE 0
......
......@@ -18,6 +18,7 @@ Currently, these files are in /proc/sys/vm:
- bdflush
- buffermem
- freepages
- kswapd
- overcommit_memory
- pagecache
- swapctl
......@@ -112,9 +113,58 @@ freepages:
This file contains the values in the struct freepages. That
struct contains three members: min, low and high.
These variables are currently unused (?), but they're
very likely to be abused for something else in the near
future, so don't yet remove it from the source...
Although the goal of the Linux memory management subsystem
is to avoid fragmentation and make large chunks of free
memory (so that we can hand out DMA buffers and such), there
still are some page-based limits in the system, mainly to
make sure we don't waste too much memory trying to get large
free area's.
The meaning of the numbers is:
freepages.min When the number of free pages in the system
reaches this number, only the kernel can
allocate more memory.
freepages.low If memory is too fragmented, the swapout
daemon is started, except when the number
of free pages is larger than freepages.low.
freepages.high The swapping daemon exits when memory is
sufficiently defragmented, when the number
of free pages reaches freepages.high or when
it has tried the maximum number of times.
==============================================================
kswapd:
Kswapd is the kernel swapout daemon. That is, kswapd is that
piece of the kernel that frees memory when it get's fragmented
or full. Since every system is different, you'll probably want
some control over this piece of the system.
The numbers in this page correspond to the numbers in the
struct pager_daemon {tries_base, tries_min, swap_cluster
}; The tries_base and swap_cluster probably have the
largest influence on system performance.
tries_base The maximum number of pages kswapd tries to
free in one round is calculated from this
number. Usually this number will be divided
by 4 or 8 (see mm/vmscan.c), so it isn't as
big as it looks.
When you need to increase the bandwith to/from
swap, you'll want to increase this number.
tries_min This is the minimum number of times kswapd
tries to free a page each time it is called.
Basically it's just there to make sure that
kswapd frees some pages even when it's being
called with minimum priority.
swap_cluster This is the number of pages kswapd writes in
one turn. You want this large so that kswapd
does it's I/O in large chunks and the disk
doesn't have to seek often, but you don't want
it to be too large since that would flood the
request queue.
==============================================================
......
/*
* bios32.c - Low-Level PCI Access
*
* $Id: bios32.c,v 1.29 1998/04/17 16:31:15 mj Exp $
* $Id: bios32.c,v 1.32 1998/05/02 12:03:05 davem Exp $
*
* Sponsored by
* iX Multiuser Multitasking Magazine
......@@ -66,6 +66,8 @@
* and cleaned it up... Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*
* Feb 6, 1998 : No longer using BIOS to find devices and device classes. [mj]
*
* May 1, 1998 : Support for peer host bridges. [mj]
*/
#include <linux/config.h>
......@@ -74,6 +76,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/malloc.h>
#include <asm/page.h>
#include <asm/segment.h>
......@@ -832,7 +835,10 @@ __initfunc(static struct pci_access *pci_find_bios(void))
}
/*
* Sort the device list according to PCI BIOS.
* Sort the device list according to PCI BIOS. Nasty hack, but since some
* fool forgot to define the `correct' device order in the PCI BIOS specs
* and we want to be (possibly bug-to-bug ;-]) compatible with older kernels
* which used BIOS ordering, we are bound to do this...
*/
__initfunc(void pcibios_sort(void))
......@@ -924,11 +930,41 @@ __initfunc(void pcibios_fixup_io_addr(struct pci_dev *dev, int idx))
}
/*
* Arch-dependent fixups. We need to fix here base addresses, I/O
* and memory enables and IRQ's as the PCI BIOS'es are buggy as hell.
* In case there are peer host bridges, scan bus behind each of them.
* Although several sources claim that the host bridges should have
* header type 1 and be assigned a bus number as for PCI2PCI bridges,
* the reality doesn't pass this test and the bus number is usually
* hard-wired to 1.
*/
__initfunc(void pcibios_fixup_peer_bridges(void))
{
struct pci_dev *dev;
int cnt = 0;
for(dev=pci_root.devices; dev; dev=dev->sibling)
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
DBG("PCI: Host bridge at %02x\n", dev->devfn);
if (cnt) {
struct pci_bus *b = kmalloc(sizeof(struct pci_bus), GFP_KERNEL);
memset(b, 0, sizeof(*b));
b->parent = &pci_root;
b->next = pci_root.next;
pci_root.next = b;
b->self = dev;
b->number = b->secondary = cnt;
b->subordinate = 0xff;
b->subordinate = pci_scan_bus(b);
}
cnt++;
}
}
__initfunc(void pcibios_fixup(void))
/*
* Fix base addresses, I/O and memory enables and IRQ's (mostly work-arounds
* for buggy PCI BIOS'es :-[).
*/
__initfunc(void pcibios_fixup_devices(void))
{
struct pci_dev *dev;
int i, has_io, has_mem;
......@@ -991,6 +1027,16 @@ __initfunc(void pcibios_fixup(void))
if (dev->irq >= NR_IRQS)
dev->irq = 0;
}
}
/*
* Arch-dependent fixups.
*/
__initfunc(void pcibios_fixup(void))
{
pcibios_fixup_peer_bridges();
pcibios_fixup_devices();
#ifdef CONFIG_PCI_BIOS
if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
......
/*
* Intel IO-APIC support for multi-pentium hosts.
*
* (c) 1997 Ingo Molnar, Hajnalka Szabo
* Copyright (C) 1997, 1998 Ingo Molnar, Hajnalka Szabo
*
* Many thanks to Stig Venaas for trying out countless experimental
* patches and reporting/debugging problems patiently!
......@@ -34,6 +34,19 @@
*/
#define IO_APIC_BASE ((volatile int *)0xfec00000)
enum mp_irq_source_types {
mp_INT = 0,
mp_NMI = 1,
mp_SMI = 2,
mp_ExtINT = 3
};
enum ioapic_irq_destination_types {
dest_Fixed = 0,
dest_LowestPrio = 1,
dest_ExtINT = 7
};
/*
* The structure of the IO-APIC:
*/
......@@ -60,7 +73,7 @@ struct IO_APIC_route_entry {
__u32 vector : 8,
delivery_mode : 3, /* 000: FIXED
* 001: lowest prio
* 111: ExtInt
* 111: ExtINT
*/
dest_mode : 1, /* 0: physical, 1: logical */
delivery_status : 1,
......@@ -137,7 +150,7 @@ void disable_IO_APIC_irq (unsigned int irq)
io_apic_write(0x10+2*irq, *(((int *)&entry)+0));
}
void clear_IO_APIC_irq (unsigned int irq)
void clear_IO_APIC_pin (unsigned int pin)
{
struct IO_APIC_route_entry entry;
......@@ -146,12 +159,12 @@ void clear_IO_APIC_irq (unsigned int irq)
*/
memset(&entry, 0, sizeof(entry));
entry.mask = 1;
io_apic_write(0x10+2*irq, *(((int *)&entry)+0));
io_apic_write(0x11+2*irq, *(((int *)&entry)+1));
io_apic_write(0x10+2*pin, *(((int *)&entry)+0));
io_apic_write(0x11+2*pin, *(((int *)&entry)+1));
}
/*
* support for broken MP BIOSes, enables hand-redirection of PIRQ0-3 to
* support for broken MP BIOSes, enables hand-redirection of PIRQ0-7 to
* specific CPU-side IRQs.
*/
......@@ -159,7 +172,7 @@ void clear_IO_APIC_irq (unsigned int irq)
int pirq_entries [MAX_PIRQS];
int pirqs_enabled;
void ioapic_pirq_setup(char *str, int *ints)
__initfunc(void ioapic_pirq_setup(char *str, int *ints))
{
int i, max;
......@@ -187,12 +200,15 @@ void ioapic_pirq_setup(char *str, int *ints)
}
}
int find_irq_entry(int pin)
/*
* Find the irq entry nr of a certain pin.
*/
__initfunc(static int find_irq_entry(int pin, int type))
{
int i;
for (i=0; i<mp_irq_entries; i++)
if ( (mp_irqs[i].mpc_irqtype == 0x00) &&
if ( (mp_irqs[i].mpc_irqtype == type) &&
(mp_irqs[i].mpc_dstirq == pin))
return i;
......@@ -200,7 +216,49 @@ int find_irq_entry(int pin)
return -1;
}
void setup_IO_APIC_irqs (void)
/*
* Find the pin to which IRQ0 (ISA) is connected
*/
__initfunc(int find_timer_pin (int type))
{
int i;
for (i=0; i<mp_irq_entries; i++) {
int lbus = mp_irqs[i].mpc_srcbus;
if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA) &&
(mp_irqs[i].mpc_irqtype == type) &&
(mp_irqs[i].mpc_srcbusirq == 0x00))
return mp_irqs[i].mpc_dstirq;
}
return -1;
}
/*
* Find a specific PCI IRQ entry.
* Not an initfunc, possibly needed by modules
*/
int IO_APIC_get_PCI_irq_vector (int bus, int slot, int pci_pin)
{
int i;
for (i=0; i<mp_irq_entries; i++) {
int lbus = mp_irqs[i].mpc_srcbus;
if (IO_APIC_IRQ(mp_irqs[i].mpc_dstirq) &&
(mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
!mp_irqs[i].mpc_irqtype &&
(bus == mp_bus_id_to_pci_bus[mp_irqs[i].mpc_srcbus]) &&
(slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f)) &&
(pci_pin == (mp_irqs[i].mpc_srcbusirq & 3)))
return mp_irqs[i].mpc_dstirq;
}
return -1;
}
__initfunc(void setup_IO_APIC_irqs (void))
{
struct IO_APIC_route_entry entry;
int i, idx, bus, irq, first_notcon=1;
......@@ -214,12 +272,12 @@ void setup_IO_APIC_irqs (void)
*/
memset(&entry,0,sizeof(entry));
entry.delivery_mode = 1; /* lowest prio */
entry.delivery_mode = dest_LowestPrio;
entry.dest_mode = 1; /* logical delivery */
entry.mask = 0; /* enable IRQ */
entry.dest.logical.logical_dest = 0xff; /* all CPUs */
idx = find_irq_entry(i);
idx = find_irq_entry(i,mp_INT);
if (idx == -1) {
if (first_notcon) {
printk(" IO-APIC pin %d", i);
......@@ -361,6 +419,21 @@ void setup_IO_APIC_irqs (void)
}
}
/*
* There are broken mptables which register ISA+high-active+level IRQs,
* these are illegal and are converted here to ISA+high-active+edge
* IRQ sources. Careful, ISA+low-active+level is another broken entry
* type, it represents PCI IRQs 'embedded into an ISA bus', they have
* to be accepted. Yes, ugh.
*/
if ( (mp_bus_id_to_type[bus] == MP_BUS_ISA) &&
(entry.polarity == 0) /* active-high */ &&
(entry.trigger == 1) /* level */ )
{
printk("broken BIOS, changing pin %d to edge\n", i);
entry.trigger = 0;
}
io_apic_write(0x10+2*i, *(((int *)&entry)+0));
io_apic_write(0x11+2*i, *(((int *)&entry)+1));
}
......@@ -369,7 +442,7 @@ void setup_IO_APIC_irqs (void)
printk(" not connected.\n");
}
void setup_IO_APIC_irq_ISA_default (unsigned int irq)
__initfunc(void setup_IO_APIC_irq_ISA_default (unsigned int irq))
{
struct IO_APIC_route_entry entry;
......@@ -378,9 +451,9 @@ void setup_IO_APIC_irq_ISA_default (unsigned int irq)
*/
memset(&entry,0,sizeof(entry));
entry.delivery_mode = 1; /* lowest prio */
entry.delivery_mode = dest_LowestPrio; /* lowest prio */
entry.dest_mode = 1; /* logical delivery */
entry.mask = 1; /* unmask IRQ now */
entry.mask = 0; /* unmask IRQ now */
entry.dest.logical.logical_dest = 0xff; /* all CPUs */
entry.vector = IO_APIC_VECTOR(irq);
......@@ -392,56 +465,42 @@ void setup_IO_APIC_irq_ISA_default (unsigned int irq)
io_apic_write(0x11+2*irq, *(((int *)&entry)+1));
}
int IO_APIC_get_PCI_irq_vector (int bus, int slot, int pci_pin)
{
int i;
for (i=0; i<mp_irq_entries; i++) {
int lbus = mp_irqs[i].mpc_srcbus;
if (IO_APIC_IRQ(mp_irqs[i].mpc_dstirq) &&
(mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
!mp_irqs[i].mpc_irqtype &&
(bus == mp_bus_id_to_pci_bus[mp_irqs[i].mpc_srcbus]) &&
(slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f)) &&
(pci_pin == (mp_irqs[i].mpc_srcbusirq & 3)))
return mp_irqs[i].mpc_dstirq;
}
return -1;
}
/*
* There is a nasty bug in some older SMP boards, their mptable lies
* about the timer IRQ. We do the following to work around the situation:
*
* - timer IRQ defaults to IO-APIC IRQ
* - if this function detects that timer IRQs are defunct, then we fall
* back to ISA timer IRQs
* Set up a certain pin as ExtINT delivered interrupt
*/
static int timer_irq_works (void)
__initfunc(void setup_ExtINT_pin (unsigned int pin))
{
unsigned int t1=jiffies;
unsigned long flags;
struct IO_APIC_route_entry entry;
save_flags(flags);
sti();
/*
* add it to the IO-APIC irq-routing table:
*/
memset(&entry,0,sizeof(entry));
udelay(100*1000);
entry.delivery_mode = dest_ExtINT;
entry.dest_mode = 1; /* logical delivery */
entry.mask = 0; /* unmask IRQ now */
entry.dest.logical.logical_dest = 0xff; /* all CPUs */
if (jiffies-t1>1)
return 1;
entry.vector = IO_APIC_VECTOR(pin); /* it's ignored */
return 0;
entry.polarity=0;
entry.trigger=0;
io_apic_write(0x10+2*pin, *(((int *)&entry)+0));
io_apic_write(0x11+2*pin, *(((int *)&entry)+1));
}
void print_IO_APIC (void)
__initfunc(void print_IO_APIC (void))
{
int i;
struct IO_APIC_reg_00 reg_00;
struct IO_APIC_reg_01 reg_01;
struct IO_APIC_reg_02 reg_02;
printk("nr of MP irq sources: %d.\n", mp_irq_entries);
printk("nr of IO-APIC registers: %d.\n", nr_ioapic_registers);
*(int *)&reg_00 = io_apic_read(0);
*(int *)&reg_01 = io_apic_read(1);
*(int *)&reg_02 = io_apic_read(2);
......@@ -513,14 +572,41 @@ void print_IO_APIC (void)
return;
}
static void init_sym_mode (void)
__initfunc(static void init_sym_mode (void))
{
int i;
if (!pirqs_enabled)
for (i=0; i<MAX_PIRQS; i++)
pirq_entries[i]=-1;
printk("enabling Symmetric IO mode ... ");
outb_p (0x70, 0x22);
outb_p (0x01, 0x23);
outb(0x70, 0x22);
outb(0x01, 0x23);
printk("...done.\n");
/*
* The number of IO-APIC irq-registers (== #pins):
*/
{
struct IO_APIC_reg_01 reg_01;
*(int *)&reg_01 = io_apic_read(1);
nr_ioapic_registers = reg_01.entries+1;
}
/*
* Do not trust the IO-APIC being empty at bootup
*/
for (i=0; i<nr_ioapic_registers; i++)
clear_IO_APIC_pin (i);
}
/*
* Not an initfunc, needed by the reboot code
*/
void init_pic_mode (void)
{
printk("disabling Symmetric IO mode ... ");
......@@ -551,8 +637,7 @@ struct ioapic_list_entry ioapic_blacklist [] = {
{ 0 , 0 }
};
static int in_ioapic_list (struct ioapic_list_entry * table)
__initfunc(static int in_ioapic_list (struct ioapic_list_entry * table))
{
for (;table->oem_id; table++)
if ((!strcmp(table->oem_id,ioapic_OEM_ID)) &&
......@@ -561,7 +646,7 @@ static int in_ioapic_list (struct ioapic_list_entry * table)
return 0;
}
static int ioapic_whitelisted (void)
__initfunc(static int ioapic_whitelisted (void))
{
/*
* Right now, whitelist everything to see whether the new parsing
......@@ -574,12 +659,12 @@ static int ioapic_whitelisted (void)
#endif
}
static int ioapic_blacklisted (void)
__initfunc(static int ioapic_blacklisted (void))
{
return in_ioapic_list(ioapic_blacklist);
}
static void setup_ioapic_id (void)
__initfunc(static void setup_ioapic_id (void))
{
struct IO_APIC_reg_00 reg_00;
......@@ -598,7 +683,7 @@ static void setup_ioapic_id (void)
panic("APIC ID 2 already used");
/*
* set the ID
* Set the ID
*/
*(int *)&reg_00 = io_apic_read(0);
printk("... changing IO-APIC physical APIC ID to 2 ...\n");
......@@ -613,7 +698,7 @@ static void setup_ioapic_id (void)
panic("could not set ID");
}
static void construct_default_ISA_mptable (void)
__initfunc(static void construct_default_ISA_mptable (void))
{
int i, pos=0;
......@@ -650,31 +735,84 @@ static void construct_default_ISA_mptable (void)
setup_ioapic_id();
}
void setup_IO_APIC (void)
/*
* There is a nasty bug in some older SMP boards, their mptable lies
* about the timer IRQ. We do the following to work around the situation:
*
* - timer IRQ defaults to IO-APIC IRQ
* - if this function detects that timer IRQs are defunct, then we fall
* back to ISA timer IRQs
*/
__initfunc(static int timer_irq_works (void))
{
int i;
unsigned int t1=jiffies;
unsigned long flags;
if (!pirqs_enabled)
for (i=0; i<MAX_PIRQS; i++)
pirq_entries[i]=-1;
save_flags(flags);
sti();
init_sym_mode();
{
struct IO_APIC_reg_01 reg_01;
udelay(10*10000);
*(int *)&reg_01 = io_apic_read(1);
nr_ioapic_registers = reg_01.entries+1;
if (jiffies-t1>1)
return 1;
return 0;
}
/*
* This code may look a bit paranoid, but it's supposed to cooperate with
* a wide range of boards and BIOS bugs ... fortunately only the timer IRQ
* is so screwy. Thanks to Brian Perkins for testing/hacking this beast
* fanatically on his truly bugged board.
*/
__initfunc(static void check_timer (void))
{
int pin1, pin2;
pin1 = find_timer_pin (mp_INT);
pin2 = find_timer_pin (mp_ExtINT);
if (!timer_irq_works ()) {
if (pin1 != -1)
printk("..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
printk("..trying to set up timer as ExtINT ... ");
if (pin2 != -1) {
printk(".. (found pin %d) ...", pin2);
setup_ExtINT_pin (pin2);
make_8259A_irq(0);
}
if (!timer_irq_works ()) {
printk(" failed.\n");
printk("..trying to set up timer as BP irq ...");
/*
* Just in case ...
*/
if (pin1 != -1)
clear_IO_APIC_pin (pin1);
if (pin2 != -1)
clear_IO_APIC_pin (pin2);
make_8259A_irq(0);
if (!timer_irq_works ()) {
printk(" failed.\n");
panic("IO-APIC + timer doesnt work!");
}
}
printk(" works.\n");
}
}
/*
* do not trust the IO-APIC being empty at bootup
*/
for (i=0; i<nr_ioapic_registers; i++)
clear_IO_APIC_irq (i);
__initfunc(void setup_IO_APIC (void))
{
init_sym_mode();
/*
* the following IO-APIC's can be enabled:
* Determine the range of IRQs handled by the IO-APIC. The
* following boards can be fully enabled:
*
* - whitelisted ones
* - those which have no PCI pins connected
......@@ -699,7 +837,7 @@ void setup_IO_APIC (void)
/*
* If there are no explicit mp irq entries: it's either one of the
* default configuration types or we are broken. In both cases it's
* fine to set up most of the low 16 IOAPIC pins to ISA defaults.
* fine to set up most of the low 16 IO-APIC pins to ISA defaults.
*/
if (!mp_irq_entries) {
printk("no explicit IRQ entries, using default mptable\n");
......@@ -708,18 +846,13 @@ void setup_IO_APIC (void)
init_IO_APIC_traps();
/*
* Set up the IO-APIC irq routing table by parsing the MP-BIOS
* mptable:
*/
setup_IO_APIC_irqs ();
if (!timer_irq_works ()) {
make_8259A_irq(0);
if (!timer_irq_works ())
panic("IO-APIC + timer doesnt work!");
printk("..MP-BIOS bug: i8254 timer not connected to IO-APIC\n");
printk("..falling back to 8259A-based timer interrupt\n");
}
check_timer();
printk("nr of MP irq sources: %d.\n", mp_irq_entries);
printk("nr of IOAPIC registers: %d.\n", nr_ioapic_registers);
print_IO_APIC();
}
......@@ -735,7 +735,11 @@ static void do_8259A_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
static void enable_ioapic_irq(unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
#if 0
enable_IO_APIC_irq(irq);
#endif
if (desc->events && !desc->ipi) {
ack_APIC_irq();
desc->ipi = 1;
send_IPI(APIC_DEST_SELF, IO_APIC_VECTOR(irq));
}
......@@ -746,6 +750,9 @@ static void enable_ioapic_irq(unsigned int irq)
*/
static void disable_ioapic_irq(unsigned int irq)
{
#if 0
disable_IO_APIC_irq(irq);
#endif
}
static void do_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
......@@ -754,13 +761,15 @@ static void do_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
spin_lock(&irq_controller_lock);
/* Ack the irq inside the lock! */
ack_APIC_irq();
desc->ipi = 0;
/* If the irq is disabled for whatever reason, just set a flag and return */
/*
* If the irq is disabled for whatever reason, just
* set a flag and return
*/
if (desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)) {
desc->events = 1;
ack_APIC_irq();
spin_unlock(&irq_controller_lock);
return;
}
......@@ -790,6 +799,7 @@ static void do_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
spin_unlock(&irq_controller_lock);
no_handler:
ack_APIC_irq();
hardirq_exit(cpu);
release_irqlock(cpu);
}
......
......@@ -104,6 +104,12 @@
Moved register-setting macros into this file.
Moved setup code from init/main.c to i386-specific areas.
v1.18
19980502 Richard Gooch <rgooch@atnf.csiro.au>
Moved MTRR detection outside conditionals in <mtrr_init>.
v1.19
19980502 Richard Gooch <rgooch@atnf.csiro.au>
Documentation improvement: mention Pentium II and AGP.
v1.20
*/
#include <linux/types.h>
#include <linux/errno.h>
......@@ -137,7 +143,7 @@
#include <asm/atomic.h>
#include <linux/smp.h>
#define MTRR_VERSION "1.18 (19980429)"
#define MTRR_VERSION "1.20 (19980502)"
#define TRUE 1
#define FALSE 0
......@@ -801,7 +807,7 @@ int mtrr_add (unsigned long base, unsigned long size, unsigned int type,
if (ltype != type)
{
spin_unlock (&main_lock);
printk ( "mtrr: type missmatch for %lx,%lx old: %s new: %s\n",
printk ( "mtrr: type mismatch for %lx,%lx old: %s new: %s\n",
base, size, attrib_to_str (ltype), attrib_to_str (type) );
return -EINVAL;
}
......@@ -1193,8 +1199,8 @@ int init_module (void)
__initfunc(int mtrr_init(void))
#endif
{
# if !defined(__SMP__) || defined(MODULE)
if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return 0;
# if !defined(__SMP__) || defined(MODULE)
printk("mtrr: v%s Richard Gooch (rgooch@atnf.csiro.au)\n", MTRR_VERSION);
#endif
......
......@@ -297,9 +297,9 @@ void machine_restart(char * __unused)
int i;
for (i=0; i<100; i++) {
kb_wait();
udelay(10);
udelay(50);
outb(0xfe,0x64); /* pulse reset low */
udelay(10);
udelay(50);
}
/* That didn't work - force a triple fault.. */
__asm__ __volatile__("lidt %0": :"m" (no_idt));
......
......@@ -627,20 +627,29 @@ __initfunc(void smp_commence(void))
smp_commenced=1;
}
__initfunc(void enable_local_APIC(void))
{
unsigned long value;
value = apic_read(APIC_SPIV);
value |= (1<<8); /* Enable APIC (bit==1) */
value &= ~(1<<9); /* Enable focus processor (bit==0) */
apic_write(APIC_SPIV,value);
udelay(100); /* B safe */
}
__initfunc(void smp_callin(void))
{
extern void calibrate_delay(void);
int cpuid=GET_APIC_ID(apic_read(APIC_ID));
unsigned long l;
/*
* Activate our APIC
*/
SMP_PRINTK(("CALLIN %d %d\n",hard_smp_processor_id(), smp_processor_id()));
l=apic_read(APIC_SPIV);
l|=(1<<8); /* Enable */
apic_write(APIC_SPIV,l);
enable_local_APIC();
/*
* Set up our APIC timer.
......@@ -1004,15 +1013,7 @@ __initfunc(void smp_boot_cpus(void))
}
#endif
/*
* Enable the local APIC
*/
cfg=apic_read(APIC_SPIV);
cfg|=(1<<8); /* Enable APIC */
apic_write(APIC_SPIV,cfg);
udelay(10);
enable_local_APIC();
/*
* Set up our local APIC timer:
......@@ -1561,7 +1562,7 @@ __initfunc(static unsigned int get_8254_timer_count (void))
* APIC double write bug.
*/
#define APIC_DIVISOR 16
#define APIC_DIVISOR 1
void setup_APIC_timer (unsigned int clocks)
{
......@@ -1585,7 +1586,7 @@ void setup_APIC_timer (unsigned int clocks)
*/
tmp_value = apic_read(APIC_TDCR);
apic_write(APIC_TDCR , (tmp_value & ~APIC_TDR_DIV_1 )
| APIC_TDR_DIV_16);
| APIC_TDR_DIV_1);
tmp_value = apic_read(APIC_TMICT);
apic_write(APIC_TMICT, clocks/APIC_DIVISOR);
......
......@@ -1209,6 +1209,14 @@ static int raid5_make_request (struct md_dev *mddev, int rw, struct buffer_head
sh->pd_idx = pd_idx;
if (sh->phase != PHASE_COMPLETE && sh->phase != PHASE_BEGIN)
PRINTK(("stripe %lu catching the bus!\n", sh->sector));
if (sh->bh_new[dd_idx]) {
printk("raid5: bug: stripe->bh_new[%d], sector %lu exists\n", dd_idx, sh->sector);
printk("raid5: bh %p, bh_new %p\n", bh, sh->bh_new[dd_idx]);
lock_stripe(sh);
md_wakeup_thread(raid_conf->thread);
wait_on_stripe(sh);
goto repeat;
}
add_stripe_bh(sh, bh, dd_idx, rw);
md_wakeup_thread(raid_conf->thread);
......
......@@ -37,8 +37,8 @@ static int irq_write_proc(struct file *file, const char *buffer,
int retval = -EINVAL;
int newirq = PARPORT_IRQ_NONE;
struct parport *pp = (struct parport *)data;
struct pardevice *cad = pp->cad;
int oldirq = pp->irq;
unsigned long flags;
/*
* We can have these valid cases:
......@@ -70,36 +70,31 @@ static int irq_write_proc(struct file *file, const char *buffer,
if (oldirq == newirq)
goto out;
spin_lock_irqsave(&port->lock, flags);
if (pp->flags & PARPORT_FLAG_COMA)
goto out_ok;
if (newirq != PARPORT_IRQ_NONE) {
void (*handler)(int, void *, struct pt_regs *);
if (cad && cad->irq_func)
handler = cad->irq_func;
else
handler = parport_null_intr_func;
retval = -EBUSY;
if (pp->cad)
goto out_unlock;
retval = request_irq(newirq, handler,
SA_INTERRUPT,
cad ? cad->name : pp->name,
cad ? cad->private : NULL);
if (newirq != PARPORT_IRQ_NONE) {
retval = request_irq(newirq, parport_null_intr_func,
SA_INTERRUPT, pp->name, NULL);
if (retval)
goto out;
goto out_unlock;
else retval = count;
}
if (oldirq != PARPORT_IRQ_NONE) {
if (cad && cad->irq_func)
free_irq(oldirq, cad->private);
else
free_irq(oldirq, NULL);
}
if (oldirq != PARPORT_IRQ_NONE)
free_irq(oldirq, NULL);
out_ok:
pp->irq = newirq;
out_unlock:
spin_unlock_irqrestore (&pp->lock, flags);
out:
return retval;
}
......
......@@ -308,7 +308,9 @@ int parport_claim(struct pardevice *dev)
}
/* Now we do the change of devices */
spin_lock_irqsave(&port->lock, flags);
port->cad = dev;
spin_unlock_irqrestore(&port->lock, flags);
/* Swap the IRQ handlers. */
if (port->irq != PARPORT_IRQ_NONE) {
......@@ -346,9 +348,8 @@ int parport_claim(struct pardevice *dev)
dev->waitprev = port->waittail;
if (port->waittail)
port->waittail->waitnext = dev;
else {
port->waithead = dev->port->waittail = dev;
}
else
port->waithead = port->waittail = dev;
}
spin_unlock_irqrestore (&port->lock, flags);
}
......
......@@ -8,7 +8,7 @@
* Dynamic PPP devices by Jim Freeman <jfree@caldera.com>.
* ppp_tty_receive ``noisy-raise-bug'' fixed by Ove Ewerlid <ewerlid@syscon.uu.se>
*
* ==FILEVERSION 980319==
* ==FILEVERSION 980501==
*
* NOTE TO MAINTAINERS:
* If you modify this file at all, please set the number above to the
......@@ -107,8 +107,10 @@ typedef struct sk_buff sk_buff;
#define PPP_LQR 0xc025 /* Link Quality Reporting Protocol */
#endif
#ifdef CONFIG_MODULES
static int ppp_register_compressor (struct compressor *cp);
static void ppp_unregister_compressor (struct compressor *cp);
#endif
/*
* Local functions
......@@ -3210,6 +3212,7 @@ static struct compressor *find_compressor (int type)
return (struct compressor *) 0;
}
#ifdef CONFIG_MODULES
static int ppp_register_compressor (struct compressor *cp)
{
struct compressor_link *new;
......@@ -3261,6 +3264,7 @@ static void ppp_unregister_compressor (struct compressor *cp)
}
restore_flags(flags);
}
#endif
/*************************************************************
* Module support routines
......
/*
* $Id: oldproc.c,v 1.10 1998/03/15 13:50:11 ecd Exp $
* $Id: oldproc.c,v 1.12 1998/05/01 10:58:21 mj Exp $
*
* Backward-compatible procfs interface for PCI.
*
......@@ -60,10 +60,14 @@ struct pci_dev_info dev_info[] = {
DEVICE( ATI, ATI_210888CX, "210888CX"),
DEVICE( ATI, ATI_215GB, "Mach64 GB"),
DEVICE( ATI, ATI_215GD, "Mach64 GD (Rage Pro)"),
DEVICE( ATI, ATI_215GI, "Mach64 GI (Rage Pro)"),
DEVICE( ATI, ATI_215GP, "Mach64 GP (Rage Pro)"),
DEVICE( ATI, ATI_215GQ, "Mach64 GQ (Rage Pro)"),
DEVICE( ATI, ATI_215GT, "Mach64 GT (Rage II)"),
DEVICE( ATI, ATI_215GTB, "Mach64 GT (Rage II)"),
DEVICE( ATI, ATI_210888GX, "210888GX"),
DEVICE( ATI, ATI_215LG, "Mach64 LG (Rage Pro)"),
DEVICE( ATI, ATI_264LT, "Mach64 LT"),
DEVICE( ATI, ATI_264VT, "Mach64 VT"),
DEVICE( VLSI, VLSI_82C592, "82C592-FC1"),
DEVICE( VLSI, VLSI_82C593, "82C593-FC1"),
......@@ -116,6 +120,9 @@ struct pci_dev_info dev_info[] = {
DEVICE( IBM, IBM_82G2675, "82G2675"),
DEVICE( IBM, IBM_MCA, "MicroChannel"),
DEVICE( IBM, IBM_82351, "82351"),
DEVICE( IBM, IBM_SERVERAID, "ServeRAID"),
DEVICE( IBM, IBM_TR_WAKE, "Wake On LAN Token Ring"),
DEVICE( IBM, IBM_3780IDSP, "MWave DSP"),
DEVICE( WD, WD_7197, "WD 7197"),
DEVICE( AMD, AMD_LANCE, "79C970"),
DEVICE( AMD, AMD_SCSI, "53C974"),
......@@ -135,12 +142,15 @@ struct pci_dev_info dev_info[] = {
DEVICE( CT, CT_65548, "65548"),
DEVICE( CT, CT_65550, "65550"),
DEVICE( CT, CT_65554, "65554"),
DEVICE( CT, CT_65555, "65555"),
DEVICE( MIRO, MIRO_36050, "ZR36050"),
DEVICE( NEC, NEC_PCX2, "PowerVR PCX2"),
DEVICE( FD, FD_36C70, "TMC-18C30"),
DEVICE( SI, SI_6201, "6201"),
DEVICE( SI, SI_5591_AGP, "5591/5592 AGP"),
DEVICE( SI, SI_6202, "6202"),
DEVICE( SI, SI_503, "85C503"),
DEVICE( SI, SI_ACPI, "ACPI"),
DEVICE( SI, SI_5597_VGA, "5597/5598 VGA"),
DEVICE( SI, SI_6205, "6205"),
DEVICE( SI, SI_501, "85C501"),
DEVICE( SI, SI_496, "85C496"),
......@@ -149,8 +159,9 @@ struct pci_dev_info dev_info[] = {
DEVICE( SI, SI_5511, "85C5511"),
DEVICE( SI, SI_5513, "85C5513"),
DEVICE( SI, SI_5571, "5571"),
DEVICE( SI, SI_5597, "5597"),
DEVICE( SI, SI_7001, "7001"),
DEVICE( SI, SI_5591, "5591/5592 Host"),
DEVICE( SI, SI_5597, "5597/5598 Host"),
DEVICE( SI, SI_7001, "7001 USB"),
DEVICE( HP, HP_J2585A, "J2585A"),
DEVICE( HP, HP_J2585B, "J2585B (Lassen)"),
DEVICE( PCTECH, PCTECH_RZ1000, "RZ1000 (buggy)"),
......@@ -198,6 +209,7 @@ struct pci_dev_info dev_info[] = {
DEVICE( UMC, UMC_UM8891N, "UM8891N"),
DEVICE( X, X_AGX016, "ITT AGX016"),
DEVICE( PICOP, PICOP_PT86C52X, "PT86C52x Vesuvius"),
DEVICE( PICOP, PICOP_PT80C524, "PT80C524 Nile"),
DEVICE( APPLE, APPLE_BANDIT, "Bandit"),
DEVICE( APPLE, APPLE_GC, "Grand Central"),
DEVICE( APPLE, APPLE_HYDRA, "Hydra"),
......@@ -242,6 +254,8 @@ struct pci_dev_info dev_info[] = {
DEVICE( WINBOND, WINBOND_83C553, "W83C553"),
DEVICE( DATABOOK, DATABOOK_87144, "DB87144"),
DEVICE( PLX, PLX_9080, "PCI9080 I2O"),
DEVICE( MADGE, MADGE_MK2, "Smart 16/4 BM Mk2 Ringnode"),
DEVICE( 3COM, 3COM_3C339, "3C339 TokenRing"),
DEVICE( 3COM, 3COM_3C590, "3C590 10bT"),
DEVICE( 3COM, 3COM_3C595TX, "3C595 100bTX"),
DEVICE( 3COM, 3COM_3C595T4, "3C595 100bT4"),
......@@ -249,6 +263,8 @@ struct pci_dev_info dev_info[] = {
DEVICE( 3COM, 3COM_3C900TPO, "3C900 10bTPO"),
DEVICE( 3COM, 3COM_3C900COMBO,"3C900 10b Combo"),
DEVICE( 3COM, 3COM_3C905TX, "3C905 100bTX"),
DEVICE( 3COM, 3COM_3C905T4, "3C905 100bT4"),
DEVICE( 3COM, 3COM_3C905B_TX, "3C905B 100bTX"),
DEVICE( SMC, SMC_EPIC100, "9432 TX"),
DEVICE( AL, AL_M1445, "M1445"),
DEVICE( AL, AL_M1449, "M1449"),
......@@ -274,6 +290,8 @@ struct pci_dev_info dev_info[] = {
DEVICE( ASP, ASP_ABP940, "ABP940"),
DEVICE( ASP, ASP_ABP940U, "ABP940U"),
DEVICE( ASP, ASP_ABP940UW, "ABP940UW"),
DEVICE( MACRONIX, MACRONIX_MX98713,"MX98713"),
DEVICE( MACRONIX, MACRONIX_MX987x5,"MX98715 / MX98725"),
DEVICE( CERN, CERN_SPSB_PMC, "STAR/RD24 SCI-PCI (PMC)"),
DEVICE( CERN, CERN_SPSB_PCI, "STAR/RD24 SCI-PCI (PMC)"),
DEVICE( CERN, CERN_HIPPI_DST, "HIPPI destination"),
......@@ -282,12 +300,14 @@ struct pci_dev_info dev_info[] = {
DEVICE( TEKRAM2, TEKRAM2_690c, "DC690c"),
DEVICE( TUNDRA, TUNDRA_CA91C042,"CA91C042 Universe"),
DEVICE( AMCC, AMCC_MYRINET, "Myrinet PCI (M2-PCI-32)"),
DEVICE( AMCC, AMCC_PARASTATION,"ParaStation Interface"),
DEVICE( AMCC, AMCC_S5933, "S5933 PCI44"),
DEVICE( AMCC, AMCC_S5933_HEPC3,"S5933 Traquair HEPC3"),
DEVICE( INTERG, INTERG_1680, "IGA-1680"),
DEVICE( INTERG, INTERG_1682, "IGA-1682"),
DEVICE( REALTEK, REALTEK_8029, "8029"),
DEVICE( REALTEK, REALTEK_8129, "8129"),
DEVICE( REALTEK, REALTEK_8139, "8139"),
DEVICE( TRUEVISION, TRUEVISION_T1000,"TARGA 1000"),
DEVICE( INIT, INIT_320P, "320 P"),
DEVICE( INIT, INIT_360P, "360 P"),
......@@ -304,6 +324,7 @@ struct pci_dev_info dev_info[] = {
DEVICE( VIA, VIA_82C595_97, "VT 82C595 Apollo VP2/97"),
DEVICE( VIA, VIA_82C586_2, "VT 82C586 Apollo USB"),
DEVICE( VIA, VIA_82C586_3, "VT 82C586B Apollo ACPI"),
DEVICE( VIA, VIA_86C100A, "VT 86C100A"),
DEVICE( VIA, VIA_82C597_1, "VT 82C597 Apollo VP3 AGP"),
DEVICE( VORTEX, VORTEX_GDT60x0, "GDT 60x0"),
DEVICE( VORTEX, VORTEX_GDT6000B,"GDT 6000b"),
......@@ -342,6 +363,7 @@ struct pci_dev_info dev_info[] = {
DEVICE( FORE, FORE_PCA200PC, "PCA-200PC"),
DEVICE( FORE, FORE_PCA200E, "PCA-200E"),
DEVICE( IMAGINGTECH, IMAGINGTECH_ICPCI, "MVC IC-PCI"),
DEVICE( PHILIPS, PHILIPS_SAA7145,"SAA7145"),
DEVICE( PHILIPS, PHILIPS_SAA7146,"SAA7146"),
DEVICE( CYCLONE, CYCLONE_SDK, "SDK"),
DEVICE( ALLIANCE, ALLIANCE_PROMOTIO, "Promotion-6410"),
......@@ -356,6 +378,7 @@ struct pci_dev_info dev_info[] = {
DEVICE( DIGI, DIGI_CX, "AccelPort C/X"),
DEVICE( DIGI, DIGI_XRJ, "AccelPort Xr/J"),
DEVICE( DIGI, DIGI_EPCJ, "AccelPort EPC/J"),
DEVICE( DIGI, DIGI_XR_920, "AccelPort Xr 920"),
DEVICE( MUTECH, MUTECH_MV1000, "MV-1000"),
DEVICE( RENDITION, RENDITION_VERITE,"Verite 1000"),
DEVICE( RENDITION, RENDITION_VERITE2100,"Verite 2100"),
......@@ -377,20 +400,21 @@ struct pci_dev_info dev_info[] = {
DEVICE( IKON, IKON_10117, "10117 Greensheet"),
DEVICE( ZORAN, ZORAN_36057, "ZR36057"),
DEVICE( ZORAN, ZORAN_36120, "ZR36120"),
DEVICE( KINETIC, KINETIC_2915, "2915 CAMAC"),
DEVICE( COMPEX, COMPEX_ENET100VG4, "Readylink ENET100-VG4"),
DEVICE( COMPEX, COMPEX_RL2000, "ReadyLink 2000"),
DEVICE( RP, RP8OCTA, "RocketPort 8 Oct"),
DEVICE( RP, RP8INTF, "RocketPort 8 Intf"),
DEVICE( RP, RP16INTF, "RocketPort 16 Intf"),
DEVICE( RP, RP32INTF, "RocketPort 32 Intf"),
DEVICE( ESSENTIAL, ROADRUNNER, "RoadRunner serial HIPPI"),
DEVICE( CYCLADES, CYCLOM_Y_Lo, "Cyclom-Y below 1Mbyte"),
DEVICE( CYCLADES, CYCLOM_Y_Hi, "Cyclom-Y above 1Mbyte"),
DEVICE( CYCLADES, CYCLOM_Z_Lo, "Cyclom-Z below 1Mbyte"),
DEVICE( CYCLADES, CYCLOM_Z_Hi, "Cyclom-Z above 1Mbyte"),
DEVICE( ESSENTIAL, ESSENTIAL_ROADRUNNER,"Roadrunner serial HIPPI"),
DEVICE( O2, O2_6832, "6832"),
DEVICE( 3DFX, 3DFX_VOODOO, "Voodoo"),
DEVICE( 3DFX, 3DFX_VOODOO2, "Voodoo2"),
DEVICE( 3DFX, 3DFX_VOODOO2, "Voodoo2"),
DEVICE( SIGMADES, SIGMADES_6425, "REALmagic64/GX"),
DEVICE( STALLION, STALLION_ECHPCI832,"EasyConnection 8/32"),
DEVICE( STALLION, STALLION_ECHPCI864,"EasyConnection 8/64"),
......@@ -400,15 +424,20 @@ struct pci_dev_info dev_info[] = {
DEVICE( OPTIBASE, OPTIBASE_VPLEX, "VideoPlex"),
DEVICE( OPTIBASE, OPTIBASE_VPLEXCC,"VideoPlex CC"),
DEVICE( OPTIBASE, OPTIBASE_VQUEST,"VideoQuest"),
DEVICE( SATSAGEM, SATSAGEM_PCR2101,"PCR2101 DVB receiver"),
DEVICE( SATSAGEM, SATSAGEM_TELSATTURBO,"Telsat Turbo DVB"),
DEVICE( HUGHES, HUGHES_DIRECPC, "DirecPC"),
DEVICE( ENSONIQ, ENSONIQ_AUDIOPCI,"AudioPCI"),
DEVICE( PICTUREL, PICTUREL_PCIVST,"PCIVST"),
DEVICE( NVIDIA_SGS, NVIDIA_SGS_RIVA128, "Riva 128"),
DEVICE( CBOARDS, CBOARDS_DAS1602_16,"DAS1602/16"),
DEVICE( SYMPHONY, SYMPHONY_101, "82C101"),
DEVICE( TEKRAM, TEKRAM_DC290, "DC-290"),
DEVICE( 3DLABS, 3DLABS_300SX, "GLINT 300SX"),
DEVICE( 3DLABS, 3DLABS_500TX, "GLINT 500TX"),
DEVICE( 3DLABS, 3DLABS_DELTA, "GLINT Delta"),
DEVICE( 3DLABS, 3DLABS_PERMEDIA,"PERMEDIA"),
DEVICE( 3DLABS, 3DLABS_MX, "GLINT MX"),
DEVICE( AVANCE, AVANCE_ALG2064, "ALG2064i"),
DEVICE( AVANCE, AVANCE_2302, "ALG-2302"),
DEVICE( NETVIN, NETVIN_NV5000SC,"NV5000"),
......@@ -450,6 +479,7 @@ struct pci_dev_info dev_info[] = {
DEVICE( INTEL, INTEL_82371MX, "430MX - 82371MX MPIIX"),
DEVICE( INTEL, INTEL_82437MX, "430MX - 82437MX MTSC"),
DEVICE( INTEL, INTEL_82441, "82441FX Natoma"),
DEVICE( INTEL, INTEL_82380FB, "82380FB Mobile"),
DEVICE( INTEL, INTEL_82439, "82439HX Triton II"),
DEVICE( INTEL, INTEL_82371SB_0,"82371SB PIIX3 ISA"),
DEVICE( INTEL, INTEL_82371SB_1,"82371SB PIIX3 IDE"),
......@@ -462,9 +492,13 @@ struct pci_dev_info dev_info[] = {
DEVICE( INTEL, INTEL_82371AB_3,"82371AB PIIX4 ACPI"),
DEVICE( INTEL, INTEL_82443LX_0,"440LX - 82443LX PAC Host"),
DEVICE( INTEL, INTEL_82443LX_1,"440LX - 82443LX PAC AGP"),
DEVICE( INTEL, INTEL_82443BX_0,"440BX - 82443BX Host"),
DEVICE( INTEL, INTEL_82443BX_1,"440BX - 82443BX AGP"),
DEVICE( INTEL, INTEL_82443BX_2,"440BX - 82443BX Host (no AGP)"),
DEVICE( INTEL, INTEL_P6, "Orion P6"),
DEVICE( INTEL, INTEL_82450GX, "82450GX Orion P6"),
DEVICE( KTI, KTI_ET32P2, "ET32P2"),
DEVICE( ADAPTEC, ADAPTEC_7810, "AIC-7810 RAID"),
DEVICE( ADAPTEC, ADAPTEC_7850, "AIC-7850"),
DEVICE( ADAPTEC, ADAPTEC_7855, "AIC-7855"),
DEVICE( ADAPTEC, ADAPTEC_5800, "AIC-5800"),
......@@ -481,7 +515,9 @@ struct pci_dev_info dev_info[] = {
DEVICE( ADAPTEC, ADAPTEC_7882, "AIC-7882U"),
DEVICE( ADAPTEC, ADAPTEC_7883, "AIC-7883U"),
DEVICE( ADAPTEC, ADAPTEC_7884, "AIC-7884U"),
DEVICE( ADAPTEC, ADAPTEC_1030, "ABA-1030 DVB receiver"),
DEVICE( ATRONICS, ATRONICS_2015, "IDE-2015PL"),
DEVICE( TIGERJET, TIGERJET_300, "Tiger300 ISDN"),
DEVICE( ARK, ARK_STING, "Stingray"),
DEVICE( ARK, ARK_STINGARK, "Stingray ARK 2000PV"),
DEVICE( ARK, ARK_2000MT, "2000MT")
......@@ -658,6 +694,7 @@ static const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_WINBOND: return "Winbond";
case PCI_VENDOR_ID_DATABOOK: return "Databook";
case PCI_VENDOR_ID_PLX: return "PLX";
case PCI_VENDOR_ID_MADGE: return "Madge Networks";
case PCI_VENDOR_ID_3COM: return "3Com";
case PCI_VENDOR_ID_SMC: return "SMC";
case PCI_VENDOR_ID_AL: return "Acer Labs";
......@@ -665,6 +702,7 @@ static const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_SURECOM: return "Surecom";
case PCI_VENDOR_ID_NEOMAGIC: return "Neomagic";
case PCI_VENDOR_ID_ASP: return "Advanced System Products";
case PCI_VENDOR_ID_MACRONIX: return "Macronix";
case PCI_VENDOR_ID_CERN: return "CERN";
case PCI_VENDOR_ID_NVIDIA: return "NVidia";
case PCI_VENDOR_ID_IMS: return "IMS";
......@@ -699,17 +737,23 @@ static const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_AURAVISION: return "Auravision";
case PCI_VENDOR_ID_IKON: return "Ikon";
case PCI_VENDOR_ID_ZORAN: return "Zoran";
case PCI_VENDOR_ID_KINETIC: return "Kinetic";
case PCI_VENDOR_ID_COMPEX: return "Compex";
case PCI_VENDOR_ID_RP: return "Comtrol";
case PCI_VENDOR_ID_CYCLADES: return "Cyclades";
case PCI_VENDOR_ID_O2: return "O2 Micro";
case PCI_VENDOR_ID_3DFX: return "3Dfx";
case PCI_VENDOR_ID_STALLION: return "Stallion Technologies";
case PCI_VENDOR_ID_SIGMADES: return "Sigma Designs";
case PCI_VENDOR_ID_CCUBE: return "C-Cube";
case PCI_VENDOR_ID_DIPIX: return "Dipix";
case PCI_VENDOR_ID_STALLION: return "Stallion Technologies";
case PCI_VENDOR_ID_OPTIBASE: return "Optibase";
case PCI_VENDOR_ID_SATSAGEM: return "SatSagem";
case PCI_VENDOR_ID_HUGHES: return "Hughes";
case PCI_VENDOR_ID_ENSONIQ: return "Ensoniq";
case PCI_VENDOR_ID_PICTUREL: return "Picture Elements";
case PCI_VENDOR_ID_NVIDIA_SGS: return "NVidia/SGS Thomson";
case PCI_VENDOR_ID_CBOARDS: return "ComputerBoards";
case PCI_VENDOR_ID_SYMPHONY: return "Symphony";
case PCI_VENDOR_ID_TEKRAM: return "Tekram";
case PCI_VENDOR_ID_3DLABS: return "3Dlabs";
......@@ -720,6 +764,7 @@ static const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_KTI: return "KTI";
case PCI_VENDOR_ID_ADAPTEC: return "Adaptec";
case PCI_VENDOR_ID_ATRONICS: return "Atronics";
case PCI_VENDOR_ID_TIGERJET: return "TigerJet";
case PCI_VENDOR_ID_ARK: return "ARK Logic";
default: return "Unknown vendor";
}
......@@ -744,7 +789,7 @@ static const char *pci_strdev(unsigned int vendor, unsigned int device)
static int sprint_dev_config(struct pci_dev *dev, char *buf, int size)
{
unsigned long base;
unsigned int l, class_rev, bus, devfn;
unsigned int class_rev, bus, devfn;
unsigned short vendor, device, status;
unsigned char bist, latency, min_gnt, max_lat;
int reg, len = 0;
......@@ -835,12 +880,7 @@ static int sprint_dev_config(struct pci_dev *dev, char *buf, int size)
if (len + 40 > size) {
return -1;
}
pcibios_read_config_dword(bus, devfn,
PCI_BASE_ADDRESS_0 + (reg << 2), &l);
if (l == 0xffffffff)
base = 0;
else
base = l;
base = dev->base_address[reg];
if (!base)
continue;
......@@ -863,12 +903,7 @@ static int sprint_dev_config(struct pci_dev *dev, char *buf, int size)
case PCI_BASE_ADDRESS_MEM_TYPE_1M:
type = "20 bit"; break;
case PCI_BASE_ADDRESS_MEM_TYPE_64:
type = "64 bit";
/* read top 32 bit address of base addr: */
reg += 4;
pcibios_read_config_dword(bus, devfn, reg, &l);
base |= ((u64) l) << 32;
break;
type = "64 bit"; break;
}
len += sprintf(buf + len,
"\n %srefetchable %s memory at "
......
/*
* $Id: pci.c,v 1.79 1998/04/17 16:25:24 mj Exp $
* $Id: pci.c,v 1.84 1998/05/02 19:22:06 mj Exp $
*
* PCI Bus Services
*
......@@ -68,11 +68,48 @@ pci_find_class(unsigned int class, struct pci_dev *from)
}
int
pci_read_config_byte(struct pci_dev *dev, u8 where, u8 *val)
{
return pcibios_read_config_byte(dev->bus->number, dev->devfn, where, val);
}
int
pci_read_config_word(struct pci_dev *dev, u8 where, u16 *val)
{
return pcibios_read_config_word(dev->bus->number, dev->devfn, where, val);
}
int
pci_read_config_dword(struct pci_dev *dev, u8 where, u32 *val)
{
return pcibios_read_config_dword(dev->bus->number, dev->devfn, where, val);
}
int
pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val)
{
return pcibios_write_config_byte(dev->bus->number, dev->devfn, where, val);
}
int
pci_write_config_word(struct pci_dev *dev, u8 where, u16 val)
{
return pcibios_write_config_word(dev->bus->number, dev->devfn, where, val);
}
int
pci_write_config_dword(struct pci_dev *dev, u8 where, u32 val)
{
return pcibios_write_config_dword(dev->bus->number, dev->devfn, where, val);
}
void
pci_set_master(struct pci_dev *dev)
{
unsigned short cmd;
unsigned char lat;
u16 cmd;
u8 lat;
pci_read_config_word(dev, PCI_COMMAND, &cmd);
if (! (cmd & PCI_COMMAND_MASTER)) {
......@@ -89,16 +126,43 @@ pci_set_master(struct pci_dev *dev)
}
}
__initfunc(void pci_read_bases(struct pci_dev *dev, unsigned int howmany))
{
unsigned int reg;
u32 l;
for(reg=0; reg<howmany; reg++) {
pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + (reg << 2), &l);
if (l == 0xffffffff)
continue;
dev->base_address[reg] = l;
if ((l & PCI_MEMORY_RANGE_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
reg++;
pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + (reg << 2), &l);
if (l) {
#if BITS_PER_LONG == 64
dev->base_address[reg-1] |= ((unsigned long) l) << 32;
#else
printk("PCI: Unable to handle 64-bit address for device %02x:%02x\n",
dev->bus->number, dev->devfn);
dev->base_address[reg-1] = 0;
#endif
}
}
}
}
__initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
{
unsigned int devfn, l, max, class;
unsigned char cmd, irq, tmp, hdr_type, is_multi = 0;
struct pci_dev *dev;
struct pci_dev *dev, **bus_last;
struct pci_bus *child;
int reg;
DBG("pci_scan_bus for bus %d\n", bus->number);
bus_last = &bus->devices;
max = bus->secondary;
for (devfn = 0; devfn < 0xff; ++devfn) {
if (PCI_FUNC(devfn) && !is_multi) {
......@@ -111,8 +175,8 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
pcibios_read_config_dword(bus->number, devfn, PCI_VENDOR_ID, &l);
/* some broken boards return 0 if a slot is empty: */
if (l == 0xffffffff || l == 0x00000000) {
hdr_type = 0;
if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000) {
is_multi = 0;
continue;
}
......@@ -133,11 +197,12 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
pcibios_read_config_dword(bus->number, devfn, PCI_CLASS_REVISION, &class);
class >>= 8; /* upper 3 bytes */
dev->class = class;
class >>= 8;
dev->hdr_type = hdr_type;
switch (hdr_type & 0x7f) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */
if (class >> 8 == PCI_CLASS_BRIDGE_PCI)
if (class == PCI_CLASS_BRIDGE_PCI)
goto bad;
/*
* If the card generates interrupts, read IRQ number
......@@ -151,25 +216,19 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
* read base address registers, again pcibios_fixup() can
* tweak these
*/
for (reg = 0; reg < 6; reg++) {
pcibios_read_config_dword(bus->number, devfn, PCI_BASE_ADDRESS_0 + (reg << 2), &l);
dev->base_address[reg] = (l == 0xffffffff) ? 0 : l;
}
pci_read_bases(dev, 6);
pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS, &l);
dev->rom_address = (l == 0xffffffff) ? 0 : l;
break;
case PCI_HEADER_TYPE_BRIDGE: /* bridge header */
if (class >> 8 != PCI_CLASS_BRIDGE_PCI)
if (class != PCI_CLASS_BRIDGE_PCI)
goto bad;
for (reg = 0; reg < 2; reg++) {
pcibios_read_config_dword(bus->number, devfn, PCI_BASE_ADDRESS_0 + (reg << 2), &l);
dev->base_address[reg] = (l == 0xffffffff) ? 0 : l;
}
pci_read_bases(dev, 2);
pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS1, &l);
dev->rom_address = (l == 0xffffffff) ? 0 : l;
break;
case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */
if (class >> 16 != PCI_BASE_CLASS_BRIDGE)
if (class != PCI_CLASS_BRIDGE_CARDBUS)
goto bad;
for (reg = 0; reg < 2; reg++) {
pcibios_read_config_dword(bus->number, devfn, PCI_CB_MEMORY_BASE_0 + (reg << 3), &l);
......@@ -201,8 +260,8 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
* Now insert it into the list of devices held
* by the parent bus.
*/
dev->sibling = bus->devices;
bus->devices = dev;
*bus_last = dev;
bus_last = &dev->sibling;
#if 0
/*
......@@ -217,7 +276,7 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
/*
* If it's a bridge, scan the bus behind it.
*/
if (class >> 8 == PCI_CLASS_BRIDGE_PCI) {
if (class == PCI_CLASS_BRIDGE_PCI) {
unsigned int buses;
unsigned short cr;
......
/*
* $Id: pcisyms.c,v 1.4 1998/04/17 16:34:19 mj Exp $
* $Id: pcisyms.c,v 1.7 1998/05/02 19:20:06 mj Exp $
*
* PCI Bus Services -- Exported Symbols
*
......@@ -16,6 +16,12 @@ EXPORT_SYMBOL(pcibios_read_config_dword);
EXPORT_SYMBOL(pcibios_write_config_byte);
EXPORT_SYMBOL(pcibios_write_config_word);
EXPORT_SYMBOL(pcibios_write_config_dword);
EXPORT_SYMBOL(pci_read_config_byte);
EXPORT_SYMBOL(pci_read_config_word);
EXPORT_SYMBOL(pci_read_config_dword);
EXPORT_SYMBOL(pci_write_config_byte);
EXPORT_SYMBOL(pci_write_config_word);
EXPORT_SYMBOL(pci_write_config_dword);
EXPORT_SYMBOL(pci_devices);
EXPORT_SYMBOL(pci_root);
EXPORT_SYMBOL(pci_find_class);
......
/*
* $Id: quirks.c,v 1.3 1998/02/06 19:51:42 mj Exp $
* $Id: quirks.c,v 1.5 1998/05/02 19:24:14 mj Exp $
*
* PCI Chipset-Specific Quirks
*
......@@ -7,8 +7,7 @@
*
* This is the right place for all special fixups for on-board
* devices not depending on system architecture -- for example
* bus bridges. The only thing implemented in this release is
* the bridge optimization, but others might appear later.
* bus bridges.
*/
#include <linux/config.h>
......@@ -88,21 +87,19 @@ __initfunc(static void quirk_bridge(struct pci_dev *dev, int pos))
printk(" %s: ", bridge_optimization[i].type);
bmap = &bridge_mapping[pos + i];
if (!bmap->addr) {
printk("Not supported.");
printk("Not supported.\n");
} else {
pcibios_read_config_byte(dev->bus->number, dev->devfn, bmap->addr, &val);
pci_read_config_byte(dev, bmap->addr, &val);
if ((val & bmap->mask) == bmap->value)
printk("%s.", bridge_optimization[i].on);
printk("%s.\n", bridge_optimization[i].on);
else {
printk("%s.", bridge_optimization[i].off);
pcibios_write_config_byte(dev->bus->number, dev->devfn,
bmap->addr,
(val & (0xff - bmap->mask))
+ bmap->value);
printk("Changed! Now %s.", bridge_optimization[i].on);
printk("%s", bridge_optimization[i].off);
pci_write_config_byte(dev,
bmap->addr,
(val & (0xff - bmap->mask)) + bmap->value);
printk(" -> %s.\n", bridge_optimization[i].on);
}
}
printk("\n");
}
}
......@@ -113,27 +110,18 @@ __initfunc(static void quirk_bridge(struct pci_dev *dev, int pos))
which can cause problems in combination with the 82441FX/PPro MTRRs */
__initfunc(static void quirk_passive_release(struct pci_dev *dev, int arg))
{
struct pci_dev *piix3;
struct pci_dev *d = NULL;
unsigned char dlc;
/* We have to make sure a particular bit is set in the PIIX3
ISA bridge, so we have to go out and find it. */
for (piix3 = pci_devices; ; piix3 = piix3->next) {
if (!piix3)
return;
if (piix3->vendor == PCI_VENDOR_ID_INTEL
&& piix3->device == PCI_DEVICE_ID_INTEL_82371SB_0)
break;
}
pcibios_read_config_byte(piix3->bus->number, piix3->devfn, 0x82, &dlc);
if (!(dlc & 1<<1)) {
printk("PIIX3: Enabling Passive Release\n");
dlc |= 1<<1;
pcibios_write_config_byte(piix3->bus->number, piix3->devfn,
0x82, dlc);
while ((d = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
pci_read_config_byte(d, 0x82, &dlc);
if (!(dlc & 1<<1)) {
printk("PIIX3: Enabling Passive Release\n");
dlc |= 1<<1;
pci_write_config_byte(d, 0x82, dlc);
}
}
}
......@@ -141,7 +129,7 @@ __initfunc(static void quirk_passive_release(struct pci_dev *dev, int arg))
typedef void (*quirk_handler)(struct pci_dev *, int);
/*
* Mpping from quirk handler functions to names.
* Mapping from quirk handler functions to names.
*/
struct quirk_name {
......@@ -185,6 +173,7 @@ static struct quirk_info quirk_list[] __initdata = {
{ PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8891A, quirk_bridge, 0x01 },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424, quirk_bridge, 0x00 },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82434, quirk_bridge, 0x00 },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82430, quirk_bridge, 0x00 },
#endif
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release, 0x00 },
};
......
......@@ -260,7 +260,7 @@ static void idescsi_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
struct request *rq = hwgroup->rq;
idescsi_pc_t *pc = (idescsi_pc_t *) rq->buffer;
int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
u8 *scsi_buf = pc->scsi_cmd->request_buffer;
u8 *scsi_buf;
if (rq->cmd != IDESCSI_PC_RQ) {
ide_end_request (uptodate, hwgroup);
......@@ -282,6 +282,7 @@ static void idescsi_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
printk ("ide-scsi: %s: suc %lu", drive->name, pc->scsi_cmd->serial_number);
if (!test_bit(PC_WRITING, &pc->flags) && pc->actually_transferred && pc->actually_transferred <= 1024 && pc->buffer) {
printk(", rst = ");
scsi_buf = pc->scsi_cmd->request_buffer;
hexdump(scsi_buf, IDE_MIN(16, pc->scsi_cmd->request_bufflen));
} else printk("\n");
}
......@@ -345,7 +346,18 @@ static void idescsi_pc_intr (ide_drive_t *drive)
if ( temp > pc->request_transfer) {
if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-scsi: The scsi wants to send us more data than expected - discarding data\n");
idescsi_discard_data (drive,bcount);
temp = pc->buffer_size - pc->actually_transferred;
if (temp) {
clear_bit(PC_WRITING, &pc->flags);
if (pc->sg)
idescsi_input_buffers(drive, pc, temp);
else
atapi_input_bytes(drive, pc->current_position, temp);
printk(KERN_ERR "ide-scsi: transferred %d of %d bytes\n", temp, bcount);
}
pc->actually_transferred += temp;
pc->current_position += temp;
idescsi_discard_data (drive,bcount - temp);
ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc));
return;
}
......
......@@ -1605,6 +1605,7 @@ void scsi_bottom_half_handler(void)
if( SCpnt == NULL )
return;
spin_lock_irqsave(&io_request_lock, flags);
atomic_inc(&recursion_depth);
SCnext = SCpnt->bh_next;
......@@ -1696,6 +1697,7 @@ void scsi_bottom_half_handler(void)
} /* for(; SCpnt...) */
atomic_dec(&recursion_depth);
spin_unlock_irqrestore(&io_request_lock, flags);
} /* while(1==1) */
......
......@@ -159,7 +159,7 @@ scsi_delete_timer(Scsi_Cmnd * SCset)
*
* Notes:
*/
void scsi_times_out (Scsi_Cmnd * SCpnt)
static void do_scsi_times_out (Scsi_Cmnd * SCpnt)
{
/*
......@@ -222,6 +222,15 @@ void scsi_times_out (Scsi_Cmnd * SCpnt)
}
}
void scsi_times_out (Scsi_Cmnd * SCpnt)
{
unsigned long flags;
spin_lock_irqsave(&io_request_lock, flags);
do_scsi_times_out(SCpnt);
spin_unlock_irqrestore(&io_request_lock, flags);
}
/*
* Function scsi_block_when_processing_errors
*
......@@ -264,6 +273,9 @@ scsi_block_when_processing_errors(Scsi_Device * SDpnt)
STATIC
void scsi_eh_times_out (Scsi_Cmnd * SCpnt)
{
unsigned long flags;
spin_lock_irqsave(&io_request_lock, flags);
SCpnt->request.rq_status = RQ_SCSI_DONE;
SCpnt->owner = SCSI_OWNER_ERROR_HANDLER;
SCpnt->eh_state = SCSI_STATE_TIMEOUT;
......@@ -273,7 +285,8 @@ void scsi_eh_times_out (Scsi_Cmnd * SCpnt)
if (SCpnt->host->eh_action != NULL)
up(SCpnt->host->eh_action);
else
panic("Missing scsi error handler thread");
printk("Missing scsi error handler thread\n");
spin_unlock_irqrestore(&io_request_lock, flags);
}
......@@ -446,6 +459,11 @@ scsi_test_unit_ready(Scsi_Cmnd * SCpnt)
return SCpnt->eh_state;
}
/*
* This would normally need to get the IO request lock,
* but as it doesn't actually touch anything that needs
* to be locked we can avoid the lock here..
*/
STATIC
void scsi_sleep_done (struct semaphore * sem)
{
......
......@@ -65,6 +65,7 @@ EXPORT_SYMBOL(scsi_release_command);
EXPORT_SYMBOL(print_Scsi_Cmnd);
EXPORT_SYMBOL(scsi_block_when_processing_errors);
EXPORT_SYMBOL(scsi_mark_host_reset);
EXPORT_SYMBOL(scsi_ioctl_send_command);
#if defined(CONFIG_SCSI_LOGGING) /* { */
EXPORT_SYMBOL(scsi_logging_level);
#endif
......
......@@ -106,8 +106,8 @@ int sr_do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned bufl
break;
case ILLEGAL_REQUEST:
if (!quiet)
printk("sr%d: CDROM (ioctl) reports ILLEGAL REQUEST.\n",
target);
printk(KERN_ERR "sr%d: CDROM (ioctl) reports ILLEGAL "
"REQUEST.\n", target);
if (SCpnt->sense_buffer[12] == 0x20 &&
SCpnt->sense_buffer[13] == 0x00) {
/* sense: Invalid command operation code */
......@@ -121,7 +121,7 @@ int sr_do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned bufl
#endif
break;
default:
printk("sr%d: CDROM (ioctl) error, command: ", target);
printk(KERN_ERR "sr%d: CDROM (ioctl) error, command: ", target);
print_command(sr_cmd);
print_sense("sr", SCpnt);
err = -EIO;
......
......@@ -26,6 +26,7 @@ EXPORT_SYMBOL(num_audiodevs);
EXPORT_SYMBOL(note_to_freq);
EXPORT_SYMBOL(compute_finetune);
EXPORT_SYMBOL(seq_copy_to_input);
EXPORT_SYMBOL(seq_input_event);
EXPORT_SYMBOL(sequencer_init);
EXPORT_SYMBOL(sequencer_timer);
......@@ -61,6 +62,7 @@ EXPORT_SYMBOL(conf_printf2);
EXPORT_SYMBOL(sound_timer_init);
EXPORT_SYMBOL(sound_timer_interrupt);
EXPORT_SYMBOL(sound_timer_syncinterval);
EXPORT_SYMBOL(sound_timer_devs);
/* Locking */
EXPORT_SYMBOL(sound_locker);
......
......@@ -970,7 +970,7 @@ void cleanup_module(void)
if (mss)
unload_ss_ms_sound(&config);
SOUND_LOCK_END;
unload_sscape(&config);
unload_sscape(&mpu_config);
}
#endif
......
......@@ -4,7 +4,7 @@
O_TARGET := coda.o
O_OBJS := psdev.o cache.o cnode.o inode.o dir.o file.o upcall.o coda_linux.o\
symlink.o pioctl.o sysctl.o
symlink.o pioctl.o sysctl.o stats.o
M_OBJS := $(O_TARGET)
# If you want debugging output, please uncomment the following line
......
......@@ -32,9 +32,6 @@ static void coda_cache_create(struct inode *inode, int mask);
static struct coda_cache * coda_cache_find(struct inode *inode);
/* Keep various stats */
struct cfsnc_statistics cfsnc_stat;
/* insert a acl-cache entry in sb list */
static void coda_ccinsert(struct coda_cache *el, struct super_block *sb)
{
......@@ -295,41 +292,3 @@ void coda_flag_inode(struct inode *inode, int flag)
int
cfsnc_nc_info(char *buffer, char **start, off_t offset, int length, int dummy)
{
int len=0;
off_t begin;
/* cfsnc_gather_stats(); */
/* this works as long as we are below 1024 characters! */
len += sprintf(buffer,"Coda minicache statistics\n\n");
len += sprintf(buffer+len, "cfsnc_hits : %d\n", cfsnc_stat.hits);
len += sprintf(buffer+len, "cfsnc_misses : %d\n", cfsnc_stat.misses);
len += sprintf(buffer+len, "cfsnc_enters : %d\n", cfsnc_stat.enters);
len += sprintf(buffer+len, "cfsnc_dbl_enters : %d\n", cfsnc_stat.dbl_enters);
len += sprintf(buffer+len, "cfsnc_long_name_enters : %d\n", cfsnc_stat.long_name_enters);
len += sprintf(buffer+len, "cfsnc_long_name_lookups : %d\n", cfsnc_stat.long_name_lookups);
len += sprintf(buffer+len, "cfsnc_long_remove : %d\n", cfsnc_stat.long_remove);
len += sprintf(buffer+len, "cfsnc_lru_rm : %d\n", cfsnc_stat.lru_rm);
len += sprintf(buffer+len, "cfsnc_zapPfids : %d\n", cfsnc_stat.zapPfids);
len += sprintf(buffer+len, "cfsnc_zapFids : %d\n", cfsnc_stat.zapFids);
len += sprintf(buffer+len, "cfsnc_zapFile : %d\n", cfsnc_stat.zapFile);
len += sprintf(buffer+len, "cfsnc_zapUsers : %d\n", cfsnc_stat.zapUsers);
len += sprintf(buffer+len, "cfsnc_Flushes : %d\n", cfsnc_stat.Flushes);
len += sprintf(buffer+len, "cfsnc_SumLen : %d\n", cfsnc_stat.Sum_bucket_len);
len += sprintf(buffer+len, "cfsnc_Sum2Len : %d\n", cfsnc_stat.Sum2_bucket_len);
len += sprintf(buffer+len, "cfsnc_# 0 len : %d\n", cfsnc_stat.Num_zero_len);
len += sprintf(buffer+len, "cfsnc_MaxLen : %d\n", cfsnc_stat.Max_bucket_len);
len += sprintf(buffer+len, "cfsnc_SearchLen : %d\n", cfsnc_stat.Search_len);
begin = offset;
*start = buffer + begin;
len -= begin;
if(len>length)
len = length;
if (len< 0)
len = 0;
return len;
}
......@@ -7,6 +7,7 @@
* the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
*/
#include <linux/version.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
......
......@@ -23,6 +23,7 @@
#include <linux/coda_psdev.h>
#include <linux/coda_fs_i.h>
#include <linux/coda_cache.h>
#include <linux/coda_proc.h>
/* dir inode-ops */
static int coda_create(struct inode *dir, struct dentry *new, int mode);
......@@ -179,6 +180,8 @@ int coda_permission(struct inode *inode, int mask)
int error;
ENTRY;
coda_vfs_stat.permission++;
coda_permission_stat.count++;
if ( mask == 0 ) {
EXIT;
......@@ -187,6 +190,7 @@ int coda_permission(struct inode *inode, int mask)
if ( coda_access_cache == 1 ) {
if ( coda_cache_check(inode, mask) ) {
coda_permission_stat.hit_count++;
return 0;
}
}
......@@ -221,6 +225,8 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode)
struct ViceFid newfid;
struct coda_vattr attrs;
coda_vfs_stat.create++;
CDEBUG(D_INODE, "name: %s, length %d, mode %o\n",name, length, mode);
if (!dir || !S_ISDIR(dir->i_mode)) {
......@@ -274,6 +280,8 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
struct ViceFid newfid;
coda_vfs_stat.mkdir++;
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("coda_mkdir: inode is NULL or not a directory\n");
return -ENOENT;
......@@ -329,6 +337,7 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
int error;
ENTRY;
coda_vfs_stat.link++;
if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
return -EPERM;
......@@ -373,6 +382,7 @@ static int coda_symlink(struct inode *dir_inode, struct dentry *de,
int error=0;
ENTRY;
coda_vfs_stat.symlink++;
if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
return -EPERM;
......@@ -414,6 +424,7 @@ int coda_unlink(struct inode *dir, struct dentry *de)
int len = de->d_name.len;
ENTRY;
coda_vfs_stat.unlink++;
dircnp = ITOC(dir);
CHECK_CNODE(dircnp);
......@@ -446,6 +457,8 @@ int coda_rmdir(struct inode *dir, struct dentry *de)
int len = de->d_name.len;
int error, rehash = 0;
coda_vfs_stat.rmdir++;
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("coda_rmdir: inode is NULL or not a directory\n");
return -ENOENT;
......@@ -502,6 +515,8 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
struct coda_inode_info *new_cnp, *old_cnp;
int error, rehash = 0, update = 1;
ENTRY;
coda_vfs_stat.rename++;
old_cnp = ITOC(old_dir);
CHECK_CNODE(old_cnp);
new_cnp = ITOC(new_dir);
......@@ -565,6 +580,7 @@ int coda_readdir(struct file *file, void *dirent, filldir_t filldir)
struct inode *inode=file->f_dentry->d_inode;
ENTRY;
coda_vfs_stat.readdir++;
if (!inode || !inode->i_sb || !S_ISDIR(inode->i_mode)) {
printk("coda_readdir: inode is NULL or not a directory\n");
......@@ -606,6 +622,7 @@ int coda_open(struct inode *i, struct file *f)
unsigned short coda_flags = coda_flags_to_cflags(flags);
ENTRY;
coda_vfs_stat.open++;
CDEBUG(D_SPECIAL, "OPEN inode number: %ld, flags %o.\n",
f->f_dentry->d_inode->i_ino, flags);
......@@ -659,6 +676,7 @@ int coda_release(struct inode *i, struct file *f)
unsigned short cflags = coda_flags_to_cflags(flags);
ENTRY;
coda_vfs_stat.release++;
cnp =ITOC(i);
CHECK_CNODE(cnp);
......
......@@ -23,6 +23,7 @@
#include <linux/coda_fs_i.h>
#include <linux/coda_psdev.h>
#include <linux/coda_cache.h>
#include <linux/coda_proc.h>
/* file operations */
static int coda_readpage(struct file *file, struct page * page);
......@@ -83,6 +84,7 @@ static int coda_readpage(struct file * coda_file, struct page * page)
struct coda_inode_info *cii;
ENTRY;
coda_vfs_stat.readpage++;
cii = ITOC(coda_inode);
......@@ -108,6 +110,8 @@ static int coda_file_mmap(struct file * file, struct vm_area_struct * vma)
struct coda_inode_info *cii;
int res;
coda_vfs_stat.file_mmap++;
ENTRY;
cii = ITOC(file->f_dentry->d_inode);
cii->c_mmcount++;
......@@ -126,7 +130,9 @@ static ssize_t coda_file_read(struct file *coda_file, char *buff,
struct file cont_file;
struct dentry cont_dentry;
int result = 0;
ENTRY;
ENTRY;
coda_vfs_stat.file_read++;
cnp = ITOC(coda_inode);
CHECK_CNODE(cnp);
......@@ -167,6 +173,7 @@ static ssize_t coda_file_write(struct file *coda_file, const char *buff,
int result = 0;
ENTRY;
coda_vfs_stat.file_write++;
cnp = ITOC(coda_inode);
CHECK_CNODE(cnp);
......@@ -205,6 +212,7 @@ int coda_fsync(struct file *coda_file, struct dentry *coda_dentry)
struct dentry cont_dentry;
int result = 0;
ENTRY;
coda_vfs_stat.fsync++;
if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) ||
S_ISLNK(coda_inode->i_mode)))
......
......@@ -44,7 +44,7 @@
#include <linux/coda_fs_i.h>
#include <linux/coda_psdev.h>
#include <linux/coda_cache.h>
#include <linux/coda_sysctl.h>
#include <linux/coda_proc.h>
/*
......@@ -401,19 +401,106 @@ static struct file_operations coda_psdev_fops = {
#ifdef CONFIG_PROC_FS
struct proc_dir_entry proc_coda = {
struct proc_dir_entry proc_sys_root = {
PROC_SYS, 3, "sys", /* inode, name */
S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, /* mode, nlink, uid, gid */
0, &proc_dir_inode_operations, /* size, ops */
NULL, NULL, /* get_info, fill_inode */
NULL, /* next */
NULL, NULL /* parent, subdir */
};
struct proc_dir_entry proc_fs_coda = {
PROC_FS_CODA, 4, "coda",
S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
0, &proc_dir_inode_operations,
NULL, NULL,
NULL,
NULL, NULL
};
struct proc_dir_entry proc_sys_coda = {
0, 4, "coda",
S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR, 2, 0, 0,
0, &proc_net_inode_operations,
S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
0, &proc_dir_inode_operations,
NULL, NULL,
NULL,
NULL, NULL
};
struct proc_dir_entry proc_fs = {
PROC_FS, 2, "fs",
S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
0, &proc_dir_inode_operations,
NULL, NULL,
NULL,
NULL, NULL
};
#if 0
struct proc_dir_entry proc_coda_ncstats = {
0 , 12, "coda-ncstats",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
cfsnc_nc_info
};
#endif
struct proc_dir_entry proc_coda_vfs = {
PROC_VFS_STATS , 9, "vfs_stats",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
coda_vfs_stats_get_info
};
struct proc_dir_entry proc_coda_vfs_control = {
0 , 9, "vfs_stats",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
coda_vfs_stats_get_info
};
struct proc_dir_entry proc_coda_upcall = {
PROC_UPCALL_STATS , 12, "upcall_stats",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
coda_upcall_stats_get_info
};
struct proc_dir_entry proc_coda_upcall_control = {
0 , 12, "upcall_stats",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
coda_upcall_stats_get_info
};
struct proc_dir_entry proc_coda_permission = {
PROC_PERMISSION_STATS , 16, "permission_stats",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
coda_permission_stats_get_info
};
struct proc_dir_entry proc_coda_permission_control = {
0 , 16, "permission_stats",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
coda_permission_stats_get_info
};
struct proc_dir_entry proc_coda_cache_inv = {
PROC_CACHE_INV_STATS , 15, "cache_inv_stats",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
coda_cache_inv_stats_get_info
};
struct proc_dir_entry proc_coda_cache_inv_control = {
0 , 15, "cache_inv_stats",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
coda_cache_inv_stats_get_info
};
#endif
......@@ -429,9 +516,27 @@ int init_coda_psdev(void)
memset(coda_super_info, 0, sizeof(coda_super_info));
memset(&coda_callstats, 0, sizeof(coda_callstats));
reset_coda_vfs_stats();
reset_coda_upcall_stats();
reset_coda_permission_stats();
reset_coda_cache_inv_stats();
#ifdef CONFIG_PROC_FS
proc_register(&proc_root,&proc_coda);
proc_register(&proc_coda, &proc_coda_ncstats);
proc_register(&proc_root,&proc_fs);
proc_register(&proc_fs,&proc_fs_coda);
proc_register(&proc_fs_coda,&proc_coda_vfs);
proc_register(&proc_fs_coda,&proc_coda_upcall);
proc_register(&proc_fs_coda,&proc_coda_permission);
proc_register(&proc_fs_coda,&proc_coda_cache_inv);
#if 0
proc_register(&proc_fs_coda, &proc_coda_ncstats);
#endif
proc_register(&proc_sys_root,&proc_sys_coda);
proc_register(&proc_sys_coda,&proc_coda_vfs_control);
proc_register(&proc_sys_coda,&proc_coda_upcall_control);
proc_register(&proc_sys_coda,&proc_coda_permission_control);
proc_register(&proc_sys_coda,&proc_coda_cache_inv_control);
coda_sysctl_init();
#endif
return 0;
......@@ -476,8 +581,22 @@ void cleanup_module(void)
#if CONFIG_PROC_FS
coda_sysctl_clean();
proc_unregister(&proc_coda, proc_coda_ncstats.low_ino);
proc_unregister(&proc_root, proc_coda.low_ino);
proc_unregister(&proc_sys_coda, proc_coda_cache_inv_control.low_ino);
proc_unregister(&proc_sys_coda, proc_coda_permission_control.low_ino);
proc_unregister(&proc_sys_coda, proc_coda_upcall_control.low_ino);
proc_unregister(&proc_sys_coda,proc_coda_vfs_control.low_ino);
proc_unregister(&proc_sys_root, proc_sys_coda.low_ino);
#if 0
proc_unregister(&proc_fs_coda, proc_coda_ncstats.low_ino);
#endif
proc_unregister(&proc_fs_coda, proc_coda_cache_inv.low_ino);
proc_unregister(&proc_fs_coda, proc_coda_permission.low_ino);
proc_unregister(&proc_fs_coda, proc_coda_upcall.low_ino);
proc_unregister(&proc_fs_coda, proc_coda_vfs.low_ino);
proc_unregister(&proc_fs, proc_fs_coda.low_ino);
proc_unregister(&proc_root, proc_fs.low_ino);
#endif
}
......
/*
* stats.c
*
* CODA operation statistics
*
* (c) March, 1998 Zhanyong Wan <zhanyong.wan@yale.edu>
*
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/sysctl.h>
#include <linux/swapctl.h>
#include <linux/proc_fs.h>
#include <linux/malloc.h>
#include <linux/stat.h>
#include <linux/ctype.h>
#include <asm/bitops.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/utsname.h>
#include <linux/coda.h>
#include <linux/coda_linux.h>
#include <linux/coda_fs_i.h>
#include <linux/coda_psdev.h>
#include <linux/coda_cache.h>
#include <linux/coda_proc.h>
struct coda_vfs_stats coda_vfs_stat;
struct coda_permission_stats coda_permission_stat;
struct coda_cache_inv_stats coda_cache_inv_stat;
struct coda_upcall_stats_entry coda_upcall_stat[CFS_NCALLS];
/* keep this in sync with coda.h! */
char *coda_upcall_names[] = {
"totals ", /* 0 */
"noop ", /* 1 */
"root ", /* 2 */
"sync ", /* 3 */
"open ", /* 4 */
"close ", /* 5 */
"ioctl ", /* 6 */
"getattr ", /* 7 */
"setattr ", /* 8 */
"access ", /* 9 */
"lookup ", /* 10 */
"create ", /* 11 */
"remove ", /* 12 */
"link ", /* 13 */
"rename ", /* 14 */
"mkdir ", /* 15 */
"rmdir ", /* 16 */
"readdir ", /* 17 */
"symlink ", /* 18 */
"readlink ", /* 19 */
"fsync ", /* 20 */
"inactive ", /* 21 */
"vget ", /* 22 */
"signal ", /* 23 */
"replace ", /* 24 */
"flush ", /* 25 */
"purgeuser ", /* 26 */
"zapfile ", /* 27 */
"zapdir ", /* 28 */
"zapvnode ", /* 28 */
"purgefid ", /* 30 */
"open_by_path" /* 31 */
};
void reset_coda_vfs_stats( void )
{
memset( &coda_vfs_stat, 0, sizeof( coda_vfs_stat ) );
}
#if 0
static void reset_upcall_entry( struct coda_upcall_stats_entry * pentry )
{
pentry->count = 0;
pentry->time_sum = pentry->time_squared_sum = 0;
}
#endif
void reset_coda_upcall_stats( void )
{
memset( &coda_upcall_stat, 0, sizeof( coda_upcall_stat ) );
}
void reset_coda_permission_stats( void )
{
memset( &coda_permission_stat, 0, sizeof( coda_permission_stat ) );
}
void reset_coda_cache_inv_stats( void )
{
memset( &coda_cache_inv_stat, 0, sizeof( coda_cache_inv_stat ) );
}
void do_time_stats( struct coda_upcall_stats_entry * pentry,
unsigned long runtime )
{
unsigned long time = runtime * 1000 /HZ; /* time in ms */
CDEBUG(D_SPECIAL, "time: %ld\n", time);
if ( pentry->count == 0 ) {
pentry->time_sum = pentry->time_squared_sum = 0;
}
pentry->count++;
pentry->time_sum += time;
pentry->time_squared_sum += time*time;
}
void coda_upcall_stats(int opcode, long unsigned runtime)
{
struct coda_upcall_stats_entry * pentry;
if ( opcode < 0 || opcode > CFS_NCALLS - 1) {
printk("Nasty opcode %d passed to coda_upcall_stats\n",
opcode);
return;
}
pentry = &coda_upcall_stat[opcode];
do_time_stats(pentry, runtime);
/* fill in the totals */
pentry = &coda_upcall_stat[0];
do_time_stats(pentry, runtime);
}
unsigned long get_time_average( const struct coda_upcall_stats_entry * pentry )
{
return ( pentry->count == 0 ) ? 0 : pentry->time_sum / pentry->count;
}
static inline unsigned long absolute( unsigned long x )
{
return x >= 0 ? x : -x;
}
static unsigned long sqr_root( unsigned long x )
{
unsigned long y = x, r;
int n_bit = 0;
if ( x == 0 )
return 0;
if ( x < 0)
x = -x;
while ( y ) {
y >>= 1;
n_bit++;
}
r = 1 << (n_bit/2);
while ( 1 ) {
r = (r + x/r)/2;
if ( r*r <= x && x < (r+1)*(r+1) )
break;
}
return r;
}
unsigned long get_time_std_deviation( const struct coda_upcall_stats_entry * pentry )
{
unsigned long time_avg;
if ( pentry->count <= 1 )
return 0;
time_avg = get_time_average( pentry );
return
sqr_root( (pentry->time_squared_sum / pentry->count) -
time_avg * time_avg );
}
int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
void * buffer, size_t * lenp )
{
if ( write ) {
reset_coda_vfs_stats();
}
*lenp = 0;
return 0;
}
int do_reset_coda_upcall_stats( ctl_table * table, int write,
struct file * filp, void * buffer,
size_t * lenp )
{
if ( write ) {
reset_coda_upcall_stats();
}
*lenp = 0;
return 0;
}
int do_reset_coda_permission_stats( ctl_table * table, int write,
struct file * filp, void * buffer,
size_t * lenp )
{
if ( write ) {
reset_coda_permission_stats();
}
*lenp = 0;
return 0;
}
int do_reset_coda_cache_inv_stats( ctl_table * table, int write,
struct file * filp, void * buffer,
size_t * lenp )
{
if ( write ) {
reset_coda_cache_inv_stats();
}
*lenp = 0;
return 0;
}
int coda_vfs_stats_get_info( char * buffer, char ** start, off_t offset,
int length, int dummy )
{
int len=0;
off_t begin;
struct coda_vfs_stats * ps = & coda_vfs_stat;
/* this works as long as we are below 1024 characters! */
len += sprintf( buffer,
"Coda VFS statistics\n"
"===================\n\n"
"File Operations:\n"
"\tfile_read\t%9d\n"
"\tfile_write\t%9d\n"
"\tfile_mmap\t%9d\n"
"\topen\t\t%9d\n"
"\trelase\t\t%9d\n"
"\tfsync\t\t%9d\n\n"
"Dir Operations:\n"
"\treaddir\t\t%9d\n\n"
"Inode Operations\n"
"\tcreate\t\t%9d\n"
"\tlookup\t\t%9d\n"
"\tlink\t\t%9d\n"
"\tunlink\t\t%9d\n"
"\tsymlink\t\t%9d\n"
"\tmkdir\t\t%9d\n"
"\trmdir\t\t%9d\n"
"\trename\t\t%9d\n"
"\tpermission\t%9d\n"
"\treadpage\t%9d\n",
/* file operations */
ps->file_read,
ps->file_write,
ps->file_mmap,
ps->open,
ps->release,
ps->fsync,
/* dir operations */
ps->readdir,
/* inode operations */
ps->create,
ps->lookup,
ps->link,
ps->unlink,
ps->symlink,
ps->mkdir,
ps->rmdir,
ps->rename,
ps->permission,
ps->readpage );
begin = offset;
*start = buffer + begin;
len -= begin;
if ( len > length )
len = length;
if ( len < 0 )
len = 0;
return len;
}
int coda_upcall_stats_get_info( char * buffer, char ** start, off_t offset,
int length, int dummy )
{
int len=0;
int i;
off_t begin;
off_t pos = 0;
char tmpbuf[80];
int tmplen = 0;
ENTRY;
/* this works as long as we are below 1024 characters! */
if ( offset < 80 )
len += sprintf( buffer,"%-79s\n", "Coda upcall statistics");
if ( offset < 160)
len += sprintf( buffer + len,"%-79s\n", "======================");
if ( offset < 240)
len += sprintf( buffer + len,"%-79s\n", "upcall\t\t count\tavg time(ms)\tstd deviation(ms)");
if ( offset < 320)
len += sprintf( buffer + len,"%-79s\n", "------\t\t -----\t------------\t-----------------");
pos = 320;
for ( i = 0 ; i < CFS_NCALLS ; i++ ) {
tmplen += sprintf(tmpbuf,"%s\t%9d\t%10ld\t%10ld",
coda_upcall_names[i],
coda_upcall_stat[i].count,
get_time_average(&coda_upcall_stat[i]),
coda_upcall_stat[i].time_squared_sum);
pos += 80;
if ( pos < offset )
continue;
len += sprintf(buffer + len, "%-79s\n", tmpbuf);
if ( len >= length )
break;
}
begin = len- (pos - offset);
*start = buffer + begin;
len -= begin;
if ( len > length )
len = length;
if ( len < 0 )
len = 0;
EXIT;
return len;
}
int coda_permission_stats_get_info( char * buffer, char ** start, off_t offset,
int length, int dummy )
{
int len=0;
off_t begin;
struct coda_permission_stats * ps = & coda_permission_stat;
/* this works as long as we are below 1024 characters! */
len += sprintf( buffer,
"Coda permission statistics\n"
"==========================\n\n"
"count\t\t%9d\n"
"hit count\t%9d\n",
ps->count,
ps->hit_count );
begin = offset;
*start = buffer + begin;
len -= begin;
if ( len > length )
len = length;
if ( len < 0 )
len = 0;
return len;
}
int coda_cache_inv_stats_get_info( char * buffer, char ** start, off_t offset,
int length, int dummy )
{
int len=0;
off_t begin;
struct coda_cache_inv_stats * ps = & coda_cache_inv_stat;
/* this works as long as we are below 1024 characters! */
len += sprintf( buffer,
"Coda cache invalidation statistics\n"
"==================================\n\n"
"flush\t\t%9d\n"
"purge user\t%9d\n"
"zap_dir\t\t%9d\n"
"zap_file\t%9d\n"
"zap_vnode\t%9d\n"
"purge_fid\t%9d\n"
"replace\t\t%9d\n",
ps->flush,
ps->purge_user,
ps->zap_dir,
ps->zap_file,
ps->zap_vnode,
ps->purge_fid,
ps->replace );
begin = offset;
*start = buffer + begin;
len -= begin;
if ( len > length )
len = length;
if ( len < 0 )
len = 0;
return len;
}
......@@ -23,6 +23,7 @@
#include <linux/coda_psdev.h>
#include <linux/coda_fs_i.h>
#include <linux/coda_cache.h>
#include <linux/coda_proc.h>
static int coda_readlink(struct dentry *de, char *buffer, int length);
static struct dentry *coda_follow_link(struct dentry *, struct dentry *);
......@@ -60,7 +61,7 @@ static int coda_readlink(struct dentry *de, char *buffer, int length)
ENTRY;
cp = ITOC(inode);
CHECK_CNODE(cp);
coda_vfs_stat.readlink++;
/* the maximum length we receive is len */
if ( length > CFS_MAXPATHLEN )
......@@ -93,11 +94,11 @@ static struct dentry *coda_follow_link(struct dentry *de,
unsigned int len;
char mem[CFS_MAXPATHLEN];
char *path;
ENTRY;
ENTRY;
CDEBUG(D_INODE, "(%x/%ld)\n", inode->i_dev, inode->i_ino);
cnp = ITOC(inode);
CHECK_CNODE(cnp);
coda_vfs_stat.follow_link++;
len = CFS_MAXPATHLEN;
error = venus_readlink(inode->i_sb, &(cnp->c_fid), mem, &len);
......
......@@ -26,7 +26,7 @@
#include <linux/coda_fs_i.h>
#include <linux/coda_psdev.h>
#include <linux/coda_cache.h>
#include <linux/coda_sysctl.h>
#include <linux/coda_proc.h>
extern int coda_debug;
/* extern int cfsnc_use; */
extern int coda_print_entry;
......@@ -47,6 +47,10 @@ struct ctl_table_header *fs_table_header, *coda_table_header;
#define CODA_TIMEOUT 3 /* timeout on upcalls to become intrble */
#define CODA_MC 4 /* use/do not use the access cache */
#define CODA_HARD 5 /* mount type "hard" or "soft" */
#define CODA_VFS 6 /* vfs statistics */
#define CODA_UPCALL 7 /* upcall statistics */
#define CODA_PERMISSION 8 /* permission statistics */
#define CODA_CACHE_INV 9 /* cache invalidation statistics */
......@@ -56,6 +60,10 @@ static ctl_table coda_table[] = {
{CODA_MC, "accesscache", &coda_access_cache, sizeof(int), 0644, NULL, &coda_dointvec},
{CODA_TIMEOUT, "timeout", &coda_timeout, sizeof(int), 0644, NULL, &coda_dointvec},
{CODA_HARD, "hard", &coda_hard, sizeof(int), 0644, NULL, &coda_dointvec},
{CODA_VFS, "vfs_stats", NULL, 0, 0644, NULL, &do_reset_coda_vfs_stats},
{CODA_UPCALL, "upcall_stats", NULL, 0, 0644, NULL, &do_reset_coda_upcall_stats},
{CODA_PERMISSION, "permission_stats", NULL, 0, 0644, NULL, &do_reset_coda_permission_stats},
{CODA_CACHE_INV, "cache_inv_stats", NULL, 0, 0644, NULL, &do_reset_coda_cache_inv_stats},
{ 0 }
};
......
......@@ -37,6 +37,11 @@
#include <linux/coda_psdev.h>
#include <linux/coda_fs_i.h>
#include <linux/coda_cache.h>
#include <linux/coda_proc.h>
static int coda_upcall(struct coda_sb_info *mntinfo, int inSize, int *outSize,
union inputArgs *buffer);
#define UPARG(op)\
do {\
......@@ -68,10 +73,11 @@ int venus_rootfid(struct super_block *sb, ViceFid *fidp)
union inputArgs *inp;
union outputArgs *outp;
int insize, outsize, error;
ENTRY;
ENTRY;
insize = SIZE(root);
UPARG(CFS_ROOT);
error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
if (error) {
......@@ -92,7 +98,7 @@ int venus_getattr(struct super_block *sb, struct ViceFid *fid,
{
union inputArgs *inp;
union outputArgs *outp;
int insize, outsize, error;
int insize, outsize, error;
ENTRY;
insize = SIZE(getattr);
UPARG(CFS_GETATTR);
......@@ -458,8 +464,8 @@ int venus_symlink(struct super_block *sb, struct ViceFid *fid,
int venus_fsync(struct super_block *sb, struct ViceFid *fid)
{
union inputArgs *inp;
union outputArgs *outp;
int insize, outsize, error;
union outputArgs *outp;
int insize, outsize, error;
insize=SIZE(fsync);
UPARG(CFS_FSYNC);
......@@ -476,8 +482,8 @@ int venus_fsync(struct super_block *sb, struct ViceFid *fid)
int venus_access(struct super_block *sb, struct ViceFid *fid, int mask)
{
union inputArgs *inp;
union outputArgs *outp;
int insize, outsize, error;
union outputArgs *outp;
int insize, outsize, error;
insize = SIZE(access);
UPARG(CFS_ACCESS);
......@@ -497,8 +503,8 @@ int venus_pioctl(struct super_block *sb, struct ViceFid *fid,
unsigned int cmd, struct PioctlData *data)
{
union inputArgs *inp;
union outputArgs *outp;
int insize, outsize, error;
union outputArgs *outp;
int insize, outsize, error;
int iocsize;
insize = VC_MAXMSGSIZE;
......@@ -583,11 +589,13 @@ int venus_pioctl(struct super_block *sb, struct ViceFid *fid,
* reply and return Venus' error, also POSITIVE.
*
*/
static inline void coda_waitfor_upcall(struct vmsg *vmp)
static inline unsigned long coda_waitfor_upcall(struct vmsg *vmp)
{
struct wait_queue wait = { current, NULL };
unsigned long posttime;
vmp->vm_posttime = jiffies;
posttime = jiffies;
add_wait_queue(&vmp->vm_sleep, &wait);
for (;;) {
......@@ -616,13 +624,17 @@ static inline void coda_waitfor_upcall(struct vmsg *vmp)
remove_wait_queue(&vmp->vm_sleep, &wait);
current->state = TASK_RUNNING;
return;
CDEBUG(D_SPECIAL, "posttime: %ld, returned: %ld\n", posttime, jiffies-posttime);
return (jiffies - posttime);
}
int coda_upcall(struct coda_sb_info *sbi, int inSize, int *outSize,
static int coda_upcall(struct coda_sb_info *sbi,
int inSize, int *outSize,
union inputArgs *buffer)
{
unsigned long runtime;
struct vcomm *vcommp;
union outputArgs *out;
struct vmsg *vmp;
......@@ -635,7 +647,6 @@ ENTRY;
}
vcommp = sbi->sbi_vcomm;
clstats(((union inputArgs *)buffer)->ih.opcode);
if (!vcomm_open(vcommp))
return(ENODEV);
......@@ -670,7 +681,8 @@ ENTRY;
* ENODEV. */
/* Go to sleep. Wake up on signals only after the timeout. */
coda_waitfor_upcall(vmp);
runtime = coda_waitfor_upcall(vmp);
coda_upcall_stats(((union inputArgs *)buffer)->ih.opcode, runtime);
CDEBUG(D_TIMING, "opc: %d time: %ld uniq: %d size: %d\n",
vmp->vm_opcode, jiffies - vmp->vm_posttime,
......
......@@ -109,7 +109,11 @@ extern inline void get_mmu_context(struct task_struct *p)
#endif
}
#define init_new_context(mm) do { } while(0)
extern inline void init_new_context(struct mm_struct *mm)
{
mm->context = 0;
}
#define destroy_context(mm) do { } while(0)
#endif
......
/*
* coda_statis.h
*
* CODA operation statistics
*
* (c) March, 1998
* by Michihiro Kuramochi, Zhenyu Xia and Zhanyong Wan
* zhanyong.wan@yale.edu
*
*/
#ifndef _CODA_PROC_H
#define _CODA_PROC_H
void coda_sysctl_init(void);
void coda_sysctl_clean(void);
void coda_upcall_stats(int opcode, unsigned long jiffies);
#include <linux/sysctl.h>
#include <linux/coda_fs_i.h>
#include <linux/coda.h>
/* these four files are presented to show the result of the statistics:
*
* /proc/fs/coda/vfs_stats
* upcall_stats
* permission_stats
* cache_inv_stats
*
* these four files are presented to reset the statistics to 0:
*
* /proc/sys/coda/vfs_stats
* upcall_stats
* permission_stats
* cache_inv_stats
*/
/* VFS operation statistics */
struct coda_vfs_stats
{
/* file operations */
int file_read;
int file_write;
int file_mmap;
int open;
int release;
int fsync;
/* dir operations */
int readdir;
/* inode operations */
int create;
int lookup;
int link;
int unlink;
int symlink;
int mkdir;
int rmdir;
int rename;
int permission;
int readpage;
/* symlink operatoins*/
int follow_link;
int readlink;
};
struct coda_upcall_stats_entry
{
int count;
unsigned long time_sum;
unsigned long time_squared_sum;
};
/* cache hits for permissions statistics */
struct coda_permission_stats
{
int count;
int hit_count;
};
/* cache invalidation statistics */
struct coda_cache_inv_stats
{
int flush;
int purge_user;
int zap_dir;
int zap_file;
int zap_vnode;
int purge_fid;
int replace;
};
/* these global variables hold the actual statistics data */
extern struct coda_vfs_stats coda_vfs_stat;
extern struct coda_permission_stats coda_permission_stat;
extern struct coda_cache_inv_stats coda_cache_inv_stat;
/* reset statistics to 0 */
void reset_coda_vfs_stats( void );
void reset_coda_upcall_stats( void );
void reset_coda_permission_stats( void );
void reset_coda_cache_inv_stats( void );
/* some utitlities to make it easier for you to do statistics for time */
void do_time_stats( struct coda_upcall_stats_entry * pentry,
unsigned long jiffy );
/*
double get_time_average( const struct coda_upcall_stats_entry * pentry );
double get_time_std_deviation( const struct coda_upcall_stats_entry * pentry );
*/
unsigned long get_time_average( const struct coda_upcall_stats_entry * pentry );
unsigned long get_time_std_deviation( const struct coda_upcall_stats_entry * pentry );
/* like coda_dointvec, these functions are to be registered in the ctl_table
* data structure for /proc/sys/... files
*/
int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
void * buffer, size_t * lenp );
int do_reset_coda_upcall_stats( ctl_table * table, int write,
struct file * filp, void * buffer,
size_t * lenp );
int do_reset_coda_permission_stats( ctl_table * table, int write,
struct file * filp, void * buffer,
size_t * lenp );
int do_reset_coda_cache_inv_stats( ctl_table * table, int write,
struct file * filp, void * buffer,
size_t * lenp );
/* these functions are called to form the content of /proc/fs/coda/... files */
int coda_vfs_stats_get_info( char * buffer, char ** start, off_t offset,
int length, int dummy );
int coda_upcall_stats_get_info( char * buffer, char ** start, off_t offset,
int length, int dummy );
int coda_permission_stats_get_info( char * buffer, char ** start, off_t offset,
int length, int dummy );
int coda_cache_inv_stats_get_info( char * buffer, char ** start, off_t offset,
int length, int dummy );
#endif /* _CODA_PROC_H */
......@@ -94,8 +94,6 @@ int venus_access(struct super_block *sb, struct ViceFid *fid, int mask);
int venus_pioctl(struct super_block *sb, struct ViceFid *fid,
unsigned int cmd, struct PioctlData *data);
int coda_downcall(int opcode, union outputArgs *out, struct super_block *sb);
int coda_upcall(struct coda_sb_info *mntinfo, int inSize,
int *outSize, union inputArgs *buffer);
int venus_fsync(struct super_block *sb, struct ViceFid *fid);
......
/*
* Sysctl operations for Coda.
* Original version: (C) 1996 Peter Braam
* Rewritten for Linux 2.1: (C) 1997 Carnegie Mellon University
*
* Carnegie Mellon encourages users of this code to contribute improvements
* to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
*/
void coda_sysctl_init(void);
void coda_sysctl_clean(void);
......@@ -131,7 +131,7 @@ extern int d_invalidate(struct dentry *);
/* dcache memory management */
extern int select_dcache(int, int);
extern void shrink_dcache_memory(void);
extern void shrink_dcache_memory(int, unsigned int);
extern void check_dcache_memory(void);
extern void free_inode_memory(int); /* defined in fs/inode.c */
......
/*
* $Id: pci.h,v 1.67 1998/04/16 20:48:33 mj Exp $
* $Id: pci.h,v 1.70 1998/05/02 19:20:03 mj Exp $
*
* PCI defines and function prototypes
* Copyright 1994, Drew Eckhardt
......@@ -275,6 +275,7 @@
*/
#define PCI_VENDOR_ID_COMPAQ 0x0e11
#define PCI_DEVICE_ID_COMPAQ_1280 0x3033
#define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000
#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10
#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32
#define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34
......@@ -303,10 +304,14 @@
#define PCI_DEVICE_ID_ATI_210888CX 0x4358
#define PCI_DEVICE_ID_ATI_215GB 0x4742
#define PCI_DEVICE_ID_ATI_215GD 0x4744
#define PCI_DEVICE_ID_ATI_215GI 0x4749
#define PCI_DEVICE_ID_ATI_215GP 0x4750
#define PCI_DEVICE_ID_ATI_215GQ 0x4751
#define PCI_DEVICE_ID_ATI_215GT 0x4754
#define PCI_DEVICE_ID_ATI_215GTB 0x4755
#define PCI_DEVICE_ID_ATI_210888GX 0x4758
#define PCI_DEVICE_ID_ATI_215LG 0x4c47
#define PCI_DEVICE_ID_ATI_264LT 0x4c54
#define PCI_DEVICE_ID_ATI_264VT 0x5654
#define PCI_VENDOR_ID_VLSI 0x1004
......@@ -376,7 +381,8 @@
#define PCI_DEVICE_ID_IBM_MCA 0x0020
#define PCI_DEVICE_ID_IBM_82351 0x0022
#define PCI_DEVICE_ID_IBM_SERVERAID 0x002e
#define PCI_DEVICE_ID_IBM_MPEG2 0x007d
#define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e
#define PCI_DEVICE_ID_IBM_3780IDSP 0x007d
#define PCI_VENDOR_ID_WD 0x101c
#define PCI_DEVICE_ID_WD_7197 0x3296
......@@ -408,6 +414,7 @@
#define PCI_DEVICE_ID_CT_65548 0x00dc
#define PCI_DEVICE_ID_CT_65550 0x00e0
#define PCI_DEVICE_ID_CT_65554 0x00e4
#define PCI_DEVICE_ID_CT_65555 0x00e5
#define PCI_VENDOR_ID_MIRO 0x1031
#define PCI_DEVICE_ID_MIRO_36050 0x5601
......@@ -419,9 +426,11 @@
#define PCI_DEVICE_ID_FD_36C70 0x0000
#define PCI_VENDOR_ID_SI 0x1039
#define PCI_DEVICE_ID_SI_6201 0x0001
#define PCI_DEVICE_ID_SI_5591_AGP 0x0001
#define PCI_DEVICE_ID_SI_6202 0x0002
#define PCI_DEVICE_ID_SI_503 0x0008
#define PCI_DEVICE_ID_SI_ACPI 0x0009
#define PCI_DEVICE_ID_SI_5597_VGA 0x0200
#define PCI_DEVICE_ID_SI_6205 0x0205
#define PCI_DEVICE_ID_SI_501 0x0406
#define PCI_DEVICE_ID_SI_496 0x0496
......@@ -430,6 +439,7 @@
#define PCI_DEVICE_ID_SI_5511 0x5511
#define PCI_DEVICE_ID_SI_5513 0x5513
#define PCI_DEVICE_ID_SI_5571 0x5571
#define PCI_DEVICE_ID_SI_5591 0x5591
#define PCI_DEVICE_ID_SI_5597 0x5597
#define PCI_DEVICE_ID_SI_7001 0x7001
......@@ -493,6 +503,7 @@
#define PCI_VENDOR_ID_N9 0x105d
#define PCI_DEVICE_ID_N9_I128 0x2309
#define PCI_DEVICE_ID_N9_I128_2 0x2339
#define PCI_DEVICE_ID_N9_I128_T2R 0x493d
#define PCI_VENDOR_ID_UMC 0x1060
#define PCI_DEVICE_ID_UMC_UM8673F 0x0101
......@@ -510,6 +521,7 @@
#define PCI_VENDOR_ID_PICOP 0x1066
#define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001
#define PCI_DEVICE_ID_PICOP_PT80C524 0x8002
#define PCI_VENDOR_ID_APPLE 0x106b
#define PCI_DEVICE_ID_APPLE_BANDIT 0x0001
......@@ -538,7 +550,7 @@
#define PCI_VENDOR_ID_CONTAQ 0x1080
#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600
#define PCI_DEVICE_ID_CONTAQ_82C693 0xC693
#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693
#define PCI_VENDOR_ID_FOREX 0x1083
......@@ -589,7 +601,11 @@
#define PCI_VENDOR_ID_PLX 0x10b5
#define PCI_DEVICE_ID_PLX_9080 0x9080
#define PCI_VENDOR_ID_MADGE 0x10b6
#define PCI_DEVICE_ID_MADGE_MK2 0x0002
#define PCI_VENDOR_ID_3COM 0x10b7
#define PCI_DEVICE_ID_3COM_3C339 0x3390
#define PCI_DEVICE_ID_3COM_3C590 0x5900
#define PCI_DEVICE_ID_3COM_3C595TX 0x5950
#define PCI_DEVICE_ID_3COM_3C595T4 0x5951
......@@ -597,6 +613,8 @@
#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000
#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001
#define PCI_DEVICE_ID_3COM_3C905TX 0x9050
#define PCI_DEVICE_ID_3COM_3C905T4 0x9051
#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055
#define PCI_VENDOR_ID_SMC 0x10b8
#define PCI_DEVICE_ID_SMC_EPIC100 0x0005
......@@ -618,6 +636,7 @@
#define PCI_DEVICE_ID_AL_M5219 0x5219
#define PCI_DEVICE_ID_AL_M5229 0x5229
#define PCI_DEVICE_ID_AL_M5237 0x5237
#define PCI_DEVICE_ID_AL_M7101 0x7101
#define PCI_VENDOR_ID_MITSUBISHI 0x10ba
......@@ -635,6 +654,10 @@
#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
#define PCI_VENDOR_ID_MACRONIX 0x10d9
#define PCI_DEVICE_ID_MACRONIX_MX98713 0x0512
#define PCI_DEVICE_ID_MACRONIX_MX987x5 0x0531
#define PCI_VENDOR_ID_CERN 0x10dc
#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001
#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002
......@@ -654,6 +677,7 @@
#define PCI_VENDOR_ID_AMCC 0x10e8
#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043
#define PCI_DEVICE_ID_AMCC_PARASTATION 0x8062
#define PCI_DEVICE_ID_AMCC_S5933 0x807d
#define PCI_DEVICE_ID_AMCC_S5933_HEPC3 0x809c
......@@ -664,6 +688,7 @@
#define PCI_VENDOR_ID_REALTEK 0x10ec
#define PCI_DEVICE_ID_REALTEK_8029 0x8029
#define PCI_DEVICE_ID_REALTEK_8129 0x8129
#define PCI_DEVICE_ID_REALTEK_8139 0x8139
#define PCI_VENDOR_ID_TRUEVISION 0x10fa
#define PCI_DEVICE_ID_TRUEVISION_T1000 0x000c
......@@ -686,6 +711,7 @@
#define PCI_DEVICE_ID_VIA_82C595_97 0x1595
#define PCI_DEVICE_ID_VIA_82C586_2 0x3038
#define PCI_DEVICE_ID_VIA_82C586_3 0x3040
#define PCI_DEVICE_ID_VIA_86C100A 0x6100
#define PCI_DEVICE_ID_VIA_82C597_1 0x8597
#define PCI_VENDOR_ID_VORTEX 0x1119
......@@ -734,6 +760,7 @@
#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000
#define PCI_VENDOR_ID_PHILIPS 0x1131
#define PCI_DEVICE_ID_PHILIPS_SAA7145 0x7145
#define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146
#define PCI_VENDOR_ID_CYCLONE 0x113c
......@@ -756,6 +783,7 @@
#define PCI_DEVICE_ID_DIGI_CX 0x0006
#define PCI_DEVICE_ID_DIGI_XRJ 0x0009
#define PCI_DEVICE_ID_DIGI_EPCJ 0x000a
#define PCI_DEVICE_ID_DIGI_XR_920 0x0027
#define PCI_VENDOR_ID_MUTECH 0x1159
#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001
......@@ -806,6 +834,9 @@
#define PCI_DEVICE_ID_ZORAN_36057 0x6057
#define PCI_DEVICE_ID_ZORAN_36120 0x6120
#define PCI_VENDOR_ID_KINETIC 0x11f4
#define PCI_DEVICE_ID_KINETIC_2915 0x2915
#define PCI_VENDOR_ID_COMPEX 0x11f6
#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112
#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
......@@ -823,7 +854,7 @@
#define PCI_DEVICE_ID_CYCLOM_Z_Hi 0x0201
#define PCI_VENDOR_ID_ESSENTIAL 0x120f
#define PCI_DEVICE_ID_ROADRUNNER 0x0001
#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001
#define PCI_VENDOR_ID_O2 0x1217
#define PCI_DEVICE_ID_O2_6832 0x6832
......@@ -835,6 +866,10 @@
#define PCI_VENDOR_ID_SIGMADES 0x1236
#define PCI_DEVICE_ID_SIGMADES_6425 0x6401
#define PCI_VENDOR_ID_CCUBE 0x123f
#define PCI_VENDOR_ID_DIPIX 0x1246
#define PCI_VENDOR_ID_STALLION 0x124d
#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000
#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002
......@@ -847,6 +882,13 @@
#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC 0x2120
#define PCI_DEVICE_ID_OPTIBASE_VQUEST 0x2130
#define PCI_VENDOR_ID_SATSAGEM 0x1267
#define PCI_DEVICE_ID_SATSAGEM_PCR2101 0x5352
#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b
#define PCI_VENDOR_ID_HUGHES 0x1273
#define PCI_DEVICE_ID_HUGHES_DIRECPC 0x0002
#define PCI_VENDOR_ID_ENSONIQ 0x1274
#define PCI_DEVICE_ID_ENSONIQ_AUDIOPCI 0x5000
......@@ -856,6 +898,9 @@
#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2
#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
#define PCI_VENDOR_ID_CBOARDS 0x1307
#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001
#define PCI_VENDOR_ID_SYMPHONY 0x1c1c
#define PCI_DEVICE_ID_SYMPHONY_101 0x0001
......@@ -867,6 +912,7 @@
#define PCI_DEVICE_ID_3DLABS_500TX 0x0002
#define PCI_DEVICE_ID_3DLABS_DELTA 0x0003
#define PCI_DEVICE_ID_3DLABS_PERMEDIA 0x0004
#define PCI_DEVICE_ID_3DLABS_MX 0x0006
#define PCI_VENDOR_ID_AVANCE 0x4005
#define PCI_DEVICE_ID_AVANCE_ALG2064 0x2064
......@@ -916,6 +962,7 @@
#define PCI_DEVICE_ID_INTEL_82371MX 0x1234
#define PCI_DEVICE_ID_INTEL_82437MX 0x1235
#define PCI_DEVICE_ID_INTEL_82441 0x1237
#define PCI_DEVICE_ID_INTEL_82380FB 0x124b
#define PCI_DEVICE_ID_INTEL_82439 0x1250
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
......@@ -928,6 +975,9 @@
#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
#define PCI_DEVICE_ID_INTEL_82443LX_0 0x7180
#define PCI_DEVICE_ID_INTEL_82443LX_1 0x7181
#define PCI_DEVICE_ID_INTEL_82443BX_0 0x7190
#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191
#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192
#define PCI_DEVICE_ID_INTEL_P6 0x84c4
#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
......@@ -952,6 +1002,7 @@
#define PCI_DEVICE_ID_ADAPTEC_7882 0x8278
#define PCI_DEVICE_ID_ADAPTEC_7883 0x8378
#define PCI_DEVICE_ID_ADAPTEC_7884 0x8478
#define PCI_DEVICE_ID_ADAPTEC_1030 0x8b78
#define PCI_VENDOR_ID_ATRONICS 0x907f
#define PCI_DEVICE_ID_ATRONICS_2015 0x2015
......@@ -959,6 +1010,9 @@
#define PCI_VENDOR_ID_HOLTEK 0x9412
#define PCI_DEVICE_ID_HOLTEK_6565 0x6565
#define PCI_VENDOR_ID_TIGERJET 0xe159
#define PCI_DEVICE_ID_TIGERJET_300 0x0001
#define PCI_VENDOR_ID_ARK 0xedd8
#define PCI_DEVICE_ID_ARK_STING 0xa091
#define PCI_DEVICE_ID_ARK_STINGARK 0xa099
......@@ -978,6 +1032,8 @@
#ifdef __KERNEL__
#include <linux/types.h>
/*
* Error values that may be returned by the PCI bios.
*/
......@@ -1084,13 +1140,13 @@ struct pci_dev *pci_find_class (unsigned int class, struct pci_dev *from);
struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
#define pci_present pcibios_present
#define pci_read_config_byte(dev, where, val) pcibios_read_config_byte(dev->bus->number, dev->devfn, where, val)
#define pci_read_config_word(dev, where, val) pcibios_read_config_word(dev->bus->number, dev->devfn, where, val)
#define pci_read_config_dword(dev, where, val) pcibios_read_config_dword(dev->bus->number, dev->devfn, where, val)
#define pci_write_config_byte(dev, where, val) pcibios_write_config_byte(dev->bus->number, dev->devfn, where, val)
#define pci_write_config_word(dev, where, val) pcibios_write_config_word(dev->bus->number, dev->devfn, where, val)
#define pci_write_config_dword(dev, where, val) pcibios_write_config_dword(dev->bus->number, dev->devfn, where, val)
void pci_set_master(struct pci_dev *);
int pci_read_config_byte(struct pci_dev *dev, u8 where, u8 *val);
int pci_read_config_word(struct pci_dev *dev, u8 where, u16 *val);
int pci_read_config_dword(struct pci_dev *dev, u8 where, u32 *val);
int pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val);
int pci_write_config_word(struct pci_dev *dev, u8 where, u16 val);
int pci_write_config_dword(struct pci_dev *dev, u8 where, u32 val);
void pci_set_master(struct pci_dev *dev);
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
......@@ -51,6 +51,7 @@ enum root_directory_inos {
PROC_PPC_HTAB,
PROC_SOUND,
PROC_MTRR, /* whether enabled or not */
PROC_FS
};
enum pid_directory_inos {
......@@ -205,6 +206,19 @@ enum bus_directory_inos {
PROC_BUS_LAST
};
enum fs_directory_inos {
PROC_FS_CODA = PROC_MCA_LAST,
PROC_FS_LAST
};
enum fs_coda_directory_inos {
PROC_VFS_STATS = PROC_MCA_LAST,
PROC_UPCALL_STATS,
PROC_PERMISSION_STATS,
PROC_CACHE_INV_STATS,
PROC_CODA_FS_LAST
};
/* Finally, the dynamically allocatable proc entries are reserved: */
#define PROC_DYNAMIC_FIRST 4096
......
......@@ -50,6 +50,15 @@ typedef struct freepages_v1
typedef freepages_v1 freepages_t;
extern freepages_t freepages;
typedef struct pager_daemon_v1
{
unsigned int tries_base;
unsigned int tries_min;
unsigned int swap_cluster;
} pager_daemon_v1;
typedef pager_daemon_v1 pager_daemon_t;
extern pager_daemon_t pager_daemon;
#define SC_VERSION 1
#define SC_MAX_VERSION 1
......
......@@ -84,7 +84,8 @@ enum
VM_BDFLUSH, /* struct: Control buffer cache flushing */
VM_OVERCOMMIT_MEMORY, /* Turn off the virtual memory safety limit */
VM_BUFFERMEM, /* struct: Set buffer memory thresholds */
VM_PAGECACHE /* struct: Set cache memory thresholds */
VM_PAGECACHE, /* struct: Set cache memory thresholds */
VM_PAGERDAEMON /* struct: Control kswapd behaviour */
};
......
......@@ -255,12 +255,12 @@ struct ufs_superblock {
__s32 fs_contigsumsize;/* size of cluster summary array */
__s32 fs_maxsymlinklen;/* max length of an internal symlink */
__s32 fs_inodefmt; /* format of on-disk inodes */
__u64 fs_maxfilesize; /* max representable file size */
__u32 fs_maxfilesize[2];/* max representable file size */
__u32 fs_qbmask[2]; /* ~usb_bmask */
__u32 fs_qfmask[2]; /* ~usb_fmask */
__s32 fs_state; /* file system state time stamp */
} fs_44;
} fs_u __attribute__ ((packed));
} fs_u;
__s32 fs_postblformat; /* format of positional layout tables */
__s32 fs_nrpos; /* number of rotational positions */
__s32 fs_postbloff; /* (__s16) rotation block list head */
......
......@@ -189,20 +189,22 @@ static ctl_table kern_table[] = {
static ctl_table vm_table[] = {
{VM_SWAPCTL, "swapctl",
&swap_control, sizeof(swap_control_t), 0600, NULL, &proc_dointvec},
&swap_control, sizeof(swap_control_t), 0644, NULL, &proc_dointvec},
{VM_SWAPOUT, "swapout_interval",
&swapout_interval, sizeof(int), 0600, NULL, &proc_dointvec},
&swapout_interval, sizeof(int), 0644, NULL, &proc_dointvec},
{VM_FREEPG, "freepages",
&freepages, sizeof(freepages_t), 0600, NULL, &proc_dointvec},
&freepages, sizeof(freepages_t), 0644, NULL, &proc_dointvec},
{VM_BDFLUSH, "bdflush", &bdf_prm, 9*sizeof(int), 0600, NULL,
&proc_dointvec_minmax, &sysctl_intvec, NULL,
&bdflush_min, &bdflush_max},
{VM_OVERCOMMIT_MEMORY, "overcommit_memory", &sysctl_overcommit_memory,
sizeof(sysctl_overcommit_memory), 0644, NULL, &proc_dointvec},
{VM_BUFFERMEM, "buffermem",
&buffer_mem, sizeof(buffer_mem_t), 0600, NULL, &proc_dointvec},
&buffer_mem, sizeof(buffer_mem_t), 0644, NULL, &proc_dointvec},
{VM_PAGECACHE, "pagecache",
&page_cache, sizeof(buffer_mem_t), 0600, NULL, &proc_dointvec},
&page_cache, sizeof(buffer_mem_t), 0644, NULL, &proc_dointvec},
{VM_PAGERDAEMON, "kswapd",
&pager_daemon, sizeof(pager_daemon_t), 0644, NULL, &proc_dointvec},
{0}
};
......
......@@ -9,7 +9,7 @@
O_TARGET := mm.o
O_OBJS := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
vmalloc.o slab.o simp.o\
vmalloc.o slab.o \
swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o
include $(TOPDIR)/Rules.make
......@@ -125,7 +125,7 @@ int free_memory_available(int nr)
* free unfragmented memory.
* Added low/high water marks to avoid thrashing -- Rik.
*/
if (nr_free_pages > (num_physpages >> 5) + (nr ? 0 : num_physpages >> 6))
if (nr_free_pages > (nr ? freepages.low : freepages.high))
return nr+1;
list = free_area + NR_MEM_LISTS;
......@@ -282,7 +282,6 @@ unsigned long __get_free_pages(int gfp_mask, unsigned long order)
spin_unlock_irqrestore(&page_alloc_lock, flags);
if (!(gfp_mask & __GFP_WAIT))
break;
shrink_dcache();
if (!try_to_free_pages(gfp_mask, SWAP_CLUSTER_MAX))
break;
gfp_mask &= ~__GFP_WAIT; /* go through this only once */
......@@ -335,15 +334,19 @@ __initfunc(unsigned long free_area_init(unsigned long start_mem, unsigned long e
int i;
/*
* select nr of pages we try to keep free for important stuff
* with a minimum of 48 pages. This is totally arbitrary
* Select nr of pages we try to keep free for important stuff
* with a minimum of 48 pages and a maximum of 256 pages, so
* that we don't waste too much memory on large systems.
* This is totally arbitrary.
*/
i = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT+7);
if (i < 48)
i = 48;
if (i > 256)
i = 256;
freepages.min = i;
freepages.low = i + (i>>1);
freepages.high = i + i;
freepages.low = i << 1;
freepages.high = freepages.low + i;
mem_map = (mem_map_t *) LONG_ALIGN(start_mem);
p = mem_map + MAP_NR(end_mem);
start_mem = LONG_ALIGN((unsigned long) p);
......
......@@ -44,8 +44,8 @@
*/
freepages_t freepages = {
48, /* freepages.min */
72, /* freepages.low */
96 /* freepages.high */
96, /* freepages.low */
144 /* freepages.high */
};
/* We track the number of pages currently being asynchronously swapped
......@@ -77,3 +77,9 @@ buffer_mem_t page_cache = {
30, /* borrow percent page cache */
75 /* maximum */
};
pager_daemon_t pager_daemon = {
512, /* base number for calculating the number of tries */
SWAP_CLUSTER_MAX, /* minimum number of tries */
SWAP_CLUSTER_MAX, /* do swap I/O in clusters of this size */
};
......@@ -553,22 +553,23 @@ int kswapd(void *unused)
* more aggressive if we're really
* low on free memory.
*
* The number of tries is 512 divided by an
* 'urgency factor'. In practice this will mean
* a value of 512 / 8 = 64 pages at a time,
* giving 64 * 4 (times/sec) * 4k (pagesize) =
* 1 MB/s in lowest-priority background
* paging. This number rises to 8 MB/s when the
* priority is highest (but then we'll be woken
* up more often and the rate will be even higher).
* -- Should make this sysctl tunable...
* We try page_daemon.tries_base times, divided by
* an 'urgency factor'. In practice this will mean
* a value of pager_daemon.tries_base / 8 or 4 = 64
* or 128 pages at a time.
* This gives us 64 (or 128) * 4k * 4 (times/sec) =
* 1 (or 2) MB/s swapping bandwidth in low-priority
* background paging. This number rises to 8 MB/s
* when the priority is highest (but then we'll be
* woken up more often and the rate will be even
* higher).
*/
tries = (512) >> free_memory_available(3);
tries = pager_daemon.tries_base >> free_memory_available(3);
while (tries--) {
int gfp_mask;
if (++tried > SWAP_CLUSTER_MAX && free_memory_available(0))
if (++tried > pager_daemon.tries_min && free_memory_available(0))
break;
gfp_mask = __GFP_IO;
try_to_free_page(gfp_mask);
......@@ -576,7 +577,7 @@ int kswapd(void *unused)
* Syncing large chunks is faster than swapping
* synchronously (less head movement). -- Rik.
*/
if (atomic_read(&nr_async_pages) >= SWAP_CLUSTER_MAX)
if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster)
run_task_queue(&tq_disk);
}
......
......@@ -53,10 +53,6 @@
#
# 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help
# texts.
#
# 100498 Riley Williams (rhw@bigfoot.com) - added ability to display
# blank lines in help texts: Any line consisting only of a single dot
# will be displayed blank.
#
# Make sure we're really running bash.
......@@ -107,7 +103,7 @@ ${var}:\\
then
echo; echo " Sorry, no help available for this option yet.";echo
else
(echo; echo "$text") | sed 's/^\.$//' | ${PAGER:-more}
(echo; echo "$text") | ${PAGER:-more}
fi
else
echo;
......
......@@ -47,13 +47,6 @@
#
# 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help
# texts.
#----------------------------------------------------------------------------
#
# 10 Apr 1998 - Added ability to display blank lines in help text: Any line
# which only contains a single dot will be displayed blank.
# Author: Riley Williams <rhw@bigfoot.com>
#
#----------------------------------------------------------------------------
#
......@@ -301,7 +294,7 @@ ${var}:\\
echo "There is no help available for this kernel option."
return 1
else
echo "$text" | sed 's/^\.$//'
echo "$text"
fi
else
echo "There is no help available for this kernel option."
......
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