Commit 81e6c66d authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.54

parent 0e8625c7
...@@ -187,6 +187,10 @@ S: 14509 NE 39th Street #1096 ...@@ -187,6 +187,10 @@ S: 14509 NE 39th Street #1096
S: Bellevue, Washington 98007 S: Bellevue, Washington 98007
S: USA S: USA
N: Juan Jose Ciarlante
E: jjciarla@raiz.uncu.edu.ar
D: Network driver alias support
N: Hamish Coleman N: Hamish Coleman
E: hamish@zot.apana.org.au E: hamish@zot.apana.org.au
D: SEEQ8005 network driver D: SEEQ8005 network driver
...@@ -195,11 +199,13 @@ S: East Malvern, Victoria, 3145 ...@@ -195,11 +199,13 @@ S: East Malvern, Victoria, 3145
S: Australia S: Australia
N: Alan Cox N: Alan Cox
E: iialan@iifeak.swan.ac.uk E: alan@lxorguk.ukuu.org.uk (linux related - except big patches)
E: alan@cymru.net (use for commercial traffic) E: iialan@www.linux.org.uk (linux.org.uk/big patches)
E: gw4pts@gw4pts.ampr.org E: alan@cymru.net (commercial CymruNET stuff)
E: gw4pts@gw4pts.ampr.org (amateur radio stuff)
E: GW4PTS@GB7SWN (packet radio) E: GW4PTS@GB7SWN (packet radio)
S: c/o I^2IT Limited E: Please don't use iialan@iifeak.swan.ac.uk for Linux stuff
S: c/o 3Com/I^2IT Limited
S: The Innovation Centre S: The Innovation Centre
S: University Of Wales S: University Of Wales
S: Swansea, SA2 8PP S: Swansea, SA2 8PP
...@@ -209,6 +215,8 @@ D: Network layer debugging ...@@ -209,6 +215,8 @@ D: Network layer debugging
D: Initial AX.25 & IPX releases D: Initial AX.25 & IPX releases
D: Original Linux netatalk patches. D: Original Linux netatalk patches.
D: Current 3c501 hacker. >>More 3c501 info/tricks wanted<<. D: Current 3c501 hacker. >>More 3c501 info/tricks wanted<<.
D: Watchdog timer drivers
D: Linux/SMP
N: Laurence Culhane N: Laurence Culhane
E: loz@holmes.demon.co.uk E: loz@holmes.demon.co.uk
...@@ -557,6 +565,7 @@ S: The Netherlands ...@@ -557,6 +565,7 @@ S: The Netherlands
N: Volker Lendecke N: Volker Lendecke
E: lendecke@namu01.gwdg.de E: lendecke@namu01.gwdg.de
D: Kernel smbfs (to mount WfW, NT and OS/2 network drives.) D: Kernel smbfs (to mount WfW, NT and OS/2 network drives.)
D: NCP filesystem support (to mount NetWare volumes)
S: Innersteweg 11 S: Innersteweg 11
S: 37081 Goettingen S: 37081 Goettingen
S: Germany S: Germany
...@@ -799,6 +808,13 @@ N: Greg Page ...@@ -799,6 +808,13 @@ N: Greg Page
E: greg@caldera.com E: greg@caldera.com
D: IPX development and support D: IPX development and support
N: Avery Pennarun
E: apenwarr@foxnet.net
D: ARCnet driver, various small changes
S: RR #5, 497 Pole Line Road
S: Thunder Bay, Ontario
S: CANADA P7C 5M9
N: Kai Petzke N: Kai Petzke
E: wpp@marie.physik.tu-berlin.de E: wpp@marie.physik.tu-berlin.de
D: Driver for Laser Magnetic Storage CD-ROM D: Driver for Laser Magnetic Storage CD-ROM
......
...@@ -177,9 +177,34 @@ typing - a infinite number of monkeys typing into GNU emacs would never ...@@ -177,9 +177,34 @@ typing - a infinite number of monkeys typing into GNU emacs would never
make a good program). make a good program).
So, you can either get rid of GNU emacs, or change it to use saner So, you can either get rid of GNU emacs, or change it to use saner
values. I did the first, so don't ask me how to do the latter. But values. To do the latter, you can stick the following in your .emacs file:
even if you fail in getting emacs to do sane formatting, not everything
is lost: use "indent". (defun linux-c-mode ()
"C mode with adjusted defaults for use with the Linux kernel."
(interactive)
(c-mode)
(setq c-indent-level 8)
(setq c-brace-imaginary-offset 0)
(setq c-brace-offset -8)
(setq c-argdecl-indent 8)
(setq c-label-offset -8)
(setq c-continued-statement-offset 8)
(setq indent-tabs-mode nil)
(setq tab-width 8))
This will define the M-x linux-c-mode command. When hacking on a
module, if you put the string -*- linux-c -*- somewhere on the first
two lines, this mode will be automatically invoked. Also, you may want
to add
(setq auto-mode-alist (cons '("/usr/src/linux.*/.*\\.[ch]$" . linux-c-mode)
auto-mode-alist))
to your .emacs file if you want to have linux-c-mode switched on
automagically when you edit source files under /usr/src/linux.
But even if you fail in getting emacs to do sane formatting, not
everything is lost: use "indent".
Now, again, GNU indent has the same brain dead settings that GNU emacs Now, again, GNU indent has the same brain dead settings that GNU emacs
has, which is why you need to give it a few command line options. has, which is why you need to give it a few command line options.
......
...@@ -177,6 +177,17 @@ CONFIG_NET ...@@ -177,6 +177,17 @@ CONFIG_NET
consider updating your networking tools too; read net/README for consider updating your networking tools too; read net/README for
details. details.
Network aliasing
CONFIG_NET_ALIAS
This is for setting several network addresses on the same low-level network
device driver. Typically used for services that act different based
on the address they listen (eg. Apache httpd) or for connecting to
different logical networks through the same physical interface.
This is the generic part, later when configuring network protocol
options you will be asked for protocol-specific aliasing support.
See net/core/README.alias for more info.
If you need this features (for any protocol, like IP) say Y.
Sun floppy controller support Sun floppy controller support
CONFIG_BLK_DEV_SUNFD CONFIG_BLK_DEV_SUNFD
This is support for floppy drives on Sun Sparc workstations. Say Y This is support for floppy drives on Sun Sparc workstations. Say Y
...@@ -492,6 +503,12 @@ CONFIG_IP_MASQUERADE ...@@ -492,6 +503,12 @@ CONFIG_IP_MASQUERADE
has nothing to do with the computer architecture of the same has nothing to do with the computer architecture of the same
name. If you want this, say Y. name. If you want this, say Y.
IP: aliasing support
CONFIG_IP_ALIAS
You need this to enable IP layer network aliasing. This will also
enable ARP resolution for alias devices. If you don't need several
IP addresses per interface, answer N.
IP: multicast routing(in progress) IP: multicast routing(in progress)
CONFIG_IP_MROUTE CONFIG_IP_MROUTE
This is used if you want your machine to act as a router for IP This is used if you want your machine to act as a router for IP
...@@ -787,9 +804,10 @@ CONFIG_SCSI_BUSLOGIC ...@@ -787,9 +804,10 @@ CONFIG_SCSI_BUSLOGIC
the documentation in drivers/scsi/README.BusLogic for more information. the documentation in drivers/scsi/README.BusLogic for more information.
BusLogic FlashPoint SCSI Host Adapters are not supported by this driver. BusLogic FlashPoint SCSI Host Adapters are not supported by this driver.
If this driver does not work correctly without modification, please If this driver does not work correctly without modification, please
consult the author. This driver is not currently available as a module. consult the author. This driver may also be built as a module, but
You might want to read the SCSI-HOWTO, available via ftp (user: only a single instance may be loaded. You might also want to read
anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. the SCSI-HOWTO, available via anonymous ftp from
sunsite.unc.edu:/pub/Linux/docs/HOWTO.
EATA-DMA (DPT,NEC&ATT for ISA,EISA,PCI) support EATA-DMA (DPT,NEC&ATT for ISA,EISA,PCI) support
CONFIG_SCSI_EATA_DMA CONFIG_SCSI_EATA_DMA
......
NET_ALIAS device aliasing v0.4x
===============================
The main step taken in versions 0.40+ is the implementation of a
device aliasing mechanism that creates *actual* devices.
This development includes NET_ALIAS (generic aliasing) plus IP_ALIAS
(specific IP) support.
Features
--------
o ACTUAL alias devices created & inserted in dev chain
o AF_ independent: net_alias_type objects. Generic aliasing engine.
o AF_INET optimized
o hashed alias address lookup
o net_alias_type objs registration/unreg., module-ables.
o /proc/net/aliases & /proc/net/alias_types entries
o IP alias implementation: static or runtime module.
Usage (IP aliasing)
-------------------
A very first step to test if you are running a net_alias-ed kernel
is to check /proc/net/aliases & /proc/net/alias_types entries:
# cat /proc/net/alias*
For IP aliasing you must have IP_ALIAS support included by
static linking ('y' to 2nd question above), or runtime module
insertion ('m' to 2nd q. above):
# insmod /usr/src/linux/modules/ip_alias.o (1.3.xx)
# insmod /usr/src/ip_alias/ip_alias.o (1.2.xx) see above.
o Alias creation.
Alias creation is done by 'magic' iface naming: eg. to create a
200.1.1.1 alias for eth0 ...
# ifconfig eth0:0 200.1.1.1 etc,etc....
~~ -> request alias #0 creation (if it not exists) for eth0
and routing stuff also ...
# route add -host 200.1.1.1 dev eth0:0 (if same IP network as
main device)
# route add -net 200.1.1.0 dev eth0:0 (if completely new network wanted
for eth0:0)
o Alias deletion.
Also done by magic naming, eg:
# ifconfig eth0:0- 0 (maybe any address)
~~~ -> will delete alias (note '-' after dev name)
alias device is closed before deletion, so all network stuff that
points to it (routes, arp entries, ...) will be released.
Alias (re-)configuring
Aliases *are* devices, so you configure and refer to them as usual (ifconfig,
route, etc).
o Procfs entries
2 entries are added to help fetching alias runtime configuration:
a) /proc/net/alias_types
Will show you alias_types registered (ie. address families that
can be aliased).
eg. for IP aliasing with 1 alias configured:
# cat /proc/net/alias_types
type name n_attach
2 ip 1
b) /proc/net/aliases
Will show aliased devices info, eg (same as above):
# cat /proc/net/aliases
device family address
eth0:0 2 200.1.1.1
Relationship with main device
-----------------------------
- On main device closing, all aliases will be closed and freed.
- Each new alias created is inserted in dev_chain just before next
main device (aliases get 'stacked' after main_dev), eg:
lo->eth0->eth0:0->eth0:2->eth1->0
If eth0 is unregistered, all it aliases will also be:
lo->eth1->0
Contact
-------
Please finger or e-mail me:
Juan Jose Ciarlante <jjciarla@raiz.uncu.edu.ar>
; local variables:
; mode: indented-text
; mode: auto-fill
; end:
Using the RAM disk block device with Linux
------------------------------------------
Contents:
1) Overview
2) Kernel Command Line Parameters
3) Using "rdev -r" With New Kernels
4) An Example of Creating a Compressed ramdisk
1) Overview
-----------
As of kernel v1.3.48, the ramdisk driver was substantially changed.
The older versions would grab a chunk of memory off the top before
handing the remainder to the kernel at boot time. Thus a size parameter
had to be specified via "ramdisk=1440" or "rdev -r /dev/fd0 1440" so
that the driver knew how much memory to grab.
Now the ramdisk dynamically grows as more space is required. It does
this by using RAM from the buffer cache. The driver marks the buffers
it is using with a new "BH_Protected" flag so that the kernel does
not try to reuse them later. This means that the old size parameter
is no longer used, new command line parameters exist, and the behavior
of the "rdev -r" or "ramsize" (usually a symbolic link to "rdev")
command has changed.
The old "ramdisk=<ram_size>" is now obsolete. The kernel will ignore
such old commands, and thus they will be passed on through to the init
program, which will then complain. You should remove any of these old
style commands from config files such as "/etc/lilo.config".
The new ramdisk also has the ability to load compressed ramdisk images,
allowing one to squeeze more programs onto an average installation or
rescue floppy disk.
Notes: You may have "dev/ram" or "/dev/ramdisk" or both. They are
equivalent from the standpoint of this document. Also, the new ramdisk
is a config option. When running "make config", make sure you enable
ramdisk support for the kernel you intend to use the ramdisk with.
2) Kernel Command Line Parameters
---------------------------------
ramdisk_start=NNN
=================
To allow a kernel image to reside on a floppy disk along with a compressed
ramdisk image, the "ramdisk_start=<offset>" command was added. The kernel
can't be included into the compressed ramdisk filesystem image, because
it needs to be stored starting at block zero so that the BIOS can load the
bootsector and then the kernel can bootstrap itself to get going.
Note: If you are using an uncompressed ramdisk image, then the kernel can
be a part of the filesystem image that is being loaded into the ramdisk,
and the floppy can be booted with LILO, or the two can be separate as
is done for the compressed images.
If you are using a two-disk boot/root setup (kernel on #1, ramdisk image
on #2) then the ramdisk would start at block zero, and an offset of
zero would be used. Since this is the default value, you would not need
to actually use the command at all.
If instead, you have a "zImage" of about 350k, and a "fs_image.gz" of
say about 1MB, and you want them both on the same disk, then you
would use an offset. If you stored the "fs_image.gz" onto the floppy
starting at an offset of 400kB, you would use "ramdisk_start=400".
load_ramdisk=N
==============
This parameter tells the kernel whether it is to try and load a
ramdisk image or not. Specifying "load_ramdisk=1" will tell the
kernel to load a floppy into the ramdisk. The default value is
zero, meaning that the kernel should not try to load a ramdisk.
prompt_ramdisk=N
================
This parameter tells the kernel whether or not to give you a prompt
asking you to insert the floppy containing the ramdisk image. In
a single floppy configuration the ramdisk image is on the same floppy
as the kernel that just finished loading/booting and so a prompt
is not needed. In this case one can use "prompt_ramdisk=0". In a
two floppy configuration, you will need the chance to switch disks,
and thus "prompt_ramdisk=1" can be used. Since this is the default
value, it doesn't really need to be specified.
3) Using "rdev -r" With New Kernels
-----------------------------------
The usage of the word (two bytes) that "rdev -r" sets in the kernel image
has changed. The low 11 bits (0 -> 10) specify an offset (in 1k blocks)
of up to 2MB (2^11) of where to find the ramdisk (this used to be the
size). Bit 14 indicates that a ramdisk is to be loaded, and bit 15
indicates whether a prompt/wait sequence is to be given before trying
to read the ramdisk. Since the ramdisk dynamically grows as data is
being written into it, a size field is no longer required. Bits 11
to 13 are not presently used and may as well be zero. These numbers
are no magical secrets, as seen below:
./arch/i386/kernel/setup.c:#define RAMDISK_IMAGE_START_MASK 0x07FF
./arch/i386/kernel/setup.c:#define RAMDISK_PROMPT_FLAG 0x8000
./arch/i386/kernel/setup.c:#define RAMDISK_LOAD_FLAG 0x4000
Consider a typical two floppy disk setup, where you will have the
kernel on disk one, and have already put a ramdisk image onto disk #2.
Hence you want to set bits 0 to 13 as zero, meaning that your ramdisk
starts at an offset of zero kB from the beginning of the floppy.
The command line equivalent is: "ramdisk_start=0"
You want bit 14 as one, indicating that a ramdisk is to be loaded.
The command line equivalent is: "load_ramdisk=1"
You want bit 15 as one, indicating that you want a prompt/keypress
sequence so that you have a chance to switch floppy disks.
The command line equivalent is: "prompt_ramdisk=1"
Putting that together gives 2^15 + 2^14 + 0 = 49152 for an rdev word.
So to create disk one of the set, you would do:
/usr/src/linux# cat arch/i386/boot/zImage > /dev/fd0
/usr/src/linux# rdev /dev/fd0 /dev/fd0
/usr/src/linux# rdev -r /dev/fd0 49152
If you make a boot disk that has LILO, then for the above, you would use:
append = "ramdisk_start=0 load_ramdisk=1 prompt_ramdisk=1"
Since the default start = 0 and the default prompt = 1, you could use:
append = "load_ramdisk=1"
4) An Example of Creating a Compressed ramdisk
----------------------------------------------
To create a ramdisk image, you will need a spare block device to
construct it on. This can be the ramdisk device itself, or an
unused disk partition (such as an unmounted swap partition). For this
example, we will use the ramdisk device, "/dev/ram".
Note: This technique should not be done on a machine with less than 8MB
of RAM. If using a spare disk partition instead of /dev/ram, then this
restriction does not apply.
a) Decide on the ramdisk size that you want. Say 2MB for this example.
Create it by writing to the ramdisk device. (This step is not presently
required, but may be in the future.) It is wise to zero out the
area (esp. for disks) so that maximal compression is achieved for
the unused blocks of the image that you are about to create.
dd if=/dev/zero of=/dev/ram bs=1k count=2048
b) Make a filesystem on it. Say ext2fs for this example.
mke2fs -vm0 /dev/ram 2048
c) Mount it, copy the files you want to it (eg: /etc/* /dev/* ...)
and unmount it again.
d) Compress the contents of the ramdisk. The level of compression
will be approximately 50% of the space used by the files. Unused
space on the ramdisk will compress to almost nothing.
dd if=/dev/ram bs=1k count=2048 | gzip -v9 > /tmp/ram_image.gz
e) Put the kernel onto the floppy
cat zImage > /dev/fd0
f) Put the ramdisk image onto the floppy, after the kernel. Use an offset
that is slightly larger than the kernel, so that you can put another
(possibly larger) kernel onto the same floppy later without overlapping
the ramdisk image. An offset of 400kB for kernels about 350kB in
size would be reasonable. Make sure offset+size of ram_image.gz is
not larger than the total space on your floppy (usually 1440kB).
dd if=/tmp/ram_image.gz of=/dev/fd0 bs=1k skip=400
g) Use "rdev" to set the boot device, ramdisk offset, prompt flag, etc.
For ramdisk_start=400, load_ramdisk=1, ramdisk_start=400, one would
have 2^15 + 2^14 + 400 = 49552.
rdev /dev/fd0 /dev/fd0
rdev -r /dev/fd0 49552
That is it. You now have your boot/root compressed ramdisk floppy. Some
users may wish to combine steps (d) and (f) by using a pipe.
--------------------------------------------------------------------------
Paul Gortmaker 12/95
VERSION = 1 VERSION = 1
PATCHLEVEL = 3 PATCHLEVEL = 3
SUBLEVEL = 53 SUBLEVEL = 54
ARCH = i386 ARCH = i386
...@@ -249,7 +249,7 @@ MODFLAGS += -DMODVERSIONS -include $(HPATH)/linux/modversions.h ...@@ -249,7 +249,7 @@ MODFLAGS += -DMODVERSIONS -include $(HPATH)/linux/modversions.h
endif endif
modules: include/linux/version.h modules: include/linux/version.h
@set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i CFLAGS="-dc $(CFLAGS) $(MODFLAGS)" modules; done @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i CFLAGS="$(CFLAGS) $(MODFLAGS)" modules; done
modules_install: modules_install:
@( \ @( \
......
...@@ -71,6 +71,18 @@ INSTALLING the kernel: ...@@ -71,6 +71,18 @@ INSTALLING the kernel:
failed patches (xxx# or xxx.rej). If there are, either you or me has failed patches (xxx# or xxx.rej). If there are, either you or me has
made a mistake. made a mistake.
Alternatively, the script patch-kernel can be used to automate this
process. It determines the current kernel version and applies any
patches found.
cd /usr/src
linux/scripts/patch-kernel
The default directory for the kernel source is /usr/src/linux, but
can be specified as the first argument. Patches are applied from
the current directory, but an alternative directory can be specified
as the second argument.
- make sure your /usr/include/linux and /usr/include/asm directories - make sure your /usr/include/linux and /usr/include/asm directories
are just symlinks to the kernel sources: are just symlinks to the kernel sources:
......
...@@ -153,10 +153,10 @@ CONFIG_MSDOS_FS=y ...@@ -153,10 +153,10 @@ CONFIG_MSDOS_FS=y
# CONFIG_UMSDOS_FS is not set # CONFIG_UMSDOS_FS is not set
CONFIG_PROC_FS=y CONFIG_PROC_FS=y
# CONFIG_NFS_FS is not set # CONFIG_NFS_FS is not set
# CONFIG_SMB_FS is not set
CONFIG_ISO9660_FS=y CONFIG_ISO9660_FS=y
# CONFIG_HPFS_FS is not set # CONFIG_HPFS_FS is not set
# CONFIG_SYSV_FS is not set # CONFIG_SYSV_FS is not set
# CONFIG_SMB_FS is not set
# #
# character devices # character devices
......
...@@ -643,10 +643,13 @@ static inline void avanti_and_noname_fixup(void) ...@@ -643,10 +643,13 @@ static inline void avanti_and_noname_fixup(void)
PCI_INTERRUPT_LINE, dev->irq); PCI_INTERRUPT_LINE, dev->irq);
#endif #endif
} }
/* now, set any level-triggered IRQs */ /*
if (level_bits) * Now, make all PCI interrupts level sensitive. Notice:
outw(level_bits, 0x4d0); * these registers must be accessed byte-wise. outw() doesn't
* work, for some reason.
*/
outb((level_bits >> 0) & 0xff, 0x4d0);
outb((level_bits >> 8) & 0xff, 0x4d1);
#if PCI_MODIFY #if PCI_MODIFY
{ {
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/hwrpb.h> #include <asm/hwrpb.h>
extern void scsi_mem_init(unsigned long);
extern void die_if_kernel(char *,struct pt_regs *,long); extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void); extern void show_net_buffers(void);
...@@ -155,11 +154,6 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) ...@@ -155,11 +154,6 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
tmp += PAGE_SIZE; tmp += PAGE_SIZE;
} }
#ifdef CONFIG_SCSI
scsi_mem_init(high_memory);
#endif
for (tmp = PAGE_OFFSET ; tmp < high_memory ; tmp += PAGE_SIZE) { for (tmp = PAGE_OFFSET ; tmp < high_memory ; tmp += PAGE_SIZE) {
if (mem_map[MAP_NR(tmp)].reserved) if (mem_map[MAP_NR(tmp)].reserved)
continue; continue;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* Felix Koop : NR_CPUS used properly * Felix Koop : NR_CPUS used properly
* Jose Renau : Handle single CPU case. * Jose Renau : Handle single CPU case.
* Alan Cox : By repeated request 8) - Total BogoMIP report. * Alan Cox : By repeated request 8) - Total BogoMIP report.
* Greg Wright : Fix for kernel stacks panic.
* *
*/ */
...@@ -42,7 +43,7 @@ int smp_threads_ready=0; /* Set when the idlers are all forked */ ...@@ -42,7 +43,7 @@ int smp_threads_ready=0; /* Set when the idlers are all forked */
volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; /* We always use 0 the rest is ready for parallel delivery */ volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; /* We always use 0 the rest is ready for parallel delivery */
volatile unsigned long smp_invalidate_needed; /* Used for the invalidate map thats also checked in the spinlock */ volatile unsigned long smp_invalidate_needed; /* Used for the invalidate map thats also checked in the spinlock */
struct cpuinfo_x86 cpu_data[NR_CPUS]; /* Per cpu bogomips and other parameters */ struct cpuinfo_x86 cpu_data[NR_CPUS]; /* Per cpu bogomips and other parameters */
static unsigned int num_processors = 0; /* Internal processor count */ static unsigned int num_processors = 1; /* Internal processor count */
static unsigned long io_apic_addr = 0; /* Address of the I/O apic (not yet used) */ static unsigned long io_apic_addr = 0; /* Address of the I/O apic (not yet used) */
unsigned char boot_cpu_id = 0; /* Processor that is doing the boot up */ unsigned char boot_cpu_id = 0; /* Processor that is doing the boot up */
static unsigned char *kstack_base,*kstack_end; /* Kernel stack list pointers */ static unsigned char *kstack_base,*kstack_end; /* Kernel stack list pointers */
...@@ -249,7 +250,6 @@ void smp_scan_config(unsigned long base, unsigned long length) ...@@ -249,7 +250,6 @@ void smp_scan_config(unsigned long base, unsigned long length)
{ {
unsigned long *bp=(unsigned long *)base; unsigned long *bp=(unsigned long *)base;
struct intel_mp_floating *mpf; struct intel_mp_floating *mpf;
num_processors = 1; /* The boot processor */
/* printk("Scan SMP from %p for %ld bytes.\n", /* printk("Scan SMP from %p for %ld bytes.\n",
bp,length);*/ bp,length);*/
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#undef USE_PENTIUM_MM #undef USE_PENTIUM_MM
#endif #endif
extern void scsi_mem_init(unsigned long);
extern void die_if_kernel(char *,struct pt_regs *,long); extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void); extern void show_net_buffers(void);
...@@ -232,9 +231,6 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) ...@@ -232,9 +231,6 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
mem_map[MAP_NR(start_mem)].reserved = 0; mem_map[MAP_NR(start_mem)].reserved = 0;
start_mem += PAGE_SIZE; start_mem += PAGE_SIZE;
} }
#ifdef CONFIG_SCSI
scsi_mem_init(high_memory);
#endif
for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) { for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) {
if (mem_map[MAP_NR(tmp)].reserved) { if (mem_map[MAP_NR(tmp)].reserved) {
if (tmp >= 0xA0000 && tmp < 0x100000) if (tmp >= 0xA0000 && tmp < 0x100000)
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
extern void deskstation_tyne_dma_init(void); extern void deskstation_tyne_dma_init(void);
extern void scsi_mem_init(unsigned long);
extern void sound_mem_init(void); extern void sound_mem_init(void);
extern void die_if_kernel(char *,struct pt_regs *,long); extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void); extern void show_net_buffers(void);
...@@ -258,9 +257,6 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) ...@@ -258,9 +257,6 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
#ifdef CONFIG_DESKSTATION_TYNE #ifdef CONFIG_DESKSTATION_TYNE
deskstation_tyne_dma_init(); deskstation_tyne_dma_init();
#endif #endif
#ifdef CONFIG_SCSI
scsi_mem_init(high_memory);
#endif
#ifdef CONFIG_SOUND #ifdef CONFIG_SOUND
sound_mem_init(); sound_mem_init();
#endif #endif
......
...@@ -45,9 +45,6 @@ extern unsigned long pg0[1024]; /* page table for 0-4MB for everybody */ ...@@ -45,9 +45,6 @@ extern unsigned long pg0[1024]; /* page table for 0-4MB for everybody */
#ifdef CONFIG_DESKSTATION_TYNE #ifdef CONFIG_DESKSTATION_TYNE
extern void deskstation_tyne_dma_init(void); extern void deskstation_tyne_dma_init(void);
#endif #endif
#ifdef CONFIG_SCSI
extern void scsi_mem_init(unsigned long);
#endif
#ifdef CONFIG_SOUND #ifdef CONFIG_SOUND
extern void sound_mem_init(void); extern void sound_mem_init(void);
#endif #endif
...@@ -225,9 +222,6 @@ printk("Mem init - Start: %x, End: %x\n", start_mem, high_memory); ...@@ -225,9 +222,6 @@ printk("Mem init - Start: %x, End: %x\n", start_mem, high_memory);
#ifdef CONFIG_DESKSTATION_TYNE #ifdef CONFIG_DESKSTATION_TYNE
deskstation_tyne_dma_init(); deskstation_tyne_dma_init();
#endif #endif
#ifdef CONFIG_SCSI
scsi_mem_init(high_memory);
#endif
#ifdef CONFIG_SOUND #ifdef CONFIG_SOUND
sound_mem_init(); sound_mem_init();
#endif #endif
......
...@@ -391,6 +391,9 @@ by doing the following after installing slackware (or whatever): ...@@ -391,6 +391,9 @@ by doing the following after installing slackware (or whatever):
program is run (like Norton "speeddisk"), it may move the Linux boot program is run (like Norton "speeddisk"), it may move the Linux boot
files around, confusing LILO and making the (Linux) system unbootable. files around, confusing LILO and making the (Linux) system unbootable.
Be sure to keep a kernel "boot floppy" at hand for such circumstances. Be sure to keep a kernel "boot floppy" at hand for such circumstances.
A possible workaround is to mark the Linux files as S+H+R (System,
Hidden, Readonly), to prevent most defragmentation programs from
moving the files around.
If you "don't do DOS", then partition as you please, but remember to create If you "don't do DOS", then partition as you please, but remember to create
a small partition to hold the /boot directory (and vmlinuz) as described above a small partition to hold the /boot directory (and vmlinuz) as described above
......
...@@ -272,7 +272,7 @@ static inline int DRIVE(kdev_t x) { ...@@ -272,7 +272,7 @@ static inline int DRIVE(kdev_t x) {
/* /*
* globals used by 'result()' * globals used by 'result()'
*/ */
#define MAX_REPLIES 10 #define MAX_REPLIES 17
static unsigned char reply_buffer[MAX_REPLIES]; static unsigned char reply_buffer[MAX_REPLIES];
static int inr; /* size of reply buffer, when called from interrupt */ static int inr; /* size of reply buffer, when called from interrupt */
#define ST0 (reply_buffer[0]) #define ST0 (reply_buffer[0])
...@@ -3656,8 +3656,38 @@ static char get_fdc_version(void) ...@@ -3656,8 +3656,38 @@ static char get_fdc_version(void)
printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r); printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
return FDC_UNKNOWN; return FDC_UNKNOWN;
} }
output_byte(FD_PARTID);
r = result();
if (r != 1) {
printk("FDC init: PARTID: unexpected return of %d bytes.\n",r);
return FDC_UNKNOWN;
}
if (reply_buffer[0] == 0x80) {
printk("FDC %d is a post-1991 82077\n",fdc); printk("FDC %d is a post-1991 82077\n",fdc);
return FDC_82077; /* Revised 82077AA passes all the tests */ return FDC_82077; /* Revised 82077AA passes all the tests */
}
switch (reply_buffer[0] >> 5) {
case 0x0:
output_byte(FD_SAVE);
r = result();
if (r != 17) {
printk("FDC init: SAVE: unexpected return of %d bytes.\n",r);
return FDC_UNKNOWN;
}
if (!(reply_buffer[0] & 0x40)) {
printk("FDC %d is a 3Volt 82078SL.\n",fdc);
return FDC_82078;
}
/* Either a 82078-1 or a 82078SL running at 5Volt */
printk("FDC %d is a 82078-1.\n",fdc);
return FDC_82078_1;
case 0x1:
printk("FDC %d is a 44pin 82078\n",fdc);
return FDC_82078;
default:
printk("FDC %d init: PARTID returned an unknown ID: %d.\n", fdc, reply_buffer[0] >> 5);
return FDC_UNKNOWN;
}
} /* get_fdc_version */ } /* get_fdc_version */
/* lilo configuration */ /* lilo configuration */
......
This diff is collapsed.
/* /*
* linux/drivers/block/ide-tape.h Version 1.1 - ALPHA Dec 14, 1995 * linux/drivers/block/ide-tape.h Version 1.2 - ALPHA Jan 1, 1996
* *
* Copyright (C) 1995 Gadi Oxman <tgud@tochnapc2.technion.ac.il> * Copyright (C) 1995, 1996 Gadi Oxman <tgud@tochnapc2.technion.ac.il>
*/ */
/* /*
...@@ -23,8 +23,7 @@ ...@@ -23,8 +23,7 @@
* *
* Pipelined operation mode has the potential to maximize the * Pipelined operation mode has the potential to maximize the
* performance of the driver and thus to saturate the throughput * performance of the driver and thus to saturate the throughput
* to the maximum value supported by the tape. Currently, pipelined * to the maximum value supported by the tape.
* mode is supported only on writes.
* *
* In pipelined mode we are servicing requests without blocking the * In pipelined mode we are servicing requests without blocking the
* user backup program. For example, on a write request, we will add it * user backup program. For example, on a write request, we will add it
...@@ -32,9 +31,8 @@ ...@@ -32,9 +31,8 @@
* user program will then have enough time to prepare the next blocks * user program will then have enough time to prepare the next blocks
* while the tape is still busy working on the previous requests. * while the tape is still busy working on the previous requests.
* *
* Pipelined (write) operation mode is enabled by default, but since * Pipelined operation mode is enabled by default, but since it has a
* it has a few downfalls as well (Use of additional memory and deferred * few downfalls as well, you may wish to disable it.
* error code to the application), you may wish to disable it.
* Further explanation of pipelined mode is available in ide-tape.c . * Further explanation of pipelined mode is available in ide-tape.c .
*/ */
...@@ -57,6 +55,29 @@ ...@@ -57,6 +55,29 @@
#define IDETAPE_MAX_PIPELINE_STAGES 200 #define IDETAPE_MAX_PIPELINE_STAGES 200
#define IDETAPE_INCREASE_STAGES_RATE 0.2 #define IDETAPE_INCREASE_STAGES_RATE 0.2
/*
* Assuming the tape shares an interface with another device, the default
* behavior is to service our pending pipeline requests as soon as
* possible, but to gracefully postpone them in favor of the other device
* when the tape is busy. This has the potential to maximize our
* throughput and in the same time, to make efficient use of the IDE bus.
*
* Note that when we transfer data to / from the tape, we co-operate with
* the relatively fast tape buffers and the tape will perform the
* actual media access in the background, without blocking the IDE
* bus. This means that as long as the maximum IDE bus throughput is much
* higher than the sum of our maximum throughput and the maximum
* throughput of the other device, we should probably leave the default
* behavior.
*
* However, if it is still desired to give the other device a share even
* in our own (small) bus bandwidth, you can set IDETAPE_LOW_TAPE_PRIORITY
* to 1. This will let the other device finish *all* its pending requests
* before we even check if we can service our next pending request.
*/
#define IDETAPE_LOW_TAPE_PRIORITY 0
/* /*
* It seems that dynamically allocating buffers of about 32KB * It seems that dynamically allocating buffers of about 32KB
* each is doomed to fail, unless we are in or very near the * each is doomed to fail, unless we are in or very near the
...@@ -76,21 +97,25 @@ ...@@ -76,21 +97,25 @@
#endif #endif
/* /*
* Setting IDETAPE_DEBUG to 1 will: * The following are used to debug the driver:
*
* 1. Generally log all driver actions.
* 2. Enable self-sanity checks in some places.
* *
* Use IDETAPE_DEBUG when encountering a problem with the driver. * Setting IDETAPE_DEBUG_LOG to 1 will log driver flow control.
* Setting IDETAPE_DEBUG_BUGS to 1 will enable self-sanity checks in
* some places.
* *
* Setting IDETAPE_DEBUG to 0 will restore normal operation mode: * Setting them to 0 will restore normal operation mode:
* *
* 1. Disable logging normal successful operations. * 1. Disable logging normal successful operations.
* 2. Disable self-sanity checks. * 2. Disable self-sanity checks.
* 3. Errors will still be logged, of course. * 3. Errors will still be logged, of course.
*
* All the #if DEBUG code will be removed some day, when the driver
* is verified to be stable enough. This will make it much more
* esthetic.
*/ */
#define IDETAPE_DEBUG 0 #define IDETAPE_DEBUG_LOG 0
#define IDETAPE_DEBUG_BUGS 1
/* /*
* After each failed packet command we issue a request sense command * After each failed packet command we issue a request sense command
...@@ -147,9 +172,12 @@ ...@@ -147,9 +172,12 @@
* request queue, so that ide.c will service requests from * request queue, so that ide.c will service requests from
* the other device on the same interface meanwhile. * the other device on the same interface meanwhile.
* *
* The polling frequency is 1/IDETAPE_DSC_READ_WRITE_FREQUENCY, * We can now automatically select the "best" polling frequency.
* and it should be relatively fast. The default is a period * Have a look at IDETAPE_ANTICIPATE_READ_WRITE_DSC below.
* of 50 msec. *
* In case you don't want to use the automatic selection,
* choose it to be relatively fast. The default fallback
* frequency is 1/50 msec.
* *
* 2. After the successful initialization of a "media access * 2. After the successful initialization of a "media access
* packet command", which is a command which can take a long * packet command", which is a command which can take a long
...@@ -173,7 +201,30 @@ ...@@ -173,7 +201,30 @@
* *
*/ */
#define IDETAPE_DSC_READ_WRITE_FREQUENCY 5*HZ/100 /* 50 msec */ /*
* Setting IDETAPE_ANTICIPATE_READ_WRITE_DSC to 1 will allow ide-tape
* to cleverly select the lowest possible frequency which will
* not affect performance, based on the tape parameters and our operation
* mode. This has potential to dramatically decrease our polling load
* on Linux.
*
* However, for the cases in which our calculation fails, setting
* the following option to 0 will force the use of the "fallback"
* polling period defined below (defaults to 50 msec).
*
* In any case, the frequency will be between the "lowest" value
* to the "fallback" value, to ensure that our selected "best" frequency
* is reasonable.
*/
#define IDETAPE_ANTICIPATE_READ_WRITE_DSC 1
/*
* DSC timings.
*/
#define IDETAPE_DSC_READ_WRITE_FALLBACK_FREQUENCY 5*HZ/100 /* 50 msec */
#define IDETAPE_DSC_READ_WRITE_LOWEST_FREQUENCY 30*HZ/100 /* 300 msec */
#define IDETAPE_DSC_FAST_MEDIA_ACCESS_FREQUENCY 1*HZ /* 1 second */ #define IDETAPE_DSC_FAST_MEDIA_ACCESS_FREQUENCY 1*HZ /* 1 second */
#define IDETAPE_FAST_SLOW_THRESHOLD 5*60*HZ /* 5 minutes */ #define IDETAPE_FAST_SLOW_THRESHOLD 5*60*HZ /* 5 minutes */
#define IDETAPE_DSC_SLOW_MEDIA_ACCESS_FREQUENCY 60*HZ /* 1 minute */ #define IDETAPE_DSC_SLOW_MEDIA_ACCESS_FREQUENCY 60*HZ /* 1 minute */
...@@ -186,11 +237,10 @@ ...@@ -186,11 +237,10 @@
*/ */
/* /*
* The following is currently not used. * Current character device data transfer direction.
*/ */
typedef enum {no_excess_data,excess_data_read,excess_data_write} excess_data_status_t; typedef enum {idetape_direction_none,idetape_direction_read,idetape_direction_write} chrdev_direction_t;
struct ide_drive_s; /* Forward declaration - Will be defined later in ide.h */ struct ide_drive_s; /* Forward declaration - Will be defined later in ide.h */
typedef void (idetape_pc_completed_t)(struct ide_drive_s *); typedef void (idetape_pc_completed_t)(struct ide_drive_s *);
...@@ -203,10 +253,9 @@ typedef struct idetape_packet_command_s { ...@@ -203,10 +253,9 @@ typedef struct idetape_packet_command_s {
byte c [12]; /* Actual packet bytes */ byte c [12]; /* Actual packet bytes */
byte retries; /* On each retry, we increment retries */ byte retries; /* On each retry, we increment retries */
byte error; /* Set when an error occured */ byte error; /* Error code */
byte active; /* Set when a packet command is in progress */ byte abort; /* Set when an error is considered normal - We won't retry */
byte wait_for_dsc; /* 1 When polling for DSC */ byte wait_for_dsc; /* 1 When polling for DSC on a media access command */
byte dsc_count;
unsigned long request_transfer; /* Bytes to transfer */ unsigned long request_transfer; /* Bytes to transfer */
unsigned long actually_transferred; /* Bytes actually transferred */ unsigned long actually_transferred; /* Bytes actually transferred */
unsigned long buffer_size; /* Size of our data buffer */ unsigned long buffer_size; /* Size of our data buffer */
...@@ -353,12 +402,20 @@ typedef struct { ...@@ -353,12 +402,20 @@ typedef struct {
byte dsc_count; /* We received DSC dsc_count times in a row */ byte dsc_count; /* We received DSC dsc_count times in a row */
unsigned long dsc_polling_start; /* The time in which we started polling for DSC */ unsigned long dsc_polling_start; /* The time in which we started polling for DSC */
struct timer_list dsc_timer; /* Timer used to poll for dsc */ struct timer_list dsc_timer; /* Timer used to poll for dsc */
/*
* We can now be much more clever in our selection of the
* read/write polling frequency. This is used along with
* the compile time option IDETAPE_ANTICIPATE_DSC.
*/
unsigned long best_dsc_rw_frequency; /* Read/Write dsc polling frequency */
unsigned long dsc_polling_frequency; /* The current polling frequency */ unsigned long dsc_polling_frequency; /* The current polling frequency */
unsigned long dsc_timeout; /* Maximum waiting time */ unsigned long dsc_timeout; /* Maximum waiting time */
byte dsc_received; /* Set when we receive DSC */ byte dsc_received; /* Set when we receive DSC */
byte request_status; byte request_status;
byte request_dsc_callback;
byte last_status; /* Contents of the tape status register */ byte last_status; /* Contents of the tape status register */
/* before the current request (saved for us */ /* before the current request (saved for us */
/* by ide.c) */ /* by ide.c) */
...@@ -374,7 +431,7 @@ typedef struct { ...@@ -374,7 +431,7 @@ typedef struct {
/* Character device operation */ /* Character device operation */
unsigned char last_dt_was_write; /* Last character device data transfer was a write */ chrdev_direction_t chrdev_direction; /* Current character device data transfer direction */
byte busy; /* Device already opened */ byte busy; /* Device already opened */
/* Device information */ /* Device information */
...@@ -410,14 +467,19 @@ typedef struct { ...@@ -410,14 +467,19 @@ typedef struct {
int current_number_of_stages; /* Number of currently used stages */ int current_number_of_stages; /* Number of currently used stages */
int max_number_of_stages; /* We will not allocate more than this number of stages */ int max_number_of_stages; /* We will not allocate more than this number of stages */
idetape_pipeline_stage_t *first_stage; /* Will be serviced after the currently active request */ idetape_pipeline_stage_t *first_stage; /* The first stage which will be removed from the pipeline */
idetape_pipeline_stage_t *last_stage; /* New write requests will be added to the pipeline here */ idetape_pipeline_stage_t *active_stage; /* The currently active stage */
int pipeline_was_full_once; /* Set at the first time we fill the pipeline since the tape was opened */ idetape_pipeline_stage_t *next_stage; /* Will be serviced after the currently active request */
idetape_pipeline_stage_t *last_stage; /* New requests will be added to the pipeline here */
int error_in_pipeline_stage; /* Set when an error was detected in one of the pipeline stages */ int error_in_pipeline_stage; /* Set when an error was detected in one of the pipeline stages */
int pipeline_locked; /* Against race conditions ... */
} idetape_tape_t; } idetape_tape_t;
/*
* The following is used to have a quick look at the tape's status
* register between requests of the other device.
*/
#define POLL_HWIF_TAPE_DRIVE \ #define POLL_HWIF_TAPE_DRIVE \
if (hwif->tape_drive != NULL) { \ if (hwif->tape_drive != NULL) { \
if (hwif->tape_drive->tape.request_status) { \ if (hwif->tape_drive->tape.request_status) { \
...@@ -425,10 +487,6 @@ typedef struct { ...@@ -425,10 +487,6 @@ typedef struct {
hwif->tape_drive->tape.last_status=GET_STAT(); \ hwif->tape_drive->tape.last_status=GET_STAT(); \
hwif->tape_drive->tape.request_status=0; \ hwif->tape_drive->tape.request_status=0; \
} \ } \
if (hwif->tape_drive->tape.request_dsc_callback) { \
hwif->tape_drive->tape.request_dsc_callback=0; \
idetape_put_back_postponed_request(hwif->tape_drive); \
} \
} }
#endif /* IDETAPE_H */ #endif /* IDETAPE_H */
/* /*
* linux/drivers/block/ide.c Version 5.23 Dec 15, 1995 * linux/drivers/block/ide.c Version 5.24 Jan 4, 1996
* *
* Copyright (C) 1994, 1995 Linus Torvalds & authors (see below) * Copyright (C) 1994-1996 Linus Torvalds & authors (see below)
*/ */
/* /*
...@@ -179,6 +179,7 @@ ...@@ -179,6 +179,7 @@
* Version 5.21 fix nasty cdrom/tape bug (ide_preempt was messed up) * Version 5.21 fix nasty cdrom/tape bug (ide_preempt was messed up)
* Version 5.22 fix ide_xlate_1024() to work with/without drive->id * Version 5.22 fix ide_xlate_1024() to work with/without drive->id
* Version 5.23 miscellaneous touch-ups * Version 5.23 miscellaneous touch-ups
* Version 5.24 fix #if's for SUPPORT_CMD640
* *
* Driver compile-time options are in ide.h * Driver compile-time options are in ide.h
* *
...@@ -221,7 +222,7 @@ ...@@ -221,7 +222,7 @@
#include "ide.h" #include "ide.h"
#ifdef SUPPORT_CMD640 #if SUPPORT_CMD640
void cmd640_tune_drive(ide_drive_t *); void cmd640_tune_drive(ide_drive_t *);
static int cmd640_vlb = 0; static int cmd640_vlb = 0;
#endif #endif
...@@ -2209,7 +2210,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -2209,7 +2210,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
printk(", DMA"); printk(", DMA");
} }
printk("\n"); printk("\n");
#ifdef SUPPORT_CMD640 #if SUPPORT_CMD640
cmd640_tune_drive(drive); /* but can we tune a fish? */ cmd640_tune_drive(drive); /* but can we tune a fish? */
#endif #endif
} }
...@@ -2526,7 +2527,7 @@ static void init_qd6580 (void) ...@@ -2526,7 +2527,7 @@ static void init_qd6580 (void)
#include "umc8672.c" /* until we tidy up the interface some more */ #include "umc8672.c" /* until we tidy up the interface some more */
#endif #endif
#ifdef SUPPORT_CMD640 #if SUPPORT_CMD640
#include "cmd640.c" /* until we tidy up the interface some more */ #include "cmd640.c" /* until we tidy up the interface some more */
#endif #endif
...@@ -3037,7 +3038,7 @@ int ide_init (void) ...@@ -3037,7 +3038,7 @@ int ide_init (void)
if (pcibios_present()) if (pcibios_present())
ide_init_pci (); ide_init_pci ();
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
#ifdef SUPPORT_CMD640 #if SUPPORT_CMD640
ide_probe_for_cmd640x(); ide_probe_for_cmd640x();
#endif #endif
......
...@@ -598,13 +598,6 @@ void idetape_blkdev_release (struct inode *inode, struct file *filp, ide_drive_t ...@@ -598,13 +598,6 @@ void idetape_blkdev_release (struct inode *inode, struct file *filp, ide_drive_t
void idetape_register_chrdev (void); void idetape_register_chrdev (void);
/*
* The following function is called to re-insert a postponed tape
* request into the request queue.
*/
void idetape_put_back_postponed_request (ide_drive_t *drive);
#endif /* CONFIG_BLK_DEV_IDETAPE */ #endif /* CONFIG_BLK_DEV_IDETAPE */
#ifdef CONFIG_BLK_DEV_TRITON #ifdef CONFIG_BLK_DEV_TRITON
......
...@@ -25,6 +25,11 @@ ...@@ -25,6 +25,11 @@
* been completely removed. * been completely removed.
* *
* Loadable module support added by Tom Dyas. * Loadable module support added by Tom Dyas.
*
* Further cleanups by Chad Page (page0588@sundance.sjsu.edu):
* Cosmetic changes in #ifdef MODULE, code movement, etc...
* When the ramdisk is rmmod'ed, free the protected buffers
* Default ramdisk size changed to 2.88MB
*/ */
#include <linux/sched.h> #include <linux/sched.h>
...@@ -52,10 +57,15 @@ extern void wait_for_keypress(void); ...@@ -52,10 +57,15 @@ extern void wait_for_keypress(void);
#define MAJOR_NR RAMDISK_MAJOR #define MAJOR_NR RAMDISK_MAJOR
#include <linux/blk.h> #include <linux/blk.h>
#define BUILD_CRAMDISK /* These *should* be defined as parameters */
#define NUM_RAMDISKS 8 #define NUM_RAMDISKS 8
#define RD_DEFAULTSIZE 2880 /* 2.88 MB */
#ifndef MODULE #ifndef MODULE
/* We don't have to load ramdisks or gunzip them in a module... */
#define RD_LOADER
#define BUILD_CRAMDISK
void rd_load(void); void rd_load(void);
static int crd_load(struct file *fp, struct file *outfp); static int crd_load(struct file *fp, struct file *outfp);
#endif #endif
...@@ -106,9 +116,16 @@ static void rd_request(void) ...@@ -106,9 +116,16 @@ static void rd_request(void)
goto repeat; goto repeat;
} }
if (CURRENT->cmd == READ) { /*
* If we're reading, fill the buffer with 0's. This is okay since
* we're using protected buffers which should never get freed...
*
* If we're writing, we protect the buffer.
*/
if (CURRENT->cmd == READ)
memset(CURRENT->buffer, 0, len); memset(CURRENT->buffer, 0, len);
} else
set_bit(BH_Protected, &CURRENT->bh->b_state); set_bit(BH_Protected, &CURRENT->bh->b_state);
end_request(1); end_request(1);
...@@ -146,7 +163,6 @@ static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un ...@@ -146,7 +163,6 @@ static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
static int rd_open(struct inode * inode, struct file * filp) static int rd_open(struct inode * inode, struct file * filp)
{ {
if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS) if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
return -ENODEV; return -ENODEV;
...@@ -192,7 +208,7 @@ int rd_init(void) ...@@ -192,7 +208,7 @@ int rd_init(void)
blk_dev[MAJOR_NR].request_fn = &rd_request; blk_dev[MAJOR_NR].request_fn = &rd_request;
for (i = 0; i < NUM_RAMDISKS; i++) { for (i = 0; i < NUM_RAMDISKS; i++) {
rd_length[i] = (16384 * 1024); rd_length[i] = (RD_DEFAULTSIZE * 1024);
rd_blocksizes[i] = 1024; rd_blocksizes[i] = 1024;
} }
...@@ -201,7 +217,35 @@ int rd_init(void) ...@@ -201,7 +217,35 @@ int rd_init(void)
return 0; return 0;
} }
#ifndef MODULE /* loadable module support */
#ifdef MODULE
int init_module(void)
{
int error = rd_init();
if (!error)
printk(KERN_INFO "RAMDISK: Loaded as module.\n");
return error;
}
/* Before freeing the module, invalidate all of the protected buffers! */
void cleanup_module(void)
{
int i;
for (i = 0 ; i < NUM_RAMDISKS; i++)
invalidate_buffers(MKDEV(MAJOR_NR, i));
unregister_blkdev( MAJOR_NR, "ramdisk" );
blk_dev[MAJOR_NR].request_fn = 0;
}
#endif /* MODULE */
/* End of non-loading portions of the ramdisk driver */
#ifdef RD_LOADER
/* /*
* This routine tries to a ramdisk image to load, and returns the * This routine tries to a ramdisk image to load, and returns the
* number of blocks to read for a non-compressed image, 0 if the image * number of blocks to read for a non-compressed image, 0 if the image
...@@ -403,6 +447,7 @@ void rd_load() ...@@ -403,6 +447,7 @@ void rd_load()
infile.f_op->release(&inode, &infile); infile.f_op->release(&inode, &infile);
set_fs(fs); set_fs(fs);
} }
#endif /* RD_LOADER */
#ifdef BUILD_CRAMDISK #ifdef BUILD_CRAMDISK
...@@ -546,25 +591,3 @@ crd_load(struct file * fp, struct file *outfp) ...@@ -546,25 +591,3 @@ crd_load(struct file * fp, struct file *outfp)
#endif /* BUILD_CRAMDISK */ #endif /* BUILD_CRAMDISK */
#endif /* MODULE */
/* loadable module support */
#ifdef MODULE
int init_module(void)
{
int error = rd_init();
if (!error)
printk(KERN_INFO "RAMDISK: Loaded as module.\n");
return error;
}
void cleanup_module(void)
{
unregister_blkdev( MAJOR_NR, "ramdisk" );
blk_dev[MAJOR_NR].request_fn = 0;
}
#endif /* MODULE */
/* /*
* random.c -- A strong random number generator * random.c -- A strong random number generator
* *
* Version 0.95, last modified 4-Nov-95 * Version 0.96, last modified 29-Dec-95
* *
* Copyright Theodore Ts'o, 1994, 1995. All rights reserved. * Copyright Theodore Ts'o, 1994, 1995. All rights reserved.
* *
...@@ -276,7 +276,7 @@ void rand_initialize_irq(int irq) ...@@ -276,7 +276,7 @@ void rand_initialize_irq(int irq)
} }
} }
void rand_initialize_blkdev(int major) void rand_initialize_blkdev(int major, int mode)
{ {
struct timer_rand_state *state; struct timer_rand_state *state;
...@@ -287,7 +287,7 @@ void rand_initialize_blkdev(int major) ...@@ -287,7 +287,7 @@ void rand_initialize_blkdev(int major)
* If kamlloc returns null, we just won't use that entropy * If kamlloc returns null, we just won't use that entropy
* source. * source.
*/ */
state = kmalloc(sizeof(struct timer_rand_state), GFP_KERNEL); state = kmalloc(sizeof(struct timer_rand_state), mode);
if (state) { if (state) {
blkdev_timer_state[major] = state; blkdev_timer_state[major] = state;
memset(state, 0, sizeof(struct timer_rand_state)); memset(state, 0, sizeof(struct timer_rand_state));
...@@ -437,8 +437,14 @@ void add_interrupt_randomness(int irq) ...@@ -437,8 +437,14 @@ void add_interrupt_randomness(int irq)
void add_blkdev_randomness(int major) void add_blkdev_randomness(int major)
{ {
if (major >= MAX_BLKDEV || blkdev_timer_state[major] == 0) if (major >= MAX_BLKDEV)
return;
if (blkdev_timer_state[major] == 0) {
rand_initialize_blkdev(major, GFP_ATOMIC);
if (blkdev_timer_state[major] == 0)
return; return;
}
add_timer_randomness(&random_state, blkdev_timer_state[major], add_timer_randomness(&random_state, blkdev_timer_state[major],
0x200+major); 0x200+major);
......
...@@ -976,19 +976,30 @@ lance_rx(struct device *dev) ...@@ -976,19 +976,30 @@ lance_rx(struct device *dev)
if (status & 0x08) lp->stats.rx_crc_errors++; if (status & 0x08) lp->stats.rx_crc_errors++;
if (status & 0x04) lp->stats.rx_fifo_errors++; if (status & 0x04) lp->stats.rx_fifo_errors++;
lp->rx_ring[entry].base &= 0x03ffffff; lp->rx_ring[entry].base &= 0x03ffffff;
} else { }
else
{
/* Malloc up new buffer, compatible with net-2e. */ /* Malloc up new buffer, compatible with net-2e. */
short pkt_len = (lp->rx_ring[entry].msg_length & 0xfff)-4; short pkt_len = (lp->rx_ring[entry].msg_length & 0xfff)-4;
struct sk_buff *skb; struct sk_buff *skb;
if(pkt_len<60)
{
printk("%s: Runt packet!\n",dev->name);
lp->stats.rx_errors++;
}
else
{
skb = dev_alloc_skb(pkt_len+2); skb = dev_alloc_skb(pkt_len+2);
if (skb == NULL) { if (skb == NULL)
{
printk("%s: Memory squeeze, deferring packet.\n", dev->name); printk("%s: Memory squeeze, deferring packet.\n", dev->name);
for (i=0; i < RX_RING_SIZE; i++) for (i=0; i < RX_RING_SIZE; i++)
if (lp->rx_ring[(entry+i) & RX_RING_MOD_MASK].base < 0) if (lp->rx_ring[(entry+i) & RX_RING_MOD_MASK].base < 0)
break; break;
if (i > RX_RING_SIZE -2) { if (i > RX_RING_SIZE -2)
{
lp->stats.rx_dropped++; lp->stats.rx_dropped++;
lp->rx_ring[entry].base |= 0x80000000; lp->rx_ring[entry].base |= 0x80000000;
lp->cur_rx++; lp->cur_rx++;
...@@ -1005,7 +1016,7 @@ lance_rx(struct device *dev) ...@@ -1005,7 +1016,7 @@ lance_rx(struct device *dev)
netif_rx(skb); netif_rx(skb);
lp->stats.rx_packets++; lp->stats.rx_packets++;
} }
}
/* The docs say that the buffer length isn't touched, but Andrew Boyd /* The docs say that the buffer length isn't touched, but Andrew Boyd
of QNX reports that some revs of the 79C965 clear it. */ of QNX reports that some revs of the 79C965 clear it. */
lp->rx_ring[entry].buf_length = -PKT_BUF_SZ; lp->rx_ring[entry].buf_length = -PKT_BUF_SZ;
......
This diff is collapsed.
/* /*
Linux Driver for BusLogic SCSI Host Adapters Linux Driver for BusLogic MultiMaster SCSI Host Adapters
Copyright 1995 by Leonard N. Zubkoff <lnz@dandelion.com> Copyright 1995 by Leonard N. Zubkoff <lnz@dandelion.com>
...@@ -95,13 +95,11 @@ int BusLogic_BIOSDiskParameters(SCSI_Disk_T *, KernelDevice_T, int *); ...@@ -95,13 +95,11 @@ int BusLogic_BIOSDiskParameters(SCSI_Disk_T *, KernelDevice_T, int *);
/* /*
Define the number of Incoming and Outgoing Mailboxes used by this driver. Define the number of Incoming and Outgoing Mailboxes used by this driver.
Since BusLogic Host Adapters have room to buffer 32 commands internally,
there is significant virtue in setting BusLogic_MailboxCount to 32 or above.
The maximum possible value is 255, since the MailboxCount parameter to the The maximum possible value is 255, since the MailboxCount parameter to the
Initialize Extended Mailbox command is limited to a single byte. Initialize Extended Mailbox command is limited to a single byte.
*/ */
#define BusLogic_MailboxCount 32 #define BusLogic_MailboxCount 64
/* /*
...@@ -124,11 +122,12 @@ int BusLogic_BIOSDiskParameters(SCSI_Disk_T *, KernelDevice_T, int *); ...@@ -124,11 +122,12 @@ int BusLogic_BIOSDiskParameters(SCSI_Disk_T *, KernelDevice_T, int *);
/* /*
Define the default number of Concurrent Commands per Logical Unit to allow Define the default number of Concurrent Commands per Logical Unit to allow
for Target Devices on non-ISA and ISA Host Adapters. for Target Devices depending on whether or not ISA bounce buffers are
required.
*/ */
#define BusLogic_Concurrency 7 #define BusLogic_Concurrency 7
#define BusLogic_Concurrency_ISA 1 #define BusLogic_Concurrency_BB 1
/* /*
...@@ -142,7 +141,14 @@ int BusLogic_BIOSDiskParameters(SCSI_Disk_T *, KernelDevice_T, int *); ...@@ -142,7 +141,14 @@ int BusLogic_BIOSDiskParameters(SCSI_Disk_T *, KernelDevice_T, int *);
/* /*
Define the possible Tracing Options. Define the possible Local Options.
*/
#define BusLogic_InhibitTargetInquiry 1
/*
Define the possible Global Options.
*/ */
#define BusLogic_TraceProbe 1 #define BusLogic_TraceProbe 1
...@@ -267,7 +273,7 @@ typedef enum ...@@ -267,7 +273,7 @@ typedef enum
BusLogic_InitializeExtendedMailbox = 0x81, /* documented */ BusLogic_InitializeExtendedMailbox = 0x81, /* documented */
BusLogic_InquireFirmwareVersion3rdDigit = 0x84, /* undocumented */ BusLogic_InquireFirmwareVersion3rdDigit = 0x84, /* undocumented */
BusLogic_InquireFirmwareVersionLetter = 0x85, /* undocumented */ BusLogic_InquireFirmwareVersionLetter = 0x85, /* undocumented */
BusLogic_InquireBoardModelAndRevision = 0x8B, /* undocumented */ BusLogic_InquireBoardModelNumber = 0x8B, /* undocumented */
BusLogic_InquireSynchronousPeriod = 0x8C, /* undocumented */ BusLogic_InquireSynchronousPeriod = 0x8C, /* undocumented */
BusLogic_InquireExtendedSetupInformation = 0x8D, /* documented */ BusLogic_InquireExtendedSetupInformation = 0x8D, /* documented */
BusLogic_EnableStrictRoundRobinMode = 0x8F, /* documented */ BusLogic_EnableStrictRoundRobinMode = 0x8F, /* documented */
...@@ -395,15 +401,10 @@ typedef unsigned char BusLogic_FirmwareVersionLetter_T; ...@@ -395,15 +401,10 @@ typedef unsigned char BusLogic_FirmwareVersionLetter_T;
/* /*
Define the Inquire Board Model and Revision reply structure. Define the Inquire Board Model Number reply type.
*/ */
typedef struct BusLogic_ModelAndRevision typedef unsigned char BusLogic_BoardModelNumber_T[5];
{
unsigned char Model[5];
unsigned char Revision;
}
BusLogic_ModelAndRevision_T;
/* /*
...@@ -427,7 +428,7 @@ typedef struct BusLogic_ExtendedSetupInformation ...@@ -427,7 +428,7 @@ typedef struct BusLogic_ExtendedSetupInformation
unsigned char MailboxCount; /* Byte 4 */ unsigned char MailboxCount; /* Byte 4 */
void *BaseMailboxAddress __attribute__ ((packed)); /* Bytes 5-8 */ void *BaseMailboxAddress __attribute__ ((packed)); /* Bytes 5-8 */
struct { unsigned char :6; /* Byte 9 */ struct { unsigned char :6; /* Byte 9 */
boolean LevelTriggeredInterrupts:1; boolean LevelSensitiveInterrupts:1;
unsigned char :1; } Misc; unsigned char :1; } Misc;
unsigned char FirmwareRevision[3]; /* Bytes 10-12 */ unsigned char FirmwareRevision[3]; /* Bytes 10-12 */
boolean HostWideSCSI:1; /* Byte 13 Bit 0 */ boolean HostWideSCSI:1; /* Byte 13 Bit 0 */
...@@ -479,8 +480,8 @@ typedef unsigned char BusLogic_WideModeCCBRequest_T; ...@@ -479,8 +480,8 @@ typedef unsigned char BusLogic_WideModeCCBRequest_T;
/* /*
Define the Requested Reply Length type used by the Inquire Setup Information, Define the Requested Reply Length type used by the Inquire Setup Information,
Inquire Board Model and Revision, Inquire Synchronous Period, and Inquire Inquire Board Model Number, Inquire Synchronous Period, and Inquire Extended
Extended Setup Information commands. Setup Information commands.
*/ */
typedef unsigned char BusLogic_RequestedReplyLength_T; typedef unsigned char BusLogic_RequestedReplyLength_T;
...@@ -676,7 +677,7 @@ typedef struct BusLogic_CCB ...@@ -676,7 +677,7 @@ typedef struct BusLogic_CCB
BusLogic_HostAdapterStatus_T HostAdapterStatus:8; /* Byte 14 */ BusLogic_HostAdapterStatus_T HostAdapterStatus:8; /* Byte 14 */
BusLogic_TargetDeviceStatus_T TargetDeviceStatus:8; /* Byte 15 */ BusLogic_TargetDeviceStatus_T TargetDeviceStatus:8; /* Byte 15 */
unsigned char TargetID; /* Byte 16 */ unsigned char TargetID; /* Byte 16 */
unsigned char LogicalUnit:5; /* Byte 17 Bits 0-2 */ unsigned char LogicalUnit:5; /* Byte 17 Bits 0-4 */
boolean TagEnable:1; /* Byte 17 Bit 5 */ boolean TagEnable:1; /* Byte 17 Bit 5 */
BusLogic_QueueTag_T QueueTag:2; /* Byte 17 Bits 6-7 */ BusLogic_QueueTag_T QueueTag:2; /* Byte 17 Bits 6-7 */
SCSI_CDB_T CDB; /* Bytes 18-29 */ SCSI_CDB_T CDB; /* Bytes 18-29 */
...@@ -691,7 +692,8 @@ typedef struct BusLogic_CCB ...@@ -691,7 +692,8 @@ typedef struct BusLogic_CCB
SCSI_Command_T *Command; SCSI_Command_T *Command;
enum { BusLogic_CCB_Free = 0, enum { BusLogic_CCB_Free = 0,
BusLogic_CCB_Active = 1, BusLogic_CCB_Active = 1,
BusLogic_CCB_Completed = 2 } Status; BusLogic_CCB_Completed = 2,
BusLogic_CCB_Reset = 3 } Status;
BusLogic_CompletionCode_T MailboxCompletionCode; BusLogic_CompletionCode_T MailboxCompletionCode;
unsigned int SerialNumber; unsigned int SerialNumber;
struct BusLogic_CCB *Next; struct BusLogic_CCB *Next;
...@@ -759,6 +761,7 @@ typedef struct BusLogic_CommandLineEntry ...@@ -759,6 +761,7 @@ typedef struct BusLogic_CommandLineEntry
unsigned short IO_Address; unsigned short IO_Address;
unsigned short Concurrency; unsigned short Concurrency;
unsigned short BusSettleTime; unsigned short BusSettleTime;
unsigned short LocalOptions;
unsigned short TaggedQueuingPermitted; unsigned short TaggedQueuingPermitted;
unsigned short TaggedQueuingPermittedMask; unsigned short TaggedQueuingPermittedMask;
unsigned char ErrorRecoveryOption[BusLogic_MaxTargetIDs]; unsigned char ErrorRecoveryOption[BusLogic_MaxTargetIDs];
...@@ -774,10 +777,10 @@ typedef struct BusLogic_HostAdapter ...@@ -774,10 +777,10 @@ typedef struct BusLogic_HostAdapter
{ {
SCSI_Host_T *SCSI_Host; SCSI_Host_T *SCSI_Host;
unsigned char HostNumber; unsigned char HostNumber;
unsigned char ModelName[6]; unsigned char ModelName[9];
unsigned char FirmwareVersion[6]; unsigned char FirmwareVersion[6];
unsigned char BoardName[15]; unsigned char BoardName[18];
unsigned char InterruptLabel[63]; unsigned char InterruptLabel[62];
unsigned short IO_Address; unsigned short IO_Address;
unsigned char IRQ_Channel; unsigned char IRQ_Channel;
unsigned char DMA_Channel; unsigned char DMA_Channel;
...@@ -788,10 +791,11 @@ typedef struct BusLogic_HostAdapter ...@@ -788,10 +791,11 @@ typedef struct BusLogic_HostAdapter
boolean SynchronousInitiation:1; boolean SynchronousInitiation:1;
boolean ParityChecking:1; boolean ParityChecking:1;
boolean ExtendedTranslation:1; boolean ExtendedTranslation:1;
boolean LevelTriggeredInterrupts:1; boolean LevelSensitiveInterrupts:1;
boolean HostWideSCSI:1; boolean HostWideSCSI:1;
boolean HostDifferentialSCSI:1; boolean HostDifferentialSCSI:1;
boolean HostAdapterResetPending:1; boolean HostAdapterResetPending:1;
boolean BounceBuffersRequired:1;
volatile boolean HostAdapterCommandCompleted:1; volatile boolean HostAdapterCommandCompleted:1;
unsigned short HostAdapterScatterGatherLimit; unsigned short HostAdapterScatterGatherLimit;
unsigned short DriverScatterGatherLimit; unsigned short DriverScatterGatherLimit;
...@@ -799,6 +803,7 @@ typedef struct BusLogic_HostAdapter ...@@ -799,6 +803,7 @@ typedef struct BusLogic_HostAdapter
unsigned short MaxLogicalUnits; unsigned short MaxLogicalUnits;
unsigned short Concurrency; unsigned short Concurrency;
unsigned short BusSettleTime; unsigned short BusSettleTime;
unsigned short LocalOptions;
unsigned short DisconnectPermitted; unsigned short DisconnectPermitted;
unsigned short TaggedQueuingPermitted; unsigned short TaggedQueuingPermitted;
unsigned long BIOS_Address; unsigned long BIOS_Address;
...@@ -813,6 +818,8 @@ typedef struct BusLogic_HostAdapter ...@@ -813,6 +818,8 @@ typedef struct BusLogic_HostAdapter
unsigned char ErrorRecoveryOption[BusLogic_MaxTargetIDs]; unsigned char ErrorRecoveryOption[BusLogic_MaxTargetIDs];
unsigned char CommandSuccessfulFlag[BusLogic_MaxTargetIDs]; unsigned char CommandSuccessfulFlag[BusLogic_MaxTargetIDs];
unsigned long ReadWriteOperationCount[BusLogic_MaxTargetIDs]; unsigned long ReadWriteOperationCount[BusLogic_MaxTargetIDs];
unsigned char QueuedOperationCount[BusLogic_MaxTargetIDs];
unsigned long LastSequencePoint[BusLogic_MaxTargetIDs];
BusLogic_OutgoingMailbox_T *FirstOutgoingMailbox; BusLogic_OutgoingMailbox_T *FirstOutgoingMailbox;
BusLogic_OutgoingMailbox_T *LastOutgoingMailbox; BusLogic_OutgoingMailbox_T *LastOutgoingMailbox;
BusLogic_OutgoingMailbox_T *NextOutgoingMailbox; BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
...@@ -943,14 +950,17 @@ void BusLogic_StartMailboxScan(BusLogic_HostAdapter_T *HostAdapter) ...@@ -943,14 +950,17 @@ void BusLogic_StartMailboxScan(BusLogic_HostAdapter_T *HostAdapter)
/* /*
BusLogic_Delay waits for Seconds to elapse. It must be called with BusLogic_Delay waits for Seconds to elapse.
interrupts enabled so that jiffies is updated.
*/ */
static inline void BusLogic_Delay(int Seconds) static inline void BusLogic_Delay(int Seconds)
{ {
unsigned long TimeoutJiffies = jiffies + Seconds * HZ; unsigned long TimeoutJiffies = jiffies + Seconds * HZ;
unsigned long ProcessorFlags;
save_flags(ProcessorFlags);
sti();
while (jiffies < TimeoutJiffies) ; while (jiffies < TimeoutJiffies) ;
restore_flags(ProcessorFlags);
} }
......
Fri Nov 10 15:29:49 1995 Leonard N. Zubkoff (lnz@dandelion.com) Sun Dec 31 23:26:00 1995 Leonard N. Zubkoff <lnz@dandelion.com>
* BusLogic Driver Version 1.3.1 Released.
Fri Nov 10 15:29:49 1995 Leonard N. Zubkoff <lnz@dandelion.com>
* Released new BusLogic driver. * Released new BusLogic driver.
......
...@@ -18,7 +18,7 @@ dep_tristate 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X $CONFIG_SCSI ...@@ -18,7 +18,7 @@ dep_tristate 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
dep_tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI dep_tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC
dep_tristate 'EATA-DMA (DPT, NEC, ATT, Olivetti) support' CONFIG_SCSI_EATA_DMA $CONFIG_SCSI dep_tristate 'EATA-DMA (DPT, NEC, ATT, Olivetti) support' CONFIG_SCSI_EATA_DMA $CONFIG_SCSI
dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO $CONFIG_SCSI dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO $CONFIG_SCSI
dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F $CONFIG_SCSI dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F $CONFIG_SCSI
......
BusLogic SCSI Driver for Linux 1.3.41 BusLogic MultiMaster SCSI Driver for Linux 1.3.51
Version 1.3.0 ~ 13 November 1995 Version 1.3.1 ~ 31 December 1995
Leonard N. Zubkoff Leonard N. Zubkoff
Dandelion Digital Dandelion Digital
...@@ -15,7 +15,7 @@ adapters which share a common programming interface across a diverse collection ...@@ -15,7 +15,7 @@ adapters which share a common programming interface across a diverse collection
of bus architectures by virtue of their MultiMaster ASIC technology. This of bus architectures by virtue of their MultiMaster ASIC technology. This
driver supports all present BusLogic MultiMaster Host Adapters, and should driver supports all present BusLogic MultiMaster Host Adapters, and should
support any future MultiMaster designs with little or no modification. Host support any future MultiMaster designs with little or no modification. Host
adapters based on the new FlashPoint technology are not supported by this adapters based on the new FlashPoint architecture are not supported by this
driver. driver.
My primary goals in writing this completely new BusLogic driver for Linux are My primary goals in writing this completely new BusLogic driver for Linux are
...@@ -86,9 +86,10 @@ o Performance Features ...@@ -86,9 +86,10 @@ o Performance Features
number of concurrent commands per logical unit is available from the kernel number of concurrent commands per logical unit is available from the kernel
command line. In addition, tagged queuing is automatically disabled whenever command line. In addition, tagged queuing is automatically disabled whenever
the host adapter firmware version is known not to implement it correctly, or the host adapter firmware version is known not to implement it correctly, or
whenever a concurrency value of 1 is selected. In performance testing, whenever a concurrency value of 1 is selected. Tagged queuing is also
sustained disk writes of 7.3MB per second have been observed to a /dev/sd disabled for individual target devices if disconnect/reconnect is disabled
device. for that device. In performance testing, sustained disk writes of 7.3MB per
second have been observed to a /dev/sd device.
o Robustness Features o Robustness Features
...@@ -106,7 +107,9 @@ o Robustness Features ...@@ -106,7 +107,9 @@ o Robustness Features
correct operation, the next command that is reset will force a full host correct operation, the next command that is reset will force a full host
adapter hard reset and SCSI bus reset. SCSI bus resets caused by other adapter hard reset and SCSI bus reset. SCSI bus resets caused by other
devices and detected by the host adapter are also handled by issuing a hard devices and detected by the host adapter are also handled by issuing a hard
reset to the host adapter and full reinitialization. These error recovery reset to the host adapter and full reinitialization. Finally, if a command
using tagged queuing causes a bus device reset or SCSI bus reset, then tagged
queuing will be disabled for that target device. These error recovery
options should improve overall system robustness by preventing individual options should improve overall system robustness by preventing individual
errant devices from causing the system as a whole to lock up or crash, and errant devices from causing the system as a whole to lock up or crash, and
thereby allowing a clean shutdown and restart after the offending component thereby allowing a clean shutdown and restart after the offending component
...@@ -126,7 +129,9 @@ o PCI Configuration Support ...@@ -126,7 +129,9 @@ o PCI Configuration Support
On PCI systems running kernels compiled with PCI BIOS support enabled, this On PCI systems running kernels compiled with PCI BIOS support enabled, this
driver will interrogate the PCI configuration space and use the I/O port driver will interrogate the PCI configuration space and use the I/O port
addresses assigned by the system BIOS, rather than the ISA compatible I/O addresses assigned by the system BIOS, rather than the ISA compatible I/O
port addresses. port addresses. The ISA compatible I/O port address is then disabled by the
driver. On PCI systems it is also recommended that the AutoSCSI utility be
used to disable the ISA compatible I/O port entirely as it is not necessary.
o Shared Interrupts Support o Shared Interrupts Support
...@@ -156,34 +161,34 @@ that it is or will be supported. ...@@ -156,34 +161,34 @@ that it is or will be supported.
"C" Series Host Adapters: "C" Series Host Adapters:
946C PCI Fast Single-ended SCSI-2 BT-946C PCI Fast Single-ended SCSI-2
956C PCI Fast/Wide Single-ended SCSI-2 BT-956C PCI Fast/Wide Single-ended SCSI-2
956CD PCI Fast/Wide Differential SCSI-2 BT-956CD PCI Fast/Wide Differential SCSI-2
445C VLB Fast Single-ended SCSI-2 BT-445C VLB Fast Single-ended SCSI-2
747C EISA Fast Single-ended SCSI-2 BT-747C EISA Fast Single-ended SCSI-2
757C EISA Fast/Wide Single-ended SCSI-2 BT-757C EISA Fast/Wide Single-ended SCSI-2
757CD EISA Fast/Wide Differential SCSI-2 BT-757CD EISA Fast/Wide Differential SCSI-2
545C ISA Fast Single-ended SCSI-2 BT-545C ISA Fast Single-ended SCSI-2
540CF ISA Fast Single-ended SCSI-2 BT-540CF ISA Fast Single-ended SCSI-2
"S" Series Host Adapters: "S" Series Host Adapters:
445S VLB Fast Single-ended SCSI-2 BT-445S VLB Fast Single-ended SCSI-2
747S EISA Fast Single-ended SCSI-2 BT-747S EISA Fast Single-ended SCSI-2
747D EISA Fast Differential SCSI-2 BT-747D EISA Fast Differential SCSI-2
757S EISA Fast/Wide Single-ended SCSI-2 BT-757S EISA Fast/Wide Single-ended SCSI-2
757D EISA Fast/Wide Differential SCSI-2 BT-757D EISA Fast/Wide Differential SCSI-2
545S ISA Fast Single-ended SCSI-2 BT-545S ISA Fast Single-ended SCSI-2
542D ISA Fast Differential SCSI-2 BT-542D ISA Fast Differential SCSI-2
742A EISA Single-ended SCSI-2 (742A revision H) BT-742A EISA Single-ended SCSI-2 (742A revision H)
542B ISA Single-ended SCSI-2 (542B revision H) BT-542B ISA Single-ended SCSI-2 (542B revision H)
"A" Series Host Adapters: "A" Series Host Adapters:
742A EISA Single-ended SCSI-2 (742A revisions A - G) BT-742A EISA Single-ended SCSI-2 (742A revisions A - G)
542B ISA Single-ended SCSI-2 (542B revisions A - G) BT-542B ISA Single-ended SCSI-2 (542B revisions A - G)
The FlashPoint LT, also known as the 930 Ultra, implements a different host The FlashPoint LT, also known as the BT-930 Ultra, implements a different host
interface and is not supported by this driver. interface and is not supported by this driver.
AMI FastDisk Host Adapters are true BusLogic clones and are supported by this AMI FastDisk Host Adapters are true BusLogic clones and are supported by this
...@@ -235,18 +240,16 @@ substantially impact performance. ...@@ -235,18 +240,16 @@ substantially impact performance.
INSTALLATION INSTALLATION
This distribution was prepared for Linux kernel version 1.3.41. Installation This distribution was prepared for Linux kernel version 1.3.51. Installation
in later versions will probably be successful as well, though BusLogic.patch in later versions will probably be successful as well, though BusLogic.patch
may not be required once this driver becomes part of the standard development may not be required. Installation in Linux 1.3.41 - 1.3.50 will probably be
kernel; installation in earlier versions should not be attempted as 1.3.41 successful, but may require minor modifications.
contains changes I made to the common code that are essential for correct error
recovery.
To install the BusLogic SCSI driver, you may use the following commands, To install the BusLogic SCSI driver, you may use the following commands,
replacing "/usr/src" with wherever you keep your Linux kernel source tree: replacing "/usr/src" with wherever you keep your Linux kernel source tree:
cd /usr/src cd /usr/src
tar -xvzf BusLogic-1.3.0.tar.gz tar -xvzf BusLogic-1.3.1.tar.gz
mv README.BusLogic BusLogic.[ch] linux/drivers/scsi mv README.BusLogic BusLogic.[ch] linux/drivers/scsi
patch -p < BusLogic.patch patch -p < BusLogic.patch
cd linux cd linux
......
...@@ -290,8 +290,6 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){ ...@@ -290,8 +290,6 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
retval->unique_id = 0; retval->unique_id = 0;
retval->io_port = 0; retval->io_port = 0;
retval->forbidden_addr = 0;
retval->forbidden_size = 0;
retval->hostt = tpnt; retval->hostt = tpnt;
retval->next = NULL; retval->next = NULL;
#ifdef DEBUG #ifdef DEBUG
...@@ -404,28 +402,6 @@ unsigned int scsi_init() ...@@ -404,28 +402,6 @@ unsigned int scsi_init()
return 0; return 0;
} }
void scsi_mem_init(unsigned long memory_end)
{
struct Scsi_Host *Host;
long High8, Low24;
for (Host = scsi_hostlist; Host != NULL; Host = Host->next) {
if (Host->forbidden_addr > 0 && Host->forbidden_size > 0) {
for (High8 = 1<<24; High8 < memory_end; High8 += 1<<24) {
for (Low24 = Host->forbidden_addr;
Low24 < Host->forbidden_addr + Host->forbidden_size;
Low24 += PAGE_SIZE) {
unsigned long ForbiddenAddress = High8 + Low24;
if (ForbiddenAddress >= memory_end) goto next_host;
mem_map[MAP_NR(ForbiddenAddress)].reserved = 1;
}
}
}
next_host:
continue;
}
}
/* /*
* Overrides for Emacs so that we follow Linus's tabbing style. * Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically * Emacs will notice this stuff at the end of the file and automatically
......
...@@ -283,14 +283,6 @@ struct Scsi_Host ...@@ -283,14 +283,6 @@ struct Scsi_Host
*/ */
unsigned int unique_id; unsigned int unique_id;
/*
* Set these if there are conflicts between memory
* in the < 1mb region and regions at 16mb multiples.
* The address must be on a page boundary.
*/
unsigned long forbidden_addr;
unsigned long forbidden_size;
/* /*
* The rest can be copied from the template, or specifically * The rest can be copied from the template, or specifically
* initialized, as required. * initialized, as required.
...@@ -313,7 +305,7 @@ struct Scsi_Host ...@@ -313,7 +305,7 @@ struct Scsi_Host
*/ */
unsigned suggest_bus_reset:1; unsigned suggest_bus_reset:1;
int hostdata[0]; /* Used for storage of host specific stuff */ unsigned long hostdata[0]; /* Used for storage of host specific stuff */
}; };
extern struct Scsi_Host * scsi_hostlist; extern struct Scsi_Host * scsi_hostlist;
......
...@@ -802,8 +802,8 @@ static void scsi_times_out (Scsi_Cmnd * SCpnt, int pid) ...@@ -802,8 +802,8 @@ static void scsi_times_out (Scsi_Cmnd * SCpnt, int pid)
if (!scsi_abort (SCpnt, DID_TIME_OUT, pid)) if (!scsi_abort (SCpnt, DID_TIME_OUT, pid))
return; return;
case IN_ABORT: case IN_ABORT:
printk("SCSI host %d abort() timed out - resetting\n", printk("SCSI host %d abort (pid %ld) timed out - resetting\n",
SCpnt->host->host_no); SCpnt->host->host_no, SCpnt->pid);
if (!scsi_reset (SCpnt, FALSE)) if (!scsi_reset (SCpnt, FALSE))
return; return;
case IN_RESET: case IN_RESET:
......
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
* the 24F, cause the SCSI bus to do odd things and generally lead to * the 24F, cause the SCSI bus to do odd things and generally lead to
* kernel panics and machine hangs. This is like the Adaptec code. * kernel panics and machine hangs. This is like the Adaptec code.
* *
* Check I/O ports 14f, and 34f before allocating them to avoid conflicts. * Use check/snarf_region for 14f, 34f to avoid I/O space address conflicts.
*/ */
/* Changes from version 1.8 to version 1.9 /* Changes from version 1.8 to version 1.9
......
...@@ -25,7 +25,9 @@ ...@@ -25,7 +25,9 @@
#include <linux/locks.h> #include <linux/locks.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/malloc.h> #include <linux/malloc.h>
#include <linux/pagemap.h>
#include <linux/swapctl.h> #include <linux/swapctl.h>
#include <linux/smp.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/segment.h> #include <asm/segment.h>
...@@ -278,6 +280,7 @@ void invalidate_buffers(kdev_t dev) ...@@ -278,6 +280,7 @@ void invalidate_buffers(kdev_t dev)
if (bh->b_count) if (bh->b_count)
continue; continue;
bh->b_flushtime = 0; bh->b_flushtime = 0;
clear_bit(BH_Protected, &bh->b_state);
clear_bit(BH_Uptodate, &bh->b_state); clear_bit(BH_Uptodate, &bh->b_state);
clear_bit(BH_Dirty, &bh->b_state); clear_bit(BH_Dirty, &bh->b_state);
clear_bit(BH_Req, &bh->b_state); clear_bit(BH_Req, &bh->b_state);
...@@ -837,6 +840,7 @@ void __bforget(struct buffer_head * buf) ...@@ -837,6 +840,7 @@ void __bforget(struct buffer_head * buf)
{ {
wait_on_buffer(buf); wait_on_buffer(buf);
mark_buffer_clean(buf); mark_buffer_clean(buf);
clear_bit(BH_Protected, &buf->b_state);
buf->b_count--; buf->b_count--;
remove_from_hash_queue(buf); remove_from_hash_queue(buf);
buf->b_dev = NODEV; buf->b_dev = NODEV;
...@@ -1023,7 +1027,7 @@ static void read_buffers(struct buffer_head * bh[], int nrbuf) ...@@ -1023,7 +1027,7 @@ static void read_buffers(struct buffer_head * bh[], int nrbuf)
} while (nrbuf > 0); } while (nrbuf > 0);
} }
int bread_page(unsigned long address, kdev_t dev, int b[], int size) static int bread_page(unsigned long address, kdev_t dev, int b[], int size)
{ {
struct buffer_head *bh, *next, *arr[MAX_BUF_PER_PAGE]; struct buffer_head *bh, *next, *arr[MAX_BUF_PER_PAGE];
int block, nr; int block, nr;
...@@ -1072,6 +1076,34 @@ int bread_page(unsigned long address, kdev_t dev, int b[], int size) ...@@ -1072,6 +1076,34 @@ int bread_page(unsigned long address, kdev_t dev, int b[], int size)
return 0; return 0;
} }
/*
* Generic "readpage" function for block devices that have the
* normal bmap functionality. This is most of the block device
* filesystems.
*/
int generic_readpage(struct inode * inode, struct page * page)
{
unsigned long block;
int *p, nr[PAGE_SIZE/512];
int i;
i = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
block = page->offset >> inode->i_sb->s_blocksize_bits;
p = nr;
do {
*p = inode->i_op->bmap(inode, block);
i--;
block++;
p++;
} while (i > 0);
/* We should make this asynchronous, but this is good enough for now.. */
bread_page(page_address(page), inode->i_dev, nr, inode->i_sb->s_blocksize);
page->uptodate = 1;
wake_up(&page->wait);
return 0;
}
#if 0 #if 0
/* /*
* bwrite_page writes a page out to the buffer cache and/or the physical device. * bwrite_page writes a page out to the buffer cache and/or the physical device.
...@@ -1781,22 +1813,35 @@ asmlinkage int sys_bdflush(int func, long data) ...@@ -1781,22 +1813,35 @@ asmlinkage int sys_bdflush(int func, long data)
* the syscall above, but now we launch it ourselves internally with * the syscall above, but now we launch it ourselves internally with
* kernel_thread(...) directly after the first thread in init/main.c */ * kernel_thread(...) directly after the first thread in init/main.c */
int bdflush(void * unused) { int bdflush(void * unused)
{
int i; int i;
int ndirty; int ndirty;
int nlist; int nlist;
int ncount; int ncount;
struct buffer_head * bh, *next; struct buffer_head * bh, *next;
/* We have a bare-bones task_struct, and really should fill /*
in a few more things so "top" and /proc/2/{exe,root,cwd} * We have a bare-bones task_struct, and really should fill
display semi-sane things. Not real crucial though... */ * in a few more things so "top" and /proc/2/{exe,root,cwd}
* display semi-sane things. Not real crucial though...
*/
current->session = 1; current->session = 1;
current->pgrp = 1; current->pgrp = 1;
sprintf(current->comm, "kernel bdflush"); sprintf(current->comm, "kernel bdflush");
/*
* As a kernel thread we want to tamper with system buffers
* and other internals and thus be subject to the SMP locking
* rules. (On a uniprocessor box this does nothing).
*/
#ifdef __SMP__
lock_kernel();
syscall_count++;
#endif
for (;;) { for (;;) {
#ifdef DEBUG #ifdef DEBUG
printk("bdflush() activated..."); printk("bdflush() activated...");
......
...@@ -64,7 +64,7 @@ struct inode_operations ext_file_inode_operations = { ...@@ -64,7 +64,7 @@ struct inode_operations ext_file_inode_operations = {
NULL, /* rename */ NULL, /* rename */
NULL, /* readlink */ NULL, /* readlink */
NULL, /* follow_link */ NULL, /* follow_link */
NULL, /* readpage */ generic_readpage, /* readpage */
NULL, /* writepage */ NULL, /* writepage */
ext_bmap, /* bmap */ ext_bmap, /* bmap */
ext_truncate, /* truncate */ ext_truncate, /* truncate */
......
...@@ -227,7 +227,7 @@ void ext2_free_blocks (const struct inode * inode, unsigned long block, ...@@ -227,7 +227,7 @@ void ext2_free_blocks (const struct inode * inode, unsigned long block,
block); block);
else { else {
if (sb->dq_op) if (sb->dq_op)
sb->dq_op->free_block(inode, fs_to_dq_blocks(1, inode->i_blksize)); sb->dq_op->free_block(inode, fs_to_dq_blocks(1, sb->s_blocksize));
gdp->bg_free_blocks_count++; gdp->bg_free_blocks_count++;
es->s_free_blocks_count++; es->s_free_blocks_count++;
} }
...@@ -404,7 +404,7 @@ int ext2_new_block (const struct inode * inode, unsigned long goal, ...@@ -404,7 +404,7 @@ int ext2_new_block (const struct inode * inode, unsigned long goal,
* Check quota for allocation of this block. * Check quota for allocation of this block.
*/ */
if (sb->dq_op) if (sb->dq_op)
if (sb->dq_op->alloc_block (inode, fs_to_dq_blocks(1, inode->i_blksize))) { if (sb->dq_op->alloc_block (inode, fs_to_dq_blocks(1, sb->s_blocksize))) {
unlock_super (sb); unlock_super (sb);
*err = -EDQUOT; *err = -EDQUOT;
return 0; return 0;
...@@ -424,7 +424,7 @@ int ext2_new_block (const struct inode * inode, unsigned long goal, ...@@ -424,7 +424,7 @@ int ext2_new_block (const struct inode * inode, unsigned long goal,
ext2_warning (sb, "ext2_new_block", ext2_warning (sb, "ext2_new_block",
"bit already set for block %d", j); "bit already set for block %d", j);
if (sb->dq_op) if (sb->dq_op)
sb->dq_op->free_block(inode, fs_to_dq_blocks(1, inode->i_blksize)); sb->dq_op->free_block(inode, fs_to_dq_blocks(1, sb->s_blocksize));
goto repeat; goto repeat;
} }
...@@ -440,11 +440,11 @@ int ext2_new_block (const struct inode * inode, unsigned long goal, ...@@ -440,11 +440,11 @@ int ext2_new_block (const struct inode * inode, unsigned long goal,
for (k = 1; for (k = 1;
k < 8 && (j + k) < EXT2_BLOCKS_PER_GROUP(sb); k++) { k < 8 && (j + k) < EXT2_BLOCKS_PER_GROUP(sb); k++) {
if (sb->dq_op) if (sb->dq_op)
if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(1, inode->i_blksize))) if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(1, sb->s_blocksize)))
break; break;
if (set_bit (j + k, bh->b_data)) { if (set_bit (j + k, bh->b_data)) {
if (sb->dq_op) if (sb->dq_op)
sb->dq_op->free_block(inode, fs_to_dq_blocks(1, inode->i_blksize)); sb->dq_op->free_block(inode, fs_to_dq_blocks(1, sb->s_blocksize));
break; break;
} }
(*prealloc_count)++; (*prealloc_count)++;
......
...@@ -36,8 +36,6 @@ ...@@ -36,8 +36,6 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/ext2_fs.h> #include <linux/ext2_fs.h>
static int ext2_readpage(struct inode *, unsigned long, char *);
static int ext2_file_read (struct inode *, struct file *, char *, int);
static int ext2_file_write (struct inode *, struct file *, const char *, int); static int ext2_file_write (struct inode *, struct file *, const char *, int);
static void ext2_release_file (struct inode *, struct file *); static void ext2_release_file (struct inode *, struct file *);
...@@ -47,7 +45,7 @@ static void ext2_release_file (struct inode *, struct file *); ...@@ -47,7 +45,7 @@ static void ext2_release_file (struct inode *, struct file *);
*/ */
static struct file_operations ext2_file_operations = { static struct file_operations ext2_file_operations = {
NULL, /* lseek - default */ NULL, /* lseek - default */
ext2_file_read, /* read */ generic_file_read, /* read */
ext2_file_write, /* write */ ext2_file_write, /* write */
NULL, /* readdir - bad */ NULL, /* readdir - bad */
NULL, /* select - default */ NULL, /* select - default */
...@@ -74,7 +72,7 @@ struct inode_operations ext2_file_inode_operations = { ...@@ -74,7 +72,7 @@ struct inode_operations ext2_file_inode_operations = {
NULL, /* rename */ NULL, /* rename */
NULL, /* readlink */ NULL, /* readlink */
NULL, /* follow_link */ NULL, /* follow_link */
ext2_readpage, /* readpage */ generic_readpage, /* readpage */
NULL, /* writepage */ NULL, /* writepage */
ext2_bmap, /* bmap */ ext2_bmap, /* bmap */
ext2_truncate, /* truncate */ ext2_truncate, /* truncate */
...@@ -82,120 +80,6 @@ struct inode_operations ext2_file_inode_operations = { ...@@ -82,120 +80,6 @@ struct inode_operations ext2_file_inode_operations = {
NULL /* smap */ NULL /* smap */
}; };
static int ext2_readpage(struct inode * inode, unsigned long offset, char * page)
{
int *p, nr[PAGE_SIZE/512];
int i;
i = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
offset >>= inode->i_sb->s_blocksize_bits;
p = nr;
do {
*p = ext2_bmap(inode, offset);
i--;
offset++;
p++;
} while (i > 0);
return bread_page((unsigned long) page, inode->i_dev, nr, inode->i_sb->s_blocksize);
}
/*
* This is a generic file read routine, and uses the
* inode->i_op->readpage() function for the actual low-level
* stuff. We can put this into the other filesystems too
* once we've debugged it a bit more.
*/
static int ext2_file_read (struct inode * inode, struct file * filp,
char * buf, int count)
{
int read = 0;
unsigned long pos;
unsigned long addr;
unsigned long cached_page = 0;
struct page *page;
if (count <= 0)
return 0;
pos = filp->f_pos;
for (;;) {
unsigned long offset, nr;
if (pos >= inode->i_size)
break;
offset = pos & ~PAGE_MASK;
nr = PAGE_SIZE - offset;
if (nr > count)
nr = count;
/* is it already cached? */
page = find_page(inode, pos & PAGE_MASK);
if (page)
goto found_page;
/* not cached, have to read it in.. */
if (!(addr = cached_page)) {
addr = cached_page = __get_free_page(GFP_KERNEL);
if (!addr) {
if (!read)
read = -ENOMEM;
break;
}
}
inode->i_op->readpage(inode, pos & PAGE_MASK, (char *) addr);
/* while we did that, things may have changed.. */
if (pos >= inode->i_size)
break;
page = find_page(inode, pos & PAGE_MASK);
if (page)
goto found_page;
/* nope, this is the only copy.. */
cached_page = 0;
page = mem_map + MAP_NR(addr);
page->offset = pos & PAGE_MASK;
add_page_to_inode_queue(inode, page);
add_page_to_hash_queue(inode, page);
found_page:
if (nr > inode->i_size - pos)
nr = inode->i_size - pos;
page->count++;
addr = page_address(page);
memcpy_tofs(buf, (void *) (addr + offset), nr);
free_page(addr);
buf += nr;
pos += nr;
read += nr;
count -= nr;
if (!count)
break;
}
filp->f_pos = pos;
if (cached_page)
free_page(cached_page);
if (!IS_RDONLY(inode)) {
inode->i_atime = CURRENT_TIME;
inode->i_dirt = 1;
}
return read;
}
static inline void update_vm_cache(struct inode * inode, unsigned long pos,
char * buf, int count)
{
struct page * page;
page = find_page(inode, pos & PAGE_MASK);
if (page) {
pos = (pos & ~PAGE_MASK) + page_address(page);
memcpy((void *) pos, buf, count);
}
}
static int ext2_file_write (struct inode * inode, struct file * filp, static int ext2_file_write (struct inode * inode, struct file * filp,
const char * buf, int count) const char * buf, int count)
{ {
......
...@@ -464,7 +464,7 @@ struct inode * ext2_new_inode (const struct inode * dir, int mode, int * err) ...@@ -464,7 +464,7 @@ struct inode * ext2_new_inode (const struct inode * dir, int mode, int * err)
inode->i_gid = current->fsgid; inode->i_gid = current->fsgid;
inode->i_dirt = 1; inode->i_dirt = 1;
inode->i_ino = j; inode->i_ino = j;
inode->i_blksize = sb->s_blocksize; inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size (for stat), not the fs block size */
inode->i_blocks = 0; inode->i_blocks = 0;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->u.ext2_i.i_flags = dir->u.ext2_i.i_flags; inode->u.ext2_i.i_flags = dir->u.ext2_i.i_flags;
......
...@@ -533,7 +533,7 @@ void ext2_read_inode (struct inode * inode) ...@@ -533,7 +533,7 @@ void ext2_read_inode (struct inode * inode)
inode->i_ctime = raw_inode->i_ctime; inode->i_ctime = raw_inode->i_ctime;
inode->i_mtime = raw_inode->i_mtime; inode->i_mtime = raw_inode->i_mtime;
inode->u.ext2_i.i_dtime = raw_inode->i_dtime; inode->u.ext2_i.i_dtime = raw_inode->i_dtime;
inode->i_blksize = inode->i_sb->s_blocksize; inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size (for stat), not the fs block size */
inode->i_blocks = raw_inode->i_blocks; inode->i_blocks = raw_inode->i_blocks;
inode->i_version = ++event; inode->i_version = ++event;
inode->u.ext2_i.i_flags = raw_inode->i_flags; inode->u.ext2_i.i_flags = raw_inode->i_flags;
......
...@@ -175,7 +175,7 @@ static const struct inode_operations hpfs_file_iops = ...@@ -175,7 +175,7 @@ static const struct inode_operations hpfs_file_iops =
NULL, /* rename */ NULL, /* rename */
NULL, /* readlink */ NULL, /* readlink */
NULL, /* follow_link */ NULL, /* follow_link */
NULL, /* readpage */ generic_readpage, /* readpage */
NULL, /* writepage */ NULL, /* writepage */
(int (*)(struct inode *, int)) (int (*)(struct inode *, int))
&hpfs_bmap, /* bmap */ &hpfs_bmap, /* bmap */
......
...@@ -306,14 +306,22 @@ void inode_setattr(struct inode *inode, struct iattr *attr) ...@@ -306,14 +306,22 @@ void inode_setattr(struct inode *inode, struct iattr *attr)
* notify_change is called for inode-changing operations such as * notify_change is called for inode-changing operations such as
* chown, chmod, utime, and truncate. It is guaranteed (unlike * chown, chmod, utime, and truncate. It is guaranteed (unlike
* write_inode) to be called from the context of the user requesting * write_inode) to be called from the context of the user requesting
* the change. It is not called for ordinary access-time updates. * the change.
* NFS uses this to get the authentication correct. -- jrs
*/ */
int notify_change(struct inode * inode, struct iattr *attr) int notify_change(struct inode * inode, struct iattr *attr)
{ {
int retval; int retval;
if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME)) {
unsigned long now = CURRENT_TIME;
if (!(attr->ia_valid & ATTR_ATIME_SET))
attr->ia_atime = now;
if (!(attr->ia_valid & ATTR_MTIME_SET))
attr->ia_mtime = now;
attr->ia_ctime = now;
}
if (inode->i_sb && inode->i_sb->s_op && if (inode->i_sb && inode->i_sb->s_op &&
inode->i_sb->s_op->notify_change) inode->i_sb->s_op->notify_change)
return inode->i_sb->s_op->notify_change(inode, attr); return inode->i_sb->s_op->notify_change(inode, attr);
......
...@@ -15,27 +15,16 @@ ...@@ -15,27 +15,16 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/locks.h> #include <linux/locks.h>
#include <asm/segment.h>
#include <asm/system.h>
#define NBUF 32
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/iso_fs.h> #include <linux/iso_fs.h>
static int isofs_file_read(struct inode *, struct file *, char *, int);
/* /*
* We have mostly NULL's here: the current defaults are ok for * We have mostly NULL's here: the current defaults are ok for
* the isofs filesystem. * the isofs filesystem.
*/ */
static struct file_operations isofs_file_operations = { static struct file_operations isofs_file_operations = {
NULL, /* lseek - default */ NULL, /* lseek - default */
isofs_file_read, /* read */ generic_file_read, /* read */
NULL, /* write */ NULL, /* write */
NULL, /* readdir - bad */ NULL, /* readdir - bad */
NULL, /* select - default */ NULL, /* select - default */
...@@ -59,202 +48,9 @@ struct inode_operations isofs_file_inode_operations = { ...@@ -59,202 +48,9 @@ struct inode_operations isofs_file_inode_operations = {
NULL, /* rename */ NULL, /* rename */
NULL, /* readlink */ NULL, /* readlink */
NULL, /* follow_link */ NULL, /* follow_link */
NULL, /* readpage */ generic_readpage, /* readpage */
NULL, /* writepage */ NULL, /* writepage */
isofs_bmap, /* bmap */ isofs_bmap, /* bmap */
NULL, /* truncate */ NULL, /* truncate */
NULL /* permission */ NULL /* permission */
}; };
/* This is a heuristic to determine if a file is text of binary. If it
* is text, then we translate all 0x0d characters to spaces. If the 0x0d
* character is not preceded or followed by a 0x0a, then we turn it into
* a 0x0a. A control-Z is also turned into a linefeed.
*/
static inline void unixify_to_fs(char * outbuf, char * buffer, int chars,
int mode)
{
char outchar;
while(chars--){
outchar = *buffer;
if(outchar == 0x1a) outchar = 0x0a;
if(outchar == 0x0d){
if(mode == ISOFS_FILE_TEXT_M) outchar = 0x0a;
if(mode == ISOFS_FILE_TEXT) outchar = ' ';
}
put_user(outchar, outbuf++);
buffer++;
}
}
/*This function determines if a given file has a DOS-like text format or not*/
static void isofs_determine_filetype(struct inode * inode)
{
int block;
int result, i;
struct buffer_head * bh;
unsigned char * pnt;
block = isofs_bmap(inode,0);
if (block && (bh = bread(inode->i_dev,block, ISOFS_BUFFER_SIZE(inode)))) {
pnt = (unsigned char *) bh->b_data;
result = ISOFS_FILE_TEXT_M;
for(i=0;i<(inode->i_size < ISOFS_BUFFER_SIZE(inode) ? inode->i_size : ISOFS_BUFFER_SIZE(inode));
i++,pnt++){
if(*pnt & 0x80) {result = ISOFS_FILE_BINARY; break;};
if(*pnt >= 0x20 || *pnt == 0x1a) continue;
if(*pnt == 0x0a) {result = ISOFS_FILE_TEXT; continue;};
if(*pnt >= 0x9 && *pnt <= 0x0d) continue;
result = ISOFS_FILE_BINARY;
break;
}
brelse(bh);
inode->u.isofs_i.i_file_format = result;
}
}
static int isofs_file_read(struct inode * inode, struct file * filp, char * buf, int count)
{
int read,left,chars;
int block, blocks, offset, total_blocks;
int bhrequest;
int ra_blocks, max_block, nextblock;
struct buffer_head ** bhb, ** bhe;
struct buffer_head * bhreq[NBUF];
struct buffer_head * buflist[NBUF];
if (!inode) {
printk("isofs_file_read: inode = NULL\n");
return -EINVAL;
}
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
printk("isofs_file_read: mode = %07o\n",inode->i_mode);
return -EINVAL;
}
if (inode->u.isofs_i.i_file_format == ISOFS_FILE_UNKNOWN)
isofs_determine_filetype(inode);
if (filp->f_pos > inode->i_size)
left = 0;
else
left = inode->i_size - filp->f_pos;
if (left > count)
left = count;
if (left <= 0)
return 0;
read = 0;
block = filp->f_pos >> ISOFS_BUFFER_BITS(inode);
offset = (inode->u.isofs_i.i_first_extent + filp->f_pos)
& (ISOFS_BUFFER_SIZE(inode)-1);
blocks = (left + offset + ISOFS_BUFFER_SIZE(inode) - 1) / ISOFS_BUFFER_SIZE(inode);
bhb = bhe = buflist;
ra_blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
if(ra_blocks > blocks) blocks = ra_blocks;
/*
* this is for stopping read ahead at EOF. It's important for
* reading PhotoCD's, because they have many small data tracks instead
* of one big. And between two data-tracks are some unreadable sectors.
* A read ahead after a EOF may try to read such an unreadable sector.
* kraxel@cs.tu-berlin.de (Gerd Knorr)
*/
total_blocks = (inode->i_size + (1 << ISOFS_BUFFER_BITS(inode)) - 1)
>> ISOFS_BUFFER_BITS(inode);
if (block + blocks > total_blocks)
blocks = total_blocks - block;
max_block = (inode->i_size + BLOCK_SIZE - 1)/BLOCK_SIZE;
nextblock = -1;
/* We do this in a two stage process. We first try and request
as many blocks as we can, then we wait for the first one to
complete, and then we try and wrap up as many as are actually
done. This routine is rather generic, in that it can be used
in a filesystem by substituting the appropriate function in
for getblk.
This routine is optimized to make maximum use of the various
buffers and caches. */
do {
bhrequest = 0;
while (blocks) {
int uptodate;
--blocks;
*bhb = getblk(inode->i_dev,isofs_bmap(inode, block++), ISOFS_BUFFER_SIZE(inode));
uptodate = 1;
if (*bhb && !buffer_uptodate(*bhb)) {
uptodate = 0;
bhreq[bhrequest++] = *bhb;
};
if (++bhb == &buflist[NBUF])
bhb = buflist;
/* If the block we have on hand is uptodate, go ahead
and complete processing. */
if(uptodate) break;
if (bhb == bhe)
break;
}
/* Now request them all */
if (bhrequest)
ll_rw_block(READ, bhrequest, bhreq);
do{ /* Finish off all I/O that has actually completed */
if (*bhe) {/* test for valid buffer */
wait_on_buffer(*bhe);
if (!buffer_uptodate(*bhe)) {
brelse(*bhe);
if (++bhe == &buflist[NBUF])
bhe = buflist;
left = 0;
break;
}
}
if (left < ISOFS_BUFFER_SIZE(inode) - offset)
chars = left;
else
chars = ISOFS_BUFFER_SIZE(inode) - offset;
filp->f_pos += chars;
left -= chars;
read += chars;
if (*bhe) {
if (inode->u.isofs_i.i_file_format == ISOFS_FILE_TEXT ||
inode->u.isofs_i.i_file_format == ISOFS_FILE_TEXT_M)
unixify_to_fs(buf, offset+(*bhe)->b_data, chars,
inode->u.isofs_i.i_file_format);
else
memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
brelse(*bhe);
buf += chars;
} else {
while (chars-->0)
put_user(0,buf++);
}
offset = 0;
if (++bhe == &buflist[NBUF])
bhe = buflist;
} while( bhe != bhb && (*bhe == 0 || !buffer_locked(*bhe)) &&
(left > 0));
} while (left > 0);
/* Release the read-ahead blocks */
while (bhe != bhb) {
if (*bhe) brelse(*bhe);
if (++bhe == &buflist[NBUF])
bhe = buflist;
};
filp->f_reada = 1;
if (!read)
return -EIO;
return read;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -441,6 +441,7 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo ...@@ -441,6 +441,7 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo
} }
skb->dev = dev; skb->dev = dev;
skb->protocol = htons(ETH_P_ATALK);
hash=sa->s_node%(AARP_HASH_SIZE-1); hash=sa->s_node%(AARP_HASH_SIZE-1);
save_flags(flags); save_flags(flags);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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