aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcmcia')
-rw-r--r--drivers/net/pcmcia/axnet_cs.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 853b586e481a..23ce77b1d5b0 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -850,6 +850,34 @@ static void block_output(struct net_device *dev, int count,
850 outsw(nic_base + AXNET_DATAPORT, buf, count>>1); 850 outsw(nic_base + AXNET_DATAPORT, buf, count>>1);
851} 851}
852 852
853static struct pcmcia_device_id axnet_ids[] = {
854 PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081),
855 PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301),
856 PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301),
857 PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303),
858 PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309),
859 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1106),
860 PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab),
861 PCMCIA_DEVICE_PROD_ID124("Fast Ethernet", "16-bit PC Card", "AX88190", 0xb4be14e3, 0x9a12eb6a, 0xab9be5ef),
862 PCMCIA_DEVICE_PROD_ID12("ASIX", "AX88190", 0x0959823b, 0xab9be5ef),
863 PCMCIA_DEVICE_PROD_ID12("Billionton", "LNA-100B", 0x552ab682, 0xbc3b87e1),
864 PCMCIA_DEVICE_PROD_ID12("CHEETAH ETHERCARD", "EN2228", 0x00fa7bc8, 0x00e990cc),
865 PCMCIA_DEVICE_PROD_ID12("CNet", "CNF301", 0xbc477dde, 0x78c5f40b),
866 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXD", 0x5261440f, 0x436768c5),
867 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEtherII PCC-TXD", 0x5261440f, 0x730df72e),
868 PCMCIA_DEVICE_PROD_ID12("Dynalink", "L100C16", 0x55632fd5, 0x66bc2a90),
869 PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8),
870 PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC3-TX", 0x481e0094, 0xf91af609),
871 PCMCIA_DEVICE_PROD_ID12("PCMCIA", "100BASE", 0x281f1c5d, 0x7c2add04),
872 PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEtherCard", 0x281f1c5d, 0x7ef26116),
873 PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FEP501", 0x281f1c5d, 0x2e272058),
874 PCMCIA_DEVICE_PROD_ID14("Network Everywhere", "AX88190", 0x820a67b6, 0xab9be5ef),
875 /* this is not specific enough */
876 /* PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), */
877 PCMCIA_DEVICE_NULL,
878};
879MODULE_DEVICE_TABLE(pcmcia, axnet_ids);
880
853static struct pcmcia_driver axnet_cs_driver = { 881static struct pcmcia_driver axnet_cs_driver = {
854 .owner = THIS_MODULE, 882 .owner = THIS_MODULE,
855 .drv = { 883 .drv = {
@@ -857,6 +885,7 @@ static struct pcmcia_driver axnet_cs_driver = {
857 }, 885 },
858 .attach = axnet_attach, 886 .attach = axnet_attach,
859 .detach = axnet_detach, 887 .detach = axnet_detach,
888 .id_table = axnet_ids,
860}; 889};
861 890
862static int __init init_axnet_cs(void) 891static int __init init_axnet_cs(void)
.git/commit/fs/file.c?id=ab2af1f5005069321c5d130f09cce577b03f43ef'>ab2af1f50050
5466b456ed67
ab2af1f50050
5466b456ed67
ab2af1f50050
1da177e4c3f4
ab2af1f50050



593be07ae8f6

ab2af1f50050

1da177e4c3f4
ab2af1f50050

ab2af1f50050



5466b456ed67
ab2af1f50050
5466b456ed67
ab2af1f50050
5466b456ed67

1da177e4c3f4
5466b456ed67











1da177e4c3f4

5466b456ed67
1da177e4c3f4
5466b456ed67

1da177e4c3f4
ab2af1f50050
5466b456ed67




ab2af1f50050
5466b456ed67


9cfe015aa424

bbea9f69668a
5466b456ed67

bbea9f69668a
5466b456ed67














ab2af1f50050
5466b456ed67



ab2af1f50050
5466b456ed67
ab2af1f50050

1da177e4c3f4
ab2af1f50050
74d392aaabfc




ab2af1f50050




74d392aaabfc
ab2af1f50050

74d392aaabfc
ab2af1f50050
74d392aaabfc

ab2af1f50050
74d392aaabfc

ab2af1f50050
74d392aaabfc
bbea9f69668a
74d392aaabfc


4fd45812cbe8
01b2d93ca4c4
ab2af1f50050
74d392aaabfc
5466b456ed67


ab2af1f50050
74d392aaabfc
1da177e4c3f4



74d392aaabfc




1da177e4c3f4


badf16621c1f
1da177e4c3f4
badf16621c1f
74d392aaabfc
bbea9f69668a
74d392aaabfc

9cfe015aa424
74d392aaabfc



1da177e4c3f4
ab2af1f50050




65f27f38446e
ab2af1f50050





0a945022778f
ab2af1f50050

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258














                                                             







                              


                             

                                             






                                                                              
 
                                                   
 
                              


                                                 

 
                                                  
 

                                                                
            
                               

 
                                                  
 



                                                            
 
 
                                                       
 

                                                             
                            
 





                                                 


                                


                           
 
                                           

                                                                     
                                    
 
                     
 
                                              
                  

                                                                           
                   

                                                                               

                       
                                                                  
                               
                                     
                           
                



                                                         

                                                                     

                                                
         

 



                                                                        
                                                                    
 
                              
 

                                              
                       











                                                                      

 
                                                      
 

                            
 
          




                                                                               
           


                                             

                                    
 

                                                          
                         














                                                                          
                   



                        
                   
    

                    
 
  




                                                                            




                                                             
                                          

                                       
                                    
                                     

                               
          

                                                                              
           
                                       
                                     


                                                        
                                                       
                                              
                
                                                                 


                                    
         
                 



                




                                                                               


                                                    
                            
 
                                   
                                   
                              

                            
                                 



                                         
 




                                                                        
                                                 





                                  
                                

                                           
/*
 *  linux/fs/file.c
 *
 *  Copyright (C) 1998-1999, Stephen Tweedie and Bill Hawes
 *
 *  Manage the dynamic fd arrays in the process files_struct.
 */

#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/file.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
#include <linux/workqueue.h>

struct fdtable_defer {
	spinlock_t lock;
	struct work_struct wq;
	struct fdtable *next;
};

int sysctl_nr_open __read_mostly = 1024*1024;

/*
 * We use this list to defer free fdtables that have vmalloced
 * sets/arrays. By keeping a per-cpu list, we avoid having to embed
 * the work_struct in fdtable itself which avoids a 64 byte (i386) increase in
 * this per-task structure.
 */
static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list);

static inline void * alloc_fdmem(unsigned int size)
{
	if (size <= PAGE_SIZE)
		return kmalloc(size, GFP_KERNEL);
	else
		return vmalloc(size);
}

static inline void free_fdarr(struct fdtable *fdt)
{
	if (fdt->max_fds <= (PAGE_SIZE / sizeof(struct file *)))
		kfree(fdt->fd);
	else
		vfree(fdt->fd);
}

static inline void free_fdset(struct fdtable *fdt)
{
	if (fdt->max_fds <= (PAGE_SIZE * BITS_PER_BYTE / 2))
		kfree(fdt->open_fds);
	else
		vfree(fdt->open_fds);
}

static void free_fdtable_work(struct work_struct *work)
{
	struct fdtable_defer *f =
		container_of(work, struct fdtable_defer, wq);
	struct fdtable *fdt;

	spin_lock_bh(&f->lock);
	fdt = f->next;
	f->next = NULL;
	spin_unlock_bh(&f->lock);
	while(fdt) {
		struct fdtable *next = fdt->next;
		vfree(fdt->fd);
		free_fdset(fdt);
		kfree(fdt);
		fdt = next;
	}
}

void free_fdtable_rcu(struct rcu_head *rcu)
{
	struct fdtable *fdt = container_of(rcu, struct fdtable, rcu);
	struct fdtable_defer *fddef;

	BUG_ON(!fdt);

	if (fdt->max_fds <= NR_OPEN_DEFAULT) {
		/*
		 * This fdtable is embedded in the files structure and that
		 * structure itself is getting destroyed.
		 */
		kmem_cache_free(files_cachep,
				container_of(fdt, struct files_struct, fdtab));
		return;
	}
	if (fdt->max_fds <= (PAGE_SIZE / sizeof(struct file *))) {
		kfree(fdt->fd);
		kfree(fdt->open_fds);
		kfree(fdt);
	} else {
		fddef = &get_cpu_var(fdtable_defer_list);
		spin_lock(&fddef->lock);
		fdt->next = fddef->next;
		fddef->next = fdt;
		/* vmallocs are handled from the workqueue context */
		schedule_work(&fddef->wq);
		spin_unlock(&fddef->lock);
		put_cpu_var(fdtable_defer_list);
	}
}

/*
 * Expand the fdset in the files_struct.  Called with the files spinlock
 * held for write.
 */
static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt)
{
	unsigned int cpy, set;

	BUG_ON(nfdt->max_fds < ofdt->max_fds);
	if (ofdt->max_fds == 0)
		return;

	cpy = ofdt->max_fds * sizeof(struct file *);
	set = (nfdt->max_fds - ofdt->max_fds) * sizeof(struct file *);
	memcpy(nfdt->fd, ofdt->fd, cpy);
	memset((char *)(nfdt->fd) + cpy, 0, set);

	cpy = ofdt->max_fds / BITS_PER_BYTE;
	set = (nfdt->max_fds - ofdt->max_fds) / BITS_PER_BYTE;
	memcpy(nfdt->open_fds, ofdt->open_fds, cpy);
	memset((char *)(nfdt->open_fds) + cpy, 0, set);
	memcpy(nfdt->close_on_exec, ofdt->close_on_exec, cpy);
	memset((char *)(nfdt->close_on_exec) + cpy, 0, set);
}

static struct fdtable * alloc_fdtable(unsigned int nr)
{
	struct fdtable *fdt;
	char *data;

	/*
	 * Figure out how many fds we actually want to support in this fdtable.
	 * Allocation steps are keyed to the size of the fdarray, since it
	 * grows far faster than any of the other dynamic data. We try to fit
	 * the fdarray into comfortable page-tuned chunks: starting at 1024B
	 * and growing in powers of two from there on.
	 */
	nr /= (1024 / sizeof(struct file *));
	nr = roundup_pow_of_two(nr + 1);
	nr *= (1024 / sizeof(struct file *));
	if (nr > sysctl_nr_open)
		nr = sysctl_nr_open;

	fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL);
	if (!fdt)
		goto out;
	fdt->max_fds = nr;
	data = alloc_fdmem(nr * sizeof(struct file *));
	if (!data)
		goto out_fdt;
	fdt->fd = (struct file **)data;
	data = alloc_fdmem(max_t(unsigned int,
				 2 * nr / BITS_PER_BYTE, L1_CACHE_BYTES));
	if (!data)
		goto out_arr;
	fdt->open_fds = (fd_set *)data;
	data += nr / BITS_PER_BYTE;
	fdt->close_on_exec = (fd_set *)data;
	INIT_RCU_HEAD(&fdt->rcu);
	fdt->next = NULL;

	return fdt;

out_arr:
	free_fdarr(fdt);
out_fdt:
	kfree(fdt);
out:
	return NULL;
}

/*
 * Expand the file descriptor table.
 * This function will allocate a new fdtable and both fd array and fdset, of
 * the given size.
 * Return <0 error code on error; 1 on successful completion.
 * The files->file_lock should be held on entry, and will be held on exit.
 */
static int expand_fdtable(struct files_struct *files, int nr)
	__releases(files->file_lock)
	__acquires(files->file_lock)
{
	struct fdtable *new_fdt, *cur_fdt;

	spin_unlock(&files->file_lock);
	new_fdt = alloc_fdtable(nr);
	spin_lock(&files->file_lock);
	if (!new_fdt)
		return -ENOMEM;
	/*
	 * Check again since another task may have expanded the fd table while
	 * we dropped the lock
	 */
	cur_fdt = files_fdtable(files);
	if (nr >= cur_fdt->max_fds) {
		/* Continue as planned */
		copy_fdtable(new_fdt, cur_fdt);
		rcu_assign_pointer(files->fdt, new_fdt);
		if (cur_fdt->max_fds > NR_OPEN_DEFAULT)
			free_fdtable(cur_fdt);
	} else {
		/* Somebody else expanded, so undo our attempt */
		free_fdarr(new_fdt);
		free_fdset(new_fdt);
		kfree(new_fdt);
	}
	return 1;
}

/*
 * Expand files.
 * This function will expand the file structures, if the requested size exceeds
 * the current capacity and there is room for expansion.
 * Return <0 error code on error; 0 when nothing done; 1 when files were
 * expanded and execution may have blocked.
 * The files->file_lock should be held on entry, and will be held on exit.
 */
int expand_files(struct files_struct *files, int nr)
{
	struct fdtable *fdt;

	fdt = files_fdtable(files);
	/* Do we need to expand? */
	if (nr < fdt->max_fds)
		return 0;
	/* Can we expand? */
	if (nr >= sysctl_nr_open)
		return -EMFILE;

	/* All good, so we try */
	return expand_fdtable(files, nr);
}

static void __devinit fdtable_defer_list_init(int cpu)
{
	struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu);
	spin_lock_init(&fddef->lock);
	INIT_WORK(&fddef->wq, free_fdtable_work);
	fddef->next = NULL;
}

void __init files_defer_init(void)
{
	int i;
	for_each_possible_cpu(i)
		fdtable_defer_list_init(i);
}