--- av7110_hw.c	Tue Dec 14 23:29:46 2004
+++ /home/endriss/cvs-work/2.6/dvb-kernel/build-2.6/av7110_hw.c	Tue Dec 14 17:08:17 2004
@@ -316,9 +328,9 @@ int __av7110_send_fw_cmd(struct av7110 *
 {
 	int i;
 	unsigned long start;
-#ifdef COM_DEBUG
+	char *type = NULL;
+	u16 flags[2] = {0, 0};
 	u32 stat;
-#endif
 
 //	dprintk(4, "%p\n", av7110);
 
@@ -349,14 +361,52 @@ int __av7110_send_fw_cmd(struct av7110 *
 	}
 #endif
 
-	start = jiffies;
-	while (rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2) & OSDQFull) {
-		msleep(1);
-		if (time_after(jiffies, start + ARM_WAIT_OSD)) {
-			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for !OSDQFull\n", __FUNCTION__);
-			return -1;
+	switch ((buf[0] >> 8) & 0xff) {
+	case COMTYPE_PIDFILTER:
+	case COMTYPE_ENCODER:
+	case COMTYPE_REC_PLAY:
+	case COMTYPE_MPEGDECODER:
+		type = "MSG";
+		flags[0] = GPMQOver;
+		flags[1] = GPMQFull;
+		break;
+	case COMTYPE_OSD:
+		type = "OSD";
+		flags[0] = OSDQOver;
+		flags[1] = OSDQFull;
+		break;
+	case COMTYPE_MISC:
+		if (FW_VERSION(av7110->arm_app) >= 0x261d) {
+			type = "MSG";
+			flags[0] = GPMQOver;
+			flags[1] = GPMQBusy;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (type != NULL) {
+		/* non-immediate COMMAND type */
+		start = jiffies;
+		for (;;) {
+			stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
+			if (stat & flags[0]) {
+				printk(KERN_ERR "%s: %s QUEUE overflow\n",
+					__FUNCTION__, type);
+				return -1;
+			}
+			if ((stat & flags[1]) == 0)
+				break;
+			if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+				printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
+					__FUNCTION__, type);
+				return -1;
+			}
+			msleep(1);
 		}
 	}
+
 	for (i = 2; i < length; i++)
 		wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2);
 
@@ -833,16 +883,17 @@ static int BlitBitmap(struct av7110 *av7
 
 	BUG_ON (av7110->bmp_state == BMP_NONE);
 
-	ret = wait_event_interruptible_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, HZ);
+	ret = wait_event_interruptible_timeout(av7110->bmpq,
+				av7110->bmp_state != BMP_LOADING, 10*HZ);
 	if (ret == -ERESTARTSYS || ret == 0) {
 		printk("dvb-ttpci: warning: timeout waiting in %s()\n", __FUNCTION__);
 		av7110->bmp_state = BMP_NONE;
-		return -1;
-		}
+		return (ret == 0) ? -ETIMEDOUT : ret;
+	}
 
 	BUG_ON (av7110->bmp_state != BMP_LOADED);
 
-		return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans);
+	return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans);
 }
 
 static inline int ReleaseBitmap(struct av7110 *av7110)
@@ -911,10 +962,11 @@ static int OSDSetPalette(struct av7110 *
 }
 
 static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
-		       int x1, int y1, int inc, u8 __user *data)
+		       int x1, int y1, int inc, u8 __user * data)
 {
 	uint w, h, bpp, bpl, size, lpb, bnum, brest;
 	int i;
+	int rc;
 
 	w = x1 - x0 + 1;
 	h = y1 - y0 + 1;
@@ -930,15 +982,23 @@ static int OSDSetBlock(struct av7110 *av
 	brest = size - bnum * lpb * bpl;
 
 	for (i = 0; i < bnum; i++) {
-		LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
+		rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
 			   w, lpb, inc, data);
-		BlitBitmap(av7110, av7110->osdwin, x0, y0 + i * lpb, 0);
+		if (rc)
+			return rc;
+		rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + i * lpb, 0);
+		if (rc)
+			return rc;
 		data += lpb * inc;
 	}
 	if (brest) {
-		LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
+		rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
 			   w, brest / bpl, inc, data);
-		BlitBitmap(av7110, av7110->osdwin, x0, y0 + bnum * lpb, 0);
+		if (rc)
+			return rc;
+		rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + bnum * lpb, 0);
+		if (rc)
+			return rc;
 	}
 	ReleaseBitmap(av7110);
 	return 0;
@@ -1020,7 +1080,7 @@ int av7110_osd_cmd(struct av7110 *av7110
 		dc->y1 = dc->y0;
 		/* fall through */
 	case OSD_SetBlock:
-		OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
+		ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
 		goto out;
 	case OSD_FillRow:
 		DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
