コード例 #1
0
ファイル: printer.c プロジェクト: liexusong/Linux-2.4.16
static void *usblp_probe(struct usb_device *dev, unsigned int ifnum,
			 const struct usb_device_id *id)
{
	struct usb_interface_descriptor *interface;
	struct usb_endpoint_descriptor *epread, *epwrite;
	struct usblp *usblp;
	int minor, i, bidir = 0, quirks;
	int alts = dev->actconfig->interface[ifnum].act_altsetting;
	int length, err;
	char *buf;
	char name[6];

	/* If a bidirectional interface exists, use it. */
	for (i = 0; i < dev->actconfig->interface[ifnum].num_altsetting; i++) {

		interface = &dev->actconfig->interface[ifnum].altsetting[i];

		if (interface->bInterfaceClass != 7 || interface->bInterfaceSubClass != 1 ||
		    interface->bInterfaceProtocol < 1 || interface->bInterfaceProtocol > 3 ||
		   (interface->bInterfaceProtocol > 1 && interface->bNumEndpoints < 2))
			continue;

		if (interface->bInterfaceProtocol > 1) {
			bidir = 1;
			alts = i;
			break;
		}
	}

	interface = &dev->actconfig->interface[ifnum].altsetting[alts];
	if (usb_set_interface(dev, ifnum, alts))
		err("can't set desired altsetting %d on interface %d", alts, ifnum);

	epwrite = interface->endpoint + 0;
	epread = bidir ? interface->endpoint + 1 : NULL;

	if ((epwrite->bEndpointAddress & 0x80) == 0x80) {
		if (interface->bNumEndpoints == 1)
			return NULL;
		epwrite = interface->endpoint + 1;
		epread = bidir ? interface->endpoint + 0 : NULL;
	}

	if ((epwrite->bEndpointAddress & 0x80) == 0x80)
		return NULL;

	if (bidir && (epread->bEndpointAddress & 0x80) != 0x80)
		return NULL;

	for (minor = 0; minor < USBLP_MINORS && usblp_table[minor]; minor++);
	if (usblp_table[minor]) {
		err("no more free usblp devices");
		return NULL;
	}

	if (!(usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL))) {
		err("out of memory");
		return NULL;
	}
	memset(usblp, 0, sizeof(struct usblp));
	init_MUTEX (&usblp->sem);

	/* lookup quirks for this printer */
	quirks = usblp_quirks(dev->descriptor.idVendor, dev->descriptor.idProduct);

	if (bidir && (quirks & USBLP_QUIRK_BIDIR)) {
		bidir = 0;
		epread = NULL;
		info ("Disabling reads from problem bidirectional printer on usblp%d",
			minor);
	}

	usblp->dev = dev;
	usblp->ifnum = ifnum;
	usblp->minor = minor;
	usblp->bidir = bidir;
	usblp->quirks = quirks;

	init_waitqueue_head(&usblp->wait);

	if (!(buf = kmalloc(USBLP_BUF_SIZE * (bidir ? 2 : 1), GFP_KERNEL))) {
		err("out of memory");
		kfree(usblp);
		return NULL;
	}

	if (!(usblp->device_id_string = kmalloc(DEVICE_ID_SIZE, GFP_KERNEL))) {
		err("out of memory");
		kfree(usblp);
		kfree(buf);
		return NULL;
	}

	FILL_BULK_URB(&usblp->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
		buf, 0, usblp_bulk, usblp);

	if (bidir)
		FILL_BULK_URB(&usblp->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
			buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE, usblp_bulk, usblp);

	/* Get the device_id string if possible. FIXME: Could make this kmalloc(length). */
	err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
	if (err >= 0) {
		length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
		if (length < DEVICE_ID_SIZE)
			usblp->device_id_string[length] = '\0';
		else
			usblp->device_id_string[DEVICE_ID_SIZE - 1] = '\0';
		dbg ("usblp%d Device ID string [%d]=%s",
			minor, length, &usblp->device_id_string[2]);
	}
	else {
		err ("usblp%d: error = %d reading IEEE-1284 Device ID string",
			minor, err);
		usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
	}

#ifdef DEBUG
	usblp_check_status(usblp, 0);
#endif

	sprintf(name, "lp%d", minor);

	/* if we have devfs, create with perms=660 */
	usblp->devfs = devfs_register(usb_devfs_handle, name,
				      DEVFS_FL_DEFAULT, USB_MAJOR,
				      USBLP_MINOR_BASE + minor,
				      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
				      S_IWGRP, &usblp_fops, NULL);

	info("usblp%d: USB %sdirectional printer dev %d if %d alt %d",
		minor, bidir ? "Bi" : "Uni", dev->devnum, ifnum, alts);

	return usblp_table[minor] = usblp;
}
コード例 #2
0
ファイル: printer.c プロジェクト: SnkBitten/amithlon4
static void *usblp_probe(struct usb_device *dev, unsigned int ifnum,
			 const struct usb_device_id *id)
{
	struct usblp *usblp = 0;
	int protocol;
	char name[6];

	/* Malloc and start initializing usblp structure so we can use it
	 * directly. */
	if (!(usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL))) {
		err("out of memory for usblp");
		goto abort;
	}
	memset(usblp, 0, sizeof(struct usblp));
	usblp->dev = dev;
	init_MUTEX (&usblp->sem);
	init_waitqueue_head(&usblp->wait);
	usblp->ifnum = ifnum;

	/* Look for a free usblp_table entry. */
	while (usblp_table[usblp->minor]) {
		usblp->minor++;
		if (usblp->minor >= USBLP_MINORS) {
			err("no more free usblp devices");
			goto abort;
		}
	}

	usblp->writeurb = usb_alloc_urb(0);
	if (!usblp->writeurb) {
		err("out of memory");
		goto abort;
	}
	usblp->readurb = usb_alloc_urb(0);
	if (!usblp->readurb) {
		err("out of memory");
		goto abort;
	}

	/* Malloc device ID string buffer to the largest expected length,
	 * since we can re-query it on an ioctl and a dynamic string
	 * could change in length. */
	if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) {
		err("out of memory for device_id_string");
		goto abort;
	}

	usblp->writebuf = usblp->readbuf = NULL;
	/* Malloc write & read buffers.  We somewhat wastefully
	 * malloc both regardless of bidirectionality, because the
	 * alternate setting can be changed later via an ioctl. */
	if (!(usblp->writebuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL))) {
		err("out of memory for write buf");
		goto abort;
	}
	if (!(usblp->readbuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL))) {
		err("out of memory for read buf");
		goto abort;
	}

	/* Allocate buffer for printer status */
	usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL);
	if (!usblp->statusbuf) {
		err("out of memory for statusbuf");
		goto abort;
	}

	/* Lookup quirks for this printer. */
	usblp->quirks = usblp_quirks(
		dev->descriptor.idVendor,
		dev->descriptor.idProduct);

	/* Analyze and pick initial alternate settings and endpoints. */
	protocol = usblp_select_alts(usblp);
	if (protocol < 0) {
		dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
			dev->descriptor.idVendor,
			dev->descriptor.idProduct);
		goto abort;
	}

	/* Setup the selected alternate setting and endpoints. */
	if (usblp_set_protocol(usblp, protocol) < 0)
		goto abort;

	/* Retrieve and store the device ID string. */
	usblp_cache_device_id_string(usblp);

#ifdef DEBUG
	usblp_check_status(usblp, 0);
#endif

	usblp_table[usblp->minor] = usblp;
	/* If we have devfs, create with perms=660. */
	sprintf(name, "lp%d", usblp->minor);
	usblp->devfs = devfs_register(usb_devfs_handle, name,
				      DEVFS_FL_DEFAULT, USB_MAJOR,
				      USBLP_MINOR_BASE + usblp->minor,
				      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
				      S_IWGRP, &usblp_fops, NULL);

	info("usblp%d: USB %sdirectional printer dev %d "
		"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
		usblp->ifnum,
		usblp->protocol[usblp->current_protocol].alt_setting,
		usblp->current_protocol, usblp->dev->descriptor.idVendor,
		usblp->dev->descriptor.idProduct);

	usblp->present = 1;

	return usblp;

abort:
	if (usblp) {
		if (usblp->writebuf)
			kfree (usblp->writebuf);
		if (usblp->readbuf)
			kfree (usblp->readbuf);
		kfree(usblp->statusbuf);
		kfree(usblp->device_id_string);
		usb_free_urb(usblp->writeurb);
		usb_free_urb(usblp->readurb);
		kfree(usblp);
	}
	return NULL;
}
static void *usblp_probe(struct usb_device *dev, unsigned int ifnum,const struct usb_device_id *id)
{
	struct usb_interface_descriptor *interface;
	struct usb_endpoint_descriptor *epread, *epwrite;
	struct usblp *usblp;
	int minor, bidir, quirks;
	int alts;
	int length, errno;
	char *buf,*buf1;
	char name[6];

//ZOT716u2	armond_printf("usblp probe\n");

	alts = usblp_select_alts(dev, ifnum);
	interface = &dev->actconfig->interface[ifnum].altsetting[alts];
	if (usb_set_interface(dev, ifnum, alts)) {
//{{MARK_DEBUG
//		err("can't set desired altsetting %d on interface %d", alts, ifnum);
//}}MARK_DEBUG
//ZOT716u2		armond_printf("usb_set_interface Error\n");
	}	
	bidir = (interface->bInterfaceProtocol > 1);

	epwrite = interface->endpoint + 0;
	epread = bidir ? interface->endpoint + 1 : NULL;

	if ((epwrite->bEndpointAddress & 0x80) == 0x80) {
		if (interface->bNumEndpoints == 1)
			return NULL;
		epwrite = interface->endpoint + 1;
		epread = bidir ? interface->endpoint + 0 : NULL;
	}

	if ((epwrite->bEndpointAddress & 0x80) == 0x80)
		return NULL;

	if (bidir && (epread->bEndpointAddress & 0x80) != 0x80)
		return NULL;

	for (minor = 0; minor < USBLP_MINORS && usblp_table[minor]; minor++);
	if (usblp_table[minor]) {
//{{MARK_DEBUG
//		err("no more free usblp devices");
//}}MARK_DEBUG
		return NULL;
	}

	if ((usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL)) == NULL ) {
//{{MARK_DEBUG
//		err("out of memory");
//}}MARK_DEBUG
		return NULL;
	}
	memset(usblp, 0, sizeof(struct usblp));

	/* lookup quirks for this printer */
	quirks = usblp_quirks(dev->descriptor.idVendor, dev->descriptor.idProduct);

	if (bidir && (quirks & USBLP_QUIRK_BIDIR)) {
		bidir = 0;
		epread = NULL;
//{{MARK_DEBUG
//		dbg ("Disabling reads from problem bidirectional printer on usblp%d",
//			minor);
//}}MARK_DEBUG
	}

	usblp->dev = dev;
	usblp->ifnum = ifnum;
	usblp->minor = minor;
	usblp->bidir = bidir;
	usblp->quirks = quirks;

//	init_waitqueue_head(&usblp->wait);
	usblp->wait = malloc (sizeof(cyg_sem_t));	//ZOT716u2
	cyg_semaphore_init(usblp->wait, 0);		//ZOT716u2

//615wu
/*
	if ((buf = kmalloc(USBLP_BUF_SIZE * (bidir ? 2 : 1), GFP_KERNEL))==NULL) {
//{{MARK_DEBUG
//		err("out of memory");
//}}MARK_DEBUG
		kfree(usblp);
		return NULL;
	}
*/

//719AW	buf = USB_PRINTER_WRITE_BUFFER;
	buf = kaligned_alloc(8192, 4096);	//eason 20100407	
	
	if ((usblp->device_id_string = kmalloc(DEVICE_ID_SIZE, GFP_KERNEL))==NULL) {
//{{MARK_DEBUG
//		err("out of memory");
//}}MARK_DEBUG
		kfree(usblp, 0);
//615wu		kfree(buf);
		return NULL;
	}
	
//719AW	buf1 =	USB_PRINTER_READ_BUFFER;
	buf1 = kaligned_alloc(8192, 4096);	//eason 20100407

	FILL_BULK_URB(&usblp->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
		buf, 0, usblp_bulk, usblp);

	if (bidir)
//615WU		FILL_BULK_URB(&usblp->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
//			buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE, usblp_bulk, usblp);
		FILL_BULK_URB(&usblp->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
			buf1, 256, usblp_bulk, usblp);

	/* Get the device_id string if possible. FIXME: Could make this kmalloc(length). */

	errno = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
	if (errno >= 0) {
		length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
		if (length < DEVICE_ID_SIZE)
			usblp->device_id_string[length] = '\0';
		else
			usblp->device_id_string[DEVICE_ID_SIZE - 1] = '\0';
//{{MARK_DEBUG
//		dbg ("usblp%d Device ID string [%d]=%s",
//			minor, length, &usblp->device_id_string[2]);
//}}MARK_DEBUG
//ZOT716u2		armond_printf("usblp_get_id OK\n");
	}
	else {
//{{MARK_DEBUG
//		err ("usblp%d: error = %d reading IEEE-1284 Device ID string",
//			minor, errno);
//}}MARK_DEBUG
		usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
//ZOT716u2		armond_printf("usblp_get_id error:%d\n",errno);
	}


//#ifdef DEBUG
//	usblp_check_status(usblp, 0);
//#endif

//	sprintf(name, "lp%d", minor);
	
	/* Create with perms=664 */
//	usblp->devfs = devfs_register(usb_devfs_handle, name,
//				      DEVFS_FL_DEFAULT, USB_MAJOR,
//				      USBLP_MINOR_BASE + minor,
//				      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
//				      S_IWGRP, &usblp_fops, NULL);
//	if (usblp->devfs == NULL)
//		err("usblp%d: device node registration failed", minor);

//{{MARK_DEBUG
//	dbg("usblp%d: USB %sdirectional printer dev %d if %d alt %d",
//		minor, bidir ? "Bi" : "Uni", dev->devnum, ifnum, alts);
//}}MARK_DEBUG

	usblp_table[minor] = usblp;

	usbprn_attach( minor );

	return usblp;
}
コード例 #4
-1
ファイル: usblp.c プロジェクト: 3sOx/asuswrt-merlin
static int usblp_probe(struct usb_interface *intf,
		       const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	struct usblp *usblp;
	int protocol;
	int retval;

	/* Malloc and start initializing usblp structure so we can use it
	 * directly. */
	usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL);
	if (!usblp) {
		retval = -ENOMEM;
		goto abort_ret;
	}
	usblp->dev = dev;
	mutex_init(&usblp->wmut);
	mutex_init(&usblp->mut);
	spin_lock_init(&usblp->lock);
	init_waitqueue_head(&usblp->rwait);
	init_waitqueue_head(&usblp->wwait);
	init_usb_anchor(&usblp->urbs);
	usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
	usblp->intf = intf;

	/* Malloc device ID string buffer to the largest expected length,
	 * since we can re-query it on an ioctl and a dynamic string
	 * could change in length. */
	if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) {
		retval = -ENOMEM;
		goto abort;
	}

	/*
	 * Allocate read buffer. We somewhat wastefully
	 * malloc both regardless of bidirectionality, because the
	 * alternate setting can be changed later via an ioctl.
	 */
	if (!(usblp->readbuf = kmalloc(USBLP_BUF_SIZE_IN, GFP_KERNEL))) {
		retval = -ENOMEM;
		goto abort;
	}

	/* Allocate buffer for printer status */
	usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL);
	if (!usblp->statusbuf) {
		retval = -ENOMEM;
		goto abort;
	}

	/* Lookup quirks for this printer. */
	usblp->quirks = usblp_quirks(
		le16_to_cpu(dev->descriptor.idVendor),
		le16_to_cpu(dev->descriptor.idProduct));

	/* Analyze and pick initial alternate settings and endpoints. */
	protocol = usblp_select_alts(usblp);
	if (protocol < 0) {
		dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
			le16_to_cpu(dev->descriptor.idVendor),
			le16_to_cpu(dev->descriptor.idProduct));
		retval = -ENODEV;
		goto abort;
	}

	/* Setup the selected alternate setting and endpoints. */
	if (usblp_set_protocol(usblp, protocol) < 0) {
		retval = -ENODEV;	/* ->probe isn't ->ioctl */
		goto abort;
	}

	/* Retrieve and store the device ID string. */
	usblp_cache_device_id_string(usblp);
	retval = device_create_file(&intf->dev, &dev_attr_ieee1284_id);
	if (retval)
		goto abort_intfdata;

#ifdef DEBUG
	usblp_check_status(usblp, 0);
#endif

	usb_set_intfdata(intf, usblp);

	usblp->present = 1;

	retval = usb_register_dev(intf, &usblp_class);
	if (retval) {
		printk(KERN_ERR "usblp: Not able to get a minor"
		    " (base %u, slice default): %d\n",
		    USBLP_MINOR_BASE, retval);
		goto abort_intfdata;
	}
	usblp->minor = intf->minor;
	printk(KERN_INFO "usblp%d: USB %sdirectional printer dev %d "
		"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X\n",
		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
		usblp->ifnum,
		usblp->protocol[usblp->current_protocol].alt_setting,
		usblp->current_protocol,
		le16_to_cpu(usblp->dev->descriptor.idVendor),
		le16_to_cpu(usblp->dev->descriptor.idProduct));

        /* Added by PaN */
        /* create directory */
        if(pan_count < 0)
                pan_count = 0;
        ++pan_count;
        if(pan_count == 1)
        {
                usblp_dir = proc_mkdir(MODULE_NAME, NULL);
                if(usblp_dir == NULL) {
                        goto outpan;
                }
                //usblp_dir->owner = THIS_MODULE;

                usblpid_file = create_proc_read_entry("usblpid", 0444, usblp_dir, proc_read_usblpid, NULL);
                if(usblpid_file == NULL) {
                        remove_proc_entry(MODULE_NAME, NULL);

                        goto outpan;
                }
                //usblpid_file->owner = THIS_MODULE;
                /* get device id */
                if (proc_get_usblpid(usblp) < 0)
                        dbg ("proc:get usblpid error!!");

        }
outpan:
        // End PaN 

	return 0;

abort_intfdata:
	usb_set_intfdata(intf, NULL);
	device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
abort:
	kfree(usblp->readbuf);
	kfree(usblp->statusbuf);
	kfree(usblp->device_id_string);
	kfree(usblp);
abort_ret:
	return retval;
}
コード例 #5
-1
ファイル: usblp.c プロジェクト: rcplay/snake-os
static int usblp_probe(struct usb_interface *intf,
                       const struct usb_device_id *id)
{
    struct usb_device *dev = interface_to_usbdev (intf);
    struct usblp *usblp = NULL;
    int protocol;
    int retval;

    /* Malloc and start initializing usblp structure so we can use it
     * directly. */
    if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) {
        err("out of memory for usblp");
        goto abort;
    }
    usblp->dev = dev;
    init_MUTEX (&usblp->sem);
    init_waitqueue_head(&usblp->wait);
    usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
    usblp->intf = intf;

    usblp->writeurb = usb_alloc_urb(0, GFP_KERNEL);
    if (!usblp->writeurb) {
        err("out of memory");
        goto abort;
    }
    usblp->readurb = usb_alloc_urb(0, GFP_KERNEL);
    if (!usblp->readurb) {
        err("out of memory");
        goto abort;
    }

    /* Malloc device ID string buffer to the largest expected length,
     * since we can re-query it on an ioctl and a dynamic string
     * could change in length. */
    if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) {
        err("out of memory for device_id_string");
        goto abort;
    }

    usblp->writebuf = usblp->readbuf = NULL;
    usblp->writeurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
    usblp->readurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
    /* Malloc write & read buffers.  We somewhat wastefully
     * malloc both regardless of bidirectionality, because the
     * alternate setting can be changed later via an ioctl. */
    if (!(usblp->writebuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE,
                            GFP_KERNEL, &usblp->writeurb->transfer_dma))) {
        err("out of memory for write buf");
        goto abort;
    }
    if (!(usblp->readbuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE,
                                            GFP_KERNEL, &usblp->readurb->transfer_dma))) {
        err("out of memory for read buf");
        goto abort;
    }

    /* Allocate buffer for printer status */
    usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL);
    if (!usblp->statusbuf) {
        err("out of memory for statusbuf");
        goto abort;
    }

    /* Lookup quirks for this printer. */
    usblp->quirks = usblp_quirks(
                        le16_to_cpu(dev->descriptor.idVendor),
                        le16_to_cpu(dev->descriptor.idProduct));

    /* Analyze and pick initial alternate settings and endpoints. */
    protocol = usblp_select_alts(usblp);
    if (protocol < 0) {
        dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
            le16_to_cpu(dev->descriptor.idVendor),
            le16_to_cpu(dev->descriptor.idProduct));
        goto abort;
    }

    /* Setup the selected alternate setting and endpoints. */
    if (usblp_set_protocol(usblp, protocol) < 0)
        goto abort;

    /* Retrieve and store the device ID string. */
    usblp_cache_device_id_string(usblp);
    device_create_file(&intf->dev, &dev_attr_ieee1284_id);

#ifdef DEBUG
    usblp_check_status(usblp, 0);
#endif

    usb_set_intfdata (intf, usblp);

    usblp->present = 1;

    retval = usb_register_dev(intf, &usblp_class);
    if (retval) {
        err("Not able to get a minor for this device.");
        goto abort_intfdata;
    }
    usblp->minor = intf->minor;
    info("usblp%d: USB %sdirectional printer dev %d "
         "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
         usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
         usblp->ifnum,
         usblp->protocol[usblp->current_protocol].alt_setting,
         usblp->current_protocol,
         le16_to_cpu(usblp->dev->descriptor.idVendor),
         le16_to_cpu(usblp->dev->descriptor.idProduct));

    return 0;

abort_intfdata:
    usb_set_intfdata (intf, NULL);
    device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
abort:
    if (usblp) {
        if (usblp->writebuf)
            usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
                             usblp->writebuf, usblp->writeurb->transfer_dma);
        if (usblp->readbuf)
            usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
                             usblp->readbuf, usblp->writeurb->transfer_dma);
        kfree(usblp->statusbuf);
        kfree(usblp->device_id_string);
        usb_free_urb(usblp->writeurb);
        usb_free_urb(usblp->readurb);
        kfree(usblp);
    }
    return -EIO;
}