]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/plat-omap/dsp/task.c
ARM: OMAP: Adapt to new MMU framework
[linux-2.6-omap-h63xx.git] / arch / arm / plat-omap / dsp / task.c
1 /*
2  * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
3  *
4  * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
5  *
6  * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * 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., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/major.h>
28 #include <linux/fs.h>
29 #include <linux/poll.h>
30 #include <linux/platform_device.h>
31 #include <linux/slab.h>
32 #include <linux/sched.h>
33 #include <linux/mm.h>
34 #include <linux/mutex.h>
35 #include <linux/interrupt.h>
36 #include <asm/uaccess.h>
37 #include <asm/io.h>
38 #include <asm/arch/mailbox.h>
39 #include <asm/arch/dsp.h>
40 #include "uaccess_dsp.h"
41 #include "dsp_mbcmd.h"
42 #include "dsp.h"
43 #include "ipbuf.h"
44 #include "fifo.h"
45 #include "proclist.h"
46
47 #define is_aligned(adr,align)   (!((adr)&((align)-1)))
48
49 /*
50  * devstate: task device state machine
51  * NOTASK:      task is not attached.
52  * ATTACHED:    task is attached.
53  * GARBAGE:     task is detached. waiting for all processes to close this device.
54  * ADDREQ:      requesting for tadd
55  * DELREQ:      requesting for tdel. no process is opening this device.
56  * FREEZED:     task is attached, but reserved to be killed.
57  * ADDFAIL:     tadd failed.
58  * ADDING:      tadd in process.
59  * DELING:      tdel in process.
60  * KILLING:     tkill in process.
61  */
62 #define TASKDEV_ST_NOTASK       0x00000001
63 #define TASKDEV_ST_ATTACHED     0x00000002
64 #define TASKDEV_ST_GARBAGE      0x00000004
65 #define TASKDEV_ST_INVALID      0x00000008
66 #define TASKDEV_ST_ADDREQ       0x00000100
67 #define TASKDEV_ST_DELREQ       0x00000200
68 #define TASKDEV_ST_FREEZED      0x00000400
69 #define TASKDEV_ST_ADDFAIL      0x00001000
70 #define TASKDEV_ST_ADDING       0x00010000
71 #define TASKDEV_ST_DELING       0x00020000
72 #define TASKDEV_ST_KILLING      0x00040000
73 #define TASKDEV_ST_STATE_MASK   0x7fffffff
74 #define TASKDEV_ST_STALE        0x80000000
75
76 struct {
77         long state;
78         char *name;
79 } devstate_desc[] = {
80         { TASKDEV_ST_NOTASK,   "notask" },
81         { TASKDEV_ST_ATTACHED, "attached" },
82         { TASKDEV_ST_GARBAGE,  "garbage" },
83         { TASKDEV_ST_INVALID,  "invalid" },
84         { TASKDEV_ST_ADDREQ,   "addreq" },
85         { TASKDEV_ST_DELREQ,   "delreq" },
86         { TASKDEV_ST_FREEZED,  "freezed" },
87         { TASKDEV_ST_ADDFAIL,  "addfail" },
88         { TASKDEV_ST_ADDING,   "adding" },
89         { TASKDEV_ST_DELING,   "deling" },
90         { TASKDEV_ST_KILLING,  "killing" },
91 };
92
93 static char *devstate_name(long state) {
94         int i;
95         int max = ARRAY_SIZE(devstate_desc);
96
97         for (i = 0; i < max; i++) {
98                 if (state & devstate_desc[i].state)
99                         return devstate_desc[i].name;
100         }
101         return "unknown";
102 }
103
104 struct rcvdt_bk_struct {
105         struct ipblink link;
106         unsigned int rp;
107 };
108
109 struct taskdev {
110         struct bus_type *bus;
111         struct device dev;      /* Generic device interface */
112
113         long state;
114         struct rw_semaphore state_sem;
115         wait_queue_head_t state_wait_q;
116         struct mutex usecount_lock;
117         unsigned int usecount;
118         char name[TNM_LEN];
119         struct file_operations fops;
120         spinlock_t proc_list_lock;
121         struct list_head proc_list;
122         struct dsptask *task;
123
124         /* read stuff */
125         wait_queue_head_t read_wait_q;
126         struct mutex read_mutex;
127         union {
128                 struct fifo_struct fifo;        /* for active word */
129                 struct rcvdt_bk_struct bk;
130         } rcvdt;
131
132         /* write stuff */
133         wait_queue_head_t write_wait_q;
134         struct mutex write_mutex;
135         spinlock_t wsz_lock;
136         size_t wsz;
137
138         /* tctl stuff */
139         wait_queue_head_t tctl_wait_q;
140         struct mutex tctl_mutex;
141         int tctl_stat;
142         int tctl_ret;   /* return value for tctl_show() */
143
144         /* device lock */
145         struct mutex lock;
146         pid_t lock_pid;
147 };
148
149 #define to_taskdev(n) container_of(n, struct taskdev, dev)
150
151 struct dsptask {
152         enum {
153                 TASK_ST_ERR = 0,
154                 TASK_ST_READY,
155                 TASK_ST_CFGREQ
156         } state;
157         u8 tid;
158         char name[TNM_LEN];
159         u16 ttyp;
160         struct taskdev *dev;
161
162         /* read stuff */
163         struct ipbuf_p *ipbuf_pvt_r;
164
165         /* write stuff */
166         struct ipbuf_p *ipbuf_pvt_w;
167
168         /* mmap stuff */
169         void *map_base;
170         size_t map_length;
171 };
172
173 #define sndtyp_acv(ttyp)        ((ttyp) & TTYP_ASND)
174 #define sndtyp_psv(ttyp)        (!((ttyp) & TTYP_ASND))
175 #define sndtyp_bk(ttyp)         ((ttyp) & TTYP_BKDM)
176 #define sndtyp_wd(ttyp)         (!((ttyp) & TTYP_BKDM))
177 #define sndtyp_pvt(ttyp)        ((ttyp) & TTYP_PVDM)
178 #define sndtyp_gbl(ttyp)        (!((ttyp) & TTYP_PVDM))
179 #define rcvtyp_acv(ttyp)        ((ttyp) & TTYP_ARCV)
180 #define rcvtyp_psv(ttyp)        (!((ttyp) & TTYP_ARCV))
181 #define rcvtyp_bk(ttyp)         ((ttyp) & TTYP_BKMD)
182 #define rcvtyp_wd(ttyp)         (!((ttyp) & TTYP_BKMD))
183 #define rcvtyp_pvt(ttyp)        ((ttyp) & TTYP_PVMD)
184 #define rcvtyp_gbl(ttyp)        (!((ttyp) & TTYP_PVMD))
185
186 static __inline__ int has_taskdev_lock(struct taskdev *dev);
187 static int dsp_rmdev_minor(unsigned char minor);
188 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor);
189 static void taskdev_delete(unsigned char minor);
190 static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task);
191 static int dsp_tdel_bh(struct taskdev *dev, u16 type);
192
193 static struct bus_type dsptask_bus = {
194         .name = "dsptask",
195 };
196
197 static struct class *dsp_task_class;
198 static DEFINE_MUTEX(devmgr_lock);
199 static struct taskdev *taskdev[TASKDEV_MAX];
200 static struct dsptask *dsptask[TASKDEV_MAX];
201 static DEFINE_MUTEX(cfg_lock);
202 static u16 cfg_cmd;
203 static u8 cfg_tid;
204 static DECLARE_WAIT_QUEUE_HEAD(cfg_wait_q);
205 static u8 n_task;       /* static task count */
206 static void *heap;
207
208 #define is_dynamic_task(tid)    ((tid) >= n_task)
209
210 #define devstate_read_lock(dev, devstate) \
211                 devstate_read_lock_timeout(dev, devstate, 0)
212 #define devstate_read_unlock(dev)       up_read(&(dev)->state_sem)
213 #define devstate_write_lock(dev, devstate) \
214                 devstate_write_lock_timeout(dev, devstate, 0)
215 #define devstate_write_unlock(dev)      up_write(&(dev)->state_sem)
216
217 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
218                             char *buf);
219 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
220                              char *buf);
221 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
222                               char *buf);
223 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
224                              char *buf);
225 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
226                          char *buf);
227 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
228                            char *buf);
229 static int fifosz_store(struct device *d, struct device_attribute *attr,
230                         const char *buf, size_t count);
231 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
232                             char *buf);
233 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
234                             char *buf);
235 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
236                         char *buf);
237 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
238                          char *buf);
239
240 #define __ATTR_RW(_name,_mode) { \
241         .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },     \
242         .show   = _name##_show,                                 \
243         .store  = _name##_store,                                        \
244 }
245
246 static struct device_attribute dev_attr_devname   = __ATTR_RO(devname);
247 static struct device_attribute dev_attr_devstate  = __ATTR_RO(devstate);
248 static struct device_attribute dev_attr_proc_list = __ATTR_RO(proc_list);
249 static struct device_attribute dev_attr_taskname  = __ATTR_RO(taskname);
250 static struct device_attribute dev_attr_ttyp      = __ATTR_RO(ttyp);
251 static struct device_attribute dev_attr_fifosz    = __ATTR_RW(fifosz, 0666);
252 static struct device_attribute dev_attr_fifocnt   = __ATTR_RO(fifocnt);
253 static struct device_attribute dev_attr_ipblink   = __ATTR_RO(ipblink);
254 static struct device_attribute dev_attr_wsz       = __ATTR_RO(wsz);
255 static struct device_attribute dev_attr_mmap      = __ATTR_RO(mmap);
256
257 /*
258  * devstate_read_lock_timeout()
259  * devstate_write_lock_timeout():
260  * timeout != 0: dev->state can be diffeent from what you want.
261  * timeout == 0: no timeout
262  */
263 static int devstate_read_lock_timeout(struct taskdev *dev, long devstate,
264                                       int timeout)
265 {
266         DECLARE_WAITQUEUE(wait, current);
267         long current_state = current->state;
268         int ret = 0;
269
270         down_read(&dev->state_sem);
271         if (dev->state & devstate)
272                 return 0;
273
274         add_wait_queue(&dev->state_wait_q, &wait);
275         do {
276                 set_current_state(TASK_INTERRUPTIBLE);
277                 up_read(&dev->state_sem);
278                 if (timeout) {
279                         if ((timeout = schedule_timeout(timeout)) == 0) {
280                                 /* timeout */
281                                 down_read(&dev->state_sem);
282                                 break;
283                         }
284                 } else
285                         schedule();
286                 if (signal_pending(current)) {
287                         ret = -EINTR;
288                         break;
289                 }
290                 down_read(&dev->state_sem);
291         } while (!(dev->state & devstate));
292         remove_wait_queue(&dev->state_wait_q, &wait);
293         set_current_state(current_state);
294         return ret;
295 }
296
297 static int devstate_read_lock_and_test(struct taskdev *dev, long devstate)
298 {
299         down_read(&dev->state_sem);
300         if (dev->state & devstate)
301                 return 1;       /* success */
302         /* failure */
303         up_read(&dev->state_sem);
304         return 0;
305 }
306
307 static int devstate_write_lock_timeout(struct taskdev *dev, long devstate,
308                                        int timeout)
309 {
310         DECLARE_WAITQUEUE(wait, current);
311         long current_state = current->state;
312         int ret = 0;
313
314         down_write(&dev->state_sem);
315         if (dev->state & devstate)
316                 return 0;
317
318         add_wait_queue(&dev->state_wait_q, &wait);
319         do {
320                 set_current_state(TASK_INTERRUPTIBLE);
321                 up_write(&dev->state_sem);
322                 if (timeout) {
323                         if ((timeout = schedule_timeout(timeout)) == 0) {
324                                 /* timeout */
325                                 down_write(&dev->state_sem);
326                                 break;
327                         }
328                 } else
329                         schedule();
330                 if (signal_pending(current)) {
331                         ret = -EINTR;
332                         break;
333                 }
334                 down_write(&dev->state_sem);
335         } while (!(dev->state & devstate));
336         remove_wait_queue(&dev->state_wait_q, &wait);
337         set_current_state(current_state);
338         return ret;
339 }
340
341 static int devstate_write_lock_and_test(struct taskdev *dev, long devstate)
342 {
343         down_write(&dev->state_sem);
344         if (dev->state & devstate)      /* success */
345                 return 1;
346
347         /* failure */
348         up_write(&dev->state_sem);
349         return -1;
350 }
351
352 static int taskdev_lock_interruptible(struct taskdev *dev,
353                                       struct mutex *lock)
354 {
355         int ret;
356
357         if (has_taskdev_lock(dev))
358                 ret = mutex_lock_interruptible(lock);
359         else {
360                 if ((ret = mutex_lock_interruptible(&dev->lock)) != 0)
361                         return ret;
362                 ret = mutex_lock_interruptible(lock);
363                 mutex_unlock(&dev->lock);
364         }
365
366         return ret;
367 }
368
369 static int taskdev_lock_and_statelock_attached(struct taskdev *dev,
370                                                struct mutex *lock)
371 {
372         int ret;
373
374         if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
375                 return -ENODEV;
376
377         if ((ret = taskdev_lock_interruptible(dev, lock)) != 0)
378                 devstate_read_unlock(dev);
379
380         return ret;
381 }
382
383 static __inline__ void taskdev_unlock_and_stateunlock(struct taskdev *dev,
384                                                       struct mutex *lock)
385 {
386         mutex_unlock(lock);
387         devstate_read_unlock(dev);
388 }
389
390 /*
391  * taskdev_flush_buf()
392  * must be called under state_lock(ATTACHED) and dev->read_mutex.
393  */
394 static int taskdev_flush_buf(struct taskdev *dev)
395 {
396         u16 ttyp = dev->task->ttyp;
397
398         if (sndtyp_wd(ttyp)) {
399                 /* word receiving */
400                 flush_fifo(&dev->rcvdt.fifo);
401         } else {
402                 /* block receiving */
403                 struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
404
405                 if (sndtyp_gbl(ttyp))
406                         ipblink_flush(&rcvdt->link);
407                 else {
408                         ipblink_flush_pvt(&rcvdt->link);
409                         release_ipbuf_pvt(dev->task->ipbuf_pvt_r);
410                 }
411         }
412
413         return 0;
414 }
415
416 /*
417  * taskdev_set_fifosz()
418  * must be called under dev->read_mutex.
419  */
420 static int taskdev_set_fifosz(struct taskdev *dev, unsigned long sz)
421 {
422         u16 ttyp = dev->task->ttyp;
423         int stat;
424
425         if (!(sndtyp_wd(ttyp) && sndtyp_acv(ttyp))) {
426                 printk(KERN_ERR
427                        "omapdsp: buffer size can be changed only for "
428                        "active word sending task.\n");
429                 return -EINVAL;
430         }
431         if ((sz == 0) || (sz & 1)) {
432                 printk(KERN_ERR "omapdsp: illegal buffer size! (%ld)\n"
433                                 "it must be even and non-zero value.\n", sz);
434                 return -EINVAL;
435         }
436
437         stat = realloc_fifo(&dev->rcvdt.fifo, sz);
438         if (stat == -EBUSY) {
439                 printk(KERN_ERR "omapdsp: buffer is not empty!\n");
440                 return stat;
441         } else if (stat < 0) {
442                 printk(KERN_ERR
443                        "omapdsp: unable to change receive buffer size. "
444                        "(%ld bytes for %s)\n", sz, dev->name);
445                 return stat;
446         }
447
448         return 0;
449 }
450
451 static __inline__ int has_taskdev_lock(struct taskdev *dev)
452 {
453         return (dev->lock_pid == current->pid);
454 }
455
456 static int taskdev_lock(struct taskdev *dev)
457 {
458         if (mutex_lock_interruptible(&dev->lock))
459                 return -EINTR;
460         dev->lock_pid = current->pid;
461         return 0;
462 }
463
464 static int taskdev_unlock(struct taskdev *dev)
465 {
466         if (!has_taskdev_lock(dev)) {
467                 printk(KERN_ERR
468                        "omapdsp: an illegal process attempted to "
469                        "unlock the dsptask lock!\n");
470                 return -EINVAL;
471         }
472         dev->lock_pid = 0;
473         mutex_unlock(&dev->lock);
474         return 0;
475 }
476
477 static int dsp_task_config(struct dsptask *task, u8 tid)
478 {
479         u16 ttyp;
480         int ret;
481
482         task->tid = tid;
483         dsptask[tid] = task;
484
485         /* TCFG request */
486         task->state = TASK_ST_CFGREQ;
487         if (mutex_lock_interruptible(&cfg_lock)) {
488                 ret = -EINTR;
489                 goto fail_out;
490         }
491         cfg_cmd = MBOX_CMD_DSP_TCFG;
492         mbcompose_send_and_wait(TCFG, tid, 0, &cfg_wait_q);
493         cfg_cmd = 0;
494         mutex_unlock(&cfg_lock);
495
496         if (task->state != TASK_ST_READY) {
497                 printk(KERN_ERR "omapdsp: task %d configuration error!\n", tid);
498                 ret = -EINVAL;
499                 goto fail_out;
500         }
501
502         if (strlen(task->name) <= 1)
503                 sprintf(task->name, "%d", tid);
504         printk(KERN_INFO "omapdsp: task %d: name %s\n", tid, task->name);
505
506         ttyp = task->ttyp;
507
508         /*
509          * task info sanity check
510          */
511
512         /* task type check */
513         if (rcvtyp_psv(ttyp) && rcvtyp_pvt(ttyp)) {
514                 printk(KERN_ERR "omapdsp: illegal task type(0x%04x), tid=%d\n",
515                        tid, ttyp);
516                 ret = -EINVAL;
517                 goto fail_out;
518         }
519
520         /* private buffer address check */
521         if (sndtyp_pvt(ttyp) &&
522             (ipbuf_p_validate(task->ipbuf_pvt_r, DIR_D2A) < 0)) {
523                 ret = -EINVAL;
524                 goto fail_out;
525         }
526         if (rcvtyp_pvt(ttyp) &&
527             (ipbuf_p_validate(task->ipbuf_pvt_w, DIR_A2D) < 0)) {
528                 ret = -EINVAL;
529                 goto fail_out;
530         }
531
532         /* mmap buffer configuration check */
533         if ((task->map_length > 0) &&
534             ((!is_aligned((unsigned long)task->map_base, PAGE_SIZE)) ||
535              (!is_aligned(task->map_length, PAGE_SIZE)) ||
536              (dsp_mem_type(task->map_base, task->map_length) != MEM_TYPE_EXTERN))) {
537                 printk(KERN_ERR
538                        "omapdsp: illegal mmap buffer address(0x%p) or "
539                        "length(0x%x).\n"
540                        "  It needs to be page-aligned and located at "
541                        "external memory.\n",
542                        task->map_base, task->map_length);
543                 ret = -EINVAL;
544                 goto fail_out;
545         }
546
547         return 0;
548
549 fail_out:
550         dsptask[tid] = NULL;
551         return ret;
552 }
553
554 static void dsp_task_init(struct dsptask *task)
555 {
556         mbcompose_send(TCTL, task->tid, TCTL_TINIT);
557 }
558
559 int dsp_task_config_all(u8 n)
560 {
561         int i, ret;
562         struct taskdev *devheap;
563         struct dsptask *taskheap;
564         size_t devheapsz, taskheapsz;
565
566         printk(KERN_INFO "omapdsp: found %d task(s)\n", n);
567         if (n == 0)
568                 return 0;
569
570         /*
571          * reducing kmalloc!
572          */
573         devheapsz  = sizeof(struct taskdev) * n;
574         taskheapsz = sizeof(struct dsptask) * n;
575         heap = kzalloc(devheapsz + taskheapsz, GFP_KERNEL);
576         if (heap == NULL)
577                 return -ENOMEM;
578         devheap  = heap;
579         taskheap = heap + devheapsz;
580
581         n_task = n;
582         for (i = 0; i < n; i++) {
583                 struct taskdev *dev  = &devheap[i];
584                 struct dsptask *task = &taskheap[i];
585
586                 if ((ret = dsp_task_config(task, i)) < 0)
587                         return ret;
588                 if ((ret = taskdev_init(dev, task->name, i)) < 0)
589                         return ret;
590                 if ((ret = taskdev_attach_task(dev, task)) < 0)
591                         return ret;
592                 dsp_task_init(task);
593                 printk(KERN_INFO "omapdsp: taskdev %s enabled.\n", dev->name);
594         }
595
596         return 0;
597 }
598
599 static void dsp_task_unconfig(struct dsptask *task)
600 {
601         dsptask[task->tid] = NULL;
602 }
603
604 void dsp_task_unconfig_all(void)
605 {
606         unsigned char minor;
607         u8 tid;
608         struct dsptask *task;
609
610         for (minor = 0; minor < n_task; minor++) {
611                 /*
612                  * taskdev[minor] can be NULL in case of
613                  * configuration failure
614                  */
615                 if (taskdev[minor])
616                         taskdev_delete(minor);
617         }
618         for (; minor < TASKDEV_MAX; minor++) {
619                 if (taskdev[minor])
620                         dsp_rmdev_minor(minor);
621         }
622
623         for (tid = 0; tid < n_task; tid++) {
624                 /*
625                  * dsptask[tid] can be NULL in case of
626                  * configuration failure
627                  */
628                 task = dsptask[tid];
629                 if (task)
630                         dsp_task_unconfig(task);
631         }
632         for (; tid < TASKDEV_MAX; tid++) {
633                 task = dsptask[tid];
634                 if (task) {
635                         /*
636                          * on-demand tasks should be deleted in
637                          * rmdev_minor(), but just in case.
638                          */
639                         dsp_task_unconfig(task);
640                         kfree(task);
641                 }
642         }
643
644         if (heap) {
645                 kfree(heap);
646                 heap = NULL;
647         }
648
649         n_task = 0;
650 }
651
652 static struct device_driver dsptask_driver = {
653         .name   = "dsptask",
654         .bus    = &dsptask_bus,
655 };
656
657 u8 dsp_task_count(void)
658 {
659         return n_task;
660 }
661
662 int dsp_taskmod_busy(void)
663 {
664         struct taskdev *dev;
665         unsigned char minor;
666         unsigned int usecount;
667
668         for (minor = 0; minor < TASKDEV_MAX; minor++) {
669                 dev = taskdev[minor];
670                 if (dev == NULL)
671                         continue;
672                 if ((usecount = dev->usecount) > 0) {
673                         printk("dsp_taskmod_busy(): %s: usecount=%d\n",
674                                dev->name, usecount);
675                         return 1;
676                 }
677 /*
678                 if ((dev->state & (TASKDEV_ST_ADDREQ |
679                                    TASKDEV_ST_DELREQ)) {
680 */
681                 if (dev->state & TASKDEV_ST_ADDREQ) {
682                         printk("dsp_taskmod_busy(): %s is in %s\n",
683                                dev->name, devstate_name(dev->state));
684                         return 1;
685                 }
686         }
687         return 0;
688 }
689
690 /*
691  * DSP task device file operations
692  */
693 static ssize_t dsp_task_read_wd_acv(struct file *file, char __user *buf,
694                                     size_t count, loff_t *ppos)
695 {
696         unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
697         struct taskdev *dev = taskdev[minor];
698         int ret = 0;
699
700         if (count == 0) {
701                 return 0;
702         } else if (count & 0x1) {
703                 printk(KERN_ERR
704                        "omapdsp: odd count is illegal for DSP task device.\n");
705                 return -EINVAL;
706         }
707
708         if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
709                 return -ENODEV;
710
711         if (fifo_empty(&dev->rcvdt.fifo)) {
712                 long current_state = current->state;
713                 DECLARE_WAITQUEUE(wait, current);
714
715                 set_current_state(TASK_INTERRUPTIBLE);
716                 add_wait_queue(&dev->read_wait_q, &wait);
717                 if (fifo_empty(&dev->rcvdt.fifo))       /* last check */
718                         schedule();
719                 set_current_state(current_state);
720                 remove_wait_queue(&dev->read_wait_q, &wait);
721                 if (fifo_empty(&dev->rcvdt.fifo)) {
722                         /* failure */
723                         if (signal_pending(current))
724                                 ret = -EINTR;
725                         goto up_out;
726                 }
727         }
728
729         ret = copy_to_user_fm_fifo(buf, &dev->rcvdt.fifo, count);
730
731 up_out:
732         taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
733         return ret;
734 }
735
736 static ssize_t dsp_task_read_bk_acv(struct file *file, char __user *buf,
737                                     size_t count, loff_t *ppos)
738 {
739         unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
740         struct taskdev *dev = taskdev[minor];
741         struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
742         ssize_t ret = 0;
743
744         if (count == 0) {
745                 return 0;
746         } else if (count & 0x1) {
747                 printk(KERN_ERR
748                        "omapdsp: odd count is illegal for DSP task device.\n");
749                 return -EINVAL;
750         } else if ((int)buf & 0x1) {
751                 printk(KERN_ERR
752                        "omapdsp: buf should be word aligned for "
753                        "dsp_task_read().\n");
754                 return -EINVAL;
755         }
756
757         if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
758                 return -ENODEV;
759
760         if (ipblink_empty(&rcvdt->link)) {
761                 long current_state;
762                 DECLARE_WAITQUEUE(wait, current);
763
764                 add_wait_queue(&dev->read_wait_q, &wait);
765                 current_state = current->state;
766                 set_current_state(TASK_INTERRUPTIBLE);
767                 if (ipblink_empty(&rcvdt->link))        /* last check */
768                         schedule();
769                 set_current_state(current_state);
770                 remove_wait_queue(&dev->read_wait_q, &wait);
771                 if (ipblink_empty(&rcvdt->link)) {
772                         /* failure */
773                         if (signal_pending(current))
774                                 ret = -EINTR;
775                         goto up_out;
776                 }
777         }
778
779         /* copy from delayed IPBUF */
780         if (sndtyp_pvt(dev->task->ttyp)) {
781                 /* private */
782                 if (!ipblink_empty(&rcvdt->link)) {
783                         struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_r;
784                         unsigned char *base, *src;
785                         size_t bkcnt;
786
787                         if (dsp_mem_enable(ipbp) < 0) {
788                                 ret = -EBUSY;
789                                 goto up_out;
790                         }
791                         base = MKVIRT(ipbp->ah, ipbp->al);
792                         bkcnt = ((unsigned long)ipbp->c) * 2 - rcvdt->rp;
793                         if (dsp_address_validate(base, bkcnt,
794                                                  "task %s read buffer",
795                                                  dev->task->name) < 0) {
796                                 ret = -EINVAL;
797                                 goto pv_out1;
798                         }
799                         if (dsp_mem_enable(base) < 0) {
800                                 ret = -EBUSY;
801                                 goto pv_out1;
802                         }
803                         src = base + rcvdt->rp;
804                         if (bkcnt > count) {
805                                 if (copy_to_user_dsp(buf, src, count)) {
806                                         ret = -EFAULT;
807                                         goto pv_out2;
808                                 }
809                                 ret = count;
810                                 rcvdt->rp += count;
811                         } else {
812                                 if (copy_to_user_dsp(buf, src, bkcnt)) {
813                                         ret = -EFAULT;
814                                         goto pv_out2;
815                                 }
816                                 ret = bkcnt;
817                                 ipblink_del_pvt(&rcvdt->link);
818                                 release_ipbuf_pvt(ipbp);
819                                 rcvdt->rp = 0;
820                         }
821 pv_out2:
822                         dsp_mem_disable(src);
823 pv_out1:
824                         dsp_mem_disable(ipbp);
825                 }
826         } else {
827                 /* global */
828                 if (dsp_mem_enable_ipbuf() < 0) {
829                         ret = -EBUSY;
830                         goto up_out;
831                 }
832                 while (!ipblink_empty(&rcvdt->link)) {
833                         unsigned char *src;
834                         size_t bkcnt;
835                         struct ipbuf_head *ipb_h = bid_to_ipbuf(rcvdt->link.top);
836
837                         src = ipb_h->p->d + rcvdt->rp;
838                         bkcnt = ((unsigned long)ipb_h->p->c) * 2 - rcvdt->rp;
839                         if (bkcnt > count) {
840                                 if (copy_to_user_dsp(buf, src, count)) {
841                                         ret = -EFAULT;
842                                         goto gb_out;
843                                 }
844                                 ret += count;
845                                 rcvdt->rp += count;
846                                 break;
847                         } else {
848                                 if (copy_to_user_dsp(buf, src, bkcnt)) {
849                                         ret = -EFAULT;
850                                         goto gb_out;
851                                 }
852                                 ret += bkcnt;
853                                 buf += bkcnt;
854                                 count -= bkcnt;
855                                 ipblink_del_top(&rcvdt->link);
856                                 unuse_ipbuf(ipb_h);
857                                 rcvdt->rp = 0;
858                         }
859                 }
860 gb_out:
861                 dsp_mem_disable_ipbuf();
862         }
863
864 up_out:
865         taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
866         return ret;
867 }
868
869 static ssize_t dsp_task_read_wd_psv(struct file *file, char __user *buf,
870                                     size_t count, loff_t *ppos)
871 {
872         unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
873         struct taskdev *dev = taskdev[minor];
874         int ret = 0;
875
876         if (count == 0) {
877                 return 0;
878         } else if (count & 0x1) {
879                 printk(KERN_ERR
880                        "omapdsp: odd count is illegal for DSP task device.\n");
881                 return -EINVAL;
882         } else {
883                 /* force! */
884                 count = 2;
885         }
886
887         if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
888                 return -ENODEV;
889
890         mbcompose_send_and_wait(WDREQ, dev->task->tid, 0, &dev->read_wait_q);
891
892         if (fifo_empty(&dev->rcvdt.fifo)) {
893                 /* failure */
894                 if (signal_pending(current))
895                         ret = -EINTR;
896                 goto up_out;
897         }
898
899         ret = copy_to_user_fm_fifo(buf, &dev->rcvdt.fifo, count);
900
901 up_out:
902         taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
903         return ret;
904 }
905
906 static ssize_t dsp_task_read_bk_psv(struct file *file, char __user *buf,
907                                     size_t count, loff_t *ppos)
908 {
909         unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
910         struct taskdev *dev = taskdev[minor];
911         struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
912         int ret = 0;
913
914         if (count == 0) {
915                 return 0;
916         } else if (count & 0x1) {
917                 printk(KERN_ERR
918                        "omapdsp: odd count is illegal for DSP task device.\n");
919                 return -EINVAL;
920         } else if ((int)buf & 0x1) {
921                 printk(KERN_ERR
922                        "omapdsp: buf should be word aligned for "
923                        "dsp_task_read().\n");
924                 return -EINVAL;
925         }
926
927         if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
928                 return -ENODEV;
929
930         mbcompose_send_and_wait(BKREQ, dev->task->tid, count/2,
931                                 &dev->read_wait_q);
932
933         if (ipblink_empty(&rcvdt->link)) {
934                 /* failure */
935                 if (signal_pending(current))
936                         ret = -EINTR;
937                 goto up_out;
938         }
939
940         /*
941          * We will not receive more than requested count.
942          */
943         if (sndtyp_pvt(dev->task->ttyp)) {
944                 /* private */
945                 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_r;
946                 size_t rcvcnt;
947                 void *src;
948
949                 if (dsp_mem_enable(ipbp) < 0) {
950                         ret = -EBUSY;
951                         goto up_out;
952                 }
953                 src = MKVIRT(ipbp->ah, ipbp->al);
954                 rcvcnt = ((unsigned long)ipbp->c) * 2;
955                 if (dsp_address_validate(src, rcvcnt, "task %s read buffer",
956                                          dev->task->name) < 0) {
957                         ret = -EINVAL;
958                         goto pv_out1;
959                 }
960                 if (dsp_mem_enable(src) < 0) {
961                         ret = -EBUSY;
962                         goto pv_out1;
963                 }
964                 if (count > rcvcnt)
965                         count = rcvcnt;
966                 if (copy_to_user_dsp(buf, src, count)) {
967                         ret = -EFAULT;
968                         goto pv_out2;
969                 }
970                 ipblink_del_pvt(&rcvdt->link);
971                 release_ipbuf_pvt(ipbp);
972                 ret = count;
973 pv_out2:
974                 dsp_mem_disable(src);
975 pv_out1:
976                 dsp_mem_disable(ipbp);
977         } else {
978                 /* global */
979                 struct ipbuf_head *ipb_h = bid_to_ipbuf(rcvdt->link.top);
980                 size_t rcvcnt;
981
982                 if (dsp_mem_enable_ipbuf() < 0) {
983                         ret = -EBUSY;
984                         goto up_out;
985                 }
986                 rcvcnt = ((unsigned long)ipb_h->p->c) * 2;
987                 if (count > rcvcnt)
988                         count = rcvcnt;
989                 if (copy_to_user_dsp(buf, ipb_h->p->d, count)) {
990                         ret = -EFAULT;
991                         goto gb_out;
992                 }
993                 ipblink_del_top(&rcvdt->link);
994                 unuse_ipbuf(ipb_h);
995                 ret = count;
996 gb_out:
997                 dsp_mem_disable_ipbuf();
998         }
999
1000 up_out:
1001         taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
1002         return ret;
1003 }
1004
1005 static ssize_t dsp_task_write_wd(struct file *file, const char __user *buf,
1006                                  size_t count, loff_t *ppos)
1007 {
1008         unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1009         struct taskdev *dev = taskdev[minor];
1010         u16 wd;
1011         int ret = 0;
1012
1013         if (count == 0) {
1014                 return 0;
1015         } else if (count & 0x1) {
1016                 printk(KERN_ERR
1017                        "omapdsp: odd count is illegal for DSP task device.\n");
1018                 return -EINVAL;
1019         } else {
1020                 /* force! */
1021                 count = 2;
1022         }
1023
1024         if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex))
1025                 return -ENODEV;
1026
1027         if (dev->wsz == 0) {
1028                 long current_state;
1029                 DECLARE_WAITQUEUE(wait, current);
1030
1031                 add_wait_queue(&dev->write_wait_q, &wait);
1032                 current_state = current->state;
1033                 set_current_state(TASK_INTERRUPTIBLE);
1034                 if (dev->wsz == 0)      /* last check */
1035                         schedule();
1036                 set_current_state(current_state);
1037                 remove_wait_queue(&dev->write_wait_q, &wait);
1038                 if (dev->wsz == 0) {
1039                         /* failure */
1040                         if (signal_pending(current))
1041                                 ret = -EINTR;
1042                         goto up_out;
1043                 }
1044         }
1045
1046         if (copy_from_user(&wd, buf, count)) {
1047                 ret = -EFAULT;
1048                 goto up_out;
1049         }
1050
1051         spin_lock(&dev->wsz_lock);
1052         if (mbcompose_send(WDSND, dev->task->tid, wd) < 0) {
1053                 spin_unlock(&dev->wsz_lock);
1054                 goto up_out;
1055         }
1056         ret = count;
1057         if (rcvtyp_acv(dev->task->ttyp))
1058                 dev->wsz = 0;
1059         spin_unlock(&dev->wsz_lock);
1060
1061 up_out:
1062         taskdev_unlock_and_stateunlock(dev, &dev->write_mutex);
1063         return ret;
1064 }
1065
1066 static ssize_t dsp_task_write_bk(struct file *file, const char __user *buf,
1067                                  size_t count, loff_t *ppos)
1068 {
1069         unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1070         struct taskdev *dev = taskdev[minor];
1071         int ret = 0;
1072
1073         if (count == 0) {
1074                 return 0;
1075         } else if (count & 0x1) {
1076                 printk(KERN_ERR
1077                        "omapdsp: odd count is illegal for DSP task device.\n");
1078                 return -EINVAL;
1079         } else if ((int)buf & 0x1) {
1080                 printk(KERN_ERR
1081                        "omapdsp: buf should be word aligned for "
1082                        "dsp_task_write().\n");
1083                 return -EINVAL;
1084         }
1085
1086         if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex))
1087                 return -ENODEV;
1088
1089         if (dev->wsz == 0) {
1090                 long current_state;
1091                 DECLARE_WAITQUEUE(wait, current);
1092
1093                 add_wait_queue(&dev->write_wait_q, &wait);
1094                 current_state = current->state;
1095                 set_current_state(TASK_INTERRUPTIBLE);
1096                 if (dev->wsz == 0)      /* last check */
1097                         schedule();
1098                 set_current_state(current_state);
1099                 remove_wait_queue(&dev->write_wait_q, &wait);
1100                 if (dev->wsz == 0) {
1101                         /* failure */
1102                         if (signal_pending(current))
1103                                 ret = -EINTR;
1104                         goto up_out;
1105                 }
1106         }
1107
1108         if (count > dev->wsz)
1109                 count = dev->wsz;
1110
1111         if (rcvtyp_pvt(dev->task->ttyp)) {
1112                 /* private */
1113                 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_w;
1114                 unsigned char *dst;
1115
1116                 if (dsp_mem_enable(ipbp) < 0) {
1117                         ret = -EBUSY;
1118                         goto up_out;
1119                 }
1120                 dst = MKVIRT(ipbp->ah, ipbp->al);
1121                 if (dsp_address_validate(dst, count, "task %s write buffer",
1122                                          dev->task->name) < 0) {
1123                         ret = -EINVAL;
1124                         goto pv_out1;
1125                 }
1126                 if (dsp_mem_enable(dst) < 0) {
1127                         ret = -EBUSY;
1128                         goto pv_out1;
1129                 }
1130                 if (copy_from_user_dsp(dst, buf, count)) {
1131                         ret = -EFAULT;
1132                         goto pv_out2;
1133                 }
1134                 ipbp->c = count/2;
1135                 ipbp->s = dev->task->tid;
1136                 spin_lock(&dev->wsz_lock);
1137                 if (mbcompose_send(BKSNDP, dev->task->tid, 0) == 0) {
1138                         if (rcvtyp_acv(dev->task->ttyp))
1139                                 dev->wsz = 0;
1140                         ret = count;
1141                 }
1142                 spin_unlock(&dev->wsz_lock);
1143 pv_out2:
1144                 dsp_mem_disable(dst);
1145 pv_out1:
1146                 dsp_mem_disable(ipbp);
1147         } else {
1148                 /* global */
1149                 struct ipbuf_head *ipb_h;
1150
1151                 if (dsp_mem_enable_ipbuf() < 0) {
1152                         ret = -EBUSY;
1153                         goto up_out;
1154                 }
1155                 if ((ipb_h = get_free_ipbuf(dev->task->tid)) == NULL)
1156                         goto gb_out;
1157                 if (copy_from_user_dsp(ipb_h->p->d, buf, count)) {
1158                         release_ipbuf(ipb_h);
1159                         ret = -EFAULT;
1160                         goto gb_out;
1161                 }
1162                 ipb_h->p->c  = count/2;
1163                 ipb_h->p->sa = dev->task->tid;
1164                 spin_lock(&dev->wsz_lock);
1165                 if (mbcompose_send(BKSND, dev->task->tid, ipb_h->bid) == 0) {
1166                         if (rcvtyp_acv(dev->task->ttyp))
1167                                 dev->wsz = 0;
1168                         ret = count;
1169                         ipb_bsycnt_inc(&ipbcfg);
1170                 } else
1171                         release_ipbuf(ipb_h);
1172                 spin_unlock(&dev->wsz_lock);
1173 gb_out:
1174                 dsp_mem_disable_ipbuf();
1175         }
1176
1177 up_out:
1178         taskdev_unlock_and_stateunlock(dev, &dev->write_mutex);
1179         return ret;
1180 }
1181
1182 static unsigned int dsp_task_poll(struct file * file, poll_table * wait)
1183 {
1184         unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1185         struct taskdev *dev = taskdev[minor];
1186         struct dsptask *task = dev->task;
1187         unsigned int mask = 0;
1188
1189         if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
1190                 return 0;
1191         poll_wait(file, &dev->read_wait_q, wait);
1192         poll_wait(file, &dev->write_wait_q, wait);
1193         if (sndtyp_psv(task->ttyp) ||
1194             (sndtyp_wd(task->ttyp) && !fifo_empty(&dev->rcvdt.fifo)) ||
1195             (sndtyp_bk(task->ttyp) && !ipblink_empty(&dev->rcvdt.bk.link)))
1196                 mask |= POLLIN | POLLRDNORM;
1197         if (dev->wsz)
1198                 mask |= POLLOUT | POLLWRNORM;
1199         devstate_read_unlock(dev);
1200
1201         return mask;
1202 }
1203
1204 static int dsp_tctl_issue(struct taskdev *dev, u16 cmd, int argc, u16 argv[])
1205 {
1206         int tctl_argc;
1207         struct mb_exarg mbarg, *mbargp;
1208         int interactive;
1209         u8 tid;
1210         int ret = 0;
1211
1212         if (cmd < 0x8000) {
1213                 /*
1214                  * 0x0000 - 0x7fff
1215                  * system reserved TCTL commands
1216                  */
1217                 switch (cmd) {
1218                 case TCTL_TEN:
1219                 case TCTL_TDIS:
1220                         tctl_argc = 0;
1221                         interactive = 0;
1222                         break;
1223                 default:
1224                         return -EINVAL;
1225                 }
1226         }
1227         /*
1228          * 0x8000 - 0xffff
1229          * user-defined TCTL commands
1230          */
1231         else if (cmd < 0x8100) {
1232                 /* 0x8000-0x80ff: no arg, non-interactive */
1233                 tctl_argc = 0;
1234                 interactive = 0;
1235         } else if (cmd < 0x8200) {
1236                 /* 0x8100-0x81ff: 1 arg, non-interactive */
1237                 tctl_argc = 1;
1238                 interactive = 0;
1239         } else if (cmd < 0x9000) {
1240                 /* 0x8200-0x8fff: reserved */
1241                 return -EINVAL;
1242         } else if (cmd < 0x9100) {
1243                 /* 0x9000-0x90ff: no arg, interactive */
1244                 tctl_argc = 0;
1245                 interactive = 1;
1246         } else if (cmd < 0x9200) {
1247                 /* 0x9100-0x91ff: 1 arg, interactive */
1248                 tctl_argc = 1;
1249                 interactive = 1;
1250         } else {
1251                 /* 0x9200-0xffff: reserved */
1252                 return -EINVAL;
1253         }
1254
1255         /*
1256          * if argc < 0, use tctl_argc as is.
1257          * if argc >= 0, check arg count.
1258          */
1259         if ((argc >= 0) && (argc != tctl_argc))
1260                 return -EINVAL;
1261
1262         /*
1263          * issue TCTL
1264          */
1265         if (taskdev_lock_interruptible(dev, &dev->tctl_mutex))
1266                 return -EINTR;
1267
1268         tid = dev->task->tid;
1269         if (tctl_argc > 0) {
1270                 mbarg.argc = tctl_argc;
1271                 mbarg.tid  = tid;
1272                 mbarg.argv = argv;
1273                 mbargp = &mbarg;
1274         } else
1275                 mbargp = NULL;
1276
1277         if (interactive) {
1278                 dev->tctl_stat = -EINVAL;
1279
1280                 mbcompose_send_and_wait_exarg(TCTL, tid, cmd, mbargp,
1281                                               &dev->tctl_wait_q);
1282                 if (signal_pending(current)) {
1283                         ret = -EINTR;
1284                         goto up_out;
1285                 }
1286                 if ((ret = dev->tctl_stat) < 0) {
1287                         printk(KERN_ERR "omapdsp: TCTL not responding.\n");
1288                         goto up_out;
1289                 }
1290         } else
1291                 mbcompose_send_exarg(TCTL, tid, cmd, mbargp);
1292
1293 up_out:
1294         mutex_unlock(&dev->tctl_mutex);
1295         return ret;
1296 }
1297
1298 static int dsp_task_ioctl(struct inode *inode, struct file *file,
1299                           unsigned int cmd, unsigned long arg)
1300 {
1301         unsigned int minor = MINOR(inode->i_rdev);
1302         struct taskdev *dev = taskdev[minor];
1303         int ret;
1304
1305         if (cmd < 0x10000) {
1306                 /* issue TCTL */
1307                 u16 mbargv[1];
1308
1309                 mbargv[0] = arg & 0xffff;
1310                 return dsp_tctl_issue(dev, cmd, -1, mbargv);
1311         }
1312
1313         /* non TCTL ioctls */
1314         switch (cmd) {
1315
1316         case TASK_IOCTL_LOCK:
1317                 ret = taskdev_lock(dev);
1318                 break;
1319
1320         case TASK_IOCTL_UNLOCK:
1321                 ret = taskdev_unlock(dev);
1322                 break;
1323
1324         case TASK_IOCTL_BFLSH:
1325                 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
1326                         return -ENODEV;
1327                 ret = taskdev_flush_buf(dev);
1328                 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
1329                 break;
1330
1331         case TASK_IOCTL_SETBSZ:
1332                 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
1333                         return -ENODEV;
1334                 ret = taskdev_set_fifosz(dev, arg);
1335                 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
1336                 break;
1337
1338         case TASK_IOCTL_GETNAME:
1339                 ret = 0;
1340                 if (copy_to_user((void __user *)arg, dev->name,
1341                                  strlen(dev->name) + 1))
1342                         ret = -EFAULT;
1343                 break;
1344
1345         default:
1346                 ret = -ENOIOCTLCMD;
1347
1348         }
1349
1350         return ret;
1351 }
1352
1353 static void dsp_task_mmap_open(struct vm_area_struct *vma)
1354 {
1355         struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1356         struct dsptask *task;
1357         size_t len = vma->vm_end - vma->vm_start;
1358
1359         BUG_ON(!(dev->state & TASKDEV_ST_ATTACHED));
1360         task = dev->task;
1361         omap_mmu_exmap_use(&dsp_mmu, task->map_base, len);
1362 }
1363
1364 static void dsp_task_mmap_close(struct vm_area_struct *vma)
1365 {
1366         struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1367         struct dsptask *task;
1368         size_t len = vma->vm_end - vma->vm_start;
1369
1370         BUG_ON(!(dev->state & TASKDEV_ST_ATTACHED));
1371         task = dev->task;
1372         omap_mmu_exmap_unuse(&dsp_mmu, task->map_base, len);
1373 }
1374
1375 /**
1376  * On demand page allocation is not allowed. The mapping area is defined by
1377  * corresponding DSP tasks.
1378  */
1379 static struct page *dsp_task_mmap_nopage(struct vm_area_struct *vma,
1380                                          unsigned long address, int *type)
1381 {
1382         return NOPAGE_SIGBUS;
1383 }
1384
1385 static struct vm_operations_struct dsp_task_vm_ops = {
1386         .open = dsp_task_mmap_open,
1387         .close = dsp_task_mmap_close,
1388         .nopage = dsp_task_mmap_nopage,
1389 };
1390
1391 static int dsp_task_mmap(struct file *filp, struct vm_area_struct *vma)
1392 {
1393         void *tmp_vadr;
1394         unsigned long tmp_padr, tmp_vmadr, off;
1395         size_t req_len, tmp_len;
1396         unsigned int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
1397         struct taskdev *dev = taskdev[minor];
1398         struct dsptask *task;
1399         int ret = 0;
1400
1401         if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
1402                 return -ENODEV;
1403         task = dev->task;
1404
1405         /*
1406          * Don't swap this area out
1407          * Don't dump this area to a core file
1408          */
1409         vma->vm_flags |= VM_RESERVED | VM_IO;
1410
1411         /* Do not cache this area */
1412         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1413
1414         req_len = vma->vm_end - vma->vm_start;
1415         off = vma->vm_pgoff << PAGE_SHIFT;
1416         tmp_vmadr = vma->vm_start;
1417         tmp_vadr = task->map_base + off;
1418         do {
1419                 tmp_padr = omap_mmu_virt_to_phys(&dsp_mmu, tmp_vadr, &tmp_len);
1420                 if (tmp_padr == 0) {
1421                         printk(KERN_ERR
1422                                "omapdsp: task %s: illegal address "
1423                                "for mmap: %p", task->name, tmp_vadr);
1424                         /* partial mapping will be cleared in upper layer */
1425                         ret = -EINVAL;
1426                         goto unlock_out;
1427                 }
1428                 if (tmp_len > req_len)
1429                         tmp_len = req_len;
1430
1431                 printk(KERN_DEBUG
1432                        "omapdsp: mmap info: "
1433                        "vmadr = %08lx, padr = %08lx, len = %x\n",
1434                        tmp_vmadr, tmp_padr, tmp_len);
1435                 if (remap_pfn_range(vma, tmp_vmadr, tmp_padr >> PAGE_SHIFT,
1436                                     tmp_len, vma->vm_page_prot) != 0) {
1437                         printk(KERN_ERR
1438                                "omapdsp: task %s: remap_page_range() failed.\n",
1439                                task->name);
1440                         /* partial mapping will be cleared in upper layer */
1441                         ret = -EINVAL;
1442                         goto unlock_out;
1443                 }
1444
1445                 req_len   -= tmp_len;
1446                 tmp_vmadr += tmp_len;
1447                 tmp_vadr  += tmp_len;
1448         } while (req_len);
1449
1450         vma->vm_ops = &dsp_task_vm_ops;
1451         vma->vm_private_data = dev;
1452         omap_mmu_exmap_use(&dsp_mmu, task->map_base, vma->vm_end - vma->vm_start);
1453
1454 unlock_out:
1455         devstate_read_unlock(dev);
1456         return ret;
1457 }
1458
1459 static int dsp_task_open(struct inode *inode, struct file *file)
1460 {
1461         unsigned int minor = MINOR(inode->i_rdev);
1462         struct taskdev *dev;
1463         int ret = 0;
1464
1465         if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL))
1466                 return -ENODEV;
1467
1468 restart:
1469         mutex_lock(&dev->usecount_lock);
1470         down_write(&dev->state_sem);
1471
1472         /* state can be NOTASK, ATTACHED/FREEZED, KILLING, GARBAGE or INVALID here. */
1473         switch (dev->state & TASKDEV_ST_STATE_MASK) {
1474                 case TASKDEV_ST_NOTASK:
1475                         break;
1476                 case TASKDEV_ST_ATTACHED:
1477                         goto attached;
1478
1479                 case TASKDEV_ST_INVALID:
1480                         up_write(&dev->state_sem);
1481                         mutex_unlock(&dev->usecount_lock);
1482                         return -ENODEV;
1483
1484                 case TASKDEV_ST_FREEZED:
1485                 case TASKDEV_ST_KILLING:
1486                 case TASKDEV_ST_GARBAGE:
1487                 case TASKDEV_ST_DELREQ:
1488                         /* on the kill process. wait until it becomes NOTASK. */
1489                         up_write(&dev->state_sem);
1490                         mutex_unlock(&dev->usecount_lock);
1491                         if (devstate_write_lock(dev, TASKDEV_ST_NOTASK) < 0)
1492                                 return -EINTR;
1493                         devstate_write_unlock(dev);
1494                         goto restart;
1495         }
1496
1497         /* NOTASK */
1498         dev->state = TASKDEV_ST_ADDREQ;
1499         /* wake up twch daemon for tadd */
1500         dsp_twch_touch();
1501         up_write(&dev->state_sem);
1502         if (devstate_write_lock(dev, TASKDEV_ST_ATTACHED |
1503                                      TASKDEV_ST_ADDFAIL) < 0) {
1504                 /* cancelled */
1505                 if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) {
1506                         mutex_unlock(&dev->usecount_lock);
1507                         /* out of control ??? */
1508                         return -EINTR;
1509                 }
1510                 dev->state = TASKDEV_ST_NOTASK;
1511                 ret = -EINTR;
1512                 goto change_out;
1513         }
1514         if (dev->state & TASKDEV_ST_ADDFAIL) {
1515                 printk(KERN_ERR "omapdsp: task attach failed for %s!\n",
1516                        dev->name);
1517                 ret = -EBUSY;
1518                 dev->state = TASKDEV_ST_NOTASK;
1519                 goto change_out;
1520         }
1521
1522 attached:
1523         /* ATTACHED */
1524 #ifndef CONFIG_OMAP_DSP_TASK_MULTIOPEN
1525         if (dev->usecount > 0) {
1526                 up_write(&dev->state_sem);
1527                 return -EBUSY;
1528         }
1529 #endif
1530         dev->usecount++;
1531         proc_list_add(&dev->proc_list_lock, &dev->proc_list, current, file);
1532         file->f_op = &dev->fops;
1533         up_write(&dev->state_sem);
1534         mutex_unlock(&dev->usecount_lock);
1535
1536 #ifdef DSP_PTE_FREE     /* not used currently. */
1537         dsp_map_update(current);
1538         dsp_cur_users_add(current);
1539 #endif /* DSP_PTE_FREE */
1540         return 0;
1541
1542 change_out:
1543         wake_up_interruptible_all(&dev->state_wait_q);
1544         up_write(&dev->state_sem);
1545         mutex_unlock(&dev->usecount_lock);
1546         return ret;
1547 }
1548
1549 static int dsp_task_release(struct inode *inode, struct file *file)
1550 {
1551         unsigned int minor = MINOR(inode->i_rdev);
1552         struct taskdev *dev = taskdev[minor];
1553
1554 #ifdef DSP_PTE_FREE     /* not used currently. */
1555         dsp_cur_users_del(current);
1556 #endif /* DSP_PTE_FREE */
1557
1558         if (has_taskdev_lock(dev))
1559                 taskdev_unlock(dev);
1560
1561         proc_list_del(&dev->proc_list_lock, &dev->proc_list, current, file);
1562         mutex_lock(&dev->usecount_lock);
1563         if (--dev->usecount > 0) {
1564                 /* other processes are using this device. no state change. */
1565                 mutex_unlock(&dev->usecount_lock);
1566                 return 0;
1567         }
1568
1569         /* usecount == 0 */
1570         down_write(&dev->state_sem);
1571
1572         /* state can be ATTACHED/FREEZED, KILLING or GARBAGE here. */
1573         switch (dev->state & TASKDEV_ST_STATE_MASK) {
1574
1575         case TASKDEV_ST_KILLING:
1576                 break;
1577
1578         case TASKDEV_ST_GARBAGE:
1579                 dev->state = TASKDEV_ST_NOTASK;
1580                 wake_up_interruptible_all(&dev->state_wait_q);
1581                 break;
1582
1583         case TASKDEV_ST_ATTACHED:
1584         case TASKDEV_ST_FREEZED:
1585                 if (is_dynamic_task(minor)) {
1586                         dev->state = TASKDEV_ST_DELREQ;
1587                         /* wake up twch daemon for tdel */
1588                         dsp_twch_touch();
1589                 }
1590                 break;
1591
1592         }
1593
1594         up_write(&dev->state_sem);
1595         mutex_unlock(&dev->usecount_lock);
1596         return 0;
1597 }
1598
1599 /*
1600  * mkdev / rmdev
1601  */
1602 int dsp_mkdev(char *name)
1603 {
1604         struct taskdev *dev;
1605         int status;
1606         unsigned char minor;
1607         int ret;
1608
1609         if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
1610                 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1611                 return -EINVAL;
1612         }
1613
1614         if (mutex_lock_interruptible(&devmgr_lock))
1615                 return -EINTR;
1616
1617         /* naming check */
1618         for (minor = 0; minor < TASKDEV_MAX; minor++) {
1619                 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1620                         printk(KERN_ERR
1621                                "omapdsp: task device name %s is already "
1622                                "in use.\n", name);
1623                         ret = -EINVAL;
1624                         goto out;
1625                 }
1626         }
1627
1628         /* find free minor number */
1629         for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1630                 if (taskdev[minor] == NULL)
1631                         goto do_make;
1632         }
1633         printk(KERN_ERR "omapdsp: Too many task devices.\n");
1634         ret = -EBUSY;
1635         goto out;
1636
1637 do_make:
1638         if ((dev = kzalloc(sizeof(struct taskdev), GFP_KERNEL)) == NULL) {
1639                 ret = -ENOMEM;
1640                 goto out;
1641         }
1642         if ((status = taskdev_init(dev, name, minor)) < 0) {
1643                 kfree(dev);
1644                 ret = status;
1645                 goto out;
1646         }
1647         ret = minor;
1648
1649 out:
1650         mutex_unlock(&devmgr_lock);
1651         return ret;
1652 }
1653
1654 int dsp_rmdev(char *name)
1655 {
1656         unsigned char minor;
1657         int status;
1658         int ret;
1659
1660         if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
1661                 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1662                 return -EINVAL;
1663         }
1664
1665         if (mutex_lock_interruptible(&devmgr_lock))
1666                 return -EINTR;
1667
1668         /* find in dynamic devices */
1669         for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1670                 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name))
1671                         goto do_remove;
1672         }
1673
1674         /* find in static devices */
1675         for (minor = 0; minor < n_task; minor++) {
1676                 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1677                         printk(KERN_ERR
1678                                "omapdsp: task device %s is static.\n", name);
1679                         ret = -EINVAL;
1680                         goto out;
1681                 }
1682         }
1683
1684         printk(KERN_ERR "omapdsp: task device %s not found.\n", name);
1685         return -EINVAL;
1686
1687 do_remove:
1688         ret = minor;
1689         if ((status = dsp_rmdev_minor(minor)) < 0)
1690                 ret = status;
1691 out:
1692         mutex_unlock(&devmgr_lock);
1693         return ret;
1694 }
1695
1696 static int dsp_rmdev_minor(unsigned char minor)
1697 {
1698         struct taskdev *dev = taskdev[minor];
1699
1700         while (!down_write_trylock(&dev->state_sem)) {
1701                 down_read(&dev->state_sem);
1702                 if (dev->state & (TASKDEV_ST_ATTACHED |
1703                                   TASKDEV_ST_FREEZED)) {
1704                         /*
1705                          * task is working. kill it.
1706                          * ATTACHED -> FREEZED can be changed under
1707                          * down_read of state_sem..
1708                          */
1709                         dev->state = TASKDEV_ST_FREEZED;
1710                         wake_up_interruptible_all(&dev->read_wait_q);
1711                         wake_up_interruptible_all(&dev->write_wait_q);
1712                         wake_up_interruptible_all(&dev->tctl_wait_q);
1713                 }
1714                 up_read(&dev->state_sem);
1715                 schedule();
1716         }
1717
1718         switch (dev->state & TASKDEV_ST_STATE_MASK) {
1719
1720         case TASKDEV_ST_NOTASK:
1721                 /* fine */
1722                 goto notask;
1723
1724         case TASKDEV_ST_ATTACHED:
1725         case TASKDEV_ST_FREEZED:
1726                 /* task is working. kill it. */
1727                 dev->state = TASKDEV_ST_KILLING;
1728                 up_write(&dev->state_sem);
1729                 dsp_tdel_bh(dev, TDEL_KILL);
1730                 goto invalidate;
1731
1732         case TASKDEV_ST_ADDREQ:
1733                 /* open() is waiting. drain it. */
1734                 dev->state = TASKDEV_ST_ADDFAIL;
1735                 wake_up_interruptible_all(&dev->state_wait_q);
1736                 break;
1737
1738         case TASKDEV_ST_DELREQ:
1739                 /* nobody is waiting. */
1740                 dev->state = TASKDEV_ST_NOTASK;
1741                 wake_up_interruptible_all(&dev->state_wait_q);
1742                 break;
1743
1744         case TASKDEV_ST_ADDING:
1745         case TASKDEV_ST_DELING:
1746         case TASKDEV_ST_KILLING:
1747         case TASKDEV_ST_GARBAGE:
1748         case TASKDEV_ST_ADDFAIL:
1749                 /* transient state. wait for a moment. */
1750                 break;
1751
1752         }
1753
1754         up_write(&dev->state_sem);
1755
1756 invalidate:
1757         /* wait for some time and hope the state is settled */
1758         devstate_read_lock_timeout(dev, TASKDEV_ST_NOTASK, 5 * HZ);
1759         if (!(dev->state & TASKDEV_ST_NOTASK)) {
1760                 printk(KERN_WARNING
1761                        "omapdsp: illegal device state (%s) on rmdev %s.\n",
1762                        devstate_name(dev->state), dev->name);
1763         }
1764 notask:
1765         dev->state = TASKDEV_ST_INVALID;
1766         devstate_read_unlock(dev);
1767
1768         taskdev_delete(minor);
1769         kfree(dev);
1770
1771         return 0;
1772 }
1773
1774 struct file_operations dsp_task_fops = {
1775         .owner   = THIS_MODULE,
1776         .poll    = dsp_task_poll,
1777         .ioctl   = dsp_task_ioctl,
1778         .open    = dsp_task_open,
1779         .release = dsp_task_release,
1780 };
1781
1782 static void dsptask_dev_release(struct device *dev)
1783 {
1784 }
1785
1786 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor)
1787 {
1788         int ret;
1789
1790         taskdev[minor] = dev;
1791
1792         spin_lock_init(&dev->proc_list_lock);
1793         INIT_LIST_HEAD(&dev->proc_list);
1794         init_waitqueue_head(&dev->read_wait_q);
1795         init_waitqueue_head(&dev->write_wait_q);
1796         init_waitqueue_head(&dev->tctl_wait_q);
1797         mutex_init(&dev->read_mutex);
1798         mutex_init(&dev->write_mutex);
1799         mutex_init(&dev->tctl_mutex);
1800         mutex_init(&dev->lock);
1801         spin_lock_init(&dev->wsz_lock);
1802         dev->tctl_ret = -EINVAL;
1803         dev->lock_pid = 0;
1804
1805         strncpy(dev->name, name, TNM_LEN);
1806         dev->name[TNM_LEN-1] = '\0';
1807         dev->state = (minor < n_task) ? TASKDEV_ST_ATTACHED : TASKDEV_ST_NOTASK;
1808         dev->usecount = 0;
1809         mutex_init(&dev->usecount_lock);
1810         memcpy(&dev->fops, &dsp_task_fops, sizeof(struct file_operations));
1811
1812         dev->dev.parent = omap_dsp->dev;
1813         dev->dev.bus = &dsptask_bus;
1814         sprintf(dev->dev.bus_id, "dsptask%d", minor);
1815         dev->dev.release = dsptask_dev_release;
1816         ret = device_register(&dev->dev);
1817         if (ret)
1818                 printk(KERN_ERR "device_register failed: %d\n", ret);
1819         ret = device_create_file(&dev->dev, &dev_attr_devname);
1820         ret |= device_create_file(&dev->dev, &dev_attr_devstate);
1821         ret |= device_create_file(&dev->dev, &dev_attr_proc_list);
1822         if (ret)
1823                 printk(KERN_ERR "device_create_file failed: %d\n", ret);
1824         device_create(dsp_task_class, NULL,
1825                         MKDEV(OMAP_DSP_TASK_MAJOR, minor),
1826                         "dsptask%d", minor);
1827
1828         init_waitqueue_head(&dev->state_wait_q);
1829         init_rwsem(&dev->state_sem);
1830
1831         return 0;
1832 }
1833
1834 static void taskdev_delete(unsigned char minor)
1835 {
1836         struct taskdev *dev = taskdev[minor];
1837
1838         if (!dev)
1839                 return;
1840         device_remove_file(&dev->dev, &dev_attr_devname);
1841         device_remove_file(&dev->dev, &dev_attr_devstate);
1842         device_remove_file(&dev->dev, &dev_attr_proc_list);
1843         device_destroy(dsp_task_class, MKDEV(OMAP_DSP_TASK_MAJOR, minor));
1844         device_unregister(&dev->dev);
1845         proc_list_flush(&dev->proc_list_lock, &dev->proc_list);
1846         taskdev[minor] = NULL;
1847 }
1848
1849 static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task)
1850 {
1851         u16 ttyp = task->ttyp;
1852         int ret;
1853
1854         dev->fops.read =
1855                 sndtyp_acv(ttyp) ?
1856                         sndtyp_wd(ttyp) ? dsp_task_read_wd_acv:
1857                         /* sndtyp_bk */   dsp_task_read_bk_acv:
1858                 /* sndtyp_psv */
1859                         sndtyp_wd(ttyp) ? dsp_task_read_wd_psv:
1860                         /* sndtyp_bk */   dsp_task_read_bk_psv;
1861         if (sndtyp_wd(ttyp)) {
1862                 /* word */
1863                 size_t fifosz;
1864
1865                 fifosz = sndtyp_psv(ttyp) ? 2 : /* passive */
1866                                             32; /* active */
1867                 if (init_fifo(&dev->rcvdt.fifo, fifosz) < 0) {
1868                         printk(KERN_ERR
1869                                "omapdsp: unable to allocate receive buffer. "
1870                                "(%d bytes for %s)\n", fifosz, dev->name);
1871                         return -ENOMEM;
1872                 }
1873         } else {
1874                 /* block */
1875                 INIT_IPBLINK(&dev->rcvdt.bk.link);
1876                 dev->rcvdt.bk.rp = 0;
1877         }
1878
1879         dev->fops.write =
1880                 rcvtyp_wd(ttyp) ? dsp_task_write_wd:
1881                 /* rcvbyp_bk */   dsp_task_write_bk;
1882         dev->wsz = rcvtyp_acv(ttyp) ? 0 :               /* active */
1883                    rcvtyp_wd(ttyp)  ? 2 :               /* passive word */
1884                                       ipbcfg.lsz*2;     /* passive block */
1885
1886         if (task->map_length)
1887                 dev->fops.mmap = dsp_task_mmap;
1888
1889         ret = device_create_file(&dev->dev, &dev_attr_taskname);
1890         ret |= device_create_file(&dev->dev, &dev_attr_ttyp);
1891         if (sndtyp_wd(ttyp)) {
1892                 ret |= device_create_file(&dev->dev, &dev_attr_fifosz);
1893                 ret |= device_create_file(&dev->dev, &dev_attr_fifocnt);
1894         } else
1895                 ret |= device_create_file(&dev->dev, &dev_attr_ipblink);
1896         ret |= device_create_file(&dev->dev, &dev_attr_wsz);
1897         if (task->map_length)
1898                 ret |= device_create_file(&dev->dev, &dev_attr_mmap);
1899         if (ret)
1900                 printk(KERN_ERR "device_create_file failed: %d\n", ret);
1901
1902         dev->task = task;
1903         task->dev = dev;
1904
1905         return 0;
1906 }
1907
1908 static void taskdev_detach_task(struct taskdev *dev)
1909 {
1910         u16 ttyp = dev->task->ttyp;
1911
1912         device_remove_file(&dev->dev, &dev_attr_taskname);
1913         device_remove_file(&dev->dev, &dev_attr_ttyp);
1914         if (sndtyp_wd(ttyp)) {
1915                 device_remove_file(&dev->dev, &dev_attr_fifosz);
1916                 device_remove_file(&dev->dev, &dev_attr_fifocnt);
1917         } else
1918                 device_remove_file(&dev->dev, &dev_attr_ipblink);
1919         device_remove_file(&dev->dev, &dev_attr_wsz);
1920         if (dev->task->map_length)
1921                 device_remove_file(&dev->dev, &dev_attr_mmap);
1922
1923         dev->fops.read = NULL;
1924         taskdev_flush_buf(dev);
1925         if (sndtyp_wd(ttyp))
1926                 free_fifo(&dev->rcvdt.fifo);
1927
1928         dev->fops.write = NULL;
1929         dev->wsz = 0;
1930
1931         printk(KERN_INFO "omapdsp: taskdev %s disabled.\n", dev->name);
1932         dev->task = NULL;
1933 }
1934
1935 /*
1936  * tadd / tdel / tkill
1937  */
1938 static int dsp_tadd(struct taskdev *dev, dsp_long_t adr)
1939 {
1940         struct dsptask *task;
1941         struct mb_exarg arg;
1942         u8 tid, tid_response;
1943         u16 argv[2];
1944         int ret = 0;
1945
1946         if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) {
1947                 printk(KERN_ERR
1948                        "omapdsp: taskdev %s is not requesting for tadd. "
1949                        "(state is %s)\n", dev->name, devstate_name(dev->state));
1950                 return -EINVAL;
1951         }
1952         dev->state = TASKDEV_ST_ADDING;
1953         devstate_write_unlock(dev);
1954
1955         if (adr == TADD_ABORTADR) {
1956                 /* aborting tadd intentionally */
1957                 printk(KERN_INFO "omapdsp: tadd address is ABORTADR.\n");
1958                 goto fail_out;
1959         }
1960         if (adr >= DSPSPACE_SIZE) {
1961                 printk(KERN_ERR
1962                        "omapdsp: illegal address 0x%08x for tadd\n", adr);
1963                 ret = -EINVAL;
1964                 goto fail_out;
1965         }
1966
1967         adr >>= 1;      /* word address */
1968         argv[0] = adr >> 16;    /* addrh */
1969         argv[1] = adr & 0xffff; /* addrl */
1970
1971         if (mutex_lock_interruptible(&cfg_lock)) {
1972                 ret = -EINTR;
1973                 goto fail_out;
1974         }
1975         cfg_tid = TID_ANON;
1976         cfg_cmd = MBOX_CMD_DSP_TADD;
1977         arg.tid  = TID_ANON;
1978         arg.argc = 2;
1979         arg.argv = argv;
1980
1981         if (dsp_mem_sync_inc() < 0) {
1982                 printk(KERN_ERR "omapdsp: memory sync failed!\n");
1983                 ret = -EBUSY;
1984                 goto fail_out;
1985         }
1986         mbcompose_send_and_wait_exarg(TADD, 0, 0, &arg, &cfg_wait_q);
1987
1988         tid = cfg_tid;
1989         cfg_tid = TID_ANON;
1990         cfg_cmd = 0;
1991         mutex_unlock(&cfg_lock);
1992
1993         if (tid == TID_ANON) {
1994                 printk(KERN_ERR "omapdsp: tadd failed!\n");
1995                 ret = -EINVAL;
1996                 goto fail_out;
1997         }
1998         if ((tid < n_task) || dsptask[tid]) {
1999                 printk(KERN_ERR "omapdsp: illegal tid (%d)!\n", tid);
2000                 ret = -EINVAL;
2001                 goto fail_out;
2002         }
2003         if ((task = kzalloc(sizeof(struct dsptask), GFP_KERNEL)) == NULL) {
2004                 ret = -ENOMEM;
2005                 goto del_out;
2006         }
2007
2008         if ((ret = dsp_task_config(task, tid)) < 0)
2009                 goto free_out;
2010
2011         if (strcmp(dev->name, task->name)) {
2012                 printk(KERN_ERR
2013                        "omapdsp: task name (%s) doesn't match with "
2014                        "device name (%s).\n", task->name, dev->name);
2015                 ret = -EINVAL;
2016                 goto free_out;
2017         }
2018
2019         if ((ret = taskdev_attach_task(dev, task)) < 0)
2020                 goto free_out;
2021
2022         dsp_task_init(task);
2023         printk(KERN_INFO "omapdsp: taskdev %s enabled.\n", dev->name);
2024         dev->state = TASKDEV_ST_ATTACHED;
2025         wake_up_interruptible_all(&dev->state_wait_q);
2026         return 0;
2027
2028 free_out:
2029         kfree(task);
2030
2031 del_out:
2032         printk(KERN_ERR "omapdsp: deleting the task...\n");
2033
2034         dev->state = TASKDEV_ST_DELING;
2035
2036         if (mutex_lock_interruptible(&cfg_lock)) {
2037                 printk(KERN_ERR "omapdsp: aborting tdel process. "
2038                                 "DSP side could be corrupted.\n");
2039                 goto fail_out;
2040         }
2041         cfg_tid = TID_ANON;
2042         cfg_cmd = MBOX_CMD_DSP_TDEL;
2043         mbcompose_send_and_wait(TDEL, tid, TDEL_KILL, &cfg_wait_q);
2044         tid_response = cfg_tid;
2045         cfg_tid = TID_ANON;
2046         cfg_cmd = 0;
2047         mutex_unlock(&cfg_lock);
2048
2049         if (tid_response != tid)
2050                 printk(KERN_ERR "omapdsp: tdel failed. "
2051                                 "DSP side could be corrupted.\n");
2052
2053 fail_out:
2054         dev->state = TASKDEV_ST_ADDFAIL;
2055         wake_up_interruptible_all(&dev->state_wait_q);
2056         return ret;
2057 }
2058
2059 int dsp_tadd_minor(unsigned char minor, dsp_long_t adr)
2060 {
2061         struct taskdev *dev;
2062         int status;
2063         int ret;
2064
2065         if (mutex_lock_interruptible(&devmgr_lock))
2066                 return -EINTR;
2067
2068         if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2069                 printk(KERN_ERR
2070                        "omapdsp: no task device with minor %d\n", minor);
2071                 ret = -EINVAL;
2072                 goto out;
2073         }
2074         ret = minor;
2075         if ((status = dsp_tadd(dev, adr)) < 0)
2076                 ret = status;
2077
2078 out:
2079         mutex_unlock(&devmgr_lock);
2080         return ret;
2081 }
2082
2083 static int dsp_tdel(struct taskdev *dev)
2084 {
2085         if (!devstate_write_lock_and_test(dev, TASKDEV_ST_DELREQ)) {
2086                 printk(KERN_ERR
2087                        "omapdsp: taskdev %s is not requesting for tdel. "
2088                        "(state is %s)\n", dev->name, devstate_name(dev->state));
2089                 return -EINVAL;
2090         }
2091         dev->state = TASKDEV_ST_DELING;
2092         devstate_write_unlock(dev);
2093
2094         return dsp_tdel_bh(dev, TDEL_SAFE);
2095 }
2096
2097 int dsp_tdel_minor(unsigned char minor)
2098 {
2099         struct taskdev *dev;
2100         int status;
2101         int ret;
2102
2103         if (mutex_lock_interruptible(&devmgr_lock))
2104                 return -EINTR;
2105
2106         if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2107                 printk(KERN_ERR
2108                        "omapdsp: no task device with minor %d\n", minor);
2109                 ret = -EINVAL;
2110                 goto out;
2111         }
2112
2113         ret = minor;
2114         if ((status = dsp_tdel(dev)) < 0)
2115                 ret = status;
2116
2117 out:
2118         mutex_unlock(&devmgr_lock);
2119         return ret;
2120 }
2121
2122 static int dsp_tkill(struct taskdev *dev)
2123 {
2124         while (!down_write_trylock(&dev->state_sem)) {
2125                 if (!devstate_read_lock_and_test(dev, (TASKDEV_ST_ATTACHED |
2126                                                        TASKDEV_ST_FREEZED))) {
2127                         printk(KERN_ERR
2128                                "omapdsp: task has not been attached for "
2129                                "taskdev %s\n", dev->name);
2130                         return -EINVAL;
2131                 }
2132                 /* ATTACHED -> FREEZED can be changed under read semaphore. */
2133                 dev->state = TASKDEV_ST_FREEZED;
2134                 wake_up_interruptible_all(&dev->read_wait_q);
2135                 wake_up_interruptible_all(&dev->write_wait_q);
2136                 wake_up_interruptible_all(&dev->tctl_wait_q);
2137                 devstate_read_unlock(dev);
2138                 schedule();
2139         }
2140
2141         if (!(dev->state & (TASKDEV_ST_ATTACHED |
2142                             TASKDEV_ST_FREEZED))) {
2143                 printk(KERN_ERR
2144                        "omapdsp: task has not been attached for taskdev %s\n",
2145                        dev->name);
2146                 devstate_write_unlock(dev);
2147                 return -EINVAL;
2148         }
2149         if (!is_dynamic_task(dev->task->tid)) {
2150                 printk(KERN_ERR "omapdsp: task %s is not a dynamic task.\n",
2151                        dev->name);
2152                 devstate_write_unlock(dev);
2153                 return -EINVAL;
2154         }
2155         dev->state = TASKDEV_ST_KILLING;
2156         devstate_write_unlock(dev);
2157
2158         return dsp_tdel_bh(dev, TDEL_KILL);
2159 }
2160
2161 int dsp_tkill_minor(unsigned char minor)
2162 {
2163         struct taskdev *dev;
2164         int status;
2165         int ret;
2166
2167         if (mutex_lock_interruptible(&devmgr_lock))
2168                 return -EINTR;
2169
2170         if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2171                 printk(KERN_ERR
2172                        "omapdsp: no task device with minor %d\n", minor);
2173                 ret = -EINVAL;
2174                 goto out;
2175         }
2176
2177         ret = minor;
2178         if ((status = dsp_tkill(dev)) < 0)
2179                 ret = status;
2180
2181 out:
2182         mutex_unlock(&devmgr_lock);
2183         return ret;
2184 }
2185
2186 static int dsp_tdel_bh(struct taskdev *dev, u16 type)
2187 {
2188         struct dsptask *task;
2189         u8 tid, tid_response;
2190         int ret = 0;
2191
2192         task = dev->task;
2193         tid = task->tid;
2194         if (mutex_lock_interruptible(&cfg_lock)) {
2195                 if (type == TDEL_SAFE) {
2196                         dev->state = TASKDEV_ST_DELREQ;
2197                         return -EINTR;
2198                 } else {
2199                         tid_response = TID_ANON;
2200                         ret = -EINTR;
2201                         goto detach_out;
2202                 }
2203         }
2204         cfg_tid = TID_ANON;
2205         cfg_cmd = MBOX_CMD_DSP_TDEL;
2206         mbcompose_send_and_wait(TDEL, tid, type, &cfg_wait_q);
2207         tid_response = cfg_tid;
2208         cfg_tid = TID_ANON;
2209         cfg_cmd = 0;
2210         mutex_unlock(&cfg_lock);
2211
2212 detach_out:
2213         taskdev_detach_task(dev);
2214         dsp_task_unconfig(task);
2215         kfree(task);
2216
2217         if (tid_response != tid) {
2218                 printk(KERN_ERR "omapdsp: %s failed!\n",
2219                        (type == TDEL_SAFE) ? "tdel" : "tkill");
2220                 ret = -EINVAL;
2221         }
2222         down_write(&dev->state_sem);
2223         dev->state = (dev->usecount > 0) ? TASKDEV_ST_GARBAGE :
2224                                            TASKDEV_ST_NOTASK;
2225         wake_up_interruptible_all(&dev->state_wait_q);
2226         up_write(&dev->state_sem);
2227
2228         return ret;
2229 }
2230
2231 /*
2232  * state inquiry
2233  */
2234 long taskdev_state_stale(unsigned char minor)
2235 {
2236         if (taskdev[minor]) {
2237                 long state = taskdev[minor]->state;
2238                 taskdev[minor]->state |= TASKDEV_ST_STALE;
2239                 return state;
2240         } else
2241                 return TASKDEV_ST_NOTASK;
2242 }
2243
2244 /*
2245  * functions called from mailbox interrupt routine
2246  */
2247 void mbox_wdsnd(struct mbcmd *mb)
2248 {
2249         u8 tid = mb->cmd_l;
2250         struct dsptask *task = dsptask[tid];
2251
2252         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2253                 printk(KERN_ERR "mbox: WDSND with illegal tid! %d\n", tid);
2254                 return;
2255         }
2256         if (sndtyp_bk(task->ttyp)) {
2257                 printk(KERN_ERR
2258                        "mbox: WDSND from block sending task! (task%d)\n", tid);
2259                 return;
2260         }
2261         if (sndtyp_psv(task->ttyp) &&
2262             !waitqueue_active(&task->dev->read_wait_q)) {
2263                 printk(KERN_WARNING
2264                        "mbox: WDSND from passive sending task (task%d) "
2265                        "without request!\n", tid);
2266                 return;
2267         }
2268
2269         write_word_to_fifo(&task->dev->rcvdt.fifo, mb->data);
2270         wake_up_interruptible(&task->dev->read_wait_q);
2271 }
2272
2273 void mbox_wdreq(struct mbcmd *mb)
2274 {
2275         u8 tid = mb->cmd_l;
2276         struct dsptask *task = dsptask[tid];
2277         struct taskdev *dev;
2278
2279         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2280                 printk(KERN_ERR "mbox: WDREQ with illegal tid! %d\n", tid);
2281                 return;
2282         }
2283         if (rcvtyp_psv(task->ttyp)) {
2284                 printk(KERN_ERR
2285                        "mbox: WDREQ from passive receiving task! (task%d)\n",
2286                        tid);
2287                 return;
2288         }
2289
2290         dev = task->dev;
2291         spin_lock(&dev->wsz_lock);
2292         dev->wsz = 2;
2293         spin_unlock(&dev->wsz_lock);
2294         wake_up_interruptible(&dev->write_wait_q);
2295 }
2296
2297 void mbox_bksnd(struct mbcmd *mb)
2298 {
2299         u8 tid = mb->cmd_l;
2300         u16 bid = mb->data;
2301         struct dsptask *task = dsptask[tid];
2302         struct ipbuf_head *ipb_h;
2303         u16 cnt;
2304
2305         if (bid >= ipbcfg.ln) {
2306                 printk(KERN_ERR "mbox: BKSND with illegal bid! %d\n", bid);
2307                 return;
2308         }
2309         ipb_h = bid_to_ipbuf(bid);
2310         ipb_bsycnt_dec(&ipbcfg);
2311         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2312                 printk(KERN_ERR "mbox: BKSND with illegal tid! %d\n", tid);
2313                 goto unuse_ipbuf_out;
2314         }
2315         if (sndtyp_wd(task->ttyp)) {
2316                 printk(KERN_ERR
2317                        "mbox: BKSND from word sending task! (task%d)\n", tid);
2318                 goto unuse_ipbuf_out;
2319         }
2320         if (sndtyp_pvt(task->ttyp)) {
2321                 printk(KERN_ERR
2322                        "mbox: BKSND from private sending task! (task%d)\n", tid);
2323                 goto unuse_ipbuf_out;
2324         }
2325         if (sync_with_dsp(&ipb_h->p->sd, tid, 10) < 0) {
2326                 printk(KERN_ERR "mbox: BKSND - IPBUF sync failed!\n");
2327                 return;
2328         }
2329
2330         /* should be done in DSP, but just in case. */
2331         ipb_h->p->next = BID_NULL;
2332
2333         cnt = ipb_h->p->c;
2334         if (cnt > ipbcfg.lsz) {
2335                 printk(KERN_ERR "mbox: BKSND cnt(%d) > ipbuf line size(%d)!\n",
2336                        cnt, ipbcfg.lsz);
2337                 goto unuse_ipbuf_out;
2338         }
2339
2340         if (cnt == 0) {
2341                 /* 0-byte send from DSP */
2342                 unuse_ipbuf_nowait(ipb_h);
2343                 goto done;
2344         }
2345         ipblink_add_tail(&task->dev->rcvdt.bk.link, bid);
2346         /* we keep coming bid and return alternative line to DSP. */
2347         balance_ipbuf();
2348
2349 done:
2350         wake_up_interruptible(&task->dev->read_wait_q);
2351         return;
2352
2353 unuse_ipbuf_out:
2354         unuse_ipbuf_nowait(ipb_h);
2355         return;
2356 }
2357
2358 void mbox_bkreq(struct mbcmd *mb)
2359 {
2360         u8 tid = mb->cmd_l;
2361         u16 cnt = mb->data;
2362         struct dsptask *task = dsptask[tid];
2363         struct taskdev *dev;
2364
2365         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2366                 printk(KERN_ERR "mbox: BKREQ with illegal tid! %d\n", tid);
2367                 return;
2368         }
2369         if (rcvtyp_wd(task->ttyp)) {
2370                 printk(KERN_ERR
2371                        "mbox: BKREQ from word receiving task! (task%d)\n", tid);
2372                 return;
2373         }
2374         if (rcvtyp_pvt(task->ttyp)) {
2375                 printk(KERN_ERR
2376                        "mbox: BKREQ from private receiving task! (task%d)\n",
2377                        tid);
2378                 return;
2379         }
2380         if (rcvtyp_psv(task->ttyp)) {
2381                 printk(KERN_ERR
2382                        "mbox: BKREQ from passive receiving task! (task%d)\n",
2383                        tid);
2384                 return;
2385         }
2386
2387         dev = task->dev;
2388         spin_lock(&dev->wsz_lock);
2389         dev->wsz = cnt*2;
2390         spin_unlock(&dev->wsz_lock);
2391         wake_up_interruptible(&dev->write_wait_q);
2392 }
2393
2394 void mbox_bkyld(struct mbcmd *mb)
2395 {
2396         u16 bid = mb->data;
2397         struct ipbuf_head *ipb_h;
2398
2399         if (bid >= ipbcfg.ln) {
2400                 printk(KERN_ERR "mbox: BKYLD with illegal bid! %d\n", bid);
2401                 return;
2402         }
2403         ipb_h = bid_to_ipbuf(bid);
2404
2405         /* should be done in DSP, but just in case. */
2406         ipb_h->p->next = BID_NULL;
2407
2408         /* we don't need to sync with DSP */
2409         ipb_bsycnt_dec(&ipbcfg);
2410         release_ipbuf(ipb_h);
2411 }
2412
2413 void mbox_bksndp(struct mbcmd *mb)
2414 {
2415         u8 tid = mb->cmd_l;
2416         struct dsptask *task = dsptask[tid];
2417         struct ipbuf_p *ipbp;
2418
2419         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2420                 printk(KERN_ERR "mbox: BKSNDP with illegal tid! %d\n", tid);
2421                 return;
2422         }
2423         if (sndtyp_wd(task->ttyp)) {
2424                 printk(KERN_ERR
2425                        "mbox: BKSNDP from word sending task! (task%d)\n", tid);
2426                 return;
2427         }
2428         if (sndtyp_gbl(task->ttyp)) {
2429                 printk(KERN_ERR
2430                        "mbox: BKSNDP from non-private sending task! (task%d)\n",
2431                        tid);
2432                 return;
2433         }
2434
2435         /*
2436          * we should not have delayed block at this point
2437          * because read() routine releases the lock of the buffer and
2438          * until then DSP can't send next data.
2439          */
2440
2441         ipbp = task->ipbuf_pvt_r;
2442         if (sync_with_dsp(&ipbp->s, tid, 10) < 0) {
2443                 printk(KERN_ERR "mbox: BKSNDP - IPBUF sync failed!\n");
2444                 return;
2445         }
2446         printk(KERN_DEBUG "mbox: ipbuf_pvt_r->a = 0x%08lx\n",
2447                MKLONG(ipbp->ah, ipbp->al));
2448         ipblink_add_pvt(&task->dev->rcvdt.bk.link);
2449         wake_up_interruptible(&task->dev->read_wait_q);
2450 }
2451
2452 void mbox_bkreqp(struct mbcmd *mb)
2453 {
2454         u8 tid = mb->cmd_l;
2455         struct dsptask *task = dsptask[tid];
2456         struct taskdev *dev;
2457         struct ipbuf_p *ipbp;
2458
2459         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2460                 printk(KERN_ERR "mbox: BKREQP with illegal tid! %d\n", tid);
2461                 return;
2462         }
2463         if (rcvtyp_wd(task->ttyp)) {
2464                 printk(KERN_ERR
2465                        "mbox: BKREQP from word receiving task! (task%d)\n", tid);
2466                 return;
2467         }
2468         if (rcvtyp_gbl(task->ttyp)) {
2469                 printk(KERN_ERR
2470                        "mbox: BKREQP from non-private receiving task! (task%d)\n", tid);
2471                 return;
2472         }
2473         if (rcvtyp_psv(task->ttyp)) {
2474                 printk(KERN_ERR
2475                        "mbox: BKREQP from passive receiving task! (task%d)\n", tid);
2476                 return;
2477         }
2478
2479         ipbp = task->ipbuf_pvt_w;
2480         if (sync_with_dsp(&ipbp->s, TID_FREE, 10) < 0) {
2481                 printk(KERN_ERR "mbox: BKREQP - IPBUF sync failed!\n");
2482                 return;
2483         }
2484         printk(KERN_DEBUG "mbox: ipbuf_pvt_w->a = 0x%08lx\n",
2485                MKLONG(ipbp->ah, ipbp->al));
2486         dev = task->dev;
2487         spin_lock(&dev->wsz_lock);
2488         dev->wsz = ipbp->c*2;
2489         spin_unlock(&dev->wsz_lock);
2490         wake_up_interruptible(&dev->write_wait_q);
2491 }
2492
2493 void mbox_tctl(struct mbcmd *mb)
2494 {
2495         u8 tid = mb->cmd_l;
2496         struct dsptask *task = dsptask[tid];
2497
2498         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2499                 printk(KERN_ERR "mbox: TCTL with illegal tid! %d\n", tid);
2500                 return;
2501         }
2502
2503         if (!waitqueue_active(&task->dev->tctl_wait_q)) {
2504                 printk(KERN_WARNING "mbox: unexpected TCTL from DSP!\n");
2505                 return;
2506         }
2507
2508         task->dev->tctl_stat = mb->data;
2509         wake_up_interruptible(&task->dev->tctl_wait_q);
2510 }
2511
2512 void mbox_tcfg(struct mbcmd *mb)
2513 {
2514         u8 tid = mb->cmd_l;
2515         struct dsptask *task = dsptask[tid];
2516         u16 *tnm;
2517         volatile u16 *buf;
2518         int i;
2519
2520         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2521                 printk(KERN_ERR "mbox: TCFG with illegal tid! %d\n", tid);
2522                 return;
2523         }
2524         if ((task->state != TASK_ST_CFGREQ) || (cfg_cmd != MBOX_CMD_DSP_TCFG)) {
2525                 printk(KERN_WARNING "mbox: unexpected TCFG from DSP!\n");
2526                 return;
2527         }
2528
2529         if (dsp_mem_enable(ipbuf_sys_da) < 0) {
2530                 printk(KERN_ERR "mbox: TCFG - ipbuf_sys_da read failed!\n");
2531                 dsp_mem_disable(ipbuf_sys_da);
2532                 goto out;
2533         }
2534         if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2535                 printk(KERN_ERR "mbox: TCFG - IPBUF sync failed!\n");
2536                 dsp_mem_disable(ipbuf_sys_da);
2537                 goto out;
2538         }
2539
2540         /*
2541          * read configuration data on system IPBUF
2542          */
2543         buf = ipbuf_sys_da->d;
2544         task->ttyp        = buf[0];
2545         task->ipbuf_pvt_r = MKVIRT(buf[1], buf[2]);
2546         task->ipbuf_pvt_w = MKVIRT(buf[3], buf[4]);
2547         task->map_base    = MKVIRT(buf[5], buf[6]);
2548         task->map_length  = MKLONG(buf[7], buf[8]) << 1;        /* word -> byte */
2549         tnm               = MKVIRT(buf[9], buf[10]);
2550         release_ipbuf_pvt(ipbuf_sys_da);
2551         dsp_mem_disable(ipbuf_sys_da);
2552
2553         /*
2554          * copy task name string
2555          */
2556         if (dsp_address_validate(tnm, TNM_LEN, "task name buffer") < 0) {
2557                 task->name[0] = '\0';
2558                 goto out;
2559         }
2560
2561         for (i = 0; i < TNM_LEN-1; i++) {
2562                 /* avoiding byte access */
2563                 u16 tmp = tnm[i];
2564                 task->name[i] = tmp & 0x00ff;
2565                 if (!tmp)
2566                         break;
2567         }
2568         task->name[TNM_LEN-1] = '\0';
2569
2570         task->state = TASK_ST_READY;
2571 out:
2572         wake_up_interruptible(&cfg_wait_q);
2573 }
2574
2575 void mbox_tadd(struct mbcmd *mb)
2576 {
2577         u8 tid = mb->cmd_l;
2578
2579         if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBOX_CMD_DSP_TADD)) {
2580                 printk(KERN_WARNING "mbox: unexpected TADD from DSP!\n");
2581                 return;
2582         }
2583         cfg_tid = tid;
2584         wake_up_interruptible(&cfg_wait_q);
2585 }
2586
2587 void mbox_tdel(struct mbcmd *mb)
2588 {
2589         u8 tid = mb->cmd_l;
2590
2591         if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBOX_CMD_DSP_TDEL)) {
2592                 printk(KERN_WARNING "mbox: unexpected TDEL from DSP!\n");
2593                 return;
2594         }
2595         cfg_tid = tid;
2596         wake_up_interruptible(&cfg_wait_q);
2597 }
2598
2599 void mbox_err_fatal(u8 tid)
2600 {
2601         struct dsptask *task = dsptask[tid];
2602         struct taskdev *dev;
2603
2604         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2605                 printk(KERN_ERR "mbox: FATAL ERR with illegal tid! %d\n", tid);
2606                 return;
2607         }
2608
2609         /* wake up waiting processes */
2610         dev = task->dev;
2611         wake_up_interruptible_all(&dev->read_wait_q);
2612         wake_up_interruptible_all(&dev->write_wait_q);
2613         wake_up_interruptible_all(&dev->tctl_wait_q);
2614 }
2615
2616 static u16 *dbg_buf;
2617 static u16 dbg_buf_sz, dbg_line_sz;
2618 static int dbg_rp;
2619
2620 int dsp_dbg_config(u16 *buf, u16 sz, u16 lsz)
2621 {
2622 #ifdef OLD_BINARY_SUPPORT
2623         if ((mbox_revision == MBREV_3_0) || (mbox_revision == MBREV_3_2)) {
2624                 dbg_buf = NULL;
2625                 dbg_buf_sz = 0;
2626                 dbg_line_sz = 0;
2627                 dbg_rp = 0;
2628                 return 0;
2629         }
2630 #endif
2631
2632         if (dsp_address_validate(buf, sz, "debug buffer") < 0)
2633                 return -1;
2634
2635         if (lsz > sz) {
2636                 printk(KERN_ERR
2637                        "omapdsp: dbg_buf lsz (%d) is greater than its "
2638                        "buffer size (%d)\n", lsz, sz);
2639                 return -1;
2640         }
2641
2642         dbg_buf = buf;
2643         dbg_buf_sz = sz;
2644         dbg_line_sz = lsz;
2645         dbg_rp = 0;
2646
2647         return 0;
2648 }
2649
2650 void dsp_dbg_stop(void)
2651 {
2652         dbg_buf = NULL;
2653 }
2654
2655 #ifdef OLD_BINARY_SUPPORT
2656 static void mbox_dbg_old(struct mbcmd *mb);
2657 #endif
2658
2659 void mbox_dbg(struct mbcmd *mb)
2660 {
2661         u8 tid = mb->cmd_l;
2662         int cnt = mb->data;
2663         char s[80], *s_end = &s[79], *p;
2664         u16 *src;
2665         int i;
2666
2667 #ifdef OLD_BINARY_SUPPORT
2668         if ((mbox_revision == MBREV_3_0) || (mbox_revision == MBREV_3_2)) {
2669                 mbox_dbg_old(mb);
2670                 return;
2671         }
2672 #endif
2673
2674         if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2675             (tid != TID_ANON)) {
2676                 printk(KERN_ERR "mbox: DBG with illegal tid! %d\n", tid);
2677                 return;
2678         }
2679         if (dbg_buf == NULL) {
2680                 printk(KERN_ERR "mbox: DBG command received, but "
2681                        "dbg_buf has not been configured yet.\n");
2682                 return;
2683         }
2684
2685         if (dsp_mem_enable(dbg_buf) < 0)
2686                 return;
2687
2688         src = &dbg_buf[dbg_rp];
2689         p = s;
2690         for (i = 0; i < cnt; i++) {
2691                 u16 tmp;
2692                 /*
2693                  * Be carefull that dbg_buf should not be read with
2694                  * 1-byte access since it might be placed in DARAM/SARAM
2695                  * and it can cause unexpected byteswap.
2696                  * For example,
2697                  *   *(p++) = *(src++) & 0xff;
2698                  * causes 1-byte access!
2699                  */
2700                 tmp = *src++;
2701                 *(p++) = tmp & 0xff;
2702                 if (*(p-1) == '\n') {
2703                         *p = '\0';
2704                         printk(KERN_INFO "%s", s);
2705                         p = s;
2706                         continue;
2707                 }
2708                 if (p == s_end) {
2709                         *p = '\0';
2710                         printk(KERN_INFO "%s\n", s);
2711                         p = s;
2712                         continue;
2713                 }
2714         }
2715         if (p > s) {
2716                 *p = '\0';
2717                 printk(KERN_INFO "%s\n", s);
2718         }
2719         if ((dbg_rp += cnt + 1) > dbg_buf_sz - dbg_line_sz)
2720                 dbg_rp = 0;
2721
2722         dsp_mem_disable(dbg_buf);
2723 }
2724
2725 #ifdef OLD_BINARY_SUPPORT
2726 static void mbox_dbg_old(struct mbcmd *mb)
2727 {
2728         u8 tid = mb->cmd_l;
2729         char s[80], *s_end = &s[79], *p;
2730         u16 *src;
2731         volatile u16 *buf;
2732         int cnt;
2733         int i;
2734
2735         if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2736             (tid != TID_ANON)) {
2737                 printk(KERN_ERR "mbox: DBG with illegal tid! %d\n", tid);
2738                 return;
2739         }
2740         if (dsp_mem_enable(ipbuf_sys_da) < 0) {
2741                 printk(KERN_ERR "mbox: DBG - ipbuf_sys_da read failed!\n");
2742                 return;
2743         }
2744         if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2745                 printk(KERN_ERR "mbox: DBG - IPBUF sync failed!\n");
2746                 goto out1;
2747         }
2748         buf = ipbuf_sys_da->d;
2749         cnt = buf[0];
2750         src = MKVIRT(buf[1], buf[2]);
2751         if (dsp_address_validate(src, cnt, "dbg buffer") < 0)
2752                 goto out2;
2753
2754         if (dsp_mem_enable(src) < 0)
2755                 goto out2;
2756
2757         p = s;
2758         for (i = 0; i < cnt; i++) {
2759                 u16 tmp;
2760                 /*
2761                  * Be carefull that ipbuf should not be read with
2762                  * 1-byte access since it might be placed in DARAM/SARAM
2763                  * and it can cause unexpected byteswap.
2764                  * For example,
2765                  *   *(p++) = *(src++) & 0xff;
2766                  * causes 1-byte access!
2767                  */
2768                 tmp = *src++;
2769                 *(p++) = tmp & 0xff;
2770                 if (*(p-1) == '\n') {
2771                         *p = '\0';
2772                         printk(KERN_INFO "%s", s);
2773                         p = s;
2774                         continue;
2775                 }
2776                 if (p == s_end) {
2777                         *p = '\0';
2778                         printk(KERN_INFO "%s\n", s);
2779                         p = s;
2780                         continue;
2781                 }
2782         }
2783         if (p > s) {
2784                 *p = '\0';
2785                 printk(KERN_INFO "%s\n", s);
2786         }
2787
2788         dsp_mem_disable(src);
2789 out2:
2790         release_ipbuf_pvt(ipbuf_sys_da);
2791 out1:
2792         dsp_mem_disable(ipbuf_sys_da);
2793 }
2794 #endif /* OLD_BINARY_SUPPORT */
2795
2796 /*
2797  * sysfs files: for each device
2798  */
2799
2800 /* devname */
2801 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
2802                             char *buf)
2803 {
2804         return sprintf(buf, "%s\n", to_taskdev(d)->name);
2805 }
2806
2807 /* devstate */
2808 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
2809                              char *buf)
2810 {
2811         return sprintf(buf, "%s\n", devstate_name(to_taskdev(d)->state));
2812 }
2813
2814 /* proc_list */
2815 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
2816                               char *buf)
2817 {
2818         struct taskdev *dev;
2819         struct proc_list *pl;
2820         int len = 0;
2821
2822         dev = to_taskdev(d);
2823         spin_lock(&dev->proc_list_lock);
2824         list_for_each_entry(pl, &dev->proc_list, list_head) {
2825                 /* need to lock tasklist_lock before calling
2826                  * find_task_by_pid_type. */
2827                 if (find_task_by_pid_type(PIDTYPE_PID, pl->pid) != NULL)
2828                         len += sprintf(buf + len, "%d\n", pl->pid);
2829                 read_unlock(&tasklist_lock);
2830         }
2831         spin_unlock(&dev->proc_list_lock);
2832
2833         return len;
2834 }
2835
2836 /* taskname */
2837 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
2838                              char *buf)
2839 {
2840         struct taskdev *dev = to_taskdev(d);
2841         int len;
2842
2843         if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
2844                 return -ENODEV;
2845
2846         len = sprintf(buf, "%s\n", dev->task->name);
2847
2848         devstate_read_unlock(dev);
2849         return len;
2850 }
2851
2852 /* ttyp */
2853 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
2854                          char *buf)
2855 {
2856         struct taskdev *dev = to_taskdev(d);
2857         u16 ttyp;
2858         int len = 0;
2859
2860         if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
2861                 return -ENODEV;
2862
2863         ttyp = dev->task->ttyp;
2864         len += sprintf(buf + len, "0x%04x\n", ttyp);
2865         len += sprintf(buf + len, "%s %s send\n",
2866                         (sndtyp_acv(ttyp)) ? "active" :
2867                                              "passive",
2868                         (sndtyp_wd(ttyp))  ? "word" :
2869                         (sndtyp_pvt(ttyp)) ? "private block" :
2870                                              "global block");
2871         len += sprintf(buf + len, "%s %s receive\n",
2872                         (rcvtyp_acv(ttyp)) ? "active" :
2873                                              "passive",
2874                         (rcvtyp_wd(ttyp))  ? "word" :
2875                         (rcvtyp_pvt(ttyp)) ? "private block" :
2876                                              "global block");
2877
2878         devstate_read_unlock(dev);
2879         return len;
2880 }
2881
2882 /* fifosz */
2883 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
2884                            char *buf)
2885 {
2886         struct fifo_struct *fifo = &to_taskdev(d)->rcvdt.fifo;
2887         return sprintf(buf, "%d\n", fifo->sz);
2888 }
2889
2890 static int fifosz_store(struct device *d, struct device_attribute *attr,
2891                         const char *buf, size_t count)
2892 {
2893         struct taskdev *dev = to_taskdev(d);
2894         unsigned long fifosz;
2895         int ret;
2896
2897         fifosz = simple_strtol(buf, NULL, 10);
2898         ret = taskdev_set_fifosz(dev, fifosz);
2899
2900         return (ret < 0) ? ret : strlen(buf);
2901 }
2902
2903 /* fifocnt */
2904 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
2905                             char *buf)
2906 {
2907         struct fifo_struct *fifo = &to_taskdev(d)->rcvdt.fifo;
2908         return sprintf(buf, "%d\n", fifo->cnt);
2909 }
2910
2911 /* ipblink */
2912 static __inline__ char *bid_name(u16 bid)
2913 {
2914         static char s[6];
2915
2916         switch (bid) {
2917         case BID_NULL:
2918                 return "NULL";
2919         case BID_PVT:
2920                 return "PRIVATE";
2921         default:
2922                 sprintf(s, "%d", bid);
2923                 return s;
2924         }
2925 }
2926
2927 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
2928                             char *buf)
2929 {
2930         struct rcvdt_bk_struct *rcvdt = &to_taskdev(d)->rcvdt.bk;
2931         int len;
2932
2933         spin_lock(&rcvdt->link.lock);
2934         len = sprintf(buf, "top  %s\ntail %s\n",
2935                       bid_name(rcvdt->link.top), bid_name(rcvdt->link.tail));
2936         spin_unlock(&rcvdt->link.lock);
2937
2938         return len;
2939 }
2940
2941 /* wsz */
2942 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
2943                         char *buf)
2944 {
2945         return sprintf(buf, "%d\n", to_taskdev(d)->wsz);
2946 }
2947
2948 /* mmap */
2949 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
2950                          char *buf)
2951 {
2952         struct dsptask *task = to_taskdev(d)->task;
2953         return sprintf(buf, "0x%p 0x%x\n", task->map_base, task->map_length);
2954 }
2955
2956 /*
2957  * called from ipbuf_show()
2958  */
2959 int ipbuf_is_held(u8 tid, u16 bid)
2960 {
2961         struct dsptask *task = dsptask[tid];
2962         struct ipblink *link;
2963         u16 b;
2964         int ret = 0;
2965
2966         if (task == NULL)
2967                 return 0;
2968
2969         link = &task->dev->rcvdt.bk.link;
2970         spin_lock(&link->lock);
2971         ipblink_for_each(b, link) {
2972                 if (b == bid) { /* found */
2973                         ret = 1;
2974                         break;
2975                 }
2976         }
2977         spin_unlock(&link->lock);
2978
2979         return ret;
2980 }
2981
2982 int __init dsp_taskmod_init(void)
2983 {
2984         int retval;
2985
2986         memset(taskdev, 0, sizeof(void *) * TASKDEV_MAX);
2987         memset(dsptask, 0, sizeof(void *) * TASKDEV_MAX);
2988
2989         retval = register_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask",
2990                                  &dsp_task_fops);
2991         if (retval < 0) {
2992                 printk(KERN_ERR
2993                        "omapdsp: failed to register task device: %d\n", retval);
2994                 return retval;
2995         }
2996
2997         retval = bus_register(&dsptask_bus);
2998         if (retval) {
2999                 printk(KERN_ERR
3000                        "omapdsp: failed to register DSP task bus: %d\n",
3001                        retval);
3002                 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3003                 return -EINVAL;
3004         }
3005         retval = driver_register(&dsptask_driver);
3006         if (retval) {
3007                 printk(KERN_ERR
3008                        "omapdsp: failed to register DSP task driver: %d\n",
3009                        retval);
3010                 bus_unregister(&dsptask_bus);
3011                 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3012                 return -EINVAL;
3013         }
3014         dsp_task_class = class_create(THIS_MODULE, "dsptask");
3015
3016         return 0;
3017 }
3018
3019 void dsp_taskmod_exit(void)
3020 {
3021         class_destroy(dsp_task_class);
3022         driver_unregister(&dsptask_driver);
3023         bus_unregister(&dsptask_bus);
3024         unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3025 }