diff -u --recursive --new-file v2.0.24/linux/CREDITS linux/CREDITS --- v2.0.24/linux/CREDITS Thu Oct 31 12:08:50 1996 +++ linux/CREDITS Fri Nov 1 13:04:07 1996 @@ -667,7 +667,7 @@ S: USA N: Bernhard Kaindl -E: bartelt@computerhaus.at +E: edv@bartelt.via.at D: Author of a menu based configuration tool, kmenu, which D: is the predecessor of 'make menuconfig' and 'make xconfig'. S: Tallak 95 diff -u --recursive --new-file v2.0.24/linux/Makefile linux/Makefile --- v2.0.24/linux/Makefile Thu Oct 31 12:08:50 1996 +++ linux/Makefile Wed Oct 30 12:46:07 1996 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 0 -SUBLEVEL = 24 +SUBLEVEL = 25 ARCH = i386 diff -u --recursive --new-file v2.0.24/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- v2.0.24/linux/arch/i386/kernel/entry.S Wed Jul 17 12:33:25 1996 +++ linux/arch/i386/kernel/entry.S Wed Nov 6 11:54:51 1996 @@ -503,6 +503,11 @@ pushl $ SYMBOL_NAME(do_page_fault) jmp error_code +ENTRY(spurious_interrupt_bug) + pushl $0 + pushl $ SYMBOL_NAME(do_spurious_interrupt_bug) + jmp error_code + .data ENTRY(sys_call_table) .long SYMBOL_NAME(sys_setup) /* 0 */ diff -u --recursive --new-file v2.0.24/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.0.24/linux/arch/i386/kernel/irq.c Wed Sep 11 17:57:13 1996 +++ linux/arch/i386/kernel/irq.c Thu Nov 7 11:25:21 1996 @@ -522,7 +522,7 @@ irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21; #ifdef DEBUG - printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask); + printk("probe_irq_off: irqs=0x%04lx irqmask=0x%04x\n", irqs, irqmask); #endif irqs &= irqmask; if (!irqs) diff -u --recursive --new-file v2.0.24/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c --- v2.0.24/linux/arch/i386/kernel/time.c Sat Aug 17 21:19:26 1996 +++ linux/arch/i386/kernel/time.c Thu Nov 7 19:48:18 1996 @@ -20,10 +20,13 @@ #include #include #include +#include +#include #include #include #include +#include #include #include @@ -462,6 +465,21 @@ needs more debugging. */ if (x86_capability & 16) { do_gettimeoffset = do_fast_gettimeoffset; + + if( strcmp( x86_vendor_id, "AuthenticAMD" ) == 0 ) { + if( x86 == 5 ) { + if( x86_model == 0 ) { + /* turn on cycle counters during power down */ + __asm__ __volatile__ (" movl $0x83, %%ecx \n \ + rdmsr \n \ + orl $1,%%eax \n \ + wrmsr \n " + : : : "ax", "cx", "dx" ); + udelay(500); + } + } + } + /* read Pentium cycle counter */ __asm__(".byte 0x0f,0x31" :"=a" (init_timer_cc.low), diff -u --recursive --new-file v2.0.24/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c --- v2.0.24/linux/arch/i386/kernel/traps.c Tue Oct 8 21:20:08 1996 +++ linux/arch/i386/kernel/traps.c Wed Nov 6 11:54:51 1996 @@ -81,6 +81,7 @@ asmlinkage void coprocessor_error(void); asmlinkage void reserved(void); asmlinkage void alignment_check(void); +asmlinkage void spurious_interrupt_bug(void); int kstack_depth_to_print = 24; @@ -173,8 +174,8 @@ DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS, current) DO_ERROR(11, SIGBUS, "segment not present", segment_not_present, current) DO_ERROR(12, SIGBUS, "stack segment", stack_segment, current) -DO_ERROR(15, SIGSEGV, "reserved", reserved, current) DO_ERROR(17, SIGSEGV, "alignment check", alignment_check, current) +DO_ERROR(18, SIGSEGV, "reserved", reserved, current) asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) { @@ -258,6 +259,12 @@ math_error(); } +asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs, + long error_code) +{ + printk("Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); +} + /* * 'math_state_restore()' saves the current math information in the * old math state array, and gets the new ones from the current task @@ -343,7 +350,7 @@ set_trap_gate(12,&stack_segment); set_trap_gate(13,&general_protection); set_trap_gate(14,&page_fault); - set_trap_gate(15,&reserved); + set_trap_gate(15,&spurious_interrupt_bug); set_trap_gate(16,&coprocessor_error); set_trap_gate(17,&alignment_check); for (i=18;i<48;i++) diff -u --recursive --new-file v2.0.24/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c --- v2.0.24/linux/drivers/block/ide-tape.c Tue Oct 8 21:20:09 1996 +++ linux/drivers/block/ide-tape.c Wed Nov 6 14:48:32 1996 @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-tape.c Version 1.8 - ALPHA Sep 26, 1996 + * linux/drivers/block/ide-tape.c Version 1.9 - ALPHA Nov 5, 1996 * * Copyright (C) 1995, 1996 Gadi Oxman * @@ -189,6 +189,12 @@ * Ver 1.7 Sep 10 96 Minor changes for the CONNER CTT8000-A model. * Ver 1.8 Sep 26 96 Attempt to find a better balance between good * interactive response and high system throughput. + * Ver 1.9 Nov 5 96 Automatically cross encountered filemarks rather + * than requiring an explicit FSF command. + * Abort pending requests at end of media. + * MTTELL was sometimes returning incorrect results. + * Return the real block size in the MTIOCGET ioctl. + * Some error recovery bug fixes. * * We are currently in an *alpha* stage. The driver is not complete and not * much tested. I would strongly suggest to: @@ -418,8 +424,9 @@ #define IDETAPE_READ_REQUEST 92 #define IDETAPE_WRITE_REQUEST 93 +#define IDETAPE_ABORTED_WRITE_REQUEST 94 -#define IDETAPE_LAST_REQUEST 93 +#define IDETAPE_LAST_REQUEST 94 /* * A macro which can be used to check if a we support a given @@ -1205,10 +1212,6 @@ printk ("Unable to register character device interface !\n"); /* ??? */ } - else { - printk ("ide-tape: %s <-> %s : Character device interface on major = %d\n", - drive->name,idetape_chrdev.name,major); - } } /* @@ -1260,10 +1263,8 @@ #if IDETAPE_PIPELINE tape->max_number_of_stages=IDETAPE_MIN_PIPELINE_STAGES; - printk ("ide-tape: Operating in pipelined (fast and tricky) operation mode.\n"); #else tape->max_number_of_stages=0; - printk ("ide-tape: Operating in non-pipelined (slow and safe) operation mode.\n"); #endif /* IDETAPE_PIPELINE */ idetape_get_mode_sense_results (drive); @@ -2474,7 +2475,12 @@ pc->abort=1; } } - + if (pc->c[0] == IDETAPE_WRITE_CMD) { + if (result->eom || (result->sense_key == 0xd && result->asc == 0x0 && result->ascq == 0x2)) { + pc->error = IDETAPE_RQ_ERROR_EOD; + pc->abort = 1; + } + } if (pc->c[0] == IDETAPE_READ_CMD || pc->c[0] == IDETAPE_WRITE_CMD) { if (result->sense_key == 8) { pc->error=IDETAPE_RQ_ERROR_EOD; @@ -2853,6 +2859,17 @@ } } +static void idetape_abort_pipeline (ide_drive_t *drive) +{ + idetape_tape_t *tape = &drive->tape; + idetape_pipeline_stage_t *stage = tape->next_stage; + + while (stage) { + stage->rq.cmd = IDETAPE_ABORTED_WRITE_REQUEST; + stage = stage->next; + } +} + /* * Functions which handle requests. */ @@ -2880,7 +2897,9 @@ if (!rq->errors) /* In case rq->errors is already set, */ rq->errors=!uptodate; /* we won't change it. */ error=rq->errors; - + if (error) + tape->failed_pc = NULL; + if (tape->active_data_request == rq) { /* The request was a pipelined data transfer request */ if (rq->cmd == IDETAPE_READ_REQUEST) { @@ -2896,8 +2915,11 @@ tape->active_data_request=NULL; if (rq->cmd == IDETAPE_WRITE_REQUEST) { - if (rq->errors) + if (rq->errors) { tape->error_in_pipeline_stage=rq->errors; + if (error == IDETAPE_RQ_ERROR_EOD) + idetape_abort_pipeline (drive); + } idetape_remove_stage_head (drive); } @@ -3078,6 +3100,12 @@ idetape_issue_packet_command (drive,pc,&idetape_pc_intr); return; + case IDETAPE_ABORTED_WRITE_REQUEST: + rq->cmd = IDETAPE_WRITE_REQUEST; + rq->errors = IDETAPE_RQ_ERROR_EOD; + idetape_end_request (1, HWGROUP(drive)); + return; + case IDETAPE_PACKET_COMMAND_REQUEST_TYPE1: case IDETAPE_PACKET_COMMAND_REQUEST_TYPE2: /* @@ -3282,8 +3310,11 @@ bytes_read=tape->tape_block_size*(rq_ptr->nr_sectors-rq_ptr->current_nr_sectors); rq_ptr->nr_sectors=rq_ptr->current_nr_sectors=0; idetape_copy_buffer_from_stage (tape->first_stage,buffer); - if (rq_ptr->errors != IDETAPE_RQ_ERROR_FILEMARK) + if (rq_ptr->errors != IDETAPE_RQ_ERROR_FILEMARK) { + tape->filemark = 0; idetape_remove_stage_head (drive); + } else + tape->filemark = 1; #if IDETAPE_DEBUG_BUGS if (bytes_read > blocks*tape->tape_block_size) { printk ("ide-tape: bug: trying to return more bytes than requested\n"); @@ -3686,7 +3717,7 @@ ide_drive_t *drive=idetape_chrdev.drive; idetape_tape_t *tape=&(drive->tape); char *buf_ptr=buf; - int bytes_read,temp,actually_read=0; + int bytes_read,temp,actually_read=0, original_count = count; #if IDETAPE_DEBUG_LOG printk ("Reached idetape_chrdev_read\n"); @@ -3730,7 +3761,7 @@ while (count >= tape->data_buffer_size) { bytes_read=idetape_add_chrdev_read_request (drive,tape->capabilities.ctl,tape->merge_buffer); if (bytes_read <= 0) - return (actually_read); + goto finish; memcpy_tofs (buf_ptr,tape->merge_buffer,bytes_read); buf_ptr+=bytes_read;count-=bytes_read;actually_read+=bytes_read; } @@ -3738,13 +3769,16 @@ if (count) { bytes_read=idetape_add_chrdev_read_request (drive,tape->capabilities.ctl,tape->merge_buffer); if (bytes_read <= 0) - return (actually_read); + goto finish; temp=IDETAPE_MIN (count,bytes_read); memcpy_tofs (buf_ptr,tape->merge_buffer,temp); actually_read+=temp; tape->merge_buffer_offset=temp; tape->merge_buffer_size=bytes_read-temp; } +finish: + if (actually_read < original_count && tape->filemark) + idetape_space_over_filemarks (drive, MTFSF, 1); return (actually_read); } @@ -3817,6 +3851,26 @@ return (actually_written); } +static int idetape_pipeline_size (ide_drive_t *drive) +{ + idetape_tape_t *tape = &drive->tape; + idetape_pipeline_stage_t *stage; + struct request *rq; + int size = 0; + + idetape_wait_for_pipeline (drive); + stage = tape->first_stage; + while (stage != NULL) { + rq = &stage->rq; + size += tape->tape_block_size * (rq->nr_sectors-rq->current_nr_sectors); + if (rq->errors == IDETAPE_RQ_ERROR_FILEMARK) + size += tape->tape_block_size; + stage = stage->next; + } + size += tape->merge_buffer_size; + return size; +} + /* * Our character device ioctls. * @@ -3827,17 +3881,7 @@ * * MTIOCTOP - Refer to idetape_mtioctop for detailed description. * - * MTIOCGET - The mt_dsreg field in the returned mtget structure - * will be set to (recommended block size << - * MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK, which - * is currently equal to the size itself. - * The other mtget fields are not supported. - * - * Note that we do not actually return the tape's - * block size. Rather, we provide the recommended - * number of bytes which should be used as a "user - * block size" with the character device read/write - * functions to maximize throughput. + * MTIOCGET - Some of the fields are not supported. * * MTIOCPOS - The current tape "position" is returned. * (A unique number which can be used with the MTSEEK @@ -3857,7 +3901,7 @@ struct mtop mtop; struct mtget mtget; struct mtpos mtpos; - int retval; + int retval, block_offset = 0; #if IDETAPE_DEBUG_LOG printk ("Reached idetape_chrdev_ioctl, cmd=%u\n",cmd); @@ -3867,14 +3911,16 @@ idetape_empty_write_pipeline (drive); idetape_flush_tape_buffers (drive); } - - if (tape->chrdev_direction == idetape_direction_read && cmd != MTIOCTOP) - idetape_discard_read_pipeline (drive); - pc.buffer=pc.temp_buffer; pc.buffer_size=IDETAPE_TEMP_BUFFER_SIZE; pc.current_position=pc.temp_buffer; + if (cmd == MTIOCGET || cmd == MTIOCPOS) { + block_offset = idetape_pipeline_size (drive) / tape->tape_block_size; + idetape_create_read_position_cmd (&pc); + retval=idetape_queue_pc_tail (drive,&pc); + if (retval) return (retval); + } switch (cmd) { case MTIOCTOP: retval=verify_area (VERIFY_READ,(char *) arg,sizeof (struct mtop)); @@ -3882,16 +3928,15 @@ memcpy_fromfs ((char *) &mtop, (char *) arg, sizeof (struct mtop)); return (idetape_mtioctop (drive,mtop.mt_op,mtop.mt_count)); case MTIOCGET: + memset (&mtget, 0, sizeof (struct mtget)); + mtget.mt_blkno = tape->block_address - block_offset; mtget.mt_dsreg=(tape->data_buffer_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK; retval=verify_area (VERIFY_WRITE,(char *) arg,sizeof (struct mtget)); if (retval) return (retval); memcpy_tofs ((char *) arg,(char *) &mtget, sizeof (struct mtget)); return (0); case MTIOCPOS: - idetape_create_read_position_cmd (&pc); - retval=idetape_queue_pc_tail (drive,&pc); - if (retval) return (retval); - mtpos.mt_blkno=tape->block_address; + mtpos.mt_blkno = tape->block_address - block_offset; retval=verify_area (VERIFY_WRITE,(char *) arg,sizeof (struct mtpos)); if (retval) return (retval); memcpy_tofs ((char *) arg,(char *) &mtpos, sizeof (struct mtpos)); @@ -4052,6 +4097,7 @@ */ tape->merge_buffer_size=tape->merge_buffer_offset=0; + tape->filemark = 0; while (tape->first_stage != NULL) { /* diff -u --recursive --new-file v2.0.24/linux/drivers/block/ide-tape.h linux/drivers/block/ide-tape.h --- v2.0.24/linux/drivers/block/ide-tape.h Tue Oct 8 21:20:09 1996 +++ linux/drivers/block/ide-tape.h Wed Nov 6 14:48:32 1996 @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-tape.h Version 1.8 - ALPHA Sep 26, 1996 + * linux/drivers/block/ide-tape.h Version 1.9 - ALPHA Nov 5, 1996 * * Copyright (C) 1995, 1996 Gadi Oxman */ @@ -466,6 +466,7 @@ /* Character device operation */ chrdev_direction_t chrdev_direction; /* Current character device data transfer direction */ + int filemark; /* Currently on a filemark */ byte busy; /* Device already opened */ /* Device information */ diff -u --recursive --new-file v2.0.24/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.0.24/linux/drivers/block/ide.c Thu Oct 31 12:08:50 1996 +++ linux/drivers/block/ide.c Wed Nov 6 14:48:33 1996 @@ -811,6 +811,10 @@ */ for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *rdrive = &hwif->drives[unit]; +#ifdef CONFIG_BLK_DEV_IDETAPE + if (rdrive->media == ide_tape) + rdrive->tape.reset_issued = 1; +#endif /* CONFIG_BLK_DEV_IDETAPE */ rdrive->special.all = 0; rdrive->special.b.set_geometry = 1; rdrive->special.b.recalibrate = 1; diff -u --recursive --new-file v2.0.24/linux/drivers/char/console.c linux/drivers/char/console.c --- v2.0.24/linux/drivers/char/console.c Mon Sep 2 15:18:26 1996 +++ linux/drivers/char/console.c Thu Nov 7 11:25:21 1996 @@ -1446,7 +1446,8 @@ ok = tc && (c >= 32 || (!utf && !(((disp_ctrl ? CTRL_ALWAYS : CTRL_ACTION) >> c) & 1))) - && (c != 127 || disp_ctrl); + && (c != 127 || disp_ctrl) + && (c != 128+27); if (vc_state == ESnormal && ok) { /* Now try to find out how to display it */ @@ -1486,6 +1487,8 @@ * of an escape sequence. */ switch (c) { + case 0: + continue; case 7: if (bell_duration) kd_mksound(bell_pitch, bell_duration); diff -u --recursive --new-file v2.0.24/linux/drivers/char/keyb_m68k.c linux/drivers/char/keyb_m68k.c --- v2.0.24/linux/drivers/char/keyb_m68k.c Fri Apr 5 17:16:48 1996 +++ linux/drivers/char/keyb_m68k.c Thu Nov 7 11:25:21 1996 @@ -508,8 +508,9 @@ #define A_CFLEX '^' #define A_TILDE '~' #define A_DIAER '"' -static unsigned char ret_diacr[] = - {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER }; +#define A_CEDIL ',' +static unsigned char ret_diacr[NR_DEAD] = + {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL }; /* If a dead key pressed twice, output a character corresponding to it, */ /* otherwise just remember the dead key. */ diff -u --recursive --new-file v2.0.24/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- v2.0.24/linux/drivers/char/keyboard.c Thu Jul 25 20:24:49 1996 +++ linux/drivers/char/keyboard.c Thu Nov 7 11:25:21 1996 @@ -822,8 +822,9 @@ #define A_CFLEX '^' #define A_TILDE '~' #define A_DIAER '"' -static unsigned char ret_diacr[] = - {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER }; +#define A_CEDIL ',' +static unsigned char ret_diacr[NR_DEAD] = + {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL }; /* If a dead key pressed twice, output a character corresponding to it, */ /* otherwise just remember the dead key. */ diff -u --recursive --new-file v2.0.24/linux/drivers/char/misc.c linux/drivers/char/misc.c --- v2.0.24/linux/drivers/char/misc.c Thu Aug 29 19:15:14 1996 +++ linux/drivers/char/misc.c Wed Nov 6 14:39:42 1996 @@ -67,6 +67,7 @@ extern int atixl_busmouse_init(void); extern int sun_mouse_init(void); extern void watchdog_init(void); +extern void wdt_init(void); extern void pcwatchdog_init(void); extern int rtc_init(void); @@ -218,7 +219,10 @@ #endif #ifdef CONFIG_SOFT_WATCHDOG watchdog_init(); -#endif +#endif +#ifdef CONFIG_WDT + wdt_init(); +#endif #ifdef CONFIG_PCWATCHDOG pcwatchdog_init(); #endif diff -u --recursive --new-file v2.0.24/linux/drivers/net/3c501.c linux/drivers/net/3c501.c --- v2.0.24/linux/drivers/net/3c501.c Mon May 6 12:26:07 1996 +++ linux/drivers/net/3c501.c Wed Nov 6 14:39:42 1996 @@ -237,8 +237,6 @@ static int el1_probe1(struct device *dev, int ioaddr) { -#ifndef MODULE - const char *mname; /* Vendor name */ unsigned char station_addr[6]; int autoirq = 0; @@ -343,8 +341,6 @@ */ ether_setup(dev); - -#endif /* !MODULE */ return 0; } diff -u --recursive --new-file v2.0.24/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c --- v2.0.24/linux/drivers/net/3c59x.c Thu Oct 31 12:08:51 1996 +++ linux/drivers/net/3c59x.c Thu Nov 7 11:25:21 1996 @@ -634,7 +634,7 @@ /* Switch to register set 7 for normal use. */ EL3WINDOW(7); - /* Set reciever mode: presumably accept b-case and phys addr only. */ + /* Set receiver mode: presumably accept b-case and phys addr only. */ set_rx_mode(dev); outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ diff -u --recursive --new-file v2.0.24/linux/drivers/net/Space.c linux/drivers/net/Space.c --- v2.0.24/linux/drivers/net/Space.c Thu Oct 31 12:08:51 1996 +++ linux/drivers/net/Space.c Fri Nov 1 23:07:23 1996 @@ -195,6 +195,9 @@ #ifdef CONFIG_NI52 && ni52_probe(dev) #endif +#ifdef CONFIG_NI65 + && ni65_probe(dev) +#endif #ifdef CONFIG_ATARILANCE /* Lance-based Atari ethernet boards */ && atarilance_probe(dev) #endif diff -u --recursive --new-file v2.0.24/linux/drivers/net/net_init.c linux/drivers/net/net_init.c --- v2.0.24/linux/drivers/net/net_init.c Thu Oct 31 12:08:51 1996 +++ linux/drivers/net/net_init.c Wed Nov 6 14:39:42 1996 @@ -163,12 +163,12 @@ #ifdef CONFIG_FDDI static int fddi_change_mtu(struct device *dev, int new_mtu) - { +{ if ((new_mtu < FDDI_K_SNAP_HLEN) || (new_mtu > FDDI_K_SNAP_DLEN)) return(-EINVAL); dev->mtu = new_mtu; return(0); - } +} #endif diff -u --recursive --new-file v2.0.24/linux/drivers/net/ni65.c linux/drivers/net/ni65.c --- v2.0.24/linux/drivers/net/ni65.c Thu Oct 31 12:08:52 1996 +++ linux/drivers/net/ni65.c Fri Nov 1 23:07:23 1996 @@ -1,6 +1,6 @@ /* * ni6510 (am7990 'lance' chip) driver for Linux-net-3 - * BETAcode v0.70 (96/04/07) for 1.3.66 (or later) + * BETAcode v0.71 (96/09/29) for 2.0.0 (or later) * copyrights (c) 1994,1995,1996 by M.Hipp * * This driver can handle the old ni6510 board and the newer ni6510 @@ -23,16 +23,19 @@ * and from the original drivers by D.Becker * * known problems: - * on some PCI boards (including my own) the card/board/ISA-bridge has - * problems with bus master DMA. This results in lotsa overruns. - * It may help to '#define RCV_PARANOIA_CHECK' or try to #undef - * the XMT and RCV_VIA_SKB option .. this reduces driver performance. - * Or just play with your BIOS options to optimize ISA-DMA access. - * Maybe you also wanna play with the LOW_PERFORAMCE and MID_PERFORMANCE - * defines -> please report me your experience then + * - on some PCI boards (including my own) the card/board/ISA-bridge has + * problems with bus master DMA. This results in lotsa overruns. + * It may help to '#define RCV_PARANOIA_CHECK' or try to #undef + * the XMT and RCV_VIA_SKB option .. this reduces driver performance. + * Or just play with your BIOS options to optimize ISA-DMA access. + * Maybe you also wanna play with the LOW_PERFORAMCE and MID_PERFORMANCE + * defines -> please report me your experience then + * - Harald reported for ASUS SP3G mainboards, that you should use + * the 'optimal settings' from the user's manual on page 3-12! * * credits: * thanx to Jason Sullivan for sending me a ni6510 card! + * lot of debug runs with ASUS SP3G Boards (Intel Saturn) by Harald Koenig * * simple performance test: (486DX-33/Ni6510-EB receives from 486DX4-100/Ni6510-EB) * average: FTP -> 8384421 bytes received in 8.5 seconds @@ -42,8 +45,10 @@ */ /* + * 96.Sept.29: virt_to_bus stuff added for new memory modell + * 96.April.29: Added Harald Koenig's Patches (MH) * 96.April.13: enhanced error handling .. more tests (MH) - * 96.April.5/6: a lot of performance tests .. got it stable now (hopefully) (MH) + * 96.April.5/6: a lot of performance tests. Got it stable now (hopefully) (MH) * 96.April.1: (no joke ;) .. added EtherBlaster and Module support (MH) * 96.Feb.19: fixed a few bugs .. cleanups .. tested for 1.3.66 (MH) * hopefully no more 16MB limit @@ -52,7 +57,7 @@ * * 94.Aug.22: changes in xmit_intr (ack more than one xmitted-packet), ni65_send_packet (p->lock) (MH) * - * 94,July.16: fixed bugs in recv_skb and skb-alloc stuff (MH) + * 94.July.16: fixed bugs in recv_skb and skb-alloc stuff (MH) */ #include @@ -84,8 +89,8 @@ * 'invert' the defines for max. performance. This may cause DMA problems * on some boards (e.g on my ASUS SP3G) */ -#define XMT_VIA_SKB -#define RCV_VIA_SKB +#undef XMT_VIA_SKB +#undef RCV_VIA_SKB #define RCV_PARANOIA_CHECK #define MID_PERFORMANCE @@ -121,12 +126,12 @@ #define RMDNUMMASK 0x60000000 /* log2(RMDNUM)<<29 */ #endif -#if 1 +#if 0 #define TMDNUM 1 -#define TMDNUMMASK 0x00000000 /* log2(TMDNUM)<<29 */ +#define TMDNUMMASK 0x00000000 #else -#define TMDNUM 2 -#define TMDNUMMASK 0x20000000 /* log2(TMDNUM)<<29 */ +#define TMDNUM 4 +#define TMDNUMMASK 0x40000000 /* log2(TMDNUM)<<29 */ #endif /* slightly oversized */ @@ -239,7 +244,7 @@ { writereg(CSR0_STOP | CSR0_CLRALL,CSR0); /* STOP */ - if(!test_bit(1,&cards[p->cardno].config)) + if( !(cards[p->cardno].config & 0x02) ) return; outw(80,PORT+L_ADDRREG); @@ -487,6 +492,7 @@ static void ni65_init_lance(struct priv *p,unsigned char *daddr,int filter,int mode) { int i; + u32 pib; writereg(CSR0_CLRALL|CSR0_STOP,CSR0); @@ -497,11 +503,12 @@ p->ib.filter[i] = filter; p->ib.mode = mode; - p->ib.trp = (unsigned long) p->tmdhead | TMDNUMMASK; - p->ib.rrp = (unsigned long) p->rmdhead | RMDNUMMASK; + p->ib.trp = (u32) virt_to_bus(p->tmdhead) | TMDNUMMASK; + p->ib.rrp = (u32) virt_to_bus(p->rmdhead) | RMDNUMMASK; writereg(0,CSR3); /* busmaster/no word-swap */ - writereg((unsigned short) (((unsigned long) &(p->ib)) & 0xffff),CSR1); - writereg((unsigned short) (((unsigned long) &(p->ib))>>16),CSR2); + pib = (u32) virt_to_bus(&p->ib); + writereg(pib & 0xffff,CSR1); + writereg(pib >> 16,CSR2); writereg(CSR0_INIT,CSR0); /* this changes L_ADDRREG to CSR0 */ @@ -540,7 +547,7 @@ return NULL; } } - if( (unsigned long) (ptr+size) > 0x1000000) { + if( (u32) virt_to_bus(ptr+size) > 0x1000000) { printk("%s: unable to allocate %s memory in lower 16MB!\n",dev->name,what); if(type) kfree_skb(skb,FREE_WRITE); @@ -672,7 +679,7 @@ #ifdef XMT_VIA_SKB skb_save[i] = p->tmd_skb[i]; #endif - buffer[i] = tmdp->u.buffer; + buffer[i] = (u32) bus_to_virt(tmdp->u.buffer); blen[i] = tmdp->blen; tmdp->u.s.status = 0x0; } @@ -686,10 +693,10 @@ for(i=0;itmdlast) & (TMDNUM-1); - p->tmdhead[i].u.buffer = buffer[num]; /* status is part of buffer field */ + p->tmdhead[i].u.buffer = (u32) virt_to_bus((char *)buffer[num]); /* status is part of buffer field */ p->tmdhead[i].blen = blen[num]; if(p->tmdhead[i].u.s.status & XMIT_OWN) { - p->tmdnum = (p->tmdnum + 1) & (TMDNUM-1); + p->tmdnum = (p->tmdnum + 1) & (TMDNUM-1); p->xmit_queued = 1; writedatareg(CSR0_TDMD | CSR0_INEA | csr0); } @@ -749,9 +756,9 @@ { struct rmd *rmdp = p->rmdhead + i; #ifdef RCV_VIA_SKB - rmdp->u.buffer = (unsigned long) p->recv_skb[i]->data; + rmdp->u.buffer = (u32) virt_to_bus(p->recv_skb[i]->data); #else - rmdp->u.buffer = (unsigned long) p->recvbounce[i]; + rmdp->u.buffer = (u32) virt_to_bus(p->recvbounce[i]); #endif rmdp->blen = -(R_BUF_SIZE-8); rmdp->mlen = 0; @@ -822,8 +829,8 @@ if(csr0 & CSR0_ERR) { struct priv *p = (struct priv *) dev->priv; - if (debuglevel > 1) - printk("%s: general error: %04x.\n",dev->name,csr0); + if(debuglevel > 1) + printk("%s: general error: %04x.\n",dev->name,csr0); if(csr0 & CSR0_BABL) p->stats.tx_errors++; if(csr0 & CSR0_MISS) { @@ -834,8 +841,8 @@ p->stats.rx_errors++; } if(csr0 & CSR0_MERR) { - if (debuglevel > 1) - printk("%s: Ooops .. memory error: %04x.\n",dev->name,csr0); + if(debuglevel > 1) + printk("%s: Ooops .. memory error: %04x.\n",dev->name,csr0); ni65_stop_start(dev,p); } } @@ -887,7 +894,7 @@ } #endif - if(csr0 & (CSR0_RXON | CSR0_TXON) != (CSR0_RXON | CSR0_TXON) ) { + if( (csr0 & (CSR0_RXON | CSR0_TXON)) != (CSR0_RXON | CSR0_TXON) ) { printk("%s: RX or TX was offline -> restart\n",dev->name); ni65_stop_start(dev,p); } @@ -1024,7 +1031,7 @@ struct sk_buff *skb1 = p->recv_skb[p->rmdnum]; skb_put(skb,R_BUF_SIZE); p->recv_skb[p->rmdnum] = skb; - rmdp->u.buffer = (unsigned long) skb->data; + rmdp->u.buffer = (u32) virt_to_bus(skb->data); skb = skb1; skb_trim(skb,len); } @@ -1068,14 +1075,12 @@ return 1; printk(KERN_ERR "%s: xmitter timed out, try to restart!\n",dev->name); -#if 0 { int i; for(i=0;itmdhead[i].u.s.status); printk("\n"); } -#endif ni65_lance_reinit(dev); dev->tbusy=0; dev->trans_start = jiffies; @@ -1115,7 +1120,7 @@ cli(); tmdp = p->tmdhead + p->tmdnum; - tmdp->u.buffer = (unsigned long ) p->tmdbounce[p->tmdbouncenum]; + tmdp->u.buffer = (u32) virt_to_bus(p->tmdbounce[p->tmdbouncenum]); p->tmdbouncenum = (p->tmdbouncenum + 1) & (TMDNUM - 1); #ifdef XMT_VIA_SKB @@ -1125,7 +1130,7 @@ cli(); tmdp = p->tmdhead + p->tmdnum; - tmdp->u.buffer = (unsigned long) skb->data; + tmdp->u.buffer = (u32) virt_to_bus(skb->data); p->tmd_skb[p->tmdnum] = skb; } #endif @@ -1178,9 +1183,9 @@ 0, 0, 0, NULL, ni65_probe }; /* set: io,irq,dma or set it when calling insmod */ -int irq=0; -int io=0; -int dma=0; +static int irq=0; +static int io=0; +static int dma=0; int init_module(void) { diff -u --recursive --new-file v2.0.24/linux/drivers/net/ni65.h linux/drivers/net/ni65.h --- v2.0.24/linux/drivers/net/ni65.h Thu Oct 31 12:08:52 1996 +++ linux/drivers/net/ni65.h Fri Nov 1 23:07:23 1996 @@ -1,6 +1,6 @@ /* am7990 (lance) definitions * - * This is a extension to the Linux operating system, and is covered by + * This is an extension to the Linux operating system, and is covered by * same Gnu Public License that covers that work. * * Michael Hipp @@ -92,16 +92,16 @@ unsigned char eaddr[6]; unsigned char filter[8]; /* bit 29-31: number of rmd's (power of 2) */ - unsigned long rrp; /* receive ring pointer (align 8) */ + u32 rrp; /* receive ring pointer (align 8) */ /* bit 29-31: number of tmd's (power of 2) */ - unsigned long trp; /* transmit ring pointer (align 8) */ + u32 trp; /* transmit ring pointer (align 8) */ }; struct rmd /* Receive Message Descriptor */ { union { - volatile unsigned long buffer; + volatile u32 buffer; struct { volatile unsigned char dummy[3]; @@ -116,7 +116,7 @@ { union { - volatile unsigned long buffer; + volatile u32 buffer; struct { volatile unsigned char dummy[3]; diff -u --recursive --new-file v2.0.24/linux/drivers/net/tulip.c linux/drivers/net/tulip.c --- v2.0.24/linux/drivers/net/tulip.c Thu Oct 31 12:08:52 1996 +++ linux/drivers/net/tulip.c Fri Nov 1 13:59:05 1996 @@ -1145,7 +1145,7 @@ tp->tx_skbuff[entry] = 0; /* Put the setup frame on the Tx list. */ tp->tx_ring[entry].length = 192 | - (entry == TX_RING_SIZE-1 ? 0x0a000000 : 0x08000); + (entry == TX_RING_SIZE-1 ? 0x0a000000 : 0x08000000); tp->tx_ring[entry].buffer1 = virt_to_bus((char *)tp->setup_frame); tp->tx_ring[entry].buffer2 = 0; tp->tx_ring[entry].status = TRING_OWN; diff -u --recursive --new-file v2.0.24/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.0.24/linux/drivers/pci/pci.c Sat Oct 19 10:06:10 1996 +++ linux/drivers/pci/pci.c Wed Nov 6 12:12:35 1996 @@ -70,6 +70,7 @@ DEVICE( DEC, DEC_FDDI, "DEFPA"), DEVICE( DEC, DEC_TULIP_PLUS, "DC21041"), DEVICE( DEC, DEC_21052_AB, "DC21052-AB"), + DEVICE( DEC, DEC_21152_AA, "DC21152-AA"), DEVICE( CIRRUS, CIRRUS_5430, "GD 5430"), DEVICE( CIRRUS, CIRRUS_5434_4, "GD 5434"), DEVICE( CIRRUS, CIRRUS_5434_8, "GD 5434"), diff -u --recursive --new-file v2.0.24/linux/drivers/sbus/char/sunkbd.c linux/drivers/sbus/char/sunkbd.c --- v2.0.24/linux/drivers/sbus/char/sunkbd.c Sat May 4 19:39:23 1996 +++ linux/drivers/sbus/char/sunkbd.c Thu Nov 7 11:25:21 1996 @@ -735,8 +735,9 @@ #define A_CFLEX '^' #define A_TILDE '~' #define A_DIAER '"' -static unsigned char ret_diacr[] = - {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER }; +#define A_CEDIL ',' +static unsigned char ret_diacr[NR_DEAD] = + {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL }; /* If a dead key pressed twice, output a character corresponding to it, */ /* otherwise just remember the dead key. */ diff -u --recursive --new-file v2.0.24/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c --- v2.0.24/linux/drivers/scsi/aha1542.c Mon Aug 5 10:13:52 1996 +++ linux/drivers/scsi/aha1542.c Thu Nov 7 11:25:21 1996 @@ -1027,7 +1027,7 @@ shpnt->dma_channel = dma_chan; shpnt->irq = irq_level; HOSTDATA(shpnt)->bios_translation = trans; - if(trans == 2) + if(trans == BIOS_TRANSLATION_25563) printk("aha1542.c: Using extended bios translation\n"); HOSTDATA(shpnt)->aha1542_last_mbi_used = (2*AHA1542_MAILBOXES - 1); HOSTDATA(shpnt)->aha1542_last_mbo_used = (AHA1542_MAILBOXES - 1); @@ -1300,8 +1300,8 @@ int size = disk->capacity; translation_algorithm = HOSTDATA(disk->device->host)->bios_translation; - /* Should this be > 1024, or >= 1024? Enquiring minds want to know. */ - if((size>>11) > 1024 && translation_algorithm == 2) { + + if((size>>11) > 1024 && translation_algorithm == BIOS_TRANSLATION_25563) { /* Please verify that this is the same as what DOS returns */ ip[0] = 255; ip[1] = 63; @@ -1310,8 +1310,8 @@ ip[0] = 64; ip[1] = 32; ip[2] = size >> 11; - }; -/* if (ip[2] >= 1024) ip[2] = 1024; */ + } + return 0; } diff -u --recursive --new-file v2.0.24/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c --- v2.0.24/linux/drivers/scsi/fdomain.c Sat Aug 10 10:03:15 1996 +++ linux/drivers/scsi/fdomain.c Sat Nov 2 16:41:06 1996 @@ -1,6 +1,6 @@ /* fdomain.c -- Future Domain TMC-16x0 SCSI driver * Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu - * Revised: Thu Aug 8 14:58:51 1996 by r.faith@ieee.org + * Revised: Sat Nov 2 09:27:47 1996 by root@cs.unc.edu * Author: Rickard E. Faith, faith@cs.unc.edu * Copyright 1992, 1993, 1994, 1995, 1996 Rickard E. Faith * @@ -461,7 +461,7 @@ { "IBM F1 P2 BIOS v1.0104/29/93", 5, 28, 3, -1, 0 }, { "Future Domain Corp. V1.0008/18/93", 5, 33, 3, 4, 0 }, { "Future Domain Corp. V1.0008/18/93", 26, 33, 3, 4, 1 }, - { "Adaptec AHA-2920 PCI-SCSI Card", 42, 31, 3, 0, 1 }, + { "Adaptec AHA-2920 PCI-SCSI Card", 42, 31, 3, -1, 1 }, /* This next signature may not be a 3.5 bios */ { "Future Domain Corp. V2.0108/18/93", 5, 33, 3, 5, 0 }, { "FUTURE DOMAIN CORP. V3.5008/18/93", 5, 34, 3, 5, 0 }, diff -u --recursive --new-file v2.0.24/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c --- v2.0.24/linux/drivers/scsi/hosts.c Thu Oct 31 12:08:53 1996 +++ linux/drivers/scsi/hosts.c Wed Oct 30 12:45:53 1996 @@ -224,12 +224,6 @@ #ifdef CONFIG_SCSI_ADVANSYS ADVANSYS, #endif -#ifdef CONFIG_SCSI_EATA_DMA - EATA_DMA, -#endif -#ifdef CONFIG_SCSI_EATA_PIO - EATA_PIO, -#endif /* BusLogic must come before aha1542.c */ #ifdef CONFIG_SCSI_BUSLOGIC BUSLOGIC, @@ -287,6 +281,12 @@ #endif #ifdef CONFIG_SCSI_NCR53C8XX NCR53C8XX, +#endif +#ifdef CONFIG_SCSI_EATA_DMA + EATA_DMA, +#endif +#ifdef CONFIG_SCSI_EATA_PIO + EATA_PIO, #endif #ifdef CONFIG_SCSI_7000FASST WD7000, diff -u --recursive --new-file v2.0.24/linux/drivers/scsi/scsicam.c linux/drivers/scsi/scsicam.c --- v2.0.24/linux/drivers/scsi/scsicam.c Mon Aug 5 10:13:52 1996 +++ linux/drivers/scsi/scsicam.c Thu Nov 7 11:25:21 1996 @@ -54,22 +54,28 @@ if (!(bh = bread(MKDEV(MAJOR(dev), MINOR(dev)&~0xf), 0, 1024))) return -1; -#ifdef DEBUG - printk ("scsicam_bios_param : trying existing mapping\n"); -#endif + /* try to infer mapping from partition table */ ret_code = partsize (bh, (unsigned long) size, (unsigned int *) ip + 2, (unsigned int *) ip + 0, (unsigned int *) ip + 1); brelse (bh); if (ret_code == -1) { -#ifdef DEBUG - printk ("scsicam_bios_param : trying optimal mapping\n"); -#endif + /* pick some standard mapping with at most 1024 cylinders, + and at most 62 sectors per track - this works up to + 7905 MB */ ret_code = setsize ((unsigned long) size, (unsigned int *) ip + 2, (unsigned int *) ip + 0, (unsigned int *) ip + 1); } - return ret_code; + /* if something went wrong, then apparently we have to return + a geometry with more than 1024 cylinders */ + if (ret_code || ip[0] > 255 || ip[1] > 63) { + ip[0] = 64; + ip[1] = 32; + ip[2] = size / (ip[0] * ip[1]); + } + + return 0; } /* diff -u --recursive --new-file v2.0.24/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c --- v2.0.24/linux/fs/smbfs/inode.c Wed Sep 11 17:57:16 1996 +++ linux/fs/smbfs/inode.c Thu Nov 7 14:41:14 1996 @@ -126,7 +126,7 @@ struct smb_inode_info *info = SMB_INOP(inode); int opened = finfo->opened; - int mtime = finfo->mtime; + int mtime = inode->i_mtime; int file_id = finfo->fileid; int isdir = S_ISDIR(inode->i_mode); unsigned long ino = inode->i_ino; diff -u --recursive --new-file v2.0.24/linux/include/linux/keyboard.h linux/include/linux/keyboard.h --- v2.0.24/linux/include/linux/keyboard.h Sun Oct 8 12:37:07 1995 +++ linux/include/linux/keyboard.h Thu Nov 7 11:25:22 1996 @@ -352,8 +352,9 @@ #define K_DCIRCM K(KT_DEAD,2) #define K_DTILDE K(KT_DEAD,3) #define K_DDIERE K(KT_DEAD,4) +#define K_DCEDIL K(KT_DEAD,5) -#define NR_DEAD 5 +#define NR_DEAD 6 #define K_DOWN K(KT_CUR,0) #define K_LEFT K(KT_CUR,1) diff -u --recursive --new-file v2.0.24/linux/include/linux/locks.h linux/include/linux/locks.h --- v2.0.24/linux/include/linux/locks.h Thu Jul 25 20:26:46 1996 +++ linux/include/linux/locks.h Thu Nov 7 14:02:23 1996 @@ -28,7 +28,7 @@ extern inline void lock_buffer(struct buffer_head * bh) { - if (set_bit(BH_Lock, &bh->b_state)) + while (set_bit(BH_Lock, &bh->b_state)) __wait_on_buffer(bh); } diff -u --recursive --new-file v2.0.24/linux/include/linux/pci.h linux/include/linux/pci.h --- v2.0.24/linux/include/linux/pci.h Sat Oct 19 10:06:12 1996 +++ linux/include/linux/pci.h Wed Nov 6 12:12:35 1996 @@ -265,6 +265,7 @@ #define PCI_DEVICE_ID_DEC_FDDI 0x000F #define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014 #define PCI_DEVICE_ID_DEC_21052_AB 0x0021 +#define PCI_DEVICE_ID_DEC_21152_AA 0x0024 #define PCI_VENDOR_ID_CIRRUS 0x1013 #define PCI_DEVICE_ID_CIRRUS_5430 0x00a0 diff -u --recursive --new-file v2.0.24/linux/include/net/sock.h linux/include/net/sock.h --- v2.0.24/linux/include/net/sock.h Thu Oct 31 12:08:54 1996 +++ linux/include/net/sock.h Thu Nov 7 11:35:28 1996 @@ -252,8 +252,8 @@ unsigned char max_ack_backlog; unsigned char priority; unsigned char debug; - unsigned int rcvbuf; - unsigned int sndbuf; + int rcvbuf; + int sndbuf; unsigned short type; unsigned char localroute; /* Route locally only */ #ifdef CONFIG_AX25 diff -u --recursive --new-file v2.0.24/linux/kernel/fork.c linux/kernel/fork.c --- v2.0.24/linux/kernel/fork.c Tue Oct 8 21:20:14 1996 +++ linux/kernel/fork.c Thu Nov 7 11:25:22 1996 @@ -253,7 +253,7 @@ p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0; init_timer(&p->real_timer); p->real_timer.data = (unsigned long) p; - p->leader = 0; /* process leadership doesn't inherit */ + p->leader = 0; /* session leadership doesn't inherit */ p->tty_old_pgrp = 0; p->utime = p->stime = 0; p->cutime = p->cstime = 0; diff -u --recursive --new-file v2.0.24/linux/net/bridge/br.c linux/net/bridge/br.c --- v2.0.24/linux/net/bridge/br.c Tue Oct 8 21:20:14 1996 +++ linux/net/bridge/br.c Fri Nov 8 08:44:27 1996 @@ -267,7 +267,7 @@ (((port_info[port_no].designated_cost + port_info[port_no].path_cost ) - == + < (port_info[root_port].designated_cost + port_info[root_port].path_cost ) /* (4.6.8.3.1(2)) */ diff -u --recursive --new-file v2.0.24/linux/net/core/dev.c linux/net/core/dev.c --- v2.0.24/linux/net/core/dev.c Thu Oct 31 12:08:55 1996 +++ linux/net/core/dev.c Wed Nov 6 14:39:47 1996 @@ -1110,7 +1110,7 @@ #ifdef CONFIG_NET_ALIAS if (net_alias_is(dev)) - net_alias_dev_rehash(dev ,&ifr.ifr_addr); + net_alias_dev_rehash(dev ,&ifr.ifr_addr); #endif dev->pa_addr = new_pa_addr; dev->family = new_family; @@ -1200,7 +1200,7 @@ case SIOCSIFMTU: /* Set the MTU of a device */ if (dev->change_mtu) - ret = (*dev->change_mtu)(dev, ifr.ifr_mtu); + ret = dev->change_mtu(dev, ifr.ifr_mtu); else { /* @@ -1367,7 +1367,6 @@ * */ extern int lance_init(void); -extern int ni65_init(void); extern int pi_init(void); extern void sdla_setup(void); extern int dlci_setup(void); @@ -1397,9 +1396,6 @@ */ #if defined(CONFIG_LANCE) lance_init(); -#endif -#if defined(CONFIG_NI65) - ni65_init(); #endif #if defined(CONFIG_PI) pi_init(); diff -u --recursive --new-file v2.0.24/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c --- v2.0.24/linux/net/ipv4/icmp.c Thu Oct 31 12:08:55 1996 +++ linux/net/ipv4/icmp.c Wed Nov 6 14:39:47 1996 @@ -38,6 +38,7 @@ * path MTU bug. * Thomas Quinot : ICMP Dest Unreach codes up to 15 are * valid (RFC 1812). + * Alan Cox : Spoofing and junk icmp protections. * * * RFC1122 (Host Requirements -- Comm. Layer) Status: @@ -639,6 +640,7 @@ int hash; struct inet_protocol *ipprot; unsigned char *dp; + int match_addr=0; iph = (struct iphdr *) (icmph + 1); @@ -655,8 +657,9 @@ case ICMP_PROT_UNREACH: /* printk(KERN_INFO "ICMP: %s:%d: protocol unreachable.\n", in_ntoa(iph->daddr), (int)iph->protocol);*/ - break; + /* Drop through */ case ICMP_PORT_UNREACH: + match_addr=1; break; case ICMP_FRAG_NEEDED: #ifdef CONFIG_NO_PATH_MTU_DISCOVERY @@ -747,42 +750,46 @@ * RFC 1122: 3.2.2 MUST extract the protocol ID from the passed header. * RFC 1122: 3.2.2.1 MUST pass ICMP unreach messages to the transport layer. * RFC 1122: 3.2.2.2 MUST pass ICMP time expired messages to transport layer. - */ - - /* - * Get the protocol(s). - */ - - hash = iph->protocol & (MAX_INET_PROTOS -1); - - /* - * This can't change while we are doing it. * - * FIXME: Deliver to appropriate raw sockets too. + * Rule: Require port unreachable and protocol unreachable come + * from the host in question. Stop junk spoofs. */ - - ipprot = (struct inet_protocol *) inet_protos[hash]; - while(ipprot != NULL) - { - struct inet_protocol *nextip; - - nextip = (struct inet_protocol *) ipprot->next; - /* - * Pass it off to everyone who wants it. + if(!match_addr || saddr == iph->daddr) + { + /* + * Get the protocol(s). */ + + hash = iph->protocol & (MAX_INET_PROTOS -1); - /* RFC1122: OK. Passes appropriate ICMP errors to the */ - /* appropriate protocol layer (MUST), as per 3.2.2. */ - - if (iph->protocol == ipprot->protocol && ipprot->err_handler) + /* + * This can't change while we are doing it. + */ + + ipprot = (struct inet_protocol *) inet_protos[hash]; + while(ipprot != NULL) { - ipprot->err_handler(icmph->type, icmph->code, dp, + struct inet_protocol *nextip; + + nextip = (struct inet_protocol *) ipprot->next; + + /* + * Pass it off to everyone who wants it. + */ + + /* RFC1122: OK. Passes appropriate ICMP errors to the */ + /* appropriate protocol layer (MUST), as per 3.2.2. */ + + if (iph->protocol == ipprot->protocol && ipprot->err_handler) + { + ipprot->err_handler(icmph->type, icmph->code, dp, iph->daddr, iph->saddr, ipprot); - } + } - ipprot = nextip; - } + ipprot = nextip; + } + } kfree_skb(skb, FREE_READ); } diff -u --recursive --new-file v2.0.24/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c --- v2.0.24/linux/net/ipv4/tcp.c Sat Oct 19 10:06:12 1996 +++ linux/net/ipv4/tcp.c Wed Nov 6 14:39:47 1996 @@ -2058,21 +2058,6 @@ sk->mtu = min(sk->mtu, dev->mtu - sizeof(struct iphdr) - sizeof(struct tcphdr)); -#ifdef CONFIG_SKIP - - /* - * SKIP devices set their MTU to 65535. This is so they can take packets - * unfragmented to security process then fragment. They could lie to the - * TCP layer about a suitable MTU, but it's easier to let skip sort it out - * simply because the final package we want unfragmented is going to be - * - * [IPHDR][IPSP][Security data][Modified TCP data][Security data] - */ - - if(skip_pick_mtu!=NULL) /* If SKIP is loaded.. */ - sk->mtu=skip_pick_mtu(sk->mtu,dev); -#endif - /* * Put in the TCP options to say MTU. */