From d3069e7f64a42a60e78a187399325b4990e3d222 Mon Sep 17 00:00:00 2001 From: Rod Whitby Date: Mon, 20 Mar 2006 23:32:38 +0000 Subject: ixp4xx-kernel: Added missing patches --- .../ixp4xx-kernel/2.6.16/10-ixp4xx-fix-irq.patch | 25 + .../2.6.16/83-nas100d-memory-fixup.patch | 66 + .../ixp4xx-kernel/2.6.16/84-nas100d-cmdline.patch | 31 + packages/linux/ixp4xx-kernel/2.6.16/97-ds101.patch | 457 + .../ixp4xx-kernel/2.6.16/patch-2.6.16-rc6-ide1 | 18684 +++++++++++++++++++ 5 files changed, 19263 insertions(+) create mode 100644 packages/linux/ixp4xx-kernel/2.6.16/10-ixp4xx-fix-irq.patch create mode 100644 packages/linux/ixp4xx-kernel/2.6.16/83-nas100d-memory-fixup.patch create mode 100644 packages/linux/ixp4xx-kernel/2.6.16/84-nas100d-cmdline.patch create mode 100644 packages/linux/ixp4xx-kernel/2.6.16/97-ds101.patch create mode 100644 packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc6-ide1 (limited to 'packages') diff --git a/packages/linux/ixp4xx-kernel/2.6.16/10-ixp4xx-fix-irq.patch b/packages/linux/ixp4xx-kernel/2.6.16/10-ixp4xx-fix-irq.patch new file mode 100644 index 0000000000..4326df2add --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/10-ixp4xx-fix-irq.patch @@ -0,0 +1,25 @@ +--- + arch/arm/mach-ixp4xx/common.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/common.c 2006-03-18 18:10:56.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/common.c 2006-03-18 18:48:46.000000000 +0100 +@@ -91,7 +91,7 @@ static void ixp4xx_config_irq(unsigned i + /* + * IRQ -> GPIO mapping table + */ +-static int irq2gpio[32] = { ++static char irq2gpio[32] = { + -1, -1, -1, -1, -1, -1, 0, 1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 2, 3, 4, 5, 6, +@@ -153,6 +153,9 @@ static int ixp4xx_set_irq_type(unsigned + /* Set the new style */ + *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); + ++ /* Configure the line as an input */ ++ gpio_line_config(line, IXP4XX_GPIO_IN); ++ + return 0; + } + diff --git a/packages/linux/ixp4xx-kernel/2.6.16/83-nas100d-memory-fixup.patch b/packages/linux/ixp4xx-kernel/2.6.16/83-nas100d-memory-fixup.patch new file mode 100644 index 0000000000..3d5e20c6cf --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/83-nas100d-memory-fixup.patch @@ -0,0 +1,66 @@ +Include a fixup machine start function in nas100d-setup.c to handle +the command line and memory setup parameters which are not specifiable +in the boot loader. + +TODO: We must check what is actually passed by the stock +RedBoot on the nas100d. + +Signed-off-by: John Bowler + + arch/arm/mach-ixp4xx/nas100d-setup.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-03-09 02:13:15.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-03-09 02:13:54.000000000 +0100 +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + static struct flash_platform_data nas100d_flash_data = { + .map_name = "cfi_probe", +@@ -125,11 +126,43 @@ static void __init nas100d_init(void) + platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices)); + } + ++/* ++ * NAS100D bootstrap may pass in parameters, but we zap the mem ++ * settings to be safe (the box always has 64MByte at 0). The ++ * passed in command line can override this default, we prepend ++ * to the config'ed default. ++ * ++ * NOTE: the startup sequence is: ++ * 1) Call the machine fixup ++ * 2) Parse the ATAG list, the ATAG_CMDLINE is copied in ++ * to default_command_line which is the value of *from ++ * 3) Parse the command line in *from (*not* ++ * default_command_line unless they are the same!) ++ * ++ * Setting mi->nr_banks causes (2) to 'squash' (set to ATAG_NONE) ++ * any ATAG_MEM tags, but mem= command line options cause nr_banks ++ * to be reset to 0 (on the first mem=) ++ */ ++ ++static void __init nas100d_fixup(struct machine_desc *desc, ++ struct tag *tags, char **cmdline, struct meminfo *mi) ++{ ++ /* The NAS100D has one bank of 64MByte memory. ++ * NOTE: setting nr_banks != 0 causes kernel/setup.c to remove ++ * the mem tags from the tag list. We need do nothing here! ++ */ ++ mi->nr_banks = 1; ++ mi->bank[0].start = 0; ++ mi->bank[0].size = (64*1024*1024); ++ mi->bank[0].node = PHYS_TO_NID(0); ++} ++ + MACHINE_START(NAS100D, "Iomega NAS 100d") + /* Maintainer: www.nslu2-linux.org */ + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, + .boot_params = 0x00000100, ++ .fixup = nas100d_fixup, + .map_io = ixp4xx_map_io, + .init_irq = ixp4xx_init_irq, + .timer = &ixp4xx_timer, diff --git a/packages/linux/ixp4xx-kernel/2.6.16/84-nas100d-cmdline.patch b/packages/linux/ixp4xx-kernel/2.6.16/84-nas100d-cmdline.patch new file mode 100644 index 0000000000..2f02f5622d --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/84-nas100d-cmdline.patch @@ -0,0 +1,31 @@ +--- + arch/arm/mach-ixp4xx/nas100d-setup.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-03-09 02:14:52.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/nas100d-setup.c 2006-03-09 02:16:43.000000000 +0100 +@@ -144,6 +144,12 @@ static void __init nas100d_init(void) + * to be reset to 0 (on the first mem=) + */ + ++static char nas100d_command_line[] __initdata = ++ "root=/dev/mtdblock2 rootfstype=jffs2 init=/linuxrc " ++ "rtc-pcf8563.probe=0,0x51 " ++ CONFIG_CMDLINE; ++ ++ + static void __init nas100d_fixup(struct machine_desc *desc, + struct tag *tags, char **cmdline, struct meminfo *mi) + { +@@ -155,6 +161,11 @@ static void __init nas100d_fixup(struct + mi->bank[0].start = 0; + mi->bank[0].size = (64*1024*1024); + mi->bank[0].node = PHYS_TO_NID(0); ++ ++ /* A command line in the ATAG list will override this one, ++ * as is intended. ++ */ ++ strlcpy(*cmdline, nas100d_command_line, COMMAND_LINE_SIZE); + } + + MACHINE_START(NAS100D, "Iomega NAS 100d") diff --git a/packages/linux/ixp4xx-kernel/2.6.16/97-ds101.patch b/packages/linux/ixp4xx-kernel/2.6.16/97-ds101.patch new file mode 100644 index 0000000000..77df5ace86 --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/97-ds101.patch @@ -0,0 +1,457 @@ + arch/arm/mach-ixp4xx/Kconfig | 8 + + arch/arm/mach-ixp4xx/Makefile | 2 + arch/arm/mach-ixp4xx/ds101-pci.c | 66 +++++++++ + arch/arm/mach-ixp4xx/ds101-setup.c | 234 +++++++++++++++++++++++++++++++++ + include/asm-arm/arch-ixp4xx/ds101.h | 88 ++++++++++++ + include/asm-arm/arch-ixp4xx/hardware.h | 1 + include/asm-arm/arch-ixp4xx/irqs.h | 8 + + 7 files changed, 406 insertions(+), 1 deletion(-) + +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/ds101.h 2006-03-08 08:41:31.000000000 +0100 +@@ -0,0 +1,88 @@ ++/* ++ * DS101 platform specific definitions ++ * ++ * Author: Øyvind Repvik ++ * ++ * based on ixdp425.h: ++ * Copyright 2004 (c) MontaVista, Software, Inc. ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#ifndef __ASM_ARCH_HARDWARE_H__ ++#error "Do not include this directly, instead #include " ++#endif ++ ++#define DS101_SCL_PIN DS101_GPIO0 ++#define DS101_SDA_PIN DS101_GPIO1 ++#define DS101_GPIO_BUZZ DS101_GPIO2 ++#define DS101_POWER_LED DS101_GPIO3 ++#define DS101_USBCOPYB_GPIO DS101_GPIO4 /* shared */ ++#define DS101_USBCOPY_SOLID_LED DS101_GPIO4 /* shared */ ++#define DS101_USBCOPY_BLINK_LED DS101_GPIO5 ++/* GPIO6 is unknown */ ++#define DS101_POWEROFF_GPIO DS101_GPIO7 ++#define DS101_POWERB_GPIO DS101_GPIO8 ++/*#define DS101_PCI_INTC_PIN DS101_GPIO9 ++#define DS101_PCI_INTB_PIN DS101_GPIO10 ++#define DS101_PCI_INTA_PIN DS101_GPIO11 ++*/ ++#define DS101_RESETB_GPIO DS101_GPIO12 ++#define DS101_STATUSOK_LED DS101_GPIO14 ++#define DS101_STATUSBAD_LED DS101_GPIO15 ++ ++#define DS101_PCI_MAX_DEV 2 ++#define DS101_PCI_IRQ_LINES 3 ++ ++#define DS101_POWERB_IRQ IRQ_IXP4XX_GPIO8 ++#define DS101_RESETB_IRQ IRQ_IXP4XX_GPIO12 ++#define DS101_USBCOPYB_IRQ IRQ_IXP4XX_GPIO4 ++ ++/* XXX use IXP4XX_GPIO_XX directly */ ++#define DS101_GPIO_IN IXP4XX_GPIO_IN ++#define DS101_GPIO_OUT IXP4XX_GPIO_OUT ++#define DS101_GPIO_HIGH 1 ++#define DS101_GPIO_LOW 0 ++ ++/* GPIO */ ++ ++#define DS101_GPIO0 0 ++#define DS101_GPIO1 1 ++#define DS101_GPIO2 2 ++#define DS101_GPIO3 3 ++#define DS101_GPIO4 4 ++#define DS101_GPIO5 5 ++#define DS101_GPIO6 6 ++#define DS101_GPIO7 7 ++#define DS101_GPIO8 8 ++#define DS101_GPIO9 9 ++#define DS101_GPIO10 10 ++#define DS101_GPIO11 11 ++#define DS101_GPIO12 12 ++#define DS101_GPIO13 13 ++#define DS101_GPIO14 14 ++#define DS101_GPIO15 15 ++ ++/* Stuff needed to setup the IXP expansion ++ * bus on the DS101 ++ */ ++ ++#define DS101_EXP_RECOVERY_T(x) (((x) & 15) << 16) ++#define DS101_EXP_HOLD_T(x) (((x) & 3) << 20) ++#define DS101_EXP_STROBE_T(x) (((x) & 15) << 22) ++#define DS101_EXP_SETUP_T(x) (((x) & 3) << 26) ++#define DS101_EXP_ADDR_T(x) (((x) & 3) << 28) ++ ++#define DS101_EXP_SZ_16M (15 << 10) ++#define DS101_EXP_WR_EN (1 << 1) ++#define DS101_EXP_BYTE_RD16 (1 << 6) ++#define DS101_EXP_CS_EN (1 << 31) ++ ++/* XXX nope. use the _EXP_ macros in the -setup.c */ ++#define DS101_EXP_CS0_INIT (DS101_EXP_ADDR_T(1) | \ ++ DS101_EXP_SETUP_T(1) | DS101_EXP_STROBE_T(1) | \ ++ DS101_EXP_HOLD_T(1) | DS101_EXP_RECOVERY_T(1)| \ ++ DS101_EXP_SZ_16M | DS101_EXP_WR_EN | \ ++ DS101_EXP_BYTE_RD16 | DS101_EXP_CS_EN) +--- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/hardware.h 2006-03-08 08:41:02.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/hardware.h 2006-03-08 08:41:31.000000000 +0100 +@@ -47,5 +47,6 @@ extern unsigned int processor_id; + #include "nslu2.h" + #include "nas100d.h" + #include "dsmg600.h" ++#include "ds101.h" + + #endif /* _ASM_ARCH_HARDWARE_H */ +--- linux-ixp4xx.orig/include/asm-arm/arch-ixp4xx/irqs.h 2006-03-08 08:41:02.000000000 +0100 ++++ linux-ixp4xx/include/asm-arm/arch-ixp4xx/irqs.h 2006-03-08 08:41:31.000000000 +0100 +@@ -110,6 +110,14 @@ + #define IRQ_NAS100D_PCI_INTE IRQ_IXP4XX_GPIO7 + + /* ++ * Synology DS101 board IRQs ++ */ ++ ++#define IRQ_DS101_PCI_INTA IRQ_IXP4XX_GPIO11 ++#define IRQ_DS101_PCI_INTB IRQ_IXP4XX_GPIO10 ++#define IRQ_DS101_PCI_INTC IRQ_IXP4XX_GPIO9 ++ ++/* + * D-Link DSM-G600 board IRQs + */ + #define IRQ_DSMG600_PCI_INTA IRQ_IXP4XX_GPIO11 +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/ds101-pci.c 2006-03-08 08:41:31.000000000 +0100 +@@ -0,0 +1,66 @@ ++/* ++ * DS101 board-level PCI initialization ++ * ++ * based on ixdp425-pci.c: ++ * Copyright (C) 2002 Intel Corporation. ++ * Copyright (C) 2003-2004 MontaVista Software, Inc. ++ * ++ * Maintainer: http://www.nslu2-linux.org/ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++void __init ds101_pci_preinit(void) ++{ ++ set_irq_type(IRQ_DS101_PCI_INTA, IRQT_LOW); ++ set_irq_type(IRQ_DS101_PCI_INTB, IRQT_LOW); ++ set_irq_type(IRQ_DS101_PCI_INTC, IRQT_LOW); ++ ++ ixp4xx_pci_preinit(); ++} ++ ++static int __init ds101_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ static int pci_irq_table[DS101_PCI_MAX_DEV][DS101_PCI_IRQ_LINES] = ++ { ++ { IRQ_DS101_PCI_INTA, -1, -1 }, ++ { IRQ_DS101_PCI_INTB, IRQ_DS101_PCI_INTB, IRQ_DS101_PCI_INTC }, ++ }; ++ ++ int irq = -1; ++ ++ if (slot >= 1 && slot <= DS101_PCI_MAX_DEV && ++ pin >= 1 && pin <= DS101_PCI_IRQ_LINES) ++ irq = pci_irq_table[slot-1][pin-1]; ++ ++ return irq; ++} ++ ++struct hw_pci __initdata ds101_pci = { ++ .nr_controllers = 1, ++ .preinit = ds101_pci_preinit, ++ .swizzle = pci_std_swizzle, ++ .setup = ixp4xx_setup, ++ .scan = ixp4xx_scan_bus, ++ .map_irq = ds101_map_irq, ++}; ++ ++int __init ds101_pci_init(void) ++{ ++ if (machine_is_ds101()) ++ pci_common_init(&ds101_pci); ++ ++ return 0; ++} ++ ++subsys_initcall(ds101_pci_init); +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/ds101-setup.c 2006-03-08 08:41:31.000000000 +0100 +@@ -0,0 +1,234 @@ ++/* ++ * Synology DS101 board setup ++ * ++ * based ixdp425-setup.c: ++ * Copyright (C) 2003-2004 MontaVista Software, Inc. ++ * ++ * Author: Alessandro Zummo ++ * Author: Rod Whitby ++ * Author: OEyvind Repvik ++ * Maintainers: http://www.nslu2-linux.org/ ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_LEDS_CLASS ++static struct resource ds101_led_resources[] = { ++ { ++ .name = "power", ++ .start = DS101_POWER_LED, ++ .end = DS101_POWER_LED, ++ .flags = IXP4XX_GPIO_LOW, ++ }, ++ { ++ .name = "usbcopy-solid", ++ .start = DS101_USBCOPY_SOLID_LED, ++ .end = DS101_USBCOPY_SOLID_LED, ++ .flags = IXP4XX_GPIO_LOW, ++ }, ++ { ++ .name = "usbcopy-blink", ++ .start = DS101_USBCOPY_BLINK_LED, ++ .end = DS101_USBCOPY_BLINK_LED, ++ .flags = IXP4XX_GPIO_LOW, ++ }, ++ { ++ .name = "status-ready", ++ .start = DS101_STATUSOK_LED, ++ .end = DS101_STATUSOK_LED, ++ .flags = IXP4XX_GPIO_LOW, ++ }, ++ { ++ .name = "status-error", ++ .start = DS101_STATUSBAD_LED, ++ .start = DS101_STATUSBAD_LED, ++ .flags = IXP4XX_GPIO_LOW, ++ } ++}; ++ ++ ++static struct platform_device ds101_leds = { ++ .name = "IXP4XX-GPIO-LED", ++ .id = -1, ++ .num_resources = ARRAY_SIZE(ds101_led_resources), ++ .resource = ds101_led_resources, ++}; ++#endif ++ ++static struct ixp4xx_i2c_pins ds101_i2c_gpio_pins = { ++ .sda_pin = DS101_SDA_PIN, ++ .scl_pin = DS101_SCL_PIN, ++}; ++ ++static struct platform_device ds101_i2c_controller = { ++ .name = "IXP4XX-I2C", ++ .id = 0, ++ .dev.platform_data = &ds101_i2c_gpio_pins, ++ .num_resources = 0, ++}; ++ ++static struct platform_device ds101_beeper = { ++ .name = "ixp4xx-beeper", ++ .id = DS101_GPIO_BUZZ, ++ .num_resources = 0, ++}; ++ ++static struct resource ds101_uart_resources[] = { ++ { ++ .start = IXP4XX_UART1_BASE_PHYS, ++ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IXP4XX_UART2_BASE_PHYS, ++ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++static struct plat_serial8250_port ds101_uart_data[] = { ++ { ++ .mapbase = IXP4XX_UART1_BASE_PHYS, ++ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, ++ .irq = IRQ_IXP4XX_UART1, ++ .flags = UPF_BOOT_AUTOCONF, ++ .iotype = UPIO_MEM, ++ .regshift = 2, ++ .uartclk = IXP4XX_UART_XTAL, ++ }, ++ { ++ .mapbase = IXP4XX_UART2_BASE_PHYS, ++ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++ .irq = IRQ_IXP4XX_UART2, ++ .flags = UPF_BOOT_AUTOCONF, ++ .iotype = UPIO_MEM, ++ .regshift = 2, ++ .uartclk = IXP4XX_UART_XTAL, ++ }, ++ { } ++}; ++ ++static struct platform_device ds101_uart = { ++ .name = "serial8250", ++ .id = PLAT8250_DEV_PLATFORM, ++ .dev.platform_data = ds101_uart_data, ++ .num_resources = 2, ++ .resource = ds101_uart_resources, ++}; ++ ++static struct platform_device *ds101_devices[] __initdata = { ++ &ds101_i2c_controller, ++ &ds101_beeper, ++}; ++ ++static void ds101_power_off(void) ++{ ++ /* Simple, but effective */ ++ gpio_line_set(DS101_POWEROFF_GPIO, IXP4XX_GPIO_LOW); ++} ++ ++static void ds101_gpio_setup(void) ++{ ++ /* Set up buzzer */ ++ gpio_line_config(DS101_GPIO_BUZZ, DS101_GPIO_OUT); ++ gpio_line_set(DS101_GPIO_BUZZ, DS101_GPIO_LOW); ++ ++ /* Set up power led */ ++ gpio_line_config(DS101_POWER_LED, DS101_GPIO_OUT); ++ gpio_line_set(DS101_POWER_LED, DS101_GPIO_LOW); ++ ++ /* Poweroff */ ++ gpio_line_config(DS101_POWEROFF_GPIO, DS101_GPIO_OUT); ++ gpio_line_set(DS101_POWEROFF_GPIO, DS101_GPIO_HIGH); ++ ++ /* Status leds */ ++ *IXP4XX_GPIO_GPCLKR = 0; ++ ++ /* XXX can't the leds subsystem take care of those? */ ++ gpio_line_config(DS101_STATUSOK_LED, DS101_GPIO_OUT); ++ gpio_line_config(DS101_STATUSBAD_LED, DS101_GPIO_OUT); ++ gpio_line_set(DS101_STATUSOK_LED, DS101_GPIO_HIGH); ++ gpio_line_set(DS101_STATUSBAD_LED, DS101_GPIO_LOW); ++}; ++ ++static void ds101_cs0_setup(void) ++{ ++ /* XXX don't use macro */ ++ *IXP4XX_EXP_CS0 = DS101_EXP_CS0_INIT; ++}; ++ ++static void __init ds101_init(void) ++{ ++ ixp4xx_sys_init(); ++ ++ ds101_cs0_setup(); /* Needed for DoC support */ ++ ds101_gpio_setup(); ++ pm_power_off = ds101_power_off; ++ ++ platform_add_devices(ds101_devices, ARRAY_SIZE(ds101_devices)); ++ ++ /* This is only useful on a modified machine, but it is valuable ++ * to have it first in order to see debug messages, and so that ++ * it does *not* get removed if platform_add_devices fails! ++ */ ++ (void)platform_device_register(&ds101_uart); ++ ++#ifdef CONFIG_LEDS_CLASS ++ /* We don't care whether or not this works. */ ++ (void)platform_device_register(&ds101_leds); ++#endif ++} ++ ++/* ++ * DS101 bootstrap may pass in parameters, but we zap the mem ++ * settings to be safe (DS101 always has 64MByte at 0, DS101J has ++ * 32MB). The passed in command line can override this default, we ++ * prepend to the config'ed default. ++ * ++ * NOTE: the startup sequence is: ++ * 1) Call the machine fixup ++ * 2) Parse the ATAG list, the ATAG_CMDLINE is copied in ++ * to default_command_line which is the value of *from ++ * 3) Parse the command line in *from (*not* ++ * default_command_line unless they are the same!) ++ * ++ * Setting mi->nr_banks causes (2) to 'squash' (set to ATAG_NONE) ++ * any ATAG_MEM tags, but mem= command line options cause nr_banks ++ * to be reset to 0 (on the first mem=) ++ */ ++ ++static void __init ds101_fixup(struct machine_desc *desc, ++ struct tag *tags, char **cmdline, struct meminfo *mi) ++{ ++ /* The DS101 has one bank of 64MByte memory. ++ * NOTE: setting nr_banks != 0 causes kernel/setup.c to remove ++ * the mem tags from the tag list. We need do nothing here! ++ */ ++ mi->nr_banks = 1; ++ mi->bank[0].start = 0; ++ mi->bank[0].size = (64*1024*1024); ++ mi->bank[0].node = PHYS_TO_NID(0); ++} ++ ++MACHINE_START(DS101, "Synology DiskStation DS101") ++ /* Maintainer: www.nslu2-linux.org */ ++ .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, ++ .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, ++ .boot_params = 0x00000100, ++ .fixup = ds101_fixup, ++ .map_io = ixp4xx_map_io, ++ .init_irq = ixp4xx_init_irq, ++ .timer = &ixp4xx_timer, ++ .init_machine = ds101_init, ++MACHINE_END +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/Kconfig 2006-03-08 08:41:02.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/Kconfig 2006-03-08 08:41:31.000000000 +0100 +@@ -93,6 +93,14 @@ config MACH_DSMG600 + DSM-G600 device. For more information on this platform, + see http://www.nslu2-linux.org/ + ++config MACH_DS101 ++ bool ++ prompt "Synology DS101" ++ help ++ Say 'Y' here if you want your kernel to support Synology's ++ DiskStation DS101(j) device. For more information on this ++ platform see http://www.nslu2-linux.org/wiki/DS101/HomePage ++ + # + # Avila and IXDP share the same source for now. Will change in future + # +--- linux-ixp4xx.orig/arch/arm/mach-ixp4xx/Makefile 2006-03-08 08:41:02.000000000 +0100 ++++ linux-ixp4xx/arch/arm/mach-ixp4xx/Makefile 2006-03-08 08:41:31.000000000 +0100 +@@ -11,4 +11,4 @@ obj-$(CONFIG_MACH_GTWX5715) += gtwx5715- + obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o + obj-$(CONFIG_MACH_NAS100D) += nas100d-pci.o nas100d-setup.o nas100d-power.o + obj-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o dsmg600-setup.o +- ++obj-$(CONFIG_MACH_DS101) += ds101-pci.o ds101-setup.o diff --git a/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc6-ide1 b/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc6-ide1 new file mode 100644 index 0000000000..f35facae1b --- /dev/null +++ b/packages/linux/ixp4xx-kernel/2.6.16/patch-2.6.16-rc6-ide1 @@ -0,0 +1,18684 @@ +diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc6/arch/i386/pci/fixup.c linux-2.6.16-rc6/arch/i386/pci/fixup.c +--- linux.vanilla-2.6.16-rc6/arch/i386/pci/fixup.c 2006-03-13 14:00:11.000000000 +0000 ++++ linux-2.6.16-rc6/arch/i386/pci/fixup.c 2006-02-01 14:49:17.000000000 +0000 +@@ -74,52 +74,6 @@ + } + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, pci_fixup_ncr53c810); + +-static void __devinit pci_fixup_ide_bases(struct pci_dev *d) +-{ +- int i; +- +- /* +- * PCI IDE controllers use non-standard I/O port decoding, respect it. +- */ +- if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) +- return; +- DBG("PCI: IDE base address fixup for %s\n", pci_name(d)); +- for(i=0; i<4; i++) { +- struct resource *r = &d->resource[i]; +- if ((r->start & ~0x80) == 0x374) { +- r->start |= 2; +- r->end = r->start; +- } +- } +-} +-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); +- +-static void __devinit pci_fixup_ide_trash(struct pci_dev *d) +-{ +- int i; +- +- /* +- * Runs the fixup only for the first IDE controller +- * (Shai Fultheim - shai@ftcon.com) +- */ +- static int called = 0; +- if (called) +- return; +- called = 1; +- +- /* +- * There exist PCI IDE controllers which have utter garbage +- * in first four base registers. Ignore that. +- */ +- DBG("PCI: IDE base address trash cleared for %s\n", pci_name(d)); +- for(i=0; i<4; i++) +- d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0; +-} +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, pci_fixup_ide_trash); +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_fixup_ide_trash); +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, pci_fixup_ide_trash); +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_9, pci_fixup_ide_trash); +- + static void __devinit pci_fixup_latency(struct pci_dev *d) + { + /* +diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc6/drivers/cdrom/cdrom.c linux-2.6.16-rc6/drivers/cdrom/cdrom.c +--- linux.vanilla-2.6.16-rc6/drivers/cdrom/cdrom.c 2006-03-13 14:00:12.000000000 +0000 ++++ linux-2.6.16-rc6/drivers/cdrom/cdrom.c 2006-01-17 16:34:19.000000000 +0000 +@@ -1131,7 +1131,8 @@ + This ensures that the drive gets unlocked after a mount fails. This + is a goto to avoid bloating the driver with redundant code. */ + clean_up_and_return: +- cdinfo(CD_OPEN, "open failed.\n"); ++ /* Don't log this, its a perfectly normal user occurence */ ++ /* cdinfo(CD_WARNING, "open failed.\n"); */ + if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) { + cdo->lock_door(cdi, 0); + cdinfo(CD_OPEN, "door unlocked.\n"); +diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc6/drivers/pci/probe.c linux-2.6.16-rc6/drivers/pci/probe.c +--- linux.vanilla-2.6.16-rc6/drivers/pci/probe.c 2006-03-13 14:00:13.000000000 +0000 ++++ linux-2.6.16-rc6/drivers/pci/probe.c 2006-02-01 15:56:28.000000000 +0000 +@@ -627,6 +627,7 @@ + static int pci_setup_device(struct pci_dev * dev) + { + u32 class; ++ u16 cmd; + + sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); +@@ -654,6 +655,31 @@ + pci_read_bases(dev, 6, PCI_ROM_ADDRESS); + pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor); + pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); ++ ++ /* ++ * Do the ugly legacy mode stuff here rather than broken chip ++ * quirk code. Legacy mode ATA controllers have fixed ++ * addresses. These are not always echoed in BAR0-3, and ++ * BAR0-3 in a few cases contain junk! ++ */ ++ if (class == PCI_CLASS_STORAGE_IDE) { ++ u8 progif; ++ pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); ++ if ((progif & 5) != 5) { ++ dev->resource[0].start = 0x1F0; ++ dev->resource[0].end = 0x1F7; ++ dev->resource[0].flags = IORESOURCE_IO; ++ dev->resource[1].start = 0x3F6; ++ dev->resource[1].end = 0x3F6; ++ dev->resource[1].flags = IORESOURCE_IO; ++ dev->resource[2].start = 0x170; ++ dev->resource[2].end = 0x177; ++ dev->resource[2].flags = IORESOURCE_IO; ++ dev->resource[3].start = 0x376; ++ dev->resource[3].end = 0x376; ++ dev->resource[3].flags = IORESOURCE_IO; ++ } ++ } + break; + + case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ +diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc6/drivers/scsi/ata_generic.c linux-2.6.16-rc6/drivers/scsi/ata_generic.c +--- linux.vanilla-2.6.16-rc6/drivers/scsi/ata_generic.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16-rc6/drivers/scsi/ata_generic.c 2006-02-16 15:35:41.000000000 +0000 +@@ -0,0 +1,241 @@ ++/* ++ * ata_generic.c - Generic PATA/SATA controller driver. ++ * Copyright 2005 Red Hat Inc , all rights reserved. ++ * ++ * Elements from ide/pci/generic.c ++ * Copyright (C) 2001-2002 Andre Hedrick ++ * Portions (C) Copyright 2002 Red Hat Inc ++ * ++ * May be copied or modified under the terms of the GNU General Public License ++ * ++ * Driver for PCI IDE interfaces implementing the standard bus mastering ++ * interface functionality. This assumes the BIOS did the drive set up and ++ * tuning for us. By default we do not grab all IDE class devices as they ++ * may have other drivers or need fixups to avoid problems. Instead we keep ++ * a default list of stuff without documentation/driver that appears to ++ * work. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "scsi.h" ++#include ++#include ++ ++#define DRV_NAME "generic" ++#define DRV_VERSION "0.1" ++ ++/* ++ * A generic parallel ATA driver using libata ++ */ ++ ++static void genpata_phy_reset(struct ata_port *ap) ++{ ++ /* We know the BIOS already did the mode work. Don't tempt any ++ one else to "fix" things */ ++ ap->cbl = ATA_CBL_PATA80; ++ ata_port_probe(ap); ++ ata_bus_reset(ap); ++} ++ ++/** ++ * genpata_set_mode - mode setting ++ * @ap: interface to set up ++ * ++ * Use a non standard set_mode function. We don't want to be tuned. ++ * The BIOS configured everything. Our job is not to fiddle. We ++ * read the dma enabled bits from the PCI configuration of the device ++ * and respect them. ++ */ ++ ++static void genpata_set_mode(struct ata_port *ap) ++{ ++ int dma_enabled; ++ int i; ++ ++ /* Bits 5 and 6 indicate if DMA is active on master/slave */ ++ dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); ++ ++ for (i = 0; i < ATA_MAX_DEVICES; i++) { ++ struct ata_device *dev = &ap->device[i]; ++ if (ata_dev_present(dev)) { ++ /* We don't really care */ ++ dev->pio_mode = XFER_PIO_0; ++ dev->dma_mode = XFER_MW_DMA_0; ++ /* We do need the right mode information for DMA or PIO ++ and this comes from the current configuration flags */ ++ /* FIXME: at some point in the future this should become ++ a library helper which reads the disk modes from the ++ disk as well */ ++ if (dma_enabled & (1 << (5 + i))) { ++ dev->xfer_mode = XFER_MW_DMA_0; ++ dev->xfer_shift = ATA_SHIFT_MWDMA; ++ dev->flags &= ~ATA_DFLAG_PIO; ++ } else { ++ dev->xfer_mode = XFER_PIO_0; ++ dev->xfer_shift = ATA_SHIFT_PIO; ++ dev->flags |= ATA_DFLAG_PIO; ++ } ++ } ++ } ++} ++ ++static struct scsi_host_template genpata_sht = { ++ .module = THIS_MODULE, ++ .name = DRV_NAME, ++ .ioctl = ata_scsi_ioctl, ++ .queuecommand = ata_scsi_queuecmd, ++ .eh_strategy_handler = ata_scsi_error, ++ .can_queue = ATA_DEF_QUEUE, ++ .this_id = ATA_SHT_THIS_ID, ++ .sg_tablesize = LIBATA_MAX_PRD, ++ .max_sectors = ATA_MAX_SECTORS, ++ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, ++ .emulated = ATA_SHT_EMULATED, ++ .use_clustering = ATA_SHT_USE_CLUSTERING, ++ .proc_name = DRV_NAME, ++ .dma_boundary = ATA_DMA_BOUNDARY, ++ .slave_configure = ata_scsi_slave_config, ++ .bios_param = ata_std_bios_param, ++// .ordered_flush = 1, ++}; ++ ++static struct ata_port_operations genpata_port_ops = { ++ .set_mode = genpata_set_mode, ++ ++ .port_disable = ata_port_disable, ++ .tf_load = ata_tf_load, ++ .tf_read = ata_tf_read, ++ .check_status = ata_check_status, ++ .exec_command = ata_exec_command, ++ .dev_select = ata_std_dev_select, ++ ++ .phy_reset = genpata_phy_reset, ++ ++ .bmdma_setup = ata_bmdma_setup, ++ .bmdma_start = ata_bmdma_start, ++ .bmdma_stop = ata_bmdma_stop, ++ .bmdma_status = ata_bmdma_status, ++ ++ .data_xfer = ata_pio_data_xfer, ++ ++ .qc_prep = ata_qc_prep, ++ .qc_issue = ata_qc_issue_prot, ++ .eng_timeout = ata_eng_timeout, ++ .irq_handler = ata_interrupt, ++ .irq_clear = ata_bmdma_irq_clear, ++ ++ .port_start = ata_port_start, ++ .port_stop = ata_port_stop, ++ .host_stop = ata_host_stop ++}; ++ ++static int ide_generic_all; /* Set to claim all devices */ ++ ++static int __init ide_generic_all_on(char *unused) ++{ ++ ide_generic_all = 1; ++ printk(KERN_INFO "ATA generic will claim all unknown PCI IDE class storage controllers.\n"); ++ return 1; ++} ++ ++__setup("all-generic-ide", ide_generic_all_on); ++ ++/** ++ * pata_generic_init - attach generic IDE ++ * @dev: PCI device found ++ * @id: match entry ++ * ++ * Called each time a matching IDE interface is found. We check if the ++ * interface is one we wish to claim and if so we perform any chip ++ * specific hacks then let the ATA layer do the heavy lifting. ++ */ ++ ++static int pata_generic_init_one(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ u16 command; ++ static struct ata_port_info info = { ++ .sht = &genpata_sht, ++ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_IRQ_MASK, ++ .pio_mask = 0x1f, ++ .mwdma_mask = 0x07, ++ .udma_mask = 0x3f, ++ .port_ops = &genpata_port_ops ++ }; ++ static struct ata_port_info *port_info[2] = { &info, &info }; ++ ++ /* Don't use the generic entry unless instructed to do so */ ++ if (id->driver_data == 1 && ide_generic_all == 0) ++ return -ENODEV; ++ ++ /* Devices that need care */ ++ if (dev->vendor == PCI_VENDOR_ID_UMC && ++ dev->device == PCI_DEVICE_ID_UMC_UM8886A && ++ (!(PCI_FUNC(dev->devfn) & 1))) ++ return -ENODEV; ++ ++ if (dev->vendor == PCI_VENDOR_ID_OPTI && ++ dev->device == PCI_DEVICE_ID_OPTI_82C558 && ++ (!(PCI_FUNC(dev->devfn) & 1))) ++ return -ENODEV; ++ ++ /* Don't re-enable devices in generic mode or we will break some ++ motherboards with disabled and unused IDE controllers */ ++ pci_read_config_word(dev, PCI_COMMAND, &command); ++ if (!(command & PCI_COMMAND_IO)) ++ return -ENODEV; ++ ++ if (dev->vendor == PCI_VENDOR_ID_AL) ++ ata_pci_clear_simplex(dev); ++ ++ return ata_pci_init_one(dev, port_info, 2); ++} ++ ++static struct pci_device_id pata_generic[] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2), }, ++ /* Must come last. If you add entries adjust this table appropriately */ ++ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1}, ++ { 0, }, ++}; ++ ++static struct pci_driver pata_generic_pci_driver = { ++ .name = DRV_NAME, ++ .id_table = pata_generic, ++ .probe = pata_generic_init_one, ++ .remove = ata_pci_remove_one ++}; ++ ++static int __init pata_generic_init(void) ++{ ++ return pci_module_init(&pata_generic_pci_driver); ++} ++ ++ ++static void __exit pata_generic_exit(void) ++{ ++ pci_unregister_driver(&pata_generic_pci_driver); ++} ++ ++ ++MODULE_AUTHOR("Alan Cox"); ++MODULE_DESCRIPTION("low-level driver for generic ATA"); ++MODULE_LICENSE("GPL"); ++MODULE_DEVICE_TABLE(pci, pata_generic); ++MODULE_VERSION(DRV_VERSION); ++ ++module_init(pata_generic_init); ++module_exit(pata_generic_exit); +diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc6/drivers/scsi/ata_piix.c linux-2.6.16-rc6/drivers/scsi/ata_piix.c +--- linux.vanilla-2.6.16-rc6/drivers/scsi/ata_piix.c 2006-03-13 14:00:14.000000000 +0000 ++++ linux-2.6.16-rc6/drivers/scsi/ata_piix.c 2006-02-20 20:06:17.000000000 +0000 +@@ -91,9 +91,10 @@ + #include + #include + #include ++#include + + #define DRV_NAME "ata_piix" +-#define DRV_VERSION "1.05" ++#define DRV_VERSION "1.05-ac7" + + enum { + PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ +@@ -122,6 +123,17 @@ + piix4_pata = 2, + ich6_sata = 3, + ich6_sata_ahci = 4, ++ ich0_pata = 5, ++ ich2_pata = 6, ++ ich3_pata = 7, ++ ich4_pata = 8, ++ cich_pata = 9, ++ piix3_pata = 10, ++ esb_pata = 11, ++ ich_pata = 12, ++ ich6_pata = 13, ++ ich7_pata = 14, ++ esb2_pata = 15, + + PIIX_AHCI_DEVICE = 6, + }; +@@ -130,20 +142,69 @@ + const struct pci_device_id *ent); + + static void piix_pata_phy_reset(struct ata_port *ap); ++static void ich_pata_phy_reset(struct ata_port *ap); + static void piix_sata_phy_reset(struct ata_port *ap); + static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev); + static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); ++static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev); + + static unsigned int in_module_init = 1; + + static const struct pci_device_id piix_pci_tbl[] = { + #ifdef ATA_ENABLE_PATA ++#if 0 ++ /* Neptune and earlier are simple PIO */ ++ /* 430HX and friends. MWDMA */ ++ { 0x8086, 0x122e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix3_pata }, ++ { 0x8086, 0x1230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix3_pata }, ++ /* Intel PIIX3 */ ++ { 0x8086, 0x7010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix3_pata }, ++#endif ++ /* Intel PIIX4 for the 430TX/440BX/MX chipset: UDMA 33 */ ++ /* Also PIIX4E (fn3 rev 2) and PIIX4M (fn3 rev 3) */ + { 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, + { 0x8086, 0x24db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, + { 0x8086, 0x25a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, ++ /* Intel PIIX4 */ ++ { 0x8086, 0x7199, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, ++ /* Intel PIIX4 */ ++ { 0x8086, 0x7601, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, ++ /* Intel PIIX */ ++ { 0x8086, 0x84CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, ++ /* Intel ICH (i810, i815, i840) UDMA 66*/ ++ { 0x8086, 0x2411, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata }, ++ /* Intel ICH0 : UDMA 33*/ ++ { 0x8086, 0x2421, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich0_pata }, ++ /* Intel ICH2M */ ++ { 0x8086, 0x244A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich2_pata }, ++ /* Intel ICH2 (i810E2, i845, 850, 860) UDMA 100 */ ++ { 0x8086, 0x244B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich2_pata }, ++ /* Intel ICH3M */ ++ { 0x8086, 0x248A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich3_pata }, ++ /* Intel ICH3 (E7500/1) UDMA 100 */ ++ { 0x8086, 0x248B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich3_pata }, ++#if 0 ++ { 0x8086, 0x24C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, dunno_pata }, ++#endif ++ /* Intel ICH4 (i845GV, i845E, i852, i855) UDMA 100 */ ++ { 0x8086, 0x24CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich4_pata }, ++ { 0x8086, 0x24CB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich4_pata }, ++ /* Intel ICH5 */ ++ { 0x8086, 0x24DB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, ++ /* C-ICH (i810E2) */ ++ { 0x8086, 0x245B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, cich_pata }, ++ /* ESB (855GME/875P + 6300ESB) UDMA 100 */ ++ { 0x8086, 0x25A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_pata }, ++ /* ICH6 (and 6) (i915) UDMA 100 */ ++ { 0x8086, 0x266F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_pata }, ++ /* ICH7/7-R (i945, i975) UDMA 100*/ ++ { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_pata }, ++ { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb2_pata }, + #endif +- +- /* NOTE: The following PCI ids must be kept in sync with the ++ /* ++ * SATA ports ++ * ++ * NOTE: The following PCI ids must be kept in sync with the + * list in drivers/pci/quirks.c. + */ + +@@ -213,6 +274,40 @@ + .bmdma_status = ata_bmdma_status, + .qc_prep = ata_qc_prep, + .qc_issue = ata_qc_issue_prot, ++ ++ .data_xfer = ata_pio_data_xfer, ++ ++ .eng_timeout = ata_eng_timeout, ++ ++ .irq_handler = ata_interrupt, ++ .irq_clear = ata_bmdma_irq_clear, ++ ++ .port_start = ata_port_start, ++ .port_stop = ata_port_stop, ++ .host_stop = ata_host_stop, ++}; ++ ++static const struct ata_port_operations ich_pata_ops = { ++ .port_disable = ata_port_disable, ++ .set_piomode = piix_set_piomode, ++ .set_dmamode = ich_set_dmamode, ++ ++ .tf_load = ata_tf_load, ++ .tf_read = ata_tf_read, ++ .check_status = ata_check_status, ++ .exec_command = ata_exec_command, ++ .dev_select = ata_std_dev_select, ++ ++ .phy_reset = ich_pata_phy_reset, ++ ++ .bmdma_setup = ata_bmdma_setup, ++ .bmdma_start = ata_bmdma_start, ++ .bmdma_stop = ata_bmdma_stop, ++ .bmdma_status = ata_bmdma_status, ++ .qc_prep = ata_qc_prep, ++ .qc_issue = ata_qc_issue_prot, ++ ++ .data_xfer = ata_pio_data_xfer, + + .eng_timeout = ata_eng_timeout, + +@@ -242,6 +337,8 @@ + .qc_prep = ata_qc_prep, + .qc_issue = ata_qc_issue_prot, + ++ .data_xfer = ata_pio_data_xfer, ++ + .eng_timeout = ata_eng_timeout, + + .irq_handler = ata_interrupt, +@@ -253,47 +350,39 @@ + }; + + static struct ata_port_info piix_port_info[] = { +- /* ich5_pata */ ++ /* ich5_pata: 0*/ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | + PIIX_FLAG_CHECKINTR, + .pio_mask = 0x1f, /* pio0-4 */ +-#if 0 + .mwdma_mask = 0x06, /* mwdma1-2 */ +-#else +- .mwdma_mask = 0x00, /* mwdma broken */ +-#endif +- .udma_mask = 0x3f, /* udma0-5 */ +- .port_ops = &piix_pata_ops, ++ .udma_mask = ATA_UDMA6, ++ .port_ops = &ich_pata_ops, + }, + +- /* ich5_sata */ ++ /* ich5_sata: 1 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | + PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ +- .udma_mask = 0x7f, /* udma0-6 */ ++ .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + +- /* piix4_pata */ ++ /* piix4_pata: 2 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .pio_mask = 0x1f, /* pio0-4 */ +-#if 0 + .mwdma_mask = 0x06, /* mwdma1-2 */ +-#else +- .mwdma_mask = 0x00, /* mwdma broken */ +-#endif + .udma_mask = ATA_UDMA_MASK_40C, + .port_ops = &piix_pata_ops, + }, + +- /* ich6_sata */ ++ /* ich6_sata: 3 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | +@@ -301,11 +390,11 @@ + ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ +- .udma_mask = 0x7f, /* udma0-6 */ ++ .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, + +- /* ich6_sata_ahci */ ++ /* ich6_sata_ahci: 4 */ + { + .sht = &piix_sht, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | +@@ -313,9 +402,119 @@ + ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ +- .udma_mask = 0x7f, /* udma0-6 */ ++ .udma_mask = ATA_UDMA6, + .port_ops = &piix_sata_ops, + }, ++ ++ /* ich0_pata: 5 */ ++ { ++ .sht = &piix_sht, ++ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, ++ .pio_mask = 0x1f, /* pio 0-4 */ ++ .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ ++ .udma_mask = ATA_UDMA4, ++ .port_ops = &ich_pata_ops, ++ }, ++ ++ /* ich2_pata: 6 */ ++ { ++ .sht = &piix_sht, ++ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, ++ .pio_mask = 0x1f, /* pio 0-4 */ ++ .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ ++ .udma_mask = ATA_UDMA5, ++ .port_ops = &ich_pata_ops, ++ }, ++ ++ /* ich3_pata: 7 */ ++ { ++ .sht = &piix_sht, ++ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, ++ .pio_mask = 0x1f, /* pio 0-4 */ ++ .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ ++ .udma_mask = ATA_UDMA5, ++ .port_ops = &ich_pata_ops, ++ }, ++ ++ /* ich4_pata: 8 */ ++ { ++ .sht = &piix_sht, ++ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, ++ .pio_mask = 0x1f, /* pio 0-4 */ ++ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ ++ .udma_mask = ATA_UDMA5, ++ .port_ops = &ich_pata_ops, ++ }, ++ ++ /* cich_pata: 9 */ ++ { ++ .sht = &piix_sht, ++ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, ++ .pio_mask = 0x1f, /* pio 0-4 */ ++ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ ++ .udma_mask = ATA_UDMA5, ++ .port_ops = &ich_pata_ops, ++ }, ++ ++ /* piix3_pata: 10 */ ++ { ++ .sht = &piix_sht, ++ .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, ++ .pio_mask = 0x1f, /* pio0-4 */ ++ .mwdma_mask = 0x07, /* mwdma1-2 */ ++ .udma_mask = ATA_UDMA_MASK_40C, ++ .port_ops = &piix_pata_ops, ++ }, ++ ++ /* esb_pata: 11 */ ++ { ++ .sht = &piix_sht, ++ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, ++ .pio_mask = 0x1f, /* pio 0-4 */ ++ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ ++ .udma_mask = ATA_UDMA5, ++ .port_ops = &piix_pata_ops, ++ }, ++ ++ /* ich_pata: 12 */ ++ { ++ .sht = &piix_sht, ++ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, ++ .pio_mask = 0x1f, /* pio 0-4 */ ++ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ ++ .udma_mask = ATA_UDMA4, /* UDMA66 */ ++ .port_ops = &ich_pata_ops, ++ }, ++ ++ /* ich6_pata: 13 */ ++ { ++ .sht = &piix_sht, ++ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, ++ .pio_mask = 0x1f, /* pio 0-4 */ ++ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ ++ .udma_mask = ATA_UDMA6, /* UDMA133 */ ++ .port_ops = &ich_pata_ops, ++ }, ++ ++ /* ich7_pata: 14 */ ++ { ++ .sht = &piix_sht, ++ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, ++ .pio_mask = 0x1f, /* pio 0-4 */ ++ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ ++ .udma_mask = ATA_UDMA6, ++ .port_ops = &ich_pata_ops, ++ }, ++ ++ /* esb2_pata: 15 */ ++ { ++ .sht = &piix_sht, ++ .host_flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, ++ .pio_mask = 0x1f, /* pio 0-4 */ ++ .mwdma_mask = 0x06, /* Check: maybe 0x07 */ ++ .udma_mask = ATA_UDMA5, ++ .port_ops = &ich_pata_ops, ++ }, + }; + + static struct pci_bits piix_enable_bits[] = { +@@ -339,7 +538,7 @@ + * LOCKING: + * None (inherited from caller). + */ +-static void piix_pata_cbl_detect(struct ata_port *ap) ++static void ich_pata_cbl_detect(struct ata_port *ap) + { + struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); + u8 tmp, mask; +@@ -366,8 +565,9 @@ + * piix_pata_phy_reset - Probe specified port on PATA host controller + * @ap: Port to probe + * +- * Probe PATA phy. +- * ++ * Probe PATA phy. Unlike the ICH we have no IOCFG register and ++ * don't do UDMA66+ anyway. ++ + * LOCKING: + * None (inherited from caller). + */ +@@ -381,11 +581,34 @@ + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return; + } ++ ap->cbl = ATA_CBL_PATA40; ++ ata_port_probe(ap); ++ ata_bus_reset(ap); ++} + +- piix_pata_cbl_detect(ap); + +- ata_port_probe(ap); ++/** ++ * ich_pata_phy_reset - Probe specified port on PATA host controller ++ * @ap: Port to probe ++ * ++ * Probe PATA phy. ++ * ++ * LOCKING: ++ * None (inherited from caller). ++ */ ++ ++static void ich_pata_phy_reset(struct ata_port *ap) ++{ ++ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); + ++ if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) { ++ ata_port_disable(ap); ++ printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); ++ return; ++ } ++ ++ ich_pata_cbl_detect(ap); ++ ata_port_probe(ap); + ata_bus_reset(ap); + } + +@@ -481,6 +704,13 @@ + unsigned int slave_port = 0x44; + u16 master_data; + u8 slave_data; ++ u8 udma_enable; ++ int control = 0; ++ ++ /* ++ * See Intel Document 298600-004 for the timing programing rules ++ * for ICH controllers. ++ */ + + static const /* ISP RTC */ + u8 timings[][2] = { { 0, 0 }, +@@ -489,20 +719,30 @@ + { 2, 1 }, + { 2, 3 }, }; + ++ if (pio > 2) ++ control |= 1; /* TIME1 enable */ ++ if (ata_pio_need_iordy(adev)) ++ control |= 2; /* IE enable */ ++ ++ /* Intel specifies that the PPE functionality is for disk only */ ++ if (adev->class == ATA_DEV_ATA) ++ control |= 4; /* PPE enable */ ++ + pci_read_config_word(dev, master_port, &master_data); + if (is_slave) { ++ /* Enable SITRE (seperate slave timing register) */ + master_data |= 0x4000; +- /* enable PPE, IE and TIME */ +- master_data |= 0x0070; ++ /* enable PPE1, IE1 and TIME1 as needed */ ++ master_data |= (control << 4); + pci_read_config_byte(dev, slave_port, &slave_data); + slave_data &= (ap->hard_port_no ? 0x0f : 0xf0); +- slave_data |= +- (timings[pio][0] << 2) | +- (timings[pio][1] << (ap->hard_port_no ? 4 : 0)); ++ /* Load the timing nibble for this slave */ ++ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->hard_port_no ? 4 : 0); + } else { ++ /* Master keeps the bits in a different format */ + master_data &= 0xccf8; +- /* enable PPE, IE and TIME */ +- master_data |= 0x0007; ++ /* Enable PPE, IE and TIME as appropriate */ ++ master_data |= control; + master_data |= + (timings[pio][0] << 12) | + (timings[pio][1] << 8); +@@ -510,84 +750,165 @@ + pci_write_config_word(dev, master_port, master_data); + if (is_slave) + pci_write_config_byte(dev, slave_port, slave_data); ++ ++ /* Ensure the UDMA bit is off - it will be turned back on if ++ UDMA is selected */ ++ ++ if (ap->udma_mask) { ++ pci_read_config_byte(dev, 0x48, &udma_enable); ++ udma_enable &= ~(1 << (2 * ap->hard_port_no + adev->devno)); ++ pci_write_config_byte(dev, 0x48, udma_enable); ++ } + } + + /** +- * piix_set_dmamode - Initialize host controller PATA PIO timings ++ * do_piix_set_dmamode - Initialize host controller PATA PIO timings + * @ap: Port whose timings we are configuring +- * @adev: um +- * @udma: udma mode, 0 - 6 ++ * @adev: device to configure ++ * @isich: True if the device is an ICH and has IOCFG registers + * +- * Set UDMA mode for device, in host controller PCI config space. ++ * Set MW/UDMA mode for device, in host controller PCI config space. ++ * Note: We know the caller has already set the PIO mode. In doing ++ * so it has correctly set PPE, SITRE, IORDY and TIME1. We rely on that. + * + * LOCKING: + * None (inherited from caller). + */ + +-static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev) ++static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, int isich) + { +- unsigned int udma = adev->dma_mode; /* FIXME: MWDMA too */ + struct pci_dev *dev = to_pci_dev(ap->host_set->dev); +- u8 maslave = ap->hard_port_no ? 0x42 : 0x40; +- u8 speed = udma; +- unsigned int drive_dn = (ap->hard_port_no ? 2 : 0) + adev->devno; +- int a_speed = 3 << (drive_dn * 4); +- int u_flag = 1 << drive_dn; +- int v_flag = 0x01 << drive_dn; +- int w_flag = 0x10 << drive_dn; +- int u_speed = 0; +- int sitre; +- u16 reg4042, reg4a; +- u8 reg48, reg54, reg55; +- +- pci_read_config_word(dev, maslave, ®4042); +- DPRINTK("reg4042 = 0x%04x\n", reg4042); +- sitre = (reg4042 & 0x4000) ? 1 : 0; +- pci_read_config_byte(dev, 0x48, ®48); +- pci_read_config_word(dev, 0x4a, ®4a); +- pci_read_config_byte(dev, 0x54, ®54); +- pci_read_config_byte(dev, 0x55, ®55); +- +- switch(speed) { +- case XFER_UDMA_4: +- case XFER_UDMA_2: u_speed = 2 << (drive_dn * 4); break; +- case XFER_UDMA_6: +- case XFER_UDMA_5: +- case XFER_UDMA_3: +- case XFER_UDMA_1: u_speed = 1 << (drive_dn * 4); break; +- case XFER_UDMA_0: u_speed = 0 << (drive_dn * 4); break; +- case XFER_MW_DMA_2: +- case XFER_MW_DMA_1: break; +- default: +- BUG(); +- return; +- } ++ u8 master_port = ap->hard_port_no ? 0x42 : 0x40; ++ u16 master_data; ++ u8 speed = adev->dma_mode; ++ int devid = adev->devno + 2 * ap->hard_port_no; ++ u8 udma_enable; ++ ++ static const /* ISP RTC */ ++ u8 timings[][2] = { { 0, 0 }, ++ { 0, 0 }, ++ { 1, 0 }, ++ { 2, 1 }, ++ { 2, 3 }, }; + ++ pci_read_config_word(dev, master_port, &master_data); ++ pci_read_config_byte(dev, 0x48, &udma_enable); ++ + if (speed >= XFER_UDMA_0) { +- if (!(reg48 & u_flag)) +- pci_write_config_byte(dev, 0x48, reg48 | u_flag); +- if (speed == XFER_UDMA_5) { +- pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag); +- } else { +- pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); ++ unsigned int udma = adev->dma_mode - XFER_UDMA_0; ++ u16 udma_timing; ++ u16 ideconf; ++ int u_clock, u_speed; ++ ++ /* ++ * UDMA is handled by a combination of clock switching and ++ * selection of dividers ++ * ++ * Handy rule: Odd modes are UDMATIMx 01, even are 02 ++ * except UDMA0 which is 00 ++ */ ++ u_speed = min(2 - (udma & 1), udma); ++ if (udma == 5) ++ u_clock = 0x1000; /* 100Mhz */ ++ else if (udma > 2) ++ u_clock = 1; /* 66Mhz */ ++ else ++ u_clock = 0; /* 33Mhz */ ++ ++ udma_enable |= (1 << devid); ++ ++ /* Load the CT/RP selection */ ++ pci_read_config_word(dev, 0x4A, &udma_timing); ++ udma_timing &= ~(3 << (4 * devid)); ++ udma_timing |= u_speed << (4 * devid); ++ pci_write_config_word(dev, 0x4A, udma_timing); ++ ++ if (isich) { ++ /* Select a 33/66/100Mhz clock */ ++ pci_read_config_word(dev, 0x54, &ideconf); ++ ideconf &= ~(0x1001 << devid); ++ ideconf |= u_clock << devid; ++ /* For ICH or later we should set bit 10 for better ++ performance (WR_PingPong_En) */ ++ pci_write_config_word(dev, 0x54, ideconf); + } +- if ((reg4a & a_speed) != u_speed) +- pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed); +- if (speed > XFER_UDMA_2) { +- if (!(reg54 & v_flag)) +- pci_write_config_byte(dev, 0x54, reg54 | v_flag); +- } else +- pci_write_config_byte(dev, 0x54, reg54 & ~v_flag); + } else { +- if (reg48 & u_flag) +- pci_write_config_byte(dev, 0x48, reg48 & ~u_flag); +- if (reg4a & a_speed) +- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); +- if (reg54 & v_flag) +- pci_write_config_byte(dev, 0x54, reg54 & ~v_flag); +- if (reg55 & w_flag) +- pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); ++ /* ++ * MWDMA is driven by the PIO timings. We must also enable ++ * IORDY unconditionally along with TIME1. PPE has already ++ * been set when the PIO timing was set. ++ */ ++ unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0; ++ unsigned int control; ++ u8 slave_data; ++ const unsigned int needed_pio[3] = { ++ XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 ++ }; ++ int pio = needed_pio[mwdma] - XFER_PIO_0; ++ ++ control = 3; /* IORDY|TIME1 */ ++ ++ /* If the drive MWDMA is faster than it can do PIO then ++ we must force PIO into PIO0 */ ++ ++ if (adev->pio_mode < needed_pio[mwdma]) ++ /* Enable DMA timing only */ ++ control |= 8; /* PIO cycles in PIO0 */ ++ ++ if (adev->devno) { /* Slave */ ++ master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */ ++ master_data |= control << 4; ++ pci_read_config_byte(dev, 0x44, &slave_data); ++ slave_data &= (0x0F + 0xE1 * ap->hard_port_no); ++ /* Load the matching timing */ ++ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->hard_port_no ? 4 : 0); ++ pci_write_config_byte(dev, 0x44, slave_data); ++ } else { /* Master */ ++ master_data &= 0xCCF4; /* Mask out IORDY|TIME1|DMAONLY ++ and master timing bits */ ++ master_data |= control; ++ master_data |= ++ (timings[pio][0] << 12) | ++ (timings[pio][1] << 8); ++ } ++ udma_enable &= ~(1 << devid); ++ pci_write_config_word(dev, master_port, master_data); + } ++ /* Don't scribble on 0x48 if the controller does not support UDMA */ ++ if (ap->udma_mask) ++ pci_write_config_byte(dev, 0x48, udma_enable); ++} ++ ++/** ++ * piix_set_dmamode - Initialize host controller PATA DMA timings ++ * @ap: Port whose timings we are configuring ++ * @adev: um ++ * ++ * Set MW/UDMA mode for device, in host controller PCI config space. ++ * ++ * LOCKING: ++ * None (inherited from caller). ++ */ ++ ++static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev) ++{ ++ do_pata_set_dmamode(ap, adev, 0); ++} ++ ++/** ++ * ich_set_dmamode - Initialize host controller PATA DMA timings ++ * @ap: Port whose timings we are configuring ++ * @adev: um ++ * ++ * Set MW/UDMA mode for device, in host controller PCI config space. ++ * ++ * LOCKING: ++ * None (inherited from caller). ++ */ ++ ++static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev) ++{ ++ do_pata_set_dmamode(ap, adev, 1); + } + + #define AHCI_PCI_BAR 5 +@@ -646,15 +967,15 @@ + pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); + pci_read_config_word(pdev, 0x41, &cfg); + /* Only on the original revision: IDE DMA can hang */ +- if(rev == 0x00) ++ if (rev == 0x00) + no_piix_dma = 1; + /* On all revisions below 5 PXB bus lock must be disabled for IDE */ +- else if(cfg & (1<<14) && rev < 5) ++ else if (cfg & (1<<14) && rev < 5) + no_piix_dma = 2; + } +- if(no_piix_dma) ++ if (no_piix_dma) + dev_printk(KERN_WARNING, &ata_dev->dev, "450NX errata present, disabling IDE DMA.\n"); +- if(no_piix_dma == 2) ++ if (no_piix_dma == 2) + dev_printk(KERN_WARNING, &ata_dev->dev, "A BIOS update may resolve this.\n"); + return no_piix_dma; + } +diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc6/drivers/scsi/Kconfig linux-2.6.16-rc6/drivers/scsi/Kconfig +--- linux.vanilla-2.6.16-rc6/drivers/scsi/Kconfig 2006-03-13 14:00:13.000000000 +0000 ++++ linux-2.6.16-rc6/drivers/scsi/Kconfig 2006-02-20 17:27:24.000000000 +0000 +@@ -599,6 +599,316 @@ + depends on IDE=y && !BLK_DEV_IDE_SATA && (SCSI_SATA_AHCI || SCSI_ATA_PIIX) + default y + ++config SCSI_PATA_ALI ++ tristate "ALi PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for the ALi ATA interfaces ++ found on the many ALi chipsets. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_AMD ++ tristate "AMD/NVidia PATA support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for the AMD and NVidia PATA ++ interfaces found on the chipsets for Athlon/Athlon64. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_ARTOP ++ tristate "ARTOP 6210/6260 PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for ARTOP PATA controllers. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_ATIIXP ++ tristate "ATI PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for the ATI ATA interfaces ++ found on the many ATI chipsets. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_CMD64X ++ tristate "CMD64x PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for the CMD64x series chips ++ except for the CMD640. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_CS5520 ++ tristate "CS5510/5520 PATA support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for the Cyrix 5510/5520 ++ companion chip used with the MediaGX/Geode processor family. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_CS5530 ++ tristate "CS5530 PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for the Cyrix/NatSemi/AMD CS5530 ++ companion chip used with the MediaGX/Geode processor family. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_CS5535 ++ tristate "CS5535 PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && X86 && !X86_64 && EXPERIMENTAL ++ help ++ This option enables support for the NatSemi/AMD CS5535 ++ companion chip used with the Geode processor family. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_CYPRESS ++ tristate "Cypress CY82C693 PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for the Cypress/Contaq CY82C693 ++ chipset found in some Alpha systems ++ ++ If unsure, say N. ++ ++config SCSI_PATA_EFAR ++ tristate "EFAR SLC90E66 support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for the EFAR SLC90E66 ++ IDE controller found on some older machines. ++ ++ If unsure, say N. ++ ++config SCSI_ATA_GENERIC ++ tristate "Generic PATA support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for generic BIOS configured ++ PATA controllers via the new ATA layer ++ ++ If unsure, say N. ++ ++config SCSI_PATA_HPT37X ++ tristate "HPT 370/370A/371/372/374/302 PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for the majority of the later HPT ++ PATA controllers via the new ATA layer. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_HPT3X2N ++ tristate "HPT 372N/302N PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for the N variant HPT PATA ++ controllers via the new ATA layer ++ ++ If unsure, say N. ++ ++config SCSI_PATA_HPT3X3 ++ tristate "HPT 343/363 PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for the HPT 343/363 ++ PATA controllers via the new ATA layer ++ ++ If unsure, say N. ++ ++config SCSI_PATA_ISAPNP ++ tristate "ISA Plug and Play PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && EXPERIMENTAL ++ help ++ This option enables support for ISA plug & play ATA ++ controllers such as those found on old soundcards. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_IT8172 ++ tristate "IT8172 PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for the ITE 8172 PATA controller ++ via the new ATA layer. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_IT821X ++ tristate "IT821x PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for the ITE 8211 and 8212 ++ PATA controllers via the new ATA layer, including RAID ++ mode. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_LEGACY ++ tristate "Legacy ISA PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for ISA bus legacy PATA ++ interfaces on ide2-5 and allows them to be accessed via ++ the new ATA layer. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_MPIIX ++ tristate "Intel PATA MPIIX support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for MPIIX PATA support. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_NETCELL ++ tristate "NETCELL Revolution RAID support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for the Netcell Revolution RAID ++ PATA controller. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_NS87410 ++ tristate "Nat Semi NS87410 PATA support (Experimental)" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for the National Semiconductor ++ NS87410 PCI-IDE controller. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_OLDPIIX ++ tristate "Intel PATA old PIIX support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for early PIIX PATA interfaces. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_OPTI ++ tristate "OPTI621/6215 PATA support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables full PIO support for the early Opti ATA ++ controllers found on some old motherboards. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_PCMCIA ++ tristate "PCMCIA PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCMCIA ++ help ++ This option enables support for PCMCIA ATA interfaces, including ++ compact flash card adapters via the new ATA layer. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_PDC_OLD ++ tristate "Older Promise PATA controller support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for the Promise 20246, 20262, 20263, ++ 20265 and 20267 adapters. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_QDI ++ tristate "QDI VLB PATA support" ++ depends on SCSI_SATA ++ help ++ Support for QDI 6500 and 6580 PATA controllers on VESA local bus. ++ ++config SCSI_PATA_RADISYS ++ tristate "RADISYS 82600 PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for the RADISYS 82600 ++ PATA controllers via the new ATA layer ++ ++ If unsure, say N. ++ ++config SCSI_PATA_RZ1000 ++ tristate "PC Tech RZ1000 PATA support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables basic support for the PC Tech RZ1000/1 ++ PATA controllers via the new ATA layer ++ ++ If unsure, say N. ++ ++config SCSI_PATA_SC1200 ++ tristate "SC1200 PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for the NatSemi/AMD SC1200 SoC ++ companion chip used with the Geode processor family. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_SERVERWORKS ++ tristate "SERVERWORKS OSB4/CSB5/CSB6 PATA support (Experimental)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for the Serverworks OSB4/CSB5 and ++ CSB6 IDE controllers, via the new ATA layer. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_SIL680 ++ tristate "CMD / Silicon Image 680 PATA support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for CMD / Silicon Image 680 PATA. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_SIS ++ tristate "SiS PATA support (Experimental)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ This option enables support for SiS PATA controllers ++ ++ If unsure, say N. ++ ++config SCSI_PATA_TRIFLEX ++ tristate "Compaq Triflex PATA support (Raving Lunatic)" ++ depends on SCSI_SATA && PCI && EXPERIMENTAL ++ help ++ Enable support for the Compaq 'Triflex' IDE controller as found ++ on many Compaq Pentium-Pro systems, via the new ATA layer. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_VIA ++ tristate "VIA PATA support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for the VIA PATA interfaces ++ found on the many VIA chipsets. ++ ++ If unsure, say N. ++ ++config SCSI_PATA_WINBOND ++ tristate "Winbond SL82C105 PATA support" ++ depends on SCSI_SATA && PCI ++ help ++ This option enables support for SL82C105 PATA devices found in the ++ Netwinder and some other systems ++ ++ If unsure, say N. ++ ++ + config SCSI_BUSLOGIC + tristate "BusLogic SCSI support" + depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API +diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.16-rc6/drivers/scsi/libata-core.c linux-2.6.16-rc6/drivers/scsi/libata-core.c +--- linux.vanilla-2.6.16-rc6/drivers/scsi/libata-core.c 2006-03-13 14:00:14.000000000 +0000 ++++ linux-2.6.16-rc6/drivers/scsi/libata-core.c 2006-03-13 14:30:45.838552760 +0000 +@@ -68,9 +68,10 @@ + static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); + static void ata_set_mode(struct ata_port *ap); + static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); +-static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift); ++static unsigned int ata_get_mode_mask(const struct ata_port *ap, struct ata_device *adev, int shift); + static int fgb(u32 bitmap); + static int ata_choose_xfer_mode(const struct ata_port *ap, ++ struct ata_device *adev, + u8 *xfer_mode_out, + unsigned int *xfer_shift_out); + static void __ata_qc_complete(struct ata_queued_cmd *qc); +@@ -78,7 +79,7 @@ + static unsigned int ata_unique_id = 1; + static struct workqueue_struct *ata_wq; + +-int atapi_enabled = 0; ++int