Ejemplo n.º 1
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)
{
  int bytes, ix = 0;
  iovec_dat_s_t *iovp = &dep->de_write_iovec;
  int r, 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 */
	r= sys_safe_outsb(dep->de_data_port, iovp->iod_proc_nr,
		iovp->iod_iovec[ix].iov_grant, 0, bytes);
	if (r != OK)
		panic("el3_write_fifo: sys_safe_outsb failed: %d", r);
		
	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.º 2
0
/*
**  Name:	void pio_user2nic(dpeth_t *dep, int pageno, int pktsize)
**  Function:	Copies a packet from user area to board (Prog. I/O).
*/
static void pio_user2nic(dpeth_t *dep, int pageno, int pktsize)
{
  iovec_dat_s_t *iovp = &dep->de_write_iovec;
  int r, bytes, ix = 0;

  /* Sets up board for writing */
  ns_rw_setup(dep, CR_DM_RW, pktsize, pageno * DP_PAGESIZE);
  
  do {				/* Reads chuncks of packet from user area */

	bytes = iovp->iod_iovec[ix].iov_size;	/* Size of chunck */
	if (bytes > pktsize) bytes = pktsize;
	r= sys_safe_outsb(dep->de_data_port, iovp->iod_proc_nr,
	      iovp->iod_iovec[ix].iov_grant, 0, bytes);
	if (r != OK)
		panic("pio_user2nic: sys_safe_outsb failed: %d", r);

	if (++ix >= IOVEC_NR) {	/* Next buffer of I/O vector */
		dp_next_iovec(iovp);
		ix = 0;
	}
	/* Till packet done */
  } while ((pktsize -= bytes) > 0);

  for (ix = 0; ix < 100; ix += 1) {
	if (inb_reg0(dep, DP_ISR) & ISR_RDC) break;
  }
  if (ix == 100) {
	panic(RdmaErrMsg);
  }
  return;
}
Ejemplo n.º 3
0
/*
**  Name:	void user2mem(dpeth_t *dep, buff_t *txbuff)
**  Function:	Copies a packet from user area to local buffer.
*/
void user2mem(dpeth_t *dep, buff_t *txbuff)
{
  int bytes, ix = 0;
  iovec_dat_s_t *iovp = &dep->de_write_iovec;
  int r, pktsize = txbuff->size;
  char *buffer = txbuff->buffer;

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

	bytes = iovp->iod_iovec[ix].iov_size;	/* Size of buffer */
	if (bytes > pktsize) bytes = pktsize;
	r= sys_safecopyfrom(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant,
		0, (vir_bytes)buffer, bytes);
	if (r != OK)
		panic("user2mem: sys_safecopyfrom failed: %d", r);
	buffer += bytes;

	if (++ix >= IOVEC_NR) {	/* Next buffer of IO vector */
		dp_next_iovec(iovp);
		ix = 0;
	}
	/* Till packet done */
  } while ((pktsize -= bytes) > 0);
  return;
}
Ejemplo n.º 4
0
/*
**  Name:	void mem_user2nic(dpeth_t *dep, int pageno, int pktsize)
**  Function:	Copies a packet from user area to board (shared memory).
*/
static void mem_user2nic(dpeth_t *dep, int pageno, int pktsize)
{
#if 1
  panic("mem_user2nic: not converted to safecopies");
#else
  phys_bytes offset, phys_user;
  iovec_dat_s_t *iovp = &dep->de_write_iovec;
  int bytes, ix = 0;

  /* Computes shared memory address */
  offset = pageno * DP_PAGESIZE;

  do {				/* Reads chuncks of packet from user area */

	bytes = iovp->iod_iovec[ix].iov_size;	/* Size of chunck */
	if (bytes > pktsize) bytes = pktsize;

	/* Reads from user area to board (shared memory) */
	sys_user2nic_s(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant, 
		     dep->de_linmem + offset, bytes);
	offset += bytes;

	if (++ix >= IOVEC_NR) {	/* Next buffer of IO vector */
		dp_next_iovec(iovp);
		ix = 0;
	}
	/* Till packet done */
  } while ((pktsize -= bytes) > 0);
  return;
#endif
}
Ejemplo n.º 5
0
/*
**  Name:	void dp_pio16_user2nic(dpeth_t *dep, int pageno, int pktsize)
**  Function:	Copies a packet from user area to board (Prog. I/O, 16bits).
*/
static void dp_pio16_user2nic(dpeth_t *dep, int pageno, int pktsize)
{
  u8_t two_bytes[2];
  phys_bytes phys_user, phys_2bytes = vir2phys(two_bytes);
  vir_bytes ecount = (pktsize + 1) & NOT(0x0001);
  int bytes, ix = 0, odd_byte = 0;
  iovec_dat_t *iovp = &dep->de_write_iovec;

  outb_reg0(dep, DP_ISR, ISR_RDC);
  dp_read_setup(dep, ecount, pageno * DP_PAGESIZE);

  do {
	bytes = iovp->iod_iovec[ix].iov_size;
	if (bytes > pktsize) bytes = pktsize;

	phys_user = numap(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr, bytes);
	if (!phys_user) panic(UmapErrMsg);

	if (odd_byte) {
		phys_copy(phys_user, phys_2bytes + 1, (phys_bytes) 1);
		out_word(dep->de_data_port, *(u16_t *)two_bytes);
		pktsize--;
		bytes--;
		phys_user++;
		odd_byte = 0;
		if (!bytes) continue;
	}
	ecount = bytes & NOT(0x0001);
	if (ecount != 0) {
		phys_outsw(dep->de_data_port, phys_user, ecount);
		pktsize -= ecount;
		bytes -= ecount;
		phys_user += ecount;
	}
	if (bytes) {
		phys_copy(phys_user, phys_2bytes, (phys_bytes) 1);
		pktsize--;
		bytes--;
		phys_user++;
		odd_byte = 1;
	}
	if (++ix >= IOVEC_NR) {	/* Next buffer of I/O vector */
		dp_next_iovec(iovp);
		ix = 0;
	}

  }  while (bytes > 0);

  if (odd_byte) out_word(dep->de_data_port, *(u16_t *) two_bytes);
  for (ix = 0; ix < 100; ix++) {
	if (inb_reg0(dep, DP_ISR) & ISR_RDC) break;
  }
  if (ix == 100) {
	panic(RdmaErrMsg);
  }
  return;
}
Ejemplo n.º 6
0
/*
**  Name:	void dp_pio16_nic2user(dpeth_t *dep, int pageno, int pktsize)
**  Function:	Copies a packet from board to user area (Prog. I/O, 16bits).
*/
static void dp_pio16_nic2user(dpeth_t * dep, int nic_addr, int count)
{
  phys_bytes phys_user;
  vir_bytes ecount;
  int bytes, i;
  u8_t two_bytes[2];
  phys_bytes phys_2bytes;
  int odd_byte;

  ecount = (count + 1) & ~1;
  phys_2bytes = vir2phys(two_bytes);
  odd_byte = 0;

  dp_read_setup(dep, ecount, nic_addr);

  i = 0;
  while (count > 0) {
	if (i >= IOVEC_NR) {
		dp_next_iovec(iovp);
		i = 0;
		continue;
	}
	bytes = iovp->iod_iovec[i].iov_size;
	if (bytes > count) bytes = count;

	phys_user = numap(iovp->iod_proc_nr,
			  iovp->iod_iovec[i].iov_addr, bytes);
	if (!phys_user) panic(UmapErrMsg);
	if (odd_byte) {
		phys_copy(phys_2bytes + 1, phys_user, (phys_bytes) 1);
		count--;
		bytes--;
		phys_user++;
		odd_byte = 0;
		if (!bytes) continue;
	}
	ecount = bytes & ~1;
	if (ecount != 0) {
		phys_insw(dep->de_data_port, phys_user, ecount);
		count -= ecount;
		bytes -= ecount;
		phys_user += ecount;
	}
	if (bytes) {
		*(u16_t *) two_bytes = in_word(dep->de_data_port);
		phys_copy(phys_2bytes, phys_user, (phys_bytes) 1);
		count--;
		bytes--;
		phys_user++;
		odd_byte = 1;
	}
  }
  return;
}
Ejemplo n.º 7
0
/*
**  Name:	void pio_nic2user(dpeth_t *dep, int pageno, int pktsize)
**  Function:	Copies a packet from board to user area (Prog. I/O).
*/
static void pio_nic2user(dpeth_t *dep, int pageno, int pktsize)
{
  iovec_dat_s_t *iovp = &dep->de_read_iovec;
  unsigned offset, iov_offset; int r, bytes, ix = 0;

  /* Computes memory address (skipping receive header) */
  offset = pageno * DP_PAGESIZE + sizeof(dp_rcvhdr_t);
  /* Sets up board for reading */
  ns_rw_setup(dep, CR_DM_RR, ((offset + pktsize) > (dep->de_stoppage * DP_PAGESIZE)) ?
	(dep->de_stoppage * DP_PAGESIZE) - offset : pktsize, offset);

  iov_offset= 0;
  do {				/* Reads chuncks of packet into user area */

	bytes = iovp->iod_iovec[ix].iov_size;	/* Size of a chunck */
	if (bytes > pktsize) bytes = pktsize;

	if ((offset + bytes) > (dep->de_stoppage * DP_PAGESIZE)) {

		/* Circular buffer wrap-around */
		bytes = dep->de_stoppage * DP_PAGESIZE - offset;
		r= sys_safe_insb(dep->de_data_port, iovp->iod_proc_nr, 
			iovp->iod_iovec[ix].iov_grant, iov_offset, bytes);
		if (r != OK) {
			panic("pio_nic2user: sys_safe_insb failed: %d", 				r);
		}
		pktsize -= bytes;
		iov_offset += bytes;
		bytes = iovp->iod_iovec[ix].iov_size - bytes;
		if (bytes > pktsize) bytes = pktsize;
		offset = dep->de_startpage * DP_PAGESIZE;
  		ns_rw_setup(dep, CR_DM_RR, pktsize, offset);
	}
	r= sys_safe_insb(dep->de_data_port, iovp->iod_proc_nr,
		iovp->iod_iovec[ix].iov_grant, iov_offset, bytes);
	if (r != OK)
		panic("pio_nic2user: sys_safe_insb failed: %d", r);
	offset += bytes;

	if (++ix >= IOVEC_NR) {	/* Next buffer of IO vector */
		dp_next_iovec(iovp);
		ix = 0;
	}
	iov_offset= 0;
	/* Till packet done */
  } while ((pktsize -= bytes) > 0);
  return;
}
Ejemplo n.º 8
0
/*
**  Name:	int calc_iovec_size(iovec_dat_t *iovp)
**  Function:	Compute the size of a request.
*/
static int calc_iovec_size(iovec_dat_s_t * iovp)
{
  int size, ix;

  size = ix = 0;
  do {
	size += iovp->iod_iovec[ix].iov_size;
	if (++ix >= IOVEC_NR) {
		dp_next_iovec(iovp);
		ix = 0;
	}

	/* Till all vectors added */
  } while (ix < iovp->iod_iovec_s);
  return size;
}
Ejemplo n.º 9
0
/*
**  Name:	void mem_nic2user(dpeth_t *dep, int pageno, int pktsize);
**  Function:	Copies a packet from board to user area (shared memory).
*/
static void mem_nic2user(dpeth_t * dep, int pageno, int pktsize)
{
  panic("mem_nic2user: not converted to safecopies");
#if 0
  phys_bytes offset;
  iovec_dat_s_t *iovp = &dep->de_read_iovec;
  int bytes, ix = 0;


  /* Computes shared memory address (skipping receive header) */
  offset = pageno * DP_PAGESIZE + sizeof(dp_rcvhdr_t);

  do {				/* Reads chuncks of packet into user area */

	bytes = iovp->iod_iovec[ix].iov_size;	/* Size of a chunck */
	if (bytes > pktsize) bytes = pktsize;

	/* Reads from board to user area */
	if ((offset + bytes) > (dep->de_stoppage * DP_PAGESIZE)) {

		/* Circular buffer wrap-around */
		bytes = dep->de_stoppage * DP_PAGESIZE - offset;
		sys_nic2mem_s(dep->de_linmem + offset, iovp->iod_proc_nr,
			    iovp->iod_iovec[ix].iov_grant, bytes);
		pktsize -= bytes;
		phys_user += bytes;
		bytes = iovp->iod_iovec[ix].iov_size - bytes;
		if (bytes > pktsize) bytes = pktsize;
		offset = dep->de_startpage * DP_PAGESIZE;
	}
	sys_nic2mem_s(dep->de_linmem + offset, iovp->iod_proc_nr,
		    iovp->iod_iovec[ix].iov_grant, bytes);
	offset += bytes;

	if (++ix >= IOVEC_NR) {	/* Next buffer of IO vector */
		dp_next_iovec(iovp);
		ix = 0;
	}
	/* Till packet done */
  } while ((pktsize -= bytes) > 0);
  return;
#endif
}
Ejemplo n.º 10
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;
}