Statistics
| Branch: | Revision:

root / hw / scsi-bus.c @ 6f3a7798

History | View | Annotate | Download (2.4 kB)

1
#include "hw.h"
2
#include "sysemu.h"
3
#include "scsi-disk.h"
4
#include "block.h"
5
#include "qdev.h"
6

    
7
static struct BusInfo scsi_bus_info = {
8
    .name  = "SCSI",
9
    .size  = sizeof(SCSIBus),
10
    .props = (Property[]) {
11
        DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
12
        DEFINE_PROP_END_OF_LIST(),
13
    },
14
};
15
static int next_scsi_bus;
16

    
17
/* Create a scsi bus, and attach devices to it.  */
18
SCSIBus *scsi_bus_new(DeviceState *host, int tcq, int ndev,
19
                      scsi_completionfn complete)
20
{
21
    SCSIBus *bus;
22

    
23
    bus = FROM_QBUS(SCSIBus, qbus_create(&scsi_bus_info, host, NULL));
24
    bus->busnr = next_scsi_bus++;
25
    bus->tcq = tcq;
26
    bus->ndev = ndev;
27
    bus->complete = complete;
28
    return bus;
29
}
30

    
31
static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
32
{
33
    SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
34
    SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base);
35
    SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
36

    
37
    if (dev->id == -1) {
38
        for (dev->id = 0; dev->id < bus->ndev; dev->id++) {
39
            if (bus->devs[dev->id] == NULL)
40
                break;
41
        }
42
    }
43
    if (dev->id >= bus->ndev) {
44
        qemu_error("bad scsi device id: %d\n", dev->id);
45
        goto err;
46
    }
47

    
48
    if (bus->devs[dev->id]) {
49
        bus->devs[dev->id]->info->destroy(bus->devs[dev->id]);
50
    }
51
    bus->devs[dev->id] = dev;
52

    
53
    dev->info = info;
54
    return dev->info->init(dev);
55

    
56
err:
57
    return -1;
58
}
59

    
60
void scsi_qdev_register(SCSIDeviceInfo *info)
61
{
62
    info->qdev.bus_info = &scsi_bus_info;
63
    info->qdev.init     = scsi_qdev_init;
64
    qdev_register(&info->qdev);
65
}
66

    
67
/* handle legacy '-drive if=scsi,...' cmd line args */
68
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit)
69
{
70
    const char *driver;
71
    DeviceState *dev;
72

    
73
    driver = bdrv_is_sg(dinfo->bdrv) ? "scsi-generic" : "scsi-disk";
74
    dev = qdev_create(&bus->qbus, driver);
75
    qdev_prop_set_uint32(dev, "scsi-id", unit);
76
    qdev_prop_set_drive(dev, "drive", dinfo);
77
    qdev_init(dev);
78
    return DO_UPCAST(SCSIDevice, qdev, dev);
79
}
80

    
81
void scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
82
{
83
    DriveInfo *dinfo;
84
    int unit;
85

    
86
    for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
87
        dinfo = drive_get(IF_SCSI, bus->busnr, unit);
88
        if (dinfo == NULL) {
89
            continue;
90
        }
91
        scsi_bus_legacy_add_drive(bus, dinfo, unit);
92
    }
93
}