00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <assert.h>
00035
00036 #include <stdio.h>
00037 #include <string.h>
00038
00039 #include <discover/discover.h>
00040 #include <discover/discover-conf.h>
00041 #include <discover/discover-xml.h>
00042 #include <discover/sysdep.h>
00043
00044 #include <discover/device.h>
00045 #include <discover/utils.h>
00046
00047
00049 typedef discover_sysdep_data_t *(raw_sysdep_function_t)(void);
00050
00051 static raw_sysdep_function_t *raw_map[] = {
00052 _discover_get_ata_raw,
00053 _discover_get_pci_raw,
00054 _discover_get_pcmcia_raw,
00055 _discover_get_scsi_raw,
00056 _discover_get_usb_raw
00057 };
00058
00059
00060
00061
00062
00063
00065 discover_sysdep_data_t *
00066 _discover_sysdep_data_new(void)
00067 {
00068 discover_sysdep_data_t *node =
00069 _discover_xmalloc(sizeof(discover_sysdep_data_t));
00070 node->busclass = NULL;
00071 node->vendor = NULL;
00072 node->model = NULL;
00073 node->data = NULL;
00074 node->next = NULL;
00075 return node;
00076 }
00077
00079 discover_sysdep_device_data_t *
00080 _discover_sysdep_device_data_new(void)
00081 {
00082 discover_sysdep_device_data_t *node =
00083 _discover_xmalloc(sizeof(discover_sysdep_device_data_t));
00084 node->path = NULL;
00085 node->value = NULL;
00086 node->next = NULL;
00087 return node;
00088 }
00089
00091 void
00092 _discover_free_sysdep_data(discover_sysdep_data_t *head)
00093 {
00094 discover_sysdep_data_t *node;
00095
00096 while (head) {
00097 node = head->next;
00098 if (head->vendor) {
00099 free(head->vendor);
00100 }
00101 if (head->model) {
00102 free(head->model);
00103 }
00104 if (head->busclass) {
00105 free(head->busclass);
00106 }
00107 if (head->data) {
00108 _discover_free_sysdep_device_data(head->data);
00109 }
00110 free(head);
00111 head = node;
00112 }
00113 }
00114
00116 void
00117 _discover_free_sysdep_device_data(discover_sysdep_device_data_t *head)
00118 {
00119 discover_sysdep_device_data_t *node;
00120 while (head) {
00121 node = head->next;
00122 if (head->path) {
00123 free(head->path);
00124 }
00125 if (head->value) {
00126 free(head->value);
00127 }
00128 free(head);
00129 head = node;
00130 }
00131 }
00132
00134 discover_data_t *
00135 _discover_convert_device_data(discover_sysdep_device_data_t *head)
00136 {
00137 discover_data_t *data_head, *data_current, *data_new;
00138 discover_sysdep_device_data_t *node;
00139 char *buffer, *path, *token;
00140
00142 data_head = discover_data_new();
00143 data_head->discover_class = _discover_xstrdup("device");
00144
00145
00146
00147
00148
00149
00150
00151 for (node = head; node; node = head->next) {
00153 data_current = NULL;
00154
00156 path = _discover_xstrdup(node->path);
00157 buffer = _discover_xstrdup(node->path);
00158
00160 for (token = strtok_r(path, "/", &buffer); token;
00161 token = strtok_r(NULL, "/", &buffer)) {
00163 data_new = discover_data_new();
00164 data_new->discover_class = _discover_xstrdup(token);
00165
00167 if (data_current == NULL) {
00169 if (data_head->child == NULL) {
00170 data_head->child = data_new;
00171 } else {
00172 data_current = data_head->child;
00173 while (data_current->next)
00174 data_current = data_current->next;
00175 data_current->next = data_new;
00176 }
00177 } else {
00179 data_current->child = data_new;
00180 data_new->parent = data_current;
00181 }
00182
00183 data_current = data_new;
00184 }
00185
00186
00187
00188
00189
00190 data_current->text = _discover_xstrdup(node->value);
00191
00193 free(path);
00194 free(buffer);
00195 }
00196
00197 return data_head;
00198 }
00199
00200
00201
00202
00203 static discover_device_t *devices[BUS_COUNT];
00204
00205 discover_device_t *
00206 discover_get_devices(discover_bus_t bus, discover_error_t *status)
00207 {
00208 discover_device_t *device, *last;
00209 discover_device_t *xml_devices;
00210 discover_bus_map_t *busmap;
00211 discover_sysdep_data_t *head, *node;
00212 discover_data_t *data_head, *data_node;
00213
00214 assert(status);
00215
00216 status->code = DISCOVER_SUCCESS;
00217 device = last = NULL;
00218
00219 busmap = discover_conf_get_bus_map(bus, status);
00220 if (status->code != 0) {
00221 return NULL;
00222 }
00223
00224 if (busmap->scan_never) {
00225 status->code = DISCOVER_EBUSDISABLED;
00226 return NULL;
00227 }
00228
00229 if (devices[bus]) {
00230 return devices[bus];
00231 }
00232
00233 xml_devices = discover_xml_get_devices(bus, status);
00234 if (!xml_devices) {
00235 return NULL;
00236 }
00237
00238
00239
00240
00241 if (busmap->get_raw) {
00242 head = node = busmap->get_raw();
00243 } else {
00244 head = node = raw_map[bus]();
00245 }
00246
00247 while (node) {
00248
00249
00250
00251
00252
00253 device =
00254 discover_xml_get_matching_devices(xml_devices, node->vendor,
00255 node->model, status);
00256
00257 if (!device) {
00258 device = discover_device_new();
00259 device->model_id = strdup(node->model);
00260 device->vendor_id = strdup(node->vendor);
00261 }
00262
00263
00264
00265
00266
00267 if (node->busclass != NULL) {
00268 if (device->busclass != NULL) {
00269 free(device->busclass);
00270 }
00271 device->busclass = strdup(node->busclass);
00272 }
00273
00274
00275 if (node->data != NULL) {
00276 data_head = _discover_convert_device_data(node->data);
00277 if (data_head != NULL) {
00278 for (data_node = data_head; data_node->next != NULL;
00279 data_node = data_node->next) ;
00280 data_node->next = device->data;
00281 device->data = data_head;
00282 }
00283 }
00284
00285 if (last) {
00286 last->next = device;
00287 last = device;
00288 } else {
00289 devices[bus] = last = device;
00290 }
00291
00292 node = node->next;
00293 }
00294
00295 _discover_free_sysdep_data(head);
00296
00297 return devices[bus];
00298 }
00299
00300 void
00301 discover_free_devices(void)
00302 {
00303 int i;
00304
00305 for (i = 0; i < BUS_COUNT; i++) {
00306 discover_device_free(devices[i], 0);
00307 devices[i] = NULL;
00308 }
00309 }
00310
00311
00312
00313
00314
00315
00316
00317