Changes in uspace/lib/c/generic/devmap.c [9934f7d:64d2b10] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/devmap.c
r9934f7d r64d2b10 30 30 #include <str.h> 31 31 #include <ipc/services.h> 32 #include < ns.h>32 #include <ipc/ns.h> 33 33 #include <ipc/devmap.h> 34 34 #include <devmap.h> 35 #include <fibril_synch.h>36 35 #include <async.h> 37 36 #include <errno.h> … … 39 38 #include <bool.h> 40 39 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) 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) 72 45 { 73 46 switch (iface) { 74 47 case DEVMAP_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); 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; 93 59 case DEVMAP_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); 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; 112 71 default: 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) 72 return -1; 73 } 74 } 75 76 void devmap_hangup_phone(devmap_interface_t iface) 125 77 { 126 78 switch (iface) { 127 79 case DEVMAP_DRIVER: 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); 80 if (devmap_phone_driver >= 0) { 81 async_hangup(devmap_phone_driver); 82 devmap_phone_driver = -1; 83 } 84 break; 141 85 case DEVMAP_CLIENT: 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); 86 if (devmap_phone_client >= 0) { 87 async_hangup(devmap_phone_client); 88 devmap_phone_client = -1; 89 } 90 break; 155 91 default: 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); 92 break; 93 } 168 94 } 169 95 … … 171 97 int devmap_driver_register(const char *name, async_client_conn_t conn) 172 98 { 173 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER); 99 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING); 100 101 if (phone < 0) 102 return phone; 103 104 async_serialize_start(); 174 105 175 106 ipc_call_t answer; 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 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)); 181 110 if (retval != EOK) { 182 111 async_wait_for(req, NULL); 183 return retval; 112 async_serialize_end(); 113 return -1; 184 114 } 185 115 186 116 async_set_client_connection(conn); 187 117 188 exch = devmap_exchange_begin(DEVMAP_DRIVER); 189 async_connect_to_me(exch, 0, 0, 0, NULL, NULL); 190 devmap_exchange_end(exch); 191 118 async_connect_to_me(phone, 0, 0, 0, NULL); 192 119 async_wait_for(req, &retval); 120 121 async_serialize_end(); 122 193 123 return retval; 194 124 } … … 199 129 * If not 0, the first argument is the interface and the second argument 200 130 * is the devmap handle of the device. 201 *202 131 * When the interface is zero (default), the first argument is directly 203 132 * the handle (to ensure backward compatibility). 204 133 * 205 * @param fqdnFully qualified device name.206 * @param[out] handle 207 * @param 134 * @param fqdn Fully qualified device name. 135 * @param[out] handle Handle to the created instance of device. 136 * @param interface Interface when forwarding. 208 137 * 209 138 */ … … 211 140 devmap_handle_t *handle, sysarg_t interface) 212 141 { 213 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER); 142 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING); 143 144 if (phone < 0) 145 return phone; 146 147 async_serialize_start(); 214 148 215 149 ipc_call_t answer; 216 aid_t req = async_send_2( exch, DEVMAP_DEVICE_REGISTER, interface, 0,150 aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, interface, 0, 217 151 &answer); 218 sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn)); 219 220 devmap_exchange_end(exch); 221 152 153 sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn)); 222 154 if (retval != EOK) { 223 155 async_wait_for(req, NULL); 156 async_serialize_end(); 224 157 return retval; 225 158 } 226 159 227 160 async_wait_for(req, &retval); 161 162 async_serialize_end(); 228 163 229 164 if (retval != EOK) { 230 165 if (handle != NULL) 231 166 *handle = -1; 232 233 167 return retval; 234 168 } … … 242 176 /** Register new device. 243 177 * 244 * @param fqdn Fully qualified device name.245 * @param handle Output: Handle to the created instance of device.178 * @param fqdn Fully qualified device name. 179 * @param handle Output: Handle to the created instance of device. 246 180 * 247 181 */ … … 251 185 } 252 186 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 } 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(); 265 196 266 197 ipc_call_t answer; 267 aid_t req = async_send_2( exch, DEVMAP_DEVICE_GET_HANDLE, flags, 0,198 aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0, 268 199 &answer); 269 sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn)); 270 271 devmap_exchange_end(exch); 272 200 201 sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn)); 273 202 if (retval != EOK) { 274 203 async_wait_for(req, NULL); 204 async_serialize_end(); 275 205 return retval; 276 206 } 277 207 278 208 async_wait_for(req, &retval); 209 210 async_serialize_end(); 279 211 280 212 if (retval != EOK) { 281 213 if (handle != NULL) 282 214 *handle = (devmap_handle_t) -1; 283 284 215 return retval; 285 216 } … … 291 222 } 292 223 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 } 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(); 305 232 306 233 ipc_call_t answer; 307 aid_t req = async_send_2( exch, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,234 aid_t req = async_send_2(phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0, 308 235 &answer); 309 sysarg_t retval = async_data_write_start(exch, name, str_size(name)); 310 311 devmap_exchange_end(exch); 312 236 237 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 313 238 if (retval != EOK) { 314 239 async_wait_for(req, NULL); 240 async_serialize_end(); 315 241 return retval; 316 242 } 317 243 318 244 async_wait_for(req, &retval); 245 246 async_serialize_end(); 319 247 320 248 if (retval != EOK) { 321 249 if (handle != NULL) 322 250 *handle = (devmap_handle_t) -1; 323 324 251 return retval; 325 252 } … … 333 260 devmap_handle_type_t devmap_handle_probe(devmap_handle_t handle) 334 261 { 335 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 262 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 263 264 if (phone < 0) 265 return phone; 336 266 337 267 sysarg_t type; 338 int retval = async_req_1_1(exch, DEVMAP_HANDLE_PROBE, handle, &type); 339 340 devmap_exchange_end(exch); 341 268 int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type); 342 269 if (retval != EOK) 343 270 return DEV_HANDLE_NONE; … … 346 273 } 347 274 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, 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, 355 281 DEVMAP_CONNECT_TO_DEVICE, handle); 356 else357 sess = service_connect(mgmt, SERVICE_DEVMAP,282 } else { 283 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAP, 358 284 DEVMAP_CONNECT_TO_DEVICE, handle); 359 360 return sess; 285 } 286 287 return phone; 361 288 } 362 289 363 290 int devmap_null_create(void) 364 291 { 365 async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT); 292 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 293 294 if (phone < 0) 295 return -1; 366 296 367 297 sysarg_t null_id; 368 int retval = async_req_0_1(exch, DEVMAP_NULL_CREATE, &null_id); 369 370 devmap_exchange_end(exch); 371 298 int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id); 372 299 if (retval != EOK) 373 300 return -1; … … 378 305 void devmap_null_destroy(int null_id) 379 306 { 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) 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) 386 316 { 387 317 sysarg_t count; 388 int retval = async_req_0_1( exch, DEVMAP_GET_NAMESPACE_COUNT, &count);318 int retval = async_req_0_1(phone, DEVMAP_GET_NAMESPACE_COUNT, &count); 389 319 if (retval != EOK) 390 320 return 0; … … 393 323 } 394 324 395 static size_t devmap_count_devices_internal(async_exch_t *exch, 396 devmap_handle_t ns_handle) 325 static size_t devmap_count_devices_internal(int phone, devmap_handle_t ns_handle) 397 326 { 398 327 sysarg_t count; 399 int retval = async_req_1_1(exch, DEVMAP_GET_DEVICE_COUNT, ns_handle, 400 &count); 328 int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count); 401 329 if (retval != EOK) 402 330 return 0; … … 407 335 size_t devmap_count_namespaces(void) 408 336 { 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; 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); 414 343 } 415 344 416 345 size_t devmap_count_devices(devmap_handle_t ns_handle) 417 346 { 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; 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); 423 353 } 424 354 425 355 size_t devmap_get_namespaces(dev_desc_t **data) 426 356 { 357 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 358 359 if (phone < 0) 360 return 0; 361 427 362 /* Loop until namespaces read succesful */ 428 363 while (true) { 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 364 size_t count = devmap_count_namespaces_internal(phone); 433 365 if (count == 0) 434 366 return 0; … … 438 370 return 0; 439 371 440 exch = devmap_exchange_begin(DEVMAP_CLIENT);372 async_serialize_start(); 441 373 442 374 ipc_call_t answer; 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 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)); 448 378 if (rc == EOVERFLOW) { 449 379 /* … … 451 381 * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT 452 382 */ 383 async_serialize_end(); 453 384 free(devs); 454 385 continue; … … 457 388 if (rc != EOK) { 458 389 async_wait_for(req, NULL); 390 async_serialize_end(); 459 391 free(devs); 460 392 return 0; … … 463 395 sysarg_t retval; 464 396 async_wait_for(req, &retval); 397 async_serialize_end(); 465 398 466 399 if (retval != EOK) … … 474 407 size_t devmap_get_devices(devmap_handle_t ns_handle, dev_desc_t **data) 475 408 { 476 /* Loop until devices read succesful */ 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 */ 477 415 while (true) { 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 416 size_t count = devmap_count_devices_internal(phone, ns_handle); 482 417 if (count == 0) 483 418 return 0; … … 487 422 return 0; 488 423 489 exch = devmap_exchange_begin(DEVMAP_CLIENT);424 async_serialize_start(); 490 425 491 426 ipc_call_t answer; 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 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)); 497 430 if (rc == EOVERFLOW) { 498 431 /* … … 500 433 * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT 501 434 */ 435 async_serialize_end(); 502 436 free(devs); 503 437 continue; … … 506 440 if (rc != EOK) { 507 441 async_wait_for(req, NULL); 442 async_serialize_end(); 508 443 free(devs); 509 444 return 0; … … 512 447 sysarg_t retval; 513 448 async_wait_for(req, &retval); 449 async_serialize_end(); 514 450 515 451 if (retval != EOK)
Note:
See TracChangeset
for help on using the changeset viewer.