## Automatically generated incremental diff ## From: linux-2.0.32-pre2 ## To: linux-2.0.32-pre5 ## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $ diff -urN linux-2.0.32-pre2/arch/i386/kernel/head.S linux-2.0.32-pre5/arch/i386/kernel/head.S --- linux-2.0.32-pre2/arch/i386/kernel/head.S 1997-08-05 09:19:53.000000000 -0700 +++ linux-2.0.32-pre5/arch/i386/kernel/head.S 2003-08-15 15:04:17.000000000 -0700 @@ -260,7 +260,7 @@ movw %dx,%ax /* selector = 0x0010 = cs */ movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ - lea SYMBOL_NAME(idt),%edi + lea SYMBOL_NAME(__idt),%edi mov $256,%ecx rp_sidt: movl %eax,(%edi) @@ -376,9 +376,9 @@ .word 0 idt_descr: .word 256*8-1 # idt contains 256 entries - .long 0xc0000000+SYMBOL_NAME(idt) + .long 0xc0000000+SYMBOL_NAME(__idt) -ENTRY(idt) +ENTRY(__idt) .fill 256,8,0 # idt is uninitialized ALIGN diff -urN linux-2.0.32-pre2/arch/i386/kernel/setup.c linux-2.0.32-pre5/arch/i386/kernel/setup.c --- linux-2.0.32-pre2/arch/i386/kernel/setup.c 1996-09-20 07:00:34.000000000 -0700 +++ linux-2.0.32-pre5/arch/i386/kernel/setup.c 2003-08-15 15:04:17.000000000 -0700 @@ -42,6 +42,7 @@ char x86_mask = 0; /* set by kernel/head.S */ int x86_capability = 0; /* set by kernel/head.S */ int fdiv_bug = 0; /* set if Pentium(TM) with FP bug */ +int pentium_f00f_bug = 0; /* set if Pentium(TM) with F00F bug */ int have_cpuid = 0; /* set if CPUID instruction works */ char x86_vendor_id[13] = "unknown"; @@ -306,6 +307,7 @@ len += sprintf(buffer+len, "fdiv_bug\t: %s\n" "hlt_bug\t\t: %s\n" + "f00f_bug\t\t: %s\n" "fpu\t\t: %s\n" "fpu_exception\t: %s\n" "cpuid\t\t: %s\n" @@ -313,6 +315,7 @@ "flags\t\t:", CD(fdiv_bug) ? "yes" : "no", CD(hlt_works_ok) ? "no" : "yes", + pentium_f00f_bug ? "yes" : "no", CD(hard_math) ? "yes" : "no", (CD(hard_math) && ignore_irq13) ? "yes" : "no", diff -urN linux-2.0.32-pre2/arch/i386/kernel/smp.c linux-2.0.32-pre5/arch/i386/kernel/smp.c --- linux-2.0.32-pre2/arch/i386/kernel/smp.c 1997-08-11 13:42:11.000000000 -0700 +++ linux-2.0.32-pre5/arch/i386/kernel/smp.c 2003-08-15 15:04:17.000000000 -0700 @@ -537,7 +537,13 @@ extern void calibrate_delay(void); int cpuid=GET_APIC_ID(apic_read(APIC_ID)); unsigned long l; + extern struct desc_struct idt_descriptor; + extern int pentium_f00f_bug; + if (pentium_f00f_bug) { + __asm__ __volatile__("\tlidt %0": "=m" (idt_descriptor)); + } + /* * Activate our APIC */ diff -urN linux-2.0.32-pre2/arch/i386/kernel/traps.c linux-2.0.32-pre5/arch/i386/kernel/traps.c --- linux-2.0.32-pre2/arch/i386/kernel/traps.c 1997-08-11 13:37:24.000000000 -0700 +++ linux-2.0.32-pre5/arch/i386/kernel/traps.c 2003-08-15 15:04:17.000000000 -0700 @@ -24,6 +24,7 @@ #include #include #include +#include asmlinkage int system_call(void); asmlinkage void lcall7(void); @@ -336,6 +337,49 @@ #endif /* CONFIG_MATH_EMULATION */ +struct desc_struct *idt = __idt+0; +struct { + unsigned short limit; + unsigned long addr __attribute__((packed)); +} idt_descriptor; + +void trap_init_f00f_bug(void) +{ + pgd_t * pgd; + pmd_t * pmd; + pte_t * pte; + unsigned long twopage; + struct desc_struct *new_idt; + + printk("moving IDT ... "); + + twopage = (unsigned long) vmalloc (2*PAGE_SIZE); + + new_idt = (void *)(twopage + 4096-7*8); + + memcpy(new_idt,idt,256*8); + + idt_descriptor.limit = 256*8-1; + idt_descriptor.addr = VMALLOC_VMADDR(new_idt); + + __asm__ __volatile__("\tlidt %0": "=m" (idt_descriptor)); + idt = new_idt; + + /* + * Unmap lower page: + */ + twopage = VMALLOC_VMADDR(twopage); + pgd = pgd_offset(current->mm, twopage); + pmd = pmd_offset(pgd, twopage); + pte = pte_offset(pmd, twopage); + + pte_clear(pte); + flush_tlb_all(); + + printk(" ... done\n"); +} + + void trap_init(void) { int i; diff -urN linux-2.0.32-pre2/arch/i386/mm/fault.c linux-2.0.32-pre5/arch/i386/mm/fault.c --- linux-2.0.32-pre2/arch/i386/mm/fault.c 1997-08-16 22:21:20.000000000 -0700 +++ linux-2.0.32-pre5/arch/i386/mm/fault.c 2003-08-15 15:04:17.000000000 -0700 @@ -21,6 +21,16 @@ extern void die_if_kernel(const char *,struct pt_regs *,long); +asmlinkage void do_divide_error (struct pt_regs *, unsigned long); +asmlinkage void do_debug (struct pt_regs *, unsigned long); +asmlinkage void do_nmi (struct pt_regs *, unsigned long); +asmlinkage void do_int3 (struct pt_regs *, unsigned long); +asmlinkage void do_overflow (struct pt_regs *, unsigned long); +asmlinkage void do_bounds (struct pt_regs *, unsigned long); +asmlinkage void do_invalid_op (struct pt_regs *, unsigned long); + +extern int pentium_f00f_bug; + /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate @@ -117,6 +127,30 @@ force_sig(SIGSEGV, tsk); return; } + + /* + * Pentium F0 0F C7 C8 bug workaround: + */ + if ( pentium_f00f_bug ) { + unsigned long nr; + + nr = (address - TASK_SIZE - (unsigned long) idt) >> 3; + + if (nr < 7) { + static void (*handler[])(struct pt_regs *, unsigned long) = { + do_divide_error, /* 0 - divide overflow */ + do_debug, /* 1 - debug trap */ + do_nmi, /* 2 - NMI */ + do_int3, /* 3 - int 3 */ + do_overflow, /* 4 - overflow */ + do_bounds, /* 5 - bound range */ + do_invalid_op }; /* 6 - invalid opcode */ + handler[nr](regs, error_code); + return; + } + } + + /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. diff -urN linux-2.0.32-pre2/CREDITS linux-2.0.32-pre5/CREDITS --- linux-2.0.32-pre2/CREDITS 2003-08-15 15:04:16.000000000 -0700 +++ linux-2.0.32-pre5/CREDITS 2003-08-15 15:04:17.000000000 -0700 @@ -868,7 +868,7 @@ N: John A. Martin E: jam@acm.org -W: http://linux.wauug.org/~jam/ +W: http://www.tux.org/~jam/ P: 1024/04456D53 9D A3 6C 6B 88 80 8A 61 D7 06 22 4F 95 40 CE D2 P: 1024/3B986635 5A61 7EE6 9E20 51FB 59FB 2DA5 3E18 DD55 3B98 6635 D: FSSTND contributor @@ -1031,9 +1031,10 @@ S: Germany N: David C. Niemi -E: niemi@erols.com +E: niemi@tux.org +W: http://www.tux.org/~niemi/ D: Assistant maintainer of Mtools, fdutils, and floppy driver -D: Administrator of WAUUG Linux Server, http://linux.wauug.org +D: Administrator of Tux.Org Linux Server, http://www.tux.org S: 2364 Old Trail Drive S: Reston, Virginia 20191 S: USA diff -urN linux-2.0.32-pre2/drivers/net/3c59x.c linux-2.0.32-pre5/drivers/net/3c59x.c --- linux-2.0.32-pre2/drivers/net/3c59x.c 1997-09-15 09:45:39.000000000 -0700 +++ linux-2.0.32-pre5/drivers/net/3c59x.c 2003-08-15 15:04:17.000000000 -0700 @@ -15,7 +15,7 @@ */ static char *version = -"3c59x.c:v0.44 9/9/97 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n"; +"3c59x.c:v0.46C 10/14/97 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n"; /* "Knobs" that adjust features and parameters. */ /* Set the copy breakpoint for the copy-only-tiny-frames scheme. @@ -24,7 +24,7 @@ /* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */ static const mtu = 1500; /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ -static const max_interrupt_work = 12; +static int max_interrupt_work = 20; /* Enable the automatic media selection code -- usually set. */ #define AUTOMEDIA 1 @@ -113,6 +113,14 @@ #if (LINUX_VERSION_CODE < 0x20123) #define test_and_set_bit(val, addr) set_bit(val, addr) +#else +MODULE_AUTHOR("Donald Becker "); +MODULE_DESCRIPTION("3Com 3c590/3c900 series Vortex/Boomerang driver"); +MODULE_PARM(debug, "i"); +MODULE_PARM(options, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(rx_copybreak, "i"); +MODULE_PARM(max_interrupt_work, "i"); #endif /* "Knobs" for adjusting internal parameters. */ @@ -717,7 +725,7 @@ /* Read the station address from the EEPROM. */ EL3WINDOW(0); for (i = 0; i < 0x18; i++) { - short *phys_addr = (short *)dev->dev_addr; + u16 *phys_addr = (u16 *)dev->dev_addr; int timer; outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd); /* Pause for at least 162 us. for the read to take place. */ @@ -1076,7 +1084,7 @@ outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ /* Allow status bits to be seen. */ - outw(SetStatusEnb | AdapterFailure|IntReq|StatsFull | + outw(SetStatusEnb | AdapterFailure|IntReq|StatsFull|TxComplete| (vp->full_bus_master_tx ? DownComplete : TxAvailable) | (vp->full_bus_master_rx ? UpComplete : RxComplete) | (vp->bus_master ? DMADone : 0), @@ -1085,7 +1093,7 @@ outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, ioaddr + EL3_CMD); outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull - | AdapterFailure + | AdapterFailure | TxComplete | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete, ioaddr + EL3_CMD); @@ -1389,7 +1397,8 @@ int entry = vp->cur_tx % TX_RING_SIZE; struct boom_tx_desc *prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE]; - unsigned long flags, i; + unsigned long flags; + int i; if (vortex_debug > 3) printk("%s: Trying to send a packet, Tx index %d.\n", @@ -1492,10 +1501,15 @@ mark_bh(NET_BH); } if (status & TxComplete) { /* Really "TxError" for us. */ + unsigned char tx_status = inb(ioaddr + TxStatus); /* Presumably a tx-timeout. We must merely re-enable. */ - if (vortex_debug > 0) - printk("%s: Host error, Tx status register %2.2x.\n", - dev->name, inb(TxStatus)); + if (vortex_debug > 2 + || (tx_status != 0x88 && vortex_debug > 0)) + printk("%s: Transmit error, Tx status register %2.2x.\n", + dev->name, tx_status); + if (tx_status & 0x04) lp->stats.tx_fifo_errors++; + if (tx_status & 0x38) lp->stats.tx_aborted_errors++; + outb(0, ioaddr + TxStatus); outw(TxEnable, ioaddr + EL3_CMD); } if (status & DownComplete) { @@ -1559,7 +1573,8 @@ } EL3WINDOW(7); outw(SetIntrEnb | TxAvailable | RxComplete | AdapterFailure - | UpComplete | DownComplete, ioaddr + EL3_CMD); + | UpComplete | DownComplete | TxComplete, + ioaddr + EL3_CMD); DoneDidThat++; } } @@ -1590,7 +1605,7 @@ } if (--i < 0) { - printk("%s: Infinite loop in interrupt, status %4.4x. " + printk("%s: Too much work in interrupt, status %4.4x. " "Disabling functions (%4.4x).\n", dev->name, status, SetStatusEnb | ((~status) & 0x7FE)); /* Disable all pending interrupts. */ @@ -1925,7 +1940,7 @@ static void set_rx_mode(struct device *dev) { - short ioaddr = dev->base_addr; + int ioaddr = dev->base_addr; short new_mode; if (dev->flags & IFF_PROMISC) { diff -urN linux-2.0.32-pre2/drivers/scsi/aic7xxx/aic7xxx.reg linux-2.0.32-pre5/drivers/scsi/aic7xxx/aic7xxx.reg --- linux-2.0.32-pre2/drivers/scsi/aic7xxx/aic7xxx.reg 1997-09-22 14:53:10.000000000 -0700 +++ linux-2.0.32-pre5/drivers/scsi/aic7xxx/aic7xxx.reg 2003-08-15 15:04:17.000000000 -0700 @@ -1091,13 +1091,14 @@ * the QOUTFIFO. This is cleared by the * kernel driver every FIFODEPTH commands. * - * NOTE: these scratch RAM registers are *only* used on cards - * that enable SCB paging. The 2742 is unable to page. We - * won't use these on a 2742, and we can't init these registers - * in the kernel driver for 2742 cards because these locations are - * are used by the 2742 cards to control things like bus - * termination. Touching these memory locations is a no-no on all - * non-paging cards as far as we are concerned. + * NOTE: These scratch RAM registers are overlaying SCSICONF + * and SCSICONF2 and are only used on cards that are + * capable of SCB paging. Currently, only the PCI + * controllers can do this, which is good because the + * AIC-7770 based controllers use the SCSICONF register + * to control termination. In other words, do not + * destroy the contents of SCSICONF and SCSICONF2 for + * AIC-7770 based controllers. */ CMDOUTCNT { size 1 diff -urN linux-2.0.32-pre2/drivers/scsi/aic7xxx.c linux-2.0.32-pre5/drivers/scsi/aic7xxx.c --- linux-2.0.32-pre2/drivers/scsi/aic7xxx.c 1997-09-22 14:53:09.000000000 -0700 +++ linux-2.0.32-pre5/drivers/scsi/aic7xxx.c 2003-08-15 15:04:17.000000000 -0700 @@ -147,6 +147,8 @@ #define ALL_TARGETS -1 #define ALL_CHANNELS '\0' #define ALL_LUNS -1 +#define MAX_TARGETS 16 +#define MAX_LUNS 8 #ifndef TRUE # define TRUE 1 #endif @@ -301,7 +303,7 @@ #ifdef AIC7XXX_TAGGED_QUEUEING_BY_DEVICE typedef struct { - char tag_commands[16]; /* Allow for wide/twin channel adapters. */ + unsigned char tag_commands[16]; /* Allow for wide/twin channel adapters. */ } adapter_tag_info_t; /* @@ -871,7 +873,7 @@ long r_total; /* total reads */ long r_total512; /* 512 byte blocks read */ long r_bins[10]; /* binned reads */ - } stats[16][8]; /* channel, target, lun */ + } stats[MAX_TARGETS][MAX_LUNS]; /* [(channel << 3)|target][lun] */ #endif /* AIC7XXX_PROC_STATS */ }; @@ -968,13 +970,8 @@ * These functions are not used yet, but when we do memory mapped * IO, we'll use them then. * - * For now we leave these commented out as the x86 inline assembly causes - * compiles to barf on DEC Alphas. Besides, they aren't even used yet, so - * they constitute wasted .text space right now. ***************************************************************************/ -/*************************************************************************** - static inline unsigned char aic_inb(struct aic7xxx_host *p, long port) { @@ -998,22 +995,30 @@ { if (p->maddr != NULL) { +#ifdef __alpha__ + int i; + + for (i=0; i < size; i++) + { + p->maddr[port] = valp[i]; + } +#else __asm __volatile(" cld; 1: lodsb; movb %%al,(%0); loop 1b" : : - "r" ((p)->maddr + (port)), - "S" ((valp)), "c" ((size)) : + "r" (p->maddr + port), + "S" (valp), "c" (size) : "%esi", "%ecx", "%eax"); +#endif } else { outsb(p->base + port, valp, size); } } - ***************************************************************************/ /*+F************************************************************************* * Function: @@ -1443,10 +1448,10 @@ unsigned char ultra_enb, sxfrctl0; /* - * If the offset is 0, then the device is requesting asynchronous + * If the period is 0, then the device is requesting asynchronous * transfers. */ - if ((*period >= aic7xxx_syncrates[i].period) && *offset != 0) + if (*period != 0) { for (i = 0; i < num_aic7xxx_syncrates; i++) { @@ -1977,15 +1982,38 @@ if ((scb->flags & (SCB_MSGOUT_WDTR | SCB_MSGOUT_SDTR)) != 0) { unsigned short mask; + int message_error = FALSE; mask = 0x01 << TARGET_INDEX(scb->cmd); + + /* + * Check to see if we get an invalid message or a message error + * after failing to negotiate a wide or sync transfer message. + */ + if ((scb->flags & SCB_SENSE) && + ((scb->cmd->sense_buffer[12] == 0x43) || /* INVALID_MESSAGE */ + (scb->cmd->sense_buffer[12] == 0x49))) /* MESSAGE_ERROR */ + { + message_error = TRUE; + } + if (scb->flags & SCB_MSGOUT_WDTR) { p->wdtr_pending &= ~mask; + if (message_error) + { + p->needwdtr &= ~mask; + p->needwdtr_copy &= ~mask; + } } if (scb->flags & SCB_MSGOUT_SDTR) { p->sdtr_pending &= ~mask; + if (message_error) + { + p->needsdtr &= ~mask; + p->needsdtr_copy &= ~mask; + } } } aic7xxx_free_scb(p, scb); @@ -2009,7 +2037,7 @@ long *ptr; int x; - sp = &p->stats[((cmd->channel << 3) | cmd->target) & 0xf][cmd->lun & 0x7]; + sp = &p->stats[TARGET_INDEX(cmd)][cmd->lun & 0x7]; sp->xfers++; if (cmd->request.cmd == WRITE) @@ -3097,6 +3125,8 @@ } else { + int send_reject = FALSE; + /* * Send our own WDTR in reply. */ @@ -3119,14 +3149,25 @@ { bus_width = BUS_8_BIT; scratch &= 0x7F; /* XXX - FreeBSD doesn't do this. */ + send_reject = TRUE; } break; default: break; } - aic7xxx_construct_wdtr(p, /* start byte */ 0, bus_width); - outb(SEND_MSG, p->base + RETURN_1); + if (send_reject) + { + outb(SEND_REJ, p->base + RETURN_1); + printk(KERN_WARNING "scsi%d: Target %d, channel %c, initiating " + "wide negotiation on a narrow bus - rejecting!\n", + p->host_no, target, channel); + } + else + { + aic7xxx_construct_wdtr(p, /* start byte */ 0, bus_width); + outb(SEND_MSG, p->base + RETURN_1); + } } p->needwdtr &= ~target_mask; outb(scratch, p->base + TARG_SCRATCH + scratch_offset); @@ -5314,6 +5355,12 @@ */ outb(p->qcntmask, p->base + QCNTMASK); + /* + * Set FIFO depth and command out count. These are only used when + * paging is enabled and should not be touched for AIC-7770 based + * adapters; FIFODEPTH and CMDOUTCNT overlay SCSICONF and SCSICONF+1 + * which are used to control termination. + */ if (p->flags & PAGE_ENABLED) { outb(p->qfullcount, p->base + FIFODEPTH); @@ -5549,7 +5596,6 @@ { case AIC_7770: /* None of these adapters have seeproms. */ case AIC_7771: - case AIC_7850: case AIC_7855: break; @@ -5557,6 +5603,7 @@ have_seeprom = read_284x_seeprom(p, (struct seeprom_config *) scarray); break; + case AIC_7850: /* The 2910B is a 7850 with a seeprom. */ case AIC_7861: case AIC_7870: case AIC_7871: @@ -5666,7 +5713,11 @@ scsi_conf = (p->scsi_id & 0x7); if (sc->adapter_control & CFSPARITY) scsi_conf |= ENSPCHK; - if (sc->adapter_control & CFRESETB) + /* + * The 7850 controllers with a seeprom, do not honor the CFRESETB + * flag in the seeprom. Assume that we want to reset the SCSI bus. + */ + if ((sc->adapter_control & CFRESETB) || (p->chip_class == AIC_7850)) scsi_conf |= RESET_SCSI; if ((p->chip_class == AIC_786x) || (p->chip_class == AIC_788x)) @@ -5799,6 +5850,14 @@ hcntrl = inb(base + HCNTRL) & IRQMS; /* Default */ outb(hcntrl | PAUSE, base + HCNTRL); + p = aic7xxx_alloc(template, base, 0, chip_type, 0, NULL); + if (p == NULL) + { + printk(KERN_WARNING "aic7xxx: Unable to allocate device space.\n"); + continue; + } + aic7xxx_chip_reset(p); + irq = inb(INTDEF + base) & 0x0F; switch (irq) { @@ -5812,19 +5871,14 @@ default: printk(KERN_WARNING "aic7xxx: Host adapter uses unsupported IRQ " - "level, ignoring.\n"); + "level %d, ignoring.\n", irq); irq = 0; + aic7xxx_free(p); break; } if (irq != 0) { - p = aic7xxx_alloc(template, base, 0, chip_type, 0, NULL); - if (p == NULL) - { - printk(KERN_WARNING "aic7xxx: Unable to allocate device space.\n"); - continue; - } p->irq = irq & 0x0F; p->chip_class = AIC_777x; #ifdef AIC7XXX_PAGE_ENABLE @@ -5835,7 +5889,6 @@ { p->flags |= EXTENDED_TRANSLATION; } - aic7xxx_chip_reset(p); switch (p->chip_type) { @@ -5997,7 +6050,6 @@ flags = 0; switch (aic7xxx_pci_devices[i].chip_type) { - case AIC_7850: case AIC_7855: flags |= USE_DEFAULTS; break; @@ -6790,17 +6842,43 @@ int aic7xxx_abort(Scsi_Cmnd *cmd) { +#if 0 struct aic7xxx_scb *scb = NULL; +#endif struct aic7xxx_host *p; +#if 0 int base, result; unsigned long processor_flags; +#endif p = (struct aic7xxx_host *) cmd->host->hostdata; +#if 0 scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]); base = p->base; save_flags(processor_flags); cli(); +#endif + +#if 1 + switch (aic7xxx_reset(cmd, 0) & 0x0f) + { + case SCSI_RESET_SNOOZE: + return(SCSI_ABORT_SNOOZE); + case SCSI_RESET_PENDING: + return(SCSI_ABORT_PENDING); + case SCSI_RESET_SUCCESS: + return(SCSI_ABORT_SUCCESS); + case SCSI_RESET_NOT_RUNNING: + return(SCSI_ABORT_NOT_RUNNING); + case SCSI_RESET_ERROR: + return(SCSI_ABORT_ERROR); + default: + printk(KERN_WARNING "scsi%d Unknown abort/reset return state.\n", + p->host_no); + return(SCSI_ABORT_ERROR); + } /* NOT REACHED */ +#else #ifdef AIC7XXX_DEBUG_ABORT if (scb != NULL) @@ -6872,6 +6950,7 @@ } restore_flags(processor_flags); return (result); +#endif } @@ -6899,7 +6978,7 @@ scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]); base = p->base; channel = cmd->channel ? 'B': 'A'; - tindex = (cmd->channel << 3) | cmd->target; + tindex = TARGET_INDEX(cmd); #ifdef 0 /* AIC7XXX_DEBUG_ABORT */ if (scb != NULL) diff -urN linux-2.0.32-pre2/drivers/scsi/aic7xxx.h linux-2.0.32-pre5/drivers/scsi/aic7xxx.h --- linux-2.0.32-pre2/drivers/scsi/aic7xxx.h 1997-07-31 12:37:17.000000000 -0700 +++ linux-2.0.32-pre5/drivers/scsi/aic7xxx.h 2003-08-15 15:04:17.000000000 -0700 @@ -40,7 +40,7 @@ aic7xxx_info, \ NULL, \ aic7xxx_queue, \ - NULL, \ + aic7xxx_abort, \ aic7xxx_reset, \ NULL, \ aic7xxx_biosparam, \ @@ -57,6 +57,7 @@ extern int aic7xxx_biosparam(Disk *, kdev_t, int[]); extern int aic7xxx_detect(Scsi_Host_Template *); extern int aic7xxx_command(Scsi_Cmnd *); +extern int aic7xxx_abort(Scsi_Cmnd *); extern int aic7xxx_reset(Scsi_Cmnd *, unsigned int); extern const char *aic7xxx_info(struct Scsi_Host *); diff -urN linux-2.0.32-pre2/drivers/scsi/aic7xxx_proc.c linux-2.0.32-pre5/drivers/scsi/aic7xxx_proc.c --- linux-2.0.32-pre2/drivers/scsi/aic7xxx_proc.c 1997-09-22 14:53:09.000000000 -0700 +++ linux-2.0.32-pre5/drivers/scsi/aic7xxx_proc.c 2003-08-15 15:04:17.000000000 -0700 @@ -51,6 +51,13 @@ # define proc_debug(fmt, args...) #endif /* PROC_DEBUG */ +static int aic7xxx_buffer_size = 0; +static char *aic7xxx_buffer = NULL; +static const char *bus_names[] = { "Single", "Twin", "Wide" }; +static const char *chip_names[] = { "AIC-777x", "AIC-785x", "AIC-786x", + "AIC-787x", "AIC-788x" }; + + /*+F************************************************************************* * Function: * aic7xxx_set_info @@ -64,7 +71,8 @@ proc_debug("aic7xxx_set_info(): %s\n", buffer); return (-ENOSYS); /* Currently this is a no-op */ } - + + /*+F************************************************************************* * Function: * aic7xxx_proc_info @@ -78,14 +86,9 @@ { struct Scsi_Host *HBAptr; struct aic7xxx_host *p; - static int aic7xxx_buffer_size = 0; int found = FALSE; - static int size = 0; + int size = 0; unsigned char i; - static char *aic7xxx_buffer = NULL; - static char *bus_names[] = { "Single", "Twin", "Wide" }; - static char *chip_names[] = { "AIC-777x", "AIC-785x", "AIC-786x", - "AIC-787x", "AIC-788x" }; #ifdef AIC7XXX_PROC_STATS struct aic7xxx_xferstats *sp; unsigned char target, lun; @@ -100,7 +103,7 @@ { break; } - + while ((HBAptr->hostdata != NULL) && !found && ((HBAptr = ((struct aic7xxx_host *) HBAptr->hostdata)->next) != NULL)) { @@ -109,7 +112,7 @@ found = TRUE; } } - + if (!found) { HBAptr = NULL; @@ -120,49 +123,59 @@ } } } - + if (HBAptr == NULL) { - size += sprintf( buffer, "Can't find adapter for host number %d\n", hostno); - if ( size > length) return size; - return length; + size += sprintf(buffer, "Can't find adapter for host number %d\n", hostno); + if (size > length) + { + return (size); + } + else + { + return (length); + } } - + if (inout == TRUE) /* Has data been written to the file? */ { return (aic7xxx_set_info(buffer, length, HBAptr)); } - + p = (struct aic7xxx_host *) HBAptr->hostdata; - /* It takes roughly 1K of space to hold all relevant card info, not */ - /* counting any proc stats, so we start out with a 1.5k buffer size and */ - /* if proc_stats is defined, then we sweep the stats structure to see */ - /* how many drives we will be printing out for and add 384 bytes per */ - /* device with active stats. */ + /* + * It takes roughly 1K of space to hold all relevant card info, not + * counting any proc stats, so we start out with a 1.5k buffer size and + * if proc_stats is defined, then we sweep the stats structure to see + * how many drives we will be printing out for and add 384 bytes per + * device with active stats. + */ size = 1536; #ifdef AIC7XXX_PROC_STATS - for (target=0; target<16; target++) + for (target = 0; target < MAX_TARGETS; target++) { - for (lun=0; lun<8; lun++) + for (lun = 0; lun < MAX_LUNS; lun++) { if (p->stats[target][lun].xfers != 0) size += 384; } } #endif - if ( aic7xxx_buffer_size != size) { - if ( aic7xxx_buffer != NULL) + if (aic7xxx_buffer_size != size) + { + if (aic7xxx_buffer != NULL) { - kfree ( aic7xxx_buffer); + kfree(aic7xxx_buffer); aic7xxx_buffer_size = 0; } - aic7xxx_buffer = kmalloc ( size, GFP_KERNEL); + aic7xxx_buffer = kmalloc(size, GFP_KERNEL); } - if ( aic7xxx_buffer == NULL) { - size = sprintf ( buffer, "AIC7xxx - kmalloc error at line %d\n", - __LINE__); + if (aic7xxx_buffer == NULL) + { + size = sprintf(buffer, "AIC7xxx - kmalloc error at line %d\n", + __LINE__); return size; } aic7xxx_buffer_size = size; @@ -177,12 +190,10 @@ size += sprintf(BLS, "\n"); size += sprintf(BLS, "Compile Options:\n"); #ifdef AIC7XXX_RESET_DELAY - size += sprintf(BLS, " AIC7XXX_RESET_DELAY : %d\n", - AIC7XXX_RESET_DELAY); + size += sprintf(BLS, " AIC7XXX_RESET_DELAY : %d\n", AIC7XXX_RESET_DELAY); #endif #ifdef AIC7XXX_CMDS_PER_LUN - size += sprintf(BLS, " AIC7XXX_CMDS_PER_LUN : %d\n", - AIC7XXX_CMDS_PER_LUN); + size += sprintf(BLS, " AIC7XXX_CMDS_PER_LUN : %d\n", AIC7XXX_CMDS_PER_LUN); #endif #ifdef AIC7XXX_TAGGED_QUEUEING size += sprintf(BLS, " AIC7XXX_TAGGED_QUEUEING: Enabled\n"); @@ -201,18 +212,17 @@ #endif size += sprintf(BLS, "\n"); size += sprintf(BLS, "Adapter Configuration:\n"); - size += sprintf(BLS, " SCSI Adapter: %s\n", - board_names[p->chip_type]); - size += sprintf(BLS, " (%s chipset)\n", - chip_names[p->chip_class]); - size += sprintf(BLS, " Host Bus: %s\n", - bus_names[p->bus_type]); - size += sprintf(BLS, " Base IO: %#.4x\n", p->base); - size += sprintf(BLS, " Base IO Memory: 0x%x\n", p->mbase); - size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq); - size += sprintf(BLS, " SCBs: Used %d, HW %d, Page %d\n", - p->scb_data->numscbs, p->scb_data->maxhscbs, p->scb_data->maxscbs); - size += sprintf(BLS, " Interrupts: %d", p->isr_count); + size += sprintf(BLS, " SCSI Adapter: %s\n", + board_names[p->chip_type]); + size += sprintf(BLS, " (%s chipset)\n", + chip_names[p->chip_class]); + size += sprintf(BLS, " Host Bus: %s\n", bus_names[p->bus_type]); + size += sprintf(BLS, " Base IO: %#.4x\n", p->base); + size += sprintf(BLS, " Base IO Memory: 0x%x\n", p->mbase); + size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq); + size += sprintf(BLS, " SCBs: Used %d, HW %d, Page %d\n", + p->scb_data->numscbs, p->scb_data->maxhscbs, p->scb_data->maxscbs); + size += sprintf(BLS, " Interrupts: %d", p->isr_count); if (p->chip_class == AIC_777x) { size += sprintf(BLS, " %s\n", @@ -222,23 +232,22 @@ { size += sprintf(BLS, "\n"); } - size += sprintf(BLS, " Serial EEPROM: %s\n", + size += sprintf(BLS, " Serial EEPROM: %s\n", (p->flags & HAVE_SEEPROM) ? "True" : "False"); - size += sprintf(BLS, " Extended Translation: %sabled\n", + size += sprintf(BLS, " Extended Translation: %sabled\n", (p->flags & EXTENDED_TRANSLATION) ? "En" : "Dis"); - size += sprintf(BLS, " SCSI Bus Reset: %sabled\n", + size += sprintf(BLS, " SCSI Bus Reset: %sabled\n", aic7xxx_no_reset ? "Dis" : "En"); - size += sprintf(BLS, " Ultra SCSI: %sabled\n", + size += sprintf(BLS, " Ultra SCSI: %sabled\n", (p->flags & ULTRA_ENABLED) ? "En" : "Dis"); - size += sprintf(BLS, " Target Disconnect: %sabled\n", - p->discenable ? "En" : "Dis"); + size += sprintf(BLS, "Disconnect Enable Flags: 0x%x\n", p->discenable); #ifdef AIC7XXX_PROC_STATS size += sprintf(BLS, "\n"); size += sprintf(BLS, "Statistics:\n"); - for (target = 0; target < 16; target++) + for (target = 0; target < MAX_TARGETS; target++) { - for (lun = 0; lun < 8; lun++) + for (lun = 0; lun < MAX_LUNS; lun++) { sp = &p->stats[target][lun]; if (sp->xfers == 0) @@ -246,42 +255,58 @@ continue; } if (p->bus_type == AIC_TWIN) + { size += sprintf(BLS, "CHAN#%c (TGT %d LUN %d):\n", 'A' + (target >> 3), (target & 0x7), lun); + } else + { size += sprintf(BLS, "CHAN#%c (TGT %d LUN %d):\n", 'A', target, lun); + } size += sprintf(BLS, "nxfers %ld (%ld read;%ld written)\n", - sp->xfers, sp->r_total, sp->w_total); + sp->xfers, sp->r_total, sp->w_total); size += sprintf(BLS, "blks(512) rd=%ld; blks(512) wr=%ld\n", - sp->r_total512, sp->w_total512); + sp->r_total512, sp->w_total512); size += sprintf(BLS, "%s\n", HDRB); size += sprintf(BLS, " Reads:"); - for (i=0; i<10; i++) - size += sprintf(BLS, "%6ld ", sp->r_bins[i]); + for (i = 0; i < NUMBER(sp->r_bins); i++) + { + size += sprintf(BLS, "%6ld ", sp->r_bins[i]); + } size += sprintf(BLS, "\n"); size += sprintf(BLS, "Writes:"); - for (i=0; i<10; i++) - size += sprintf(BLS, "%6ld ", sp->w_bins[i]); + for (i = 0; i < NUMBER(sp->w_bins); i++) + { + size += sprintf(BLS, "%6ld ", sp->w_bins[i]); + } size += sprintf(BLS, "\n\n"); } } #endif /* AIC7XXX_PROC_STATS */ - if ( size >= aic7xxx_buffer_size ) + if (size >= aic7xxx_buffer_size) + { printk(KERN_WARNING "aic7xxx: Overflow in aic7xxx_proc.c\n"); + } - if ( offset > size - 1) { - kfree ( aic7xxx_buffer); - aic7xxx_buffer = NULL; - aic7xxx_buffer_size = length = 0; - *start = NULL; - } else { - *start = &aic7xxx_buffer[offset]; /* Start of wanted data */ - if ( size - offset < length) length = size - offset; + if (offset > size - 1) + { + kfree(aic7xxx_buffer); + aic7xxx_buffer = NULL; + aic7xxx_buffer_size = length = 0; + *start = NULL; } - - return length; + else + { + *start = &aic7xxx_buffer[offset]; /* Start of wanted data */ + if (size - offset < length) + { + length = size - offset; + } + } + + return (length); } /* diff -urN linux-2.0.32-pre2/drivers/scsi/aic7xxx_reg.h linux-2.0.32-pre5/drivers/scsi/aic7xxx_reg.h --- linux-2.0.32-pre2/drivers/scsi/aic7xxx_reg.h 1997-09-22 14:53:09.000000000 -0700 +++ linux-2.0.32-pre5/drivers/scsi/aic7xxx_reg.h 2003-08-15 15:04:17.000000000 -0700 @@ -30,6 +30,13 @@ #define ACTNEGEN 0x02 #define STPWEN 0x01 +#define SCSISIGI 0x03 +#define ATNI 0x10 +#define SELI 0x08 +#define BSYI 0x04 +#define REQI 0x02 +#define ACKI 0x01 + #define SCSISIGO 0x03 #define CDO 0x80 #define IOO 0x40 @@ -40,13 +47,6 @@ #define REQO 0x02 #define ACKO 0x01 -#define SCSISIGI 0x03 -#define ATNI 0x10 -#define SELI 0x08 -#define BSYI 0x04 -#define REQI 0x02 -#define ACKI 0x01 - #define SCSIRATE 0x04 #define WIDEXFER 0x80 #define SXFR 0x70 @@ -262,16 +262,16 @@ #define CMDOUTCNT 0x5a -#define FIFODEPTH 0x5b - #define SCSICONF2 0x5b #define RESET_SCSI 0x40 +#define FIFODEPTH 0x5b + #define HOSTCONF 0x5d #define HA_274_BIOSCTRL 0x5f -#define BIOSMODE 0x30 #define BIOSDISABLED 0x30 +#define BIOSMODE 0x30 #define CHANNEL_B_PRIMARY 0x08 #define SEQCTL 0x60 @@ -315,16 +315,16 @@ #define STACK 0x6f -#define BCTL 0x84 -#define ACE 0x08 -#define ENABLE 0x01 - #define DSCOMMAND 0x84 #define CACHETHEN 0x80 #define DPARCKEN 0x40 #define MPARCKEN 0x20 #define EXTREQLCK 0x10 +#define BCTL 0x84 +#define ACE 0x08 +#define ENABLE 0x01 + #define BUSTIME 0x85 #define BOFF 0xf0 #define BON 0x0f @@ -374,18 +374,18 @@ #define BAD_PHASE 0x01 #define SEQINT 0x01 -#define CLRINT 0x92 -#define CLRBRKADRINT 0x08 -#define CLRSCSIINT 0x04 -#define CLRCMDINT 0x02 -#define CLRSEQINT 0x01 - #define ERROR 0x92 #define PARERR 0x08 #define ILLOPCODE 0x04 #define ILLSADDR 0x02 #define ILLHADDR 0x01 +#define CLRINT 0x92 +#define CLRBRKADRINT 0x08 +#define CLRSCSIINT 0x04 +#define CLRCMDINT 0x02 +#define CLRSEQINT 0x01 + #define DFCNTRL 0x93 #define DFSTATUS 0x94 @@ -410,6 +410,8 @@ #define QOUTCNT 0x9e +#define SCB_BASE 0xa0 + #define SCB_CONTROL 0xa0 #define MK_MESSAGE 0x80 #define DISCENB 0x40 @@ -419,8 +421,6 @@ #define DISCONNECTED 0x04 #define SCB_TAG_TYPE 0x03 -#define SCB_BASE 0xa0 - #define SCB_TCL 0xa1 #define TID 0xf0 #define SELBUSB 0x08 @@ -466,10 +466,10 @@ #define DI_2840 0x01 -#define BUS_8_BIT 0x00 -#define MAX_OFFSET_8BIT 0x0f -#define BUS_16_BIT 0x01 #define MAX_OFFSET_16BIT 0x08 +#define BUS_8_BIT 0x00 #define SCB_LIST_NULL 0xff #define SG_SIZEOF 0x08 +#define MAX_OFFSET_8BIT 0x0f #define BUS_32_BIT 0x02 +#define BUS_16_BIT 0x01 diff -urN linux-2.0.32-pre2/fs/inode.c linux-2.0.32-pre5/fs/inode.c --- linux-2.0.32-pre2/fs/inode.c 1997-10-15 10:28:42.000000000 -0700 +++ linux-2.0.32-pre5/fs/inode.c 2003-08-15 15:04:17.000000000 -0700 @@ -173,7 +173,25 @@ { struct wait_queue * wait; + /* + * We can clear inodes either when a last deref to the inode + * causes it to be deleted (reference count==1), or when we want to + * reuse it (reference count==0). Any other count is an error. + */ + if (inode->i_count > 1) + panic ("clear_inode: Inode still has references"); + + /* + * We are about to zap this inode. This operation may block, + * and it's imperative that we don't allow another process to + * grab it before it is completely pulled down. The i_count + * will prevent reuse of the inode by get_empty_inode(), but the + * i_condemned flag will also prevent __iget() from finding the + * inode until it is completely dead. + */ + inode->i_condemned = 1; inode->i_count++; + truncate_inode_pages(inode, 0); wait_on_inode(inode); if (IS_WRITABLE(inode)) { @@ -188,6 +206,11 @@ memset(inode,0,sizeof(*inode)); ((volatile struct inode *) inode)->i_wait = wait; insert_inode_free(inode); + /* + * The inode is now reusable again, and the condemned flag is + * clear. Wake up anybody who is waiting on the condemned flag. + */ + wake_up(&inode->i_wait); } int fs_may_mount(kdev_t dev) @@ -428,6 +451,7 @@ } if (inode->i_pipe) wake_up_interruptible(&PIPE_WAIT(*inode)); + repeat: if (inode->i_count>1) { inode->i_count--; @@ -501,7 +525,7 @@ for (i = nr_inodes/2; i > 0; i--,inode = inode->i_next) { if (!inode->i_count) { unsigned long i = 999; - if (!(inode->i_lock | inode->i_dirt)) + if (!(inode->i_lock || inode->i_dirt)) i = inode->i_nrpages; if (i < badness) { best = inode; @@ -615,6 +639,15 @@ goto return_it; found_it: + /* + * The inode may currently be being pulled down by + * clear_inode(). Avoid it if so. If we get past this, then + * the increment of i_count will prevent the inode's reuse. + */ + if (inode->i_condemned) { + sleep_on(&inode->i_wait); + goto repeat; + } if (!inode->i_count) nr_free_inodes--; inode->i_count++; diff -urN linux-2.0.32-pre2/fs/proc/fd.c linux-2.0.32-pre5/fs/proc/fd.c --- linux-2.0.32-pre2/fs/proc/fd.c 2003-08-15 15:04:17.000000000 -0700 +++ linux-2.0.32-pre5/fs/proc/fd.c 2003-08-15 15:04:17.000000000 -0700 @@ -106,7 +106,8 @@ if (!pid || i >= NR_TASKS) return -ENOENT; - if (fd >= NR_OPEN || !p->files || !p->files->fd[fd] || !p->files->fd[fd]->f_inode) + if (fd >= NR_OPEN || !p->files || !p->files->fd[fd] + || !p->files->fd[fd]->f_inode) return -ENOENT; ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd; diff -urN linux-2.0.32-pre2/include/asm-i386/bugs.h linux-2.0.32-pre5/include/asm-i386/bugs.h --- linux-2.0.32-pre2/include/asm-i386/bugs.h 1997-10-15 15:22:04.000000000 -0700 +++ linux-2.0.32-pre5/include/asm-i386/bugs.h 2003-08-15 15:04:17.000000000 -0700 @@ -125,10 +125,32 @@ #endif } +/* + * All current models of Pentium and Pentium with MMX technology CPUs + * have the F0 0F bug, which lets nonpriviledged users lock up the system: + */ +extern int pentium_f00f_bug; +extern void trap_init_f00f_bug(void); + +static void check_pentium_f00f(void) +{ + /* + * Pentium and Pentium MMX + */ + pentium_f00f_bug = 0; + if (x86==5 && !memcmp(x86_vendor_id, "GenuineIntel", 12)) { + printk(KERN_INFO "Intel Pentium with F0 0F bug - workaround enabled.\n"); + pentium_f00f_bug = 1; + trap_init_f00f_bug(); + } +} + + static void check_bugs(void) { check_tlb(); check_fpu(); check_hlt(); + check_pentium_f00f(); system_utsname.machine[1] = '0' + x86; } diff -urN linux-2.0.32-pre2/include/linux/fs.h linux-2.0.32-pre5/include/linux/fs.h --- linux-2.0.32-pre2/include/linux/fs.h 1997-10-15 15:22:04.000000000 -0700 +++ linux-2.0.32-pre5/include/linux/fs.h 2003-08-15 15:04:17.000000000 -0700 @@ -312,6 +312,7 @@ unsigned char i_sock; unsigned char i_seek; unsigned char i_update; + unsigned char i_condemned; unsigned short i_writecount; union { struct pipe_inode_info pipe_i; diff -urN linux-2.0.32-pre2/include/linux/head.h linux-2.0.32-pre5/include/linux/head.h --- linux-2.0.32-pre2/include/linux/head.h 1995-01-22 04:38:45.000000000 -0800 +++ linux-2.0.32-pre5/include/linux/head.h 2003-08-15 15:04:17.000000000 -0700 @@ -5,7 +5,8 @@ unsigned long a,b; } desc_table[256]; -extern desc_table idt,gdt; +extern desc_table __idt,gdt; +extern struct desc_struct *idt; #define GDT_NUL 0 #define GDT_CODE 1 diff -urN linux-2.0.32-pre2/kernel/fork.c linux-2.0.32-pre5/kernel/fork.c --- linux-2.0.32-pre2/kernel/fork.c 2003-08-15 15:04:17.000000000 -0700 +++ linux-2.0.32-pre5/kernel/fork.c 2003-08-15 15:04:17.000000000 -0700 @@ -135,12 +135,12 @@ tsk->nswap = tsk->cnswap = 0; if (new_page_tables(tsk)) { tsk->mm = NULL; - mm->pgd = NULL; exit_mmap(mm); goto free_mm; } if (dup_mmap(mm)) { tsk->mm = NULL; + exit_mmap(mm); free_page_tables(mm); free_mm: kfree(mm); diff -urN linux-2.0.32-pre2/net/ipv4/ip_fragment.c linux-2.0.32-pre5/net/ipv4/ip_fragment.c --- linux-2.0.32-pre2/net/ipv4/ip_fragment.c 1997-08-12 11:30:25.000000000 -0700 +++ linux-2.0.32-pre5/net/ipv4/ip_fragment.c 2003-08-15 15:04:17.000000000 -0700 @@ -375,7 +375,7 @@ fp = qp->fragments; while(fp != NULL) { - if(count+fp->len > skb->len) + if (fp->len < 0 || count+fp->len > skb->len) { NETDEBUG(printk("Invalid fragment list: Fragment over size.\n")); ip_free(qp); diff -urN linux-2.0.32-pre2/net/ipv4/rarp.c linux-2.0.32-pre5/net/ipv4/rarp.c --- linux-2.0.32-pre2/net/ipv4/rarp.c 1997-08-12 11:30:35.000000000 -0700 +++ linux-2.0.32-pre5/net/ipv4/rarp.c 2003-08-15 15:04:17.000000000 -0700 @@ -175,6 +175,8 @@ NULL, 0 }; + +static int rarp_pkt_inited=0; static void rarp_init_pkt (void) { @@ -182,8 +184,19 @@ rarp_packet_type.type=htons(ETH_P_RARP); dev_add_pack(&rarp_packet_type); register_netdevice_notifier(&rarp_dev_notifier); + rarp_pkt_inited=1; +} + +static void rarp_end_pkt(void) +{ + if(!rarp_pkt_inited) + return; + dev_remove_pack(&rarp_packet_type); + unregister_netdevice_notifier(&rarp_dev_notifier); + rarp_pkt_inited=0; } + /* * Receive an arp request by the device layer. Maybe it should be * rewritten to use the incoming packet for the reply. The current @@ -574,12 +587,14 @@ void rarp_init(void) { +#ifdef CONFIG_PROC_FS proc_net_register(&(struct proc_dir_entry) { PROC_NET_RARP, 4, "rarp", S_IFREG | S_IRUGO, 1, 0, 0, 0, &proc_net_inode_operations, rarp_get_info }); +#endif rarp_ioctl_hook = rarp_ioctl; } @@ -594,7 +609,9 @@ void cleanup_module(void) { struct rarp_table *rt, *rt_next; +#ifdef CONFIG_PROC_FS proc_net_unregister(PROC_NET_RARP); +#endif rarp_ioctl_hook = NULL; cli(); /* Destroy the RARP-table */ @@ -606,5 +623,6 @@ rt_next = rt->next; rarp_release_entry(rt); } + rarp_end_pkt(); } #endif