]> git.neil.brown.name Git - history.git/commitdiff
Import 1.1.2 1.1.2
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:27 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:27 +0000 (15:09 -0500)
70 files changed:
CREDITS
Makefile
README
drivers/block/hd.c
drivers/block/ramdisk.c
drivers/block/xd.c
drivers/char/keyboard.c
drivers/net/3c503.c
drivers/net/3c507.c
drivers/net/depca.c
drivers/net/depca.h
drivers/net/eexpress.c
drivers/net/net_init.c
drivers/scsi/scsi.c
drivers/scsi/scsi.h
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_debug.h
drivers/scsi/scsi_ioctl.c
drivers/scsi/scsi_ioctl.h
drivers/scsi/sd.c
drivers/scsi/sd_ioctl.c
drivers/scsi/sr.c
drivers/scsi/sr_ioctl.c
drivers/sound/os.h
fs/block_dev.c
fs/buffer.c
fs/ext/file.c
fs/ext/freelists.c
fs/ext/inode.c
fs/ext/namei.c
fs/ext/truncate.c
fs/ext2/balloc.c
fs/ext2/file.c
fs/ext2/ialloc.c
fs/ext2/inode.c
fs/ext2/namei.c
fs/ext2/super.c
fs/ext2/truncate.c
fs/hpfs/hpfs_fs.c
fs/isofs/dir.c
fs/isofs/file.c
fs/isofs/inode.c
fs/isofs/rock.c
fs/minix/bitmap.c
fs/minix/file.c
fs/minix/inode.c
fs/minix/namei.c
fs/minix/truncate.c
fs/msdos/fat.c
fs/msdos/file.c
fs/msdos/inode.c
fs/msdos/misc.c
fs/msdos/namei.c
fs/sysv/balloc.c
fs/sysv/file.c
fs/sysv/ialloc.c
fs/sysv/inode.c
fs/sysv/namei.c
fs/sysv/truncate.c
fs/xiafs/bitmap.c
fs/xiafs/file.c
fs/xiafs/inode.c
fs/xiafs/namei.c
fs/xiafs/truncate.c
include/linux/fs.h
kernel/ksyms.c
mm/memory.c
net/inet/icmp.c
net/inet/ip.c
net/inet/skbuff.c

diff --git a/CREDITS b/CREDITS
index 541d5508e59ede2dd11e5c70911e1f87681793d6..4368680baab51451307ea6c133034d070f62d976 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -351,6 +351,13 @@ S: 249 Nichols Avenue
 S: Syracuse, New York 13206
 S: USA
 
+N: Dirk Melchers
+E: dirk@merlin.nbg.sub.org
+D: 8 bit XT hard disk driver for OMTI5520
+S: Branderweg 4
+S: D-91058 Erlangen
+S: Germany
+
 N: Craig Metz
 E: cmetz@tjhsst.edu
 D: Some of PAS 16 mixer & PCM support
index e7ff908cbc46b2eaa0f56c04e6c0654f879197b2..c06f8b79d3bbbf615f83fb3972398001053124c7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 1
+SUBLEVEL = 2
 
 all:   Version zImage
 
@@ -9,7 +9,7 @@ all:    Version zImage
 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
          else if [ -x /bin/bash ]; then echo /bin/bash; \
          else echo sh; fi ; fi)
-ROOT   := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
+TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
 
 #
 # Make "config" the default target if there is no configuration file or
@@ -77,7 +77,7 @@ AS    =as
 LD     =ld
 LDFLAGS        =#-qmagic
 HOSTCC =gcc
-CC     =gcc -D__KERNEL__ -I$(ROOT)/include
+CC     =gcc -D__KERNEL__ -I$(TOPDIR)/include
 MAKE   =make
 CPP    =$(CC) -E
 AR     =ar
diff --git a/README b/README
index 5bea132584032af1009917ac7ddf1c6ee02e8e11..f6be4bede22b50e95f3202cb359d403c63e8937c 100644 (file)
--- a/README
+++ b/README
@@ -81,9 +81,6 @@ CONFIGURING the kernel:
          should probably answer 'n' to the questions for a "production"
          kernel. 
 
- - edit drivers/net/CONFIG to configure the networking parts of the
-   kernel.  The comments should hopefully clarify it all. 
-
  - Check the top Makefile for further site-dependent configuration
    (default SVGA mode etc). 
 
index c26348f0e37b2d6c3c421b06f8067ae921c2cd85..564dc99b9220cc3e4cd50fdedb4521321d3156ed 100644 (file)
@@ -542,6 +542,12 @@ static int hd_ioctl(struct inode * inode, struct file * file,
                        put_fs_long(hd[MINOR(inode->i_rdev)].start_sect,
                                (long *) &loc->start);
                        return 0;
+               case BLKRASET:
+                       if(!suser())  return -EACCES;
+                       if(!inode->i_rdev) return -EINVAL;
+                       if(arg > 0xff) return -EINVAL;
+                       read_ahead[MAJOR(inode->i_rdev)] = arg;
+                       return 0;
                case BLKGETSIZE:   /* Return device size */
                        if (!arg)  return -EINVAL;
                        err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
index 4904409df1d3a6e5b62a89ee748faed7ad5e8f5d..0a13e7a586c0feec7bbd11a36b34fc1733612c6a 100644 (file)
@@ -126,7 +126,7 @@ void rd_load(void)
         */
        for (tries = 0; tries < 1000; tries += 512) {
                block = tries;
-               bh = breada(ROOT_DEV,block+1,block,block+2,-1);
+               bh = breada(ROOT_DEV,block+1,BLOCK_SIZE, 0,  PAGE_SIZE);
                if (!bh) {
                        printk("RAMDISK: I/O error while looking for super block!\n");
                        return;
@@ -154,7 +154,7 @@ void rd_load(void)
                cp = rd_start;
                while (nblocks) {
                        if (nblocks > 2) 
-                               bh = breada(ROOT_DEV, block, block+1, block+2, -1);
+                               bh = breada(ROOT_DEV, block, BLOCK_SIZE, 0,  PAGE_SIZE);
                        else
                                bh = bread(ROOT_DEV, block, BLOCK_SIZE);
                        if (!bh) {
index bc5258c52bc34237d088519c65c853b7e83c2792..973a902641adae1500d49e60ac6a5cb8ca84f2c7 100644 (file)
@@ -252,6 +252,12 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
                                        return (0);
                                }
                                break;
+                       case BLKRASET:
+                         if(!suser())  return -EACCES;
+                         if(!inode->i_rdev) return -EINVAL;
+                         if(arg > 0xff) return -EINVAL;
+                         read_ahead[MAJOR(inode->i_rdev)] = arg;
+                         return 0;
                        case BLKGETSIZE:
                                if (arg) {
                                        if ((err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long))))
index cec544913386d0d07a657d41bfc600e5b358456c..57425762c279d032bea600abdb08fe99a14a20e7 100644 (file)
@@ -85,7 +85,7 @@ static int want_console = -1;
 static int last_console = 0;           /* last used VC */
 static int dead_key_next = 0;
 static int shift_state = 0;
-static int npadch = -1;                        /* -1 or number assembled on pad */
+static int npadch = -1;                        /* -1 or number assembled on pad */
 static unsigned char diacr = 0;
 static char rep = 0;                   /* flag telling character repeat */
 struct kbd_struct kbd_table[NR_CONSOLES];
@@ -100,7 +100,7 @@ typedef void (*k_hand)(unsigned char value, char up_flag);
 typedef void (k_handfn)(unsigned char value, char up_flag);
 
 static k_handfn
-        do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
+       do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
        do_meta, do_ascii, do_lock, do_lowercase;
 
 static k_hand key_handler[] = {
@@ -196,7 +196,7 @@ static void keyboard_interrupt(int int_pt_regs)
 {
        unsigned char scancode;
        static unsigned int prev_scancode = 0;   /* remember E0, E1 */
-       char up_flag;                            /* 0 or 0200 */
+       char up_flag;                            /* 0 or 0200 */
        char raw_mode;
 
        pt_regs = (struct pt_regs *) int_pt_regs;
@@ -214,15 +214,15 @@ static void keyboard_interrupt(int int_pt_regs)
                goto end_kbd_intr;
        } else if (scancode == 0) {
 #ifdef KBD_REPORT_ERR
-               printk("keyboard buffer overflow\n");
+               printk("keyboard buffer overflow\n");
 #endif
                goto end_kbd_intr;
        } else if (scancode == 0xff) {
 #ifdef KBD_REPORT_ERR
-               printk("keyboard error\n");
+               printk("keyboard error\n");
 #endif
-               prev_scancode = 0;
-               goto end_kbd_intr;
+               prev_scancode = 0;
+               goto end_kbd_intr;
        }
        tty = TTY_TABLE(0);
        kbd = kbd_table + fg_console;
@@ -242,7 +242,7 @@ static void keyboard_interrupt(int int_pt_regs)
         */
        up_flag = (scancode & 0200);
        scancode &= 0x7f;
-  
+
        if (prev_scancode) {
          /*
           * usually it will be 0xe0, but a Pause key generates
@@ -294,7 +294,7 @@ static void keyboard_interrupt(int int_pt_regs)
 #endif
          goto end_kbd_intr;
        }
-  
+
        /*
         * At this point the variable `scancode' contains the keysym.
         * We keep track of the up/down status of the key, and
@@ -308,15 +308,15 @@ static void keyboard_interrupt(int int_pt_regs)
                rep = 0;
        } else
                rep = set_bit(scancode, key_down);
-  
+
        if (raw_mode)
-               goto end_kbd_intr;
+               goto end_kbd_intr;
 
        if (vc_kbd_mode(kbd, VC_MEDIUMRAW)) {
                put_queue(scancode + up_flag);
                goto end_kbd_intr;
        }
-  
+
        /*
         * Small change in philosophy: earlier we defined repetition by
         *       rep = scancode == prev_keysym;
@@ -330,7 +330,7 @@ static void keyboard_interrupt(int int_pt_regs)
         *  characters get echoed locally. This makes key repeat usable
         *  with slow applications and under heavy loads.
         */
-       if (!rep || 
+       if (!rep ||
            (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
             (L_ECHO(tty) || (EMPTY(&tty->secondary) && EMPTY(&tty->read_q)))))
        {
@@ -499,7 +499,7 @@ static void boot_it(void)
 
 static void compose(void)
 {
-        dead_key_next = 1;
+       dead_key_next = 1;
 }
 
 static void do_spec(unsigned char value, char up_flag)
@@ -523,22 +523,22 @@ static void do_spec(unsigned char value, char up_flag)
 
 static void do_lowercase(unsigned char value, char up_flag)
 {
-        printk("keyboard.c: do_lowercase was called - impossible\n");
+       printk("keyboard.c: do_lowercase was called - impossible\n");
 }
-  
+
 static void do_self(unsigned char value, char up_flag)
 {
        if (up_flag)
                return;         /* no action, if this is a key release */
 
-        if (diacr)
-                value = handle_diacr(value);
+       if (diacr)
+               value = handle_diacr(value);
 
-        if (dead_key_next) {
-                dead_key_next = 0;
-                diacr = value;
-                return;
-        }
+       if (dead_key_next) {
+               dead_key_next = 0;
+               diacr = value;
+               return;
+       }
 
        put_queue(value);
 }
@@ -549,7 +549,7 @@ static void do_self(unsigned char value, char up_flag)
 #define A_TILDE  '~'
 #define A_DIAER  '"'
 static unsigned char ret_diacr[] =
-        {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
+       {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
 
 /* If a dead key pressed twice, output a character corresponding to it,        */
 /* otherwise just remember the dead key.                               */
@@ -559,12 +559,12 @@ static void do_dead(unsigned char value, char up_flag)
        if (up_flag)
                return;
 
-        value = ret_diacr[value];
-        if (diacr == value) {   /* pressed twice */
-                diacr = 0;
-                put_queue(value);
-                return;
-        }
+       value = ret_diacr[value];
+       if (diacr == value) {   /* pressed twice */
+               diacr = 0;
+               put_queue(value);
+               return;
+       }
        diacr = value;
 }
 
@@ -574,19 +574,20 @@ static void do_dead(unsigned char value, char up_flag)
 
 unsigned char handle_diacr(unsigned char ch)
 {
-        int d = diacr;
-        int i;
+       int d = diacr;
+       int i;
 
-        diacr = 0;
-        if (ch == ' ')
-                return d;
+       diacr = 0;
+       if (ch == ' ')
+               return d;
 
-        for (i = 0; i < accent_table_size; i++)
-          if(accent_table[i].diacr == d && accent_table[i].base == ch)
-            return accent_table[i].result;
+       for (i = 0; i < accent_table_size; i++) {
+               if (accent_table[i].diacr == d && accent_table[i].base == ch)
+                       return accent_table[i].result;
+       }
 
-        put_queue(d);
-        return ch;
+       put_queue(d);
+       return ch;
 }
 
 static void do_cons(unsigned char value, char up_flag)
@@ -601,9 +602,9 @@ static void do_fn(unsigned char value, char up_flag)
        if (up_flag)
                return;
        if (value < SIZE(func_table))
-               puts_queue(func_table[value]);
+               puts_queue(func_table[value]);
        else
-               printk("do_fn called with value=%d\n", value);
+               printk("do_fn called with value=%d\n", value);
 }
 
 static void do_pad(unsigned char value, char up_flag)
@@ -686,7 +687,7 @@ static void do_shift(unsigned char value, char up_flag)
        }
 
        if (up_flag) {
-               /* handle the case that two shift or control
+               /* handle the case that two shift or control
                   keys are depressed simultaneously */
                if (k_down[value])
                        k_down[value]--;
@@ -709,9 +710,9 @@ static void do_shift(unsigned char value, char up_flag)
    recompute k_down[] and shift_state from key_down[] */
 void compute_shiftstate(void)
 {
-        int i, j, k, sym, val;
+       int i, j, k, sym, val;
 
-        shift_state = 0;
+       shift_state = 0;
        for(i=0; i < SIZE(k_down); i++)
          k_down[i] = 0;
 
@@ -725,7 +726,7 @@ void compute_shiftstate(void)
                  val = KVAL(sym);
                  k_down[val]++;
                  shift_state |= (1<<val);
-               }
+               }
              }
          }
 }
@@ -748,9 +749,9 @@ static void do_ascii(unsigned char value, char up_flag)
                return;
 
        if (npadch == -1)
-               npadch = value;
+               npadch = value;
        else
-               npadch = (npadch * 10 + value) % 1000;
+               npadch = (npadch * 10 + value) % 1000;
 }
 
 static void do_lock(unsigned char value, char up_flag)
index f46f3b13f0e304e20bea4e25a423994e7256ba77..6e5ef8ddd647a1db68121c28de6eca8828062a7f 100644 (file)
@@ -22,6 +22,7 @@ static char *version =
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
+#include <linux/string.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
index 4c6221e979e3466dd7f571ba5c6d563545733490..cdf16cd93360d45e8e45821bad6cbccc4fa355bb 100644 (file)
@@ -44,12 +44,12 @@ static char *version =
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
+#include <linux/string.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
-#include <errno.h>
-#include <memory.h>
+#include <linux/errno.h>
 
 #include "dev.h"
 #include "eth.h"
index 31781596d35713f5eae424dadfc7dae64547a797..2c996a8bd52462c60fe762d4b2eb71464f4bdc06 100644 (file)
@@ -1,24 +1,34 @@
-/*  depca.c: A DIGITAL DEPCA ethernet driver for linux.
+/*  depca.c: A DIGITAL DEPCA  & EtherWORKS ethernet driver for linux.
 
     Written 1994 by David C. Davies.
 
-    Copyright 1994 David C. Davies and United States Government as
-    represented by the Director, National Security Agency.  This software
-    may be used and distributed according to the terms of the GNU Public
-    License, incorporated herein by reference.
+
+                      Copyright 1994 David C. Davies
+                                  and 
+                        United States Government
+        (as represented by the Director, National Security Agency).  
+
+
+    This software may be used and distributed according to the terms of
+    the GNU Public License, incorporated herein by reference.
 
     This driver is written for the Digital Equipment Corporation series
-    of DEPCA ethernet cards:
+    of DEPCA and EtherWORKS ethernet cards:
 
-       DE100 DEPCA
-       DE200 DEPCA Turbo
-       DE202 DEPCA Turbo (TP BNC)
-       DE210 DEPCA
+        DEPCA       (the original)
+       DE100
+       DE200 Turbo
+       DE201 Turbo
+       DE202 Turbo (TP BNC)
+       DE210
 
-    The driver has been tested on DE100 and DE20x cards in a relatively busy 
-    network.
+    The  driver has been tested on DE100, DE200 and DE202 cards  in  a
+    relatively busy network.
 
-    The author may be reached as davies@wanton.enet.dec.com or
+    This driver  will  not work  for the DE203,  DE204  and DE205 series  of
+    cards, since they have a new custom ASIC in place of the AMD LANCE chip.
+
+    The author may be reached as davies@wanton.lkg.dec.com or
     Digital Equipment Corporation, 146 Main Street, Maynard MA 01754.
 
     =========================================================================
     the   filter bit   positions  correctly.  Hash   filtering  is  not  yet
     implemented in the current driver set.
 
-    The  DE200 series boards have   on-board 64kB RAM  for  use as a  shared
-    memory network buffer. Only  the DE100 cards  make  use of a  2kB buffer
-    mode  which has not  been implemented in  this driver (only the 32kB and
-    64kB modes are supported).
+    The original DEPCA  card requires that  the ethernet ROM address counter
+    be enabled to count and has an 8 bit NICSR.  The ROM counter enabling is
+    only done when  a 0x08 is read as  the first address octet  (to minimise
+    the chances of  writing over some other hardware's  I/O  register).  The
+    size of the NICSR is tested by a word read: if  both bytes are the same,
+    the register  is 8 bits wide.   Also,  there is a   maximum of only 48kB
+    network  RAM for   this card.  My   thanks  to Torbjorn Lindh   for help
+    debugging all this  (and holding  my  feet to the   fire until I got  it
+    right).
+
+    The DE200  series  boards have  on-board 64kB  RAM for  use  as a shared
+    memory network  buffer. Only the DE100  cards make use  of a  2kB buffer
+    mode which has not  been implemented in  this driver (only the 32kB  and
+    64kB modes are supported [16kB/48kB for the original DEPCA]).
 
     At the  most only 2 DEPCA  cards can be supported  because there is only
     provision for two I/O base addresses on the cards (0x300 and 0x200). The
     this unambiguously at the moment, since there is nothing on the cards to
     tie I/O and memory information together.
 
-    I   am unable to test    2 DEPCAs together for   now,   so this code  is
+    I am unable  to  test  2 cards   together for now,    so this  code   is
     unchecked. All reports, good or bad, are welcome.
 
     ************************************************************************
 
-    The board IRQ  setting must be  at  an unused  IRQ  which is auto-probed
-    using   Donald Becker's   autoprobe   routines. DE100   board IRQs   are
-    {2,3,4,5,7}, whereas  the DE200 is at  {5,9,10,11,15}. Note that IRQ2 is
+    The board IRQ   setting must be  at an  unused IRQ which  is auto-probed
+    using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are
+    {2,3,4,5,7}, whereas the  DE200 is at {5,9,10,11,15}.  Note that IRQ2 is
     really IRQ9 in machines with 16 IRQ lines.
 
     No 16MB memory  limitation should exist with this  driver as DMA is  not
     used and the common memory area is in low memory on the network card (my
     current system has 20MB and I've not had problems yet).
 
-    The DE203,  DE204  and DE205 cards  may  also work  with this driver  (I
-    haven't tested  them so I don't  know). If you have  one of these cards,
-    place the name in the DEPCA_SIGNATURE string  around line 160, recompile
-    the kernel and reboot. Check if the card  is recognised and works - mail
-    me if so, so that I can add it into the list of supported cards!
-
     TO DO:
     ------
 
 
     Version   Date        Description
   
-      0.1   25-jan-94     Initial writing
-      0.2   27-jan-94     Added LANCE TX buffer chaining
-      0.3    1-feb-94     Added multiple DEPCA support
-      0.31   4-feb-94     Added DE202 recognition
+      0.1   25-jan-94     Initial writing.
+      0.2   27-jan-94     Added LANCE TX buffer chaining.
+      0.3    1-feb-94     Added multiple DEPCA support.
+      0.31   4-feb-94     Added DE202 recognition.
       0.32  19-feb-94     Tidy up. Improve multi-DEPCA support.
+      0.33  25-feb-94     Fix DEPCA ethernet ROM counter enable.
+                          Add jabber packet fix from murf@perftech.com
+                         and becker@super.org
+      0.34   7-mar-94     Fix DEPCA max network memory RAM & NICSR access.
+      0.35   8-mar-94     Added DE201 recognition.
 
     =========================================================================
 */
 
-static char *version = "depca.c:v0.32 2/19/94 davies@wanton.enet.dec.com\n";
+static char *version = "depca.c:v0.35 3/8/94 davies@wanton.lkg.dec.com\n";
 
 #include <stdarg.h>
 #include <linux/config.h>
@@ -129,7 +148,7 @@ static char *version = "depca.c:v0.32 2/19/94 davies@wanton.enet.dec.com\n";
 #include <asm/dma.h>
 
 #include "dev.h"
-#include "iow.h"
+#include "iow.h"                    /* left in for pl13/14 compatibility... */
 #include "eth.h"
 #include "skbuff.h"
 #include "arp.h"
@@ -155,7 +174,7 @@ int depca_debug = 1;
 #endif
 
 #ifndef DEPCA_SIGNATURE
-#define DEPCA_SIGNATURE {"DEPCA","DE100","DE200","DE202","DE210",""}
+#define DEPCA_SIGNATURE {"DEPCA","DE100","DE200","DE201","DE202","DE210",""}
 #define DEPCA_NAME_LENGTH 8
 #endif
 
@@ -241,7 +260,7 @@ struct depca_private {
     int dirty_rx, dirty_tx;    /* The ring entries to be free()ed. */
     int dma;
     struct enet_statistics stats;
-    char old_depca;
+    char depca_na;              /* NICSR access width: 0=>byte, 1=>word */
     short ringSize;             /* ring size based on available memory */
     short rmask;                /* modulus mask based on ring size */
     long rlen;                  /* log2(ringSize) for the descriptors */
@@ -275,6 +294,7 @@ static int DevicePresent(short ioaddr);
 static void SetMulticastFilter(int num_addrs, char *addrs, char *multicast_table);
 #endif
 
+static int depca_na;
 static int num_depcas = 0, num_eth = 0;;
 
 /*
@@ -284,6 +304,21 @@ static int num_depcas = 0, num_eth = 0;;
     outw(CSR0, DEPCA_ADDR);\
     outw(STOP, DEPCA_DATA)
 
+#define GET_NICSR(a,b) \
+    if (depca_na) { \
+      (a) = inw((b)); \
+    } else { \
+      (a) = inb((b)); \
+    }
+
+#define PUT_NICSR(a,b) \
+    if (depca_na) { \
+      outw((a), (b)); \
+    } else { \
+      outb((a), (b)); \
+    }
+
+
 \f
 
 int depca_probe(struct device *dev)
@@ -294,7 +329,10 @@ int depca_probe(struct device *dev)
     struct device *eth0 = (struct device *) NULL;
 
     if (base_addr > 0x1ff) {         /* Check a single specified location. */
-               status = depca_probe1(dev, base_addr);
+      status = -ENODEV;
+      if (DevicePresent(base_addr) == 0) { /* Is DEPCA really here? */
+       status = depca_probe1(dev, base_addr);
+      }
     } else if (base_addr > 0) {              /* Don't probe at all. */
                status = -ENXIO;
     } else {                          /* First probe for the DEPCA test */
@@ -308,7 +346,7 @@ int depca_probe(struct device *dev)
        if (check_region(ioaddr, DEPCA_TOTAL_SIZE))
            continue;
 #endif
-       if (DevicePresent(DEPCA_PROM) == 0) {
+       if (DevicePresent(ioaddr) == 0) {
          if (num_depcas > 0) {        /* only gets here in autoprobe */
 
            /*
@@ -370,17 +408,18 @@ depca_probe1(struct device *dev, short ioaddr)
     int i,j, status=0;
     unsigned long mem_start, mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
     char *name=(char *)NULL;
-    int nicsr, offset;
+    unsigned int nicsr, offset, netRAM;
 
 
     /*
-    ** Stop the DEPCA. Enable the DBR ROM. Disable interrupts and remote boot
+    ** Stop the DEPCA. Enable the DBR ROM and the ethernet ROM address counter
+    ** (for the really old DEPCAs). Disable interrupts and remote boot.
     */
     STOP_DEPCA;
 
-    nicsr = inw(DEPCA_NICSR);
-    nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
-    outw(nicsr, DEPCA_NICSR);
+    GET_NICSR(nicsr, DEPCA_NICSR);
+    nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | AAC | IM);
+    PUT_NICSR(nicsr, DEPCA_NICSR);
 
     if (inw(DEPCA_DATA) == STOP) {
 
@@ -438,18 +477,27 @@ depca_probe1(struct device *dev, short ioaddr)
        snarf_region(ioaddr, DEPCA_TOTAL_SIZE);
 #endif
 
+       /*
+       ** Set up the maximum amount of network RAM(kB)
+       */
+       if (strstr(name,"DEPCA")==(char *)NULL) {
+         netRAM=64;
+       } else {
+         netRAM=48;
+       }
+
        /* 
         ** Determine the base address for the DEPCA RAM from the NI-CSR
         ** and make up a DEPCA-specific-data structure. 
         */
 
        if (nicsr & BUF) {
-         offset = 0x8000;              /* 32kbyte RAM */
+         offset = 0x8000;              /* 32kbyte RAM offset*/
          nicsr &= ~BS;                 /* DEPCA RAM in top 32k */
-         printk(",\n      with 32kB RAM");
+         printk(",\n      with %dkB RAM", netRAM-(offset >> 10));
        } else {
-         offset = 0x0000;              /* 64kbyte RAM */
-         printk(",\n      with 64kB RAM");
+         offset = 0x0000;              /* 64k/48k bytes RAM */
+         printk(",\n      with %dkB RAM", netRAM);
        }
 
        mem_start += offset;
@@ -459,17 +507,19 @@ depca_probe1(struct device *dev, short ioaddr)
         ** Enable the shadow RAM.
        */
        nicsr |= SHE;
-       outw(nicsr, DEPCA_NICSR);
+       PUT_NICSR(nicsr, DEPCA_NICSR);
  
        /*
        ** Calculate the ring size based on the available RAM
        ** found above. Allocate an equal number of buffers, each
-       ** of size PKT_BUF_SZ (1544 bytes) to the Tx and Rx. Make sure
+       ** of size PKT_BUF_SZ (1544 bytes) to the Tx and Rx, allowing one
+       ** descriptor entry (8 bytes) for each buffer. Make sure
        ** that this ring size is <= RING_SIZE. The ring size must be
        ** a power of 2.
        */
 
-       j = ((0x10000 - offset) / PKT_BUF_SZ) >> 1;
+       j = (((netRAM << 10) - offset - sizeof(struct depca_private)) / 
+                                                      (PKT_BUF_SZ + 8)) >> 1;
        for (i=0;j>1;i++) {
          j >>= 1;
        }
@@ -548,11 +598,16 @@ depca_probe1(struct device *dev, short ioaddr)
        */
        LoadCSRs(dev);
 
+       /*
+       ** Store the NICSR width for this DEPCA
+       */
+       lp->depca_na = depca_na;
+
        /*
        ** Enable DEPCA board interrupts for autoprobing
        */
        nicsr = ((nicsr & ~IM)|IEN);
-       outw(nicsr, DEPCA_NICSR);
+       PUT_NICSR(nicsr, DEPCA_NICSR);
 
        /* The DMA channel may be passed in on this parameter. */
        dev->dma = 0;
@@ -646,8 +701,9 @@ depca_open(struct device *dev)
     /*
     ** Stop the DEPCA & get the board status information.  
     */
+    depca_na=lp->depca_na;
     STOP_DEPCA;
-    nicsr = inw(DEPCA_NICSR);
+    GET_NICSR(nicsr, DEPCA_NICSR);
 
     /* 
     ** Re-initialize the DEPCA... 
@@ -698,7 +754,7 @@ depca_open(struct device *dev)
     ** Enable DEPCA board interrupts
     */
     nicsr = ((nicsr & ~IM & ~LED)|SHE|IEN);
-    outw(nicsr, DEPCA_NICSR);
+    PUT_NICSR(nicsr, DEPCA_NICSR);
     outw(CSR0,DEPCA_ADDR);
 
     dev->tbusy = 0;                         
@@ -709,7 +765,8 @@ depca_open(struct device *dev)
 
     if (depca_debug > 1){
       printk("CSR0: 0x%4.4x\n",inw(DEPCA_DATA));
-      printk("nicsr: 0x%4.4x\n",inw(DEPCA_NICSR));
+      GET_NICSR(nicsr, DEPCA_NICSR);
+      printk("nicsr: 0x%4.4x\n",nicsr);
     }
 
     return 0;                            /* Always succeed */
@@ -760,7 +817,7 @@ depca_start_xmit(struct sk_buff *skb, struct device *dev)
     /* Transmitter timeout, serious problems. */
     if (dev->tbusy) {
       int tickssofar = jiffies - dev->trans_start;
-      if (tickssofar < 5) {
+      if (tickssofar < 10) {
        status = -1;
       } else {
        STOP_DEPCA;
@@ -921,6 +978,7 @@ depca_interrupt(int reg_ptr)
     } else {
       lp = (struct depca_private *)dev->priv;
       ioaddr = dev->base_addr;
+      depca_na = lp->depca_na;
     }
 
     if (dev->interrupt)
@@ -929,9 +987,9 @@ depca_interrupt(int reg_ptr)
     dev->interrupt = MASK_INTERRUPTS;
 
     /* mask the DEPCA board interrupts and turn on the LED */
-    nicsr = inw(DEPCA_NICSR);
+    GET_NICSR(nicsr, DEPCA_NICSR);
     nicsr |= (IM|LED);
-    outw(nicsr, DEPCA_NICSR);
+    PUT_NICSR(nicsr, DEPCA_NICSR);
 
     outw(CSR0, DEPCA_ADDR);
     csr0 = inw(DEPCA_DATA);
@@ -961,7 +1019,7 @@ depca_interrupt(int reg_ptr)
 
     /* Unmask the DEPCA board interrupts and turn off the LED */
     nicsr = (nicsr & ~IM & ~LED);
-    outw(nicsr, DEPCA_NICSR);
+    PUT_NICSR(nicsr, DEPCA_NICSR);
 
     dev->interrupt = UNMASK_INTERRUPTS;
     return;
@@ -976,9 +1034,32 @@ depca_rx(struct device *dev)
     /* If we own the next entry, it's a new packet. Send it up. */
     for (; lp->rx_ring[entry].base >= 0; entry = (++lp->cur_rx) & lp->rmask) {
        int status = lp->rx_ring[entry].base >> 16 ;
+       int chained;
 
-       if (status & R_ERR) {          /* There was an error. */
-           lp->stats.rx_errors++;     /* Update the error stats. */
+       /*
+       ** There is a tricky error noted by John Murphy, <murf@perftech.com>
+       ** to Russ Nelson: even with full-sized buffers, it's possible for a
+       ** jabber packet to use two buffers, with only the last one correctly
+       ** noting the error.
+       */
+
+       /* Check for a chaining buffer */
+       chained = 0;
+       if (status == R_STP) { 
+         chained = 1;
+
+         /* 
+         ** Wait for next buffer to complete to check for errors. This
+         ** is slow but infrequent and allows for correct hardware buffer
+         ** chaining (whilst defeating the chaining's purpose).
+         */
+         while ((status=(lp->rx_ring[(entry+1)&lp->rmask].base >> 16)) < 0);
+
+         /* NB: 'status' now comes from the buffer following 'entry'. */
+       }
+         
+       if (status & R_ERR) {                  /* There was an error. */
+           lp->stats.rx_errors++;             /* Update the error stats. */
            if (status & R_FRAM) lp->stats.rx_frame_errors++;
            if (status & R_OFLO) lp->stats.rx_over_errors++;
            if (status & R_CRC)  lp->stats.rx_crc_errors++;
@@ -1020,6 +1101,10 @@ depca_rx(struct device *dev)
 
        /* turn over ownership of the current entry back to the LANCE */
        lp->rx_ring[entry].base |= R_OWN;
+       if (chained && (status & R_ERR)) {          /* next entry also bad */
+         entry = (++lp->cur_rx) & lp->rmask;
+         lp->rx_ring[entry].base |= R_OWN;
+       }
     }
 
     /* 
@@ -1277,7 +1362,15 @@ static char *DepcaSignature(unsigned long mem_addr)
 
 /*
 ** Look for a special sequence in the Ethernet station address PROM that
-** is common across all DEPCA products.
+** is common across all DEPCA products. Note that the original DEPCA needs
+** its ROM address counter to be initialized and enabled. Only enable
+** if the first address octet is a 0x08 - this minimises the chances of
+** messing around with some other hardware, but it assumes that this DEPCA
+** card initialized itself correctly. It also assumes that all past and
+** future DEPCA/EtherWORKS cards will have ethernet addresses beginning with
+** a 0x08. The choice of byte or word addressing is made here based on whether
+** word read of the NICSR returns two identical lower and upper bytes: if so
+** the register is 8 bits wide.
 */
 
 static int DevicePresent(short ioaddr)
@@ -1285,9 +1378,40 @@ static int DevicePresent(short ioaddr)
   static short fp=1,sigLength=0;
   static char devSig[] = PROBE_SEQUENCE;
   char data;
-  int i, j, status = 0;
+  unsigned char LSB,MSB;
+  int i, j, nicsr, status = 0;
   static char asc2hex(char value);
 
+/*
+** Initialize the counter on a DEPCA card. Two reads to ensure DEPCA ethernet
+** address counter is a) cleared and b) the correct data read.
+*/
+  data = inb(DEPCA_PROM);                /* clear counter */
+  data = inb(DEPCA_PROM);                /* read data */
+
+/*
+** Determine whether a byte or word access should be made on the NICSR.
+** Since the I/O 'functions' are actually in-line code, the choice not to use
+** pointers to functions vs. just set a conditional, is made for us. This code
+** assumes that the NICSR has an asymmetric bit pattern already in it.
+*/
+  nicsr = inw(DEPCA_NICSR);
+  LSB = nicsr & 0xff;
+  MSB = (((unsigned) nicsr) >> 8) & 0xff;
+  if (MSB == LSB) {
+    depca_na = 0;        /* byte accesses */
+  } else {
+    depca_na = 1;        /* word accesses */
+  }
+
+/*
+** Enable counter
+*/
+  if (data == 0x08) {
+    nicsr |= AAC;
+    PUT_NICSR(nicsr, DEPCA_NICSR);
+  }
+  
 /* 
 ** Convert the ascii signature to a hex equivalent & pack in place 
 */
@@ -1318,7 +1442,7 @@ static int DevicePresent(short ioaddr)
 */
   if (!status) {
     for (i=0,j=0;j<sigLength && i<PROBE_LENGTH+sigLength-1;i++) {
-      data = inb(ioaddr);
+      data = inb(DEPCA_PROM);
       if (devSig[j] == data) {    /* track signature */
        j++;
       } else {                    /* lost signature; begin search again */
index 4f5d719bb8fa940670e162f3138e4aefa6bd5740..531211836dc22c4c58a208b01b6c927d1de1e6ff 100644 (file)
@@ -34,7 +34,7 @@
 #define BS             0x0040  /* Bank Select */
 #define BUF            0x0020  /* BUFfer size (1->32k, 0->64k) */
 #define RBE            0x0010  /* Remote Boot Enable (1->net boot) */
-#define AAC            0x0008  /* for DEPCA family compatability */
+#define AAC            0x0008  /* Address ROM Address Counter (1->enable) */
 #define IM             0x0004  /* Interrupt Mask (1->mask) */
 #define IEN            0x0002  /* Interrupt tristate ENable (1->enable) */
 #define LED            0x0001  /* LED control */
index 5372fa1f22b0a115913deb63643344e904374d54..c47bfd790ca8ca762d2380f71b69c2a6bbc6180f 100644 (file)
@@ -42,12 +42,12 @@ static char *version =
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
+#include <linux/string.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
-#include <errno.h>
-#include <memory.h>
+#include <linux/errno.h>
 
 #include "dev.h"
 #include "eth.h"
index 4c15147a0bf872ffe81eff76fba943bf8f45f4a8..490abae0af56ee75d40557a119b6032fb8e1ed35 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/fs.h>
 #include <linux/malloc.h>
 #include <linux/if_ether.h>
-#include <memory.h>
+#include <linux/string.h>
 #include "dev.h"
 #include "eth.h"
 
index abef8aa7f729a0796667d905b1fcbb802b76040b..e2f0f90d223b78111314ff50c1c03f188ce81a2f 100644 (file)
@@ -127,6 +127,7 @@ static unsigned char generic_sense[6] = {REQUEST_SENSE, 0,0,0, 255, 0};
 static struct blist blacklist[] = 
 {
    {"CHINON","CD-ROM CDS-431","H42"},  /* Locks up if polled for lun != 0 */
+   {"CHINON","CD-ROM CDS-535","Q14"}, /* Lockup if polled for lun != 0 */
    {"DENON","DRD-25X","V"},   /* A cdrom that locks up when probed at lun != 0 */
    {"IMS", "CDD521/10","2.06"},   /* Locks-up when LUN>0 polled. */
    {"MAXTOR","XT-3280","PR02"},   /* Locks-up when LUN>0 polled. */
@@ -533,7 +534,7 @@ Scsi_Cmnd * request_queueable (struct request * req, int index)
 {
   Scsi_Cmnd * SCpnt = NULL;
   int tablesize;
-  struct buffer_head * bh;
+  struct buffer_head * bh, *bhp;
 
   if ((index < 0) ||  (index > NR_SCSI_DEVICES))
     panic ("Index number in allocate_device() is out of range.\n");
@@ -557,16 +558,17 @@ Scsi_Cmnd * request_queueable (struct request * req, int index)
   if (req) {
     memcpy(&SCpnt->request, req, sizeof(struct request));
     tablesize = scsi_devices[index].host->sg_tablesize;
-    bh = req->bh;
+    bhp = bh = req->bh;
     if(!tablesize) bh = NULL;
     /* Take a quick look through the table to see how big it is.  We already
        have our copy of req, so we can mess with that if we want to.  */
     while(req->nr_sectors && bh){
-           tablesize--;
+           bhp = bhp->b_reqnext;
+           if(!bhp || !CONTIGUOUS_BUFFERS(bh,bhp)) tablesize--;
            req->nr_sectors -= bh->b_size >> 9;
            req->sector += bh->b_size >> 9;
            if(!tablesize) break;
-           bh = bh->b_reqnext;
+           bh = bhp;
     };
     if(req->nr_sectors && bh && bh->b_reqnext){  /* Any leftovers? */
       SCpnt->request.bhtail = bh;
@@ -579,9 +581,10 @@ Scsi_Cmnd * request_queueable (struct request * req, int index)
       req->current_nr_sectors = bh->b_size >> 9;
       req->buffer = bh->b_data;
       SCpnt->request.waiting = NULL; /* Wait until whole thing done */
-    } else
+    } else {
       req->dev = -1;
-      
+      wake_up(&wait_for_request);
+    };      
   } else {
     SCpnt->request.dev = 0xffff; /* Busy, but no request */
     SCpnt->request.waiting = NULL;  /* And no one is waiting for the device either */
@@ -608,7 +611,7 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
   int dev = -1;
   struct request * req = NULL;
   int tablesize;
-  struct buffer_head * bh;
+  struct buffer_head * bh, *bhp;
   struct Scsi_Host * host;
   Scsi_Cmnd * SCpnt = NULL;
   Scsi_Cmnd * SCwait = NULL;
@@ -654,16 +657,17 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
        if (req) {
          memcpy(&SCpnt->request, req, sizeof(struct request));
          tablesize = scsi_devices[index].host->sg_tablesize;
-         bh = req->bh;
+         bhp = bh = req->bh;
          if(!tablesize) bh = NULL;
          /* Take a quick look through the table to see how big it is.  We already
             have our copy of req, so we can mess with that if we want to.  */
          while(req->nr_sectors && bh){
-           tablesize--;
+           bhp = bhp->b_reqnext;
+           if(!bhp || !CONTIGUOUS_BUFFERS(bh,bhp)) tablesize--;
            req->nr_sectors -= bh->b_size >> 9;
            req->sector += bh->b_size >> 9;
            if(!tablesize) break;
-           bh = bh->b_reqnext;
+           bh = bhp;
          };
          if(req->nr_sectors && bh && bh->b_reqnext){  /* Any leftovers? */
            SCpnt->request.bhtail = bh;
@@ -680,6 +684,7 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
            {
              req->dev = -1;
              *reqp = req->next;
+             wake_up(&wait_for_request);
            };
        } else {
          SCpnt->request.dev = 0xffff; /* Busy */
@@ -1503,8 +1508,8 @@ void *scsi_malloc(unsigned int len)
 {
   unsigned int nbits, mask;
   int i, j;
-  if((len & 0x1ff) || len > 4096)
-    panic("Inappropriate buffer size requested");
+  if((len & 0x1ff) || len > 8192)
+    return NULL;
   
   cli();
   nbits = len >> 9;
@@ -1593,6 +1598,7 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
 
        for (i=0; i< NR_SCSI_DEVICES; i++) {
          int j;
+         scsi_devices[i].scsi_request_fn = NULL;
          switch (scsi_devices[i].type)
            {
            case TYPE_TAPE :
index 381b86bbe3b1d373ae0c3aa8be0596267d08ef69..3e7ae559411a3b43594dc03dbf6ecf82503dbc22 100644 (file)
@@ -262,6 +262,7 @@ typedef struct scsi_device {
        int access_count;       /* Count of open channels/mounts */
        struct wait_queue * device_wait;  /* Used to wait if device is busy */
        struct Scsi_Host * host;
+       void (*scsi_request_fn)(void); /* Used to jumpstart things after an ioctl */
        char type;
        char scsi_level;
        unsigned writeable:1;
@@ -307,10 +308,12 @@ struct scatterlist {
      char *  address; /* Location data is to be transferred to */
      char * alt_address; /* Location of actual if address is a 
                            dma indirect buffer.  NULL otherwise */
-     unsigned short length;
+     unsigned int length;
      };
 
 #define ISA_DMA_THRESHOLD (0x00ffffff)
+#define CONTIGUOUS_BUFFERS(X,Y) ((X->b_data+X->b_size) == Y->b_data)
+
 
 void *   scsi_malloc(unsigned int);
 int      scsi_free(void *, unsigned int);
@@ -389,7 +392,6 @@ typedef struct scsi_cmnd {
        /* Low-level done function - can be used by low-level driver to point
         to completion function.  Not used by mid/upper level code. */
        void (*scsi_done)(struct scsi_cmnd *);  
-
        void (*done)(struct scsi_cmnd *);  /* Mid-level done function */
 
 /* The following fields can be written to by the host specific code. 
@@ -426,7 +428,6 @@ extern void scsi_do_cmd (Scsi_Cmnd *, const void *cmnd ,
 extern Scsi_Cmnd * allocate_device(struct request **, int, int);
 
 extern Scsi_Cmnd * request_queueable(struct request *, int);
-
 extern int scsi_reset (Scsi_Cmnd *);
 
 extern int max_scsi_hosts;
index 4fe973e7508dfadbdb5a03d435bee7823286a04e..afc617f313893bc075e9cce37a2ac01122f3fa81 100644 (file)
 
 #include <asm/system.h>
 #include <asm/io.h>
-
 #include "../block/blk.h"
 #include "scsi.h"
 #include "hosts.h"
 
+/* A few options that we want selected */
+
+/* Do not attempt to use a timer to simulate a real disk with latency */
+/* Only use this in the actual kernel, not in the simulator. */
+#define IMMEDIATE
+
+/* Skip some consistency checking.  Good for benchmarking */
+#define SPEEDY
+
 /* Number of real scsi disks that will be detected ahead of time */
 static int NR_REAL=-1;
 
-#define MAJOR_NR SCSI_DISK_MAJOR
+#define NR_BLK_DEV     12
+#ifndef MAJOR_NR
+#define MAJOR_NR 8
+#endif
 #define START_PARTITION 4
 #define SCSI_DEBUG_TIMER 20
 /* Number of jiffies to wait before completing a command */
@@ -43,6 +54,11 @@ static int npart = 0;
 #define DEB(x)
 #endif
 
+#ifdef SPEEDY
+#define VERIFY1_DEBUG(RW) 1
+#define VERIFY_DEBUG(RW) 1
+#else
+
 #define VERIFY1_DEBUG(RW)                                              \
       if (bufflen != 1024) {printk("%d", bufflen); panic("(1)Bad bufflen");};                  \
       start = 0;                                                       \
@@ -79,6 +95,7 @@ static int npart = 0;
          panic ("Wrong bh block#");};  \
        if (SCpnt->request.bh->b_dev != SCpnt->request.dev) panic ("Bad bh target");\
       };
+#endif
 
 static volatile void (*do_done[SCSI_DEBUG_MAILBOXES])(Scsi_Cmnd *) = {NULL, };
 static int scsi_debug_host = 0;
@@ -154,7 +171,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     
     buff = (unsigned char *) SCpnt->request_buffer;
 
-    if(target>=2 || SCpnt->lun != 0) {
+    if(target>=1 || SCpnt->lun != 0) {
       SCpnt->result =  DID_NO_CONNECT << 16;
       done(SCpnt);
       return 0;
@@ -187,6 +204,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
       buff[0] = TYPE_DISK;
       buff[1] = 0x80;  /* Removable disk */
       buff[2] = 1;
+      buff[4] = 33 - 5;
       memcpy(&buff[8],"Foo Inc",7);
       memcpy(&buff[16],"XYZZY",5);
       memcpy(&buff[32],"1",1);
@@ -219,7 +237,21 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
       else 
        block = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);
       VERIFY_DEBUG(READ);
+#if defined(SCSI_SETUP_LATENCY) || defined(SCSI_DATARATE)
+      {
+       int delay = SCSI_SETUP_LATENCY;
+       double usec;
+
+       usec = 0.0;
+       usec = (SCpnt->request.nr_sectors << 9) * 1.0e6 / SCSI_DATARATE;
+       delay += usec;
+       if(delay) usleep(delay);
+      };
+#endif
+
+#ifdef DEBUG
       printk("(r%d)",SCpnt->request.nr_sectors);
+#endif
       nbytes = bufflen;
       if(SCpnt->use_sg){
        sgcount = 0;
@@ -231,7 +263,10 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
       scsi_debug_errsts = 0;
       do{
        VERIFY1_DEBUG(READ);
+/* For the speedy test, we do not even want to fill the buffer with anything */
+#ifndef SPEEDY
        memset(buff, 0, bufflen);
+#endif
 /* If this is block 0, then we want to read the partition table for this
    device.  Let's make one up */
        if(block == 0 && target == 0) {
@@ -252,6 +287,8 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
        if (SCpnt->use_sg) printk("Block %x (%d %d)\n",block, SCpnt->request.nr_sectors,
               SCpnt->request.current_nr_sectors);
 #endif
+
+#if 0
        /* Simulate a disk change */
        if(block == 0xfff0) {
          sense_buffer[0] = 0x70;
@@ -270,14 +307,19 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
          scsi_debug_errsts = (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
          break;
        } /* End phony disk change code */
-       memset(buff, 0, bufflen);
+#endif
+
+#ifndef SPEEDY
        memcpy(buff, &target, sizeof(target));
        memcpy(buff+sizeof(target), cmd, 24);
        memcpy(buff+60, &block, sizeof(block));
        memcpy(buff+64, SCpnt, sizeof(Scsi_Cmnd));
+#endif
        nbytes -= bufflen;
        if(SCpnt->use_sg){
+#ifndef SPEEDY
          memcpy(buff+128, bh, sizeof(struct buffer_head));
+#endif
          block += bufflen >> 9;
          bh = bh->b_reqnext;
          sgcount++;
@@ -288,6 +330,11 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
          };
        }
       } while(nbytes);
+
+      SCpnt->result = 0;
+      (done)(SCpnt);
+      return;
+
       if (SCpnt->use_sg && !scsi_debug_errsts)
        if(bh) scsi_dump(SCpnt, 0);
       break;
@@ -301,7 +348,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
       else 
        block = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);
       VERIFY_DEBUG(WRITE);
-      printk("(w%d)",SCpnt->request.nr_sectors);
+/*      printk("(w%d)",SCpnt->request.nr_sectors); */
       if (SCpnt->use_sg){
        if ((bufflen >> 9) != SCpnt->request.nr_sectors)
          panic ("Trying to write wrong number of blocks\n");
@@ -344,6 +391,10 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     else
       printk("scsi_debug_queuecommand: done cant be NULL\n");
 
+#ifdef IMMEDIATE
+    SCpnt->result = scsi_debug_errsts;
+    scsi_debug_intr_handle();  /* No timer - do this one right away */
+#else
     timeout[i] = jiffies+DISK_SPEED;
 
 /* If no timers active, then set this one */
@@ -357,6 +408,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 
 #if 0
     printk("Sending command (%d %x %d %d)...", i, done, timeout[i],jiffies);
+#endif
 #endif
 
     return 0;
@@ -390,18 +442,25 @@ static void scsi_debug_intr_handle(void)
     void (*my_done)(Scsi_Cmnd *); 
    int to;
 
+#ifndef IMMEDIATE
     timer_table[SCSI_DEBUG_TIMER].expires = 0;
     timer_active &= ~(1 << SCSI_DEBUG_TIMER);
+#endif
 
   repeat:
     cli();
     for(i=0;i<SCSI_DEBUG_MAILBOXES; i++) {
       if (SCint[i] == 0) continue;
+#ifndef IMMEDIATE
       if (timeout[i] == 0) continue;
       if (timeout[i] <= jiffies) break;
+#else
+      break;
+#endif
     };
 
     if(i == SCSI_DEBUG_MAILBOXES){
+#ifndef IMMEDIATE
       pending = INT_MAX;
       for(i=0;i<SCSI_DEBUG_MAILBOXES; i++) {
        if (SCint[i] == 0) continue;
@@ -418,6 +477,7 @@ static void scsi_debug_intr_handle(void)
        timer_active |= 1 << SCSI_DEBUG_TIMER;
       };
       sti();
+#endif
       return;
     };
 
@@ -454,8 +514,10 @@ static void scsi_debug_intr_handle(void)
 int scsi_debug_detect(int hostnum)
 {
     scsi_debug_host = hostnum;
+#ifndef IMMEDIATE
     timer_table[SCSI_DEBUG_TIMER].fn = scsi_debug_intr_handle;
     timer_table[SCSI_DEBUG_TIMER].expires = 0;
+#endif
     return 1;
 }
 
@@ -479,7 +541,7 @@ int scsi_debug_abort(Scsi_Cmnd * SCpnt,int i)
     return 0;
 }
 
-int scsi_debug_biosparam(int size, int* info){
+int scsi_debug_biosparam(int size, int dev, int* info){
   info[0] = 32;
   info[1] = 64;
   info[2] = (size + 2047) >> 11;
@@ -506,7 +568,7 @@ int scsi_debug_reset(Scsi_Cmnd * SCpnt)
     return 0;
 }
 
-char *scsi_debug_info(void)
+const char *scsi_debug_info(void)
 {
     static char buffer[] = " ";                        /* looks nicer without anything here */
     return buffer;
index 725b37e944f99819daa820656d4bf6572f17b934..97ff8c943ea86255a9add3b54425e2f2f325aee2 100644 (file)
@@ -6,8 +6,8 @@ int scsi_debug_detect(int);
 int scsi_debug_command(Scsi_Cmnd *);
 int scsi_debug_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int scsi_debug_abort(Scsi_Cmnd *, int);
-int scsi_debug_biosparam(int, int*);
-char *scsi_debug_info(void);
+int scsi_debug_biosparam(int, int, int[]);
+const char *scsi_debug_info(void);
 int scsi_debug_reset(Scsi_Cmnd *);
 
 #ifndef NULL
index 51406de5afc3291abfa2d8437cfa24bcc8e6d982..1b4b4969a36c67dd47fa80a8089d1a3ded8f2b55 100644 (file)
@@ -134,7 +134,7 @@ static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
          };
 
        result = SCpnt->result;
-       SCpnt->request.dev = -1;  /* Mark as not busy */
+       SCpnt->request.dev = -1;
        wake_up(&scsi_devices[SCpnt->index].device_wait);
        return result;
 }
@@ -203,6 +203,10 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
        result = SCpnt->result;
        SCpnt->request.dev = -1;  /* Mark as not busy */
        if (buf) scsi_free(buf, needed);
+
+       if(scsi_devices[SCpnt->index].scsi_request_fn)
+         (*scsi_devices[SCpnt->index].scsi_request_fn)();
+
        wake_up(&scsi_devices[SCpnt->index].device_wait);
        return result;
 #else
@@ -223,8 +227,6 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
 #endif
 }
 
-       
-
 /*
        the scsi_ioctl() function differs from most ioctls in that it does
        not take a major/minor number as the dev filed.  Rather, it takes
@@ -302,4 +304,3 @@ int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg) {
   set_fs(oldfs);
   return tmp;
 }
-
index dac9548ca9b09ce01a2359cf963ac6d65f2f6068..9046f608098c629f6a00128b675550e04c8d7d87 100644 (file)
@@ -4,6 +4,7 @@
 #define SCSI_IOCTL_PROBE_HOST 0
 #define SCSI_IOCTL_SEND_COMMAND 1
 #define SCSI_IOCTL_TEST_UNIT_READY 2
+#define SCSI_IOCTL_BENCHMARK_COMMAND 3
 /* The door lock/unlock constants are compatible with Sun constants for
    the cdrom */
 #define SCSI_IOCTL_DOORLOCK 0x5380             /* lock the eject mechanism */
index 31ba51d184a4cd4b0b0676b368665d4f978a701f..68086bf4ddf0289ead54fe2013cb8f2c3d627c2a 100644 (file)
@@ -34,10 +34,14 @@ static const char RCSid[] = "$Header:";
 #define MAX_RETRIES 5
 
 /*
- *     Time out in seconds
+ *     Time out in seconds for disks and Magneto-opticals (which are slower).
  */
 
 #define SD_TIMEOUT 300
+#define SD_MOD_TIMEOUT 750
+
+#define CLUSTERABLE_DEVICE(SC) (SC->host->sg_tablesize < 64 && \
+                           scsi_devices[SC->index].type != TYPE_MOD)
 
 struct hd_struct * sd;
 
@@ -369,9 +373,7 @@ static void do_sd_request (void)
     };
     
     if (!SCpnt) return; /* Could not find anything to do */
-    
-    wake_up(&wait_for_request);
-    
+        
     /* Queue command */
     requeue_sd_request(SCpnt);
   };  /* While */
@@ -381,7 +383,10 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt)
 {
        int dev, block, this_count;
        unsigned char cmd[10];
-       char * buff;
+       int bounce_size, contiguous;
+       int max_sg;
+       struct buffer_head * bh, *bhp;
+       char * buff, *bounce_buffer;
 
 repeat:
 
@@ -440,8 +445,35 @@ repeat:
 
        SCpnt->this_count = 0;
 
-       if (!SCpnt->request.bh || 
-           (SCpnt->request.nr_sectors == SCpnt->request.current_nr_sectors)) {
+       /* If the host adapter can deal with very large scatter-gather
+          requests, it is a waste of time to cluster */
+       contiguous = (!CLUSTERABLE_DEVICE(SCpnt) ? 0 :1);
+       bounce_buffer = NULL;
+       bounce_size = (SCpnt->request.nr_sectors << 9);
+
+       /* First see if we need a bounce buffer for this request.  If we do, make sure
+          that we can allocate a buffer.  Do not waste space by allocating a bounce
+          buffer if we are straddling the 16Mb line */
+
+       
+       if (contiguous && SCpnt->request.bh &&
+           ((int) SCpnt->request.bh->b_data) + (SCpnt->request.nr_sectors << 9) - 1 > 
+           ISA_DMA_THRESHOLD && SCpnt->host->unchecked_isa_dma) {
+         if(((int) SCpnt->request.bh->b_data) > ISA_DMA_THRESHOLD)
+           bounce_buffer = scsi_malloc(bounce_size);
+         if(!bounce_buffer) contiguous = 0;
+       };
+
+       if(contiguous && SCpnt->request.bh && SCpnt->request.bh->b_reqnext)
+         for(bh = SCpnt->request.bh, bhp = bh->b_reqnext; bhp; bh = bhp, 
+             bhp = bhp->b_reqnext) {
+           if(!CONTIGUOUS_BUFFERS(bh,bhp)) { 
+             if(bounce_buffer) scsi_free(bounce_buffer, bounce_size);
+             contiguous = 0;
+             break;
+           } 
+         };
+       if (!SCpnt->request.bh || contiguous) {
 
          /* case of page request (i.e. raw device), or unlinked buffer */
          this_count = SCpnt->request.nr_sectors;
@@ -450,7 +482,7 @@ repeat:
 
        } else if (SCpnt->host->sg_tablesize == 0 ||
                   (need_isa_buffer && 
-                   dma_free_sectors < 10)) {
+                   dma_free_sectors <= 10)) {
 
          /* Case of host adapter that cannot scatter-gather.  We also
           come here if we are running low on DMA buffer memory.  We set
@@ -461,7 +493,7 @@ repeat:
 
          if (SCpnt->host->sg_tablesize != 0 &&
              need_isa_buffer && 
-             dma_free_sectors < 10)
+             dma_free_sectors <= 10)
            printk("Warning: SCSI DMA buffer space running low.  Using non scatter-gather I/O.\n");
 
          this_count = SCpnt->request.current_nr_sectors;
@@ -471,25 +503,41 @@ repeat:
        } else {
 
          /* Scatter-gather capable host adapter */
-         struct buffer_head * bh;
          struct scatterlist * sgpnt;
          int count, this_count_max;
+         int counted;
+
          bh = SCpnt->request.bh;
          this_count = 0;
          this_count_max = (rscsi_disks[dev].ten ? 0xffff : 0xff);
          count = 0;
-         while(bh && count < SCpnt->host->sg_tablesize) {
+         bhp = NULL;
+         while(bh) {
            if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
+           if(!bhp || !CONTIGUOUS_BUFFERS(bhp,bh) ||
+              !CLUSTERABLE_DEVICE(SCpnt) ||
+              (SCpnt->host->unchecked_isa_dma &&
+              ((unsigned int) bh->b_data-1) == ISA_DMA_THRESHOLD)) {
+             if (count < SCpnt->host->sg_tablesize) count++;
+             else break;
+           };
            this_count += (bh->b_size >> 9);
-           count++;
+           bhp = bh;
            bh = bh->b_reqnext;
          };
+#if 0
+         if(SCpnt->host->unchecked_isa_dma &&
+            ((unsigned int) SCpnt->request.bh->b_data-1) == ISA_DMA_THRESHOLD) count--;
+#endif
          SCpnt->use_sg = count;  /* Number of chains */
          count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
          while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
            count = count << 1;
          SCpnt->sglist_len = count;
+         max_sg = count / sizeof(struct scatterlist);
+         if(SCpnt->host->sg_tablesize < max_sg) max_sg = SCpnt->host->sg_tablesize;
          sgpnt = (struct scatterlist * ) scsi_malloc(count);
+         memset(sgpnt, 0, count);  /* Zero so it is easy to fill */
          if (!sgpnt) {
            printk("Warning - running *really* short on DMA buffers\n");
            SCpnt->use_sg = 0;  /* No memory left - bail out */
@@ -497,20 +545,25 @@ repeat:
            buff = SCpnt->request.buffer;
          } else {
            buff = (char *) sgpnt;
-           count = 0;
-           bh = SCpnt->request.bh;
-           for(count = 0, bh = SCpnt->request.bh; count < SCpnt->use_sg; 
-               count++, bh = bh->b_reqnext) {
-             sgpnt[count].address = bh->b_data;
-             sgpnt[count].alt_address = NULL;
-             sgpnt[count].length = bh->b_size;
-             if (((int) sgpnt[count].address) + sgpnt[count].length > 
-                 ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) {
+           counted = 0;
+           for(count = 0, bh = SCpnt->request.bh, bhp = bh->b_reqnext;
+               count < SCpnt->use_sg && bh; 
+               count++, bh = bhp) {
+
+             bhp = bh->b_reqnext;
+
+             if(!sgpnt[count].address) sgpnt[count].address = bh->b_data;
+             sgpnt[count].length += bh->b_size;
+             counted += bh->b_size >> 9;
+
+             if (((int) sgpnt[count].address) + sgpnt[count].length - 1 > 
+                 ISA_DMA_THRESHOLD && (SCpnt->host->unchecked_isa_dma) &&
+                 !sgpnt[count].alt_address) {
                sgpnt[count].alt_address = sgpnt[count].address;
                /* We try and avoid exhausting the DMA pool, since it is easier
                   to control usage here.  In other places we might have a more
                   pressing need, and we would be screwed if we ran out */
-               if(dma_free_sectors < (bh->b_size >> 9) + 5) {
+               if(dma_free_sectors < (sgpnt[count].length >> 9) + 10) {
                  sgpnt[count].address = NULL;
                } else {
                  sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
@@ -520,6 +573,7 @@ repeat:
    ensure that all scsi operations are able to do at least a non-scatter/gather
    operation */
                if(sgpnt[count].address == NULL){ /* Out of dma memory */
+#if 0
                  printk("Warning: Running low on SCSI DMA buffers");
                  /* Try switching back to a non scatter-gather operation. */
                  while(--count >= 0){
@@ -529,30 +583,93 @@ repeat:
                  this_count = SCpnt->request.current_nr_sectors;
                  buff = SCpnt->request.buffer;
                  SCpnt->use_sg = 0;
-                 scsi_free(buff, SCpnt->sglist_len);
+                 scsi_free(sgpnt, SCpnt->sglist_len);
+#endif
+                 SCpnt->use_sg = count;
+                 this_count = counted -= bh->b_size >> 9;
                  break;
                };
 
-               if (SCpnt->request.cmd == WRITE)
-                 memcpy(sgpnt[count].address, sgpnt[count].alt_address, 
-                        sgpnt[count].length);
              };
+
+             /* Only cluster buffers if we know that we can supply DMA buffers
+                large enough to satisfy the request.  Do not cluster a new
+                request if this would mean that we suddenly need to start
+                using DMA bounce buffers */
+             if(bhp && CONTIGUOUS_BUFFERS(bh,bhp) && CLUSTERABLE_DEVICE(SCpnt)) {
+               char * tmp;
+
+               if (((int) sgpnt[count].address) + sgpnt[count].length +
+                   bhp->b_size - 1 > ISA_DMA_THRESHOLD && 
+                   (SCpnt->host->unchecked_isa_dma) &&
+                   !sgpnt[count].alt_address) continue;
+
+               if(!sgpnt[count].alt_address) {count--; continue; }
+               if(dma_free_sectors > 10)
+                 tmp = scsi_malloc(sgpnt[count].length + bhp->b_size);
+               else {
+                 tmp = NULL;
+                 max_sg = SCpnt->use_sg;
+               };
+               if(tmp){
+                 scsi_free(sgpnt[count].address, sgpnt[count].length);
+                 sgpnt[count].address = tmp;
+                 count--;
+                 continue;
+               };
+
+               /* If we are allowed another sg chain, then increment counter so we
+                  can insert it.  Otherwise we will end up truncating */
+
+               if (SCpnt->use_sg < max_sg) SCpnt->use_sg++;
+             };  /* contiguous buffers */
            }; /* for loop */
+
+           this_count = counted; /* This is actually how many we are going to transfer */
+
+           if(count < SCpnt->use_sg || SCpnt->use_sg > SCpnt->host->sg_tablesize){
+             bh = SCpnt->request.bh;
+             printk("Use sg, count %d %x %d\n", SCpnt->use_sg, count, dma_free_sectors);
+             printk("maxsg = %x, counted = %d this_count = %d\n", max_sg, counted, this_count);
+             while(bh){
+               printk("[%8.8x %x] ", bh->b_data, bh->b_size);
+               bh = bh->b_reqnext;
+             };
+             if(SCpnt->use_sg < 16)
+               for(count=0; count<SCpnt->use_sg; count++)
+                 printk("{%d:%8.8x %8.8x %d}  ", count,
+                        sgpnt[count].address,
+                        sgpnt[count].alt_address,
+                        sgpnt[count].length);
+             panic("Ooops");
+           };
+
+           if (SCpnt->request.cmd == WRITE)
+             for(count=0; count<SCpnt->use_sg; count++)
+               if(sgpnt[count].alt_address)
+                 memcpy(sgpnt[count].address, sgpnt[count].alt_address, 
+                        sgpnt[count].length);
          };  /* Able to malloc sgpnt */
        };  /* Host adapter capable of scatter-gather */
 
 /* Now handle the possibility of DMA to addresses > 16Mb */
 
        if(SCpnt->use_sg == 0){
-         if (((int) buff) + (this_count << 9) > ISA_DMA_THRESHOLD && 
+         if (((int) buff) + (this_count << 9) - 1 > ISA_DMA_THRESHOLD && 
            (SCpnt->host->unchecked_isa_dma)) {
-           buff = (char *) scsi_malloc(this_count << 9);
-           if(buff == NULL) panic("Ran out of DMA buffers.");
+           if(bounce_buffer)
+             buff = bounce_buffer;
+           else
+             buff = (char *) scsi_malloc(this_count << 9);
+           if(buff == NULL) {  /* Try backing off a bit if we are low on mem*/
+             this_count = SCpnt->request.current_nr_sectors;
+             buff = (char *) scsi_malloc(this_count << 9);
+             if(!buff) panic("Ran out of DMA buffers.");
+           };
            if (SCpnt->request.cmd == WRITE)
              memcpy(buff, (char *)SCpnt->request.buffer, this_count << 9);
          };
        };
-
 #ifdef DEBUG
        printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(SCpnt->request.dev),
                (SCpnt->request.cmd == WRITE) ? "writing" : "reading",
@@ -607,10 +724,12 @@ repeat:
 
         SCpnt->transfersize = rscsi_disks[dev].sector_size;
         SCpnt->underflow = this_count << 9; 
-
        scsi_do_cmd (SCpnt, (void *) cmd, buff, 
                     this_count * rscsi_disks[dev].sector_size,
-                    rw_intr, SD_TIMEOUT, MAX_RETRIES);
+                    rw_intr, 
+                    (scsi_devices[SCpnt->index].type == TYPE_DISK ? 
+                                    SD_TIMEOUT : SD_MOD_TIMEOUT),
+                    MAX_RETRIES);
 }
 
 int check_scsidisk_media_change(int full_dev, int flag){
@@ -857,6 +976,7 @@ static int sd_init_onedisk(int i)
        their size, and reads partition table entries for them.
 */
 
+
 unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
 {
        int i;
@@ -893,7 +1013,7 @@ unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
           the read-ahead to 16 blocks (32 sectors).  If not, we use
           a two block (4 sector) read ahead. */
        if(rscsi_disks[0].device->host->sg_tablesize)
-         read_ahead[MAJOR_NR] = 32;
+         read_ahead[MAJOR_NR] = 120;
        /* 64 sector read-ahead */
        else
          read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
@@ -910,6 +1030,7 @@ unsigned long sd_init1(unsigned long mem_start, unsigned long mem_end){
 };
 
 void sd_attach(Scsi_Device * SDp){
+  SDp->scsi_request_fn = do_sd_request;
   rscsi_disks[NR_SD++].device = SDp;
   if(NR_SD > MAX_SD) panic ("scsi_devices corrupt (sd)");
 };
@@ -968,3 +1089,4 @@ int revalidate_scsidisk(int dev, int maxusage){
          DEVICE_BUSY = 0;
          return 0;
 }
+
index f51ec664a6422a55a9ffef560bc6155a054642ee..385221d0ea9398120371db5e870904f53f838bfe 100644 (file)
@@ -53,6 +53,12 @@ int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne
                        put_fs_long(sd[MINOR(inode->i_rdev)].nr_sects,
                                (long *) arg);
                        return 0;
+               case BLKRASET:
+                       if(!suser())  return -EACCES;
+                       if(!inode->i_rdev) return -EINVAL;
+                       if(arg > 0xff) return -EINVAL;
+                       read_ahead[MAJOR(inode->i_rdev)] = arg;
+                       return 0;
                case BLKFLSBUF:
                        if(!suser())  return -EACCES;
                        if(!inode->i_rdev) return -EINVAL;
index bdaf3a698de5fe556f610b560174ec6bf86fbb78..d1fc8a3829610e905914c3e394a8a1503d939e03 100644 (file)
@@ -624,6 +624,7 @@ unsigned long sr_init1(unsigned long mem_start, unsigned long mem_end){
 };
 
 void sr_attach(Scsi_Device * SDp){
+  SDp->scsi_request_fn = do_sr_request;
   scsi_CDs[NR_SR++].device = SDp;
   if(NR_SR > MAX_SR) panic ("scsi_devices corrupt (sr)");
 };
index c43122e537f5fa7f728224a456c46946bacfd1e3..5b3c8df5a8a0651c1d5163445b2c6b153ed6d12b 100644 (file)
@@ -385,6 +385,12 @@ int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne
                case CDROMREADMODE1:
                        return -EINVAL;
 
+               case BLKRASET:
+                       if(!suser())  return -EACCES;
+                       if(!inode->i_rdev) return -EINVAL;
+                       if(arg > 0xff) return -EINVAL;
+                       read_ahead[MAJOR(inode->i_rdev)] = arg;
+                       return 0;
                RO_IOCTLS(dev,arg);
                default:
                        return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
index fbad9eabeabd239cade75658426d12f2ea1bf426..76a3b057ecf2c5f12710b071da8e5645828f71b2 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/timer.h>
 #include <linux/tty.h>
 #include <linux/ctype.h>
+#include <linux/string.h>
 #include <asm/io.h>
 #include <asm/segment.h>
 #include <asm/system.h>
index 22ffc2154525fce136e95ff3c4ba00a367091f42..cf4ab3b28277e4f4c9e7e5b4113a791c54fbcca5 100644 (file)
@@ -54,7 +54,8 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
                if (chars == blocksize)
                        bh = getblk(dev, block, blocksize);
                else
-                       bh = breada(dev,block,block+1,block+2,-1);
+                       bh = breada(dev, block, blocksize, offset, 
+                                   size << blocksize_bits);
                block++;
                if (!bh)
                        return written?written:-EIO;
@@ -67,7 +68,7 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
                p += chars;
                buf += chars;
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse(bh);
        }
        return written;
index 923343f9bf2dfcac8aab4c21fd30d73b036ee2ca..49f1e4ae028b32ce5a9dc3c2e6b649d8720f51ec 100644 (file)
@@ -46,6 +46,10 @@ extern int check_cdu31a_media_change(int, int);
 extern int check_mcd_media_change(int, int);
 #endif
 
+static char buffersize_index[9] = {-1,  0,  1, -1,  2, -1, -1, -1, 3};
+
+#define BUFSIZE_INDEX(X) (buffersize_index[(X)>>9])
+
 static int grow_buffers(int pri, int size);
 
 static struct buffer_head * hash_table[NR_HASH];
@@ -556,42 +560,62 @@ struct buffer_head * bread(dev_t dev, int block, int size)
 
 /*
  * Ok, breada can be used as bread, but additionally to mark other
- * blocks for reading as well. End the argument list with a negative
- * number.
+ * blocks for reading as well.
  */
-struct buffer_head * breada(dev_t dev,int first, ...)
-{
-       va_list args;
-       unsigned int blocksize;
-       struct buffer_head * bh, *tmp;
 
-       va_start(args,first);
+#define NBUF 16
 
-       blocksize = BLOCK_SIZE;
-       if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
-               blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
+struct buffer_head * breada(dev_t dev, int block, int bufsize,
+       unsigned int pos, unsigned int filesize)
+{
+       struct buffer_head * bhlist[NBUF];
+       unsigned int blocks;
+       struct buffer_head * bh;
+       int index;
+       int i, j;
 
-       if (!(bh = getblk(dev, first, blocksize))) {
-               printk("VFS: breada: READ error on device %d/%d\n",
-                                               MAJOR(dev), MINOR(dev));
+       if (pos >= filesize)
                return NULL;
-       }
-       if (!bh->b_uptodate)
-               ll_rw_block(READ, 1, &bh);
-       while ((first=va_arg(args,int))>=0) {
-               tmp = getblk(dev, first, blocksize);
-               if (tmp) {
-                       if (!tmp->b_uptodate)
-                               ll_rw_block(READA, 1, &tmp);
-                       tmp->b_count--;
+
+       if (block < 0 || !(bh = getblk(dev,block,bufsize)))
+               return NULL;
+
+       index = BUFSIZE_INDEX(bh->b_size);
+
+       if (bh->b_uptodate)
+               return bh;
+
+       blocks = ((filesize & (bufsize - 1)) - (pos & (bufsize - 1))) >> (9+index);
+
+       if (blocks > (read_ahead[MAJOR(dev)] >> index))
+               blocks = read_ahead[MAJOR(dev)] >> index;
+       if (blocks > NBUF)
+               blocks = NBUF;
+       
+       bhlist[0] = bh;
+       j = 1;
+       for(i=1; i<blocks; i++) {
+               bh = getblk(dev,block+i,bufsize);
+               if (bh->b_uptodate) {
+                       brelse(bh);
+                       break;
                }
+               bhlist[j++] = bh;
        }
-       va_end(args);
+
+       /* Request the read for these buffers, and then release them */
+       ll_rw_block(READ, j, bhlist);
+
+       for(i=1; i<j; i++)
+               brelse(bhlist[i]);
+
+       /* Wait for this buffer, and then continue on */
+       bh = bhlist[0];
        wait_on_buffer(bh);
        if (bh->b_uptodate)
                return bh;
        brelse(bh);
-       return (NULL);
+       return NULL;
 }
 
 /*
@@ -616,7 +640,7 @@ static void get_more_buffer_heads(void)
        if (unused_list)
                return;
 
-       if(! (bh = (struct buffer_head*) get_free_page(GFP_BUFFER)))
+       if (!(bh = (struct buffer_head*) get_free_page(GFP_BUFFER)))
                return;
 
        for (nr_buffer_heads+=i=PAGE_SIZE/sizeof*bh ; i>0; i--) {
@@ -870,7 +894,7 @@ static int grow_buffers(int pri, int size)
                printk("VFS: grow_buffers: size = %d\n",size);
                return 0;
        }
-       if(!(page = __get_free_page(pri)))
+       if (!(page = __get_free_page(pri)))
                return 0;
        bh = create_buffers(page, size);
        if (!bh) {
index d8caabd2c91a6b6665dba8b981b0f17092093d4c..16fe1ffb448faaea760823a9da1ef0d5b38635fb 100644 (file)
@@ -104,7 +104,8 @@ static int ext_file_read(struct inode * inode, struct file * filp, char * buf, i
        blocks = (left + offset + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
        bhb = bhe = buflist;
        if (filp->f_reada) {
-               blocks += read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
+               if(blocks < read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9))
+                 blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
                if (block + blocks > size)
                        blocks = size - block;
        }
@@ -247,7 +248,7 @@ static int ext_file_write(struct inode * inode, struct file * filp, char * buf,
                memcpy_fromfs(p,buf,c);
                buf += c;
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse(bh);
        }
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
index 6462da1c95d740ed4f040929061ca73e86811ac7..e46bb9e99a1abceae4e3f7c7bdbc8a1b6e1f646b 100644 (file)
@@ -83,7 +83,7 @@ printk("ext_free_block: block full, skipping to %d\n", block);
        }
        sb->u.ext_sb.s_freeblockscount ++;
        sb->s_dirt = 1;
-       sb->u.ext_sb.s_firstfreeblock->b_dirt = 1;
+       dirtify_buffer(sb->u.ext_sb.s_firstfreeblock, 1);
        unlock_super (sb);
        return;
 }
@@ -104,7 +104,7 @@ int ext_new_block(struct super_block * sb)
        efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data;
        if (efb->count) {
                j = efb->free[--efb->count];
-               sb->u.ext_sb.s_firstfreeblock->b_dirt = 1;
+               dirtify_buffer(sb->u.ext_sb.s_firstfreeblock, 1);
        } else {
 #ifdef EXTFS_DEBUG
 printk("ext_new_block: block empty, skipping to %d\n", efb->next);
@@ -135,7 +135,7 @@ printk("ext_new_block: block empty, skipping to %d\n", efb->next);
        }
        clear_block(bh->b_data);
        bh->b_uptodate = 1;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
 #ifdef EXTFS_DEBUG
 printk("ext_new_block: allocating block %d\n", j);
@@ -239,7 +239,7 @@ printk("ext_free_inode: inode full, skipping to %d\n", ino);
        }
        sb->u.ext_sb.s_freeinodescount ++;
        sb->s_dirt = 1;
-       sb->u.ext_sb.s_firstfreeinodeblock->b_dirt = 1;
+       dirtify_buffer(sb->u.ext_sb.s_firstfreeinodeblock, 1);
        unlock_super (sb);
 }
 
@@ -263,7 +263,7 @@ struct inode * ext_new_inode(const struct inode * dir)
                (sb->u.ext_sb.s_firstfreeinodenumber-1)%EXT_INODES_PER_BLOCK;
        if (efi->count) {
                j = efi->free[--efi->count];
-               sb->u.ext_sb.s_firstfreeinodeblock->b_dirt = 1;
+               dirtify_buffer(sb->u.ext_sb.s_firstfreeinodeblock, 1);
        } else {
 #ifdef EXTFS_DEBUG
 printk("ext_free_inode: inode empty, skipping to %d\n", efi->next);
index 910ab5891c521682d0fac9bf7bf8d77704f7ecdc..eff68fcb525c8cd5b98eb131e03b15bd645c2d3a 100644 (file)
@@ -139,7 +139,7 @@ void ext_write_super (struct super_block *sb)
        es->s_freeblockscount = sb->u.ext_sb.s_freeblockscount;
        es->s_firstfreeinode = sb->u.ext_sb.s_firstfreeinodenumber;
        es->s_freeinodescount = sb->u.ext_sb.s_freeinodescount;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse (bh);
        sb->s_dirt = 0;
 }
@@ -296,7 +296,7 @@ repeat:
                goto repeat;
        }
        *p = tmp;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        return result;
 }
@@ -407,7 +407,7 @@ static struct buffer_head * ext_update_inode(struct inode * inode)
                raw_inode->i_zone[0] = inode->i_rdev;
        else for (block = 0; block < 12; block++)
                raw_inode->i_zone[block] = inode->u.ext_i.i_data[block];
-       bh->b_dirt=1;
+       dirtify_buffer(bh, 1);
        inode->i_dirt=0;
        return bh;
 }
index a8bc1cb31b9bb1af1a3ce7543c1b518686860a85..5a1ac36c681cbb6989b1ce263322c9fb4ad04aae 100644 (file)
@@ -249,7 +249,7 @@ printk ("ext_add_entry: skipping to next block\n");
 #if 0
                                        dir->i_ctime = CURRENT_TIME;
 #endif
-                                       bh->b_dirt = 1;
+                                       dirtify_buffer(bh, 1);
                                }
                                brelse (bh);
                                bh = NULL;
@@ -296,7 +296,7 @@ printk ("ext_add_entry : creating next block\n");
                        de->name_len = namelen;
                        for (i=0; i < namelen ; i++)
                                de->name[i] = name[i];
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                        *res_dir = de;
                        return bh;
                }
@@ -334,7 +334,7 @@ int ext_create(struct inode * dir,const char * name, int len, int mode,
                return -ENOSPC;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        *result = inode;
@@ -393,7 +393,7 @@ int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev
                return -ENOSPC;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -445,7 +445,7 @@ int ext_mkdir(struct inode * dir, const char * name, int len, int mode)
        de->name_len=2;
        strcpy(de->name,"..");
        inode->i_nlink = 2;
-       dir_block->b_dirt = 1;
+       dirtify_buffer(dir_block, 1);
        brelse(dir_block);
        inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
        if (dir->i_mode & S_ISGID)
@@ -459,7 +459,7 @@ int ext_mkdir(struct inode * dir, const char * name, int len, int mode)
                return -ENOSPC;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        dir->i_nlink++;
        dir->i_dirt = 1;
        iput(dir);
@@ -567,7 +567,7 @@ int ext_rmdir(struct inode * dir, const char * name, int len)
        de->inode = 0;
        de->name_len = 0;
        ext_merge_entries (de, pde, nde);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        inode->i_nlink=0;
        inode->i_dirt=1;
        dir->i_nlink--;
@@ -610,7 +610,7 @@ int ext_unlink(struct inode * dir, const char * name, int len)
        de->inode = 0;
        de->name_len = 0;
        ext_merge_entries (de, pde, nde);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        inode->i_nlink--;
        inode->i_dirt = 1;
        inode->i_ctime = CURRENT_TIME;
@@ -650,7 +650,7 @@ int ext_symlink(struct inode * dir, const char * name, int len, const char * sym
        while (i < 1023 && (c = *(symname++)))
                name_block->b_data[i++] = c;
        name_block->b_data[i] = 0;
-       name_block->b_dirt = 1;
+       dirtify_buffer(name_block, 1);
        brelse(name_block);
        inode->i_size = i;
        inode->i_dirt = 1;
@@ -672,7 +672,7 @@ int ext_symlink(struct inode * dir, const char * name, int len, const char * sym
                return -ENOSPC;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -708,7 +708,7 @@ int ext_link(struct inode * oldinode, struct inode * dir, const char * name, int
                return -ENOSPC;
        }
        de->inode = oldinode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        oldinode->i_nlink++;
@@ -851,11 +851,11 @@ start_up:
                new_inode->i_nlink--;
                new_inode->i_dirt = 1;
        }
-       old_bh->b_dirt = 1;
-       new_bh->b_dirt = 1;
+       dirtify_buffer(old_bh, 1);
+       dirtify_buffer(new_bh, 1);
        if (dir_bh) {
                PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
-               dir_bh->b_dirt = 1;
+               dirtify_buffer(dir_bh, 1);
                old_dir->i_nlink--;
                new_dir->i_nlink++;
                old_dir->i_dirt = 1;
index d14dc6cb340c8e089a6231f734794fc5f5e8bdc6..21f85bef3393ee8d0e1a3a4b3002e4bb6f20f85a 100644 (file)
@@ -102,7 +102,7 @@ repeat:
                        continue;
                }
                *ind = 0;
-               ind_bh->b_dirt = 1;
+               dirtify_buffer(ind_bh, 1);
                brelse(bh);
                ext_free_block(inode->i_sb,tmp);
        }
@@ -154,7 +154,7 @@ repeat:
                if (!tmp)
                        continue;
                retry |= trunc_indirect(inode,offset+(i<<8),dind);
-               dind_bh->b_dirt = 1;
+               dirtify_buffer(dind_bh, 1);
        }
        dind = (unsigned long *) dind_bh->b_data;
        for (i = 0; i < 256; i++)
@@ -201,7 +201,7 @@ repeat:
                        goto repeat;
                tind = i+(unsigned long *) tind_bh->b_data;
                retry |= trunc_dindirect(inode,9+256+256*256+(i<<16),tind);
-               tind_bh->b_dirt = 1;
+               dirtify_buffer(tind_bh, 1);
        }
        tind = (unsigned long *) tind_bh->b_data;
        for (i = 0; i < 256; i++)
index a8d868900ee277befb9f6c332093d26a5a6d0ce1..82e4019a422f0c25644d967bc591baad492d43fd 100644 (file)
@@ -310,10 +310,10 @@ void ext2_free_blocks (struct super_block * sb, unsigned long block,
                }
        }
        
-       bh2->b_dirt = 1;
-       sb->u.ext2_sb.s_sbh->b_dirt = 1;
+       dirtify_buffer(bh2, 1);
+       dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
 
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (sb->s_flags & MS_SYNC) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -524,7 +524,7 @@ got_block:
 
        j = tmp;
 
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (sb->s_flags & MS_SYNC) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -544,16 +544,16 @@ got_block:
        }
        clear_block (bh->b_data, sb->s_blocksize);
        bh->b_uptodate = 1;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse (bh);
 
        ext2_debug ("allocating block %d. "
                    "Goal hits %d of %d.\n", j, goal_hits, goal_attempts);
 
        gdp->bg_free_blocks_count--;
-       bh2->b_dirt = 1;
+       dirtify_buffer(bh2, 1);
        es->s_free_blocks_count--;
-       sb->u.ext2_sb.s_sbh->b_dirt = 1;
+       dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
        sb->s_dirt = 1;
        unlock_super (sb);
        return j;
index 7251a40e05c0cce714b17935f024a772fa661979..806165f470210e5766e5fb31b10f7bdd6dfc1858 100644 (file)
@@ -112,8 +112,8 @@ static int ext2_file_read (struct inode * inode, struct file * filp,
        blocks = (left + offset + sb->s_blocksize - 1) >> EXT2_BLOCK_SIZE_BITS(sb);
        bhb = bhe = buflist;
        if (filp->f_reada) {
-               blocks += read_ahead[MAJOR(inode->i_dev)] >>
-                       (EXT2_BLOCK_SIZE_BITS(sb) - 9);
+               if (blocks < read_ahead[MAJOR(inode->i_dev)] >> (EXT2_BLOCK_SIZE_BITS(sb) - 9))
+                   blocks = read_ahead[MAJOR(inode->i_dev)] >> (EXT2_BLOCK_SIZE_BITS(sb) - 9);
                if (block + blocks > size)
                        blocks = size - block;
        }
@@ -277,7 +277,7 @@ static int ext2_file_write (struct inode * inode, struct file * filp,
                memcpy_fromfs (p, buf, c);
                buf += c;
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse (bh);
        }
        up(&inode->i_sem);
index de2144aa1fefec4a0f34100543dbb502a5aa5249..d3ba1df81cf86ecb531bd4a5d962c76673326681 100644 (file)
@@ -202,7 +202,7 @@ static void set_inode_dtime (struct inode * inode,
                        EXT2_INODES_PER_BLOCK(inode->i_sb));
        raw_inode->i_links_count = 0;
        raw_inode->i_dtime = CURRENT_TIME;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(inode)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -266,12 +266,12 @@ void ext2_free_inode (struct inode * inode)
                gdp->bg_free_inodes_count++;
                if (S_ISDIR(inode->i_mode))
                        gdp->bg_used_dirs_count--;
-               bh2->b_dirt = 1;
+               dirtify_buffer(bh2, 1);
                es->s_free_inodes_count++;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
                set_inode_dtime (inode, gdp);
        }
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (sb->s_flags & MS_SYNC) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -313,7 +313,7 @@ static void inc_inode_version (struct inode * inode,
                        EXT2_INODES_PER_BLOCK(inode->i_sb));
        raw_inode->i_version++;
        inode->u.ext2_i.i_version = raw_inode->i_version;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse (bh);
 }
 
@@ -438,7 +438,7 @@ repeat:
                                      "bit already set for inode %d", j);
                        goto repeat;
                }
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                if (sb->s_flags & MS_SYNC) {
                        ll_rw_block (WRITE, 1, &bh);
                        wait_on_buffer (bh);
@@ -466,9 +466,9 @@ repeat:
        gdp->bg_free_inodes_count--;
        if (S_ISDIR(mode))
                gdp->bg_used_dirs_count++;
-       bh2->b_dirt = 1;
+       dirtify_buffer(bh2, 1);
        es->s_free_inodes_count--;
-       sb->u.ext2_sb.s_sbh->b_dirt = 1;
+       dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
        sb->s_dirt = 1;
        inode->i_mode = mode;
        inode->i_sb = sb;
index 050b0f2ff47b90b10a4f25866e069fcf9dcef488..409846553c2553b6ff39352c87b08a02ddcb4451 100644 (file)
@@ -109,7 +109,7 @@ static int ext2_alloc_block (struct inode * inode, unsigned long goal)
                }
                clear_block (bh->b_data, inode->i_sb->s_blocksize);
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                brelse (bh);
        } else {
                ext2_discard_prealloc (inode);
@@ -314,7 +314,7 @@ repeat:
                goto repeat;
        }
        *p = tmp;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(inode)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -549,7 +549,7 @@ static struct buffer_head * ext2_update_inode (struct inode * inode)
                raw_inode->i_block[0] = inode->i_rdev;
        else for (block = 0; block < EXT2_N_BLOCKS; block++)
                raw_inode->i_block[block] = inode->u.ext2_i.i_data[block];
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        inode->i_dirt = 0;
        return bh;
 }
index 960fae9bc8a02a80a8d636f456c4e93d587949f2..6a92d13e2f61361c5efab386f373123446b24274 100644 (file)
@@ -275,9 +275,6 @@ static struct buffer_head * ext2_add_entry (struct inode * dir,
                                de->rec_len = sb->s_blocksize;
                                dir->i_size = offset + sb->s_blocksize;
                                dir->i_dirt = 1;
-#if 0 /* XXX don't update any times until successful completion of syscall */
-                               dir->i_ctime = CURRENT_TIME;
-#endif
                        } else {
 
                                ext2_debug ("skipping to next block\n");
@@ -323,7 +320,7 @@ static struct buffer_head * ext2_add_entry (struct inode * dir,
                         */
                        dir->i_mtime = dir->i_ctime = CURRENT_TIME;
                        dir->i_dirt = 1;
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                        *res_dir = de;
                        *err = 0;
                        return bh;
@@ -397,7 +394,7 @@ int ext2_create (struct inode * dir,const char * name, int len, int mode,
        ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
                         de->inode);
 #endif
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -449,14 +446,6 @@ int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
                init_fifo(inode);
        if (S_ISBLK(mode) || S_ISCHR(mode))
                inode->i_rdev = rdev;
-#if 0
-       /*
-        * XXX we may as well use the times set by ext2_new_inode().  The
-        * following usually does nothing, but sometimes it invalidates
-        * inode->i_ctime.
-        */
-       inode->i_mtime = inode->i_atime = CURRENT_TIME;
-#endif
        inode->i_dirt = 1;
        bh = ext2_add_entry (dir, name, len, &de, &err);
        if (!bh) {
@@ -471,7 +460,7 @@ int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
        ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
                         de->inode);
 #endif
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -508,9 +497,6 @@ int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
        }
        inode->i_op = &ext2_dir_inode_operations;
        inode->i_size = inode->i_sb->s_blocksize;
-#if 0 /* XXX as above */
-       inode->i_mtime = inode->i_atime = CURRENT_TIME;
-#endif
        dir_block = ext2_bread (inode, 0, 1, &err);
        if (!dir_block) {
                iput (dir);
@@ -531,7 +517,7 @@ int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
        de->name_len = 2;
        strcpy (de->name, "..");
        inode->i_nlink = 2;
-       dir_block->b_dirt = 1;
+       dirtify_buffer(dir_block, 1);
        brelse (dir_block);
        inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->umask);
        if (dir->i_mode & S_ISGID)
@@ -550,7 +536,7 @@ int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
        ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
                         de->inode);
 #endif
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -674,7 +660,7 @@ repeat:
        up(&inode->i_sem);
        if (retval)
                goto end_rmdir;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -742,7 +728,7 @@ repeat:
        retval = ext2_delete_entry (de, bh);
        if (retval)
                goto end_unlink;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -807,7 +793,7 @@ int ext2_symlink (struct inode * dir, const char * name, int len,
                link[i++] = c;
        link[i] = 0;
        if (name_block) {
-               name_block->b_dirt = 1;
+               dirtify_buffer(name_block, 1);
                brelse (name_block);
        }
        inode->i_size = i;
@@ -834,7 +820,7 @@ int ext2_symlink (struct inode * dir, const char * name, int len,
        ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
                         de->inode);
 #endif
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -880,7 +866,7 @@ int ext2_link (struct inode * oldinode, struct inode * dir,
        ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
                         de->inode);
 #endif
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -1056,19 +1042,19 @@ start_up:
        }
        old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
        old_dir->i_dirt = 1;
-       old_bh->b_dirt = 1;
+       dirtify_buffer(old_bh,  1);
        if (IS_SYNC(old_dir)) {
                ll_rw_block (WRITE, 1, &old_bh);
                wait_on_buffer (old_bh);
        }
-       new_bh->b_dirt = 1;
+       dirtify_buffer(new_bh, 1);
        if (IS_SYNC(new_dir)) {
                ll_rw_block (WRITE, 1, &new_bh);
                wait_on_buffer (new_bh);
        }
        if (dir_bh) {
                PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
-               dir_bh->b_dirt = 1;
+               dirtify_buffer(dir_bh, 1);
                old_dir->i_nlink--;
                old_dir->i_dirt = 1;
                if (new_inode) {
index 1ceaf3467d7e0f07c4c0a6caf3a38c36d3acded8..4cfa9ff017dded8df74d2d533ace429ca6ea4260 100644 (file)
@@ -36,7 +36,7 @@ void ext2_error (struct super_block * sb, const char * function,
        if (!(sb->s_flags & MS_RDONLY)) {
                sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
                sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
                sb->s_dirt = 1;
        }
        va_start (args, fmt);
@@ -66,7 +66,7 @@ NORET_TYPE void ext2_panic (struct super_block * sb, const char * function,
        if (!(sb->s_flags & MS_RDONLY)) {
                sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
                sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
                sb->s_dirt = 1;
        }
        va_start (args, fmt);
@@ -96,7 +96,7 @@ void ext2_put_super (struct super_block * sb)
        lock_super (sb);
        if (!(sb->s_flags & MS_RDONLY)) {
                sb->u.ext2_sb.s_es->s_state = sb->u.ext2_sb.s_mount_state;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
        }
 #ifndef DONT_USE_DCACHE
        ext2_dcache_invalidate (sb->s_dev);
@@ -159,10 +159,10 @@ static int convert_pre_02b_fs (struct super_block * sb,
                gdp[i].bg_free_blocks_count = old_group_desc[i].bg_free_blocks_count;
                gdp[i].bg_free_inodes_count = old_group_desc[i].bg_free_inodes_count;
        }
-       bh2->b_dirt = 1;
+       dirtify_buffer(bh2, 1);
        brelse (bh2);
        es->s_magic = EXT2_SUPER_MAGIC;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        sb->s_magic = EXT2_SUPER_MAGIC;
        return 1;
 }
@@ -287,7 +287,7 @@ static void ext2_setup_super (struct super_block * sb,
                        es->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT;
                es->s_mnt_count++;
                es->s_mtime = CURRENT_TIME;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
                sb->s_dirt = 1;
                if (test_opt (sb, DEBUG))
                        printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, "
@@ -570,7 +570,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
 #ifdef EXT2FS_PRE_02B_COMPAT
        if (fs_converted) {
                for (i = 0; i < bh_count; i++)
-                       sb->u.ext2_sb.s_group_desc[i]->b_dirt = 1;
+                       dirtify_buffer(sb->u.ext2_sb.s_group_desc[i], 1);
                sb->s_dirt = 1;
        }
 #endif
@@ -582,7 +582,7 @@ static void ext2_commit_super (struct super_block * sb,
                               struct ext2_super_block * es)
 {
        es->s_wtime = CURRENT_TIME;
-       sb->u.ext2_sb.s_sbh->b_dirt = 1;
+       dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
        sb->s_dirt = 0;
 }
 
@@ -639,7 +639,7 @@ int ext2_remount (struct super_block * sb, int * flags, char * data)
                 */
                es->s_state = sb->u.ext2_sb.s_mount_state;
                es->s_mtime = CURRENT_TIME;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
                sb->s_dirt = 1;
                ext2_commit_super (sb, es);
        }
index 95db1ed4a8a813fab989c0c32bd8aad387c56ccc..589e3650fd57fff5613eee3d6a1acb8f954e1100 100644 (file)
@@ -90,7 +90,7 @@ repeat:
                if (inode->u.ext2_i.i_flags & EXT2_SECRM_FL) {
                        clear_block (bh->b_data, inode->i_sb->s_blocksize,
                                     RANDOM_INT);
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                }
                brelse (bh);
                if (free_count == 0) {
@@ -162,11 +162,11 @@ repeat:
                        continue;
                }
                *ind = 0;
-               ind_bh->b_dirt = 1;
+               dirtify_buffer(ind_bh, 1);
                if (inode->u.ext2_i.i_flags & EXT2_SECRM_FL) {
                        clear_block (bh->b_data, inode->i_sb->s_blocksize,
                                     RANDOM_INT);
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                }
                brelse (bh);
                if (free_count == 0) {
@@ -243,7 +243,7 @@ repeat:
                        continue;
                retry |= trunc_indirect (inode, offset + (i * addr_per_block),
                                          dind);
-               dind_bh->b_dirt = 1;
+               dirtify_buffer(dind_bh, 1);
        }
        dind = (unsigned long *) dind_bh->b_data;
        for (i = 0; i < addr_per_block; i++)
@@ -302,7 +302,7 @@ repeat:
                retry |= trunc_dindirect(inode, EXT2_NDIR_BLOCKS +
                        addr_per_block + (i + 1) * addr_per_block * addr_per_block,
                        tind);
-               tind_bh->b_dirt = 1;
+               dirtify_buffer(tind_bh, 1);
        }
        tind = (unsigned long *) tind_bh->b_data;
        for (i = 0; i < addr_per_block; i++)
index f2abf2c17dd79e620f9480bbdf6cb98e700fbfbd..aee32f7ffdbbdee9eef9886f9c64a4fb00fded64 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/hpfs_fs.h>
 #include <linux/errno.h>
 #include <linux/malloc.h>
+#include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/locks.h>
 #include <linux/stat.h>
@@ -1676,8 +1677,7 @@ static void *map_4sectors(dev_t dev, unsigned secno,
        if (!data)
                goto bail;
 
-       qbh->bh[0] = bh = breada(dev,
-                                secno, secno + 1, secno + 2, secno + 3, -1);
+       qbh->bh[0] = bh = breada(dev, secno, 512, 0, UINT_MAX);
        if (!bh)
                goto bail0;
        memcpy(data, bh->b_data, 512);
index 1aebbb17694d1646518ca29554e44329f41bdf91..7d8260f5f88189e2b30fdda8e7d4a29997d71934 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/fs/isofs/dir.c
  *
- *  (C) 1992  Eric Youngdale Modified for ISO9660 filesystem.
+ *  (C) 1992, 1993, 1994  Eric Youngdale Modified for ISO9660 filesystem.
  *
  *  (C) 1991  Linus Torvalds - minix filesystem
  *
@@ -19,6 +19,8 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/malloc.h>
+#include <linux/sched.h>
+#include <linux/locks.h>
 
 static int isofs_readdir(struct inode *, struct file *, struct dirent *, int);
 
@@ -81,9 +83,12 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
        
        offset = filp->f_pos & (bufsize - 1);
        block = isofs_bmap(inode,filp->f_pos>>bufbits);
-       if (!block || !(bh = bread(inode->i_dev,block,bufsize)))
-               return 0;
-       
+
+       if(!block) return 0;
+
+       if(!(bh = breada(inode->i_dev, block, bufsize, filp->f_pos, inode->i_size)))
+         return 0;
+
        while (filp->f_pos < inode->i_size) {
 #ifdef DEBUG
                printk("Block, offset: %x %x %x\n",
@@ -103,7 +108,8 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
                                       + ISOFS_BLOCK_SIZE);
                        block = isofs_bmap(inode,(filp->f_pos)>>bufbits);
                        if (!block
-                           || !(bh = bread(inode->i_dev,block,bufsize)))
+                           || !(bh = breada(inode->i_dev, block, bufsize, filp->f_pos, 
+                                            inode->i_size)))
                                return 0;
                        continue;
                }
@@ -126,7 +132,8 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
                        offset = filp->f_pos & (bufsize - 1);
                        block = isofs_bmap(inode,(filp->f_pos)>> bufbits);
                        if (!block
-                           || !(bh = bread(inode->i_dev,block,bufsize))) {
+                           || !(bh = breada(inode->i_dev, block, bufsize,
+                                            filp->f_pos, inode->i_size))) {
                                kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
                                return 0;
                        };
index 35d501a29d88fb9dbff80cd18db06a6f5b5acf37..03cf412d14e4071500c4273559fd61967743b6b8 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/fs/isofs/file.c
  *
- *  (C) 1992  Eric Youngdale Modified for ISO9660 filesystem.
+ *  (C) 1992, 1993, 1994  Eric Youngdale Modified for ISO9660 filesystem.
  *
  *  (C) 1991  Linus Torvalds - minix filesystem
  *
@@ -146,6 +146,8 @@ static int isofs_file_read(struct inode * inode, struct file * filp, char * buf,
        bhb = bhe = buflist;
 
        ra_blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
+       if(ra_blocks > blocks) blocks = ra_blocks;
+
        max_block = (inode->i_size + BLOCK_SIZE - 1)/BLOCK_SIZE;
        nextblock = -1;
 
@@ -169,7 +171,6 @@ static int isofs_file_read(struct inode * inode, struct file * filp, char * buf,
                        if (*bhb && !(*bhb)->b_uptodate) {
                                uptodate = 0;
                                bhreq[bhrequest++] = *bhb;
-                               nextblock = (*bhb)->b_blocknr + 1;
                              };
 
                        if (++bhb == &buflist[NBUF])
@@ -177,37 +178,12 @@ static int isofs_file_read(struct inode * inode, struct file * filp, char * buf,
 
                        /* If the block we have on hand is uptodate, go ahead
                           and complete processing. */
-                       if(bhrequest == 0 && uptodate) break;
+                       if(uptodate) break;
 
                        if (bhb == bhe)
                                break;
                      }
 
-               if(blocks == 0 && bhrequest && filp->f_reada && bhb != bhe) { 
-                 /* If we are going to read something anyways, add in the
-                    read-ahead blocks */
-                 while(ra_blocks){
-                   if (block >= max_block) break;
-                   if(bhrequest == NBUF) break;  /* Block full */
-                   --ra_blocks;
-                   *bhb = getblk(inode->i_dev,isofs_bmap(inode, block++), ISOFS_BUFFER_SIZE(inode));
-
-                   if (*bhb && !(*bhb)->b_uptodate) {
-                     if((*bhb)->b_blocknr != nextblock) {
-                       brelse(*bhb);
-                       break;
-                     };
-                     nextblock = (*bhb)->b_blocknr + 1;
-                     bhreq[bhrequest++] = *bhb;
-                   };
-                   
-                   if (++bhb == &buflist[NBUF])
-                     bhb = buflist;
-                   
-                   if (bhb == bhe)
-                     break;
-                 };
-               };
                /* Now request them all */
                if (bhrequest)
                  ll_rw_block(READ, bhrequest, bhreq);
index 0ba69b32c5e00cffaf8fd9b1c0c526b4082db365..2b3258904224c0a12ce3232da874c18b91568663 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/fs/isofs/inode.c
  * 
- *  (C) 1992  Eric Youngdale Modified for ISO9660 filesystem.
+ *  (C) 1992, 1993, 1994  Eric Youngdale Modified for ISO9660 filesystem.
  *
  *  (C) 1991  Linus Torvalds - minix filesystem
  */
@@ -354,7 +354,7 @@ void isofs_read_inode(struct inode * inode)
        if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize){
                cpnt = kmalloc(1 << ISOFS_BLOCK_BITS, GFP_KERNEL);
                if (cpnt == NULL) {
-                       printk(KERN_INFO "NoMem ISO inode %d\n",inode->i_ino);
+                       printk(KERN_INFO "NoMem ISO inode %lu\n",inode->i_ino);
                        brelse(bh);
                        goto fail;
                }
@@ -600,7 +600,8 @@ int isofs_lookup_grandparent(struct inode * parent, int extent)
                        brelse(bh);
                        offset = 0;
                        block++;
-                       if(block & 1) return -1;
+                       if((block & 1) && (ISOFS_BLOCK_BITS - bufbits))
+                         return -1;
                        if (!block
                            || !(bh = bread(parent->i_dev,block, bufsize)))
                                return -1;
index f62faf137513b3dc31e579af13eaff0bc0e19ccf..dea267f265e7d7dd059735ff83df55fc56a96a5c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/fs/isofs/rock.c
  *
- *  (C) 1992  Eric Youngdale
+ *  (C) 1992, 1993  Eric Youngdale
  *
  *  Rock Ridge Extensions to iso9660
  */
index 8f4d1c8e3eb388ab538344d7d44f168eafb43b92..4d8cf173897f4b7644ffd666773455a540979e0e 100644 (file)
@@ -93,7 +93,7 @@ void minix_free_block(struct super_block * sb, int block)
        }
        if (!clear_bit(bit,bh->b_data))
                printk("free_block (%04x:%d): bit already cleared\n",sb->s_dev,block);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        return;
 }
 
@@ -118,7 +118,7 @@ repeat:
                printk("new_block: bit already set");
                goto repeat;
        }
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        j += i*8192 + sb->u.minix_sb.s_firstdatazone-1;
        if (j < sb->u.minix_sb.s_firstdatazone ||
            j >= sb->u.minix_sb.s_nzones)
@@ -129,7 +129,7 @@ repeat:
        }
        clear_block(bh->b_data);
        bh->b_uptodate = 1;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        return j;
 }
@@ -175,7 +175,7 @@ void minix_free_inode(struct inode * inode)
        clear_inode(inode);
        if (!clear_bit(ino & 8191, bh->b_data))
                printk("free_inode: bit %lu already cleared.\n",ino);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
 }
 
 struct inode * minix_new_inode(const struct inode * dir)
@@ -204,7 +204,7 @@ struct inode * minix_new_inode(const struct inode * dir)
                iput(inode);
                return NULL;
        }
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        j += i*8192;
        if (!j || j >= inode->i_sb->u.minix_sb.s_ninodes) {
                iput(inode);
index 8329a48d77097f0908d6ac54d3c6ccb8fc42fb21..73088e0e95e777e05e1e86e043dc7aed3c376ff3 100644 (file)
@@ -98,7 +98,8 @@ static int minix_file_read(struct inode * inode, struct file * filp, char * buf,
        blocks = (left + offset + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
        bhb = bhe = buflist;
        if (filp->f_reada) {
-               blocks += read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
+               if(blocks < read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9))
+                 blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
                if (block + blocks > size)
                        blocks = size - block;
        }
@@ -239,7 +240,7 @@ static int minix_file_write(struct inode * inode, struct file * filp, char * buf
                memcpy_fromfs(p,buf,c);
                buf += c;
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse(bh);
        }
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
index bc4b16c5b366b65749d73ff9352b9b5cf4359b9d..b4226db4a9049a64d9a5c47b825dbd098c819a65 100644 (file)
@@ -28,7 +28,7 @@ void minix_put_inode(struct inode *inode)
 static void minix_commit_super (struct super_block * sb,
                               struct minix_super_block * ms)
 {
-       sb->u.minix_sb.s_sbh->b_dirt = 1;
+       dirtify_buffer(sb->u.minix_sb.s_sbh, 1);
        sb->s_dirt = 0;
 }
 
@@ -54,7 +54,7 @@ void minix_put_super(struct super_block *sb)
        lock_super(sb);
        if (!(sb->s_flags & MS_RDONLY)) {
                sb->u.minix_sb.s_ms->s_state = sb->u.minix_sb.s_mount_state;
-               sb->u.minix_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.minix_sb.s_sbh, 1);
        }
        sb->s_dev = 0;
        for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
@@ -90,7 +90,7 @@ int minix_remount (struct super_block * sb, int * flags, char * data)
                        return 0;
                /* Mounting a rw partition read-only. */
                ms->s_state = sb->u.minix_sb.s_mount_state;
-               sb->u.minix_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.minix_sb.s_sbh, 1);
                sb->s_dirt = 1;
                minix_commit_super (sb, ms);
        }
@@ -98,7 +98,7 @@ int minix_remount (struct super_block * sb, int * flags, char * data)
                /* Mount a partition which is read-only, read-write. */
                sb->u.minix_sb.s_mount_state = ms->s_state;
                ms->s_state &= ~MINIX_VALID_FS;
-               sb->u.minix_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.minix_sb.s_sbh, 1);
                sb->s_dirt = 1;
 
                if (!(sb->u.minix_sb.s_mount_state & MINIX_VALID_FS))
@@ -197,7 +197,7 @@ struct super_block *minix_read_super(struct super_block *s,void *data,
        }
        if (!(s->s_flags & MS_RDONLY)) {
                ms->s_state &= ~MINIX_VALID_FS;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                s->s_dirt = 1;
        }
        if (!(s->u.minix_sb.s_mount_state & MINIX_VALID_FS))
@@ -349,7 +349,7 @@ repeat:
                goto repeat;
        }
        *p = tmp;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        return result;
 }
@@ -477,7 +477,7 @@ static struct buffer_head * minix_update_inode(struct inode * inode)
        else for (block = 0; block < 9; block++)
                raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
        inode->i_dirt=0;
-       bh->b_dirt=1;
+       dirtify_buffer(bh, 1);
        return bh;
 }
 
index f4814ee7099588fdcfd139cd96aa7b46f0618149..68d7cedd48427b2bd62e63f3f4b6c54a08046ef8 100644 (file)
@@ -195,7 +195,7 @@ static int minix_add_entry(struct inode * dir,
                        dir->i_mtime = dir->i_ctime = CURRENT_TIME;
                        for (i = 0; i < info->s_namelen ; i++)
                                de->name[i] = (i < namelen) ? name[i] : 0;
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                        *res_dir = de;
                        break;
                }
@@ -238,7 +238,7 @@ int minix_create(struct inode * dir,const char * name, int len, int mode,
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        *result = inode;
@@ -295,7 +295,7 @@ int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rd
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -347,7 +347,7 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
        de->inode = dir->i_ino;
        strcpy(de->name,"..");
        inode->i_nlink = 2;
-       dir_block->b_dirt = 1;
+       dirtify_buffer(dir_block, 1);
        brelse(dir_block);
        inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
        if (dir->i_mode & S_ISGID)
@@ -361,7 +361,7 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        dir->i_nlink++;
        dir->i_dirt = 1;
        iput(dir);
@@ -469,7 +469,7 @@ int minix_rmdir(struct inode * dir, const char * name, int len)
        if (inode->i_nlink != 2)
                printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink);
        de->inode = 0;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        inode->i_nlink=0;
        inode->i_dirt=1;
        dir->i_nlink--;
@@ -522,7 +522,7 @@ repeat:
                inode->i_nlink=1;
        }
        de->inode = 0;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
        dir->i_dirt = 1;
        inode->i_nlink--;
@@ -562,7 +562,7 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s
        while (i < 1023 && (c=*(symname++)))
                name_block->b_data[i++] = c;
        name_block->b_data[i] = 0;
-       name_block->b_dirt = 1;
+       dirtify_buffer(name_block, 1);
        brelse(name_block);
        inode->i_size = i;
        inode->i_dirt = 1;
@@ -584,7 +584,7 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s
                return i;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -621,7 +621,7 @@ int minix_link(struct inode * oldinode, struct inode * dir, const char * name, i
                return error;
        }
        de->inode = oldinode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        oldinode->i_nlink++;
@@ -774,11 +774,11 @@ start_up:
                new_inode->i_ctime = CURRENT_TIME;
                new_inode->i_dirt = 1;
        }
-       old_bh->b_dirt = 1;
-       new_bh->b_dirt = 1;
+       dirtify_buffer(old_bh, 1);
+       dirtify_buffer(new_bh, 1);
        if (dir_bh) {
                PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
-               dir_bh->b_dirt = 1;
+               dirtify_buffer(dir_bh, 1);
                old_dir->i_nlink--;
                old_dir->i_dirt = 1;
                if (new_inode) {
index bef81a302eab34ee14a79f6cc68b931d250cf2c0..bd5445367e09a142ae430fc87900a3f8a56a2d78 100644 (file)
@@ -96,7 +96,7 @@ repeat:
                        continue;
                }
                *ind = 0;
-               ind_bh->b_dirt = 1;
+               dirtify_buffer(ind_bh, 1);
                brelse(bh);
                minix_free_block(inode->i_sb,tmp);
        }
@@ -144,7 +144,7 @@ repeat:
                        goto repeat;
                dind = i+(unsigned short *) dind_bh->b_data;
                retry |= trunc_indirect(inode,7+512+(i<<9),dind);
-               dind_bh->b_dirt = 1;
+               dirtify_buffer(dind_bh, 1);
        }
        dind = (unsigned short *) dind_bh->b_data;
        for (i = 0; i < 512; i++)
index b4ec8d7b091b32899588bcde842ce4a8c009a99a..8576a81d419bcd8e718efec1a50849d0803bacbf 100644 (file)
@@ -72,15 +72,15 @@ int fat_access(struct super_block *sb,int nr,int new_value)
                                *p_first = new_value & 0xff;
                                *p_last = (*p_last & 0xf0) | (new_value >> 8);
                        }
-                       bh2->b_dirt = 1;
+                       dirtify_buffer(bh2, 1);
                }
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                for (copy = 1; copy < MSDOS_SB(sb)->fats; copy++) {
                        if (!(c_bh = msdos_sread(sb->s_dev,MSDOS_SB(sb)->
                            fat_start+(first >> SECTOR_BITS)+MSDOS_SB(sb)->
                            fat_length*copy,&c_data))) break;
                        memcpy(c_data,data,SECTOR_SIZE);
-                       c_bh->b_dirt = 1;
+                       dirtify_buffer(c_bh, 1);
                        if (data != data2 || bh != bh2) {
                                if (!(c_bh2 = msdos_sread(sb->s_dev,
                                    MSDOS_SB(sb)->fat_start+(first >>
index fc5463dbf2ad87b1420aa0355ca9464a2811f031..ba1d623184df5fee317260ce356ce39ac7298247 100644 (file)
@@ -200,7 +200,7 @@ static int msdos_file_write(struct inode *inode,struct file *filp,char *buf,
                        inode->i_size = filp->f_pos;
                        inode->i_dirt = 1;
                }
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse(bh);
        }
        if (start == buf)
index cf333623d7c2b04e1b8c789a82239b0703698b7b..7d028fd4a614f66f0a7affc98707da87b66f75ee 100644 (file)
@@ -415,7 +415,7 @@ void msdos_write_inode(struct inode *inode)
        date_unix2dos(inode->i_mtime,&raw_entry->time,&raw_entry->date);
        raw_entry->time = CT_LE_W(raw_entry->time);
        raw_entry->date = CT_LE_W(raw_entry->date);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
 }
 
index 49b7215c8f5b3b73d78884c0e101bdac6f1a283d..7b23886c03e850cba8991659d652baa41787db85 100644 (file)
@@ -185,7 +185,7 @@ printk("zeroing sector %d\n",sector);
                        else memset(data,0,SECTOR_SIZE);
                }
                if (bh) {
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                        brelse(bh);
                }
        }
index cf64067c949e919e4a2d89950739e79ac6d1fc1c..2ed3ee94cc792d2b1ff9941b161afa99a397a374 100644 (file)
@@ -181,7 +181,7 @@ static int msdos_create_entry(struct inode *dir,char *name,int is_dir,
        de->start = 0;
        date_unix2dos(dir->i_mtime,&de->time,&de->date);
        de->size = 0;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if ((*result = iget(dir->i_sb,ino)) != NULL)
                msdos_read_inode(*result);
        brelse(bh);
@@ -350,7 +350,7 @@ int msdos_rmdir(struct inode *dir,const char *name,int len)
        dir->i_nlink--;
        inode->i_dirt = dir->i_dirt = 1;
        de->name[0] = DELETED_FLAG;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        res = 0;
 rmdir_done:
        brelse(bh);
@@ -384,7 +384,7 @@ int msdos_unlink(struct inode *dir,const char *name,int len)
        MSDOS_I(inode)->i_busy = 1;
        inode->i_dirt = dir->i_dirt = 1;
        de->name[0] = DELETED_FLAG;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
 unlink_done:
        brelse(bh);
        iput(inode);
@@ -429,12 +429,12 @@ static int rename_same_dir(struct inode *old_dir,char *old_name,
                MSDOS_I(new_inode)->i_busy = 1;
                new_inode->i_dirt = 1;
                new_de->name[0] = DELETED_FLAG;
-               new_bh->b_dirt = 1;
+               dirtify_buffer(new_bh, 1);
                iput(new_inode);
                brelse(new_bh);
        }
        memcpy(old_de->name,new_name,MSDOS_NAME);
-       old_bh->b_dirt = 1;
+       dirtify_buffer(old_bh, 1);
        if (MSDOS_SB(old_dir->i_sb)->conversion == 'a') /* update binary info */
                if ((old_inode = iget(old_dir->i_sb,old_ino)) != NULL) {
                        msdos_read_inode(old_inode);
@@ -503,7 +503,7 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,
                MSDOS_I(new_inode)->i_busy = 1;
                new_inode->i_dirt = 1;
                new_de->name[0] = DELETED_FLAG;
-               new_bh->b_dirt = 1;
+               dirtify_buffer(new_bh, 1);
        }
        memcpy(free_de,old_de,sizeof(struct msdos_dir_entry));
        memcpy(free_de->name,new_name,MSDOS_NAME);
@@ -526,8 +526,8 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,
        cache_inval_inode(old_inode);
        old_inode->i_dirt = 1;
        old_de->name[0] = DELETED_FLAG;
-       old_bh->b_dirt = 1;
-       free_bh->b_dirt = 1;
+       dirtify_buffer(old_bh, 1);
+       dirtify_buffer(free_bh, 1);
        if (!exists) iput(free_inode);
        else {
                MSDOS_I(new_inode)->i_depend = free_inode;
@@ -547,7 +547,7 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,
                dotdot_de->start = MSDOS_I(dotdot_inode)->i_start =
                    MSDOS_I(new_dir)->i_start;
                dotdot_inode->i_dirt = 1;
-               dotdot_bh->b_dirt = 1;
+               dirtify_buffer(dotdot_bh, 1);
                old_dir->i_nlink--;
                new_dir->i_nlink++;
                /* no need to mark them dirty */
index 6990b4175508fb0b5467f0068b3187293570db81..6707267b40a9e04b8fb3026c15970b9eff6b84fe 100644 (file)
@@ -96,7 +96,7 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
                }
                *flc_count = *sb->sv_sb_flc_count; /* = sb->sv_flc_size */
                memcpy(flc_blocks, sb->sv_sb_flc_blocks, *flc_count * sizeof(sysv_zone_t));
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                bh->b_uptodate = 1;
                brelse(bh);
                *sb->sv_sb_flc_count = 0;
@@ -117,7 +117,7 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
                bh_data = bh->b_data + ((block & sb->sv_block_size_ratio_1) << sb->sv_block_size_bits);
                memzero(bh_data, sb->sv_block_size);
                /* this implies ((struct ..._freelist_chunk *) bh_data)->flc_count = 0; */
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                bh->b_uptodate = 1;
                brelse(bh);
                /* still *sb->sv_sb_flc_count = 0 */
@@ -138,7 +138,7 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
                  to_coh_ulong(from_coh_ulong(*sb->sv_sb_total_free_blocks) + 1);
        else
                *sb->sv_sb_total_free_blocks = *sb->sv_sb_total_free_blocks + 1;
-       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
        sb->s_dirt = 1; /* and needs time stamp */
        unlock_super(sb);
 }
@@ -229,7 +229,7 @@ int sysv_new_block(struct super_block * sb)
                        return 0;
                }
        memzero(bh_data,sb->sv_block_size);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        bh->b_uptodate = 1;
        brelse(bh);
        if (sb->sv_convert)
@@ -237,7 +237,7 @@ int sysv_new_block(struct super_block * sb)
                  to_coh_ulong(from_coh_ulong(*sb->sv_sb_total_free_blocks) - 1);
        else
                *sb->sv_sb_total_free_blocks = *sb->sv_sb_total_free_blocks - 1;
-       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
        sb->s_dirt = 1; /* and needs time stamp */
        unlock_super(sb);
        return block;
@@ -331,7 +331,7 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
                printk("sysv_count_free_blocks: free block count was %d, correcting to %d\n",old_count,count);
                if (!(sb->s_flags & MS_RDONLY)) {
                        *sb->sv_sb_total_free_blocks = (sb->sv_convert ? to_coh_ulong(count) : count);
-                       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+                       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
                        sb->s_dirt = 1; /* and needs time stamp */
                }
        }
index 4c012fc6fa2f6f245d52809c3f3a6100eb02559a..df61c0d2b014c3565179add71a6c185c3102453a 100644 (file)
@@ -301,7 +301,7 @@ static int sysv_file_write(struct inode * inode, struct file * filp, char * buf,
                memcpy_fromfs(p,buf,c);
                buf += c;
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse(bh);
        }
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
index cfa56943ddc667bf9344ab22e3ad1fbe97d0c33d..4aa79035823e7aa3d37a1bb355b33e7493a3502c 100644 (file)
@@ -74,10 +74,10 @@ void sysv_free_inode(struct inode * inode)
        if (*sb->sv_sb_fic_count < sb->sv_fic_size)
                sb->sv_sb_fic_inodes[(*sb->sv_sb_fic_count)++] = ino;
        (*sb->sv_sb_total_free_inodes)++;
-       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
        sb->s_dirt = 1; /* and needs time stamp */
        memset(raw_inode, 0, sizeof(struct sysv_inode));
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        unlock_super(sb);
        brelse(bh);
        clear_inode(inode);
@@ -130,7 +130,7 @@ struct inode * sysv_new_inode(const struct inode * dir)
        }
        /* Now *sb->sv_sb_fic_count > 0. */
        ino = sb->sv_sb_fic_inodes[--(*sb->sv_sb_fic_count)];
-       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
        sb->s_dirt = 1; /* and needs time stamp */
        inode->i_count = 1;
        inode->i_nlink = 1;
@@ -152,7 +152,7 @@ struct inode * sysv_new_inode(const struct inode * dir)
        inode->i_dirt = 1;              /* cleared by sysv_write_inode() */
        /* That's it. */
        (*sb->sv_sb_total_free_inodes)--;
-       sb->sv_bh->b_dirt = 1; /* super-block has been modified again */
+       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified again */
        sb->s_dirt = 1; /* and needs time stamp again */
        unlock_super(sb);
        return inode;
@@ -191,7 +191,7 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
                printk("sysv_count_free_inodes: free inode count was %d, correcting to %d\n",(short)(*sb->sv_sb_total_free_inodes),count);
                if (!(sb->s_flags & MS_RDONLY)) {
                        *sb->sv_sb_total_free_inodes = count;
-                       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+                       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
                        sb->s_dirt = 1; /* and needs time stamp */
                }
        }
index d9eb8482d6267f0361fcc74b35613396e4f36017..4c1d94bdece2ae75911a83ab08ee62461ce30e0d 100644 (file)
@@ -557,7 +557,7 @@ repeat:
                goto repeat;
        }
        *p = (sb->sv_convert ? to_coh_ulong(block) : block);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        *start = result->b_data + ((block & sb->sv_block_size_ratio_1) << sb->sv_block_size_bits);
        return result;
@@ -773,7 +773,7 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
                for (block = 0; block < 10+1+1+1; block++)
                        write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
        inode->i_dirt=0;
-       bh->b_dirt=1;
+       dirtify_buffer(bh, 1);
        return bh;
 }
 
index e0e17cdde318bef90e39430c00d315d210bf8a8c..a08d2943b8c2e0843a8d0d9c777057b5c000e6c3 100644 (file)
@@ -193,7 +193,7 @@ static int sysv_add_entry(struct inode * dir,
                        dir->i_mtime = dir->i_ctime = CURRENT_TIME;
                        for (i = 0; i < SYSV_NAMELEN ; i++)
                                de->name[i] = (i < namelen) ? name[i] : 0;
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                        *res_dir = de;
                        break;
                }
@@ -238,7 +238,7 @@ int sysv_create(struct inode * dir,const char * name, int len, int mode,
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        *result = inode;
@@ -298,7 +298,7 @@ int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rde
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -349,7 +349,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
        de->inode = dir->i_ino;
        strcpy(de->name,".."); /* rest of de->name is zero, see sysv_new_block */
        inode->i_nlink = 2;
-       dir_block->b_dirt = 1;
+       dirtify_buffer(dir_block, 1);
        brelse(dir_block);
        inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
        if (dir->i_mode & S_ISGID)
@@ -363,7 +363,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        dir->i_nlink++;
        dir->i_dirt = 1;
        iput(dir);
@@ -473,7 +473,7 @@ int sysv_rmdir(struct inode * dir, const char * name, int len)
        if (inode->i_nlink != 2)
                printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink);
        de->inode = 0;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        inode->i_nlink=0;
        inode->i_dirt=1;
        dir->i_nlink--;
@@ -526,7 +526,7 @@ repeat:
                inode->i_nlink=1;
        }
        de->inode = 0;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
        dir->i_dirt = 1;
        inode->i_nlink--;
@@ -570,7 +570,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
        while (i < sb->sv_block_size_1 && (c = *(symname++)))
                name_block_data[i++] = c;
        name_block_data[i] = 0;
-       name_block->b_dirt = 1;
+       dirtify_buffer(name_block, 1);
        brelse(name_block);
        inode->i_size = i;
        inode->i_dirt = 1;
@@ -592,7 +592,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
                return i;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -629,7 +629,7 @@ int sysv_link(struct inode * oldinode, struct inode * dir, const char * name, in
                return error;
        }
        de->inode = oldinode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        oldinode->i_nlink++;
@@ -782,11 +782,11 @@ start_up:
                new_inode->i_ctime = CURRENT_TIME;
                new_inode->i_dirt = 1;
        }
-       old_bh->b_dirt = 1;
-       new_bh->b_dirt = 1;
+       dirtify_buffer(old_bh, 1);
+       dirtify_buffer(new_bh, 1);
        if (dir_bh) {
                PARENT_INO(dir_bh_data) = new_dir->i_ino;
-               dir_bh->b_dirt = 1;
+               dirtify_buffer(dir_bh, 1);
                old_dir->i_nlink--;
                old_dir->i_dirt = 1;
                if (new_inode) {
index e9b6ccf36ca035206b52ae3450579d8e717c8509..e8b5ddee13202ace3df81f498a4fb23b6fe1916a 100644 (file)
@@ -84,7 +84,7 @@ static int coh_trunc_indirect (struct inode * inode, unsigned long blocks, unsig
                if (!indblock)
                        continue;
                *ind = 0;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                sysv_free_block(sb,indblock);
        }
        for (i = 0; i < sb->sv_ind_per_block; i++)
@@ -338,7 +338,7 @@ repeat:
                        continue;
                }
                *ind = 0;
-               indbh->b_dirt = 1;
+               dirtify_buffer(indbh, 1);
                brelse(bh);
                sysv_free_block(sb,block);
        }
index 3dd74fa59c99ebc38d5d721e4f4f8eb0775163e0..c191d64f41a6623add560a8f5429a0f3eba5a2e7 100644 (file)
@@ -65,7 +65,7 @@ zone_found:
         start_bit=j + (i << 5) + 1;
        goto repeat;
     }
-    bh->b_dirt=1;
+    dirtify_buffer(bh, 1);
     return j + (i << 5);
 }
 
@@ -245,7 +245,7 @@ void xiafs_free_zone(struct super_block * sb, int d_addr)
         printk("XIA-FS: dev %04x"
               " block bit %u (0x%x) already cleared (%s %d)\n",
               sb->s_dev, bit, bit, WHERE_ERR);
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached);
 }
 
@@ -277,7 +277,7 @@ int xiafs_new_zone(struct super_block * sb, u_long prev_addr)
     }
     clear_buf(bh);
     bh->b_uptodate = 1;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     return tmp;
 }
@@ -305,7 +305,7 @@ void xiafs_free_inode(struct inode * inode)
         printk("XIA-FS: dev %04x"
               "inode bit %ld (0x%lx) already cleared (%s %d)\n",
               inode->i_dev, ino, ino, WHERE_ERR);
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     xiafs_unlock_super(sb, sb->u.xiafs_sb.s_imap_cached);
 }
 
index 3c5bd5a14f5c59b57595a39ade53ba6f05b8bae4..92075b5f3a76f447291324ad19617ae9faca92d9 100644 (file)
@@ -97,7 +97,8 @@ xiafs_file_read(struct inode * inode, struct file * filp, char * buf, int count)
     zones = (left+offset+XIAFS_ZSIZE(inode->i_sb)-1) >> XIAFS_ZSIZE_BITS(inode->i_sb);
     bhb = bhe = buflist;
     if (filp->f_reada) {
-        zones += read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb));
+        if(zones < read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb)))
+         zones = read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb));
        if (zone_nr + zones > f_zones)
            zones = f_zones - zone_nr;
     }
@@ -240,7 +241,7 @@ xiafs_file_write(struct inode * inode, struct file * filp, char * buf, int count
        memcpy_fromfs(cp,buf,c);
        buf += c;
        bh->b_uptodate = 1;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 0);
        brelse(bh);
     }
     inode->i_mtime = inode->i_ctime = CURRENT_TIME;
index 84e2109ec765cc194032f349f7b09149faaa9c99..8af15c3a413a714b96c30dcb5c04dcde5551ba8b 100644 (file)
@@ -306,7 +306,7 @@ repeat:
     }
     *lp = tmp;
     inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb);
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     return result;
 }
@@ -466,7 +466,7 @@ static struct buffer_head *  xiafs_update_inode(struct inode * inode)
                                     | (inode->u.xiafs_i.i_dind_zone  & 0xffffff);
     }
     inode->i_dirt=0;
-    bh->b_dirt=1;
+    dirtify_buffer(bh, 1);
     return bh;
 }
 
index 52c9a68122f0ee65210ece112c3e5a7cc947efbe..13d49d6b52c823ee885b5fde1434176a2e394faa 100644 (file)
@@ -221,7 +221,7 @@ static struct buffer_head * xiafs_add_entry(struct inode * dir,
                memcpy(de->d_name, name, namelen);
                de->d_name[namelen]=0;
                de->d_name_len=namelen;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                *res_dir = de;
                if (res_pre)
                    *res_pre = de_pre;
@@ -268,7 +268,7 @@ int xiafs_create(struct inode * dir, const char * name, int len, int mode,
        return -ENOSPC;
     }
     de->d_ino = inode->i_ino;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     iput(dir);
     *result = inode;
@@ -325,7 +325,7 @@ int xiafs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev
        return -ENOSPC;
     }
     de->d_ino = inode->i_ino;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     iput(dir);
     iput(inode);
@@ -375,7 +375,7 @@ int xiafs_mkdir(struct inode * dir, const char * name, int len, int mode)
     de->d_name_len=2;
     de->d_rec_len=XIAFS_ZSIZE(dir->i_sb)-12;
     inode->i_nlink = 2;
-    dir_block->b_dirt = 1;
+    dirtify_buffer(dir_block, 1);
     brelse(dir_block);
     inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->umask);
     if (dir->i_mode & S_ISGID)
@@ -389,7 +389,7 @@ int xiafs_mkdir(struct inode * dir, const char * name, int len, int mode)
        return -ENOSPC;
     }
     de->d_ino = inode->i_ino;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     dir->i_nlink++;
     dir->i_dirt = 1;
     iput(dir);
@@ -518,7 +518,7 @@ int xiafs_rmdir(struct inode * dir, const char * name, int len)
     if (inode->i_nlink != 2)
         printk("XIA-FS: empty directory has nlink!=2 (%s %d)\n", WHERE_ERR);
     xiafs_rm_entry(de, de_pre);
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     inode->i_nlink=0;
     inode->i_dirt=1;
     dir->i_nlink--;
@@ -566,7 +566,7 @@ repeat:
        inode->i_nlink=1;
     }
     xiafs_rm_entry(de, de_pre);
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
     dir->i_dirt = 1;
     inode->i_nlink--;
@@ -611,7 +611,7 @@ int xiafs_symlink(struct inode * dir, const char * name,
     for (i = 0; i < BLOCK_SIZE-1 && (c=*symname++); i++)
         name_block->b_data[i] = c;
     name_block->b_data[i] = 0;
-    name_block->b_dirt = 1;
+    dirtify_buffer(name_block, 1);
     brelse(name_block);
     inode->i_size = i;
     inode->i_dirt = 1;
@@ -624,7 +624,7 @@ int xiafs_symlink(struct inode * dir, const char * name,
        return -ENOSPC;
     }
     de->d_ino = inode->i_ino;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     iput(dir);
     iput(inode);
@@ -661,7 +661,7 @@ int xiafs_link(struct inode * oldinode, struct inode * dir,
        return -ENOSPC;
     }
     de->d_ino = oldinode->i_ino;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     iput(dir);
     oldinode->i_nlink++;
@@ -798,11 +798,11 @@ try_again:
         new_inode->i_nlink--;
        new_inode->i_dirt = 1;
     }
-    old_bh->b_dirt = 1;
-    new_bh->b_dirt = 1;
+    dirtify_buffer(old_bh, 1);
+    dirtify_buffer(new_bh, 1);
     if (dir_bh) {
         PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
-       dir_bh->b_dirt = 1;
+       dirtify_buffer(dir_bh, 1);
        old_dir->i_nlink--;
        new_dir->i_nlink++;
        old_dir->i_dirt = 1;
index 336dcb0ab3265ba2b1b3473f675d253d917aa4f7..6cae2507eb0c11a4e2e76bb8cd8a1d3e7c62b458 100644 (file)
@@ -104,7 +104,7 @@ repeat:
            retry = 1;
        else {
            *indp = 0;
-           ind_bh->b_dirt = 1;
+           dirtify_buffer(ind_bh, 1);
            inode->i_blocks-= 2 << XIAFS_ZSHIFT(inode->i_sb);
            xiafs_free_zone(inode->i_sb, tmp);
        }
@@ -157,7 +157,7 @@ repeat:
        retry |= trunc_indirect(inode, 
                                8+((1+i)<<XIAFS_ADDRS_PER_Z_BITS(inode->i_sb)), 
                                dindp);
-       dind_bh->b_dirt = 1;
+       dirtify_buffer(dind_bh, 1);
     }
     dindp = (u_long *) dind_bh->b_data;
     for (i = 0; i < XIAFS_ADDRS_PER_Z(inode->i_sb) && !(*dindp++); i++);
index 173d33352371ad4c02f83e2221e464be49af61de..16ebab99ade0b4cf5367c77c5724b58561f4b893 100644 (file)
@@ -103,6 +103,7 @@ extern unsigned long file_table_init(unsigned long start, unsigned long end);
 #define BLKRRPART 4703 /* re-read partition table */
 #define BLKGETSIZE 4704 /* return device size */
 #define BLKFLSBUF 4705 /* flush buffer cache */
+#define BLKRASET 4706 /* Set read ahead for block device */
 
 /* These are a few other constants  only used by scsi  devices */
 
@@ -210,7 +211,7 @@ struct file {
        off_t f_pos;
        unsigned short f_flags;
        unsigned short f_count;
-       unsigned short f_reada;
+       off_t f_reada;
        struct file *f_next, *f_prev;
        struct inode * f_inode;
        struct file_operations * f_op;
@@ -359,6 +360,12 @@ extern int nr_buffers;
 extern int buffermem;
 extern int nr_buffer_heads;
 
+/* Once the full cluster diffs are in place, this will be filled out a bit. */
+extern inline void dirtify_buffer(struct buffer_head * bh, int flag)
+{
+  bh->b_dirt = 1;
+}
+
 extern void check_disk_change(dev_t dev);
 extern void invalidate_inodes(dev_t dev);
 extern void invalidate_buffers(dev_t dev);
@@ -392,7 +399,8 @@ extern void brelse(struct buffer_head * buf);
 extern void set_blocksize(dev_t dev, int size);
 extern struct buffer_head * bread(dev_t dev, int block, int size);
 extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int prot);
-extern struct buffer_head * breada(dev_t dev,int block,...);
+extern struct buffer_head * breada(dev_t dev,int block, int size, 
+                                  unsigned int pos, unsigned int filesize);
 extern void put_super(dev_t dev);
 extern dev_t ROOT_DEV;
 
index ad391183e376aff7140fd5b10f30e8611be10061..e83874b7bb422943092ac7a668509b0794f6a53e 100644 (file)
 
 #define X(name)        { (void *) &name, "_" #name }
 
+#ifdef CONFIG_FTAPE
+extern char * ftape_big_buffer;
+extern void (*do_floppy)(void);
+#endif
+
 struct {
        void *addr;
        const char *name;
index 30ecb8782ddd81293a7e64b4735dadba7e58fbf6..d3914af85e7cb33c8ecd09bdd6666acde9c26d33 100644 (file)
@@ -902,7 +902,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
                        } else 
                                user_esp = regs->esp;
                }
-               if (error_code & 1)
+               if (error_code & PAGE_PRESENT)
                        do_wp_page(error_code, address, current, user_esp);
                else
                        do_no_page(error_code, address, current, user_esp);
@@ -1084,10 +1084,17 @@ void mem_init(unsigned long start_low_mem,
        /* mark usable pages in the mem_map[] */
        start_low_mem = PAGE_ALIGN(start_low_mem);
        start_mem = PAGE_ALIGN(start_mem);
-       while (start_low_mem < 0xA0000) {
+
+       /*
+        * IBM messed up *AGAIN* in their thinkpad: 0xA0000 -> 0x9F000.
+        * They seem to have done something stupid with the floppy
+        * controller as well..
+        */
+       while (start_low_mem < 0x9f000) {
                mem_map[MAP_NR(start_low_mem)] = 0;
                start_low_mem += PAGE_SIZE;
        }
+
        while (start_mem < high_memory) {
                mem_map[MAP_NR(start_mem)] = 0;
                start_mem += PAGE_SIZE;
@@ -1133,21 +1140,18 @@ void si_meminfo(struct sysinfo *val)
 
        i = high_memory >> PAGE_SHIFT;
        val->totalram = 0;
-       val->freeram = 0;
        val->sharedram = 0;
+       val->freeram = nr_free_pages << PAGE_SHIFT;
        val->bufferram = buffermem;
        while (i-- > 0)  {
                if (mem_map[i] & MAP_PAGE_RESERVED)
                        continue;
                val->totalram++;
-               if (!mem_map[i]) {
-                       val->freeram++;
+               if (!mem_map[i])
                        continue;
-               }
                val->sharedram += mem_map[i]-1;
        }
        val->totalram <<= PAGE_SHIFT;
-       val->freeram <<= PAGE_SHIFT;
        val->sharedram <<= PAGE_SHIFT;
        return;
 }
index e1874f2cf3724d8e82d0a8ce98bb79ba267db9ca..419681a066e2fa67caa2483cd7395c9393d90b1f 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/fcntl.h>
 #include <linux/socket.h>
 #include <linux/in.h>
+#include <linux/string.h>
 #include "inet.h"
 #include "dev.h"
 #include "ip.h"
index a3f17e710513e312f7a2da55f1513cf52f2e2cc7..d1840ce02757ffbecef468a77f9e3a4aaf0887b7 100644 (file)
@@ -44,6 +44,7 @@
  *             Linus Torvalds/ :       Memory leakage on fragmentation 
  *             Alan Cox        :       handling.
  *             Gerhard Koerting:       Forwarding uses IP priority hints
+ *             Teemu Rantanen  :       Fragment problems.
  *
  * To Fix:
  *             IP option processing is mostly not needed. ip_forward needs to know about routing rules
@@ -774,6 +775,7 @@ static struct sk_buff *ip_glue(struct ipq *qp)
        skb->len = (len - qp->maclen);
        skb->h.raw = skb->data;
        skb->free = 1;
+       skb->dev = qp->dev;
  
        /* Copy the original MAC and IP headers into the new buffer. */
        ptr = (unsigned char *) skb->h.raw;
index 20af8c0d4975a357107498936aa56340cf1f32d3..6be78d74da6a939e47de4e468061805f8ab8131b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/in.h>
+#include <linux/string.h>
 #include "inet.h"
 #include "dev.h"
 #include "ip.h"