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 <asm/uaccess.h>
41 #include <asm/signal.h>
43 #include <asm/ioctls.h>
44 #include <asm/arch/dsp.h>
45 #include "uaccess_dsp.h"
51 #define is_aligned(adr,align) (!((adr)&((align)-1)))
54 * taskdev.state: device state machine
55 * NOTASK: task is not attached.
56 * ATTACHED: task is attached.
57 * GARBAGE: task is detached. waiting for all processes to close this device.
58 * ADDREQ: requesting for tadd
59 * DELREQ: requesting for tdel. no process is opening this device.
60 * ADDFAIL: tadd failed.
61 * ADDING: tadd in process.
62 * DELING: tdel in process.
63 * KILLING: tkill in process.
65 #define devstate_name(stat) (\
66 ((stat) & OMAP_DSP_DEVSTATE_NOTASK) ? "NOTASK" :\
67 ((stat) & OMAP_DSP_DEVSTATE_ATTACHED) ? "ATTACHED" :\
68 ((stat) & OMAP_DSP_DEVSTATE_GARBAGE) ? "GARBAGE" :\
69 ((stat) & OMAP_DSP_DEVSTATE_INVALID) ? "INVALID" :\
70 ((stat) & OMAP_DSP_DEVSTATE_ADDREQ) ? "ADDREQ" :\
71 ((stat) & OMAP_DSP_DEVSTATE_DELREQ) ? "DELREQ" :\
72 ((stat) & OMAP_DSP_DEVSTATE_ADDFAIL) ? "ADDFAIL" :\
73 ((stat) & OMAP_DSP_DEVSTATE_ADDING) ? "ADDING" :\
74 ((stat) & OMAP_DSP_DEVSTATE_DELING) ? "DELING" :\
75 ((stat) & OMAP_DSP_DEVSTATE_KILLING) ? "KILLING" :\
80 // struct device_driver *driver;
81 struct device dev; /* Generic device interface */
84 spinlock_t state_lock;
85 wait_queue_head_t state_wait_q;
86 unsigned int usecount;
87 char name[OMAP_DSP_TNM_LEN];
88 struct file_operations fops;
89 struct list_head proc_list;
93 wait_queue_head_t read_wait_q;
94 struct semaphore read_sem;
97 wait_queue_head_t write_wait_q;
98 struct semaphore write_sem;
101 wait_queue_head_t ioctl_wait_q;
102 struct semaphore ioctl_sem;
105 struct semaphore lock_sem;
109 #define to_taskdev(n) container_of(n, struct taskdev, dev)
111 struct rcvdt_bk_struct {
114 struct ipbuf_p *ipbuf_pvt_r;
124 char name[OMAP_DSP_TNM_LEN];
130 struct fifo_struct fifo; /* for active word */
131 struct rcvdt_bk_struct bk;
137 struct ipbuf_p *ipbuf_pvt_w; /* for private block */
147 #define sndtyp_acv(ttyp) ((ttyp) & OMAP_DSP_TTYP_ASND)
148 #define sndtyp_psv(ttyp) (!((ttyp) & OMAP_DSP_TTYP_ASND))
149 #define sndtyp_bk(ttyp) ((ttyp) & OMAP_DSP_TTYP_BKDM)
150 #define sndtyp_wd(ttyp) (!((ttyp) & OMAP_DSP_TTYP_BKDM))
151 #define sndtyp_pvt(ttyp) ((ttyp) & OMAP_DSP_TTYP_PVDM)
152 #define sndtyp_gbl(ttyp) (!((ttyp) & OMAP_DSP_TTYP_PVDM))
153 #define rcvtyp_acv(ttyp) ((ttyp) & OMAP_DSP_TTYP_ARCV)
154 #define rcvtyp_psv(ttyp) (!((ttyp) & OMAP_DSP_TTYP_ARCV))
155 #define rcvtyp_bk(ttyp) ((ttyp) & OMAP_DSP_TTYP_BKMD)
156 #define rcvtyp_wd(ttyp) (!((ttyp) & OMAP_DSP_TTYP_BKMD))
157 #define rcvtyp_pvt(ttyp) ((ttyp) & OMAP_DSP_TTYP_PVMD)
158 #define rcvtyp_gbl(ttyp) (!((ttyp) & OMAP_DSP_TTYP_PVMD))
160 static int dsp_rmdev_minor(unsigned char minor);
161 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor);
162 static void taskdev_delete(unsigned char minor);
163 static void taskdev_attach_task(struct taskdev *dev, struct dsptask *task);
164 static void taskdev_detach_task(struct taskdev *dev);
165 static int dsp_tdel_bh(unsigned char minor, unsigned short type);
167 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
169 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
171 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
173 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
175 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
177 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
179 static int fifosz_store(struct device *d, struct device_attribute *attr,
180 const char *buf, size_t count);
181 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
183 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
185 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
187 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
190 static struct device_attribute dev_attr_devname = __ATTR_RO(devname);
191 static struct device_attribute dev_attr_devstate = __ATTR_RO(devstate);
192 static struct device_attribute dev_attr_proc_list = __ATTR_RO(proc_list);
193 static struct device_attribute dev_attr_fifosz =
194 __ATTR(fifosz, S_IWUGO | S_IRUGO, fifosz_show, fifosz_store);
195 static struct device_attribute dev_attr_fifocnt = __ATTR_RO(fifocnt);
196 static struct device_attribute dev_attr_taskname = __ATTR_RO(taskname);
197 static struct device_attribute dev_attr_ttyp = __ATTR_RO(ttyp);
198 static struct device_attribute dev_attr_ipblink = __ATTR_RO(ipblink);
199 static struct device_attribute dev_attr_wsz = __ATTR_RO(wsz);
200 static struct device_attribute dev_attr_mmap = __ATTR_RO(mmap);
202 static struct bus_type dsptask_bus = {
206 static struct class *dsp_task_class;
207 static struct taskdev *taskdev[TASKDEV_MAX];
208 static struct dsptask *dsptask[TASKDEV_MAX];
209 static DECLARE_MUTEX(cfg_sem);
210 static unsigned short cfg_cmd;
211 static unsigned char cfg_tid;
212 static DECLARE_WAIT_QUEUE_HEAD(cfg_wait_q);
213 static unsigned char n_task;
216 #define devstate_lock(dev, devstate) devstate_lock_timeout(dev, devstate, 0)
219 * devstate_lock_timeout():
220 * when called with timeout > 0, dev->state can be diffeent from what you want.
222 static int devstate_lock_timeout(struct taskdev *dev, long devstate,
225 DECLARE_WAITQUEUE(wait, current);
226 long current_state = current->state;
229 spin_lock(&dev->state_lock);
230 add_wait_queue(&dev->state_wait_q, &wait);
231 while (!(dev->state & devstate)) {
232 set_current_state(TASK_INTERRUPTIBLE);
233 spin_unlock(&dev->state_lock);
235 if ((timeout = schedule_timeout(timeout)) == 0) {
237 spin_lock(&dev->state_lock);
243 if (signal_pending(current)) {
247 spin_lock(&dev->state_lock);
249 remove_wait_queue(&dev->state_wait_q, &wait);
250 set_current_state(current_state);
254 static __inline__ void devstate_unlock(struct taskdev *dev)
256 spin_unlock(&dev->state_lock);
259 static __inline__ int down_tasksem_interruptible(struct taskdev *dev,
260 struct semaphore *sem)
264 if (dev->lock_pid == current->pid) {
265 /* this process has lock */
266 ret = down_interruptible(sem);
268 if ((ret = down_interruptible(&dev->lock_sem)) != 0)
270 ret = down_interruptible(sem);
276 static void proclist_send_sigbus(struct list_head *list)
279 struct proc_list *pl;
280 struct task_struct *tsk;
282 info.si_signo = SIGBUS;
284 info.si_code = SI_KERNEL;
285 info._sifields._sigfault._addr = NULL;
287 /* need to lock tasklist_lock before calling find_task_by_pid_type. */
288 read_lock(&tasklist_lock);
289 list_for_each_entry(pl, list, list_head) {
290 if ((tsk = find_task_by_pid_type(PIDTYPE_PID, pl->pid)) != NULL)
291 send_sig_info(SIGBUS, &info, tsk);
293 read_unlock(&tasklist_lock);
296 static int dsp_task_flush_buf(struct dsptask *task)
298 unsigned short ttyp = task->ttyp;
300 if (sndtyp_wd(ttyp)) {
302 flush_fifo(&task->rcvdt.fifo);
304 /* block receiving */
305 struct rcvdt_bk_struct *rcvdt = &task->rcvdt.bk;
307 spin_lock(&rcvdt->link.lock);
308 if (sndtyp_gbl(ttyp)) {
310 while (!ipblink_empty(&rcvdt->link)) {
311 unsigned short bid = rcvdt->link.top;
312 ipblink_del_top(&rcvdt->link, ipbuf);
317 if (!ipblink_empty(&rcvdt->link)) {
318 ipblink_del_pvt(&rcvdt->link);
319 release_ipbuf_pvt(rcvdt->ipbuf_pvt_r);
322 spin_unlock(&rcvdt->link.lock);
328 static int dsp_task_set_fifosz(struct dsptask *task, unsigned long sz)
330 unsigned short ttyp = task->ttyp;
333 if (!(sndtyp_wd(ttyp) && sndtyp_acv(ttyp))) {
335 "omapdsp: buffer size can be changed only for "
336 "active word sending task.\n");
339 if ((sz == 0) || (sz & 1)) {
340 printk(KERN_ERR "omapdsp: illegal buffer size! (%ld)\n"
341 "it must be even and non-zero value.\n", sz);
345 stat = realloc_fifo(&task->rcvdt.fifo, sz);
346 if (stat == -EBUSY) {
347 printk(KERN_ERR "omapdsp: buffer is not empty!\n");
349 } else if (stat < 0) {
351 "omapdsp: unable to change receive buffer size. "
352 "(%ld bytes for %s)\n", sz, task->name);
359 static int taskdev_lock(struct taskdev *dev)
361 if (down_interruptible(&dev->lock_sem))
363 dev->lock_pid = current->pid;
367 static int taskdev_unlock(struct taskdev *dev)
369 if (dev->lock_pid != current->pid) {
371 "omapdsp: an illegal process attempted to "
372 "unlock the dsptask lock!\n");
380 static int dsp_task_config(struct dsptask *task, unsigned char tid)
390 task->state = TASK_STATE_CFGREQ;
391 if (down_interruptible(&cfg_sem)) {
395 cfg_cmd = MBCMD(TCFG);
396 mbcmd_set(mb, MBCMD(TCFG), tid, 0);
397 dsp_mbcmd_send_and_wait(&mb, &cfg_wait_q);
401 if (task->state != TASK_STATE_READY) {
402 printk(KERN_ERR "omapdsp: task %d configuration error!\n", tid);
407 if (strlen(task->name) <= 1)
408 sprintf(task->name, "%d", tid);
409 printk(KERN_INFO "omapdsp: task %d: name %s\n", tid, task->name);
414 * task info sanity check
417 /* task type check */
418 if (rcvtyp_psv(ttyp) && rcvtyp_pvt(ttyp)) {
419 printk(KERN_ERR "omapdsp: illegal task type(0x%04x), tid=%d\n",
425 /* private buffer address check */
426 if (sndtyp_pvt(ttyp) &&
427 (ipbuf_p_validate(task->rcvdt.bk.ipbuf_pvt_r, DIR_D2A) < 0)) {
431 if (rcvtyp_pvt(ttyp) &&
432 (ipbuf_p_validate(task->ipbuf_pvt_w, DIR_A2D) < 0)) {
437 /* mmap buffer configuration check */
438 if ((task->map_length > 0) &&
439 ((!is_aligned((unsigned long)task->map_base, PAGE_SIZE)) ||
440 (!is_aligned(task->map_length, PAGE_SIZE)) ||
441 (dsp_mem_type(task->map_base, task->map_length) != MEM_TYPE_EXTERN))) {
443 "omapdsp: illegal mmap buffer address(0x%p) or "
445 " It needs to be page-aligned and located at "
446 "external memory.\n",
447 task->map_base, task->map_length);
456 /* read initialization */
457 if (sndtyp_wd(ttyp)) {
461 fifosz = sndtyp_psv(ttyp) ? 2 : /* passive */
463 if (init_fifo(&task->rcvdt.fifo, fifosz) < 0) {
465 "omapdsp: unable to allocate receive buffer. "
466 "(%d bytes for %s)\n", fifosz, task->name);
472 INIT_IPBLINK(&task->rcvdt.bk.link);
473 task->rcvdt.bk.rp = 0;
476 /* write initialization */
477 spin_lock_init(&task->wsz_lock);
478 task->wsz = rcvtyp_acv(ttyp) ? 0 : /* active */
479 rcvtyp_wd(ttyp) ? 2 : /* passive word */
480 ipbcfg.lsz*2; /* passive block */
489 static void dsp_task_init(struct dsptask *task)
491 dsp_mbsend(MBCMD(TCTL), task->tid, OMAP_DSP_MBCMD_TCTL_TINIT);
494 int dsp_task_config_all(unsigned char n)
497 struct taskdev *devheap;
498 struct dsptask *taskheap;
499 size_t devheapsz, taskheapsz;
501 memset(taskdev, 0, sizeof(void *) * TASKDEV_MAX);
502 memset(dsptask, 0, sizeof(void *) * TASKDEV_MAX);
505 printk(KERN_INFO "omapdsp: found %d task(s)\n", n_task);
512 devheapsz = sizeof(struct taskdev) * n_task;
513 taskheapsz = sizeof(struct dsptask) * n_task;
514 heap = kmalloc(devheapsz + taskheapsz, GFP_KERNEL);
519 memset(heap, 0, devheapsz + taskheapsz);
521 taskheap = heap + devheapsz;
523 for (i = 0; i < n_task; i++) {
524 struct taskdev *dev = &devheap[i];
525 struct dsptask *task = &taskheap[i];
527 if ((ret = dsp_task_config(task, i)) < 0)
529 if ((ret = taskdev_init(dev, task->name, i)) < 0)
531 taskdev_attach_task(dev, task);
533 printk(KERN_INFO "omapdsp: taskdev %s enabled.\n", dev->name);
539 static void dsp_task_unconfig(struct dsptask *task)
541 unsigned char tid = task->tid;
544 dsp_task_flush_buf(task);
545 if (sndtyp_wd(task->ttyp) && (task->state == TASK_STATE_READY))
546 free_fifo(&task->rcvdt.fifo);
551 void dsp_task_unconfig_all(void)
555 struct dsptask *task;
557 for (minor = 0; minor < n_task; minor++) {
559 * taskdev[minor] can be NULL in case of
560 * configuration failure
563 taskdev_delete(minor);
565 for (; minor < TASKDEV_MAX; minor++) {
567 dsp_rmdev_minor(minor);
570 for (tid = 0; tid < n_task; tid++) {
572 * dsptask[tid] can be NULL in case of
573 * configuration failure
577 dsp_task_unconfig(task);
579 for (; tid < TASKDEV_MAX; tid++) {
583 * on-demand tasks should be deleted in
584 * rmdev_minor(), but just in case.
586 dsp_task_unconfig(task);
599 static struct device_driver dsptask_driver = {
604 unsigned char dsp_task_count(void)
609 int dsp_taskmod_busy(void)
614 for (minor = 0; minor < TASKDEV_MAX; minor++) {
615 dev = taskdev[minor];
618 if (dev->usecount > 0) {
619 printk("dsp_taskmod_busy(): %s: usecount=%d\n",
620 dev->name, dev->usecount);
624 if ((dev->state & (OMAP_DSP_DEVSTATE_ADDREQ |
625 OMAP_DSP_DEVSTATE_DELREQ)) {
627 if (dev->state & OMAP_DSP_DEVSTATE_ADDREQ) {
628 printk("dsp_taskmod_busy(): %s is in %s\n",
629 dev->name, devstate_name(dev->state));
637 * DSP task device file operations
639 static ssize_t dsp_task_read_wd_acv(struct file *file, char *buf, size_t count,
642 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
643 struct taskdev *dev = taskdev[minor];
644 int have_devstate_lock = 0;
649 } else if (count & 0x1) {
651 "omapdsp: odd count is illegal for DSP task device.\n");
655 if (down_tasksem_interruptible(dev, &dev->read_sem))
657 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
661 have_devstate_lock = 1;
663 if (fifo_empty(&dev->task->rcvdt.fifo)) {
664 long current_state = current->state;
665 DECLARE_WAITQUEUE(wait, current);
667 set_current_state(TASK_INTERRUPTIBLE);
668 add_wait_queue(&dev->read_wait_q, &wait);
669 if (fifo_empty(&dev->task->rcvdt.fifo)) { /* last check */
670 devstate_unlock(dev);
671 have_devstate_lock = 0;
674 set_current_state(current_state);
675 remove_wait_queue(&dev->read_wait_q, &wait);
676 if (signal_pending(current)) {
680 if (!have_devstate_lock) {
681 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
685 have_devstate_lock = 1;
687 if (fifo_empty(&dev->task->rcvdt.fifo)) /* should not occur */
691 ret = copy_to_user_fm_fifo(buf, &dev->task->rcvdt.fifo, count);
694 if (have_devstate_lock)
695 devstate_unlock(dev);
700 static ssize_t dsp_task_read_bk_acv(struct file *file, char *buf, size_t count,
703 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
704 struct taskdev *dev = taskdev[minor];
705 struct rcvdt_bk_struct *rcvdt;
706 int have_devstate_lock = 0;
711 } else if (count & 0x1) {
713 "omapdsp: odd count is illegal for DSP task device.\n");
715 } else if ((int)buf & 0x1) {
717 "omapdsp: buf should be word aligned for "
718 "dsp_task_read().\n");
722 if (down_tasksem_interruptible(dev, &dev->read_sem))
724 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
728 have_devstate_lock = 1;
730 if (ipblink_empty(&dev->task->rcvdt.bk.link)) {
732 DECLARE_WAITQUEUE(wait, current);
734 add_wait_queue(&dev->read_wait_q, &wait);
735 current_state = current->state;
736 set_current_state(TASK_INTERRUPTIBLE);
737 if (ipblink_empty(&dev->task->rcvdt.bk.link)) { /* last check */
738 devstate_unlock(dev);
739 have_devstate_lock = 0;
742 set_current_state(current_state);
743 remove_wait_queue(&dev->read_wait_q, &wait);
744 if (signal_pending(current)) {
748 if (!have_devstate_lock) {
749 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
753 have_devstate_lock = 1;
755 /* signal or 0-byte send from DSP */
756 if (ipblink_empty(&dev->task->rcvdt.bk.link))
760 rcvdt = &dev->task->rcvdt.bk;
761 /* copy from delayed IPBUF */
762 if (sndtyp_pvt(dev->task->ttyp)) {
764 if (!ipblink_empty(&rcvdt->link)) {
765 struct ipbuf_p *ipbp = rcvdt->ipbuf_pvt_r;
766 unsigned char *base, *src;
769 if (dsp_mem_enable(ipbp) < 0) {
773 base = MKVIRT(ipbp->ah, ipbp->al);
774 bkcnt = ((unsigned long)ipbp->c) * 2 - rcvdt->rp;
775 if (dsp_address_validate(base, bkcnt,
776 "task %s read buffer",
777 dev->task->name) < 0) {
781 if (dsp_mem_enable(base) < 0) {
785 src = base + rcvdt->rp;
787 if (copy_to_user_dsp(buf, src, count)) {
794 if (copy_to_user_dsp(buf, src, bkcnt)) {
799 spin_lock(&rcvdt->link.lock);
800 ipblink_del_pvt(&rcvdt->link);
801 spin_unlock(&rcvdt->link.lock);
802 release_ipbuf_pvt(ipbp);
806 dsp_mem_disable(src);
808 dsp_mem_disable(ipbp);
812 if (dsp_mem_enable_ipbuf() < 0) {
816 while (!ipblink_empty(&rcvdt->link)) {
819 unsigned short bid = rcvdt->link.top;
820 struct ipbuf *ipbp = ipbuf[bid];
822 src = ipbp->d + rcvdt->rp;
823 bkcnt = ((unsigned long)ipbp->c) * 2 - rcvdt->rp;
825 if (copy_to_user_dsp(buf, src, count)) {
833 if (copy_to_user_dsp(buf, src, bkcnt)) {
840 spin_lock(&rcvdt->link.lock);
841 ipblink_del_top(&rcvdt->link, ipbuf);
842 spin_unlock(&rcvdt->link.lock);
848 dsp_mem_disable_ipbuf();
852 if (have_devstate_lock)
853 devstate_unlock(dev);
858 static ssize_t dsp_task_read_wd_psv(struct file *file, char *buf, size_t count,
861 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
862 struct taskdev *dev = taskdev[minor];
869 } else if (count & 0x1) {
871 "omapdsp: odd count is illegal for DSP task device.\n");
878 if (down_tasksem_interruptible(dev, &dev->read_sem))
880 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
884 tid = dev->task->tid;
885 devstate_unlock(dev);
887 mbcmd_set(mb, MBCMD(WDREQ), tid, 0);
888 dsp_mbcmd_send_and_wait(&mb, &dev->read_wait_q);
890 if (signal_pending(current)) {
894 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
898 if (fifo_empty(&dev->task->rcvdt.fifo)) /* should not occur */
901 ret = copy_to_user_fm_fifo(buf, &dev->task->rcvdt.fifo, count);
904 devstate_unlock(dev);
910 static ssize_t dsp_task_read_bk_psv(struct file *file, char *buf, size_t count,
913 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
914 struct taskdev *dev = taskdev[minor];
915 struct rcvdt_bk_struct *rcvdt;
922 } else if (count & 0x1) {
924 "omapdsp: odd count is illegal for DSP task device.\n");
926 } else if ((int)buf & 0x1) {
928 "omapdsp: buf should be word aligned for "
929 "dsp_task_read().\n");
933 if (down_tasksem_interruptible(dev, &dev->read_sem))
935 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
939 tid = dev->task->tid;
940 devstate_unlock(dev);
942 mbcmd_set(mb, MBCMD(BKREQ), tid, count/2);
943 dsp_mbcmd_send_and_wait(&mb, &dev->read_wait_q);
945 if (signal_pending(current)) {
949 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
953 rcvdt = &dev->task->rcvdt.bk;
954 /* signal or 0-byte send from DSP */
955 if (ipblink_empty(&rcvdt->link))
959 * We will not receive more than requested count.
961 if (sndtyp_pvt(dev->task->ttyp)) {
963 struct ipbuf_p *ipbp = rcvdt->ipbuf_pvt_r;
967 if (dsp_mem_enable(ipbp) < 0) {
971 src = MKVIRT(ipbp->ah, ipbp->al);
972 rcvcnt = ((unsigned long)ipbp->c) * 2;
973 if (dsp_address_validate(src, rcvcnt, "task %s read buffer",
974 dev->task->name) < 0) {
978 if (dsp_mem_enable(src) < 0) {
984 if (copy_to_user_dsp(buf, src, count)) {
988 spin_lock(&rcvdt->link.lock);
989 ipblink_del_pvt(&rcvdt->link);
990 spin_unlock(&rcvdt->link.lock);
991 release_ipbuf_pvt(ipbp);
994 dsp_mem_disable(src);
996 dsp_mem_disable(ipbp);
999 unsigned short bid = rcvdt->link.top;
1000 struct ipbuf *ipbp = ipbuf[bid];
1003 if (dsp_mem_enable_ipbuf() < 0) {
1007 rcvcnt = ((unsigned long)ipbp->c) * 2;
1010 if (copy_to_user_dsp(buf, ipbp->d, count)) {
1014 spin_lock(&rcvdt->link.lock);
1015 ipblink_del_top(&rcvdt->link, ipbuf);
1016 spin_unlock(&rcvdt->link.lock);
1020 dsp_mem_disable_ipbuf();
1024 devstate_unlock(dev);
1030 static ssize_t dsp_task_write_wd(struct file *file, const char *buf,
1031 size_t count, loff_t *ppos)
1033 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1034 struct taskdev *dev = taskdev[minor];
1036 int have_devstate_lock = 0;
1041 } else if (count & 0x1) {
1043 "omapdsp: odd count is illegal for DSP task device.\n");
1050 if (down_tasksem_interruptible(dev, &dev->write_sem))
1051 return -ERESTARTSYS;
1052 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1056 have_devstate_lock = 1;
1058 if (dev->task->wsz == 0) {
1060 DECLARE_WAITQUEUE(wait, current);
1062 add_wait_queue(&dev->write_wait_q, &wait);
1063 current_state = current->state;
1064 set_current_state(TASK_INTERRUPTIBLE);
1065 if (dev->task->wsz == 0) { /* last check */
1066 devstate_unlock(dev);
1067 have_devstate_lock = 0;
1070 set_current_state(current_state);
1071 remove_wait_queue(&dev->write_wait_q, &wait);
1072 if (signal_pending(current)) {
1076 if (!have_devstate_lock) {
1077 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1081 have_devstate_lock = 1;
1083 if (dev->task->wsz == 0) /* should not occur */
1087 if (copy_from_user(&wd, buf, count)) {
1092 spin_lock(&dev->task->wsz_lock);
1093 if (dsp_mbsend(MBCMD(WDSND), dev->task->tid, wd) < 0) {
1094 spin_unlock(&dev->task->wsz_lock);
1098 if (rcvtyp_acv(dev->task->ttyp))
1100 spin_unlock(&dev->task->wsz_lock);
1103 if (have_devstate_lock)
1104 devstate_unlock(dev);
1105 up(&dev->write_sem);
1109 static ssize_t dsp_task_write_bk(struct file *file, const char *buf,
1110 size_t count, loff_t *ppos)
1112 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1113 struct taskdev *dev = taskdev[minor];
1114 int have_devstate_lock = 0;
1119 } else if (count & 0x1) {
1121 "omapdsp: odd count is illegal for DSP task device.\n");
1123 } else if ((int)buf & 0x1) {
1125 "omapdsp: buf should be word aligned for "
1126 "dsp_task_write().\n");
1130 if (down_tasksem_interruptible(dev, &dev->write_sem))
1131 return -ERESTARTSYS;
1132 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1136 have_devstate_lock = 1;
1138 if (dev->task->wsz == 0) {
1140 DECLARE_WAITQUEUE(wait, current);
1142 add_wait_queue(&dev->write_wait_q, &wait);
1143 current_state = current->state;
1144 set_current_state(TASK_INTERRUPTIBLE);
1145 if (dev->task->wsz == 0) { /* last check */
1146 devstate_unlock(dev);
1147 have_devstate_lock = 0;
1150 set_current_state(current_state);
1151 remove_wait_queue(&dev->write_wait_q, &wait);
1152 if (signal_pending(current)) {
1156 if (!have_devstate_lock) {
1157 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1161 have_devstate_lock = 1;
1163 if (dev->task->wsz == 0) /* should not occur */
1167 if (count > dev->task->wsz)
1168 count = dev->task->wsz;
1170 if (rcvtyp_pvt(dev->task->ttyp)) {
1172 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_w;
1175 if (dsp_mem_enable(ipbp) < 0) {
1179 dst = MKVIRT(ipbp->ah, ipbp->al);
1180 if (dsp_address_validate(dst, count, "task %s write buffer",
1181 dev->task->name) < 0) {
1185 if (dsp_mem_enable(dst) < 0) {
1189 if (copy_from_user_dsp(dst, buf, count)) {
1194 ipbp->s = dev->task->tid;
1195 spin_lock(&dev->task->wsz_lock);
1196 if (dsp_mbsend(MBCMD(BKSNDP), dev->task->tid, 0) == 0) {
1197 if (rcvtyp_acv(dev->task->ttyp))
1201 spin_unlock(&dev->task->wsz_lock);
1203 dsp_mem_disable(dst);
1205 dsp_mem_disable(ipbp);
1211 if (dsp_mem_enable_ipbuf() < 0) {
1215 bid = get_free_ipbuf(dev->task->tid);
1216 if (bid == OMAP_DSP_BID_NULL)
1219 if (copy_from_user_dsp(ipbp->d, buf, count)) {
1225 ipbp->sa = dev->task->tid;
1226 spin_lock(&dev->task->wsz_lock);
1227 if (dsp_mbsend(MBCMD(BKSND), dev->task->tid, bid) == 0) {
1228 if (rcvtyp_acv(dev->task->ttyp))
1231 ipb_bsycnt_inc(&ipbcfg);
1234 spin_unlock(&dev->task->wsz_lock);
1236 dsp_mem_disable_ipbuf();
1240 if (have_devstate_lock)
1241 devstate_unlock(dev);
1242 up(&dev->write_sem);
1246 static unsigned int dsp_task_poll(struct file * file, poll_table * wait)
1248 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1249 struct taskdev *dev = taskdev[minor];
1250 struct dsptask *task = dev->task;
1251 unsigned int mask = 0;
1253 poll_wait(file, &dev->read_wait_q, wait);
1254 poll_wait(file, &dev->write_wait_q, wait);
1255 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0)
1257 if (sndtyp_psv(task->ttyp) ||
1258 (sndtyp_wd(task->ttyp) && !fifo_empty(&task->rcvdt.fifo)) ||
1259 (sndtyp_bk(task->ttyp) && !ipblink_empty(&task->rcvdt.bk.link)))
1260 mask |= POLLIN | POLLRDNORM;
1262 mask |= POLLOUT | POLLWRNORM;
1263 devstate_unlock(dev);
1268 static int dsp_task_ioctl(struct inode *inode, struct file *file,
1269 unsigned int cmd, unsigned long arg)
1271 unsigned int minor = MINOR(inode->i_rdev);
1272 struct taskdev *dev = taskdev[minor];
1275 struct mb_exarg mbarg, *mbargp;
1277 unsigned short mbargv[1];
1281 /* LOCK / UNLOCK operations */
1283 case OMAP_DSP_TASK_IOCTL_LOCK:
1284 return taskdev_lock(dev);
1285 case OMAP_DSP_TASK_IOCTL_UNLOCK:
1286 return taskdev_unlock(dev);
1290 * actually only interractive commands need to lock
1291 * the semaphore, but here all commands do it for simplicity.
1293 if (down_tasksem_interruptible(dev, &dev->ioctl_sem))
1294 return -ERESTARTSYS;
1295 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1300 if ((cmd >= 0x0080) && (cmd < 0x0100)) {
1303 * reserved for backward compatibility
1304 * user-defined TCTL commands: no arg, non-interactive
1306 printk(KERN_WARNING "omapdsp: "
1307 "TCTL commands in 0x0080 - 0x0100 are obsolete.\n"
1308 "they won't be supported in the future.\n");
1311 } else if (cmd < 0x8000) {
1313 * 0x0000 - 0x7fff (except 0x0080 - 0x00ff)
1314 * system reserved TCTL commands
1317 case OMAP_DSP_MBCMD_TCTL_TEN:
1318 case OMAP_DSP_MBCMD_TCTL_TDIS:
1329 * user-defined TCTL commands
1331 else if (cmd < 0x8100) {
1332 /* 0x8000-0x80ff: no arg, non-interactive */
1335 } else if (cmd < 0x8200) {
1336 /* 0x8100-0x81ff: 1 arg, non-interactive */
1338 mbargv[0] = arg & 0xffff;
1340 } else if (cmd < 0x9000) {
1341 /* 0x8200-0x8fff: reserved */
1344 } else if (cmd < 0x9100) {
1345 /* 0x9000-0x90ff: no arg, interactive */
1348 } else if (cmd < 0x9200) {
1349 /* 0x9100-0x91ff: 1 arg, interactive */
1351 mbargv[0] = arg & 0xffff;
1353 } else if (cmd < 0x10000) {
1354 /* 0x9200-0xffff: reserved */
1363 case OMAP_DSP_TASK_IOCTL_BFLSH:
1364 ret = dsp_task_flush_buf(dev->task);
1366 case OMAP_DSP_TASK_IOCTL_SETBSZ:
1367 ret = dsp_task_set_fifosz(dev->task, arg);
1369 case OMAP_DSP_TASK_IOCTL_GETNAME:
1371 if (copy_to_user((void *)arg, dev->name,
1372 strlen(dev->name) + 1))
1384 tid = dev->task->tid;
1385 mbcmd_set(mb, MBCMD(TCTL), tid, cmd);
1387 mbarg.argc = mbargc;
1389 mbarg.argv = mbargv;
1395 dev->task->tctl_stat = -ERESTARTSYS;
1396 devstate_unlock(dev);
1398 dsp_mbcmd_send_and_wait_exarg(&mb, mbargp, &dev->ioctl_wait_q);
1399 if (signal_pending(current)) {
1403 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0) {
1407 ret = dev->task->tctl_stat;
1409 printk(KERN_ERR "omapdsp: TCTL not responding.\n");
1413 dsp_mbcmd_send_exarg(&mb, mbargp);
1418 devstate_unlock(dev);
1420 up(&dev->ioctl_sem);
1424 static void dsp_task_mmap_open(struct vm_area_struct *vma)
1426 struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1427 struct dsptask *task;
1428 size_t len = vma->vm_end - vma->vm_start;
1430 BUG_ON(!(dev->state & OMAP_DSP_DEVSTATE_ATTACHED));
1432 exmap_use(task->map_base, len);
1435 static void dsp_task_mmap_close(struct vm_area_struct *vma)
1437 struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1438 struct dsptask *task;
1439 size_t len = vma->vm_end - vma->vm_start;
1441 BUG_ON(!(dev->state & OMAP_DSP_DEVSTATE_ATTACHED));
1443 exmap_unuse(task->map_base, len);
1447 * On demand page allocation is not allowed. The mapping area is defined by
1448 * corresponding DSP tasks.
1450 static struct page *dsp_task_mmap_nopage(struct vm_area_struct *vma,
1451 unsigned long address, int *type)
1453 return NOPAGE_SIGBUS;
1456 static struct vm_operations_struct dsp_task_vm_ops = {
1457 .open = dsp_task_mmap_open,
1458 .close = dsp_task_mmap_close,
1459 .nopage = dsp_task_mmap_nopage,
1462 static int dsp_task_mmap(struct file *filp, struct vm_area_struct *vma)
1465 unsigned long tmp_padr, tmp_vmadr, off;
1466 size_t req_len, tmp_len;
1467 unsigned int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
1468 struct taskdev *dev = taskdev[minor];
1469 struct dsptask *task;
1472 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED) < 0)
1473 return -ERESTARTSYS;
1477 * Don't swap this area out
1478 * Don't dump this area to a core file
1480 vma->vm_flags |= VM_RESERVED | VM_IO;
1482 /* Do not cache this area */
1483 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1485 req_len = vma->vm_end - vma->vm_start;
1486 off = vma->vm_pgoff << PAGE_SHIFT;
1487 tmp_vmadr = vma->vm_start;
1488 tmp_vadr = task->map_base + off;
1490 tmp_padr = dsp_virt_to_phys(tmp_vadr, &tmp_len);
1491 if (tmp_padr == 0) {
1493 "omapdsp: task %s: illegal address "
1494 "for mmap: %p", task->name, tmp_vadr);
1495 /* partial mapping will be cleared in upper layer */
1499 if (tmp_len > req_len)
1503 "omapdsp: mmap info: "
1504 "vmadr = %08lx, padr = %08lx, len = %x\n",
1505 tmp_vmadr, tmp_padr, tmp_len);
1506 if (remap_pfn_range(vma, tmp_vmadr, tmp_padr >> PAGE_SHIFT,
1507 tmp_len, vma->vm_page_prot) != 0) {
1509 "omapdsp: task %s: remap_page_range() failed.\n",
1511 /* partial mapping will be cleared in upper layer */
1517 tmp_vmadr += tmp_len;
1518 tmp_vadr += tmp_len;
1521 vma->vm_ops = &dsp_task_vm_ops;
1522 vma->vm_private_data = dev;
1523 exmap_use(task->map_base, vma->vm_end - vma->vm_start);
1526 devstate_unlock(dev);
1530 static int dsp_task_open(struct inode *inode, struct file *file)
1532 unsigned int minor = MINOR(inode->i_rdev);
1533 struct taskdev *dev;
1536 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL))
1538 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_NOTASK |
1539 OMAP_DSP_DEVSTATE_ATTACHED) < 0)
1540 return -ERESTARTSYS;
1541 #ifndef CONFIG_OMAP_DSP_TASK_MULTIOPEN
1542 if (dev->usecount > 0) {
1548 if (dev->state & OMAP_DSP_DEVSTATE_NOTASK) {
1549 dev->state = OMAP_DSP_DEVSTATE_ADDREQ;
1550 /* wake up twch daemon for tadd */
1552 devstate_unlock(dev);
1553 if (devstate_lock(dev, OMAP_DSP_DEVSTATE_ATTACHED |
1554 OMAP_DSP_DEVSTATE_ADDFAIL) < 0) {
1555 spin_lock(&dev->state_lock);
1556 if (dev->state & OMAP_DSP_DEVSTATE_ADDREQ)
1557 dev->state = OMAP_DSP_DEVSTATE_NOTASK;
1558 spin_unlock(&dev->state_lock);
1559 return -ERESTARTSYS;
1561 if (dev->state & OMAP_DSP_DEVSTATE_ADDFAIL) {
1562 printk(KERN_ERR "omapdsp: task attach failed for %s!\n",
1565 dev->state = OMAP_DSP_DEVSTATE_NOTASK;
1566 wake_up_interruptible_all(&dev->state_wait_q);
1571 /* state_lock covers usecount, proc_list as well. */
1573 proc_list_add(&dev->proc_list, current);
1574 file->f_op = &dev->fops;
1575 devstate_unlock(dev);
1580 devstate_unlock(dev);
1584 static int dsp_task_release(struct inode *inode, struct file *file)
1586 unsigned int minor = MINOR(inode->i_rdev);
1587 struct taskdev *dev = taskdev[minor];
1589 /* state_lock covers usecount, proc_list as well. */
1590 spin_lock(&dev->state_lock);
1592 /* state can be ATTACHED, KILLING or GARBAGE here. */
1593 switch (dev->state & OMAP_DSP_DEVSTATE_STATE_MASK) {
1595 case OMAP_DSP_DEVSTATE_KILLING:
1599 case OMAP_DSP_DEVSTATE_GARBAGE:
1600 if(--dev->usecount == 0) {
1601 dev->state = OMAP_DSP_DEVSTATE_NOTASK;
1602 wake_up_interruptible_all(&dev->state_wait_q);
1606 case OMAP_DSP_DEVSTATE_ATTACHED:
1607 if (dev->lock_pid == current->pid)
1608 taskdev_unlock(dev);
1609 proc_list_del(&dev->proc_list, current);
1610 if (--dev->usecount == 0) {
1611 if (minor >= n_task) { /* dynamic task */
1612 dev->state = OMAP_DSP_DEVSTATE_DELREQ;
1613 /* wake up twch daemon for tdel */
1621 spin_unlock(&dev->state_lock);
1628 int dsp_mkdev(char *name)
1630 struct taskdev *dev;
1632 unsigned char minor;
1634 if (!dsp_is_ready()) {
1635 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1638 for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1639 if (taskdev[minor] == NULL)
1642 printk(KERN_ERR "omapdsp: Too many task devices.\n");
1646 if ((dev = kmalloc(sizeof(struct taskdev), GFP_KERNEL)) == NULL)
1648 memset(dev, 0, sizeof(struct taskdev));
1649 if ((status = taskdev_init(dev, name, minor)) < 0) {
1656 int dsp_rmdev(char *name)
1658 unsigned char minor;
1661 if (!dsp_is_ready()) {
1662 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1665 for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1666 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1667 if ((ret = dsp_rmdev_minor(minor)) < 0)
1675 static int dsp_rmdev_minor(unsigned char minor)
1677 struct taskdev *dev = taskdev[minor];
1679 spin_lock(&dev->state_lock);
1681 switch (dev->state & OMAP_DSP_DEVSTATE_STATE_MASK) {
1683 case OMAP_DSP_DEVSTATE_NOTASK:
1687 case OMAP_DSP_DEVSTATE_ATTACHED:
1688 /* task is working. kill it. */
1689 dev->state = OMAP_DSP_DEVSTATE_KILLING;
1690 proclist_send_sigbus(&dev->proc_list);
1691 spin_unlock(&dev->state_lock);
1692 dsp_tdel_bh(minor, OMAP_DSP_MBCMD_TDEL_KILL);
1695 case OMAP_DSP_DEVSTATE_ADDREQ:
1696 /* open() is waiting. drain it. */
1697 dev->state = OMAP_DSP_DEVSTATE_ADDFAIL;
1698 wake_up_interruptible_all(&dev->state_wait_q);
1701 case OMAP_DSP_DEVSTATE_DELREQ:
1702 /* nobody is waiting. */
1703 dev->state = OMAP_DSP_DEVSTATE_NOTASK;
1704 wake_up_interruptible_all(&dev->state_wait_q);
1707 case OMAP_DSP_DEVSTATE_ADDING:
1708 case OMAP_DSP_DEVSTATE_DELING:
1709 case OMAP_DSP_DEVSTATE_KILLING:
1710 case OMAP_DSP_DEVSTATE_GARBAGE:
1711 case OMAP_DSP_DEVSTATE_ADDFAIL:
1712 /* transient state. wait for a moment. */
1717 spin_unlock(&dev->state_lock);
1720 /* wait for some time and hope the state is settled */
1721 devstate_lock_timeout(dev, OMAP_DSP_DEVSTATE_NOTASK, HZ);
1722 if (!(dev->state & OMAP_DSP_DEVSTATE_NOTASK)) {
1724 "omapdsp: illegal device state (%s) on rmdev %s.\n",
1725 devstate_name(dev->state), dev->name);
1727 dev->state = OMAP_DSP_DEVSTATE_INVALID;
1728 devstate_unlock(dev);
1730 taskdev_delete(minor);
1736 struct file_operations dsp_task_fops = {
1737 .owner = THIS_MODULE,
1738 .poll = dsp_task_poll,
1739 .ioctl = dsp_task_ioctl,
1740 .open = dsp_task_open,
1741 .release = dsp_task_release,
1744 static void dsptask_dev_release(struct device *dev)
1748 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor)
1750 struct class_device *cdev;
1752 taskdev[minor] = dev;
1754 INIT_LIST_HEAD(&dev->proc_list);
1755 init_waitqueue_head(&dev->read_wait_q);
1756 init_waitqueue_head(&dev->write_wait_q);
1757 init_waitqueue_head(&dev->ioctl_wait_q);
1758 init_MUTEX(&dev->read_sem);
1759 init_MUTEX(&dev->write_sem);
1760 init_MUTEX(&dev->ioctl_sem);
1761 init_MUTEX(&dev->lock_sem);
1764 strncpy(dev->name, name, OMAP_DSP_TNM_LEN);
1765 dev->name[OMAP_DSP_TNM_LEN-1] = '\0';
1766 dev->state = (minor < n_task) ? OMAP_DSP_DEVSTATE_ATTACHED :
1767 OMAP_DSP_DEVSTATE_NOTASK;
1769 memcpy(&dev->fops, &dsp_task_fops, sizeof(struct file_operations));
1771 dev->dev.parent = &dsp_device.dev;
1772 dev->dev.bus = &dsptask_bus;
1773 sprintf(dev->dev.bus_id, "dsptask%d", minor);
1774 dev->dev.release = dsptask_dev_release;
1775 device_register(&dev->dev);
1776 device_create_file(&dev->dev, &dev_attr_devname);
1777 device_create_file(&dev->dev, &dev_attr_devstate);
1778 device_create_file(&dev->dev, &dev_attr_proc_list);
1779 cdev = class_device_create(dsp_task_class, NULL,
1780 MKDEV(OMAP_DSP_TASK_MAJOR, minor),
1781 NULL, "dsptask%d", minor);
1783 init_waitqueue_head(&dev->state_wait_q);
1784 spin_lock_init(&dev->state_lock);
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 class_device_destroy(dsp_task_class, MKDEV(OMAP_DSP_TASK_MAJOR, minor));
1799 device_unregister(&dev->dev);
1800 proc_list_flush(&dev->proc_list);
1801 taskdev[minor] = NULL;
1804 static void taskdev_attach_task(struct taskdev *dev, struct dsptask *task)
1806 unsigned short ttyp = task->ttyp;
1812 sndtyp_wd(ttyp) ? dsp_task_read_wd_acv:
1813 /* sndtyp_bk */ dsp_task_read_bk_acv:
1815 sndtyp_wd(ttyp) ? dsp_task_read_wd_psv:
1816 /* sndtyp_bk */ dsp_task_read_bk_psv;
1818 rcvtyp_wd(ttyp) ? dsp_task_write_wd:
1819 /* rcvbyp_bk */ dsp_task_write_bk;
1820 if (task->map_length)
1821 dev->fops.mmap = dsp_task_mmap;
1823 device_create_file(&dev->dev, &dev_attr_taskname);
1824 device_create_file(&dev->dev, &dev_attr_ttyp);
1825 if (sndtyp_wd(ttyp)) {
1826 device_create_file(&dev->dev, &dev_attr_fifosz);
1827 device_create_file(&dev->dev, &dev_attr_fifocnt);
1829 device_create_file(&dev->dev, &dev_attr_ipblink);
1830 device_create_file(&dev->dev, &dev_attr_wsz);
1831 if (task->map_length)
1832 device_create_file(&dev->dev, &dev_attr_mmap);
1835 static void taskdev_detach_task(struct taskdev *dev)
1837 unsigned short ttyp = dev->task->ttyp;
1839 device_remove_file(&dev->dev, &dev_attr_taskname);
1840 device_remove_file(&dev->dev, &dev_attr_ttyp);
1841 if (sndtyp_wd(ttyp)) {
1842 device_remove_file(&dev->dev, &dev_attr_fifosz);
1843 device_remove_file(&dev->dev, &dev_attr_fifocnt);
1845 device_remove_file(&dev->dev, &dev_attr_ipblink);
1846 device_remove_file(&dev->dev, &dev_attr_wsz);
1847 if (dev->task->map_length)
1848 device_remove_file(&dev->dev, &dev_attr_mmap);
1852 dev->fops.read = NULL;
1853 dev->fops.write = NULL;
1854 printk(KERN_INFO "omapdsp: taskdev %s disabled.\n", dev->name);
1859 * tadd / tdel / tkill
1861 int dsp_tadd(unsigned char minor, unsigned long adr)
1863 struct taskdev *dev;
1864 struct dsptask *task;
1866 struct mb_exarg arg;
1867 unsigned char tid, tid_response;
1868 unsigned short argv[2];
1871 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
1873 "omapdsp: no task device with minor %d\n", minor);
1877 spin_lock(&dev->state_lock);
1878 if (!(dev->state & OMAP_DSP_DEVSTATE_ADDREQ)) {
1880 "omapdsp: taskdev %s is not requesting for tadd. "
1881 "(state is %s)\n", dev->name, devstate_name(dev->state));
1882 spin_unlock(&dev->state_lock);
1885 dev->state = OMAP_DSP_DEVSTATE_ADDING;
1886 spin_unlock(&dev->state_lock);
1888 if (adr == OMAP_DSP_TADD_ABORTADR) {
1889 /* aborting tadd intentionally */
1890 printk(KERN_INFO "omapdsp: tadd address is ABORTADR.\n");
1893 if (adr >= DSPSPACE_SIZE) {
1895 "omapdsp: illegal address 0x%08lx for tadd\n", adr);
1900 adr >>= 1; /* word address */
1901 argv[0] = adr >> 16; /* addrh */
1902 argv[1] = adr & 0xffff; /* addrl */
1904 if (down_interruptible(&cfg_sem)) {
1908 cfg_tid = OMAP_DSP_TID_ANON;
1909 cfg_cmd = MBCMD(TADD);
1910 mbcmd_set(mb, MBCMD(TADD), 0, 0);
1911 arg.tid = OMAP_DSP_TID_ANON;
1916 dsp_mbcmd_send_and_wait_exarg(&mb, &arg, &cfg_wait_q);
1919 cfg_tid = OMAP_DSP_TID_ANON;
1923 if (tid == OMAP_DSP_TID_ANON) {
1924 printk(KERN_ERR "omapdsp: tadd failed!\n");
1928 if ((tid < n_task) || dsptask[tid]) {
1929 printk(KERN_ERR "omapdsp: illegal tid (%d)!\n", tid);
1933 if ((task = kmalloc(sizeof(struct dsptask), GFP_KERNEL)) == NULL) {
1937 memset(task, 0, sizeof(struct dsptask));
1939 if ((ret = dsp_task_config(task, tid)) < 0)
1941 taskdev_attach_task(dev, task);
1943 if (strcmp(dev->name, task->name)) {
1945 "omapdsp: task name (%s) doesn't match with "
1946 "device name (%s).\n", task->name, dev->name);
1951 dsp_task_init(task);
1952 printk(KERN_INFO "omapdsp: taskdev %s enabled.\n", dev->name);
1953 dev->state = OMAP_DSP_DEVSTATE_ATTACHED;
1954 wake_up_interruptible_all(&dev->state_wait_q);
1961 printk(KERN_ERR "omapdsp: deleting the task...\n");
1963 dev->state = OMAP_DSP_DEVSTATE_DELING;
1965 if (down_interruptible(&cfg_sem)) {
1966 printk(KERN_ERR "omapdsp: aborting tdel process. "
1967 "DSP side could be corrupted.\n");
1970 cfg_tid = OMAP_DSP_TID_ANON;
1971 cfg_cmd = MBCMD(TDEL);
1972 mbcmd_set(mb, MBCMD(TDEL), tid, OMAP_DSP_MBCMD_TDEL_KILL);
1973 dsp_mbcmd_send_and_wait(&mb, &cfg_wait_q);
1974 tid_response = cfg_tid;
1975 cfg_tid = OMAP_DSP_TID_ANON;
1979 if (tid_response != tid)
1980 printk(KERN_ERR "omapdsp: tdel failed. "
1981 "DSP side could be corrupted.\n");
1984 dev->state = OMAP_DSP_DEVSTATE_ADDFAIL;
1985 wake_up_interruptible_all(&dev->state_wait_q);
1989 int dsp_tdel(unsigned char minor)
1991 struct taskdev *dev;
1993 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
1995 "omapdsp: no task device with minor %d\n", minor);
1998 spin_lock(&dev->state_lock);
1999 if (!(dev->state & OMAP_DSP_DEVSTATE_DELREQ)) {
2001 "omapdsp: taskdev %s is not requesting for tdel. "
2002 "(state is %s)\n", dev->name, devstate_name(dev->state));
2003 spin_unlock(&dev->state_lock);
2006 dev->state = OMAP_DSP_DEVSTATE_DELING;
2007 spin_unlock(&dev->state_lock);
2009 return dsp_tdel_bh(minor, OMAP_DSP_MBCMD_TDEL_SAFE);
2012 int dsp_tkill(unsigned char minor)
2014 struct taskdev *dev;
2016 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2018 "omapdsp: no task device with minor %d\n", minor);
2021 spin_lock(&dev->state_lock);
2022 if (!(dev->state & OMAP_DSP_DEVSTATE_ATTACHED)) {
2024 "omapdsp: task has not been attached for taskdev %s\n",
2026 spin_unlock(&dev->state_lock);
2029 dev->state = OMAP_DSP_DEVSTATE_KILLING;
2030 proclist_send_sigbus(&dev->proc_list);
2031 spin_unlock(&dev->state_lock);
2033 return dsp_tdel_bh(minor, OMAP_DSP_MBCMD_TDEL_KILL);
2036 static int dsp_tdel_bh(unsigned char minor, unsigned short type)
2038 struct taskdev *dev = taskdev[minor];
2039 struct dsptask *task;
2041 unsigned char tid, tid_response;
2046 if (down_interruptible(&cfg_sem)) {
2047 if (type == OMAP_DSP_MBCMD_TDEL_SAFE) {
2048 dev->state = OMAP_DSP_DEVSTATE_DELREQ;
2049 return -ERESTARTSYS;
2051 tid_response = OMAP_DSP_TID_ANON;
2056 cfg_tid = OMAP_DSP_TID_ANON;
2057 cfg_cmd = MBCMD(TDEL);
2058 mbcmd_set(mb, MBCMD(TDEL), tid, type);
2059 dsp_mbcmd_send_and_wait(&mb, &cfg_wait_q);
2060 tid_response = cfg_tid;
2061 cfg_tid = OMAP_DSP_TID_ANON;
2066 taskdev_detach_task(dev);
2067 dsp_task_unconfig(task);
2070 if (tid_response != tid) {
2071 printk(KERN_ERR "omapdsp: %s failed!\n",
2072 (type == OMAP_DSP_MBCMD_TDEL_SAFE) ? "tdel" : "tkill");
2075 spin_lock(&dev->state_lock);
2076 dev->state = (dev->usecount > 0) ? OMAP_DSP_DEVSTATE_GARBAGE :
2077 OMAP_DSP_DEVSTATE_NOTASK;
2078 wake_up_interruptible_all(&dev->state_wait_q);
2079 spin_unlock(&dev->state_lock);
2087 long taskdev_state_stale(unsigned char minor)
2089 if (taskdev[minor]) {
2090 long state = taskdev[minor]->state;
2091 taskdev[minor]->state |= OMAP_DSP_DEVSTATE_STALE;
2094 return OMAP_DSP_DEVSTATE_NOTASK;
2098 * functions called from mailbox1 interrupt routine
2100 void mbx1_wdsnd(struct mbcmd *mb)
2102 unsigned char tid = mb->cmd_l;
2103 struct dsptask *task = dsptask[tid];
2105 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2106 printk(KERN_ERR "mbx: WDSND with illegal tid! %d\n", tid);
2109 if (sndtyp_bk(task->ttyp)) {
2111 "mbx: WDSND from block sending task! (task%d)\n", tid);
2114 if (sndtyp_psv(task->ttyp) &&
2115 !waitqueue_active(&task->dev->read_wait_q)) {
2117 "mbx: WDSND from passive sending task (task%d) "
2118 "without request!\n", tid);
2122 write_word_to_fifo(&task->rcvdt.fifo, mb->data);
2123 wake_up_interruptible(&task->dev->read_wait_q);
2126 void mbx1_wdreq(struct mbcmd *mb)
2128 unsigned char tid = mb->cmd_l;
2129 struct dsptask *task = dsptask[tid];
2131 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2132 printk(KERN_ERR "mbx: WDREQ with illegal tid! %d\n", tid);
2135 if (rcvtyp_psv(task->ttyp)) {
2137 "mbx: WDREQ from passive receiving task! (task%d)\n",
2142 spin_lock(&task->wsz_lock);
2144 spin_unlock(&task->wsz_lock);
2145 wake_up_interruptible(&task->dev->write_wait_q);
2148 void mbx1_bksnd(struct mbcmd *mb)
2150 unsigned char tid = mb->cmd_l;
2151 unsigned short bid = mb->data;
2152 struct dsptask *task = dsptask[tid];
2155 if (bid >= ipbcfg.ln) {
2156 printk(KERN_ERR "mbx: BKSND with illegal bid! %d\n", bid);
2159 ipb_bsycnt_dec(&ipbcfg);
2160 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2161 printk(KERN_ERR "mbx: BKSND with illegal tid! %d\n", tid);
2162 goto unuse_ipbuf_out;
2164 if (sndtyp_wd(task->ttyp)) {
2166 "mbx: BKSND from word sending task! (task%d)\n", tid);
2167 goto unuse_ipbuf_out;
2169 if (sndtyp_pvt(task->ttyp)) {
2171 "mbx: BKSND from private sending task! (task%d)\n", tid);
2172 goto unuse_ipbuf_out;
2174 if (sync_with_dsp(&ipbuf[bid]->sd, tid, 10) < 0) {
2175 printk(KERN_ERR "mbx: BKSND - IPBUF sync failed!\n");
2179 /* should be done in DSP, but just in case. */
2180 ipbuf[bid]->next = OMAP_DSP_BID_NULL;
2182 cnt = ipbuf[bid]->c;
2183 if (cnt > ipbcfg.lsz) {
2184 printk(KERN_ERR "mbx: BKSND cnt(%d) > ipbuf line size(%d)!\n",
2186 goto unuse_ipbuf_out;
2190 /* 0-byte send from DSP */
2191 unuse_ipbuf_nowait(bid);
2194 spin_lock(&task->rcvdt.bk.link.lock);
2195 ipblink_add_tail(&task->rcvdt.bk.link, bid, ipbuf);
2196 spin_unlock(&task->rcvdt.bk.link.lock);
2197 /* we keep coming bid and return alternative line to DSP. */
2201 wake_up_interruptible(&task->dev->read_wait_q);
2205 unuse_ipbuf_nowait(bid);
2209 void mbx1_bkreq(struct mbcmd *mb)
2211 unsigned char tid = mb->cmd_l;
2212 unsigned short cnt = mb->data;
2213 struct dsptask *task = dsptask[tid];
2215 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2216 printk(KERN_ERR "mbx: BKREQ with illegal tid! %d\n", tid);
2219 if (rcvtyp_wd(task->ttyp)) {
2221 "mbx: BKREQ from word receiving task! (task%d)\n", tid);
2224 if (rcvtyp_pvt(task->ttyp)) {
2226 "mbx: BKREQ from private receiving task! (task%d)\n",
2230 if (rcvtyp_psv(task->ttyp)) {
2232 "mbx: BKREQ from passive receiving task! (task%d)\n",
2237 spin_lock(&task->wsz_lock);
2239 spin_unlock(&task->wsz_lock);
2240 wake_up_interruptible(&task->dev->write_wait_q);
2243 void mbx1_bkyld(struct mbcmd *mb)
2245 unsigned short bid = mb->data;
2247 if (bid >= ipbcfg.ln) {
2248 printk(KERN_ERR "mbx: BKYLD with illegal bid! %d\n", bid);
2252 /* should be done in DSP, but just in case. */
2253 ipbuf[bid]->next = OMAP_DSP_BID_NULL;
2255 /* we don't need to sync with DSP */
2256 ipb_bsycnt_dec(&ipbcfg);
2260 void mbx1_bksndp(struct mbcmd *mb)
2262 unsigned char tid = mb->cmd_l;
2263 struct dsptask *task = dsptask[tid];
2264 struct rcvdt_bk_struct *rcvdt = &task->rcvdt.bk;
2265 struct ipbuf_p *ipbp = rcvdt->ipbuf_pvt_r;
2267 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2268 printk(KERN_ERR "mbx: BKSNDP with illegal tid! %d\n", tid);
2271 if (sndtyp_wd(task->ttyp)) {
2273 "mbx: BKSNDP from word sending task! (task%d)\n", tid);
2276 if (sndtyp_gbl(task->ttyp)) {
2278 "mbx: BKSNDP from non-private sending task! (task%d)\n",
2284 * we should not have delayed block at this point
2285 * because read() routine releases the lock of the buffer and
2286 * until then DSP can't send next data.
2289 if (sync_with_dsp(&ipbp->s, tid, 10) < 0) {
2290 printk(KERN_ERR "mbx: BKSNDP - IPBUF sync failed!\n");
2293 printk(KERN_DEBUG "mbx: ipbuf_pvt_r->a = 0x%08lx\n",
2294 MKLONG(ipbp->ah, ipbp->al));
2295 spin_lock(&rcvdt->link.lock);
2296 ipblink_add_pvt(&rcvdt->link);
2297 spin_unlock(&rcvdt->link.lock);
2298 wake_up_interruptible(&task->dev->read_wait_q);
2301 void mbx1_bkreqp(struct mbcmd *mb)
2303 unsigned char tid = mb->cmd_l;
2304 struct dsptask *task = dsptask[tid];
2305 struct ipbuf_p *ipbp = task->ipbuf_pvt_w;
2307 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2308 printk(KERN_ERR "mbx: BKREQP with illegal tid! %d\n", tid);
2311 if (rcvtyp_wd(task->ttyp)) {
2313 "mbx: BKREQP from word receiving task! (task%d)\n", tid);
2316 if (rcvtyp_gbl(task->ttyp)) {
2318 "mbx: BKREQP from non-private receiving task! (task%d)\n", tid);
2321 if (rcvtyp_psv(task->ttyp)) {
2323 "mbx: BKREQP from passive receiving task! (task%d)\n", tid);
2327 if (sync_with_dsp(&ipbp->s, OMAP_DSP_TID_FREE, 10) < 0) {
2328 printk(KERN_ERR "mbx: BKREQP - IPBUF sync failed!\n");
2331 printk(KERN_DEBUG "mbx: ipbuf_pvt_w->a = 0x%08lx\n",
2332 MKLONG(ipbp->ah, ipbp->al));
2333 spin_lock(&task->wsz_lock);
2334 task->wsz = ipbp->c*2;
2335 spin_unlock(&task->wsz_lock);
2336 wake_up_interruptible(&task->dev->write_wait_q);
2339 void mbx1_tctl(struct mbcmd *mb)
2341 unsigned char tid = mb->cmd_l;
2342 struct dsptask *task = dsptask[tid];
2344 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2345 printk(KERN_ERR "mbx: TCTL with illegal tid! %d\n", tid);
2349 if (!waitqueue_active(&task->dev->ioctl_wait_q)) {
2350 printk(KERN_WARNING "mbx: unexpected TCTL from DSP!\n");
2354 task->tctl_stat = mb->data;
2355 wake_up_interruptible(&task->dev->ioctl_wait_q);
2358 void mbx1_tcfg(struct mbcmd *mb)
2360 unsigned char tid = mb->cmd_l;
2361 struct dsptask *task = dsptask[tid];
2362 unsigned short *tnm;
2363 volatile unsigned short *buf;
2366 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2367 printk(KERN_ERR "mbx: TCFG with illegal tid! %d\n", tid);
2370 if ((task->state != TASK_STATE_CFGREQ) || (cfg_cmd != MBCMD(TCFG))) {
2371 printk(KERN_WARNING "mbx: unexpected TCFG from DSP!\n");
2375 if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2376 printk(KERN_ERR "mbx: TCFG - IPBUF sync failed!\n");
2381 * read configuration data on system IPBUF
2383 buf = ipbuf_sys_da->d;
2384 task->ttyp = buf[0];
2385 task->rcvdt.bk.ipbuf_pvt_r = MKVIRT(buf[1], buf[2]);
2386 task->ipbuf_pvt_w = MKVIRT(buf[3], buf[4]);
2387 task->map_base = MKVIRT(buf[5], buf[6]);
2388 task->map_length = MKLONG(buf[7], buf[8]) << 1; /* word -> byte */
2389 tnm = MKVIRT(buf[9], buf[10]);
2390 release_ipbuf_pvt(ipbuf_sys_da);
2393 * copy task name string
2395 if (dsp_address_validate(tnm, OMAP_DSP_TNM_LEN, "task name buffer") <0) {
2396 task->name[0] = '\0';
2400 for (i = 0; i < OMAP_DSP_TNM_LEN-1; i++) {
2401 /* avoiding byte access */
2402 unsigned short tmp = tnm[i];
2403 task->name[i] = tmp & 0x00ff;
2407 task->name[OMAP_DSP_TNM_LEN-1] = '\0';
2409 task->state = TASK_STATE_READY;
2411 wake_up_interruptible(&cfg_wait_q);
2414 void mbx1_tadd(struct mbcmd *mb)
2416 unsigned char tid = mb->cmd_l;
2418 if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBCMD(TADD))) {
2419 printk(KERN_WARNING "mbx: unexpected TADD from DSP!\n");
2423 wake_up_interruptible(&cfg_wait_q);
2426 void mbx1_tdel(struct mbcmd *mb)
2428 unsigned char tid = mb->cmd_l;
2430 if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBCMD(TDEL))) {
2431 printk(KERN_WARNING "mbx: unexpected TDEL from DSP!\n");
2435 wake_up_interruptible(&cfg_wait_q);
2438 void mbx1_err_fatal(unsigned char tid)
2440 struct dsptask *task = dsptask[tid];
2442 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2443 printk(KERN_ERR "mbx: FATAL ERR with illegal tid! %d\n", tid);
2447 spin_lock(&task->dev->state_lock);
2448 proclist_send_sigbus(&task->dev->proc_list);
2449 spin_unlock(&task->dev->state_lock);
2452 static short *dbg_buf;
2453 static unsigned short dbg_buf_sz, dbg_line_sz;
2456 int dsp_dbg_config(short *buf, unsigned short sz, unsigned short lsz)
2458 #ifdef OLD_BINARY_SUPPORT
2459 if ((mbx_revision == MBREV_3_0) || (mbx_revision == MBREV_3_2)) {
2468 if (dsp_address_validate(buf, sz, "debug buffer") < 0)
2473 "omapdsp: dbg_buf lsz (%d) is greater than its "
2474 "buffer size (%d)\n", lsz, sz);
2486 void dsp_dbg_stop(void)
2491 #ifdef OLD_BINARY_SUPPORT
2492 static void mbx1_dbg_old(struct mbcmd *mb);
2495 void mbx1_dbg(struct mbcmd *mb)
2497 unsigned char tid = mb->cmd_l;
2499 char s[80], *s_end = &s[79], *p;
2500 unsigned short *src;
2503 #ifdef OLD_BINARY_SUPPORT
2504 if ((mbx_revision == MBREV_3_0) || (mbx_revision == MBREV_3_2)) {
2510 if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2511 (tid != OMAP_DSP_TID_ANON)) {
2512 printk(KERN_ERR "mbx: DBG with illegal tid! %d\n", tid);
2515 if (dbg_buf == NULL) {
2516 printk(KERN_ERR "mbx: DBG command received, but "
2517 "dbg_buf has not been configured yet.\n");
2521 if (dsp_mem_enable(dbg_buf) < 0)
2524 src = &dbg_buf[dbg_rp];
2526 for (i = 0; i < cnt; i++) {
2529 * Be carefull that dbg_buf should not be read with
2530 * 1-byte access since it might be placed in DARAM/SARAM
2531 * and it can cause unexpected byteswap.
2533 * *(p++) = *(src++) & 0xff;
2534 * causes 1-byte access!
2537 *(p++) = tmp & 0xff;
2538 if (*(p-1) == '\n') {
2540 printk(KERN_INFO "%s", s);
2546 printk(KERN_INFO "%s\n", s);
2553 printk(KERN_INFO "%s\n", s);
2555 if ((dbg_rp += cnt + 1) > dbg_buf_sz - dbg_line_sz)
2558 dsp_mem_disable(dbg_buf);
2561 #ifdef OLD_BINARY_SUPPORT
2562 static void mbx1_dbg_old(struct mbcmd *mb)
2564 unsigned char tid = mb->cmd_l;
2565 char s[80], *s_end = &s[79], *p;
2566 unsigned short *src;
2567 volatile unsigned short *buf;
2571 if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2572 (tid != OMAP_DSP_TID_ANON)) {
2573 printk(KERN_ERR "mbx: DBG with illegal tid! %d\n", tid);
2576 if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2577 printk(KERN_ERR "mbx: DBG - IPBUF sync failed!\n");
2580 buf = ipbuf_sys_da->d;
2582 src = MKVIRT(buf[1], buf[2]);
2583 if (dsp_address_validate(src, cnt, "dbg buffer") < 0)
2586 if (dsp_mem_enable(src) < 0)
2590 for (i = 0; i < cnt; i++) {
2593 * Be carefull that ipbuf should not be read with
2594 * 1-byte access since it might be placed in DARAM/SARAM
2595 * and it can cause unexpected byteswap.
2597 * *(p++) = *(src++) & 0xff;
2598 * causes 1-byte access!
2601 *(p++) = tmp & 0xff;
2602 if (*(p-1) == '\n') {
2604 printk(KERN_INFO "%s", s);
2610 printk(KERN_INFO "%s\n", s);
2617 printk(KERN_INFO "%s\n", s);
2620 release_ipbuf_pvt(ipbuf_sys_da);
2621 dsp_mem_disable(src);
2623 #endif /* OLD_BINARY_SUPPORT */
2628 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
2631 struct taskdev *dev = to_taskdev(d);
2632 return sprintf(buf, "%s\n", dev->name);
2635 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
2638 struct taskdev *dev = to_taskdev(d);
2639 return sprintf(buf, "%s\n", devstate_name(dev->state));
2642 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
2645 struct taskdev *dev;
2646 struct proc_list *pl;
2649 dev = to_taskdev(d);
2650 spin_lock(&dev->state_lock);
2651 list_for_each_entry(pl, &dev->proc_list, list_head) {
2652 len += sprintf(buf + len, "%d\n", pl->pid);
2654 spin_unlock(&dev->state_lock);
2659 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
2662 struct taskdev *dev = to_taskdev(d);
2665 len = sprintf(buf, "%s\n", dev->task->name);
2670 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
2673 unsigned short ttyp = to_taskdev(d)->task->ttyp;
2676 len += sprintf(buf + len, "0x%04x\n", ttyp);
2677 len += sprintf(buf + len, "%s %s send\n",
2678 (sndtyp_acv(ttyp)) ? "active" :
2680 (sndtyp_wd(ttyp)) ? "word" :
2681 (sndtyp_pvt(ttyp)) ? "private block" :
2683 len += sprintf(buf + len, "%s %s receive\n",
2684 (rcvtyp_acv(ttyp)) ? "active" :
2686 (rcvtyp_wd(ttyp)) ? "word" :
2687 (rcvtyp_pvt(ttyp)) ? "private block" :
2693 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
2696 struct fifo_struct *fifo = &to_taskdev(d)->task->rcvdt.fifo;
2697 return sprintf(buf, "%d\n", fifo->sz);
2700 static int fifosz_store(struct device *d, struct device_attribute *attr,
2701 const char *buf, size_t count)
2703 struct dsptask *task = to_taskdev(d)->task;
2704 unsigned long fifosz;
2707 fifosz = simple_strtol(buf, NULL, 10);
2708 ret = dsp_task_set_fifosz(task, fifosz);
2710 return (ret < 0) ? ret : strlen(buf);
2713 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
2716 struct fifo_struct *fifo = &to_taskdev(d)->task->rcvdt.fifo;
2717 return sprintf(buf, "%d\n", fifo->cnt);
2720 static __inline__ char *bid_name(unsigned short bid)
2725 case OMAP_DSP_BID_NULL:
2727 case OMAP_DSP_BID_PVT:
2730 sprintf(s, "%d", bid);
2735 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
2738 struct rcvdt_bk_struct *rcvdt = &to_taskdev(d)->task->rcvdt.bk;
2741 spin_lock(&rcvdt->link.lock);
2742 len = sprintf(buf, "top %s\ntail %s\n",
2743 bid_name(rcvdt->link.top), bid_name(rcvdt->link.tail));
2744 spin_unlock(&rcvdt->link.lock);
2749 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
2752 return sprintf(buf, "%d\n", to_taskdev(d)->task->wsz);
2755 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
2758 struct dsptask *task = to_taskdev(d)->task;
2759 return sprintf(buf, "0x%p 0x%x\n", task->map_base, task->map_length);
2763 * called from ipbuf_read_proc()
2765 int ipbuf_is_held(unsigned char tid, unsigned short bid)
2767 struct dsptask *task = dsptask[tid];
2774 spin_lock(&task->rcvdt.bk.link.lock);
2775 ipblink_for_each(b, &task->rcvdt.bk.link, ipbuf) {
2776 if (b == bid) { /* found */
2781 spin_unlock(&task->rcvdt.bk.link.lock);
2786 int __init dsp_taskmod_init(void)
2790 memset(taskdev, 0, sizeof(void *) * TASKDEV_MAX);
2791 memset(dsptask, 0, sizeof(void *) * TASKDEV_MAX);
2793 retval = register_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask",
2797 "omapdsp: failed to register task device: %d\n", retval);
2801 bus_register(&dsptask_bus);
2802 retval = driver_register(&dsptask_driver);
2805 "omapdsp: failed to register DSP task driver: %d\n",
2807 bus_unregister(&dsptask_bus);
2808 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
2811 dsp_task_class = class_create(THIS_MODULE, "dsptask");
2816 void dsp_taskmod_exit(void)
2818 class_destroy(dsp_task_class);
2819 driver_unregister(&dsptask_driver);
2820 bus_unregister(&dsptask_bus);
2821 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");