|
|
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);
|