static void check_change(unsigned long dummy) { static int drive = 0; unsigned long flags; int stat; if (fdc_busy) return; /* Don't start poking about if the fdc is busy */ return; /* let's just forget it for the mo DAG */ if (++drive > 1 || !unit[drive].connected) drive = 0; save_flags(flags); cli(); if (!stdma_islocked()) { stat = !!(FDC1772_READ(FDC1772REG_STATUS) & FDC1772STAT_WPROT); /* The idea here is that if the write protect line has changed then the disc must have changed */ if (stat != unit[drive].wpstat) { DPRINT(("wpstat[%d] = %d\n", drive, stat)); unit[drive].wpstat = stat; set_bit(drive, &changed_floppies); } } restore_flags(flags); START_CHECK_CHANGE_TIMER(CHECK_CHANGE_DELAY); }
/* bionet_tick: called by bionet_timer. Reads packets from the adapter, * passes them to the higher layers and restarts the timer. */ static void bionet_tick(unsigned long data) { struct net_device *dev = (struct net_device *)data; struct net_local *lp = netdev_priv(dev); if( bionet_debug > 0 && (lp->open_time++ & 7) == 8 ) printk("bionet_tick: %ld\n", lp->open_time); if( !stdma_islocked() ) bionet_poll_rx(dev); bionet_timer.expires = jiffies + lp->poll_time; add_timer(&bionet_timer); }
/* We have a good packet(s), get it/them out of the buffers. */ static void bionet_poll_rx(struct net_device *dev) { struct net_local *lp = netdev_priv(dev); int boguscount = 10; int pkt_len, status; unsigned long flags; local_irq_save(flags); /* ++roman: Take care at locking the ST-DMA... This must be done with ints * off, since otherwise an int could slip in between the question and the * locking itself, and then we'd go to sleep... And locking itself is * necessary to keep the floppy_change timer from working with ST-DMA * registers. */ if (stdma_islocked()) { local_irq_restore(flags); return; } stdma_lock(bionet_intr, NULL); DISABLE_IRQ(); local_irq_restore(flags); if( lp->poll_time < MAX_POLL_TIME ) lp->poll_time++; while(boguscount--) { status = get_frame((unsigned long)phys_nic_packet, 0); if( status == 0 ) break; /* Good packet... */ dma_cache_maintenance((unsigned long)phys_nic_packet, 1520, 0); pkt_len = (nic_packet->l_hi << 8) | nic_packet->l_lo; lp->poll_time = bionet_min_poll_time; /* fast poll */ if( pkt_len >= 60 && pkt_len <= 1520 ) { /* ^^^^ war 1514 KHL */ /* Malloc up new buffer. */ struct sk_buff *skb = dev_alloc_skb( pkt_len + 2 ); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); lp->stats.rx_dropped++; break; } skb->dev = dev; skb_reserve( skb, 2 ); /* 16 Byte align */ skb_put( skb, pkt_len ); /* make room */ /* 'skb->data' points to the start of sk_buff data area. */ memcpy(skb->data, nic_packet->buffer, pkt_len); skb->protocol = eth_type_trans( skb, dev ); netif_rx(skb); dev->last_rx = jiffies; lp->stats.rx_packets++; lp->stats.rx_bytes+=pkt_len; /* If any worth-while packets have been received, dev_rint() has done a mark_bh(INET_BH) for us and will work on them when we get to the bottom-half routine. */ if (bionet_debug >1) { u_char *data = nic_packet->buffer, *p; int i; printk( "%s: RX pkt type 0x%4x from ", dev->name, ((u_short *)data)[6]); for( p = &data[6], i = 0; i < 6; i++ ) printk("%02x%s", *p++,i != 5 ? ":" : "" ); printk(" to "); for( p = data, i = 0; i < 6; i++ ) printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" ); printk( "%s: ", dev->name ); printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x" " %02x%02x%02x%02x len %d\n", data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], pkt_len ); } } else { printk(" Packet has wrong length: %04d bytes\n", pkt_len); lp->stats.rx_errors++; } } stdma_release(); ENABLE_IRQ(); return; }
static int bionet_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = netdev_priv(dev); unsigned long flags; /* Block a timer-based transmit from overlapping. This could better be * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ local_irq_save(flags); if (stdma_islocked()) { local_irq_restore(flags); lp->stats.tx_errors++; } else { int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned long buf = virt_to_phys(skb->data); int stat; stdma_lock(bionet_intr, NULL); local_irq_restore(flags); if( !STRAM_ADDR(buf+length-1) ) { memcpy(nic_packet->buffer, skb->data, length); buf = (unsigned long)&((struct nic_pkt_s *)phys_nic_packet)->buffer; } if (bionet_debug >1) { u_char *data = nic_packet->buffer, *p; int i; printk( "%s: TX pkt type 0x%4x from ", dev->name, ((u_short *)data)[6]); for( p = &data[6], i = 0; i < 6; i++ ) printk("%02x%s", *p++,i != 5 ? ":" : "" ); printk(" to "); for( p = data, i = 0; i < 6; i++ ) printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" ); printk( "%s: ", dev->name ); printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x" " %02x%02x%02x%02x len %d\n", data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], length ); } dma_cache_maintenance(buf, length, 1); stat = hardware_send_packet(buf, length); ENABLE_IRQ(); stdma_release(); dev->trans_start = jiffies; dev->tbusy = 0; lp->stats.tx_packets++; lp->stats.tx_bytes+=length; } dev_kfree_skb(skb); return 0; }