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