Revision 8869e103 hw/scsi-generic.c

b/hw/scsi-generic.c
46 46
#define MAX_UINT ((unsigned int)-1)
47 47
#endif
48 48

  
49
typedef struct SCSIGenericState SCSIGenericState;
50

  
51 49
typedef struct SCSIGenericReq {
52 50
    SCSIRequest req;
53 51
    uint8_t *buf;
......
56 54
    sg_io_hdr_t io_header;
57 55
} SCSIGenericReq;
58 56

  
59
struct SCSIGenericState
60
{
61
    SCSIDevice qdev;
62
    BlockDriverState *bs;
63
};
64

  
65 57
static void scsi_free_request(SCSIRequest *req)
66 58
{
67 59
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
......
174 166
static void scsi_read_data(SCSIRequest *req)
175 167
{
176 168
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
177
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
169
    SCSIDevice *s = r->req.dev;
178 170
    int ret;
179 171

  
180 172
    DPRINTF("scsi_read_data 0x%x\n", req->tag);
......
183 175
        return;
184 176
    }
185 177

  
186
    ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
178
    ret = execute_command(s->conf.bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
187 179
    if (ret < 0) {
188 180
        scsi_command_complete(r, ret);
189
        return;
190 181
    }
191 182
}
192 183

  
193 184
static void scsi_write_complete(void * opaque, int ret)
194 185
{
195 186
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
196
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
187
    SCSIDevice *s = r->req.dev;
197 188

  
198 189
    DPRINTF("scsi_write_complete() ret = %d\n", ret);
199 190
    r->req.aiocb = NULL;
......
204 195
    }
205 196

  
206 197
    if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
207
        s->qdev.type == TYPE_TAPE) {
208
        s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
209
        DPRINTF("block size %d\n", s->qdev.blocksize);
198
        s->type == TYPE_TAPE) {
199
        s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
200
        DPRINTF("block size %d\n", s->blocksize);
210 201
    }
211 202

  
212 203
    scsi_command_complete(r, ret);
......
216 207
   The transfer may complete asynchronously.  */
217 208
static void scsi_write_data(SCSIRequest *req)
218 209
{
219
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
220 210
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
211
    SCSIDevice *s = r->req.dev;
221 212
    int ret;
222 213

  
223 214
    DPRINTF("scsi_write_data 0x%x\n", req->tag);
......
227 218
        return;
228 219
    }
229 220

  
230
    ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
221
    ret = execute_command(s->conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
231 222
    if (ret < 0) {
232 223
        scsi_command_complete(r, ret);
233 224
    }
......
261 252

  
262 253
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
263 254
{
264
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
265 255
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
256
    SCSIDevice *s = r->req.dev;
266 257
    int ret;
267 258

  
268 259
    scsi_req_fixup(&r->req);
......
285 276
            g_free(r->buf);
286 277
        r->buflen = 0;
287 278
        r->buf = NULL;
288
        ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
279
        ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete);
289 280
        if (ret < 0) {
290 281
            scsi_command_complete(r, ret);
291 282
            return 0;
......
373 364

  
374 365
static void scsi_generic_reset(DeviceState *dev)
375 366
{
376
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
367
    SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev);
377 368

  
378
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
369
    scsi_device_purge_requests(s, SENSE_CODE(RESET));
379 370
}
380 371

  
381
static void scsi_destroy(SCSIDevice *d)
372
static void scsi_destroy(SCSIDevice *s)
382 373
{
383
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
384

  
385
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
386
    blockdev_mark_auto_del(s->qdev.conf.bs);
374
    scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
375
    blockdev_mark_auto_del(s->conf.bs);
387 376
}
388 377

  
389
static int scsi_generic_initfn(SCSIDevice *dev)
378
static int scsi_generic_initfn(SCSIDevice *s)
390 379
{
391
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
392 380
    int sg_version;
393 381
    struct sg_scsi_id scsiid;
394 382

  
395
    if (!s->qdev.conf.bs) {
383
    if (!s->conf.bs) {
396 384
        error_report("scsi-generic: drive property not set");
397 385
        return -1;
398 386
    }
399
    s->bs = s->qdev.conf.bs;
400 387

  
401 388
    /* check we are really using a /dev/sg* file */
402
    if (!bdrv_is_sg(s->bs)) {
389
    if (!bdrv_is_sg(s->conf.bs)) {
403 390
        error_report("scsi-generic: not /dev/sg*");
404 391
        return -1;
405 392
    }
406 393

  
407
    if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
394
    if (bdrv_get_on_error(s->conf.bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
408 395
        error_report("Device doesn't support drive option werror");
409 396
        return -1;
410 397
    }
411
    if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
398
    if (bdrv_get_on_error(s->conf.bs, 1) != BLOCK_ERR_REPORT) {
412 399
        error_report("Device doesn't support drive option rerror");
413 400
        return -1;
414 401
    }
415 402

  
416 403
    /* check we are using a driver managing SG_IO (version 3 and after */
417
    if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
404
    if (bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
418 405
        sg_version < 30000) {
419 406
        error_report("scsi-generic: scsi generic interface too old");
420 407
        return -1;
421 408
    }
422 409

  
423 410
    /* get LUN of the /dev/sg? */
424
    if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
411
    if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
425 412
        error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
426 413
        return -1;
427 414
    }
428 415

  
429 416
    /* define device state */
430
    s->qdev.type = scsiid.scsi_type;
431
    DPRINTF("device type %d\n", s->qdev.type);
432
    if (s->qdev.type == TYPE_TAPE) {
433
        s->qdev.blocksize = get_stream_blocksize(s->bs);
434
        if (s->qdev.blocksize == -1)
435
            s->qdev.blocksize = 0;
417
    s->type = scsiid.scsi_type;
418
    DPRINTF("device type %d\n", s->type);
419
    if (s->type == TYPE_TAPE) {
420
        s->blocksize = get_stream_blocksize(s->conf.bs);
421
        if (s->blocksize == -1) {
422
            s->blocksize = 0;
423
        }
436 424
    } else {
437
        s->qdev.blocksize = get_blocksize(s->bs);
425
        s->blocksize = get_blocksize(s->conf.bs);
438 426
        /* removable media returns 0 if not present */
439
        if (s->qdev.blocksize <= 0) {
440
            if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
441
                s->qdev.blocksize = 2048;
442
            else
443
                s->qdev.blocksize = 512;
427
        if (s->blocksize <= 0) {
428
            if (s->type == TYPE_ROM || s->type  == TYPE_WORM) {
429
                s->blocksize = 2048;
430
            } else {
431
                s->blocksize = 512;
432
            }
444 433
        }
445 434
    }
446
    DPRINTF("block size %d\n", s->qdev.blocksize);
435

  
436
    DPRINTF("block size %d\n", s->blocksize);
447 437
    return 0;
448 438
}
449 439

  
......
469 459
static SCSIDeviceInfo scsi_generic_info = {
470 460
    .qdev.name    = "scsi-generic",
471 461
    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
472
    .qdev.size    = sizeof(SCSIGenericState),
462
    .qdev.size    = sizeof(SCSIDevice),
473 463
    .qdev.reset   = scsi_generic_reset,
474 464
    .init         = scsi_generic_initfn,
475 465
    .destroy      = scsi_destroy,
476 466
    .alloc_req    = scsi_new_request,
477 467
    .qdev.props   = (Property[]) {
478
        DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
468
        DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf),
479 469
        DEFINE_PROP_END_OF_LIST(),
480 470
    },
481 471
};

Also available in: Unified diff