示例#1
0
文件: usblp.c 项目: Mr-Aloof/wl500g
static int proc_get_usblpid(struct usblp *usblp)
{
	char *str_dev_id; // Added by PaN: JYWeng 20031212: modified from the above
	int length;

	length = usblp_cache_device_id_string(usblp);
	if (length < 0)
		return length;

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

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

	return 0;
}
示例#2
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;
}
示例#3
0
static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct usblp *usblp = file->private_data;
	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;
	}

	if (usblp->sleeping) {
		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) {

			case LPGETSTATUS:
				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;
				if (copy_to_user ((void __user *)arg, &status, sizeof(int)))
					retval = -EFAULT;
				break;

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

			default:
				retval = -ENOTTY;
		}

done:
	mutex_unlock (&usblp->mut);
	return retval;
}
示例#4
0
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;
}
示例#5
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;
}
示例#6
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, i;
	unsigned char lpstatus, newChannel;
	int status;
	int twoints[2];
	int retval = 0;

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

			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;

			default:
				retval = -EINVAL;
		}

done:
	up (&usblp->sem);
	return retval;
}
示例#7
-1
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;
}
示例#8
-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;
}