]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/plat-omap/dsp/task.c
ARM: OMAP: Misc compile fixes after updating to current mainline tree
[linux-2.6-omap-h63xx.git] / arch / arm / plat-omap / dsp / task.c
1 /*
2  * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
3  *
4  * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
5  *
6  * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/major.h>
28 #include <linux/fs.h>
29 #include <linux/poll.h>
30 #include <linux/platform_device.h>
31 #include <linux/slab.h>
32 #include <linux/sched.h>
33 #include <linux/mm.h>
34 #include <linux/mutex.h>
35 #include <linux/interrupt.h>
36 #include <linux/kfifo.h>
37 #include <asm/uaccess.h>
38 #include <asm/io.h>
39 #include <asm/arch/mailbox.h>
40 #include <asm/arch/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 struct page *dsp_task_mmap_nopage(struct vm_area_struct *vma,
1315                                          unsigned long address, int *type)
1316 {
1317         return NOPAGE_SIGBUS;
1318 }
1319
1320 static struct vm_operations_struct dsp_task_vm_ops = {
1321         .open = dsp_task_mmap_open,
1322         .close = dsp_task_mmap_close,
1323         .nopage = dsp_task_mmap_nopage,
1324 };
1325
1326 static int dsp_task_mmap(struct file *filp, struct vm_area_struct *vma)
1327 {
1328         void *tmp_vadr;
1329         unsigned long tmp_padr, tmp_vmadr, off;
1330         size_t req_len, tmp_len;
1331         unsigned int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
1332         struct taskdev *dev = taskdev[minor];
1333         struct dsptask *task;
1334         int ret = 0;
1335
1336         if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
1337                 return -ENODEV;
1338         task = dev->task;
1339
1340         /*
1341          * Don't swap this area out
1342          * Don't dump this area to a core file
1343          */
1344         vma->vm_flags |= VM_RESERVED | VM_IO;
1345
1346         /* Do not cache this area */
1347         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1348
1349         req_len = vma->vm_end - vma->vm_start;
1350         off = vma->vm_pgoff << PAGE_SHIFT;
1351         tmp_vmadr = vma->vm_start;
1352         tmp_vadr = task->map_base + off;
1353         do {
1354                 tmp_padr = omap_mmu_virt_to_phys(&dsp_mmu, tmp_vadr, &tmp_len);
1355                 if (tmp_padr == 0) {
1356                         printk(KERN_ERR
1357                                "omapdsp: task %s: illegal address "
1358                                "for mmap: %p", task->name, tmp_vadr);
1359                         /* partial mapping will be cleared in upper layer */
1360                         ret = -EINVAL;
1361                         goto unlock_out;
1362                 }
1363                 if (tmp_len > req_len)
1364                         tmp_len = req_len;
1365
1366                 pr_debug("omapdsp: mmap info: "
1367                          "vmadr = %08lx, padr = %08lx, len = %x\n",
1368                          tmp_vmadr, tmp_padr, tmp_len);
1369                 if (remap_pfn_range(vma, tmp_vmadr, tmp_padr >> PAGE_SHIFT,
1370                                     tmp_len, vma->vm_page_prot) != 0) {
1371                         printk(KERN_ERR
1372                                "omapdsp: task %s: remap_page_range() failed.\n",
1373                                task->name);
1374                         /* partial mapping will be cleared in upper layer */
1375                         ret = -EINVAL;
1376                         goto unlock_out;
1377                 }
1378
1379                 req_len   -= tmp_len;
1380                 tmp_vmadr += tmp_len;
1381                 tmp_vadr  += tmp_len;
1382         } while (req_len);
1383
1384         vma->vm_ops = &dsp_task_vm_ops;
1385         vma->vm_private_data = dev;
1386         omap_mmu_exmap_use(&dsp_mmu, task->map_base, vma->vm_end - vma->vm_start);
1387
1388 unlock_out:
1389         devstate_read_unlock(dev);
1390         return ret;
1391 }
1392
1393 static int dsp_task_open(struct inode *inode, struct file *file)
1394 {
1395         unsigned int minor = MINOR(inode->i_rdev);
1396         struct taskdev *dev;
1397         int ret = 0;
1398
1399         if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL))
1400                 return -ENODEV;
1401
1402  restart:
1403         mutex_lock(&dev->usecount_lock);
1404         down_write(&dev->state_sem);
1405
1406         /* state can be NOTASK, ATTACHED/FREEZED, KILLING, GARBAGE or INVALID here. */
1407         switch (dev->state & TASKDEV_ST_STATE_MASK) {
1408         case TASKDEV_ST_NOTASK:
1409                 break;
1410         case TASKDEV_ST_ATTACHED:
1411                 goto attached;
1412
1413         case TASKDEV_ST_INVALID:
1414                 up_write(&dev->state_sem);
1415                 mutex_unlock(&dev->usecount_lock);
1416                 return -ENODEV;
1417
1418         case TASKDEV_ST_FREEZED:
1419         case TASKDEV_ST_KILLING:
1420         case TASKDEV_ST_GARBAGE:
1421         case TASKDEV_ST_DELREQ:
1422                 /* on the kill process. wait until it becomes NOTASK. */
1423                 up_write(&dev->state_sem);
1424                 mutex_unlock(&dev->usecount_lock);
1425                 if (devstate_write_lock(dev, TASKDEV_ST_NOTASK) < 0)
1426                         return -EINTR;
1427                 devstate_write_unlock(dev);
1428                 goto restart;
1429         }
1430
1431         /* NOTASK */
1432         set_taskdev_state(dev, TASKDEV_ST_ADDREQ);
1433         /* wake up twch daemon for tadd */
1434         dsp_twch_touch();
1435         up_write(&dev->state_sem);
1436         if (devstate_write_lock(dev, TASKDEV_ST_ATTACHED |
1437                                 TASKDEV_ST_ADDFAIL) < 0) {
1438                 /* cancelled */
1439                 if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) {
1440                         mutex_unlock(&dev->usecount_lock);
1441                         /* out of control ??? */
1442                         return -EINTR;
1443                 }
1444                 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1445                 ret = -EINTR;
1446                 goto change_out;
1447         }
1448         if (dev->state & TASKDEV_ST_ADDFAIL) {
1449                 printk(KERN_ERR "omapdsp: task attach failed for %s!\n",
1450                        dev->name);
1451                 ret = -EBUSY;
1452                 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1453                 goto change_out;
1454         }
1455
1456  attached:
1457         ret = proc_list_add(&dev->proc_list_lock,
1458                             &dev->proc_list, current, file);
1459         if (ret)
1460                 goto out;
1461
1462         dev->usecount++;
1463         file->f_op = &dev->fops;
1464         up_write(&dev->state_sem);
1465         mutex_unlock(&dev->usecount_lock);
1466
1467 #ifdef DSP_PTE_FREE     /* not used currently. */
1468         dsp_map_update(current);
1469         dsp_cur_users_add(current);
1470 #endif /* DSP_PTE_FREE */
1471         return 0;
1472
1473  change_out:
1474         wake_up_interruptible_all(&dev->state_wait_q);
1475  out:
1476         up_write(&dev->state_sem);
1477         mutex_unlock(&dev->usecount_lock);
1478         return ret;
1479 }
1480
1481 static int dsp_task_release(struct inode *inode, struct file *file)
1482 {
1483         unsigned int minor = MINOR(inode->i_rdev);
1484         struct taskdev *dev = taskdev[minor];
1485
1486 #ifdef DSP_PTE_FREE     /* not used currently. */
1487         dsp_cur_users_del(current);
1488 #endif /* DSP_PTE_FREE */
1489
1490         if (has_taskdev_lock(dev))
1491                 taskdev_unlock(dev);
1492
1493         proc_list_del(&dev->proc_list_lock, &dev->proc_list, current, file);
1494         mutex_lock(&dev->usecount_lock);
1495         if (--dev->usecount > 0) {
1496                 /* other processes are using this device. no state change. */
1497                 mutex_unlock(&dev->usecount_lock);
1498                 return 0;
1499         }
1500
1501         /* usecount == 0 */
1502         down_write(&dev->state_sem);
1503
1504         /* state can be ATTACHED/FREEZED, KILLING or GARBAGE here. */
1505         switch (dev->state & TASKDEV_ST_STATE_MASK) {
1506
1507         case TASKDEV_ST_KILLING:
1508                 break;
1509
1510         case TASKDEV_ST_GARBAGE:
1511                 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1512                 wake_up_interruptible_all(&dev->state_wait_q);
1513                 break;
1514
1515         case TASKDEV_ST_ATTACHED:
1516         case TASKDEV_ST_FREEZED:
1517                 if (is_dynamic_task(minor)) {
1518                         set_taskdev_state(dev, TASKDEV_ST_DELREQ);
1519                         /* wake up twch daemon for tdel */
1520                         dsp_twch_touch();
1521                 }
1522                 break;
1523
1524         }
1525
1526         up_write(&dev->state_sem);
1527         mutex_unlock(&dev->usecount_lock);
1528         return 0;
1529 }
1530
1531 /*
1532  * mkdev / rmdev
1533  */
1534 int dsp_mkdev(char *name)
1535 {
1536         struct taskdev *dev;
1537         int status;
1538         unsigned char minor;
1539         int ret;
1540
1541         if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
1542                 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1543                 return -EINVAL;
1544         }
1545
1546         if (mutex_lock_interruptible(&devmgr_lock))
1547                 return -EINTR;
1548
1549         /* naming check */
1550         for (minor = 0; minor < TASKDEV_MAX; minor++) {
1551                 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1552                         printk(KERN_ERR
1553                                "omapdsp: task device name %s is already "
1554                                "in use.\n", name);
1555                         ret = -EINVAL;
1556                         goto out;
1557                 }
1558         }
1559
1560         /* find free minor number */
1561         for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1562                 if (taskdev[minor] == NULL)
1563                         goto do_make;
1564         }
1565         printk(KERN_ERR "omapdsp: Too many task devices.\n");
1566         ret = -EBUSY;
1567         goto out;
1568
1569 do_make:
1570         if ((dev = kzalloc(sizeof(struct taskdev), GFP_KERNEL)) == NULL) {
1571                 ret = -ENOMEM;
1572                 goto out;
1573         }
1574         if ((status = taskdev_init(dev, name, minor)) < 0) {
1575                 kfree(dev);
1576                 ret = status;
1577                 goto out;
1578         }
1579         ret = minor;
1580
1581 out:
1582         mutex_unlock(&devmgr_lock);
1583         return ret;
1584 }
1585
1586 int dsp_rmdev(char *name)
1587 {
1588         unsigned char minor;
1589         int status;
1590         int ret;
1591
1592         if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
1593                 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1594                 return -EINVAL;
1595         }
1596
1597         if (mutex_lock_interruptible(&devmgr_lock))
1598                 return -EINTR;
1599
1600         /* find in dynamic devices */
1601         for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1602                 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name))
1603                         goto do_remove;
1604         }
1605
1606         /* find in static devices */
1607         for (minor = 0; minor < n_task; minor++) {
1608                 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1609                         printk(KERN_ERR
1610                                "omapdsp: task device %s is static.\n", name);
1611                         ret = -EINVAL;
1612                         goto out;
1613                 }
1614         }
1615
1616         printk(KERN_ERR "omapdsp: task device %s not found.\n", name);
1617         return -EINVAL;
1618
1619 do_remove:
1620         ret = minor;
1621         if ((status = dsp_rmdev_minor(minor)) < 0)
1622                 ret = status;
1623 out:
1624         mutex_unlock(&devmgr_lock);
1625         return ret;
1626 }
1627
1628 static int dsp_rmdev_minor(unsigned char minor)
1629 {
1630         struct taskdev *dev = taskdev[minor];
1631
1632         while (!down_write_trylock(&dev->state_sem)) {
1633                 down_read(&dev->state_sem);
1634                 if (dev->state & (TASKDEV_ST_ATTACHED |
1635                                   TASKDEV_ST_FREEZED)) {
1636                         /*
1637                          * task is working. kill it.
1638                          * ATTACHED -> FREEZED can be changed under
1639                          * down_read of state_sem..
1640                          */
1641                         set_taskdev_state(dev, TASKDEV_ST_FREEZED);
1642                         wake_up_interruptible_all(&dev->read_wait_q);
1643                         wake_up_interruptible_all(&dev->write_wait_q);
1644                         wake_up_interruptible_all(&dev->tctl_wait_q);
1645                 }
1646                 up_read(&dev->state_sem);
1647                 schedule();
1648         }
1649
1650         switch (dev->state & TASKDEV_ST_STATE_MASK) {
1651
1652         case TASKDEV_ST_NOTASK:
1653         case TASKDEV_ST_INVALID:
1654                 /* fine */
1655                 goto notask;
1656
1657         case TASKDEV_ST_ATTACHED:
1658         case TASKDEV_ST_FREEZED:
1659                 /* task is working. kill it. */
1660                 set_taskdev_state(dev, TASKDEV_ST_KILLING);
1661                 up_write(&dev->state_sem);
1662                 dsp_tdel_bh(dev, TDEL_KILL);
1663                 goto invalidate;
1664
1665         case TASKDEV_ST_ADDREQ:
1666                 /* open() is waiting. drain it. */
1667                 set_taskdev_state(dev, TASKDEV_ST_ADDFAIL);
1668                 wake_up_interruptible_all(&dev->state_wait_q);
1669                 break;
1670
1671         case TASKDEV_ST_DELREQ:
1672                 /* nobody is waiting. */
1673                 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1674                 wake_up_interruptible_all(&dev->state_wait_q);
1675                 break;
1676
1677         case TASKDEV_ST_ADDING:
1678         case TASKDEV_ST_DELING:
1679         case TASKDEV_ST_KILLING:
1680         case TASKDEV_ST_GARBAGE:
1681         case TASKDEV_ST_ADDFAIL:
1682                 /* transient state. wait for a moment. */
1683                 break;
1684
1685         }
1686
1687         up_write(&dev->state_sem);
1688
1689 invalidate:
1690         /* wait for some time and hope the state is settled */
1691         devstate_read_lock_timeout(dev, TASKDEV_ST_NOTASK, 5 * HZ);
1692         if (!(dev->state & TASKDEV_ST_NOTASK)) {
1693                 printk(KERN_WARNING
1694                        "omapdsp: illegal device state (%s) on rmdev %s.\n",
1695                        devstate_name(dev->state), dev->name);
1696         }
1697 notask:
1698         set_taskdev_state(dev, TASKDEV_ST_INVALID);
1699         devstate_read_unlock(dev);
1700
1701         taskdev_delete(minor);
1702         kfree(dev);
1703
1704         return 0;
1705 }
1706
1707 static struct file_operations dsp_task_fops = {
1708         .owner   = THIS_MODULE,
1709         .poll    = dsp_task_poll,
1710         .ioctl   = dsp_task_ioctl,
1711         .open    = dsp_task_open,
1712         .release = dsp_task_release,
1713 };
1714
1715 static void dsptask_dev_release(struct device *dev)
1716 {
1717 }
1718
1719 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor)
1720 {
1721         int ret;
1722         struct device *task_dev;
1723
1724         taskdev[minor] = dev;
1725
1726         spin_lock_init(&dev->proc_list_lock);
1727         INIT_LIST_HEAD(&dev->proc_list);
1728         init_waitqueue_head(&dev->read_wait_q);
1729         init_waitqueue_head(&dev->write_wait_q);
1730         init_waitqueue_head(&dev->tctl_wait_q);
1731         mutex_init(&dev->read_mutex);
1732         mutex_init(&dev->write_mutex);
1733         mutex_init(&dev->tctl_mutex);
1734         mutex_init(&dev->lock);
1735         spin_lock_init(&dev->wsz_lock);
1736         dev->tctl_ret = -EINVAL;
1737         dev->lock_pid = 0;
1738
1739         strncpy(dev->name, name, TNM_LEN);
1740         dev->name[TNM_LEN-1] = '\0';
1741         set_taskdev_state(dev, (minor < n_task) ? TASKDEV_ST_ATTACHED : TASKDEV_ST_NOTASK);
1742         dev->usecount = 0;
1743         mutex_init(&dev->usecount_lock);
1744         memcpy(&dev->fops, &dsp_task_fops, sizeof(struct file_operations));
1745
1746         dev->dev.parent = omap_dsp->dev;
1747         dev->dev.bus = &dsptask_bus;
1748         sprintf(dev->dev.bus_id, "dsptask%d", minor);
1749         dev->dev.release = dsptask_dev_release;
1750         ret = device_register(&dev->dev);
1751         if (ret) {
1752                 printk(KERN_ERR "device_register failed: %d\n", ret);
1753                 return ret;
1754         }
1755         ret = device_create_file(&dev->dev, &dev_attr_devname);
1756         if (ret)
1757                 goto fail_create_devname;
1758         ret = device_create_file(&dev->dev, &dev_attr_devstate);
1759         if (ret)
1760                 goto fail_create_devstate;
1761         ret = device_create_file(&dev->dev, &dev_attr_proc_list);
1762         if (ret)
1763                 goto fail_create_proclist;
1764
1765         task_dev = device_create(dsp_task_class, NULL,
1766                                  MKDEV(OMAP_DSP_TASK_MAJOR, minor),
1767                                  "dsptask%d", (int)minor);
1768
1769         if (unlikely(IS_ERR(task_dev))) {
1770                 ret = -EINVAL;
1771                 goto fail_create_taskclass;
1772         }
1773
1774         init_waitqueue_head(&dev->state_wait_q);
1775         init_rwsem(&dev->state_sem);
1776
1777         return 0;
1778
1779  fail_create_taskclass:
1780         device_remove_file(&dev->dev, &dev_attr_proc_list);
1781  fail_create_proclist:
1782         device_remove_file(&dev->dev, &dev_attr_devstate);
1783  fail_create_devstate:
1784         device_remove_file(&dev->dev, &dev_attr_devname);
1785  fail_create_devname:
1786         device_unregister(&dev->dev);
1787         return ret;
1788 }
1789
1790 static void taskdev_delete(unsigned char minor)
1791 {
1792         struct taskdev *dev = taskdev[minor];
1793
1794         if (!dev)
1795                 return;
1796         device_remove_file(&dev->dev, &dev_attr_devname);
1797         device_remove_file(&dev->dev, &dev_attr_devstate);
1798         device_remove_file(&dev->dev, &dev_attr_proc_list);
1799         device_destroy(dsp_task_class, MKDEV(OMAP_DSP_TASK_MAJOR, minor));
1800         device_unregister(&dev->dev);
1801         proc_list_flush(&dev->proc_list_lock, &dev->proc_list);
1802         taskdev[minor] = NULL;
1803 }
1804
1805 static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task)
1806 {
1807         u16 ttyp = task->ttyp;
1808         int ret;
1809
1810         dev->fops.read =
1811                 sndtyp_acv(ttyp) ?
1812                 sndtyp_wd(ttyp) ? dsp_task_read_wd_acv:
1813                 /* sndtyp_bk */   dsp_task_read_bk_acv:
1814                 /* sndtyp_psv */
1815                 sndtyp_wd(ttyp) ? dsp_task_read_wd_psv:
1816                 /* sndtyp_bk */   dsp_task_read_bk_psv;
1817         if (sndtyp_wd(ttyp)) {
1818                 /* word */
1819                 size_t fifosz = sndtyp_psv(ttyp) ? 2:32; /* passive:active */
1820
1821                 dev->rcvdt.fifo = kfifo_alloc(fifosz, GFP_KERNEL,
1822                                               &dev->read_lock);
1823                 if (IS_ERR(dev->rcvdt.fifo)) {
1824                         printk(KERN_ERR
1825                                "omapdsp: unable to allocate receive buffer. "
1826                                "(%d bytes for %s)\n", fifosz, dev->name);
1827                         return -ENOMEM;
1828                 }
1829         } else {
1830                 /* block */
1831                 INIT_IPBLINK(&dev->rcvdt.bk.link);
1832                 dev->rcvdt.bk.rp = 0;
1833         }
1834
1835         dev->fops.write =
1836                 rcvtyp_wd(ttyp) ? dsp_task_write_wd:
1837                 /* rcvbyp_bk */   dsp_task_write_bk;
1838         dev->wsz = rcvtyp_acv(ttyp) ? 0 :               /* active */
1839                 rcvtyp_wd(ttyp)  ? 2 :          /* passive word */
1840                 ipbcfg.lsz*2;   /* passive block */
1841
1842         if (task->map_length)
1843                 dev->fops.mmap = dsp_task_mmap;
1844
1845         ret = device_create_file(&dev->dev, &dev_attr_taskname);
1846         if (unlikely(ret))
1847                 goto fail_create_taskname;
1848         ret = device_create_file(&dev->dev, &dev_attr_ttyp);
1849         if (unlikely(ret))
1850                 goto fail_create_ttyp;
1851         ret = device_create_file(&dev->dev, &dev_attr_wsz);
1852         if (unlikely(ret))
1853                 goto fail_create_wsz;
1854         if (task->map_length) {
1855                 ret = device_create_file(&dev->dev, &dev_attr_mmap);
1856                 if (unlikely(ret))
1857                         goto fail_create_mmap;
1858         }
1859         if (sndtyp_wd(ttyp)) {
1860                 ret = device_create_file(&dev->dev, &dev_attr_fifosz);
1861                 if (unlikely(ret))
1862                         goto fail_create_fifosz;
1863                 ret = device_create_file(&dev->dev, &dev_attr_fifocnt);
1864                 if (unlikely(ret))
1865                         goto fail_create_fifocnt;
1866         } else {
1867                 ret = device_create_file(&dev->dev, &dev_attr_ipblink);
1868                 if (unlikely(ret))
1869                         goto fail_create_ipblink;
1870         }
1871
1872         dev->task = task;
1873         task->dev = dev;
1874
1875         return 0;
1876
1877  fail_create_fifocnt:
1878         device_remove_file(&dev->dev, &dev_attr_fifosz);
1879  fail_create_ipblink:
1880  fail_create_fifosz:
1881         if (task->map_length)
1882                 device_remove_file(&dev->dev, &dev_attr_mmap);
1883  fail_create_mmap:
1884         device_remove_file(&dev->dev, &dev_attr_wsz);
1885  fail_create_wsz:
1886         device_remove_file(&dev->dev, &dev_attr_ttyp);
1887  fail_create_ttyp:
1888         device_remove_file(&dev->dev, &dev_attr_taskname);
1889  fail_create_taskname:
1890         if (task->map_length)
1891                 dev->fops.mmap = NULL;
1892
1893         dev->fops.write = NULL;
1894         dev->wsz = 0;
1895
1896         dev->fops.read = NULL;
1897         taskdev_flush_buf(dev);
1898
1899         if (sndtyp_wd(ttyp))
1900                 kfifo_free(dev->rcvdt.fifo);
1901
1902         dev->task = NULL;
1903
1904         return ret;
1905 }
1906
1907 static void taskdev_detach_task(struct taskdev *dev)
1908 {
1909         u16 ttyp = dev->task->ttyp;
1910
1911         device_remove_file(&dev->dev, &dev_attr_taskname);
1912         device_remove_file(&dev->dev, &dev_attr_ttyp);
1913         if (sndtyp_wd(ttyp)) {
1914                 device_remove_file(&dev->dev, &dev_attr_fifosz);
1915                 device_remove_file(&dev->dev, &dev_attr_fifocnt);
1916         } else
1917                 device_remove_file(&dev->dev, &dev_attr_ipblink);
1918         device_remove_file(&dev->dev, &dev_attr_wsz);
1919         if (dev->task->map_length) {
1920                 device_remove_file(&dev->dev, &dev_attr_mmap);
1921                 dev->fops.mmap = NULL;
1922         }
1923
1924         dev->fops.read = NULL;
1925         taskdev_flush_buf(dev);
1926         if (sndtyp_wd(ttyp))
1927                 kfifo_free(dev->rcvdt.fifo);
1928
1929         dev->fops.write = NULL;
1930         dev->wsz = 0;
1931
1932         pr_info("omapdsp: taskdev %s disabled.\n", dev->name);
1933         dev->task = NULL;
1934 }
1935
1936 /*
1937  * tadd / tdel / tkill
1938  */
1939 static int dsp_tadd(struct taskdev *dev, dsp_long_t adr)
1940 {
1941         struct dsptask *task;
1942         struct mb_exarg arg;
1943         u8 tid, tid_response;
1944         u16 argv[2];
1945         int ret = 0;
1946
1947         if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) {
1948                 printk(KERN_ERR
1949                        "omapdsp: taskdev %s is not requesting for tadd. "
1950                        "(state is %s)\n", dev->name, devstate_name(dev->state));
1951                 return -EINVAL;
1952         }
1953         set_taskdev_state(dev, TASKDEV_ST_ADDING);
1954         devstate_write_unlock(dev);
1955
1956         if (adr == TADD_ABORTADR) {
1957                 /* aborting tadd intentionally */
1958                 pr_info("omapdsp: tadd address is ABORTADR.\n");
1959                 goto fail_out;
1960         }
1961         if (adr >= DSPSPACE_SIZE) {
1962                 printk(KERN_ERR
1963                        "omapdsp: illegal address 0x%08x for tadd\n", adr);
1964                 ret = -EINVAL;
1965                 goto fail_out;
1966         }
1967
1968         adr >>= 1;      /* word address */
1969         argv[0] = adr >> 16;    /* addrh */
1970         argv[1] = adr & 0xffff; /* addrl */
1971
1972         if (mutex_lock_interruptible(&cfg_lock)) {
1973                 ret = -EINTR;
1974                 goto fail_out;
1975         }
1976         cfg_tid = TID_ANON;
1977         cfg_cmd = MBOX_CMD_DSP_TADD;
1978         arg.tid  = TID_ANON;
1979         arg.argc = 2;
1980         arg.argv = argv;
1981
1982         if (dsp_mem_sync_inc() < 0) {
1983                 printk(KERN_ERR "omapdsp: memory sync failed!\n");
1984                 ret = -EBUSY;
1985                 goto fail_out;
1986         }
1987         mbcompose_send_and_wait_exarg(TADD, 0, 0, &arg, &cfg_wait_q);
1988
1989         tid = cfg_tid;
1990         cfg_tid = TID_ANON;
1991         cfg_cmd = 0;
1992         mutex_unlock(&cfg_lock);
1993
1994         if (tid == TID_ANON) {
1995                 printk(KERN_ERR "omapdsp: tadd failed!\n");
1996                 ret = -EINVAL;
1997                 goto fail_out;
1998         }
1999         if ((tid < n_task) || dsptask[tid]) {
2000                 printk(KERN_ERR "omapdsp: illegal tid (%d)!\n", tid);
2001                 ret = -EINVAL;
2002                 goto fail_out;
2003         }
2004         if ((task = kzalloc(sizeof(struct dsptask), GFP_KERNEL)) == NULL) {
2005                 ret = -ENOMEM;
2006                 goto del_out;
2007         }
2008
2009         if ((ret = dsp_task_config(task, tid)) < 0)
2010                 goto free_out;
2011
2012         if (strcmp(dev->name, task->name)) {
2013                 printk(KERN_ERR
2014                        "omapdsp: task name (%s) doesn't match with "
2015                        "device name (%s).\n", task->name, dev->name);
2016                 ret = -EINVAL;
2017                 goto free_out;
2018         }
2019
2020         if ((ret = taskdev_attach_task(dev, task)) < 0)
2021                 goto free_out;
2022
2023         dsp_task_init(task);
2024         pr_info("omapdsp: taskdev %s enabled.\n", dev->name);
2025         set_taskdev_state(dev, TASKDEV_ST_ATTACHED);
2026         wake_up_interruptible_all(&dev->state_wait_q);
2027         return 0;
2028
2029 free_out:
2030         kfree(task);
2031
2032 del_out:
2033         printk(KERN_ERR "omapdsp: deleting the task...\n");
2034
2035         set_taskdev_state(dev, TASKDEV_ST_DELING);
2036
2037         if (mutex_lock_interruptible(&cfg_lock)) {
2038                 printk(KERN_ERR "omapdsp: aborting tdel process. "
2039                                 "DSP side could be corrupted.\n");
2040                 goto fail_out;
2041         }
2042         cfg_tid = TID_ANON;
2043         cfg_cmd = MBOX_CMD_DSP_TDEL;
2044         mbcompose_send_and_wait(TDEL, tid, TDEL_KILL, &cfg_wait_q);
2045         tid_response = cfg_tid;
2046         cfg_tid = TID_ANON;
2047         cfg_cmd = 0;
2048         mutex_unlock(&cfg_lock);
2049
2050         if (tid_response != tid)
2051                 printk(KERN_ERR "omapdsp: tdel failed. "
2052                                 "DSP side could be corrupted.\n");
2053
2054 fail_out:
2055         set_taskdev_state(dev, TASKDEV_ST_ADDFAIL);
2056         wake_up_interruptible_all(&dev->state_wait_q);
2057         return ret;
2058 }
2059
2060 int dsp_tadd_minor(unsigned char minor, dsp_long_t adr)
2061 {
2062         struct taskdev *dev;
2063         int status;
2064         int ret;
2065
2066         if (mutex_lock_interruptible(&devmgr_lock))
2067                 return -EINTR;
2068
2069         if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2070                 printk(KERN_ERR
2071                        "omapdsp: no task device with minor %d\n", minor);
2072                 ret = -EINVAL;
2073                 goto out;
2074         }
2075         ret = minor;
2076         if ((status = dsp_tadd(dev, adr)) < 0)
2077                 ret = status;
2078
2079 out:
2080         mutex_unlock(&devmgr_lock);
2081         return ret;
2082 }
2083
2084 static int dsp_tdel(struct taskdev *dev)
2085 {
2086         if (!devstate_write_lock_and_test(dev, TASKDEV_ST_DELREQ)) {
2087                 printk(KERN_ERR
2088                        "omapdsp: taskdev %s is not requesting for tdel. "
2089                        "(state is %s)\n", dev->name, devstate_name(dev->state));
2090                 return -EINVAL;
2091         }
2092         set_taskdev_state(dev, TASKDEV_ST_DELING);
2093         devstate_write_unlock(dev);
2094
2095         return dsp_tdel_bh(dev, TDEL_SAFE);
2096 }
2097
2098 int dsp_tdel_minor(unsigned char minor)
2099 {
2100         struct taskdev *dev;
2101         int status;
2102         int ret;
2103
2104         if (mutex_lock_interruptible(&devmgr_lock))
2105                 return -EINTR;
2106
2107         if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2108                 printk(KERN_ERR
2109                        "omapdsp: no task device with minor %d\n", minor);
2110                 ret = -EINVAL;
2111                 goto out;
2112         }
2113
2114         ret = minor;
2115         if ((status = dsp_tdel(dev)) < 0)
2116                 ret = status;
2117
2118 out:
2119         mutex_unlock(&devmgr_lock);
2120         return ret;
2121 }
2122
2123 static int dsp_tkill(struct taskdev *dev)
2124 {
2125         while (!down_write_trylock(&dev->state_sem)) {
2126                 if (!devstate_read_lock_and_test(dev, (TASKDEV_ST_ATTACHED |
2127                                                        TASKDEV_ST_FREEZED))) {
2128                         printk(KERN_ERR
2129                                "omapdsp: task has not been attached for "
2130                                "taskdev %s\n", dev->name);
2131                         return -EINVAL;
2132                 }
2133                 /* ATTACHED -> FREEZED can be changed under read semaphore. */
2134                 set_taskdev_state(dev, TASKDEV_ST_FREEZED);
2135                 wake_up_interruptible_all(&dev->read_wait_q);
2136                 wake_up_interruptible_all(&dev->write_wait_q);
2137                 wake_up_interruptible_all(&dev->tctl_wait_q);
2138                 devstate_read_unlock(dev);
2139                 schedule();
2140         }
2141
2142         if (!(dev->state & (TASKDEV_ST_ATTACHED |
2143                             TASKDEV_ST_FREEZED))) {
2144                 printk(KERN_ERR
2145                        "omapdsp: task has not been attached for taskdev %s\n",
2146                        dev->name);
2147                 devstate_write_unlock(dev);
2148                 return -EINVAL;
2149         }
2150         if (!is_dynamic_task(dev->task->tid)) {
2151                 printk(KERN_ERR "omapdsp: task %s is not a dynamic task.\n",
2152                        dev->name);
2153                 devstate_write_unlock(dev);
2154                 return -EINVAL;
2155         }
2156         set_taskdev_state(dev, TASKDEV_ST_KILLING);
2157         devstate_write_unlock(dev);
2158
2159         return dsp_tdel_bh(dev, TDEL_KILL);
2160 }
2161
2162 int dsp_tkill_minor(unsigned char minor)
2163 {
2164         struct taskdev *dev;
2165         int status;
2166         int ret;
2167
2168         if (mutex_lock_interruptible(&devmgr_lock))
2169                 return -EINTR;
2170
2171         if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2172                 printk(KERN_ERR
2173                        "omapdsp: no task device with minor %d\n", minor);
2174                 ret = -EINVAL;
2175                 goto out;
2176         }
2177
2178         ret = minor;
2179         if ((status = dsp_tkill(dev)) < 0)
2180                 ret = status;
2181
2182 out:
2183         mutex_unlock(&devmgr_lock);
2184         return ret;
2185 }
2186
2187 static int dsp_tdel_bh(struct taskdev *dev, u16 type)
2188 {
2189         struct dsptask *task;
2190         u8 tid, tid_response;
2191         int ret = 0;
2192
2193         task = dev->task;
2194         tid = task->tid;
2195         if (mutex_lock_interruptible(&cfg_lock)) {
2196                 if (type == TDEL_SAFE) {
2197                         set_taskdev_state(dev, TASKDEV_ST_DELREQ);
2198                         return -EINTR;
2199                 } else {
2200                         tid_response = TID_ANON;
2201                         ret = -EINTR;
2202                         goto detach_out;
2203                 }
2204         }
2205         cfg_tid = TID_ANON;
2206         cfg_cmd = MBOX_CMD_DSP_TDEL;
2207         mbcompose_send_and_wait(TDEL, tid, type, &cfg_wait_q);
2208         tid_response = cfg_tid;
2209         cfg_tid = TID_ANON;
2210         cfg_cmd = 0;
2211         mutex_unlock(&cfg_lock);
2212
2213 detach_out:
2214         taskdev_detach_task(dev);
2215         dsp_task_unconfig(task);
2216         kfree(task);
2217
2218         if (tid_response != tid) {
2219                 printk(KERN_ERR "omapdsp: %s failed!\n",
2220                        (type == TDEL_SAFE) ? "tdel" : "tkill");
2221                 ret = -EINVAL;
2222         }
2223         down_write(&dev->state_sem);
2224         set_taskdev_state(dev, (dev->usecount > 0) ? TASKDEV_ST_GARBAGE :
2225                                            TASKDEV_ST_NOTASK);
2226         wake_up_interruptible_all(&dev->state_wait_q);
2227         up_write(&dev->state_sem);
2228
2229         return ret;
2230 }
2231
2232 /*
2233  * state inquiry
2234  */
2235 long taskdev_state_stale(unsigned char minor)
2236 {
2237         if (taskdev[minor]) {
2238                 long state = taskdev[minor]->state;
2239                 taskdev[minor]->state |= TASKDEV_ST_STALE;
2240                 return state;
2241         } else
2242                 return TASKDEV_ST_NOTASK;
2243 }
2244
2245 /*
2246  * functions called from mailbox interrupt routine
2247  */
2248 void mbox_wdsnd(struct mbcmd *mb)
2249 {
2250         unsigned int n;
2251         u8 tid = mb->cmd_l;
2252         u16 data = mb->data;
2253         struct dsptask *task = dsptask[tid];
2254
2255         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2256                 printk(KERN_ERR "mbox: WDSND with illegal tid! %d\n", tid);
2257                 return;
2258         }
2259         if (sndtyp_bk(task->ttyp)) {
2260                 printk(KERN_ERR
2261                        "mbox: WDSND from block sending task! (task%d)\n", tid);
2262                 return;
2263         }
2264         if (sndtyp_psv(task->ttyp) &&
2265             !waitqueue_active(&task->dev->read_wait_q)) {
2266                 printk(KERN_WARNING
2267                        "mbox: WDSND from passive sending task (task%d) "
2268                        "without request!\n", tid);
2269                 return;
2270         }
2271
2272         n = kfifo_put(task->dev->rcvdt.fifo, (unsigned char *)&data,
2273                       sizeof(data));
2274         if (n != sizeof(data))
2275                 printk(KERN_WARNING "Receive FIFO(%d) is full\n", tid);
2276
2277         wake_up_interruptible(&task->dev->read_wait_q);
2278 }
2279
2280 void mbox_wdreq(struct mbcmd *mb)
2281 {
2282         u8 tid = mb->cmd_l;
2283         struct dsptask *task = dsptask[tid];
2284         struct taskdev *dev;
2285
2286         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2287                 printk(KERN_ERR "mbox: WDREQ with illegal tid! %d\n", tid);
2288                 return;
2289         }
2290         if (rcvtyp_psv(task->ttyp)) {
2291                 printk(KERN_ERR
2292                        "mbox: WDREQ from passive receiving task! (task%d)\n",
2293                        tid);
2294                 return;
2295         }
2296
2297         dev = task->dev;
2298         spin_lock(&dev->wsz_lock);
2299         dev->wsz = 2;
2300         spin_unlock(&dev->wsz_lock);
2301         wake_up_interruptible(&dev->write_wait_q);
2302 }
2303
2304 void mbox_bksnd(struct mbcmd *mb)
2305 {
2306         u8 tid = mb->cmd_l;
2307         u16 bid = mb->data;
2308         struct dsptask *task = dsptask[tid];
2309         struct ipbuf_head *ipb_h;
2310         u16 cnt;
2311
2312         if (bid >= ipbcfg.ln) {
2313                 printk(KERN_ERR "mbox: BKSND with illegal bid! %d\n", bid);
2314                 return;
2315         }
2316         ipb_h = bid_to_ipbuf(bid);
2317         ipb_bsycnt_dec(&ipbcfg);
2318         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2319                 printk(KERN_ERR "mbox: BKSND with illegal tid! %d\n", tid);
2320                 goto unuse_ipbuf_out;
2321         }
2322         if (sndtyp_wd(task->ttyp)) {
2323                 printk(KERN_ERR
2324                        "mbox: BKSND from word sending task! (task%d)\n", tid);
2325                 goto unuse_ipbuf_out;
2326         }
2327         if (sndtyp_pvt(task->ttyp)) {
2328                 printk(KERN_ERR
2329                        "mbox: BKSND from private sending task! (task%d)\n", tid);
2330                 goto unuse_ipbuf_out;
2331         }
2332         if (sync_with_dsp(&ipb_h->p->sd, tid, 10) < 0) {
2333                 printk(KERN_ERR "mbox: BKSND - IPBUF sync failed!\n");
2334                 return;
2335         }
2336
2337         /* should be done in DSP, but just in case. */
2338         ipb_h->p->next = BID_NULL;
2339
2340         cnt = ipb_h->p->c;
2341         if (cnt > ipbcfg.lsz) {
2342                 printk(KERN_ERR "mbox: BKSND cnt(%d) > ipbuf line size(%d)!\n",
2343                        cnt, ipbcfg.lsz);
2344                 goto unuse_ipbuf_out;
2345         }
2346
2347         if (cnt == 0) {
2348                 /* 0-byte send from DSP */
2349                 unuse_ipbuf_nowait(ipb_h);
2350                 goto done;
2351         }
2352         ipblink_add_tail(&task->dev->rcvdt.bk.link, bid);
2353         /* we keep coming bid and return alternative line to DSP. */
2354         balance_ipbuf();
2355
2356 done:
2357         wake_up_interruptible(&task->dev->read_wait_q);
2358         return;
2359
2360 unuse_ipbuf_out:
2361         unuse_ipbuf_nowait(ipb_h);
2362         return;
2363 }
2364
2365 void mbox_bkreq(struct mbcmd *mb)
2366 {
2367         u8 tid = mb->cmd_l;
2368         u16 cnt = mb->data;
2369         struct dsptask *task = dsptask[tid];
2370         struct taskdev *dev;
2371
2372         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2373                 printk(KERN_ERR "mbox: BKREQ with illegal tid! %d\n", tid);
2374                 return;
2375         }
2376         if (rcvtyp_wd(task->ttyp)) {
2377                 printk(KERN_ERR
2378                        "mbox: BKREQ from word receiving task! (task%d)\n", tid);
2379                 return;
2380         }
2381         if (rcvtyp_pvt(task->ttyp)) {
2382                 printk(KERN_ERR
2383                        "mbox: BKREQ from private receiving task! (task%d)\n",
2384                        tid);
2385                 return;
2386         }
2387         if (rcvtyp_psv(task->ttyp)) {
2388                 printk(KERN_ERR
2389                        "mbox: BKREQ from passive receiving task! (task%d)\n",
2390                        tid);
2391                 return;
2392         }
2393
2394         dev = task->dev;
2395         spin_lock(&dev->wsz_lock);
2396         dev->wsz = cnt*2;
2397         spin_unlock(&dev->wsz_lock);
2398         wake_up_interruptible(&dev->write_wait_q);
2399 }
2400
2401 void mbox_bkyld(struct mbcmd *mb)
2402 {
2403         u16 bid = mb->data;
2404         struct ipbuf_head *ipb_h;
2405
2406         if (bid >= ipbcfg.ln) {
2407                 printk(KERN_ERR "mbox: BKYLD with illegal bid! %d\n", bid);
2408                 return;
2409         }
2410         ipb_h = bid_to_ipbuf(bid);
2411
2412         /* should be done in DSP, but just in case. */
2413         ipb_h->p->next = BID_NULL;
2414
2415         /* we don't need to sync with DSP */
2416         ipb_bsycnt_dec(&ipbcfg);
2417         release_ipbuf(ipb_h);
2418 }
2419
2420 void mbox_bksndp(struct mbcmd *mb)
2421 {
2422         u8 tid = mb->cmd_l;
2423         struct dsptask *task = dsptask[tid];
2424         struct ipbuf_p *ipbp;
2425
2426         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2427                 printk(KERN_ERR "mbox: BKSNDP with illegal tid! %d\n", tid);
2428                 return;
2429         }
2430         if (sndtyp_wd(task->ttyp)) {
2431                 printk(KERN_ERR
2432                        "mbox: BKSNDP from word sending task! (task%d)\n", tid);
2433                 return;
2434         }
2435         if (sndtyp_gbl(task->ttyp)) {
2436                 printk(KERN_ERR
2437                        "mbox: BKSNDP from non-private sending task! (task%d)\n",
2438                        tid);
2439                 return;
2440         }
2441
2442         /*
2443          * we should not have delayed block at this point
2444          * because read() routine releases the lock of the buffer and
2445          * until then DSP can't send next data.
2446          */
2447
2448         ipbp = task->ipbuf_pvt_r;
2449         if (sync_with_dsp(&ipbp->s, tid, 10) < 0) {
2450                 printk(KERN_ERR "mbox: BKSNDP - IPBUF sync failed!\n");
2451                 return;
2452         }
2453         pr_debug("mbox: ipbuf_pvt_r->a = 0x%08lx\n",
2454                MKLONG(ipbp->ah, ipbp->al));
2455         ipblink_add_pvt(&task->dev->rcvdt.bk.link);
2456         wake_up_interruptible(&task->dev->read_wait_q);
2457 }
2458
2459 void mbox_bkreqp(struct mbcmd *mb)
2460 {
2461         u8 tid = mb->cmd_l;
2462         struct dsptask *task = dsptask[tid];
2463         struct taskdev *dev;
2464         struct ipbuf_p *ipbp;
2465
2466         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2467                 printk(KERN_ERR "mbox: BKREQP with illegal tid! %d\n", tid);
2468                 return;
2469         }
2470         if (rcvtyp_wd(task->ttyp)) {
2471                 printk(KERN_ERR
2472                        "mbox: BKREQP from word receiving task! (task%d)\n", tid);
2473                 return;
2474         }
2475         if (rcvtyp_gbl(task->ttyp)) {
2476                 printk(KERN_ERR
2477                        "mbox: BKREQP from non-private receiving task! (task%d)\n", tid);
2478                 return;
2479         }
2480         if (rcvtyp_psv(task->ttyp)) {
2481                 printk(KERN_ERR
2482                        "mbox: BKREQP from passive receiving task! (task%d)\n", tid);
2483                 return;
2484         }
2485
2486         ipbp = task->ipbuf_pvt_w;
2487         if (sync_with_dsp(&ipbp->s, TID_FREE, 10) < 0) {
2488                 printk(KERN_ERR "mbox: BKREQP - IPBUF sync failed!\n");
2489                 return;
2490         }
2491         pr_debug("mbox: ipbuf_pvt_w->a = 0x%08lx\n",
2492                MKLONG(ipbp->ah, ipbp->al));
2493         dev = task->dev;
2494         spin_lock(&dev->wsz_lock);
2495         dev->wsz = ipbp->c*2;
2496         spin_unlock(&dev->wsz_lock);
2497         wake_up_interruptible(&dev->write_wait_q);
2498 }
2499
2500 void mbox_tctl(struct mbcmd *mb)
2501 {
2502         u8 tid = mb->cmd_l;
2503         struct dsptask *task = dsptask[tid];
2504
2505         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2506                 printk(KERN_ERR "mbox: TCTL with illegal tid! %d\n", tid);
2507                 return;
2508         }
2509
2510         if (!waitqueue_active(&task->dev->tctl_wait_q)) {
2511                 printk(KERN_WARNING "mbox: unexpected TCTL from DSP!\n");
2512                 return;
2513         }
2514
2515         task->dev->tctl_stat = mb->data;
2516         wake_up_interruptible(&task->dev->tctl_wait_q);
2517 }
2518
2519 void mbox_tcfg(struct mbcmd *mb)
2520 {
2521         u8 tid = mb->cmd_l;
2522         struct dsptask *task = dsptask[tid];
2523         u16 *tnm;
2524         volatile u16 *buf;
2525         int i;
2526
2527         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2528                 printk(KERN_ERR "mbox: TCFG with illegal tid! %d\n", tid);
2529                 return;
2530         }
2531         if ((task->state != TASK_ST_CFGREQ) || (cfg_cmd != MBOX_CMD_DSP_TCFG)) {
2532                 printk(KERN_WARNING "mbox: unexpected TCFG from DSP!\n");
2533                 return;
2534         }
2535
2536         if (dsp_mem_enable(ipbuf_sys_da) < 0) {
2537                 printk(KERN_ERR "mbox: TCFG - ipbuf_sys_da read failed!\n");
2538                 dsp_mem_disable(ipbuf_sys_da);
2539                 goto out;
2540         }
2541         if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2542                 printk(KERN_ERR "mbox: TCFG - IPBUF sync failed!\n");
2543                 dsp_mem_disable(ipbuf_sys_da);
2544                 goto out;
2545         }
2546
2547         /*
2548          * read configuration data on system IPBUF
2549          */
2550         buf = ipbuf_sys_da->d;
2551         task->ttyp        = buf[0];
2552         task->ipbuf_pvt_r = MKVIRT(buf[1], buf[2]);
2553         task->ipbuf_pvt_w = MKVIRT(buf[3], buf[4]);
2554         task->map_base    = MKVIRT(buf[5], buf[6]);
2555         task->map_length  = MKLONG(buf[7], buf[8]) << 1;        /* word -> byte */
2556         tnm               = MKVIRT(buf[9], buf[10]);
2557         release_ipbuf_pvt(ipbuf_sys_da);
2558         dsp_mem_disable(ipbuf_sys_da);
2559
2560         /*
2561          * copy task name string
2562          */
2563         if (dsp_address_validate(tnm, TNM_LEN, "task name buffer") < 0) {
2564                 task->name[0] = '\0';
2565                 goto out;
2566         }
2567
2568         for (i = 0; i < TNM_LEN-1; i++) {
2569                 /* avoiding byte access */
2570                 u16 tmp = tnm[i];
2571                 task->name[i] = tmp & 0x00ff;
2572                 if (!tmp)
2573                         break;
2574         }
2575         task->name[TNM_LEN-1] = '\0';
2576
2577         task->state = TASK_ST_READY;
2578 out:
2579         wake_up_interruptible(&cfg_wait_q);
2580 }
2581
2582 void mbox_tadd(struct mbcmd *mb)
2583 {
2584         u8 tid = mb->cmd_l;
2585
2586         if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBOX_CMD_DSP_TADD)) {
2587                 printk(KERN_WARNING "mbox: unexpected TADD from DSP!\n");
2588                 return;
2589         }
2590         cfg_tid = tid;
2591         wake_up_interruptible(&cfg_wait_q);
2592 }
2593
2594 void mbox_tdel(struct mbcmd *mb)
2595 {
2596         u8 tid = mb->cmd_l;
2597
2598         if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBOX_CMD_DSP_TDEL)) {
2599                 printk(KERN_WARNING "mbox: unexpected TDEL from DSP!\n");
2600                 return;
2601         }
2602         cfg_tid = tid;
2603         wake_up_interruptible(&cfg_wait_q);
2604 }
2605
2606 void mbox_err_fatal(u8 tid)
2607 {
2608         struct dsptask *task = dsptask[tid];
2609         struct taskdev *dev;
2610
2611         if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2612                 printk(KERN_ERR "mbox: FATAL ERR with illegal tid! %d\n", tid);
2613                 return;
2614         }
2615
2616         /* wake up waiting processes */
2617         dev = task->dev;
2618         wake_up_interruptible_all(&dev->read_wait_q);
2619         wake_up_interruptible_all(&dev->write_wait_q);
2620         wake_up_interruptible_all(&dev->tctl_wait_q);
2621 }
2622
2623 static u16 *dbg_buf;
2624 static u16 dbg_buf_sz, dbg_line_sz;
2625 static int dbg_rp;
2626
2627 int dsp_dbg_config(u16 *buf, u16 sz, u16 lsz)
2628 {
2629 #ifdef OLD_BINARY_SUPPORT
2630         if ((mbox_revision == MBREV_3_0) || (mbox_revision == MBREV_3_2)) {
2631                 dbg_buf = NULL;
2632                 dbg_buf_sz = 0;
2633                 dbg_line_sz = 0;
2634                 dbg_rp = 0;
2635                 return 0;
2636         }
2637 #endif
2638
2639         if (dsp_address_validate(buf, sz, "debug buffer") < 0)
2640                 return -1;
2641
2642         if (lsz > sz) {
2643                 printk(KERN_ERR
2644                        "omapdsp: dbg_buf lsz (%d) is greater than its "
2645                        "buffer size (%d)\n", lsz, sz);
2646                 return -1;
2647         }
2648
2649         dbg_buf = buf;
2650         dbg_buf_sz = sz;
2651         dbg_line_sz = lsz;
2652         dbg_rp = 0;
2653
2654         return 0;
2655 }
2656
2657 void dsp_dbg_stop(void)
2658 {
2659         dbg_buf = NULL;
2660 }
2661
2662 #ifdef OLD_BINARY_SUPPORT
2663 static void mbox_dbg_old(struct mbcmd *mb);
2664 #endif
2665
2666 void mbox_dbg(struct mbcmd *mb)
2667 {
2668         u8 tid = mb->cmd_l;
2669         int cnt = mb->data;
2670         char s[80], *s_end = &s[79], *p;
2671         u16 *src;
2672         int i;
2673
2674 #ifdef OLD_BINARY_SUPPORT
2675         if ((mbox_revision == MBREV_3_0) || (mbox_revision == MBREV_3_2)) {
2676                 mbox_dbg_old(mb);
2677                 return;
2678         }
2679 #endif
2680
2681         if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2682             (tid != TID_ANON)) {
2683                 printk(KERN_ERR "mbox: DBG with illegal tid! %d\n", tid);
2684                 return;
2685         }
2686         if (dbg_buf == NULL) {
2687                 printk(KERN_ERR "mbox: DBG command received, but "
2688                        "dbg_buf has not been configured yet.\n");
2689                 return;
2690         }
2691
2692         if (dsp_mem_enable(dbg_buf) < 0)
2693                 return;
2694
2695         src = &dbg_buf[dbg_rp];
2696         p = s;
2697         for (i = 0; i < cnt; i++) {
2698                 u16 tmp;
2699                 /*
2700                  * Be carefull that dbg_buf should not be read with
2701                  * 1-byte access since it might be placed in DARAM/SARAM
2702                  * and it can cause unexpected byteswap.
2703                  * For example,
2704                  *   *(p++) = *(src++) & 0xff;
2705                  * causes 1-byte access!
2706                  */
2707                 tmp = *src++;
2708                 *(p++) = tmp & 0xff;
2709                 if (*(p-1) == '\n') {
2710                         *p = '\0';
2711                         pr_info("%s", s);
2712                         p = s;
2713                         continue;
2714                 }
2715                 if (p == s_end) {
2716                         *p = '\0';
2717                         pr_info("%s\n", s);
2718                         p = s;
2719                         continue;
2720                 }
2721         }
2722         if (p > s) {
2723                 *p = '\0';
2724                 pr_info("%s\n", s);
2725         }
2726         if ((dbg_rp += cnt + 1) > dbg_buf_sz - dbg_line_sz)
2727                 dbg_rp = 0;
2728
2729         dsp_mem_disable(dbg_buf);
2730 }
2731
2732 #ifdef OLD_BINARY_SUPPORT
2733 static void mbox_dbg_old(struct mbcmd *mb)
2734 {
2735         u8 tid = mb->cmd_l;
2736         char s[80], *s_end = &s[79], *p;
2737         u16 *src;
2738         volatile u16 *buf;
2739         int cnt;
2740         int i;
2741
2742         if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2743             (tid != TID_ANON)) {
2744                 printk(KERN_ERR "mbox: DBG with illegal tid! %d\n", tid);
2745                 return;
2746         }
2747         if (dsp_mem_enable(ipbuf_sys_da) < 0) {
2748                 printk(KERN_ERR "mbox: DBG - ipbuf_sys_da read failed!\n");
2749                 return;
2750         }
2751         if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2752                 printk(KERN_ERR "mbox: DBG - IPBUF sync failed!\n");
2753                 goto out1;
2754         }
2755         buf = ipbuf_sys_da->d;
2756         cnt = buf[0];
2757         src = MKVIRT(buf[1], buf[2]);
2758         if (dsp_address_validate(src, cnt, "dbg buffer") < 0)
2759                 goto out2;
2760
2761         if (dsp_mem_enable(src) < 0)
2762                 goto out2;
2763
2764         p = s;
2765         for (i = 0; i < cnt; i++) {
2766                 u16 tmp;
2767                 /*
2768                  * Be carefull that ipbuf should not be read with
2769                  * 1-byte access since it might be placed in DARAM/SARAM
2770                  * and it can cause unexpected byteswap.
2771                  * For example,
2772                  *   *(p++) = *(src++) & 0xff;
2773                  * causes 1-byte access!
2774                  */
2775                 tmp = *src++;
2776                 *(p++) = tmp & 0xff;
2777                 if (*(p-1) == '\n') {
2778                         *p = '\0';
2779                         pr_info("%s", s);
2780                         p = s;
2781                         continue;
2782                 }
2783                 if (p == s_end) {
2784                         *p = '\0';
2785                         pr_info("%s\n", s);
2786                         p = s;
2787                         continue;
2788                 }
2789         }
2790         if (p > s) {
2791                 *p = '\0';
2792                 pr_info("%s\n", s);
2793         }
2794
2795         dsp_mem_disable(src);
2796 out2:
2797         release_ipbuf_pvt(ipbuf_sys_da);
2798 out1:
2799         dsp_mem_disable(ipbuf_sys_da);
2800 }
2801 #endif /* OLD_BINARY_SUPPORT */
2802
2803 /*
2804  * sysfs files: for each device
2805  */
2806
2807 /* devname */
2808 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
2809                             char *buf)
2810 {
2811         return sprintf(buf, "%s\n", to_taskdev(d)->name);
2812 }
2813
2814 /* devstate */
2815 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
2816                              char *buf)
2817 {
2818         return sprintf(buf, "%s\n", devstate_name(to_taskdev(d)->state));
2819 }
2820
2821 /* proc_list */
2822 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
2823                               char *buf)
2824 {
2825         struct taskdev *dev;
2826         struct proc_list *pl;
2827         int len = 0;
2828
2829         dev = to_taskdev(d);
2830         spin_lock(&dev->proc_list_lock);
2831         list_for_each_entry(pl, &dev->proc_list, list_head) {
2832                 /* need to lock tasklist_lock before calling
2833                  * find_task_by_pid_type. */
2834                 if (find_task_by_pid(pl->pid) != NULL)
2835                         len += sprintf(buf + len, "%d\n", pl->pid);
2836                 read_unlock(&tasklist_lock);
2837         }
2838         spin_unlock(&dev->proc_list_lock);
2839
2840         return len;
2841 }
2842
2843 /* taskname */
2844 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
2845                              char *buf)
2846 {
2847         struct taskdev *dev = to_taskdev(d);
2848         int len;
2849
2850         if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
2851                 return -ENODEV;
2852
2853         len = sprintf(buf, "%s\n", dev->task->name);
2854
2855         devstate_read_unlock(dev);
2856         return len;
2857 }
2858
2859 /* ttyp */
2860 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
2861                          char *buf)
2862 {
2863         struct taskdev *dev = to_taskdev(d);
2864         u16 ttyp;
2865         int len = 0;
2866
2867         if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
2868                 return -ENODEV;
2869
2870         ttyp = dev->task->ttyp;
2871         len += sprintf(buf + len, "0x%04x\n", ttyp);
2872         len += sprintf(buf + len, "%s %s send\n",
2873                         (sndtyp_acv(ttyp)) ? "active" :
2874                                              "passive",
2875                         (sndtyp_wd(ttyp))  ? "word" :
2876                         (sndtyp_pvt(ttyp)) ? "private block" :
2877                                              "global block");
2878         len += sprintf(buf + len, "%s %s receive\n",
2879                         (rcvtyp_acv(ttyp)) ? "active" :
2880                                              "passive",
2881                         (rcvtyp_wd(ttyp))  ? "word" :
2882                         (rcvtyp_pvt(ttyp)) ? "private block" :
2883                                              "global block");
2884
2885         devstate_read_unlock(dev);
2886         return len;
2887 }
2888
2889 /* fifosz */
2890 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
2891                            char *buf)
2892 {
2893         struct kfifo *fifo = to_taskdev(d)->rcvdt.fifo;
2894         return sprintf(buf, "%d\n", fifo->size);
2895 }
2896
2897 static int fifosz_store(struct device *d, struct device_attribute *attr,
2898                         const char *buf, size_t count)
2899 {
2900         struct taskdev *dev = to_taskdev(d);
2901         unsigned long fifosz;
2902         int ret;
2903
2904         fifosz = simple_strtol(buf, NULL, 10);
2905         if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
2906                 return -ENODEV;
2907         ret = taskdev_set_fifosz(dev, fifosz);
2908         taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
2909
2910         return (ret < 0) ? ret : strlen(buf);
2911 }
2912
2913 /* fifocnt */
2914 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
2915                             char *buf)
2916 {
2917         struct kfifo *fifo = to_taskdev(d)->rcvdt.fifo;
2918         return sprintf(buf, "%d\n", fifo->size);
2919 }
2920
2921 /* ipblink */
2922 static inline char *bid_name(u16 bid)
2923 {
2924         static char s[6];
2925
2926         switch (bid) {
2927         case BID_NULL:
2928                 return "NULL";
2929         case BID_PVT:
2930                 return "PRIVATE";
2931         default:
2932                 sprintf(s, "%d", bid);
2933                 return s;
2934         }
2935 }
2936
2937 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
2938                             char *buf)
2939 {
2940         struct rcvdt_bk_struct *rcvdt = &to_taskdev(d)->rcvdt.bk;
2941         int len;
2942
2943         spin_lock(&rcvdt->link.lock);
2944         len = sprintf(buf, "top  %s\ntail %s\n",
2945                       bid_name(rcvdt->link.top), bid_name(rcvdt->link.tail));
2946         spin_unlock(&rcvdt->link.lock);
2947
2948         return len;
2949 }
2950
2951 /* wsz */
2952 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
2953                         char *buf)
2954 {
2955         return sprintf(buf, "%d\n", to_taskdev(d)->wsz);
2956 }
2957
2958 /* mmap */
2959 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
2960                          char *buf)
2961 {
2962         struct dsptask *task = to_taskdev(d)->task;
2963         return sprintf(buf, "0x%p 0x%x\n", task->map_base, task->map_length);
2964 }
2965
2966 /*
2967  * called from ipbuf_show()
2968  */
2969 int ipbuf_is_held(u8 tid, u16 bid)
2970 {
2971         struct dsptask *task = dsptask[tid];
2972         struct ipblink *link;
2973         u16 b;
2974         int ret = 0;
2975
2976         if (task == NULL)
2977                 return 0;
2978
2979         link = &task->dev->rcvdt.bk.link;
2980         spin_lock(&link->lock);
2981         ipblink_for_each(b, link) {
2982                 if (b == bid) { /* found */
2983                         ret = 1;
2984                         break;
2985                 }
2986         }
2987         spin_unlock(&link->lock);
2988
2989         return ret;
2990 }
2991
2992 int __init dsp_taskmod_init(void)
2993 {
2994         int retval;
2995
2996         memset(taskdev, 0, sizeof(void *) * TASKDEV_MAX);
2997         memset(dsptask, 0, sizeof(void *) * TASKDEV_MAX);
2998
2999         retval = register_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask",
3000                                  &dsp_task_fops);
3001         if (retval < 0) {
3002                 printk(KERN_ERR
3003                        "omapdsp: failed to register task device: %d\n", retval);
3004                 return retval;
3005         }
3006
3007         retval = bus_register(&dsptask_bus);
3008         if (retval) {
3009                 printk(KERN_ERR
3010                        "omapdsp: failed to register DSP task bus: %d\n",
3011                        retval);
3012                 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3013                 return -EINVAL;
3014         }
3015         retval = driver_register(&dsptask_driver);
3016         if (retval) {
3017                 printk(KERN_ERR
3018                        "omapdsp: failed to register DSP task driver: %d\n",
3019                        retval);
3020                 bus_unregister(&dsptask_bus);
3021                 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3022                 return -EINVAL;
3023         }
3024         dsp_task_class = class_create(THIS_MODULE, "dsptask");
3025         if (IS_ERR(dsp_task_class)) {
3026                 printk(KERN_ERR "omapdsp: failed to create DSP task class\n");
3027                 driver_unregister(&dsptask_driver);
3028                 bus_unregister(&dsptask_bus);
3029                 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3030                 return -EINVAL;
3031         }
3032
3033         return 0;
3034 }
3035
3036 void dsp_taskmod_exit(void)
3037 {
3038         class_destroy(dsp_task_class);
3039         driver_unregister(&dsptask_driver);
3040         bus_unregister(&dsptask_bus);
3041         unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3042 }