qdev-properties.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. #include "net.h"
  2. #include "qdev.h"
  3. #include "qerror.h"
  4. #include "blockdev.h"
  5. void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
  6. {
  7. void *ptr = dev;
  8. ptr += prop->offset;
  9. return ptr;
  10. }
  11. static uint32_t qdev_get_prop_mask(Property *prop)
  12. {
  13. assert(prop->info->type == PROP_TYPE_BIT);
  14. return 0x1 << prop->bitnr;
  15. }
  16. static void bit_prop_set(DeviceState *dev, Property *props, bool val)
  17. {
  18. uint32_t *p = qdev_get_prop_ptr(dev, props);
  19. uint32_t mask = qdev_get_prop_mask(props);
  20. if (val)
  21. *p |= mask;
  22. else
  23. *p &= ~mask;
  24. }
  25. static void qdev_prop_cpy(DeviceState *dev, Property *props, void *src)
  26. {
  27. if (props->info->type == PROP_TYPE_BIT) {
  28. bool *defval = src;
  29. bit_prop_set(dev, props, *defval);
  30. } else {
  31. char *dst = qdev_get_prop_ptr(dev, props);
  32. memcpy(dst, src, props->info->size);
  33. }
  34. }
  35. /* Bit */
  36. static int parse_bit(DeviceState *dev, Property *prop, const char *str)
  37. {
  38. if (!strncasecmp(str, "on", 2))
  39. bit_prop_set(dev, prop, true);
  40. else if (!strncasecmp(str, "off", 3))
  41. bit_prop_set(dev, prop, false);
  42. else
  43. return -EINVAL;
  44. return 0;
  45. }
  46. static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
  47. {
  48. uint32_t *p = qdev_get_prop_ptr(dev, prop);
  49. return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
  50. }
  51. PropertyInfo qdev_prop_bit = {
  52. .name = "on/off",
  53. .type = PROP_TYPE_BIT,
  54. .size = sizeof(uint32_t),
  55. .parse = parse_bit,
  56. .print = print_bit,
  57. };
  58. /* --- 8bit integer --- */
  59. static int parse_uint8(DeviceState *dev, Property *prop, const char *str)
  60. {
  61. uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
  62. char *end;
  63. /* accept both hex and decimal */
  64. *ptr = strtoul(str, &end, 0);
  65. if ((*end != '\0') || (end == str)) {
  66. return -EINVAL;
  67. }
  68. return 0;
  69. }
  70. static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len)
  71. {
  72. uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
  73. return snprintf(dest, len, "%" PRIu8, *ptr);
  74. }
  75. PropertyInfo qdev_prop_uint8 = {
  76. .name = "uint8",
  77. .type = PROP_TYPE_UINT8,
  78. .size = sizeof(uint8_t),
  79. .parse = parse_uint8,
  80. .print = print_uint8,
  81. };
  82. /* --- 8bit hex value --- */
  83. static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
  84. {
  85. uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
  86. char *end;
  87. *ptr = strtoul(str, &end, 16);
  88. if ((*end != '\0') || (end == str)) {
  89. return -EINVAL;
  90. }
  91. return 0;
  92. }
  93. static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
  94. {
  95. uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
  96. return snprintf(dest, len, "0x%" PRIx8, *ptr);
  97. }
  98. PropertyInfo qdev_prop_hex8 = {
  99. .name = "hex8",
  100. .type = PROP_TYPE_UINT8,
  101. .size = sizeof(uint8_t),
  102. .parse = parse_hex8,
  103. .print = print_hex8,
  104. };
  105. /* --- 16bit integer --- */
  106. static int parse_uint16(DeviceState *dev, Property *prop, const char *str)
  107. {
  108. uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
  109. char *end;
  110. /* accept both hex and decimal */
  111. *ptr = strtoul(str, &end, 0);
  112. if ((*end != '\0') || (end == str)) {
  113. return -EINVAL;
  114. }
  115. return 0;
  116. }
  117. static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len)
  118. {
  119. uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
  120. return snprintf(dest, len, "%" PRIu16, *ptr);
  121. }
  122. PropertyInfo qdev_prop_uint16 = {
  123. .name = "uint16",
  124. .type = PROP_TYPE_UINT16,
  125. .size = sizeof(uint16_t),
  126. .parse = parse_uint16,
  127. .print = print_uint16,
  128. };
  129. /* --- 32bit integer --- */
  130. static int parse_uint32(DeviceState *dev, Property *prop, const char *str)
  131. {
  132. uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
  133. char *end;
  134. /* accept both hex and decimal */
  135. *ptr = strtoul(str, &end, 0);
  136. if ((*end != '\0') || (end == str)) {
  137. return -EINVAL;
  138. }
  139. return 0;
  140. }
  141. static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len)
  142. {
  143. uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
  144. return snprintf(dest, len, "%" PRIu32, *ptr);
  145. }
  146. PropertyInfo qdev_prop_uint32 = {
  147. .name = "uint32",
  148. .type = PROP_TYPE_UINT32,
  149. .size = sizeof(uint32_t),
  150. .parse = parse_uint32,
  151. .print = print_uint32,
  152. };
  153. static int parse_int32(DeviceState *dev, Property *prop, const char *str)
  154. {
  155. int32_t *ptr = qdev_get_prop_ptr(dev, prop);
  156. char *end;
  157. *ptr = strtol(str, &end, 10);
  158. if ((*end != '\0') || (end == str)) {
  159. return -EINVAL;
  160. }
  161. return 0;
  162. }
  163. static int print_int32(DeviceState *dev, Property *prop, char *dest, size_t len)
  164. {
  165. int32_t *ptr = qdev_get_prop_ptr(dev, prop);
  166. return snprintf(dest, len, "%" PRId32, *ptr);
  167. }
  168. PropertyInfo qdev_prop_int32 = {
  169. .name = "int32",
  170. .type = PROP_TYPE_INT32,
  171. .size = sizeof(int32_t),
  172. .parse = parse_int32,
  173. .print = print_int32,
  174. };
  175. /* --- 32bit hex value --- */
  176. static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
  177. {
  178. uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
  179. char *end;
  180. *ptr = strtoul(str, &end, 16);
  181. if ((*end != '\0') || (end == str)) {
  182. return -EINVAL;
  183. }
  184. return 0;
  185. }
  186. static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
  187. {
  188. uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
  189. return snprintf(dest, len, "0x%" PRIx32, *ptr);
  190. }
  191. PropertyInfo qdev_prop_hex32 = {
  192. .name = "hex32",
  193. .type = PROP_TYPE_UINT32,
  194. .size = sizeof(uint32_t),
  195. .parse = parse_hex32,
  196. .print = print_hex32,
  197. };
  198. /* --- 64bit integer --- */
  199. static int parse_uint64(DeviceState *dev, Property *prop, const char *str)
  200. {
  201. uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
  202. char *end;
  203. /* accept both hex and decimal */
  204. *ptr = strtoull(str, &end, 0);
  205. if ((*end != '\0') || (end == str)) {
  206. return -EINVAL;
  207. }
  208. return 0;
  209. }
  210. static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len)
  211. {
  212. uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
  213. return snprintf(dest, len, "%" PRIu64, *ptr);
  214. }
  215. PropertyInfo qdev_prop_uint64 = {
  216. .name = "uint64",
  217. .type = PROP_TYPE_UINT64,
  218. .size = sizeof(uint64_t),
  219. .parse = parse_uint64,
  220. .print = print_uint64,
  221. };
  222. /* --- 64bit hex value --- */
  223. static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
  224. {
  225. uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
  226. char *end;
  227. *ptr = strtoull(str, &end, 16);
  228. if ((*end != '\0') || (end == str)) {
  229. return -EINVAL;
  230. }
  231. return 0;
  232. }
  233. static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
  234. {
  235. uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
  236. return snprintf(dest, len, "0x%" PRIx64, *ptr);
  237. }
  238. PropertyInfo qdev_prop_hex64 = {
  239. .name = "hex64",
  240. .type = PROP_TYPE_UINT64,
  241. .size = sizeof(uint64_t),
  242. .parse = parse_hex64,
  243. .print = print_hex64,
  244. };
  245. /* --- string --- */
  246. static int parse_string(DeviceState *dev, Property *prop, const char *str)
  247. {
  248. char **ptr = qdev_get_prop_ptr(dev, prop);
  249. if (*ptr)
  250. g_free(*ptr);
  251. *ptr = g_strdup(str);
  252. return 0;
  253. }
  254. static void free_string(DeviceState *dev, Property *prop)
  255. {
  256. g_free(*(char **)qdev_get_prop_ptr(dev, prop));
  257. }
  258. static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
  259. {
  260. char **ptr = qdev_get_prop_ptr(dev, prop);
  261. if (!*ptr)
  262. return snprintf(dest, len, "<null>");
  263. return snprintf(dest, len, "\"%s\"", *ptr);
  264. }
  265. PropertyInfo qdev_prop_string = {
  266. .name = "string",
  267. .type = PROP_TYPE_STRING,
  268. .size = sizeof(char*),
  269. .parse = parse_string,
  270. .print = print_string,
  271. .free = free_string,
  272. };
  273. /* --- drive --- */
  274. static int parse_drive(DeviceState *dev, Property *prop, const char *str)
  275. {
  276. BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
  277. BlockDriverState *bs;
  278. bs = bdrv_find(str);
  279. if (bs == NULL)
  280. return -ENOENT;
  281. if (bdrv_attach_dev(bs, dev) < 0)
  282. return -EEXIST;
  283. *ptr = bs;
  284. return 0;
  285. }
  286. static void free_drive(DeviceState *dev, Property *prop)
  287. {
  288. BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
  289. if (*ptr) {
  290. bdrv_detach_dev(*ptr, dev);
  291. blockdev_auto_del(*ptr);
  292. }
  293. }
  294. static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
  295. {
  296. BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
  297. return snprintf(dest, len, "%s",
  298. *ptr ? bdrv_get_device_name(*ptr) : "<null>");
  299. }
  300. PropertyInfo qdev_prop_drive = {
  301. .name = "drive",
  302. .type = PROP_TYPE_DRIVE,
  303. .size = sizeof(BlockDriverState *),
  304. .parse = parse_drive,
  305. .print = print_drive,
  306. .free = free_drive,
  307. };
  308. /* --- character device --- */
  309. static int parse_chr(DeviceState *dev, Property *prop, const char *str)
  310. {
  311. CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
  312. *ptr = qemu_chr_find(str);
  313. if (*ptr == NULL) {
  314. return -ENOENT;
  315. }
  316. if ((*ptr)->avail_connections < 1) {
  317. return -EEXIST;
  318. }
  319. --(*ptr)->avail_connections;
  320. return 0;
  321. }
  322. static int print_chr(DeviceState *dev, Property *prop, char *dest, size_t len)
  323. {
  324. CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
  325. if (*ptr && (*ptr)->label) {
  326. return snprintf(dest, len, "%s", (*ptr)->label);
  327. } else {
  328. return snprintf(dest, len, "<null>");
  329. }
  330. }
  331. PropertyInfo qdev_prop_chr = {
  332. .name = "chr",
  333. .type = PROP_TYPE_CHR,
  334. .size = sizeof(CharDriverState*),
  335. .parse = parse_chr,
  336. .print = print_chr,
  337. };
  338. /* --- netdev device --- */
  339. static int parse_netdev(DeviceState *dev, Property *prop, const char *str)
  340. {
  341. VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
  342. *ptr = qemu_find_netdev(str);
  343. if (*ptr == NULL)
  344. return -ENOENT;
  345. if ((*ptr)->peer) {
  346. return -EEXIST;
  347. }
  348. return 0;
  349. }
  350. static int print_netdev(DeviceState *dev, Property *prop, char *dest, size_t len)
  351. {
  352. VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
  353. if (*ptr && (*ptr)->name) {
  354. return snprintf(dest, len, "%s", (*ptr)->name);
  355. } else {
  356. return snprintf(dest, len, "<null>");
  357. }
  358. }
  359. PropertyInfo qdev_prop_netdev = {
  360. .name = "netdev",
  361. .type = PROP_TYPE_NETDEV,
  362. .size = sizeof(VLANClientState*),
  363. .parse = parse_netdev,
  364. .print = print_netdev,
  365. };
  366. /* --- vlan --- */
  367. static int parse_vlan(DeviceState *dev, Property *prop, const char *str)
  368. {
  369. VLANState **ptr = qdev_get_prop_ptr(dev, prop);
  370. int id;
  371. if (sscanf(str, "%d", &id) != 1)
  372. return -EINVAL;
  373. *ptr = qemu_find_vlan(id, 1);
  374. if (*ptr == NULL)
  375. return -ENOENT;
  376. return 0;
  377. }
  378. static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
  379. {
  380. VLANState **ptr = qdev_get_prop_ptr(dev, prop);
  381. if (*ptr) {
  382. return snprintf(dest, len, "%d", (*ptr)->id);
  383. } else {
  384. return snprintf(dest, len, "<null>");
  385. }
  386. }
  387. PropertyInfo qdev_prop_vlan = {
  388. .name = "vlan",
  389. .type = PROP_TYPE_VLAN,
  390. .size = sizeof(VLANClientState*),
  391. .parse = parse_vlan,
  392. .print = print_vlan,
  393. };
  394. /* --- pointer --- */
  395. /* Not a proper property, just for dirty hacks. TODO Remove it! */
  396. PropertyInfo qdev_prop_ptr = {
  397. .name = "ptr",
  398. .type = PROP_TYPE_PTR,
  399. .size = sizeof(void*),
  400. };
  401. /* --- mac address --- */
  402. /*
  403. * accepted syntax versions:
  404. * 01:02:03:04:05:06
  405. * 01-02-03-04-05-06
  406. */
  407. static int parse_mac(DeviceState *dev, Property *prop, const char *str)
  408. {
  409. MACAddr *mac = qdev_get_prop_ptr(dev, prop);
  410. int i, pos;
  411. char *p;
  412. for (i = 0, pos = 0; i < 6; i++, pos += 3) {
  413. if (!qemu_isxdigit(str[pos]))
  414. return -EINVAL;
  415. if (!qemu_isxdigit(str[pos+1]))
  416. return -EINVAL;
  417. if (i == 5) {
  418. if (str[pos+2] != '\0')
  419. return -EINVAL;
  420. } else {
  421. if (str[pos+2] != ':' && str[pos+2] != '-')
  422. return -EINVAL;
  423. }
  424. mac->a[i] = strtol(str+pos, &p, 16);
  425. }
  426. return 0;
  427. }
  428. static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len)
  429. {
  430. MACAddr *mac = qdev_get_prop_ptr(dev, prop);
  431. return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x",
  432. mac->a[0], mac->a[1], mac->a[2],
  433. mac->a[3], mac->a[4], mac->a[5]);
  434. }
  435. PropertyInfo qdev_prop_macaddr = {
  436. .name = "macaddr",
  437. .type = PROP_TYPE_MACADDR,
  438. .size = sizeof(MACAddr),
  439. .parse = parse_mac,
  440. .print = print_mac,
  441. };
  442. /* --- pci address --- */
  443. /*
  444. * bus-local address, i.e. "$slot" or "$slot.$fn"
  445. */
  446. static int parse_pci_devfn(DeviceState *dev, Property *prop, const char *str)
  447. {
  448. uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
  449. unsigned int slot, fn, n;
  450. if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
  451. fn = 0;
  452. if (sscanf(str, "%x%n", &slot, &n) != 1) {
  453. return -EINVAL;
  454. }
  455. }
  456. if (str[n] != '\0')
  457. return -EINVAL;
  458. if (fn > 7)
  459. return -EINVAL;
  460. if (slot > 31)
  461. return -EINVAL;
  462. *ptr = slot << 3 | fn;
  463. return 0;
  464. }
  465. static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
  466. {
  467. uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
  468. if (*ptr == -1) {
  469. return snprintf(dest, len, "<unset>");
  470. } else {
  471. return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
  472. }
  473. }
  474. PropertyInfo qdev_prop_pci_devfn = {
  475. .name = "pci-devfn",
  476. .type = PROP_TYPE_UINT32,
  477. .size = sizeof(uint32_t),
  478. .parse = parse_pci_devfn,
  479. .print = print_pci_devfn,
  480. };
  481. /* --- public helpers --- */
  482. static Property *qdev_prop_walk(Property *props, const char *name)
  483. {
  484. if (!props)
  485. return NULL;
  486. while (props->name) {
  487. if (strcmp(props->name, name) == 0)
  488. return props;
  489. props++;
  490. }
  491. return NULL;
  492. }
  493. static Property *qdev_prop_find(DeviceState *dev, const char *name)
  494. {
  495. Property *prop;
  496. /* device properties */
  497. prop = qdev_prop_walk(dev->info->props, name);
  498. if (prop)
  499. return prop;
  500. /* bus properties */
  501. prop = qdev_prop_walk(dev->parent_bus->info->props, name);
  502. if (prop)
  503. return prop;
  504. return NULL;
  505. }
  506. int qdev_prop_exists(DeviceState *dev, const char *name)
  507. {
  508. return qdev_prop_find(dev, name) ? true : false;
  509. }
  510. int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
  511. {
  512. Property *prop;
  513. int ret;
  514. prop = qdev_prop_find(dev, name);
  515. /*
  516. * TODO Properties without a parse method are just for dirty
  517. * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
  518. * marked for removal. The test !prop->info->parse should be
  519. * removed along with it.
  520. */
  521. if (!prop || !prop->info->parse) {
  522. qerror_report(QERR_PROPERTY_NOT_FOUND, dev->info->name, name);
  523. return -1;
  524. }
  525. ret = prop->info->parse(dev, prop, value);
  526. if (ret < 0) {
  527. switch (ret) {
  528. case -EEXIST:
  529. qerror_report(QERR_PROPERTY_VALUE_IN_USE,
  530. dev->info->name, name, value);
  531. break;
  532. default:
  533. case -EINVAL:
  534. qerror_report(QERR_PROPERTY_VALUE_BAD,
  535. dev->info->name, name, value);
  536. break;
  537. case -ENOENT:
  538. qerror_report(QERR_PROPERTY_VALUE_NOT_FOUND,
  539. dev->info->name, name, value);
  540. break;
  541. }
  542. return -1;
  543. }
  544. return 0;
  545. }
  546. void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
  547. {
  548. Property *prop;
  549. prop = qdev_prop_find(dev, name);
  550. if (!prop) {
  551. fprintf(stderr, "%s: property \"%s.%s\" not found\n",
  552. __FUNCTION__, dev->info->name, name);
  553. abort();
  554. }
  555. if (prop->info->type != type) {
  556. fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",
  557. __FUNCTION__, dev->info->name, name);
  558. abort();
  559. }
  560. qdev_prop_cpy(dev, prop, src);
  561. }
  562. void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
  563. {
  564. qdev_prop_set(dev, name, &value, PROP_TYPE_BIT);
  565. }
  566. void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
  567. {
  568. qdev_prop_set(dev, name, &value, PROP_TYPE_UINT8);
  569. }
  570. void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
  571. {
  572. qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16);
  573. }
  574. void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
  575. {
  576. qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32);
  577. }
  578. void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
  579. {
  580. qdev_prop_set(dev, name, &value, PROP_TYPE_INT32);
  581. }
  582. void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
  583. {
  584. qdev_prop_set(dev, name, &value, PROP_TYPE_UINT64);
  585. }
  586. void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
  587. {
  588. qdev_prop_set(dev, name, &value, PROP_TYPE_STRING);
  589. }
  590. int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
  591. {
  592. int res;
  593. res = bdrv_attach_dev(value, dev);
  594. if (res < 0) {
  595. error_report("Can't attach drive %s to %s.%s: %s",
  596. bdrv_get_device_name(value),
  597. dev->id ? dev->id : dev->info->name,
  598. name, strerror(-res));
  599. return -1;
  600. }
  601. qdev_prop_set(dev, name, &value, PROP_TYPE_DRIVE);
  602. return 0;
  603. }
  604. void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value)
  605. {
  606. if (qdev_prop_set_drive(dev, name, value) < 0) {
  607. exit(1);
  608. }
  609. }
  610. void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
  611. {
  612. qdev_prop_set(dev, name, &value, PROP_TYPE_CHR);
  613. }
  614. void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
  615. {
  616. qdev_prop_set(dev, name, &value, PROP_TYPE_NETDEV);
  617. }
  618. void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
  619. {
  620. qdev_prop_set(dev, name, &value, PROP_TYPE_VLAN);
  621. }
  622. void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
  623. {
  624. qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
  625. }
  626. void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
  627. {
  628. qdev_prop_set(dev, name, &value, PROP_TYPE_PTR);
  629. }
  630. void qdev_prop_set_defaults(DeviceState *dev, Property *props)
  631. {
  632. if (!props)
  633. return;
  634. while (props->name) {
  635. if (props->defval) {
  636. qdev_prop_cpy(dev, props, props->defval);
  637. }
  638. props++;
  639. }
  640. }
  641. static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
  642. static void qdev_prop_register_global(GlobalProperty *prop)
  643. {
  644. QTAILQ_INSERT_TAIL(&global_props, prop, next);
  645. }
  646. void qdev_prop_register_global_list(GlobalProperty *props)
  647. {
  648. int i;
  649. for (i = 0; props[i].driver != NULL; i++) {
  650. qdev_prop_register_global(props+i);
  651. }
  652. }
  653. void qdev_prop_set_globals(DeviceState *dev)
  654. {
  655. GlobalProperty *prop;
  656. QTAILQ_FOREACH(prop, &global_props, next) {
  657. if (strcmp(dev->info->name, prop->driver) != 0 &&
  658. strcmp(dev->info->bus_info->name, prop->driver) != 0) {
  659. continue;
  660. }
  661. if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
  662. exit(1);
  663. }
  664. }
  665. }
  666. static int qdev_add_one_global(QemuOpts *opts, void *opaque)
  667. {
  668. GlobalProperty *g;
  669. g = g_malloc0(sizeof(*g));
  670. g->driver = qemu_opt_get(opts, "driver");
  671. g->property = qemu_opt_get(opts, "property");
  672. g->value = qemu_opt_get(opts, "value");
  673. qdev_prop_register_global(g);
  674. return 0;
  675. }
  676. void qemu_add_globals(void)
  677. {
  678. qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0);
  679. }