Example #1
0
int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
{
	struct usbnet		*dev = usb_get_intfdata(intf);

	pr_info("%s+\n", __func__);

	if (!dev->suspend_count++) {
		spin_lock_irq(&dev->txq.lock);
		/* don't autosuspend while transmitting */
		if (dev->txq.qlen && (message.event & PM_EVENT_AUTO)) {
			spin_unlock_irq(&dev->txq.lock);
			--dev->suspend_count;
			return -EBUSY;
		} else {
			set_bit(EVENT_DEV_ASLEEP, &dev->flags);
			spin_unlock_irq(&dev->txq.lock);
		}
		/*
		 * accelerate emptying of the rx and queues, to avoid
		 * having everything error out.
		 */
		pr_info("%s+:d\n", __func__);
		netif_device_detach (dev->net);
		pr_info("%s+:t\n", __func__);
		usbnet_terminate_urbs(dev);
		pr_info("%s+:k\n", __func__);
		usb_kill_urb(dev->interrupt);

		/*
		 * reattach so runtime management can use and
		 * wake the device
		 */
		pr_info("%s+:a\n", __func__);
		netif_device_attach (dev->net);
	}
	pr_info("%s-\n", __func__);
	return 0;
}
int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
{
	struct usbnet		*dev = usb_get_intfdata(intf);

	if (!dev->suspend_count++) {
#if defined(CONFIG_ERICSSON_F3307_ENABLE)
		spin_lock_irq(&dev->txq.lock);
		/* don't autosuspend while transmitting */
		if (dev->txq.qlen && (message.event & PM_EVENT_AUTO)) {
			spin_unlock_irq(&dev->txq.lock);
			return -EBUSY;
		} else {
			set_bit(EVENT_DEV_ASLEEP, &dev->flags);
			spin_unlock_irq(&dev->txq.lock);
		}
#endif
		/*
		 * accelerate emptying of the rx and queues, to avoid
		 * having everything error out.
		 */
		netif_device_detach (dev->net);
#if !defined(CONFIG_ERICSSON_F3307_ENABLE)
		(void) unlink_urbs (dev, &dev->rxq);
		(void) unlink_urbs (dev, &dev->txq);
#else
		usbnet_terminate_urbs(dev);
		usb_kill_urb(dev->interrupt);
#endif

		/*
		 * reattach so runtime management can use and
		 * wake the device
		 */
		netif_device_attach (dev->net);
	}
	return 0;
}
Example #3
0
static int rmnet_usb_suspend(struct usb_interface *iface, pm_message_t message)
{
	struct usbnet		*unet = usb_get_intfdata(iface);
	struct rmnet_ctrl_dev	*dev;
	int			i, n, rdev_cnt, unet_id;
	int			retval = 0;

	rdev_cnt = unet->data[4] ? no_rmnet_insts_per_dev : 1;

	for (n = 0; n < rdev_cnt; n++) {
		unet_id = n + unet->driver_info->data * no_rmnet_insts_per_dev;
		unet =
		unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);

		dev = (struct rmnet_ctrl_dev *)unet->data[1];
		spin_lock_irq(&unet->txq.lock);
		if (work_busy(&dev->get_encap_work) || unet->txq.qlen) {
			spin_unlock_irq(&unet->txq.lock);
			retval = -EBUSY;
			goto abort_suspend;
		}

		set_bit(EVENT_DEV_ASLEEP, &unet->flags);
		spin_unlock_irq(&unet->txq.lock);

		usb_kill_anchored_urbs(&dev->rx_submitted);
		if (work_busy(&dev->get_encap_work)) {
			spin_lock_irq(&unet->txq.lock);
			clear_bit(EVENT_DEV_ASLEEP, &unet->flags);
			spin_unlock_irq(&unet->txq.lock);
			retval = -EBUSY;
			goto abort_suspend;
		}
	}

	for (n = 0; n < rdev_cnt; n++) {
		unet_id = n + unet->driver_info->data * no_rmnet_insts_per_dev;
		unet =
		unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);

		dev = (struct rmnet_ctrl_dev *)unet->data[1];
		netif_device_detach(unet->net);
		usbnet_terminate_urbs(unet);
		netif_device_attach(unet->net);
	}

	#if defined(CONFIG_MONITOR_STREAMING_PORT_SOCKET) && defined(CONFIG_MSM_NONSMD_PACKET_FILTER)
	if (use_extend_suspend_timer) {
	    if (original_autosuspend_timer != 0) {
	        struct usb_device	*udev= unet->udev;

	        if (udev) {
	            use_extend_suspend_timer= false;
	            pm_runtime_set_autosuspend_delay(&udev->dev, original_autosuspend_timer);
	            dev_err(&udev->dev, "is_streaming_sock_connectted:%d pm_runtime_set_autosuspend_delay %d\n", is_streaming_sock_connectted, original_autosuspend_timer);
	        }
	    }
	}
	#endif 

	return 0;

abort_suspend:
	for (i = 0; i < n; i++) {
		unet_id = i + unet->driver_info->data * no_rmnet_insts_per_dev;
		unet =
		unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);

		dev = (struct rmnet_ctrl_dev *)unet->data[1];
		rmnet_usb_ctrl_start_rx(dev);
		spin_lock_irq(&unet->txq.lock);
		clear_bit(EVENT_DEV_ASLEEP, &unet->flags);
		spin_unlock_irq(&unet->txq.lock);
	}
	return retval;
}
static int rmnet_usb_suspend(struct usb_interface *iface, pm_message_t message)
{
	struct usbnet		*unet = usb_get_intfdata(iface);
	struct rmnet_ctrl_dev	*dev;
	int			i, n, rdev_cnt, unet_id;
	int			retval = 0;

	rdev_cnt = unet->data[4] ? no_rmnet_insts_per_dev : 1;

	for (n = 0; n < rdev_cnt; n++) {
		unet_id = n + unet->driver_info->data * no_rmnet_insts_per_dev;
		unet =
		unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);

		dev = (struct rmnet_ctrl_dev *)unet->data[1];
		spin_lock_irq(&unet->txq.lock);
		if (work_busy(&dev->get_encap_work) || unet->txq.qlen) {
			spin_unlock_irq(&unet->txq.lock);
			retval = -EBUSY;
			goto abort_suspend;
		}

		set_bit(EVENT_DEV_ASLEEP, &unet->flags);
		spin_unlock_irq(&unet->txq.lock);

		usb_kill_anchored_urbs(&dev->rx_submitted);
		if (work_busy(&dev->get_encap_work)) {
			spin_lock_irq(&unet->txq.lock);
			clear_bit(EVENT_DEV_ASLEEP, &unet->flags);
			spin_unlock_irq(&unet->txq.lock);
			retval = -EBUSY;
			goto abort_suspend;
		}
	}

	for (n = 0; n < rdev_cnt; n++) {
		unet_id = n + unet->driver_info->data * no_rmnet_insts_per_dev;
		unet =
		unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);

		dev = (struct rmnet_ctrl_dev *)unet->data[1];
		netif_device_detach(unet->net);
		usbnet_terminate_urbs(unet);
		netif_device_attach(unet->net);
	}

	return 0;

abort_suspend:
	for (i = 0; i < n; i++) {
		unet_id = i + unet->driver_info->data * no_rmnet_insts_per_dev;
		unet =
		unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);

		dev = (struct rmnet_ctrl_dev *)unet->data[1];
		rmnet_usb_ctrl_start_rx(dev);
		spin_lock_irq(&unet->txq.lock);
		clear_bit(EVENT_DEV_ASLEEP, &unet->flags);
		spin_unlock_irq(&unet->txq.lock);
	}
	return retval;
}
int usbnet_stop (struct net_device *net)
{
	struct usbnet		*dev = netdev_priv(net);
	struct driver_info	*info = dev->driver_info;
#if !defined(CONFIG_ERICSSON_F3307_ENABLE)
	int			temp;
#endif
	int			retval;
#if !defined(CONFIG_ERICSSON_F3307_ENABLE)
	DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup);
	DECLARE_WAITQUEUE (wait, current);
#endif
	netif_stop_queue (net);

	if (netif_msg_ifdown (dev))
		devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld",
			net->stats.rx_packets, net->stats.tx_packets,
			net->stats.rx_errors, net->stats.tx_errors
			);

	/* allow minidriver to stop correctly (wireless devices to turn off
	 * radio etc) */
	if (info->stop) {
		retval = info->stop(dev);
		if (retval < 0 && netif_msg_ifdown(dev))
			devinfo(dev,
				"stop fail (%d) usbnet usb-%s-%s, %s",
				retval,
				dev->udev->bus->bus_name, dev->udev->devpath,
				info->description);
	}
#if !defined(CONFIG_ERICSSON_F3307_ENABLE)
	if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) {
		/* ensure there are no more active urbs */
		add_wait_queue(&unlink_wakeup, &wait);
		dev->wait = &unlink_wakeup;
		temp = unlink_urbs(dev, &dev->txq) +
			unlink_urbs(dev, &dev->rxq);

		/* maybe wait for deletions to finish. */
		while (!skb_queue_empty(&dev->rxq)
				&& !skb_queue_empty(&dev->txq)
				&& !skb_queue_empty(&dev->done)) {
			msleep(UNLINK_TIMEOUT_MS);
			if (netif_msg_ifdown(dev))
				devdbg(dev, "waited for %d urb completions",
					temp);
		}
		dev->wait = NULL;
		remove_wait_queue(&unlink_wakeup, &wait);
	}
#else
	if (!(info->flags & FLAG_AVOID_UNLINK_URBS))
 		usbnet_terminate_urbs(dev);
#endif

	usb_kill_urb(dev->interrupt);

	usbnet_purge_paused_rxq(dev);

	/* deferred work (task, timer, softirq) must also stop.
	 * can't flush_scheduled_work() until we drop rtnl (later),
	 * else workers could deadlock; so make workers a NOP.
	 */
	dev->flags = 0;
	del_timer_sync (&dev->delay);
	tasklet_kill (&dev->bh);
#if !defined(CONFIG_ERICSSON_F3307_ENABLE)
	usb_autopm_put_interface(dev->intf);
#else
	if (info->manage_power)
		info->manage_power(dev, 0);
	else
		usb_autopm_put_interface(dev->intf);
#endif

	return 0;
}