Beispiel #1
0
boolean_t
sce_prime(sce_softc_t ssc, ipc_kmsg_t old_kmsg)
{
	ipc_kmsg_t new_kmsg;
	sce_softc_t *pssc;
	register struct ether_header *ehp;
	register struct packet_header *pkt;
	scsit_return_t sr;

	new_kmsg = net_kmsg_get();
	if (new_kmsg == IKM_NULL) {
		assert(old_kmsg != IKM_NULL);
		new_kmsg = old_kmsg;
	}
	pssc = (sce_softc_t *)&net_kmsg(new_kmsg)->header[0];
	*pssc = ssc;
	ehp = ((struct ether_header *) (&net_kmsg(new_kmsg)->packet[0])) - 1;
	pkt = ((struct packet_header *)ehp) + 1;

	sr = scsit_receive(ssc->recv_handle,
			   ssc->node,
			   sce_lun,
			   (void *)new_kmsg,
			   (char *)pkt,
			   NET_RCV_MAX,
			   0);
	assert(sr == SCSIT_SUCCESS);
	return(new_kmsg != old_kmsg);
}
Beispiel #2
0
Datei: net.c Projekt: ctos/bpi
/* Accept packet SKB received on an interface.  */
void
netif_rx (struct sk_buff *skb)
{
  ipc_kmsg_t kmsg;
  struct ether_header *eh;
  struct packet_header *ph;
  struct linux_device *dev = skb->dev;

  assert (skb != NULL);

  if (print_packet_size)
    printf ("netif_rx: length %ld\n", skb->len);

  /* Allocate a kernel message buffer.  */
  kmsg = net_kmsg_get ();
  if (!kmsg)
    {
      dev_kfree_skb (skb, FREE_READ);
      return;
    }

  /* Copy packet into message buffer.  */
  eh = (struct ether_header *) (net_kmsg (kmsg)->header);
  ph = (struct packet_header *) (net_kmsg (kmsg)->packet);
  memcpy (eh, skb->data, sizeof (struct ether_header));

  /* packet is prefixed with a struct packet_header,
     see include/device/net_status.h.  */
  memcpy (ph + 1, skb->data + sizeof (struct ether_header),
	  skb->len - sizeof (struct ether_header));
  ph->type = eh->ether_type;
  ph->length = (skb->len - sizeof (struct ether_header)
		+ sizeof (struct packet_header));

  dev_kfree_skb (skb, FREE_READ);

  net_kmsg(kmsg)->sent = FALSE; /* Mark packet as received.  */

  /* Pass packet up to the microkernel.  */
  net_packet (&dev->net_data->ifnet, kmsg,
	      ph->length, ethernet_priority (kmsg));
}
Beispiel #3
0
Datei: net.c Projekt: ctos/bpi
static io_return_t
device_write (void *d, ipc_port_t reply_port,
	      mach_msg_type_name_t reply_port_type, dev_mode_t mode,
	      recnum_t bn, io_buf_ptr_t data, unsigned int count,
	      int *bytes_written)
{
  unsigned char *p;
  int i, amt, skblen, s;
  io_return_t err = 0;
  vm_map_copy_t copy = (vm_map_copy_t) data;
  struct net_data *nd = d;
  struct linux_device *dev = nd->dev;
  struct sk_buff *skb;

  if (count == 0 || count > dev->mtu + dev->hard_header_len)
    return D_INVALID_SIZE;

  /* Allocate a sk_buff.  */
  amt = PAGE_SIZE - (copy->offset & PAGE_MASK);
  skblen = (amt >= count) ? 0 : count;
  skb = dev_alloc_skb (skblen);
  if (!skb)
    return D_NO_MEMORY;

  /* Copy user data.  This is only required if it spans multiple pages.  */
  if (skblen == 0)
    {
      assert (copy->cpy_npages == 1);

      skb->copy = copy;
      skb->data = ((void *) copy->cpy_page_list[0]->phys_addr
		   + (copy->offset & PAGE_MASK));
      skb->len = count;
      skb->head = skb->data;
      skb->tail = skb->data + skb->len;
      skb->end = skb->tail;
    }
  else
    {
      skb->len = skblen;
      skb->tail = skb->data + skblen;
      skb->end = skb->tail;
      
      memcpy (skb->data,
	      ((void *) copy->cpy_page_list[0]->phys_addr
	       + (copy->offset & PAGE_MASK)),
	      amt);
      count -= amt;
      p = skb->data + amt;
      for (i = 1; count > 0 && i < copy->cpy_npages; i++)
	{
	  amt = PAGE_SIZE;
	  if (amt > count)
	    amt = count;
	  memcpy (p, (void *) copy->cpy_page_list[i]->phys_addr, amt);
	  count -= amt;
	  p += amt;
	}

      assert (count == 0);

      vm_map_copy_discard (copy);
    }

  skb->dev = dev;
  skb->reply = reply_port;
  skb->reply_type = reply_port_type;

  /* Queue packet for transmission and schedule a software interrupt.  */
  s = splimp ();
  if (dev->buffs[0].next != (struct sk_buff *) &dev->buffs[0]
      || (*dev->hard_start_xmit) (skb, dev))
    {
      __skb_queue_tail (&dev->buffs[0], skb);
      mark_bh (NET_BH);
    }
  splx (s);

  /* Send packet to filters.  */
  {
    struct packet_header *packet;
    struct ether_header *header;
    ipc_kmsg_t kmsg;

    kmsg = net_kmsg_get ();

    if (kmsg != IKM_NULL)
      {
        /* Suitable for Ethernet only.  */
        header = (struct ether_header *) (net_kmsg (kmsg)->header);
        packet = (struct packet_header *) (net_kmsg (kmsg)->packet);
        memcpy (header, skb->data, sizeof (struct ether_header));

        /* packet is prefixed with a struct packet_header,
           see include/device/net_status.h.  */
        memcpy (packet + 1, skb->data + sizeof (struct ether_header),
                skb->len - sizeof (struct ether_header));
        packet->length = skb->len - sizeof (struct ether_header)
                         + sizeof (struct packet_header);
        packet->type = header->ether_type;
        net_kmsg (kmsg)->sent = TRUE; /* Mark packet as sent.  */
        s = splimp ();
        net_packet (&dev->net_data->ifnet, kmsg, packet->length,
                    ethernet_priority (kmsg));
        splx (s);
      }
  }

  return MIG_NO_REPLY;
}