summaryrefslogtreecommitdiff
path: root/sys/dev/usb/udl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/udl.c')
-rw-r--r--sys/dev/usb/udl.c309
1 files changed, 225 insertions, 84 deletions
diff --git a/sys/dev/usb/udl.c b/sys/dev/usb/udl.c
index 68646aef9aa..ec55576092e 100644
--- a/sys/dev/usb/udl.c
+++ b/sys/dev/usb/udl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udl.c,v 1.34 2009/09/09 07:01:20 mglocker Exp $ */
+/* $OpenBSD: udl.c,v 1.35 2009/09/11 20:12:51 mglocker Exp $ */
/*
* Copyright (c) 2009 Marcus Glocker <mglocker@openbsd.org>
@@ -110,7 +110,8 @@ void udl_cmd_insert_buf(struct udl_softc *, uint8_t *, uint32_t);
int udl_cmd_insert_buf_comp(struct udl_softc *, uint8_t *,
uint32_t);
int udl_cmd_insert_head_comp(struct udl_softc *, uint32_t);
-void udl_cmd_insert_check(struct udl_cmd_buf *, int);
+int udl_cmd_insert_check(struct udl_softc *, int);
+void udl_cmd_set_xfer(struct udl_softc *, int);
uint32_t udl_cmd_get_offset(struct udl_softc *);
void udl_cmd_set_offset(struct udl_softc *, uint32_t);
void udl_cmd_write_reg_1(struct udl_softc *, uint8_t, uint8_t);
@@ -124,35 +125,35 @@ usbd_status udl_init_chip(struct udl_softc *);
void udl_init_fb_offsets(struct udl_softc *, uint32_t, uint32_t,
uint32_t, uint32_t);
usbd_status udl_init_resolution(struct udl_softc *, uint8_t *, uint8_t);
-void udl_fb_off_write(struct udl_softc *, uint16_t, uint32_t,
+int udl_fb_off_write(struct udl_softc *, uint16_t, uint32_t,
uint16_t);
-void udl_fb_line_write(struct udl_softc *, uint16_t, uint32_t,
+int udl_fb_line_write(struct udl_softc *, uint16_t, uint32_t,
uint32_t, uint32_t);
-void udl_fb_block_write(struct udl_softc *, uint16_t, uint32_t,
+int udl_fb_block_write(struct udl_softc *, uint16_t, uint32_t,
uint32_t, uint32_t, uint32_t);
-void udl_fb_buf_write(struct udl_softc *, uint8_t *, uint32_t,
+int udl_fb_buf_write(struct udl_softc *, uint8_t *, uint32_t,
uint32_t, uint16_t);
-void udl_fb_off_copy(struct udl_softc *, uint32_t, uint32_t,
+int udl_fb_off_copy(struct udl_softc *, uint32_t, uint32_t,
uint16_t);
-void udl_fb_line_copy(struct udl_softc *, uint32_t, uint32_t,
+int udl_fb_line_copy(struct udl_softc *, uint32_t, uint32_t,
uint32_t, uint32_t, uint32_t);
-void udl_fb_block_copy(struct udl_softc *, uint32_t, uint32_t,
+int udl_fb_block_copy(struct udl_softc *, uint32_t, uint32_t,
uint32_t, uint32_t, uint32_t, uint32_t);
-void udl_fb_off_write_comp(struct udl_softc *, uint16_t, uint32_t,
+int udl_fb_off_write_comp(struct udl_softc *, uint16_t, uint32_t,
uint16_t);
-void udl_fb_line_write_comp(struct udl_softc *, uint16_t, uint32_t,
+int udl_fb_line_write_comp(struct udl_softc *, uint16_t, uint32_t,
uint32_t, uint32_t);
-void udl_fb_block_write_comp(struct udl_softc *, uint16_t, uint32_t,
+int udl_fb_block_write_comp(struct udl_softc *, uint16_t, uint32_t,
uint32_t, uint32_t, uint32_t);
-void udl_fb_buf_write_comp(struct udl_softc *, uint8_t *, uint32_t,
+int udl_fb_buf_write_comp(struct udl_softc *, uint8_t *, uint32_t,
uint32_t, uint16_t);
-void udl_fb_off_copy_comp(struct udl_softc *, uint32_t, uint32_t,
+int udl_fb_off_copy_comp(struct udl_softc *, uint32_t, uint32_t,
uint16_t);
-void udl_fb_line_copy_comp(struct udl_softc *, uint32_t, uint32_t,
+int udl_fb_line_copy_comp(struct udl_softc *, uint32_t, uint32_t,
uint32_t, uint32_t, uint32_t);
-void udl_fb_block_copy_comp(struct udl_softc *, uint32_t, uint32_t,
+int udl_fb_block_copy_comp(struct udl_softc *, uint32_t, uint32_t,
uint32_t, uint32_t, uint32_t, uint32_t);
-void udl_draw_char(struct udl_softc *, uint16_t, uint16_t, u_int,
+int udl_draw_char(struct udl_softc *, uint16_t, uint16_t, u_int,
uint32_t, uint32_t);
#ifdef UDL_DEBUG
void udl_hexdump(void *, int, int);
@@ -285,6 +286,11 @@ udl_attach(struct device *parent, struct device *self, void *aux)
return;
/*
+ * Device initialization is done per synchronous xfers.
+ */
+ udl_cmd_set_xfer(sc, UDL_CMD_XFER_SYNC);
+
+ /*
* Initialize chip.
*/
error = udl_init_chip(sc);
@@ -353,6 +359,10 @@ udl_attach_hook(void *arg)
#ifdef UDL_DEBUG
udl_init_test(sc);
#endif
+ /*
+ * From this point on we do asynchronous xfers.
+ */
+ udl_cmd_set_xfer(sc, UDL_CMD_XFER_ASYNC);
}
int
@@ -556,7 +566,7 @@ udl_copycols(void *cookie, int row, int src, int dst, int num)
{
struct rasops_info *ri = cookie;
struct udl_softc *sc;
- int sx, sy, dx, dy, cx, cy;
+ int sx, sy, dx, dy, cx, cy, r;
uint32_t save_offset;
usbd_status error;
@@ -575,13 +585,20 @@ udl_copycols(void *cookie, int row, int src, int dst, int num)
cy = ri->ri_font->fontheight;
/* copy row block to off-screen first to fix overlay-copy problem */
- (sc->udl_fb_block_copy)(sc, sx, sy, 0, sc->sc_ri.ri_emuheight, cx, cy);
+ r = (sc->udl_fb_block_copy)
+ (sc, sx, sy, 0, sc->sc_ri.ri_emuheight, cx, cy);
+ if (r != 0)
+ goto fail;
/* copy row block back from off-screen now */
- (sc->udl_fb_block_copy)(sc, 0, sc->sc_ri.ri_emuheight, dx, dy, cx, cy);
+ r = (sc->udl_fb_block_copy)
+ (sc, 0, sc->sc_ri.ri_emuheight, dx, dy, cx, cy);
+ if (r != 0)
+ goto fail;
error = udl_cmd_send_async(sc);
if (error != USBD_NORMAL_COMPLETION) {
+fail:
udl_cmd_set_offset(sc, save_offset);
return (EAGAIN);
}
@@ -594,7 +611,7 @@ udl_copyrows(void *cookie, int src, int dst, int num)
{
struct rasops_info *ri = cookie;
struct udl_softc *sc;
- int sy, dy, cx, cy;
+ int sy, dy, cx, cy, r;
uint32_t save_offset;
usbd_status error;
@@ -611,13 +628,20 @@ udl_copyrows(void *cookie, int src, int dst, int num)
cy = num * sc->sc_ri.ri_font->fontheight;
/* copy row block to off-screen first to fix overlay-copy problem */
- (sc->udl_fb_block_copy)(sc, 0, sy, 0, sc->sc_ri.ri_emuheight, cx, cy);
+ r = (sc->udl_fb_block_copy)
+ (sc, 0, sy, 0, sc->sc_ri.ri_emuheight, cx, cy);
+ if (r != 0)
+ goto fail;
/* copy row block back from off-screen now */
- (sc->udl_fb_block_copy)(sc, 0, sc->sc_ri.ri_emuheight, 0, dy, cx, cy);
+ r = (sc->udl_fb_block_copy)
+ (sc, 0, sc->sc_ri.ri_emuheight, 0, dy, cx, cy);
+ if (r != 0)
+ goto fail;
error = udl_cmd_send_async(sc);
if (error != USBD_NORMAL_COMPLETION) {
+fail:
udl_cmd_set_offset(sc, save_offset);
return (EAGAIN);
}
@@ -632,7 +656,7 @@ udl_erasecols(void *cookie, int row, int col, int num, long attr)
struct udl_softc *sc = ri->ri_hw;
uint16_t bgc;
int fg, bg;
- int x, y, cx, cy;
+ int x, y, cx, cy, r;
uint32_t save_offset;
usbd_status error;
@@ -651,10 +675,13 @@ udl_erasecols(void *cookie, int row, int col, int num, long attr)
cx = num * sc->sc_ri.ri_font->fontwidth;
cy = sc->sc_ri.ri_font->fontheight;
- udl_fb_block_write(sc, bgc, x, y, cx, cy);
+ r = udl_fb_block_write(sc, bgc, x, y, cx, cy);
+ if (r != 0)
+ goto fail;
error = udl_cmd_send_async(sc);
if (error != USBD_NORMAL_COMPLETION) {
+fail:
udl_cmd_set_offset(sc, save_offset);
return (EAGAIN);
}
@@ -669,7 +696,7 @@ udl_eraserows(void *cookie, int row, int num, long attr)
struct udl_softc *sc;
uint16_t bgc;
int fg, bg;
- int x, y, cx, cy;
+ int x, y, cx, cy, r;
uint32_t save_offset;
usbd_status error;
@@ -687,10 +714,13 @@ udl_eraserows(void *cookie, int row, int num, long attr)
cx = sc->sc_ri.ri_emuwidth;
cy = num * sc->sc_ri.ri_font->fontheight;
- udl_fb_block_write(sc, bgc, x, y, cx, cy);
+ r = udl_fb_block_write(sc, bgc, x, y, cx, cy);
+ if (r != 0)
+ goto fail;
error = udl_cmd_send_async(sc);
if (error != USBD_NORMAL_COMPLETION) {
+fail:
udl_cmd_set_offset(sc, save_offset);
return (EAGAIN);
}
@@ -703,11 +733,15 @@ udl_putchar(void *cookie, int row, int col, u_int uc, long attr)
{
struct rasops_info *ri = cookie;
struct udl_softc *sc = ri->ri_hw;
+ int r;
uint16_t fgc, bgc;
uint32_t x, y, fg, bg;
+ uint32_t save_offset;
DPRINTF(2, "%s: %s\n", DN(sc), FUNC);
+ save_offset = udl_cmd_get_offset(sc);
+
sc->sc_ri.ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
fgc = (uint16_t)sc->sc_ri.ri_devcmap[fg];
bgc = (uint16_t)sc->sc_ri.ri_devcmap[bg];
@@ -720,11 +754,15 @@ udl_putchar(void *cookie, int row, int col, u_int uc, long attr)
* Writting a block for the space character instead rendering
* it from font bits is more slim.
*/
- (sc->udl_fb_block_write)(sc, bgc, x, y,
+ r = (sc->udl_fb_block_write)(sc, bgc, x, y,
ri->ri_font->fontwidth, ri->ri_font->fontheight);
+ if (r != 0)
+ goto fail;
} else {
/* render a character from font bits */
- udl_draw_char(sc, fgc, bgc, uc, x, y);
+ r = udl_draw_char(sc, fgc, bgc, uc, x, y);
+ if (r != 0)
+ goto fail;
}
/*
@@ -735,12 +773,17 @@ udl_putchar(void *cookie, int row, int col, u_int uc, long attr)
*/
return (0);
+
+fail:
+ udl_cmd_set_offset(sc, save_offset);
+ return (EAGAIN);
}
int
udl_do_cursor(struct rasops_info *ri)
{
struct udl_softc *sc = ri->ri_hw;
+ int r;
uint32_t x, y;
uint32_t save_offset;
uint8_t save_cursor;
@@ -765,24 +808,31 @@ udl_do_cursor(struct rasops_info *ri)
if (sc->sc_cursor_on == 0) {
/* save the last character block to off-screen */
- (sc->udl_fb_block_copy)(sc, x, y, 0, sc->sc_ri.ri_emuheight,
+ r = (sc->udl_fb_block_copy)(sc, x, y, 0, sc->sc_ri.ri_emuheight,
ri->ri_font->fontwidth, ri->ri_font->fontheight);
+ if (r != 0)
+ goto fail;
/* draw cursor */
- (sc->udl_fb_block_write)(sc, 0xffff, x, y,
+ r = (sc->udl_fb_block_write)(sc, 0xffff, x, y,
ri->ri_font->fontwidth, ri->ri_font->fontheight);
+ if (r != 0)
+ goto fail;
sc->sc_cursor_on = 1;
} else {
/* restore the last saved character from off-screen */
- (sc->udl_fb_block_copy)(sc, 0, sc->sc_ri.ri_emuheight, x, y,
+ r = (sc->udl_fb_block_copy)(sc, 0, sc->sc_ri.ri_emuheight, x, y,
ri->ri_font->fontwidth, ri->ri_font->fontheight);
+ if (r != 0)
+ goto fail;
sc->sc_cursor_on = 0;
}
error = udl_cmd_send_async(sc);
if (error != USBD_NORMAL_COMPLETION) {
+fail:
udl_cmd_set_offset(sc, save_offset);
sc->sc_cursor_on = save_cursor;
return (EAGAIN);
@@ -1043,8 +1093,6 @@ udl_cmd_insert_int_1(struct udl_softc *sc, uint8_t value)
{
struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
- udl_cmd_insert_check(cb, 1);
-
cb->buf[cb->off] = value;
cb->off += 1;
@@ -1056,8 +1104,6 @@ udl_cmd_insert_int_2(struct udl_softc *sc, uint16_t value)
uint16_t lvalue;
struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
- udl_cmd_insert_check(cb, 2);
-
lvalue = htobe16(value);
bcopy(&lvalue, cb->buf + cb->off, 2);
@@ -1069,8 +1115,6 @@ udl_cmd_insert_int_3(struct udl_softc *sc, uint32_t value)
{
uint32_t lvalue;
struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
-
- udl_cmd_insert_check(cb, 3);
#if BYTE_ORDER == BIG_ENDIAN
lvalue = htobe32(value) << 8;
#else
@@ -1087,8 +1131,6 @@ udl_cmd_insert_int_4(struct udl_softc *sc, uint32_t value)
uint32_t lvalue;
struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
- udl_cmd_insert_check(cb, 4);
-
lvalue = htobe32(value);
bcopy(&lvalue, cb->buf + cb->off, 4);
@@ -1100,8 +1142,6 @@ udl_cmd_insert_buf(struct udl_softc *sc, uint8_t *buf, uint32_t len)
{
struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
- udl_cmd_insert_check(cb, len);
-
bcopy(buf, cb->buf + cb->off, len);
cb->off += len;
@@ -1118,8 +1158,6 @@ udl_cmd_insert_buf_comp(struct udl_softc *sc, uint8_t *buf, uint32_t len)
uint32_t bit_count, bit_pattern, bit_cur;
int i, j, bytes, eob, padding, next;
- udl_cmd_insert_check(cb, len);
-
pixels = (uint16_t *)buf;
bit_pos = bytes = eob = padding = 0;
@@ -1215,8 +1253,6 @@ udl_cmd_insert_head_comp(struct udl_softc *sc, uint32_t len)
struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
int i, padding;
- udl_cmd_insert_check(cb, len);
-
if (cb->compblock > UDL_CB_BODY_SIZE) {
cb->off -= UDL_CMD_COPY_HEAD_SIZE;
cb->compblock -= UDL_CMD_COPY_HEAD_SIZE;
@@ -1235,17 +1271,37 @@ udl_cmd_insert_head_comp(struct udl_softc *sc, uint32_t len)
return (len);
}
-void
-udl_cmd_insert_check(struct udl_cmd_buf *cb, int len)
+int
+udl_cmd_insert_check(struct udl_softc *sc, int len)
{
+ struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
int total;
+ usbd_status error;
total = cb->off + len;
- if (total >= UDL_CMD_MAX_XFER_SIZE) {
- /* XXX */
- panic("udl_cmd_insert_check: command buffer is full");
+ if (total > UDL_CMD_MAX_XFER_SIZE) {
+ /* command buffer is almost full, try to flush it */
+ if (cb->xfer_method == UDL_CMD_XFER_ASYNC)
+ error = udl_cmd_send_async(sc);
+ else
+ error = udl_cmd_send(sc);
+ if (error != USBD_NORMAL_COMPLETION) {
+ DPRINTF(1, "%s: %s: can't flush full command buffer\n",
+ DN(sc), FUNC);
+ return (EAGAIN);
+ }
}
+
+ return (0);
+}
+
+void
+udl_cmd_set_xfer(struct udl_softc *sc, int xfer_method)
+{
+ struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
+
+ cb->xfer_method = xfer_method;
}
uint32_t
@@ -1490,14 +1546,18 @@ udl_init_resolution(struct udl_softc *sc, uint8_t *buf, uint8_t len)
return (USBD_NORMAL_COMPLETION);
}
-void
+int
udl_fb_off_write(struct udl_softc *sc, uint16_t rgb16, uint32_t off,
uint16_t width)
{
uint8_t buf[UDL_CMD_MAX_DATA_SIZE];
uint16_t lwidth, lrgb16;
uint32_t loff;
- int i;
+ int i, r;
+
+ r = udl_cmd_insert_check(sc, UDL_CMD_WRITE_MAX_SIZE);
+ if (r != 0)
+ return (r);
loff = off * 2;
lwidth = width * 2;
@@ -1513,13 +1573,16 @@ udl_fb_off_write(struct udl_softc *sc, uint16_t rgb16, uint32_t off,
}
udl_cmd_insert_buf(sc, buf, lwidth);
+
+ return (0);
}
-void
+int
udl_fb_line_write(struct udl_softc *sc, uint16_t rgb16, uint32_t x,
uint32_t y, uint32_t width)
{
uint32_t off, block;
+ int r;
off = (y * sc->sc_width) + x;
@@ -1529,29 +1592,44 @@ udl_fb_line_write(struct udl_softc *sc, uint16_t rgb16, uint32_t x,
else
block = width;
- udl_fb_off_write(sc, rgb16, off, block);
+ r = udl_fb_off_write(sc, rgb16, off, block);
+ if (r != 0)
+ return (r);
off += block;
width -= block;
}
+
+ return (0);
}
-void
+int
udl_fb_block_write(struct udl_softc *sc, uint16_t rgb16, uint32_t x,
uint32_t y, uint32_t width, uint32_t height)
{
uint32_t i;
+ int r;
+
+ for (i = 0; i < height; i++) {
+ r = udl_fb_line_write(sc, rgb16, x, y + i, width);
+ if (r != 0)
+ return (r);
+ }
- for (i = 0; i < height; i++)
- udl_fb_line_write(sc, rgb16, x, y + i, width);
+ return (0);
}
-void
+int
udl_fb_buf_write(struct udl_softc *sc, uint8_t *buf, uint32_t x,
uint32_t y, uint16_t width)
{
uint16_t lwidth;
uint32_t off;
+ int r;
+
+ r = udl_cmd_insert_check(sc, UDL_CMD_WRITE_MAX_SIZE);
+ if (r != 0)
+ return (r);
off = ((y * sc->sc_width) + x) * 2;
lwidth = width * 2;
@@ -1562,13 +1640,20 @@ udl_fb_buf_write(struct udl_softc *sc, uint8_t *buf, uint32_t x,
udl_cmd_insert_int_1(sc, width >= UDL_CMD_MAX_PIXEL_COUNT ? 0 : width);
udl_cmd_insert_buf(sc, buf, lwidth);
+
+ return (0);
}
-void
+int
udl_fb_off_copy(struct udl_softc *sc, uint32_t src_off, uint32_t dst_off,
uint16_t width)
{
uint32_t ldst_off, lsrc_off;
+ int r;
+
+ r = udl_cmd_insert_check(sc, UDL_CMD_COPY_MAX_SIZE);
+ if (r != 0)
+ return (r);
ldst_off = dst_off * 2;
lsrc_off = src_off * 2;
@@ -1578,13 +1663,16 @@ udl_fb_off_copy(struct udl_softc *sc, uint32_t src_off, uint32_t dst_off,
udl_cmd_insert_int_3(sc, ldst_off);
udl_cmd_insert_int_1(sc, width >= UDL_CMD_MAX_PIXEL_COUNT ? 0 : width);
udl_cmd_insert_int_3(sc, lsrc_off);
+
+ return (0);
}
-void
+int
udl_fb_line_copy(struct udl_softc *sc, uint32_t src_x, uint32_t src_y,
uint32_t dst_x, uint32_t dst_y, uint32_t width)
{
uint32_t src_off, dst_off, block;
+ int r;
src_off = (src_y * sc->sc_width) + src_x;
dst_off = (dst_y * sc->sc_width) + dst_x;
@@ -1595,25 +1683,35 @@ udl_fb_line_copy(struct udl_softc *sc, uint32_t src_x, uint32_t src_y,
else
block = width;
- udl_fb_off_copy(sc, src_off, dst_off, block);
+ r = udl_fb_off_copy(sc, src_off, dst_off, block);
+ if (r != 0)
+ return (r);
src_off += block;
dst_off += block;
width -= block;
}
+
+ return (0);
}
-void
+int
udl_fb_block_copy(struct udl_softc *sc, uint32_t src_x, uint32_t src_y,
uint32_t dst_x, uint32_t dst_y, uint32_t width, uint32_t height)
{
- int i;
+ int i, r;
+
+ for (i = 0; i < height; i++) {
+ r = udl_fb_line_copy(sc, src_x, src_y + i, dst_x, dst_y + i,
+ width);
+ if (r != 0)
+ return (r);
+ }
- for (i = 0; i < height; i++)
- udl_fb_line_copy(sc, src_x, src_y + i, dst_x, dst_y + i, width);
+ return (0);
}
-void
+int
udl_fb_off_write_comp(struct udl_softc *sc, uint16_t rgb16, uint32_t off,
uint16_t width)
{
@@ -1624,6 +1722,10 @@ udl_fb_off_write_comp(struct udl_softc *sc, uint16_t rgb16, uint32_t off,
uint32_t loff;
int i, r, sent;
+ r = udl_cmd_insert_check(sc, UDL_CMD_WRITE_MAX_SIZE);
+ if (r != 0)
+ return (r);
+
loff = off * 2;
lwidth = width * 2;
@@ -1659,13 +1761,16 @@ udl_fb_off_write_comp(struct udl_softc *sc, uint16_t rgb16, uint32_t off,
}
sent += r;
}
+
+ return (0);
}
-void
+int
udl_fb_line_write_comp(struct udl_softc *sc, uint16_t rgb16, uint32_t x,
uint32_t y, uint32_t width)
{
uint32_t off, block;
+ int r;
off = (y * sc->sc_width) + x;
@@ -1675,24 +1780,34 @@ udl_fb_line_write_comp(struct udl_softc *sc, uint16_t rgb16, uint32_t x,
else
block = width;
- (sc->udl_fb_off_write)(sc, rgb16, off, block);
+ r = (sc->udl_fb_off_write)(sc, rgb16, off, block);
+ if (r != 0)
+ return (r);
off += block;
width -= block;
}
+
+ return (0);
}
-void
+int
udl_fb_block_write_comp(struct udl_softc *sc, uint16_t rgb16, uint32_t x,
uint32_t y, uint32_t width, uint32_t height)
{
uint32_t i;
+ int r;
+
+ for (i = 0; i < height; i++) {
+ r = udl_fb_line_write_comp(sc, rgb16, x, y + i, width);
+ if (r != 0)
+ return (r);
+ }
- for (i = 0; i < height; i++)
- udl_fb_line_write_comp(sc, rgb16, x, y + i, width);
+ return (0);
}
-void
+int
udl_fb_buf_write_comp(struct udl_softc *sc, uint8_t *buf, uint32_t x,
uint32_t y, uint16_t width)
{
@@ -1702,6 +1817,10 @@ udl_fb_buf_write_comp(struct udl_softc *sc, uint8_t *buf, uint32_t x,
uint32_t off;
int r, sent;
+ r = udl_cmd_insert_check(sc, UDL_CMD_WRITE_MAX_SIZE);
+ if (r != 0)
+ return (r);
+
off = ((y * sc->sc_width) + x) * 2;
lwidth = width * 2;
@@ -1732,9 +1851,11 @@ udl_fb_buf_write_comp(struct udl_softc *sc, uint8_t *buf, uint32_t x,
}
sent += r;
}
+
+ return (0);
}
-void
+int
udl_fb_off_copy_comp(struct udl_softc *sc, uint32_t src_off, uint32_t dst_off,
uint16_t width)
{
@@ -1742,6 +1863,10 @@ udl_fb_off_copy_comp(struct udl_softc *sc, uint32_t src_off, uint32_t dst_off,
uint32_t ldst_off, lsrc_off;
int r;
+ r = udl_cmd_insert_check(sc, UDL_CMD_COPY_MAX_SIZE);
+ if (r != 0)
+ return (r);
+
ldst_off = dst_off * 2;
lsrc_off = src_off * 2;
@@ -1765,13 +1890,16 @@ udl_fb_off_copy_comp(struct udl_softc *sc, uint32_t src_off, uint32_t dst_off,
r = udl_cmd_insert_head_comp(sc, UDL_CMD_COPY_HEAD_SIZE);
}
+
+ return (0);
}
-void
+int
udl_fb_line_copy_comp(struct udl_softc *sc, uint32_t src_x, uint32_t src_y,
uint32_t dst_x, uint32_t dst_y, uint32_t width)
{
uint32_t src_off, dst_off, block;
+ int r;
src_off = (src_y * sc->sc_width) + src_x;
dst_off = (dst_y * sc->sc_width) + dst_x;
@@ -1782,30 +1910,39 @@ udl_fb_line_copy_comp(struct udl_softc *sc, uint32_t src_x, uint32_t src_y,
else
block = width;
- udl_fb_off_copy_comp(sc, src_off, dst_off, block);
+ r = udl_fb_off_copy_comp(sc, src_off, dst_off, block);
+ if (r != 0)
+ return (r);
src_off += block;
dst_off += block;
width -= block;
}
+
+ return (0);
}
-void
+int
udl_fb_block_copy_comp(struct udl_softc *sc, uint32_t src_x, uint32_t src_y,
uint32_t dst_x, uint32_t dst_y, uint32_t width, uint32_t height)
{
- int i;
+ int i, r;
- for (i = 0; i < height; i++)
- udl_fb_line_copy_comp(sc, src_x, src_y + i, dst_x, dst_y + i,
- width);
+ for (i = 0; i < height; i++) {
+ r = udl_fb_line_copy_comp(sc, src_x, src_y + i,
+ dst_x, dst_y + i, width);
+ if (r != 0)
+ return (r);
+ }
+
+ return (0);
}
-void
+int
udl_draw_char(struct udl_softc *sc, uint16_t fg, uint16_t bg, u_int uc,
uint32_t x, uint32_t y)
{
- int i, j, ly;
+ int i, j, ly, r;
uint8_t *fontchar;
uint8_t buf[UDL_CMD_MAX_DATA_SIZE];
uint16_t *line, lrgb16, fontbits, luc;
@@ -1833,11 +1970,15 @@ udl_draw_char(struct udl_softc *sc, uint16_t fg, uint16_t bg, u_int uc,
bcopy(&lrgb16, line, 2);
line++;
}
- (sc->udl_fb_buf_write)(sc, buf, x, ly, font->fontwidth);
+ r = (sc->udl_fb_buf_write)(sc, buf, x, ly, font->fontwidth);
+ if (r != 0)
+ return (r);
ly++;
fontchar += font->stride;
}
+
+ return (0);
}
/* ---------- */