~ubuntu-branches/ubuntu/edgy/hwinfo/edgy

« back to all changes in this revision

Viewing changes to src/hd/manual.c

  • Committer: Bazaar Package Importer
  • Author(s): James Vega
  • Date: 2006-09-28 20:56:06 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060928205606-bgxl69hts04xbx51
Tags: 13.4-1
* New upstream version.
* Switch from dbs to quilt
  - Revamp debian/rules
  - Add quilt and remove dbs from Build-Depends in debian/control
* Remove reference to hwscan(8) from manpage. (closes: #388245)
* Re-wrote manpage from scratch.  Drop docbook-to-man from Build-Depends.
* Remove NEWS.Debian since it is no longer applicable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <unistd.h>
 
5
#include <dirent.h>
 
6
#include <ctype.h>
 
7
#include <sys/types.h>
 
8
#include <sys/stat.h>
 
9
 
 
10
#include "hd.h"
 
11
#include "hd_int.h"
 
12
#include "manual.h"
 
13
#include "hddb.h"
 
14
 
 
15
/**
 
16
 * @defgroup Manualint UDI manual hardware 
 
17
 * @ingroup  libhdInternals
 
18
 * @brief Manual hardware information functions (/var/lib/hardware/udi/)
 
19
 *
 
20
 * @{
 
21
 */
 
22
 
 
23
#include <hwclass_names.h>
 
24
 
 
25
/* corresponds to hd_status_value_t */
 
26
static hash_t status_names[] = {
 
27
  { status_no,      "no"      },
 
28
  { status_yes,     "yes"     },
 
29
  { status_unknown, "unknown" },
 
30
  { status_new,     "new"     },
 
31
  { 0,              NULL      }
 
32
};
 
33
 
 
34
#ifndef LIBHD_TINY
 
35
 
 
36
static void prop2hd(hd_data_t *hd_data, hd_t *hd, int status_only);
 
37
static hal_prop_t *hal_get_new(hal_prop_t **list, const char *key);
 
38
static void hd2prop_add_int32(hal_prop_t **list, const char *key, int32_t i);
 
39
static void hd2prop_add_str(hal_prop_t **list, const char *key, const char *str);
 
40
static void hd2prop_add_list(hal_prop_t **list, const char *key, str_list_t *sl);
 
41
static void hd2prop_append_list(hal_prop_t **list, const char *key, char *str);
 
42
static void hd2prop(hd_data_t *hd_data, hd_t *hd);
 
43
 
 
44
static hal_prop_t *hd_manual_read_entry_old(const char *id);
 
45
static hal_prop_t *read_properties(hd_data_t *hd_data, const char *udi, const char *id);
 
46
 
 
47
 
 
48
void hd_scan_manual(hd_data_t *hd_data)
 
49
{
 
50
  DIR *dir;
 
51
  struct dirent *de;
 
52
  int i;
 
53
  hd_t *hd, *hd1, *next, *hdm, **next2;
 
54
  char *s;
 
55
 
 
56
  if(!hd_probe_feature(hd_data, pr_manual)) return;
 
57
 
 
58
  hd_data->module = mod_manual;
 
59
 
 
60
  /* some clean-up */
 
61
  remove_hd_entries(hd_data);
 
62
 
 
63
  for(hd = hd_data->manual; hd; hd = next) {
 
64
    next = hd->next; 
 
65
    hd->next = NULL;
 
66
    hd_free_hd_list(hd);
 
67
  }
 
68
  hd_data->manual = NULL;
 
69
 
 
70
  next2 = &hd_data->manual;
 
71
 
 
72
  if((dir = opendir(hd_get_hddb_path("udi/org/freedesktop/Hal/devices")))) {
 
73
    i = 0;
 
74
    s = NULL;
 
75
    while((de = readdir(dir))) {
 
76
      if(*de->d_name == '.') continue;
 
77
      PROGRESS(1, ++i, "read");
 
78
      str_printf(&s, 0, "/org/freedesktop/Hal/devices/%s", de->d_name);
 
79
      if((hd = hd_read_config(hd_data, s))) {
 
80
        if(hd->status.available != status_unknown) hd->status.available = status_no;
 
81
        ADD2LOG("  got %s\n", hd->unique_id);
 
82
        *next2 = hd;
 
83
        next2 = &hd->next;
 
84
      }
 
85
    }
 
86
    s = free_mem(s);
 
87
    closedir(dir);
 
88
  }
 
89
 
 
90
  hd_data->flags.keep_kmods = 1;
 
91
  for(hdm = hd_data->manual; hdm; hdm = next) {
 
92
    next = hdm->next;
 
93
 
 
94
    for(hd = hd_data->hd; hd; hd = hd->next) {
 
95
      if(hd->unique_id && hdm->unique_id && !strcmp(hd->unique_id, hdm->unique_id)) break;
 
96
    }
 
97
 
 
98
    if(hd) {
 
99
      /* just update config status */
 
100
      hd->status = hdm->status;
 
101
      if(hd->status.available != status_unknown) hd->status.available = status_yes;
 
102
 
 
103
      hd->config_string = new_str(hdm->config_string);
 
104
 
 
105
      hd->persistent_prop = hdm->persistent_prop;
 
106
      hdm->persistent_prop = NULL;
 
107
    }
 
108
    else {
 
109
      /* add new entry */
 
110
      hd = add_hd_entry(hd_data, __LINE__, 0);
 
111
      *hd = *hdm;
 
112
      hd->next = NULL;
 
113
      hd->tag.freeit = 0;
 
114
 
 
115
      hdm->tag.remove = 1;
 
116
 
 
117
      if(hd->status.available != status_unknown) hd->status.available = status_no;
 
118
 
 
119
      // FIXME: do it really here?
 
120
      if(hd->parent_id) {
 
121
        for(hd1 = hd_data->hd; hd1; hd1 = hd1->next) {
 
122
          if(hd1->unique_id && !strcmp(hd1->unique_id, hd->parent_id)) {
 
123
            hd->attached_to = hd1->idx;
 
124
            break;
 
125
          }
 
126
        }
 
127
      }
 
128
    }
 
129
  }
 
130
  hd_data->flags.keep_kmods = 0;
 
131
 
 
132
  for(hd = hd_data->manual; hd; hd = next) {
 
133
    next = hd->next;
 
134
    hd->next = NULL;
 
135
    if(!hd->tag.remove) {
 
136
      hd_free_hd_list(hd);
 
137
    }
 
138
    else {
 
139
      free_mem(hd);
 
140
    }
 
141
  }
 
142
  hd_data->manual = NULL;
 
143
 
 
144
}
 
145
 
 
146
 
 
147
void hd_scan_manual2(hd_data_t *hd_data)
 
148
{
 
149
  hd_t *hd, *hd1;
 
150
 
 
151
  /* add persistent properties */
 
152
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
153
    if(hd->persistent_prop) continue;
 
154
    hd->persistent_prop = read_properties(hd_data, hd->udi, hd->unique_id);
 
155
    prop2hd(hd_data, hd, 1);
 
156
    if(hd->status.available != status_unknown) hd->status.available = status_yes;
 
157
  }
 
158
 
 
159
  /* check if it's necessary to reconfigure this hardware */
 
160
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
161
    hd->status.reconfig = status_no;
 
162
 
 
163
    if(hd->status.needed != status_yes) continue;
 
164
 
 
165
    if(hd->status.available == status_no) {
 
166
      hd->status.reconfig = status_yes;
 
167
      continue;
 
168
    }
 
169
 
 
170
    if(hd->status.available != status_unknown) continue;
 
171
 
 
172
    for(hd1 = hd_data->hd; hd1; hd1 = hd1->next) {
 
173
      if(hd1 == hd) continue;
 
174
 
 
175
      if(
 
176
        hd1->hw_class == hd->hw_class &&
 
177
        hd1->status.configured == status_new &&
 
178
        hd1->status.available == status_yes
 
179
      ) break;
 
180
    }
 
181
 
 
182
    if(hd1) hd->status.reconfig = status_yes;
 
183
  }
 
184
}
 
185
 
 
186
 
 
187
char *hd_status_value_name(hd_status_value_t status)
 
188
{
 
189
  return key2value(status_names, status);
 
190
}
 
191
 
 
192
 
 
193
/*
 
194
 * read an entry - obsolete
 
195
 */
 
196
hd_manual_t *hd_manual_read_entry(hd_data_t *hd_data, const char *id)
 
197
{
 
198
  return NULL;
 
199
}
 
200
 
 
201
 
 
202
/*
 
203
 * read an entry
 
204
 */
 
205
hal_prop_t *hd_manual_read_entry_old(const char *id)
 
206
{
 
207
  char path[PATH_MAX];
 
208
  int line;
 
209
  str_list_t *sl, *sl0;
 
210
  char *s, *s1, *s2;
 
211
  hal_prop_t *prop_list = NULL, *prop = NULL;
 
212
 
 
213
  if(!id) return NULL;
 
214
 
 
215
  snprintf(path, sizeof path, "%s/%s", hd_get_hddb_path("unique-keys"), id);
 
216
 
 
217
  if(!(sl0 = read_file(path, 0, 0))) return prop_list;
 
218
 
 
219
  for(line = 1, sl = sl0; sl; sl = sl->next, line++) {
 
220
    s = sl->str;
 
221
    while(isspace(*s)) s++;
 
222
    if(!*s || *s == '#' || *s == ';') continue; /* empty lines & comments */
 
223
 
 
224
    s2 = s;
 
225
    s1 = strsep(&s2, "=");
 
226
 
 
227
    if(!s2 && *s == '[') continue;
 
228
 
 
229
    if(!s2) break;
 
230
 
 
231
    if(s1) {
 
232
      if(prop) {
 
233
        prop->next = new_mem(sizeof *prop);
 
234
        prop = prop->next;
 
235
      }
 
236
      else {
 
237
        prop_list = prop = new_mem(sizeof *prop);
 
238
      }
 
239
 
 
240
      prop->type = p_string;
 
241
      for(s = s1; *s; s++) if(*s >= 'A' && *s <= 'Z') *s += 'a' - 'A';
 
242
      str_printf(&prop->key, 0, "hwinfo.%s", s1);
 
243
      prop->val.str = canon_str(s2, strlen(s2));
 
244
    }
 
245
  }
 
246
 
 
247
  free_str_list(sl0);
 
248
 
 
249
  return prop_list;
 
250
}
 
251
 
 
252
 
 
253
/*
 
254
 * write an entry
 
255
 */
 
256
 
 
257
int hd_manual_write_entry(hd_data_t *hd_data, hd_manual_t *entry)
 
258
{
 
259
  return 0;
 
260
}
 
261
 
 
262
 
 
263
char *prop2hd_str(hal_prop_t *prop, const char *id)
 
264
{
 
265
  return (prop = hal_get_str(prop, id)) ? new_str(prop->val.str) : NULL;
 
266
}
 
267
 
 
268
 
 
269
int32_t prop2hd_int32(hal_prop_t *prop, const char *id)
 
270
{
 
271
  return (prop = hal_get_int32(prop, id)) ? prop->val.int32 : 0;
 
272
}
 
273
 
 
274
 
 
275
str_list_t *prop2hd_list(hal_prop_t *prop, const char *id)
 
276
{
 
277
  str_list_t *sl0 = NULL, *sl;
 
278
 
 
279
  prop = hal_get_list(prop, id);
 
280
 
 
281
  if(prop) {
 
282
    for(sl = prop->val.list; sl; sl = sl->next) {
 
283
      add_str_list(&sl0, sl->str);
 
284
    }
 
285
  }
 
286
 
 
287
  return sl0;
 
288
}
 
289
 
 
290
 
 
291
void prop2hd(hd_data_t *hd_data, hd_t *hd, int status_only)
 
292
{
 
293
  hal_prop_t *prop, *list;
 
294
  hd_res_t *res;
 
295
  int i;
 
296
  unsigned u, u0, u1, u2, u3, u4;
 
297
  char *s;
 
298
  uint64_t u64_0, u64_1;
 
299
  str_list_t *sl;
 
300
 
 
301
  list = hd->persistent_prop;
 
302
 
 
303
  hd->config_string = prop2hd_str(list, "hwinfo.configstring");
 
304
 
 
305
  if((prop = hal_get_str(list, "hwinfo.configured"))) {
 
306
    hd->status.configured = value2key(status_names, prop->val.str);
 
307
  }
 
308
 
 
309
  if((prop = hal_get_str(list, "hwinfo.available"))) {
 
310
    hd->status.available_orig =
 
311
    hd->status.available = value2key(status_names, prop->val.str);
 
312
  }
 
313
 
 
314
  if((prop = hal_get_str(list, "hwinfo.needed"))) {
 
315
    hd->status.needed = value2key(status_names, prop->val.str);
 
316
  }
 
317
 
 
318
  if((prop = hal_get_str(list, "hwinfo.active"))) {
 
319
    hd->status.active = value2key(status_names, prop->val.str);
 
320
  }
 
321
 
 
322
  /*
 
323
   * if the status info is completely missing, fake some:
 
324
   * new hardware, autodetectable, not needed
 
325
   */
 
326
  if(
 
327
    !hd->status.configured &&
 
328
    !hd->status.available &&
 
329
    !hd->status.needed &&
 
330
    !hd->status.invalid
 
331
  ) {
 
332
    hd->status.configured = status_new;
 
333
    hd->status.available = status_yes;
 
334
    hd->status.needed = status_no;
 
335
  }
 
336
  if(!hd->status.active) hd->status.active = status_unknown;
 
337
 
 
338
  if(status_only || !list) return;
 
339
 
 
340
  hd->udi = prop2hd_str(list, "info.udi");
 
341
  hd->unique_id = prop2hd_str(list, "hwinfo.uniqueid");
 
342
  hd->parent_id = prop2hd_str(list, "hwinfo.parentid");
 
343
  hd->child_ids = prop2hd_list(list, "hwinfo.childids");
 
344
  hd->model = prop2hd_str(list, "hwinfo.model");
 
345
 
 
346
  if((prop = hal_get_str(list, "hwinfo.hwclass"))) {
 
347
    hd->hw_class = value2key(hw_items, prop->val.str);
 
348
  }
 
349
 
 
350
  hd->broken = prop2hd_int32(list, "hwinfo.broken");
 
351
 
 
352
  hd->bus.id = prop2hd_int32(list, "hwinfo.busid");
 
353
  hd->slot = prop2hd_int32(list, "hwinfo.slot");
 
354
  hd->func = prop2hd_int32(list, "hwinfo.func");
 
355
 
 
356
  hd->base_class.id = prop2hd_int32(list, "hwinfo.baseclass");
 
357
  hd->sub_class.id = prop2hd_int32(list, "hwinfo.subclass");
 
358
  hd->prog_if.id = prop2hd_int32(list, "hwinfo.progif");
 
359
 
 
360
  hd->revision.id = prop2hd_int32(list, "hwinfo.revisionid");
 
361
  hd->revision.name = prop2hd_str(list, "hwinfo.revisionname");
 
362
 
 
363
  hd->vendor.id = prop2hd_int32(list, "hwinfo.vendorid");
 
364
  hd->vendor.name = prop2hd_str(list, "hwinfo.vendorname");
 
365
 
 
366
  hd->device.id = prop2hd_int32(list, "hwinfo.deviceid");
 
367
  hd->device.name = prop2hd_str(list, "hwinfo.devicename");
 
368
 
 
369
  hd->sub_vendor.id = prop2hd_int32(list, "hwinfo.subvendorid");
 
370
  hd->sub_vendor.name = prop2hd_str(list, "hwinfo.subvendorname");
 
371
 
 
372
  hd->sub_device.id = prop2hd_int32(list, "hwinfo.subdeviceid");
 
373
  hd->sub_device.name = prop2hd_str(list, "hwinfo.subdevicename");
 
374
 
 
375
  hd->compat_device.id = prop2hd_int32(list, "hwinfo.compatdeviceid");
 
376
  hd->compat_device.name = prop2hd_str(list, "hwinfo.compatdevicename");
 
377
 
 
378
  hd->serial = prop2hd_str(list, "hwinfo.serial");
 
379
  hd->unix_dev_name = prop2hd_str(list, "hwinfo.unixdevice");
 
380
  hd->unix_dev_name2 = prop2hd_str(list, "hwinfo.unixdevicealt");
 
381
 
 
382
  hd->unix_dev_names = prop2hd_list(list, "hwinfo.unixdevicelist");
 
383
  hd->drivers = prop2hd_list(list, "hwinfo.drivers");
 
384
 
 
385
  hd->sysfs_id = prop2hd_str(list, "hwinfo.sysfsid");
 
386
  hd->sysfs_bus_id = prop2hd_str(list, "hwinfo.sysfsbusid");
 
387
  hd->sysfs_device_link = prop2hd_str(list, "hwinfo.sysfslink");
 
388
  hd->rom_id = prop2hd_str(list, "hwinfo.romid");
 
389
  hd->usb_guid = prop2hd_str(list, "hwinfo.usbguid");
 
390
  hd->hotplug = prop2hd_int32(list, "hwinfo.hotplug");
 
391
 
 
392
  if((s = hal_get_useful_str(list, "hwinfo.hwclasslist"))) {
 
393
    for(u = 0; u < sizeof hd->hw_class_list / sizeof *hd->hw_class_list; u++) {
 
394
      if(*s && s[1] && (i = hex(s, 2)) >= 0) {
 
395
        hd->hw_class_list[u] = i;
 
396
        s += 2;
 
397
      }
 
398
      else {
 
399
        break;
 
400
      }
 
401
    }
 
402
  }
 
403
 
 
404
  u = prop2hd_int32(list, "hwinfo.features");
 
405
  if(u & (1 << 0)) hd->is.agp = 1;
 
406
  if(u & (1 << 1)) hd->is.isapnp = 1;
 
407
  if(u & (1 << 2)) hd->is.softraiddisk = 1;
 
408
  if(u & (1 << 3)) hd->is.zip = 1;
 
409
  if(u & (1 << 4)) hd->is.cdr = 1;
 
410
  if(u & (1 << 5)) hd->is.cdrw = 1;
 
411
  if(u & (1 << 6)) hd->is.dvd = 1;
 
412
  if(u & (1 << 7)) hd->is.dvdr = 1;
 
413
  if(u & (1 << 8)) hd->is.dvdram = 1;
 
414
  if(u & (1 << 9)) hd->is.pppoe = 1;
 
415
  if(u & (1 << 10)) hd->is.wlan = 1;
 
416
 
 
417
 
 
418
  if((prop = hal_get_list(list, "hwinfo.res.memory"))) {
 
419
    for(sl = prop->val.list; sl; sl = sl->next) {
 
420
      if(sscanf(sl->str, "0x%"SCNx64",0x%"SCNx64",%u,%u,%u", &u64_0, &u64_1, &u0, &u1, &u2) == 5) {
 
421
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
422
        res->any.type = res_mem;
 
423
        res->mem.base = u64_0;
 
424
        res->mem.range = u64_1;
 
425
        res->mem.enabled = u0;
 
426
        res->mem.access = u1;
 
427
        res->mem.prefetch = u2;
 
428
      }
 
429
    }
 
430
  }
 
431
 
 
432
  if((prop = hal_get_list(list, "hwinfo.res.physmemory"))) {
 
433
    for(sl = prop->val.list; sl; sl = sl->next) {
 
434
      if(sscanf(sl->str, "0x%"SCNx64"", &u64_0) == 1) {
 
435
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
436
        res->any.type = res_phys_mem;
 
437
        res->phys_mem.range = u64_0;
 
438
      }
 
439
    }
 
440
  }
 
441
 
 
442
  if((prop = hal_get_list(list, "hwinfo.res.io"))) {
 
443
    for(sl = prop->val.list; sl; sl = sl->next) {
 
444
      if(sscanf(sl->str, "0x%"SCNx64",0x%"SCNx64",%u,%u", &u64_0, &u64_1, &u0, &u1) == 4) {
 
445
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
446
        res->any.type = res_io;
 
447
        res->io.base = u64_0;
 
448
        res->io.range = u64_1;
 
449
        res->io.enabled = u0;
 
450
        res->io.access = u1;
 
451
      }
 
452
    }
 
453
  }
 
454
 
 
455
  if((prop = hal_get_list(list, "hwinfo.res.interrupts"))) {
 
456
    for(sl = prop->val.list; sl; sl = sl->next) {
 
457
      if(sscanf(sl->str, "%u,%u,%u", &u0, &u1, &u2) == 3) {
 
458
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
459
        res->any.type = res_irq;
 
460
        res->irq.base = u0;
 
461
        res->irq.triggered = u1;
 
462
        res->irq.enabled = u2;
 
463
      }
 
464
    }
 
465
  }
 
466
 
 
467
  if((prop = hal_get_list(list, "hwinfo.res.dma"))) {
 
468
    for(sl = prop->val.list; sl; sl = sl->next) {
 
469
      if(sscanf(sl->str, "%u,%u", &u0, &u1) == 2) {
 
470
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
471
        res->any.type = res_dma;
 
472
        res->dma.base = u0;
 
473
        res->dma.enabled = u1;
 
474
      }
 
475
    }
 
476
  }
 
477
 
 
478
  if((prop = hal_get_list(list, "hwinfo.res.size"))) {
 
479
    for(sl = prop->val.list; sl; sl = sl->next) {
 
480
      if(sscanf(sl->str, "%u,%u,%u", &u0, &u1, &u2) == 3) {
 
481
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
482
        res->any.type = res_size;
 
483
        res->size.unit = u0;
 
484
        res->size.val1 = u1;
 
485
        res->size.val2 = u2;
 
486
      }
 
487
    }
 
488
  }
 
489
 
 
490
  if((prop = hal_get_list(list, "hwinfo.res.baud"))) {
 
491
    for(sl = prop->val.list; sl; sl = sl->next) {
 
492
      if(sscanf(sl->str, "%u,%u,%u,%u,%u", &u0, &u1, &u2, &u3, &u4) == 5) {
 
493
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
494
        res->any.type = res_baud;
 
495
        res->baud.speed = u0;
 
496
        res->baud.bits = u1;
 
497
        res->baud.stopbits = u2;
 
498
        res->baud.parity = (char) u3;
 
499
        res->baud.handshake = (char) u4;
 
500
      }
 
501
    }
 
502
  }
 
503
 
 
504
  if((prop = hal_get_list(list, "hwinfo.res.cache"))) {
 
505
    for(sl = prop->val.list; sl; sl = sl->next) {
 
506
      if(sscanf(sl->str, "%u", &u0) == 1) {
 
507
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
508
        res->any.type = res_cache;
 
509
        res->cache.size = u0;
 
510
      }
 
511
    }
 
512
  }
 
513
 
 
514
  if((prop = hal_get_list(list, "hwinfo.res.diskgeometry"))) {
 
515
    for(sl = prop->val.list; sl; sl = sl->next) {
 
516
      if(sscanf(sl->str, "%u,%u,%u,%u", &u0, &u1, &u2, &u3) == 4) {
 
517
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
518
        res->any.type = res_disk_geo;
 
519
        res->disk_geo.cyls = u0;
 
520
        res->disk_geo.heads = u1;
 
521
        res->disk_geo.sectors = u2;
 
522
        res->disk_geo.geotype = u3;
 
523
      }
 
524
    }
 
525
  }
 
526
 
 
527
  if((prop = hal_get_list(list, "hwinfo.res.monitor"))) {
 
528
    for(sl = prop->val.list; sl; sl = sl->next) {
 
529
      if(sscanf(sl->str, "%u,%u,%u,%u", &u0, &u1, &u2, &u3) == 4) {
 
530
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
531
        res->any.type = res_monitor;
 
532
        res->monitor.width = u0;
 
533
        res->monitor.height = u1;
 
534
        res->monitor.vfreq = u2;
 
535
        res->monitor.interlaced = u3;
 
536
      }
 
537
    }
 
538
  }
 
539
 
 
540
  if((prop = hal_get_list(list, "hwinfo.res.framebuffer"))) {
 
541
    for(sl = prop->val.list; sl; sl = sl->next) {
 
542
      if(sscanf(sl->str, "%u,%u,%u,%u,%u", &u0, &u1, &u2, &u3, &u4) == 5) {
 
543
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
544
        res->any.type = res_framebuffer;
 
545
        res->framebuffer.width = u0;
 
546
        res->framebuffer.height = u1;
 
547
        res->framebuffer.bytes_p_line = u2;
 
548
        res->framebuffer.colorbits = u3;
 
549
        res->framebuffer.mode = u4;
 
550
      }
 
551
    }
 
552
  }
 
553
 
 
554
  hddb_add_info(hd_data, hd);
 
555
 
 
556
}
 
557
 
 
558
 
 
559
hal_prop_t *hal_get_new(hal_prop_t **list, const char *key)
 
560
{
 
561
  hal_prop_t *prop;
 
562
 
 
563
  prop = hal_get_any(*list, key);
 
564
  if(!prop) {
 
565
    prop = new_mem(sizeof *prop);
 
566
    prop->next = *list;
 
567
    *list = prop;
 
568
    prop->key = new_str(key);
 
569
  }
 
570
  else {
 
571
    hal_invalidate_all(prop, key);
 
572
  }
 
573
 
 
574
  return prop;
 
575
}
 
576
 
 
577
 
 
578
void hd2prop_add_int32(hal_prop_t **list, const char *key, int32_t i)
 
579
{
 
580
  hal_prop_t *prop;
 
581
 
 
582
  if(i) {
 
583
    prop = hal_get_new(list, key);
 
584
    prop->type = p_int32;
 
585
    prop->val.int32 = i;
 
586
  }
 
587
  else {
 
588
    hal_invalidate_all(*list, key);
 
589
  }
 
590
}
 
591
 
 
592
 
 
593
void hd2prop_add_str(hal_prop_t **list, const char *key, const char *str)
 
594
{
 
595
  hal_prop_t *prop;
 
596
 
 
597
  if(str) {
 
598
    prop = hal_get_new(list, key);
 
599
    prop->type = p_string;
 
600
    prop->val.str = new_str(str);
 
601
  }
 
602
  else {
 
603
    hal_invalidate_all(*list, key);
 
604
  }
 
605
}
 
606
 
 
607
 
 
608
void hd2prop_add_list(hal_prop_t **list, const char *key, str_list_t *sl)
 
609
{
 
610
  hal_prop_t *prop;
 
611
 
 
612
  if(sl) {
 
613
    prop = hal_get_new(list, key);
 
614
    prop->type = p_list;
 
615
    for(; sl; sl = sl->next) {
 
616
      add_str_list(&prop->val.list, sl->str);
 
617
    }
 
618
  }
 
619
  else {
 
620
    hal_invalidate_all(*list, key);
 
621
  }
 
622
}
 
623
 
 
624
 
 
625
void hd2prop_append_list(hal_prop_t **list, const char *key, char *str)
 
626
{
 
627
  hal_prop_t *prop;
 
628
  str_list_t *sl = NULL;
 
629
 
 
630
  if(!str) return;
 
631
 
 
632
  prop = hal_get_list(*list, key);
 
633
 
 
634
  if(!prop) {
 
635
    add_str_list(&sl, str);
 
636
    hd2prop_add_list(list, key, sl);
 
637
    return;
 
638
  }
 
639
 
 
640
  add_str_list(&prop->val.list, str);
 
641
}
 
642
 
 
643
 
 
644
void hd2prop(hd_data_t *hd_data, hd_t *hd)
 
645
{
 
646
  hal_prop_t **list;
 
647
  char *s = NULL;
 
648
  unsigned u;
 
649
  hd_res_t *res;
 
650
 
 
651
  list = &hd->persistent_prop;
 
652
 
 
653
  hd2prop_add_str(list, "info.udi", hd->udi);
 
654
 
 
655
  hd2prop_add_str(list, "hwinfo.uniqueid", hd->unique_id);
 
656
  hd2prop_add_str(list, "hwinfo.parentid", hd->parent_id);
 
657
 
 
658
  hd2prop_add_list(list, "hwinfo.childids", hd->child_ids);
 
659
 
 
660
  hd2prop_add_str(list, "hwinfo.model", hd->model);
 
661
  hd2prop_add_str(list, "hwinfo.configstring", hd->config_string);
 
662
  hd2prop_add_str(list, "hwinfo.hwclass", key2value(hw_items, hd->hw_class));
 
663
  hd2prop_add_str(list, "hwinfo.configured", key2value(status_names, hd->status.configured));
 
664
  hd2prop_add_str(list, "hwinfo.available", key2value(status_names, hd->status.available));
 
665
  hd2prop_add_str(list, "hwinfo.needed", key2value(status_names, hd->status.needed));
 
666
  hd2prop_add_str(list, "hwinfo.active", key2value(status_names, hd->status.active));
 
667
 
 
668
  hd2prop_add_int32(list, "hwinfo.broken", hd->broken);
 
669
  hd2prop_add_int32(list, "hwinfo.bus", hd->bus.id);
 
670
  hd2prop_add_int32(list, "hwinfo.slot", hd->slot);
 
671
 
 
672
  hd2prop_add_int32(list, "hwinfo.func", hd->func);
 
673
  hd2prop_add_int32(list, "hwinfo.baseclass", hd->base_class.id);
 
674
  hd2prop_add_int32(list, "hwinfo.subclass", hd->sub_class.id);
 
675
  hd2prop_add_int32(list, "hwinfo.progif", hd->prog_if.id);
 
676
 
 
677
  hd2prop_add_int32(list, "hwinfo.revisionid", hd->revision.id);
 
678
  hd2prop_add_str(list, "hwinfo.revisionname", hd->revision.name);
 
679
 
 
680
  hd2prop_add_int32(list, "hwinfo.vendorid", hd->vendor.id);
 
681
  hd2prop_add_str(list, "hwinfo.vendorname", hd->vendor.name);
 
682
 
 
683
  hd2prop_add_int32(list, "hwinfo.deviceid", hd->device.id);
 
684
  hd2prop_add_str(list, "hwinfo.devicename", hd->device.name);
 
685
 
 
686
  hd2prop_add_int32(list, "hwinfo.subvendorid", hd->sub_vendor.id);
 
687
  hd2prop_add_str(list, "hwinfo.subvendorname", hd->sub_vendor.name);
 
688
 
 
689
  hd2prop_add_int32(list, "hwinfo.subdeviceid", hd->sub_device.id);
 
690
  hd2prop_add_str(list, "hwinfo.subdevicename", hd->sub_device.name);
 
691
 
 
692
  hd2prop_add_int32(list, "hwinfo.compatvendorid", hd->compat_vendor.id);
 
693
  hd2prop_add_int32(list, "hwinfo.compatdeviceid", hd->compat_device.id);
 
694
 
 
695
  hd2prop_add_str(list, "hwinfo.serial", hd->serial);
 
696
  hd2prop_add_str(list, "hwinfo.unixdevice", hd->unix_dev_name);
 
697
  hd2prop_add_str(list, "hwinfo.unixdevicealt", hd->unix_dev_name2);
 
698
 
 
699
  hd2prop_add_list(list, "hwinfo.unixdevicelist", hd->unix_dev_names);
 
700
  hd2prop_add_list(list, "hwinfo.drivers", hd->drivers);
 
701
 
 
702
  hd2prop_add_str(list, "hwinfo.sysfsid", hd->sysfs_id);
 
703
  hd2prop_add_str(list, "hwinfo.sysfsbusid", hd->sysfs_bus_id);
 
704
  hd2prop_add_str(list, "hwinfo.sysfslink", hd->sysfs_device_link);
 
705
  hd2prop_add_str(list, "hwinfo.romid", hd->rom_id);
 
706
  hd2prop_add_str(list, "hwinfo.usbguid", hd->usb_guid);
 
707
  hd2prop_add_int32(list, "hwinfo.hotplug", hd->hotplug);
 
708
 
 
709
  for(u = 0; u < sizeof hd->hw_class_list / sizeof *hd->hw_class_list; u++) {
 
710
    str_printf(&s, -1, "%02x", hd->hw_class_list[u]);
 
711
  }
 
712
  hd2prop_add_str(list, "hwinfo.hwclasslist", s);
 
713
  s = free_mem(s);
 
714
 
 
715
  u = 0;
 
716
  if(hd->is.agp)          u |= 1 << 0;
 
717
  if(hd->is.isapnp)       u |= 1 << 1;
 
718
  if(hd->is.softraiddisk) u |= 1 << 2;
 
719
  if(hd->is.zip)          u |= 1 << 3;
 
720
  if(hd->is.cdr)          u |= 1 << 4;
 
721
  if(hd->is.cdrw)         u |= 1 << 5;
 
722
  if(hd->is.dvd)          u |= 1 << 6;
 
723
  if(hd->is.dvdr)         u |= 1 << 7;
 
724
  if(hd->is.dvdram)       u |= 1 << 8;
 
725
  if(hd->is.pppoe)        u |= 1 << 9;
 
726
  if(hd->is.wlan)         u |= 1 << 10;
 
727
 
 
728
  hd2prop_add_int32(list, "hwinfo.features", u);
 
729
 
 
730
  hal_invalidate_all(*list, "hwinfo.res.memory");
 
731
  hal_invalidate_all(*list, "hwinfo.res.physmemory");
 
732
  hal_invalidate_all(*list, "hwinfo.res.io");
 
733
  hal_invalidate_all(*list, "hwinfo.res.interrupts");
 
734
  hal_invalidate_all(*list, "hwinfo.res.dma");
 
735
  hal_invalidate_all(*list, "hwinfo.res.size");
 
736
  hal_invalidate_all(*list, "hwinfo.res.baud");
 
737
  hal_invalidate_all(*list, "hwinfo.res.cache");
 
738
  hal_invalidate_all(*list, "hwinfo.res.diskgeometry");
 
739
  hal_invalidate_all(*list, "hwinfo.res.monitor");
 
740
  hal_invalidate_all(*list, "hwinfo.res.framebuffer");
 
741
  
 
742
  for(res = hd->res; res; res = res->next) {
 
743
    switch(res->any.type) {
 
744
      case res_mem:
 
745
        str_printf(&s, 0,
 
746
          "0x%"PRIx64",0x%"PRIx64",%u,%u,%u",
 
747
          res->mem.base, res->mem.range, res->mem.enabled, res->mem.access, res->mem.prefetch
 
748
        );
 
749
        hd2prop_append_list(list, "hwinfo.res.memory", s);
 
750
        break;
 
751
 
 
752
      case res_phys_mem:
 
753
        str_printf(&s, 0,
 
754
          "0x%"PRIx64,
 
755
          res->phys_mem.range
 
756
        );
 
757
        hd2prop_append_list(list, "hwinfo.res.physmemory", s);
 
758
        break;
 
759
 
 
760
      case res_io:
 
761
        str_printf(&s, 0,
 
762
          "0x%"PRIx64",0x%"PRIx64",%u,%u",
 
763
          res->io.base, res->io.range, res->io.enabled, res->io.access
 
764
        );
 
765
        hd2prop_append_list(list, "hwinfo.res.io", s);
 
766
        break;
 
767
 
 
768
      case res_irq:
 
769
        str_printf(&s, 0,
 
770
          "%u,%u,%u",
 
771
          res->irq.base, res->irq.triggered, res->irq.enabled
 
772
        );
 
773
        hd2prop_append_list(list, "hwinfo.res.interrupts", s);
 
774
        break;
 
775
 
 
776
      case res_dma:
 
777
        str_printf(&s, 0,
 
778
          "%u,%u",
 
779
          res->dma.base, res->dma.enabled
 
780
        );
 
781
        hd2prop_append_list(list, "hwinfo.res.dma", s);
 
782
        break;
 
783
 
 
784
      case res_size:
 
785
        str_printf(&s, 0,
 
786
          "%u,%"PRIu64",%"PRIu64,
 
787
          res->size.unit, res->size.val1, res->size.val2
 
788
        );
 
789
        hd2prop_append_list(list, "hwinfo.res.size", s);
 
790
        break;
 
791
 
 
792
      case res_baud:
 
793
        str_printf(&s, 0,
 
794
          "%u,%u,%u,0x%02x,0x%02x",
 
795
          res->baud.speed, res->baud.bits, res->baud.stopbits,
 
796
          (unsigned) res->baud.parity, (unsigned) res->baud.handshake
 
797
        );
 
798
        hd2prop_append_list(list, "hwinfo.res.baud", s);
 
799
        break;
 
800
 
 
801
      case res_cache:
 
802
        str_printf(&s, 0,
 
803
          "%u",
 
804
          res->cache.size
 
805
        );
 
806
        hd2prop_append_list(list, "hwinfo.res.cache", s);
 
807
        break;
 
808
 
 
809
      case res_disk_geo:
 
810
        str_printf(&s, 0,
 
811
          "%u,%u,%u,%u",
 
812
          res->disk_geo.cyls, res->disk_geo.heads, res->disk_geo.sectors, res->disk_geo.geotype
 
813
        );
 
814
        hd2prop_append_list(list, "hwinfo.res.diskgeometry", s);
 
815
        break;
 
816
 
 
817
      case res_monitor:
 
818
        str_printf(&s, 0,
 
819
          "%u,%u,%u,%u",
 
820
          res->monitor.width, res->monitor.height, res->monitor.vfreq, res->monitor.interlaced
 
821
        );
 
822
        hd2prop_append_list(list, "hwinfo.res.monitor", s);
 
823
        break;
 
824
 
 
825
      case res_framebuffer:
 
826
        str_printf(&s, 0,
 
827
          "%u,%u,%u,%u,%u",
 
828
          res->framebuffer.width, res->framebuffer.height, res->framebuffer.bytes_p_line,
 
829
          res->framebuffer.colorbits, res->framebuffer.mode
 
830
        );
 
831
        hd2prop_append_list(list, "hwinfo.res.framebuffer", s);
 
832
        break;
 
833
 
 
834
      default:
 
835
        break;
 
836
    }
 
837
  }
 
838
 
 
839
  s = free_mem(s);
 
840
 
 
841
}
 
842
 
 
843
 
 
844
hal_prop_t *read_properties(hd_data_t *hd_data, const char *udi, const char *id)
 
845
{
 
846
  hd_t *hd;
 
847
  hal_prop_t *prop = NULL;
 
848
 
 
849
  if(udi) {
 
850
    prop = hd_read_properties(udi);
 
851
    ADD2LOG("  prop read: %s (%s)\n", udi, prop ? "ok" : "failed");
 
852
  }
 
853
 
 
854
  if(prop) return prop;
 
855
 
 
856
  if(id && !udi) {
 
857
    /* try to find udi entry */
 
858
    for(hd = hd_data->hd; hd; hd = hd->next) {
 
859
      if(hd->udi && hd->unique_id && !strcmp(id, hd->unique_id)) {
 
860
        udi = hd->udi;
 
861
        break;
 
862
      }
 
863
    }
 
864
 
 
865
    if(udi) {
 
866
      prop = hd_read_properties(udi);
 
867
      ADD2LOG("  prop read: %s (%s)\n", udi, prop ? "ok" : "failed");
 
868
    }
 
869
  }
 
870
 
 
871
  if(!prop) {
 
872
    prop = hd_read_properties(id);
 
873
    ADD2LOG("  prop read: %s (%s)\n", id, prop ? "ok" : "failed");
 
874
  }
 
875
  if(!prop) {
 
876
    prop = hd_manual_read_entry_old(id);
 
877
    ADD2LOG("  old prop read: %s (%s)\n", id, prop ? "ok" : "failed");
 
878
  }
 
879
 
 
880
  return prop;
 
881
}
 
882
 
 
883
 
 
884
hd_t *hd_read_config(hd_data_t *hd_data, const char *id)
 
885
{
 
886
  hd_t *hd = NULL;
 
887
  hal_prop_t *prop = NULL;
 
888
  const char *udi = NULL;
 
889
 
 
890
  /* only of we didn't already (check internal db pointer) */
 
891
  /* prop2hd() makes db lookups */
 
892
  if(!hd_data->hddb2[1]) hddb_init(hd_data);
 
893
 
 
894
  if(id && *id == '/') {
 
895
    udi = id;
 
896
    id = NULL;
 
897
  }
 
898
 
 
899
  prop = read_properties(hd_data, udi, id);
 
900
 
 
901
  if(prop) {
 
902
    hd = new_mem(sizeof *hd);
 
903
    hd->idx = ++(hd_data->last_idx);
 
904
    hd->module = hd_data->module;
 
905
    hd->line = __LINE__;
 
906
    hd->tag.freeit = 1;         /* make it a 'stand alone' entry */
 
907
    hd->persistent_prop = prop;
 
908
    prop2hd(hd_data, hd, 0);
 
909
  }
 
910
 
 
911
  return hd;
 
912
}
 
913
 
 
914
 
 
915
int hd_write_config(hd_data_t *hd_data, hd_t *hd)
 
916
{
 
917
  char *udi;
 
918
 
 
919
  if(!hd_report_this(hd_data, hd)) return 0;
 
920
 
 
921
  hd2prop(hd_data, hd);
 
922
 
 
923
  udi = hd->unique_id;
 
924
  if(hd->udi) udi = hd->udi;
 
925
 
 
926
  if(!udi) return 5;
 
927
 
 
928
  return hd_write_properties(udi, hd->persistent_prop);
 
929
}
 
930
 
 
931
 
 
932
#endif  /* LIBHD_TINY */
 
933
 
 
934
/** @} */
 
935