static void gigaset_disconnect(struct usb_interface *interface) { struct cardstate *cs; struct usb_cardstate *ucs; cs = usb_get_intfdata(interface); ucs = cs->hw.usb; dev_info(cs->dev, "disconnecting Gigaset USB adapter\n"); usb_kill_urb(ucs->read_urb); gigaset_stop(cs); usb_set_intfdata(interface, NULL); tasklet_kill(&cs->write_tasklet); usb_kill_urb(ucs->bulk_out_urb); kfree(ucs->bulk_out_buffer); usb_free_urb(ucs->bulk_out_urb); kfree(ucs->rcvbuf); usb_free_urb(ucs->read_urb); ucs->read_urb = ucs->bulk_out_urb = NULL; ucs->rcvbuf = ucs->bulk_out_buffer = NULL; usb_put_dev(ucs->udev); ucs->interface = NULL; ucs->udev = NULL; cs->dev = NULL; gigaset_freecs(cs); }
/** * usb_gigaset_exit * This function is called while unloading the kernel-module */ static void __exit usb_gigaset_exit(void) { gigaset_blockdriver(driver); /* => probe will fail * => no gigaset_start any more */ gigaset_shutdown(cardstate); /* from now on, no isdn callback should be possible */ /* deregister this driver with the USB subsystem */ usb_deregister(&gigaset_usb_driver); /* this will call the disconnect-callback */ /* from now on, no disconnect/probe callback should be running */ gigaset_freecs(cardstate); cardstate = NULL; gigaset_freedriver(driver); driver = NULL; }
/** * usb_gigaset_init * This function is called while kernel-module is loaded */ static int __init usb_gigaset_init(void) { int result; /* allocate memory for our driver state and intialize it */ if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, GIGASET_MODULENAME, GIGASET_DEVNAME, GIGASET_DEVFSNAME, &ops, THIS_MODULE)) == NULL) goto error; /* allocate memory for our device state and intialize it */ cardstate = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME); if (!cardstate) goto error; /* register this driver with the USB subsystem */ result = usb_register(&gigaset_usb_driver); if (result < 0) { err("usb_gigaset: usb_register failed (error %d)", -result); goto error; } info(DRIVER_AUTHOR); info(DRIVER_DESC); return 0; error: if (cardstate) gigaset_freecs(cardstate); cardstate = NULL; if (driver) gigaset_freedriver(driver); driver = NULL; return -1; }
static int gigaset_probe(struct usb_interface *interface, const struct usb_device_id *id) { int retval; struct usb_device *udev = interface_to_usbdev(interface); struct usb_host_interface *hostif = interface->cur_altsetting; struct cardstate *cs = NULL; struct usb_cardstate *ucs = NULL; struct usb_endpoint_descriptor *endpoint; int buffer_size; gig_dbg(DEBUG_ANY, "%s: Check if device matches ...", __func__); /* See if the device offered us matches what we can accept */ if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) || (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) { gig_dbg(DEBUG_ANY, "device ID (0x%x, 0x%x) not for me - skip", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct)); return -ENODEV; } if (hostif->desc.bInterfaceNumber != 0) { gig_dbg(DEBUG_ANY, "interface %d not for me - skip", hostif->desc.bInterfaceNumber); return -ENODEV; } if (hostif->desc.bAlternateSetting != 0) { dev_notice(&udev->dev, "unsupported altsetting %d - skip", hostif->desc.bAlternateSetting); return -ENODEV; } if (hostif->desc.bInterfaceClass != 255) { dev_notice(&udev->dev, "unsupported interface class %d - skip", hostif->desc.bInterfaceClass); return -ENODEV; } dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); /* allocate memory for our device state and initialize it */ cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME); if (!cs) return -ENODEV; ucs = cs->hw.usb; /* save off device structure ptrs for later use */ usb_get_dev(udev); ucs->udev = udev; ucs->interface = interface; cs->dev = &interface->dev; /* save address of controller structure */ usb_set_intfdata(interface, cs); endpoint = &hostif->endpoint[0].desc; buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); ucs->bulk_out_size = buffer_size; ucs->bulk_out_endpointAddr = endpoint->bEndpointAddress; ucs->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!ucs->bulk_out_buffer) { dev_err(cs->dev, "Couldn't allocate bulk_out_buffer\n"); retval = -ENOMEM; goto error; } ucs->bulk_out_urb = usb_alloc_urb(0, GFP_KERNEL); if (!ucs->bulk_out_urb) { dev_err(cs->dev, "Couldn't allocate bulk_out_urb\n"); retval = -ENOMEM; goto error; } endpoint = &hostif->endpoint[1].desc; ucs->busy = 0; ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL); if (!ucs->read_urb) { dev_err(cs->dev, "No free urbs available\n"); retval = -ENOMEM; goto error; } buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); ucs->rcvbuf_size = buffer_size; ucs->int_in_endpointAddr = endpoint->bEndpointAddress; ucs->rcvbuf = kmalloc(buffer_size, GFP_KERNEL); if (!ucs->rcvbuf) { dev_err(cs->dev, "Couldn't allocate rcvbuf\n"); retval = -ENOMEM; goto error; } /* Fill the interrupt urb and send it to the core */ usb_fill_int_urb(ucs->read_urb, udev, usb_rcvintpipe(udev, endpoint->bEndpointAddress & 0x0f), ucs->rcvbuf, buffer_size, gigaset_read_int_callback, cs, endpoint->bInterval); retval = usb_submit_urb(ucs->read_urb, GFP_KERNEL); if (retval) { dev_err(cs->dev, "Could not submit URB (error %d)\n", -retval); goto error; } /* tell common part that the device is ready */ if (startmode == SM_LOCKED) cs->mstate = MS_LOCKED; if (!gigaset_start(cs)) { tasklet_kill(&cs->write_tasklet); retval = -ENODEV; goto error; } return 0; error: usb_kill_urb(ucs->read_urb); kfree(ucs->bulk_out_buffer); usb_free_urb(ucs->bulk_out_urb); kfree(ucs->rcvbuf); usb_free_urb(ucs->read_urb); usb_set_intfdata(interface, NULL); ucs->read_urb = ucs->bulk_out_urb = NULL; ucs->rcvbuf = ucs->bulk_out_buffer = NULL; usb_put_dev(ucs->udev); ucs->udev = NULL; ucs->interface = NULL; gigaset_freecs(cs); return retval; }