Linux????????????????????????+??·??
???????????? ???????[ 2012/12/25 10:21:35 ] ????????
????ei_receive()????
static void ei_receive(struct device *dev)
{
int e8390_base = dev->base_addr;
struct ei_device *ei_local = (struct ei_device *) dev->priv;
int rxing_page?? this_frame?? next_frame?? current_offset;
int rx_pkt_count = 0;
struct e8390_pkt_hdr rx_frame;
int num_rx_pages = ei_local->stop_page-ei_local->rx_start_page;
while (++rx_pkt_count < 10) {
int pkt_len;
/* Get the rx page (incoming packet pointer). */
outb_p(E8390_NODMA+E8390_PAGE1?? e8390_base + E8390_CMD);
rxing_page = inb_p(e8390_base + EN1_CURPAG);
outb_p(E8390_NODMA+E8390_PAGE0?? e8390_base + E8390_CMD);
/* Remove one frame from the ring. Boundary is always a page behind. */
this_frame = inb_p(e8390_base + EN0_BOUNDARY) + 1;
if (this_frame >= ei_local->stop_page)
this_frame = ei_local->rx_start_page;
/* Someday we'll omit the previous?? iff we never get this message.
(There is at least one clone claimed to have a problem.) */
if (ei_debug > 0 && this_frame != ei_local->current_page)
printk("%s: mismatched read page pointers %2x vs %2x.
"??
dev->name?? this_frame?? ei_local->current_page);
if (this_frame == rxing_page) /* Read all the frames? */
break; /* Done for now */
current_offset = this_frame << 8;
ei_block_input(dev?? sizeof(rx_frame)?? (char *)&rx_frame??
current_offset);
pkt_len = rx_frame.count - sizeof(rx_frame);
next_frame = this_frame + 1 + ((pkt_len+4)>>8);
/* Check for bogosity warned by 3c503 book: the status byte is never
written. This happened a lot during testing! This code should be
cleaned up someday. */
if (rx_frame.next != next_frame
&& rx_frame.next != next_frame + 1
&& rx_frame.next != next_frame - num_rx_pages
&& rx_frame.next != next_frame + 1 - num_rx_pages) {
ei_local->current_page = rxing_page;
outb(ei_local->current_page-1?? e8390_base+EN0_BOUNDARY);
ei_local->stat.rx_errors++;
continue;
}
if (pkt_len < 60 || pkt_len > 1518) {
if (ei_debug)
printk("%s: bogus packet size: %d?? status=%#2x nxpg=%#2x.
"??
dev->name?? rx_frame.count?? rx_frame.status??
rx_frame.next);
ei_local->stat.rx_errors++;
} else if ((rx_frame.status & 0x0F) == ENRSR_RXOK) {
struct sk_buff *skb;
skb = alloc_skb(pkt_len?? GFP_ATOMIC);
if (skb == NULL) {
if (ei_debug > 1)
printk("%s: Couldn't allocate a sk_buff of size %d.
"??
dev->name?? pkt_len);
ei_local->stat.rx_dropped++;
break;
} else {
skb->len = pkt_len;
skb->dev = dev;
ei_block_input(dev?? pkt_len?? (char *) skb->data??
current_offset + sizeof(rx_frame));
netif_rx(skb);
ei_local->stat.rx_packets++;
}
} else {
int errs = rx_frame.status;
if (ei_debug)
printk("%s: bogus packet: status=%#2x nxpg=%#2x size=%d
"??
dev->name?? rx_frame.status?? rx_frame.next??
rx_frame.count);
if (errs & ENRSR_FO)
ei_local->stat.rx_fifo_errors++;
}
next_frame = rx_frame.next;
/* This _should_ never happen: it's here for avoiding bad clones. */
if (next_frame >= ei_local->stop_page) {
printk("%s: next frame inconsistency?? %#2x
"?? dev->name??
next_frame);
next_frame = ei_local->rx_start_page;
}
ei_local->current_page = next_frame;
outb_p(next_frame-1?? e8390_base+EN0_BOUNDARY);
}
/* If any worth-while packets have been received?? dev_rint()
has done a mark_bh(NET_BH) for us and will work on them
when we get to the bottom-half routine. */
/* Record the maximum Rx packet queue. */
if (rx_pkt_count > high_water_mark)
high_water_mark = rx_pkt_count;
/* Bug alert! Reset ENISR_OVER to avoid spurious overruns! */
outb_p(ENISR_RX+ENISR_RX_ERR+ENISR_OVER?? e8390_base+EN0_ISR);
return;
}
????????????http://blog.csdn.net/yming0221/article/details/7492423
??????
???·???
??????????????????
2023/3/23 14:23:39???д?ò??????????
2023/3/22 16:17:39????????????????????Щ??
2022/6/14 16:14:27??????????????????????????
2021/10/18 15:37:44???????????????
2021/9/17 15:19:29???·???????·
2021/9/14 15:42:25?????????????
2021/5/28 17:25:47??????APP??????????
2021/5/8 17:01:11