Changes in uspace/drv/isa/isa.c [28a3e74:032e0bb] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/isa/isa.c
r28a3e74 r032e0bb 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda4 3 * All rights reserved. 5 4 * … … 44 43 #include <stdlib.h> 45 44 #include <str.h> 46 #include <str_error.h>47 45 #include <ctype.h> 48 46 #include <macros.h> … … 52 50 #include <sys/stat.h> 53 51 54 #include <ddf/driver.h> 55 #include <ddf/log.h> 56 #include <ops/hw_res.h> 52 #include <driver.h> 53 #include <resource.h> 57 54 58 55 #include <devman.h> … … 61 58 62 59 #define NAME "isa" 63 #define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev" 64 65 /** Obtain soft-state pointer from function node pointer */ 66 #define ISA_FUN(fnode) ((isa_fun_t *) ((fnode)->driver_data)) 60 #define CHILD_DEV_CONF_PATH "/drv/isa/isa.dev" 67 61 68 62 #define ISA_MAX_HW_RES 4 69 63 70 typedef struct isa_fun { 71 ddf_fun_t *fnode; 64 typedef struct isa_child_data { 72 65 hw_resource_list_t hw_resources; 73 } isa_fun_t; 74 75 static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode) 76 { 77 isa_fun_t *fun = ISA_FUN(fnode); 78 assert(fun != NULL); 79 80 return &fun->hw_resources; 81 } 82 83 static bool isa_enable_fun_interrupt(ddf_fun_t *fnode) 84 { 85 /* TODO */ 66 } isa_child_data_t; 67 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) 74 return NULL; 75 76 return &dev_data->hw_resources; 77 } 78 79 static bool isa_enable_child_interrupt(device_t *dev) 80 { 81 // TODO 86 82 87 83 return false; 88 84 } 89 85 90 static hw_res_ops_t isa_fun_hw_res_ops= {91 &isa_get_ fun_resources,92 &isa_enable_ fun_interrupt86 static resource_iface_t isa_child_res_iface = { 87 &isa_get_child_resources, 88 &isa_enable_child_interrupt 93 89 }; 94 90 95 static d df_dev_ops_t isa_fun_ops;96 97 static int isa_add_device(d df_dev_t *dev);91 static device_ops_t isa_child_dev_ops; 92 93 static int isa_add_device(device_t *dev); 98 94 99 95 /** The isa device driver's standard operations */ … … 108 104 }; 109 105 110 static isa_fun_t *isa_fun_create(ddf_dev_t *dev, const char *name) 111 { 112 isa_fun_t *fun = calloc(1, sizeof(isa_fun_t)); 113 if (fun == NULL) 106 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() 119 { 120 device_t *dev = create_device(); 121 if (dev == NULL) 114 122 return NULL; 115 123 116 ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name);117 if ( fnode== NULL) {118 free(fun);124 isa_child_data_t *data = create_isa_child_data(); 125 if (data == NULL) { 126 delete_device(dev); 119 127 return NULL; 120 128 } 121 129 122 fun->fnode = fnode; 123 fnode->driver_data = fun; 124 return fun; 125 } 126 127 static char *fun_conf_read(const char *conf_path) 130 dev->driver_data = data; 131 return dev; 132 } 133 134 static char *read_dev_conf(const char *conf_path) 128 135 { 129 136 bool suc = false; … … 135 142 fd = open(conf_path, O_RDONLY); 136 143 if (fd < 0) { 137 ddf_msg(LVL_ERROR, "Unable to open %s", conf_path);144 printf(NAME ": unable to open %s\n", conf_path); 138 145 goto cleanup; 139 146 } … … 142 149 143 150 len = lseek(fd, 0, SEEK_END); 144 lseek(fd, 0, SEEK_SET); 151 lseek(fd, 0, SEEK_SET); 145 152 if (len == 0) { 146 ddf_msg(LVL_ERROR, "Configuration file '%s' is empty.",147 conf_path);153 printf(NAME ": read_dev_conf error: configuration file '%s' " 154 "is empty.\n", conf_path); 148 155 goto cleanup; 149 156 } … … 151 158 buf = malloc(len + 1); 152 159 if (buf == NULL) { 153 ddf_msg(LVL_ERROR, "Memory allocation failed.");160 printf(NAME ": read_dev_conf error: memory allocation failed.\n"); 154 161 goto cleanup; 155 162 } 156 163 157 164 if (0 >= read(fd, buf, len)) { 158 ddf_msg(LVL_ERROR, "Unable to read file '%s'.", conf_path); 165 printf(NAME ": read_dev_conf error: unable to read file '%s'.\n", 166 conf_path); 159 167 goto cleanup; 160 168 } … … 241 249 } 242 250 243 static void isa_fun_set_irq(isa_fun_t *fun, int irq) 244 { 245 size_t count = fun->hw_resources.count; 246 hw_resource_t *resources = fun->hw_resources.resources; 251 static void isa_child_set_irq(device_t *dev, int irq) 252 { 253 isa_child_data_t *data = (isa_child_data_t *)dev->driver_data; 254 255 size_t count = data->hw_resources.count; 256 hw_resource_t *resources = data->hw_resources.resources; 247 257 248 258 if (count < ISA_MAX_HW_RES) { … … 250 260 resources[count].res.interrupt.irq = irq; 251 261 252 fun->hw_resources.count++; 253 254 ddf_msg(LVL_NOTE, "Added irq 0x%x to function %s", irq, 255 fun->fnode->name); 256 } 257 } 258 259 static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len) 260 { 261 size_t count = fun->hw_resources.count; 262 hw_resource_t *resources = fun->hw_resources.resources; 262 data->hw_resources.count++; 263 264 printf(NAME ": added irq 0x%x to device %s\n", irq, dev->name); 265 } 266 } 267 268 static void isa_child_set_io_range(device_t *dev, size_t addr, size_t len) 269 { 270 isa_child_data_t *data = (isa_child_data_t *)dev->driver_data; 271 272 size_t count = data->hw_resources.count; 273 hw_resource_t *resources = data->hw_resources.resources; 263 274 264 275 if (count < ISA_MAX_HW_RES) { … … 268 279 resources[count].res.io_range.endianness = LITTLE_ENDIAN; 269 280 270 fun->hw_resources.count++; 271 272 ddf_msg(LVL_NOTE, "Added io range (addr=0x%x, size=0x%x) to " 273 "function %s", (unsigned int) addr, (unsigned int) len, 274 fun->fnode->name); 275 } 276 } 277 278 static void fun_parse_irq(isa_fun_t *fun, char *val) 281 data->hw_resources.count++; 282 283 printf(NAME ": added io range (addr=0x%x, size=0x%x) to " 284 "device %s\n", addr, len, dev->name); 285 } 286 } 287 288 static void get_dev_irq(device_t *dev, char *val) 279 289 { 280 290 int irq = 0; 281 291 char *end = NULL; 282 292 283 val = skip_spaces(val); 293 val = skip_spaces(val); 284 294 irq = (int)strtol(val, &end, 0x10); 285 295 286 296 if (val != end) 287 isa_ fun_set_irq(fun, irq);288 } 289 290 static void fun_parse_io_range(isa_fun_t *fun, char *val)297 isa_child_set_irq(dev, irq); 298 } 299 300 static void get_dev_io_range(device_t *dev, char *val) 291 301 { 292 302 size_t addr, len; 293 303 char *end = NULL; 294 304 295 val = skip_spaces(val); 305 val = skip_spaces(val); 296 306 addr = strtol(val, &end, 0x10); 297 307 … … 299 309 return; 300 310 301 val = skip_spaces(end); 311 val = skip_spaces(end); 302 312 len = strtol(val, &end, 0x10); 303 313 … … 305 315 return; 306 316 307 isa_ fun_set_io_range(fun, addr, len);317 isa_child_set_io_range(dev, addr, len); 308 318 } 309 319 … … 320 330 } 321 331 322 static void fun_parse_match_id(isa_fun_t *fun, char *val)332 static void get_dev_match_id(device_t *dev, char *val) 323 333 { 324 334 char *id = NULL; 325 335 int score = 0; 326 336 char *end = NULL; 327 int rc; 328 329 val = skip_spaces(val); 337 338 val = skip_spaces(val); 330 339 331 340 score = (int)strtol(val, &end, 10); 332 341 if (val == end) { 333 ddf_msg(LVL_ERROR, "Cannot read match score for function"334 " %s.", fun->fnode->name);342 printf(NAME " : error - could not read match score for " 343 "device %s.\n", dev->name); 335 344 return; 336 345 } 337 346 338 val = skip_spaces(end); 347 match_id_t *match_id = create_match_id(); 348 if (match_id == NULL) { 349 printf(NAME " : failed to allocate match id for device %s.\n", 350 dev->name); 351 return; 352 } 353 354 val = skip_spaces(end); 339 355 get_match_id(&id, val); 340 356 if (id == NULL) { 341 ddf_msg(LVL_ERROR, "Cannot read match ID for function %s.", 342 fun->fnode->name); 357 printf(NAME " : error - could not read match id for " 358 "device %s.\n", dev->name); 359 delete_match_id(match_id); 343 360 return; 344 361 } 345 362 346 ddf_msg(LVL_DEBUG, "Adding match id '%s' with score %d to " 347 "function %s", id, score, fun->fnode->name); 348 349 rc = ddf_fun_add_match_id(fun->fnode, id, score); 350 if (rc != EOK) { 351 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", 352 str_error(rc)); 353 } 354 } 355 356 static bool prop_parse(isa_fun_t *fun, char *line, const char *prop, 357 void (*read_fn)(isa_fun_t *, char *)) 363 match_id->id = id; 364 match_id->score = score; 365 366 printf(NAME ": adding match id '%s' with score %d to device %s\n", id, 367 score, dev->name); 368 add_match_id(&dev->match_ids, match_id); 369 } 370 371 static bool read_dev_prop(device_t *dev, char *line, const char *prop, 372 void (*read_fn)(device_t *, char *)) 358 373 { 359 374 size_t proplen = str_size(prop); … … 362 377 line += proplen; 363 378 line = skip_spaces(line); 364 (*read_fn)( fun, line);379 (*read_fn)(dev, line); 365 380 366 381 return true; … … 370 385 } 371 386 372 static void fun_prop_parse(isa_fun_t *fun, char *line)387 static void get_dev_prop(device_t *dev, char *line) 373 388 { 374 389 /* Skip leading spaces. */ 375 390 line = skip_spaces(line); 376 391 377 if (!prop_parse(fun, line, "io_range", &fun_parse_io_range) && 378 !prop_parse(fun, line, "irq", &fun_parse_irq) && 379 !prop_parse(fun, line, "match", &fun_parse_match_id)) { 380 381 ddf_msg(LVL_ERROR, "Undefined device property at line '%s'", 382 line); 383 } 384 } 385 386 static void fun_hw_res_alloc(isa_fun_t *fun) 387 { 388 fun->hw_resources.resources = 392 if (!read_dev_prop(dev, line, "io_range", &get_dev_io_range) && 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) 402 { 403 isa_child_data_t *data = (isa_child_data_t *)dev->driver_data; 404 data->hw_resources.resources = 389 405 (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES); 390 406 } 391 407 392 static char * isa_fun_read_info(char *fun_conf, ddf_dev_t *dev)408 static char *read_isa_dev_info(char *dev_conf, device_t *parent) 393 409 { 394 410 char *line; 395 char * fun_name = NULL;411 char *dev_name = NULL; 396 412 397 413 /* Skip empty lines. */ 398 414 while (true) { 399 line = str_get_line( fun_conf, &fun_conf);415 line = str_get_line(dev_conf, &dev_conf); 400 416 401 417 if (line == NULL) { … … 409 425 410 426 /* Get device name. */ 411 fun_name = get_device_name(line);412 if ( fun_name == NULL)427 dev_name = get_device_name(line); 428 if (dev_name == NULL) 413 429 return NULL; 414 430 415 isa_fun_t *fun = isa_fun_create(dev, fun_name);416 if ( fun== NULL) {417 free( fun_name);431 device_t *dev = create_isa_child_dev(); 432 if (dev == NULL) { 433 free(dev_name); 418 434 return NULL; 419 435 } 420 436 437 dev->name = dev_name; 438 421 439 /* Allocate buffer for the list of hardware resources of the device. */ 422 fun_hw_res_alloc(fun);440 child_alloc_hw_res(dev); 423 441 424 442 /* Get properties of the device (match ids, irq and io range). */ 425 443 while (true) { 426 line = str_get_line( fun_conf, &fun_conf);444 line = str_get_line(dev_conf, &dev_conf); 427 445 428 446 if (line_empty(line)) { … … 435 453 * and store it in the device structure. 436 454 */ 437 fun_prop_parse(fun, line); 455 get_dev_prop(dev, line); 456 457 //printf(NAME ": next line ='%s'\n", dev_conf); 458 //printf(NAME ": current line ='%s'\n", line); 438 459 } 439 460 440 461 /* Set device operations to the device. */ 441 fun->fnode->ops = &isa_fun_ops; 442 443 ddf_msg(LVL_DEBUG, "Binding function %s.", fun->fnode->name); 444 445 /* XXX Handle error */ 446 (void) ddf_fun_bind(fun->fnode); 447 448 return fun_conf; 449 } 450 451 static void fun_conf_parse(char *conf, ddf_dev_t *dev) 462 dev->ops = &isa_child_dev_ops; 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; 469 } 470 471 static void parse_dev_conf(char *conf, device_t *parent) 452 472 { 453 473 while (conf != NULL && *conf != '\0') { 454 conf = isa_fun_read_info(conf, dev); 455 } 456 } 457 458 static void isa_functions_add(ddf_dev_t *dev) 459 { 460 char *fun_conf; 461 462 fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH); 463 if (fun_conf != NULL) { 464 fun_conf_parse(fun_conf, dev); 465 free(fun_conf); 466 } 467 } 468 469 static int isa_add_device(ddf_dev_t *dev) 470 { 471 ddf_msg(LVL_DEBUG, "isa_add_device, device handle = %d", 472 (int) dev->handle); 473 474 /* Make the bus device more visible. Does not do anything. */ 475 ddf_msg(LVL_DEBUG, "Adding a 'ctl' function"); 476 477 ddf_fun_t *ctl = ddf_fun_create(dev, fun_exposed, "ctl"); 478 if (ctl == NULL) { 479 ddf_msg(LVL_ERROR, "Failed creating control function."); 480 return EXDEV; 481 } 482 483 if (ddf_fun_bind(ctl) != EOK) { 484 ddf_msg(LVL_ERROR, "Failed binding control function."); 485 return EXDEV; 486 } 487 488 /* Add functions as specified in the configuration file. */ 489 isa_functions_add(dev); 490 ddf_msg(LVL_NOTE, "Finished enumerating legacy functions"); 474 conf = read_isa_dev_info(conf, parent); 475 } 476 } 477 478 static void add_legacy_children(device_t *parent) 479 { 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); 485 free(dev_conf); 486 } 487 } 488 489 static int isa_add_device(device_t *dev) 490 { 491 printf(NAME ": isa_add_device, device handle = %d\n", dev->handle); 492 493 /* Add child devices. */ 494 add_legacy_children(dev); 495 printf(NAME ": finished the enumeration of legacy devices\n", 496 dev->handle); 491 497 492 498 return EOK; … … 495 501 static void isa_init() 496 502 { 497 ddf_log_init(NAME, LVL_ERROR); 498 isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops; 503 isa_child_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_child_res_iface; 499 504 } 500 505 … … 503 508 printf(NAME ": HelenOS ISA bus driver\n"); 504 509 isa_init(); 505 return d df_driver_main(&isa_driver);510 return driver_main(&isa_driver); 506 511 } 507 512 … … 509 514 * @} 510 515 */ 516
Note:
See TracChangeset
for help on using the changeset viewer.