SATA ACPI: call new ACPI functions
Subsystems (3)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/6 libata_suspend (Jens)
From: Jens Axboe <[email protected]>
SATA suspend/resume patch.
--- 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(-)
drivers/scsi/ata_piix.c +4 -0
@@ -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 = {
drivers/scsi/libata-core.c +122 -0
138 lines not on this page · raw message
drivers/scsi/libata-scsi.c +16 -0
@@ -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
drivers/scsi/scsi_sysfs.c +33 -2
@@ -263,9 +263,40 @@ static int scsi_bus_match(struct devicereturn (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 )
include/linux/ata.h +2 -0
@@ -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 */
include/linux/libata.h +7 -0
@@ -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_iopextern 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 scsiextern 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 );/*
include/scsi/scsi_host.h +6 -0
@@ -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;
---
PATCH 2/6 SATA ACPI: make/config changes
In reply to a message not in the archiveFrom: Randy Dunlap <[email protected]>
Add ata_acpi in Makefile and Kconfig.
--- drivers/scsi/Kconfig | 5 +++++ drivers/scsi/Makefile | 1 + 2 files changed, 6 insertions(+)
drivers/scsi/Makefile +1 -0
@@ -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/
drivers/scsi/Kconfig +5 -0
@@ -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
---
PATCH 3/6 SATA ACPI: libata.h changes
In reply to a message not in the archiveFrom: Randy Dunlap <[email protected]>
Add ACPI data pointer/length holders.
--- include/linux/libata.h | 6 ++++++ 1 files changed, 6 insertions(+)
include/linux/libata.h +6 -0
@@ -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,11 @@ struct ata_device {u16 cylinders;/* Number of cylinders */ u16 heads;/* Number of heads */ u16 sectors;/* Number of sectors per track */ + +/* ACPI objects info */ +acpi_handle obj_handle; +acpi_size gtf_length; +u8 *gtf_address; };struct ata_port {
---
PATCH 4/6 SATA ACPI: call new ACPI functions
In reply to a message not in the archiveFrom: Randy Dunlap <[email protected]>
Add calls to ACPI methods for SATA drives.
--- drivers/scsi/libata-core.c | 4 ++++ drivers/scsi/libata.h | 7 +++++++ 2 files changed, 11 insertions(+)
drivers/scsi/libata-core.c +4 -0
@@ -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_portif (ap->flags &ATA_FLAG_PORT_DISABLED )return ; +do_drive_update_taskfiles (ap); +if (ap->ops->post_set_mode) ap->ops->post_set_mode (ap);
drivers/scsi/libata.h +7 -0
@@ -53,6 +53,13 @@ extern int ata_task_ioctl(struct scsi_deextern int ata_cmd_ioctl (struct scsi_device *scsidev,void __user *arg); +/* ata_acpi.c */ +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); + +/* libata-scsi.c */ extern void ata_scsi_scan_host (struct ata_port *ap);extern int ata_scsi_error (struct Scsi_Host *host);
---
PATCH 5/6 SATA ACPI: kernel-doc
In reply to a message not in the archiveFrom: Randy Dunlap <[email protected]>
Add ata_acpi.c to libata kernel-doc template file.
--- Documentation/DocBook/libata.tmpl | 6 ++++++ 1 files changed, 6 insertions(+)
Documentation/DocBook/libata.tmpl +6 -0
@@ -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>
---
Re: [PATCH 0/6] SATA use ACPI methods for PM
In reply to a message not in the archivemore comments:
Yes, the patch still contains some debugging code. If you try it out and have problems, please give me as much of the debug output as possible. It is likely that I will also want to see your ACPI tables. To dump those, use 'acpidump' from the latest pmtools release at:
http://www.kernel.org/pub/linux/kernel/people/lenb/acpi/utils/
The patch series is available at:
http://www.xenotime.net/linux/SATA/2.6.15-rc/
---
~Randy
PATCH 6/6 SATA ACPI: ata_acpi functions
In reply to a message not in the archiveFrom: Randy Dunlap <[email protected]>
Add support for ACPI methods to SATA suspend/resume.
--- drivers/scsi/ata_acpi.c | 488 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 488 insertions(+)
drivers/scsi/ata_acpi.c new file +488 -0
@@ -0,0 +1,488 @@ +/* +* 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_LOCAL_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_MEM_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 ==NULL ) + 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; +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; + +/* 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)) { +ACPI_MEM_FREE (output.pointer); +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_MEM_FREE (output.pointer); + goto out; + } + + out_obj = output.pointer; +if (out_obj->type !=ACPI_TYPE_BUFFER ) { +ACPI_MEM_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);
---
PATCH 6/6 SATA ACPI: ata_acpi functions
From: Randy Dunlap <[email protected]>
Add support for ACPI methods to SATA suspend/resume. do_drive_get_GTF() is changed to get the ACPI obj_handle in case do_drive_SDD() did not set that value.
---
All patch files are available at
http://www.xenotime.net/linux/SATA/2.6.15-rc/
drivers/scsi/ata_acpi.c | 497 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 497 insertions(+)
drivers/scsi/ata_acpi.c new file +497 -0
@@ -0,0 +1,497 @@ +/* +* 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_LOCAL_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_MEM_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)) { +ACPI_MEM_FREE (output.pointer); +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_MEM_FREE (output.pointer); + goto out; + } + + out_obj = output.pointer; +if (out_obj->type !=ACPI_TYPE_BUFFER ) { +ACPI_MEM_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);
---
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
I get a segfault when applying these patches to 2.6.15-rc4. ahci compiled as module and inserted through initrd so the module fails with segfault and kernel doesnt go any further through boot, hence no logging. last thing screen shows is:
Code: e3 36 34 c0 c7 44 24 18 29 02 00 00 59 5b 5e 5f 5d e9 f3 05 00 00 53 8b 5c
2408 e8 e9 03 00 00 a1 dc 0c 42 c0 eb 04 39 d8 74 07 <8b> 40 04 85 c0 75 f5 5b c3 55 57 56 53 50 8b 44 24 20 8b 5c 24
also, is there a working archive for this list? the MARC archive died on 25th november.
Quoting Randy Dunlap <[email protected]>:
Quoted 522 lines
From: Randy Dunlap <[email protected]>
Add support for ACPI methods to SATA suspend/resume.
do_drive_get_GTF()is changed to get the ACPIobj_handlein casedo_drive_SDD()did not set that value.Signed-off-by Randy Dunlap <[email protected]>---
All patch files are available at
http://www.xenotime.net/linux/SATA/2.6.15-rc/drivers/scsi/ata_acpi.c | 497 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 497 insertions(+)drivers/scsi/ata_acpi.c new file +427
-0@@ -0,0 +1,497 @@ +/* + * 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_LOCAL_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_MEM_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)) { + ACPI_MEM_FREE(output.pointer); + 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_MEM_FREE(output.pointer); + goto out; + } + + out_obj = output.pointer; + if (out_obj->type != ACPI_TYPE_BUFFER) { + ACPI_MEM_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_issuefunction entry points\n",drivers/scsi/ata_acpi.c new file +70
-2+ __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); --- -
Quoted 3 lines
To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
------------------------------------------
This message was penned by the hand of Domw
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
Quoted 7 lines · On Wed, 07 Dec 2005 16:36:47 +0000 Dominic Ijichi <[email protected]> wrote:
I get a segfault when applying these patches to 2.6.15-rc4. ahci compiled as module and inserted through initrd so the module fails with segfault and kernel doesnt go any further through boot, hence no logging. last thing screen shows is:
Code: e3 36 34 c0 c7 44 24 18 29 02 00 00 59 5b 5e 5f 5d e9 f3 05 00 00 53 8b 5c2408 e8 e9 03 00 00 a1 dc 0c 42 c0 eb 04 39 d8 74 07 <8b> 40 04 85 c0 75 f5 5b c3 55 57 56 53 50 8b 44 24 20 8b 5c 24
Can you provide any more of the segfault messages? That one isn't particularly helpful.
Is this on your Fujitsu notebook, with the same hardware configuration as last week?
Quoted 2 lines
also, is there a working archive for this list? the MARC archive died on 25th november.
I contacted them. It appears that their subscription to linux-ide was dropped, so they resubscribed. However, they are missing linux-ide archives from Nov. 25 - Dec. 7, so if anyone has those, they would like to get them and stuff those into the archives. If you have linux-ide archives from that period, please let me know or (even better) send them to hlein at progressive-comp.com .
Thanks,
---
~Randy
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
Quoting Randy Dunlap <[email protected]>:
Quoted 10 lines
Quoted 1 line · On Wed, 07 Dec 2005 16:36:47 +0000 Dominic Ijichi <[email protected]> wrote:
I get a segfault when applying these patches to 2.6.15-rc4. ahci compiled
as
Quoted 1 line
module and inserted through initrd so the module fails with segfault and
kernel
Quoted 1 line
doesnt go any further through boot, hence no logging. last thing screen
shows is:
Quoted 1 line
Quoted 8 lines
Quoted 1 line
Code: e3 36 34 c0 c7 44 24 18 29 02 00 00 59 5b 5e 5f 5d e9 f3 05 00 00 538b 5c
Quoted 1 line
2408 e8 e9 03 00 00 a1 dc 0c 42 c0 eb 04 39 d8 74 07 <8b> 40 04 85 c0 75 f5
5b
Quoted 1 line
c3 55 57 56 53 50 8b 44 24 20 8b 5c 24
Can you provide any more of the segfault messages? That one isn't particularly helpful.
ok, see below. this is typed in on another computer, i'll try to minimise typos!
Quoted 2 lines
Is this on your Fujitsu notebook, with the same hardware configuration as last week?
yup
--
[<c02516c9>] ata_device_add+0x1e9/0x2b0 [<e082d850>] ahci_interrupt+0x0/0x1e0 [achi] [<e082e263>] ahci_init_one+0x1a3/0x270 [achi] [<c01cb5d6>] __pci_device_probe+0x56/0x70 [<c01cb61f>] pci_device_probe+0x2f/0x50 [<c023b313>] driver_probe_device+0x43/0xd0 [<c023b420>] __driver_attach+0x0/0x50 [<c023b461>] __driver_attach+0x41/0x50 [<c023a84d>] bus_for_each_dev+0x5d/0x80 [<c023b495>] driver_attach+0x25/0x30 [<c023b420>] __driver_attach+0x0/0x50 [<c023ada9>] bus_add_driver+0x89/0xf0 [<c01cb8a4>] __pci_register_driver+0x74/0xa0 [<e0832018>] ahci_init+0x18/0x1c [achi] [c01364c2>] sys_init_module+0xd/0x210 [<c0103291>] syscall_call+0x7/0xb
then the Code: line
thats all that's left on the screen unfortunately, the rest scrolls off the top.
cheers
dom
Quoted 11 lines
Quoted 1 line
also, is there a working archive for this list? the MARC archive died on
25th
Quoted 1 line
november.
I contacted them. It appears that their subscription to linux-ide was dropped, so they resubscribed. However, they are missing linux-ide archives from Nov. 25 - Dec. 7, so if anyone has those, they would like to get them and stuff those into the archives. If you have linux-ide archives from that period, please let me know or (even better) send them to hlein at progressive-comp.com .
Quoted 3 lines
Thanks,
---
~Randy
------------------------------------------
This message was penned by the hand of Dom
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
Quoted 14 lines · On Wed, 07 Dec 2005 17:24:30 +0000 Dominic Ijichi <[email protected]> wrote:
Quoting Randy Dunlap <[email protected]>:
Quoted 12 lines
Quoted 1 line · On Wed, 07 Dec 2005 16:36:47 +0000 Dominic Ijichi <[email protected]> wrote:
I get a segfault when applying these patches to 2.6.15-rc4. ahci compiled
as
Quoted 1 line
module and inserted through initrd so the module fails with segfault and
kernel
Quoted 1 line
doesnt go any further through boot, hence no logging. last thing screen
shows is:
Quoted 2 lines
Code: e3 36 34 c0 c7 44 24 18 29 02 00 00 59 5b 5e 5f 5d e9 f3 05 00 00 538b 5c
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
2408 e8 e9 03 00 00 a1 dc 0c 42 c0 eb 04 39 d8 74 07 <8b> 40 04 85 c0 75 f5
5b
Quoted 1 line
c3 55 57 56 53 50 8b 44 24 20 8b 5c 24
Can you provide any more of the segfault messages? That one isn't particularly helpful.
ok, see below. this is typed in on another computer, i'll try to minimise typos!
OK, well, that's a little better, but the top of the backtrace is where the nitty gritty info is.
Is it possible for you to use any other method of capturing more fault messages, like serial console, netconsole, or even higher resolution video (and smaller font) so that I can see where the fault is actually happening?
Thanks.
Quoted 24 lines
Quoted 2 lines
Is this on your Fujitsu notebook, with the same hardware configuration as last week?
yup
--
[<c02516c9>] ata_device_add+0x1e9/0x2b0 [<e082d850>] ahci_interrupt+0x0/0x1e0 [achi] [<e082e263>] ahci_init_one+0x1a3/0x270 [achi] [<c01cb5d6>] __pci_device_probe+0x56/0x70 [<c01cb61f>] pci_device_probe+0x2f/0x50 [<c023b313>] driver_probe_device+0x43/0xd0 [<c023b420>] __driver_attach+0x0/0x50 [<c023b461>] __driver_attach+0x41/0x50 [<c023a84d>] bus_for_each_dev+0x5d/0x80 [<c023b495>] driver_attach+0x25/0x30 [<c023b420>] __driver_attach+0x0/0x50 [<c023ada9>] bus_add_driver+0x89/0xf0 [<c01cb8a4>] __pci_register_driver+0x74/0xa0 [<e0832018>] ahci_init+0x18/0x1c [achi] [c01364c2>] sys_init_module+0xd/0x210 [<c0103291>] syscall_call+0x7/0xb
Quoted 3 lines
then the Code: line
thats all that's left on the screen unfortunately, the rest scrolls off the top.
---
~Randy
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
Quoting Randy Dunlap <[email protected]>:
Quoted 32 lines
Quoted 6 lines · On Wed, 07 Dec 2005 17:24:30 +0000 Dominic Ijichi <[email protected]> wrote:
Quoting Randy Dunlap <[email protected]>:
Quoted 4 lines
Quoted 1 line · On Wed, 07 Dec 2005 16:36:47 +0000 Dominic Ijichi <[email protected]> wrote:
I get a segfault when applying these patches to 2.6.15-rc4. ahci
compiled
Quoted 2 lines
Quoted 2 lines
as
Quoted 1 line
module and inserted through initrd so the module fails with segfault
and
Quoted 2 lines
Quoted 2 lines
kernel
Quoted 1 line
doesnt go any further through boot, hence no logging. last thing
screen
Quoted 3 lines
Quoted 3 lines
shows is:
Quoted 2 lines
Code: e3 36 34 c0 c7 44 24 18 29 02 00 00 59 5b 5e 5f 5d e9 f3 05 00 0053
Quoted 2 lines
Quoted 2 lines
8b 5c
Quoted 1 line
2408 e8 e9 03 00 00 a1 dc 0c 42 c0 eb 04 39 d8 74 07 <8b> 40 04 85 c0
75 f5
Quoted 7 lines
Quoted 5 lines
5b
Quoted 1 line
c3 55 57 56 53 50 8b 44 24 20 8b 5c 24
Can you provide any more of the segfault messages? That one isn't particularly helpful.
ok, see below. this is typed in on another computer, i'll try to minimise
typos!
Quoted 8 lines
OK, well, that's a little better, but the top of the backtrace is where the nitty gritty info is.
Is it possible for you to use any other method of capturing more fault messages, like serial console, netconsole, or even higher resolution video (and smaller font) so that I can see where the fault is actually happening?Thanks.
ok. eye-watering font, but here's what it says:
ata1: dev 0 configured for UDMA/100
Unable to handle kernel paging request at virtual address eaeaeaee printing eip: c0218c67 *pde = 00000000 Oops: 0000 [#1] PREEMPT Modules linked in: ahci piix ide_disk ide_core CPU: 0
EIP: 0060:[<c0218c67>] Not tainted VLI
EFLAGS: 00010202 (2.6.15-rc4)
EIP is at acpi_ut_find_allocation+0x15/0x1e
eax: eaeaeaea ebx: df0d8c00 ec: 00000000 edx: 00000007
esi: c0388b0d edi: 00000000 ebp: dffd0e40 esp: c17e9bdc
ds: 007b es: 007b ss: 0068
Process modprobe (pid: 1353, threadinfo=c17e8000 task=deeb3070)
Stack: df0d8c00 c0218cd8 df0d8c00 0000001 df0d8c00 000001ef 00000010 c0388b0d c0218b04 df0d8c00 00000008 00000001 00000010 c0388b0d 000001ef c03890d5 c17e9c40 c17e9c74 c03890d5 c020ea16 00000008 00000010 c0388b0d 000001ef Call Trace: [<c0218cd8>] acpi_ut_track_allocation+0x68/0x127 [<c0218b04>] acpi_ut_callocate_and_track+0x55/0x83 [<c020ea16>] acpi_ns_internalize_name+0x82/0x113 [<c020dcf6>] acpi_ns_evaluate_relatvie+0x66/0x1ca [<c02195de>] acpi_ut_evaluate_object+0x46/0x22a [<c0219ba3>] acpi_ut_execute_STA+0x35/0xc4 [<c020d468>] acpi_ns_get_device_callback+0x4e/0x151 [<c02104ec>] acpi_ns_walk_namespace+0xbb/0x1b7 [<c020d604>] acpi_get_devices+0x99/0xc4 [<c020d41a>] acpi_ns_get_device_callback+0x0/0x151 [<c0277280>] get_devices+0x0/0x220 [<c0277539>] get_sata_adr+0x99/0x110 [<c0277280>] get_devices+0x0/0x220 [<c02778e6>] do_drive_get_GTF+0x136/0x200 [<c0277d8f>] do_drive_update_taskfiles+0x2f/0x70 [<c0270578>] ata_set_mode+0x98/0xb0 [<c026fc0b>] ata_bus_probe+0xab/0xc0 > > [<c02516c9>] ata_device_add+0x1e9/0x2b0 > > [<e082d850>] ahci_interrupt+0x0/0x1e0 [achi] > > [<e082e263>] ahci_init_one+0x1a3/0x270 [achi] > > [<c01cb5d6>] __pci_device_probe+0x56/0x70 > > [<c01cb61f>] pci_device_probe+0x2f/0x50 > > [<c023b313>] driver_probe_device+0x43/0xd0 > > [<c023b420>] __driver_attach+0x0/0x50 > > [<c023b461>] __driver_attach+0x41/0x50 > > [<c023a84d>] bus_for_each_dev+0x5d/0x80 > > [<c023b495>] driver_attach+0x25/0x30 > > [<c023b420>] __driver_attach+0x0/0x50 > > [<c023ada9>] bus_add_driver+0x89/0xf0 > > [<c01cb8a4>] __pci_register_driver+0x74/0xa0 > > [<e0832018>] ahci_init+0x18/0x1c [achi] > > [c01364c2>] sys_init_module+0xd/0x210 > > [<c0103291>] syscall_call+0x7/0xb
Quoted 25 lines
Quoted 25 lines
Quoted 3 lines
Is this on your Fujitsu notebook, with the same hardware configuration as last week?
yup
--
[<c02516c9>] ata_device_add+0x1e9/0x2b0 [<e082d850>] ahci_interrupt+0x0/0x1e0 [achi] [<e082e263>] ahci_init_one+0x1a3/0x270 [achi] [<c01cb5d6>] __pci_device_probe+0x56/0x70 [<c01cb61f>] pci_device_probe+0x2f/0x50 [<c023b313>] driver_probe_device+0x43/0xd0 [<c023b420>] __driver_attach+0x0/0x50 [<c023b461>] __driver_attach+0x41/0x50 [<c023a84d>] bus_for_each_dev+0x5d/0x80 [<c023b495>] driver_attach+0x25/0x30 [<c023b420>] __driver_attach+0x0/0x50 [<c023ada9>] bus_add_driver+0x89/0xf0 [<c01cb8a4>] __pci_register_driver+0x74/0xa0 [<e0832018>] ahci_init+0x18/0x1c [achi] [c01364c2>] sys_init_module+0xd/0x210 [<c0103291>] syscall_call+0x7/0xb
Quoted 7 lines
Quoted 3 lines
then the Code: line
thats all that's left on the screen unfortunately, the rest scrolls off the
top.
---
~Randy
------------------------------------------
This message was penned by the hand of Dom
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
Quoted 41 lines · On Thu, 08 Dec 2005 09:43:30 +0000 Dominic Ijichi <[email protected]> wrote:
Quoting Randy Dunlap <[email protected]>:
Quoted 39 lines
Quoted 6 lines · On Wed, 07 Dec 2005 17:24:30 +0000 Dominic Ijichi <[email protected]> wrote:
Quoting Randy Dunlap <[email protected]>:
Quoted 4 lines
Quoted 1 line · On Wed, 07 Dec 2005 16:36:47 +0000 Dominic Ijichi <[email protected]> wrote:
I get a segfault when applying these patches to 2.6.15-rc4. ahci
compiled
Quoted 2 lines
Quoted 2 lines
as
Quoted 1 line
module and inserted through initrd so the module fails with segfault
and
Quoted 2 lines
Quoted 2 lines
kernel
Quoted 1 line
doesnt go any further through boot, hence no logging. last thing
screen
Quoted 3 lines
Quoted 3 lines
shows is:
Quoted 2 lines
Code: e3 36 34 c0 c7 44 24 18 29 02 00 00 59 5b 5e 5f 5d e9 f3 05 00 0053
Quoted 2 lines
Quoted 2 lines
8b 5c
Quoted 1 line
2408 e8 e9 03 00 00 a1 dc 0c 42 c0 eb 04 39 d8 74 07 <8b> 40 04 85 c0
75 f5
Quoted 7 lines
Quoted 5 lines
5b
Quoted 1 line
c3 55 57 56 53 50 8b 44 24 20 8b 5c 24
Can you provide any more of the segfault messages? That one isn't particularly helpful.
ok, see below. this is typed in on another computer, i'll try to minimise
typos!
OK, well, that's a little better, but the top of the backtrace is where the nitty gritty info is.
Is it possible for you to use any other method of capturing more fault messages, like serial console, netconsole, or even higher resolution video (and smaller font) so that I can see where the fault is actually happening?
Quoted 3 lines
Quoted 1 line
Thanks.
ok. eye-watering font, but here's what it says:
Thanks for doing that.
Did you enable ACPI debug output? If so, how? (in .config or by modifying a header file? if by modifying a header file, please tell us exactly.)
Quoted 45 lines
ata1: dev 0 configured for UDMA/100
Unable to handle kernel paging request at virtual address eaeaeaee printing eip: c0218c67 *pde = 00000000 Oops: 0000 [#1] PREEMPT Modules linked in: ahci piix ide_disk ide_core CPU: 0EIP: 0060:[<c0218c67>] Not tainted VLI
EFLAGS: 00010202 (2.6.15-rc4)
EIP is atacpi_ut_find_allocation+0x15/0x1e
eax: eaeaeaea ebx:df0d8c00ec: 00000000 edx: 00000007
esi:c0388b0dedi: 00000000 ebp:dffd0e40esp:c17e9bdc
ds: 007b es: 007b ss: 0068
Process modprobe (pid: 1353, threadinfo=c17e8000 task=deeb3070)Stack: df0d8c00 c0218cd8 df0d8c00 0000001 df0d8c00 000001ef 00000010 c0388b0d c0218b04 df0d8c00 00000008 00000001 00000010 c0388b0d 000001ef c03890d5 c17e9c40 c17e9c74 c03890d5 c020ea16 00000008 00000010 c0388b0d 000001ef Call Trace: [<c0218cd8>] acpi_ut_track_allocation+0x68/0x127 [<c0218b04>] acpi_ut_callocate_and_track+0x55/0x83 [<c020ea16>] acpi_ns_internalize_name+0x82/0x113 [<c020dcf6>] acpi_ns_evaluate_relatvie+0x66/0x1ca [<c02195de>] acpi_ut_evaluate_object+0x46/0x22a [<c0219ba3>] acpi_ut_execute_STA+0x35/0xc4 [<c020d468>] acpi_ns_get_device_callback+0x4e/0x151 [<c02104ec>] acpi_ns_walk_namespace+0xbb/0x1b7 [<c020d604>] acpi_get_devices+0x99/0xc4 [<c020d41a>] acpi_ns_get_device_callback+0x0/0x151 [<c0277280>] get_devices+0x0/0x220 [<c0277539>] get_sata_adr+0x99/0x110 [<c0277280>] get_devices+0x0/0x220 [<c02778e6>] do_drive_get_GTF+0x136/0x200 [<c0277d8f>] do_drive_update_taskfiles+0x2f/0x70 [<c0270578>] ata_set_mode+0x98/0xb0 [<c026fc0b>] ata_bus_probe+0xab/0xc0 > > [<c02516c9>] ata_device_add+0x1e9/0x2b0 > > [<e082d850>] ahci_interrupt+0x0/0x1e0 [achi] > > [<e082e263>] ahci_init_one+0x1a3/0x270 [achi] > > [<c01cb5d6>] __pci_device_probe+0x56/0x70 > > [<c01cb61f>] pci_device_probe+0x2f/0x50 > > [<c023b313>] driver_probe_device+0x43/0xd0 > > [<c023b420>] __driver_attach+0x0/0x50 > > [<c023b461>] __driver_attach+0x41/0x50
Quoted 41 lines
> > [<c023a84d>] bus_for_each_dev+0x5d/0x80 > > [<c023b495>] driver_attach+0x25/0x30 > > [<c023b420>] __driver_attach+0x0/0x50 > > [<c023ada9>] bus_add_driver+0x89/0xf0 > > [<c01cb8a4>] __pci_register_driver+0x74/0xa0 > > [<e0832018>] ahci_init+0x18/0x1c [achi] > > [c01364c2>] sys_init_module+0xd/0x210 > > [<c0103291>] syscall_call+0x7/0xbQuoted 31 lines
Quoted 25 lines
Quoted 3 lines
Is this on your Fujitsu notebook, with the same hardware configuration as last week?
yup
--
[<c02516c9>] ata_device_add+0x1e9/0x2b0 [<e082d850>] ahci_interrupt+0x0/0x1e0 [achi] [<e082e263>] ahci_init_one+0x1a3/0x270 [achi] [<c01cb5d6>] __pci_device_probe+0x56/0x70 [<c01cb61f>] pci_device_probe+0x2f/0x50 [<c023b313>] driver_probe_device+0x43/0xd0 [<c023b420>] __driver_attach+0x0/0x50 [<c023b461>] __driver_attach+0x41/0x50 [<c023a84d>] bus_for_each_dev+0x5d/0x80 [<c023b495>] driver_attach+0x25/0x30 [<c023b420>] __driver_attach+0x0/0x50 [<c023ada9>] bus_add_driver+0x89/0xf0 [<c01cb8a4>] __pci_register_driver+0x74/0xa0 [<e0832018>] ahci_init+0x18/0x1c [achi] [c01364c2>] sys_init_module+0xd/0x210 [<c0103291>] syscall_call+0x7/0xbQuoted 3 lines
then the Code: line
thats all that's left on the screen unfortunately, the rest scrolls off the
top.
---
---
~Randy
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
Quoting Randy Dunlap <[email protected]>:
Quoted 50 lines
Quoted 14 lines · On Thu, 08 Dec 2005 09:43:30 +0000 Dominic Ijichi <[email protected]> wrote:
Quoting Randy Dunlap <[email protected]>:
Quoted 12 lines
Quoted 6 lines · On Wed, 07 Dec 2005 17:24:30 +0000 Dominic Ijichi <[email protected]> wrote:
Quoting Randy Dunlap <[email protected]>:
Quoted 4 lines
Quoted 1 line · On Wed, 07 Dec 2005 16:36:47 +0000 Dominic Ijichi <[email protected]> wrote:
I get a segfault when applying these patches to 2.6.15-rc4. ahci
compiled
Quoted 2 lines
Quoted 2 lines
as
Quoted 1 line
module and inserted through initrd so the module fails with
segfault
Quoted 7 lines
Quoted 7 lines
and
Quoted 2 lines
Quoted 2 lines
kernel
Quoted 1 line
doesnt go any further through boot, hence no logging. last thing
screen
Quoted 3 lines
Quoted 3 lines
shows is:
Quoted 2 lines
Code: e3 36 34 c0 c7 44 24 18 29 02 00 00 59 5b 5e 5f 5d e9 f3 0500 00
Quoted 3 lines
Quoted 3 lines
53
Quoted 2 lines
Quoted 2 lines
8b 5c
Quoted 1 line
2408 e8 e9 03 00 00 a1 dc 0c 42 c0 eb 04 39 d8 74 07 <8b> 40 04 85
c0
Quoted 8 lines
Quoted 8 lines
75 f5
Quoted 7 lines
Quoted 5 lines
5b
Quoted 1 line
c3 55 57 56 53 50 8b 44 24 20 8b 5c 24
Can you provide any more of the segfault messages? That one isn't particularly helpful.
ok, see below. this is typed in on another computer, i'll try to
minimise
Quoted 11 lines
Quoted 10 lines
typos!
OK, well, that's a little better, but the top of the backtrace is where the nitty gritty info is.
Is it possible for you to use any other method of capturing more fault messages, like serial console, netconsole, or even higher resolution video (and smaller font) so that I can see where the fault is actually happening?Thanks.
Quoted 7 lines
Quoted 1 line
ok. eye-watering font, but here's what it says:
Thanks for doing that.
Did you enable ACPI debug output? If so, how? (in .config or by modifying a header file? if by modifying a header file, please tell us exactly.)
ACPI_DEBUG in .config and also applied your debug patch
Quoted 84 lines
Quoted 10 lines
ata1: dev 0 configured for UDMA/100
Unable to handle kernel paging request at virtual address eaeaeaee printing eip: c0218c67 *pde = 00000000 Oops: 0000 [#1] PREEMPT Modules linked in: ahci piix ide_disk ide_core CPU: 0Quoted 8 lines
EIP: 0060:[<c0218c67>] Not tainted VLI
EFLAGS: 00010202 (2.6.15-rc4)
EIP is atacpi_ut_find_allocation+0x15/0x1e
eax: eaeaeaea ebx:df0d8c00ec: 00000000 edx: 00000007
esi:c0388b0dedi: 00000000 ebp:dffd0e40esp:c17e9bdc
ds: 007b es: 007b ss: 0068
Process modprobe (pid: 1353, threadinfo=c17e8000 task=deeb3070)Stack: df0d8c00 c0218cd8 df0d8c00 0000001 df0d8c00 000001ef 00000010
c0388b0dQuoted 65 lines
c0218b04df0d8c0000000008 00000001 00000010c0388b0d000001efc03890d5c17e9c40c17e9c74c03890d5c020ea1600000008 00000010c0388b0d000001efCall Trace: [<c0218cd8>] acpi_ut_track_allocation+0x68/0x127 [<c0218b04>] acpi_ut_callocate_and_track+0x55/0x83 [<c020ea16>] acpi_ns_internalize_name+0x82/0x113 [<c020dcf6>] acpi_ns_evaluate_relatvie+0x66/0x1ca [<c02195de>] acpi_ut_evaluate_object+0x46/0x22a [<c0219ba3>] acpi_ut_execute_STA+0x35/0xc4 [<c020d468>] acpi_ns_get_device_callback+0x4e/0x151 [<c02104ec>] acpi_ns_walk_namespace+0xbb/0x1b7 [<c020d604>] acpi_get_devices+0x99/0xc4 [<c020d41a>] acpi_ns_get_device_callback+0x0/0x151 [<c0277280>] get_devices+0x0/0x220 [<c0277539>] get_sata_adr+0x99/0x110 [<c0277280>] get_devices+0x0/0x220 [<c02778e6>] do_drive_get_GTF+0x136/0x200 [<c0277d8f>] do_drive_update_taskfiles+0x2f/0x70 [<c0270578>] ata_set_mode+0x98/0xb0 [<c026fc0b>] ata_bus_probe+0xab/0xc0 > > [<c02516c9>] ata_device_add+0x1e9/0x2b0 > > [<e082d850>] ahci_interrupt+0x0/0x1e0 [achi] > > [<e082e263>] ahci_init_one+0x1a3/0x270 [achi] > > [<c01cb5d6>] __pci_device_probe+0x56/0x70 > > [<c01cb61f>] pci_device_probe+0x2f/0x50 > > [<c023b313>] driver_probe_device+0x43/0xd0 > > [<c023b420>] __driver_attach+0x0/0x50 > > [<c023b461>] __driver_attach+0x41/0x50 > > [<c023a84d>] bus_for_each_dev+0x5d/0x80 > > [<c023b495>] driver_attach+0x25/0x30 > > [<c023b420>] __driver_attach+0x0/0x50 > > [<c023ada9>] bus_add_driver+0x89/0xf0 > > [<c01cb8a4>] __pci_register_driver+0x74/0xa0 > > [<e0832018>] ahci_init+0x18/0x1c [achi] > > [c01364c2>] sys_init_module+0xd/0x210 > > [<c0103291>] syscall_call+0x7/0xbQuoted 27 lines
Quoted 27 lines
Quoted 3 lines
Is this on your Fujitsu notebook, with the same hardware configuration as last week?
yup
--
[<c02516c9>] ata_device_add+0x1e9/0x2b0 [<e082d850>] ahci_interrupt+0x0/0x1e0 [achi] [<e082e263>] ahci_init_one+0x1a3/0x270 [achi] [<c01cb5d6>] __pci_device_probe+0x56/0x70 [<c01cb61f>] pci_device_probe+0x2f/0x50 [<c023b313>] driver_probe_device+0x43/0xd0 [<c023b420>] __driver_attach+0x0/0x50 [<c023b461>] __driver_attach+0x41/0x50 [<c023a84d>] bus_for_each_dev+0x5d/0x80 [<c023b495>] driver_attach+0x25/0x30 [<c023b420>] __driver_attach+0x0/0x50 [<c023ada9>] bus_add_driver+0x89/0xf0 [<c01cb8a4>] __pci_register_driver+0x74/0xa0 [<e0832018>] ahci_init+0x18/0x1c [achi] [c01364c2>] sys_init_module+0xd/0x210 [<c0103291>] syscall_call+0x7/0xbthen the Code: line
Quoted 8 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
thats all that's left on the screen unfortunately, the rest scrolls off
the
Quoted 3 lines
Quoted 3 lines
top.
---
---
~Randy
------------------------------------------
This message was penned by the hand of Dom
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
Quoted 9 lines
OK, well, that's a little better, but the top of the backtrace is where the nitty gritty info is.
Is it possible for you to use any other method of capturing more fault messages, like serial console, netconsole, or even higher resolution video (and smaller font) so that I can see where the fault is actually happening?Thanks.
ok. eye-watering font, but here's what it says:
Quoted 7 lines
Quoted 5 lines
Thanks for doing that.
Did you enable ACPI debug output? If so, how? (in .config or by modifying a header file? if by modifying a header file, please tell us exactly.)
ACPI_DEBUGin .config and also applied your debug patch
Yes, easy to reproduce with CONFIG_ACPI_DEBUG=y.
My new code frees a buffer that it does not own.
Just comment out or delete line 156 in drivers/scsi/ata_acpi.c, which is:
ACPI_MEM_FREE(dinfo);
It shouldn't be there.
Thanks!
---
~Randy
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
Quoted 22 lines · On Thu, 8 Dec 2005 17:03:02 -0800 Randy Dunlap…
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
Quoted 9 lines
OK, well, that's a little better, but the top of the backtrace is where the nitty gritty info is.
Is it possible for you to use any other method of capturing more fault messages, like serial console, netconsole, or even higher resolution video (and smaller font) so that I can see where the fault is actually happening?Thanks.
ok. eye-watering font, but here's what it says:
Quoted 7 lines
Quoted 5 lines
Thanks for doing that.
Did you enable ACPI debug output? If so, how? (in .config or by modifying a header file? if by modifying a header file, please tell us exactly.)
ACPI_DEBUGin .config and also applied your debug patchYes, easy to reproduce with
CONFIG_ACPI_DEBUG=y.
Quoted 7 lines
My new code frees a buffer that it does not own.
Just comment out or delete line 156 in
drivers/scsi/ata_acpi.c, which is:ACPI_MEM_FREE(dinfo);It shouldn't be there.
That's not quite correct. It will boot & run with that change, but now the buffer isn't being freed at all. I'll rethink that and post a patch.
---
~Randy
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
Quoted 11 lines · On Thu, 8 Dec 2005 17:10:08 -0800 Randy Dunlap…
Quoted 11 lines
Quoted 2 lines
ACPI_DEBUGin .config and also applied your debug patchYes, easy to reproduce with
CONFIG_ACPI_DEBUG=y.My new code frees a buffer that it does not own.
Just comment out or delete line 156 in
drivers/scsi/ata_acpi.c, which is:ACPI_MEM_FREE(dinfo);
Quoted 5 lines
Quoted 1 line
It shouldn't be there.
That's not quite correct. It will boot & run with that change, but now the buffer isn't being freed at all. I'll rethink that and post a patch.
Dom,
I've updated the ata_apci.patch file to fix this bug. I was misusing some of the ACPI memory alloc/free interfaces.
Updated file is at
http://www.xenotime.net/linux/SATA/2.6.15-rc/ata_acpi.patch
Thanks,
---
~Randy
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
Quoting Randy Dunlap <[email protected]>:
Quoted 20 lines
Quoted 11 lines · On Thu, 8 Dec 2005 17:10:08 -0800 Randy Dunlap…
Quoted 11 lines
Quoted 2 lines
ACPI_DEBUGin .config and also applied your debug patchYes, easy to reproduce with
CONFIG_ACPI_DEBUG=y.My new code frees a buffer that it does not own.
Just comment out or delete line 156 in
drivers/scsi/ata_acpi.c, which is:ACPI_MEM_FREE(dinfo);Quoted 5 lines
Quoted 1 line
It shouldn't be there.
That's not quite correct. It will boot & run with that change, but now the buffer isn't being freed at all. I'll rethink that and post a patch.
Quoted 7 lines
Dom,
I've updated the ata_apci.patch file to fix this bug. I was misusing some of the ACPI memory alloc/free interfaces.
Updated file is at
http://www.xenotime.net/linux/SATA/2.6.15-rc/ata_acpi.patch
hi
it applies cleanly now, but unfortunately this doesnt seem to work in my case. on waking from S3 sleep there is still no disk activity and terminals hang on first disk access. dmesg attached, there's some more debug now which hopefully will be helpful!
cheers
dom
------------------------------------------
This message was penned by the hand of Dom
.......................................................
Table [DSDT](id 0007) - 671 Objects with 65 Devices 181 Methods 18 Regions
Parsing all Control Methods:...
Table [SSDT](id 0004) - 5 Objects with 0 Devices 3 Methods 0 Regions
Parsing all Control Methods:.
Table [SSDT](id 0005) - 1 Objects with 0 Devices 1 Methods 0 Regions
ACPI Namespace successfully loaded at root c043cc58
ACPI: setting ELCR to 0200 (from 0ca0)
evxfevnt-0091 [03] enable : Transition to ACPI mode successful
checking if image is initramfs... it is
Freeing initrd memory: 1623k freed
NET: Registered protocol family 16
ACPI: bus type pci registered
PCI: PCI BIOS revision 2.10 entry at 0xeafc4, last bus=6
PCI: Using MMCONFIG
ACPI: Subsystem revision 20050902
evgpeblk-0988 [06] ev_create_gpe_block : GPE 00 to 1F [_GPE] 4 regs on int 0x9
evgpeblk-0996 [06] ev_create_gpe_block : Found 4 Wake, Enabled 2 Runtime GPEs in this block
Completing Region/Field/Buffer/Package initialization:....................................................... Initialized 18/18 Regions 0/0 Fields 23/23 Buffers 14/20 Packages (686 nodes)
Executing all Device _STA and_INI methods:...................................................................... 70 Devices found containing: 70 _STA, 2 _INI methods
ACPI: Interpreter enabled
ACPI: Using PIC for interrupt routing
ACPI: PCI Root Bridge [PCI0] (0000:00)
PCI: Probing PCI hardware (bus 00)
PCI quirk: region 1000-107f claimed by ICH6 ACPI/GPIO/TCO
PCI quirk: region 1300-133f claimed by ICH6 GPIO
PCI: Ignoring BAR0-3 of IDE controller 0000:00:1f.1
Boot video device is 0000:01:00.0
PCI: Transparent bridge - 0000:00:1e.0
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.PEGP._PRT]
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.RP01._PRT]
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.PCIB._PRT]
ACPI: PCI Interrupt Link [LNKA] (IRQs 10) *11
ACPI: PCI Interrupt Link [LNKB] (IRQs *10)
ACPI: PCI Interrupt Link [LNKC] (IRQs *10)
ACPI: PCI Interrupt Link [LNKD] (IRQs *10)
ACPI: PCI Interrupt Link [LNKE] (IRQs 10) *7
ACPI: PCI Interrupt Link [LNKF] (IRQs 10) *0, disabled.
ACPI: PCI Interrupt Link [LNKG] (IRQs 10) *0, disabled.
ACPI: PCI Interrupt Link [LNKH] (IRQs 10) *5
ACPI: Embedded Controller [EC0] (gpe 28)
ACPI: Power Resource [QFAN] (off)
Linux Plug and Play Support v0.97 (c) Adam Belay
pnp: PnP ACPI init
pnp: ACPI device : hid PNP0C02
pnp: ACPI device : hid PNP0200
pnp: ACPI device : hid INT0800
pnp: ACPI device : hid PNP0C04
pnp: ACPI device : hid PNP0C02
pnp: ACPI device : hid PNP0B00
pnp: ACPI device : hid PNP0303
pnp: ACPI device : hid PNP0F13
pnp: ACPI device : hid FUJ02B1
pnp: PnP ACPI: found 9 devices
PnPBIOS: Disabled by ACPI PNP
SCSI subsystem initialized
usbcore: registered new driver usbfs
usbcore: registered new driver hub
PCI: Using ACPI for IRQ routing
PCI: If a device doesn't work, try "pci=routeirq". If it helps, post a report
pnp: the driver 'system' has been registered
pnp: match found with the PnP device '00:00' and the driver 'system'
pnp: match found with the PnP device '00:04' and the driver 'system'
PCI: Bridge: 0000:00:01.0
IO window: c000-dfff
MEM window: c0000000-cfffffff
PREFETCH window: 90000000-9fffffff
PCI: Bridge: 0000:00:1c.0
IO window: a000-bfff
MEM window: bc000000-bfffffff
PREFETCH window: 8c000000-8fffffff
PCI: Bus 7, cardbus bridge: 0000:06:06.0
IO window: 00008000-000080ff
IO window: 00008400-000084ff
PREFETCH window: 84000000-85ffffff
MEM window: b6000000-b7ffffff
PCI: Bridge: 0000:00:1e.0
IO window: 8000-9fff
MEM window: b4000000-bbffffff
PREFETCH window: 84000000-8bffffff
acpi_bus-0201 [01] bus_set_power : Device is not power manageable
ACPI: PCI Interrupt Link [LNKA] enabled at IRQ 10
PCI: setting IRQ 10 as level-triggered
ACPI: PCI Interrupt 0000:00:01.0[A] -> Link [LNKA] -> GSI 10 (level, low) -> IRQ 10
PCI: Setting latency timer of device 0000:00:01.0 to 64
acpi_bus-0201 [01] bus_set_power : Device is not power manageable
ACPI: PCI Interrupt Link [LNKB] enabled at IRQ 10
ACPI: PCI Interrupt 0000:00:1c.0[A] -> Link [LNKB] -> GSI 10 (level, low) -> IRQ 10
PCI: Setting latency timer of device 0000:00:1c.0 to 64
PCI: Setting latency timer of device 0000:00:1e.0 to 64
acpi_bus-0201 [01] bus_set_power : Device is not power manageable
ACPI: PCI Interrupt 0000:06:06.0[A] -> Link [LNKB] -> GSI 10 (level, low) -> IRQ 10
Machine check exception polling timer started.
audit: initializing netlink socket (disabled)
audit(1134240289.108:1): initialized
Initializing Cryptographic API
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered
Linux agpgart interface v0.101 (c) Dave Jones
agpgart: Detected an Intel 915GM Chipset.
agpgart: AGP aperture is 256M @ 0x0
[drm] Initialized drm 1.0.0 20040925
pnp: the driver 'i8042 kbd' has been registered
pnp: match found with the PnP device '00:06' and the driver 'i8042 kbd'
pnp: the driver 'i8042 aux' has been registered
pnp: match found with the PnP device '00:07' and the driver 'i8042 aux'
PNP: PS/2 Controller [PNP0303:PS2K,PNP0f13:PS2M] at 0x60,0x64 irq 1,12
serio: i8042 AUX port at 0x60,0x64 irq 12
serio: i8042 KBD port at 0x60,0x64 irq 1
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
pnp: the driver 'serial' has been registered
acpi_bus-0201 [01] bus_set_power : Device is not power manageable
ACPI: PCI Interrupt Link [LNKE] enabled at IRQ 10
ACPI: PCI Interrupt 0000:00:1e.3[B] -> Link [LNKE] -> GSI 10 (level, low) -> IRQ 10
ACPI: PCI interrupt for device 0000:00:1e.3 disabled
Floppy drive(s): fd0 is 1.44M
floppy0: no floppy controllers found
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
libata version 1.20 loaded.
ohci1394: $Rev: 1313 $ Ben Collins <[email protected]>
acpi_bus-0201 [01] bus_set_power : Device is not power manageable
ACPI: PCI Interrupt Link [LNKD] enabled at IRQ 10
ACPI: PCI Interrupt 0000:06:06.2[C] -> Link [LNKD] -> GSI 10 (level, low) -> IRQ 10
ohci1394: fw-host0: OHCI-1394 1.1 (PCI): IRQ=[10] MMIO=[b4000000-b40007ff] Max Packet=[2048]
ieee1394: raw1394: /dev/raw1394 device initialized
usbmon: debugfs is not available
acpi_bus-0201 [01] bus_set_power : Device is not power manageable
ACPI: PCI Interrupt Link [LNKH] enabled at IRQ 10
ACPI: PCI Interrupt 0000:00:1d.7[A] -> Link [LNKH] -> GSI 10 (level, low) -> IRQ 10
PCI: Setting latency timer of device 0000:00:1d.7 to 64ehci_hcd 0000:00:1d.7: EHCI Host Controllerehci_hcd 0000:00:1d.7: debug port 1
PCI: cache line size of 32 is not supported by device 0000:00:1d.7ehci_hcd 0000:00:1d.7: new USB bus registered, assigned bus number 1ehci_hcd 0000:00:1d.7: irq 10, io mem 0xd0000400ehci_hcd 0000:00:1d.7: USB 2.0 started, EHCI 1.00, driver 10 Dec 2004
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 8 ports detected
USB Universal Host Controller Interface driver v2.3
ACPI: PCI Interrupt 0000:00:1d.0[A] -> Link [LNKH] -> GSI 10 (level, low) -> IRQ 10
PCI: Setting latency timer of device 0000:00:1d.0 to 64uhci_hcd 0000:00:1d.0: UHCI Host Controlleruhci_hcd 0000:00:1d.0: new USB bus registered, assigned bus number 2uhci_hcd 0000:00:1d.0: irq 10, io base 0x00001200
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 2 ports detected
ACPI: PCI Interrupt 0000:00:1d.1[B] -> Link [LNKD] -> GSI 10 (level, low) -> IRQ 10
PCI: Setting latency timer of device 0000:00:1d.1 to 64uhci_hcd 0000:00:1d.1: UHCI Host Controlleruhci_hcd 0000:00:1d.1: new USB bus registered, assigned bus number 3uhci_hcd 0000:00:1d.1: irq 10, io base 0x00001220
hub 3-0:1.0: USB hub found
hub 3-0:1.0: 2 ports detected
ACPI: PCI Interrupt Link [LNKC] enabled at IRQ 10
ACPI: PCI Interrupt 0000:00:1d.2[C] -> Link [LNKC] -> GSI 10 (level, low) -> IRQ 10
PCI: Setting latency timer of device 0000:00:1d.2 to 64uhci_hcd 0000:00:1d.2: UHCI Host Controlleruhci_hcd 0000:00:1d.2: new USB bus registered, assigned bus number 4uhci_hcd 0000:00:1d.2: irq 10, io base 0x0000e380
hub 4-0:1.0: USB hub found
hub 4-0:1.0: 2 ports detected
ACPI: PCI Interrupt 0000:00:1d.3[D] -> Link [LNKA] -> GSI 10 (level, low) -> IRQ 10
PCI: Setting latency timer of device 0000:00:1d.3 to 64uhci_hcd 0000:00:1d.3: UHCI Host Controlleruhci_hcd 0000:00:1d.3: new USB bus registered, assigned bus number 5uhci_hcd 0000:00:1d.3: irq 10, io base 0x0000e3a0
hub 5-0:1.0: USB hub found
hub 5-0:1.0: 0 ports detected
usb 3-2: new low speed USB device using uhci_hcd and address 2
usbcore: registered new driver usblpdrivers/usb/class/usblp.c: v0.13: USB Printer Device Class driver
Initializing USB Mass Storage driver...
usbcore: registered new driver usb-storage
USB Mass Storage support registered.
input: Microsoft Microsoft USB Wireless Mouse as /class/input/input0
input: USB HID v1.11 Mouse [Microsoft Microsoft USB Wireless Mouse] on usb-0000:00:1d.1-2
usbcore: registered new driver usbhiddrivers/usb/input/hid-core.c: v2.6:USB HID core driver
mice: PS/2 mouse device common for all mice
Advanced Linux Sound Architecture Driver Version 1.0.10rc3 (Mon Nov 07 13:30:21 2005 UTC).
acpi_bus-0201 [01] bus_set_power : Device is not power manageable
ACPI: PCI Interrupt 0000:00:1e.2[A] -> Link [LNKB] -> GSI 10 (level, low) -> IRQ 10
PCI: Setting latency timer of device 0000:00:1e.2 to 64
input: AT Translated Set 2 keyboard as /class/input/input1
input: PS/2 Mouse as /class/input/input2
input: AlpsPS/2 ALPS GlidePoint as /class/input/input3
ieee1394: Host added: ID:BUS[0-00:1023] GUID[00000e10000d9124]intel8x0_measure_ac97_clock: measured 55488 usecs
intel8x0: clocking to 48000
ALSA device list:
#0: Intel ICH6 with ALC203 at 0xd0000000, irq 10
oprofile: using timer interrupt.
NET: Registered protocol family 2
IP route cache hash table entries: 8192 (order: 3, 32768 bytes)
TCP established hash table entries: 32768 (order: 5, 131072 bytes)
TCP bind hash table entries: 32768 (order: 5, 131072 bytes)
TCP: Hash tables configured (established 32768 bind 32768)
TCP reno registeredip_conntrack version 2.4 (4095 buckets, 32760 max) - 212 bytes per conntrackip_tables: (C) 2000-2002 Netfilter core teamipt_recent v0.3.1: Stephen Frost <[email protected]>. http://snowman.net/projects/ipt_recent/arp_tables: (C) 2002 David S. Miller
TCP bic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
Using IPI Shortcut mode
ACPI wakeup devices:
LID AZAL RP01 MINI LAN MODM
ACPI: (supports S0 S3 S4 S5)
Freeing unused kernel memory: 196k freed
Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
pnp: the driver 'ide' has been registered
ICH6: IDE controller at PCI slot 0000:00:1f.1
ACPI: PCI Interrupt 0000:00:1f.1[A] -> Link [LNKC] -> GSI 10 (level, low) -> IRQ 10
ICH6: chipset revision 4
ICH6: not 100% native mode: will probe irqs later
ide0: BM-DMA at 0x1100-0x1107, BIOS settings: hda:DMA, hdb:pio
ide1: BM-DMA at 0x1108-0x110f, BIOS settings: hdc:DMA, hdd:pioProbing IDE interface ide0...
hda: DW-224E-B, ATAPI CD/DVD-ROM drive
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
Probing IDE interface ide1...
ahci 0000:00:1f.2: version 1.2
acpi_bus-0201 [01] bus_set_power : Device is not power manageable
ACPI: PCI Interrupt 0000:00:1f.2[D] -> Link [LNKA] -> GSI 10 (level, low) -> IRQ 10
PCI: Setting latency timer of device 0000:00:1f.2 to 64
ahci 0000:00:1f.2: AHCI 0001.0000 32 slots 4 ports 1.5 Gbps 0x5 impl IDE mode
ahci 0000:00:1f.2: flags: 64bit stag led pmp
ata1: SATA max UDMA/133 cmd 0xE085A100 ctl 0x0 bmdma 0x0 irq 10
ata2: SATA max UDMA/133 cmd 0xE085A180 ctl 0x0 bmdma 0x0 irq 10
ata3: SATA max UDMA/133 cmd 0xE085A200 ctl 0x0 bmdma 0x0 irq 10
ata4: SATA max UDMA/133 cmd 0xE085A280 ctl 0x0 bmdma 0x0 irq 10
ata1: dev 0 cfg 00:045a 49:0b00 82:746b 83:5988 84:4003 85:7469 86:1808 87:4003 88:003f 93:600b
ata1: dev 0 ATA-5, max UDMA/100, 117210240 sectors: LBA
ata1(0): applying bridge limitsdo_drive_SDD: ap->id: 1, ix = 0, port#: 0, hard_port#: 0do_drive_SDD: ata_id_is_sata is False
ata1: dev 0 configured for UDMA/100pci_acpi_get_dev_handle: pcidevfn: 0x1f0002get_devices: :\_SB_.PCI0.SATA: matches pcidevfn (0x1f0002)get_devices: GOT ONE: (\_SB_.PCI0.SATA.PRID) root_port = 0x0, port_num = 0x0get_devices: warning: don't know how to handle SATA port multiplierget_devices: GOT ONE: (\_SB_.PCI0.SATA.PRID.P_D0) root_port = 0x0, port_num = 0x0get_devices: warning: don't know how to handle SATA port multiplierget_devices: GOT ONE: (\_SB_.PCI0.SATA.PRID.P_D1) root_port = 0x0, port_num = 0x1get_devices: warning: don't know how to handle SATA port multiplierget_devices: GOT ONE: (\_SB_.PCI0.SATA.SECD) root_port = 0x0, port_num = 0x1get_devices: warning: don't know how to handle SATA port multiplierget_devices: GOT ONE: (\_SB_.PCI0.SATA.SECD.S_D0) root_port = 0x0, port_num = 0x0get_devices: warning: don't know how to handle SATA port multiplierget_devices: GOT ONE: (\_SB_.PCI0.SATA.SECD.S_D1) root_port = 0x0, port_num = 0x1get_devices: warning: don't know how to handle SATA port multiplier
scsi0 : ahci
ata2: no device found (phy stat 00000000)
scsi1 : ahci
ata3: no device found (phy stat 00000000)
scsi2 : ahci
ata4: no device found (phy stat 00000000)
scsi3 : ahci
Vendor: ATA Model: HITACHI_DK23FA-6 Rev: 00M4
Type: Direct-Access ANSI SCSI revision: 05
ACPI: CPU0 (power states: C1[C1] C2[C2] C3[C3] C4[C3])
ACPI: Processor [CPU0] (supports 8 throttling states)
acpi_processor-0507 [06] processor_get_info : Error getting cpuindex for acpiid 0x1
[ACPI Debug] String: [0x13] "THERM: _SCP(Active)"
ACPI: Thermal Zone [THRM] (72 C)
ACPI: Fan [FAN] (on)
SCSI device sda: 117210240 512-byte hdwr sectors (60012 MB)
SCSI device sda: drive cache: write back
SCSI device sda: 117210240 512-byte hdwr sectors (60012 MB)
SCSI device sda: drive cache: write back
sda: sda1 sda2 sda3 sda4
sd 0:0:0:0: Attached scsi disk sda
sd 0:0:0:0: Attached scsi generic sg0 type 0
ReiserFS: sda4: found reiserfs format "3.6" with standard journal
ReiserFS: sda4: using ordered data mode
ReiserFS: sda4: journal params: device sda4, size 8192, journal first block 18, max trans len 1024, max batch 900, max commit age 30, max trans age 30
ReiserFS: sda4: checking transaction log (sda4)
ReiserFS: sda4: Using r5 hash to sort names
ReiserFS: sda4: Removing [48544 68043 0x0 SD]..done
ReiserFS: sda4: There were 1 uncompleted unlinks/truncates. Completed
Adding 1052248k swap on /dev/sda2. Priority:-1 extents:1 across:1052248k
NTFS driver 2.1.25 [Flags: R/W MODULE].
NTFS volume version 3.1.
hda: ATAPI 24X DVD-ROM CD-R/RW drive, 1654kB Cache, UDMA(33)
Uniform CD-ROM driver Revision: 3.20
cdrom: open failed.
BIOS EDD facility v0.16 2004-Jun-25, 1 devices found
ACPI: AC Adapter [ACAD] (off-line)
ACPI: Battery Slot [BAT1] (battery present)
ACPI: Power Button (FF) [PWRF]
ACPI: Lid Switch [LID]
ACPI: Power Button (CM) [PWRB]
acpi-cpufreq: CPU0 - ACPI performance management activated.
osl-0854 [83] os_wait_semaphore : Failed to acquire semaphore[dffde5c0|1|0], AE_TIME
osl-0854 [83] os_wait_semaphore : Failed to acquire semaphore[dffde5c0|1|20480], AE_TIME exmutex-0258: *** Error: Thread C cannot release Mutex [MUT0] acquired by thread 1430
psparse-0508: *** Error: Method execution failed [\_SB_.BAT1._STA] (Node dfe2ae28), AE_AML_NOT_OWNER
[ACPI Debug] String: [0x13] "THERM: _SCP(Active)"
Re: [PATCH 6/6 update] SATA ACPI: ata_acpi functions
Quoted 10 lines · On Sat, 10 Dec 2005 19:01:50 +0000 Dominic Ijichi wrote:
Quoting Randy Dunlap <[email protected]>:
Quoted 7 lines
Dom,
I've updated the ata_apci.patch file to fix this bug. I was misusing some of the ACPI memory alloc/free interfaces.
Updated file is at
http://www.xenotime.net/linux/SATA/2.6.15-rc/ata_acpi.patch
Quoted 6 lines
hi
it applies cleanly now, but unfortunately this doesnt seem to work in my case. on waking from S3 sleep there is still no disk activity and terminals hang on first disk access. dmesg attached, there's some more debug now which hopefully will be helpful!
partial dmesg:
ata1: dev 0 cfg 00:045a 49:0b00 82:746b 83:5988 84:4003 85:7469 86:1808 87:4003 88:003f 93:600b
ata1: dev 0 ATA-5, max UDMA/100, 117210240 sectors: LBA
ata1(0): applying bridge limitsdo_drive_SDD: ap->id: 1, ix = 0, port#: 0, hard_port#: 0do_drive_SDD: ata_id_is_sata is False
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The drive is not reported as a SATA drive, so the patch that I wrote won't work for it. Have you tried this patch to see if it works/helps on your machine?
From: Shaohua Li <[email protected]>
To: linux-ide <[email protected]>, lkml <[email protected]>
Subject: [RFC]add ACPI hooks for IDE suspend/resume
Date: Tue, 06 Dec 2005 14:10:04 +0800
Thanks,
---
~Randy