|
@@ -277,7 +277,7 @@ out_unref:
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port)
|
|
|
+static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port, bool intr)
|
|
|
{
|
|
|
int irq_num;
|
|
|
long addr = qdev->io_base + port;
|
|
@@ -285,20 +285,29 @@ static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port)
|
|
|
|
|
|
mutex_lock(&qdev->async_io_mutex);
|
|
|
irq_num = atomic_read(&qdev->irq_received_io_cmd);
|
|
|
-
|
|
|
-
|
|
|
if (qdev->last_sent_io_cmd > irq_num) {
|
|
|
- ret = wait_event_interruptible(qdev->io_cmd_event,
|
|
|
- atomic_read(&qdev->irq_received_io_cmd) > irq_num);
|
|
|
- if (ret)
|
|
|
+ if (intr)
|
|
|
+ ret = wait_event_interruptible_timeout(qdev->io_cmd_event,
|
|
|
+ atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ);
|
|
|
+ else
|
|
|
+ ret = wait_event_timeout(qdev->io_cmd_event,
|
|
|
+ atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ);
|
|
|
+ /* 0 is timeout, just bail the "hw" has gone away */
|
|
|
+ if (ret <= 0)
|
|
|
goto out;
|
|
|
irq_num = atomic_read(&qdev->irq_received_io_cmd);
|
|
|
}
|
|
|
outb(val, addr);
|
|
|
qdev->last_sent_io_cmd = irq_num + 1;
|
|
|
- ret = wait_event_interruptible(qdev->io_cmd_event,
|
|
|
- atomic_read(&qdev->irq_received_io_cmd) > irq_num);
|
|
|
+ if (intr)
|
|
|
+ ret = wait_event_interruptible_timeout(qdev->io_cmd_event,
|
|
|
+ atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ);
|
|
|
+ else
|
|
|
+ ret = wait_event_timeout(qdev->io_cmd_event,
|
|
|
+ atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ);
|
|
|
out:
|
|
|
+ if (ret > 0)
|
|
|
+ ret = 0;
|
|
|
mutex_unlock(&qdev->async_io_mutex);
|
|
|
return ret;
|
|
|
}
|
|
@@ -308,7 +317,7 @@ static void wait_for_io_cmd(struct qxl_device *qdev, uint8_t val, long port)
|
|
|
int ret;
|
|
|
|
|
|
restart:
|
|
|
- ret = wait_for_io_cmd_user(qdev, val, port);
|
|
|
+ ret = wait_for_io_cmd_user(qdev, val, port, false);
|
|
|
if (ret == -ERESTARTSYS)
|
|
|
goto restart;
|
|
|
}
|
|
@@ -340,7 +349,7 @@ int qxl_io_update_area(struct qxl_device *qdev, struct qxl_bo *surf,
|
|
|
mutex_lock(&qdev->update_area_mutex);
|
|
|
qdev->ram_header->update_area = *area;
|
|
|
qdev->ram_header->update_surface = surface_id;
|
|
|
- ret = wait_for_io_cmd_user(qdev, 0, QXL_IO_UPDATE_AREA_ASYNC);
|
|
|
+ ret = wait_for_io_cmd_user(qdev, 0, QXL_IO_UPDATE_AREA_ASYNC, true);
|
|
|
mutex_unlock(&qdev->update_area_mutex);
|
|
|
return ret;
|
|
|
}
|