Revision bf011293

b/hw/virtio-blk.c
25 25
    BlockDriverState *bs;
26 26
    VirtQueue *vq;
27 27
    void *rq;
28
    char serial_str[BLOCK_SERIAL_STRLEN + 1];
28 29
} VirtIOBlock;
29 30

  
30 31
static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
......
32 33
    return (VirtIOBlock *)vdev;
33 34
}
34 35

  
36
/* store identify data in little endian format
37
 */
38
static inline void put_le16(uint16_t *p, unsigned int v)
39
{
40
    *p = cpu_to_le16(v);
41
}
42

  
43
/* copy to *dst from *src, nul pad dst tail as needed to len bytes
44
 */
45
static inline void padstr(char *dst, const char *src, int len)
46
{
47
    while (len--)
48
        *dst++ = *src ? *src++ : '\0';
49
}
50

  
51
/* setup simulated identify data as appropriate for virtio block device
52
 *
53
 * ref: AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
54
 */
55
static inline void virtio_identify_template(struct virtio_blk_config *bc)
56
{
57
    uint16_t *p = &bc->identify[0];
58
    uint64_t lba_sectors = bc->capacity;
59

  
60
    memset(p, 0, sizeof(bc->identify));
61
    put_le16(p + 0, 0x0);                            /* ATA device */
62
    padstr((char *)(p + 23), QEMU_VERSION, 8);       /* firmware revision */
63
    padstr((char *)(p + 27), "QEMU VIRT_BLK", 40);   /* model# */
64
    put_le16(p + 47, 0x80ff);                        /* max xfer 255 sectors */
65
    put_le16(p + 49, 0x0b00);                        /* support IORDY/LBA/DMA */
66
    put_le16(p + 59, 0x1ff);                         /* cur xfer 255 sectors */
67
    put_le16(p + 80, 0x1f0);                         /* support ATA8/7/6/5/4 */
68
    put_le16(p + 81, 0x16);
69
    put_le16(p + 82, 0x400);
70
    put_le16(p + 83, 0x400);
71
    put_le16(p + 100, lba_sectors);
72
    put_le16(p + 101, lba_sectors >> 16);
73
    put_le16(p + 102, lba_sectors >> 32);
74
    put_le16(p + 103, lba_sectors >> 48);
75
}
76

  
35 77
typedef struct VirtIOBlockReq
36 78
{
37 79
    VirtIOBlock *dev;
......
285 327
    qemu_aio_flush();
286 328
}
287 329

  
330
/* coalesce internal state, copy to pci i/o region 0
331
 */
288 332
static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
289 333
{
290 334
    VirtIOBlock *s = to_virtio_blk(vdev);
......
301 345
    blkcfg.heads = heads;
302 346
    blkcfg.sectors = secs;
303 347
    blkcfg.size_max = 0;
348
    virtio_identify_template(&blkcfg);
349
    memcpy(&blkcfg.identify[VIRTIO_BLK_ID_SN], s->serial_str,
350
        VIRTIO_BLK_ID_SN_BYTES);
304 351
    memcpy(config, &blkcfg, sizeof(blkcfg));
305 352
}
306 353

  
307 354
static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
308 355
{
356
    VirtIOBlock *s = to_virtio_blk(vdev);
309 357
    uint32_t features = 0;
310 358

  
311 359
    features |= (1 << VIRTIO_BLK_F_SEG_MAX);
......
313 361
#ifdef __linux__
314 362
    features |= (1 << VIRTIO_BLK_F_SCSI);
315 363
#endif
364
    if (strcmp(s->serial_str, "0"))
365
        features |= 1 << VIRTIO_BLK_F_IDENTIFY;
316 366

  
317 367
    return features;
318 368
}
......
356 406
    int cylinders, heads, secs;
357 407
    static int virtio_blk_id;
358 408
    BlockDriverState *bs;
409
    char *ps;
359 410

  
360 411
    s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
361 412
                                          sizeof(struct virtio_blk_config),
......
367 418
    s->vdev.reset = virtio_blk_reset;
368 419
    s->bs = bs;
369 420
    s->rq = NULL;
421
    if (strlen(ps = (char *)drive_get_serial(bs)))
422
        strncpy(s->serial_str, ps, sizeof(s->serial_str));
423
    else
424
        snprintf(s->serial_str, sizeof(s->serial_str), "0");
370 425
    bs->private = dev;
371 426
    bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
372 427
    bdrv_set_geometry_hint(s->bs, cylinders, heads, secs);
b/hw/virtio-blk.h
30 30
#define VIRTIO_BLK_F_RO         5       /* Disk is read-only */
31 31
#define VIRTIO_BLK_F_BLK_SIZE   6       /* Block size of disk is available*/
32 32
#define VIRTIO_BLK_F_SCSI       7       /* Supports scsi command passthru */
33
#define VIRTIO_BLK_F_IDENTIFY   8       /* ATA IDENTIFY supported */
34

  
35
#define VIRTIO_BLK_ID_LEN       256     /* length of identify u16 array */
36
#define VIRTIO_BLK_ID_SN        10      /* start of char * serial# */
37
#define VIRTIO_BLK_ID_SN_BYTES  20      /* length in bytes of serial# */
33 38

  
34 39
struct virtio_blk_config
35 40
{
......
39 44
    uint16_t cylinders;
40 45
    uint8_t heads;
41 46
    uint8_t sectors;
47
    uint32_t _blk_size;    /* structure pad, currently unused */
48
    uint16_t identify[VIRTIO_BLK_ID_LEN];
42 49
} __attribute__((packed));
43 50

  
44 51
/* These two define direction. */
b/sysemu.h
154 154
    BLOCK_ERR_STOP_ANY
155 155
} BlockInterfaceErrorAction;
156 156

  
157
#define BLOCK_SERIAL_STRLEN 20
158

  
157 159
typedef struct DriveInfo {
158 160
    BlockDriverState *bdrv;
159 161
    const char *devaddr;
......
163 165
    int used;
164 166
    int drive_opt_idx;
165 167
    BlockInterfaceErrorAction onerror;
166
    char serial[21];
168
    char serial[BLOCK_SERIAL_STRLEN + 1];
167 169
} DriveInfo;
168 170

  
169 171
#define MAX_IDE_DEVS	2

Also available in: Unified diff