Changeset 1ffa73b in mainline for uspace/lib/net/netif/netif_skel.c


Ignore:
Timestamp:
2011-01-10T16:33:08Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b207803
Parents:
863d45e (diff), 6610565b (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 development/ changes

File:
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/net/netif/netif_skel.c

    r863d45e r1ffa73b  
    2727 */
    2828
    29 /** @addtogroup libnet 
     29/** @addtogroup libnet
    3030 * @{
    3131 */
     
    5353#include <net/device.h>
    5454#include <nil_interface.h>
    55 #include <netif_local.h>
    56 #include <netif_interface.h>
     55#include <netif_skel.h>
    5756
    5857DEVICE_MAP_IMPLEMENT(netif_device_map, netif_device_t);
     
    6362/** Probe the existence of the device.
    6463 *
    65  * @param[in] netif_phone The network interface phone.
    66  * @param[in] device_id The device identifier.
    67  * @param[in] irq       The device interrupt number.
    68  * @param[in] io        The device input/output address.
    69  * @return              EOK on success.
    70  * @return              Other error codes as defined for the
    71  *                      netif_probe_message().
    72  */
    73 int
    74 netif_probe_req_local(int netif_phone, device_id_t device_id, int irq, int io)
     64 * @param[in] netif_phone Network interface phone.
     65 * @param[in] device_id   Device identifier.
     66 * @param[in] irq         Device interrupt number.
     67 * @param[in] io          Device input/output address.
     68 *
     69 * @return EOK on success.
     70 * @return Other error codes as defined for the
     71 *         netif_probe_message().
     72 *
     73 */
     74static int netif_probe_req_local(int netif_phone, device_id_t device_id,
     75    int irq, void *io)
    7576{
    7677        fibril_rwlock_write_lock(&netif_globals.lock);
     
    8384/** Send the packet queue.
    8485 *
    85  * @param[in] netif_phone The network interface phone.
    86  * @param[in] device_id The device identifier.
    87  * @param[in] packet    The packet queue.
    88  * @param[in] sender    The sending module service.
    89  * @return              EOK on success.
    90  * @return              Other error codes as defined for the generic_send_msg()
    91  *                      function.
    92  */
    93 int netif_send_msg_local(int netif_phone, device_id_t device_id,
     86 * @param[in] netif_phone Network interface phone.
     87 * @param[in] device_id   Device identifier.
     88 * @param[in] packet      Packet queue.
     89 * @param[in] sender      Sending module service.
     90 *
     91 * @return EOK on success.
     92 * @return Other error codes as defined for the generic_send_msg()
     93 *         function.
     94 *
     95 */
     96static int netif_send_msg_local(int netif_phone, device_id_t device_id,
    9497    packet_t *packet, services_t sender)
    9598{
     
    103106/** Start the device.
    104107 *
    105  * @param[in] netif_phone The network interface phone.
    106  * @param[in] device_id The device identifier.
    107  * @return              EOK on success.
    108  * @return              Other error codes as defined for the find_device()
    109  *                      function.
    110  * @return              Other error codes as defined for the
    111  *                      netif_start_message() function.
    112  */
    113 int netif_start_req_local(int netif_phone, device_id_t device_id)
    114 {
    115         int rc;
    116        
     108 * @param[in] netif_phone Network interface phone.
     109 * @param[in] device_id   Device identifier.
     110 *
     111 * @return EOK on success.
     112 * @return Other error codes as defined for the find_device()
     113 *         function.
     114 * @return Other error codes as defined for the
     115 *         netif_start_message() function.
     116 *
     117 */
     118static int netif_start_req_local(int netif_phone, device_id_t device_id)
     119{
    117120        fibril_rwlock_write_lock(&netif_globals.lock);
    118121       
    119122        netif_device_t *device;
    120         rc = find_device(device_id, &device);
     123        int rc = find_device(device_id, &device);
    121124        if (rc != EOK) {
    122125                fibril_rwlock_write_unlock(&netif_globals.lock);
     
    139142/** Stop the device.
    140143 *
    141  * @param[in] netif_phone The network interface phone.
    142  * @param[in] device_id The device identifier.
    143  * @return              EOK on success.
    144  * @return              Other error codes as defined for the find_device()
    145  *                      function.
    146  * @return              Other error codes as defined for the
    147  *                      netif_stop_message() function.
    148  */
    149 int netif_stop_req_local(int netif_phone, device_id_t device_id)
    150 {
    151         int rc;
    152        
     144 * @param[in] netif_phone Network interface phone.
     145 * @param[in] device_id   Device identifier.
     146 *
     147 * @return EOK on success.
     148 * @return Other error codes as defined for the find_device()
     149 *         function.
     150 * @return Other error codes as defined for the
     151 *         netif_stop_message() function.
     152 *
     153 */
     154static int netif_stop_req_local(int netif_phone, device_id_t device_id)
     155{
    153156        fibril_rwlock_write_lock(&netif_globals.lock);
    154157       
    155158        netif_device_t *device;
    156         rc = find_device(device_id, &device);
     159        int rc = find_device(device_id, &device);
    157160        if (rc != EOK) {
    158161                fibril_rwlock_write_unlock(&netif_globals.lock);
     
    173176}
    174177
    175 /** Return the device usage statistics.
    176  *
    177  * @param[in] netif_phone The network interface phone.
    178  * @param[in] device_id The device identifier.
    179  * @param[out] stats    The device usage statistics.
    180  * @return EOK on success.
    181  */
    182 int netif_stats_req_local(int netif_phone, device_id_t device_id,
    183     device_stats_t *stats)
    184 {
    185         fibril_rwlock_read_lock(&netif_globals.lock);
    186         int res = netif_get_device_stats(device_id, stats);
    187         fibril_rwlock_read_unlock(&netif_globals.lock);
    188        
    189         return res;
    190 }
    191 
    192 /** Return the device local hardware address.
    193  *
    194  * @param[in] netif_phone The network interface phone.
    195  * @param[in] device_id The device identifier.
    196  * @param[out] address  The device local hardware address.
    197  * @param[out] data     The address data.
    198  * @return              EOK on success.
    199  * @return              EBADMEM if the address parameter is NULL.
    200  * @return              ENOENT if there no such device.
    201  * @return              Other error codes as defined for the
    202  *                      netif_get_addr_message() function.
    203  */
    204 int netif_get_addr_req_local(int netif_phone, device_id_t device_id,
    205     measured_string_t **address, char **data)
    206 {
    207         int rc;
    208        
    209         if (!address || !data)
    210                 return EBADMEM;
    211        
    212         fibril_rwlock_read_lock(&netif_globals.lock);
    213        
    214         measured_string_t translation;
    215         rc = netif_get_addr_message(device_id, &translation);
    216         if (rc == EOK) {
    217                 *address = measured_string_copy(&translation);
    218                 rc = (*address) ? EOK : ENOMEM;
    219         }
    220        
    221         fibril_rwlock_read_unlock(&netif_globals.lock);
    222        
    223         *data = (**address).value;
    224        
    225         return rc;
    226 }
    227 
    228178/** Find the device specific data.
    229179 *
    230  * @param[in] device_id The device identifier.
    231  * @param[out] device   The device specific data.
    232  * @return              EOK on success.
    233  * @return              ENOENT if device is not found.
    234  * @return              EPERM if the device is not initialized.
     180 * @param[in]  device_id Device identifier.
     181 * @param[out] device    Device specific data.
     182 *
     183 * @return EOK on success.
     184 * @return ENOENT if device is not found.
     185 * @return EPERM if the device is not initialized.
     186 *
    235187 */
    236188int find_device(device_id_t device_id, netif_device_t **device)
     
    251203/** Clear the usage statistics.
    252204 *
    253  * @param[in] stats     The usage statistics.
     205 * @param[in] stats The usage statistics.
     206 *
    254207 */
    255208void null_device_stats(device_stats_t *stats)
     
    258211}
    259212
    260 /** Initialize the netif module.
    261  *
    262  * @param[in] client_connection The client connection functio to be registered.
    263  * @return              EOK on success.
    264  * @return              Other error codes as defined for each specific module
    265  *                      message function.
    266  */
    267 int netif_init_module(async_client_conn_t client_connection)
    268 {
    269         int rc;
    270        
    271         async_set_client_connection(client_connection);
    272        
    273         netif_globals.net_phone = connect_to_service(SERVICE_NETWORKING);
    274         netif_device_map_initialize(&netif_globals.device_map);
    275        
    276         rc = pm_init();
     213/** Release the given packet.
     214 *
     215 * Prepared for future optimization.
     216 *
     217 * @param[in] packet_id The packet identifier.
     218 *
     219 */
     220void netif_pq_release(packet_id_t packet_id)
     221{
     222        pq_release_remote(netif_globals.net_phone, packet_id);
     223}
     224
     225/** Allocate new packet to handle the given content size.
     226 *
     227 * @param[in] content Minimum content size.
     228 *
     229 * @return The allocated packet.
     230 * @return NULL on error.
     231 *
     232 */
     233packet_t *netif_packet_get_1(size_t content)
     234{
     235        return packet_get_1_remote(netif_globals.net_phone, content);
     236}
     237
     238/** Register the device notification receiver,
     239 *
     240 * Register a  network interface layer module as the device
     241 * notification receiver.
     242 *
     243 * @param[in] device_id Device identifier.
     244 * @param[in] phone     Network interface layer module phone.
     245 *
     246 * @return EOK on success.
     247 * @return ENOENT if there is no such device.
     248 * @return ELIMIT if there is another module registered.
     249 *
     250 */
     251static int register_message(device_id_t device_id, int phone)
     252{
     253        netif_device_t *device;
     254        int rc = find_device(device_id, &device);
    277255        if (rc != EOK)
    278256                return rc;
    279257       
    280         fibril_rwlock_initialize(&netif_globals.lock);
    281        
    282         rc = netif_initialize();
    283         if (rc != EOK) {
    284                 pm_destroy();
    285                 return rc;
    286         }
    287        
     258        if (device->nil_phone >= 0)
     259                return ELIMIT;
     260       
     261        device->nil_phone = phone;
    288262        return EOK;
    289263}
    290264
    291 /** Release the given packet.
    292  *
    293  * Prepared for future optimization.
    294  *
    295  * @param[in] packet_id The packet identifier.
    296  */
    297 void netif_pq_release(packet_id_t packet_id)
    298 {
    299         pq_release_remote(netif_globals.net_phone, packet_id);
    300 }
    301 
    302 /** Allocate new packet to handle the given content size.
    303  *
    304  * @param[in] content   The minimum content size.
    305  * @return              The allocated packet.
    306  * @return              NULL if there is an error.
    307  *
    308  */
    309 packet_t *netif_packet_get_1(size_t content)
    310 {
    311         return packet_get_1_remote(netif_globals.net_phone, content);
    312 }
    313 
    314 /** Register the device notification receiver, the network interface layer
    315  * module.
    316  *
    317  * @param[in] name      Module name.
    318  * @param[in] device_id The device identifier.
    319  * @param[in] phone     The network interface layer module phone.
    320  * @return              EOK on success.
    321  * @return              ENOENT if there is no such device.
    322  * @return              ELIMIT if there is another module registered.
    323  */
    324 static int register_message(const char *name, device_id_t device_id, int phone)
    325 {
    326         netif_device_t *device;
    327         int rc;
    328        
    329         rc = find_device(device_id, &device);
    330         if (rc != EOK)
    331                 return rc;
    332        
    333         if (device->nil_phone > 0)
    334                 return ELIMIT;
    335        
    336         device->nil_phone = phone;
    337         printf("%s: Receiver of device %d registered (phone: %d)\n",
    338             name, device->device_id, device->nil_phone);
    339         return EOK;
    340 }
    341 
    342265/** Process the netif module messages.
    343266 *
    344  * @param[in] name      Module name.
    345  * @param[in] callid    The message identifier.
    346  * @param[in] call      The message parameters.
    347  * @param[out] answer   The message answer parameters.
    348  * @param[out] answer_count The last parameter for the actual answer in the
    349  *                      answer parameter.
    350  * @return              EOK on success.
    351  * @return              ENOTSUP if the message is not known.
    352  * @return              Other error codes as defined for each specific module
    353  *                      message function.
     267 * @param[in]  callid Mmessage identifier.
     268 * @param[in]  call   Message.
     269 * @param[out] answer Answer.
     270 * @param[out] count  Number of arguments of the answer.
     271 *
     272 * @return EOK on success.
     273 * @return ENOTSUP if the message is unknown.
     274 * @return Other error codes as defined for each specific module
     275 *         message function.
    354276 *
    355277 * @see IS_NET_NETIF_MESSAGE()
    356278 *
    357279 */
    358 int netif_module_message_standalone(const char *name, ipc_callid_t callid,
    359     ipc_call_t *call, ipc_call_t *answer, int *answer_count)
     280static int netif_module_message(ipc_callid_t callid, ipc_call_t *call,
     281    ipc_call_t *answer, size_t *count)
    360282{
    361283        size_t length;
     
    365287        int rc;
    366288       
    367         *answer_count = 0;
     289        *count = 0;
     290       
    368291        switch (IPC_GET_IMETHOD(*call)) {
    369292        case IPC_M_PHONE_HUNGUP:
     
    371294       
    372295        case NET_NETIF_PROBE:
    373                 return netif_probe_req_local(0, IPC_GET_DEVICE(call),
    374                     NETIF_GET_IRQ(call), NETIF_GET_IO(call));
    375                    
     296                return netif_probe_req_local(0, IPC_GET_DEVICE(*call),
     297                    NETIF_GET_IRQ(*call), NETIF_GET_IO(*call));
     298       
    376299        case IPC_M_CONNECT_TO_ME:
    377300                fibril_rwlock_write_lock(&netif_globals.lock);
    378                 rc = register_message(name, IPC_GET_DEVICE(call),
    379                     IPC_GET_PHONE(call));
     301               
     302                rc = register_message(IPC_GET_DEVICE(*call), IPC_GET_PHONE(*call));
     303               
    380304                fibril_rwlock_write_unlock(&netif_globals.lock);
    381305                return rc;
    382                
     306       
    383307        case NET_NETIF_SEND:
    384308                rc = packet_translate_remote(netif_globals.net_phone, &packet,
    385                     IPC_GET_PACKET(call));
     309                    IPC_GET_PACKET(*call));
    386310                if (rc != EOK)
    387311                        return rc;
    388                 return netif_send_msg_local(0, IPC_GET_DEVICE(call), packet,
    389                     IPC_GET_SENDER(call));
    390                
     312               
     313                return netif_send_msg_local(0, IPC_GET_DEVICE(*call), packet,
     314                    IPC_GET_SENDER(*call));
     315       
    391316        case NET_NETIF_START:
    392                 return netif_start_req_local(0, IPC_GET_DEVICE(call));
    393                
     317                return netif_start_req_local(0, IPC_GET_DEVICE(*call));
     318       
    394319        case NET_NETIF_STATS:
    395320                fibril_rwlock_read_lock(&netif_globals.lock);
    396 
     321               
    397322                rc = async_data_read_receive(&callid, &length);
    398323                if (rc != EOK) {
     
    400325                        return rc;
    401326                }
     327               
    402328                if (length < sizeof(device_stats_t)) {
    403329                        fibril_rwlock_read_unlock(&netif_globals.lock);
    404330                        return EOVERFLOW;
    405331                }
    406 
    407                 rc = netif_get_device_stats(IPC_GET_DEVICE(call), &stats);
     332               
     333                rc = netif_get_device_stats(IPC_GET_DEVICE(*call), &stats);
    408334                if (rc == EOK) {
    409335                        rc = async_data_read_finalize(callid, &stats,
    410336                            sizeof(device_stats_t));
    411337                }
    412 
     338               
    413339                fibril_rwlock_read_unlock(&netif_globals.lock);
    414340                return rc;
    415 
     341       
    416342        case NET_NETIF_STOP:
    417                 return netif_stop_req_local(0, IPC_GET_DEVICE(call));
    418                
     343                return netif_stop_req_local(0, IPC_GET_DEVICE(*call));
     344       
    419345        case NET_NETIF_GET_ADDR:
    420346                fibril_rwlock_read_lock(&netif_globals.lock);
    421                 rc = netif_get_addr_message(IPC_GET_DEVICE(call), &address);
     347               
     348                rc = netif_get_addr_message(IPC_GET_DEVICE(*call), &address);
    422349                if (rc == EOK)
    423350                        rc = measured_strings_reply(&address, 1);
     351               
    424352                fibril_rwlock_read_unlock(&netif_globals.lock);
    425353                return rc;
    426354        }
    427355       
    428         return netif_specific_message(callid, call, answer, answer_count);
     356        return netif_specific_message(callid, call, answer, count);
     357}
     358
     359/** Default fibril for new module connections.
     360 *
     361 * @param[in] iid   Initial message identifier.
     362 * @param[in] icall Initial message call structure.
     363 *
     364 */
     365static void netif_client_connection(ipc_callid_t iid, ipc_call_t *icall)
     366{
     367        /*
     368         * Accept the connection by answering
     369         * the initial IPC_M_CONNECT_ME_TO call.
     370         */
     371        ipc_answer_0(iid, EOK);
     372       
     373        while (true) {
     374                ipc_call_t answer;
     375                size_t count;
     376               
     377                /* Clear the answer structure */
     378                refresh_answer(&answer, &count);
     379               
     380                /* Fetch the next message */
     381                ipc_call_t call;
     382                ipc_callid_t callid = async_get_call(&call);
     383               
     384                /* Process the message */
     385                int res = netif_module_message(callid, &call, &answer, &count);
     386               
     387                /* End if said to either by the message or the processing result */
     388                if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
     389                    (res == EHANGUP))
     390                        return;
     391               
     392                /* Answer the message */
     393                answer_call(callid, res, &answer, count);
     394        }
    429395}
    430396
     
    435401 * messages in an infinite loop.
    436402 *
    437  * @param[in] client_connection The client connection processing function.
    438  *                      The module skeleton propagates its own one.
    439  * @return              EOK on success.
    440  * @return              Other error codes as defined for each specific module
    441  *                      message function.
    442  */
    443 int netif_module_start_standalone(async_client_conn_t client_connection)
    444 {
    445         int rc;
    446        
    447         rc = netif_init_module(client_connection);
     403 * @return EOK on success.
     404 * @return Other error codes as defined for each specific module
     405 *         message function.
     406 *
     407 */
     408int netif_module_start(void)
     409{
     410        async_set_client_connection(netif_client_connection);
     411       
     412        netif_globals.net_phone = connect_to_service(SERVICE_NETWORKING);
     413        netif_device_map_initialize(&netif_globals.device_map);
     414       
     415        int rc = pm_init();
    448416        if (rc != EOK)
    449417                return rc;
     418       
     419        fibril_rwlock_initialize(&netif_globals.lock);
     420       
     421        rc = netif_initialize();
     422        if (rc != EOK) {
     423                pm_destroy();
     424                return rc;
     425        }
    450426       
    451427        async_manager();
Note: See TracChangeset for help on using the changeset viewer.