Revision 042ec49d hw/lsi53c895a.c

b/hw/lsi53c895a.c
173 173
/* Flag set if this is a tagged command.  */
174 174
#define LSI_TAG_VALID     (1 << 16)
175 175

  
176
typedef struct {
176
typedef struct lsi_request {
177 177
    uint32_t tag;
178 178
    uint32_t pending;
179 179
    int out;
180
} lsi_queue;
180
    QTAILQ_ENTRY(lsi_request) next;
181
} lsi_request;
181 182

  
182 183
typedef struct {
183 184
    PCIDevice dev;
......
205 206
    uint32_t current_dma_len;
206 207
    int command_complete;
207 208
    uint8_t *dma_buf;
208
    lsi_queue *queue;
209
    int queue_len;
210
    int active_commands;
209
    QTAILQ_HEAD(, lsi_request) queue;
211 210

  
212 211
    uint32_t dsa;
213 212
    uint32_t temp;
......
391 390

  
392 391
static void lsi_update_irq(LSIState *s)
393 392
{
394
    int i;
395 393
    int level;
396 394
    static int last_level;
395
    lsi_request *p;
397 396

  
398 397
    /* It's unclear whether the DIP/SIP bits should be cleared when the
399 398
       Interrupt Status Registers are cleared or when istat0 is read.
......
427 426
    if (!level && lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON)) {
428 427
        DPRINTF("Handled IRQs & disconnected, looking for pending "
429 428
                "processes\n");
430
        for (i = 0; i < s->active_commands; i++) {
431
            if (s->queue[i].pending) {
432
                lsi_reselect(s, s->queue[i].tag);
429
        QTAILQ_FOREACH(p, &s->queue, next) {
430
            if (p->pending) {
431
                lsi_reselect(s, p->tag);
433 432
                break;
434 433
            }
435 434
        }
......
563 562
/* Add a command to the queue.  */
564 563
static void lsi_queue_command(LSIState *s)
565 564
{
566
    lsi_queue *p;
565
    lsi_request *p;
567 566

  
568 567
    DPRINTF("Queueing tag=0x%x\n", s->current_tag);
569
    if (s->queue_len == s->active_commands) {
570
        s->queue_len++;
571
        s->queue = qemu_realloc(s->queue, s->queue_len * sizeof(lsi_queue));
572
    }
573
    p = &s->queue[s->active_commands++];
568
    p = qemu_mallocz(sizeof(*p));
569
    QTAILQ_INSERT_TAIL(&s->queue, p, next);
574 570
    p->tag = s->current_tag;
575 571
    p->pending = 0;
576 572
    p->out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
......
590 586
/* Perform reselection to continue a command.  */
591 587
static void lsi_reselect(LSIState *s, uint32_t tag)
592 588
{
593
    lsi_queue *p;
594
    int n;
589
    lsi_request *p;
595 590
    int id;
596 591

  
597
    p = NULL;
598
    for (n = 0; n < s->active_commands; n++) {
599
        p = &s->queue[n];
592
    QTAILQ_FOREACH(p, &s->queue, next) {
600 593
        if (p->tag == tag)
601 594
            break;
602 595
    }
603
    if (n == s->active_commands) {
596
    if (p == NULL) {
604 597
        BADF("Reselected non-existant command tag=0x%x\n", tag);
605 598
        return;
606 599
    }
......
624 617
        lsi_add_msg_byte(s, tag & 0xff);
625 618
    }
626 619

  
627
    s->active_commands--;
628
    if (n != s->active_commands) {
629
        s->queue[n] = s->queue[s->active_commands];
630
    }
620
    QTAILQ_REMOVE(&s->queue, p, next);
621
    qemu_free(p);
631 622

  
632 623
    if (lsi_irq_on_rsl(s)) {
633 624
        lsi_script_scsi_interrupt(s, LSI_SIST0_RSL, 0);
......
638 629
   the device was reselected, nonzero if the IO is deferred.  */
639 630
static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
640 631
{
641
    lsi_queue *p;
642
    int i;
643
    for (i = 0; i < s->active_commands; i++) {
644
        p = &s->queue[i];
632
    lsi_request *p;
633

  
634
    QTAILQ_FOREACH(p, &s->queue, next) {
645 635
        if (p->tag == tag) {
646 636
            if (p->pending) {
647 637
                BADF("Multiple IO pending for tag %d\n", tag);
......
659 649
                lsi_reselect(s, tag);
660 650
                return 0;
661 651
            } else {
662
               DPRINTF("Queueing IO tag=0x%x\n", tag);
652
                DPRINTF("Queueing IO tag=0x%x\n", tag);
663 653
                p->pending = arg;
664 654
                return 1;
665 655
            }
......
905 895

  
906 896
static void lsi_wait_reselect(LSIState *s)
907 897
{
908
    int i;
898
    lsi_request *p;
899

  
909 900
    DPRINTF("Wait Reselect\n");
910 901
    if (s->current_dma_len)
911 902
        BADF("Reselect with pending DMA\n");
912
    for (i = 0; i < s->active_commands; i++) {
913
        if (s->queue[i].pending) {
914
            lsi_reselect(s, s->queue[i].tag);
903

  
904
    QTAILQ_FOREACH(p, &s->queue, next) {
905
        if (p->pending) {
906
            lsi_reselect(s, p->tag);
915 907
            break;
916 908
        }
917 909
    }
......
2008 2000

  
2009 2001
    assert(s->dma_buf == NULL);
2010 2002
    assert(s->current_dma_len == 0);
2011
    assert(s->active_commands == 0);
2003
    assert(QTAILQ_EMPTY(&s->queue));
2012 2004
}
2013 2005

  
2014 2006
static const VMStateDescription vmstate_lsi_scsi = {
......
2101 2093
    cpu_unregister_io_memory(s->mmio_io_addr);
2102 2094
    cpu_unregister_io_memory(s->ram_io_addr);
2103 2095

  
2104
    qemu_free(s->queue);
2105

  
2106 2096
    return 0;
2107 2097
}
2108 2098

  
......
2140 2130
                           PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_mmio_mapfunc);
2141 2131
    pci_register_bar((struct PCIDevice *)s, 2, 0x2000,
2142 2132
                           PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc);
2143
    s->queue = qemu_malloc(sizeof(lsi_queue));
2144
    s->queue_len = 1;
2145
    s->active_commands = 0;
2133
    QTAILQ_INIT(&s->queue);
2146 2134

  
2147 2135
    lsi_soft_reset(s);
2148 2136

  

Also available in: Unified diff