diff -u --recursive v1.1.33/linux/Makefile linux/Makefile --- v1.1.33/linux/Makefile Fri Jul 22 16:40:59 1994 +++ linux/Makefile Fri Jul 22 16:11:08 1994 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 1 -SUBLEVEL = 33 +SUBLEVEL = 34 all: Version zImage @@ -79,9 +79,21 @@ AS86 =as86 -0 -a LD86 =ld86 -0 +# +# Set these to indicate how to link it.. +# +# -zmagic: +# +#LOWLDFLAGS = -Ttext 0x1000 +#HIGHLDFLAGS = -Ttext 0x100000 +# +# -qmagic (we need to remove the 32 byte header for bootup purposes) +# +LOWLDFLAGS =-qmagic -Ttext 0xfe0 +HIGHLDFLAGS =-qmagic -Ttext 0xfffe0 + AS =as LD =ld -LDFLAGS =#-qmagic HOSTCC =gcc CC =gcc -D__KERNEL__ -I$(TOPDIR)/include MAKE =make @@ -156,7 +168,7 @@ $(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $< tools/system: boot/head.o init/main.o tools/version.o linuxsubdirs - $(LD) $(LDFLAGS) -Ttext 1000 boot/head.o init/main.o tools/version.o \ + $(LD) $(LOWLDFLAGS) boot/head.o init/main.o tools/version.o \ $(ARCHIVES) \ $(FILESYSTEMS) \ $(DRIVERS) \ @@ -201,7 +213,7 @@ if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi tools/zSystem: boot/head.o init/main.o tools/version.o linuxsubdirs - $(LD) $(LDFLAGS) -Ttext 100000 boot/head.o init/main.o tools/version.o \ + $(LD) $(HIGHLDFLAGS) boot/head.o init/main.o tools/version.o \ $(ARCHIVES) \ $(FILESYSTEMS) \ $(DRIVERS) \ diff -u --recursive v1.1.33/linux/boot/setup.S linux/boot/setup.S --- v1.1.33/linux/boot/setup.S Thu Jul 7 21:37:11 1994 +++ linux/boot/setup.S Fri Jul 22 11:57:54 1994 @@ -14,8 +14,8 @@ ! Move PS/2 aux init code to psaux.c ! (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92 ! -! some changes and additional features by Christoph Niemann, March 1993 -! (niemann@rubdv15.ETDV.Ruhr-Uni-Bochum.De) +! some changes and additional features by Christoph Niemann, +! March 1993/June 1994 (Christoph.Niemann@linux.org) ! ! NOTE! These had better be the same as in bootsect.s! @@ -97,9 +97,11 @@ mov ds,ax lds si,[4*0x41] mov ax,#INITSEG + push ax mov es,ax mov di,#0x0080 mov cx,#0x10 + push cx cld rep movsb @@ -109,11 +111,9 @@ xor ax,ax ! clear ax mov ds,ax lds si,[4*0x46] - mov ax,#INITSEG - mov es,ax + pop cx + pop es mov di,#0x0090 - mov cx,#0x10 - cld rep movsb @@ -159,7 +159,7 @@ cld ! 'direction'=0, movs moves forward do_move: mov es,ax ! destination segment - add ax,#0x100 + inc ah ! instead of add ax,#0x100 cmp ax,#0x9000 jz end_move mov ds,bx ! source segment @@ -246,7 +246,8 @@ ! Note that the short jump isn't strictly needed, althought there are ! reasons why it might be a good idea. It won't hurt in any case. ! - mov ax,#0x0001 ! protected mode (PE) bit + xor ax,ax + inc ax ! protected mode (PE) bit lmsw ax ! This is it! jmp flush_instr flush_instr: @@ -394,33 +395,89 @@ mov ax,#0x501c ! return 80x28 ret /* svga modes */ +! +! test for presence of an S3 VGA chip. The algorithm was taken +! from the SuperProbe package of XFree86 1.2.1 +! report bugs to Christoph.Niemann@linux.org +! svga: cld - lea si,id9GXE ! Check for the #9GXE (jyanowit@orixa.mtholyoke.edu,thanks dlm40629@uxa.cso.uiuc.edu) - mov di,#0x49 ! id string is at c000:049 - mov cx,#0x11 ! length of "Graphics Power By" - repe - cmpsb - jne of1280 -is9GXE: lea si,dsc9GXE ! table of descriptions of video modes for BIOS - lea di,mo9GXE ! table of sizes of video modes for my BIOS + mov cx,#0x0f35 ! we store some constants in cl/ch + mov dx,#0x03d4 + movb al,#0x38 + call inidx + mov bh,al ! store current value of CRT-register 0x38 + mov ax,#0x0038 + call outidx ! disable writing to special regs + movb al,cl ! check wether we can write special reg 0x35 + call inidx + movb bl,al ! save the current value of CRT reg 0x35 + andb al,#0xf0 ! clear bits 0-3 + movb ah,al + movb al,cl ! and write it to CRT reg 0x35 + call outidx + call inidx ! now read it back + andb al,ch ! clear the upper 4 bits + jz s3_2 ! the first test failed. But we have a + movb ah,bl ! second chance + mov al,cl + call outidx + jmp s3_1 ! do the other tests +s3_2: mov ax,cx ! load ah with 0xf and al with 0x35 + orb ah,bl ! set the upper 4 bits of ah with the orig value + call outidx ! write ... + call inidx ! ... and reread + andb al,cl ! turn off the upper 4 bits + push ax + movb ah,bl ! restore old value in register 0x35 + movb al,cl + call outidx + pop ax + cmp al,ch ! setting lower 4 bits was successful => bad + je no_s3 ! writing is allowed => this is not an S3 +s3_1: mov ax,#0x4838 ! allow writing to special regs by putting + call outidx ! magic number into CRT-register 0x38 + movb al,cl ! check wether we can write special reg 0x35 + call inidx + movb bl,al + andb al,#0xf0 + movb ah,al + movb al,cl + call outidx + call inidx + andb al,ch + jnz no_s3 ! no, we can't write => no S3 + mov ax,cx + orb ah,bl + call outidx + call inidx + andb al,ch + push ax + movb ah,bl ! restore old value in register 0x35 + movb al,cl + call outidx + pop ax + cmp al,ch + jne no_s31 ! writing not possible => no S3 + movb al,#0x30 + call inidx ! now get the S3 id ... + lea di,idS3 + mov cx,#0x10 + repne + scasb + je no_s31 + lea si,dsc_S3 ! table of descriptions of video modes for BIOS + lea di,mo_S3 ! table of sizes of video modes for my BIOS + movb ah,bh + movb al,#0x38 + call outidx ! restore old value of CRT register 0x38 br selmod ! go ask for video mode -of1280: cld - lea si,idf1280 ! Check for Orchid F1280 (dingbat@diku.dk) - mov di,#0x10a ! id string is at c000:010a - mov cx,#0x21 ! length - repe - cmpsb - jne nf1280 -isVRAM: lea si,dscf1280 - lea di,mof1280 - br selmod -nf1280: lea si,idVRAM - mov di,#0x10a - mov cx,#0x0c - repe - cmpsb - je isVRAM - cld +no_s3: movb al,#0x35 ! restore CRT register 0x35 + movb ah,bl + call outidx +no_s31: movb ah,bh + movb al,#0x38 + call outidx ! restore old value of CRT register 0x38 + lea si,idati ! Check ATI 'clues' mov di,#0x31 mov cx,#0x09 @@ -710,6 +767,29 @@ pop ds ret +! Routine to write al into a VGA-register that is +! accessed via an index register +! +! dx contains the address of the index register +! al contains the index +! ah contains the value to write to the data register (dx + 1) +! +! no registers are changed + +outidx: out dx,al + push ax + mov al,ah + inc dx + out dx,al + dec dx + pop ax + ret +inidx: out dx,al + inc dx + in al,dx + dec dx + ret + ! Routine to print asciiz-string at DS:SI prtstr: lodsb @@ -817,9 +897,8 @@ idgenoa: .byte 0x77, 0x00, 0x99, 0x66 idparadise: .ascii "VGA=" idoakvga: .ascii "OAK VGA " -idf1280: .ascii "Orchid Technology Fahrenheit 1280" -id9GXE: .ascii "Graphics Power By" -idVRAM: .ascii "Stealth VRAM" +idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95 + .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0 ! Manufacturer: Numofmodes+2: Mode: ! Number of modes is the number of chip-specific svga modes plus the extended @@ -836,8 +915,7 @@ motseng: .byte 0x07, 0x26, 0x2a, 0x23, 0x24, 0x22 movideo7: .byte 0x08, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45 mooakvga: .byte 0x08, 0x00, 0x07, 0x4e, 0x4f, 0x50, 0x51 -mo9GXE: .byte 0x04, 0x54, 0x55 -mof1280: .byte 0x04, 0x54, 0x55 +mo_S3: .byte 0x04, 0x54, 0x55 mounknown: .byte 0x02 ! msb = Cols lsb = Rows: @@ -855,8 +933,7 @@ dsctseng: .word 0x5032, 0x501c, 0x503c, 0x6428, 0x8419, 0x841c, 0x842c dscvideo7: .word 0x5032, 0x501c, 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c dscoakvga: .word 0x5032, 0x501c, 0x2819, 0x5019, 0x503c, 0x843c, 0x8419, 0x842b -dscf1280: .word 0x5032, 0x501c, 0x842b, 0x8419 -dsc9GXE: .word 0x5032, 0x501c, 0x842b, 0x8419 +dsc_S3: .word 0x5032, 0x501c, 0x842b, 0x8419 dsunknown: .word 0x5032, 0x501c modesave: .word SVGA_MODE diff -u --recursive v1.1.33/linux/drivers/block/sbpcd.c linux/drivers/block/sbpcd.c --- v1.1.33/linux/drivers/block/sbpcd.c Fri Jul 22 16:41:00 1994 +++ linux/drivers/block/sbpcd.c Sat Jul 23 00:42:50 1994 @@ -5,7 +5,7 @@ * and for "no-sound" interfaces like Lasermate and the * Panasonic CI-101P. * - * NOTE: This is release 2.3. + * NOTE: This is release 2.4. * 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. @@ -117,6 +117,9 @@ * 2.3 Let "door lock" and "eject" live together. * Implemented "close tray" (done automatically during open). * + * 2.4 Use different names for device registering. + * + * * TODO * * disk change detection @@ -192,7 +195,7 @@ #include "blk.h" -#define VERSION "2.3 Eberhard Moenkeberg " +#define VERSION "2.4 Eberhard Moenkeberg " #define SBPCD_DEBUG @@ -397,6 +400,18 @@ static char *str_lm = "LaserMate"; static char *str_sp = "SPEA"; char *type; +#if !(SBPCD_ISSUE-1) +static char *major_name="sbpcd"; +#endif +#if !(SBPCD_ISSUE-2) +static char *major_name="sbpcd2"; +#endif +#if !(SBPCD_ISSUE-3) +static char *major_name="sbpcd3"; +#endif +#if !(SBPCD_ISSUE-4) +static char *major_name="sbpcd4"; +#endif /*==========================================================================*/ @@ -2840,7 +2855,6 @@ /*==========================================================================*/ /* * Take care of the different block sizes between cdrom and Linux. - * When Linux gets variable block sizes this will probably go away. */ static void sbp_transfer(void) { @@ -3551,7 +3565,7 @@ OUT(MIXER_data,0xCC); /* one nibble per channel */ } - if (register_blkdev(MAJOR_NR, "sbpcd", &sbpcd_fops) != 0) + if (register_blkdev(MAJOR_NR, major_name, &sbpcd_fops) != 0) { printk("SBPCD: Can't get MAJOR %d for Matsushita CDROM\n", MAJOR_NR); #if PRINTK_BUG diff -u --recursive v1.1.33/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v1.1.33/linux/drivers/net/Makefile Mon Jul 18 14:48:29 1994 +++ linux/drivers/net/Makefile Fri Jul 22 11:29:18 1994 @@ -21,7 +21,7 @@ net_init.o: ../../include/linux/autoconf.h ifdef CONFIG_SK_G16 -NETDRV_OBJS := $(NETDRV_OBJS) net.a(sk_g16.o) +NETDRV_OBJS := $(NETDRV_OBJS) sk_g16.o endif ifdef CONFIG_WD80x3 @@ -53,7 +53,7 @@ endif ifdef CONFIG_HPLAN_PLUS -NETDRV_OBJS := $(NETDRV_OBJS) net.a(hp-plus.o) +NETDRV_OBJS := $(NETDRV_OBJS) hp-plus.o CONFIG_8390 = CONFIG_8390 endif @@ -104,7 +104,7 @@ $(CC) $(CPPFLAGS) $(CFLAGS) $(DE600_OPTS) -c $< ifdef CONFIG_DE620 -NETDRV_OBJS := $(NETDRV_OBJS) net.a(de620.o) +NETDRV_OBJS := $(NETDRV_OBJS) de620.o endif de620.o: de620.c CONFIG $(CC) $(CPPFLAGS) $(CFLAGS) $(DE620_OPTS) -c $< @@ -155,7 +155,7 @@ CONFIG_8390 = CONFIG_8390 endif ifdef CONFIG_APRICOT -NETDRV_OBJS := $(NETDRV_OBJS) net.a(apricot.o) +NETDRV_OBJS := $(NETDRV_OBJS) apricot.o endif ifdef CONFIG_8390 diff -u --recursive v1.1.33/linux/drivers/net/e2100.c linux/drivers/net/e2100.c --- v1.1.33/linux/drivers/net/e2100.c Mon Jun 27 16:47:00 1994 +++ linux/drivers/net/e2100.c Fri Jul 22 11:32:04 1994 @@ -1,23 +1,25 @@ /* e2100.c: A Cabletron E2100 series ethernet driver for linux. */ /* - Written 1993 by Donald Becker. - Copyright 1993 United States Government as represented by the - Director, National Security Agency. This software may be used and - distributed according to the terms of the GNU Public License, - incorporated herein by reference. + Written 1993-1994 by Donald Becker. - This is a driver for the Cabletron E2100 series ethercards. + Copyright 1994 by Donald Becker. + Copyright 1993 United States Government as represented by the + Director, National Security Agency. This software may be used and + distributed according to the terms of the GNU Public License, + incorporated herein by reference. - The Author may be reached as becker@cesdis.gsfc.nasa.gov, or - C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715 + This is a driver for the Cabletron E2100 series ethercards. + The Author may be reached as becker@cesdis.gsfc.nasa.gov, or + C/O Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 + The E2100 series ethercard is a fairly generic shared memory 8390 implementation. The only unusual aspect is the way the shared memory registers are set: first you do an inb() in what is normally the - station address region, and the low four bits of next outb() is used - as the write value for that register. Either someone wasn't too used - to dem bit en bites, or they were trying to obfusicate the programming - interface. + station address region, and the low three bits of next outb() *address* + is used as the write value for that register. Either someone wasn't + too used to dem bit en bites, or they were trying to obfusicate the + programming interface. There is an additional complication when setting the window on the packet buffer. You must first do a read into the packet buffer region with the @@ -30,7 +32,7 @@ */ static char *version = - "e2100.c:v0.01 11/21/93 Donald Becker (becker@super.org)\n"; + "e2100.c:v1.01 7/21/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; #include #include @@ -39,42 +41,29 @@ #include #include #include -#ifndef PRE_PL13 -#include /* Delete if your kernel doesn't have it. */ -#endif +#include #include #include "8390.h" -/* Compatibility definitions for earlier kernel versions. */ -#ifndef HAVE_PORTRESERVE -#define check_region(ioaddr, size) 0 -#define snarf_region(ioaddr, size); do ; while (0) -#endif -#ifndef HAVE_AUTOIRQ -/* From auto_irq.c, in ioport.h for later versions. */ -extern void autoirq_setup(int waittime); -extern int autoirq_report(int waittime); -/* The map from IRQ number (as passed to the interrupt handler) to - 'struct device'. */ -extern struct device *irq2dev_map[16]; -#endif +static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0}; /* Offsets from the base_addr. - Read from the ASIC register, and the low 3(?) bits of the next outb() address - is used to set the cooresponding register. */ -#define E21_NIC_OFFSET 0 /* Offset to the 8390 NIC. */ + Read from the ASIC register, and the low three bits of the next outb() + address is used to set the cooresponding register. */ +#define E21_NIC_OFFSET 0 /* Offset to the 8390 NIC. */ #define E21_ASIC 0x10 #define E21_MEM_ENABLE 0x10 #define E21_MEM_ON 0x05 /* Enable memory in 16 bit mode. */ #define E21_MEM_ON_8 0x07 /* Enable memory in 8 bit mode. */ #define E21_MEM_BASE 0x11 #define E21_IRQ_LOW 0x12 /* The low three bits of the IRQ number. */ -#define E21_IRQ_HIGH 0x14 /* The high IRQ bit, and ... */ +#define E21_IRQ_HIGH 0x14 /* The high IRQ bit and media select ... */ +#define E21_MEDIA 0x14 /* (alias). */ #define E21_ALT_IFPORT 0x02 /* Set to use the other (BNC,AUI) port. */ #define E21_BIG_MEM 0x04 /* Use a bigger (64K) buffer (we don't) */ -#define E21_SAPROM 0x10 /* Offset to station address data. */ -#define ETHERCARD_TOTAL_SIZE 0x20 +#define E21_SAPROM 0x10 /* Offset to station address data. */ +#define E21_IO_EXTENT 0x20 extern inline void mem_on(short port, volatile char *mem_base, unsigned char start_page ) @@ -96,10 +85,10 @@ is designed to have a 4K Tx region last. The windowing circuitry wraps the window at 0x2fff->0x0000 so that the packets at e.g. 0x2f00 in the RX ring appear contiguously in the window. */ -#define E21_RX_START_PG 0x00 /* First page of RX buffer */ -#define E21_RX_STOP_PG 0x30 /* Last page +1 of RX ring */ -#define E21_BIG_RX_STOP_PG 0xF0 /* Last page +1 of RX ring */ -#define E21_TX_START_PG E21_RX_STOP_PG /* First page of TX buffer */ +#define E21_RX_START_PG 0x00 /* First page of RX buffer */ +#define E21_RX_STOP_PG 0x30 /* Last page +1 of RX ring */ +#define E21_BIG_RX_STOP_PG 0xF0 /* Last page +1 of RX ring */ +#define E21_TX_START_PG E21_RX_STOP_PG /* First page of TX buffer */ int e2100_probe(struct device *dev); int e21_probe1(struct device *dev, int ioaddr); @@ -107,9 +96,9 @@ static int e21_open(struct device *dev); static void e21_reset_8390(struct device *dev); static int e21_block_input(struct device *dev, int count, - char *buf, int ring_offset); + char *buf, int ring_offset); static void e21_block_output(struct device *dev, int count, - const unsigned char *buf, const start_page); + const unsigned char *buf, const start_page); static int e21_close(struct device *dev); @@ -122,26 +111,22 @@ int e2100_probe(struct device *dev) { - int *port, ports[] = {0x300, 0x280, 0x380, 0x220, 0}; - short base_addr = dev->base_addr; + int *port; + int base_addr = dev->base_addr; - if (base_addr > 0x1ff) /* Check a single specified location. */ - return e21_probe1(dev, base_addr); - else if (base_addr > 0) /* Don't probe at all. */ - return ENXIO; - - for (port = &ports[0]; *port; port++) { - ushort ioaddr = *port; - - if (check_region(ioaddr, ETHERCARD_TOTAL_SIZE)) - continue; - if (inb(ioaddr + E21_SAPROM + 0) == 0x00 - && inb(ioaddr + E21_SAPROM + 1) == 0x00 - && inb(ioaddr + E21_SAPROM + 2) == 0x1d - && e21_probe1(dev, ioaddr) == 0) - return 0; - } - return -ENODEV; + if (base_addr > 0x1ff) /* Check a single specified location. */ + return e21_probe1(dev, base_addr); + else if (base_addr != 0) /* Don't probe at all. */ + return ENXIO; + + for (port = e21_probe_list; *port; port++) { + if (check_region(*port, E21_IO_EXTENT)) + continue; + if (e21_probe1(dev, *port) == 0) + return 0; + } + + return ENODEV; } int e21_probe1(struct device *dev, int ioaddr) @@ -149,29 +134,30 @@ int i, status; unsigned char *station_addr = dev->dev_addr; - /* We've already checked the station address prefix, now verify by making - certain that there is a 8390 at the expected location. */ + /* First check the station address for the Ctron prefix. */ + if (inb(ioaddr + E21_SAPROM + 0) != 0x00 + || inb(ioaddr + E21_SAPROM + 1) != 0x00 + || inb(ioaddr + E21_SAPROM + 2) != 0x1d) + return ENODEV; + + /* Verify by making certain that there is a 8390 at there. */ outb(E8390_NODMA + E8390_STOP, ioaddr); SLOW_DOWN_IO; status = inb(ioaddr); if (status != 0x21 && status != 0x23) - return -ENODEV; + return ENODEV; -#ifdef testing_only - printk("%s: E21xx at %#3x (PAXI backwards): ", dev->name, ioaddr); - for (i = 0; i < 16; i++) - printk(" %02X", inb(ioaddr + 0x1f - i)); - printk("\n"); -#endif + /* Grab the region so we can find a different board if IRQ select fails. */ + snarf_region(ioaddr, E21_IO_EXTENT); /* Read the station address PROM. */ for (i = 0; i < 6; i++) station_addr[i] = inb(ioaddr + E21_SAPROM + i); - /* Grab the region so we can find another board if needed . */ - snarf_region(ioaddr, ETHERCARD_TOTAL_SIZE); + inb(ioaddr + E21_MEDIA); /* Point to media selection. */ + outb(0, ioaddr + E21_ASIC); /* and disable the secondary interface. */ - printk("%s: E21xx at %#3x, ", dev->name, ioaddr); + printk("%s: E21** at %#3x,", dev->name, ioaddr); for (i = 0; i < 6; i++) printk(" %02X", station_addr[i]); @@ -182,15 +168,13 @@ dev->irq = irqlist[i]; break; } - } else if (dev->irq == 2) /* Fixup bogosity: IRQ2 is really IRQ9 */ + if (i >= 8) { + printk(" unable to get IRQ %d.\n", dev->irq); + return EAGAIN; + } + } else if (dev->irq == 2) /* Fixup luser bogosity: IRQ2 is really IRQ9 */ dev->irq = 9; - /* Snarf the interrupt now. */ - if (irqaction (dev->irq, &ei_sigaction)) { - printk (" unable to get IRQ %d.\n", dev->irq); - return -EBUSY; - } - /* The 8390 is at the base address. */ dev->base_addr = ioaddr; @@ -201,6 +185,7 @@ ei_status.tx_start_page = E21_TX_START_PG; ei_status.rx_start_page = E21_RX_START_PG; ei_status.stop_page = E21_RX_STOP_PG; + ei_status.saved_irq = dev->irq; /* Check the media port used. The port can be passed in on the low mem_end bits. */ @@ -208,10 +193,12 @@ dev->if_port = dev->mem_end & 7; else { dev->if_port = 0; - inb_p(ioaddr + E21_IRQ_HIGH); /* Select if_port detect. */ + inb(ioaddr + E21_MEDIA); /* Turn automatic media detection on. */ for(i = 0; i < 6; i++) - if (station_addr[i] != inb(ioaddr + E21_SAPROM)) + if (station_addr[i] != inb(ioaddr + E21_SAPROM + 8 + i)) { dev->if_port = 1; + break; + } } /* Never map in the E21 shared memory unless you are actively using it. @@ -227,9 +214,8 @@ dev->mem_end = dev->rmem_end = dev->mem_start + 2*1024; #endif - printk(" IRQ %d, %s interface, memory at %#x-%#x.\n", dev->irq, - dev->if_port ? "secondary" : "primary", dev->mem_start, - dev->mem_start + 2*1024 - 1); + printk(", IRQ %d, %s media, memory @ %#lx.\n", dev->irq, + dev->if_port ? "secondary" : "primary", dev->mem_start); if (ei_debug > 0) printk(version); @@ -247,16 +233,21 @@ static int e21_open(struct device *dev) { - short ioaddr = dev->base_addr; + short ioaddr = dev->base_addr; + + if (irqaction (dev->irq, &ei_sigaction)) { + return EBUSY; + } + irq2dev_map[dev->irq] = dev; /* Set the interrupt line and memory base on the hardware. */ - inb_p(ioaddr + E21_IRQ_LOW); - outb_p(0, ioaddr + E21_ASIC + (dev->irq & 7)); - inb_p(ioaddr + E21_IRQ_HIGH); /* High IRQ bit, and if_port. */ - outb_p(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0) + inb(ioaddr + E21_IRQ_LOW); + outb(0, ioaddr + E21_ASIC + (dev->irq & 7)); + inb(ioaddr + E21_IRQ_HIGH); /* High IRQ bit, and if_port. */ + outb(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0) + (dev->if_port ? E21_ALT_IFPORT : 0)); - inb_p(ioaddr + E21_MEM_BASE); - outb_p(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7)); + inb(ioaddr + E21_MEM_BASE); + outb(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7)); return ei_open(dev); } @@ -264,47 +255,47 @@ static void e21_reset_8390(struct device *dev) { - short ioaddr = dev->base_addr; + short ioaddr = dev->base_addr; - outb(0x01, ioaddr); - if (ei_debug > 1) printk("resetting the E2180x3 t=%d...", jiffies); - ei_status.txing = 0; + outb(0x01, ioaddr); + if (ei_debug > 1) printk("resetting the E2180x3 t=%ld...", jiffies); + ei_status.txing = 0; - /* Set up the ASIC registers, just in case something changed them. */ + /* Set up the ASIC registers, just in case something changed them. */ - if (ei_debug > 1) printk("reset done\n"); - return; + if (ei_debug > 1) printk("reset done\n"); + return; } -/* Block input and output are easy on shared memory ethercards. The E21xx makes - block_input() especially easy by wrapping the top ring buffer to the bottom - automatically. */ +/* Block input and output are easy on shared memory ethercards. + The E21xx makes block_input() especially easy by wrapping the top + ring buffer to the bottom automatically. */ static int e21_block_input(struct device *dev, int count, char *buf, int ring_offset) { - short ioaddr = dev->base_addr; + short ioaddr = dev->base_addr; char *shared_mem = (char *)dev->mem_start; int start_page = (ring_offset>>8); mem_on(ioaddr, shared_mem, start_page); - /* We'll always get a 4 byte header read first. */ - if (count == 4) - ((int*)buf)[0] = ((int*)shared_mem)[0]; - else - memcpy(buf, shared_mem + (ring_offset & 0xff), count); + /* We'll always get a 4 byte header read first. */ + if (count == 4) + ((int*)buf)[0] = ((int*)shared_mem)[0]; + else + memcpy(buf, shared_mem + (ring_offset & 0xff), count); - /* Turn off memory access: we would need to reprogram the window anyway. */ + /* Turn off memory access: we would need to reprogram the window anyway. */ mem_off(ioaddr); - return 0; + return 0; } static void e21_block_output(struct device *dev, int count, const unsigned char *buf, - int start_page) + int start_page) { - short ioaddr = dev->base_addr; + short ioaddr = dev->base_addr; volatile char *shared_mem = (char *)dev->mem_start; /* Set the shared memory window start by doing a read, with the low address @@ -319,18 +310,37 @@ static int e21_close(struct device *dev) { - short ioaddr = dev->base_addr; + short ioaddr = dev->base_addr; + + if (ei_debug > 1) + printk("%s: Shutting down ethercard.\n", dev->name); + + free_irq(dev->irq); + dev->irq = ei_status.saved_irq; + + /* Shut off the interrupt line and secondary interface. */ + inb(ioaddr + E21_IRQ_LOW); + outb(0, ioaddr + E21_ASIC); + inb(ioaddr + E21_IRQ_HIGH); /* High IRQ bit, and if_port. */ + outb(0, ioaddr + E21_ASIC); + + irq2dev_map[dev->irq] = NULL; - if (ei_debug > 1) - printk("%s: Shutting down ethercard.\n", dev->name); - NS8390_init(dev, 0); + NS8390_init(dev, 0); + /* Double-check that the memory has been turned off, because really + really bad things happen if it isn't. */ mem_off(ioaddr); - return 0; + return 0; } - +#ifdef HAVE_DEVLIST +struct netdev_entry e21_drv = +{"e21", e21_probe1, E21_IO_EXTENT, e21_probe_list}; +#endif + + /* * Local variables: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c e2100.c" diff -u --recursive v1.1.33/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v1.1.33/linux/drivers/net/plip.c Wed Jun 22 14:57:09 1994 +++ linux/drivers/net/plip.c Fri Jul 22 12:44:39 1994 @@ -941,8 +941,8 @@ static int plip_ioctl(struct device *dev, struct ifreq *rq) { - struct net_local *nl=(struct net_local *)dev->priv; - struct plipconf *pc=(struct plipconf *)rq->ifr_data; + struct net_local *nl = (struct net_local *) dev->priv; + struct plipconf *pc = (struct plipconf *) &rq->ifr_data; switch(pc->pcmd) { diff -u --recursive v1.1.33/linux/fs/buffer.c linux/fs/buffer.c --- v1.1.33/linux/fs/buffer.c Tue Jul 19 10:19:12 1994 +++ linux/fs/buffer.c Sat Jul 23 00:43:38 1994 @@ -1113,14 +1113,14 @@ * etc. This also allows us to optimize memory usage by sharing code pages * and filesystem buffers.. */ -unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, int share) +unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, int no_share) { struct buffer_head * bh[8]; unsigned long where; int i, j; - if (share) { - where = try_to_share_buffers(address,dev,b,size); + if (!no_share) { + where = try_to_share_buffers(address, dev, b, size); if (where) return where; } @@ -1132,14 +1132,14 @@ } read_buffers(bh,i); where = address; - for (i=0, j=0; jb_uptodate) - COPYBLK(size, (unsigned long) bh[i]->b_data,address); + COPYBLK(size, (unsigned long) bh[i]->b_data, where); brelse(bh[i]); } } - return where; + return address; } /* diff -u --recursive v1.1.33/linux/fs/nfs/mmap.c linux/fs/nfs/mmap.c --- v1.1.33/linux/fs/nfs/mmap.c Fri Jul 22 16:41:02 1994 +++ linux/fs/nfs/mmap.c Sat Jul 23 00:43:38 1994 @@ -27,7 +27,7 @@ * Fill in the supplied page for mmap */ static unsigned long nfs_file_mmap_nopage(struct vm_area_struct * area, - unsigned long address, unsigned long page, int error_code) + unsigned long address, unsigned long page, int no_share) { struct inode * inode = area->vm_inode; unsigned int clear; diff -u --recursive v1.1.33/linux/include/linux/fs.h linux/include/linux/fs.h --- v1.1.33/linux/include/linux/fs.h Tue Jul 19 10:19:14 1994 +++ linux/include/linux/fs.h Sat Jul 23 00:43:38 1994 @@ -444,7 +444,7 @@ extern void brelse(struct buffer_head * buf); extern void set_blocksize(dev_t dev, int size); extern struct buffer_head * bread(dev_t dev, int block, int size); -extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int share); +extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int no_share); extern struct buffer_head * breada(dev_t dev,int block, int size, unsigned int pos, unsigned int filesize); extern void put_super(dev_t dev); diff -u --recursive v1.1.33/linux/include/linux/mm.h linux/include/linux/mm.h --- v1.1.33/linux/include/linux/mm.h Fri Jul 22 16:41:02 1994 +++ linux/include/linux/mm.h Fri Jul 22 16:40:43 1994 @@ -228,9 +228,14 @@ /* swap cache stuff (in swap.c) */ extern unsigned long * swap_cache; -extern inline unsigned long in_swap_cache (unsigned long addr) +extern inline unsigned long in_swap_cache(unsigned long addr) { return swap_cache[addr >> PAGE_SHIFT]; +} + +extern inline void swap_cache_invalidate(unsigned long addr) +{ + swap_cache[addr >> PAGE_SHIFT] = 0; } #endif diff -u --recursive v1.1.33/linux/kernel/ptrace.c linux/kernel/ptrace.c --- v1.1.33/linux/kernel/ptrace.c Thu Jul 21 08:18:20 1994 +++ linux/kernel/ptrace.c Fri Jul 22 12:53:39 1994 @@ -157,7 +157,7 @@ struct vm_area_struct * vma; addr &= PAGE_MASK; - for (vma = current->mm->mmap ; ; vma = vma->vm_next) { + for (vma = tsk->mm->mmap ; ; vma = vma->vm_next) { if (!vma) return NULL; if (vma->vm_end > addr) diff -u --recursive v1.1.33/linux/mm/memory.c linux/mm/memory.c --- v1.1.33/linux/mm/memory.c Fri Jul 22 16:41:03 1994 +++ linux/mm/memory.c Sat Jul 23 00:43:38 1994 @@ -263,11 +263,17 @@ *new_page_table = swap_duplicate(pg); continue; } - if ((pg & (PAGE_RW | PAGE_COW)) == (PAGE_RW | PAGE_COW)) + if (pg > high_memory || (mem_map[MAP_NR(pg)] & MAP_PAGE_RESERVED)) { + *new_page_table = pg; + continue; + } + if (pg & PAGE_COW) pg &= ~PAGE_RW; + if (in_swap_cache(pg)) { + swap_cache_invalidate(pg); + pg |= PAGE_DIRTY; + } *new_page_table = pg; - if (mem_map[MAP_NR(pg)] & MAP_PAGE_RESERVED) - continue; *old_page_table = pg; mem_map[MAP_NR(pg)]++; } @@ -730,9 +736,6 @@ /* if it is private, it must be clean to be shared */ if ((from_area->vm_page_prot & PAGE_COW) && (from & PAGE_DIRTY)) return 0; -/* the swap caching doesn't really handle shared pages.. */ - if (in_swap_cache(from)) - return 0; /* is the page reasonable at all? */ if (from >= high_memory) return 0; @@ -748,14 +751,26 @@ return 0; /* do we copy? */ if (newpage) { + if (in_swap_cache(from)) { /* implies PAGE_DIRTY */ + if (from_area->vm_page_prot & PAGE_COW) + return 0; + } copy_page((from & PAGE_MASK), newpage); *(unsigned long *) to_page = newpage | to_area->vm_page_prot; return 1; } -/* just share them.. */ +/* do a final swap-cache test before sharing them.. */ + if (in_swap_cache(from)) { + if (from_area->vm_page_prot & PAGE_COW) + return 0; + from |= PAGE_DIRTY; + *(unsigned long *) from_page = from; + swap_cache_invalidate(from); + invalidate(); + } mem_map[MAP_NR(from)]++; /* fill in the 'to' field, checking for COW-stuff */ - to = (from & PAGE_MASK) | to_area->vm_page_prot; + to = (from & (PAGE_MASK | PAGE_DIRTY)) | to_area->vm_page_prot; if (to & PAGE_COW) to &= ~PAGE_RW; *(unsigned long *) to_page = to; @@ -764,7 +779,7 @@ return 1; if (!(from_area->vm_page_prot & PAGE_COW)) return 1; -/* ok, need to mark it read-only, so invalidate aany possible old TB entry */ +/* ok, need to mark it read-only, so invalidate any possible old TB entry */ from &= ~PAGE_RW; *(unsigned long *) from_page = from; invalidate(); @@ -923,13 +938,24 @@ } ++vma->vm_task->mm->maj_flt; ++vma->vm_task->mm->rss; - page = vma->vm_ops->nopage(vma, address, page, error_code); + prot = vma->vm_page_prot; + /* + * The fourth argument is "no_share", which tells the low-level code + * to copy, not share the page even if sharing is possible. It's + * essentially an early COW detection ("moo at 5 AM"). + */ + page = vma->vm_ops->nopage(vma, address, page, (error_code & PAGE_RW) && (prot & PAGE_COW)); if (share_page(vma, address, error_code, 0)) { free_page(page); return; } - prot = vma->vm_page_prot; - if ((prot & PAGE_COW) && mem_map[MAP_NR(page)] > 1) + /* + * This silly early PAGE_DIRTY setting removes a race + * due to the bad i386 page protection. + */ + if (error_code & PAGE_RW) { + prot |= PAGE_DIRTY; /* can't be COW-shared: see "no_share" above */ + } else if ((prot & PAGE_COW) && mem_map[MAP_NR(page)] > 1) prot &= ~PAGE_RW; if (put_page(vma->vm_task, page, address, prot)) return; @@ -1251,25 +1277,29 @@ } -/* This handles a generic mmap of a disk file */ +/* + * This handles a generic mmap of a disk file. + */ static unsigned long file_mmap_nopage(struct vm_area_struct * area, unsigned long address, - unsigned long page, int error_code) + unsigned long page, int no_share) { struct inode * inode = area->vm_inode; unsigned int block; int nr[8]; - int i, j; - int prot = area->vm_page_prot; + int i, *p; address &= PAGE_MASK; block = address - area->vm_start + area->vm_offset; block >>= inode->i_sb->s_blocksize_bits; - - for (i=0, j=0; i< PAGE_SIZE ; j++, block++, i += inode->i_sb->s_blocksize) - nr[j] = bmap(inode,block); - if (error_code & PAGE_RW) - prot |= PAGE_RW | PAGE_DIRTY; - return bread_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize, !(error_code & PAGE_RW)); + i = PAGE_SIZE >> inode->i_sb->s_blocksize_bits; + p = nr; + do { + *p = bmap(inode,block); + i--; + block++; + p++; + } while (i > 0); + return bread_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize, no_share); } struct vm_operations_struct file_mmap = { diff -u --recursive v1.1.33/linux/mm/swap.c linux/mm/swap.c --- v1.1.33/linux/mm/swap.c Fri Jul 22 16:41:04 1994 +++ linux/mm/swap.c Fri Jul 22 16:16:49 1994 @@ -344,21 +344,13 @@ } if ((entry = find_in_swap_cache(page))) { - *table_ptr |= PAGE_DIRTY; if (mem_map[MAP_NR(page)] != 1) { + *table_ptr |= PAGE_DIRTY; + printk("Aiee.. duplicated cached swap-cache entry\n"); return 0; } - if (!entry) { - if (!(entry = get_swap_page())) { - return 0; - } - *table_ptr = entry; - invalidate(); - write_swap_page(entry, (char *) (page & PAGE_MASK)); - } else { - *table_ptr = entry; - invalidate(); - } + *table_ptr = entry; + invalidate(); free_page(page & PAGE_MASK); return 1; } @@ -901,12 +893,14 @@ error = namei(specialfile,&swap_inode); if (error) goto bad_swap; + p->swap_file = swap_inode; error = -EBUSY; if (swap_inode->i_count != 1) goto bad_swap; error = -EINVAL; if (S_ISBLK(swap_inode->i_mode)) { p->swap_device = swap_inode->i_rdev; + p->swap_file = NULL; iput(swap_inode); error = -ENODEV; if (!p->swap_device) @@ -918,9 +912,7 @@ if (p->swap_device == swap_info[i].swap_device) goto bad_swap; } - } else if (S_ISREG(swap_inode->i_mode)) - p->swap_file = swap_inode; - else + } else if (!S_ISREG(swap_inode->i_mode)) goto bad_swap; p->swap_lockmap = (unsigned char *) get_free_page(GFP_USER); if (!p->swap_lockmap) { diff -u --recursive v1.1.33/linux/tools/build.c linux/tools/build.c --- v1.1.33/linux/tools/build.c Wed Dec 29 06:50:28 1993 +++ linux/tools/build.c Fri Jul 22 13:35:23 1994 @@ -32,8 +32,10 @@ #include #define MINIX_HEADER 32 -#define GCC_HEADER 1024 +#define N_MAGIC_OFFSET 1024 +static int GCC_HEADER = sizeof(struct exec); + #define SYS_SIZE DEF_SYSSIZE #define DEFAULT_MAJOR_ROOT 0 @@ -188,7 +190,10 @@ die("Unable to open 'system'"); if (read(id,buf,GCC_HEADER) != GCC_HEADER) die("Unable to read header of 'system'"); - if (N_MAGIC(*ex) != ZMAGIC) + if (N_MAGIC(*ex) == ZMAGIC) { + GCC_HEADER = N_MAGIC_OFFSET; + lseek(id, GCC_HEADER, SEEK_SET); + } else if (N_MAGIC(*ex) != QMAGIC) die("Non-GCC header of 'system'"); fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n", (ex->a_text+ex->a_data+ex->a_bss)/1024, diff -u --recursive v1.1.33/linux/zBoot/Makefile linux/zBoot/Makefile --- v1.1.33/linux/zBoot/Makefile Wed Mar 9 11:11:16 1994 +++ linux/zBoot/Makefile Fri Jul 22 12:49:28 1994 @@ -11,14 +11,14 @@ .c.s: $(CC) $(CFLAGS) -S -o $*.s $< .s.o: - $(AS) -c -o $*.o $< + $(AS) -o $*.o $< .c.o: $(CC) $(CFLAGS) -c -o $*.o $< all: zSystem zSystem: piggy.o $(zOBJECTS) - $(LD) $(LDFLAGS) -o zSystem -Ttext 1000 $(zOBJECTS) piggy.o + $(LD) $(LOWLDFLAGS) -o zSystem $(zOBJECTS) piggy.o head.o: head.s diff -u --recursive v1.1.33/linux/zBoot/xtract.c linux/zBoot/xtract.c --- v1.1.33/linux/zBoot/xtract.c Wed Dec 1 14:44:15 1993 +++ linux/zBoot/xtract.c Fri Jul 22 13:34:18 1994 @@ -18,8 +18,10 @@ #include #include -#define GCC_HEADER 1024 +#define N_MAGIC_OFFSET 1024 +static int GCC_HEADER = sizeof(struct exec); + #define STRINGIFY(x) #x void die(char * str) @@ -49,7 +51,10 @@ die("Unable to open 'system'"); if (read(id,buf,GCC_HEADER) != GCC_HEADER) die("Unable to read header of 'system'"); - if (N_MAGIC(*ex) != ZMAGIC) + if (N_MAGIC(*ex) == ZMAGIC) { + GCC_HEADER = N_MAGIC_OFFSET; + lseek(id, GCC_HEADER, SEEK_SET); + } else if (N_MAGIC(*ex) != QMAGIC) die("Non-GCC header of 'system'"); sz = N_SYMOFF(*ex) - GCC_HEADER + 4; /* +4 to get the same result than tools/build */