Changes in uspace/lib/drv/generic/driver.c [ffa2c8ef:7e752b2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
rffa2c8ef r7e752b2 52 52 #include <ipc/driver.h> 53 53 54 #include "dev_iface.h"55 54 #include "driver.h" 56 55 57 /** Driver structure */ 56 /* driver structure */ 57 58 58 static driver_t *driver; 59 59 60 /** Devices */ 60 /* devices */ 61 61 62 LIST_INITIALIZE(devices); 62 63 FIBRIL_MUTEX_INITIALIZE(devices_mutex); 63 64 64 /** Interrupts */ 65 /* interrupts */ 66 65 67 static interrupt_context_list_t interrupt_contexts; 66 68 … … 79 81 static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall) 80 82 { 81 int id = (int)IPC_GET_ IMETHOD(*icall);83 int id = (int)IPC_GET_METHOD(*icall); 82 84 interrupt_context_t *ctx; 83 85 84 86 ctx = find_interrupt_context_by_id(&interrupt_contexts, id); 85 if ( ctx != NULL && ctx->handler != NULL)87 if (NULL != ctx && NULL != ctx->handler) 86 88 (*ctx->handler)(ctx->dev, iid, icall); 87 89 } 88 89 interrupt_context_t *create_interrupt_context(void)90 {91 interrupt_context_t *ctx;92 93 ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));94 if (ctx != NULL)95 memset(ctx, 0, sizeof(interrupt_context_t));96 97 return ctx;98 }99 100 void delete_interrupt_context(interrupt_context_t *ctx)101 {102 if (ctx != NULL)103 free(ctx);104 }105 106 void init_interrupt_context_list(interrupt_context_list_t *list)107 {108 memset(list, 0, sizeof(interrupt_context_list_t));109 fibril_mutex_initialize(&list->mutex);110 list_initialize(&list->contexts);111 }112 113 void114 add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx)115 {116 fibril_mutex_lock(&list->mutex);117 ctx->id = list->curr_id++;118 list_append(&ctx->link, &list->contexts);119 fibril_mutex_unlock(&list->mutex);120 }121 122 void remove_interrupt_context(interrupt_context_list_t *list,123 interrupt_context_t *ctx)124 {125 fibril_mutex_lock(&list->mutex);126 list_remove(&ctx->link);127 fibril_mutex_unlock(&list->mutex);128 }129 130 interrupt_context_t *131 find_interrupt_context_by_id(interrupt_context_list_t *list, int id)132 {133 fibril_mutex_lock(&list->mutex);134 135 link_t *link = list->contexts.next;136 interrupt_context_t *ctx;137 138 while (link != &list->contexts) {139 ctx = list_get_instance(link, interrupt_context_t, link);140 if (ctx->id == id) {141 fibril_mutex_unlock(&list->mutex);142 return ctx;143 }144 link = link->next;145 }146 147 fibril_mutex_unlock(&list->mutex);148 return NULL;149 }150 151 interrupt_context_t *152 find_interrupt_context(interrupt_context_list_t *list, device_t *dev, int irq)153 {154 fibril_mutex_lock(&list->mutex);155 156 link_t *link = list->contexts.next;157 interrupt_context_t *ctx;158 159 while (link != &list->contexts) {160 ctx = list_get_instance(link, interrupt_context_t, link);161 if (ctx->irq == irq && ctx->dev == dev) {162 fibril_mutex_unlock(&list->mutex);163 return ctx;164 }165 link = link->next;166 }167 168 fibril_mutex_unlock(&list->mutex);169 return NULL;170 }171 172 90 173 91 int … … 183 101 add_interrupt_context(&interrupt_contexts, ctx); 184 102 185 if ( pseudocode == NULL)103 if (NULL == pseudocode) 186 104 pseudocode = &default_pseudocode; 187 105 188 int res = register_irq(irq, dev->handle, ctx->id, pseudocode);189 if ( res != EOK) {106 int res = ipc_register_irq(irq, dev->handle, ctx->id, pseudocode); 107 if (0 != res) { 190 108 remove_interrupt_context(&interrupt_contexts, ctx); 191 109 delete_interrupt_context(ctx); … … 199 117 interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts, 200 118 dev, irq); 201 int res = unregister_irq(irq, dev->handle);202 203 if ( ctx != NULL) {119 int res = ipc_unregister_irq(irq, dev->handle); 120 121 if (NULL != ctx) { 204 122 remove_interrupt_context(&interrupt_contexts, ctx); 205 123 delete_interrupt_context(ctx); 206 124 } 207 208 125 return res; 209 126 } … … 223 140 } 224 141 225 static device_t * driver_get_device(link_t *devices, devman_handle_t handle)142 static device_t * driver_get_device(link_t *devices, devman_handle_t handle) 226 143 { 227 144 device_t *dev = NULL; … … 229 146 fibril_mutex_lock(&devices_mutex); 230 147 link_t *link = devices->next; 231 232 148 while (link != devices) { 233 149 dev = list_get_instance(link, device_t, link); 234 if ( dev->handle ==handle) {150 if (handle == dev->handle) { 235 151 fibril_mutex_unlock(&devices_mutex); 236 152 return dev; … … 238 154 link = link->next; 239 155 } 240 241 156 fibril_mutex_unlock(&devices_mutex); 242 157 243 158 return NULL; 244 159 } … … 247 162 { 248 163 char *dev_name = NULL; 249 int res; 250 251 devman_handle_t dev_handle = IPC_GET_ARG1(*icall); 252 devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall); 253 164 int res = EOK; 165 166 devman_handle_t dev_handle = IPC_GET_ARG1(*icall); 254 167 device_t *dev = create_device(); 255 168 dev->handle = dev_handle; … … 259 172 260 173 add_to_devices_list(dev); 261 dev->parent = driver_get_device(&devices, parent_dev_handle);262 263 174 res = driver->driver_ops->add_device(dev); 264 if ( res == EOK) {175 if (0 == res) { 265 176 printf("%s: new device with handle=%" PRIun " was added.\n", 266 177 driver->name, dev_handle); … … 272 183 } 273 184 274 async_answer_0(iid, res);185 ipc_answer_0(iid, res); 275 186 } 276 187 … … 278 189 { 279 190 /* Accept connection */ 280 async_answer_0(iid, EOK);281 191 ipc_answer_0(iid, EOK); 192 282 193 bool cont = true; 283 194 while (cont) { 284 195 ipc_call_t call; 285 196 ipc_callid_t callid = async_get_call(&call); 286 287 switch (IPC_GET_ IMETHOD(call)) {197 198 switch (IPC_GET_METHOD(call)) { 288 199 case IPC_M_PHONE_HUNGUP: 289 200 cont = false; … … 293 204 break; 294 205 default: 295 async_answer_0(callid, ENOENT);206 ipc_answer_0(callid, ENOENT); 296 207 } 297 208 } … … 316 227 printf("%s: driver_connection_gen error - no device with handle" 317 228 " %" PRIun " was found.\n", driver->name, handle); 318 async_answer_0(iid, ENOENT);229 ipc_answer_0(iid, ENOENT); 319 230 return; 320 231 } … … 325 236 * use the device. 326 237 */ 327 238 328 239 int ret = EOK; 329 240 /* open the device */ 330 if ( dev->ops != NULL && dev->ops->open != NULL)241 if (NULL != dev->ops && NULL != dev->ops->open) 331 242 ret = (*dev->ops->open)(dev); 332 243 333 async_answer_0(iid, ret);334 if ( ret != EOK)244 ipc_answer_0(iid, ret); 245 if (EOK != ret) 335 246 return; 336 247 337 248 while (1) { 338 249 ipc_callid_t callid; 339 250 ipc_call_t call; 340 251 callid = async_get_call(&call); 341 sysarg_t method = IPC_GET_IMETHOD(call);252 ipcarg_t method = IPC_GET_METHOD(call); 342 253 int iface_idx; 343 254 344 255 switch (method) { 345 case IPC_M_PHONE_HUNGUP: 256 case IPC_M_PHONE_HUNGUP: 346 257 /* close the device */ 347 if ( dev->ops != NULL && dev->ops->close != NULL)258 if (NULL != dev->ops && NULL != dev->ops->close) 348 259 (*dev->ops->close)(dev); 349 async_answer_0(callid, EOK);260 ipc_answer_0(callid, EOK); 350 261 return; 351 default: 262 default: 352 263 /* convert ipc interface id to interface index */ 353 264 … … 357 268 remote_handler_t *default_handler = 358 269 device_get_default_handler(dev); 359 if ( default_handler != NULL) {270 if (NULL != default_handler) { 360 271 (*default_handler)(dev, callid, &call); 361 272 break; … … 368 279 "invalid interface id %d.", 369 280 driver->name, iface_idx); 370 async_answer_0(callid, ENOTSUP);281 ipc_answer_0(callid, ENOTSUP); 371 282 break; 372 283 } 373 284 374 285 /* calling one of the device's interfaces */ 375 286 376 /* Get the interface ops structure.*/377 void * ops = device_get_ops(dev, iface_idx);378 if ( ops == NULL) {287 /* get the device interface structure */ 288 void *iface = device_get_iface(dev, iface_idx); 289 if (NULL == iface) { 379 290 printf("%s: driver_connection_gen error - ", 380 291 driver->name); 381 292 printf("device with handle %" PRIun " has no interface " 382 293 "with id %d.\n", handle, iface_idx); 383 async_answer_0(callid, ENOTSUP);294 ipc_answer_0(callid, ENOTSUP); 384 295 break; 385 296 } 386 297 387 298 /* 388 299 * Get the corresponding interface for remote request 389 300 * handling ("remote interface"). 390 301 */ 391 remote_iface_t *rem_iface = get_remote_iface(iface_idx);392 assert( rem_iface != NULL);393 302 remote_iface_t* rem_iface = get_remote_iface(iface_idx); 303 assert(NULL != rem_iface); 304 394 305 /* get the method of the remote interface */ 395 sysarg_t iface_method_idx = IPC_GET_ARG1(call);306 ipcarg_t iface_method_idx = IPC_GET_ARG1(call); 396 307 remote_iface_func_ptr_t iface_method_ptr = 397 308 get_remote_method(rem_iface, iface_method_idx); 398 if ( iface_method_ptr == NULL) {309 if (NULL == iface_method_ptr) { 399 310 // the interface has not such method 400 311 printf("%s: driver_connection_gen error - " 401 312 "invalid interface method.", driver->name); 402 async_answer_0(callid, ENOTSUP);313 ipc_answer_0(callid, ENOTSUP); 403 314 break; 404 315 } … … 410 321 * associated with the device by its driver. 411 322 */ 412 (*iface_method_ptr)(dev, ops, callid, &call);323 (*iface_method_ptr)(dev, iface, callid, &call); 413 324 break; 414 325 } … … 431 342 { 432 343 /* Select interface */ 433 switch (( sysarg_t) (IPC_GET_ARG1(*icall))) {344 switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) { 434 345 case DRIVER_DEVMAN: 435 /* Handle requestfrom device manager */346 /* handle PnP events from device manager */ 436 347 driver_connection_devman(iid, icall); 437 348 break; 438 349 case DRIVER_DRIVER: 439 /* Handle request from drivers of child devices */350 /* handle request from drivers of child devices */ 440 351 driver_connection_driver(iid, icall); 441 352 break; 442 353 case DRIVER_CLIENT: 443 /* Handle requestfrom client applications */354 /* handle requests from client applications */ 444 355 driver_connection_client(iid, icall); 445 356 break; 357 446 358 default: 447 359 /* No such interface */ 448 async_answer_0(iid, ENOENT); 449 } 450 } 451 452 /** Create new device structure. 453 * 454 * @return The device structure. 455 */ 456 device_t *create_device(void) 457 { 458 device_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 465 return dev; 466 } 467 468 /** Delete device structure. 469 * 470 * @param dev The device structure. 471 */ 472 void delete_device(device_t *dev) 473 { 474 clean_match_ids(&dev->match_ids); 475 if (dev->name != NULL) 476 free(dev->name); 477 free(dev); 478 } 479 480 void *device_get_ops(device_t *dev, dev_inferface_idx_t idx) 481 { 482 assert(is_valid_iface_idx(idx)); 483 if (dev->ops == NULL) 484 return NULL; 485 return dev->ops->interfaces[idx]; 360 ipc_answer_0(iid, ENOENT); 361 } 486 362 } 487 363 488 364 int child_device_register(device_t *child, device_t *parent) 489 365 { 490 assert( child->name != NULL);491 366 assert(NULL != child->name); 367 492 368 int res; 493 369 … … 495 371 res = devman_child_device_register(child->name, &child->match_ids, 496 372 parent->handle, &child->handle); 497 if (res != EOK) { 498 remove_from_devices_list(child); 373 if (EOK == res) 499 374 return res; 500 } 501 375 remove_from_devices_list(child); 502 376 return res; 503 }504 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;527 528 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 542 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 }557 558 /** Get default handler for client requests */559 remote_handler_t *device_get_default_handler(device_t *dev)560 {561 if (dev->ops == NULL)562 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 377 } 570 378 … … 576 384 */ 577 385 driver = drv; 578 386 579 387 /* Initialize the list of interrupt contexts. */ 580 388 init_interrupt_context_list(&interrupt_contexts); … … 588 396 */ 589 397 devman_driver_register(driver->name, driver_connection); 590 398 591 399 async_manager(); 592 400 593 401 /* Never reached. */ 594 402 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.