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

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
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -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);
@@ -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;

@@ -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;

@@ -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)
@@ -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");
@@ -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);

@@ -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 */
+10 −11
Original line number Diff line number Diff line
@@ -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;
}

@@ -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;
}

@@ -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;
}
+8 −8
Original line number Diff line number Diff line
@@ -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;
}

/*
+48 −24
Original line number Diff line number Diff line
@@ -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);
@@ -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,
@@ -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)
@@ -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);

#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", mv_scr_read(ap, SCR_STATUS),
		mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
			"SCtrl 0x%08x\n", status, serror, scontrol);
	}
#endif

	/* Issue COMRESET via SControl */
comreset_retry:
@@ -2175,9 +2191,17 @@ comreset_retry:
	    (retry-- > 0))
		goto comreset_retry;

#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", mv_scr_read(ap, SCR_STATUS),
		mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
			"SCtrl 0x%08x\n", sstatus, serror, scontrol);
	}
#endif

	if (ata_port_offline(ap)) {
		*class = ATA_DEV_NONE;
+9 −7
Original line number Diff line number Diff line
@@ -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);
@@ -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)
Loading