예제 #1
0
static int pcan_usb_stop(struct pcandev *dev)
{
	int err = 0;
	USB_PORT *u = &dev->port.usb;
	struct pcan_usb_interface *usb_if = u->usb_if;

	DPRINTK(KERN_DEBUG "%s: %s(CAN#%d), minor=%d\n", 
	        DEVICE_NAME, __FUNCTION__, u->dev_ctrl_index, dev->nMinor);

	if (usb_if->device_ctrl_close)
		err = usb_if->device_ctrl_close(dev);

	err = usb_if->device_ctrl_set_bus_off(dev);

#if 1
	/* let bus_off handler decide if we should wait or not */
#else
	// wait until all has settled
	mdelay(5);
#endif
	// unlink URBs for device/controller
	pcan_kill_sync_urb(&u->write_data);

	DPRINTK(KERN_ERR "%s: have still %d active URBs on interface\n", 
	        DEVICE_NAME, atomic_read(&usb_if->active_urbs));

	return err;
}
예제 #2
0
static void pcan_usb_plugout(struct usb_interface *interface)
{
	struct pcan_usb_interface *usb_if = usb_get_intfdata(interface);

	if (usb_if)
	{
		int c;
		struct pcandev *dev;

		for (dev=&usb_if->dev[c=0]; c < usb_if->dev_ctrl_count; c++, dev++)
		{
			DPRINTK(KERN_DEBUG "%s: %s(%d)\n", 
			        DEVICE_NAME, __FUNCTION__, dev->nMinor);

#ifdef NETDEV_SUPPORT
			pcan_usb_plugout_netdev(dev);
#endif

			// mark this device as plugged out
			dev->ucPhysicallyInstalled = 0;

			// do not remove resources if the device is still in use
			if (!dev->nOpenPaths)
				pcan_usb_cleanup(dev);

			pcan_kill_sync_urb(&dev->port.usb.write_data);

			interface->minor = dev->nMinor;
			usb_deregister_dev(interface, &pcan_class);
		}

		pcan_kill_sync_urb(&usb_if->urb_cmd_sync);
		pcan_kill_sync_urb(&usb_if->urb_cmd_async);
		pcan_kill_sync_urb(&usb_if->read_data);

		kfree(usb_if->read_buffer_addr[0]);

		if (usb_if->device_free)
			usb_if->device_free(usb_if);

		usb_reset_device(usb_if->usb_dev);

		kfree(usb_if);

		usb_set_intfdata(interface, NULL);
	}
}
예제 #3
0
static void pcan_usb_plugout(struct usb_interface *interface)
{
	struct pcan_usb_interface *usb_if = usb_get_intfdata(interface);

	DPRINTK(KERN_DEBUG "%s: %s(): usb_if=%p\n",
					DEVICE_NAME, __func__, usb_if);
	if (usb_if) {
		int c;
		struct pcandev *dev;

		for (dev=&usb_if->dev[c=0]; c < usb_if->dev_ctrl_count;
								c++, dev++) {
			DPRINTK(KERN_DEBUG "%s: %s(%d)\n",
			        DEVICE_NAME, __func__, dev->nMinor);

#ifdef PCAN_DEV_USES_ALT_NUM
			pcan_sysfs_del_attrs(dev->mapped_dev,
						pcan_usb_sysfs_attrs[c]);
#endif

#ifdef NETDEV_SUPPORT
			pcan_usb_plugout_netdev(dev);
#endif

			// mark this device as plugged out
			dev->ucPhysicallyInstalled = 0;

#if 0
			// do not remove resources if the device is still in use
			if (!dev->nOpenPaths)
				pcan_usb_cleanup(dev);
#else
			/*
			 * Should close all dev resources EVEN if the device is
			 * in use, otherwise application may not be noticed
			 * that the device was removed:
			 * CAN_Open(); while (1) CAN_Read(h);
			 */
			pcan_usb_cleanup(dev);

#endif
			/*
			 * don't forget to remove link to USB interface object
			 * from the device object (the USB interface will be
			 * freed next)
			 */
			dev->port.usb.usb_if = NULL;

			pcan_kill_sync_urb(&dev->port.usb.write_data);

			interface->minor = dev->nMinor;
			usb_deregister_dev(interface, &pcan_class);
		}

		pcan_kill_sync_urb(&usb_if->urb_cmd_sync);
		pcan_kill_sync_urb(&usb_if->urb_cmd_async);
		pcan_kill_sync_urb(&usb_if->read_data);

		kfree(usb_if->read_buffer_addr[0]);

		kfree(usb_if->cout_baddr);

		if (usb_if->device_free)
			usb_if->device_free(usb_if);

		usb_reset_device(usb_if->usb_dev);

		kfree(usb_if);

		usb_set_intfdata(interface, NULL);
	}
}