Changeset 7a252ec8 in mainline for uspace/lib/drv/generic
- Timestamp:
- 2010-10-21T20:13:40Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 848e3d15
- Parents:
- a79d88d
- Location:
- uspace/lib/drv/generic
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/dev_iface.c
ra79d88d r7a252ec8 35 35 /** @file 36 36 */ 37 37 38 38 #include "dev_iface.h" 39 39 #include "remote_res.h" 40 40 #include "remote_char.h" 41 41 42 42 static iface_dipatch_table_t remote_ifaces = { 43 43 .ifaces = { … … 49 49 remote_iface_t* get_remote_iface(int idx) 50 50 { 51 assert(is_valid_iface_idx(idx)); 52 return remote_ifaces.ifaces[idx]; 51 assert(is_valid_iface_idx(idx)); 52 return remote_ifaces.ifaces[idx]; 53 53 } 54 54 55 remote_iface_func_ptr_t get_remote_method(remote_iface_t *rem_iface, ipcarg_t iface_method_idx) 55 remote_iface_func_ptr_t 56 get_remote_method(remote_iface_t *rem_iface, ipcarg_t iface_method_idx) 56 57 { 57 58 if (iface_method_idx >= rem_iface->method_count) { … … 60 61 return rem_iface->methods[iface_method_idx]; 61 62 } 62 63 64 63 65 64 /** 66 65 * @} -
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 } -
uspace/lib/drv/generic/remote_char.c
ra79d88d r7a252ec8 1 1 /* 2 * Copyright (c) 2010 Lenka Trochtova 2 * Copyright (c) 2010 Lenka Trochtova 3 3 * All rights reserved. 4 4 * … … 42 42 #define MAX_CHAR_RW_COUNT 256 43 43 44 static void remote_char_read(device_t * dev, void *iface, ipc_callid_t callid, ipc_call_t *call);45 static void remote_char_write(device_t * dev, void *iface, ipc_callid_t callid, ipc_call_t *call);44 static void remote_char_read(device_t *, void *, ipc_callid_t, ipc_call_t *); 45 static void remote_char_write(device_t *, void *, ipc_callid_t, ipc_call_t *); 46 46 47 /** Remote character interface operations. 48 */ 47 /** Remote character interface operations. */ 49 48 static remote_iface_func_ptr_t remote_char_iface_ops [] = { 50 49 &remote_char_read, 51 &remote_char_write 52 }; 53 54 /** Remote character interface structure. 55 * Interface for processing request from remote clients addressed to the character interface. 50 &remote_char_write 51 }; 52 53 /** Remote character interface structure. 54 * 55 * Interface for processing request from remote clients addressed to the 56 * character interface. 56 57 */ 57 58 remote_iface_t remote_char_iface = { 58 .method_count = sizeof(remote_char_iface_ops) / sizeof(remote_iface_func_ptr_t), 59 .method_count = sizeof(remote_char_iface_ops) / 60 sizeof(remote_iface_func_ptr_t), 59 61 .methods = remote_char_iface_ops 60 62 }; 61 63 62 64 /** Process the read request from the remote client. 63 * 64 * Receive the read request's parameters from the remote client and pass them to the local interface. 65 * Return the result of the operation processed by the local interface to the remote client. 66 * 67 * @param dev the device from which the data are read. 68 * @param iface the local interface structure. 65 * 66 * Receive the read request's parameters from the remote client and pass them 67 * to the local interface. Return the result of the operation processed by the 68 * local interface to the remote client. 69 * 70 * @param dev The device from which the data are read. 71 * @param iface The local interface structure. 69 72 */ 70 static void remote_char_read(device_t *dev, void *iface, ipc_callid_t callid, ipc_call_t *call) 73 static void 74 remote_char_read(device_t *dev, void *iface, ipc_callid_t callid, 75 ipc_call_t *call) 71 76 { 72 char_iface_t *char_iface = (char_iface_t *) iface;77 char_iface_t *char_iface = (char_iface_t *) iface; 73 78 ipc_callid_t cid; 74 79 75 80 size_t len; 76 81 if (!async_data_read_receive(&cid, &len)) { 77 / / TODO handle protocol error82 /* TODO handle protocol error. */ 78 83 ipc_answer_0(callid, EINVAL); 79 84 return; … … 86 91 } 87 92 88 if (len > MAX_CHAR_RW_COUNT) {93 if (len > MAX_CHAR_RW_COUNT) 89 94 len = MAX_CHAR_RW_COUNT; 90 }91 95 92 96 char buf[MAX_CHAR_RW_COUNT]; 93 97 int ret = (*char_iface->read)(dev, buf, len); 94 98 95 if (ret < 0) { // some error occured 99 if (ret < 0) { 100 /* Some error occured. */ 96 101 async_data_read_finalize(cid, buf, 0); 97 102 ipc_answer_0(callid, ret); … … 99 104 } 100 105 101 / / the operation was successful, return the number of data read106 /* The operation was successful, return the number of data read. */ 102 107 async_data_read_finalize(cid, buf, ret); 103 ipc_answer_1(callid, EOK, ret); 108 ipc_answer_1(callid, EOK, ret); 104 109 } 105 110 106 111 /** Process the write request from the remote client. 107 * 108 * Receive the write request's parameters from the remote client and pass them to the local interface. 109 * Return the result of the operation processed by the local interface to the remote client. 110 * 111 * @param dev the device to which the data are written. 112 * @param iface the local interface structure. 112 * 113 * Receive the write request's parameters from the remote client and pass them 114 * to the local interface. Return the result of the operation processed by the 115 * local interface to the remote client. 116 * 117 * @param dev The device to which the data are written. 118 * @param iface The local interface structure. 113 119 */ 114 static void remote_char_write(device_t *dev, void *iface, ipc_callid_t callid, ipc_call_t *call) 120 static void 121 remote_char_write(device_t *dev, void *iface, ipc_callid_t callid, 122 ipc_call_t *call) 115 123 { 116 char_iface_t *char_iface = (char_iface_t *) iface;124 char_iface_t *char_iface = (char_iface_t *) iface; 117 125 ipc_callid_t cid; 118 126 size_t len; 119 127 120 128 if (!async_data_write_receive(&cid, &len)) { 121 / / TODO handle protocol error129 /* TODO handle protocol error. */ 122 130 ipc_answer_0(callid, EINVAL); 123 131 return; 124 132 } 125 133 126 134 if (!char_iface->write) { … … 130 138 } 131 139 132 if (len > MAX_CHAR_RW_COUNT) {140 if (len > MAX_CHAR_RW_COUNT) 133 141 len = MAX_CHAR_RW_COUNT; 134 }135 142 136 143 char buf[MAX_CHAR_RW_COUNT]; … … 139 146 140 147 int ret = (*char_iface->write)(dev, buf, len); 141 if (ret < 0) { // some error occured 148 if (ret < 0) { 149 /* Some error occured. */ 142 150 ipc_answer_0(callid, ret); 143 151 } else { 144 // the operation was successful, return the number of data written 152 /* 153 * The operation was successful, return the number of data 154 * written. 155 */ 145 156 ipc_answer_1(callid, EOK, ret); 146 157 } 147 158 } 148 159 149 160 /** 150 161 * @} 151 162 */ -
uspace/lib/drv/generic/remote_res.c
ra79d88d r7a252ec8 1 1 /* 2 * Copyright (c) 2010 Lenka Trochtova 2 * Copyright (c) 2010 Lenka Trochtova 3 3 * All rights reserved. 4 4 * … … 40 40 #include "resource.h" 41 41 42 43 static void remote_res_get_resources(device_t *dev, void *iface, ipc_callid_t callid, ipc_call_t *call); 44 static void remote_res_enable_interrupt(device_t *dev, void *iface, ipc_callid_t callid, ipc_call_t *call); 42 static void remote_res_get_resources(device_t *, void *, ipc_callid_t, 43 ipc_call_t *); 44 static void remote_res_enable_interrupt(device_t *, void *, ipc_callid_t, 45 ipc_call_t *); 45 46 46 47 static remote_iface_func_ptr_t remote_res_iface_ops [] = { 47 48 &remote_res_get_resources, 48 &remote_res_enable_interrupt 49 }; 50 49 &remote_res_enable_interrupt 50 }; 51 51 52 remote_iface_t remote_res_iface = { 52 .method_count = sizeof(remote_res_iface_ops) / sizeof(remote_iface_func_ptr_t), 53 .method_count = sizeof(remote_res_iface_ops) / 54 sizeof(remote_iface_func_ptr_t), 53 55 .methods = remote_res_iface_ops 54 56 }; 55 57 56 static void remote_res_enable_interrupt(device_t *dev, void *iface, ipc_callid_t callid, ipc_call_t *call) 58 static void remote_res_enable_interrupt(device_t *dev, void *iface, 59 ipc_callid_t callid, ipc_call_t *call) 57 60 { 58 resource_iface_t *ires = (resource_iface_t *) iface;61 resource_iface_t *ires = (resource_iface_t *) iface; 59 62 60 if (NULL == ires->enable_interrupt) {63 if (NULL == ires->enable_interrupt) 61 64 ipc_answer_0(callid, ENOTSUP); 62 } else if (ires->enable_interrupt(dev)) {65 else if (ires->enable_interrupt(dev)) 63 66 ipc_answer_0(callid, EOK); 64 } else {67 else 65 68 ipc_answer_0(callid, EREFUSED); 66 }67 69 } 68 70 69 static void remote_res_get_resources(device_t *dev, void *iface, ipc_callid_t callid, ipc_call_t *call) 71 static void remote_res_get_resources(device_t *dev, void *iface, 72 ipc_callid_t callid, ipc_call_t *call) 70 73 { 71 resource_iface_t *ires = (resource_iface_t *) iface;74 resource_iface_t *ires = (resource_iface_t *) iface; 72 75 if (NULL == ires->get_resources) { 73 76 ipc_answer_0(callid, ENOTSUP); … … 75 78 } 76 79 77 hw_resource_list_t *hw_resources = ires->get_resources(dev); 80 hw_resource_list_t *hw_resources = ires->get_resources(dev); 78 81 if (NULL == hw_resources){ 79 82 ipc_answer_0(callid, ENOENT); … … 85 88 size_t len; 86 89 if (!async_data_read_receive(&callid, &len)) { 87 / / protocol error - the recipient is not accepting data90 /* protocol error - the recipient is not accepting data */ 88 91 return; 89 92 } 90 93 async_data_read_finalize(callid, hw_resources->resources, len); 91 94 } 92 93 94 /** 95 96 /** 95 97 * @} 96 98 */
Note:
See TracChangeset
for help on using the changeset viewer.