Changes in uspace/drv/bus/isa/isa.c [3e6a98c5:3869c596] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/isa/isa.c
r3e6a98c5 r3869c596 42 42 #include <stdio.h> 43 43 #include <errno.h> 44 #include < stdbool.h>44 #include <bool.h> 45 45 #include <fibril_synch.h> 46 46 #include <stdlib.h> … … 73 73 #define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev" 74 74 75 /** Obtain soft-state from device node */ 76 #define ISA_BUS(dev) ((isa_bus_t *) ((dev)->driver_data)) 77 78 /** Obtain soft-state from function node */ 79 #define ISA_FUN(fun) ((isa_fun_t *) ((fun)->driver_data)) 80 75 81 #define ISA_MAX_HW_RES 5 76 82 … … 85 91 fibril_mutex_t mutex; 86 92 ddf_fun_t *fnode; 93 hw_resource_t resources[ISA_MAX_HW_RES]; 87 94 hw_resource_list_t hw_resources; 88 95 link_t bus_link; 89 96 } isa_fun_t; 90 97 91 /** Obtain soft-state from device node */ 92 static isa_bus_t *isa_bus(ddf_dev_t *dev) 93 { 94 return ddf_dev_data_get(dev); 95 } 96 97 /** Obtain soft-state from function node */ 98 static isa_fun_t *isa_fun(ddf_fun_t *fun) 99 { 100 return ddf_fun_data_get(fun); 101 } 102 103 static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode) 104 { 105 isa_fun_t *fun = isa_fun(fnode); 106 assert(fun != NULL); 98 static hw_resource_list_t *isa_fun_get_resources(ddf_fun_t *fnode) 99 { 100 isa_fun_t *fun = ISA_FUN(fnode); 101 assert(fun); 107 102 108 103 return &fun->hw_resources; 109 104 } 110 105 111 static bool isa_ enable_fun_interrupt(ddf_fun_t *fnode)106 static bool isa_fun_enable_interrupt(ddf_fun_t *fnode) 112 107 { 113 108 /* This is an old ugly way, copied from pci driver */ 114 109 assert(fnode); 115 isa_fun_t * fun = isa_fun(fnode);110 isa_fun_t *isa_fun = ISA_FUN(fnode); 116 111 117 112 sysarg_t apic; … … 129 124 return false; 130 125 131 const hw_resource_list_t *res = &fun->hw_resources; 126 assert(isa_fun); 127 const hw_resource_list_t *res = &isa_fun->hw_resources; 132 128 assert(res); 133 129 for (size_t i = 0; i < res->count; ++i) { … … 151 147 } 152 148 153 static int isa_ dma_channel_fun_setup(ddf_fun_t *fnode,149 static int isa_fun_setup_dma(ddf_fun_t *fnode, 154 150 unsigned int channel, uint32_t pa, uint16_t size, uint8_t mode) 155 151 { 156 152 assert(fnode); 157 isa_fun_t *fun = isa_fun(fnode); 158 const hw_resource_list_t *res = &fun->hw_resources; 153 isa_fun_t *isa_fun = fnode->driver_data; 154 assert(isa_fun); 155 const hw_resource_list_t *res = &isa_fun->hw_resources; 159 156 assert(res); 160 157 161 const unsigned int ch = channel;162 158 for (size_t i = 0; i < res->count; ++i) { 159 /* Check for assigned channel */ 163 160 if (((res->resources[i].type == DMA_CHANNEL_16) && 164 (res->resources[i].res.dma_channel.dma16 == ch )) ||161 (res->resources[i].res.dma_channel.dma16 == channel)) || 165 162 ((res->resources[i].type == DMA_CHANNEL_8) && 166 (res->resources[i].res.dma_channel.dma8 == ch ))) {167 return dma_ setup_channel(channel, pa, size, mode);163 (res->resources[i].res.dma_channel.dma8 == channel))) { 164 return dma_channel_setup(channel, pa, size, mode); 168 165 } 169 166 } … … 172 169 } 173 170 171 static int isa_fun_remain_dma(ddf_fun_t *fnode, 172 unsigned channel, size_t *size) 173 { 174 assert(size); 175 assert(fnode); 176 isa_fun_t *isa_fun = fnode->driver_data; 177 assert(isa_fun); 178 const hw_resource_list_t *res = &isa_fun->hw_resources; 179 assert(res); 180 181 for (size_t i = 0; i < res->count; ++i) { 182 /* Check for assigned channel */ 183 if (((res->resources[i].type == DMA_CHANNEL_16) && 184 (res->resources[i].res.dma_channel.dma16 == channel)) || 185 ((res->resources[i].type == DMA_CHANNEL_8) && 186 (res->resources[i].res.dma_channel.dma8 == channel))) { 187 return dma_channel_remain(channel, size); 188 } 189 } 190 191 return EINVAL; 192 } 193 174 194 static hw_res_ops_t isa_fun_hw_res_ops = { 175 .get_resource_list = isa_get_fun_resources, 176 .enable_interrupt = isa_enable_fun_interrupt, 177 .dma_channel_setup = isa_dma_channel_fun_setup, 195 .get_resource_list = isa_fun_get_resources, 196 .enable_interrupt = isa_fun_enable_interrupt, 197 .dma_channel_setup = isa_fun_setup_dma, 198 .dma_channel_remain = isa_fun_remain_dma, 178 199 }; 179 200 180 static ddf_dev_ops_t isa_fun_ops; 201 static ddf_dev_ops_t isa_fun_ops= { 202 .interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops, 203 }; 181 204 182 205 static int isa_dev_add(ddf_dev_t *dev); … … 212 235 213 236 fibril_mutex_initialize(&fun->mutex); 237 fun->hw_resources.resources = fun->resources; 238 214 239 fun->fnode = fnode; 215 240 return fun; … … 270 295 { 271 296 char *line = str; 297 *next = NULL; 272 298 273 299 if (str == NULL) { 274 *next = NULL;275 300 return NULL; 276 301 } … … 282 307 if (*str != '\0') { 283 308 *next = str + 1; 284 } else {285 *next = NULL;286 309 } 287 310 … … 310 333 /* Get the name part of the rest of the line. */ 311 334 strtok(line, ":"); 312 313 /* Allocate output buffer. */ 314 size_t size = str_size(line) + 1; 315 char *name = malloc(size); 316 317 if (name != NULL) { 318 /* Copy the result to the output buffer. */ 319 str_cpy(name, size, line); 320 } 321 322 return name; 323 } 324 325 static inline char *skip_spaces(char *line) 335 return line; 336 } 337 338 static inline const char *skip_spaces(const char *line) 326 339 { 327 340 /* Skip leading spaces. */ … … 332 345 } 333 346 334 static void isa_fun_ set_irq(isa_fun_t *fun, int irq)347 static void isa_fun_add_irq(isa_fun_t *fun, int irq) 335 348 { 336 349 size_t count = fun->hw_resources.count; … … 344 357 345 358 ddf_msg(LVL_NOTE, "Added irq 0x%x to function %s", irq, 346 ddf_fun_get_name(fun->fnode));347 } 348 } 349 350 static void isa_fun_ set_dma(isa_fun_t *fun, int dma)359 fun->fnode->name); 360 } 361 } 362 363 static void isa_fun_add_dma(isa_fun_t *fun, int dma) 351 364 { 352 365 size_t count = fun->hw_resources.count; … … 360 373 fun->hw_resources.count++; 361 374 ddf_msg(LVL_NOTE, "Added dma 0x%x to function %s", dma, 362 ddf_fun_get_name(fun->fnode));375 fun->fnode->name); 363 376 364 377 return; … … 371 384 fun->hw_resources.count++; 372 385 ddf_msg(LVL_NOTE, "Added dma 0x%x to function %s", dma, 373 ddf_fun_get_name(fun->fnode));386 fun->fnode->name); 374 387 375 388 return; … … 377 390 378 391 ddf_msg(LVL_WARN, "Skipped dma 0x%x for function %s", dma, 379 ddf_fun_get_name(fun->fnode));380 } 381 } 382 383 static void isa_fun_ set_io_range(isa_fun_t *fun, size_t addr, size_t len)392 fun->fnode->name); 393 } 394 } 395 396 static void isa_fun_add_io_range(isa_fun_t *fun, size_t addr, size_t len) 384 397 { 385 398 size_t count = fun->hw_resources.count; … … 396 409 ddf_msg(LVL_NOTE, "Added io range (addr=0x%x, size=0x%x) to " 397 410 "function %s", (unsigned int) addr, (unsigned int) len, 398 ddf_fun_get_name(fun->fnode));399 } 400 } 401 402 static void fun_parse_irq(isa_fun_t *fun, c har *val)411 fun->fnode->name); 412 } 413 } 414 415 static void fun_parse_irq(isa_fun_t *fun, const char *val) 403 416 { 404 417 int irq = 0; … … 409 422 410 423 if (val != end) 411 isa_fun_set_irq(fun, irq); 412 } 413 414 static void fun_parse_dma(isa_fun_t *fun, char *val) 415 { 416 unsigned int dma = 0; 424 isa_fun_add_irq(fun, irq); 425 } 426 427 static void fun_parse_dma(isa_fun_t *fun, const char *val) 428 { 417 429 char *end = NULL; 418 430 419 431 val = skip_spaces(val); 420 dma = (unsigned int)strtol(val, &end, 10);432 const int dma = strtol(val, &end, 10); 421 433 422 434 if (val != end) 423 isa_fun_ set_dma(fun, dma);424 } 425 426 static void fun_parse_io_range(isa_fun_t *fun, c har *val)435 isa_fun_add_dma(fun, dma); 436 } 437 438 static void fun_parse_io_range(isa_fun_t *fun, const char *val) 427 439 { 428 440 size_t addr, len; … … 441 453 return; 442 454 443 isa_fun_ set_io_range(fun, addr, len);444 } 445 446 static void get_match_id(char **id, c har *val)447 { 448 c har *end = val;455 isa_fun_add_io_range(fun, addr, len); 456 } 457 458 static void get_match_id(char **id, const char *val) 459 { 460 const char *end = val; 449 461 450 462 while (!isspace(*end)) … … 456 468 } 457 469 458 static void fun_parse_match_id(isa_fun_t *fun, c har *val)470 static void fun_parse_match_id(isa_fun_t *fun, const char *val) 459 471 { 460 472 char *id = NULL; 461 int score = 0;462 473 char *end = NULL; 463 int rc;464 474 465 475 val = skip_spaces(val); 466 476 467 score = (int)strtol(val, &end, 10);477 int score = (int)strtol(val, &end, 10); 468 478 if (val == end) { 469 479 ddf_msg(LVL_ERROR, "Cannot read match score for function " 470 "%s.", ddf_fun_get_name(fun->fnode));480 "%s.", fun->fnode->name); 471 481 return; 472 482 } … … 476 486 if (id == NULL) { 477 487 ddf_msg(LVL_ERROR, "Cannot read match ID for function %s.", 478 ddf_fun_get_name(fun->fnode));488 fun->fnode->name); 479 489 return; 480 490 } 481 491 482 492 ddf_msg(LVL_DEBUG, "Adding match id '%s' with score %d to " 483 "function %s", id, score, ddf_fun_get_name(fun->fnode));484 485 rc = ddf_fun_add_match_id(fun->fnode, id, score);493 "function %s", id, score, fun->fnode->name); 494 495 int rc = ddf_fun_add_match_id(fun->fnode, id, score); 486 496 if (rc != EOK) { 487 497 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", … … 492 502 } 493 503 494 static bool prop_parse(isa_fun_t *fun, c har *line, const char *prop,495 void (*read_fn)(isa_fun_t *, c har *))504 static bool prop_parse(isa_fun_t *fun, const char *line, const char *prop, 505 void (*read_fn)(isa_fun_t *, const char *)) 496 506 { 497 507 size_t proplen = str_size(prop); … … 508 518 } 509 519 510 static void fun_prop_parse(isa_fun_t *fun, c har *line)520 static void fun_prop_parse(isa_fun_t *fun, const char *line) 511 521 { 512 522 /* Skip leading spaces. */ … … 523 533 } 524 534 525 static void fun_hw_res_alloc(isa_fun_t *fun)526 {527 fun->hw_resources.resources =528 (hw_resource_t *) malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);529 }530 531 static void fun_hw_res_free(isa_fun_t *fun)532 {533 free(fun->hw_resources.resources);534 fun->hw_resources.resources = NULL;535 }536 537 535 static char *isa_fun_read_info(char *fun_conf, isa_bus_t *isa) 538 536 { 539 537 char *line; 540 char *fun_name = NULL;541 538 542 539 /* Skip empty lines. */ 543 while (true){540 do { 544 541 line = str_get_line(fun_conf, &fun_conf); 545 542 … … 549 546 } 550 547 551 if (!line_empty(line)) 552 break; 553 } 548 } while (line_empty(line)); 554 549 555 550 /* Get device name. */ 556 fun_name = get_device_name(line);551 const char *fun_name = get_device_name(line); 557 552 if (fun_name == NULL) 558 553 return NULL; 559 554 560 555 isa_fun_t *fun = isa_fun_create(isa, fun_name); 561 free(fun_name);562 556 if (fun == NULL) { 563 557 return NULL; 564 558 } 565 566 /* Allocate buffer for the list of hardware resources of the device. */567 fun_hw_res_alloc(fun);568 559 569 560 /* Get properties of the device (match ids, irq and io range). */ … … 584 575 585 576 /* Set device operations to the device. */ 586 ddf_fun_set_ops(fun->fnode, &isa_fun_ops);587 588 ddf_msg(LVL_DEBUG, "Binding function %s.", ddf_fun_get_name(fun->fnode));577 fun->fnode->ops = &isa_fun_ops; 578 579 ddf_msg(LVL_DEBUG, "Binding function %s.", fun->fnode->name); 589 580 590 581 /* XXX Handle error */ … … 596 587 } 597 588 598 static void fun_conf_parse(char *conf, isa_bus_t *isa) 599 { 589 static void isa_functions_add(isa_bus_t *isa) 590 { 591 char *conf = fun_conf_read(CHILD_FUN_CONF_PATH); 600 592 while (conf != NULL && *conf != '\0') { 601 593 conf = isa_fun_read_info(conf, isa); 602 594 } 603 } 604 605 static void isa_functions_add(isa_bus_t *isa) 606 { 607 char *fun_conf; 608 609 fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH); 610 if (fun_conf != NULL) { 611 fun_conf_parse(fun_conf, isa); 612 free(fun_conf); 613 } 595 free(conf); 614 596 } 615 597 616 598 static int isa_dev_add(ddf_dev_t *dev) 617 599 { 618 isa_bus_t *isa;619 620 600 ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d", 621 (int) d df_dev_get_handle(dev));622 623 isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));601 (int) dev->handle); 602 603 isa_bus_t *isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t)); 624 604 if (isa == NULL) 625 605 return ENOMEM; … … 657 637 static int isa_dev_remove(ddf_dev_t *dev) 658 638 { 659 isa_bus_t *isa = isa_bus(dev); 660 int rc; 639 isa_bus_t *isa = ISA_BUS(dev); 661 640 662 641 fibril_mutex_lock(&isa->mutex); … … 666 645 isa_fun_t, bus_link); 667 646 668 rc = ddf_fun_offline(fun->fnode);647 int rc = ddf_fun_offline(fun->fnode); 669 648 if (rc != EOK) { 670 649 fibril_mutex_unlock(&isa->mutex); 671 ddf_msg(LVL_ERROR, "Failed offlining %s", ddf_fun_get_name(fun->fnode));650 ddf_msg(LVL_ERROR, "Failed offlining %s", fun->fnode->name); 672 651 return rc; 673 652 } … … 676 655 if (rc != EOK) { 677 656 fibril_mutex_unlock(&isa->mutex); 678 ddf_msg(LVL_ERROR, "Failed unbinding %s", ddf_fun_get_name(fun->fnode));657 ddf_msg(LVL_ERROR, "Failed unbinding %s", fun->fnode->name); 679 658 return rc; 680 659 } … … 682 661 list_remove(&fun->bus_link); 683 662 684 fun_hw_res_free(fun);685 663 ddf_fun_destroy(fun->fnode); 686 664 } … … 709 687 } 710 688 711 712 static void isa_init()713 {714 ddf_log_init(NAME);715 isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;716 }717 718 689 int main(int argc, char *argv[]) 719 690 { 720 691 printf(NAME ": HelenOS ISA bus driver\n"); 721 isa_init();692 ddf_log_init(NAME, LVL_ERROR); 722 693 return ddf_driver_main(&isa_driver); 723 694 }
Note:
See TracChangeset
for help on using the changeset viewer.