Changeset 41811af in mainline for uspace/lib/c/generic/devmap.c
- Timestamp:
- 2011-06-10T10:14:26Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ab547063
- Parents:
- 9536e6e (diff), 390d80d (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/devmap.c
r9536e6e r41811af 30 30 #include <str.h> 31 31 #include <ipc/services.h> 32 #include < ipc/ns.h>32 #include <ns.h> 33 33 #include <ipc/devmap.h> 34 34 #include <devmap.h> 35 #include <fibril_synch.h> 35 36 #include <async.h> 36 37 #include <errno.h> … … 38 39 #include <bool.h> 39 40 40 static int devmap_phone_driver = -1; 41 static int devmap_phone_client = -1; 42 43 /** Get phone to device mapper task. */ 44 int devmap_get_phone(devmap_interface_t iface, unsigned int flags) 41 static FIBRIL_MUTEX_INITIALIZE(devmap_driver_block_mutex); 42 static FIBRIL_MUTEX_INITIALIZE(devmap_client_block_mutex); 43 44 static FIBRIL_MUTEX_INITIALIZE(devmap_driver_mutex); 45 static FIBRIL_MUTEX_INITIALIZE(devmap_client_mutex); 46 47 static async_sess_t *devmap_driver_block_sess = NULL; 48 static async_sess_t *devmap_client_block_sess = NULL; 49 50 static async_sess_t *devmap_driver_sess = NULL; 51 static async_sess_t *devmap_client_sess = NULL; 52 53 static void clone_session(fibril_mutex_t *mtx, async_sess_t *src, 54 async_sess_t **dst) 55 { 56 fibril_mutex_lock(mtx); 57 58 if ((*dst == NULL) && (src != NULL)) 59 *dst = src; 60 61 fibril_mutex_unlock(mtx); 62 } 63 64 /** Start an async exchange on the devmap session (blocking). 65 * 66 * @param iface Device mapper interface to choose 67 * 68 * @return New exchange. 69 * 70 */ 71 async_exch_t *devmap_exchange_begin_blocking(devmap_interface_t iface) 45 72 { 46 73 switch (iface) { 47 74 case DEVMAP_DRIVER: 48 if (devmap_phone_driver >= 0) 49 return devmap_phone_driver; 50 51 if (flags & IPC_FLAG_BLOCKING) 52 devmap_phone_driver = service_connect_blocking(SERVICE_DEVMAP, 53 DEVMAP_DRIVER, 0); 54 else 55 devmap_phone_driver = service_connect(SERVICE_DEVMAP, 56 DEVMAP_DRIVER, 0); 57 58 return devmap_phone_driver; 75 fibril_mutex_lock(&devmap_driver_block_mutex); 76 77 while (devmap_driver_block_sess == NULL) { 78 clone_session(&devmap_driver_mutex, devmap_driver_sess, 79 &devmap_driver_block_sess); 80 81 if (devmap_driver_block_sess == NULL) 82 devmap_driver_block_sess = 83 service_connect_blocking(EXCHANGE_SERIALIZE, 84 SERVICE_DEVMAP, DEVMAP_DRIVER, 0); 85 } 86 87 fibril_mutex_unlock(&devmap_driver_block_mutex); 88 89 clone_session(&devmap_driver_mutex, devmap_driver_block_sess, 90 &devmap_driver_sess); 91 92 return async_exchange_begin(devmap_driver_block_sess); 59 93 case DEVMAP_CLIENT: 60 if (devmap_phone_client >= 0) 61 return devmap_phone_client; 62 63 if (flags & IPC_FLAG_BLOCKING) 64 devmap_phone_client = service_connect_blocking(SERVICE_DEVMAP, 65 DEVMAP_CLIENT, 0); 66 else 67 devmap_phone_client = service_connect(SERVICE_DEVMAP, 68 DEVMAP_CLIENT, 0); 69 70 return devmap_phone_client; 94 fibril_mutex_lock(&devmap_client_block_mutex); 95 96 while (devmap_client_block_sess == NULL) { 97 clone_session(&devmap_client_mutex, devmap_client_sess, 98 &devmap_client_block_sess); 99 100 if (devmap_client_block_sess == NULL) 101 devmap_client_block_sess = 102 service_connect_blocking(EXCHANGE_SERIALIZE, 103 SERVICE_DEVMAP, DEVMAP_CLIENT, 0); 104 } 105 106 fibril_mutex_unlock(&devmap_client_block_mutex); 107 108 clone_session(&devmap_client_mutex, devmap_client_block_sess, 109 &devmap_client_sess); 110 111 return async_exchange_begin(devmap_client_block_sess); 71 112 default: 72 return -1; 73 } 74 } 75 76 void devmap_hangup_phone(devmap_interface_t iface) 113 return NULL; 114 } 115 } 116 117 /** Start an async exchange on the devmap session. 118 * 119 * @param iface Device mapper interface to choose 120 * 121 * @return New exchange. 122 * 123 */ 124 async_exch_t *devmap_exchange_begin(devmap_interface_t iface) 77 125 { 78 126 switch (iface) { 79 127 case DEVMAP_DRIVER: 80 if (devmap_phone_driver >= 0) { 81 async_hangup(devmap_phone_driver); 82 devmap_phone_driver = -1; 83 } 84 break; 128 fibril_mutex_lock(&devmap_driver_mutex); 129 130 if (devmap_driver_sess == NULL) 131 devmap_driver_sess = 132 service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAP, 133 DEVMAP_DRIVER, 0); 134 135 fibril_mutex_unlock(&devmap_driver_mutex); 136 137 if (devmap_driver_sess == NULL) 138 return NULL; 139 140 return async_exchange_begin(devmap_driver_sess); 85 141 case DEVMAP_CLIENT: 86 if (devmap_phone_client >= 0) { 87 async_hangup(devmap_phone_client); 88 devmap_phone_client = -1; 89 } 90 break; 142 fibril_mutex_lock(&devmap_client_mutex); 143 144 if (devmap_client_sess == NULL) 145 devmap_client_sess = 146 service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAP, 147 DEVMAP_CLIENT, 0); 148 149 fibril_mutex_unlock(&devmap_client_mutex); 150 151 if (devmap_client_sess == NULL) 152 return NULL; 153 154 return async_exchange_begin(devmap_client_sess); 91 155 default: 92 break; 93 } 156 return NULL; 157 } 158 } 159 160 /** Finish an async exchange on the devmap session. 161 * 162 * @param exch Exchange to be finished. 163 * 164 */ 165 void devmap_exchange_end(async_exch_t *exch) 166 { 167 async_exchange_end(exch); 94 168 } 95 169 … … 97 171 int devmap_driver_register(const char *name, async_client_conn_t conn) 98 172 { 99 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING); 100 101 if (phone < 0) 102 return phone; 103 104 async_serialize_start(); 173 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER); 105 174 106 175 ipc_call_t answer; 107 aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); 108 109 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 176 aid_t req = async_send_2(exch, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); 177 sysarg_t retval = async_data_write_start(exch, name, str_size(name)); 178 179 devmap_exchange_end(exch); 180 110 181 if (retval != EOK) { 111 182 async_wait_for(req, NULL); 112 async_serialize_end(); 113 return -1; 183 return retval; 114 184 } 115 185 116 186 async_set_client_connection(conn); 117 187 118 async_connect_to_me(phone, 0, 0, 0, NULL); 188 exch = devmap_exchange_begin(DEVMAP_DRIVER); 189 async_connect_to_me(exch, 0, 0, 0, NULL); 190 devmap_exchange_end(exch); 191 119 192 async_wait_for(req, &retval); 120 121 async_serialize_end();122 123 193 return retval; 124 194 } … … 129 199 * If not 0, the first argument is the interface and the second argument 130 200 * is the devmap handle of the device. 201 * 131 202 * When the interface is zero (default), the first argument is directly 132 203 * the handle (to ensure backward compatibility). 133 204 * 134 * @param fqdnFully qualified device name.135 * @param[out] handle Handle to the created instance of device.136 * @param interface Interface when forwarding.205 * @param fqdn Fully qualified device name. 206 * @param[out] handle Handle to the created instance of device. 207 * @param interface Interface when forwarding. 137 208 * 138 209 */ … … 140 211 devmap_handle_t *handle, sysarg_t interface) 141 212 { 142 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING); 143 144 if (phone < 0) 145 return phone; 146 147 async_serialize_start(); 213 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER); 148 214 149 215 ipc_call_t answer; 150 aid_t req = async_send_2( phone, DEVMAP_DEVICE_REGISTER, interface, 0,216 aid_t req = async_send_2(exch, DEVMAP_DEVICE_REGISTER, interface, 0, 151 217 &answer); 152 153 sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn)); 218 sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn)); 219 220 devmap_exchange_end(exch); 221 154 222 if (retval != EOK) { 155 223 async_wait_for(req, NULL); 156 async_serialize_end();157 224 return retval; 158 225 } 159 226 160 227 async_wait_for(req, &retval); 161 162 async_serialize_end();163 228 164 229 if (retval != EOK) { 165 230 if (handle != NULL) 166 231 *handle = -1; 232 167 233 return retval; 168 234 } … … 176 242 /** Register new device. 177 243 * 178 * @param fqdn 179 * @param handle 244 * @param fqdn Fully qualified device name. 245 * @param handle Output: Handle to the created instance of device. 180 246 * 181 247 */ … … 185 251 } 186 252 187 188 int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle, unsigned int flags) 189 { 190 int phone = devmap_get_phone(DEVMAP_CLIENT, flags); 191 192 if (phone < 0) 193 return phone; 194 195 async_serialize_start(); 253 int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle, 254 unsigned int flags) 255 { 256 async_exch_t *exch; 257 258 if (flags & IPC_FLAG_BLOCKING) 259 exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 260 else { 261 exch = devmap_exchange_begin(DEVMAP_CLIENT); 262 if (exch == NULL) 263 return errno; 264 } 196 265 197 266 ipc_call_t answer; 198 aid_t req = async_send_2( phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,267 aid_t req = async_send_2(exch, DEVMAP_DEVICE_GET_HANDLE, flags, 0, 199 268 &answer); 200 201 sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn)); 269 sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn)); 270 271 devmap_exchange_end(exch); 272 202 273 if (retval != EOK) { 203 274 async_wait_for(req, NULL); 204 async_serialize_end();205 275 return retval; 206 276 } 207 277 208 278 async_wait_for(req, &retval); 209 210 async_serialize_end();211 279 212 280 if (retval != EOK) { 213 281 if (handle != NULL) 214 282 *handle = (devmap_handle_t) -1; 283 215 284 return retval; 216 285 } … … 222 291 } 223 292 224 int devmap_namespace_get_handle(const char *name, devmap_handle_t *handle, unsigned int flags) 225 { 226 int phone = devmap_get_phone(DEVMAP_CLIENT, flags); 227 228 if (phone < 0) 229 return phone; 230 231 async_serialize_start(); 293 int devmap_namespace_get_handle(const char *name, devmap_handle_t *handle, 294 unsigned int flags) 295 { 296 async_exch_t *exch; 297 298 if (flags & IPC_FLAG_BLOCKING) 299 exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 300 else { 301 exch = devmap_exchange_begin(DEVMAP_CLIENT); 302 if (exch == NULL) 303 return errno; 304 } 232 305 233 306 ipc_call_t answer; 234 aid_t req = async_send_2( phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,307 aid_t req = async_send_2(exch, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0, 235 308 &answer); 236 237 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 309 sysarg_t retval = async_data_write_start(exch, name, str_size(name)); 310 311 devmap_exchange_end(exch); 312 238 313 if (retval != EOK) { 239 314 async_wait_for(req, NULL); 240 async_serialize_end();241 315 return retval; 242 316 } 243 317 244 318 async_wait_for(req, &retval); 245 246 async_serialize_end();247 319 248 320 if (retval != EOK) { 249 321 if (handle != NULL) 250 322 *handle = (devmap_handle_t) -1; 323 251 324 return retval; 252 325 } … … 260 333 devmap_handle_type_t devmap_handle_probe(devmap_handle_t handle) 261 334 { 262 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 263 264 if (phone < 0) 265 return phone; 335 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 266 336 267 337 sysarg_t type; 268 int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type); 338 int retval = async_req_1_1(exch, DEVMAP_HANDLE_PROBE, handle, &type); 339 340 devmap_exchange_end(exch); 341 269 342 if (retval != EOK) 270 343 return DEV_HANDLE_NONE; … … 273 346 } 274 347 275 int devmap_device_connect(devmap_handle_t handle, unsigned int flags) 276 { 277 int phone; 278 279 if (flags & IPC_FLAG_BLOCKING) { 280 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP, 348 async_sess_t *devmap_device_connect(exch_mgmt_t mgmt, devmap_handle_t handle, 349 unsigned int flags) 350 { 351 async_sess_t *sess; 352 353 if (flags & IPC_FLAG_BLOCKING) 354 sess = service_connect_blocking(mgmt, SERVICE_DEVMAP, 281 355 DEVMAP_CONNECT_TO_DEVICE, handle); 282 } else {283 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAP,356 else 357 sess = service_connect(mgmt, SERVICE_DEVMAP, 284 358 DEVMAP_CONNECT_TO_DEVICE, handle); 285 } 286 287 return phone; 359 360 return sess; 288 361 } 289 362 290 363 int devmap_null_create(void) 291 364 { 292 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 293 294 if (phone < 0) 295 return -1; 365 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 296 366 297 367 sysarg_t null_id; 298 int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id); 368 int retval = async_req_0_1(exch, DEVMAP_NULL_CREATE, &null_id); 369 370 devmap_exchange_end(exch); 371 299 372 if (retval != EOK) 300 373 return -1; … … 305 378 void devmap_null_destroy(int null_id) 306 379 { 307 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 308 309 if (phone < 0) 310 return; 311 312 async_req_1_0(phone, DEVMAP_NULL_DESTROY, (sysarg_t) null_id); 313 } 314 315 static size_t devmap_count_namespaces_internal(int phone) 380 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 381 async_req_1_0(exch, DEVMAP_NULL_DESTROY, (sysarg_t) null_id); 382 devmap_exchange_end(exch); 383 } 384 385 static size_t devmap_count_namespaces_internal(async_exch_t *exch) 316 386 { 317 387 sysarg_t count; 318 int retval = async_req_0_1( phone, DEVMAP_GET_NAMESPACE_COUNT, &count);388 int retval = async_req_0_1(exch, DEVMAP_GET_NAMESPACE_COUNT, &count); 319 389 if (retval != EOK) 320 390 return 0; … … 323 393 } 324 394 325 static size_t devmap_count_devices_internal(int phone, devmap_handle_t ns_handle) 395 static size_t devmap_count_devices_internal(async_exch_t *exch, 396 devmap_handle_t ns_handle) 326 397 { 327 398 sysarg_t count; 328 int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count); 399 int retval = async_req_1_1(exch, DEVMAP_GET_DEVICE_COUNT, ns_handle, 400 &count); 329 401 if (retval != EOK) 330 402 return 0; … … 335 407 size_t devmap_count_namespaces(void) 336 408 { 337 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 338 339 if (phone < 0) 340 return 0; 341 342 return devmap_count_namespaces_internal(phone); 409 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 410 size_t size = devmap_count_namespaces_internal(exch); 411 devmap_exchange_end(exch); 412 413 return size; 343 414 } 344 415 345 416 size_t devmap_count_devices(devmap_handle_t ns_handle) 346 417 { 347 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 348 349 if (phone < 0) 350 return 0; 351 352 return devmap_count_devices_internal(phone, ns_handle); 418 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 419 size_t size = devmap_count_devices_internal(exch, ns_handle); 420 devmap_exchange_end(exch); 421 422 return size; 353 423 } 354 424 355 425 size_t devmap_get_namespaces(dev_desc_t **data) 356 426 { 357 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);358 359 if (phone < 0)360 return 0;361 362 427 /* Loop until namespaces read succesful */ 363 428 while (true) { 364 size_t count = devmap_count_namespaces_internal(phone); 429 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 430 size_t count = devmap_count_namespaces_internal(exch); 431 devmap_exchange_end(exch); 432 365 433 if (count == 0) 366 434 return 0; … … 370 438 return 0; 371 439 372 async_serialize_start();440 exch = devmap_exchange_begin(DEVMAP_CLIENT); 373 441 374 442 ipc_call_t answer; 375 aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer); 376 377 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t)); 443 aid_t req = async_send_0(exch, DEVMAP_GET_NAMESPACES, &answer); 444 int rc = async_data_read_start(exch, devs, count * sizeof(dev_desc_t)); 445 446 devmap_exchange_end(exch); 447 378 448 if (rc == EOVERFLOW) { 379 449 /* … … 381 451 * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT 382 452 */ 383 async_serialize_end();384 453 free(devs); 385 454 continue; … … 388 457 if (rc != EOK) { 389 458 async_wait_for(req, NULL); 390 async_serialize_end();391 459 free(devs); 392 460 return 0; … … 395 463 sysarg_t retval; 396 464 async_wait_for(req, &retval); 397 async_serialize_end();398 465 399 466 if (retval != EOK) … … 407 474 size_t devmap_get_devices(devmap_handle_t ns_handle, dev_desc_t **data) 408 475 { 409 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 410 411 if (phone < 0) 412 return 0; 413 414 /* Loop until namespaces read succesful */ 476 /* Loop until devices read succesful */ 415 477 while (true) { 416 size_t count = devmap_count_devices_internal(phone, ns_handle); 478 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 479 size_t count = devmap_count_devices_internal(exch, ns_handle); 480 devmap_exchange_end(exch); 481 417 482 if (count == 0) 418 483 return 0; … … 422 487 return 0; 423 488 424 async_serialize_start();489 exch = devmap_exchange_begin(DEVMAP_CLIENT); 425 490 426 491 ipc_call_t answer; 427 aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer); 428 429 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t)); 492 aid_t req = async_send_1(exch, DEVMAP_GET_DEVICES, ns_handle, &answer); 493 int rc = async_data_read_start(exch, devs, count * sizeof(dev_desc_t)); 494 495 devmap_exchange_end(exch); 496 430 497 if (rc == EOVERFLOW) { 431 498 /* … … 433 500 * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT 434 501 */ 435 async_serialize_end();436 502 free(devs); 437 503 continue; … … 440 506 if (rc != EOK) { 441 507 async_wait_for(req, NULL); 442 async_serialize_end();443 508 free(devs); 444 509 return 0; … … 447 512 sysarg_t retval; 448 513 async_wait_for(req, &retval); 449 async_serialize_end();450 514 451 515 if (retval != EOK)
Note:
See TracChangeset
for help on using the changeset viewer.