[PATCH 1/15] ACPI support for IDE devices

2007-01-18 Thread Bartlomiej Zolnierkiewicz
[PATCH] ACPI support for IDE devices

This patch implements ACPI integration for generic IDE devices.
The ACPI spec mandates that some methods are called during suspend and
resume. And consequently there most modern Laptops cannot resume
properly without it.

According to the spec, we should call '_GTM' (Get Timing) upon suspend
to store the current IDE adapter settings.
Upon resume we should call '_STM' (Set Timing) to initialize the
adapter with the stored settings; afterwards '_GTF' (Get Taskfile)
should be called which returns a buffer with some IDE initialisation
commands. Those commands should be passed to the drive.

There are two module params which control the behaviour of this patch:

'ide=noacpi'
Do not call any ACPI methods (Disables any ACPI method calls)
'ide=acpigtf'
Enable execution of _GTF methods upon resume.
Has no effect if 'ide=noacpi' is set.
'ide=acpionboot'
Enable execution of ACPI methods during boot.
This might be required on some machines if 'ide=acpigtf' is
selected as some machines modify the _GTF information
depending on the drive identification passed down with _STM.

Signed-off-by: Hannes Reinecke <[EMAIL PROTECTED]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>

---
 drivers/ide/Kconfig |7 
 drivers/ide/Makefile|1 
 drivers/ide/ide-acpi.c  |  696 
 drivers/ide/ide-probe.c |3 
 drivers/ide/ide.c   |   36 ++
 include/linux/ide.h |   27 +
 6 files changed, 770 insertions(+)

Index: b/drivers/ide/Kconfig
===
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -271,6 +271,13 @@ config BLK_DEV_IDESCSI
  If both this SCSI emulation and native ATAPI support are compiled
  into the kernel, the native support will be used.
 
+config BLK_DEV_IDEACPI
+   bool "IDE ACPI support"
+   depends on ACPI
+   ---help---
+ Implement ACPI support for generic IDE devices. On modern
+ machines ACPI support is required to properly handle ACPI S3 states.
+
 config IDE_TASK_IOCTL
bool "IDE Taskfile Access"
help
Index: b/drivers/ide/Makefile
===
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -22,6 +22,7 @@ ide-core-$(CONFIG_BLK_DEV_IDEPCI) += set
 ide-core-$(CONFIG_BLK_DEV_IDEDMA)  += ide-dma.o
 ide-core-$(CONFIG_PROC_FS) += ide-proc.o
 ide-core-$(CONFIG_BLK_DEV_IDEPNP)  += ide-pnp.o
+ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o
 
 # built-in only drivers from arm/
 ide-core-$(CONFIG_IDE_ARM) += arm/ide_arm.o
Index: b/drivers/ide/ide-acpi.c
===
--- /dev/null
+++ b/drivers/ide/ide-acpi.c
@@ -0,0 +1,696 @@
+/*
+ * ide-acpi.c
+ * Provides ACPI support for IDE drives.
+ *
+ * Copyright (C) 2005 Intel Corp.
+ * Copyright (C) 2005 Randy Dunlap
+ * Copyright (C) 2006 SUSE Linux Products GmbH
+ * Copyright (C) 2006 Hannes Reinecke
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define REGS_PER_GTF   7
+struct taskfile_array {
+   u8  tfa[REGS_PER_GTF];  /* regs. 0x1f1 - 0x1f7 */
+};
+
+struct GTM_buffer {
+   u32 PIO_speed0;
+   u32 DMA_speed0;
+   u32 PIO_speed1;
+   u32 DMA_speed1;
+   u32 GTM_flags;
+};
+
+struct ide_acpi_drive_link {
+   ide_drive_t *drive;
+   acpi_handle  obj_handle;
+   u8   idbuff[512];
+};
+
+struct ide_acpi_hwif_link {
+   ide_hwif_t  *hwif;
+   acpi_handle  obj_handle;
+   struct GTM_buffergtm;
+   struct ide_acpi_drive_link   master;
+   struct ide_acpi_drive_link   slave;
+};
+
+#undef DEBUGGING
+/* note: adds function name and KERN_DEBUG */
+#ifdef DEBUGGING
+#define DEBPRINT(fmt, args...) \
+   printk(KERN_DEBUG "%s: " fmt, __FUNCTION__, ## args)
+#else
+#define DEBPRINT(fmt, args...) do {} while (0)
+#endif /* DEBUGGING */
+
+extern int ide_noacpi;
+extern int ide_noacpitfs;
+extern int ide_noacpionboot;
+
+/**
+ * ide_get_dev_handle - finds acpi_handle and PCI device.function
+ * @dev: device to locate
+ * @handle: returned acpi_handle for @dev
+ * @pcidevfn: return PCI device.func for @dev
+ *
+ * Returns the ACPI object handle to the corresponding PCI device.
+ *
+ * Returns 0 on success, <0 on error.
+ */
+static int ide_get_dev_handle(struct device *dev, acpi_handle *handle,
+  acpi_integer *pcidevfn)
+{
+   struct pci_dev *pdev = to_pci_dev(dev);
+   unsigned int bus, devnum, func;
+   acpi_integer addr;
+   acpi_handle dev_handle;
+   struct acpi_buffer buffer = 

[PATCH 1/15] ACPI support for IDE devices

2007-01-18 Thread Bartlomiej Zolnierkiewicz
[PATCH] ACPI support for IDE devices

This patch implements ACPI integration for generic IDE devices.
The ACPI spec mandates that some methods are called during suspend and
resume. And consequently there most modern Laptops cannot resume
properly without it.

According to the spec, we should call '_GTM' (Get Timing) upon suspend
to store the current IDE adapter settings.
Upon resume we should call '_STM' (Set Timing) to initialize the
adapter with the stored settings; afterwards '_GTF' (Get Taskfile)
should be called which returns a buffer with some IDE initialisation
commands. Those commands should be passed to the drive.

There are two module params which control the behaviour of this patch:

'ide=noacpi'
Do not call any ACPI methods (Disables any ACPI method calls)
'ide=acpigtf'
Enable execution of _GTF methods upon resume.
Has no effect if 'ide=noacpi' is set.
'ide=acpionboot'
Enable execution of ACPI methods during boot.
This might be required on some machines if 'ide=acpigtf' is
selected as some machines modify the _GTF information
depending on the drive identification passed down with _STM.

Signed-off-by: Hannes Reinecke [EMAIL PROTECTED]
Signed-off-by: Bartlomiej Zolnierkiewicz [EMAIL PROTECTED]

---
 drivers/ide/Kconfig |7 
 drivers/ide/Makefile|1 
 drivers/ide/ide-acpi.c  |  696 
 drivers/ide/ide-probe.c |3 
 drivers/ide/ide.c   |   36 ++
 include/linux/ide.h |   27 +
 6 files changed, 770 insertions(+)

Index: b/drivers/ide/Kconfig
===
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -271,6 +271,13 @@ config BLK_DEV_IDESCSI
  If both this SCSI emulation and native ATAPI support are compiled
  into the kernel, the native support will be used.
 
+config BLK_DEV_IDEACPI
+   bool IDE ACPI support
+   depends on ACPI
+   ---help---
+ Implement ACPI support for generic IDE devices. On modern
+ machines ACPI support is required to properly handle ACPI S3 states.
+
 config IDE_TASK_IOCTL
bool IDE Taskfile Access
help
Index: b/drivers/ide/Makefile
===
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -22,6 +22,7 @@ ide-core-$(CONFIG_BLK_DEV_IDEPCI) += set
 ide-core-$(CONFIG_BLK_DEV_IDEDMA)  += ide-dma.o
 ide-core-$(CONFIG_PROC_FS) += ide-proc.o
 ide-core-$(CONFIG_BLK_DEV_IDEPNP)  += ide-pnp.o
+ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o
 
 # built-in only drivers from arm/
 ide-core-$(CONFIG_IDE_ARM) += arm/ide_arm.o
Index: b/drivers/ide/ide-acpi.c
===
--- /dev/null
+++ b/drivers/ide/ide-acpi.c
@@ -0,0 +1,696 @@
+/*
+ * ide-acpi.c
+ * Provides ACPI support for IDE drives.
+ *
+ * Copyright (C) 2005 Intel Corp.
+ * Copyright (C) 2005 Randy Dunlap
+ * Copyright (C) 2006 SUSE Linux Products GmbH
+ * Copyright (C) 2006 Hannes Reinecke
+ */
+
+#include linux/ata.h
+#include linux/delay.h
+#include linux/device.h
+#include linux/errno.h
+#include linux/kernel.h
+#include acpi/acpi.h
+#include linux/ide.h
+#include linux/pci.h
+
+#include acpi/acpi_bus.h
+#include acpi/acnames.h
+#include acpi/acnamesp.h
+#include acpi/acparser.h
+#include acpi/acexcep.h
+#include acpi/acmacros.h
+#include acpi/actypes.h
+
+#define REGS_PER_GTF   7
+struct taskfile_array {
+   u8  tfa[REGS_PER_GTF];  /* regs. 0x1f1 - 0x1f7 */
+};
+
+struct GTM_buffer {
+   u32 PIO_speed0;
+   u32 DMA_speed0;
+   u32 PIO_speed1;
+   u32 DMA_speed1;
+   u32 GTM_flags;
+};
+
+struct ide_acpi_drive_link {
+   ide_drive_t *drive;
+   acpi_handle  obj_handle;
+   u8   idbuff[512];
+};
+
+struct ide_acpi_hwif_link {
+   ide_hwif_t  *hwif;
+   acpi_handle  obj_handle;
+   struct GTM_buffergtm;
+   struct ide_acpi_drive_link   master;
+   struct ide_acpi_drive_link   slave;
+};
+
+#undef DEBUGGING
+/* note: adds function name and KERN_DEBUG */
+#ifdef DEBUGGING
+#define DEBPRINT(fmt, args...) \
+   printk(KERN_DEBUG %s:  fmt, __FUNCTION__, ## args)
+#else
+#define DEBPRINT(fmt, args...) do {} while (0)
+#endif /* DEBUGGING */
+
+extern int ide_noacpi;
+extern int ide_noacpitfs;
+extern int ide_noacpionboot;
+
+/**
+ * ide_get_dev_handle - finds acpi_handle and PCI device.function
+ * @dev: device to locate
+ * @handle: returned acpi_handle for @dev
+ * @pcidevfn: return PCI device.func for @dev
+ *
+ * Returns the ACPI object handle to the corresponding PCI device.
+ *
+ * Returns 0 on success, 0 on error.
+ */
+static int ide_get_dev_handle(struct device *dev, acpi_handle *handle,
+  acpi_integer