All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Keeping <john@metanate.com>
To: Volodymyr Lisivka <vlisivka@gmail.com>
Cc: linux-usb@vger.kernel.org
Subject: Re: BUG: iPNPstring in f_printer USB gadget is reduced by two bytes
Date: Tue, 7 Dec 2021 10:27:11 +0000	[thread overview]
Message-ID: <Ya82/4kQ2+7Iuzl6@donbot> (raw)
In-Reply-To: <CAKjGFBUdjXcZoVV4jdrgTz4rKThTfZAK4CqreKmBZ4KHE+K1GA@mail.gmail.com>

On Fri, Dec 03, 2021 at 04:46:17PM +0200, Volodymyr Lisivka wrote:
> > On Tue, Nov 30, 2021 at 08:01:46PM +0200, Volodymyr Lisivka wrote:
> > > Description:
> > >
> > > Printer USB gadget uses iPNPstring to communicate device name and
> > > command language with host. Linux driver for printer gadget sends
> > > GET_DEVICE_ID response packet without 2 last bytes, which may cause
> > > trouble for the host driver.
> > >
> > > Steps to reproduce:
> > >
> > > Use Raspberry Pi, or an other device with USB OTG plug. Raspberry Pi 4
> > > was used by issue author.
> > > Configure plug to be in peripheral mode, e.g. by adding
> > > dtoverlay=dwc2,dr_mode=peripheral to /boot/config.txt.
> > > Connect OTG port to host and reboot Raspberry Pi.
> > > Load g_printer module using command sudo modprobe g_printer.
> > > Use command ./get-iPNPstring.pl /dev/usb/lp1 to get iPNPstring from
> > > the device. (See get-iPNPstring.pl.gz ). As alternative, kernel usbmon
> > > or WireShark can be used to capture raw USB packet for GET_DEVICE_ID
> > > response.
> > >
> > > Expected result:
> > >
> > > It's expected to receive same string as defined in module:
> > > iPNPstring='MFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;'
> > >
> > > Actual result:
> > >
> > > iPNPstring='MFG:linux;MDL:g_printer;CLS:PRINTER;SN:'
> > >
> > > (Notice that last 2 chars are missing).
> > >
> > > Workarround:
> > >
> > > Just add two space to the end of printer gadget iPNPstring.
> > >
> > > Root cause:
> > >
> > > In drivers/usb/gadget/function/f_printer.c, length of iPNPstring is
> > > used as length of the whole packet, without length of 2 byte size
> > > field.
> >
> > If I understand correctly, the length should be inclusive of the two
> > length bytes, but currently this driver encodes it exclusive.
> >
> > The USB printer class specification says:
> >
> > ... a device ID string that is compatible with IEEE 1284.  See
> > IEEE 1284 for syntax and formatting information
> >
> > and goes on to specify that this includes the length in the first two
> > bytes as big endian.
> >
> > I don't have access to IEEE 1284, but looking in drivers/parport/probe.c
> > which implements the host side of IEEE 1284, we find
> > parport_read_device_id() with the comment:
> >
> > /* Some devices wrongly send LE length, and some send it two
> > * bytes short. Construct a sorted array of lengths to try. */
> >
> > and code that assumes the values are inclusive of the length bytes.
> >
> > So the patch below looks like it does the right thing to me, although it
> > appears whitespace damaged and it may be clearer to introduce a separate
> > variable for the string length compared to the value.
> 
> diff --git a/drivers/usb/gadget/function/f_printer.c
> b/drivers/usb/gadget/function/f_printer.c
> index 236ecc968..403faa05b 100644
> --- a/drivers/usb/gadget/function/f_printer.c
> +++ b/drivers/usb/gadget/function/f_printer.c
> @@ -987,6 +987,7 @@ static int printer_func_setup(struct usb_function *f,
>         u16                     wIndex = le16_to_cpu(ctrl->wIndex);
>         u16                     wValue = le16_to_cpu(ctrl->wValue);
>         u16                     wLength = le16_to_cpu(ctrl->wLength);
> +       u16                     pnp_length;
> 
>         DBG(dev, "ctrl req%02x.%02x v%04x i%04x l%d\n",
>                 ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength);
> @@ -1003,11 +1004,12 @@ static int printer_func_setup(struct usb_function *f,
>                                 value = 0;
>                                 break;
>                         }
> -                       value = strlen(dev->pnp_string);
> +                       pnp_length = strlen(dev->pnp_string);
> +                       value = pnp_length + 2;
>                         buf[0] = (value >> 8) & 0xFF;
>                         buf[1] = value & 0xFF;
> -                       memcpy(buf + 2, dev->pnp_string, value);
> -                       DBG(dev, "1284 PNP String: %x %s\n", value,
> +                       memcpy(buf + 2, dev->pnp_string, pnp_length);
> +                       DBG(dev, "1284 PNP String: %x %s\n", pnp_length,
>                             dev->pnp_string);
>                         break;
> 
> 
> 
> >
> > Are you interested in working up a proper patch, as described in
> > Documentation/process/submitting-patches.rst ?
> >
> 
> No. It's my second patch in 15 years. If you have a proper procedure
> for diffing/patching, then make corresponding targets in the top
> Makefile, e.g. `make diff` or `make patch`.

Do you mean `git format-patch`? ;-)

Note that the diff is only part of a patch, the commit message and
Signed-off-by line ceritifying the developer certificate of origin [1]
are also important.

[1] https://developercertificate.org/

  reply	other threads:[~2021-12-07 10:27 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-03 14:46 BUG: iPNPstring in f_printer USB gadget is reduced by two bytes Volodymyr Lisivka
2021-12-07 10:27 ` John Keeping [this message]
  -- strict thread matches above, loose matches on Subject: below --
2021-11-30 18:01 Volodymyr Lisivka
2021-12-01 15:28 ` John Keeping

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Ya82/4kQ2+7Iuzl6@donbot \
    --to=john@metanate.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=vlisivka@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.