public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* [bug report] media: rc: ttusbir: respect DMA coherency rules
@ 2026-04-10 10:12 Dan Carpenter
  2026-04-10 19:59 ` Sean Young
  0 siblings, 1 reply; 2+ messages in thread
From: Dan Carpenter @ 2026-04-10 10:12 UTC (permalink / raw)
  To: Oliver Neukum; +Cc: linux-media

Hello Oliver Neukum,

Commit 50acaad3d202 ("media: rc: ttusbir: respect DMA coherency
rules") from Feb 11, 2026 (linux-next), leads to the following Smatch
static checker warning:

	drivers/media/rc/ttusbir.c:281 ttusbir_probe()
	error: we previously assumed 'tt->bulk_buffer' could be null (see line 198)

drivers/media/rc/ttusbir.c
    180 static int ttusbir_probe(struct usb_interface *intf,
    181                          const struct usb_device_id *id)
    182 {
    183         struct ttusbir *tt;
    184         struct usb_interface_descriptor *idesc;
    185         struct usb_endpoint_descriptor *desc;
    186         struct rc_dev *rc;
    187         int i, j, ret;
    188         int altsetting = -1;
    189         u8 *buffer;
    190 
    191         tt = kzalloc_obj(*tt);
    192         buffer = kzalloc(5, GFP_KERNEL);
    193         rc = rc_allocate_device(RC_DRIVER_IR_RAW);
    194         if (!tt || !rc || buffer) {

This ! in !buffer is missing.

    195                 ret = -ENOMEM;
    196                 goto out;
    197         }
    198         tt->bulk_buffer = buffer;
    199 
    200         /* find the correct alt setting */
    201         for (i = 0; i < intf->num_altsetting && altsetting == -1; i++) {
    202                 int max_packet, bulk_out_endp = -1, iso_in_endp = -1;
    203 
    204                 idesc = &intf->altsetting[i].desc;
    205 
    206                 for (j = 0; j < idesc->bNumEndpoints; j++) {
    207                         desc = &intf->altsetting[i].endpoint[j].desc;
    208                         max_packet = le16_to_cpu(desc->wMaxPacketSize);
    209                         if (usb_endpoint_dir_in(desc) &&
    210                                         usb_endpoint_xfer_isoc(desc) &&
    211                                         max_packet == 0x10)
    212                                 iso_in_endp = j;
    213                         else if (usb_endpoint_dir_out(desc) &&
    214                                         usb_endpoint_xfer_bulk(desc) &&
    215                                         max_packet == 0x20)
    216                                 bulk_out_endp = j;
    217 
    218                         if (bulk_out_endp != -1 && iso_in_endp != -1) {
    219                                 tt->bulk_out_endp = bulk_out_endp;
    220                                 tt->iso_in_endp = iso_in_endp;
    221                                 altsetting = i;
    222                                 break;
    223                         }
    224                 }
    225         }
    226 
    227         if (altsetting == -1) {
    228                 dev_err(&intf->dev, "cannot find expected altsetting\n");
    229                 ret = -ENODEV;
    230                 goto out;
    231         }
    232 
    233         tt->dev = &intf->dev;
    234         tt->udev = interface_to_usbdev(intf);
    235         tt->rc = rc;
    236 
    237         ret = usb_set_interface(tt->udev, 0, altsetting);
    238         if (ret)
    239                 goto out;
    240 
    241         for (i = 0; i < NUM_URBS; i++) {
    242                 struct urb *urb = usb_alloc_urb(8, GFP_KERNEL);
    243                 void *buffer;
    244 
    245                 if (!urb) {
    246                         ret = -ENOMEM;
    247                         goto out;
    248                 }
    249 
    250                 urb->dev = tt->udev;
    251                 urb->context = tt;
    252                 urb->pipe = usb_rcvisocpipe(tt->udev, tt->iso_in_endp);
    253                 urb->interval = 1;
    254                 buffer = usb_alloc_coherent(tt->udev, 128, GFP_KERNEL,
    255                                                 &urb->transfer_dma);
    256                 if (!buffer) {
    257                         usb_free_urb(urb);
    258                         ret = -ENOMEM;
    259                         goto out;
    260                 }
    261                 urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP | URB_ISO_ASAP;
    262                 urb->transfer_buffer = buffer;
    263                 urb->complete = ttusbir_urb_complete;
    264                 urb->number_of_packets = 8;
    265                 urb->transfer_buffer_length = 128;
    266 
    267                 for (j = 0; j < 8; j++) {
    268                         urb->iso_frame_desc[j].offset = j * 16;
    269                         urb->iso_frame_desc[j].length = 16;
    270                 }
    271 
    272                 tt->urb[i] = urb;
    273         }
    274 
    275         tt->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
    276         if (!tt->bulk_urb) {
    277                 ret = -ENOMEM;
    278                 goto out;
    279         }
    280 
--> 281         tt->bulk_buffer[0] = 0xaa;
                ^^^^^^^^^^^^^^^^^^

    282         tt->bulk_buffer[1] = 0x01;

This email is a free service from the Smatch-CI project [smatch.sf.net].

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [bug report] media: rc: ttusbir: respect DMA coherency rules
  2026-04-10 10:12 [bug report] media: rc: ttusbir: respect DMA coherency rules Dan Carpenter
@ 2026-04-10 19:59 ` Sean Young
  0 siblings, 0 replies; 2+ messages in thread
From: Sean Young @ 2026-04-10 19:59 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: Oliver Neukum, linux-media

On Fri, Apr 10, 2026 at 01:12:29PM +0300, Dan Carpenter wrote:
> Hello Oliver Neukum,
> 
> Commit 50acaad3d202 ("media: rc: ttusbir: respect DMA coherency
> rules") from Feb 11, 2026 (linux-next), leads to the following Smatch
> static checker warning:
> 
> 	drivers/media/rc/ttusbir.c:281 ttusbir_probe()
> 	error: we previously assumed 'tt->bulk_buffer' could be null (see line 198)
> 
> drivers/media/rc/ttusbir.c
>     180 static int ttusbir_probe(struct usb_interface *intf,
>     181                          const struct usb_device_id *id)
>     182 {
>     183         struct ttusbir *tt;
>     184         struct usb_interface_descriptor *idesc;
>     185         struct usb_endpoint_descriptor *desc;
>     186         struct rc_dev *rc;
>     187         int i, j, ret;
>     188         int altsetting = -1;
>     189         u8 *buffer;
>     190 
>     191         tt = kzalloc_obj(*tt);
>     192         buffer = kzalloc(5, GFP_KERNEL);
>     193         rc = rc_allocate_device(RC_DRIVER_IR_RAW);
>     194         if (!tt || !rc || buffer) {
> 
> This ! in !buffer is missing.

Yep, that's wrong.

Thank you for reporting, this obviously breaks the driver.

Sean

> 
>     195                 ret = -ENOMEM;
>     196                 goto out;
>     197         }
>     198         tt->bulk_buffer = buffer;
>     199 
>     200         /* find the correct alt setting */
>     201         for (i = 0; i < intf->num_altsetting && altsetting == -1; i++) {
>     202                 int max_packet, bulk_out_endp = -1, iso_in_endp = -1;
>     203 
>     204                 idesc = &intf->altsetting[i].desc;
>     205 
>     206                 for (j = 0; j < idesc->bNumEndpoints; j++) {
>     207                         desc = &intf->altsetting[i].endpoint[j].desc;
>     208                         max_packet = le16_to_cpu(desc->wMaxPacketSize);
>     209                         if (usb_endpoint_dir_in(desc) &&
>     210                                         usb_endpoint_xfer_isoc(desc) &&
>     211                                         max_packet == 0x10)
>     212                                 iso_in_endp = j;
>     213                         else if (usb_endpoint_dir_out(desc) &&
>     214                                         usb_endpoint_xfer_bulk(desc) &&
>     215                                         max_packet == 0x20)
>     216                                 bulk_out_endp = j;
>     217 
>     218                         if (bulk_out_endp != -1 && iso_in_endp != -1) {
>     219                                 tt->bulk_out_endp = bulk_out_endp;
>     220                                 tt->iso_in_endp = iso_in_endp;
>     221                                 altsetting = i;
>     222                                 break;
>     223                         }
>     224                 }
>     225         }
>     226 
>     227         if (altsetting == -1) {
>     228                 dev_err(&intf->dev, "cannot find expected altsetting\n");
>     229                 ret = -ENODEV;
>     230                 goto out;
>     231         }
>     232 
>     233         tt->dev = &intf->dev;
>     234         tt->udev = interface_to_usbdev(intf);
>     235         tt->rc = rc;
>     236 
>     237         ret = usb_set_interface(tt->udev, 0, altsetting);
>     238         if (ret)
>     239                 goto out;
>     240 
>     241         for (i = 0; i < NUM_URBS; i++) {
>     242                 struct urb *urb = usb_alloc_urb(8, GFP_KERNEL);
>     243                 void *buffer;
>     244 
>     245                 if (!urb) {
>     246                         ret = -ENOMEM;
>     247                         goto out;
>     248                 }
>     249 
>     250                 urb->dev = tt->udev;
>     251                 urb->context = tt;
>     252                 urb->pipe = usb_rcvisocpipe(tt->udev, tt->iso_in_endp);
>     253                 urb->interval = 1;
>     254                 buffer = usb_alloc_coherent(tt->udev, 128, GFP_KERNEL,
>     255                                                 &urb->transfer_dma);
>     256                 if (!buffer) {
>     257                         usb_free_urb(urb);
>     258                         ret = -ENOMEM;
>     259                         goto out;
>     260                 }
>     261                 urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP | URB_ISO_ASAP;
>     262                 urb->transfer_buffer = buffer;
>     263                 urb->complete = ttusbir_urb_complete;
>     264                 urb->number_of_packets = 8;
>     265                 urb->transfer_buffer_length = 128;
>     266 
>     267                 for (j = 0; j < 8; j++) {
>     268                         urb->iso_frame_desc[j].offset = j * 16;
>     269                         urb->iso_frame_desc[j].length = 16;
>     270                 }
>     271 
>     272                 tt->urb[i] = urb;
>     273         }
>     274 
>     275         tt->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
>     276         if (!tt->bulk_urb) {
>     277                 ret = -ENOMEM;
>     278                 goto out;
>     279         }
>     280 
> --> 281         tt->bulk_buffer[0] = 0xaa;
>                 ^^^^^^^^^^^^^^^^^^
> 
>     282         tt->bulk_buffer[1] = 0x01;
> 
> This email is a free service from the Smatch-CI project [smatch.sf.net].
> 
> regards,
> dan carpenter

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-04-10 20:06 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-10 10:12 [bug report] media: rc: ttusbir: respect DMA coherency rules Dan Carpenter
2026-04-10 19:59 ` Sean Young

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox