V4L/DVB (12923): SAA7164: Add support for the NXP SAA7164 silicon
[linux-block.git] / drivers / media / video / saa7164 / saa7164-cmd.c
1 /*
2  *  Driver for the NXP SAA7164 PCIe bridge
3  *
4  *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include <linux/wait.h>
23
24 #include "saa7164.h"
25
26 int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
27 {
28         int i, ret = -1;
29
30         mutex_lock(&dev->lock);
31         for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
32                 if (dev->cmds[i].inuse == 0) {
33                         dev->cmds[i].inuse = 1;
34                         dev->cmds[i].signalled = 0;
35                         dev->cmds[i].timeout = 0;
36                         ret = dev->cmds[i].seqno;
37                         break;
38                 }
39         }
40         mutex_unlock(&dev->lock);
41
42         return ret;
43 }
44
45 void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
46 {
47         mutex_lock(&dev->lock);
48         if ((dev->cmds[seqno].inuse == 1) &&
49                 (dev->cmds[seqno].seqno == seqno)) {
50                 dev->cmds[seqno].inuse = 0;
51                 dev->cmds[seqno].signalled = 0;
52                 dev->cmds[seqno].timeout = 0;
53         }
54         mutex_unlock(&dev->lock);
55 }
56
57 void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
58 {
59         mutex_lock(&dev->lock);
60         if ((dev->cmds[seqno].inuse == 1) &&
61                 (dev->cmds[seqno].seqno == seqno)) {
62                 dev->cmds[seqno].timeout = 1;
63         }
64         mutex_unlock(&dev->lock);
65 }
66
67 u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
68 {
69         int ret = 0;
70
71         mutex_lock(&dev->lock);
72         if ((dev->cmds[seqno].inuse == 1) &&
73                 (dev->cmds[seqno].seqno == seqno)) {
74                 ret = dev->cmds[seqno].timeout;
75         }
76         mutex_unlock(&dev->lock);
77
78         return ret;
79 }
80
81 /* Commands to the f/w get marshelled to/from this code then onto the PCI
82  * -bus/c running buffer. */
83 int saa7164_cmd_dequeue(struct saa7164_dev *dev)
84 {
85         int loop = 1;
86         int ret;
87         u32 timeout;
88         wait_queue_head_t *q = 0;
89         u8 tmp[512];
90         dprintk(DBGLVL_CMD, "%s()\n", __func__);
91
92         while (loop) {
93
94                 tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
95                 ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
96                 if (ret == SAA_ERR_EMPTY)
97                         return SAA_OK;
98
99                 if (ret != SAA_OK)
100                         return ret;
101
102                 q = &dev->cmds[tRsp.seqno].wait;
103                 timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
104                 dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
105                 if (timeout) {
106                         printk(KERN_ERR "found timed out command on the bus\n");
107
108                         /* Clean the bus */
109                         ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
110                         printk(KERN_ERR "ret = %x\n", ret);
111                         if (ret == SAA_ERR_EMPTY)
112                                 /* Someone else already fetched the response */
113                                 return SAA_OK;
114
115                         if (ret != SAA_OK)
116                                 return ret;
117
118                         if (tRsp.flags & PVC_CMDFLAG_CONTINUE)
119                                 printk(KERN_ERR "split response\n");
120                         else
121                                 saa7164_cmd_free_seqno(dev, tRsp.seqno);
122
123                         printk(KERN_ERR " timeout continue\n");
124                         continue;
125                 }
126
127                 dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n",
128                         __func__, tRsp.seqno);
129                 dev->cmds[tRsp.seqno].signalled = 1;
130                 wake_up(q);
131                 return SAA_OK;
132         }
133
134         return SAA_OK;
135 }
136
137 int saa7164_cmd_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
138 {
139         tmComResBusInfo_t *bus = &dev->bus;
140         u8 cmd_sent;
141         u16 size, idx;
142         u32 cmds;
143         void *tmp;
144         int ret = -1;
145
146         if (!msg) {
147                 printk(KERN_ERR "%s() !msg\n", __func__);
148                 return SAA_ERR_BAD_PARAMETER;
149         }
150
151         mutex_lock(&dev->cmds[msg->id].lock);
152
153         size = msg->size;
154         idx = 0;
155         cmds = size / bus->m_wMaxReqSize;
156         if (size % bus->m_wMaxReqSize == 0)
157                 cmds -= 1;
158
159         cmd_sent = 0;
160
161         /* Split the request into smaller chunks */
162         for (idx = 0; idx < cmds; idx++) {
163
164                 msg->flags |= SAA_CMDFLAG_CONTINUE;
165                 msg->size = bus->m_wMaxReqSize;
166                 tmp = buf + idx * bus->m_wMaxReqSize;
167
168                 ret = saa7164_bus_set(dev, msg, tmp);
169                 if (ret != SAA_OK) {
170                         printk(KERN_ERR "%s() set failed %d\n", __func__, ret);
171
172                         if (cmd_sent) {
173                                 ret = SAA_ERR_BUSY;
174                                 goto out;
175                         }
176                         ret = SAA_ERR_OVERFLOW;
177                         goto out;
178                 }
179                 cmd_sent = 1;
180         }
181
182         /* If not the last command... */
183         if (idx != 0)
184                 msg->flags &= ~SAA_CMDFLAG_CONTINUE;
185
186         msg->size = size - idx * bus->m_wMaxReqSize;
187
188         ret = saa7164_bus_set(dev, msg, buf + idx * bus->m_wMaxReqSize);
189         if (ret != SAA_OK) {
190                 printk(KERN_ERR "%s() set last failed %d\n", __func__, ret);
191
192                 if (cmd_sent) {
193                         ret = SAA_ERR_BUSY;
194                         goto out;
195                 }
196                 ret = SAA_ERR_OVERFLOW;
197                 goto out;
198         }
199         ret = SAA_OK;
200
201 out:
202         mutex_unlock(&dev->cmds[msg->id].lock);
203         return ret;
204 }
205
206 /* Wait for a signal event, without holding a mutex. Either return TIMEOUT if
207  * the event never occured, or SAA_OK if it was signaled during the wait.
208  */
209 int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
210 {
211         wait_queue_head_t *q = 0;
212         int ret = SAA_BUS_TIMEOUT;
213         unsigned long stamp;
214         int r;
215
216         if (debug >= 4)
217                 saa7164_bus_dump(dev);
218
219         dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno);
220
221         mutex_lock(&dev->lock);
222         if ((dev->cmds[seqno].inuse == 1) &&
223                 (dev->cmds[seqno].seqno == seqno)) {
224                 q = &dev->cmds[seqno].wait;
225         }
226         mutex_unlock(&dev->lock);
227
228         if (q) {
229                 /* If we haven't been signalled we need to wait */
230                 if (dev->cmds[seqno].signalled == 0) {
231                         stamp = jiffies;
232                         dprintk(DBGLVL_CMD,
233                                 "%s(seqno=%d) Waiting (signalled=%d)\n",
234                                 __func__, seqno, dev->cmds[seqno].signalled);
235
236                         /* Wait for signalled to be flagged or timeout */
237                         wait_event_timeout(*q, dev->cmds[seqno].signalled, HZ);
238                         r = time_before(jiffies, stamp + HZ);
239                         if (r)
240                                 ret = SAA_OK;
241                         else
242                                 saa7164_cmd_timeout_seqno(dev, seqno);
243
244                         dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d "
245                                 "(signalled=%d)\n", __func__, seqno, r,
246                                 dev->cmds[seqno].signalled);
247                 } else
248                         ret = SAA_OK;
249         } else
250                 printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n",
251                         __func__, seqno);
252
253         return ret;
254 }
255
256 void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno)
257 {
258         int i;
259         dprintk(DBGLVL_CMD, "%s()\n", __func__);
260
261         mutex_lock(&dev->lock);
262         for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
263                 if (dev->cmds[i].inuse == 1) {
264                         dprintk(DBGLVL_CMD,
265                                 "seqno %d inuse, sig = %d, t/out = %d\n",
266                                 dev->cmds[i].seqno,
267                                 dev->cmds[i].signalled,
268                                 dev->cmds[i].timeout);
269                 }
270         }
271
272         for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
273                 if ((dev->cmds[i].inuse == 1) && ((i == 0) ||
274                         (dev->cmds[i].signalled) || (dev->cmds[i].timeout))) {
275                         dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n",
276                                 __func__, i);
277                         dev->cmds[i].signalled = 1;
278                         wake_up(&dev->cmds[i].wait);
279                 }
280         }
281         mutex_unlock(&dev->lock);
282 }
283
284 int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, tmComResCmd_t command,
285         u16 controlselector, u16 size, void *buf)
286 {
287         tmComResInfo_t command_t, *pcommand_t;
288         tmComResInfo_t response_t, *presponse_t;
289         u8 errdata[256];
290         u16 resp_dsize;
291         u16 data_recd;
292         u32 loop;
293         int ret;
294         int safety = 0;
295
296         dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, "
297                 "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
298                 command, controlselector);
299
300         if ((size == 0) || (buf == 0)) {
301                 printk(KERN_ERR "%s() Invalid param\n", __func__);
302                 return SAA_ERR_BAD_PARAMETER;
303         }
304
305         /* Prepare some basic command/response structures */
306         memset(&command_t, 0, sizeof(command_t));
307         memset(&response_t, 0, sizeof(&response_t));
308         pcommand_t = &command_t;
309         presponse_t = &response_t;
310         command_t.id = id;
311         command_t.command = command;
312         command_t.controlselector = controlselector;
313         command_t.size = size;
314
315         /* Allocate a unique sequence number */
316         ret = saa7164_cmd_alloc_seqno(dev);
317         if (ret < 0) {
318                 printk(KERN_ERR "%s() No free sequences\n", __func__);
319                 ret = SAA_ERR_NO_RESOURCES;
320                 goto out;
321         }
322
323         command_t.seqno = (u8)ret;
324
325         /* Send Command */
326         resp_dsize = size;
327         pcommand_t->size = size;
328
329         dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n",
330                 __func__, pcommand_t->seqno);
331
332         dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n",
333                 __func__, pcommand_t->size);
334
335         ret = saa7164_cmd_set(dev, pcommand_t, buf);
336         if (ret != SAA_OK) {
337                 printk(KERN_ERR "%s() set command failed %d\n", __func__, ret);
338
339                 if (ret != SAA_ERR_BUSY)
340                         saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
341                 else
342                         /* Flag a timeout, because at least one
343                          * command was sent */
344                         saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
345
346                 goto out;
347         }
348
349         /* With split responses we have to collect the msgs piece by piece */
350         data_recd = 0;
351         loop = 1;
352         while (loop) {
353                 dprintk(DBGLVL_CMD, "%s() loop\n", __func__);
354
355                 ret = saa7164_cmd_wait(dev, pcommand_t->seqno);
356                 dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret);
357
358                 /* if power is down and this is not a power command ... */
359
360                 if (ret == SAA_BUS_TIMEOUT) {
361                         printk(KERN_ERR "Event timed out\n");
362                         saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
363                         return ret;
364                 }
365
366                 if (ret != SAA_OK) {
367                         printk(KERN_ERR "spurious error\n");
368                         return ret;
369                 }
370
371                 /* Peek response */
372                 ret = saa7164_bus_get(dev, presponse_t, NULL, 1);
373                 if (ret == SAA_ERR_EMPTY) {
374                         dprintk(4, "%s() SAA_ERR_EMPTY\n", __func__);
375                         continue;
376                 }
377                 if (ret != SAA_OK) {
378                         printk(KERN_ERR "peek failed\n");
379                         return ret;
380                 }
381
382                 dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n",
383                         __func__, presponse_t->seqno);
384
385                 dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n",
386                         __func__, presponse_t->flags);
387
388                 dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n",
389                         __func__, presponse_t->size);
390
391                 /* Check if the response was for our command */
392                 if (presponse_t->seqno != pcommand_t->seqno) {
393
394                         dprintk(DBGLVL_CMD,
395                                 "wrong event: seqno = %d, "
396                                 "expected seqno = %d, "
397                                 "will dequeue regardless\n",
398                                 presponse_t->seqno, pcommand_t->seqno);
399
400                         ret = saa7164_cmd_dequeue(dev);
401                         if (ret != SAA_OK) {
402                                 printk(KERN_ERR "dequeue failed, ret = %d\n",
403                                         ret);
404                                 if (safety++ > 16) {
405                                         printk(KERN_ERR
406                                         "dequeue exceeded, safety exit\n");
407                                         return SAA_ERR_BUSY;
408                                 }
409                         }
410
411                         continue;
412                 }
413
414                 if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) {
415
416                         memset(&errdata[0], 0, sizeof(errdata));
417
418                         ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0);
419                         if (ret != SAA_OK) {
420                                 printk(KERN_ERR "get error(2)\n");
421                                 return ret;
422                         }
423
424                         saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
425
426                         dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n",
427                                 __func__, errdata[0], errdata[1], errdata[2],
428                                 errdata[3]);
429
430                         /* Map error codes */
431                         dprintk(DBGLVL_CMD, "%s() cmd, error code  = 0x%x\n",
432                                 __func__, errdata[0]);
433
434                         switch (errdata[0]) {
435                         case PVC_ERRORCODE_INVALID_COMMAND:
436                                 dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n",
437                                         __func__);
438                                 ret = SAA_ERR_INVALID_COMMAND;
439                                 break;
440                         case PVC_ERRORCODE_INVALID_DATA:
441                                 dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n",
442                                         __func__);
443                                 ret = SAA_ERR_BAD_PARAMETER;
444                                 break;
445                         case PVC_ERRORCODE_TIMEOUT:
446                                 dprintk(DBGLVL_CMD, "%s() TIMEOUT\n", __func__);
447                                 ret = SAA_ERR_TIMEOUT;
448                                 break;
449                         case PVC_ERRORCODE_NAK:
450                                 dprintk(DBGLVL_CMD, "%s() NAK\n", __func__);
451                                 ret = SAA_ERR_NULL_PACKET;
452                                 break;
453                         case PVC_ERRORCODE_UNKNOWN:
454                         case PVC_ERRORCODE_INVALID_CONTROL:
455                                 dprintk(DBGLVL_CMD,
456                                         "%s() UNKNOWN OR INVALID CONTROL\n",
457                                         __func__);
458                         default:
459                                 dprintk(DBGLVL_CMD, "%s() UNKNOWN\n", __func__);
460                                 ret = SAA_ERR_NOT_SUPPORTED;
461                         }
462
463                         /* See of other commands are on the bus */
464                         if (saa7164_cmd_dequeue(dev) != SAA_OK)
465                                 printk(KERN_ERR "dequeue(2) failed\n");
466
467                         return ret;
468                 }
469
470                 /* If response is invalid */
471                 if ((presponse_t->id != pcommand_t->id) ||
472                         (presponse_t->command != pcommand_t->command) ||
473                         (presponse_t->controlselector !=
474                                 pcommand_t->controlselector) ||
475                         (((resp_dsize - data_recd) != presponse_t->size) &&
476                                 !(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) ||
477                         ((resp_dsize - data_recd) < presponse_t->size)) {
478
479                         /* Invalid */
480                         dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
481                         ret = saa7164_bus_get(dev, presponse_t, 0, 0);
482                         if (ret != SAA_OK) {
483                                 printk(KERN_ERR "get failed\n");
484                                 return ret;
485                         }
486
487                         /* See of other commands are on the bus */
488                         if (saa7164_cmd_dequeue(dev) != SAA_OK)
489                                 printk(KERN_ERR "dequeue(3) failed\n");
490                         continue;
491                 }
492
493                 /* OK, now we're actually getting out correct response */
494                 ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0);
495                 if (ret != SAA_OK) {
496                         printk(KERN_ERR "get failed\n");
497                         return ret;
498                 }
499
500                 data_recd = presponse_t->size + data_recd;
501                 if (resp_dsize == data_recd) {
502                         dprintk(DBGLVL_CMD, "%s() Resp recd\n", __func__);
503                         break;
504                 }
505
506                 /* See of other commands are on the bus */
507                 if (saa7164_cmd_dequeue(dev) != SAA_OK)
508                         printk(KERN_ERR "dequeue(3) failed\n");
509
510                 continue;
511
512         } /* (loop) */
513
514         /* Release the sequence number allocation */
515         saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
516
517         /* if powerdown signal all pending commands */
518
519         dprintk(DBGLVL_CMD, "%s() Calling dequeue then exit\n", __func__);
520
521         /* See of other commands are on the bus */
522         if (saa7164_cmd_dequeue(dev) != SAA_OK)
523                 printk(KERN_ERR "dequeue(4) failed\n");
524
525         ret = SAA_OK;
526 out:
527         return ret;
528 }
529