Blame view

net/atm/resources.c 9.88 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
  /* net/atm/resources.c - Statically allocated resources */
  
  /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
  
  /* Fixes
   * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   * 2002/01 - don't free the whole struct sock on sk->destruct time,
   * 	     use the default destruct function initialized by sock_init_data */
99824461e   Joe Perches   net/atm: Convert ...
9
  #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
13
14
15
16
17
  #include <linux/ctype.h>
  #include <linux/string.h>
  #include <linux/atmdev.h>
  #include <linux/sonet.h>
  #include <linux/kernel.h> /* for barrier */
  #include <linux/module.h>
  #include <linux/bitops.h>
4fc268d24   Randy Dunlap   [PATCH] capable/c...
18
  #include <linux/capability.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
  #include <linux/delay.h>
57b47a53e   Ingo Molnar   [NET]: sem2mutex ...
20
  #include <linux/mutex.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
21
  #include <linux/slab.h>
57b47a53e   Ingo Molnar   [NET]: sem2mutex ...
22

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
26
27
28
29
30
  #include <net/sock.h>	 /* for struct sock */
  
  #include "common.h"
  #include "resources.h"
  #include "addr.h"
  
  
  LIST_HEAD(atm_devs);
57b47a53e   Ingo Molnar   [NET]: sem2mutex ...
31
  DEFINE_MUTEX(atm_dev_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
34
35
  
  static struct atm_dev *__alloc_atm_dev(const char *type)
  {
  	struct atm_dev *dev;
0da974f4f   Panagiotis Issaris   [NET]: Conversion...
36
  	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
38
  	if (!dev)
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
43
  	dev->type = type;
  	dev->signal = ATM_PHY_SIG_UNKNOWN;
  	dev->link_rate = ATM_OC3_PCR;
  	spin_lock_init(&dev->lock);
  	INIT_LIST_HEAD(&dev->local);
0f21ba7cc   Eric Kinzie   [ATM]: add suppor...
44
  	INIT_LIST_HEAD(&dev->lecs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
46
47
  
  	return dev;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
49
50
51
52
53
54
  static struct atm_dev *__atm_dev_lookup(int number)
  {
  	struct atm_dev *dev;
  	struct list_head *p;
  
  	list_for_each(p, &atm_devs) {
  		dev = list_entry(p, struct atm_dev, dev_list);
aaaaaadbe   Stanislaw Gruszka   [ATM]: avoid race...
55
  		if (dev->number == number) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
58
59
60
61
62
63
64
65
  			atm_dev_hold(dev);
  			return dev;
  		}
  	}
  	return NULL;
  }
  
  struct atm_dev *atm_dev_lookup(int number)
  {
  	struct atm_dev *dev;
57b47a53e   Ingo Molnar   [NET]: sem2mutex ...
66
  	mutex_lock(&atm_dev_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
  	dev = __atm_dev_lookup(number);
57b47a53e   Ingo Molnar   [NET]: sem2mutex ...
68
  	mutex_unlock(&atm_dev_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
70
  	return dev;
  }
07b54c9ad   Joe Perches   net/atm/resources...
71
  EXPORT_SYMBOL(atm_dev_lookup);
64bf69ddf   Stanislaw Gruszka   [ATM]: deregistra...
72

d9ca676bc   Dan Williams   atm: correct sysf...
73
74
75
  struct atm_dev *atm_dev_register(const char *type, struct device *parent,
  				 const struct atmdev_ops *ops, int number,
  				 unsigned long *flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
78
79
80
  {
  	struct atm_dev *dev, *inuse;
  
  	dev = __alloc_atm_dev(type);
  	if (!dev) {
99824461e   Joe Perches   net/atm: Convert ...
81
82
  		pr_err("no space for dev %s
  ", type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
  		return NULL;
  	}
57b47a53e   Ingo Molnar   [NET]: sem2mutex ...
85
  	mutex_lock(&atm_dev_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
  	if (number != -1) {
07b54c9ad   Joe Perches   net/atm/resources...
87
88
  		inuse = __atm_dev_lookup(number);
  		if (inuse) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
  			atm_dev_put(inuse);
57b47a53e   Ingo Molnar   [NET]: sem2mutex ...
90
  			mutex_unlock(&atm_dev_mutex);
ebc37b611   Adrian Bunk   [ATM]: net/atm/re...
91
  			kfree(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  			return NULL;
  		}
  		dev->number = number;
  	} else {
  		dev->number = 0;
  		while ((inuse = __atm_dev_lookup(dev->number))) {
  			atm_dev_put(inuse);
  			dev->number++;
  		}
  	}
  
  	dev->ops = ops;
  	if (flags)
  		dev->flags = *flags;
  	else
  		memset(&dev->flags, 0, sizeof(dev->flags));
  	memset(&dev->stats, 0, sizeof(dev->stats));
  	atomic_set(&dev->refcnt, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
111
  
  	if (atm_proc_dev_register(dev) < 0) {
99824461e   Joe Perches   net/atm: Convert ...
112
113
  		pr_err("atm_proc_dev_register failed for dev %s
  ", type);
656d98b09   Roman Kagan   [ATM]: basic sysf...
114
115
  		goto out_fail;
  	}
d9ca676bc   Dan Williams   atm: correct sysf...
116
  	if (atm_register_sysfs(dev, parent) < 0) {
99824461e   Joe Perches   net/atm: Convert ...
117
118
  		pr_err("atm_register_sysfs failed for dev %s
  ", type);
656d98b09   Roman Kagan   [ATM]: basic sysf...
119
120
  		atm_proc_dev_deregister(dev);
  		goto out_fail;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
  	}
656d98b09   Roman Kagan   [ATM]: basic sysf...
122

aaaaaadbe   Stanislaw Gruszka   [ATM]: avoid race...
123
  	list_add_tail(&dev->dev_list, &atm_devs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124

656d98b09   Roman Kagan   [ATM]: basic sysf...
125
126
  out:
  	mutex_unlock(&atm_dev_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
  	return dev;
656d98b09   Roman Kagan   [ATM]: basic sysf...
128
129
130
131
132
  
  out_fail:
  	kfree(dev);
  	dev = NULL;
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
  }
07b54c9ad   Joe Perches   net/atm/resources...
134
  EXPORT_SYMBOL(atm_dev_register);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
136
137
  
  void atm_dev_deregister(struct atm_dev *dev)
  {
64bf69ddf   Stanislaw Gruszka   [ATM]: deregistra...
138
139
140
141
  	BUG_ON(test_bit(ATM_DF_REMOVED, &dev->flags));
  	set_bit(ATM_DF_REMOVED, &dev->flags);
  
  	/*
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
142
143
  	 * if we remove current device from atm_devs list, new device
  	 * with same number can appear, such we need deregister proc,
64bf69ddf   Stanislaw Gruszka   [ATM]: deregistra...
144
145
  	 * release async all vccs and remove them from vccs list too
  	 */
57b47a53e   Ingo Molnar   [NET]: sem2mutex ...
146
  	mutex_lock(&atm_dev_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
  	list_del(&dev->dev_list);
57b47a53e   Ingo Molnar   [NET]: sem2mutex ...
148
  	mutex_unlock(&atm_dev_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149

64bf69ddf   Stanislaw Gruszka   [ATM]: deregistra...
150
  	atm_dev_release_vccs(dev);
656d98b09   Roman Kagan   [ATM]: basic sysf...
151
  	atm_unregister_sysfs(dev);
64bf69ddf   Stanislaw Gruszka   [ATM]: deregistra...
152
  	atm_proc_dev_deregister(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153

64bf69ddf   Stanislaw Gruszka   [ATM]: deregistra...
154
  	atm_dev_put(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
  }
07b54c9ad   Joe Perches   net/atm/resources...
156
  EXPORT_SYMBOL(atm_dev_deregister);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
158
159
160
161
162
163
164
  
  static void copy_aal_stats(struct k_atm_aal_stats *from,
      struct atm_aal_stats *to)
  {
  #define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
  	__AAL_STAT_ITEMS
  #undef __HANDLE_ITEM
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
166
167
168
169
170
171
  static void subtract_aal_stats(struct k_atm_aal_stats *from,
      struct atm_aal_stats *to)
  {
  #define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
  	__AAL_STAT_ITEMS
  #undef __HANDLE_ITEM
  }
07b54c9ad   Joe Perches   net/atm/resources...
172
173
  static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats __user *arg,
  		       int zero)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
  {
  	struct atm_dev_stats tmp;
  	int error = 0;
  
  	copy_aal_stats(&dev->stats.aal0, &tmp.aal0);
  	copy_aal_stats(&dev->stats.aal34, &tmp.aal34);
  	copy_aal_stats(&dev->stats.aal5, &tmp.aal5);
  	if (arg)
  		error = copy_to_user(arg, &tmp, sizeof(tmp));
  	if (zero && !error) {
  		subtract_aal_stats(&dev->stats.aal0, &tmp.aal0);
  		subtract_aal_stats(&dev->stats.aal34, &tmp.aal34);
  		subtract_aal_stats(&dev->stats.aal5, &tmp.aal5);
  	}
  	return error ? -EFAULT : 0;
  }
8865c418c   David Woodhouse   atm: 32-bit ioctl...
190
  int atm_dev_ioctl(unsigned int cmd, void __user *arg, int compat)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
193
194
195
196
  {
  	void __user *buf;
  	int error, len, number, size = 0;
  	struct atm_dev *dev;
  	struct list_head *p;
  	int *tmp_buf, *tmp_p;
8865c418c   David Woodhouse   atm: 32-bit ioctl...
197
198
199
200
201
202
  	int __user *sioc_len;
  	int __user *iobuf_len;
  
  #ifndef CONFIG_COMPAT
  	compat = 0; /* Just so the compiler _knows_ */
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
  	switch (cmd) {
07b54c9ad   Joe Perches   net/atm/resources...
204
205
  	case ATM_GETNAMES:
  		if (compat) {
8865c418c   David Woodhouse   atm: 32-bit ioctl...
206
  #ifdef CONFIG_COMPAT
07b54c9ad   Joe Perches   net/atm/resources...
207
208
209
210
211
212
  			struct compat_atm_iobuf __user *ciobuf = arg;
  			compat_uptr_t cbuf;
  			iobuf_len = &ciobuf->length;
  			if (get_user(cbuf, &ciobuf->buffer))
  				return -EFAULT;
  			buf = compat_ptr(cbuf);
8865c418c   David Woodhouse   atm: 32-bit ioctl...
213
  #endif
07b54c9ad   Joe Perches   net/atm/resources...
214
215
216
217
  		} else {
  			struct atm_iobuf __user *iobuf = arg;
  			iobuf_len = &iobuf->length;
  			if (get_user(buf, &iobuf->buffer))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
  				return -EFAULT;
07b54c9ad   Joe Perches   net/atm/resources...
219
220
221
222
223
224
225
  		}
  		if (get_user(len, iobuf_len))
  			return -EFAULT;
  		mutex_lock(&atm_dev_mutex);
  		list_for_each(p, &atm_devs)
  			size += sizeof(int);
  		if (size > len) {
57b47a53e   Ingo Molnar   [NET]: sem2mutex ...
226
  			mutex_unlock(&atm_dev_mutex);
07b54c9ad   Joe Perches   net/atm/resources...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
  			return -E2BIG;
  		}
  		tmp_buf = kmalloc(size, GFP_ATOMIC);
  		if (!tmp_buf) {
  			mutex_unlock(&atm_dev_mutex);
  			return -ENOMEM;
  		}
  		tmp_p = tmp_buf;
  		list_for_each(p, &atm_devs) {
  			dev = list_entry(p, struct atm_dev, dev_list);
  			*tmp_p++ = dev->number;
  		}
  		mutex_unlock(&atm_dev_mutex);
  		error = ((copy_to_user(buf, tmp_buf, size)) ||
  			 put_user(size, iobuf_len))
  			? -EFAULT : 0;
  		kfree(tmp_buf);
  		return error;
  	default:
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
  	}
8865c418c   David Woodhouse   atm: 32-bit ioctl...
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
  	if (compat) {
  #ifdef CONFIG_COMPAT
  		struct compat_atmif_sioc __user *csioc = arg;
  		compat_uptr_t carg;
  
  		sioc_len = &csioc->length;
  		if (get_user(carg, &csioc->arg))
  			return -EFAULT;
  		buf = compat_ptr(carg);
  
  		if (get_user(len, &csioc->length))
  			return -EFAULT;
  		if (get_user(number, &csioc->number))
  			return -EFAULT;
  #endif
  	} else {
  		struct atmif_sioc __user *sioc = arg;
  
  		sioc_len = &sioc->length;
  		if (get_user(buf, &sioc->arg))
  			return -EFAULT;
  		if (get_user(len, &sioc->length))
  			return -EFAULT;
  		if (get_user(number, &sioc->number))
  			return -EFAULT;
  	}
07b54c9ad   Joe Perches   net/atm/resources...
274
275
276
277
  
  	dev = try_then_request_module(atm_dev_lookup(number), "atm-device-%d",
  				      number);
  	if (!dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278
  		return -ENODEV;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
279

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
  	switch (cmd) {
07b54c9ad   Joe Perches   net/atm/resources...
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
  	case ATM_GETTYPE:
  		size = strlen(dev->type) + 1;
  		if (copy_to_user(buf, dev->type, size)) {
  			error = -EFAULT;
  			goto done;
  		}
  		break;
  	case ATM_GETESI:
  		size = ESI_LEN;
  		if (copy_to_user(buf, dev->esi, size)) {
  			error = -EFAULT;
  			goto done;
  		}
  		break;
  	case ATM_SETESI:
  	{
  		int i;
  
  		for (i = 0; i < ESI_LEN; i++)
  			if (dev->esi[i]) {
  				error = -EEXIST;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
303
  				goto done;
  			}
07b54c9ad   Joe Perches   net/atm/resources...
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
  	}
  	/* fall through */
  	case ATM_SETESIF:
  	{
  		unsigned char esi[ESI_LEN];
  
  		if (!capable(CAP_NET_ADMIN)) {
  			error = -EPERM;
  			goto done;
  		}
  		if (copy_from_user(esi, buf, ESI_LEN)) {
  			error = -EFAULT;
  			goto done;
  		}
  		memcpy(dev->esi, esi, ESI_LEN);
  		error =  ESI_LEN;
  		goto done;
  	}
  	case ATM_GETSTATZ:
  		if (!capable(CAP_NET_ADMIN)) {
  			error = -EPERM;
  			goto done;
  		}
  		/* fall through */
  	case ATM_GETSTAT:
  		size = sizeof(struct atm_dev_stats);
  		error = fetch_stats(dev, buf, cmd == ATM_GETSTATZ);
  		if (error)
  			goto done;
  		break;
  	case ATM_GETCIRANGE:
  		size = sizeof(struct atm_cirange);
  		if (copy_to_user(buf, &dev->ci_range, size)) {
  			error = -EFAULT;
  			goto done;
  		}
  		break;
  	case ATM_GETLINKRATE:
  		size = sizeof(int);
  		if (copy_to_user(buf, &dev->link_rate, size)) {
  			error = -EFAULT;
  			goto done;
  		}
  		break;
  	case ATM_RSTADDR:
  		if (!capable(CAP_NET_ADMIN)) {
  			error = -EPERM;
  			goto done;
  		}
  		atm_reset_addr(dev, ATM_ADDR_LOCAL);
  		break;
  	case ATM_ADDADDR:
  	case ATM_DELADDR:
  	case ATM_ADDLECSADDR:
  	case ATM_DELLECSADDR:
  	{
  		struct sockaddr_atmsvc addr;
  
  		if (!capable(CAP_NET_ADMIN)) {
  			error = -EPERM;
  			goto done;
  		}
  
  		if (copy_from_user(&addr, buf, sizeof(addr))) {
  			error = -EFAULT;
  			goto done;
  		}
  		if (cmd == ATM_ADDADDR || cmd == ATM_ADDLECSADDR)
  			error = atm_add_addr(dev, &addr,
  					     (cmd == ATM_ADDADDR ?
0f21ba7cc   Eric Kinzie   [ATM]: add suppor...
374
  					      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
07b54c9ad   Joe Perches   net/atm/resources...
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
  		else
  			error = atm_del_addr(dev, &addr,
  					     (cmd == ATM_DELADDR ?
  					      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
  		goto done;
  	}
  	case ATM_GETADDR:
  	case ATM_GETLECSADDR:
  		error = atm_get_addr(dev, buf, len,
  				     (cmd == ATM_GETADDR ?
  				      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
  		if (error < 0)
  			goto done;
  		size = error;
  		/* may return 0, but later on size == 0 means "don't
  		   write the length" */
  		error = put_user(size, sioc_len) ? -EFAULT : 0;
  		goto done;
  	case ATM_SETLOOP:
  		if (__ATM_LM_XTRMT((int) (unsigned long) buf) &&
  		    __ATM_LM_XTLOC((int) (unsigned long) buf) >
  		    __ATM_LM_XTRMT((int) (unsigned long) buf)) {
  			error = -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
  			goto done;
07b54c9ad   Joe Perches   net/atm/resources...
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
  		}
  		/* fall through */
  	case ATM_SETCIRANGE:
  	case SONET_GETSTATZ:
  	case SONET_SETDIAG:
  	case SONET_CLRDIAG:
  	case SONET_SETFRAMING:
  		if (!capable(CAP_NET_ADMIN)) {
  			error = -EPERM;
  			goto done;
  		}
  		/* fall through */
  	default:
  		if (compat) {
  #ifdef CONFIG_COMPAT
  			if (!dev->ops->compat_ioctl) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
416
417
  				error = -EINVAL;
  				goto done;
  			}
07b54c9ad   Joe Perches   net/atm/resources...
418
  			size = dev->ops->compat_ioctl(dev, cmd, buf);
8865c418c   David Woodhouse   atm: 32-bit ioctl...
419
  #endif
07b54c9ad   Joe Perches   net/atm/resources...
420
421
422
  		} else {
  			if (!dev->ops->ioctl) {
  				error = -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
424
  				goto done;
  			}
07b54c9ad   Joe Perches   net/atm/resources...
425
426
427
428
429
430
  			size = dev->ops->ioctl(dev, cmd, buf);
  		}
  		if (size < 0) {
  			error = (size == -ENOIOCTLCMD ? -EINVAL : size);
  			goto done;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431
  	}
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
432

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433
  	if (size)
07b54c9ad   Joe Perches   net/atm/resources...
434
  		error = put_user(size, sioc_len) ? -EFAULT : 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
436
437
438
439
440
  	else
  		error = 0;
  done:
  	atm_dev_put(dev);
  	return error;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
442
  void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
  {
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
443
  	mutex_lock(&atm_dev_mutex);
67de79242   Li Zefan   net: atm: use seq...
444
  	return seq_list_start_head(&atm_devs, *pos);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
446
447
448
  }
  
  void atm_dev_seq_stop(struct seq_file *seq, void *v)
  {
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
449
  	mutex_unlock(&atm_dev_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
  }
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
451

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
452
453
  void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  {
67de79242   Li Zefan   net: atm: use seq...
454
  	return seq_list_next(v, &atm_devs, pos);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
  }