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

Commit dc8dcad8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  sata_via: load DEVICE register when CTL changes
  libata: set device class to NONE if phys_offline
  libata-eh: fix slave link EH action mask handling
  libata: transfer EHI control flags to slave ehc.i
  libata-sff: fix ata_sff_post_internal_cmd()
  libata: initialize port_task when !CONFIG_ATA_SFF
parents fdc76bf9 b78152e9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -5373,6 +5373,8 @@ struct ata_port *ata_port_alloc(struct ata_host *host)

#ifdef CONFIG_ATA_SFF
	INIT_DELAYED_WORK(&ap->port_task, ata_pio_task);
#else
	INIT_DELAYED_WORK(&ap->port_task, NULL);
#endif
	INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
	INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
+17 −9
Original line number Diff line number Diff line
@@ -1206,7 +1206,10 @@ void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,

	ata_eh_clear_action(link, dev, ehi, action);

	if (!(ehc->i.flags & ATA_EHI_QUIET))
	/* About to take EH action, set RECOVERED.  Ignore actions on
	 * slave links as master will do them again.
	 */
	if (!(ehc->i.flags & ATA_EHI_QUIET) && link != ap->slave_link)
		ap->pflags |= ATA_PFLAG_RECOVERED;

	spin_unlock_irqrestore(ap->lock, flags);
@@ -2010,8 +2013,13 @@ void ata_eh_autopsy(struct ata_port *ap)
		struct ata_eh_context *mehc = &ap->link.eh_context;
		struct ata_eh_context *sehc = &ap->slave_link->eh_context;

		/* transfer control flags from master to slave */
		sehc->i.flags |= mehc->i.flags & ATA_EHI_TO_SLAVE_MASK;

		/* perform autopsy on the slave link */
		ata_eh_link_autopsy(ap->slave_link);

		/* transfer actions from slave to master and clear slave */
		ata_eh_about_to_do(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS);
		mehc->i.action		|= sehc->i.action;
		mehc->i.dev_action[1]	|= sehc->i.dev_action[1];
@@ -2447,14 +2455,14 @@ int ata_eh_reset(struct ata_link *link, int classify,
		dev->pio_mode = XFER_PIO_0;
		dev->flags &= ~ATA_DFLAG_SLEEPING;

		if (ata_phys_link_offline(ata_dev_phys_link(dev)))
			continue;

		if (!ata_phys_link_offline(ata_dev_phys_link(dev))) {
			/* apply class override */
			if (lflags & ATA_LFLAG_ASSUME_ATA)
				classes[dev->devno] = ATA_DEV_ATA;
			else if (lflags & ATA_LFLAG_ASSUME_SEMB)
			classes[dev->devno] = ATA_DEV_SEMB_UNSUP; /* not yet */
				classes[dev->devno] = ATA_DEV_SEMB_UNSUP;
		} else
			classes[dev->devno] = ATA_DEV_NONE;
	}

	/* record current link speed */
+10 −1
Original line number Diff line number Diff line
@@ -2153,8 +2153,17 @@ void ata_sff_error_handler(struct ata_port *ap)
 */
void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc)
{
	if (qc->ap->ioaddr.bmdma_addr)
	struct ata_port *ap = qc->ap;
	unsigned long flags;

	spin_lock_irqsave(ap->lock, flags);

	ap->hsm_task_state = HSM_ST_IDLE;

	if (ap->ioaddr.bmdma_addr)
		ata_bmdma_stop(qc);

	spin_unlock_irqrestore(ap->lock, flags);
}

/**
+32 −3
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ enum {
static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
static void svia_noop_freeze(struct ata_port *ap);
static int vt6420_prereset(struct ata_link *link, unsigned long deadline);
static int vt6421_pata_cable_detect(struct ata_port *ap);
@@ -103,21 +104,26 @@ static struct scsi_host_template svia_sht = {
	ATA_BMDMA_SHT(DRV_NAME),
};

static struct ata_port_operations vt6420_sata_ops = {
static struct ata_port_operations svia_base_ops = {
	.inherits		= &ata_bmdma_port_ops,
	.sff_tf_load		= svia_tf_load,
};

static struct ata_port_operations vt6420_sata_ops = {
	.inherits		= &svia_base_ops,
	.freeze			= svia_noop_freeze,
	.prereset		= vt6420_prereset,
};

static struct ata_port_operations vt6421_pata_ops = {
	.inherits		= &ata_bmdma_port_ops,
	.inherits		= &svia_base_ops,
	.cable_detect		= vt6421_pata_cable_detect,
	.set_piomode		= vt6421_set_pio_mode,
	.set_dmamode		= vt6421_set_dma_mode,
};

static struct ata_port_operations vt6421_sata_ops = {
	.inherits		= &ata_bmdma_port_ops,
	.inherits		= &svia_base_ops,
	.scr_read		= svia_scr_read,
	.scr_write		= svia_scr_write,
};
@@ -168,6 +174,29 @@ static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
	return 0;
}

/**
 *	svia_tf_load - send taskfile registers to host controller
 *	@ap: Port to which output is sent
 *	@tf: ATA taskfile register set
 *
 *	Outputs ATA taskfile to standard ATA host controller.
 *
 *	This is to fix the internal bug of via chipsets, which will
 *	reset the device register after changing the IEN bit on ctl
 *	register.
 */
static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
	struct ata_taskfile ttf;

	if (tf->ctl != ap->last_ctl)  {
		ttf = *tf;
		ttf.flags |= ATA_TFLAG_DEVICE;
		tf = &ttf;
	}
	ata_sff_tf_load(ap, tf);
}

static void svia_noop_freeze(struct ata_port *ap)
{
	/* Some VIA controllers choke if ATA_NIEN is manipulated in
+3 −0
Original line number Diff line number Diff line
@@ -340,6 +340,9 @@ enum {

	ATA_EHI_DID_RESET	= ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,

	/* mask of flags to transfer *to* the slave link */
	ATA_EHI_TO_SLAVE_MASK	= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET,

	/* max tries if error condition is still set after ->error_handler */
	ATA_EH_MAX_TRIES	= 5,