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