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