Esempio n. 1
0
static void pegasus_disconnect(struct usb_interface *intf)
{
	struct pegasus *pegasus = usb_get_intfdata(intf);

	usb_set_intfdata(intf, NULL);
	if (!pegasus) {
		warn("unregistering non-existant device");
		return;
	}

	pegasus->flags |= PEGASUS_UNPLUG;
	unregister_netdev(pegasus->net);
	usb_put_dev(interface_to_usbdev(intf));
	free_all_urbs(pegasus);
	free_skb_pool(pegasus);
	if (pegasus->rx_skb)
		dev_kfree_skb(pegasus->rx_skb);
	free_netdev(pegasus->net);
}
Esempio n. 2
0
static int pegasus_open(struct net_device *net)
{
	pegasus_t *pegasus = (pegasus_t *) net->priv;
	int res;

	if (pegasus->rx_skb == NULL)
		pegasus->rx_skb = pull_skb(pegasus);
	/*
	 ** Note: no point to free the pool.  it is empty :-)
	 */
	if (!pegasus->rx_skb)
		return -ENOMEM;

	set_registers(pegasus, EthID, 6, net->dev_addr);
	
	usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
			  usb_rcvbulkpipe(pegasus->usb, 1),
			  pegasus->rx_skb->data, PEGASUS_MTU + 8,
			  read_bulk_callback, pegasus);
	if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL)))
		warn("%s: failed rx_urb %d", __FUNCTION__, res);
	usb_fill_int_urb(pegasus->intr_urb, pegasus->usb,
			 usb_rcvintpipe(pegasus->usb, 3),
			 pegasus->intr_buff, sizeof (pegasus->intr_buff),
			 intr_callback, pegasus, pegasus->intr_interval);
	if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL)))
		warn("%s: failed intr_urb %d", __FUNCTION__, res);
	netif_start_queue(net);
	pegasus->flags |= PEGASUS_RUNNING;
	if ((res = enable_net_traffic(net, pegasus->usb))) {
		err("can't enable_net_traffic() - %d", res);
		res = -EIO;
		usb_unlink_urb(pegasus->rx_urb);
		usb_unlink_urb(pegasus->intr_urb);
		free_skb_pool(pegasus);
		goto exit;
	}
	set_carrier(net);
	res = 0;
exit:
	return res;
}
Esempio n. 3
0
static int pegasus_probe(struct usb_interface *intf,
			 const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	struct net_device *net;
	pegasus_t *pegasus;
	int dev_index = id - pegasus_ids;
	int res = -ENOMEM;

	usb_get_dev(dev);
	if (!(pegasus = kmalloc(sizeof (struct pegasus), GFP_KERNEL))) {
		err("out of memory allocating device structure");
		goto out;
	}

	memset(pegasus, 0, sizeof (struct pegasus));
	pegasus->dev_index = dev_index;
	init_waitqueue_head(&pegasus->ctrl_wait);

	if (!alloc_urbs(pegasus))
		goto out1;

	net = alloc_etherdev(0);
	if (!net)
		goto out2;

	tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus);

	pegasus->usb = dev;
	pegasus->net = net;
	SET_MODULE_OWNER(net);
	net->priv = pegasus;
	net->open = pegasus_open;
	net->stop = pegasus_close;
	net->watchdog_timeo = PEGASUS_TX_TIMEOUT;
	net->tx_timeout = pegasus_tx_timeout;
	net->do_ioctl = pegasus_ioctl;
	net->hard_start_xmit = pegasus_start_xmit;
	net->set_multicast_list = pegasus_set_multicast;
	net->get_stats = pegasus_netdev_stats;
	net->mtu = PEGASUS_MTU;
	pegasus->mii.dev = net;
	pegasus->mii.mdio_read = mdio_read;
	pegasus->mii.mdio_write = mdio_write;
	pegasus->mii.phy_id_mask = 0x1f;
	pegasus->mii.reg_num_mask = 0x1f;
	spin_lock_init(&pegasus->rx_pool_lock);

	pegasus->features = usb_dev_id[dev_index].private;
	get_interrupt_interval(pegasus);
	if (reset_mac(pegasus)) {
		err("can't reset MAC");
		res = -EIO;
		goto out3;
	}
	set_ethernet_addr(pegasus);
	fill_skb_pool(pegasus);
	if (pegasus->features & PEGASUS_II) {
		info("setup Pegasus II specific registers");
		setup_pegasus_II(pegasus);
	}
	pegasus->phy = mii_phy_probe(pegasus);
	if (pegasus->phy == 0xff) {
		warn("can't locate MII phy, using default");
		pegasus->phy = 1;
	}
	usb_set_intfdata(intf, pegasus);
	SET_NETDEV_DEV(net, &intf->dev);
	res = register_netdev(net);
	if (res)
		goto out4;
	printk("%s: %s\n", net->name, usb_dev_id[dev_index].name);
	return 0;

out4:
	usb_set_intfdata(intf, NULL);
	free_skb_pool(pegasus);
out3:
	free_netdev(net);
out2:
	free_all_urbs(pegasus);
out1:
	kfree(pegasus);
out:
	usb_put_dev(dev);
	return res;
}