Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 47a7174f in mainline


Ignore:
Timestamp:
2010-12-17T22:03:15Z (11 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master
Children:
7551706b
Parents:
0bff73a
Message:

Devmap drivers can customize forwarded connections

It is possible to set an extra parameter for forwarded connections through
devmap. The change shall ensure backward compatibility and allows to connect
to devman-style drivers through their devmap path.

Location:
uspace
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/devmap.c

    r0bff73a r47a7174f  
    127127/** Register new device.
    128128 *
    129  * @param namespace Namespace name.
     129 * The @p interface is used when forwarding connection to the driver.
     130 * If not 0, the first argument is the interface and the second argument
     131 * is the devmap handle of the device.
     132 * When the interface is zero (default), the first argument is directly
     133 * the handle (to ensure backward compatibility).
     134 *
     135 * @param fqdn Fully qualified device name.
     136 * @param[out] handle Handle to the created instance of device.
     137 * @param interface Interface when forwarding.
     138 *
     139 */
     140int devmap_device_register_with_iface(const char *fqdn,
     141    devmap_handle_t *handle, sysarg_t interface)
     142{
     143        int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
     144       
     145        if (phone < 0)
     146                return phone;
     147       
     148        async_serialize_start();
     149       
     150        ipc_call_t answer;
     151        aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, interface, 0,
     152            &answer);
     153       
     154        sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
     155        if (retval != EOK) {
     156                async_wait_for(req, NULL);
     157                async_serialize_end();
     158                return retval;
     159        }
     160       
     161        async_wait_for(req, &retval);
     162       
     163        async_serialize_end();
     164       
     165        if (retval != EOK) {
     166                if (handle != NULL)
     167                        *handle = -1;
     168                return retval;
     169        }
     170       
     171        if (handle != NULL)
     172                *handle = (devmap_handle_t) IPC_GET_ARG1(answer);
     173       
     174        return retval;
     175}
     176
     177/** Register new device.
     178 *
    130179 * @param fqdn      Fully qualified device name.
    131180 * @param handle    Output: Handle to the created instance of device.
     
    134183int devmap_device_register(const char *fqdn, devmap_handle_t *handle)
    135184{
    136         int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
    137        
    138         if (phone < 0)
    139                 return phone;
    140        
    141         async_serialize_start();
    142        
    143         ipc_call_t answer;
    144         aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, 0, 0,
    145             &answer);
    146        
    147         sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
    148         if (retval != EOK) {
    149                 async_wait_for(req, NULL);
    150                 async_serialize_end();
    151                 return retval;
    152         }
    153        
    154         async_wait_for(req, &retval);
    155        
    156         async_serialize_end();
    157        
    158         if (retval != EOK) {
    159                 if (handle != NULL)
    160                         *handle = -1;
    161                 return retval;
    162         }
    163        
    164         if (handle != NULL)
    165                 *handle = (devmap_handle_t) IPC_GET_ARG1(answer);
    166        
    167         return retval;
    168 }
     185        return devmap_device_register_with_iface(fqdn, handle, 0);
     186}
     187
    169188
    170189int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle, unsigned int flags)
  • uspace/lib/c/include/devmap.h

    r0bff73a r47a7174f  
    4545extern int devmap_driver_register(const char *, async_client_conn_t);
    4646extern int devmap_device_register(const char *, devmap_handle_t *);
     47extern int devmap_device_register_with_iface(const char *, devmap_handle_t *, sysarg_t);
    4748
    4849extern int devmap_device_get_handle(const char *, devmap_handle_t *, unsigned int);
  • uspace/lib/c/include/ipc/devman.h

    r0bff73a r47a7174f  
    123123        DEVMAN_CLIENT,
    124124        DEVMAN_CONNECT_TO_DEVICE,
     125        DEVMAN_CONNECT_FROM_DEVMAP,
    125126        DEVMAN_CONNECT_TO_PARENTS_DEVICE
    126127} devman_interface_t;
  • uspace/srv/devman/devman.c

    r0bff73a r47a7174f  
    670670        }
    671671       
    672         devmap_device_register(devmap_pathname, &node->devmap_handle);
     672        devmap_device_register_with_iface(devmap_pathname,
     673            &node->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);
    673674       
    674675        tree_add_devmap_device(tree, node);
  • uspace/srv/devman/main.c

    r0bff73a r47a7174f  
    486486static void devman_connection_devmapper(ipc_callid_t iid, ipc_call_t *icall)
    487487{
    488         devmap_handle_t devmap_handle = IPC_GET_IMETHOD(*icall);
     488        devmap_handle_t devmap_handle = IPC_GET_ARG2(*icall);
    489489        node_t *dev;
    490490
     
    503503        }
    504504       
    505         printf(NAME ": devman_connection_devmapper: forward connection to "
    506             "device %s to driver %s.\n", dev->pathname, dev->drv->name);
    507505        ipc_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, dev->handle, 0,
    508506            IPC_FF_NONE);
     507        printf(NAME ": devman_connection_devmapper: forwarded connection to "
     508            "device %s to driver %s.\n", dev->pathname, dev->drv->name);
    509509}
    510510
     
    512512static void devman_connection(ipc_callid_t iid, ipc_call_t *icall)
    513513{
    514         /*
    515          * Silly hack to enable the device manager to register as a driver by
    516          * the device mapper. If the ipc method is not IPC_M_CONNECT_ME_TO, this
    517          * is not the forwarded connection from naming service, so it must be a
    518          * connection from the devmapper which thinks this is a devmapper-style
    519          * driver. So pretend this is a devmapper-style driver. (This does not
    520          * work for device with handle == IPC_M_CONNECT_ME_TO, because devmapper
    521          * passes device handle to the driver as an ipc method.)
    522          */
    523         if (IPC_GET_IMETHOD(*icall) != IPC_M_CONNECT_ME_TO)
    524                 devman_connection_devmapper(iid, icall);
    525 
    526         /*
    527          * ipc method is IPC_M_CONNECT_ME_TO, so this is forwarded connection
    528          * from naming service by which we registered as device manager, so be
    529          * device manager.
    530          */
    531        
    532514        /* Select interface. */
    533515        switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
     
    542524                devman_forward(iid, icall, false);
    543525                break;
     526        case DEVMAN_CONNECT_FROM_DEVMAP:
     527                /* Someone connected through devmap node. */
     528                devman_connection_devmapper(iid, icall);
     529                break;
    544530        case DEVMAN_CONNECT_TO_PARENTS_DEVICE:
    545531                /* Connect client to selected device. */
  • uspace/srv/devmap/devmap.c

    r0bff73a r47a7174f  
    9999        /** Device driver handling this device */
    100100        devmap_driver_t *driver;
     101        /** Use this interface when forwarding to driver. */
     102        sysarg_t forward_interface;
    101103} devmap_device_t;
    102104
     
    517519        }
    518520       
     521        /* Set the interface, if any. */
     522        device->forward_interface = IPC_GET_ARG1(*icall);
     523
    519524        /* Get fqdn */
    520525        char *fqdn;
     
    566571        /* Get unique device handle */
    567572        device->handle = devmap_create_handle();
    568        
     573
    569574        devmap_namespace_addref(namespace, device);
    570575        device->driver = driver;
     
    617622        }
    618623       
    619         ipc_forward_fast(callid, dev->driver->phone, dev->handle,
    620             IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
     624        if (dev->forward_interface == 0) {
     625                /* The IPC_GET_ARG3(*icall) would be always zero,
     626                 * wouldn't it? So why to pass it at all?
     627                 */
     628                ipc_forward_fast(callid, dev->driver->phone,
     629                    dev->handle, 0, 0,
     630                    IPC_FF_NONE);
     631        } else {
     632                ipc_forward_fast(callid, dev->driver->phone,
     633                    dev->forward_interface, dev->handle, 0,
     634                    IPC_FF_NONE);
     635        }
    621636       
    622637        fibril_mutex_unlock(&devices_list_mutex);
Note: See TracChangeset for help on using the changeset viewer.