intelfb: fix ring space calculation
If there is less than RING_MIN_FREE available in the ring buffer, dinfo->ring_space is set to a big value forcing wait_ring to return. Fix by making ring space = 0 if ring space < RING_MIN_FREE. Signed-off-by: Dave Airlie <airlied@gmail.com> Signed-off-by: Antonino Daplas <adaplas@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
33a9f640a2
Коммит
71c6efd993
|
@ -1428,6 +1428,24 @@ static void refresh_ring(struct intelfb_info *dinfo);
|
||||||
static void reset_state(struct intelfb_info *dinfo);
|
static void reset_state(struct intelfb_info *dinfo);
|
||||||
static void do_flush(struct intelfb_info *dinfo);
|
static void do_flush(struct intelfb_info *dinfo);
|
||||||
|
|
||||||
|
static u32 get_ring_space(struct intelfb_info *dinfo)
|
||||||
|
{
|
||||||
|
u32 ring_space;
|
||||||
|
|
||||||
|
if (dinfo->ring_tail >= dinfo->ring_head)
|
||||||
|
ring_space = dinfo->ring.size -
|
||||||
|
(dinfo->ring_tail - dinfo->ring_head);
|
||||||
|
else
|
||||||
|
ring_space = dinfo->ring_head - dinfo->ring_tail;
|
||||||
|
|
||||||
|
if (ring_space > RING_MIN_FREE)
|
||||||
|
ring_space -= RING_MIN_FREE;
|
||||||
|
else
|
||||||
|
ring_space = 0;
|
||||||
|
|
||||||
|
return ring_space;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wait_ring(struct intelfb_info *dinfo, int n)
|
wait_ring(struct intelfb_info *dinfo, int n)
|
||||||
{
|
{
|
||||||
|
@ -1442,13 +1460,8 @@ wait_ring(struct intelfb_info *dinfo, int n)
|
||||||
end = jiffies + (HZ * 3);
|
end = jiffies + (HZ * 3);
|
||||||
while (dinfo->ring_space < n) {
|
while (dinfo->ring_space < n) {
|
||||||
dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
|
dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
|
||||||
if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head)
|
dinfo->ring_space = get_ring_space(dinfo);
|
||||||
dinfo->ring_space = dinfo->ring_head
|
|
||||||
- (dinfo->ring_tail + RING_MIN_FREE);
|
|
||||||
else
|
|
||||||
dinfo->ring_space = (dinfo->ring.size +
|
|
||||||
dinfo->ring_head)
|
|
||||||
- (dinfo->ring_tail + RING_MIN_FREE);
|
|
||||||
if (dinfo->ring_head != last_head) {
|
if (dinfo->ring_head != last_head) {
|
||||||
end = jiffies + (HZ * 3);
|
end = jiffies + (HZ * 3);
|
||||||
last_head = dinfo->ring_head;
|
last_head = dinfo->ring_head;
|
||||||
|
@ -1513,12 +1526,7 @@ refresh_ring(struct intelfb_info *dinfo)
|
||||||
|
|
||||||
dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
|
dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
|
||||||
dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK;
|
dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK;
|
||||||
if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head)
|
dinfo->ring_space = get_ring_space(dinfo);
|
||||||
dinfo->ring_space = dinfo->ring_head
|
|
||||||
- (dinfo->ring_tail + RING_MIN_FREE);
|
|
||||||
else
|
|
||||||
dinfo->ring_space = (dinfo->ring.size + dinfo->ring_head)
|
|
||||||
- (dinfo->ring_tail + RING_MIN_FREE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Загрузка…
Ссылка в новой задаче