~ubuntu-branches/ubuntu/trusty/ndiswrapper/trusty

« back to all changes in this revision

Viewing changes to .pc/update-for-linux-3.10.patch/driver/proc.c

  • Committer: Package Import Robot
  • Author(s): Julian Andres Klode
  • Date: 2013-12-27 16:28:41 UTC
  • mfrom: (16.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20131227162841-gnl24tqjykf0h6k4
Tags: 1.59-1
* Imported Upstream version 1.59
* Drop unused patches and fixup the remaining ones

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
3
 
 *
4
 
 *  This program is free software; you can redistribute it and/or modify
5
 
 *  it under the terms of the GNU General Public License as published by
6
 
 *  the Free Software Foundation; either version 2 of the License, or
7
 
 *  (at your option) any later version.
8
 
 *
9
 
 *  This program is distributed in the hope that it will be useful,
10
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
 
 *  GNU General Public License for more details.
13
 
 *
14
 
 */
15
 
#include <linux/proc_fs.h>
16
 
#include <linux/module.h>
17
 
#include <asm/uaccess.h>
18
 
 
19
 
#include "ndis.h"
20
 
#include "iw_ndis.h"
21
 
#include "wrapndis.h"
22
 
#include "pnp.h"
23
 
#include "wrapper.h"
24
 
 
25
 
#define MAX_PROC_STR_LEN 32
26
 
 
27
 
static struct proc_dir_entry *wrap_procfs_entry;
28
 
 
29
 
static int procfs_read_ndis_stats(char *page, char **start, off_t off,
30
 
                                  int count, int *eof, void *data)
31
 
{
32
 
        char *p = page;
33
 
        struct ndis_device *wnd = (struct ndis_device *)data;
34
 
        struct ndis_wireless_stats stats;
35
 
        NDIS_STATUS res;
36
 
        ndis_rssi rssi;
37
 
 
38
 
        if (off != 0) {
39
 
                *eof = 1;
40
 
                return 0;
41
 
        }
42
 
 
43
 
        res = mp_query(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi));
44
 
        if (!res)
45
 
                p += sprintf(p, "signal_level=%d dBm\n", (s32)rssi);
46
 
 
47
 
        res = mp_query(wnd, OID_802_11_STATISTICS, &stats, sizeof(stats));
48
 
        if (!res) {
49
 
 
50
 
                p += sprintf(p, "tx_frames=%llu\n", stats.tx_frag);
51
 
                p += sprintf(p, "tx_multicast_frames=%llu\n",
52
 
                             stats.tx_multi_frag);
53
 
                p += sprintf(p, "tx_failed=%llu\n", stats.failed);
54
 
                p += sprintf(p, "tx_retry=%llu\n", stats.retry);
55
 
                p += sprintf(p, "tx_multi_retry=%llu\n", stats.multi_retry);
56
 
                p += sprintf(p, "tx_rtss_success=%llu\n", stats.rtss_succ);
57
 
                p += sprintf(p, "tx_rtss_fail=%llu\n", stats.rtss_fail);
58
 
                p += sprintf(p, "ack_fail=%llu\n", stats.ack_fail);
59
 
                p += sprintf(p, "frame_duplicates=%llu\n", stats.frame_dup);
60
 
                p += sprintf(p, "rx_frames=%llu\n", stats.rx_frag);
61
 
                p += sprintf(p, "rx_multicast_frames=%llu\n",
62
 
                             stats.rx_multi_frag);
63
 
                p += sprintf(p, "fcs_errors=%llu\n", stats.fcs_err);
64
 
        }
65
 
 
66
 
        if (p - page > count) {
67
 
                ERROR("wrote %td bytes (limit is %u)\n",
68
 
                      p - page, count);
69
 
                *eof = 1;
70
 
        }
71
 
 
72
 
        return p - page;
73
 
}
74
 
 
75
 
static int procfs_read_ndis_encr(char *page, char **start, off_t off,
76
 
                                 int count, int *eof, void *data)
77
 
{
78
 
        char *p = page;
79
 
        struct ndis_device *wnd = (struct ndis_device *)data;
80
 
        int i, encr_status, auth_mode, infra_mode;
81
 
        NDIS_STATUS res;
82
 
        struct ndis_essid essid;
83
 
        mac_address ap_address;
84
 
 
85
 
        if (off != 0) {
86
 
                *eof = 1;
87
 
                return 0;
88
 
        }
89
 
 
90
 
        res = mp_query(wnd, OID_802_11_BSSID,
91
 
                       &ap_address, sizeof(ap_address));
92
 
        if (res)
93
 
                memset(ap_address, 0, ETH_ALEN);
94
 
        p += sprintf(p, "ap_address=%2.2X", ap_address[0]);
95
 
        for (i = 1; i < ETH_ALEN; i++)
96
 
                p += sprintf(p, ":%2.2X", ap_address[i]);
97
 
        p += sprintf(p, "\n");
98
 
 
99
 
        res = mp_query(wnd, OID_802_11_SSID, &essid, sizeof(essid));
100
 
        if (!res)
101
 
                p += sprintf(p, "essid=%.*s\n", essid.length, essid.essid);
102
 
 
103
 
        res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &encr_status);
104
 
        if (!res) {
105
 
                typeof(&wnd->encr_info.keys[0]) tx_key;
106
 
                p += sprintf(p, "tx_key=%u\n", wnd->encr_info.tx_key_index);
107
 
                p += sprintf(p, "key=");
108
 
                tx_key = &wnd->encr_info.keys[wnd->encr_info.tx_key_index];
109
 
                if (tx_key->length > 0)
110
 
                        for (i = 0; i < tx_key->length; i++)
111
 
                                p += sprintf(p, "%2.2X", tx_key->key[i]);
112
 
                else
113
 
                        p += sprintf(p, "off");
114
 
                p += sprintf(p, "\n");
115
 
                p += sprintf(p, "encr_mode=%d\n", encr_status);
116
 
        }
117
 
        res = mp_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &auth_mode);
118
 
        if (!res)
119
 
                p += sprintf(p, "auth_mode=%d\n", auth_mode);
120
 
        res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, &infra_mode);
121
 
        p += sprintf(p, "mode=%s\n", (infra_mode == Ndis802_11IBSS) ?
122
 
                     "adhoc" : (infra_mode == Ndis802_11Infrastructure) ?
123
 
                     "managed" : "auto");
124
 
        if (p - page > count) {
125
 
                WARNING("wrote %td bytes (limit is %u)",
126
 
                        p - page, count);
127
 
                *eof = 1;
128
 
        }
129
 
 
130
 
        return p - page;
131
 
}
132
 
 
133
 
static int procfs_read_ndis_hw(char *page, char **start, off_t off,
134
 
                               int count, int *eof, void *data)
135
 
{
136
 
        char *p = page;
137
 
        struct ndis_device *wnd = (struct ndis_device *)data;
138
 
        struct ndis_configuration config;
139
 
        enum ndis_power power_mode;
140
 
        NDIS_STATUS res;
141
 
        ndis_tx_power_level tx_power;
142
 
        ULONG bit_rate;
143
 
        ndis_rts_threshold rts_threshold;
144
 
        ndis_fragmentation_threshold frag_threshold;
145
 
        ndis_antenna antenna;
146
 
        ULONG packet_filter;
147
 
        int n;
148
 
        mac_address mac;
149
 
        char *hw_status[] = {"ready", "initializing", "resetting", "closing",
150
 
                             "not ready"};
151
 
 
152
 
        if (off != 0) {
153
 
                *eof = 1;
154
 
                return 0;
155
 
        }
156
 
 
157
 
        res = mp_query_int(wnd, OID_GEN_HARDWARE_STATUS, &n);
158
 
        if (res == NDIS_STATUS_SUCCESS && n >= 0 && n < ARRAY_SIZE(hw_status))
159
 
                p += sprintf(p, "status=%s\n", hw_status[n]);
160
 
 
161
 
        res = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, mac, sizeof(mac));
162
 
        if (!res)
163
 
                p += sprintf(p, "mac: " MACSTRSEP "\n", MAC2STR(mac));
164
 
        res = mp_query(wnd, OID_802_11_CONFIGURATION, &config, sizeof(config));
165
 
        if (!res) {
166
 
                p += sprintf(p, "beacon_period=%u msec\n",
167
 
                             config.beacon_period);
168
 
                p += sprintf(p, "atim_window=%u msec\n", config.atim_window);
169
 
                p += sprintf(p, "frequency=%u kHz\n", config.ds_config);
170
 
                p += sprintf(p, "hop_pattern=%u\n",
171
 
                             config.fh_config.hop_pattern);
172
 
                p += sprintf(p, "hop_set=%u\n",
173
 
                             config.fh_config.hop_set);
174
 
                p += sprintf(p, "dwell_time=%u msec\n",
175
 
                             config.fh_config.dwell_time);
176
 
        }
177
 
 
178
 
        res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL,
179
 
                       &tx_power, sizeof(tx_power));
180
 
        if (!res)
181
 
                p += sprintf(p, "tx_power=%u mW\n", tx_power);
182
 
 
183
 
        res = mp_query(wnd, OID_GEN_LINK_SPEED, &bit_rate, sizeof(bit_rate));
184
 
        if (!res)
185
 
                p += sprintf(p, "bit_rate=%u kBps\n", (u32)bit_rate / 10);
186
 
 
187
 
        res = mp_query(wnd, OID_802_11_RTS_THRESHOLD,
188
 
                       &rts_threshold, sizeof(rts_threshold));
189
 
        if (!res)
190
 
                p += sprintf(p, "rts_threshold=%u bytes\n", rts_threshold);
191
 
 
192
 
        res = mp_query(wnd, OID_802_11_FRAGMENTATION_THRESHOLD,
193
 
                       &frag_threshold, sizeof(frag_threshold));
194
 
        if (!res)
195
 
                p += sprintf(p, "frag_threshold=%u bytes\n", frag_threshold);
196
 
 
197
 
        res = mp_query_int(wnd, OID_802_11_POWER_MODE, &power_mode);
198
 
        if (!res)
199
 
                p += sprintf(p, "power_mode=%s\n",
200
 
                             (power_mode == NDIS_POWER_OFF) ? "always_on" :
201
 
                             (power_mode == NDIS_POWER_MAX) ?
202
 
                             "max_savings" : "min_savings");
203
 
 
204
 
        res = mp_query(wnd, OID_802_11_NUMBER_OF_ANTENNAS,
205
 
                       &antenna, sizeof(antenna));
206
 
        if (!res)
207
 
                p += sprintf(p, "num_antennas=%u\n", antenna);
208
 
 
209
 
        res = mp_query(wnd, OID_802_11_TX_ANTENNA_SELECTED,
210
 
                       &antenna, sizeof(antenna));
211
 
        if (!res)
212
 
                p += sprintf(p, "tx_antenna=%u\n", antenna);
213
 
 
214
 
        res = mp_query(wnd, OID_802_11_RX_ANTENNA_SELECTED,
215
 
                       &antenna, sizeof(antenna));
216
 
        if (!res)
217
 
                p += sprintf(p, "rx_antenna=%u\n", antenna);
218
 
 
219
 
        p += sprintf(p, "encryption_modes=%s%s%s%s%s%s%s\n",
220
 
                     test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ?
221
 
                     "WEP" : "none",
222
 
 
223
 
                     test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ?
224
 
                     "; TKIP with WPA" : "",
225
 
                     test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ?
226
 
                     ", WPA2" : "",
227
 
                     test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ?
228
 
                     ", WPA2PSK" : "",
229
 
 
230
 
                     test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr) ?
231
 
                     "; AES/CCMP with WPA" : "",
232
 
                     test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ?
233
 
                     ", WPA2" : "",
234
 
                     test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ?
235
 
                     ", WPA2PSK" : "");
236
 
 
237
 
        res = mp_query_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, &packet_filter);
238
 
        if (!res) {
239
 
                if (packet_filter != wnd->packet_filter)
240
 
                        WARNING("wrong packet_filter? 0x%08x, 0x%08x\n",
241
 
                                packet_filter, wnd->packet_filter);
242
 
                p += sprintf(p, "packet_filter: 0x%08x\n", packet_filter);
243
 
        }
244
 
        if (p - page > count) {
245
 
                WARNING("wrote %td bytes (limit is %u)",
246
 
                        p - page, count);
247
 
                *eof = 1;
248
 
        }
249
 
 
250
 
        return p - page;
251
 
}
252
 
 
253
 
static int procfs_read_ndis_settings(char *page, char **start, off_t off,
254
 
                                     int count, int *eof, void *data)
255
 
{
256
 
        char *p = page;
257
 
        struct ndis_device *wnd = (struct ndis_device *)data;
258
 
        struct wrap_device_setting *setting;
259
 
 
260
 
        if (off != 0) {
261
 
                *eof = 1;
262
 
                return 0;
263
 
        }
264
 
 
265
 
        p += sprintf(p, "hangcheck_interval=%d\n",
266
 
                     hangcheck_interval == 0 ?
267
 
                     (wnd->hangcheck_interval / HZ) : -1);
268
 
 
269
 
        list_for_each_entry(setting, &wnd->wd->settings, list) {
270
 
                p += sprintf(p, "%s=%s\n", setting->name, setting->value);
271
 
        }
272
 
 
273
 
        list_for_each_entry(setting, &wnd->wd->driver->settings, list) {
274
 
                p += sprintf(p, "%s=%s\n", setting->name, setting->value);
275
 
        }
276
 
 
277
 
        return p - page;
278
 
}
279
 
 
280
 
static int procfs_write_ndis_settings(struct file *file, const char __user *buf,
281
 
                                      unsigned long count, void *data)
282
 
{
283
 
        struct ndis_device *wnd = (struct ndis_device *)data;
284
 
        char setting[MAX_PROC_STR_LEN], *p;
285
 
        unsigned int i;
286
 
        NDIS_STATUS res;
287
 
 
288
 
        if (count > MAX_PROC_STR_LEN)
289
 
                return -EINVAL;
290
 
 
291
 
        memset(setting, 0, sizeof(setting));
292
 
        if (copy_from_user(setting, buf, count))
293
 
                return -EFAULT;
294
 
 
295
 
        if ((p = strchr(setting, '\n')))
296
 
                *p = 0;
297
 
 
298
 
        if ((p = strchr(setting, '=')))
299
 
                *p = 0;
300
 
 
301
 
        if (!strcmp(setting, "hangcheck_interval")) {
302
 
                if (!p)
303
 
                        return -EINVAL;
304
 
                p++;
305
 
                i = simple_strtol(p, NULL, 10);
306
 
                hangcheck_del(wnd);
307
 
                if (i > 0) {
308
 
                        wnd->hangcheck_interval = i * HZ;
309
 
                        hangcheck_add(wnd);
310
 
                }
311
 
        } else if (!strcmp(setting, "suspend")) {
312
 
                if (!p)
313
 
                        return -EINVAL;
314
 
                p++;
315
 
                i = simple_strtol(p, NULL, 10);
316
 
                if (i <= 0 || i > 3)
317
 
                        return -EINVAL;
318
 
                i = -1;
319
 
                if (wrap_is_pci_bus(wnd->wd->dev_bus))
320
 
                        i = wrap_pnp_suspend_pci_device(wnd->wd->pci.pdev,
321
 
                                                        PMSG_SUSPEND);
322
 
                else if (wrap_is_usb_bus(wnd->wd->dev_bus))
323
 
                        i = wrap_pnp_suspend_usb_device(wnd->wd->usb.intf,
324
 
                                                        PMSG_SUSPEND);
325
 
                if (i)
326
 
                        return -EINVAL;
327
 
        } else if (!strcmp(setting, "resume")) {
328
 
                i = -1;
329
 
                if (wrap_is_pci_bus(wnd->wd->dev_bus))
330
 
                        i = wrap_pnp_resume_pci_device(wnd->wd->pci.pdev);
331
 
                else if (wrap_is_usb_bus(wnd->wd->dev_bus))
332
 
                        i = wrap_pnp_resume_usb_device(wnd->wd->usb.intf);
333
 
                if (i)
334
 
                        return -EINVAL;
335
 
        } else if (!strcmp(setting, "stats_enabled")) {
336
 
                if (!p)
337
 
                        return -EINVAL;
338
 
                p++;
339
 
                i = simple_strtol(p, NULL, 10);
340
 
                if (i > 0)
341
 
                        wnd->iw_stats_enabled = TRUE;
342
 
                else
343
 
                        wnd->iw_stats_enabled = FALSE;
344
 
        } else if (!strcmp(setting, "packet_filter")) {
345
 
                if (!p)
346
 
                        return -EINVAL;
347
 
                p++;
348
 
                i = simple_strtol(p, NULL, 10);
349
 
                res = mp_set_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, i);
350
 
                if (res)
351
 
                        WARNING("setting packet_filter failed: %08X", res);
352
 
        } else if (!strcmp(setting, "reinit")) {
353
 
                if (ndis_reinit(wnd) != NDIS_STATUS_SUCCESS)
354
 
                        return -EFAULT;
355
 
        } else {
356
 
                struct ndis_configuration_parameter param;
357
 
                struct unicode_string key;
358
 
                struct ansi_string ansi;
359
 
 
360
 
                if (!p)
361
 
                        return -EINVAL;
362
 
                p++;
363
 
                RtlInitAnsiString(&ansi, p);
364
 
                if (RtlAnsiStringToUnicodeString(&param.data.string, &ansi,
365
 
                                                 TRUE) != STATUS_SUCCESS)
366
 
                        EXIT1(return -EFAULT);
367
 
                param.type = NdisParameterString;
368
 
                RtlInitAnsiString(&ansi, setting);
369
 
                if (RtlAnsiStringToUnicodeString(&key, &ansi,
370
 
                                                 TRUE) != STATUS_SUCCESS) {
371
 
                        RtlFreeUnicodeString(&param.data.string);
372
 
                        EXIT1(return -EINVAL);
373
 
                }
374
 
                NdisWriteConfiguration(&res, wnd->nmb, &key, &param);
375
 
                RtlFreeUnicodeString(&key);
376
 
                RtlFreeUnicodeString(&param.data.string);
377
 
                if (res != NDIS_STATUS_SUCCESS)
378
 
                        return -EFAULT;
379
 
        }
380
 
        return count;
381
 
}
382
 
 
383
 
int wrap_procfs_add_ndis_device(struct ndis_device *wnd)
384
 
{
385
 
        struct proc_dir_entry *procfs_entry;
386
 
 
387
 
        if (wrap_procfs_entry == NULL)
388
 
                return -ENOMEM;
389
 
 
390
 
        if (wnd->procfs_iface) {
391
 
                ERROR("%s already registered?", wnd->procfs_iface->name);
392
 
                return -EINVAL;
393
 
        }
394
 
        wnd->procfs_iface = proc_mkdir(wnd->net_dev->name, wrap_procfs_entry);
395
 
        if (wnd->procfs_iface == NULL) {
396
 
                ERROR("couldn't create proc directory");
397
 
                return -ENOMEM;
398
 
        }
399
 
        wnd->procfs_iface->uid = proc_uid;
400
 
        wnd->procfs_iface->gid = proc_gid;
401
 
 
402
 
        procfs_entry = create_proc_entry("hw", S_IFREG | S_IRUSR | S_IRGRP,
403
 
                                         wnd->procfs_iface);
404
 
        if (procfs_entry == NULL) {
405
 
                ERROR("couldn't create proc entry for 'hw'");
406
 
                goto err_hw;
407
 
        } else {
408
 
                procfs_entry->uid = proc_uid;
409
 
                procfs_entry->gid = proc_gid;
410
 
                procfs_entry->data = wnd;
411
 
                procfs_entry->read_proc = procfs_read_ndis_hw;
412
 
        }
413
 
 
414
 
        procfs_entry = create_proc_entry("stats", S_IFREG | S_IRUSR | S_IRGRP,
415
 
                                         wnd->procfs_iface);
416
 
        if (procfs_entry == NULL) {
417
 
                ERROR("couldn't create proc entry for 'stats'");
418
 
                goto err_stats;
419
 
        } else {
420
 
                procfs_entry->uid = proc_uid;
421
 
                procfs_entry->gid = proc_gid;
422
 
                procfs_entry->data = wnd;
423
 
                procfs_entry->read_proc = procfs_read_ndis_stats;
424
 
        }
425
 
 
426
 
        procfs_entry = create_proc_entry("encr", S_IFREG | S_IRUSR | S_IRGRP,
427
 
                                         wnd->procfs_iface);
428
 
        if (procfs_entry == NULL) {
429
 
                ERROR("couldn't create proc entry for 'encr'");
430
 
                goto err_encr;
431
 
        } else {
432
 
                procfs_entry->uid = proc_uid;
433
 
                procfs_entry->gid = proc_gid;
434
 
                procfs_entry->data = wnd;
435
 
                procfs_entry->read_proc = procfs_read_ndis_encr;
436
 
        }
437
 
 
438
 
        procfs_entry = create_proc_entry("settings", S_IFREG |
439
 
                                         S_IRUSR | S_IRGRP |
440
 
                                         S_IWUSR | S_IWGRP, wnd->procfs_iface);
441
 
        if (procfs_entry == NULL) {
442
 
                ERROR("couldn't create proc entry for 'settings'");
443
 
                goto err_settings;
444
 
        } else {
445
 
                procfs_entry->uid = proc_uid;
446
 
                procfs_entry->gid = proc_gid;
447
 
                procfs_entry->data = wnd;
448
 
                procfs_entry->read_proc = procfs_read_ndis_settings;
449
 
                procfs_entry->write_proc = procfs_write_ndis_settings;
450
 
        }
451
 
        return 0;
452
 
 
453
 
err_settings:
454
 
        remove_proc_entry("encr", wnd->procfs_iface);
455
 
err_encr:
456
 
        remove_proc_entry("stats", wnd->procfs_iface);
457
 
err_stats:
458
 
        remove_proc_entry("hw", wnd->procfs_iface);
459
 
err_hw:
460
 
        remove_proc_entry(wnd->procfs_iface->name, wrap_procfs_entry);
461
 
        wnd->procfs_iface = NULL;
462
 
        return -ENOMEM;
463
 
}
464
 
 
465
 
void wrap_procfs_remove_ndis_device(struct ndis_device *wnd)
466
 
{
467
 
        struct proc_dir_entry *procfs_iface = xchg(&wnd->procfs_iface, NULL);
468
 
 
469
 
        if (procfs_iface == NULL)
470
 
                return;
471
 
        remove_proc_entry("hw", procfs_iface);
472
 
        remove_proc_entry("stats", procfs_iface);
473
 
        remove_proc_entry("encr", procfs_iface);
474
 
        remove_proc_entry("settings", procfs_iface);
475
 
        if (wrap_procfs_entry)
476
 
                remove_proc_entry(procfs_iface->name, wrap_procfs_entry);
477
 
}
478
 
 
479
 
static int procfs_read_debug(char *page, char **start, off_t off,
480
 
                             int count, int *eof, void *data)
481
 
{
482
 
        char *p = page;
483
 
#if ALLOC_DEBUG
484
 
        enum alloc_type type;
485
 
#endif
486
 
 
487
 
        if (off != 0) {
488
 
                *eof = 1;
489
 
                return 0;
490
 
        }
491
 
        p += sprintf(p, "%d\n", debug);
492
 
#if ALLOC_DEBUG
493
 
        for (type = 0; type < ALLOC_TYPE_MAX; type++)
494
 
                p += sprintf(p, "total size of allocations in %s: %d\n",
495
 
                             alloc_type_name[type], alloc_size(type));
496
 
#endif
497
 
        return p - page;
498
 
}
499
 
 
500
 
static int procfs_write_debug(struct file *file, const char __user *buf,
501
 
                              unsigned long count, void *data)
502
 
{
503
 
        int i;
504
 
        char setting[MAX_PROC_STR_LEN], *p;
505
 
 
506
 
        if (count > MAX_PROC_STR_LEN)
507
 
                return -EINVAL;
508
 
 
509
 
        memset(setting, 0, sizeof(setting));
510
 
        if (copy_from_user(setting, buf, count))
511
 
                return -EFAULT;
512
 
 
513
 
        if ((p = strchr(setting, '\n')))
514
 
                *p = 0;
515
 
 
516
 
        if ((p = strchr(setting, '=')))
517
 
                *p = 0;
518
 
 
519
 
        i = simple_strtol(setting, NULL, 10);
520
 
        if (i >= 0 && i < 10)
521
 
                debug = i;
522
 
        else
523
 
                return -EINVAL;
524
 
        return count;
525
 
}
526
 
 
527
 
int wrap_procfs_init(void)
528
 
{
529
 
        struct proc_dir_entry *procfs_entry;
530
 
 
531
 
        wrap_procfs_entry = proc_mkdir(DRIVER_NAME, proc_net_root);
532
 
        if (wrap_procfs_entry == NULL) {
533
 
                ERROR("couldn't create procfs directory");
534
 
                return -ENOMEM;
535
 
        }
536
 
        wrap_procfs_entry->uid = proc_uid;
537
 
        wrap_procfs_entry->gid = proc_gid;
538
 
 
539
 
        procfs_entry = create_proc_entry("debug", S_IFREG | S_IRUSR | S_IRGRP,
540
 
                                         wrap_procfs_entry);
541
 
        if (procfs_entry == NULL) {
542
 
                ERROR("couldn't create proc entry for 'debug'");
543
 
                return -ENOMEM;
544
 
        } else {
545
 
                procfs_entry->uid = proc_uid;
546
 
                procfs_entry->gid = proc_gid;
547
 
                procfs_entry->read_proc = procfs_read_debug;
548
 
                procfs_entry->write_proc = procfs_write_debug;
549
 
        }
550
 
        return 0;
551
 
}
552
 
 
553
 
void wrap_procfs_remove(void)
554
 
{
555
 
        if (wrap_procfs_entry == NULL)
556
 
                return;
557
 
        remove_proc_entry("debug", wrap_procfs_entry);
558
 
        remove_proc_entry(DRIVER_NAME, proc_net_root);
559
 
}