* [PATCH 1/7] SATA suspend/resume support (Jens)
[not found] <20051213160110.193e3f61.randy_d_dunlap@linux.intel.com>
@ 2005-12-14 0:02 ` Randy Dunlap
2005-12-14 22:07 ` Jeff Garzik
2005-12-14 0:04 ` [PATCH 2/7] SATA ACPI make/config Randy Dunlap
` (5 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Randy Dunlap @ 2005-12-14 0:02 UTC (permalink / raw)
To: ide; +Cc: axboe, jgarzik
From: Jens Axboe <axboe@suse.de>
Add libata suspend/resume support.
drivers/scsi/ata_piix.c | 4 +
drivers/scsi/libata-core.c | 122 +++++++++++++++++++++++++++++++++++++++++++++
drivers/scsi/libata-scsi.c | 16 +++++
drivers/scsi/scsi_sysfs.c | 35 ++++++++++++
include/linux/ata.h | 2
include/linux/libata.h | 7 ++
include/scsi/scsi_host.h | 6 ++
7 files changed, 190 insertions(+), 2 deletions(-)
---
--- linux-2615-rc5g3.orig/drivers/scsi/ata_piix.c
+++ linux-2615-rc5g3/drivers/scsi/ata_piix.c
@@ -125,6 +125,8 @@ static struct pci_driver piix_pci_driver
.id_table = piix_pci_tbl,
.probe = piix_init_one,
.remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
};
static struct scsi_host_template piix_sht = {
@@ -145,6 +147,8 @@ static struct scsi_host_template piix_sh
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
.ordered_flush = 1,
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
};
static const struct ata_port_operations piix_pata_ops = {
--- linux-2615-rc5g3.orig/drivers/scsi/libata-core.c
+++ linux-2615-rc5g3/drivers/scsi/libata-core.c
@@ -4099,6 +4099,104 @@ err_out:
}
+/*
+ * Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
+ * without filling any other registers
+ */
+static int ata_do_simple_cmd(struct ata_port *ap, struct ata_device *dev,
+ u8 cmd)
+{
+ DECLARE_COMPLETION(wait);
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+ int rc;
+
+ while ((qc = ata_qc_new_init(ap, dev)) == NULL)
+ msleep(10);
+
+ qc->tf.command = cmd;
+ qc->tf.flags |= ATA_TFLAG_DEVICE;
+ qc->tf.protocol = ATA_PROT_NODATA;
+
+ qc->waiting = &wait;
+ qc->complete_fn = ata_qc_complete_noop;
+
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ rc = ata_qc_issue(qc);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+ if (!rc)
+ wait_for_completion(&wait);
+
+ return rc;
+}
+
+static int ata_flush_cache(struct ata_port *ap, struct ata_device *dev)
+{
+ u8 cmd;
+
+ if (!ata_try_flush_cache(dev))
+ return 0;
+
+ if (ata_id_has_flush_ext(dev->id))
+ cmd = ATA_CMD_FLUSH_EXT;
+ else
+ cmd = ATA_CMD_FLUSH;
+
+ return ata_do_simple_cmd(ap, dev, cmd);
+}
+
+static int ata_standby_drive(struct ata_port *ap, struct ata_device *dev)
+{
+ return ata_do_simple_cmd(ap, dev, ATA_CMD_STANDBYNOW1);
+}
+
+static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
+{
+ return ata_do_simple_cmd(ap, dev, ATA_CMD_IDLEIMMEDIATE);
+}
+
+/**
+ * ata_device_resume - wakeup a previously suspended devices
+ *
+ * Kick the drive back into action, by sending it an idle immediate
+ * command and making sure its transfer mode matches between drive
+ * and host.
+ *
+ */
+int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
+{
+ if (ap->flags & ATA_FLAG_SUSPENDED) {
+ ap->flags &= ~ATA_FLAG_SUSPENDED;
+ ata_set_mode(ap);
+ }
+ if (!ata_dev_present(dev))
+ return 0;
+ if (dev->class == ATA_DEV_ATA)
+ ata_start_drive(ap, dev);
+
+ return 0;
+}
+
+/**
+ * ata_device_suspend - prepare a device for suspend
+ *
+ * Flush the cache on the drive, if appropriate, then issue a
+ * standbynow command.
+ *
+ */
+int ata_device_suspend(struct ata_port *ap, struct ata_device *dev)
+{
+ if (!ata_dev_present(dev))
+ return 0;
+ if (dev->class == ATA_DEV_ATA)
+ ata_flush_cache(ap, dev);
+
+ ata_standby_drive(ap, dev);
+ ap->flags |= ATA_FLAG_SUSPENDED;
+ return 0;
+}
+
/**
* ata_port_start - Set port up for dma.
* @ap: Port to initialize
@@ -4860,6 +4958,23 @@ int pci_test_config_bits(struct pci_dev
return (tmp == bits->val) ? 1 : 0;
}
+
+int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+ return 0;
+}
+
+int ata_pci_device_resume(struct pci_dev *pdev)
+{
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ pci_enable_device(pdev);
+ pci_set_master(pdev);
+ return 0;
+}
#endif /* CONFIG_PCI */
@@ -4963,4 +5078,11 @@ EXPORT_SYMBOL_GPL(ata_pci_host_stop);
EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
EXPORT_SYMBOL_GPL(ata_pci_init_one);
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
+EXPORT_SYMBOL_GPL(ata_pci_device_resume);
#endif /* CONFIG_PCI */
+
+EXPORT_SYMBOL_GPL(ata_device_suspend);
+EXPORT_SYMBOL_GPL(ata_device_resume);
+EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
+EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
--- linux-2615-rc5g3.orig/drivers/scsi/libata-scsi.c
+++ linux-2615-rc5g3/drivers/scsi/libata-scsi.c
@@ -396,6 +396,22 @@ void ata_dump_status(unsigned id, struct
}
}
+int ata_scsi_device_resume(struct scsi_device *sdev)
+{
+ struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
+ struct ata_device *dev = &ap->device[sdev->id];
+
+ return ata_device_resume(ap, dev);
+}
+
+int ata_scsi_device_suspend(struct scsi_device *sdev)
+{
+ struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
+ struct ata_device *dev = &ap->device[sdev->id];
+
+ return ata_device_suspend(ap, dev);
+}
+
/**
* ata_to_sense_error - convert ATA error to SCSI error
* @id: ATA device number
--- linux-2615-rc5g3.orig/drivers/scsi/scsi_sysfs.c
+++ linux-2615-rc5g3/drivers/scsi/scsi_sysfs.c
@@ -263,9 +263,40 @@ static int scsi_bus_match(struct device
return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
}
+static int scsi_bus_suspend(struct device * dev, pm_message_t state)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ struct scsi_host_template *sht = sdev->host->hostt;
+ int err;
+
+ err = scsi_device_quiesce(sdev);
+ if (err)
+ return err;
+
+ if (sht->suspend)
+ err = sht->suspend(sdev);
+
+ return err;
+}
+
+static int scsi_bus_resume(struct device * dev)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ struct scsi_host_template *sht = sdev->host->hostt;
+ int err = 0;
+
+ if (sht->resume)
+ err = sht->resume(sdev);
+
+ scsi_device_resume(sdev);
+ return err;
+}
+
struct bus_type scsi_bus_type = {
- .name = "scsi",
- .match = scsi_bus_match,
+ .name = "scsi",
+ .match = scsi_bus_match,
+ .suspend = scsi_bus_suspend,
+ .resume = scsi_bus_resume,
};
int scsi_sysfs_register(void)
--- linux-2615-rc5g3.orig/include/linux/ata.h
+++ linux-2615-rc5g3/include/linux/ata.h
@@ -141,6 +141,8 @@ enum {
ATA_CMD_PACKET = 0xA0,
ATA_CMD_VERIFY = 0x40,
ATA_CMD_VERIFY_EXT = 0x42,
+ ATA_CMD_STANDBYNOW1 = 0xE0,
+ ATA_CMD_IDLEIMMEDIATE = 0xE1,
ATA_CMD_INIT_DEV_PARAMS = 0x91,
/* SETFEATURES stuff */
--- linux-2615-rc5g3.orig/include/linux/libata.h
+++ linux-2615-rc5g3/include/linux/libata.h
@@ -122,6 +122,7 @@ enum {
ATA_FLAG_NOINTR = (1 << 9), /* FIXME: Remove this once
* proper HSM is in place. */
ATA_FLAG_DEBUGMSG = (1 << 10),
+ ATA_FLAG_SUSPENDED = (1 << 11), /* port is suspended */
ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */
ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */
@@ -435,6 +436,8 @@ extern void ata_std_ports(struct ata_iop
extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
unsigned int n_ports);
extern void ata_pci_remove_one (struct pci_dev *pdev);
+extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state);
+extern int ata_pci_device_resume(struct pci_dev *pdev);
#endif /* CONFIG_PCI */
extern int ata_device_add(const struct ata_probe_ent *ent);
extern void ata_host_set_remove(struct ata_host_set *host_set);
@@ -444,6 +447,10 @@ extern int ata_scsi_queuecmd(struct scsi
extern int ata_scsi_error(struct Scsi_Host *host);
extern int ata_scsi_release(struct Scsi_Host *host);
extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
+extern int ata_scsi_device_resume(struct scsi_device *);
+extern int ata_scsi_device_suspend(struct scsi_device *);
+extern int ata_device_resume(struct ata_port *, struct ata_device *);
+extern int ata_device_suspend(struct ata_port *, struct ata_device *);
extern int ata_ratelimit(void);
/*
--- linux-2615-rc5g3.orig/include/scsi/scsi_host.h
+++ linux-2615-rc5g3/include/scsi/scsi_host.h
@@ -296,6 +296,12 @@ struct scsi_host_template {
int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int);
/*
+ * suspend support
+ */
+ int (*suspend)(struct scsi_device *);
+ int (*resume)(struct scsi_device *);
+
+ /*
* Name of proc directory
*/
char *proc_name;
---
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 2/7] SATA ACPI make/config
[not found] <20051213160110.193e3f61.randy_d_dunlap@linux.intel.com>
2005-12-14 0:02 ` [PATCH 1/7] SATA suspend/resume support (Jens) Randy Dunlap
@ 2005-12-14 0:04 ` Randy Dunlap
2005-12-14 22:07 ` Jeff Garzik
2005-12-14 0:05 ` [PATCH 3/7] SATA ACPI linux/libata.h update Randy Dunlap
` (4 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Randy Dunlap @ 2005-12-14 0:04 UTC (permalink / raw)
To: ide; +Cc: axboe, jgarzik
From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
Add ata_acpi in Makefile and Kconfig.
Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
---
drivers/scsi/Kconfig | 5 +++++
drivers/scsi/Makefile | 1 +
2 files changed, 6 insertions(+)
--- linux-2615-rc5g3.orig/drivers/scsi/Makefile
+++ linux-2615-rc5g3/drivers/scsi/Makefile
@@ -138,6 +138,7 @@ obj-$(CONFIG_SCSI_SATA_NV) += libata.o s
obj-$(CONFIG_SCSI_SATA_ULI) += libata.o sata_uli.o
obj-$(CONFIG_SCSI_SATA_MV) += libata.o sata_mv.o
obj-$(CONFIG_SCSI_PDC_ADMA) += libata.o pdc_adma.o
+obj-$(CONFIG_SCSI_SATA_ACPI) += libata.o ata_acpi.o
obj-$(CONFIG_ARM) += arm/
--- linux-2615-rc5g3.orig/drivers/scsi/Kconfig
+++ linux-2615-rc5g3/drivers/scsi/Kconfig
@@ -598,6 +598,11 @@ config SCSI_SATA_INTEL_COMBINED
depends on IDE=y && !BLK_DEV_IDE_SATA && (SCSI_SATA_AHCI || SCSI_ATA_PIIX)
default y
+config SCSI_SATA_ACPI
+ bool
+ depends on SCSI_SATA && ACPI
+ default y
+
config SCSI_BUSLOGIC
tristate "BusLogic SCSI support"
depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API
---
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/7] SATA ACPI linux/libata.h update
[not found] <20051213160110.193e3f61.randy_d_dunlap@linux.intel.com>
2005-12-14 0:02 ` [PATCH 1/7] SATA suspend/resume support (Jens) Randy Dunlap
2005-12-14 0:04 ` [PATCH 2/7] SATA ACPI make/config Randy Dunlap
@ 2005-12-14 0:05 ` Randy Dunlap
2005-12-14 22:08 ` Jeff Garzik
2005-12-14 0:06 ` [PATCH 4/7] call/invoke SATA ACPI suspend/resume functions Randy Dunlap
` (3 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Randy Dunlap @ 2005-12-14 0:05 UTC (permalink / raw)
To: ide; +Cc: axboe, jgarzik
From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
Add ACPI data pointer/length holders.
Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
---
include/linux/libata.h | 8 ++++++++
1 files changed, 8 insertions(+)
--- linux-2615-rc5g3.orig/include/linux/libata.h
+++ linux-2615-rc5g3/include/linux/libata.h
@@ -33,6 +33,7 @@
#include <asm/io.h>
#include <linux/ata.h>
#include <linux/workqueue.h>
+#include <acpi/acpi.h>
/*
* compile-time options
@@ -311,6 +312,13 @@ struct ata_device {
u16 cylinders; /* Number of cylinders */
u16 heads; /* Number of heads */
u16 sectors; /* Number of sectors per track */
+
+#ifdef CONFIG_SCSI_SATA_ACPI
+ /* ACPI objects info */
+ acpi_handle obj_handle;
+ acpi_size gtf_length;
+ u8 *gtf_address;
+#endif
};
struct ata_port {
---
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 4/7] call/invoke SATA ACPI suspend/resume functions
[not found] <20051213160110.193e3f61.randy_d_dunlap@linux.intel.com>
` (2 preceding siblings ...)
2005-12-14 0:05 ` [PATCH 3/7] SATA ACPI linux/libata.h update Randy Dunlap
@ 2005-12-14 0:06 ` Randy Dunlap
2005-12-14 22:11 ` Jeff Garzik
2005-12-14 0:07 ` [PATCH 5/7] SATA ACPI kernel-doc Randy Dunlap
` (2 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Randy Dunlap @ 2005-12-14 0:06 UTC (permalink / raw)
To: ide; +Cc: axboe, jgarzik
From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
Add calls to ACPI methods for SATA drives.
Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
---
drivers/scsi/libata-core.c | 4 ++++
drivers/scsi/libata.h | 26 ++++++++++++++++++++++++++
2 files changed, 30 insertions(+)
--- linux-2615-rc5g3.orig/drivers/scsi/libata-core.c
+++ linux-2615-rc5g3/drivers/scsi/libata-core.c
@@ -1345,6 +1345,8 @@ void ata_dev_config(struct ata_port *ap,
if (ap->ops->dev_config)
ap->ops->dev_config(ap, &ap->device[i]);
+
+ do_drive_SDD(ap, i);
}
/**
@@ -1784,6 +1786,8 @@ static void ata_set_mode(struct ata_port
if (ap->flags & ATA_FLAG_PORT_DISABLED)
return;
+ do_drive_update_taskfiles(ap);
+
if (ap->ops->post_set_mode)
ap->ops->post_set_mode(ap);
--- linux-2615-rc5g3.orig/drivers/scsi/libata.h
+++ linux-2615-rc5g3/drivers/scsi/libata.h
@@ -53,6 +53,32 @@ extern int ata_task_ioctl(struct scsi_de
extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
+/* ata_acpi.c */
+#ifdef CONFIG_SCSI_SATA_ACPI
+extern int do_drive_SDD(struct ata_port *ap, unsigned int ix);
+extern int do_drive_get_GTF(struct ata_port *ap, struct ata_device *atadev);
+extern int do_drive_set_taskfiles(struct ata_port *ap, struct ata_device *atadev);
+extern int do_drive_update_taskfiles(struct ata_port *ap);
+#else
+static inline int do_drive_SDD(struct ata_port *ap, unsigned int ix)
+{
+ return 0;
+}
+static inline int do_drive_get_GTF(struct ata_port *ap, struct ata_device *atadev)
+{
+ return 0;
+}
+static inline int do_drive_set_taskfiles(struct ata_port *ap, struct ata_device *atadev)
+{
+ return 0;
+}
+static inline int do_drive_update_taskfiles(struct ata_port *ap)
+{
+ return 0;
+}
+#endif
+
+
/* libata-scsi.c */
extern void ata_scsi_scan_host(struct ata_port *ap);
extern int ata_scsi_error(struct Scsi_Host *host);
---
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/7] SATA ACPI kernel-doc
[not found] <20051213160110.193e3f61.randy_d_dunlap@linux.intel.com>
` (3 preceding siblings ...)
2005-12-14 0:06 ` [PATCH 4/7] call/invoke SATA ACPI suspend/resume functions Randy Dunlap
@ 2005-12-14 0:07 ` Randy Dunlap
2005-12-14 22:12 ` Jeff Garzik
2005-12-14 0:09 ` [PATCH 6/7] SATA ACPI suspend/resume functions Randy Dunlap
2005-12-14 0:10 ` [PATCH 7/7] SATA ACPI debug-only output Randy Dunlap
6 siblings, 1 reply; 19+ messages in thread
From: Randy Dunlap @ 2005-12-14 0:07 UTC (permalink / raw)
To: ide; +Cc: axboe, jgarzik
From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
Add ata_acpi.c to libata kernel-doc template file.
Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
---
Documentation/DocBook/libata.tmpl | 6 ++++++
1 files changed, 6 insertions(+)
--- linux-2615-rc5g3.orig/Documentation/DocBook/libata.tmpl
+++ linux-2615-rc5g3/Documentation/DocBook/libata.tmpl
@@ -787,6 +787,12 @@ and other resources, etc.
!Idrivers/scsi/libata-scsi.c
</chapter>
+ <chapter id="libataAcpi">
+ <title>libata ACPI interfaces/methods</title>
+!Edrivers/scsi/ata_acpi.c
+!Idrivers/scsi/ata_acpi.c
+ </chapter>
+
<chapter id="ataExceptions">
<title>ATA errors & exceptions</title>
---
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 6/7] SATA ACPI suspend/resume functions
[not found] <20051213160110.193e3f61.randy_d_dunlap@linux.intel.com>
` (4 preceding siblings ...)
2005-12-14 0:07 ` [PATCH 5/7] SATA ACPI kernel-doc Randy Dunlap
@ 2005-12-14 0:09 ` Randy Dunlap
2005-12-14 22:23 ` Jeff Garzik
2005-12-14 0:10 ` [PATCH 7/7] SATA ACPI debug-only output Randy Dunlap
6 siblings, 1 reply; 19+ messages in thread
From: Randy Dunlap @ 2005-12-14 0:09 UTC (permalink / raw)
To: ide; +Cc: axboe, jgarzik
From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
Add support for ACPI methods to SATA suspend/resume.
Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
---
drivers/scsi/ata_acpi.c | 496 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 496 insertions(+)
--- /dev/null
+++ linux-2615-rc5g3/drivers/scsi/ata_acpi.c
@@ -0,0 +1,496 @@
+/*
+ * ata-acpi.c
+ * Provides ACPI support for PATA/SATA.
+ *
+ * Copyright (C) 2005 Intel Corp.
+ * Copyright (C) 2005 Randy Dunlap
+ */
+
+#include <linux/ata.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <acpi/acpi.h>
+#include "scsi.h"
+#include <linux/libata.h>
+#include <linux/pci.h>
+#include "libata.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 SATA_ROOT_PORT(x) (((x) >> 16) & 0xffff)
+#define SATA_PORT_NUMBER(x) ((x) & 0xffff) /* or NO_PORT_MULT */
+#define NO_PORT_MULT 0xffff
+#define SATA_ADR_RSVD 0xffffffff
+
+#define REGS_PER_GTF 7
+struct taskfile_array {
+ u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
+};
+
+#define DEBUGGING 1
+/* 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 */
+
+static u8 *acpi_path_name(acpi_handle handle)
+{
+ acpi_status status;
+ static u8 path_name[ACPI_PATHNAME_MAX];
+ struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name };
+
+ memset(path_name, 0, sizeof (path_name));
+ status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
+
+ if (ACPI_FAILURE(status))
+ return NULL;
+
+ return path_name;
+}
+
+/**
+ * pci_acpi_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 0 on success, <0 on error.
+ */
+static int pci_acpi_get_dev_handle(struct device *dev, acpi_handle *handle,
+ acpi_integer *pcidevfn)
+{
+ struct pci_dev *pci_dev;
+ acpi_integer addr;
+
+ pci_dev = to_pci_dev(dev);
+ /* Please refer to the ACPI spec for the syntax of _ADR. */
+ addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
+ *pcidevfn = addr;
+ *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
+ DEBPRINT("pcidevfn: 0x%llx\n",
+ (unsigned long long)*pcidevfn);
+ if (!*handle)
+ return -ENODEV;
+ return 0;
+}
+
+struct walk_info { /* can be trimmed some */
+ struct device *dev;
+ struct acpi_device *adev;
+ acpi_handle handle;
+ acpi_integer pcidevfn;
+ unsigned int drivenum;
+ acpi_handle obj_handle;
+ struct ata_port *ataport;
+ struct ata_device *atadev;
+ u32 sata_adr;
+ int status;
+ char basepath[ACPI_PATHNAME_MAX];
+ int basepath_len;
+};
+
+static acpi_status get_devices(acpi_handle handle,
+ u32 level, void *context, void **return_value)
+{
+ acpi_status status;
+ struct walk_info *winfo = context;
+ u8 *path_name = acpi_path_name(handle);
+ struct acpi_buffer buffer;
+ struct acpi_device_info *dinfo;
+
+ buffer.length = ACPI_ALLOCATE_BUFFER;
+ buffer.pointer = NULL;
+ status = acpi_get_object_info(handle, &buffer);
+
+ if (ACPI_SUCCESS(status)) {
+ dinfo = buffer.pointer;
+
+ /* find full device path name for pcidevfn */
+ if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
+ dinfo->address == winfo->pcidevfn) {
+ DEBPRINT(":%s: matches pcidevfn (0x%llx)\n",
+ path_name, winfo->pcidevfn);
+ strlcpy(winfo->basepath, path_name,
+ sizeof(winfo->basepath));
+ winfo->basepath_len = strlen(path_name);
+ goto out;
+ }
+
+ /* if basepath is not yet known, ignore this object */
+ if (!winfo->basepath_len)
+ goto out;
+
+ /* if this object is in scope of basepath, maybe use it */
+ if (strncmp(path_name, winfo->basepath,
+ winfo->basepath_len) == 0) {
+ if (!(dinfo->valid & ACPI_VALID_ADR))
+ goto out;
+ DEBPRINT("GOT ONE: "
+ "(%s) root_port = 0x%llx, port_num = 0x%llx\n",
+ path_name,
+ SATA_ROOT_PORT(dinfo->address),
+ SATA_PORT_NUMBER(dinfo->address));
+ /* heuristics: */
+ if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT)
+ DEBPRINT("warning: don't know how to handle SATA port multiplier\n");
+ if (SATA_ROOT_PORT(dinfo->address) ==
+ winfo->ataport->port_no &&
+ SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) {
+ DEBPRINT("THIS ^^^^^ is the requested SATA drive (handle = 0x%p)\n",
+ handle);
+ winfo->sata_adr = dinfo->address;
+ winfo->obj_handle = handle;
+ }
+ }
+out:
+ acpi_os_free(dinfo);
+ }
+
+ return status;
+}
+
+/* Get the SATA drive _ADR object. */
+static int get_sata_adr(struct device *dev, acpi_handle handle,
+ acpi_integer pcidevfn, unsigned int drive,
+ struct ata_port *ap,
+ struct ata_device *atadev, u32 *dev_adr)
+{
+ acpi_status status;
+ struct walk_info *winfo;
+ int err = -ENOMEM;
+
+ winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL);
+ if (!winfo)
+ goto out;
+
+ winfo->dev = dev;
+ winfo->atadev = atadev;
+ winfo->ataport = ap;
+ if (acpi_bus_get_device(handle, &winfo->adev) < 0)
+ DEBPRINT("acpi_bus_get_device failed\n");
+ winfo->handle = handle;
+ winfo->pcidevfn = pcidevfn;
+ winfo->drivenum = drive;
+
+ status = acpi_get_devices(NULL, get_devices, winfo, NULL);
+ if (ACPI_FAILURE(status))
+ err = -ENODEV;
+ else {
+ *dev_adr = winfo->sata_adr;
+ atadev->obj_handle = winfo->obj_handle;
+ err = 0;
+ }
+ kfree(winfo);
+out:
+ return err;
+}
+
+/**
+ * do_drive_SDD - send Identify data to a drive
+ * @ap: the ata_port for the drive
+ * @ix: drive index
+ *
+ * Must be after Identify (Packet) Device -- uses its data.
+ */
+int do_drive_SDD(struct ata_port *ap, unsigned int ix)
+{
+ acpi_handle handle;
+ acpi_integer pcidevfn;
+ int err = -ENODEV;
+ struct device *dev = ap->host_set->dev;
+ struct ata_device *atadev = &ap->device[ix];
+ u32 dev_adr;
+ acpi_status status;
+ struct acpi_object_list input;
+ union acpi_object in_params[1];
+
+ printk(KERN_DEBUG
+ "%s: ap->id: %d, ix = %d, port#: %d, hard_port#: %d\n",
+ __FUNCTION__, ap->id, ix, ap->port_no, ap->hard_port_no);
+
+ /* Don't continue if not a SATA device. */
+ if (!ata_id_is_sata(atadev->id))
+ goto out;
+
+ /* Don't continue if device has no _ADR method.
+ * _SDD is intended for known motherboard devices. */
+ err = pci_acpi_get_dev_handle(dev, &handle, &pcidevfn);
+ if (err < 0)
+ goto out;
+ /* Get this drive's _ADR info. */
+ dev_adr = SATA_ADR_RSVD;
+ err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev, &dev_adr);
+ if (err < 0 || dev_adr == SATA_ADR_RSVD || !atadev->obj_handle)
+ goto out;
+
+ /* Give the drive Identify data to the drive via the _SDD method */
+ /* _SDD: set up input parameters */
+ input.count = 1;
+ input.pointer = in_params;
+ in_params[0].type = ACPI_TYPE_BUFFER;
+ in_params[0].buffer.length = sizeof(atadev->id);
+ in_params[0].buffer.pointer = (u8 *)atadev->id;
+ /* Output buffer: _SDD has no output */
+
+ /* It's OK for _SDD to be missing too. */
+ status = acpi_evaluate_object(atadev->obj_handle, "_SDD", &input, NULL);
+ err = ACPI_FAILURE(status) ? -EIO : 0;
+ if (err < 0) {
+ printk(KERN_DEBUG
+ "ata%u(%u): %s _SDD error: status = 0x%x\n",
+ ap->id, ap->device->devno, __FUNCTION__, status);
+ }
+out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(do_drive_SDD);
+
+/**
+ * do_drive_get_GTF - get the drive bootup default taskfile settings
+ * @ap: the ata_port for the drive
+ * @atadev: target ata_device
+ *
+ * This applies to both PATA and SATA drives.
+ *
+ * The _GTF method has no input parameters.
+ * It returns a variable number of register set values (registers
+ * hex 1F1..1F7, taskfiles).
+ * The <variable number> is not known in advance, so have ACPI-CA
+ * allocate the buffer as needed and return it, then free it later.
+ *
+ */
+int do_drive_get_GTF(struct ata_port *ap, struct ata_device *atadev)
+{
+ acpi_status status;
+ acpi_handle handle;
+ acpi_integer pcidevfn;
+ u32 dev_adr;
+ struct acpi_buffer output;
+ union acpi_object *out_obj;
+ struct device *dev = ap->host_set->dev;
+ int err = -ENODEV;
+
+ if (!ata_dev_present(atadev)) /* or port disabled ? */
+ goto out;
+
+ /* Don't continue if device has no _ADR method.
+ * _GTF is intended for known motherboard devices. */
+ err = pci_acpi_get_dev_handle(dev, &handle, &pcidevfn);
+ if (err < 0)
+ goto out;
+
+ /* Get this drive's _ADR info. if _SDD didn't get it. */
+ if (!atadev->obj_handle) {
+ dev_adr = SATA_ADR_RSVD;
+ err = get_sata_adr(dev, handle, pcidevfn, 0, ap, atadev, &dev_adr);
+ if (err < 0 || dev_adr == SATA_ADR_RSVD || !atadev->obj_handle)
+ goto out;
+ }
+
+ /* Setting up output buffer */
+ output.length = ACPI_ALLOCATE_BUFFER;
+ output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
+
+ /* _GTF has no input parameters */
+ err = -EIO;
+ status = acpi_evaluate_object(atadev->obj_handle, "_GTF",
+ NULL, &output);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_DEBUG
+ "%s: Run _GTF error: status = 0x%x\n",
+ __FUNCTION__, status);
+ goto out;
+ }
+
+ if (!output.length || !output.pointer) {
+ printk(KERN_DEBUG
+ "%s: Run _GTF: length or ptr is NULL (0x%llx, 0x%p)\n",
+ __FUNCTION__,
+ (unsigned long long)output.length, output.pointer);
+ acpi_os_free(output.pointer);
+ goto out;
+ }
+
+ out_obj = output.pointer;
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
+ acpi_os_free(output.pointer);
+ printk(KERN_DEBUG "%s: Run _GTF: error: "
+ "expected object type of ACPI_TYPE_BUFFER, got 0x%x\n",
+ __FUNCTION__, out_obj->type);
+ err = -ENOENT;
+ goto out;
+ }
+
+ atadev->gtf_length = out_obj->buffer.length;
+ atadev->gtf_address = out_obj->buffer.pointer;
+ err = 0;
+out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(do_drive_get_GTF);
+
+/**
+ * taskfile_load_raw - send taskfile registers to host controller
+ * @ap: Port to which output is sent
+ * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
+ *
+ * Outputs ATA taskfile to standard ATA host controller using MMIO
+ * or PIO as indicated by the ATA_FLAG_MMIO flag.
+ * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
+ * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
+ * hob_lbal, hob_lbam, and hob_lbah.
+ *
+ * This function waits for idle (!BUSY and !DRQ) after writing
+ * registers. If the control register has a new value, this
+ * function also waits for idle after writing control and before
+ * writing the remaining registers.
+ *
+ * LOCKING: TBD:
+ * Inherited from caller.
+ */
+static void taskfile_load_raw(struct ata_port *ap,
+ struct ata_device *atadev,
+ const struct taskfile_array *gtf)
+{
+ DEBPRINT("(0x1f1-1f7): hex: %02x %02x %02x %02x %02x %02x %02x\n",
+ gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
+ gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
+
+ if (ap->ops->tf_load && ap->ops->exec_command) {
+ struct ata_taskfile atf;
+
+ /* convert gtf to atf */
+ ata_tf_init(ap, &atf, 0);
+ atf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
+ atf.protocol = ATA_PROT_NODATA; /* or ATA_PROT_ATAPI_NODATA */
+ atf.feature = gtf->tfa[0]; /* 0x1f1 */
+ atf.nsect = gtf->tfa[1]; /* 0x1f2 */
+ atf.lbal = gtf->tfa[2]; /* 0x1f3 */
+ atf.lbam = gtf->tfa[3]; /* 0x1f4 */
+ atf.lbah = gtf->tfa[4]; /* 0x1f5 */
+ atf.device = gtf->tfa[5]; /* 0x1f6 */
+ atf.command = gtf->tfa[6]; /* 0x1f7 */
+
+ DEBPRINT("call tf_load:\n");
+ ap->ops->tf_load(ap, &atf);
+ DEBPRINT("call exec_command:\n");
+ ap->ops->exec_command(ap, &atf);
+ DEBPRINT("tf_load & exec_command done.\n");
+ } else if (ap->ops->qc_issue && ap->ops->qc_prep) {
+ int ret;
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+ DECLARE_COMPLETION(wait);
+
+ qc = ata_qc_new_init(ap, atadev);
+ if (!qc) {
+ printk(KERN_DEBUG "%s: ata_qc_new_init ret. NULL\n",
+ __FUNCTION__);
+ return;
+ }
+
+ /* convert gtf to qc.tf */
+ qc->tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
+ qc->tf.protocol = ATA_PROT_NODATA; /* or ATA_PROT_ATAPI_NODATA */
+ qc->tf.feature = gtf->tfa[0]; /* 0x1f1 */
+ qc->tf.nsect = gtf->tfa[1]; /* 0x1f2 */
+ qc->tf.lbal = gtf->tfa[2]; /* 0x1f3 */
+ qc->tf.lbam = gtf->tfa[3]; /* 0x1f4 */
+ qc->tf.lbah = gtf->tfa[4]; /* 0x1f5 */
+ qc->tf.device = gtf->tfa[5]; /* 0x1f6 */
+ qc->tf.command = gtf->tfa[6]; /* 0x1f7 */
+
+ qc->waiting = &wait;
+ qc->complete_fn = ata_qc_complete_noop;
+
+ // TBD: fix locking and return value/wait_for_completion here:
+ DEBPRINT("call ata_qc_issue:\n");
+ spin_lock_irqsave(&ap->host_set->lock, flags);
+ ret = ata_qc_issue(qc);
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
+ DEBPRINT("ata_qc_issue done: ret = 0x%x\n", ret);
+
+ if (!ret)
+ wait_for_completion(&wait);
+ } else
+ printk(KERN_WARNING "%s: SATA driver is missing tf_load/exec_command or qc_issue function entry points\n",
+ __FUNCTION__);
+}
+
+/**
+ * do_drive_set_taskfiles - write the drive taskfile settings from _GTF
+ * @ap: the ata_port for the drive
+ * @atadev: target ata_device
+ *
+ * This applies to both PATA and SATA drives.
+ *
+ * Write {atadev->gtf_address, length atadev->gtf_length} in groups of
+ * REGS_PER_GTF bytes.
+ *
+ */
+int do_drive_set_taskfiles(struct ata_port *ap, struct ata_device *atadev)
+{
+ int err = -ENODEV;
+ int gtf_count =
+ atadev->gtf_length / REGS_PER_GTF;
+ int ix;
+ struct taskfile_array *gtf;
+
+ if (!ata_dev_present(atadev)) /* or port disabled ? */
+ goto out;
+ if (!gtf_count) /* shouldn't be here */
+ goto out;
+
+ DEBPRINT("total GTF bytes = %lld (0x%llx), gtf_count = %d\n",
+ (unsigned long long)atadev->gtf_length,
+ (unsigned long long)atadev->gtf_length, gtf_count);
+ if (atadev->gtf_length % REGS_PER_GTF) {
+ printk(KERN_ERR "%s: unexpected GTF length (%zd)\n",
+ __FUNCTION__, atadev->gtf_length);
+ goto out;
+ }
+
+ for (ix = 0; ix < gtf_count; ix++) {
+ gtf = (struct taskfile_array *)
+ (atadev->gtf_address + ix * REGS_PER_GTF);
+
+ /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
+ taskfile_load_raw(ap, atadev, gtf);
+ }
+
+ err = 0;
+out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(do_drive_set_taskfiles);
+
+/**
+ * do_drive_update_taskfiles - get then write drive taskfile settings
+ * @ap: the ata_port for the drive
+ *
+ * This applies to both PATA and SATA drives.
+ */
+int do_drive_update_taskfiles(struct ata_port *ap)
+{
+ int ix;
+ int ret;
+
+ for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
+ ret = do_drive_get_GTF(ap, &ap->device[ix]);
+ if (ret >= 0)
+ ret = do_drive_set_taskfiles(ap, &ap->device[ix]);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(do_drive_update_taskfiles);
---
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 7/7] SATA ACPI debug-only output
[not found] <20051213160110.193e3f61.randy_d_dunlap@linux.intel.com>
` (5 preceding siblings ...)
2005-12-14 0:09 ` [PATCH 6/7] SATA ACPI suspend/resume functions Randy Dunlap
@ 2005-12-14 0:10 ` Randy Dunlap
2005-12-14 22:23 ` Jeff Garzik
6 siblings, 1 reply; 19+ messages in thread
From: Randy Dunlap @ 2005-12-14 0:10 UTC (permalink / raw)
To: ide; +Cc: axboe, jgarzik
From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
Add some extra debug-only output.
Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
---
drivers/scsi/ata_acpi.c | 17 ++++++++++++-----
drivers/scsi/libata-core.c | 6 +++---
2 files changed, 15 insertions(+), 8 deletions(-)
--- linux-2615-rc5g3.orig/drivers/scsi/ata_acpi.c
+++ linux-2615-rc5g3/drivers/scsi/ata_acpi.c
@@ -183,9 +183,10 @@ static int get_sata_adr(struct device *d
winfo->drivenum = drive;
status = acpi_get_devices(NULL, get_devices, winfo, NULL);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(status)) {
+ DEBPRINT("acpi_get_devices failed\n");
err = -ENODEV;
- else {
+ } else {
*dev_adr = winfo->sata_adr;
atadev->obj_handle = winfo->obj_handle;
err = 0;
@@ -219,19 +220,25 @@ int do_drive_SDD(struct ata_port *ap, un
__FUNCTION__, ap->id, ix, ap->port_no, ap->hard_port_no);
/* Don't continue if not a SATA device. */
- if (!ata_id_is_sata(atadev->id))
+ if (!ata_id_is_sata(atadev->id)) {
+ DEBPRINT("ata_id_is_sata is False\n");
goto out;
+ }
/* Don't continue if device has no _ADR method.
* _SDD is intended for known motherboard devices. */
err = pci_acpi_get_dev_handle(dev, &handle, &pcidevfn);
- if (err < 0)
+ if (err < 0) {
+ DEBPRINT("get_dev_handle failed\n");
goto out;
+ }
/* Get this drive's _ADR info. */
dev_adr = SATA_ADR_RSVD;
err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev, &dev_adr);
- if (err < 0 || dev_adr == SATA_ADR_RSVD || !atadev->obj_handle)
+ if (err < 0 || dev_adr == SATA_ADR_RSVD || !atadev->obj_handle) {
+ DEBPRINT("get_sata_adr failed\n");
goto out;
+ }
/* Give the drive Identify data to the drive via the _SDD method */
/* _SDD: set up input parameters */
--- linux-2615-rc5g3.orig/drivers/scsi/libata-core.c
+++ linux-2615-rc5g3/drivers/scsi/libata-core.c
@@ -1185,11 +1185,11 @@ retry:
/* print device capabilities */
printk(KERN_DEBUG "ata%u: dev %u cfg "
- "49:%04x 82:%04x 83:%04x 84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n",
- ap->id, device, dev->id[49],
+ "00:%04x 49:%04x 82:%04x 83:%04x 84:%04x 85:%04x 86:%04x 87:%04x 88:%04x 93:%04x\n",
+ ap->id, device, dev->id[0], dev->id[49],
dev->id[82], dev->id[83], dev->id[84],
dev->id[85], dev->id[86], dev->id[87],
- dev->id[88]);
+ dev->id[88], dev->id[93]);
/*
* common ATA, ATAPI feature tests
---
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/7] SATA suspend/resume support (Jens)
2005-12-14 0:02 ` [PATCH 1/7] SATA suspend/resume support (Jens) Randy Dunlap
@ 2005-12-14 22:07 ` Jeff Garzik
2005-12-14 22:22 ` Randy Dunlap
0 siblings, 1 reply; 19+ messages in thread
From: Jeff Garzik @ 2005-12-14 22:07 UTC (permalink / raw)
To: Randy Dunlap; +Cc: ide, axboe
Randy Dunlap wrote:
> From: Jens Axboe <axboe@suse.de>
>
> Add libata suspend/resume support.
>
> drivers/scsi/ata_piix.c | 4 +
> drivers/scsi/libata-core.c | 122 +++++++++++++++++++++++++++++++++++++++++++++
> drivers/scsi/libata-scsi.c | 16 +++++
> drivers/scsi/scsi_sysfs.c | 35 ++++++++++++
> include/linux/ata.h | 2
> include/linux/libata.h | 7 ++
> include/scsi/scsi_host.h | 6 ++
> 7 files changed, 190 insertions(+), 2 deletions(-)
What happened to the patch you were attempting to resurrect, which
implemented scsi suspend/resume a better way?
Jeff
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/7] SATA ACPI make/config
2005-12-14 0:04 ` [PATCH 2/7] SATA ACPI make/config Randy Dunlap
@ 2005-12-14 22:07 ` Jeff Garzik
0 siblings, 0 replies; 19+ messages in thread
From: Jeff Garzik @ 2005-12-14 22:07 UTC (permalink / raw)
To: Randy Dunlap; +Cc: ide, axboe
Randy Dunlap wrote:
> From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
>
> Add ata_acpi in Makefile and Kconfig.
>
> Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
obviously OK (depending on other things)
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/7] SATA ACPI linux/libata.h update
2005-12-14 0:05 ` [PATCH 3/7] SATA ACPI linux/libata.h update Randy Dunlap
@ 2005-12-14 22:08 ` Jeff Garzik
2005-12-14 23:00 ` Randy Dunlap
0 siblings, 1 reply; 19+ messages in thread
From: Jeff Garzik @ 2005-12-14 22:08 UTC (permalink / raw)
To: Randy Dunlap; +Cc: ide, axboe
Randy Dunlap wrote:
> From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
>
> Add ACPI data pointer/length holders.
>
> Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
Why does struct ata_device need to remember this info at all?
Jeff
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 4/7] call/invoke SATA ACPI suspend/resume functions
2005-12-14 0:06 ` [PATCH 4/7] call/invoke SATA ACPI suspend/resume functions Randy Dunlap
@ 2005-12-14 22:11 ` Jeff Garzik
0 siblings, 0 replies; 19+ messages in thread
From: Jeff Garzik @ 2005-12-14 22:11 UTC (permalink / raw)
To: Randy Dunlap; +Cc: ide, axboe
Randy Dunlap wrote:
> From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
>
> Add calls to ACPI methods for SATA drives.
>
> Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
> ---
> drivers/scsi/libata-core.c | 4 ++++
> drivers/scsi/libata.h | 26 ++++++++++++++++++++++++++
> 2 files changed, 30 insertions(+)
>
> --- linux-2615-rc5g3.orig/drivers/scsi/libata-core.c
> +++ linux-2615-rc5g3/drivers/scsi/libata-core.c
> @@ -1345,6 +1345,8 @@ void ata_dev_config(struct ata_port *ap,
>
> if (ap->ops->dev_config)
> ap->ops->dev_config(ap, &ap->device[i]);
> +
> + do_drive_SDD(ap, i);
> }
>
> /**
> @@ -1784,6 +1786,8 @@ static void ata_set_mode(struct ata_port
> if (ap->flags & ATA_FLAG_PORT_DISABLED)
> return;
>
> + do_drive_update_taskfiles(ap);
> +
> if (ap->ops->post_set_mode)
> ap->ops->post_set_mode(ap);
>
Mostly OK.
1) The function names are awful. I would suggest ata_acpi_push_id() and
ata_acpi_exec_tfs() instead.
2) The call to do_drive_update_taskfiles() should be done in
ata_bus_probe(), not inside ata_set_mode() where it is essentially
hidden amongst code that is dedicated to a single purpose, getting the
data xfer timings.
Jeff
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 5/7] SATA ACPI kernel-doc
2005-12-14 0:07 ` [PATCH 5/7] SATA ACPI kernel-doc Randy Dunlap
@ 2005-12-14 22:12 ` Jeff Garzik
0 siblings, 0 replies; 19+ messages in thread
From: Jeff Garzik @ 2005-12-14 22:12 UTC (permalink / raw)
To: Randy Dunlap; +Cc: ide, axboe
Randy Dunlap wrote:
> From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
>
> Add ata_acpi.c to libata kernel-doc template file.
>
> Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
obviously OK
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/7] SATA suspend/resume support (Jens)
2005-12-14 22:07 ` Jeff Garzik
@ 2005-12-14 22:22 ` Randy Dunlap
0 siblings, 0 replies; 19+ messages in thread
From: Randy Dunlap @ 2005-12-14 22:22 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-ide, axboe
On Wed, 14 Dec 2005 17:07:38 -0500
Jeff Garzik <jgarzik@pobox.com> wrote:
> Randy Dunlap wrote:
> > From: Jens Axboe <axboe@suse.de>
> >
> > Add libata suspend/resume support.
> >
> > drivers/scsi/ata_piix.c | 4 +
> > drivers/scsi/libata-core.c | 122 +++++++++++++++++++++++++++++++++++++++++++++
> > drivers/scsi/libata-scsi.c | 16 +++++
> > drivers/scsi/scsi_sysfs.c | 35 ++++++++++++
> > include/linux/ata.h | 2
> > include/linux/libata.h | 7 ++
> > include/scsi/scsi_host.h | 6 ++
> > 7 files changed, 190 insertions(+), 2 deletions(-)
>
> What happened to the patch you were attempting to resurrect, which
> implemented scsi suspend/resume a better way?
The last incarnation of it is still at
http://www.xenotime.net/linux/scsi/scsi-susres-devattr.patch
It is missing some linkage (maybe ->ops) between layers.
I was getting close to zero feedback on it --> it went stale,
so I decided to try make make Jens's patch work with ACPI
additions.
---
~Randy
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 6/7] SATA ACPI suspend/resume functions
2005-12-14 0:09 ` [PATCH 6/7] SATA ACPI suspend/resume functions Randy Dunlap
@ 2005-12-14 22:23 ` Jeff Garzik
0 siblings, 0 replies; 19+ messages in thread
From: Jeff Garzik @ 2005-12-14 22:23 UTC (permalink / raw)
To: Randy Dunlap; +Cc: ide, axboe
Randy Dunlap wrote:
> From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
>
> Add support for ACPI methods to SATA suspend/resume.
>
> Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
> ---
> drivers/scsi/ata_acpi.c | 496 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 496 insertions(+)
>
> --- /dev/null
> +++ linux-2615-rc5g3/drivers/scsi/ata_acpi.c
> @@ -0,0 +1,496 @@
> +/*
> + * ata-acpi.c
> + * Provides ACPI support for PATA/SATA.
> + *
> + * Copyright (C) 2005 Intel Corp.
> + * Copyright (C) 2005 Randy Dunlap
> + */
> +
> +#include <linux/ata.h>
> +#include <linux/device.h>
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +#include <acpi/acpi.h>
> +#include "scsi.h"
> +#include <linux/libata.h>
> +#include <linux/pci.h>
> +#include "libata.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 SATA_ROOT_PORT(x) (((x) >> 16) & 0xffff)
> +#define SATA_PORT_NUMBER(x) ((x) & 0xffff) /* or NO_PORT_MULT */
> +#define NO_PORT_MULT 0xffff
> +#define SATA_ADR_RSVD 0xffffffff
> +
> +#define REGS_PER_GTF 7
> +struct taskfile_array {
> + u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
> +};
> +
> +#define DEBUGGING 1
> +/* 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 */
> +
> +static u8 *acpi_path_name(acpi_handle handle)
> +{
> + acpi_status status;
> + static u8 path_name[ACPI_PATHNAME_MAX];
> + struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name };
> +
> + memset(path_name, 0, sizeof (path_name));
> + status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
> +
> + if (ACPI_FAILURE(status))
> + return NULL;
> +
> + return path_name;
> +}
this should be in generic code somewhere
> +/**
> + * pci_acpi_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 0 on success, <0 on error.
> + */
> +static int pci_acpi_get_dev_handle(struct device *dev, acpi_handle *handle,
> + acpi_integer *pcidevfn)
> +{
> + struct pci_dev *pci_dev;
> + acpi_integer addr;
> +
> + pci_dev = to_pci_dev(dev);
> + /* Please refer to the ACPI spec for the syntax of _ADR. */
> + addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
> + *pcidevfn = addr;
> + *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
> + DEBPRINT("pcidevfn: 0x%llx\n",
> + (unsigned long long)*pcidevfn);
> + if (!*handle)
> + return -ENODEV;
> + return 0;
> +}
this should be in generic code somewhere
> +struct walk_info { /* can be trimmed some */
> + struct device *dev;
> + struct acpi_device *adev;
> + acpi_handle handle;
> + acpi_integer pcidevfn;
> + unsigned int drivenum;
> + acpi_handle obj_handle;
> + struct ata_port *ataport;
> + struct ata_device *atadev;
> + u32 sata_adr;
> + int status;
> + char basepath[ACPI_PATHNAME_MAX];
> + int basepath_len;
> +};
> +
> +static acpi_status get_devices(acpi_handle handle,
> + u32 level, void *context, void **return_value)
> +{
> + acpi_status status;
> + struct walk_info *winfo = context;
> + u8 *path_name = acpi_path_name(handle);
> + struct acpi_buffer buffer;
> + struct acpi_device_info *dinfo;
> +
> + buffer.length = ACPI_ALLOCATE_BUFFER;
> + buffer.pointer = NULL;
> + status = acpi_get_object_info(handle, &buffer);
> +
> + if (ACPI_SUCCESS(status)) {
> + dinfo = buffer.pointer;
> +
> + /* find full device path name for pcidevfn */
> + if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
> + dinfo->address == winfo->pcidevfn) {
> + DEBPRINT(":%s: matches pcidevfn (0x%llx)\n",
> + path_name, winfo->pcidevfn);
> + strlcpy(winfo->basepath, path_name,
> + sizeof(winfo->basepath));
> + winfo->basepath_len = strlen(path_name);
> + goto out;
> + }
> +
> + /* if basepath is not yet known, ignore this object */
> + if (!winfo->basepath_len)
> + goto out;
> +
> + /* if this object is in scope of basepath, maybe use it */
> + if (strncmp(path_name, winfo->basepath,
> + winfo->basepath_len) == 0) {
> + if (!(dinfo->valid & ACPI_VALID_ADR))
> + goto out;
> + DEBPRINT("GOT ONE: "
> + "(%s) root_port = 0x%llx, port_num = 0x%llx\n",
> + path_name,
> + SATA_ROOT_PORT(dinfo->address),
> + SATA_PORT_NUMBER(dinfo->address));
> + /* heuristics: */
> + if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT)
> + DEBPRINT("warning: don't know how to handle SATA port multiplier\n");
> + if (SATA_ROOT_PORT(dinfo->address) ==
> + winfo->ataport->port_no &&
> + SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) {
> + DEBPRINT("THIS ^^^^^ is the requested SATA drive (handle = 0x%p)\n",
> + handle);
> + winfo->sata_adr = dinfo->address;
> + winfo->obj_handle = handle;
> + }
> + }
> +out:
> + acpi_os_free(dinfo);
> + }
> +
> + return status;
> +}
> +/* Get the SATA drive _ADR object. */
> +static int get_sata_adr(struct device *dev, acpi_handle handle,
> + acpi_integer pcidevfn, unsigned int drive,
> + struct ata_port *ap,
> + struct ata_device *atadev, u32 *dev_adr)
> +{
> + acpi_status status;
> + struct walk_info *winfo;
> + int err = -ENOMEM;
> +
> + winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL);
> + if (!winfo)
> + goto out;
> +
> + winfo->dev = dev;
> + winfo->atadev = atadev;
> + winfo->ataport = ap;
> + if (acpi_bus_get_device(handle, &winfo->adev) < 0)
> + DEBPRINT("acpi_bus_get_device failed\n");
> + winfo->handle = handle;
> + winfo->pcidevfn = pcidevfn;
> + winfo->drivenum = drive;
> +
> + status = acpi_get_devices(NULL, get_devices, winfo, NULL);
> + if (ACPI_FAILURE(status))
> + err = -ENODEV;
> + else {
> + *dev_adr = winfo->sata_adr;
> + atadev->obj_handle = winfo->obj_handle;
> + err = 0;
> + }
> + kfree(winfo);
> +out:
> + return err;
> +}
> +
> +/**
> + * do_drive_SDD - send Identify data to a drive
> + * @ap: the ata_port for the drive
> + * @ix: drive index
> + *
> + * Must be after Identify (Packet) Device -- uses its data.
> + */
> +int do_drive_SDD(struct ata_port *ap, unsigned int ix)
> +{
> + acpi_handle handle;
> + acpi_integer pcidevfn;
> + int err = -ENODEV;
> + struct device *dev = ap->host_set->dev;
> + struct ata_device *atadev = &ap->device[ix];
> + u32 dev_adr;
> + acpi_status status;
> + struct acpi_object_list input;
> + union acpi_object in_params[1];
> +
> + printk(KERN_DEBUG
> + "%s: ap->id: %d, ix = %d, port#: %d, hard_port#: %d\n",
> + __FUNCTION__, ap->id, ix, ap->port_no, ap->hard_port_no);
> +
> + /* Don't continue if not a SATA device. */
> + if (!ata_id_is_sata(atadev->id))
> + goto out;
> +
> + /* Don't continue if device has no _ADR method.
> + * _SDD is intended for known motherboard devices. */
> + err = pci_acpi_get_dev_handle(dev, &handle, &pcidevfn);
> + if (err < 0)
> + goto out;
> + /* Get this drive's _ADR info. */
> + dev_adr = SATA_ADR_RSVD;
> + err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev, &dev_adr);
> + if (err < 0 || dev_adr == SATA_ADR_RSVD || !atadev->obj_handle)
> + goto out;
> +
> + /* Give the drive Identify data to the drive via the _SDD method */
> + /* _SDD: set up input parameters */
> + input.count = 1;
> + input.pointer = in_params;
> + in_params[0].type = ACPI_TYPE_BUFFER;
> + in_params[0].buffer.length = sizeof(atadev->id);
> + in_params[0].buffer.pointer = (u8 *)atadev->id;
libata runs swap_buf_le16() on atadev->id. Are you sure you don't need
swap the buffer before sending?
> + /* Output buffer: _SDD has no output */
> +
> + /* It's OK for _SDD to be missing too. */
> + status = acpi_evaluate_object(atadev->obj_handle, "_SDD", &input, NULL);
> + err = ACPI_FAILURE(status) ? -EIO : 0;
> + if (err < 0) {
> + printk(KERN_DEBUG
> + "ata%u(%u): %s _SDD error: status = 0x%x\n",
> + ap->id, ap->device->devno, __FUNCTION__, status);
> + }
> +out:
> + return err;
> +}
> +EXPORT_SYMBOL_GPL(do_drive_SDD);
> +
> +/**
> + * do_drive_get_GTF - get the drive bootup default taskfile settings
> + * @ap: the ata_port for the drive
> + * @atadev: target ata_device
> + *
> + * This applies to both PATA and SATA drives.
> + *
> + * The _GTF method has no input parameters.
> + * It returns a variable number of register set values (registers
> + * hex 1F1..1F7, taskfiles).
> + * The <variable number> is not known in advance, so have ACPI-CA
> + * allocate the buffer as needed and return it, then free it later.
> + *
> + */
> +int do_drive_get_GTF(struct ata_port *ap, struct ata_device *atadev)
> +{
> + acpi_status status;
> + acpi_handle handle;
> + acpi_integer pcidevfn;
> + u32 dev_adr;
> + struct acpi_buffer output;
> + union acpi_object *out_obj;
> + struct device *dev = ap->host_set->dev;
> + int err = -ENODEV;
> +
> + if (!ata_dev_present(atadev)) /* or port disabled ? */
yes, you should check for port disabled too
> + goto out;
> +
> + /* Don't continue if device has no _ADR method.
> + * _GTF is intended for known motherboard devices. */
> + err = pci_acpi_get_dev_handle(dev, &handle, &pcidevfn);
> + if (err < 0)
> + goto out;
> +
> + /* Get this drive's _ADR info. if _SDD didn't get it. */
> + if (!atadev->obj_handle) {
> + dev_adr = SATA_ADR_RSVD;
> + err = get_sata_adr(dev, handle, pcidevfn, 0, ap, atadev, &dev_adr);
> + if (err < 0 || dev_adr == SATA_ADR_RSVD || !atadev->obj_handle)
> + goto out;
> + }
> +
> + /* Setting up output buffer */
> + output.length = ACPI_ALLOCATE_BUFFER;
> + output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
> +
> + /* _GTF has no input parameters */
> + err = -EIO;
> + status = acpi_evaluate_object(atadev->obj_handle, "_GTF",
> + NULL, &output);
> + if (ACPI_FAILURE(status)) {
> + printk(KERN_DEBUG
> + "%s: Run _GTF error: status = 0x%x\n",
> + __FUNCTION__, status);
> + goto out;
> + }
> +
> + if (!output.length || !output.pointer) {
> + printk(KERN_DEBUG
> + "%s: Run _GTF: length or ptr is NULL (0x%llx, 0x%p)\n",
> + __FUNCTION__,
> + (unsigned long long)output.length, output.pointer);
> + acpi_os_free(output.pointer);
> + goto out;
> + }
> +
> + out_obj = output.pointer;
> + if (out_obj->type != ACPI_TYPE_BUFFER) {
> + acpi_os_free(output.pointer);
> + printk(KERN_DEBUG "%s: Run _GTF: error: "
> + "expected object type of ACPI_TYPE_BUFFER, got 0x%x\n",
> + __FUNCTION__, out_obj->type);
> + err = -ENOENT;
> + goto out;
> + }
> +
> + atadev->gtf_length = out_obj->buffer.length;
> + atadev->gtf_address = out_obj->buffer.pointer;
> + err = 0;
> +out:
> + return err;
> +}
> +EXPORT_SYMBOL_GPL(do_drive_get_GTF);
> +
> +/**
> + * taskfile_load_raw - send taskfile registers to host controller
> + * @ap: Port to which output is sent
> + * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
> + *
> + * Outputs ATA taskfile to standard ATA host controller using MMIO
> + * or PIO as indicated by the ATA_FLAG_MMIO flag.
> + * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
> + * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
> + * hob_lbal, hob_lbam, and hob_lbah.
> + *
> + * This function waits for idle (!BUSY and !DRQ) after writing
> + * registers. If the control register has a new value, this
> + * function also waits for idle after writing control and before
> + * writing the remaining registers.
> + *
> + * LOCKING: TBD:
> + * Inherited from caller.
> + */
> +static void taskfile_load_raw(struct ata_port *ap,
> + struct ata_device *atadev,
> + const struct taskfile_array *gtf)
> +{
> + DEBPRINT("(0x1f1-1f7): hex: %02x %02x %02x %02x %02x %02x %02x\n",
> + gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
> + gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
> +
> + if (ap->ops->tf_load && ap->ops->exec_command) {
> + struct ata_taskfile atf;
> +
> + /* convert gtf to atf */
> + ata_tf_init(ap, &atf, 0);
> + atf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
> + atf.protocol = ATA_PROT_NODATA; /* or ATA_PROT_ATAPI_NODATA */
> + atf.feature = gtf->tfa[0]; /* 0x1f1 */
> + atf.nsect = gtf->tfa[1]; /* 0x1f2 */
> + atf.lbal = gtf->tfa[2]; /* 0x1f3 */
> + atf.lbam = gtf->tfa[3]; /* 0x1f4 */
> + atf.lbah = gtf->tfa[4]; /* 0x1f5 */
> + atf.device = gtf->tfa[5]; /* 0x1f6 */
> + atf.command = gtf->tfa[6]; /* 0x1f7 */
> +
> + DEBPRINT("call tf_load:\n");
> + ap->ops->tf_load(ap, &atf);
> + DEBPRINT("call exec_command:\n");
> + ap->ops->exec_command(ap, &atf);
> + DEBPRINT("tf_load & exec_command done.\n");
delete this entire code block
> + } else if (ap->ops->qc_issue && ap->ops->qc_prep) {
> + int ret;
> + struct ata_queued_cmd *qc;
> + unsigned long flags;
> + DECLARE_COMPLETION(wait);
> +
> + qc = ata_qc_new_init(ap, atadev);
> + if (!qc) {
> + printk(KERN_DEBUG "%s: ata_qc_new_init ret. NULL\n",
> + __FUNCTION__);
> + return;
> + }
> +
> + /* convert gtf to qc.tf */
> + qc->tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
> + qc->tf.protocol = ATA_PROT_NODATA; /* or ATA_PROT_ATAPI_NODATA */
> + qc->tf.feature = gtf->tfa[0]; /* 0x1f1 */
> + qc->tf.nsect = gtf->tfa[1]; /* 0x1f2 */
> + qc->tf.lbal = gtf->tfa[2]; /* 0x1f3 */
> + qc->tf.lbam = gtf->tfa[3]; /* 0x1f4 */
> + qc->tf.lbah = gtf->tfa[4]; /* 0x1f5 */
> + qc->tf.device = gtf->tfa[5]; /* 0x1f6 */
> + qc->tf.command = gtf->tfa[6]; /* 0x1f7 */
> +
> + qc->waiting = &wait;
> + qc->complete_fn = ata_qc_complete_noop;
> +
> + // TBD: fix locking and return value/wait_for_completion here:
> + DEBPRINT("call ata_qc_issue:\n");
> + spin_lock_irqsave(&ap->host_set->lock, flags);
> + ret = ata_qc_issue(qc);
> + spin_unlock_irqrestore(&ap->host_set->lock, flags);
> + DEBPRINT("ata_qc_issue done: ret = 0x%x\n", ret);
> +
> + if (!ret)
> + wait_for_completion(&wait);
always use this code block.
note that 'upstream' branch has Tejun's ata_exec_internal() changes,
which cause Jens' suspend patch as well as the above code to change.
> + } else
> + printk(KERN_WARNING "%s: SATA driver is missing tf_load/exec_command or qc_issue function entry points\n",
> + __FUNCTION__);
> +}
> +
> +/**
> + * do_drive_set_taskfiles - write the drive taskfile settings from _GTF
> + * @ap: the ata_port for the drive
> + * @atadev: target ata_device
> + *
> + * This applies to both PATA and SATA drives.
> + *
> + * Write {atadev->gtf_address, length atadev->gtf_length} in groups of
> + * REGS_PER_GTF bytes.
> + *
> + */
> +int do_drive_set_taskfiles(struct ata_port *ap, struct ata_device *atadev)
> +{
> + int err = -ENODEV;
> + int gtf_count =
> + atadev->gtf_length / REGS_PER_GTF;
> + int ix;
> + struct taskfile_array *gtf;
> +
> + if (!ata_dev_present(atadev)) /* or port disabled ? */
> + goto out;
> + if (!gtf_count) /* shouldn't be here */
> + goto out;
> +
> + DEBPRINT("total GTF bytes = %lld (0x%llx), gtf_count = %d\n",
> + (unsigned long long)atadev->gtf_length,
> + (unsigned long long)atadev->gtf_length, gtf_count);
> + if (atadev->gtf_length % REGS_PER_GTF) {
> + printk(KERN_ERR "%s: unexpected GTF length (%zd)\n",
> + __FUNCTION__, atadev->gtf_length);
> + goto out;
> + }
> +
> + for (ix = 0; ix < gtf_count; ix++) {
> + gtf = (struct taskfile_array *)
> + (atadev->gtf_address + ix * REGS_PER_GTF);
> +
> + /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
> + taskfile_load_raw(ap, atadev, gtf);
> + }
stop the loop on error
> + err = 0;
> +out:
> + return err;
> +}
> +EXPORT_SYMBOL_GPL(do_drive_set_taskfiles);
> +
> +/**
> + * do_drive_update_taskfiles - get then write drive taskfile settings
> + * @ap: the ata_port for the drive
> + *
> + * This applies to both PATA and SATA drives.
> + */
> +int do_drive_update_taskfiles(struct ata_port *ap)
> +{
> + int ix;
> + int ret;
> +
> + for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
> + ret = do_drive_get_GTF(ap, &ap->device[ix]);
> + if (ret >= 0)
> + ret = do_drive_set_taskfiles(ap, &ap->device[ix]);
what's the point of continuing to loop, but simply avoiding the call, on
error? why not just stop the loop?
> + }
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(do_drive_update_taskfiles);
>
>
>
> ---
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 7/7] SATA ACPI debug-only output
2005-12-14 0:10 ` [PATCH 7/7] SATA ACPI debug-only output Randy Dunlap
@ 2005-12-14 22:23 ` Jeff Garzik
2005-12-14 22:42 ` Randy Dunlap
0 siblings, 1 reply; 19+ messages in thread
From: Jeff Garzik @ 2005-12-14 22:23 UTC (permalink / raw)
To: Randy Dunlap; +Cc: ide, axboe
Randy Dunlap wrote:
> From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
>
> Add some extra debug-only output.
>
> Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
> ---
> drivers/scsi/ata_acpi.c | 17 ++++++++++++-----
> drivers/scsi/libata-core.c | 6 +++---
> 2 files changed, 15 insertions(+), 8 deletions(-)
>
> --- linux-2615-rc5g3.orig/drivers/scsi/ata_acpi.c
> +++ linux-2615-rc5g3/drivers/scsi/ata_acpi.c
> @@ -183,9 +183,10 @@ static int get_sata_adr(struct device *d
> winfo->drivenum = drive;
>
> status = acpi_get_devices(NULL, get_devices, winfo, NULL);
> - if (ACPI_FAILURE(status))
> + if (ACPI_FAILURE(status)) {
> + DEBPRINT("acpi_get_devices failed\n");
don't invent your own debugprint, use libata's
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 7/7] SATA ACPI debug-only output
2005-12-14 22:42 ` Randy Dunlap
@ 2005-12-14 22:42 ` Jeff Garzik
2005-12-14 23:08 ` Randy Dunlap
0 siblings, 1 reply; 19+ messages in thread
From: Jeff Garzik @ 2005-12-14 22:42 UTC (permalink / raw)
To: Randy Dunlap; +Cc: linux-ide, axboe, petkov
Randy Dunlap wrote:
> On Wed, 14 Dec 2005 17:23:58 -0500
> Jeff Garzik <jgarzik@pobox.com> wrote:
>
>
>>Randy Dunlap wrote:
>>
>>>From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
>>>
>>>Add some extra debug-only output.
>>>
>>>
>>> status = acpi_get_devices(NULL, get_devices, winfo, NULL);
>>>- if (ACPI_FAILURE(status))
>>>+ if (ACPI_FAILURE(status)) {
>>>+ DEBPRINT("acpi_get_devices failed\n");
>>
>>don't invent your own debugprint, use libata's
>
>
> DPRINTK() is too verbose for me. Would you accept something
> that just does debug printing for probe/discovery/enumeration and
> not on every I/O? then I could use the probe/discovery/enumeration
> level of debug printing.
Dig up the patches from Borislav Petkov on linux-ide that made debug
messages more fine-grained. Then we can specific things on and off at
runtime...
Jeff
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 7/7] SATA ACPI debug-only output
2005-12-14 22:23 ` Jeff Garzik
@ 2005-12-14 22:42 ` Randy Dunlap
2005-12-14 22:42 ` Jeff Garzik
0 siblings, 1 reply; 19+ messages in thread
From: Randy Dunlap @ 2005-12-14 22:42 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-ide, axboe
On Wed, 14 Dec 2005 17:23:58 -0500
Jeff Garzik <jgarzik@pobox.com> wrote:
> Randy Dunlap wrote:
> > From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
> >
> > Add some extra debug-only output.
> >
> >
> > status = acpi_get_devices(NULL, get_devices, winfo, NULL);
> > - if (ACPI_FAILURE(status))
> > + if (ACPI_FAILURE(status)) {
> > + DEBPRINT("acpi_get_devices failed\n");
>
> don't invent your own debugprint, use libata's
DPRINTK() is too verbose for me. Would you accept something
that just does debug printing for probe/discovery/enumeration and
not on every I/O? then I could use the probe/discovery/enumeration
level of debug printing.
---
~Randy
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/7] SATA ACPI linux/libata.h update
2005-12-14 22:08 ` Jeff Garzik
@ 2005-12-14 23:00 ` Randy Dunlap
0 siblings, 0 replies; 19+ messages in thread
From: Randy Dunlap @ 2005-12-14 23:00 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-ide, axboe
On Wed, 14 Dec 2005 17:08:33 -0500
Jeff Garzik <jgarzik@pobox.com> wrote:
> Randy Dunlap wrote:
> > From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
> >
> > Add ACPI data pointer/length holders.
> >
> > Signed-off-by: Randy Dunlap <randy_d_dunlap@linux.intel.com>
>
> Why does struct ata_device need to remember this info at all?
Uh... I dunno. I'll see if I can just read that data
during resume.
---
~Randy
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 7/7] SATA ACPI debug-only output
2005-12-14 22:42 ` Jeff Garzik
@ 2005-12-14 23:08 ` Randy Dunlap
0 siblings, 0 replies; 19+ messages in thread
From: Randy Dunlap @ 2005-12-14 23:08 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-ide, axboe, petkov
On Wed, 14 Dec 2005 17:42:00 -0500
Jeff Garzik <jgarzik@pobox.com> wrote:
> Randy Dunlap wrote:
> > On Wed, 14 Dec 2005 17:23:58 -0500
> > Jeff Garzik <jgarzik@pobox.com> wrote:
> >
> >
> >>Randy Dunlap wrote:
> >>
> >>>From: Randy Dunlap <randy_d_dunlap@linux.intel.com>
> >>>
> >>>Add some extra debug-only output.
> >>>
> >>>
> >>> status = acpi_get_devices(NULL, get_devices, winfo, NULL);
> >>>- if (ACPI_FAILURE(status))
> >>>+ if (ACPI_FAILURE(status)) {
> >>>+ DEBPRINT("acpi_get_devices failed\n");
> >>
> >>don't invent your own debugprint, use libata's
> >
> >
> > DPRINTK() is too verbose for me. Would you accept something
> > that just does debug printing for probe/discovery/enumeration and
> > not on every I/O? then I could use the probe/discovery/enumeration
> > level of debug printing.
>
> Dig up the patches from Borislav Petkov on linux-ide that made debug
> messages more fine-grained. Then we can specific things on and off at
> runtime...
OK, I found 1/2 in the archive but not 2/2.
Borislav, did you send 2/2? Can you resend it, please?
---
~Randy
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2005-12-14 23:04 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <20051213160110.193e3f61.randy_d_dunlap@linux.intel.com>
2005-12-14 0:02 ` [PATCH 1/7] SATA suspend/resume support (Jens) Randy Dunlap
2005-12-14 22:07 ` Jeff Garzik
2005-12-14 22:22 ` Randy Dunlap
2005-12-14 0:04 ` [PATCH 2/7] SATA ACPI make/config Randy Dunlap
2005-12-14 22:07 ` Jeff Garzik
2005-12-14 0:05 ` [PATCH 3/7] SATA ACPI linux/libata.h update Randy Dunlap
2005-12-14 22:08 ` Jeff Garzik
2005-12-14 23:00 ` Randy Dunlap
2005-12-14 0:06 ` [PATCH 4/7] call/invoke SATA ACPI suspend/resume functions Randy Dunlap
2005-12-14 22:11 ` Jeff Garzik
2005-12-14 0:07 ` [PATCH 5/7] SATA ACPI kernel-doc Randy Dunlap
2005-12-14 22:12 ` Jeff Garzik
2005-12-14 0:09 ` [PATCH 6/7] SATA ACPI suspend/resume functions Randy Dunlap
2005-12-14 22:23 ` Jeff Garzik
2005-12-14 0:10 ` [PATCH 7/7] SATA ACPI debug-only output Randy Dunlap
2005-12-14 22:23 ` Jeff Garzik
2005-12-14 22:42 ` Randy Dunlap
2005-12-14 22:42 ` Jeff Garzik
2005-12-14 23:08 ` Randy Dunlap
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.