* Re: [PATCH libata-dev-2.6:sil24 01/03] sil24: ignore non-error exception irqs
2005-10-06 2:43 [PATCH libata-dev-2.6:sil24 00/03] sil24: update interrupt handling and implment tf reading Tejun Heo
@ 2005-10-06 2:43 ` Tejun Heo
2005-10-06 9:51 ` Jeff Garzik
2005-10-06 2:43 ` [PATCH libata-dev-2.6:sil24 02/03] sil24: remove CMDERR clearing Tejun Heo
2005-10-06 2:43 ` [PATCH libata-dev-2.6:sil24 03/03] sil24: implement proper TF register reading & caching Tejun Heo
2 siblings, 1 reply; 5+ messages in thread
From: Tejun Heo @ 2005-10-06 2:43 UTC (permalink / raw)
To: jgarzik, efalk; +Cc: linux-ide
01_sil24_ignore-non-error-exception-irqs.patch
Do not error-finish commands for non-error exception irqs -
just ignore them. This is taken from Edward's driver.
Signed-off-by: Tejun Heo <htejun@gmail.com>
sata_sil24.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
Index: work/drivers/scsi/sata_sil24.c
===================================================================
--- work.orig/drivers/scsi/sata_sil24.c 2005-10-06 11:43:17.000000000 +0900
+++ work/drivers/scsi/sata_sil24.c 2005-10-06 11:43:21.000000000 +0900
@@ -489,12 +489,21 @@ static void sil24_error_intr(struct ata_
u32 irq_stat, cmd_err, sstatus, serror;
irq_stat = readl(port + PORT_IRQ_STAT);
+ writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */
+
+ if (!(irq_stat & PORT_IRQ_ERROR)) {
+ /* ignore non-completion, non-error irqs for now */
+ printk(KERN_WARNING DRV_NAME
+ "ata%u: non-error exception irq (irq_stat %x)\n",
+ ap->id, irq_stat);
+ return;
+ }
+
cmd_err = readl(port + PORT_CMD_ERR);
sstatus = readl(port + PORT_SSTATUS);
serror = readl(port + PORT_SERROR);
/* Clear IRQ/errors */
- writel(irq_stat, port + PORT_IRQ_STAT);
if (cmd_err)
writel(cmd_err, port + PORT_CMD_ERR);
if (serror)
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH libata-dev-2.6:sil24 03/03] sil24: implement proper TF register reading & caching
2005-10-06 2:43 [PATCH libata-dev-2.6:sil24 00/03] sil24: update interrupt handling and implment tf reading Tejun Heo
2005-10-06 2:43 ` [PATCH libata-dev-2.6:sil24 01/03] sil24: ignore non-error exception irqs Tejun Heo
2005-10-06 2:43 ` [PATCH libata-dev-2.6:sil24 02/03] sil24: remove CMDERR clearing Tejun Heo
@ 2005-10-06 2:43 ` Tejun Heo
2 siblings, 0 replies; 5+ messages in thread
From: Tejun Heo @ 2005-10-06 2:43 UTC (permalink / raw)
To: jgarzik, efalk; +Cc: linux-ide
03_sil24_add-tf-reading.patch
This patch implements proper TF register reading back and
caching and bumps up version to 0.22. This is taken from
Edward's driver.
Signed-off-by: Tejun Heo <htejun@gmail.com>
sata_sil24.c | 50 +++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 45 insertions(+), 5 deletions(-)
Index: work/drivers/scsi/sata_sil24.c
===================================================================
--- work.orig/drivers/scsi/sata_sil24.c 2005-10-06 11:43:21.000000000 +0900
+++ work/drivers/scsi/sata_sil24.c 2005-10-06 11:43:21.000000000 +0900
@@ -41,7 +41,7 @@
#include <asm/io.h>
#define DRV_NAME "sata_sil24"
-#define DRV_VERSION "0.21" /* Silicon Image's preview driver was 0.10 */
+#define DRV_VERSION "0.22" /* Silicon Image's preview driver was 0.10 */
#define NR_PORTS 4
@@ -216,6 +216,7 @@ struct sil24_cmd_block {
struct sil24_port_priv {
struct sil24_cmd_block *cmd_block; /* 32 cmd blocks */
dma_addr_t cmd_block_dma; /* DMA base addr for them */
+ struct ata_taskfile tf; /* Cached taskfile registers */
};
/* ap->host_set->private_data */
@@ -322,14 +323,25 @@ static struct ata_port_info sil24_port_i
},
};
+static inline void sil24_update_tf(struct ata_port *ap)
+{
+ struct sil24_port_priv *pp = ap->private_data;
+ void *port = (void *)ap->ioaddr.cmd_addr;
+ struct sil24_prb *prb = port;
+
+ ata_tf_from_fis(prb->fis, &pp->tf);
+}
+
static u8 sil24_check_status(struct ata_port *ap)
{
- return ATA_DRDY;
+ struct sil24_port_priv *pp = ap->private_data;
+ return pp->tf.command;
}
static u8 sil24_check_err(struct ata_port *ap)
{
- return 0;
+ struct sil24_port_priv *pp = ap->private_data;
+ return pp->tf.feature;
}
static int sil24_scr_map[] = {
@@ -485,6 +497,7 @@ static void sil24_eng_timeout(struct ata
static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
{
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+ struct sil24_port_priv *pp = ap->private_data;
void *port = (void *)ap->ioaddr.cmd_addr;
u32 irq_stat, cmd_err, sstatus, serror;
@@ -509,8 +522,22 @@ static void sil24_error_intr(struct ata_
" stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
+ if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) {
+ /*
+ * Device is reporting error, tf registers are valid.
+ */
+ sil24_update_tf(ap);
+ } else {
+ /*
+ * Other errors. libata currently doesn't have any
+ * mechanism to report these errors. Just turn on
+ * ATA_ERR.
+ */
+ pp->tf.command = ATA_ERR;
+ }
+
if (qc)
- ata_qc_complete(qc, ATA_ERR);
+ ata_qc_complete(qc, pp->tf.command);
sil24_reset_controller(ap);
}
@@ -523,8 +550,19 @@ static inline void sil24_host_intr(struc
slot_stat = readl(port + PORT_SLOT_STAT);
if (!(slot_stat & HOST_SSTAT_ATTN)) {
+ struct sil24_port_priv *pp = ap->private_data;
+ /*
+ * !HOST_SSAT_ATTN guarantees successful completion,
+ * so reading back tf registers is unnecessary for
+ * most commands. TODO: read tf registers for
+ * commands which require these values on successful
+ * completion (EXECUTE DEVICE DIAGNOSTIC, CHECK POWER,
+ * DEVICE RESET and READ PORT MULTIPLIER (any more?).
+ */
+ sil24_update_tf(ap);
+
if (qc)
- ata_qc_complete(qc, 0);
+ ata_qc_complete(qc, pp->tf.command);
} else
sil24_error_intr(ap, slot_stat);
}
@@ -579,6 +617,8 @@ static int sil24_port_start(struct ata_p
return -ENOMEM;
memset(pp, 0, sizeof(*pp));
+ pp->tf.command = ATA_DRDY;
+
cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
if (!cb) {
kfree(pp);
^ permalink raw reply [flat|nested] 5+ messages in thread