com90xx.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:18k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Linux ARCnet driver - COM90xx chipset (memory-mapped buffers)
  3.  * 
  4.  * Written 1994-1999 by Avery Pennarun.
  5.  * Written 1999 by Martin Mares <mj@ucw.cz>.
  6.  * Derived from skeleton.c by Donald Becker.
  7.  *
  8.  * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
  9.  *  for sponsoring the further development of this driver.
  10.  *
  11.  * **********************
  12.  *
  13.  * The original copyright of skeleton.c was as follows:
  14.  *
  15.  * skeleton.c Written 1993 by Donald Becker.
  16.  * Copyright 1993 United States Government as represented by the
  17.  * Director, National Security Agency.  This software may only be used
  18.  * and distributed according to the terms of the GNU General Public License as
  19.  * modified by SRC, incorporated herein by reference.
  20.  *
  21.  * **********************
  22.  *
  23.  * For more details, see drivers/net/arcnet.c
  24.  *
  25.  * **********************
  26.  */
  27. #include <linux/module.h>
  28. #include <linux/init.h>
  29. #include <linux/ioport.h>
  30. #include <linux/delay.h>
  31. #include <linux/netdevice.h>
  32. #include <linux/bootmem.h>
  33. #include <asm/io.h>
  34. #include <linux/arcdevice.h>
  35. #define VERSION "arcnet: COM90xx chipset supportn"
  36. /* Define this to speed up the autoprobe by assuming if only one io port and
  37.  * shmem are left in the list at Stage 5, they must correspond to each
  38.  * other.
  39.  *
  40.  * This is undefined by default because it might not always be true, and the
  41.  * extra check makes the autoprobe even more careful.  Speed demons can turn
  42.  * it on - I think it should be fine if you only have one ARCnet card
  43.  * installed.
  44.  *
  45.  * If no ARCnet cards are installed, this delay never happens anyway and thus
  46.  * the option has no effect.
  47.  */
  48. #undef FAST_PROBE
  49. /* Internal function declarations */
  50. static int com90xx_found(struct net_device *dev, int ioaddr, int airq,
  51.  u_long shmem);
  52. static void com90xx_command(struct net_device *dev, int command);
  53. static int com90xx_status(struct net_device *dev);
  54. static void com90xx_setmask(struct net_device *dev, int mask);
  55. static int com90xx_reset(struct net_device *dev, int really_reset);
  56. static void com90xx_openclose(struct net_device *dev, bool open);
  57. static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
  58.  void *buf, int count);
  59. static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
  60.    void *buf, int count);
  61. /* Known ARCnet cards */
  62. static struct net_device *cards[16];
  63. static int numcards;
  64. /* Handy defines for ARCnet specific stuff */
  65. /* The number of low I/O ports used by the card */
  66. #define ARCNET_TOTAL_SIZE 16
  67. /* Amount of I/O memory used by the card */
  68. #define BUFFER_SIZE (512)
  69. #define MIRROR_SIZE (BUFFER_SIZE*4)
  70. /* COM 9026 controller chip --> ARCnet register addresses */
  71. #define _INTMASK (ioaddr+0) /* writable */
  72. #define _STATUS  (ioaddr+0) /* readable */
  73. #define _COMMAND (ioaddr+1) /* writable, returns random vals on read (?) */
  74. #define _CONFIG  (ioaddr+2) /* Configuration register */
  75. #define _RESET   (ioaddr+8) /* software reset (on read) */
  76. #define _MEMDATA (ioaddr+12) /* Data port for IO-mapped memory */
  77. #define _ADDR_HI (ioaddr+15) /* Control registers for said */
  78. #define _ADDR_LO (ioaddr+14)
  79. #undef ASTATUS
  80. #undef ACOMMAND
  81. #undef AINTMASK
  82. #define ASTATUS() inb(_STATUS)
  83. #define ACOMMAND(cmd)  outb((cmd),_COMMAND)
  84. #define AINTMASK(msk) outb((msk),_INTMASK)
  85. static int com90xx_skip_probe __initdata = 0;
  86. int __init com90xx_probe(struct net_device *dev)
  87. {
  88. int count, status, ioaddr, numprint, airq, retval = -ENODEV,
  89.  openparen = 0;
  90. unsigned long airqmask;
  91. int ports[(0x3f0 - 0x200) / 16 + 1] =
  92. {0};
  93. u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] =
  94. {0};
  95. int numports, numshmems, *port;
  96. u_long *shmem;
  97. if (!dev && com90xx_skip_probe)
  98. return -ENODEV;
  99. #ifndef MODULE
  100. arcnet_init();
  101. #endif
  102. BUGLVL(D_NORMAL) printk(VERSION);
  103. /* set up the arrays where we'll store the possible probe addresses */
  104. numports = numshmems = 0;
  105. if (dev && dev->base_addr)
  106. ports[numports++] = dev->base_addr;
  107. else
  108. for (count = 0x200; count <= 0x3f0; count += 16)
  109. ports[numports++] = count;
  110. if (dev && dev->mem_start)
  111. shmems[numshmems++] = dev->mem_start;
  112. else
  113. for (count = 0xA0000; count <= 0xFF800; count += 2048)
  114. shmems[numshmems++] = count;
  115. /* Stage 1: abandon any reserved ports, or ones with status==0xFF
  116.  * (empty), and reset any others by reading the reset port.
  117.  */
  118. numprint = -1;
  119. for (port = &ports[0]; port - ports < numports; port++) {
  120. numprint++;
  121. numprint %= 8;
  122. if (!numprint) {
  123. BUGMSG2(D_INIT, "n");
  124. BUGMSG2(D_INIT, "S1: ");
  125. }
  126. BUGMSG2(D_INIT, "%Xh ", *port);
  127. ioaddr = *port;
  128. if (check_region(*port, ARCNET_TOTAL_SIZE)) {
  129. BUGMSG2(D_INIT_REASONS, "(check_region)n");
  130. BUGMSG2(D_INIT_REASONS, "S1: ");
  131. BUGLVL(D_INIT_REASONS) numprint = 0;
  132. *port = ports[numports - 1];
  133. numports--;
  134. port--;
  135. continue;
  136. }
  137. if (ASTATUS() == 0xFF) {
  138. BUGMSG2(D_INIT_REASONS, "(empty)n");
  139. BUGMSG2(D_INIT_REASONS, "S1: ");
  140. BUGLVL(D_INIT_REASONS) numprint = 0;
  141. *port = ports[numports - 1];
  142. numports--;
  143. port--;
  144. continue;
  145. }
  146. inb(_RESET); /* begin resetting card */
  147. BUGMSG2(D_INIT_REASONS, "n");
  148. BUGMSG2(D_INIT_REASONS, "S1: ");
  149. BUGLVL(D_INIT_REASONS) numprint = 0;
  150. }
  151. BUGMSG2(D_INIT, "n");
  152. if (!numports) {
  153. BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.n");
  154. return -ENODEV;
  155. }
  156. /* Stage 2: we have now reset any possible ARCnet cards, so we can't
  157.  * do anything until they finish.  If D_INIT, print the list of
  158.  * cards that are left.
  159.  */
  160. numprint = -1;
  161. for (port = &ports[0]; port - ports < numports; port++) {
  162. numprint++;
  163. numprint %= 8;
  164. if (!numprint) {
  165. BUGMSG2(D_INIT, "n");
  166. BUGMSG2(D_INIT, "S2: ");
  167. }
  168. BUGMSG2(D_INIT, "%Xh ", *port);
  169. }
  170. BUGMSG2(D_INIT, "n");
  171. mdelay(RESETtime);
  172. /* Stage 3: abandon any shmem addresses that don't have the signature
  173.  * 0xD1 byte in the right place, or are read-only.
  174.  */
  175. numprint = -1;
  176. for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
  177. u_long ptr = *shmem;
  178. numprint++;
  179. numprint %= 8;
  180. if (!numprint) {
  181. BUGMSG2(D_INIT, "n");
  182. BUGMSG2(D_INIT, "S3: ");
  183. }
  184. BUGMSG2(D_INIT, "%lXh ", *shmem);
  185. if (check_mem_region(*shmem, BUFFER_SIZE)) {
  186. BUGMSG2(D_INIT_REASONS, "(check_mem_region)n");
  187. BUGMSG2(D_INIT_REASONS, "Stage 3: ");
  188. BUGLVL(D_INIT_REASONS) numprint = 0;
  189. *shmem = shmems[numshmems - 1];
  190. numshmems--;
  191. shmem--;
  192. continue;
  193. }
  194. if (isa_readb(ptr) != TESTvalue) {
  195. BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)n",
  196. isa_readb(ptr), TESTvalue);
  197. BUGMSG2(D_INIT_REASONS, "S3: ");
  198. BUGLVL(D_INIT_REASONS) numprint = 0;
  199. *shmem = shmems[numshmems - 1];
  200. numshmems--;
  201. shmem--;
  202. continue;
  203. }
  204. /* By writing 0x42 to the TESTvalue location, we also make
  205.  * sure no "mirror" shmem areas show up - if they occur
  206.  * in another pass through this loop, they will be discarded
  207.  * because *cptr != TESTvalue.
  208.  */
  209. isa_writeb(0x42, ptr);
  210. if (isa_readb(ptr) != 0x42) {
  211. BUGMSG2(D_INIT_REASONS, "(read only)n");
  212. BUGMSG2(D_INIT_REASONS, "S3: ");
  213. *shmem = shmems[numshmems - 1];
  214. numshmems--;
  215. shmem--;
  216. continue;
  217. }
  218. BUGMSG2(D_INIT_REASONS, "n");
  219. BUGMSG2(D_INIT_REASONS, "S3: ");
  220. BUGLVL(D_INIT_REASONS) numprint = 0;
  221. }
  222. BUGMSG2(D_INIT, "n");
  223. if (!numshmems) {
  224. BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.n");
  225. return -ENODEV;
  226. }
  227. /* Stage 4: something of a dummy, to report the shmems that are
  228.  * still possible after stage 3.
  229.  */
  230. numprint = -1;
  231. for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
  232. numprint++;
  233. numprint %= 8;
  234. if (!numprint) {
  235. BUGMSG2(D_INIT, "n");
  236. BUGMSG2(D_INIT, "S4: ");
  237. }
  238. BUGMSG2(D_INIT, "%lXh ", *shmem);
  239. }
  240. BUGMSG2(D_INIT, "n");
  241. /* Stage 5: for any ports that have the correct status, can disable
  242.  * the RESET flag, and (if no irq is given) generate an autoirq,
  243.  * register an ARCnet device.
  244.  *
  245.  * Currently, we can only register one device per probe, so quit
  246.  * after the first one is found.
  247.  */
  248. numprint = -1;
  249. for (port = &ports[0]; port - ports < numports; port++) {
  250. numprint++;
  251. numprint %= 8;
  252. if (!numprint) {
  253. BUGMSG2(D_INIT, "n");
  254. BUGMSG2(D_INIT, "S5: ");
  255. }
  256. BUGMSG2(D_INIT, "%Xh ", *port);
  257. ioaddr = *port;
  258. status = ASTATUS();
  259. if ((status & 0x9D)
  260.     != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
  261. BUGMSG2(D_INIT_REASONS, "(status=%Xh)n", status);
  262. BUGMSG2(D_INIT_REASONS, "S5: ");
  263. BUGLVL(D_INIT_REASONS) numprint = 0;
  264. *port = ports[numports - 1];
  265. numports--;
  266. port--;
  267. continue;
  268. }
  269. ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
  270. status = ASTATUS();
  271. if (status & RESETflag) {
  272. BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)n",
  273. status);
  274. BUGMSG2(D_INIT_REASONS, "S5: ");
  275. BUGLVL(D_INIT_REASONS) numprint = 0;
  276. *port = ports[numports - 1];
  277. numports--;
  278. port--;
  279. continue;
  280. }
  281. /* skip this completely if an IRQ was given, because maybe
  282.  * we're on a machine that locks during autoirq!
  283.  */
  284. if (!dev || !dev->irq) {
  285. /* if we do this, we're sure to get an IRQ since the
  286.  * card has just reset and the NORXflag is on until
  287.  * we tell it to start receiving.
  288.  */
  289. airqmask = probe_irq_on();
  290. AINTMASK(NORXflag);
  291. udelay(1);
  292. AINTMASK(0);
  293. airq = probe_irq_off(airqmask);
  294. if (airq <= 0) {
  295. BUGMSG2(D_INIT_REASONS, "(airq=%d)n", airq);
  296. BUGMSG2(D_INIT_REASONS, "S5: ");
  297. BUGLVL(D_INIT_REASONS) numprint = 0;
  298. *port = ports[numports - 1];
  299. numports--;
  300. port--;
  301. continue;
  302. }
  303. } else {
  304. airq = dev->irq;
  305. }
  306. BUGMSG2(D_INIT, "(%d,", airq);
  307. openparen = 1;
  308. /* Everything seems okay.  But which shmem, if any, puts
  309.  * back its signature byte when the card is reset?
  310.  *
  311.  * If there are multiple cards installed, there might be
  312.  * multiple shmems still in the list.
  313.  */
  314. #ifdef FAST_PROBE
  315. if (numports > 1 || numshmems > 1) {
  316. inb(_RESET);
  317. mdelay(RESETtime);
  318. } else {
  319. /* just one shmem and port, assume they match */
  320. isa_writeb(TESTvalue, shmems[0]);
  321. }
  322. #else
  323. inb(_RESET);
  324. mdelay(RESETtime);
  325. #endif
  326. for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
  327. u_long ptr = *shmem;
  328. if (isa_readb(ptr) == TESTvalue) { /* found one */
  329. BUGMSG2(D_INIT, "%lXh)n", *shmem);
  330. openparen = 0;
  331. /* register the card */
  332. retval = com90xx_found(dev, *port, airq, *shmem);
  333. numprint = -1;
  334. /* remove shmem from the list */
  335. *shmem = shmems[numshmems - 1];
  336. numshmems--;
  337. break; /* go to the next I/O port */
  338. } else {
  339. BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr));
  340. }
  341. }
  342. if (openparen) {
  343. BUGLVL(D_INIT) printk("no matching shmem)n");
  344. BUGLVL(D_INIT_REASONS) printk("S5: ");
  345. BUGLVL(D_INIT_REASONS) numprint = 0;
  346. }
  347. *port = ports[numports - 1];
  348. numports--;
  349. port--;
  350. }
  351. BUGLVL(D_INIT_REASONS) printk("n");
  352. /* Now put back TESTvalue on all leftover shmems. */
  353. for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)
  354. isa_writeb(TESTvalue, *shmem);
  355. if (retval && dev && !numcards)
  356. BUGMSG2(D_NORMAL, "S5: No ARCnet cards found.n");
  357. return retval;
  358. }
  359. /* Set up the struct net_device associated with this card.  Called after
  360.  * probing succeeds.
  361.  */
  362. static int __init com90xx_found(struct net_device *dev0, int ioaddr, int airq,
  363. u_long shmem)
  364. {
  365. struct net_device *dev = dev0;
  366. struct arcnet_local *lp;
  367. u_long first_mirror, last_mirror;
  368. int mirror_size, err;
  369. /* allocate struct net_device if we don't have one yet */
  370. if (!dev && !(dev = dev_alloc("arc%d", &err))) {
  371. BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!n");
  372. return err;
  373. }
  374. lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
  375. if (!lp) {
  376. BUGMSG(D_NORMAL, "Can't allocate device data!n");
  377. goto err_free_dev;
  378. }
  379. /* find the real shared memory start/end points, including mirrors */
  380. /* guess the actual size of one "memory mirror" - the number of
  381.  * bytes between copies of the shared memory.  On most cards, it's
  382.  * 2k (or there are no mirrors at all) but on some, it's 4k.
  383.  */
  384. mirror_size = MIRROR_SIZE;
  385. if (isa_readb(shmem) == TESTvalue
  386.     && isa_readb(shmem - mirror_size) != TESTvalue
  387.     && isa_readb(shmem - 2 * mirror_size) == TESTvalue)
  388. mirror_size *= 2;
  389. first_mirror = last_mirror = shmem;
  390. while (isa_readb(first_mirror) == TESTvalue)
  391. first_mirror -= mirror_size;
  392. first_mirror += mirror_size;
  393. while (isa_readb(last_mirror) == TESTvalue)
  394. last_mirror += mirror_size;
  395. last_mirror -= mirror_size;
  396. dev->mem_start = first_mirror;
  397. dev->mem_end = last_mirror + MIRROR_SIZE - 1;
  398. dev->rmem_start = dev->mem_start + BUFFER_SIZE * 0;
  399. dev->rmem_end = dev->mem_start + BUFFER_SIZE * 2 - 1;
  400. /* Initialize the rest of the device structure. */
  401. memset(lp, 0, sizeof(struct arcnet_local));
  402. lp->card_name = "COM90xx";
  403. lp->hw.command = com90xx_command;
  404. lp->hw.status = com90xx_status;
  405. lp->hw.intmask = com90xx_setmask;
  406. lp->hw.reset = com90xx_reset;
  407. lp->hw.open_close = com90xx_openclose;
  408. lp->hw.copy_to_card = com90xx_copy_to_card;
  409. lp->hw.copy_from_card = com90xx_copy_from_card;
  410. lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
  411. if (!lp->mem_start) {
  412. BUGMSG(D_NORMAL, "Can't remap device memory!n");
  413. goto err_free_dev_priv;
  414. }
  415. /* Fill in the fields of the device structure with generic values. */
  416. arcdev_setup(dev);
  417. /* get and check the station ID from offset 1 in shmem */
  418. dev->dev_addr[0] = readb(lp->mem_start + 1);
  419. /* reserve the irq */
  420. if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
  421. BUGMSG(D_NORMAL, "Can't get IRQ %d!n", airq);
  422. goto err_unmap;
  423. }
  424. dev->irq = airq;
  425. /* reserve the I/O and memory regions - guaranteed to work by check_region */
  426. request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (90xx)");
  427. request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)");
  428. dev->base_addr = ioaddr;
  429. BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, "
  430.        "ShMem %lXh (%ld*%xh).n",
  431.        dev->dev_addr[0],
  432.        dev->base_addr, dev->irq, dev->mem_start,
  433.  (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
  434. if (!dev0 && register_netdev(dev))
  435. goto err_release;
  436. cards[numcards++] = dev;
  437. return 0;
  438.       err_release:
  439. free_irq(dev->irq, dev);
  440. release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
  441. release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
  442.       err_unmap:
  443. iounmap(lp->mem_start);
  444.       err_free_dev_priv:
  445. kfree(dev->priv);
  446.       err_free_dev:
  447. if (!dev0)
  448. kfree(dev);
  449. return -EIO;
  450. }
  451. static void com90xx_command(struct net_device *dev, int cmd)
  452. {
  453. short ioaddr = dev->base_addr;
  454. ACOMMAND(cmd);
  455. }
  456. static int com90xx_status(struct net_device *dev)
  457. {
  458. short ioaddr = dev->base_addr;
  459. return ASTATUS();
  460. }
  461. static void com90xx_setmask(struct net_device *dev, int mask)
  462. {
  463. short ioaddr = dev->base_addr;
  464. AINTMASK(mask);
  465. }
  466. /*
  467.  * Do a hardware reset on the card, and set up necessary registers.
  468.  * 
  469.  * This should be called as little as possible, because it disrupts the
  470.  * token on the network (causes a RECON) and requires a significant delay.
  471.  *
  472.  * However, it does make sure the card is in a defined state.
  473.  */
  474. int com90xx_reset(struct net_device *dev, int really_reset)
  475. {
  476. struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
  477. short ioaddr = dev->base_addr;
  478. BUGMSG(D_INIT, "Resetting (status=%02Xh)n", ASTATUS());
  479. if (really_reset) {
  480. /* reset the card */
  481. inb(_RESET);
  482. mdelay(RESETtime);
  483. }
  484. ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */
  485. ACOMMAND(CFLAGScmd | CONFIGclear);
  486. /* don't do this until we verify that it doesn't hurt older cards! */
  487. /* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */
  488. /* verify that the ARCnet signature byte is present */
  489. if (readb(lp->mem_start) != TESTvalue) {
  490. if (really_reset)
  491. BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.n");
  492. return 1;
  493. }
  494. /* enable extended (512-byte) packets */
  495. ACOMMAND(CONFIGcmd | EXTconf);
  496. /* clean out all the memory to make debugging make more sense :) */
  497. BUGLVL(D_DURING)
  498.     memset_io(lp->mem_start, 0x42, 2048);
  499. /* done!  return success. */
  500. return 0;
  501. }
  502. static void com90xx_openclose(struct net_device *dev, bool open)
  503. {
  504. if (open)
  505. MOD_INC_USE_COUNT;
  506. else
  507. MOD_DEC_USE_COUNT;
  508. }
  509. static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
  510.  void *buf, int count)
  511. {
  512. struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
  513. void *memaddr = lp->mem_start + bufnum * 512 + offset;
  514. TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
  515. }
  516. static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
  517.    void *buf, int count)
  518. {
  519. struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
  520. void *memaddr = lp->mem_start + bufnum * 512 + offset;
  521. TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
  522. }
  523. #ifdef MODULE
  524. /* Module parameters */
  525. static int io; /* use the insmod io= irq= shmem= options */
  526. static int irq;
  527. static int shmem;
  528. static char *device; /* use eg. device=arc1 to change name */
  529. MODULE_PARM(io, "i");
  530. MODULE_PARM(irq, "i");
  531. MODULE_PARM(shmem, "i");
  532. MODULE_PARM(device, "s");
  533. int init_module(void)
  534. {
  535. struct net_device *dev;
  536. int err;
  537. if (io || irq || shmem || device) {
  538. dev = dev_alloc(device ? : "arc%d", &err);
  539. if (!dev)
  540. return err;
  541. dev->base_addr = io;
  542. dev->irq = irq;
  543. if (dev->irq == 2)
  544. dev->irq = 9;
  545. dev->mem_start = shmem;
  546. com90xx_probe(dev);
  547. } else
  548. com90xx_probe(NULL);
  549. if (!numcards)
  550. return -EIO;
  551. return 0;
  552. }
  553. void cleanup_module(void)
  554. {
  555. struct net_device *dev;
  556. struct arcnet_local *lp;
  557. int count;
  558. for (count = 0; count < numcards; count++) {
  559. dev = cards[count];
  560. lp = (struct arcnet_local *) dev->priv;
  561. unregister_netdev(dev);
  562. free_irq(dev->irq, dev);
  563. iounmap(lp->mem_start);
  564. release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
  565. release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
  566. kfree(dev->priv);
  567. kfree(dev);
  568. }
  569. }
  570. #else
  571. static int __init com90xx_setup(char *s)
  572. {
  573. struct net_device *dev;
  574. int ints[8];
  575. com90xx_skip_probe = 1;
  576. s = get_options(s, 8, ints);
  577. if (!ints[0] && !*s) {
  578. printk("com90xx: Disabled.n");
  579. return 1;
  580. }
  581. dev = alloc_bootmem(sizeof(struct net_device));
  582. memset(dev, 0, sizeof(struct net_device));
  583. dev->init = com90xx_probe;
  584. switch (ints[0]) {
  585. default: /* ERROR */
  586. printk("com90xx: Too many arguments.n");
  587. case 3: /* Mem address */
  588. dev->mem_start = ints[3];
  589. case 2: /* IRQ */
  590. dev->irq = ints[2];
  591. case 1: /* IO address */
  592. dev->base_addr = ints[1];
  593. }
  594. if (*s)
  595. strncpy(dev->name, s, 9);
  596. else
  597. strcpy(dev->name, "arc%d");
  598. if (register_netdev(dev))
  599. printk(KERN_ERR "com90xx: Cannot register arcnet devicen");
  600. return 1;
  601. }
  602. __setup("com90xx=", com90xx_setup);
  603. #endif /* MODULE */