qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/5] lsi: a bunch of cleanups
@ 2010-01-06 16:07 Gerd Hoffmann
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 1/5] lsi: use QTAILQ for lsi_queue Gerd Hoffmann
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2010-01-06 16:07 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

This patch series brings a few code cleanups to the lsi driver,
check the individual patches for details.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 1/5] lsi: use QTAILQ for lsi_queue
  2010-01-06 16:07 [Qemu-devel] [PATCH 0/5] lsi: a bunch of cleanups Gerd Hoffmann
@ 2010-01-06 16:08 ` Gerd Hoffmann
  2010-01-11 16:02   ` Anthony Liguori
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 2/5] lsi: have lsi_request for the whole life time of the request Gerd Hoffmann
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Gerd Hoffmann @ 2010-01-06 16:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Replace the funky array logic for queued commands with standard
qemu list functions.  Also rename lsi_queue to lsi_request.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/lsi53c895a.c |   68 ++++++++++++++++++++++--------------------------------
 1 files changed, 28 insertions(+), 40 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index e4033b1..71a95f5 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -173,11 +173,12 @@ do { fprintf(stderr, "lsi_scsi: error: " fmt , ## __VA_ARGS__);} while (0)
 /* Flag set if this is a tagged command.  */
 #define LSI_TAG_VALID     (1 << 16)
 
-typedef struct {
+typedef struct lsi_request {
     uint32_t tag;
     uint32_t pending;
     int out;
-} lsi_queue;
+    QTAILQ_ENTRY(lsi_request) next;
+} lsi_request;
 
 typedef struct {
     PCIDevice dev;
@@ -205,9 +206,7 @@ typedef struct {
     uint32_t current_dma_len;
     int command_complete;
     uint8_t *dma_buf;
-    lsi_queue *queue;
-    int queue_len;
-    int active_commands;
+    QTAILQ_HEAD(, lsi_request) queue;
 
     uint32_t dsa;
     uint32_t temp;
@@ -391,9 +390,9 @@ static void lsi_stop_script(LSIState *s)
 
 static void lsi_update_irq(LSIState *s)
 {
-    int i;
     int level;
     static int last_level;
+    lsi_request *p;
 
     /* It's unclear whether the DIP/SIP bits should be cleared when the
        Interrupt Status Registers are cleared or when istat0 is read.
@@ -427,9 +426,9 @@ static void lsi_update_irq(LSIState *s)
     if (!level && lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON)) {
         DPRINTF("Handled IRQs & disconnected, looking for pending "
                 "processes\n");
-        for (i = 0; i < s->active_commands; i++) {
-            if (s->queue[i].pending) {
-                lsi_reselect(s, s->queue[i].tag);
+        QTAILQ_FOREACH(p, &s->queue, next) {
+            if (p->pending) {
+                lsi_reselect(s, p->tag);
                 break;
             }
         }
@@ -563,14 +562,11 @@ static void lsi_do_dma(LSIState *s, int out)
 /* Add a command to the queue.  */
 static void lsi_queue_command(LSIState *s)
 {
-    lsi_queue *p;
+    lsi_request *p;
 
     DPRINTF("Queueing tag=0x%x\n", s->current_tag);
-    if (s->queue_len == s->active_commands) {
-        s->queue_len++;
-        s->queue = qemu_realloc(s->queue, s->queue_len * sizeof(lsi_queue));
-    }
-    p = &s->queue[s->active_commands++];
+    p = qemu_mallocz(sizeof(*p));
+    QTAILQ_INSERT_TAIL(&s->queue, p, next);
     p->tag = s->current_tag;
     p->pending = 0;
     p->out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
@@ -590,17 +586,14 @@ static void lsi_add_msg_byte(LSIState *s, uint8_t data)
 /* Perform reselection to continue a command.  */
 static void lsi_reselect(LSIState *s, uint32_t tag)
 {
-    lsi_queue *p;
-    int n;
+    lsi_request *p;
     int id;
 
-    p = NULL;
-    for (n = 0; n < s->active_commands; n++) {
-        p = &s->queue[n];
+    QTAILQ_FOREACH(p, &s->queue, next) {
         if (p->tag == tag)
             break;
     }
-    if (n == s->active_commands) {
+    if (p == NULL) {
         BADF("Reselected non-existant command tag=0x%x\n", tag);
         return;
     }
@@ -624,10 +617,8 @@ static void lsi_reselect(LSIState *s, uint32_t tag)
         lsi_add_msg_byte(s, tag & 0xff);
     }
 
-    s->active_commands--;
-    if (n != s->active_commands) {
-        s->queue[n] = s->queue[s->active_commands];
-    }
+    QTAILQ_REMOVE(&s->queue, p, next);
+    qemu_free(p);
 
     if (lsi_irq_on_rsl(s)) {
         lsi_script_scsi_interrupt(s, LSI_SIST0_RSL, 0);
@@ -638,10 +629,9 @@ static void lsi_reselect(LSIState *s, uint32_t tag)
    the device was reselected, nonzero if the IO is deferred.  */
 static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
 {
-    lsi_queue *p;
-    int i;
-    for (i = 0; i < s->active_commands; i++) {
-        p = &s->queue[i];
+    lsi_request *p;
+
+    QTAILQ_FOREACH(p, &s->queue, next) {
         if (p->tag == tag) {
             if (p->pending) {
                 BADF("Multiple IO pending for tag %d\n", tag);
@@ -659,7 +649,7 @@ static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
                 lsi_reselect(s, tag);
                 return 0;
             } else {
-               DPRINTF("Queueing IO tag=0x%x\n", tag);
+                DPRINTF("Queueing IO tag=0x%x\n", tag);
                 p->pending = arg;
                 return 1;
             }
@@ -905,13 +895,15 @@ static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count)
 
 static void lsi_wait_reselect(LSIState *s)
 {
-    int i;
+    lsi_request *p;
+
     DPRINTF("Wait Reselect\n");
     if (s->current_dma_len)
         BADF("Reselect with pending DMA\n");
-    for (i = 0; i < s->active_commands; i++) {
-        if (s->queue[i].pending) {
-            lsi_reselect(s, s->queue[i].tag);
+
+    QTAILQ_FOREACH(p, &s->queue, next) {
+        if (p->pending) {
+            lsi_reselect(s, p->tag);
             break;
         }
     }
@@ -2008,7 +2000,7 @@ static void lsi_pre_save(void *opaque)
 
     assert(s->dma_buf == NULL);
     assert(s->current_dma_len == 0);
-    assert(s->active_commands == 0);
+    assert(QTAILQ_EMPTY(&s->queue));
 }
 
 static const VMStateDescription vmstate_lsi_scsi = {
@@ -2101,8 +2093,6 @@ static int lsi_scsi_uninit(PCIDevice *d)
     cpu_unregister_io_memory(s->mmio_io_addr);
     cpu_unregister_io_memory(s->ram_io_addr);
 
-    qemu_free(s->queue);
-
     return 0;
 }
 
@@ -2138,9 +2128,7 @@ static int lsi_scsi_init(PCIDevice *dev)
                            PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_mmio_mapfunc);
     pci_register_bar((struct PCIDevice *)s, 2, 0x2000,
                            PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc);
-    s->queue = qemu_malloc(sizeof(lsi_queue));
-    s->queue_len = 1;
-    s->active_commands = 0;
+    QTAILQ_INIT(&s->queue);
 
     lsi_soft_reset(s);
 
-- 
1.6.5.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 2/5] lsi: have lsi_request for the whole life time of the request.
  2010-01-06 16:07 [Qemu-devel] [PATCH 0/5] lsi: a bunch of cleanups Gerd Hoffmann
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 1/5] lsi: use QTAILQ for lsi_queue Gerd Hoffmann
@ 2010-01-06 16:08 ` Gerd Hoffmann
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 3/5] lsi: move current_dev into lsi_request Gerd Hoffmann
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2010-01-06 16:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Right now lsi_request is allocated when a request is queued and released
when a request is unqueued.  With this patch applied the lsi_request is
kept for the whole lifetime of the scsi request.

Rationale: We can use it for per-request data then.  The patch does that
already for the request tag.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/lsi53c895a.c |   53 ++++++++++++++++++++++++++++++++---------------------
 1 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 71a95f5..e6c13eb 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -202,11 +202,12 @@ typedef struct {
     SCSIDevice *current_dev;
     int current_lun;
     /* The tag is a combination of the device ID and the SCSI tag.  */
-    uint32_t current_tag;
+    uint32_t select_tag;
     uint32_t current_dma_len;
     int command_complete;
     uint8_t *dma_buf;
     QTAILQ_HEAD(, lsi_request) queue;
+    lsi_request *current;
 
     uint32_t dsa;
     uint32_t temp;
@@ -533,7 +534,7 @@ static void lsi_do_dma(LSIState *s, int out)
 
     if (s->dma_buf == NULL) {
         s->dma_buf = s->current_dev->info->get_buf(s->current_dev,
-                                                   s->current_tag);
+                                                   s->current->tag);
     }
 
     /* ??? Set SFBR to first data byte.  */
@@ -547,10 +548,10 @@ static void lsi_do_dma(LSIState *s, int out)
         s->dma_buf = NULL;
         if (out) {
             /* Write the data.  */
-            s->current_dev->info->write_data(s->current_dev, s->current_tag);
+            s->current_dev->info->write_data(s->current_dev, s->current->tag);
         } else {
             /* Request any remaining data.  */
-            s->current_dev->info->read_data(s->current_dev, s->current_tag);
+            s->current_dev->info->read_data(s->current_dev, s->current->tag);
         }
     } else {
         s->dma_buf += count;
@@ -562,12 +563,13 @@ static void lsi_do_dma(LSIState *s, int out)
 /* Add a command to the queue.  */
 static void lsi_queue_command(LSIState *s)
 {
-    lsi_request *p;
+    lsi_request *p = s->current;
 
     DPRINTF("Queueing tag=0x%x\n", s->current_tag);
-    p = qemu_mallocz(sizeof(*p));
-    QTAILQ_INSERT_TAIL(&s->queue, p, next);
-    p->tag = s->current_tag;
+    assert(s->current != NULL);
+    QTAILQ_INSERT_TAIL(&s->queue, s->current, next);
+    s->current = NULL;
+
     p->pending = 0;
     p->out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
 }
@@ -597,6 +599,10 @@ static void lsi_reselect(LSIState *s, uint32_t tag)
         BADF("Reselected non-existant command tag=0x%x\n", tag);
         return;
     }
+    assert(s->current == NULL);
+    QTAILQ_REMOVE(&s->queue, p, next);
+    s->current = p;
+
     id = (tag >> 8) & 0xf;
     s->ssid = id | 0x80;
     /* LSI53C700 Family Compatibility, see LSI53C895A 4-73 */
@@ -605,21 +611,17 @@ static void lsi_reselect(LSIState *s, uint32_t tag)
     }
     DPRINTF("Reselected target %d\n", id);
     s->current_dev = s->bus.devs[id];
-    s->current_tag = tag;
     s->scntl1 |= LSI_SCNTL1_CON;
     lsi_set_phase(s, PHASE_MI);
     s->msg_action = p->out ? 2 : 3;
     s->current_dma_len = p->pending;
     s->dma_buf = NULL;
     lsi_add_msg_byte(s, 0x80);
-    if (s->current_tag & LSI_TAG_VALID) {
+    if (s->current->tag & LSI_TAG_VALID) {
         lsi_add_msg_byte(s, 0x20);
         lsi_add_msg_byte(s, tag & 0xff);
     }
 
-    QTAILQ_REMOVE(&s->queue, p, next);
-    qemu_free(p);
-
     if (lsi_irq_on_rsl(s)) {
         lsi_script_scsi_interrupt(s, LSI_SIST0_RSL, 0);
     }
@@ -677,11 +679,15 @@ static void lsi_command_complete(SCSIBus *bus, int reason, uint32_t tag,
         } else {
             lsi_set_phase(s, PHASE_ST);
         }
+
+        qemu_free(s->current);
+        s->current = NULL;
+
         lsi_resume_script(s);
         return;
     }
 
-    if (s->waiting == 1 || tag != s->current_tag ||
+    if (s->waiting == 1 || tag != s->current->tag ||
         (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
         if (lsi_queue_tag(s, tag, arg))
             return;
@@ -711,14 +717,19 @@ static void lsi_do_command(LSIState *s)
     cpu_physical_memory_read(s->dnad, buf, s->dbc);
     s->sfbr = buf[0];
     s->command_complete = 0;
-    n = s->current_dev->info->send_command(s->current_dev, s->current_tag, buf,
+
+    assert(s->current == NULL);
+    s->current = qemu_mallocz(sizeof(lsi_request));
+    s->current->tag = s->select_tag;
+
+    n = s->current_dev->info->send_command(s->current_dev, s->current->tag, buf,
                                            s->current_lun);
     if (n > 0) {
         lsi_set_phase(s, PHASE_DI);
-        s->current_dev->info->read_data(s->current_dev, s->current_tag);
+        s->current_dev->info->read_data(s->current_dev, s->current->tag);
     } else if (n < 0) {
         lsi_set_phase(s, PHASE_DO);
-        s->current_dev->info->write_data(s->current_dev, s->current_tag);
+        s->current_dev->info->write_data(s->current_dev, s->current->tag);
     }
 
     if (!s->command_complete) {
@@ -841,16 +852,16 @@ static void lsi_do_msgout(LSIState *s)
             }
             break;
         case 0x20: /* SIMPLE queue */
-            s->current_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
+            s->select_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
             DPRINTF("SIMPLE queue tag=0x%x\n", s->current_tag & 0xff);
             break;
         case 0x21: /* HEAD of queue */
             BADF("HEAD queue not implemented\n");
-            s->current_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
+            s->select_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
             break;
         case 0x22: /* ORDERED queue */
             BADF("ORDERED queue not implemented\n");
-            s->current_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
+            s->select_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
             break;
         default:
             if ((msg & 0x80) == 0) {
@@ -1086,7 +1097,7 @@ again:
                    it only applies in low-level mode (unimplemented).
                 lsi_script_scsi_interrupt(s, LSI_SIST0_CMP, 0); */
                 s->current_dev = s->bus.devs[id];
-                s->current_tag = id << 8;
+                s->select_tag = id << 8;
                 s->scntl1 |= LSI_SCNTL1_CON;
                 if (insn & (1 << 3)) {
                     s->socl |= LSI_SOCL_ATN;
-- 
1.6.5.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 3/5] lsi: move current_dev into lsi_request
  2010-01-06 16:07 [Qemu-devel] [PATCH 0/5] lsi: a bunch of cleanups Gerd Hoffmann
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 1/5] lsi: use QTAILQ for lsi_queue Gerd Hoffmann
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 2/5] lsi: have lsi_request for the whole life time of the request Gerd Hoffmann
@ 2010-01-06 16:08 ` Gerd Hoffmann
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 4/5] lsi: move dma_len+dma_buf " Gerd Hoffmann
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 5/5] lsi: pass lsi_request to lsi_reselect Gerd Hoffmann
  4 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2010-01-06 16:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/lsi53c895a.c |   23 ++++++++++++-----------
 1 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index e6c13eb..8715b99 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -175,6 +175,7 @@ do { fprintf(stderr, "lsi_scsi: error: " fmt , ## __VA_ARGS__);} while (0)
 
 typedef struct lsi_request {
     uint32_t tag;
+    SCSIDevice *dev;
     uint32_t pending;
     int out;
     QTAILQ_ENTRY(lsi_request) next;
@@ -199,7 +200,7 @@ typedef struct {
      * 3 if a DMA operation is in progress.  */
     int waiting;
     SCSIBus bus;
-    SCSIDevice *current_dev;
+    SCSIDevice *select_dev;
     int current_lun;
     /* The tag is a combination of the device ID and the SCSI tag.  */
     uint32_t select_tag;
@@ -533,8 +534,8 @@ static void lsi_do_dma(LSIState *s, int out)
     s->dbc -= count;
 
     if (s->dma_buf == NULL) {
-        s->dma_buf = s->current_dev->info->get_buf(s->current_dev,
-                                                   s->current->tag);
+        s->dma_buf = s->current->dev->info->get_buf(s->current->dev,
+                                                    s->current->tag);
     }
 
     /* ??? Set SFBR to first data byte.  */
@@ -548,10 +549,10 @@ static void lsi_do_dma(LSIState *s, int out)
         s->dma_buf = NULL;
         if (out) {
             /* Write the data.  */
-            s->current_dev->info->write_data(s->current_dev, s->current->tag);
+            s->current->dev->info->write_data(s->current->dev, s->current->tag);
         } else {
             /* Request any remaining data.  */
-            s->current_dev->info->read_data(s->current_dev, s->current->tag);
+            s->current->dev->info->read_data(s->current->dev, s->current->tag);
         }
     } else {
         s->dma_buf += count;
@@ -610,7 +611,6 @@ static void lsi_reselect(LSIState *s, uint32_t tag)
         s->sfbr = 1 << (id & 0x7);
     }
     DPRINTF("Reselected target %d\n", id);
-    s->current_dev = s->bus.devs[id];
     s->scntl1 |= LSI_SCNTL1_CON;
     lsi_set_phase(s, PHASE_MI);
     s->msg_action = p->out ? 2 : 3;
@@ -721,15 +721,16 @@ static void lsi_do_command(LSIState *s)
     assert(s->current == NULL);
     s->current = qemu_mallocz(sizeof(lsi_request));
     s->current->tag = s->select_tag;
+    s->current->dev = s->select_dev;
 
-    n = s->current_dev->info->send_command(s->current_dev, s->current->tag, buf,
-                                           s->current_lun);
+    n = s->current->dev->info->send_command(s->current->dev, s->current->tag, buf,
+                                            s->current_lun);
     if (n > 0) {
         lsi_set_phase(s, PHASE_DI);
-        s->current_dev->info->read_data(s->current_dev, s->current->tag);
+        s->current->dev->info->read_data(s->current->dev, s->current->tag);
     } else if (n < 0) {
         lsi_set_phase(s, PHASE_DO);
-        s->current_dev->info->write_data(s->current_dev, s->current->tag);
+        s->current->dev->info->write_data(s->current->dev, s->current->tag);
     }
 
     if (!s->command_complete) {
@@ -1096,7 +1097,7 @@ again:
                 /* ??? Linux drivers compain when this is set.  Maybe
                    it only applies in low-level mode (unimplemented).
                 lsi_script_scsi_interrupt(s, LSI_SIST0_CMP, 0); */
-                s->current_dev = s->bus.devs[id];
+                s->select_dev = s->bus.devs[id];
                 s->select_tag = id << 8;
                 s->scntl1 |= LSI_SCNTL1_CON;
                 if (insn & (1 << 3)) {
-- 
1.6.5.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 4/5] lsi: move dma_len+dma_buf into lsi_request
  2010-01-06 16:07 [Qemu-devel] [PATCH 0/5] lsi: a bunch of cleanups Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 3/5] lsi: move current_dev into lsi_request Gerd Hoffmann
@ 2010-01-06 16:08 ` Gerd Hoffmann
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 5/5] lsi: pass lsi_request to lsi_reselect Gerd Hoffmann
  4 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2010-01-06 16:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/lsi53c895a.c |   45 +++++++++++++++++++++++----------------------
 1 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 8715b99..f28fc76 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -176,6 +176,8 @@ do { fprintf(stderr, "lsi_scsi: error: " fmt , ## __VA_ARGS__);} while (0)
 typedef struct lsi_request {
     uint32_t tag;
     SCSIDevice *dev;
+    uint32_t dma_len;
+    uint8_t *dma_buf;
     uint32_t pending;
     int out;
     QTAILQ_ENTRY(lsi_request) next;
@@ -204,9 +206,7 @@ typedef struct {
     int current_lun;
     /* The tag is a combination of the device ID and the SCSI tag.  */
     uint32_t select_tag;
-    uint32_t current_dma_len;
     int command_complete;
-    uint8_t *dma_buf;
     QTAILQ_HEAD(, lsi_request) queue;
     lsi_request *current;
 
@@ -509,15 +509,16 @@ static void lsi_do_dma(LSIState *s, int out)
     uint32_t count;
     target_phys_addr_t addr;
 
-    if (!s->current_dma_len) {
+    assert(s->current);
+    if (!s->current->dma_len) {
         /* Wait until data is available.  */
         DPRINTF("DMA no data available\n");
         return;
     }
 
     count = s->dbc;
-    if (count > s->current_dma_len)
-        count = s->current_dma_len;
+    if (count > s->current->dma_len)
+        count = s->current->dma_len;
 
     addr = s->dnad;
     /* both 40 and Table Indirect 64-bit DMAs store upper bits in dnad64 */
@@ -533,20 +534,20 @@ static void lsi_do_dma(LSIState *s, int out)
     s->dnad += count;
     s->dbc -= count;
 
-    if (s->dma_buf == NULL) {
-        s->dma_buf = s->current->dev->info->get_buf(s->current->dev,
-                                                    s->current->tag);
+    if (s->current->dma_buf == NULL) {
+        s->current->dma_buf = s->current->dev->info->get_buf(s->current->dev,
+                                                             s->current->tag);
     }
 
     /* ??? Set SFBR to first data byte.  */
     if (out) {
-        cpu_physical_memory_read(addr, s->dma_buf, count);
+        cpu_physical_memory_read(addr, s->current->dma_buf, count);
     } else {
-        cpu_physical_memory_write(addr, s->dma_buf, count);
+        cpu_physical_memory_write(addr, s->current->dma_buf, count);
     }
-    s->current_dma_len -= count;
-    if (s->current_dma_len == 0) {
-        s->dma_buf = NULL;
+    s->current->dma_len -= count;
+    if (s->current->dma_len == 0) {
+        s->current->dma_buf = NULL;
         if (out) {
             /* Write the data.  */
             s->current->dev->info->write_data(s->current->dev, s->current->tag);
@@ -555,7 +556,7 @@ static void lsi_do_dma(LSIState *s, int out)
             s->current->dev->info->read_data(s->current->dev, s->current->tag);
         }
     } else {
-        s->dma_buf += count;
+        s->current->dma_buf += count;
         lsi_resume_script(s);
     }
 }
@@ -568,6 +569,7 @@ static void lsi_queue_command(LSIState *s)
 
     DPRINTF("Queueing tag=0x%x\n", s->current_tag);
     assert(s->current != NULL);
+    assert(s->current->dma_len == 0);
     QTAILQ_INSERT_TAIL(&s->queue, s->current, next);
     s->current = NULL;
 
@@ -614,8 +616,7 @@ static void lsi_reselect(LSIState *s, uint32_t tag)
     s->scntl1 |= LSI_SCNTL1_CON;
     lsi_set_phase(s, PHASE_MI);
     s->msg_action = p->out ? 2 : 3;
-    s->current_dma_len = p->pending;
-    s->dma_buf = NULL;
+    s->current->dma_len = p->pending;
     lsi_add_msg_byte(s, 0x80);
     if (s->current->tag & LSI_TAG_VALID) {
         lsi_add_msg_byte(s, 0x20);
@@ -695,7 +696,7 @@ static void lsi_command_complete(SCSIBus *bus, int reason, uint32_t tag,
 
     /* host adapter (re)connected */
     DPRINTF("Data ready tag=0x%x len=%d\n", tag, arg);
-    s->current_dma_len = arg;
+    s->current->dma_len = arg;
     s->command_complete = 1;
     if (!s->waiting)
         return;
@@ -910,8 +911,6 @@ static void lsi_wait_reselect(LSIState *s)
     lsi_request *p;
 
     DPRINTF("Wait Reselect\n");
-    if (s->current_dma_len)
-        BADF("Reselect with pending DMA\n");
 
     QTAILQ_FOREACH(p, &s->queue, next) {
         if (p->pending) {
@@ -919,7 +918,7 @@ static void lsi_wait_reselect(LSIState *s)
             break;
         }
     }
-    if (s->current_dma_len == 0) {
+    if (s->current == NULL) {
         s->waiting = 1;
     }
 }
@@ -2010,8 +2009,10 @@ static void lsi_pre_save(void *opaque)
 {
     LSIState *s = opaque;
 
-    assert(s->dma_buf == NULL);
-    assert(s->current_dma_len == 0);
+    if (s->current) {
+        assert(s->current->dma_buf == NULL);
+        assert(s->current->dma_len == 0);
+    }
     assert(QTAILQ_EMPTY(&s->queue));
 }
 
-- 
1.6.5.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 5/5] lsi: pass lsi_request to lsi_reselect
  2010-01-06 16:07 [Qemu-devel] [PATCH 0/5] lsi: a bunch of cleanups Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 4/5] lsi: move dma_len+dma_buf " Gerd Hoffmann
@ 2010-01-06 16:08 ` Gerd Hoffmann
  4 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2010-01-06 16:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

All callers of lsi_reselect have a lsi_request struct at hand anyway.
So just pass it directly instead of having lsi_reselect search for it
using the tag.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/lsi53c895a.c |   23 +++++++----------------
 1 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index f28fc76..dbc8c66 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -371,7 +371,7 @@ static int lsi_dma_64bit(LSIState *s)
 static uint8_t lsi_reg_readb(LSIState *s, int offset);
 static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val);
 static void lsi_execute_script(LSIState *s);
-static void lsi_reselect(LSIState *s, uint32_t tag);
+static void lsi_reselect(LSIState *s, lsi_request *p);
 
 static inline uint32_t read_dword(LSIState *s, uint32_t addr)
 {
@@ -430,7 +430,7 @@ static void lsi_update_irq(LSIState *s)
                 "processes\n");
         QTAILQ_FOREACH(p, &s->queue, next) {
             if (p->pending) {
-                lsi_reselect(s, p->tag);
+                lsi_reselect(s, p);
                 break;
             }
         }
@@ -589,24 +589,15 @@ static void lsi_add_msg_byte(LSIState *s, uint8_t data)
 }
 
 /* Perform reselection to continue a command.  */
-static void lsi_reselect(LSIState *s, uint32_t tag)
+static void lsi_reselect(LSIState *s, lsi_request *p)
 {
-    lsi_request *p;
     int id;
 
-    QTAILQ_FOREACH(p, &s->queue, next) {
-        if (p->tag == tag)
-            break;
-    }
-    if (p == NULL) {
-        BADF("Reselected non-existant command tag=0x%x\n", tag);
-        return;
-    }
     assert(s->current == NULL);
     QTAILQ_REMOVE(&s->queue, p, next);
     s->current = p;
 
-    id = (tag >> 8) & 0xf;
+    id = (p->tag >> 8) & 0xf;
     s->ssid = id | 0x80;
     /* LSI53C700 Family Compatibility, see LSI53C895A 4-73 */
     if (!(s->dcntl & LSI_DCNTL_COM)) {
@@ -620,7 +611,7 @@ static void lsi_reselect(LSIState *s, uint32_t tag)
     lsi_add_msg_byte(s, 0x80);
     if (s->current->tag & LSI_TAG_VALID) {
         lsi_add_msg_byte(s, 0x20);
-        lsi_add_msg_byte(s, tag & 0xff);
+        lsi_add_msg_byte(s, p->tag & 0xff);
     }
 
     if (lsi_irq_on_rsl(s)) {
@@ -649,7 +640,7 @@ static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
                 (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
                  !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) {
                 /* Reselect device.  */
-                lsi_reselect(s, tag);
+                lsi_reselect(s, p);
                 return 0;
             } else {
                 DPRINTF("Queueing IO tag=0x%x\n", tag);
@@ -914,7 +905,7 @@ static void lsi_wait_reselect(LSIState *s)
 
     QTAILQ_FOREACH(p, &s->queue, next) {
         if (p->pending) {
-            lsi_reselect(s, p->tag);
+            lsi_reselect(s, p);
             break;
         }
     }
-- 
1.6.5.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH 1/5] lsi: use QTAILQ for lsi_queue
  2010-01-06 16:08 ` [Qemu-devel] [PATCH 1/5] lsi: use QTAILQ for lsi_queue Gerd Hoffmann
@ 2010-01-11 16:02   ` Anthony Liguori
  0 siblings, 0 replies; 7+ messages in thread
From: Anthony Liguori @ 2010-01-11 16:02 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On 01/06/2010 10:08 AM, Gerd Hoffmann wrote:
> Replace the funky array logic for queued commands with standard
> qemu list functions.  Also rename lsi_queue to lsi_request.
>
> Signed-off-by: Gerd Hoffmann<kraxel@redhat.com>
>    

Applied all.  Thanks.

Regards,

Anthony Liguori
> ---
>   hw/lsi53c895a.c |   68 ++++++++++++++++++++++--------------------------------
>   1 files changed, 28 insertions(+), 40 deletions(-)
>
> diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
> index e4033b1..71a95f5 100644
> --- a/hw/lsi53c895a.c
> +++ b/hw/lsi53c895a.c
> @@ -173,11 +173,12 @@ do { fprintf(stderr, "lsi_scsi: error: " fmt , ## __VA_ARGS__);} while (0)
>   /* Flag set if this is a tagged command.  */
>   #define LSI_TAG_VALID     (1<<  16)
>
> -typedef struct {
> +typedef struct lsi_request {
>       uint32_t tag;
>       uint32_t pending;
>       int out;
> -} lsi_queue;
> +    QTAILQ_ENTRY(lsi_request) next;
> +} lsi_request;
>
>   typedef struct {
>       PCIDevice dev;
> @@ -205,9 +206,7 @@ typedef struct {
>       uint32_t current_dma_len;
>       int command_complete;
>       uint8_t *dma_buf;
> -    lsi_queue *queue;
> -    int queue_len;
> -    int active_commands;
> +    QTAILQ_HEAD(, lsi_request) queue;
>
>       uint32_t dsa;
>       uint32_t temp;
> @@ -391,9 +390,9 @@ static void lsi_stop_script(LSIState *s)
>
>   static void lsi_update_irq(LSIState *s)
>   {
> -    int i;
>       int level;
>       static int last_level;
> +    lsi_request *p;
>
>       /* It's unclear whether the DIP/SIP bits should be cleared when the
>          Interrupt Status Registers are cleared or when istat0 is read.
> @@ -427,9 +426,9 @@ static void lsi_update_irq(LSIState *s)
>       if (!level&&  lsi_irq_on_rsl(s)&&  !(s->scntl1&  LSI_SCNTL1_CON)) {
>           DPRINTF("Handled IRQs&  disconnected, looking for pending "
>                   "processes\n");
> -        for (i = 0; i<  s->active_commands; i++) {
> -            if (s->queue[i].pending) {
> -                lsi_reselect(s, s->queue[i].tag);
> +        QTAILQ_FOREACH(p,&s->queue, next) {
> +            if (p->pending) {
> +                lsi_reselect(s, p->tag);
>                   break;
>               }
>           }
> @@ -563,14 +562,11 @@ static void lsi_do_dma(LSIState *s, int out)
>   /* Add a command to the queue.  */
>   static void lsi_queue_command(LSIState *s)
>   {
> -    lsi_queue *p;
> +    lsi_request *p;
>
>       DPRINTF("Queueing tag=0x%x\n", s->current_tag);
> -    if (s->queue_len == s->active_commands) {
> -        s->queue_len++;
> -        s->queue = qemu_realloc(s->queue, s->queue_len * sizeof(lsi_queue));
> -    }
> -    p =&s->queue[s->active_commands++];
> +    p = qemu_mallocz(sizeof(*p));
> +    QTAILQ_INSERT_TAIL(&s->queue, p, next);
>       p->tag = s->current_tag;
>       p->pending = 0;
>       p->out = (s->sstat1&  PHASE_MASK) == PHASE_DO;
> @@ -590,17 +586,14 @@ static void lsi_add_msg_byte(LSIState *s, uint8_t data)
>   /* Perform reselection to continue a command.  */
>   static void lsi_reselect(LSIState *s, uint32_t tag)
>   {
> -    lsi_queue *p;
> -    int n;
> +    lsi_request *p;
>       int id;
>
> -    p = NULL;
> -    for (n = 0; n<  s->active_commands; n++) {
> -        p =&s->queue[n];
> +    QTAILQ_FOREACH(p,&s->queue, next) {
>           if (p->tag == tag)
>               break;
>       }
> -    if (n == s->active_commands) {
> +    if (p == NULL) {
>           BADF("Reselected non-existant command tag=0x%x\n", tag);
>           return;
>       }
> @@ -624,10 +617,8 @@ static void lsi_reselect(LSIState *s, uint32_t tag)
>           lsi_add_msg_byte(s, tag&  0xff);
>       }
>
> -    s->active_commands--;
> -    if (n != s->active_commands) {
> -        s->queue[n] = s->queue[s->active_commands];
> -    }
> +    QTAILQ_REMOVE(&s->queue, p, next);
> +    qemu_free(p);
>
>       if (lsi_irq_on_rsl(s)) {
>           lsi_script_scsi_interrupt(s, LSI_SIST0_RSL, 0);
> @@ -638,10 +629,9 @@ static void lsi_reselect(LSIState *s, uint32_t tag)
>      the device was reselected, nonzero if the IO is deferred.  */
>   static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
>   {
> -    lsi_queue *p;
> -    int i;
> -    for (i = 0; i<  s->active_commands; i++) {
> -        p =&s->queue[i];
> +    lsi_request *p;
> +
> +    QTAILQ_FOREACH(p,&s->queue, next) {
>           if (p->tag == tag) {
>               if (p->pending) {
>                   BADF("Multiple IO pending for tag %d\n", tag);
> @@ -659,7 +649,7 @@ static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
>                   lsi_reselect(s, tag);
>                   return 0;
>               } else {
> -               DPRINTF("Queueing IO tag=0x%x\n", tag);
> +                DPRINTF("Queueing IO tag=0x%x\n", tag);
>                   p->pending = arg;
>                   return 1;
>               }
> @@ -905,13 +895,15 @@ static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count)
>
>   static void lsi_wait_reselect(LSIState *s)
>   {
> -    int i;
> +    lsi_request *p;
> +
>       DPRINTF("Wait Reselect\n");
>       if (s->current_dma_len)
>           BADF("Reselect with pending DMA\n");
> -    for (i = 0; i<  s->active_commands; i++) {
> -        if (s->queue[i].pending) {
> -            lsi_reselect(s, s->queue[i].tag);
> +
> +    QTAILQ_FOREACH(p,&s->queue, next) {
> +        if (p->pending) {
> +            lsi_reselect(s, p->tag);
>               break;
>           }
>       }
> @@ -2008,7 +2000,7 @@ static void lsi_pre_save(void *opaque)
>
>       assert(s->dma_buf == NULL);
>       assert(s->current_dma_len == 0);
> -    assert(s->active_commands == 0);
> +    assert(QTAILQ_EMPTY(&s->queue));
>   }
>
>   static const VMStateDescription vmstate_lsi_scsi = {
> @@ -2101,8 +2093,6 @@ static int lsi_scsi_uninit(PCIDevice *d)
>       cpu_unregister_io_memory(s->mmio_io_addr);
>       cpu_unregister_io_memory(s->ram_io_addr);
>
> -    qemu_free(s->queue);
> -
>       return 0;
>   }
>
> @@ -2138,9 +2128,7 @@ static int lsi_scsi_init(PCIDevice *dev)
>                              PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_mmio_mapfunc);
>       pci_register_bar((struct PCIDevice *)s, 2, 0x2000,
>                              PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc);
> -    s->queue = qemu_malloc(sizeof(lsi_queue));
> -    s->queue_len = 1;
> -    s->active_commands = 0;
> +    QTAILQ_INIT(&s->queue);
>
>       lsi_soft_reset(s);
>
>    

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-01-11 16:02 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-06 16:07 [Qemu-devel] [PATCH 0/5] lsi: a bunch of cleanups Gerd Hoffmann
2010-01-06 16:08 ` [Qemu-devel] [PATCH 1/5] lsi: use QTAILQ for lsi_queue Gerd Hoffmann
2010-01-11 16:02   ` Anthony Liguori
2010-01-06 16:08 ` [Qemu-devel] [PATCH 2/5] lsi: have lsi_request for the whole life time of the request Gerd Hoffmann
2010-01-06 16:08 ` [Qemu-devel] [PATCH 3/5] lsi: move current_dev into lsi_request Gerd Hoffmann
2010-01-06 16:08 ` [Qemu-devel] [PATCH 4/5] lsi: move dma_len+dma_buf " Gerd Hoffmann
2010-01-06 16:08 ` [Qemu-devel] [PATCH 5/5] lsi: pass lsi_request to lsi_reselect Gerd Hoffmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).