Example #1
0
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;
	}
}
Example #2
0
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;
}
Example #4
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);
}
Example #5
0
static void ide_outsl (unsigned long port, void *addr, u32 count)
{
	outsl(port, addr, count);
}
Example #6
0
wstdcall void WRAP_EXPORT(WRITE_PORT_BUFFER_ULONG)
	(ULONG_PTR port, ULONG *buf, ULONG count)
{
	outsl(port, buf, count);
}
Example #7
0
static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n)
{
	outsl(ADDR2PORT(addr), s, n);
}
Example #8
0
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;
}
Example #9
0
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);
}