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

« back to all changes in this revision

Viewing changes to src/hd/int.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 <sys/pci.h>
 
6
#include <sys/types.h>
 
7
#include <sys/stat.h>
 
8
 
 
9
#include "hd.h"
 
10
#include "hd_int.h"
 
11
#include "int.h"
 
12
 
 
13
/**
 
14
 * @defgroup LIBHDint Internal utilities
 
15
 * @ingroup libhdInternals
 
16
 * @brief Internal utility functions
 
17
 *
 
18
 * @{
 
19
 */
 
20
 
 
21
static void int_hotplug(hd_data_t *hd_data);
 
22
static void int_cdrom(hd_data_t *hd_data);
 
23
#if defined(__i386__) || defined (__x86_64__)
 
24
static int set_bios_id(hd_data_t *hd_data, hd_t *hd_ref, int bios_id);
 
25
static int bios_ctrl_order(hd_data_t *hd_data, unsigned *sctrl, int sctrl_len);
 
26
static void int_bios(hd_data_t *hd_data);
 
27
#endif
 
28
static void int_media_check(hd_data_t *hd_data);
 
29
static int contains_word(char *str, char *str2);
 
30
static int is_zip(hd_t *hd);
 
31
static void int_floppy(hd_data_t *hd_data);
 
32
static void int_fix_usb_scsi(hd_data_t *hd_data);
 
33
static void int_mouse(hd_data_t *hd_data);
 
34
static void new_id(hd_data_t *hd_data, hd_t *hd);
 
35
static void int_modem(hd_data_t *hd_data);
 
36
static void int_wlan(hd_data_t *hd_data);
 
37
static void int_udev(hd_data_t *hd_data);
 
38
static void int_devicenames(hd_data_t *hd_data);
 
39
#if defined(__i386__) || defined (__x86_64__)
 
40
static void int_softraid(hd_data_t *hd_data);
 
41
#endif
 
42
#if defined(__i386__) || defined (__x86_64__)
 
43
static void int_system(hd_data_t *hd_data);
 
44
static void int_legacy_geo(hd_data_t *hd_data);
 
45
#endif
 
46
static void int_find_parent(hd_data_t *hd_data);
 
47
static void int_add_driver_modules(hd_data_t *hd_data);
 
48
 
 
49
 
 
50
void hd_scan_int(hd_data_t *hd_data)
 
51
{
 
52
  hd_t *hd;
 
53
 
 
54
  if(!hd_probe_feature(hd_data, pr_int)) return;
 
55
 
 
56
  hd_data->module = mod_int;
 
57
 
 
58
  /* some clean-up */
 
59
  remove_hd_entries(hd_data);
 
60
 
 
61
  PROGRESS(2, 0, "cdrom");
 
62
  int_cdrom(hd_data);
 
63
 
 
64
  PROGRESS(3, 0, "media");
 
65
  int_media_check(hd_data);
 
66
 
 
67
  PROGRESS(4, 0, "floppy");
 
68
  int_floppy(hd_data);
 
69
 
 
70
#if defined(__i386__) || defined (__x86_64__)
 
71
  PROGRESS(5, 0, "bios");
 
72
  int_bios(hd_data);
 
73
#endif
 
74
 
 
75
  PROGRESS(6, 0, "mouse");
 
76
  int_mouse(hd_data);
 
77
 
 
78
#if defined(__i386__) || defined (__x86_64__)
 
79
  PROGRESS(15, 0, "system info");
 
80
  int_system(hd_data);
 
81
#endif
 
82
 
 
83
  PROGRESS(7, 0, "hdb");
 
84
  hd_data->flags.keep_kmods = 1;
 
85
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
86
    hddb_add_info(hd_data, hd);
 
87
  }
 
88
  hd_data->flags.keep_kmods = 0;
 
89
 
 
90
  PROGRESS(7, 1, "modules");
 
91
  int_add_driver_modules(hd_data);
 
92
 
 
93
  PROGRESS(8, 0, "usbscsi");
 
94
  int_fix_usb_scsi(hd_data);
 
95
 
 
96
  PROGRESS(9, 0, "hotplug");
 
97
  int_hotplug(hd_data);
 
98
 
 
99
  PROGRESS(10, 0, "modem");
 
100
  int_modem(hd_data);
 
101
 
 
102
  PROGRESS(11, 0, "wlan");
 
103
  int_wlan(hd_data);
 
104
 
 
105
  PROGRESS(12, 0, "udev");
 
106
  int_udev(hd_data);
 
107
 
 
108
  PROGRESS(13, 0, "device names");
 
109
  int_devicenames(hd_data);
 
110
 
 
111
#if defined(__i386__) || defined (__x86_64__)
 
112
  PROGRESS(14, 0, "soft raid");
 
113
  int_softraid(hd_data);
 
114
 
 
115
  PROGRESS(15, 0, "geo");
 
116
  int_legacy_geo(hd_data);
 
117
#endif
 
118
 
 
119
  PROGRESS(16, 0, "parent");
 
120
  int_find_parent(hd_data);
 
121
}
 
122
 
 
123
/*
 
124
 * Identify hotpluggable devices.
 
125
 */
 
126
void int_hotplug(hd_data_t *hd_data)
 
127
{
 
128
  hd_t *hd;
 
129
  hal_prop_t *prop;
 
130
 
 
131
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
132
    if(hd->bus.id == bus_usb || hd->usb_guid) {
 
133
      hd->hotplug = hp_usb;
 
134
    }
 
135
    if((prop = hal_get_bool(hd->hal_prop, "storage.hotpluggable")) && prop->val.b) {
 
136
      hd->is.hotpluggable = 1;
 
137
    }
 
138
  }
 
139
}
 
140
 
 
141
/*
 
142
 * Add more info to CDROM entries.
 
143
 */
 
144
void int_cdrom(hd_data_t *hd_data)
 
145
{
 
146
  hd_t *hd;
 
147
  hal_prop_t *prop;
 
148
 
 
149
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
150
    if(
 
151
      hd->base_class.id == bc_storage_device &&
 
152
      hd->sub_class.id == sc_sdev_cdrom
 
153
    ) {
 
154
      if(!hd->prog_if.id && hd->device.name && strstr(hd->device.name, "DVD")) hd->is.dvd = 1;
 
155
 
 
156
      if((prop = hal_get_bool(hd->hal_prop, "storage.cdrom.cdr")) && prop->val.b) {
 
157
        hd->is.cdr = 1;
 
158
      }
 
159
      if((prop = hal_get_bool(hd->hal_prop, "storage.cdrom.cdrw")) && prop->val.b) {
 
160
        hd->is.cdrw = 1;
 
161
      }
 
162
      if((prop = hal_get_bool(hd->hal_prop, "storage.cdrom.dvdr")) && prop->val.b) {
 
163
        hd->is.dvdr = 1;
 
164
      }
 
165
      if((prop = hal_get_bool(hd->hal_prop, "storage.cdrom.dvdrw")) && prop->val.b) {
 
166
        hd->is.dvdrw = 1;
 
167
      }
 
168
      if((prop = hal_get_bool(hd->hal_prop, "storage.cdrom.dvdram")) && prop->val.b) {
 
169
        hd->is.dvdram = 1;
 
170
      }
 
171
      if((prop = hal_get_bool(hd->hal_prop, "storage.cdrom.dvdplusr")) && prop->val.b) {
 
172
        hd->is.dvdpr = 1;
 
173
      }
 
174
      if((prop = hal_get_bool(hd->hal_prop, "storage.cdrom.dvdplusrw")) && prop->val.b) {
 
175
        hd->is.dvdprw = 1;
 
176
      }
 
177
      if((prop = hal_get_bool(hd->hal_prop, "storage.cdrom.dvdplusrdl")) && prop->val.b) {
 
178
        hd->is.dvdprdl = 1;
 
179
      }
 
180
 
 
181
      if(hd->is.dvd) hd->prog_if.id = 3;
 
182
    }
 
183
  }
 
184
}
 
185
 
 
186
#if defined(__i386__) || defined (__x86_64__)
 
187
 
 
188
int set_bios_id(hd_data_t *hd_data, hd_t *hd_ref, int bios_id)
 
189
{
 
190
  int found = 0;
 
191
  hd_t *hd;
 
192
 
 
193
  if(!hd_ref || !hd_ref->unix_dev_name) return 0;
 
194
 
 
195
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
196
    if(
 
197
      hd->base_class.id == bc_storage_device &&
 
198
      hd->sub_class.id == sc_sdev_disk &&
 
199
      hd->unix_dev_name &&
 
200
      !strcmp(hd->unix_dev_name, hd_ref->unix_dev_name)
 
201
    ) {
 
202
      str_printf(&hd->rom_id, 0, "0x%02x", bios_id);
 
203
      found = 1;
 
204
    }
 
205
  }
 
206
 
 
207
  return found;
 
208
}
 
209
 
 
210
 
 
211
int bios_ctrl_order(hd_data_t *hd_data, unsigned *sctrl, int sctrl_len)
 
212
{
 
213
  hd_t *hd;
 
214
  bios_info_t *bt;
 
215
  int i, j, k, sctrl2_len = 0;
 
216
  unsigned pci_slot, pci_func;
 
217
  unsigned *sctrl2 = NULL, *sctrl3 = NULL;
 
218
  int order_info = 0;
 
219
 
 
220
  for(bt = NULL, hd = hd_data->hd; hd; hd = hd->next) {
 
221
    if(
 
222
      hd->base_class.id == bc_internal &&
 
223
      hd->sub_class.id == sc_int_bios &&
 
224
      hd->detail &&
 
225
      hd->detail->type == hd_detail_bios &&
 
226
      (bt = hd->detail->bios.data)
 
227
    ) {
 
228
      break;
 
229
    }
 
230
  }
 
231
 
 
232
  if(!bt || !bt->bios32.ok || !bt->bios32.compaq) return 0;
 
233
 
 
234
  sctrl2 = new_mem((sizeof bt->bios32.cpq_ctrl / sizeof *bt->bios32.cpq_ctrl) * sizeof *sctrl2);
 
235
 
 
236
  for(i = 0; (unsigned) i < sizeof bt->bios32.cpq_ctrl / sizeof *bt->bios32.cpq_ctrl; i++) {
 
237
    if(
 
238
      bt->bios32.cpq_ctrl[i].id &&
 
239
      !(bt->bios32.cpq_ctrl[i].misc & 0x40)     /* bios support ??????? */
 
240
    ) {
 
241
      pci_slot = PCI_SLOT(bt->bios32.cpq_ctrl[i].devfn) + (bt->bios32.cpq_ctrl[i].bus << 8);
 
242
      pci_func = PCI_FUNC(bt->bios32.cpq_ctrl[i].devfn);
 
243
      for(hd = hd_data->hd; hd; hd = hd->next) {
 
244
        if(hd->bus.id == bus_pci && hd->slot == pci_slot && hd->func == pci_func) {
 
245
          sctrl2[sctrl2_len++] = hd->idx;
 
246
          break;
 
247
        }
 
248
      }
 
249
    }
 
250
  }
 
251
 
 
252
  if(sctrl2_len) order_info = 1;
 
253
 
 
254
  for(i = 0; i < sctrl2_len; i++) {
 
255
    ADD2LOG("  bios ord %d: %d\n", i, sctrl2[i]);
 
256
  }
 
257
 
 
258
  /* sort list */
 
259
 
 
260
  sctrl3 = new_mem(sctrl_len * sizeof *sctrl3);
 
261
 
 
262
  k = 0 ;
 
263
  for(i = 0; i < sctrl2_len; i++) {
 
264
    for(j = 0; j < sctrl_len; j++) {
 
265
      if(sctrl[j] == sctrl2[i]) {
 
266
        sctrl3[k++] = sctrl[j];
 
267
        sctrl[j] = 0;
 
268
        break;
 
269
      }
 
270
    }
 
271
  }
 
272
 
 
273
  for(i = 0; i < sctrl_len; i++) {
 
274
    if(sctrl[i] && k < sctrl_len) sctrl3[k++] = sctrl[i];
 
275
  }
 
276
 
 
277
  memcpy(sctrl, sctrl3, sctrl_len * sizeof *sctrl);
 
278
 
 
279
  free_mem(sctrl2);
 
280
  free_mem(sctrl3);
 
281
 
 
282
  return order_info;
 
283
}
 
284
 
 
285
 
 
286
void int_bios(hd_data_t *hd_data)
 
287
{
 
288
  hd_t *hd, *hd_boot;
 
289
  unsigned *sctrl, *sctrl2;
 
290
  int sctrl_len, i, j;
 
291
  int bios_id, list_sorted;
 
292
 
 
293
  /* don't do anything if there is useful edd info */
 
294
  if(hd_data->flags.edd_used) return;
 
295
 
 
296
  for(i = 0, hd = hd_data->hd; hd; hd = hd->next) {
 
297
    if(
 
298
      hd->base_class.id == bc_storage_device &&
 
299
      hd->sub_class.id == sc_sdev_disk
 
300
    ) {
 
301
      i++;
 
302
    }
 
303
  }
 
304
 
 
305
  if(!i) return;
 
306
 
 
307
  sctrl = new_mem(i * sizeof *sctrl);
 
308
 
 
309
  /* sctrl: list of storage controllers with disks */
 
310
 
 
311
  for(sctrl_len = 0, hd = hd_data->hd; hd; hd = hd->next) {
 
312
    if(
 
313
      hd->base_class.id == bc_storage_device &&
 
314
      hd->sub_class.id == sc_sdev_disk
 
315
    ) {
 
316
      for(i = 0; i < sctrl_len; i++) {
 
317
        if(sctrl[i] == hd->attached_to) break;
 
318
      }
 
319
      if(i == sctrl_len) sctrl[sctrl_len++] = hd->attached_to;
 
320
    }
 
321
  }
 
322
 
 
323
  /* sort list, if possible */
 
324
 
 
325
  list_sorted = bios_ctrl_order(hd_data, sctrl, sctrl_len);
 
326
 
 
327
  hd_boot = hd_get_device_by_idx(hd_data, hd_boot_disk(hd_data, &i));
 
328
 
 
329
  /* if we know the boot device, make this controller the first */
 
330
 
 
331
  if(hd_boot && hd_boot->attached_to && i == 1) {
 
332
    for(i = 0; i < sctrl_len; i++) {
 
333
      if(sctrl[i] == hd_boot->attached_to) break;
 
334
    }
 
335
    if(i < sctrl_len) {
 
336
      sctrl2 = new_mem(sctrl_len * sizeof *sctrl2);
 
337
      *sctrl2 = hd_boot->attached_to;
 
338
      for(i = 0, j = 1; i < sctrl_len; i++) {
 
339
        if(sctrl[i] != hd_boot->attached_to) sctrl2[j++] = sctrl[i];
 
340
      }
 
341
      free_mem(sctrl);
 
342
      sctrl = sctrl2;
 
343
    }
 
344
  }
 
345
  else {
 
346
    hd_boot = NULL;
 
347
  }
 
348
 
 
349
  if(hd_boot) ADD2LOG("  bios boot dev: %d\n", hd_boot->idx);
 
350
  for(i = 0; i < sctrl_len; i++) {
 
351
    ADD2LOG("  bios ctrl %d: %d\n", i, sctrl[i]);
 
352
  }
 
353
 
 
354
  /* remove existing entries */
 
355
 
 
356
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
357
    if(
 
358
      hd->base_class.id == bc_storage_device &&
 
359
      hd->sub_class.id == sc_sdev_disk
 
360
    ) {
 
361
      hd->rom_id = free_mem(hd->rom_id);
 
362
    }
 
363
  }
 
364
 
 
365
  if(!list_sorted && !hd_boot && sctrl_len > 1) {
 
366
    /* we have no info at all */
 
367
    sctrl_len = 0;
 
368
  }
 
369
  else if(!list_sorted && hd_boot && sctrl_len > 2) {
 
370
    /* we know which controller has the boot device */
 
371
    sctrl_len = 1;
 
372
  }
 
373
 
 
374
  bios_id = 0x80;
 
375
 
 
376
  /* rely on it */
 
377
 
 
378
  if(hd_boot) {
 
379
    bios_id += set_bios_id(hd_data, hd_boot, bios_id);
 
380
  }
 
381
 
 
382
  /* assign all the others */
 
383
 
 
384
  for(i = 0; i < sctrl_len; i++) {
 
385
    for(hd = hd_data->hd; hd; hd = hd->next) {
 
386
      if(
 
387
        hd->base_class.id == bc_storage_device &&
 
388
        hd->sub_class.id == sc_sdev_disk &&
 
389
        hd->attached_to == sctrl[i] &&
 
390
        !hd->rom_id
 
391
      ) {
 
392
        bios_id += set_bios_id(hd_data, hd, bios_id);
 
393
      }
 
394
    }
 
395
  }
 
396
 
 
397
  free_mem(sctrl);
 
398
}
 
399
 
 
400
 
 
401
#if 0
 
402
void int_bios(hd_data_t *hd_data)
 
403
{
 
404
  hd_t *hd, *hd_boot;
 
405
  int i, start, bios = 0x80;
 
406
  int ide_1st;
 
407
  char ide_name[] = "/dev/hda";
 
408
  char scsi_name[] = "/dev/sda";
 
409
  char *s;
 
410
 
 
411
  hd_boot = hd_get_device_by_idx(hd_data, hd_boot_disk(hd_data, &i));
 
412
 
 
413
  if(hd_boot) {
 
414
    free_mem(hd_boot->rom_id);
 
415
    hd_boot->rom_id = new_str("0x80");
 
416
  }
 
417
 
 
418
  if(!hd_boot || i != 1) return;
 
419
 
 
420
  if(strstr(hd_boot->unix_dev_name, "/dev/sd") == hd_boot->unix_dev_name) {
 
421
    ide_1st = 0;
 
422
    start = hd_boot->unix_dev_name[sizeof "/dev/sd" - 1] - 'a';
 
423
  }
 
424
  else if(strstr(hd_boot->unix_dev_name, "/dev/hd") == hd_boot->unix_dev_name) {
 
425
    ide_1st = 1;
 
426
    start = hd_boot->unix_dev_name[sizeof "/dev/hd" - 1] - 'a';
 
427
  }
 
428
  else {
 
429
    return;
 
430
  }
 
431
 
 
432
  if(start < 0) return;
 
433
 
 
434
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
435
    if(
 
436
      hd->base_class.id == bc_storage_device &&
 
437
      hd->sub_class.id == sc_sdev_disk
 
438
    ) {
 
439
      hd->rom_id = free_mem(hd->rom_id);
 
440
    }
 
441
  }
 
442
 
 
443
  s = ide_1st ? ide_name : scsi_name;
 
444
 
 
445
  for(i = start; i < 26; i++) {
 
446
    s[strlen(s) - 1] = 'a' + i;
 
447
    bios += set_bios_id(hd_data, s, bios);
 
448
  }
 
449
 
 
450
  for(i = 0; i < start; i++) {
 
451
    s[strlen(s) - 1] = 'a' + i;
 
452
    bios += set_bios_id(hd_data, s, bios);
 
453
  }
 
454
 
 
455
  s = ide_1st ? scsi_name : ide_name;
 
456
 
 
457
  for(i = 0; i < 26; i++) {
 
458
    s[strlen(s) - 1] = 'a' + i;
 
459
    bios += set_bios_id(hd_data, s, bios);
 
460
  }
 
461
}
 
462
#endif  /* 0 */
 
463
#endif  /* defined(__i386__) || defined (__x86_64__) */
 
464
 
 
465
/*
 
466
 * Try to read block 0 for block devices.
 
467
 */
 
468
void int_media_check(hd_data_t *hd_data)
 
469
{
 
470
  hd_t *hd;
 
471
  int i, j = 0;
 
472
 
 
473
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
474
    if(!hd_report_this(hd_data, hd)) continue;
 
475
    if(
 
476
      hd->base_class.id == bc_storage_device &&
 
477
      (
 
478
        /* hd->sub_class.id == sc_sdev_cdrom || */ /* cf. cdrom.c */
 
479
        hd->sub_class.id == sc_sdev_disk ||
 
480
        hd->sub_class.id == sc_sdev_floppy
 
481
      ) &&
 
482
      hd->unix_dev_name &&
 
483
      !hd->block0 &&
 
484
      !hd->is.notready &&
 
485
      hd->status.available != status_no
 
486
    ) {
 
487
      i = 5;
 
488
      PROGRESS(4, ++j, hd->unix_dev_name);
 
489
      hd->block0 = read_block0(hd_data, hd->unix_dev_name, &i);
 
490
      hd->is.notready = hd->block0 ? 0 : 1;
 
491
    }
 
492
  }
 
493
}
 
494
 
 
495
 
 
496
/*
 
497
 * Check if str has str2 in it.
 
498
 */
 
499
int contains_word(char *str, char *str2)
 
500
{
 
501
  int i, len, len2, found = 0;
 
502
  char *s;
 
503
 
 
504
  if(!str2 || !*str2 || !str || !*str) return 0;
 
505
 
 
506
  str = new_str(str);
 
507
 
 
508
  len = strlen(str);
 
509
  len2 = strlen(str2);
 
510
 
 
511
  for(i = 0; i < len; i++) {
 
512
    if(str[i] >= 'a' && str[i] <= 'z') str[i] -= 'a' - 'A';
 
513
  }
 
514
 
 
515
  for(s = str; (s = strstr(s, str2)); s++) {
 
516
    if(
 
517
      (s == str || s[-1] < 'A' || s[-1] > 'Z') &&
 
518
      (s[len2] < 'A' || s[len2] > 'Z')
 
519
    ) {
 
520
      found = 1;
 
521
      break;
 
522
    }
 
523
  }
 
524
 
 
525
  free_mem(str);
 
526
 
 
527
  return found;
 
528
}
 
529
 
 
530
 
 
531
/*
 
532
 * Check for zip drive.
 
533
 */
 
534
int is_zip(hd_t *hd)
 
535
{
 
536
  if(
 
537
    hd->base_class.id == bc_storage_device &&
 
538
    (
 
539
      hd->sub_class.id == sc_sdev_disk ||
 
540
      hd->sub_class.id == sc_sdev_floppy
 
541
    )
 
542
  ) {
 
543
    if(
 
544
      (
 
545
        contains_word(hd->vendor.name, "IOMEGA") ||
 
546
        contains_word(hd->sub_vendor.name, "IOMEGA") ||
 
547
        contains_word(hd->device.name, "IOMEGA") ||
 
548
        contains_word(hd->sub_device.name, "IOMEGA")
 
549
      ) && (
 
550
        contains_word(hd->device.name, "ZIP") ||
 
551
        contains_word(hd->sub_device.name, "ZIP")
 
552
      )
 
553
    ) {
 
554
      return 1;
 
555
    }
 
556
  }
 
557
 
 
558
  return 0;
 
559
}
 
560
 
 
561
 
 
562
/*
 
563
 * Turn some drives into floppies.
 
564
 */
 
565
void int_floppy(hd_data_t *hd_data)
 
566
{
 
567
  hd_t *hd;
 
568
  hd_res_t *res;
 
569
 
 
570
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
571
    if(is_zip(hd)) hd->is.zip = 1;
 
572
    if(
 
573
      hd->base_class.id == bc_storage_device &&
 
574
      hd->sub_class.id == sc_sdev_disk
 
575
    ) {
 
576
      if(hd->is.zip) {
 
577
        hd->sub_class.id = sc_sdev_floppy;
 
578
        new_id(hd_data, hd);
 
579
      }
 
580
      else {
 
581
        /* make everything a floppy that is 1440k */
 
582
        for(res = hd->res; res; res = res->next) {
 
583
          if(
 
584
            res->any.type == res_size &&
 
585
            res->size.unit == size_unit_sectors &&
 
586
            res->size.val1 == 2880 &&
 
587
            res->size.val2 == 512
 
588
          ) {
 
589
            hd->sub_class.id = sc_sdev_floppy;
 
590
            new_id(hd_data, hd);
 
591
            break;
 
592
          }
 
593
        }
 
594
      }
 
595
    }
 
596
  }
 
597
}
 
598
 
 
599
 
 
600
/*
 
601
 * Remove usb entries that are handled by usb-storage.
 
602
 */
 
603
void int_fix_usb_scsi(hd_data_t *hd_data)
 
604
{
 
605
  hd_t *hd_scsi, *hd_usb;
 
606
 
 
607
  for(hd_usb = hd_data->hd; hd_usb; hd_usb= hd_usb->next) {
 
608
    if(
 
609
      hd_usb->bus.id == bus_usb &&
 
610
      hd_usb->sysfs_id &&
 
611
      search_str_list(hd_usb->drivers, "usb-storage")
 
612
    ) {
 
613
      for(hd_scsi = hd_data->hd; hd_scsi; hd_scsi = hd_scsi->next) {
 
614
        if(
 
615
          hd_scsi->bus.id == bus_scsi &&
 
616
          hd_scsi->sysfs_device_link &&
 
617
          search_str_list(hd_scsi->drivers, "usb-storage")
 
618
        ) {
 
619
          if(!strncmp(hd_scsi->sysfs_device_link, hd_usb->sysfs_id, strlen(hd_usb->sysfs_id))) {
 
620
            hd_set_hw_class(hd_scsi, hw_usb);
 
621
 
 
622
            free_mem(hd_scsi->unique_id);
 
623
            hd_scsi->unique_id = hd_usb->unique_id;
 
624
            hd_usb->unique_id = NULL;
 
625
 
 
626
            add_res_entry(&hd_scsi->res, hd_usb->res);
 
627
            hd_usb->res = NULL;
 
628
 
 
629
            if(!hd_scsi->modalias) {
 
630
              hd_scsi->modalias = hd_usb->modalias;
 
631
              hd_usb->modalias = NULL;
 
632
            }
 
633
 
 
634
            if(!hd_scsi->vendor.id) hd_scsi->vendor.id = hd_usb->vendor.id;
 
635
            if(!hd_scsi->device.id) hd_scsi->device.id = hd_usb->device.id;
 
636
 
 
637
            if(!hd_scsi->serial) {
 
638
              hd_scsi->serial = hd_usb->serial;
 
639
              hd_usb->serial = NULL;
 
640
            }
 
641
 
 
642
            if(!hd_scsi->driver_info) {
 
643
              hd_scsi->driver_info = hd_usb->driver_info;
 
644
              hd_usb->driver_info = NULL;
 
645
            }
 
646
 
 
647
            new_id(hd_data, hd_scsi);
 
648
 
 
649
            hd_usb->tag.remove = 1;
 
650
          }
 
651
        }
 
652
      }
 
653
    }
 
654
  }
 
655
 
 
656
  remove_tagged_hd_entries(hd_data);
 
657
}
 
658
 
 
659
 
 
660
/*
 
661
 * Improve mouse info.
 
662
 */
 
663
void int_mouse(hd_data_t *hd_data)
 
664
{
 
665
  hd_t *hd;
 
666
  bios_info_t *bt = NULL;
 
667
 
 
668
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
669
    if(
 
670
      hd->detail &&
 
671
      hd->detail->type == hd_detail_bios &&
 
672
      (bt = hd->detail->bios.data) &&
 
673
      bt->mouse.type
 
674
    ) break;
 
675
  }
 
676
 
 
677
  if(!bt) return;
 
678
 
 
679
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
680
    if(
 
681
      hd->base_class.id == bc_mouse &&
 
682
      hd->sub_class.id == sc_mou_ps2 &&
 
683
      hd->bus.id == bt->mouse.bus &&
 
684
      hd->vendor.id == MAKE_ID(TAG_SPECIAL, 0x0200) &&
 
685
      hd->device.id == MAKE_ID(TAG_SPECIAL, 0x0002)
 
686
    ) {
 
687
      hd->vendor.name = free_mem(hd->vendor.name);
 
688
      hd->device.name = free_mem(hd->device.name);
 
689
      hd->vendor.id = hd->device.id = 0;
 
690
#if 0
 
691
      hd->vendor.id = bt->mouse.compat_vend;
 
692
      hd->device.id = bt->mouse.compat_dev;
 
693
#else
 
694
      hd->vendor.name = new_str(bt->mouse.vendor);
 
695
      hd->device.name = new_str(bt->mouse.type);
 
696
      hd->compat_vendor.id = bt->mouse.compat_vend;
 
697
      hd->compat_device.id = bt->mouse.compat_dev;
 
698
#endif
 
699
      new_id(hd_data, hd);
 
700
    }
 
701
  }
 
702
}
 
703
 
 
704
 
 
705
void new_id(hd_data_t *hd_data, hd_t *hd)
 
706
{
 
707
#if 0
 
708
  hd->unique_id = free_mem(hd->unique_id);
 
709
  hd->unique_id1 = free_mem(hd->unique_id1);
 
710
  hd->old_unique_id = free_mem(hd->old_unique_id);
 
711
  hd_add_id(hd_data, hd);
 
712
#endif
 
713
}
 
714
 
 
715
 
 
716
/*
 
717
 * Assign device names to (win-)modems.
 
718
 */
 
719
void int_modem(hd_data_t *hd_data)
 
720
{
 
721
  hd_t *hd;
 
722
  char *s;
 
723
  hd_dev_num_t dev_num = { type: 'c', range: 1 };
 
724
  unsigned cnt4 = 0;
 
725
 
 
726
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
727
    if(
 
728
      hd->base_class.id == bc_modem
 
729
    ) {
 
730
      s = NULL;
 
731
      switch(hd->sub_class.id) {
 
732
        case sc_mod_win1:
 
733
          s = new_str("/dev/ham");
 
734
          dev_num.major = 240;
 
735
          dev_num.minor = 1;
 
736
          break;
 
737
        case sc_mod_win2:
 
738
          s = new_str("/dev/536ep0");
 
739
          dev_num.major = 240;
 
740
          dev_num.minor = 1;
 
741
          break;
 
742
        case sc_mod_win3:
 
743
          s = new_str("/dev/ttyLT0");
 
744
          dev_num.major = 62;
 
745
          dev_num.minor = 64;
 
746
          break;
 
747
        case sc_mod_win4:
 
748
          if(cnt4 < 4) {
 
749
            str_printf(&s, 0, "/dev/ttySL%u", cnt4);
 
750
            dev_num.major = 212;
 
751
            dev_num.minor = cnt4++;
 
752
          }
 
753
          break;
 
754
      }
 
755
      if(s) {
 
756
        free_mem(hd->unix_dev_name);
 
757
        hd->unix_dev_name = s;
 
758
        s = NULL;
 
759
        hd->unix_dev_num = dev_num;
 
760
      }
 
761
    }
 
762
  }
 
763
}
 
764
 
 
765
 
 
766
/*
 
767
 * Look for WLAN cards by checking module info.
 
768
 */
 
769
void int_wlan(hd_data_t *hd_data)
 
770
{
 
771
  hd_t *hd;
 
772
  driver_info_t *di;
 
773
  str_list_t *sl;
 
774
  unsigned u, found;
 
775
  static char *wlan_mods[] = {
 
776
    "acx",
 
777
    "acx_pci",
 
778
    "airo",
 
779
    "airo_cs",
 
780
    "aironet4500_card",
 
781
    "aironet4500_cs",
 
782
    "airport",
 
783
    "adm8211",
 
784
    "arlan",
 
785
    "at76c503",
 
786
    "at76c503-i3861",
 
787
    "at76c503-i3863",
 
788
    "at76c503-rfmd",
 
789
    "at76c503-rfmd-acc",
 
790
    "at76c505-rfmd",
 
791
    "at76c505-rfmd2958",
 
792
    "ath_hal",
 
793
    "ath_pci",
 
794
    "atmel",
 
795
    "atmel_cs",
 
796
    "atmel_pci",
 
797
    "hermes",
 
798
    "hostap",
 
799
    "hostap_pci",
 
800
    "hostap_plx",
 
801
    "ipw2100",
 
802
    "ipw2200",
 
803
    "ipw3945",
 
804
    "netwave_cs",
 
805
    "orinoco_cs",
 
806
    "orinoco_pci",
 
807
    "orinoco_plx",
 
808
    "p80211",
 
809
    "prism2_cs",
 
810
    "prism2_pci",
 
811
    "prism2_plx",
 
812
    "prism2_usb",
 
813
    "prism54",
 
814
    "r8180",
 
815
    "ray_cs",
 
816
    "rt2400",
 
817
    "rt2500",
 
818
    "rt2570",
 
819
    "rt2400pci",
 
820
    "rt2500pci",
 
821
    "rt2500usb",
 
822
    "usbdfu",
 
823
    "wavelan",
 
824
    "wavelan_cs",
 
825
    "wl3501_cs",
 
826
    "zd1201"
 
827
  };
 
828
 
 
829
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
830
    for(found = 0, di = hd->driver_info; di && !found; di = di->next) {
 
831
      if(di->any.type == di_module) {
 
832
        for(sl = di->module.names; sl && !found; sl = sl->next) {
 
833
          for(u = 0; u < sizeof wlan_mods / sizeof *wlan_mods; u++) {
 
834
            if(!strcmp(sl->str, wlan_mods[u])) {
 
835
              found = 1;
 
836
              break;
 
837
            }
 
838
          }
 
839
        }
 
840
      }
 
841
    }
 
842
    if(found) {
 
843
      hd->is.wlan = 1;
 
844
      hd->base_class.id = bc_network;
 
845
      hd->sub_class.id = 0x82;                  /* wlan */
 
846
      hddb_add_info(hd_data, hd);
 
847
    }
 
848
  }
 
849
}
 
850
 
 
851
 
 
852
/*
 
853
 * Add udev info.
 
854
 */
 
855
void int_udev(hd_data_t *hd_data)
 
856
{
 
857
  hd_udevinfo_t *ui;
 
858
  hd_t *hd;
 
859
  str_list_t *sl;
 
860
 
 
861
  if(!hd_data->udevinfo) read_udevinfo(hd_data);
 
862
 
 
863
  if(!hd_data->udevinfo) return;
 
864
 
 
865
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
866
    if(!hd->unix_dev_names && hd->unix_dev_name) {
 
867
      add_str_list(&hd->unix_dev_names, hd->unix_dev_name);
 
868
    }
 
869
 
 
870
    if(!hd->sysfs_id) continue;
 
871
 
 
872
    for(ui = hd_data->udevinfo; ui; ui = ui->next) {
 
873
      if(ui->name && !strcmp(ui->sysfs, hd->sysfs_id)) {
 
874
        if(!search_str_list(hd->unix_dev_names, ui->name)) {
 
875
          add_str_list(&hd->unix_dev_names, ui->name);
 
876
        }
 
877
        for(sl = ui->links; sl; sl = sl->next) {
 
878
          if(!search_str_list(hd->unix_dev_names, sl->str)) {
 
879
            add_str_list(&hd->unix_dev_names, sl->str);
 
880
          }
 
881
        }
 
882
 
 
883
        if(!hd->unix_dev_name) {
 
884
          sl = hd->unix_dev_names;
 
885
 
 
886
          if(hd_data->flags.udev) {
 
887
            /* use first link as canonical device name */
 
888
            if(ui->links) sl = sl->next;
 
889
          }
 
890
 
 
891
          hd->unix_dev_name = new_str(sl->str);
 
892
        }
 
893
 
 
894
        break;
 
895
      }
 
896
    }
 
897
  }
 
898
 
 
899
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
900
    if(!hd->unix_dev_names) continue;
 
901
 
 
902
    for(ui = hd_data->udevinfo; ui; ui = ui->next) {
 
903
      if(search_str_list(hd->unix_dev_names, ui->name)) {
 
904
        for(sl = ui->links; sl; sl = sl->next) {
 
905
          if(!search_str_list(hd->unix_dev_names, sl->str)) {
 
906
            add_str_list(&hd->unix_dev_names, sl->str);
 
907
          }
 
908
        }
 
909
      }
 
910
    }
 
911
  }
 
912
}
 
913
 
 
914
 
 
915
/*
 
916
 * If hd->unix_dev_name is not in hd->unix_dev_names, add it.
 
917
 */
 
918
void int_devicenames(hd_data_t *hd_data)
 
919
{
 
920
  hd_t *hd;
 
921
 
 
922
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
923
    if(
 
924
      hd->unix_dev_name &&
 
925
      !search_str_list(hd->unix_dev_names, hd->unix_dev_name)
 
926
    ) {
 
927
      add_str_list(&hd->unix_dev_names, hd->unix_dev_name);
 
928
    }
 
929
  }
 
930
}
 
931
 
 
932
 
 
933
#if defined(__i386__) || defined (__x86_64__)
 
934
/*
 
935
 * Tag ide soft raid disks.
 
936
 */
 
937
void int_softraid(hd_data_t *hd_data)
 
938
{
 
939
  hd_t *hd;
 
940
  str_list_t *raid, *sl, *raid_sysfs = NULL, *sl1;
 
941
  size_t len;
 
942
  char *s;
 
943
 
 
944
  if(hd_data->flags.fast) return;
 
945
 
 
946
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
947
    if(
 
948
      hd->base_class.id == bc_storage_device &&
 
949
      hd->status.available != status_no
 
950
    ) break;
 
951
  }
 
952
 
 
953
  /* no disks -> no check necessary */
 
954
  if(!hd) return;
 
955
  
 
956
  raid = read_file("| /sbin/dmraid -rc 2>/dev/null", 0, 0);
 
957
 
 
958
  for(sl = raid; sl; sl = sl->next) {
 
959
    s = *sl->str ? strchr(sl->str + 1, '/') : NULL;
 
960
    if(s) {
 
961
      sl1 = add_str_list(&raid_sysfs, NULL);
 
962
      str_printf(&sl1->str, 0, "/block%s", s);
 
963
      len = strlen(sl1->str);
 
964
      if(len) sl1->str[len - 1] = 0;
 
965
    }
 
966
  }
 
967
 
 
968
  free_str_list(raid);
 
969
 
 
970
  ADD2LOG("----- soft raid devices -----\n");
 
971
  for(sl = raid_sysfs; sl; sl = sl->next) {
 
972
    ADD2LOG("  %s\n", sl->str);
 
973
  }
 
974
  ADD2LOG("----- soft raid devices end -----\n");
 
975
 
 
976
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
977
    if(search_str_list(raid_sysfs, hd->sysfs_id)) {
 
978
      hd->is.softraiddisk = 1;
 
979
    }
 
980
  }
 
981
 
 
982
  free_str_list(raid_sysfs);
 
983
 
 
984
}
 
985
 
 
986
 
 
987
/*
 
988
 *
 
989
 */
 
990
void int_system(hd_data_t *hd_data)
 
991
{
 
992
  hd_t *hd_sys;
 
993
  hd_smbios_t *sm;
 
994
  struct {
 
995
    unsigned notebook:1;
 
996
    enum { v_none = 0, v_ibm = 1, v_toshiba, v_sony } vendor;
 
997
  } is = { };
 
998
  char *s;
 
999
  struct stat sbuf;
 
1000
 
 
1001
  for(hd_sys = hd_data->hd; hd_sys; hd_sys = hd_sys->next) {
 
1002
    if(
 
1003
      hd_sys->base_class.id == bc_internal &&
 
1004
      hd_sys->sub_class.id == sc_int_sys
 
1005
    ) break;
 
1006
  }
 
1007
 
 
1008
  if(!hd_sys) return;
 
1009
 
 
1010
  if(
 
1011
    hd_sys->vendor.name &&
 
1012
    !strncasecmp(hd_sys->vendor.name, "sony", sizeof "sony" - 1)
 
1013
  ) {
 
1014
    is.vendor = v_sony;
 
1015
  }
 
1016
 
 
1017
  if(
 
1018
    hd_sys->device.name &&
 
1019
    !strncmp(hd_sys->device.name, "PCG-", sizeof "PCG-" - 1)
 
1020
  ) {
 
1021
    is.notebook = 1;
 
1022
  }
 
1023
 
 
1024
  for(sm = hd_data->smbios; sm; sm = sm->next) {
 
1025
    if(
 
1026
      sm->any.type == sm_sysinfo &&
 
1027
      sm->sysinfo.manuf &&
 
1028
      !strcasecmp(sm->sysinfo.manuf, "ibm")
 
1029
    ) {
 
1030
      is.vendor = v_ibm;
 
1031
    }
 
1032
 
 
1033
    if(
 
1034
      sm->any.type == sm_sysinfo &&
 
1035
      sm->sysinfo.manuf &&
 
1036
      !strcasecmp(sm->sysinfo.manuf, "toshiba")
 
1037
    ) {
 
1038
      is.vendor = v_toshiba;
 
1039
 
 
1040
      if(!hd_sys->device.name && !hd_sys->device.id && sm->sysinfo.product) {
 
1041
        hd_sys->device.name = new_str(sm->sysinfo.product);
 
1042
      }
 
1043
      if(!hd_sys->vendor.name && !hd_sys->vendor.id) {
 
1044
        hd_sys->vendor.name = new_str("Toshiba");
 
1045
      }
 
1046
    }
 
1047
 
 
1048
    if(
 
1049
      sm->any.type == sm_sysinfo &&
 
1050
      sm->sysinfo.manuf &&
 
1051
      !strncasecmp(sm->sysinfo.manuf, "sony", sizeof "sony" - 1)
 
1052
    ) {
 
1053
      is.vendor = v_sony;
 
1054
 
 
1055
      if(!hd_sys->device.name && !hd_sys->device.id && sm->sysinfo.product) {
 
1056
        hd_sys->device.name = new_str(sm->sysinfo.product);
 
1057
        if(
 
1058
          (s = strchr(hd_sys->device.name, '(')) &&
 
1059
          hd_sys->device.name[strlen(hd_sys->device.name) - 1] == ')'
 
1060
        ) {
 
1061
          *s = 0;
 
1062
        }
 
1063
      }
 
1064
      if(!hd_sys->vendor.name && !hd_sys->vendor.id) {
 
1065
        hd_sys->vendor.name = new_str("Sony");
 
1066
      }
 
1067
    }
 
1068
 
 
1069
    if(
 
1070
      sm->any.type == sm_chassis &&
 
1071
      (
 
1072
        (sm->chassis.ch_type.id >= 8 && sm->chassis.ch_type.id <= 11) ||
 
1073
        sm->chassis.ch_type.id == 14
 
1074
      )
 
1075
    ) {
 
1076
      is.notebook = 1;
 
1077
    }
 
1078
  }
 
1079
 
 
1080
  ADD2LOG(
 
1081
    "  system type:%s%s\n",
 
1082
    is.vendor == v_ibm ? " ibm" :
 
1083
      is.vendor == v_toshiba ? " toshiba" :
 
1084
      is.vendor == v_sony ? " sony" :
 
1085
      "",
 
1086
    is.notebook ? " notebook" : ""
 
1087
  );
 
1088
 
 
1089
  if(is.notebook && is.vendor) {
 
1090
    hd_sys->compat_vendor.id = MAKE_ID(TAG_SPECIAL, 0xf001);
 
1091
    hd_sys->compat_device.id = MAKE_ID(TAG_SPECIAL, is.vendor);
 
1092
  }
 
1093
 
 
1094
  hd_sys->is.with_acpi = stat("/proc/acpi", &sbuf) ? 0 : 1;
 
1095
  ADD2LOG("  acpi: %d\n", hd_sys->is.with_acpi);
 
1096
}
 
1097
 
 
1098
 
 
1099
void int_legacy_geo(hd_data_t *hd_data)
 
1100
{
 
1101
  hd_t *hd;
 
1102
  hd_res_t *res;
 
1103
  int id;
 
1104
  char *s;
 
1105
  edd_info_t *ei;
 
1106
 
 
1107
  if(!hd_data->edd) return;
 
1108
 
 
1109
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
1110
    if(
 
1111
      hd->base_class.id == bc_storage_device &&
 
1112
      hd->sub_class.id == sc_sdev_disk &&
 
1113
      hd->rom_id
 
1114
    ) {
 
1115
      id = strtol(hd->rom_id, &s, 0) - 0x80;
 
1116
      if(*s || id < 0 || id >= sizeof hd_data->edd / sizeof *hd_data->edd) continue;
 
1117
 
 
1118
      ei = hd_data->edd + id;
 
1119
 
 
1120
      if(ei->edd.cyls) {
 
1121
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
1122
        res->disk_geo.type = res_disk_geo;
 
1123
        res->disk_geo.cyls = ei->edd.cyls;
 
1124
        res->disk_geo.heads = ei->edd.heads;
 
1125
        res->disk_geo.sectors = ei->edd.sectors;
 
1126
        res->disk_geo.size = ei->sectors;
 
1127
        res->disk_geo.geotype = geo_bios_edd;
 
1128
      }
 
1129
 
 
1130
      if(ei->legacy.cyls) {
 
1131
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
 
1132
        res->disk_geo.type = res_disk_geo;
 
1133
        res->disk_geo.cyls = ei->legacy.cyls;
 
1134
        res->disk_geo.heads = ei->legacy.heads;
 
1135
        res->disk_geo.sectors = ei->legacy.sectors;
 
1136
        res->disk_geo.geotype = geo_bios_legacy;
 
1137
      }
 
1138
 
 
1139
    }
 
1140
  }
 
1141
}
 
1142
#endif
 
1143
 
 
1144
 
 
1145
void int_find_parent(hd_data_t *hd_data)
 
1146
{
 
1147
  hd_t *hd, *hd2;
 
1148
 
 
1149
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
1150
    if(hd->attached_to || !hd->parent_udi) continue;
 
1151
 
 
1152
    for(hd2 = hd_data->hd; hd2; hd2 = hd2->next) {
 
1153
      if(!hd2->udi) continue;
 
1154
      if(!strcmp(hd->parent_udi, hd2->udi)) {
 
1155
        hd->attached_to = hd2->idx;
 
1156
        break;
 
1157
      }
 
1158
    }
 
1159
  }
 
1160
}
 
1161
 
 
1162
 
 
1163
void int_add_driver_modules(hd_data_t *hd_data)
 
1164
{
 
1165
  hd_t *hd;
 
1166
  hd_sysfsdrv_t *sf;
 
1167
  str_list_t *sl;
 
1168
 
 
1169
  hd_sysfs_driver_list(hd_data);
 
1170
 
 
1171
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
1172
    hd->driver_modules = free_str_list(hd->driver_modules);
 
1173
 
 
1174
    for(sl = hd->drivers; sl; sl = sl->next) {
 
1175
      for(sf = hd_data->sysfsdrv; sf; sf = sf->next) {
 
1176
        if(sf->module && !strcmp(sf->driver, sl->str)) {
 
1177
          add_str_list(&hd->driver_modules, sf->module);
 
1178
        }
 
1179
      }
 
1180
    }
 
1181
  }
 
1182
}
 
1183
 
 
1184
 
 
1185
/** @} */
 
1186