static inline void rds_regb (const hrz_dev * dev, unsigned char reg, void * addr, u32 len) { insb (dev->iobase + reg, addr, len); }
static inline void read_fifo_ipac(unsigned int adr, u_short off, u_char * data, int size) { byteout(adr, off); insb(adr + 4, data, size); }
static inline void readfifo(struct IsdnCardState *cs, unsigned int adr, u8 off, u8 *data, int size) { byteout(cs->hw.saphir.ale, off); insb(adr, data, size); }
static inline void readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size) { byteout(ale, off); insb(adr, data, size); }
/* controller interrupt */ static void elintr(void *arg) { int unit = (int)arg; struct el_softc *sc; int base; int stat, rxstat, len, done; lwkt_serialize_enter(&el_serializer); /* Get things pointing properly */ sc = &el_softc[unit]; base = sc->el_base; dprintf(("elintr: ")); /* Check board status */ stat = inb(base+EL_AS); if(stat & EL_AS_RXBUSY) { inb(base+EL_RXC); outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX)); lwkt_serialize_exit(&el_serializer); return; } done = 0; while(!done) { rxstat = inb(base+EL_RXS); if(rxstat & EL_RXS_STALE) { inb(base+EL_RXC); outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX)); lwkt_serialize_exit(&el_serializer); return; } /* If there's an overflow, reinit the board. */ if(!(rxstat & EL_RXS_NOFLOW)) { dprintf(("overflow.\n")); el_hardreset(sc); /* Put board back into receive mode */ if(sc->arpcom.ac_if.if_flags & IFF_PROMISC) outb(base+EL_RXC,(EL_RXC_PROMISC|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW)); else outb(base+EL_RXC,(EL_RXC_ABROAD|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW)); inb(base+EL_AS); outb(base+EL_RBC,0); inb(base+EL_RXC); outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX)); lwkt_serialize_exit(&el_serializer); return; } /* Incoming packet */ len = inb(base+EL_RBL); len |= inb(base+EL_RBH) << 8; dprintf(("receive len=%d rxstat=%x ",len,rxstat)); outb(base+EL_AC,EL_AC_HOST); /* If packet too short or too long, restore rx mode and return */ if((len <= sizeof(struct ether_header)) || (len > ETHER_MAX_LEN)) { if(sc->arpcom.ac_if.if_flags & IFF_PROMISC) outb(base+EL_RXC,(EL_RXC_PROMISC|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW)); else outb(base+EL_RXC,(EL_RXC_ABROAD|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW)); inb(base+EL_AS); outb(base+EL_RBC,0); inb(base+EL_RXC); outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX)); lwkt_serialize_exit(&el_serializer); return; } sc->arpcom.ac_if.if_ipackets++; /* Copy the data into our buffer */ outb(base+EL_GPBL,0); outb(base+EL_GPBH,0); insb(base+EL_BUF,sc->el_pktbuf,len); outb(base+EL_RBC,0); outb(base+EL_AC,EL_AC_RX); dprintf(("%6D-->",sc->el_pktbuf+6,":")); dprintf(("%6D\n",sc->el_pktbuf,":")); /* Pass data up to upper levels */ elread(sc,(caddr_t)(sc->el_pktbuf),len); /* Is there another packet? */ stat = inb(base+EL_AS); /* If so, do it all again (i.e. don't set done to 1) */ if(!(stat & EL_AS_RXBUSY)) dprintf(("<rescan> ")); else done = 1; } inb(base+EL_RXC); outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX)); lwkt_serialize_exit(&el_serializer); }
void fw_cfg_get(int entry, void *dst, int dstlen) { outw(entry, FW_CFG_PORT_CTL); insb(FW_CFG_PORT_DATA, dst, dstlen); }
/* ** Name: void el1_interrupt(dpeth_t *dep) ** Function: Interrupt handler. Acknwledges transmit interrupts ** or unloads receive buffer to memory queue. */ static void el1_interrupt(dpeth_t * dep) { u16_t csr, isr; int pktsize; buff_t *rxptr; csr = inb_el1(dep, EL1_CSR); if ((csr & ECSR_XMIT) && (dep->de_flags & DEF_XMIT_BUSY)) { /* Got a transmit interrupt */ isr = inb_el1(dep, EL1_XMIT); if ((isr & (EXSR_16JAM | EXSR_UNDER | EXSR_JAM)) || !(isr & EXSR_IDLE)) { DEBUG(printf("3c501: got xmit interrupt (ASR=0x%02X XSR=0x%02X)\n", csr, isr)); if (isr & EXSR_JAM) { /* Sending, packet got a collision */ dep->de_stat.ets_collision += 1; /* Put pointer back to beginning of packet */ outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_SYS); outw_el1(dep, EL1_XMITPTR, (EL1_BFRSIZ - TxBuff->size)); /* And retrigger transmission */ outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_XMIT); return; } else if ((isr & EXSR_16JAM) || !(isr & EXSR_IDLE)) { dep->de_stat.ets_sendErr += 1; } else if (isr & EXSR_UNDER) { dep->de_stat.ets_fifoUnder += 1; } DEBUG(printf("3c501: got xmit interrupt (0x%02X)\n", isr)); el1_reset(dep); } else { /** if (inw_el1(dep, EL1_XMITPTR) == EL1_BFRSIZ) **/ /* Packet transmitted successfully */ dep->de_stat.ets_packetT += 1; dep->bytes_Tx += (long) (TxBuff->size); free_buff(dep, TxBuff); dep->de_flags &= NOT(DEF_XMIT_BUSY); if ((dep->de_flags & DEF_SENDING) && dep->de_xmitq_head) { /* Pending transmit request available in queue */ el1_send(dep, TRUE, 0); if (dep->de_flags & (DEF_XMIT_BUSY | DEF_ACK_SEND)) return; } } } else if ((csr & (ECSR_RECV | ECSR_XMTBSY)) == (ECSR_RECV | ECSR_XMTBSY)) { /* Got a receive interrupt */ isr = inb_el1(dep, EL1_RECV); pktsize = inw_el1(dep, EL1_RECVPTR); if ((isr & ERSR_RERROR) || (isr & ERSR_STALE)) { DEBUG(printf("Rx0 (ASR=0x%02X RSR=0x%02X size=%d)\n", csr, isr, pktsize)); dep->de_stat.ets_recvErr += 1; } else if (pktsize < ETH_MIN_PACK_SIZE || pktsize > ETH_MAX_PACK_SIZE) { DEBUG(printf("Rx1 (ASR=0x%02X RSR=0x%02X size=%d)\n", csr, isr, pktsize)); dep->de_stat.ets_recvErr += 1; } else if ((rxptr = alloc_buff(dep, pktsize + sizeof(buff_t))) == NULL) { /* Memory not available. Drop packet */ dep->de_stat.ets_fifoOver += 1; } else if (isr & (ERSR_GOOD | ERSR_ANY)) { /* Got a good packet. Read it from buffer */ outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_SYS); outw_el1(dep, EL1_XMITPTR, 0); insb(dep->de_data_port, SELF, rxptr->buffer, pktsize); rxptr->next = NULL; rxptr->size = pktsize; dep->de_stat.ets_packetR += 1; dep->bytes_Rx += (long) pktsize; lock(); /* Queue packet to receive queue */ if (dep->de_recvq_head == NULL) dep->de_recvq_head = rxptr; else dep->de_recvq_tail->next = rxptr; dep->de_recvq_tail = rxptr; unlock(); /* Reply to pending Receive requests, if any */ el1_recv(dep, TRUE, 0); } } else { /* Nasty condition, should never happen */ DEBUG( printf("3c501: got interrupt with status 0x%02X\n" " de_flags=0x%04X XSR=0x%02X RSR=0x%02X \n" " xmit buffer = 0x%4X recv buffer = 0x%4X\n", csr, dep->de_flags, inb_el1(dep, EL1_RECV), inb_el1(dep, EL1_XMIT), inw_el1(dep, EL1_XMITPTR), inw_el1(dep, EL1_RECVPTR)) ); el1_reset(dep); } /* Move into receive mode */ outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_RECV); outw_el1(dep, EL1_RECVPTR, 0); /* Be sure that interrupts are cleared */ inb_el1(dep, EL1_RECV); inb_el1(dep, EL1_XMIT); return; }
static void mcd_poll(unsigned long dummy) { int st; if (mcd_error) { if (mcd_error & 0xA5) { printk(KERN_ERR "mcd: I/O error 0x%02x", mcd_error); if (mcd_error & 0x80) printk(" (Door open)"); if (mcd_error & 0x20) printk(" (Disk changed)"); if (mcd_error & 0x04) { printk(" (Read error)"); /* Bitch about the problem. */ /* Time to get fancy! If at 2x speed and 1 error, drop to 1x speed! */ /* Interesting how it STAYS at MCD_RETRY_ATTEMPTS on first error! */ /* But I find that rather HANDY!!! */ /* Neat! it REALLY WORKS on those LOW QUALITY CD's!!! Smile! :) */ /* AJK [06/17/95] */ /* Slap the CD down to single speed! */ if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_2X_READ) { MCMD_DATA_READ = MCMD_PLAY_READ; /* Uhhh, Ummmm, muhuh-huh! */ mcd1xhold = SINGLE_HOLD_SECTORS; /* Hey Beavis! */ printk(" Speed now 1x"); /* Pull my finger! */ } } printk("\n"); mcd_invalidate_buffers(); #ifdef WARN_IF_READ_FAILURE if (McdTries == MCD_RETRY_ATTEMPTS) printk(KERN_ERR "mcd: read of block %d failed\n", mcd_next_bn); #endif if (!McdTries--) { /* Nuts! This cd is ready for recycling! */ /* When WAS the last time YOU cleaned it CORRECTLY?! */ printk(KERN_ERR "mcd: read of block %d failed, giving up\n", mcd_next_bn); if (mcd_transfer_is_active) { McdTries = 0; goto ret; } if (CURRENT_VALID) end_request(0); McdTries = MCD_RETRY_ATTEMPTS; } } mcd_error = 0; mcd_state = MCD_S_STOP; } /* Switch back to Double speed if enough GOOD sectors were read! */ /* Are we a double speed with a crappy CD?! */ if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_PLAY_READ) { /* We ARE a double speed and we ARE bitching! */ if (mcd1xhold == 0) { /* Okay, Like are we STILL at single speed? *//* We need to switch back to double speed now... */ MCMD_DATA_READ = MCMD_2X_READ; /* Uhhh... BACK You GO! */ printk(KERN_INFO "mcd: Switching back to 2X speed!\n"); /* Tell 'em! */ } else mcd1xhold--; /* No?! Count down the good reads some more... */ /* and try, try again! */ } immediately: switch (mcd_state) { case MCD_S_IDLE: test3(printk("MCD_S_IDLE\n")); goto out; case MCD_S_START: test3(printk("MCD_S_START\n")); outb(MCMD_GET_STATUS, MCDPORT(0)); mcd_state = mcd_mode == 1 ? MCD_S_READ : MCD_S_MODE; McdTimeout = 3000; break; case MCD_S_MODE: test3(printk("MCD_S_MODE\n")); if ((st = mcdStatus()) != -1) { if (st & MST_DSK_CHG) { mcdDiskChanged = 1; tocUpToDate = 0; mcd_invalidate_buffers(); } set_mode_immediately: if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) { mcdDiskChanged = 1; tocUpToDate = 0; if (mcd_transfer_is_active) { mcd_state = MCD_S_START; goto immediately; } printk(KERN_INFO); printk((st & MST_DOOR_OPEN) ? "mcd: door open\n" : "mcd: disk removed\n"); mcd_state = MCD_S_IDLE; while (CURRENT_VALID) end_request(0); goto out; } outb(MCMD_SET_MODE, MCDPORT(0)); outb(1, MCDPORT(0)); mcd_mode = 1; mcd_state = MCD_S_READ; McdTimeout = 3000; } break; case MCD_S_READ: test3(printk("MCD_S_READ\n")); if ((st = mcdStatus()) != -1) { if (st & MST_DSK_CHG) { mcdDiskChanged = 1; tocUpToDate = 0; mcd_invalidate_buffers(); } read_immediately: if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) { mcdDiskChanged = 1; tocUpToDate = 0; if (mcd_transfer_is_active) { mcd_state = MCD_S_START; goto immediately; } printk(KERN_INFO); printk((st & MST_DOOR_OPEN) ? "mcd: door open\n" : "mcd: disk removed\n"); mcd_state = MCD_S_IDLE; while (CURRENT_VALID) end_request(0); goto out; } if (CURRENT_VALID) { struct mcd_Play_msf msf; mcd_next_bn = CURRENT->sector / 4; hsg2msf(mcd_next_bn, &msf.start); msf.end.min = ~0; msf.end.sec = ~0; msf.end.frame = ~0; sendMcdCmd(MCMD_DATA_READ, &msf); mcd_state = MCD_S_DATA; McdTimeout = READ_TIMEOUT; } else { mcd_state = MCD_S_STOP; goto immediately; } } break; case MCD_S_DATA: test3(printk("MCD_S_DATA\n")); st = inb(MCDPORT(1)) & (MFL_STATUSorDATA); data_immediately: test5(printk("Status %02x\n", st)) switch (st) { case MFL_DATA: #ifdef WARN_IF_READ_FAILURE if (McdTries == 5) printk(KERN_WARNING "mcd: read of block %d failed\n", mcd_next_bn); #endif if (!McdTries--) { printk(KERN_ERR "mcd: read of block %d failed, giving up\n", mcd_next_bn); if (mcd_transfer_is_active) { McdTries = 0; break; } if (CURRENT_VALID) end_request(0); McdTries = 5; } mcd_state = MCD_S_START; McdTimeout = READ_TIMEOUT; goto immediately; case MFL_STATUSorDATA: break; default: McdTries = 5; if (!CURRENT_VALID && mcd_buf_in == mcd_buf_out) { mcd_state = MCD_S_STOP; goto immediately; } mcd_buf_bn[mcd_buf_in] = -1; insb(MCDPORT(0), mcd_buf + 2048 * mcd_buf_in, 2048); mcd_buf_bn[mcd_buf_in] = mcd_next_bn++; if (mcd_buf_out == -1) mcd_buf_out = mcd_buf_in; mcd_buf_in = mcd_buf_in + 1 == MCD_BUF_SIZ ? 0 : mcd_buf_in + 1; if (!mcd_transfer_is_active) { while (CURRENT_VALID) { mcd_transfer(); if (CURRENT->nr_sectors == 0) end_request(1); else break; } } if (CURRENT_VALID && (CURRENT->sector / 4 < mcd_next_bn || CURRENT->sector / 4 > mcd_next_bn + 16)) { mcd_state = MCD_S_STOP; goto immediately; } McdTimeout = READ_TIMEOUT; { int count = QUICK_LOOP_COUNT; while (count--) { QUICK_LOOP_DELAY; if ((st = (inb(MCDPORT(1))) & (MFL_STATUSorDATA)) != (MFL_STATUSorDATA)) { test4(printk(" %d ", QUICK_LOOP_COUNT - count)); goto data_immediately; } } test4(printk("ended ")); } break; } break; case MCD_S_STOP: test3(printk("MCD_S_STOP\n")); if (!mitsumi_bug_93_wait) goto do_not_work_around_mitsumi_bug_93_1; McdTimeout = mitsumi_bug_93_wait; mcd_state = 9 + 3 + 1; break; case 9 + 3 + 1: if (McdTimeout) break; do_not_work_around_mitsumi_bug_93_1: outb(MCMD_STOP, MCDPORT(0)); if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) { int i = 4096; do { inb(MCDPORT(0)); } while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS && --i); outb(MCMD_STOP, MCDPORT(0)); if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) { i = 4096; do { inb(MCDPORT(0)); } while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS && --i); outb(MCMD_STOP, MCDPORT(0)); } } mcd_state = MCD_S_STOPPING; McdTimeout = 1000; break; case MCD_S_STOPPING: test3(printk("MCD_S_STOPPING\n")); if ((st = mcdStatus()) == -1 && McdTimeout) break; if ((st != -1) && (st & MST_DSK_CHG)) { mcdDiskChanged = 1; tocUpToDate = 0; mcd_invalidate_buffers(); } if (!mitsumi_bug_93_wait) goto do_not_work_around_mitsumi_bug_93_2; McdTimeout = mitsumi_bug_93_wait; mcd_state = 9 + 3 + 2; break; case 9 + 3 + 2: if (McdTimeout) break; st = -1; do_not_work_around_mitsumi_bug_93_2: test3(printk("CURRENT_VALID %d mcd_mode %d\n", CURRENT_VALID, mcd_mode)); if (CURRENT_VALID) { if (st != -1) { if (mcd_mode == 1) goto read_immediately; else goto set_mode_immediately; } else { mcd_state = MCD_S_START; McdTimeout = 1; } } else { mcd_state = MCD_S_IDLE; goto out; } break; default: printk(KERN_ERR "mcd: invalid state %d\n", mcd_state); goto out; } ret: if (!McdTimeout--) { printk(KERN_WARNING "mcd: timeout in state %d\n", mcd_state); mcd_state = MCD_S_STOP; } mcd_timer.function = mcd_poll; mod_timer(&mcd_timer, jiffies + 1); out: return; }
/*---------------------------------------------------------------------------* * AVM read fifo routines *---------------------------------------------------------------------------*/ #ifdef __FreeBSD__ static int PCMCIA_IO_BASE = 0; /* ap: XXX hack */ static void avma1_pcmcia_read_fifo(void *buf, const void *base, size_t len) { outb(PCMCIA_IO_BASE + ADDR_REG_OFFSET, (int)base - 0x20); insb(PCMCIA_IO_BASE + DATA_REG_OFFSET, (u_char *)buf, (u_int)len); }
static inline void ipac_readfifo(struct IsdnCardState *cs, u8 off, u8 * data, int size) { byteout(cs->hw.asus.adr, off); insb(cs->hw.asus.isac, data, size); }
static void ioport_read8r(void __iomem *addr, void *dst, unsigned long count) { insb(ADDR2PORT(addr), dst, count); }
static void sws_read_fifo(void *buf, const void *base, size_t len) { outb(SWS_IDO(base),SWS_REG(base,0)); insb(SWS_ADDR(base),buf,len); }
static inline int generic_NCR5380_pread(struct NCR5380_hostdata *hostdata, unsigned char *dst, int len) { int blocks = len / 128; int start = 0; NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR); NCR5380_write(hostdata->c400_blk_cnt, blocks); while (1) { if (NCR5380_read(hostdata->c400_blk_cnt) == 0) break; if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) { printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); return -1; } while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) ; /* FIXME - no timeout */ if (hostdata->io_port && hostdata->io_width == 2) insw(hostdata->io_port + hostdata->c400_host_buf, dst + start, 64); else if (hostdata->io_port) insb(hostdata->io_port + hostdata->c400_host_buf, dst + start, 128); else memcpy_fromio(dst + start, hostdata->io + NCR53C400_host_buffer, 128); start += 128; blocks--; } if (blocks) { while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) ; /* FIXME - no timeout */ if (hostdata->io_port && hostdata->io_width == 2) insw(hostdata->io_port + hostdata->c400_host_buf, dst + start, 64); else if (hostdata->io_port) insb(hostdata->io_port + hostdata->c400_host_buf, dst + start, 128); else memcpy_fromio(dst + start, hostdata->io + NCR53C400_host_buffer, 128); start += 128; blocks--; } if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) printk("53C400r: no 53C80 gated irq after transfer"); /* wait for 53C80 registers to be available */ while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) ; if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) printk(KERN_ERR "53C400r: no end dma signal\n"); return 0; }
static void tels0163_read_fifo(void *buf, const void *base, size_t len) { insb((int)base + 0x3e, (u_char *)buf, (u_int)len); }
static inline void ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size) { byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_FIFO_OFFSET); insb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size); }
static void avma1_read_fifo(void *buf, const void *base, size_t len) { insb((int)base - 0x3e0, (u_char *)buf, (u_int)len); }
/* * We have a good packet(s), get it/them out of the buffers. */ static void cops_rx(struct net_device *dev) { int pkt_len = 0; int rsp_type = 0; struct sk_buff *skb = NULL; struct cops_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int boguscount = 0; unsigned long flags; spin_lock_irqsave(&lp->lock, flags); if(lp->board==DAYNA) { outb(0, ioaddr); /* Send out Zero length. */ outb(0, ioaddr); outb(DATA_READ, ioaddr); /* Send read command out. */ /* Wait for DMA to turn around. */ while(++boguscount<1000000) { barrier(); if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_READY) break; } if(boguscount==1000000) { printk(KERN_WARNING "%s: DMA timed out.\n",dev->name); spin_unlock_irqrestore(&lp->lock, flags); return; } } /* Get response length. */ if(lp->board==DAYNA) pkt_len = inb(ioaddr) & 0xFF; else pkt_len = inb(ioaddr) & 0x00FF; pkt_len |= (inb(ioaddr) << 8); /* Input IO code. */ rsp_type=inb(ioaddr); /* Malloc up new buffer. */ skb = dev_alloc_skb(pkt_len); if(skb == NULL) { printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); dev->stats.rx_dropped++; while(pkt_len--) /* Discard packet */ inb(ioaddr); spin_unlock_irqrestore(&lp->lock, flags); return; } skb->dev = dev; skb_put(skb, pkt_len); skb->protocol = htons(ETH_P_LOCALTALK); insb(ioaddr, skb->data, pkt_len); /* Eat the Data */ if(lp->board==DAYNA) outb(1, ioaddr+DAYNA_INT_CARD); /* Interrupt the card */ spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */ /* Check for bad response length */ if(pkt_len < 0 || pkt_len > MAX_LLAP_SIZE) { printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n", dev->name, pkt_len); dev->stats.tx_errors++; dev_kfree_skb_any(skb); return; } /* Set nodeid and then get out. */ if(rsp_type == LAP_INIT_RSP) { /* Nodeid taken from received packet. */ lp->node_acquire = skb->data[0]; dev_kfree_skb_any(skb); return; } /* One last check to make sure we have a good packet. */ if(rsp_type != LAP_RESPONSE) { printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type); dev->stats.tx_errors++; dev_kfree_skb_any(skb); return; } skb_reset_mac_header(skb); /* Point to entire packet. */ skb_pull(skb,3); skb_reset_transport_header(skb); /* Point to data (Skip header). */ /* Update the counters. */ dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; /* Send packet to a higher place. */ netif_rx(skb); }
static void epread(struct ep_softc *sc) { struct mbuf *top, *mcur, *m; struct ifnet *ifp; int lenthisone; short rx_fifo2, status; short rx_fifo; ifp = &sc->arpcom.ac_if; status = inw(BASE + EP_W1_RX_STATUS); read_again: if (status & ERR_RX) { IFNET_STAT_INC(ifp, ierrors, 1); if (status & ERR_RX_OVERRUN) { /* * we can think the rx latency is actually greather than we * expect */ #ifdef EP_LOCAL_STATS if (EP_FTST(sc, F_RX_FIRST)) sc->rx_overrunf++; else sc->rx_overrunl++; #endif } goto out; } rx_fifo = rx_fifo2 = status & RX_BYTES_MASK; if (EP_FTST(sc, F_RX_FIRST)) { m = m_getl(rx_fifo, MB_DONTWAIT, MT_DATA, M_PKTHDR, NULL); if (!m) goto out; sc->top = sc->mcur = top = m; #define EROUND ((sizeof(struct ether_header) + 3) & ~3) #define EOFF (EROUND - sizeof(struct ether_header)) top->m_data += EOFF; /* Read what should be the header. */ insw(BASE + EP_W1_RX_PIO_RD_1, mtod(top, caddr_t), sizeof(struct ether_header) / 2); top->m_len = sizeof(struct ether_header); rx_fifo -= sizeof(struct ether_header); sc->cur_len = rx_fifo2; } else { /* come here if we didn't have a complete packet last time */ top = sc->top; m = sc->mcur; sc->cur_len += rx_fifo2; } /* Reads what is left in the RX FIFO */ while (rx_fifo > 0) { lenthisone = min(rx_fifo, M_TRAILINGSPACE(m)); if (lenthisone == 0) { /* no room in this one */ mcur = m; m = m_getl(rx_fifo, MB_DONTWAIT, MT_DATA, 0, NULL); if (!m) goto out; m->m_len = 0; mcur->m_next = m; lenthisone = min(rx_fifo, M_TRAILINGSPACE(m)); } if (EP_FTST(sc, F_ACCESS_32_BITS)) { /* default for EISA configured cards*/ insl(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len, lenthisone / 4); m->m_len += (lenthisone & ~3); if (lenthisone & 3) insb(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len, lenthisone & 3); m->m_len += (lenthisone & 3); } else { insw(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len, lenthisone / 2); m->m_len += lenthisone; if (lenthisone & 1) *(mtod(m, caddr_t) + m->m_len - 1) = inb(BASE + EP_W1_RX_PIO_RD_1); } rx_fifo -= lenthisone; } if (status & ERR_RX_INCOMPLETE) { /* we haven't received the complete * packet */ sc->mcur = m; #ifdef EP_LOCAL_STATS sc->rx_no_first++; /* to know how often we come here */ #endif EP_FRST(sc, F_RX_FIRST); if (!((status = inw(BASE + EP_W1_RX_STATUS)) & ERR_RX_INCOMPLETE)) { /* we see if by now, the packet has completly arrived */ goto read_again; } outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_NEXT_EARLY_THRESH); return; } outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); IFNET_STAT_INC(ifp, ipackets, 1); EP_FSET(sc, F_RX_FIRST); top->m_pkthdr.rcvif = &sc->arpcom.ac_if; top->m_pkthdr.len = sc->cur_len; ifp->if_input(ifp, top); sc->top = 0; while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS); outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH); return; out: outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); if (sc->top) { m_freem(sc->top); sc->top = 0; #ifdef EP_LOCAL_STATS sc->rx_no_mbuf++; #endif } EP_FSET(sc, F_RX_FIRST); while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS); outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH); }
static int mcdx_xfer(struct s_drive_stuff *stuffp, char *p, int sector, int nr_sectors) /* This does actually the transfer from the drive. Return: -1 on timeout or other error else status byte (as in stuff->st) */ { int border; int done = 0; long timeout; if (stuffp->audio) { xwarn("Attempt to read from audio CD.\n"); return -1; } if (!stuffp->readcmd) { xinfo("Can't transfer from missing disk.\n"); return -1; } while (stuffp->lock) { interruptible_sleep_on(&stuffp->lockq); } if (stuffp->valid && (sector >= stuffp->pending) && (sector < stuffp->low_border)) { /* All (or at least a part of the sectors requested) seems * to be already requested, so we don't need to bother the * drive with new requests ... * Wait for the drive become idle, but first * check for possible occurred errors --- the drive * seems to report them asynchronously */ border = stuffp->high_border < (border = sector + nr_sectors) ? stuffp->high_border : border; stuffp->lock = current->pid; do { while (stuffp->busy) { timeout = interruptible_sleep_on_timeout (&stuffp->busyq, 5 * HZ); if (!stuffp->introk) { xtrace(XFER, "error via interrupt\n"); } else if (!timeout) { xtrace(XFER, "timeout\n"); } else if (signal_pending(current)) { xtrace(XFER, "signal\n"); } else continue; stuffp->lock = 0; stuffp->busy = 0; stuffp->valid = 0; wake_up_interruptible(&stuffp->lockq); xtrace(XFER, "transfer() done (-1)\n"); return -1; } /* check if we need to set the busy flag (as we * expect an interrupt */ stuffp->busy = (3 == (stuffp->pending & 3)); /* Test if it's the first sector of a block, * there we have to skip some bytes as we read raw data */ if (stuffp->xa && (0 == (stuffp->pending & 3))) { const int HEAD = CD_FRAMESIZE_RAW - CD_XA_TAIL - CD_FRAMESIZE; insb(stuffp->rreg_data, p, HEAD); } /* now actually read the data */ insb(stuffp->rreg_data, p, 512); /* test if it's the last sector of a block, * if so, we have to handle XA special */ if ((3 == (stuffp->pending & 3)) && stuffp->xa) { char dummy[CD_XA_TAIL]; insb(stuffp->rreg_data, &dummy[0], CD_XA_TAIL); } if (stuffp->pending == sector) { p += 512; done++; sector++; } } while (++(stuffp->pending) < border); stuffp->lock = 0; wake_up_interruptible(&stuffp->lockq); } else { /* The requested sector(s) is/are out of the * already requested range, so we have to bother the drive * with a new request. */ static unsigned char cmd[] = { 0, 0, 0, 0, 0, 0, 0 }; cmd[0] = stuffp->readcmd; /* The numbers held in ->pending, ..., should be valid */ stuffp->valid = 1; stuffp->pending = sector & ~3; /* do some sanity checks */ if (stuffp->pending > stuffp->lastsector) { xwarn ("transfer() sector %d from nirvana requested.\n", stuffp->pending); stuffp->status = MCDX_ST_EOM; stuffp->valid = 0; xtrace(XFER, "transfer() done (-1)\n"); return -1; } if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE) > stuffp->lastsector + 1) { xtrace(XFER, "cut low_border\n"); stuffp->low_border = stuffp->lastsector + 1; } if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE) > stuffp->lastsector + 1) { xtrace(XFER, "cut high_border\n"); stuffp->high_border = stuffp->lastsector + 1; } { /* Convert the sector to be requested to MSF format */ struct cdrom_msf0 pending; log2msf(stuffp->pending / 4, &pending); cmd[1] = pending.minute; cmd[2] = pending.second; cmd[3] = pending.frame; } cmd[6] = (unsigned char) ((stuffp->high_border - stuffp->pending) / 4); xtrace(XFER, "[%2d]\n", cmd[6]); stuffp->busy = 1; /* Now really issue the request command */ outsb(stuffp->wreg_data, cmd, sizeof cmd); } #ifdef AK2 if (stuffp->int_err) { stuffp->valid = 0; stuffp->int_err = 0; return -1; } #endif /* AK2 */ stuffp->low_border = (stuffp->low_border += done) < stuffp->high_border ? stuffp->low_border : stuffp->high_border; return done; }
static void qemu_cfg_read(u8 *buf, int len) { insb(PORT_QEMU_CFG_DATA, buf, len); }
static inline void read_fifo(unsigned int adr, u_char * data, int size) { insb(adr, data, size); }
static void dynalink_read_fifo(void *buf, const void *base, size_t len) { outb(IOBASE(base)+ADDR, 0+IS_HSCXB_HACK(base)); insb(IOADDR(base), (u_char *)buf, (u_int)len); }
static void ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size) { insb(cs->hw.w6692.iobase + W_D_RFIFO, data, size); }
void x86_bus_space_io_read_multi_1(bus_space_handle_t h, bus_size_t o, u_int8_t *ptr, bus_size_t cnt) { insb(h + o, ptr, cnt); }