示例#1
0
static void ni5010_transmit(struct nic *nic,
	const char *d,	/* Destination */
	unsigned int t,	/* Type */
	unsigned int s,	/* size */
	const char *p)	/* Packet */
{
	unsigned int	len;
	int		buf_offs, xmt_stat;
	unsigned long	time;

	len = s + ETH_HLEN;
	if (len < ETH_ZLEN)
		len = ETH_ZLEN;
	buf_offs = NI5010_BUFSIZE - len;
	outb(0, EDLC_RMASK);	/* Mask all receive interrupts */
	outb(0, IE_MMODE);	/* Put Xmit buffer on system bus */
	outb(0xFF, EDLC_RCLR);	/* Clear out pending rcv interrupts */
	outw(buf_offs, IE_GP);	/* Point GP at start of packet */
	outsb(IE_XBUF, d, ETH_ALEN);	/* Put dst in buffer */
	outsb(IE_XBUF, nic->node_addr, ETH_ALEN);/* Put src in buffer */
	outb(t >> 8, IE_XBUF);
	outb(t, IE_XBUF);
	outsb(IE_XBUF, p, s);	/* Put data in buffer */
	while (s++ < ETH_ZLEN - ETH_HLEN)	/* Pad to min size */
		outb(0, IE_XBUF);
	outw(buf_offs, IE_GP);	/* Rewrite where packet starts */
	/* should work without that outb() (Crynwr used it) */
	/*outb(MM_MUX, IE_MMODE);*/
	/* Xmt buffer to EDLC bus */
	outb(MM_EN_XMT | MM_MUX, IE_MMODE);	/* Begin transmission */
	/* wait for transmit complete */
	while (((xmt_stat = inb(IE_ISTAT)) & IS_EN_XMT) != 0)
		;
	reset_receiver();	/* Immediately switch to receive */
}
示例#2
0
static int snd_gf1_pcm_poke_block(struct snd_gus_card *gus, unsigned char *buf,
				  unsigned int pos, unsigned int count,
				  int w16, int invert)
{
	unsigned int len;
	unsigned long flags;

	/*
	printk(KERN_DEBUG
	       "poke block; buf = 0x%x, pos = %i, count = %i, port = 0x%x\n",
	       (int)buf, pos, count, gus->gf1.port);
	*/
	while (count > 0) {
		len = count;
		if (len > 512)		/* limit, to allow IRQ */
			len = 512;
		count -= len;
		if (gus->interwave) {
			spin_lock_irqsave(&gus->reg_lock, flags);
			snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01 | (invert ? 0x08 : 0x00));
			snd_gf1_dram_addr(gus, pos);
			if (w16) {
				outb(SNDRV_GF1_GW_DRAM_IO16, GUSP(gus, GF1REGSEL));
				outsw(GUSP(gus, GF1DATALOW), buf, len >> 1);
			} else {
				outsb(GUSP(gus, DRAM), buf, len);
			}
			spin_unlock_irqrestore(&gus->reg_lock, flags);
			buf += 512;
			pos += 512;
		} else {
示例#3
0
static inline void
writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
{
	/* fifo write without cli because it's allready done  */
	byteout(ale, off);
	outsb(adr, data, size);
}
示例#4
0
static void
W6692_fill_Dfifo(struct w6692_hw *card)
{
	struct dchannel *dch = &card->dch;
	int count;
	u8 *ptr;
	u8 cmd = W_D_CMDR_XMS;

	pr_debug("%s: fill_Dfifo\n", card->name);
	if (!dch->tx_skb)
		return;
	count = dch->tx_skb->len - dch->tx_idx;
	if (count <= 0)
		return;
	if (count > W_D_FIFO_THRESH)
		count = W_D_FIFO_THRESH;
	else
		cmd |= W_D_CMDR_XME;
	ptr = dch->tx_skb->data + dch->tx_idx;
	dch->tx_idx += count;
	outsb(card->addr + W_D_XFIFO, ptr, count);
	WriteW6692(card, W_D_CMDR, cmd);
	if (test_and_set_bit(FLG_BUSY_TIMER, &dch->Flags)) {
		pr_debug("%s: fill_Dfifo dbusytimer running\n", card->name);
		del_timer(&dch->timer);
	}
	init_timer(&dch->timer);
	dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
	add_timer(&dch->timer);
	if (debug & DEBUG_HW_DFIFO) {
		snprintf(card->log, 63, "D-send %s %d ",
			card->name, count);
		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
	}
}
示例#5
0
文件: mcdx.c 项目: Einheri/wl500g
static int
mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf)
{
	unsigned char cmd[7] = {
		0, 0, 0, 0, 0, 0, 0
	};

	if (!stuffp->readcmd) {
		xinfo("Can't play from missing disk.\n");
		return -1;
	}

	cmd[0] = stuffp->playcmd;

	cmd[1] = msf->cdmsf_min0;
	cmd[2] = msf->cdmsf_sec0;
	cmd[3] = msf->cdmsf_frame0;
	cmd[4] = msf->cdmsf_min1;
	cmd[5] = msf->cdmsf_sec1;
	cmd[6] = msf->cdmsf_frame1;

	xtrace(PLAYMSF, "ioctl(): play %x "
	       "%02x:%02x:%02x -- %02x:%02x:%02x\n",
	       cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]);

	outsb(stuffp->wreg_data, cmd, sizeof cmd);

	if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
		xwarn("playmsf() timeout\n");
		return -1;
	}

	stuffp->audiostatus = CDROM_AUDIO_PLAY;
	return 0;
}
static int snd_gus_dram_poke(snd_gus_card_t *gus, char __user *_buffer,
			     unsigned int address, unsigned int size)
{
	unsigned long flags;
	unsigned int size1, size2;
	char buffer[512], *pbuffer;

	while (size > 0) {
		if (copy_from_user(buffer, _buffer, 512))
			return -EFAULT;
		size1 = size > 512 ? 512 : size;
		if (gus->interwave) {
			spin_lock_irqsave(&gus->reg_lock, flags);
			snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);
			snd_gf1_dram_addr(gus, address);
			outsb(GUSP(gus, DRAM), buffer, size1);
			spin_unlock_irqrestore(&gus->reg_lock, flags);
			address += size1;
		} else {
			pbuffer = buffer;
			size2 = size1;
			while (size2--)
				snd_gf1_poke(gus, address++, *pbuffer++);
		}
		size -= size1;
		_buffer += size1;
	}
	return 0;
}
示例#7
0
static void
W6692_fill_Bfifo(struct w6692_ch *wch)
{
	struct w6692_hw *card = wch->bch.hw;
	int count;
	u8 *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS;

	pr_debug("%s: fill Bfifo\n", card->name);
	if (!wch->bch.tx_skb)
		return;
	count = wch->bch.tx_skb->len - wch->bch.tx_idx;
	if (count <= 0)
		return;
	ptr = wch->bch.tx_skb->data + wch->bch.tx_idx;
	if (count > W_B_FIFO_THRESH)
		count = W_B_FIFO_THRESH;
	else if (test_bit(FLG_HDLC, &wch->bch.Flags))
		cmd |= W_B_CMDR_XME;

	pr_debug("%s: fill Bfifo%d/%d\n", card->name,
			count, wch->bch.tx_idx);
	wch->bch.tx_idx += count;
	outsb(wch->addr + W_B_XFIFO, ptr, count);
	WriteW6692B(wch, W_B_CMDR, cmd);
	if (debug & DEBUG_HW_DFIFO) {
		snprintf(card->log, 63, "B%1d-send %s %d ",
			wch->bch.nr, card->name, count);
		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
	}
}
示例#8
0
static inline void
WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
{
	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
			HSCX_FIFO_OFFSET+hscx*HSCX_CH_DIFF);
	outsb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
}
示例#9
0
文件: ne.c 项目: amitks/xv6-network
// sizeバイトのpacketをローカルバッファに書き込み、その後送信する
// sizeは適正([46, 1514])であること
int
ne_pio_write(ne_t* ne, uchar* packet, int size)
{
  // sendqの先頭がちゃんと空いてる?
  int q = ne->sendq_head % SENDQ_LEN;
  if (ne->sendq[q].filled || ne->sendq_head > ne->sendq_tail) {
    cprintf("%s: all transmitting buffers in NIC are busy.\n", ne->name);
    return 0;
  }

  // 書き込み処理
  ne_rdma_setup(ne, CR_DM_RW, ne->sendq[q].sendpage * DP_PAGESIZE, size);
  if (ne->is16bit)
    outsw(ne->base + NE_DATA, packet, size);
  else
    outsb(ne->base + NE_DATA, packet, size);
  // ToDo: ここでISR_RDCのチェックは必要なのか?

  ne->sendq[q].filled = TRUE;
  ne_start_xmit(ne, ne->sendq[q].sendpage, size);

  // ToDo: 多分算術オーバーフロー対策しないといけない。
  ne->sendq_head++;
  
  return size;
}
static void
siemens_isurf_write_fifo(void *base, const void *buf, size_t len)
{
    if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB)
    {
        outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXB_OFF);
        outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len);
    }
    else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA)
    {
        outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXA_OFF);
        outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len);
    }
    else /* if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC) */
    {
        outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_ISAC_OFF);
        outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len);
    }
}
示例#11
0
static void
itkix1_write_fifo(void *base, const void *buf, size_t len)
{
	u_int port = (u_int)base & ~0x0003;
	switch ((u_int)base & 3) {
	case 0:	/* ISAC */
		outb(port+ITK_ALE, 0);
		outsb(port+ITK_ISAC_DATA, (u_char *)buf, (u_int)len);
		break;
	case 1: /* HSCXA */
		outb(port+ITK_ALE, HSCXA);
		outsb(port+ITK_HSCX_DATA, (u_char *)buf, (u_int)len);
		break;
	case 2: /* HSCXB */
		outb(port+ITK_ALE, HSCXB);
		outsb(port+ITK_HSCX_DATA, (u_char *)buf, (u_int)len);
		break;
	}
}
示例#12
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;
	}
}
示例#13
0
static void fcpci_write_isac_fifo(struct isac *isac, unsigned char * data, 
				  int size)
{
	struct fritz_adapter *adapter = isac->priv;
	unsigned long flags;

	spin_lock_irqsave(&adapter->hw_lock, flags);
	outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX);
	outsb(adapter->io + AVM_DATA, data, size);
 	spin_unlock_irqrestore(&adapter->hw_lock, flags);
}
示例#14
0
static inline void
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
{
	long flags;

	save_flags(flags);
	cli();
	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_FIFO_OFFSET);
	outsb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
	restore_flags(flags);
}
示例#15
0
static inline void
WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
{
	long flags;

	save_flags(flags);
	cli();
	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
			HSCX_FIFO_OFFSET+hscx*HSCX_CH_DIFF);
	outsb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
	restore_flags(flags);
}
示例#16
0
ssize_t do_short_write (struct inode *inode, struct file *filp, const char *buf,
                size_t count, loff_t *f_pos)
{
    int retval = count;
    unsigned long address = short_base + (MINOR(inode->i_rdev)&0x0f);
    int mode = (MINOR(inode->i_rdev)&0x70) >> 4;
    unsigned char *kbuf=kmalloc(count, GFP_KERNEL), *ptr;

    if (!kbuf) return -ENOMEM;
    copy_from_user(kbuf, buf, count);
    ptr=kbuf;

    if (use_mem)
	mode = SHORT_MEMORY;

    switch(mode) {
      case SHORT_PAUSE:
        while (count--) {
            outb_p(*(ptr++), address);
	    wmb();
	}
        break;

      case SHORT_STRING:
        outsb(address, ptr, count);
	wmb();
        break;

      case SHORT_DEFAULT:
        while (count--) {
            outb(*(ptr++), address);
	    wmb();
	}
        break;

      case SHORT_MEMORY:
        while (count--) {
            writeb(*(ptr++), address);
	    wmb();
	}
        break;

      default: /* no more modes defined by now */
        retval = -EINVAL;
        break;
    }
    kfree(kbuf);
    return retval;
}
示例#17
0
void __svgalib_port_rep_outb(unsigned char* string, int length, int port)
{
  if(__svgalib_nohelper)
  {
    outsb(port, string, length);
  }
  else
  {
    io_string_t iostr;

    iostr.port = port;
    iostr.string = string;
    iostr.length = length;
    
    ioctl(__svgalib_mem_fd,SVGAHELPER_REPOUTB,&iostr); 
  }
}
示例#18
0
文件: opl4_lib.c 项目: 020gzh/linux
void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size)
{
	unsigned long flags;
	u8 memcfg;

	spin_lock_irqsave(&opl4->reg_lock, flags);

	memcfg = snd_opl4_read(opl4, OPL4_REG_MEMORY_CONFIGURATION);
	snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg | OPL4_MODE_BIT);

	snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_HIGH, offset >> 16);
	snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_MID, offset >> 8);
	snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_LOW, offset);

	snd_opl4_wait(opl4);
	outb(OPL4_REG_MEMORY_DATA, opl4->pcm_port);
	snd_opl4_wait(opl4);
	outsb(opl4->pcm_port + 1, buf, size);

	snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg);

	spin_unlock_irqrestore(&opl4->reg_lock, flags);
}
示例#19
0
文件: 3c509.c 项目: Johnwei386/Minix3
/*
**  Name:	void el3_write_fifo(dpeth_t * dep, int pktsize);
**  Function:	Writes a packet from user area to board.
**  Remark:	Writing a word/dword at a time may result faster
**  		but is a lot more complicated. Let's go simpler way.
*/
static void el3_write_fifo(dpeth_t * dep, int pktsize)
{
  phys_bytes phys_user;
  int bytes, ix = 0;
  iovec_dat_t *iovp = &dep->de_write_iovec;
  int padding = pktsize;

  do {				/* Writes chuncks of packet from user buffers */

	bytes = iovp->iod_iovec[ix].iov_size;	/* Size of buffer */
	if (bytes > pktsize) bytes = pktsize;
	/* Writes from user buffer to Tx FIFO */
        outsb(dep->de_data_port, iovp->iod_proc_nr,
              (void*)(iovp->iod_iovec[ix].iov_addr), bytes);
	if (++ix >= IOVEC_NR) {	/* Next buffer of IO vector */
		dp_next_iovec(iovp);
		ix = 0;
	}
	/* Till packet done */
  } while ((pktsize -= bytes) > 0);
  while ((padding++ % sizeof(long)) != 0) outb(dep->de_data_port, 0x00);
  return;
}
示例#20
0
/*---------------------------------------------------------------------------*
 *	AVM write fifo routines
 *---------------------------------------------------------------------------*/
static void
avm_pnp_write_fifo(void *base, const void *buf, size_t len)
{
	int unit;
	struct isic_softc *sc;

	unit = (int)base & 0xff;
	sc = &isic_sc[unit];

	/* check whether the target is an HSCX */
	if (((int)base & IS_HSCX_MASK) == HSCX0FAKE)
	{
		hscx_write_fifo(0, buf, len, sc);
		return;
	}
	if (((int)base & IS_HSCX_MASK)  == HSCX1FAKE)
	{
		hscx_write_fifo(1, buf, len, sc);
		return;
	}
	/* tell the board to use the ISAC fifo */
	outb(sc->sc_port + ADDR_REG_OFFSET, ISAC_FIFO);
	outsb(sc->sc_port + ISAC_REG_OFFSET, (const u_char *)buf, len);
}
示例#21
0
}
/*------- Ide String Operations -------------------------------------
*/
void ideCpyReadb( FLWORD address, FLBYTE far *des, FLWORD count )
{
  FLWORD readPort = ideDocSocPtr->ioRegs[R_READ].port;

  ideSetAddr(address);
  insb( readPort, (void *)des, (FLDWORD)count );
#if 0  
  asm {
      push dx
      push cx
      push di
      push es
      mov  dx, readPort
      mov  cx, count
      les  di, des
      cld
      rep  insb
      pop  es
      pop  di
      pop  cx
      pop  dx
示例#22
0
static inline void
writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
{
	byteout(ale, off);
	outsb(adr, data, size);
}
示例#23
0
static void
write_fifo(unsigned int adr, u_char * data, int size)
{
	outsb(adr, data, size);
}
示例#24
0
static void
wbcir_irq_tx(struct wbcir_data *data)
{
	unsigned int space;
	unsigned int used;
	u8 bytes[16];
	u8 byte;

	if (!data->txbuf)
		return;

	switch (data->txstate) {
	case WBCIR_TXSTATE_INACTIVE:
		/* TX FIFO empty */
		space = 16;
		led_trigger_event(data->txtrigger, LED_FULL);
		break;
	case WBCIR_TXSTATE_ACTIVE:
		/* TX FIFO low (3 bytes or less) */
		space = 13;
		break;
	case WBCIR_TXSTATE_ERROR:
		space = 0;
		break;
	default:
		return;
	}

	/*
	 * TX data is run-length coded in bytes: YXXXXXXX
	 * Y = space (1) or pulse (0)
	 * X = duration, encoded as (X + 1) * 10us (i.e 10 to 1280 us)
	 */
	for (used = 0; used < space && data->txoff != data->txlen; used++) {
		if (data->txbuf[data->txoff] == 0) {
			data->txoff++;
			continue;
		}
		byte = min((u32)0x80, data->txbuf[data->txoff]);
		data->txbuf[data->txoff] -= byte;
		byte--;
		byte |= (data->txoff % 2 ? 0x80 : 0x00); /* pulse/space */
		bytes[used] = byte;
	}

	while (data->txbuf[data->txoff] == 0 && data->txoff != data->txlen)
		data->txoff++;

	if (used == 0) {
		/* Finished */
		if (data->txstate == WBCIR_TXSTATE_ERROR)
			/* Clear TX underrun bit */
			outb(WBCIR_TX_UNDERRUN, data->sbase + WBCIR_REG_SP3_ASCR);
		else
			data->txstate = WBCIR_TXSTATE_DONE;
		wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR);
		led_trigger_event(data->txtrigger, LED_OFF);
		wake_up(&data->txwaitq);
	} else if (data->txoff == data->txlen) {
		/* At the end of transmission, tell the hw before last byte */
		outsb(data->sbase + WBCIR_REG_SP3_TXDATA, bytes, used - 1);
		outb(WBCIR_TX_EOT, data->sbase + WBCIR_REG_SP3_ASCR);
		outb(bytes[used - 1], data->sbase + WBCIR_REG_SP3_TXDATA);
		wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR |
				  WBCIR_IRQ_TX_EMPTY);
	} else {
		/* More data to follow... */
		outsb(data->sbase + WBCIR_REG_SP3_RXDATA, bytes, used);
		if (data->txstate == WBCIR_TXSTATE_INACTIVE) {
			wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR |
					  WBCIR_IRQ_TX_LOW);
			data->txstate = WBCIR_TXSTATE_ACTIVE;
		}
	}
}
示例#25
0
文件: 3c501.c 项目: AjeyBohare/minix
/*
**  Name:	void el1_send(dpeth_t *dep, int from_int, int pktsize)
**  Function:	Send function.  Called from main to transit a packet or
**  		from interrupt handler when a new packet was queued.
*/
static void el1_send(dpeth_t * dep, int from_int, int pktsize)
{
  buff_t *txbuff;
  clock_t now;

  if (from_int == FALSE) {

	if ((txbuff = alloc_buff(dep, pktsize + sizeof(buff_t))) != NULL) {

		/*  Fill transmit buffer from user area */
		txbuff->next = NULL;
		txbuff->size = pktsize;
		txbuff->client = dep->de_client;
		user2mem(dep, txbuff);
	} else
		panic("out of memory for Tx");

  } else if ((txbuff = dep->de_xmitq_head) != NULL) {

	/* Get first packet in queue */
	lock();
	if (dep->de_xmitq_tail == dep->de_xmitq_head)
		dep->de_xmitq_head = dep->de_xmitq_tail = NULL;
	else
		dep->de_xmitq_head = txbuff->next;
	unlock();
	pktsize = txbuff->size;

  } else
	panic("should not be sending ");

  if ((dep->de_flags & DEF_XMIT_BUSY)) {
	if (from_int) panic("should not be sending ");
	getticks(&now);
	if ((now - dep->de_xmit_start) > 4) {
		/* Transmitter timed out */
		DEBUG(printf("3c501: transmitter timed out ... \n"));
		dep->de_stat.ets_sendErr += 1;
		dep->de_flags &= NOT(DEF_XMIT_BUSY);
		el1_reset(dep);
	}

	/* Queue packet */
	lock();			/* Queue packet to receive queue */
	if (dep->de_xmitq_head == NULL)
		dep->de_xmitq_head = txbuff;
	else
		dep->de_xmitq_tail->next = txbuff;
	dep->de_xmitq_tail = txbuff;
	unlock();
  } else {
	/* Save for retransmission */
	TxBuff = txbuff;
	dep->de_flags |= (DEF_XMIT_BUSY | DEF_ACK_SEND);

	/* Setup board for packet loading */
	lock();			/* Buffer to processor */
	outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_SYS);
	inb_el1(dep, EL1_RECV);	/* Clears any spurious interrupt */
	inb_el1(dep, EL1_XMIT);
	outw_el1(dep, EL1_RECVPTR, 0);	/* Clears RX packet area */

	/* Loads packet */
	outw_el1(dep, EL1_XMITPTR, (EL1_BFRSIZ - pktsize));
	outsb(dep->de_data_port, SELF, txbuff->buffer, pktsize);
	/* Starts transmitter */
	outw_el1(dep, EL1_XMITPTR, (EL1_BFRSIZ - pktsize));
	outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_XMIT);	/* There it goes... */
	unlock();

	getticks(&dep->de_xmit_start);
	dep->de_flags &= NOT(DEF_SENDING);
  }
  return;
}
static int mcdx_talk(struct s_drive_stuff *stuffp,
	  const unsigned char *cmd, size_t cmdlen,
	  void *buffer, size_t size, unsigned int timeout, int tries)
/* Send a command to the drive, wait for the result.
 * returns -1 on timeout, drive status otherwise
 * If buffer is not zero, the result (length size) is stored there.
 * If buffer is zero the size should be the number of bytes to read
 * from the drive.  These bytes are discarded.
 */
{
	int st;
	char c;
	int discard;

	/* Somebody wants the data read? */
	if ((discard = (buffer == NULL)))
		buffer = &c;

	while (stuffp->lock) {
		xtrace(SLEEP, "*** talk: lockq\n");
		interruptible_sleep_on(&stuffp->lockq);
		xtrace(SLEEP, "talk: awoken\n");
	}

	stuffp->lock = 1;

	/* An operation other then reading data destroys the
	   * data already requested and remembered in stuffp->request, ... */
	stuffp->valid = 0;

#if MCDX_DEBUG & TALK
	{
		unsigned char i;
		xtrace(TALK,
		       "talk() %d / %d tries, res.size %d, command 0x%02x",
		       tries, timeout, size, (unsigned char) cmd[0]);
		for (i = 1; i < cmdlen; i++)
			xtrace(TALK, " 0x%02x", cmd[i]);
		xtrace(TALK, "\n");
	}
#endif

	/*  give up if all tries are done (bad) or if the status
	 *  st != -1 (good) */
	for (st = -1; st == -1 && tries; tries--) {

		char *bp = (char *) buffer;
		size_t sz = size;

		outsb(stuffp->wreg_data, cmd, cmdlen);
		xtrace(TALK, "talk() command sent\n");

		/* get the status byte */
		if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
			xinfo("talk() %02x timed out (status), %d tr%s left\n",
			     cmd[0], tries - 1, tries == 2 ? "y" : "ies");
			continue;
		}
		st = *bp;
		sz--;
		if (!discard)
			bp++;

		xtrace(TALK, "talk() got status 0x%02x\n", st);

		/* command error? */
		if (e_cmderr(st)) {
			xwarn("command error cmd = %02x %s \n",
			      cmd[0], cmdlen > 1 ? "..." : "");
			st = -1;
			continue;
		}

		/* audio status? */
		if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
			stuffp->audiostatus =
			    e_audiobusy(st) ? CDROM_AUDIO_PLAY :
			    CDROM_AUDIO_NO_STATUS;
		else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
			 && e_audiobusy(st) == 0)
			stuffp->audiostatus = CDROM_AUDIO_COMPLETED;

		/* media change? */
		if (e_changed(st)) {
			xinfo("talk() media changed\n");
			stuffp->xxx = stuffp->yyy = 1;
		}

		/* now actually get the data */
		while (sz--) {
			if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
				xinfo("talk() %02x timed out (data), %d tr%s left\n",
				     cmd[0], tries - 1,
				     tries == 2 ? "y" : "ies");
				st = -1;
				break;
			}
			if (!discard)
				bp++;
			xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
		}
	}

#if !MCDX_QUIET
	if (!tries && st == -1)
		xinfo("talk() giving up\n");
#endif

	stuffp->lock = 0;
	wake_up_interruptible(&stuffp->lockq);

	xtrace(TALK, "talk() done with 0x%02x\n", st);
	return st;
}
static void
WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
{
	outsb(cs->hw.w6692.iobase + W_D_XFIFO, data, size);
}
示例#28
0
static netdev_tx_t el_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct net_local *lp = netdev_priv(dev);
	int ioaddr = dev->base_addr;
	unsigned long flags;

	/*
	 *	Avoid incoming interrupts between us flipping txing and flipping
	 *	mode as the driver assumes txing is a faithful indicator of card
	 *	state
	 */

	spin_lock_irqsave(&lp->lock, flags);

	/*
	 *	Avoid timer-based retransmission conflicts.
	 */

	netif_stop_queue(dev);

	do {
		int len = skb->len;
		int pad = 0;
		int gp_start;
		unsigned char *buf = skb->data;

		if (len < ETH_ZLEN)
			pad = ETH_ZLEN - len;

		gp_start = 0x800 - (len + pad);

		lp->tx_pkt_start = gp_start;
		lp->collisions = 0;

		dev->stats.tx_bytes += skb->len;

		/*
		 *	Command mode with status cleared should [in theory]
		 *	mean no more interrupts can be pending on the card.
		 */

		outb_p(AX_SYS, AX_CMD);
		inb_p(RX_STATUS);
		inb_p(TX_STATUS);

		lp->loading = 1;
		lp->txing = 1;

		/*
		 *	Turn interrupts back on while we spend a pleasant
		 *	afternoon loading bytes into the board
		 */

		spin_unlock_irqrestore(&lp->lock, flags);

		/* Set rx packet area to 0. */
		outw(0x00, RX_BUF_CLR);
		/* aim - packet will be loaded into buffer start */
		outw(gp_start, GP_LOW);
		/* load buffer (usual thing each byte increments the pointer) */
		outsb(DATAPORT, buf, len);
		if (pad) {
			while (pad--)		/* Zero fill buffer tail */
				outb(0, DATAPORT);
		}
		/* the board reuses the same register */
		outw(gp_start, GP_LOW);

		if (lp->loading != 2) {
			/* fire ... Trigger xmit.  */
			outb(AX_XMIT, AX_CMD);
			lp->loading = 0;
			if (el_debug > 2)
				pr_debug(" queued xmit.\n");
			dev_kfree_skb(skb);
			return NETDEV_TX_OK;
		}
		/* A receive upset our load, despite our best efforts */
		if (el_debug > 2)
			pr_debug("%s: burped during tx load.\n", dev->name);
		spin_lock_irqsave(&lp->lock, flags);
	} while (1);
}
示例#29
0
static void
avma1_write_fifo(void *base, const void *buf, size_t len)
{
	outsb((int)base - 0x3e0, (u_char *)buf, (u_int)len);
}
示例#30
0
static void
ctxs0P_write_fifo(void *base, const void *buf, size_t len)
{
        outsb((int)base + 0x3e, (u_char *)buf, (u_int)len);
}