diff options
author | Orczykowski, Juergen <juergen.orczykowski@siemens.com> | 2007-05-08 03:37:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:26 -0400 |
commit | 71c6efd9930bd87249d007120425341d1293303d (patch) | |
tree | 43cdb8c00526f16ca5e2cbb99012277fbb1fe116 /drivers/video | |
parent | 33a9f640a2511155517d316e696654b84dd48654 (diff) |
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>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/intelfb/intelfbhw.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index c1eb18bf0883..16bc8d75e36e 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c | |||
@@ -1428,6 +1428,24 @@ static void refresh_ring(struct intelfb_info *dinfo); | |||
1428 | static void reset_state(struct intelfb_info *dinfo); | 1428 | static void reset_state(struct intelfb_info *dinfo); |
1429 | static void do_flush(struct intelfb_info *dinfo); | 1429 | static void do_flush(struct intelfb_info *dinfo); |
1430 | 1430 | ||
1431 | static u32 get_ring_space(struct intelfb_info *dinfo) | ||
1432 | { | ||
1433 | u32 ring_space; | ||
1434 | |||
1435 | if (dinfo->ring_tail >= dinfo->ring_head) | ||
1436 | ring_space = dinfo->ring.size - | ||
1437 | (dinfo->ring_tail - dinfo->ring_head); | ||
1438 | else | ||
1439 | ring_space = dinfo->ring_head - dinfo->ring_tail; | ||
1440 | |||
1441 | if (ring_space > RING_MIN_FREE) | ||
1442 | ring_space -= RING_MIN_FREE; | ||
1443 | else | ||
1444 | ring_space = 0; | ||
1445 | |||
1446 | return ring_space; | ||
1447 | } | ||
1448 | |||
1431 | static int | 1449 | static int |
1432 | wait_ring(struct intelfb_info *dinfo, int n) | 1450 | wait_ring(struct intelfb_info *dinfo, int n) |
1433 | { | 1451 | { |
@@ -1442,13 +1460,8 @@ wait_ring(struct intelfb_info *dinfo, int n) | |||
1442 | end = jiffies + (HZ * 3); | 1460 | end = jiffies + (HZ * 3); |
1443 | while (dinfo->ring_space < n) { | 1461 | while (dinfo->ring_space < n) { |
1444 | dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; | 1462 | dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; |
1445 | if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head) | 1463 | dinfo->ring_space = get_ring_space(dinfo); |
1446 | dinfo->ring_space = dinfo->ring_head | 1464 | |
1447 | - (dinfo->ring_tail + RING_MIN_FREE); | ||
1448 | else | ||
1449 | dinfo->ring_space = (dinfo->ring.size + | ||
1450 | dinfo->ring_head) | ||
1451 | - (dinfo->ring_tail + RING_MIN_FREE); | ||
1452 | if (dinfo->ring_head != last_head) { | 1465 | if (dinfo->ring_head != last_head) { |
1453 | end = jiffies + (HZ * 3); | 1466 | end = jiffies + (HZ * 3); |
1454 | last_head = dinfo->ring_head; | 1467 | last_head = dinfo->ring_head; |
@@ -1513,12 +1526,7 @@ refresh_ring(struct intelfb_info *dinfo) | |||
1513 | 1526 | ||
1514 | dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; | 1527 | dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; |
1515 | dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; | 1528 | dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; |
1516 | if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head) | 1529 | dinfo->ring_space = get_ring_space(dinfo); |
1517 | dinfo->ring_space = dinfo->ring_head | ||
1518 | - (dinfo->ring_tail + RING_MIN_FREE); | ||
1519 | else | ||
1520 | dinfo->ring_space = (dinfo->ring.size + dinfo->ring_head) | ||
1521 | - (dinfo->ring_tail + RING_MIN_FREE); | ||
1522 | } | 1530 | } |
1523 | 1531 | ||
1524 | static void | 1532 | static void |