OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [smc-ultra.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* smc-ultra.c: A SMC Ultra ethernet driver for linux. */
2
/*
3
        This is a driver for the SMC Ultra and SMC EtherEZ ISA ethercards.
4
 
5
        Written 1993-1998 by Donald Becker.
6
 
7
        Copyright 1993 United States Government as represented by the
8
        Director, National Security Agency.
9
 
10
        This software may be used and distributed according to the terms
11
        of the GNU General Public License, incorporated herein by reference.
12
 
13
        The author may be reached as becker@scyld.com, or C/O
14
        Scyld Computing Corporation
15
        410 Severn Ave., Suite 210
16
        Annapolis MD 21403
17
 
18
        This driver uses the cards in the 8390-compatible mode.
19
        Most of the run-time complexity is handled by the generic code in
20
        8390.c.  The code in this file is responsible for
21
 
22
                ultra_probe()           Detecting and initializing the card.
23
                ultra_probe1()
24
                ultra_probe_isapnp()
25
 
26
                ultra_open()            The card-specific details of starting, stopping
27
                ultra_reset_8390()      and resetting the 8390 NIC core.
28
                ultra_close()
29
 
30
                ultra_block_input()             Routines for reading and writing blocks of
31
                ultra_block_output()    packet buffer memory.
32
                ultra_pio_input()
33
                ultra_pio_output()
34
 
35
        This driver enables the shared memory only when doing the actual data
36
        transfers to avoid a bug in early version of the card that corrupted
37
        data transferred by a AHA1542.
38
 
39
        This driver now supports the programmed-I/O (PIO) data transfer mode of
40
        the EtherEZ. It does not use the non-8390-compatible "Altego" mode.
41
        That support (if available) is in smc-ez.c.
42
 
43
        Changelog:
44
 
45
        Paul Gortmaker  : multiple card support for module users.
46
        Donald Becker   : 4/17/96 PIO support, minor potential problems avoided.
47
        Donald Becker   : 6/6/96 correctly set auto-wrap bit.
48
        Alexander Sotirov : 1/20/01 Added support for ISAPnP cards
49
 
50
        Note about the ISA PnP support:
51
 
52
        This driver can not autoprobe for more than one SMC EtherEZ PnP card.
53
        You have to configure the second card manually through the /proc/isapnp
54
        interface and then load the module with an explicit io=0x___ option.
55
*/
56
 
57
static const char version[] =
58
        "smc-ultra.c:v2.02 2/3/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
59
 
60
#include <linux/module.h>
61
#include <linux/kernel.h>
62
#include <linux/errno.h>
63
#include <linux/string.h>
64
#include <linux/init.h>
65
#include <linux/isapnp.h>
66
#include <linux/netdevice.h>
67
#include <linux/etherdevice.h>
68
 
69
#include <asm/io.h>
70
#include <asm/irq.h>
71
#include <asm/system.h>
72
 
73
#include "8390.h"
74
 
75
#define DRV_NAME "smc-ultra"
76
 
77
/* A zero-terminated list of I/O addresses to be probed. */
78
static unsigned int ultra_portlist[] __initdata =
79
{0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0};
80
 
81
static int ultra_probe1(struct net_device *dev, int ioaddr);
82
 
83
#ifdef __ISAPNP__
84
static int ultra_probe_isapnp(struct net_device *dev);
85
#endif
86
 
87
static int ultra_open(struct net_device *dev);
88
static void ultra_reset_8390(struct net_device *dev);
89
static void ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
90
                                                int ring_page);
91
static void ultra_block_input(struct net_device *dev, int count,
92
                                                  struct sk_buff *skb, int ring_offset);
93
static void ultra_block_output(struct net_device *dev, int count,
94
                                                        const unsigned char *buf, const int start_page);
95
static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
96
                                                int ring_page);
97
static void ultra_pio_input(struct net_device *dev, int count,
98
                                                  struct sk_buff *skb, int ring_offset);
99
static void ultra_pio_output(struct net_device *dev, int count,
100
                                                         const unsigned char *buf, const int start_page);
101
static int ultra_close_card(struct net_device *dev);
102
 
103
#ifdef __ISAPNP__
104
static struct isapnp_device_id ultra_device_ids[] __initdata = {
105
        {       ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416),
106
                ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416),
107
                (long) "SMC EtherEZ (8416)" },
108
        { }     /* terminate list */
109
};
110
 
111
MODULE_DEVICE_TABLE(isapnp, ultra_device_ids);
112
#endif
113
 
114
 
115
#define START_PG                0x00    /* First page of TX buffer */
116
 
117
#define ULTRA_CMDREG    0                /* Offset to ASIC command register. */
118
#define  ULTRA_RESET    0x80    /* Board reset, in ULTRA_CMDREG. */
119
#define  ULTRA_MEMENB   0x40    /* Enable the shared memory. */
120
#define IOPD    0x02                    /* I/O Pipe Data (16 bits), PIO operation. */
121
#define IOPA    0x07                    /* I/O Pipe Address for PIO operation. */
122
#define ULTRA_NIC_OFFSET  16    /* NIC register offset from the base_addr. */
123
#define ULTRA_IO_EXTENT 32
124
#define EN0_ERWCNT              0x08    /* Early receive warning count. */
125
 
126
#ifdef CONFIG_NET_POLL_CONTROLLER
127
static void ultra_poll(struct net_device *dev)
128
{
129
        disable_irq(dev->irq);
130
        ei_interrupt(dev->irq, dev);
131
        enable_irq(dev->irq);
132
}
133
#endif
134
/*      Probe for the Ultra.  This looks like a 8013 with the station
135
        address PROM at I/O ports <base>+8 to <base>+13, with a checksum
136
        following.
137
*/
138
 
139
static int __init do_ultra_probe(struct net_device *dev)
140
{
141
        int i;
142
        int base_addr = dev->base_addr;
143
        int irq = dev->irq;
144
 
145
#ifdef CONFIG_NET_POLL_CONTROLLER
146
        dev->poll_controller = &ultra_poll;
147
#endif
148
        if (base_addr > 0x1ff)          /* Check a single specified location. */
149
                return ultra_probe1(dev, base_addr);
150
        else if (base_addr != 0) /* Don't probe at all. */
151
                return -ENXIO;
152
 
153
#ifdef __ISAPNP__
154
        /* Look for any installed ISAPnP cards */
155
        if (isapnp_present() && (ultra_probe_isapnp(dev) == 0))
156
                return 0;
157
#endif
158
 
159
        for (i = 0; ultra_portlist[i]; i++) {
160
                dev->irq = irq;
161
                if (ultra_probe1(dev, ultra_portlist[i]) == 0)
162
                        return 0;
163
        }
164
 
165
        return -ENODEV;
166
}
167
 
168
#ifndef MODULE
169
struct net_device * __init ultra_probe(int unit)
170
{
171
        struct net_device *dev = alloc_ei_netdev();
172
        int err;
173
 
174
        if (!dev)
175
                return ERR_PTR(-ENOMEM);
176
 
177
        sprintf(dev->name, "eth%d", unit);
178
        netdev_boot_setup_check(dev);
179
 
180
        err = do_ultra_probe(dev);
181
        if (err)
182
                goto out;
183
        return dev;
184
out:
185
        free_netdev(dev);
186
        return ERR_PTR(err);
187
}
188
#endif
189
 
190
static int __init ultra_probe1(struct net_device *dev, int ioaddr)
191
{
192
        int i, retval;
193
        int checksum = 0;
194
        const char *model_name;
195
        unsigned char eeprom_irq = 0;
196
        static unsigned version_printed;
197
        /* Values from various config regs. */
198
        unsigned char num_pages, irqreg, addr, piomode;
199
        unsigned char idreg = inb(ioaddr + 7);
200
        unsigned char reg4 = inb(ioaddr + 4) & 0x7f;
201
        DECLARE_MAC_BUF(mac);
202
 
203
        if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME))
204
                return -EBUSY;
205
 
206
        /* Check the ID nibble. */
207
        if ((idreg & 0xF0) != 0x20                      /* SMC Ultra */
208
                && (idreg & 0xF0) != 0x40) {            /* SMC EtherEZ */
209
                retval = -ENODEV;
210
                goto out;
211
        }
212
 
213
        /* Select the station address register set. */
214
        outb(reg4, ioaddr + 4);
215
 
216
        for (i = 0; i < 8; i++)
217
                checksum += inb(ioaddr + 8 + i);
218
        if ((checksum & 0xff) != 0xFF) {
219
                retval = -ENODEV;
220
                goto out;
221
        }
222
 
223
        if (ei_debug  &&  version_printed++ == 0)
224
                printk(version);
225
 
226
        model_name = (idreg & 0xF0) == 0x20 ? "SMC Ultra" : "SMC EtherEZ";
227
 
228
        for (i = 0; i < 6; i++)
229
                dev->dev_addr[i] = inb(ioaddr + 8 + i);
230
 
231
        printk("%s: %s at %#3x, %s", dev->name, model_name,
232
               ioaddr, print_mac(mac, dev->dev_addr));
233
 
234
        /* Switch from the station address to the alternate register set and
235
           read the useful registers there. */
236
        outb(0x80 | reg4, ioaddr + 4);
237
 
238
        /* Enabled FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */
239
        outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c);
240
        piomode = inb(ioaddr + 0x8);
241
        addr = inb(ioaddr + 0xb);
242
        irqreg = inb(ioaddr + 0xd);
243
 
244
        /* Switch back to the station address register set so that the MS-DOS driver
245
           can find the card after a warm boot. */
246
        outb(reg4, ioaddr + 4);
247
 
248
        if (dev->irq < 2) {
249
                unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15};
250
                int irq;
251
 
252
                /* The IRQ bits are split. */
253
                irq = irqmap[((irqreg & 0x40) >> 4) + ((irqreg & 0x0c) >> 2)];
254
 
255
                if (irq == 0) {
256
                        printk(", failed to detect IRQ line.\n");
257
                        retval =  -EAGAIN;
258
                        goto out;
259
                }
260
                dev->irq = irq;
261
                eeprom_irq = 1;
262
        }
263
 
264
        /* The 8390 isn't at the base address, so fake the offset */
265
        dev->base_addr = ioaddr+ULTRA_NIC_OFFSET;
266
 
267
        {
268
                int addr_tbl[4] = {0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000};
269
                short num_pages_tbl[4] = {0x20, 0x40, 0x80, 0xff};
270
 
271
                dev->mem_start = ((addr & 0x0f) << 13) + addr_tbl[(addr >> 6) & 3] ;
272
                num_pages = num_pages_tbl[(addr >> 4) & 3];
273
        }
274
 
275
        ei_status.name = model_name;
276
        ei_status.word16 = 1;
277
        ei_status.tx_start_page = START_PG;
278
        ei_status.rx_start_page = START_PG + TX_PAGES;
279
        ei_status.stop_page = num_pages;
280
 
281
        ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG)*256);
282
        if (!ei_status.mem) {
283
                printk(", failed to ioremap.\n");
284
                retval =  -ENOMEM;
285
                goto out;
286
        }
287
 
288
        dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG)*256;
289
 
290
        if (piomode) {
291
                printk(",%s IRQ %d programmed-I/O mode.\n",
292
                           eeprom_irq ? "EEPROM" : "assigned ", dev->irq);
293
                ei_status.block_input = &ultra_pio_input;
294
                ei_status.block_output = &ultra_pio_output;
295
                ei_status.get_8390_hdr = &ultra_pio_get_hdr;
296
        } else {
297
                printk(",%s IRQ %d memory %#lx-%#lx.\n", eeprom_irq ? "" : "assigned ",
298
                           dev->irq, dev->mem_start, dev->mem_end-1);
299
                ei_status.block_input = &ultra_block_input;
300
                ei_status.block_output = &ultra_block_output;
301
                ei_status.get_8390_hdr = &ultra_get_8390_hdr;
302
        }
303
        ei_status.reset_8390 = &ultra_reset_8390;
304
        dev->open = &ultra_open;
305
        dev->stop = &ultra_close_card;
306
#ifdef CONFIG_NET_POLL_CONTROLLER
307
        dev->poll_controller = ei_poll;
308
#endif
309
        NS8390_init(dev, 0);
310
 
311
        retval = register_netdev(dev);
312
        if (retval)
313
                goto out;
314
        return 0;
315
out:
316
        release_region(ioaddr, ULTRA_IO_EXTENT);
317
        return retval;
318
}
319
 
320
#ifdef __ISAPNP__
321
static int __init ultra_probe_isapnp(struct net_device *dev)
322
{
323
        int i;
324
 
325
        for (i = 0; ultra_device_ids[i].vendor != 0; i++) {
326
                struct pnp_dev *idev = NULL;
327
 
328
                while ((idev = pnp_find_dev(NULL,
329
                                            ultra_device_ids[i].vendor,
330
                                            ultra_device_ids[i].function,
331
                                            idev))) {
332
                        /* Avoid already found cards from previous calls */
333
                        if (pnp_device_attach(idev) < 0)
334
                                continue;
335
                        if (pnp_activate_dev(idev) < 0) {
336
                              __again:
337
                                pnp_device_detach(idev);
338
                                continue;
339
                        }
340
                        /* if no io and irq, search for next */
341
                        if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0))
342
                                goto __again;
343
                        /* found it */
344
                        dev->base_addr = pnp_port_start(idev, 0);
345
                        dev->irq = pnp_irq(idev, 0);
346
                        printk(KERN_INFO "smc-ultra.c: ISAPnP reports %s at i/o %#lx, irq %d.\n",
347
                                (char *) ultra_device_ids[i].driver_data,
348
                                dev->base_addr, dev->irq);
349
                        if (ultra_probe1(dev, dev->base_addr) != 0) {      /* Shouldn't happen. */
350
                                printk(KERN_ERR "smc-ultra.c: Probe of ISAPnP card at %#lx failed.\n", dev->base_addr);
351
                                pnp_device_detach(idev);
352
                                return -ENXIO;
353
                        }
354
                        ei_status.priv = (unsigned long)idev;
355
                        break;
356
                }
357
                if (!idev)
358
                        continue;
359
                return 0;
360
        }
361
 
362
        return -ENODEV;
363
}
364
#endif
365
 
366
static int
367
ultra_open(struct net_device *dev)
368
{
369
        int retval;
370
        int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
371
        unsigned char irq2reg[] = {0, 0, 0x04, 0x08, 0, 0x0C, 0, 0x40,
372
                                   0, 0x04, 0x44, 0x48, 0, 0, 0, 0x4C, };
373
 
374
        retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
375
        if (retval)
376
                return retval;
377
 
378
        outb(0x00, ioaddr);     /* Disable shared memory for safety. */
379
        outb(0x80, ioaddr + 5);
380
        /* Set the IRQ line. */
381
        outb(inb(ioaddr + 4) | 0x80, ioaddr + 4);
382
        outb((inb(ioaddr + 13) & ~0x4C) | irq2reg[dev->irq], ioaddr + 13);
383
        outb(inb(ioaddr + 4) & 0x7f, ioaddr + 4);
384
 
385
        if (ei_status.block_input == &ultra_pio_input) {
386
                outb(0x11, ioaddr + 6);         /* Enable interrupts and PIO. */
387
                outb(0x01, ioaddr + 0x19);      /* Enable ring read auto-wrap. */
388
        } else
389
                outb(0x01, ioaddr + 6);         /* Enable interrupts and memory. */
390
        /* Set the early receive warning level in window 0 high enough not
391
           to receive ERW interrupts. */
392
        outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr);
393
        outb(0xff, dev->base_addr + EN0_ERWCNT);
394
        ei_open(dev);
395
        return 0;
396
}
397
 
398
static void
399
ultra_reset_8390(struct net_device *dev)
400
{
401
        int cmd_port = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC base addr */
402
 
403
        outb(ULTRA_RESET, cmd_port);
404
        if (ei_debug > 1) printk("resetting Ultra, t=%ld...", jiffies);
405
        ei_status.txing = 0;
406
 
407
        outb(0x00, cmd_port);   /* Disable shared memory for safety. */
408
        outb(0x80, cmd_port + 5);
409
        if (ei_status.block_input == &ultra_pio_input)
410
                outb(0x11, cmd_port + 6);               /* Enable interrupts and PIO. */
411
        else
412
                outb(0x01, cmd_port + 6);               /* Enable interrupts and memory. */
413
 
414
        if (ei_debug > 1) printk("reset done\n");
415
        return;
416
}
417
 
418
/* Grab the 8390 specific header. Similar to the block_input routine, but
419
   we don't need to be concerned with ring wrap as the header will be at
420
   the start of a page, so we optimize accordingly. */
421
 
422
static void
423
ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
424
{
425
        void __iomem *hdr_start = ei_status.mem + ((ring_page - START_PG)<<8);
426
 
427
        outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);  /* shmem on */
428
#ifdef __BIG_ENDIAN
429
        /* Officially this is what we are doing, but the readl() is faster */
430
        /* unfortunately it isn't endian aware of the struct               */
431
        memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
432
        hdr->count = le16_to_cpu(hdr->count);
433
#else
434
        ((unsigned int*)hdr)[0] = readl(hdr_start);
435
#endif
436
        outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */
437
}
438
 
439
/* Block input and output are easy on shared memory ethercards, the only
440
   complication is when the ring buffer wraps. */
441
 
442
static void
443
ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
444
{
445
        void __iomem *xfer_start = ei_status.mem + ring_offset - (START_PG<<8);
446
 
447
        /* Enable shared memory. */
448
        outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);
449
 
450
        if (ring_offset + count > ei_status.stop_page*256) {
451
                /* We must wrap the input move. */
452
                int semi_count = ei_status.stop_page*256 - ring_offset;
453
                memcpy_fromio(skb->data, xfer_start, semi_count);
454
                count -= semi_count;
455
                memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
456
        } else {
457
                memcpy_fromio(skb->data, xfer_start, count);
458
        }
459
 
460
        outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET);  /* Disable memory. */
461
}
462
 
463
static void
464
ultra_block_output(struct net_device *dev, int count, const unsigned char *buf,
465
                                int start_page)
466
{
467
        void __iomem *shmem = ei_status.mem + ((start_page - START_PG)<<8);
468
 
469
        /* Enable shared memory. */
470
        outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);
471
 
472
        memcpy_toio(shmem, buf, count);
473
 
474
        outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */
475
}
476
 
477
/* The identical operations for programmed I/O cards.
478
   The PIO model is trivial to use: the 16 bit start address is written
479
   byte-sequentially to IOPA, with no intervening I/O operations, and the
480
   data is read or written to the IOPD data port.
481
   The only potential complication is that the address register is shared
482
   and must be always be rewritten between each read/write direction change.
483
   This is no problem for us, as the 8390 code ensures that we are single
484
   threaded. */
485
static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
486
                                                int ring_page)
487
{
488
        int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
489
        outb(0x00, ioaddr + IOPA);      /* Set the address, LSB first. */
490
        outb(ring_page, ioaddr + IOPA);
491
        insw(ioaddr + IOPD, hdr, sizeof(struct e8390_pkt_hdr)>>1);
492
}
493
 
494
static void ultra_pio_input(struct net_device *dev, int count,
495
                                                  struct sk_buff *skb, int ring_offset)
496
{
497
        int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
498
    char *buf = skb->data;
499
 
500
        /* For now set the address again, although it should already be correct. */
501
        outb(ring_offset, ioaddr + IOPA);       /* Set the address, LSB first. */
502
        outb(ring_offset >> 8, ioaddr + IOPA);
503
        /* We know skbuffs are padded to at least word alignment. */
504
        insw(ioaddr + IOPD, buf, (count+1)>>1);
505
}
506
 
507
static void ultra_pio_output(struct net_device *dev, int count,
508
                                                        const unsigned char *buf, const int start_page)
509
{
510
        int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
511
        outb(0x00, ioaddr + IOPA);      /* Set the address, LSB first. */
512
        outb(start_page, ioaddr + IOPA);
513
        /* An extra odd byte is OK here as well. */
514
        outsw(ioaddr + IOPD, buf, (count+1)>>1);
515
}
516
 
517
static int
518
ultra_close_card(struct net_device *dev)
519
{
520
        int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* CMDREG */
521
 
522
        netif_stop_queue(dev);
523
 
524
        if (ei_debug > 1)
525
                printk("%s: Shutting down ethercard.\n", dev->name);
526
 
527
        outb(0x00, ioaddr + 6);         /* Disable interrupts. */
528
        free_irq(dev->irq, dev);
529
 
530
        NS8390_init(dev, 0);
531
 
532
        /* We should someday disable shared memory and change to 8-bit mode
533
           "just in case"... */
534
 
535
        return 0;
536
}
537
 
538
 
539
#ifdef MODULE
540
#define MAX_ULTRA_CARDS 4       /* Max number of Ultra cards per module */
541
static struct net_device *dev_ultra[MAX_ULTRA_CARDS];
542
static int io[MAX_ULTRA_CARDS];
543
static int irq[MAX_ULTRA_CARDS];
544
 
545
module_param_array(io, int, NULL, 0);
546
module_param_array(irq, int, NULL, 0);
547
MODULE_PARM_DESC(io, "I/O base address(es)");
548
MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
549
MODULE_DESCRIPTION("SMC Ultra/EtherEZ ISA/PnP Ethernet driver");
550
MODULE_LICENSE("GPL");
551
 
552
/* This is set up so that only a single autoprobe takes place per call.
553
ISA device autoprobes on a running machine are not recommended. */
554
int __init
555
init_module(void)
556
{
557
        struct net_device *dev;
558
        int this_dev, found = 0;
559
 
560
        for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
561
                if (io[this_dev] == 0)  {
562
                        if (this_dev != 0) break; /* only autoprobe 1st one */
563
                        printk(KERN_NOTICE "smc-ultra.c: Presently autoprobing (not recommended) for a single card.\n");
564
                }
565
                dev = alloc_ei_netdev();
566
                if (!dev)
567
                        break;
568
                dev->irq = irq[this_dev];
569
                dev->base_addr = io[this_dev];
570
                if (do_ultra_probe(dev) == 0) {
571
                        dev_ultra[found++] = dev;
572
                        continue;
573
                }
574
                free_netdev(dev);
575
                printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
576
                break;
577
        }
578
        if (found)
579
                return 0;
580
        return -ENXIO;
581
}
582
 
583
static void cleanup_card(struct net_device *dev)
584
{
585
        /* NB: ultra_close_card() does free_irq */
586
#ifdef __ISAPNP__
587
        struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
588
        if (idev)
589
                pnp_device_detach(idev);
590
#endif
591
        release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT);
592
        iounmap(ei_status.mem);
593
}
594
 
595
void __exit
596
cleanup_module(void)
597
{
598
        int this_dev;
599
 
600
        for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
601
                struct net_device *dev = dev_ultra[this_dev];
602
                if (dev) {
603
                        unregister_netdev(dev);
604
                        cleanup_card(dev);
605
                        free_netdev(dev);
606
                }
607
        }
608
}
609
#endif /* MODULE */

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.