From: Jeff Garzik Date: Fri, 24 Mar 2006 14:24:04 +0000 (-0500) Subject: Merge branch 'upstream' X-Git-Tag: v2.6.18-rc1~1079^2~98^2~13^2~32 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=11ed56fb7899f9eb9eaef8e5919db1bf08f1b07e;p=karo-tx-linux.git Merge branch 'upstream' Conflicts: drivers/scsi/sata_vsc.c --- 11ed56fb7899f9eb9eaef8e5919db1bf08f1b07e diff --cc drivers/scsi/sata_vsc.c index 5845758e9a69,9701a806539d..8c818d47c1fd --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c @@@ -215,22 -221,30 +221,38 @@@ static irqreturn_t vsc_sata_interrupt ( 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)) { + 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.flags & ATA_TFLAG_POLLING))) handled += ata_host_intr(ap, qc); - else { - printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); + } else if (is_vsc_sata_int_err(i, int_status)) { + /* + * On some chips (i.e. Intel 31244), an error + * interrupt will sneak in at initialization + * time (phy state changes). Clearing the SCR + * error register is not required, but it prevents + * the phy state change interrupts from recurring + * later. + */ + u32 err_status; + err_status = vsc_sata_scr_read(ap, SCR_ERROR); + printk(KERN_DEBUG "%s: clearing interrupt, " + "status %x; sata err status %x\n", + __FUNCTION__, + int_status, err_status); + vsc_sata_scr_write(ap, SCR_ERROR, err_status); + /* Clear interrupt status */ ata_chk_status(ap); handled++; }