Revision c701b35b hw/i2c.c
b/hw/i2c.c | ||
---|---|---|
14 | 14 |
{ |
15 | 15 |
i2c_slave *current_dev; |
16 | 16 |
i2c_slave *dev; |
17 |
int saved_address; |
|
17 | 18 |
}; |
18 | 19 |
|
20 |
static void i2c_bus_save(QEMUFile *f, void *opaque) |
|
21 |
{ |
|
22 |
i2c_bus *bus = (i2c_bus *)opaque; |
|
23 |
|
|
24 |
qemu_put_byte(f, bus->current_dev ? bus->current_dev->address : -1); |
|
25 |
} |
|
26 |
|
|
27 |
static int i2c_bus_load(QEMUFile *f, void *opaque, int version_id) |
|
28 |
{ |
|
29 |
i2c_bus *bus = (i2c_bus *)opaque; |
|
30 |
|
|
31 |
if (version_id != 1) |
|
32 |
return -EINVAL; |
|
33 |
|
|
34 |
/* The bus is loaded before attached devices, so load and save the |
|
35 |
current device id. Devices will check themselves as loaded. */ |
|
36 |
bus->saved_address = qemu_get_be32(f); |
|
37 |
bus->current_dev = NULL; |
|
38 |
|
|
39 |
return 0; |
|
40 |
} |
|
41 |
|
|
19 | 42 |
/* Create a new I2C bus. */ |
20 | 43 |
i2c_bus *i2c_init_bus(void) |
21 | 44 |
{ |
22 | 45 |
i2c_bus *bus; |
23 | 46 |
|
24 | 47 |
bus = (i2c_bus *)qemu_mallocz(sizeof(i2c_bus)); |
48 |
register_savevm("i2c_bus", -1, 1, i2c_bus_save, i2c_bus_load, bus); |
|
25 | 49 |
return bus; |
26 | 50 |
} |
27 | 51 |
|
... | ... | |
37 | 61 |
dev->address = address; |
38 | 62 |
dev->next = bus->dev; |
39 | 63 |
bus->dev = dev; |
64 |
dev->bus = bus; |
|
40 | 65 |
|
41 | 66 |
return dev; |
42 | 67 |
} |
... | ... | |
115 | 140 |
dev->event(dev, I2C_NACK); |
116 | 141 |
} |
117 | 142 |
|
118 |
void i2c_bus_save(QEMUFile *f, i2c_bus *bus) |
|
119 |
{ |
|
120 |
qemu_put_byte(f, bus->current_dev ? bus->current_dev->address : 0x00); |
|
121 |
} |
|
122 |
|
|
123 |
void i2c_bus_load(QEMUFile *f, i2c_bus *bus) |
|
124 |
{ |
|
125 |
i2c_slave *dev; |
|
126 |
uint8_t address = qemu_get_byte(f); |
|
127 |
|
|
128 |
if (address) { |
|
129 |
for (dev = bus->dev; dev; dev = dev->next) |
|
130 |
if (dev->address == address) { |
|
131 |
bus->current_dev = dev; |
|
132 |
return; |
|
133 |
} |
|
134 |
|
|
135 |
fprintf(stderr, "%s: I2C slave with address %02x disappeared\n", |
|
136 |
__FUNCTION__, address); |
|
137 |
} |
|
138 |
} |
|
139 |
|
|
140 | 143 |
void i2c_slave_save(QEMUFile *f, i2c_slave *dev) |
141 | 144 |
{ |
142 | 145 |
qemu_put_byte(f, dev->address); |
... | ... | |
145 | 148 |
void i2c_slave_load(QEMUFile *f, i2c_slave *dev) |
146 | 149 |
{ |
147 | 150 |
dev->address = qemu_get_byte(f); |
151 |
if (dev->bus->saved_address == dev->address) |
|
152 |
dev->bus->current_dev = dev; |
|
148 | 153 |
} |
Also available in: Unified diff