diff -u -p -r -b ipw2100-0.55.orig/ieee80211_crypt.c ipw2100-0.55/ieee80211_crypt.c
|
|
--- ipw2100-0.55.orig/ieee80211_crypt.c 2004-09-27 19:29:17.000000000 +0200
|
|
+++ ipw2100-0.55/ieee80211_crypt.c 2004-09-28 21:10:53.000000000 +0200
|
|
@@ -55,7 +55,9 @@ void ieee80211_crypt_deinit_entries(stru
|
|
|
|
if (entry->ops) {
|
|
entry->ops->deinit(entry->priv);
|
|
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
|
|
module_put(entry->ops->owner);
|
|
+#endif
|
|
}
|
|
kfree(entry);
|
|
}
|
|
diff -u -p -r -b ipw2100-0.55.orig/ieee80211_module.c ipw2100-0.55/ieee80211_module.c
|
|
--- ipw2100-0.55.orig/ieee80211_module.c 2004-09-27 19:29:17.000000000 +0200
|
|
+++ ipw2100-0.55/ieee80211_module.c 2004-09-28 21:10:53.000000000 +0200
|
|
@@ -157,7 +157,9 @@ void ieee80211_free(struct ieee80211_dev
|
|
if (crypt) {
|
|
if (crypt->ops) {
|
|
crypt->ops->deinit(crypt->priv);
|
|
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
|
|
module_put(crypt->ops->owner);
|
|
+#endif
|
|
}
|
|
kfree(crypt);
|
|
ieee->crypt[i] = NULL;
|
|
diff -u -p -r -b ipw2100-0.55.orig/ieee80211_wx.c ipw2100-0.55/ieee80211_wx.c
|
|
--- ipw2100-0.55.orig/ieee80211_wx.c 2004-09-27 19:29:17.000000000 +0200
|
|
+++ ipw2100-0.55/ieee80211_wx.c 2004-09-28 21:10:53.000000000 +0200
|
|
@@ -237,7 +237,11 @@ int ieee80211_wx_set_encode(struct ieee8
|
|
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
|
|
}
|
|
|
|
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
|
|
if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
|
|
+#else
|
|
+ if (new_crypt->ops)
|
|
+#endif
|
|
new_crypt->priv = new_crypt->ops->init(key);
|
|
|
|
if (!new_crypt->ops || !new_crypt->priv) {
|
|
diff -u -p -r -b ipw2100-0.55.orig/ipw2100.c ipw2100-0.55/ipw2100.c
|
|
--- ipw2100-0.55.orig/ipw2100.c 2004-09-27 19:29:17.000000000 +0200
|
|
+++ ipw2100-0.55/ipw2100.c 2004-09-28 21:10:53.000000000 +0200
|
|
@@ -358,6 +358,10 @@ static void ipw2100_queues_initialize(st
|
|
static void ipw2100_queues_free(struct ipw2100_priv *priv);
|
|
static int ipw2100_queues_allocate(struct ipw2100_priv *priv);
|
|
|
|
+static void ipw2100_proc_cleanup(void);
|
|
+static void ipw2100_proc_dev_cleanup(struct ipw2100_priv *priv);
|
|
+static int ipw2100_proc_dev_init(struct ipw2100_priv *priv);
|
|
+
|
|
static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
|
|
{
|
|
return (dev->base_addr &&
|
|
@@ -3064,26 +3068,35 @@ static void ipw2100_msg_free(struct ipw2
|
|
priv->msg_buffers = NULL;
|
|
}
|
|
|
|
-static ssize_t show_pci(struct device *d, char *buf)
|
|
+static struct proc_dir_entry *ipw2100_proc = NULL;
|
|
+
|
|
+static int proc_get_pci(char *page, char **start,
|
|
+ off_t offset, int count,
|
|
+ int *eof, void *data)
|
|
{
|
|
- struct pci_dev *pdev = container_of(d, struct pci_dev, dev);
|
|
- char * out = buf;
|
|
- int i, j;
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
+ struct pci_dev *pdev = priv->pdev;
|
|
+ int i, j, len;
|
|
u32 val;
|
|
|
|
- out += sprintf(out, "PCI Configuration Data\n");
|
|
+
|
|
+ len = 0;
|
|
+
|
|
+ len += snprintf(page + len, count - len, "PCI Configuration Data\n");
|
|
+
|
|
for (i = 0; i < 16; i++) {
|
|
- out += sprintf(out, "[%08X] ", i * 16);
|
|
+ len += snprintf(page + len, count - len, "[%08X] ", i * 16);
|
|
for (j = 0; j < 16; j += 4) {
|
|
pci_read_config_dword(pdev, i * 16 + j, &val);
|
|
- out += sprintf(out, "%08X ", val);
|
|
+ len += snprintf(page + len, count - len, "%08X ", val);
|
|
}
|
|
- out += sprintf(out, "\n");
|
|
+ len += snprintf(page + len, count - len, "\n");
|
|
}
|
|
|
|
- return out - buf;
|
|
+ *eof = 1;
|
|
+ return len;
|
|
}
|
|
-static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
|
|
|
|
|
|
#define IPW2100_REG(x) { IPW_ ##x, #x }
|
|
@@ -3263,37 +3276,48 @@ const struct {
|
|
};
|
|
|
|
|
|
-static ssize_t show_registers(struct device *d, char *buf)
|
|
+static int proc_get_registers(char *page, char **start,
|
|
+ off_t offset, int count,
|
|
+ int *eof, void *data)
|
|
{
|
|
+ struct net_device *dev = data;
|
|
int i;
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- struct net_device *dev = priv->ndev;
|
|
- char * out = buf;
|
|
+ int len = 0;
|
|
u32 val = 0;
|
|
|
|
- out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "%30s [Address ] : Hex\n", "Register");
|
|
|
|
- for (i = 0; i < (sizeof(hw_data) / sizeof(*hw_data)); i++) {
|
|
+ for (i = 0;
|
|
+ i < (sizeof(hw_data) / sizeof(*hw_data));
|
|
+ i++) {
|
|
read_register(dev, hw_data[i].addr, &val);
|
|
- out += sprintf(out, "%30s [%08X] : %08X\n",
|
|
- hw_data[i].name, hw_data[i].addr, val);
|
|
+
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "%30s [%08X] : %08X\n",
|
|
+ hw_data[i].name, hw_data[i].addr,
|
|
+ val);
|
|
}
|
|
|
|
- return out - buf;
|
|
+ *eof = 1;
|
|
+ return len;
|
|
}
|
|
-static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
|
|
|
|
|
|
-static ssize_t show_hardware(struct device *d, char *buf)
|
|
+static int proc_get_hw(char *page, char **start,
|
|
+ off_t offset, int count,
|
|
+ int *eof, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- struct net_device *dev = priv->ndev;
|
|
- char * out = buf;
|
|
+ struct net_device *dev = data;
|
|
int i;
|
|
+ int len = 0;
|
|
|
|
- out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "%30s [Address ] : Hex\n", "NIC entry");
|
|
|
|
- for (i = 0; i < (sizeof(nic_data) / sizeof(*nic_data)); i++) {
|
|
+ for (i = 0;
|
|
+ i < (sizeof(nic_data) / sizeof(*nic_data));
|
|
+ i++) {
|
|
u8 tmp8;
|
|
u16 tmp16;
|
|
u32 tmp32;
|
|
@@ -3301,163 +3325,213 @@ static ssize_t show_hardware(struct devi
|
|
switch (nic_data[i].size) {
|
|
case 1:
|
|
read_nic_byte(dev, nic_data[i].addr, &tmp8);
|
|
- out += sprintf(out, "%30s [%08X] : %02X\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "%30s [%08X] : %02X\n",
|
|
nic_data[i].name, nic_data[i].addr,
|
|
tmp8);
|
|
break;
|
|
case 2:
|
|
read_nic_word(dev, nic_data[i].addr, &tmp16);
|
|
- out += sprintf(out, "%30s [%08X] : %04X\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "%30s [%08X] : %04X\n",
|
|
nic_data[i].name, nic_data[i].addr,
|
|
tmp16);
|
|
break;
|
|
case 4:
|
|
read_nic_dword(dev, nic_data[i].addr, &tmp32);
|
|
- out += sprintf(out, "%30s [%08X] : %08X\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "%30s [%08X] : %08X\n",
|
|
nic_data[i].name, nic_data[i].addr,
|
|
tmp32);
|
|
break;
|
|
}
|
|
}
|
|
- return out - buf;
|
|
+ *eof = 1;
|
|
+ return len;
|
|
}
|
|
-static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
|
|
|
|
|
|
-static ssize_t show_memory(struct device *d, char *buf)
|
|
+static int proc_set_memory(struct file *file, const char *buffer,
|
|
+ unsigned long count, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- struct net_device *dev = priv->ndev;
|
|
- static unsigned long loop = 0;
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
+ char buf[] = "0000";
|
|
+ unsigned long len = (sizeof(buf) - 1) > count ? count :
|
|
+ sizeof(buf) - 1;
|
|
+ char *p = buf;
|
|
+
|
|
+ if (copy_from_user(buf, buffer, len)) {
|
|
+ IPW_DEBUG_INFO("can't copy data from userspace\n");
|
|
+ /* stupid? yes, but how do I signal an error here? */
|
|
+ return count;
|
|
+ } else
|
|
+ buf[len] = 0;
|
|
+
|
|
+ if (p[0] == '1' || (tolower(p[0]) == 'o' && tolower(p[1] == 'n'))) {
|
|
+ printk(KERN_INFO "%s: Setting memory dump to RAW mode.\n",
|
|
+ dev->name);
|
|
+ priv->dump_raw = 1;
|
|
+ } else if (p[0] == '0' ||
|
|
+ (tolower(p[0]) == 'o' && tolower(p[1] == 'f'))) {
|
|
+ printk(KERN_INFO "%s: Setting memory dump to HEX mode.\n",
|
|
+ dev->name);
|
|
+ priv->dump_raw = 0;
|
|
+ } else if (tolower(p[0]) == 'r') {
|
|
+ printk(KERN_INFO "%s: Resetting firmware snapshot.\n",
|
|
+ dev->name);
|
|
+ ipw2100_snapshot_free(priv);
|
|
+ } else
|
|
+ printk(KERN_INFO "%s: Usage: 0|on = HEX, 1|off = RAW, "
|
|
+ "reset = clear memory snapshot\n",
|
|
+ dev->name);
|
|
+
|
|
+ return count;
|
|
+}
|
|
+
|
|
+static int proc_get_memory(char *page, char **start,
|
|
+ off_t offset, int count,
|
|
+ int *eof, void *data)
|
|
+{
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
int len = 0;
|
|
- u32 buffer[4];
|
|
+ static unsigned long loop = 0;
|
|
+ u32 buf[4];
|
|
int i;
|
|
char line[81];
|
|
|
|
- if (loop >= 0x30000)
|
|
+ if (offset == 0)
|
|
loop = 0;
|
|
|
|
- /* sysfs provides us PAGE_SIZE buffer */
|
|
- while (len < PAGE_SIZE - 128 && loop < 0x30000) {
|
|
+ /* If we've reached EOF or the user is cutting is short, then
|
|
+ * restart the counter and return 0 bytes */
|
|
+ if (loop >= 0x30000) {
|
|
+ *start = NULL;
|
|
+ *eof = 1;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* Return around 2k per pass... */
|
|
+ while (count - len > 256 &&
|
|
+ len < 2048 &&
|
|
+ loop < 0x30000) {
|
|
|
|
if (priv->snapshot[0]) for (i = 0; i < 4; i++)
|
|
- buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4);
|
|
+ buf[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4);
|
|
else for (i = 0; i < 4; i++)
|
|
- read_nic_dword(dev, loop + i * 4, &buffer[i]);
|
|
+ read_nic_dword(dev, loop + i * 4, &buf[i]);
|
|
|
|
if (priv->dump_raw)
|
|
- len += sprintf(buf + len,
|
|
+ len += snprintf(page + len, count - len,
|
|
"%c%c%c%c"
|
|
"%c%c%c%c"
|
|
"%c%c%c%c"
|
|
"%c%c%c%c",
|
|
- ((u8*)buffer)[0x0],
|
|
- ((u8*)buffer)[0x1],
|
|
- ((u8*)buffer)[0x2],
|
|
- ((u8*)buffer)[0x3],
|
|
- ((u8*)buffer)[0x4],
|
|
- ((u8*)buffer)[0x5],
|
|
- ((u8*)buffer)[0x6],
|
|
- ((u8*)buffer)[0x7],
|
|
- ((u8*)buffer)[0x8],
|
|
- ((u8*)buffer)[0x9],
|
|
- ((u8*)buffer)[0xa],
|
|
- ((u8*)buffer)[0xb],
|
|
- ((u8*)buffer)[0xc],
|
|
- ((u8*)buffer)[0xd],
|
|
- ((u8*)buffer)[0xe],
|
|
- ((u8*)buffer)[0xf]);
|
|
+ ((u8*)buf)[0x0],
|
|
+ ((u8*)buf)[0x1],
|
|
+ ((u8*)buf)[0x2],
|
|
+ ((u8*)buf)[0x3],
|
|
+ ((u8*)buf)[0x4],
|
|
+ ((u8*)buf)[0x5],
|
|
+ ((u8*)buf)[0x6],
|
|
+ ((u8*)buf)[0x7],
|
|
+ ((u8*)buf)[0x8],
|
|
+ ((u8*)buf)[0x9],
|
|
+ ((u8*)buf)[0xa],
|
|
+ ((u8*)buf)[0xb],
|
|
+ ((u8*)buf)[0xc],
|
|
+ ((u8*)buf)[0xd],
|
|
+ ((u8*)buf)[0xe],
|
|
+ ((u8*)buf)[0xf]);
|
|
else
|
|
- len += sprintf(buf + len, "%s\n",
|
|
- snprint_line(line, sizeof(line),
|
|
- (u8*)buffer, 16, loop));
|
|
+ len += snprintf(page + len, count - len, "%s\n",
|
|
+ snprint_line(
|
|
+ line, sizeof(line), (u8*)buf,
|
|
+ 16, loop));
|
|
+
|
|
loop += 16;
|
|
}
|
|
|
|
- return len;
|
|
-}
|
|
-
|
|
-static ssize_t store_memory(struct device *d, const char *buf, size_t count)
|
|
-{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- struct net_device *dev = priv->ndev;
|
|
- const char *p = buf;
|
|
-
|
|
- if (count < 1)
|
|
- return count;
|
|
-
|
|
- if (p[0] == '1' ||
|
|
- (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
|
|
- printk(KERN_INFO "%s: Setting memory dump to RAW mode.\n",
|
|
- dev->name);
|
|
- priv->dump_raw = 1;
|
|
-
|
|
- } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
|
|
- tolower(p[1]) == 'f')) {
|
|
- printk(KERN_INFO "%s: Setting memory dump to HEX mode.\n",
|
|
- dev->name);
|
|
- priv->dump_raw = 0;
|
|
-
|
|
- } else if (tolower(p[0]) == 'r') {
|
|
- printk(KERN_INFO "%s: Resetting firmware snapshot.\n",
|
|
- dev->name);
|
|
- ipw2100_snapshot_free(priv);
|
|
-
|
|
- } else
|
|
- printk(KERN_INFO "%s: Usage: 0|on = HEX, 1|off = RAW, "
|
|
- "reset = clear memory snapshot\n",
|
|
- dev->name);
|
|
+ /* see comment in fs/proc/generic.c proc_file_read */
|
|
+ if (len)
|
|
+ *start = (char*)len;
|
|
+ else
|
|
+ *eof = 1;
|
|
|
|
- return count;
|
|
+ return len;
|
|
}
|
|
-static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
|
|
|
|
|
|
-static ssize_t show_ordinals(struct device *d, char *buf)
|
|
+static int proc_get_ordinals(char *page, char **start,
|
|
+ off_t offset, int count,
|
|
+ int *eof, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- u32 val = 0;
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
int len = 0;
|
|
u32 val_len;
|
|
+ u32 val = 0;
|
|
static int loop = 0;
|
|
|
|
- if (loop >= sizeof(ord_data) / sizeof(*ord_data))
|
|
+ if (offset == 0)
|
|
loop = 0;
|
|
|
|
- /* sysfs provides us PAGE_SIZE buffer */
|
|
- while (len < PAGE_SIZE - 128 &&
|
|
+ /* If we've reached EOF or the user is cutting is short, then
|
|
+ * restart the counter and return 0 bytes */
|
|
+ if (loop >= (sizeof(ord_data) / sizeof(*ord_data))) {
|
|
+ *start = NULL;
|
|
+ *eof = 1;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* Return around 2k per pass... */
|
|
+ while (count - len > 256 &&
|
|
+ len < 2048 &&
|
|
loop < (sizeof(ord_data) / sizeof(*ord_data))) {
|
|
|
|
val_len = sizeof(u32);
|
|
|
|
if (ipw2100_get_ordinal(priv, ord_data[loop].index, &val,
|
|
&val_len))
|
|
- len += sprintf(buf + len, "[0x%02X] = ERROR %s\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "[0x%02X] = ERROR %s\n",
|
|
ord_data[loop].index,
|
|
ord_data[loop].desc);
|
|
else
|
|
- len += sprintf(buf + len, "[0x%02X] = 0x%08X %s\n",
|
|
- ord_data[loop].index, val,
|
|
- ord_data[loop].desc);
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "[0x%02X] = 0x%08X %s\n",
|
|
+ ord_data[loop].index,
|
|
+ val, ord_data[loop].desc);
|
|
+
|
|
loop++;
|
|
}
|
|
|
|
+ /* see comment in fs/proc/generic.c proc_file_read */
|
|
+ if (len)
|
|
+ *start = (char*)len;
|
|
+ else
|
|
+ *eof = 1;
|
|
+
|
|
return len;
|
|
}
|
|
-static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
|
|
-
|
|
|
|
-static ssize_t show_version(struct device *d, char *buf)
|
|
+static int proc_get_version(char *page, char **start,
|
|
+ off_t offset, int count,
|
|
+ int *eof, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- char * out = buf;
|
|
- char tmp[MAX_FW_VERSION_LEN];
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
int err;
|
|
+ int len = 0;
|
|
+ char tmp[MAX_FW_VERSION_LEN];
|
|
|
|
- out += sprintf(out, "hardware : 0x%04X\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "hardware : 0x%04X\n",
|
|
priv->pdev->subsystem_device);
|
|
|
|
- out += sprintf(out, "driver : " DRV_VERSION " ["
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "driver : " DRV_VERSION " ["
|
|
#ifdef CONFIG_IEEE80211_NOWEP
|
|
" !WEP"
|
|
#else
|
|
@@ -3470,53 +3544,66 @@ static ssize_t show_version(struct devic
|
|
#endif
|
|
" ]\n");
|
|
|
|
- out += sprintf(out, "build date : " __DATE__ "\n");
|
|
- out += sprintf(out, "build time : " __TIME__ "\n");
|
|
- out += sprintf(out, "eeprom : %d\n", priv->eeprom_version);
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "build date : " __DATE__ "\n");
|
|
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "build time : " __TIME__ "\n");
|
|
+
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "eeprom : %d\n", priv->eeprom_version);
|
|
err = ipw2100_get_ucodeversion(priv, tmp, sizeof(tmp));
|
|
if (err < 0)
|
|
- out += sprintf(out, "ucode : error\n");
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "ucode : error\n");
|
|
else
|
|
- out += sprintf(out, "ucode : %s\n", tmp);
|
|
-
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "ucode : %s\n", tmp);
|
|
err = ipw2100_get_fwversion(priv, tmp, sizeof(tmp));
|
|
if (err < 0)
|
|
- out += sprintf(out, "firmware : error\n");
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "firmware : error\n");
|
|
else
|
|
- out += sprintf(out, "firmware : %s\n", tmp);
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "firmware : %s\n", tmp);
|
|
|
|
- out += sprintf(out, "firmware img : 0x%04X\n",
|
|
- priv->firmware_version);
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "firmware img : 0x%04X\n", priv->firmware_version);
|
|
|
|
- out += sprintf(out, "firmware mode: %s\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "firmware mode: %s\n",
|
|
priv->ctx->port_type == MONITOR ? "RFMON" :
|
|
priv->ctx->port_type == IBSS ? "IBSS" : "BSS");
|
|
|
|
- return out - buf;
|
|
+ *eof = 1;
|
|
+ return len;
|
|
}
|
|
-static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
|
|
|
|
-
|
|
-static ssize_t show_stats(struct device *d, char *buf)
|
|
+static int proc_get_stats(char *page, char **start,
|
|
+ off_t offset, int count,
|
|
+ int *eof, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- char * out = buf;
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
+ int len = 0;
|
|
|
|
- out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
|
|
priv->interrupts, priv->tx_interrupts,
|
|
priv->rx_interrupts, priv->inta_other);
|
|
- out += sprintf(out, "firmware resets: %d\n", priv->resets);
|
|
- out += sprintf(out, "firmware hangs: %d\n", priv->hangs);
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "firmware resets: %d\n", priv->resets);
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "firmware hangs: %d\n", priv->hangs);
|
|
#ifdef CONFIG_IPW_DEBUG
|
|
- out += sprintf(out, "packet mismatch image: %s\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "packet mismatch image: %s\n",
|
|
priv->snapshot[0] ? "YES" : "NO");
|
|
#endif
|
|
|
|
- return out - buf;
|
|
+ *eof = 1;
|
|
+ return len;
|
|
}
|
|
-static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
|
|
-
|
|
|
|
#ifdef CONFIG_IPW2100_PROMISC
|
|
int ipw2100_enable_monitor(struct ipw2100_priv *priv, u32 channel)
|
|
@@ -3614,12 +3701,17 @@ int ipw2100_switch_mode(struct ipw2100_p
|
|
return 0;
|
|
}
|
|
|
|
-static ssize_t show_internals(struct device *d, char *buf)
|
|
+static int proc_get_internals(char *page, char **start,
|
|
+ off_t offset, int count,
|
|
+ int *eof, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
int len = 0;
|
|
|
|
-#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" # y "\n", priv-> x)
|
|
+#define DUMP_VAR(x,y) \
|
|
+ len += snprintf(page + len, count - len, \
|
|
+ # x ": %" # y "\n", priv-> x)
|
|
|
|
DUMP_VAR(connected, d);
|
|
DUMP_VAR(connected ? get_seconds() - priv->connect_start : 0, lu);
|
|
@@ -3660,20 +3752,23 @@ static ssize_t show_internals(struct dev
|
|
DUMP_VAR(ieee->scans, d);
|
|
DUMP_VAR(reset_backoff, d);
|
|
|
|
+ *eof = 1;
|
|
return len;
|
|
}
|
|
-static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
|
|
-
|
|
|
|
-static ssize_t show_bssinfo(struct device *d, char *buf)
|
|
+static int proc_get_bssinfo(char *page,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int count, int *eof, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
+ int len = 0;
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
+ int ret;
|
|
+ int length;
|
|
char essid[IW_ESSID_MAX_SIZE + 1];
|
|
u8 bssid[ETH_ALEN];
|
|
u32 chan = 0;
|
|
- char * out = buf;
|
|
- int length;
|
|
- int ret;
|
|
|
|
memset(essid, 0, sizeof(essid));
|
|
memset(bssid, 0, sizeof(bssid));
|
|
@@ -3697,23 +3792,26 @@ static ssize_t show_bssinfo(struct devic
|
|
IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
|
|
__LINE__);
|
|
|
|
- out += sprintf(out, "ESSID: %s\n", essid);
|
|
- out += sprintf(out, "BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
+ len += snprintf(page + len, count - len, "ESSID: %s\n", essid);
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
bssid[0], bssid[1], bssid[2],
|
|
bssid[3], bssid[4], bssid[5]);
|
|
- out += sprintf(out, "Channel: %d\n", chan);
|
|
+ len += snprintf(page + len, count - len, "Channel: %d\n", chan);
|
|
|
|
- return out - buf;
|
|
+ *eof = 1;
|
|
+ return len;
|
|
}
|
|
-static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
|
|
-
|
|
|
|
-static ssize_t show_txqueue(struct device *d, char *buf)
|
|
+static int proc_get_txqueue(char *page,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int count, int *eof, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- struct net_device *dev = priv->ndev;
|
|
- char * out = buf;
|
|
+ int len = 0;
|
|
u32 tbdr_r, tbdr_w;
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
|
|
IPW_DEBUG_INFO("enter\n");
|
|
|
|
@@ -3724,25 +3822,29 @@ static ssize_t show_txqueue(struct devic
|
|
|
|
IPW_DEBUG_INFO("after register read\n");
|
|
|
|
- out += sprintf(out,
|
|
+ len += snprintf(page, count,
|
|
"Tx Queue\nnic:\n\tread index=%d\n\twrite index=%d\n",
|
|
tbdr_r, tbdr_w);
|
|
- out += sprintf(out, "drv:\n\tread index=%d\n\twrite index=%d\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "drv:\n\tread index=%d\n\twrite index=%d\n",
|
|
priv->tx_queue.oldest,
|
|
priv->tx_queue.next);
|
|
+ *eof = 1;
|
|
|
|
IPW_DEBUG_INFO("exit\n");
|
|
- return out - buf;
|
|
-}
|
|
-static DEVICE_ATTR(txqueue, S_IRUGO, show_txqueue, NULL);
|
|
|
|
+ return len;
|
|
+}
|
|
|
|
-static ssize_t show_rxqueue(struct device *d, char *buf)
|
|
+static int proc_get_rxqueue(char *page,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int count, int *eof, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- struct net_device *dev = priv->ndev;
|
|
- char * out = buf;
|
|
+ int len = 0;
|
|
u32 rbdr_r, rbdr_w;
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
|
|
IPW_DEBUG_INFO("enter\n");
|
|
|
|
@@ -3751,33 +3853,37 @@ static ssize_t show_rxqueue(struct devic
|
|
|
|
IPW_DEBUG_INFO("after register read\n");
|
|
|
|
- out += sprintf(out,
|
|
+ len += snprintf(page, count,
|
|
"Rx Queue\nnic:\n\tread index=%d\n\twrite index=%d\n",
|
|
rbdr_r, rbdr_w);
|
|
- out += sprintf(out,
|
|
+ len += snprintf(page + len, count - len,
|
|
"drv:\n\tread index=NOT USED\n\twrite index=%d\n",
|
|
priv->rx_queue.next);
|
|
|
|
+ *eof = 1;
|
|
+
|
|
IPW_DEBUG_INFO("exit\n");
|
|
- return out - buf;
|
|
+
|
|
+ return len;
|
|
}
|
|
-static DEVICE_ATTR(rxqueue, S_IRUGO, show_rxqueue, NULL);
|
|
|
|
|
|
-#ifdef CONFIG_IPW_DEBUG
|
|
-static ssize_t show_debug_level(struct device_driver *d, char *buf)
|
|
+static int proc_get_debug_level(char *page, char **start, off_t offset,
|
|
+ int count, int *eof, void *data)
|
|
{
|
|
- char * out = buf;
|
|
+ int len = 0;
|
|
int i;
|
|
|
|
if (!IPW_DEBUG_ENABLED)
|
|
return 0;
|
|
|
|
- out += sprintf(out, "%-25s\tHex SET Decimal\n", "Description");
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "%-25s\tHex SET Decimal\n",
|
|
+ "Description");
|
|
for (i = 0; i < sizeof(ipw2100_debug_levels) /
|
|
sizeof(struct ipw2100_dl); i++) {
|
|
- out += sprintf(
|
|
- out, "%-25s\t0x%08lX [%c] %lu\n",
|
|
+ len += snprintf(
|
|
+ page + len, count - len, "%-25s\t0x%08lX [%c] %lu\n",
|
|
ipw2100_debug_levels[i].name,
|
|
ipw2100_debug_levels[i].value,
|
|
(ipw2100_debug_level & ipw2100_debug_levels[i].value) ?
|
|
@@ -3785,14 +3891,16 @@ static ssize_t show_debug_level(struct d
|
|
ipw2100_debug_levels[i].value);
|
|
}
|
|
|
|
- out += sprintf(out, "debug_level = 0x%08lX (* = enabled)\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "debug_level = 0x%08lX (* = enabled)\n",
|
|
ipw2100_debug_level);
|
|
|
|
- return out - buf;
|
|
+ *eof = 1;
|
|
+ return len;
|
|
}
|
|
|
|
-static ssize_t store_debug_level(struct device_driver *d, const char *buf,
|
|
- size_t count)
|
|
+static int proc_set_debug_level(struct file *file, const char *buf,
|
|
+ unsigned long count, void *data)
|
|
{
|
|
char buffer[] = "0x00000000";
|
|
unsigned long len =
|
|
@@ -3804,7 +3912,10 @@ static ssize_t store_debug_level(struct
|
|
if (!IPW_DEBUG_ENABLED)
|
|
return 0;
|
|
|
|
- strncpy(buffer, buf, len);
|
|
+ if (copy_from_user(buffer, buf, len)) {
|
|
+ IPW_DEBUG_INFO("can't copy data from userspace\n");
|
|
+ return count;
|
|
+ } else
|
|
buffer[len] = 0;
|
|
|
|
if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
|
|
@@ -3835,25 +3946,25 @@ static ssize_t store_debug_level(struct
|
|
}
|
|
}
|
|
|
|
- return len;
|
|
+ return count;
|
|
}
|
|
-static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
|
|
- store_debug_level);
|
|
-#endif /* CONFIG_IPW_DEBUG */
|
|
|
|
|
|
-static ssize_t show_fatal_error(struct device *d, char *buf)
|
|
+static int proc_get_fatal_error(char *page, char **start, off_t offset,
|
|
+ int count, int *eof, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- char * out = buf;
|
|
- int errors = 0;
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
+ int len = 0;
|
|
int i;
|
|
+ int errors = 0;
|
|
|
|
if (priv->fatal_error)
|
|
- out += sprintf(out, "Current error: 0x%08X\n",
|
|
- priv->fatal_error);
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "Current error: 0x%08X\n", priv->fatal_error);
|
|
else
|
|
- out += sprintf(out, "No current error condition.\n");
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "No current error condition.\n");
|
|
|
|
for (i = 1; i <= IPW2100_ERROR_QUEUE; i++) {
|
|
if (!priv->fatal_errors[(priv->fatal_index - i) %
|
|
@@ -3861,59 +3972,70 @@ static ssize_t show_fatal_error(struct d
|
|
continue;
|
|
|
|
if (!errors)
|
|
- out += sprintf(out, "Up to last %d errors:\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "Up to last %d errors:\n",
|
|
IPW2100_ERROR_QUEUE);
|
|
- out += sprintf(out, "%d. Error: 0x%08X\n", i,
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "%d. Error: 0x%08X\n", i,
|
|
priv->fatal_errors[(priv->fatal_index - i) %
|
|
IPW2100_ERROR_QUEUE]);
|
|
errors++;
|
|
}
|
|
|
|
if (!errors)
|
|
- out += sprintf(out, "No errors encountered.\n");
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "No errors encountered.\n");
|
|
|
|
#ifdef CONFIG_IPW_DEBUG
|
|
- out += sprintf(out, "Packet mismatch image: %s\n",
|
|
+ len += snprintf(page + len, count - len,
|
|
+ "Packet mismatch image: %s\n",
|
|
priv->snapshot[0] ? "YES" : "NO");
|
|
#endif
|
|
|
|
if (priv->fatal_error)
|
|
- out += sprintf(out,
|
|
+ len += snprintf(page + len, count - len,
|
|
"`echo 0 > fatal_error` to force firmware "
|
|
- "restart and clear current error condition.\n");
|
|
+ "restart and clear current error "
|
|
+ "condition.\n");
|
|
|
|
- return out - buf;
|
|
+ *eof = 1;
|
|
+ return len;
|
|
}
|
|
|
|
-static ssize_t store_fatal_error(struct device *d, const char *buf,
|
|
- size_t count)
|
|
+static int proc_set_fatal_error(struct file *file, const char *buffer,
|
|
+ unsigned long count, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
schedule_reset(priv);
|
|
return count;
|
|
}
|
|
-static DEVICE_ATTR(fatal_error, S_IWUSR|S_IRUGO, show_fatal_error, store_fatal_error);
|
|
-
|
|
|
|
-static ssize_t show_cardmem(struct device *d, char *buf)
|
|
+static int proc_get_cardmem(char *page,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int count, int *eof, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- struct net_device *dev = priv->ndev;
|
|
- char * out = buf;
|
|
- u32 dword;
|
|
+ int len = 0;
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
+ u32 d;
|
|
|
|
- read_nic_dword(dev, priv->proc_cardmemaddr, &dword);
|
|
+ read_nic_dword(dev, priv->proc_cardmemaddr, &d);
|
|
|
|
- out += sprintf(out, "cardmem addr[0x%08x] = 0x%08x (%d)\n",
|
|
- priv->proc_cardmemaddr, dword, dword);
|
|
+ len += snprintf(page, count,
|
|
+ "cardmem addr[0x%08x] = 0x%08x (%d)\n",
|
|
+ priv->proc_cardmemaddr, d, d);
|
|
|
|
- return out - buf;
|
|
+ *eof = 1;
|
|
+ return len;
|
|
}
|
|
|
|
-static ssize_t store_cardmem(struct device *d, const char *buf, size_t count)
|
|
+static int proc_set_cardmemaddr(struct file *file, const char *buf,
|
|
+ unsigned long count, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- struct net_device *dev = priv->ndev;
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
char buffer[] = "00000000";
|
|
unsigned long len =
|
|
(sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
|
|
@@ -3922,7 +4044,11 @@ static ssize_t store_cardmem(struct devi
|
|
|
|
IPW_DEBUG_INFO("enter\n");
|
|
|
|
- strncpy(buffer, buf, len);
|
|
+ if (copy_from_user(buffer, buf, len)) {
|
|
+ IPW_DEBUG_INFO("can't copy data from userspace\n");
|
|
+ /* stupid? yes, but how do I signal an error here? */
|
|
+ return count;
|
|
+ } else
|
|
buffer[len] = 0;
|
|
|
|
if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
|
|
@@ -3942,24 +4068,32 @@ static ssize_t store_cardmem(struct devi
|
|
}
|
|
|
|
IPW_DEBUG_INFO("exit\n");
|
|
- return len;
|
|
+ return count;
|
|
}
|
|
-static DEVICE_ATTR(cardmem, S_IWUSR | S_IRUGO, show_cardmem, store_cardmem);
|
|
-
|
|
|
|
-static ssize_t show_scan_age(struct device *d, char *buf)
|
|
+static int proc_get_scan_age(char *page,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int count, int *eof, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
+ int len = 0;
|
|
+ struct net_device *dev = (struct net_device *) data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
|
|
- return sprintf(buf, "Scan entries will expire after %u missed scans. "
|
|
+ len += snprintf(page, count,
|
|
+ "Scan entries will expire after %u missed scans. "
|
|
"(default is %u, 0 = never expire)\n",
|
|
priv->ieee->scan_age, DEFAULT_MAX_SCAN_AGE);
|
|
+
|
|
+ *eof = 1;
|
|
+ return len;
|
|
}
|
|
|
|
-static ssize_t store_scan_age(struct device *d, const char *buf, size_t count)
|
|
+static int proc_set_scan_age(struct file *file, const char *buf,
|
|
+ unsigned long count, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- struct net_device *dev = priv->ndev;
|
|
+ struct net_device *dev = (struct net_device *) data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
char buffer[] = "00000000";
|
|
unsigned long len =
|
|
(sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
|
|
@@ -3968,7 +4102,11 @@ static ssize_t store_scan_age(struct dev
|
|
|
|
IPW_DEBUG_INFO("enter\n");
|
|
|
|
- strncpy(buffer, buf, len);
|
|
+ if (copy_from_user(buffer, buf, len)) {
|
|
+ IPW_DEBUG_INFO("can't copy data from userspace\n");
|
|
+ /* stupid? yes, but how do I signal an error here? */
|
|
+ return count;
|
|
+ } else
|
|
buffer[len] = 0;
|
|
|
|
if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
|
|
@@ -3987,37 +4125,24 @@ static ssize_t store_scan_age(struct dev
|
|
}
|
|
|
|
IPW_DEBUG_INFO("exit\n");
|
|
- return len;
|
|
-}
|
|
-static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
|
|
-
|
|
-
|
|
-static ssize_t show_rf_kill(struct device *d, char *buf)
|
|
-{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- char * out = buf;
|
|
-
|
|
- if (priv->manual_disable)
|
|
- out += sprintf(out, "Radio disabled by manual switch.\n");
|
|
- else if (priv->hw_features & HW_FEATURE_RFKILL)
|
|
- out += sprintf(out, "Radio is %s by RF switch\n",
|
|
- ipw2100_get_rf_switch(priv) ?
|
|
- "disabled" : "enabled");
|
|
- else
|
|
- out += sprintf(out,
|
|
- "Your hardware does not have an RF switch\n");
|
|
-
|
|
- return out - buf;
|
|
+ return count;
|
|
}
|
|
|
|
-static ssize_t store_rf_kill(struct device *d, const char *buf, size_t count)
|
|
+static int proc_set_state(struct file *file, const char *buf,
|
|
+ unsigned long count, void *data)
|
|
{
|
|
- struct ipw2100_priv *priv = dev_get_drvdata(d);
|
|
- int state;
|
|
+ struct net_device *dev = (struct net_device *) data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
+ char state;
|
|
|
|
IPW_DEBUG_INFO("enter\n");
|
|
|
|
- sscanf(buf, "%d", &state);
|
|
+ if (copy_from_user(&state, buf, 1)) {
|
|
+ IPW_DEBUG_INFO("can't copy data from userspace\n");
|
|
+ /* stupid? yes, but how do I signal an error here? */
|
|
+ return count;
|
|
+ }
|
|
+
|
|
switch (state) {
|
|
case 0: /* Turn off Manual Disable */
|
|
if (priv->manual_disable) {
|
|
@@ -4052,31 +4177,323 @@ static ssize_t store_rf_kill(struct devi
|
|
IPW_DEBUG_INFO("exit\n");
|
|
return count;
|
|
}
|
|
-static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill);
|
|
|
|
+static int proc_get_state(char *page,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int count, int *eof, void *data)
|
|
+{
|
|
+ int len = 0;
|
|
+ struct net_device *dev = data;
|
|
+ struct ipw2100_priv *priv = ipw2100_netdev(dev);
|
|
|
|
-static struct attribute *ipw2100_sysfs_entries[] = {
|
|
- &dev_attr_hardware.attr,
|
|
- &dev_attr_registers.attr,
|
|
- &dev_attr_ordinals.attr,
|
|
- &dev_attr_pci.attr,
|
|
- &dev_attr_version.attr,
|
|
- &dev_attr_stats.attr,
|
|
- &dev_attr_internals.attr,
|
|
- &dev_attr_txqueue.attr,
|
|
- &dev_attr_rxqueue.attr,
|
|
- &dev_attr_bssinfo.attr,
|
|
- &dev_attr_memory.attr,
|
|
- &dev_attr_cardmem.attr,
|
|
- &dev_attr_scan_age.attr,
|
|
- &dev_attr_fatal_error.attr,
|
|
- &dev_attr_rf_kill.attr,
|
|
- NULL,
|
|
-};
|
|
+ if (priv->manual_disable)
|
|
+ len += snprintf(page, count,
|
|
+ "Radio disabled by manual switch.\n");
|
|
+ else if (priv->hw_features & HW_FEATURE_RFKILL)
|
|
+ len += snprintf(page, count, "Radio is %s by RF switch\n",
|
|
+ ipw2100_get_rf_switch(priv) ?
|
|
+ "disabled" : "enabled");
|
|
+ else
|
|
+ len += snprintf(page, count,
|
|
+ "Your hardware does not have an RF switch\n");
|
|
|
|
-static struct attribute_group ipw2100_attribute_group = {
|
|
- .attrs = ipw2100_sysfs_entries,
|
|
-};
|
|
+ *eof = 1;
|
|
+ return len;
|
|
+}
|
|
+
|
|
+
|
|
+int ipw2100_proc_dev_init(struct ipw2100_priv *priv)
|
|
+{
|
|
+ struct proc_dir_entry *e;
|
|
+
|
|
+ IPW_DEBUG_INFO("enter %s\n", priv->ndev->name);
|
|
+
|
|
+ priv->dir_dev = create_proc_entry(priv->ndev->name,
|
|
+ S_IFDIR | S_IRUGO | S_IXUGO,
|
|
+ ipw2100_proc);
|
|
+ if (!priv->dir_dev) {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize /proc/net/ipw2100/%s\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_read_entry("hw", S_IFREG | S_IRUGO,
|
|
+ priv->dir_dev, proc_get_hw, priv->ndev);
|
|
+ if (!e) {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/hw\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
|
|
+ priv->dir_dev, proc_get_registers, priv->ndev);
|
|
+ if (!e) {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/registers\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_read_entry("ordinals", S_IFREG | S_IRUGO,
|
|
+ priv->dir_dev, proc_get_ordinals, priv->ndev);
|
|
+ if (!e) {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/ordinals\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_read_entry("pci", S_IFREG | S_IRUGO,
|
|
+ priv->dir_dev, proc_get_pci, priv->ndev);
|
|
+ if (!e) {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/pci\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_read_entry("version", S_IFREG | S_IRUGO,
|
|
+ priv->dir_dev, proc_get_version, priv->ndev);
|
|
+ if (!e) {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/version\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_read_entry("stats", S_IFREG | S_IRUGO,
|
|
+ priv->dir_dev, proc_get_stats, priv->ndev);
|
|
+ if (!e) {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/stats\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_read_entry("internals", S_IFREG | S_IRUGO,
|
|
+ priv->dir_dev, proc_get_internals, priv->ndev);
|
|
+ if (!e) {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/internals\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_read_entry("txqueue", S_IFREG | S_IRUGO,
|
|
+ priv->dir_dev, proc_get_txqueue, priv->ndev);
|
|
+ if (!e) {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/txqueue\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_read_entry("rxqueue", S_IFREG | S_IRUGO,
|
|
+ priv->dir_dev, proc_get_rxqueue, priv->ndev);
|
|
+ if (!e) {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/rxqueue\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_read_entry("bssinfo", S_IFREG | S_IRUGO,
|
|
+ priv->dir_dev, proc_get_bssinfo, priv->ndev);
|
|
+ if (!e) {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/bssinfo\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_entry("memory", S_IFREG | S_IRUGO | S_IWUSR,
|
|
+ priv->dir_dev);
|
|
+ if (e) {
|
|
+ e->read_proc = proc_get_memory;
|
|
+ e->write_proc = proc_set_memory;
|
|
+ e->data = priv->ndev;
|
|
+ } else {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/memory\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_entry("cardmem", S_IFREG | S_IRUGO | S_IWUSR,
|
|
+ priv->dir_dev);
|
|
+ if (e) {
|
|
+ e->read_proc = proc_get_cardmem;
|
|
+ e->write_proc = proc_set_cardmemaddr;
|
|
+ e->data = priv->ndev;
|
|
+ } else {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/cardmem\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_entry("scan_age", S_IFREG | S_IRUGO | S_IWUSR,
|
|
+ priv->dir_dev);
|
|
+ if (e) {
|
|
+ e->read_proc = proc_get_scan_age;
|
|
+ e->write_proc = proc_set_scan_age;
|
|
+ e->data = priv->ndev;
|
|
+ } else {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/scan_age\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_entry("fatal_error", S_IFREG | S_IRUGO | S_IWUSR,
|
|
+ priv->dir_dev);
|
|
+ if (e) {
|
|
+ e->read_proc = proc_get_fatal_error;
|
|
+ e->write_proc = proc_set_fatal_error;
|
|
+ e->data = priv->ndev;
|
|
+ } else {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/fatal_error\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ e = create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR,
|
|
+ priv->dir_dev);
|
|
+ if (e) {
|
|
+ e->read_proc = proc_get_state;
|
|
+ e->write_proc = proc_set_state;
|
|
+ e->data = priv->ndev;
|
|
+ } else {
|
|
+ printk(KERN_ERR
|
|
+ "Unable to initialize "
|
|
+ "/proc/net/ipw2100/%s/state\n",
|
|
+ priv->ndev->name);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ IPW_DEBUG_INFO("exit %s\n", priv->ndev->name);
|
|
+
|
|
+ return 0;
|
|
+
|
|
+ fail:
|
|
+ ipw2100_proc_dev_cleanup(priv);
|
|
+ IPW_DEBUG_INFO("exit on fail %s\n", priv->ndev->name);
|
|
+
|
|
+ return -ENOMEM;
|
|
+}
|
|
+
|
|
+void ipw2100_proc_dev_cleanup(struct ipw2100_priv *priv)
|
|
+{
|
|
+ IPW_DEBUG_INFO("enter %s\n", priv->ndev->name);
|
|
+
|
|
+ if (priv->dir_dev) {
|
|
+ remove_proc_entry("stats", priv->dir_dev);
|
|
+ remove_proc_entry("internals", priv->dir_dev);
|
|
+ remove_proc_entry("txqueue", priv->dir_dev);
|
|
+ remove_proc_entry("rxqueue", priv->dir_dev);
|
|
+ remove_proc_entry("cardmem", priv->dir_dev);
|
|
+ remove_proc_entry("scan_age", priv->dir_dev);
|
|
+ remove_proc_entry("bssinfo", priv->dir_dev);
|
|
+ remove_proc_entry("state", priv->dir_dev);
|
|
+ remove_proc_entry("version", priv->dir_dev);
|
|
+ remove_proc_entry("hw", priv->dir_dev);
|
|
+ remove_proc_entry("registers", priv->dir_dev);
|
|
+ remove_proc_entry("memory", priv->dir_dev);
|
|
+ remove_proc_entry("ordinals", priv->dir_dev);
|
|
+ remove_proc_entry("pci", priv->dir_dev);
|
|
+ remove_proc_entry("fatal_error", priv->dir_dev);
|
|
+ remove_proc_entry(priv->ndev->name, ipw2100_proc);
|
|
+ priv->dir_dev = NULL;
|
|
+ }
|
|
+
|
|
+ IPW_DEBUG_INFO("exit %s\n", priv->ndev->name);
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * Initialize ipw2100 proc filesystem's entry.
|
|
+ *
|
|
+ * @returns 0 if ok, < 0 errno code on error [-ENOMEM].
|
|
+ *
|
|
+ * On error, it takes care of cleaning up as if nothing had been
|
|
+ * done.
|
|
+ */
|
|
+static
|
|
+int ipw2100_proc_init(void)
|
|
+{
|
|
+ struct proc_dir_entry *e;
|
|
+
|
|
+ IPW_DEBUG_INFO("enter\n");
|
|
+
|
|
+ ipw2100_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
|
|
+ if (ipw2100_proc == NULL)
|
|
+ goto fail_ipw2100;
|
|
+
|
|
+ /* Next we create only if we compiled in debug support */
|
|
+ if (!IPW_DEBUG_ENABLED)
|
|
+ goto skip_debug;
|
|
+
|
|
+ e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
|
|
+ ipw2100_proc);
|
|
+ if (e == NULL)
|
|
+ goto fail_debug;
|
|
+ e->read_proc = proc_get_debug_level;
|
|
+ e->write_proc = proc_set_debug_level;
|
|
+ e->data = NULL;
|
|
+
|
|
+skip_debug:
|
|
+ IPW_DEBUG_INFO("exit\n");
|
|
+ return 0;
|
|
+
|
|
+fail_debug:
|
|
+ printk(KERN_ERR DRV_NAME ": Unable to initialize "
|
|
+ "/proc/net/" DRV_NAME "/debug_level\n");
|
|
+ remove_proc_entry(DRV_NAME, proc_net);
|
|
+ ipw2100_proc = NULL;
|
|
+ goto fail;
|
|
+
|
|
+fail_ipw2100:
|
|
+ printk(KERN_ERR DRV_NAME ": Unable to initialize /proc/net/"
|
|
+ DRV_NAME "\n");
|
|
+
|
|
+fail:
|
|
+ IPW_DEBUG_INFO("exit on fail\n");
|
|
+ return -ENOMEM;
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * Releases /proc filesystem entries.
|
|
+ *
|
|
+ * Assumes all went ok when allocating them.
|
|
+ */
|
|
+static void ipw2100_proc_cleanup(void)
|
|
+{
|
|
+ IPW_DEBUG_INFO("enter\n");
|
|
+
|
|
+ if (IPW_DEBUG_ENABLED && ipw2100_proc)
|
|
+ remove_proc_entry("debug_level", ipw2100_proc);
|
|
+ remove_proc_entry(DRV_NAME, proc_net);
|
|
+ IPW_DEBUG_INFO("exit\n");
|
|
+}
|
|
|
|
|
|
static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
|
|
@@ -6647,8 +7064,17 @@ static int ipw2100_pci_init_one(struct p
|
|
|
|
printk(KERN_INFO "%s: Bound to %s\n", dev->name, pci_name(pdev));
|
|
|
|
- /* perform this after register_netdev so that dev->name is set */
|
|
- sysfs_create_group(&pdev->dev.kobj, &ipw2100_attribute_group);
|
|
+ /* perform this after register_netdev so that dev->name is
|
|
+ * set */
|
|
+ err = ipw2100_proc_dev_init(priv);
|
|
+ if (err) {
|
|
+ printk(KERN_ERR
|
|
+ "%s: Failed to create /proc node\n",
|
|
+ dev->name);
|
|
+ err = -EIO;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
netif_carrier_off(dev);
|
|
|
|
/* If the RF Kill switch is disabled, go ahead and complete the
|
|
@@ -6698,7 +7124,7 @@ static int ipw2100_pci_init_one(struct p
|
|
|
|
/* These are safe to call even if they weren't allocated */
|
|
ipw2100_queues_free(priv);
|
|
- sysfs_remove_group(&pdev->dev.kobj, &ipw2100_attribute_group);
|
|
+ ipw2100_proc_dev_cleanup(priv);
|
|
|
|
free_netdev(dev);
|
|
pci_set_drvdata(pdev, NULL);
|
|
@@ -6720,7 +7146,7 @@ static void __devexit ipw2100_pci_remove
|
|
|
|
if (priv) {
|
|
dev = priv->ndev;
|
|
- sysfs_remove_group(&pdev->dev.kobj, &ipw2100_attribute_group);
|
|
+ ipw2100_proc_dev_cleanup(priv);
|
|
|
|
#ifdef CONFIG_PM
|
|
if (ipw2100_firmware.version)
|
|
@@ -6912,17 +7338,16 @@ static int __init ipw2100_init(void)
|
|
printk(KERN_INFO DRV_NAME ": Compiled with LEGACY FW load.\n");
|
|
#endif
|
|
|
|
- ret = pci_module_init(&ipw2100_pci_driver);
|
|
-
|
|
/* If debug module parameter declared, set debug_level to that */
|
|
if (debug != -1)
|
|
ipw2100_debug_level = debug;
|
|
|
|
-#ifdef CONFIG_IPW_DEBUG
|
|
- driver_create_file(&ipw2100_pci_driver.driver,
|
|
- &driver_attr_debug_level);
|
|
-#endif
|
|
-
|
|
+ ret = ipw2100_proc_init();
|
|
+ if (!ret) {
|
|
+ ret = pci_module_init(&ipw2100_pci_driver);
|
|
+ if (ret)
|
|
+ ipw2100_proc_cleanup();
|
|
+ }
|
|
return ret;
|
|
}
|
|
|
|
@@ -6933,11 +7358,8 @@ static int __init ipw2100_init(void)
|
|
static void __exit ipw2100_exit(void)
|
|
{
|
|
/* FIXME: IPG: check that we have no instances of the devices open */
|
|
-#ifdef CONFIG_IPW_DEBUG
|
|
- driver_remove_file(&ipw2100_pci_driver.driver,
|
|
- &driver_attr_debug_level);
|
|
-#endif
|
|
pci_unregister_driver(&ipw2100_pci_driver);
|
|
+ ipw2100_proc_cleanup();
|
|
}
|
|
|
|
module_init(ipw2100_init);
|