/* * Open/initialize the board. This is called (in the current kernel) * sometime after booting when the 'ifconfig' program is run. * * This routine should set everything up anew at each open, even * registers that "should" only need to be set once at boot, so that * there is non-reboot way to recover if something goes wrong. */ static int net_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; struct sk_buff *skb; int irqval; int i; MOD_INC_USE_COUNT; /* For now we always do Eth1 */ lp->uEth = uETH1; BUGMSG("%s:Opening Ethernet interface ", dev->name); if(lp->uEth == uETH1) { BUGMSG("1\n"); dev->irq = IRQ_ETH1; } else { BUGMSG("2\n"); dev->irq = IRQ_ETH2; } irqval = request_irq(dev->irq, &net_interrupt, SA_INTERRUPT, cardname, NULL); if (irqval) { printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, dev->irq, irqval); return -EAGAIN; } /* Allocate Ethernet RX buffers */ for( i = 0; i < ETH_RXQ_SIZE; i++ ) { skb = dev_alloc_skb( PKT_BUF_SZ ); if (skb == NULL) { printk("%s: Could not allocate RX Ring buffer\n", dev->name); while(i != 0) dev_kfree_skb(lp->rx_frames[--i]); return -ENOMEM; } skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */ /* word align IP header */ skb_reserve( skb, 2 ); lp->rx_frames[i] = skb; } lp->rxq_ptr = 0; lp->txq_p = 0; lp->txq_c = 0; BUGMSG("%s: Resetting hardware\n", dev->name); /* Reset the hardware here. */ chipset_init( dev, 1 ); lp->open_time = jiffies; BUGMSG("%s: netif_start_queue\n", dev->name); netif_start_queue(dev); return 0; }
static int net_send_packet(struct sk_buff *skb, struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; if (dev->tbusy) { /* If we get here, some higher level has decided we are broken. There should really be a "kick me" function call instead. */ int tickssofar = jiffies - dev->trans_start; if (tickssofar < 5) return 1; printk("%s: transmit timed out, %s?\n", dev->name, tx_done(dev) ? "IRQ conflict" : "network cable problem"); /* Try to restart the adaptor. */ chipset_init(dev, 1); dev->tbusy=0; dev->trans_start = jiffies; } /* If some higher layer thinks we've missed an tx-done interrupt we are passed NULL. Caution: dev_tint() handles the cli()/sti() itself. */ if (skb == NULL) { dev_tint(dev); return 0; } /* For ethernet, fill in the header. This should really be done by a higher level, rather than duplicated for each ethernet adaptor. */ if (!skb->arp && dev->rebuild_header(skb->data, dev)) { skb->dev = dev; arp_queue (skb); return 0; } skb->arp=1; /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ if (set_bit(0, (void*)&dev->tbusy) != 0) printk("%s: Transmitter access conflict.\n", dev->name); else { short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; hardware_send_packet(ioaddr, buf, length); dev->trans_start = jiffies; } if (skb->free) kfree_skb (skb, FREE_WRITE); /* You might need to clean up and record Tx statistics here. */ if (inw(ioaddr) == /*RU*/81) lp->stats.tx_aborted_errors++; return 0; }
static int cl_set_var(struct fb_info *info, const struct fb_var_screeninfo *var) { cirrus_chip_info.doubleVCLK = 0; cirrus_chip_info.multiplexing = 0; cirrus_chip_info.screen_info = var; cirrus_chip_info.screen_base = info->screen_base; chipset_init(&cirrus_chip_info); setup_resolution(&cirrus_chip_info); cirrus_setup_bits_per_pixel(&cirrus_chip_info); vga_display_enable(1); return 0; }