Changeset 8b5690f in mainline for uspace/lib/net/netif/netif_skel.c


Ignore:
Timestamp:
2011-02-03T05:11:01Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ba38f72c
Parents:
22027b6e (diff), 86d7bfa (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 moved

Legend:

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

    r22027b6e r8b5690f  
    2727 */
    2828
    29 /** @addtogroup libnet 
     29/** @addtogroup libnet
    3030 * @{
    3131 */
     
    3333/** @file
    3434 * Network interface module skeleton implementation.
    35  * @see netif.h
     35 * @see netif_skel.h
    3636 */
    3737
     
    4040#include <fibril_synch.h>
    4141#include <stdio.h>
    42 #include <ipc/ipc.h>
    4342#include <ipc/services.h>
    4443#include <ipc/netif.h>
     
    5251#include <adt/measured_strings.h>
    5352#include <net/device.h>
    54 #include <nil_interface.h>
    55 #include <netif_local.h>
    56 #include <netif_interface.h>
     53#include <netif_skel.h>
     54#include <nil_remote.h>
    5755
    5856DEVICE_MAP_IMPLEMENT(netif_device_map, netif_device_t);
     
    6361/** Probe the existence of the device.
    6462 *
    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)
     63 * @param[in] netif_phone Network interface phone.
     64 * @param[in] device_id   Device identifier.
     65 * @param[in] irq         Device interrupt number.
     66 * @param[in] io          Device input/output address.
     67 *
     68 * @return EOK on success.
     69 * @return Other error codes as defined for the
     70 *         netif_probe_message().
     71 *
     72 */
     73static int netif_probe_req_local(int netif_phone, device_id_t device_id,
     74    int irq, void *io)
    7575{
    7676        fibril_rwlock_write_lock(&netif_globals.lock);
     
    8383/** Send the packet queue.
    8484 *
    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,
     85 * @param[in] netif_phone Network interface phone.
     86 * @param[in] device_id   Device identifier.
     87 * @param[in] packet      Packet queue.
     88 * @param[in] sender      Sending module service.
     89 *
     90 * @return EOK on success.
     91 * @return Other error codes as defined for the generic_send_msg()
     92 *         function.
     93 *
     94 */
     95static int netif_send_msg_local(int netif_phone, device_id_t device_id,
    9496    packet_t *packet, services_t sender)
    9597{
     
    103105/** Start the device.
    104106 *
    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        
     107 * @param[in] netif_phone Network interface phone.
     108 * @param[in] device_id   Device identifier.
     109 *
     110 * @return EOK on success.
     111 * @return Other error codes as defined for the find_device()
     112 *         function.
     113 * @return Other error codes as defined for the
     114 *         netif_start_message() function.
     115 *
     116 */
     117static int netif_start_req_local(int netif_phone, device_id_t device_id)
     118{
    117119        fibril_rwlock_write_lock(&netif_globals.lock);
    118120       
    119121        netif_device_t *device;
    120         rc = find_device(device_id, &device);
     122        int rc = find_device(device_id, &device);
    121123        if (rc != EOK) {
    122124                fibril_rwlock_write_unlock(&netif_globals.lock);
     
    127129        if (result > NETIF_NULL) {
    128130                int phone = device->nil_phone;
     131                nil_device_state_msg(phone, device_id, result);
    129132                fibril_rwlock_write_unlock(&netif_globals.lock);
    130                 nil_device_state_msg(phone, device_id, result);
    131133                return EOK;
    132134        }
     
    139141/** Stop the device.
    140142 *
    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        
     143 * @param[in] netif_phone Network interface phone.
     144 * @param[in] device_id   Device identifier.
     145 *
     146 * @return EOK on success.
     147 * @return Other error codes as defined for the find_device()
     148 *         function.
     149 * @return Other error codes as defined for the
     150 *         netif_stop_message() function.
     151 *
     152 */
     153static int netif_stop_req_local(int netif_phone, device_id_t device_id)
     154{
    153155        fibril_rwlock_write_lock(&netif_globals.lock);
    154156       
    155157        netif_device_t *device;
    156         rc = find_device(device_id, &device);
     158        int rc = find_device(device_id, &device);
    157159        if (rc != EOK) {
    158160                fibril_rwlock_write_unlock(&netif_globals.lock);
     
    163165        if (result > NETIF_NULL) {
    164166                int phone = device->nil_phone;
     167                nil_device_state_msg(phone, device_id, result);
    165168                fibril_rwlock_write_unlock(&netif_globals.lock);
    166                 nil_device_state_msg(phone, device_id, result);
    167169                return EOK;
    168170        }
     
    173175}
    174176
    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, uint8_t **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 
    228177/** Find the device specific data.
    229178 *
    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.
     179 * @param[in]  device_id Device identifier.
     180 * @param[out] device    Device specific data.
     181 *
     182 * @return EOK on success.
     183 * @return ENOENT if device is not found.
     184 * @return EPERM if the device is not initialized.
     185 *
    235186 */
    236187int find_device(device_id_t device_id, netif_device_t **device)
     
    251202/** Clear the usage statistics.
    252203 *
    253  * @param[in] stats     The usage statistics.
     204 * @param[in] stats The usage statistics.
     205 *
    254206 */
    255207void null_device_stats(device_stats_t *stats)
     
    258210}
    259211
    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();
     212/** Release the given packet.
     213 *
     214 * Prepared for future optimization.
     215 *
     216 * @param[in] packet_id The packet identifier.
     217 *
     218 */
     219void netif_pq_release(packet_id_t packet_id)
     220{
     221        pq_release_remote(netif_globals.net_phone, packet_id);
     222}
     223
     224/** Allocate new packet to handle the given content size.
     225 *
     226 * @param[in] content Minimum content size.
     227 *
     228 * @return The allocated packet.
     229 * @return NULL on error.
     230 *
     231 */
     232packet_t *netif_packet_get_1(size_t content)
     233{
     234        return packet_get_1_remote(netif_globals.net_phone, content);
     235}
     236
     237/** Register the device notification receiver,
     238 *
     239 * Register a  network interface layer module as the device
     240 * notification receiver.
     241 *
     242 * @param[in] device_id Device identifier.
     243 * @param[in] phone     Network interface layer module phone.
     244 *
     245 * @return EOK on success.
     246 * @return ENOENT if there is no such device.
     247 * @return ELIMIT if there is another module registered.
     248 *
     249 */
     250static int register_message(device_id_t device_id, int phone)
     251{
     252        netif_device_t *device;
     253        int rc = find_device(device_id, &device);
    277254        if (rc != EOK)
    278255                return rc;
    279256       
    280         fibril_rwlock_initialize(&netif_globals.lock);
    281        
    282         rc = netif_initialize();
    283         if (rc != EOK) {
    284                 pm_destroy();
    285                 return rc;
    286         }
    287        
     257        if (device->nil_phone >= 0)
     258                return ELIMIT;
     259       
     260        device->nil_phone = phone;
    288261        return EOK;
    289262}
    290263
    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 
    342264/** Process the netif module messages.
    343265 *
    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.
     266 * @param[in]  callid Mmessage identifier.
     267 * @param[in]  call   Message.
     268 * @param[out] answer Answer.
     269 * @param[out] count  Number of arguments of the answer.
     270 *
     271 * @return EOK on success.
     272 * @return ENOTSUP if the message is unknown.
     273 * @return Other error codes as defined for each specific module
     274 *         message function.
    354275 *
    355276 * @see IS_NET_NETIF_MESSAGE()
    356277 *
    357278 */
    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)
     279static int netif_module_message(ipc_callid_t callid, ipc_call_t *call,
     280    ipc_call_t *answer, size_t *count)
    360281{
    361282        size_t length;
     
    365286        int rc;
    366287       
    367         *answer_count = 0;
     288        *count = 0;
     289       
    368290        switch (IPC_GET_IMETHOD(*call)) {
    369291        case IPC_M_PHONE_HUNGUP:
     
    371293       
    372294        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                    
     295                return netif_probe_req_local(0, IPC_GET_DEVICE(*call),
     296                    NETIF_GET_IRQ(*call), NETIF_GET_IO(*call));
     297       
    376298        case IPC_M_CONNECT_TO_ME:
    377299                fibril_rwlock_write_lock(&netif_globals.lock);
    378                 rc = register_message(name, IPC_GET_DEVICE(call),
    379                     IPC_GET_PHONE(call));
     300               
     301                rc = register_message(IPC_GET_DEVICE(*call), IPC_GET_PHONE(*call));
     302               
    380303                fibril_rwlock_write_unlock(&netif_globals.lock);
    381304                return rc;
    382                
     305       
    383306        case NET_NETIF_SEND:
    384307                rc = packet_translate_remote(netif_globals.net_phone, &packet,
    385                     IPC_GET_PACKET(call));
     308                    IPC_GET_PACKET(*call));
    386309                if (rc != EOK)
    387310                        return rc;
    388                 return netif_send_msg_local(0, IPC_GET_DEVICE(call), packet,
    389                     IPC_GET_SENDER(call));
    390                
     311               
     312                return netif_send_msg_local(0, IPC_GET_DEVICE(*call), packet,
     313                    IPC_GET_SENDER(*call));
     314       
    391315        case NET_NETIF_START:
    392                 return netif_start_req_local(0, IPC_GET_DEVICE(call));
    393                
     316                return netif_start_req_local(0, IPC_GET_DEVICE(*call));
     317       
    394318        case NET_NETIF_STATS:
    395319                fibril_rwlock_read_lock(&netif_globals.lock);
    396 
     320               
    397321                rc = async_data_read_receive(&callid, &length);
    398322                if (rc != EOK) {
     
    400324                        return rc;
    401325                }
     326               
    402327                if (length < sizeof(device_stats_t)) {
    403328                        fibril_rwlock_read_unlock(&netif_globals.lock);
    404329                        return EOVERFLOW;
    405330                }
    406 
    407                 rc = netif_get_device_stats(IPC_GET_DEVICE(call), &stats);
     331               
     332                rc = netif_get_device_stats(IPC_GET_DEVICE(*call), &stats);
    408333                if (rc == EOK) {
    409334                        rc = async_data_read_finalize(callid, &stats,
    410335                            sizeof(device_stats_t));
    411336                }
    412 
     337               
    413338                fibril_rwlock_read_unlock(&netif_globals.lock);
    414339                return rc;
    415 
     340       
    416341        case NET_NETIF_STOP:
    417                 return netif_stop_req_local(0, IPC_GET_DEVICE(call));
    418                
     342                return netif_stop_req_local(0, IPC_GET_DEVICE(*call));
     343       
    419344        case NET_NETIF_GET_ADDR:
    420345                fibril_rwlock_read_lock(&netif_globals.lock);
    421                 rc = netif_get_addr_message(IPC_GET_DEVICE(call), &address);
     346               
     347                rc = netif_get_addr_message(IPC_GET_DEVICE(*call), &address);
    422348                if (rc == EOK)
    423349                        rc = measured_strings_reply(&address, 1);
     350               
    424351                fibril_rwlock_read_unlock(&netif_globals.lock);
    425352                return rc;
    426353        }
    427354       
    428         return netif_specific_message(callid, call, answer, answer_count);
     355        return netif_specific_message(callid, call, answer, count);
     356}
     357
     358/** Default fibril for new module connections.
     359 *
     360 * @param[in] iid   Initial message identifier.
     361 * @param[in] icall Initial message call structure.
     362 *
     363 */
     364static void netif_client_connection(ipc_callid_t iid, ipc_call_t *icall)
     365{
     366        /*
     367         * Accept the connection by answering
     368         * the initial IPC_M_CONNECT_ME_TO call.
     369         */
     370        async_answer_0(iid, EOK);
     371       
     372        while (true) {
     373                ipc_call_t answer;
     374                size_t count;
     375               
     376                /* Clear the answer structure */
     377                refresh_answer(&answer, &count);
     378               
     379                /* Fetch the next message */
     380                ipc_call_t call;
     381                ipc_callid_t callid = async_get_call(&call);
     382               
     383                /* Process the message */
     384                int res = netif_module_message(callid, &call, &answer, &count);
     385               
     386                /* End if said to either by the message or the processing result */
     387                if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
     388                    (res == EHANGUP))
     389                        return;
     390               
     391                /* Answer the message */
     392                answer_call(callid, res, &answer, count);
     393        }
    429394}
    430395
     
    435400 * messages in an infinite loop.
    436401 *
    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);
     402 * @return EOK on success.
     403 * @return Other error codes as defined for each specific module
     404 *         message function.
     405 *
     406 */
     407int netif_module_start(void)
     408{
     409        async_set_client_connection(netif_client_connection);
     410       
     411        netif_globals.net_phone = connect_to_service(SERVICE_NETWORKING);
     412        netif_device_map_initialize(&netif_globals.device_map);
     413       
     414        int rc = pm_init();
    448415        if (rc != EOK)
    449416                return rc;
     417       
     418        fibril_rwlock_initialize(&netif_globals.lock);
     419       
     420        rc = netif_initialize();
     421        if (rc != EOK) {
     422                pm_destroy();
     423                return rc;
     424        }
    450425       
    451426        async_manager();
Note: See TracChangeset for help on using the changeset viewer.