Lines Matching +full:render +full:- +full:max
2 * udlfb.c -- Framebuffer driver for DisplayLink USB controller
13 * usb-skeleton by GregKH.
15 * Device-specific portions based on information from Displaylink, with work
51 * There are many DisplayLink-based graphics products, all with unique PIDs.
52 * So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff)
109 * ----- -----------------------------
195 while (actual_count--) { in dlfb_lfsr16()
224 xds = var->left_margin + var->hsync_len; in dlfb_set_vid_cmds()
227 xde = xds + var->xres; in dlfb_set_vid_cmds()
231 yds = var->upper_margin + var->vsync_len; in dlfb_set_vid_cmds()
234 yde = yds + var->yres; in dlfb_set_vid_cmds()
237 /* x end count is active + blanking - 1 */ in dlfb_set_vid_cmds()
239 xde + var->right_margin - 1); in dlfb_set_vid_cmds()
245 wrptr = dlfb_set_register_lfsr16(wrptr, 0x0D, var->hsync_len + 1); in dlfb_set_vid_cmds()
248 wrptr = dlfb_set_register_16(wrptr, 0x0F, var->xres); in dlfb_set_vid_cmds()
251 yec = var->yres + var->upper_margin + var->lower_margin + in dlfb_set_vid_cmds()
252 var->vsync_len; in dlfb_set_vid_cmds()
259 wrptr = dlfb_set_register_lfsr16(wrptr, 0x15, var->vsync_len); in dlfb_set_vid_cmds()
262 wrptr = dlfb_set_register_16(wrptr, 0x17, var->yres); in dlfb_set_vid_cmds()
266 200*1000*1000/var->pixclock); in dlfb_set_vid_cmds()
285 if (!atomic_read(&dev->usb_active)) in dlfb_set_video_mode()
286 return -EPERM; in dlfb_set_video_mode()
290 return -ENOMEM; in dlfb_set_video_mode()
292 buf = (char *) urb->transfer_buffer; in dlfb_set_video_mode()
304 wrptr = dlfb_set_base8bpp(wrptr, dev->info->fix.smem_len); in dlfb_set_video_mode()
310 writesize = wrptr - buf; in dlfb_set_video_mode()
314 dev->blank_mode = FB_BLANK_UNBLANK; in dlfb_set_video_mode()
321 unsigned long start = vma->vm_start; in dlfb_ops_mmap()
322 unsigned long size = vma->vm_end - vma->vm_start; in dlfb_ops_mmap()
323 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; in dlfb_ops_mmap()
326 if (offset + size > info->fix.smem_len) in dlfb_ops_mmap()
327 return -EINVAL; in dlfb_ops_mmap()
329 pos = (unsigned long)info->fix.smem_start + offset; in dlfb_ops_mmap()
337 return -EAGAIN; in dlfb_ops_mmap()
342 size -= PAGE_SIZE; in dlfb_ops_mmap()
347 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ in dlfb_ops_mmap()
378 for (k = width - 1; k > j; k--) { in dlfb_trim_hline()
385 identical = start + (width - end); in dlfb_trim_hline()
387 *width_bytes = (end - start) * sizeof(unsigned long); in dlfb_trim_hline()
393 * Render a command stream for an encoded horizontal line segment of pixels.
432 (cmd_buffer_end - MIN_RLX_CMD_BYTES > cmd)) { in dlfb_compress_hline()
453 min((int)(pixel_end - pixel), in dlfb_compress_hline()
454 (int)(cmd_buffer_end - cmd) / bpp)); in dlfb_compress_hline()
456 prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp); in dlfb_compress_hline()
468 *raw_pixels_count_byte = ((repeating_pixel - in dlfb_compress_hline()
477 *cmd++ = ((pixel - repeating_pixel) - 1) & 0xFF; in dlfb_compress_hline()
487 *raw_pixels_count_byte = (pixel-raw_pixel_start) & 0xFF; in dlfb_compress_hline()
490 *cmd_pixels_count_byte = (pixel - cmd_pixel_start) & 0xFF; in dlfb_compress_hline()
491 dev_addr += (pixel - cmd_pixel_start) * bpp; in dlfb_compress_hline()
495 /* Fill leftover bytes with no-ops */ in dlfb_compress_hline()
497 memset(cmd, 0xAF, cmd_buffer_end - cmd); in dlfb_compress_hline()
520 u32 dev_addr = dev->base16 + byte_offset; in dlfb_render_hline()
523 u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; in dlfb_render_hline()
529 if (dev->backing_buffer) { in dlfb_render_hline()
531 const u8 *back_start = (u8 *) (dev->backing_buffer in dlfb_render_hline()
537 offset = next_pixel - line_start; in dlfb_render_hline()
554 int len = cmd - (u8 *) urb->transfer_buffer; in dlfb_render_hline()
562 cmd = urb->transfer_buffer; in dlfb_render_hline()
563 cmd_end = &cmd[urb->transfer_buffer_length]; in dlfb_render_hline()
586 width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long)); in dlfb_handle_damage()
590 (x + width > dev->info->var.xres) || in dlfb_handle_damage()
591 (y + height > dev->info->var.yres)) in dlfb_handle_damage()
592 return -EINVAL; in dlfb_handle_damage()
594 if (!atomic_read(&dev->usb_active)) in dlfb_handle_damage()
600 cmd = urb->transfer_buffer; in dlfb_handle_damage()
603 const int line_offset = dev->info->fix.line_length * i; in dlfb_handle_damage()
607 (char *) dev->info->fix.smem_start, in dlfb_handle_damage()
613 if (cmd > (char *) urb->transfer_buffer) { in dlfb_handle_damage()
615 int len = cmd - (char *) urb->transfer_buffer; in dlfb_handle_damage()
622 atomic_add(bytes_sent, &dev->bytes_sent); in dlfb_handle_damage()
623 atomic_add(bytes_identical, &dev->bytes_identical); in dlfb_handle_damage()
624 atomic_add(width*height*2, &dev->bytes_rendered); in dlfb_handle_damage()
626 atomic_add(((unsigned int) ((end_cycles - start_cycles) in dlfb_handle_damage()
628 &dev->cpu_kcycles_used); in dlfb_handle_damage()
636 * Not used by X Windows or text-mode console. But useful for testing.
643 struct dlfb_data *dev = info->par; in dlfb_ops_write()
649 int start = max((int)(offset / info->fix.line_length) - 1, 0); in dlfb_ops_write()
650 int lines = min((u32)((result / info->fix.line_length) + 1), in dlfb_ops_write()
651 (u32)info->var.yres); in dlfb_ops_write()
653 dlfb_handle_damage(dev, 0, start, info->var.xres, in dlfb_ops_write()
654 lines, info->screen_base); in dlfb_ops_write()
665 struct dlfb_data *dev = info->par; in dlfb_ops_copyarea()
669 dlfb_handle_damage(dev, area->dx, area->dy, in dlfb_ops_copyarea()
670 area->width, area->height, info->screen_base); in dlfb_ops_copyarea()
676 struct dlfb_data *dev = info->par; in dlfb_ops_imageblit()
680 dlfb_handle_damage(dev, image->dx, image->dy, in dlfb_ops_imageblit()
681 image->width, image->height, info->screen_base); in dlfb_ops_imageblit()
687 struct dlfb_data *dev = info->par; in dlfb_ops_fillrect()
691 dlfb_handle_damage(dev, rect->dx, rect->dy, rect->width, in dlfb_ops_fillrect()
692 rect->height, info->screen_base); in dlfb_ops_fillrect()
696 * NOTE: fb_defio.c is holding info->fbdefio.mutex
705 struct fb_deferred_io *fbdefio = info->fbdefio; in dlfb_dpy_deferred_io()
706 struct dlfb_data *dev = info->par; in dlfb_dpy_deferred_io()
717 if (!atomic_read(&dev->usb_active)) in dlfb_dpy_deferred_io()
726 cmd = urb->transfer_buffer; in dlfb_dpy_deferred_io()
728 /* walk the written page list and render each to device */ in dlfb_dpy_deferred_io()
729 list_for_each_entry(cur, &fbdefio->pagelist, lru) { in dlfb_dpy_deferred_io()
731 if (dlfb_render_hline(dev, &urb, (char *) info->fix.smem_start, in dlfb_dpy_deferred_io()
732 &cmd, cur->index << PAGE_SHIFT, in dlfb_dpy_deferred_io()
738 if (cmd > (char *) urb->transfer_buffer) { in dlfb_dpy_deferred_io()
740 int len = cmd - (char *) urb->transfer_buffer; in dlfb_dpy_deferred_io()
747 atomic_add(bytes_sent, &dev->bytes_sent); in dlfb_dpy_deferred_io()
748 atomic_add(bytes_identical, &dev->bytes_identical); in dlfb_dpy_deferred_io()
749 atomic_add(bytes_rendered, &dev->bytes_rendered); in dlfb_dpy_deferred_io()
751 atomic_add(((unsigned int) ((end_cycles - start_cycles) in dlfb_dpy_deferred_io()
753 &dev->cpu_kcycles_used); in dlfb_dpy_deferred_io()
767 ret = usb_control_msg(dev->udev, in dlfb_get_edid()
768 usb_rcvctrlpipe(dev->udev, 0), (0x02), in dlfb_get_edid()
773 i--; in dlfb_get_edid()
788 struct dlfb_data *dev = info->par; in dlfb_ops_ioctl()
790 if (!atomic_read(&dev->usb_active)) in dlfb_ops_ioctl()
796 if (copy_to_user(edid, dev->edid, dev->edid_size)) in dlfb_ops_ioctl()
797 return -EFAULT; in dlfb_ops_ioctl()
807 return -EFAULT; in dlfb_ops_ioctl()
810 * If we have a damage-aware client, turn fb_defio "off" in dlfb_ops_ioctl()
816 if (info->fbdefio) in dlfb_ops_ioctl()
817 info->fbdefio->delay = DL_DEFIO_WRITE_DISABLE; in dlfb_ops_ioctl()
822 if (area.x > info->var.xres) in dlfb_ops_ioctl()
823 area.x = info->var.xres; in dlfb_ops_ioctl()
828 if (area.y > info->var.yres) in dlfb_ops_ioctl()
829 area.y = info->var.yres; in dlfb_ops_ioctl()
832 info->screen_base); in dlfb_ops_ioctl()
845 if (regno >= info->cmap.len) in dlfb_ops_setcolreg()
849 if (info->var.red.offset == 10) { in dlfb_ops_setcolreg()
851 ((u32 *) (info->pseudo_palette))[regno] = in dlfb_ops_setcolreg()
856 ((u32 *) (info->pseudo_palette))[regno] = in dlfb_ops_setcolreg()
868 * Assumes caller is holding info->lock (for open and release at least)
872 struct dlfb_data *dev = info->par; in dlfb_ops_open()
880 return -EBUSY; in dlfb_ops_open()
883 if (dev->virtualized) in dlfb_ops_open()
884 return -ENODEV; in dlfb_ops_open()
886 dev->fb_count++; in dlfb_ops_open()
888 kref_get(&dev->kref); in dlfb_ops_open()
890 if (fb_defio && (info->fbdefio == NULL)) { in dlfb_ops_open()
898 fbdefio->delay = DL_DEFIO_WRITE_DELAY; in dlfb_ops_open()
899 fbdefio->deferred_io = dlfb_dpy_deferred_io; in dlfb_ops_open()
902 info->fbdefio = fbdefio; in dlfb_ops_open()
907 info->node, user, info, dev->fb_count); in dlfb_ops_open()
921 /* this function will wait for all in-flight urbs to complete */ in dlfb_free()
922 if (dev->urbs.count > 0) in dlfb_free()
925 if (dev->backing_buffer) in dlfb_free()
926 vfree(dev->backing_buffer); in dlfb_free()
928 kfree(dev->edid); in dlfb_free()
940 up(&unode->dev->urbs.limit_sem); in dlfb_release_urb_work()
947 struct fb_info *info = dev->info; in dlfb_free_framebuffer_work()
948 int node = info->node; in dlfb_free_framebuffer_work()
952 if (info->cmap.len != 0) in dlfb_free_framebuffer_work()
953 fb_dealloc_cmap(&info->cmap); in dlfb_free_framebuffer_work()
954 if (info->monspecs.modedb) in dlfb_free_framebuffer_work()
955 fb_destroy_modedb(info->monspecs.modedb); in dlfb_free_framebuffer_work()
956 if (info->screen_base) in dlfb_free_framebuffer_work()
957 vfree(info->screen_base); in dlfb_free_framebuffer_work()
959 fb_destroy_modelist(&info->modelist); in dlfb_free_framebuffer_work()
961 dev->info = 0; in dlfb_free_framebuffer_work()
969 kref_put(&dev->kref, dlfb_free); in dlfb_free_framebuffer_work()
973 * Assumes caller is holding info->lock mutex (for open and release at least)
977 struct dlfb_data *dev = info->par; in dlfb_ops_release()
979 dev->fb_count--; in dlfb_ops_release()
981 /* We can't free fb_info here - fbmem will touch it when we return */ in dlfb_ops_release()
982 if (dev->virtualized && (dev->fb_count == 0)) in dlfb_ops_release()
983 schedule_delayed_work(&dev->free_framebuffer_work, HZ); in dlfb_ops_release()
985 if ((dev->fb_count == 0) && (info->fbdefio)) { in dlfb_ops_release()
987 kfree(info->fbdefio); in dlfb_ops_release()
988 info->fbdefio = NULL; in dlfb_ops_release()
989 info->fbops->fb_mmap = dlfb_ops_mmap; in dlfb_ops_release()
993 info->node, user, dev->fb_count); in dlfb_ops_release()
995 kref_put(&dev->kref, dlfb_free); in dlfb_ops_release()
1007 struct dlfb_data *dev = info->par; in dlfb_is_valid_mode()
1009 if (mode->xres * mode->yres > dev->sku_pixel_limit) { in dlfb_is_valid_mode()
1011 mode->xres, mode->yres); in dlfb_is_valid_mode()
1015 pr_info("%dx%d valid mode\n", mode->xres, mode->yres); in dlfb_is_valid_mode()
1026 var->bits_per_pixel = 16; in dlfb_var_color_format()
1027 var->red = red; in dlfb_var_color_format()
1028 var->green = green; in dlfb_var_color_format()
1029 var->blue = blue; in dlfb_var_color_format()
1038 if ((var->xres * var->yres * 2) > info->fix.smem_len) in dlfb_ops_check_var()
1039 return -EINVAL; in dlfb_ops_check_var()
1041 /* set device-specific elements of var unrelated to mode */ in dlfb_ops_check_var()
1047 return -EINVAL; in dlfb_ops_check_var()
1054 struct dlfb_data *dev = info->par; in dlfb_ops_set_par()
1059 pr_notice("set_par mode %dx%d\n", info->var.xres, info->var.yres); in dlfb_ops_set_par()
1061 result = dlfb_set_video_mode(dev, &info->var); in dlfb_ops_set_par()
1063 if ((result == 0) && (dev->fb_count == 0)) { in dlfb_ops_set_par()
1067 pix_framebuffer = (u16 *) info->screen_base; in dlfb_ops_set_par()
1068 for (i = 0; i < info->fix.smem_len / 2; i++) in dlfb_ops_set_par()
1071 dlfb_handle_damage(dev, 0, 0, info->var.xres, info->var.yres, in dlfb_ops_set_par()
1072 info->screen_base); in dlfb_ops_set_par()
1098 struct dlfb_data *dev = info->par; in dlfb_ops_blank()
1102 pr_info("/dev/fb%d FB_BLANK mode %d --> %d\n", in dlfb_ops_blank()
1103 info->node, dev->blank_mode, blank_mode); in dlfb_ops_blank()
1105 if ((dev->blank_mode == FB_BLANK_POWERDOWN) && in dlfb_ops_blank()
1109 dlfb_set_video_mode(dev, &info->var); in dlfb_ops_blank()
1116 bufptr = (char *) urb->transfer_buffer; in dlfb_ops_blank()
1121 /* seems like a render op is needed to have blank change take effect */ in dlfb_ops_blank()
1124 dlfb_submit_urb(dev, urb, bufptr - in dlfb_ops_blank()
1125 (char *) urb->transfer_buffer); in dlfb_ops_blank()
1127 dev->blank_mode = blank_mode; in dlfb_ops_blank()
1151 * Assumes &info->lock held by caller
1156 int retval = -ENOMEM; in dlfb_realloc_framebuffer()
1157 int old_len = info->fix.smem_len; in dlfb_realloc_framebuffer()
1159 unsigned char *old_fb = info->screen_base; in dlfb_realloc_framebuffer()
1165 new_len = info->fix.line_length * info->var.yres; in dlfb_realloc_framebuffer()
1177 if (info->screen_base) { in dlfb_realloc_framebuffer()
1179 vfree(info->screen_base); in dlfb_realloc_framebuffer()
1182 info->screen_base = new_fb; in dlfb_realloc_framebuffer()
1183 info->fix.smem_len = PAGE_ALIGN(new_len); in dlfb_realloc_framebuffer()
1184 info->fix.smem_start = (unsigned long) new_fb; in dlfb_realloc_framebuffer()
1185 info->flags = udlfb_info_flags; in dlfb_realloc_framebuffer()
1191 * that were, in fact, unchanged - wasting limited USB bandwidth in dlfb_realloc_framebuffer()
1198 if (dev->backing_buffer) in dlfb_realloc_framebuffer()
1199 vfree(dev->backing_buffer); in dlfb_realloc_framebuffer()
1200 dev->backing_buffer = new_back; in dlfb_realloc_framebuffer()
1234 if (info->dev) /* only use mutex if info has been registered */ in dlfb_setup_modes()
1235 mutex_lock(&info->lock); in dlfb_setup_modes()
1239 result = -ENOMEM; in dlfb_setup_modes()
1243 fb_destroy_modelist(&info->modelist); in dlfb_setup_modes()
1244 memset(&info->monspecs, 0, sizeof(info->monspecs)); in dlfb_setup_modes()
1251 while (tries--) { in dlfb_setup_modes()
1256 fb_edid_to_monspecs(edid, &info->monspecs); in dlfb_setup_modes()
1258 if (info->monspecs.modedb_len > 0) { in dlfb_setup_modes()
1259 dev->edid = edid; in dlfb_setup_modes()
1260 dev->edid_size = i; in dlfb_setup_modes()
1266 if (info->monspecs.modedb_len == 0) { in dlfb_setup_modes()
1270 if (dev->edid) { in dlfb_setup_modes()
1271 fb_edid_to_monspecs(dev->edid, &info->monspecs); in dlfb_setup_modes()
1272 if (info->monspecs.modedb_len > 0) in dlfb_setup_modes()
1278 if (info->monspecs.modedb_len == 0) { in dlfb_setup_modes()
1280 fb_edid_to_monspecs(default_edid, &info->monspecs); in dlfb_setup_modes()
1281 if (info->monspecs.modedb_len > 0) { in dlfb_setup_modes()
1283 dev->edid = edid; in dlfb_setup_modes()
1284 dev->edid_size = default_edid_size; in dlfb_setup_modes()
1291 if (info->monspecs.modedb_len > 0) { in dlfb_setup_modes()
1293 for (i = 0; i < info->monspecs.modedb_len; i++) { in dlfb_setup_modes()
1294 if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info)) in dlfb_setup_modes()
1295 fb_add_videomode(&info->monspecs.modedb[i], in dlfb_setup_modes()
1296 &info->modelist); in dlfb_setup_modes()
1300 info->monspecs.misc in dlfb_setup_modes()
1305 default_vmode = fb_find_best_display(&info->monspecs, in dlfb_setup_modes()
1306 &info->modelist); in dlfb_setup_modes()
1324 &info->modelist); in dlfb_setup_modes()
1335 &info->modelist); in dlfb_setup_modes()
1339 if ((default_vmode != NULL) && (dev->fb_count == 0)) { in dlfb_setup_modes()
1341 fb_videomode_to_var(&info->var, default_vmode); in dlfb_setup_modes()
1342 dlfb_var_color_format(&info->var); in dlfb_setup_modes()
1347 memcpy(&info->fix, &dlfb_fix, sizeof(dlfb_fix)); in dlfb_setup_modes()
1348 info->fix.line_length = info->var.xres * in dlfb_setup_modes()
1349 (info->var.bits_per_pixel / 8); in dlfb_setup_modes()
1354 result = -EINVAL; in dlfb_setup_modes()
1357 if (edid && (dev->edid != edid)) in dlfb_setup_modes()
1360 if (info->dev) in dlfb_setup_modes()
1361 mutex_unlock(&info->lock); in dlfb_setup_modes()
1369 struct dlfb_data *dev = fb_info->par; in metrics_bytes_rendered_show()
1371 atomic_read(&dev->bytes_rendered)); in metrics_bytes_rendered_show()
1377 struct dlfb_data *dev = fb_info->par; in metrics_bytes_identical_show()
1379 atomic_read(&dev->bytes_identical)); in metrics_bytes_identical_show()
1385 struct dlfb_data *dev = fb_info->par; in metrics_bytes_sent_show()
1387 atomic_read(&dev->bytes_sent)); in metrics_bytes_sent_show()
1393 struct dlfb_data *dev = fb_info->par; in metrics_cpu_kcycles_used_show()
1395 atomic_read(&dev->cpu_kcycles_used)); in metrics_cpu_kcycles_used_show()
1404 struct dlfb_data *dev = fb_info->par; in edid_show()
1406 if (dev->edid == NULL) in edid_show()
1409 if ((off >= dev->edid_size) || (count > dev->edid_size)) in edid_show()
1412 if (off + count > dev->edid_size) in edid_show()
1413 count = dev->edid_size - off; in edid_show()
1416 dev->edid, buf, (int) count); in edid_show()
1418 memcpy(buf, dev->edid, count); in edid_show()
1429 struct dlfb_data *dev = fb_info->par; in edid_store()
1437 if (dev->edid && (memcmp(src, dev->edid, src_size) == 0)) { in edid_store()
1450 struct dlfb_data *dev = fb_info->par; in metrics_reset_store()
1452 atomic_set(&dev->bytes_rendered, 0); in metrics_reset_store()
1453 atomic_set(&dev->bytes_identical, 0); in metrics_reset_store()
1454 atomic_set(&dev->bytes_sent, 0); in metrics_reset_store()
1455 atomic_set(&dev->cpu_kcycles_used, 0); in metrics_reset_store()
1487 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), in dlfb_select_std_channel()
1514 if (0 == usb_get_extra_descriptor(interface->cur_altsetting, in dlfb_parse_vendor_descriptor()
1530 (desc[4] != total_len - 2)) /* length after type */ in dlfb_parse_vendor_descriptor()
1551 dev->sku_pixel_limit = max_area; in dlfb_parse_vendor_descriptor()
1579 int retval = -ENOMEM; in dlfb_usb_probe()
1593 kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */ in dlfb_usb_probe()
1594 kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */ in dlfb_usb_probe()
1596 dev->udev = usbdev; in dlfb_usb_probe()
1597 dev->gdev = &usbdev->dev; /* our generic struct device * */ in dlfb_usb_probe()
1600 pr_info("%s %s - serial #%s\n", in dlfb_usb_probe()
1601 usbdev->manufacturer, usbdev->product, usbdev->serial); in dlfb_usb_probe()
1603 usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, in dlfb_usb_probe()
1604 usbdev->descriptor.bcdDevice, dev); in dlfb_usb_probe()
1609 dev->sku_pixel_limit = 2048 * 1152; /* default to maximum */ in dlfb_usb_probe()
1617 retval = -ENOMEM; in dlfb_usb_probe()
1625 info = framebuffer_alloc(0, &interface->dev); in dlfb_usb_probe()
1627 retval = -ENOMEM; in dlfb_usb_probe()
1632 dev->info = info; in dlfb_usb_probe()
1633 info->par = dev; in dlfb_usb_probe()
1634 info->pseudo_palette = dev->pseudo_palette; in dlfb_usb_probe()
1635 info->fbops = &dlfb_ops; in dlfb_usb_probe()
1637 retval = fb_alloc_cmap(&info->cmap, 256, 0); in dlfb_usb_probe()
1643 INIT_DELAYED_WORK(&dev->free_framebuffer_work, in dlfb_usb_probe()
1646 INIT_LIST_HEAD(&info->modelist); in dlfb_usb_probe()
1656 atomic_set(&dev->usb_active, 1); in dlfb_usb_probe()
1659 dlfb_ops_check_var(&info->var, info); in dlfb_usb_probe()
1669 retval = device_create_file(info->dev, &fb_device_attrs[i]); in dlfb_usb_probe()
1676 retval = device_create_bin_file(info->dev, &edid_attr); in dlfb_usb_probe()
1683 " Using %dK framebuffer memory\n", info->node, in dlfb_usb_probe()
1684 info->var.xres, info->var.yres, in dlfb_usb_probe()
1685 ((dev->backing_buffer) ? in dlfb_usb_probe()
1686 info->fix.smem_len * 2 : info->fix.smem_len) >> 10); in dlfb_usb_probe()
1690 for (i -= 1; i >= 0; i--) in dlfb_usb_probe()
1691 device_remove_file(info->dev, &fb_device_attrs[i]); in dlfb_usb_probe()
1697 if (info->cmap.len != 0) in dlfb_usb_probe()
1698 fb_dealloc_cmap(&info->cmap); in dlfb_usb_probe()
1699 if (info->monspecs.modedb) in dlfb_usb_probe()
1700 fb_destroy_modedb(info->monspecs.modedb); in dlfb_usb_probe()
1701 if (info->screen_base) in dlfb_usb_probe()
1702 vfree(info->screen_base); in dlfb_usb_probe()
1704 fb_destroy_modelist(&info->modelist); in dlfb_usb_probe()
1709 if (dev->backing_buffer) in dlfb_usb_probe()
1710 vfree(dev->backing_buffer); in dlfb_usb_probe()
1712 kref_put(&dev->kref, dlfb_free); /* ref for framebuffer */ in dlfb_usb_probe()
1713 kref_put(&dev->kref, dlfb_free); /* last ref from kref_init */ in dlfb_usb_probe()
1728 info = dev->info; in dlfb_usb_disconnect()
1733 dev->virtualized = true; in dlfb_usb_disconnect()
1735 /* When non-active we'll update virtual framebuffer, but no new urbs */ in dlfb_usb_disconnect()
1736 atomic_set(&dev->usb_active, 0); in dlfb_usb_disconnect()
1740 device_remove_file(info->dev, &fb_device_attrs[i]); in dlfb_usb_disconnect()
1741 device_remove_bin_file(info->dev, &edid_attr); in dlfb_usb_disconnect()
1746 if (dev->fb_count == 0) in dlfb_usb_disconnect()
1747 schedule_delayed_work(&dev->free_framebuffer_work, 0); in dlfb_usb_disconnect()
1750 kref_put(&dev->kref, dlfb_free); in dlfb_usb_disconnect()
1768 struct urb_node *unode = urb->context; in dlfb_urb_completion()
1769 struct dlfb_data *dev = unode->dev; in dlfb_urb_completion()
1773 if (urb->status) { in dlfb_urb_completion()
1774 if (!(urb->status == -ENOENT || in dlfb_urb_completion()
1775 urb->status == -ECONNRESET || in dlfb_urb_completion()
1776 urb->status == -ESHUTDOWN)) { in dlfb_urb_completion()
1777 pr_err("%s - nonzero write bulk status received: %d\n", in dlfb_urb_completion()
1778 __func__, urb->status); in dlfb_urb_completion()
1779 atomic_set(&dev->lost_pixels, 1); in dlfb_urb_completion()
1783 urb->transfer_buffer_length = dev->urbs.size; /* reset to actual */ in dlfb_urb_completion()
1785 spin_lock_irqsave(&dev->urbs.lock, flags); in dlfb_urb_completion()
1786 list_add_tail(&unode->entry, &dev->urbs.list); in dlfb_urb_completion()
1787 dev->urbs.available++; in dlfb_urb_completion()
1788 spin_unlock_irqrestore(&dev->urbs.lock, flags); in dlfb_urb_completion()
1795 schedule_delayed_work(&unode->release_urb_work, 0); in dlfb_urb_completion()
1797 up(&dev->urbs.limit_sem); in dlfb_urb_completion()
1802 int count = dev->urbs.count; in dlfb_free_urb_list()
1809 pr_notice("Waiting for completes and freeing all render urbs\n"); in dlfb_free_urb_list()
1812 while (count--) { in dlfb_free_urb_list()
1815 ret = down_interruptible(&dev->urbs.limit_sem); in dlfb_free_urb_list()
1819 spin_lock_irqsave(&dev->urbs.lock, flags); in dlfb_free_urb_list()
1821 node = dev->urbs.list.next; /* have reserved one with sem */ in dlfb_free_urb_list()
1824 spin_unlock_irqrestore(&dev->urbs.lock, flags); in dlfb_free_urb_list()
1827 urb = unode->urb; in dlfb_free_urb_list()
1830 usb_free_coherent(urb->dev, dev->urbs.size, in dlfb_free_urb_list()
1831 urb->transfer_buffer, urb->transfer_dma); in dlfb_free_urb_list()
1845 spin_lock_init(&dev->urbs.lock); in dlfb_alloc_urb_list()
1847 dev->urbs.size = size; in dlfb_alloc_urb_list()
1848 INIT_LIST_HEAD(&dev->urbs.list); in dlfb_alloc_urb_list()
1854 unode->dev = dev; in dlfb_alloc_urb_list()
1856 INIT_DELAYED_WORK(&unode->release_urb_work, in dlfb_alloc_urb_list()
1864 unode->urb = urb; in dlfb_alloc_urb_list()
1866 buf = usb_alloc_coherent(dev->udev, MAX_TRANSFER, GFP_KERNEL, in dlfb_alloc_urb_list()
1867 &urb->transfer_dma); in dlfb_alloc_urb_list()
1874 /* urb->transfer_buffer_length set to actual before submit */ in dlfb_alloc_urb_list()
1875 usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 1), in dlfb_alloc_urb_list()
1877 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; in dlfb_alloc_urb_list()
1879 list_add_tail(&unode->entry, &dev->urbs.list); in dlfb_alloc_urb_list()
1884 sema_init(&dev->urbs.limit_sem, i); in dlfb_alloc_urb_list()
1885 dev->urbs.count = i; in dlfb_alloc_urb_list()
1886 dev->urbs.available = i; in dlfb_alloc_urb_list()
1901 /* Wait for an in-flight buffer to complete and get re-queued */ in dlfb_get_urb()
1902 ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT); in dlfb_get_urb()
1904 atomic_set(&dev->lost_pixels, 1); in dlfb_get_urb()
1906 ret, dev->urbs.available); in dlfb_get_urb()
1910 spin_lock_irqsave(&dev->urbs.lock, flags); in dlfb_get_urb()
1912 BUG_ON(list_empty(&dev->urbs.list)); /* reserved one with limit_sem */ in dlfb_get_urb()
1913 entry = dev->urbs.list.next; in dlfb_get_urb()
1915 dev->urbs.available--; in dlfb_get_urb()
1917 spin_unlock_irqrestore(&dev->urbs.lock, flags); in dlfb_get_urb()
1920 urb = unode->urb; in dlfb_get_urb()
1930 BUG_ON(len > dev->urbs.size); in dlfb_submit_urb()
1932 urb->transfer_buffer_length = len; /* set to actual payload len */ in dlfb_submit_urb()
1936 atomic_set(&dev->lost_pixels, 1); in dlfb_submit_urb()