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