Skip to content

Commit

Permalink
libata: implement and use ata_port_desc() to report port configuration
Browse files Browse the repository at this point in the history
Currently, port configuration reporting has the following problems.

* iomapped address is reported instead of raw address
* report contains irrelevant fields or lacks necessary fields for
  non-SFF controllers.
* host->irq/irq2 are there just for reporting and hacky.

This patch implements and uses ata_port_desc() and
ata_port_pbar_desc().  ata_port_desc() is almost identical to
ata_ehi_push_desc() except that it takes @ap instead of @EHI, has no
locking requirement, can only be used during host initialization and "
" is used as separator instead of ", ".  ata_port_pbar_desc() is a
helper to ease reporting of a PCI BAR or an offsetted address into it.

LLD pushes whatever description it wants using the above two
functions.  The accumulated description is printed on host
registration after "[S/P]ATA max MAX_XFERMODE ".

SFF init helpers and ata_host_activate() automatically add
descriptions for addresses and irq respectively, so only LLDs which
isn't standard SFF need to add custom descriptions.  In many cases,
such controllers need to report different things anyway.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
  • Loading branch information
htejun authored and Jeff Garzik committed Oct 12, 2007
1 parent e923090 commit cbcdd87
Show file tree
Hide file tree
Showing 31 changed files with 309 additions and 81 deletions.
4 changes: 4 additions & 0 deletions drivers/ata/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1887,6 +1887,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
struct ata_port *ap = host->ports[i];
void __iomem *port_mmio = ahci_port_base(ap);

ata_port_pbar_desc(ap, AHCI_PCI_BAR, -1, "abar");
ata_port_pbar_desc(ap, AHCI_PCI_BAR,
0x100 + ap->port_no * 0x80, "port");

/* standard SATA port setup */
if (hpriv->port_map & (1 << i))
ap->ioaddr.cmd_addr = port_mmio;
Expand Down
27 changes: 11 additions & 16 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -6541,7 +6541,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
/* set cable, sata_spd_limit and report */
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
int irq_line;
unsigned long xfer_mask;

/* set SATA cable type if still unset */
Expand All @@ -6551,24 +6550,16 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
/* init sata_spd_limit to the current value */
sata_link_init_spd(&ap->link);

/* report the secondary IRQ for second channel legacy */
irq_line = host->irq;
if (i == 1 && host->irq2)
irq_line = host->irq2;

/* print per-port info to dmesg */
xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
ap->udma_mask);

/* print per-port info to dmesg */
if (!ata_port_is_dummy(ap))
ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p "
"ctl 0x%p bmdma 0x%p irq %d\n",
ata_port_printk(ap, KERN_INFO,
"%cATA max %s %s\n",
(ap->flags & ATA_FLAG_SATA) ? 'S' : 'P',
ata_mode_string(xfer_mask),
ap->ioaddr.cmd_addr,
ap->ioaddr.ctl_addr,
ap->ioaddr.bmdma_addr,
irq_line);
ap->link.eh_info.desc);
else
ata_port_printk(ap, KERN_INFO, "DUMMY\n");
}
Expand Down Expand Up @@ -6652,7 +6643,7 @@ int ata_host_activate(struct ata_host *host, int irq,
irq_handler_t irq_handler, unsigned long irq_flags,
struct scsi_host_template *sht)
{
int rc;
int i, rc;

rc = ata_host_start(host);
if (rc)
Expand All @@ -6663,8 +6654,8 @@ int ata_host_activate(struct ata_host *host, int irq,
if (rc)
return rc;

/* Used to print device info at probe */
host->irq = irq;
for (i = 0; i < host->n_ports; i++)
ata_port_desc(host->ports[i], "irq %d", irq);

rc = ata_host_register(host, sht);
/* if failed, just free the IRQ and leave ports alone */
Expand Down Expand Up @@ -7136,6 +7127,10 @@ EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
EXPORT_SYMBOL_GPL(__ata_ehi_push_desc);
EXPORT_SYMBOL_GPL(ata_ehi_push_desc);
EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);
EXPORT_SYMBOL_GPL(ata_port_desc);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(ata_port_pbar_desc);
#endif /* CONFIG_PCI */
EXPORT_SYMBOL_GPL(ata_eng_timeout);
EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
EXPORT_SYMBOL_GPL(ata_link_abort);
Expand Down
67 changes: 67 additions & 0 deletions drivers/ata/libata-eh.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,73 @@ void ata_ehi_clear_desc(struct ata_eh_info *ehi)
ehi->desc_len = 0;
}

/**
* ata_port_desc - append port description
* @ap: target ATA port
* @fmt: printf format string
*
* Format string according to @fmt and append it to port
* description. If port description is not empty, " " is added
* in-between. This function is to be used while initializing
* ata_host. The description is printed on host registration.
*
* LOCKING:
* None.
*/
void ata_port_desc(struct ata_port *ap, const char *fmt, ...)
{
va_list args;

WARN_ON(!(ap->pflags & ATA_PFLAG_INITIALIZING));

if (ap->link.eh_info.desc_len)
__ata_ehi_push_desc(&ap->link.eh_info, " ");

va_start(args, fmt);
__ata_ehi_pushv_desc(&ap->link.eh_info, fmt, args);
va_end(args);
}

#ifdef CONFIG_PCI

/**
* ata_port_pbar_desc - append PCI BAR description
* @ap: target ATA port
* @bar: target PCI BAR
* @offset: offset into PCI BAR
* @name: name of the area
*
* If @offset is negative, this function formats a string which
* contains the name, address, size and type of the BAR and
* appends it to the port description. If @offset is zero or
* positive, only name and offsetted address is appended.
*
* LOCKING:
* None.
*/
void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
const char *name)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
char *type = "";
unsigned long long start, len;

if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM)
type = "m";
else if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
type = "i";

start = (unsigned long long)pci_resource_start(pdev, bar);
len = (unsigned long long)pci_resource_len(pdev, bar);

if (offset < 0)
ata_port_desc(ap, "%s %s%llu@0x%llx", name, type, len, start);
else
ata_port_desc(ap, "%s 0x%llx", name, start + offset);
}

#endif /* CONFIG_PCI */

static void ata_ering_record(struct ata_ering *ering, int is_io,
unsigned int err_mask)
{
Expand Down
23 changes: 18 additions & 5 deletions drivers/ata/libata-sff.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,9 @@ int ata_pci_init_bmdma(struct ata_host *host)
if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) &&
(ioread8(bmdma + 2) & 0x80))
host->flags |= ATA_HOST_SIMPLEX;

ata_port_desc(ap, "bmdma 0x%llx",
(unsigned long long)pci_resource_start(pdev, 4) + 8 * i);
}

return 0;
Expand Down Expand Up @@ -634,6 +637,10 @@ int ata_pci_init_sff_host(struct ata_host *host)
((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS);
ata_std_ports(&ap->ioaddr);

ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
(unsigned long long)pci_resource_start(pdev, base),
(unsigned long long)pci_resource_start(pdev, base + 1));

mask |= 1 << i;
}

Expand Down Expand Up @@ -804,24 +811,30 @@ int ata_pci_init_one(struct pci_dev *pdev,
IRQF_SHARED, DRV_NAME, host);
if (rc)
goto err_out;
host->irq = pdev->irq;

ata_port_desc(host->ports[0], "irq %d", pdev->irq);
ata_port_desc(host->ports[1], "irq %d", pdev->irq);
} else {
if (!ata_port_is_dummy(host->ports[0])) {
host->irq = ATA_PRIMARY_IRQ(pdev);
rc = devm_request_irq(dev, host->irq,
rc = devm_request_irq(dev, ATA_PRIMARY_IRQ(pdev),
pi->port_ops->irq_handler,
IRQF_SHARED, DRV_NAME, host);
if (rc)
goto err_out;

ata_port_desc(host->ports[0], "irq %d",
ATA_PRIMARY_IRQ(pdev));
}

if (!ata_port_is_dummy(host->ports[1])) {
host->irq2 = ATA_SECONDARY_IRQ(pdev);
rc = devm_request_irq(dev, host->irq2,
rc = devm_request_irq(dev, ATA_SECONDARY_IRQ(pdev),
pi->port_ops->irq_handler,
IRQF_SHARED, DRV_NAME, host);
if (rc)
goto err_out;

ata_port_desc(host->ports[1], "irq %d",
ATA_SECONDARY_IRQ(pdev));
}
}

Expand Down
23 changes: 15 additions & 8 deletions drivers/ata/pata_cs5520.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ static struct ata_port_operations cs5520_port_ops = {

static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const unsigned int cmd_port[] = { 0x1F0, 0x170 };
static const unsigned int ctl_port[] = { 0x3F6, 0x376 };
struct ata_port_info pi = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
Expand Down Expand Up @@ -242,10 +244,10 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
}

/* Map IO ports and initialize host accordingly */
iomap[0] = devm_ioport_map(&pdev->dev, 0x1F0, 8);
iomap[1] = devm_ioport_map(&pdev->dev, 0x3F6, 1);
iomap[2] = devm_ioport_map(&pdev->dev, 0x170, 8);
iomap[3] = devm_ioport_map(&pdev->dev, 0x376, 1);
iomap[0] = devm_ioport_map(&pdev->dev, cmd_port[0], 8);
iomap[1] = devm_ioport_map(&pdev->dev, ctl_port[0], 1);
iomap[2] = devm_ioport_map(&pdev->dev, cmd_port[1], 8);
iomap[3] = devm_ioport_map(&pdev->dev, ctl_port[1], 1);
iomap[4] = pcim_iomap(pdev, 2, 0);

if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4])
Expand All @@ -258,13 +260,21 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
ioaddr->bmdma_addr = iomap[4];
ata_std_ports(ioaddr);

ata_port_desc(host->ports[0],
"cmd 0x%x ctl 0x%x", cmd_port[0], ctl_port[0]);
ata_port_pbar_desc(host->ports[0], 4, 0, "bmdma");

ioaddr = &host->ports[1]->ioaddr;
ioaddr->cmd_addr = iomap[2];
ioaddr->ctl_addr = iomap[3];
ioaddr->altstatus_addr = iomap[3];
ioaddr->bmdma_addr = iomap[4] + 8;
ata_std_ports(ioaddr);

ata_port_desc(host->ports[1],
"cmd 0x%x ctl 0x%x", cmd_port[1], ctl_port[1]);
ata_port_pbar_desc(host->ports[1], 4, 8, "bmdma");

/* activate the host */
pci_set_master(pdev);
rc = ata_host_start(host);
Expand All @@ -283,10 +293,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
if (rc)
return rc;

if (i == 0)
host->irq = irq[0];
else
host->irq2 = irq[1];
ata_port_desc(ap, "irq %d", irq[i]);
}

return ata_host_register(host, &cs5520_sht);
Expand Down
6 changes: 5 additions & 1 deletion drivers/ata/pata_hpt3x3.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,18 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
base = host->iomap[4]; /* Bus mastering base */

for (i = 0; i < host->n_ports; i++) {
struct ata_ioports *ioaddr = &host->ports[i]->ioaddr;
struct ata_port *ap = host->ports[i];
struct ata_ioports *ioaddr = &ap->ioaddr;

ioaddr->cmd_addr = base + offset_cmd[i];
ioaddr->altstatus_addr =
ioaddr->ctl_addr = base + offset_ctl[i];
ioaddr->scr_addr = NULL;
ata_std_ports(ioaddr);
ioaddr->bmdma_addr = base + 8 * i;

ata_port_pbar_desc(ap, 4, -1, "ioport");
ata_port_pbar_desc(ap, 4, offset_cmd[i], "cmd");
}
pci_set_master(pdev);
return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
Expand Down
19 changes: 17 additions & 2 deletions drivers/ata/pata_icside.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ struct pata_icside_info {
unsigned int mwdma_mask;
unsigned int nr_ports;
const struct portinfo *port[2];
unsigned long raw_base;
unsigned long raw_ioc_base;
};

#define ICS_TYPE_A3IN 0
Expand Down Expand Up @@ -392,9 +394,10 @@ static struct ata_port_operations pata_icside_port_ops = {
};

static void __devinit
pata_icside_setup_ioaddr(struct ata_ioports *ioaddr, void __iomem *base,
pata_icside_setup_ioaddr(struct ata_port *ap, void __iomem *base,
const struct portinfo *info)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
void __iomem *cmd = base + info->dataoffset;

ioaddr->cmd_addr = cmd;
Expand All @@ -411,6 +414,13 @@ pata_icside_setup_ioaddr(struct ata_ioports *ioaddr, void __iomem *base,

ioaddr->ctl_addr = base + info->ctrloffset;
ioaddr->altstatus_addr = ioaddr->ctl_addr;

ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx",
info->raw_base + info->dataoffset,
info->raw_base + info->ctrloffset);

if (info->raw_ioc_base)
ata_port_desc(ap, "iocbase 0x%lx", info->raw_ioc_base);
}

static int __devinit pata_icside_register_v5(struct pata_icside_info *info)
Expand All @@ -431,6 +441,8 @@ static int __devinit pata_icside_register_v5(struct pata_icside_info *info)
info->nr_ports = 1;
info->port[0] = &pata_icside_portinfo_v5;

info->raw_base = ecard_resource_start(ec, ECARD_RES_MEMC);

return 0;
}

Expand Down Expand Up @@ -471,6 +483,9 @@ static int __devinit pata_icside_register_v6(struct pata_icside_info *info)
info->port[0] = &pata_icside_portinfo_v6_1;
info->port[1] = &pata_icside_portinfo_v6_2;

info->raw_base = ecard_resource_start(ec, ECARD_RES_EASI);
info->raw_ioc_base = ecard_resource_start(ec, ECARD_RES_IOCFAST);

return icside_dma_init(info);
}

Expand Down Expand Up @@ -507,7 +522,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ops = &pata_icside_port_ops;

pata_icside_setup_ioaddr(&ap->ioaddr, info->base, info->port[i]);
pata_icside_setup_ioaddr(ap, info->base, info->port[i]);
}

return ata_host_activate(host, ec->irq, ata_interrupt, 0,
Expand Down
4 changes: 4 additions & 0 deletions drivers/ata/pata_isapnp.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev

ata_std_ports(&ap->ioaddr);

ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
(unsigned long long)pnp_port_start(idev, 0),
(unsigned long long)pnp_port_start(idev, 1));

/* activate */
return ata_host_activate(host, pnp_irq(idev, 0), ata_interrupt, 0,
&isapnp_sht);
Expand Down
13 changes: 11 additions & 2 deletions drivers/ata/pata_ixp4xx_cf.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,12 @@ static struct ata_port_operations ixp4xx_port_ops = {
};

static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
struct ixp4xx_pata_data *data)
struct ixp4xx_pata_data *data,
unsigned long raw_cs0, unsigned long raw_cs1)
{
unsigned long raw_cmd = raw_cs0;
unsigned long raw_ctl = raw_cs1 + 0x06;

ioaddr->cmd_addr = data->cs0;
ioaddr->altstatus_addr = data->cs1 + 0x06;
ioaddr->ctl_addr = data->cs1 + 0x06;
Expand All @@ -158,7 +162,12 @@ static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
*(unsigned long *)&ioaddr->device_addr ^= 0x03;
*(unsigned long *)&ioaddr->status_addr ^= 0x03;
*(unsigned long *)&ioaddr->command_addr ^= 0x03;

raw_cmd ^= 0x03;
raw_ctl ^= 0x03;
#endif

ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", raw_cmd, raw_ctl);
}

static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
Expand Down Expand Up @@ -203,7 +212,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
ap->pio_mask = 0x1f; /* PIO4 */
ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;

ixp4xx_setup_port(&ap->ioaddr, data);
ixp4xx_setup_port(ap, data, cs0->start, cs1->start);

dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");

Expand Down
Loading

0 comments on commit cbcdd87

Please sign in to comment.