/* * Check for a network adaptor of this type, and return '0' iff one exists. * If dev->base_addr == 0, probe all likely locations. * If dev->base_addr in [1..0x1ff], always return failure. * otherwise go with what we pass in. */ struct net_device * __init cops_probe(int unit) { struct net_device *dev; unsigned *port; int base_addr; int err = 0; dev = alloc_ltalkdev(sizeof(struct cops_local)); if (!dev) return ERR_PTR(-ENOMEM); if (unit >= 0) { sprintf(dev->name, "lt%d", unit); netdev_boot_setup_check(dev); irq = dev->irq; base_addr = dev->base_addr; } else { base_addr = dev->base_addr = io; } SET_MODULE_OWNER(dev); if (base_addr > 0x1ff) { /* Check a single specified location. */ err = cops_probe1(dev, base_addr); } else if (base_addr != 0) { /* Don't probe at all. */ err = -ENXIO; } else { /* FIXME Does this really work for cards which generate irq? * It's definitely N.G. for polled Tangent. sh * Dayna cards don't autoprobe well at all, but if your card is * at IRQ 5 & IO 0x240 we find it every time. ;) JS */ for (port = ports; *port && cops_probe1(dev, *port) < 0; port++) ; if (!*port) err = -ENODEV; } if (err) goto out; err = register_netdev(dev); if (err) goto out1; return dev; out1: cleanup_card(dev); out: free_netdev(dev); return ERR_PTR(err); }
struct net_device * __init ltpc_probe(void) { struct net_device *dev; int err = -ENOMEM; int x=0,y=0; int autoirq; unsigned long f; unsigned long timeout; dev = alloc_ltalkdev(sizeof(struct ltpc_private)); if (!dev) goto out; SET_MODULE_OWNER(dev); /* probe for the I/O port address */ if (io != 0x240 && request_region(0x220,8,"ltpc")) { x = inb_p(0x220+6); if ( (x!=0xff) && (x>=0xf0) ) { io = 0x220; goto got_port; } release_region(0x220,8); } if (io != 0x220 && request_region(0x240,8,"ltpc")) { y = inb_p(0x240+6); if ( (y!=0xff) && (y>=0xf0) ){ io = 0x240; goto got_port; } release_region(0x240,8); } /* give up in despair */ printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y); err = -ENODEV; goto out1; got_port: /* probe for the IRQ line */ if (irq < 2) { unsigned long irq_mask; irq_mask = probe_irq_on(); /* reset the interrupt line */ inb_p(io+7); inb_p(io+7); /* trigger an interrupt (I hope) */ inb_p(io+6); mdelay(2); autoirq = probe_irq_off(irq_mask); if (autoirq == 0) { printk(KERN_ERR "ltpc: probe at %#x failed to detect IRQ line.\n", io); } else { irq = autoirq; } } /* allocate a DMA buffer */ ltdmabuf = (unsigned char *) dma_mem_alloc(1000); if (!ltdmabuf) { printk(KERN_ERR "ltpc: mem alloc failed\n"); err = -ENOMEM; goto out2; } ltdmacbuf = <dmabuf[800]; if(debug & DEBUG_VERBOSE) { printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf); } /* reset the card */ inb_p(io+1); inb_p(io+3); msleep(20); inb_p(io+0); inb_p(io+2); inb_p(io+7); /* clear reset */ inb_p(io+4); inb_p(io+5); inb_p(io+5); /* enable dma */ inb_p(io+6); /* tri-state interrupt line */ ssleep(1); /* now, figure out which dma channel we're using, unless it's already been specified */ /* well, 0 is a legal DMA channel, but the LTPC card doesn't use it... */ dma = ltpc_probe_dma(io, dma); if (!dma) { /* no dma channel */ printk(KERN_ERR "No DMA channel found on ltpc card.\n"); err = -ENODEV; goto out3; } /* print out friendly message */ if(irq) printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma); else printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma); /* Fill in the fields of the device structure with ethernet-generic values. */ dev->hard_start_xmit = ltpc_xmit; dev->hard_header = ltpc_hard_header; dev->get_stats = ltpc_get_stats; /* add the ltpc-specific things */ dev->do_ioctl = <pc_ioctl; dev->set_multicast_list = &set_multicast_list; dev->mc_list = NULL; dev->base_addr = io; dev->irq = irq; dev->dma = dma; /* the card will want to send a result at this point */ /* (I think... leaving out this part makes the kernel crash, so I put it back in...) */ f=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); set_dma_mode(dma,DMA_MODE_READ); set_dma_addr(dma,virt_to_bus(ltdmabuf)); set_dma_count(dma,0x100); enable_dma(dma); release_dma_lock(f); (void) inb_p(io+3); (void) inb_p(io+2); timeout = jiffies+100*HZ/100; while(time_before(jiffies, timeout)) { if( 0xf9 == inb_p(io+6)) break; schedule(); } if(debug & DEBUG_VERBOSE) { printk("setting up timer and irq\n"); } /* grab it and don't let go :-) */ if (irq && request_irq( irq, <pc_interrupt, 0, "ltpc", dev) >= 0) { (void) inb_p(io+7); /* enable interrupts from board */ (void) inb_p(io+7); /* and reset irq line */ } else { if( irq ) printk(KERN_ERR "ltpc: IRQ already in use, using polled mode.\n"); dev->irq = 0; /* polled mode -- 20 times per second */ /* this is really, really slow... should it poll more often? */ init_timer(<pc_timer); ltpc_timer.function=ltpc_poll; ltpc_timer.data = (unsigned long) dev; ltpc_timer.expires = jiffies + HZ/20; add_timer(<pc_timer); } err = register_netdev(dev); if (err) goto out4; return NULL; out4: del_timer_sync(<pc_timer); if (dev->irq) free_irq(dev->irq, dev); out3: free_pages((unsigned long)ltdmabuf, get_order(1000)); out2: release_region(io, 8); out1: free_netdev(dev); out: return ERR_PTR(err); }