mirror of https://gitee.com/openkylin/linux.git
ahci: implement SCR_NOTIFICATION r/w
Make ahci_scr_read/write() handle SCR_NOTIFICATION if the controller supports it. Also, print "sntf" in the cap line if supported. While at it, convert eight space into a tab in ahci_print_info(). Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
274c1fde5c
commit
203ef6c456
|
@ -99,6 +99,7 @@ enum {
|
||||||
HOST_CAP_SSC = (1 << 14), /* Slumber capable */
|
HOST_CAP_SSC = (1 << 14), /* Slumber capable */
|
||||||
HOST_CAP_CLO = (1 << 24), /* Command List Override support */
|
HOST_CAP_CLO = (1 << 24), /* Command List Override support */
|
||||||
HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
|
HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
|
||||||
|
HOST_CAP_SNTF = (1 << 29), /* SNotification register */
|
||||||
HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */
|
HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */
|
||||||
HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */
|
HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */
|
||||||
|
|
||||||
|
@ -113,11 +114,11 @@ enum {
|
||||||
PORT_TFDATA = 0x20, /* taskfile data */
|
PORT_TFDATA = 0x20, /* taskfile data */
|
||||||
PORT_SIG = 0x24, /* device TF signature */
|
PORT_SIG = 0x24, /* device TF signature */
|
||||||
PORT_CMD_ISSUE = 0x38, /* command issue */
|
PORT_CMD_ISSUE = 0x38, /* command issue */
|
||||||
PORT_SCR = 0x28, /* SATA phy register block */
|
|
||||||
PORT_SCR_STAT = 0x28, /* SATA phy register: SStatus */
|
PORT_SCR_STAT = 0x28, /* SATA phy register: SStatus */
|
||||||
PORT_SCR_CTL = 0x2c, /* SATA phy register: SControl */
|
PORT_SCR_CTL = 0x2c, /* SATA phy register: SControl */
|
||||||
PORT_SCR_ERR = 0x30, /* SATA phy register: SError */
|
PORT_SCR_ERR = 0x30, /* SATA phy register: SError */
|
||||||
PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */
|
PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */
|
||||||
|
PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */
|
||||||
|
|
||||||
/* PORT_IRQ_{STAT,MASK} bits */
|
/* PORT_IRQ_{STAT,MASK} bits */
|
||||||
PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */
|
PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */
|
||||||
|
@ -631,40 +632,46 @@ static void ahci_restore_initial_config(struct ata_host *host)
|
||||||
(void) readl(mmio + HOST_PORTS_IMPL); /* flush */
|
(void) readl(mmio + HOST_PORTS_IMPL); /* flush */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
|
static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg)
|
||||||
{
|
{
|
||||||
unsigned int sc_reg;
|
static const int offset[] = {
|
||||||
|
[SCR_STATUS] = PORT_SCR_STAT,
|
||||||
|
[SCR_CONTROL] = PORT_SCR_CTL,
|
||||||
|
[SCR_ERROR] = PORT_SCR_ERR,
|
||||||
|
[SCR_ACTIVE] = PORT_SCR_ACT,
|
||||||
|
[SCR_NOTIFICATION] = PORT_SCR_NTF,
|
||||||
|
};
|
||||||
|
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||||
|
|
||||||
switch (sc_reg_in) {
|
if (sc_reg < ARRAY_SIZE(offset) &&
|
||||||
case SCR_STATUS: sc_reg = 0; break;
|
(sc_reg != SCR_NOTIFICATION || (hpriv->cap & HOST_CAP_SNTF)))
|
||||||
case SCR_CONTROL: sc_reg = 1; break;
|
return offset[sc_reg];
|
||||||
case SCR_ERROR: sc_reg = 2; break;
|
|
||||||
case SCR_ACTIVE: sc_reg = 3; break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*val = readl(ap->ioaddr.scr_addr + (sc_reg * 4));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
|
||||||
static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
|
|
||||||
{
|
{
|
||||||
unsigned int sc_reg;
|
void __iomem *port_mmio = ahci_port_base(ap);
|
||||||
|
int offset = ahci_scr_offset(ap, sc_reg);
|
||||||
|
|
||||||
switch (sc_reg_in) {
|
if (offset) {
|
||||||
case SCR_STATUS: sc_reg = 0; break;
|
*val = readl(port_mmio + offset);
|
||||||
case SCR_CONTROL: sc_reg = 1; break;
|
return 0;
|
||||||
case SCR_ERROR: sc_reg = 2; break;
|
}
|
||||||
case SCR_ACTIVE: sc_reg = 3; break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
|
static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
|
||||||
|
{
|
||||||
|
void __iomem *port_mmio = ahci_port_base(ap);
|
||||||
|
int offset = ahci_scr_offset(ap, sc_reg);
|
||||||
|
|
||||||
|
if (offset) {
|
||||||
|
writel(val, port_mmio + offset);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
static void ahci_start_engine(struct ata_port *ap)
|
static void ahci_start_engine(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
|
@ -1768,12 +1775,13 @@ static void ahci_print_info(struct ata_host *host)
|
||||||
|
|
||||||
dev_printk(KERN_INFO, &pdev->dev,
|
dev_printk(KERN_INFO, &pdev->dev,
|
||||||
"flags: "
|
"flags: "
|
||||||
"%s%s%s%s%s%s"
|
"%s%s%s%s%s%s%s"
|
||||||
"%s%s%s%s%s%s%s\n"
|
"%s%s%s%s%s%s%s\n"
|
||||||
,
|
,
|
||||||
|
|
||||||
cap & (1 << 31) ? "64bit " : "",
|
cap & (1 << 31) ? "64bit " : "",
|
||||||
cap & (1 << 30) ? "ncq " : "",
|
cap & (1 << 30) ? "ncq " : "",
|
||||||
|
cap & (1 << 29) ? "sntf " : "",
|
||||||
cap & (1 << 28) ? "ilck " : "",
|
cap & (1 << 28) ? "ilck " : "",
|
||||||
cap & (1 << 27) ? "stag " : "",
|
cap & (1 << 27) ? "stag " : "",
|
||||||
cap & (1 << 26) ? "pm " : "",
|
cap & (1 << 26) ? "pm " : "",
|
||||||
|
@ -1842,10 +1850,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
void __iomem *port_mmio = ahci_port_base(ap);
|
void __iomem *port_mmio = ahci_port_base(ap);
|
||||||
|
|
||||||
/* standard SATA port setup */
|
/* standard SATA port setup */
|
||||||
if (hpriv->port_map & (1 << i)) {
|
if (hpriv->port_map & (1 << i))
|
||||||
ap->ioaddr.cmd_addr = port_mmio;
|
ap->ioaddr.cmd_addr = port_mmio;
|
||||||
ap->ioaddr.scr_addr = port_mmio + PORT_SCR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* disabled/not-implemented port */
|
/* disabled/not-implemented port */
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue