From 45a66c1c3ff88e8050dd25e81bafdf79a12a8042 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 9 Jul 2007 11:46:13 -0700 Subject: libata-core: convert to use cancel_rearming_delayed_work() We should not use cancel_work_sync(delayed_work->work). This works, but not good. We can use cancel_rearming_delayed_work(), this also simplifies the code. Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index a3df64677ac3..bf98d44c8109 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -196,7 +196,6 @@ enum { ATA_PFLAG_SCSI_HOTPLUG = (1 << 6), /* SCSI hotplug scheduled */ ATA_PFLAG_INITIALIZING = (1 << 7), /* being initialized, don't touch */ - ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */ ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ ATA_PFLAG_GTM_VALID = (1 << 19), /* acpi_gtm data valid */ -- cgit v1.2.3 From d583bc18812f8da52bf25eef9cd111e5fd46a6ab Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 4 Jul 2007 18:02:07 +0900 Subject: libata: simplify PCI legacy SFF host handling With PCI resource fix up for legacy hosts. We can use the same code path to allocate IO resources and initialize host for both legacy and native SFF hosts. Only IRQ requesting needs to be different. Rename ata_pci_*_native_host() to ata_pci_*_sff_host(), kill all legacy specific functions and use the renamed functions instead. This simplifies code a lot. Signed-off-by: Tejun Heo Cc: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 4 +- drivers/ata/libata-sff.c | 288 ++++++---------------------------------------- drivers/ata/sata_nv.c | 2 +- drivers/ata/sata_sis.c | 2 +- drivers/ata/sata_uli.c | 2 +- drivers/ata/sata_via.c | 2 +- include/linux/libata.h | 8 +- 7 files changed, 42 insertions(+), 266 deletions(-) (limited to 'include') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 257fda90e527..681693534f4f 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6925,9 +6925,9 @@ EXPORT_SYMBOL_GPL(ata_timing_merge); #ifdef CONFIG_PCI EXPORT_SYMBOL_GPL(pci_test_config_bits); -EXPORT_SYMBOL_GPL(ata_pci_init_native_host); +EXPORT_SYMBOL_GPL(ata_pci_init_sff_host); EXPORT_SYMBOL_GPL(ata_pci_init_bmdma); -EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host); +EXPORT_SYMBOL_GPL(ata_pci_prepare_sff_host); EXPORT_SYMBOL_GPL(ata_pci_init_one); EXPORT_SYMBOL_GPL(ata_pci_remove_one); #ifdef CONFIG_PM diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index fa1c22c7b38f..ca7d2245d684 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -604,13 +604,17 @@ int ata_pci_init_bmdma(struct ata_host *host) } /** - * ata_pci_init_native_host - acquire native ATA resources and init host + * ata_pci_init_sff_host - acquire native PCI ATA resources and init host * @host: target ATA host * * Acquire native PCI ATA resources for @host and initialize the * first two ports of @host accordingly. Ports marked dummy are * skipped and allocation failure makes the port dummy. * + * Note that native PCI resources are valid even for legacy hosts + * as we fix up pdev resources array early in boot, so this + * function can be used for both native and legacy SFF hosts. + * * LOCKING: * Inherited from calling layer (may sleep). * @@ -618,7 +622,7 @@ int ata_pci_init_bmdma(struct ata_host *host) * 0 if at least one port is initialized, -ENODEV if no port is * available. */ -int ata_pci_init_native_host(struct ata_host *host) +int ata_pci_init_sff_host(struct ata_host *host) { struct device *gdev = host->dev; struct pci_dev *pdev = to_pci_dev(gdev); @@ -673,7 +677,7 @@ int ata_pci_init_native_host(struct ata_host *host) } /** - * ata_pci_prepare_native_host - helper to prepare native PCI ATA host + * ata_pci_prepare_sff_host - helper to prepare native PCI ATA host * @pdev: target PCI device * @ppi: array of port_info, must be enough for two ports * @r_host: out argument for the initialized ATA host @@ -687,9 +691,9 @@ int ata_pci_init_native_host(struct ata_host *host) * RETURNS: * 0 on success, -errno otherwise. */ -int ata_pci_prepare_native_host(struct pci_dev *pdev, - const struct ata_port_info * const * ppi, - struct ata_host **r_host) +int ata_pci_prepare_sff_host(struct pci_dev *pdev, + const struct ata_port_info * const * ppi, + struct ata_host **r_host) { struct ata_host *host; int rc; @@ -705,7 +709,7 @@ int ata_pci_prepare_native_host(struct pci_dev *pdev, goto err_out; } - rc = ata_pci_init_native_host(host); + rc = ata_pci_init_sff_host(host); if (rc) goto err_out; @@ -730,221 +734,6 @@ int ata_pci_prepare_native_host(struct pci_dev *pdev, return rc; } -struct ata_legacy_devres { - unsigned int mask; - unsigned long cmd_port[2]; - void __iomem * cmd_addr[2]; - void __iomem * ctl_addr[2]; - unsigned int irq[2]; - void * irq_dev_id[2]; -}; - -static void ata_legacy_free_irqs(struct ata_legacy_devres *legacy_dr) -{ - int i; - - for (i = 0; i < 2; i++) { - if (!legacy_dr->irq[i]) - continue; - - free_irq(legacy_dr->irq[i], legacy_dr->irq_dev_id[i]); - legacy_dr->irq[i] = 0; - legacy_dr->irq_dev_id[i] = NULL; - } -} - -static void ata_legacy_release(struct device *gdev, void *res) -{ - struct ata_legacy_devres *this = res; - int i; - - ata_legacy_free_irqs(this); - - for (i = 0; i < 2; i++) { - if (this->cmd_addr[i]) - ioport_unmap(this->cmd_addr[i]); - if (this->ctl_addr[i]) - ioport_unmap(this->ctl_addr[i]); - if (this->cmd_port[i]) - release_region(this->cmd_port[i], 8); - } -} - -static int ata_init_legacy_port(struct ata_port *ap, - struct ata_legacy_devres *legacy_dr) -{ - struct ata_host *host = ap->host; - int port_no = ap->port_no; - unsigned long cmd_port, ctl_port; - - if (port_no == 0) { - cmd_port = ATA_PRIMARY_CMD; - ctl_port = ATA_PRIMARY_CTL; - } else { - cmd_port = ATA_SECONDARY_CMD; - ctl_port = ATA_SECONDARY_CTL; - } - - /* request cmd_port */ - if (request_region(cmd_port, 8, "libata")) - legacy_dr->cmd_port[port_no] = cmd_port; - else { - dev_printk(KERN_WARNING, host->dev, - "0x%0lX IDE port busy\n", cmd_port); - return -EBUSY; - } - - /* iomap cmd and ctl ports */ - legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8); - legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1); - if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no]) { - dev_printk(KERN_WARNING, host->dev, - "failed to map cmd/ctl ports\n"); - return -ENOMEM; - } - - /* init IO addresses */ - ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no]; - ap->ioaddr.altstatus_addr = legacy_dr->ctl_addr[port_no]; - ap->ioaddr.ctl_addr = legacy_dr->ctl_addr[port_no]; - ata_std_ports(&ap->ioaddr); - - return 0; -} - -/** - * ata_init_legacy_host - acquire legacy ATA resources and init ATA host - * @host: target ATA host - * @was_busy: out parameter, indicates whether any port was busy - * - * Acquire legacy ATA resources for the first two ports of @host - * and initialize it accordingly. Ports marked dummy are skipped - * and resource acquistion failure makes the port dummy. - * - * LOCKING: - * Inherited from calling layer (may sleep). - * - * RETURNS: - * 0 if at least one port is initialized, -ENODEV if no port is - * available. - */ -static int ata_init_legacy_host(struct ata_host *host, int *was_busy) -{ - struct device *gdev = host->dev; - struct ata_legacy_devres *legacy_dr; - int i, rc; - - if (!devres_open_group(gdev, NULL, GFP_KERNEL)) - return -ENOMEM; - - rc = -ENOMEM; - legacy_dr = devres_alloc(ata_legacy_release, sizeof(*legacy_dr), - GFP_KERNEL); - if (!legacy_dr) - goto err_out; - devres_add(gdev, legacy_dr); - - for (i = 0; i < 2; i++) { - if (ata_port_is_dummy(host->ports[i])) - continue; - - rc = ata_init_legacy_port(host->ports[i], legacy_dr); - if (rc == 0) - legacy_dr->mask |= 1 << i; - else { - if (rc == -EBUSY) - (*was_busy)++; - host->ports[i]->ops = &ata_dummy_port_ops; - } - } - - if (!legacy_dr->mask) { - dev_printk(KERN_ERR, gdev, "no available legacy port\n"); - return -ENODEV; - } - - devres_remove_group(gdev, NULL); - return 0; - - err_out: - devres_release_group(gdev, NULL); - return rc; -} - -/** - * ata_request_legacy_irqs - request legacy ATA IRQs - * @host: target ATA host - * @handler: array of IRQ handlers - * @irq_flags: array of IRQ flags - * @dev_id: array of IRQ dev_ids - * - * Request legacy IRQs for non-dummy legacy ports in @host. All - * IRQ parameters are passed as array to allow ports to have - * separate IRQ handlers. - * - * LOCKING: - * Inherited from calling layer (may sleep). - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -static int ata_request_legacy_irqs(struct ata_host *host, - irq_handler_t const *handler, - const unsigned int *irq_flags, - void * const *dev_id) -{ - struct device *gdev = host->dev; - struct ata_legacy_devres *legacy_dr; - int i, rc; - - legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL); - BUG_ON(!legacy_dr); - - for (i = 0; i < 2; i++) { - unsigned int irq; - - /* FIXME: ATA_*_IRQ() should take generic device not pci_dev */ - if (i == 0) - irq = ATA_PRIMARY_IRQ(to_pci_dev(gdev)); - else - irq = ATA_SECONDARY_IRQ(to_pci_dev(gdev)); - - if (!(legacy_dr->mask & (1 << i))) - continue; - - if (!handler[i]) { - dev_printk(KERN_ERR, gdev, - "NULL handler specified for port %d\n", i); - rc = -EINVAL; - goto err_out; - } - - rc = request_irq(irq, handler[i], irq_flags[i], DRV_NAME, - dev_id[i]); - if (rc) { - dev_printk(KERN_ERR, gdev, - "irq %u request failed (errno=%d)\n", irq, rc); - goto err_out; - } - - /* record irq allocation in legacy_dr */ - legacy_dr->irq[i] = irq; - legacy_dr->irq_dev_id[i] = dev_id[i]; - - /* only used to print info */ - if (i == 0) - host->irq = irq; - else - host->irq2 = irq; - } - - return 0; - - err_out: - ata_legacy_free_irqs(legacy_dr); - return rc; -} - /** * ata_pci_init_one - Initialize/register PCI IDE host controller * @pdev: Controller to be initialized @@ -1029,35 +818,11 @@ int ata_pci_init_one(struct pci_dev *pdev, #endif } - /* alloc and init host */ - host = ata_host_alloc_pinfo(dev, ppi, 2); - if (!host) { - dev_printk(KERN_ERR, &pdev->dev, - "failed to allocate ATA host\n"); - rc = -ENOMEM; + /* prepare host */ + rc = ata_pci_prepare_sff_host(pdev, ppi, &host); + if (rc) goto err_out; - } - if (!legacy_mode) { - rc = ata_pci_init_native_host(host); - if (rc) - goto err_out; - } else { - int was_busy = 0; - - rc = ata_init_legacy_host(host, &was_busy); - if (was_busy) - pcim_pin_device(pdev); - if (rc) - goto err_out; - - /* request respective PCI regions, may fail */ - rc = pci_request_region(pdev, 1, DRV_NAME); - rc = pci_request_region(pdev, 3, DRV_NAME); - } - - /* init BMDMA, may fail */ - ata_pci_init_bmdma(host); pci_set_master(pdev); /* start host and request IRQ */ @@ -1068,17 +833,28 @@ int ata_pci_init_one(struct pci_dev *pdev, if (!legacy_mode) { rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler, IRQF_SHARED, DRV_NAME, host); + if (rc) + goto err_out; host->irq = pdev->irq; } else { - irq_handler_t handler[2] = { host->ops->irq_handler, - host->ops->irq_handler }; - unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED }; - void *dev_id[2] = { host, host }; + if (!ata_port_is_dummy(host->ports[0])) { + host->irq = ATA_PRIMARY_IRQ(pdev); + rc = devm_request_irq(dev, host->irq, + pi->port_ops->irq_handler, + IRQF_SHARED, DRV_NAME, host); + if (rc) + goto err_out; + } - rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id); + if (!ata_port_is_dummy(host->ports[1])) { + host->irq2 = ATA_SECONDARY_IRQ(pdev); + rc = devm_request_irq(dev, host->irq2, + pi->port_ops->irq_handler, + IRQF_SHARED, DRV_NAME, host); + if (rc) + goto err_out; + } } - if (rc) - goto err_out; /* register */ rc = ata_host_register(host, pi->sht); diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index b2656867c647..db81e3efa5ec 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -1560,7 +1560,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) } ppi[0] = &nv_port_info[type]; - rc = ata_pci_prepare_native_host(pdev, ppi, &host); + rc = ata_pci_prepare_sff_host(pdev, ppi, &host); if (rc) return rc; diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index fd80bcf1b236..33716b00c6b7 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -334,7 +334,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) break; } - rc = ata_pci_prepare_native_host(pdev, ppi, &host); + rc = ata_pci_prepare_sff_host(pdev, ppi, &host); if (rc) return rc; diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index aca71819f6e8..b52f83ab056a 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c @@ -213,7 +213,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) host->private_data = hpriv; /* the first two ports are standard SFF */ - rc = ata_pci_init_native_host(host); + rc = ata_pci_init_sff_host(host); if (rc) return rc; diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index a4c0832033d8..c4124475f754 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -412,7 +412,7 @@ static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) struct ata_host *host; int rc; - rc = ata_pci_prepare_native_host(pdev, ppi, &host); + rc = ata_pci_prepare_sff_host(pdev, ppi, &host); if (rc) return rc; *r_host = host; diff --git a/include/linux/libata.h b/include/linux/libata.h index bf98d44c8109..0c8b6578bd59 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -870,11 +870,11 @@ struct pci_bits { unsigned long val; }; -extern int ata_pci_init_native_host(struct ata_host *host); +extern int ata_pci_init_sff_host(struct ata_host *host); extern int ata_pci_init_bmdma(struct ata_host *host); -extern int ata_pci_prepare_native_host(struct pci_dev *pdev, - const struct ata_port_info * const * ppi, - struct ata_host **r_host); +extern int ata_pci_prepare_sff_host(struct pci_dev *pdev, + const struct ata_port_info * const * ppi, + struct ata_host **r_host); extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits); extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long); #endif /* CONFIG_PCI */ -- cgit v1.2.3 From 75683fe7153c3817bb4fd4491e2a5913af6c463e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 5 Jul 2007 13:31:27 +0900 Subject: libata: clean up horkage handling Horkage handling had the following problems. * dev->horkage was positioned after ATA_DEVICE_CLEAR_OFFSET, so it was cleared before the device is configured. This broke HORKAGE_DIAGNOSTIC. * Some used dev->horkage while others called ata_device_blacklisted() directly. This was at best confusing. This patch moves dev->horkage right after dev->flags and set the field according to the blacklist during device configuration. All users test against dev->horkage. ata_device_blacklisted() now has only one user, make it static. While at it, rename it to ata_dev_blacklisted() for consistency. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 13 ++++++++----- include/linux/libata.h | 3 +-- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a00e4ee58b73..66c8c8c377ab 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -71,6 +71,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev, u16 heads, u16 sectors); static unsigned int ata_dev_set_xfermode(struct ata_device *dev); static void ata_dev_xfermask(struct ata_device *dev); +static unsigned long ata_dev_blacklisted(const struct ata_device *dev); unsigned int ata_print_id = 1; static struct workqueue_struct *ata_wq; @@ -1784,7 +1785,7 @@ static void ata_dev_config_ncq(struct ata_device *dev, desc[0] = '\0'; return; } - if (ata_device_blacklisted(dev) & ATA_HORKAGE_NONCQ) { + if (dev->horkage & ATA_HORKAGE_NONCQ) { snprintf(desc, desc_sz, "NCQ (not used)"); return; } @@ -1833,6 +1834,9 @@ int ata_dev_configure(struct ata_device *dev) if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); + /* set horkage */ + dev->horkage |= ata_dev_blacklisted(dev); + /* let ACPI work its magic */ rc = ata_acpi_on_devcfg(dev); if (rc) @@ -2008,7 +2012,7 @@ int ata_dev_configure(struct ata_device *dev) dev->max_sectors = ATA_MAX_SECTORS; } - if (ata_device_blacklisted(dev) & ATA_HORKAGE_MAX_SEC_128) + if (dev->horkage & ATA_HORKAGE_MAX_SEC_128) dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128, dev->max_sectors); @@ -3775,7 +3779,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { } }; -unsigned long ata_device_blacklisted(const struct ata_device *dev) +static unsigned long ata_dev_blacklisted(const struct ata_device *dev) { unsigned char model_num[ATA_ID_PROD_LEN + 1]; unsigned char model_rev[ATA_ID_FW_REV_LEN + 1]; @@ -3805,7 +3809,7 @@ static int ata_dma_blacklisted(const struct ata_device *dev) if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) && (dev->flags & ATA_DFLAG_CDB_INTR)) return 1; - return (ata_device_blacklisted(dev) & ATA_HORKAGE_NODMA) ? 1 : 0; + return (dev->horkage & ATA_HORKAGE_NODMA) ? 1 : 0; } /** @@ -6918,7 +6922,6 @@ EXPORT_SYMBOL_GPL(ata_host_resume); EXPORT_SYMBOL_GPL(ata_id_string); EXPORT_SYMBOL_GPL(ata_id_c_string); EXPORT_SYMBOL_GPL(ata_id_to_dma_mode); -EXPORT_SYMBOL_GPL(ata_device_blacklisted); EXPORT_SYMBOL_GPL(ata_scsi_simulate); EXPORT_SYMBOL_GPL(ata_pio_need_iordy); diff --git a/include/linux/libata.h b/include/linux/libata.h index 0c8b6578bd59..47cd2a1c5544 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -434,6 +434,7 @@ struct ata_device { struct ata_port *ap; unsigned int devno; /* 0 or 1 */ unsigned long flags; /* ATA_DFLAG_xxx */ + unsigned int horkage; /* List of broken features */ struct scsi_device *sdev; /* attached SCSI device */ #ifdef CONFIG_ATA_ACPI acpi_handle acpi_handle; @@ -465,7 +466,6 @@ struct ata_device { /* error history */ struct ata_ering ering; int spdn_cnt; - unsigned int horkage; /* List of broken features */ }; /* Offset into struct ata_device. Fields above it are maintained @@ -793,7 +793,6 @@ extern void ata_id_string(const u16 *id, unsigned char *s, extern void ata_id_c_string(const u16 *id, unsigned char *s, unsigned int ofs, unsigned int len); extern void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown); -extern unsigned long ata_device_blacklisted(const struct ata_device *dev); extern void ata_bmdma_setup (struct ata_queued_cmd *qc); extern void ata_bmdma_start (struct ata_queued_cmd *qc); extern void ata_bmdma_stop(struct ata_queued_cmd *qc); -- cgit v1.2.3 From 814600ee10d3c056ada315cdbdc2ebe48f54c75a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 1 Jul 2007 19:05:58 +0900 Subject: libata-link: add PMP related ATA constants Add Port Multiplier related ATA constants and macros. Some of these will be used by ata_link implementation. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/ata.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'include') diff --git a/include/linux/ata.h b/include/linux/ata.h index 407dc7e098bc..b5a20162af32 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -164,6 +164,8 @@ enum { ATA_CMD_SET_MAX = 0xF9, ATA_CMD_SET_MAX_EXT = 0x37, ATA_CMD_READ_LOG_EXT = 0x2f, + ATA_CMD_PMP_READ = 0xE4, + ATA_CMD_PMP_WRITE = 0xE8, /* READ_LOG_EXT pages */ ATA_LOG_SATA_NCQ = 0x10, @@ -212,6 +214,28 @@ enum { 0=to device, 1=to host */ ATAPI_CDB_LEN = 16, + /* PMP stuff */ + SATA_PMP_MAX_PORTS = 15, + SATA_PMP_CTRL_PORT = 15, + + SATA_PMP_GSCR_DWORDS = 128, + SATA_PMP_GSCR_PROD_ID = 0, + SATA_PMP_GSCR_REV = 1, + SATA_PMP_GSCR_PORT_INFO = 2, + SATA_PMP_GSCR_ERROR = 32, + SATA_PMP_GSCR_ERROR_EN = 33, + SATA_PMP_GSCR_FEAT = 64, + SATA_PMP_GSCR_FEAT_EN = 96, + + SATA_PMP_PSCR_STATUS = 0, + SATA_PMP_PSCR_ERROR = 1, + SATA_PMP_PSCR_CONTROL = 2, + + SATA_PMP_FEAT_BIST = (1 << 0), + SATA_PMP_FEAT_PMREQ = (1 << 1), + SATA_PMP_FEAT_DYNSSC = (1 << 2), + SATA_PMP_FEAT_NOTIFY = (1 << 3), + /* cable types */ ATA_CBL_NONE = 0, ATA_CBL_PATA40 = 1, @@ -418,4 +442,9 @@ static inline int lba_48_ok(u64 block, u32 n_block) return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536); } +#define sata_pmp_gscr_vendor(gscr) ((gscr)[SATA_PMP_GSCR_PROD_ID] & 0xffff) +#define sata_pmp_gscr_devid(gscr) ((gscr)[SATA_PMP_GSCR_PROD_ID] >> 16) +#define sata_pmp_gscr_rev(gscr) (((gscr)[SATA_PMP_GSCR_REV] >> 8) & 0xff) +#define sata_pmp_gscr_ports(gscr) ((gscr)[SATA_PMP_GSCR_PORT_INFO] & 0xf) + #endif /* __LINUX_ATA_H__ */ -- cgit v1.2.3