|
|
1.1 ! root 1: #include "qdev.h" ! 2: ! 3: void *qdev_get_prop_ptr(DeviceState *dev, Property *prop) ! 4: { ! 5: void *ptr = dev; ! 6: ptr += prop->offset; ! 7: return ptr; ! 8: } ! 9: ! 10: /* --- 16bit integer --- */ ! 11: ! 12: static int parse_uint16(DeviceState *dev, Property *prop, const char *str) ! 13: { ! 14: uint16_t *ptr = qdev_get_prop_ptr(dev, prop); ! 15: const char *fmt; ! 16: ! 17: /* accept both hex and decimal */ ! 18: fmt = strncasecmp(str, "0x",2) == 0 ? "%" PRIx16 : "%" PRIu16; ! 19: if (sscanf(str, fmt, ptr) != 1) ! 20: return -1; ! 21: return 0; ! 22: } ! 23: ! 24: static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len) ! 25: { ! 26: uint16_t *ptr = qdev_get_prop_ptr(dev, prop); ! 27: return snprintf(dest, len, "%" PRIu16, *ptr); ! 28: } ! 29: ! 30: PropertyInfo qdev_prop_uint16 = { ! 31: .name = "uint16", ! 32: .type = PROP_TYPE_UINT16, ! 33: .size = sizeof(uint16_t), ! 34: .parse = parse_uint16, ! 35: .print = print_uint16, ! 36: }; ! 37: ! 38: /* --- 32bit integer --- */ ! 39: ! 40: static int parse_uint32(DeviceState *dev, Property *prop, const char *str) ! 41: { ! 42: uint32_t *ptr = qdev_get_prop_ptr(dev, prop); ! 43: const char *fmt; ! 44: ! 45: /* accept both hex and decimal */ ! 46: fmt = strncasecmp(str, "0x",2) == 0 ? "%" PRIx32 : "%" PRIu32; ! 47: if (sscanf(str, fmt, ptr) != 1) ! 48: return -1; ! 49: return 0; ! 50: } ! 51: ! 52: static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len) ! 53: { ! 54: uint32_t *ptr = qdev_get_prop_ptr(dev, prop); ! 55: return snprintf(dest, len, "%" PRIu32, *ptr); ! 56: } ! 57: ! 58: PropertyInfo qdev_prop_uint32 = { ! 59: .name = "uint32", ! 60: .type = PROP_TYPE_UINT32, ! 61: .size = sizeof(uint32_t), ! 62: .parse = parse_uint32, ! 63: .print = print_uint32, ! 64: }; ! 65: ! 66: /* --- 32bit hex value --- */ ! 67: ! 68: static int parse_hex32(DeviceState *dev, Property *prop, const char *str) ! 69: { ! 70: uint32_t *ptr = qdev_get_prop_ptr(dev, prop); ! 71: ! 72: if (sscanf(str, "%" PRIx32, ptr) != 1) ! 73: return -1; ! 74: return 0; ! 75: } ! 76: ! 77: static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len) ! 78: { ! 79: uint32_t *ptr = qdev_get_prop_ptr(dev, prop); ! 80: return snprintf(dest, len, "0x%" PRIx32, *ptr); ! 81: } ! 82: ! 83: PropertyInfo qdev_prop_hex32 = { ! 84: .name = "hex32", ! 85: .type = PROP_TYPE_UINT32, ! 86: .size = sizeof(uint32_t), ! 87: .parse = parse_hex32, ! 88: .print = print_hex32, ! 89: }; ! 90: ! 91: /* --- pointer --- */ ! 92: ! 93: static int print_ptr(DeviceState *dev, Property *prop, char *dest, size_t len) ! 94: { ! 95: void **ptr = qdev_get_prop_ptr(dev, prop); ! 96: return snprintf(dest, len, "<%p>", *ptr); ! 97: } ! 98: ! 99: PropertyInfo qdev_prop_ptr = { ! 100: .name = "ptr", ! 101: .type = PROP_TYPE_PTR, ! 102: .size = sizeof(void*), ! 103: .print = print_ptr, ! 104: }; ! 105: ! 106: /* --- mac address --- */ ! 107: ! 108: /* ! 109: * accepted syntax versions: ! 110: * 01:02:03:04:05:06 ! 111: * 01-02-03-04-05-06 ! 112: */ ! 113: static int parse_mac(DeviceState *dev, Property *prop, const char *str) ! 114: { ! 115: uint8_t *mac = qdev_get_prop_ptr(dev, prop); ! 116: int i, pos; ! 117: char *p; ! 118: ! 119: for (i = 0, pos = 0; i < 6; i++, pos += 3) { ! 120: if (!qemu_isxdigit(str[pos])) ! 121: return -1; ! 122: if (!qemu_isxdigit(str[pos+1])) ! 123: return -1; ! 124: if (i == 5 && str[pos+2] != '\0') ! 125: return -1; ! 126: if (str[pos+2] != ':' && str[pos+2] != '-') ! 127: return -1; ! 128: mac[i] = strtol(str+pos, &p, 16); ! 129: } ! 130: return 0; ! 131: } ! 132: ! 133: static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len) ! 134: { ! 135: uint8_t *mac = qdev_get_prop_ptr(dev, prop); ! 136: return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x", ! 137: mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); ! 138: } ! 139: ! 140: PropertyInfo qdev_prop_macaddr = { ! 141: .name = "mac-addr", ! 142: .type = PROP_TYPE_MACADDR, ! 143: .size = 6, ! 144: .parse = parse_mac, ! 145: .print = print_mac, ! 146: }; ! 147: ! 148: /* --- public helpers --- */ ! 149: ! 150: static Property *qdev_prop_walk(Property *props, const char *name) ! 151: { ! 152: if (!props) ! 153: return NULL; ! 154: while (props->name) { ! 155: if (strcmp(props->name, name) == 0) ! 156: return props; ! 157: props++; ! 158: } ! 159: return NULL; ! 160: } ! 161: ! 162: static Property *qdev_prop_find(DeviceState *dev, const char *name) ! 163: { ! 164: Property *prop; ! 165: ! 166: /* device properties */ ! 167: prop = qdev_prop_walk(dev->info->props, name); ! 168: if (prop) ! 169: return prop; ! 170: ! 171: /* bus properties */ ! 172: prop = qdev_prop_walk(dev->parent_bus->info->props, name); ! 173: if (prop) ! 174: return prop; ! 175: ! 176: return NULL; ! 177: } ! 178: ! 179: int qdev_prop_parse(DeviceState *dev, const char *name, const char *value) ! 180: { ! 181: Property *prop; ! 182: ! 183: prop = qdev_prop_find(dev, name); ! 184: if (!prop) { ! 185: fprintf(stderr, "property \"%s.%s\" not found\n", ! 186: dev->info->name, name); ! 187: return -1; ! 188: } ! 189: if (!prop->info->parse) { ! 190: fprintf(stderr, "property \"%s.%s\" has no parser\n", ! 191: dev->info->name, name); ! 192: return -1; ! 193: } ! 194: return prop->info->parse(dev, prop, value); ! 195: } ! 196: ! 197: void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type) ! 198: { ! 199: Property *prop; ! 200: void *dst; ! 201: ! 202: prop = qdev_prop_find(dev, name); ! 203: if (!prop) { ! 204: fprintf(stderr, "%s: property \"%s.%s\" not found\n", ! 205: __FUNCTION__, dev->info->name, name); ! 206: abort(); ! 207: } ! 208: if (prop->info->type != type) { ! 209: fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n", ! 210: __FUNCTION__, dev->info->name, name); ! 211: abort(); ! 212: } ! 213: dst = qdev_get_prop_ptr(dev, prop); ! 214: memcpy(dst, src, prop->info->size); ! 215: } ! 216: ! 217: void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) ! 218: { ! 219: qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16); ! 220: } ! 221: ! 222: void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) ! 223: { ! 224: qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32); ! 225: } ! 226: ! 227: void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) ! 228: { ! 229: qdev_prop_set(dev, name, &value, PROP_TYPE_PTR); ! 230: } ! 231: ! 232: void qdev_prop_set_defaults(DeviceState *dev, Property *props) ! 233: { ! 234: char *dst; ! 235: ! 236: if (!props) ! 237: return; ! 238: while (props->name) { ! 239: if (props->defval) { ! 240: dst = qdev_get_prop_ptr(dev, props); ! 241: memcpy(dst, props->defval, props->info->size); ! 242: } ! 243: props++; ! 244: } ! 245: } ! 246: ! 247: static CompatProperty *compat_props; ! 248: ! 249: void qdev_prop_register_compat(CompatProperty *props) ! 250: { ! 251: compat_props = props; ! 252: } ! 253: ! 254: void qdev_prop_set_compat(DeviceState *dev) ! 255: { ! 256: CompatProperty *prop; ! 257: ! 258: if (!compat_props) { ! 259: return; ! 260: } ! 261: for (prop = compat_props; prop->driver != NULL; prop++) { ! 262: if (strcmp(dev->info->name, prop->driver) != 0) { ! 263: continue; ! 264: } ! 265: if (qdev_prop_parse(dev, prop->property, prop->value) != 0) { ! 266: abort(); ! 267: } ! 268: } ! 269: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.