Lines Matching +full:render +full:- +full:max

2  * smscufx.c -- Framebuffer driver for SMSC UFX USB controller
16 * Works well with Bernie Thompson's X DAMAGE patch to xf86-video-fbdev
20 * usb-skeleton by GregKH.
55 * DisplayLink X server as yet - need both to be modified in tandem
61 /* -BULK_SIZE as per usb-skeleton. Can we get full page and avoid overhead? */
63 #define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE)
97 struct device *gdev; /* &udev->dev */
105 atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
152 return -ENOMEM; in ufx_reg_read()
154 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), in ufx_reg_read()
178 return -ENOMEM; in ufx_reg_write()
183 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), in ufx_reg_write()
236 return (value == 0) ? 0 : -EIO; in ufx_lite_reset()
273 return -EIO; in ufx_blank()
310 return -EIO; in ufx_unblank()
347 return -EIO; in ufx_disable()
384 return -EIO; in ufx_enable()
494 return -ETIMEDOUT; in ufx_config_ddr2()
581 int error = abs(pllout_freq1 - clk_pixel_pll); in ufx_calc_pll_values()
592 /* final returned value is equal to calculated value - 1 in ufx_calc_pll_values()
594 asic_pll->div_r0 = div_r0 - 1; in ufx_calc_pll_values()
595 asic_pll->div_f0 = div_f0 - 1; in ufx_calc_pll_values()
596 asic_pll->div_q0 = div_q0; in ufx_calc_pll_values()
597 asic_pll->div_r1 = div_r1 - 1; in ufx_calc_pll_values()
598 asic_pll->div_f1 = div_f1 - 1; in ufx_calc_pll_values()
599 asic_pll->div_q1 = div_q1; in ufx_calc_pll_values()
601 asic_pll->range0 = ufx_calc_range(ref_freq0); in ufx_calc_pll_values()
602 asic_pll->range1 = ufx_calc_range(ref_freq1); in ufx_calc_pll_values()
680 status = ufx_config_pix_clk(dev, var->pixclock); in ufx_set_vid_mode()
687 h_total = var->xres + var->right_margin + var->hsync_len + var->left_margin; in ufx_set_vid_mode()
688 h_active = var->xres; in ufx_set_vid_mode()
689 h_blank_start = var->xres + var->right_margin; in ufx_set_vid_mode()
690 h_blank_end = var->xres + var->right_margin + var->hsync_len; in ufx_set_vid_mode()
691 h_sync_start = var->xres + var->right_margin; in ufx_set_vid_mode()
692 h_sync_end = var->xres + var->right_margin + var->hsync_len; in ufx_set_vid_mode()
694 temp = ((h_total - 1) << 16) | (h_active - 1); in ufx_set_vid_mode()
698 temp = ((h_blank_start - 1) << 16) | (h_blank_end - 1); in ufx_set_vid_mode()
702 temp = ((h_sync_start - 1) << 16) | (h_sync_end - 1); in ufx_set_vid_mode()
707 v_total = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; in ufx_set_vid_mode()
708 v_active = var->yres; in ufx_set_vid_mode()
709 v_blank_start = var->yres + var->lower_margin; in ufx_set_vid_mode()
710 v_blank_end = var->yres + var->lower_margin + var->vsync_len; in ufx_set_vid_mode()
711 v_sync_start = var->yres + var->lower_margin; in ufx_set_vid_mode()
712 v_sync_end = var->yres + var->lower_margin + var->vsync_len; in ufx_set_vid_mode()
714 temp = ((v_total - 1) << 16) | (v_active - 1); in ufx_set_vid_mode()
718 temp = ((v_blank_start - 1) << 16) | (v_blank_end - 1); in ufx_set_vid_mode()
722 temp = ((v_sync_start - 1) << 16) | (v_sync_end - 1); in ufx_set_vid_mode()
733 temp = var->xres * var->yres * 2; in ufx_set_vid_mode()
750 if (var->sync & FB_SYNC_HOR_HIGH_ACT) in ufx_set_vid_mode()
753 if (var->sync & FB_SYNC_VERT_HIGH_ACT) in ufx_set_vid_mode()
780 unsigned long start = vma->vm_start; in ufx_ops_mmap()
781 unsigned long size = vma->vm_end - vma->vm_start; in ufx_ops_mmap()
782 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; in ufx_ops_mmap()
785 if (offset + size > info->fix.smem_len) in ufx_ops_mmap()
786 return -EINVAL; in ufx_ops_mmap()
788 pos = (unsigned long)info->fix.smem_start + offset; in ufx_ops_mmap()
796 return -EAGAIN; in ufx_ops_mmap()
801 size -= PAGE_SIZE; in ufx_ops_mmap()
806 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ in ufx_ops_mmap()
818 BUG_ON(!dev->info); in ufx_raw_rect()
835 cmd[10] = cpu_to_le16(0x4000 | dev->info->var.xres); in ufx_raw_rect()
838 cmd[11] = cpu_to_le16(dev->info->var.yres); in ufx_raw_rect()
842 const int line_offset = dev->info->fix.line_length * (y + line); in ufx_raw_rect()
845 (char *)dev->info->fix.smem_start + byte_offset, width * BPP); in ufx_raw_rect()
856 (x + width > dev->info->var.xres) || in ufx_handle_damage()
857 (y + height > dev->info->var.yres)) in ufx_handle_damage()
858 return -EINVAL; in ufx_handle_damage()
860 if (!atomic_read(&dev->usb_active)) in ufx_handle_damage()
871 BUG_ON(urb->transfer_buffer_length < (24 + (width * 2))); in ufx_handle_damage()
874 urb_lines = (urb->transfer_buffer_length - 24) / packed_line_len; in ufx_handle_damage()
877 urb_lines = min(urb_lines, (height - start_line)); in ufx_handle_damage()
879 memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); in ufx_handle_damage()
881 ufx_raw_rect(dev, urb->transfer_buffer, x, (y + start_line), width, urb_lines); in ufx_handle_damage()
895 * Not used by X Windows or text-mode console. But useful for testing.
901 struct ufx_data *dev = info->par; in ufx_ops_write()
907 int start = max((int)(offset / info->fix.line_length) - 1, 0); in ufx_ops_write()
908 int lines = min((u32)((result / info->fix.line_length) + 1), in ufx_ops_write()
909 (u32)info->var.yres); in ufx_ops_write()
911 ufx_handle_damage(dev, 0, start, info->var.xres, lines); in ufx_ops_write()
921 struct ufx_data *dev = info->par; in ufx_ops_copyarea()
925 ufx_handle_damage(dev, area->dx, area->dy, in ufx_ops_copyarea()
926 area->width, area->height); in ufx_ops_copyarea()
932 struct ufx_data *dev = info->par; in ufx_ops_imageblit()
936 ufx_handle_damage(dev, image->dx, image->dy, in ufx_ops_imageblit()
937 image->width, image->height); in ufx_ops_imageblit()
943 struct ufx_data *dev = info->par; in ufx_ops_fillrect()
947 ufx_handle_damage(dev, rect->dx, rect->dy, rect->width, in ufx_ops_fillrect()
948 rect->height); in ufx_ops_fillrect()
951 /* NOTE: fb_defio.c is holding info->fbdefio.mutex
959 struct fb_deferred_io *fbdefio = info->fbdefio; in ufx_dpy_deferred_io()
960 struct ufx_data *dev = info->par; in ufx_dpy_deferred_io()
965 if (!atomic_read(&dev->usb_active)) in ufx_dpy_deferred_io()
968 /* walk the written page list and render each to device */ in ufx_dpy_deferred_io()
969 list_for_each_entry(cur, &fbdefio->pagelist, lru) { in ufx_dpy_deferred_io()
973 const int width = dev->info->var.xres; in ufx_dpy_deferred_io()
974 const int y = (cur->index << PAGE_SHIFT) / (width * 2); in ufx_dpy_deferred_io()
976 height = min(height, (int)(dev->info->var.yres - y)); in ufx_dpy_deferred_io()
978 BUG_ON(y >= dev->info->var.yres); in ufx_dpy_deferred_io()
979 BUG_ON((y + height) > dev->info->var.yres); in ufx_dpy_deferred_io()
988 struct ufx_data *dev = info->par; in ufx_ops_ioctl()
991 if (!atomic_read(&dev->usb_active)) in ufx_ops_ioctl()
997 if (copy_to_user(edid, dev->edid, dev->edid_size)) in ufx_ops_ioctl()
998 return -EFAULT; in ufx_ops_ioctl()
1004 /* If we have a damage-aware client, turn fb_defio "off" in ufx_ops_ioctl()
1010 if (info->fbdefio) in ufx_ops_ioctl()
1011 info->fbdefio->delay = UFX_DEFIO_WRITE_DISABLE; in ufx_ops_ioctl()
1015 if (area->x < 0) in ufx_ops_ioctl()
1016 area->x = 0; in ufx_ops_ioctl()
1018 if (area->x > info->var.xres) in ufx_ops_ioctl()
1019 area->x = info->var.xres; in ufx_ops_ioctl()
1021 if (area->y < 0) in ufx_ops_ioctl()
1022 area->y = 0; in ufx_ops_ioctl()
1024 if (area->y > info->var.yres) in ufx_ops_ioctl()
1025 area->y = info->var.yres; in ufx_ops_ioctl()
1027 ufx_handle_damage(dev, area->x, area->y, area->w, area->h); in ufx_ops_ioctl()
1040 if (regno >= info->cmap.len) in ufx_ops_setcolreg()
1044 if (info->var.red.offset == 10) { in ufx_ops_setcolreg()
1046 ((u32 *) (info->pseudo_palette))[regno] = in ufx_ops_setcolreg()
1051 ((u32 *) (info->pseudo_palette))[regno] = in ufx_ops_setcolreg()
1062 * Assumes caller is holding info->lock (for open and release at least) */
1065 struct ufx_data *dev = info->par; in ufx_ops_open()
1071 return -EBUSY; in ufx_ops_open()
1074 if (dev->virtualized) in ufx_ops_open()
1075 return -ENODEV; in ufx_ops_open()
1077 dev->fb_count++; in ufx_ops_open()
1079 kref_get(&dev->kref); in ufx_ops_open()
1081 if (fb_defio && (info->fbdefio == NULL)) { in ufx_ops_open()
1089 fbdefio->delay = UFX_DEFIO_WRITE_DELAY; in ufx_ops_open()
1090 fbdefio->deferred_io = ufx_dpy_deferred_io; in ufx_ops_open()
1093 info->fbdefio = fbdefio; in ufx_ops_open()
1098 info->node, user, info, dev->fb_count); in ufx_ops_open()
1112 /* this function will wait for all in-flight urbs to complete */ in ufx_free()
1113 if (dev->urbs.count > 0) in ufx_free()
1126 up(&unode->dev->urbs.limit_sem); in ufx_release_urb_work()
1133 struct fb_info *info = dev->info; in ufx_free_framebuffer_work()
1134 int node = info->node; in ufx_free_framebuffer_work()
1138 if (info->cmap.len != 0) in ufx_free_framebuffer_work()
1139 fb_dealloc_cmap(&info->cmap); in ufx_free_framebuffer_work()
1140 if (info->monspecs.modedb) in ufx_free_framebuffer_work()
1141 fb_destroy_modedb(info->monspecs.modedb); in ufx_free_framebuffer_work()
1142 if (info->screen_base) in ufx_free_framebuffer_work()
1143 vfree(info->screen_base); in ufx_free_framebuffer_work()
1145 fb_destroy_modelist(&info->modelist); in ufx_free_framebuffer_work()
1147 dev->info = 0; in ufx_free_framebuffer_work()
1155 kref_put(&dev->kref, ufx_free); in ufx_free_framebuffer_work()
1159 * Assumes caller is holding info->lock mutex (for open and release at least)
1163 struct ufx_data *dev = info->par; in ufx_ops_release()
1165 dev->fb_count--; in ufx_ops_release()
1167 /* We can't free fb_info here - fbmem will touch it when we return */ in ufx_ops_release()
1168 if (dev->virtualized && (dev->fb_count == 0)) in ufx_ops_release()
1169 schedule_delayed_work(&dev->free_framebuffer_work, HZ); in ufx_ops_release()
1171 if ((dev->fb_count == 0) && (info->fbdefio)) { in ufx_ops_release()
1173 kfree(info->fbdefio); in ufx_ops_release()
1174 info->fbdefio = NULL; in ufx_ops_release()
1175 info->fbops->fb_mmap = ufx_ops_mmap; in ufx_ops_release()
1179 info->node, user, dev->fb_count); in ufx_ops_release()
1181 kref_put(&dev->kref, ufx_free); in ufx_ops_release()
1191 if ((mode->xres * mode->yres) > (2048 * 1152)) { in ufx_is_valid_mode()
1193 mode->xres, mode->yres); in ufx_is_valid_mode()
1197 if (mode->pixclock < 5000) { in ufx_is_valid_mode()
1199 mode->xres, mode->yres, mode->pixclock); in ufx_is_valid_mode()
1203 pr_debug("%dx%d (pixclk %dps %dMHz) valid mode", mode->xres, mode->yres, in ufx_is_valid_mode()
1204 mode->pixclock, (1000000 / mode->pixclock)); in ufx_is_valid_mode()
1214 var->bits_per_pixel = 16; in ufx_var_color_format()
1215 var->red = red; in ufx_var_color_format()
1216 var->green = green; in ufx_var_color_format()
1217 var->blue = blue; in ufx_var_color_format()
1226 if ((var->xres * var->yres * 2) > info->fix.smem_len) in ufx_ops_check_var()
1227 return -EINVAL; in ufx_ops_check_var()
1229 /* set device-specific elements of var unrelated to mode */ in ufx_ops_check_var()
1235 return -EINVAL; in ufx_ops_check_var()
1242 struct ufx_data *dev = info->par; in ufx_ops_set_par()
1247 pr_debug("set_par mode %dx%d", info->var.xres, info->var.yres); in ufx_ops_set_par()
1248 result = ufx_set_vid_mode(dev, &info->var); in ufx_ops_set_par()
1250 if ((result == 0) && (dev->fb_count == 0)) { in ufx_ops_set_par()
1252 pix_framebuffer = (u16 *) info->screen_base; in ufx_ops_set_par()
1253 for (i = 0; i < info->fix.smem_len / 2; i++) in ufx_ops_set_par()
1256 ufx_handle_damage(dev, 0, 0, info->var.xres, info->var.yres); in ufx_ops_set_par()
1259 /* re-enable defio if previously disabled by damage tracking */ in ufx_ops_set_par()
1260 if (info->fbdefio) in ufx_ops_set_par()
1261 info->fbdefio->delay = UFX_DEFIO_WRITE_DELAY; in ufx_ops_set_par()
1269 struct ufx_data *dev = info->par; in ufx_ops_blank()
1270 ufx_set_vid_mode(dev, &info->var); in ufx_ops_blank()
1291 /* Assumes &info->lock held by caller
1295 int retval = -ENOMEM; in ufx_realloc_framebuffer()
1296 int old_len = info->fix.smem_len; in ufx_realloc_framebuffer()
1298 unsigned char *old_fb = info->screen_base; in ufx_realloc_framebuffer()
1303 new_len = info->fix.line_length * info->var.yres; in ufx_realloc_framebuffer()
1315 if (info->screen_base) { in ufx_realloc_framebuffer()
1317 vfree(info->screen_base); in ufx_realloc_framebuffer()
1320 info->screen_base = new_fb; in ufx_realloc_framebuffer()
1321 info->fix.smem_len = PAGE_ALIGN(new_len); in ufx_realloc_framebuffer()
1322 info->fix.smem_start = (unsigned long) new_fb; in ufx_realloc_framebuffer()
1323 info->flags = smscufx_info_flags; in ufx_realloc_framebuffer()
1332 /* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, master,
1358 /* 7-bit (not 10-bit) addressing */ in ufx_i2c_init()
1412 return -EIO; in ufx_i2c_wait_busy()
1427 return -ETIMEDOUT; in ufx_i2c_wait_busy()
1430 /* reads a 128-byte EDID block from the currently selected port and TAR */
1446 /* Read the 128-byte EDID as 2 bursts of 64 bytes */ in ufx_read_edid()
1475 return -ETIMEDOUT; in ufx_read_edid()
1497 if (info->dev) /* only use mutex if info has been registered */ in ufx_setup_modes()
1498 mutex_lock(&info->lock); in ufx_setup_modes()
1502 result = -ENOMEM; in ufx_setup_modes()
1506 fb_destroy_modelist(&info->modelist); in ufx_setup_modes()
1507 memset(&info->monspecs, 0, sizeof(info->monspecs)); in ufx_setup_modes()
1512 while (tries--) { in ufx_setup_modes()
1516 fb_edid_to_monspecs(edid, &info->monspecs); in ufx_setup_modes()
1518 if (info->monspecs.modedb_len > 0) { in ufx_setup_modes()
1519 dev->edid = edid; in ufx_setup_modes()
1520 dev->edid_size = i; in ufx_setup_modes()
1526 if (info->monspecs.modedb_len == 0) { in ufx_setup_modes()
1529 if (dev->edid) { in ufx_setup_modes()
1530 fb_edid_to_monspecs(dev->edid, &info->monspecs); in ufx_setup_modes()
1531 if (info->monspecs.modedb_len > 0) in ufx_setup_modes()
1537 if (info->monspecs.modedb_len == 0) { in ufx_setup_modes()
1539 fb_edid_to_monspecs(default_edid, &info->monspecs); in ufx_setup_modes()
1540 if (info->monspecs.modedb_len > 0) { in ufx_setup_modes()
1542 dev->edid = edid; in ufx_setup_modes()
1543 dev->edid_size = default_edid_size; in ufx_setup_modes()
1550 if (info->monspecs.modedb_len > 0) { in ufx_setup_modes()
1552 for (i = 0; i < info->monspecs.modedb_len; i++) { in ufx_setup_modes()
1553 if (ufx_is_valid_mode(&info->monspecs.modedb[i], info)) in ufx_setup_modes()
1554 fb_add_videomode(&info->monspecs.modedb[i], in ufx_setup_modes()
1555 &info->modelist); in ufx_setup_modes()
1557 info->monspecs.misc &= ~FB_MISC_1ST_DETAIL; in ufx_setup_modes()
1560 default_vmode = fb_find_best_display(&info->monspecs, in ufx_setup_modes()
1561 &info->modelist); in ufx_setup_modes()
1578 &info->modelist); in ufx_setup_modes()
1588 &info->modelist); in ufx_setup_modes()
1592 if ((default_vmode != NULL) && (dev->fb_count == 0)) { in ufx_setup_modes()
1594 fb_videomode_to_var(&info->var, default_vmode); in ufx_setup_modes()
1595 ufx_var_color_format(&info->var); in ufx_setup_modes()
1598 memcpy(&info->fix, &ufx_fix, sizeof(ufx_fix)); in ufx_setup_modes()
1599 info->fix.line_length = info->var.xres * in ufx_setup_modes()
1600 (info->var.bits_per_pixel / 8); in ufx_setup_modes()
1605 result = -EINVAL; in ufx_setup_modes()
1608 if (edid && (dev->edid != edid)) in ufx_setup_modes()
1611 if (info->dev) in ufx_setup_modes()
1612 mutex_unlock(&info->lock); in ufx_setup_modes()
1623 int retval = -ENOMEM; in ufx_usb_probe()
1632 dev_err(&usbdev->dev, "ufx_usb_probe: failed alloc of dev struct\n"); in ufx_usb_probe()
1637 kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */ in ufx_usb_probe()
1638 kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */ in ufx_usb_probe()
1640 dev->udev = usbdev; in ufx_usb_probe()
1641 dev->gdev = &usbdev->dev; /* our generic struct device * */ in ufx_usb_probe()
1644 dev_dbg(dev->gdev, "%s %s - serial #%s\n", in ufx_usb_probe()
1645 usbdev->manufacturer, usbdev->product, usbdev->serial); in ufx_usb_probe()
1646 dev_dbg(dev->gdev, "vid_%04x&pid_%04x&rev_%04x driver's ufx_data struct at %p\n", in ufx_usb_probe()
1647 usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, in ufx_usb_probe()
1648 usbdev->descriptor.bcdDevice, dev); in ufx_usb_probe()
1649 dev_dbg(dev->gdev, "console enable=%d\n", console); in ufx_usb_probe()
1650 dev_dbg(dev->gdev, "fb_defio enable=%d\n", fb_defio); in ufx_usb_probe()
1653 retval = -ENOMEM; in ufx_usb_probe()
1654 dev_err(dev->gdev, "ufx_alloc_urb_list failed\n"); in ufx_usb_probe()
1661 info = framebuffer_alloc(0, &usbdev->dev); in ufx_usb_probe()
1663 retval = -ENOMEM; in ufx_usb_probe()
1664 dev_err(dev->gdev, "framebuffer_alloc failed\n"); in ufx_usb_probe()
1668 dev->info = info; in ufx_usb_probe()
1669 info->par = dev; in ufx_usb_probe()
1670 info->pseudo_palette = dev->pseudo_palette; in ufx_usb_probe()
1671 info->fbops = &ufx_ops; in ufx_usb_probe()
1673 retval = fb_alloc_cmap(&info->cmap, 256, 0); in ufx_usb_probe()
1675 dev_err(dev->gdev, "fb_alloc_cmap failed %x\n", retval); in ufx_usb_probe()
1679 INIT_DELAYED_WORK(&dev->free_framebuffer_work, in ufx_usb_probe()
1682 INIT_LIST_HEAD(&info->modelist); in ufx_usb_probe()
1686 dev_dbg(dev->gdev, "ID_REV register value 0x%08x", id_rev); in ufx_usb_probe()
1690 dev_dbg(dev->gdev, "FPGA_REV register value 0x%08x", fpga_rev); in ufx_usb_probe()
1692 dev_dbg(dev->gdev, "resetting device"); in ufx_usb_probe()
1696 dev_dbg(dev->gdev, "configuring system clock"); in ufx_usb_probe()
1700 dev_dbg(dev->gdev, "configuring DDR2 controller"); in ufx_usb_probe()
1704 dev_dbg(dev->gdev, "configuring I2C controller"); in ufx_usb_probe()
1708 dev_dbg(dev->gdev, "selecting display mode"); in ufx_usb_probe()
1716 atomic_set(&dev->usb_active, 1); in ufx_usb_probe()
1718 dev_dbg(dev->gdev, "checking var"); in ufx_usb_probe()
1719 retval = ufx_ops_check_var(&info->var, info); in ufx_usb_probe()
1722 dev_dbg(dev->gdev, "setting par"); in ufx_usb_probe()
1726 dev_dbg(dev->gdev, "registering framebuffer"); in ufx_usb_probe()
1730 dev_info(dev->gdev, "SMSC UDX USB device /dev/fb%d attached. %dx%d resolution." in ufx_usb_probe()
1731 " Using %dK framebuffer memory\n", info->node, in ufx_usb_probe()
1732 info->var.xres, info->var.yres, info->fix.smem_len >> 10); in ufx_usb_probe()
1739 if (info->cmap.len != 0) in ufx_usb_probe()
1740 fb_dealloc_cmap(&info->cmap); in ufx_usb_probe()
1741 if (info->monspecs.modedb) in ufx_usb_probe()
1742 fb_destroy_modedb(info->monspecs.modedb); in ufx_usb_probe()
1743 if (info->screen_base) in ufx_usb_probe()
1744 vfree(info->screen_base); in ufx_usb_probe()
1746 fb_destroy_modelist(&info->modelist); in ufx_usb_probe()
1751 kref_put(&dev->kref, ufx_free); /* ref for framebuffer */ in ufx_usb_probe()
1752 kref_put(&dev->kref, ufx_free); /* last ref from kref_init */ in ufx_usb_probe()
1766 info = dev->info; in ufx_usb_disconnect()
1771 dev->virtualized = true; in ufx_usb_disconnect()
1773 /* When non-active we'll update virtual framebuffer, but no new urbs */ in ufx_usb_disconnect()
1774 atomic_set(&dev->usb_active, 0); in ufx_usb_disconnect()
1779 if (dev->fb_count == 0) in ufx_usb_disconnect()
1780 schedule_delayed_work(&dev->free_framebuffer_work, 0); in ufx_usb_disconnect()
1783 kref_put(&dev->kref, ufx_free); in ufx_usb_disconnect()
1799 struct urb_node *unode = urb->context; in ufx_urb_completion()
1800 struct ufx_data *dev = unode->dev; in ufx_urb_completion()
1804 if (urb->status) { in ufx_urb_completion()
1805 if (!(urb->status == -ENOENT || in ufx_urb_completion()
1806 urb->status == -ECONNRESET || in ufx_urb_completion()
1807 urb->status == -ESHUTDOWN)) { in ufx_urb_completion()
1808 pr_err("%s - nonzero write bulk status received: %d\n", in ufx_urb_completion()
1809 __func__, urb->status); in ufx_urb_completion()
1810 atomic_set(&dev->lost_pixels, 1); in ufx_urb_completion()
1814 urb->transfer_buffer_length = dev->urbs.size; /* reset to actual */ in ufx_urb_completion()
1816 spin_lock_irqsave(&dev->urbs.lock, flags); in ufx_urb_completion()
1817 list_add_tail(&unode->entry, &dev->urbs.list); in ufx_urb_completion()
1818 dev->urbs.available++; in ufx_urb_completion()
1819 spin_unlock_irqrestore(&dev->urbs.lock, flags); in ufx_urb_completion()
1824 schedule_delayed_work(&unode->release_urb_work, 0); in ufx_urb_completion()
1826 up(&dev->urbs.limit_sem); in ufx_urb_completion()
1831 int count = dev->urbs.count; in ufx_free_urb_list()
1838 pr_debug("Waiting for completes and freeing all render urbs\n"); in ufx_free_urb_list()
1841 while (count--) { in ufx_free_urb_list()
1843 ret = down_interruptible(&dev->urbs.limit_sem); in ufx_free_urb_list()
1847 spin_lock_irqsave(&dev->urbs.lock, flags); in ufx_free_urb_list()
1849 node = dev->urbs.list.next; /* have reserved one with sem */ in ufx_free_urb_list()
1852 spin_unlock_irqrestore(&dev->urbs.lock, flags); in ufx_free_urb_list()
1855 urb = unode->urb; in ufx_free_urb_list()
1858 usb_free_coherent(urb->dev, dev->urbs.size, in ufx_free_urb_list()
1859 urb->transfer_buffer, urb->transfer_dma); in ufx_free_urb_list()
1872 spin_lock_init(&dev->urbs.lock); in ufx_alloc_urb_list()
1874 dev->urbs.size = size; in ufx_alloc_urb_list()
1875 INIT_LIST_HEAD(&dev->urbs.list); in ufx_alloc_urb_list()
1881 unode->dev = dev; in ufx_alloc_urb_list()
1883 INIT_DELAYED_WORK(&unode->release_urb_work, in ufx_alloc_urb_list()
1891 unode->urb = urb; in ufx_alloc_urb_list()
1893 buf = usb_alloc_coherent(dev->udev, size, GFP_KERNEL, in ufx_alloc_urb_list()
1894 &urb->transfer_dma); in ufx_alloc_urb_list()
1901 /* urb->transfer_buffer_length set to actual before submit */ in ufx_alloc_urb_list()
1902 usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 1), in ufx_alloc_urb_list()
1904 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; in ufx_alloc_urb_list()
1906 list_add_tail(&unode->entry, &dev->urbs.list); in ufx_alloc_urb_list()
1911 sema_init(&dev->urbs.limit_sem, i); in ufx_alloc_urb_list()
1912 dev->urbs.count = i; in ufx_alloc_urb_list()
1913 dev->urbs.available = i; in ufx_alloc_urb_list()
1928 /* Wait for an in-flight buffer to complete and get re-queued */ in ufx_get_urb()
1929 ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT); in ufx_get_urb()
1931 atomic_set(&dev->lost_pixels, 1); in ufx_get_urb()
1933 ret, dev->urbs.available); in ufx_get_urb()
1937 spin_lock_irqsave(&dev->urbs.lock, flags); in ufx_get_urb()
1939 BUG_ON(list_empty(&dev->urbs.list)); /* reserved one with limit_sem */ in ufx_get_urb()
1940 entry = dev->urbs.list.next; in ufx_get_urb()
1942 dev->urbs.available--; in ufx_get_urb()
1944 spin_unlock_irqrestore(&dev->urbs.lock, flags); in ufx_get_urb()
1947 urb = unode->urb; in ufx_get_urb()
1957 BUG_ON(len > dev->urbs.size); in ufx_submit_urb()
1959 urb->transfer_buffer_length = len; /* set to actual payload len */ in ufx_submit_urb()
1963 atomic_set(&dev->lost_pixels, 1); in ufx_submit_urb()