Revision ad2d30f7

b/hw/scsi-bus.c
136 136
    SCSIRequest *req;
137 137

  
138 138
    req = qemu_mallocz(size);
139
    /* Two references: one is passed back to the HBA, one is in d->requests.  */
140
    req->refcount = 2;
139 141
    req->bus = scsi_bus_from_device(d);
140 142
    req->dev = d;
141 143
    req->tag = tag;
......
159 161
    return NULL;
160 162
}
161 163

  
162
static void scsi_req_dequeue(SCSIRequest *req)
164
void scsi_req_dequeue(SCSIRequest *req)
163 165
{
164 166
    trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag);
165 167
    if (req->enqueued) {
166 168
        QTAILQ_REMOVE(&req->dev->requests, req, next);
167 169
        req->enqueued = false;
170
        scsi_req_unref(req);
168 171
    }
169 172
}
170 173

  
171
void scsi_req_free(SCSIRequest *req)
172
{
173
    scsi_req_dequeue(req);
174
    qemu_free(req);
175
}
176

  
177 174
static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
178 175
{
179 176
    switch (cmd[0] >> 5) {
......
495 492
    return names[cmd];
496 493
}
497 494

  
495
SCSIRequest *scsi_req_ref(SCSIRequest *req)
496
{
497
    req->refcount++;
498
    return req;
499
}
500

  
501
void scsi_req_unref(SCSIRequest *req)
502
{
503
    if (--req->refcount == 0) {
504
        if (req->dev->info->free_req) {
505
            req->dev->info->free_req(req);
506
        }
507
        qemu_free(req);
508
    }
509
}
510

  
498 511
/* Called by the devices when data is ready for the HBA.  The HBA should
499 512
   start a DMA operation to read or fill the device's data buffer.
500 513
   Once it completes, calling one of req->dev->info->read_data or
......
537 550
void scsi_req_complete(SCSIRequest *req)
538 551
{
539 552
    assert(req->status != -1);
553
    scsi_req_ref(req);
540 554
    scsi_req_dequeue(req);
541 555
    req->bus->ops->complete(req->bus, SCSI_REASON_DONE,
542 556
                            req->tag,
543 557
                            req->status);
558
    scsi_req_unref(req);
544 559
}
545 560

  
546 561
static char *scsibus_get_fw_dev_path(DeviceState *dev)
b/hw/scsi-disk.c
98 98
    return r;
99 99
}
100 100

  
101
static void scsi_remove_request(SCSIDiskReq *r)
101
static void scsi_free_request(SCSIRequest *req)
102 102
{
103
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
104

  
103 105
    qemu_vfree(r->iov.iov_base);
104
    scsi_req_free(&r->req);
105 106
}
106 107

  
107 108
static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag)
......
134 135
            r->req.tag, status, sense);
135 136
    scsi_req_set_status(r, status, sense);
136 137
    scsi_req_complete(&r->req);
137
    scsi_remove_request(r);
138 138
}
139 139

  
140 140
/* Cancel a pending data transfer.  */
......
148 148
        if (r->req.aiocb)
149 149
            bdrv_aio_cancel(r->req.aiocb);
150 150
        r->req.aiocb = NULL;
151
        scsi_remove_request(r);
151
        scsi_req_dequeue(&r->req);
152 152
    }
153 153
}
154 154

  
......
1033 1033
                                 uint8_t *buf, int lun)
1034 1034
{
1035 1035
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
1036
    uint32_t len;
1036
    int32_t len;
1037 1037
    int is_write;
1038 1038
    uint8_t command;
1039 1039
    uint8_t *outbuf;
......
1095 1095
    case REZERO_UNIT:
1096 1096
        rc = scsi_disk_emulate_command(r, outbuf);
1097 1097
        if (rc < 0) {
1098
            scsi_req_unref(&r->req);
1098 1099
            return 0;
1099 1100
        }
1100 1101

  
......
1181 1182
        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
1182 1183
    fail:
1183 1184
        scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST);
1185
        scsi_req_unref(&r->req);
1184 1186
        return 0;
1185 1187
    illegal_lba:
1186 1188
        scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
1189
        scsi_req_unref(&r->req);
1187 1190
        return 0;
1188 1191
    }
1189 1192
    if (r->sector_count == 0 && r->iov.iov_len == 0) {
......
1191 1194
    }
1192 1195
    len = r->sector_count * 512 + r->iov.iov_len;
1193 1196
    if (is_write) {
1194
        return -len;
1197
        len = -len;
1195 1198
    } else {
1196 1199
        if (!r->sector_count)
1197 1200
            r->sector_count = -1;
1198
        return len;
1199 1201
    }
1202
    scsi_req_unref(&r->req);
1203
    return len;
1200 1204
}
1201 1205

  
1202 1206
static void scsi_disk_purge_requests(SCSIDiskState *s)
......
1208 1212
        if (r->req.aiocb) {
1209 1213
            bdrv_aio_cancel(r->req.aiocb);
1210 1214
        }
1211
        scsi_remove_request(r);
1215
        scsi_req_dequeue(&r->req);
1212 1216
    }
1213 1217
}
1214 1218

  
......
1321 1325
        .qdev.reset   = scsi_disk_reset,
1322 1326
        .init         = scsi_hd_initfn,
1323 1327
        .destroy      = scsi_destroy,
1328
        .free_req     = scsi_free_request,
1324 1329
        .send_command = scsi_send_command,
1325 1330
        .read_data    = scsi_read_data,
1326 1331
        .write_data   = scsi_write_data,
......
1339 1344
        .qdev.reset   = scsi_disk_reset,
1340 1345
        .init         = scsi_cd_initfn,
1341 1346
        .destroy      = scsi_destroy,
1347
        .free_req     = scsi_free_request,
1342 1348
        .send_command = scsi_send_command,
1343 1349
        .read_data    = scsi_read_data,
1344 1350
        .write_data   = scsi_write_data,
......
1356 1362
        .qdev.reset   = scsi_disk_reset,
1357 1363
        .init         = scsi_disk_initfn,
1358 1364
        .destroy      = scsi_destroy,
1365
        .free_req     = scsi_free_request,
1359 1366
        .send_command = scsi_send_command,
1360 1367
        .read_data    = scsi_read_data,
1361 1368
        .write_data   = scsi_write_data,
b/hw/scsi-generic.c
74 74
    return DO_UPCAST(SCSIGenericReq, req, req);
75 75
}
76 76

  
77
static void scsi_remove_request(SCSIGenericReq *r)
77
static void scsi_free_request(SCSIRequest *req)
78 78
{
79
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
80

  
79 81
    qemu_free(r->buf);
80
    scsi_req_free(&r->req);
81 82
}
82 83

  
83 84
static SCSIGenericReq *scsi_find_request(SCSIGenericState *s, uint32_t tag)
......
113 114
            r, r->req.tag, r->req.status);
114 115

  
115 116
    scsi_req_complete(&r->req);
116
    scsi_remove_request(r);
117 117
}
118 118

  
119 119
/* Cancel a pending data transfer.  */
......
128 128
        if (r->req.aiocb)
129 129
            bdrv_aio_cancel(r->req.aiocb);
130 130
        r->req.aiocb = NULL;
131
        scsi_remove_request(r);
131
        scsi_req_dequeue(&r->req);
132 132
    }
133 133
}
134 134

  
......
323 323
    SCSIGenericReq *r;
324 324
    SCSIBus *bus;
325 325
    int ret;
326
    int32_t len;
326 327

  
327 328
    if (cmd[0] != REQUEST_SENSE &&
328 329
        (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
......
351 352

  
352 353
    if (-1 == scsi_req_parse(&r->req, cmd)) {
353 354
        BADF("Unsupported command length, command %x\n", cmd[0]);
354
        scsi_remove_request(r);
355
        scsi_req_dequeue(&r->req);
356
        scsi_req_unref(&r->req);
355 357
        return 0;
356 358
    }
357 359
    scsi_req_fixup(&r->req);
......
377 379
        ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
378 380
        if (ret == -1) {
379 381
            scsi_command_complete(r, -EINVAL);
382
            scsi_req_unref(&r->req);
380 383
            return 0;
381 384
        }
385
        scsi_req_unref(&r->req);
382 386
        return 0;
383 387
    }
384 388

  
......
393 397
    r->len = r->req.cmd.xfer;
394 398
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
395 399
        r->len = 0;
396
        return -r->req.cmd.xfer;
400
        len = -r->req.cmd.xfer;
401
    } else {
402
        len = r->req.cmd.xfer;
397 403
    }
398 404

  
399
    return r->req.cmd.xfer;
405
    scsi_req_unref(&r->req);
406
    return len;
400 407
}
401 408

  
402 409
static int get_blocksize(BlockDriverState *bdrv)
......
469 476
        if (r->req.aiocb) {
470 477
            bdrv_aio_cancel(r->req.aiocb);
471 478
        }
472
        scsi_remove_request(r);
479
        scsi_req_dequeue(&r->req);
473 480
    }
474 481
}
475 482

  
......
561 568
    .qdev.reset   = scsi_generic_reset,
562 569
    .init         = scsi_generic_initfn,
563 570
    .destroy      = scsi_destroy,
571
    .free_req     = scsi_free_request,
564 572
    .send_command = scsi_send_command,
565 573
    .read_data    = scsi_read_data,
566 574
    .write_data   = scsi_write_data,
b/hw/scsi.h
29 29
typedef struct SCSIRequest {
30 30
    SCSIBus           *bus;
31 31
    SCSIDevice        *dev;
32
    uint32_t          refcount;
32 33
    uint32_t          tag;
33 34
    uint32_t          lun;
34 35
    uint32_t          status;
......
65 66
    DeviceInfo qdev;
66 67
    scsi_qdev_initfn init;
67 68
    void (*destroy)(SCSIDevice *s);
69
    void (*free_req)(SCSIRequest *req);
68 70
    int32_t (*send_command)(SCSIDevice *s, uint32_t tag, uint8_t *buf,
69 71
                            int lun);
70 72
    void (*read_data)(SCSIDevice *s, uint32_t tag);
......
103 105
SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun);
104 106
SCSIRequest *scsi_req_find(SCSIDevice *d, uint32_t tag);
105 107
void scsi_req_free(SCSIRequest *req);
108
void scsi_req_dequeue(SCSIRequest *req);
109
SCSIRequest *scsi_req_ref(SCSIRequest *req);
110
void scsi_req_unref(SCSIRequest *req);
106 111

  
107 112
int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
108 113
void scsi_req_print(SCSIRequest *req);

Also available in: Unified diff