Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4581 → Rev 4582

/branches/network/uspace/srv/net/nil/eth/eth.c
39,6 → 39,7
#include <malloc.h>
#include <mem.h>
#include <stdio.h>
#include <string.h>
 
#include <ipc/ipc.h>
#include <ipc/services.h>
267,12 → 268,12
eth_proto_ref proto;
 
//TODO clear device if off?
rwlock_read_lock( & eth_globals.protos_lock );
fibril_rwlock_read_lock( & eth_globals.protos_lock );
for( index = eth_protos_count( & eth_globals.protos ) - 1; index >= 0; -- index ){
proto = eth_protos_get_index( & eth_globals.protos, index );
if( proto && proto->phone ) il_device_state_msg( proto->phone, device_id, state, proto->service );
}
rwlock_read_unlock( & eth_globals.protos_lock );
fibril_rwlock_read_unlock( & eth_globals.protos_lock );
return EOK;
}
 
279,10 → 280,10
int nil_initialize( int net_phone ){
ERROR_DECLARE;
 
rwlock_initialize( & eth_globals.devices_lock );
rwlock_initialize( & eth_globals.protos_lock );
rwlock_write_lock( & eth_globals.devices_lock );
rwlock_write_lock( & eth_globals.protos_lock );
fibril_rwlock_initialize( & eth_globals.devices_lock );
fibril_rwlock_initialize( & eth_globals.protos_lock );
fibril_rwlock_write_lock( & eth_globals.devices_lock );
fibril_rwlock_write_lock( & eth_globals.protos_lock );
eth_globals.net_phone = net_phone;
eth_globals.broadcast_addr = measured_string_create_bulk( "\xFF\xFF\xFF\xFF\xFF\xFF", CONVERT_SIZE( uint8_t, char, ETH_ADDR ));
if( ! eth_globals.broadcast_addr ) return ENOMEM;
291,8 → 292,8
eth_devices_destroy( & eth_globals.devices );
return ERROR_CODE;
}
rwlock_write_unlock( & eth_globals.protos_lock );
rwlock_write_unlock( & eth_globals.devices_lock );
fibril_rwlock_write_unlock( & eth_globals.protos_lock );
fibril_rwlock_write_unlock( & eth_globals.devices_lock );
return EOK;
}
 
306,13 → 307,13
size_t count = sizeof( names ) / sizeof( measured_string_t );
char * data;
 
rwlock_write_lock( & eth_globals.devices_lock );
fibril_rwlock_write_lock( & eth_globals.devices_lock );
// an existing device?
device = eth_devices_find( & eth_globals.devices, device_id );
if( device ){
if( device->service != service ){
printf( "Device %d already exists\n", device->device_id );
rwlock_write_unlock( & eth_globals.devices_lock );
fibril_rwlock_write_unlock( & eth_globals.devices_lock );
return EEXIST;
}else{
// update mtu
329,7 → 330,7
device->mtu = (( mtu > 0 ) && ( mtu <= ETH_MAX_TAGGED_CONTENT( device->flags ))) ? mtu : ETH_MAX_TAGGED_CONTENT( device->flags );
configuration = & names[ 0 ];
if( ERROR_OCCURRED( net_get_device_conf_req( eth_globals.net_phone, device->device_id, & configuration, count, & data ))){
rwlock_write_unlock( & eth_globals.devices_lock );
fibril_rwlock_write_unlock( & eth_globals.devices_lock );
free( device );
return ERROR_CODE;
}
351,13 → 352,13
// bind the device driver
device->phone = netif_bind_service( device->service, device->device_id, SERVICE_ETHERNET, eth_receiver );
if( device->phone < 0 ){
rwlock_write_unlock( & eth_globals.devices_lock );
fibril_rwlock_write_unlock( & eth_globals.devices_lock );
free( device );
return device->phone;
}
// get hardware address
if( ERROR_OCCURRED( netif_get_addr( device->phone, device->device_id, & device->addr, & device->addr_data ))){
rwlock_write_unlock( & eth_globals.devices_lock );
fibril_rwlock_write_unlock( & eth_globals.devices_lock );
free( device );
return ERROR_CODE;
}
364,7 → 365,7
// add to the cache
index = eth_devices_add( & eth_globals.devices, device->device_id, device );
if( index < 0 ){
rwlock_write_unlock( & eth_globals.devices_lock );
fibril_rwlock_write_unlock( & eth_globals.devices_lock );
free( device->addr );
free( device->addr_data );
free( device );
372,7 → 373,7
}
printf( "New device registered:\n\tid\t= %d\n\tservice\t= %d\n\tMTU\t= %d\n\taddress\t= %X:%X:%X:%X:%X:%X\n\tflags\t= 0x%x\n", device->device_id, device->service, device->mtu, device->addr_data[ 0 ], device->addr_data[ 1 ], device->addr_data[ 2 ], device->addr_data[ 3 ], device->addr_data[ 4 ], device->addr_data[ 5 ], device->flags );
}
rwlock_write_unlock( & eth_globals.devices_lock );
fibril_rwlock_write_unlock( & eth_globals.devices_lock );
return EOK;
}
 
444,15 → 445,15
eth_device_ref device;
int flags;
 
rwlock_read_lock( & eth_globals.devices_lock );
fibril_rwlock_read_lock( & eth_globals.devices_lock );
device = eth_devices_find( & eth_globals.devices, device_id );
if( ! device ){
rwlock_read_unlock( & eth_globals.devices_lock );
fibril_rwlock_read_unlock( & eth_globals.devices_lock );
return ENOENT;
}
flags = device->flags;
rwlock_read_unlock( & eth_globals.devices_lock );
rwlock_read_lock( & eth_globals.protos_lock );
fibril_rwlock_read_unlock( & eth_globals.devices_lock );
fibril_rwlock_read_lock( & eth_globals.protos_lock );
do{
next = pq_detach( packet );
proto = eth_process_packet( flags, packet );
464,7 → 465,7
}
packet = next;
}while( packet );
rwlock_read_unlock( & eth_globals.protos_lock );
fibril_rwlock_read_unlock( & eth_globals.protos_lock );
return EOK;
}
 
472,14 → 473,14
eth_device_ref device;
 
if( !( addr_len && prefix && content && suffix )) return EBADMEM;
rwlock_read_lock( & eth_globals.devices_lock );
fibril_rwlock_read_lock( & eth_globals.devices_lock );
device = eth_devices_find( & eth_globals.devices, device_id );
if( ! device ){
rwlock_read_unlock( & eth_globals.devices_lock );
fibril_rwlock_read_unlock( & eth_globals.devices_lock );
return ENOENT;
}
* content = device->mtu;
rwlock_read_unlock( & eth_globals.devices_lock );
fibril_rwlock_read_unlock( & eth_globals.devices_lock );
* addr_len = ETH_ADDR;
* prefix = ETH_PREFIX;
* suffix = ETH_MIN_CONTENT + ETH_SUFFIX;
493,14 → 494,14
if( type == ETH_BROADCAST_ADDR ){
* address = eth_globals.broadcast_addr;
}else{
rwlock_read_lock( & eth_globals.devices_lock );
fibril_rwlock_read_lock( & eth_globals.devices_lock );
device = eth_devices_find( & eth_globals.devices, device_id );
if( ! device ){
rwlock_read_unlock( & eth_globals.devices_lock );
fibril_rwlock_read_unlock( & eth_globals.devices_lock );
return ENOENT;
}
* address = device->addr;
rwlock_read_unlock( & eth_globals.devices_lock );
fibril_rwlock_read_unlock( & eth_globals.devices_lock );
}
return ( * address ) ? EOK : ENOENT;
}
512,16 → 513,16
 
protocol = protocol_map( SERVICE_ETHERNET, service );
if( ! protocol ) return ENOENT;
rwlock_write_lock( & eth_globals.protos_lock );
fibril_rwlock_write_lock( & eth_globals.protos_lock );
proto = eth_protos_find( & eth_globals.protos, protocol );
if( proto ){
proto->phone = phone;
rwlock_write_unlock( & eth_globals.protos_lock );
fibril_rwlock_write_unlock( & eth_globals.protos_lock );
return EOK;
}else{
proto = ( eth_proto_ref ) malloc( sizeof( eth_proto_t ));
if( ! proto ){
rwlock_write_unlock( & eth_globals.protos_lock );
fibril_rwlock_write_unlock( & eth_globals.protos_lock );
return ENOMEM;
}
proto->service = service;
529,13 → 530,13
proto->phone = phone;
index = eth_protos_add( & eth_globals.protos, protocol, proto );
if( index < 0 ){
rwlock_write_unlock( & eth_globals.protos_lock );
fibril_rwlock_write_unlock( & eth_globals.protos_lock );
free( proto );
return index;
}
}
printf( "New protocol registered:\n\tprotocol\t= 0x%x\n\tservice\t= %d\n\tphone\t= %d\n", proto->protocol, proto->service, proto->phone );
rwlock_write_unlock( & eth_globals.protos_lock );
fibril_rwlock_write_unlock( & eth_globals.protos_lock );
return EOK;
}
 
608,10 → 609,10
pq_release( eth_globals.net_phone, packet_get_id( packet ));
return EINVAL;
}
rwlock_read_lock( & eth_globals.devices_lock );
fibril_rwlock_read_lock( & eth_globals.devices_lock );
device = eth_devices_find( & eth_globals.devices, device_id );
if( ! device ){
rwlock_read_unlock( & eth_globals.devices_lock );
fibril_rwlock_read_unlock( & eth_globals.devices_lock );
return ENOENT;
}
// process packet queue
631,7 → 632,7
if( packet ){
netif_send_msg( device->phone, device_id, packet, SERVICE_ETHERNET );
}
rwlock_read_unlock( & eth_globals.devices_lock );
fibril_rwlock_read_unlock( & eth_globals.devices_lock );
return EOK;
}
 
/branches/network/uspace/srv/net/nil/eth/eth.h
37,7 → 37,7
#ifndef __NET_ETH_H__
#define __NET_ETH_H__
 
#include <rwlock.h>
#include <fibril_sync.h>
#include <ipc/services.h>
 
#include "../../include/device.h"
130,13 → 130,13
int net_phone;
/** Safety lock for devices.
*/
rwlock_t devices_lock;
fibril_rwlock_t devices_lock;
/** All known Ethernet devices.
*/
eth_devices_t devices;
/** Safety lock for protocols.
*/
rwlock_t protos_lock;
fibril_rwlock_t protos_lock;
/** Protocol map.
* Service phone map for each protocol.
*/