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