Exemplo n.º 1
0
/* Retrieves and caches device ID string.
 * Returns length, including length bytes but not null terminator.
 * On error, returns a negative errno value. */
static int usblp_cache_device_id_string(struct usblp *usblp)
{
	int err, length;

	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
	if (err < 0) {
		dbg("usblp%d: error = %d reading IEEE-1284 Device ID string",
			usblp->minor, err);
		usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
		return -EIO;
	}

	/* First two bytes are length in big-endian.
	 * They count themselves, and we copy them into
	 * the user's buffer. */
	length = be16_to_cpu(*((__be16 *)usblp->device_id_string));
	if (length < 2)
		length = 2;
	else if (length >= USBLP_DEVICE_ID_SIZE)
		length = USBLP_DEVICE_ID_SIZE - 1;
	usblp->device_id_string[length] = '\0';

	dbg("usblp%d Device ID string [len=%d]=\"%s\"",
		usblp->minor, length, &usblp->device_id_string[2]);

	return length;
}
Exemplo n.º 2
0
static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	struct usblp *usblp = file->private_data;
	int length, err;
	unsigned char status;

	if (_IOC_TYPE(cmd) == 'P')	/* new-style ioctl number */
	
		switch (_IOC_NR(cmd)) {

			case IOCNR_GET_DEVICE_ID: /* get the DEVICE_ID string */
				if (_IOC_DIR(cmd) != _IOC_READ)
					return -EINVAL;

				err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
				if (err < 0) {
					dbg ("usblp%d: error = %d reading IEEE-1284 Device ID string",
						usblp->minor, err);
					usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
					return -EIO;
				}

				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/max %d]='%s'",
					usblp->minor, length, _IOC_SIZE(cmd), &usblp->device_id_string[2]);

				if (length > _IOC_SIZE(cmd)) length = _IOC_SIZE(cmd); /* truncate */

				if (copy_to_user((unsigned char *) arg, usblp->device_id_string, (unsigned long) length))
					return -EFAULT;

				break;

			default:
				return -EINVAL;
		}
	else	/* old-style ioctl value */
		switch (cmd) {

			case LPGETSTATUS:
				if (usblp_read_status(usblp, &status)) {
					err("usblp%d: failed reading printer status", usblp->minor);
					return -EIO;
				}
				if (copy_to_user ((unsigned char *)arg, &status, 1))
					return -EFAULT;
				break;

			default:
				return -EINVAL;
		}

	return 0;
}
Exemplo n.º 3
0
static int proc_get_usblpid(struct usblp *usblp)
{
//JYWeng 20031212: set this as global   char *strtmp, *str_dev_id, *strunknown="unknown"; // Added by PaN
        char *strtmp, *str_dev_id; // Added by PaN: JYWeng 20031212: modified from the above
        int i, unk = 0; // Added by PaN
        int length, err;
        int retval = 0;

        prn_info= &prn_info_tmp; // Added by JYWeng 20031212:


        err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);

        if (err < 0) {
                dbg ("usblp%d: error = %d reading IEEE-1284 Device ID string",
                        usblp->minor, err);
                        usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
                retval = -EIO;
                goto done;
        }

        length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
        if (length < USBLP_DEVICE_ID_SIZE)
                usblp->device_id_string[length] = '\0';
        else
                usblp->device_id_string[USBLP_DEVICE_ID_SIZE - 1] = '\0';

        dbg ("usblp%d Device ID string [%d]='%s'",
                usblp->minor, length, &usblp->device_id_string[2]);

        str_dev_id = &usblp->device_id_string[2];
#if 1//JYWeng 20031212: modified from below
                                parseKeywords(str_dev_id, "MFG:", "MANUFACTURE:", prn_info->mfr, usblpid_info.mfr);
                                parseKeywords(str_dev_id, "MDL:", "MODEL:", prn_info->model, usblpid_info.model);
                                parseKeywords(str_dev_id, "CLS:", "CLASS:", prn_info->class_name, usblpid_info.class_name);
                                parseKeywords(str_dev_id, "DES:", "DESCRIPTION:", prn_info->description, usblpid_info.description);
#endif//JYWeng 20031212: end

done:
        return retval;

}
Exemplo n.º 4
0
static void *usblp_probe(struct usb_device *dev, unsigned int ifnum)
{
    struct usb_interface_descriptor *interface;
    struct usb_endpoint_descriptor *epread, *epwrite;
    struct usblp *usblp;
    int minor, i, alts = -1, bidir = 0;
    int length, err;
    char *buf;

    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 (alts == -1)
            alts = i;

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

    if (alts == -1)
        return NULL;

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

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

    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);
#endif

    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;
}
Exemplo n.º 5
0
static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct usblp *usblp = file->private_data;
        struct print_buffer user_buf_tmp, *user_buf; // Added by PaN
        char *strtmp, *str_dev_id; // Added by PaN: JYWeng 20031212: modified from the above
        int unk=0; // Added by PaN ---remove declaration of i for i is declared below: JY
	int length, err, i;
	unsigned char newChannel;
	int status;
	int twoints[2];
	int retval = 0;

	mutex_lock(&usblp->mut);
	if (!usblp->present) {
		retval = -ENODEV;
		goto done;
	}

	dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, _IOC_TYPE(cmd),
		_IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd));

	if (_IOC_TYPE(cmd) == 'P')	/* new-style ioctl number */

		switch (_IOC_NR(cmd)) {

		case IOCNR_GET_DEVICE_ID: /* get the DEVICE_ID string */
			if (_IOC_DIR(cmd) != _IOC_READ) {
				retval = -EINVAL;
				goto done;
			}

			length = usblp_cache_device_id_string(usblp);
			if (length < 0) {
				retval = length;
				goto done;
			}
			if (length > _IOC_SIZE(cmd))
				length = _IOC_SIZE(cmd); /* truncate */

			if (copy_to_user((void __user *) arg,
					usblp->device_id_string,
					(unsigned long) length)) {
				retval = -EFAULT;
				goto done;
			}

			break;

		case IOCNR_GET_PROTOCOLS:
			if (_IOC_DIR(cmd) != _IOC_READ ||
			    _IOC_SIZE(cmd) < sizeof(twoints)) {
				retval = -EINVAL;
				goto done;
			}

			twoints[0] = usblp->current_protocol;
			twoints[1] = 0;
			for (i = USBLP_FIRST_PROTOCOL;
			     i <= USBLP_LAST_PROTOCOL; i++) {
				if (usblp->protocol[i].alt_setting >= 0)
					twoints[1] |= (1<<i);
			}

			if (copy_to_user((void __user *)arg,
					(unsigned char *)twoints,
					sizeof(twoints))) {
				retval = -EFAULT;
				goto done;
			}

			break;

		case IOCNR_SET_PROTOCOL:
			if (_IOC_DIR(cmd) != _IOC_WRITE) {
				retval = -EINVAL;
				goto done;
			}

#ifdef DEBUG
			if (arg == -10) {
				usblp_dump(usblp);
				break;
			}
#endif

			usblp_unlink_urbs(usblp);
			retval = usblp_set_protocol(usblp, arg);
			if (retval < 0) {
				usblp_set_protocol(usblp,
					usblp->current_protocol);
			}
			break;

		case IOCNR_HP_SET_CHANNEL:
			if (_IOC_DIR(cmd) != _IOC_WRITE ||
			    le16_to_cpu(usblp->dev->descriptor.idVendor) != 0x03F0 ||
			    usblp->quirks & USBLP_QUIRK_BIDIR) {
				retval = -EINVAL;
				goto done;
			}

			err = usblp_hp_channel_change_request(usblp,
				arg, &newChannel);
			if (err < 0) {
				dev_err(&usblp->dev->dev,
					"usblp%d: error = %d setting "
					"HP channel\n",
					usblp->minor, err);
				retval = -EIO;
				goto done;
			}

			dbg("usblp%d requested/got HP channel %ld/%d",
				usblp->minor, arg, newChannel);
			break;

		case IOCNR_GET_BUS_ADDRESS:
			if (_IOC_DIR(cmd) != _IOC_READ ||
			    _IOC_SIZE(cmd) < sizeof(twoints)) {
				retval = -EINVAL;
				goto done;
			}

			twoints[0] = usblp->dev->bus->busnum;
			twoints[1] = usblp->dev->devnum;
			if (copy_to_user((void __user *)arg,
					(unsigned char *)twoints,
					sizeof(twoints))) {
				retval = -EFAULT;
				goto done;
			}

			dbg("usblp%d is bus=%d, device=%d",
				usblp->minor, twoints[0], twoints[1]);
			break;

		case IOCNR_GET_VID_PID:
			if (_IOC_DIR(cmd) != _IOC_READ ||
			    _IOC_SIZE(cmd) < sizeof(twoints)) {
				retval = -EINVAL;
				goto done;
			}

			twoints[0] = le16_to_cpu(usblp->dev->descriptor.idVendor);
			twoints[1] = le16_to_cpu(usblp->dev->descriptor.idProduct);
			if (copy_to_user((void __user *)arg,
					(unsigned char *)twoints,
					sizeof(twoints))) {
				retval = -EFAULT;
				goto done;
			}

			dbg("usblp%d is VID=0x%4.4X, PID=0x%4.4X",
				usblp->minor, twoints[0], twoints[1]);
			break;

		case IOCNR_SOFT_RESET:
			if (_IOC_DIR(cmd) != _IOC_NONE) {
				retval = -EINVAL;
				goto done;
			}
			retval = usblp_reset(usblp);
			break;
		default:
			retval = -ENOTTY;
		}
	else	/* old-style ioctl value */
		switch (cmd) {
                        /*=================================================================================== PaN */
                        case LPGETID: /* get the DEVICE_ID string */
                                err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
                                if (err < 0) {
                                        dbg ("usblp%d: error = %d reading IEEE-1284 Device ID string",
                                                usblp->minor, err);
                                        usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
                                        retval = -EIO;
                                        goto done;
                                }

                                length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
                                if (length < USBLP_DEVICE_ID_SIZE)
                                        usblp->device_id_string[length] = '\0';
                                else
                                        usblp->device_id_string[USBLP_DEVICE_ID_SIZE - 1] = '\0';

                                dbg ("usblp%d Device ID string [%d/max %d]='%s'",
                                        usblp->minor, length, cmd, &usblp->device_id_string[2]);

                                str_dev_id = &usblp->device_id_string[2];
#if 1//JYWeng 20031212: modified from below
                                parseKeywords(str_dev_id, "MFG:", "MANUFACTURE:", prn_info->mfr, usblpid_info.mfr);
                                parseKeywords(str_dev_id, "MDL:", "MODEL:", prn_info->model, usblpid_info.model);
                                parseKeywords(str_dev_id, "CLS:", "CLASS:", prn_info->class_name, usblpid_info.class_name);
                                parseKeywords(str_dev_id, "DES:", "DESCRIPTION:", prn_info->description, usblpid_info.description);
#endif//JYWeng 20031212: end

                                dbg ("Parsing USBLPID...");
                                if (copy_to_user((unsigned char *) arg,
                                                prn_info, (unsigned long) length)) {
                                        retval = -EFAULT;
                                        goto done;
                                }
                                break;

                        case LPREADDATA:
                                mutex_unlock (&usblp_mutex);
                                user_buf = (struct print_buffer *)arg;
                                retval = usblp_read(file, user_buf->buf, user_buf->len, NULL);
                                mutex_lock (&usblp_mutex);
                                break;


                        case LPWRITEDATA:
                                mutex_unlock (&usblp_mutex);
                                user_buf = (struct print_buffer *)arg;
                                retval = usblp_write(file, user_buf->buf, user_buf->len, NULL);
                                mutex_lock (&usblp_mutex);
                                break;

                        case LPRESET:
                                usblp_reset(usblp);
                                break;

			case LPGETSTATUS:
				/* OLD USB Code Removed by PaN for Printer Server
				if ((retval = usblp_read_status(usblp, usblp->statusbuf))) {
					if (printk_ratelimit())
						printk(KERN_ERR "usblp%d:"
					    	"failed reading printer status (%d)\n",
					    	usblp->minor, retval);
					retval = -EIO;
					goto done;
				}
				status = *usblp->statusbuf;
				*/
				status = 0;
				if (copy_to_user((void __user *)arg, &status, sizeof(int)))
				retval = -EFAULT;
			break;
/*=================================================================== PaN for Printer Server */

		case LPABORT:
			if (arg)
				usblp->flags |= LP_ABORT;
			else
				usblp->flags &= ~LP_ABORT;
			break;

		default:
			retval = -ENOTTY;
		}

done:
	mutex_unlock(&usblp->mut);
	return retval;
}
Exemplo n.º 6
0
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;
}
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;
}
Exemplo n.º 8
0
static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	struct usblp *usblp = file->private_data;
	struct parport_splink_device_info prn_info_tmp, *prn_info; // Added by PaN
	struct print_buffer user_buf_tmp, *user_buf; // Added by PaN
	char *strtmp, *str_dev_id, *strunknown="unknown"; // Added by PaN
	//int i, unk=0; // Added by PaN
	int unk=0; // Added by PaN ---remove declaration of i for i is declared below: JY
	int length, err, i;
	unsigned char lpstatus, newChannel;
	int status;
	int twoints[2];
	int retval = 0;
	prn_info= &prn_info_tmp; // Added by PaN

	down (&usblp->sem);
	if (!usblp->dev) {
		retval = -ENODEV;
		goto done;
	}

	if (_IOC_TYPE(cmd) == 'P')	/* new-style ioctl number */

		switch (_IOC_NR(cmd)) {

			case IOCNR_GET_DEVICE_ID: /* get the DEVICE_ID string */
				if (_IOC_DIR(cmd) != _IOC_READ) {
					retval = -EINVAL;
					goto done;
				}

				length = usblp_cache_device_id_string(usblp);
				if (length < 0) {
					retval = length;
					goto done;
				}
				if (length > _IOC_SIZE(cmd))
					length = _IOC_SIZE(cmd); /* truncate */

				if (copy_to_user((unsigned char *) arg,
						usblp->device_id_string,
						(unsigned long) length)) {
					retval = -EFAULT;
					goto done;
				}

				break;

			case IOCNR_GET_PROTOCOLS:
				if (_IOC_DIR(cmd) != _IOC_READ ||
				    _IOC_SIZE(cmd) < sizeof(twoints)) {
					retval = -EINVAL;
					goto done;
				}

				twoints[0] = usblp->current_protocol;
				twoints[1] = 0;
				for (i = USBLP_FIRST_PROTOCOL;
				     i <= USBLP_LAST_PROTOCOL; i++) {
					if (usblp->protocol[i].alt_setting >= 0)
						twoints[1] |= (1<<i);
				}

				if (copy_to_user((unsigned char *)arg,
						(unsigned char *)twoints,
						sizeof(twoints))) {
					retval = -EFAULT;
					goto done;
				}

				break;

			case IOCNR_SET_PROTOCOL:
				if (_IOC_DIR(cmd) != _IOC_WRITE) {
					retval = -EINVAL;
					goto done;
				}

#ifdef DEBUG
				if (arg == -10) {
					usblp_dump(usblp);
					break;
				}
#endif

				usblp_unlink_urbs(usblp);
				retval = usblp_set_protocol(usblp, arg);
				if (retval < 0) {
					usblp_set_protocol(usblp,
						usblp->current_protocol);
				}
				break;

			case IOCNR_HP_SET_CHANNEL:
				if (_IOC_DIR(cmd) != _IOC_WRITE ||
				    usblp->dev->descriptor.idVendor != 0x03F0 ||
				    usblp->quirks & USBLP_QUIRK_BIDIR) {
					retval = -EINVAL;
					goto done;
				}

				err = usblp_hp_channel_change_request(usblp,
					arg, &newChannel);
				if (err < 0) {
					err("usblp%d: error = %d setting "
						"HP channel",
						usblp->minor, err);
					retval = -EIO;
					goto done;
				}

				dbg("usblp%d requested/got HP channel %ld/%d",
					usblp->minor, arg, newChannel);
				break;

			case IOCNR_GET_BUS_ADDRESS:
				if (_IOC_DIR(cmd) != _IOC_READ ||
				    _IOC_SIZE(cmd) < sizeof(twoints)) {
					retval = -EINVAL;
					goto done;
				}

				twoints[0] = usblp->dev->bus->busnum;
				twoints[1] = usblp->dev->devnum;
				if (copy_to_user((unsigned char *)arg,
						(unsigned char *)twoints,
						sizeof(twoints))) {
					retval = -EFAULT;
					goto done;
				}

				dbg("usblp%d is bus=%d, device=%d",
					usblp->minor, twoints[0], twoints[1]);
				break;

			case IOCNR_GET_VID_PID:
				if (_IOC_DIR(cmd) != _IOC_READ ||
				    _IOC_SIZE(cmd) < sizeof(twoints)) {
					retval = -EINVAL;
					goto done;
				}

				twoints[0] = usblp->dev->descriptor.idVendor;
				twoints[1] = usblp->dev->descriptor.idProduct;
				if (copy_to_user((unsigned char *)arg,
						(unsigned char *)twoints,
						sizeof(twoints))) {
					retval = -EFAULT;
					goto done;
				}

				dbg("usblp%d is VID=0x%4.4X, PID=0x%4.4X",
					usblp->minor, twoints[0], twoints[1]);
				break;

			default:
				retval = -EINVAL;
		}
	else	/* old-style ioctl value */
		switch (cmd) {
/*=================================================================================== PaN */
			case LPGETID: /* get the DEVICE_ID string */
				err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
				if (err < 0) {
					dbg ("usblp%d: error = %d reading IEEE-1284 Device ID string",
						usblp->minor, err);
					usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
					retval = -EIO;
					goto done;
				}

				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/max %d]='%s'",
					usblp->minor, length, cmd, &usblp->device_id_string[2]);
				info ("usblp%d Device ID string [%d/max %d]='%s'",
					usblp->minor, length, cmd, &usblp->device_id_string[2]);

				str_dev_id = &usblp->device_id_string[2];	
				if ( (strtmp = strstr(str_dev_id, "MFG:")) == NULL) {
					if ( (strtmp = strstr(str_dev_id, "MANUFACTURE:")) == NULL) {
						for (i=0; i<7; i++) {
							prn_info->mfr[i]= strunknown[i];
							usblpid_info.mfr[i] = strunknown[i];
						}
						prn_info->mfr[i]= '\0';
						usblpid_info.mfr[i]='\0';
						unk=1;
					}
					else 
						strtmp+=12;
				}
				else
					strtmp+=4;
					
				i=0;
				while (strtmp[i] != ';' && unk==0) {
					prn_info->mfr[i]= strtmp[i];
					usblpid_info.mfr[i] = strtmp[i];
					i++;
				}
				prn_info->mfr[i]= '\0';
				usblpid_info.mfr[i]='\0';
				unk=0;

				if ( (strtmp = strstr(str_dev_id, "MDL:")) == NULL) {
					if ( (strtmp = strstr(str_dev_id, "MODEL:")) == NULL) {
						for (i=0; i<7; i++) {
							prn_info->model[i]= strunknown[i];
							usblpid_info.model[i] = strunknown[i];
						}
						prn_info->model[i]= '\0';
						usblpid_info.model[i]='\0';
						unk=1;
					}
					else
						strtmp+=6;
				}
				else 
					strtmp+=4;
				
				i=0;
				while (strtmp[i] != ';' && unk==0) {
					prn_info->model[i]= strtmp[i];
					usblpid_info.model[i] = strtmp[i];
					i++;
				}		
				prn_info->model[i]= '\0';
				usblpid_info.model[i]='\0';
				unk=0;
				
				if ( (strtmp = strstr(str_dev_id, "CLS:")) == NULL) {
					if ( (strtmp = strstr(str_dev_id, "CLASS:")) == NULL) {
						for (i=0; i<7; i++) {
							prn_info->class_name[i]= strunknown[i];
							usblpid_info.class_name[i] = strunknown[i];
						}
						prn_info->class_name[i]= '\0';
						usblpid_info.class_name[i]='\0';
						unk=1;
					}
					else
						strtmp+=6;
				}
				else 
					strtmp+=4;
				
				i=0;
				while (strtmp[i] != ';' && unk==0) {
					prn_info->class_name[i]= strtmp[i];
					usblpid_info.class_name[i]= strtmp[i];
					i++;
				}		
				prn_info->class_name[i]= '\0';
				usblpid_info.class_name[i]='\0';
				unk=0;
				
				if ( (strtmp = strstr(str_dev_id, "DES:")) == NULL) {
					if ( (strtmp = strstr(str_dev_id, "DESCRIPTION:")) == NULL) {
						for (i=0; i<7; i++) {
							prn_info->description[i]= strunknown[i];
							usblpid_info.description[i] = strunknown[i];
						}
						prn_info->description[i]= '\0';
						usblpid_info.description[i]='\0';
						unk=1;
					}
					else
						strtmp+=12;
				}
				else
					strtmp+=4;
				
				i=0;
				while (strtmp[i] != ';' && unk==0) {
					prn_info->description[i]= strtmp[i];
					usblpid_info.description[i]= strtmp[i];
					i++;
				}		
				prn_info->description[i]= '\0';
				usblpid_info.description[i]='\0';
				
				info("Parsing USBLPID...");
				if (copy_to_user((unsigned char *) arg,
						prn_info, (unsigned long) length)) {
					retval = -EFAULT;
					goto done;
				}
				break;

			case LPREADDATA:
			        up (&usblp->sem);
				user_buf = (struct print_buffer *)arg;
				retval = usblp_read(file, user_buf->buf, user_buf->len, NULL);
				down (&usblp->sem);
	                        break;
										

			case LPWRITEDATA:
			        up (&usblp->sem);
				user_buf = (struct print_buffer *)arg;
				retval = usblp_write(file, user_buf->buf, user_buf->len, NULL);
				down (&usblp->sem);
	                        break;
										 
			case LPRESET:
                                usblp_reset(usblp);
				break;

			case LPGETSTATUS:
				/* OLD USB Code Removed by PaN for Printer Server 
				if (usblp_read_status(usblp, &status)) {
					err("usblp%d: failed reading printer status", usblp->minor);
					retval = -EIO;
					goto done;
				}
				if (copy_to_user ((int *)arg, &status, 2))
					retval = -EFAULT;
				*/
                                status = usblp_check_status(usblp, 0);
#if 0
				info("start=%s", usblpid_info.mfr);
				for (i=0; i< MAX_STATUS_TYPE; i++) {
				info("compare=%s", usblp_status_type[i]);
					if ( !( strcmp(usblpid_info.mfr, usblp_status_type[i]) ) )
						break;
				}
				info("%d=%s", i, usblp_status_type[i]);
				status=usblp_status_maping[i][status];
				info("STATUS=%x", status);
#endif
				status=0;
				if (copy_to_user ((int *)arg, &status, 2))
					retval = -EFAULT;
				break;
				
/*=================================================================== PaN for Printer Server */

/* Marked by JY 20031118*/
#if 0
			case LPGETSTATUS:
				if (usblp_read_status(usblp, &lpstatus)) {
					err("usblp%d: failed reading printer status", usblp->minor);
					retval = -EIO;
					goto done;
				}
				status = lpstatus;
				if (copy_to_user ((int *)arg, &status, sizeof(int)))
					retval = -EFAULT;
				break;
#endif
/* Marked by JY 20031118*/

			default:
				retval = -EINVAL;
		}

done:
	up (&usblp->sem);
	return retval;
}
Exemplo n.º 9
0
static int proc_get_usblpid(struct usblp *usblp)
{
	char *strtmp, *str_dev_id, *strunknown="unknown"; // Added by PaN
	int i, unk = 0; // Added by PaN
	int length, err;
	int retval = 0;
	
	err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
	
	if (err < 0) {
		dbg ("usblp%d: error = %d reading IEEE-1284 Device ID string",
			usblp->minor, err);
			usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
		retval = -EIO;
		goto done;
	}

	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'",
		usblp->minor, length, &usblp->device_id_string[2]);
	info ("usblp%d Device ID string [%d]='%s'",
		usblp->minor, length, &usblp->device_id_string[2]);

	str_dev_id = &usblp->device_id_string[2];	
	if ( (strtmp = strstr(str_dev_id, "MFG:")) == NULL) {
		if ( (strtmp = strstr(str_dev_id, "MANUFACTURE:")) == NULL) {
			for (i=0; i<7; i++) {
				usblpid_info.mfr[i] = strunknown[i];
			}
			usblpid_info.mfr[i]='\0';
			unk=1;
		}
		else 
			strtmp+=12;
	}
	else
		strtmp+=4;
					
	i=0;
	while (strtmp[i] != ';' && unk==0) {
		usblpid_info.mfr[i] = strtmp[i];
		i++;
	}
	usblpid_info.mfr[i]='\0';
	unk=0;

	if ( (strtmp = strstr(str_dev_id, "MDL:")) == NULL) {
		if ( (strtmp = strstr(str_dev_id, "MODEL:")) == NULL) {
			for (i=0; i<7; i++) {
				usblpid_info.model[i] = strunknown[i];
			}
			usblpid_info.model[i]='\0';
			unk=1;
		}
		else
			strtmp+=6;
		}
	else 
		strtmp+=4;
				
	i=0;
	while (strtmp[i] != ';' && unk==0) {
		usblpid_info.model[i] = strtmp[i];
		i++;
	}		
	usblpid_info.model[i]='\0';
	unk=0;
	
	if ( (strtmp = strstr(str_dev_id, "CLS:")) == NULL) {
		if ( (strtmp = strstr(str_dev_id, "CLASS:")) == NULL) {
			for (i=0; i<7; i++) {
				usblpid_info.class_name[i] = strunknown[i];
			}
			usblpid_info.class_name[i]='\0';
			unk=1;
		}
		else
			strtmp+=6;
	}
	else 
		strtmp+=4;
	
	i=0;
	while (strtmp[i] != ';' && unk==0) {
		usblpid_info.class_name[i]= strtmp[i];
		i++;
	}		
	usblpid_info.class_name[i]='\0';
	unk=0;
	
	if ( (strtmp = strstr(str_dev_id, "DES:")) == NULL) {
		if ( (strtmp = strstr(str_dev_id, "DESCRIPTION:")) == NULL) {
			for (i=0; i<7; i++) {
				usblpid_info.description[i] = strunknown[i];
			}
			usblpid_info.description[i]='\0';
			unk=1;
		}
		else
			strtmp+=12;
	}
	else
		strtmp+=4;
		
	i=0;
	while (strtmp[i] != ';' && unk==0) {
		usblpid_info.description[i]= strtmp[i];
		i++;
	}		
	usblpid_info.description[i]='\0';
done:
	return retval;
	
}