mirror of the now-defunct rocklinux.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1439 lines
41 KiB

  1. diff -u -p -r -b ipw2100-0.55.orig/ieee80211_crypt.c ipw2100-0.55/ieee80211_crypt.c
  2. --- ipw2100-0.55.orig/ieee80211_crypt.c 2004-09-27 19:29:17.000000000 +0200
  3. +++ ipw2100-0.55/ieee80211_crypt.c 2004-09-28 21:10:53.000000000 +0200
  4. @@ -55,7 +55,9 @@ void ieee80211_crypt_deinit_entries(stru
  5. if (entry->ops) {
  6. entry->ops->deinit(entry->priv);
  7. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
  8. module_put(entry->ops->owner);
  9. +#endif
  10. }
  11. kfree(entry);
  12. }
  13. diff -u -p -r -b ipw2100-0.55.orig/ieee80211_module.c ipw2100-0.55/ieee80211_module.c
  14. --- ipw2100-0.55.orig/ieee80211_module.c 2004-09-27 19:29:17.000000000 +0200
  15. +++ ipw2100-0.55/ieee80211_module.c 2004-09-28 21:10:53.000000000 +0200
  16. @@ -157,7 +157,9 @@ void ieee80211_free(struct ieee80211_dev
  17. if (crypt) {
  18. if (crypt->ops) {
  19. crypt->ops->deinit(crypt->priv);
  20. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
  21. module_put(crypt->ops->owner);
  22. +#endif
  23. }
  24. kfree(crypt);
  25. ieee->crypt[i] = NULL;
  26. diff -u -p -r -b ipw2100-0.55.orig/ieee80211_wx.c ipw2100-0.55/ieee80211_wx.c
  27. --- ipw2100-0.55.orig/ieee80211_wx.c 2004-09-27 19:29:17.000000000 +0200
  28. +++ ipw2100-0.55/ieee80211_wx.c 2004-09-28 21:10:53.000000000 +0200
  29. @@ -237,7 +237,11 @@ int ieee80211_wx_set_encode(struct ieee8
  30. new_crypt->ops = ieee80211_get_crypto_ops("WEP");
  31. }
  32. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
  33. if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
  34. +#else
  35. + if (new_crypt->ops)
  36. +#endif
  37. new_crypt->priv = new_crypt->ops->init(key);
  38. if (!new_crypt->ops || !new_crypt->priv) {
  39. diff -u -p -r -b ipw2100-0.55.orig/ipw2100.c ipw2100-0.55/ipw2100.c
  40. --- ipw2100-0.55.orig/ipw2100.c 2004-09-27 19:29:17.000000000 +0200
  41. +++ ipw2100-0.55/ipw2100.c 2004-09-28 21:10:53.000000000 +0200
  42. @@ -358,6 +358,10 @@ static void ipw2100_queues_initialize(st
  43. static void ipw2100_queues_free(struct ipw2100_priv *priv);
  44. static int ipw2100_queues_allocate(struct ipw2100_priv *priv);
  45. +static void ipw2100_proc_cleanup(void);
  46. +static void ipw2100_proc_dev_cleanup(struct ipw2100_priv *priv);
  47. +static int ipw2100_proc_dev_init(struct ipw2100_priv *priv);
  48. +
  49. static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
  50. {
  51. return (dev->base_addr &&
  52. @@ -3064,26 +3068,35 @@ static void ipw2100_msg_free(struct ipw2
  53. priv->msg_buffers = NULL;
  54. }
  55. -static ssize_t show_pci(struct device *d, char *buf)
  56. +static struct proc_dir_entry *ipw2100_proc = NULL;
  57. +
  58. +static int proc_get_pci(char *page, char **start,
  59. + off_t offset, int count,
  60. + int *eof, void *data)
  61. {
  62. - struct pci_dev *pdev = container_of(d, struct pci_dev, dev);
  63. - char * out = buf;
  64. - int i, j;
  65. + struct net_device *dev = data;
  66. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  67. + struct pci_dev *pdev = priv->pdev;
  68. + int i, j, len;
  69. u32 val;
  70. - out += sprintf(out, "PCI Configuration Data\n");
  71. +
  72. + len = 0;
  73. +
  74. + len += snprintf(page + len, count - len, "PCI Configuration Data\n");
  75. +
  76. for (i = 0; i < 16; i++) {
  77. - out += sprintf(out, "[%08X] ", i * 16);
  78. + len += snprintf(page + len, count - len, "[%08X] ", i * 16);
  79. for (j = 0; j < 16; j += 4) {
  80. pci_read_config_dword(pdev, i * 16 + j, &val);
  81. - out += sprintf(out, "%08X ", val);
  82. + len += snprintf(page + len, count - len, "%08X ", val);
  83. }
  84. - out += sprintf(out, "\n");
  85. + len += snprintf(page + len, count - len, "\n");
  86. }
  87. - return out - buf;
  88. + *eof = 1;
  89. + return len;
  90. }
  91. -static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
  92. #define IPW2100_REG(x) { IPW_ ##x, #x }
  93. @@ -3263,37 +3276,48 @@ const struct {
  94. };
  95. -static ssize_t show_registers(struct device *d, char *buf)
  96. +static int proc_get_registers(char *page, char **start,
  97. + off_t offset, int count,
  98. + int *eof, void *data)
  99. {
  100. + struct net_device *dev = data;
  101. int i;
  102. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  103. - struct net_device *dev = priv->ndev;
  104. - char * out = buf;
  105. + int len = 0;
  106. u32 val = 0;
  107. - out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
  108. + len += snprintf(page + len, count - len,
  109. + "%30s [Address ] : Hex\n", "Register");
  110. - for (i = 0; i < (sizeof(hw_data) / sizeof(*hw_data)); i++) {
  111. + for (i = 0;
  112. + i < (sizeof(hw_data) / sizeof(*hw_data));
  113. + i++) {
  114. read_register(dev, hw_data[i].addr, &val);
  115. - out += sprintf(out, "%30s [%08X] : %08X\n",
  116. - hw_data[i].name, hw_data[i].addr, val);
  117. +
  118. + len += snprintf(page + len, count - len,
  119. + "%30s [%08X] : %08X\n",
  120. + hw_data[i].name, hw_data[i].addr,
  121. + val);
  122. }
  123. - return out - buf;
  124. + *eof = 1;
  125. + return len;
  126. }
  127. -static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
  128. -static ssize_t show_hardware(struct device *d, char *buf)
  129. +static int proc_get_hw(char *page, char **start,
  130. + off_t offset, int count,
  131. + int *eof, void *data)
  132. {
  133. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  134. - struct net_device *dev = priv->ndev;
  135. - char * out = buf;
  136. + struct net_device *dev = data;
  137. int i;
  138. + int len = 0;
  139. - out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
  140. + len += snprintf(page + len, count - len,
  141. + "%30s [Address ] : Hex\n", "NIC entry");
  142. - for (i = 0; i < (sizeof(nic_data) / sizeof(*nic_data)); i++) {
  143. + for (i = 0;
  144. + i < (sizeof(nic_data) / sizeof(*nic_data));
  145. + i++) {
  146. u8 tmp8;
  147. u16 tmp16;
  148. u32 tmp32;
  149. @@ -3301,163 +3325,213 @@ static ssize_t show_hardware(struct devi
  150. switch (nic_data[i].size) {
  151. case 1:
  152. read_nic_byte(dev, nic_data[i].addr, &tmp8);
  153. - out += sprintf(out, "%30s [%08X] : %02X\n",
  154. + len += snprintf(page + len, count - len,
  155. + "%30s [%08X] : %02X\n",
  156. nic_data[i].name, nic_data[i].addr,
  157. tmp8);
  158. break;
  159. case 2:
  160. read_nic_word(dev, nic_data[i].addr, &tmp16);
  161. - out += sprintf(out, "%30s [%08X] : %04X\n",
  162. + len += snprintf(page + len, count - len,
  163. + "%30s [%08X] : %04X\n",
  164. nic_data[i].name, nic_data[i].addr,
  165. tmp16);
  166. break;
  167. case 4:
  168. read_nic_dword(dev, nic_data[i].addr, &tmp32);
  169. - out += sprintf(out, "%30s [%08X] : %08X\n",
  170. + len += snprintf(page + len, count - len,
  171. + "%30s [%08X] : %08X\n",
  172. nic_data[i].name, nic_data[i].addr,
  173. tmp32);
  174. break;
  175. }
  176. }
  177. - return out - buf;
  178. + *eof = 1;
  179. + return len;
  180. }
  181. -static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
  182. -static ssize_t show_memory(struct device *d, char *buf)
  183. +static int proc_set_memory(struct file *file, const char *buffer,
  184. + unsigned long count, void *data)
  185. {
  186. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  187. - struct net_device *dev = priv->ndev;
  188. - static unsigned long loop = 0;
  189. + struct net_device *dev = data;
  190. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  191. + char buf[] = "0000";
  192. + unsigned long len = (sizeof(buf) - 1) > count ? count :
  193. + sizeof(buf) - 1;
  194. + char *p = buf;
  195. +
  196. + if (copy_from_user(buf, buffer, len)) {
  197. + IPW_DEBUG_INFO("can't copy data from userspace\n");
  198. + /* stupid? yes, but how do I signal an error here? */
  199. + return count;
  200. + } else
  201. + buf[len] = 0;
  202. +
  203. + if (p[0] == '1' || (tolower(p[0]) == 'o' && tolower(p[1] == 'n'))) {
  204. + printk(KERN_INFO "%s: Setting memory dump to RAW mode.\n",
  205. + dev->name);
  206. + priv->dump_raw = 1;
  207. + } else if (p[0] == '0' ||
  208. + (tolower(p[0]) == 'o' && tolower(p[1] == 'f'))) {
  209. + printk(KERN_INFO "%s: Setting memory dump to HEX mode.\n",
  210. + dev->name);
  211. + priv->dump_raw = 0;
  212. + } else if (tolower(p[0]) == 'r') {
  213. + printk(KERN_INFO "%s: Resetting firmware snapshot.\n",
  214. + dev->name);
  215. + ipw2100_snapshot_free(priv);
  216. + } else
  217. + printk(KERN_INFO "%s: Usage: 0|on = HEX, 1|off = RAW, "
  218. + "reset = clear memory snapshot\n",
  219. + dev->name);
  220. +
  221. + return count;
  222. +}
  223. +
  224. +static int proc_get_memory(char *page, char **start,
  225. + off_t offset, int count,
  226. + int *eof, void *data)
  227. +{
  228. + struct net_device *dev = data;
  229. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  230. int len = 0;
  231. - u32 buffer[4];
  232. + static unsigned long loop = 0;
  233. + u32 buf[4];
  234. int i;
  235. char line[81];
  236. - if (loop >= 0x30000)
  237. + if (offset == 0)
  238. loop = 0;
  239. - /* sysfs provides us PAGE_SIZE buffer */
  240. - while (len < PAGE_SIZE - 128 && loop < 0x30000) {
  241. + /* If we've reached EOF or the user is cutting is short, then
  242. + * restart the counter and return 0 bytes */
  243. + if (loop >= 0x30000) {
  244. + *start = NULL;
  245. + *eof = 1;
  246. + return 0;
  247. + }
  248. +
  249. + /* Return around 2k per pass... */
  250. + while (count - len > 256 &&
  251. + len < 2048 &&
  252. + loop < 0x30000) {
  253. if (priv->snapshot[0]) for (i = 0; i < 4; i++)
  254. - buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4);
  255. + buf[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4);
  256. else for (i = 0; i < 4; i++)
  257. - read_nic_dword(dev, loop + i * 4, &buffer[i]);
  258. + read_nic_dword(dev, loop + i * 4, &buf[i]);
  259. if (priv->dump_raw)
  260. - len += sprintf(buf + len,
  261. + len += snprintf(page + len, count - len,
  262. "%c%c%c%c"
  263. "%c%c%c%c"
  264. "%c%c%c%c"
  265. "%c%c%c%c",
  266. - ((u8*)buffer)[0x0],
  267. - ((u8*)buffer)[0x1],
  268. - ((u8*)buffer)[0x2],
  269. - ((u8*)buffer)[0x3],
  270. - ((u8*)buffer)[0x4],
  271. - ((u8*)buffer)[0x5],
  272. - ((u8*)buffer)[0x6],
  273. - ((u8*)buffer)[0x7],
  274. - ((u8*)buffer)[0x8],
  275. - ((u8*)buffer)[0x9],
  276. - ((u8*)buffer)[0xa],
  277. - ((u8*)buffer)[0xb],
  278. - ((u8*)buffer)[0xc],
  279. - ((u8*)buffer)[0xd],
  280. - ((u8*)buffer)[0xe],
  281. - ((u8*)buffer)[0xf]);
  282. + ((u8*)buf)[0x0],
  283. + ((u8*)buf)[0x1],
  284. + ((u8*)buf)[0x2],
  285. + ((u8*)buf)[0x3],
  286. + ((u8*)buf)[0x4],
  287. + ((u8*)buf)[0x5],
  288. + ((u8*)buf)[0x6],
  289. + ((u8*)buf)[0x7],
  290. + ((u8*)buf)[0x8],
  291. + ((u8*)buf)[0x9],
  292. + ((u8*)buf)[0xa],
  293. + ((u8*)buf)[0xb],
  294. + ((u8*)buf)[0xc],
  295. + ((u8*)buf)[0xd],
  296. + ((u8*)buf)[0xe],
  297. + ((u8*)buf)[0xf]);
  298. else
  299. - len += sprintf(buf + len, "%s\n",
  300. - snprint_line(line, sizeof(line),
  301. - (u8*)buffer, 16, loop));
  302. + len += snprintf(page + len, count - len, "%s\n",
  303. + snprint_line(
  304. + line, sizeof(line), (u8*)buf,
  305. + 16, loop));
  306. +
  307. loop += 16;
  308. }
  309. - return len;
  310. -}
  311. -
  312. -static ssize_t store_memory(struct device *d, const char *buf, size_t count)
  313. -{
  314. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  315. - struct net_device *dev = priv->ndev;
  316. - const char *p = buf;
  317. -
  318. - if (count < 1)
  319. - return count;
  320. -
  321. - if (p[0] == '1' ||
  322. - (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
  323. - printk(KERN_INFO "%s: Setting memory dump to RAW mode.\n",
  324. - dev->name);
  325. - priv->dump_raw = 1;
  326. -
  327. - } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
  328. - tolower(p[1]) == 'f')) {
  329. - printk(KERN_INFO "%s: Setting memory dump to HEX mode.\n",
  330. - dev->name);
  331. - priv->dump_raw = 0;
  332. -
  333. - } else if (tolower(p[0]) == 'r') {
  334. - printk(KERN_INFO "%s: Resetting firmware snapshot.\n",
  335. - dev->name);
  336. - ipw2100_snapshot_free(priv);
  337. -
  338. - } else
  339. - printk(KERN_INFO "%s: Usage: 0|on = HEX, 1|off = RAW, "
  340. - "reset = clear memory snapshot\n",
  341. - dev->name);
  342. + /* see comment in fs/proc/generic.c proc_file_read */
  343. + if (len)
  344. + *start = (char*)len;
  345. + else
  346. + *eof = 1;
  347. - return count;
  348. + return len;
  349. }
  350. -static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
  351. -static ssize_t show_ordinals(struct device *d, char *buf)
  352. +static int proc_get_ordinals(char *page, char **start,
  353. + off_t offset, int count,
  354. + int *eof, void *data)
  355. {
  356. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  357. - u32 val = 0;
  358. + struct net_device *dev = data;
  359. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  360. int len = 0;
  361. u32 val_len;
  362. + u32 val = 0;
  363. static int loop = 0;
  364. - if (loop >= sizeof(ord_data) / sizeof(*ord_data))
  365. + if (offset == 0)
  366. loop = 0;
  367. - /* sysfs provides us PAGE_SIZE buffer */
  368. - while (len < PAGE_SIZE - 128 &&
  369. + /* If we've reached EOF or the user is cutting is short, then
  370. + * restart the counter and return 0 bytes */
  371. + if (loop >= (sizeof(ord_data) / sizeof(*ord_data))) {
  372. + *start = NULL;
  373. + *eof = 1;
  374. + return 0;
  375. + }
  376. +
  377. + /* Return around 2k per pass... */
  378. + while (count - len > 256 &&
  379. + len < 2048 &&
  380. loop < (sizeof(ord_data) / sizeof(*ord_data))) {
  381. val_len = sizeof(u32);
  382. if (ipw2100_get_ordinal(priv, ord_data[loop].index, &val,
  383. &val_len))
  384. - len += sprintf(buf + len, "[0x%02X] = ERROR %s\n",
  385. + len += snprintf(page + len, count - len,
  386. + "[0x%02X] = ERROR %s\n",
  387. ord_data[loop].index,
  388. ord_data[loop].desc);
  389. else
  390. - len += sprintf(buf + len, "[0x%02X] = 0x%08X %s\n",
  391. - ord_data[loop].index, val,
  392. - ord_data[loop].desc);
  393. + len += snprintf(page + len, count - len,
  394. + "[0x%02X] = 0x%08X %s\n",
  395. + ord_data[loop].index,
  396. + val, ord_data[loop].desc);
  397. +
  398. loop++;
  399. }
  400. + /* see comment in fs/proc/generic.c proc_file_read */
  401. + if (len)
  402. + *start = (char*)len;
  403. + else
  404. + *eof = 1;
  405. +
  406. return len;
  407. }
  408. -static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
  409. -
  410. -static ssize_t show_version(struct device *d, char *buf)
  411. +static int proc_get_version(char *page, char **start,
  412. + off_t offset, int count,
  413. + int *eof, void *data)
  414. {
  415. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  416. - char * out = buf;
  417. - char tmp[MAX_FW_VERSION_LEN];
  418. + struct net_device *dev = data;
  419. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  420. int err;
  421. + int len = 0;
  422. + char tmp[MAX_FW_VERSION_LEN];
  423. - out += sprintf(out, "hardware : 0x%04X\n",
  424. + len += snprintf(page + len, count - len,
  425. + "hardware : 0x%04X\n",
  426. priv->pdev->subsystem_device);
  427. - out += sprintf(out, "driver : " DRV_VERSION " ["
  428. + len += snprintf(page + len, count - len,
  429. + "driver : " DRV_VERSION " ["
  430. #ifdef CONFIG_IEEE80211_NOWEP
  431. " !WEP"
  432. #else
  433. @@ -3470,53 +3544,66 @@ static ssize_t show_version(struct devic
  434. #endif
  435. " ]\n");
  436. - out += sprintf(out, "build date : " __DATE__ "\n");
  437. - out += sprintf(out, "build time : " __TIME__ "\n");
  438. - out += sprintf(out, "eeprom : %d\n", priv->eeprom_version);
  439. + len += snprintf(page + len, count - len,
  440. + "build date : " __DATE__ "\n");
  441. + len += snprintf(page + len, count - len,
  442. + "build time : " __TIME__ "\n");
  443. +
  444. + len += snprintf(page + len, count - len,
  445. + "eeprom : %d\n", priv->eeprom_version);
  446. err = ipw2100_get_ucodeversion(priv, tmp, sizeof(tmp));
  447. if (err < 0)
  448. - out += sprintf(out, "ucode : error\n");
  449. + len += snprintf(page + len, count - len,
  450. + "ucode : error\n");
  451. else
  452. - out += sprintf(out, "ucode : %s\n", tmp);
  453. -
  454. + len += snprintf(page + len, count - len,
  455. + "ucode : %s\n", tmp);
  456. err = ipw2100_get_fwversion(priv, tmp, sizeof(tmp));
  457. if (err < 0)
  458. - out += sprintf(out, "firmware : error\n");
  459. + len += snprintf(page + len, count - len,
  460. + "firmware : error\n");
  461. else
  462. - out += sprintf(out, "firmware : %s\n", tmp);
  463. + len += snprintf(page + len, count - len,
  464. + "firmware : %s\n", tmp);
  465. - out += sprintf(out, "firmware img : 0x%04X\n",
  466. - priv->firmware_version);
  467. + len += snprintf(page + len, count - len,
  468. + "firmware img : 0x%04X\n", priv->firmware_version);
  469. - out += sprintf(out, "firmware mode: %s\n",
  470. + len += snprintf(page + len, count - len,
  471. + "firmware mode: %s\n",
  472. priv->ctx->port_type == MONITOR ? "RFMON" :
  473. priv->ctx->port_type == IBSS ? "IBSS" : "BSS");
  474. - return out - buf;
  475. + *eof = 1;
  476. + return len;
  477. }
  478. -static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
  479. -
  480. -static ssize_t show_stats(struct device *d, char *buf)
  481. +static int proc_get_stats(char *page, char **start,
  482. + off_t offset, int count,
  483. + int *eof, void *data)
  484. {
  485. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  486. - char * out = buf;
  487. + struct net_device *dev = data;
  488. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  489. + int len = 0;
  490. - out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
  491. + len += snprintf(page + len, count - len,
  492. + "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
  493. priv->interrupts, priv->tx_interrupts,
  494. priv->rx_interrupts, priv->inta_other);
  495. - out += sprintf(out, "firmware resets: %d\n", priv->resets);
  496. - out += sprintf(out, "firmware hangs: %d\n", priv->hangs);
  497. + len += snprintf(page + len, count - len,
  498. + "firmware resets: %d\n", priv->resets);
  499. + len += snprintf(page + len, count - len,
  500. + "firmware hangs: %d\n", priv->hangs);
  501. #ifdef CONFIG_IPW_DEBUG
  502. - out += sprintf(out, "packet mismatch image: %s\n",
  503. + len += snprintf(page + len, count - len,
  504. + "packet mismatch image: %s\n",
  505. priv->snapshot[0] ? "YES" : "NO");
  506. #endif
  507. - return out - buf;
  508. + *eof = 1;
  509. + return len;
  510. }
  511. -static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
  512. -
  513. #ifdef CONFIG_IPW2100_PROMISC
  514. int ipw2100_enable_monitor(struct ipw2100_priv *priv, u32 channel)
  515. @@ -3614,12 +3701,17 @@ int ipw2100_switch_mode(struct ipw2100_p
  516. return 0;
  517. }
  518. -static ssize_t show_internals(struct device *d, char *buf)
  519. +static int proc_get_internals(char *page, char **start,
  520. + off_t offset, int count,
  521. + int *eof, void *data)
  522. {
  523. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  524. + struct net_device *dev = data;
  525. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  526. int len = 0;
  527. -#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" # y "\n", priv-> x)
  528. +#define DUMP_VAR(x,y) \
  529. + len += snprintf(page + len, count - len, \
  530. + # x ": %" # y "\n", priv-> x)
  531. DUMP_VAR(connected, d);
  532. DUMP_VAR(connected ? get_seconds() - priv->connect_start : 0, lu);
  533. @@ -3660,20 +3752,23 @@ static ssize_t show_internals(struct dev
  534. DUMP_VAR(ieee->scans, d);
  535. DUMP_VAR(reset_backoff, d);
  536. + *eof = 1;
  537. return len;
  538. }
  539. -static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
  540. -
  541. -static ssize_t show_bssinfo(struct device *d, char *buf)
  542. +static int proc_get_bssinfo(char *page,
  543. + char **start,
  544. + off_t offset,
  545. + int count, int *eof, void *data)
  546. {
  547. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  548. + int len = 0;
  549. + struct net_device *dev = data;
  550. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  551. + int ret;
  552. + int length;
  553. char essid[IW_ESSID_MAX_SIZE + 1];
  554. u8 bssid[ETH_ALEN];
  555. u32 chan = 0;
  556. - char * out = buf;
  557. - int length;
  558. - int ret;
  559. memset(essid, 0, sizeof(essid));
  560. memset(bssid, 0, sizeof(bssid));
  561. @@ -3697,23 +3792,26 @@ static ssize_t show_bssinfo(struct devic
  562. IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
  563. __LINE__);
  564. - out += sprintf(out, "ESSID: %s\n", essid);
  565. - out += sprintf(out, "BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n",
  566. + len += snprintf(page + len, count - len, "ESSID: %s\n", essid);
  567. + len += snprintf(page + len, count - len,
  568. + "BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n",
  569. bssid[0], bssid[1], bssid[2],
  570. bssid[3], bssid[4], bssid[5]);
  571. - out += sprintf(out, "Channel: %d\n", chan);
  572. + len += snprintf(page + len, count - len, "Channel: %d\n", chan);
  573. - return out - buf;
  574. + *eof = 1;
  575. + return len;
  576. }
  577. -static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
  578. -
  579. -static ssize_t show_txqueue(struct device *d, char *buf)
  580. +static int proc_get_txqueue(char *page,
  581. + char **start,
  582. + off_t offset,
  583. + int count, int *eof, void *data)
  584. {
  585. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  586. - struct net_device *dev = priv->ndev;
  587. - char * out = buf;
  588. + int len = 0;
  589. u32 tbdr_r, tbdr_w;
  590. + struct net_device *dev = data;
  591. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  592. IPW_DEBUG_INFO("enter\n");
  593. @@ -3724,25 +3822,29 @@ static ssize_t show_txqueue(struct devic
  594. IPW_DEBUG_INFO("after register read\n");
  595. - out += sprintf(out,
  596. + len += snprintf(page, count,
  597. "Tx Queue\nnic:\n\tread index=%d\n\twrite index=%d\n",
  598. tbdr_r, tbdr_w);
  599. - out += sprintf(out, "drv:\n\tread index=%d\n\twrite index=%d\n",
  600. + len += snprintf(page + len, count - len,
  601. + "drv:\n\tread index=%d\n\twrite index=%d\n",
  602. priv->tx_queue.oldest,
  603. priv->tx_queue.next);
  604. + *eof = 1;
  605. IPW_DEBUG_INFO("exit\n");
  606. - return out - buf;
  607. -}
  608. -static DEVICE_ATTR(txqueue, S_IRUGO, show_txqueue, NULL);
  609. + return len;
  610. +}
  611. -static ssize_t show_rxqueue(struct device *d, char *buf)
  612. +static int proc_get_rxqueue(char *page,
  613. + char **start,
  614. + off_t offset,
  615. + int count, int *eof, void *data)
  616. {
  617. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  618. - struct net_device *dev = priv->ndev;
  619. - char * out = buf;
  620. + int len = 0;
  621. u32 rbdr_r, rbdr_w;
  622. + struct net_device *dev = data;
  623. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  624. IPW_DEBUG_INFO("enter\n");
  625. @@ -3751,33 +3853,37 @@ static ssize_t show_rxqueue(struct devic
  626. IPW_DEBUG_INFO("after register read\n");
  627. - out += sprintf(out,
  628. + len += snprintf(page, count,
  629. "Rx Queue\nnic:\n\tread index=%d\n\twrite index=%d\n",
  630. rbdr_r, rbdr_w);
  631. - out += sprintf(out,
  632. + len += snprintf(page + len, count - len,
  633. "drv:\n\tread index=NOT USED\n\twrite index=%d\n",
  634. priv->rx_queue.next);
  635. + *eof = 1;
  636. +
  637. IPW_DEBUG_INFO("exit\n");
  638. - return out - buf;
  639. +
  640. + return len;
  641. }
  642. -static DEVICE_ATTR(rxqueue, S_IRUGO, show_rxqueue, NULL);
  643. -#ifdef CONFIG_IPW_DEBUG
  644. -static ssize_t show_debug_level(struct device_driver *d, char *buf)
  645. +static int proc_get_debug_level(char *page, char **start, off_t offset,
  646. + int count, int *eof, void *data)
  647. {
  648. - char * out = buf;
  649. + int len = 0;
  650. int i;
  651. if (!IPW_DEBUG_ENABLED)
  652. return 0;
  653. - out += sprintf(out, "%-25s\tHex SET Decimal\n", "Description");
  654. + len += snprintf(page + len, count - len,
  655. + "%-25s\tHex SET Decimal\n",
  656. + "Description");
  657. for (i = 0; i < sizeof(ipw2100_debug_levels) /
  658. sizeof(struct ipw2100_dl); i++) {
  659. - out += sprintf(
  660. - out, "%-25s\t0x%08lX [%c] %lu\n",
  661. + len += snprintf(
  662. + page + len, count - len, "%-25s\t0x%08lX [%c] %lu\n",
  663. ipw2100_debug_levels[i].name,
  664. ipw2100_debug_levels[i].value,
  665. (ipw2100_debug_level & ipw2100_debug_levels[i].value) ?
  666. @@ -3785,14 +3891,16 @@ static ssize_t show_debug_level(struct d
  667. ipw2100_debug_levels[i].value);
  668. }
  669. - out += sprintf(out, "debug_level = 0x%08lX (* = enabled)\n",
  670. + len += snprintf(page + len, count - len,
  671. + "debug_level = 0x%08lX (* = enabled)\n",
  672. ipw2100_debug_level);
  673. - return out - buf;
  674. + *eof = 1;
  675. + return len;
  676. }
  677. -static ssize_t store_debug_level(struct device_driver *d, const char *buf,
  678. - size_t count)
  679. +static int proc_set_debug_level(struct file *file, const char *buf,
  680. + unsigned long count, void *data)
  681. {
  682. char buffer[] = "0x00000000";
  683. unsigned long len =
  684. @@ -3804,7 +3912,10 @@ static ssize_t store_debug_level(struct
  685. if (!IPW_DEBUG_ENABLED)
  686. return 0;
  687. - strncpy(buffer, buf, len);
  688. + if (copy_from_user(buffer, buf, len)) {
  689. + IPW_DEBUG_INFO("can't copy data from userspace\n");
  690. + return count;
  691. + } else
  692. buffer[len] = 0;
  693. if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
  694. @@ -3835,25 +3946,25 @@ static ssize_t store_debug_level(struct
  695. }
  696. }
  697. - return len;
  698. + return count;
  699. }
  700. -static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
  701. - store_debug_level);
  702. -#endif /* CONFIG_IPW_DEBUG */
  703. -static ssize_t show_fatal_error(struct device *d, char *buf)
  704. +static int proc_get_fatal_error(char *page, char **start, off_t offset,
  705. + int count, int *eof, void *data)
  706. {
  707. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  708. - char * out = buf;
  709. - int errors = 0;
  710. + struct net_device *dev = data;
  711. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  712. + int len = 0;
  713. int i;
  714. + int errors = 0;
  715. if (priv->fatal_error)
  716. - out += sprintf(out, "Current error: 0x%08X\n",
  717. - priv->fatal_error);
  718. + len += snprintf(page + len, count - len,
  719. + "Current error: 0x%08X\n", priv->fatal_error);
  720. else
  721. - out += sprintf(out, "No current error condition.\n");
  722. + len += snprintf(page + len, count - len,
  723. + "No current error condition.\n");
  724. for (i = 1; i <= IPW2100_ERROR_QUEUE; i++) {
  725. if (!priv->fatal_errors[(priv->fatal_index - i) %
  726. @@ -3861,59 +3972,70 @@ static ssize_t show_fatal_error(struct d
  727. continue;
  728. if (!errors)
  729. - out += sprintf(out, "Up to last %d errors:\n",
  730. + len += snprintf(page + len, count - len,
  731. + "Up to last %d errors:\n",
  732. IPW2100_ERROR_QUEUE);
  733. - out += sprintf(out, "%d. Error: 0x%08X\n", i,
  734. + len += snprintf(page + len, count - len,
  735. + "%d. Error: 0x%08X\n", i,
  736. priv->fatal_errors[(priv->fatal_index - i) %
  737. IPW2100_ERROR_QUEUE]);
  738. errors++;
  739. }
  740. if (!errors)
  741. - out += sprintf(out, "No errors encountered.\n");
  742. + len += snprintf(page + len, count - len,
  743. + "No errors encountered.\n");
  744. #ifdef CONFIG_IPW_DEBUG
  745. - out += sprintf(out, "Packet mismatch image: %s\n",
  746. + len += snprintf(page + len, count - len,
  747. + "Packet mismatch image: %s\n",
  748. priv->snapshot[0] ? "YES" : "NO");
  749. #endif
  750. if (priv->fatal_error)
  751. - out += sprintf(out,
  752. + len += snprintf(page + len, count - len,
  753. "`echo 0 > fatal_error` to force firmware "
  754. - "restart and clear current error condition.\n");
  755. + "restart and clear current error "
  756. + "condition.\n");
  757. - return out - buf;
  758. + *eof = 1;
  759. + return len;
  760. }
  761. -static ssize_t store_fatal_error(struct device *d, const char *buf,
  762. - size_t count)
  763. +static int proc_set_fatal_error(struct file *file, const char *buffer,
  764. + unsigned long count, void *data)
  765. {
  766. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  767. + struct net_device *dev = data;
  768. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  769. schedule_reset(priv);
  770. return count;
  771. }
  772. -static DEVICE_ATTR(fatal_error, S_IWUSR|S_IRUGO, show_fatal_error, store_fatal_error);
  773. -
  774. -static ssize_t show_cardmem(struct device *d, char *buf)
  775. +static int proc_get_cardmem(char *page,
  776. + char **start,
  777. + off_t offset,
  778. + int count, int *eof, void *data)
  779. {
  780. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  781. - struct net_device *dev = priv->ndev;
  782. - char * out = buf;
  783. - u32 dword;
  784. + int len = 0;
  785. + struct net_device *dev = data;
  786. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  787. + u32 d;
  788. - read_nic_dword(dev, priv->proc_cardmemaddr, &dword);
  789. + read_nic_dword(dev, priv->proc_cardmemaddr, &d);
  790. - out += sprintf(out, "cardmem addr[0x%08x] = 0x%08x (%d)\n",
  791. - priv->proc_cardmemaddr, dword, dword);
  792. + len += snprintf(page, count,
  793. + "cardmem addr[0x%08x] = 0x%08x (%d)\n",
  794. + priv->proc_cardmemaddr, d, d);
  795. - return out - buf;
  796. + *eof = 1;
  797. + return len;
  798. }
  799. -static ssize_t store_cardmem(struct device *d, const char *buf, size_t count)
  800. +static int proc_set_cardmemaddr(struct file *file, const char *buf,
  801. + unsigned long count, void *data)
  802. {
  803. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  804. - struct net_device *dev = priv->ndev;
  805. + struct net_device *dev = data;
  806. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  807. char buffer[] = "00000000";
  808. unsigned long len =
  809. (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
  810. @@ -3922,7 +4044,11 @@ static ssize_t store_cardmem(struct devi
  811. IPW_DEBUG_INFO("enter\n");
  812. - strncpy(buffer, buf, len);
  813. + if (copy_from_user(buffer, buf, len)) {
  814. + IPW_DEBUG_INFO("can't copy data from userspace\n");
  815. + /* stupid? yes, but how do I signal an error here? */
  816. + return count;
  817. + } else
  818. buffer[len] = 0;
  819. if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
  820. @@ -3942,24 +4068,32 @@ static ssize_t store_cardmem(struct devi
  821. }
  822. IPW_DEBUG_INFO("exit\n");
  823. - return len;
  824. + return count;
  825. }
  826. -static DEVICE_ATTR(cardmem, S_IWUSR | S_IRUGO, show_cardmem, store_cardmem);
  827. -
  828. -static ssize_t show_scan_age(struct device *d, char *buf)
  829. +static int proc_get_scan_age(char *page,
  830. + char **start,
  831. + off_t offset,
  832. + int count, int *eof, void *data)
  833. {
  834. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  835. + int len = 0;
  836. + struct net_device *dev = (struct net_device *) data;
  837. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  838. - return sprintf(buf, "Scan entries will expire after %u missed scans. "
  839. + len += snprintf(page, count,
  840. + "Scan entries will expire after %u missed scans. "
  841. "(default is %u, 0 = never expire)\n",
  842. priv->ieee->scan_age, DEFAULT_MAX_SCAN_AGE);
  843. +
  844. + *eof = 1;
  845. + return len;
  846. }
  847. -static ssize_t store_scan_age(struct device *d, const char *buf, size_t count)
  848. +static int proc_set_scan_age(struct file *file, const char *buf,
  849. + unsigned long count, void *data)
  850. {
  851. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  852. - struct net_device *dev = priv->ndev;
  853. + struct net_device *dev = (struct net_device *) data;
  854. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  855. char buffer[] = "00000000";
  856. unsigned long len =
  857. (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
  858. @@ -3968,7 +4102,11 @@ static ssize_t store_scan_age(struct dev
  859. IPW_DEBUG_INFO("enter\n");
  860. - strncpy(buffer, buf, len);
  861. + if (copy_from_user(buffer, buf, len)) {
  862. + IPW_DEBUG_INFO("can't copy data from userspace\n");
  863. + /* stupid? yes, but how do I signal an error here? */
  864. + return count;
  865. + } else
  866. buffer[len] = 0;
  867. if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
  868. @@ -3987,37 +4125,24 @@ static ssize_t store_scan_age(struct dev
  869. }
  870. IPW_DEBUG_INFO("exit\n");
  871. - return len;
  872. -}
  873. -static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
  874. -
  875. -
  876. -static ssize_t show_rf_kill(struct device *d, char *buf)
  877. -{
  878. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  879. - char * out = buf;
  880. -
  881. - if (priv->manual_disable)
  882. - out += sprintf(out, "Radio disabled by manual switch.\n");
  883. - else if (priv->hw_features & HW_FEATURE_RFKILL)
  884. - out += sprintf(out, "Radio is %s by RF switch\n",
  885. - ipw2100_get_rf_switch(priv) ?
  886. - "disabled" : "enabled");
  887. - else
  888. - out += sprintf(out,
  889. - "Your hardware does not have an RF switch\n");
  890. -
  891. - return out - buf;
  892. + return count;
  893. }
  894. -static ssize_t store_rf_kill(struct device *d, const char *buf, size_t count)
  895. +static int proc_set_state(struct file *file, const char *buf,
  896. + unsigned long count, void *data)
  897. {
  898. - struct ipw2100_priv *priv = dev_get_drvdata(d);
  899. - int state;
  900. + struct net_device *dev = (struct net_device *) data;
  901. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  902. + char state;
  903. IPW_DEBUG_INFO("enter\n");
  904. - sscanf(buf, "%d", &state);
  905. + if (copy_from_user(&state, buf, 1)) {
  906. + IPW_DEBUG_INFO("can't copy data from userspace\n");
  907. + /* stupid? yes, but how do I signal an error here? */
  908. + return count;
  909. + }
  910. +
  911. switch (state) {
  912. case 0: /* Turn off Manual Disable */
  913. if (priv->manual_disable) {
  914. @@ -4052,31 +4177,323 @@ static ssize_t store_rf_kill(struct devi
  915. IPW_DEBUG_INFO("exit\n");
  916. return count;
  917. }
  918. -static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill);
  919. +static int proc_get_state(char *page,
  920. + char **start,
  921. + off_t offset,
  922. + int count, int *eof, void *data)
  923. +{
  924. + int len = 0;
  925. + struct net_device *dev = data;
  926. + struct ipw2100_priv *priv = ipw2100_netdev(dev);
  927. -static struct attribute *ipw2100_sysfs_entries[] = {
  928. - &dev_attr_hardware.attr,
  929. - &dev_attr_registers.attr,
  930. - &dev_attr_ordinals.attr,
  931. - &dev_attr_pci.attr,
  932. - &dev_attr_version.attr,
  933. - &dev_attr_stats.attr,
  934. - &dev_attr_internals.attr,
  935. - &dev_attr_txqueue.attr,
  936. - &dev_attr_rxqueue.attr,
  937. - &dev_attr_bssinfo.attr,
  938. - &dev_attr_memory.attr,
  939. - &dev_attr_cardmem.attr,
  940. - &dev_attr_scan_age.attr,
  941. - &dev_attr_fatal_error.attr,
  942. - &dev_attr_rf_kill.attr,
  943. - NULL,
  944. -};
  945. + if (priv->manual_disable)
  946. + len += snprintf(page, count,
  947. + "Radio disabled by manual switch.\n");
  948. + else if (priv->hw_features & HW_FEATURE_RFKILL)
  949. + len += snprintf(page, count, "Radio is %s by RF switch\n",
  950. + ipw2100_get_rf_switch(priv) ?
  951. + "disabled" : "enabled");
  952. + else
  953. + len += snprintf(page, count,
  954. + "Your hardware does not have an RF switch\n");
  955. -static struct attribute_group ipw2100_attribute_group = {
  956. - .attrs = ipw2100_sysfs_entries,
  957. -};
  958. + *eof = 1;
  959. + return len;
  960. +}
  961. +
  962. +
  963. +int ipw2100_proc_dev_init(struct ipw2100_priv *priv)
  964. +{
  965. + struct proc_dir_entry *e;
  966. +
  967. + IPW_DEBUG_INFO("enter %s\n", priv->ndev->name);
  968. +
  969. + priv->dir_dev = create_proc_entry(priv->ndev->name,
  970. + S_IFDIR | S_IRUGO | S_IXUGO,
  971. + ipw2100_proc);
  972. + if (!priv->dir_dev) {
  973. + printk(KERN_ERR
  974. + "Unable to initialize /proc/net/ipw2100/%s\n",
  975. + priv->ndev->name);
  976. + goto fail;
  977. + }
  978. +
  979. + e = create_proc_read_entry("hw", S_IFREG | S_IRUGO,
  980. + priv->dir_dev, proc_get_hw, priv->ndev);
  981. + if (!e) {
  982. + printk(KERN_ERR
  983. + "Unable to initialize "
  984. + "/proc/net/ipw2100/%s/hw\n",
  985. + priv->ndev->name);
  986. + goto fail;
  987. + }
  988. +
  989. + e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
  990. + priv->dir_dev, proc_get_registers, priv->ndev);
  991. + if (!e) {
  992. + printk(KERN_ERR
  993. + "Unable to initialize "
  994. + "/proc/net/ipw2100/%s/registers\n",
  995. + priv->ndev->name);
  996. + goto fail;
  997. + }
  998. +
  999. + e = create_proc_read_entry("ordinals", S_IFREG | S_IRUGO,
  1000. + priv->dir_dev, proc_get_ordinals, priv->ndev);
  1001. + if (!e) {
  1002. + printk(KERN_ERR
  1003. + "Unable to initialize "
  1004. + "/proc/net/ipw2100/%s/ordinals\n",
  1005. + priv->ndev->name);
  1006. + goto fail;
  1007. + }
  1008. +
  1009. + e = create_proc_read_entry("pci", S_IFREG | S_IRUGO,
  1010. + priv->dir_dev, proc_get_pci, priv->ndev);
  1011. + if (!e) {
  1012. + printk(KERN_ERR
  1013. + "Unable to initialize "
  1014. + "/proc/net/ipw2100/%s/pci\n",
  1015. + priv->ndev->name);
  1016. + goto fail;
  1017. + }
  1018. +
  1019. + e = create_proc_read_entry("version", S_IFREG | S_IRUGO,
  1020. + priv->dir_dev, proc_get_version, priv->ndev);
  1021. + if (!e) {
  1022. + printk(KERN_ERR
  1023. + "Unable to initialize "
  1024. + "/proc/net/ipw2100/%s/version\n",
  1025. + priv->ndev->name);
  1026. + goto fail;
  1027. + }
  1028. +
  1029. + e = create_proc_read_entry("stats", S_IFREG | S_IRUGO,
  1030. + priv->dir_dev, proc_get_stats, priv->ndev);
  1031. + if (!e) {
  1032. + printk(KERN_ERR
  1033. + "Unable to initialize "
  1034. + "/proc/net/ipw2100/%s/stats\n",
  1035. + priv->ndev->name);
  1036. + goto fail;
  1037. + }
  1038. +
  1039. + e = create_proc_read_entry("internals", S_IFREG | S_IRUGO,
  1040. + priv->dir_dev, proc_get_internals, priv->ndev);
  1041. + if (!e) {
  1042. + printk(KERN_ERR
  1043. + "Unable to initialize "
  1044. + "/proc/net/ipw2100/%s/internals\n",
  1045. + priv->ndev->name);
  1046. + goto fail;
  1047. + }
  1048. +
  1049. + e = create_proc_read_entry("txqueue", S_IFREG | S_IRUGO,
  1050. + priv->dir_dev, proc_get_txqueue, priv->ndev);
  1051. + if (!e) {
  1052. + printk(KERN_ERR
  1053. + "Unable to initialize "
  1054. + "/proc/net/ipw2100/%s/txqueue\n",
  1055. + priv->ndev->name);
  1056. + goto fail;
  1057. + }
  1058. +
  1059. + e = create_proc_read_entry("rxqueue", S_IFREG | S_IRUGO,
  1060. + priv->dir_dev, proc_get_rxqueue, priv->ndev);
  1061. + if (!e) {
  1062. + printk(KERN_ERR
  1063. + "Unable to initialize "
  1064. + "/proc/net/ipw2100/%s/rxqueue\n",
  1065. + priv->ndev->name);
  1066. + goto fail;
  1067. + }
  1068. +
  1069. + e = create_proc_read_entry("bssinfo", S_IFREG | S_IRUGO,
  1070. + priv->dir_dev, proc_get_bssinfo, priv->ndev);
  1071. + if (!e) {
  1072. + printk(KERN_ERR
  1073. + "Unable to initialize "
  1074. + "/proc/net/ipw2100/%s/bssinfo\n",
  1075. + priv->ndev->name);
  1076. + goto fail;
  1077. + }
  1078. +
  1079. + e = create_proc_entry("memory", S_IFREG | S_IRUGO | S_IWUSR,
  1080. + priv->dir_dev);
  1081. + if (e) {
  1082. + e->read_proc = proc_get_memory;
  1083. + e->write_proc = proc_set_memory;
  1084. + e->data = priv->ndev;
  1085. + } else {
  1086. + printk(KERN_ERR
  1087. + "Unable to initialize "
  1088. + "/proc/net/ipw2100/%s/memory\n",
  1089. + priv->ndev->name);
  1090. + goto fail;
  1091. + }
  1092. +
  1093. + e = create_proc_entry("cardmem", S_IFREG | S_IRUGO | S_IWUSR,
  1094. + priv->dir_dev);
  1095. + if (e) {
  1096. + e->read_proc = proc_get_cardmem;
  1097. + e->write_proc = proc_set_cardmemaddr;
  1098. + e->data = priv->ndev;
  1099. + } else {
  1100. + printk(KERN_ERR
  1101. + "Unable to initialize "
  1102. + "/proc/net/ipw2100/%s/cardmem\n",
  1103. + priv->ndev->name);
  1104. + goto fail;
  1105. + }
  1106. +
  1107. + e = create_proc_entry("scan_age", S_IFREG | S_IRUGO | S_IWUSR,
  1108. + priv->dir_dev);
  1109. + if (e) {
  1110. + e->read_proc = proc_get_scan_age;
  1111. + e->write_proc = proc_set_scan_age;
  1112. + e->data = priv->ndev;
  1113. + } else {
  1114. + printk(KERN_ERR
  1115. + "Unable to initialize "
  1116. + "/proc/net/ipw2100/%s/scan_age\n",
  1117. + priv->ndev->name);
  1118. + goto fail;
  1119. + }
  1120. +
  1121. + e = create_proc_entry("fatal_error", S_IFREG | S_IRUGO | S_IWUSR,
  1122. + priv->dir_dev);
  1123. + if (e) {
  1124. + e->read_proc = proc_get_fatal_error;
  1125. + e->write_proc = proc_set_fatal_error;
  1126. + e->data = priv->ndev;
  1127. + } else {
  1128. + printk(KERN_ERR
  1129. + "Unable to initialize "
  1130. + "/proc/net/ipw2100/%s/fatal_error\n",
  1131. + priv->ndev->name);
  1132. + goto fail;
  1133. + }
  1134. +
  1135. + e = create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR,
  1136. + priv->dir_dev);
  1137. + if (e) {
  1138. + e->read_proc = proc_get_state;
  1139. + e->write_proc = proc_set_state;
  1140. + e->data = priv->ndev;
  1141. + } else {
  1142. + printk(KERN_ERR
  1143. + "Unable to initialize "
  1144. + "/proc/net/ipw2100/%s/state\n",
  1145. + priv->ndev->name);
  1146. + goto fail;
  1147. + }
  1148. +
  1149. + IPW_DEBUG_INFO("exit %s\n", priv->ndev->name);
  1150. +
  1151. + return 0;
  1152. +
  1153. + fail:
  1154. + ipw2100_proc_dev_cleanup(priv);
  1155. + IPW_DEBUG_INFO("exit on fail %s\n", priv->ndev->name);
  1156. +
  1157. + return -ENOMEM;
  1158. +}
  1159. +
  1160. +void ipw2100_proc_dev_cleanup(struct ipw2100_priv *priv)
  1161. +{
  1162. + IPW_DEBUG_INFO("enter %s\n", priv->ndev->name);
  1163. +
  1164. + if (priv->dir_dev) {
  1165. + remove_proc_entry("stats", priv->dir_dev);
  1166. + remove_proc_entry("internals", priv->dir_dev);
  1167. + remove_proc_entry("txqueue", priv->dir_dev);
  1168. + remove_proc_entry("rxqueue", priv->dir_dev);
  1169. + remove_proc_entry("cardmem", priv->dir_dev);
  1170. + remove_proc_entry("scan_age", priv->dir_dev);
  1171. + remove_proc_entry("bssinfo", priv->dir_dev);
  1172. + remove_proc_entry("state", priv->dir_dev);
  1173. + remove_proc_entry("version", priv->dir_dev);
  1174. + remove_proc_entry("hw", priv->dir_dev);
  1175. + remove_proc_entry("registers", priv->dir_dev);
  1176. + remove_proc_entry("memory", priv->dir_dev);
  1177. + remove_proc_entry("ordinals", priv->dir_dev);
  1178. + remove_proc_entry("pci", priv->dir_dev);
  1179. + remove_proc_entry("fatal_error", priv->dir_dev);
  1180. + remove_proc_entry(priv->ndev->name, ipw2100_proc);
  1181. + priv->dir_dev = NULL;
  1182. + }
  1183. +
  1184. + IPW_DEBUG_INFO("exit %s\n", priv->ndev->name);
  1185. +}
  1186. +
  1187. +
  1188. +/**
  1189. + * Initialize ipw2100 proc filesystem's entry.
  1190. + *
  1191. + * @returns 0 if ok, < 0 errno code on error [-ENOMEM].
  1192. + *
  1193. + * On error, it takes care of cleaning up as if nothing had been
  1194. + * done.
  1195. + */
  1196. +static
  1197. +int ipw2100_proc_init(void)
  1198. +{
  1199. + struct proc_dir_entry *e;
  1200. +
  1201. + IPW_DEBUG_INFO("enter\n");
  1202. +
  1203. + ipw2100_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
  1204. + if (ipw2100_proc == NULL)
  1205. + goto fail_ipw2100;
  1206. +
  1207. + /* Next we create only if we compiled in debug support */
  1208. + if (!IPW_DEBUG_ENABLED)
  1209. + goto skip_debug;
  1210. +
  1211. + e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
  1212. + ipw2100_proc);
  1213. + if (e == NULL)
  1214. + goto fail_debug;
  1215. + e->read_proc = proc_get_debug_level;
  1216. + e->write_proc = proc_set_debug_level;
  1217. + e->data = NULL;
  1218. +
  1219. +skip_debug:
  1220. + IPW_DEBUG_INFO("exit\n");
  1221. + return 0;
  1222. +
  1223. +fail_debug:
  1224. + printk(KERN_ERR DRV_NAME ": Unable to initialize "
  1225. + "/proc/net/" DRV_NAME "/debug_level\n");
  1226. + remove_proc_entry(DRV_NAME, proc_net);
  1227. + ipw2100_proc = NULL;
  1228. + goto fail;
  1229. +
  1230. +fail_ipw2100:
  1231. + printk(KERN_ERR DRV_NAME ": Unable to initialize /proc/net/"
  1232. + DRV_NAME "\n");
  1233. +
  1234. +fail:
  1235. + IPW_DEBUG_INFO("exit on fail\n");
  1236. + return -ENOMEM;
  1237. +}
  1238. +
  1239. +
  1240. +/**
  1241. + * Releases /proc filesystem entries.
  1242. + *
  1243. + * Assumes all went ok when allocating them.
  1244. + */
  1245. +static void ipw2100_proc_cleanup(void)
  1246. +{
  1247. + IPW_DEBUG_INFO("enter\n");
  1248. +
  1249. + if (IPW_DEBUG_ENABLED && ipw2100_proc)
  1250. + remove_proc_entry("debug_level", ipw2100_proc);
  1251. + remove_proc_entry(DRV_NAME, proc_net);
  1252. + IPW_DEBUG_INFO("exit\n");
  1253. +}
  1254. static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
  1255. @@ -6647,8 +7064,17 @@ static int ipw2100_pci_init_one(struct p
  1256. printk(KERN_INFO "%s: Bound to %s\n", dev->name, pci_name(pdev));
  1257. - /* perform this after register_netdev so that dev->name is set */
  1258. - sysfs_create_group(&pdev->dev.kobj, &ipw2100_attribute_group);
  1259. + /* perform this after register_netdev so that dev->name is
  1260. + * set */
  1261. + err = ipw2100_proc_dev_init(priv);
  1262. + if (err) {
  1263. + printk(KERN_ERR
  1264. + "%s: Failed to create /proc node\n",
  1265. + dev->name);
  1266. + err = -EIO;
  1267. + goto fail;
  1268. + }
  1269. +
  1270. netif_carrier_off(dev);
  1271. /* If the RF Kill switch is disabled, go ahead and complete the
  1272. @@ -6698,7 +7124,7 @@ static int ipw2100_pci_init_one(struct p
  1273. /* These are safe to call even if they weren't allocated */
  1274. ipw2100_queues_free(priv);
  1275. - sysfs_remove_group(&pdev->dev.kobj, &ipw2100_attribute_group);
  1276. + ipw2100_proc_dev_cleanup(priv);
  1277. free_netdev(dev);
  1278. pci_set_drvdata(pdev, NULL);
  1279. @@ -6720,7 +7146,7 @@ static void __devexit ipw2100_pci_remove
  1280. if (priv) {
  1281. dev = priv->ndev;
  1282. - sysfs_remove_group(&pdev->dev.kobj, &ipw2100_attribute_group);
  1283. + ipw2100_proc_dev_cleanup(priv);
  1284. #ifdef CONFIG_PM
  1285. if (ipw2100_firmware.version)
  1286. @@ -6912,17 +7338,16 @@ static int __init ipw2100_init(void)
  1287. printk(KERN_INFO DRV_NAME ": Compiled with LEGACY FW load.\n");
  1288. #endif
  1289. - ret = pci_module_init(&ipw2100_pci_driver);
  1290. -
  1291. /* If debug module parameter declared, set debug_level to that */
  1292. if (debug != -1)
  1293. ipw2100_debug_level = debug;
  1294. -#ifdef CONFIG_IPW_DEBUG
  1295. - driver_create_file(&ipw2100_pci_driver.driver,
  1296. - &driver_attr_debug_level);
  1297. -#endif
  1298. -
  1299. + ret = ipw2100_proc_init();
  1300. + if (!ret) {
  1301. + ret = pci_module_init(&ipw2100_pci_driver);
  1302. + if (ret)
  1303. + ipw2100_proc_cleanup();
  1304. + }
  1305. return ret;
  1306. }
  1307. @@ -6933,11 +7358,8 @@ static int __init ipw2100_init(void)
  1308. static void __exit ipw2100_exit(void)
  1309. {
  1310. /* FIXME: IPG: check that we have no instances of the devices open */
  1311. -#ifdef CONFIG_IPW_DEBUG
  1312. - driver_remove_file(&ipw2100_pci_driver.driver,
  1313. - &driver_attr_debug_level);
  1314. -#endif
  1315. pci_unregister_driver(&ipw2100_pci_driver);
  1316. + ipw2100_proc_cleanup();
  1317. }
  1318. module_init(ipw2100_init);