Skip to content

Commit

Permalink
libata: make ->scr_read/write callbacks return error code
Browse files Browse the repository at this point in the history
Convert ->scr_read/write callbacks to return error code to better
indicate failure.  This will help handling of SCR_NOTIFICATION.

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 Jul 20, 2007
1 parent 5335b72 commit da3dbb1
Show file tree
Hide file tree
Showing 15 changed files with 191 additions and 136 deletions.
23 changes: 13 additions & 10 deletions drivers/ata/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ struct ahci_port_priv {
unsigned int ncq_saw_sdb:1;
};

static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
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, u32 val);
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 void ahci_irq_clear(struct ata_port *ap);
Expand Down Expand Up @@ -625,7 +625,7 @@ static void ahci_restore_initial_config(struct ata_host *host)
(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;

Expand All @@ -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_ACTIVE: sc_reg = 3; break;
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,
u32 val)
static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
{
unsigned int sc_reg;

Expand All @@ -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_ACTIVE: sc_reg = 3; break;
default:
return;
return -EINVAL;
}

writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
}

static void ahci_start_engine(struct ata_port *ap)
Expand Down Expand Up @@ -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,
unsigned long deadline)
{
u32 serror;
int rc;

DPRINTK("ENTER\n");
Expand All @@ -1143,7 +1145,8 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
deadline);

/* 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);

Expand Down Expand Up @@ -1265,7 +1268,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
ata_ehi_clear_desc(ehi);

/* 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);

/* analyze @irq_stat */
Expand Down
21 changes: 10 additions & 11 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -5732,10 +5732,8 @@ int sata_scr_valid(struct ata_port *ap)
*/
int sata_scr_read(struct ata_port *ap, int reg, u32 *val)
{
if (sata_scr_valid(ap)) {
*val = ap->ops->scr_read(ap, reg);
return 0;
}
if (sata_scr_valid(ap))
return ap->ops->scr_read(ap, reg, val);
return -EOPNOTSUPP;
}

Expand All @@ -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)
{
if (sata_scr_valid(ap)) {
ap->ops->scr_write(ap, reg, val);
return 0;
}
if (sata_scr_valid(ap))
return ap->ops->scr_write(ap, reg, val);
return -EOPNOTSUPP;
}

Expand All @@ -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 rc;

if (sata_scr_valid(ap)) {
ap->ops->scr_write(ap, reg, val);
ap->ops->scr_read(ap, reg);
return 0;
rc = ap->ops->scr_write(ap, reg, val);
if (rc == 0)
rc = ap->ops->scr_read(ap, reg, &val);
return rc;
}
return -EOPNOTSUPP;
}
Expand Down
16 changes: 8 additions & 8 deletions drivers/ata/sata_inic162x.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,34 +190,34 @@ static void inic_reset_port(void __iomem *port_base)
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 *addr;
u32 val;

if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
return 0xffffffffU;
return -EINVAL;

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 */
if (sc_reg == SCR_ERROR)
val &= ~SERR_PHYRDY_CHG;
return val;
*val &= ~SERR_PHYRDY_CHG;
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 *addr;

if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
return;
return -EINVAL;

addr = scr_addr + scr_map[sc_reg] * 4;
writel(val, scr_addr + scr_map[sc_reg] * 4);
return 0;
}

/*
Expand Down
72 changes: 48 additions & 24 deletions drivers/ata/sata_mv.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,10 +404,10 @@ struct mv_host_priv {
};

static void mv_irq_clear(struct ata_port *ap);
static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
static void 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 void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
static int mv_scr_read(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 int mv5_scr_read(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 void mv_port_stop(struct ata_port *ap);
static void mv_qc_prep(struct ata_queued_cmd *qc);
Expand Down Expand Up @@ -974,22 +974,26 @@ static unsigned int mv_scr_offset(unsigned int sc_reg_in)
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);

if (ofs != 0xffffffffU)
return readl(mv_ap_base(ap) + ofs);
else
return (u32) ofs;
if (ofs != 0xffffffffU) {
*val = readl(mv_ap_base(ap) + ofs);
return 0;
} 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);

if (ofs != 0xffffffffU)
if (ofs != 0xffffffffU) {
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,
Expand Down Expand Up @@ -1752,26 +1756,30 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
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 *addr = mv5_phy_base(mmio, ap->port_no);
unsigned int ofs = mv5_scr_offset(sc_reg_in);

if (ofs != 0xffffffffU)
return readl(addr + ofs);
else
return (u32) ofs;
if (ofs != 0xffffffffU) {
*val = readl(addr + ofs);
return 0;
} 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 *addr = mv5_phy_base(mmio, ap->port_no);
unsigned int ofs = mv5_scr_offset(sc_reg_in);

if (ofs != 0xffffffffU)
if (ofs != 0xffffffffU) {
writelfl(val, addr + ofs);
return 0;
} else
return -EINVAL;
}

static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio)
Expand Down Expand Up @@ -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);

DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
"SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
#ifdef DEBUG
{
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 */
comreset_retry:
Expand All @@ -2175,9 +2191,17 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class,
(retry-- > 0))
goto comreset_retry;

DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
"SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
#ifdef DEBUG
{
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)) {
*class = ATA_DEV_NONE;
Expand Down
16 changes: 9 additions & 7 deletions drivers/ata/sata_nv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_nf2_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 void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static int nv_scr_read (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_thaw(struct ata_port *ap);
Expand Down Expand Up @@ -1393,20 +1393,22 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance)
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)
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)
return;
return -EINVAL;

iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
}

static void nv_nf2_freeze(struct ata_port *ap)
Expand Down
25 changes: 15 additions & 10 deletions drivers/ata/sata_promise.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ struct pdc_port_priv {
dma_addr_t pkt_dma;
};

static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static int pdc_sata_scr_read(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_common_port_start(struct ata_port *ap);
static int pdc_sata_port_start(struct ata_port *ap);
Expand Down Expand Up @@ -427,19 +427,20 @@ static int pdc_sata_cable_detect(struct ata_port *ap)
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)
return 0xffffffffU;
return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
return -EINVAL;
*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,
u32 val)
static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
{
if (sc_reg > SCR_CONTROL)
return;
return -EINVAL;
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
return 0;
}

static void pdc_atapi_pkt(struct ata_queued_cmd *qc)
Expand Down Expand Up @@ -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))
ac_err_mask |= AC_ERR_HOST_BUS;

if (sata_scr_valid(ap))
ehi->serror |= pdc_sata_scr_read(ap, SCR_ERROR);
if (sata_scr_valid(ap)) {
u32 serror;

pdc_sata_scr_read(ap, SCR_ERROR, &serror);
ehi->serror |= serror;
}

qc->err_mask |= ac_err_mask;

Expand Down
Loading

0 comments on commit da3dbb1

Please sign in to comment.