/* Commands to the f/w get marshelled to/from this code then onto the PCI * -bus/c running buffer. */ int saa7164_cmd_dequeue(struct saa7164_dev *dev) { int loop = 1; int ret; u32 timeout; wait_queue_head_t *q = NULL; u8 tmp[512]; ; while (loop) { struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 }; ret = saa7164_bus_get(dev, &tRsp, NULL, 1); if (ret == SAA_ERR_EMPTY) return SAA_OK; if (ret != SAA_OK) return ret; q = &dev->cmds[tRsp.seqno].wait; timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno); ; if (timeout) { ; /* Clean the bus */ ret = saa7164_bus_get(dev, &tRsp, &tmp, 0); ; if (ret == SAA_ERR_EMPTY) /* Someone else already fetched the response */ return SAA_OK; if (ret != SAA_OK) return ret; if (tRsp.flags & PVC_CMDFLAG_CONTINUE) ; else saa7164_cmd_free_seqno(dev, tRsp.seqno); ; continue; } // dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n", ; dev->cmds[tRsp.seqno].signalled = 1; wake_up(q); return SAA_OK; } return SAA_OK; }
/* Commands to the f/w get marshelled to/from this code then onto the PCI * -bus/c running buffer. */ int saa7164_cmd_dequeue(struct saa7164_dev *dev) { int loop = 1; int ret; u32 timeout; wait_queue_head_t *q = 0; u8 tmp[512]; dprintk(DBGLVL_CMD, "%s()\n", __func__); while (loop) { tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 }; ret = saa7164_bus_get(dev, &tRsp, NULL, 1); if (ret == SAA_ERR_EMPTY) return SAA_OK; if (ret != SAA_OK) return ret; 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) { printk(KERN_ERR "found timed out command on the bus\n"); /* Clean the bus */ ret = saa7164_bus_get(dev, &tRsp, &tmp, 0); printk(KERN_ERR "ret = %x\n", ret); if (ret == SAA_ERR_EMPTY) /* Someone else already fetched the response */ return SAA_OK; if (ret != SAA_OK) return ret; if (tRsp.flags & PVC_CMDFLAG_CONTINUE) printk(KERN_ERR "split response\n"); else saa7164_cmd_free_seqno(dev, tRsp.seqno); printk(KERN_ERR " timeout continue\n"); continue; } dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n", __func__, tRsp.seqno); dev->cmds[tRsp.seqno].signalled = 1; wake_up(q); return SAA_OK; } return SAA_OK; }
/* 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]; ; /* 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); ; if (!timeout) { // dprintk(DBGLVL_CMD, // "%s() signalled seqno(%d) (for dequeue)\n", ; dev->cmds[tRsp.seqno].signalled = 1; wake_up(q); } else { // printk(KERN_ERR // "%s() found timed out command on the bus\n", ; /* Clean the bus */ ret = saa7164_bus_get(dev, &tRsp, &tmp, 0); ; 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. */ int saa7164_irq_dequeue(struct saa7164_dev *dev) { int ret = SAA_OK; u32 timeout; wait_queue_head_t *q = 0; dprintk(DBGLVL_CMD, "%s()\n", __func__); /* While any outstand message on the bus exists... */ do { /* Peek the msg bus */ tmComResInfo_t 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__); } } while (0); return ret; }
int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command, u16 controlselector, u16 size, void *buf) { struct tmComResInfo command_t, *pcommand_t; struct tmComResInfo response_t, *presponse_t; u8 errdata[256]; u16 resp_dsize; u16 data_recd; u32 loop; int ret; int safety = 0; // dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, " // "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id, ; if ((size == 0) || (buf == NULL)) { ; return SAA_ERR_BAD_PARAMETER; } /* Prepare some basic command/response structures */ memset(&command_t, 0, sizeof(command_t)); memset(&response_t, 0, sizeof(response_t)); pcommand_t = &command_t; presponse_t = &response_t; command_t.id = id; command_t.command = command; command_t.controlselector = controlselector; command_t.size = size; /* Allocate a unique sequence number */ ret = saa7164_cmd_alloc_seqno(dev); if (ret < 0) { ; ret = SAA_ERR_NO_RESOURCES; goto out; } command_t.seqno = (u8)ret; /* Send Command */ resp_dsize = size; pcommand_t->size = size; // dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n", ; // dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n", ; ret = saa7164_cmd_set(dev, pcommand_t, buf); if (ret != SAA_OK) { ; 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) { ; ret = saa7164_cmd_wait(dev, pcommand_t->seqno); ; /* if power is down and this is not a power command ... */ if (ret == SAA_BUS_TIMEOUT) { ; saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno); return ret; } if (ret != SAA_OK) { ; return ret; } /* Peek response */ ret = saa7164_bus_get(dev, presponse_t, NULL, 1); if (ret == SAA_ERR_EMPTY) { ; continue; } if (ret != SAA_OK) { ; return ret; } // dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n", ; // dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n", ; // dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n", ; /* Check if the response was for our command */ if (presponse_t->seqno != pcommand_t->seqno) { // dprintk(DBGLVL_CMD, // "wrong event: seqno = %d, " // "expected seqno = %d, " // "will dequeue regardless\n", ; ret = saa7164_cmd_dequeue(dev); if (ret != SAA_OK) { // printk(KERN_ERR "dequeue failed, ret = %d\n", ; if (safety++ > 16) { // printk(KERN_ERR ; return SAA_ERR_BUSY; } } continue; } if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) { memset(&errdata[0], 0, sizeof(errdata)); ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0); if (ret != SAA_OK) { ; return ret; } saa7164_cmd_free_seqno(dev, pcommand_t->seqno); // dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n", // __func__, errdata[0], errdata[1], errdata[2], ; /* Map error codes */ // dprintk(DBGLVL_CMD, "%s() cmd, error code = 0x%x\n", ; switch (errdata[0]) { case PVC_ERRORCODE_INVALID_COMMAND: // dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n", ; ret = SAA_ERR_INVALID_COMMAND; break; case PVC_ERRORCODE_INVALID_DATA: // dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n", ; ret = SAA_ERR_BAD_PARAMETER; break; case PVC_ERRORCODE_TIMEOUT: ; ret = SAA_ERR_TIMEOUT; break; case PVC_ERRORCODE_NAK: ; ret = SAA_ERR_NULL_PACKET; break; case PVC_ERRORCODE_UNKNOWN: case PVC_ERRORCODE_INVALID_CONTROL: // dprintk(DBGLVL_CMD, // "%s() UNKNOWN OR INVALID CONTROL\n", ; default: ; ret = SAA_ERR_NOT_SUPPORTED; } /* See of other commands are on the bus */ if (saa7164_cmd_dequeue(dev) != SAA_OK) ; return ret; } /* If response is invalid */ if ((presponse_t->id != pcommand_t->id) || (presponse_t->command != pcommand_t->command) || (presponse_t->controlselector != pcommand_t->controlselector) || (((resp_dsize - data_recd) != presponse_t->size) && !(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) || ((resp_dsize - data_recd) < presponse_t->size)) { /* Invalid */ ; ret = saa7164_bus_get(dev, presponse_t, NULL, 0); if (ret != SAA_OK) { ; return ret; } /* See of other commands are on the bus */ if (saa7164_cmd_dequeue(dev) != SAA_OK) ; continue; } /* OK, now we're actually getting out correct response */ ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0); if (ret != SAA_OK) { ; return ret; } data_recd = presponse_t->size + data_recd; if (resp_dsize == data_recd) { ; break; } /* See of other commands are on the bus */ if (saa7164_cmd_dequeue(dev) != SAA_OK) ; continue; } /* (loop) */ /* Release the sequence number allocation */ saa7164_cmd_free_seqno(dev, pcommand_t->seqno); /* if powerdown signal all pending commands */ ; /* See of other commands are on the bus */ if (saa7164_cmd_dequeue(dev) != SAA_OK) ; ret = SAA_OK; out: return ret; }