summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/udl/udl_main.c
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2025-04-10 12:59:06 +0200
committerThomas Zimmermann <tzimmermann@suse.de>2025-04-14 10:19:21 +0200
commitfb10144ba426b88080c6abcede5f1332bebc3c60 (patch)
tree87010ddfa728e4b0552d3d199137ee107569d941 /drivers/gpu/drm/udl/udl_main.c
parentdf6dc12e5e6ddbf2a59d5283fcf6ccd0b3d0334d (diff)
drm/udl: Support adapters without firmware descriptor
Set default limit on the number of pixels for adapters without vendor firmware descriptor. The devices work as expected, they just don't provide any description. If parsing the vendor firmware descriptor fails, the device falls back to the given default limits. Failing to allocate memory is still an error. v2: - fix typo in constant (Patrik) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> Link: https://lore.kernel.org/r/20250410105948.25463-10-tzimmermann@suse.de
Diffstat (limited to 'drivers/gpu/drm/udl/udl_main.c')
-rw-r--r--drivers/gpu/drm/udl/udl_main.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index b5a6b254a202..3dfeb88cf918 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -76,6 +76,7 @@ static int udl_parse_vendor_descriptor(struct udl_device *udl)
{
struct drm_device *dev = &udl->drm;
struct usb_device *udev = udl_to_usb_device(udl);
+ bool detected = false;
void *buf;
int ret;
unsigned int len;
@@ -84,16 +85,16 @@ static int udl_parse_vendor_descriptor(struct udl_device *udl)
buf = kzalloc(MAX_VENDOR_DESCRIPTOR_SIZE, GFP_KERNEL);
if (!buf)
- return false;
+ return -ENOMEM;
ret = usb_get_descriptor(udev, 0x5f, /* vendor specific */
0, buf, MAX_VENDOR_DESCRIPTOR_SIZE);
if (ret < 0)
- goto unrecognized;
+ goto out;
len = ret;
if (len < 5)
- goto unrecognized;
+ goto out;
desc = buf;
desc_end = desc + len;
@@ -103,21 +104,20 @@ static int udl_parse_vendor_descriptor(struct udl_device *udl)
(desc[2] != 0x01) || /* version (2 bytes) */
(desc[3] != 0x00) ||
(desc[4] != len - 2)) /* length after type */
- goto unrecognized;
+ goto out;
desc += 5;
+ detected = true;
+
while (desc < desc_end)
desc = udl_parse_key_value_pair(udl, desc, desc_end);
- goto success;
-
-unrecognized:
- /* allow udlfb to load for now even if firmware unrecognized */
- drm_warn(dev, "Unrecognized vendor firmware descriptor\n");
-
-success:
+out:
+ if (!detected)
+ drm_warn(dev, "Unrecognized vendor firmware descriptor\n");
kfree(buf);
- return true;
+
+ return 0;
}
/*
@@ -345,11 +345,16 @@ int udl_init(struct udl_device *udl)
drm_warn(dev, "buffer sharing not supported"); /* not an error */
}
- if (!udl_parse_vendor_descriptor(udl)) {
- ret = -ENODEV;
- DRM_ERROR("firmware not recognized. Assume incompatible device\n");
+ /*
+ * Not all devices provide vendor descriptors with device
+ * information. Initialize to default values of real-world
+ * devices. It is just enough memory for FullHD.
+ */
+ udl->sku_pixel_limit = UDL_SKU_PIXEL_LIMIT_DEFAULT;
+
+ ret = udl_parse_vendor_descriptor(udl);
+ if (ret)
goto err;
- }
if (udl_select_std_channel(udl))
DRM_ERROR("Selecting channel failed\n");