2 * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
4 * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
6 * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
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.
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.
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
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/major.h>
29 #include <linux/poll.h>
30 #include <linux/platform_device.h>
31 #include <linux/slab.h>
32 #include <linux/sched.h>
34 #include <linux/mutex.h>
35 #include <linux/interrupt.h>
36 #include <linux/kfifo.h>
37 #include <asm/uaccess.h>
39 #include <asm/arch/mailbox.h>
40 #include <asm/arch/dsp.h>
41 #include "uaccess_dsp.h"
42 #include "dsp_mbcmd.h"
47 #define is_aligned(adr,align) (!((adr)&((align)-1)))
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.
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
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" },
93 static char *devstate_name(long state)
96 int max = ARRAY_SIZE(devstate_desc);
98 for (i = 0; i < max; i++) {
99 if (state & devstate_desc[i].state)
100 return devstate_desc[i].name;
105 struct rcvdt_bk_struct {
111 struct bus_type *bus;
112 struct device dev; /* Generic device interface */
115 struct rw_semaphore state_sem;
116 wait_queue_head_t state_wait_q;
117 struct mutex usecount_lock;
118 unsigned int usecount;
120 struct file_operations fops;
121 spinlock_t proc_list_lock;
122 struct list_head proc_list;
123 struct dsptask *task;
126 wait_queue_head_t read_wait_q;
127 struct mutex read_mutex;
128 spinlock_t read_lock;
130 struct kfifo *fifo; /* for active word */
131 struct rcvdt_bk_struct bk;
135 wait_queue_head_t write_wait_q;
136 struct mutex write_mutex;
141 wait_queue_head_t tctl_wait_q;
142 struct mutex tctl_mutex;
144 int tctl_ret; /* return value for tctl_show() */
151 #define to_taskdev(n) container_of(n, struct taskdev, dev)
165 struct ipbuf_p *ipbuf_pvt_r;
168 struct ipbuf_p *ipbuf_pvt_w;
175 #define sndtyp_acv(ttyp) ((ttyp) & TTYP_ASND)
176 #define sndtyp_psv(ttyp) (!((ttyp) & TTYP_ASND))
177 #define sndtyp_bk(ttyp) ((ttyp) & TTYP_BKDM)
178 #define sndtyp_wd(ttyp) (!((ttyp) & TTYP_BKDM))
179 #define sndtyp_pvt(ttyp) ((ttyp) & TTYP_PVDM)
180 #define sndtyp_gbl(ttyp) (!((ttyp) & TTYP_PVDM))
181 #define rcvtyp_acv(ttyp) ((ttyp) & TTYP_ARCV)
182 #define rcvtyp_psv(ttyp) (!((ttyp) & TTYP_ARCV))
183 #define rcvtyp_bk(ttyp) ((ttyp) & TTYP_BKMD)
184 #define rcvtyp_wd(ttyp) (!((ttyp) & TTYP_BKMD))
185 #define rcvtyp_pvt(ttyp) ((ttyp) & TTYP_PVMD)
186 #define rcvtyp_gbl(ttyp) (!((ttyp) & TTYP_PVMD))
188 static inline int has_taskdev_lock(struct taskdev *dev);
189 static int dsp_rmdev_minor(unsigned char minor);
190 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor);
191 static void taskdev_delete(unsigned char minor);
192 static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task);
193 static int dsp_tdel_bh(struct taskdev *dev, u16 type);
195 static struct bus_type dsptask_bus = {
199 static struct class *dsp_task_class;
200 static DEFINE_MUTEX(devmgr_lock);
201 static struct taskdev *taskdev[TASKDEV_MAX];
202 static struct dsptask *dsptask[TASKDEV_MAX];
203 static DEFINE_MUTEX(cfg_lock);
206 static DECLARE_WAIT_QUEUE_HEAD(cfg_wait_q);
207 static u8 n_task; /* static task count */
210 #define is_dynamic_task(tid) ((tid) >= n_task)
212 #define devstate_read_lock(dev, devstate) \
213 devstate_read_lock_timeout(dev, devstate, 0)
214 #define devstate_read_unlock(dev) up_read(&(dev)->state_sem)
215 #define devstate_write_lock(dev, devstate) \
216 devstate_write_lock_timeout(dev, devstate, 0)
217 #define devstate_write_unlock(dev) up_write(&(dev)->state_sem)
219 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
221 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
223 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
225 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
227 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
229 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
231 static int fifosz_store(struct device *d, struct device_attribute *attr,
232 const char *buf, size_t count);
233 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
235 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
237 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
239 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
242 #define __ATTR_RW(_name,_mode) { \
243 .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
244 .show = _name##_show, \
245 .store = _name##_store, \
248 static struct device_attribute dev_attr_devname = __ATTR_RO(devname);
249 static struct device_attribute dev_attr_devstate = __ATTR_RO(devstate);
250 static struct device_attribute dev_attr_proc_list = __ATTR_RO(proc_list);
251 static struct device_attribute dev_attr_taskname = __ATTR_RO(taskname);
252 static struct device_attribute dev_attr_ttyp = __ATTR_RO(ttyp);
253 static struct device_attribute dev_attr_fifosz = __ATTR_RW(fifosz, 0666);
254 static struct device_attribute dev_attr_fifocnt = __ATTR_RO(fifocnt);
255 static struct device_attribute dev_attr_ipblink = __ATTR_RO(ipblink);
256 static struct device_attribute dev_attr_wsz = __ATTR_RO(wsz);
257 static struct device_attribute dev_attr_mmap = __ATTR_RO(mmap);
259 static inline void set_taskdev_state(struct taskdev *dev, int state)
261 pr_debug("omapdsp: devstate: CHANGE %s[%d]:\"%s\"->\"%s\"\n",
263 (dev->task ? dev->task->tid : -1),
264 devstate_name(dev->state),
265 devstate_name(state));
270 * devstate_read_lock_timeout()
271 * devstate_write_lock_timeout():
272 * timeout != 0: dev->state can be diffeent from what you want.
273 * timeout == 0: no timeout
275 #define BUILD_DEVSTATE_LOCK_TIMEOUT(rw) \
276 static int devstate_##rw##_lock_timeout(struct taskdev *dev, long devstate, \
280 down_##rw(&dev->state_sem); \
281 while (!(dev->state & devstate)) { \
282 up_##rw(&dev->state_sem); \
283 prepare_to_wait(&dev->state_wait_q, &wait, TASK_INTERRUPTIBLE); \
285 timeout = MAX_SCHEDULE_TIMEOUT; \
286 timeout = schedule_timeout(timeout); \
287 finish_wait(&dev->state_wait_q, &wait); \
290 if (signal_pending(current)) \
292 down_##rw(&dev->state_sem); \
296 BUILD_DEVSTATE_LOCK_TIMEOUT(read)
297 BUILD_DEVSTATE_LOCK_TIMEOUT(write)
299 #define BUILD_DEVSTATE_LOCK_AND_TEST(rw) \
300 static int devstate_##rw##_lock_and_test(struct taskdev *dev, long devstate) \
302 down_##rw(&dev->state_sem); \
303 if (dev->state & devstate) \
304 return 1; /* success */ \
306 up_##rw(&dev->state_sem); \
309 BUILD_DEVSTATE_LOCK_AND_TEST(read)
310 BUILD_DEVSTATE_LOCK_AND_TEST(write)
312 static int taskdev_lock_interruptible(struct taskdev *dev,
317 if (has_taskdev_lock(dev))
318 ret = mutex_lock_interruptible(lock);
320 if ((ret = mutex_lock_interruptible(&dev->lock)) != 0)
322 ret = mutex_lock_interruptible(lock);
323 mutex_unlock(&dev->lock);
329 static int taskdev_lock_and_statelock_attached(struct taskdev *dev,
334 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
337 if ((ret = taskdev_lock_interruptible(dev, lock)) != 0)
338 devstate_read_unlock(dev);
343 static inline void taskdev_unlock_and_stateunlock(struct taskdev *dev,
347 devstate_read_unlock(dev);
351 * taskdev_flush_buf()
352 * must be called under state_lock(ATTACHED) and dev->read_mutex.
354 static int taskdev_flush_buf(struct taskdev *dev)
356 u16 ttyp = dev->task->ttyp;
358 if (sndtyp_wd(ttyp)) {
360 kfifo_reset(dev->rcvdt.fifo);
362 /* block receiving */
363 struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
365 if (sndtyp_gbl(ttyp))
366 ipblink_flush(&rcvdt->link);
368 ipblink_flush_pvt(&rcvdt->link);
369 release_ipbuf_pvt(dev->task->ipbuf_pvt_r);
377 * taskdev_set_fifosz()
378 * must be called under dev->read_mutex.
380 static int taskdev_set_fifosz(struct taskdev *dev, unsigned long sz)
382 u16 ttyp = dev->task->ttyp;
384 if (!(sndtyp_wd(ttyp) && sndtyp_acv(ttyp))) {
386 "omapdsp: buffer size can be changed only for "
387 "active word sending task.\n");
390 if ((sz == 0) || (sz & 1)) {
391 printk(KERN_ERR "omapdsp: illegal buffer size! (%ld)\n"
392 "it must be even and non-zero value.\n", sz);
396 if (kfifo_len(dev->rcvdt.fifo)) {
397 printk(KERN_ERR "omapdsp: buffer is not empty!\n");
401 kfifo_free(dev->rcvdt.fifo);
402 dev->rcvdt.fifo = kfifo_alloc(sz, GFP_KERNEL, &dev->read_lock);
403 if (IS_ERR(dev->rcvdt.fifo)) {
405 "omapdsp: unable to change receive buffer size. "
406 "(%ld bytes for %s)\n", sz, dev->name);
413 static inline int has_taskdev_lock(struct taskdev *dev)
415 return (dev->lock_pid == current->pid);
418 static int taskdev_lock(struct taskdev *dev)
420 if (mutex_lock_interruptible(&dev->lock))
422 dev->lock_pid = current->pid;
426 static int taskdev_unlock(struct taskdev *dev)
428 if (!has_taskdev_lock(dev)) {
430 "omapdsp: an illegal process attempted to "
431 "unlock the dsptask lock!\n");
435 mutex_unlock(&dev->lock);
439 static int dsp_task_config(struct dsptask *task, u8 tid)
448 task->state = TASK_ST_CFGREQ;
449 if (mutex_lock_interruptible(&cfg_lock)) {
453 cfg_cmd = MBOX_CMD_DSP_TCFG;
454 mbcompose_send_and_wait(TCFG, tid, 0, &cfg_wait_q);
456 mutex_unlock(&cfg_lock);
458 if (task->state != TASK_ST_READY) {
459 printk(KERN_ERR "omapdsp: task %d configuration error!\n", tid);
464 if (strlen(task->name) <= 1)
465 sprintf(task->name, "%d", tid);
466 pr_info("omapdsp: task %d: name %s\n", tid, task->name);
471 * task info sanity check
474 /* task type check */
475 if (rcvtyp_psv(ttyp) && rcvtyp_pvt(ttyp)) {
476 printk(KERN_ERR "omapdsp: illegal task type(0x%04x), tid=%d\n",
482 /* private buffer address check */
483 if (sndtyp_pvt(ttyp) &&
484 (ipbuf_p_validate(task->ipbuf_pvt_r, DIR_D2A) < 0)) {
488 if (rcvtyp_pvt(ttyp) &&
489 (ipbuf_p_validate(task->ipbuf_pvt_w, DIR_A2D) < 0)) {
494 /* mmap buffer configuration check */
495 if ((task->map_length > 0) &&
496 ((!is_aligned((unsigned long)task->map_base, PAGE_SIZE)) ||
497 (!is_aligned(task->map_length, PAGE_SIZE)) ||
498 (dsp_mem_type(task->map_base, task->map_length) != MEM_TYPE_EXTERN))) {
500 "omapdsp: illegal mmap buffer address(0x%p) or "
502 " It needs to be page-aligned and located at "
503 "external memory.\n",
504 task->map_base, task->map_length);
516 static void dsp_task_init(struct dsptask *task)
518 mbcompose_send(TCTL, task->tid, TCTL_TINIT);
521 int dsp_task_config_all(u8 n)
524 struct taskdev *devheap;
525 struct dsptask *taskheap;
526 size_t devheapsz, taskheapsz;
528 pr_info("omapdsp: found %d task(s)\n", n);
535 devheapsz = sizeof(struct taskdev) * n;
536 taskheapsz = sizeof(struct dsptask) * n;
537 heap = kzalloc(devheapsz + taskheapsz, GFP_KERNEL);
541 taskheap = heap + devheapsz;
544 for (i = 0; i < n; i++) {
545 struct taskdev *dev = &devheap[i];
546 struct dsptask *task = &taskheap[i];
548 if ((ret = dsp_task_config(task, i)) < 0)
550 if ((ret = taskdev_init(dev, task->name, i)) < 0)
552 if ((ret = taskdev_attach_task(dev, task)) < 0)
555 pr_info("omapdsp: taskdev %s enabled.\n", dev->name);
561 static void dsp_task_unconfig(struct dsptask *task)
563 dsptask[task->tid] = NULL;
566 void dsp_task_unconfig_all(void)
570 struct dsptask *task;
572 for (minor = 0; minor < n_task; minor++) {
574 * taskdev[minor] can be NULL in case of
575 * configuration failure
578 taskdev_delete(minor);
580 for (; minor < TASKDEV_MAX; minor++) {
582 dsp_rmdev_minor(minor);
585 for (tid = 0; tid < n_task; tid++) {
587 * dsptask[tid] can be NULL in case of
588 * configuration failure
592 dsp_task_unconfig(task);
594 for (; tid < TASKDEV_MAX; tid++) {
598 * on-demand tasks should be deleted in
599 * rmdev_minor(), but just in case.
601 dsp_task_unconfig(task);
614 static struct device_driver dsptask_driver = {
619 u8 dsp_task_count(void)
624 int dsp_taskmod_busy(void)
628 unsigned int usecount;
630 for (minor = 0; minor < TASKDEV_MAX; minor++) {
631 dev = taskdev[minor];
634 if ((usecount = dev->usecount) > 0) {
635 printk("dsp_taskmod_busy(): %s: usecount=%d\n",
636 dev->name, usecount);
640 if ((dev->state & (TASKDEV_ST_ADDREQ |
641 TASKDEV_ST_DELREQ)) {
643 if (dev->state & TASKDEV_ST_ADDREQ) {
644 printk("dsp_taskmod_busy(): %s is in %s\n",
645 dev->name, devstate_name(dev->state));
653 * DSP task device file operations
655 static ssize_t dsp_task_read_wd_acv(struct file *file, char __user *buf,
656 size_t count, loff_t *ppos)
658 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
659 struct taskdev *dev = taskdev[minor];
665 } else if (count & 0x1) {
667 "omapdsp: odd count is illegal for DSP task device.\n");
671 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
675 prepare_to_wait(&dev->read_wait_q, &wait, TASK_INTERRUPTIBLE);
676 if (kfifo_len(dev->rcvdt.fifo) == 0)
678 finish_wait(&dev->read_wait_q, &wait);
679 if (kfifo_len(dev->rcvdt.fifo) == 0) {
681 if (signal_pending(current))
687 ret = kfifo_get_to_user(dev->rcvdt.fifo, buf, count);
690 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
694 static ssize_t dsp_task_read_bk_acv(struct file *file, char __user *buf,
695 size_t count, loff_t *ppos)
697 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
698 struct taskdev *dev = taskdev[minor];
699 struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
705 } else if (count & 0x1) {
707 "omapdsp: odd count is illegal for DSP task device.\n");
709 } else if ((int)buf & 0x1) {
711 "omapdsp: buf should be word aligned for "
712 "dsp_task_read().\n");
716 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
719 prepare_to_wait(&dev->read_wait_q, &wait, TASK_INTERRUPTIBLE);
720 if (ipblink_empty(&rcvdt->link))
722 finish_wait(&dev->read_wait_q, &wait);
723 if (ipblink_empty(&rcvdt->link)) {
725 if (signal_pending(current))
730 /* copy from delayed IPBUF */
731 if (sndtyp_pvt(dev->task->ttyp)) {
733 if (!ipblink_empty(&rcvdt->link)) {
734 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_r;
735 unsigned char *base, *src;
738 if (dsp_mem_enable(ipbp) < 0) {
742 base = MKVIRT(ipbp->ah, ipbp->al);
743 bkcnt = ((unsigned long)ipbp->c) * 2 - rcvdt->rp;
744 if (dsp_address_validate(base, bkcnt,
745 "task %s read buffer",
746 dev->task->name) < 0) {
750 if (dsp_mem_enable(base) < 0) {
754 src = base + rcvdt->rp;
756 if (copy_to_user_dsp(buf, src, count)) {
763 if (copy_to_user_dsp(buf, src, bkcnt)) {
768 ipblink_del_pvt(&rcvdt->link);
769 release_ipbuf_pvt(ipbp);
773 dsp_mem_disable(src);
775 dsp_mem_disable(ipbp);
779 if (dsp_mem_enable_ipbuf() < 0) {
783 while (!ipblink_empty(&rcvdt->link)) {
786 struct ipbuf_head *ipb_h = bid_to_ipbuf(rcvdt->link.top);
788 src = ipb_h->p->d + rcvdt->rp;
789 bkcnt = ((unsigned long)ipb_h->p->c) * 2 - rcvdt->rp;
791 if (copy_to_user_dsp(buf, src, count)) {
799 if (copy_to_user_dsp(buf, src, bkcnt)) {
806 ipblink_del_top(&rcvdt->link);
812 dsp_mem_disable_ipbuf();
816 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
820 static ssize_t dsp_task_read_wd_psv(struct file *file, char __user *buf,
821 size_t count, loff_t *ppos)
823 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
824 struct taskdev *dev = taskdev[minor];
829 } else if (count & 0x1) {
831 "omapdsp: odd count is illegal for DSP task device.\n");
838 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
841 mbcompose_send_and_wait(WDREQ, dev->task->tid, 0, &dev->read_wait_q);
843 if (kfifo_len(dev->rcvdt.fifo) == 0) {
845 if (signal_pending(current))
850 ret = kfifo_get_to_user(dev->rcvdt.fifo, buf, count);
853 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
857 static ssize_t dsp_task_read_bk_psv(struct file *file, char __user *buf,
858 size_t count, loff_t *ppos)
860 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
861 struct taskdev *dev = taskdev[minor];
862 struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
867 } else if (count & 0x1) {
869 "omapdsp: odd count is illegal for DSP task device.\n");
871 } else if ((int)buf & 0x1) {
873 "omapdsp: buf should be word aligned for "
874 "dsp_task_read().\n");
878 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
881 mbcompose_send_and_wait(BKREQ, dev->task->tid, count/2,
884 if (ipblink_empty(&rcvdt->link)) {
886 if (signal_pending(current))
892 * We will not receive more than requested count.
894 if (sndtyp_pvt(dev->task->ttyp)) {
896 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_r;
900 if (dsp_mem_enable(ipbp) < 0) {
904 src = MKVIRT(ipbp->ah, ipbp->al);
905 rcvcnt = ((unsigned long)ipbp->c) * 2;
906 if (dsp_address_validate(src, rcvcnt, "task %s read buffer",
907 dev->task->name) < 0) {
911 if (dsp_mem_enable(src) < 0) {
917 if (copy_to_user_dsp(buf, src, count)) {
921 ipblink_del_pvt(&rcvdt->link);
922 release_ipbuf_pvt(ipbp);
925 dsp_mem_disable(src);
927 dsp_mem_disable(ipbp);
930 struct ipbuf_head *ipb_h = bid_to_ipbuf(rcvdt->link.top);
933 if (dsp_mem_enable_ipbuf() < 0) {
937 rcvcnt = ((unsigned long)ipb_h->p->c) * 2;
940 if (copy_to_user_dsp(buf, ipb_h->p->d, count)) {
944 ipblink_del_top(&rcvdt->link);
948 dsp_mem_disable_ipbuf();
952 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
956 static ssize_t dsp_task_write_wd(struct file *file, const char __user *buf,
957 size_t count, loff_t *ppos)
959 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
960 struct taskdev *dev = taskdev[minor];
967 } else if (count & 0x1) {
969 "omapdsp: odd count is illegal for DSP task device.\n");
976 if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex))
979 prepare_to_wait(&dev->write_wait_q, &wait, TASK_INTERRUPTIBLE);
982 finish_wait(&dev->write_wait_q, &wait);
985 if (signal_pending(current))
990 if (copy_from_user(&wd, buf, count)) {
995 spin_lock(&dev->wsz_lock);
996 if (mbcompose_send(WDSND, dev->task->tid, wd) < 0) {
997 spin_unlock(&dev->wsz_lock);
1001 if (rcvtyp_acv(dev->task->ttyp))
1003 spin_unlock(&dev->wsz_lock);
1006 taskdev_unlock_and_stateunlock(dev, &dev->write_mutex);
1010 static ssize_t dsp_task_write_bk(struct file *file, const char __user *buf,
1011 size_t count, loff_t *ppos)
1013 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1014 struct taskdev *dev = taskdev[minor];
1020 } else if (count & 0x1) {
1022 "omapdsp: odd count is illegal for DSP task device.\n");
1024 } else if ((int)buf & 0x1) {
1026 "omapdsp: buf should be word aligned for "
1027 "dsp_task_write().\n");
1031 if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex))
1034 prepare_to_wait(&dev->write_wait_q, &wait, TASK_INTERRUPTIBLE);
1037 finish_wait(&dev->write_wait_q, &wait);
1038 if (dev->wsz == 0) {
1040 if (signal_pending(current))
1045 if (count > dev->wsz)
1048 if (rcvtyp_pvt(dev->task->ttyp)) {
1050 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_w;
1053 if (dsp_mem_enable(ipbp) < 0) {
1057 dst = MKVIRT(ipbp->ah, ipbp->al);
1058 if (dsp_address_validate(dst, count, "task %s write buffer",
1059 dev->task->name) < 0) {
1063 if (dsp_mem_enable(dst) < 0) {
1067 if (copy_from_user_dsp(dst, buf, count)) {
1072 ipbp->s = dev->task->tid;
1073 spin_lock(&dev->wsz_lock);
1074 if (mbcompose_send(BKSNDP, dev->task->tid, 0) == 0) {
1075 if (rcvtyp_acv(dev->task->ttyp))
1079 spin_unlock(&dev->wsz_lock);
1081 dsp_mem_disable(dst);
1083 dsp_mem_disable(ipbp);
1086 struct ipbuf_head *ipb_h;
1088 if (dsp_mem_enable_ipbuf() < 0) {
1092 if ((ipb_h = get_free_ipbuf(dev->task->tid)) == NULL)
1094 if (copy_from_user_dsp(ipb_h->p->d, buf, count)) {
1095 release_ipbuf(ipb_h);
1099 ipb_h->p->c = count/2;
1100 ipb_h->p->sa = dev->task->tid;
1101 spin_lock(&dev->wsz_lock);
1102 if (mbcompose_send(BKSND, dev->task->tid, ipb_h->bid) == 0) {
1103 if (rcvtyp_acv(dev->task->ttyp))
1106 ipb_bsycnt_inc(&ipbcfg);
1108 release_ipbuf(ipb_h);
1109 spin_unlock(&dev->wsz_lock);
1111 dsp_mem_disable_ipbuf();
1115 taskdev_unlock_and_stateunlock(dev, &dev->write_mutex);
1119 static unsigned int dsp_task_poll(struct file * file, poll_table * wait)
1121 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1122 struct taskdev *dev = taskdev[minor];
1123 struct dsptask *task = dev->task;
1124 unsigned int mask = 0;
1126 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
1128 poll_wait(file, &dev->read_wait_q, wait);
1129 poll_wait(file, &dev->write_wait_q, wait);
1130 if (sndtyp_psv(task->ttyp) ||
1131 (sndtyp_wd(task->ttyp) && kfifo_len(dev->rcvdt.fifo)) ||
1132 (sndtyp_bk(task->ttyp) && !ipblink_empty(&dev->rcvdt.bk.link)))
1133 mask |= POLLIN | POLLRDNORM;
1135 mask |= POLLOUT | POLLWRNORM;
1136 devstate_read_unlock(dev);
1141 static int dsp_tctl_issue(struct taskdev *dev, u16 cmd, int argc, u16 argv[])
1144 struct mb_exarg mbarg, *mbargp;
1152 * system reserved TCTL commands
1166 * user-defined TCTL commands
1168 else if (cmd < 0x8100) {
1169 /* 0x8000-0x80ff: no arg, non-interactive */
1172 } else if (cmd < 0x8200) {
1173 /* 0x8100-0x81ff: 1 arg, non-interactive */
1176 } else if (cmd < 0x9000) {
1177 /* 0x8200-0x8fff: reserved */
1179 } else if (cmd < 0x9100) {
1180 /* 0x9000-0x90ff: no arg, interactive */
1183 } else if (cmd < 0x9200) {
1184 /* 0x9100-0x91ff: 1 arg, interactive */
1188 /* 0x9200-0xffff: reserved */
1193 * if argc < 0, use tctl_argc as is.
1194 * if argc >= 0, check arg count.
1196 if ((argc >= 0) && (argc != tctl_argc))
1202 if (taskdev_lock_interruptible(dev, &dev->tctl_mutex))
1205 tid = dev->task->tid;
1206 if (tctl_argc > 0) {
1207 mbarg.argc = tctl_argc;
1215 dev->tctl_stat = -EINVAL;
1217 mbcompose_send_and_wait_exarg(TCTL, tid, cmd, mbargp,
1219 if (signal_pending(current)) {
1223 if ((ret = dev->tctl_stat) < 0) {
1224 printk(KERN_ERR "omapdsp: TCTL not responding.\n");
1228 mbcompose_send_exarg(TCTL, tid, cmd, mbargp);
1231 mutex_unlock(&dev->tctl_mutex);
1235 static int dsp_task_ioctl(struct inode *inode, struct file *file,
1236 unsigned int cmd, unsigned long arg)
1238 unsigned int minor = MINOR(inode->i_rdev);
1239 struct taskdev *dev = taskdev[minor];
1242 if (cmd < 0x10000) {
1246 mbargv[0] = arg & 0xffff;
1247 return dsp_tctl_issue(dev, cmd, -1, mbargv);
1250 /* non TCTL ioctls */
1253 case TASK_IOCTL_LOCK:
1254 ret = taskdev_lock(dev);
1257 case TASK_IOCTL_UNLOCK:
1258 ret = taskdev_unlock(dev);
1261 case TASK_IOCTL_BFLSH:
1262 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
1264 ret = taskdev_flush_buf(dev);
1265 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
1268 case TASK_IOCTL_SETBSZ:
1269 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
1271 ret = taskdev_set_fifosz(dev, arg);
1272 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
1275 case TASK_IOCTL_GETNAME:
1277 if (copy_to_user((void __user *)arg, dev->name,
1278 strlen(dev->name) + 1))
1290 static void dsp_task_mmap_open(struct vm_area_struct *vma)
1292 struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1293 struct dsptask *task;
1294 size_t len = vma->vm_end - vma->vm_start;
1296 BUG_ON(!(dev->state & TASKDEV_ST_ATTACHED));
1298 omap_mmu_exmap_use(&dsp_mmu, task->map_base, len);
1301 static void dsp_task_mmap_close(struct vm_area_struct *vma)
1303 struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1304 struct dsptask *task;
1305 size_t len = vma->vm_end - vma->vm_start;
1307 BUG_ON(!(dev->state & TASKDEV_ST_ATTACHED));
1309 omap_mmu_exmap_unuse(&dsp_mmu, task->map_base, len);
1313 * On demand page allocation is not allowed. The mapping area is defined by
1314 * corresponding DSP tasks.
1316 static struct page *dsp_task_mmap_nopage(struct vm_area_struct *vma,
1317 unsigned long address, int *type)
1319 return NOPAGE_SIGBUS;
1322 static struct vm_operations_struct dsp_task_vm_ops = {
1323 .open = dsp_task_mmap_open,
1324 .close = dsp_task_mmap_close,
1325 .nopage = dsp_task_mmap_nopage,
1328 static int dsp_task_mmap(struct file *filp, struct vm_area_struct *vma)
1331 unsigned long tmp_padr, tmp_vmadr, off;
1332 size_t req_len, tmp_len;
1333 unsigned int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
1334 struct taskdev *dev = taskdev[minor];
1335 struct dsptask *task;
1338 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
1343 * Don't swap this area out
1344 * Don't dump this area to a core file
1346 vma->vm_flags |= VM_RESERVED | VM_IO;
1348 /* Do not cache this area */
1349 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1351 req_len = vma->vm_end - vma->vm_start;
1352 off = vma->vm_pgoff << PAGE_SHIFT;
1353 tmp_vmadr = vma->vm_start;
1354 tmp_vadr = task->map_base + off;
1356 tmp_padr = omap_mmu_virt_to_phys(&dsp_mmu, tmp_vadr, &tmp_len);
1357 if (tmp_padr == 0) {
1359 "omapdsp: task %s: illegal address "
1360 "for mmap: %p", task->name, tmp_vadr);
1361 /* partial mapping will be cleared in upper layer */
1365 if (tmp_len > req_len)
1368 pr_debug("omapdsp: mmap info: "
1369 "vmadr = %08lx, padr = %08lx, len = %x\n",
1370 tmp_vmadr, tmp_padr, tmp_len);
1371 if (remap_pfn_range(vma, tmp_vmadr, tmp_padr >> PAGE_SHIFT,
1372 tmp_len, vma->vm_page_prot) != 0) {
1374 "omapdsp: task %s: remap_page_range() failed.\n",
1376 /* partial mapping will be cleared in upper layer */
1382 tmp_vmadr += tmp_len;
1383 tmp_vadr += tmp_len;
1386 vma->vm_ops = &dsp_task_vm_ops;
1387 vma->vm_private_data = dev;
1388 omap_mmu_exmap_use(&dsp_mmu, task->map_base, vma->vm_end - vma->vm_start);
1391 devstate_read_unlock(dev);
1395 static int dsp_task_open(struct inode *inode, struct file *file)
1397 unsigned int minor = MINOR(inode->i_rdev);
1398 struct taskdev *dev;
1401 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL))
1405 mutex_lock(&dev->usecount_lock);
1406 down_write(&dev->state_sem);
1408 /* state can be NOTASK, ATTACHED/FREEZED, KILLING, GARBAGE or INVALID here. */
1409 switch (dev->state & TASKDEV_ST_STATE_MASK) {
1410 case TASKDEV_ST_NOTASK:
1412 case TASKDEV_ST_ATTACHED:
1415 case TASKDEV_ST_INVALID:
1416 up_write(&dev->state_sem);
1417 mutex_unlock(&dev->usecount_lock);
1420 case TASKDEV_ST_FREEZED:
1421 case TASKDEV_ST_KILLING:
1422 case TASKDEV_ST_GARBAGE:
1423 case TASKDEV_ST_DELREQ:
1424 /* on the kill process. wait until it becomes NOTASK. */
1425 up_write(&dev->state_sem);
1426 mutex_unlock(&dev->usecount_lock);
1427 if (devstate_write_lock(dev, TASKDEV_ST_NOTASK) < 0)
1429 devstate_write_unlock(dev);
1434 set_taskdev_state(dev, TASKDEV_ST_ADDREQ);
1435 /* wake up twch daemon for tadd */
1437 up_write(&dev->state_sem);
1438 if (devstate_write_lock(dev, TASKDEV_ST_ATTACHED |
1439 TASKDEV_ST_ADDFAIL) < 0) {
1441 if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) {
1442 mutex_unlock(&dev->usecount_lock);
1443 /* out of control ??? */
1446 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1450 if (dev->state & TASKDEV_ST_ADDFAIL) {
1451 printk(KERN_ERR "omapdsp: task attach failed for %s!\n",
1454 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1459 ret = proc_list_add(&dev->proc_list_lock,
1460 &dev->proc_list, current, file);
1465 file->f_op = &dev->fops;
1466 up_write(&dev->state_sem);
1467 mutex_unlock(&dev->usecount_lock);
1469 #ifdef DSP_PTE_FREE /* not used currently. */
1470 dsp_map_update(current);
1471 dsp_cur_users_add(current);
1472 #endif /* DSP_PTE_FREE */
1476 wake_up_interruptible_all(&dev->state_wait_q);
1478 up_write(&dev->state_sem);
1479 mutex_unlock(&dev->usecount_lock);
1483 static int dsp_task_release(struct inode *inode, struct file *file)
1485 unsigned int minor = MINOR(inode->i_rdev);
1486 struct taskdev *dev = taskdev[minor];
1488 #ifdef DSP_PTE_FREE /* not used currently. */
1489 dsp_cur_users_del(current);
1490 #endif /* DSP_PTE_FREE */
1492 if (has_taskdev_lock(dev))
1493 taskdev_unlock(dev);
1495 proc_list_del(&dev->proc_list_lock, &dev->proc_list, current, file);
1496 mutex_lock(&dev->usecount_lock);
1497 if (--dev->usecount > 0) {
1498 /* other processes are using this device. no state change. */
1499 mutex_unlock(&dev->usecount_lock);
1504 down_write(&dev->state_sem);
1506 /* state can be ATTACHED/FREEZED, KILLING or GARBAGE here. */
1507 switch (dev->state & TASKDEV_ST_STATE_MASK) {
1509 case TASKDEV_ST_KILLING:
1512 case TASKDEV_ST_GARBAGE:
1513 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1514 wake_up_interruptible_all(&dev->state_wait_q);
1517 case TASKDEV_ST_ATTACHED:
1518 case TASKDEV_ST_FREEZED:
1519 if (is_dynamic_task(minor)) {
1520 set_taskdev_state(dev, TASKDEV_ST_DELREQ);
1521 /* wake up twch daemon for tdel */
1528 up_write(&dev->state_sem);
1529 mutex_unlock(&dev->usecount_lock);
1536 int dsp_mkdev(char *name)
1538 struct taskdev *dev;
1540 unsigned char minor;
1543 if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
1544 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1548 if (mutex_lock_interruptible(&devmgr_lock))
1552 for (minor = 0; minor < TASKDEV_MAX; minor++) {
1553 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1555 "omapdsp: task device name %s is already "
1562 /* find free minor number */
1563 for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1564 if (taskdev[minor] == NULL)
1567 printk(KERN_ERR "omapdsp: Too many task devices.\n");
1572 if ((dev = kzalloc(sizeof(struct taskdev), GFP_KERNEL)) == NULL) {
1576 if ((status = taskdev_init(dev, name, minor)) < 0) {
1584 mutex_unlock(&devmgr_lock);
1588 int dsp_rmdev(char *name)
1590 unsigned char minor;
1594 if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
1595 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1599 if (mutex_lock_interruptible(&devmgr_lock))
1602 /* find in dynamic devices */
1603 for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1604 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name))
1608 /* find in static devices */
1609 for (minor = 0; minor < n_task; minor++) {
1610 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1612 "omapdsp: task device %s is static.\n", name);
1618 printk(KERN_ERR "omapdsp: task device %s not found.\n", name);
1623 if ((status = dsp_rmdev_minor(minor)) < 0)
1626 mutex_unlock(&devmgr_lock);
1630 static int dsp_rmdev_minor(unsigned char minor)
1632 struct taskdev *dev = taskdev[minor];
1634 while (!down_write_trylock(&dev->state_sem)) {
1635 down_read(&dev->state_sem);
1636 if (dev->state & (TASKDEV_ST_ATTACHED |
1637 TASKDEV_ST_FREEZED)) {
1639 * task is working. kill it.
1640 * ATTACHED -> FREEZED can be changed under
1641 * down_read of state_sem..
1643 set_taskdev_state(dev, TASKDEV_ST_FREEZED);
1644 wake_up_interruptible_all(&dev->read_wait_q);
1645 wake_up_interruptible_all(&dev->write_wait_q);
1646 wake_up_interruptible_all(&dev->tctl_wait_q);
1648 up_read(&dev->state_sem);
1652 switch (dev->state & TASKDEV_ST_STATE_MASK) {
1654 case TASKDEV_ST_NOTASK:
1655 case TASKDEV_ST_INVALID:
1659 case TASKDEV_ST_ATTACHED:
1660 case TASKDEV_ST_FREEZED:
1661 /* task is working. kill it. */
1662 set_taskdev_state(dev, TASKDEV_ST_KILLING);
1663 up_write(&dev->state_sem);
1664 dsp_tdel_bh(dev, TDEL_KILL);
1667 case TASKDEV_ST_ADDREQ:
1668 /* open() is waiting. drain it. */
1669 set_taskdev_state(dev, TASKDEV_ST_ADDFAIL);
1670 wake_up_interruptible_all(&dev->state_wait_q);
1673 case TASKDEV_ST_DELREQ:
1674 /* nobody is waiting. */
1675 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1676 wake_up_interruptible_all(&dev->state_wait_q);
1679 case TASKDEV_ST_ADDING:
1680 case TASKDEV_ST_DELING:
1681 case TASKDEV_ST_KILLING:
1682 case TASKDEV_ST_GARBAGE:
1683 case TASKDEV_ST_ADDFAIL:
1684 /* transient state. wait for a moment. */
1689 up_write(&dev->state_sem);
1692 /* wait for some time and hope the state is settled */
1693 devstate_read_lock_timeout(dev, TASKDEV_ST_NOTASK, 5 * HZ);
1694 if (!(dev->state & TASKDEV_ST_NOTASK)) {
1696 "omapdsp: illegal device state (%s) on rmdev %s.\n",
1697 devstate_name(dev->state), dev->name);
1700 set_taskdev_state(dev, TASKDEV_ST_INVALID);
1701 devstate_read_unlock(dev);
1703 taskdev_delete(minor);
1709 static struct file_operations dsp_task_fops = {
1710 .owner = THIS_MODULE,
1711 .poll = dsp_task_poll,
1712 .ioctl = dsp_task_ioctl,
1713 .open = dsp_task_open,
1714 .release = dsp_task_release,
1717 static void dsptask_dev_release(struct device *dev)
1721 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor)
1724 struct device *task_dev;
1726 taskdev[minor] = dev;
1728 spin_lock_init(&dev->proc_list_lock);
1729 INIT_LIST_HEAD(&dev->proc_list);
1730 init_waitqueue_head(&dev->read_wait_q);
1731 init_waitqueue_head(&dev->write_wait_q);
1732 init_waitqueue_head(&dev->tctl_wait_q);
1733 mutex_init(&dev->read_mutex);
1734 mutex_init(&dev->write_mutex);
1735 mutex_init(&dev->tctl_mutex);
1736 mutex_init(&dev->lock);
1737 spin_lock_init(&dev->wsz_lock);
1738 dev->tctl_ret = -EINVAL;
1741 strncpy(dev->name, name, TNM_LEN);
1742 dev->name[TNM_LEN-1] = '\0';
1743 set_taskdev_state(dev, (minor < n_task) ? TASKDEV_ST_ATTACHED : TASKDEV_ST_NOTASK);
1745 mutex_init(&dev->usecount_lock);
1746 memcpy(&dev->fops, &dsp_task_fops, sizeof(struct file_operations));
1748 dev->dev.parent = omap_dsp->dev;
1749 dev->dev.bus = &dsptask_bus;
1750 sprintf(dev->dev.bus_id, "dsptask%d", minor);
1751 dev->dev.release = dsptask_dev_release;
1752 ret = device_register(&dev->dev);
1754 printk(KERN_ERR "device_register failed: %d\n", ret);
1757 ret = device_create_file(&dev->dev, &dev_attr_devname);
1759 goto fail_create_devname;
1760 ret = device_create_file(&dev->dev, &dev_attr_devstate);
1762 goto fail_create_devstate;
1763 ret = device_create_file(&dev->dev, &dev_attr_proc_list);
1765 goto fail_create_proclist;
1767 task_dev = device_create(dsp_task_class, NULL,
1768 MKDEV(OMAP_DSP_TASK_MAJOR, minor),
1769 "dsptask%d", (int)minor);
1771 if (unlikely(IS_ERR(task_dev))) {
1773 goto fail_create_taskclass;
1776 init_waitqueue_head(&dev->state_wait_q);
1777 init_rwsem(&dev->state_sem);
1781 fail_create_taskclass:
1782 device_remove_file(&dev->dev, &dev_attr_proc_list);
1783 fail_create_proclist:
1784 device_remove_file(&dev->dev, &dev_attr_devstate);
1785 fail_create_devstate:
1786 device_remove_file(&dev->dev, &dev_attr_devname);
1787 fail_create_devname:
1788 device_unregister(&dev->dev);
1792 static void taskdev_delete(unsigned char minor)
1794 struct taskdev *dev = taskdev[minor];
1798 device_remove_file(&dev->dev, &dev_attr_devname);
1799 device_remove_file(&dev->dev, &dev_attr_devstate);
1800 device_remove_file(&dev->dev, &dev_attr_proc_list);
1801 device_destroy(dsp_task_class, MKDEV(OMAP_DSP_TASK_MAJOR, minor));
1802 device_unregister(&dev->dev);
1803 proc_list_flush(&dev->proc_list_lock, &dev->proc_list);
1804 taskdev[minor] = NULL;
1807 static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task)
1809 u16 ttyp = task->ttyp;
1814 sndtyp_wd(ttyp) ? dsp_task_read_wd_acv:
1815 /* sndtyp_bk */ dsp_task_read_bk_acv:
1817 sndtyp_wd(ttyp) ? dsp_task_read_wd_psv:
1818 /* sndtyp_bk */ dsp_task_read_bk_psv;
1819 if (sndtyp_wd(ttyp)) {
1821 size_t fifosz = sndtyp_psv(ttyp) ? 2:32; /* passive:active */
1823 dev->rcvdt.fifo = kfifo_alloc(fifosz, GFP_KERNEL,
1825 if (IS_ERR(dev->rcvdt.fifo)) {
1827 "omapdsp: unable to allocate receive buffer. "
1828 "(%d bytes for %s)\n", fifosz, dev->name);
1833 INIT_IPBLINK(&dev->rcvdt.bk.link);
1834 dev->rcvdt.bk.rp = 0;
1838 rcvtyp_wd(ttyp) ? dsp_task_write_wd:
1839 /* rcvbyp_bk */ dsp_task_write_bk;
1840 dev->wsz = rcvtyp_acv(ttyp) ? 0 : /* active */
1841 rcvtyp_wd(ttyp) ? 2 : /* passive word */
1842 ipbcfg.lsz*2; /* passive block */
1844 if (task->map_length)
1845 dev->fops.mmap = dsp_task_mmap;
1847 ret = device_create_file(&dev->dev, &dev_attr_taskname);
1849 goto fail_create_taskname;
1850 ret = device_create_file(&dev->dev, &dev_attr_ttyp);
1852 goto fail_create_ttyp;
1853 ret = device_create_file(&dev->dev, &dev_attr_wsz);
1855 goto fail_create_wsz;
1856 if (task->map_length) {
1857 ret = device_create_file(&dev->dev, &dev_attr_mmap);
1859 goto fail_create_mmap;
1861 if (sndtyp_wd(ttyp)) {
1862 ret = device_create_file(&dev->dev, &dev_attr_fifosz);
1864 goto fail_create_fifosz;
1865 ret = device_create_file(&dev->dev, &dev_attr_fifocnt);
1867 goto fail_create_fifocnt;
1869 ret = device_create_file(&dev->dev, &dev_attr_ipblink);
1871 goto fail_create_ipblink;
1879 fail_create_fifocnt:
1880 device_remove_file(&dev->dev, &dev_attr_fifosz);
1881 fail_create_ipblink:
1883 if (task->map_length)
1884 device_remove_file(&dev->dev, &dev_attr_mmap);
1886 device_remove_file(&dev->dev, &dev_attr_wsz);
1888 device_remove_file(&dev->dev, &dev_attr_ttyp);
1890 device_remove_file(&dev->dev, &dev_attr_taskname);
1891 fail_create_taskname:
1892 if (task->map_length)
1893 dev->fops.mmap = NULL;
1895 dev->fops.write = NULL;
1898 dev->fops.read = NULL;
1899 taskdev_flush_buf(dev);
1901 if (sndtyp_wd(ttyp))
1902 kfifo_free(dev->rcvdt.fifo);
1909 static void taskdev_detach_task(struct taskdev *dev)
1911 u16 ttyp = dev->task->ttyp;
1913 device_remove_file(&dev->dev, &dev_attr_taskname);
1914 device_remove_file(&dev->dev, &dev_attr_ttyp);
1915 if (sndtyp_wd(ttyp)) {
1916 device_remove_file(&dev->dev, &dev_attr_fifosz);
1917 device_remove_file(&dev->dev, &dev_attr_fifocnt);
1919 device_remove_file(&dev->dev, &dev_attr_ipblink);
1920 device_remove_file(&dev->dev, &dev_attr_wsz);
1921 if (dev->task->map_length) {
1922 device_remove_file(&dev->dev, &dev_attr_mmap);
1923 dev->fops.mmap = NULL;
1926 dev->fops.read = NULL;
1927 taskdev_flush_buf(dev);
1928 if (sndtyp_wd(ttyp))
1929 kfifo_free(dev->rcvdt.fifo);
1931 dev->fops.write = NULL;
1934 pr_info("omapdsp: taskdev %s disabled.\n", dev->name);
1939 * tadd / tdel / tkill
1941 static int dsp_tadd(struct taskdev *dev, dsp_long_t adr)
1943 struct dsptask *task;
1944 struct mb_exarg arg;
1945 u8 tid, tid_response;
1949 if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) {
1951 "omapdsp: taskdev %s is not requesting for tadd. "
1952 "(state is %s)\n", dev->name, devstate_name(dev->state));
1955 set_taskdev_state(dev, TASKDEV_ST_ADDING);
1956 devstate_write_unlock(dev);
1958 if (adr == TADD_ABORTADR) {
1959 /* aborting tadd intentionally */
1960 pr_info("omapdsp: tadd address is ABORTADR.\n");
1963 if (adr >= DSPSPACE_SIZE) {
1965 "omapdsp: illegal address 0x%08x for tadd\n", adr);
1970 adr >>= 1; /* word address */
1971 argv[0] = adr >> 16; /* addrh */
1972 argv[1] = adr & 0xffff; /* addrl */
1974 if (mutex_lock_interruptible(&cfg_lock)) {
1979 cfg_cmd = MBOX_CMD_DSP_TADD;
1984 if (dsp_mem_sync_inc() < 0) {
1985 printk(KERN_ERR "omapdsp: memory sync failed!\n");
1989 mbcompose_send_and_wait_exarg(TADD, 0, 0, &arg, &cfg_wait_q);
1994 mutex_unlock(&cfg_lock);
1996 if (tid == TID_ANON) {
1997 printk(KERN_ERR "omapdsp: tadd failed!\n");
2001 if ((tid < n_task) || dsptask[tid]) {
2002 printk(KERN_ERR "omapdsp: illegal tid (%d)!\n", tid);
2006 if ((task = kzalloc(sizeof(struct dsptask), GFP_KERNEL)) == NULL) {
2011 if ((ret = dsp_task_config(task, tid)) < 0)
2014 if (strcmp(dev->name, task->name)) {
2016 "omapdsp: task name (%s) doesn't match with "
2017 "device name (%s).\n", task->name, dev->name);
2022 if ((ret = taskdev_attach_task(dev, task)) < 0)
2025 dsp_task_init(task);
2026 pr_info("omapdsp: taskdev %s enabled.\n", dev->name);
2027 set_taskdev_state(dev, TASKDEV_ST_ATTACHED);
2028 wake_up_interruptible_all(&dev->state_wait_q);
2035 printk(KERN_ERR "omapdsp: deleting the task...\n");
2037 set_taskdev_state(dev, TASKDEV_ST_DELING);
2039 if (mutex_lock_interruptible(&cfg_lock)) {
2040 printk(KERN_ERR "omapdsp: aborting tdel process. "
2041 "DSP side could be corrupted.\n");
2045 cfg_cmd = MBOX_CMD_DSP_TDEL;
2046 mbcompose_send_and_wait(TDEL, tid, TDEL_KILL, &cfg_wait_q);
2047 tid_response = cfg_tid;
2050 mutex_unlock(&cfg_lock);
2052 if (tid_response != tid)
2053 printk(KERN_ERR "omapdsp: tdel failed. "
2054 "DSP side could be corrupted.\n");
2057 set_taskdev_state(dev, TASKDEV_ST_ADDFAIL);
2058 wake_up_interruptible_all(&dev->state_wait_q);
2062 int dsp_tadd_minor(unsigned char minor, dsp_long_t adr)
2064 struct taskdev *dev;
2068 if (mutex_lock_interruptible(&devmgr_lock))
2071 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2073 "omapdsp: no task device with minor %d\n", minor);
2078 if ((status = dsp_tadd(dev, adr)) < 0)
2082 mutex_unlock(&devmgr_lock);
2086 static int dsp_tdel(struct taskdev *dev)
2088 if (!devstate_write_lock_and_test(dev, TASKDEV_ST_DELREQ)) {
2090 "omapdsp: taskdev %s is not requesting for tdel. "
2091 "(state is %s)\n", dev->name, devstate_name(dev->state));
2094 set_taskdev_state(dev, TASKDEV_ST_DELING);
2095 devstate_write_unlock(dev);
2097 return dsp_tdel_bh(dev, TDEL_SAFE);
2100 int dsp_tdel_minor(unsigned char minor)
2102 struct taskdev *dev;
2106 if (mutex_lock_interruptible(&devmgr_lock))
2109 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2111 "omapdsp: no task device with minor %d\n", minor);
2117 if ((status = dsp_tdel(dev)) < 0)
2121 mutex_unlock(&devmgr_lock);
2125 static int dsp_tkill(struct taskdev *dev)
2127 while (!down_write_trylock(&dev->state_sem)) {
2128 if (!devstate_read_lock_and_test(dev, (TASKDEV_ST_ATTACHED |
2129 TASKDEV_ST_FREEZED))) {
2131 "omapdsp: task has not been attached for "
2132 "taskdev %s\n", dev->name);
2135 /* ATTACHED -> FREEZED can be changed under read semaphore. */
2136 set_taskdev_state(dev, TASKDEV_ST_FREEZED);
2137 wake_up_interruptible_all(&dev->read_wait_q);
2138 wake_up_interruptible_all(&dev->write_wait_q);
2139 wake_up_interruptible_all(&dev->tctl_wait_q);
2140 devstate_read_unlock(dev);
2144 if (!(dev->state & (TASKDEV_ST_ATTACHED |
2145 TASKDEV_ST_FREEZED))) {
2147 "omapdsp: task has not been attached for taskdev %s\n",
2149 devstate_write_unlock(dev);
2152 if (!is_dynamic_task(dev->task->tid)) {
2153 printk(KERN_ERR "omapdsp: task %s is not a dynamic task.\n",
2155 devstate_write_unlock(dev);
2158 set_taskdev_state(dev, TASKDEV_ST_KILLING);
2159 devstate_write_unlock(dev);
2161 return dsp_tdel_bh(dev, TDEL_KILL);
2164 int dsp_tkill_minor(unsigned char minor)
2166 struct taskdev *dev;
2170 if (mutex_lock_interruptible(&devmgr_lock))
2173 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2175 "omapdsp: no task device with minor %d\n", minor);
2181 if ((status = dsp_tkill(dev)) < 0)
2185 mutex_unlock(&devmgr_lock);
2189 static int dsp_tdel_bh(struct taskdev *dev, u16 type)
2191 struct dsptask *task;
2192 u8 tid, tid_response;
2197 if (mutex_lock_interruptible(&cfg_lock)) {
2198 if (type == TDEL_SAFE) {
2199 set_taskdev_state(dev, TASKDEV_ST_DELREQ);
2202 tid_response = TID_ANON;
2208 cfg_cmd = MBOX_CMD_DSP_TDEL;
2209 mbcompose_send_and_wait(TDEL, tid, type, &cfg_wait_q);
2210 tid_response = cfg_tid;
2213 mutex_unlock(&cfg_lock);
2216 taskdev_detach_task(dev);
2217 dsp_task_unconfig(task);
2220 if (tid_response != tid) {
2221 printk(KERN_ERR "omapdsp: %s failed!\n",
2222 (type == TDEL_SAFE) ? "tdel" : "tkill");
2225 down_write(&dev->state_sem);
2226 set_taskdev_state(dev, (dev->usecount > 0) ? TASKDEV_ST_GARBAGE :
2228 wake_up_interruptible_all(&dev->state_wait_q);
2229 up_write(&dev->state_sem);
2237 long taskdev_state_stale(unsigned char minor)
2239 if (taskdev[minor]) {
2240 long state = taskdev[minor]->state;
2241 taskdev[minor]->state |= TASKDEV_ST_STALE;
2244 return TASKDEV_ST_NOTASK;
2248 * functions called from mailbox interrupt routine
2250 void mbox_wdsnd(struct mbcmd *mb)
2254 u16 data = mb->data;
2255 struct dsptask *task = dsptask[tid];
2257 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2258 printk(KERN_ERR "mbox: WDSND with illegal tid! %d\n", tid);
2261 if (sndtyp_bk(task->ttyp)) {
2263 "mbox: WDSND from block sending task! (task%d)\n", tid);
2266 if (sndtyp_psv(task->ttyp) &&
2267 !waitqueue_active(&task->dev->read_wait_q)) {
2269 "mbox: WDSND from passive sending task (task%d) "
2270 "without request!\n", tid);
2274 n = kfifo_put(task->dev->rcvdt.fifo, (unsigned char *)&data,
2276 if (n != sizeof(data))
2277 printk(KERN_WARNING "Receive FIFO(%d) is full\n", tid);
2279 wake_up_interruptible(&task->dev->read_wait_q);
2282 void mbox_wdreq(struct mbcmd *mb)
2285 struct dsptask *task = dsptask[tid];
2286 struct taskdev *dev;
2288 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2289 printk(KERN_ERR "mbox: WDREQ with illegal tid! %d\n", tid);
2292 if (rcvtyp_psv(task->ttyp)) {
2294 "mbox: WDREQ from passive receiving task! (task%d)\n",
2300 spin_lock(&dev->wsz_lock);
2302 spin_unlock(&dev->wsz_lock);
2303 wake_up_interruptible(&dev->write_wait_q);
2306 void mbox_bksnd(struct mbcmd *mb)
2310 struct dsptask *task = dsptask[tid];
2311 struct ipbuf_head *ipb_h;
2314 if (bid >= ipbcfg.ln) {
2315 printk(KERN_ERR "mbox: BKSND with illegal bid! %d\n", bid);
2318 ipb_h = bid_to_ipbuf(bid);
2319 ipb_bsycnt_dec(&ipbcfg);
2320 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2321 printk(KERN_ERR "mbox: BKSND with illegal tid! %d\n", tid);
2322 goto unuse_ipbuf_out;
2324 if (sndtyp_wd(task->ttyp)) {
2326 "mbox: BKSND from word sending task! (task%d)\n", tid);
2327 goto unuse_ipbuf_out;
2329 if (sndtyp_pvt(task->ttyp)) {
2331 "mbox: BKSND from private sending task! (task%d)\n", tid);
2332 goto unuse_ipbuf_out;
2334 if (sync_with_dsp(&ipb_h->p->sd, tid, 10) < 0) {
2335 printk(KERN_ERR "mbox: BKSND - IPBUF sync failed!\n");
2339 /* should be done in DSP, but just in case. */
2340 ipb_h->p->next = BID_NULL;
2343 if (cnt > ipbcfg.lsz) {
2344 printk(KERN_ERR "mbox: BKSND cnt(%d) > ipbuf line size(%d)!\n",
2346 goto unuse_ipbuf_out;
2350 /* 0-byte send from DSP */
2351 unuse_ipbuf_nowait(ipb_h);
2354 ipblink_add_tail(&task->dev->rcvdt.bk.link, bid);
2355 /* we keep coming bid and return alternative line to DSP. */
2359 wake_up_interruptible(&task->dev->read_wait_q);
2363 unuse_ipbuf_nowait(ipb_h);
2367 void mbox_bkreq(struct mbcmd *mb)
2371 struct dsptask *task = dsptask[tid];
2372 struct taskdev *dev;
2374 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2375 printk(KERN_ERR "mbox: BKREQ with illegal tid! %d\n", tid);
2378 if (rcvtyp_wd(task->ttyp)) {
2380 "mbox: BKREQ from word receiving task! (task%d)\n", tid);
2383 if (rcvtyp_pvt(task->ttyp)) {
2385 "mbox: BKREQ from private receiving task! (task%d)\n",
2389 if (rcvtyp_psv(task->ttyp)) {
2391 "mbox: BKREQ from passive receiving task! (task%d)\n",
2397 spin_lock(&dev->wsz_lock);
2399 spin_unlock(&dev->wsz_lock);
2400 wake_up_interruptible(&dev->write_wait_q);
2403 void mbox_bkyld(struct mbcmd *mb)
2406 struct ipbuf_head *ipb_h;
2408 if (bid >= ipbcfg.ln) {
2409 printk(KERN_ERR "mbox: BKYLD with illegal bid! %d\n", bid);
2412 ipb_h = bid_to_ipbuf(bid);
2414 /* should be done in DSP, but just in case. */
2415 ipb_h->p->next = BID_NULL;
2417 /* we don't need to sync with DSP */
2418 ipb_bsycnt_dec(&ipbcfg);
2419 release_ipbuf(ipb_h);
2422 void mbox_bksndp(struct mbcmd *mb)
2425 struct dsptask *task = dsptask[tid];
2426 struct ipbuf_p *ipbp;
2428 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2429 printk(KERN_ERR "mbox: BKSNDP with illegal tid! %d\n", tid);
2432 if (sndtyp_wd(task->ttyp)) {
2434 "mbox: BKSNDP from word sending task! (task%d)\n", tid);
2437 if (sndtyp_gbl(task->ttyp)) {
2439 "mbox: BKSNDP from non-private sending task! (task%d)\n",
2445 * we should not have delayed block at this point
2446 * because read() routine releases the lock of the buffer and
2447 * until then DSP can't send next data.
2450 ipbp = task->ipbuf_pvt_r;
2451 if (sync_with_dsp(&ipbp->s, tid, 10) < 0) {
2452 printk(KERN_ERR "mbox: BKSNDP - IPBUF sync failed!\n");
2455 pr_debug("mbox: ipbuf_pvt_r->a = 0x%08lx\n",
2456 MKLONG(ipbp->ah, ipbp->al));
2457 ipblink_add_pvt(&task->dev->rcvdt.bk.link);
2458 wake_up_interruptible(&task->dev->read_wait_q);
2461 void mbox_bkreqp(struct mbcmd *mb)
2464 struct dsptask *task = dsptask[tid];
2465 struct taskdev *dev;
2466 struct ipbuf_p *ipbp;
2468 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2469 printk(KERN_ERR "mbox: BKREQP with illegal tid! %d\n", tid);
2472 if (rcvtyp_wd(task->ttyp)) {
2474 "mbox: BKREQP from word receiving task! (task%d)\n", tid);
2477 if (rcvtyp_gbl(task->ttyp)) {
2479 "mbox: BKREQP from non-private receiving task! (task%d)\n", tid);
2482 if (rcvtyp_psv(task->ttyp)) {
2484 "mbox: BKREQP from passive receiving task! (task%d)\n", tid);
2488 ipbp = task->ipbuf_pvt_w;
2489 if (sync_with_dsp(&ipbp->s, TID_FREE, 10) < 0) {
2490 printk(KERN_ERR "mbox: BKREQP - IPBUF sync failed!\n");
2493 pr_debug("mbox: ipbuf_pvt_w->a = 0x%08lx\n",
2494 MKLONG(ipbp->ah, ipbp->al));
2496 spin_lock(&dev->wsz_lock);
2497 dev->wsz = ipbp->c*2;
2498 spin_unlock(&dev->wsz_lock);
2499 wake_up_interruptible(&dev->write_wait_q);
2502 void mbox_tctl(struct mbcmd *mb)
2505 struct dsptask *task = dsptask[tid];
2507 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2508 printk(KERN_ERR "mbox: TCTL with illegal tid! %d\n", tid);
2512 if (!waitqueue_active(&task->dev->tctl_wait_q)) {
2513 printk(KERN_WARNING "mbox: unexpected TCTL from DSP!\n");
2517 task->dev->tctl_stat = mb->data;
2518 wake_up_interruptible(&task->dev->tctl_wait_q);
2521 void mbox_tcfg(struct mbcmd *mb)
2524 struct dsptask *task = dsptask[tid];
2529 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2530 printk(KERN_ERR "mbox: TCFG with illegal tid! %d\n", tid);
2533 if ((task->state != TASK_ST_CFGREQ) || (cfg_cmd != MBOX_CMD_DSP_TCFG)) {
2534 printk(KERN_WARNING "mbox: unexpected TCFG from DSP!\n");
2538 if (dsp_mem_enable(ipbuf_sys_da) < 0) {
2539 printk(KERN_ERR "mbox: TCFG - ipbuf_sys_da read failed!\n");
2540 dsp_mem_disable(ipbuf_sys_da);
2543 if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2544 printk(KERN_ERR "mbox: TCFG - IPBUF sync failed!\n");
2545 dsp_mem_disable(ipbuf_sys_da);
2550 * read configuration data on system IPBUF
2552 buf = ipbuf_sys_da->d;
2553 task->ttyp = buf[0];
2554 task->ipbuf_pvt_r = MKVIRT(buf[1], buf[2]);
2555 task->ipbuf_pvt_w = MKVIRT(buf[3], buf[4]);
2556 task->map_base = MKVIRT(buf[5], buf[6]);
2557 task->map_length = MKLONG(buf[7], buf[8]) << 1; /* word -> byte */
2558 tnm = MKVIRT(buf[9], buf[10]);
2559 release_ipbuf_pvt(ipbuf_sys_da);
2560 dsp_mem_disable(ipbuf_sys_da);
2563 * copy task name string
2565 if (dsp_address_validate(tnm, TNM_LEN, "task name buffer") < 0) {
2566 task->name[0] = '\0';
2570 for (i = 0; i < TNM_LEN-1; i++) {
2571 /* avoiding byte access */
2573 task->name[i] = tmp & 0x00ff;
2577 task->name[TNM_LEN-1] = '\0';
2579 task->state = TASK_ST_READY;
2581 wake_up_interruptible(&cfg_wait_q);
2584 void mbox_tadd(struct mbcmd *mb)
2588 if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBOX_CMD_DSP_TADD)) {
2589 printk(KERN_WARNING "mbox: unexpected TADD from DSP!\n");
2593 wake_up_interruptible(&cfg_wait_q);
2596 void mbox_tdel(struct mbcmd *mb)
2600 if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBOX_CMD_DSP_TDEL)) {
2601 printk(KERN_WARNING "mbox: unexpected TDEL from DSP!\n");
2605 wake_up_interruptible(&cfg_wait_q);
2608 void mbox_err_fatal(u8 tid)
2610 struct dsptask *task = dsptask[tid];
2611 struct taskdev *dev;
2613 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2614 printk(KERN_ERR "mbox: FATAL ERR with illegal tid! %d\n", tid);
2618 /* wake up waiting processes */
2620 wake_up_interruptible_all(&dev->read_wait_q);
2621 wake_up_interruptible_all(&dev->write_wait_q);
2622 wake_up_interruptible_all(&dev->tctl_wait_q);
2625 static u16 *dbg_buf;
2626 static u16 dbg_buf_sz, dbg_line_sz;
2629 int dsp_dbg_config(u16 *buf, u16 sz, u16 lsz)
2631 #ifdef OLD_BINARY_SUPPORT
2632 if ((mbox_revision == MBREV_3_0) || (mbox_revision == MBREV_3_2)) {
2641 if (dsp_address_validate(buf, sz, "debug buffer") < 0)
2646 "omapdsp: dbg_buf lsz (%d) is greater than its "
2647 "buffer size (%d)\n", lsz, sz);
2659 void dsp_dbg_stop(void)
2664 #ifdef OLD_BINARY_SUPPORT
2665 static void mbox_dbg_old(struct mbcmd *mb);
2668 void mbox_dbg(struct mbcmd *mb)
2672 char s[80], *s_end = &s[79], *p;
2676 #ifdef OLD_BINARY_SUPPORT
2677 if ((mbox_revision == MBREV_3_0) || (mbox_revision == MBREV_3_2)) {
2683 if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2684 (tid != TID_ANON)) {
2685 printk(KERN_ERR "mbox: DBG with illegal tid! %d\n", tid);
2688 if (dbg_buf == NULL) {
2689 printk(KERN_ERR "mbox: DBG command received, but "
2690 "dbg_buf has not been configured yet.\n");
2694 if (dsp_mem_enable(dbg_buf) < 0)
2697 src = &dbg_buf[dbg_rp];
2699 for (i = 0; i < cnt; i++) {
2702 * Be carefull that dbg_buf should not be read with
2703 * 1-byte access since it might be placed in DARAM/SARAM
2704 * and it can cause unexpected byteswap.
2706 * *(p++) = *(src++) & 0xff;
2707 * causes 1-byte access!
2710 *(p++) = tmp & 0xff;
2711 if (*(p-1) == '\n') {
2728 if ((dbg_rp += cnt + 1) > dbg_buf_sz - dbg_line_sz)
2731 dsp_mem_disable(dbg_buf);
2734 #ifdef OLD_BINARY_SUPPORT
2735 static void mbox_dbg_old(struct mbcmd *mb)
2738 char s[80], *s_end = &s[79], *p;
2744 if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2745 (tid != TID_ANON)) {
2746 printk(KERN_ERR "mbox: DBG with illegal tid! %d\n", tid);
2749 if (dsp_mem_enable(ipbuf_sys_da) < 0) {
2750 printk(KERN_ERR "mbox: DBG - ipbuf_sys_da read failed!\n");
2753 if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2754 printk(KERN_ERR "mbox: DBG - IPBUF sync failed!\n");
2757 buf = ipbuf_sys_da->d;
2759 src = MKVIRT(buf[1], buf[2]);
2760 if (dsp_address_validate(src, cnt, "dbg buffer") < 0)
2763 if (dsp_mem_enable(src) < 0)
2767 for (i = 0; i < cnt; i++) {
2770 * Be carefull that ipbuf should not be read with
2771 * 1-byte access since it might be placed in DARAM/SARAM
2772 * and it can cause unexpected byteswap.
2774 * *(p++) = *(src++) & 0xff;
2775 * causes 1-byte access!
2778 *(p++) = tmp & 0xff;
2779 if (*(p-1) == '\n') {
2797 dsp_mem_disable(src);
2799 release_ipbuf_pvt(ipbuf_sys_da);
2801 dsp_mem_disable(ipbuf_sys_da);
2803 #endif /* OLD_BINARY_SUPPORT */
2806 * sysfs files: for each device
2810 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
2813 return sprintf(buf, "%s\n", to_taskdev(d)->name);
2817 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
2820 return sprintf(buf, "%s\n", devstate_name(to_taskdev(d)->state));
2824 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
2827 struct taskdev *dev;
2828 struct proc_list *pl;
2831 dev = to_taskdev(d);
2832 spin_lock(&dev->proc_list_lock);
2833 list_for_each_entry(pl, &dev->proc_list, list_head) {
2834 /* need to lock tasklist_lock before calling
2835 * find_task_by_pid_type. */
2836 if (find_task_by_pid_type(PIDTYPE_PID, pl->pid) != NULL)
2837 len += sprintf(buf + len, "%d\n", pl->pid);
2838 read_unlock(&tasklist_lock);
2840 spin_unlock(&dev->proc_list_lock);
2846 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
2849 struct taskdev *dev = to_taskdev(d);
2852 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
2855 len = sprintf(buf, "%s\n", dev->task->name);
2857 devstate_read_unlock(dev);
2862 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
2865 struct taskdev *dev = to_taskdev(d);
2869 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
2872 ttyp = dev->task->ttyp;
2873 len += sprintf(buf + len, "0x%04x\n", ttyp);
2874 len += sprintf(buf + len, "%s %s send\n",
2875 (sndtyp_acv(ttyp)) ? "active" :
2877 (sndtyp_wd(ttyp)) ? "word" :
2878 (sndtyp_pvt(ttyp)) ? "private block" :
2880 len += sprintf(buf + len, "%s %s receive\n",
2881 (rcvtyp_acv(ttyp)) ? "active" :
2883 (rcvtyp_wd(ttyp)) ? "word" :
2884 (rcvtyp_pvt(ttyp)) ? "private block" :
2887 devstate_read_unlock(dev);
2892 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
2895 struct kfifo *fifo = to_taskdev(d)->rcvdt.fifo;
2896 return sprintf(buf, "%d\n", fifo->size);
2899 static int fifosz_store(struct device *d, struct device_attribute *attr,
2900 const char *buf, size_t count)
2902 struct taskdev *dev = to_taskdev(d);
2903 unsigned long fifosz;
2906 fifosz = simple_strtol(buf, NULL, 10);
2907 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
2909 ret = taskdev_set_fifosz(dev, fifosz);
2910 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
2912 return (ret < 0) ? ret : strlen(buf);
2916 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
2919 struct kfifo *fifo = to_taskdev(d)->rcvdt.fifo;
2920 return sprintf(buf, "%d\n", fifo->size);
2924 static inline char *bid_name(u16 bid)
2934 sprintf(s, "%d", bid);
2939 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
2942 struct rcvdt_bk_struct *rcvdt = &to_taskdev(d)->rcvdt.bk;
2945 spin_lock(&rcvdt->link.lock);
2946 len = sprintf(buf, "top %s\ntail %s\n",
2947 bid_name(rcvdt->link.top), bid_name(rcvdt->link.tail));
2948 spin_unlock(&rcvdt->link.lock);
2954 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
2957 return sprintf(buf, "%d\n", to_taskdev(d)->wsz);
2961 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
2964 struct dsptask *task = to_taskdev(d)->task;
2965 return sprintf(buf, "0x%p 0x%x\n", task->map_base, task->map_length);
2969 * called from ipbuf_show()
2971 int ipbuf_is_held(u8 tid, u16 bid)
2973 struct dsptask *task = dsptask[tid];
2974 struct ipblink *link;
2981 link = &task->dev->rcvdt.bk.link;
2982 spin_lock(&link->lock);
2983 ipblink_for_each(b, link) {
2984 if (b == bid) { /* found */
2989 spin_unlock(&link->lock);
2994 int __init dsp_taskmod_init(void)
2998 memset(taskdev, 0, sizeof(void *) * TASKDEV_MAX);
2999 memset(dsptask, 0, sizeof(void *) * TASKDEV_MAX);
3001 retval = register_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask",
3005 "omapdsp: failed to register task device: %d\n", retval);
3009 retval = bus_register(&dsptask_bus);
3012 "omapdsp: failed to register DSP task bus: %d\n",
3014 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3017 retval = driver_register(&dsptask_driver);
3020 "omapdsp: failed to register DSP task driver: %d\n",
3022 bus_unregister(&dsptask_bus);
3023 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3026 dsp_task_class = class_create(THIS_MODULE, "dsptask");
3027 if (IS_ERR(dsp_task_class)) {
3028 printk(KERN_ERR "omapdsp: failed to create DSP task class\n");
3029 driver_unregister(&dsptask_driver);
3030 bus_unregister(&dsptask_bus);
3031 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3038 void dsp_taskmod_exit(void)
3040 class_destroy(dsp_task_class);
3041 driver_unregister(&dsptask_driver);
3042 bus_unregister(&dsptask_bus);
3043 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");