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) ...@@ -614,7 +614,7 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
} else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) { } else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) {
/* Unable to use DMA due to host limitation */ /* Unable to use DMA due to host limitation */
tf->protocol = ATA_PROT_PIO; tf->protocol = ATA_PROT_PIO;
index = dev->multi_count ? 0 : 4; index = dev->multi_count ? 0 : 8;
} else { } else {
tf->protocol = ATA_PROT_DMA; tf->protocol = ATA_PROT_DMA;
index = 16; index = 16;
...@@ -3357,11 +3357,12 @@ static void ata_pio_error(struct ata_port *ap) ...@@ -3357,11 +3357,12 @@ static void ata_pio_error(struct ata_port *ap)
{ {
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL); 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 /* make sure qc->err_mask is available to
* know what's wrong and recover * know what's wrong and recover
*/ */
......
...@@ -997,6 +997,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) ...@@ -997,6 +997,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
case ATA_CMD_READ_EXT: case ATA_CMD_READ_EXT:
case ATA_CMD_WRITE: case ATA_CMD_WRITE:
case ATA_CMD_WRITE_EXT: case ATA_CMD_WRITE_EXT:
case ATA_CMD_WRITE_FUA_EXT:
mv_crqb_pack_cmd(cw++, tf->hob_nsect, ATA_REG_NSECT, 0); mv_crqb_pack_cmd(cw++, tf->hob_nsect, ATA_REG_NSECT, 0);
break; break;
#ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */ #ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */
......
...@@ -81,6 +81,19 @@ ...@@ -81,6 +81,19 @@
/* Port stride */ /* Port stride */
#define VSC_SATA_PORT_OFFSET 0x200 #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) 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, ...@@ -201,13 +214,28 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance,
struct ata_port *ap; struct ata_port *ap;
ap = host_set->ports[i]; 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 & if (ap && !(ap->flags &
(ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) {
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag); 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); 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