]> git.neil.brown.name Git - history.git/commitdiff
Import 1.1.23 1.1.23
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:32 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:32 +0000 (15:09 -0500)
23 files changed:
Makefile
boot/head.S
drivers/block/README.sbpcd
drivers/block/floppy.c
drivers/block/sbpcd.c
drivers/char/n_tty.c
drivers/net/d_link.c [deleted file]
fs/binfmt_coff.c [deleted file]
fs/binfmt_elf.c [deleted file]
fs/exec.c
fs/msdos/misc.c
fs/proc/array.c
fs/proc/root.c
include/linux/cdrom.h
include/linux/mktime.h [deleted file]
include/linux/module.h
include/linux/sbpcd.h
init/main.c
kernel/ksyms.c
kernel/mktime.c [deleted file]
kernel/module.c
net/ddi.c [deleted file]
net/inet/tcp.c

index 1e9fd91825f9865e1f4c678ce6b5aa54f9295a5d..efa6d70814b19598e1b67011c582e13914d8fdd9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 22
+SUBLEVEL = 23
 
 all:   Version zImage
 
index 493fcbc16b3267611ea037001261681ca5f1ca7f..ff37a462e0c927ad09580cf3401359a388658bd9 100644 (file)
@@ -289,7 +289,7 @@ _tmp_floppy_area:
  * data (18*2*512 bytes).
  */
 _floppy_track_buffer:
-       .fill 512*2*18,1,0
+       .fill 512*2*36,1,0
 
 /* This is the default interrupt "handler" :-) */
 int_msg:
index 88473f34bc20fd77c2ea50a55a0282c1a28835a6..d8eda41f58968c52ef1701e53e3c871772bd792d 100644 (file)
@@ -1,11 +1,11 @@
-This README belongs to release 1.6 of the SoundBlaster Pro (Matsushita,
+This README belongs to release 2.0 of the SoundBlaster Pro (Matsushita,
 Kotobuki, Panasonic, CreativeLabs) CD-ROM driver for Linux.
 
 The driver is able to drive the whole family of IDE-style
 Matsushita/Kotobuki/Panasonic drives (the "double speed" versions like CR-562
 and CR-563, too), and it will work with the soundcard interfaces (SB Pro,
 SB 16, Galaxy, SoundFX, ...) and/or with the "no-sound" cards (Panasonic
-CI-101P, LaserMate, Aztech, ...).
+CI-101P, LaserMate, WDH-7001C, Aztech, ...).
 It should work too now with the "configurable" interface "Sequoia S-1000",
 which is found on the Spea Media FX sound card.
 The interface type has to get configured in /usr/include/linux/sbpcd.h, 
@@ -16,7 +16,10 @@ but it should work with "old" drives <2.01 ... >3.00 and with "new" drives
 (which count the releases around 0.75 or 1.00).
 
 Up to 4 drives are supported. CR-52x ("old") and CR-56x ("new") drives can be
-mixed, but the CR-521 ones are hard-wired to drive ID 0. 
+mixed, but the CR-521 ones are hard-wired to drive ID 0. The drives have to
+use different drive IDs, and each drive has to get a unique minor number
+(0...3), corresponding to it's drive ID. The drive IDs may be selected freely
+from 0 to 3 - they must not be in consecutive order.
 
 As Don Carroll, don@ds9.us.dell.com or FIDO 1:382/14, told me, it is possible
 to change old drives to any ID, too. He writes in this sense:
@@ -35,17 +38,20 @@ to change old drives to any ID, too. He writes in this sense:
    did not work with other values. If the values are not good,
    ID 3 behaves like ID 0."
 
-The drives have to use different drive IDs, but the same controller (it will
-be a little bit harder to support up to four interface cards -  but I plan to
-do it the day somebody wishes to connect a fifth drive).
-Each drive has to get a unique minor number (0...3), corresponding to it's
-drive ID. The drive IDs may be selected freely from 0 to 3 - they must not be
-in consecutive order.
+To use more than 4 drives (now that the single-speed CR-521's are as cheap as
+50$), you have to "duplicate" the driver. Just copy sbpcd.c into sbpcd2.c and
+change SBPCD_ISSUE accordingly.
 
 The driver supports reading of data from the CD and playing of audio tracks.
 The audio part should run with WorkMan, xcdplayer, with the "non-X11" products
 CDplayer and WorkBone - tell me if it is not compatible with other software.
 
+With the "new" drive family CR-562 and CR-563, the reading of audio frames is
+possible. This is currently implemented by an IOCTL function which reads only
+one frame of 2352 bytes at a time. The transfer rate is as slow as 32 kB/sec.
+This will get better, and the software interface may change. We have to 
+standardize it the day the SCSI driver supports it too.
+
 MultiSession is supported (even my "old" CR-521 can handle it), "ManySession"
 (not recommended, see below) alternatively.
 Photo CDs work, too. At ftp.gwdg.de:/pub/linux/hpcdtoppm/ is Hadmut Danisch's
@@ -106,6 +112,10 @@ To install:
    So, if the DOS driver tells you have drive id #3, you have to
         mknod /dev/<any_name> b 25 3
    
+   For a second interface board, you have to make nodes like
+        mknod /dev/sbpcd4 b 26 0
+   and so on. Use the MAJORs 26, 27, 28.
+
    If you further make a link like
         ln -s sbpcd /dev/cdrom
    you can use the name /dev/cdrom, too.
@@ -142,7 +152,12 @@ Those "many-session" CDs can get made by CDROM writers like Philips CDD 521.
 If you enable this feature, it is impossible to read true multisession CDs.
 
 The driver uses the "variable BLOCK_SIZE" feature. To use it, you have to
-specify "block=2048" as a mount option.
+specify "block=2048" as a mount option. Doing this will disable the direct
+execution of a binary from the CD; you have to copy it to a device with the
+standard BLOCK_SIZE (1024) before. So, do not use this if your system is
+directly "running from the CDROM" (like some of YGGDRASIL's installation
+variants). There are CDs on the market (like the german "unifix" Linux
+distribution) which MUST get handled with a block_size of 1024.
 
 
 Auto-probing at boot time:
@@ -199,6 +214,133 @@ The program CDplayer likes to talk to "/dev/mcd" only, xcdplayer wants
 them without the need of supplying parameters.
 
 
+Copying audio tracks:
+---------------------
+
+The following little program will copy track 2 of an audio CD into the file
+"track02":
+
+/*=================== begin program ========================================*/
+/*
+ * read an audio track from a CD
+ *
+ * (c) 1994 Eberhard Moenkeberg <emoenke@gwdg.de>
+ *          may be used & enhanced freely
+ *
+ * Due to non-existent sync bytes at the beginning of each audio frame,
+ * it is currently a kind of fortune if two consecutive frames fit together.
+ * Usually, they overlap, or a little piece is missing. This has to get
+ * fixed by higher-level software (reading until an overlap occurs, and then
+ * eliminate the overlapping bytes). Possibly the first read bytes of each
+ * frame must get discarded because they are read before we got synchronized.
+ * 
+ * This example program further is missing to obtain the SubChannel data
+ * which belong to each frame.
+ */
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <linux/cdrom.h>
+
+static struct cdrom_tochdr hdr;
+static struct cdrom_tocentry entry[100];
+static struct cdrom_read_audio arg;
+static u_char buffer[CD_FRAMESIZE_RAW];
+static int datafile, drive;
+static int i, j, limit, track, err;
+static char filename[32];
+
+main(int argc, char *argv[])
+{
+/*
+ * open /dev/cdrom
+ */
+  drive=open("/dev/cdrom", 0);
+  if (drive<0)
+    {
+      fprintf(stderr, "can't open drive.\n");
+      exit (-1);
+    }
+/*
+ * get TocHeader
+ */
+  fprintf(stdout, "getting TocHeader...\n");
+  err=ioctl(drive, CDROMREADTOCHDR, &hdr);
+  if (err!=0)
+    {
+      fprintf(stderr, "can't get TocHeader (error %d).\n", err);
+      exit (-1);
+    }
+  else
+    fprintf(stdout, "TocHeader: %d %d\n", hdr.cdth_trk0, hdr.cdth_trk1);
+/*
+ * get and display all TocEntries
+ */
+  fprintf(stdout, "getting TocEntries...\n");
+  for (i=1;i<=hdr.cdth_trk1;i++)
+    {
+      entry[i].cdte_track = i;
+      entry[i].cdte_format = CDROM_LBA;
+      err=ioctl(drive, CDROMREADTOCENTRY, &entry[i]);
+      if (err!=0)
+       {
+         fprintf(stderr, "can't get TocEntry #%d (error %d).\n", i, err);
+         exit (-1);
+       }
+      else
+       {
+         fprintf(stdout, "TocEntry #%d: %1X %1X %06X %02X\n",
+                entry[i].cdte_track,
+                entry[i].cdte_adr,
+                entry[i].cdte_ctrl,
+                entry[i].cdte_addr.lba,
+                entry[i].cdte_datamode);
+       }
+    }
+  fprintf(stdout, "got all TocEntries.\n");
+/*
+ * ask for track number (not implemented here)
+ */
+track=2;
+#if 0 /* just read a little piece */
+entry[track].cdte_addr.lba=170;
+entry[track+1].cdte_addr.lba=190;
+#endif
+/*
+ * read track into file
+ */
+  sprintf(filename, "track%02d\0", track);
+  datafile=creat(filename, 0755);
+  if (datafile<0)
+    {
+      fprintf(stderr, "can't open datafile %s.\n", filename);
+      exit (-1);
+    }
+  arg.addr.lba=entry[track].cdte_addr.lba;
+  arg.addr_format=CDROM_LBA; /* CDROM_MSF is still buggy, I know that */
+  arg.nframes=1;
+  arg.buf=&buffer[0];
+  limit=entry[track+1].cdte_addr.lba;
+  for (i=arg.addr.lba;i<limit;i++)
+    {
+      err=ioctl(drive, CDROMREADAUDIO, &arg);
+      if (err!=0)
+       {
+         fprintf(stderr, "can't read frame #%d (error %d).\n", 
+                i-entry[track].cdte_addr.lba+1, err);
+         exit (-1);
+       }
+      j=write(datafile, &buffer[0], CD_FRAMESIZE_RAW);
+      if (j!=CD_FRAMESIZE_RAW)
+       {
+         fprintf(stderr,"I/O error (datafile) at frame %d\n",
+                i-entry[track].cdte_addr.lba+1);
+       }
+      arg.addr.lba++;
+    }
+}
+/*===================== end program ========================================*/
+
+
 Known problems:
 ---------------
 
@@ -212,9 +354,6 @@ All attempts to read the UPC/EAN code result in a stream of zeroes. All my
 drives are telling there is no UPC/EAN code on disk or there is, but it is an
 all-zero number.
 
-My attempts to read audio tracks like data files are of no success. Contact me,
-if you have an idea, please.
-
 Bug reports, comments, wishes, donations (technical information is a donation,
 too :-) etc. to
                          emoenke@gwdg.de
index a65fa4f84fa3641d1eff87c1a11d04d86f2a0259..a79128be8056fbb29f05d1032281009b0616ffa7 100644 (file)
  * work.
  */
 
+/* 1994/6/24 --bbroad-- added the floppy table entries and made
+ * minor modifications to allow 2.88 floppies to be run. 
+ */
+
+
 #define REALLY_SLOW_IO
 #define FLOPPY_IRQ 6
 #define FLOPPY_DMA 2
+#define FDC_FIFO_UNTESTED           /* -bb */
 
 #include <linux/sched.h>
 #include <linux/fs.h>
@@ -77,6 +83,7 @@
 #include <linux/errno.h>
 
 #include <asm/dma.h>
+#include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/segment.h>
@@ -110,13 +117,14 @@ static unsigned char running = 0;
  * Maximum disk size (in kilobytes). This default is used whenever the
  * current disk size is unknown.
  */
-#define MAX_DISK_SIZE 1440
+#define MAX_DISK_SIZE 2880 /* was 1440 -bb */
 
 /*
  * Maximum number of sectors in a track buffer. Track buffering is disabled
  * if tracks are bigger.
  */
-#define MAX_BUFFER_SECTORS 18
+#define MAX_BUFFER_SECTORS 36 /* was 18 -bb */
+
 
 /*
  * The DMA channel used by the floppy controller cannot access data at
@@ -154,6 +162,8 @@ static struct floppy_struct floppy_type[] = {
        {  720, 9,2,40,1,0x23,0x01,0xDF,0x50,NULL },    /* 360kB in 1.2MB drive */
        { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,NULL },    /* 720kB in 1.2MB drive */
        { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL },    /* 1.44MB diskette */
+       { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,NULL },    /* 2.88MB diskette */
+       { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,NULL },    /* 2.88MB diskette */
 };
 
 /*
@@ -170,6 +180,10 @@ static struct floppy_struct floppy_types[] = {
        { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"720k" },    /* 3.5" 720kB diskette */
        { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"1.44M" },   /* 1.44MB diskette */
        { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"720k/AT" }, /* 3.5" 720kB diskette */
+       { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"2.88M-AMI" },   /* DUMMY */ 
+       { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"1.44M-AMI" },   /* Dummy */
+       { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"2.88M" },   /* 2.88MB diskette */ 
+       { 2880,18,2,80,0,0x1B,0x40,0xCF,0x6C,"1.44MX" },   /* 1.44MB diskette */ 
 };
 
 /* Auto-detection: Disk type used until the next media change occurs. */
@@ -186,13 +200,14 @@ struct floppy_struct user_params[4];
 
 static int floppy_sizes[] ={
        MAX_DISK_SIZE, MAX_DISK_SIZE, MAX_DISK_SIZE, MAX_DISK_SIZE,
-        360, 360 ,360, 360,
+        360, 360360, 360,
        1200,1200,1200,1200,
         360, 360, 360, 360,
         720, 720, 720, 720,
         360, 360, 360, 360,
         720, 720, 720, 720,
-       1440,1440,1440,1440
+       1440,1440,1440,1440,
+       2880,2880,2880,2880           /* -bb */
 };
 
 /*
@@ -269,6 +284,11 @@ extern char tmp_floppy_area[BLOCK_SIZE];
 extern char floppy_track_buffer[512*2*MAX_BUFFER_SECTORS];
 
 static void redo_fd_request(void);
+static void floppy_ready(void);
+static void recalibrate_floppy(void);
+
+static int floppy_grab_irq_and_dma(void);
+static void floppy_release_irq_and_dma(void);
 
 /*
  * These are global variables, as that's the easiest way to give
@@ -290,9 +310,7 @@ static unsigned char track = 0;
 static unsigned char seek_track = 0;
 static unsigned char current_track = NO_TRACK;
 static unsigned char command = 0;
-static unsigned char fdc_version = FDC_TYPE_STD;       /* FDC version code */
-
-static void floppy_ready(void);
+static unsigned char fdc_version = 0x90;       /* FDC version code */
 
 static void select_callback(unsigned long unused)
 {
@@ -794,8 +812,6 @@ static void transfer(void)
  * Special case - used after a unexpected interrupt (or reset)
  */
 
-static void recalibrate_floppy(void);
-
 static void recal_interrupt(void)
 {
        output_byte(FD_SENSEI);
@@ -1237,7 +1253,7 @@ static struct floppy_struct *find_base(int drive,int code)
 {
        struct floppy_struct *base;
 
-       if (code > 0 && code < 5) {
+       if (code > 0 && code < 7) {                            /* -bb*/
                base = &floppy_types[(code-1)*2];
                printk("fd%d is %s",drive,base->name);
                return base;
@@ -1273,6 +1289,9 @@ static int floppy_open(struct inode * inode, struct file * filp)
        int drive;
        int old_dev;
 
+       if (floppy_grab_irq_and_dma()) {
+               return -EBUSY;
+       }
        drive = inode->i_rdev & 3;
        old_dev = fd_device[drive];
        if (fd_ref[drive])
@@ -1295,6 +1314,7 @@ static void floppy_release(struct inode * inode, struct file * filp)
                printk("floppy_release with fd_ref == 0");
                fd_ref[inode->i_rdev & 3] = 0;
        }
+        floppy_release_irq_and_dma();
 }
 
 static struct file_operations floppy_fops = {
@@ -1360,10 +1380,6 @@ void floppy_init(void)
        timer_table[FLOPPY_TIMER].fn = floppy_shutdown;
        timer_active &= ~(1 << FLOPPY_TIMER);
        config_types();
-       if (irqaction(FLOPPY_IRQ,&floppy_sigaction))
-               printk("Unable to grab IRQ%d for the floppy driver\n", FLOPPY_IRQ);
-       if (request_dma(FLOPPY_DMA))
-               printk("Unable to grab DMA%d for the floppy driver\n", FLOPPY_DMA);
        /* Try to determine the floppy controller type */
        DEVICE_INTR = ignore_interrupt; /* don't ask ... */
        output_byte(FD_VERSION);        /* get FDC version code */
@@ -1382,9 +1398,31 @@ void floppy_init(void)
         * properly, so force a reset for the standard FDC clones,
         * to avoid interrupt garbage.
         */
-
        if (fdc_version == FDC_TYPE_STD) {
                initial_reset_flag = 1;
                reset_floppy();
        }
 }
+
+static int floppy_grab_irq_and_dma(void)
+{
+       if (irqaction(FLOPPY_IRQ,&floppy_sigaction)) {
+               printk("Unable to grab IRQ%d for the floppy driver\n", FLOPPY_IRQ);
+               return -1;
+       }
+       if (request_dma(FLOPPY_DMA)) {
+               printk("Unable to grab DMA%d for the floppy driver\n", FLOPPY_DMA);
+               free_irq(FLOPPY_IRQ);
+               return -1;
+       }
+       enable_irq(FLOPPY_IRQ);
+       return 0;
+}
+
+static void floppy_release_irq_and_dma(void)
+{
+       disable_dma(FLOPPY_DMA);
+       free_dma(FLOPPY_DMA);
+       disable_irq(FLOPPY_IRQ);
+       free_irq(FLOPPY_IRQ);
+}
index 42f7e5d98d98ab885988445337c0e4d8816333fe..240edb541de039106022ac17b9ec543ed1b70e77 100644 (file)
@@ -5,7 +5,7 @@
  *            and for "no-sound" interfaces like Lasermate and the
  *            Panasonic CI-101P.
  *
- *  NOTE:     This is release 1.6.
+ *  NOTE:     This is release 2.0.
  *            It works with my SbPro & drive CR-521 V2.11 from 2/92
  *            and with the new CR-562-B V0.75 on a "naked" Panasonic
  *            CI-101P interface. And vice versa. 
  *       called as it should I fear it must get synchronized for not to
  *       disturb the normal driver's activity.
  *
+ *  2.0  Version number bumped - two reasons:
+ *       - reading audio tracks as data works now with CR-562 and CR-563. We
+ *       currently do it by an IOCTL (yet has to get standardized), one frame
+ *       at a time; that is pretty slow. But it works.
+ *       - we are maintaining now up to 4 interfaces (each up to 4 drives):
+ *       did it the easy way - a different MAJOR (25, 26, ...) and a different
+ *       copy of the driver (sbpcd.c, sbpcd2.c, sbpcd3.c, sbpcd4.c - only
+ *       distinguished by the value of SBPCD_ISSUE and the driver's name),
+ *       and a common sbpcd.h file.
+ *       Bettered the "ReadCapacity error" problem with old CR-52x drives (the
+ *       drives sometimes need a manual "eject/insert" before work): just
+ *       reset the drive and do again. Needs lots of resets here and sometimes
+ *       that does not cure, so this can't be the solution.
+ *
  *     special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine
  *     elaborated speed-up experiments (and the fabulous results!), for
  *     the "push" towards load-free wait loops, and for the extensive mail
  *
  */
 
+#define SBPCD_ISSUE 1 /* change to 2, 3, 4 for multiple interface boards */
+
 #include <linux/config.h>
 #include <linux/errno.h>
 
 #include <linux/kernel.h>
 #include <linux/cdrom.h>
 #include <linux/ioport.h>
+#include <linux/major.h> 
 #include <linux/sbpcd.h>
 #include <linux/string.h>
-#include <linux/major.h> 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/segment.h>
 #include <stdarg.h>
 
+#if !(SBPCD_ISSUE-1)
 #define MAJOR_NR MATSUSHITA_CDROM_MAJOR
+#endif
+#if !(SBPCD_ISSUE-2)
+#define MAJOR_NR MATSUSHITA_CDROM2_MAJOR /* second driver issue */
+#endif
+#if !(SBPCD_ISSUE-3)
+#define MAJOR_NR MATSUSHITA_CDROM3_MAJOR /* third driver issue */
+#endif
+#if !(SBPCD_ISSUE-4)
+#define MAJOR_NR MATSUSHITA_CDROM4_MAJOR /* fourth driver issue */
+#endif
+
 #include "blk.h"
 
-#define VERSION "1.6 Eberhard Moenkeberg <emoenke@gwdg.de>"
+#define VERSION "2.0 Eberhard Moenkeberg <emoenke@gwdg.de>"
 
 #define SBPCD_DEBUG
 
 #define XA_TEST2
 
 #define TEST_UPC 0
-#define READ_AUDIO 0 /* does not work today (the drives won't read audio) */
-
+#define READ_AUDIO 1
+#define SPEA_TEST 0
+#define PRINTK_BUG 0
+#define TEST_STI 0
 /*==========================================================================*/
+/*
+ * provisions for more than 1 driver issues
+ * currently up to 4 drivers, expandable
+ */
+#if !(SBPCD_ISSUE-1)
+#define SBPCD_IOCTL_F sbpcd_ioctl
+#define SBPCD_IOCTL(a,b,c,d) sbpcd_ioctl(a,b,c,d)
+#define DO_SBPCD_REQUEST(a) do_sbpcd_request(a)
+#define SBPCD_OPEN_F sbpcd_open
+#define SBPCD_OPEN(a,b) sbpcd_open(a,b)
+#define SBPCD_RELEASE_F sbpcd_release
+#define SBPCD_RELEASE(a,b) sbpcd_release(a,b)
+#define SBPCD_SETUP(a,b) sbpcd_setup(a,b)
+#define SBPCD_INIT(a,b) sbpcd_init(a,b)
+#define SBPCD_MEDIA_CHANGE(a,b) check_sbpcd_media_change(a,b)
+#endif
+#if !(SBPCD_ISSUE-2)
+#define SBPCD_IOCTL_F sbpcd2_ioctl
+#define SBPCD_IOCTL(a,b,c,d) sbpcd2_ioctl(a,b,c,d)
+#define DO_SBPCD_REQUEST(a) do_sbpcd2_request(a)
+#define SBPCD_OPEN_F sbpcd2_open
+#define SBPCD_OPEN(a,b) sbpcd2_open(a,b)
+#define SBPCD_RELEASE_F sbpcd2_release
+#define SBPCD_RELEASE(a,b) sbpcd2_release(a,b)
+#define SBPCD_SETUP(a,b) sbpcd2_setup(a,b)
+#define SBPCD_INIT(a,b) sbpcd2_init(a,b)
+#define SBPCD_MEDIA_CHANGE(a,b) check_sbpcd2_media_change(a,b)
+#endif
+#if !(SBPCD_ISSUE-3)
+#define SBPCD_IOCTL_F sbpcd3_ioctl
+#define SBPCD_IOCTL(a,b,c,d) sbpcd3_ioctl(a,b,c,d)
+#define DO_SBPCD_REQUEST(a) do_sbpcd3_request(a)
+#define SBPCD_OPEN_F sbpcd3_open
+#define SBPCD_OPEN(a,b) sbpcd3_open(a,b)
+#define SBPCD_RELEASE_F sbpcd3_release
+#define SBPCD_RELEASE(a,b) sbpcd3_release(a,b)
+#define SBPCD_SETUP(a,b) sbpcd3_setup(a,b)
+#define SBPCD_INIT(a,b) sbpcd3_init(a,b)
+#define SBPCD_MEDIA_CHANGE(a,b) check_sbpcd3_media_change(a,b)
+#endif
+#if !(SBPCD_ISSUE-4)
+#define SBPCD_IOCTL_F sbpcd4_ioctl
+#define SBPCD_IOCTL(a,b,c,d) sbpcd4_ioctl(a,b,c,d)
+#define DO_SBPCD_REQUEST(a) do_sbpcd4_request(a)
+#define SBPCD_OPEN_F sbpcd4_open
+#define SBPCD_OPEN(a,b) sbpcd4_open(a,b)
+#define SBPCD_RELEASE_F sbpcd4_release
+#define SBPCD_RELEASE(a,b) sbpcd4_release(a,b)
+#define SBPCD_SETUP(a,b) sbpcd4_setup(a,b)
+#define SBPCD_INIT(a,b) sbpcd4_init(a,b)
+#define SBPCD_MEDIA_CHANGE(a,b) check_sbpcd4_media_change(a,b)
+#endif
 /*==========================================================================*/
-
 #if MANY_SESSION
 #undef LONG_TIMING
 #define LONG_TIMING 1
@@ -215,8 +296,6 @@ static int autoprobe[] =
   0x340, 0, /* Lasermate, CI-101P */
   0x360, 0, /* Lasermate, CI-101P */
   0x270, 1, /* Soundblaster 16 */
-  0x630, 0, /* "sound card #9" (default) */
-  0x650, 0, /* "sound card #9" */
   0x670, 0, /* "sound card #9" */
   0x690, 0, /* "sound card #9" */
   0x330, 2, /* SPEA Media FX (default) */
@@ -230,6 +309,9 @@ static int autoprobe[] =
   0x370, 0, /* Lasermate, CI-101P */
   0x290, 1, /* Soundblaster 16 */
   0x310, 0, /* Lasermate, CI-101P */
+/* excluded due to incomplete address decoding of the SbPro card */
+  0x630, 0, /* "sound card #9" (default) */
+  0x650, 0, /* "sound card #9" */
 #endif
 };
 
@@ -242,6 +324,7 @@ static int autoprobe[] =
  */
 static void sbp_read_cmd(void);
 static int  sbp_data(void);
+static int cmd_out(void);
 
 /*==========================================================================*/
 
@@ -273,22 +356,28 @@ static int  sbp_data(void);
  * (1<<DBG_LCK)  door (un)lock info
  * (1<<DBG_SQ)   dump SubQ frame
  * (1<<DBG_AUD)  "read audio" debugging
+ * (1<<DBG_SEQ)  Sequoia interface configuration trace
  * (1<<DBG_000)  unnecessary information
  */
 #if 1
 static int sbpcd_debug =  (1<<DBG_INF) | (1<<DBG_WRN);
 #else
+#if SPEA_TEST
+static int sbpcd_debug =  (1<<DBG_INF) |
+                          (1<<DBG_INI) |
+                          (1<<DBG_ID)  |
+                          (1<<DBG_SEQ);
+#else
 static int sbpcd_debug =  (1<<DBG_INF) |
                           (1<<DBG_TOC) |
                           (1<<DBG_UPC) |
-                          (1<<DBG_IOC) |
-                          (1<<DBG_XA)  |
+                          (1<<DBG_TIM) |
                           (1<<DBG_LCK) |
                           (1<<DBG_CHK) |
                           (1<<DBG_AUD) |
-                          (1<<DBG_BSZ) |
                           (1<<DBG_IOX);
 #endif
+#endif
 static int sbpcd_ioaddr = CDROM_PORT;  /* default I/O base address */
 static int sbpro_type = SBPRO;
 static int CDo_command, CDo_reset;
@@ -301,9 +390,10 @@ static struct cdrom_tochdr tochdr;
 static struct cdrom_tocentry tocentry;
 static struct cdrom_subchnl SC;
 static struct cdrom_volctrl volctrl;
-char *str_sb = "SoundBlaster";
-char *str_lm = "LaserMate";
-char *str_sp = "SPEA";
+static struct cdrom_read_audio read_audio;
+static char *str_sb = "SoundBlaster";
+static char *str_lm = "LaserMate";
+static char *str_sp = "SPEA";
 char *type;
 
 /*==========================================================================*/
@@ -371,7 +461,7 @@ static struct {
 
   u_char mode;           /* read_mode: READ_M1, READ_M2, READ_SC, READ_AU */
 #if READ_AUDIO
-  u_char *aud_buf;                  /* Pointer to internal data buffer,
+  u_char *aud_buf;                  /* Pointer to audio data buffer,
                                  space allocated during sbpcd_init() */
 #endif READ_AUDIO
 
@@ -452,7 +542,7 @@ static struct {
 #ifdef SBPCD_DEBUG
 # define DPRINTF(x)    sbpcd_dprintf x
 
-void sbpcd_dprintf(int level, char *fmt, ...)
+static void sbpcd_dprintf(int level, char *fmt, ...)
 {
   char buff[256];
   va_list args;
@@ -464,6 +554,9 @@ void sbpcd_dprintf(int level, char *fmt, ...)
   vsprintf(buff, fmt, args);
   va_end(args);
   printk(buff);
+#if PRINTK_BUG
+  sti(); /* to avoid possible "printk" bug */
+#endif
 }
 
 #else
@@ -666,6 +759,7 @@ static int ResponseInfo(void)
   int i,j, st=0;
   u_long timeout;
 
+  DPRINTF((DBG_000,"SBPCD: ResponseInfo entered.\n"));
   if (current == task[0])
     for (i=0;i<response_count;i++)
       {
@@ -674,7 +768,11 @@ static int ResponseInfo(void)
            st=inb(CDi_status);
            if (!(st&s_not_result_ready)) break;
          }
-       if (j==0) return (-1);
+       if (j==0)
+         {
+           DPRINTF((DBG_SEQ,"SBPCD: ResponseInfo: not_result_ready (got %d of %d bytes).\n", i, response_count));
+           return (-1);
+         }
        infobuf[i]=inb(CDi_info);
       }
   else 
@@ -696,6 +794,7 @@ static int ResponseInfo(void)
          infobuf[i]=inb(CDi_info);
        }
     }
+  DPRINTF((DBG_000,"SBPCD: ResponseInfo: done.\n"));
   return (0);
 }
 /*==========================================================================*/
@@ -780,9 +879,8 @@ static void xx_ReadStatus(void)
     }
 }
 /*==========================================================================*/
-int xx_ReadError(void)
+static int xx_ReadError(void)
 {
-  int cmd_out(void);
   int i;
 
   clr_cmdbuf();
@@ -811,7 +909,7 @@ int xx_ReadError(void)
   return (i);
 }
 /*==========================================================================*/
-int cmd_out(void)
+static int cmd_out(void)
 {
   int i=0;
 
@@ -1283,6 +1381,8 @@ static int xx_ModeSelect(int framesize)
   DriveStruct[d].diskstate_flags &= ~frame_size_bit;
   clr_cmdbuf();
   DriveStruct[d].frame_size=framesize;
+  if (framesize==CD_FRAMESIZE_RAW) DriveStruct[d].sense_byte=0x82;
+  else DriveStruct[d].sense_byte=0x00;
 
   DPRINTF((DBG_XA,"SBPCD: xx_ModeSelect: %02X %04X\n",
           DriveStruct[d].sense_byte, DriveStruct[d].frame_size));
@@ -1658,14 +1758,17 @@ static void check_datarate(void)
 #ifdef CDMKE
   int i=0;
 
+  DPRINTF((DBG_IOX,"SBPCD: check_datarate entered.\n"));
   timed_out=0;
   datarate=0;
 
+#if TEST_STI
+  for (i=0;i<=1000;i++) printk(".");
+#endif
+
   /* set a timer to make (timed_out!=0) after 1.1 seconds */
 
   DPRINTF((DBG_TIM,"SBPCD: timer started (110).\n"));
-  sti(); /* to avoid possible "printf" bug */
-
   SET_TIMER(mark_timeout,110);
   do
     {
@@ -1700,12 +1803,14 @@ static int check_version(void)
 {
   int i, j;
 
+  DPRINTF((DBG_INI,"SBPCD: check_version entered.\n"));
   /* clear any pending error state */
   clr_cmdbuf();
   drvcmd[0]=0x82;
   response_count=9;
   flags_cmd_out=f_putcmd;
-  cmd_out();
+  i=cmd_out();
+  if (i<0) DPRINTF((DBG_INI,"SBPCD: cmd_82 returns %d (ok anyway).\n",i));
 
   /* read drive version */
   clr_cmdbuf();
@@ -1732,7 +1837,11 @@ static int check_version(void)
   else
     {
       for (i=0;i<8;i++) if (infobuf[i]!=drive_vendor[i]) break;
-      if (i!=8) return (-1);
+      if (i!=8)
+       {
+         DPRINTF((DBG_INI,"SBPCD: check_version: error.\n"));
+         return (-1);
+       }
       DriveStruct[d].drive_model[0]='2';
       DriveStruct[d].drive_model[1]='x';
       DriveStruct[d].drive_model[2]='-';
@@ -1754,6 +1863,7 @@ static int check_version(void)
   else if (j<211) DriveStruct[d].drv_type=drv_210;
   else if (j<300) DriveStruct[d].drv_type=drv_211;
   else DriveStruct[d].drv_type=drv_300;
+  DPRINTF((DBG_INI,"SBPCD: check_version done.\n"));
   return (0);
 }
 /*==========================================================================*/
@@ -1792,7 +1902,8 @@ static int check_drives(void)
        {
          ndrives++;
          DriveStruct[d].drv_options=drv_pattern[j];
-         if (!new_drive) DriveStruct[d].drv_options&=~(speed_auto|speed_300|speed_150);
+         if (!new_drive)
+           DriveStruct[d].drv_options&=~(speed_auto|speed_300|speed_150);
          printk("%sDrive %d: %s%.4s (%.4s)\n", printk_header,
                 DriveStruct[d].drv_minor,
                  drive_family,
@@ -1975,47 +2086,36 @@ static int ReadToC(void)
 /*==========================================================================*/
 static int DiskInfo(void)
 {
-  int i;
+  int i, j;
 
 #if READ_AUDIO
       DriveStruct[d].mode=READ_M1;
 #endif READ_AUDIO
 
-  i=SetSpeed();
-  if (i<0)
+#undef LOOP_COUNT
+#define LOOP_COUNT 20 /* needed for some "old" drives */
+
+  for (j=1;j<LOOP_COUNT;j++)
     {
-      DPRINTF((DBG_INF,"SBPCD: DiskInfo: first SetSpeed returns %d\n", i));
       i=SetSpeed();
       if (i<0)
        {
-         DPRINTF((DBG_INF,"SBPCD: DiskInfo: second SetSpeed returns %d\n", i));
-         return (i);
+         DPRINTF((DBG_INF,"SBPCD: DiskInfo: SetSpeed returns %d\n", i));
+         continue;
        }
-    }
-  i=xx_ModeSense();
-  if (i<0)
-    {
-      DPRINTF((DBG_INF,"SBPCD: DiskInfo: first xx_ModeSense returns %d\n", i));
       i=xx_ModeSense();
       if (i<0)
        {
-         DPRINTF((DBG_INF,"SBPCD: DiskInfo: second xx_ModeSense returns %d\n", i));
-         return (i);
+         DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ModeSense returns %d\n", i));
+         continue;
        }
-      return (i);
-    }
-  i=xx_ReadCapacity();
-  if (i<0)
-    {
-      DPRINTF((DBG_INF,"SBPCD: DiskInfo: first ReadCapacity returns %d\n", i));
       i=xx_ReadCapacity();
-      if (i<0)
-       {
-         DPRINTF((DBG_INF,"SBPCD: DiskInfo: second ReadCapacity returns %d\n", i));
-         return (i);
-       }
-      return (i);
+      if (i>=0) break;
+      DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadCapacity #%d returns %d\n", j, i));
+      i=DriveReset();
     }
+  if (j==LOOP_COUNT) return (-2); /* give up */
+
   i=xx_ReadTocDescr();
   if (i<0)
     {
@@ -2220,8 +2320,8 @@ static int sbp_status(void)
 /*
  * ioctl support, adopted from scsi/sr_ioctl.c and mcd.c
  */
-static int sbpcd_ioctl(struct inode *inode,struct file *file,
-                      u_int cmd, u_long arg)
+static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd,
+                      u_long arg)
 {
   int i, st;
 
@@ -2472,7 +2572,7 @@ static int sbpcd_ioctl(struct inode *inode,struct file *file,
       DriveStruct[d].mode=READ_M1;
       return (0);
 
-    case CDROMREADMODE2:
+    case CDROMREADMODE2: /* not useable at the moment */
       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADMODE2 requested.\n"));
       xx_ModeSelect(CD_FRAMESIZE_XA);
       xx_ModeSense();
@@ -2482,214 +2582,188 @@ static int sbpcd_ioctl(struct inode *inode,struct file *file,
 #if READ_AUDIO
     case CDROMREADAUDIO:
       { /* start of CDROMREADAUDIO */
-
-      int i=0, j=0, frame, block;
-      u_int try=0;
-      u_long timeout;
-      u_char *p;
-      u_int data_tries = 0;
-      u_int data_waits = 0;
-      u_int data_retrying = 0;
-      int status_tries;
-      int error_flag;
-      struct cdrom_aud aud_arg;
-
-      error_flag=0;
-
-#if 0
-#define AUD_FRM_SIZ CD_FRAMESIZE_RAW
-#else
-#define AUD_FRM_SIZ CD_FRAMESIZE_XA
-#endif
-
-      DPRINTF((DBG_IOC,"SBPCD: read_audio: ioctl: CDROMREADAUDIO requested.\n"));
-
-      i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_aud));
-      if (i) return (i);
-      memcpy_fromfs(&aud_arg, (void *) arg, sizeof(struct cdrom_aud));
-      i=verify_area(VERIFY_WRITE, aud_arg.buf, AUD_FRM_SIZ);
-      if (i) return (i);
-      DPRINTF((DBG_AUD,"SBPCD: read_audio: lba: %d, buffer: %08X\n", aud_arg.lba, aud_arg.buf));
-
-      DPRINTF((DBG_AUD,"SBPCD: read_audio: before xx_ReadStatus.\n"));
-      for (data_tries=5; data_tries>0; data_tries--)
-       {
-         DPRINTF((DBG_AUD,"SBPCD: data_tries=%d ...\n", data_tries));
-         DriveStruct[d].mode=READ_AU;
-         xx_ModeSelect(AUD_FRM_SIZ);
-         xx_ModeSense();
-
-
-         for (status_tries=3; status_tries > 0; status_tries--)
-           {
-             flags_cmd_out |= f_respo3;
-             xx_ReadStatus();
-             if (sbp_status() != 0) break;
-             sbp_sleep(1);    /* wait a bit, try again */
-           }
-         if (status_tries == 0)
-           {
-             DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: failed after 3 tries.\n"));
-             continue;
-           }
-         DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: ok.\n"));
-
-
-         block=aud_arg.lba;
-         flags_cmd_out = f_putcmd |
-                         f_respo2 |
-                          f_ResponseStatus |
-                          f_obey_p_check;
-
-
-
-
-         if (!new_drive)
-           {
-             flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
-             cmd_type=READ_M2;
-             drvcmd[0]=0x03;   /* "read XA frames" command for old drives */
-             drvcmd[1]=(block>>16)&0x000000ff;
-             drvcmd[2]=(block>>8)&0x000000ff;
-             drvcmd[3]=block&0x000000ff;
-             drvcmd[4]=0;
-             drvcmd[5]=1;   /* # of frames */
-             drvcmd[6]=0;
-           }
-         else /* if new_drive */
-           {
-             drvcmd[0]=0x10;              /* "read frames" command for new drives */
-             lba2msf(block,&drvcmd[1]); /* msf-bin format required */
-             drvcmd[4]=0;
-             drvcmd[5]=0;
-             drvcmd[6]=1;   /* # of frames */
-           }
-
-
-
-         DPRINTF((DBG_AUD,"SBPCD: read_audio: before giving \"read\" command.\n"));
-         for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
-
-         sbp_sleep(0);
-
-         DPRINTF((DBG_AUD,"SBPCD: read_audio: after giving \"read\" command.\n"));
-         for (frame=1;frame<2 && !error_flag; frame++)
-           {
-             try=maxtim_data;
-             for (timeout=jiffies+900; ; )
-               {
-                 for ( ; try!=0;try--)
-                   {
-                     j=inb(CDi_status);
-                     if (!(j&s_not_data_ready)) break;
-                     if (!(j&s_not_result_ready)) break;
-                     if (!new_drive) if (j&s_attention) break;
-                   }
-                 if (try != 0 || timeout <= jiffies) break;
-                 if (data_retrying == 0) data_waits++;
-                 data_retrying = 1;
-                 sbp_sleep(1);
-                 try = 1;
-               }
-             if (try==0)
-               {
-                 DPRINTF((DBG_INF,"SBPCD: read_audio: sbp_data: CDi_status timeout.\n"));
-                 error_flag++;
-                 break;
-               }
-             DPRINTF((DBG_INF,"SBPCD: read_audio: sbp_data: CDi_status ok.\n"));
-             
-             if (j&s_not_data_ready)
-               {
-                 printk("SBPCD: read_audio: sbp_data: DATA_READY timeout.\n");
-                 error_flag++;
-                 break;
-               }
-             
-             DPRINTF((DBG_AUD,"SBPCD: read_audio: before reading data.\n"));
-             CLEAR_TIMER;
-             error_flag=0;
-             p = DriveStruct[d].aud_buf;
-             if (sbpro_type==1) OUT(CDo_sel_d_i,0x01);
-             READ_DATA(CDi_data, p, AUD_FRM_SIZ);
-             if (sbpro_type==1) OUT(CDo_sel_d_i,0x00);
-             data_retrying = 0;
-           }
-         DPRINTF((DBG_AUD,"SBPCD: read_audio: after reading data.\n"));
-         if (error_flag)    /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
-           {
-             DPRINTF((DBG_AUD,"SBPCD: read_audio: read aborted by drive\n"));
+       int i=0, j=0, frame, block;
+       u_int try=0;
+       u_long timeout;
+       u_char *p;
+       u_int data_tries = 0;
+       u_int data_waits = 0;
+       u_int data_retrying = 0;
+       int status_tries;
+       int error_flag;
+
+       error_flag=0;
+
+       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADAUDIO requested.\n"));
+
+       i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio));
+       if (i) return (i);
+       memcpy_fromfs(&read_audio, (void *) arg, sizeof(struct cdrom_read_audio));
+       i=verify_area(VERIFY_WRITE, read_audio.buf, CD_FRAMESIZE_RAW);
+       if (i) return (i);
+
+       if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
+         block=msf2blk(read_audio.addr.lba);
+       else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
+         block=read_audio.addr.lba;
+       else return (-EINVAL);
+       if (read_audio.nframes!=1) return (-EINVAL);
+       DPRINTF((DBG_AUD,"SBPCD: read_audio: lba: %d, msf: %06X\n",
+                block, blk2msf(block)));
+       DPRINTF((DBG_AUD,"SBPCD: read_audio: before xx_ReadStatus.\n"));
+       for (data_tries=5; data_tries>0; data_tries--)
+         {
+           DPRINTF((DBG_AUD,"SBPCD: data_tries=%d ...\n", data_tries));
+           DriveStruct[d].mode=READ_AU;
+           xx_ModeSelect(CD_FRAMESIZE_RAW);
+           xx_ModeSense();
+           for (status_tries=3; status_tries > 0; status_tries--)
+             {
+               flags_cmd_out |= f_respo3;
+               xx_ReadStatus();
+               if (sbp_status() != 0) break;
+               sbp_sleep(1);    /* wait a bit, try again */
+             }
+           if (status_tries == 0)
+             {
+               DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: failed after 3 tries.\n"));
+               continue;
+             }
+           DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: ok.\n"));
+           
+           flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
+           if (!new_drive)
+             {
+               flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
+               cmd_type=READ_M2;
+               drvcmd[0]=0x03;   /* "read XA frames" command for old drives */
+               drvcmd[1]=(block>>16)&0x000000ff;
+               drvcmd[2]=(block>>8)&0x000000ff;
+               drvcmd[3]=block&0x000000ff;
+               drvcmd[4]=0;
+               drvcmd[5]=1;   /* # of frames */
+               drvcmd[6]=0;
+             }
+           else /* if new_drive */
+             {
+               drvcmd[0]=0x10;              /* "read frames" command for new drives */
+               lba2msf(block,&drvcmd[1]); /* msf-bin format required */
+               drvcmd[4]=0;
+               drvcmd[5]=0;
+               drvcmd[6]=1;   /* # of frames */
+             }
+           DPRINTF((DBG_AUD,"SBPCD: read_audio: before giving \"read\" command.\n"));
+           for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
+           sbp_sleep(0);
+           DPRINTF((DBG_AUD,"SBPCD: read_audio: after giving \"read\" command.\n"));
+           for (frame=1;frame<2 && !error_flag; frame++)
+             {
+               try=maxtim_data;
+               for (timeout=jiffies+900; ; )
+                 {
+                   for ( ; try!=0;try--)
+                     {
+                       j=inb(CDi_status);
+                       if (!(j&s_not_data_ready)) break;
+                       if (!(j&s_not_result_ready)) break;
+                       if (!new_drive) if (j&s_attention) break;
+                     }
+                   if (try != 0 || timeout <= jiffies) break;
+                   if (data_retrying == 0) data_waits++;
+                   data_retrying = 1;
+                   sbp_sleep(1);
+                   try = 1;
+                 }
+               if (try==0)
+                 {
+                   DPRINTF((DBG_INF,"SBPCD: read_audio: sbp_data: CDi_status timeout.\n"));
+                   error_flag++;
+                   break;
+                 }
+               DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_data: CDi_status ok.\n"));
+               if (j&s_not_data_ready)
+                 {
+                   printk("SBPCD: read_audio: sbp_data: DATA_READY timeout.\n");
+                   error_flag++;
+                   break;
+                 }
+               DPRINTF((DBG_AUD,"SBPCD: read_audio: before reading data.\n"));
+               CLEAR_TIMER;
+               error_flag=0;
+               p = DriveStruct[d].aud_buf;
+               if (sbpro_type==1) OUT(CDo_sel_d_i,0x01);
+               READ_DATA(CDi_data, p, CD_FRAMESIZE_RAW);
+               if (sbpro_type==1) OUT(CDo_sel_d_i,0x00);
+               data_retrying = 0;
+             }
+           DPRINTF((DBG_AUD,"SBPCD: read_audio: after reading data.\n"));
+           if (error_flag)    /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
+             {
+               DPRINTF((DBG_AUD,"SBPCD: read_audio: read aborted by drive\n"));
 #if 0000
-             i=DriveReset();                /* ugly fix to prevent a hang */
+               i=DriveReset();                /* ugly fix to prevent a hang */
 #endif 0000
-             continue;
-           }
-
-         if (!new_drive)
-           {
-             i=maxtim_data;
-             for (timeout=jiffies+900; timeout > jiffies; timeout--)
-               {
-                 for ( ;i!=0;i--)
-                   {
-                     j=inb(CDi_status);
-                     if (!(j&s_not_data_ready)) break;
-                     if (!(j&s_not_result_ready)) break;
-                     if (j&s_attention) break;
-                   }
-                 if (i != 0 || timeout <= jiffies) break;
-                 sbp_sleep(0);
-                 i = 1;
-               }
-             if (i==0) { DPRINTF((DBG_AUD,"SBPCD: read_audio: STATUS TIMEOUT AFTER READ")); }
-             if (!(j&s_attention))
-               {
-                 DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n"));
-                 i=DriveReset();  /* ugly fix to prevent a hang */
+               continue;
+             }
+           if (!new_drive)
+             {
+               i=maxtim_data;
+               for (timeout=jiffies+900; timeout > jiffies; timeout--)
+                 {
+                   for ( ;i!=0;i--)
+                     {
+                       j=inb(CDi_status);
+                       if (!(j&s_not_data_ready)) break;
+                       if (!(j&s_not_result_ready)) break;
+                       if (j&s_attention) break;
+                     }
+                   if (i != 0 || timeout <= jiffies) break;
+                   sbp_sleep(0);
+                   i = 1;
+                 }
+               if (i==0) { DPRINTF((DBG_AUD,"SBPCD: read_audio: STATUS TIMEOUT AFTER READ")); }
+               if (!(j&s_attention))
+                 {
+                   DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n"));
+                   i=DriveReset();  /* ugly fix to prevent a hang */
                  continue;
-               }
-           }
-
-         do
-           {
-             if (!new_drive) xx_ReadStatus();
-             i=ResponseStatus();  /* builds status_byte, returns orig. status (old) or faked p_success_old (new) */
-             if (i<0) { DPRINTF((DBG_AUD,
-                                 "SBPCD: read_audio: xx_ReadStatus error after read: %02X\n",
-                                 DriveStruct[d].status_byte));
-                        continue; /* FIXME */
-                      }
-           }
-         while ((!new_drive)&&(!st_check)&&(!(i&p_success_old)));
-         if (st_check)
-           {
-             i=xx_ReadError();
-             DPRINTF((DBG_AUD,"SBPCD: read_audio: xx_ReadError was necessary after read: %02X\n",i));
-             continue;
-           }
-         memcpy_tofs((u_char *) aud_arg.buf,
-                     (u_char *) DriveStruct[d].aud_buf, AUD_FRM_SIZ);
-         DPRINTF((DBG_AUD,"SBPCD: read_audio: memcpy_tofs done.\n"));
-         break;
-       }
-      xx_ModeSelect(CD_FRAMESIZE);
-      xx_ModeSense();
-      DriveStruct[d].mode=READ_M1;
-
-
-      if (data_tries == 0)
-       {
-         DPRINTF((DBG_AUD,"SBPCD: read_audio: failed after 5 tries.\n"));
-         return (-8);
-       }
-      DPRINTF((DBG_AUD,"SBPCD: read_audio: successful return.\n"));
-      return (0);
-    } /* end of CDROMREADAUDIO */
+                 }
+             }
+           do
+             {
+               if (!new_drive) xx_ReadStatus();
+               i=ResponseStatus();  /* builds status_byte, returns orig. status (old) or faked p_success_old (new) */
+               if (i<0) { DPRINTF((DBG_AUD,
+                                   "SBPCD: read_audio: xx_ReadStatus error after read: %02X\n",
+                                   DriveStruct[d].status_byte));
+                          continue; /* FIXME */
+                        }
+             }
+           while ((!new_drive)&&(!st_check)&&(!(i&p_success_old)));
+           if (st_check)
+             {
+               i=xx_ReadError();
+               DPRINTF((DBG_AUD,"SBPCD: read_audio: xx_ReadError was necessary after read: %02X\n",i));
+               continue;
+             }
+           memcpy_tofs((u_char *) read_audio.buf,
+                       (u_char *) DriveStruct[d].aud_buf, CD_FRAMESIZE_RAW);
+           DPRINTF((DBG_AUD,"SBPCD: read_audio: memcpy_tofs done.\n"));
+           break;
+         }
+       xx_ModeSelect(CD_FRAMESIZE);
+       xx_ModeSense();
+       DriveStruct[d].mode=READ_M1;
+       if (data_tries == 0)
+         {
+           DPRINTF((DBG_AUD,"SBPCD: read_audio: failed after 5 tries.\n"));
+           return (-8);
+         }
+       DPRINTF((DBG_AUD,"SBPCD: read_audio: successful return.\n"));
+       return (0);
+      } /* end of CDROMREADAUDIO */
 #endif READ_AUDIO
 
-
-
-
     case BLKRASET:
       if(!suser())  return -EACCES;
       if(!inode->i_rdev) return -EINVAL;
@@ -2726,7 +2800,7 @@ static void sbp_transfer(void)
 /*
  *  I/O request routine, called from Linux kernel.
  */
-static void do_sbpcd_request(void)
+static void DO_SBPCD_REQUEST(void)
 {
   u_int block;
   int dev;
@@ -2836,7 +2910,7 @@ static void sbp_read_cmd(void)
          block=DriveStruct[d].lba_multi+block;
        }
 #else
-      if ( (block==166) && (DriveStruct[d].f_multisession) && (multisession_valid) )
+      if ( (block==CD_BLOCK_OFFSET+16) && (DriveStruct[d].f_multisession) && (multisession_valid) )
        {
          DPRINTF((DBG_MUL,"SBPCD: MultiSession: use %08X for %08X (msf)\n",
                         blk2msf(DriveStruct[d].lba_multi+16),
@@ -3064,7 +3138,7 @@ static int sbp_data(void)
 /*
  *  Open the device special file.  Check that a disk is in. Read TOC.
  */
-int sbpcd_open(struct inode *ip, struct file *fp)
+int SBPCD_OPEN(struct inode *ip, struct file *fp)
 {
   int i;
 
@@ -3100,8 +3174,12 @@ int sbpcd_open(struct inode *ip, struct file *fp)
  */
   DPRINTF((DBG_LCK,"SBPCD: open_count: %d -> %d\n",
           DriveStruct[d].open_count,DriveStruct[d].open_count+1));
-  if (++DriveStruct[d].open_count==1) yy_LockDoor(1);
-  
+  if (++DriveStruct[d].open_count==1)
+    {
+      do
+       i=yy_LockDoor(1);
+      while (i!=0);
+    }
   if (!st_spinning) xx_SpinUp();
 
   i=DiskInfo();
@@ -3113,7 +3191,7 @@ int sbpcd_open(struct inode *ip, struct file *fp)
 /*
  *  On close, we flush all sbp blocks from the buffer cache.
  */
-static void sbpcd_release(struct inode * ip, struct file * file)
+static void SBPCD_RELEASE(struct inode * ip, struct file * file)
 {
   int i;
 
@@ -3153,10 +3231,10 @@ static struct file_operations sbpcd_fops =
   block_write,            /* write - general block-dev write */
   NULL,                   /* readdir - bad */
   NULL,                   /* select */
-  sbpcd_ioctl,            /* ioctl */
+  SBPCD_IOCTL_F,          /* ioctl */
   NULL,                   /* mmap */
-  sbpcd_open,             /* open */
-  sbpcd_release,          /* release */
+  SBPCD_OPEN_F,           /* open */
+  SBPCD_RELEASE_F,        /* release */
   NULL,                   /* fsync */
   NULL                    /* fasync */
 };
@@ -3178,7 +3256,7 @@ static struct file_operations sbpcd_fops =
  * not the soundcard base address.
  *
  */
-void sbpcd_setup(char *s, int *p)
+void SBPCD_SETUP(char *s, int *p)
 {
   DPRINTF((DBG_INI,"SBPCD: sbpcd_setup called with %04X,%s\n",p[1], s));
   sbpro_type=0;
@@ -3208,7 +3286,7 @@ void sbpcd_setup(char *s, int *p)
  *     -> interface type "Matsushita/Panasonic" (not Sony or Mitsumi)
  *     -> I/O base address (0x320, 0x330, 0x340, 0x350)
  */
-int config_spea(void)
+static int config_spea(void)
 {
   int n_ports=0x10; /* 2:0x00, 8:0x10, 16:0x20, 32:0x30 */
   int irq_number=0; /* 2:0x01, 7:0x03, 12:0x05, 15:0x07, OFF:0x00 */
@@ -3225,7 +3303,7 @@ int config_spea(void)
   i=inb(SPEA_REG_1);
   if (i!=0x0F)
     {
-      DPRINTF((DBG_INF,"SBPCD: no SPEA interface at %04X present.\n",
+      DPRINTF((DBG_SEQ,"SBPCD: no SPEA interface at %04X present.\n",
               sbpcd_ioaddr));
       return (-1); /* no interface found */
     }
@@ -3249,18 +3327,22 @@ int config_spea(void)
   OUT(SPEA_REG_2,i);
 
   sbpro_type = 0; /* acts like a LaserMate interface now */
+  DPRINTF((DBG_SEQ,"SBPCD: found SPEA interface at %04X.\n",
+          sbpcd_ioaddr));
   return (0);
 }
 /*==========================================================================*/
 /*
  *  Test for presence of drive and initialize it.  Called at boot time.
  */
-u_long sbpcd_init(u_long mem_start, u_long mem_end)
+unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end)
 {
   int i=0, j=0;
   int addr[2]={1, CDROM_PORT};
   int port_index;
    
+  sti(); /* necessary, has consequences for other drivers' init routines */
+
   DPRINTF((DBG_INF,"SBPCD version %s\n", VERSION));
 
   DPRINTF((DBG_INF,"SBPCD: Looking for a SoundBlaster/Matsushita CD-ROM drive\n"));
@@ -3279,7 +3361,6 @@ u_long sbpcd_init(u_long mem_start, u_long mem_end)
   DPRINTF((DBG_WRN,"SBPCD: with your REAL address.\n"));
   DPRINTF((DBG_WRN,"SBPCD: = = = = = = = = = = END of WARNING = = = = = = = = = =\n"));
   DPRINTF((DBG_WRN,"SBPCD: \n"));
-  sti(); /* to avoid possible "printk" bug */
 
   autoprobe[0]=sbpcd_ioaddr; /* possibly changed by kernel command line */
   autoprobe[1]=sbpro_type; /* possibly changed by kernel command line */
@@ -3288,48 +3369,54 @@ u_long sbpcd_init(u_long mem_start, u_long mem_end)
     {
       addr[1]=autoprobe[port_index];
       if (check_region(addr[1],4)) continue;
-      DPRINTF((DBG_INI,"SBPCD: check_region done.\n"));
+      DPRINTF((DBG_INI,"SBPCD: check_region: free.\n"));
       if (autoprobe[port_index+1]==0) type=str_lm;
       else if (autoprobe[port_index+1]==1) type=str_sb;
       else type=str_sp;
-      sbpcd_setup(type, addr);
+      SBPCD_SETUP(type, addr);
       DPRINTF((DBG_INF,"SBPCD: Trying to detect a %s CD-ROM drive at 0x%X.\n",
                     type, CDo_command));
 
       DPRINTF((DBG_INF,"SBPCD: - "));
-      sti(); /* to avoid possible "printk" bug */
       if (autoprobe[port_index+1]==2)
        {
          i=config_spea();
-         if (i<0) continue;
+         if (i<0)
+           {
+             DPRINTF((DBG_INF,"\n"));
+             continue;
+           }
        }
       i=check_drives();
       DPRINTF((DBG_INI,"SBPCD: check_drives done.\n"));
-      sti(); /* to avoid possible "printk" bug */
       if (i>=0) break; /* drive found */
       DPRINTF((DBG_INF,"\n"));
-      sti(); /* to avoid possible "printk" bug */
     } /* end of cycling through the set of possible I/O port addresses */
 
   if (ndrives==0)
     {
       printk("SBPCD: No drive found.\n");
-      sti();
+#if PRINTK_BUG
+      sti(); /* to avoid possible "printk" bug */
+#endif
       return (mem_start);
     }
 
   if (port_index>0)
     {
       printk("SBPCD: You should configure sbpcd.h for your hardware.\n");
-      sti();
+#if PRINTK_BUG
+      sti(); /* to avoid possible "printk" bug */
+#endif
     }
 
   printk("SBPCD: %d %s CD-ROM drive(s) at 0x%04X.\n",
           ndrives, type, CDo_command);
+#if PRINTK_BUG
   sti(); /* to avoid possible "printk" bug */
+#endif
   check_datarate();
   DPRINTF((DBG_INI,"SBPCD: check_datarate done.\n"));
-  sti(); /* to avoid possible "printk" bug */
 
   for (j=0;j<NR_SBPCD;j++)
     {
@@ -3354,16 +3441,13 @@ u_long sbpcd_init(u_long mem_start, u_long mem_end)
            {
              i=xx_ReadError();
              DPRINTF((DBG_INI,"SBPCD: init: xx_ReadError returns %d\n",i));
-             sti(); /* to avoid possible "printk" bug */
            }
        }
       DPRINTF((DBG_INI,"SBPCD: init: first GetStatus: %d\n",i));
-      sti(); /* to avoid possible "printk" bug */
       if (DriveStruct[d].error_byte==aud_12)
        {
          do { i=GetStatus();
               DPRINTF((DBG_INI,"SBPCD: init: second GetStatus: %02X\n",i));
-              sti(); /* to avoid possible "printk" bug */
               if (i<0) break;
               if (!st_caddy_in) break;
             }
@@ -3382,7 +3466,9 @@ u_long sbpcd_init(u_long mem_start, u_long mem_end)
   if (register_blkdev(MAJOR_NR, "sbpcd", &sbpcd_fops) != 0)
     {
       printk("SBPCD: Can't get MAJOR %d for Matsushita CDROM\n", MAJOR_NR);
+#if PRINTK_BUG
       sti(); /* to avoid possible "printk" bug */
+#endif
       return (mem_start);
     }
   blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
@@ -3410,7 +3496,6 @@ u_long sbpcd_init(u_long mem_start, u_long mem_end)
   blksize_size[MAJOR_NR]=sbpcd_blocksizes;
 
   DPRINTF((DBG_INF,"SBPCD: init done.\n"));
-  sti(); /* to avoid possible "printk" bug */
   return (mem_start);
 }
 /*==========================================================================*/
@@ -3419,7 +3504,7 @@ u_long sbpcd_init(u_long mem_start, u_long mem_end)
  * used externally (isofs/inode.c, fs/buffer.c)
  * Currently disabled (has to get "synchronized").
  */
-int check_sbpcd_media_change(int full_dev, int unused_minor)
+int SBPCD_MEDIA_CHANGE(int full_dev, int unused_minor)
 {
   int st;
 
index 061a4ba7aa2936d05b860d009aaad001382a24de..1a8d34098678f20f2489e78aea1e262eef7924f7 100644 (file)
@@ -967,9 +967,12 @@ static int normal_select(struct tty_struct * tty, struct inode * inode,
                                return 1;
                        if (tty_hung_up_p(file))
                                return 1;
-                       if (!tty->read_wait)
-                               tty->minimum_to_wake = MIN_CHAR(tty) ?
-                                       MIN_CHAR(tty) : 1;
+                       if (!tty->read_wait) {
+                               if (MIN_CHAR(tty) && !TIME_CHAR(tty))
+                                       tty->minimum_to_wake = MIN_CHAR(tty);
+                               else
+                                       tty->minimum_to_wake = 1;
+                       }
                        select_wait(&tty->read_wait, wait);
                        return 0;
                case SEL_OUT:
diff --git a/drivers/net/d_link.c b/drivers/net/d_link.c
deleted file mode 100644 (file)
index 6154b3e..0000000
+++ /dev/null
@@ -1,734 +0,0 @@
-static char *version =
-       "d_link.c: $Revision: 0.32 $,  Bjorn Ekwall (bj0rn@blox.se)\n";
-/*
- *     d_link.c
- *
- *     Linux driver for the D-Link DE-600 Ethernet pocket adapter.
- *
- *     Portions (C) Copyright 1993 by Bjorn Ekwall
- *     The Author may be reached as bj0rn@blox.se
- *
- *     Based on adapter information gathered from DE600.ASM by D-Link Inc.,
- *     as included on disk C in the v.2.11 of PC/TCP from FTP Software.
- *     For DE600.asm:
- *             Portions (C) Copyright 1990 D-Link, Inc.
- *             Copyright, 1988-1992, Russell Nelson, Crynwr Software
- *
- *     Adapted to the sample network driver core for linux,
- *     written by: Donald Becker <becker@super.org>
- *     C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
- *
- *     compile-command:
- *     "gcc -D__KERNEL__  -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer \
- *      -m486 -DD_LINK_IO=0x378 -DD_LINK_IRQ=7 -UD_LINK_DEBUG -S d_link.c
- *
- **************************************************************/
-/*
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2, or (at your option)
- *     any later version.
- *
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
- *
- **************************************************************/
-/* Add another "; SLOW_DOWN_IO" here if your adapter won't work OK: */
-#define D_LINK_SLOW_DOWN SLOW_DOWN_IO; SLOW_DOWN_IO; SLOW_DOWN_IO
-
- /*
- * If you still have trouble reading/writing to the adapter,
- * modify the following "#define": (see <asm/io.h> for more info)
-#define REALLY_SLOW_IO
- */
-#define SLOW_IO_BY_JUMPING /* Looks "better" than dummy write to port 0x80 :-) */
-
-/*
- * For fix to TCP "slowdown", take a look at the "#define D_LINK_MAX_WINDOW"
- * near the end of the file...
- */
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifdef D_LINK_DEBUG
-#define PRINTK(x) if (d_link_debug >= 2) printk x
-#else
-#define D_LINK_DEBUG 0
-#define PRINTK(x) /**/
-#endif
-static unsigned int d_link_debug = D_LINK_DEBUG;
-\f
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-#include <netinet/in.h>
-#include <linux/ptrace.h>
-#include <asm/system.h>
-#include <errno.h>
-
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#define netstats enet_statistics
-
-/**************************************************
- *                                                *
- * Definition of D-Link Ethernet Pocket adapter   *
- *                                                *
- **************************************************/
-/*
- * D-Link Ethernet pocket adapter ports
- */
-/*
- * OK, so I'm cheating, but there are an awful lot of
- * reads and writes in order to get anything in and out
- * of the DE-600 with 4 bits at a time in the parallel port,
- * so every saved instruction really helps :-)
- *
- * That is, I don't care what the device struct says
- * but hope that Space.c will keep the rest of the drivers happy.
- */
-#ifndef D_LINK_IO
-#define D_LINK_IO 0x378
-#endif
-
-#define DATA_PORT      (D_LINK_IO)
-#define STATUS_PORT    (D_LINK_IO + 1)
-#define COMMAND_PORT   (D_LINK_IO + 2)
-
-#ifndef D_LINK_IRQ
-#define D_LINK_IRQ     7
-#endif
-/*
- * It really should look like this, and autoprobing as well...
- *
-#define DATA_PORT      (dev->base_addr + 0)
-#define STATUS_PORT    (dev->base_addr + 1)
-#define COMMAND_PORT   (dev->base_addr + 2)
-#define D_LINK_IRQ     dev->irq
- */
-
-/*
- * D-Link COMMAND_PORT commands
- */
-#define SELECT_NIC     0x04 /* select Network Interface Card */
-#define SELECT_PRN     0x1c /* select Printer */
-#define NML_PRN                0xec /* normal Printer situation */
-#define IRQEN          0x10 /* enable IRQ line */
-
-/*
- * D-Link STATUS_PORT
- */
-#define RX_BUSY                0x80
-#define RX_GOOD                0x40
-#define TX_FAILED16    0x10
-#define TX_BUSY                0x08
-
-/*
- * D-Link DATA_PORT commands
- * command in low 4 bits
- * data in high 4 bits
- * select current data nibble with HI_NIBBLE bit
- */
-#define WRITE_DATA     0x00 /* write memory */
-#define READ_DATA      0x01 /* read memory */
-#define STATUS         0x02 /* read  status register */
-#define COMMAND                0x03 /* write command register (see COMMAND below) */
-#define NULL_COMMAND   0x04 /* null command */
-#define RX_LEN         0x05 /* read  received packet length */
-#define TX_ADDR                0x06 /* set adapter transmit memory address */
-#define RW_ADDR                0x07 /* set adapter read/write memory address */
-#define HI_NIBBLE      0x08 /* read/write the high nibble of data,
-                               or-ed with rest of command */
-
-/*
- * command register, accessed through DATA_PORT with low bits = COMMAND
- */
-#define RX_ALL         0x01 /* PROMISCIOUS */
-#define RX_BP          0x02 /* default: BROADCAST & PHYSICAL ADRESS */
-#define RX_MBP         0x03 /* MULTICAST, BROADCAST & PHYSICAL ADRESS */
-
-#define TX_ENABLE      0x04 /* bit 2 */
-#define RX_ENABLE      0x08 /* bit 3 */
-
-#define RESET          0x80 /* set bit 7 high */
-#define STOP_RESET     0x00 /* set bit 7 low */
-
-/*
- * data to command register
- * (high 4 bits in write to DATA_PORT)
- */
-#define RX_PAGE2_SELECT        0x10 /* bit 4, only 2 pages to select */
-#define RX_BASE_PAGE   0x20 /* bit 5, always set when specifying RX_ADDR */
-#define FLIP_IRQ       0x40 /* bit 6 */
-
-/*
- * D-Link adapter internal memory:
- *
- * 0-2K 1:st transmit page (send from pointer up to 2K)
- * 2-4K        2:nd transmit page (send from pointer up to 4K)
- *
- * 4-6K 1:st receive page (data from 4K upwards)
- * 6-8K 2:nd receive page (data from 6K upwards)
- *
- * 8K+ Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
- */
-#define MEM_2K         0x0800 /* 2048 */
-#define MEM_4K         0x1000 /* 4096 */
-#define MEM_6K         0x1800 /* 6144 */
-#define NODE_ADDRESS   0x2000 /* 8192 */
-
-#define RUNT 60                /* Too small Ethernet packet */
-
-/**************************************************
- *                                                *
- *             End of definition                  *
- *                                                *
- **************************************************/
-
-/*
- * Index to functions, as function prototypes.
- */
-#if 0
-/* For tricking tcp.c to announce a small max window (max 2 fast packets please :-) */
-static unsigned long   d_link_rspace(struct sock *sk);
-#endif
-
-/* Routines used internally. (See "convenience macros") */
-static int             d_link_read_status(struct device *dev);
-static unsigned        char    d_link_read_byte(unsigned char type, struct device *dev);
-
-/* Put in the device structure. */
-static int     d_link_open(struct device *dev);
-static int     d_link_close(struct device *dev);
-static struct netstats *get_stats(struct device *dev);
-static int     d_link_start_xmit(struct sk_buff *skb, struct device *dev);
-
-/* Dispatch from interrupts. */
-static void    d_link_interrupt(int reg_ptr);
-static int     d_link_tx_intr(struct device *dev, int irq_status);
-static void    d_link_rx_intr(struct device *dev);
-
-/* Initialization */
-static void    trigger_interrupt(struct device *dev);
-int            d_link_init(struct device *dev);
-static void    adapter_init(struct device *dev);
-
-/*
- * D-Link driver variables:
- */
-extern struct device           *irq2dev_map[16];
-static volatile int            rx_page         = 0;
-
-#define TX_PAGES 2
-static volatile int            tx_fifo[TX_PAGES];
-static volatile int            tx_fifo_in = 0;
-static volatile int            tx_fifo_out = 0;
-static volatile int            free_tx_pages = TX_PAGES;
-
-/*
- * Convenience macros/functions for D-Link adapter
- */
-
-#define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); D_LINK_SLOW_DOWN
-#define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); D_LINK_SLOW_DOWN
-
-/* Thanks for hints from Mark Burton <markb@ordern.demon.co.uk> */
-#define d_link_put_byte(data) ( \
-       outb_p(((data) << 4)   | WRITE_DATA            , DATA_PORT), \
-       outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT))
-
-/*
- * The first two outb_p()'s below could perhaps be deleted if there
- * would be more delay in the last two. Not certain about it yet...
- */
-#define d_link_put_command(cmd) ( \
-       outb_p(( rx_page        << 4)   | COMMAND            , DATA_PORT), \
-       outb_p(( rx_page        & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \
-       outb_p(((rx_page | cmd) << 4)   | COMMAND            , DATA_PORT), \
-       outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT))
-
-#define d_link_setup_address(addr,type) ( \
-       outb_p((((addr) << 4) & 0xf0) | type            , DATA_PORT), \
-       outb_p(( (addr)       & 0xf0) | type | HI_NIBBLE, DATA_PORT), \
-       outb_p((((addr) >> 4) & 0xf0) | type            , DATA_PORT), \
-       outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT))
-
-#define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K))
-
-/* Flip bit, only 2 pages */
-#define next_rx_page() (rx_page ^= RX_PAGE2_SELECT)
-
-#define tx_page_adr(a) (((a) + 1) * MEM_2K)
-
-static inline int
-d_link_read_status(struct device *dev)
-{
-       int     status;
-
-       outb_p(STATUS, DATA_PORT);
-       status = inb(STATUS_PORT);
-       outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
-
-       return status;
-}
-
-static inline unsigned char
-d_link_read_byte(unsigned char type, struct device *dev) { /* dev used by macros */
-       unsigned char   lo;
-
-       (void)outb_p((type), DATA_PORT);
-       lo = ((unsigned char)inb(STATUS_PORT)) >> 4;
-       (void)outb_p((type) | HI_NIBBLE, DATA_PORT);
-       return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo;
-}
-\f
-/*
- * Open/initialize the board.  This is called (in the current kernel)
- * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is a non-reboot way to recover if something goes wrong.
- */
-static int
-d_link_open(struct device *dev)
-{
-       extern struct proto tcp_prot;
-
-       if (request_irq(D_LINK_IRQ, d_link_interrupt)) {
-               printk ("%s: unable to get IRQ %d\n", dev->name, D_LINK_IRQ);
-               return 1;
-       }
-       irq2dev_map[D_LINK_IRQ] = dev;
-
-       adapter_init(dev);
-
-       /*
-        * Yes, I know!
-        * This is really not nice, but since a machine that uses DE-600
-        * rarely uses any other TCP/IP connection device simultaneously,
-        * this hack shouldn't really slow anything up.
-        * (I don't know about slip though... but it won't break it)
-        *
-        * This fix is better than changing in tcp.h IMHO
-        */
-#if 0   
-       tcp_prot.rspace = d_link_rspace; /* was: sock_rspace */
-#endif
-
-
-       return 0;
-}
-
-/*
- * The inverse routine to d_link_open().
- */
-static int
-d_link_close(struct device *dev)
-{
-       select_nic();
-       rx_page = 0;
-       d_link_put_command(RESET);
-       d_link_put_command(STOP_RESET);
-       d_link_put_command(0);
-       select_prn();
-
-       free_irq(D_LINK_IRQ);
-       irq2dev_map[D_LINK_IRQ] = NULL;
-       dev->start = 0;
-#if 0
-       tcp_prot.rspace = sock_rspace; /* see comment above! */
-#endif
-       return 0;
-}
-
-static struct netstats *
-get_stats(struct device *dev)
-{
-    return (struct netstats *)(dev->priv);
-}
-
-static inline void
-trigger_interrupt(struct device *dev)
-{
-       d_link_put_command(FLIP_IRQ);
-       select_prn();
-       D_LINK_SLOW_DOWN;
-       select_nic();
-       d_link_put_command(0);
-}
-
-/*
- * Copy a buffer to the adapter transmit page memory.
- * Start sending.
- */
-static int
-d_link_start_xmit(struct sk_buff *skb, struct device *dev)
-{
-       int             transmit_from;
-       int             len;
-       int             tickssofar;
-       unsigned char   *buffer = skb->data;
-
-       /*
-        * If some higher layer thinks we've missed a
-        * tx-done interrupt we are passed NULL.
-        * Caution: dev_tint() handles the cli()/sti() itself.
-        */
-
-       if (skb == NULL) {
-               dev_tint(dev);
-               return 0;
-       }
-
-       if (free_tx_pages <= 0) {       /* Do timeouts, to avoid hangs. */
-               tickssofar = jiffies - dev->trans_start;
-
-               if (tickssofar < 5)
-                       return 1;
-
-               /* else */
-               printk("%s: transmit timed out (%d), %s?\n",
-                       dev->name,
-                       tickssofar,
-                       "network cable problem"
-                       );
-               /* Restart the adapter. */
-               adapter_init(dev);
-       }
-
-       /* Start real output */
-       PRINTK(("d_link_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
-
-       if ((len = skb->len) < RUNT)
-               len = RUNT;
-
-       cli();
-       select_nic();
-
-       tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
-       tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */
-
-       d_link_setup_address(transmit_from, RW_ADDR);
-       for ( ; len > 0; --len, ++buffer)
-               d_link_put_byte(*buffer);
-
-       if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
-               dev->trans_start = jiffies;
-               dev->tbusy = 0; /* allow more packets into adapter */
-               /* Send page and generate an interrupt */
-               d_link_setup_address(transmit_from, TX_ADDR);
-               d_link_put_command(TX_ENABLE);
-       }
-       else {
-               dev->tbusy = !free_tx_pages;
-               select_prn();
-       }
-       
-       sti(); /* interrupts back on */
-       
-       if (skb->free)
-               kfree_skb (skb, FREE_WRITE);
-
-       return 0;
-}
-\f
-/*
- * The typical workload of the driver:
- * Handle the network interface interrupts.
- */
-static void
-d_link_interrupt(int reg_ptr)
-{
-       int             irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
-       struct device   *dev = irq2dev_map[irq];
-       unsigned char   irq_status;
-       int             retrig = 0;
-       int             boguscount = 0;
-
-       /* This might just as well be deleted now, no crummy drivers present :-) */
-       if ((dev == NULL) || (dev->start == 0) || (D_LINK_IRQ != irq)) {
-               printk("%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq);
-               return;
-       }
-
-       dev->interrupt = 1;
-       select_nic();
-       irq_status = d_link_read_status(dev);
-
-       do {
-               PRINTK(("d_link_interrupt (%2.2X)\n", irq_status));
-
-               if (irq_status & RX_GOOD)
-                       d_link_rx_intr(dev);
-               else if (!(irq_status & RX_BUSY))
-                       d_link_put_command(RX_ENABLE);
-
-               /* Any transmission in progress? */
-               if (free_tx_pages < TX_PAGES)
-                       retrig = d_link_tx_intr(dev, irq_status);
-               else
-                       retrig = 0;
-
-               irq_status = d_link_read_status(dev);
-       } while ( (irq_status & RX_GOOD) || ((++boguscount < 10) && retrig) );
-       /*
-        * Yeah, it _looks_ like busy waiting, smells like busy waiting
-        * and I know it's not PC, but please, it will only occur once
-        * in a while and then only for a loop or so (< 1ms for sure!)
-        */
-
-       /* Enable adapter interrupts */
-       dev->interrupt = 0;
-       select_prn();
-
-       if (retrig)
-               trigger_interrupt(dev);
-
-       sti();
-       return;
-}
-
-static int
-d_link_tx_intr(struct device *dev, int irq_status)
-{
-       /*
-        * Returns 1 if tx still not done
-        */
-
-       mark_bh(INET_BH);
-       /* Check if current transmission is done yet */
-       if (irq_status & TX_BUSY)
-               return 1; /* tx not done, try again */
-
-       /* else */
-       /* If last transmission OK then bump fifo index */
-       if (!(irq_status & TX_FAILED16)) {
-               tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES;
-               ++free_tx_pages;
-               ((struct netstats *)(dev->priv))->tx_packets++;
-               dev->tbusy = 0;
-       }
-
-       /* More to send, or resend last packet? */
-       if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) {
-               dev->trans_start = jiffies;
-               d_link_setup_address(tx_fifo[tx_fifo_out], TX_ADDR);
-               d_link_put_command(TX_ENABLE);
-               return 1;
-       }
-       /* else */
-
-       return 0;
-}
-
-/*
- * We have a good packet, get it out of the adapter.
- */
-static void
-d_link_rx_intr(struct device *dev)
-{
-       struct sk_buff  *skb;
-       int             i;
-       int             read_from;
-       int             size;
-       register unsigned char  *buffer;
-
-       cli();
-       /* Get size of received packet */
-       size = d_link_read_byte(RX_LEN, dev);   /* low byte */
-       size += (d_link_read_byte(RX_LEN, dev) << 8);   /* high byte */
-       size -= 4;      /* Ignore trailing 4 CRC-bytes */
-
-       /* Tell adapter where to store next incoming packet, enable receiver */
-       read_from = rx_page_adr();
-       next_rx_page();
-       d_link_put_command(RX_ENABLE);
-       sti();
-
-       if ((size < 32)  ||  (size > 1535))
-               printk("%s: Bogus packet size %d.\n", dev->name, size);
-
-       skb = alloc_skb(size, GFP_ATOMIC);
-       sti();
-       if (skb == NULL) {
-               printk("%s: Couldn't allocate a sk_buff of size %d.\n",
-                       dev->name, size);
-               return;
-       }
-       /* else */
-
-       skb->lock = 0;
-       /* 'skb->data' points to the start of sk_buff data area. */
-       buffer = skb->data;
-
-       /* copy the packet into the buffer */
-       d_link_setup_address(read_from, RW_ADDR);
-       for (i = size; i > 0; --i, ++buffer)
-               *buffer = d_link_read_byte(READ_DATA, dev);
-       
-       ((struct netstats *)(dev->priv))->rx_packets++; /* count all receives */
-
-       if (dev_rint((unsigned char *)skb, size, IN_SKBUFF, dev))
-               printk("%s: receive buffers full.\n", dev->name);
-       /*
-        * If any worth-while packets have been received, dev_rint()
-        * has done a mark_bh(INET_BH) for us and will work on them
-        * when we get to the bottom-half routine.
-        */
-}
-
-int
-d_link_init(struct device *dev)
-{
-       int     i;
-
-       printk("%s: D-Link DE-600 pocket adapter", dev->name);
-       /* Alpha testers must have the version number to report bugs. */
-       if (d_link_debug > 1)
-               printk(version);
-
-       /* probe for adapter */
-       rx_page = 0;
-       select_nic();
-       (void)d_link_read_status(dev);
-       d_link_put_command(RESET);
-       d_link_put_command(STOP_RESET);
-       if (d_link_read_status(dev) & 0xf0) {
-               printk(": not at I/O %#3x.\n", DATA_PORT);
-               return ENODEV;
-       }
-
-       /*
-        * Maybe we found one,
-        * have to check if it is a D-Link DE-600 adapter...
-        */
-
-       /* Get the adapter ethernet address from the ROM */
-       d_link_setup_address(NODE_ADDRESS, RW_ADDR);
-       for (i = 0; i < ETH_ALEN; i++) {
-               dev->dev_addr[i] = d_link_read_byte(READ_DATA, dev);
-               dev->broadcast[i] = 0xff;
-       }
-
-       /* Check magic code */
-       if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) {
-               /* OK, install real address */
-               dev->dev_addr[0] = 0x00;
-               dev->dev_addr[1] = 0x80;
-               dev->dev_addr[2] = 0xc8;
-               dev->dev_addr[3] &= 0x0f;
-               dev->dev_addr[3] |= 0x70;
-       } else {
-               printk(" not identified in the printer port\n");
-               return ENODEV;
-       }
-
-       printk(", Ethernet Address: %2.2X", dev->dev_addr[0]);
-       for (i = 1; i < ETH_ALEN; i++)
-               printk(":%2.2X",dev->dev_addr[i]);
-       printk("\n");
-
-       /* Initialize the device structure. */
-       dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);
-       memset(dev->priv, 0, sizeof(struct netstats));
-       dev->get_stats = get_stats;
-
-       dev->open = d_link_open;
-       dev->stop = d_link_close;
-       dev->hard_start_xmit = &d_link_start_xmit;
-
-       ether_setup(dev);
-       
-       select_prn();
-       return 0;
-}
-
-static void
-adapter_init(struct device *dev)
-{
-       int     i;
-
-       cli();
-       dev->tbusy = 0;         /* Transmit busy...  */
-       dev->interrupt = 0;
-       dev->start = 1;
-
-       select_nic();
-       rx_page = 0; /* used by RESET */
-       d_link_put_command(RESET);
-       d_link_put_command(STOP_RESET);
-
-       tx_fifo_in = 0;
-       tx_fifo_out = 0;
-       free_tx_pages = TX_PAGES;
-
-       /* set the ether address. */
-       d_link_setup_address(NODE_ADDRESS, RW_ADDR);
-       for (i = 0; i < ETH_ALEN; i++)
-               d_link_put_byte(dev->dev_addr[i]);
-
-       /* where to start saving incoming packets */
-       rx_page = RX_BP | RX_BASE_PAGE;
-       d_link_setup_address(MEM_4K, RW_ADDR);
-       /* Enable receiver */
-       d_link_put_command(RX_ENABLE);
-       select_prn();
-       sti();
-}
-
-#if 0
-/*
- *     The new router code (coming soon 8-) ) will fix this properly.
- */
-#define D_LINK_MIN_WINDOW 1024
-#define D_LINK_MAX_WINDOW 2048
-#define D_LINK_TCP_WINDOW_DIFF 1024
-/*
- * Copied from sock.c
- *
- * Sets a lower max receive window in order to achieve <= 2
- * packets arriving at the adapter in fast succession.
- * (No way that a DE-600 can cope with an ethernet saturated with its packets :-)
- *
- * Since there are only 2 receive buffers in the DE-600
- * and it takes some time to copy from the adapter,
- * this is absolutely necessary for any TCP performance whatsoever!
- *
- */
-#define min(a,b)       ((a)<(b)?(a):(b))
-static unsigned long
-d_link_rspace(struct sock *sk)
-{
-  int amt;
-
-  if (sk != NULL) {
-/*
- * Hack! You might want to play with commenting away the following line,
- * if you know what you do!
- */
-       sk->max_unacked = D_LINK_MAX_WINDOW - D_LINK_TCP_WINDOW_DIFF;
-
-       if (sk->rmem_alloc >= SK_RMEM_MAX-2*D_LINK_MIN_WINDOW) return(0);
-       amt = min((SK_RMEM_MAX-sk->rmem_alloc)/2-D_LINK_MIN_WINDOW, D_LINK_MAX_WINDOW);
-       if (amt < 0) return(0);
-       return(amt);
-  }
-  return(0);
-}
-
-
-#endif
diff --git a/fs/binfmt_coff.c b/fs/binfmt_coff.c
deleted file mode 100644 (file)
index 425a759..0000000
+++ /dev/null
@@ -1,784 +0,0 @@
-/*
- * These are the functions used to load COFF IBSC style executables.
- * Information on COFF format may be obtained in either the Intel Binary
- * Compatibility Specification 2 or O'Rilley's book on COFF. The shared
- * libraries are defined only the in the Intel book.
- *
- * This file is based upon code written by Eric Youndale for the ELF object
- * file format.
- *
- * Author: Al Longyear (longyear@sii.com)
- *
- * Latest Revision:
- *    3 Feburary 1994
- *      Al Longyear (longyear@sii.com)
- *      Cleared first page of bss section using put_fs_byte.
- */
-
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/a.out.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/binfmts.h>
-#include <asm/segment.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/coff.h>
-#include <linux/malloc.h>
-
-asmlinkage int sys_exit (int exit_code);
-asmlinkage int sys_close (unsigned fd);
-asmlinkage int sys_open (const char *, int, int);
-asmlinkage int sys_uselib(const char * library);
-
-static int preload_library (struct linux_binprm *exe_bprm,
-                           COFF_SCNHDR * sect,
-                           struct file *fp);
-
-static int load_object (struct linux_binprm *bprm,
-                       struct pt_regs *regs,
-                       int lib_ok);
-
-/*
- *  Small procedure to test for the proper file alignment.
- */
-
-static inline int
-is_properly_aligned (COFF_SCNHDR *sect)
-{
-    long scnptr = COFF_LONG (sect->s_scnptr);
-    long vaddr  = COFF_LONG (sect->s_vaddr);
-/*
- *  Print the section information if needed
- */
-
-#ifdef COFF_DEBUG
-    printk ("%s, scnptr = %d, vaddr = %d\n",
-           sect->s_name,
-           scnptr, vaddr);
-#endif
-
-/*
- *  Return the error code if the section is not properly aligned.
- */
-
-#ifdef COFF_DEBUG
-    if (((vaddr - scnptr) & ~PAGE_MASK) != 0)
-       printk ("bad alignment in %s\n", sect->s_name);
-#endif
-    return ((((vaddr - scnptr) & ~PAGE_MASK) != 0) ? -ENOEXEC : 0);
-}
-
-/*
- *    Clear the bytes in the last page of data.
- */
-
-static
-int clear_memory (unsigned long addr, unsigned long size)
-{
-    int status;
-
-    size = (PAGE_SIZE - (addr & ~PAGE_MASK)) & ~PAGE_MASK;
-    if (size == 0)
-        status = 0;
-    else {
-      
-#ifdef COFF_DEBUG
-        printk ("un-initialized storage in last page %d\n", size);
-#endif
-
-       status = verify_area (VERIFY_WRITE,
-                             (void *) addr, size);
-#ifdef COFF_DEBUG
-       printk ("result from verify_area = %d\n", status);
-#endif
-
-       if (status >= 0)
-           while (size-- != 0)
-               put_fs_byte (0, addr++);
-    }
-    return status;
-}
-
-/*
- *  Helper function to process the load operation.
- */
-
-static int
-load_object (struct linux_binprm * bprm, struct pt_regs *regs, int lib_ok)
-{
-    COFF_FILHDR  *coff_hdr = (COFF_FILHDR *) bprm->buf;        /* COFF Header */
-    COFF_SCNHDR  *sect_bufr;   /* Pointer to section table            */
-    COFF_SCNHDR  *text_sect;   /* Pointer to the text section         */
-    COFF_SCNHDR  *data_sect;   /* Pointer to the data section         */
-    COFF_SCNHDR  *bss_sect;    /* Pointer to the bss section          */
-    int text_count;            /* Number of text sections             */
-    int data_count;            /* Number of data sections             */
-    int bss_count;             /* Number of bss sections              */
-    int lib_count;             /* Number of lib sections              */
-    unsigned int start_addr = 0;/* Starting location for program       */
-    int status = 0;            /* Result status register              */
-    int fd = -1;               /* Open file descriptor                */
-    struct file *fp     = NULL;        /* Pointer to the file at "fd"         */
-    short int sections  = 0;   /* Number of sections in the file      */
-    short int aout_size = 0;   /* Size of the a.out header area       */
-    short int flags;           /* Flag bits from the COFF header      */
-
-#ifdef COFF_DEBUG
-    printk ("binfmt_coff entry: %s\n", bprm->filename);
-#endif
-
-/*
- *  Validate the magic value for the object file.
- */
-    do {
-       if (COFF_I386BADMAG (*coff_hdr)) {
-#ifdef COFF_DEBUG
-           printk ("bad filehdr magic\n");
-#endif
-           status = -ENOEXEC;
-           break;
-       }
-/*
- *  The object file should have 32 BIT little endian format. Do not allow
- *  it to have the 16 bit object file flag set as Linux is not able to run
- *  on the 80286/80186/8086.
- */
-       flags = COFF_SHORT (coff_hdr->f_flags);
-       if ((flags & (COFF_F_AR32WR | COFF_F_AR16WR)) != COFF_F_AR32WR) {
-#ifdef COFF_DEBUG
-           printk ("invalid f_flags bits\n");
-#endif
-           status = -ENOEXEC;
-           break;
-       }
-/*
- *  Extract the header information which we need.
- */
-       sections  = COFF_SHORT (coff_hdr->f_nscns);   /* Number of sections */
-       aout_size = COFF_SHORT (coff_hdr->f_opthdr);  /* Size of opt. headr */
-/*
- *  If the file is not executable then reject the exectution. This means
- *  that there must not be external references.
- */
-       if ((flags & COFF_F_EXEC) == 0) {
-#ifdef COFF_DEBUG
-           printk ("not executable bit\n");
-#endif
-           status = -ENOEXEC;
-           break;
-       }
-/*
- *  There must be atleast one section.
- */
-       if (sections == 0) {
-#ifdef COFF_DEBUG
-           printk ("no sections\n");
-#endif
-           status = -ENOEXEC;
-           break;
-       }
-/*
- *  Do some additional consistency checks.
- *  The system requires mapping for this loader. If you try
- *  to use a file system with no mapping, the format is not valid.
- */
-       if (!bprm->inode->i_op ||
-           !bprm->inode->i_op->default_file_ops->mmap) {
-#ifdef COFF_DEBUG
-           printk ("no mmap in fs\n");
-#endif
-           status = -ENOEXEC;
-       }
-    }
-    while (0);
-/*
- *  Allocate a buffer to hold the entire coff section list.
- */
-    if (status >= 0) {
-       int nbytes = sections * COFF_SCNHSZ;
-
-       sect_bufr = (COFF_SCNHDR *) kmalloc (nbytes, GFP_KERNEL);
-       if (0 == sect_bufr) {
-#ifdef COFF_DEBUG
-           printk ("kmalloc failed\n");
-#endif
-           status = -ENOEXEC;
-       }
-/*
- *  Read the section list from the disk file.
- */
-       else {
-            int old_fs = get_fs ();
-            set_fs (get_ds ());  /* Make it point to the proper location    */
-            status = read_exec (bprm->inode,        /* INODE for file       */
-                           aout_size + COFF_FILHSZ, /* Offset in the file   */
-                           (char *) sect_bufr,      /* Buffer for read      */
-                           nbytes);                 /* Byte count reqd.     */
-            set_fs (old_fs);                        /* Restore the selector */
-#ifdef COFF_DEBUG
-            if (status < 0)
-               printk ("read aout hdr, status = %d\n", status);
-#endif
-        }
-    }
-    else
-       sect_bufr = NULL;       /* Errors do not have a section buffer */
-/*
- *  Count the number of sections for the required types and store the location
- *  of the last section for the three primary types.
- */
-    text_count = 0;
-    data_count = 0;
-    bss_count  = 0;
-    lib_count  = 0;
-
-    text_sect = NULL;
-    data_sect = NULL;
-    bss_sect  = NULL;
-/*
- *  Loop through the sections and find the various types
- */
-    if (status >= 0) {
-       int nIndex;
-       COFF_SCNHDR *sect_ptr = sect_bufr;
-
-       for (nIndex = 0; nIndex < sections; ++nIndex) {
-           long int sect_flags = COFF_LONG (sect_ptr->s_flags);
-
-           switch (sect_flags) {
-           case COFF_STYP_TEXT:
-               text_sect = sect_ptr;
-               ++text_count;
-               status = is_properly_aligned (sect_ptr);
-               break;
-
-           case COFF_STYP_DATA:
-               data_sect = sect_ptr;
-               ++data_count;
-               status = is_properly_aligned (sect_ptr);
-               break;
-
-           case COFF_STYP_BSS:
-               bss_sect = sect_ptr;
-               ++bss_count;
-               break;
-
-           case COFF_STYP_LIB:
-#ifdef COFF_DEBUG
-               printk (".lib section found\n");
-#endif
-               ++lib_count;
-               break;
-
-           default:
-               break;
-           }
-           sect_ptr = (COFF_SCNHDR *) & ((char *) sect_ptr)[COFF_SCNHSZ];
-       }
-/*
- *  Ensure that there are the required sections. There must be one text
- *  sections and one each of the data and bss sections for an executable.
- *  A library may or may not have a data / bss section.
- */
-       if (text_count != 1) {
-           status = -ENOEXEC;
-#ifdef COFF_DEBUG
-           printk ("no text sections\n");
-#endif
-       }
-       else {
-           if (lib_ok) {
-               if (data_count != 1 || bss_count != 1) {
-                   status = -ENOEXEC;
-#ifdef COFF_DEBUG
-                   printk ("no .data nor .bss sections\n");
-#endif
-               }
-           }
-       }
-    }
-/*
- *  If there is no additional header then assume the file starts at
- *  the first byte of the text section. This may not be the proper place,
- *  so the best solution is to include the optional header. A shared library
- *  __MUST__ have an optional header to indicate that it is a shared library.
- */
-    if (status >= 0) {
-       if (aout_size == 0) {
-           if (!lib_ok) {
-               status = -ENOEXEC;
-#ifdef COFF_DEBUG
-               printk ("no header in library\n");
-#endif
-           }
-           start_addr = COFF_LONG (text_sect->s_vaddr);
-       }
-/*
- *  There is some header. Ensure that it is sufficient.
- */
-       else {
-           if (aout_size < COFF_AOUTSZ) {
-               status = -ENOEXEC;
-#ifdef COFF_DEBUG
-               printk ("header too small\n");
-#endif
-           }
-           else {
-               COFF_AOUTHDR *aout_hdr =        /* Pointer to a.out header */
-               (COFF_AOUTHDR *) & ((char *) coff_hdr)[COFF_FILHSZ];
-               short int aout_magic = COFF_SHORT (aout_hdr->magic); /* id */
-/*
- *  Validate the magic number in the a.out header. If it is valid then
- *  update the starting symbol location. Do not accept these file formats
- *  when loading a shared library.
- */
-               switch (aout_magic) {
-               case COFF_OMAGIC:
-               case COFF_ZMAGIC:
-               case COFF_STMAGIC:
-                   if (!lib_ok) {
-                       status = -ENOEXEC;
-#ifdef COFF_DEBUG
-                       printk ("wrong a.out header magic\n");
-#endif
-                   }
-                   start_addr = (unsigned int) COFF_LONG (aout_hdr->entry);
-                   break;
-/*
- *  Magic value for a shared library. This is valid only when loading a
- *  shared library. (There is no need for a start_addr. It won't be used.)
- */
-               case COFF_SHMAGIC:
-                   if (lib_ok) {
-#ifdef COFF_DEBUG
-                       printk ("wrong a.out header magic\n");
-#endif
-                       status = -ENOEXEC;
-                   }
-                   break;
-
-               default:
-#ifdef COFF_DEBUG
-                   printk ("wrong a.out header magic\n");
-#endif
-                   status = -ENOEXEC;
-                   break;
-               }
-           }
-       }
-    }
-/*
- *  Fetch a file pointer to the executable.
- */
-    if (status >= 0) {
-       fd = open_inode (bprm->inode, O_RDONLY);
-       if (fd < 0) {
-#ifdef COFF_DEBUG
-           printk ("can not open inode, result = %d\n", fd);
-#endif
-           status = fd;
-       }
-       else
-           fp = current->files->fd[fd];
-    }
-    else
-       fd = -1;                /* Invalidate the open file descriptor */
-/*
- *  Generate the proper values for the text fields
- *
- *  THIS IS THE POINT OF NO RETURN. THE NEW PROCESS WILL TRAP OUT SHOULD
- *  SOMETHING FAIL IN THE LOAD SEQUENCE FROM THIS POINT ONWARD.
- */
-    if (status >= 0) {
-       long text_scnptr = COFF_LONG (text_sect->s_scnptr);
-       long text_size   = COFF_LONG (text_sect->s_size);
-       long text_vaddr  = COFF_LONG (text_sect->s_vaddr);
-
-       long data_scnptr;
-       long data_size;
-       long data_vaddr;
-
-       long bss_size;
-       long bss_vaddr;
-/*
- *  Generate the proper values for the data fields
- */
-       if (data_sect != NULL) {
-           data_scnptr = COFF_LONG (data_sect->s_scnptr);
-           data_size   = COFF_LONG (data_sect->s_size);
-           data_vaddr  = COFF_LONG (data_sect->s_vaddr);
-       }
-       else {
-           data_scnptr = 0;
-           data_size   = 0;
-           data_vaddr  = 0;
-       }
-/*
- *  Generate the proper values for the bss fields
- */
-       if (bss_sect != NULL) {
-           bss_size  = COFF_LONG (bss_sect->s_size);
-           bss_vaddr = COFF_LONG (bss_sect->s_vaddr);
-       }
-       else {
-           bss_size  = 0;
-           bss_vaddr = 0;
-       }
-/*
- *  Flush the executable from memory. At this point the executable is
- *  committed to being defined or a segmentation violation will occur.
- */
-       if (lib_ok) {
-#ifdef COFF_DEBUG
-           printk ("flushing executable\n");
-#endif
-           flush_old_exec (bprm);
-/*
- *  Define the initial locations for the various items in the new process
- */
-           current->mm->mmap        = NULL;
-           current->mm->rss         = 0;
-/*
- *  Construct the parameter and environment string table entries.
- */
-           bprm->p += change_ldt (0, bprm->page);
-           bprm->p -= MAX_ARG_PAGES*PAGE_SIZE;
-           bprm->p  = (unsigned long) create_tables ((char *) bprm->p,
-                                                     bprm->argc,
-                                                     bprm->envc,
-                                                     1);
-/*
- *  Do the end processing once the stack has been constructed
- */
-           current->mm->start_code  = text_vaddr & PAGE_MASK;
-           current->mm->end_code    = text_vaddr + text_size;
-           current->mm->end_data    = data_vaddr + data_size;
-           current->mm->start_brk   =
-           current->mm->brk         = bss_vaddr + bss_size;
-           current->suid            =
-           current->euid            = bprm->e_uid;
-           current->sgid            =
-           current->egid            = bprm->e_gid;
-           current->executable      = bprm->inode; /* Store inode for file  */
-           ++bprm->inode->i_count;             /* Count the open inode  */
-           regs->eip                = start_addr;  /* Current EIP register  */
-           regs->esp                =
-           current->mm->start_stack = bprm->p;
-       }
-/*
- *   Map the text pages
- */
-
-#ifdef COFF_DEBUG
-       printk (".text: vaddr = %d, size = %d, scnptr = %d\n",
-                text_vaddr,
-                text_size,
-                text_scnptr);
-#endif
-       status = do_mmap (fp,
-                         text_vaddr & PAGE_MASK,
-                         text_size + (text_vaddr & ~PAGE_MASK),
-                         PROT_READ | PROT_EXEC,
-                         MAP_FIXED | MAP_SHARED,
-                         text_scnptr & PAGE_MASK);
-
-       status = (status == (text_vaddr & PAGE_MASK)) ? 0 : -ENOEXEC;
-/*
- *   Map the data pages
- */
-       if (status >= 0 && data_size != 0) {
-#ifdef COFF_DEBUG
-           printk (".data: vaddr = %d, size = %d, scnptr = %d\n",
-                    data_vaddr,
-                    data_size,
-                    data_scnptr);
-#endif
-           status = do_mmap (fp,
-                             data_vaddr & PAGE_MASK,
-                             data_size + (data_vaddr & ~PAGE_MASK),
-                             PROT_READ | PROT_WRITE | PROT_EXEC,
-                             MAP_FIXED | MAP_PRIVATE,
-                             data_scnptr & PAGE_MASK);
-
-           status = (status == (data_vaddr & PAGE_MASK)) ? 0 : -ENOEXEC;
-       }
-/*
- *   Construct the bss data for the process. The bss ranges from the
- *   end of the data (which may not be on a page boundry) to the end
- *   of the bss section. Allocate any necessary pages for the data.
- */
-       if (status >= 0 && bss_size != 0) {
-#ifdef COFF_DEBUG
-           printk (".bss: vaddr = %d, size = %d\n",
-                    bss_vaddr,
-                    bss_size);
-#endif
-           zeromap_page_range (PAGE_ALIGN (bss_vaddr),
-                               PAGE_ALIGN (bss_size),
-                               PAGE_COPY);
-
-           status = clear_memory (bss_vaddr, bss_size);
-       }
-/*
- *  Load any shared library for the executable.
- */
-       if (status >= 0 && lib_ok && lib_count != 0) {
-           int nIndex;
-           COFF_SCNHDR *sect_ptr = sect_bufr;
-/*
- *  Find the library sections. (There should be atleast one. It was counted
- *  earlier.) This will evenutally recurse to our code and load the shared
- *  library with our own procedures.
- */
-           for (nIndex = 0; nIndex < sections; ++nIndex) {
-               long int sect_flags = COFF_LONG (sect_ptr->s_flags);
-               if (sect_flags == COFF_STYP_LIB) {
-                   status = preload_library (bprm, sect_ptr, fp);
-                   if (status != 0)
-                       break;
-               }
-           sect_ptr = (COFF_SCNHDR *) &((char *) sect_ptr) [COFF_SCNHSZ];
-           }
-       }
-/*
- *   Generate any needed trap for this process. If an error occured then
- *   generate a segmentation violation. If the process is being debugged
- *   then generate the load trap. (Note: If this is a library load then
- *   do not generate the trap here. Pass the error to the caller who
- *   will do it for the process in the outer lay of this procedure call.)
- */
-       if (lib_ok) {
-           if (status < 0)
-               send_sig (SIGSEGV, current, 0); /* Generate the error trap  */
-           else {
-               if (current->flags & PF_PTRACED)
-                   send_sig (SIGTRAP, current, 0);
-           }
-           status = 0;         /* We are committed. It can't fail */
-       }
-    }
-/*
- *  Do any cleanup processing
- */
-    if (fd >= 0)
-       sys_close (fd);         /* Close unused code file      */
-
-    if (sect_bufr != NULL)
-       kfree (sect_bufr);      /* Release section list buffer */
-/*
- *  Return the completion status.
- */
-#ifdef COFF_DEBUG
-    printk ("binfmt_coff: result = %d\n", status);
-#endif
-    return (status);
-}
-
-/*
- *  This procedure will load the library listed in the file name given
- *  as the paramter. The result will be non-zero should something fail
- *  to load.
- */
-
-static int
-preload_this_library (struct linux_binprm *exe_bprm, char *lib_name)
-{
-    int   status;
-    int   old_fs = get_fs();
-/*
- *  If debugging then print "we have arrived"
- */
-#ifdef COFF_DEBUG
-    printk ("%s loading shared library %s\n",
-           exe_bprm->filename,
-           lib_name);
-#endif
-/*
- *  Change the FS register to the proper kernel address space and attempt
- *  to load the library. The library name is allocated from the kernel
- *  pool.
- */
-    set_fs (get_ds ());
-    status = sys_uselib (lib_name);
-    set_fs (old_fs);
-/*
- *  Return the success/failure to the caller.
- */
-    return (status);
-}
-
-/*
- *  This procedure is called to load a library section. The various
- *  libraries are loaded from the list given in the section data.
- */
-
-static int
-preload_library (struct linux_binprm *exe_bprm,
-                COFF_SCNHDR * sect, struct file *fp)
-{
-    int status = 0;            /* Completion status                  */
-    long nbytes;               /* Count of bytes in the header area  */
-/*
- *  Fetch the size of the section. There must be enough room for atleast
- *  one entry.
- */
-    nbytes = COFF_LONG (sect->s_size);
-    if (nbytes < COFF_SLIBSZ) {
-       status = -ENOEXEC;
-#ifdef COFF_DEBUG
-       printk ("library section too small\n");
-#endif
-    }
-/*
- *  Allocate a buffer to hold the section data
- */
-    else {
-       COFF_SLIBHD *phdr;
-       char *buffer = (char *) kmalloc (nbytes, GFP_KERNEL);
-
-        if (0 == buffer) {
-           status = -ENOEXEC;
-#ifdef COFF_DEBUG
-           printk ("kmalloc failed\n");
-#endif
-       }
-       else {
-           int old_fs   = get_fs ();
-/*
- *  Read the section data from the disk file.
- */
-           set_fs (get_ds ());   /* Make it point to the proper location    */
-           status = read_exec (exe_bprm->inode,     /* INODE for file       */
-                           COFF_LONG (sect->s_scnptr), /* Disk location     */
-                           buffer,                     /* Buffer for read   */
-                           nbytes);                    /* Byte count reqd.  */
-           set_fs (old_fs);                         /* Restore the selector */
-/*
- *  Check the result. The value returned is the byte count actaully read.
- */
-           if (status >= 0 && status != nbytes) {
-#ifdef COFF_DEBUG
-               printk ("read of lib section was short\n");
-#endif
-               status = -ENOEXEC;
-           }
-       }
-/*
- *  At this point, go through the list of libraries in the data area.
- */
-       phdr = (COFF_SLIBHD *) buffer;
-       while (status >= 0 && nbytes > COFF_SLIBSZ) {
-           int entry_size  = COFF_LONG (phdr->sl_entsz)   * sizeof (long);
-           int header_size = COFF_LONG (phdr->sl_pathndx) * sizeof (long);
-/*
- *  Validate the sizes of the various items. I don't trust the linker!!
- */
-           if ((unsigned) header_size >= (unsigned) nbytes ||
-               entry_size <= 0 ||
-               (unsigned) entry_size <= (unsigned) header_size) {
-               status = -ENOEXEC;
-#ifdef COFF_DEBUG
-               printk ("header count is invalid\n");
-#endif
-           }
-/*
- *  Load the library. Stop the load process on the first error.
- */
-           else {
-               status = preload_this_library (exe_bprm,
-                                              &((char *) phdr)[header_size]);
-#ifdef COFF_DEBUG
-               printk ("preload_this_library result = %d\n", status);
-#endif
-           }
-/*
- *  Point to the next library in the section data.
- */
-           nbytes -= entry_size;
-           phdr = (COFF_SLIBHD *) &((char *) phdr)[entry_size];
-       }
-/*
- *  Release the space for the library list.
- */
-       if (buffer != NULL)
-           kfree (buffer);
-    }
-/*
- *  Return the resulting status to the caller.
- */
-    return (status);
-}
-
-/*
- *  This procedure is called by the main load sequence. It will load
- *  the executable and prepare it for execution. It provides the additional
- *  parameters used by the recursive coff loader and tells the loader that
- *  this is the main executable. How simple it is . . . .
- */
-
-int
-load_coff_binary (struct linux_binprm *bprm, struct pt_regs *regs)
-{
-    return (load_object (bprm, regs, 1));
-}
-
-/*
- *   Load the image for any shared library.
- *
- *   This is called when we need to load a library based upon a file name.
- */
-
-int
-load_coff_library (int fd)
-{
-    struct linux_binprm *bprm;  /* Parameters for the load operation   */
-    int    status;              /* Status of the request               */
-/*
- *  Read the first portion of the file.
- */
-    bprm = (struct linux_binprm *) kmalloc (sizeof (struct linux_binprm),
-                                           GFP_KERNEL);
-    if (0 == bprm) {
-#ifdef COFF_DEBUG
-       printk ("kmalloc failed\n");
-#endif
-        status = -ENOEXEC;
-    }
-    else {
-        struct file         *file;  /* Pointer to the file table           */
-        struct pt_regs       regs;  /* Register work area                  */
-        int old_fs = get_fs ();     /* Previous FS register value          */
-
-        memset (bprm, '\0', sizeof (struct linux_binprm));
-
-       file           = current->files->fd[fd];
-       bprm->inode    = file->f_inode;   /* The only item _really_ needed */
-       bprm->filename = "";              /* Make it a legal string        */
-/*
- *  Read the section list from the disk file.
- */
-       set_fs (get_ds ());   /* Make it point to the proper location    */
-       status = read_exec (bprm->inode,         /* INODE for file       */
-                           0L,                  /* Offset in the file   */
-                           bprm->buf,           /* Buffer for read      */
-                           sizeof (bprm->buf)); /* Size of the buffer   */
-       set_fs (old_fs);                         /* Restore the selector */
-/*
- *  Try to load the library.
- */
-       status = load_object (bprm, &regs, 0);
-/*
- *  Release the work buffer and return the result.
- */
-       kfree (bprm);                 /* Release the buffer area */
-    }
-/*
- *  Return the result of the load operation
- */
-    return (status);
-}
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
deleted file mode 100644 (file)
index a4fe3bc..0000000
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * linux/fs/binfmt_elf.c
- */
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/a.out.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/binfmts.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/malloc.h>
-#include <linux/shm.h>
-
-#include <asm/segment.h>
-
-asmlinkage int sys_exit(int exit_code);
-asmlinkage int sys_close(unsigned fd);
-asmlinkage int sys_open(const char *, int, int);
-asmlinkage int sys_brk(unsigned long);
-
-#define DLINFO_ITEMS 8
-
-#include <linux/elf.h>
-
-/* We need to explicitly zero any fractional pages
-   after the data section (i.e. bss).  This would
-   contain the junk from the file that should not
-   be in memory */
-
-static void padzero(int elf_bss){
-  unsigned int fpnt, nbyte;
-  
-  if(elf_bss & 0xfff) {
-    
-    nbyte = (PAGE_SIZE - (elf_bss & 0xfff)) & 0xfff;
-    if(nbyte){
-      verify_area(VERIFY_WRITE, (void *) elf_bss, nbyte);
-      
-      fpnt = elf_bss;
-      while(fpnt & 0xfff) put_fs_byte(0, fpnt++);
-    };
-  };
-}
-
-unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exec, unsigned int load_addr, int ibcs)
-{
-       unsigned long *argv,*envp, *dlinfo;
-       unsigned long * sp;
-       struct vm_area_struct *mpnt;
-
-       mpnt = (struct vm_area_struct *)kmalloc(sizeof(*mpnt), GFP_KERNEL);
-       if (mpnt) {
-               mpnt->vm_task = current;
-               mpnt->vm_start = PAGE_MASK & (unsigned long) p;
-               mpnt->vm_end = TASK_SIZE;
-               mpnt->vm_page_prot = PAGE_PRIVATE|PAGE_DIRTY;
-               mpnt->vm_share = NULL;
-               mpnt->vm_inode = NULL;
-               mpnt->vm_offset = 0;
-               mpnt->vm_ops = NULL;
-               insert_vm_struct(current, mpnt);
-               current->mm->stk_vma = mpnt;
-       }
-       sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
-       if(exec) sp -= DLINFO_ITEMS*2;
-       dlinfo = sp;
-       sp -= envc+1;
-       envp = sp;
-       sp -= argc+1;
-       argv = sp;
-       if (!ibcs) {
-               put_fs_long((unsigned long)envp,--sp);
-               put_fs_long((unsigned long)argv,--sp);
-       }
-
-       /* The constant numbers (0-9) that we are writing here are
-          described in the header file sys/auxv.h on at least
-          some versions of SVr4 */
-       if(exec) { /* Put this here for an ELF program interpreter */
-         struct elf_phdr * eppnt;
-         eppnt = (struct elf_phdr *) exec->e_phoff;
-         put_fs_long(3,dlinfo++); put_fs_long(load_addr + exec->e_phoff,dlinfo++);
-         put_fs_long(4,dlinfo++); put_fs_long(sizeof(struct elf_phdr),dlinfo++);
-         put_fs_long(5,dlinfo++); put_fs_long(exec->e_phnum,dlinfo++);
-         put_fs_long(9,dlinfo++); put_fs_long((unsigned long) exec->e_entry,dlinfo++);
-         put_fs_long(7,dlinfo++); put_fs_long(SHM_RANGE_START,dlinfo++);
-         put_fs_long(8,dlinfo++); put_fs_long(0,dlinfo++);
-         put_fs_long(6,dlinfo++); put_fs_long(PAGE_SIZE,dlinfo++);
-         put_fs_long(0,dlinfo++); put_fs_long(0,dlinfo++);
-       };
-
-       put_fs_long((unsigned long)argc,--sp);
-       current->mm->arg_start = (unsigned long) p;
-       while (argc-->0) {
-               put_fs_long((unsigned long) p,argv++);
-               while (get_fs_byte(p++)) /* nothing */ ;
-       }
-       put_fs_long(0,argv);
-       current->mm->arg_end = current->mm->env_start = (unsigned long) p;
-       while (envc-->0) {
-               put_fs_long((unsigned long) p,envp++);
-               while (get_fs_byte(p++)) /* nothing */ ;
-       }
-       put_fs_long(0,envp);
-       current->mm->env_end = (unsigned long) p;
-       return sp;
-}
-
-
-/* This is much more generalized than the library routine read function,
-   so we keep this separate.  Techincally the library read function
-   is only provided so that we can read a.out libraries that have
-   an ELF header */
-
-static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
-                            struct inode * interpreter_inode)
-{
-        struct file * file;
-       struct elf_phdr *elf_phdata  =  NULL;
-       struct elf_phdr *eppnt;
-       unsigned int len;
-       unsigned int load_addr;
-       int elf_exec_fileno;
-       int elf_bss;
-       int old_fs, retval;
-       unsigned int last_bss;
-       int error;
-       int i, k;
-       
-       elf_bss = 0;
-       last_bss = 0;
-       error = load_addr = 0;
-       
-       /* First of all, some simple consistency checks */
-       if((interp_elf_ex->e_type != ET_EXEC && 
-           interp_elf_ex->e_type != ET_DYN) || 
-          (interp_elf_ex->e_machine != EM_386 && interp_elf_ex->e_machine != EM_486) ||
-          (!interpreter_inode->i_op || !interpreter_inode->i_op->bmap || 
-           !interpreter_inode->i_op->default_file_ops->mmap)){
-               return 0xffffffff;
-       };
-       
-       /* Now read in all of the header information */
-       
-       if(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > PAGE_SIZE) 
-           return 0xffffffff;
-       
-       elf_phdata =  (struct elf_phdr *) 
-               kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, GFP_KERNEL);
-       if(!elf_phdata) return 0xffffffff;
-       
-       old_fs = get_fs();
-       set_fs(get_ds());
-       retval = read_exec(interpreter_inode, interp_elf_ex->e_phoff, (char *) elf_phdata,
-                          sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
-       set_fs(old_fs);
-       
-       elf_exec_fileno = open_inode(interpreter_inode, O_RDONLY);
-       if (elf_exec_fileno < 0) return 0xffffffff;
-       file = current->files->fd[elf_exec_fileno];
-
-       eppnt = elf_phdata;
-       for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
-         if(eppnt->p_type == PT_LOAD) {
-           error = do_mmap(file, 
-                           eppnt->p_vaddr & 0xfffff000,
-                           eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
-                           PROT_READ | PROT_WRITE | PROT_EXEC,
-                           MAP_PRIVATE | (interp_elf_ex->e_type == ET_EXEC ? MAP_FIXED : 0),
-                           eppnt->p_offset & 0xfffff000);
-           
-           if(!load_addr && interp_elf_ex->e_type == ET_DYN)
-             load_addr = error;
-           k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
-           if(k > elf_bss) elf_bss = k;
-           if(error < 0 && error > -1024) break;  /* Real error */
-           k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
-           if(k > last_bss) last_bss = k;
-         }
-       
-       /* Now use mmap to map the library into memory. */
-
-       
-       sys_close(elf_exec_fileno);
-       if(error < 0 && error > -1024) {
-               kfree(elf_phdata);
-               return 0xffffffff;
-       }
-
-       padzero(elf_bss);
-       len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */
-
-       /* Map the last of the bss segment */
-       if (last_bss > len)
-         do_mmap(NULL, len, last_bss-len,
-                 PROT_READ|PROT_WRITE|PROT_EXEC,
-                 MAP_FIXED|MAP_PRIVATE, 0);
-       kfree(elf_phdata);
-
-       return ((unsigned int) interp_elf_ex->e_entry) + load_addr;
-}
-
-static unsigned int load_aout_interp(struct exec * interp_ex,
-                            struct inode * interpreter_inode)
-{
-  int retval;
-  unsigned int elf_entry;
-  
-  current->mm->brk = interp_ex->a_bss +
-    (current->mm->end_data = interp_ex->a_data +
-     (current->mm->end_code = interp_ex->a_text));
-  elf_entry = interp_ex->a_entry;
-  
-  
-  if (N_MAGIC(*interp_ex) == OMAGIC) {
-    do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data,
-           PROT_READ|PROT_WRITE|PROT_EXEC,
-           MAP_FIXED|MAP_PRIVATE, 0);
-    retval = read_exec(interpreter_inode, 32, (char *) 0, 
-                      interp_ex->a_text+interp_ex->a_data);
-  } else if (N_MAGIC(*interp_ex) == ZMAGIC || N_MAGIC(*interp_ex) == QMAGIC) {
-    do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data,
-           PROT_READ|PROT_WRITE|PROT_EXEC,
-           MAP_FIXED|MAP_PRIVATE, 0);
-    retval = read_exec(interpreter_inode,
-                      N_TXTOFF(*interp_ex) ,
-                      (char *) N_TXTADDR(*interp_ex),
-                      interp_ex->a_text+interp_ex->a_data);
-  } else
-    retval = -1;
-  
-  if(retval >= 0)
-    do_mmap(NULL, (interp_ex->a_text + interp_ex->a_data + 0xfff) & 
-           0xfffff000, interp_ex->a_bss,
-           PROT_READ|PROT_WRITE|PROT_EXEC,
-           MAP_FIXED|MAP_PRIVATE, 0);
-  if(retval < 0) return 0xffffffff;
-  return elf_entry;
-}
-
-/*
- * These are the functions used to load ELF style executables and shared
- * libraries.  There is no binary dependent code anywhere else.
- */
-
-#define INTERPRETER_NONE 0
-#define INTERPRETER_AOUT 1
-#define INTERPRETER_ELF 2
-
-int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
-{
-       struct elfhdr elf_ex;
-       struct elfhdr interp_elf_ex;
-       struct file * file;
-       struct exec interp_ex;
-       struct inode *interpreter_inode;
-       unsigned int load_addr;
-       unsigned int interpreter_type = INTERPRETER_NONE;
-       int i;
-       int old_fs;
-       int error;
-       struct elf_phdr * elf_ppnt, *elf_phdata;
-       int elf_exec_fileno;
-       unsigned int elf_bss, k, elf_brk;
-       int retval;
-       char * elf_interpreter;
-       unsigned int elf_entry;
-       int status;
-       unsigned int start_code, end_code, end_data;
-       unsigned int elf_stack;
-       char passed_fileno[6];
-       
-       status = 0;
-       load_addr = 0;
-       elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
-       
-       if (elf_ex.e_ident[0] != 0x7f ||
-           strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
-               return  -ENOEXEC;
-       
-       
-       /* First of all, some simple consistency checks */
-       if(elf_ex.e_type != ET_EXEC || 
-          (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
-          (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
-           !bprm->inode->i_op->default_file_ops->mmap)){
-               return -ENOEXEC;
-       };
-       
-       /* Now read in all of the header information */
-       
-       elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize * 
-                                                elf_ex.e_phnum, GFP_KERNEL);
-       
-       old_fs = get_fs();
-       set_fs(get_ds());
-       retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata,
-                          elf_ex.e_phentsize * elf_ex.e_phnum);
-       set_fs(old_fs);
-       if (retval < 0) {
-               kfree (elf_phdata);
-               return retval;
-       }
-       
-       elf_ppnt = elf_phdata;
-       
-       elf_bss = 0;
-       elf_brk = 0;
-       
-       elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
-
-       if (elf_exec_fileno < 0) {
-               kfree (elf_phdata);
-               return elf_exec_fileno;
-       }
-       
-       file = current->files->fd[elf_exec_fileno];
-       
-       elf_stack = 0xffffffff;
-       elf_interpreter = NULL;
-       start_code = 0;
-       end_code = 0;
-       end_data = 0;
-       
-       old_fs = get_fs();
-       set_fs(get_ds());
-       
-       for(i=0;i < elf_ex.e_phnum; i++){
-               if(elf_ppnt->p_type == PT_INTERP) {
-                       /* This is the program interpreter used for shared libraries - 
-                          for now assume that this is an a.out format binary */
-                       
-                       elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz, 
-                                                          GFP_KERNEL);
-                       
-                       retval = read_exec(bprm->inode,elf_ppnt->p_offset,elf_interpreter,
-                                          elf_ppnt->p_filesz);
-#if 0
-                       printk("Using ELF interpreter %s\n", elf_interpreter);
-#endif
-                       if(retval >= 0)
-                               retval = namei(elf_interpreter, &interpreter_inode);
-                       if(retval >= 0)
-                               retval = read_exec(interpreter_inode,0,bprm->buf,128);
-                       
-                       if(retval >= 0){
-                               interp_ex = *((struct exec *) bprm->buf);               /* exec-header */
-                               interp_elf_ex = *((struct elfhdr *) bprm->buf);   /* exec-header */
-                               
-                       };
-                       if(retval < 0) {
-                         kfree (elf_phdata);
-                         kfree(elf_interpreter);
-                         return retval;
-                       };
-               };
-               elf_ppnt++;
-       };
-       
-       set_fs(old_fs);
-       
-       /* Some simple consistency checks for the interpreter */
-       if(elf_interpreter){
-               interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
-               if(retval < 0) {
-                       kfree(elf_interpreter);
-                       kfree(elf_phdata);
-                       return -ELIBACC;
-               };
-               /* Now figure out which format our binary is */
-               if((N_MAGIC(interp_ex) != OMAGIC) && 
-                  (N_MAGIC(interp_ex) != ZMAGIC) &&
-                  (N_MAGIC(interp_ex) != QMAGIC)) 
-                 interpreter_type = INTERPRETER_ELF;
-
-               if (interp_elf_ex.e_ident[0] != 0x7f ||
-                   strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0)
-                 interpreter_type &= ~INTERPRETER_ELF;
-
-               if(!interpreter_type)
-                 {
-                   kfree(elf_interpreter);
-                   kfree(elf_phdata);
-                   return -ELIBBAD;
-                 };
-       }
-       
-       /* OK, we are done with that, now set up the arg stuff,
-          and then start this sucker up */
-       
-       if (!bprm->sh_bang) {
-               char * passed_p;
-               
-               if(interpreter_type == INTERPRETER_AOUT) {
-                 sprintf(passed_fileno, "%d", elf_exec_fileno);
-                 passed_p = passed_fileno;
-               
-                 if(elf_interpreter) {
-                   bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2);
-                   bprm->argc++;
-                 };
-               };
-               if (!bprm->p) {
-                       if(elf_interpreter) {
-                             kfree(elf_interpreter);
-                       }
-                       kfree (elf_phdata);
-                       return -E2BIG;
-               }
-       }
-       
-       /* OK, This is the point of no return */
-       flush_old_exec(bprm);
-
-       current->mm->end_data = 0;
-       current->mm->end_code = 0;
-       current->mm->start_mmap = ELF_START_MMAP;
-       current->mm->mmap = NULL;
-       elf_entry = (unsigned int) elf_ex.e_entry;
-       
-       /* Do this so that we can load the interpreter, if need be.  We will
-          change some of these later */
-       current->mm->rss = 0;
-       bprm->p += change_ldt(0, bprm->page);
-       current->mm->start_stack = bprm->p;
-       
-       /* Now we do a little grungy work by mmaping the ELF image into
-          the correct location in memory.  At this point, we assume that
-          the image should be loaded at fixed address, not at a variable
-          address. */
-       
-       old_fs = get_fs();
-       set_fs(get_ds());
-       
-       elf_ppnt = elf_phdata;
-       for(i=0;i < elf_ex.e_phnum; i++){
-               
-               if(elf_ppnt->p_type == PT_INTERP) {
-                       /* Set these up so that we are able to load the interpreter */
-                 /* Now load the interpreter into user address space */
-                 set_fs(old_fs);
-
-                 if(interpreter_type & 1) elf_entry = 
-                   load_aout_interp(&interp_ex, interpreter_inode);
-
-                 if(interpreter_type & 2) elf_entry = 
-                   load_elf_interp(&interp_elf_ex, interpreter_inode);
-
-                 old_fs = get_fs();
-                 set_fs(get_ds());
-
-                 iput(interpreter_inode);
-                 kfree(elf_interpreter);
-                       
-                 if(elf_entry == 0xffffffff) { 
-                   printk("Unable to load interpreter\n");
-                   kfree(elf_phdata);
-                   send_sig(SIGSEGV, current, 0);
-                   return 0;
-                 };
-               };
-               
-               
-               if(elf_ppnt->p_type == PT_LOAD) {
-                       error = do_mmap(file,
-                                       elf_ppnt->p_vaddr & 0xfffff000,
-                                       elf_ppnt->p_filesz + (elf_ppnt->p_vaddr & 0xfff),
-                                       PROT_READ | PROT_WRITE | PROT_EXEC,
-                                       MAP_FIXED | MAP_PRIVATE,
-                                       elf_ppnt->p_offset & 0xfffff000);
-                       
-#ifdef LOW_ELF_STACK
-                       if(elf_ppnt->p_vaddr & 0xfffff000 < elf_stack) 
-                               elf_stack = elf_ppnt->p_vaddr & 0xfffff000;
-#endif
-                       
-                       if(!load_addr) 
-                         load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
-                       k = elf_ppnt->p_vaddr;
-                       if(k > start_code) start_code = k;
-                       k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
-                       if(k > elf_bss) elf_bss = k;
-                       if((elf_ppnt->p_flags | PROT_WRITE) && end_code <  k)
-                               end_code = k; 
-                       if(end_data < k) end_data = k; 
-                       k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
-                       if(k > elf_brk) elf_brk = k;                 
-                     };
-               elf_ppnt++;
-       };
-       set_fs(old_fs);
-       
-       kfree(elf_phdata);
-       
-       if(!elf_interpreter) sys_close(elf_exec_fileno);
-       current->elf_executable = 1;
-       current->executable = bprm->inode;
-       bprm->inode->i_count++;
-#ifdef LOW_ELF_STACK
-       current->start_stack = p = elf_stack - 4;
-#endif
-       bprm->p -= MAX_ARG_PAGES*PAGE_SIZE;
-       bprm->p = (unsigned long) 
-         create_elf_tables((char *)bprm->p,
-                       bprm->argc,
-                       bprm->envc,
-                       (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
-                       load_addr,    
-                       (interpreter_type == INTERPRETER_AOUT ? 0 : 1));
-       if(interpreter_type == INTERPRETER_AOUT)
-         current->mm->arg_start += strlen(passed_fileno) + 1;
-       current->mm->start_brk = current->mm->brk = elf_brk;
-       current->mm->end_code = end_code;
-       current->mm->start_code = start_code;
-       current->mm->end_data = end_data;
-       current->mm->start_stack = bprm->p;
-       current->suid = current->euid = bprm->e_uid;
-       current->sgid = current->egid = bprm->e_gid;
-
-       /* Calling sys_brk effectively mmaps the pages that we need for the bss and break
-          sections */
-       current->mm->brk = (elf_bss + 0xfff) & 0xfffff000;
-       sys_brk((elf_brk + 0xfff) & 0xfffff000);
-
-       padzero(elf_bss);
-
-       /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
-          and some applications "depend" upon this behavior.
-          Since we do not have the power to recompile these, we
-          emulate the SVr4 behavior.  Sigh.  */
-       error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
-                       MAP_FIXED | MAP_PRIVATE, 0);
-
-       regs->eip = elf_entry;          /* eip, magic happens :-) */
-       regs->esp = bprm->p;                    /* stack pointer */
-       if (current->flags & PF_PTRACED)
-               send_sig(SIGTRAP, current, 0);
-       return 0;
-}
-
-/* This is really simpleminded and specialized - we are loading an
-   a.out library that is given an ELF header. */
-
-int load_elf_library(int fd){
-        struct file * file;
-       struct elfhdr elf_ex;
-       struct elf_phdr *elf_phdata  =  NULL;
-       struct  inode * inode;
-       unsigned int len;
-       int elf_bss;
-       int old_fs, retval;
-       unsigned int bss;
-       int error;
-       int i,j, k;
-       
-       len = 0;
-       file = current->files->fd[fd];
-       inode = file->f_inode;
-       elf_bss = 0;
-       
-       set_fs(KERNEL_DS);
-       if (file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) {
-               sys_close(fd);
-               return -EACCES;
-       }
-       set_fs(USER_DS);
-       
-       if (elf_ex.e_ident[0] != 0x7f ||
-           strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
-               return -ENOEXEC;
-       
-       /* First of all, some simple consistency checks */
-       if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
-          (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
-          (!inode->i_op || !inode->i_op->bmap || 
-           !inode->i_op->default_file_ops->mmap)){
-               return -ENOEXEC;
-       };
-       
-       /* Now read in all of the header information */
-       
-       if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE) 
-               return -ENOEXEC;
-       
-       elf_phdata =  (struct elf_phdr *) 
-               kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);
-       
-       old_fs = get_fs();
-       set_fs(get_ds());
-       retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata,
-                          sizeof(struct elf_phdr) * elf_ex.e_phnum);
-       set_fs(old_fs);
-       
-       j = 0;
-       for(i=0; i<elf_ex.e_phnum; i++)
-               if((elf_phdata + i)->p_type == PT_LOAD) j++;
-       
-       if(j != 1)  {
-               kfree(elf_phdata);
-               return -ENOEXEC;
-       };
-       
-       while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
-       
-       /* Now use mmap to map the library into memory. */
-       error = do_mmap(file,
-                       elf_phdata->p_vaddr & 0xfffff000,
-                       elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),
-                       PROT_READ | PROT_WRITE | PROT_EXEC,
-                       MAP_FIXED | MAP_PRIVATE,
-                       elf_phdata->p_offset & 0xfffff000);
-
-       k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
-       if(k > elf_bss) elf_bss = k;
-       
-       sys_close(fd);
-       if (error != elf_phdata->p_vaddr & 0xfffff000) {
-               kfree(elf_phdata);
-               return error;
-       }
-
-       padzero(elf_bss);
-
-       len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
-       bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
-       if (bss > len)
-         do_mmap(NULL, len, bss-len,
-                 PROT_READ|PROT_WRITE|PROT_EXEC,
-                 MAP_FIXED|MAP_PRIVATE, 0);
-       kfree(elf_phdata);
-       return 0;
-}
index b920c37887ee76c8386fbbbd13df20fdca66f0b3..4971b5df8046b48d3ad39bceffeb99314684bdd4 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -255,13 +255,13 @@ static int aout_core_dump(long signr, struct pt_regs * regs)
                dump_start = dump.u_tsize << 12;
                dump_size = dump.u_dsize << 12;
                DUMP_WRITE(dump_start,dump_size);
-       };
+       }
 /* Now prepare to dump the stack area */
        if (dump.u_ssize != 0) {
                dump_start = dump.start_stack;
                dump_size = dump.u_ssize << 12;
                DUMP_WRITE(dump_start,dump_size);
-       };
+       }
 /* Finally dump the task struct.  Not be used by gdb, but could be useful */
        set_fs(KERNEL_DS);
        DUMP_WRITE(current,sizeof(*current));
@@ -854,8 +854,8 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                        if (error != N_TXTADDR(ex)) {
                                sys_close(fd);
                                send_sig(SIGSEGV, current, 0);
-                               return 0;
-                       };
+                               return -EINVAL;
+                       }
                }
                
                error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data,
@@ -864,8 +864,8 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                sys_close(fd);
                if (error != N_TXTADDR(ex) + ex.a_text) {
                        send_sig(SIGSEGV, current, 0);
-                       return 0;
-               };
+                       return -EINVAL;
+               }
                current->executable = bprm->inode;
                bprm->inode->i_count++;
        }
index 022c59779227f7330de3977eff0ad3021ac0e2ae..bc8d652a6b48e0bf812eac0568fa9091d5baf754 100644 (file)
@@ -18,6 +18,7 @@ static char bin_extensions[] =
   "EXECOMBINAPPSYSDRVOVLOVROBJLIBDLLPIF"       /* program code */
   "ARCZIPLHALZHZOOTARZ  ARJ"   /* common archivers */
   "TZ TAZTZPTPZ"               /* abbreviations of tar.Z and tar.zip */
+  "GZ TGZDEB"                  /* .gz, .tar.gz and Debian packages   */
   "GIFBMPTIFGL JPGPCX"         /* graphics */
   "TFMVF GF PK PXLDVI";                /* TeX */
 
index 4197bd2d22e0c7b71186a3d92a86954a007d08e9..5ddf75d301f2bb513bbd16d39d89ad3b2b933a89 100644 (file)
@@ -466,6 +466,7 @@ static int get_maps(int pid, char *buf)
 extern int get_module_list(char *);
 extern int get_device_list(char *);
 extern int get_filesystem_list(char *);
+extern int get_ksyms_list(char *);
 
 static int array_read(struct inode * inode, struct file * file,char * buf, int count)
 {
@@ -529,6 +530,9 @@ static int array_read(struct inode * inode, struct file * file,char * buf, int c
                case 19:
                        length = get_filesystem_list(page);
                        break;
+               case 20:
+                       length = get_ksyms_list(page);
+                       break;
                default:
                        free_page((unsigned long) page);
                        return -EBADF;
index 29010f14a95a312dbd5891071c5623465ef2d3c5..7da96da93bb23450f5858759fa74988ac828ecd0 100644 (file)
@@ -69,6 +69,7 @@ static struct proc_dir_entry root_dir[] = {
        {17,4,"stat" },
        {18,7,"devices" },
        {19,11,"filesystems" },
+       {20,5,"ksyms" },
 };
 
 #define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0])))
index a4635f8466fb8fe9fda1bdd5f75e4281a7b87930..75d38ff8a6f0b6df0a78dec170b17112c53274a9 100644 (file)
@@ -1,7 +1,8 @@
 /****************************************************************************************
  *                                                                                     *
- * SCSI header library for linux                                                       *
+ * general (not only SCSI) header library for linux CDROM drivers                       *
  * (C) 1992 David Giller rafetmad@oxy.edu                                              *
+ *     1994 Eberhard Moenkeberg emoenke@gwdg.de ("read audio" and some other stuff)    *
  *                                                                                     *
  * <linux/cdrom.h> -- CD-ROM IOCTLs and structs                                                *
  *                                                                                     *
 #ifndef        _LINUX_CDROM_H
 #define        _LINUX_CDROM_H
 
+/*
+ * some fix numbers
+ */
+#define CD_MINS                   75  /* minutes per CD                  */
+#define CD_SECS                   60  /* seconds per minute              */
+#define CD_FRAMES                 75  /* frames per second               */
+#define CD_FRAMESIZE            2048  /* bytes per frame, cooked mode    */
+#define CD_FRAMESIZE_XA         2340  /* bytes per frame, "xa" mode      */
+#define CD_FRAMESIZE_RAW        2352  /* bytes per frame, "raw" mode     */
+#define CD_FRAMESIZE_SUB          96  /* subchannel data size            */
+#define CD_BLOCK_OFFSET          150  /* offset of first logical frame   */
+#define CD_XA_HEAD                12  /* header size of XA frame         */
+#define CD_XA_TAIL               280  /* tail size of XA frame           */
+
 /*
  *
  * For IOCTL calls, we will commandeer byte 0x53, or 'S'.
@@ -295,6 +310,28 @@ struct cdrom_read
        int     cdread_buflen;
        };
 
+/*
+ * preliminary extensions for transfering audio frames
+ * currently used by sbpcd.c
+ * (still may change if other drivers will use it, too):
+ */
+struct cdrom_read_audio
+       {
+         union
+           {
+             struct                    
+               {
+                 u_char minute;
+                 u_char second;
+                 u_char frame;
+               } msf;
+             int       lba;
+           } addr; /* frame address */
+         u_char addr_format; /* CDROM_LBA or CDROM_MSF */
+         int nframes; /* number of 2352-byte-frames to read at once, currently only 1 allowed */
+         u_char *buf; /* frame buffer (size: nframes*2352 bytes) */
+       };
+
 #ifdef FIVETWELVE
 #define        CDROM_MODE1_SIZE        512
 #else
@@ -309,7 +346,7 @@ struct cdrom_read
 #define        CDROMPAUSE              0x5301          /* pause                        */
 #define        CDROMRESUME             0x5302          /* resume                       */
 
-#define        CDROMPLAYMSF            0x5303          /* (stuct cdrom_msf)            */
+#define        CDROMPLAYMSF            0x5303          /* (struct cdrom_msf)           */
                                                 /* SCMD_PLAY_AUDIO_MSF         */
 
 #define        CDROMPLAYTRKIND         0x5304          /* (struct cdrom_ti)            */
@@ -336,5 +373,12 @@ struct cdrom_read
 
 #define        CDROMREADMODE1          0x530d          /* (struct cdrom_read)          */
                                                 /* read type-1 data            */
+/*
+ * preliminary extension for transfering audio frames
+ * currently used by sbpcd.c
+ * (still may change if other drivers will use it, too):
+ */
+#define        CDROMREADAUDIO          0x530e          /* (struct cdrom_read_audio)    */
 
 #endif  _LINUX_CDROM_H
+
diff --git a/include/linux/mktime.h b/include/linux/mktime.h
deleted file mode 100644 (file)
index 1c58e63..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _LINUX_MKTIME_H
-#define _LINUX_MKTIME_H
-
-struct mktime {
-       int sec;
-       int min;
-       int hour;
-       int day;
-       int mon;
-       int year;
-};
-
-#endif
index 117478c0c19e1a718dc93e9e8b8948b1074b31ac..b82fa281b65808840718d12bc666c5d3a7e851b1 100644 (file)
@@ -1,5 +1,7 @@
 /*
  * Dynamic loading of modules into the kernel.
+ *
+ * Modified by Bjorn Ekwall <bj0rn@blox.se>
  */
 
 #ifndef _LINUX_MODULE_H
 /* maximum length of symbol name */
 #define SYM_MAX_NAME 60
 
+struct kernel_sym { /* sent to "insmod" */
+       unsigned long value;            /* value of symbol */
+       char name[SYM_MAX_NAME];        /* name of symbol */
+};
+
+struct module_ref {
+       struct module *module;
+       struct module_ref *next;
+};
+
+struct internal_symbol {
+       void *addr;
+       char *name;
+       };
+
+struct symbol_table { /* received from "insmod" */
+       int size; /* total, including string table!!! */
+       int n_symbols;
+       int n_refs;
+       struct internal_symbol symbol[0]; /* actual size defined by n_symbols */
+       struct module_ref ref[0]; /* actual size defined by n_refs */
+};
+/*
+ * Note: The string table follows immediately after the symbol table in memory!
+ */
 
 struct module {
        struct module *next;
+       struct module_ref *ref; /* the list of modules that refer to me */
+       struct symbol_table *symtab;
        char *name;
        int size;                       /* size of module in pages */
        void* addr;                     /* address of module */
@@ -26,19 +55,13 @@ struct module {
        void (*cleanup)(void);          /* cleanup routine */
 };
 
-
 struct mod_routines {
        int (*init)(void);              /* initialization routine */
        void (*cleanup)(void);          /* cleanup routine */
 };
 
-
-struct kernel_sym {
-       unsigned long value;            /* value of symbol */
-       char name[SYM_MAX_NAME];        /* name of symbol */
-};
-
-extern struct module *module_list;
+/* rename_module_symbol(old_name, new_name)  WOW! */
+extern int rename_module_symbol(char *, char *);
 
 
 /*
index 4370dd099739c1db3e84c61f45c42d5f3724292a..9d50007e5f74fad7dbea2b1e08bb647bd606dcce 100644 (file)
  *                                 sbpcd=0x300,LaserMate
  *                             or
  *                                 sbpcd=0x330,SPEA
- * these strings are case sensitive !!!
+ *
+ *  and, if you have a second CDROM controller board,
+ *                                 sbpcd2=0x310,LaserMate
+ *  and so on.
+ *
+ * These strings are case sensitive !!!
  */
 
-/* 
- * change this to select the type of your interface board:
+/*
+ * put your CDROM port base address into CDROM_PORT
+ * and specify the type of your interface in SBPRO.
+ *
+ * SBPRO addresses typically are 0x0230 (=0x220+0x10), 0x0250, ...
+ * LASERMATE (CI-101P) adresses typically are 0x0300, 0x0310, ...
+ * SPEA addresses are 0x320, 0x330, 0x340, 0x350
+ * there are some soundcards on the market with 0x0630, 0x0650, ...
+ *
+ * example: if your SBPRO audio address is 0x220, specify 0x230.
+ *
  *
  * set SBPRO to 1 for "true" SoundBlaster card
  * set SBPRO to 0 for "poor" (no sound) interface cards
  * (currently I do not know any "compatible" with SBPRO 1)
  * then I can include better information with the next release.
  */
+#if !(SBPCD_ISSUE-1) /* first (or if you have only one) interface board: */
+#define CDROM_PORT 0x0230
 #define SBPRO     1
+#endif
+
+/* ignore the rest if you have only one interface board & driver */
+
+#if !(SBPCD_ISSUE-2) /* second interface board: */
+#define CDROM_PORT 0x0370
+#define SBPRO     0
+#endif
+#if !(SBPCD_ISSUE-3) /* third interface board: */
+#define CDROM_PORT 0x0330
+#define SBPRO     0
+#endif
+#if !(SBPCD_ISSUE-4) /* fourth interface board: */
+#define CDROM_PORT 0x0340
+#define SBPRO     0
+#endif
 
+/*==========================================================================*/
+/*==========================================================================*/
 /*
- * put your CDROM port base address here:
- * SBPRO addresses typically are 0x0230 (=0x220+0x10), 0x0250, ...
- * LASERMATE (CI-101P) adresses typically are 0x0300, 0x0310, ...
- * SPEA addresses are 0x320, 0x330, 0x340, 0x350
- * there are some soundcards on the market with 0x0630, 0x0650, ...
- *
- * example: if your SBPRO audio address is 0x220, specify 0x230.
- *
+ * nothing to change below here if you are not experimenting
  */
-#define CDROM_PORT 0x0230
+#ifndef _LINUX_SBPCD_H
 
+#define _LINUX_SBPCD_H
 
 /*==========================================================================*/
 /*==========================================================================*/
 /*
- * nothing to change below here if you are not experimenting
+ * to fork and execute a function after some elapsed time:
+ * one "jifs" unit is 10 msec.
  */
+#undef MY_TIMER
+#undef SET_TIMER
+#undef CLEAR_TIMER
+
+#if !(SBPCD_ISSUE-1)
+#define MY_TIMER SBPCD_TIMER
+#endif
+#if !(SBPCD_ISSUE-2)
+#define MY_TIMER SBPCD2_TIMER
+#endif
+#if !(SBPCD_ISSUE-3)
+#define MY_TIMER SBPCD3_TIMER
+#endif
+#if !(SBPCD_ISSUE-4)
+#define MY_TIMER SBPCD4_TIMER
+#endif
+
+#define SET_TIMER(func, jifs) \
+        ((timer_table[MY_TIMER].expires = jiffies + jifs), \
+        (timer_table[MY_TIMER].fn = func), \
+        (timer_active |= 1<<MY_TIMER))
+
+#define CLEAR_TIMER    timer_active &= ~(1<<MY_TIMER)
+
 /*==========================================================================*/
 /*==========================================================================*/
 /*
 #define DBG_LCK                23      /* door (un)lock info */
 #define DBG_SQ                 24      /* dump SubQ frame */
 #define DBG_AUD                25      /* "read audio" debugging */
-#define DBG_000                26      /* unnecessary information */
+#define DBG_SEQ                26      /* Sequoia interface configuration trace */
+#define DBG_000                27      /* unnecessary information */
 
 /*==========================================================================*/
 /*==========================================================================*/
 #define READ_SC  0x04 /* "subchannel info": 96 bytes per frame */
 #define READ_AU  0x08 /* "audio frame": 2352 bytes per frame */
 
-/*
- * preliminary extensions to cdrom.h for transfering audio frames:
- */
-#define CDROMREADAUDIO 0xE0 /* IOCTL function (arg = &cdrom_aud) */
-
-struct cdrom_aud { u_int lba; /* frame address */
-                   u_char *buf; /* frame buffer (2352 bytes) */
-                 };
-
 /*
  * sense byte: used only if new_drive
  *                  only during cmd 09 00 xx ah al 00 00
  *
  *          values: 00
- *                  82
+ *                  82 "raw audio" mode
  *                  xx from infobuf[0] after 85 00 00 00 00 00 00
  */
 
-
-#define CD_MINS                   75  /* minutes per CD                  */
-#define CD_SECS                   60  /* seconds per minutes             */
-#define CD_FRAMES                 75  /* frames per second               */
-#define CD_FRAMESIZE            2048  /* bytes per frame, data mode      */
-#define CD_FRAMESIZE_XA         2340  /* bytes per frame, "xa" mode      */
-#define CD_FRAMESIZE_RAW        2352  /* bytes per frame, "raw" mode     */
-#define CD_FRAMESIZE_SUB          96  /* subchannel data size            */
-#define CD_BLOCK_OFFSET          150  /* offset of first logical frame   */
-#define CD_XA_HEAD                12  /* header size of XA frame         */
-#define CD_XA_TAIL               280  /* tail size of XA frame           */
-
 /* audio status (bin) */
 #define aud_00 0x00 /* Audio status byte not supported or not valid */
 #define audx11 0x0b /* Audio play operation in progress             */
@@ -406,7 +439,6 @@ Read XA Parameter:
 
 /*
  * highest allowed drive number (MINOR+1)
- * currently only one controller, maybe later up to 4
  */
 #define NR_SBPCD 4
 
@@ -429,25 +461,12 @@ Read XA Parameter:
  */
 #define READ_DATA(port, buf, nr) insb(port, buf, nr)
 
-/*==========================================================================*/
-/*
- * to fork and execute a function after some elapsed time:
- * one "jifs" unit is 10 msec.
- */
-#define SET_TIMER(func, jifs) \
-        ((timer_table[SBPCD_TIMER].expires = jiffies + jifs), \
-        (timer_table[SBPCD_TIMER].fn = func), \
-        (timer_active |= 1<<SBPCD_TIMER))
-
-#define CLEAR_TIMER    timer_active &= ~(1<<SBPCD_TIMER)
-
 /*==========================================================================*/
 /*
  * Creative Labs Programmers did this:
  */
 #define MAX_TRACKS     120 /* why more than 99? */
 
-
 /*==========================================================================*/
 /*
  * To make conversions easier (machine dependent!)
@@ -467,3 +486,4 @@ typedef union _blk
 BLK;
 
 /*==========================================================================*/
+#endif _LINUX_SBPCD_H
index 5b3f21fd1ef59e98db00cd2ca2d86afc4773bacb..dd457e118990882cfa2b8325f1e5473204f91804 100644 (file)
@@ -71,6 +71,7 @@ extern char empty_zero_page[PAGE_SIZE];
 extern int vsprintf(char *,const char *,va_list);
 extern void init(void);
 extern void init_IRQ(void);
+extern void init_modules(void);
 extern long kmalloc_init (long,long);
 extern long blk_dev_init(long,long);
 extern long chr_dev_init(long,long);
@@ -399,6 +400,7 @@ asmlinkage void start_kernel(void)
        init_IRQ();
        sched_init();
        parse_options(command_line);
+       init_modules();
 #ifdef CONFIG_PROFILE
        prof_buffer = (unsigned long *) memory_start;
        prof_len = (unsigned long) &end;
index 34170227b6aa428c2128897f92b47e27e16fdd6f..b8328554e1cedb9a7f9f9f1a8de68afd301d7d63 100644 (file)
@@ -2,6 +2,9 @@
  * Herein lies all the functions/variables that are "exported" for linkage
  * with dynamically loaded kernel modules.
  *                     Jon.
+ *
+ * Stacked module support and unified symbol table added by
+ * Bjorn Ekwall <bj0rn@blox.se>
  */
 
 #include <linux/autoconf.h>
 #include <linux/interrupt.h>
 #include <linux/binfmts.h>
 #include <linux/personality.h>
+#include <linux/module.h>
 #ifdef CONFIG_INET
 #include <linux/netdevice.h>
 #endif
+
+#include <asm/irq.h>
   
 extern void *sys_call_table;
 
+/* must match struct internal_symbol !!! */
 #define X(name)        { (void *) &name, "_" #name }
 
 #ifdef CONFIG_FTAPE
@@ -53,12 +60,14 @@ extern void netif_rx(struct sk_buff *);
 extern int dev_rint(unsigned char *, long, int, struct device *);
 extern void dev_tint(struct device *);
 extern struct device *irq2dev_map[];
+extern void dev_kfree_skb(struct sk_buff *, int);
 #endif
 
-struct {
-       void *addr;
-       const char *name;
-} symbol_table[] = {
+struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
+       {
+       /* stackable module support */
+       X(rename_module_symbol),
+
        /* system info variables */
        X(EISA_bus),
        X(wp_works_ok),
@@ -109,6 +118,8 @@ struct {
        X(irqaction),
        X(request_irq),
        X(free_irq),
+       X(enable_irq),
+       X(disable_irq),
        X(bh_active),
        X(bh_mask),
 
@@ -164,7 +175,18 @@ struct {
        X(dev_rint),
        X(dev_tint),
        X(irq2dev_map),
+       X(dev_kfree_skb),
 #endif
+
+       /********************************************************
+        * Do not add anything below this line,
+        * as the stacked modules depend on this!
+        */
+       { NULL, NULL } /* mark end of table */
+       },
+       { NULL, NULL } /* no module refs */
 };
 
+/*
 int symbol_table_size = sizeof (symbol_table) / sizeof (symbol_table[0]);
+*/
diff --git a/kernel/mktime.c b/kernel/mktime.c
deleted file mode 100644 (file)
index 26abae2..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  linux/kernel/mktime.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-#include <linux/mktime.h>
-
-/*
- * This isn't the library routine, it is only used in the kernel.
- * as such, we don't care about years<1970 etc, but assume everything
- * is ok. Similarly, TZ etc is happily ignored. We just do everything
- * as easily as possible. Let's find something public for the library
- * routines (although I think minix times is public).
- */
-/*
- * PS. I hate whoever though up the year 1970 - couldn't they have gotten
- * a leap-year instead? I also hate Gregorius, pope or no. I'm grumpy.
- */
-#define MINUTE 60
-#define HOUR (60*MINUTE)
-#define DAY (24*HOUR)
-#define YEAR (365*DAY)
-
-/* interestingly, we assume leap-years */
-static int month[12] = {
-       0,
-       DAY*(31),
-       DAY*(31+29),
-       DAY*(31+29+31),
-       DAY*(31+29+31+30),
-       DAY*(31+29+31+30+31),
-       DAY*(31+29+31+30+31+30),
-       DAY*(31+29+31+30+31+30+31),
-       DAY*(31+29+31+30+31+30+31+31),
-       DAY*(31+29+31+30+31+30+31+31+30),
-       DAY*(31+29+31+30+31+30+31+31+30+31),
-       DAY*(31+29+31+30+31+30+31+31+30+31+30)
-};
-
-long kernel_mktime(struct mktime * time)
-{
-       long res;
-       int year;
-
-       year = time->year - 70;
-/* magic offsets (y+1) needed to get leapyears right.*/
-       res = YEAR*year + DAY*((year+1)/4);
-       res += month[time->mon];
-/* and (y+2) here. If it wasn't a leap-year, we have to adjust */
-       if (time->mon>1 && ((year+2)%4))
-               res -= DAY;
-       res += DAY*(time->day-1);
-       res += HOUR*time->hour;
-       res += MINUTE*time->min;
-       res += time->sec;
-       return res;
-}
index 9beb06f0175061e820fbb758db47de64959d848d..80679d6ea5fa49535fe1268591cb19df07d058f8 100644 (file)
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/malloc.h>
+/*
+ * Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May 1994 (C)
+ * This source is covered by the GNU GPL, the same as all kernel sources.
+ *
+ * Features:
+ *     - Supports stacked modules (removeable only of there are no dependants).
+ *     - Supports table of symbols defined by the modules.
+ *     - Supports /proc/ksyms, showing value, name and owner of all
+ *       the symbols defined by all modules (in stack order).
+ *     - Added module dependencies information into /proc/modules
+ *     - Supports redefines of all symbols, for streams-like behaviour.
+ *     - Compatible with older versions of insmod.
+ *
+ */
+
+#ifdef DEBUG_MODULE
+#define PRINTK(a) printk a
+#else
+#define PRINTK(a) /* */
+#endif
+
+static struct module kernel_module;
+static struct module *module_list = &kernel_module;
+
+static int freeing_modules; /* true if some modules are marked for deletion */
+
+static struct module *find_module( const char *name);
+static int get_mod_name( char *user_name, char *buf);
+static int free_modules( void);
+
+
+/*
+ * Called at boot time
+ */
+void init_modules(void) {
+       extern struct symbol_table symbol_table; /* in kernel/ksyms.c */
+       struct internal_symbol *sym;
+       int i;
 
-struct module *module_list = NULL;
-int freeing_modules;           /* true if some modules are marked for deletion */
+       for (i = 0, sym = symbol_table.symbol; sym->name; ++sym, ++i)
+               ;
+       symbol_table.n_symbols = i;
 
-struct module *find_module( const char *name);
-int get_mod_name( char *user_name, char *buf);
-int free_modules( void);
+       kernel_module.symtab = &symbol_table;
+       kernel_module.state = MOD_RUNNING; /* Hah! */
+       kernel_module.name = "";
+}
+
+int
+rename_module_symbol(char *old_name, char *new_name)
+{
+       struct internal_symbol *sym;
+       int i = 0; /* keep gcc silent */
+
+       if (module_list->symtab) {
+               sym = module_list->symtab->symbol;
+               for (i = module_list->symtab->n_symbols; i > 0; ++sym, --i) {
+                       if (strcmp(sym->name, old_name) == 0) { /* found it! */
+                               sym->name = new_name; /* done! */
+                               PRINTK(("renamed %s to %s\n", old_name, new_name));
+                               return 1; /* it worked! */
+                       }
+               }
+       }
+       printk("rename %s to %s failed!\n", old_name, new_name);
+       return 0; /* not there... */
+
+       /*
+        * This one will change the name of the first matching symbol!
+        *
+        * With this function, you can replace the name of a symbol defined
+        * in the current module with a new name, e.g. when you want to insert
+        * your own function instead of a previously defined function
+        * with the same name.
+        *
+        * "Normal" usage:
+        *
+        * bogus_function(int params)
+        * {
+        *      do something "smart";
+        *      return real_function(params);
+        * }
+        *
+        * ...
+        *
+        * init_module()
+        * {
+        *      if (rename_module_symbol("_bogus_function", "_real_function"))
+        *              printk("yep!\n");
+        *      else
+        *              printk("no way!\n");
+        * ...
+        * }
+        *
+        * When loading this module, real_function will be resolved
+        * to the real function address.
+        * All later loaded modules that refer to "real_function()" will
+        * then really call "bogus_function()" instead!!!
+        *
+        * This feature will give you ample opportunities to get to know
+        * the taste of your foot when you stuff it into your mouth!!!
+        */
+}
 
 /*
  * Allocate space for a module.
@@ -20,13 +116,12 @@ int free_modules( void);
 asmlinkage int
 sys_create_module(char *module_name, unsigned long size)
 {
-       int npages;
-       void* addr;
-       int len;
-       char name[MOD_MAX_NAME];
-       char *savename;
        struct module *mp;
+       void* addr;
        int error;
+       int npages;
+       int sspace = sizeof(struct module) + MOD_MAX_NAME;
+       char name[MOD_MAX_NAME];
 
        if (!suser())
                return -EPERM;
@@ -37,30 +132,32 @@ sys_create_module(char *module_name, unsigned long size)
        if (find_module(name) != NULL) {
                return -EEXIST;
        }
-       len = strlen(name) + 1;
-       if ((savename = (char*) kmalloc(len, GFP_KERNEL)) == NULL)
-               return -ENOMEM;
-       memcpy(savename, name, len);
-       if ((mp = (struct module*) kmalloc(sizeof *mp, GFP_KERNEL)) == NULL) {
-               kfree(savename);
+
+       if ((mp = (struct module*) kmalloc(sspace, GFP_KERNEL)) == NULL) {
                return -ENOMEM;
        }
+       strcpy((char *)(mp + 1), name); /* why not? */
+
        npages = (size + sizeof (int) + 4095) / 4096;
        if ((addr = vmalloc(npages * 4096)) == 0) {
-               kfree_s(mp, sizeof *mp);
-               kfree(savename);
+               kfree_s(mp, sspace);
                return -ENOMEM;
        }
-       mp->name = savename;
+
+       mp->next = module_list;
+       mp->ref = NULL;
+       mp->symtab = NULL;
+       mp->name = (char *)(mp + 1);
        mp->size = npages;
        mp->addr = addr;
        mp->state = MOD_UNINITIALIZED;
-       * (int *) addr = 0;             /* set use count to zero */
        mp->cleanup = NULL;
-       mp->next = module_list;
-       module_list = mp;
-       printk("module `%s' (%lu pages @ 0x%08lx) created\n",
-               mp->name, (unsigned long) mp->size, (unsigned long) mp->addr);
+
+       * (int *) addr = 0;     /* set use count to zero */
+       module_list = mp;       /* link it in */
+
+       PRINTK(("module `%s' (%lu pages @ 0x%08lx) created\n",
+               mp->name, (unsigned long) mp->size, (unsigned long) mp->addr));
        return (int) addr;
 }
 
@@ -69,15 +166,24 @@ sys_create_module(char *module_name, unsigned long size)
  */
 asmlinkage int
 sys_init_module(char *module_name, char *code, unsigned codesize,
-               struct mod_routines *routines)
+               struct mod_routines *routines,
+               struct symbol_table *symtab)
 {
        struct module *mp;
+       struct symbol_table *newtab;
        char name[MOD_MAX_NAME];
        int error;
        struct mod_routines rt;
 
        if (!suser())
                return -EPERM;
+
+       /* A little bit of protection... we "know" where the user stack is... */
+       if (symtab && ((unsigned long)symtab > 0xb0000000)) {
+               printk("warning: you are using an old insmod, no symbols will be inserted!\n");
+               symtab = NULL;
+       }
+
        /*
         * First reclaim any memory from dead modules that where not
         * freed when deleted. Should I think be done by timers when
@@ -87,8 +193,8 @@ sys_init_module(char *module_name, char *code, unsigned codesize,
 
        if ((error = get_mod_name(module_name, name)) != 0)
                return error;
-       printk( "initializing module `%s', %d (0x%x) bytes\n",
-               name, codesize, codesize);
+       PRINTK(("initializing module `%s', %d (0x%x) bytes\n",
+               name, codesize, codesize));
        memcpy_fromfs(&rt, routines, sizeof rt);
        if ((mp = find_module(name)) == NULL)
                return -ENOENT;
@@ -97,12 +203,53 @@ sys_init_module(char *module_name, char *code, unsigned codesize,
        memcpy_fromfs((char *)mp->addr + sizeof (int), code, codesize);
        memset((char *)mp->addr + sizeof (int) + codesize, 0,
                mp->size * 4096 - (codesize + sizeof (int)));
-       printk( "  init entry @ 0x%08lx, cleanup entry @ 0x%08lx\n",
-               (unsigned long) rt.init, (unsigned long) rt.cleanup);
+       PRINTK(( "module init entry = 0x%08lx, cleanup entry = 0x%08lx\n",
+               (unsigned long) rt.init, (unsigned long) rt.cleanup));
        mp->cleanup = rt.cleanup;
+
+       /* update kernel symbol table */
+       if (symtab) { /* symtab == NULL means no new entries to handle */
+               struct internal_symbol *sym;
+               struct module_ref *ref;
+               int size;
+               int i;
+
+               if ((error = verify_area(VERIFY_READ, symtab, sizeof(int))))
+                       return error;
+               memcpy_fromfs((char *)(&(size)), symtab, sizeof(int));
+
+               if ((newtab = (struct symbol_table*) kmalloc(size, GFP_KERNEL)) == NULL) {
+                       return -ENOMEM;
+               }
+
+               if ((error = verify_area(VERIFY_READ, symtab, size)))
+                       return error;
+               memcpy_fromfs((char *)(newtab), symtab, size);
+
+               /* relocate name pointers, index referred from start of table */
+               for (sym = &(newtab->symbol[0]), i = 0;
+                       i < newtab->n_symbols; ++sym, ++i) {
+                       sym->name += (long)newtab;
+               }
+               mp->symtab = newtab;
+
+               /* Update module references.
+                * On entry, from "insmod", ref->module points to
+                * the referenced module!
+                * Also, "sym" from above, points to the first ref entry!!!
+                */
+               for (ref = (struct module_ref *)sym, i = 0;
+                       i < newtab->n_refs; ++ref, ++i) {
+                       ref->next = ref->module->ref;
+                       ref->module->ref = ref;
+                       ref->module = mp;
+               }
+       }
+
        if ((*rt.init)() != 0)
                return -EBUSY;
        mp->state = MOD_RUNNING;
+
        return 0;
 }
 
@@ -115,12 +262,13 @@ sys_delete_module(char *module_name)
 
        if (!suser())
                return -EPERM;
+       /* else */
        if (module_name != NULL) {
                if ((error = get_mod_name(module_name, name)) != 0)
                        return error;
                if ((mp = find_module(name)) == NULL)
                        return -ENOENT;
-               if (GET_USE_COUNT(mp) != 0)
+               if ((mp->ref != NULL) || (GET_USE_COUNT(mp) != 0))
                        return -EBUSY;
                if (mp->state == MOD_RUNNING)
                        (*mp->cleanup)();
@@ -130,38 +278,74 @@ sys_delete_module(char *module_name)
        return 0;
 }
 
+
 /*
  * Copy the kernel symbol table to user space.  If the argument is null,
  * just return the size of the table.
+ *
+ * Note that the transient module symbols are copied _first_,
+ * in lifo order!!!
+ *
+ * The symbols to "insmod" are according to the "old" format: struct kernel_sym,
+ * which is actually quite handy for this purpose.
+ * Note that insmod inserts a struct symbol_table later on...
+ * (as that format is quite handy for the kernel...)
+ *
+ * For every module, the first (pseudo)symbol copied is the module name
+ * and the adress of the module struct.
+ * This lets "insmod" keep track of references, and build the array of
+ * struct module_refs in the symbol table.
+ * The format of the module name is "#module", so that "insmod" can easily
+ * notice when a module name comes along. Also, this will make it possible
+ * to use old versions of "insmod", albeit with reduced functionality...
+ * The "kernel" module has an empty name.
  */
 asmlinkage int
 sys_get_kernel_syms(struct kernel_sym *table)
 {
-       struct symbol {
-               unsigned long addr;
-               char *name;
-       };
-       extern int symbol_table_size;
-       extern struct symbol symbol_table[];
-       int i;
-       struct symbol *from;
+       struct internal_symbol *from;
+       struct kernel_sym isym;
        struct kernel_sym *to;
-       struct kernel_sym sym;
+       struct module *mp = module_list;
+       int i;
+       int nmodsyms = 0;
+
+       for (mp = module_list; mp; mp = mp->next) {
+               if (mp->symtab && mp->symtab->n_symbols) {
+                       /* include the count for the module name! */
+                       nmodsyms += mp->symtab->n_symbols + 1;
+               }
+       }
 
        if (table != NULL) {
-               from = symbol_table;
                to = table;
-               i = verify_area(VERIFY_WRITE, to, symbol_table_size * sizeof *table);
-               if (i)
+
+               if ((i = verify_area(VERIFY_WRITE, to, nmodsyms * sizeof(*table))))
                        return i;
-               for (i = symbol_table_size ; --i >= 0 ; ) {
-                       sym.value = from->addr;
-                       strncpy(sym.name, from->name, sizeof sym.name);
-                       memcpy_tofs(to, &sym, sizeof sym);
-                       from++, to++;
+
+               /* copy all module symbols first (always LIFO order) */
+               for (mp = module_list; mp; mp = mp->next) {
+                       if ((mp->state == MOD_RUNNING) &&
+                               (mp->symtab != NULL) && (mp->symtab->n_symbols > 0)) {
+                               /* magic: write module info as a pseudo symbol */
+                               isym.value = (unsigned long)mp;
+                               sprintf(isym.name, "#%s", mp->name);
+                               memcpy_tofs(to, &isym, sizeof isym);
+                               ++to;
+
+                               for (i = mp->symtab->n_symbols,
+                                       from = mp->symtab->symbol;
+                                       i > 0; --i, ++from, ++to) {
+
+                                       isym.value = (unsigned long)from->addr;
+                                       strncpy(isym.name, from->name, sizeof isym.name);
+                                       memcpy_tofs(to, &isym, sizeof isym);
+                               }
+                       }
                }
        }
-       return symbol_table_size;
+
+       return nmodsyms;
 }
 
 
@@ -199,6 +383,27 @@ find_module( const char *name)
        return mp;
 }
 
+static void
+drop_refs(struct module *mp)
+{
+       struct module *step;
+       struct module_ref *prev;
+       struct module_ref *ref;
+
+       for (step = module_list; step; step = step->next) {
+               for (prev = ref = step->ref; ref; ref = prev->next) {
+                       if (ref->module == mp) {
+                               if (ref == step->ref)
+                                       step->ref = ref->next;
+                               else
+                                       prev->next = ref->next;
+                               break; /* every module only references once! */
+                       }
+                       else
+                               prev = ref;
+               }
+       }
+}
 
 /*
  * Try to free modules which have been marked for deletion.  Returns nonzero
@@ -217,15 +422,22 @@ free_modules( void)
        while ((mp = *mpp) != NULL) {
                if (mp->state != MOD_DELETED) {
                        mpp = &mp->next;
-               } else if (GET_USE_COUNT(mp) != 0) {
-                       freeing_modules = 1;
-                       mpp = &mp->next;
-               } else {        /* delete it */
-                       *mpp = mp->next;
-                       vfree(mp->addr);
-                       kfree(mp->name);
-                       kfree_s(mp, sizeof *mp);
-                       did_deletion = 1;
+               } else {
+                       if (GET_USE_COUNT(mp) != 0) {
+                               freeing_modules = 1;
+                               mpp = &mp->next;
+                       } else {        /* delete it */
+                               *mpp = mp->next;
+                               if (mp->symtab) {
+                                       if (mp->symtab->n_refs)
+                                               drop_refs(mp);
+                                       if (mp->symtab->size)
+                                               kfree_s(mp->symtab, mp->symtab->size);
+                               }
+                               vfree(mp->addr);
+                               kfree_s(mp, sizeof(struct module) + MOD_MAX_NAME);
+                               did_deletion = 1;
+                       }
                }
        }
        return did_deletion;
@@ -241,10 +453,12 @@ int get_module_list(char *buf)
        char *q;
        int i;
        struct module *mp;
+       struct module_ref *ref;
        char size[32];
 
        p = buf;
-       for (mp = module_list ; mp ; mp = mp->next) {
+       /* Do not show the kernel pseudo module */
+       for (mp = module_list ; mp && mp->next; mp = mp->next) {
                if (p - buf > 4096 - 100)
                        break;                  /* avoid overflowing buffer */
                q = mp->name;
@@ -272,7 +486,60 @@ int get_module_list(char *buf)
                        q = "  (bad state)";
                while (*q)
                        *p++ = *q++;
+
+               if ((ref = mp->ref) != NULL) {
+                       *p++ = '\t';
+                       *p++ = '[';
+                       for (; ref; ref = ref->next) {
+                               q = ref->module->name;
+                               while (*q)
+                                       *p++ = *q++;
+                               if (ref->next)
+                                       *p++ = ' ';
+                       }
+                       *p++ = ']';
+               }
                *p++ = '\n';
        }
        return p - buf;
 }
+
+
+/*
+ * Called by the /proc file system to return a current list of ksyms.
+ */
+int get_ksyms_list(char *buf)
+{
+       struct module *mp;
+       struct internal_symbol *sym;
+       int i;
+       char *p = buf;
+
+       for (mp = module_list; mp; mp = mp->next) {
+               if ((mp->state == MOD_RUNNING) &&
+                       (mp->symtab != NULL) && (mp->symtab->n_symbols > 0)) {
+                       for (i = mp->symtab->n_symbols,
+                               sym = mp->symtab->symbol;
+                               i > 0; --i, ++sym) {
+
+                               if (p - buf > 4096 - 100) {
+                                       strcat(p, "...\n");
+                                       p += strlen(p);
+                                       return p - buf; /* avoid overflowing buffer */
+                               }
+
+                               if (mp->name[0]) {
+                                       sprintf(p, "%08lx %s\t[%s]\n",
+                                               (long)sym->addr, sym->name, mp->name);
+                               }
+                               else {
+                                       sprintf(p, "%08lx %s\n",
+                                               (long)sym->addr, sym->name);
+                               }
+                               p += strlen(p);
+                       }
+               }
+       }
+
+       return p - buf;
+}
diff --git a/net/ddi.c b/net/ddi.c
deleted file mode 100644 (file)
index d87cf14..0000000
--- a/net/ddi.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * ddi.c       Implement the Device Driver Interface (DDI) routines.
- *             Currently, this is only used by the NET layer of LINUX,
- *             but it eventually might move to an upper directory of
- *             the system.
- *
- * Version:    @(#)ddi.c       1.0.5   04/22/93
- *
- * Author:     Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
- *
- *
- *     For the moment I'm classifying DDI as 'dead'. However if/when Fred
- *     produces a masterpiece of design DDI may get resurrected. With the
- *     current kernel as modules work by Peter MacDonald they might be
- *     redundant anyway. Thus I've removed all but the protocol initialise.
- *
- *     We will end up with protocol initialisers and socket family initialisers.
- */
-#include <asm/segment.h>
-#include <asm/system.h>
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/ddi.h>
-
-
-#undef DDI_DEBUG
-#ifdef DDI_DEBUG
-#   define PRINTK(x)   printk x
-#else
-#   define PRINTK(x)   /**/
-#endif
-
-
-extern struct ddi_proto                protocols[];    /* network protocols    */
-
-
-/*
- * This is the function that is called by a kernel routine during
- * system startup.  Its purpose is to walk trough the "devices"
- * table (defined above), and to call all moduled defined in it.
- */
-void
-ddi_init(void)
-{
-       struct ddi_proto *pro;
-
-       PRINTK (("DDI: Starting up!\n"));
-
-       /* Kick all configured protocols. */
-       pro = protocols;
-       while (pro->name != NULL) 
-       {
-               (*pro->init)(pro);
-               pro++;
-       }
-       /* We're all done... */
-}
index eb7c7bf0cbade7b15a5dcf0dc7b3f6faedf65fed..d680abcada429ee4c1250eb6b23eb33027ae22e6 100644 (file)
@@ -2030,9 +2030,9 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb,
        rt=ip_rt_route(saddr, NULL,NULL);
        
        if(rt!=NULL && (rt->rt_flags&RTF_WINDOW))
-               sk->window_clamp=rt->rt_window;
+               newsk->window_clamp = rt->rt_window;
        else
-               sk->window_clamp=0;
+               newsk->window_clamp = 0;
                
        if (sk->user_mss)
                newsk->mtu = sk->user_mss;