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