/* urb->transfer_buffer_length set to actual before submit */
usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, 1),
buf, size, udl_urb_completion, unode);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
/* Wait for an in-flight buffer to complete and get re-queued */ if (!wait_event_lock_irq_timeout(udl->urbs.sleep,
!udl->urbs.count ||
!list_empty(&udl->urbs.list),
udl->urbs.lock, timeout)) {
DRM_INFO("wait for urb interrupted: available: %d\n",
udl->urbs.available); return NULL;
}
int udl_submit_urb(struct udl_device *udl, struct urb *urb, size_t len)
{ int ret;
if (WARN_ON(len > udl->urbs.size)) {
ret = -EINVAL; goto error;
}
urb->transfer_buffer_length = len; /* set to actual payload len */
ret = usb_submit_urb(urb, GFP_ATOMIC);
error: if (ret) {
udl_urb_completion(urb); /* because no one else will */
DRM_ERROR("usb_submit_urb error %x\n", ret);
} return ret;
}
/* wait until all pending URBs have been processed */ void udl_sync_pending_urbs(struct udl_device *udl)
{ struct drm_device *dev = &udl->drm;
spin_lock_irq(&udl->urbs.lock); /* 2 seconds as a sane timeout */ if (!wait_event_lock_irq_timeout(udl->urbs.sleep,
udl->urbs.available == udl->urbs.count,
udl->urbs.lock,
msecs_to_jiffies(2000)))
drm_err(dev, "Timeout for syncing pending URBs\n");
spin_unlock_irq(&udl->urbs.lock);
}
int udl_init(struct udl_device *udl)
{ struct drm_device *dev = &udl->drm; int ret = -ENOMEM; struct device *dma_dev;
DRM_DEBUG("\n");
dma_dev = usb_intf_get_dma_device(to_usb_interface(dev->dev)); if (dma_dev) {
drm_dev_set_dma_dev(dev, dma_dev);
put_device(dma_dev);
} else {
drm_warn(dev, "buffer sharing not supported"); /* not an error */
}
/* * 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");
if (!udl_alloc_urb_list(udl, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
DRM_ERROR("udl_alloc_urb_list failed\n");
ret = -ENOMEM; goto err;
}
DRM_DEBUG("\n");
ret = udl_modeset_init(udl); if (ret) goto err;
return 0;
err: if (udl->urbs.count)
udl_free_urb_list(udl);
DRM_ERROR("%d\n", ret); return ret;
}
int udl_drop_usb(struct udl_device *udl)
{
udl_free_urb_list(udl);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.