Changeset ec7f8b1 in mainline for uspace/srv/devman/main.c


Ignore:
Timestamp:
2011-08-21T15:35:03Z (13 years ago)
Author:
Petr Koupy <petr.koupy@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bb74dabe
Parents:
c4a8e4a (diff), 5935c079 (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.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/devman/main.c

    rc4a8e4a rec7f8b1  
    6565static dev_tree_t device_tree;
    6666
     67static int init_running_drv(void *drv);
     68
    6769/** Register running driver. */
    68 static driver_t *devman_driver_register(void)
    69 {
    70         ipc_call_t icall;
    71         ipc_callid_t iid;
     70static driver_t *devman_driver_register(ipc_callid_t callid, ipc_call_t *call)
     71{
    7272        driver_t *driver = NULL;
     73        char *drv_name = NULL;
    7374
    7475        log_msg(LVL_DEBUG, "devman_driver_register");
    75        
    76         iid = async_get_call(&icall);
    77         if (IPC_GET_IMETHOD(icall) != DEVMAN_DRIVER_REGISTER) {
    78                 async_answer_0(iid, EREFUSED);
    79                 return NULL;
    80         }
    81        
    82         char *drv_name = NULL;
    8376       
    8477        /* Get driver name. */
    8578        int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0);
    8679        if (rc != EOK) {
    87                 async_answer_0(iid, rc);
     80                async_answer_0(callid, rc);
    8881                return NULL;
    8982        }
     
    9891                free(drv_name);
    9992                drv_name = NULL;
    100                 async_answer_0(iid, ENOENT);
     93                async_answer_0(callid, ENOENT);
    10194                return NULL;
    10295        }
     
    112105                    driver->name);
    113106                fibril_mutex_unlock(&driver->driver_mutex);
    114                 async_answer_0(iid, EEXISTS);
     107                async_answer_0(callid, EEXISTS);
    115108                return NULL;
    116109        }
     
    134127        log_msg(LVL_DEBUG, "Creating connection to the `%s' driver.",
    135128            driver->name);
    136         driver->sess = async_callback_receive(EXCHANGE_SERIALIZE);
     129        driver->sess = async_callback_receive(EXCHANGE_PARALLEL);
    137130        if (!driver->sess) {
    138131                fibril_mutex_unlock(&driver->driver_mutex);
    139                 async_answer_0(iid, ENOTSUP);
     132                async_answer_0(callid, ENOTSUP);
    140133                return NULL;
    141134        }
    142        
    143         fibril_mutex_unlock(&driver->driver_mutex);
     135        /* FIXME: Work around problem with callback sessions */
     136        async_sess_args_set(driver->sess, DRIVER_DEVMAN, 0, 0);
    144137       
    145138        log_msg(LVL_NOTE,
     
    147140            driver->name);
    148141       
    149         async_answer_0(iid, EOK);
    150        
     142        /*
     143         * Initialize the driver as running (e.g. pass assigned devices to it)
     144         * in a separate fibril; the separate fibril is used to enable the
     145         * driver to use devman service during the driver's initialization.
     146         */
     147        fid_t fid = fibril_create(init_running_drv, driver);
     148        if (fid == 0) {
     149                log_msg(LVL_ERROR, "Failed to create initialization fibril " \
     150                    "for driver `%s'.", driver->name);
     151                fibril_mutex_unlock(&driver->driver_mutex);
     152                async_answer_0(callid, ENOMEM);
     153                return NULL;
     154        }
     155       
     156        fibril_add_ready(fid);
     157        fibril_mutex_unlock(&driver->driver_mutex);
     158       
     159        async_answer_0(callid, EOK);
    151160        return driver;
    152161}
     
    429438static void devman_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
    430439{
     440        client_t *client;
     441        driver_t *driver;
     442       
    431443        /* Accept the connection. */
    432444        async_answer_0(iid, EOK);
    433445       
    434         driver_t *driver = devman_driver_register();
    435         if (driver == NULL)
    436                 return;
    437        
    438         /*
    439          * Initialize the driver as running (e.g. pass assigned devices to it)
    440          * in a separate fibril; the separate fibril is used to enable the
    441          * driver to use devman service during the driver's initialization.
    442          */
    443         fid_t fid = fibril_create(init_running_drv, driver);
    444         if (fid == 0) {
    445                 log_msg(LVL_ERROR, "Failed to create initialization fibril " \
    446                     "for driver `%s'.", driver->name);
    447                 return;
    448         }
    449         fibril_add_ready(fid);
     446        client = async_get_client_data();
     447        if (client == NULL) {
     448                log_msg(LVL_ERROR, "Failed to allocate client data.");
     449                return;
     450        }
    450451       
    451452        while (true) {
     
    456457                        break;
    457458               
     459                if (IPC_GET_IMETHOD(call) != DEVMAN_DRIVER_REGISTER) {
     460                        fibril_mutex_lock(&client->mutex);
     461                        driver = client->driver;
     462                        fibril_mutex_unlock(&client->mutex);
     463                        if (driver == NULL) {
     464                                /* First call must be to DEVMAN_DRIVER_REGISTER */
     465                                async_answer_0(callid, ENOTSUP);
     466                                continue;
     467                        }
     468                }
     469               
    458470                switch (IPC_GET_IMETHOD(call)) {
     471                case DEVMAN_DRIVER_REGISTER:
     472                        fibril_mutex_lock(&client->mutex);
     473                        if (client->driver != NULL) {
     474                                fibril_mutex_unlock(&client->mutex);
     475                                async_answer_0(callid, EINVAL);
     476                                continue;
     477                        }
     478                        client->driver = devman_driver_register(callid, &call);
     479                        fibril_mutex_unlock(&client->mutex);
     480                        break;
    459481                case DEVMAN_ADD_FUNCTION:
    460482                        devman_add_function(callid, &call);
     
    814836static void devman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    815837{
    816         /* Select interface. */
     838        /* Select port. */
    817839        switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
    818840        case DEVMAN_DRIVER:
     
    840862}
    841863
     864static void *devman_client_data_create(void)
     865{
     866        client_t *client;
     867       
     868        client = calloc(1, sizeof(client_t));
     869        if (client == NULL)
     870                return NULL;
     871       
     872        fibril_mutex_initialize(&client->mutex);
     873        return client;
     874}
     875
     876static void devman_client_data_destroy(void *data)
     877{
     878        free(data);
     879}
     880
    842881/** Initialize device manager internal structures. */
    843882static bool devman_init(void)
     
    886925        }
    887926       
    888         /* Set a handler of incomming connections. */
     927        /* Set handlers for incoming connections. */
     928        async_set_client_data_constructor(devman_client_data_create);
     929        async_set_client_data_destructor(devman_client_data_destroy);
    889930        async_set_client_connection(devman_connection);
    890931
Note: See TracChangeset for help on using the changeset viewer.