Changes in uspace/drv/bus/isa/isa.c [3e6a98c5:9e470c0] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/isa/isa.c
r3e6a98c5 r9e470c0 65 65 #include <ddf/log.h> 66 66 #include <ops/hw_res.h> 67 #include <ops/pio_window.h> 67 68 68 69 #include <device/hw_res.h> 70 #include <device/pio_window.h> 69 71 70 72 #include "i8237.h" … … 79 81 ddf_dev_t *dev; 80 82 ddf_fun_t *fctl; 83 pio_window_t pio_win; 81 84 list_t functions; 82 85 } isa_bus_t; … … 85 88 fibril_mutex_t mutex; 86 89 ddf_fun_t *fnode; 90 hw_resource_t resources[ISA_MAX_HW_RES]; 87 91 hw_resource_list_t hw_resources; 88 92 link_t bus_link; … … 101 105 } 102 106 103 static hw_resource_list_t *isa_ get_fun_resources(ddf_fun_t *fnode)107 static hw_resource_list_t *isa_fun_get_resources(ddf_fun_t *fnode) 104 108 { 105 109 isa_fun_t *fun = isa_fun(fnode); 106 assert(fun != NULL);110 assert(fun); 107 111 108 112 return &fun->hw_resources; 109 113 } 110 114 111 static bool isa_ enable_fun_interrupt(ddf_fun_t *fnode)115 static bool isa_fun_enable_interrupt(ddf_fun_t *fnode) 112 116 { 113 117 /* This is an old ugly way, copied from pci driver */ 114 118 assert(fnode); 115 119 isa_fun_t *fun = isa_fun(fnode); 120 assert(fun); 116 121 117 122 sysarg_t apic; … … 151 156 } 152 157 153 static int isa_ dma_channel_fun_setup(ddf_fun_t *fnode,154 unsigned int channel, uint32_t pa, uint 16_t size, uint8_t mode)158 static int isa_fun_setup_dma(ddf_fun_t *fnode, 159 unsigned int channel, uint32_t pa, uint32_t size, uint8_t mode) 155 160 { 156 161 assert(fnode); 157 162 isa_fun_t *fun = isa_fun(fnode); 163 assert(fun); 158 164 const hw_resource_list_t *res = &fun->hw_resources; 159 165 assert(res); 160 161 const unsigned int ch = channel; 166 162 167 for (size_t i = 0; i < res->count; ++i) { 168 /* Check for assigned channel */ 163 169 if (((res->resources[i].type == DMA_CHANNEL_16) && 164 (res->resources[i].res.dma_channel.dma16 == ch )) ||170 (res->resources[i].res.dma_channel.dma16 == channel)) || 165 171 ((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);168 } 169 } 170 172 (res->resources[i].res.dma_channel.dma8 == channel))) { 173 return dma_channel_setup(channel, pa, size, mode); 174 } 175 } 176 171 177 return EINVAL; 172 178 } 173 179 180 static int isa_fun_remain_dma(ddf_fun_t *fnode, 181 unsigned channel, size_t *size) 182 { 183 assert(size); 184 assert(fnode); 185 isa_fun_t *fun = isa_fun(fnode); 186 assert(fun); 187 const hw_resource_list_t *res = &fun->hw_resources; 188 assert(res); 189 190 for (size_t i = 0; i < res->count; ++i) { 191 /* Check for assigned channel */ 192 if (((res->resources[i].type == DMA_CHANNEL_16) && 193 (res->resources[i].res.dma_channel.dma16 == channel)) || 194 ((res->resources[i].type == DMA_CHANNEL_8) && 195 (res->resources[i].res.dma_channel.dma8 == channel))) { 196 return dma_channel_remain(channel, size); 197 } 198 } 199 200 return EINVAL; 201 } 202 174 203 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, 204 .get_resource_list = isa_fun_get_resources, 205 .enable_interrupt = isa_fun_enable_interrupt, 206 .dma_channel_setup = isa_fun_setup_dma, 207 .dma_channel_remain = isa_fun_remain_dma, 178 208 }; 179 209 180 static ddf_dev_ops_t isa_fun_ops; 210 static pio_window_t *isa_fun_get_pio_window(ddf_fun_t *fnode) 211 { 212 ddf_dev_t *dev = ddf_fun_get_dev(fnode); 213 isa_bus_t *isa = isa_bus(dev); 214 assert(isa); 215 216 return &isa->pio_win; 217 } 218 219 static pio_window_ops_t isa_fun_pio_window_ops = { 220 .get_pio_window = isa_fun_get_pio_window 221 }; 222 223 static ddf_dev_ops_t isa_fun_ops= { 224 .interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops, 225 .interfaces[PIO_WINDOW_DEV_IFACE] = &isa_fun_pio_window_ops, 226 }; 181 227 182 228 static int isa_dev_add(ddf_dev_t *dev); … … 212 258 213 259 fibril_mutex_initialize(&fun->mutex); 260 fun->hw_resources.resources = fun->resources; 261 214 262 fun->fnode = fnode; 215 263 return fun; … … 270 318 { 271 319 char *line = str; 320 *next = NULL; 272 321 273 322 if (str == NULL) { 274 *next = NULL;275 323 return NULL; 276 324 } … … 282 330 if (*str != '\0') { 283 331 *next = str + 1; 284 } else {285 *next = NULL;286 332 } 287 333 … … 310 356 /* Get the name part of the rest of the line. */ 311 357 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) 358 return line; 359 } 360 361 static inline const char *skip_spaces(const char *line) 326 362 { 327 363 /* Skip leading spaces. */ … … 332 368 } 333 369 334 static void isa_fun_ set_irq(isa_fun_t *fun, int irq)370 static void isa_fun_add_irq(isa_fun_t *fun, int irq) 335 371 { 336 372 size_t count = fun->hw_resources.count; … … 348 384 } 349 385 350 static void isa_fun_ set_dma(isa_fun_t *fun, int dma)386 static void isa_fun_add_dma(isa_fun_t *fun, int dma) 351 387 { 352 388 size_t count = fun->hw_resources.count; … … 381 417 } 382 418 383 static void isa_fun_ set_io_range(isa_fun_t *fun, size_t addr, size_t len)419 static void isa_fun_add_io_range(isa_fun_t *fun, size_t addr, size_t len) 384 420 { 385 421 size_t count = fun->hw_resources.count; 386 422 hw_resource_t *resources = fun->hw_resources.resources; 423 424 isa_bus_t *isa = isa_bus(ddf_fun_get_dev(fun->fnode)); 387 425 388 426 if (count < ISA_MAX_HW_RES) { 389 427 resources[count].type = IO_RANGE; 390 428 resources[count].res.io_range.address = addr; 429 resources[count].res.io_range.address += isa->pio_win.io.base; 391 430 resources[count].res.io_range.size = len; 431 resources[count].res.io_range.relative = false; 392 432 resources[count].res.io_range.endianness = LITTLE_ENDIAN; 393 433 … … 400 440 } 401 441 402 static void fun_parse_irq(isa_fun_t *fun, c har *val)442 static void fun_parse_irq(isa_fun_t *fun, const char *val) 403 443 { 404 444 int irq = 0; … … 409 449 410 450 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; 451 isa_fun_add_irq(fun, irq); 452 } 453 454 static void fun_parse_dma(isa_fun_t *fun, const char *val) 455 { 417 456 char *end = NULL; 418 457 419 458 val = skip_spaces(val); 420 dma = (unsigned int)strtol(val, &end, 10);459 const int dma = strtol(val, &end, 10); 421 460 422 461 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)462 isa_fun_add_dma(fun, dma); 463 } 464 465 static void fun_parse_io_range(isa_fun_t *fun, const char *val) 427 466 { 428 467 size_t addr, len; … … 441 480 return; 442 481 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;482 isa_fun_add_io_range(fun, addr, len); 483 } 484 485 static void get_match_id(char **id, const char *val) 486 { 487 const char *end = val; 449 488 450 489 while (!isspace(*end)) … … 456 495 } 457 496 458 static void fun_parse_match_id(isa_fun_t *fun, c har *val)497 static void fun_parse_match_id(isa_fun_t *fun, const char *val) 459 498 { 460 499 char *id = NULL; 461 int score = 0;462 500 char *end = NULL; 463 int rc;464 501 465 502 val = skip_spaces(val); 466 503 467 score = (int)strtol(val, &end, 10);504 int score = (int)strtol(val, &end, 10); 468 505 if (val == end) { 469 506 ddf_msg(LVL_ERROR, "Cannot read match score for function " … … 483 520 "function %s", id, score, ddf_fun_get_name(fun->fnode)); 484 521 485 rc = ddf_fun_add_match_id(fun->fnode, id, score);522 int rc = ddf_fun_add_match_id(fun->fnode, id, score); 486 523 if (rc != EOK) { 487 524 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", … … 492 529 } 493 530 494 static bool prop_parse(isa_fun_t *fun, c har *line, const char *prop,495 void (*read_fn)(isa_fun_t *, c har *))531 static bool prop_parse(isa_fun_t *fun, const char *line, const char *prop, 532 void (*read_fn)(isa_fun_t *, const char *)) 496 533 { 497 534 size_t proplen = str_size(prop); … … 508 545 } 509 546 510 static void fun_prop_parse(isa_fun_t *fun, c har *line)547 static void fun_prop_parse(isa_fun_t *fun, const char *line) 511 548 { 512 549 /* Skip leading spaces. */ … … 523 560 } 524 561 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 562 static char *isa_fun_read_info(char *fun_conf, isa_bus_t *isa) 538 563 { 539 564 char *line; 540 char *fun_name = NULL;541 565 542 566 /* Skip empty lines. */ 543 while (true){567 do { 544 568 line = str_get_line(fun_conf, &fun_conf); 545 569 … … 549 573 } 550 574 551 if (!line_empty(line)) 552 break; 553 } 575 } while (line_empty(line)); 554 576 555 577 /* Get device name. */ 556 fun_name = get_device_name(line);578 const char *fun_name = get_device_name(line); 557 579 if (fun_name == NULL) 558 580 return NULL; 559 581 560 582 isa_fun_t *fun = isa_fun_create(isa, fun_name); 561 free(fun_name);562 583 if (fun == NULL) { 563 584 return NULL; 564 585 } 565 566 /* Allocate buffer for the list of hardware resources of the device. */567 fun_hw_res_alloc(fun);568 586 569 587 /* Get properties of the device (match ids, irq and io range). */ … … 596 614 } 597 615 598 static void fun_conf_parse(char *conf, isa_bus_t *isa) 599 { 616 static void isa_functions_add(isa_bus_t *isa) 617 { 618 char *conf = fun_conf_read(CHILD_FUN_CONF_PATH); 600 619 while (conf != NULL && *conf != '\0') { 601 620 conf = isa_fun_read_info(conf, isa); 602 621 } 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 } 622 free(conf); 614 623 } 615 624 616 625 static int isa_dev_add(ddf_dev_t *dev) 617 626 { 618 isa_bus_t *isa; 627 async_sess_t *sess; 628 int rc; 619 629 620 630 ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d", 621 631 (int) ddf_dev_get_handle(dev)); 622 632 623 isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));633 isa_bus_t *isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t)); 624 634 if (isa == NULL) 625 635 return ENOMEM; … … 628 638 isa->dev = dev; 629 639 list_initialize(&isa->functions); 640 641 sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE); 642 if (sess == NULL) { 643 ddf_msg(LVL_ERROR, "isa_dev_add failed to connect to the " 644 "parent driver."); 645 return ENOENT; 646 } 647 648 rc = pio_window_get(sess, &isa->pio_win); 649 if (rc != EOK) { 650 ddf_msg(LVL_ERROR, "isa_dev_add failed to get PIO window " 651 "for the device."); 652 return rc; 653 } 630 654 631 655 /* Make the bus device more visible. Does not do anything. */ … … 658 682 { 659 683 isa_bus_t *isa = isa_bus(dev); 660 int rc;661 684 662 685 fibril_mutex_lock(&isa->mutex); … … 666 689 isa_fun_t, bus_link); 667 690 668 rc = ddf_fun_offline(fun->fnode);691 int rc = ddf_fun_offline(fun->fnode); 669 692 if (rc != EOK) { 670 693 fibril_mutex_unlock(&isa->mutex); … … 682 705 list_remove(&fun->bus_link); 683 706 684 fun_hw_res_free(fun);685 707 ddf_fun_destroy(fun->fnode); 686 708 } … … 709 731 } 710 732 711 712 static void isa_init() 713 { 733 int main(int argc, char *argv[]) 734 { 735 printf(NAME ": HelenOS ISA bus driver\n"); 714 736 ddf_log_init(NAME); 715 isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;716 }717 718 int main(int argc, char *argv[])719 {720 printf(NAME ": HelenOS ISA bus driver\n");721 isa_init();722 737 return ddf_driver_main(&isa_driver); 723 738 }
Note:
See TracChangeset
for help on using the changeset viewer.