On Thu, Jun 13, 2002 at 01:19:57AM +0200, Flavien Lebarbe wrote:
> Hello,
> 
> 
> ioctl(LPGETSTATUS) is known to put the status into  an  int.  The  usblp
> driver has a problem in this area as it does not put it into an int  but
> into a char. Let's see :
> 
> from drivers/char/lp.c : lp_ioctl :
>     int status
>     copy_to_user((int *) arg, &status, sizeof(int))
> 
> from drivers/usb/printer.c : usblp_ioctl :
>     unsigned char status;
>     copy_to_user ((unsigned char *)arg, &status, 1)
> 
> Even though in  most  cases  it  can  work  unnoticed  on  little-endian
> machines ;o), it's broken on non-little-endian machines (I got bitten on
> PPC).
> 
> Attached are patches to fix this issue. These  are  against  2.4.18  and
> 2.5.21 (untested), upported from 2.4.12 (with 2.4.18 usb stack) which is
> the one I've successfully tested. It  works  for  me  on  PPC  now  (I'm
> printing  on  USB  Canon  printers  like   the   S100   using   in-house
> hardware...). Feedback is welcome,

Yes, this sounds reasonable. Greg, please apply this.

> --- linux-2.4.18/drivers/usb/printer.c        Wed Oct 10 00:15:02 2001
> +++ linux-2.4.18.fl/drivers/usb/printer.c     Wed Jun 12 19:03:01 2002
> @@ -295,7 +295,8 @@
>  {
>       struct usblp *usblp = file->private_data;
>       int length, err;
> -     unsigned char status;
> +     unsigned char lpstatus;
> +     int status;
>       int retval = 0;
>  
>       down (&usblp->sem);
> @@ -349,12 +350,13 @@
>               switch (cmd) {
>  
>                       case LPGETSTATUS:
> -                             if (usblp_read_status(usblp, &status)) {
> +                             if (usblp_read_status(usblp, &lpstatus)) {
>                                       err("usblp%d: failed reading printer status", 
>usblp->minor);
>                                       retval = -EIO;
>                                       goto done;
>                               }
> -                             if (copy_to_user ((unsigned char *)arg, &status, 1))
> +                             status = lpstatus;
> +                             if (copy_to_user ((int *)arg, &status, sizeof(int)))
>                                       retval = -EFAULT;
>                               break;
>  

> --- linux-2.5.21/drivers/usb/class/printer.c  Sun Jun  9 07:27:45 2002
> +++ linux-2.5.21.fl/drivers/usb/class/printer.c       Wed Jun 12 16:08:08 2002
> @@ -418,7 +418,8 @@
>  {
>       struct usblp *usblp = file->private_data;
>       int length, err, i;
> -     unsigned char status, newChannel;
> +     unsigned char lpstatus, newChannel;
> +     int status;
>       int twoints[2];
>       int retval = 0;
>  
> @@ -569,12 +570,13 @@
>               switch (cmd) {
>  
>                       case LPGETSTATUS:
> -                             if (usblp_read_status(usblp, &status)) {
> +                             if (usblp_read_status(usblp, &lpstatus)) {
>                                       err("usblp%d: failed reading printer status", 
>usblp->minor);
>                                       retval = -EIO;
>                                       goto done;
>                               }
> -                             if (copy_to_user ((unsigned char *)arg, &status, 1))
> +                             status = lpstatus;
> +                             if (copy_to_user ((int *)arg, &status, sizeof(int)))
>                                       retval = -EFAULT;
>                               break;
>  


-- 
Vojtech Pavlik
SuSE Labs

_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas - 
http://devcon.sprintpcs.com/adp/index.cfm?source=osdntextlink

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to