59
58
/** Opened devices structure */
61
60
devmap_handle_t handle;
61
int phone; /**< When < 0, the structure is incomplete. */
64
fibril_condvar_t cv; /**< Broadcast when completed. */
67
67
/** Hash table of opened devices */
146
147
if (str_cmp(devs[pos].name, component) == 0) {
148
ret = devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle);
148
return devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle);
162
164
for (pos = 0; pos < count; pos++) {
163
165
if (str_cmp(devs[pos].name, component) == 0) {
166
ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
165
return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
184
187
for (pos = 0; pos < count; pos++) {
185
188
if (str_cmp(devs[pos].name, component) == 0) {
189
ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
187
return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);
226
230
unsigned long key[] = {
227
231
[DEVICES_KEY_HANDLE] = (unsigned long) node->handle
230
235
fibril_mutex_lock(&devices_mutex);
231
link_t *lnk = hash_table_find(&devices, key);
237
lnk = hash_table_find(&devices, key);
232
238
if (lnk == NULL) {
233
239
device_t *dev = (device_t *) malloc(sizeof(device_t));
234
240
if (dev == NULL) {
245
dev->handle = node->handle;
246
dev->phone = -1; /* mark as incomplete */
248
fibril_condvar_initialize(&dev->cv);
251
* Insert the incomplete device structure so that other
252
* fibrils will not race with us when we drop the mutex
255
hash_table_insert(&devices, key, &dev->link);
258
* Drop the mutex to allow recursive devfs requests.
260
fibril_mutex_unlock(&devices_mutex);
239
262
int phone = devmap_device_connect(node->handle, 0);
264
fibril_mutex_lock(&devices_mutex);
267
* Notify possible waiters about this device structure
268
* being completed (or destroyed).
270
fibril_condvar_broadcast(&dev->cv);
274
* Connecting failed, need to remove the
275
* entry and free the device structure.
277
hash_table_remove(&devices, key, DEVICES_KEYS);
241
278
fibril_mutex_unlock(&devices_mutex);
246
dev->handle = node->handle;
283
/* Set the correct phone. */
247
284
dev->phone = phone;
250
hash_table_insert(&devices, key, &dev->link);
252
286
device_t *dev = hash_table_get_instance(lnk, device_t, link);
288
if (dev->phone < 0) {
290
* Wait until the device structure is completed
291
* and start from the beginning as the device
292
* structure might have entirely disappeared
293
* while we were not holding the mutex in
294
* fibril_condvar_wait().
296
fibril_condvar_wait(&dev->cv, &devices_mutex);
422
466
sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
424
468
if (retval != EOK) {
425
ipc_answer_0(rid, retval);
469
async_answer_0(rid, retval);
430
ipc_answer_3(rid, EOK, 0, 0, 0);
474
async_answer_3(rid, EOK, 0, 0, 0);
433
477
void devfs_mount(ipc_callid_t rid, ipc_call_t *request)
438
482
void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
440
ipc_answer_0(rid, ENOTSUP);
484
async_answer_0(rid, ENOTSUP);
443
487
void devfs_unmount(ipc_callid_t rid, ipc_call_t *request)
470
514
ipc_callid_t callid;
472
516
if (!async_data_read_receive(&callid, &size)) {
473
ipc_answer_0(callid, EINVAL);
474
ipc_answer_0(rid, EINVAL);
517
async_answer_0(callid, EINVAL);
518
async_answer_0(rid, EINVAL);
492
536
if (pos < count) {
493
537
async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
495
ipc_answer_1(rid, EOK, 1);
539
async_answer_1(rid, EOK, 1);
507
551
if (pos < count) {
508
552
async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
510
ipc_answer_1(rid, EOK, 1);
554
async_answer_1(rid, EOK, 1);
517
ipc_answer_0(callid, ENOENT);
518
ipc_answer_1(rid, ENOENT, 0);
561
async_answer_0(callid, ENOENT);
562
async_answer_1(rid, ENOENT, 0);
526
570
ipc_callid_t callid;
528
572
if (!async_data_read_receive(&callid, &size)) {
529
ipc_answer_0(callid, EINVAL);
530
ipc_answer_0(rid, EINVAL);
573
async_answer_0(callid, EINVAL);
574
async_answer_0(rid, EINVAL);
537
581
if (pos < count) {
538
582
async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
540
ipc_answer_1(rid, EOK, 1);
584
async_answer_1(rid, EOK, 1);
545
ipc_answer_0(callid, ENOENT);
546
ipc_answer_1(rid, ENOENT, 0);
589
async_answer_0(callid, ENOENT);
590
async_answer_1(rid, ENOENT, 0);
558
602
link_t *lnk = hash_table_find(&devices, key);
559
603
if (lnk == NULL) {
560
604
fibril_mutex_unlock(&devices_mutex);
561
ipc_answer_0(rid, ENOENT);
605
async_answer_0(rid, ENOENT);
565
609
device_t *dev = hash_table_get_instance(lnk, device_t, link);
610
assert(dev->phone >= 0);
567
612
ipc_callid_t callid;
568
613
if (!async_data_read_receive(&callid, NULL)) {
569
614
fibril_mutex_unlock(&devices_mutex);
570
ipc_answer_0(callid, EINVAL);
571
ipc_answer_0(rid, EINVAL);
615
async_answer_0(callid, EINVAL);
616
async_answer_0(rid, EINVAL);
579
624
IPC_GET_ARG3(*request), &answer);
581
626
/* Forward the IPC_M_DATA_READ request to the driver */
582
ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
627
async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
583
628
fibril_mutex_unlock(&devices_mutex);
585
630
/* Wait for reply from the driver. */
588
633
size_t bytes = IPC_GET_ARG1(answer);
590
635
/* Driver reply is the final result of the whole operation */
591
ipc_answer_1(rid, rc, bytes);
636
async_answer_1(rid, rc, bytes);
595
ipc_answer_0(rid, ENOENT);
640
async_answer_0(rid, ENOENT);
598
643
void devfs_write(ipc_callid_t rid, ipc_call_t *request)
600
645
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
601
646
if (index == 0) {
602
ipc_answer_0(rid, ENOTSUP);
647
async_answer_0(rid, ENOTSUP);
608
653
if (type == DEV_HANDLE_NAMESPACE) {
609
654
/* Namespace directory */
610
ipc_answer_0(rid, ENOTSUP);
655
async_answer_0(rid, ENOTSUP);
621
666
link_t *lnk = hash_table_find(&devices, key);
622
667
if (lnk == NULL) {
623
668
fibril_mutex_unlock(&devices_mutex);
624
ipc_answer_0(rid, ENOENT);
669
async_answer_0(rid, ENOENT);
628
673
device_t *dev = hash_table_get_instance(lnk, device_t, link);
674
assert(dev->phone >= 0);
630
676
ipc_callid_t callid;
631
677
if (!async_data_write_receive(&callid, NULL)) {
632
678
fibril_mutex_unlock(&devices_mutex);
633
ipc_answer_0(callid, EINVAL);
634
ipc_answer_0(rid, EINVAL);
679
async_answer_0(callid, EINVAL);
680
async_answer_0(rid, EINVAL);
642
688
IPC_GET_ARG3(*request), &answer);
644
690
/* Forward the IPC_M_DATA_WRITE request to the driver */
645
ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
691
async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
647
693
fibril_mutex_unlock(&devices_mutex);
652
698
size_t bytes = IPC_GET_ARG1(answer);
654
700
/* Driver reply is the final result of the whole operation */
655
ipc_answer_1(rid, rc, bytes);
701
async_answer_1(rid, rc, bytes);
659
ipc_answer_0(rid, ENOENT);
705
async_answer_0(rid, ENOENT);
662
708
void devfs_truncate(ipc_callid_t rid, ipc_call_t *request)
664
ipc_answer_0(rid, ENOTSUP);
710
async_answer_0(rid, ENOTSUP);
667
713
void devfs_close(ipc_callid_t rid, ipc_call_t *request)
690
736
link_t *lnk = hash_table_find(&devices, key);
691
737
if (lnk == NULL) {
692
738
fibril_mutex_unlock(&devices_mutex);
693
ipc_answer_0(rid, ENOENT);
739
async_answer_0(rid, ENOENT);
697
743
device_t *dev = hash_table_get_instance(lnk, device_t, link);
744
assert(dev->phone >= 0);
700
747
if (dev->refcount == 0) {
701
ipc_hangup(dev->phone);
748
async_hangup(dev->phone);
702
749
hash_table_remove(&devices, key, DEVICES_KEYS);
705
752
fibril_mutex_unlock(&devices_mutex);
707
ipc_answer_0(rid, EOK);
754
async_answer_0(rid, EOK);
711
ipc_answer_0(rid, ENOENT);
758
async_answer_0(rid, ENOENT);
714
761
void devfs_sync(ipc_callid_t rid, ipc_call_t *request)
737
784
link_t *lnk = hash_table_find(&devices, key);
738
785
if (lnk == NULL) {
739
786
fibril_mutex_unlock(&devices_mutex);
740
ipc_answer_0(rid, ENOENT);
787
async_answer_0(rid, ENOENT);
744
791
device_t *dev = hash_table_get_instance(lnk, device_t, link);
792
assert(dev->phone >= 0);
746
794
/* Make a request at the driver */
747
795
ipc_call_t answer;
755
803
async_wait_for(msg, &rc);
757
805
/* Driver reply is the final result of the whole operation */
758
ipc_answer_0(rid, rc);
806
async_answer_0(rid, rc);
762
ipc_answer_0(rid, ENOENT);
810
async_answer_0(rid, ENOENT);
765
813
void devfs_destroy(ipc_callid_t rid, ipc_call_t *request)
767
ipc_answer_0(rid, ENOTSUP);
815
async_answer_0(rid, ENOTSUP);