Commit 614f8f50 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev

parents 00ab2f3d c15d85c8
......@@ -614,7 +614,7 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
} else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) {
/* Unable to use DMA due to host limitation */
tf->protocol = ATA_PROT_PIO;
index = dev->multi_count ? 0 : 4;
index = dev->multi_count ? 0 : 8;
} else {
tf->protocol = ATA_PROT_DMA;
index = 16;
......@@ -3357,11 +3357,12 @@ static void ata_pio_error(struct ata_port *ap)
{
struct ata_queued_cmd *qc;
printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL);
if (qc->tf.command != ATA_CMD_PACKET)
printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
/* make sure qc->err_mask is available to
* know what's wrong and recover
*/
......
......@@ -997,6 +997,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
case ATA_CMD_READ_EXT:
case ATA_CMD_WRITE:
case ATA_CMD_WRITE_EXT:
case ATA_CMD_WRITE_FUA_EXT:
mv_crqb_pack_cmd(cw++, tf->hob_nsect, ATA_REG_NSECT, 0);
break;
#ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */
......
......@@ -81,6 +81,19 @@
/* Port stride */
#define VSC_SATA_PORT_OFFSET 0x200
/* Error interrupt status bit offsets */
#define VSC_SATA_INT_ERROR_E_OFFSET 2
#define VSC_SATA_INT_ERROR_P_OFFSET 4
#define VSC_SATA_INT_ERROR_T_OFFSET 5
#define VSC_SATA_INT_ERROR_M_OFFSET 1
#define is_vsc_sata_int_err(port_idx, int_status) \
(int_status & ((1 << (VSC_SATA_INT_ERROR_E_OFFSET + (8 * port_idx))) | \
(1 << (VSC_SATA_INT_ERROR_P_OFFSET + (8 * port_idx))) | \
(1 << (VSC_SATA_INT_ERROR_T_OFFSET + (8 * port_idx))) | \
(1 << (VSC_SATA_INT_ERROR_M_OFFSET + (8 * port_idx))) \
)\
)
static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
......@@ -201,13 +214,28 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance,
struct ata_port *ap;
ap = host_set->ports[i];
if (is_vsc_sata_int_err(i, int_status)) {
u32 err_status;
printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__);
err_status = ap ? vsc_sata_scr_read(ap, SCR_ERROR) : 0;
vsc_sata_scr_write(ap, SCR_ERROR, err_status);
handled++;
}
if (ap && !(ap->flags &
(ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) {
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && (!(qc->tf.ctl & ATA_NIEN)))
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
handled += ata_host_intr(ap, qc);
} else {
printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__);
ata_chk_status(ap);
handled++;
}
}
}
}
......
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