Commit da3dbb17 authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik

libata: make ->scr_read/write callbacks return error code

Convert ->scr_read/write callbacks to return error code to better
indicate failure.  This will help handling of SCR_NOTIFICATION.
Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 5335b729
...@@ -216,8 +216,8 @@ struct ahci_port_priv { ...@@ -216,8 +216,8 @@ struct ahci_port_priv {
unsigned int ncq_saw_sdb:1; unsigned int ncq_saw_sdb:1;
}; };
static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
static void ahci_irq_clear(struct ata_port *ap); static void ahci_irq_clear(struct ata_port *ap);
...@@ -625,7 +625,7 @@ static void ahci_restore_initial_config(struct ata_host *host) ...@@ -625,7 +625,7 @@ 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 u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
{ {
unsigned int sc_reg; unsigned int sc_reg;
...@@ -635,15 +635,15 @@ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) ...@@ -635,15 +635,15 @@ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
case SCR_ERROR: sc_reg = 2; break; case SCR_ERROR: sc_reg = 2; break;
case SCR_ACTIVE: sc_reg = 3; break; case SCR_ACTIVE: sc_reg = 3; break;
default: default:
return 0xffffffffU; return -EINVAL;
} }
return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
} }
static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
u32 val)
{ {
unsigned int sc_reg; unsigned int sc_reg;
...@@ -653,10 +653,11 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, ...@@ -653,10 +653,11 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
case SCR_ERROR: sc_reg = 2; break; case SCR_ERROR: sc_reg = 2; break;
case SCR_ACTIVE: sc_reg = 3; break; case SCR_ACTIVE: sc_reg = 3; break;
default: default:
return; return -EINVAL;
} }
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
} }
static void ahci_start_engine(struct ata_port *ap) static void ahci_start_engine(struct ata_port *ap)
...@@ -1133,6 +1134,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class, ...@@ -1133,6 +1134,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class,
static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class, static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
unsigned long deadline) unsigned long deadline)
{ {
u32 serror;
int rc; int rc;
DPRINTK("ENTER\n"); DPRINTK("ENTER\n");
...@@ -1143,7 +1145,8 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class, ...@@ -1143,7 +1145,8 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
deadline); deadline);
/* vt8251 needs SError cleared for the port to operate */ /* vt8251 needs SError cleared for the port to operate */
ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR)); ahci_scr_read(ap, SCR_ERROR, &serror);
ahci_scr_write(ap, SCR_ERROR, serror);
ahci_start_engine(ap); ahci_start_engine(ap);
...@@ -1265,7 +1268,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) ...@@ -1265,7 +1268,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
ata_ehi_clear_desc(ehi); ata_ehi_clear_desc(ehi);
/* AHCI needs SError cleared; otherwise, it might lock up */ /* AHCI needs SError cleared; otherwise, it might lock up */
serror = ahci_scr_read(ap, SCR_ERROR); ahci_scr_read(ap, SCR_ERROR, &serror);
ahci_scr_write(ap, SCR_ERROR, serror); ahci_scr_write(ap, SCR_ERROR, serror);
/* analyze @irq_stat */ /* analyze @irq_stat */
......
...@@ -5732,10 +5732,8 @@ int sata_scr_valid(struct ata_port *ap) ...@@ -5732,10 +5732,8 @@ int sata_scr_valid(struct ata_port *ap)
*/ */
int sata_scr_read(struct ata_port *ap, int reg, u32 *val) int sata_scr_read(struct ata_port *ap, int reg, u32 *val)
{ {
if (sata_scr_valid(ap)) { if (sata_scr_valid(ap))
*val = ap->ops->scr_read(ap, reg); return ap->ops->scr_read(ap, reg, val);
return 0;
}
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -5757,10 +5755,8 @@ int sata_scr_read(struct ata_port *ap, int reg, u32 *val) ...@@ -5757,10 +5755,8 @@ int sata_scr_read(struct ata_port *ap, int reg, u32 *val)
*/ */
int sata_scr_write(struct ata_port *ap, int reg, u32 val) int sata_scr_write(struct ata_port *ap, int reg, u32 val)
{ {
if (sata_scr_valid(ap)) { if (sata_scr_valid(ap))
ap->ops->scr_write(ap, reg, val); return ap->ops->scr_write(ap, reg, val);
return 0;
}
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -5781,10 +5777,13 @@ int sata_scr_write(struct ata_port *ap, int reg, u32 val) ...@@ -5781,10 +5777,13 @@ int sata_scr_write(struct ata_port *ap, int reg, u32 val)
*/ */
int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val) int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val)
{ {
int rc;
if (sata_scr_valid(ap)) { if (sata_scr_valid(ap)) {
ap->ops->scr_write(ap, reg, val); rc = ap->ops->scr_write(ap, reg, val);
ap->ops->scr_read(ap, reg); if (rc == 0)
return 0; rc = ap->ops->scr_read(ap, reg, &val);
return rc;
} }
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
...@@ -190,34 +190,34 @@ static void inic_reset_port(void __iomem *port_base) ...@@ -190,34 +190,34 @@ static void inic_reset_port(void __iomem *port_base)
writew(ctl, idma_ctl); writew(ctl, idma_ctl);
} }
static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg) static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
{ {
void __iomem *scr_addr = ap->ioaddr.scr_addr; void __iomem *scr_addr = ap->ioaddr.scr_addr;
void __iomem *addr; void __iomem *addr;
u32 val;
if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
return 0xffffffffU; return -EINVAL;
addr = scr_addr + scr_map[sc_reg] * 4; addr = scr_addr + scr_map[sc_reg] * 4;
val = readl(scr_addr + scr_map[sc_reg] * 4); *val = readl(scr_addr + scr_map[sc_reg] * 4);
/* this controller has stuck DIAG.N, ignore it */ /* this controller has stuck DIAG.N, ignore it */
if (sc_reg == SCR_ERROR) if (sc_reg == SCR_ERROR)
val &= ~SERR_PHYRDY_CHG; *val &= ~SERR_PHYRDY_CHG;
return val; return 0;
} }
static void inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) static int inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
{ {
void __iomem *scr_addr = ap->ioaddr.scr_addr; void __iomem *scr_addr = ap->ioaddr.scr_addr;
void __iomem *addr; void __iomem *addr;
if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
return; return -EINVAL;
addr = scr_addr + scr_map[sc_reg] * 4; addr = scr_addr + scr_map[sc_reg] * 4;
writel(val, scr_addr + scr_map[sc_reg] * 4); writel(val, scr_addr + scr_map[sc_reg] * 4);
return 0;
} }
/* /*
......
...@@ -404,10 +404,10 @@ struct mv_host_priv { ...@@ -404,10 +404,10 @@ struct mv_host_priv {
}; };
static void mv_irq_clear(struct ata_port *ap); static void mv_irq_clear(struct ata_port *ap);
static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in); static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val);
static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in); static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val);
static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
static int mv_port_start(struct ata_port *ap); static int mv_port_start(struct ata_port *ap);
static void mv_port_stop(struct ata_port *ap); static void mv_port_stop(struct ata_port *ap);
static void mv_qc_prep(struct ata_queued_cmd *qc); static void mv_qc_prep(struct ata_queued_cmd *qc);
...@@ -974,22 +974,26 @@ static unsigned int mv_scr_offset(unsigned int sc_reg_in) ...@@ -974,22 +974,26 @@ static unsigned int mv_scr_offset(unsigned int sc_reg_in)
return ofs; return ofs;
} }
static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in) static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
{ {
unsigned int ofs = mv_scr_offset(sc_reg_in); unsigned int ofs = mv_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU) if (ofs != 0xffffffffU) {
return readl(mv_ap_base(ap) + ofs); *val = readl(mv_ap_base(ap) + ofs);
else return 0;
return (u32) ofs; } else
return -EINVAL;
} }
static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
{ {
unsigned int ofs = mv_scr_offset(sc_reg_in); unsigned int ofs = mv_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU) if (ofs != 0xffffffffU) {
writelfl(val, mv_ap_base(ap) + ofs); writelfl(val, mv_ap_base(ap) + ofs);
return 0;
} else
return -EINVAL;
} }
static void mv_edma_cfg(struct ata_port *ap, struct mv_host_priv *hpriv, static void mv_edma_cfg(struct ata_port *ap, struct mv_host_priv *hpriv,
...@@ -1752,26 +1756,30 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in) ...@@ -1752,26 +1756,30 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
return ofs; return ofs;
} }
static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in) static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
{ {
void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
void __iomem *addr = mv5_phy_base(mmio, ap->port_no); void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
unsigned int ofs = mv5_scr_offset(sc_reg_in); unsigned int ofs = mv5_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU) if (ofs != 0xffffffffU) {
return readl(addr + ofs); *val = readl(addr + ofs);
else return 0;
return (u32) ofs; } else
return -EINVAL;
} }
static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
{ {
void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
void __iomem *addr = mv5_phy_base(mmio, ap->port_no); void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
unsigned int ofs = mv5_scr_offset(sc_reg_in); unsigned int ofs = mv5_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU) if (ofs != 0xffffffffU) {
writelfl(val, addr + ofs); writelfl(val, addr + ofs);
return 0;
} else
return -EINVAL;
} }
static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio) static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio)
...@@ -2149,9 +2157,17 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class, ...@@ -2149,9 +2157,17 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class,
VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio); VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio);
DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " #ifdef DEBUG
"SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), {
mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); u32 sstatus, serror, scontrol;
mv_scr_read(ap, SCR_STATUS, &sstatus);
mv_scr_read(ap, SCR_ERROR, &serror);
mv_scr_read(ap, SCR_CONTROL, &scontrol);
DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
"SCtrl 0x%08x\n", status, serror, scontrol);
}
#endif
/* Issue COMRESET via SControl */ /* Issue COMRESET via SControl */
comreset_retry: comreset_retry:
...@@ -2175,9 +2191,17 @@ comreset_retry: ...@@ -2175,9 +2191,17 @@ comreset_retry:
(retry-- > 0)) (retry-- > 0))
goto comreset_retry; goto comreset_retry;
DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " #ifdef DEBUG
"SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), {
mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); u32 sstatus, serror, scontrol;
mv_scr_read(ap, SCR_STATUS, &sstatus);
mv_scr_read(ap, SCR_ERROR, &serror);
mv_scr_read(ap, SCR_CONTROL, &scontrol);
DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
"SCtrl 0x%08x\n", sstatus, serror, scontrol);
}
#endif
if (ata_port_offline(ap)) { if (ata_port_offline(ap)) {
*class = ATA_DEV_NONE; *class = ATA_DEV_NONE;
......
...@@ -236,8 +236,8 @@ static void nv_ck804_host_stop(struct ata_host *host); ...@@ -236,8 +236,8 @@ static void nv_ck804_host_stop(struct ata_host *host);
static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance);
static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance); static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance);
static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance);
static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg); static int nv_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val);
static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static void nv_nf2_freeze(struct ata_port *ap); static void nv_nf2_freeze(struct ata_port *ap);
static void nv_nf2_thaw(struct ata_port *ap); static void nv_nf2_thaw(struct ata_port *ap);
...@@ -1393,20 +1393,22 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance) ...@@ -1393,20 +1393,22 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance)
return ret; return ret;
} }
static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg) static int nv_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return 0xffffffffU; return -EINVAL;
return ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); *val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
} }
static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) static int nv_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return; return -EINVAL;
iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
} }
static void nv_nf2_freeze(struct ata_port *ap) static void nv_nf2_freeze(struct ata_port *ap)
......
...@@ -128,8 +128,8 @@ struct pdc_port_priv { ...@@ -128,8 +128,8 @@ struct pdc_port_priv {
dma_addr_t pkt_dma; dma_addr_t pkt_dma;
}; };
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static int pdc_common_port_start(struct ata_port *ap); static int pdc_common_port_start(struct ata_port *ap);
static int pdc_sata_port_start(struct ata_port *ap); static int pdc_sata_port_start(struct ata_port *ap);
...@@ -427,19 +427,20 @@ static int pdc_sata_cable_detect(struct ata_port *ap) ...@@ -427,19 +427,20 @@ static int pdc_sata_cable_detect(struct ata_port *ap)
return ATA_CBL_SATA; return ATA_CBL_SATA;
} }
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return 0xffffffffU; return -EINVAL;
return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
} }
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return; return -EINVAL;
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
} }
static void pdc_atapi_pkt(struct ata_queued_cmd *qc) static void pdc_atapi_pkt(struct ata_queued_cmd *qc)
...@@ -642,8 +643,12 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, ...@@ -642,8 +643,12 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
| PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR)) | PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR))
ac_err_mask |= AC_ERR_HOST_BUS; ac_err_mask |= AC_ERR_HOST_BUS;
if (sata_scr_valid(ap)) if (sata_scr_valid(ap)) {
ehi->serror |= pdc_sata_scr_read(ap, SCR_ERROR); u32 serror;
pdc_sata_scr_read(ap, SCR_ERROR, &serror);
ehi->serror |= serror;
}
qc->err_mask |= ac_err_mask; qc->err_mask |= ac_err_mask;
......
...@@ -111,8 +111,8 @@ struct qs_port_priv { ...@@ -111,8 +111,8 @@ struct qs_port_priv {
qs_state_t state; qs_state_t state;
}; };
static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg); static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static int qs_port_start(struct ata_port *ap); static int qs_port_start(struct ata_port *ap);
static void qs_host_stop(struct ata_host *host); static void qs_host_stop(struct ata_host *host);
...@@ -255,18 +255,20 @@ static void qs_eng_timeout(struct ata_port *ap) ...@@ -255,18 +255,20 @@ static void qs_eng_timeout(struct ata_port *ap)
ata_eng_timeout(ap); ata_eng_timeout(ap);
} }
static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg) static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return ~0U; return -EINVAL;
return readl(ap->ioaddr.scr_addr + (sc_reg * 8)); *val = readl(ap->ioaddr.scr_addr + (sc_reg * 8));
return 0;
} }
static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return; return -EINVAL;
writel(val, ap->ioaddr.scr_addr + (sc_reg * 8)); writel(val, ap->ioaddr.scr_addr + (sc_reg * 8));
return 0;
} }
static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) static unsigned int qs_fill_sg(struct ata_queued_cmd *qc)
......
...@@ -115,8 +115,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); ...@@ -115,8 +115,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static int sil_pci_device_resume(struct pci_dev *pdev); static int sil_pci_device_resume(struct pci_dev *pdev);
#endif #endif
static void sil_dev_config(struct ata_device *dev); static void sil_dev_config(struct ata_device *dev);
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed); static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed);
static void sil_freeze(struct ata_port *ap); static void sil_freeze(struct ata_port *ap);
static void sil_thaw(struct ata_port *ap); static void sil_thaw(struct ata_port *ap);
...@@ -350,19 +350,26 @@ static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_re ...@@ -350,19 +350,26 @@ static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_re
return NULL; return NULL;
} }
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg) static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
{ {
void __iomem *mmio = sil_scr_addr(ap, sc_reg); void __iomem *mmio = sil_scr_addr(ap, sc_reg);
if (mmio)
return readl(mmio); if (mmio) {
return 0xffffffffU; *val = readl(mmio);
return 0;
}
return -EINVAL;
} }
static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
{ {
void __iomem *mmio = sil_scr_addr(ap, sc_reg); void __iomem *mmio = sil_scr_addr(ap, sc_reg);
if (mmio)
if (mmio) {
writel(val, mmio); writel(val, mmio);
return 0;
}
return -EINVAL;
} }
static void sil_host_intr(struct ata_port *ap, u32 bmdma2) static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
...@@ -378,7 +385,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) ...@@ -378,7 +385,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
* controllers continue to assert IRQ as long as * controllers continue to assert IRQ as long as
* SError bits are pending. Clear SError immediately. * SError bits are pending. Clear SError immediately.
*/ */
serror = sil_scr_read(ap, SCR_ERROR); sil_scr_read(ap, SCR_ERROR, &serror);
sil_scr_write(ap, SCR_ERROR, serror); sil_scr_write(ap, SCR_ERROR, serror);
/* Trigger hotplug and accumulate SError only if the /* Trigger hotplug and accumulate SError only if the
......
...@@ -326,8 +326,8 @@ struct sil24_port_priv { ...@@ -326,8 +326,8 @@ struct sil24_port_priv {
static void sil24_dev_config(struct ata_device *dev); static void sil24_dev_config(struct ata_device *dev);
static u8 sil24_check_status(struct ata_port *ap); static u8 sil24_check_status(struct ata_port *ap);
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val);
static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
static void sil24_qc_prep(struct ata_queued_cmd *qc); static void sil24_qc_prep(struct ata_queued_cmd *qc);
static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
...@@ -488,25 +488,30 @@ static int sil24_scr_map[] = { ...@@ -488,25 +488,30 @@ static int sil24_scr_map[] = {
[SCR_ACTIVE] = 3, [SCR_ACTIVE] = 3,
}; };
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg) static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
{ {
void __iomem *scr_addr = ap->ioaddr.scr_addr; void __iomem *scr_addr = ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void __iomem *addr; void __iomem *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4; addr = scr_addr + sil24_scr_map[sc_reg] * 4;
return readl(scr_addr + sil24_scr_map[sc_reg] * 4); *val = readl(scr_addr + sil24_scr_map[sc_reg] * 4);
return 0;
} }
return 0xffffffffU; return -EINVAL;
} }
static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
{ {
void __iomem *scr_addr = ap->ioaddr.scr_addr; void __iomem *scr_addr = ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void __iomem *addr; void __iomem *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4; addr = scr_addr + sil24_scr_map[sc_reg] * 4;
writel(val, scr_addr + sil24_scr_map[sc_reg] * 4); writel(val, scr_addr + sil24_scr_map[sc_reg] * 4);
return 0;
} }
return -EINVAL;
} }
static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf) static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
......
...@@ -64,8 +64,8 @@ enum { ...@@ -64,8 +64,8 @@ enum {
}; };
static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg); static int sis_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val);
static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static const struct pci_device_id sis_pci_tbl[] = { static const struct pci_device_id sis_pci_tbl[] = {
{ PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */ { PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */
...@@ -207,36 +207,37 @@ static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val ...@@ -207,36 +207,37 @@ static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val
pci_write_config_dword(pdev, cfg_addr+0x10, val); pci_write_config_dword(pdev, cfg_addr+0x10, val);
} }
static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg) static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
{ {
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 val, val2 = 0;
u8 pmr; u8 pmr;
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return 0xffffffffU; return -EINVAL;
if (ap->flags & SIS_FLAG_CFGSCR) if (ap->flags & SIS_FLAG_CFGSCR)
return sis_scr_cfg_read(ap, sc_reg); return sis_scr_cfg_read(ap, sc_reg);
pci_read_config_byte(pdev, SIS_PMR, &pmr); pci_read_config_byte(pdev, SIS_PMR, &pmr);
val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); *val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4));
if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || if ((pdev->device == 0x0182) || (pdev->device == 0x0183) ||
(pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED))
val2 = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); *val |= ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10);
*val &= 0xfffffffb;
return (val | val2) & 0xfffffffb; return 0;
} }
static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
{ {
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u8 pmr; u8 pmr;
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return; return -EINVAL;
pci_read_config_byte(pdev, SIS_PMR, &pmr); pci_read_config_byte(pdev, SIS_PMR, &pmr);
...@@ -248,6 +249,7 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) ...@@ -248,6 +249,7 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
(pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED))
iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10);
} }
return 0;
} }
static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
......
...@@ -103,20 +103,21 @@ static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) ...@@ -103,20 +103,21 @@ static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
return 0; return 0;
} }
static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return 0xffffffffU; return -EINVAL;
return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
} }
static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, static int k2_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return; return -EINVAL;
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
} }
......
...@@ -57,8 +57,8 @@ struct uli_priv { ...@@ -57,8 +57,8 @@ struct uli_priv {
}; };
static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg); static int uli_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val);
static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static const struct pci_device_id uli_pci_tbl[] = { static const struct pci_device_id uli_pci_tbl[] = {
{ PCI_VDEVICE(AL, 0x5289), uli_5289 }, { PCI_VDEVICE(AL, 0x5289), uli_5289 },
...@@ -164,20 +164,22 @@ static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val) ...@@ -164,20 +164,22 @@ static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
pci_write_config_dword(pdev, cfg_addr, val); pci_write_config_dword(pdev, cfg_addr, val);
} }
static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg) static int uli_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return 0xffffffffU; return -EINVAL;
return uli_scr_cfg_read(ap, sc_reg); *val = uli_scr_cfg_read(ap, sc_reg);
return 0;
} }
static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) static int uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{ {
if (sc_reg > SCR_CONTROL) //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0 if (sc_reg > SCR_CONTROL) //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0
return; return -EINVAL;
uli_scr_cfg_write(ap, sc_reg, val); uli_scr_cfg_write(ap, sc_reg, val);
return 0;
} }
static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
......
...@@ -72,8 +72,8 @@ enum { ...@@ -72,8 +72,8 @@ enum {
}; };
static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
static void svia_noop_freeze(struct ata_port *ap); static void svia_noop_freeze(struct ata_port *ap);
static void vt6420_error_handler(struct ata_port *ap); static void vt6420_error_handler(struct ata_port *ap);
static int vt6421_pata_cable_detect(struct ata_port *ap); static int vt6421_pata_cable_detect(struct ata_port *ap);
...@@ -249,18 +249,20 @@ MODULE_LICENSE("GPL"); ...@@ -249,18 +249,20 @@ MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, svia_pci_tbl); MODULE_DEVICE_TABLE(pci, svia_pci_tbl);
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg) static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return 0xffffffffU; return -EINVAL;
return ioread32(ap->ioaddr.scr_addr + (4 * sc_reg)); *val = ioread32(ap->ioaddr.scr_addr + (4 * sc_reg));
return 0;
} }
static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return; return -EINVAL;
iowrite32(val, ap->ioaddr.scr_addr + (4 * sc_reg)); iowrite32(val, ap->ioaddr.scr_addr + (4 * sc_reg));
return 0;
} }
static void svia_noop_freeze(struct ata_port *ap) static void svia_noop_freeze(struct ata_port *ap)
...@@ -305,18 +307,19 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline) ...@@ -305,18 +307,19 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline)
/* Resume phy. This is the old SATA resume sequence */ /* Resume phy. This is the old SATA resume sequence */
svia_scr_write(ap, SCR_CONTROL, 0x300); svia_scr_write(ap, SCR_CONTROL, 0x300);
svia_scr_read(ap, SCR_CONTROL); /* flush */ svia_scr_read(ap, SCR_CONTROL, &scontrol); /* flush */
/* wait for phy to become ready, if necessary */ /* wait for phy to become ready, if necessary */
do { do {
msleep(200); msleep(200);
if ((svia_scr_read(ap, SCR_STATUS) & 0xf) != 1) svia_scr_read(ap, SCR_STATUS, &sstatus);
if ((sstatus & 0xf) != 1)
break; break;
} while (time_before(jiffies, timeout)); } while (time_before(jiffies, timeout));
/* open code sata_print_link_status() */ /* open code sata_print_link_status() */
sstatus = svia_scr_read(ap, SCR_STATUS); svia_scr_read(ap, SCR_STATUS, &sstatus);
scontrol = svia_scr_read(ap, SCR_CONTROL); svia_scr_read(ap, SCR_CONTROL, &scontrol);
online = (sstatus & 0xf) == 0x3; online = (sstatus & 0xf) == 0x3;
...@@ -325,7 +328,7 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline) ...@@ -325,7 +328,7 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline)
online ? "up" : "down", sstatus, scontrol); online ? "up" : "down", sstatus, scontrol);
/* SStatus is read one more time */ /* SStatus is read one more time */
svia_scr_read(ap, SCR_STATUS); svia_scr_read(ap, SCR_STATUS, &sstatus);
if (!online) { if (!online) {
/* tell EH to bail */ /* tell EH to bail */
......
...@@ -98,20 +98,21 @@ enum { ...@@ -98,20 +98,21 @@ enum {
VSC_SATA_INT_PHY_CHANGE), VSC_SATA_INT_PHY_CHANGE),
}; };
static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) static int vsc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return 0xffffffffU; return -EINVAL;
return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
} }
static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, static int vsc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return; return -EINVAL;
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
} }
......
...@@ -620,9 +620,8 @@ struct ata_port_operations { ...@@ -620,9 +620,8 @@ struct ata_port_operations {
u8 (*irq_on) (struct ata_port *); u8 (*irq_on) (struct ata_port *);
u8 (*irq_ack) (struct ata_port *ap, unsigned int chk_drq); u8 (*irq_ack) (struct ata_port *ap, unsigned int chk_drq);
u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); int (*scr_read) (struct ata_port *ap, unsigned int sc_reg, u32 *val);
void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, int (*scr_write) (struct ata_port *ap, unsigned int sc_reg, u32 val);
u32 val);
int (*port_suspend) (struct ata_port *ap, pm_message_t mesg); int (*port_suspend) (struct ata_port *ap, pm_message_t mesg);
int (*port_resume) (struct ata_port *ap); int (*port_resume) (struct ata_port *ap);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment