Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.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_irq_dequeue(struct saa7164_dev *dev)
84 {
85         int ret = SAA_OK;
86         u32 timeout;
87         wait_queue_head_t *q = 0;
88         dprintk(DBGLVL_CMD, "%s()\n", __func__);
89
90         /* While any outstand message on the bus exists... */
91         do {
92
93                 /* Peek the msg bus */
94                 tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
95                 ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
96                 if (ret != SAA_OK)
97                         break;
98
99                 q = &dev->cmds[tRsp.seqno].wait;
100                 timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
101                 dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
102                 if (!timeout) {
103                         dprintk(DBGLVL_CMD,
104                                 "%s() signalled seqno(%d) (for dequeue)\n",
105                                 __func__, tRsp.seqno);
106                         dev->cmds[tRsp.seqno].signalled = 1;
107                         wake_up(q);
108                 } else {
109                         printk(KERN_ERR
110                                 "%s() found timed out command on the bus\n",
111                                         __func__);
112                 }
113         } while (0);
114
115         return ret;
116 }
117
118 /* Commands to the f/w get marshelled to/from this code then onto the PCI
119  * -bus/c running buffer. */
120 int saa7164_cmd_dequeue(struct saa7164_dev *dev)
121 {
122         int loop = 1;
123         int ret;
124         u32 timeout;
125         wait_queue_head_t *q = 0;
126         u8 tmp[512];
127         dprintk(DBGLVL_CMD, "%s()\n", __func__);
128
129         while (loop) {
130
131                 tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
132                 ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
133                 if (ret == SAA_ERR_EMPTY)
134                         return SAA_OK;
135
136                 if (ret != SAA_OK)
137                         return ret;
138
139                 q = &dev->cmds[tRsp.seqno].wait;
140                 timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
141                 dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
142                 if (timeout) {
143                         printk(KERN_ERR "found timed out command on the bus\n");
144
145                         /* Clean the bus */
146                         ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
147                         printk(KERN_ERR "ret = %x\n", ret);
148                         if (ret == SAA_ERR_EMPTY)
149                                 /* Someone else already fetched the response */
150                                 return SAA_OK;
151
152                         if (ret != SAA_OK)
153                                 return ret;
154
155                         if (tRsp.flags & PVC_CMDFLAG_CONTINUE)
156                                 printk(KERN_ERR "split response\n");
157                         else
158                                 saa7164_cmd_free_seqno(dev, tRsp.seqno);
159
160                         printk(KERN_ERR " timeout continue\n");
161                         continue;
162                 }
163
164                 dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n",
165                         __func__, tRsp.seqno);
166                 dev->cmds[tRsp.seqno].signalled = 1;
167                 wake_up(q);
168                 return SAA_OK;
169         }
170
171         return SAA_OK;
172 }
173
174 int saa7164_cmd_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
175 {
176         tmComResBusInfo_t *bus = &dev->bus;
177         u8 cmd_sent;
178         u16 size, idx;
179         u32 cmds;
180         void *tmp;
181         int ret = -1;
182
183         if (!msg) {
184                 printk(KERN_ERR "%s() !msg\n", __func__);
185                 return SAA_ERR_BAD_PARAMETER;
186         }
187
188         mutex_lock(&dev->cmds[msg->id].lock);
189
190         size = msg->size;
191         idx = 0;
192         cmds = size / bus->m_wMaxReqSize;
193         if (size % bus->m_wMaxReqSize == 0)
194                 cmds -= 1;
195
196         cmd_sent = 0;
197
198         /* Split the request into smaller chunks */
199         for (idx = 0; idx < cmds; idx++) {
200
201                 msg->flags |= SAA_CMDFLAG_CONTINUE;
202                 msg->size = bus->m_wMaxReqSize;
203                 tmp = buf + idx * bus->m_wMaxReqSize;
204
205                 ret = saa7164_bus_set(dev, msg, tmp);
206                 if (ret != SAA_OK) {
207                         printk(KERN_ERR "%s() set failed %d\n", __func__, ret);
208
209                         if (cmd_sent) {
210                                 ret = SAA_ERR_BUSY;
211                                 goto out;
212                         }
213                         ret = SAA_ERR_OVERFLOW;
214                         goto out;
215                 }
216                 cmd_sent = 1;
217         }
218
219         /* If not the last command... */
220         if (idx != 0)
221                 msg->flags &= ~SAA_CMDFLAG_CONTINUE;
222
223         msg->size = size - idx * bus->m_wMaxReqSize;
224
225         ret = saa7164_bus_set(dev, msg, buf + idx * bus->m_wMaxReqSize);
226         if (ret != SAA_OK) {
227                 printk(KERN_ERR "%s() set last failed %d\n", __func__, ret);
228
229                 if (cmd_sent) {
230                         ret = SAA_ERR_BUSY;
231                         goto out;
232                 }
233                 ret = SAA_ERR_OVERFLOW;
234                 goto out;
235         }
236         ret = SAA_OK;
237
238 out:
239         mutex_unlock(&dev->cmds[msg->id].lock);
240         return ret;
241 }
242
243 /* Wait for a signal event, without holding a mutex. Either return TIMEOUT if
244  * the event never occured, or SAA_OK if it was signaled during the wait.
245  */
246 int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
247 {
248         wait_queue_head_t *q = 0;
249         int ret = SAA_BUS_TIMEOUT;
250         unsigned long stamp;
251         int r;
252
253         if (saa_debug >= 4)
254                 saa7164_bus_dump(dev);
255
256         dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno);
257
258         mutex_lock(&dev->lock);
259         if ((dev->cmds[seqno].inuse == 1) &&
260                 (dev->cmds[seqno].seqno == seqno)) {
261                 q = &dev->cmds[seqno].wait;
262         }
263         mutex_unlock(&dev->lock);
264
265         if (q) {
266                 /* If we haven't been signalled we need to wait */
267                 if (dev->cmds[seqno].signalled == 0) {
268                         stamp = jiffies;
269                         dprintk(DBGLVL_CMD,
270                                 "%s(seqno=%d) Waiting (signalled=%d)\n",
271                                 __func__, seqno, dev->cmds[seqno].signalled);
272
273                         /* Wait for signalled to be flagged or timeout */
274                         /* In a highly stressed system this can easily extend
275                          * into multiple seconds before the deferred worker
276                          * is scheduled, and we're woken up via signal.
277                          * We typically are signalled in < 50ms but it can
278                          * take MUCH longer.
279                          */
280                         wait_event_timeout(*q, dev->cmds[seqno].signalled, (HZ * waitsecs));
281                         r = time_before(jiffies, stamp + (HZ * waitsecs));
282                         if (r)
283                                 ret = SAA_OK;
284                         else
285                                 saa7164_cmd_timeout_seqno(dev, seqno);
286
287                         dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d "
288                                 "(signalled=%d)\n", __func__, seqno, r,
289                                 dev->cmds[seqno].signalled);
290                 } else
291                         ret = SAA_OK;
292         } else
293                 printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n",
294                         __func__, seqno);
295
296         return ret;
297 }
298
299 void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno)
300 {
301         int i;
302         dprintk(DBGLVL_CMD, "%s()\n", __func__);
303
304         mutex_lock(&dev->lock);
305         for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
306                 if (dev->cmds[i].inuse == 1) {
307                         dprintk(DBGLVL_CMD,
308                                 "seqno %d inuse, sig = %d, t/out = %d\n",
309                                 dev->cmds[i].seqno,
310                                 dev->cmds[i].signalled,
311                                 dev->cmds[i].timeout);
312                 }
313         }
314
315         for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
316                 if ((dev->cmds[i].inuse == 1) && ((i == 0) ||
317                         (dev->cmds[i].signalled) || (dev->cmds[i].timeout))) {
318                         dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n",
319                                 __func__, i);
320                         dev->cmds[i].signalled = 1;
321                         wake_up(&dev->cmds[i].wait);
322                 }
323         }
324         mutex_unlock(&dev->lock);
325 }
326
327 int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, tmComResCmd_t command,
328         u16 controlselector, u16 size, void *buf)
329 {
330         tmComResInfo_t command_t, *pcommand_t;
331         tmComResInfo_t response_t, *presponse_t;
332         u8 errdata[256];
333         u16 resp_dsize;
334         u16 data_recd;
335         u32 loop;
336         int ret;
337         int safety = 0;
338
339         dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, "
340                 "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
341                 command, controlselector);
342
343         if ((size == 0) || (buf == 0)) {
344                 printk(KERN_ERR "%s() Invalid param\n", __func__);
345                 return SAA_ERR_BAD_PARAMETER;
346         }
347
348         /* Prepare some basic command/response structures */
349         memset(&command_t, 0, sizeof(command_t));
350         memset(&response_t, 0, sizeof(&response_t));
351         pcommand_t = &command_t;
352         presponse_t = &response_t;
353         command_t.id = id;
354         command_t.command = command;
355         command_t.controlselector = controlselector;
356         command_t.size = size;
357
358         /* Allocate a unique sequence number */
359         ret = saa7164_cmd_alloc_seqno(dev);
360         if (ret < 0) {
361                 printk(KERN_ERR "%s() No free sequences\n", __func__);
362                 ret = SAA_ERR_NO_RESOURCES;
363                 goto out;
364         }
365
366         command_t.seqno = (u8)ret;
367
368         /* Send Command */
369         resp_dsize = size;
370         pcommand_t->size = size;
371
372         dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n",
373                 __func__, pcommand_t->seqno);
374
375         dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n",
376                 __func__, pcommand_t->size);
377
378         ret = saa7164_cmd_set(dev, pcommand_t, buf);
379         if (ret != SAA_OK) {
380                 printk(KERN_ERR "%s() set command failed %d\n", __func__, ret);
381
382                 if (ret != SAA_ERR_BUSY)
383                         saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
384                 else
385                         /* Flag a timeout, because at least one
386                          * command was sent */
387                         saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
388
389                 goto out;
390         }
391
392         /* With split responses we have to collect the msgs piece by piece */
393         data_recd = 0;
394         loop = 1;
395         while (loop) {
396                 dprintk(DBGLVL_CMD, "%s() loop\n", __func__);
397
398                 ret = saa7164_cmd_wait(dev, pcommand_t->seqno);
399                 dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret);
400
401                 /* if power is down and this is not a power command ... */
402
403                 if (ret == SAA_BUS_TIMEOUT) {
404                         printk(KERN_ERR "Event timed out\n");
405                         saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
406                         return ret;
407                 }
408
409                 if (ret != SAA_OK) {
410                         printk(KERN_ERR "spurious error\n");
411                         return ret;
412                 }
413
414                 /* Peek response */
415                 ret = saa7164_bus_get(dev, presponse_t, NULL, 1);
416                 if (ret == SAA_ERR_EMPTY) {
417                         dprintk(4, "%s() SAA_ERR_EMPTY\n", __func__);
418                         continue;
419                 }
420                 if (ret != SAA_OK) {
421                         printk(KERN_ERR "peek failed\n");
422                         return ret;
423                 }
424
425                 dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n",
426                         __func__, presponse_t->seqno);
427
428                 dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n",
429                         __func__, presponse_t->flags);
430
431                 dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n",
432                         __func__, presponse_t->size);
433
434                 /* Check if the response was for our command */
435                 if (presponse_t->seqno != pcommand_t->seqno) {
436
437                         dprintk(DBGLVL_CMD,
438                                 "wrong event: seqno = %d, "
439                                 "expected seqno = %d, "
440                                 "will dequeue regardless\n",
441                                 presponse_t->seqno, pcommand_t->seqno);
442
443                         ret = saa7164_cmd_dequeue(dev);
444                         if (ret != SAA_OK) {
445                                 printk(KERN_ERR "dequeue failed, ret = %d\n",
446                                         ret);
447                                 if (safety++ > 16) {
448                                         printk(KERN_ERR
449                                         "dequeue exceeded, safety exit\n");
450                                         return SAA_ERR_BUSY;
451                                 }
452                         }
453
454                         continue;
455                 }
456
457                 if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) {
458
459                         memset(&errdata[0], 0, sizeof(errdata));
460
461                         ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0);
462                         if (ret != SAA_OK) {
463                                 printk(KERN_ERR "get error(2)\n");
464                                 return ret;
465                         }
466
467                         saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
468
469                         dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n",
470                                 __func__, errdata[0], errdata[1], errdata[2],
471                                 errdata[3]);
472
473                         /* Map error codes */
474                         dprintk(DBGLVL_CMD, "%s() cmd, error code  = 0x%x\n",
475                                 __func__, errdata[0]);
476
477                         switch (errdata[0]) {
478                         case PVC_ERRORCODE_INVALID_COMMAND:
479                                 dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n",
480                                         __func__);
481                                 ret = SAA_ERR_INVALID_COMMAND;
482                                 break;
483                         case PVC_ERRORCODE_INVALID_DATA:
484                                 dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n",
485                                         __func__);
486                                 ret = SAA_ERR_BAD_PARAMETER;
487                                 break;
488                         case PVC_ERRORCODE_TIMEOUT:
489                                 dprintk(DBGLVL_CMD, "%s() TIMEOUT\n", __func__);
490                                 ret = SAA_ERR_TIMEOUT;
491                                 break;
492                         case PVC_ERRORCODE_NAK:
493                                 dprintk(DBGLVL_CMD, "%s() NAK\n", __func__);
494                                 ret = SAA_ERR_NULL_PACKET;
495                                 break;
496                         case PVC_ERRORCODE_UNKNOWN:
497                         case PVC_ERRORCODE_INVALID_CONTROL:
498                                 dprintk(DBGLVL_CMD,
499                                         "%s() UNKNOWN OR INVALID CONTROL\n",
500                                         __func__);
501                         default:
502                                 dprintk(DBGLVL_CMD, "%s() UNKNOWN\n", __func__);
503                                 ret = SAA_ERR_NOT_SUPPORTED;
504                         }
505
506                         /* See of other commands are on the bus */
507                         if (saa7164_cmd_dequeue(dev) != SAA_OK)
508                                 printk(KERN_ERR "dequeue(2) failed\n");
509
510                         return ret;
511                 }
512
513                 /* If response is invalid */
514                 if ((presponse_t->id != pcommand_t->id) ||
515                         (presponse_t->command != pcommand_t->command) ||
516                         (presponse_t->controlselector !=
517                                 pcommand_t->controlselector) ||
518                         (((resp_dsize - data_recd) != presponse_t->size) &&
519                                 !(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) ||
520                         ((resp_dsize - data_recd) < presponse_t->size)) {
521
522                         /* Invalid */
523                         dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
524                         ret = saa7164_bus_get(dev, presponse_t, 0, 0);
525                         if (ret != SAA_OK) {
526                                 printk(KERN_ERR "get failed\n");
527                                 return ret;
528                         }
529
530                         /* See of other commands are on the bus */
531                         if (saa7164_cmd_dequeue(dev) != SAA_OK)
532                                 printk(KERN_ERR "dequeue(3) failed\n");
533                         continue;
534                 }
535
536                 /* OK, now we're actually getting out correct response */
537                 ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0);
538                 if (ret != SAA_OK) {
539                         printk(KERN_ERR "get failed\n");
540                         return ret;
541                 }
542
543                 data_recd = presponse_t->size + data_recd;
544                 if (resp_dsize == data_recd) {
545                         dprintk(DBGLVL_CMD, "%s() Resp recd\n", __func__);
546                         break;
547                 }
548
549                 /* See of other commands are on the bus */
550                 if (saa7164_cmd_dequeue(dev) != SAA_OK)
551                         printk(KERN_ERR "dequeue(3) failed\n");
552
553                 continue;
554
555         } /* (loop) */
556
557         /* Release the sequence number allocation */
558         saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
559
560         /* if powerdown signal all pending commands */
561
562         dprintk(DBGLVL_CMD, "%s() Calling dequeue then exit\n", __func__);
563
564         /* See of other commands are on the bus */
565         if (saa7164_cmd_dequeue(dev) != SAA_OK)
566                 printk(KERN_ERR "dequeue(4) failed\n");
567
568         ret = SAA_OK;
569 out:
570         return ret;
571 }
572