Changeset f9b2cb4c in mainline for uspace/srv/devman/main.c
- Timestamp:
- 2015-08-23T12:50:23Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9ef495f
- Parents:
- 0dd16778
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/main.c
r0dd16778 rf9b2cb4c 49 49 #include <io/log.h> 50 50 #include <ipc/devman.h> 51 #include <ipc/driver.h>52 51 #include <loc.h> 53 52 … … 66 65 dev_tree_t device_tree; 67 66 68 static void devman_ forward(ipc_callid_t iid, ipc_call_t *icall,69 bool drv_to_parent)67 static void devman_connection_device(ipc_callid_t iid, ipc_call_t *icall, 68 void *arg) 70 69 { 71 70 devman_handle_t handle = IPC_GET_ARG2(*icall); 72 devman_handle_t fwd_h;73 fun_node_t *fun = NULL;74 71 dev_node_t *dev = NULL; 75 72 76 fun = find_fun_node(&device_tree, handle);77 if (fun == NULL) 73 fun_node_t *fun = find_fun_node(&device_tree, handle); 74 if (fun == NULL) { 78 75 dev = find_dev_node(&device_tree, handle); 79 else {76 } else { 80 77 fibril_rwlock_read_lock(&device_tree.rwlock); 78 81 79 dev = fun->dev; 82 80 if (dev != NULL) 83 81 dev_add_ref(dev); 82 84 83 fibril_rwlock_read_unlock(&device_tree.rwlock); 85 84 } 86 85 87 86 /* 88 87 * For a valid function to connect to we need a device. The root … … 97 96 goto cleanup; 98 97 } 99 100 if (fun == NULL && !drv_to_parent) {98 99 if (fun == NULL) { 101 100 log_msg(LOG_DEFAULT, LVL_ERROR, NAME ": devman_forward error - cannot " 102 101 "connect to handle %" PRIun ", refers to a device.", … … 106 105 } 107 106 108 driver_t *driver = NULL;109 110 107 fibril_rwlock_read_lock(&device_tree.rwlock); 111 108 112 if (drv_to_parent) { 113 /* Connect to parent function of a device (or device function). */ 114 if (dev->pfun->dev != NULL) 115 driver = dev->pfun->dev->drv; 116 117 fwd_h = dev->pfun->handle; 118 } else { 119 /* Connect to the specified function */ 120 driver = dev->drv; 121 fwd_h = handle; 122 } 109 /* Connect to the specified function */ 110 driver_t *driver = dev->drv; 123 111 124 112 fibril_rwlock_read_unlock(&device_tree.rwlock); … … 130 118 goto cleanup; 131 119 } 132 133 int method;134 if (drv_to_parent)135 method = DRIVER_DRIVER;136 else137 method = DRIVER_CLIENT;138 120 139 121 if (!driver->sess) { … … 143 125 goto cleanup; 144 126 } 145 127 146 128 if (fun != NULL) { 147 129 log_msg(LOG_DEFAULT, LVL_DEBUG, … … 155 137 156 138 async_exch_t *exch = async_exchange_begin(driver->sess); 157 async_forward_fast(iid, exch, method, fwd_h, 0, IPC_FF_NONE);139 async_forward_fast(iid, exch, INTERFACE_DDF_CLIENT, handle, 0, IPC_FF_NONE); 158 140 async_exchange_end(exch); 159 141 … … 166 148 } 167 149 168 /** Function for handling connections from a client forwarded by the location 169 * service to the device manager. */ 170 static void devman_connection_loc(ipc_callid_t iid, ipc_call_t *icall) 171 { 150 static void devman_connection_parent(ipc_callid_t iid, ipc_call_t *icall, 151 void *arg) 152 { 153 devman_handle_t handle = IPC_GET_ARG2(*icall); 154 dev_node_t *dev = NULL; 155 156 fun_node_t *fun = find_fun_node(&device_tree, handle); 157 if (fun == NULL) { 158 dev = find_dev_node(&device_tree, handle); 159 } else { 160 fibril_rwlock_read_lock(&device_tree.rwlock); 161 162 dev = fun->dev; 163 if (dev != NULL) 164 dev_add_ref(dev); 165 166 fibril_rwlock_read_unlock(&device_tree.rwlock); 167 } 168 169 /* 170 * For a valid function to connect to we need a device. The root 171 * function, for example, has no device and cannot be connected to. 172 * This means @c dev needs to be valid regardless whether we are 173 * connecting to a device or to a function. 174 */ 175 if (dev == NULL) { 176 log_msg(LOG_DEFAULT, LVL_ERROR, "IPC forwarding failed - no device or " 177 "function with handle %" PRIun " was found.", handle); 178 async_answer_0(iid, ENOENT); 179 goto cleanup; 180 } 181 182 driver_t *driver = NULL; 183 184 fibril_rwlock_read_lock(&device_tree.rwlock); 185 186 /* Connect to parent function of a device (or device function). */ 187 if (dev->pfun->dev != NULL) 188 driver = dev->pfun->dev->drv; 189 190 devman_handle_t fun_handle = dev->pfun->handle; 191 192 fibril_rwlock_read_unlock(&device_tree.rwlock); 193 194 if (driver == NULL) { 195 log_msg(LOG_DEFAULT, LVL_ERROR, "IPC forwarding refused - " \ 196 "the device %" PRIun " is not in usable state.", handle); 197 async_answer_0(iid, ENOENT); 198 goto cleanup; 199 } 200 201 if (!driver->sess) { 202 log_msg(LOG_DEFAULT, LVL_ERROR, 203 "Could not forward to driver `%s'.", driver->name); 204 async_answer_0(iid, EINVAL); 205 goto cleanup; 206 } 207 208 if (fun != NULL) { 209 log_msg(LOG_DEFAULT, LVL_DEBUG, 210 "Forwarding request for `%s' function to driver `%s'.", 211 fun->pathname, driver->name); 212 } else { 213 log_msg(LOG_DEFAULT, LVL_DEBUG, 214 "Forwarding request for `%s' device to driver `%s'.", 215 dev->pfun->pathname, driver->name); 216 } 217 218 async_exch_t *exch = async_exchange_begin(driver->sess); 219 async_forward_fast(iid, exch, INTERFACE_DDF_DRIVER, fun_handle, 0, IPC_FF_NONE); 220 async_exchange_end(exch); 221 222 cleanup: 223 if (dev != NULL) 224 dev_del_ref(dev); 225 226 if (fun != NULL) 227 fun_del_ref(fun); 228 } 229 230 static void devman_forward(ipc_callid_t iid, ipc_call_t *icall, void *arg) 231 { 232 iface_t iface = IPC_GET_ARG1(*icall); 172 233 service_id_t service_id = IPC_GET_ARG2(*icall); 173 fun_node_t *fun; 174 dev_node_t *dev; 175 devman_handle_t handle; 176 driver_t *driver; 177 178 fun = find_loc_tree_function(&device_tree, service_id); 234 235 fun_node_t *fun = find_loc_tree_function(&device_tree, service_id); 179 236 180 237 fibril_rwlock_read_lock(&device_tree.rwlock); 181 238 182 if ( fun == NULL || fun->dev == NULL || fun->dev->drv == NULL) {183 log_msg(LOG_DEFAULT, LVL_WARN, "devman_ connection_loc(): function "239 if ((fun == NULL) || (fun->dev == NULL) || (fun->dev->drv == NULL)) { 240 log_msg(LOG_DEFAULT, LVL_WARN, "devman_forward(): function " 184 241 "not found.\n"); 185 242 fibril_rwlock_read_unlock(&device_tree.rwlock); … … 188 245 } 189 246 190 dev = fun->dev;191 driver = dev->drv;192 handle = fun->handle;247 dev_node_t *dev = fun->dev; 248 driver_t *driver = dev->drv; 249 devman_handle_t handle = fun->handle; 193 250 194 251 fibril_rwlock_read_unlock(&device_tree.rwlock); 195 252 196 253 async_exch_t *exch = async_exchange_begin(driver->sess); 197 async_forward_fast(iid, exch, DRIVER_CLIENT, handle, 0, 198 IPC_FF_NONE); 254 async_forward_fast(iid, exch, iface, handle, 0, IPC_FF_NONE); 199 255 async_exchange_end(exch); 200 256 201 257 log_msg(LOG_DEFAULT, LVL_DEBUG, 202 "Forwarding locservice request for `%s' function to driver `%s'.",258 "Forwarding service request for `%s' function to driver `%s'.", 203 259 fun->pathname, driver->name); 204 260 205 261 fun_del_ref(fun); 206 }207 208 /** Function for handling connections to device manager. */209 static void devman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)210 {211 /* Select port. */212 switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {213 case DEVMAN_DRIVER:214 devman_connection_driver(iid, icall);215 break;216 case DEVMAN_CLIENT:217 devman_connection_client(iid, icall);218 break;219 case DEVMAN_CONNECT_TO_DEVICE:220 /* Connect client to selected device. */221 devman_forward(iid, icall, false);222 break;223 case INTERFACE_DDF_CLIENT:224 /* Someone connected through loc node. */225 devman_connection_loc(iid, icall);226 break;227 case DEVMAN_CONNECT_TO_PARENTS_DEVICE:228 /* Connect client to selected device. */229 devman_forward(iid, icall, true);230 break;231 default:232 /* No such interface */233 async_answer_0(iid, ENOENT);234 }235 262 } 236 263 … … 298 325 async_set_client_data_constructor(devman_client_data_create); 299 326 async_set_client_data_destructor(devman_client_data_destroy); 300 async_set_fallback_port_handler(devman_connection, NULL); 327 328 port_id_t port; 329 rc = async_create_port(INTERFACE_DDF_DRIVER, 330 devman_connection_driver, NULL, &port); 331 if (rc != EOK) 332 return rc; 333 334 rc = async_create_port(INTERFACE_DDF_CLIENT, 335 devman_connection_client, NULL, &port); 336 if (rc != EOK) 337 return rc; 338 339 rc = async_create_port(INTERFACE_DEVMAN_DEVICE, 340 devman_connection_device, NULL, &port); 341 if (rc != EOK) 342 return rc; 343 344 rc = async_create_port(INTERFACE_DEVMAN_PARENT, 345 devman_connection_parent, NULL, &port); 346 if (rc != EOK) 347 return rc; 348 349 async_set_fallback_port_handler(devman_forward, NULL); 301 350 302 351 if (!devman_init()) {
Note:
See TracChangeset
for help on using the changeset viewer.