Changeset 0c968a17 in mainline
- Timestamp:
- 2011-02-15T22:58:28Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8b1ea2d4
- Parents:
- 6a343bdf (diff), aa7dc64 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 1 added
- 25 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/tester/hw/serial/serial1.c
r6a343bdf r0c968a17 74 74 75 75 devman_handle_t handle; 76 res = devman_device_get_handle("/hw/pci0/00:01.0/com1 ", &handle,76 res = devman_device_get_handle("/hw/pci0/00:01.0/com1/a", &handle, 77 77 IPC_FLAG_BLOCKING); 78 78 if (res != EOK) -
uspace/drv/isa/isa.c
r6a343bdf r0c968a17 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 43 44 #include <stdlib.h> 44 45 #include <str.h> 46 #include <str_error.h> 45 47 #include <ctype.h> 46 48 #include <macros.h> … … 50 52 #include <sys/stat.h> 51 53 52 #include <d river.h>54 #include <ddf/driver.h> 53 55 #include <ops/hw_res.h> 54 56 … … 58 60 59 61 #define NAME "isa" 60 #define CHILD_DEV_CONF_PATH "/drv/isa/isa.dev" 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)) 61 66 62 67 #define ISA_MAX_HW_RES 4 63 68 64 typedef struct isa_child_data { 69 typedef struct isa_fun { 70 ddf_fun_t *fnode; 65 71 hw_resource_list_t hw_resources; 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) 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) 80 83 { 81 84 // TODO … … 84 87 } 85 88 86 static hw_res_ops_t isa_ child_hw_res_ops = {87 &isa_get_ child_resources,88 &isa_enable_ child_interrupt89 static hw_res_ops_t isa_fun_hw_res_ops = { 90 &isa_get_fun_resources, 91 &isa_enable_fun_interrupt 89 92 }; 90 93 91 static d evice_ops_t isa_child_dev_ops;92 93 static int isa_add_device(d evice_t *dev);94 static ddf_dev_ops_t isa_fun_ops; 95 96 static int isa_add_device(ddf_dev_t *dev); 94 97 95 98 /** The isa device driver's standard operations */ … … 104 107 }; 105 108 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) 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) 122 113 return NULL; 123 114 124 isa_child_data_t *data = create_isa_child_data();125 if ( data== NULL) {126 delete_device(dev);115 ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name); 116 if (fnode == NULL) { 117 free(fun); 127 118 return NULL; 128 119 } 129 120 130 dev->driver_data = data; 131 return dev; 132 } 133 134 static char *read_dev_conf(const char *conf_path) 121 fun->fnode = fnode; 122 fnode->driver_data = fun; 123 return fun; 124 } 125 126 static char *fun_conf_read(const char *conf_path) 135 127 { 136 128 bool suc = false; … … 151 143 lseek(fd, 0, SEEK_SET); 152 144 if (len == 0) { 153 printf(NAME ": read_dev_conferror: configuration file '%s' "145 printf(NAME ": fun_conf_read error: configuration file '%s' " 154 146 "is empty.\n", conf_path); 155 147 goto cleanup; … … 158 150 buf = malloc(len + 1); 159 151 if (buf == NULL) { 160 printf(NAME ": read_dev_conferror: memory allocation failed.\n");152 printf(NAME ": fun_conf_read error: memory allocation failed.\n"); 161 153 goto cleanup; 162 154 } 163 155 164 156 if (0 >= read(fd, buf, len)) { 165 printf(NAME ": read_dev_conferror: unable to read file '%s'.\n",157 printf(NAME ": fun_conf_read error: unable to read file '%s'.\n", 166 158 conf_path); 167 159 goto cleanup; … … 249 241 } 250 242 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; 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; 257 247 258 248 if (count < ISA_MAX_HW_RES) { … … 260 250 resources[count].res.interrupt.irq = irq; 261 251 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; 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; 274 263 275 264 if (count < ISA_MAX_HW_RES) { … … 279 268 resources[count].res.io_range.endianness = LITTLE_ENDIAN; 280 269 281 data->hw_resources.count++;270 fun->hw_resources.count++; 282 271 283 272 printf(NAME ": added io range (addr=0x%x, size=0x%x) to " 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)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) 290 279 { 291 280 int irq = 0; 292 281 char *end = NULL; 293 282 294 val = skip_spaces(val); 283 val = skip_spaces(val); 295 284 irq = (int)strtol(val, &end, 0x10); 296 285 297 286 if (val != end) 298 isa_ child_set_irq(dev, irq);299 } 300 301 static void get_dev_io_range(device_t *dev, char *val)287 isa_fun_set_irq(fun, irq); 288 } 289 290 static void fun_parse_io_range(isa_fun_t *fun, char *val) 302 291 { 303 292 size_t addr, len; 304 293 char *end = NULL; 305 294 306 val = skip_spaces(val); 295 val = skip_spaces(val); 307 296 addr = strtol(val, &end, 0x10); 308 297 … … 310 299 return; 311 300 312 val = skip_spaces(end); 301 val = skip_spaces(end); 313 302 len = strtol(val, &end, 0x10); 314 303 … … 316 305 return; 317 306 318 isa_ child_set_io_range(dev, addr, len);307 isa_fun_set_io_range(fun, addr, len); 319 308 } 320 309 … … 331 320 } 332 321 333 static void get_dev_match_id(device_t *dev, char *val)322 static void fun_parse_match_id(isa_fun_t *fun, char *val) 334 323 { 335 324 char *id = NULL; 336 325 int score = 0; 337 326 char *end = NULL; 338 339 val = skip_spaces(val); 327 int rc; 328 329 val = skip_spaces(val); 340 330 341 331 score = (int)strtol(val, &end, 10); 342 332 if (val == end) { 343 333 printf(NAME " : error - could not read match score for " 344 " device %s.\n", dev->name);334 "function %s.\n", fun->fnode->name); 345 335 return; 346 336 } 347 337 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); 338 val = skip_spaces(end); 356 339 get_match_id(&id, val); 357 340 if (id == NULL) { 358 341 printf(NAME " : error - could not read match id for " 359 "device %s.\n", dev->name); 360 delete_match_id(match_id); 342 "function %s.\n", fun->fnode->name); 361 343 return; 362 344 } 363 345 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 *))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 *)) 374 356 { 375 357 size_t proplen = str_size(prop); … … 378 360 line += proplen; 379 361 line = skip_spaces(line); 380 (*read_fn)( dev, line);362 (*read_fn)(fun, line); 381 363 382 364 return true; … … 386 368 } 387 369 388 static void get_dev_prop(device_t *dev, char *line)370 static void fun_prop_parse(isa_fun_t *fun, char *line) 389 371 { 390 372 /* Skip leading spaces. */ 391 373 line = skip_spaces(line); 392 374 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))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)) 396 378 { 397 379 printf(NAME " error undefined device property at line '%s'\n", … … 400 382 } 401 383 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 = 384 static void fun_hw_res_alloc(isa_fun_t *fun) 385 { 386 fun->hw_resources.resources = 406 387 (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES); 407 388 } 408 389 409 static char * read_isa_dev_info(char *dev_conf, device_t *parent)390 static char *isa_fun_read_info(char *fun_conf, ddf_dev_t *dev) 410 391 { 411 392 char *line; 412 char * dev_name = NULL;393 char *fun_name = NULL; 413 394 414 395 /* Skip empty lines. */ 415 396 while (true) { 416 line = str_get_line( dev_conf, &dev_conf);397 line = str_get_line(fun_conf, &fun_conf); 417 398 418 399 if (line == NULL) { … … 426 407 427 408 /* Get device name. */ 428 dev_name = get_device_name(line);429 if ( dev_name == NULL)409 fun_name = get_device_name(line); 410 if (fun_name == NULL) 430 411 return NULL; 431 412 432 device_t *dev = create_isa_child_dev();433 if ( dev== NULL) {434 free( dev_name);413 isa_fun_t *fun = isa_fun_create(dev, fun_name); 414 if (fun == NULL) { 415 free(fun_name); 435 416 return NULL; 436 417 } 437 418 438 dev->name = dev_name;439 440 419 /* Allocate buffer for the list of hardware resources of the device. */ 441 child_alloc_hw_res(dev);420 fun_hw_res_alloc(fun); 442 421 443 422 /* Get properties of the device (match ids, irq and io range). */ 444 423 while (true) { 445 line = str_get_line( dev_conf, &dev_conf);424 line = str_get_line(fun_conf, &fun_conf); 446 425 447 426 if (line_empty(line)) { … … 454 433 * and store it in the device structure. 455 434 */ 456 get_dev_prop(dev, line); 457 458 //printf(NAME ": next line ='%s'\n", dev_conf); 459 //printf(NAME ": current line ='%s'\n", line); 435 fun_prop_parse(fun, line); 460 436 } 461 437 462 438 /* Set device operations to the device. */ 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) 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) 473 450 { 474 451 while (conf != NULL && *conf != '\0') { 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(d evice_t *dev)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(ddf_dev_t *dev) 491 468 { 492 469 printf(NAME ": isa_add_device, device handle = %d\n", 493 470 (int) dev->handle); 494 471 495 /* Add child devices. */ 496 add_legacy_children(dev); 497 printf(NAME ": finished the enumeration of legacy devices\n"); 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"); 498 489 499 490 return EOK; … … 502 493 static void isa_init() 503 494 { 504 isa_ child_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_child_hw_res_ops;495 isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops; 505 496 } 506 497 … … 509 500 printf(NAME ": HelenOS ISA bus driver\n"); 510 501 isa_init(); 511 return d river_main(&isa_driver);502 return ddf_driver_main(&isa_driver); 512 503 } 513 504 … … 515 506 * @} 516 507 */ 517 -
uspace/drv/ns8250/ns8250.c
r6a343bdf r0c968a17 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 52 53 #include <libarch/ddi.h> 53 54 54 #include <driver.h> 55 #include <ddf/driver.h> 56 #include <ddf/interrupt.h> 55 57 #include <ops/char_dev.h> 56 58 … … 67 69 #define MAX_BAUD_RATE 115200 68 70 #define DLAB_MASK (1 << 7) 71 72 /** Obtain soft-state structure from function node */ 73 #define NS8250(fnode) ((ns8250_t *) ((fnode)->dev->driver_data)) 74 75 /** Obtain soft-state structure from device node */ 76 #define NS8250_FROM_DEV(dnode) ((ns8250_t *) ((dnode)->driver_data)) 69 77 70 78 /** The number of bits of one data unit send by the serial port. */ … … 85 93 86 94 /** The driver data for the serial port devices. */ 87 typedef struct ns8250_dev_data { 95 typedef struct ns8250 { 96 /** DDF device node */ 97 ddf_dev_t *dev; 98 /** DDF function node */ 99 ddf_fun_t *fun; 88 100 /** Is there any client conntected to the device? */ 89 101 bool client_connected; … … 98 110 /** The fibril mutex for synchronizing the access to the device. */ 99 111 fibril_mutex_t mutex; 100 } ns8250_ dev_data_t;101 102 /** Create driver data for a device.103 * 104 * @return The driver data.105 */ 106 static ns8250_ dev_data_t *create_ns8250_dev_data(void)107 { 108 ns8250_ dev_data_t *data;109 110 data = (ns8250_dev_data_t *) malloc(sizeof(ns8250_dev_data_t));111 if ( NULL != data) {112 memset(data, 0, sizeof(ns8250_dev_data_t));113 fibril_mutex_initialize(&data->mutex);114 }115 return data;116 } 117 118 /** Delete driver data.119 * 120 * @param dataThe driver data structure.121 */ 122 static void delete_ns8250_dev_data(ns8250_dev_data_t *data)123 { 124 if (data != NULL)125 free(data);112 } ns8250_t; 113 114 /** Create per-device soft-state structure. 115 * 116 * @return Pointer to soft-state structure. 117 */ 118 static ns8250_t *ns8250_new(void) 119 { 120 ns8250_t *ns; 121 122 ns = (ns8250_t *) calloc(1, sizeof(ns8250_t)); 123 if (ns == NULL) 124 return NULL; 125 126 fibril_mutex_initialize(&ns->mutex); 127 return ns; 128 } 129 130 /** Delete soft-state structure. 131 * 132 * @param ns The driver data structure. 133 */ 134 static void ns8250_delete(ns8250_t *ns) 135 { 136 assert(ns != NULL); 137 free(ns); 126 138 } 127 139 … … 171 183 /** Read data from the serial port device. 172 184 * 173 * @param dev The serial port device.185 * @param fun The serial port function 174 186 * @param buf The ouput buffer for read data. 175 187 * @param count The number of bytes to be read. … … 178 190 * error number otherwise. 179 191 */ 180 static int ns8250_read(device_t *dev, char *buf, size_t count) 181 { 192 static int ns8250_read(ddf_fun_t *fun, char *buf, size_t count) 193 { 194 ns8250_t *ns = NS8250(fun); 182 195 int ret = EOK; 183 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 184 185 fibril_mutex_lock(&data->mutex); 186 while (!buf_is_empty(&data->input_buffer) && (size_t)ret < count) { 187 buf[ret] = (char)buf_pop_front(&data->input_buffer); 196 197 fibril_mutex_lock(&ns->mutex); 198 while (!buf_is_empty(&ns->input_buffer) && (size_t)ret < count) { 199 buf[ret] = (char)buf_pop_front(&ns->input_buffer); 188 200 ret++; 189 201 } 190 fibril_mutex_unlock(& data->mutex);202 fibril_mutex_unlock(&ns->mutex); 191 203 192 204 return ret; … … 195 207 /** Write a character to the serial port. 196 208 * 197 * @param data The serial port device's driver data.198 * @param c The character to be written .199 */ 200 static inline void ns8250_putchar(ns8250_ dev_data_t *data, uint8_t c)201 { 202 fibril_mutex_lock(& data->mutex);203 ns8250_write_8( data->port, c);204 fibril_mutex_unlock(& data->mutex);209 * @param ns Serial port device 210 * @param c The character to be written 211 */ 212 static inline void ns8250_putchar(ns8250_t *ns, uint8_t c) 213 { 214 fibril_mutex_lock(&ns->mutex); 215 ns8250_write_8(ns->port, c); 216 fibril_mutex_unlock(&ns->mutex); 205 217 } 206 218 207 219 /** Write data to the serial port. 208 220 * 209 * @param dev The serial port device.210 * @param buf The data to be written .211 * @param count The number of bytes to be written .212 * @return Zero on success .213 */ 214 static int ns8250_write(d evice_t *dev, char *buf, size_t count)215 { 216 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;221 * @param fun The serial port function 222 * @param buf The data to be written 223 * @param count The number of bytes to be written 224 * @return Zero on success 225 */ 226 static int ns8250_write(ddf_fun_t *fun, char *buf, size_t count) 227 { 228 ns8250_t *ns = NS8250(fun); 217 229 size_t idx; 218 230 219 231 for (idx = 0; idx < count; idx++) 220 ns8250_putchar( data, (uint8_t) buf[idx]);232 ns8250_putchar(ns, (uint8_t) buf[idx]); 221 233 222 234 return 0; 223 235 } 224 236 225 static d evice_ops_t ns8250_dev_ops;237 static ddf_dev_ops_t ns8250_dev_ops; 226 238 227 239 /** The character interface's callbacks. */ … … 231 243 }; 232 244 233 static int ns8250_add_device(d evice_t *dev);245 static int ns8250_add_device(ddf_dev_t *dev); 234 246 235 247 /** The serial port device driver's standard operations. */ … … 244 256 }; 245 257 246 /** Clean up the serial port device structure. 247 * 248 * @param dev The device structure. 249 */ 250 static void ns8250_dev_cleanup(device_t *dev) 251 { 252 if (dev->driver_data != NULL) { 253 delete_ns8250_dev_data((ns8250_dev_data_t*) dev->driver_data); 254 dev->driver_data = NULL; 255 } 256 257 if (dev->parent_phone > 0) { 258 async_hangup(dev->parent_phone); 259 dev->parent_phone = 0; 258 /** Clean up the serial port soft-state 259 * 260 * @param ns Serial port device 261 */ 262 static void ns8250_dev_cleanup(ns8250_t *ns) 263 { 264 if (ns->dev->parent_phone > 0) { 265 async_hangup(ns->dev->parent_phone); 266 ns->dev->parent_phone = 0; 260 267 } 261 268 } … … 263 270 /** Enable the i/o ports of the device. 264 271 * 265 * @param dev The serial port device. 266 * @return True on success, false otherwise. 267 */ 268 static bool ns8250_pio_enable(device_t *dev) 269 { 270 printf(NAME ": ns8250_pio_enable %s\n", dev->name); 271 272 ns8250_dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data; 272 * @param ns Serial port device 273 * @return True on success, false otherwise 274 */ 275 static bool ns8250_pio_enable(ns8250_t *ns) 276 { 277 printf(NAME ": ns8250_pio_enable %s\n", ns->dev->name); 273 278 274 279 /* Gain control over port's registers. */ 275 if (pio_enable((void *)(uintptr_t) data->io_addr, REG_COUNT,276 (void **) & data->port)) {280 if (pio_enable((void *)(uintptr_t) ns->io_addr, REG_COUNT, 281 (void **) &ns->port)) { 277 282 printf(NAME ": error - cannot gain the port %#" PRIx32 " for device " 278 "%s.\n", data->io_addr,dev->name);283 "%s.\n", ns->io_addr, ns->dev->name); 279 284 return false; 280 285 } … … 285 290 /** Probe the serial port device for its presence. 286 291 * 287 * @param dev The serial port device. 288 * @return True if the device is present, false otherwise. 289 */ 290 static bool ns8250_dev_probe(device_t *dev) 291 { 292 printf(NAME ": ns8250_dev_probe %s\n", dev->name); 293 294 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 295 ioport8_t *port_addr = data->port; 292 * @param ns Serial port device 293 * @return True if the device is present, false otherwise 294 */ 295 static bool ns8250_dev_probe(ns8250_t *ns) 296 { 297 printf(NAME ": ns8250_dev_probe %s\n", ns->dev->name); 298 299 ioport8_t *port_addr = ns->port; 296 300 bool res = true; 297 301 uint8_t olddata; … … 310 314 311 315 if (!res) 312 printf(NAME ": device %s is not present.\n", dev->name);316 printf(NAME ": device %s is not present.\n", ns->dev->name); 313 317 314 318 return res; … … 317 321 /** Initialize serial port device. 318 322 * 319 * @param dev The serial port device.320 * @return Zero on success, negative error number otherwise .321 */ 322 static int ns8250_dev_initialize( device_t *dev)323 { 324 printf(NAME ": ns8250_dev_initialize %s\n", dev->name);323 * @param ns Serial port device 324 * @return Zero on success, negative error number otherwise 325 */ 326 static int ns8250_dev_initialize(ns8250_t *ns) 327 { 328 printf(NAME ": ns8250_dev_initialize %s\n", ns->dev->name); 325 329 326 330 int ret = EOK; … … 329 333 memset(&hw_resources, 0, sizeof(hw_resource_list_t)); 330 334 331 /* Allocate driver data for the device. */332 ns8250_dev_data_t *data = create_ns8250_dev_data();333 if (data == NULL)334 return ENOMEM;335 dev->driver_data = data;336 337 335 /* Connect to the parent's driver. */ 338 dev->parent_phone = devman_parent_device_connect(dev->handle,336 ns->dev->parent_phone = devman_parent_device_connect(ns->dev->handle, 339 337 IPC_FLAG_BLOCKING); 340 if ( dev->parent_phone < 0) {338 if (ns->dev->parent_phone < 0) { 341 339 printf(NAME ": failed to connect to the parent driver of the " 342 "device %s.\n", dev->name);343 ret = dev->parent_phone;340 "device %s.\n", ns->dev->name); 341 ret = ns->dev->parent_phone; 344 342 goto failed; 345 343 } 346 344 347 345 /* Get hw resources. */ 348 ret = hw_res_get_resource_list( dev->parent_phone, &hw_resources);346 ret = hw_res_get_resource_list(ns->dev->parent_phone, &hw_resources); 349 347 if (ret != EOK) { 350 348 printf(NAME ": failed to get hw resources for the device " 351 "%s.\n", dev->name);349 "%s.\n", ns->dev->name); 352 350 goto failed; 353 351 } … … 362 360 switch (res->type) { 363 361 case INTERRUPT: 364 data->irq = res->res.interrupt.irq;362 ns->irq = res->res.interrupt.irq; 365 363 irq = true; 366 364 printf(NAME ": the %s device was asigned irq = 0x%x.\n", 367 dev->name, data->irq);365 ns->dev->name, ns->irq); 368 366 break; 369 367 370 368 case IO_RANGE: 371 data->io_addr = res->res.io_range.address;369 ns->io_addr = res->res.io_range.address; 372 370 if (res->res.io_range.size < REG_COUNT) { 373 371 printf(NAME ": i/o range assigned to the device " 374 "%s is too small.\n", dev->name);372 "%s is too small.\n", ns->dev->name); 375 373 ret = ELIMIT; 376 374 goto failed; … … 378 376 ioport = true; 379 377 printf(NAME ": the %s device was asigned i/o address = " 380 "0x%x.\n", dev->name, data->io_addr);378 "0x%x.\n", ns->dev->name, ns->io_addr); 381 379 break; 382 380 … … 388 386 if (!irq || !ioport) { 389 387 printf(NAME ": missing hw resource(s) for the device %s.\n", 390 dev->name);388 ns->dev->name); 391 389 ret = ENOENT; 392 390 goto failed; … … 397 395 398 396 failed: 399 ns8250_dev_cleanup( dev);397 ns8250_dev_cleanup(ns); 400 398 hw_res_clean_resource_list(&hw_resources); 401 399 return ret; … … 404 402 /** Enable interrupts on the serial port device. 405 403 * 406 * Interrupt when data is received .404 * Interrupt when data is received 407 405 * 408 406 * @param port The base address of the serial port device's ports. 409 407 */ 410 408 static inline void ns8250_port_interrupts_enable(ioport8_t *port) 411 { 409 { 412 410 pio_write_8(port + 1, 0x1); /* Interrupt when data received. */ 413 411 pio_write_8(port + 4, 0xB); … … 416 414 /** Disable interrupts on the serial port device. 417 415 * 418 * @param port The base address of the serial port device's ports .416 * @param port The base address of the serial port device's ports 419 417 */ 420 418 static inline void ns8250_port_interrupts_disable(ioport8_t *port) … … 425 423 /** Enable interrupts for the serial port device. 426 424 * 427 * @param dev The device. 428 * @return Zero on success, negative error number otherwise. 429 */ 430 static int ns8250_interrupt_enable(device_t *dev) 431 { 432 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 433 425 * @param ns Serial port device 426 * @return Zero on success, negative error number otherwise 427 */ 428 static int ns8250_interrupt_enable(ns8250_t *ns) 429 { 434 430 /* Enable interrupt on the serial port. */ 435 ns8250_port_interrupts_enable( data->port);431 ns8250_port_interrupts_enable(ns->port); 436 432 437 433 return EOK; … … 618 614 * Set the default parameters of the serial communication. 619 615 * 620 * @param dev The serial port device. 621 */ 622 static void ns8250_initialize_port(device_t *dev) 623 { 624 ns8250_dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data; 625 ioport8_t *port = data->port; 616 * @param ns Serial port device 617 */ 618 static void ns8250_initialize_port(ns8250_t *ns) 619 { 620 ioport8_t *port = ns->port; 626 621 627 622 /* Disable interrupts. */ … … 643 638 * buffer. 644 639 * 645 * @param dev The serial port device. 646 */ 647 static void ns8250_read_from_device(device_t *dev) 648 { 649 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 650 ioport8_t *port = data->port; 640 * @param ns Serial port device 641 */ 642 static void ns8250_read_from_device(ns8250_t *ns) 643 { 644 ioport8_t *port = ns->port; 651 645 bool cont = true; 652 646 653 647 while (cont) { 654 fibril_mutex_lock(& data->mutex);648 fibril_mutex_lock(&ns->mutex); 655 649 656 650 cont = ns8250_received(port); … … 658 652 uint8_t val = ns8250_read_8(port); 659 653 660 if ( data->client_connected) {661 if (!buf_push_back(& data->input_buffer, val)) {654 if (ns->client_connected) { 655 if (!buf_push_back(&ns->input_buffer, val)) { 662 656 printf(NAME ": buffer overflow on " 663 "%s.\n", dev->name);657 "%s.\n", ns->dev->name); 664 658 } else { 665 659 printf(NAME ": the character %c saved " 666 660 "to the buffer of %s.\n", 667 val, dev->name);661 val, ns->dev->name); 668 662 } 669 663 } 670 664 } 671 665 672 fibril_mutex_unlock(& data->mutex);666 fibril_mutex_unlock(&ns->mutex); 673 667 fibril_yield(); 674 668 } … … 682 676 * @param dev The serial port device. 683 677 */ 684 static inline void ns8250_interrupt_handler(d evice_t *dev, ipc_callid_t iid,678 static inline void ns8250_interrupt_handler(ddf_dev_t *dev, ipc_callid_t iid, 685 679 ipc_call_t *icall) 686 680 { 687 ns8250_read_from_device( dev);681 ns8250_read_from_device(NS8250_FROM_DEV(dev)); 688 682 } 689 683 690 684 /** Register the interrupt handler for the device. 691 685 * 686 * @param ns Serial port device 687 */ 688 static inline int ns8250_register_interrupt_handler(ns8250_t *ns) 689 { 690 return register_interrupt_handler(ns->dev, ns->irq, 691 ns8250_interrupt_handler, NULL); 692 } 693 694 /** Unregister the interrupt handler for the device. 695 * 696 * @param ns Serial port device 697 */ 698 static inline int ns8250_unregister_interrupt_handler(ns8250_t *ns) 699 { 700 return unregister_interrupt_handler(ns->dev, ns->irq); 701 } 702 703 /** The add_device callback method of the serial port driver. 704 * 705 * Probe and initialize the newly added device. 706 * 692 707 * @param dev The serial port device. 693 708 */ 694 static inline int ns8250_register_interrupt_handler(device_t *dev) 695 { 696 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 697 698 return register_interrupt_handler(dev, data->irq, 699 ns8250_interrupt_handler, NULL); 700 } 701 702 /** Unregister the interrupt handler for the device. 703 * 704 * @param dev The serial port device. 705 */ 706 static inline int ns8250_unregister_interrupt_handler(device_t *dev) 707 { 708 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 709 710 return unregister_interrupt_handler(dev, data->irq); 711 } 712 713 /** The add_device callback method of the serial port driver. 714 * 715 * Probe and initialize the newly added device. 716 * 717 * @param dev The serial port device. 718 */ 719 static int ns8250_add_device(device_t *dev) 720 { 709 static int ns8250_add_device(ddf_dev_t *dev) 710 { 711 ns8250_t *ns = NULL; 712 ddf_fun_t *fun = NULL; 713 bool need_cleanup = false; 714 int rc; 715 721 716 printf(NAME ": ns8250_add_device %s (handle = %d)\n", 722 717 dev->name, (int) dev->handle); 723 718 724 int res = ns8250_dev_initialize(dev); 725 if (res != EOK) 726 return res; 727 728 if (!ns8250_pio_enable(dev)) { 729 ns8250_dev_cleanup(dev); 730 return EADDRNOTAVAIL; 719 /* Allocate soft-state for the device */ 720 ns = ns8250_new(); 721 if (ns == NULL) { 722 rc = ENOMEM; 723 goto fail; 724 } 725 726 ns->dev = dev; 727 dev->driver_data = ns; 728 729 rc = ns8250_dev_initialize(ns); 730 if (rc != EOK) 731 goto fail; 732 733 need_cleanup = true; 734 735 if (!ns8250_pio_enable(ns)) { 736 rc = EADDRNOTAVAIL; 737 goto fail; 731 738 } 732 739 733 740 /* Find out whether the device is present. */ 734 if (!ns8250_dev_probe( dev)) {735 ns8250_dev_cleanup(dev);736 return ENOENT;741 if (!ns8250_dev_probe(ns)) { 742 rc = ENOENT; 743 goto fail; 737 744 } 738 745 739 746 /* Serial port initialization (baud rate etc.). */ 740 ns8250_initialize_port( dev);747 ns8250_initialize_port(ns); 741 748 742 749 /* Register interrupt handler. */ 743 if (ns8250_register_interrupt_handler( dev) != EOK) {750 if (ns8250_register_interrupt_handler(ns) != EOK) { 744 751 printf(NAME ": failed to register interrupt handler.\n"); 745 ns8250_dev_cleanup(dev);746 return res;752 rc = EADDRNOTAVAIL; 753 goto fail; 747 754 } 748 755 749 756 /* Enable interrupt. */ 750 r es = ns8250_interrupt_enable(dev);751 if (r es!= EOK) {757 rc = ns8250_interrupt_enable(ns); 758 if (rc != EOK) { 752 759 printf(NAME ": failed to enable the interrupt. Error code = " 753 "%d.\n", res); 754 ns8250_dev_cleanup(dev); 755 ns8250_unregister_interrupt_handler(dev); 756 return res; 760 "%d.\n", rc); 761 goto fail; 762 } 763 764 fun = ddf_fun_create(dev, fun_exposed, "a"); 765 if (fun == NULL) { 766 printf(NAME ": error creating function.\n"); 767 goto fail; 757 768 } 758 769 759 770 /* Set device operations. */ 760 dev->ops = &ns8250_dev_ops; 761 762 add_device_to_class(dev, "serial"); 771 fun->ops = &ns8250_dev_ops; 772 rc = ddf_fun_bind(fun); 773 if (rc != EOK) { 774 printf(NAME ": error binding function.\n"); 775 goto fail; 776 } 777 778 ns->fun = fun; 779 780 ddf_fun_add_to_class(fun, "serial"); 763 781 764 782 printf(NAME ": the %s device has been successfully initialized.\n", … … 766 784 767 785 return EOK; 786 fail: 787 if (fun != NULL) 788 ddf_fun_destroy(fun); 789 if (need_cleanup) 790 ns8250_dev_cleanup(ns); 791 if (ns != NULL) 792 ns8250_delete(ns); 793 return rc; 768 794 } 769 795 … … 775 801 * @param dev The device. 776 802 */ 777 static int ns8250_open(d evice_t *dev)778 { 779 ns8250_ dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data;803 static int ns8250_open(ddf_fun_t *fun) 804 { 805 ns8250_t *data = (ns8250_t *) fun->dev->driver_data; 780 806 int res; 781 807 … … 788 814 } 789 815 fibril_mutex_unlock(&data->mutex); 790 816 791 817 return res; 792 818 } … … 799 825 * @param dev The device. 800 826 */ 801 static void ns8250_close(d evice_t *dev)802 { 803 ns8250_ dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data;827 static void ns8250_close(ddf_fun_t *fun) 828 { 829 ns8250_t *data = (ns8250_t *) fun->dev->driver_data; 804 830 805 831 fibril_mutex_lock(&data->mutex); … … 823 849 */ 824 850 static void 825 ns8250_get_props(d evice_t *dev, unsigned int *baud_rate, unsigned int *parity,851 ns8250_get_props(ddf_dev_t *dev, unsigned int *baud_rate, unsigned int *parity, 826 852 unsigned int *word_length, unsigned int* stop_bits) 827 853 { 828 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;854 ns8250_t *data = (ns8250_t *) dev->driver_data; 829 855 ioport8_t *port = data->port; 830 856 … … 850 876 * @param stop_bits The number of stop bits to be used. 851 877 */ 852 static int ns8250_set_props(d evice_t *dev, unsigned int baud_rate,878 static int ns8250_set_props(ddf_dev_t *dev, unsigned int baud_rate, 853 879 unsigned int parity, unsigned int word_length, unsigned int stop_bits) 854 880 { … … 857 883 stop_bits); 858 884 859 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;885 ns8250_t *data = (ns8250_t *) dev->driver_data; 860 886 ioport8_t *port = data->port; 861 887 int ret; … … 877 903 * Configure the parameters of the serial communication. 878 904 */ 879 static void ns8250_default_handler(d evice_t *dev, ipc_callid_t callid,905 static void ns8250_default_handler(ddf_fun_t *fun, ipc_callid_t callid, 880 906 ipc_call_t *call) 881 907 { … … 886 912 switch (method) { 887 913 case SERIAL_GET_COM_PROPS: 888 ns8250_get_props( dev, &baud_rate, &parity, &word_length,914 ns8250_get_props(fun->dev, &baud_rate, &parity, &word_length, 889 915 &stop_bits); 890 916 async_answer_4(callid, EOK, baud_rate, parity, word_length, … … 897 923 word_length = IPC_GET_ARG3(*call); 898 924 stop_bits = IPC_GET_ARG4(*call); 899 ret = ns8250_set_props( dev, baud_rate, parity, word_length,925 ret = ns8250_set_props(fun->dev, baud_rate, parity, word_length, 900 926 stop_bits); 901 927 async_answer_0(callid, ret); … … 925 951 printf(NAME ": HelenOS serial port driver\n"); 926 952 ns8250_init(); 927 return d river_main(&ns8250_driver);953 return ddf_driver_main(&ns8250_driver); 928 954 } 929 955 -
uspace/drv/pciintel/pci.c
r6a343bdf r0c968a17 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 44 45 #include <ctype.h> 45 46 #include <macros.h> 46 47 #include <driver.h> 47 #include <str_error.h> 48 49 #include <ddf/driver.h> 48 50 #include <devman.h> 49 51 #include <ipc/devman.h> … … 61 63 ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) 62 64 63 static hw_resource_list_t *pciintel_get_child_resources(device_t *dev) 64 { 65 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 66 67 if (dev_data == NULL) 65 /** Obtain PCI function soft-state from DDF function node */ 66 #define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data) 67 68 /** Obtain PCI bus soft-state from DDF device node */ 69 #define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data) 70 71 /** Obtain PCI bus soft-state from function soft-state */ 72 #define PCI_BUS_FROM_FUN(fun) ((fun)->busptr) 73 74 static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode) 75 { 76 pci_fun_t *fun = PCI_FUN(fnode); 77 78 if (fun == NULL) 68 79 return NULL; 69 return & dev_data->hw_resources;70 } 71 72 static bool pciintel_enable_ child_interrupt(device_t *dev)80 return &fun->hw_resources; 81 } 82 83 static bool pciintel_enable_interrupt(ddf_fun_t *fnode) 73 84 { 74 85 /* TODO */ … … 77 88 } 78 89 79 static hw_res_ops_t pciintel_ child_hw_res_ops = {80 &pciintel_get_ child_resources,81 &pciintel_enable_ child_interrupt90 static hw_res_ops_t pciintel_hw_res_ops = { 91 &pciintel_get_resources, 92 &pciintel_enable_interrupt 82 93 }; 83 94 84 static d evice_ops_t pci_child_ops;85 86 static int pci_add_device(d evice_t *);87 88 /** The pci bus driver's standard operations.*/95 static ddf_dev_ops_t pci_fun_ops; 96 97 static int pci_add_device(ddf_dev_t *); 98 99 /** PCI bus driver standard operations */ 89 100 static driver_ops_t pci_ops = { 90 101 .add_device = &pci_add_device 91 102 }; 92 103 93 /** The pci bus driver structure.*/104 /** PCI bus driver structure */ 94 105 static driver_t pci_driver = { 95 106 .name = NAME, … … 97 108 }; 98 109 99 typedef struct pciintel_bus_data { 100 uint32_t conf_io_addr; 101 void *conf_data_port; 102 void *conf_addr_port; 103 fibril_mutex_t conf_mutex; 104 } pci_bus_data_t; 105 106 static pci_bus_data_t *create_pci_bus_data(void) 107 { 108 pci_bus_data_t *bus_data; 109 110 bus_data = (pci_bus_data_t *) malloc(sizeof(pci_bus_data_t)); 111 if (bus_data != NULL) { 112 memset(bus_data, 0, sizeof(pci_bus_data_t)); 113 fibril_mutex_initialize(&bus_data->conf_mutex); 114 } 115 116 return bus_data; 117 } 118 119 static void delete_pci_bus_data(pci_bus_data_t *bus_data) 120 { 121 free(bus_data); 122 } 123 124 static void pci_conf_read(device_t *dev, int reg, uint8_t *buf, size_t len) 125 { 126 assert(dev->parent != NULL); 127 128 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 129 pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data; 130 131 fibril_mutex_lock(&bus_data->conf_mutex); 110 static pci_bus_t *pci_bus_new(void) 111 { 112 pci_bus_t *bus; 113 114 bus = (pci_bus_t *) calloc(1, sizeof(pci_bus_t)); 115 if (bus == NULL) 116 return NULL; 117 118 fibril_mutex_initialize(&bus->conf_mutex); 119 return bus; 120 } 121 122 static void pci_bus_delete(pci_bus_t *bus) 123 { 124 assert(bus != NULL); 125 free(bus); 126 } 127 128 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 129 { 130 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 131 132 fibril_mutex_lock(&bus->conf_mutex); 132 133 133 134 uint32_t conf_addr; 134 conf_addr = CONF_ADDR( dev_data->bus, dev_data->dev, dev_data->fn, reg);135 void *addr = bus _data->conf_data_port + (reg & 3);136 137 pio_write_32(bus _data->conf_addr_port, conf_addr);135 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 136 void *addr = bus->conf_data_port + (reg & 3); 137 138 pio_write_32(bus->conf_addr_port, conf_addr); 138 139 139 140 switch (len) { … … 149 150 } 150 151 151 fibril_mutex_unlock(&bus_data->conf_mutex); 152 } 153 154 static void pci_conf_write(device_t *dev, int reg, uint8_t *buf, size_t len) 155 { 156 assert(dev->parent != NULL); 157 158 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 159 pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data; 160 161 fibril_mutex_lock(&bus_data->conf_mutex); 152 fibril_mutex_unlock(&bus->conf_mutex); 153 } 154 155 static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 156 { 157 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 158 159 fibril_mutex_lock(&bus->conf_mutex); 162 160 163 161 uint32_t conf_addr; 164 conf_addr = CONF_ADDR( dev_data->bus, dev_data->dev, dev_data->fn, reg);165 void *addr = bus _data->conf_data_port + (reg & 3);166 167 pio_write_32(bus _data->conf_addr_port, conf_addr);162 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 163 void *addr = bus->conf_data_port + (reg & 3); 164 165 pio_write_32(bus->conf_addr_port, conf_addr); 168 166 169 167 switch (len) { … … 179 177 } 180 178 181 fibril_mutex_unlock(&bus _data->conf_mutex);182 } 183 184 uint8_t pci_conf_read_8( device_t *dev, int reg)179 fibril_mutex_unlock(&bus->conf_mutex); 180 } 181 182 uint8_t pci_conf_read_8(pci_fun_t *fun, int reg) 185 183 { 186 184 uint8_t res; 187 pci_conf_read( dev, reg, &res, 1);185 pci_conf_read(fun, reg, &res, 1); 188 186 return res; 189 187 } 190 188 191 uint16_t pci_conf_read_16( device_t *dev, int reg)189 uint16_t pci_conf_read_16(pci_fun_t *fun, int reg) 192 190 { 193 191 uint16_t res; 194 pci_conf_read( dev, reg, (uint8_t *) &res, 2);192 pci_conf_read(fun, reg, (uint8_t *) &res, 2); 195 193 return res; 196 194 } 197 195 198 uint32_t pci_conf_read_32( device_t *dev, int reg)196 uint32_t pci_conf_read_32(pci_fun_t *fun, int reg) 199 197 { 200 198 uint32_t res; 201 pci_conf_read( dev, reg, (uint8_t *) &res, 4);199 pci_conf_read(fun, reg, (uint8_t *) &res, 4); 202 200 return res; 203 201 } 204 202 205 void pci_conf_write_8(device_t *dev, int reg, uint8_t val) 206 { 207 pci_conf_write(dev, reg, (uint8_t *) &val, 1); 208 } 209 210 void pci_conf_write_16(device_t *dev, int reg, uint16_t val) 211 { 212 pci_conf_write(dev, reg, (uint8_t *) &val, 2); 213 } 214 215 void pci_conf_write_32(device_t *dev, int reg, uint32_t val) 216 { 217 pci_conf_write(dev, reg, (uint8_t *) &val, 4); 218 } 219 220 void create_pci_match_ids(device_t *dev) 221 { 222 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 223 match_id_t *match_id = NULL; 203 void pci_conf_write_8(pci_fun_t *fun, int reg, uint8_t val) 204 { 205 pci_conf_write(fun, reg, (uint8_t *) &val, 1); 206 } 207 208 void pci_conf_write_16(pci_fun_t *fun, int reg, uint16_t val) 209 { 210 pci_conf_write(fun, reg, (uint8_t *) &val, 2); 211 } 212 213 void pci_conf_write_32(pci_fun_t *fun, int reg, uint32_t val) 214 { 215 pci_conf_write(fun, reg, (uint8_t *) &val, 4); 216 } 217 218 void pci_fun_create_match_ids(pci_fun_t *fun) 219 { 224 220 char *match_id_str; 225 226 match_id = create_match_id(); 227 if (match_id != NULL) { 228 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 229 dev_data->vendor_id, dev_data->device_id); 230 match_id->id = match_id_str; 231 match_id->score = 90; 232 add_match_id(&dev->match_ids, match_id); 233 } 234 221 int rc; 222 223 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 224 fun->vendor_id, fun->device_id); 225 226 if (match_id_str == NULL) { 227 printf(NAME ": out of memory creating match ID.\n"); 228 return; 229 } 230 231 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90); 232 if (rc != EOK) { 233 printf(NAME ": error adding match ID: %s\n", 234 str_error(rc)); 235 } 236 235 237 /* TODO add more ids (with subsys ids, using class id etc.) */ 236 238 } 237 239 238 void 239 pci_add_range(device_t *dev, uint64_t range_addr, size_t range_size, bool io) 240 { 241 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 242 hw_resource_list_t *hw_res_list = &dev_data->hw_resources; 240 void pci_add_range(pci_fun_t *fun, uint64_t range_addr, size_t range_size, 241 bool io) 242 { 243 hw_resource_list_t *hw_res_list = &fun->hw_resources; 243 244 hw_resource_t *hw_resources = hw_res_list->resources; 244 245 size_t count = hw_res_list->count; … … 265 266 * address add it to the devices hw resource list. 266 267 * 267 * @param dev The pci device.268 * @param fun PCI function 268 269 * @param addr The address of the BAR in the PCI configuration address space of 269 * the device .270 * @return The addr the address of the BAR which should be read next .270 * the device 271 * @return The addr the address of the BAR which should be read next 271 272 */ 272 int pci_read_bar( device_t *dev, int addr)273 { 273 int pci_read_bar(pci_fun_t *fun, int addr) 274 { 274 275 /* Value of the BAR */ 275 276 uint32_t val, mask; … … 285 286 286 287 /* Get the value of the BAR. */ 287 val = pci_conf_read_32( dev, addr);288 val = pci_conf_read_32(fun, addr); 288 289 289 290 io = (bool) (val & 1); … … 305 306 306 307 /* Get the address mask. */ 307 pci_conf_write_32( dev, addr, 0xffffffff);308 mask = pci_conf_read_32( dev, addr);308 pci_conf_write_32(fun, addr, 0xffffffff); 309 mask = pci_conf_read_32(fun, addr); 309 310 310 311 /* Restore the original value. */ 311 pci_conf_write_32( dev, addr, val);312 val = pci_conf_read_32( dev, addr);312 pci_conf_write_32(fun, addr, val); 313 val = pci_conf_read_32(fun, addr); 313 314 314 315 range_size = pci_bar_mask_to_size(mask); 315 316 316 317 if (addrw64) { 317 range_addr = ((uint64_t)pci_conf_read_32( dev, addr + 4) << 32) |318 range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) | 318 319 (val & 0xfffffff0); 319 320 } else { … … 322 323 323 324 if (range_addr != 0) { 324 printf(NAME ": device %s : ", dev->name);325 printf(NAME ": function %s : ", fun->fnode->name); 325 326 printf("address = %" PRIx64, range_addr); 326 327 printf(", size = %x\n", (unsigned int) range_size); 327 328 } 328 329 329 pci_add_range( dev, range_addr, range_size, io);330 pci_add_range(fun, range_addr, range_size, io); 330 331 331 332 if (addrw64) … … 335 336 } 336 337 337 void pci_add_interrupt(device_t *dev, int irq) 338 { 339 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 340 hw_resource_list_t *hw_res_list = &dev_data->hw_resources; 338 void pci_add_interrupt(pci_fun_t *fun, int irq) 339 { 340 hw_resource_list_t *hw_res_list = &fun->hw_resources; 341 341 hw_resource_t *hw_resources = hw_res_list->resources; 342 342 size_t count = hw_res_list->count; … … 350 350 hw_res_list->count++; 351 351 352 printf(NAME ": device %s uses irq %x.\n", dev->name, irq);353 } 354 355 void pci_read_interrupt( device_t *dev)356 { 357 uint8_t irq = pci_conf_read_8( dev, PCI_BRIDGE_INT_LINE);352 printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq); 353 } 354 355 void pci_read_interrupt(pci_fun_t *fun) 356 { 357 uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE); 358 358 if (irq != 0xff) 359 pci_add_interrupt( dev, irq);359 pci_add_interrupt(fun, irq); 360 360 } 361 361 362 362 /** Enumerate (recursively) and register the devices connected to a pci bus. 363 363 * 364 * @param parent The host-to-pci bridge device.365 * @param bus_num The bus number.364 * @param bus Host-to-PCI bridge 365 * @param bus_num Bus number 366 366 */ 367 void pci_bus_scan(device_t *parent, int bus_num) 368 { 369 device_t *dev = create_device(); 370 pci_dev_data_t *dev_data = create_pci_dev_data(); 371 dev->driver_data = dev_data; 372 dev->parent = parent; 367 void pci_bus_scan(pci_bus_t *bus, int bus_num) 368 { 369 ddf_fun_t *fnode; 370 pci_fun_t *fun; 373 371 374 372 int child_bus = 0; 375 373 int dnum, fnum; 376 374 bool multi; 377 uint8_t header_type; 375 uint8_t header_type; 376 377 fun = pci_fun_new(bus); 378 378 379 379 for (dnum = 0; dnum < 32; dnum++) { 380 380 multi = true; 381 381 for (fnum = 0; multi && fnum < 8; fnum++) { 382 init_pci_dev_data(dev_data, bus_num, dnum, fnum);383 dev_data->vendor_id = pci_conf_read_16(dev,382 pci_fun_init(fun, bus_num, dnum, fnum); 383 fun->vendor_id = pci_conf_read_16(fun, 384 384 PCI_VENDOR_ID); 385 dev_data->device_id = pci_conf_read_16(dev,385 fun->device_id = pci_conf_read_16(fun, 386 386 PCI_DEVICE_ID); 387 if ( dev_data->vendor_id == 0xffff) {387 if (fun->vendor_id == 0xffff) { 388 388 /* 389 389 * The device is not present, go on scanning the … … 396 396 } 397 397 398 header_type = pci_conf_read_8( dev, PCI_HEADER_TYPE);398 header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE); 399 399 if (fnum == 0) { 400 400 /* Is the device multifunction? */ … … 404 404 header_type = header_type & 0x7F; 405 405 406 create_pci_dev_name(dev); 407 408 pci_alloc_resource_list(dev); 409 pci_read_bars(dev); 410 pci_read_interrupt(dev); 411 412 dev->ops = &pci_child_ops; 413 414 printf(NAME ": adding new child device %s.\n", 415 dev->name); 416 417 create_pci_match_ids(dev); 418 419 if (child_device_register(dev, parent) != EOK) { 420 pci_clean_resource_list(dev); 421 clean_match_ids(&dev->match_ids); 422 free((char *) dev->name); 423 dev->name = NULL; 406 char *fun_name = pci_fun_create_name(fun); 407 if (fun_name == NULL) { 408 printf(NAME ": out of memory.\n"); 409 return; 410 } 411 412 fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name); 413 if (fnode == NULL) { 414 printf(NAME ": error creating function.\n"); 415 return; 416 } 417 418 free(fun_name); 419 fun->fnode = fnode; 420 421 pci_alloc_resource_list(fun); 422 pci_read_bars(fun); 423 pci_read_interrupt(fun); 424 425 fnode->ops = &pci_fun_ops; 426 fnode->driver_data = fun; 427 428 printf(NAME ": adding new function %s.\n", 429 fnode->name); 430 431 pci_fun_create_match_ids(fun); 432 433 if (ddf_fun_bind(fnode) != EOK) { 434 pci_clean_resource_list(fun); 435 clean_match_ids(&fnode->match_ids); 436 free((char *) fnode->name); 437 fnode->name = NULL; 424 438 continue; 425 439 } … … 427 441 if (header_type == PCI_HEADER_TYPE_BRIDGE || 428 442 header_type == PCI_HEADER_TYPE_CARDBUS) { 429 child_bus = pci_conf_read_8( dev,443 child_bus = pci_conf_read_8(fun, 430 444 PCI_BRIDGE_SEC_BUS_NUM); 431 445 printf(NAME ": device is pci-to-pci bridge, " 432 446 "secondary bus number = %d.\n", bus_num); 433 447 if (child_bus > bus_num) 434 pci_bus_scan( parent, child_bus);448 pci_bus_scan(bus, child_bus); 435 449 } 436 450 437 /* Alloc new aux. dev. structure. */ 438 dev = create_device(); 439 dev_data = create_pci_dev_data(); 440 dev->driver_data = dev_data; 441 dev->parent = parent; 451 fun = pci_fun_new(bus); 442 452 } 443 453 } 444 454 445 if (dev_data->vendor_id == 0xffff) { 446 delete_device(dev); 447 /* Free the auxiliary device structure. */ 448 delete_pci_dev_data(dev_data); 449 } 450 } 451 452 static int pci_add_device(device_t *dev) 453 { 455 if (fun->vendor_id == 0xffff) { 456 /* Free the auxiliary function structure. */ 457 pci_fun_delete(fun); 458 } 459 } 460 461 static int pci_add_device(ddf_dev_t *dnode) 462 { 463 pci_bus_t *bus = NULL; 464 ddf_fun_t *ctl = NULL; 465 bool got_res = false; 454 466 int rc; 455 467 456 468 printf(NAME ": pci_add_device\n"); 457 458 pci_bus_data_t *bus_data = create_pci_bus_data(); 459 if (bus_data == NULL) { 469 dnode->parent_phone = -1; 470 471 bus = pci_bus_new(); 472 if (bus == NULL) { 460 473 printf(NAME ": pci_add_device allocation failed.\n"); 461 return ENOMEM; 462 } 463 464 dev->parent_phone = devman_parent_device_connect(dev->handle, 474 rc = ENOMEM; 475 goto fail; 476 } 477 bus->dnode = dnode; 478 dnode->driver_data = bus; 479 480 dnode->parent_phone = devman_parent_device_connect(dnode->handle, 465 481 IPC_FLAG_BLOCKING); 466 if (d ev->parent_phone < 0) {482 if (dnode->parent_phone < 0) { 467 483 printf(NAME ": pci_add_device failed to connect to the " 468 484 "parent's driver.\n"); 469 delete_pci_bus_data(bus_data);470 return dev->parent_phone;485 rc = dnode->parent_phone; 486 goto fail; 471 487 } 472 488 473 489 hw_resource_list_t hw_resources; 474 490 475 rc = hw_res_get_resource_list(d ev->parent_phone, &hw_resources);491 rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources); 476 492 if (rc != EOK) { 477 493 printf(NAME ": pci_add_device failed to get hw resources for " 478 494 "the device.\n"); 479 delete_pci_bus_data(bus_data); 480 async_hangup(dev->parent_phone); 481 return rc; 482 } 495 goto fail; 496 } 497 got_res = true; 483 498 484 499 printf(NAME ": conf_addr = %" PRIx64 ".\n", … … 489 504 assert(hw_resources.resources[0].res.io_range.size == 8); 490 505 491 bus _data->conf_io_addr =506 bus->conf_io_addr = 492 507 (uint32_t) hw_resources.resources[0].res.io_range.address; 493 508 494 if (pio_enable((void *)(uintptr_t)bus _data->conf_io_addr, 8,495 &bus _data->conf_addr_port)) {509 if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8, 510 &bus->conf_addr_port)) { 496 511 printf(NAME ": failed to enable configuration ports.\n"); 497 delete_pci_bus_data(bus_data); 498 async_hangup(dev->parent_phone); 512 rc = EADDRNOTAVAIL; 513 goto fail; 514 } 515 bus->conf_data_port = (char *) bus->conf_addr_port + 4; 516 517 /* Make the bus device more visible. It has no use yet. */ 518 printf(NAME ": adding a 'ctl' function\n"); 519 520 ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl"); 521 if (ctl == NULL) { 522 printf(NAME ": error creating control function.\n"); 523 rc = ENOMEM; 524 goto fail; 525 } 526 527 rc = ddf_fun_bind(ctl); 528 if (rc != EOK) { 529 printf(NAME ": error binding control function.\n"); 530 goto fail; 531 } 532 533 /* Enumerate functions. */ 534 printf(NAME ": scanning the bus\n"); 535 pci_bus_scan(bus, 0); 536 537 hw_res_clean_resource_list(&hw_resources); 538 539 return EOK; 540 541 fail: 542 if (bus != NULL) 543 pci_bus_delete(bus); 544 if (dnode->parent_phone >= 0) 545 async_hangup(dnode->parent_phone); 546 if (got_res) 499 547 hw_res_clean_resource_list(&hw_resources); 500 return EADDRNOTAVAIL; 501 } 502 bus_data->conf_data_port = (char *) bus_data->conf_addr_port + 4; 503 504 dev->driver_data = bus_data; 505 506 /* Enumerate child devices. */ 507 printf(NAME ": scanning the bus\n"); 508 pci_bus_scan(dev, 0); 509 510 hw_res_clean_resource_list(&hw_resources); 511 512 return EOK; 548 if (ctl != NULL) 549 ddf_fun_destroy(ctl); 550 551 return rc; 513 552 } 514 553 515 554 static void pciintel_init(void) 516 555 { 517 pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_hw_res_ops; 518 } 519 520 pci_dev_data_t *create_pci_dev_data(void) 521 { 522 pci_dev_data_t *res = (pci_dev_data_t *) malloc(sizeof(pci_dev_data_t)); 523 524 if (res != NULL) 525 memset(res, 0, sizeof(pci_dev_data_t)); 526 return res; 527 } 528 529 void init_pci_dev_data(pci_dev_data_t *dev_data, int bus, int dev, int fn) 530 { 531 dev_data->bus = bus; 532 dev_data->dev = dev; 533 dev_data->fn = fn; 534 } 535 536 void delete_pci_dev_data(pci_dev_data_t *dev_data) 537 { 538 if (dev_data != NULL) { 539 hw_res_clean_resource_list(&dev_data->hw_resources); 540 free(dev_data); 541 } 542 } 543 544 void create_pci_dev_name(device_t *dev) 545 { 546 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 556 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 557 } 558 559 pci_fun_t *pci_fun_new(pci_bus_t *bus) 560 { 561 pci_fun_t *fun; 562 563 fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t)); 564 if (fun == NULL) 565 return NULL; 566 567 fun->busptr = bus; 568 return fun; 569 } 570 571 void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn) 572 { 573 fun->bus = bus; 574 fun->dev = dev; 575 fun->fn = fn; 576 } 577 578 void pci_fun_delete(pci_fun_t *fun) 579 { 580 assert(fun != NULL); 581 hw_res_clean_resource_list(&fun->hw_resources); 582 free(fun); 583 } 584 585 char *pci_fun_create_name(pci_fun_t *fun) 586 { 547 587 char *name = NULL; 548 588 549 asprintf(&name, "%02x:%02x.%01x", dev_data->bus, dev_data->dev, 550 dev_data->fn); 551 dev->name = name; 552 } 553 554 bool pci_alloc_resource_list(device_t *dev) 555 { 556 pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data; 557 558 dev_data->hw_resources.resources = 589 asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev, 590 fun->fn); 591 return name; 592 } 593 594 bool pci_alloc_resource_list(pci_fun_t *fun) 595 { 596 fun->hw_resources.resources = 559 597 (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t)); 560 return dev_data->hw_resources.resources != NULL; 561 } 562 563 void pci_clean_resource_list(device_t *dev) 564 { 565 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 566 567 if (dev_data->hw_resources.resources != NULL) { 568 free(dev_data->hw_resources.resources); 569 dev_data->hw_resources.resources = NULL; 570 } 571 } 572 573 /** Read the base address registers (BARs) of the device and adds the addresses 574 * to its hw resource list. 598 return fun->hw_resources.resources != NULL; 599 } 600 601 void pci_clean_resource_list(pci_fun_t *fun) 602 { 603 if (fun->hw_resources.resources != NULL) { 604 free(fun->hw_resources.resources); 605 fun->hw_resources.resources = NULL; 606 } 607 } 608 609 /** Read the base address registers (BARs) of the function and add the addresses 610 * to its HW resource list. 575 611 * 576 * @param dev the pci device.612 * @param fun PCI function 577 613 */ 578 void pci_read_bars( device_t *dev)614 void pci_read_bars(pci_fun_t *fun) 579 615 { 580 616 /* … … 585 621 586 622 while (addr <= PCI_BASE_ADDR_5) 587 addr = pci_read_bar( dev, addr);623 addr = pci_read_bar(fun, addr); 588 624 } 589 625 … … 597 633 printf(NAME ": HelenOS pci bus driver (intel method 1).\n"); 598 634 pciintel_init(); 599 return d river_main(&pci_driver);635 return ddf_driver_main(&pci_driver); 600 636 } 601 637 -
uspace/drv/pciintel/pci.h
r6a343bdf r0c968a17 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 36 37 #define PCI_H_ 37 38 38 #include <stdlib.h> 39 #include <driver.h> 40 #include <malloc.h> 41 39 #include <ddf/driver.h> 42 40 #include "pci_regs.h" 43 41 44 42 #define PCI_MAX_HW_RES 8 45 43 46 typedef struct pci_dev_data { 44 typedef struct pciintel_bus { 45 /** DDF device node */ 46 ddf_dev_t *dnode; 47 uint32_t conf_io_addr; 48 void *conf_data_port; 49 void *conf_addr_port; 50 fibril_mutex_t conf_mutex; 51 } pci_bus_t; 52 53 typedef struct pci_fun_data { 54 pci_bus_t *busptr; 55 ddf_fun_t *fnode; 56 47 57 int bus; 48 58 int dev; … … 51 61 int device_id; 52 62 hw_resource_list_t hw_resources; 53 } pci_ dev_data_t;63 } pci_fun_t; 54 64 55 extern void create_pci_match_ids(device_t *);65 extern void pci_fun_create_match_ids(pci_fun_t *); 56 66 57 extern uint8_t pci_conf_read_8( device_t *, int);58 extern uint16_t pci_conf_read_16( device_t *, int);59 extern uint32_t pci_conf_read_32( device_t *, int);60 extern void pci_conf_write_8( device_t *, int, uint8_t);61 extern void pci_conf_write_16( device_t *, int, uint16_t);62 extern void pci_conf_write_32( device_t *, int, uint32_t);67 extern uint8_t pci_conf_read_8(pci_fun_t *, int); 68 extern uint16_t pci_conf_read_16(pci_fun_t *, int); 69 extern uint32_t pci_conf_read_32(pci_fun_t *, int); 70 extern void pci_conf_write_8(pci_fun_t *, int, uint8_t); 71 extern void pci_conf_write_16(pci_fun_t *, int, uint16_t); 72 extern void pci_conf_write_32(pci_fun_t *, int, uint32_t); 63 73 64 extern void pci_add_range( device_t *, uint64_t, size_t, bool);65 extern int pci_read_bar( device_t *, int);66 extern void pci_read_interrupt( device_t *);67 extern void pci_add_interrupt( device_t *, int);74 extern void pci_add_range(pci_fun_t *, uint64_t, size_t, bool); 75 extern int pci_read_bar(pci_fun_t *, int); 76 extern void pci_read_interrupt(pci_fun_t *); 77 extern void pci_add_interrupt(pci_fun_t *, int); 68 78 69 extern void pci_bus_scan(device_t *, int); 79 extern pci_fun_t *pci_fun_new(pci_bus_t *); 80 extern void pci_fun_init(pci_fun_t *, int, int, int); 81 extern void pci_fun_delete(pci_fun_t *); 82 extern char *pci_fun_create_name(pci_fun_t *); 70 83 71 extern pci_dev_data_t *create_pci_dev_data(void); 72 extern void init_pci_dev_data(pci_dev_data_t *, int, int, int); 73 extern void delete_pci_dev_data(pci_dev_data_t *); 74 extern void create_pci_dev_name(device_t *); 84 extern void pci_bus_scan(pci_bus_t *, int); 75 85 76 extern bool pci_alloc_resource_list( device_t *);77 extern void pci_clean_resource_list( device_t *);86 extern bool pci_alloc_resource_list(pci_fun_t *); 87 extern void pci_clean_resource_list(pci_fun_t *); 78 88 79 extern void pci_read_bars( device_t *);89 extern void pci_read_bars(pci_fun_t *); 80 90 extern size_t pci_bar_mask_to_size(uint32_t); 81 91 -
uspace/drv/root/root.c
r6a343bdf r0c968a17 2 2 * Copyright (c) 2010 Lenka Trochtova 3 3 * Copyright (c) 2010 Vojtech Horky 4 * Copyright (c) 2011 Jiri Svoboda 4 5 * All rights reserved. 5 6 * … … 44 45 #include <stdlib.h> 45 46 #include <str.h> 47 #include <str_error.h> 46 48 #include <ctype.h> 47 49 #include <macros.h> … … 49 51 #include <sysinfo.h> 50 52 51 #include <d river.h>53 #include <ddf/driver.h> 52 54 #include <devman.h> 53 55 #include <ipc/devman.h> … … 55 57 #define NAME "root" 56 58 57 #define PLATFORM_ DEVICE_NAME "hw"58 #define PLATFORM_ DEVICE_MATCH_ID_FMT "platform/%s"59 #define PLATFORM_ DEVICE_MATCH_SCORE 10060 61 #define VIRTUAL_ DEVICE_NAME "virt"62 #define VIRTUAL_ DEVICE_MATCH_ID "rootvirt"63 #define VIRTUAL_ DEVICE_MATCH_SCORE 10064 65 static int root_add_device(d evice_t *dev);59 #define PLATFORM_FUN_NAME "hw" 60 #define PLATFORM_FUN_MATCH_ID_FMT "platform/%s" 61 #define PLATFORM_FUN_MATCH_SCORE 100 62 63 #define VIRTUAL_FUN_NAME "virt" 64 #define VIRTUAL_FUN_MATCH_ID "rootvirt" 65 #define VIRTUAL_FUN_MATCH_SCORE 100 66 67 static int root_add_device(ddf_dev_t *dev); 66 68 67 69 /** The root device driver's standard operations. */ … … 76 78 }; 77 79 78 /** Create the device which represents the root of virtual device tree. 79 * 80 * @param parent Parent of the newly created device. 81 * @return Error code. 82 */ 83 static int add_virtual_root_child(device_t *parent) 84 { 85 printf(NAME ": adding new child for virtual devices.\n"); 86 printf(NAME ": device node is `%s' (%d %s)\n", VIRTUAL_DEVICE_NAME, 87 VIRTUAL_DEVICE_MATCH_SCORE, VIRTUAL_DEVICE_MATCH_ID); 88 89 int res = child_device_register_wrapper(parent, VIRTUAL_DEVICE_NAME, 90 VIRTUAL_DEVICE_MATCH_ID, VIRTUAL_DEVICE_MATCH_SCORE); 91 92 return res; 93 } 94 95 /** Create the device which represents the root of HW device tree. 96 * 97 * @param parent Parent of the newly created device. 98 * @return 0 on success, negative error number otherwise. 99 */ 100 static int add_platform_child(device_t *parent) 80 /** Create the function which represents the root of virtual device tree. 81 * 82 * @param dev Device 83 * @return EOK on success or negative error code 84 */ 85 static int add_virtual_root_fun(ddf_dev_t *dev) 86 { 87 const char *name = VIRTUAL_FUN_NAME; 88 ddf_fun_t *fun; 89 int rc; 90 91 printf(NAME ": adding new function for virtual devices.\n"); 92 printf(NAME ": function node is `%s' (%d %s)\n", name, 93 VIRTUAL_FUN_MATCH_SCORE, VIRTUAL_FUN_MATCH_ID); 94 95 fun = ddf_fun_create(dev, fun_inner, name); 96 if (fun == NULL) { 97 printf(NAME ": error creating function %s\n", name); 98 return ENOMEM; 99 } 100 101 rc = ddf_fun_add_match_id(fun, VIRTUAL_FUN_MATCH_ID, 102 VIRTUAL_FUN_MATCH_SCORE); 103 if (rc != EOK) { 104 printf(NAME ": error adding match IDs to function %s\n", name); 105 ddf_fun_destroy(fun); 106 return rc; 107 } 108 109 rc = ddf_fun_bind(fun); 110 if (rc != EOK) { 111 printf(NAME ": error binding function %s: %s\n", name, 112 str_error(rc)); 113 ddf_fun_destroy(fun); 114 return rc; 115 } 116 117 return EOK; 118 } 119 120 /** Create the function which represents the root of HW device tree. 121 * 122 * @param dev Device 123 * @return EOK on success or negative error code 124 */ 125 static int add_platform_fun(ddf_dev_t *dev) 101 126 { 102 127 char *match_id; 103 128 char *platform; 104 129 size_t platform_size; 105 int res; 130 131 const char *name = PLATFORM_FUN_NAME; 132 ddf_fun_t *fun; 133 int rc; 106 134 107 135 /* Get platform name from sysinfo. */ 108 109 136 platform = sysinfo_get_data("platform", &platform_size); 110 137 if (platform == NULL) { … … 123 150 124 151 /* Construct match ID. */ 125 126 if (asprintf(&match_id, PLATFORM_DEVICE_MATCH_ID_FMT, platform) == -1) { 152 if (asprintf(&match_id, PLATFORM_FUN_MATCH_ID_FMT, platform) == -1) { 127 153 printf(NAME ": Memory allocation failed.\n"); 128 154 return ENOMEM; 129 155 } 130 156 131 /* Add child. */ 132 133 printf(NAME ": adding new child for platform device.\n"); 134 printf(NAME ": device node is `%s' (%d %s)\n", PLATFORM_DEVICE_NAME, 135 PLATFORM_DEVICE_MATCH_SCORE, match_id); 136 137 res = child_device_register_wrapper(parent, PLATFORM_DEVICE_NAME, 138 match_id, PLATFORM_DEVICE_MATCH_SCORE); 139 140 return res; 157 /* Add function. */ 158 printf(NAME ": adding platform function\n"); 159 printf(NAME ": function node is `%s' (%d %s)\n", PLATFORM_FUN_NAME, 160 PLATFORM_FUN_MATCH_SCORE, match_id); 161 162 fun = ddf_fun_create(dev, fun_inner, name); 163 if (fun == NULL) { 164 printf(NAME ": error creating function %s\n", name); 165 return ENOMEM; 166 } 167 168 rc = ddf_fun_add_match_id(fun, match_id, PLATFORM_FUN_MATCH_SCORE); 169 if (rc != EOK) { 170 printf(NAME ": error adding match IDs to function %s\n", name); 171 ddf_fun_destroy(fun); 172 return rc; 173 } 174 175 rc = ddf_fun_bind(fun); 176 if (rc != EOK) { 177 printf(NAME ": error binding function %s: %s\n", name, 178 str_error(rc)); 179 ddf_fun_destroy(fun); 180 return rc; 181 } 182 183 return EOK; 141 184 } 142 185 … … 146 189 * of HW and pseudo devices). 147 190 */ 148 static int root_add_device(d evice_t *dev)191 static int root_add_device(ddf_dev_t *dev) 149 192 { 150 193 printf(NAME ": root_add_device, device handle=%" PRIun "\n", 151 194 dev->handle); 152 195 153 196 /* 154 197 * Register virtual devices root. … … 156 199 * vital for the system. 157 200 */ 158 add_virtual_root_ child(dev);201 add_virtual_root_fun(dev); 159 202 160 203 /* Register root device's children. */ 161 int res = add_platform_ child(dev);204 int res = add_platform_fun(dev); 162 205 if (EOK != res) 163 206 printf(NAME ": failed to add child device for platform.\n"); 164 207 165 208 return res; 166 209 } … … 169 212 { 170 213 printf(NAME ": HelenOS root device driver\n"); 171 return d river_main(&root_driver);214 return ddf_driver_main(&root_driver); 172 215 } 173 216 -
uspace/drv/rootpc/rootpc.c
r6a343bdf r0c968a17 46 46 #include <macros.h> 47 47 48 #include <d river.h>48 #include <ddf/driver.h> 49 49 #include <devman.h> 50 50 #include <ipc/devman.h> … … 55 55 #define NAME "rootpc" 56 56 57 typedef struct rootpc_child_dev_data { 57 /** Obtain function soft-state from DDF function node */ 58 #define ROOTPC_FUN(fnode) ((rootpc_fun_t *) (fnode)->driver_data) 59 60 typedef struct rootpc_fun { 58 61 hw_resource_list_t hw_resources; 59 } rootpc_ child_dev_data_t;60 61 static int rootpc_add_device(d evice_t *dev);62 } rootpc_fun_t; 63 64 static int rootpc_add_device(ddf_dev_t *dev); 62 65 static void root_pc_init(void); 63 66 … … 82 85 }; 83 86 84 static rootpc_ child_dev_data_t pci_data = {87 static rootpc_fun_t pci_data = { 85 88 .hw_resources = { 86 89 1, … … 89 92 }; 90 93 91 static hw_resource_list_t *rootpc_get_child_resources(device_t *dev) 92 { 93 rootpc_child_dev_data_t *data; 94 95 data = (rootpc_child_dev_data_t *) dev->driver_data; 96 if (NULL == data) 97 return NULL; 98 99 return &data->hw_resources; 100 } 101 102 static bool rootpc_enable_child_interrupt(device_t *dev) 94 static hw_resource_list_t *rootpc_get_resources(ddf_fun_t *fnode) 95 { 96 rootpc_fun_t *fun = ROOTPC_FUN(fnode); 97 98 assert(fun != NULL); 99 return &fun->hw_resources; 100 } 101 102 static bool rootpc_enable_interrupt(ddf_fun_t *fun) 103 103 { 104 104 /* TODO */ … … 107 107 } 108 108 109 static hw_res_ops_t child_hw_res_ops = {110 &rootpc_get_ child_resources,111 &rootpc_enable_ child_interrupt109 static hw_res_ops_t fun_hw_res_ops = { 110 &rootpc_get_resources, 111 &rootpc_enable_interrupt 112 112 }; 113 113 114 114 /* Initialized in root_pc_init() function. */ 115 static d evice_ops_t rootpc_child_ops;115 static ddf_dev_ops_t rootpc_fun_ops; 116 116 117 117 static bool 118 rootpc_add_ child(device_t *parent, const char *name, const char *str_match_id,119 rootpc_ child_dev_data_t *drv_data)120 { 121 printf(NAME ": adding new child device'%s'.\n", name);122 123 d evice_t *child= NULL;118 rootpc_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id, 119 rootpc_fun_t *fun) 120 { 121 printf(NAME ": adding new function '%s'.\n", name); 122 123 ddf_fun_t *fnode = NULL; 124 124 match_id_t *match_id = NULL; 125 125 126 126 /* Create new device. */ 127 child = create_device();128 if ( NULL == child)127 fnode = ddf_fun_create(dev, fun_inner, name); 128 if (fnode == NULL) 129 129 goto failure; 130 130 131 child->name = name; 132 child->driver_data = drv_data; 131 fnode->driver_data = fun; 133 132 134 133 /* Initialize match id list */ 135 134 match_id = create_match_id(); 136 if ( NULL == match_id)135 if (match_id == NULL) 137 136 goto failure; 138 137 139 138 match_id->id = str_match_id; 140 139 match_id->score = 100; 141 add_match_id(& child->match_ids, match_id);140 add_match_id(&fnode->match_ids, match_id); 142 141 143 142 /* Set provided operations to the device. */ 144 child->ops = &rootpc_child_ops; 145 146 /* Register child device. */ 147 if (EOK != child_device_register(child, parent)) 143 fnode->ops = &rootpc_fun_ops; 144 145 /* Register function. */ 146 if (ddf_fun_bind(fnode) != EOK) { 147 printf(NAME ": error binding function %s.\n", name); 148 148 goto failure; 149 } 149 150 150 151 return true; 151 152 152 153 failure: 153 if ( NULL != match_id)154 if (match_id != NULL) 154 155 match_id->id = NULL; 155 156 156 if (NULL != child) { 157 child->name = NULL; 158 delete_device(child); 159 } 160 161 printf(NAME ": failed to add child device '%s'.\n", name); 157 if (fnode != NULL) 158 ddf_fun_destroy(fnode); 159 160 printf(NAME ": failed to add function '%s'.\n", name); 162 161 163 162 return false; 164 163 } 165 164 166 static bool rootpc_add_ children(device_t *dev)167 { 168 return rootpc_add_ child(dev, "pci0", "intel_pci", &pci_data);165 static bool rootpc_add_functions(ddf_dev_t *dev) 166 { 167 return rootpc_add_fun(dev, "pci0", "intel_pci", &pci_data); 169 168 } 170 169 … … 175 174 * @return Zero on success, negative error number otherwise. 176 175 */ 177 static int rootpc_add_device(d evice_t *dev)176 static int rootpc_add_device(ddf_dev_t *dev) 178 177 { 179 178 printf(NAME ": rootpc_add_device, device handle = %d\n", 180 179 (int)dev->handle); 181 180 182 /* Register child devices. */183 if (!rootpc_add_ children(dev)) {184 printf(NAME ": failed to add child devices for PC platform.\n");181 /* Register functions. */ 182 if (!rootpc_add_functions(dev)) { 183 printf(NAME ": failed to add functions for PC platform.\n"); 185 184 } 186 185 … … 190 189 static void root_pc_init(void) 191 190 { 192 rootpc_ child_ops.interfaces[HW_RES_DEV_IFACE] = &child_hw_res_ops;191 rootpc_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops; 193 192 } 194 193 … … 197 196 printf(NAME ": HelenOS PC platform driver\n"); 198 197 root_pc_init(); 199 return d river_main(&rootpc_driver);198 return ddf_driver_main(&rootpc_driver); 200 199 } 201 200 -
uspace/drv/rootvirt/rootvirt.c
r6a343bdf r0c968a17 39 39 #include <errno.h> 40 40 #include <str_error.h> 41 #include <d river.h>41 #include <ddf/driver.h> 42 42 43 43 #define NAME "rootvirt" 44 44 45 /** Virtual device entry.*/45 /** Virtual function entry */ 46 46 typedef struct { 47 /** Device name.*/47 /** Function name */ 48 48 const char *name; 49 /** Device match id.*/49 /** Function match ID */ 50 50 const char *match_id; 51 } virtual_ device_t;51 } virtual_function_t; 52 52 53 /** List of existing virtual devices.*/54 virtual_ device_t virtual_devices[] = {53 /** List of existing virtual functions */ 54 virtual_function_t virtual_functions[] = { 55 55 #include "devices.def" 56 /* Terminating item .*/56 /* Terminating item */ 57 57 { 58 58 .name = NULL, … … 61 61 }; 62 62 63 static int add_device(device_t *dev);63 static int rootvirt_add_device(ddf_dev_t *dev); 64 64 65 65 static driver_ops_t rootvirt_ops = { 66 .add_device = & add_device66 .add_device = &rootvirt_add_device 67 67 }; 68 68 … … 72 72 }; 73 73 74 /** Add childdevice.74 /** Add function to the virtual device. 75 75 * 76 * @param parent Parent device.77 * @param v irt_dev Virtual device to add.78 * @return Error code.76 * @param vdev The virtual device 77 * @param vfun Virtual function description 78 * @return EOK on success or negative error code. 79 79 */ 80 static int add_child(device_t *parent, virtual_device_t *virt_dev)80 static int rootvirt_add_fun(ddf_dev_t *vdev, virtual_function_t *vfun) 81 81 { 82 printf(NAME ": registering child device `%s' (match \"%s\")\n",83 virt_dev->name, virt_dev->match_id);82 ddf_fun_t *fun; 83 int rc; 84 84 85 int rc = child_device_register_wrapper(parent, virt_dev->name,86 v irt_dev->match_id, 10);85 printf(NAME ": registering function `%s' (match \"%s\")\n", 86 vfun->name, vfun->match_id); 87 87 88 if (rc == EOK) { 89 printf(NAME ": registered child device `%s'\n", 90 virt_dev->name); 91 } else { 92 printf(NAME ": failed to register child device `%s': %s\n", 93 virt_dev->name, str_error(rc)); 88 fun = ddf_fun_create(vdev, fun_inner, vfun->name); 89 if (fun == NULL) { 90 printf(NAME ": error creating function %s\n", vfun->name); 91 return ENOMEM; 94 92 } 95 93 96 return rc; 94 rc = ddf_fun_add_match_id(fun, vfun->match_id, 10); 95 if (rc != EOK) { 96 printf(NAME ": error adding match IDs to function %s\n", 97 vfun->name); 98 ddf_fun_destroy(fun); 99 return rc; 100 } 101 102 rc = ddf_fun_bind(fun); 103 if (rc != EOK) { 104 printf(NAME ": error binding function %s: %s\n", vfun->name, 105 str_error(rc)); 106 ddf_fun_destroy(fun); 107 return rc; 108 } 109 110 printf(NAME ": registered child device `%s'\n", vfun->name); 111 return EOK; 97 112 } 98 113 99 static int add_device(device_t *dev)114 static int rootvirt_add_device(ddf_dev_t *dev) 100 115 { 101 116 static int instances = 0; … … 109 124 } 110 125 111 printf(NAME ": add_device(name=\"%s\", handle=%d)\n", 112 dev->name, (int)dev->handle); 113 126 printf(NAME ": add_device(handle=%d)\n", (int)dev->handle); 127 114 128 /* 115 * Go through all virtual devices and try to add them.129 * Go through all virtual functions and try to add them. 116 130 * We silently ignore failures. 117 131 */ 118 virtual_ device_t *virt_dev = virtual_devices;119 while (v irt_dev->name != NULL) {120 (void) add_child(dev, virt_dev);121 v irt_dev++;132 virtual_function_t *vfun = virtual_functions; 133 while (vfun->name != NULL) { 134 (void) rootvirt_add_fun(dev, vfun); 135 vfun++; 122 136 } 123 137 … … 128 142 { 129 143 printf(NAME ": HelenOS virtual devices root driver\n"); 130 return d river_main(&rootvirt_driver);144 return ddf_driver_main(&rootvirt_driver); 131 145 } 132 146 -
uspace/drv/test1/char.c
r6a343bdf r0c968a17 37 37 #include "test1.h" 38 38 39 static int impl_char_read(d evice_t *dev, char *buf, size_t count) {39 static int impl_char_read(ddf_fun_t *fun, char *buf, size_t count) { 40 40 memset(buf, 0, count); 41 41 return count; 42 42 } 43 43 44 static int imp_char_write(d evice_t *dev, char *buf, size_t count) {44 static int imp_char_write(ddf_fun_t *fun, char *buf, size_t count) { 45 45 return count; 46 46 } … … 51 51 }; 52 52 53 d evice_ops_t char_device_ops = {53 ddf_dev_ops_t char_device_ops = { 54 54 .interfaces[CHAR_DEV_IFACE] = &char_dev_ops 55 55 }; -
uspace/drv/test1/test1.c
r6a343bdf r0c968a17 34 34 #include <errno.h> 35 35 #include <str_error.h> 36 #include <ddf/driver.h> 37 36 38 #include "test1.h" 37 39 38 static int add_device(device_t *dev);40 static int test1_add_device(ddf_dev_t *dev); 39 41 40 42 static driver_ops_t driver_ops = { 41 .add_device = & add_device43 .add_device = &test1_add_device 42 44 }; 43 45 44 static driver_t t he_driver = {46 static driver_t test1_driver = { 45 47 .name = NAME, 46 48 .driver_ops = &driver_ops … … 55 57 * @param score Device match score. 56 58 */ 57 static void register_child_verbose(device_t *parent, const char *message,59 static int register_fun_verbose(ddf_dev_t *parent, const char *message, 58 60 const char *name, const char *match_id, int match_score) 59 61 { 60 printf(NAME ": registering child device `%s': %s.\n",61 name, message);62 ddf_fun_t *fun; 63 int rc; 62 64 63 int rc = child_device_register_wrapper(parent, name, 64 match_id, match_score); 65 printf(NAME ": registering function `%s': %s.\n", name, message); 65 66 66 if (rc == EOK) { 67 printf(NAME ": registered child device `%s'.\n", name); 68 } else { 69 printf(NAME ": failed to register child `%s' (%s).\n", 70 name, str_error(rc)); 67 fun = ddf_fun_create(parent, fun_inner, name); 68 if (fun == NULL) { 69 printf(NAME ": error creating function %s\n", name); 70 return ENOMEM; 71 71 } 72 73 rc = ddf_fun_add_match_id(fun, match_id, match_score); 74 if (rc != EOK) { 75 printf(NAME ": error adding match IDs to function %s\n", name); 76 ddf_fun_destroy(fun); 77 return rc; 78 } 79 80 rc = ddf_fun_bind(fun); 81 if (rc != EOK) { 82 printf(NAME ": error binding function %s: %s\n", name, 83 str_error(rc)); 84 ddf_fun_destroy(fun); 85 return rc; 86 } 87 88 printf(NAME ": registered child device `%s'\n", name); 89 return EOK; 72 90 } 73 91 … … 89 107 * @return Error code reporting success of the operation. 90 108 */ 91 static int add_device(device_t *dev)109 static int test1_add_device(ddf_dev_t *dev) 92 110 { 111 ddf_fun_t *fun_a; 112 int rc; 113 93 114 printf(NAME ": add_device(name=\"%s\", handle=%d)\n", 94 115 dev->name, (int) dev->handle); 95 116 96 add_device_to_class(dev, "virtual"); 117 fun_a = ddf_fun_create(dev, fun_exposed, "a"); 118 if (fun_a == NULL) { 119 printf(NAME ": error creating function 'a'.\n"); 120 return ENOMEM; 121 } 122 123 rc = ddf_fun_bind(fun_a); 124 if (rc != EOK) { 125 printf(NAME ": error binding function 'a'.\n"); 126 return rc; 127 } 128 129 ddf_fun_add_to_class(fun_a, "virtual"); 97 130 98 131 if (str_cmp(dev->name, "null") == 0) { 99 dev->ops = &char_device_ops;100 add_device_to_class(dev, "virt-null");101 } else if ( dev->parent == NULL) {102 register_child_verbose(dev, "cloning myself ;-)", "clone",132 fun_a->ops = &char_device_ops; 133 ddf_fun_add_to_class(fun_a, "virt-null"); 134 } else if (str_cmp(dev->name, "test1") == 0) { 135 (void) register_fun_verbose(dev, "cloning myself ;-)", "clone", 103 136 "virtual&test1", 10); 104 137 } else if (str_cmp(dev->name, "clone") == 0) { 105 register_child_verbose(dev, "run by the same task", "child",138 (void) register_fun_verbose(dev, "run by the same task", "child", 106 139 "virtual&test1&child", 10); 107 140 } … … 115 148 { 116 149 printf(NAME ": HelenOS test1 virtual device driver\n"); 117 return d river_main(&the_driver);150 return ddf_driver_main(&test1_driver); 118 151 } 119 152 -
uspace/drv/test1/test1.h
r6a343bdf r0c968a17 32 32 #define DRV_TEST1_TEST1_H_ 33 33 34 #include <d river.h>34 #include <ddf/driver.h> 35 35 36 36 #define NAME "test1" 37 37 38 extern d evice_ops_t char_device_ops;38 extern ddf_dev_ops_t char_device_ops; 39 39 40 40 #endif -
uspace/drv/test2/test2.c
r6a343bdf r0c968a17 31 31 32 32 #include <assert.h> 33 #include <async.h> 33 34 #include <stdio.h> 34 35 #include <errno.h> 35 36 #include <str_error.h> 36 #include <d river.h>37 #include <ddf/driver.h> 37 38 38 39 #define NAME "test2" 39 40 40 static int add_device(device_t *dev);41 static int test2_add_device(ddf_dev_t *dev); 41 42 42 43 static driver_ops_t driver_ops = { 43 .add_device = & add_device44 .add_device = &test2_add_device 44 45 }; 45 46 46 static driver_t t he_driver = {47 static driver_t test2_driver = { 47 48 .name = NAME, 48 49 .driver_ops = &driver_ops … … 57 58 * @param score Device match score. 58 59 */ 59 static void register_child_verbose(device_t *parent, const char *message,60 static int register_fun_verbose(ddf_dev_t *parent, const char *message, 60 61 const char *name, const char *match_id, int match_score) 61 62 { 62 printf(NAME ": registering child device `%s': %s.\n",63 name, message);63 ddf_fun_t *fun; 64 int rc; 64 65 65 int rc = child_device_register_wrapper(parent, name, 66 match_id, match_score); 66 printf(NAME ": registering function `%s': %s.\n", name, message); 67 67 68 if (rc == EOK) { 69 printf(NAME ": registered child device `%s'.\n", name); 70 } else { 71 printf(NAME ": failed to register child `%s' (%s).\n", 72 name, str_error(rc)); 68 fun = ddf_fun_create(parent, fun_inner, name); 69 if (fun == NULL) { 70 printf(NAME ": error creating function %s\n", name); 71 return ENOMEM; 73 72 } 73 74 rc = ddf_fun_add_match_id(fun, match_id, match_score); 75 if (rc != EOK) { 76 printf(NAME ": error adding match IDs to function %s\n", name); 77 ddf_fun_destroy(fun); 78 return rc; 79 } 80 81 rc = ddf_fun_bind(fun); 82 if (rc != EOK) { 83 printf(NAME ": error binding function %s: %s\n", name, 84 str_error(rc)); 85 ddf_fun_destroy(fun); 86 return rc; 87 } 88 89 printf(NAME ": registered child device `%s'\n", name); 90 return EOK; 74 91 } 75 92 76 93 /** Add child devices after some sleep. 77 94 * 78 * @param arg Parent device structure (d evice_t *).95 * @param arg Parent device structure (ddf_dev_t *). 79 96 * @return Always EOK. 80 97 */ 81 98 static int postponed_birth(void *arg) 82 99 { 83 device_t *dev = (device_t *) arg; 100 ddf_dev_t *dev = (ddf_dev_t *) arg; 101 ddf_fun_t *fun_a; 102 int rc; 84 103 85 104 async_usleep(1000); 86 105 87 register_child_verbose(dev, "child driven by the same task",106 (void) register_fun_verbose(dev, "child driven by the same task", 88 107 "child", "virtual&test2", 10); 89 register_child_verbose(dev, "child driven by test1",108 (void) register_fun_verbose(dev, "child driven by test1", 90 109 "test1", "virtual&test1", 10); 91 110 92 add_device_to_class(dev, "virtual"); 111 fun_a = ddf_fun_create(dev, fun_exposed, "a"); 112 if (fun_a == NULL) { 113 printf(NAME ": error creating function 'a'.\n"); 114 return ENOMEM; 115 } 116 117 rc = ddf_fun_bind(fun_a); 118 if (rc != EOK) { 119 printf(NAME ": error binding function 'a'.\n"); 120 return rc; 121 } 122 123 ddf_fun_add_to_class(fun_a, "virtual"); 93 124 94 125 return EOK; 95 126 } 96 127 97 98 static int add_device(device_t *dev) 128 static int test2_add_device(ddf_dev_t *dev) 99 129 { 100 printf(NAME ": add_device(name=\"%s\", handle=%d)\n",130 printf(NAME ": test2_add_device(name=\"%s\", handle=%d)\n", 101 131 dev->name, (int) dev->handle); 102 132 103 if ( dev->parent == NULL) {133 if (str_cmp(dev->name, "child") != 0) { 104 134 fid_t postpone = fibril_create(postponed_birth, dev); 105 135 if (postpone == 0) { … … 109 139 fibril_add_ready(postpone); 110 140 } else { 111 register_child_verbose(dev, "child without available driver",141 (void) register_fun_verbose(dev, "child without available driver", 112 142 "ERROR", "non-existent.match.id", 10); 113 143 } … … 119 149 { 120 150 printf(NAME ": HelenOS test2 virtual device driver\n"); 121 return d river_main(&the_driver);151 return ddf_driver_main(&test2_driver); 122 152 } 123 153 -
uspace/lib/c/generic/devman.c
r6a343bdf r0c968a17 123 123 } 124 124 125 static int devman_send_match_id(int phone, match_id_t *match_id) \ 126 { 127 ipc_call_t answer; 128 aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer); 129 int retval = async_data_write_start(phone, match_id->id, str_size(match_id->id)); 125 static int devman_send_match_id(int phone, match_id_t *match_id) 126 { 127 ipc_call_t answer; 128 129 aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, 130 &answer); 131 int retval = async_data_write_start(phone, match_id->id, 132 str_size(match_id->id)); 133 130 134 async_wait_for(req, NULL); 131 135 return retval; … … 133 137 134 138 135 static int devman_send_match_ids(int phone, match_id_list_t *match_ids) 139 static int devman_send_match_ids(int phone, match_id_list_t *match_ids) 136 140 { 137 141 link_t *link = match_ids->ids.next; 138 142 match_id_t *match_id = NULL; 139 143 int ret = EOK; 140 144 141 145 while (link != &match_ids->ids) { 142 146 match_id = list_get_instance(link, match_id_t, link); 143 if (EOK != (ret = devman_send_match_id(phone, match_id))) 144 { 145 printf("Driver failed to send match id, error number = %d\n", ret); 146 return ret; 147 } 147 ret = devman_send_match_id(phone, match_id); 148 if (ret != EOK) { 149 printf("Driver failed to send match id, error %d\n", 150 ret); 151 return ret; 152 } 153 148 154 link = link->next; 149 155 } 150 return ret; 151 } 152 153 int devman_child_device_register( 154 const char *name, match_id_list_t *match_ids, devman_handle_t parent_handle, devman_handle_t *handle) 155 { 156 157 return ret; 158 } 159 160 /** Add function to a device. 161 * 162 * Request devman to add a new function to the specified device owned by 163 * this driver task. 164 * 165 * @param name Name of the new function 166 * @param ftype Function type, fun_inner or fun_exposed 167 * @param match_ids Match IDs (should be empty for fun_exposed) 168 * @param devh Devman handle of the device 169 * @param funh Place to store handle of the new function 170 * 171 * @return EOK on success or negative error code. 172 */ 173 int devman_add_function(const char *name, fun_type_t ftype, 174 match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh) 175 { 156 176 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING); 177 int fun_handle; 157 178 158 179 if (phone < 0) … … 161 182 async_serialize_start(); 162 183 163 int match_count = list_count(&match_ids->ids); 164 ipc_call_t answer; 165 aid_t req = async_send_2(phone, DEVMAN_ADD_CHILD_DEVICE, parent_handle, match_count, &answer); 184 int match_count = list_count(&match_ids->ids); 185 ipc_call_t answer; 186 187 aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype, 188 devh, match_count, &answer); 166 189 167 190 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); … … 178 201 async_serialize_end(); 179 202 180 if (retval != EOK) { 181 if (handle != NULL) { 182 *handle = -1; 183 } 184 return retval; 185 } 186 187 if (handle != NULL) 188 *handle = (int) IPC_GET_ARG1(answer); 189 190 return retval; 191 } 192 193 int devman_add_device_to_class(devman_handle_t devman_handle, const char *class_name) 203 if (retval == EOK) 204 fun_handle = (int) IPC_GET_ARG1(answer); 205 else 206 fun_handle = -1; 207 208 *funh = fun_handle; 209 210 return retval; 211 } 212 213 int devman_add_device_to_class(devman_handle_t devman_handle, 214 const char *class_name) 194 215 { 195 216 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING); … … 200 221 async_serialize_start(); 201 222 ipc_call_t answer; 202 aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS, devman_handle, &answer); 203 204 sysarg_t retval = async_data_write_start(phone, class_name, str_size(class_name)); 223 aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS, 224 devman_handle, &answer); 225 226 sysarg_t retval = async_data_write_start(phone, class_name, 227 str_size(class_name)); 205 228 if (retval != EOK) { 206 229 async_wait_for(req, NULL); … … 212 235 async_serialize_end(); 213 236 214 return retval; 237 return retval; 215 238 } 216 239 … … 265 288 } 266 289 267 int devman_device_get_handle(const char *pathname, devman_handle_t *handle, unsigned int flags) 290 int devman_device_get_handle(const char *pathname, devman_handle_t *handle, 291 unsigned int flags) 268 292 { 269 293 int phone = devman_get_phone(DEVMAN_CLIENT, flags); … … 278 302 &answer); 279 303 280 sysarg_t retval = async_data_write_start(phone, pathname, str_size(pathname)); 304 sysarg_t retval = async_data_write_start(phone, pathname, 305 str_size(pathname)); 281 306 if (retval != EOK) { 282 307 async_wait_for(req, NULL); -
uspace/lib/c/include/devman.h
r6a343bdf r0c968a17 45 45 46 46 extern int devman_driver_register(const char *, async_client_conn_t); 47 extern int devman_ child_device_register(const char *, match_id_list_t *,47 extern int devman_add_function(const char *, fun_type_t, match_id_list_t *, 48 48 devman_handle_t, devman_handle_t *); 49 49 -
uspace/lib/c/include/ipc/devman.h
r6a343bdf r0c968a17 42 42 43 43 typedef sysarg_t devman_handle_t; 44 45 typedef enum { 46 /** Invalid value for debugging purposes */ 47 fun_invalid = 0, 48 /** Function to which child devices attach */ 49 fun_inner, 50 /** Fuction exported to external clients (leaf function) */ 51 fun_exposed 52 } fun_type_t; 44 53 45 54 /** Ids of device models used for device-to-driver matching. … … 127 136 typedef enum { 128 137 DEVMAN_DRIVER_REGISTER = IPC_FIRST_USER_METHOD, 129 DEVMAN_ADD_ CHILD_DEVICE,138 DEVMAN_ADD_FUNCTION, 130 139 DEVMAN_ADD_MATCH_ID, 131 140 DEVMAN_ADD_DEVICE_TO_CLASS -
uspace/lib/drv/generic/driver.c
r6a343bdf r0c968a17 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 49 50 #include <errno.h> 50 51 #include <inttypes.h> 52 #include <devman.h> 51 53 52 54 #include <ipc/driver.h> 53 55 54 56 #include "dev_iface.h" 55 #include "driver.h" 57 #include "ddf/driver.h" 58 #include "ddf/interrupt.h" 56 59 57 60 /** Driver structure */ … … 59 62 60 63 /** Devices */ 61 LIST_INITIALIZE( devices);62 FIBRIL_MUTEX_INITIALIZE( devices_mutex);64 LIST_INITIALIZE(functions); 65 FIBRIL_MUTEX_INITIALIZE(functions_mutex); 63 66 64 67 /** Interrupts */ … … 76 79 }; 77 80 81 static ddf_dev_t *create_device(void); 82 static void delete_device(ddf_dev_t *); 83 static remote_handler_t *function_get_default_handler(ddf_fun_t *); 84 static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t); 78 85 79 86 static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall) … … 150 157 151 158 interrupt_context_t * 152 find_interrupt_context(interrupt_context_list_t *list, d evice_t *dev, int irq)159 find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq) 153 160 { 154 161 fibril_mutex_lock(&list->mutex); … … 172 179 173 180 int 174 register_interrupt_handler(d evice_t *dev, int irq, interrupt_handler_t *handler,181 register_interrupt_handler(ddf_dev_t *dev, int irq, interrupt_handler_t *handler, 175 182 irq_code_t *pseudocode) 176 183 { … … 195 202 } 196 203 197 int unregister_interrupt_handler(d evice_t *dev, int irq)204 int unregister_interrupt_handler(ddf_dev_t *dev, int irq) 198 205 { 199 206 interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts, … … 209 216 } 210 217 211 static void add_to_ devices_list(device_t *dev)212 { 213 fibril_mutex_lock(& devices_mutex);214 list_append(& dev->link, &devices);215 fibril_mutex_unlock(& devices_mutex);216 } 217 218 static void remove_from_ devices_list(device_t *dev)219 { 220 fibril_mutex_lock(& devices_mutex);221 list_remove(& dev->link);222 fibril_mutex_unlock(& devices_mutex);223 } 224 225 static d evice_t *driver_get_device(link_t *devices, devman_handle_t handle)226 { 227 d evice_t *dev= NULL;228 229 fibril_mutex_lock(& devices_mutex);230 link_t *link = devices->next;231 232 while (link != devices) {233 dev = list_get_instance(link, device_t, link);234 if ( dev->handle == handle) {235 fibril_mutex_unlock(& devices_mutex);236 return dev;218 static void add_to_functions_list(ddf_fun_t *fun) 219 { 220 fibril_mutex_lock(&functions_mutex); 221 list_append(&fun->link, &functions); 222 fibril_mutex_unlock(&functions_mutex); 223 } 224 225 static void remove_from_functions_list(ddf_fun_t *fun) 226 { 227 fibril_mutex_lock(&functions_mutex); 228 list_remove(&fun->link); 229 fibril_mutex_unlock(&functions_mutex); 230 } 231 232 static ddf_fun_t *driver_get_function(link_t *functions, devman_handle_t handle) 233 { 234 ddf_fun_t *fun = NULL; 235 236 fibril_mutex_lock(&functions_mutex); 237 link_t *link = functions->next; 238 239 while (link != functions) { 240 fun = list_get_instance(link, ddf_fun_t, link); 241 if (fun->handle == handle) { 242 fibril_mutex_unlock(&functions_mutex); 243 return fun; 237 244 } 245 238 246 link = link->next; 239 247 } 240 248 241 fibril_mutex_unlock(& devices_mutex);249 fibril_mutex_unlock(&functions_mutex); 242 250 243 251 return NULL; … … 250 258 251 259 devman_handle_t dev_handle = IPC_GET_ARG1(*icall); 252 devman_handle_t parent_ dev_handle = IPC_GET_ARG2(*icall);253 254 d evice_t *dev = create_device();260 devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall); 261 262 ddf_dev_t *dev = create_device(); 255 263 dev->handle = dev_handle; 256 264 257 265 async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0); 258 266 dev->name = dev_name; 259 260 add_to_devices_list(dev); 261 dev->parent = driver_get_device(&devices, parent_dev_handle); 267 268 /* 269 * Currently not used, parent fun handle is stored in context 270 * of the connection to the parent device driver. 271 */ 272 (void) parent_fun_handle; 262 273 263 274 res = driver->driver_ops->add_device(dev); … … 268 279 printf("%s: failed to add a new device with handle = %" PRIun ".\n", 269 280 driver->name, dev_handle); 270 remove_from_devices_list(dev);271 281 delete_device(dev); 272 282 } … … 311 321 */ 312 322 devman_handle_t handle = IPC_GET_ARG2(*icall); 313 d evice_t *dev = driver_get_device(&devices, handle);314 315 if ( dev== NULL) {316 printf("%s: driver_connection_gen error - no devicewith handle"323 ddf_fun_t *fun = driver_get_function(&functions, handle); 324 325 if (fun == NULL) { 326 printf("%s: driver_connection_gen error - no function with handle" 317 327 " %" PRIun " was found.\n", driver->name, handle); 318 328 async_answer_0(iid, ENOENT); … … 327 337 328 338 int ret = EOK; 329 /* open the device*/330 if ( dev->ops != NULL && dev->ops->open != NULL)331 ret = (* dev->ops->open)(dev);339 /* Open device function */ 340 if (fun->ops != NULL && fun->ops->open != NULL) 341 ret = (*fun->ops->open)(fun); 332 342 333 343 async_answer_0(iid, ret); … … 344 354 switch (method) { 345 355 case IPC_M_PHONE_HUNGUP: 346 /* close the device*/347 if ( dev->ops != NULL && dev->ops->close != NULL)348 (* dev->ops->close)(dev);356 /* Close device function */ 357 if (fun->ops != NULL && fun->ops->close != NULL) 358 (*fun->ops->close)(fun); 349 359 async_answer_0(callid, EOK); 350 360 return; … … 356 366 if (!is_valid_iface_idx(iface_idx)) { 357 367 remote_handler_t *default_handler = 358 device_get_default_handler(dev);368 function_get_default_handler(fun); 359 369 if (default_handler != NULL) { 360 (*default_handler)( dev, callid, &call);370 (*default_handler)(fun, callid, &call); 361 371 break; 362 372 } 373 363 374 /* 364 * This is not device's interface and the375 * Function has no such interface and 365 376 * default handler is not provided. 366 377 */ … … 372 383 } 373 384 374 /* calling one of the device's interfaces */385 /* calling one of the function's interfaces */ 375 386 376 387 /* Get the interface ops structure. */ 377 void *ops = device_get_ops(dev, iface_idx);388 void *ops = function_get_ops(fun, iface_idx); 378 389 if (ops == NULL) { 379 390 printf("%s: driver_connection_gen error - ", 380 391 driver->name); 381 printf(" devicewith handle %" PRIun " has no interface "392 printf("Function with handle %" PRIun " has no interface " 382 393 "with id %d.\n", handle, iface_idx); 383 394 async_answer_0(callid, ENOTSUP); … … 408 419 * receive parameters from the remote client and it will 409 420 * pass it to the corresponding local interface method 410 * associated with the deviceby its driver.421 * associated with the function by its driver. 411 422 */ 412 (*iface_method_ptr)( dev, ops, callid, &call);423 (*iface_method_ptr)(fun, ops, callid, &call); 413 424 break; 414 425 } … … 425 436 driver_connection_gen(iid, icall, false); 426 437 } 427 428 438 429 439 /** Function for handling connections to device driver. */ … … 454 464 * @return The device structure. 455 465 */ 456 device_t *create_device(void)457 { 458 d evice_t *dev = malloc(sizeof(device_t));459 460 if (dev != NULL) {461 memset(dev, 0, sizeof(device_t));462 init_match_ids(&dev->match_ids);463 } 464 466 static ddf_dev_t *create_device(void) 467 { 468 ddf_dev_t *dev; 469 470 dev = malloc(sizeof(ddf_dev_t)); 471 if (dev == NULL) 472 return NULL; 473 474 memset(dev, 0, sizeof(ddf_dev_t)); 465 475 return dev; 466 476 } 467 477 478 /** Create new function structure. 479 * 480 * @return The device structure. 481 */ 482 static ddf_fun_t *create_function(void) 483 { 484 ddf_fun_t *fun; 485 486 fun = calloc(1, sizeof(ddf_fun_t)); 487 if (fun == NULL) 488 return NULL; 489 490 init_match_ids(&fun->match_ids); 491 link_initialize(&fun->link); 492 493 return fun; 494 } 495 468 496 /** Delete device structure. 469 497 * 470 498 * @param dev The device structure. 471 499 */ 472 void delete_device(device_t *dev) 473 { 474 clean_match_ids(&dev->match_ids); 475 if (dev->name != NULL) 476 free(dev->name); 500 static void delete_device(ddf_dev_t *dev) 501 { 477 502 free(dev); 478 503 } 479 504 480 void *device_get_ops(device_t *dev, dev_inferface_idx_t idx) 505 /** Delete device structure. 506 * 507 * @param dev The device structure. 508 */ 509 static void delete_function(ddf_fun_t *fun) 510 { 511 clean_match_ids(&fun->match_ids); 512 if (fun->name != NULL) 513 free(fun->name); 514 free(fun); 515 } 516 517 /** Create a DDF function node. 518 * 519 * Create a DDF function (in memory). Both child devices and external clients 520 * communicate with a device via its functions. 521 * 522 * The created function node is fully formed, but only exists in the memory 523 * of the client task. In order to be visible to the system, the function 524 * must be bound using ddf_fun_bind(). 525 * 526 * This function should only fail if there is not enough free memory. 527 * Specifically, this function succeeds even if @a dev already has 528 * a (bound) function with the same name. 529 * 530 * Type: A function of type fun_inner indicates that DDF should attempt 531 * to attach child devices to the function. fun_exposed means that 532 * the function should be exported to external clients (applications). 533 * 534 * @param dev Device to which we are adding function 535 * @param ftype Type of function (fun_inner or fun_exposed) 536 * @param name Name of function 537 * 538 * @return New function or @c NULL if memory is not available 539 */ 540 ddf_fun_t *ddf_fun_create(ddf_dev_t *dev, fun_type_t ftype, const char *name) 541 { 542 ddf_fun_t *fun; 543 544 fun = create_function(); 545 if (fun == NULL) 546 return NULL; 547 548 fun->bound = false; 549 fun->dev = dev; 550 fun->ftype = ftype; 551 552 fun->name = str_dup(name); 553 if (fun->name == NULL) { 554 delete_function(fun); 555 return NULL; 556 } 557 558 return fun; 559 } 560 561 /** Destroy DDF function node. 562 * 563 * Destroy a function previously created with ddf_fun_create(). The function 564 * must not be bound. 565 * 566 * @param fun Function to destroy 567 */ 568 void ddf_fun_destroy(ddf_fun_t *fun) 569 { 570 assert(fun->bound == false); 571 delete_function(fun); 572 } 573 574 static void *function_get_ops(ddf_fun_t *fun, dev_inferface_idx_t idx) 481 575 { 482 576 assert(is_valid_iface_idx(idx)); 483 if ( dev->ops == NULL)577 if (fun->ops == NULL) 484 578 return NULL; 485 return dev->ops->interfaces[idx]; 486 } 487 488 int child_device_register(device_t *child, device_t *parent) 489 { 490 assert(child->name != NULL); 579 return fun->ops->interfaces[idx]; 580 } 581 582 /** Bind a function node. 583 * 584 * Bind the specified function to the system. This effectively makes 585 * the function visible to the system (uploads it to the server). 586 * 587 * This function can fail for several reasons. Specifically, 588 * it will fail if the device already has a bound function of 589 * the same name. 590 * 591 * @param fun Function to bind 592 * @return EOK on success or negative error code 593 */ 594 int ddf_fun_bind(ddf_fun_t *fun) 595 { 596 assert(fun->name != NULL); 491 597 492 598 int res; 493 599 494 add_to_ devices_list(child);495 res = devman_ child_device_register(child->name, &child->match_ids,496 parent->handle, &child->handle);600 add_to_functions_list(fun); 601 res = devman_add_function(fun->name, fun->ftype, &fun->match_ids, 602 fun->dev->handle, &fun->handle); 497 603 if (res != EOK) { 498 remove_from_ devices_list(child);604 remove_from_functions_list(fun); 499 605 return res; 500 606 } 501 607 608 fun->bound = true; 502 609 return res; 503 610 } 504 611 505 /** Wrapper for child_device_register for devices with single match id. 506 * 507 * @param parent Parent device. 508 * @param child_name Child device name. 509 * @param child_match_id Child device match id. 510 * @param child_match_score Child device match score. 511 * @return Error code. 512 */ 513 int child_device_register_wrapper(device_t *parent, const char *child_name, 514 const char *child_match_id, int child_match_score) 515 { 516 device_t *child = NULL; 517 match_id_t *match_id = NULL; 518 int rc; 519 520 child = create_device(); 521 if (child == NULL) { 522 rc = ENOMEM; 523 goto failure; 524 } 525 526 child->name = child_name; 612 /** Add single match ID to inner function. 613 * 614 * Construct and add a single match ID to the specified function. 615 * Cannot be called when the function node is bound. 616 * 617 * @param fun Function 618 * @param match_id_str Match string 619 * @param match_score Match score 620 * @return EOK on success, ENOMEM if out of memory. 621 */ 622 int ddf_fun_add_match_id(ddf_fun_t *fun, const char *match_id_str, 623 int match_score) 624 { 625 match_id_t *match_id; 626 627 assert(fun->bound == false); 628 assert(fun->ftype == fun_inner); 527 629 528 630 match_id = create_match_id(); 529 if (match_id == NULL) { 530 rc = ENOMEM; 531 goto failure; 532 } 533 534 match_id->id = child_match_id; 535 match_id->score = child_match_score; 536 add_match_id(&child->match_ids, match_id); 537 538 rc = child_device_register(child, parent); 539 if (rc != EOK) 540 goto failure; 541 631 if (match_id == NULL) 632 return ENOMEM; 633 634 match_id->id = match_id_str; 635 match_id->score = 90; 636 637 add_match_id(&fun->match_ids, match_id); 542 638 return EOK; 543 544 failure:545 if (match_id != NULL) {546 match_id->id = NULL;547 delete_match_id(match_id);548 }549 550 if (child != NULL) {551 child->name = NULL;552 delete_device(child);553 }554 555 return rc;556 639 } 557 640 558 641 /** Get default handler for client requests */ 559 remote_handler_t *device_get_default_handler(device_t *dev)560 { 561 if ( dev->ops == NULL)642 static remote_handler_t *function_get_default_handler(ddf_fun_t *fun) 643 { 644 if (fun->ops == NULL) 562 645 return NULL; 563 return dev->ops->default_handler; 564 } 565 566 int add_device_to_class(device_t *dev, const char *class_name) 567 { 568 return devman_add_device_to_class(dev->handle, class_name); 569 } 570 571 int driver_main(driver_t *drv) 646 return fun->ops->default_handler; 647 } 648 649 /** Add exposed function to class. 650 * 651 * Must only be called when the function is bound. 652 */ 653 int ddf_fun_add_to_class(ddf_fun_t *fun, const char *class_name) 654 { 655 assert(fun->bound == true); 656 assert(fun->ftype == fun_exposed); 657 658 return devman_add_device_to_class(fun->handle, class_name); 659 } 660 661 int ddf_driver_main(driver_t *drv) 572 662 { 573 663 /* -
uspace/lib/drv/generic/remote_char_dev.c
r6a343bdf r0c968a17 37 37 38 38 #include "ops/char_dev.h" 39 #include "d river.h"39 #include "ddf/driver.h" 40 40 41 41 #define MAX_CHAR_RW_COUNT 256 42 42 43 static void remote_char_read(d evice_t *, void *, ipc_callid_t, ipc_call_t *);44 static void remote_char_write(d evice_t *, void *, ipc_callid_t, ipc_call_t *);43 static void remote_char_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 44 static void remote_char_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 45 45 46 46 /** Remote character interface operations. */ … … 67 67 * local interface to the remote client. 68 68 * 69 * @param dev The devicefrom which the data are read.69 * @param fun The function from which the data are read. 70 70 * @param ops The local ops structure. 71 71 */ 72 72 static void 73 remote_char_read(d evice_t *dev, void *ops, ipc_callid_t callid,73 remote_char_read(ddf_fun_t *fun, void *ops, ipc_callid_t callid, 74 74 ipc_call_t *call) 75 75 { … … 94 94 95 95 char buf[MAX_CHAR_RW_COUNT]; 96 int ret = (*char_dev_ops->read)( dev, buf, len);96 int ret = (*char_dev_ops->read)(fun, buf, len); 97 97 98 98 if (ret < 0) { … … 114 114 * local interface to the remote client. 115 115 * 116 * @param dev The deviceto which the data are written.116 * @param fun The function to which the data are written. 117 117 * @param ops The local ops structure. 118 118 */ 119 119 static void 120 remote_char_write(d evice_t *dev, void *ops, ipc_callid_t callid,120 remote_char_write(ddf_fun_t *fun, void *ops, ipc_callid_t callid, 121 121 ipc_call_t *call) 122 122 { … … 144 144 async_data_write_finalize(cid, buf, len); 145 145 146 int ret = (*char_dev_ops->write)( dev, buf, len);146 int ret = (*char_dev_ops->write)(fun, buf, len); 147 147 if (ret < 0) { 148 148 /* Some error occured. */ -
uspace/lib/drv/generic/remote_hw_res.c
r6a343bdf r0c968a17 37 37 38 38 #include "ops/hw_res.h" 39 #include "d river.h"39 #include "ddf/driver.h" 40 40 41 static void remote_hw_res_get_resource_list(d evice_t *, void *, ipc_callid_t,41 static void remote_hw_res_get_resource_list(ddf_fun_t *, void *, ipc_callid_t, 42 42 ipc_call_t *); 43 static void remote_hw_res_enable_interrupt(d evice_t *, void *, ipc_callid_t,43 static void remote_hw_res_enable_interrupt(ddf_fun_t *, void *, ipc_callid_t, 44 44 ipc_call_t *); 45 45 … … 55 55 }; 56 56 57 static void remote_hw_res_enable_interrupt(d evice_t *dev, void *ops,57 static void remote_hw_res_enable_interrupt(ddf_fun_t *fun, void *ops, 58 58 ipc_callid_t callid, ipc_call_t *call) 59 59 { … … 62 62 if (hw_res_ops->enable_interrupt == NULL) 63 63 async_answer_0(callid, ENOTSUP); 64 else if (hw_res_ops->enable_interrupt( dev))64 else if (hw_res_ops->enable_interrupt(fun)) 65 65 async_answer_0(callid, EOK); 66 66 else … … 68 68 } 69 69 70 static void remote_hw_res_get_resource_list(d evice_t *dev, void *ops,70 static void remote_hw_res_get_resource_list(ddf_fun_t *fun, void *ops, 71 71 ipc_callid_t callid, ipc_call_t *call) 72 72 { … … 78 78 } 79 79 80 hw_resource_list_t *hw_resources = hw_res_ops->get_resource_list( dev);80 hw_resource_list_t *hw_resources = hw_res_ops->get_resource_list(fun); 81 81 if (hw_resources == NULL){ 82 82 async_answer_0(callid, ENOENT); -
uspace/lib/drv/include/ddf/driver.h
r6a343bdf r0c968a17 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 33 34 */ 34 35 35 #ifndef LIBDRV_DRIVER_H_36 #define LIBDRV_DRIVER_H_36 #ifndef DDF_DRIVER_H_ 37 #define DDF_DRIVER_H_ 37 38 38 #include <kernel/ddi/irq.h>39 #include <adt/list.h>40 #include <devman.h>41 39 #include <ipc/devman.h> 42 40 #include <ipc/dev_iface.h> 43 #include <assert.h>44 #include <ddi.h>45 #include <libarch/ddi.h>46 #include <fibril_synch.h>47 #include <malloc.h>48 41 49 #include " dev_iface.h"42 #include "../dev_iface.h" 50 43 51 struct device;52 typedef struct d evice device_t;44 typedef struct ddf_dev ddf_dev_t; 45 typedef struct ddf_fun ddf_fun_t; 53 46 54 47 /* 55 * Device class48 * Device 56 49 */ 57 50 58 51 /** Devices operations */ 59 typedef struct d evice_ops {52 typedef struct ddf_dev_ops { 60 53 /** 61 54 * Optional callback function called when a client is connecting to the 62 55 * device. 63 56 */ 64 int (*open)(d evice_t *);57 int (*open)(ddf_fun_t *); 65 58 66 59 /** … … 68 61 * the device. 69 62 */ 70 void (*close)(d evice_t *);63 void (*close)(ddf_fun_t *); 71 64 72 65 /** The table of standard interfaces implemented by the device. */ … … 79 72 */ 80 73 remote_handler_t *default_handler; 81 } device_ops_t; 82 83 84 /* 85 * Device 86 */ 74 } ddf_dev_ops_t; 87 75 88 76 /** Device structure */ 89 struct d evice{77 struct ddf_dev { 90 78 /** 91 79 * Globally unique device identifier (assigned to the device by the … … 100 88 int parent_phone; 101 89 102 /** Parent device if handled by this driver, NULL otherwise */103 device_t *parent;104 90 /** Device name */ 105 91 const char *name; 106 /** List of device ids for device-to-driver matching */ 107 match_id_list_t match_ids; 92 108 93 /** Driver-specific data associated with this device */ 109 94 void *driver_data; 110 /** The implementation of operations provided by this device */111 device_ops_t *ops;112 95 113 96 /** Link in the list of devices handled by the driver */ 97 link_t link; 98 }; 99 100 /** Function structure */ 101 struct ddf_fun { 102 /** True if bound to the device manager */ 103 bool bound; 104 /** Function indentifier (asigned by device manager) */ 105 devman_handle_t handle; 106 107 /** Device which this function belogs to */ 108 ddf_dev_t *dev; 109 110 /** Function type */ 111 fun_type_t ftype; 112 /** Function name */ 113 const char *name; 114 /** List of device ids for driver matching */ 115 match_id_list_t match_ids; 116 /** Driver-specific data associated with this function */ 117 void *driver_data; 118 /** Implementation of operations provided by this function */ 119 ddf_dev_ops_t *ops; 120 121 /** Link in the list of functions handled by the driver */ 114 122 link_t link; 115 123 }; … … 122 130 typedef struct driver_ops { 123 131 /** Callback method for passing a new device to the device driver */ 124 int (*add_device)(d evice_t *dev);132 int (*add_device)(ddf_dev_t *dev); 125 133 /* TODO: add other generic driver operations */ 126 134 } driver_ops_t; … … 134 142 } driver_t; 135 143 136 intdriver_main(driver_t *);144 extern int ddf_driver_main(driver_t *); 137 145 138 /** Create new device structure. 139 * 140 * @return The device structure. 141 */ 142 extern device_t *create_device(void); 143 extern void delete_device(device_t *); 144 extern void *device_get_ops(device_t *, dev_inferface_idx_t); 146 extern ddf_fun_t *ddf_fun_create(ddf_dev_t *, fun_type_t, const char *); 147 extern void ddf_fun_destroy(ddf_fun_t *); 148 extern int ddf_fun_bind(ddf_fun_t *); 149 extern int ddf_fun_add_match_id(ddf_fun_t *, const char *, int); 145 150 146 extern int child_device_register(device_t *, device_t *); 147 extern int child_device_register_wrapper(device_t *, const char *, const char *, 148 int); 149 150 /* 151 * Interrupts 152 */ 153 154 typedef void interrupt_handler_t(device_t *, ipc_callid_t, ipc_call_t *); 155 156 typedef struct interrupt_context { 157 int id; 158 device_t *dev; 159 int irq; 160 interrupt_handler_t *handler; 161 link_t link; 162 } interrupt_context_t; 163 164 typedef struct interrupt_context_list { 165 int curr_id; 166 link_t contexts; 167 fibril_mutex_t mutex; 168 } interrupt_context_list_t; 169 170 extern interrupt_context_t *create_interrupt_context(void); 171 extern void delete_interrupt_context(interrupt_context_t *); 172 extern void init_interrupt_context_list(interrupt_context_list_t *); 173 extern void add_interrupt_context(interrupt_context_list_t *, 174 interrupt_context_t *); 175 extern void remove_interrupt_context(interrupt_context_list_t *, 176 interrupt_context_t *); 177 extern interrupt_context_t *find_interrupt_context_by_id( 178 interrupt_context_list_t *, int); 179 extern interrupt_context_t *find_interrupt_context( 180 interrupt_context_list_t *, device_t *, int); 181 182 extern int register_interrupt_handler(device_t *, int, interrupt_handler_t *, 183 irq_code_t *); 184 extern int unregister_interrupt_handler(device_t *, int); 185 186 extern remote_handler_t *device_get_default_handler(device_t *); 187 extern int add_device_to_class(device_t *, const char *); 151 extern int ddf_fun_add_to_class(ddf_fun_t *, const char *); 188 152 189 153 #endif -
uspace/lib/drv/include/dev_iface.h
r6a343bdf r0c968a17 43 43 */ 44 44 45 struct d evice;45 struct ddf_fun; 46 46 47 47 /* … … 49 49 * devices driver. 50 50 */ 51 typedef void remote_iface_func_t(struct d evice*, void *, ipc_callid_t,51 typedef void remote_iface_func_t(struct ddf_fun *, void *, ipc_callid_t, 52 52 ipc_call_t *); 53 53 typedef remote_iface_func_t *remote_iface_func_ptr_t; 54 typedef void remote_handler_t(struct d evice*, ipc_callid_t, ipc_call_t *);54 typedef void remote_handler_t(struct ddf_fun *, ipc_callid_t, ipc_call_t *); 55 55 56 56 typedef struct { -
uspace/lib/drv/include/ops/char_dev.h
r6a343bdf r0c968a17 36 36 #define LIBDRV_OPS_CHAR_DEV_H_ 37 37 38 #include "../d river.h"38 #include "../ddf/driver.h" 39 39 40 40 typedef struct { 41 int (*read)(d evice_t *, char *, size_t);42 int (*write)(d evice_t *, char *, size_t);41 int (*read)(ddf_fun_t *, char *, size_t); 42 int (*write)(ddf_fun_t *, char *, size_t); 43 43 } char_dev_ops_t; 44 44 -
uspace/lib/drv/include/ops/hw_res.h
r6a343bdf r0c968a17 39 39 #include <sys/types.h> 40 40 41 #include "../d river.h"41 #include "../ddf/driver.h" 42 42 43 43 typedef struct { 44 hw_resource_list_t *(*get_resource_list)(d evice_t *);45 bool (*enable_interrupt)(d evice_t *);44 hw_resource_list_t *(*get_resource_list)(ddf_fun_t *); 45 bool (*enable_interrupt)(ddf_fun_t *); 46 46 } hw_res_ops_t; 47 47 -
uspace/srv/devman/devman.c
r6a343bdf r0c968a17 41 41 #include "devman.h" 42 42 43 fun_node_t *find_node_child(fun_node_t *parent, const char *name); 44 43 45 /* hash table operations */ 44 46 … … 51 53 link_t *item) 52 54 { 53 node_t *dev = hash_table_get_instance(item, node_t, devman_link);55 dev_node_t *dev = hash_table_get_instance(item, dev_node_t, devman_dev); 54 56 return (dev->handle == (devman_handle_t) key[0]); 55 57 } 56 58 57 static int devma p_devices_compare(unsigned long key[], hash_count_t keys,59 static int devman_functions_compare(unsigned long key[], hash_count_t keys, 58 60 link_t *item) 59 61 { 60 node_t *dev = hash_table_get_instance(item, node_t, devmap_link); 61 return (dev->devmap_handle == (devmap_handle_t) key[0]); 62 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, devman_fun); 63 return (fun->handle == (devman_handle_t) key[0]); 64 } 65 66 static int devmap_functions_compare(unsigned long key[], hash_count_t keys, 67 link_t *item) 68 { 69 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, devmap_fun); 70 return (fun->devmap_handle == (devmap_handle_t) key[0]); 62 71 } 63 72 … … 82 91 }; 83 92 93 static hash_table_operations_t devman_functions_ops = { 94 .hash = devices_hash, 95 .compare = devman_functions_compare, 96 .remove_callback = devices_remove_callback 97 }; 98 84 99 static hash_table_operations_t devmap_devices_ops = { 85 100 .hash = devices_hash, 86 .compare = devmap_ devices_compare,101 .compare = devmap_functions_compare, 87 102 .remove_callback = devices_remove_callback 88 103 }; … … 373 388 } 374 389 375 /** Create root device node in the device tree.390 /** Create root device and function node in the device tree. 376 391 * 377 392 * @param tree The device tree. 378 393 * @return True on success, false otherwise. 379 394 */ 380 bool create_root_node(dev_tree_t *tree) 381 { 382 node_t *node; 383 384 printf(NAME ": create_root_node\n"); 385 395 bool create_root_nodes(dev_tree_t *tree) 396 { 397 fun_node_t *fun; 398 dev_node_t *dev; 399 400 printf(NAME ": create_root_nodes\n"); 401 386 402 fibril_rwlock_write_lock(&tree->rwlock); 387 node = create_dev_node(); 388 if (node != NULL) { 389 insert_dev_node(tree, node, clone_string(""), NULL); 390 match_id_t *id = create_match_id(); 391 id->id = clone_string("root"); 392 id->score = 100; 393 add_match_id(&node->match_ids, id); 394 tree->root_node = node; 395 } 403 404 /* 405 * Create root function. This is a pseudo function to which 406 * the root device node is attached. It allows us to match 407 * the root device driver in a standard manner, i.e. against 408 * the parent function. 409 */ 410 411 fun = create_fun_node(); 412 if (fun == NULL) { 413 fibril_rwlock_write_unlock(&tree->rwlock); 414 return false; 415 } 416 417 insert_fun_node(tree, fun, clone_string(""), NULL); 418 match_id_t *id = create_match_id(); 419 id->id = clone_string("root"); 420 id->score = 100; 421 add_match_id(&fun->match_ids, id); 422 tree->root_node = fun; 423 424 /* 425 * Create root device node. 426 */ 427 dev = create_dev_node(); 428 if (dev == NULL) { 429 fibril_rwlock_write_unlock(&tree->rwlock); 430 return false; 431 } 432 433 insert_dev_node(tree, dev, fun); 434 396 435 fibril_rwlock_write_unlock(&tree->rwlock); 397 398 return node!= NULL;436 437 return dev != NULL; 399 438 } 400 439 … … 414 453 * is found. 415 454 */ 416 driver_t *find_best_match_driver(driver_list_t *drivers_list, node_t *node)455 driver_t *find_best_match_driver(driver_list_t *drivers_list, dev_node_t *node) 417 456 { 418 457 driver_t *best_drv = NULL, *drv = NULL; … … 442 481 * @param drv The driver. 443 482 */ 444 void attach_driver( node_t *node, driver_t *drv)483 void attach_driver(dev_node_t *dev, driver_t *drv) 445 484 { 446 485 printf(NAME ": attach_driver %s to device %s\n", 447 drv->name, node->pathname);486 drv->name, dev->pfun->pathname); 448 487 449 488 fibril_mutex_lock(&drv->driver_mutex); 450 489 451 node->drv = drv;452 list_append(& node->driver_devices, &drv->devices);490 dev->drv = drv; 491 list_append(&dev->driver_devices, &drv->devices); 453 492 454 493 fibril_mutex_unlock(&drv->driver_mutex); … … 530 569 static void pass_devices_to_driver(driver_t *driver, dev_tree_t *tree) 531 570 { 532 node_t *dev;571 dev_node_t *dev; 533 572 link_t *link; 534 573 int phone; … … 551 590 link = driver->devices.next; 552 591 while (link != &driver->devices) { 553 dev = list_get_instance(link, node_t, driver_devices);592 dev = list_get_instance(link, dev_node_t, driver_devices); 554 593 if (dev->passed_to_driver) { 555 594 link = link->next; … … 669 708 } 670 709 671 /** Create devmap path and name for the device. */672 static void devmap_register_tree_device(node_t *node, dev_tree_t *tree)710 /** Create devmap path and name for the function. */ 711 void devmap_register_tree_function(fun_node_t *fun, dev_tree_t *tree) 673 712 { 674 713 char *devmap_pathname = NULL; 675 714 char *devmap_name = NULL; 676 715 677 asprintf(&devmap_name, "%s", node->pathname);716 asprintf(&devmap_name, "%s", fun->pathname); 678 717 if (devmap_name == NULL) 679 718 return; … … 689 728 690 729 devmap_device_register_with_iface(devmap_pathname, 691 & node->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);692 693 tree_add_devmap_ device(tree, node);730 &fun->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP); 731 732 tree_add_devmap_function(tree, fun); 694 733 695 734 free(devmap_name); … … 702 741 * @param node The device's node in the device tree. 703 742 */ 704 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree)743 void add_device(int phone, driver_t *drv, dev_node_t *dev, dev_tree_t *tree) 705 744 { 706 745 /* … … 709 748 */ 710 749 printf(NAME ": add_device (driver `%s', device `%s')\n", drv->name, 711 node->name);750 dev->pfun->name); 712 751 713 752 sysarg_t rc; … … 716 755 /* Send the device to the driver. */ 717 756 devman_handle_t parent_handle; 718 if ( node->parent) {719 parent_handle = node->parent->handle;757 if (dev->pfun) { 758 parent_handle = dev->pfun->handle; 720 759 } else { 721 760 parent_handle = 0; 722 761 } 723 762 724 aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, node->handle,763 aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, dev->handle, 725 764 parent_handle, &answer); 726 765 727 766 /* Send the device's name to the driver. */ 728 rc = async_data_write_start(phone, node->name,729 str_size( node->name) + 1);767 rc = async_data_write_start(phone, dev->pfun->name, 768 str_size(dev->pfun->name) + 1); 730 769 if (rc != EOK) { 731 770 /* TODO handle error */ … … 737 776 switch(rc) { 738 777 case EOK: 739 node->state = DEVICE_USABLE; 740 devmap_register_tree_device(node, tree); 778 dev->state = DEVICE_USABLE; 741 779 break; 742 780 case ENOENT: 743 node->state = DEVICE_NOT_PRESENT;781 dev->state = DEVICE_NOT_PRESENT; 744 782 break; 745 783 default: 746 node->state = DEVICE_INVALID;747 } 748 749 node->passed_to_driver = true;784 dev->state = DEVICE_INVALID; 785 } 786 787 dev->passed_to_driver = true; 750 788 751 789 return; … … 759 797 * successfully assigned to the device, false otherwise. 760 798 */ 761 bool assign_driver(node_t *node, driver_list_t *drivers_list, dev_tree_t *tree) 762 { 799 bool assign_driver(dev_node_t *dev, driver_list_t *drivers_list, 800 dev_tree_t *tree) 801 { 802 assert(dev != NULL); 803 assert(drivers_list != NULL); 804 assert(tree != NULL); 805 763 806 /* 764 807 * Find the driver which is the most suitable for handling this device. 765 808 */ 766 driver_t *drv = find_best_match_driver(drivers_list, node);809 driver_t *drv = find_best_match_driver(drivers_list, dev); 767 810 if (drv == NULL) { 768 811 printf(NAME ": no driver found for device '%s'.\n", 769 node->pathname);812 dev->pfun->pathname); 770 813 return false; 771 814 } 772 815 773 816 /* Attach the driver to the device. */ 774 attach_driver( node, drv);817 attach_driver(dev, drv); 775 818 776 819 fibril_mutex_lock(&drv->driver_mutex); … … 786 829 int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0); 787 830 if (phone >= 0) { 788 add_device(phone, drv, node, tree);831 add_device(phone, drv, dev, tree); 789 832 async_hangup(phone); 790 833 } … … 810 853 hash_table_create(&tree->devman_devices, DEVICE_BUCKETS, 1, 811 854 &devman_devices_ops); 812 hash_table_create(&tree->devmap_devices, DEVICE_BUCKETS, 1, 855 hash_table_create(&tree->devman_functions, DEVICE_BUCKETS, 1, 856 &devman_functions_ops); 857 hash_table_create(&tree->devmap_functions, DEVICE_BUCKETS, 1, 813 858 &devmap_devices_ops); 814 859 815 860 fibril_rwlock_initialize(&tree->rwlock); 816 861 817 /* Create root node and add itto the device tree. */818 if (!create_root_node (tree))862 /* Create root function and root device and add them to the device tree. */ 863 if (!create_root_nodes(tree)) 819 864 return false; 820 865 821 866 /* Find suitable driver and start it. */ 822 return assign_driver(tree->root_node , drivers_list, tree);867 return assign_driver(tree->root_node->child, drivers_list, tree); 823 868 } 824 869 … … 829 874 * @return A device node structure. 830 875 */ 831 node_t *create_dev_node(void)832 { 833 node_t *res = malloc(sizeof(node_t));876 dev_node_t *create_dev_node(void) 877 { 878 dev_node_t *res = malloc(sizeof(dev_node_t)); 834 879 835 880 if (res != NULL) { 836 memset(res, 0, sizeof( node_t));837 list_initialize(&res-> children);838 li st_initialize(&res->match_ids.ids);839 li st_initialize(&res->classes);881 memset(res, 0, sizeof(dev_node_t)); 882 list_initialize(&res->functions); 883 link_initialize(&res->driver_devices); 884 link_initialize(&res->devman_dev); 840 885 } 841 886 … … 847 892 * @param node The device node structure. 848 893 */ 849 void delete_dev_node(node_t *node) 850 { 851 assert(list_empty(&node->children)); 852 assert(node->parent == NULL); 853 assert(node->drv == NULL); 854 855 clean_match_ids(&node->match_ids); 856 free_not_null(node->name); 857 free_not_null(node->pathname); 858 free(node); 894 void delete_dev_node(dev_node_t *dev) 895 { 896 assert(list_empty(&dev->functions)); 897 assert(dev->pfun == NULL); 898 assert(dev->drv == NULL); 899 900 free(dev); 859 901 } 860 902 … … 865 907 * @return The device node. 866 908 */ 867 node_t *find_dev_node_no_lock(dev_tree_t *tree, devman_handle_t handle)909 dev_node_t *find_dev_node_no_lock(dev_tree_t *tree, devman_handle_t handle) 868 910 { 869 911 unsigned long key = handle; … … 873 915 874 916 link = hash_table_find(&tree->devman_devices, &key); 875 return hash_table_get_instance(link, node_t, devman_link);917 return hash_table_get_instance(link, dev_node_t, devman_dev); 876 918 } 877 919 … … 882 924 * @return The device node. 883 925 */ 884 node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle)885 { 886 node_t *node= NULL;926 dev_node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle) 927 { 928 dev_node_t *dev = NULL; 887 929 888 930 fibril_rwlock_read_lock(&tree->rwlock); 889 node= find_dev_node_no_lock(tree, handle);931 dev = find_dev_node_no_lock(tree, handle); 890 932 fibril_rwlock_read_unlock(&tree->rwlock); 891 933 892 return node; 893 } 894 934 return dev; 935 } 936 937 /* Function nodes */ 938 939 /** Create a new function node. 940 * 941 * @return A function node structure. 942 */ 943 fun_node_t *create_fun_node(void) 944 { 945 fun_node_t *res = malloc(sizeof(fun_node_t)); 946 947 if (res != NULL) { 948 memset(res, 0, sizeof(fun_node_t)); 949 link_initialize(&res->dev_functions); 950 list_initialize(&res->match_ids.ids); 951 list_initialize(&res->classes); 952 link_initialize(&res->devman_fun); 953 link_initialize(&res->devmap_fun); 954 } 955 956 return res; 957 } 958 959 /** Delete a function node. 960 * 961 * @param fun The device node structure. 962 */ 963 void delete_fun_node(fun_node_t *fun) 964 { 965 assert(fun->dev == NULL); 966 assert(fun->child == NULL); 967 968 clean_match_ids(&fun->match_ids); 969 free_not_null(fun->name); 970 free_not_null(fun->pathname); 971 free(fun); 972 } 973 974 /** Find the function node with the specified handle. 975 * 976 * @param tree The device tree where we look for the device node. 977 * @param handle The handle of the function. 978 * @return The function node. 979 */ 980 fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, devman_handle_t handle) 981 { 982 unsigned long key = handle; 983 link_t *link; 984 985 assert(fibril_rwlock_is_locked(&tree->rwlock)); 986 987 link = hash_table_find(&tree->devman_functions, &key); 988 if (link == NULL) 989 return NULL; 990 991 return hash_table_get_instance(link, fun_node_t, devman_fun); 992 } 993 994 /** Find the function node with the specified handle. 995 * 996 * @param tree The device tree where we look for the device node. 997 * @param handle The handle of the function. 998 * @return The function node. 999 */ 1000 fun_node_t *find_fun_node(dev_tree_t *tree, devman_handle_t handle) 1001 { 1002 fun_node_t *fun = NULL; 1003 1004 fibril_rwlock_read_lock(&tree->rwlock); 1005 fun = find_fun_node_no_lock(tree, handle); 1006 fibril_rwlock_read_unlock(&tree->rwlock); 1007 1008 return fun; 1009 } 895 1010 896 1011 /** Create and set device's full path in device tree. … … 901 1016 * resources etc.). 902 1017 */ 903 static bool set_ dev_path(node_t *node,node_t *parent)904 { 905 assert( node->name != NULL);906 907 size_t pathsize = (str_size( node->name) + 1);1018 static bool set_fun_path(fun_node_t *fun, fun_node_t *parent) 1019 { 1020 assert(fun->name != NULL); 1021 1022 size_t pathsize = (str_size(fun->name) + 1); 908 1023 if (parent != NULL) 909 1024 pathsize += str_size(parent->pathname) + 1; 910 1025 911 node->pathname = (char *) malloc(pathsize);912 if ( node->pathname == NULL) {1026 fun->pathname = (char *) malloc(pathsize); 1027 if (fun->pathname == NULL) { 913 1028 printf(NAME ": failed to allocate device path.\n"); 914 1029 return false; … … 916 1031 917 1032 if (parent != NULL) { 918 str_cpy( node->pathname, pathsize, parent->pathname);919 str_append( node->pathname, pathsize, "/");920 str_append( node->pathname, pathsize, node->name);1033 str_cpy(fun->pathname, pathsize, parent->pathname); 1034 str_append(fun->pathname, pathsize, "/"); 1035 str_append(fun->pathname, pathsize, fun->name); 921 1036 } else { 922 str_cpy( node->pathname, pathsize, node->name);1037 str_cpy(fun->pathname, pathsize, fun->name); 923 1038 } 924 1039 … … 936 1051 * etc.). 937 1052 */ 938 bool insert_dev_node(dev_tree_t *tree, node_t *node, char *dev_name, 939 node_t *parent) 940 { 941 assert(node != NULL); 1053 bool insert_dev_node(dev_tree_t *tree, dev_node_t *dev, fun_node_t *pfun) 1054 { 1055 assert(dev != NULL); 942 1056 assert(tree != NULL); 943 assert(dev_name != NULL);944 1057 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 945 1058 946 node->name = dev_name; 947 if (!set_dev_path(node, parent)) { 1059 /* Add the node to the handle-to-node map. */ 1060 dev->handle = ++tree->current_handle; 1061 unsigned long key = dev->handle; 1062 hash_table_insert(&tree->devman_devices, &key, &dev->devman_dev); 1063 1064 /* Add the node to the list of its parent's children. */ 1065 printf("insert_dev_node: dev=%p, dev->pfun := %p\n", dev, pfun); 1066 dev->pfun = pfun; 1067 pfun->child = dev; 1068 1069 return true; 1070 } 1071 1072 /** Insert new function into device tree. 1073 * 1074 * @param tree The device tree. 1075 * @param node The newly added function node. 1076 * @param dev_name The name of the newly added function. 1077 * @param parent Owning device node. 1078 * 1079 * @return True on success, false otherwise (insufficient resources 1080 * etc.). 1081 */ 1082 bool insert_fun_node(dev_tree_t *tree, fun_node_t *fun, char *fun_name, 1083 dev_node_t *dev) 1084 { 1085 fun_node_t *pfun; 1086 1087 assert(fun != NULL); 1088 assert(tree != NULL); 1089 assert(fun_name != NULL); 1090 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 1091 1092 /* 1093 * The root function is a special case, it does not belong to any 1094 * device so for the root function dev == NULL. 1095 */ 1096 pfun = (dev != NULL) ? dev->pfun : NULL; 1097 1098 fun->name = fun_name; 1099 if (!set_fun_path(fun, pfun)) { 948 1100 return false; 949 1101 } 950 1102 951 1103 /* Add the node to the handle-to-node map. */ 952 node->handle = ++tree->current_handle;953 unsigned long key = node->handle;954 hash_table_insert(&tree->devman_ devices, &key, &node->devman_link);1104 fun->handle = ++tree->current_handle; 1105 unsigned long key = fun->handle; 1106 hash_table_insert(&tree->devman_functions, &key, &fun->devman_fun); 955 1107 956 1108 /* Add the node to the list of its parent's children. */ 957 node->parent = parent;958 if ( parent!= NULL)959 list_append(& node->sibling, &parent->children);1109 fun->dev = dev; 1110 if (dev != NULL) 1111 list_append(&fun->dev_functions, &dev->functions); 960 1112 961 1113 return true; 962 1114 } 963 1115 964 /** Find devicenode with a specified path in the device tree.1116 /** Find function node with a specified path in the device tree. 965 1117 * 966 * @param path The path of the devicenode in the device tree.1118 * @param path The path of the function node in the device tree. 967 1119 * @param tree The device tree. 968 * @return The devicenode if it is present in the tree, NULL1120 * @return The function node if it is present in the tree, NULL 969 1121 * otherwise. 970 1122 */ 971 node_t *find_dev_node_by_path(dev_tree_t *tree, char *path)1123 fun_node_t *find_fun_node_by_path(dev_tree_t *tree, char *path) 972 1124 { 973 1125 fibril_rwlock_read_lock(&tree->rwlock); 974 1126 975 node_t *dev= tree->root_node;1127 fun_node_t *fun = tree->root_node; 976 1128 /* 977 * Relative path to the devicefrom its parent (but with '/' at the1129 * Relative path to the function from its parent (but with '/' at the 978 1130 * beginning) 979 1131 */ … … 982 1134 bool cont = (rel_path[0] == '/'); 983 1135 984 while (cont && dev!= NULL) {1136 while (cont && fun != NULL) { 985 1137 next_path_elem = get_path_elem_end(rel_path + 1); 986 1138 if (next_path_elem[0] == '/') { … … 991 1143 } 992 1144 993 dev = find_node_child(dev, rel_path + 1);1145 fun = find_node_child(fun, rel_path + 1); 994 1146 995 1147 if (cont) { … … 1002 1154 fibril_rwlock_read_unlock(&tree->rwlock); 1003 1155 1004 return dev;1005 } 1006 1007 /** Find child devicenode with a specified name.1156 return fun; 1157 } 1158 1159 /** Find child function node with a specified name. 1008 1160 * 1009 1161 * Device tree rwlock should be held at least for reading. 1010 1162 * 1011 * @param parent The parent devicenode.1012 * @param name The name of the child device node.1013 * @return The child devicenode.1014 */ 1015 node_t *find_node_child(node_t *parent, const char *name)1016 { 1017 node_t *dev;1163 * @param parent The parent function node. 1164 * @param name The name of the child function. 1165 * @return The child function node. 1166 */ 1167 fun_node_t *find_node_child(fun_node_t *pfun, const char *name) 1168 { 1169 fun_node_t *fun; 1018 1170 link_t *link; 1019 1171 1020 link = p arent->children.next;1021 1022 while (link != &p arent->children) {1023 dev = list_get_instance(link, node_t, sibling);1172 link = pfun->child->functions.next; 1173 1174 while (link != &pfun->child->functions) { 1175 fun = list_get_instance(link, fun_node_t, dev_functions); 1024 1176 1025 if (str_cmp(name, dev->name) == 0)1026 return dev;1177 if (str_cmp(name, fun->name) == 0) 1178 return fun; 1027 1179 1028 1180 link = link->next; … … 1107 1259 } 1108 1260 1109 /** Add the device to the class.1261 /** Add the device function to the class. 1110 1262 * 1111 1263 * The device may be added to multiple classes and a class may contain multiple … … 1120 1272 * with the class. 1121 1273 */ 1122 dev_class_info_t *add_ device_to_class(node_t *dev, dev_class_t *cl,1274 dev_class_info_t *add_function_to_class(fun_node_t *fun, dev_class_t *cl, 1123 1275 const char *base_dev_name) 1124 1276 { 1125 dev_class_info_t *info = create_dev_class_info(); 1277 dev_class_info_t *info; 1278 1279 assert(fun != NULL); 1280 assert(cl != NULL); 1281 1282 info = create_dev_class_info(); 1283 1126 1284 1127 1285 if (info != NULL) { 1128 1286 info->dev_class = cl; 1129 info-> dev = dev;1287 info->fun = fun; 1130 1288 1131 1289 /* Add the device to the class. */ … … 1135 1293 1136 1294 /* Add the class to the device. */ 1137 list_append(&info->dev_classes, & dev->classes);1295 list_append(&info->dev_classes, &fun->classes); 1138 1296 1139 1297 /* Create unique name for the device within the class. */ … … 1189 1347 list_initialize(&class_list->classes); 1190 1348 fibril_rwlock_initialize(&class_list->rwlock); 1191 hash_table_create(&class_list->devmap_ devices, DEVICE_BUCKETS, 1,1349 hash_table_create(&class_list->devmap_functions, DEVICE_BUCKETS, 1, 1192 1350 &devmap_devices_class_ops); 1193 1351 } … … 1196 1354 /* Devmap devices */ 1197 1355 1198 node_t *find_devmap_tree_device(dev_tree_t *tree, devmap_handle_t devmap_handle)1199 { 1200 node_t *dev= NULL;1356 fun_node_t *find_devmap_tree_function(dev_tree_t *tree, devmap_handle_t devmap_handle) 1357 { 1358 fun_node_t *fun = NULL; 1201 1359 link_t *link; 1202 1360 unsigned long key = (unsigned long) devmap_handle; 1203 1361 1204 1362 fibril_rwlock_read_lock(&tree->rwlock); 1205 link = hash_table_find(&tree->devmap_ devices, &key);1363 link = hash_table_find(&tree->devmap_functions, &key); 1206 1364 if (link != NULL) 1207 dev = hash_table_get_instance(link, node_t, devmap_link);1365 fun = hash_table_get_instance(link, fun_node_t, devmap_fun); 1208 1366 fibril_rwlock_read_unlock(&tree->rwlock); 1209 1367 1210 return dev;1211 } 1212 1213 node_t *find_devmap_class_device(class_list_t *classes,1368 return fun; 1369 } 1370 1371 fun_node_t *find_devmap_class_function(class_list_t *classes, 1214 1372 devmap_handle_t devmap_handle) 1215 1373 { 1216 node_t *dev= NULL;1374 fun_node_t *fun = NULL; 1217 1375 dev_class_info_t *cli; 1218 1376 link_t *link; … … 1220 1378 1221 1379 fibril_rwlock_read_lock(&classes->rwlock); 1222 link = hash_table_find(&classes->devmap_ devices, &key);1380 link = hash_table_find(&classes->devmap_functions, &key); 1223 1381 if (link != NULL) { 1224 1382 cli = hash_table_get_instance(link, dev_class_info_t, 1225 1383 devmap_link); 1226 dev = cli->dev;1384 fun = cli->fun; 1227 1385 } 1228 1386 fibril_rwlock_read_unlock(&classes->rwlock); 1229 1387 1230 return dev;1231 } 1232 1233 void class_add_devmap_ device(class_list_t *class_list, dev_class_info_t *cli)1388 return fun; 1389 } 1390 1391 void class_add_devmap_function(class_list_t *class_list, dev_class_info_t *cli) 1234 1392 { 1235 1393 unsigned long key = (unsigned long) cli->devmap_handle; 1236 1394 1237 1395 fibril_rwlock_write_lock(&class_list->rwlock); 1238 hash_table_insert(&class_list->devmap_ devices, &key, &cli->devmap_link);1396 hash_table_insert(&class_list->devmap_functions, &key, &cli->devmap_link); 1239 1397 fibril_rwlock_write_unlock(&class_list->rwlock); 1240 1398 1241 assert(find_devmap_class_ device(class_list, cli->devmap_handle) != NULL);1242 } 1243 1244 void tree_add_devmap_ device(dev_tree_t *tree, node_t *node)1245 { 1246 unsigned long key = (unsigned long) node->devmap_handle;1399 assert(find_devmap_class_function(class_list, cli->devmap_handle) != NULL); 1400 } 1401 1402 void tree_add_devmap_function(dev_tree_t *tree, fun_node_t *fun) 1403 { 1404 unsigned long key = (unsigned long) fun->devmap_handle; 1247 1405 fibril_rwlock_write_lock(&tree->rwlock); 1248 hash_table_insert(&tree->devmap_ devices, &key, &node->devmap_link);1406 hash_table_insert(&tree->devmap_functions, &key, &fun->devmap_fun); 1249 1407 fibril_rwlock_write_unlock(&tree->rwlock); 1250 1408 } -
uspace/srv/devman/devman.h
r6a343bdf r0c968a17 56 56 #define DEVMAP_SEPARATOR '\\' 57 57 58 struct node; 59 typedef struct node node_t; 58 struct dev_node; 59 typedef struct dev_node dev_node_t; 60 61 struct fun_node; 62 typedef struct fun_node fun_node_t; 60 63 61 64 typedef enum { … … 117 120 } device_state_t; 118 121 119 /** Representation of anode in the device tree. */120 struct node {122 /** Device node in the device tree. */ 123 struct dev_node { 121 124 /** The global unique identifier of the device. */ 122 125 devman_handle_t handle; 123 /** The name of the device specified by its parent. */ 124 char *name; 125 126 /** 127 * Full path and name of the device in device hierarchi (i. e. in full 128 * path in device tree). 129 */ 130 char *pathname; 131 132 /** The node of the parent device. */ 133 node_t *parent; 134 135 /** 136 * Pointers to previous and next child devices in the linked list of 137 * parent device's node. 138 */ 139 link_t sibling; 140 141 /** List of child device nodes. */ 142 link_t children; 143 /** List of device ids for device-to-driver matching. */ 144 match_id_list_t match_ids; 126 127 /** (Parent) function the device is attached to. */ 128 fun_node_t *pfun; 129 130 /** List of device functions. */ 131 link_t functions; 145 132 /** Driver of this device. */ 146 133 driver_t *drv; 147 134 /** The state of the device. */ 148 135 device_state_t state; 149 /** 150 * Pointer to the previous and next device in the list of devices 151 * owned by one driver. 152 */ 136 /** Link to list of devices owned by driver (driver_t.devices) */ 153 137 link_t driver_devices; 154 138 155 /** The list of device classes to which this device belongs. */156 link_t classes;157 /** Devmap handle if the device is registered by devmapper. */158 devmap_handle_t devmap_handle;159 160 139 /** 161 140 * Used by the hash table of devices indexed by devman device handles. 162 141 */ 163 link_t devman_link; 164 165 /** 166 * Used by the hash table of devices indexed by devmap device handles. 167 */ 168 link_t devmap_link; 169 142 link_t devman_dev; 143 170 144 /** 171 145 * Whether this device was already passed to the driver. … … 173 147 bool passed_to_driver; 174 148 }; 149 150 /** Function node in the device tree. */ 151 struct fun_node { 152 /** The global unique identifier of the function */ 153 devman_handle_t handle; 154 /** Name of the function, assigned by the device driver */ 155 char *name; 156 157 /** Full path and name of the device in device hierarchy */ 158 char *pathname; 159 160 /** Device which this function belongs to */ 161 dev_node_t *dev; 162 163 /** Link to list of functions in the device (ddf_dev_t.functions) */ 164 link_t dev_functions; 165 166 /** Child device node (if any attached). */ 167 dev_node_t *child; 168 /** List of device ids for device-to-driver matching. */ 169 match_id_list_t match_ids; 170 171 /** The list of device classes to which this device function belongs. */ 172 link_t classes; 173 /** Devmap handle if the device function is registered by devmap. */ 174 devmap_handle_t devmap_handle; 175 176 /** 177 * Used by the hash table of functions indexed by devman device handles. 178 */ 179 link_t devman_fun; 180 181 /** 182 * Used by the hash table of functions indexed by devmap device handles. 183 */ 184 link_t devmap_fun; 185 }; 186 175 187 176 188 /** Represents device tree. */ 177 189 typedef struct dev_tree { 178 190 /** Root device node. */ 179 node_t *root_node;191 fun_node_t *root_node; 180 192 181 193 /** … … 191 203 hash_table_t devman_devices; 192 204 205 /** Hash table of all devices indexed by devman handles. */ 206 hash_table_t devman_functions; 207 193 208 /** 194 209 * Hash table of devices registered by devmapper, indexed by devmap 195 210 * handles. 196 211 */ 197 hash_table_t devmap_ devices;212 hash_table_t devmap_functions; 198 213 } dev_tree_t; 199 214 … … 227 242 228 243 /** 229 * Provides n-to-m mapping between device nodes and classes - each device may230 * be register to the arbitrary number of classes and each class maycontain231 * the arbitrary number of devices.244 * Provides n-to-m mapping between function nodes and classes - each function 245 * can register in an arbitrary number of classes and each class can contain 246 * an arbitrary number of device functions. 232 247 */ 233 248 typedef struct dev_class_info { … … 235 250 dev_class_t *dev_class; 236 251 /** The device. */ 237 node_t *dev;252 fun_node_t *fun; 238 253 239 254 /** … … 249 264 link_t dev_classes; 250 265 251 /** The name of the device within the class. */266 /** The name of the device function within the class. */ 252 267 char *dev_name; 253 268 /** The handle of the device by device mapper in the class namespace. */ … … 270 285 * indexed by devmap handles. 271 286 */ 272 hash_table_t devmap_ devices;287 hash_table_t devmap_functions; 273 288 274 289 /** Fibril mutex for list of classes. */ … … 278 293 /* Match ids and scores */ 279 294 280 extern int get_match_score(driver_t *, node_t *);295 extern int get_match_score(driver_t *, dev_node_t *); 281 296 282 297 extern bool parse_match_ids(char *, match_id_list_t *); … … 292 307 extern int lookup_available_drivers(driver_list_t *, const char *); 293 308 294 extern driver_t *find_best_match_driver(driver_list_t *, node_t *);295 extern bool assign_driver( node_t *, driver_list_t *, dev_tree_t *);309 extern driver_t *find_best_match_driver(driver_list_t *, dev_node_t *); 310 extern bool assign_driver(dev_node_t *, driver_list_t *, dev_tree_t *); 296 311 297 312 extern void add_driver(driver_list_t *, driver_t *); 298 extern void attach_driver( node_t *, driver_t *);299 extern void add_device(int, driver_t *, node_t *, dev_tree_t *);313 extern void attach_driver(dev_node_t *, driver_t *); 314 extern void add_device(int, driver_t *, dev_node_t *, dev_tree_t *); 300 315 extern bool start_driver(driver_t *); 301 316 … … 310 325 /* Device nodes */ 311 326 312 extern node_t *create_dev_node(void);313 extern void delete_dev_node( node_t *node);314 extern node_t *find_dev_node_no_lock(dev_tree_t *tree,327 extern dev_node_t *create_dev_node(void); 328 extern void delete_dev_node(dev_node_t *node); 329 extern dev_node_t *find_dev_node_no_lock(dev_tree_t *tree, 315 330 devman_handle_t handle); 316 extern node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle); 317 extern node_t *find_dev_node_by_path(dev_tree_t *, char *); 318 extern node_t *find_node_child(node_t *, const char *); 331 extern dev_node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle); 332 extern dev_node_t *find_dev_function(dev_node_t *, const char *); 333 334 extern fun_node_t *create_fun_node(void); 335 extern void delete_fun_node(fun_node_t *); 336 extern fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, 337 devman_handle_t handle); 338 extern fun_node_t *find_fun_node(dev_tree_t *tree, devman_handle_t handle); 339 extern fun_node_t *find_fun_node_by_path(dev_tree_t *, char *); 319 340 320 341 /* Device tree */ 321 342 322 343 extern bool init_device_tree(dev_tree_t *, driver_list_t *); 323 extern bool create_root_node(dev_tree_t *); 324 extern bool insert_dev_node(dev_tree_t *, node_t *, char *, node_t *); 344 extern bool create_root_nodes(dev_tree_t *); 345 extern bool insert_dev_node(dev_tree_t *, dev_node_t *, fun_node_t *); 346 extern bool insert_fun_node(dev_tree_t *, fun_node_t *, char *, dev_node_t *); 325 347 326 348 /* Device classes */ … … 330 352 extern size_t get_new_class_dev_idx(dev_class_t *); 331 353 extern char *create_dev_name_for_class(dev_class_t *, const char *); 332 extern dev_class_info_t *add_ device_to_class(node_t *, dev_class_t *,354 extern dev_class_info_t *add_function_to_class(fun_node_t *, dev_class_t *, 333 355 const char *); 334 356 … … 341 363 /* Devmap devices */ 342 364 343 extern node_t *find_devmap_tree_device(dev_tree_t *, devmap_handle_t); 344 extern node_t *find_devmap_class_device(class_list_t *, devmap_handle_t); 345 346 extern void class_add_devmap_device(class_list_t *, dev_class_info_t *); 347 extern void tree_add_devmap_device(dev_tree_t *, node_t *); 365 extern void devmap_register_tree_function(fun_node_t *, dev_tree_t *); 366 367 extern fun_node_t *find_devmap_tree_function(dev_tree_t *, devmap_handle_t); 368 extern fun_node_t *find_devmap_class_function(class_list_t *, devmap_handle_t); 369 370 extern void class_add_devmap_function(class_list_t *, dev_class_info_t *); 371 extern void tree_add_devmap_function(dev_tree_t *, fun_node_t *); 348 372 349 373 #endif -
uspace/srv/devman/main.c
r6a343bdf r0c968a17 199 199 static int assign_driver_fibril(void *arg) 200 200 { 201 node_t *node = (node_t *) arg;202 assign_driver( node, &drivers_list, &device_tree);201 dev_node_t *dev_node = (dev_node_t *) arg; 202 assign_driver(dev_node, &drivers_list, &device_tree); 203 203 return EOK; 204 204 } 205 205 206 /** Handle child deviceregistration.206 /** Handle function registration. 207 207 * 208 208 * Child devices are registered by their parent's device driver. 209 209 */ 210 static void devman_add_child(ipc_callid_t callid, ipc_call_t *call) 211 { 212 devman_handle_t parent_handle = IPC_GET_ARG1(*call); 213 sysarg_t match_count = IPC_GET_ARG2(*call); 210 static void devman_add_function(ipc_callid_t callid, ipc_call_t *call) 211 { 212 fun_type_t ftype = (fun_type_t) IPC_GET_ARG1(*call); 213 devman_handle_t dev_handle = IPC_GET_ARG2(*call); 214 sysarg_t match_count = IPC_GET_ARG3(*call); 214 215 dev_tree_t *tree = &device_tree; 215 216 216 217 fibril_rwlock_write_lock(&tree->rwlock); 217 node_t *parent = find_dev_node_no_lock(&device_tree, parent_handle); 218 219 if (parent == NULL) { 218 219 dev_node_t *dev = NULL; 220 dev_node_t *pdev = find_dev_node_no_lock(&device_tree, dev_handle); 221 222 if (pdev == NULL) { 220 223 fibril_rwlock_write_unlock(&tree->rwlock); 221 224 async_answer_0(callid, ENOENT); … … 223 226 } 224 227 225 char *dev_name = NULL; 226 int rc = async_data_write_accept((void **)&dev_name, true, 0, 0, 0, 0); 228 if (ftype != fun_inner && ftype != fun_exposed) { 229 /* Unknown function type */ 230 printf(NAME ": Error, unknown function type provided by driver!\n"); 231 232 fibril_rwlock_write_unlock(&tree->rwlock); 233 async_answer_0(callid, EINVAL); 234 return; 235 } 236 237 char *fun_name = NULL; 238 int rc = async_data_write_accept((void **)&fun_name, true, 0, 0, 0, 0); 227 239 if (rc != EOK) { 228 240 fibril_rwlock_write_unlock(&tree->rwlock); … … 231 243 } 232 244 233 node_t *node = create_dev_node();234 if (!insert_ dev_node(&device_tree, node, dev_name, parent)) {245 fun_node_t *fun = create_fun_node(); 246 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 235 247 fibril_rwlock_write_unlock(&tree->rwlock); 236 delete_ dev_node(node);248 delete_fun_node(fun); 237 249 async_answer_0(callid, ENOMEM); 238 250 return; 239 251 } 240 252 253 if (ftype == fun_inner) { 254 dev = create_dev_node(); 255 if (dev == NULL) { 256 fibril_rwlock_write_unlock(&tree->rwlock); 257 delete_fun_node(fun); 258 async_answer_0(callid, ENOMEM); 259 return; 260 } 261 262 insert_dev_node(tree, dev, fun); 263 } 264 241 265 fibril_rwlock_write_unlock(&tree->rwlock); 242 266 243 printf(NAME ": devman_add_child %s\n", node->pathname); 244 245 devman_receive_match_ids(match_count, &node->match_ids); 246 247 /* 248 * Try to find a suitable driver and assign it to the device. We do 249 * not want to block the current fibril that is used for processing 250 * incoming calls: we will launch a separate fibril to handle the 251 * driver assigning. That is because assign_driver can actually include 252 * task spawning which could take some time. 253 */ 254 fid_t assign_fibril = fibril_create(assign_driver_fibril, node); 255 if (assign_fibril == 0) { 267 printf(NAME ": devman_add_function %s\n", fun->pathname); 268 269 devman_receive_match_ids(match_count, &fun->match_ids); 270 271 if (ftype == fun_inner) { 272 assert(dev != NULL); 256 273 /* 257 * Fallback in case we are out of memory. 258 * Probably not needed as we will die soon anyway ;-). 274 * Try to find a suitable driver and assign it to the device. We do 275 * not want to block the current fibril that is used for processing 276 * incoming calls: we will launch a separate fibril to handle the 277 * driver assigning. That is because assign_driver can actually include 278 * task spawning which could take some time. 259 279 */ 260 (void) assign_driver_fibril(node); 280 fid_t assign_fibril = fibril_create(assign_driver_fibril, dev); 281 if (assign_fibril == 0) { 282 /* 283 * Fallback in case we are out of memory. 284 * Probably not needed as we will die soon anyway ;-). 285 */ 286 (void) assign_driver_fibril(fun); 287 } else { 288 fibril_add_ready(assign_fibril); 289 } 261 290 } else { 262 fibril_add_ready(assign_fibril);263 } 264 291 devmap_register_tree_function(fun, tree); 292 } 293 265 294 /* Return device handle to parent's driver. */ 266 async_answer_1(callid, EOK, node->handle);295 async_answer_1(callid, EOK, fun->handle); 267 296 } 268 297 … … 288 317 * mapper. 289 318 */ 290 class_add_devmap_ device(&class_list, cli);319 class_add_devmap_function(&class_list, cli); 291 320 292 321 free(devmap_pathname); 293 322 } 294 323 295 static void devman_add_ device_to_class(ipc_callid_t callid, ipc_call_t *call)324 static void devman_add_function_to_class(ipc_callid_t callid, ipc_call_t *call) 296 325 { 297 326 devman_handle_t handle = IPC_GET_ARG1(*call); … … 306 335 } 307 336 308 node_t *dev = find_dev_node(&device_tree, handle);309 if ( dev== NULL) {337 fun_node_t *fun = find_fun_node(&device_tree, handle); 338 if (fun == NULL) { 310 339 async_answer_0(callid, ENOENT); 311 340 return; … … 313 342 314 343 dev_class_t *cl = get_dev_class(&class_list, class_name); 315 dev_class_info_t *class_info = add_ device_to_class(dev, cl, NULL);344 dev_class_info_t *class_info = add_function_to_class(fun, cl, NULL); 316 345 317 346 /* Register the device's class alias by devmapper. */ 318 347 devmap_register_class_dev(class_info); 319 348 320 printf(NAME ": device'%s' added to class '%s', class name '%s' was "321 "asigned to it\n", dev->pathname, class_name, class_info->dev_name);349 printf(NAME ": function'%s' added to class '%s', class name '%s' was " 350 "asigned to it\n", fun->pathname, class_name, class_info->dev_name); 322 351 323 352 async_answer_0(callid, EOK); … … 372 401 cont = false; 373 402 continue; 374 case DEVMAN_ADD_ CHILD_DEVICE:375 devman_add_ child(callid, &call);403 case DEVMAN_ADD_FUNCTION: 404 devman_add_function(callid, &call); 376 405 break; 377 406 case DEVMAN_ADD_DEVICE_TO_CLASS: 378 devman_add_ device_to_class(callid, &call);407 devman_add_function_to_class(callid, &call); 379 408 break; 380 409 default: … … 387 416 /** Find handle for the device instance identified by the device's path in the 388 417 * device tree. */ 389 static void devman_ device_get_handle(ipc_callid_t iid, ipc_call_t *icall)418 static void devman_function_get_handle(ipc_callid_t iid, ipc_call_t *icall) 390 419 { 391 420 char *pathname; … … 397 426 } 398 427 399 node_t * dev = find_dev_node_by_path(&device_tree, pathname);428 fun_node_t *fun = find_fun_node_by_path(&device_tree, pathname); 400 429 401 430 free(pathname); 402 431 403 if ( dev== NULL) {432 if (fun == NULL) { 404 433 async_answer_0(iid, ENOENT); 405 434 return; 406 435 } 407 408 async_answer_1(iid, EOK, dev->handle);436 437 async_answer_1(iid, EOK, fun->handle); 409 438 } 410 439 … … 426 455 continue; 427 456 case DEVMAN_DEVICE_GET_HANDLE: 428 devman_ device_get_handle(callid, &call);457 devman_function_get_handle(callid, &call); 429 458 break; 430 459 default: … … 438 467 { 439 468 devman_handle_t handle = IPC_GET_ARG2(*icall); 440 441 node_t *dev = find_dev_node(&device_tree, handle); 442 if (dev == NULL) { 443 printf(NAME ": devman_forward error - no device with handle %" PRIun 444 " was found.\n", handle); 469 devman_handle_t fwd_h; 470 fun_node_t *fun = NULL; 471 dev_node_t *dev = NULL; 472 473 fun = find_fun_node(&device_tree, handle); 474 if (fun == NULL) 475 dev = find_dev_node(&device_tree, handle); 476 else 477 dev = fun->dev; 478 479 if (fun == NULL && dev == NULL) { 480 printf(NAME ": devman_forward error - no device or function with " 481 "handle %" PRIun " was found.\n", handle); 445 482 async_answer_0(iid, ENOENT); 446 483 return; 447 484 } 485 486 if (fun == NULL && !drv_to_parent) { 487 printf(NAME ": devman_forward error - cannot connect to " 488 "handle %" PRIun ", refers to a device.\n", handle); 489 async_answer_0(iid, ENOENT); 490 return; 491 } 448 492 449 493 driver_t *driver = NULL; 450 494 451 495 if (drv_to_parent) { 452 if (dev->parent != NULL) 453 driver = dev->parent->drv; 496 /* Connect to parent function of a device (or device function). */ 497 if (dev->pfun->dev != NULL) 498 driver = dev->pfun->dev->drv; 499 fwd_h = dev->pfun->handle; 454 500 } else if (dev->state == DEVICE_USABLE) { 501 /* Connect to the specified function */ 455 502 driver = dev->drv; 456 503 assert(driver != NULL); 504 505 fwd_h = handle; 457 506 } 458 507 … … 478 527 } 479 528 480 printf(NAME ": devman_forward: forward connection to device %s to " 481 "driver %s.\n", dev->pathname, driver->name); 482 async_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE); 529 if (fun != NULL) { 530 printf(NAME ": devman_forward: forward connection to function %s to " 531 "driver %s.\n", fun->pathname, driver->name); 532 } else { 533 printf(NAME ": devman_forward: forward connection to device %s to " 534 "driver %s.\n", dev->pfun->pathname, driver->name); 535 } 536 537 async_forward_fast(iid, driver->phone, method, fwd_h, 0, IPC_FF_NONE); 483 538 } 484 539 … … 488 543 { 489 544 devmap_handle_t devmap_handle = IPC_GET_ARG2(*icall); 490 node_t *dev; 491 492 dev = find_devmap_tree_device(&device_tree, devmap_handle); 493 if (dev == NULL) 494 dev = find_devmap_class_device(&class_list, devmap_handle); 495 496 if (dev == NULL || dev->drv == NULL) { 545 fun_node_t *fun; 546 dev_node_t *dev; 547 548 fun = find_devmap_tree_function(&device_tree, devmap_handle); 549 if (fun == NULL) 550 fun = find_devmap_class_function(&class_list, devmap_handle); 551 552 if (fun == NULL || fun->dev->drv == NULL) { 497 553 async_answer_0(iid, ENOENT); 498 554 return; 499 555 } 556 557 dev = fun->dev; 500 558 501 559 if (dev->state != DEVICE_USABLE || dev->drv->phone <= 0) { … … 507 565 IPC_FF_NONE); 508 566 printf(NAME ": devman_connection_devmapper: forwarded connection to " 509 "device %s to driver %s.\n", dev->pathname, dev->drv->name);567 "device %s to driver %s.\n", fun->pathname, dev->drv->name); 510 568 } 511 569 -
uspace/srv/devman/match.c
r6a343bdf r0c968a17 57 57 } 58 58 59 int get_match_score(driver_t *drv, node_t *dev)59 int get_match_score(driver_t *drv, dev_node_t *dev) 60 60 { 61 61 link_t *drv_head = &drv->match_ids.ids; 62 link_t *dev_head = &dev-> match_ids.ids;62 link_t *dev_head = &dev->pfun->match_ids.ids; 63 63 64 64 if (list_empty(drv_head) || list_empty(dev_head))
Note:
See TracChangeset
for help on using the changeset viewer.