Ejemplo n.º 1
0
/**
 *	iowarrior_disconnect
 *
 *	Called by the usb core when the device is removed from the system.
 */
static void iowarrior_disconnect(struct usb_interface *interface)
{
	struct iowarrior *dev;
	int minor;

	dev = usb_get_intfdata(interface);
	mutex_lock(&iowarrior_open_disc_lock);
	usb_set_intfdata(interface, NULL);

	minor = dev->minor;

	/* give back our minor */
	usb_deregister_dev(interface, &iowarrior_class);

	mutex_lock(&dev->mutex);

	/* prevent device read, write and ioctl */
	dev->present = 0;

	mutex_unlock(&dev->mutex);
	mutex_unlock(&iowarrior_open_disc_lock);

	if (dev->opened) {
		/* There is a process that holds a filedescriptor to the device ,
		   so we only shutdown read-/write-ops going on.
		   Deleting the device is postponed until close() was called.
		 */
		usb_kill_urb(dev->int_in_urb);
		wake_up_interruptible(&dev->read_wait);
		wake_up_interruptible(&dev->write_wait);
	} else {
		/* no process is using the device, cleanup now */
		iowarrior_delete(dev);
	}

	dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n",
		 minor - IOWARRIOR_MINOR_BASE);
}
Ejemplo n.º 2
0
static int acm_resume(struct usb_interface *intf)
{
	struct acm *acm = usb_get_intfdata(intf);
	struct urb *urb;
	int rv = 0;

	spin_lock_irq(&acm->read_lock);
	spin_lock(&acm->write_lock);

	if (--acm->susp_count)
		goto out;

	if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {
		rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);

		for (;;) {
			urb = usb_get_from_anchor(&acm->delayed);
			if (!urb)
				break;

			acm_start_wb(acm, urb->context);
		}

		/*
		 * delayed error checking because we must
		 * do the write path at all cost
		 */
		if (rv < 0)
			goto out;

		rv = acm_submit_read_urbs(acm, GFP_ATOMIC);
	}
out:
	spin_unlock(&acm->write_lock);
	spin_unlock_irq(&acm->read_lock);

	return rv;
}
Ejemplo n.º 3
0
Archivo: usblcd.c Proyecto: 274914765/C
static int lcd_open(struct inode *inode, struct file *file)
{
    struct usb_lcd *dev;
    struct usb_interface *interface;
    int subminor, r;

    subminor = iminor(inode);

    interface = usb_find_interface(&lcd_driver, subminor);
    if (!interface) {
        err ("USBLCD: %s - error, can't find device for minor %d",
             __func__, subminor);
        return -ENODEV;
    }

    mutex_lock(&open_disc_mutex);
    dev = usb_get_intfdata(interface);
    if (!dev) {
        mutex_unlock(&open_disc_mutex);
        return -ENODEV;
    }

    /* increment our usage count for the device */
    kref_get(&dev->kref);
    mutex_unlock(&open_disc_mutex);

    /* grab a power reference */
    r = usb_autopm_get_interface(interface);
    if (r < 0) {
        kref_put(&dev->kref, lcd_delete);
        return r;
    }

    /* save our object in the file's private structure */
    file->private_data = dev;

    return 0;
}
Ejemplo n.º 4
0
static void mwifiex_usb_disconnect(struct usb_interface *intf)
{
	struct usb_card_rec *card = usb_get_intfdata(intf);
	struct mwifiex_adapter *adapter;

	if (!card || !card->adapter) {
		pr_err("%s: card or card->adapter is NULL\n", __func__);
		return;
	}

	adapter = card->adapter;
	if (!adapter->priv_num)
		return;

	if (user_rmmod) {
#ifdef CONFIG_PM
		if (adapter->is_suspended)
			mwifiex_usb_resume(intf);
#endif

		mwifiex_deauthenticate_all(adapter);

		mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
							  MWIFIEX_BSS_ROLE_ANY),
					 MWIFIEX_FUNC_SHUTDOWN);
	}

	mwifiex_usb_free(card);

	dev_dbg(adapter->dev, "%s: removing card\n", __func__);
	mwifiex_remove_card(adapter, &add_remove_card_sem);

	usb_set_intfdata(intf, NULL);
	usb_put_dev(interface_to_usbdev(intf));
	kfree(card);

	return;
}
Ejemplo n.º 5
0
/*
 * Disconnect USB device (maybe the MDC800)
 */
static void mdc800_usb_disconnect (struct usb_interface *intf)
{
	struct mdc800_data* mdc800 = usb_get_intfdata(intf);

	dbg ("(mdc800_usb_disconnect) called");

	if (mdc800) {
		if (mdc800->state == NOT_CONNECTED)
			return;

		usb_deregister_dev(intf, &mdc800_class);

		mdc800->state=NOT_CONNECTED;

		usb_unlink_urb (mdc800->irq_urb);
		usb_unlink_urb (mdc800->write_urb);
		usb_unlink_urb (mdc800->download_urb);

		mdc800->dev = NULL;
		usb_set_intfdata(intf, NULL);
	}
	info ("Mustek MDC800 disconnected from USB.");
}
Ejemplo n.º 6
0
static int bladerf_open(struct inode *inode, struct file *file)
{
    bladerf_device_t *dev;
    struct usb_interface *interface;
    int subminor;

    subminor = iminor(inode);

    interface = usb_find_interface(&bladerf_driver, subminor);
    if (interface == NULL) {
        pr_err("%s - error, cannot find device for minor %d\n", __func__, subminor);
        return -ENODEV;
    }

    dev = usb_get_intfdata(interface);
    if (dev == NULL) {
        return -ENODEV;
    }

    file->private_data = dev;

    return 0;
}
Ejemplo n.º 7
0
/* The user yanked out the cable... */
static void usb_pwc_disconnect(struct usb_interface *intf)
{
	struct v4l2_device *v = usb_get_intfdata(intf);
	struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);

	mutex_lock(&pdev->udevlock);
	/* No need to keep the urbs around after disconnection */
	pwc_isoc_cleanup(pdev);
	pdev->udev = NULL;
	mutex_unlock(&pdev->udevlock);

	pwc_cleanup_queued_bufs(pdev);

	video_unregister_device(&pdev->vdev);
	v4l2_device_unregister(&pdev->v4l2_dev);

#ifdef CONFIG_USB_PWC_INPUT_EVDEV
	if (pdev->button_dev)
		input_unregister_device(pdev->button_dev);
#endif

	v4l2_device_put(&pdev->v4l2_dev);
}
static void si470x_usb_driver_disconnect(struct usb_interface *intf)
{
	struct si470x_device *radio = usb_get_intfdata(intf);

	mutex_lock(&radio->lock);
	radio->disconnected = 1;
	usb_set_intfdata(intf, NULL);
	if (radio->users == 0) {
		/*                             */
		si470x_set_led_state(radio, BLINK_ORANGE_LED);

		/*                       */
		usb_free_urb(radio->int_in_urb);

		kfree(radio->int_in_buffer);
		video_unregister_device(radio->videodev);
		kfree(radio->buffer);
		mutex_unlock(&radio->lock);
		kfree(radio);
	} else {
		mutex_unlock(&radio->lock);
	}
}
Ejemplo n.º 9
0
static
int i2400mu_resume(struct usb_interface *iface)
{
	int ret = 0;
	struct device *dev = &iface->dev;
	struct i2400mu *i2400mu = usb_get_intfdata(iface);
	struct i2400m *i2400m = &i2400mu->i2400m;

	d_fnstart(3, dev, "(iface %p)\n", iface);
	rmb();		/*                                     */
	if (i2400m->updown == 0) {
		d_printf(1, dev, "fw was down, no resume neeed\n");
		goto out;
	}
	d_printf(1, dev, "fw was up, resuming\n");
	i2400mu_notification_setup(i2400mu);
	/*                                                          
                                                             
               */
out:
	d_fnend(3, dev, "(iface %p) = %d\n", iface, ret);
	return ret;
}
Ejemplo n.º 10
0
static void chatpad_disconnect(struct usb_interface *intf)
{
  printk(KERN_INFO "chatpad_disconnect()\n");
  {
    struct usb_chatpad* chatpad = usb_get_intfdata(intf);

    // stop the keepalive messages
    cancel_delayed_work(&chatpad->worker);
    flush_delayed_work(&chatpad->worker);

    // kill the urb
    usb_kill_urb(chatpad->chatpad_urb);
    usb_free_urb(chatpad->chatpad_urb);

    // kill the urb
    usb_kill_urb(chatpad->control_urb);
    usb_free_urb(chatpad->control_urb);

    // deallocate memory
    usb_buffer_free(chatpad->udev, 32, chatpad->chatpad_idata, chatpad->chatpad_idata_dma);
    kfree(chatpad);
  }
}
Ejemplo n.º 11
0
static void skel_disconnect(struct usb_interface *interface)
{
	struct usb_skel *dev;
	int minor = interface->minor;

	/* prevent skel_open() from racing skel_disconnect() */
	//lock_kernel();

	dev = usb_get_intfdata(interface);
	disable_irq(dev->irqN);
	free_irq(dev->irqN, dev->udev);
	usb_set_intfdata(interface, NULL);

	/* give back our minor */
	usb_deregister_dev(interface, &skel_class);

	//unlock_kernel();

	/* decrement our usage count */
	kref_put(&dev->kref, skel_delete);

	printk(KERN_DEBUG "[HALEEQ PIANO]: USB Skeleton #%d now disconnected\n", minor);
}
static void skel_disconnect(struct usb_interface *interface)
{
	struct usb_skel *dev;
	int minor = interface->minor;

	dev = usb_get_intfdata(interface);
	usb_set_intfdata(interface, NULL);

	
	usb_deregister_dev(interface, &skel_class);

	
	mutex_lock(&dev->io_mutex);
	dev->interface = NULL;
	mutex_unlock(&dev->io_mutex);

	usb_kill_anchored_urbs(&dev->submitted);

	
	kref_put(&dev->kref, skel_delete);

	dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor);
}
Ejemplo n.º 13
0
/**
 *  @brief free resource and cleanup
 *  @param intf		USB interface structure
 *  @return 	   	N/A
 */
static void if_usb_disconnect(struct usb_interface *intf)
{
	struct if_usb_card *cardp = usb_get_intfdata(intf);
	struct lbs_private *priv = (struct lbs_private *) cardp->priv;

	lbs_deb_enter(LBS_DEB_MAIN);

	cardp->surprise_removed = 1;

	if (priv) {
		priv->surpriseremoved = 1;
		lbs_stop_card(priv);
		lbs_remove_card(priv);
	}

	/* Unlink and free urb */
	if_usb_free(cardp);

	usb_set_intfdata(intf, NULL);
	usb_put_dev(interface_to_usbdev(intf));

	lbs_deb_leave(LBS_DEB_MAIN);
}
Ejemplo n.º 14
0
Archivo: xpad.c Proyecto: 19Dan01/linux
static void xpad_disconnect(struct usb_interface *intf)
{
	struct usb_xpad *xpad = usb_get_intfdata (intf);

	xpad_led_disconnect(xpad);
	input_unregister_device(xpad->dev);
	xpad_deinit_output(xpad);

	if (xpad->xtype == XTYPE_XBOX360W) {
		usb_kill_urb(xpad->bulk_out);
		usb_free_urb(xpad->bulk_out);
		usb_kill_urb(xpad->irq_in);
	}

	usb_free_urb(xpad->irq_in);
	usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
			xpad->idata, xpad->idata_dma);

	kfree(xpad->bdata);
	kfree(xpad);

	usb_set_intfdata(intf, NULL);
}
Ejemplo n.º 15
0
static
int i2400mu_resume(struct usb_interface *iface)
{
	int ret = 0;
	struct device *dev = &iface->dev;
	struct i2400mu *i2400mu = usb_get_intfdata(iface);
	struct i2400m *i2400m = &i2400mu->i2400m;

	d_fnstart(3, dev, "(iface %p)\n", iface);
	rmb();		/* see i2400m->updown's documentation  */
	if (i2400m->updown == 0) {
		d_printf(1, dev, "fw was down, no resume neeed\n");
		goto out;
	}
	d_printf(1, dev, "fw was up, resuming\n");
	i2400mu_notification_setup(i2400mu);
	/* USB has flow control, so we don't need to give it time to
	 * come back; otherwise, we'd use something like a get-state
	 * command... */
out:
	d_fnend(3, dev, "(iface %p) = %d\n", iface, ret);
	return ret;
}
Ejemplo n.º 16
0
static void as102_usb_disconnect(struct usb_interface *intf)
{
	struct as102_dev_t *as102_dev;

	/* extract as102_dev_t from usb_device private data */
	as102_dev = usb_get_intfdata(intf);

	/* unregister dvb layer */
	as102_dvb_unregister(as102_dev);

	/* free usb buffers */
	as102_free_usb_stream_buffer(as102_dev);

	usb_set_intfdata(intf, NULL);

	/* usb unregister device */
	usb_deregister_dev(intf, &as102_usb_class_driver);

	/* decrement usage counter */
	kref_put(&as102_dev->kref, as102_usb_release);

	pr_info("%s: device has been disconnected\n", DRIVER_NAME);
}
Ejemplo n.º 17
0
static void asus_oled_disconnect(struct usb_interface *interface)
{
	struct asus_oled_dev *odev;

	odev = usb_get_intfdata(interface);
	usb_set_intfdata(interface, NULL);

	device_remove_file(odev->dev, &dev_attr_picture);
	device_remove_file(odev->dev, &dev_attr_enabled);
	device_unregister(odev->dev);

	device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
	device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));

	usb_put_dev(odev->udev);

	if (odev->buf)
		kfree(odev->buf);

	kfree(odev);

	dev_info(&interface->dev, "Disconnected Asus OLED device\n");
}
Ejemplo n.º 18
0
static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct wdm_device *desc = usb_get_intfdata(intf);
	int rv = 0;

	dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);

	mutex_lock(&desc->plock);
#ifdef CONFIG_PM
	if ((message.event & PM_EVENT_AUTO) &&
			test_bit(WDM_IN_USE, &desc->flags)) {
		rv = -EBUSY;
	} else {
#endif
		cancel_work_sync(&desc->rxwork);
		kill_urbs(desc);
#ifdef CONFIG_PM
	}
#endif
	mutex_unlock(&desc->plock);

	return rv;
}
Ejemplo n.º 19
0
/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() => how to recognize both */
static void rtw_dev_remove(struct usb_interface *pusb_intf)
{
	struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
	struct adapter *padapter = dvobj->if1;

	pr_debug("+rtw_dev_remove\n");
	RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n"));

	if (!pusb_intf->unregistering)
		padapter->bSurpriseRemoved = true;

	rtw_pm_set_ips(padapter, IPS_NONE);
	rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);

	LeaveAllPowerSaveMode(padapter);

	rtw_usb_if1_deinit(padapter);

	usb_dvobj_deinit(pusb_intf);

	RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-dev_remove()\n"));
	pr_debug("-r871xu_dev_remove, done\n");
}
Ejemplo n.º 20
0
/*
	Variax destructor.
*/
static void variax_destruct(struct usb_interface *interface)
{
	struct usb_line6_variax *variax = usb_get_intfdata(interface);
	struct usb_line6 *line6;

	if (variax == NULL)
		return;
	line6 = &variax->line6;
	if (line6 == NULL)
		return;
	line6_cleanup_audio(line6);

	del_timer(&variax->startup_timer1);
	del_timer(&variax->startup_timer2);
	cancel_work_sync(&variax->startup_work);

	/* free dump request data: */
	line6_dumpreq_destructbuf(&variax->dumpreq, 2);
	line6_dumpreq_destructbuf(&variax->dumpreq, 1);
	line6_dumpreq_destruct(&variax->dumpreq);

	kfree(variax->buffer_activate);
}
Ejemplo n.º 21
0
static void skel_disconnect(struct usb_interface *interface)
{
	struct usb_skel *dev;
	int minor = interface->minor;

	dev = usb_get_intfdata(interface);
	usb_set_intfdata(interface, NULL);

	/* give back our minor */
	usb_deregister_dev(interface, &skel_class);

	/* prevent more I/O from starting */
	mutex_lock(&dev->io_mutex);
	dev->interface = NULL;
	mutex_unlock(&dev->io_mutex);

	usb_kill_anchored_urbs(&dev->submitted);

	/* decrement our usage count */
	kref_put(&dev->kref, skel_delete);

	dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor);
}
Ejemplo n.º 22
0
static void avrBridge_disconnect(struct usb_interface *interface)
{
	struct avrBridge *dev;

	dev = usb_get_intfdata (interface);

	usb_deregister_dev(interface,&avrBridge_class);

	remove_proc_entry("portB", port_dir);
	remove_proc_entry("ports", avrBridge_dir);
	remove_proc_entry("pins", avrBridge_dir);
	remove_proc_entry("avrBridge", NULL);

	
	/* first remove the files, then set the pointer to NULL */
	usb_set_intfdata (interface, NULL);

	usb_put_dev(dev->udev);

	kfree(dev);

	dev_info(&interface->dev, "avrBridge now disconnected\n");
}
Ejemplo n.º 23
0
/*
	Generic destructor.
*/
static void line6_destruct(struct usb_interface *interface)
{
	struct usb_line6 *line6;

	if (interface == NULL)
		return;
	line6 = usb_get_intfdata(interface);
	if (line6 == NULL)
		return;

	/* free buffer memory first: */
	kfree(line6->buffer_message);
	kfree(line6->buffer_listen);

	/* then free URBs: */
	usb_free_urb(line6->urb_listen);

	/* make sure the device isn't destructed twice: */
	usb_set_intfdata(interface, NULL);

	/* free interface data: */
	kfree(line6);
}
Ejemplo n.º 24
0
static void _rtl_rx_work(unsigned long param)
{
	struct rtl_usb *rtlusb = (struct rtl_usb *)param;
	struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf);
	struct sk_buff *skb;

	while ((skb = skb_dequeue(&rtlusb->rx_queue))) {
		if (unlikely(IS_USB_STOP(rtlusb))) {
			dev_kfree_skb_any(skb);
			continue;
		}

		if (likely(!rtlusb->usb_rx_hdl(hw, skb))) {
			if (likely(!rtlusb->usb_rx_segregate_hdl)) {
				_rtl_usb_rx_process_noagg(hw, skb);
			} else {
				/* TO DO */
				_rtl_rx_pre_process(hw, skb);
				pr_err("rx agg not supported\n");
			}
		}
	}
}
Ejemplo n.º 25
0
static void wdm_disconnect(struct usb_interface *intf)
{
	struct wdm_device *desc;
	unsigned long flags;

	usb_deregister_dev(intf, &wdm_class);
	mutex_lock(&wdm_mutex);
	desc = usb_get_intfdata(intf);

	/* the spinlock makes sure no new urbs are generated in the callbacks */
	spin_lock_irqsave(&desc->iuspin, flags);
	set_bit(WDM_DISCONNECTING, &desc->flags);
	set_bit(WDM_READ, &desc->flags);
	/* to terminate pending flushes */
	clear_bit(WDM_IN_USE, &desc->flags);
	spin_unlock_irqrestore(&desc->iuspin, flags);
	cancel_work_sync(&desc->rxwork);
	kill_urbs(desc);
	wake_up_all(&desc->wait);
	if (!desc->count)
		cleanup(desc);
	mutex_unlock(&wdm_mutex);
}
Ejemplo n.º 26
0
static int as102_open(struct inode *inode, struct file *file)
{
	int ret = 0, minor = 0;
	struct usb_interface *intf = NULL;
	struct as102_dev_t *dev = NULL;

	ENTER();

	/* read minor from inode */
	minor = iminor(inode);

	/* fetch device from usb interface */
	intf = usb_find_interface(&as102_usb_driver, minor);
	if (intf == NULL) {
		printk(KERN_ERR "%s: can't find device for minor %d\n",
				__func__, minor);
		ret = -ENODEV;
		goto exit;
	}

	/* get our device */
	dev = usb_get_intfdata(intf);
	if (dev == NULL) {
		ret = -EFAULT;
		goto exit;
	}

	/* save our device object in the file's private structure */
	file->private_data = dev;

	/* increment our usage count for the device */
	kref_get(&dev->kref);

exit:
	LEAVE();
	return ret;
}
static void ft1000_disconnect(struct usb_interface *interface)
{
	struct ft1000_info *pft1000info;

	DEBUG("ft1000_disconnect is called\n");

	pft1000info = (struct ft1000_info *) usb_get_intfdata(interface);
	DEBUG("In disconnect pft1000info=%p\n", pft1000info);

	if (pft1000info) {
		ft1000_cleanup_proc(pft1000info);
		if (pft1000info->pPollThread)
			kthread_stop(pft1000info->pPollThread);

		DEBUG("ft1000_disconnect: threads are terminated\n");

		if (pft1000info->pFt1000Dev->net) {
			DEBUG("ft1000_disconnect: destroy char driver\n");
			ft1000_destroy_dev(pft1000info->pFt1000Dev->net);
			unregister_netdev(pft1000info->pFt1000Dev->net);
			DEBUG
			    ("ft1000_disconnect: network device unregisterd\n");
			free_netdev(pft1000info->pFt1000Dev->net);

		}

		usb_free_urb(pft1000info->pFt1000Dev->rx_urb);
		usb_free_urb(pft1000info->pFt1000Dev->tx_urb);

		DEBUG("ft1000_disconnect: urb freed\n");

		kfree(pft1000info->pFt1000Dev);
	}
	kfree(pFileStart);

	return;
}
Ejemplo n.º 28
0
/**
 * adu_disconnect
 *
 * Called by the usb core when the device is removed from the system.
 */
static void adu_disconnect(struct usb_interface *interface)
{
	struct adu_device *dev;
	int minor;

	dbg(2," %s : enter", __FUNCTION__);

	mutex_lock(&disconnect_mutex); /* not interruptible */

	dev = usb_get_intfdata(interface);
	usb_set_intfdata(interface, NULL);

	down(&dev->sem); /* not interruptible */

	minor = dev->minor;

	/* give back our minor */
	usb_deregister_dev(interface, &adu_class);
	dev->minor = 0;

	/* if the device is not opened, then we clean up right now */
	dbg(2," %s : open count %d", __FUNCTION__, dev->open_count);
	if (!dev->open_count) {
		up(&dev->sem);
		adu_delete(dev);
	} else {
		dev->udev = NULL;
		up(&dev->sem);
	}

	mutex_unlock(&disconnect_mutex);

	dev_info(&interface->dev, "ADU device adutux%d now disconnected",
		 (minor - ADU_MINOR_BASE));

	dbg(2," %s : leave", __FUNCTION__);
}
Ejemplo n.º 29
0
static int acm_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct acm *acm = usb_get_intfdata(intf);
	int cnt;

	if (message.event & PM_EVENT_AUTO) {
		int b;

		spin_lock_irq(&acm->read_lock);
		spin_lock(&acm->write_lock);
		b = acm->processing + acm->transmitting;
		spin_unlock(&acm->write_lock);
		spin_unlock_irq(&acm->read_lock);
		if (b)
			return -EBUSY;
	}

	spin_lock_irq(&acm->read_lock);
	spin_lock(&acm->write_lock);
	cnt = acm->susp_count++;
	spin_unlock(&acm->write_lock);
	spin_unlock_irq(&acm->read_lock);

	if (cnt)
		return 0;
	/*
	we treat opened interfaces differently,
	we must guard against open
	*/
	mutex_lock(&acm->mutex);

	if (acm->port.count)
		stop_data_traffic(acm);

	mutex_unlock(&acm->mutex);
	return 0;
}
Ejemplo n.º 30
0
static void ksb_usb_disconnect(struct usb_interface *ifc)
{
	struct ks_bridge *ksb = usb_get_intfdata(ifc);
	unsigned long flags;
	struct data_pkt *pkt;

	dbg_log_event(ksb, "PID-DETACH", 0, 0);

	clear_bit(USB_DEV_CONNECTED, &ksb->flags);
	wake_up(&ksb->ks_wait_q);
	cancel_work_sync(&ksb->to_mdm_work);

	usb_kill_anchored_urbs(&ksb->submitted);

	spin_lock_irqsave(&ksb->lock, flags);
	while (!list_empty(&ksb->to_ks_list)) {
		pkt = list_first_entry(&ksb->to_ks_list,
				struct data_pkt, list);
		list_del_init(&pkt->list);
		ksb_free_data_pkt(pkt);
	}
	while (!list_empty(&ksb->to_mdm_list)) {
		pkt = list_first_entry(&ksb->to_mdm_list,
				struct data_pkt, list);
		list_del_init(&pkt->list);
		ksb_free_data_pkt(pkt);
	}
	spin_unlock_irqrestore(&ksb->lock, flags);

	misc_deregister(ksb->fs_dev);
	ifc->needs_remote_wakeup = 0;
	usb_put_dev(ksb->udev);
	ksb->ifc = NULL;
	usb_set_intfdata(ifc, NULL);

	return;
}