lkml.org 
[lkml]   [2006]   [Nov]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patches in this message
/
Date
From
SubjectRe: qstor driver -> irq 193: nobody cared
Alberto Alonso wrote:
> Sounds good, let me know if you need me to do any
> testing or help on the programming.

Okay, try this (untested) and see if it cleans things up.
I'm also including the old "printk" patch, so that we can
tell whether the "fix" is actually working or not.

Thanks
--- old/drivers/scsi/sata_qstor.c 2006-09-19 23:42:06.000000000 -0400
+++ linux/drivers/scsi/sata_qstor.c 2006-11-06 09:50:02.000000000 -0500
@@ -459,6 +459,7 @@
{
struct ata_host_set *host_set = dev_instance;
unsigned int handled = 0;
+ static int spurious = 0;

VPRINTK("ENTER\n");

@@ -466,6 +467,20 @@
handled = qs_intr_pkt(host_set) | qs_intr_mmio(host_set);
spin_unlock(&host_set->lock);

+ /* There are reports of at least one system with glitchy interrupts,
+ * and if we return !handled here for those then the kernel may totally
+ * disable our own IRQ line (duh!).
+ * So, try and be tolerant, but not *too* tolerant.
+ */
+ if (!handled) {
+ if (spurious < 10) {
+ printk("sata_qstor: spurious=%d\n", spurious);
+ ++spurious;
+ handled = 1;
+ }
+ } else if (spurious)
+ --spurious;
+
VPRINTK("EXIT\n");

return IRQ_RETVAL(handled);--- old/drivers/scsi/sata_qstor.c 2006-11-14 11:30:37.000000000 -0500
+++ linux/drivers/scsi/sata_qstor.c 2006-11-14 13:22:05.000000000 -0500
@@ -299,6 +299,19 @@
return nelem;
}

+static void qs_set_nien (struct ata_port *ap, int new_nien)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+
+ if ((ap->ctl & ATA_NIEN) != new_nien) {
+ ap->ctl = (ap->ctl & ~ATA_NIEN) | new_nien;
+ ap->last_ctl = ap->ctl;
+ writeb(ap->ctl, (void __iomem *)ioaddr->ctl_addr);
+ wmb();
+ ata_check_status(ap);
+ }
+}
+
static void qs_qc_prep(struct ata_queued_cmd *qc)
{
struct qs_port_priv *pp = qc->ap->private_data;
@@ -357,6 +370,8 @@

switch (qc->tf.protocol) {
case ATA_PROT_DMA:
+ /* packet mode requires that the NIEN bit be turned on */
+ qs_set_nien(qc->ap, ATA_NIEN);

pp->state = qs_state_pkt;
qs_packet_start(qc);
@@ -370,6 +385,7 @@
break;
}

+ qs_set_nien(qc->ap, 0); // FIXME: is this necessary here?
pp->state = qs_state_mmio;
return ata_qc_issue_prot(qc);
}
\
 
 \ /
  Last update: 2006-11-14 19:27    [W:2.268 / U:0.500 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site