Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[pandora-kernel.git] / drivers / staging / tidspbridge / include / dspbridge / node.h
1 /*
2  * node.h
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * DSP/BIOS Bridge Node Manager.
7  *
8  * Copyright (C) 2005-2006 Texas Instruments, Inc.
9  *
10  * This package is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  */
18
19 #ifndef NODE_
20 #define NODE_
21
22 #include <dspbridge/procpriv.h>
23
24 #include <dspbridge/nodedefs.h>
25 #include <dspbridge/dispdefs.h>
26 #include <dspbridge/nldrdefs.h>
27 #include <dspbridge/drv.h>
28
29 /*
30  *  ======== node_allocate ========
31  *  Purpose:
32  *      Allocate GPP resources to manage a node on the DSP.
33  *  Parameters:
34  *      hprocessor:         Handle of processor that is allocating the node.
35  *      node_uuid:          Pointer to a dsp_uuid for the node.
36  *      pargs:              Optional arguments to be passed to the node.
37  *      attr_in:            Optional pointer to node attributes (priority,
38  *                          timeout...)
39  *      noderes:             Location to store node resource info.
40  *  Returns:
41  *      0:            Success.
42  *      -ENOMEM:        Insufficient memory on GPP.
43  *      -ENOKEY:          Node UUID has not been registered.
44  *      -ESPIPE:        iAlg functions not found for a DAIS node.
45  *      -EDOM:         attr_in != NULL and attr_in->prio out of
46  *                          range.
47  *      -EPERM:          A failure occured, unable to allocate node.
48  *      -EBADR:    Proccessor is not in the running state.
49  *  Requires:
50  *      node_init(void) called.
51  *      hprocessor != NULL.
52  *      node_uuid != NULL.
53  *      noderes != NULL.
54  *  Ensures:
55  *      0:            IsValidNode(*ph_node).
56  *      error:              *noderes == NULL.
57  */
58 extern int node_allocate(struct proc_object *hprocessor,
59                                 const struct dsp_uuid *node_uuid,
60                                 const struct dsp_cbdata
61                                 *pargs, const struct dsp_nodeattrin
62                                 *attr_in,
63                                 struct node_res_object **noderes,
64                                 struct process_context *pr_ctxt);
65
66 /*
67  *  ======== node_alloc_msg_buf ========
68  *  Purpose:
69  *      Allocate and Prepare a buffer whose descriptor will be passed to a
70  *      Node within a (dsp_msg)message
71  *  Parameters:
72  *      hnode:          The node handle.
73  *      usize:          The size of the buffer to be allocated.
74  *      pattr:          Pointer to a dsp_bufferattr structure.
75  *      pbuffer:        Location to store the address of the allocated
76  *                      buffer on output.
77  *  Returns:
78  *      0:        Success.
79  *      -EFAULT:    Invalid node handle.
80  *      -ENOMEM:    Insufficent memory.
81  *      -EPERM:      General Failure.
82  *      -EINVAL:      Invalid Size.
83  *  Requires:
84  *      node_init(void) called.
85  *      pbuffer != NULL.
86  *  Ensures:
87  */
88 extern int node_alloc_msg_buf(struct node_object *hnode,
89                                      u32 usize, struct dsp_bufferattr
90                                      *pattr, u8 **pbuffer);
91
92 /*
93  *  ======== node_change_priority ========
94  *  Purpose:
95  *      Change the priority of an allocated node.
96  *  Parameters:
97  *      hnode:              Node handle returned from node_allocate.
98  *      prio:          New priority level to set node's priority to.
99  *  Returns:
100  *      0:            Success.
101  *      -EFAULT:        Invalid hnode.
102  *      -EDOM:         prio is out of range.
103  *      -EPERM: The specified node is not a task node.
104  *              Unable to change node's runtime priority level.
105  *      -EBADR:    Node is not in the NODE_ALLOCATED, NODE_PAUSED,
106  *                          or NODE_RUNNING state.
107  *      -ETIME:       A timeout occurred before the DSP responded.
108  *  Requires:
109  *      node_init(void) called.
110  *  Ensures:
111  *      0 && (Node's current priority == prio)
112  */
113 extern int node_change_priority(struct node_object *hnode, s32 prio);
114
115 /*
116  *  ======== node_close_orphans ========
117  *  Purpose:
118  *      Delete all nodes whose owning processor is being destroyed.
119  *  Parameters:
120  *      hnode_mgr:       Node manager object.
121  *      proc:          Handle to processor object being destroyed.
122  *  Returns:
123  *      0:        Success.
124  *      -EPERM:      Unable to delete all nodes belonging to proc.
125  *  Requires:
126  *      Valid hnode_mgr.
127  *      proc != NULL.
128  *  Ensures:
129  */
130 extern int node_close_orphans(struct node_mgr *hnode_mgr,
131                                      struct proc_object *proc);
132
133 /*
134  *  ======== node_connect ========
135  *  Purpose:
136  *      Connect two nodes on the DSP, or a node on the DSP to the GPP. In the
137  *      case that the connnection is being made between a node on the DSP and
138  *      the GPP, one of the node handles (either node1 or node2) must be
139  *      the constant NODE_HGPPNODE.
140  *  Parameters:
141  *      node1:         Handle of first node to connect to second node. If
142  *                      this is a connection from the GPP to node2, node1
143  *                      must be the constant NODE_HGPPNODE. Otherwise, node1
144  *                      must be a node handle returned from a successful call
145  *                      to Node_Allocate().
146  *      node2:         Handle of second node. Must be either NODE_HGPPNODE
147  *                      if this is a connection from DSP node to GPP, or a
148  *                      node handle returned from a successful call to
149  *                      node_allocate().
150  *      stream1:        Output stream index on first node, to be connected
151  *                      to second node's input stream. Value must range from
152  *                      0 <= stream1 < number of output streams.
153  *      stream2:        Input stream index on second node. Value must range
154  *                      from 0 <= stream2 < number of input streams.
155  *      pattrs:         Stream attributes (NULL ==> use defaults).
156  *      conn_param:     A pointer to a dsp_cbdata structure that defines
157  *                      connection parameter for device nodes to pass to DSP
158  *                      side.
159  *                      If the value of this parameter is NULL, then this API
160  *                      behaves like DSPNode_Connect. This parameter will have
161  *                      length of the string and the null terminated string in
162  *                      dsp_cbdata struct. This can be extended in future tp
163  *                      pass binary data.
164  *  Returns:
165  *      0:                Success.
166  *      -EFAULT:            Invalid node1 or node2.
167  *      -ENOMEM:            Insufficient host memory.
168  *      -EINVAL:             A stream index parameter is invalid.
169  *      -EISCONN:  A connection already exists for one of the
170  *                              indices stream1 or stream2.
171  *      -EBADR:        Either node1 or node2 is not in the
172  *                              NODE_ALLOCATED state.
173  *      -ECONNREFUSED: No more connections available.
174  *      -EPERM:              Attempt to make an illegal connection (eg,
175  *                              Device node to device node, or device node to
176  *                              GPP), the two nodes are on different DSPs.
177  *  Requires:
178  *      node_init(void) called.
179  *  Ensures:
180  */
181 extern int node_connect(struct node_object *node1,
182                                u32 stream1,
183                                struct node_object *node2,
184                                u32 stream2,
185                                struct dsp_strmattr *pattrs,
186                                struct dsp_cbdata
187                                *conn_param);
188
189 /*
190  *  ======== node_create ========
191  *  Purpose:
192  *      Create a node on the DSP by remotely calling the node's create
193  *      function. If necessary, load code that contains the node's create
194  *      function.
195  *  Parameters:
196  *      hnode:              Node handle returned from node_allocate().
197  *  Returns:
198  *      0:            Success.
199  *      -EFAULT:        Invalid hnode.
200  *      -ESPIPE:        Create function not found in the COFF file.
201  *      -EBADR:    Node is not in the NODE_ALLOCATED state.
202  *      -ENOMEM:        Memory allocation failure on the DSP.
203  *      -ETIME:       A timeout occurred before the DSP responded.
204  *      -EPERM:          A failure occurred, unable to create node.
205  *  Requires:
206  *      node_init(void) called.
207  *  Ensures:
208  */
209 extern int node_create(struct node_object *hnode);
210
211 /*
212  *  ======== node_create_mgr ========
213  *  Purpose:
214  *      Create a NODE Manager object. This object handles the creation,
215  *      deletion, and execution of nodes on the DSP target. The NODE Manager
216  *      also maintains a pipe map of used and available node connections.
217  *      Each DEV object should have exactly one NODE Manager object.
218  *
219  *  Parameters:
220  *      node_man:       Location to store node manager handle on output.
221  *      hdev_obj:     Device for this processor.
222  *  Returns:
223  *      0:        Success;
224  *      -ENOMEM:    Insufficient memory for requested resources.
225  *      -EPERM:      General failure.
226  *  Requires:
227  *      node_init(void) called.
228  *      node_man != NULL.
229  *      hdev_obj != NULL.
230  *  Ensures:
231  *      0:        Valide *node_man.
232  *      error:          *node_man == NULL.
233  */
234 extern int node_create_mgr(struct node_mgr **node_man,
235                                   struct dev_object *hdev_obj);
236
237 /*
238  *  ======== node_delete ========
239  *  Purpose:
240  *      Delete resources allocated in node_allocate(). If the node was
241  *      created, delete the node on the DSP by remotely calling the node's
242  *      delete function. Loads the node's delete function if necessary.
243  *      GPP side resources are freed after node's delete function returns.
244  *  Parameters:
245  *      noderes:              Node resource info handle returned from
246  *                                 node_allocate().
247  *      pr_ctxt:                Poninter to process context data.
248  *  Returns:
249  *      0:            Success.
250  *      -EFAULT:        Invalid hnode.
251  *      -ETIME:       A timeout occurred before the DSP responded.
252  *      -EPERM:          A failure occurred in deleting the node.
253  *      -ESPIPE:        Delete function not found in the COFF file.
254  *  Requires:
255  *      node_init(void) called.
256  *  Ensures:
257  *      0:            hnode is invalid.
258  */
259 extern int node_delete(struct node_res_object *noderes,
260                               struct process_context *pr_ctxt);
261
262 /*
263  *  ======== node_delete_mgr ========
264  *  Purpose:
265  *      Delete the NODE Manager.
266  *  Parameters:
267  *      hnode_mgr:       Node manager object.
268  *  Returns:
269  *      0:        Success.
270  *  Requires:
271  *      node_init(void) called.
272  *      Valid hnode_mgr.
273  *  Ensures:
274  */
275 extern int node_delete_mgr(struct node_mgr *hnode_mgr);
276
277 /*
278  *  ======== node_enum_nodes ========
279  *  Purpose:
280  *      Enumerate the nodes currently allocated for the DSP.
281  *  Parameters:
282  *      hnode_mgr:       Node manager returned from node_create_mgr().
283  *      node_tab:       Array to copy node handles into.
284  *      node_tab_size:   Number of handles that can be written to node_tab.
285  *      pu_num_nodes:     Location where number of node handles written to
286  *                      node_tab will be written.
287  *      pu_allocated:    Location to write total number of allocated nodes.
288  *  Returns:
289  *      0:        Success.
290  *      -EINVAL:      node_tab is too small to hold all node handles.
291  *  Requires:
292  *      Valid hnode_mgr.
293  *      node_tab != NULL || node_tab_size == 0.
294  *      pu_num_nodes != NULL.
295  *      pu_allocated != NULL.
296  *  Ensures:
297  *      - (-EINVAL && *pu_num_nodes == 0)
298  *      - || (0 && *pu_num_nodes <= node_tab_size)  &&
299  *        (*pu_allocated == *pu_num_nodes)
300  */
301 extern int node_enum_nodes(struct node_mgr *hnode_mgr,
302                                   void **node_tab,
303                                   u32 node_tab_size,
304                                   u32 *pu_num_nodes,
305                                   u32 *pu_allocated);
306
307 /*
308  *  ======== node_exit ========
309  *  Purpose:
310  *      Discontinue usage of NODE module.
311  *  Parameters:
312  *  Returns:
313  *  Requires:
314  *      node_init(void) successfully called before.
315  *  Ensures:
316  *      Any resources acquired in node_init(void) will be freed when last NODE
317  *      client calls node_exit(void).
318  */
319 extern void node_exit(void);
320
321 /*
322  *  ======== node_free_msg_buf ========
323  *  Purpose:
324  *      Free a message buffer previously allocated with node_alloc_msg_buf.
325  *  Parameters:
326  *      hnode:          The node handle.
327  *      pbuffer:        (Address) Buffer allocated by node_alloc_msg_buf.
328  *      pattr:          Same buffer attributes passed to node_alloc_msg_buf.
329  *  Returns:
330  *      0:        Success.
331  *      -EFAULT:    Invalid node handle.
332  *      -EPERM:      Failure to free the buffer.
333  *  Requires:
334  *      node_init(void) called.
335  *      pbuffer != NULL.
336  *  Ensures:
337  */
338 extern int node_free_msg_buf(struct node_object *hnode,
339                                     u8 *pbuffer,
340                                     struct dsp_bufferattr
341                                     *pattr);
342
343 /*
344  *  ======== node_get_attr ========
345  *  Purpose:
346  *      Copy the current attributes of the specified node into a dsp_nodeattr
347  *      structure.
348  *  Parameters:
349  *      hnode:          Node object allocated from node_allocate().
350  *      pattr:          Pointer to dsp_nodeattr structure to copy node's
351  *                      attributes.
352  *      attr_size:      Size of pattr.
353  *  Returns:
354  *      0:        Success.
355  *      -EFAULT:    Invalid hnode.
356  *  Requires:
357  *      node_init(void) called.
358  *      pattr != NULL.
359  *  Ensures:
360  *      0:        *pattrs contains the node's current attributes.
361  */
362 extern int node_get_attr(struct node_object *hnode,
363                                 struct dsp_nodeattr *pattr, u32 attr_size);
364
365 /*
366  *  ======== node_get_message ========
367  *  Purpose:
368  *      Retrieve a message from a node on the DSP. The node must be either a
369  *      message node, task node, or XDAIS socket node.
370  *      If a message is not available, this function will block until a
371  *      message is available, or the node's timeout value is reached.
372  *  Parameters:
373  *      hnode:          Node handle returned from node_allocate().
374  *      message:       Pointer to dsp_msg structure to copy the
375  *                      message into.
376  *      utimeout:       Timeout in milliseconds to wait for message.
377  *  Returns:
378  *      0:        Success.
379  *      -EFAULT:    Invalid hnode.
380  *      -EPERM: Cannot retrieve messages from this type of node.
381  *              Error occurred while trying to retrieve a message.
382  *      -ETIME:   Timeout occurred and no message is available.
383  *  Requires:
384  *      node_init(void) called.
385  *      message != NULL.
386  *  Ensures:
387  */
388 extern int node_get_message(struct node_object *hnode,
389                                    struct dsp_msg *message, u32 utimeout);
390
391 /*
392  *  ======== node_get_nldr_obj ========
393  *  Purpose:
394  *      Retrieve the Nldr manager
395  *  Parameters:
396  *      hnode_mgr:       Node Manager
397  *      nldr_ovlyobj:   Pointer to a Nldr manager handle
398  *  Returns:
399  *      0:        Success.
400  *      -EFAULT:    Invalid hnode.
401  *  Ensures:
402  */
403 extern int node_get_nldr_obj(struct node_mgr *hnode_mgr,
404                                     struct nldr_object **nldr_ovlyobj);
405
406 /*
407  *  ======== node_init ========
408  *  Purpose:
409  *      Initialize the NODE module.
410  *  Parameters:
411  *  Returns:
412  *      TRUE if initialization succeeded, FALSE otherwise.
413  *  Ensures:
414  */
415 extern bool node_init(void);
416
417 /*
418  *  ======== node_on_exit ========
419  *  Purpose:
420  *      Gets called when RMS_EXIT is received for a node. PROC needs to pass
421  *      this function as a parameter to msg_create(). This function then gets
422  *      called by the Bridge driver when an exit message for a node is received.
423  *  Parameters:
424  *      hnode:      Handle of the node that the exit message is for.
425  *      node_status:    Return status of the node's execute phase.
426  *  Returns:
427  *  Ensures:
428  */
429 void node_on_exit(struct node_object *hnode, s32 node_status);
430
431 /*
432  *  ======== node_pause ========
433  *  Purpose:
434  *      Suspend execution of a node currently running on the DSP.
435  *  Parameters:
436  *      hnode:              Node object representing a node currently
437  *                          running on the DSP.
438  *  Returns:
439  *      0:            Success.
440  *      -EFAULT:        Invalid hnode.
441  *      -EPERM: Node is not a task or socket node.
442  *              Failed to pause node.
443  *      -ETIME:       A timeout occurred before the DSP responded.
444  *      DSP_EWRONGSTSATE:   Node is not in NODE_RUNNING state.
445  *  Requires:
446  *      node_init(void) called.
447  *  Ensures:
448  */
449 extern int node_pause(struct node_object *hnode);
450
451 /*
452  *  ======== node_put_message ========
453  *  Purpose:
454  *      Send a message to a message node, task node, or XDAIS socket node.
455  *      This function will block until the message stream can accommodate
456  *      the message, or a timeout occurs. The message will be copied, so Msg
457  *      can be re-used immediately after return.
458  *  Parameters:
459  *      hnode:              Node handle returned by node_allocate().
460  *      pmsg:               Location of message to be sent to the node.
461  *      utimeout:           Timeout in msecs to wait.
462  *  Returns:
463  *      0:            Success.
464  *      -EFAULT:        Invalid hnode.
465  *      -EPERM: Messages can't be sent to this type of node.
466  *              Unable to send message.
467  *      -ETIME:       Timeout occurred before message could be set.
468  *      -EBADR:    Node is in invalid state for sending messages.
469  *  Requires:
470  *      node_init(void) called.
471  *      pmsg != NULL.
472  *  Ensures:
473  */
474 extern int node_put_message(struct node_object *hnode,
475                                    const struct dsp_msg *pmsg, u32 utimeout);
476
477 /*
478  *  ======== node_register_notify ========
479  *  Purpose:
480  *      Register to be notified on specific events for this node.
481  *  Parameters:
482  *      hnode:          Node handle returned by node_allocate().
483  *      event_mask:     Mask of types of events to be notified about.
484  *      notify_type:    Type of notification to be sent.
485  *      hnotification:  Handle to be used for notification.
486  *  Returns:
487  *      0:        Success.
488  *      -EFAULT:    Invalid hnode.
489  *      -ENOMEM:    Insufficient memory on GPP.
490  *      -EINVAL:     event_mask is invalid.
491  *      -ENOSYS:   Notification type specified by notify_type is not
492  *                      supported.
493  *  Requires:
494  *      node_init(void) called.
495  *      hnotification != NULL.
496  *  Ensures:
497  */
498 extern int node_register_notify(struct node_object *hnode,
499                                        u32 event_mask, u32 notify_type,
500                                        struct dsp_notification
501                                        *hnotification);
502
503 /*
504  *  ======== node_run ========
505  *  Purpose:
506  *      Start execution of a node's execute phase, or resume execution of
507  *      a node that has been suspended (via node_pause()) on the DSP. Load
508  *      the node's execute function if necessary.
509  *  Parameters:
510  *      hnode:              Node object representing a node currently
511  *                          running on the DSP.
512  *  Returns:
513  *      0:            Success.
514  *      -EFAULT:        Invalid hnode.
515  *      -EPERM: hnode doesn't represent a message, task or dais socket node.
516  *              Unable to start or resume execution.
517  *      -ETIME:       A timeout occurred before the DSP responded.
518  *      DSP_EWRONGSTSATE:   Node is not in NODE_PAUSED or NODE_CREATED state.
519  *      -ESPIPE:        Execute function not found in the COFF file.
520  *  Requires:
521  *      node_init(void) called.
522  *  Ensures:
523  */
524 extern int node_run(struct node_object *hnode);
525
526 /*
527  *  ======== node_terminate ========
528  *  Purpose:
529  *      Signal a node running on the DSP that it should exit its execute
530  *      phase function.
531  *  Parameters:
532  *      hnode:              Node object representing a node currently
533  *                          running on the DSP.
534  *      pstatus:            Location to store execute-phase function return
535  *                          value.
536  *  Returns:
537  *      0:            Success.
538  *      -EFAULT:        Invalid hnode.
539  *      -ETIME:       A timeout occurred before the DSP responded.
540  *      -EPERM: Type of node specified cannot be terminated.
541  *              Unable to terminate the node.
542  *      -EBADR:    Operation not valid for the current node state.
543  *  Requires:
544  *      node_init(void) called.
545  *      pstatus != NULL.
546  *  Ensures:
547  */
548 extern int node_terminate(struct node_object *hnode,
549                                  int *pstatus);
550
551 /*
552  *  ======== node_get_uuid_props ========
553  *  Purpose:
554  *      Fetch Node properties given the UUID
555  *  Parameters:
556  *
557  */
558 extern int node_get_uuid_props(void *hprocessor,
559                                       const struct dsp_uuid *node_uuid,
560                                       struct dsp_ndbprops
561                                       *node_props);
562
563 #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
564 /**
565  * node_find_addr() - Find the closest symbol to the given address.
566  *
567  * @node_mgr:           Node manager handle
568  * @sym_addr:           Given address to find the closest symbol
569  * @offset_range:               offset range to look fo the closest symbol
570  * @sym_addr_output:    Symbol Output address
571  * @sym_name:           String with the symbol name of the closest symbol
572  *
573  *      This function finds the closest symbol to the address where a MMU
574  *      Fault occurred on the DSP side.
575  */
576 int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr,
577                                 u32 offset_range, void *sym_addr_output,
578                                 char *sym_name);
579
580 enum node_state node_get_state(void *hnode);
581 #endif
582
583 #endif /* NODE_ */