Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[PATCH] libata: make ata_set_mode() responsible for failure handling



Make ata_set_mode() responsible for determining whether to take port
or device offline on failure.  ata_dev_set_xfermode() and
ata_dev_set_mode() indicate error to the caller instead of disabling
port directly on failure.  Also, for consistency, ata_dev_present()
check is done in ata_set_mode() instead of ata_dev_set_mode().

Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent fcef978f
Loading
Loading
Loading
Loading
+36 −20
Original line number Diff line number Diff line
@@ -64,7 +64,8 @@
static unsigned int ata_dev_init_params(struct ata_port *ap,
					struct ata_device *dev);
static void ata_set_mode(struct ata_port *ap);
static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
					 struct ata_device *dev);
static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev);

static unsigned int ata_unique_id = 1;
@@ -1742,20 +1743,28 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
	return 0;
}

static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
{
	if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
		return;
	unsigned int err_mask;
	int rc;

	if (dev->xfer_shift == ATA_SHIFT_PIO)
		dev->flags |= ATA_DFLAG_PIO;

	ata_dev_set_xfermode(ap, dev);
	err_mask = ata_dev_set_xfermode(ap, dev);
	if (err_mask) {
		printk(KERN_ERR
		       "ata%u: failed to set xfermode (err_mask=0x%x)\n",
		       ap->id, err_mask);
		return -EIO;
	}

	if (ata_dev_revalidate(ap, dev, 0)) {
		printk(KERN_ERR "ata%u: failed to revalidate after set "
		       "xfermode, disabled\n", ap->id);
		ata_port_disable(ap);
	rc = ata_dev_revalidate(ap, dev, 0);
	if (rc) {
		printk(KERN_ERR
		       "ata%u: failed to revalidate after set xfermode\n",
		       ap->id);
		return rc;
	}

	DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n",
@@ -1764,6 +1773,7 @@ static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
	printk(KERN_INFO "ata%u: dev %u configured for %s\n",
	       ap->id, dev->devno,
	       ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode)));
	return 0;
}

static int ata_host_set_pio(struct ata_port *ap)
@@ -1847,11 +1857,15 @@ static void ata_set_mode(struct ata_port *ap)
	ata_host_set_dma(ap);

	/* step 4: update devices' xfer mode */
	for (i = 0; i < ATA_MAX_DEVICES; i++)
		ata_dev_set_mode(ap, &ap->device[i]);
	for (i = 0; i < ATA_MAX_DEVICES; i++) {
		struct ata_device *dev = &ap->device[i];

	if (ap->flags & ATA_FLAG_PORT_DISABLED)
		return;
		if (!ata_dev_present(dev))
			continue;

		if (ata_dev_set_mode(ap, dev))
			goto err_out;
	}

	if (ap->ops->post_set_mode)
		ap->ops->post_set_mode(ap);
@@ -2724,11 +2738,16 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
 *
 *	LOCKING:
 *	PCI/etc. bus probe sem.
 *
 *	RETURNS:
 *	0 on success, AC_ERR_* mask otherwise.
 */

static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
					 struct ata_device *dev)
{
	struct ata_taskfile tf;
	unsigned int err_mask;

	/* set up set-features taskfile */
	DPRINTK("set features - xfer mode\n");
@@ -2740,13 +2759,10 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
	tf.protocol = ATA_PROT_NODATA;
	tf.nsect = dev->xfer_mode;

	if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) {
		printk(KERN_ERR "ata%u: failed to set xfermode, disabled\n",
		       ap->id);
		ata_port_disable(ap);
	}
	err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);

	DPRINTK("EXIT\n");
	DPRINTK("EXIT, err_mask=%x\n", err_mask);
	return err_mask;
}

/**