Re: qstor driver -> irq 193: nobody cared

From: Mark Lord
Date: Thu Nov 16 2006 - 08:55:00 EST


Alberto Alonso wrote:
Sorry for the long delay, I've been called on too
many issues at work this week.

Anyway, the patch basically made the drives not usable.

Mmm.. Okay, thanks for helping track this down.

It appears that this got broken when the ATA_TFLAG_POLLING
got introduced into libata, replacing previous checks of ATA_NIEN.
Or maybe even before that. Not many of us have qstor cards!

Speaking of which, I'll dig my own qstor card out of mothballs soon,
and work out a proper fix for it soon-ish.

In the meanwhile, could you take a clean kernel, and apply the first
attached patch (qstor_spurious_1.patch), and see if it fixes things.

If not, then you can instead apply the second patch (qstor_spurious_kludge.patch)
and your problems should disappear. But I cannot actually push that rubbish
upstream, so a "proper" fix will have to come later.

Cheers --- linux/drivers/scsi/sata_qstor.c.orig 2006-09-19 23:42:06.000000000 -0400
+++ linux/drivers/scsi/sata_qstor.c 2006-11-16 08:46:43.000000000 -0500
@@ -399,6 +399,7 @@
if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
struct ata_queued_cmd *qc;
struct qs_port_priv *pp = ap->private_data;
+ ata_check_status(ap); /* kill spurious ints */
if (!pp || pp->state != qs_state_pkt)
continue;
qc = ata_qc_from_tag(ap, ap->active_tag);
--- linux/drivers/scsi/sata_qstor.c.orig 2006-09-19 23:42:06.000000000 -0400
+++ linux/drivers/scsi/sata_qstor.c 2006-11-16 08:49:57.000000000 -0500
@@ -423,7 +423,7 @@

static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
{
- unsigned int handled = 0, port_no;
+ unsigned int handled = 1, port_no;

for (port_no = 0; port_no < host_set->n_ports; ++port_no) {
struct ata_port *ap;
@@ -432,13 +432,13 @@
!(ap->flags & ATA_FLAG_DISABLED)) {
struct ata_queued_cmd *qc;
struct qs_port_priv *pp = ap->private_data;
+ u8 status = ata_check_status(ap);
if (!pp || pp->state != qs_state_mmio)
continue;
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {

/* check main status, clearing INTRQ */
- u8 status = ata_check_status(ap);
if ((status & ATA_BUSY))
continue;
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",