@@ -109,17 +109,65 @@ static int netdev_has_ll_addr ( struct net_device *netdev ) {
109
109
return 0 ;
110
110
}
111
111
112
+ /**
113
+ * Get offset of network device driver private data
114
+ *
115
+ * @v driver Upper-layer driver, or NULL for device driver
116
+ * @ret offset Offset of driver private data
117
+ */
118
+ static size_t netdev_priv_offset ( struct net_driver * driver ) {
119
+ struct net_device * netdev ;
120
+ unsigned int num_configs ;
121
+ size_t offset ;
122
+
123
+ /* Allow space for network device */
124
+ offset = sizeof ( * netdev );
125
+
126
+ /* Allow space for configurations */
127
+ num_configs = table_num_entries ( NET_DEVICE_CONFIGURATORS );
128
+ offset += ( num_configs * sizeof ( netdev -> configs [0 ] ) );
129
+
130
+ /* Place variable-length device driver private data at end */
131
+ if ( ! driver )
132
+ driver = table_end ( NET_DRIVERS );
133
+
134
+ /* Allow space for preceding upper-layer drivers' private data */
135
+ for_each_table_entry_continue_reverse ( driver , NET_DRIVERS ) {
136
+ offset += driver -> priv_len ;
137
+ }
138
+
139
+ /* Sanity check */
140
+ assert ( ( offset & ( sizeof ( void * ) - 1 ) ) == 0 );
141
+
142
+ return offset ;
143
+ }
144
+
145
+ /**
146
+ * Get network device driver private data
147
+ *
148
+ * @v netdev Network device
149
+ * @v driver Upper-layer driver, or NULL for device driver
150
+ * @ret priv Driver private data
151
+ */
152
+ static void * netdev_priv ( struct net_device * netdev ,
153
+ struct net_driver * driver ) {
154
+
155
+ return ( ( ( void * ) netdev ) + netdev_priv_offset ( driver ) );
156
+ }
157
+
112
158
/**
113
159
* Notify drivers of network device or link state change
114
160
*
115
161
* @v netdev Network device
116
162
*/
117
163
static void netdev_notify ( struct net_device * netdev ) {
118
164
struct net_driver * driver ;
165
+ void * priv ;
119
166
120
167
for_each_table_entry ( driver , NET_DRIVERS ) {
168
+ priv = netdev_priv ( netdev , driver );
121
169
if ( driver -> notify )
122
- driver -> notify ( netdev );
170
+ driver -> notify ( netdev , priv );
123
171
}
124
172
}
125
173
@@ -675,14 +723,8 @@ struct net_device * alloc_netdev ( size_t priv_len ) {
675
723
struct net_device * netdev ;
676
724
struct net_device_configurator * configurator ;
677
725
struct net_device_configuration * config ;
678
- unsigned int num_configs ;
679
- size_t confs_len ;
680
- size_t total_len ;
681
726
682
- num_configs = table_num_entries ( NET_DEVICE_CONFIGURATORS );
683
- confs_len = ( num_configs * sizeof ( netdev -> configs [0 ] ) );
684
- total_len = ( sizeof ( * netdev ) + confs_len + priv_len );
685
- netdev = zalloc ( total_len );
727
+ netdev = zalloc ( netdev_priv_offset ( NULL ) + priv_len );
686
728
if ( netdev ) {
687
729
ref_init ( & netdev -> refcnt , free_netdev );
688
730
netdev -> link_rc = - EUNKNOWN_LINK_STATUS ;
@@ -701,8 +743,7 @@ struct net_device * alloc_netdev ( size_t priv_len ) {
701
743
& netdev -> refcnt );
702
744
config ++ ;
703
745
}
704
- netdev -> priv = ( ( ( void * ) netdev ) + sizeof ( * netdev ) +
705
- confs_len );
746
+ netdev -> priv = netdev_priv ( netdev , NULL );
706
747
}
707
748
return netdev ;
708
749
}
@@ -722,6 +763,7 @@ int register_netdev ( struct net_device *netdev ) {
722
763
struct net_device * duplicate ;
723
764
unsigned int i ;
724
765
uint32_t seed ;
766
+ void * priv ;
725
767
int rc ;
726
768
727
769
/* Set initial link-layer address, if not already set */
@@ -784,7 +826,9 @@ int register_netdev ( struct net_device *netdev ) {
784
826
785
827
/* Probe device */
786
828
for_each_table_entry ( driver , NET_DRIVERS ) {
787
- if ( driver -> probe && ( rc = driver -> probe ( netdev ) ) != 0 ) {
829
+ priv = netdev_priv ( netdev , driver );
830
+ if ( driver -> probe &&
831
+ ( rc = driver -> probe ( netdev , priv ) ) != 0 ) {
788
832
DBGC ( netdev , "NETDEV %s could not add %s device: "
789
833
"%s\n" , netdev -> name , driver -> name ,
790
834
strerror ( rc ) );
@@ -796,8 +840,9 @@ int register_netdev ( struct net_device *netdev ) {
796
840
797
841
err_probe :
798
842
for_each_table_entry_continue_reverse ( driver , NET_DRIVERS ) {
843
+ priv = netdev_priv ( netdev , driver );
799
844
if ( driver -> remove )
800
- driver -> remove ( netdev );
845
+ driver -> remove ( netdev , priv );
801
846
}
802
847
clear_settings ( netdev_settings ( netdev ) );
803
848
unregister_settings ( netdev_settings ( netdev ) );
@@ -896,14 +941,16 @@ void netdev_close ( struct net_device *netdev ) {
896
941
*/
897
942
void unregister_netdev ( struct net_device * netdev ) {
898
943
struct net_driver * driver ;
944
+ void * priv ;
899
945
900
946
/* Ensure device is closed */
901
947
netdev_close ( netdev );
902
948
903
949
/* Remove device */
904
950
for_each_table_entry_reverse ( driver , NET_DRIVERS ) {
951
+ priv = netdev_priv ( netdev , driver );
905
952
if ( driver -> remove )
906
- driver -> remove ( netdev );
953
+ driver -> remove ( netdev , priv );
907
954
}
908
955
909
956
/* Unregister per-netdev configuration settings */
0 commit comments