diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2006-02-20 05:13:31 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-20 05:13:31 -0500 |
commit | ff607748590fba14aecedb0d50edc4ada98d4302 (patch) | |
tree | 986e0a3abe922713069a8e8bc913043fed89a39a /drivers/scsi/sata_vsc.c | |
parent | db024d5398cd332023896caf70530564b15ec88e (diff) | |
parent | 6aff8f1f07a7fff48121d1ad4a550f3af24ccc81 (diff) |
Merge branch 'upstream'
Diffstat (limited to 'drivers/scsi/sata_vsc.c')
-rw-r--r-- | drivers/scsi/sata_vsc.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 976a6b124af9..2d448e84889c 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c | |||
@@ -81,6 +81,19 @@ | |||
81 | /* Port stride */ | 81 | /* Port stride */ |
82 | #define VSC_SATA_PORT_OFFSET 0x200 | 82 | #define VSC_SATA_PORT_OFFSET 0x200 |
83 | 83 | ||
84 | /* Error interrupt status bit offsets */ | ||
85 | #define VSC_SATA_INT_ERROR_E_OFFSET 2 | ||
86 | #define VSC_SATA_INT_ERROR_P_OFFSET 4 | ||
87 | #define VSC_SATA_INT_ERROR_T_OFFSET 5 | ||
88 | #define VSC_SATA_INT_ERROR_M_OFFSET 1 | ||
89 | #define is_vsc_sata_int_err(port_idx, int_status) \ | ||
90 | (int_status & ((1 << (VSC_SATA_INT_ERROR_E_OFFSET + (8 * port_idx))) | \ | ||
91 | (1 << (VSC_SATA_INT_ERROR_P_OFFSET + (8 * port_idx))) | \ | ||
92 | (1 << (VSC_SATA_INT_ERROR_T_OFFSET + (8 * port_idx))) | \ | ||
93 | (1 << (VSC_SATA_INT_ERROR_M_OFFSET + (8 * port_idx))) \ | ||
94 | )\ | ||
95 | ) | ||
96 | |||
84 | 97 | ||
85 | static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | 98 | static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) |
86 | { | 99 | { |
@@ -201,13 +214,27 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, | |||
201 | struct ata_port *ap; | 214 | struct ata_port *ap; |
202 | 215 | ||
203 | ap = host_set->ports[i]; | 216 | ap = host_set->ports[i]; |
204 | if (ap && | 217 | |
205 | !(ap->flags & ATA_FLAG_PORT_DISABLED)) { | 218 | if (is_vsc_sata_int_err(i, int_status)) { |
219 | u32 err_status; | ||
220 | printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); | ||
221 | err_status = ap ? vsc_sata_scr_read(ap, SCR_ERROR) : 0; | ||
222 | vsc_sata_scr_write(ap, SCR_ERROR, err_status); | ||
223 | handled++; | ||
224 | } | ||
225 | |||
226 | if (ap && !(ap->flags & ATA_FLAG_PORT_DISABLED)) { | ||
206 | struct ata_queued_cmd *qc; | 227 | struct ata_queued_cmd *qc; |
207 | 228 | ||
208 | qc = ata_qc_from_tag(ap, ap->active_tag); | 229 | qc = ata_qc_from_tag(ap, ap->active_tag); |
209 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) | 230 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) |
210 | handled += ata_host_intr(ap, qc); | 231 | handled += ata_host_intr(ap, qc); |
232 | } else { | ||
233 | printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); | ||
234 | ata_chk_status(ap); | ||
235 | handled++; | ||
236 | } | ||
237 | |||
211 | } | 238 | } |
212 | } | 239 | } |
213 | } | 240 | } |