Ejemplo n.º 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 */
}
Ejemplo n.º 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 {
Ejemplo n.º 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);
}
Ejemplo n.º 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);
	}
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 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);
	}
}
Ejemplo n.º 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);
}
Ejemplo n.º 9
0
// 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;
}
Ejemplo n.º 10
0
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);
    }
}
Ejemplo n.º 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;
	}
}
Ejemplo n.º 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;
	}
}
Ejemplo n.º 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);
}
Ejemplo n.º 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);
}
Ejemplo n.º 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);
}
Ejemplo n.º 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;
}
Ejemplo n.º 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); 
  }
}
Ejemplo n.º 18
0
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);
}
Ejemplo n.º 19
0
/*
**  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;
}
Ejemplo n.º 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);
}
Ejemplo n.º 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
Ejemplo n.º 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);
}
Ejemplo n.º 23
0
static void
write_fifo(unsigned int adr, u_char * data, int size)
{
	outsb(adr, data, size);
}
Ejemplo n.º 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;
		}
	}
}
Ejemplo n.º 25
0
/*
**  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);
}
Ejemplo n.º 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);
}
Ejemplo n.º 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);
}
Ejemplo n.º 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);
}