Changeset 032e0bb in mainline
- Timestamp:
- 2010-10-22T16:38:25Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 38b3baf
- Parents:
- 848e3d15
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/isa/isa.c
r848e3d15 r032e0bb 63 63 64 64 typedef struct isa_child_data { 65 hw_resource_list_t hw_resources; 65 hw_resource_list_t hw_resources; 66 66 } isa_child_data_t; 67 67 68 static hw_resource_list_t * isa_get_child_resources(device_t *dev) 69 { 70 isa_child_data_t *dev_data = (isa_child_data_t *)dev->driver_data; 71 if (NULL == dev_data) { 68 static hw_resource_list_t *isa_get_child_resources(device_t *dev) 69 { 70 isa_child_data_t *dev_data; 71 72 dev_data = (isa_child_data_t *)dev->driver_data; 73 if (dev_data == NULL) 72 74 return NULL; 73 } 75 74 76 return &dev_data->hw_resources; 75 77 } 76 78 77 static bool isa_enable_child_interrupt(device_t *dev) 79 static bool isa_enable_child_interrupt(device_t *dev) 78 80 { 79 81 // TODO 80 82 81 83 return false; 82 84 } … … 84 86 static resource_iface_t isa_child_res_iface = { 85 87 &isa_get_child_resources, 86 &isa_enable_child_interrupt 88 &isa_enable_child_interrupt 87 89 }; 88 90 … … 91 93 static int isa_add_device(device_t *dev); 92 94 93 /** The isa device driver's standard operations. 94 */ 95 /** The isa device driver's standard operations */ 95 96 static driver_ops_t isa_ops = { 96 97 .add_device = &isa_add_device 97 98 }; 98 99 99 /** The isa device driver structure. 100 */ 100 /** The isa device driver structure. */ 101 101 static driver_t isa_driver = { 102 102 .name = NAME, … … 105 105 106 106 107 static isa_child_data_t * create_isa_child_data() 108 { 109 isa_child_data_t *data = (isa_child_data_t *) malloc(sizeof(isa_child_data_t)); 110 if (NULL != data) { 111 memset(data, 0, sizeof(isa_child_data_t)); 112 } 113 return data; 114 } 115 116 static device_t * create_isa_child_dev() 107 static isa_child_data_t *create_isa_child_data() 108 { 109 isa_child_data_t *data; 110 111 data = (isa_child_data_t *) malloc(sizeof(isa_child_data_t)); 112 if (data != NULL) 113 memset(data, 0, sizeof(isa_child_data_t)); 114 115 return data; 116 } 117 118 static device_t *create_isa_child_dev() 117 119 { 118 120 device_t *dev = create_device(); 119 if ( NULL == dev) {121 if (dev == NULL) 120 122 return NULL; 121 } 123 122 124 isa_child_data_t *data = create_isa_child_data(); 123 if ( NULL == data) {125 if (data == NULL) { 124 126 delete_device(dev); 125 127 return NULL; 126 128 } 127 129 128 130 dev->driver_data = data; 129 131 return dev; 130 132 } 131 133 132 static char * 133 { 134 bool suc = false; 134 static char *read_dev_conf(const char *conf_path) 135 { 136 bool suc = false; 135 137 char *buf = NULL; 136 138 bool opened = false; 137 int fd; 139 int fd; 138 140 size_t len = 0; 139 141 140 142 fd = open(conf_path, O_RDONLY); 141 143 if (fd < 0) { 142 144 printf(NAME ": unable to open %s\n", conf_path); 143 145 goto cleanup; 144 } 145 opened = true; 146 146 } 147 148 opened = true; 149 147 150 len = lseek(fd, 0, SEEK_END); 148 151 lseek(fd, 0, SEEK_SET); 149 152 if (len == 0) { 150 printf(NAME ": read_dev_conf error: configuration file '%s' is empty.\n", conf_path); 151 goto cleanup; 152 } 153 153 printf(NAME ": read_dev_conf error: configuration file '%s' " 154 "is empty.\n", conf_path); 155 goto cleanup; 156 } 157 154 158 buf = malloc(len + 1); 155 159 if (buf == NULL) { 156 160 printf(NAME ": read_dev_conf error: memory allocation failed.\n"); 157 161 goto cleanup; 158 } 159 162 } 163 160 164 if (0 >= read(fd, buf, len)) { 161 printf(NAME ": read_dev_conf error: unable to read file '%s'.\n", conf_path); 165 printf(NAME ": read_dev_conf error: unable to read file '%s'.\n", 166 conf_path); 162 167 goto cleanup; 163 168 } 169 164 170 buf[len] = 0; 165 171 166 172 suc = true; 167 173 168 174 cleanup: 169 170 if (!suc && NULL != buf) { 171 free(buf); 175 if (!suc && buf != NULL) { 176 free(buf); 172 177 buf = NULL; 173 178 } 174 175 if (opened) {176 close(fd); 177 } 178 179 return buf; 180 } 181 182 static char * str_get_line(char *str, char **next) { 179 180 if (opened) 181 close(fd); 182 183 return buf; 184 } 185 186 static char *str_get_line(char *str, char **next) 187 { 183 188 char *line = str; 184 185 if ( NULL == str) {189 190 if (str == NULL) { 186 191 *next = NULL; 187 192 return NULL; 188 193 } 189 190 while ( 0 != *str && '\n' != *str) {194 195 while (*str != '\0' && *str != '\n') { 191 196 str++; 192 } 193 194 if ( 0 != *str) {197 } 198 199 if (*str != '\0') { 195 200 *next = str + 1; 196 201 } else { 197 202 *next = NULL; 198 } 199 200 *str = 0; 201 203 } 204 205 *str = '\0'; 202 206 return line; 203 207 } 204 208 205 206 209 static bool line_empty(const char *line) 207 210 { 208 while ( NULL != line && 0 != *line) {209 if (!isspace(*line)) {211 while (line != NULL && *line != 0) { 212 if (!isspace(*line)) 210 213 return false; 211 }212 line++;213 }214 return true;215 }216 217 static char * get_device_name(char *line) {218 // skip leading spaces219 while (0 != *line && isspace(*line)) {220 214 line++; 221 215 } 222 223 // get the name part of the rest of the line 224 strtok(line, ":"); 225 226 // alloc output buffer 216 217 return true; 218 } 219 220 static char *get_device_name(char *line) 221 { 222 /* Skip leading spaces. */ 223 while (*line != '\0' && isspace(*line)) { 224 line++; 225 } 226 227 /* Get the name part of the rest of the line. */ 228 strtok(line, ":"); 229 230 /* Allocate output buffer. */ 227 231 size_t size = str_size(line) + 1; 228 232 char *name = malloc(size); 229 230 if ( NULL != name) {231 / / copy the result to the output buffer233 234 if (name != NULL) { 235 /* Copy the result to the output buffer. */ 232 236 str_cpy(name, size, line); 233 237 } … … 236 240 } 237 241 238 static inline char * skip_spaces(char *line)239 { 240 / / skip leading spaces241 while ( 0 != *line && isspace(*line)) {242 static inline char *skip_spaces(char *line) 243 { 244 /* Skip leading spaces. */ 245 while (*line != '\0' && isspace(*line)) 242 246 line++; 243 } 244 return line; 245 } 246 247 248 return line; 249 } 247 250 248 251 static void isa_child_set_irq(device_t *dev, int irq) 249 252 { 250 253 isa_child_data_t *data = (isa_child_data_t *)dev->driver_data; 251 254 252 255 size_t count = data->hw_resources.count; 253 256 hw_resource_t *resources = data->hw_resources.resources; 254 257 255 258 if (count < ISA_MAX_HW_RES) { 256 259 resources[count].type = INTERRUPT; 257 260 resources[count].res.interrupt.irq = irq; 258 261 259 262 data->hw_resources.count++; 260 263 261 264 printf(NAME ": added irq 0x%x to device %s\n", irq, dev->name); 262 } 265 } 263 266 } 264 267 … … 266 269 { 267 270 isa_child_data_t *data = (isa_child_data_t *)dev->driver_data; 268 271 269 272 size_t count = data->hw_resources.count; 270 273 hw_resource_t *resources = data->hw_resources.resources; 271 274 272 275 if (count < ISA_MAX_HW_RES) { 273 276 resources[count].type = IO_RANGE; 274 277 resources[count].res.io_range.address = addr; 275 278 resources[count].res.io_range.size = len; 276 resources[count].res.io_range.endianness = LITTLE_ENDIAN; 277 279 resources[count].res.io_range.endianness = LITTLE_ENDIAN; 280 278 281 data->hw_resources.count++; 279 280 printf(NAME ": added io range (addr=0x%x, size=0x%x) to device %s\n", addr, len, dev->name); 281 } 282 283 printf(NAME ": added io range (addr=0x%x, size=0x%x) to " 284 "device %s\n", addr, len, dev->name); 285 } 282 286 } 283 287 … … 286 290 int irq = 0; 287 291 char *end = NULL; 288 292 289 293 val = skip_spaces(val); 290 294 irq = (int)strtol(val, &end, 0x10); 291 292 if (val != end) { 293 isa_child_set_irq(dev, irq); 294 } 295 296 if (val != end) 297 isa_child_set_irq(dev, irq); 295 298 } 296 299 … … 299 302 size_t addr, len; 300 303 char *end = NULL; 301 304 302 305 val = skip_spaces(val); 303 306 addr = strtol(val, &end, 0x10); 304 305 if (val == end) {307 308 if (val == end) 306 309 return; 307 } 308 310 309 311 val = skip_spaces(end); 310 312 len = strtol(val, &end, 0x10); 311 312 if (val == end) {313 314 if (val == end) 313 315 return; 314 } 315 316 316 317 isa_child_set_io_range(dev, addr, len); 317 318 } … … 320 321 { 321 322 char *end = val; 322 323 while (!isspace(*end)) {323 324 while (!isspace(*end)) 324 325 end++; 325 } 326 326 327 size_t size = end - val + 1; 327 328 *id = (char *)malloc(size); 328 str_cpy(*id, size, val); 329 str_cpy(*id, size, val); 329 330 } 330 331 331 332 static void get_dev_match_id(device_t *dev, char *val) 332 { 333 { 333 334 char *id = NULL; 334 335 int score = 0; 335 336 char *end = NULL; 336 337 337 338 val = skip_spaces(val); 338 339 339 340 score = (int)strtol(val, &end, 10); 340 341 if (val == end) { 341 printf(NAME " : error - could not read match score for device %s.\n", dev->name); 342 printf(NAME " : error - could not read match score for " 343 "device %s.\n", dev->name); 342 344 return; 343 345 } 344 346 345 347 match_id_t *match_id = create_match_id(); 346 if (NULL == match_id) { 347 printf(NAME " : failed to allocate match id for device %s.\n", dev->name); 348 if (match_id == NULL) { 349 printf(NAME " : failed to allocate match id for device %s.\n", 350 dev->name); 348 351 return; 349 352 } 350 353 351 354 val = skip_spaces(end); 352 355 get_match_id(&id, val); 353 if (NULL == id) { 354 printf(NAME " : error - could not read match id for device %s.\n", dev->name); 356 if (id == NULL) { 357 printf(NAME " : error - could not read match id for " 358 "device %s.\n", dev->name); 355 359 delete_match_id(match_id); 356 360 return; 357 361 } 358 362 359 363 match_id->id = id; 360 364 match_id->score = score; 361 362 printf(NAME ": adding match id '%s' with score %d to device %s\n", id, score, dev->name); 365 366 printf(NAME ": adding match id '%s' with score %d to device %s\n", id, 367 score, dev->name); 363 368 add_match_id(&dev->match_ids, match_id); 364 369 } 365 370 366 static bool read_dev_prop( 367 device_t *dev, char *line, const char *prop, void (* read_fn)(device_t *, char *)) 371 static bool read_dev_prop(device_t *dev, char *line, const char *prop, 372 void (*read_fn)(device_t *, char *)) 368 373 { 369 374 size_t proplen = str_size(prop); 370 if (0 == str_lcmp(line, prop, proplen)) { 375 376 if (str_lcmp(line, prop, proplen) == 0) { 371 377 line += proplen; 372 378 line = skip_spaces(line); 373 379 (*read_fn)(dev, line); 380 374 381 return true; 375 382 } 376 return false; 383 384 return false; 377 385 } 378 386 379 387 static void get_dev_prop(device_t *dev, char *line) 380 388 { 381 / / skip leading spaces389 /* Skip leading spaces. */ 382 390 line = skip_spaces(line); 383 391 384 392 if (!read_dev_prop(dev, line, "io_range", &get_dev_io_range) && 385 !read_dev_prop(dev, line, "irq", &get_dev_irq) && 386 !read_dev_prop(dev, line, "match", &get_dev_match_id) 387 ) { 388 printf(NAME " error undefined device property at line '%s'\n", line); 389 } 390 } 391 392 static void child_alloc_hw_res(device_t *dev) 393 !read_dev_prop(dev, line, "irq", &get_dev_irq) && 394 !read_dev_prop(dev, line, "match", &get_dev_match_id)) 395 { 396 printf(NAME " error undefined device property at line '%s'\n", 397 line); 398 } 399 } 400 401 static void child_alloc_hw_res(device_t *dev) 393 402 { 394 403 isa_child_data_t *data = (isa_child_data_t *)dev->driver_data; 395 404 data->hw_resources.resources = 396 (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES); 397 398 } 399 400 static char * read_isa_dev_info(char *dev_conf, device_t *parent) 405 (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES); 406 } 407 408 static char *read_isa_dev_info(char *dev_conf, device_t *parent) 401 409 { 402 410 char *line; 403 411 char *dev_name = NULL; 404 405 / / skip empty lines406 while (true) { 412 413 /* Skip empty lines. */ 414 while (true) { 407 415 line = str_get_line(dev_conf, &dev_conf); 408 409 if ( NULL == line) {410 / / no more lines416 417 if (line == NULL) { 418 /* no more lines */ 411 419 return NULL; 412 420 } 413 414 if (!line_empty(line)) { 421 422 if (!line_empty(line)) 423 break; 424 } 425 426 /* Get device name. */ 427 dev_name = get_device_name(line); 428 if (dev_name == NULL) 429 return NULL; 430 431 device_t *dev = create_isa_child_dev(); 432 if (dev == NULL) { 433 free(dev_name); 434 return NULL; 435 } 436 437 dev->name = dev_name; 438 439 /* Allocate buffer for the list of hardware resources of the device. */ 440 child_alloc_hw_res(dev); 441 442 /* Get properties of the device (match ids, irq and io range). */ 443 while (true) { 444 line = str_get_line(dev_conf, &dev_conf); 445 446 if (line_empty(line)) { 447 /* no more device properties */ 415 448 break; 416 449 } 417 } 418 419 // get device name 420 dev_name = get_device_name(line); 421 if (NULL == dev_name) { 422 return NULL; 423 } 424 425 device_t *dev = create_isa_child_dev(); 426 if (NULL == dev) { 427 free(dev_name); 428 return NULL; 429 } 430 dev->name = dev_name; 431 432 // allocate buffer for the list of hardware resources of the device 433 child_alloc_hw_res(dev); 434 435 // get properties of the device (match ids, irq and io range) 436 while (true) { 437 line = str_get_line(dev_conf, &dev_conf); 438 439 if (line_empty(line)) { 440 // no more device properties 441 break; 442 } 443 444 // get the device's property from the configuration line and store it in the device structure 450 451 /* 452 * Get the device's property from the configuration line 453 * and store it in the device structure. 454 */ 445 455 get_dev_prop(dev, line); 446 456 447 457 //printf(NAME ": next line ='%s'\n", dev_conf); 448 //printf(NAME ": current line ='%s'\n", line); 449 } 450 451 / / set device operations to the device458 //printf(NAME ": current line ='%s'\n", line); 459 } 460 461 /* Set device operations to the device. */ 452 462 dev->ops = &isa_child_dev_ops; 453 454 printf(NAME ": child_device_register(dev, parent); device is %s.\n", dev->name); 455 child_device_register(dev, parent); 456 457 return dev_conf; 463 464 printf(NAME ": child_device_register(dev, parent); device is %s.\n", 465 dev->name); 466 child_device_register(dev, parent); 467 468 return dev_conf; 458 469 } 459 470 460 471 static void parse_dev_conf(char *conf, device_t *parent) 461 472 { 462 while ( NULL != conf && 0 != *conf) {473 while (conf != NULL && *conf != '\0') { 463 474 conf = read_isa_dev_info(conf, parent); 464 } 475 } 465 476 } 466 477 467 478 static void add_legacy_children(device_t *parent) 468 479 { 469 char *dev_conf = read_dev_conf(CHILD_DEV_CONF_PATH); 470 if (NULL != dev_conf) { 471 parse_dev_conf(dev_conf, parent); 480 char *dev_conf; 481 482 dev_conf = read_dev_conf(CHILD_DEV_CONF_PATH); 483 if (dev_conf != NULL) { 484 parse_dev_conf(dev_conf, parent); 472 485 free(dev_conf); 473 486 } 474 487 } 475 488 476 static int isa_add_device(device_t *dev) 489 static int isa_add_device(device_t *dev) 477 490 { 478 491 printf(NAME ": isa_add_device, device handle = %d\n", dev->handle); 479 480 / / add child devices492 493 /* Add child devices. */ 481 494 add_legacy_children(dev); 482 printf(NAME ": finished the enumeration of legacy devices\n", dev->handle); 483 495 printf(NAME ": finished the enumeration of legacy devices\n", 496 dev->handle); 497 484 498 return EOK; 485 499 } … … 492 506 int main(int argc, char *argv[]) 493 507 { 494 printf(NAME ": HelenOS ISA bus driver\n"); 508 printf(NAME ": HelenOS ISA bus driver\n"); 495 509 isa_init(); 496 510 return driver_main(&isa_driver);
Note:
See TracChangeset
for help on using the changeset viewer.