Example #1
0
io_return_t
sceopen(
       dev_t			dev,
       dev_mode_t		flag,
       io_req_t			ior)
{
	struct	ifnet	*ifp;
	int i, unit;
	sce_softc_t ssc;
	scsit_return_t sr;
	TR_DECL("sceopen");

	tr4("enter: dev = 0x%x flag = 0x%x ior = 0x%x", dev, flag, ior);
	unit = minor(dev);

	if (scegetssc(unit) != NULL_SSC) {
		tr1("exit: D_ALREADY_OPEN");
		return (D_ALREADY_OPEN);
	}

	for(i=0;i<NSCE;i++) {
		ssc = &sce_softc[i];
		if (!ssc->inuse)
		    break;
	}
	if (ssc->inuse) {
		tr1("exit: D_WOULD_BLOCK");
		return (D_WOULD_BLOCK);
	}

	ssc->inuse = TRUE;
	ssc->node = unit;
	sr = scsit_handle_alloc(&ssc->recv_handle);
	assert(sr == SCSIT_SUCCESS);
	sr = scsit_handle_mismatch(ssc->recv_handle);
	assert(sr == SCSIT_SUCCESS);

	ifp = &(ssc->sce_if);
	ifp->if_unit = unit;
	ifp->if_mtu = SCE_MTU;
	ifp->if_flags = IFF_UP | IFF_RUNNING | IFF_BROADCAST;
	ifp->if_header_size = sizeof(struct ether_header);
	ifp->if_header_format = HDR_ETHERNET;
	ifp->if_address_size = 6;
	ifp->if_address = sce_fake_addr;
	if_init_queues(ifp);

	(void)sce_prime(ssc, IKM_NULL);
	tr1("exit: D_SUCCESS");
	return (D_SUCCESS);
}
Example #2
0
File: net.c Project: ctos/bpi
static io_return_t
device_open (ipc_port_t reply_port, mach_msg_type_name_t reply_port_type,
	     dev_mode_t mode, char *name, device_t *devp)
{
  io_return_t err = D_SUCCESS;
  ipc_port_t notify;
  struct ifnet *ifp;
  struct linux_device *dev;
  struct net_data *nd;

  /* Search for the device.  */
  for (dev = dev_base; dev; dev = dev->next)
    if (dev->base_addr
	&& dev->base_addr != 0xffe0
	&& !strcmp (name, dev->name))
      break;
  if (!dev)
    return D_NO_SUCH_DEVICE;

  /* Allocate and initialize device data if this is the first open.  */
  nd = dev->net_data;
  if (!nd)
    {
      dev->net_data = nd = ((struct net_data *)
			    kalloc (sizeof (struct net_data)));
      if (!nd)
	{
	  err = D_NO_MEMORY;
	  goto out;
	}
      nd->dev = dev;
      nd->device.emul_data = nd;
      nd->device.emul_ops = &linux_net_emulation_ops;
      nd->port = ipc_port_alloc_kernel ();
      if (nd->port == IP_NULL)
	{
	  err = KERN_RESOURCE_SHORTAGE;
	  goto out;
	}
      ipc_kobject_set (nd->port, (ipc_kobject_t) & nd->device, IKOT_DEVICE);
      notify = ipc_port_make_sonce (nd->port);
      ip_lock (nd->port);
      ipc_port_nsrequest (nd->port, 1, notify, &notify);
      assert (notify == IP_NULL);

      ifp = &nd->ifnet;
      ifp->if_unit = dev->name[strlen (dev->name) - 1] - '0';
      ifp->if_flags = IFF_UP | IFF_RUNNING;
      ifp->if_mtu = dev->mtu;
      ifp->if_header_size = dev->hard_header_len;
      ifp->if_header_format = dev->type;
      ifp->if_address_size = dev->addr_len;
      ifp->if_address = dev->dev_addr;
      if_init_queues (ifp);

      if (dev->open)
	{
	  linux_intr_pri = SPL6;
	  if ((*dev->open) (dev))
	    err = D_NO_SUCH_DEVICE;
	}

    out:
      if (err)
	{
	  if (nd)
	    {
	      if (nd->port != IP_NULL)
		{
		  ipc_kobject_set (nd->port, IKO_NULL, IKOT_NONE);
		  ipc_port_dealloc_kernel (nd->port);
		}
	      kfree ((vm_offset_t) nd, sizeof (struct net_data));
	      nd = NULL;
	      dev->net_data = NULL;
	    }
	}
      else
	{
	  /* IPv6 heavily relies on multicasting (especially router and
	     neighbor solicits and advertisements), so enable reception of
	     those multicast packets by setting `LINUX_IFF_ALLMULTI'.  */
	  dev->flags |= LINUX_IFF_UP | LINUX_IFF_RUNNING | LINUX_IFF_ALLMULTI;
	  skb_queue_head_init (&dev->buffs[0]);

	  if (dev->set_multicast_list)
	    dev->set_multicast_list (dev);
	}
      if (IP_VALID (reply_port))
	ds_device_open_reply (reply_port, reply_port_type,
			      err, dev_to_port (nd));
      return MIG_NO_REPLY;
    }

  *devp = &nd->device;
  return D_SUCCESS;
}