2 * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
4 * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
6 * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/major.h>
29 #include <linux/poll.h>
30 #include <linux/platform_device.h>
31 #include <linux/slab.h>
32 #include <linux/sched.h>
34 #include <linux/mutex.h>
35 #include <linux/interrupt.h>
36 #include <asm/uaccess.h>
38 #include <asm/arch/mailbox.h>
39 #include "uaccess_dsp.h"
40 #include "dsp_mbcmd.h"
47 #define is_aligned(adr,align) (!((adr)&((align)-1)))
50 * devstate: task device state machine
51 * NOTASK: task is not attached.
52 * ATTACHED: task is attached.
53 * GARBAGE: task is detached. waiting for all processes to close this device.
54 * ADDREQ: requesting for tadd
55 * DELREQ: requesting for tdel. no process is opening this device.
56 * FREEZED: task is attached, but reserved to be killed.
57 * ADDFAIL: tadd failed.
58 * ADDING: tadd in process.
59 * DELING: tdel in process.
60 * KILLING: tkill in process.
62 #define TASKDEV_ST_NOTASK 0x00000001
63 #define TASKDEV_ST_ATTACHED 0x00000002
64 #define TASKDEV_ST_GARBAGE 0x00000004
65 #define TASKDEV_ST_INVALID 0x00000008
66 #define TASKDEV_ST_ADDREQ 0x00000100
67 #define TASKDEV_ST_DELREQ 0x00000200
68 #define TASKDEV_ST_FREEZED 0x00000400
69 #define TASKDEV_ST_ADDFAIL 0x00001000
70 #define TASKDEV_ST_ADDING 0x00010000
71 #define TASKDEV_ST_DELING 0x00020000
72 #define TASKDEV_ST_KILLING 0x00040000
73 #define TASKDEV_ST_STATE_MASK 0x7fffffff
74 #define TASKDEV_ST_STALE 0x80000000
80 { TASKDEV_ST_NOTASK, "notask" },
81 { TASKDEV_ST_ATTACHED, "attached" },
82 { TASKDEV_ST_GARBAGE, "garbage" },
83 { TASKDEV_ST_INVALID, "invalid" },
84 { TASKDEV_ST_ADDREQ, "addreq" },
85 { TASKDEV_ST_DELREQ, "delreq" },
86 { TASKDEV_ST_FREEZED, "freezed" },
87 { TASKDEV_ST_ADDFAIL, "addfail" },
88 { TASKDEV_ST_ADDING, "adding" },
89 { TASKDEV_ST_DELING, "deling" },
90 { TASKDEV_ST_KILLING, "killing" },
93 static char *devstate_name(long state) {
95 int max = ARRAY_SIZE(devstate_desc);
97 for (i = 0; i < max; i++) {
98 if (state & devstate_desc[i].state)
99 return devstate_desc[i].name;
104 struct rcvdt_bk_struct {
110 struct bus_type *bus;
111 // struct device_driver *driver;
112 struct device dev; /* Generic device interface */
115 struct rw_semaphore state_sem;
116 wait_queue_head_t state_wait_q;
117 struct mutex usecount_mutex;
118 unsigned int usecount;
120 struct file_operations fops;
121 spinlock_t proc_list_lock;
122 struct list_head proc_list;
123 struct dsptask *task;
126 wait_queue_head_t read_wait_q;
127 struct mutex read_mutex;
129 struct fifo_struct fifo; /* for active word */
130 struct rcvdt_bk_struct bk;
134 wait_queue_head_t write_wait_q;
135 struct mutex write_mutex;
140 wait_queue_head_t tctl_wait_q;
141 struct mutex tctl_mutex;
143 int tctl_ret; /* return value for tctl_show() */
150 #define to_taskdev(n) container_of(n, struct taskdev, dev)
164 struct ipbuf_p *ipbuf_pvt_r;
167 struct ipbuf_p *ipbuf_pvt_w;
174 #define sndtyp_acv(ttyp) ((ttyp) & TTYP_ASND)
175 #define sndtyp_psv(ttyp) (!((ttyp) & TTYP_ASND))
176 #define sndtyp_bk(ttyp) ((ttyp) & TTYP_BKDM)
177 #define sndtyp_wd(ttyp) (!((ttyp) & TTYP_BKDM))
178 #define sndtyp_pvt(ttyp) ((ttyp) & TTYP_PVDM)
179 #define sndtyp_gbl(ttyp) (!((ttyp) & TTYP_PVDM))
180 #define rcvtyp_acv(ttyp) ((ttyp) & TTYP_ARCV)
181 #define rcvtyp_psv(ttyp) (!((ttyp) & TTYP_ARCV))
182 #define rcvtyp_bk(ttyp) ((ttyp) & TTYP_BKMD)
183 #define rcvtyp_wd(ttyp) (!((ttyp) & TTYP_BKMD))
184 #define rcvtyp_pvt(ttyp) ((ttyp) & TTYP_PVMD)
185 #define rcvtyp_gbl(ttyp) (!((ttyp) & TTYP_PVMD))
187 static __inline__ int has_taskdev_lock(struct taskdev *dev);
188 static int dsp_rmdev_minor(unsigned char minor);
189 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor);
190 static void taskdev_delete(unsigned char minor);
191 static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task);
192 static int dsp_tdel_bh(struct taskdev *dev, u16 type);
194 static struct bus_type dsptask_bus = {
198 static struct class *dsp_task_class;
199 static DEFINE_MUTEX(devmgr_lock);
200 static struct taskdev *taskdev[TASKDEV_MAX];
201 static struct dsptask *dsptask[TASKDEV_MAX];
202 static DEFINE_MUTEX(cfg_lock);
205 static DECLARE_WAIT_QUEUE_HEAD(cfg_wait_q);
206 static u8 n_task; /* static task count */
209 #define is_dynamic_task(tid) ((tid) >= n_task)
211 #define devstate_read_lock(dev, devstate) \
212 devstate_read_lock_timeout(dev, devstate, 0)
213 #define devstate_read_unlock(dev) up_read(&(dev)->state_sem)
214 #define devstate_write_lock(dev, devstate) \
215 devstate_write_lock_timeout(dev, devstate, 0)
216 #define devstate_write_unlock(dev) up_write(&(dev)->state_sem)
218 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
220 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
222 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
224 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
226 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
228 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
230 static int fifosz_store(struct device *d, struct device_attribute *attr,
231 const char *buf, size_t count);
232 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
234 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
236 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
238 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
241 #define __ATTR_RW(_name,_mode) { \
242 .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
243 .show = _name##_show, \
244 .store = _name##_store, \
247 static struct device_attribute dev_attr_devname = __ATTR_RO(devname);
248 static struct device_attribute dev_attr_devstate = __ATTR_RO(devstate);
249 static struct device_attribute dev_attr_proc_list = __ATTR_RO(proc_list);
250 static struct device_attribute dev_attr_taskname = __ATTR_RO(taskname);
251 static struct device_attribute dev_attr_ttyp = __ATTR_RO(ttyp);
252 static struct device_attribute dev_attr_fifosz = __ATTR_RW(fifosz, 0666);
253 static struct device_attribute dev_attr_fifocnt = __ATTR_RO(fifocnt);
254 static struct device_attribute dev_attr_ipblink = __ATTR_RO(ipblink);
255 static struct device_attribute dev_attr_wsz = __ATTR_RO(wsz);
256 static struct device_attribute dev_attr_mmap = __ATTR_RO(mmap);
259 * devstate_read_lock_timeout()
260 * devstate_write_lock_timeout():
261 * timeout != 0: dev->state can be diffeent from what you want.
262 * timeout == 0: no timeout
264 static int devstate_read_lock_timeout(struct taskdev *dev, long devstate,
267 DECLARE_WAITQUEUE(wait, current);
268 long current_state = current->state;
271 down_read(&dev->state_sem);
272 if (dev->state & devstate)
275 add_wait_queue(&dev->state_wait_q, &wait);
277 set_current_state(TASK_INTERRUPTIBLE);
278 up_read(&dev->state_sem);
280 if ((timeout = schedule_timeout(timeout)) == 0) {
282 down_read(&dev->state_sem);
287 if (signal_pending(current)) {
291 down_read(&dev->state_sem);
292 } while (!(dev->state & devstate));
293 remove_wait_queue(&dev->state_wait_q, &wait);
294 set_current_state(current_state);
298 static int devstate_read_lock_and_test(struct taskdev *dev, long devstate)
300 down_read(&dev->state_sem);
301 if (dev->state & devstate)
302 return 1; /* success */
304 up_read(&dev->state_sem);
308 static int devstate_write_lock_timeout(struct taskdev *dev, long devstate,
311 DECLARE_WAITQUEUE(wait, current);
312 long current_state = current->state;
315 down_write(&dev->state_sem);
316 if (dev->state & devstate)
319 add_wait_queue(&dev->state_wait_q, &wait);
321 set_current_state(TASK_INTERRUPTIBLE);
322 up_write(&dev->state_sem);
324 if ((timeout = schedule_timeout(timeout)) == 0) {
326 down_write(&dev->state_sem);
331 if (signal_pending(current)) {
335 down_write(&dev->state_sem);
336 } while (!(dev->state & devstate));
337 remove_wait_queue(&dev->state_wait_q, &wait);
338 set_current_state(current_state);
342 static int devstate_write_lock_and_test(struct taskdev *dev, long devstate)
344 down_write(&dev->state_sem);
345 if (dev->state & devstate) /* success */
349 up_write(&dev->state_sem);
353 static int taskdev_lock_interruptible(struct taskdev *dev, struct mutex *mutex)
357 if (has_taskdev_lock(dev))
358 ret = mutex_lock_interruptible(mutex);
360 if ((ret = mutex_lock_interruptible(&dev->lock)) != 0)
362 ret = mutex_lock_interruptible(mutex);
363 mutex_unlock(&dev->lock);
369 static int taskdev_lock_and_statelock_attached(struct taskdev *dev,
374 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
377 if ((ret = taskdev_lock_interruptible(dev, mutex)) != 0)
378 devstate_read_unlock(dev);
383 static __inline__ void taskdev_unlock_and_stateunlock(struct taskdev *dev,
387 devstate_read_unlock(dev);
391 * taskdev_flush_buf()
392 * must be called under state_lock(ATTACHED) and dev->read_mutex.
394 static int taskdev_flush_buf(struct taskdev *dev)
396 u16 ttyp = dev->task->ttyp;
398 if (sndtyp_wd(ttyp)) {
400 flush_fifo(&dev->rcvdt.fifo);
402 /* block receiving */
403 struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
405 if (sndtyp_gbl(ttyp))
406 ipblink_flush(&rcvdt->link);
408 ipblink_flush_pvt(&rcvdt->link);
409 release_ipbuf_pvt(dev->task->ipbuf_pvt_r);
417 * taskdev_set_fifosz()
418 * must be called under dev->read_mutex.
420 static int taskdev_set_fifosz(struct taskdev *dev, unsigned long sz)
422 u16 ttyp = dev->task->ttyp;
425 if (!(sndtyp_wd(ttyp) && sndtyp_acv(ttyp))) {
427 "omapdsp: buffer size can be changed only for "
428 "active word sending task.\n");
431 if ((sz == 0) || (sz & 1)) {
432 printk(KERN_ERR "omapdsp: illegal buffer size! (%ld)\n"
433 "it must be even and non-zero value.\n", sz);
437 stat = realloc_fifo(&dev->rcvdt.fifo, sz);
438 if (stat == -EBUSY) {
439 printk(KERN_ERR "omapdsp: buffer is not empty!\n");
441 } else if (stat < 0) {
443 "omapdsp: unable to change receive buffer size. "
444 "(%ld bytes for %s)\n", sz, dev->name);
451 static __inline__ int has_taskdev_lock(struct taskdev *dev)
453 return (dev->lock_pid == current->pid);
456 static int taskdev_lock(struct taskdev *dev)
458 if (mutex_lock_interruptible(&dev->lock))
460 dev->lock_pid = current->pid;
464 static int taskdev_unlock(struct taskdev *dev)
466 if (!has_taskdev_lock(dev)) {
468 "omapdsp: an illegal process attempted to "
469 "unlock the dsptask lock!\n");
473 mutex_unlock(&dev->lock);
477 static int dsp_task_config(struct dsptask *task, u8 tid)
486 task->state = TASK_ST_CFGREQ;
487 if (mutex_lock_interruptible(&cfg_lock)) {
491 cfg_cmd = MBX_CMD_DSP_TCFG;
492 mbcompose_send_and_wait(TCFG, tid, 0, &cfg_wait_q);
494 mutex_unlock(&cfg_lock);
496 if (task->state != TASK_ST_READY) {
497 printk(KERN_ERR "omapdsp: task %d configuration error!\n", tid);
502 if (strlen(task->name) <= 1)
503 sprintf(task->name, "%d", tid);
504 printk(KERN_INFO "omapdsp: task %d: name %s\n", tid, task->name);
509 * task info sanity check
512 /* task type check */
513 if (rcvtyp_psv(ttyp) && rcvtyp_pvt(ttyp)) {
514 printk(KERN_ERR "omapdsp: illegal task type(0x%04x), tid=%d\n",
520 /* private buffer address check */
521 if (sndtyp_pvt(ttyp) &&
522 (ipbuf_p_validate(task->ipbuf_pvt_r, DIR_D2A) < 0)) {
526 if (rcvtyp_pvt(ttyp) &&
527 (ipbuf_p_validate(task->ipbuf_pvt_w, DIR_A2D) < 0)) {
532 /* mmap buffer configuration check */
533 if ((task->map_length > 0) &&
534 ((!is_aligned((unsigned long)task->map_base, PAGE_SIZE)) ||
535 (!is_aligned(task->map_length, PAGE_SIZE)) ||
536 (dsp_mem_type(task->map_base, task->map_length) != MEM_TYPE_EXTERN))) {
538 "omapdsp: illegal mmap buffer address(0x%p) or "
540 " It needs to be page-aligned and located at "
541 "external memory.\n",
542 task->map_base, task->map_length);
554 static void dsp_task_init(struct dsptask *task)
556 mbcompose_send(TCTL, task->tid, TCTL_TINIT);
559 int dsp_task_config_all(u8 n)
562 struct taskdev *devheap;
563 struct dsptask *taskheap;
564 size_t devheapsz, taskheapsz;
566 memset(taskdev, 0, sizeof(void *) * TASKDEV_MAX);
567 memset(dsptask, 0, sizeof(void *) * TASKDEV_MAX);
569 printk(KERN_INFO "omapdsp: found %d task(s)\n", n);
576 devheapsz = sizeof(struct taskdev) * n;
577 taskheapsz = sizeof(struct dsptask) * n;
578 heap = kzalloc(devheapsz + taskheapsz, GFP_KERNEL);
582 taskheap = heap + devheapsz;
585 for (i = 0; i < n; i++) {
586 struct taskdev *dev = &devheap[i];
587 struct dsptask *task = &taskheap[i];
589 if ((ret = dsp_task_config(task, i)) < 0)
591 if ((ret = taskdev_init(dev, task->name, i)) < 0)
593 if ((ret = taskdev_attach_task(dev, task)) < 0)
596 printk(KERN_INFO "omapdsp: taskdev %s enabled.\n", dev->name);
602 static void dsp_task_unconfig(struct dsptask *task)
604 dsptask[task->tid] = NULL;
607 void dsp_task_unconfig_all(void)
611 struct dsptask *task;
613 for (minor = 0; minor < n_task; minor++) {
615 * taskdev[minor] can be NULL in case of
616 * configuration failure
619 taskdev_delete(minor);
621 for (; minor < TASKDEV_MAX; minor++) {
623 dsp_rmdev_minor(minor);
626 for (tid = 0; tid < n_task; tid++) {
628 * dsptask[tid] can be NULL in case of
629 * configuration failure
633 dsp_task_unconfig(task);
635 for (; tid < TASKDEV_MAX; tid++) {
639 * on-demand tasks should be deleted in
640 * rmdev_minor(), but just in case.
642 dsp_task_unconfig(task);
655 static struct device_driver dsptask_driver = {
660 u8 dsp_task_count(void)
665 int dsp_taskmod_busy(void)
669 unsigned int usecount;
671 for (minor = 0; minor < TASKDEV_MAX; minor++) {
672 dev = taskdev[minor];
675 if ((usecount = dev->usecount) > 0) {
676 printk("dsp_taskmod_busy(): %s: usecount=%d\n",
677 dev->name, usecount);
681 if ((dev->state & (TASKDEV_ST_ADDREQ |
682 TASKDEV_ST_DELREQ)) {
684 if (dev->state & TASKDEV_ST_ADDREQ) {
685 printk("dsp_taskmod_busy(): %s is in %s\n",
686 dev->name, devstate_name(dev->state));
694 * DSP task device file operations
696 static ssize_t dsp_task_read_wd_acv(struct file *file, char __user *buf,
697 size_t count, loff_t *ppos)
699 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
700 struct taskdev *dev = taskdev[minor];
705 } else if (count & 0x1) {
707 "omapdsp: odd count is illegal for DSP task device.\n");
711 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
714 if (fifo_empty(&dev->rcvdt.fifo)) {
715 long current_state = current->state;
716 DECLARE_WAITQUEUE(wait, current);
718 set_current_state(TASK_INTERRUPTIBLE);
719 add_wait_queue(&dev->read_wait_q, &wait);
720 if (fifo_empty(&dev->rcvdt.fifo)) /* last check */
722 set_current_state(current_state);
723 remove_wait_queue(&dev->read_wait_q, &wait);
724 if (fifo_empty(&dev->rcvdt.fifo)) {
726 if (signal_pending(current))
732 ret = copy_to_user_fm_fifo(buf, &dev->rcvdt.fifo, count);
735 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
739 static ssize_t dsp_task_read_bk_acv(struct file *file, char __user *buf,
740 size_t count, loff_t *ppos)
742 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
743 struct taskdev *dev = taskdev[minor];
744 struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
749 } else if (count & 0x1) {
751 "omapdsp: odd count is illegal for DSP task device.\n");
753 } else if ((int)buf & 0x1) {
755 "omapdsp: buf should be word aligned for "
756 "dsp_task_read().\n");
760 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
763 if (ipblink_empty(&rcvdt->link)) {
765 DECLARE_WAITQUEUE(wait, current);
767 add_wait_queue(&dev->read_wait_q, &wait);
768 current_state = current->state;
769 set_current_state(TASK_INTERRUPTIBLE);
770 if (ipblink_empty(&rcvdt->link)) /* last check */
772 set_current_state(current_state);
773 remove_wait_queue(&dev->read_wait_q, &wait);
774 if (ipblink_empty(&rcvdt->link)) {
776 if (signal_pending(current))
782 /* copy from delayed IPBUF */
783 if (sndtyp_pvt(dev->task->ttyp)) {
785 if (!ipblink_empty(&rcvdt->link)) {
786 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_r;
787 unsigned char *base, *src;
790 if (dsp_mem_enable(ipbp) < 0) {
794 base = MKVIRT(ipbp->ah, ipbp->al);
795 bkcnt = ((unsigned long)ipbp->c) * 2 - rcvdt->rp;
796 if (dsp_address_validate(base, bkcnt,
797 "task %s read buffer",
798 dev->task->name) < 0) {
802 if (dsp_mem_enable(base) < 0) {
806 src = base + rcvdt->rp;
808 if (copy_to_user_dsp(buf, src, count)) {
815 if (copy_to_user_dsp(buf, src, bkcnt)) {
820 ipblink_del_pvt(&rcvdt->link);
821 release_ipbuf_pvt(ipbp);
825 dsp_mem_disable(src);
827 dsp_mem_disable(ipbp);
831 if (dsp_mem_enable_ipbuf() < 0) {
835 while (!ipblink_empty(&rcvdt->link)) {
838 struct ipbuf_head *ipb_h = bid_to_ipbuf(rcvdt->link.top);
840 src = ipb_h->p->d + rcvdt->rp;
841 bkcnt = ((unsigned long)ipb_h->p->c) * 2 - rcvdt->rp;
843 if (copy_to_user_dsp(buf, src, count)) {
851 if (copy_to_user_dsp(buf, src, bkcnt)) {
858 ipblink_del_top(&rcvdt->link);
864 dsp_mem_disable_ipbuf();
868 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
872 static ssize_t dsp_task_read_wd_psv(struct file *file, char __user *buf,
873 size_t count, loff_t *ppos)
875 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
876 struct taskdev *dev = taskdev[minor];
881 } else if (count & 0x1) {
883 "omapdsp: odd count is illegal for DSP task device.\n");
890 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
893 mbcompose_send_and_wait(WDREQ, dev->task->tid, 0, &dev->read_wait_q);
895 if (fifo_empty(&dev->rcvdt.fifo)) {
897 if (signal_pending(current))
902 ret = copy_to_user_fm_fifo(buf, &dev->rcvdt.fifo, count);
905 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
909 static ssize_t dsp_task_read_bk_psv(struct file *file, char __user *buf,
910 size_t count, loff_t *ppos)
912 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
913 struct taskdev *dev = taskdev[minor];
914 struct rcvdt_bk_struct *rcvdt = &dev->rcvdt.bk;
919 } else if (count & 0x1) {
921 "omapdsp: odd count is illegal for DSP task device.\n");
923 } else if ((int)buf & 0x1) {
925 "omapdsp: buf should be word aligned for "
926 "dsp_task_read().\n");
930 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
933 mbcompose_send_and_wait(BKREQ, dev->task->tid, count/2,
936 if (ipblink_empty(&rcvdt->link)) {
938 if (signal_pending(current))
944 * We will not receive more than requested count.
946 if (sndtyp_pvt(dev->task->ttyp)) {
948 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_r;
952 if (dsp_mem_enable(ipbp) < 0) {
956 src = MKVIRT(ipbp->ah, ipbp->al);
957 rcvcnt = ((unsigned long)ipbp->c) * 2;
958 if (dsp_address_validate(src, rcvcnt, "task %s read buffer",
959 dev->task->name) < 0) {
963 if (dsp_mem_enable(src) < 0) {
969 if (copy_to_user_dsp(buf, src, count)) {
973 ipblink_del_pvt(&rcvdt->link);
974 release_ipbuf_pvt(ipbp);
977 dsp_mem_disable(src);
979 dsp_mem_disable(ipbp);
982 struct ipbuf_head *ipb_h = bid_to_ipbuf(rcvdt->link.top);
985 if (dsp_mem_enable_ipbuf() < 0) {
989 rcvcnt = ((unsigned long)ipb_h->p->c) * 2;
992 if (copy_to_user_dsp(buf, ipb_h->p->d, count)) {
996 ipblink_del_top(&rcvdt->link);
1000 dsp_mem_disable_ipbuf();
1004 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
1008 static ssize_t dsp_task_write_wd(struct file *file, const char __user *buf,
1009 size_t count, loff_t *ppos)
1011 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1012 struct taskdev *dev = taskdev[minor];
1018 } else if (count & 0x1) {
1020 "omapdsp: odd count is illegal for DSP task device.\n");
1027 if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex))
1030 if (dev->wsz == 0) {
1032 DECLARE_WAITQUEUE(wait, current);
1034 add_wait_queue(&dev->write_wait_q, &wait);
1035 current_state = current->state;
1036 set_current_state(TASK_INTERRUPTIBLE);
1037 if (dev->wsz == 0) /* last check */
1039 set_current_state(current_state);
1040 remove_wait_queue(&dev->write_wait_q, &wait);
1041 if (dev->wsz == 0) {
1043 if (signal_pending(current))
1049 if (copy_from_user(&wd, buf, count)) {
1054 spin_lock(&dev->wsz_lock);
1055 if (mbcompose_send(WDSND, dev->task->tid, wd) < 0) {
1056 spin_unlock(&dev->wsz_lock);
1060 if (rcvtyp_acv(dev->task->ttyp))
1062 spin_unlock(&dev->wsz_lock);
1065 taskdev_unlock_and_stateunlock(dev, &dev->write_mutex);
1069 static ssize_t dsp_task_write_bk(struct file *file, const char __user *buf,
1070 size_t count, loff_t *ppos)
1072 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1073 struct taskdev *dev = taskdev[minor];
1078 } else if (count & 0x1) {
1080 "omapdsp: odd count is illegal for DSP task device.\n");
1082 } else if ((int)buf & 0x1) {
1084 "omapdsp: buf should be word aligned for "
1085 "dsp_task_write().\n");
1089 if (taskdev_lock_and_statelock_attached(dev, &dev->write_mutex))
1092 if (dev->wsz == 0) {
1094 DECLARE_WAITQUEUE(wait, current);
1096 add_wait_queue(&dev->write_wait_q, &wait);
1097 current_state = current->state;
1098 set_current_state(TASK_INTERRUPTIBLE);
1099 if (dev->wsz == 0) /* last check */
1101 set_current_state(current_state);
1102 remove_wait_queue(&dev->write_wait_q, &wait);
1103 if (dev->wsz == 0) {
1105 if (signal_pending(current))
1111 if (count > dev->wsz)
1114 if (rcvtyp_pvt(dev->task->ttyp)) {
1116 struct ipbuf_p *ipbp = dev->task->ipbuf_pvt_w;
1119 if (dsp_mem_enable(ipbp) < 0) {
1123 dst = MKVIRT(ipbp->ah, ipbp->al);
1124 if (dsp_address_validate(dst, count, "task %s write buffer",
1125 dev->task->name) < 0) {
1129 if (dsp_mem_enable(dst) < 0) {
1133 if (copy_from_user_dsp(dst, buf, count)) {
1138 ipbp->s = dev->task->tid;
1139 spin_lock(&dev->wsz_lock);
1140 if (mbcompose_send(BKSNDP, dev->task->tid, 0) == 0) {
1141 if (rcvtyp_acv(dev->task->ttyp))
1145 spin_unlock(&dev->wsz_lock);
1147 dsp_mem_disable(dst);
1149 dsp_mem_disable(ipbp);
1152 struct ipbuf_head *ipb_h;
1154 if (dsp_mem_enable_ipbuf() < 0) {
1158 if ((ipb_h = get_free_ipbuf(dev->task->tid)) == NULL)
1160 if (copy_from_user_dsp(ipb_h->p->d, buf, count)) {
1161 release_ipbuf(ipb_h);
1165 ipb_h->p->c = count/2;
1166 ipb_h->p->sa = dev->task->tid;
1167 spin_lock(&dev->wsz_lock);
1168 if (mbcompose_send(BKSND, dev->task->tid, ipb_h->bid) == 0) {
1169 if (rcvtyp_acv(dev->task->ttyp))
1172 ipb_bsycnt_inc(&ipbcfg);
1174 release_ipbuf(ipb_h);
1175 spin_unlock(&dev->wsz_lock);
1177 dsp_mem_disable_ipbuf();
1181 taskdev_unlock_and_stateunlock(dev, &dev->write_mutex);
1185 static unsigned int dsp_task_poll(struct file * file, poll_table * wait)
1187 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
1188 struct taskdev *dev = taskdev[minor];
1189 struct dsptask *task = dev->task;
1190 unsigned int mask = 0;
1192 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
1194 poll_wait(file, &dev->read_wait_q, wait);
1195 poll_wait(file, &dev->write_wait_q, wait);
1196 if (sndtyp_psv(task->ttyp) ||
1197 (sndtyp_wd(task->ttyp) && !fifo_empty(&dev->rcvdt.fifo)) ||
1198 (sndtyp_bk(task->ttyp) && !ipblink_empty(&dev->rcvdt.bk.link)))
1199 mask |= POLLIN | POLLRDNORM;
1201 mask |= POLLOUT | POLLWRNORM;
1202 devstate_read_unlock(dev);
1207 static int dsp_tctl_issue(struct taskdev *dev, u16 cmd, int argc, u16 argv[])
1210 struct mb_exarg mbarg, *mbargp;
1218 * system reserved TCTL commands
1232 * user-defined TCTL commands
1234 else if (cmd < 0x8100) {
1235 /* 0x8000-0x80ff: no arg, non-interactive */
1238 } else if (cmd < 0x8200) {
1239 /* 0x8100-0x81ff: 1 arg, non-interactive */
1242 } else if (cmd < 0x9000) {
1243 /* 0x8200-0x8fff: reserved */
1245 } else if (cmd < 0x9100) {
1246 /* 0x9000-0x90ff: no arg, interactive */
1249 } else if (cmd < 0x9200) {
1250 /* 0x9100-0x91ff: 1 arg, interactive */
1254 /* 0x9200-0xffff: reserved */
1259 * if argc < 0, use tctl_argc as is.
1260 * if argc >= 0, check arg count.
1262 if ((argc >= 0) && (argc != tctl_argc))
1268 if (taskdev_lock_interruptible(dev, &dev->tctl_mutex))
1271 tid = dev->task->tid;
1272 if (tctl_argc > 0) {
1273 mbarg.argc = tctl_argc;
1281 dev->tctl_stat = -EINVAL;
1283 mbcompose_send_and_wait_exarg(TCTL, tid, cmd, mbargp,
1285 if (signal_pending(current)) {
1289 if ((ret = dev->tctl_stat) < 0) {
1290 printk(KERN_ERR "omapdsp: TCTL not responding.\n");
1294 mbcompose_send_exarg(TCTL, tid, cmd, mbargp);
1297 mutex_unlock(&dev->tctl_mutex);
1301 static int dsp_task_ioctl(struct inode *inode, struct file *file,
1302 unsigned int cmd, unsigned long arg)
1304 unsigned int minor = MINOR(inode->i_rdev);
1305 struct taskdev *dev = taskdev[minor];
1308 if (cmd < 0x10000) {
1312 mbargv[0] = arg & 0xffff;
1313 return dsp_tctl_issue(dev, cmd, -1, mbargv);
1316 /* non TCTL ioctls */
1319 case TASK_IOCTL_LOCK:
1320 ret = taskdev_lock(dev);
1323 case TASK_IOCTL_UNLOCK:
1324 ret = taskdev_unlock(dev);
1327 case TASK_IOCTL_BFLSH:
1328 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
1330 ret = taskdev_flush_buf(dev);
1331 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
1334 case TASK_IOCTL_SETBSZ:
1335 if (taskdev_lock_and_statelock_attached(dev, &dev->read_mutex))
1337 ret = taskdev_set_fifosz(dev, arg);
1338 taskdev_unlock_and_stateunlock(dev, &dev->read_mutex);
1341 case TASK_IOCTL_GETNAME:
1343 if (copy_to_user((void __user *)arg, dev->name,
1344 strlen(dev->name) + 1))
1356 static void dsp_task_mmap_open(struct vm_area_struct *vma)
1358 struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1359 struct dsptask *task;
1360 size_t len = vma->vm_end - vma->vm_start;
1362 BUG_ON(!(dev->state & TASKDEV_ST_ATTACHED));
1364 exmap_use(task->map_base, len);
1367 static void dsp_task_mmap_close(struct vm_area_struct *vma)
1369 struct taskdev *dev = (struct taskdev *)vma->vm_private_data;
1370 struct dsptask *task;
1371 size_t len = vma->vm_end - vma->vm_start;
1373 BUG_ON(!(dev->state & TASKDEV_ST_ATTACHED));
1375 exmap_unuse(task->map_base, len);
1379 * On demand page allocation is not allowed. The mapping area is defined by
1380 * corresponding DSP tasks.
1382 static struct page *dsp_task_mmap_nopage(struct vm_area_struct *vma,
1383 unsigned long address, int *type)
1385 return NOPAGE_SIGBUS;
1388 static struct vm_operations_struct dsp_task_vm_ops = {
1389 .open = dsp_task_mmap_open,
1390 .close = dsp_task_mmap_close,
1391 .nopage = dsp_task_mmap_nopage,
1394 static int dsp_task_mmap(struct file *filp, struct vm_area_struct *vma)
1397 unsigned long tmp_padr, tmp_vmadr, off;
1398 size_t req_len, tmp_len;
1399 unsigned int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
1400 struct taskdev *dev = taskdev[minor];
1401 struct dsptask *task;
1404 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
1409 * Don't swap this area out
1410 * Don't dump this area to a core file
1412 vma->vm_flags |= VM_RESERVED | VM_IO;
1414 /* Do not cache this area */
1415 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1417 req_len = vma->vm_end - vma->vm_start;
1418 off = vma->vm_pgoff << PAGE_SHIFT;
1419 tmp_vmadr = vma->vm_start;
1420 tmp_vadr = task->map_base + off;
1422 tmp_padr = dsp_virt_to_phys(tmp_vadr, &tmp_len);
1423 if (tmp_padr == 0) {
1425 "omapdsp: task %s: illegal address "
1426 "for mmap: %p", task->name, tmp_vadr);
1427 /* partial mapping will be cleared in upper layer */
1431 if (tmp_len > req_len)
1435 "omapdsp: mmap info: "
1436 "vmadr = %08lx, padr = %08lx, len = %x\n",
1437 tmp_vmadr, tmp_padr, tmp_len);
1438 if (remap_pfn_range(vma, tmp_vmadr, tmp_padr >> PAGE_SHIFT,
1439 tmp_len, vma->vm_page_prot) != 0) {
1441 "omapdsp: task %s: remap_page_range() failed.\n",
1443 /* partial mapping will be cleared in upper layer */
1449 tmp_vmadr += tmp_len;
1450 tmp_vadr += tmp_len;
1453 vma->vm_ops = &dsp_task_vm_ops;
1454 vma->vm_private_data = dev;
1455 exmap_use(task->map_base, vma->vm_end - vma->vm_start);
1458 devstate_read_unlock(dev);
1462 static int dsp_task_open(struct inode *inode, struct file *file)
1464 unsigned int minor = MINOR(inode->i_rdev);
1465 struct taskdev *dev;
1468 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL))
1472 mutex_lock(&dev->usecount_mutex);
1473 down_write(&dev->state_sem);
1475 /* state can be NOTASK, ATTACHED/FREEZED, KILLING, GARBAGE or INVALID here. */
1476 switch (dev->state & TASKDEV_ST_STATE_MASK) {
1477 case TASKDEV_ST_NOTASK:
1479 case TASKDEV_ST_ATTACHED:
1482 case TASKDEV_ST_INVALID:
1483 up_write(&dev->state_sem);
1484 mutex_unlock(&dev->usecount_mutex);
1487 case TASKDEV_ST_FREEZED:
1488 case TASKDEV_ST_KILLING:
1489 case TASKDEV_ST_GARBAGE:
1490 /* on the kill process. wait until it becomes NOTASK. */
1491 up_write(&dev->state_sem);
1492 mutex_unlock(&dev->usecount_mutex);
1493 if (devstate_write_lock(dev, TASKDEV_ST_NOTASK) < 0)
1495 devstate_write_unlock(dev);
1500 dev->state = TASKDEV_ST_ADDREQ;
1501 /* wake up twch daemon for tadd */
1503 up_write(&dev->state_sem);
1504 if (devstate_write_lock(dev, TASKDEV_ST_ATTACHED |
1505 TASKDEV_ST_ADDFAIL) < 0) {
1507 if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) {
1508 mutex_unlock(&dev->usecount_mutex);
1509 /* out of control ??? */
1512 dev->state = TASKDEV_ST_NOTASK;
1516 if (dev->state & TASKDEV_ST_ADDFAIL) {
1517 printk(KERN_ERR "omapdsp: task attach failed for %s!\n",
1520 dev->state = TASKDEV_ST_NOTASK;
1526 #ifndef CONFIG_OMAP_DSP_TASK_MULTIOPEN
1527 if (dev->usecount > 0) {
1528 up_write(&dev->state_sem);
1533 proc_list_add(&dev->proc_list_lock, &dev->proc_list, current, file);
1534 file->f_op = &dev->fops;
1535 up_write(&dev->state_sem);
1536 mutex_unlock(&dev->usecount_mutex);
1538 #ifdef DSP_PTE_FREE /* not used currently. */
1539 dsp_map_update(current);
1540 dsp_cur_users_add(current);
1541 #endif /* DSP_PTE_FREE */
1545 wake_up_interruptible_all(&dev->state_wait_q);
1546 up_write(&dev->state_sem);
1547 mutex_unlock(&dev->usecount_mutex);
1551 static int dsp_task_release(struct inode *inode, struct file *file)
1553 unsigned int minor = MINOR(inode->i_rdev);
1554 struct taskdev *dev = taskdev[minor];
1556 #ifdef DSP_PTE_FREE /* not used currently. */
1557 dsp_cur_users_del(current);
1558 #endif /* DSP_PTE_FREE */
1560 if (has_taskdev_lock(dev))
1561 taskdev_unlock(dev);
1563 proc_list_del(&dev->proc_list_lock, &dev->proc_list, current, file);
1564 mutex_lock(&dev->usecount_mutex);
1565 if (--dev->usecount > 0) {
1566 /* other processes are using this device. no state change. */
1567 mutex_unlock(&dev->usecount_mutex);
1572 down_write(&dev->state_sem);
1574 /* state can be ATTACHED/FREEZED, KILLING or GARBAGE here. */
1575 switch (dev->state & TASKDEV_ST_STATE_MASK) {
1577 case TASKDEV_ST_KILLING:
1580 case TASKDEV_ST_GARBAGE:
1581 dev->state = TASKDEV_ST_NOTASK;
1582 wake_up_interruptible_all(&dev->state_wait_q);
1585 case TASKDEV_ST_ATTACHED:
1586 case TASKDEV_ST_FREEZED:
1587 if (is_dynamic_task(minor)) {
1588 dev->state = TASKDEV_ST_DELREQ;
1589 /* wake up twch daemon for tdel */
1596 up_write(&dev->state_sem);
1597 mutex_unlock(&dev->usecount_mutex);
1604 int dsp_mkdev(char *name)
1606 struct taskdev *dev;
1608 unsigned char minor;
1611 if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
1612 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1616 if (mutex_lock_interruptible(&devmgr_lock))
1620 for (minor = 0; minor < TASKDEV_MAX; minor++) {
1621 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1623 "omapdsp: task device name %s is already "
1630 /* find free minor number */
1631 for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1632 if (taskdev[minor] == NULL)
1635 printk(KERN_ERR "omapdsp: Too many task devices.\n");
1640 if ((dev = kzalloc(sizeof(struct taskdev), GFP_KERNEL)) == NULL) {
1644 if ((status = taskdev_init(dev, name, minor)) < 0) {
1652 mutex_unlock(&devmgr_lock);
1656 int dsp_rmdev(char *name)
1658 unsigned char minor;
1662 if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
1663 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
1667 if (mutex_lock_interruptible(&devmgr_lock))
1670 /* find in dynamic devices */
1671 for (minor = n_task; minor < TASKDEV_MAX; minor++) {
1672 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name))
1676 /* find in static devices */
1677 for (minor = 0; minor < n_task; minor++) {
1678 if (taskdev[minor] && !strcmp(taskdev[minor]->name, name)) {
1680 "omapdsp: task device %s is static.\n", name);
1686 printk(KERN_ERR "omapdsp: task device %s not found.\n", name);
1691 if ((status = dsp_rmdev_minor(minor)) < 0)
1694 mutex_unlock(&devmgr_lock);
1698 static int dsp_rmdev_minor(unsigned char minor)
1700 struct taskdev *dev = taskdev[minor];
1702 while (!down_write_trylock(&dev->state_sem)) {
1703 down_read(&dev->state_sem);
1704 if (dev->state & (TASKDEV_ST_ATTACHED |
1705 TASKDEV_ST_FREEZED)) {
1707 * task is working. kill it.
1708 * ATTACHED -> FREEZED can be changed under
1709 * down_read of state_sem..
1711 dev->state = TASKDEV_ST_FREEZED;
1712 wake_up_interruptible_all(&dev->read_wait_q);
1713 wake_up_interruptible_all(&dev->write_wait_q);
1714 wake_up_interruptible_all(&dev->tctl_wait_q);
1716 up_read(&dev->state_sem);
1720 switch (dev->state & TASKDEV_ST_STATE_MASK) {
1722 case TASKDEV_ST_NOTASK:
1726 case TASKDEV_ST_ATTACHED:
1727 case TASKDEV_ST_FREEZED:
1728 /* task is working. kill it. */
1729 dev->state = TASKDEV_ST_KILLING;
1730 up_write(&dev->state_sem);
1731 dsp_tdel_bh(dev, TDEL_KILL);
1734 case TASKDEV_ST_ADDREQ:
1735 /* open() is waiting. drain it. */
1736 dev->state = TASKDEV_ST_ADDFAIL;
1737 wake_up_interruptible_all(&dev->state_wait_q);
1740 case TASKDEV_ST_DELREQ:
1741 /* nobody is waiting. */
1742 dev->state = TASKDEV_ST_NOTASK;
1743 wake_up_interruptible_all(&dev->state_wait_q);
1746 case TASKDEV_ST_ADDING:
1747 case TASKDEV_ST_DELING:
1748 case TASKDEV_ST_KILLING:
1749 case TASKDEV_ST_GARBAGE:
1750 case TASKDEV_ST_ADDFAIL:
1751 /* transient state. wait for a moment. */
1756 up_write(&dev->state_sem);
1759 /* wait for some time and hope the state is settled */
1760 devstate_read_lock_timeout(dev, TASKDEV_ST_NOTASK, 5 * HZ);
1761 if (!(dev->state & TASKDEV_ST_NOTASK)) {
1763 "omapdsp: illegal device state (%s) on rmdev %s.\n",
1764 devstate_name(dev->state), dev->name);
1767 dev->state = TASKDEV_ST_INVALID;
1768 devstate_read_unlock(dev);
1770 taskdev_delete(minor);
1776 struct file_operations dsp_task_fops = {
1777 .owner = THIS_MODULE,
1778 .poll = dsp_task_poll,
1779 .ioctl = dsp_task_ioctl,
1780 .open = dsp_task_open,
1781 .release = dsp_task_release,
1784 static void dsptask_dev_release(struct device *dev)
1788 static int taskdev_init(struct taskdev *dev, char *name, unsigned char minor)
1790 taskdev[minor] = dev;
1792 spin_lock_init(&dev->proc_list_lock);
1793 INIT_LIST_HEAD(&dev->proc_list);
1794 init_waitqueue_head(&dev->read_wait_q);
1795 init_waitqueue_head(&dev->write_wait_q);
1796 init_waitqueue_head(&dev->tctl_wait_q);
1797 mutex_init(&dev->read_mutex);
1798 mutex_init(&dev->write_mutex);
1799 mutex_init(&dev->tctl_mutex);
1800 mutex_init(&dev->lock);
1801 spin_lock_init(&dev->wsz_lock);
1802 dev->tctl_ret = -EINVAL;
1805 strncpy(dev->name, name, TNM_LEN);
1806 dev->name[TNM_LEN-1] = '\0';
1807 dev->state = (minor < n_task) ? TASKDEV_ST_ATTACHED : TASKDEV_ST_NOTASK;
1809 mutex_init(&dev->usecount_mutex);
1810 memcpy(&dev->fops, &dsp_task_fops, sizeof(struct file_operations));
1812 dev->dev.parent = &dsp_device.dev;
1813 dev->dev.bus = &dsptask_bus;
1814 sprintf(dev->dev.bus_id, "dsptask%d", minor);
1815 dev->dev.release = dsptask_dev_release;
1816 device_register(&dev->dev);
1817 device_create_file(&dev->dev, &dev_attr_devname);
1818 device_create_file(&dev->dev, &dev_attr_devstate);
1819 device_create_file(&dev->dev, &dev_attr_proc_list);
1820 class_device_create(dsp_task_class, NULL,
1821 MKDEV(OMAP_DSP_TASK_MAJOR, minor),
1822 NULL, "dsptask%d", minor);
1824 init_waitqueue_head(&dev->state_wait_q);
1825 init_rwsem(&dev->state_sem);
1830 static void taskdev_delete(unsigned char minor)
1832 struct taskdev *dev = taskdev[minor];
1836 device_remove_file(&dev->dev, &dev_attr_devname);
1837 device_remove_file(&dev->dev, &dev_attr_devstate);
1838 device_remove_file(&dev->dev, &dev_attr_proc_list);
1839 class_device_destroy(dsp_task_class, MKDEV(OMAP_DSP_TASK_MAJOR, minor));
1840 device_unregister(&dev->dev);
1841 proc_list_flush(&dev->proc_list_lock, &dev->proc_list);
1842 taskdev[minor] = NULL;
1845 static int taskdev_attach_task(struct taskdev *dev, struct dsptask *task)
1847 u16 ttyp = task->ttyp;
1851 sndtyp_wd(ttyp) ? dsp_task_read_wd_acv:
1852 /* sndtyp_bk */ dsp_task_read_bk_acv:
1854 sndtyp_wd(ttyp) ? dsp_task_read_wd_psv:
1855 /* sndtyp_bk */ dsp_task_read_bk_psv;
1856 if (sndtyp_wd(ttyp)) {
1860 fifosz = sndtyp_psv(ttyp) ? 2 : /* passive */
1862 if (init_fifo(&dev->rcvdt.fifo, fifosz) < 0) {
1864 "omapdsp: unable to allocate receive buffer. "
1865 "(%d bytes for %s)\n", fifosz, dev->name);
1870 INIT_IPBLINK(&dev->rcvdt.bk.link);
1871 dev->rcvdt.bk.rp = 0;
1875 rcvtyp_wd(ttyp) ? dsp_task_write_wd:
1876 /* rcvbyp_bk */ dsp_task_write_bk;
1877 dev->wsz = rcvtyp_acv(ttyp) ? 0 : /* active */
1878 rcvtyp_wd(ttyp) ? 2 : /* passive word */
1879 ipbcfg.lsz*2; /* passive block */
1881 if (task->map_length)
1882 dev->fops.mmap = dsp_task_mmap;
1884 device_create_file(&dev->dev, &dev_attr_taskname);
1885 device_create_file(&dev->dev, &dev_attr_ttyp);
1886 if (sndtyp_wd(ttyp)) {
1887 device_create_file(&dev->dev, &dev_attr_fifosz);
1888 device_create_file(&dev->dev, &dev_attr_fifocnt);
1890 device_create_file(&dev->dev, &dev_attr_ipblink);
1891 device_create_file(&dev->dev, &dev_attr_wsz);
1892 if (task->map_length)
1893 device_create_file(&dev->dev, &dev_attr_mmap);
1901 static void taskdev_detach_task(struct taskdev *dev)
1903 u16 ttyp = dev->task->ttyp;
1905 device_remove_file(&dev->dev, &dev_attr_taskname);
1906 device_remove_file(&dev->dev, &dev_attr_ttyp);
1907 if (sndtyp_wd(ttyp)) {
1908 device_remove_file(&dev->dev, &dev_attr_fifosz);
1909 device_remove_file(&dev->dev, &dev_attr_fifocnt);
1911 device_remove_file(&dev->dev, &dev_attr_ipblink);
1912 device_remove_file(&dev->dev, &dev_attr_wsz);
1913 if (dev->task->map_length)
1914 device_remove_file(&dev->dev, &dev_attr_mmap);
1916 dev->fops.read = NULL;
1917 taskdev_flush_buf(dev);
1918 if (sndtyp_wd(ttyp))
1919 free_fifo(&dev->rcvdt.fifo);
1921 dev->fops.write = NULL;
1924 printk(KERN_INFO "omapdsp: taskdev %s disabled.\n", dev->name);
1929 * tadd / tdel / tkill
1931 static int dsp_tadd(struct taskdev *dev, dsp_long_t adr)
1933 struct dsptask *task;
1934 struct mb_exarg arg;
1935 u8 tid, tid_response;
1939 if (!devstate_write_lock_and_test(dev, TASKDEV_ST_ADDREQ)) {
1941 "omapdsp: taskdev %s is not requesting for tadd. "
1942 "(state is %s)\n", dev->name, devstate_name(dev->state));
1945 dev->state = TASKDEV_ST_ADDING;
1946 devstate_write_unlock(dev);
1948 if (adr == TADD_ABORTADR) {
1949 /* aborting tadd intentionally */
1950 printk(KERN_INFO "omapdsp: tadd address is ABORTADR.\n");
1953 if (adr >= DSPSPACE_SIZE) {
1955 "omapdsp: illegal address 0x%08x for tadd\n", adr);
1960 adr >>= 1; /* word address */
1961 argv[0] = adr >> 16; /* addrh */
1962 argv[1] = adr & 0xffff; /* addrl */
1964 if (mutex_lock_interruptible(&cfg_lock)) {
1969 cfg_cmd = MBX_CMD_DSP_TADD;
1974 if (dsp_mem_sync_inc() < 0) {
1975 printk(KERN_ERR "omapdsp: memory sync failed!\n");
1979 dsp_mbcmd_send_and_wait_exarg(&mb, &arg, &cfg_wait_q);
1982 cfg_tid = OMAP_DSP_TID_ANON;
1984 mutex_unlock(&cfg_lock);
1986 if (tid == TID_ANON) {
1987 printk(KERN_ERR "omapdsp: tadd failed!\n");
1991 if ((tid < n_task) || dsptask[tid]) {
1992 printk(KERN_ERR "omapdsp: illegal tid (%d)!\n", tid);
1996 if ((task = kzalloc(sizeof(struct dsptask), GFP_KERNEL)) == NULL) {
2001 if ((ret = dsp_task_config(task, tid)) < 0)
2004 if (strcmp(dev->name, task->name)) {
2006 "omapdsp: task name (%s) doesn't match with "
2007 "device name (%s).\n", task->name, dev->name);
2012 if ((ret = taskdev_attach_task(dev, task)) < 0)
2015 dsp_task_init(task);
2016 printk(KERN_INFO "omapdsp: taskdev %s enabled.\n", dev->name);
2017 dev->state = TASKDEV_ST_ATTACHED;
2018 wake_up_interruptible_all(&dev->state_wait_q);
2025 printk(KERN_ERR "omapdsp: deleting the task...\n");
2027 dev->state = TASKDEV_ST_DELING;
2029 if (mutex_lock_interruptible(&cfg_lock)) {
2030 printk(KERN_ERR "omapdsp: aborting tdel process. "
2031 "DSP side could be corrupted.\n");
2035 cfg_cmd = MBX_CMD_DSP_TDEL;
2036 mbcompose_send_and_wait(TDEL, tid, TDEL_KILL, &cfg_wait_q);
2037 tid_response = cfg_tid;
2040 mutex_unlock(&cfg_lock);
2042 if (tid_response != tid)
2043 printk(KERN_ERR "omapdsp: tdel failed. "
2044 "DSP side could be corrupted.\n");
2047 dev->state = TASKDEV_ST_ADDFAIL;
2048 wake_up_interruptible_all(&dev->state_wait_q);
2052 int dsp_tadd_minor(unsigned char minor, dsp_long_t adr)
2054 struct taskdev *dev;
2058 if (mutex_lock_interruptible(&devmgr_lock))
2061 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2063 "omapdsp: no task device with minor %d\n", minor);
2068 if ((status = dsp_tadd(dev, adr)) < 0)
2072 mutex_unlock(&devmgr_lock);
2076 static int dsp_tdel(struct taskdev *dev)
2078 if (!devstate_write_lock_and_test(dev, TASKDEV_ST_DELREQ)) {
2080 "omapdsp: taskdev %s is not requesting for tdel. "
2081 "(state is %s)\n", dev->name, devstate_name(dev->state));
2084 dev->state = TASKDEV_ST_DELING;
2085 devstate_write_unlock(dev);
2087 return dsp_tdel_bh(dev, TDEL_SAFE);
2090 int dsp_tdel_minor(unsigned char minor)
2092 struct taskdev *dev;
2096 if (mutex_lock_interruptible(&devmgr_lock))
2099 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2101 "omapdsp: no task device with minor %d\n", minor);
2107 if ((status = dsp_tdel(dev)) < 0)
2111 mutex_unlock(&devmgr_lock);
2115 static int dsp_tkill(struct taskdev *dev)
2117 while (!down_write_trylock(&dev->state_sem)) {
2118 if (!devstate_read_lock_and_test(dev, (TASKDEV_ST_ATTACHED |
2119 TASKDEV_ST_FREEZED))) {
2121 "omapdsp: task has not been attached for "
2122 "taskdev %s\n", dev->name);
2125 /* ATTACHED -> FREEZED can be changed under read semaphore. */
2126 dev->state = TASKDEV_ST_FREEZED;
2127 wake_up_interruptible_all(&dev->read_wait_q);
2128 wake_up_interruptible_all(&dev->write_wait_q);
2129 wake_up_interruptible_all(&dev->tctl_wait_q);
2130 devstate_read_unlock(dev);
2134 if (!(dev->state & (TASKDEV_ST_ATTACHED |
2135 TASKDEV_ST_FREEZED))) {
2137 "omapdsp: task has not been attached for taskdev %s\n",
2139 devstate_write_unlock(dev);
2142 if (!is_dynamic_task(dev->task->tid)) {
2143 printk(KERN_ERR "omapdsp: task %s is not a dynamic task.\n",
2145 devstate_write_unlock(dev);
2148 dev->state = TASKDEV_ST_KILLING;
2149 devstate_write_unlock(dev);
2151 return dsp_tdel_bh(dev, TDEL_KILL);
2154 int dsp_tkill_minor(unsigned char minor)
2156 struct taskdev *dev;
2160 if (mutex_lock_interruptible(&devmgr_lock))
2163 if ((minor >= TASKDEV_MAX) || ((dev = taskdev[minor]) == NULL)) {
2165 "omapdsp: no task device with minor %d\n", minor);
2171 if ((status = dsp_tkill(dev)) < 0)
2175 mutex_unlock(&devmgr_lock);
2179 static int dsp_tdel_bh(struct taskdev *dev, u16 type)
2181 struct dsptask *task;
2182 u8 tid, tid_response;
2187 if (mutex_lock_interruptible(&cfg_lock)) {
2188 if (type == TDEL_SAFE) {
2189 dev->state = TASKDEV_ST_DELREQ;
2192 tid_response = TID_ANON;
2198 cfg_cmd = MBX_CMD_DSP_TDEL;
2199 mbcompose_send_and_wait(TDEL, tid, type, &cfg_wait_q);
2200 tid_response = cfg_tid;
2203 mutex_unlock(&cfg_lock);
2206 taskdev_detach_task(dev);
2207 dsp_task_unconfig(task);
2210 if (tid_response != tid) {
2211 printk(KERN_ERR "omapdsp: %s failed!\n",
2212 (type == TDEL_SAFE) ? "tdel" : "tkill");
2215 down_write(&dev->state_sem);
2216 dev->state = (dev->usecount > 0) ? TASKDEV_ST_GARBAGE :
2218 wake_up_interruptible_all(&dev->state_wait_q);
2219 up_write(&dev->state_sem);
2227 long taskdev_state_stale(unsigned char minor)
2229 if (taskdev[minor]) {
2230 long state = taskdev[minor]->state;
2231 taskdev[minor]->state |= TASKDEV_ST_STALE;
2234 return TASKDEV_ST_NOTASK;
2238 * functions called from mailbox interrupt routine
2240 void mbx_wdsnd(struct mbcmd *mb)
2243 struct dsptask *task = dsptask[tid];
2245 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2246 printk(KERN_ERR "mbx: WDSND with illegal tid! %d\n", tid);
2249 if (sndtyp_bk(task->ttyp)) {
2251 "mbx: WDSND from block sending task! (task%d)\n", tid);
2254 if (sndtyp_psv(task->ttyp) &&
2255 !waitqueue_active(&task->dev->read_wait_q)) {
2257 "mbx: WDSND from passive sending task (task%d) "
2258 "without request!\n", tid);
2262 write_word_to_fifo(&task->dev->rcvdt.fifo, mb->data);
2263 wake_up_interruptible(&task->dev->read_wait_q);
2266 void mbx_wdreq(struct mbcmd *mb)
2269 struct dsptask *task = dsptask[tid];
2270 struct taskdev *dev;
2272 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2273 printk(KERN_ERR "mbx: WDREQ with illegal tid! %d\n", tid);
2276 if (rcvtyp_psv(task->ttyp)) {
2278 "mbx: WDREQ from passive receiving task! (task%d)\n",
2284 spin_lock(&dev->wsz_lock);
2286 spin_unlock(&dev->wsz_lock);
2287 wake_up_interruptible(&dev->write_wait_q);
2290 void mbx_bksnd(struct mbcmd *mb)
2294 struct dsptask *task = dsptask[tid];
2295 struct ipbuf_head *ipb_h;
2298 if (bid >= ipbcfg.ln) {
2299 printk(KERN_ERR "mbx: BKSND with illegal bid! %d\n", bid);
2302 ipb_h = bid_to_ipbuf(bid);
2303 ipb_bsycnt_dec(&ipbcfg);
2304 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2305 printk(KERN_ERR "mbx: BKSND with illegal tid! %d\n", tid);
2306 goto unuse_ipbuf_out;
2308 if (sndtyp_wd(task->ttyp)) {
2310 "mbx: BKSND from word sending task! (task%d)\n", tid);
2311 goto unuse_ipbuf_out;
2313 if (sndtyp_pvt(task->ttyp)) {
2315 "mbx: BKSND from private sending task! (task%d)\n", tid);
2316 goto unuse_ipbuf_out;
2318 if (sync_with_dsp(&ipb_h->p->sd, tid, 10) < 0) {
2319 printk(KERN_ERR "mbx: BKSND - IPBUF sync failed!\n");
2323 /* should be done in DSP, but just in case. */
2324 ipb_h->p->next = BID_NULL;
2327 if (cnt > ipbcfg.lsz) {
2328 printk(KERN_ERR "mbx: BKSND cnt(%d) > ipbuf line size(%d)!\n",
2330 goto unuse_ipbuf_out;
2334 /* 0-byte send from DSP */
2335 unuse_ipbuf_nowait(ipb_h);
2338 ipblink_add_tail(&task->dev->rcvdt.bk.link, bid);
2339 /* we keep coming bid and return alternative line to DSP. */
2343 wake_up_interruptible(&task->dev->read_wait_q);
2347 unuse_ipbuf_nowait(ipb_h);
2351 void mbx_bkreq(struct mbcmd *mb)
2355 struct dsptask *task = dsptask[tid];
2356 struct taskdev *dev;
2358 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2359 printk(KERN_ERR "mbx: BKREQ with illegal tid! %d\n", tid);
2362 if (rcvtyp_wd(task->ttyp)) {
2364 "mbx: BKREQ from word receiving task! (task%d)\n", tid);
2367 if (rcvtyp_pvt(task->ttyp)) {
2369 "mbx: BKREQ from private receiving task! (task%d)\n",
2373 if (rcvtyp_psv(task->ttyp)) {
2375 "mbx: BKREQ from passive receiving task! (task%d)\n",
2381 spin_lock(&dev->wsz_lock);
2383 spin_unlock(&dev->wsz_lock);
2384 wake_up_interruptible(&dev->write_wait_q);
2387 void mbx_bkyld(struct mbcmd *mb)
2390 struct ipbuf_head *ipb_h;
2392 if (bid >= ipbcfg.ln) {
2393 printk(KERN_ERR "mbx: BKYLD with illegal bid! %d\n", bid);
2396 ipb_h = bid_to_ipbuf(bid);
2398 /* should be done in DSP, but just in case. */
2399 ipb_h->p->next = BID_NULL;
2401 /* we don't need to sync with DSP */
2402 ipb_bsycnt_dec(&ipbcfg);
2403 release_ipbuf(ipb_h);
2406 void mbx_bksndp(struct mbcmd *mb)
2409 struct dsptask *task = dsptask[tid];
2410 struct ipbuf_p *ipbp;
2412 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2413 printk(KERN_ERR "mbx: BKSNDP with illegal tid! %d\n", tid);
2416 if (sndtyp_wd(task->ttyp)) {
2418 "mbx: BKSNDP from word sending task! (task%d)\n", tid);
2421 if (sndtyp_gbl(task->ttyp)) {
2423 "mbx: BKSNDP from non-private sending task! (task%d)\n",
2429 * we should not have delayed block at this point
2430 * because read() routine releases the lock of the buffer and
2431 * until then DSP can't send next data.
2434 ipbp = task->ipbuf_pvt_r;
2435 if (sync_with_dsp(&ipbp->s, tid, 10) < 0) {
2436 printk(KERN_ERR "mbx: BKSNDP - IPBUF sync failed!\n");
2439 printk(KERN_DEBUG "mbx: ipbuf_pvt_r->a = 0x%08lx\n",
2440 MKLONG(ipbp->ah, ipbp->al));
2441 ipblink_add_pvt(&task->dev->rcvdt.bk.link);
2442 wake_up_interruptible(&task->dev->read_wait_q);
2445 void mbx_bkreqp(struct mbcmd *mb)
2448 struct dsptask *task = dsptask[tid];
2449 struct taskdev *dev;
2450 struct ipbuf_p *ipbp;
2452 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2453 printk(KERN_ERR "mbx: BKREQP with illegal tid! %d\n", tid);
2456 if (rcvtyp_wd(task->ttyp)) {
2458 "mbx: BKREQP from word receiving task! (task%d)\n", tid);
2461 if (rcvtyp_gbl(task->ttyp)) {
2463 "mbx: BKREQP from non-private receiving task! (task%d)\n", tid);
2466 if (rcvtyp_psv(task->ttyp)) {
2468 "mbx: BKREQP from passive receiving task! (task%d)\n", tid);
2472 ipbp = task->ipbuf_pvt_w;
2473 if (sync_with_dsp(&ipbp->s, TID_FREE, 10) < 0) {
2474 printk(KERN_ERR "mbx: BKREQP - IPBUF sync failed!\n");
2477 printk(KERN_DEBUG "mbx: ipbuf_pvt_w->a = 0x%08lx\n",
2478 MKLONG(ipbp->ah, ipbp->al));
2480 spin_lock(&dev->wsz_lock);
2481 dev->wsz = ipbp->c*2;
2482 spin_unlock(&dev->wsz_lock);
2483 wake_up_interruptible(&dev->write_wait_q);
2486 void mbx_tctl(struct mbcmd *mb)
2489 struct dsptask *task = dsptask[tid];
2491 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2492 printk(KERN_ERR "mbx: TCTL with illegal tid! %d\n", tid);
2496 if (!waitqueue_active(&task->dev->tctl_wait_q)) {
2497 printk(KERN_WARNING "mbx: unexpected TCTL from DSP!\n");
2501 task->dev->tctl_stat = mb->data;
2502 wake_up_interruptible(&task->dev->tctl_wait_q);
2505 void mbx_tcfg(struct mbcmd *mb)
2508 struct dsptask *task = dsptask[tid];
2513 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2514 printk(KERN_ERR "mbx: TCFG with illegal tid! %d\n", tid);
2517 if ((task->state != TASK_ST_CFGREQ) || (cfg_cmd != MBX_CMD_DSP_TCFG)) {
2518 printk(KERN_WARNING "mbx: unexpected TCFG from DSP!\n");
2522 if (dsp_mem_enable(ipbuf_sys_da) < 0) {
2523 printk(KERN_ERR "mbx: TCFG - ipbuf_sys_da read failed!\n");
2524 dsp_mem_disable(ipbuf_sys_da);
2527 if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2528 printk(KERN_ERR "mbx: TCFG - IPBUF sync failed!\n");
2529 dsp_mem_disable(ipbuf_sys_da);
2534 * read configuration data on system IPBUF
2536 buf = ipbuf_sys_da->d;
2537 task->ttyp = buf[0];
2538 task->ipbuf_pvt_r = MKVIRT(buf[1], buf[2]);
2539 task->ipbuf_pvt_w = MKVIRT(buf[3], buf[4]);
2540 task->map_base = MKVIRT(buf[5], buf[6]);
2541 task->map_length = MKLONG(buf[7], buf[8]) << 1; /* word -> byte */
2542 tnm = MKVIRT(buf[9], buf[10]);
2543 release_ipbuf_pvt(ipbuf_sys_da);
2544 dsp_mem_disable(ipbuf_sys_da);
2547 * copy task name string
2549 if (dsp_address_validate(tnm, TNM_LEN, "task name buffer") < 0) {
2550 task->name[0] = '\0';
2554 for (i = 0; i < TNM_LEN-1; i++) {
2555 /* avoiding byte access */
2557 task->name[i] = tmp & 0x00ff;
2561 task->name[TNM_LEN-1] = '\0';
2563 task->state = TASK_ST_READY;
2565 wake_up_interruptible(&cfg_wait_q);
2568 void mbx_tadd(struct mbcmd *mb)
2572 if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBX_CMD_DSP_TADD)) {
2573 printk(KERN_WARNING "mbx: unexpected TADD from DSP!\n");
2577 wake_up_interruptible(&cfg_wait_q);
2580 void mbx_tdel(struct mbcmd *mb)
2584 if ((!waitqueue_active(&cfg_wait_q)) || (cfg_cmd != MBX_CMD_DSP_TDEL)) {
2585 printk(KERN_WARNING "mbx: unexpected TDEL from DSP!\n");
2589 wake_up_interruptible(&cfg_wait_q);
2592 void mbx_err_fatal(u8 tid)
2594 struct dsptask *task = dsptask[tid];
2595 struct taskdev *dev;
2597 if ((tid >= TASKDEV_MAX) || (task == NULL)) {
2598 printk(KERN_ERR "mbx: FATAL ERR with illegal tid! %d\n", tid);
2602 /* wake up waiting processes */
2604 wake_up_interruptible_all(&dev->read_wait_q);
2605 wake_up_interruptible_all(&dev->write_wait_q);
2606 wake_up_interruptible_all(&dev->tctl_wait_q);
2609 static u16 *dbg_buf;
2610 static u16 dbg_buf_sz, dbg_line_sz;
2613 int dsp_dbg_config(u16 *buf, u16 sz, u16 lsz)
2615 #ifdef OLD_BINARY_SUPPORT
2616 if ((mbx_revision == MBREV_3_0) || (mbx_revision == MBREV_3_2)) {
2625 if (dsp_address_validate(buf, sz, "debug buffer") < 0)
2630 "omapdsp: dbg_buf lsz (%d) is greater than its "
2631 "buffer size (%d)\n", lsz, sz);
2643 void dsp_dbg_stop(void)
2648 #ifdef OLD_BINARY_SUPPORT
2649 static void mbx_dbg_old(struct mbcmd *mb);
2652 void mbx_dbg(struct mbcmd *mb)
2656 char s[80], *s_end = &s[79], *p;
2660 #ifdef OLD_BINARY_SUPPORT
2661 if ((mbx_revision == MBREV_3_0) || (mbx_revision == MBREV_3_2)) {
2667 if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2668 (tid != TID_ANON)) {
2669 printk(KERN_ERR "mbx: DBG with illegal tid! %d\n", tid);
2672 if (dbg_buf == NULL) {
2673 printk(KERN_ERR "mbx: DBG command received, but "
2674 "dbg_buf has not been configured yet.\n");
2678 if (dsp_mem_enable(dbg_buf) < 0)
2681 src = &dbg_buf[dbg_rp];
2683 for (i = 0; i < cnt; i++) {
2686 * Be carefull that dbg_buf should not be read with
2687 * 1-byte access since it might be placed in DARAM/SARAM
2688 * and it can cause unexpected byteswap.
2690 * *(p++) = *(src++) & 0xff;
2691 * causes 1-byte access!
2694 *(p++) = tmp & 0xff;
2695 if (*(p-1) == '\n') {
2697 printk(KERN_INFO "%s", s);
2703 printk(KERN_INFO "%s\n", s);
2710 printk(KERN_INFO "%s\n", s);
2712 if ((dbg_rp += cnt + 1) > dbg_buf_sz - dbg_line_sz)
2715 dsp_mem_disable(dbg_buf);
2718 #ifdef OLD_BINARY_SUPPORT
2719 static void mbx_dbg_old(struct mbcmd *mb)
2722 char s[80], *s_end = &s[79], *p;
2728 if (((tid >= TASKDEV_MAX) || (dsptask[tid] == NULL)) &&
2729 (tid != TID_ANON)) {
2730 printk(KERN_ERR "mbx: DBG with illegal tid! %d\n", tid);
2733 if (dsp_mem_enable(ipbuf_sys_da) < 0) {
2734 printk(KERN_ERR "mbx: DBG - ipbuf_sys_da read failed!\n");
2737 if (sync_with_dsp(&ipbuf_sys_da->s, tid, 10) < 0) {
2738 printk(KERN_ERR "mbx: DBG - IPBUF sync failed!\n");
2741 buf = ipbuf_sys_da->d;
2743 src = MKVIRT(buf[1], buf[2]);
2744 if (dsp_address_validate(src, cnt, "dbg buffer") < 0)
2747 if (dsp_mem_enable(src) < 0)
2751 for (i = 0; i < cnt; i++) {
2754 * Be carefull that ipbuf should not be read with
2755 * 1-byte access since it might be placed in DARAM/SARAM
2756 * and it can cause unexpected byteswap.
2758 * *(p++) = *(src++) & 0xff;
2759 * causes 1-byte access!
2762 *(p++) = tmp & 0xff;
2763 if (*(p-1) == '\n') {
2765 printk(KERN_INFO "%s", s);
2771 printk(KERN_INFO "%s\n", s);
2778 printk(KERN_INFO "%s\n", s);
2781 dsp_mem_disable(src);
2783 release_ipbuf_pvt(ipbuf_sys_da);
2785 dsp_mem_disable(ipbuf_sys_da);
2787 #endif /* OLD_BINARY_SUPPORT */
2790 * sysfs files: for each device
2794 static ssize_t devname_show(struct device *d, struct device_attribute *attr,
2797 return sprintf(buf, "%s\n", to_taskdev(d)->name);
2801 static ssize_t devstate_show(struct device *d, struct device_attribute *attr,
2804 return sprintf(buf, "%s\n", devstate_name(to_taskdev(d)->state));
2808 static ssize_t proc_list_show(struct device *d, struct device_attribute *attr,
2811 struct taskdev *dev;
2812 struct proc_list *pl;
2815 dev = to_taskdev(d);
2816 spin_lock(&dev->proc_list_lock);
2817 list_for_each_entry(pl, &dev->proc_list, list_head) {
2818 /* need to lock tasklist_lock before calling
2819 * find_task_by_pid_type. */
2820 if (find_task_by_pid_type(PIDTYPE_PID, pl->pid) != NULL)
2821 len += sprintf(buf + len, "%d\n", pl->pid);
2822 read_unlock(&tasklist_lock);
2824 spin_unlock(&dev->proc_list_lock);
2830 static ssize_t taskname_show(struct device *d, struct device_attribute *attr,
2833 struct taskdev *dev = to_taskdev(d);
2836 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
2839 len = sprintf(buf, "%s\n", dev->task->name);
2841 devstate_read_unlock(dev);
2846 static ssize_t ttyp_show(struct device *d, struct device_attribute *attr,
2849 struct taskdev *dev = to_taskdev(d);
2853 if (!devstate_read_lock_and_test(dev, TASKDEV_ST_ATTACHED))
2856 ttyp = dev->task->ttyp;
2857 len += sprintf(buf + len, "0x%04x\n", ttyp);
2858 len += sprintf(buf + len, "%s %s send\n",
2859 (sndtyp_acv(ttyp)) ? "active" :
2861 (sndtyp_wd(ttyp)) ? "word" :
2862 (sndtyp_pvt(ttyp)) ? "private block" :
2864 len += sprintf(buf + len, "%s %s receive\n",
2865 (rcvtyp_acv(ttyp)) ? "active" :
2867 (rcvtyp_wd(ttyp)) ? "word" :
2868 (rcvtyp_pvt(ttyp)) ? "private block" :
2871 devstate_read_unlock(dev);
2876 static ssize_t fifosz_show(struct device *d, struct device_attribute *attr,
2879 struct fifo_struct *fifo = &to_taskdev(d)->rcvdt.fifo;
2880 return sprintf(buf, "%d\n", fifo->sz);
2883 static int fifosz_store(struct device *d, struct device_attribute *attr,
2884 const char *buf, size_t count)
2886 struct taskdev *dev = to_taskdev(d);
2887 unsigned long fifosz;
2890 fifosz = simple_strtol(buf, NULL, 10);
2891 ret = taskdev_set_fifosz(dev, fifosz);
2893 return (ret < 0) ? ret : strlen(buf);
2897 static ssize_t fifocnt_show(struct device *d, struct device_attribute *attr,
2900 struct fifo_struct *fifo = &to_taskdev(d)->rcvdt.fifo;
2901 return sprintf(buf, "%d\n", fifo->cnt);
2905 static __inline__ char *bid_name(u16 bid)
2915 sprintf(s, "%d", bid);
2920 static ssize_t ipblink_show(struct device *d, struct device_attribute *attr,
2923 struct rcvdt_bk_struct *rcvdt = &to_taskdev(d)->rcvdt.bk;
2926 spin_lock(&rcvdt->link.lock);
2927 len = sprintf(buf, "top %s\ntail %s\n",
2928 bid_name(rcvdt->link.top), bid_name(rcvdt->link.tail));
2929 spin_unlock(&rcvdt->link.lock);
2935 static ssize_t wsz_show(struct device *d, struct device_attribute *attr,
2938 return sprintf(buf, "%d\n", to_taskdev(d)->wsz);
2942 static ssize_t mmap_show(struct device *d, struct device_attribute *attr,
2945 struct dsptask *task = to_taskdev(d)->task;
2946 return sprintf(buf, "0x%p 0x%x\n", task->map_base, task->map_length);
2950 * called from ipbuf_show()
2952 int ipbuf_is_held(u8 tid, u16 bid)
2954 struct dsptask *task = dsptask[tid];
2955 struct ipblink *link;
2962 link = &task->dev->rcvdt.bk.link;
2963 spin_lock(&link->lock);
2964 ipblink_for_each(b, link) {
2965 if (b == bid) { /* found */
2970 spin_unlock(&link->lock);
2975 int __init dsp_taskmod_init(void)
2979 memset(taskdev, 0, sizeof(void *) * TASKDEV_MAX);
2980 memset(dsptask, 0, sizeof(void *) * TASKDEV_MAX);
2982 retval = register_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask",
2986 "omapdsp: failed to register task device: %d\n", retval);
2990 bus_register(&dsptask_bus);
2991 retval = driver_register(&dsptask_driver);
2994 "omapdsp: failed to register DSP task driver: %d\n",
2996 bus_unregister(&dsptask_bus);
2997 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");
3000 dsp_task_class = class_create(THIS_MODULE, "dsptask");
3005 void dsp_taskmod_exit(void)
3007 class_destroy(dsp_task_class);
3008 driver_unregister(&dsptask_driver);
3009 bus_unregister(&dsptask_bus);
3010 unregister_chrdev(OMAP_DSP_TASK_MAJOR, "dsptask");