Changeset 68414f4a in mainline
- Timestamp:
- 2011-02-13T20:03:45Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bab6388
- Parents:
- 8b1e15ac
- Location:
- uspace/drv
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/isa/isa.c
r8b1e15ac r68414f4a 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 60 61 #define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev" 61 62 63 /** Obtain soft-state pointer from function node pointer */ 64 #define ISA_FUN(fnode) ((isa_fun_t *) ((fnode)->driver_data)) 65 62 66 #define ISA_MAX_HW_RES 4 63 67 64 typedef struct isa_fun_data { 68 typedef struct isa_fun { 69 function_t *fnode; 65 70 hw_resource_list_t hw_resources; 66 } isa_fun_data_t; 67 68 static hw_resource_list_t *isa_get_fun_resources(function_t *fun) 69 { 70 isa_fun_data_t *fun_data; 71 72 fun_data = (isa_fun_data_t *)fun->driver_data; 73 if (fun_data == NULL) 74 return NULL; 75 76 return &fun_data->hw_resources; 77 } 78 79 static bool isa_enable_fun_interrupt(function_t *fun) 71 } isa_fun_t; 72 73 static hw_resource_list_t *isa_get_fun_resources(function_t *fnode) 74 { 75 isa_fun_t *fun = ISA_FUN(fnode); 76 assert(fun != NULL); 77 78 return &fun->hw_resources; 79 } 80 81 static bool isa_enable_fun_interrupt(function_t *fnode) 80 82 { 81 83 // TODO … … 89 91 }; 90 92 91 static device_ops_t isa_fun_ dev_ops;93 static device_ops_t isa_fun_ops; 92 94 93 95 static int isa_add_device(device_t *dev); … … 104 106 }; 105 107 106 107 static isa_fun_data_t *create_isa_fun_data() 108 { 109 isa_fun_data_t *data; 110 111 data = (isa_fun_data_t *) malloc(sizeof(isa_fun_data_t)); 112 if (data != NULL) 113 memset(data, 0, sizeof(isa_fun_data_t)); 114 115 return data; 116 } 117 118 static function_t *create_isa_fun() 119 { 120 function_t *fun = create_function(); 108 static isa_fun_t *isa_fun_create() 109 { 110 isa_fun_t *fun = calloc(1, sizeof(isa_fun_t)); 121 111 if (fun == NULL) 122 112 return NULL; 123 113 124 isa_fun_data_t *data = create_isa_fun_data();125 if ( data== NULL) {126 delete_function(fun);114 function_t *fnode = create_function(); 115 if (fnode == NULL) { 116 free(fun); 127 117 return NULL; 128 118 } 129 119 130 fun->driver_data = data; 120 fun->fnode = fnode; 121 fnode->driver_data = fun; 131 122 return fun; 132 123 } 133 124 134 static char * read_fun_conf(const char *conf_path)125 static char *fun_conf_read(const char *conf_path) 135 126 { 136 127 bool suc = false; … … 151 142 lseek(fd, 0, SEEK_SET); 152 143 if (len == 0) { 153 printf(NAME ": read_fun_conferror: configuration file '%s' "144 printf(NAME ": fun_conf_read error: configuration file '%s' " 154 145 "is empty.\n", conf_path); 155 146 goto cleanup; … … 158 149 buf = malloc(len + 1); 159 150 if (buf == NULL) { 160 printf(NAME ": read_fun_conferror: memory allocation failed.\n");151 printf(NAME ": fun_conf_read error: memory allocation failed.\n"); 161 152 goto cleanup; 162 153 } 163 154 164 155 if (0 >= read(fd, buf, len)) { 165 printf(NAME ": read_fun_conferror: unable to read file '%s'.\n",156 printf(NAME ": fun_conf_read error: unable to read file '%s'.\n", 166 157 conf_path); 167 158 goto cleanup; … … 249 240 } 250 241 251 static void isa_fun_set_irq(function_t *fun, int irq) 252 { 253 isa_fun_data_t *data = (isa_fun_data_t *)fun->driver_data; 254 255 size_t count = data->hw_resources.count; 256 hw_resource_t *resources = data->hw_resources.resources; 242 static void isa_fun_set_irq(isa_fun_t *fun, int irq) 243 { 244 size_t count = fun->hw_resources.count; 245 hw_resource_t *resources = fun->hw_resources.resources; 257 246 258 247 if (count < ISA_MAX_HW_RES) { … … 260 249 resources[count].res.interrupt.irq = irq; 261 250 262 data->hw_resources.count++; 263 264 printf(NAME ": added irq 0x%x to function %s\n", irq, fun->name); 265 } 266 } 267 268 static void isa_fun_set_io_range(function_t *fun, size_t addr, size_t len) 269 { 270 isa_fun_data_t *data = (isa_fun_data_t *)fun->driver_data; 271 272 size_t count = data->hw_resources.count; 273 hw_resource_t *resources = data->hw_resources.resources; 251 fun->hw_resources.count++; 252 253 printf(NAME ": added irq 0x%x to function %s\n", irq, 254 fun->fnode->name); 255 } 256 } 257 258 static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len) 259 { 260 size_t count = fun->hw_resources.count; 261 hw_resource_t *resources = fun->hw_resources.resources; 274 262 275 263 if (count < ISA_MAX_HW_RES) { … … 279 267 resources[count].res.io_range.endianness = LITTLE_ENDIAN; 280 268 281 data->hw_resources.count++;269 fun->hw_resources.count++; 282 270 283 271 printf(NAME ": added io range (addr=0x%x, size=0x%x) to " 284 272 "function %s\n", (unsigned int) addr, (unsigned int) len, 285 fun-> name);286 } 287 } 288 289 static void get_dev_irq(function_t *fun, char *val)273 fun->fnode->name); 274 } 275 } 276 277 static void fun_parse_irq(isa_fun_t *fun, char *val) 290 278 { 291 279 int irq = 0; … … 299 287 } 300 288 301 static void get_dev_io_range(function_t *fun, char *val)289 static void fun_parse_io_range(isa_fun_t *fun, char *val) 302 290 { 303 291 size_t addr, len; … … 331 319 } 332 320 333 static void get_fun_match_id(function_t *fun, char *val)321 static void fun_parse_match_id(isa_fun_t *fun, char *val) 334 322 { 335 323 char *id = NULL; … … 337 325 char *end = NULL; 338 326 339 val = skip_spaces(val); 327 val = skip_spaces(val); 340 328 341 329 score = (int)strtol(val, &end, 10); 342 330 if (val == end) { 343 331 printf(NAME " : error - could not read match score for " 344 "function %s.\n", fun-> name);332 "function %s.\n", fun->fnode->name); 345 333 return; 346 334 } … … 349 337 if (match_id == NULL) { 350 338 printf(NAME " : failed to allocate match id for function %s.\n", 351 fun-> name);339 fun->fnode->name); 352 340 return; 353 341 } … … 357 345 if (id == NULL) { 358 346 printf(NAME " : error - could not read match id for " 359 "function %s.\n", fun-> name);347 "function %s.\n", fun->fnode->name); 360 348 delete_match_id(match_id); 361 349 return; … … 366 354 367 355 printf(NAME ": adding match id '%s' with score %d to function %s\n", id, 368 score, fun-> name);369 add_match_id(&fun-> match_ids, match_id);370 } 371 372 static bool read_fun_prop(function_t *fun, char *line, const char *prop,373 void (*read_fn)( function_t *, char *))356 score, fun->fnode->name); 357 add_match_id(&fun->fnode->match_ids, match_id); 358 } 359 360 static bool prop_parse(isa_fun_t *fun, char *line, const char *prop, 361 void (*read_fn)(isa_fun_t *, char *)) 374 362 { 375 363 size_t proplen = str_size(prop); … … 386 374 } 387 375 388 static void get_fun_prop(function_t *fun, char *line)376 static void fun_prop_parse(isa_fun_t *fun, char *line) 389 377 { 390 378 /* Skip leading spaces. */ 391 379 line = skip_spaces(line); 392 380 393 if (! read_fun_prop(fun, line, "io_range", &get_dev_io_range) &&394 ! read_fun_prop(fun, line, "irq", &get_dev_irq) &&395 ! read_fun_prop(fun, line, "match", &get_fun_match_id))381 if (!prop_parse(fun, line, "io_range", &fun_parse_io_range) && 382 !prop_parse(fun, line, "irq", &fun_parse_irq) && 383 !prop_parse(fun, line, "match", &fun_parse_match_id)) 396 384 { 397 385 printf(NAME " error undefined device property at line '%s'\n", … … 400 388 } 401 389 402 static void child_alloc_hw_res(function_t *fun) 403 { 404 isa_fun_data_t *data = (isa_fun_data_t *)fun->driver_data; 405 data->hw_resources.resources = 390 static void fun_hw_res_alloc(isa_fun_t *fun) 391 { 392 fun->hw_resources.resources = 406 393 (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES); 407 394 } 408 395 409 static char * read_isa_fun_info(char *fun_conf, device_t *dev)396 static char *isa_fun_read_info(char *fun_conf, device_t *dev) 410 397 { 411 398 char *line; … … 430 417 return NULL; 431 418 432 function_t *fun = create_isa_fun();419 isa_fun_t *fun = isa_fun_create(); 433 420 if (fun == NULL) { 434 421 free(fun_name); … … 436 423 } 437 424 438 fun->name = fun_name; 439 fun->ftype = fun_inner; 425 function_t *fnode = fun->fnode; 426 fnode->name = fun_name; 427 fnode->ftype = fun_inner; 440 428 441 429 /* Allocate buffer for the list of hardware resources of the device. */ 442 child_alloc_hw_res(fun);430 fun_hw_res_alloc(fun); 443 431 444 432 /* Get properties of the device (match ids, irq and io range). */ … … 455 443 * and store it in the device structure. 456 444 */ 457 get_fun_prop(fun, line); 458 459 //printf(NAME ": next line ='%s'\n", fun_conf); 460 //printf(NAME ": current line ='%s'\n", line); 445 fun_prop_parse(fun, line); 461 446 } 462 447 463 448 /* Set device operations to the device. */ 464 f un->ops = &isa_fun_dev_ops;449 fnode->ops = &isa_fun_ops; 465 450 466 451 printf(NAME ": register_function(fun, dev); function is %s.\n", 467 f un->name);468 register_function(f un, dev);452 fnode->name); 453 register_function(fnode, dev); 469 454 470 455 return fun_conf; 471 456 } 472 457 473 static void parse_fun_conf(char *conf, device_t *dev)458 static void fun_conf_parse(char *conf, device_t *dev) 474 459 { 475 460 while (conf != NULL && *conf != '\0') { 476 conf = read_isa_fun_info(conf, dev);477 } 478 } 479 480 static void add_legacy_children(device_t *dev)461 conf = isa_fun_read_info(conf, dev); 462 } 463 } 464 465 static void isa_functions_add(device_t *dev) 481 466 { 482 467 char *fun_conf; 483 468 484 fun_conf = read_fun_conf(CHILD_FUN_CONF_PATH);469 fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH); 485 470 if (fun_conf != NULL) { 486 parse_fun_conf(fun_conf, dev);471 fun_conf_parse(fun_conf, dev); 487 472 free(fun_conf); 488 473 } … … 502 487 register_function(ctl, dev); 503 488 504 /* Add child devices. */505 add_legacy_children(dev);506 printf(NAME ": finished the enumeration of legacy devices\n");489 /* Add functions as specified in the configuration file. */ 490 isa_functions_add(dev); 491 printf(NAME ": finished the enumeration of legacy functions\n"); 507 492 508 493 return EOK; … … 511 496 static void isa_init() 512 497 { 513 isa_fun_ dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;498 isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops; 514 499 } 515 500 … … 524 509 * @} 525 510 */ 526 -
uspace/drv/ns8250/ns8250.c
r8b1e15ac r68414f4a 1 /* 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 68 69 #define DLAB_MASK (1 << 7) 69 70 71 /** Obtain soft-state structure from function node */ 72 #define NS8250(fnode) ((ns8250_t *) ((fnode)->dev->driver_data)) 73 74 /** Obtain soft-state structure from device node */ 75 #define NS8250_FROM_DEV(dnode) ((ns8250_t *) ((dnode)->driver_data)) 76 70 77 /** The number of bits of one data unit send by the serial port. */ 71 78 typedef enum { … … 85 92 86 93 /** The driver data for the serial port devices. */ 87 typedef struct ns8250_dev_data { 94 typedef struct ns8250 { 95 /** DDF device node */ 96 device_t *dev; 97 /** DDF function node */ 98 function_t *fun; 88 99 /** Is there any client conntected to the device? */ 89 100 bool client_connected; … … 98 109 /** The fibril mutex for synchronizing the access to the device. */ 99 110 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 data The driver data structure. 121 */ 122 static void delete_ns8250_dev_data(ns8250_dev_data_t *data) 123 { 124 if (data != NULL) 125 free(data); 111 } ns8250_t; 112 113 /** Create per-device soft-state structure. 114 * 115 * @return Pointer to soft-state structure. 116 */ 117 static ns8250_t *ns8250_new(void) 118 { 119 ns8250_t *ns; 120 121 ns = (ns8250_t *) calloc(1, sizeof(ns8250_t)); 122 if (ns == NULL) 123 return NULL; 124 125 fibril_mutex_initialize(&ns->mutex); 126 return ns; 127 } 128 129 /** Delete soft-state structure. 130 * 131 * @param ns The driver data structure. 132 */ 133 static void ns8250_delete(ns8250_t *ns) 134 { 135 free(ns); 126 136 } 127 137 … … 171 181 /** Read data from the serial port device. 172 182 * 173 * @param dev The serial port device.183 * @param fun The serial port function 174 184 * @param buf The ouput buffer for read data. 175 185 * @param count The number of bytes to be read. … … 180 190 static int ns8250_read(function_t *fun, char *buf, size_t count) 181 191 { 192 ns8250_t *ns = NS8250(fun); 182 193 int ret = EOK; 183 ns8250_dev_data_t *data = (ns8250_dev_data_t *) fun->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); 194 195 fibril_mutex_lock(&ns->mutex); 196 while (!buf_is_empty(&ns->input_buffer) && (size_t)ret < count) { 197 buf[ret] = (char)buf_pop_front(&ns->input_buffer); 188 198 ret++; 189 199 } 190 fibril_mutex_unlock(& data->mutex);200 fibril_mutex_unlock(&ns->mutex); 191 201 192 202 return ret; … … 195 205 /** Write a character to the serial port. 196 206 * 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);207 * @param ns Serial port device 208 * @param c The character to be written 209 */ 210 static inline void ns8250_putchar(ns8250_t *ns, uint8_t c) 211 { 212 fibril_mutex_lock(&ns->mutex); 213 ns8250_write_8(ns->port, c); 214 fibril_mutex_unlock(&ns->mutex); 205 215 } 206 216 207 217 /** Write data to the serial port. 208 218 * 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 .219 * @param fun The serial port function 220 * @param buf The data to be written 221 * @param count The number of bytes to be written 222 * @return Zero on success 213 223 */ 214 224 static int ns8250_write(function_t *fun, char *buf, size_t count) 215 225 { 216 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) fun->dev->driver_data;226 ns8250_t *ns = NS8250(fun); 217 227 size_t idx; 218 228 219 229 for (idx = 0; idx < count; idx++) 220 ns8250_putchar( data, (uint8_t) buf[idx]);230 ns8250_putchar(ns, (uint8_t) buf[idx]); 221 231 222 232 return 0; … … 244 254 }; 245 255 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; 256 /** Clean up the serial port soft-state 257 * 258 * @param ns Serial port device 259 */ 260 static void ns8250_dev_cleanup(ns8250_t *ns) 261 { 262 if (ns->dev->parent_phone > 0) { 263 async_hangup(ns->dev->parent_phone); 264 ns->dev->parent_phone = 0; 260 265 } 261 266 } … … 263 268 /** Enable the i/o ports of the device. 264 269 * 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; 270 * @param ns Serial port device 271 * @return True on success, false otherwise 272 */ 273 static bool ns8250_pio_enable(ns8250_t *ns) 274 { 275 printf(NAME ": ns8250_pio_enable %s\n", ns->dev->name); 273 276 274 277 /* Gain control over port's registers. */ 275 if (pio_enable((void *)(uintptr_t) data->io_addr, REG_COUNT,276 (void **) & data->port)) {278 if (pio_enable((void *)(uintptr_t) ns->io_addr, REG_COUNT, 279 (void **) &ns->port)) { 277 280 printf(NAME ": error - cannot gain the port %#" PRIx32 " for device " 278 "%s.\n", data->io_addr,dev->name);281 "%s.\n", ns->io_addr, ns->dev->name); 279 282 return false; 280 283 } … … 285 288 /** Probe the serial port device for its presence. 286 289 * 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; 290 * @param ns Serial port device 291 * @return True if the device is present, false otherwise 292 */ 293 static bool ns8250_dev_probe(ns8250_t *ns) 294 { 295 printf(NAME ": ns8250_dev_probe %s\n", ns->dev->name); 296 297 ioport8_t *port_addr = ns->port; 296 298 bool res = true; 297 299 uint8_t olddata; … … 310 312 311 313 if (!res) 312 printf(NAME ": device %s is not present.\n", dev->name);314 printf(NAME ": device %s is not present.\n", ns->dev->name); 313 315 314 316 return res; … … 317 319 /** Initialize serial port device. 318 320 * 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);321 * @param ns Serial port device 322 * @return Zero on success, negative error number otherwise 323 */ 324 static int ns8250_dev_initialize(ns8250_t *ns) 325 { 326 printf(NAME ": ns8250_dev_initialize %s\n", ns->dev->name); 325 327 326 328 int ret = EOK; … … 329 331 memset(&hw_resources, 0, sizeof(hw_resource_list_t)); 330 332 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 333 /* Connect to the parent's driver. */ 338 dev->parent_phone = devman_parent_device_connect(dev->handle,334 ns->dev->parent_phone = devman_parent_device_connect(ns->dev->handle, 339 335 IPC_FLAG_BLOCKING); 340 if ( dev->parent_phone < 0) {336 if (ns->dev->parent_phone < 0) { 341 337 printf(NAME ": failed to connect to the parent driver of the " 342 "device %s.\n", dev->name);343 ret = dev->parent_phone;338 "device %s.\n", ns->dev->name); 339 ret = ns->dev->parent_phone; 344 340 goto failed; 345 341 } 346 342 347 343 /* Get hw resources. */ 348 ret = hw_res_get_resource_list( dev->parent_phone, &hw_resources);344 ret = hw_res_get_resource_list(ns->dev->parent_phone, &hw_resources); 349 345 if (ret != EOK) { 350 346 printf(NAME ": failed to get hw resources for the device " 351 "%s.\n", dev->name);347 "%s.\n", ns->dev->name); 352 348 goto failed; 353 349 } … … 362 358 switch (res->type) { 363 359 case INTERRUPT: 364 data->irq = res->res.interrupt.irq;360 ns->irq = res->res.interrupt.irq; 365 361 irq = true; 366 362 printf(NAME ": the %s device was asigned irq = 0x%x.\n", 367 dev->name, data->irq);363 ns->dev->name, ns->irq); 368 364 break; 369 365 370 366 case IO_RANGE: 371 data->io_addr = res->res.io_range.address;367 ns->io_addr = res->res.io_range.address; 372 368 if (res->res.io_range.size < REG_COUNT) { 373 369 printf(NAME ": i/o range assigned to the device " 374 "%s is too small.\n", dev->name);370 "%s is too small.\n", ns->dev->name); 375 371 ret = ELIMIT; 376 372 goto failed; … … 378 374 ioport = true; 379 375 printf(NAME ": the %s device was asigned i/o address = " 380 "0x%x.\n", dev->name, data->io_addr);376 "0x%x.\n", ns->dev->name, ns->io_addr); 381 377 break; 382 378 … … 388 384 if (!irq || !ioport) { 389 385 printf(NAME ": missing hw resource(s) for the device %s.\n", 390 dev->name);386 ns->dev->name); 391 387 ret = ENOENT; 392 388 goto failed; … … 397 393 398 394 failed: 399 ns8250_dev_cleanup( dev);395 ns8250_dev_cleanup(ns); 400 396 hw_res_clean_resource_list(&hw_resources); 401 397 return ret; … … 404 400 /** Enable interrupts on the serial port device. 405 401 * 406 * Interrupt when data is received .402 * Interrupt when data is received 407 403 * 408 404 * @param port The base address of the serial port device's ports. … … 416 412 /** Disable interrupts on the serial port device. 417 413 * 418 * @param port The base address of the serial port device's ports .414 * @param port The base address of the serial port device's ports 419 415 */ 420 416 static inline void ns8250_port_interrupts_disable(ioport8_t *port) … … 425 421 /** Enable interrupts for the serial port device. 426 422 * 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 423 * @param ns Serial port device 424 * @return Zero on success, negative error number otherwise 425 */ 426 static int ns8250_interrupt_enable(ns8250_t *ns) 427 { 434 428 /* Enable interrupt on the serial port. */ 435 ns8250_port_interrupts_enable( data->port);429 ns8250_port_interrupts_enable(ns->port); 436 430 437 431 return EOK; … … 618 612 * Set the default parameters of the serial communication. 619 613 * 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; 614 * @param ns Serial port device 615 */ 616 static void ns8250_initialize_port(ns8250_t *ns) 617 { 618 ioport8_t *port = ns->port; 626 619 627 620 /* Disable interrupts. */ … … 643 636 * buffer. 644 637 * 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; 638 * @param ns Serial port device 639 */ 640 static void ns8250_read_from_device(ns8250_t *ns) 641 { 642 ioport8_t *port = ns->port; 651 643 bool cont = true; 652 644 653 645 while (cont) { 654 fibril_mutex_lock(& data->mutex);646 fibril_mutex_lock(&ns->mutex); 655 647 656 648 cont = ns8250_received(port); … … 658 650 uint8_t val = ns8250_read_8(port); 659 651 660 if ( data->client_connected) {661 if (!buf_push_back(& data->input_buffer, val)) {652 if (ns->client_connected) { 653 if (!buf_push_back(&ns->input_buffer, val)) { 662 654 printf(NAME ": buffer overflow on " 663 "%s.\n", dev->name);655 "%s.\n", ns->dev->name); 664 656 } else { 665 657 printf(NAME ": the character %c saved " 666 658 "to the buffer of %s.\n", 667 val, dev->name);659 val, ns->dev->name); 668 660 } 669 661 } 670 662 } 671 663 672 fibril_mutex_unlock(& data->mutex);664 fibril_mutex_unlock(&ns->mutex); 673 665 fibril_yield(); 674 666 } … … 685 677 ipc_call_t *icall) 686 678 { 687 ns8250_read_from_device( dev);679 ns8250_read_from_device(NS8250_FROM_DEV(dev)); 688 680 } 689 681 690 682 /** Register the interrupt handler for the device. 691 683 * 684 * @param ns Serial port device 685 */ 686 static inline int ns8250_register_interrupt_handler(ns8250_t *ns) 687 { 688 return register_interrupt_handler(ns->dev, ns->irq, 689 ns8250_interrupt_handler, NULL); 690 } 691 692 /** Unregister the interrupt handler for the device. 693 * 694 * @param ns Serial port device 695 */ 696 static inline int ns8250_unregister_interrupt_handler(ns8250_t *ns) 697 { 698 return unregister_interrupt_handler(ns->dev, ns->irq); 699 } 700 701 /** The add_device callback method of the serial port driver. 702 * 703 * Probe and initialize the newly added device. 704 * 692 705 * @param dev The serial port device. 693 706 */ 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 707 static int ns8250_add_device(device_t *dev) 720 708 { 721 function_t *fun; 722 709 ns8250_t *ns = NULL; 710 function_t *fun = NULL; 711 bool need_cleanup = false; 712 int rc; 713 723 714 printf(NAME ": ns8250_add_device %s (handle = %d)\n", 724 715 dev->name, (int) dev->handle); 725 716 726 int res = ns8250_dev_initialize(dev); 727 if (res != EOK) 728 return res; 729 730 if (!ns8250_pio_enable(dev)) { 731 ns8250_dev_cleanup(dev); 732 return EADDRNOTAVAIL; 717 /* Allocate soft-state for the device */ 718 ns = ns8250_new(); 719 if (ns == NULL) { 720 rc = ENOMEM; 721 goto fail; 722 } 723 724 ns->dev = dev; 725 dev->driver_data = ns; 726 727 rc = ns8250_dev_initialize(ns); 728 if (rc != EOK) 729 goto fail; 730 731 need_cleanup = true; 732 733 if (!ns8250_pio_enable(ns)) { 734 rc = EADDRNOTAVAIL; 735 goto fail; 733 736 } 734 737 735 738 /* Find out whether the device is present. */ 736 if (!ns8250_dev_probe( dev)) {737 ns8250_dev_cleanup(dev);738 return ENOENT;739 if (!ns8250_dev_probe(ns)) { 740 rc = ENOENT; 741 goto fail; 739 742 } 740 743 741 744 /* Serial port initialization (baud rate etc.). */ 742 ns8250_initialize_port( dev);745 ns8250_initialize_port(ns); 743 746 744 747 /* Register interrupt handler. */ 745 if (ns8250_register_interrupt_handler( dev) != EOK) {748 if (ns8250_register_interrupt_handler(ns) != EOK) { 746 749 printf(NAME ": failed to register interrupt handler.\n"); 747 ns8250_dev_cleanup(dev);748 return res;750 rc = EADDRNOTAVAIL; 751 goto fail; 749 752 } 750 753 751 754 /* Enable interrupt. */ 752 r es = ns8250_interrupt_enable(dev);753 if (r es!= EOK) {755 rc = ns8250_interrupt_enable(ns); 756 if (rc != EOK) { 754 757 printf(NAME ": failed to enable the interrupt. Error code = " 755 "%d.\n", res); 756 ns8250_dev_cleanup(dev); 757 ns8250_unregister_interrupt_handler(dev); 758 return res; 759 } 760 758 "%d.\n", rc); 759 goto fail; 760 } 761 761 762 fun = create_function(); 762 763 fun->ftype = fun_exposed; … … 766 767 fun->ops = &ns8250_dev_ops; 767 768 register_function(fun, dev); 769 ns->fun = fun; 768 770 769 771 add_function_to_class(fun, "serial"); … … 773 775 774 776 return EOK; 777 fail: 778 if (need_cleanup) 779 ns8250_dev_cleanup(ns); 780 if (ns != NULL) 781 ns8250_delete(ns); 782 return rc; 775 783 } 776 784 … … 784 792 static int ns8250_open(function_t *fun) 785 793 { 786 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) fun->dev->driver_data;794 ns8250_t *data = (ns8250_t *) fun->dev->driver_data; 787 795 int res; 788 796 … … 808 816 static void ns8250_close(function_t *fun) 809 817 { 810 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) fun->dev->driver_data;818 ns8250_t *data = (ns8250_t *) fun->dev->driver_data; 811 819 812 820 fibril_mutex_lock(&data->mutex); … … 833 841 unsigned int *word_length, unsigned int* stop_bits) 834 842 { 835 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;843 ns8250_t *data = (ns8250_t *) dev->driver_data; 836 844 ioport8_t *port = data->port; 837 845 … … 864 872 stop_bits); 865 873 866 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;874 ns8250_t *data = (ns8250_t *) dev->driver_data; 867 875 ioport8_t *port = data->port; 868 876 int ret; -
uspace/drv/pciintel/pci.c
r8b1e15ac r68414f4a 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 61 62 ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) 62 63 63 static hw_resource_list_t *pciintel_get_child_resources(function_t *fun) 64 { 65 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 66 67 if (fun_data == NULL) 64 /** Obtain PCI function soft-state from DDF function node */ 65 #define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data) 66 67 /** Obtain PCI bus soft-state from DDF device node */ 68 #define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data) 69 70 /** Obtain PCI bus soft-state from function soft-state */ 71 #define PCI_BUS_FROM_FUN(fun) (PCI_BUS(fun->fnode->dev)) 72 73 static hw_resource_list_t *pciintel_get_resources(function_t *fnode) 74 { 75 pci_fun_t *fun = PCI_FUN(fnode); 76 77 if (fun == NULL) 68 78 return NULL; 69 return &fun _data->hw_resources;70 } 71 72 static bool pciintel_enable_ child_interrupt(function_t *fun)79 return &fun->hw_resources; 80 } 81 82 static bool pciintel_enable_interrupt(function_t *fnode) 73 83 { 74 84 /* TODO */ … … 77 87 } 78 88 79 static hw_res_ops_t pciintel_ child_hw_res_ops = {80 &pciintel_get_ child_resources,81 &pciintel_enable_ child_interrupt89 static hw_res_ops_t pciintel_hw_res_ops = { 90 &pciintel_get_resources, 91 &pciintel_enable_interrupt 82 92 }; 83 93 84 static device_ops_t pci_ child_ops;94 static device_ops_t pci_fun_ops; 85 95 86 96 static int pci_add_device(device_t *); 87 97 88 /** The pci bus driver's standard operations.*/98 /** PCI bus driver standard operations */ 89 99 static driver_ops_t pci_ops = { 90 100 .add_device = &pci_add_device 91 101 }; 92 102 93 /** The pci bus driver structure.*/103 /** PCI bus driver structure */ 94 104 static driver_t pci_driver = { 95 105 .name = NAME, … … 97 107 }; 98 108 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(function_t *fun, int reg, uint8_t *buf, size_t len) 125 { 126 assert(fun->dev != NULL); 127 128 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 129 pci_bus_data_t *bus_data = (pci_bus_data_t *) fun->dev->driver_data; 130 131 fibril_mutex_lock(&bus_data->conf_mutex); 109 static pci_bus_t *pci_bus_new(void) 110 { 111 pci_bus_t *bus; 112 113 bus = (pci_bus_t *) malloc(sizeof(pci_bus_t)); 114 if (bus != NULL) { 115 memset(bus, 0, sizeof(pci_bus_t)); 116 fibril_mutex_initialize(&bus->conf_mutex); 117 } 118 119 return bus; 120 } 121 122 static void pci_bus_delete(pci_bus_t *bus) 123 { 124 free(bus); 125 } 126 127 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 128 { 129 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 130 131 fibril_mutex_lock(&bus->conf_mutex); 132 132 133 133 uint32_t conf_addr; 134 conf_addr = CONF_ADDR(fun _data->bus, fun_data->dev, fun_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);134 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 135 void *addr = bus->conf_data_port + (reg & 3); 136 137 pio_write_32(bus->conf_addr_port, conf_addr); 138 138 139 139 switch (len) { … … 149 149 } 150 150 151 fibril_mutex_unlock(&bus_data->conf_mutex); 152 } 153 154 static void pci_conf_write(function_t *fun, int reg, uint8_t *buf, size_t len) 155 { 156 assert(fun->dev != NULL); 157 158 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 159 pci_bus_data_t *bus_data = (pci_bus_data_t *) fun->dev->driver_data; 160 161 fibril_mutex_lock(&bus_data->conf_mutex); 151 fibril_mutex_unlock(&bus->conf_mutex); 152 } 153 154 static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 155 { 156 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 157 158 fibril_mutex_lock(&bus->conf_mutex); 162 159 163 160 uint32_t conf_addr; 164 conf_addr = CONF_ADDR(fun _data->bus, fun_data->dev, fun_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);161 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 162 void *addr = bus->conf_data_port + (reg & 3); 163 164 pio_write_32(bus->conf_addr_port, conf_addr); 168 165 169 166 switch (len) { … … 179 176 } 180 177 181 fibril_mutex_unlock(&bus _data->conf_mutex);182 } 183 184 uint8_t pci_conf_read_8( function_t *fun, int reg)178 fibril_mutex_unlock(&bus->conf_mutex); 179 } 180 181 uint8_t pci_conf_read_8(pci_fun_t *fun, int reg) 185 182 { 186 183 uint8_t res; … … 189 186 } 190 187 191 uint16_t pci_conf_read_16( function_t *fun, int reg)188 uint16_t pci_conf_read_16(pci_fun_t *fun, int reg) 192 189 { 193 190 uint16_t res; … … 196 193 } 197 194 198 uint32_t pci_conf_read_32( function_t *fun, int reg)195 uint32_t pci_conf_read_32(pci_fun_t *fun, int reg) 199 196 { 200 197 uint32_t res; … … 203 200 } 204 201 205 void pci_conf_write_8( function_t *fun, int reg, uint8_t val)202 void pci_conf_write_8(pci_fun_t *fun, int reg, uint8_t val) 206 203 { 207 204 pci_conf_write(fun, reg, (uint8_t *) &val, 1); 208 205 } 209 206 210 void pci_conf_write_16( function_t *fun, int reg, uint16_t val)207 void pci_conf_write_16(pci_fun_t *fun, int reg, uint16_t val) 211 208 { 212 209 pci_conf_write(fun, reg, (uint8_t *) &val, 2); 213 210 } 214 211 215 void pci_conf_write_32( function_t *fun, int reg, uint32_t val)212 void pci_conf_write_32(pci_fun_t *fun, int reg, uint32_t val) 216 213 { 217 214 pci_conf_write(fun, reg, (uint8_t *) &val, 4); 218 215 } 219 216 220 void create_pci_match_ids(function_t *fun) 221 { 222 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 217 void pci_fun_create_match_ids(pci_fun_t *fun) 218 { 223 219 match_id_t *match_id = NULL; 224 220 char *match_id_str; … … 227 223 if (match_id != NULL) { 228 224 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 229 fun _data->vendor_id, fun_data->device_id);225 fun->vendor_id, fun->device_id); 230 226 match_id->id = match_id_str; 231 227 match_id->score = 90; 232 add_match_id(&fun-> match_ids, match_id);228 add_match_id(&fun->fnode->match_ids, match_id); 233 229 } 234 230 … … 236 232 } 237 233 238 void 239 pci_add_range(function_t *fun, uint64_t range_addr, size_t range_size, bool io) 240 { 241 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 242 hw_resource_list_t *hw_res_list = &fun_data->hw_resources; 234 void pci_add_range(pci_fun_t *fun, uint64_t range_addr, size_t range_size, 235 bool io) 236 { 237 hw_resource_list_t *hw_res_list = &fun->hw_resources; 243 238 hw_resource_t *hw_resources = hw_res_list->resources; 244 239 size_t count = hw_res_list->count; … … 265 260 * address add it to the devices hw resource list. 266 261 * 267 * @param dev The pci device.262 * @param fun PCI function 268 263 * @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 .264 * the device 265 * @return The addr the address of the BAR which should be read next 271 266 */ 272 int pci_read_bar( function_t *fun, int addr)267 int pci_read_bar(pci_fun_t *fun, int addr) 273 268 { 274 269 /* Value of the BAR */ … … 322 317 323 318 if (range_addr != 0) { 324 printf(NAME ": function %s : ", fun-> name);319 printf(NAME ": function %s : ", fun->fnode->name); 325 320 printf("address = %" PRIx64, range_addr); 326 321 printf(", size = %x\n", (unsigned int) range_size); … … 335 330 } 336 331 337 void pci_add_interrupt(function_t *fun, int irq) 338 { 339 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 340 hw_resource_list_t *hw_res_list = &fun_data->hw_resources; 332 void pci_add_interrupt(pci_fun_t *fun, int irq) 333 { 334 hw_resource_list_t *hw_res_list = &fun->hw_resources; 341 335 hw_resource_t *hw_resources = hw_res_list->resources; 342 336 size_t count = hw_res_list->count; … … 350 344 hw_res_list->count++; 351 345 352 printf(NAME ": function %s uses irq %x.\n", fun-> name, irq);353 } 354 355 void pci_read_interrupt( function_t *fun)346 printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq); 347 } 348 349 void pci_read_interrupt(pci_fun_t *fun) 356 350 { 357 351 uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE); … … 362 356 /** Enumerate (recursively) and register the devices connected to a pci bus. 363 357 * 364 * @param dev The host-to-pci bridge device.365 * @param bus_num The bus number.358 * @param bus Host-to-PCI bridge 359 * @param bus_num Bus number 366 360 */ 367 void pci_bus_scan( device_t *dev, int bus_num)368 { 369 function_t *f un= create_function();370 pci_fun_ data_t *fun_data = create_pci_fun_data();371 f un->driver_data = fun_data;361 void pci_bus_scan(pci_bus_t *bus, int bus_num) 362 { 363 function_t *fnode = create_function(); 364 pci_fun_t *fun = pci_fun_new(); 365 fnode->driver_data = fun; 372 366 373 367 int child_bus = 0; … … 377 371 378 372 /* We need this early, before registering. */ 379 fun->dev = dev; 373 fun->fnode = fnode; 374 fnode->dev = bus->dnode; 375 fnode->driver_data = fun; 380 376 381 377 for (dnum = 0; dnum < 32; dnum++) { 382 378 multi = true; 383 379 for (fnum = 0; multi && fnum < 8; fnum++) { 384 init_pci_fun_data(fun_data, bus_num, dnum, fnum);385 fun _data->vendor_id = pci_conf_read_16(fun,380 pci_fun_init(fun, bus_num, dnum, fnum); 381 fun->vendor_id = pci_conf_read_16(fun, 386 382 PCI_VENDOR_ID); 387 fun _data->device_id = pci_conf_read_16(fun,383 fun->device_id = pci_conf_read_16(fun, 388 384 PCI_DEVICE_ID); 389 if (fun _data->vendor_id == 0xffff) {385 if (fun->vendor_id == 0xffff) { 390 386 /* 391 387 * The device is not present, go on scanning the … … 406 402 header_type = header_type & 0x7F; 407 403 408 create_pci_fun_name(fun);404 pci_fun_create_name(fun); 409 405 410 406 pci_alloc_resource_list(fun); … … 412 408 pci_read_interrupt(fun); 413 409 414 f un->ftype = fun_inner;415 f un->ops = &pci_child_ops;410 fnode->ftype = fun_inner; 411 fnode->ops = &pci_fun_ops; 416 412 417 413 printf(NAME ": adding new function %s.\n", 418 f un->name);419 420 create_pci_match_ids(fun);421 422 if (register_function(f un, dev) != EOK) {414 fnode->name); 415 416 pci_fun_create_match_ids(fun); 417 418 if (register_function(fnode, bus->dnode) != EOK) { 423 419 pci_clean_resource_list(fun); 424 clean_match_ids(&f un->match_ids);425 free((char *) f un->name);426 f un->name = NULL;420 clean_match_ids(&fnode->match_ids); 421 free((char *) fnode->name); 422 fnode->name = NULL; 427 423 continue; 428 424 } … … 435 431 "secondary bus number = %d.\n", bus_num); 436 432 if (child_bus > bus_num) 437 pci_bus_scan( dev, child_bus);433 pci_bus_scan(bus, child_bus); 438 434 } 439 435 440 436 /* Alloc new aux. fun. structure. */ 441 f un= create_function();437 fnode = create_function(); 442 438 443 439 /* We need this early, before registering. */ 444 fun->dev = dev; 445 446 fun_data = create_pci_fun_data(); 447 fun->driver_data = fun_data; 440 fnode->dev = bus->dnode; 441 442 fun = pci_fun_new(); 443 fun->fnode = fnode; 444 fnode->driver_data = fun; 448 445 } 449 446 } 450 447 451 if (fun _data->vendor_id == 0xffff) {452 delete_function(f un);448 if (fun->vendor_id == 0xffff) { 449 delete_function(fnode); 453 450 /* Free the auxiliary function structure. */ 454 delete_pci_fun_data(fun_data);455 } 456 } 457 458 static int pci_add_device(device_t *d ev)451 pci_fun_delete(fun); 452 } 453 } 454 455 static int pci_add_device(device_t *dnode) 459 456 { 460 457 int rc; 461 458 462 459 printf(NAME ": pci_add_device\n"); 463 460 464 pci_bus_ data_t *bus_data = create_pci_bus_data();465 if (bus _data== NULL) {461 pci_bus_t *bus = pci_bus_new(); 462 if (bus == NULL) { 466 463 printf(NAME ": pci_add_device allocation failed.\n"); 467 464 return ENOMEM; 468 465 } 469 470 dev->parent_phone = devman_parent_device_connect(dev->handle, 466 bus->dnode = dnode; 467 dnode->driver_data = bus; 468 469 dnode->parent_phone = devman_parent_device_connect(dnode->handle, 471 470 IPC_FLAG_BLOCKING); 472 if (d ev->parent_phone < 0) {471 if (dnode->parent_phone < 0) { 473 472 printf(NAME ": pci_add_device failed to connect to the " 474 473 "parent's driver.\n"); 475 delete_pci_bus_data(bus_data);476 return d ev->parent_phone;474 pci_bus_delete(bus); 475 return dnode->parent_phone; 477 476 } 478 477 479 478 hw_resource_list_t hw_resources; 480 479 481 rc = hw_res_get_resource_list(d ev->parent_phone, &hw_resources);480 rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources); 482 481 if (rc != EOK) { 483 482 printf(NAME ": pci_add_device failed to get hw resources for " 484 483 "the device.\n"); 485 delete_pci_bus_data(bus_data);486 async_hangup(d ev->parent_phone);484 pci_bus_delete(bus); 485 async_hangup(dnode->parent_phone); 487 486 return rc; 488 487 } … … 495 494 assert(hw_resources.resources[0].res.io_range.size == 8); 496 495 497 bus _data->conf_io_addr =496 bus->conf_io_addr = 498 497 (uint32_t) hw_resources.resources[0].res.io_range.address; 499 498 500 if (pio_enable((void *)(uintptr_t)bus _data->conf_io_addr, 8,501 &bus _data->conf_addr_port)) {499 if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8, 500 &bus->conf_addr_port)) { 502 501 printf(NAME ": failed to enable configuration ports.\n"); 503 delete_pci_bus_data(bus_data);504 async_hangup(d ev->parent_phone);502 pci_bus_delete(bus); 503 async_hangup(dnode->parent_phone); 505 504 hw_res_clean_resource_list(&hw_resources); 506 505 return EADDRNOTAVAIL; 507 506 } 508 bus_data->conf_data_port = (char *) bus_data->conf_addr_port + 4; 509 510 dev->driver_data = bus_data; 511 512 /* Make the bus device more visible. Does not do anything. */ 507 bus->conf_data_port = (char *) bus->conf_addr_port + 4; 508 509 /* Make the bus device more visible. It has no use yet. */ 513 510 printf(NAME ": adding a 'ctl' function\n"); 514 511 515 512 function_t *ctl = create_function(); 516 513 ctl->ftype = fun_exposed; 517 514 ctl->name = "ctl"; 518 register_function(ctl, d ev);519 520 /* Enumerate child devices. */515 register_function(ctl, dnode); 516 517 /* Enumerate functions. */ 521 518 printf(NAME ": scanning the bus\n"); 522 pci_bus_scan( dev, 0);519 pci_bus_scan(bus, 0); 523 520 524 521 hw_res_clean_resource_list(&hw_resources); … … 529 526 static void pciintel_init(void) 530 527 { 531 pci_ child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_hw_res_ops;532 } 533 534 pci_fun_ data_t *create_pci_fun_data(void)535 { 536 pci_fun_ data_t *res = (pci_fun_data_t *) malloc(sizeof(pci_fun_data_t));528 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 529 } 530 531 pci_fun_t *pci_fun_new(void) 532 { 533 pci_fun_t *res = (pci_fun_t *) malloc(sizeof(pci_fun_t)); 537 534 538 535 if (res != NULL) 539 memset(res, 0, sizeof(pci_fun_ data_t));536 memset(res, 0, sizeof(pci_fun_t)); 540 537 return res; 541 538 } 542 539 543 void init_pci_fun_data(pci_fun_data_t *fun_data, int bus, int dev, int fn) 544 { 545 fun_data->bus = bus; 546 fun_data->dev = dev; 547 fun_data->fn = fn; 548 } 549 550 void delete_pci_fun_data(pci_fun_data_t *fun_data) 551 { 552 if (fun_data != NULL) { 553 hw_res_clean_resource_list(&fun_data->hw_resources); 554 free(fun_data); 555 } 556 } 557 558 void create_pci_fun_name(function_t *fun) 559 { 560 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 540 void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn) 541 { 542 fun->bus = bus; 543 fun->dev = dev; 544 fun->fn = fn; 545 } 546 547 void pci_fun_delete(pci_fun_t *fun) 548 { 549 if (fun != NULL) { 550 hw_res_clean_resource_list(&fun->hw_resources); 551 free(fun); 552 } 553 } 554 555 void pci_fun_create_name(pci_fun_t *fun) 556 { 561 557 char *name = NULL; 562 558 563 asprintf(&name, "%02x:%02x.%01x", fun_data->bus, fun_data->dev, 564 fun_data->fn); 565 fun->name = name; 566 } 567 568 bool pci_alloc_resource_list(function_t *fun) 569 { 570 pci_fun_data_t *fun_data = (pci_fun_data_t *)fun->driver_data; 571 572 fun_data->hw_resources.resources = 559 asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev, 560 fun->fn); 561 fun->fnode->name = name; 562 } 563 564 bool pci_alloc_resource_list(pci_fun_t *fun) 565 { 566 fun->hw_resources.resources = 573 567 (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t)); 574 return fun_data->hw_resources.resources != NULL; 575 } 576 577 void pci_clean_resource_list(function_t *fun) 578 { 579 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 580 581 if (fun_data->hw_resources.resources != NULL) { 582 free(fun_data->hw_resources.resources); 583 fun_data->hw_resources.resources = NULL; 584 } 585 } 586 587 /** Read the base address registers (BARs) of the device and adds the addresses 588 * to its hw resource list. 568 return fun->hw_resources.resources != NULL; 569 } 570 571 void pci_clean_resource_list(pci_fun_t *fun) 572 { 573 if (fun->hw_resources.resources != NULL) { 574 free(fun->hw_resources.resources); 575 fun->hw_resources.resources = NULL; 576 } 577 } 578 579 /** Read the base address registers (BARs) of the function and add the addresses 580 * to its HW resource list. 589 581 * 590 * @param dev the pci device.582 * @param fun PCI function 591 583 */ 592 void pci_read_bars( function_t *fun)584 void pci_read_bars(pci_fun_t *fun) 593 585 { 594 586 /* -
uspace/drv/pciintel/pci.h
r8b1e15ac r68414f4a 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 45 46 46 47 typedef struct pci_fun_data { 48 function_t *fnode; 49 47 50 int bus; 48 51 int dev; … … 51 54 int device_id; 52 55 hw_resource_list_t hw_resources; 53 } pci_fun_ data_t;56 } pci_fun_t; 54 57 55 extern void create_pci_match_ids(function_t *); 58 typedef struct pciintel_bus { 59 /** DDF device node */ 60 device_t *dnode; 61 uint32_t conf_io_addr; 62 void *conf_data_port; 63 void *conf_addr_port; 64 fibril_mutex_t conf_mutex; 65 } pci_bus_t; 56 66 57 extern uint8_t pci_conf_read_8(function_t *, int); 58 extern uint16_t pci_conf_read_16(function_t *, int); 59 extern uint32_t pci_conf_read_32(function_t *, int); 60 extern void pci_conf_write_8(function_t *, int, uint8_t); 61 extern void pci_conf_write_16(function_t *, int, uint16_t); 62 extern void pci_conf_write_32(function_t *, int, uint32_t); 67 extern void pci_fun_create_match_ids(pci_fun_t *); 63 68 64 extern void pci_add_range(function_t *, uint64_t, size_t, bool); 65 extern int pci_read_bar(function_t *, int); 66 extern void pci_read_interrupt(function_t *); 67 extern void pci_add_interrupt(function_t *, int); 69 extern uint8_t pci_conf_read_8(pci_fun_t *, int); 70 extern uint16_t pci_conf_read_16(pci_fun_t *, int); 71 extern uint32_t pci_conf_read_32(pci_fun_t *, int); 72 extern void pci_conf_write_8(pci_fun_t *, int, uint8_t); 73 extern void pci_conf_write_16(pci_fun_t *, int, uint16_t); 74 extern void pci_conf_write_32(pci_fun_t *, int, uint32_t); 68 75 69 extern void pci_bus_scan(device_t *, int); 76 extern void pci_add_range(pci_fun_t *, uint64_t, size_t, bool); 77 extern int pci_read_bar(pci_fun_t *, int); 78 extern void pci_read_interrupt(pci_fun_t *); 79 extern void pci_add_interrupt(pci_fun_t *, int); 70 80 71 extern pci_fun_ data_t *create_pci_fun_data(void);72 extern void init_pci_fun_data(pci_fun_data_t *, int, int, int);73 extern void delete_pci_fun_data(pci_fun_data_t *);74 extern void create_pci_fun_name(function_t *);81 extern pci_fun_t *pci_fun_new(void); 82 extern void pci_fun_init(pci_fun_t *, int, int, int); 83 extern void pci_fun_delete(pci_fun_t *); 84 extern void pci_fun_create_name(pci_fun_t *); 75 85 76 extern bool pci_alloc_resource_list(function_t *); 77 extern void pci_clean_resource_list(function_t *); 86 extern void pci_bus_scan(pci_bus_t *, int); 78 87 79 extern void pci_read_bars(function_t *); 88 extern bool pci_alloc_resource_list(pci_fun_t *); 89 extern void pci_clean_resource_list(pci_fun_t *); 90 91 extern void pci_read_bars(pci_fun_t *); 80 92 extern size_t pci_bar_mask_to_size(uint32_t); 81 93 -
uspace/drv/root/root.c
r8b1e15ac r68414f4a 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 * … … 55 56 #define NAME "root" 56 57 57 #define PLATFORM_ DEVICE_NAME "hw"58 #define PLATFORM_ DEVICE_MATCH_ID_FMT "platform/%s"59 #define PLATFORM_ DEVICE_MATCH_SCORE 10058 #define PLATFORM_FUN_NAME "hw" 59 #define PLATFORM_FUN_MATCH_ID_FMT "platform/%s" 60 #define PLATFORM_FUN_MATCH_SCORE 100 60 61 61 #define VIRTUAL_ DEVICE_NAME "virt"62 #define VIRTUAL_ DEVICE_MATCH_ID "rootvirt"63 #define VIRTUAL_ DEVICE_MATCH_SCORE 10062 #define VIRTUAL_FUN_NAME "virt" 63 #define VIRTUAL_FUN_MATCH_ID "rootvirt" 64 #define VIRTUAL_FUN_MATCH_SCORE 100 64 65 65 66 static int root_add_device(device_t *dev); … … 76 77 }; 77 78 78 /** Create the devicewhich represents the root of virtual device tree.79 /** Create the function which represents the root of virtual device tree. 79 80 * 80 * @param parent Parent of the newly created device.81 * @return Error code.81 * @param dev Device 82 * @return EOK on success or negative error code 82 83 */ 83 static int add_virtual_root_ child(device_t *parent)84 static int add_virtual_root_fun(device_t *dev) 84 85 { 85 printf(NAME ": adding new childfor 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);86 printf(NAME ": adding new function for virtual devices.\n"); 87 printf(NAME ": function node is `%s' (%d %s)\n", VIRTUAL_FUN_NAME, 88 VIRTUAL_FUN_MATCH_SCORE, VIRTUAL_FUN_MATCH_ID); 88 89 89 int res = register_function_wrapper( parent, VIRTUAL_DEVICE_NAME,90 VIRTUAL_ DEVICE_MATCH_ID, VIRTUAL_DEVICE_MATCH_SCORE);90 int res = register_function_wrapper(dev, VIRTUAL_FUN_NAME, 91 VIRTUAL_FUN_MATCH_ID, VIRTUAL_FUN_MATCH_SCORE); 91 92 92 93 return res; 93 94 } 94 95 95 /** Create the devicewhich represents the root of HW device tree.96 /** Create the function which represents the root of HW device tree. 96 97 * 97 * @param parent Parent of the newly created device.98 * @return 0 on success, negative error number otherwise.98 * @param dev Device 99 * @return EOK on success or negative error code 99 100 */ 100 static int add_platform_ child(device_t *parent)101 static int add_platform_fun(device_t *dev) 101 102 { 102 103 char *match_id; … … 106 107 107 108 /* Get platform name from sysinfo. */ 108 109 109 platform = sysinfo_get_data("platform", &platform_size); 110 110 if (platform == NULL) { … … 123 123 124 124 /* Construct match ID. */ 125 126 if (asprintf(&match_id, PLATFORM_DEVICE_MATCH_ID_FMT, platform) == -1) { 125 if (asprintf(&match_id, PLATFORM_FUN_MATCH_ID_FMT, platform) == -1) { 127 126 printf(NAME ": Memory allocation failed.\n"); 128 127 return ENOMEM; 129 128 } 130 129 131 /* Add child. */ 130 /* Add function. */ 131 printf(NAME ": adding platform function\n"); 132 printf(NAME ": function node is `%s' (%d %s)\n", PLATFORM_FUN_NAME, 133 PLATFORM_FUN_MATCH_SCORE, match_id); 132 134 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 = register_function_wrapper(parent, PLATFORM_DEVICE_NAME, 138 match_id, PLATFORM_DEVICE_MATCH_SCORE); 135 res = register_function_wrapper(dev, PLATFORM_FUN_NAME, 136 match_id, PLATFORM_FUN_MATCH_SCORE); 139 137 140 138 return res; … … 156 154 * vital for the system. 157 155 */ 158 add_virtual_root_ child(dev);156 add_virtual_root_fun(dev); 159 157 160 158 /* Register root device's children. */ 161 int res = add_platform_ child(dev);159 int res = add_platform_fun(dev); 162 160 if (EOK != res) 163 161 printf(NAME ": failed to add child device for platform.\n"); -
uspace/drv/rootpc/rootpc.c
r8b1e15ac r68414f4a 55 55 #define NAME "rootpc" 56 56 57 typedef struct rootpc_fun_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_fun_ data_t;62 } rootpc_fun_t; 60 63 61 64 static int rootpc_add_device(device_t *dev); … … 82 85 }; 83 86 84 static rootpc_fun_ 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_fun_resources(function_t *fun) 92 { 93 rootpc_fun_data_t *data; 94 95 data = (rootpc_fun_data_t *) fun->driver_data; 96 if (NULL == data) 97 return NULL; 98 99 return &data->hw_resources; 100 } 101 102 static bool rootpc_enable_fun_interrupt(function_t *fun) 94 static hw_resource_list_t *rootpc_get_resources(function_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(function_t *fun) 103 103 { 104 104 /* TODO */ … … 108 108 109 109 static hw_res_ops_t fun_hw_res_ops = { 110 &rootpc_get_ fun_resources,111 &rootpc_enable_ fun_interrupt110 &rootpc_get_resources, 111 &rootpc_enable_interrupt 112 112 }; 113 113 … … 116 116 117 117 static bool 118 rootpc_add_fun(device_t * parent, const char *name, const char *str_match_id,119 rootpc_fun_ data_t *drv_data)118 rootpc_add_fun(device_t *dev, const char *name, const char *str_match_id, 119 rootpc_fun_t *fun) 120 120 { 121 121 printf(NAME ": adding new function '%s'.\n", name); 122 122 123 function_t *f un= NULL;123 function_t *fnode = NULL; 124 124 match_id_t *match_id = NULL; 125 125 126 126 /* Create new device. */ 127 f un= create_function();128 if (f un== NULL)127 fnode = create_function(); 128 if (fnode == NULL) 129 129 goto failure; 130 130 131 f un->name = name;132 f un->driver_data = drv_data;133 f un->ftype = fun_inner;131 fnode->name = name; 132 fnode->driver_data = fun; 133 fnode->ftype = fun_inner; 134 134 135 135 /* Initialize match id list */ 136 136 match_id = create_match_id(); 137 if ( NULL == match_id)137 if (match_id == NULL) 138 138 goto failure; 139 139 140 140 match_id->id = str_match_id; 141 141 match_id->score = 100; 142 add_match_id(&f un->match_ids, match_id);142 add_match_id(&fnode->match_ids, match_id); 143 143 144 144 /* Set provided operations to the device. */ 145 f un->ops = &rootpc_fun_ops;145 fnode->ops = &rootpc_fun_ops; 146 146 147 147 /* Register function. */ 148 if ( EOK != register_function(fun, parent))148 if (register_function(fnode, dev) != EOK) 149 149 goto failure; 150 printf(NAME ": registered function handle = %u\n", f un->handle);150 printf(NAME ": registered function handle = %u\n", fnode->handle); 151 151 152 152 return true; 153 153 154 154 failure: 155 if ( NULL != match_id)155 if (match_id != NULL) 156 156 match_id->id = NULL; 157 157 158 if ( NULL != fun) {159 f un->name = NULL;160 delete_function(f un);158 if (fnode != NULL) { 159 fnode->name = NULL; 160 delete_function(fnode); 161 161 } 162 162 -
uspace/drv/rootvirt/rootvirt.c
r8b1e15ac r68414f4a 61 61 }; 62 62 63 static int add_device(device_t *dev);63 static int rootvirt_add_device(device_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 … … 78 78 * @return EOK on success or negative error code. 79 79 */ 80 static int add_child(device_t *vdev, virtual_function_t *vfun)80 static int rootvirt_add_fun(device_t *vdev, virtual_function_t *vfun) 81 81 { 82 82 printf(NAME ": registering function `%s' (match \"%s\")\n", … … 97 97 } 98 98 99 static int add_device(device_t *dev)99 static int rootvirt_add_device(device_t *dev) 100 100 { 101 101 static int instances = 0; … … 117 117 virtual_function_t *vfun = virtual_functions; 118 118 while (vfun->name != NULL) { 119 (void) add_child(dev, vfun);119 (void) rootvirt_add_fun(dev, vfun); 120 120 vfun++; 121 121 }
Note:
See TracChangeset
for help on using the changeset viewer.