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