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 <asm/uaccess.h>
38 #include <asm/arch/mailbox.h>
39 #include <asm/arch/dsp.h>
40 #include "uaccess_dsp.h"
41 #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;
129 struct fifo_struct fifo; /* for active word */
130 struct rcvdt_bk_struct bk;
134 wait_queue_head_t write_wait_q;
135 struct mutex write_mutex;
140 wait_queue_head_t tctl_wait_q;
141 struct mutex tctl_mutex;
143 int tctl_ret; /* return value for tctl_show() */
150 #define to_taskdev(n) container_of(n, struct taskdev, dev)
164 struct ipbuf_p *ipbuf_pvt_r;
167 struct ipbuf_p *ipbuf_pvt_w;
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))
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);
194 static struct bus_type dsptask_bus = {
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);
205 static DECLARE_WAIT_QUEUE_HEAD(cfg_wait_q);
206 static u8 n_task; /* static task count */
209 #define is_dynamic_task(tid) ((tid) >= n_task)
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)
218 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
220 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
222 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
224 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
226 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
228 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
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,
234 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
236 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
238 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
241 #define __ATTR_RW(_name,_mode) { \
242 .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
243 .show = _name##_show, \
244 .store = _name##_store, \
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);
258 static inline void set_taskdev_state(struct taskdev *dev, int state)
260 pr_debug("omapdsp: devstate: CHANGE %s[%d]:\"%s\"->\"%s\"\n",
262 (dev->task ? dev->task->tid : -1),
263 devstate_name(dev->state),
264 devstate_name(state));
269 * devstate_read_lock_timeout()
270 * devstate_write_lock_timeout():
271 * timeout != 0: dev->state can be diffeent from what you want.
272 * timeout == 0: no timeout
274 #define BUILD_DEVSTATE_LOCK_TIMEOUT(rw) \
275 static int devstate_##rw##_lock_timeout(struct taskdev *dev, long devstate, \
279 down_##rw(&dev->state_sem); \
280 while (!(dev->state & devstate)) { \
281 up_##rw(&dev->state_sem); \
282 prepare_to_wait(&dev->state_wait_q, &wait, TASK_INTERRUPTIBLE); \
284 timeout = MAX_SCHEDULE_TIMEOUT; \
285 timeout = schedule_timeout(timeout); \
286 finish_wait(&dev->state_wait_q, &wait); \
289 if (signal_pending(current)) \
291 down_##rw(&dev->state_sem); \
295 BUILD_DEVSTATE_LOCK_TIMEOUT(read)
296 BUILD_DEVSTATE_LOCK_TIMEOUT(write)
298 #define BUILD_DEVSTATE_LOCK_AND_TEST(rw) \
299 static int devstate_##rw##_lock_and_test(struct taskdev *dev, long devstate) \
301 down_##rw(&dev->state_sem); \
302 if (dev->state & devstate) \
303 return 1; /* success */ \
305 up_##rw(&dev->state_sem); \
308 BUILD_DEVSTATE_LOCK_AND_TEST(read)
309 BUILD_DEVSTATE_LOCK_AND_TEST(write)
311 static int taskdev_lock_interruptible(struct taskdev *dev,
316 if (has_taskdev_lock(dev))
317 ret = mutex_lock_interruptible(lock);
319 if ((ret = mutex_lock_interruptible(&dev->lock)) != 0)
321 ret = mutex_lock_interruptible(lock);
322 mutex_unlock(&dev->lock);
328 static int taskdev_lock_and_statelock_attached(struct taskdev *dev,
333 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
336 if ((ret = taskdev_lock_interruptible(dev, lock)) != 0)
337 devstate_read_unlock(dev);
342 static inline void taskdev_unlock_and_stateunlock(struct taskdev *dev,
346 devstate_read_unlock(dev);
350 * taskdev_flush_buf()
351 * must be called under state_lock(ATTACHED) and dev->read_mutex.
353 static int taskdev_flush_buf(struct taskdev *dev)
355 u16 ttyp = dev->task->ttyp;
357 if (sndtyp_wd(ttyp)) {
359 flush_fifo(&dev->rcvdt.fifo);
361 /* block receiving */
362 struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
364 if (sndtyp_gbl(ttyp))
365 ipblink_flush(&rcvdt->link);
367 ipblink_flush_pvt(&rcvdt->link);
368 release_ipbuf_pvt(dev->task->ipbuf_pvt_r);
376 * taskdev_set_fifosz()
377 * must be called under dev->read_mutex.
379 static int taskdev_set_fifosz(struct taskdev *dev, unsigned long sz)
381 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 stat = realloc_fifo(&dev->rcvdt.fifo, sz);
397 if (stat == -EBUSY) {
398 printk(KERN_ERR "omapdsp: buffer is not empty!\n");
400 } else if (stat < 0) {
402 "omapdsp: unable to change receive buffer size. "
403 "(%ld bytes for %s)\n", sz, dev->name);
410 static inline int has_taskdev_lock(struct taskdev *dev)
412 return (dev->lock_pid == current->pid);
415 static int taskdev_lock(struct taskdev *dev)
417 if (mutex_lock_interruptible(&dev->lock))
419 dev->lock_pid = current->pid;
423 static int taskdev_unlock(struct taskdev *dev)
425 if (!has_taskdev_lock(dev)) {
427 "omapdsp: an illegal process attempted to "
428 "unlock the dsptask lock!\n");
432 mutex_unlock(&dev->lock);
436 static int dsp_task_config(struct dsptask *task, u8 tid)
445 task->state = TASK_ST_CFGREQ;
446 if (mutex_lock_interruptible(&cfg_lock)) {
450 cfg_cmd = MBOX_CMD_DSP_TCFG;
451 mbcompose_send_and_wait(TCFG, tid, 0, &cfg_wait_q);
453 mutex_unlock(&cfg_lock);
455 if (task->state != TASK_ST_READY) {
456 printk(KERN_ERR "omapdsp: task %d configuration error!\n", tid);
461 if (strlen(task->name) <= 1)
462 sprintf(task->name, "%d", tid);
463 pr_info("omapdsp: task %d: name %s\n", tid, task->name);
468 * task info sanity check
471 /* task type check */
472 if (rcvtyp_psv(ttyp) && rcvtyp_pvt(ttyp)) {
473 printk(KERN_ERR "omapdsp: illegal task type(0x%04x), tid=%d\n",
479 /* private buffer address check */
480 if (sndtyp_pvt(ttyp) &&
481 (ipbuf_p_validate(task->ipbuf_pvt_r, DIR_D2A) < 0)) {
485 if (rcvtyp_pvt(ttyp) &&
486 (ipbuf_p_validate(task->ipbuf_pvt_w, DIR_A2D) < 0)) {
491 /* mmap buffer configuration check */
492 if ((task->map_length > 0) &&
493 ((!is_aligned((unsigned long)task->map_base, PAGE_SIZE)) ||
494 (!is_aligned(task->map_length, PAGE_SIZE)) ||
495 (dsp_mem_type(task->map_base, task->map_length) != MEM_TYPE_EXTERN))) {
497 "omapdsp: illegal mmap buffer address(0x%p) or "
499 " It needs to be page-aligned and located at "
500 "external memory.\n",
501 task->map_base, task->map_length);
513 static void dsp_task_init(struct dsptask *task)
515 mbcompose_send(TCTL, task->tid, TCTL_TINIT);
518 int dsp_task_config_all(u8 n)
521 struct taskdev *devheap;
522 struct dsptask *taskheap;
523 size_t devheapsz, taskheapsz;
525 pr_info("omapdsp: found %d task(s)\n", n);
532 devheapsz = sizeof(struct taskdev) * n;
533 taskheapsz = sizeof(struct dsptask) * n;
534 heap = kzalloc(devheapsz + taskheapsz, GFP_KERNEL);
538 taskheap = heap + devheapsz;
541 for (i = 0; i < n; i++) {
542 struct taskdev *dev = &devheap[i];
543 struct dsptask *task = &taskheap[i];
545 if ((ret = dsp_task_config(task, i)) < 0)
547 if ((ret = taskdev_init(dev, task->name, i)) < 0)
549 if ((ret = taskdev_attach_task(dev, task)) < 0)
552 pr_info("omapdsp: taskdev %s enabled.\n", dev->name);
558 static void dsp_task_unconfig(struct dsptask *task)
560 dsptask[task->tid] = NULL;
563 void dsp_task_unconfig_all(void)
567 struct dsptask *task;
569 for (minor = 0; minor < n_task; minor++) {
571 * taskdev[minor] can be NULL in case of
572 * configuration failure
575 taskdev_delete(minor);
577 for (; minor < TASKDEV_MAX; minor++) {
579 dsp_rmdev_minor(minor);
582 for (tid = 0; tid < n_task; tid++) {
584 * dsptask[tid] can be NULL in case of
585 * configuration failure
589 dsp_task_unconfig(task);
591 for (; tid < TASKDEV_MAX; tid++) {
595 * on-demand tasks should be deleted in
596 * rmdev_minor(), but just in case.
598 dsp_task_unconfig(task);
611 static struct device_driver dsptask_driver = {
616 u8 dsp_task_count(void)
621 int dsp_taskmod_busy(void)
625 unsigned int usecount;
627 for (minor = 0; minor < TASKDEV_MAX; minor++) {
628 dev = taskdev[minor];
631 if ((usecount = dev->usecount) > 0) {
632 printk("dsp_taskmod_busy(): %s: usecount=%d\n",
633 dev->name, usecount);
637 if ((dev->state & (TASKDEV_ST_ADDREQ |
638 TASKDEV_ST_DELREQ)) {
640 if (dev->state & TASKDEV_ST_ADDREQ) {
641 printk("dsp_taskmod_busy(): %s is in %s\n",
642 dev->name, devstate_name(dev->state));
650 * DSP task device file operations
652 static ssize_t dsp_task_read_wd_acv(struct file *file, char __user *buf,
653 size_t count, loff_t *ppos)
655 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
656 struct taskdev *dev = taskdev[minor];
662 } else if (count & 0x1) {
664 "omapdsp: odd count is illegal for DSP task device.\n");
668 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
672 prepare_to_wait(&dev->read_wait_q, &wait, TASK_INTERRUPTIBLE);
673 if (fifo_empty(&dev->rcvdt.fifo))
675 finish_wait(&dev->read_wait_q, &wait);
676 if (fifo_empty(&dev->rcvdt.fifo)) {
678 if (signal_pending(current))
684 ret = copy_to_user_fm_fifo(buf, &dev->rcvdt.fifo, count);
687 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
691 static ssize_t dsp_task_read_bk_acv(struct file *file, char __user *buf,
692 size_t count, loff_t *ppos)
694 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
695 struct taskdev *dev = taskdev[minor];
696 struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
702 } else if (count & 0x1) {
704 "omapdsp: odd count is illegal for DSP task device.\n");
706 } else if ((int)buf & 0x1) {
708 "omapdsp: buf should be word aligned for "
709 "dsp_task_read().\n");
713 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
716 prepare_to_wait(&dev->read_wait_q, &wait, TASK_INTERRUPTIBLE);
717 if (ipblink_empty(&rcvdt->link))
719 finish_wait(&dev->read_wait_q, &wait);
720 if (ipblink_empty(&rcvdt->link)) {
722 if (signal_pending(current))
727 /* copy from delayed IPBUF */
728 if (sndtyp_pvt(dev->task->ttyp)) {
730 if (!ipblink_empty(&rcvdt->link)) {
731 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_r;
732 unsigned char *base, *src;
735 if (dsp_mem_enable(ipbp) < 0) {
739 base = MKVIRT(ipbp->ah, ipbp->al);
740 bkcnt = ((unsigned long)ipbp->c) * 2 - rcvdt->rp;
741 if (dsp_address_validate(base, bkcnt,
742 "task %s read buffer",
743 dev->task->name) < 0) {
747 if (dsp_mem_enable(base) < 0) {
751 src = base + rcvdt->rp;
753 if (copy_to_user_dsp(buf, src, count)) {
760 if (copy_to_user_dsp(buf, src, bkcnt)) {
765 ipblink_del_pvt(&rcvdt->link);
766 release_ipbuf_pvt(ipbp);
770 dsp_mem_disable(src);
772 dsp_mem_disable(ipbp);
776 if (dsp_mem_enable_ipbuf() < 0) {
780 while (!ipblink_empty(&rcvdt->link)) {
783 struct ipbuf_head *ipb_h = bid_to_ipbuf(rcvdt->link.top);
785 src = ipb_h->p->d + rcvdt->rp;
786 bkcnt = ((unsigned long)ipb_h->p->c) * 2 - rcvdt->rp;
788 if (copy_to_user_dsp(buf, src, count)) {
796 if (copy_to_user_dsp(buf, src, bkcnt)) {
803 ipblink_del_top(&rcvdt->link);
809 dsp_mem_disable_ipbuf();
813 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
817 static ssize_t dsp_task_read_wd_psv(struct file *file, char __user *buf,
818 size_t count, loff_t *ppos)
820 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
821 struct taskdev *dev = taskdev[minor];
826 } else if (count & 0x1) {
828 "omapdsp: odd count is illegal for DSP task device.\n");
835 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
838 mbcompose_send_and_wait(WDREQ, dev->task->tid, 0, &dev->read_wait_q);
840 if (fifo_empty(&dev->rcvdt.fifo)) {
842 if (signal_pending(current))
847 ret = copy_to_user_fm_fifo(buf, &dev->rcvdt.fifo, count);
850 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
854 static ssize_t dsp_task_read_bk_psv(struct file *file, char __user *buf,
855 size_t count, loff_t *ppos)
857 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
858 struct taskdev *dev = taskdev[minor];
859 struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
864 } else if (count & 0x1) {
866 "omapdsp: odd count is illegal for DSP task device.\n");
868 } else if ((int)buf & 0x1) {
870 "omapdsp: buf should be word aligned for "
871 "dsp_task_read().\n");
875 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
878 mbcompose_send_and_wait(BKREQ, dev->task->tid, count/2,
881 if (ipblink_empty(&rcvdt->link)) {
883 if (signal_pending(current))
889 * We will not receive more than requested count.
891 if (sndtyp_pvt(dev->task->ttyp)) {
893 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_r;
897 if (dsp_mem_enable(ipbp) < 0) {
901 src = MKVIRT(ipbp->ah, ipbp->al);
902 rcvcnt = ((unsigned long)ipbp->c) * 2;
903 if (dsp_address_validate(src, rcvcnt, "task %s read buffer",
904 dev->task->name) < 0) {
908 if (dsp_mem_enable(src) < 0) {
914 if (copy_to_user_dsp(buf, src, count)) {
918 ipblink_del_pvt(&rcvdt->link);
919 release_ipbuf_pvt(ipbp);
922 dsp_mem_disable(src);
924 dsp_mem_disable(ipbp);
927 struct ipbuf_head *ipb_h = bid_to_ipbuf(rcvdt->link.top);
930 if (dsp_mem_enable_ipbuf() < 0) {
934 rcvcnt = ((unsigned long)ipb_h->p->c) * 2;
937 if (copy_to_user_dsp(buf, ipb_h->p->d, count)) {
941 ipblink_del_top(&rcvdt->link);
945 dsp_mem_disable_ipbuf();
949 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
953 static ssize_t dsp_task_write_wd(struct file *file, const char __user *buf,
954 size_t count, loff_t *ppos)
956 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
957 struct taskdev *dev = taskdev[minor];
964 } else if (count & 0x1) {
966 "omapdsp: odd count is illegal for DSP task device.\n");
973 if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex))
976 prepare_to_wait(&dev->write_wait_q, &wait, TASK_INTERRUPTIBLE);
979 finish_wait(&dev->write_wait_q, &wait);
982 if (signal_pending(current))
987 if (copy_from_user(&wd, buf, count)) {
992 spin_lock(&dev->wsz_lock);
993 if (mbcompose_send(WDSND, dev->task->tid, wd) < 0) {
994 spin_unlock(&dev->wsz_lock);
998 if (rcvtyp_acv(dev->task->ttyp))
1000 spin_unlock(&dev->wsz_lock);
1003 taskdev_unlock_and_stateunlock(dev, &dev->write_mutex);
1007 static ssize_t dsp_task_write_bk(struct file *file, const char __user *buf,
1008 size_t count, loff_t *ppos)
1010 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1011 struct taskdev *dev = taskdev[minor];
1017 } else if (count & 0x1) {
1019 "omapdsp: odd count is illegal for DSP task device.\n");
1021 } else if ((int)buf & 0x1) {
1023 "omapdsp: buf should be word aligned for "
1024 "dsp_task_write().\n");
1028 if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex))
1031 prepare_to_wait(&dev->write_wait_q, &wait, TASK_INTERRUPTIBLE);
1034 finish_wait(&dev->write_wait_q, &wait);
1035 if (dev->wsz == 0) {
1037 if (signal_pending(current))
1042 if (count > dev->wsz)
1045 if (rcvtyp_pvt(dev->task->ttyp)) {
1047 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_w;
1050 if (dsp_mem_enable(ipbp) < 0) {
1054 dst = MKVIRT(ipbp->ah, ipbp->al);
1055 if (dsp_address_validate(dst, count, "task %s write buffer",
1056 dev->task->name) < 0) {
1060 if (dsp_mem_enable(dst) < 0) {
1064 if (copy_from_user_dsp(dst, buf, count)) {
1069 ipbp->s = dev->task->tid;
1070 spin_lock(&dev->wsz_lock);
1071 if (mbcompose_send(BKSNDP, dev->task->tid, 0) == 0) {
1072 if (rcvtyp_acv(dev->task->ttyp))
1076 spin_unlock(&dev->wsz_lock);
1078 dsp_mem_disable(dst);
1080 dsp_mem_disable(ipbp);
1083 struct ipbuf_head *ipb_h;
1085 if (dsp_mem_enable_ipbuf() < 0) {
1089 if ((ipb_h = get_free_ipbuf(dev->task->tid)) == NULL)
1091 if (copy_from_user_dsp(ipb_h->p->d, buf, count)) {
1092 release_ipbuf(ipb_h);
1096 ipb_h->p->c = count/2;
1097 ipb_h->p->sa = dev->task->tid;
1098 spin_lock(&dev->wsz_lock);
1099 if (mbcompose_send(BKSND, dev->task->tid, ipb_h->bid) == 0) {
1100 if (rcvtyp_acv(dev->task->ttyp))
1103 ipb_bsycnt_inc(&ipbcfg);
1105 release_ipbuf(ipb_h);
1106 spin_unlock(&dev->wsz_lock);
1108 dsp_mem_disable_ipbuf();
1112 taskdev_unlock_and_stateunlock(dev, &dev->write_mutex);
1116 static unsigned int dsp_task_poll(struct file * file, poll_table * wait)
1118 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1119 struct taskdev *dev = taskdev[minor];
1120 struct dsptask *task = dev->task;
1121 unsigned int mask = 0;
1123 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
1125 poll_wait(file, &dev->read_wait_q, wait);
1126 poll_wait(file, &dev->write_wait_q, wait);
1127 if (sndtyp_psv(task->ttyp) ||
1128 (sndtyp_wd(task->ttyp) && !fifo_empty(&dev->rcvdt.fifo)) ||
1129 (sndtyp_bk(task->ttyp) && !ipblink_empty(&dev->rcvdt.bk.link)))
1130 mask |= POLLIN | POLLRDNORM;
1132 mask |= POLLOUT | POLLWRNORM;
1133 devstate_read_unlock(dev);
1138 static int dsp_tctl_issue(struct taskdev *dev, u16 cmd, int argc, u16 argv[])
1141 struct mb_exarg mbarg, *mbargp;
1149 * system reserved TCTL commands
1163 * user-defined TCTL commands
1165 else if (cmd < 0x8100) {
1166 /* 0x8000-0x80ff: no arg, non-interactive */
1169 } else if (cmd < 0x8200) {
1170 /* 0x8100-0x81ff: 1 arg, non-interactive */
1173 } else if (cmd < 0x9000) {
1174 /* 0x8200-0x8fff: reserved */
1176 } else if (cmd < 0x9100) {
1177 /* 0x9000-0x90ff: no arg, interactive */
1180 } else if (cmd < 0x9200) {
1181 /* 0x9100-0x91ff: 1 arg, interactive */
1185 /* 0x9200-0xffff: reserved */
1190 * if argc < 0, use tctl_argc as is.
1191 * if argc >= 0, check arg count.
1193 if ((argc >= 0) && (argc != tctl_argc))
1199 if (taskdev_lock_interruptible(dev, &dev->tctl_mutex))
1202 tid = dev->task->tid;
1203 if (tctl_argc > 0) {
1204 mbarg.argc = tctl_argc;
1212 dev->tctl_stat = -EINVAL;
1214 mbcompose_send_and_wait_exarg(TCTL, tid, cmd, mbargp,
1216 if (signal_pending(current)) {
1220 if ((ret = dev->tctl_stat) < 0) {
1221 printk(KERN_ERR "omapdsp: TCTL not responding.\n");
1225 mbcompose_send_exarg(TCTL, tid, cmd, mbargp);
1228 mutex_unlock(&dev->tctl_mutex);
1232 static int dsp_task_ioctl(struct inode *inode, struct file *file,
1233 unsigned int cmd, unsigned long arg)
1235 unsigned int minor = MINOR(inode->i_rdev);
1236 struct taskdev *dev = taskdev[minor];
1239 if (cmd < 0x10000) {
1243 mbargv[0] = arg & 0xffff;
1244 return dsp_tctl_issue(dev, cmd, -1, mbargv);
1247 /* non TCTL ioctls */
1250 case TASK_IOCTL_LOCK:
1251 ret = taskdev_lock(dev);
1254 case TASK_IOCTL_UNLOCK:
1255 ret = taskdev_unlock(dev);
1258 case TASK_IOCTL_BFLSH:
1259 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
1261 ret = taskdev_flush_buf(dev);
1262 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
1265 case TASK_IOCTL_SETBSZ:
1266 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
1268 ret = taskdev_set_fifosz(dev, arg);
1269 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
1272 case TASK_IOCTL_GETNAME:
1274 if (copy_to_user((void __user *)arg, dev->name,
1275 strlen(dev->name) + 1))
1287 static void dsp_task_mmap_open(struct vm_area_struct *vma)
1289 struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1290 struct dsptask *task;
1291 size_t len = vma->vm_end - vma->vm_start;
1293 BUG_ON(!(dev->state & TASKDEV_ST_ATTACHED));
1295 omap_mmu_exmap_use(&dsp_mmu, task->map_base, len);
1298 static void dsp_task_mmap_close(struct vm_area_struct *vma)
1300 struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1301 struct dsptask *task;
1302 size_t len = vma->vm_end - vma->vm_start;
1304 BUG_ON(!(dev->state & TASKDEV_ST_ATTACHED));
1306 omap_mmu_exmap_unuse(&dsp_mmu, task->map_base, len);
1310 * On demand page allocation is not allowed. The mapping area is defined by
1311 * corresponding DSP tasks.
1313 static struct page *dsp_task_mmap_nopage(struct vm_area_struct *vma,
1314 unsigned long address, int *type)
1316 return NOPAGE_SIGBUS;
1319 static struct vm_operations_struct dsp_task_vm_ops = {
1320 .open = dsp_task_mmap_open,
1321 .close = dsp_task_mmap_close,
1322 .nopage = dsp_task_mmap_nopage,
1325 static int dsp_task_mmap(struct file *filp, struct vm_area_struct *vma)
1328 unsigned long tmp_padr, tmp_vmadr, off;
1329 size_t req_len, tmp_len;
1330 unsigned int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
1331 struct taskdev *dev = taskdev[minor];
1332 struct dsptask *task;
1335 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
1340 * Don't swap this area out
1341 * Don't dump this area to a core file
1343 vma->vm_flags |= VM_RESERVED | VM_IO;
1345 /* Do not cache this area */
1346 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1348 req_len = vma->vm_end - vma->vm_start;
1349 off = vma->vm_pgoff << PAGE_SHIFT;
1350 tmp_vmadr = vma->vm_start;
1351 tmp_vadr = task->map_base + off;
1353 tmp_padr = omap_mmu_virt_to_phys(&dsp_mmu, tmp_vadr, &tmp_len);
1354 if (tmp_padr == 0) {
1356 "omapdsp: task %s: illegal address "
1357 "for mmap: %p", task->name, tmp_vadr);
1358 /* partial mapping will be cleared in upper layer */
1362 if (tmp_len > req_len)
1365 pr_debug("omapdsp: mmap info: "
1366 "vmadr = %08lx, padr = %08lx, len = %x\n",
1367 tmp_vmadr, tmp_padr, tmp_len);
1368 if (remap_pfn_range(vma, tmp_vmadr, tmp_padr >> PAGE_SHIFT,
1369 tmp_len, vma->vm_page_prot) != 0) {
1371 "omapdsp: task %s: remap_page_range() failed.\n",
1373 /* partial mapping will be cleared in upper layer */
1379 tmp_vmadr += tmp_len;
1380 tmp_vadr += tmp_len;
1383 vma->vm_ops = &dsp_task_vm_ops;
1384 vma->vm_private_data = dev;
1385 omap_mmu_exmap_use(&dsp_mmu, task->map_base, vma->vm_end - vma->vm_start);
1388 devstate_read_unlock(dev);
1392 static int dsp_task_open(struct inode *inode, struct file *file)
1394 unsigned int minor = MINOR(inode->i_rdev);
1395 struct taskdev *dev;
1398 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL))
1402 mutex_lock(&dev->usecount_lock);
1403 down_write(&dev->state_sem);
1405 /* state can be NOTASK, ATTACHED/FREEZED, KILLING, GARBAGE or INVALID here. */
1406 switch (dev->state & TASKDEV_ST_STATE_MASK) {
1407 case TASKDEV_ST_NOTASK:
1409 case TASKDEV_ST_ATTACHED:
1412 case TASKDEV_ST_INVALID:
1413 up_write(&dev->state_sem);
1414 mutex_unlock(&dev->usecount_lock);
1417 case TASKDEV_ST_FREEZED:
1418 case TASKDEV_ST_KILLING:
1419 case TASKDEV_ST_GARBAGE:
1420 case TASKDEV_ST_DELREQ:
1421 /* on the kill process. wait until it becomes NOTASK. */
1422 up_write(&dev->state_sem);
1423 mutex_unlock(&dev->usecount_lock);
1424 if (devstate_write_lock(dev, TASKDEV_ST_NOTASK) < 0)
1426 devstate_write_unlock(dev);
1431 set_taskdev_state(dev, TASKDEV_ST_ADDREQ);
1432 /* wake up twch daemon for tadd */
1434 up_write(&dev->state_sem);
1435 if (devstate_write_lock(dev, TASKDEV_ST_ATTACHED |
1436 TASKDEV_ST_ADDFAIL) < 0) {
1438 if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) {
1439 mutex_unlock(&dev->usecount_lock);
1440 /* out of control ??? */
1443 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1447 if (dev->state & TASKDEV_ST_ADDFAIL) {
1448 printk(KERN_ERR "omapdsp: task attach failed for %s!\n",
1451 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1456 ret = proc_list_add(&dev->proc_list_lock,
1457 &dev->proc_list, current, file);
1462 file->f_op = &dev->fops;
1463 up_write(&dev->state_sem);
1464 mutex_unlock(&dev->usecount_lock);
1466 #ifdef DSP_PTE_FREE /* not used currently. */
1467 dsp_map_update(current);
1468 dsp_cur_users_add(current);
1469 #endif /* DSP_PTE_FREE */
1473 wake_up_interruptible_all(&dev->state_wait_q);
1475 up_write(&dev->state_sem);
1476 mutex_unlock(&dev->usecount_lock);
1480 static int dsp_task_release(struct inode *inode, struct file *file)
1482 unsigned int minor = MINOR(inode->i_rdev);
1483 struct taskdev *dev = taskdev[minor];
1485 #ifdef DSP_PTE_FREE /* not used currently. */
1486 dsp_cur_users_del(current);
1487 #endif /* DSP_PTE_FREE */
1489 if (has_taskdev_lock(dev))
1490 taskdev_unlock(dev);
1492 proc_list_del(&dev->proc_list_lock, &dev->proc_list, current, file);
1493 mutex_lock(&dev->usecount_lock);
1494 if (--dev->usecount > 0) {
1495 /* other processes are using this device. no state change. */
1496 mutex_unlock(&dev->usecount_lock);
1501 down_write(&dev->state_sem);
1503 /* state can be ATTACHED/FREEZED, KILLING or GARBAGE here. */
1504 switch (dev->state & TASKDEV_ST_STATE_MASK) {
1506 case TASKDEV_ST_KILLING:
1509 case TASKDEV_ST_GARBAGE:
1510 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1511 wake_up_interruptible_all(&dev->state_wait_q);
1514 case TASKDEV_ST_ATTACHED:
1515 case TASKDEV_ST_FREEZED:
1516 if (is_dynamic_task(minor)) {
1517 set_taskdev_state(dev, TASKDEV_ST_DELREQ);
1518 /* wake up twch daemon for tdel */
1525 up_write(&dev->state_sem);
1526 mutex_unlock(&dev->usecount_lock);
1533 int dsp_mkdev(char *name)
1535 struct taskdev *dev;
1537 unsigned char minor;
1540 if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
1541 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1545 if (mutex_lock_interruptible(&devmgr_lock))
1549 for (minor = 0; minor < TASKDEV_MAX; minor++) {
1550 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1552 "omapdsp: task device name %s is already "
1559 /* find free minor number */
1560 for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1561 if (taskdev[minor] == NULL)
1564 printk(KERN_ERR "omapdsp: Too many task devices.\n");
1569 if ((dev = kzalloc(sizeof(struct taskdev), GFP_KERNEL)) == NULL) {
1573 if ((status = taskdev_init(dev, name, minor)) < 0) {
1581 mutex_unlock(&devmgr_lock);
1585 int dsp_rmdev(char *name)
1587 unsigned char minor;
1591 if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
1592 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1596 if (mutex_lock_interruptible(&devmgr_lock))
1599 /* find in dynamic devices */
1600 for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1601 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name))
1605 /* find in static devices */
1606 for (minor = 0; minor < n_task; minor++) {
1607 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1609 "omapdsp: task device %s is static.\n", name);
1615 printk(KERN_ERR "omapdsp: task device %s not found.\n", name);
1620 if ((status = dsp_rmdev_minor(minor)) < 0)
1623 mutex_unlock(&devmgr_lock);
1627 static int dsp_rmdev_minor(unsigned char minor)
1629 struct taskdev *dev = taskdev[minor];
1631 while (!down_write_trylock(&dev->state_sem)) {
1632 down_read(&dev->state_sem);
1633 if (dev->state & (TASKDEV_ST_ATTACHED |
1634 TASKDEV_ST_FREEZED)) {
1636 * task is working. kill it.
1637 * ATTACHED -> FREEZED can be changed under
1638 * down_read of state_sem..
1640 set_taskdev_state(dev, TASKDEV_ST_FREEZED);
1641 wake_up_interruptible_all(&dev->read_wait_q);
1642 wake_up_interruptible_all(&dev->write_wait_q);
1643 wake_up_interruptible_all(&dev->tctl_wait_q);
1645 up_read(&dev->state_sem);
1649 switch (dev->state & TASKDEV_ST_STATE_MASK) {
1651 case TASKDEV_ST_NOTASK:
1652 case TASKDEV_ST_INVALID:
1656 case TASKDEV_ST_ATTACHED:
1657 case TASKDEV_ST_FREEZED:
1658 /* task is working. kill it. */
1659 set_taskdev_state(dev, TASKDEV_ST_KILLING);
1660 up_write(&dev->state_sem);
1661 dsp_tdel_bh(dev, TDEL_KILL);
1664 case TASKDEV_ST_ADDREQ:
1665 /* open() is waiting. drain it. */
1666 set_taskdev_state(dev, TASKDEV_ST_ADDFAIL);
1667 wake_up_interruptible_all(&dev->state_wait_q);
1670 case TASKDEV_ST_DELREQ:
1671 /* nobody is waiting. */
1672 set_taskdev_state(dev, TASKDEV_ST_NOTASK);
1673 wake_up_interruptible_all(&dev->state_wait_q);
1676 case TASKDEV_ST_ADDING:
1677 case TASKDEV_ST_DELING:
1678 case TASKDEV_ST_KILLING:
1679 case TASKDEV_ST_GARBAGE:
1680 case TASKDEV_ST_ADDFAIL:
1681 /* transient state. wait for a moment. */
1686 up_write(&dev->state_sem);
1689 /* wait for some time and hope the state is settled */
1690 devstate_read_lock_timeout(dev, TASKDEV_ST_NOTASK, 5 * HZ);
1691 if (!(dev->state & TASKDEV_ST_NOTASK)) {
1693 "omapdsp: illegal device state (%s) on rmdev %s.\n",
1694 devstate_name(dev->state), dev->name);
1697 set_taskdev_state(dev, TASKDEV_ST_INVALID);
1698 devstate_read_unlock(dev);
1700 taskdev_delete(minor);
1706 static struct file_operations dsp_task_fops = {
1707 .owner = THIS_MODULE,
1708 .poll = dsp_task_poll,
1709 .ioctl = dsp_task_ioctl,
1710 .open = dsp_task_open,
1711 .release = dsp_task_release,
1714 static void dsptask_dev_release(struct device *dev)
1718 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor)
1721 struct device *task_dev;
1723 taskdev[minor] = dev;
1725 spin_lock_init(&dev->proc_list_lock);
1726 INIT_LIST_HEAD(&dev->proc_list);
1727 init_waitqueue_head(&dev->read_wait_q);
1728 init_waitqueue_head(&dev->write_wait_q);
1729 init_waitqueue_head(&dev->tctl_wait_q);
1730 mutex_init(&dev->read_mutex);
1731 mutex_init(&dev->write_mutex);
1732 mutex_init(&dev->tctl_mutex);
1733 mutex_init(&dev->lock);
1734 spin_lock_init(&dev->wsz_lock);
1735 dev->tctl_ret = -EINVAL;
1738 strncpy(dev->name, name, TNM_LEN);
1739 dev->name[TNM_LEN-1] = '\0';
1740 set_taskdev_state(dev, (minor < n_task) ? TASKDEV_ST_ATTACHED : TASKDEV_ST_NOTASK);
1742 mutex_init(&dev->usecount_lock);
1743 memcpy(&dev->fops, &dsp_task_fops, sizeof(struct file_operations));
1745 dev->dev.parent = omap_dsp->dev;
1746 dev->dev.bus = &dsptask_bus;
1747 sprintf(dev->dev.bus_id, "dsptask%d", minor);
1748 dev->dev.release = dsptask_dev_release;
1749 ret = device_register(&dev->dev);
1751 printk(KERN_ERR "device_register failed: %d\n", ret);
1754 ret = device_create_file(&dev->dev, &dev_attr_devname);
1756 goto fail_create_devname;
1757 ret = device_create_file(&dev->dev, &dev_attr_devstate);
1759 goto fail_create_devstate;
1760 ret = device_create_file(&dev->dev, &dev_attr_proc_list);
1762 goto fail_create_proclist;
1764 task_dev = device_create(dsp_task_class, NULL,
1765 MKDEV(OMAP_DSP_TASK_MAJOR, minor),
1766 "dsptask%d", (int)minor);
1768 if (unlikely(IS_ERR(task_dev))) {
1770 goto fail_create_taskclass;
1773 init_waitqueue_head(&dev->state_wait_q);
1774 init_rwsem(&dev->state_sem);
1778 fail_create_taskclass:
1779 device_remove_file(&dev->dev, &dev_attr_proc_list);
1780 fail_create_proclist:
1781 device_remove_file(&dev->dev, &dev_attr_devstate);
1782 fail_create_devstate:
1783 device_remove_file(&dev->dev, &dev_attr_devname);
1784 fail_create_devname:
1785 device_unregister(&dev->dev);
1789 static void taskdev_delete(unsigned char minor)
1791 struct taskdev *dev = taskdev[minor];
1795 device_remove_file(&dev->dev, &dev_attr_devname);
1796 device_remove_file(&dev->dev, &dev_attr_devstate);
1797 device_remove_file(&dev->dev, &dev_attr_proc_list);
1798 device_destroy(dsp_task_class, MKDEV(OMAP_DSP_TASK_MAJOR, minor));
1799 device_unregister(&dev->dev);
1800 proc_list_flush(&dev->proc_list_lock, &dev->proc_list);
1801 taskdev[minor] = NULL;
1804 static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task)
1806 u16 ttyp = task->ttyp;
1811 sndtyp_wd(ttyp) ? dsp_task_read_wd_acv:
1812 /* sndtyp_bk */ dsp_task_read_bk_acv:
1814 sndtyp_wd(ttyp) ? dsp_task_read_wd_psv:
1815 /* sndtyp_bk */ dsp_task_read_bk_psv;
1816 if (sndtyp_wd(ttyp)) {
1820 fifosz = sndtyp_psv(ttyp) ? 2 : /* passive */
1822 if (init_fifo(&dev->rcvdt.fifo, fifosz) < 0) {
1824 "omapdsp: unable to allocate receive buffer. "
1825 "(%d bytes for %s)\n", fifosz, dev->name);
1830 INIT_IPBLINK(&dev->rcvdt.bk.link);
1831 dev->rcvdt.bk.rp = 0;
1835 rcvtyp_wd(ttyp) ? dsp_task_write_wd:
1836 /* rcvbyp_bk */ dsp_task_write_bk;
1837 dev->wsz = rcvtyp_acv(ttyp) ? 0 : /* active */
1838 rcvtyp_wd(ttyp) ? 2 : /* passive word */
1839 ipbcfg.lsz*2; /* passive block */
1841 if (task->map_length)
1842 dev->fops.mmap = dsp_task_mmap;
1844 ret = device_create_file(&dev->dev, &dev_attr_taskname);
1846 goto fail_create_taskname;
1847 ret = device_create_file(&dev->dev, &dev_attr_ttyp);
1849 goto fail_create_ttyp;
1850 ret = device_create_file(&dev->dev, &dev_attr_wsz);
1852 goto fail_create_wsz;
1853 if (task->map_length) {
1854 ret = device_create_file(&dev->dev, &dev_attr_mmap);
1856 goto fail_create_mmap;
1858 if (sndtyp_wd(ttyp)) {
1859 ret = device_create_file(&dev->dev, &dev_attr_fifosz);
1861 goto fail_create_fifosz;
1862 ret = device_create_file(&dev->dev, &dev_attr_fifocnt);
1864 goto fail_create_fifocnt;
1866 ret = device_create_file(&dev->dev, &dev_attr_ipblink);
1868 goto fail_create_ipblink;
1876 fail_create_fifocnt:
1877 device_remove_file(&dev->dev, &dev_attr_fifosz);
1878 fail_create_ipblink:
1880 if (task->map_length)
1881 device_remove_file(&dev->dev, &dev_attr_mmap);
1883 device_remove_file(&dev->dev, &dev_attr_wsz);
1885 device_remove_file(&dev->dev, &dev_attr_ttyp);
1887 device_remove_file(&dev->dev, &dev_attr_taskname);
1888 fail_create_taskname:
1889 if (task->map_length)
1890 dev->fops.mmap = NULL;
1892 dev->fops.write = NULL;
1895 dev->fops.read = NULL;
1896 taskdev_flush_buf(dev);
1898 if (sndtyp_wd(ttyp))
1899 free_fifo(&dev->rcvdt.fifo);
1906 static void taskdev_detach_task(struct taskdev *dev)
1908 u16 ttyp = dev->task->ttyp;
1910 device_remove_file(&dev->dev, &dev_attr_taskname);
1911 device_remove_file(&dev->dev, &dev_attr_ttyp);
1912 if (sndtyp_wd(ttyp)) {
1913 device_remove_file(&dev->dev, &dev_attr_fifosz);
1914 device_remove_file(&dev->dev, &dev_attr_fifocnt);
1916 device_remove_file(&dev->dev, &dev_attr_ipblink);
1917 device_remove_file(&dev->dev, &dev_attr_wsz);
1918 if (dev->task->map_length) {
1919 device_remove_file(&dev->dev, &dev_attr_mmap);
1920 dev->fops.mmap = NULL;
1923 dev->fops.read = NULL;
1924 taskdev_flush_buf(dev);
1925 if (sndtyp_wd(ttyp))
1926 free_fifo(&dev->rcvdt.fifo);
1928 dev->fops.write = NULL;
1931 pr_info("omapdsp: taskdev %s disabled.\n", dev->name);
1936 * tadd / tdel / tkill
1938 static int dsp_tadd(struct taskdev *dev, dsp_long_t adr)
1940 struct dsptask *task;
1941 struct mb_exarg arg;
1942 u8 tid, tid_response;
1946 if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) {
1948 "omapdsp: taskdev %s is not requesting for tadd. "
1949 "(state is %s)\n", dev->name, devstate_name(dev->state));
1952 set_taskdev_state(dev, TASKDEV_ST_ADDING);
1953 devstate_write_unlock(dev);
1955 if (adr == TADD_ABORTADR) {
1956 /* aborting tadd intentionally */
1957 pr_info("omapdsp: tadd address is ABORTADR.\n");
1960 if (adr >= DSPSPACE_SIZE) {
1962 "omapdsp: illegal address 0x%08x for tadd\n", adr);
1967 adr >>= 1; /* word address */
1968 argv[0] = adr >> 16; /* addrh */
1969 argv[1] = adr & 0xffff; /* addrl */
1971 if (mutex_lock_interruptible(&cfg_lock)) {
1976 cfg_cmd = MBOX_CMD_DSP_TADD;
1981 if (dsp_mem_sync_inc() < 0) {
1982 printk(KERN_ERR "omapdsp: memory sync failed!\n");
1986 mbcompose_send_and_wait_exarg(TADD, 0, 0, &arg, &cfg_wait_q);
1991 mutex_unlock(&cfg_lock);
1993 if (tid == TID_ANON) {
1994 printk(KERN_ERR "omapdsp: tadd failed!\n");
1998 if ((tid < n_task) || dsptask[tid]) {
1999 printk(KERN_ERR "omapdsp: illegal tid (%d)!\n", tid);
2003 if ((task = kzalloc(sizeof(struct dsptask), GFP_KERNEL)) == NULL) {
2008 if ((ret = dsp_task_config(task, tid)) < 0)
2011 if (strcmp(dev->name, task->name)) {
2013 "omapdsp: task name (%s) doesn't match with "
2014 "device name (%s).\n", task->name, dev->name);
2019 if ((ret = taskdev_attach_task(dev, task)) < 0)
2022 dsp_task_init(task);
2023 pr_info("omapdsp: taskdev %s enabled.\n", dev->name);
2024 set_taskdev_state(dev, TASKDEV_ST_ATTACHED);
2025 wake_up_interruptible_all(&dev->state_wait_q);
2032 printk(KERN_ERR "omapdsp: deleting the task...\n");
2034 set_taskdev_state(dev, TASKDEV_ST_DELING);
2036 if (mutex_lock_interruptible(&cfg_lock)) {
2037 printk(KERN_ERR "omapdsp: aborting tdel process. "
2038 "DSP side could be corrupted.\n");
2042 cfg_cmd = MBOX_CMD_DSP_TDEL;
2043 mbcompose_send_and_wait(TDEL, tid, TDEL_KILL, &cfg_wait_q);
2044 tid_response = cfg_tid;
2047 mutex_unlock(&cfg_lock);
2049 if (tid_response != tid)
2050 printk(KERN_ERR "omapdsp: tdel failed. "
2051 "DSP side could be corrupted.\n");
2054 set_taskdev_state(dev, TASKDEV_ST_ADDFAIL);
2055 wake_up_interruptible_all(&dev->state_wait_q);
2059 int dsp_tadd_minor(unsigned char minor, dsp_long_t adr)
2061 struct taskdev *dev;
2065 if (mutex_lock_interruptible(&devmgr_lock))
2068 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2070 "omapdsp: no task device with minor %d\n", minor);
2075 if ((status = dsp_tadd(dev, adr)) < 0)
2079 mutex_unlock(&devmgr_lock);
2083 static int dsp_tdel(struct taskdev *dev)
2085 if (!devstate_write_lock_and_test(dev, TASKDEV_ST_DELREQ)) {
2087 "omapdsp: taskdev %s is not requesting for tdel. "
2088 "(state is %s)\n", dev->name, devstate_name(dev->state));
2091 set_taskdev_state(dev, TASKDEV_ST_DELING);
2092 devstate_write_unlock(dev);
2094 return dsp_tdel_bh(dev, TDEL_SAFE);
2097 int dsp_tdel_minor(unsigned char minor)
2099 struct taskdev *dev;
2103 if (mutex_lock_interruptible(&devmgr_lock))
2106 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2108 "omapdsp: no task device with minor %d\n", minor);
2114 if ((status = dsp_tdel(dev)) < 0)
2118 mutex_unlock(&devmgr_lock);
2122 static int dsp_tkill(struct taskdev *dev)
2124 while (!down_write_trylock(&dev->state_sem)) {
2125 if (!devstate_read_lock_and_test(dev, (TASKDEV_ST_ATTACHED |
2126 TASKDEV_ST_FREEZED))) {
2128 "omapdsp: task has not been attached for "
2129 "taskdev %s\n", dev->name);
2132 /* ATTACHED -> FREEZED can be changed under read semaphore. */
2133 set_taskdev_state(dev, TASKDEV_ST_FREEZED);
2134 wake_up_interruptible_all(&dev->read_wait_q);
2135 wake_up_interruptible_all(&dev->write_wait_q);
2136 wake_up_interruptible_all(&dev->tctl_wait_q);
2137 devstate_read_unlock(dev);
2141 if (!(dev->state & (TASKDEV_ST_ATTACHED |
2142 TASKDEV_ST_FREEZED))) {
2144 "omapdsp: task has not been attached for taskdev %s\n",
2146 devstate_write_unlock(dev);
2149 if (!is_dynamic_task(dev->task->tid)) {
2150 printk(KERN_ERR "omapdsp: task %s is not a dynamic task.\n",
2152 devstate_write_unlock(dev);
2155 set_taskdev_state(dev, TASKDEV_ST_KILLING);
2156 devstate_write_unlock(dev);
2158 return dsp_tdel_bh(dev, TDEL_KILL);
2161 int dsp_tkill_minor(unsigned char minor)
2163 struct taskdev *dev;
2167 if (mutex_lock_interruptible(&devmgr_lock))
2170 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2172 "omapdsp: no task device with minor %d\n", minor);
2178 if ((status = dsp_tkill(dev)) < 0)
2182 mutex_unlock(&devmgr_lock);
2186 static int dsp_tdel_bh(struct taskdev *dev, u16 type)
2188 struct dsptask *task;
2189 u8 tid, tid_response;
2194 if (mutex_lock_interruptible(&cfg_lock)) {
2195 if (type == TDEL_SAFE) {
2196 set_taskdev_state(dev, TASKDEV_ST_DELREQ);
2199 tid_response = TID_ANON;
2205 cfg_cmd = MBOX_CMD_DSP_TDEL;
2206 mbcompose_send_and_wait(TDEL, tid, type, &cfg_wait_q);
2207 tid_response = cfg_tid;
2210 mutex_unlock(&cfg_lock);
2213 taskdev_detach_task(dev);
2214 dsp_task_unconfig(task);
2217 if (tid_response != tid) {
2218 printk(KERN_ERR "omapdsp: %s failed!\n",
2219 (type == TDEL_SAFE) ? "tdel" : "tkill");
2222 down_write(&dev->state_sem);
2223 set_taskdev_state(dev, (dev->usecount > 0) ? TASKDEV_ST_GARBAGE :
2225 wake_up_interruptible_all(&dev->state_wait_q);
2226 up_write(&dev->state_sem);
2234 long taskdev_state_stale(unsigned char minor)
2236 if (taskdev[minor]) {
2237 long state = taskdev[minor]->state;
2238 taskdev[minor]->state |= TASKDEV_ST_STALE;
2241 return TASKDEV_ST_NOTASK;
2245 * functions called from mailbox interrupt routine
2247 void mbox_wdsnd(struct mbcmd *mb)
2250 struct dsptask *task = dsptask[tid];
2252 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2253 printk(KERN_ERR "mbox: WDSND with illegal tid! %d\n", tid);
2256 if (sndtyp_bk(task->ttyp)) {
2258 "mbox: WDSND from block sending task! (task%d)\n", tid);
2261 if (sndtyp_psv(task->ttyp) &&
2262 !waitqueue_active(&task->dev->read_wait_q)) {
2264 "mbox: WDSND from passive sending task (task%d) "
2265 "without request!\n", tid);
2269 write_word_to_fifo(&task->dev->rcvdt.fifo, mb->data);
2270 wake_up_interruptible(&task->dev->read_wait_q);
2273 void mbox_wdreq(struct mbcmd *mb)
2276 struct dsptask *task = dsptask[tid];
2277 struct taskdev *dev;
2279 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2280 printk(KERN_ERR "mbox: WDREQ with illegal tid! %d\n", tid);
2283 if (rcvtyp_psv(task->ttyp)) {
2285 "mbox: WDREQ from passive receiving task! (task%d)\n",
2291 spin_lock(&dev->wsz_lock);
2293 spin_unlock(&dev->wsz_lock);
2294 wake_up_interruptible(&dev->write_wait_q);
2297 void mbox_bksnd(struct mbcmd *mb)
2301 struct dsptask *task = dsptask[tid];
2302 struct ipbuf_head *ipb_h;
2305 if (bid >= ipbcfg.ln) {
2306 printk(KERN_ERR "mbox: BKSND with illegal bid! %d\n", bid);
2309 ipb_h = bid_to_ipbuf(bid);
2310 ipb_bsycnt_dec(&ipbcfg);
2311 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2312 printk(KERN_ERR "mbox: BKSND with illegal tid! %d\n", tid);
2313 goto unuse_ipbuf_out;
2315 if (sndtyp_wd(task->ttyp)) {
2317 "mbox: BKSND from word sending task! (task%d)\n", tid);
2318 goto unuse_ipbuf_out;
2320 if (sndtyp_pvt(task->ttyp)) {
2322 "mbox: BKSND from private sending task! (task%d)\n", tid);
2323 goto unuse_ipbuf_out;
2325 if (sync_with_dsp(&ipb_h->p->sd, tid, 10) < 0) {
2326 printk(KERN_ERR "mbox: BKSND - IPBUF sync failed!\n");
2330 /* should be done in DSP, but just in case. */
2331 ipb_h->p->next = BID_NULL;
2334 if (cnt > ipbcfg.lsz) {
2335 printk(KERN_ERR "mbox: BKSND cnt(%d) > ipbuf line size(%d)!\n",
2337 goto unuse_ipbuf_out;
2341 /* 0-byte send from DSP */
2342 unuse_ipbuf_nowait(ipb_h);
2345 ipblink_add_tail(&task->dev->rcvdt.bk.link, bid);
2346 /* we keep coming bid and return alternative line to DSP. */
2350 wake_up_interruptible(&task->dev->read_wait_q);
2354 unuse_ipbuf_nowait(ipb_h);
2358 void mbox_bkreq(struct mbcmd *mb)
2362 struct dsptask *task = dsptask[tid];
2363 struct taskdev *dev;
2365 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2366 printk(KERN_ERR "mbox: BKREQ with illegal tid! %d\n", tid);
2369 if (rcvtyp_wd(task->ttyp)) {
2371 "mbox: BKREQ from word receiving task! (task%d)\n", tid);
2374 if (rcvtyp_pvt(task->ttyp)) {
2376 "mbox: BKREQ from private receiving task! (task%d)\n",
2380 if (rcvtyp_psv(task->ttyp)) {
2382 "mbox: BKREQ from passive receiving task! (task%d)\n",
2388 spin_lock(&dev->wsz_lock);
2390 spin_unlock(&dev->wsz_lock);
2391 wake_up_interruptible(&dev->write_wait_q);
2394 void mbox_bkyld(struct mbcmd *mb)
2397 struct ipbuf_head *ipb_h;
2399 if (bid >= ipbcfg.ln) {
2400 printk(KERN_ERR "mbox: BKYLD with illegal bid! %d\n", bid);
2403 ipb_h = bid_to_ipbuf(bid);
2405 /* should be done in DSP, but just in case. */
2406 ipb_h->p->next = BID_NULL;
2408 /* we don't need to sync with DSP */
2409 ipb_bsycnt_dec(&ipbcfg);
2410 release_ipbuf(ipb_h);
2413 void mbox_bksndp(struct mbcmd *mb)
2416 struct dsptask *task = dsptask[tid];
2417 struct ipbuf_p *ipbp;
2419 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2420 printk(KERN_ERR "mbox: BKSNDP with illegal tid! %d\n", tid);
2423 if (sndtyp_wd(task->ttyp)) {
2425 "mbox: BKSNDP from word sending task! (task%d)\n", tid);
2428 if (sndtyp_gbl(task->ttyp)) {
2430 "mbox: BKSNDP from non-private sending task! (task%d)\n",
2436 * we should not have delayed block at this point
2437 * because read() routine releases the lock of the buffer and
2438 * until then DSP can't send next data.
2441 ipbp = task->ipbuf_pvt_r;
2442 if (sync_with_dsp(&ipbp->s, tid, 10) < 0) {
2443 printk(KERN_ERR "mbox: BKSNDP - IPBUF sync failed!\n");
2446 pr_debug("mbox: ipbuf_pvt_r->a = 0x%08lx\n",
2447 MKLONG(ipbp->ah, ipbp->al));
2448 ipblink_add_pvt(&task->dev->rcvdt.bk.link);
2449 wake_up_interruptible(&task->dev->read_wait_q);
2452 void mbox_bkreqp(struct mbcmd *mb)
2455 struct dsptask *task = dsptask[tid];
2456 struct taskdev *dev;
2457 struct ipbuf_p *ipbp;
2459 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2460 printk(KERN_ERR "mbox: BKREQP with illegal tid! %d\n", tid);
2463 if (rcvtyp_wd(task->ttyp)) {
2465 "mbox: BKREQP from word receiving task! (task%d)\n", tid);
2468 if (rcvtyp_gbl(task->ttyp)) {
2470 "mbox: BKREQP from non-private receiving task! (task%d)\n", tid);
2473 if (rcvtyp_psv(task->ttyp)) {
2475 "mbox: BKREQP from passive receiving task! (task%d)\n", tid);
2479 ipbp = task->ipbuf_pvt_w;
2480 if (sync_with_dsp(&ipbp->s, TID_FREE, 10) < 0) {
2481 printk(KERN_ERR "mbox: BKREQP - IPBUF sync failed!\n");
2484 pr_debug("mbox: ipbuf_pvt_w->a = 0x%08lx\n",
2485 MKLONG(ipbp->ah, ipbp->al));
2487 spin_lock(&dev->wsz_lock);
2488 dev->wsz = ipbp->c*2;
2489 spin_unlock(&dev->wsz_lock);
2490 wake_up_interruptible(&dev->write_wait_q);
2493 void mbox_tctl(struct mbcmd *mb)
2496 struct dsptask *task = dsptask[tid];
2498 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2499 printk(KERN_ERR "mbox: TCTL with illegal tid! %d\n", tid);
2503 if (!waitqueue_active(&task->dev->tctl_wait_q)) {
2504 printk(KERN_WARNING "mbox: unexpected TCTL from DSP!\n");
2508 task->dev->tctl_stat = mb->data;
2509 wake_up_interruptible(&task->dev->tctl_wait_q);
2512 void mbox_tcfg(struct mbcmd *mb)
2515 struct dsptask *task = dsptask[tid];
2520 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2521 printk(KERN_ERR "mbox: TCFG with illegal tid! %d\n", tid);
2524 if ((task->state != TASK_ST_CFGREQ) || (cfg_cmd != MBOX_CMD_DSP_TCFG)) {
2525 printk(KERN_WARNING "mbox: unexpected TCFG from DSP!\n");
2529 if (dsp_mem_enable(ipbuf_sys_da) < 0) {
2530 printk(KERN_ERR "mbox: TCFG - ipbuf_sys_da read failed!\n");
2531 dsp_mem_disable(ipbuf_sys_da);
2534 if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2535 printk(KERN_ERR "mbox: TCFG - IPBUF sync failed!\n");
2536 dsp_mem_disable(ipbuf_sys_da);
2541 * read configuration data on system IPBUF
2543 buf = ipbuf_sys_da->d;
2544 task->ttyp = buf[0];
2545 task->ipbuf_pvt_r = MKVIRT(buf[1], buf[2]);
2546 task->ipbuf_pvt_w = MKVIRT(buf[3], buf[4]);
2547 task->map_base = MKVIRT(buf[5], buf[6]);
2548 task->map_length = MKLONG(buf[7], buf[8]) << 1; /* word -> byte */
2549 tnm = MKVIRT(buf[9], buf[10]);
2550 release_ipbuf_pvt(ipbuf_sys_da);
2551 dsp_mem_disable(ipbuf_sys_da);
2554 * copy task name string
2556 if (dsp_address_validate(tnm, TNM_LEN, "task name buffer") < 0) {
2557 task->name[0] = '\0';
2561 for (i = 0; i < TNM_LEN-1; i++) {
2562 /* avoiding byte access */
2564 task->name[i] = tmp & 0x00ff;
2568 task->name[TNM_LEN-1] = '\0';
2570 task->state = TASK_ST_READY;
2572 wake_up_interruptible(&cfg_wait_q);
2575 void mbox_tadd(struct mbcmd *mb)
2579 if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBOX_CMD_DSP_TADD)) {
2580 printk(KERN_WARNING "mbox: unexpected TADD from DSP!\n");
2584 wake_up_interruptible(&cfg_wait_q);
2587 void mbox_tdel(struct mbcmd *mb)
2591 if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBOX_CMD_DSP_TDEL)) {
2592 printk(KERN_WARNING "mbox: unexpected TDEL from DSP!\n");
2596 wake_up_interruptible(&cfg_wait_q);
2599 void mbox_err_fatal(u8 tid)
2601 struct dsptask *task = dsptask[tid];
2602 struct taskdev *dev;
2604 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2605 printk(KERN_ERR "mbox: FATAL ERR with illegal tid! %d\n", tid);
2609 /* wake up waiting processes */
2611 wake_up_interruptible_all(&dev->read_wait_q);
2612 wake_up_interruptible_all(&dev->write_wait_q);
2613 wake_up_interruptible_all(&dev->tctl_wait_q);
2616 static u16 *dbg_buf;
2617 static u16 dbg_buf_sz, dbg_line_sz;
2620 int dsp_dbg_config(u16 *buf, u16 sz, u16 lsz)
2622 #ifdef OLD_BINARY_SUPPORT
2623 if ((mbox_revision == MBREV_3_0) || (mbox_revision == MBREV_3_2)) {
2632 if (dsp_address_validate(buf, sz, "debug buffer") < 0)
2637 "omapdsp: dbg_buf lsz (%d) is greater than its "
2638 "buffer size (%d)\n", lsz, sz);
2650 void dsp_dbg_stop(void)
2655 #ifdef OLD_BINARY_SUPPORT
2656 static void mbox_dbg_old(struct mbcmd *mb);
2659 void mbox_dbg(struct mbcmd *mb)
2663 char s[80], *s_end = &s[79], *p;
2667 #ifdef OLD_BINARY_SUPPORT
2668 if ((mbox_revision == MBREV_3_0) || (mbox_revision == MBREV_3_2)) {
2674 if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2675 (tid != TID_ANON)) {
2676 printk(KERN_ERR "mbox: DBG with illegal tid! %d\n", tid);
2679 if (dbg_buf == NULL) {
2680 printk(KERN_ERR "mbox: DBG command received, but "
2681 "dbg_buf has not been configured yet.\n");
2685 if (dsp_mem_enable(dbg_buf) < 0)
2688 src = &dbg_buf[dbg_rp];
2690 for (i = 0; i < cnt; i++) {
2693 * Be carefull that dbg_buf should not be read with
2694 * 1-byte access since it might be placed in DARAM/SARAM
2695 * and it can cause unexpected byteswap.
2697 * *(p++) = *(src++) & 0xff;
2698 * causes 1-byte access!
2701 *(p++) = tmp & 0xff;
2702 if (*(p-1) == '\n') {
2719 if ((dbg_rp += cnt + 1) > dbg_buf_sz - dbg_line_sz)
2722 dsp_mem_disable(dbg_buf);
2725 #ifdef OLD_BINARY_SUPPORT
2726 static void mbox_dbg_old(struct mbcmd *mb)
2729 char s[80], *s_end = &s[79], *p;
2735 if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2736 (tid != TID_ANON)) {
2737 printk(KERN_ERR "mbox: DBG with illegal tid! %d\n", tid);
2740 if (dsp_mem_enable(ipbuf_sys_da) < 0) {
2741 printk(KERN_ERR "mbox: DBG - ipbuf_sys_da read failed!\n");
2744 if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2745 printk(KERN_ERR "mbox: DBG - IPBUF sync failed!\n");
2748 buf = ipbuf_sys_da->d;
2750 src = MKVIRT(buf[1], buf[2]);
2751 if (dsp_address_validate(src, cnt, "dbg buffer") < 0)
2754 if (dsp_mem_enable(src) < 0)
2758 for (i = 0; i < cnt; i++) {
2761 * Be carefull that ipbuf should not be read with
2762 * 1-byte access since it might be placed in DARAM/SARAM
2763 * and it can cause unexpected byteswap.
2765 * *(p++) = *(src++) & 0xff;
2766 * causes 1-byte access!
2769 *(p++) = tmp & 0xff;
2770 if (*(p-1) == '\n') {
2788 dsp_mem_disable(src);
2790 release_ipbuf_pvt(ipbuf_sys_da);
2792 dsp_mem_disable(ipbuf_sys_da);
2794 #endif /* OLD_BINARY_SUPPORT */
2797 * sysfs files: for each device
2801 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
2804 return sprintf(buf, "%s\n", to_taskdev(d)->name);
2808 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
2811 return sprintf(buf, "%s\n", devstate_name(to_taskdev(d)->state));
2815 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
2818 struct taskdev *dev;
2819 struct proc_list *pl;
2822 dev = to_taskdev(d);
2823 spin_lock(&dev->proc_list_lock);
2824 list_for_each_entry(pl, &dev->proc_list, list_head) {
2825 /* need to lock tasklist_lock before calling
2826 * find_task_by_pid_type. */
2827 if (find_task_by_pid_type(PIDTYPE_PID, pl->pid) != NULL)
2828 len += sprintf(buf + len, "%d\n", pl->pid);
2829 read_unlock(&tasklist_lock);
2831 spin_unlock(&dev->proc_list_lock);
2837 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
2840 struct taskdev *dev = to_taskdev(d);
2843 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
2846 len = sprintf(buf, "%s\n", dev->task->name);
2848 devstate_read_unlock(dev);
2853 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
2856 struct taskdev *dev = to_taskdev(d);
2860 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
2863 ttyp = dev->task->ttyp;
2864 len += sprintf(buf + len, "0x%04x\n", ttyp);
2865 len += sprintf(buf + len, "%s %s send\n",
2866 (sndtyp_acv(ttyp)) ? "active" :
2868 (sndtyp_wd(ttyp)) ? "word" :
2869 (sndtyp_pvt(ttyp)) ? "private block" :
2871 len += sprintf(buf + len, "%s %s receive\n",
2872 (rcvtyp_acv(ttyp)) ? "active" :
2874 (rcvtyp_wd(ttyp)) ? "word" :
2875 (rcvtyp_pvt(ttyp)) ? "private block" :
2878 devstate_read_unlock(dev);
2883 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
2886 struct fifo_struct *fifo = &to_taskdev(d)->rcvdt.fifo;
2887 return sprintf(buf, "%d\n", fifo->sz);
2890 static int fifosz_store(struct device *d, struct device_attribute *attr,
2891 const char *buf, size_t count)
2893 struct taskdev *dev = to_taskdev(d);
2894 unsigned long fifosz;
2897 fifosz = simple_strtol(buf, NULL, 10);
2898 ret = taskdev_set_fifosz(dev, fifosz);
2900 return (ret < 0) ? ret : strlen(buf);
2904 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
2907 struct fifo_struct *fifo = &to_taskdev(d)->rcvdt.fifo;
2908 return sprintf(buf, "%d\n", fifo->cnt);
2912 static inline char *bid_name(u16 bid)
2922 sprintf(s, "%d", bid);
2927 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
2930 struct rcvdt_bk_struct *rcvdt = &to_taskdev(d)->rcvdt.bk;
2933 spin_lock(&rcvdt->link.lock);
2934 len = sprintf(buf, "top %s\ntail %s\n",
2935 bid_name(rcvdt->link.top), bid_name(rcvdt->link.tail));
2936 spin_unlock(&rcvdt->link.lock);
2942 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
2945 return sprintf(buf, "%d\n", to_taskdev(d)->wsz);
2949 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
2952 struct dsptask *task = to_taskdev(d)->task;
2953 return sprintf(buf, "0x%p 0x%x\n", task->map_base, task->map_length);
2957 * called from ipbuf_show()
2959 int ipbuf_is_held(u8 tid, u16 bid)
2961 struct dsptask *task = dsptask[tid];
2962 struct ipblink *link;
2969 link = &task->dev->rcvdt.bk.link;
2970 spin_lock(&link->lock);
2971 ipblink_for_each(b, link) {
2972 if (b == bid) { /* found */
2977 spin_unlock(&link->lock);
2982 int __init dsp_taskmod_init(void)
2986 memset(taskdev, 0, sizeof(void *) * TASKDEV_MAX);
2987 memset(dsptask, 0, sizeof(void *) * TASKDEV_MAX);
2989 retval = register_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask",
2993 "omapdsp: failed to register task device: %d\n", retval);
2997 retval = bus_register(&dsptask_bus);
3000 "omapdsp: failed to register DSP task bus: %d\n",
3002 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3005 retval = driver_register(&dsptask_driver);
3008 "omapdsp: failed to register DSP task driver: %d\n",
3010 bus_unregister(&dsptask_bus);
3011 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3014 dsp_task_class = class_create(THIS_MODULE, "dsptask");
3015 if (IS_ERR(dsp_task_class)) {
3016 printk(KERN_ERR "omapdsp: failed to create DSP task class\n");
3017 driver_unregister(&dsptask_driver);
3018 bus_unregister(&dsptask_bus);
3019 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3026 void dsp_taskmod_exit(void)
3028 class_destroy(dsp_task_class);
3029 driver_unregister(&dsptask_driver);
3030 bus_unregister(&dsptask_bus);
3031 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");