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