diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/arch/x86_64/Kconfig 170-x86_64/arch/x86_64/Kconfig --- 160-lotsa_sds/arch/x86_64/Kconfig Fri Jan 9 20:58:39 2004 +++ 170-x86_64/arch/x86_64/Kconfig Fri Jan 9 21:02:04 2004 @@ -68,6 +68,9 @@ config HPET_TIMER If unsure, say Y. +config HPET_EMULATE_RTC + def_bool HPET_TIMER && RTC=y + config GENERIC_ISA_DMA bool default y @@ -332,6 +335,26 @@ config PCI_DIRECT bool depends on PCI default y + +# the drivers/pci/msi.c code needs to be fixed first before enabling +config PCI_USE_VECTOR + bool "Vector-based interrupt indexing" + depends on X86_LOCAL_APIC && NOTWORKING + default n + help + This replaces the current existing IRQ-based index interrupt scheme + with the vector-base index scheme. The advantages of vector base + over IRQ base are listed below: + 1) Support MSI implementation. + 2) Support future IOxAPIC hotplug + + Note that this enables MSI, Message Signaled Interrupt, on all + MSI capable device functions detected if users also install the + MSI patch. Message Signal Interrupt enables an MSI-capable + hardware device to send an inbound Memory Write on its PCI bus + instead of asserting IRQ signal on device IRQ pin. + + If you don't know what to do here, say N. # the drivers/pci/msi.c code needs to be fixed first before enabling config PCI_USE_VECTOR diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/arch/x86_64/ia32/ia32_signal.c 170-x86_64/arch/x86_64/ia32/ia32_signal.c --- 160-lotsa_sds/arch/x86_64/ia32/ia32_signal.c Fri Jan 9 17:40:01 2004 +++ 170-x86_64/arch/x86_64/ia32/ia32_signal.c Fri Jan 9 21:02:04 2004 @@ -44,10 +44,10 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); void signal_fault(struct pt_regs *regs, void *frame, char *where); -static int ia32_copy_siginfo_to_user(siginfo_t32 *to, siginfo_t *from) +int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from) { int err; - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32))) return -EFAULT; /* If you change siginfo_t structure, please make sure that @@ -55,21 +55,17 @@ static int ia32_copy_siginfo_to_user(sig It should never copy any pad contained in the structure to avoid security leaks, but must copy the generic 3 ints plus the relevant union member. */ - - if (from->si_code < 0) { err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); err |= __put_user(from->si_code, &to->si_code); - err |= __put_user(from->_sifields._rt._pid, &to->_sifields._rt._pid); - err |= __put_user(from->_sifields._rt._uid, &to->_sifields._rt._uid); - err |= __put_user((u32)(u64)from->_sifields._rt._sigval.sival_ptr, - &to->_sifields._rt._sigval.sival_ptr); - } else { - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user(from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ + + if (from->si_code < 0) { err |= __put_user(from->si_pid, &to->si_pid); + err |= __put_user(from->si_uid, &to->si_uid); + err |= __put_user((u32)(u64)from->si_ptr, &to->si_ptr); + } else { + /* First 32bits of unions are always present: + * si_pid === si_band === si_tid === si_addr(LS half) */ switch (from->si_code >> 16) { case __SI_FAULT >> 16: break; @@ -78,15 +74,36 @@ static int ia32_copy_siginfo_to_user(sig err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); default: + case __SI_KILL >> 16: err |= __put_user(from->si_uid, &to->si_uid); break; case __SI_POLL >> 16: - err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; + case __SI_TIMER >> 16: + err |= __put_user(from->si_overrun, &to->si_overrun); + err |= __put_user((u32)(u64)from->si_ptr, &to->si_ptr); + break; /* case __SI_RT: This is not generated by the kernel as of now. */ } } + return err; +} + +int ia32_copy_siginfo_from_user(siginfo_t *to, siginfo_t32 __user *from) +{ + int err; + if (!access_ok (VERIFY_READ, from, sizeof(siginfo_t32))) + return -EFAULT; + + err = __get_user(to->si_signo, &from->si_signo); + err |= __get_user(to->si_errno, &from->si_errno); + err |= __get_user(to->si_code, &from->si_code); + + err |= __get_user(to->si_pid, &from->si_pid); + err |= __get_user(to->si_uid, &from->si_uid); + err |= __get_user((u32)(u64)to->si_ptr, &from->si_ptr); + return err; } diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/arch/x86_64/ia32/sys_ia32.c 170-x86_64/arch/x86_64/ia32/sys_ia32.c --- 160-lotsa_sds/arch/x86_64/ia32/sys_ia32.c Fri Jan 9 17:40:01 2004 +++ 170-x86_64/arch/x86_64/ia32/sys_ia32.c Fri Jan 9 21:02:04 2004 @@ -1022,84 +1022,6 @@ sys32_rt_sigpending(compat_sigset_t *set return ret; } -siginfo_t32 * -siginfo64to32(siginfo_t32 *d, siginfo_t *s) -{ - memset (d, 0, sizeof(siginfo_t32)); - d->si_signo = s->si_signo; - d->si_errno = s->si_errno; - d->si_code = s->si_code; - if (s->si_signo >= SIGRTMIN) { - d->si_pid = s->si_pid; - d->si_uid = s->si_uid; - memcpy(&d->si_int, &s->si_int, - sizeof(siginfo_t) - offsetof(siginfo_t,si_int)); - } else switch (s->si_signo) { - /* XXX: What about POSIX1.b timers */ - case SIGCHLD: - d->si_pid = s->si_pid; - d->si_status = s->si_status; - d->si_utime = s->si_utime; - d->si_stime = s->si_stime; - break; - case SIGSEGV: - case SIGBUS: - case SIGFPE: - case SIGILL: - d->si_addr = (long)(s->si_addr); -// d->si_trapno = s->si_trapno; - break; - case SIGPOLL: - d->si_band = s->si_band; - d->si_fd = s->si_fd; - break; - default: - d->si_pid = s->si_pid; - d->si_uid = s->si_uid; - break; - } - return d; -} - -siginfo_t * -siginfo32to64(siginfo_t *d, siginfo_t32 *s) -{ - d->si_signo = s->si_signo; - d->si_errno = s->si_errno; - d->si_code = s->si_code; - if (s->si_signo >= SIGRTMIN) { - d->si_pid = s->si_pid; - d->si_uid = s->si_uid; - memcpy(&d->si_int, - &s->si_int, - sizeof(siginfo_t) - offsetof(siginfo_t, si_int)); - } else switch (s->si_signo) { - /* XXX: What about POSIX1.b timers */ - case SIGCHLD: - d->si_pid = s->si_pid; - d->si_status = s->si_status; - d->si_utime = s->si_utime; - d->si_stime = s->si_stime; - break; - case SIGSEGV: - case SIGBUS: - case SIGFPE: - case SIGILL: - d->si_addr = (void *)A(s->si_addr); -// d->si_trapno = s->si_trapno; - break; - case SIGPOLL: - d->si_band = s->si_band; - d->si_fd = s->si_fd; - break; - default: - d->si_pid = s->si_pid; - d->si_uid = s->si_uid; - break; - } - return d; -} - extern asmlinkage long sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo, const struct timespec *uts, size_t sigsetsize); @@ -1114,7 +1036,6 @@ sys32_rt_sigtimedwait(compat_sigset_t *u int ret; mm_segment_t old_fs = get_fs(); siginfo_t info; - siginfo_t32 info32; if (copy_from_user (&s32, uthese, sizeof(compat_sigset_t))) return -EFAULT; @@ -1126,13 +1047,18 @@ sys32_rt_sigtimedwait(compat_sigset_t *u } if (uts && get_compat_timespec(&t, uts)) return -EFAULT; + if (uinfo) { + /* stop data leak to user space in case of structure fill mismatch + * between sys_rt_sigtimedwait & ia32_copy_siginfo_to_user. + */ + memset(&info, 0, sizeof(info)); + } set_fs (KERNEL_DS); ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL, sigsetsize); set_fs (old_fs); if (ret >= 0 && uinfo) { - if (copy_to_user (uinfo, siginfo64to32(&info32, &info), - sizeof(siginfo_t32))) + if (ia32_copy_siginfo_to_user(uinfo, &info)) return -EFAULT; } return ret; @@ -1145,14 +1071,11 @@ asmlinkage long sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo) { siginfo_t info; - siginfo_t32 info32; int ret; mm_segment_t old_fs = get_fs(); - if (copy_from_user (&info32, uinfo, sizeof(siginfo_t32))) + if (ia32_copy_siginfo_from_user(&info, uinfo)) return -EFAULT; - /* XXX: Is this correct? */ - siginfo32to64(&info, &info32); set_fs (KERNEL_DS); ret = sys_rt_sigqueueinfo(pid, sig, &info); set_fs (old_fs); diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/arch/x86_64/kernel/acpi/sleep.c 170-x86_64/arch/x86_64/kernel/acpi/sleep.c --- 160-lotsa_sds/arch/x86_64/kernel/acpi/sleep.c Tue Apr 8 14:38:15 2003 +++ 170-x86_64/arch/x86_64/kernel/acpi/sleep.c Fri Jan 9 21:02:04 2004 @@ -56,6 +56,7 @@ /* address in low memory of the wakeup routine. */ unsigned long acpi_wakeup_address = 0; +unsigned long acpi_video_flags; extern char wakeup_start, wakeup_end; extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); @@ -115,6 +116,22 @@ void __init acpi_reserve_bootmem(void) printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n"); printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address); } + +static int __init acpi_sleep_setup(char *str) +{ + while ((str != NULL) && (*str != '\0')) { + if (strncmp(str, "s3_bios", 7) == 0) + acpi_video_flags = 1; + if (strncmp(str, "s3_mode", 7) == 0) + acpi_video_flags |= 2; + str = strchr(str, ','); + if (str != NULL) + str += strspn(str, ", \t"); + } + return 1; +} + +__setup("acpi_sleep=", acpi_sleep_setup); #endif /*CONFIG_ACPI_SLEEP*/ diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/arch/x86_64/kernel/acpi/wakeup.S 170-x86_64/arch/x86_64/kernel/acpi/wakeup.S --- 160-lotsa_sds/arch/x86_64/kernel/acpi/wakeup.S Wed Jul 2 21:59:08 2003 +++ 170-x86_64/arch/x86_64/kernel/acpi/wakeup.S Fri Jan 9 21:02:04 2004 @@ -41,7 +41,19 @@ wakeup_code: cmpl $0x12345678, %eax jne bogus_real_magic + testl $1, video_flags - wakeup_code + jz 1f lcall $0xc000,$3 + movw %cs, %ax + movw %ax, %ds # Bios might have played with that + movw %ax, %ss +1: + + testl $2, video_flags - wakeup_code + jz 1f + mov video_mode - wakeup_code, %ax + call mode_seta +1: movw $0xb800, %ax movw %ax,%fs @@ -250,6 +262,7 @@ real_save_gdt: .word 0 .quad 0 real_magic: .quad 0 video_mode: .quad 0 +video_flags: .quad 0 bogus_real_magic: movb $0xba,%al ; outb %al,$0x80 @@ -382,8 +395,10 @@ ENTRY(acpi_copy_wakeup_routine) movl %eax, saved_efer movl %edx, saved_efer2 -# movq saved_videomode, %rdx # FIXME: videomode - movq %rdx, video_mode - wakeup_start (,%rdi) + movl saved_video_mode, %edx + movl %edx, video_mode - wakeup_start (,%rdi) + movl acpi_video_flags, %edx + movl %edx, video_flags - wakeup_start (,%rdi) movq $0x12345678, real_magic - wakeup_start (,%rdi) movq $0x123456789abcdef0, %rdx movq %rdx, saved_magic diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/arch/x86_64/kernel/pci-dma.c 170-x86_64/arch/x86_64/kernel/pci-dma.c --- 160-lotsa_sds/arch/x86_64/kernel/pci-dma.c Tue Sep 2 09:55:44 2003 +++ 170-x86_64/arch/x86_64/kernel/pci-dma.c Fri Jan 9 21:02:04 2004 @@ -35,6 +35,7 @@ int pci_map_sg(struct pci_dev *hwdev, st BUG_ON(!s->page); s->dma_address = pci_map_page(hwdev, s->page, s->offset, s->length, direction); + s->dma_length = s->length; } return nents; } @@ -53,7 +54,7 @@ void pci_unmap_sg(struct pci_dev *dev, s struct scatterlist *s = &sg[i]; BUG_ON(s->page == NULL); BUG_ON(s->dma_address == 0); - pci_unmap_single(dev, s->dma_address, s->length, dir); + pci_unmap_single(dev, s->dma_address, s->dma_length, dir); } } diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/arch/x86_64/kernel/pci-gart.c 170-x86_64/arch/x86_64/kernel/pci-gart.c --- 160-lotsa_sds/arch/x86_64/kernel/pci-gart.c Fri Jan 9 17:40:01 2004 +++ 170-x86_64/arch/x86_64/kernel/pci-gart.c Fri Jan 9 21:02:04 2004 @@ -382,10 +382,12 @@ static int pci_map_sg_nonforce(struct pc if (i > 0) pci_unmap_sg(dev, sg, i, dir); nents = 0; + sg[0].dma_length = 0; break; } } s->dma_address = addr; + s->dma_length = s->length; } flush_gart(dev); return nents; @@ -412,8 +414,9 @@ static int __pci_map_cont(struct scatter *sout = *s; sout->dma_address = iommu_bus_base; sout->dma_address += iommu_page*PAGE_SIZE + s->offset; + sout->dma_length = s->length; } else { - sout->length += s->length; + sout->dma_length += s->length; } addr = phys_addr; @@ -436,6 +439,7 @@ static inline int pci_map_cont(struct sc if (!need) { BUG_ON(stopat - start != 1); *sout = sg[start]; + sout->dma_length = sg[start].length; return 0; } return __pci_map_cont(sg, start, stopat, sout, pages); @@ -453,8 +457,6 @@ int pci_map_sg(struct pci_dev *dev, stru unsigned long pages = 0; int need = 0, nextneed; - unsigned long size = 0; - BUG_ON(dir == PCI_DMA_NONE); if (nents == 0) return 0; @@ -466,7 +468,6 @@ int pci_map_sg(struct pci_dev *dev, stru s->dma_address = addr; BUG_ON(s->length == 0); - size += s->length; nextneed = need_iommu(dev, addr, s->length); /* Handle the previous not yet processed entries */ @@ -493,7 +494,7 @@ int pci_map_sg(struct pci_dev *dev, stru out++; flush_gart(dev); if (out < nents) - sg[out].length = 0; + sg[out].dma_length = 0; return out; error: @@ -540,9 +541,9 @@ void pci_unmap_sg(struct pci_dev *dev, s int i; for (i = 0; i < nents; i++) { struct scatterlist *s = &sg[i]; - if (!s->length) + if (!s->dma_length || !s->length) break; - pci_unmap_single(dev, s->dma_address, s->length, dir); + pci_unmap_single(dev, s->dma_address, s->dma_length, dir); } } @@ -800,7 +801,8 @@ fs_initcall(pci_iommu_init); merge Do SG merging. Implies force (experimental) nomerge Don't do SG merging. forcesac For SAC mode for masks <40bits (experimental) - fullflush Flush IOMMU on each allocation (for testing) + fullflush Flush IOMMU on each allocation (default) + nofullflush Don't use IOMMU fullflush */ __init int iommu_setup(char *opt) { @@ -838,6 +840,8 @@ __init int iommu_setup(char *opt) iommu_sac_force = 1; if (!memcmp(p, "fullflush", 9)) iommu_fullflush = 1; + if (!memcmp(p, "nofullflush", 11)) + iommu_fullflush = 0; #ifdef CONFIG_IOMMU_LEAK if (!memcmp(p,"leak", 4)) { leak_trace = 1; diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/arch/x86_64/kernel/process.c 170-x86_64/arch/x86_64/kernel/process.c --- 160-lotsa_sds/arch/x86_64/kernel/process.c Fri Jan 9 17:40:01 2004 +++ 170-x86_64/arch/x86_64/kernel/process.c Fri Jan 9 21:02:04 2004 @@ -166,6 +166,8 @@ void idle_warning(void) printk(KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n"); } +EXPORT_SYMBOL(idle_warning); + /* Prints also some state that isn't saved in the pt_regs */ void __show_regs(struct pt_regs * regs) { @@ -439,7 +441,6 @@ struct task_struct *__switch_to(struct t write_pda(oldrsp, next->userrsp); write_pda(pcurrent, next_p); write_pda(kernelstack, (unsigned long)next_p->thread_info + THREAD_SIZE - PDA_STACKOFFSET); - /* * Now maybe reload the debug registers diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/arch/x86_64/kernel/time.c 170-x86_64/arch/x86_64/kernel/time.c --- 160-lotsa_sds/arch/x86_64/kernel/time.c Fri Jan 9 17:40:01 2004 +++ 170-x86_64/arch/x86_64/kernel/time.c Fri Jan 9 21:02:04 2004 @@ -10,6 +10,7 @@ * Copyright (c) 1998 Andrea Arcangeli * Copyright (c) 2002 Vojtech Pavlik * Copyright (c) 2003 Andi Kleen + * RTC support code taken from arch/i386/kernel/timers/time_hpet.c * */ @@ -28,6 +29,7 @@ #include #include #include +#include #include #ifdef CONFIG_X86_LOCAL_APIC #include @@ -627,10 +629,10 @@ static int hpet_init(void) * and period also hpet_tick. */ - hpet_writel(HPET_T0_ENABLE | HPET_T0_PERIODIC | HPET_T0_SETVAL | - HPET_T0_32BIT, HPET_T0_CFG); - hpet_writel(hpet_tick, HPET_T0_CMP); + hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | + HPET_TN_32BIT, HPET_T0_CFG); hpet_writel(hpet_tick, HPET_T0_CMP); + hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */ /* * Go! @@ -733,3 +735,229 @@ void __init time_init_smp(void) } __setup("report_lost_ticks", time_setup); + +#ifdef CONFIG_HPET_EMULATE_RTC +/* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET + * is enabled, we support RTC interrupt functionality in software. + * RTC has 3 kinds of interrupts: + * 1) Update Interrupt - generate an interrupt, every sec, when RTC clock + * is updated + * 2) Alarm Interrupt - generate an interrupt at a specific time of day + * 3) Periodic Interrupt - generate periodic interrupt, with frequencies + * 2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2) + * (1) and (2) above are implemented using polling at a frequency of + * 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt + * overhead. (DEFAULT_RTC_INT_FREQ) + * For (3), we use interrupts at 64Hz or user specified periodic + * frequency, whichever is higher. + */ +#include +#include + +extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs); + +#define DEFAULT_RTC_INT_FREQ 64 +#define RTC_NUM_INTS 1 + +static unsigned long UIE_on; +static unsigned long prev_update_sec; + +static unsigned long AIE_on; +static struct rtc_time alarm_time; + +static unsigned long PIE_on; +static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ; +static unsigned long PIE_count; + +static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */ + +int is_hpet_enabled(void) +{ + return vxtime.hpet_address != 0; +} + +/* + * Timer 1 for RTC, we do not use periodic interrupt feature, + * even if HPET supports periodic interrupts on Timer 1. + * The reason being, to set up a periodic interrupt in HPET, we need to + * stop the main counter. And if we do that everytime someone diables/enables + * RTC, we will have adverse effect on main kernel timer running on Timer 0. + * So, for the time being, simulate the periodic interrupt in software. + * + * hpet_rtc_timer_init() is called for the first time and during subsequent + * interuppts reinit happens through hpet_rtc_timer_reinit(). + */ +int hpet_rtc_timer_init(void) +{ + unsigned int cfg, cnt; + unsigned long flags; + + if (!is_hpet_enabled()) + return 0; + /* + * Set the counter 1 and enable the interrupts. + */ + if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ)) + hpet_rtc_int_freq = PIE_freq; + else + hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; + + local_irq_save(flags); + cnt = hpet_readl(HPET_COUNTER); + cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq); + hpet_writel(cnt, HPET_T1_CMP); + local_irq_restore(flags); + + cfg = hpet_readl(HPET_T1_CFG); + cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT; + hpet_writel(cfg, HPET_T1_CFG); + + return 1; +} + +static void hpet_rtc_timer_reinit(void) +{ + unsigned int cfg, cnt; + + if (!(PIE_on | AIE_on | UIE_on)) + return; + + if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ)) + hpet_rtc_int_freq = PIE_freq; + else + hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; + + /* It is more accurate to use the comparator value than current count.*/ + cnt = hpet_readl(HPET_T1_CMP); + cnt += hpet_tick*HZ/hpet_rtc_int_freq; + hpet_writel(cnt, HPET_T1_CMP); + + cfg = hpet_readl(HPET_T1_CFG); + cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT; + hpet_writel(cfg, HPET_T1_CFG); + + return; +} + +/* + * The functions below are called from rtc driver. + * Return 0 if HPET is not being used. + * Otherwise do the necessary changes and return 1. + */ +int hpet_mask_rtc_irq_bit(unsigned long bit_mask) +{ + if (!is_hpet_enabled()) + return 0; + + if (bit_mask & RTC_UIE) + UIE_on = 0; + if (bit_mask & RTC_PIE) + PIE_on = 0; + if (bit_mask & RTC_AIE) + AIE_on = 0; + + return 1; +} + +int hpet_set_rtc_irq_bit(unsigned long bit_mask) +{ + int timer_init_reqd = 0; + + if (!is_hpet_enabled()) + return 0; + + if (!(PIE_on | AIE_on | UIE_on)) + timer_init_reqd = 1; + + if (bit_mask & RTC_UIE) { + UIE_on = 1; + } + if (bit_mask & RTC_PIE) { + PIE_on = 1; + PIE_count = 0; + } + if (bit_mask & RTC_AIE) { + AIE_on = 1; + } + + if (timer_init_reqd) + hpet_rtc_timer_init(); + + return 1; +} + +int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec) +{ + if (!is_hpet_enabled()) + return 0; + + alarm_time.tm_hour = hrs; + alarm_time.tm_min = min; + alarm_time.tm_sec = sec; + + return 1; +} + +int hpet_set_periodic_freq(unsigned long freq) +{ + if (!is_hpet_enabled()) + return 0; + + PIE_freq = freq; + PIE_count = 0; + + return 1; +} + +int hpet_rtc_dropped_irq(void) +{ + if (!is_hpet_enabled()) + return 0; + + return 1; +} + +irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct rtc_time curr_time; + unsigned long rtc_int_flag = 0; + int call_rtc_interrupt = 0; + + hpet_rtc_timer_reinit(); + + if (UIE_on | AIE_on) { + rtc_get_rtc_time(&curr_time); + } + if (UIE_on) { + if (curr_time.tm_sec != prev_update_sec) { + /* Set update int info, call real rtc int routine */ + call_rtc_interrupt = 1; + rtc_int_flag = RTC_UF; + prev_update_sec = curr_time.tm_sec; + } + } + if (PIE_on) { + PIE_count++; + if (PIE_count >= hpet_rtc_int_freq/PIE_freq) { + /* Set periodic int info, call real rtc int routine */ + call_rtc_interrupt = 1; + rtc_int_flag |= RTC_PF; + PIE_count = 0; + } + } + if (AIE_on) { + if ((curr_time.tm_sec == alarm_time.tm_sec) && + (curr_time.tm_min == alarm_time.tm_min) && + (curr_time.tm_hour == alarm_time.tm_hour)) { + /* Set alarm int info, call real rtc int routine */ + call_rtc_interrupt = 1; + rtc_int_flag |= RTC_AF; + } + } + if (call_rtc_interrupt) { + rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8)); + rtc_interrupt(rtc_int_flag, dev_id, regs); + } + return IRQ_HANDLED; +} +#endif diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/drivers/block/paride/Kconfig 170-x86_64/drivers/block/paride/Kconfig --- 160-lotsa_sds/drivers/block/paride/Kconfig Thu Feb 13 11:08:06 2003 +++ 170-x86_64/drivers/block/paride/Kconfig Fri Jan 9 21:02:04 2004 @@ -130,7 +130,7 @@ config PARIDE_BPCK config PARIDE_BPCK6 tristate "MicroSolutions backpack (Series 6) protocol" - depends on PARIDE + depends on PARIDE && !64BIT ---help--- This option enables support for the Micro Solutions BACKPACK parallel port Series 6 IDE protocol. (Most BACKPACK drives made diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/drivers/char/agp/amd64-agp.c 170-x86_64/drivers/char/agp/amd64-agp.c --- 160-lotsa_sds/drivers/char/agp/amd64-agp.c Fri Jan 9 17:40:01 2004 +++ 170-x86_64/drivers/char/agp/amd64-agp.c Fri Jan 9 21:02:04 2004 @@ -16,11 +16,7 @@ #include "agp.h" /* Will need to be increased if AMD64 ever goes >8-way. */ -#ifdef CONFIG_SMP #define MAX_HAMMER_GARTS 8 -#else -#define MAX_HAMMER_GARTS 1 -#endif /* PTE bits. */ #define GPTE_VALID 1 @@ -35,6 +31,14 @@ #define INVGART (1<<0) #define GARTPTEERR (1<<1) +/* NVIDIA K8 registers */ +#define NVIDIA_X86_64_0_APBASE 0x10 +#define NVIDIA_X86_64_1_APBASE1 0x50 +#define NVIDIA_X86_64_1_APLIMIT1 0x54 +#define NVIDIA_X86_64_1_APSIZE 0xa8 +#define NVIDIA_X86_64_1_APBASE2 0xd8 +#define NVIDIA_X86_64_1_APLIMIT2 0xdc + static int nr_garts; static struct pci_dev * hammers[MAX_HAMMER_GARTS]; @@ -346,6 +350,10 @@ static __devinit int cache_nbs (struct p /* cache pci_devs of northbridges. */ while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) != NULL) { + if (i == MAX_HAMMER_GARTS) { + printk(KERN_ERR PFX "Too many northbridges for AGP\n"); + return -1; + } if (fix_northbridge(loop_dev, pdev, cap_ptr) < 0) { printk(KERN_ERR PFX "No usable aperture found.\n"); #ifdef __x86_64__ @@ -355,29 +363,111 @@ static __devinit int cache_nbs (struct p return -1; } hammers[i++] = loop_dev; + } nr_garts = i; -#ifdef CONFIG_SMP - if (i > MAX_HAMMER_GARTS) { - printk(KERN_ERR PFX "Too many northbridges for AGP\n"); - return -1; + return i == 0 ? -1 : 0; +} + +/* Handle AMD 8151 quirks */ +static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data *bridge) + +{ + char *revstring; + u8 rev_id; + + pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); + switch (rev_id) { + case 0x01: revstring="A0"; break; + case 0x02: revstring="A1"; break; + case 0x11: revstring="B0"; break; + case 0x12: revstring="B1"; break; + case 0x13: revstring="B2"; break; + default: revstring="??"; break; } -#else - /* Uniprocessor case, return after finding first bridge. - (There may be more, but in UP, we don't care). */ - return 0; -#endif + + printk (KERN_INFO PFX "Detected AMD 8151 AGP Bridge rev %s\n", revstring); + + /* + * Work around errata. + * Chips before B2 stepping incorrectly reporting v3.5 + */ + if (rev_id < 0x13) { + printk (KERN_INFO PFX "Correcting AGP revision (reports 3.5, is really 3.0)\n"); + bridge->major_version = 3; + bridge->minor_version = 0; } +} - return i == 0 ? -1 : 0; +static struct aper_size_info_32 nforce3_sizes[5] = +{ + {512, 131072, 7, 0x00000000 }, + {256, 65536, 6, 0x00000008 }, + {128, 32768, 5, 0x0000000C }, + {64, 16384, 4, 0x0000000E }, + {32, 8192, 3, 0x0000000F } +}; + +/* Handle shadow device of the Nvidia NForce3 */ +/* CHECK-ME original 2.4 version set up some IORRs. Check if that is needed. */ +static int __devinit nforce3_agp_init(struct pci_dev *pdev) +{ + u32 tmp, apbase, apbar, aplimit; + struct pci_dev *dev1; + int i; + unsigned size = amd64_fetch_size(); + + printk(KERN_INFO PFX "Setting up Nforce3 AGP.\n"); + + dev1 = pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(11, 0)); + if (dev1 == NULL) { + printk(KERN_INFO PFX "agpgart: Detected an NVIDIA " + "nForce3 chipset, but could not find " + "the secondary device.\n"); + return -ENODEV; + } + + for (i = 0; i < ARRAY_SIZE(nforce3_sizes); i++) + if (nforce3_sizes[i].size == size) + break; + + if (i == ARRAY_SIZE(nforce3_sizes)) { + printk(KERN_INFO PFX "No NForce3 size found for %d\n", size); + return -ENODEV; + } + + pci_read_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, &tmp); + tmp &= ~(0xf); + tmp |= nforce3_sizes[i].size_value; + pci_write_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, tmp); + + /* shadow x86-64 registers into NVIDIA registers */ + pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &apbase); + + /* if x86-64 aperture base is beyond 4G, exit here */ + if ( (apbase & 0x7fff) >> (32 - 25) ) + return -ENODEV; + + apbase = (apbase & 0x7fff) << 25; + + pci_read_config_dword(pdev, NVIDIA_X86_64_0_APBASE, &apbar); + apbar &= ~PCI_BASE_ADDRESS_MEM_MASK; + apbar |= apbase; + pci_write_config_dword(pdev, NVIDIA_X86_64_0_APBASE, apbar); + + aplimit = apbase + (size * 1024 * 1024) - 1; + pci_write_config_dword(dev1, NVIDIA_X86_64_1_APBASE1, apbase); + pci_write_config_dword(dev1, NVIDIA_X86_64_1_APLIMIT1, aplimit); + pci_write_config_dword(dev1, NVIDIA_X86_64_1_APBASE2, apbase); + pci_write_config_dword(dev1, NVIDIA_X86_64_1_APLIMIT2, aplimit); + + return 0; } static int __devinit agp_amd64_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct agp_bridge_data *bridge; - u8 rev_id; u8 cap_ptr; - char *revstring=NULL; cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); if (!cap_ptr) @@ -391,32 +481,7 @@ static int __devinit agp_amd64_probe(str if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == PCI_DEVICE_ID_AMD_8151_0) { - - pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); - switch (rev_id) { - case 0x01: revstring="A0"; - break; - case 0x02: revstring="A1"; - break; - case 0x11: revstring="B0"; - break; - case 0x12: revstring="B1"; - break; - case 0x13: revstring="B2"; - break; - default: revstring="??"; - break; - } - printk (KERN_INFO PFX "Detected AMD 8151 AGP Bridge rev %s\n", revstring); - /* - * Work around errata. - * Chips before B2 stepping incorrectly reporting v3.5 - */ - if (rev_id < 0x13) { - printk (KERN_INFO PFX "Correcting AGP revision (reports 3.5, is really 3.0)\n"); - bridge->major_version = 3; - bridge->minor_version = 0; - } + amd8151_init(pdev, bridge); } else { printk(KERN_INFO PFX "Detected AGP bridge %x\n", pdev->devfn); @@ -434,6 +499,14 @@ static int __devinit agp_amd64_probe(str return -ENODEV; } + if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) { + int ret = nforce3_agp_init(pdev); + if (ret) { + agp_put_bridge(bridge); + return ret; + } + } + pci_set_drvdata(pdev, bridge); return agp_add_bridge(bridge); } @@ -478,8 +551,25 @@ static struct pci_device_id agp_amd64_pc { .class = (PCI_CLASS_BRIDGE_HOST << 8), .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_755, + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_8380_0, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + /* NForce3 */ + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE3, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE3S, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/drivers/char/drm/Kconfig 170-x86_64/drivers/char/drm/Kconfig --- 160-lotsa_sds/drivers/char/drm/Kconfig Mon Nov 17 18:28:44 2003 +++ 170-x86_64/drivers/char/drm/Kconfig Fri Jan 9 21:02:04 2004 @@ -64,10 +64,9 @@ config DRM_I830 module will be called i830. AGP support is required for this driver to work. - config DRM_MGA tristate "Matrox g200/g400" - depends on DRM && AGP + depends on DRM && AGP && (!X86_64 || BROKEN) help Choose this option if you have a Matrox G200, G400 or G450 graphics card. If M is selected, the module will be called mga. AGP diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/drivers/net/pcmcia/Kconfig 170-x86_64/drivers/net/pcmcia/Kconfig --- 160-lotsa_sds/drivers/net/pcmcia/Kconfig Mon Nov 17 18:28:50 2003 +++ 170-x86_64/drivers/net/pcmcia/Kconfig Fri Jan 9 21:02:04 2004 @@ -119,7 +119,7 @@ config ARCNET_COM20020_CS config PCMCIA_IBMTR tristate "IBM PCMCIA tokenring adapter support" - depends on NET_PCMCIA && IBMTR!=y && TR && PCMCIA + depends on NET_PCMCIA && IBMTR!=y && TR && PCMCIA && !64BIT help Say Y here if you intend to attach this type of Token Ring PCMCIA card to your computer. You then also need to say Y to "Token Ring diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/drivers/scsi/Kconfig 170-x86_64/drivers/scsi/Kconfig --- 160-lotsa_sds/drivers/scsi/Kconfig Fri Jan 9 21:02:01 2004 +++ 170-x86_64/drivers/scsi/Kconfig Fri Jan 9 21:02:04 2004 @@ -1396,7 +1396,7 @@ config SCSI_ULTRASTOR config SCSI_NSP32 tristate "Workbit NinjaSCSI-32Bi/UDE support" - depends on PCI && SCSI + depends on PCI && SCSI && !64BIT help This is support for the Workbit NinjaSCSI-32Bi/UDE PCI/Cardbus SCSI host adapter. Please read the SCSI-HOWTO, available from diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/include/asm-x86_64/hpet.h 170-x86_64/include/asm-x86_64/hpet.h --- 160-lotsa_sds/include/asm-x86_64/hpet.h Wed Dec 31 16:00:00 1969 +++ 170-x86_64/include/asm-x86_64/hpet.h Fri Jan 9 21:02:04 2004 @@ -0,0 +1,59 @@ +#ifndef _ASM_X8664_HPET_H +#define _ASM_X8664_HPET_H 1 + +#include + +/* + * Documentation on HPET can be found at: + * http://www.intel.com/ial/home/sp/pcmmspec.htm + * ftp://download.intel.com/ial/home/sp/mmts098.pdf + */ + +#define HPET_MMAP_SIZE 1024 + +#define HPET_ID 0x000 +#define HPET_PERIOD 0x004 +#define HPET_CFG 0x010 +#define HPET_STATUS 0x020 +#define HPET_COUNTER 0x0f0 +#define HPET_T0_CFG 0x100 +#define HPET_T0_CMP 0x108 +#define HPET_T0_ROUTE 0x110 +#define HPET_T1_CFG 0x120 +#define HPET_T1_CMP 0x128 +#define HPET_T1_ROUTE 0x130 +#define HPET_T2_CFG 0x140 +#define HPET_T2_CMP 0x148 +#define HPET_T2_ROUTE 0x150 + +#define HPET_ID_VENDOR 0xffff0000 +#define HPET_ID_LEGSUP 0x00008000 +#define HPET_ID_NUMBER 0x00001f00 +#define HPET_ID_REV 0x000000ff + +#define HPET_ID_VENDOR_SHIFT 16 +#define HPET_ID_VENDOR_8086 0x8086 + +#define HPET_CFG_ENABLE 0x001 +#define HPET_CFG_LEGACY 0x002 + +#define HPET_TN_ENABLE 0x004 +#define HPET_TN_PERIODIC 0x008 +#define HPET_TN_PERIODIC_CAP 0x010 +#define HPET_TN_SETVAL 0x040 +#define HPET_TN_32BIT 0x100 + +extern int is_hpet_enabled(void); +extern int hpet_rtc_timer_init(void); + +#ifdef CONFIG_HPET_EMULATE_RTC +extern int hpet_mask_rtc_irq_bit(unsigned long bit_mask); +extern int hpet_set_rtc_irq_bit(unsigned long bit_mask); +extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec); +extern int hpet_set_periodic_freq(unsigned long freq); +extern int hpet_rtc_dropped_irq(void); +extern int hpet_rtc_timer_init(void); +extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs); +#endif /* CONFIG_HPET_EMULATE_RTC */ + +#endif diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/include/asm-x86_64/hw_irq.h 170-x86_64/include/asm-x86_64/hw_irq.h --- 160-lotsa_sds/include/asm-x86_64/hw_irq.h Fri Jan 9 17:40:08 2004 +++ 170-x86_64/include/asm-x86_64/hw_irq.h Fri Jan 9 21:02:04 2004 @@ -106,8 +106,6 @@ extern unsigned long io_apic_irqs; extern atomic_t irq_err_count; extern atomic_t irq_mis_count; -extern char _stext, _etext; - #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs)) #define __STR(x) #x diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/include/asm-x86_64/ia32.h 170-x86_64/include/asm-x86_64/ia32.h --- 160-lotsa_sds/include/asm-x86_64/ia32.h Mon Nov 17 18:28:20 2003 +++ 170-x86_64/include/asm-x86_64/ia32.h Fri Jan 9 21:02:04 2004 @@ -100,8 +100,11 @@ typedef struct siginfo32 { /* POSIX.1b timers */ struct { - unsigned int _timer1; - unsigned int _timer2; + int _tid; /* timer id */ + int _overrun; /* overrun count */ + sigval_t32 _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ + int _overrun_incr; /* amount to add to overrun */ } _timer; /* POSIX.1b signals */ @@ -164,9 +167,12 @@ struct ustat32 { #ifdef __KERNEL__ struct user_desc; +struct siginfo_t; int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info); int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info); int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs); +int ia32_copy_siginfo_from_user(siginfo_t *to, siginfo_t32 __user *from); +int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from); #endif #endif /* !CONFIG_IA32_SUPPORT */ diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/include/asm-x86_64/mc146818rtc.h 170-x86_64/include/asm-x86_64/mc146818rtc.h --- 160-lotsa_sds/include/asm-x86_64/mc146818rtc.h Sat Jun 14 18:37:37 2003 +++ 170-x86_64/include/asm-x86_64/mc146818rtc.h Fri Jan 9 21:02:04 2004 @@ -24,11 +24,6 @@ outb_p((addr),RTC_PORT(0)); \ outb_p((val),RTC_PORT(1)); \ }) -#ifndef CONFIG_HPET_TIMER #define RTC_IRQ 8 -#else -/* Temporary workaround due to IRQ routing problem. */ -#define RTC_IRQ 0 -#endif #endif /* _ASM_MC146818RTC_H */ diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/include/asm-x86_64/scatterlist.h 170-x86_64/include/asm-x86_64/scatterlist.h --- 160-lotsa_sds/include/asm-x86_64/scatterlist.h Wed Jul 2 21:59:15 2003 +++ 170-x86_64/include/asm-x86_64/scatterlist.h Fri Jan 9 21:02:04 2004 @@ -6,6 +6,7 @@ struct scatterlist { unsigned int offset; unsigned int length; dma_addr_t dma_address; + unsigned int dma_length; }; #define ISA_DMA_THRESHOLD (0x00ffffff) @@ -16,6 +17,6 @@ struct scatterlist { * returns. */ #define sg_dma_address(sg) ((sg)->dma_address) -#define sg_dma_len(sg) ((sg)->length) +#define sg_dma_len(sg) ((sg)->dma_length) #endif diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/include/asm-x86_64/timex.h 170-x86_64/include/asm-x86_64/timex.h --- 160-lotsa_sds/include/asm-x86_64/timex.h Tue Jun 17 20:58:53 2003 +++ 170-x86_64/include/asm-x86_64/timex.h Fri Jan 9 21:02:04 2004 @@ -9,6 +9,7 @@ #include #include #include +#include #define CLOCK_TICK_RATE 1193182 /* Underlying HZ */ #define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ @@ -29,34 +30,6 @@ static inline cycles_t get_cycles (void) } extern unsigned int cpu_khz; - -/* - * Documentation on HPET can be found at: - * http://www.intel.com/ial/home/sp/pcmmspec.htm - * ftp://download.intel.com/ial/home/sp/mmts098.pdf - */ - -#define HPET_ID 0x000 -#define HPET_PERIOD 0x004 -#define HPET_CFG 0x010 -#define HPET_STATUS 0x020 -#define HPET_COUNTER 0x0f0 -#define HPET_T0_CFG 0x100 -#define HPET_T0_CMP 0x108 -#define HPET_T0_ROUTE 0x110 - -#define HPET_ID_VENDOR 0xffff0000 -#define HPET_ID_LEGSUP 0x00008000 -#define HPET_ID_NUMBER 0x00000f00 -#define HPET_ID_REV 0x000000ff - -#define HPET_CFG_ENABLE 0x001 -#define HPET_CFG_LEGACY 0x002 - -#define HPET_T0_ENABLE 0x004 -#define HPET_T0_PERIODIC 0x008 -#define HPET_T0_SETVAL 0x040 -#define HPET_T0_32BIT 0x100 extern struct vxtime_data vxtime; diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/include/linux/compat_ioctl.h 170-x86_64/include/linux/compat_ioctl.h --- 160-lotsa_sds/include/linux/compat_ioctl.h Fri Jan 9 17:40:08 2004 +++ 170-x86_64/include/linux/compat_ioctl.h Fri Jan 9 21:02:04 2004 @@ -260,6 +260,7 @@ COMPATIBLE_IOCTL(SIOCATMARK) COMPATIBLE_IOCTL(SIOCSIFLINK) COMPATIBLE_IOCTL(SIOCSIFENCAP) COMPATIBLE_IOCTL(SIOCGIFENCAP) +COMPATIBLE_IOCTL(SIOCSIFNAME) COMPATIBLE_IOCTL(SIOCSIFBR) COMPATIBLE_IOCTL(SIOCGIFBR) COMPATIBLE_IOCTL(SIOCSARP) diff -aurpN -X /home/fletch/.diff.exclude 160-lotsa_sds/include/linux/pci_ids.h 170-x86_64/include/linux/pci_ids.h --- 160-lotsa_sds/include/linux/pci_ids.h Fri Jan 9 19:04:00 2004 +++ 170-x86_64/include/linux/pci_ids.h Fri Jan 9 21:02:04 2004 @@ -1034,6 +1034,8 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE 0x0085 #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA 0x008e #define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0 +#define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1 +#define PCI_DEVICE_ID_NVIDIA_NFORCE3S 0x00e1 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA 0x00e3 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE 0x00e5