⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zd1205_proc.c

📁 ZYDAS zd1211b driver for Linux2.4
💻 C
字号:
/* src/zd1205_proc.c**** Copyright (C) 2004 ZyDAS Inc.  All Rights Reserved.* --------------------------------------------------------------------****   The contents of this file are subject to the Mozilla Public*   License Version 1.1 (the "License"); you may not use this file*   except in compliance with the License. You may obtain a copy of*   the License at http://www.mozilla.org/MPL/**   Software distributed under the License is distributed on an "AS*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or*   implied. See the License for the specific language governing*   rights and limitations under the License.**   Alternatively, the contents of this file may be used under the*   terms of the GNU Public License version 2 (the "GPL"), in which*   case the provisions of the GPL are applicable instead of the*   above.  If you wish to allow the use of your version of this file*   only under the terms of the GPL and not to allow others to use*   your version of this file under the MPL, indicate your decision*   by deleting the provisions above and replace them with the notice*   and other provisions required by the GPL.  If you do not delete*   the provisions above, a recipient may use your version of this*   file under either the MPL or the GPL.** -------------------------------------------------------------------- */#include <linux/config.h>#ifdef CONFIG_PROC_FS#include "zd1205.h"/***************************************************************************//*       /proc File System Interaface Support Functions                    *//***************************************************************************/static struct proc_dir_entry *adapters_proc_dir = 0;/* externs from zd1205.c */extern char zd1205_short_driver_name[];extern char zd1205_driver_version[];extern struct net_device_stats *zd1205_get_stats(struct net_device *dev);static void zd1205_proc_cleanup(void);static unsigned char zd1205_init_proc_dir(void);#define ADAPTERS_PROC_DIR   "zd1205"#define WRITE_BUF_MAX_LEN   20#define READ_BUF_MAX_LEN    256#define ZD1205_PE_LEN       25#define bdp_drv_off(off) (unsigned long)(offsetof(struct zd1205_private, drv_stats.off))#define bdp_prm_off(off) (unsigned long)(offsetof(struct zd1205_private, params.off))typedef struct _zd1205_proc_entry{        char *name;        read_proc_t *read_proc;        write_proc_t *write_proc;        unsigned long offset;	/* offset into bdp. ~0 means no value, pass NULL. */}zd1205_proc_entry;static intgeneric_read(char *page, char **start, off_t off, int count, int *eof, int len){        if (len <= off + count)                *eof = 1;        *start = page + off;        len -= off;        if (len > count)                len = count;        if (len < 0)                len = 0;        return len;}#if 0static intread_ulong(char *page, char **start, off_t off,           int count, int *eof, unsigned long l){        int len;        len = sprintf(page, "%lu\n", l);        return generic_read(page, start, off, count, eof, len);}static intread_gen_ulong(char *page, char **start, off_t off,               int count, int *eof, void *data){        unsigned long val = 0;        if (data)                val = *((unsigned long *) data);        return read_ulong(page, start, off, count, eof, val);}#endifstatic intread_hwaddr(char *page, char **start, off_t off,            int count, int *eof, unsigned char *hwaddr){        int len;        len = sprintf(page, "%02X:%02X:%02X:%02X:%02X:%02X\n",                      hwaddr[0], hwaddr[1], hwaddr[2],                      hwaddr[3], hwaddr[4], hwaddr[5]);        return generic_read(page, start, off, count, eof, len);}static intread_permanent_hwaddr(char *page, char **start, off_t off,                      int count, int *eof, void *data){        struct zd1205_private *macp = data;        unsigned char *hwaddr = macp->macAdr;        return read_hwaddr(page, start, off, count, eof, hwaddr);}static zd1205_proc_entry zd1205_proc_list[] = {                        {"Permanent_HWaddr",      read_permanent_hwaddr, 0, 0},                        {"\n",},                        {"", 0, 0, 0}                };static intread_info(char *page, char **start, off_t off, int count, int *eof, void *data){        struct zd1205_private *macp = data;        zd1205_proc_entry *pe;        int tmp;        void *val;        int len = 0;        for (pe = zd1205_proc_list; pe->name[0]; pe++) {                if (pe->name[0] == '\n') {                        len += sprintf(page + len, "\n");                        continue;                }                if (pe->read_proc) {                        if ((len + READ_BUF_MAX_LEN + ZD1205_PE_LEN + 1) >=                                        PAGE_SIZE)                                break;                        if (pe->offset != ~0)                                val = ((char *) macp) + pe->offset;                        else                                val = NULL;                        len += sprintf(page + len, "%-"                                       __MODULE_STRING(ZD1205_PE_LEN)                                       "s ", pe->name);                        len += pe->read_proc(page + len, start, 0,                                             READ_BUF_MAX_LEN + 1, &tmp, val);                }        }        return generic_read(page, start, off, count, eof, len);}static struct proc_dir_entry *                        create_proc_rw(char *name, void *data, struct proc_dir_entry *parent,                                       read_proc_t * read_proc, write_proc_t * write_proc){        struct proc_dir_entry *pdep;        mode_t mode = S_IFREG;        if (write_proc)        {                mode |= S_IWUSR;                if (read_proc) {                        mode |= S_IRUSR;                }        } else if (read_proc)        {                mode |= S_IRUGO;        }        if (!(pdep = create_proc_entry(name, mode, parent)))                return NULL;        pdep->read_proc = read_proc;        pdep->write_proc = write_proc;        pdep->data = data;        return pdep;}voidzd1205_remove_proc_subdir(struct zd1205_private *macp, char *name){        zd1205_proc_entry *pe;        char info[256];        int len;        /* If our root /proc dir was not created, there is nothing to remove */        if (adapters_proc_dir == NULL)        {                return;        }        len = strlen(macp->ifname);        strncpy(info, macp->ifname, sizeof (info));        strncat(info + len, ".info", sizeof (info) - len);        if (macp->proc_parent)        {                for (pe = zd1205_proc_list; pe->name[0]; pe++) {                        if (pe->name[0] == '\n')                                continue;                        remove_proc_entry(pe->name, macp->proc_parent);                }                remove_proc_entry(macp->ifname, adapters_proc_dir);                macp->proc_parent = NULL;        }        remove_proc_entry(info, adapters_proc_dir);        /* try to remove the main /proc dir, if it's empty */        zd1205_proc_cleanup();}intzd1205_create_proc_subdir(struct zd1205_private *macp){        struct proc_dir_entry *dev_dir;        zd1205_proc_entry *pe;        char info[256];        int len;        void *data;        /* create the main /proc dir if needed */        if (!adapters_proc_dir)        {                if (!zd1205_init_proc_dir())                        return -ENOMEM;        }        strncpy(info, macp->ifname, sizeof (info));        len = strlen(info);        strncat(info + len, ".info", sizeof (info) - len);        /* info */        if (!(create_proc_rw(info, macp, adapters_proc_dir, read_info, 0)))        {                zd1205_proc_cleanup();                return -ENOMEM;        }        dev_dir = create_proc_entry(macp->ifname, S_IFDIR,                                    adapters_proc_dir);        macp->proc_parent = dev_dir;        if (!dev_dir)        {                zd1205_remove_proc_subdir(macp, macp->ifname);                return -ENOMEM;        }        for (pe = zd1205_proc_list; pe->name[0]; pe++)        {                if (pe->name[0] == '\n')                        continue;                if (pe->offset != ~0)                        data = ((char *) macp) + pe->offset;                else                        data = NULL;                if (!(create_proc_rw(pe->name, data, dev_dir,                                     pe->read_proc, pe->write_proc))) {                        zd1205_remove_proc_subdir(macp, macp->ifname);                        return -ENOMEM;                }        }        return 0;}/**************************************************************************** * Name:          zd1205_init_proc_dir * * Description:   This routine creates the top-level /proc directory for the *                driver in /proc/net * * Arguments:     none * * Returns:       true on success, false on fail * ***************************************************************************/static unsigned charzd1205_init_proc_dir(void){        int len;        /* first check if adapters_proc_dir already exists */        len = strlen(ADAPTERS_PROC_DIR);        for (adapters_proc_dir = proc_net->subdir;                        adapters_proc_dir; adapters_proc_dir = adapters_proc_dir->next) {                if ((adapters_proc_dir->namelen == len) &&                                (!memcmp(adapters_proc_dir->name, ADAPTERS_PROC_DIR, len)))                        break;        }        if (!adapters_proc_dir)                adapters_proc_dir =                        create_proc_entry(ADAPTERS_PROC_DIR, S_IFDIR, proc_net);        if (!adapters_proc_dir)                return false;        return true;}/**************************************************************************** * Name:          zd1205_proc_cleanup * * Description:   This routine clears the top-level /proc directory, if empty. * * Arguments:     none * * Returns:       none * ***************************************************************************/static voidzd1205_proc_cleanup(void){        struct proc_dir_entry *de;        if (adapters_proc_dir == NULL) {                return;        }        /* check if subdir list is empty before removing adapters_proc_dir */        for (de = adapters_proc_dir->subdir; de; de = de->next) {                /* ignore . and .. */                if (*(de->name) != '.')                        break;        }        if (de)                return;        remove_proc_entry(ADAPTERS_PROC_DIR, proc_net);        adapters_proc_dir = NULL;}#endif /* CONFIG_PROC_FS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -