2 * linux/arch/arm/mach-omap/dsp/task.c
4 * OMAP DSP task device driver
6 * Copyright (C) 2002-2005 Nokia Corporation
8 * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
9 * mmap function by Hiroo Ishikawa <ext-hiroo.ishikawa@nokia.com>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * 2005/07/26: DSP Gateway version 3.3
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/major.h>
33 #include <linux/poll.h>
34 #include <linux/platform_device.h>
35 #include <linux/slab.h>
36 #include <linux/sched.h>
38 #include <linux/proc_fs.h>
39 #include <linux/mutex.h>
40 #include <linux/interrupt.h>
41 #include <asm/uaccess.h>
43 #include <asm/signal.h>
45 #include <asm/ioctls.h>
46 #include <asm/arch/dsp.h>
47 #include "uaccess_dsp.h"
53 #define is_aligned(adr,align) (!((adr)&((align)-1)))
56 * taskdev.state: device state machine
57 * NOTASK: task is not attached.
58 * ATTACHED: task is attached.
59 * GARBAGE: task is detached. waiting for all processes to close this device.
60 * ADDREQ: requesting for tadd
61 * DELREQ: requesting for tdel. no process is opening this device.
62 * ADDFAIL: tadd failed.
63 * ADDING: tadd in process.
64 * DELING: tdel in process.
65 * KILLING: tkill in process.
67 #define devstate_name(stat) (\
68 ((stat) & OMAP_DSP_DEVSTATE_NOTASK) ? "NOTASK" :\
69 ((stat) & OMAP_DSP_DEVSTATE_ATTACHED) ? "ATTACHED" :\
70 ((stat) & OMAP_DSP_DEVSTATE_GARBAGE) ? "GARBAGE" :\
71 ((stat) & OMAP_DSP_DEVSTATE_INVALID) ? "INVALID" :\
72 ((stat) & OMAP_DSP_DEVSTATE_ADDREQ) ? "ADDREQ" :\
73 ((stat) & OMAP_DSP_DEVSTATE_DELREQ) ? "DELREQ" :\
74 ((stat) & OMAP_DSP_DEVSTATE_ADDFAIL) ? "ADDFAIL" :\
75 ((stat) & OMAP_DSP_DEVSTATE_ADDING) ? "ADDING" :\
76 ((stat) & OMAP_DSP_DEVSTATE_DELING) ? "DELING" :\
77 ((stat) & OMAP_DSP_DEVSTATE_KILLING) ? "KILLING" :\
82 // struct device_driver *driver;
83 struct device dev; /* Generic device interface */
86 spinlock_t state_lock;
87 wait_queue_head_t state_wait_q;
88 unsigned int usecount;
89 char name[OMAP_DSP_TNM_LEN];
90 struct file_operations fops;
91 struct list_head proc_list;
95 wait_queue_head_t read_wait_q;
96 struct mutex read_mutex;
99 wait_queue_head_t write_wait_q;
100 struct mutex write_mutex;
103 wait_queue_head_t ioctl_wait_q;
104 struct mutex ioctl_mutex;
111 #define to_taskdev(n) container_of(n, struct taskdev, dev)
113 struct rcvdt_bk_struct {
116 struct ipbuf_p *ipbuf_pvt_r;
126 char name[OMAP_DSP_TNM_LEN];
132 struct fifo_struct fifo; /* for active word */
133 struct rcvdt_bk_struct bk;
139 struct ipbuf_p *ipbuf_pvt_w; /* for private block */
149 #define sndtyp_acv(ttyp) ((ttyp) & OMAP_DSP_TTYP_ASND)
150 #define sndtyp_psv(ttyp) (!((ttyp) & OMAP_DSP_TTYP_ASND))
151 #define sndtyp_bk(ttyp) ((ttyp) & OMAP_DSP_TTYP_BKDM)
152 #define sndtyp_wd(ttyp) (!((ttyp) & OMAP_DSP_TTYP_BKDM))
153 #define sndtyp_pvt(ttyp) ((ttyp) & OMAP_DSP_TTYP_PVDM)
154 #define sndtyp_gbl(ttyp) (!((ttyp) & OMAP_DSP_TTYP_PVDM))
155 #define rcvtyp_acv(ttyp) ((ttyp) & OMAP_DSP_TTYP_ARCV)
156 #define rcvtyp_psv(ttyp) (!((ttyp) & OMAP_DSP_TTYP_ARCV))
157 #define rcvtyp_bk(ttyp) ((ttyp) & OMAP_DSP_TTYP_BKMD)
158 #define rcvtyp_wd(ttyp) (!((ttyp) & OMAP_DSP_TTYP_BKMD))
159 #define rcvtyp_pvt(ttyp) ((ttyp) & OMAP_DSP_TTYP_PVMD)
160 #define rcvtyp_gbl(ttyp) (!((ttyp) & OMAP_DSP_TTYP_PVMD))
162 static int dsp_rmdev_minor(unsigned char minor);
163 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor);
164 static void taskdev_delete(unsigned char minor);
165 static void taskdev_attach_task(struct taskdev *dev, struct dsptask *task);
166 static void taskdev_detach_task(struct taskdev *dev);
167 static int dsp_tdel_bh(unsigned char minor, unsigned short type);
169 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
171 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
173 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
175 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
177 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
179 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
181 static int fifosz_store(struct device *d, struct device_attribute *attr,
182 const char *buf, size_t count);
183 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
185 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
187 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
189 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
192 static struct device_attribute dev_attr_devname = __ATTR_RO(devname);
193 static struct device_attribute dev_attr_devstate = __ATTR_RO(devstate);
194 static struct device_attribute dev_attr_proc_list = __ATTR_RO(proc_list);
195 static struct device_attribute dev_attr_fifosz =
196 __ATTR(fifosz, S_IWUGO | S_IRUGO, fifosz_show, fifosz_store);
197 static struct device_attribute dev_attr_fifocnt = __ATTR_RO(fifocnt);
198 static struct device_attribute dev_attr_taskname = __ATTR_RO(taskname);
199 static struct device_attribute dev_attr_ttyp = __ATTR_RO(ttyp);
200 static struct device_attribute dev_attr_ipblink = __ATTR_RO(ipblink);
201 static struct device_attribute dev_attr_wsz = __ATTR_RO(wsz);
202 static struct device_attribute dev_attr_mmap = __ATTR_RO(mmap);
204 static struct bus_type dsptask_bus = {
208 static struct class *dsp_task_class;
209 static struct taskdev *taskdev[TASKDEV_MAX];
210 static struct dsptask *dsptask[TASKDEV_MAX];
211 static DEFINE_MUTEX(cfg_lock);
212 static unsigned short cfg_cmd;
213 static unsigned char cfg_tid;
214 static DECLARE_WAIT_QUEUE_HEAD(cfg_wait_q);
215 static unsigned char n_task;
218 #define devstate_lock(dev, devstate) devstate_lock_timeout(dev, devstate, 0)
221 * devstate_lock_timeout():
222 * when called with timeout > 0, dev->state can be diffeent from what you want.
224 static int devstate_lock_timeout(struct taskdev *dev, long devstate,
227 DECLARE_WAITQUEUE(wait, current);
228 long current_state = current->state;
231 spin_lock(&dev->state_lock);
232 add_wait_queue(&dev->state_wait_q, &wait);
233 while (!(dev->state & devstate)) {
234 set_current_state(TASK_INTERRUPTIBLE);
235 spin_unlock(&dev->state_lock);
237 if ((timeout = schedule_timeout(timeout)) == 0) {
239 spin_lock(&dev->state_lock);
245 if (signal_pending(current)) {
249 spin_lock(&dev->state_lock);
251 remove_wait_queue(&dev->state_wait_q, &wait);
252 set_current_state(current_state);
256 static __inline__ void devstate_unlock(struct taskdev *dev)
258 spin_unlock(&dev->state_lock);
261 static inline int taskdev_lock_interruptible(struct taskdev *dev,
266 if (dev->lock_pid == current->pid) {
267 /* this process has lock */
268 ret = mutex_lock_interruptible(lock);
270 if ((ret = mutex_lock_interruptible(&dev->lock)) != 0)
272 ret = mutex_lock_interruptible(lock);
273 mutex_unlock(&dev->lock);
278 static void proclist_send_sigbus(struct list_head *list)
281 struct proc_list *pl;
282 struct task_struct *tsk;
284 info.si_signo = SIGBUS;
286 info.si_code = SI_KERNEL;
287 info._sifields._sigfault._addr = NULL;
289 /* need to lock tasklist_lock before calling find_task_by_pid_type. */
290 read_lock(&tasklist_lock);
291 list_for_each_entry(pl, list, list_head) {
292 if ((tsk = find_task_by_pid_type(PIDTYPE_PID, pl->pid)) != NULL)
293 send_sig_info(SIGBUS, &info, tsk);
295 read_unlock(&tasklist_lock);
298 static int dsp_task_flush_buf(struct dsptask *task)
300 unsigned short ttyp = task->ttyp;
302 if (sndtyp_wd(ttyp)) {
304 flush_fifo(&task->rcvdt.fifo);
306 /* block receiving */
307 struct rcvdt_bk_struct *rcvdt = &task->rcvdt.bk;
309 spin_lock(&rcvdt->link.lock);
310 if (sndtyp_gbl(ttyp)) {
312 while (!ipblink_empty(&rcvdt->link)) {
313 unsigned short bid = rcvdt->link.top;
314 ipblink_del_top(&rcvdt->link, ipbuf);
319 if (!ipblink_empty(&rcvdt->link)) {
320 ipblink_del_pvt(&rcvdt->link);
321 release_ipbuf_pvt(rcvdt->ipbuf_pvt_r);
324 spin_unlock(&rcvdt->link.lock);
330 static int dsp_task_set_fifosz(struct dsptask *task, unsigned long sz)
332 unsigned short ttyp = task->ttyp;
335 if (!(sndtyp_wd(ttyp) && sndtyp_acv(ttyp))) {
337 "omapdsp: buffer size can be changed only for "
338 "active word sending task.\n");
341 if ((sz == 0) || (sz & 1)) {
342 printk(KERN_ERR "omapdsp: illegal buffer size! (%ld)\n"
343 "it must be even and non-zero value.\n", sz);
347 stat = realloc_fifo(&task->rcvdt.fifo, sz);
348 if (stat == -EBUSY) {
349 printk(KERN_ERR "omapdsp: buffer is not empty!\n");
351 } else if (stat < 0) {
353 "omapdsp: unable to change receive buffer size. "
354 "(%ld bytes for %s)\n", sz, task->name);
361 static int taskdev_lock(struct taskdev *dev)
363 if (mutex_lock_interruptible(&dev->lock))
365 dev->lock_pid = current->pid;
369 static int taskdev_unlock(struct taskdev *dev)
371 if (dev->lock_pid != current->pid) {
373 "omapdsp: an illegal process attempted to "
374 "unlock the dsptask lock!\n");
378 mutex_unlock(&dev->lock);
382 static int dsp_task_config(struct dsptask *task, unsigned char tid)
392 task->state = TASK_STATE_CFGREQ;
393 if (mutex_lock_interruptible(&cfg_lock)) {
397 cfg_cmd = MBCMD(TCFG);
398 mbcmd_set(mb, MBCMD(TCFG), tid, 0);
399 dsp_mbcmd_send_and_wait(&mb, &cfg_wait_q);
401 mutex_unlock(&cfg_lock);
403 if (task->state != TASK_STATE_READY) {
404 printk(KERN_ERR "omapdsp: task %d configuration error!\n", tid);
409 if (strlen(task->name) <= 1)
410 sprintf(task->name, "%d", tid);
411 printk(KERN_INFO "omapdsp: task %d: name %s\n", tid, task->name);
416 * task info sanity check
419 /* task type check */
420 if (rcvtyp_psv(ttyp) && rcvtyp_pvt(ttyp)) {
421 printk(KERN_ERR "omapdsp: illegal task type(0x%04x), tid=%d\n",
427 /* private buffer address check */
428 if (sndtyp_pvt(ttyp) &&
429 (ipbuf_p_validate(task->rcvdt.bk.ipbuf_pvt_r, DIR_D2A) < 0)) {
433 if (rcvtyp_pvt(ttyp) &&
434 (ipbuf_p_validate(task->ipbuf_pvt_w, DIR_A2D) < 0)) {
439 /* mmap buffer configuration check */
440 if ((task->map_length > 0) &&
441 ((!is_aligned((unsigned long)task->map_base, PAGE_SIZE)) ||
442 (!is_aligned(task->map_length, PAGE_SIZE)) ||
443 (dsp_mem_type(task->map_base, task->map_length) != MEM_TYPE_EXTERN))) {
445 "omapdsp: illegal mmap buffer address(0x%p) or "
447 " It needs to be page-aligned and located at "
448 "external memory.\n",
449 task->map_base, task->map_length);
458 /* read initialization */
459 if (sndtyp_wd(ttyp)) {
463 fifosz = sndtyp_psv(ttyp) ? 2 : /* passive */
465 if (init_fifo(&task->rcvdt.fifo, fifosz) < 0) {
467 "omapdsp: unable to allocate receive buffer. "
468 "(%d bytes for %s)\n", fifosz, task->name);
474 INIT_IPBLINK(&task->rcvdt.bk.link);
475 task->rcvdt.bk.rp = 0;
478 /* write initialization */
479 spin_lock_init(&task->wsz_lock);
480 task->wsz = rcvtyp_acv(ttyp) ? 0 : /* active */
481 rcvtyp_wd(ttyp) ? 2 : /* passive word */
482 ipbcfg.lsz*2; /* passive block */
491 static void dsp_task_init(struct dsptask *task)
493 dsp_mbsend(MBCMD(TCTL), task->tid, OMAP_DSP_MBCMD_TCTL_TINIT);
496 int dsp_task_config_all(unsigned char n)
499 struct taskdev *devheap;
500 struct dsptask *taskheap;
501 size_t devheapsz, taskheapsz;
503 memset(taskdev, 0, sizeof(void *) * TASKDEV_MAX);
504 memset(dsptask, 0, sizeof(void *) * TASKDEV_MAX);
507 printk(KERN_INFO "omapdsp: found %d task(s)\n", n_task);
514 devheapsz = sizeof(struct taskdev) * n_task;
515 taskheapsz = sizeof(struct dsptask) * n_task;
516 heap = kmalloc(devheapsz + taskheapsz, GFP_KERNEL);
521 memset(heap, 0, devheapsz + taskheapsz);
523 taskheap = heap + devheapsz;
525 for (i = 0; i < n_task; i++) {
526 struct taskdev *dev = &devheap[i];
527 struct dsptask *task = &taskheap[i];
529 if ((ret = dsp_task_config(task, i)) < 0)
531 if ((ret = taskdev_init(dev, task->name, i)) < 0)
533 taskdev_attach_task(dev, task);
535 printk(KERN_INFO "omapdsp: taskdev %s enabled.\n", dev->name);
541 static void dsp_task_unconfig(struct dsptask *task)
543 unsigned char tid = task->tid;
546 dsp_task_flush_buf(task);
547 if (sndtyp_wd(task->ttyp) && (task->state == TASK_STATE_READY))
548 free_fifo(&task->rcvdt.fifo);
553 void dsp_task_unconfig_all(void)
557 struct dsptask *task;
559 for (minor = 0; minor < n_task; minor++) {
561 * taskdev[minor] can be NULL in case of
562 * configuration failure
565 taskdev_delete(minor);
567 for (; minor < TASKDEV_MAX; minor++) {
569 dsp_rmdev_minor(minor);
572 for (tid = 0; tid < n_task; tid++) {
574 * dsptask[tid] can be NULL in case of
575 * configuration failure
579 dsp_task_unconfig(task);
581 for (; tid < TASKDEV_MAX; tid++) {
585 * on-demand tasks should be deleted in
586 * rmdev_minor(), but just in case.
588 dsp_task_unconfig(task);
601 static struct device_driver dsptask_driver = {
606 unsigned char dsp_task_count(void)
611 int dsp_taskmod_busy(void)
616 for (minor = 0; minor < TASKDEV_MAX; minor++) {
617 dev = taskdev[minor];
620 if (dev->usecount > 0) {
621 printk("dsp_taskmod_busy(): %s: usecount=%d\n",
622 dev->name, dev->usecount);
626 if ((dev->state & (OMAP_DSP_DEVSTATE_ADDREQ |
627 OMAP_DSP_DEVSTATE_DELREQ)) {
629 if (dev->state & OMAP_DSP_DEVSTATE_ADDREQ) {
630 printk("dsp_taskmod_busy(): %s is in %s\n",
631 dev->name, devstate_name(dev->state));
639 * DSP task device file operations
641 static ssize_t dsp_task_read_wd_acv(struct file *file, char *buf, size_t count,
644 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
645 struct taskdev *dev = taskdev[minor];
646 int have_devstate_lock = 0;
651 } else if (count & 0x1) {
653 "omapdsp: odd count is illegal for DSP task device.\n");
657 if (taskdev_lock_interruptible(dev, &dev->read_mutex))
659 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
663 have_devstate_lock = 1;
665 if (fifo_empty(&dev->task->rcvdt.fifo)) {
666 long current_state = current->state;
667 DECLARE_WAITQUEUE(wait, current);
669 set_current_state(TASK_INTERRUPTIBLE);
670 add_wait_queue(&dev->read_wait_q, &wait);
671 if (fifo_empty(&dev->task->rcvdt.fifo)) { /* last check */
672 devstate_unlock(dev);
673 have_devstate_lock = 0;
676 set_current_state(current_state);
677 remove_wait_queue(&dev->read_wait_q, &wait);
678 if (signal_pending(current)) {
682 if (!have_devstate_lock) {
683 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
687 have_devstate_lock = 1;
689 if (fifo_empty(&dev->task->rcvdt.fifo)) /* should not occur */
693 ret = copy_to_user_fm_fifo(buf, &dev->task->rcvdt.fifo, count);
696 if (have_devstate_lock)
697 devstate_unlock(dev);
698 mutex_unlock(&dev->read_mutex);
702 static ssize_t dsp_task_read_bk_acv(struct file *file, char *buf, size_t count,
705 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
706 struct taskdev *dev = taskdev[minor];
707 struct rcvdt_bk_struct *rcvdt;
708 int have_devstate_lock = 0;
713 } else if (count & 0x1) {
715 "omapdsp: odd count is illegal for DSP task device.\n");
717 } else if ((int)buf & 0x1) {
719 "omapdsp: buf should be word aligned for "
720 "dsp_task_read().\n");
724 if (taskdev_lock_interruptible(dev, &dev->read_mutex))
726 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
730 have_devstate_lock = 1;
732 if (ipblink_empty(&dev->task->rcvdt.bk.link)) {
734 DECLARE_WAITQUEUE(wait, current);
736 add_wait_queue(&dev->read_wait_q, &wait);
737 current_state = current->state;
738 set_current_state(TASK_INTERRUPTIBLE);
739 if (ipblink_empty(&dev->task->rcvdt.bk.link)) { /* last check */
740 devstate_unlock(dev);
741 have_devstate_lock = 0;
744 set_current_state(current_state);
745 remove_wait_queue(&dev->read_wait_q, &wait);
746 if (signal_pending(current)) {
750 if (!have_devstate_lock) {
751 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
755 have_devstate_lock = 1;
757 /* signal or 0-byte send from DSP */
758 if (ipblink_empty(&dev->task->rcvdt.bk.link))
762 rcvdt = &dev->task->rcvdt.bk;
763 /* copy from delayed IPBUF */
764 if (sndtyp_pvt(dev->task->ttyp)) {
766 if (!ipblink_empty(&rcvdt->link)) {
767 struct ipbuf_p *ipbp = rcvdt->ipbuf_pvt_r;
768 unsigned char *base, *src;
771 if (dsp_mem_enable(ipbp) < 0) {
775 base = MKVIRT(ipbp->ah, ipbp->al);
776 bkcnt = ((unsigned long)ipbp->c) * 2 - rcvdt->rp;
777 if (dsp_address_validate(base, bkcnt,
778 "task %s read buffer",
779 dev->task->name) < 0) {
783 if (dsp_mem_enable(base) < 0) {
787 src = base + rcvdt->rp;
789 if (copy_to_user_dsp(buf, src, count)) {
796 if (copy_to_user_dsp(buf, src, bkcnt)) {
801 spin_lock(&rcvdt->link.lock);
802 ipblink_del_pvt(&rcvdt->link);
803 spin_unlock(&rcvdt->link.lock);
804 release_ipbuf_pvt(ipbp);
808 dsp_mem_disable(src);
810 dsp_mem_disable(ipbp);
814 if (dsp_mem_enable_ipbuf() < 0) {
818 while (!ipblink_empty(&rcvdt->link)) {
821 unsigned short bid = rcvdt->link.top;
822 struct ipbuf *ipbp = ipbuf[bid];
824 src = ipbp->d + rcvdt->rp;
825 bkcnt = ((unsigned long)ipbp->c) * 2 - rcvdt->rp;
827 if (copy_to_user_dsp(buf, src, count)) {
835 if (copy_to_user_dsp(buf, src, bkcnt)) {
842 spin_lock(&rcvdt->link.lock);
843 ipblink_del_top(&rcvdt->link, ipbuf);
844 spin_unlock(&rcvdt->link.lock);
850 dsp_mem_disable_ipbuf();
854 if (have_devstate_lock)
855 devstate_unlock(dev);
856 mutex_unlock(&dev->read_mutex);
860 static ssize_t dsp_task_read_wd_psv(struct file *file, char *buf, size_t count,
863 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
864 struct taskdev *dev = taskdev[minor];
871 } else if (count & 0x1) {
873 "omapdsp: odd count is illegal for DSP task device.\n");
880 if (taskdev_lock_interruptible(dev, &dev->read_mutex))
882 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
886 tid = dev->task->tid;
887 devstate_unlock(dev);
889 mbcmd_set(mb, MBCMD(WDREQ), tid, 0);
890 dsp_mbcmd_send_and_wait(&mb, &dev->read_wait_q);
892 if (signal_pending(current)) {
896 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
900 if (fifo_empty(&dev->task->rcvdt.fifo)) /* should not occur */
903 ret = copy_to_user_fm_fifo(buf, &dev->task->rcvdt.fifo, count);
906 devstate_unlock(dev);
908 mutex_unlock(&dev->read_mutex);
912 static ssize_t dsp_task_read_bk_psv(struct file *file, char *buf, size_t count,
915 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
916 struct taskdev *dev = taskdev[minor];
917 struct rcvdt_bk_struct *rcvdt;
924 } else if (count & 0x1) {
926 "omapdsp: odd count is illegal for DSP task device.\n");
928 } else if ((int)buf & 0x1) {
930 "omapdsp: buf should be word aligned for "
931 "dsp_task_read().\n");
935 if (taskdev_lock_interruptible(dev, &dev->read_mutex))
937 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
941 tid = dev->task->tid;
942 devstate_unlock(dev);
944 mbcmd_set(mb, MBCMD(BKREQ), tid, count/2);
945 dsp_mbcmd_send_and_wait(&mb, &dev->read_wait_q);
947 if (signal_pending(current)) {
951 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
955 rcvdt = &dev->task->rcvdt.bk;
956 /* signal or 0-byte send from DSP */
957 if (ipblink_empty(&rcvdt->link))
961 * We will not receive more than requested count.
963 if (sndtyp_pvt(dev->task->ttyp)) {
965 struct ipbuf_p *ipbp = rcvdt->ipbuf_pvt_r;
969 if (dsp_mem_enable(ipbp) < 0) {
973 src = MKVIRT(ipbp->ah, ipbp->al);
974 rcvcnt = ((unsigned long)ipbp->c) * 2;
975 if (dsp_address_validate(src, rcvcnt, "task %s read buffer",
976 dev->task->name) < 0) {
980 if (dsp_mem_enable(src) < 0) {
986 if (copy_to_user_dsp(buf, src, count)) {
990 spin_lock(&rcvdt->link.lock);
991 ipblink_del_pvt(&rcvdt->link);
992 spin_unlock(&rcvdt->link.lock);
993 release_ipbuf_pvt(ipbp);
996 dsp_mem_disable(src);
998 dsp_mem_disable(ipbp);
1001 unsigned short bid = rcvdt->link.top;
1002 struct ipbuf *ipbp = ipbuf[bid];
1005 if (dsp_mem_enable_ipbuf() < 0) {
1009 rcvcnt = ((unsigned long)ipbp->c) * 2;
1012 if (copy_to_user_dsp(buf, ipbp->d, count)) {
1016 spin_lock(&rcvdt->link.lock);
1017 ipblink_del_top(&rcvdt->link, ipbuf);
1018 spin_unlock(&rcvdt->link.lock);
1022 dsp_mem_disable_ipbuf();
1026 devstate_unlock(dev);
1028 mutex_unlock(&dev->read_mutex);
1032 static ssize_t dsp_task_write_wd(struct file *file, const char *buf,
1033 size_t count, loff_t *ppos)
1035 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1036 struct taskdev *dev = taskdev[minor];
1038 int have_devstate_lock = 0;
1043 } else if (count & 0x1) {
1045 "omapdsp: odd count is illegal for DSP task device.\n");
1052 if (taskdev_lock_interruptible(dev, &dev->write_mutex))
1053 return -ERESTARTSYS;
1054 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1058 have_devstate_lock = 1;
1060 if (dev->task->wsz == 0) {
1062 DECLARE_WAITQUEUE(wait, current);
1064 add_wait_queue(&dev->write_wait_q, &wait);
1065 current_state = current->state;
1066 set_current_state(TASK_INTERRUPTIBLE);
1067 if (dev->task->wsz == 0) { /* last check */
1068 devstate_unlock(dev);
1069 have_devstate_lock = 0;
1072 set_current_state(current_state);
1073 remove_wait_queue(&dev->write_wait_q, &wait);
1074 if (signal_pending(current)) {
1078 if (!have_devstate_lock) {
1079 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1083 have_devstate_lock = 1;
1085 if (dev->task->wsz == 0) /* should not occur */
1089 if (copy_from_user(&wd, buf, count)) {
1094 spin_lock(&dev->task->wsz_lock);
1095 if (dsp_mbsend(MBCMD(WDSND), dev->task->tid, wd) < 0) {
1096 spin_unlock(&dev->task->wsz_lock);
1100 if (rcvtyp_acv(dev->task->ttyp))
1102 spin_unlock(&dev->task->wsz_lock);
1105 if (have_devstate_lock)
1106 devstate_unlock(dev);
1107 mutex_unlock(&dev->write_mutex);
1111 static ssize_t dsp_task_write_bk(struct file *file, const char *buf,
1112 size_t count, loff_t *ppos)
1114 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1115 struct taskdev *dev = taskdev[minor];
1116 int have_devstate_lock = 0;
1121 } else if (count & 0x1) {
1123 "omapdsp: odd count is illegal for DSP task device.\n");
1125 } else if ((int)buf & 0x1) {
1127 "omapdsp: buf should be word aligned for "
1128 "dsp_task_write().\n");
1132 if (taskdev_lock_interruptible(dev, &dev->write_mutex))
1133 return -ERESTARTSYS;
1134 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1138 have_devstate_lock = 1;
1140 if (dev->task->wsz == 0) {
1142 DECLARE_WAITQUEUE(wait, current);
1144 add_wait_queue(&dev->write_wait_q, &wait);
1145 current_state = current->state;
1146 set_current_state(TASK_INTERRUPTIBLE);
1147 if (dev->task->wsz == 0) { /* last check */
1148 devstate_unlock(dev);
1149 have_devstate_lock = 0;
1152 set_current_state(current_state);
1153 remove_wait_queue(&dev->write_wait_q, &wait);
1154 if (signal_pending(current)) {
1158 if (!have_devstate_lock) {
1159 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1163 have_devstate_lock = 1;
1165 if (dev->task->wsz == 0) /* should not occur */
1169 if (count > dev->task->wsz)
1170 count = dev->task->wsz;
1172 if (rcvtyp_pvt(dev->task->ttyp)) {
1174 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_w;
1177 if (dsp_mem_enable(ipbp) < 0) {
1181 dst = MKVIRT(ipbp->ah, ipbp->al);
1182 if (dsp_address_validate(dst, count, "task %s write buffer",
1183 dev->task->name) < 0) {
1187 if (dsp_mem_enable(dst) < 0) {
1191 if (copy_from_user_dsp(dst, buf, count)) {
1196 ipbp->s = dev->task->tid;
1197 spin_lock(&dev->task->wsz_lock);
1198 if (dsp_mbsend(MBCMD(BKSNDP), dev->task->tid, 0) == 0) {
1199 if (rcvtyp_acv(dev->task->ttyp))
1203 spin_unlock(&dev->task->wsz_lock);
1205 dsp_mem_disable(dst);
1207 dsp_mem_disable(ipbp);
1213 if (dsp_mem_enable_ipbuf() < 0) {
1217 bid = get_free_ipbuf(dev->task->tid);
1218 if (bid == OMAP_DSP_BID_NULL)
1221 if (copy_from_user_dsp(ipbp->d, buf, count)) {
1227 ipbp->sa = dev->task->tid;
1228 spin_lock(&dev->task->wsz_lock);
1229 if (dsp_mbsend(MBCMD(BKSND), dev->task->tid, bid) == 0) {
1230 if (rcvtyp_acv(dev->task->ttyp))
1233 ipb_bsycnt_inc(&ipbcfg);
1236 spin_unlock(&dev->task->wsz_lock);
1238 dsp_mem_disable_ipbuf();
1242 if (have_devstate_lock)
1243 devstate_unlock(dev);
1244 mutex_unlock(&dev->write_mutex);
1248 static unsigned int dsp_task_poll(struct file * file, poll_table * wait)
1250 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1251 struct taskdev *dev = taskdev[minor];
1252 struct dsptask *task = dev->task;
1253 unsigned int mask = 0;
1255 poll_wait(file, &dev->read_wait_q, wait);
1256 poll_wait(file, &dev->write_wait_q, wait);
1257 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0)
1259 if (sndtyp_psv(task->ttyp) ||
1260 (sndtyp_wd(task->ttyp) && !fifo_empty(&task->rcvdt.fifo)) ||
1261 (sndtyp_bk(task->ttyp) && !ipblink_empty(&task->rcvdt.bk.link)))
1262 mask |= POLLIN | POLLRDNORM;
1264 mask |= POLLOUT | POLLWRNORM;
1265 devstate_unlock(dev);
1270 static int dsp_task_ioctl(struct inode *inode, struct file *file,
1271 unsigned int cmd, unsigned long arg)
1273 unsigned int minor = MINOR(inode->i_rdev);
1274 struct taskdev *dev = taskdev[minor];
1277 struct mb_exarg mbarg, *mbargp;
1279 unsigned short mbargv[1];
1283 /* LOCK / UNLOCK operations */
1285 case OMAP_DSP_TASK_IOCTL_LOCK:
1286 return taskdev_lock(dev);
1287 case OMAP_DSP_TASK_IOCTL_UNLOCK:
1288 return taskdev_unlock(dev);
1292 * actually only interractive commands need to lock
1293 * the mutex, but here all commands do it for simplicity.
1295 if (taskdev_lock_interruptible(dev, &dev->ioctl_mutex))
1296 return -ERESTARTSYS;
1297 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1302 if ((cmd >= 0x0080) && (cmd < 0x0100)) {
1305 * reserved for backward compatibility
1306 * user-defined TCTL commands: no arg, non-interactive
1308 printk(KERN_WARNING "omapdsp: "
1309 "TCTL commands in 0x0080 - 0x0100 are obsolete.\n"
1310 "they won't be supported in the future.\n");
1313 } else if (cmd < 0x8000) {
1315 * 0x0000 - 0x7fff (except 0x0080 - 0x00ff)
1316 * system reserved TCTL commands
1319 case OMAP_DSP_MBCMD_TCTL_TEN:
1320 case OMAP_DSP_MBCMD_TCTL_TDIS:
1331 * user-defined TCTL commands
1333 else if (cmd < 0x8100) {
1334 /* 0x8000-0x80ff: no arg, non-interactive */
1337 } else if (cmd < 0x8200) {
1338 /* 0x8100-0x81ff: 1 arg, non-interactive */
1340 mbargv[0] = arg & 0xffff;
1342 } else if (cmd < 0x9000) {
1343 /* 0x8200-0x8fff: reserved */
1346 } else if (cmd < 0x9100) {
1347 /* 0x9000-0x90ff: no arg, interactive */
1350 } else if (cmd < 0x9200) {
1351 /* 0x9100-0x91ff: 1 arg, interactive */
1353 mbargv[0] = arg & 0xffff;
1355 } else if (cmd < 0x10000) {
1356 /* 0x9200-0xffff: reserved */
1365 case OMAP_DSP_TASK_IOCTL_BFLSH:
1366 ret = dsp_task_flush_buf(dev->task);
1368 case OMAP_DSP_TASK_IOCTL_SETBSZ:
1369 ret = dsp_task_set_fifosz(dev->task, arg);
1371 case OMAP_DSP_TASK_IOCTL_GETNAME:
1373 if (copy_to_user((void *)arg, dev->name,
1374 strlen(dev->name) + 1))
1386 tid = dev->task->tid;
1387 mbcmd_set(mb, MBCMD(TCTL), tid, cmd);
1389 mbarg.argc = mbargc;
1391 mbarg.argv = mbargv;
1397 dev->task->tctl_stat = -ERESTARTSYS;
1398 devstate_unlock(dev);
1400 dsp_mbcmd_send_and_wait_exarg(&mb, mbargp, &dev->ioctl_wait_q);
1401 if (signal_pending(current)) {
1405 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1409 ret = dev->task->tctl_stat;
1411 printk(KERN_ERR "omapdsp: TCTL not responding.\n");
1415 dsp_mbcmd_send_exarg(&mb, mbargp);
1420 devstate_unlock(dev);
1422 mutex_unlock(&dev->ioctl_mutex);
1426 static void dsp_task_mmap_open(struct vm_area_struct *vma)
1428 struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1429 struct dsptask *task;
1430 size_t len = vma->vm_end - vma->vm_start;
1432 BUG_ON(!(dev->state & OMAP_DSP_DEVSTATE_ATTACHED));
1434 exmap_use(task->map_base, len);
1437 static void dsp_task_mmap_close(struct vm_area_struct *vma)
1439 struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1440 struct dsptask *task;
1441 size_t len = vma->vm_end - vma->vm_start;
1443 BUG_ON(!(dev->state & OMAP_DSP_DEVSTATE_ATTACHED));
1445 exmap_unuse(task->map_base, len);
1449 * On demand page allocation is not allowed. The mapping area is defined by
1450 * corresponding DSP tasks.
1452 static struct page *dsp_task_mmap_nopage(struct vm_area_struct *vma,
1453 unsigned long address, int *type)
1455 return NOPAGE_SIGBUS;
1458 static struct vm_operations_struct dsp_task_vm_ops = {
1459 .open = dsp_task_mmap_open,
1460 .close = dsp_task_mmap_close,
1461 .nopage = dsp_task_mmap_nopage,
1464 static int dsp_task_mmap(struct file *filp, struct vm_area_struct *vma)
1467 unsigned long tmp_padr, tmp_vmadr, off;
1468 size_t req_len, tmp_len;
1469 unsigned int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
1470 struct taskdev *dev = taskdev[minor];
1471 struct dsptask *task;
1474 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0)
1475 return -ERESTARTSYS;
1479 * Don't swap this area out
1480 * Don't dump this area to a core file
1482 vma->vm_flags |= VM_RESERVED | VM_IO;
1484 /* Do not cache this area */
1485 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1487 req_len = vma->vm_end - vma->vm_start;
1488 off = vma->vm_pgoff << PAGE_SHIFT;
1489 tmp_vmadr = vma->vm_start;
1490 tmp_vadr = task->map_base + off;
1492 tmp_padr = dsp_virt_to_phys(tmp_vadr, &tmp_len);
1493 if (tmp_padr == 0) {
1495 "omapdsp: task %s: illegal address "
1496 "for mmap: %p", task->name, tmp_vadr);
1497 /* partial mapping will be cleared in upper layer */
1501 if (tmp_len > req_len)
1505 "omapdsp: mmap info: "
1506 "vmadr = %08lx, padr = %08lx, len = %x\n",
1507 tmp_vmadr, tmp_padr, tmp_len);
1508 if (remap_pfn_range(vma, tmp_vmadr, tmp_padr >> PAGE_SHIFT,
1509 tmp_len, vma->vm_page_prot) != 0) {
1511 "omapdsp: task %s: remap_page_range() failed.\n",
1513 /* partial mapping will be cleared in upper layer */
1519 tmp_vmadr += tmp_len;
1520 tmp_vadr += tmp_len;
1523 vma->vm_ops = &dsp_task_vm_ops;
1524 vma->vm_private_data = dev;
1525 exmap_use(task->map_base, vma->vm_end - vma->vm_start);
1528 devstate_unlock(dev);
1532 static int dsp_task_open(struct inode *inode, struct file *file)
1534 unsigned int minor = MINOR(inode->i_rdev);
1535 struct taskdev *dev;
1538 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL))
1540 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_NOTASK |
1541 OMAP_DSP_DEVSTATE_ATTACHED) < 0)
1542 return -ERESTARTSYS;
1543 #ifndef CONFIG_OMAP_DSP_TASK_MULTIOPEN
1544 if (dev->usecount > 0) {
1550 if (dev->state & OMAP_DSP_DEVSTATE_NOTASK) {
1551 dev->state = OMAP_DSP_DEVSTATE_ADDREQ;
1552 /* wake up twch daemon for tadd */
1554 devstate_unlock(dev);
1555 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED |
1556 OMAP_DSP_DEVSTATE_ADDFAIL) < 0) {
1557 spin_lock(&dev->state_lock);
1558 if (dev->state & OMAP_DSP_DEVSTATE_ADDREQ)
1559 dev->state = OMAP_DSP_DEVSTATE_NOTASK;
1560 spin_unlock(&dev->state_lock);
1561 return -ERESTARTSYS;
1563 if (dev->state & OMAP_DSP_DEVSTATE_ADDFAIL) {
1564 printk(KERN_ERR "omapdsp: task attach failed for %s!\n",
1567 dev->state = OMAP_DSP_DEVSTATE_NOTASK;
1568 wake_up_interruptible_all(&dev->state_wait_q);
1573 /* state_lock covers usecount, proc_list as well. */
1575 proc_list_add(&dev->proc_list, current);
1576 file->f_op = &dev->fops;
1577 devstate_unlock(dev);
1582 devstate_unlock(dev);
1586 static int dsp_task_release(struct inode *inode, struct file *file)
1588 unsigned int minor = MINOR(inode->i_rdev);
1589 struct taskdev *dev = taskdev[minor];
1591 /* state_lock covers usecount, proc_list as well. */
1592 spin_lock(&dev->state_lock);
1594 /* state can be ATTACHED, KILLING or GARBAGE here. */
1595 switch (dev->state & OMAP_DSP_DEVSTATE_STATE_MASK) {
1597 case OMAP_DSP_DEVSTATE_KILLING:
1601 case OMAP_DSP_DEVSTATE_GARBAGE:
1602 if(--dev->usecount == 0) {
1603 dev->state = OMAP_DSP_DEVSTATE_NOTASK;
1604 wake_up_interruptible_all(&dev->state_wait_q);
1608 case OMAP_DSP_DEVSTATE_ATTACHED:
1609 if (dev->lock_pid == current->pid)
1610 taskdev_unlock(dev);
1611 proc_list_del(&dev->proc_list, current);
1612 if (--dev->usecount == 0) {
1613 if (minor >= n_task) { /* dynamic task */
1614 dev->state = OMAP_DSP_DEVSTATE_DELREQ;
1615 /* wake up twch daemon for tdel */
1623 spin_unlock(&dev->state_lock);
1630 int dsp_mkdev(char *name)
1632 struct taskdev *dev;
1634 unsigned char minor;
1636 if (!dsp_is_ready()) {
1637 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1640 for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1641 if (taskdev[minor] == NULL)
1644 printk(KERN_ERR "omapdsp: Too many task devices.\n");
1648 if ((dev = kmalloc(sizeof(struct taskdev), GFP_KERNEL)) == NULL)
1650 memset(dev, 0, sizeof(struct taskdev));
1651 if ((status = taskdev_init(dev, name, minor)) < 0) {
1658 int dsp_rmdev(char *name)
1660 unsigned char minor;
1663 if (!dsp_is_ready()) {
1664 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1667 for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1668 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1669 if ((ret = dsp_rmdev_minor(minor)) < 0)
1677 static int dsp_rmdev_minor(unsigned char minor)
1679 struct taskdev *dev = taskdev[minor];
1681 spin_lock(&dev->state_lock);
1683 switch (dev->state & OMAP_DSP_DEVSTATE_STATE_MASK) {
1685 case OMAP_DSP_DEVSTATE_NOTASK:
1689 case OMAP_DSP_DEVSTATE_ATTACHED:
1690 /* task is working. kill it. */
1691 dev->state = OMAP_DSP_DEVSTATE_KILLING;
1692 proclist_send_sigbus(&dev->proc_list);
1693 spin_unlock(&dev->state_lock);
1694 dsp_tdel_bh(minor, OMAP_DSP_MBCMD_TDEL_KILL);
1697 case OMAP_DSP_DEVSTATE_ADDREQ:
1698 /* open() is waiting. drain it. */
1699 dev->state = OMAP_DSP_DEVSTATE_ADDFAIL;
1700 wake_up_interruptible_all(&dev->state_wait_q);
1703 case OMAP_DSP_DEVSTATE_DELREQ:
1704 /* nobody is waiting. */
1705 dev->state = OMAP_DSP_DEVSTATE_NOTASK;
1706 wake_up_interruptible_all(&dev->state_wait_q);
1709 case OMAP_DSP_DEVSTATE_ADDING:
1710 case OMAP_DSP_DEVSTATE_DELING:
1711 case OMAP_DSP_DEVSTATE_KILLING:
1712 case OMAP_DSP_DEVSTATE_GARBAGE:
1713 case OMAP_DSP_DEVSTATE_ADDFAIL:
1714 /* transient state. wait for a moment. */
1719 spin_unlock(&dev->state_lock);
1722 /* wait for some time and hope the state is settled */
1723 devstate_lock_timeout(dev, OMAP_DSP_DEVSTATE_NOTASK, HZ);
1724 if (!(dev->state & OMAP_DSP_DEVSTATE_NOTASK)) {
1726 "omapdsp: illegal device state (%s) on rmdev %s.\n",
1727 devstate_name(dev->state), dev->name);
1729 dev->state = OMAP_DSP_DEVSTATE_INVALID;
1730 devstate_unlock(dev);
1732 taskdev_delete(minor);
1738 struct file_operations dsp_task_fops = {
1739 .owner = THIS_MODULE,
1740 .poll = dsp_task_poll,
1741 .ioctl = dsp_task_ioctl,
1742 .open = dsp_task_open,
1743 .release = dsp_task_release,
1746 static void dsptask_dev_release(struct device *dev)
1750 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor)
1752 struct class_device *cdev;
1754 taskdev[minor] = dev;
1756 INIT_LIST_HEAD(&dev->proc_list);
1757 init_waitqueue_head(&dev->read_wait_q);
1758 init_waitqueue_head(&dev->write_wait_q);
1759 init_waitqueue_head(&dev->ioctl_wait_q);
1760 mutex_init(&dev->read_mutex);
1761 mutex_init(&dev->write_mutex);
1762 mutex_init(&dev->ioctl_mutex);
1763 mutex_init(&dev->lock);
1766 strncpy(dev->name, name, OMAP_DSP_TNM_LEN);
1767 dev->name[OMAP_DSP_TNM_LEN-1] = '\0';
1768 dev->state = (minor < n_task) ? OMAP_DSP_DEVSTATE_ATTACHED :
1769 OMAP_DSP_DEVSTATE_NOTASK;
1771 memcpy(&dev->fops, &dsp_task_fops, sizeof(struct file_operations));
1773 dev->dev.parent = &dsp_device.dev;
1774 dev->dev.bus = &dsptask_bus;
1775 sprintf(dev->dev.bus_id, "dsptask%d", minor);
1776 dev->dev.release = dsptask_dev_release;
1777 device_register(&dev->dev);
1778 device_create_file(&dev->dev, &dev_attr_devname);
1779 device_create_file(&dev->dev, &dev_attr_devstate);
1780 device_create_file(&dev->dev, &dev_attr_proc_list);
1781 cdev = class_device_create(dsp_task_class, NULL,
1782 MKDEV(OMAP_DSP_TASK_MAJOR, minor),
1783 NULL, "dsptask%d", minor);
1785 init_waitqueue_head(&dev->state_wait_q);
1786 spin_lock_init(&dev->state_lock);
1791 static void taskdev_delete(unsigned char minor)
1793 struct taskdev *dev = taskdev[minor];
1797 device_remove_file(&dev->dev, &dev_attr_devname);
1798 device_remove_file(&dev->dev, &dev_attr_devstate);
1799 device_remove_file(&dev->dev, &dev_attr_proc_list);
1800 class_device_destroy(dsp_task_class, MKDEV(OMAP_DSP_TASK_MAJOR, minor));
1801 device_unregister(&dev->dev);
1802 proc_list_flush(&dev->proc_list);
1803 taskdev[minor] = NULL;
1806 static void taskdev_attach_task(struct taskdev *dev, struct dsptask *task)
1808 unsigned short 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;
1820 rcvtyp_wd(ttyp) ? dsp_task_write_wd:
1821 /* rcvbyp_bk */ dsp_task_write_bk;
1822 if (task->map_length)
1823 dev->fops.mmap = dsp_task_mmap;
1825 device_create_file(&dev->dev, &dev_attr_taskname);
1826 device_create_file(&dev->dev, &dev_attr_ttyp);
1827 if (sndtyp_wd(ttyp)) {
1828 device_create_file(&dev->dev, &dev_attr_fifosz);
1829 device_create_file(&dev->dev, &dev_attr_fifocnt);
1831 device_create_file(&dev->dev, &dev_attr_ipblink);
1832 device_create_file(&dev->dev, &dev_attr_wsz);
1833 if (task->map_length)
1834 device_create_file(&dev->dev, &dev_attr_mmap);
1837 static void taskdev_detach_task(struct taskdev *dev)
1839 unsigned short ttyp = dev->task->ttyp;
1841 device_remove_file(&dev->dev, &dev_attr_taskname);
1842 device_remove_file(&dev->dev, &dev_attr_ttyp);
1843 if (sndtyp_wd(ttyp)) {
1844 device_remove_file(&dev->dev, &dev_attr_fifosz);
1845 device_remove_file(&dev->dev, &dev_attr_fifocnt);
1847 device_remove_file(&dev->dev, &dev_attr_ipblink);
1848 device_remove_file(&dev->dev, &dev_attr_wsz);
1849 if (dev->task->map_length)
1850 device_remove_file(&dev->dev, &dev_attr_mmap);
1854 dev->fops.read = NULL;
1855 dev->fops.write = NULL;
1856 printk(KERN_INFO "omapdsp: taskdev %s disabled.\n", dev->name);
1861 * tadd / tdel / tkill
1863 int dsp_tadd(unsigned char minor, unsigned long adr)
1865 struct taskdev *dev;
1866 struct dsptask *task;
1868 struct mb_exarg arg;
1869 unsigned char tid, tid_response;
1870 unsigned short argv[2];
1873 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
1875 "omapdsp: no task device with minor %d\n", minor);
1879 spin_lock(&dev->state_lock);
1880 if (!(dev->state & OMAP_DSP_DEVSTATE_ADDREQ)) {
1882 "omapdsp: taskdev %s is not requesting for tadd. "
1883 "(state is %s)\n", dev->name, devstate_name(dev->state));
1884 spin_unlock(&dev->state_lock);
1887 dev->state = OMAP_DSP_DEVSTATE_ADDING;
1888 spin_unlock(&dev->state_lock);
1890 if (adr == OMAP_DSP_TADD_ABORTADR) {
1891 /* aborting tadd intentionally */
1892 printk(KERN_INFO "omapdsp: tadd address is ABORTADR.\n");
1895 if (adr >= DSPSPACE_SIZE) {
1897 "omapdsp: illegal address 0x%08lx for tadd\n", adr);
1902 adr >>= 1; /* word address */
1903 argv[0] = adr >> 16; /* addrh */
1904 argv[1] = adr & 0xffff; /* addrl */
1906 if (mutex_lock_interruptible(&cfg_lock)) {
1910 cfg_tid = OMAP_DSP_TID_ANON;
1911 cfg_cmd = MBCMD(TADD);
1912 mbcmd_set(mb, MBCMD(TADD), 0, 0);
1913 arg.tid = OMAP_DSP_TID_ANON;
1917 if (dsp_mem_sync_inc() < 0) {
1918 printk(KERN_ERR "omapdsp: memory sync failed!\n");
1922 dsp_mbcmd_send_and_wait_exarg(&mb, &arg, &cfg_wait_q);
1925 cfg_tid = OMAP_DSP_TID_ANON;
1927 mutex_unlock(&cfg_lock);
1929 if (tid == OMAP_DSP_TID_ANON) {
1930 printk(KERN_ERR "omapdsp: tadd failed!\n");
1934 if ((tid < n_task) || dsptask[tid]) {
1935 printk(KERN_ERR "omapdsp: illegal tid (%d)!\n", tid);
1939 if ((task = kmalloc(sizeof(struct dsptask), GFP_KERNEL)) == NULL) {
1943 memset(task, 0, sizeof(struct dsptask));
1945 if ((ret = dsp_task_config(task, tid)) < 0)
1947 taskdev_attach_task(dev, task);
1949 if (strcmp(dev->name, task->name)) {
1951 "omapdsp: task name (%s) doesn't match with "
1952 "device name (%s).\n", task->name, dev->name);
1957 dsp_task_init(task);
1958 printk(KERN_INFO "omapdsp: taskdev %s enabled.\n", dev->name);
1959 dev->state = OMAP_DSP_DEVSTATE_ATTACHED;
1960 wake_up_interruptible_all(&dev->state_wait_q);
1967 printk(KERN_ERR "omapdsp: deleting the task...\n");
1969 dev->state = OMAP_DSP_DEVSTATE_DELING;
1971 if (mutex_lock_interruptible(&cfg_lock)) {
1972 printk(KERN_ERR "omapdsp: aborting tdel process. "
1973 "DSP side could be corrupted.\n");
1976 cfg_tid = OMAP_DSP_TID_ANON;
1977 cfg_cmd = MBCMD(TDEL);
1978 mbcmd_set(mb, MBCMD(TDEL), tid, OMAP_DSP_MBCMD_TDEL_KILL);
1979 dsp_mbcmd_send_and_wait(&mb, &cfg_wait_q);
1980 tid_response = cfg_tid;
1981 cfg_tid = OMAP_DSP_TID_ANON;
1983 mutex_unlock(&cfg_lock);
1985 if (tid_response != tid)
1986 printk(KERN_ERR "omapdsp: tdel failed. "
1987 "DSP side could be corrupted.\n");
1990 dev->state = OMAP_DSP_DEVSTATE_ADDFAIL;
1991 wake_up_interruptible_all(&dev->state_wait_q);
1995 int dsp_tdel(unsigned char minor)
1997 struct taskdev *dev;
1999 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2001 "omapdsp: no task device with minor %d\n", minor);
2004 spin_lock(&dev->state_lock);
2005 if (!(dev->state & OMAP_DSP_DEVSTATE_DELREQ)) {
2007 "omapdsp: taskdev %s is not requesting for tdel. "
2008 "(state is %s)\n", dev->name, devstate_name(dev->state));
2009 spin_unlock(&dev->state_lock);
2012 dev->state = OMAP_DSP_DEVSTATE_DELING;
2013 spin_unlock(&dev->state_lock);
2015 return dsp_tdel_bh(minor, OMAP_DSP_MBCMD_TDEL_SAFE);
2018 int dsp_tkill(unsigned char minor)
2020 struct taskdev *dev;
2022 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2024 "omapdsp: no task device with minor %d\n", minor);
2027 spin_lock(&dev->state_lock);
2028 if (!(dev->state & OMAP_DSP_DEVSTATE_ATTACHED)) {
2030 "omapdsp: task has not been attached for taskdev %s\n",
2032 spin_unlock(&dev->state_lock);
2035 dev->state = OMAP_DSP_DEVSTATE_KILLING;
2036 proclist_send_sigbus(&dev->proc_list);
2037 spin_unlock(&dev->state_lock);
2039 return dsp_tdel_bh(minor, OMAP_DSP_MBCMD_TDEL_KILL);
2042 static int dsp_tdel_bh(unsigned char minor, unsigned short type)
2044 struct taskdev *dev = taskdev[minor];
2045 struct dsptask *task;
2047 unsigned char tid, tid_response;
2052 if (mutex_lock_interruptible(&cfg_lock)) {
2053 if (type == OMAP_DSP_MBCMD_TDEL_SAFE) {
2054 dev->state = OMAP_DSP_DEVSTATE_DELREQ;
2055 return -ERESTARTSYS;
2057 tid_response = OMAP_DSP_TID_ANON;
2062 cfg_tid = OMAP_DSP_TID_ANON;
2063 cfg_cmd = MBCMD(TDEL);
2064 mbcmd_set(mb, MBCMD(TDEL), tid, type);
2065 dsp_mbcmd_send_and_wait(&mb, &cfg_wait_q);
2066 tid_response = cfg_tid;
2067 cfg_tid = OMAP_DSP_TID_ANON;
2069 mutex_unlock(&cfg_lock);
2072 taskdev_detach_task(dev);
2073 dsp_task_unconfig(task);
2076 if (tid_response != tid) {
2077 printk(KERN_ERR "omapdsp: %s failed!\n",
2078 (type == OMAP_DSP_MBCMD_TDEL_SAFE) ? "tdel" : "tkill");
2081 spin_lock(&dev->state_lock);
2082 dev->state = (dev->usecount > 0) ? OMAP_DSP_DEVSTATE_GARBAGE :
2083 OMAP_DSP_DEVSTATE_NOTASK;
2084 wake_up_interruptible_all(&dev->state_wait_q);
2085 spin_unlock(&dev->state_lock);
2093 long taskdev_state_stale(unsigned char minor)
2095 if (taskdev[minor]) {
2096 long state = taskdev[minor]->state;
2097 taskdev[minor]->state |= OMAP_DSP_DEVSTATE_STALE;
2100 return OMAP_DSP_DEVSTATE_NOTASK;
2104 * functions called from mailbox1 interrupt routine
2106 void mbx1_wdsnd(struct mbcmd *mb)
2108 unsigned char tid = mb->cmd_l;
2109 struct dsptask *task = dsptask[tid];
2111 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2112 printk(KERN_ERR "mbx: WDSND with illegal tid! %d\n", tid);
2115 if (sndtyp_bk(task->ttyp)) {
2117 "mbx: WDSND from block sending task! (task%d)\n", tid);
2120 if (sndtyp_psv(task->ttyp) &&
2121 !waitqueue_active(&task->dev->read_wait_q)) {
2123 "mbx: WDSND from passive sending task (task%d) "
2124 "without request!\n", tid);
2128 write_word_to_fifo(&task->rcvdt.fifo, mb->data);
2129 wake_up_interruptible(&task->dev->read_wait_q);
2132 void mbx1_wdreq(struct mbcmd *mb)
2134 unsigned char tid = mb->cmd_l;
2135 struct dsptask *task = dsptask[tid];
2137 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2138 printk(KERN_ERR "mbx: WDREQ with illegal tid! %d\n", tid);
2141 if (rcvtyp_psv(task->ttyp)) {
2143 "mbx: WDREQ from passive receiving task! (task%d)\n",
2148 spin_lock(&task->wsz_lock);
2150 spin_unlock(&task->wsz_lock);
2151 wake_up_interruptible(&task->dev->write_wait_q);
2154 void mbx1_bksnd(struct mbcmd *mb)
2156 unsigned char tid = mb->cmd_l;
2157 unsigned short bid = mb->data;
2158 struct dsptask *task = dsptask[tid];
2161 if (bid >= ipbcfg.ln) {
2162 printk(KERN_ERR "mbx: BKSND with illegal bid! %d\n", bid);
2165 ipb_bsycnt_dec(&ipbcfg);
2166 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2167 printk(KERN_ERR "mbx: BKSND with illegal tid! %d\n", tid);
2168 goto unuse_ipbuf_out;
2170 if (sndtyp_wd(task->ttyp)) {
2172 "mbx: BKSND from word sending task! (task%d)\n", tid);
2173 goto unuse_ipbuf_out;
2175 if (sndtyp_pvt(task->ttyp)) {
2177 "mbx: BKSND from private sending task! (task%d)\n", tid);
2178 goto unuse_ipbuf_out;
2180 if (sync_with_dsp(&ipbuf[bid]->sd, tid, 10) < 0) {
2181 printk(KERN_ERR "mbx: BKSND - IPBUF sync failed!\n");
2185 /* should be done in DSP, but just in case. */
2186 ipbuf[bid]->next = OMAP_DSP_BID_NULL;
2188 cnt = ipbuf[bid]->c;
2189 if (cnt > ipbcfg.lsz) {
2190 printk(KERN_ERR "mbx: BKSND cnt(%d) > ipbuf line size(%d)!\n",
2192 goto unuse_ipbuf_out;
2196 /* 0-byte send from DSP */
2197 unuse_ipbuf_nowait(bid);
2200 spin_lock(&task->rcvdt.bk.link.lock);
2201 ipblink_add_tail(&task->rcvdt.bk.link, bid, ipbuf);
2202 spin_unlock(&task->rcvdt.bk.link.lock);
2203 /* we keep coming bid and return alternative line to DSP. */
2207 wake_up_interruptible(&task->dev->read_wait_q);
2211 unuse_ipbuf_nowait(bid);
2215 void mbx1_bkreq(struct mbcmd *mb)
2217 unsigned char tid = mb->cmd_l;
2218 unsigned short cnt = mb->data;
2219 struct dsptask *task = dsptask[tid];
2221 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2222 printk(KERN_ERR "mbx: BKREQ with illegal tid! %d\n", tid);
2225 if (rcvtyp_wd(task->ttyp)) {
2227 "mbx: BKREQ from word receiving task! (task%d)\n", tid);
2230 if (rcvtyp_pvt(task->ttyp)) {
2232 "mbx: BKREQ from private receiving task! (task%d)\n",
2236 if (rcvtyp_psv(task->ttyp)) {
2238 "mbx: BKREQ from passive receiving task! (task%d)\n",
2243 spin_lock(&task->wsz_lock);
2245 spin_unlock(&task->wsz_lock);
2246 wake_up_interruptible(&task->dev->write_wait_q);
2249 void mbx1_bkyld(struct mbcmd *mb)
2251 unsigned short bid = mb->data;
2253 if (bid >= ipbcfg.ln) {
2254 printk(KERN_ERR "mbx: BKYLD with illegal bid! %d\n", bid);
2258 /* should be done in DSP, but just in case. */
2259 ipbuf[bid]->next = OMAP_DSP_BID_NULL;
2261 /* we don't need to sync with DSP */
2262 ipb_bsycnt_dec(&ipbcfg);
2266 void mbx1_bksndp(struct mbcmd *mb)
2268 unsigned char tid = mb->cmd_l;
2269 struct dsptask *task = dsptask[tid];
2270 struct rcvdt_bk_struct *rcvdt = &task->rcvdt.bk;
2271 struct ipbuf_p *ipbp = rcvdt->ipbuf_pvt_r;
2273 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2274 printk(KERN_ERR "mbx: BKSNDP with illegal tid! %d\n", tid);
2277 if (sndtyp_wd(task->ttyp)) {
2279 "mbx: BKSNDP from word sending task! (task%d)\n", tid);
2282 if (sndtyp_gbl(task->ttyp)) {
2284 "mbx: BKSNDP from non-private sending task! (task%d)\n",
2290 * we should not have delayed block at this point
2291 * because read() routine releases the lock of the buffer and
2292 * until then DSP can't send next data.
2295 if (sync_with_dsp(&ipbp->s, tid, 10) < 0) {
2296 printk(KERN_ERR "mbx: BKSNDP - IPBUF sync failed!\n");
2299 printk(KERN_DEBUG "mbx: ipbuf_pvt_r->a = 0x%08lx\n",
2300 MKLONG(ipbp->ah, ipbp->al));
2301 spin_lock(&rcvdt->link.lock);
2302 ipblink_add_pvt(&rcvdt->link);
2303 spin_unlock(&rcvdt->link.lock);
2304 wake_up_interruptible(&task->dev->read_wait_q);
2307 void mbx1_bkreqp(struct mbcmd *mb)
2309 unsigned char tid = mb->cmd_l;
2310 struct dsptask *task = dsptask[tid];
2311 struct ipbuf_p *ipbp = task->ipbuf_pvt_w;
2313 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2314 printk(KERN_ERR "mbx: BKREQP with illegal tid! %d\n", tid);
2317 if (rcvtyp_wd(task->ttyp)) {
2319 "mbx: BKREQP from word receiving task! (task%d)\n", tid);
2322 if (rcvtyp_gbl(task->ttyp)) {
2324 "mbx: BKREQP from non-private receiving task! (task%d)\n", tid);
2327 if (rcvtyp_psv(task->ttyp)) {
2329 "mbx: BKREQP from passive receiving task! (task%d)\n", tid);
2333 if (sync_with_dsp(&ipbp->s, OMAP_DSP_TID_FREE, 10) < 0) {
2334 printk(KERN_ERR "mbx: BKREQP - IPBUF sync failed!\n");
2337 printk(KERN_DEBUG "mbx: ipbuf_pvt_w->a = 0x%08lx\n",
2338 MKLONG(ipbp->ah, ipbp->al));
2339 spin_lock(&task->wsz_lock);
2340 task->wsz = ipbp->c*2;
2341 spin_unlock(&task->wsz_lock);
2342 wake_up_interruptible(&task->dev->write_wait_q);
2345 void mbx1_tctl(struct mbcmd *mb)
2347 unsigned char tid = mb->cmd_l;
2348 struct dsptask *task = dsptask[tid];
2350 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2351 printk(KERN_ERR "mbx: TCTL with illegal tid! %d\n", tid);
2355 if (!waitqueue_active(&task->dev->ioctl_wait_q)) {
2356 printk(KERN_WARNING "mbx: unexpected TCTL from DSP!\n");
2360 task->tctl_stat = mb->data;
2361 wake_up_interruptible(&task->dev->ioctl_wait_q);
2364 void mbx1_tcfg(struct mbcmd *mb)
2366 unsigned char tid = mb->cmd_l;
2367 struct dsptask *task = dsptask[tid];
2368 unsigned short *tnm;
2369 volatile unsigned short *buf;
2372 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2373 printk(KERN_ERR "mbx: TCFG with illegal tid! %d\n", tid);
2376 if ((task->state != TASK_STATE_CFGREQ) || (cfg_cmd != MBCMD(TCFG))) {
2377 printk(KERN_WARNING "mbx: unexpected TCFG from DSP!\n");
2381 if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2382 printk(KERN_ERR "mbx: TCFG - IPBUF sync failed!\n");
2387 * read configuration data on system IPBUF
2389 buf = ipbuf_sys_da->d;
2390 task->ttyp = buf[0];
2391 task->rcvdt.bk.ipbuf_pvt_r = MKVIRT(buf[1], buf[2]);
2392 task->ipbuf_pvt_w = MKVIRT(buf[3], buf[4]);
2393 task->map_base = MKVIRT(buf[5], buf[6]);
2394 task->map_length = MKLONG(buf[7], buf[8]) << 1; /* word -> byte */
2395 tnm = MKVIRT(buf[9], buf[10]);
2396 release_ipbuf_pvt(ipbuf_sys_da);
2399 * copy task name string
2401 if (dsp_address_validate(tnm, OMAP_DSP_TNM_LEN, "task name buffer") <0) {
2402 task->name[0] = '\0';
2406 for (i = 0; i < OMAP_DSP_TNM_LEN-1; i++) {
2407 /* avoiding byte access */
2408 unsigned short tmp = tnm[i];
2409 task->name[i] = tmp & 0x00ff;
2413 task->name[OMAP_DSP_TNM_LEN-1] = '\0';
2415 task->state = TASK_STATE_READY;
2417 wake_up_interruptible(&cfg_wait_q);
2420 void mbx1_tadd(struct mbcmd *mb)
2422 unsigned char tid = mb->cmd_l;
2424 if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBCMD(TADD))) {
2425 printk(KERN_WARNING "mbx: unexpected TADD from DSP!\n");
2429 wake_up_interruptible(&cfg_wait_q);
2432 void mbx1_tdel(struct mbcmd *mb)
2434 unsigned char tid = mb->cmd_l;
2436 if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBCMD(TDEL))) {
2437 printk(KERN_WARNING "mbx: unexpected TDEL from DSP!\n");
2441 wake_up_interruptible(&cfg_wait_q);
2444 void mbx1_err_fatal(unsigned char tid)
2446 struct dsptask *task = dsptask[tid];
2448 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2449 printk(KERN_ERR "mbx: FATAL ERR with illegal tid! %d\n", tid);
2453 spin_lock(&task->dev->state_lock);
2454 proclist_send_sigbus(&task->dev->proc_list);
2455 spin_unlock(&task->dev->state_lock);
2458 static short *dbg_buf;
2459 static unsigned short dbg_buf_sz, dbg_line_sz;
2462 int dsp_dbg_config(short *buf, unsigned short sz, unsigned short lsz)
2464 #ifdef OLD_BINARY_SUPPORT
2465 if ((mbx_revision == MBREV_3_0) || (mbx_revision == MBREV_3_2)) {
2474 if (dsp_address_validate(buf, sz, "debug buffer") < 0)
2479 "omapdsp: dbg_buf lsz (%d) is greater than its "
2480 "buffer size (%d)\n", lsz, sz);
2492 void dsp_dbg_stop(void)
2497 #ifdef OLD_BINARY_SUPPORT
2498 static void mbx1_dbg_old(struct mbcmd *mb);
2501 void mbx1_dbg(struct mbcmd *mb)
2503 unsigned char tid = mb->cmd_l;
2505 char s[80], *s_end = &s[79], *p;
2506 unsigned short *src;
2509 #ifdef OLD_BINARY_SUPPORT
2510 if ((mbx_revision == MBREV_3_0) || (mbx_revision == MBREV_3_2)) {
2516 if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2517 (tid != OMAP_DSP_TID_ANON)) {
2518 printk(KERN_ERR "mbx: DBG with illegal tid! %d\n", tid);
2521 if (dbg_buf == NULL) {
2522 printk(KERN_ERR "mbx: DBG command received, but "
2523 "dbg_buf has not been configured yet.\n");
2527 if (dsp_mem_enable(dbg_buf) < 0)
2530 src = &dbg_buf[dbg_rp];
2532 for (i = 0; i < cnt; i++) {
2535 * Be carefull that dbg_buf should not be read with
2536 * 1-byte access since it might be placed in DARAM/SARAM
2537 * and it can cause unexpected byteswap.
2539 * *(p++) = *(src++) & 0xff;
2540 * causes 1-byte access!
2543 *(p++) = tmp & 0xff;
2544 if (*(p-1) == '\n') {
2546 printk(KERN_INFO "%s", s);
2552 printk(KERN_INFO "%s\n", s);
2559 printk(KERN_INFO "%s\n", s);
2561 if ((dbg_rp += cnt + 1) > dbg_buf_sz - dbg_line_sz)
2564 dsp_mem_disable(dbg_buf);
2567 #ifdef OLD_BINARY_SUPPORT
2568 static void mbx1_dbg_old(struct mbcmd *mb)
2570 unsigned char tid = mb->cmd_l;
2571 char s[80], *s_end = &s[79], *p;
2572 unsigned short *src;
2573 volatile unsigned short *buf;
2577 if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2578 (tid != OMAP_DSP_TID_ANON)) {
2579 printk(KERN_ERR "mbx: DBG with illegal tid! %d\n", tid);
2582 if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2583 printk(KERN_ERR "mbx: DBG - IPBUF sync failed!\n");
2586 buf = ipbuf_sys_da->d;
2588 src = MKVIRT(buf[1], buf[2]);
2589 if (dsp_address_validate(src, cnt, "dbg buffer") < 0)
2592 if (dsp_mem_enable(src) < 0)
2596 for (i = 0; i < cnt; i++) {
2599 * Be carefull that ipbuf should not be read with
2600 * 1-byte access since it might be placed in DARAM/SARAM
2601 * and it can cause unexpected byteswap.
2603 * *(p++) = *(src++) & 0xff;
2604 * causes 1-byte access!
2607 *(p++) = tmp & 0xff;
2608 if (*(p-1) == '\n') {
2610 printk(KERN_INFO "%s", s);
2616 printk(KERN_INFO "%s\n", s);
2623 printk(KERN_INFO "%s\n", s);
2626 release_ipbuf_pvt(ipbuf_sys_da);
2627 dsp_mem_disable(src);
2629 #endif /* OLD_BINARY_SUPPORT */
2634 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
2637 struct taskdev *dev = to_taskdev(d);
2638 return sprintf(buf, "%s\n", dev->name);
2641 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
2644 struct taskdev *dev = to_taskdev(d);
2645 return sprintf(buf, "%s\n", devstate_name(dev->state));
2648 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
2651 struct taskdev *dev;
2652 struct proc_list *pl;
2655 dev = to_taskdev(d);
2656 spin_lock(&dev->state_lock);
2657 list_for_each_entry(pl, &dev->proc_list, list_head) {
2658 len += sprintf(buf + len, "%d\n", pl->pid);
2660 spin_unlock(&dev->state_lock);
2665 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
2668 struct taskdev *dev = to_taskdev(d);
2671 len = sprintf(buf, "%s\n", dev->task->name);
2676 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
2679 unsigned short ttyp = to_taskdev(d)->task->ttyp;
2682 len += sprintf(buf + len, "0x%04x\n", ttyp);
2683 len += sprintf(buf + len, "%s %s send\n",
2684 (sndtyp_acv(ttyp)) ? "active" :
2686 (sndtyp_wd(ttyp)) ? "word" :
2687 (sndtyp_pvt(ttyp)) ? "private block" :
2689 len += sprintf(buf + len, "%s %s receive\n",
2690 (rcvtyp_acv(ttyp)) ? "active" :
2692 (rcvtyp_wd(ttyp)) ? "word" :
2693 (rcvtyp_pvt(ttyp)) ? "private block" :
2699 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
2702 struct fifo_struct *fifo = &to_taskdev(d)->task->rcvdt.fifo;
2703 return sprintf(buf, "%d\n", fifo->sz);
2706 static int fifosz_store(struct device *d, struct device_attribute *attr,
2707 const char *buf, size_t count)
2709 struct dsptask *task = to_taskdev(d)->task;
2710 unsigned long fifosz;
2713 fifosz = simple_strtol(buf, NULL, 10);
2714 ret = dsp_task_set_fifosz(task, fifosz);
2716 return (ret < 0) ? ret : strlen(buf);
2719 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
2722 struct fifo_struct *fifo = &to_taskdev(d)->task->rcvdt.fifo;
2723 return sprintf(buf, "%d\n", fifo->cnt);
2726 static __inline__ char *bid_name(unsigned short bid)
2731 case OMAP_DSP_BID_NULL:
2733 case OMAP_DSP_BID_PVT:
2736 sprintf(s, "%d", bid);
2741 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
2744 struct rcvdt_bk_struct *rcvdt = &to_taskdev(d)->task->rcvdt.bk;
2747 spin_lock(&rcvdt->link.lock);
2748 len = sprintf(buf, "top %s\ntail %s\n",
2749 bid_name(rcvdt->link.top), bid_name(rcvdt->link.tail));
2750 spin_unlock(&rcvdt->link.lock);
2755 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
2758 return sprintf(buf, "%d\n", to_taskdev(d)->task->wsz);
2761 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
2764 struct dsptask *task = to_taskdev(d)->task;
2765 return sprintf(buf, "0x%p 0x%x\n", task->map_base, task->map_length);
2769 * called from ipbuf_read_proc()
2771 int ipbuf_is_held(unsigned char tid, unsigned short bid)
2773 struct dsptask *task = dsptask[tid];
2780 spin_lock(&task->rcvdt.bk.link.lock);
2781 ipblink_for_each(b, &task->rcvdt.bk.link, ipbuf) {
2782 if (b == bid) { /* found */
2787 spin_unlock(&task->rcvdt.bk.link.lock);
2792 int __init dsp_taskmod_init(void)
2796 memset(taskdev, 0, sizeof(void *) * TASKDEV_MAX);
2797 memset(dsptask, 0, sizeof(void *) * TASKDEV_MAX);
2799 retval = register_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask",
2803 "omapdsp: failed to register task device: %d\n", retval);
2807 bus_register(&dsptask_bus);
2808 retval = driver_register(&dsptask_driver);
2811 "omapdsp: failed to register DSP task driver: %d\n",
2813 bus_unregister(&dsptask_bus);
2814 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
2817 dsp_task_class = class_create(THIS_MODULE, "dsptask");
2822 void dsp_taskmod_exit(void)
2824 class_destroy(dsp_task_class);
2825 driver_unregister(&dsptask_driver);
2826 bus_unregister(&dsptask_bus);
2827 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");