Changeset 7a252ec8 in mainline for uspace/lib/drv/generic/driver.c
- Timestamp:
- 2010-10-21T20:13:40Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 848e3d15
- Parents:
- a79d88d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
ra79d88d r7a252ec8 53 53 #include "driver.h" 54 54 55 / / driver structure55 /* driver structure */ 56 56 57 57 static driver_t *driver; 58 58 59 / / devices59 /* devices */ 60 60 61 61 LIST_INITIALIZE(devices); 62 62 FIBRIL_MUTEX_INITIALIZE(devices_mutex); 63 63 64 / / interrupts64 /* interrupts */ 65 65 66 66 static interrupt_context_list_t interrupt_contexts; … … 79 79 80 80 static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall) 81 { 81 { 82 82 int id = (int)IPC_GET_METHOD(*icall); 83 interrupt_context_t *ctx = find_interrupt_context_by_id(&interrupt_contexts, id); 84 if (NULL != ctx && NULL != ctx->handler) { 85 (*ctx->handler)(ctx->dev, iid, icall); 86 } 87 } 88 89 int register_interrupt_handler(device_t *dev, int irq, interrupt_handler_t *handler, irq_code_t *pseudocode) 83 interrupt_context_t *ctx; 84 85 ctx = find_interrupt_context_by_id(&interrupt_contexts, id); 86 if (NULL != ctx && NULL != ctx->handler) 87 (*ctx->handler)(ctx->dev, iid, icall); 88 } 89 90 int 91 register_interrupt_handler(device_t *dev, int irq, interrupt_handler_t *handler, 92 irq_code_t *pseudocode) 90 93 { 91 94 interrupt_context_t *ctx = create_interrupt_context(); … … 97 100 add_interrupt_context(&interrupt_contexts, ctx); 98 101 99 if (NULL == pseudocode) {102 if (NULL == pseudocode) 100 103 pseudocode = &default_pseudocode; 101 }102 104 103 105 int res = ipc_register_irq(irq, dev->handle, ctx->id, pseudocode); … … 106 108 delete_interrupt_context(ctx); 107 109 } 108 return res; 110 111 return res; 109 112 } 110 113 111 114 int unregister_interrupt_handler(device_t *dev, int irq) 112 115 { 113 interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts, dev, irq); 116 interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts, 117 dev, irq); 114 118 int res = ipc_unregister_irq(irq, dev->handle); 119 115 120 if (NULL != ctx) { 116 121 remove_interrupt_context(&interrupt_contexts, ctx); 117 delete_interrupt_context(ctx); 122 delete_interrupt_context(ctx); 118 123 } 119 124 return res; … … 138 143 device_t *dev = NULL; 139 144 140 fibril_mutex_lock(&devices_mutex); 145 fibril_mutex_lock(&devices_mutex); 141 146 link_t *link = devices->next; 142 147 while (link != devices) { … … 162 167 dev->handle = dev_handle; 163 168 164 async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0);169 async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0); 165 170 dev->name = dev_name; 166 171 167 add_to_devices_list(dev); 172 add_to_devices_list(dev); 168 173 res = driver->driver_ops->add_device(dev); 169 174 if (0 == res) { 170 printf("%s: new device with handle = %x was added.\n", driver->name, dev_handle); 175 printf("%s: new device with handle = %x was added.\n", 176 driver->name, dev_handle); 171 177 } else { 172 printf("%s: failed to add a new device with handle = %d.\n", driver->name, dev_handle); 178 printf("%s: failed to add a new device with handle = %d.\n", 179 driver->name, dev_handle); 173 180 remove_from_devices_list(dev); 174 delete_device(dev); 181 delete_device(dev); 175 182 } 176 183 … … 205 212 * Generic client connection handler both for applications and drivers. 206 213 * 207 * @param drv true for driver client, false for other clients (applications, services etc.). 214 * @param drv True for driver client, false for other clients 215 * (applications, services etc.). 208 216 */ 209 217 static void driver_connection_gen(ipc_callid_t iid, ipc_call_t *icall, bool drv) 210 218 { 211 // Answer the first IPC_M_CONNECT_ME_TO call and remember the handle of the device to which the client connected. 219 /* 220 * Answer the first IPC_M_CONNECT_ME_TO call and remember the handle of 221 * the device to which the client connected. 222 */ 212 223 device_handle_t handle = IPC_GET_ARG2(*icall); 213 224 device_t *dev = driver_get_device(&devices, handle); 214 225 215 226 if (dev == NULL) { 216 printf("%s: driver_connection_gen error - no device with handle %x was found.\n", driver->name, handle); 227 printf("%s: driver_connection_gen error - no device with handle" 228 " %x was found.\n", driver->name, handle); 217 229 ipc_answer_0(iid, ENOENT); 218 230 return; … … 220 232 221 233 222 // TODO - if the client is not a driver, check whether it is allowed to use the device 234 /* 235 * TODO - if the client is not a driver, check whether it is allowed to 236 * use the device. 237 */ 223 238 224 239 int ret = EOK; 225 / / open the device226 if (NULL != dev->ops && NULL != dev->ops->open) {240 /* open the device */ 241 if (NULL != dev->ops && NULL != dev->ops->open) 227 242 ret = (*dev->ops->open)(dev); 228 }229 243 230 244 ipc_answer_0(iid, ret); 231 if (EOK != ret) {245 if (EOK != ret) 232 246 return; 233 }234 247 235 248 while (1) { … … 242 255 switch (method) { 243 256 case IPC_M_PHONE_HUNGUP: 244 / / close the device245 if (NULL != dev->ops && NULL != dev->ops->close) {257 /* close the device */ 258 if (NULL != dev->ops && NULL != dev->ops->close) 246 259 (*dev->ops->close)(dev); 247 }248 260 ipc_answer_0(callid, EOK); 249 261 return; 250 262 default: 251 / / convert ipc interface id to interface index263 /* convert ipc interface id to interface index */ 252 264 253 265 iface_idx = DEV_IFACE_IDX(method); 254 266 255 267 if (!is_valid_iface_idx(iface_idx)) { 256 remote_handler_t *default_handler; 257 if (NULL != (default_handler = device_get_default_handler(dev))) { 268 remote_handler_t *default_handler = 269 device_get_default_handler(dev); 270 if (NULL != default_handler) { 258 271 (*default_handler)(dev, callid, &call); 259 272 break; 260 273 } 261 // this is not device's interface and the default handler is not provided 262 printf("%s: driver_connection_gen error - invalid interface id %d.", driver->name, iface_idx); 274 /* 275 * This is not device's interface and the 276 * default handler is not provided. 277 */ 278 printf("%s: driver_connection_gen error - " 279 "invalid interface id %d.", 280 driver->name, iface_idx); 263 281 ipc_answer_0(callid, ENOTSUP); 264 282 break; 265 283 } 266 284 267 / / calling one of the device's interfaces285 /* calling one of the device's interfaces */ 268 286 269 / / get the device interface structure287 /* get the device interface structure */ 270 288 void *iface = device_get_iface(dev, iface_idx); 271 289 if (NULL == iface) { 272 printf("%s: driver_connection_gen error - ", driver->name); 273 printf("device with handle %d has no interface with id %d.\n", handle, iface_idx); 290 printf("%s: driver_connection_gen error - ", 291 driver->name); 292 printf("device with handle %d has no interface " 293 "with id %d.\n", handle, iface_idx); 274 294 ipc_answer_0(callid, ENOTSUP); 275 295 break; 276 296 } 277 297 278 // get the corresponding interface for remote request handling ("remote interface") 298 /* 299 * Get the corresponding interface for remote request 300 * handling ("remote interface"). 301 */ 279 302 remote_iface_t* rem_iface = get_remote_iface(iface_idx); 280 303 assert(NULL != rem_iface); 281 304 282 / / get the method of the remote interface305 /* get the method of the remote interface */ 283 306 ipcarg_t iface_method_idx = IPC_GET_ARG1(call); 284 remote_iface_func_ptr_t iface_method_ptr = get_remote_method(rem_iface, iface_method_idx); 307 remote_iface_func_ptr_t iface_method_ptr = 308 get_remote_method(rem_iface, iface_method_idx); 285 309 if (NULL == iface_method_ptr) { 286 310 // the interface has not such method 287 printf("%s: driver_connection_gen error - invalid interface method.", driver->name); 311 printf("%s: driver_connection_gen error - " 312 "invalid interface method.", driver->name); 288 313 ipc_answer_0(callid, ENOTSUP); 289 314 break; 290 315 } 291 316 292 // call the remote interface's method, which will receive parameters from the remote client 293 // and it will pass it to the corresponding local interface method associated with the device 294 // by its driver 317 /* 318 * Call the remote interface's method, which will 319 * receive parameters from the remote client and it will 320 * pass it to the corresponding local interface method 321 * associated with the device by its driver. 322 */ 295 323 (*iface_method_ptr)(dev, iface, callid, &call); 296 324 break; … … 310 338 311 339 312 /** Function for handling connections to device driver. 313 * 314 */ 340 /** Function for handling connections to device driver. */ 315 341 static void driver_connection(ipc_callid_t iid, ipc_call_t *icall) 316 342 { … … 318 344 switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) { 319 345 case DRIVER_DEVMAN: 320 / / handle PnP events from device manager346 /* handle PnP events from device manager */ 321 347 driver_connection_devman(iid, icall); 322 348 break; 323 349 case DRIVER_DRIVER: 324 / / handle request from drivers of child devices350 /* handle request from drivers of child devices */ 325 351 driver_connection_driver(iid, icall); 326 352 break; 327 353 case DRIVER_CLIENT: 328 / / handle requests from client applications354 /* handle requests from client applications */ 329 355 driver_connection_client(iid, icall); 330 356 break; … … 338 364 int child_device_register(device_t *child, device_t *parent) 339 365 { 340 // printf("%s: child_device_register\n", driver->name);341 342 366 assert(NULL != child->name); 343 367 … … 345 369 346 370 add_to_devices_list(child); 347 if (EOK == (res = devman_child_device_register(child->name, &child->match_ids, parent->handle, &child->handle))) { 371 res = devman_child_device_register(child->name, &child->match_ids, 372 parent->handle, &child->handle); 373 if (EOK == res) 348 374 return res; 349 }350 375 remove_from_devices_list(child); 351 376 return res; … … 354 379 int driver_main(driver_t *drv) 355 380 { 356 // remember the driver structure - driver_ops will be called by generic handler for incoming connections 381 /* 382 * Remember the driver structure - driver_ops will be called by generic 383 * handler for incoming connections. 384 */ 357 385 driver = drv; 358 386 359 / / initialize the list of interrupt contexts387 /* Initialize the list of interrupt contexts. */ 360 388 init_interrupt_context_list(&interrupt_contexts); 361 389 362 / / set generic interrupt handler390 /* Set generic interrupt handler. */ 363 391 async_set_interrupt_received(driver_irq_handler); 364 392 365 // register driver by device manager with generic handler for incoming connections 393 /* 394 * Register driver by device manager with generic handler for incoming 395 * connections. 396 */ 366 397 devman_driver_register(driver->name, driver_connection); 367 398 368 399 async_manager(); 369 400 370 / / Never reached401 /* Never reached. */ 371 402 return 0; 372 403 }
Note:
See TracChangeset
for help on using the changeset viewer.