示例#1
0
文件: mac8390.c 项目: xricson/knoppix
int __init mac8390_probe(struct net_device * dev)
{
	volatile unsigned short *i;
	int boards_found = 0;
	int version_disp = 0;
	struct nubus_dev * ndev = NULL;
	
	struct nubus_dir dir;
	struct nubus_dirent ent;
	int offset;

	enum mac8390_type cardtype;

	if (probed)
		return -ENODEV;
	probed++;

	/* probably should check for Nubus instead */

	if (!MACH_IS_MAC)
		return -ENODEV;

	while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, ndev))) {
		
		dev = NULL;
		
		if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE)
			continue;

		dev = init_etherdev(dev, 0);
		if (dev == NULL) {
			printk(KERN_ERR "Unable to allocate etherdev"
					"structure!\n");
			return -ENOMEM;
		}

		if (version_disp == 0) {
			version_disp = 1;
			printk(version);
		}

		dev->irq = SLOT2IRQ(ndev->board->slot);
		/* This is getting to be a habit */
		dev->base_addr = ndev->board->slot_addr | ((ndev->board->slot&0xf) << 20);

		/* Get some Nubus info - we will trust the card's idea
		   of where its memory and registers are. */

		if (nubus_get_func_dir(ndev, &dir) == -1) {
			printk(KERN_ERR "%s: Unable to get Nubus functional"
					" directory for slot %X!\n",
			       dev->name, ndev->board->slot);
			continue;
		}
		
		/* Get the MAC address */
		if ((nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent)) == -1) {
			printk(KERN_INFO "%s: Couldn't get MAC address!\n",
					dev->name);
			continue;
		} else {
			nubus_get_rsrc_mem(dev->dev_addr, &ent, 6);
			/* Some Sonic Sys cards masquerade as Farallon */
			if (cardtype == MAC8390_FARALLON && 
					dev->dev_addr[0] == 0x0 &&
					dev->dev_addr[1] == 0x40 &&
					dev->dev_addr[2] == 0x10) {
				/* This is really Sonic Sys card */
				cardtype = MAC8390_SONICSYS;
			}
		}
		
		if (useresources[cardtype] == 1) {
			nubus_rewinddir(&dir);
			if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS, &ent) == -1) {
				printk(KERN_ERR "%s: Memory offset resource"
						" for slot %X not found!\n",
				       dev->name, ndev->board->slot);
				continue;
			}
			nubus_get_rsrc_mem(&offset, &ent, 4);
			dev->mem_start = dev->base_addr + offset;
			/* yes, this is how the Apple driver does it */
			dev->base_addr = dev->mem_start + 0x10000;
			nubus_rewinddir(&dir);
			if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH, &ent) == -1) {
				printk(KERN_INFO "%s: Memory length resource"
						 " for slot %X not found"
						 ", probing\n",
				       dev->name, ndev->board->slot);
				offset = mac8390_memsize(dev->mem_start);
				} else {
					nubus_get_rsrc_mem(&offset, &ent, 4);
				}
			dev->mem_end = dev->mem_start + offset;
		} else {
			switch (cardtype) {
				case MAC8390_KINETICS:
				case MAC8390_DAYNA: /* it's the same */
					dev->base_addr = 
						(int)(ndev->board->slot_addr +
						DAYNA_8390_BASE);
					dev->mem_start = 
						(int)(ndev->board->slot_addr +
						DAYNA_8390_MEM);
					dev->mem_end =
						dev->mem_start +
						mac8390_memsize(dev->mem_start);
					break;
				case MAC8390_CABLETRON:
					dev->base_addr =
						(int)(ndev->board->slot_addr +
						CABLETRON_8390_BASE);
					dev->mem_start =
						(int)(ndev->board->slot_addr +
						CABLETRON_8390_MEM);
					/* The base address is unreadable if 0x00
					 * has been written to the command register
					 * Reset the chip by writing E8390_NODMA +
					 *   E8390_PAGE0 + E8390_STOP just to be
					 *   sure
					 */
					i = (void *)dev->base_addr;
					*i = 0x21;
					dev->mem_end = 
						dev->mem_start +
						mac8390_memsize(dev->mem_start);
					break;
					
				default:
					printk(KERN_ERR "Card type %s is"
							" unsupported, sorry\n",
					       cardname[cardtype]);
					return -ENODEV;
			}
		}

		/* Do the nasty 8390 stuff */
		if (mac8390_initdev(dev, ndev, cardtype))
			continue;
		boards_found++;
	}

	/* We're outta here */
	if (boards_found > 0)
		return 0;
	else
		return -ENODEV;
}
示例#2
0
struct net_device * __init mac8390_probe(int unit)
{
    struct net_device *dev;
    volatile unsigned short *i;
    int version_disp = 0;
    struct nubus_dev * ndev = NULL;
    int err = -ENODEV;

    struct nubus_dir dir;
    struct nubus_dirent ent;
    int offset;
    static unsigned int slots;

    enum mac8390_type cardtype;

    /* probably should check for Nubus instead */

    if (!MACH_IS_MAC)
        return ERR_PTR(-ENODEV);

    dev = alloc_ei_netdev();
    if (!dev)
        return ERR_PTR(-ENOMEM);

    if (unit >= 0)
        sprintf(dev->name, "eth%d", unit);

    while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, ndev))) {
        /* Have we seen it already? */
        if (slots & (1<<ndev->board->slot))
            continue;
        slots |= 1<<ndev->board->slot;

        if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE)
            continue;

        if (version_disp == 0) {
            version_disp = 1;
            printk(version);
        }

        dev->irq = SLOT2IRQ(ndev->board->slot);
        /* This is getting to be a habit */
        dev->base_addr = ndev->board->slot_addr | ((ndev->board->slot&0xf) << 20);

        /* Get some Nubus info - we will trust the card's idea
           of where its memory and registers are. */

        if (nubus_get_func_dir(ndev, &dir) == -1) {
            printk(KERN_ERR "%s: Unable to get Nubus functional"
                   " directory for slot %X!\n",
                   dev->name, ndev->board->slot);
            continue;
        }

        /* Get the MAC address */
        if ((nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent)) == -1) {
            printk(KERN_INFO "%s: Couldn't get MAC address!\n",
                   dev->name);
            continue;
        } else {
            nubus_get_rsrc_mem(dev->dev_addr, &ent, 6);
        }

        if (useresources[cardtype] == 1) {
            nubus_rewinddir(&dir);
            if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS, &ent) == -1) {
                printk(KERN_ERR "%s: Memory offset resource"
                       " for slot %X not found!\n",
                       dev->name, ndev->board->slot);
                continue;
            }
            nubus_get_rsrc_mem(&offset, &ent, 4);
            dev->mem_start = dev->base_addr + offset;
            /* yes, this is how the Apple driver does it */
            dev->base_addr = dev->mem_start + 0x10000;
            nubus_rewinddir(&dir);
            if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH, &ent) == -1) {
                printk(KERN_INFO "%s: Memory length resource"
                       " for slot %X not found"
                       ", probing\n",
                       dev->name, ndev->board->slot);
                offset = mac8390_memsize(dev->mem_start);
            } else {
                nubus_get_rsrc_mem(&offset, &ent, 4);
            }
            dev->mem_end = dev->mem_start + offset;
        } else {
            switch (cardtype) {
            case MAC8390_KINETICS:
            case MAC8390_DAYNA: /* it's the same */
                dev->base_addr =
                    (int)(ndev->board->slot_addr +
                          DAYNA_8390_BASE);
                dev->mem_start =
                    (int)(ndev->board->slot_addr +
                          DAYNA_8390_MEM);
                dev->mem_end =
                    dev->mem_start +
                    mac8390_memsize(dev->mem_start);
                break;
            case MAC8390_INTERLAN:
                dev->base_addr =
                    (int)(ndev->board->slot_addr +
                          INTERLAN_8390_BASE);
                dev->mem_start =
                    (int)(ndev->board->slot_addr +
                          INTERLAN_8390_MEM);
                dev->mem_end =
                    dev->mem_start +
                    mac8390_memsize(dev->mem_start);
                break;
            case MAC8390_CABLETRON:
                dev->base_addr =
                    (int)(ndev->board->slot_addr +
                          CABLETRON_8390_BASE);
                dev->mem_start =
                    (int)(ndev->board->slot_addr +
                          CABLETRON_8390_MEM);
                /* The base address is unreadable if 0x00
                 * has been written to the command register
                 * Reset the chip by writing E8390_NODMA +
                 *   E8390_PAGE0 + E8390_STOP just to be
                 *   sure
                 */
                i = (void *)dev->base_addr;
                *i = 0x21;
                dev->mem_end =
                    dev->mem_start +
                    mac8390_memsize(dev->mem_start);
                break;

            default:
                printk(KERN_ERR "Card type %s is"
                       " unsupported, sorry\n",
                       ndev->board->name);
                continue;
            }
        }

        /* Do the nasty 8390 stuff */
        if (!mac8390_initdev(dev, ndev, cardtype))
            break;
    }

    if (!ndev)
        goto out;
    err = register_netdev(dev);
    if (err)
        goto out;
    return dev;

out:
    free_netdev(dev);
    return ERR_PTR(err);
}