Changeset cf2af94 in mainline for uspace/lib/net/netif/netif_skel.c
- Timestamp:
- 2011-02-09T11:46:47Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cb15135a
- Parents:
- a49c4002 (diff), 0b37882 (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. - File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/net/netif/netif_skel.c
ra49c4002 rcf2af94 27 27 */ 28 28 29 /** @addtogroup libnet 29 /** @addtogroup libnet 30 30 * @{ 31 31 */ … … 33 33 /** @file 34 34 * Network interface module skeleton implementation. 35 * @see netif .h35 * @see netif_skel.h 36 36 */ 37 37 … … 40 40 #include <fibril_synch.h> 41 41 #include <stdio.h> 42 #include <ipc/ipc.h>43 42 #include <ipc/services.h> 44 43 #include <ipc/netif.h> … … 52 51 #include <adt/measured_strings.h> 53 52 #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> 57 55 58 56 DEVICE_MAP_IMPLEMENT(netif_device_map, netif_device_t); … … 63 61 /** Probe the existence of the device. 64 62 * 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 */ 73 static int netif_probe_req_local(int netif_phone, device_id_t device_id, 74 int irq, void *io) 75 75 { 76 76 fibril_rwlock_write_lock(&netif_globals.lock); … … 83 83 /** Send the packet queue. 84 84 * 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 */ 95 static int netif_send_msg_local(int netif_phone, device_id_t device_id, 94 96 packet_t *packet, services_t sender) 95 97 { … … 103 105 /** Start the device. 104 106 * 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 the111 * 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 */ 117 static int netif_start_req_local(int netif_phone, device_id_t device_id) 118 { 117 119 fibril_rwlock_write_lock(&netif_globals.lock); 118 120 119 121 netif_device_t *device; 120 rc = find_device(device_id, &device);122 int rc = find_device(device_id, &device); 121 123 if (rc != EOK) { 122 124 fibril_rwlock_write_unlock(&netif_globals.lock); … … 127 129 if (result > NETIF_NULL) { 128 130 int phone = device->nil_phone; 131 nil_device_state_msg(phone, device_id, result); 129 132 fibril_rwlock_write_unlock(&netif_globals.lock); 130 nil_device_state_msg(phone, device_id, result);131 133 return EOK; 132 134 } … … 139 141 /** Stop the device. 140 142 * 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 the147 * 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 */ 153 static int netif_stop_req_local(int netif_phone, device_id_t device_id) 154 { 153 155 fibril_rwlock_write_lock(&netif_globals.lock); 154 156 155 157 netif_device_t *device; 156 rc = find_device(device_id, &device);158 int rc = find_device(device_id, &device); 157 159 if (rc != EOK) { 158 160 fibril_rwlock_write_unlock(&netif_globals.lock); … … 163 165 if (result > NETIF_NULL) { 164 166 int phone = device->nil_phone; 167 nil_device_state_msg(phone, device_id, result); 165 168 fibril_rwlock_write_unlock(&netif_globals.lock); 166 nil_device_state_msg(phone, device_id, result);167 169 return EOK; 168 170 } … … 173 175 } 174 176 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 the202 * 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 228 177 /** Find the device specific data. 229 178 * 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 * 235 186 */ 236 187 int find_device(device_id_t device_id, netif_device_t **device) … … 251 202 /** Clear the usage statistics. 252 203 * 253 * @param[in] stats The usage statistics. 204 * @param[in] stats The usage statistics. 205 * 254 206 */ 255 207 void null_device_stats(device_stats_t *stats) … … 258 210 } 259 211 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 */ 219 void 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 */ 232 packet_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 */ 250 static int register_message(device_id_t device_id, int phone) 251 { 252 netif_device_t *device; 253 int rc = find_device(device_id, &device); 277 254 if (rc != EOK) 278 255 return rc; 279 256 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; 288 261 return EOK; 289 262 } 290 263 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 layer315 * 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 342 264 /** Process the netif module messages. 343 265 * 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. 354 275 * 355 276 * @see IS_NET_NETIF_MESSAGE() 356 277 * 357 278 */ 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)279 static int netif_module_message(ipc_callid_t callid, ipc_call_t *call, 280 ipc_call_t *answer, size_t *count) 360 281 { 361 282 size_t length; … … 365 286 int rc; 366 287 367 *answer_count = 0; 368 switch (IPC_GET_METHOD(*call)) { 288 *count = 0; 289 290 switch (IPC_GET_IMETHOD(*call)) { 369 291 case IPC_M_PHONE_HUNGUP: 370 292 return EOK; 371 293 372 294 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 376 298 case IPC_M_CONNECT_TO_ME: 377 299 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 380 303 fibril_rwlock_write_unlock(&netif_globals.lock); 381 304 return rc; 382 305 383 306 case NET_NETIF_SEND: 384 307 rc = packet_translate_remote(netif_globals.net_phone, &packet, 385 IPC_GET_PACKET( call));308 IPC_GET_PACKET(*call)); 386 309 if (rc != EOK) 387 310 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 391 315 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 394 318 case NET_NETIF_STATS: 395 319 fibril_rwlock_read_lock(&netif_globals.lock); 396 320 397 321 rc = async_data_read_receive(&callid, &length); 398 322 if (rc != EOK) { … … 400 324 return rc; 401 325 } 326 402 327 if (length < sizeof(device_stats_t)) { 403 328 fibril_rwlock_read_unlock(&netif_globals.lock); 404 329 return EOVERFLOW; 405 330 } 406 407 rc = netif_get_device_stats(IPC_GET_DEVICE( call), &stats);331 332 rc = netif_get_device_stats(IPC_GET_DEVICE(*call), &stats); 408 333 if (rc == EOK) { 409 334 rc = async_data_read_finalize(callid, &stats, 410 335 sizeof(device_stats_t)); 411 336 } 412 337 413 338 fibril_rwlock_read_unlock(&netif_globals.lock); 414 339 return rc; 415 340 416 341 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 419 344 case NET_NETIF_GET_ADDR: 420 345 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); 422 348 if (rc == EOK) 423 349 rc = measured_strings_reply(&address, 1); 350 424 351 fibril_rwlock_read_unlock(&netif_globals.lock); 425 352 return rc; 426 353 } 427 354 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 */ 364 static 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 } 429 394 } 430 395 … … 435 400 * messages in an infinite loop. 436 401 * 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 */ 407 int 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(); 448 415 if (rc != EOK) 449 416 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 } 450 425 451 426 async_manager();
Note:
See TracChangeset
for help on using the changeset viewer.