static u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
{ int ret = 0;
mutex_lock(&dev->lock); if ((dev->cmds[seqno].inuse == 1) &&
(dev->cmds[seqno].seqno == seqno)) {
ret = dev->cmds[seqno].timeout;
}
mutex_unlock(&dev->lock);
return ret;
}
/* Commands to the f/w get marshelled to/from this code then onto the PCI
* -bus/c running buffer. */ int saa7164_irq_dequeue(struct saa7164_dev *dev)
{ int ret = SAA_OK, i = 0;
u32 timeout;
wait_queue_head_t *q = NULL;
u8 tmp[512];
dprintk(DBGLVL_CMD, "%s()\n", __func__);
/* While any outstand message on the bus exists... */ do {
/* Peek the msg bus */ struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 };
ret = saa7164_bus_get(dev, &tRsp, NULL, 1); if (ret != SAA_OK) break;
q = &dev->cmds[tRsp.seqno].wait;
timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout); if (!timeout) {
dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n",
__func__, tRsp.seqno);
dev->cmds[tRsp.seqno].signalled = 1;
wake_up(q);
} else {
printk(KERN_ERR "%s() found timed out command on the bus\n",
__func__);
/* Clean the bus */
ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
printk(KERN_ERR "%s() ret = %x\n", __func__, ret); if (ret == SAA_ERR_EMPTY) /* Someone else already fetched the response */ return SAA_OK;
if (ret != SAA_OK) return ret;
}
/* It's unlikely to have more than 4 or 5 pending messages, * ensure we exit at some point regardless.
*/
} while (i++ < 32);
return ret;
}
/* Commands to the f/w get marshelled to/from this code then onto the PCI
* -bus/c running buffer. */ staticint saa7164_cmd_dequeue(struct saa7164_dev *dev)
{ int ret;
u32 timeout;
wait_queue_head_t *q = NULL;
u8 tmp[512];
dprintk(DBGLVL_CMD, "%s()\n", __func__);
/* Wait for a signal event, without holding a mutex. Either return TIMEOUT if * the event never occurred, or SAA_OK if it was signaled during the wait.
*/ staticint saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
{
wait_queue_head_t *q = NULL; int ret = SAA_BUS_TIMEOUT; unsignedlong stamp; int r;
if (q) { /* If we haven't been signalled we need to wait */ if (dev->cmds[seqno].signalled == 0) {
stamp = jiffies;
dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting (signalled=%d)\n",
__func__, seqno, dev->cmds[seqno].signalled);
/* Wait for signalled to be flagged or timeout */ /* In a highly stressed system this can easily extend * into multiple seconds before the deferred worker * is scheduled, and we're woken up via signal. * We typically are signalled in < 50ms but it can * take MUCH longer.
*/
wait_event_timeout(*q, dev->cmds[seqno].signalled,
(HZ * waitsecs));
r = time_before(jiffies, stamp + (HZ * waitsecs)); if (r)
ret = SAA_OK; else
saa7164_cmd_timeout_seqno(dev, seqno);
dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d (signalled=%d)\n",
__func__, seqno, r,
dev->cmds[seqno].signalled);
} else
ret = SAA_OK;
} else
printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n",
__func__, seqno);
/* Allocate a unique sequence number */
ret = saa7164_cmd_alloc_seqno(dev); if (ret < 0) {
printk(KERN_ERR "%s() No free sequences\n", __func__);
ret = SAA_ERR_NO_RESOURCES; goto out;
}
ret = saa7164_cmd_set(dev, pcommand_t, buf); if (ret != SAA_OK) {
printk(KERN_ERR "%s() set command failed %d\n", __func__, ret);
if (ret != SAA_ERR_BUSY)
saa7164_cmd_free_seqno(dev, pcommand_t->seqno); else /* Flag a timeout, because at least one
* command was sent */
saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
goto out;
}
/* With split responses we have to collect the msgs piece by piece */
data_recd = 0;
loop = 1; while (loop) {
dprintk(DBGLVL_CMD, "%s() loop\n", __func__);
ret = saa7164_cmd_wait(dev, pcommand_t->seqno);
dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret);
/* if power is down and this is not a power command ... */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.