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; }
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); } }
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); } }