VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / usb / class / usblp.c
index 0e269d7..b6da400 100644 (file)
@@ -75,6 +75,7 @@
 #define IOCNR_HP_SET_CHANNEL           4
 #define IOCNR_GET_BUS_ADDRESS          5
 #define IOCNR_GET_VID_PID              6
+#define IOCNR_SOFT_RESET               7
 /* Get device_id string: */
 #define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
 /* The following ioctls were added for http://hpoj.sourceforge.net: */
@@ -90,6 +91,8 @@
 #define LPIOC_GET_BUS_ADDRESS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_BUS_ADDRESS, len)
 /* Get two-int array: [0]=vendor ID, [1]=product ID: */
 #define LPIOC_GET_VID_PID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_VID_PID, len)
+/* Perform class specific soft reset */
+#define LPIOC_SOFT_RESET _IOC(_IOC_NONE, 'P', IOCNR_SOFT_RESET, 0);
 
 /*
  * A DEVICE_ID string may include the printer's serial number.
@@ -226,11 +229,21 @@ extern struct usb_driver usblp_driver;
 
 static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, int recip, int value, void *buf, int len)
 {
-       int retval = usb_control_msg(usblp->dev,
+       int retval;
+       int index = usblp->ifnum;
+
+       /* High byte has the interface index.
+          Low byte has the alternate setting.
+        */
+       if ((request == USBLP_REQ_GET_ID) && (type == USB_TYPE_CLASS)) {
+         index = (usblp->ifnum<<8)|usblp->protocol[usblp->current_protocol].alt_setting;
+       }
+
+       retval = usb_control_msg(usblp->dev,
                dir ? usb_rcvctrlpipe(usblp->dev, 0) : usb_sndctrlpipe(usblp->dev, 0),
-               request, type | dir | recip, value, usblp->ifnum, buf, len, USBLP_WRITE_TIMEOUT);
-       dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d len: %#x result: %d",
-               request, !!dir, recip, value, len, retval);
+               request, type | dir | recip, value, index, buf, len, USBLP_WRITE_TIMEOUT);
+       dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d idx: %d len: %#x result: %d",
+               request, !!dir, recip, value, index, len, retval);
        return retval < 0 ? retval : 0;
 }
 
@@ -440,6 +453,9 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                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)) {
@@ -574,6 +590,13 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                                        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;
                }
@@ -748,6 +771,7 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count,
                        usblp->minor, usblp->readurb->status);
                usblp->readurb->dev = usblp->dev;
                usblp->readcount = 0;
+               usblp->rcomplete = 0;
                if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
                        dbg("error submitting urb");
                count = -EIO;
@@ -827,7 +851,7 @@ 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 = 0;
+       struct usblp *usblp = NULL;
        int protocol;
        int retval;
 
@@ -995,7 +1019,7 @@ static int usblp_select_alts(struct usblp *usblp)
                        continue;
 
                /* Look for bulk OUT and IN endpoints. */
-               epwrite = epread = 0;
+               epwrite = epread = NULL;
                for (e = 0; e < ifd->desc.bNumEndpoints; e++) {
                        epd = &ifd->endpoint[e].desc;