From: "Hervé Poussineau" <hpoussin@reactos.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] ESP: fix irq handling
Date: Thu, 24 Apr 2008 09:44:50 +0200 [thread overview]
Message-ID: <48103A72.3030007@reactos.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 410 bytes --]
Hi,
In ESP SCSI adapter, IRQ line state should always be in sync with the
STAT_INT bit. This patch enforces this, by creating functions to raise
or lower the irq level.
This fixes bugs in do_cmd(), write_response(), esp_mem_readb(),
esp_mem_writeb(), where it was not handled properly.
Also adds IRQ line deassertion at reset.
Finally, rename STAT_IN to STAT_INT, according to datasheet.
Hervé
[-- Attachment #2: esp_interrupt.diff --]
[-- Type: text/plain, Size: 4074 bytes --]
Index: hw/esp.c
===================================================================
--- hw/esp.c (revision 4244)
+++ hw/esp.c (working copy)
@@ -127,7 +127,7 @@
#define STAT_TC 0x10
#define STAT_PE 0x20
#define STAT_GE 0x40
-#define STAT_IN 0x80
+#define STAT_INT 0x80
#define INTR_FC 0x08
#define INTR_BS 0x10
@@ -143,6 +143,22 @@
#define TCHI_FAS100A 0x4
+static void esp_raise_irq(ESPState *s)
+{
+ if (!(s->rregs[ESP_RSTAT] & STAT_INT)) {
+ s->rregs[ESP_RSTAT] |= STAT_INT;
+ qemu_irq_raise(s->irq);
+ }
+}
+
+static void esp_lower_irq(ESPState *s)
+{
+ if (s->rregs[ESP_RSTAT] & STAT_INT) {
+ s->rregs[ESP_RSTAT] &= ~STAT_INT;
+ qemu_irq_lower(s->irq);
+ }
+}
+
static int get_cmd(ESPState *s, uint8_t *buf)
{
uint32_t dmalen;
@@ -171,10 +187,10 @@
if (target >= ESP_MAX_DEVS || !s->scsi_dev[target]) {
// No such drive
- s->rregs[ESP_RSTAT] = STAT_IN;
+ s->rregs[ESP_RSTAT] = 0;
s->rregs[ESP_RINTR] = INTR_DC;
s->rregs[ESP_RSEQ] = SEQ_0;
- qemu_irq_raise(s->irq);
+ esp_raise_irq(s);
return 0;
}
s->current_dev = s->scsi_dev[target];
@@ -191,7 +207,7 @@
datalen = s->current_dev->send_command(s->current_dev, 0, &buf[1], lun);
s->ti_size = datalen;
if (datalen != 0) {
- s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC;
+ s->rregs[ESP_RSTAT] = STAT_TC;
s->dma_left = 0;
s->dma_counter = 0;
if (datalen > 0) {
@@ -204,7 +220,7 @@
}
s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
s->rregs[ESP_RSEQ] = SEQ_CD;
- qemu_irq_raise(s->irq);
+ esp_raise_irq(s);
}
static void handle_satn(ESPState *s)
@@ -223,10 +239,10 @@
if (s->cmdlen) {
DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
s->do_cmd = 1;
- s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC | STAT_CD;
+ s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
s->rregs[ESP_RSEQ] = SEQ_CD;
- qemu_irq_raise(s->irq);
+ esp_raise_irq(s);
}
}
@@ -237,7 +253,7 @@
s->ti_buf[1] = 0;
if (s->dma) {
s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
- s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC | STAT_ST;
+ s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
s->rregs[ESP_RSEQ] = SEQ_CD;
} else {
@@ -246,18 +262,18 @@
s->ti_wptr = 0;
s->rregs[ESP_RFLAGS] = 2;
}
- qemu_irq_raise(s->irq);
+ esp_raise_irq(s);
}
static void esp_dma_done(ESPState *s)
{
- s->rregs[ESP_RSTAT] |= STAT_IN | STAT_TC;
+ s->rregs[ESP_RSTAT] |= STAT_TC;
s->rregs[ESP_RINTR] = INTR_BS;
s->rregs[ESP_RSEQ] = 0;
s->rregs[ESP_RFLAGS] = 0;
s->rregs[ESP_TCLO] = 0;
s->rregs[ESP_TCMID] = 0;
- qemu_irq_raise(s->irq);
+ esp_raise_irq(s);
}
static void esp_do_dma(ESPState *s)
@@ -381,6 +397,8 @@
{
ESPState *s = opaque;
+ esp_lower_irq(s);
+
memset(s->rregs, 0, ESP_REGS);
memset(s->wregs, 0, ESP_REGS);
s->rregs[ESP_TCHI] = TCHI_FAS100A; // Indicate fas100a
@@ -415,7 +433,7 @@
} else {
s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
}
- qemu_irq_raise(s->irq);
+ esp_raise_irq(s);
}
if (s->ti_size == 0) {
s->ti_rptr = 0;
@@ -424,8 +442,8 @@
break;
case ESP_RINTR:
// Clear interrupt/error status bits
- s->rregs[ESP_RSTAT] &= ~(STAT_IN | STAT_GE | STAT_PE);
- qemu_irq_lower(s->irq);
+ s->rregs[ESP_RSTAT] &= ~(STAT_GE | STAT_PE);
+ esp_lower_irq(s);
break;
default:
break;
@@ -487,7 +505,7 @@
DPRINTF("Bus reset (%2.2x)\n", val);
s->rregs[ESP_RINTR] = INTR_RST;
if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
- qemu_irq_raise(s->irq);
+ esp_raise_irq(s);
}
break;
case CMD_TI:
reply other threads:[~2008-04-24 8:17 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48103A72.3030007@reactos.org \
--to=hpoussin@reactos.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.