diff -u --recursive --new-file v1.3.76/linux/CREDITS linux/CREDITS --- v1.3.76/linux/CREDITS Wed Mar 20 10:59:52 1996 +++ linux/CREDITS Thu Mar 21 08:55:09 1996 @@ -1198,6 +1198,7 @@ E: greg@wind.rmcc.com D: Filesystem valid flag for MINIX filesystem. D: Minor kernel debugging. +D: Development and maintenance of sysklogd. D: Monitoring of development kernels for long-term stability. D: Early implementations of Linux in a commercial environment. S: Dr. Greg Wettstein, Ph.D. diff -u --recursive --new-file v1.3.76/linux/Documentation/svga.txt linux/Documentation/svga.txt --- v1.3.76/linux/Documentation/svga.txt Wed Mar 20 10:59:53 1996 +++ linux/Documentation/svga.txt Wed Mar 20 16:49:01 1996 @@ -1,4 +1,4 @@ - Video Mode Selection Support 2.4 + Video Mode Selection Support 2.5 (c) 1995, 1996 Martin Mares, -------------------------------------------------------------------------------- @@ -222,3 +222,4 @@ these changes. Unfortunately, screen contents retaining works only with some loaders now. Added a Tseng 132x60 mode. +2.5 (19-Mar-96) Fixed a VESA mode scanning bug introduced in 2.4. diff -u --recursive --new-file v1.3.76/linux/Makefile linux/Makefile --- v1.3.76/linux/Makefile Wed Mar 20 10:59:53 1996 +++ linux/Makefile Wed Mar 20 10:50:37 1996 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 3 -SUBLEVEL = 76 +SUBLEVEL = 77 ARCH = i386 diff -u --recursive --new-file v1.3.76/linux/arch/i386/boot/video.S linux/arch/i386/boot/video.S --- v1.3.76/linux/arch/i386/boot/video.S Wed Mar 20 10:59:53 1996 +++ linux/arch/i386/boot/video.S Wed Mar 20 16:49:01 1996 @@ -1,5 +1,5 @@ ! -! Display adapter & video mode setup, version 2.4 (18-Mar-96) +! Display adapter & video mode setup, version 2.5 (19-Mar-96) ! ! Copyright (C) 1995, 1996 Martin Mares ! Based on the original setup.S code (C) Linus Torvalds @@ -753,13 +753,13 @@ mov di,bp cmp ax,#0x004f ! Successful? jnz ret0 - cmp (di+0x400),#0x4556 + cmp (di+0x200),#0x4556 jnz ret0 - cmp (di+0x402),#0x4153 + cmp (di+0x202),#0x4153 jnz ret0 mov [card_name],#vesa_name ! Set name to "VESA VGA" push gs - lgs si,(di+0x40e) ! GS:SI=mode list + lgs si,(di+0x20e) ! GS:SI=mode list mov cx,#128 ! Iteration limit vesa1: seg gs ! Get next mode in the list lodsw diff -u --recursive --new-file v1.3.76/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- v1.3.76/linux/arch/i386/kernel/setup.c Wed Mar 20 10:59:54 1996 +++ linux/arch/i386/kernel/setup.c Thu Mar 21 16:37:30 1996 @@ -232,8 +232,10 @@ switch (x86) { case 4: p = i486model(model); + break; case 5: p = i586model(model); + break; } if (p) return p; @@ -255,7 +257,9 @@ #ifdef __SMP__ int n; -#define CD(X) (cpu_data[n].(X)) +#define CD(X) (cpu_data[n].X) +/* SMP has the wrong name for loops_per_sec */ +#define loops_per_sec udelay_val #define CPUN n for ( n = 0 ; n < 32 ; n++ ) { diff -u --recursive --new-file v1.3.76/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c --- v1.3.76/linux/drivers/cdrom/cdu31a.c Sat Mar 2 10:43:22 1996 +++ linux/drivers/cdrom/cdu31a.c Wed Mar 20 08:16:16 1996 @@ -3168,6 +3168,10 @@ printk("Can't unregister cdu31a\n"); return; } + + if (cdu31a_irq > 0) + free_irq(cdu31a_irq, NULL); + release_region(cdu31a_port,4); printk("cdu31a module released.\n"); } diff -u --recursive --new-file v1.3.76/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c --- v1.3.76/linux/drivers/cdrom/mcd.c Tue Mar 5 10:10:54 1996 +++ linux/drivers/cdrom/mcd.c Thu Mar 21 08:55:44 1996 @@ -60,6 +60,7 @@ 17 June 95 Modifications By Andrew J. Kroll 07 July 1995 Modifications by Andrew J. Kroll + Bjorn Ekwall added unregister_blkdev to mcd_init() */ #include @@ -1181,6 +1182,7 @@ } if (check_region(mcd_port, 4)) { + unregister_blkdev(MAJOR_NR, "mcd"); printk("Init failed, I/O port (%X) already in use\n", mcd_port); return -EIO; @@ -1204,6 +1206,7 @@ if (count >= 2000000) { printk("Init failed. No mcd device at 0x%x irq %d\n", mcd_port, mcd_irq); + unregister_blkdev(MAJOR_NR, "mcd"); return -EIO; } count = inb(MCDPORT(0)); /* pick up the status */ @@ -1211,13 +1214,16 @@ outb(MCMD_GET_VERSION,MCDPORT(0)); for(count=0;count<3;count++) if(getValue(result+count)) { + unregister_blkdev(MAJOR_NR, "mcd"); printk("mitsumi get version failed at 0x%d\n", mcd_port); return -EIO; } - if (result[0] == result[1] && result[1] == result[2]) + if (result[0] == result[1] && result[1] == result[2]) { + unregister_blkdev(MAJOR_NR, "mcd"); return -EIO; + } printk("Mitsumi status, type and version : %02X %c %x ", result[0],result[1],result[2]); @@ -1239,6 +1245,7 @@ if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL)) { printk("Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq); + unregister_blkdev(MAJOR_NR, "mcd"); return -EIO; } request_region(mcd_port, 4,"mcd"); diff -u --recursive --new-file v1.3.76/linux/drivers/char/console.c linux/drivers/char/console.c --- v1.3.76/linux/drivers/char/console.c Sun Mar 17 09:04:06 1996 +++ linux/drivers/char/console.c Wed Mar 20 11:39:51 1996 @@ -1383,8 +1383,10 @@ disable_bh(CONSOLE_BH); while (!tty->stopped && count) { + enable_bh(CONSOLE_BH); c = from_user ? get_user(buf) : *buf; buf++; n++; count--; + disable_bh(CONSOLE_BH); if (utf) { /* Combine UTF-8 into Unicode */ diff -u --recursive --new-file v1.3.76/linux/drivers/char/ftape/Makefile linux/drivers/char/ftape/Makefile --- v1.3.76/linux/drivers/char/ftape/Makefile Fri Mar 15 16:03:11 1996 +++ linux/drivers/char/ftape/Makefile Thu Mar 21 08:55:09 1996 @@ -30,7 +30,7 @@ # FDC_82078SL - If you have a 82078SL, define this. FTAPE_OPT = -DVERIFY_HEADERS -DNR_BUFFERS=3 -DCLK_48MHZ=1 \ - -DFDC_82078SL -DNO_TRACE + -DNO_TRACE # If you're using a non-standard floppy disk controller for the # tape drive, enable one (only!) of the following lines and set diff -u --recursive --new-file v1.3.76/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v1.3.76/linux/drivers/char/lp.c Fri Mar 15 16:03:14 1996 +++ linux/drivers/char/lp.c Wed Mar 20 10:50:02 1996 @@ -602,6 +602,7 @@ { int offset = 0; int count = 0; + int failed = 0; if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) { printk("lp: unable to get major %d\n", LP_MAJOR); @@ -623,13 +624,25 @@ if (specified) { if (lp_probe(offset) <= 0) { printk(KERN_INFO "lp%d: Not found\n", offset); - return -EIO; + failed++; } else count++; } } + /* Successful specified devices increase count + * Unsuccessful specified devices increase failed + */ if (count) return 0; + if (failed) { + printk(KERN_INFO "lp: No override devices found.\n"); + unregister_chrdev(LP_MAJOR,"lp"); + return -EIO; + } + /* Only get here if there were no specified devices. To continue + * would be silly since the above code has scribbled all over the + * probe list. + */ #endif /* take on all known port values */ for (offset = 0; offset < LP_NO; offset++) { diff -u --recursive --new-file v1.3.76/linux/drivers/scsi/NCR5380.c linux/drivers/scsi/NCR5380.c --- v1.3.76/linux/drivers/scsi/NCR5380.c Sat Mar 2 10:43:36 1996 +++ linux/drivers/scsi/NCR5380.c Wed Mar 20 10:50:02 1996 @@ -809,6 +809,17 @@ hostdata->connected = NULL; hostdata->issue_queue = NULL; hostdata->disconnected_queue = NULL; +#ifdef NCR5380_STATS + for (i = 0; i < 8; ++i) { + hostdata->time_read[i] = 0; + hostdata->time_write[i] = 0; + hostdata->bytes_read[i] = 0; + hostdata->bytes_write[i] = 0; + } + hostdata->timebase = 0; + hostdata->pendingw = 0; + hostdata->pendingr = 0; +#endif /* The CHECK code seems to break the 53C400. Will check it later maybe */ if (flags & FLAG_NCR53C400) @@ -916,6 +927,7 @@ #if (NDEBUG & NDEBUG_NO_WRITE) switch (cmd->cmnd[0]) { case WRITE: + case WRITE_6: case WRITE_10: printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n", instance->host_no); @@ -925,6 +937,34 @@ } #endif /* (NDEBUG & NDEBUG_NO_WRITE) */ +#ifdef NCR5380_STATS +# if 0 + if (!hostdata->connected && !hostdata->issue_queue && + !hostdata->disconnected_queue) { + hostdata->timebase = jiffies; + } +# endif +# ifdef NCR5380_STAT_LIMIT + if (cmd->request_bufflen > NCR5380_STAT_LIMIT) +# endif + switch (cmd->cmnd[0]) + { + case WRITE: + case WRITE_6: + case WRITE_10: + hostdata->time_write[cmd->target] -= (jiffies - hostdata->timebase); + hostdata->bytes_write[cmd->target] += cmd->request_bufflen; + hostdata->pendingw++; + break; + case READ: + case READ_6: + case READ_10: + hostdata->time_read[cmd->target] -= (jiffies - hostdata->timebase); + hostdata->bytes_read[cmd->target] += cmd->request_bufflen; + hostdata->pendingr++; + break; + } +#endif /* * We use the host_scribble field as a pointer to the next command @@ -1224,6 +1264,32 @@ } while (!done); } +#ifdef NCR5380_STATS +static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd) +{ +# ifdef NCR5380_STAT_LIMIT + if (cmd->request_bufflen > NCR5380_STAT_LIMIT) +# endif + switch (cmd->cmnd[0]) + { + case WRITE: + case WRITE_6: + case WRITE_10: + hostdata->time_write[cmd->target] += (jiffies - hostdata->timebase); + /*hostdata->bytes_write[cmd->target] += cmd->request_bufflen;*/ + hostdata->pendingw--; + break; + case READ: + case READ_6: + case READ_10: + hostdata->time_read[cmd->target] += (jiffies - hostdata->timebase); + /*hostdata->bytes_read[cmd->target] += cmd->request_bufflen;*/ + hostdata->pendingr--; + break; + } +} +#endif + /* * Function : int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, * int tag); @@ -1469,6 +1535,9 @@ return -1; } cmd->result = DID_BAD_TARGET << 16; +#ifdef NCR5380_STATS + collect_stats(hostdata, cmd); +#endif cmd->scsi_done(cmd); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); #if (NDEBUG & NDEBUG_SELECTION) @@ -2322,6 +2391,9 @@ printk("scsi%d : target %d lun %d linked request done, calling scsi_done().\n", instance->host_no, cmd->target, cmd->lun); #endif +#ifdef NCR5380_STATS + collect_stats(hostdata, cmd); +#endif cmd->scsi_done(cmd); cmd = hostdata->connected; break; @@ -2387,9 +2459,13 @@ #if (NDEBUG & NDEBUG_QUEUES) printk("scsi%d : REQUEST SENSE added to head of issue queue\n",instance->host_no); #endif - } else + } else { #endif /* def AUTOSENSE */ +#ifdef NCR5380_STATS + collect_stats(hostdata, cmd); +#endif cmd->scsi_done(cmd); + } NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); /* @@ -2557,6 +2633,9 @@ hostdata->busy[cmd->target] &= ~(1 << cmd->lun); hostdata->connected = NULL; cmd->result = DID_ERROR << 16; +#ifdef NCR5380_STATS + collect_stats(hostdata, cmd); +#endif cmd->scsi_done(cmd); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); return; @@ -2841,7 +2920,7 @@ cli(); NCR5380_setup(instance); - + #if (NDEBUG & NDEBUG_ABORT) printk("scsi%d : abort called\n", instance->host_no); printk(" basr 0x%X, sr 0x%X\n", diff -u --recursive --new-file v1.3.76/linux/drivers/scsi/NCR5380.h linux/drivers/scsi/NCR5380.h --- v1.3.76/linux/drivers/scsi/NCR5380.h Sat Mar 2 10:43:36 1996 +++ linux/drivers/scsi/NCR5380.h Wed Mar 20 10:50:02 1996 @@ -265,6 +265,15 @@ unsigned long time_expires; /* in jiffies, set prior to sleeping */ struct Scsi_Host *next_timer; #endif +#ifdef NCR5380_STATS + unsigned timebase; /* Base for time calcs */ + long time_read[8]; /* time to do reads */ + long time_write[8]; /* time to do writes */ + unsigned long bytes_read[8]; /* bytes read */ + unsigned long bytes_write[8]; /* byytes written */ + unsigned pendingr; + unsigned pendingw; +#endif }; #ifdef __KERNEL__ diff -u --recursive --new-file v1.3.76/linux/drivers/scsi/README.g_NCR5380 linux/drivers/scsi/README.g_NCR5380 --- v1.3.76/linux/drivers/scsi/README.g_NCR5380 Wed Feb 7 15:11:27 1996 +++ linux/drivers/scsi/README.g_NCR5380 Wed Mar 20 10:50:02 1996 @@ -44,3 +44,49 @@ Kevin Lentin K.Lentin@cs.monash.edu.au +REAME file for the Linux g_NCR5380 driver. + +(c) 1993 Drew Eckhard +NCR53c400 extensions (c) 1994,1995,1996 Kevin Lentin + +This file documents the NCR53c400 extensions by Kevin Lentin and some +enhancements to the NCR5380 core. + +This driver supports both NCR5380 and NCR53c400 cards in port or memory +mapped modes. Currently this driver can only support one of those mapping +modes at a time but it does support both of these chips at the same time. +The next release of this driver will support port & memory mapped cards at +the same time. It should be able to handle multiple different cards in the +same machine. + +The drivers/scsi/Makefile has an override in it for the most common +NCR53c400 card, the Trantor T130B in its default configuration: + Port: 0x350 + IRQ : 5 + +The NCR53c400 does not support DMA but it does have Pseudo-DMA which is +supported by the driver. + +If the default configuration does not work for you, you can use the kernel +command lines (eg using the lilo append command): + ncr5380=port,irq,dma + ncr53c400=port,irq +or + ncr5380=base,irq,dma + ncr53c400=base,irq + +The driver does not probe for any addresses or ports other than those in +the OVERRIDE or given to the kernel as above. + +This driver provides some information on what it has detected in +/proc/scsi/g_NCR5380/x where x is the scsi card number as detected at boot +time. More info to come in the future. + +When NCR53c400 support is compiled in, BIOS paramaters will be returned by +the driver (the raw 5380 driver does not and I don't plan to fiddle with +it!). + +This driver works as a module. + +Kevin Lentin +K.Lentin@cs.monash.edu.au diff -u --recursive --new-file v1.3.76/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c --- v1.3.76/linux/drivers/scsi/g_NCR5380.c Sat Mar 2 10:43:40 1996 +++ linux/drivers/scsi/g_NCR5380.c Wed Mar 20 10:50:02 1996 @@ -65,6 +65,8 @@ #define NCR53C400_PSEUDO_DMA 1 #define PSEUDO_DMA #define NCR53C400 +#define NCR5380_STATS +#undef NCR5380_STAT_LIMIT #endif #if defined(CONFIG_SCSI_G_NCR5380_PORT) && defined(CONFIG_SCSI_G_NCR5380_MEM) #error You can not configure the Generic NCR 5380 SCSI Driver for memory mapped I/O and port mapped I/O at the same time (yet) @@ -238,8 +240,8 @@ return count; } -const char * generic_NCR5380_info (void) { - static const char string[]="Generic NCR5380/53C400 Info"; +const char * generic_NCR5380_info (struct Scsi_Host* host) { + static const char string[]="Generic NCR5380/53C400 Driver"; return string; } @@ -285,40 +287,6 @@ } #endif -int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout) -{ - int len = 0; - struct Scsi_Host *scsi_ptr; - - for (scsi_ptr = first_instance; scsi_ptr; scsi_ptr=scsi_ptr->next) - if (scsi_ptr->host_no == hostno) - break; - - len += sprintf(buffer+len, "SCSI host number %d : %s\n", scsi_ptr->host_no, scsi_ptr->hostt->name); - len += sprintf(buffer+len, "Generic NCR5380 driver version %d\n", GENERIC_NCR5380_PUBLIC_RELEASE); - len += sprintf(buffer+len, "NCR5380 driver core version %d\n", NCR5380_PUBLIC_RELEASE); -#ifdef NCR53C400 - len += sprintf(buffer+len, "NCR53C400 driver extension version %d\n", NCR53C400_PUBLIC_RELEASE); - len += sprintf(buffer+len, "NCR53C400 card%s detected\n", (((struct NCR5380_hostdata *)scsi_ptr->hostdata)->flags & FLAG_NCR53C400)?"":" not"); -# if NCR53C400_PSEUDO_DMA - len += sprintf(buffer+len, "NCR53C400 pseudo DMA being used\n"); -# endif -#else - len += sprintf(buffer+len, "NO NCR53C400 driver extensions\n"); -#endif - len += sprintf(buffer+len, "Using %s mapping at %s 0x%x, ", STRVAL(NCR5380_map_config), STRVAL(NCR5380_map_name), scsi_ptr->NCR5380_instance_name); - if (scsi_ptr->irq == IRQ_NONE) - len += sprintf(buffer+len, "interrupts disabled\n"); - else - len += sprintf(buffer+len, "on interrupt %d\n", scsi_ptr->irq); - - *start = buffer + offset; - len -= offset; - if (len > length) - len = length; - return len; -} - #if NCR53C400_PSEUDO_DMA static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst, int len) { @@ -564,6 +532,169 @@ #endif /* PSEUDO_DMA */ #include "NCR5380.c" + +#define PRINTP(x) len += sprintf(buffer+len, x) +#define ANDP , + +static int sprint_opcode(char* buffer, int len, int opcode) { + int start = len; + PRINTP("0x%02x " ANDP opcode); + return len-start; +} + +static int sprint_command (char* buffer, int len, unsigned char *command) { + int i,s,start=len; + len += sprint_opcode(buffer, len, command[0]); + for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) + PRINTP("%02x " ANDP command[i]); + PRINTP("\n"); + return len-start; +} + +static int sprint_Scsi_Cmnd (char* buffer, int len, Scsi_Cmnd *cmd) { + int start = len; + PRINTP("destination target %d, lun %d\n" ANDP + cmd->host->host_no ANDP + cmd->target ANDP + cmd->lun); + PRINTP(" command = "); + len += sprint_command (buffer, len, cmd->cmnd); + return len-start; +} + +const char *const scsi_device_types[] = +{ + "Direct-Access ", + "Sequential-Access", + "Printer ", + "Processor ", + "WORM ", + "CD-ROM ", + "Scanner ", + "Optical Device ", + "Medium Changer ", + "Communications " +}; +#define MAX_SCSI_DEVICE_CODE sizeof(scsi_device_types)/sizeof(char*) + +int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout) +{ + int len = 0; + NCR5380_local_declare(); + unsigned char status; + int i; + struct Scsi_Host *scsi_ptr; + Scsi_Device *dev; + Scsi_Cmnd *ptr; + struct NCR5380_hostdata *hostdata; + + cli(); + + for (scsi_ptr = first_instance; scsi_ptr; scsi_ptr=scsi_ptr->next) + if (scsi_ptr->host_no == hostno) + break; + NCR5380_setup(scsi_ptr); + hostdata = (struct NCR5380_hostdata *)scsi_ptr->hostdata; + + PRINTP("SCSI host number %d : %s\n" ANDP scsi_ptr->host_no ANDP scsi_ptr->hostt->name); + PRINTP("Generic NCR5380 driver version %d\n" ANDP GENERIC_NCR5380_PUBLIC_RELEASE); + PRINTP("NCR5380 core version %d\n" ANDP NCR5380_PUBLIC_RELEASE); +#ifdef NCR53C400 + PRINTP("NCR53C400 extension version %d\n" ANDP NCR53C400_PUBLIC_RELEASE); + PRINTP("NCR53C400 card%s detected\n" ANDP (((struct NCR5380_hostdata *)scsi_ptr->hostdata)->flags & FLAG_NCR53C400)?"":" not"); +# if NCR53C400_PSEUDO_DMA + PRINTP("NCR53C400 pseudo DMA used\n"); +# endif +#else + PRINTP("NO NCR53C400 driver extensions\n"); +#endif + PRINTP("Using %s mapping at %s 0x%x, " ANDP STRVAL(NCR5380_map_config) ANDP STRVAL(NCR5380_map_name) ANDP scsi_ptr->NCR5380_instance_name); + if (scsi_ptr->irq == IRQ_NONE) + PRINTP("no interrupt\n"); + else + PRINTP("on interrupt %d\n" ANDP scsi_ptr->irq); + +#ifdef NCR5380_STATS + if (hostdata->connected || hostdata->issue_queue || hostdata->disconnected_queue) + PRINTP("There are commands pending, transfer rates may be crud\n"); + if (hostdata->pendingr) + PRINTP(" %d pending reads" ANDP hostdata->pendingr); + if (hostdata->pendingw) + PRINTP(" %d pending writes" ANDP hostdata->pendingw); + if (hostdata->pendingr || hostdata->pendingw) + PRINTP("\n"); + for (dev = scsi_devices; dev; dev=dev->next) { + if (dev->host == scsi_ptr) { + unsigned long br = hostdata->bytes_read[dev->id]; + unsigned long bw = hostdata->bytes_write[dev->id]; + long tr = hostdata->time_read[dev->id] / HZ; + long tw = hostdata->time_write[dev->id] / HZ; + + PRINTP(" T:%d %s " ANDP dev->id ANDP (dev->type < MAX_SCSI_DEVICE_CODE) ? scsi_device_types[(int)dev->type] : "Unknown"); + for (i=0; i<8; i++) + if (dev->vendor[i] >= 0x20) + *(buffer+(len++)) = dev->vendor[i]; + *(buffer+(len++)) = ' '; + for (i=0; i<16; i++) + if (dev->model[i] >= 0x20) + *(buffer+(len++)) = dev->model[i]; + *(buffer+(len++)) = ' '; + for (i=0; i<4; i++) + if (dev->rev[i] >= 0x20) + *(buffer+(len++)) = dev->rev[i]; + *(buffer+(len++)) = ' '; + + PRINTP("\n%10d kb read in %5d secs" ANDP br/1024 ANDP tr); + if (tr) + PRINTP(" @ %5d bps" ANDP br / tr); + + PRINTP("\n%10d kb written in %5d secs" ANDP bw/1024 ANDP tw); + if (tw) + PRINTP(" @ %5d bps" ANDP bw / tw); + PRINTP("\n"); + } + } +#endif + + status = NCR5380_read(STATUS_REG); + if (!(status & SR_REQ)) + PRINTP("REQ not asserted, phase unknown.\n"); + else { + for (i = 0; (phases[i].value != PHASE_UNKNOWN) && + (phases[i].value != (status & PHASE_MASK)); ++i) + ; + PRINTP("Phase %s\n" ANDP phases[i].name); + } + + if (!hostdata->connected) { + PRINTP("No currently connected command\n"); + } else { + len += sprint_Scsi_Cmnd (buffer, len, (Scsi_Cmnd *) hostdata->connected); + } + + PRINTP("issue_queue\n"); + + for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; + ptr = (Scsi_Cmnd *) ptr->host_scribble) + len += sprint_Scsi_Cmnd (buffer, len, ptr); + + PRINTP("disconnected_queue\n"); + + for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; + ptr = (Scsi_Cmnd *) ptr->host_scribble) + len += sprint_Scsi_Cmnd (buffer, len, ptr); + + *start = buffer + offset; + len -= offset; + if (len > length) + len = length; + sti(); + return len; +} + +#undef PRINTP +#undef ANDP + #ifdef MODULE /* Eventually this will go into an include file, but this will be later */ Scsi_Host_Template driver_template = GENERIC_NCR5380; diff -u --recursive --new-file v1.3.76/linux/drivers/scsi/g_NCR5380.h linux/drivers/scsi/g_NCR5380.h --- v1.3.76/linux/drivers/scsi/g_NCR5380.h Wed Feb 7 15:11:28 1996 +++ linux/drivers/scsi/g_NCR5380.h Wed Mar 20 10:50:02 1996 @@ -47,6 +47,7 @@ int generic_NCR5380_release_resources(struct Scsi_Host *); int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int generic_NCR5380_reset(Scsi_Cmnd *); +const char* generic_NCR5380_info(struct Scsi_Host *); #ifdef BIOSPARAM int generic_NCR5380_biosparam(Disk *, kdev_t, int *); #endif diff -u --recursive --new-file v1.3.76/linux/drivers/sound/configure.c linux/drivers/sound/configure.c --- v1.3.76/linux/drivers/sound/configure.c Wed Mar 20 10:59:58 1996 +++ linux/drivers/sound/configure.c Wed Mar 20 08:27:42 1996 @@ -418,7 +418,6 @@ { for (i = 0; i < OPT_LAST; i++) - if (!(DISABLED_OPTIONS & B (i))) if (mask == B (i)) { unsigned int j; @@ -778,7 +777,7 @@ "Check from manual of the card"); ask_int_choice (B (OPT_SB), "SB_MPU_IRQ", - "SB MPU401 IRQ (Jazz16 and ES1688)", + "SB MPU401 IRQ (Jazz16, SM Wave and ES1688)", FMT_INT, -1, "Check from manual of the card"); diff -u --recursive --new-file v1.3.76/linux/fs/msdos/namei.c linux/fs/msdos/namei.c --- v1.3.76/linux/fs/msdos/namei.c Wed Mar 13 10:09:20 1996 +++ linux/fs/msdos/namei.c Thu Mar 21 18:08:30 1996 @@ -590,7 +590,6 @@ mark_buffer_dirty(old_bh, 1); /* update binary info for conversion, i_attrs */ if ((old_inode = iget(old_dir->i_sb,old_ino)) != NULL) { - msdos_read_inode(old_inode); MSDOS_I(old_inode)->i_attrs = is_hid ? (MSDOS_I(old_inode)->i_attrs | ATTR_HIDDEN) : (MSDOS_I(old_inode)->i_attrs &~ ATTR_HIDDEN); diff -u --recursive --new-file v1.3.76/linux/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c --- v1.3.76/linux/fs/nfs/nfsroot.c Wed Mar 20 10:59:59 1996 +++ linux/fs/nfs/nfsroot.c Thu Mar 21 08:56:46 1996 @@ -27,6 +27,9 @@ * Martin Mares : Code cleanup. * Martin Mares : (2.1) BOOTP and RARP made configuration options. * Martin Mares : Server hostname generation fixed. + * Gerd Knorr : Fixed wired inode handling + * Martin Mares : (2.2) "0.0.0.0" addresses from command line ignored. + * Martin Mares : RARP replies not tested for server address. * * * Known bugs and caveats: @@ -128,7 +131,7 @@ /* Yes, we use sys_socket, but there's no include file for it */ extern asmlinkage int sys_socket(int family, int type, int protocol); - + /*************************************************************************** @@ -302,12 +305,6 @@ kfree_skb(skb, FREE_READ); return 0; } - /* Discard packets which are not from specified server. */ - if (server.sin_addr.s_addr != INADDR_NONE && - server.sin_addr.s_addr != sip) { - kfree_skb(skb, FREE_READ); - return 0; - } /* * The packet is what we were looking for. Setup the global @@ -1170,7 +1167,7 @@ while (ip && *ip) { if ((cp = strchr(ip, ':'))) *cp++ = '\0'; - if (strlen(ip) > 0) { + if (strlen(ip) > 0 && strcmp(ip, "0.0.0.0")) { switch (num) { case 0: myaddr.sin_addr.s_addr = in_aton(ip); @@ -1361,8 +1358,8 @@ ***************************************************************************/ -static struct file nfs_file; /* File descriptor containing socket */ -static struct inode nfs_inode; /* Inode containing socket */ +static struct file *nfs_file; +static struct inode *nfs_sock_inode; /* Inode containing socket */ static int *rpc_packet = NULL; /* RPC packet */ @@ -1371,63 +1368,28 @@ */ static int root_nfs_open(void) { - struct file *filp; - /* Open the socket */ if ((nfs_data.fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { printk(KERN_ERR "Root-NFS: Cannot open UDP socket!\n"); return -1; } - /* - * Copy the file and inode data area so that we can remove the - * file lateron without killing the socket. After all this the - * closing routine just needs to remove the file pointer from the - * init-task descriptor. - */ - filp = current->files->fd[nfs_data.fd]; - memcpy(&nfs_file, filp, sizeof(struct file)); - nfs_file.f_next = nfs_file.f_prev = NULL; - current->files->fd[nfs_data.fd] = &nfs_file; - filp->f_count = 0; /* Free the file descriptor */ - - memcpy(&nfs_inode, nfs_file.f_inode, sizeof(struct inode)); - nfs_inode.i_hash_next = nfs_inode.i_hash_prev = NULL; - nfs_inode.i_next = nfs_inode.i_prev = NULL; - clear_inode(nfs_file.f_inode); - nfs_file.f_inode = &nfs_inode; - nfs_inode.u.socket_i.inode = &nfs_inode; - nfs_file.private_data = NULL; + nfs_file = current->files->fd[nfs_data.fd]; + nfs_sock_inode = nfs_file->f_inode; + /* keep socket open. Do we need really this ? */ + /* nfs_file->f_count++; */ return 0; } /* - * Close the UDP file descriptor. The main part of preserving the socket - * has already been done after opening it. Now we have to remove the file - * descriptor from the init task. + * Close the UDP file descriptor. If nfs_read_super is successful, it + * increases the reference count, so we can simply close the file, and + * the socket keeps open. */ static void root_nfs_close(int close_all) { - /* Remove the file from the list of open files */ - current->files->fd[nfs_data.fd] = NULL; - if (current->files->count > 0) - current->files->count--; - - /* Clear memory used by the RPC packet */ - if (rpc_packet != NULL) - kfree_s(rpc_packet, nfs_data.wsize + 1024); - - /* - * In case of an error we also have to close the socket again - * (sigh) - */ - if (close_all) { - nfs_inode.u.socket_i.inode = NULL; /* The inode is already - * cleared */ - if (nfs_file.f_op->release) - nfs_file.f_op->release(&nfs_inode, &nfs_file); - } + sys_close(nfs_data.fd); } @@ -1441,14 +1403,15 @@ struct sockaddr_in *sin = &myaddr; int i; - if (nfs_inode.u.socket_i.ops->bind) { + if (nfs_sock_inode->u.socket_i.ops->bind) { for (i = 0; i < NPORTS && res < 0; i++) { sin->sin_port = htons(port++); if (port > ENDPORT) { port = STARTPORT; } - res = nfs_inode.u.socket_i.ops->bind(&nfs_inode.u.socket_i, - (struct sockaddr *)sin, sizeof(struct sockaddr_in)); + res = nfs_sock_inode->u.socket_i.ops->bind + (&nfs_sock_inode->u.socket_i, + (struct sockaddr *)sin, sizeof(struct sockaddr_in)); } } if (res < 0) { @@ -1468,11 +1431,10 @@ */ static int *root_nfs_call(int *end) { - struct file *filp; struct socket *sock; int dummylen; static struct nfs_server s = { - &nfs_file, /* struct file * */ + 0, /* struct file * */ 0, /* struct rsock * */ { 0, "", @@ -1486,8 +1448,8 @@ 3 * HZ, 60 * HZ, 30 * HZ, 60 * HZ, "\0" }; - filp = &nfs_file; - sock = &((filp->f_inode)->u.socket_i); + s.file = nfs_file; + sock = &((nfs_file->f_inode)->u.socket_i); /* extract the other end of the socket into s->toaddr */ sock->ops->getname(sock, &(s.toaddr), &dummylen, 1); @@ -1495,7 +1457,7 @@ ((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family; ((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr; - s.rsock = rpc_makesock(filp); + s.rsock = rpc_makesock(nfs_file); s.flags = nfs_data.flags; s.rsize = nfs_data.rsize; s.wsize = nfs_data.wsize; @@ -1507,12 +1469,13 @@ * First connect the UDP socket to a server port, then send the * packet out, and finally check wether the answer is OK. */ - if (nfs_inode.u.socket_i.ops->connect && - nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i, - (struct sockaddr *) &server, - sizeof(struct sockaddr_in), - nfs_file.f_flags) < 0) - return NULL; + if (nfs_sock_inode->u.socket_i.ops->connect && + nfs_sock_inode->u.socket_i.ops->connect + (&nfs_sock_inode->u.socket_i, + (struct sockaddr *) &server, + sizeof(struct sockaddr_in), + nfs_file->f_flags) < 0) + return NULL; if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0) return NULL; return rpc_verify(rpc_packet); @@ -1643,11 +1606,12 @@ /* First connect to the nfsd port on the server */ server.sin_port = htons(nfs_port); nfs_data.addr = server; - if (nfs_inode.u.socket_i.ops->connect && - nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i, - (struct sockaddr *) &server, - sizeof(struct sockaddr_in), - nfs_file.f_flags) < 0) { + if (nfs_sock_inode->u.socket_i.ops->connect && + nfs_sock_inode->u.socket_i.ops->connect + (&nfs_sock_inode->u.socket_i, + (struct sockaddr *) &server, + sizeof(struct sockaddr_in), + nfs_file->f_flags) < 0) { root_nfs_close(1); return -1; } diff -u --recursive --new-file v1.3.76/linux/fs/proc/array.c linux/fs/proc/array.c --- v1.3.76/linux/fs/proc/array.c Wed Feb 28 11:50:10 1996 +++ linux/fs/proc/array.c Thu Mar 21 08:55:09 1996 @@ -194,6 +194,7 @@ { int i, len; unsigned sum = 0; + extern unsigned long total_forks; for (i = 0 ; i < NR_IRQS ; i++) sum += kstat.interrupts[i]; @@ -230,9 +231,11 @@ len += sprintf(buffer + len, " %u", kstat.interrupts[i]); len += sprintf(buffer + len, "\nctxt %u\n" - "btime %lu\n", + "btime %lu\n" + "processes %lu\n", kstat.context_swtch, - xtime.tv_sec - jiffies / HZ); + xtime.tv_sec - jiffies / HZ, + total_forks); return len; } diff -u --recursive --new-file v1.3.76/linux/include/asm-alpha/atomic.h linux/include/asm-alpha/atomic.h --- v1.3.76/linux/include/asm-alpha/atomic.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-alpha/atomic.h Wed Mar 20 15:00:13 1996 @@ -0,0 +1,53 @@ +#ifndef __ARCH_I386_ATOMIC__ +#define __ARCH_I386_ATOMIC__ + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +/* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, + * not some alias that contains the same information. + */ +#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) + +typedef int atomic_t; + +extern __inline__ void atomic_add(atomic_t i, atomic_t * v) +{ + unsigned long temp; + __asm__ __volatile__( + "\n1:\t" + "ldl_l %0,%1\n\t" + "addl %0,%2,%0\n\t" + "stl_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); +} + +extern __inline__ void atomic_sub(atomic_t i, atomic_t * v) +{ + unsigned long temp; + __asm__ __volatile__( + "\n1:\t" + "ldl_l %0,%1\n\t" + "subl %0,%2,%0\n\t" + "stl_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (__atomic_fool_gcc(v)) + :"Ir" (i), + "m" (__atomic_fool_gcc(v))); +} + +#define atomic_inc(v) atomic_add(1,(v)) +#define atomic_dec(v) atomic_sub(1,(v)) + +#endif diff -u --recursive --new-file v1.3.76/linux/include/asm-i386/atomic.h linux/include/asm-i386/atomic.h --- v1.3.76/linux/include/asm-i386/atomic.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-i386/atomic.h Wed Mar 20 14:38:42 1996 @@ -0,0 +1,56 @@ +#ifndef __ARCH_I386_ATOMIC__ +#define __ARCH_I386_ATOMIC__ + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +#ifdef __SMP__ +#define LOCK "lock ; " +#else +#define LOCK "" +#endif + +/* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, + * not some alias that contains the same information. + */ +#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) + +typedef int atomic_t; + +static __inline__ void atomic_add(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__( + LOCK "addl %1,%0" + :"=m" (__atomic_fool_gcc(v)) + :"ir" (i), "m" (__atomic_fool_gcc(v))); +} + +static __inline__ void atomic_sub(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__( + LOCK "subl %1,%0" + :"=m" (__atomic_fool_gcc(v)) + :"ir" (i), "m" (__atomic_fool_gcc(v))); +} + +static __inline__ void atomic_inc(atomic_t *v) +{ + __asm__ __volatile__( + LOCK "incl %0" + :"=m" (__atomic_fool_gcc(v)) + :"m" (__atomic_fool_gcc(v))); +} + +static __inline__ void atomic_dec(atomic_t *v) +{ + __asm__ __volatile__( + LOCK "decl %0" + :"=m" (__atomic_fool_gcc(v)) + :"m" (__atomic_fool_gcc(v))); +} + +#endif diff -u --recursive --new-file v1.3.76/linux/include/asm-i386/processor.h linux/include/asm-i386/processor.h --- v1.3.76/linux/include/asm-i386/processor.h Sun Dec 17 11:43:22 1995 +++ linux/include/asm-i386/processor.h Thu Mar 21 08:55:09 1996 @@ -9,7 +9,9 @@ /* * System setup and hardware bug flags.. + * [Note we don't test the 386 multiply bug or popad bug] */ + extern char hard_math; extern char x86; /* lower 4 bits */ extern char x86_vendor_id[13]; @@ -18,8 +20,9 @@ extern int x86_capability; /* field of flags */ extern int fdiv_bug; extern char ignore_irq13; -extern char wp_works_ok; /* doesn't work on a 386 */ +extern char wp_works_ok; /* doesn't work on a 386 */ extern char hlt_works_ok; /* problems on some 486Dx4's and old 386's */ +extern int have_cpuid; /* We have a CPUID */ /* * Bus types (default is ISA, but people can check others with these..) diff -u --recursive --new-file v1.3.76/linux/include/linux/netdevice.h linux/include/linux/netdevice.h --- v1.3.76/linux/include/linux/netdevice.h Tue Mar 5 10:11:13 1996 +++ linux/include/linux/netdevice.h Thu Mar 21 17:51:22 1996 @@ -232,7 +232,6 @@ #define HAVE_NETIF_RX 1 extern void netif_rx(struct sk_buff *skb); extern void dev_transmit(void); -extern int in_net_bh(void); extern void net_bh(void); extern void dev_tint(struct device *dev); extern int dev_get_info(char *buffer, char **start, off_t offset, int length, int dummy); diff -u --recursive --new-file v1.3.76/linux/include/net/sock.h linux/include/net/sock.h --- v1.3.76/linux/include/net/sock.h Wed Mar 20 11:00:00 1996 +++ linux/include/net/sock.h Thu Mar 21 17:51:22 1996 @@ -55,6 +55,8 @@ #include +#include + /* Think big (also on some systems a byte is faster) */ #define SOCK_ARRAY_SIZE 256 @@ -149,8 +151,8 @@ struct sock { struct options *opt; - volatile unsigned long wmem_alloc; - volatile unsigned long rmem_alloc; + atomic_t wmem_alloc; + atomic_t rmem_alloc; unsigned long allocation; /* Allocation mode */ __u32 write_seq; __u32 sent_seq; @@ -484,14 +486,10 @@ extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) { - unsigned long flags; - if(sk->rmem_alloc + skb->truesize >= sk->rcvbuf) + if (sk->rmem_alloc + skb->truesize >= sk->rcvbuf) return -ENOMEM; - save_flags(flags); - cli(); - sk->rmem_alloc+=skb->truesize; + atomic_add(skb->truesize, &sk->rmem_alloc); skb->sk=sk; - restore_flags(flags); skb_queue_tail(&sk->receive_queue,skb); if(!sk->dead) sk->data_ready(sk,skb->len); diff -u --recursive --new-file v1.3.76/linux/kernel/fork.c linux/kernel/fork.c --- v1.3.76/linux/kernel/fork.c Wed Mar 13 10:09:24 1996 +++ linux/kernel/fork.c Thu Mar 21 08:55:09 1996 @@ -28,6 +28,7 @@ int nr_tasks=1; int nr_running=1; +unsigned long int total_forks=0; /* Handle normal Linux uptimes. */ static inline int find_empty_process(void) { @@ -269,6 +270,7 @@ p->exit_signal = clone_flags & CSIGNAL; p->counter = current->counter >> 1; wake_up_process(p); /* do this last, just in case */ + ++total_forks; return p->pid; bad_fork_cleanup_sighand: diff -u --recursive --new-file v1.3.76/linux/kernel/sched.c linux/kernel/sched.c --- v1.3.76/linux/kernel/sched.c Wed Mar 20 11:00:00 1996 +++ linux/kernel/sched.c Thu Mar 21 08:44:50 1996 @@ -886,7 +886,7 @@ unsigned long it_virt = p->it_virt_value; if (it_virt) { - if (it_virt < ticks) { + if (it_virt <= ticks) { it_virt = ticks + p->it_virt_incr; send_sig(SIGVTALRM, p, 1); } @@ -899,7 +899,7 @@ unsigned long it_prof = p->it_prof_value; if (it_prof) { - if (it_prof < ticks) { + if (it_prof <= ticks) { it_prof = ticks + p->it_prof_incr; send_sig(SIGPROF, p, 1); } diff -u --recursive --new-file v1.3.76/linux/mm/filemap.c linux/mm/filemap.c --- v1.3.76/linux/mm/filemap.c Fri Mar 15 16:03:21 1996 +++ linux/mm/filemap.c Thu Mar 21 15:00:55 1996 @@ -493,12 +493,36 @@ * Tries to write a shared mapped page to its backing store. May return -EIO * if the disk is full. */ +static inline int do_write_page(struct inode * inode, struct file * file, + const char * page, unsigned long offset) +{ + int old_fs, retval; + unsigned long size; + + size = offset + PAGE_SIZE; + /* refuse to extend file size.. */ + if (S_ISREG(inode->i_mode)) { + if (size > inode->i_size) + size = inode->i_size; + /* Ho humm.. We should have tested for this earlier */ + if (size < offset) + return -EIO; + } + size -= offset; + old_fs = get_fs(); + set_fs(KERNEL_DS); + retval = -EIO; + if (size == file->f_op->write(inode, file, (const char *) page, size)) + retval = 0; + set_fs(old_fs); + return retval; +} + static int filemap_write_page(struct vm_area_struct * vma, unsigned long offset, unsigned long page) { - int old_fs; - unsigned long size, result; + int result; struct file file; struct inode * inode; struct buffer_head * bh; @@ -518,29 +542,17 @@ file.f_op = inode->i_op->default_file_ops; if (!file.f_op->write) return -EIO; - size = offset + PAGE_SIZE; - /* refuse to extend file size.. */ - if (S_ISREG(inode->i_mode)) { - if (size > inode->i_size) - size = inode->i_size; - /* Ho humm.. We should have tested for this earlier */ - if (size < offset) - return -EIO; - } - size -= offset; file.f_mode = 3; file.f_flags = 0; file.f_count = 1; file.f_inode = inode; file.f_pos = offset; file.f_reada = 0; - old_fs = get_fs(); - set_fs(KERNEL_DS); - result = file.f_op->write(inode, &file, (const char *) page, size); - set_fs(old_fs); - if (result != size) - return -EIO; - return 0; + + down(&inode->i_sem); + result = do_write_page(inode, &file, (const char *) page, offset); + up(&inode->i_sem); + return result; } diff -u --recursive --new-file v1.3.76/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c --- v1.3.76/linux/net/appletalk/ddp.c Wed Mar 13 10:09:26 1996 +++ linux/net/appletalk/ddp.c Wed Mar 20 14:14:02 1996 @@ -1791,7 +1791,7 @@ if(sk->debug) printk("SK %p: Loop back.\n", sk); /* loop back */ - sk->wmem_alloc-=skb->truesize; + atomic_sub(skb->truesize, &sk->wmem_alloc); ddp_dl->datalink_header(ddp_dl, skb, dev->dev_addr); skb->sk = NULL; skb->mac.raw=skb->data; diff -u --recursive --new-file v1.3.76/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c --- v1.3.76/linux/net/ax25/af_ax25.c Sun Mar 17 09:04:08 1996 +++ linux/net/ax25/af_ax25.c Wed Mar 20 15:08:26 1996 @@ -377,7 +377,7 @@ return; copy->sk = sk; - sk->rmem_alloc += copy->truesize; + atomic_add(copy->truesize, &sk->rmem_alloc); skb_queue_tail(&sk->receive_queue, copy); if (!sk->dead) sk->data_ready(sk, skb->len); @@ -1727,7 +1727,7 @@ skb_pull(skb, 2); skb_queue_tail(&sk->receive_queue, skb); skb->sk = sk; - sk->rmem_alloc += skb->truesize; + atomic_add(skb->truesize, &sk->rmem_alloc); if (!sk->dead) sk->data_ready(sk, skb->len); } diff -u --recursive --new-file v1.3.76/linux/net/ax25/ax25_in.c linux/net/ax25/ax25_in.c --- v1.3.76/linux/net/ax25/ax25_in.c Sun Mar 17 09:04:08 1996 +++ linux/net/ax25/ax25_in.c Wed Mar 20 14:15:53 1996 @@ -95,7 +95,7 @@ if (ax25->sk != NULL) { skbn->sk = ax25->sk; - ax25->sk->rmem_alloc += skbn->truesize; + atomic_add(skbn->truesize, &ax25->sk->rmem_alloc); } /* get first fragment from queue */ diff -u --recursive --new-file v1.3.76/linux/net/ax25/ax25_subr.c linux/net/ax25/ax25_subr.c --- v1.3.76/linux/net/ax25/ax25_subr.c Sun Mar 17 09:04:08 1996 +++ linux/net/ax25/ax25_subr.c Wed Mar 20 14:15:19 1996 @@ -215,7 +215,7 @@ if (ax25->sk != NULL) { skb->sk = ax25->sk; - ax25->sk->wmem_alloc += skb->truesize; + atomic_add(skb->truesize, &ax25->sk->wmem_alloc); } /* Assume a response - address structure for DTE */ @@ -498,7 +498,7 @@ if (ax25->sk != NULL) { skb->sk = ax25->sk; - ax25->sk->wmem_alloc += skb->truesize; + atomic_add(skb->truesize, &ax25->sk->wmem_alloc); } skb->protocol = htons(ETH_P_AX25); diff -u --recursive --new-file v1.3.76/linux/net/core/datagram.c linux/net/core/datagram.c --- v1.3.76/linux/net/core/datagram.c Sat Feb 17 16:02:57 1996 +++ linux/net/core/datagram.c Thu Mar 21 10:46:17 1996 @@ -79,7 +79,7 @@ lock_sock(sk); restart: - while(skb_peek(&sk->receive_queue) == NULL) /* No data */ + while(skb_queue_empty(&sk->receive_queue)) /* No data */ { /* Socket errors? */ error = sock_error(sk); @@ -142,14 +142,12 @@ save_flags(flags); cli(); skb->users--; - if(skb->users>0) - { - restore_flags(flags); - return; + if(skb->users <= 0) { + /* See if it needs destroying */ + /* Been dequeued by someone - ie it's read */ + if(!skb->next && !skb->prev) + kfree_skb(skb,FREE_READ); } - /* See if it needs destroying */ - if(!skb->next && !skb->prev) /* Been dequeued by someone - ie it's read */ - kfree_skb(skb,FREE_READ); restore_flags(flags); release_sock(sk); } diff -u --recursive --new-file v1.3.76/linux/net/core/dev.c linux/net/core/dev.c --- v1.3.76/linux/net/core/dev.c Tue Mar 5 10:11:15 1996 +++ linux/net/core/dev.c Wed Mar 20 17:08:27 1996 @@ -537,19 +537,6 @@ ***********************************************************************************/ /* - * This is a single non-reentrant routine which takes the received packet - * queue and throws it at the networking layers in the hope that something - * useful will emerge. - */ - -volatile unsigned long in_bh = 0; /* Non-reentrant remember */ - -int in_net_bh() /* Used by timer.c */ -{ - return(in_bh==0?0:1); -} - -/* * When we are called the queue is ready to grab, the interrupts are * on and hardware can interrupt and queue to the receive queue a we * run with no problems. @@ -559,19 +546,11 @@ void net_bh(void) { - struct sk_buff *skb; struct packet_type *ptype; struct packet_type *pt_prev; unsigned short type; /* - * Atomically check and mark our BUSY state. - */ - - if (set_bit(1, (void*)&in_bh)) - return; - - /* * Can we send anything now? We want to clear the * decks for any more sends that get done as we * process the input. This also minimises the @@ -586,19 +565,23 @@ * that from the device which does a mark_bh() just after */ - cli(); - /* - * While the queue is not empty + * While the queue is not empty.. + * + * Note that the queue never shrinks due to + * an interrupt, so we can do this test without + * disabling interrupts. */ - - while((skb=__skb_dequeue(&backlog))!=NULL) - { + + while (!skb_queue_empty(&backlog)) { + struct sk_buff * skb = backlog.next; + /* * We have a packet. Therefore the queue has shrunk */ + cli(); + __skb_unlink(skb, &backlog); backlog_size--; - sti(); /* @@ -681,15 +664,11 @@ #ifdef XMIT_EVERY dev_transmit(); #endif - cli(); } /* End of queue loop */ /* * We have emptied the queue */ - - in_bh = 0; - sti(); /* * One last output flush. diff -u --recursive --new-file v1.3.76/linux/net/core/skbuff.c linux/net/core/skbuff.c --- v1.3.76/linux/net/core/skbuff.c Sun Mar 17 09:04:08 1996 +++ linux/net/core/skbuff.c Wed Mar 20 14:24:11 1996 @@ -57,23 +57,23 @@ * Resource tracking variables */ -unsigned long net_skbcount = 0; -unsigned long net_locked = 0; -unsigned long net_allocs = 0; -unsigned long net_fails = 0; -unsigned long net_free_locked = 0; +atomic_t net_skbcount = 0; +atomic_t net_locked = 0; +atomic_t net_allocs = 0; +atomic_t net_fails = 0; +atomic_t net_free_locked = 0; -extern unsigned long ip_frag_mem; +extern atomic_t ip_frag_mem; void show_net_buffers(void) { - printk("Networking buffers in use : %lu\n",net_skbcount); - printk("Network buffers locked by drivers : %lu\n",net_locked); - printk("Total network buffer allocations : %lu\n",net_allocs); - printk("Total failed network buffer allocs : %lu\n",net_fails); - printk("Total free while locked events : %lu\n",net_free_locked); + printk("Networking buffers in use : %u\n",net_skbcount); + printk("Network buffers locked by drivers : %u\n",net_locked); + printk("Total network buffer allocations : %u\n",net_allocs); + printk("Total failed network buffer allocs : %u\n",net_fails); + printk("Total free while locked events : %u\n",net_free_locked); #ifdef CONFIG_INET - printk("IP fragment buffer size : %lu\n",ip_frag_mem); + printk("IP fragment buffer size : %u\n",ip_frag_mem); #endif } @@ -614,27 +614,24 @@ skb->destructor(skb); if (skb->sk) { - if(skb->sk->prot!=NULL) + struct sock * sk = skb->sk; + if(sk->prot!=NULL) { if (rw) - sock_rfree(skb->sk, skb); + sock_rfree(sk, skb); else - sock_wfree(skb->sk, skb); + sock_wfree(sk, skb); } else { - unsigned long flags; - /* Non INET - default wmalloc/rmalloc handler */ - save_flags(flags); - cli(); if (rw) - skb->sk->rmem_alloc-=skb->truesize; - else - skb->sk->wmem_alloc-=skb->truesize; - restore_flags(flags); - if(!skb->sk->dead) - skb->sk->write_space(skb->sk); + atomic_sub(skb->truesize, &sk->rmem_alloc); + else { + atomic_sub(skb->truesize, &sk->wmem_alloc); + if(!sk->dead) + sk->write_space(sk); + } kfree_skbmem(skb); } } @@ -760,7 +757,6 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int priority) { - unsigned long flags; struct sk_buff *n; IS_SKB(skb); @@ -771,12 +767,9 @@ n->count = 1; if (skb->data_skb) skb = skb->data_skb; - save_flags(flags); - cli(); - skb->count++; - net_allocs++; - net_skbcount++; - restore_flags(flags); + atomic_inc(&skb->count); + atomic_inc(&net_allocs); + atomic_inc(&net_skbcount); n->data_skb = skb; n->next = n->prev = n->link3 = NULL; n->list = NULL; diff -u --recursive --new-file v1.3.76/linux/net/core/sock.c linux/net/core/sock.c --- v1.3.76/linux/net/core/sock.c Tue Mar 5 10:11:15 1996 +++ linux/net/core/sock.c Wed Mar 20 15:57:00 1996 @@ -324,50 +324,32 @@ return(0); } - struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, int priority) { - if (sk) - { - if (sk->wmem_alloc + size < sk->sndbuf || force) - { - struct sk_buff * c = alloc_skb(size, priority); - if (c) - { - unsigned long flags; - save_flags(flags); - cli(); - sk->wmem_alloc+= c->truesize; - restore_flags(flags); /* was sti(); */ - } - return c; + if (sk) { + if (force || sk->wmem_alloc + size < sk->sndbuf) { + struct sk_buff * skb = alloc_skb(size, priority); + if (skb) + atomic_add(skb->truesize, &sk->wmem_alloc); + return skb; } - return(NULL); + return NULL; } - return(alloc_skb(size, priority)); + return alloc_skb(size, priority); } - struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority) { - if (sk) - { - if (sk->rmem_alloc + size < sk->rcvbuf || force) - { - struct sk_buff *c = alloc_skb(size, priority); - if (c) - { - unsigned long flags; - save_flags(flags); - cli(); - sk->rmem_alloc += c->truesize; - restore_flags(flags); /* was sti(); */ - } - return(c); + if (sk) { + if (force || sk->rmem_alloc + size < sk->rcvbuf) { + struct sk_buff *skb = alloc_skb(size, priority); + if (skb) + atomic_add(skb->truesize, &sk->rmem_alloc); + return skb; } - return(NULL); + return NULL; } - return(alloc_skb(size, priority)); + return alloc_skb(size, priority); } @@ -396,7 +378,7 @@ return(0); if (sk->wmem_alloc >= sk->sndbuf) return(0); - return(sk->sndbuf-sk->wmem_alloc ); + return sk->sndbuf - sk->wmem_alloc; } return(0); } @@ -411,14 +393,9 @@ kfree_skbmem(skb); if (sk) { - unsigned long flags; - save_flags(flags); - cli(); - sk->wmem_alloc -= s; - restore_flags(flags); + atomic_sub(s, &sk->wmem_alloc); /* In case it might be waiting for more memory. */ sk->write_space(sk); - return; } } @@ -432,11 +409,7 @@ kfree_skbmem(skb); if (sk) { - unsigned long flags; - save_flags(flags); - cli(); - sk->rmem_alloc -= s; - restore_flags(flags); + atomic_sub(s, &sk->rmem_alloc); } } diff -u --recursive --new-file v1.3.76/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c --- v1.3.76/linux/net/ipv4/af_inet.c Sun Mar 17 09:04:08 1996 +++ linux/net/ipv4/af_inet.c Wed Mar 20 15:42:33 1996 @@ -410,7 +410,8 @@ { /* this should never happen. */ /* actually it can if an ack has just been sent. */ - printk("Socket destroy delayed\n"); + printk("Socket destroy delayed (r=%d w=%d)\n", + sk->rmem_alloc, sk->wmem_alloc); sk->destroy = 1; sk->ack_backlog = 0; release_sock(sk); diff -u --recursive --new-file v1.3.76/linux/net/ipv4/ip_fragment.c linux/net/ipv4/ip_fragment.c --- v1.3.76/linux/net/ipv4/ip_fragment.c Wed Nov 8 07:11:45 1995 +++ linux/net/ipv4/ip_fragment.c Wed Mar 20 15:14:14 1996 @@ -45,7 +45,7 @@ static struct ipq *ipqueue = NULL; /* IP fragment queue */ -unsigned long ip_frag_mem = 0; /* Memory used for fragments */ +atomic_t ip_frag_mem = 0; /* Memory used for fragments */ /* * Memory Tracking Functions @@ -53,34 +53,22 @@ extern __inline__ void frag_kfree_skb(struct sk_buff *skb, int type) { - unsigned long flags; - save_flags(flags); - cli(); - ip_frag_mem-=skb->truesize; - restore_flags(flags); + atomic_sub(skb->truesize, &ip_frag_mem); kfree_skb(skb,type); } extern __inline__ void frag_kfree_s(void *ptr, int len) { - unsigned long flags; - save_flags(flags); - cli(); - ip_frag_mem-=len; - restore_flags(flags); + atomic_sub(len, &ip_frag_mem); kfree_s(ptr,len); } extern __inline__ void *frag_kmalloc(int size, int pri) { - unsigned long flags; void *vp=kmalloc(size,pri); if(!vp) return NULL; - save_flags(flags); - cli(); - ip_frag_mem+=size; - restore_flags(flags); + atomic_add(size, &ip_frag_mem); return vp; } @@ -623,7 +611,6 @@ struct sk_buff *skb2; int left, mtu, hlen, len; int offset; - unsigned long flags; /* * Point into the IP datagram header. @@ -730,14 +717,11 @@ * it might possess */ - save_flags(flags); if (sk) { - cli(); - sk->wmem_alloc += skb2->truesize; + atomic_add(skb2->truesize, &sk->wmem_alloc); skb2->sk=sk; } - restore_flags(flags); skb2->raddr = skb->raddr; /* For rebuild_header - must be here */ /* diff -u --recursive --new-file v1.3.76/linux/net/ipv4/proc.c linux/net/ipv4/proc.c --- v1.3.76/linux/net/ipv4/proc.c Tue Jan 23 21:15:55 1996 +++ linux/net/ipv4/proc.c Wed Mar 20 14:29:46 1996 @@ -108,7 +108,7 @@ timer_active=timer_active2; timer_expires=sp->timer.expires; } - len += sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08lX:%08lX %02X:%08lX %08X %d %d\n", + len += sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08X:%08X %02X:%08lX %08X %d %d\n", i, src, srcp, dest, destp, sp->state, format==0?sp->write_seq-sp->rcv_ack_seq:sp->wmem_alloc, format==0?sp->acked_seq-sp->copied_seq:sp->rmem_alloc, diff -u --recursive --new-file v1.3.76/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c --- v1.3.76/linux/net/ipv4/tcp_input.c Sun Mar 17 09:04:09 1996 +++ linux/net/ipv4/tcp_input.c Thu Mar 21 17:08:06 1996 @@ -1595,7 +1595,7 @@ */ skb->sk=sk; - sk->rmem_alloc += skb->truesize; + atomic_add(skb->truesize, &sk->rmem_alloc); /* * We should now do header prediction. @@ -1773,7 +1773,7 @@ if(sk->debug) printk("Doing a BSD time wait\n"); tcp_statistics.TcpEstabResets++; - sk->rmem_alloc -= skb->truesize; + atomic_sub(skb->truesize, &sk->rmem_alloc); skb->sk = NULL; sk->err=ECONNRESET; tcp_set_state(sk, TCP_CLOSE); @@ -1783,7 +1783,7 @@ if (sk && sk->state==TCP_LISTEN) { skb->sk = sk; - sk->rmem_alloc += skb->truesize; + atomic_add(skb->truesize, &sk->rmem_alloc); tcp_conn_request(sk, skb, daddr, saddr,opt, dev,seq+128000); return 0; } @@ -1847,12 +1847,18 @@ * now drop it (we must process the ack first to avoid * deadlock cases). */ - +#if 0 + /* + * Is this test really a good idea? We should + * throw away packets that aren't in order, not + * new packets. + */ if (sk->rmem_alloc >= sk->rcvbuf) { kfree_skb(skb, FREE_READ); return(0); } +#endif /* diff -u --recursive --new-file v1.3.76/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c --- v1.3.76/linux/net/ipv4/tcp_output.c Sun Mar 17 09:04:09 1996 +++ linux/net/ipv4/tcp_output.c Wed Mar 20 14:11:30 1996 @@ -738,8 +738,8 @@ * Charge the sock_buff to newsk. */ - sk->rmem_alloc -= skb->truesize; - newsk->rmem_alloc += skb->truesize; + atomic_sub(skb->truesize, &sk->rmem_alloc); + atomic_add(skb->truesize, &newsk->rmem_alloc); skb_queue_tail(&sk->receive_queue,skb); sk->ack_backlog++; diff -u --recursive --new-file v1.3.76/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c --- v1.3.76/linux/net/ipx/af_ipx.c Tue Mar 5 10:11:16 1996 +++ linux/net/ipx/af_ipx.c Wed Mar 20 14:08:23 1996 @@ -593,7 +593,7 @@ */ if(skb->sk) { - skb->sk->wmem_alloc-=skb->truesize; + atomic_sub(skb->truesize, &skb->sk->wmem_alloc); skb->sk=NULL; } /* @@ -608,7 +608,7 @@ { if (!send_to_wire && skb->sk) { - skb->sk->wmem_alloc-=skb->truesize; + atomic_sub(skb->truesize, &skb->sk->wmem_alloc); skb->sk=NULL; } ipxitf_demux_socket(intrfc, skb, send_to_wire); diff -u --recursive --new-file v1.3.76/linux/scripts/patch-kernel linux/scripts/patch-kernel --- v1.3.76/linux/scripts/patch-kernel Wed Mar 13 10:09:27 1996 +++ linux/scripts/patch-kernel Thu Mar 21 08:55:34 1996 @@ -43,11 +43,11 @@ echo "failed. Clean up yourself." break fi - if [ "`find $sourcedir '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ] + if [ "`find $sourcedir -follow '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ] then echo "Aborting. Reject files found." break fi # Remove backup files - find $sourcedir '(' -name '*.orig' -o -name '.*.orig' ')' -print | xargs rm -f + find $sourcedir -follow '(' -name '*.orig' -o -name '.*.orig' ')' -print | xargs rm -f done