Revision 9af99d98 hw/scsi-disk.c

b/hw/scsi-disk.c
55 55
    uint32_t sector_count;
56 56
    struct iovec iov;
57 57
    QEMUIOVector qiov;
58
    struct SCSIDiskReq *next;
59 58
    uint32_t status;
60 59
} SCSIDiskReq;
61 60

  
......
63 62
{
64 63
    SCSIDevice qdev;
65 64
    DriveInfo *dinfo;
66
    SCSIDiskReq *requests;
67 65
    /* The qemu block layer uses a fixed 512 byte sector size.
68 66
       This is the number of 512 byte blocks in a single scsi sector.  */
69 67
    int cluster_size;
......
73 71
    QEMUBH *bh;
74 72
};
75 73

  
76
/* Global pool of SCSIRequest structures.  */
77
static SCSIDiskReq *free_requests = NULL;
78

  
79 74
static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag)
80 75
{
81
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
82 76
    SCSIDiskReq *r;
83 77

  
84
    if (free_requests) {
85
        r = free_requests;
86
        free_requests = r->next;
87
    } else {
88
        r = qemu_malloc(sizeof(SCSIDiskReq));
89
        r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
90
    }
78
    r = qemu_mallocz(sizeof(SCSIDiskReq));
79
    r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
91 80
    r->req.bus = scsi_bus_from_device(d);
92 81
    r->req.dev = d;
93 82
    r->req.tag = tag;
94
    r->sector_count = 0;
95
    r->iov.iov_len = 0;
96
    r->req.aiocb = NULL;
97
    r->status = 0;
98 83

  
99
    r->next = s->requests;
100
    s->requests = r;
84
    QTAILQ_INSERT_TAIL(&d->requests, &r->req, next);
101 85
    return r;
102 86
}
103 87

  
104 88
static void scsi_remove_request(SCSIDiskReq *r)
105 89
{
106
    SCSIDiskReq *last;
107
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
108

  
109
    if (s->requests == r) {
110
        s->requests = r->next;
111
    } else {
112
        last = s->requests;
113
        while (last && last->next != r)
114
            last = last->next;
115
        if (last) {
116
            last->next = r->next;
117
        } else {
118
            BADF("Orphaned request\n");
119
        }
120
    }
121
    r->next = free_requests;
122
    free_requests = r;
90
    qemu_free(r->iov.iov_base);
91
    QTAILQ_REMOVE(&r->req.dev->requests, &r->req, next);
92
    qemu_free(r);
123 93
}
124 94

  
125 95
static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag)
126 96
{
127
    SCSIDiskReq *r;
128

  
129
    r = s->requests;
130
    while (r && r->req.tag != tag)
131
        r = r->next;
97
    SCSIRequest *req;
132 98

  
133
    return r;
99
    QTAILQ_FOREACH(req, &s->qdev.requests, next) {
100
        if (req->tag == tag) {
101
            return DO_UPCAST(SCSIDiskReq, req, req);
102
        }
103
    }
104
    return NULL;
134 105
}
135 106

  
136 107
/* Helper function for command completion.  */
......
310 281
static void scsi_dma_restart_bh(void *opaque)
311 282
{
312 283
    SCSIDiskState *s = opaque;
313
    SCSIDiskReq *r = s->requests;
284
    SCSIRequest *req;
285
    SCSIDiskReq *r;
314 286

  
315 287
    qemu_bh_delete(s->bh);
316 288
    s->bh = NULL;
317 289

  
318
    while (r) {
290
    QTAILQ_FOREACH(req, &s->qdev.requests, next) {
291
        r = DO_UPCAST(SCSIDiskReq, req, req);
319 292
        if (r->status & SCSI_REQ_STATUS_RETRY) {
320 293
            r->status &= ~SCSI_REQ_STATUS_RETRY;
321 294
            scsi_write_request(r); 
322 295
        }
323
        r = r->next;
324 296
    }
325 297
}
326 298

  
......
959 931
static void scsi_destroy(SCSIDevice *dev)
960 932
{
961 933
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
934
    SCSIDiskReq *r;
962 935

  
936
    while (!QTAILQ_EMPTY(&s->qdev.requests)) {
937
        r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests));
938
        scsi_remove_request(r);
939
    }
963 940
    drive_uninit(s->dinfo);
964 941
}
965 942

  

Also available in: Unified diff