static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev) { struct sk_buff *skb = si->rxskb; dma_addr_t dma_addr; unsigned int len, stat, data; if (!skb) { printk(KERN_ERR "sa1100_ir: SKB is NULL!\n"); return; } /* * Get the current data position. */ dma_addr = sa1100_get_dma_pos(si->rxdma); len = dma_addr - si->rxbuf_dma; if (len > HPSIR_MAX_RXLEN) len = HPSIR_MAX_RXLEN; dma_unmap_single(si->dev, si->rxbuf_dma, len, DMA_FROM_DEVICE); do { /* * Read Status, and then Data. */ stat = Ser2HSSR1; rmb(); data = Ser2HSDR; if (stat & (HSSR1_CRE | HSSR1_ROR)) { si->stats.rx_errors++; if (stat & HSSR1_CRE) si->stats.rx_crc_errors++; if (stat & HSSR1_ROR) si->stats.rx_frame_errors++; } else skb->data[len++] = data; /* * If we hit the end of frame, there's * no point in continuing. */ if (stat & HSSR1_EOF) break; } while (Ser2HSSR0 & HSSR0_EIF); if (stat & HSSR1_EOF) { si->rxskb = NULL; skb_put(skb, len); skb->dev = dev; skb->mac.raw = skb->data; skb->protocol = htons(ETH_P_IRDA); si->stats.rx_packets++; si->stats.rx_bytes += len; /* * Before we pass the buffer up, allocate a new one. */ sa1100_irda_rx_alloc(si); netif_rx(skb); dev->last_rx = jiffies; } else { /* * Remap the buffer. */ si->rxbuf_dma = dma_map_single(si->dev, si->rxskb->data, HPSIR_MAX_RXLEN, DMA_FROM_DEVICE); } }
void ep1_int_hndlr() { dma_addr_t dma_addr; unsigned int len; int status = Ser0UDCCS1; PRINTKD( "[%lu]Ep1 int %d\n", (jiffies-start_time)*10, status); if ( naking ) printk( "%sEh? in ISR but naking = %d\n", "usbrx: ", naking ); // Reive packet complete if (status & UDCCS1_RPC) { if (!ep1_curdmalen) { printk("usb_recv: RPC for non-existent buffer\n"); naking = 1; return; } sa1100_stop_dma(dmachn_rx); if (status & UDCCS1_SST) { printk("usb_recv: stall sent OMP=%d\n",Ser0UDCOMP); UDC_flip(Ser0UDCCS1, UDCCS1_SST); ep1_done(-EIO); // UDC aborted current transfer, so we do return; } if (status & UDCCS1_RPE) { printk("usb_recv: RPError %x\n", status); UDC_flip(Ser0UDCCS1, UDCCS1_RPC); ep1_done(-EIO); return; } dma_addr = sa1100_get_dma_pos(dmachn_rx); pci_unmap_single(NULL, ep1_curdmapos, ep1_curdmalen, PCI_DMA_FROMDEVICE); len = dma_addr - ep1_curdmapos; if (len < ep1_curdmalen) { char *buf = ep1_curdmabuf + len; while (Ser0UDCCS1 & UDCCS1_RNE) { if (len >= ep1_curdmalen) { printk("usb_recv: too much data in fifo\n"); break; } *buf++ = Ser0UDCDR; len++; } } else if (Ser0UDCCS1 & UDCCS1_RNE) { printk("usb_recv: fifo screwed, shouldn't contain data\n"); len = 0; } ep1_curdmalen = 0; /* dma unmap already done */ ep1_remain -= len; naking = 1; ep1_done((len) ? 0 : -EPIPE); } /* else, you can get here if we are holding NAK */ }