Changeset eb522e8 in mainline for uspace/lib/c/generic/devman.c
- Timestamp:
- 2011-06-01T08:43:42Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8d6c1f1
- Parents:
- 9e2e715 (diff), e51a514 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/devman.c
r9e2e715 reb522e8 28 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 29 */ 30 31 30 31 /** @addtogroup libc 32 32 * @{ 33 33 */ … … 37 37 #include <str.h> 38 38 #include <stdio.h> 39 #include <ipc/ipc.h>40 39 #include <ipc/services.h> 41 40 #include <ipc/devman.h> 42 41 #include <devman.h> 43 42 #include <async.h> 43 #include <fibril_synch.h> 44 44 #include <errno.h> 45 45 #include <malloc.h> … … 50 50 static int devman_phone_client = -1; 51 51 52 static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex); 53 52 54 int devman_get_phone(devman_interface_t iface, unsigned int flags) 53 55 { 54 56 switch (iface) { 55 57 case DEVMAN_DRIVER: 56 if (devman_phone_driver >= 0) 58 fibril_mutex_lock(&devman_phone_mutex); 59 if (devman_phone_driver >= 0) { 60 fibril_mutex_unlock(&devman_phone_mutex); 57 61 return devman_phone_driver; 62 } 58 63 59 64 if (flags & IPC_FLAG_BLOCKING) 60 devman_phone_driver = ipc_connect_me_to_blocking(PHONE_NS,61 SERVICE_DEVMAN, DEVMAN_DRIVER, 0);65 devman_phone_driver = async_connect_me_to_blocking( 66 PHONE_NS, SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 62 67 else 63 devman_phone_driver = ipc_connect_me_to(PHONE_NS,68 devman_phone_driver = async_connect_me_to(PHONE_NS, 64 69 SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 65 70 71 fibril_mutex_unlock(&devman_phone_mutex); 66 72 return devman_phone_driver; 67 73 case DEVMAN_CLIENT: 68 if (devman_phone_client >= 0) 74 fibril_mutex_lock(&devman_phone_mutex); 75 if (devman_phone_client >= 0) { 76 fibril_mutex_unlock(&devman_phone_mutex); 69 77 return devman_phone_client; 78 } 70 79 71 if (flags & IPC_FLAG_BLOCKING) 72 devman_phone_client = ipc_connect_me_to_blocking(PHONE_NS, 80 if (flags & IPC_FLAG_BLOCKING) { 81 devman_phone_client = async_connect_me_to_blocking( 82 PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 83 } else { 84 devman_phone_client = async_connect_me_to(PHONE_NS, 73 85 SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 74 else 75 devman_phone_client = ipc_connect_me_to(PHONE_NS, 76 SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 86 } 77 87 88 fibril_mutex_unlock(&devman_phone_mutex); 78 89 return devman_phone_client; 79 90 default: … … 95 106 aid_t req = async_send_2(phone, DEVMAN_DRIVER_REGISTER, 0, 0, &answer); 96 107 97 ipcarg_t retval = async_data_write_start(phone, name, str_size(name));108 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 98 109 if (retval != EOK) { 99 110 async_wait_for(req, NULL); … … 104 115 async_set_client_connection(conn); 105 116 106 ipcarg_t callback_phonehash; 107 ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash); 117 async_connect_to_me(phone, 0, 0, 0, NULL); 108 118 async_wait_for(req, &retval); 109 119 … … 113 123 } 114 124 115 static int devman_send_match_id(int phone, match_id_t *match_id) \ 116 { 117 ipc_call_t answer; 118 async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer); 119 int retval = async_data_write_start(phone, match_id->id, str_size(match_id->id)); 120 return retval; 121 } 122 123 124 static int devman_send_match_ids(int phone, match_id_list_t *match_ids) 125 static int devman_send_match_id(int phone, match_id_t *match_id) 126 { 127 ipc_call_t answer; 128 129 aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, 130 &answer); 131 int retval = async_data_write_start(phone, match_id->id, 132 str_size(match_id->id)); 133 134 async_wait_for(req, NULL); 135 return retval; 136 } 137 138 139 static int devman_send_match_ids(int phone, match_id_list_t *match_ids) 125 140 { 126 141 link_t *link = match_ids->ids.next; 127 142 match_id_t *match_id = NULL; 128 143 int ret = EOK; 129 144 130 145 while (link != &match_ids->ids) { 131 146 match_id = list_get_instance(link, match_id_t, link); 132 if (EOK != (ret = devman_send_match_id(phone, match_id)))133 {134 printf("Driver failed to send match id, error number = %d\n", ret);135 return ret;136 } 147 ret = devman_send_match_id(phone, match_id); 148 if (ret != EOK) { 149 return ret; 150 } 151 137 152 link = link->next; 138 153 } 139 return ret; 140 } 141 142 int devman_child_device_register( 143 const char *name, match_id_list_t *match_ids, device_handle_t parent_handle, device_handle_t *handle) 144 { 154 155 return ret; 156 } 157 158 /** Add function to a device. 159 * 160 * Request devman to add a new function to the specified device owned by 161 * this driver task. 162 * 163 * @param name Name of the new function 164 * @param ftype Function type, fun_inner or fun_exposed 165 * @param match_ids Match IDs (should be empty for fun_exposed) 166 * @param devh Devman handle of the device 167 * @param funh Place to store handle of the new function 168 * 169 * @return EOK on success or negative error code. 170 */ 171 int devman_add_function(const char *name, fun_type_t ftype, 172 match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh) 173 { 145 174 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING); 146 147 if (phone < 0) 148 return phone; 149 150 async_serialize_start(); 151 152 int match_count = list_count(&match_ids->ids); 153 ipc_call_t answer; 154 aid_t req = async_send_2(phone, DEVMAN_ADD_CHILD_DEVICE, parent_handle, match_count, &answer); 155 156 ipcarg_t retval = async_data_write_start(phone, name, str_size(name)); 157 if (retval != EOK) { 158 async_wait_for(req, NULL); 159 async_serialize_end(); 160 return retval; 161 } 162 163 devman_send_match_ids(phone, match_ids); 175 int fun_handle; 176 177 if (phone < 0) 178 return phone; 179 180 async_serialize_start(); 181 182 int match_count = list_count(&match_ids->ids); 183 ipc_call_t answer; 184 185 aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype, 186 devh, match_count, &answer); 187 188 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 189 if (retval != EOK) { 190 async_wait_for(req, NULL); 191 async_serialize_end(); 192 return retval; 193 } 194 195 int match_ids_rc = devman_send_match_ids(phone, match_ids); 164 196 165 197 async_wait_for(req, &retval); … … 167 199 async_serialize_end(); 168 200 169 if (retval != EOK) { 170 if (handle != NULL) { 171 *handle = -1; 172 } 173 return retval; 174 } 175 176 if (handle != NULL) 177 *handle = (int) IPC_GET_ARG1(answer); 178 179 return retval; 180 } 181 182 int devman_add_device_to_class(device_handle_t dev_handle, const char *class_name) 201 /* Prefer the answer to DEVMAN_ADD_FUNCTION in case of errors. */ 202 if ((match_ids_rc != EOK) && (retval == EOK)) { 203 retval = match_ids_rc; 204 } 205 206 if (retval == EOK) 207 fun_handle = (int) IPC_GET_ARG1(answer); 208 else 209 fun_handle = -1; 210 211 *funh = fun_handle; 212 213 return retval; 214 } 215 216 int devman_add_device_to_class(devman_handle_t devman_handle, 217 const char *class_name) 183 218 { 184 219 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING); … … 189 224 async_serialize_start(); 190 225 ipc_call_t answer; 191 aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS, dev_handle, &answer); 192 193 ipcarg_t retval = async_data_write_start(phone, class_name, str_size(class_name)); 226 aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS, 227 devman_handle, &answer); 228 229 sysarg_t retval = async_data_write_start(phone, class_name, 230 str_size(class_name)); 194 231 if (retval != EOK) { 195 232 async_wait_for(req, NULL); … … 201 238 async_serialize_end(); 202 239 203 return retval; 240 return retval; 204 241 } 205 242 … … 209 246 case DEVMAN_DRIVER: 210 247 if (devman_phone_driver >= 0) { 211 ipc_hangup(devman_phone_driver);248 async_hangup(devman_phone_driver); 212 249 devman_phone_driver = -1; 213 250 } … … 215 252 case DEVMAN_CLIENT: 216 253 if (devman_phone_client >= 0) { 217 ipc_hangup(devman_phone_client);254 async_hangup(devman_phone_client); 218 255 devman_phone_client = -1; 219 256 } … … 224 261 } 225 262 226 int devman_device_connect(dev ice_handle_t handle, unsigned int flags)263 int devman_device_connect(devman_handle_t handle, unsigned int flags) 227 264 { 228 265 int phone; 229 266 230 267 if (flags & IPC_FLAG_BLOCKING) { 231 phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,268 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN, 232 269 DEVMAN_CONNECT_TO_DEVICE, handle); 233 270 } else { 234 phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAN,271 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN, 235 272 DEVMAN_CONNECT_TO_DEVICE, handle); 236 273 } … … 239 276 } 240 277 241 int devman_parent_device_connect(dev ice_handle_t handle, unsigned int flags)278 int devman_parent_device_connect(devman_handle_t handle, unsigned int flags) 242 279 { 243 280 int phone; 244 281 245 282 if (flags & IPC_FLAG_BLOCKING) { 246 phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,283 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN, 247 284 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 248 285 } else { 249 phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAN,286 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN, 250 287 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 251 288 } … … 254 291 } 255 292 256 int devman_device_get_handle(const char *pathname, device_handle_t *handle, unsigned int flags) 293 int devman_device_get_handle(const char *pathname, devman_handle_t *handle, 294 unsigned int flags) 257 295 { 258 296 int phone = devman_get_phone(DEVMAN_CLIENT, flags); … … 267 305 &answer); 268 306 269 ipcarg_t retval = async_data_write_start(phone, pathname, str_size(pathname)); 307 sysarg_t retval = async_data_write_start(phone, pathname, 308 str_size(pathname)); 270 309 if (retval != EOK) { 271 310 async_wait_for(req, NULL); … … 280 319 if (retval != EOK) { 281 320 if (handle != NULL) 282 *handle = (dev ice_handle_t) -1;321 *handle = (devman_handle_t) -1; 283 322 return retval; 284 323 } 285 324 286 325 if (handle != NULL) 287 *handle = (device_handle_t) IPC_GET_ARG1(answer); 288 289 return retval; 326 *handle = (devman_handle_t) IPC_GET_ARG1(answer); 327 328 return retval; 329 } 330 331 int devman_device_get_handle_by_class(const char *classname, 332 const char *devname, devman_handle_t *handle, unsigned int flags) 333 { 334 int phone = devman_get_phone(DEVMAN_CLIENT, flags); 335 336 if (phone < 0) 337 return phone; 338 339 async_serialize_start(); 340 341 ipc_call_t answer; 342 aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS, 343 flags, &answer); 344 345 sysarg_t retval = async_data_write_start(phone, classname, 346 str_size(classname)); 347 if (retval != EOK) { 348 async_wait_for(req, NULL); 349 async_serialize_end(); 350 return retval; 351 } 352 retval = async_data_write_start(phone, devname, 353 str_size(devname)); 354 if (retval != EOK) { 355 async_wait_for(req, NULL); 356 async_serialize_end(); 357 return retval; 358 } 359 360 async_wait_for(req, &retval); 361 362 async_serialize_end(); 363 364 if (retval != EOK) { 365 if (handle != NULL) 366 *handle = (devman_handle_t) -1; 367 return retval; 368 } 369 370 if (handle != NULL) 371 *handle = (devman_handle_t) IPC_GET_ARG1(answer); 372 373 return retval; 374 } 375 376 int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size) 377 { 378 int phone = devman_get_phone(DEVMAN_CLIENT, 0); 379 380 if (phone < 0) 381 return phone; 382 383 async_serialize_start(); 384 385 ipc_call_t answer; 386 aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_DEVICE_PATH, 387 handle, &answer); 388 389 ipc_call_t data_request_call; 390 aid_t data_request = async_data_read(phone, path, path_size, 391 &data_request_call); 392 if (data_request == 0) { 393 async_wait_for(req, NULL); 394 async_serialize_end(); 395 return ENOMEM; 396 } 397 398 sysarg_t data_request_rc; 399 sysarg_t opening_request_rc; 400 async_wait_for(data_request, &data_request_rc); 401 async_wait_for(req, &opening_request_rc); 402 403 async_serialize_end(); 404 405 if (data_request_rc != EOK) { 406 /* Prefer the return code of the opening request. */ 407 if (opening_request_rc != EOK) { 408 return (int) opening_request_rc; 409 } else { 410 return (int) data_request_rc; 411 } 412 } 413 if (opening_request_rc != EOK) { 414 return (int) opening_request_rc; 415 } 416 417 /* To be on the safe-side. */ 418 path[path_size - 1] = 0; 419 420 size_t transferred_size = IPC_GET_ARG2(data_request_call); 421 422 if (transferred_size >= path_size) { 423 return ELIMIT; 424 } 425 426 /* Terminate the string (trailing 0 not send over IPC). */ 427 path[transferred_size] = 0; 428 429 return EOK; 290 430 } 291 431
Note:
See TracChangeset
for help on using the changeset viewer.