static void hdlc_fill_fifo(struct fritz_bcs *bcs) { struct fritz_adapter *adapter = bcs->adapter; struct sk_buff *skb = bcs->tx_skb; int count; int fifo_size = 32; unsigned long flags; unsigned char *p; DBG(0x40, "hdlc_fill_fifo"); if (!skb) BUG(); if (skb->len == 0) BUG(); bcs->ctrl.sr.cmd &= ~HDLC_CMD_XME; if (bcs->tx_skb->len > fifo_size) { count = fifo_size; } else { count = bcs->tx_skb->len; if (bcs->mode != L1_MODE_TRANS) bcs->ctrl.sr.cmd |= HDLC_CMD_XME; } DBG(0x40, "hdlc_fill_fifo %d/%d", count, bcs->tx_skb->len); p = bcs->tx_skb->data; skb_pull(bcs->tx_skb, count); bcs->tx_cnt += count; bcs->ctrl.sr.xml = ((count == fifo_size) ? 0 : count); switch (adapter->type) { case AVM_FRITZ_PCI: spin_lock_irqsave(&adapter->hw_lock, flags); // sets the correct AVM_INDEX, too __fcpci_write_ctrl(bcs, 3); outsl(adapter->io + AVM_DATA + HDLC_FIFO, p, (count + 3) / 4); spin_unlock_irqrestore(&adapter->hw_lock, flags); break; case AVM_FRITZ_PCIV2: fcpci2_write_ctrl(bcs, 3); outsl(adapter->io + (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1), p, (count + 3) / 4); break; case AVM_FRITZ_PNP: spin_lock_irqsave(&adapter->hw_lock, flags); // sets the correct AVM_INDEX, too __fcpnp_write_ctrl(bcs, 3); outsb(adapter->io + AVM_DATA, p, count); spin_unlock_irqrestore(&adapter->hw_lock, flags); break; } }
void playSound(void) { int i; //遍历声卡DMA的描述符列表,初始化每一个描述符buf指向缓冲队列中第一个音乐的数据块 //每个数据块大小: DMA_BUF_SIZE for (i = 0; i < DMA_BUF_NUM; i++) { descriTable[i].buf = (uint)(soundQueue->data) + i * DMA_BUF_SIZE; descriTable[i].cmd_len = 0x80000000 + DMA_SMP_NUM; } uint base = (uint)descriTable; //开始播放: PCM_OUT if ((soundQueue->flag & PCM_OUT) == PCM_OUT) { //init base register //将内存地址base开始的1个双字写到PO_BDBAR outsl(PO_BDBAR, &base, 1); //init last valid index outb(PO_LVI, 0x1F); //init control register //run audio //enable interrupt outb(PO_CR, 0x05); } //开始录音: Mic_IN else if ((soundQueue->flag & PCM_IN) == PCM_IN) { //init register //将内存地址base开始的1个双字写到PO_BDBAR outsl(MC_BDBAR, &base, 1); //init last valid index outb(MC_LVI, 0x1F); //init control register //run audio //enable interrupt outb(MC_CR, 0x05); } }
/* Write 'count' bytes from 'src' buffer to SPI. */ unsigned int ssa_spi_write_multi (unsigned char *src, int count) { unsigned int quadlet_count; unsigned char *src_end = &src[count]; if (DEBUG_LEVEL > 1) printk ("%s: src:0x%08lx, count:%4d\n", __FUNCTION__, (unsigned long) src, count); while ((((unsigned long) src) & 0x03) && (src < src_end)) writeb (*src++, IO_ADDRESS_EPLD_BASE); quadlet_count = ((src_end - src) / 4); outsl (IO_ADDRESS_EPLD_BASE, src, quadlet_count); src += (quadlet_count * 4); while (src < src_end) writeb (*src++, IO_ADDRESS_EPLD_BASE); return 0; }
/* * This is used for most PIO data transfers *to* the IDE interface */ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; unsigned long data_addr = io_ports->data_addr; unsigned int words = (len + 1) >> 1; u8 io_32bit = drive->io_32bit; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; if (io_32bit) { unsigned long uninitialized_var(flags); if ((io_32bit & 2) && !mmio) { local_irq_save_nort(flags); ata_vlb_sync(io_ports->nsect_addr); } words >>= 1; if (mmio) __ide_mm_outsl((void __iomem *)data_addr, buf, words); else outsl(data_addr, buf, words); if ((io_32bit & 2) && !mmio) local_irq_restore_nort(flags); if (((len + 1) & 3) < 2) return; buf += len & ~3; words = 1; } if (mmio) __ide_mm_outsw((void __iomem *)data_addr, buf, words); else outsw(data_addr, buf, words); }
static void ide_outsl (unsigned long port, void *addr, u32 count) { outsl(port, addr, count); }
wstdcall void WRAP_EXPORT(WRITE_PORT_BUFFER_ULONG) (ULONG_PTR port, ULONG *buf, ULONG count) { outsl(port, buf, count); }
static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n) { outsl(ADDR2PORT(addr), s, n); }
static void ep_if_start(struct ifnet *ifp, struct ifaltq_subque *ifsq) { struct ep_softc *sc = ifp->if_softc; u_int len; struct mbuf *m; struct mbuf *top; int pad; ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq); if (sc->gone) { ifq_purge(&ifp->if_snd); return; } while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS); if (ifq_is_oactive(&ifp->if_snd)) { return; } crit_enter(); startagain: /* Sneak a peek at the next packet */ m = ifq_dequeue(&ifp->if_snd, NULL); if (m == NULL) { crit_exit(); return; } for (len = 0, top = m; m; m = m->m_next) len += m->m_len; m = top; pad = padmap[len & 3]; /* * The 3c509 automatically pads short packets to minimum ethernet length, * but we drop packets that are too large. Perhaps we should truncate * them instead? */ if (len + pad > ETHER_MAX_LEN) { /* packet is obviously too large: toss it */ IFNET_STAT_INC(ifp, oerrors, 1); m_freem(m); goto readcheck; } if (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) { /* no room in FIFO */ outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4)); /* make sure */ if (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) { ifq_set_oactive(&ifp->if_snd); ifq_prepend(&ifp->if_snd, top); crit_exit(); return; } } else { outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE); } outw(BASE + EP_W1_TX_PIO_WR_1, len); outw(BASE + EP_W1_TX_PIO_WR_1, 0x0); /* Second dword meaningless */ if (EP_FTST(sc, F_ACCESS_32_BITS)) { for (top = m; m != NULL; m = m->m_next) { outsl(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t), m->m_len / 4); if (m->m_len & 3) outsb(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t) + (m->m_len & (~3)), m->m_len & 3); } } else { for (top = m; m != NULL; m = m->m_next) { outsw(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t), m->m_len / 2); if (m->m_len & 1) outb(BASE + EP_W1_TX_PIO_WR_1, *(mtod(m, caddr_t) + m->m_len - 1)); } } while (pad--) outb(BASE + EP_W1_TX_PIO_WR_1, 0); /* Padding */ BPF_MTAP(ifp, top); ifp->if_timer = 2; IFNET_STAT_INC(ifp, opackets, 1); m_freem(top); /* * Is another packet coming in? We don't want to overflow the tiny RX * fifo. */ readcheck: if (inw(BASE + EP_W1_RX_STATUS) & RX_BYTES_MASK) { /* * we check if we have packets left, in that case we prepare to come * back later */ if (!ifq_is_empty(&ifp->if_snd)) outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | 8); crit_exit(); return; } goto startagain; }
void x86_bus_space_io_write_multi_4(bus_space_handle_t h, bus_size_t o, const u_int32_t *ptr, bus_size_t cnt) { outsl(h + o, ptr, cnt); }