Revision 5c6c0e51 hw/scsi-generic.c

b/hw/scsi-generic.c
66 66
    uint8_t senselen;
67 67
};
68 68

  
69
static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
69
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
70 70
{
71 71
    SCSIRequest *req;
72 72

  
73 73
    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
74
    return DO_UPCAST(SCSIGenericReq, req, req);
74
    return req;
75 75
}
76 76

  
77 77
static void scsi_free_request(SCSIRequest *req)
......
81 81
    qemu_free(r->buf);
82 82
}
83 83

  
84
static SCSIGenericReq *scsi_find_request(SCSIGenericState *s, uint32_t tag)
85
{
86
    return DO_UPCAST(SCSIGenericReq, req, scsi_req_find(&s->qdev, tag));
87
}
88

  
89 84
/* Helper function for command completion.  */
90 85
static void scsi_command_complete(void *opaque, int ret)
91 86
{
......
117 112
}
118 113

  
119 114
/* Cancel a pending data transfer.  */
120
static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
115
static void scsi_cancel_io(SCSIRequest *req)
121 116
{
122
    DPRINTF("scsi_cancel_io 0x%x\n", tag);
123
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
124
    SCSIGenericReq *r;
125
    DPRINTF("Cancel tag=0x%x\n", tag);
126
    r = scsi_find_request(s, tag);
127
    if (r) {
128
        if (r->req.aiocb)
129
            bdrv_aio_cancel(r->req.aiocb);
130
        r->req.aiocb = NULL;
131
        scsi_req_dequeue(&r->req);
117
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
118

  
119
    DPRINTF("Cancel tag=0x%x\n", req->tag);
120
    if (r->req.aiocb) {
121
        bdrv_aio_cancel(r->req.aiocb);
132 122
    }
123
    r->req.aiocb = NULL;
124
    scsi_req_dequeue(&r->req);
133 125
}
134 126

  
135 127
static int execute_command(BlockDriverState *bdrv,
......
182 174
}
183 175

  
184 176
/* Read more data from scsi device into buffer.  */
185
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
177
static void scsi_read_data(SCSIRequest *req)
186 178
{
187
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
188
    SCSIGenericReq *r;
179
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
180
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
189 181
    int ret;
190 182

  
191
    DPRINTF("scsi_read_data 0x%x\n", tag);
192
    r = scsi_find_request(s, tag);
193
    if (!r) {
194
        BADF("Bad read tag 0x%x\n", tag);
195
        /* ??? This is the wrong error.  */
196
        scsi_command_complete(r, -EINVAL);
197
        return;
198
    }
199

  
183
    DPRINTF("scsi_read_data 0x%x\n", req->tag);
200 184
    if (r->len == -1) {
201 185
        scsi_command_complete(r, 0);
202 186
        return;
......
249 233

  
250 234
/* Write data to a scsi device.  Returns nonzero on failure.
251 235
   The transfer may complete asynchronously.  */
252
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
236
static int scsi_write_data(SCSIRequest *req)
253 237
{
254
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
255
    SCSIGenericReq *r;
238
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
239
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
256 240
    int ret;
257 241

  
258
    DPRINTF("scsi_write_data 0x%x\n", tag);
259
    r = scsi_find_request(s, tag);
260
    if (!r) {
261
        BADF("Bad write tag 0x%x\n", tag);
262
        /* ??? This is the wrong error.  */
263
        scsi_command_complete(r, -EINVAL);
264
        return 0;
265
    }
266

  
242
    DPRINTF("scsi_write_data 0x%x\n", req->tag);
267 243
    if (r->len == 0) {
268 244
        r->len = r->buflen;
269 245
        scsi_req_data(&r->req, r->len);
......
280 256
}
281 257

  
282 258
/* Return a pointer to the data buffer.  */
283
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
259
static uint8_t *scsi_get_buf(SCSIRequest *req)
284 260
{
285
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
286
    SCSIGenericReq *r;
287
    r = scsi_find_request(s, tag);
288
    if (!r) {
289
        BADF("Bad buffer tag 0x%x\n", tag);
290
        return NULL;
291
    }
261
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
262

  
292 263
    return r->buf;
293 264
}
294 265

  
......
316 287
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
317 288
   and zero if the command does not transfer any data.  */
318 289

  
319
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
320
                                 uint8_t *cmd, int lun)
290
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
321 291
{
322
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
323
    SCSIGenericReq *r;
292
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
293
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
324 294
    SCSIBus *bus;
325 295
    int ret;
326
    int32_t len;
327 296

  
297
    scsi_req_enqueue(req);
328 298
    if (cmd[0] != REQUEST_SENSE &&
329
        (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
330
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
299
        (req->lun != s->lun || (cmd[1] >> 5) != s->lun)) {
300
        DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : cmd[1] >> 5);
331 301

  
332 302
        s->sensebuf[0] = 0x70;
333 303
        s->sensebuf[1] = 0x00;
......
338 308
        s->sensebuf[6] = 0x00;
339 309
        s->senselen = 7;
340 310
        s->driver_status = SG_ERR_DRIVER_SENSE;
341
        bus = scsi_bus_from_device(d);
342
        bus->ops->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION);
311
        bus = scsi_bus_from_device(&s->qdev);
312
        bus->ops->complete(req, SCSI_REASON_DONE, CHECK_CONDITION);
343 313
        return 0;
344 314
    }
345 315

  
346
    r = scsi_find_request(s, tag);
347
    if (r) {
348
        BADF("Tag 0x%x already in use %p\n", tag, r);
349
        scsi_cancel_io(d, tag);
350
    }
351
    r = scsi_new_request(d, tag, lun);
352

  
353 316
    if (-1 == scsi_req_parse(&r->req, cmd)) {
354 317
        BADF("Unsupported command length, command %x\n", cmd[0]);
355 318
        scsi_req_dequeue(&r->req);
......
379 342
        ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
380 343
        if (ret == -1) {
381 344
            scsi_command_complete(r, -EINVAL);
382
            scsi_req_unref(&r->req);
383
            return 0;
384 345
        }
385
        scsi_req_unref(&r->req);
386 346
        return 0;
387 347
    }
388 348

  
......
397 357
    r->len = r->req.cmd.xfer;
398 358
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
399 359
        r->len = 0;
400
        len = -r->req.cmd.xfer;
360
        return -r->req.cmd.xfer;
401 361
    } else {
402
        len = r->req.cmd.xfer;
362
        return r->req.cmd.xfer;
403 363
    }
404

  
405
    scsi_req_unref(&r->req);
406
    return len;
407 364
}
408 365

  
409 366
static int get_blocksize(BlockDriverState *bdrv)
......
477 434
            bdrv_aio_cancel(r->req.aiocb);
478 435
        }
479 436
        scsi_req_dequeue(&r->req);
437
        scsi_req_unref(&r->req);
480 438
    }
481 439
}
482 440

  
......
568 526
    .qdev.reset   = scsi_generic_reset,
569 527
    .init         = scsi_generic_initfn,
570 528
    .destroy      = scsi_destroy,
529
    .alloc_req    = scsi_new_request,
571 530
    .free_req     = scsi_free_request,
572 531
    .send_command = scsi_send_command,
573 532
    .read_data    = scsi_read_data,

Also available in: Unified diff