staging: tidspbridge: convert pmgr to list_head
[deliverable/linux.git] / drivers / staging / tidspbridge / pmgr / dev.c
1 /*
2 * dev.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * Implementation of Bridge Bridge driver device operations.
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 #include <linux/types.h>
19 #include <linux/list.h>
20
21 /* ----------------------------------- Host OS */
22 #include <dspbridge/host_os.h>
23
24 /* ----------------------------------- DSP/BIOS Bridge */
25 #include <dspbridge/dbdefs.h>
26
27 /* ----------------------------------- Trace & Debug */
28 #include <dspbridge/dbc.h>
29
30 /* ----------------------------------- OS Adaptation Layer */
31 #include <dspbridge/ldr.h>
32
33 /* ----------------------------------- Platform Manager */
34 #include <dspbridge/cod.h>
35 #include <dspbridge/drv.h>
36 #include <dspbridge/proc.h>
37 #include <dspbridge/dmm.h>
38
39 /* ----------------------------------- Resource Manager */
40 #include <dspbridge/mgr.h>
41 #include <dspbridge/node.h>
42
43 /* ----------------------------------- Others */
44 #include <dspbridge/dspapi.h> /* DSP API version info. */
45
46 #include <dspbridge/chnl.h>
47 #include <dspbridge/io.h>
48 #include <dspbridge/msg.h>
49 #include <dspbridge/cmm.h>
50 #include <dspbridge/dspdeh.h>
51
52 /* ----------------------------------- This */
53 #include <dspbridge/dev.h>
54
55 /* ----------------------------------- Defines, Data Structures, Typedefs */
56
57 #define MAKEVERSION(major, minor) (major * 10 + minor)
58 #define BRD_API_VERSION MAKEVERSION(BRD_API_MAJOR_VERSION, \
59 BRD_API_MINOR_VERSION)
60
61 /* The Bridge device object: */
62 struct dev_object {
63 struct list_head link; /* Link to next dev_object. */
64 u8 dev_type; /* Device Type */
65 struct cfg_devnode *dev_node_obj; /* Platform specific dev id */
66 /* Bridge Context Handle */
67 struct bridge_dev_context *hbridge_context;
68 /* Function interface to Bridge driver. */
69 struct bridge_drv_interface bridge_interface;
70 struct brd_object *lock_owner; /* Client with exclusive access. */
71 struct cod_manager *cod_mgr; /* Code manager handle. */
72 struct chnl_mgr *hchnl_mgr; /* Channel manager. */
73 struct deh_mgr *hdeh_mgr; /* DEH manager. */
74 struct msg_mgr *hmsg_mgr; /* Message manager. */
75 struct io_mgr *hio_mgr; /* IO manager (CHNL, msg_ctrl) */
76 struct cmm_object *hcmm_mgr; /* SM memory manager. */
77 struct dmm_object *dmm_mgr; /* Dynamic memory manager. */
78 struct ldr_module *module_obj; /* Bridge Module handle. */
79 u32 word_size; /* DSP word size: quick access. */
80 struct drv_object *hdrv_obj; /* Driver Object */
81 struct list_head proc_list; /* List of Processor attached to
82 * this device */
83 struct node_mgr *hnode_mgr;
84 };
85
86 struct drv_ext {
87 struct list_head link;
88 char sz_string[MAXREGPATHLENGTH];
89 };
90
91 /* ----------------------------------- Globals */
92 static u32 refs; /* Module reference count */
93
94 /* ----------------------------------- Function Prototypes */
95 static int fxn_not_implemented(int arg, ...);
96 static int init_cod_mgr(struct dev_object *dev_obj);
97 static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
98 struct bridge_drv_interface *intf_fxns);
99 /*
100 * ======== dev_brd_write_fxn ========
101 * Purpose:
102 * Exported function to be used as the COD write function. This function
103 * is passed a handle to a DEV_hObject, then calls the
104 * device's bridge_brd_write() function.
105 */
106 u32 dev_brd_write_fxn(void *arb, u32 dsp_add, void *host_buf,
107 u32 ul_num_bytes, u32 mem_space)
108 {
109 struct dev_object *dev_obj = (struct dev_object *)arb;
110 u32 ul_written = 0;
111 int status;
112
113 DBC_REQUIRE(refs > 0);
114 DBC_REQUIRE(host_buf != NULL); /* Required of BrdWrite(). */
115 if (dev_obj) {
116 /* Require of BrdWrite() */
117 DBC_ASSERT(dev_obj->hbridge_context != NULL);
118 status = (*dev_obj->bridge_interface.pfn_brd_write) (
119 dev_obj->hbridge_context, host_buf,
120 dsp_add, ul_num_bytes, mem_space);
121 /* Special case of getting the address only */
122 if (ul_num_bytes == 0)
123 ul_num_bytes = 1;
124 if (!status)
125 ul_written = ul_num_bytes;
126
127 }
128 return ul_written;
129 }
130
131 /*
132 * ======== dev_create_device ========
133 * Purpose:
134 * Called by the operating system to load the PM Bridge Driver for a
135 * PM board (device).
136 */
137 int dev_create_device(struct dev_object **device_obj,
138 const char *driver_file_name,
139 struct cfg_devnode *dev_node_obj)
140 {
141 struct cfg_hostres *host_res;
142 struct ldr_module *module_obj = NULL;
143 struct bridge_drv_interface *drv_fxns = NULL;
144 struct dev_object *dev_obj = NULL;
145 struct chnl_mgrattrs mgr_attrs;
146 struct io_attrs io_mgr_attrs;
147 u32 num_windows;
148 struct drv_object *hdrv_obj = NULL;
149 struct drv_data *drv_datap = dev_get_drvdata(bridge);
150 int status = 0;
151 DBC_REQUIRE(refs > 0);
152 DBC_REQUIRE(device_obj != NULL);
153 DBC_REQUIRE(driver_file_name != NULL);
154
155 status = drv_request_bridge_res_dsp((void *)&host_res);
156
157 if (status) {
158 dev_dbg(bridge, "%s: Failed to reserve bridge resources\n",
159 __func__);
160 goto leave;
161 }
162
163 /* Get the Bridge driver interface functions */
164 bridge_drv_entry(&drv_fxns, driver_file_name);
165
166 /* Retrieve the Object handle from the driver data */
167 if (drv_datap && drv_datap->drv_object) {
168 hdrv_obj = drv_datap->drv_object;
169 } else {
170 status = -EPERM;
171 pr_err("%s: Failed to retrieve the object handle\n", __func__);
172 }
173
174 /* Create the device object, and pass a handle to the Bridge driver for
175 * storage. */
176 if (!status) {
177 DBC_ASSERT(drv_fxns);
178 dev_obj = kzalloc(sizeof(struct dev_object), GFP_KERNEL);
179 if (dev_obj) {
180 /* Fill out the rest of the Dev Object structure: */
181 dev_obj->dev_node_obj = dev_node_obj;
182 dev_obj->module_obj = module_obj;
183 dev_obj->cod_mgr = NULL;
184 dev_obj->hchnl_mgr = NULL;
185 dev_obj->hdeh_mgr = NULL;
186 dev_obj->lock_owner = NULL;
187 dev_obj->word_size = DSPWORDSIZE;
188 dev_obj->hdrv_obj = hdrv_obj;
189 dev_obj->dev_type = DSP_UNIT;
190 /* Store this Bridge's interface functions, based on its
191 * version. */
192 store_interface_fxns(drv_fxns,
193 &dev_obj->bridge_interface);
194
195 /* Call fxn_dev_create() to get the Bridge's device
196 * context handle. */
197 status = (dev_obj->bridge_interface.pfn_dev_create)
198 (&dev_obj->hbridge_context, dev_obj,
199 host_res);
200 /* Assert bridge_dev_create()'s ensure clause: */
201 DBC_ASSERT(status
202 || (dev_obj->hbridge_context != NULL));
203 } else {
204 status = -ENOMEM;
205 }
206 }
207 /* Attempt to create the COD manager for this device: */
208 if (!status)
209 status = init_cod_mgr(dev_obj);
210
211 /* Attempt to create the channel manager for this device: */
212 if (!status) {
213 mgr_attrs.max_channels = CHNL_MAXCHANNELS;
214 io_mgr_attrs.birq = host_res->birq_registers;
215 io_mgr_attrs.irq_shared =
216 (host_res->birq_attrib & CFG_IRQSHARED);
217 io_mgr_attrs.word_size = DSPWORDSIZE;
218 mgr_attrs.word_size = DSPWORDSIZE;
219 num_windows = host_res->num_mem_windows;
220 if (num_windows) {
221 /* Assume last memory window is for CHNL */
222 io_mgr_attrs.shm_base = host_res->dw_mem_base[1] +
223 host_res->dw_offset_for_monitor;
224 io_mgr_attrs.usm_length =
225 host_res->dw_mem_length[1] -
226 host_res->dw_offset_for_monitor;
227 } else {
228 io_mgr_attrs.shm_base = 0;
229 io_mgr_attrs.usm_length = 0;
230 pr_err("%s: No memory reserved for shared structures\n",
231 __func__);
232 }
233 status = chnl_create(&dev_obj->hchnl_mgr, dev_obj, &mgr_attrs);
234 if (status == -ENOSYS) {
235 /* It's OK for a device not to have a channel
236 * manager: */
237 status = 0;
238 }
239 /* Create CMM mgr even if Msg Mgr not impl. */
240 status = cmm_create(&dev_obj->hcmm_mgr,
241 (struct dev_object *)dev_obj, NULL);
242 /* Only create IO manager if we have a channel manager */
243 if (!status && dev_obj->hchnl_mgr) {
244 status = io_create(&dev_obj->hio_mgr, dev_obj,
245 &io_mgr_attrs);
246 }
247 /* Only create DEH manager if we have an IO manager */
248 if (!status) {
249 /* Instantiate the DEH module */
250 status = bridge_deh_create(&dev_obj->hdeh_mgr, dev_obj);
251 }
252 /* Create DMM mgr . */
253 status = dmm_create(&dev_obj->dmm_mgr,
254 (struct dev_object *)dev_obj, NULL);
255 }
256 /* Add the new DEV_Object to the global list: */
257 if (!status)
258 status = drv_insert_dev_object(hdrv_obj, dev_obj);
259
260 /* Create the Processor List */
261 if (!status)
262 INIT_LIST_HEAD(&dev_obj->proc_list);
263 leave:
264 /* If all went well, return a handle to the dev object;
265 * else, cleanup and return NULL in the OUT parameter. */
266 if (!status) {
267 *device_obj = dev_obj;
268 } else {
269 if (dev_obj) {
270 if (dev_obj->cod_mgr)
271 cod_delete(dev_obj->cod_mgr);
272 if (dev_obj->dmm_mgr)
273 dmm_destroy(dev_obj->dmm_mgr);
274 kfree(dev_obj);
275 }
276
277 *device_obj = NULL;
278 }
279
280 DBC_ENSURE((!status && *device_obj) || (status && !*device_obj));
281 return status;
282 }
283
284 /*
285 * ======== dev_create2 ========
286 * Purpose:
287 * After successful loading of the image from api_init_complete2
288 * (PROC Auto_Start) or proc_load this fxn is called. This creates
289 * the Node Manager and updates the DEV Object.
290 */
291 int dev_create2(struct dev_object *hdev_obj)
292 {
293 int status = 0;
294 struct dev_object *dev_obj = hdev_obj;
295
296 DBC_REQUIRE(refs > 0);
297 DBC_REQUIRE(hdev_obj);
298
299 /* There can be only one Node Manager per DEV object */
300 DBC_ASSERT(!dev_obj->hnode_mgr);
301 status = node_create_mgr(&dev_obj->hnode_mgr, hdev_obj);
302 if (status)
303 dev_obj->hnode_mgr = NULL;
304
305 DBC_ENSURE((!status && dev_obj->hnode_mgr != NULL)
306 || (status && dev_obj->hnode_mgr == NULL));
307 return status;
308 }
309
310 /*
311 * ======== dev_destroy2 ========
312 * Purpose:
313 * Destroys the Node manager for this device.
314 */
315 int dev_destroy2(struct dev_object *hdev_obj)
316 {
317 int status = 0;
318 struct dev_object *dev_obj = hdev_obj;
319
320 DBC_REQUIRE(refs > 0);
321 DBC_REQUIRE(hdev_obj);
322
323 if (dev_obj->hnode_mgr) {
324 if (node_delete_mgr(dev_obj->hnode_mgr))
325 status = -EPERM;
326 else
327 dev_obj->hnode_mgr = NULL;
328
329 }
330
331 DBC_ENSURE((!status && dev_obj->hnode_mgr == NULL) || status);
332 return status;
333 }
334
335 /*
336 * ======== dev_destroy_device ========
337 * Purpose:
338 * Destroys the channel manager for this device, if any, calls
339 * bridge_dev_destroy(), and then attempts to unload the Bridge module.
340 */
341 int dev_destroy_device(struct dev_object *hdev_obj)
342 {
343 int status = 0;
344 struct dev_object *dev_obj = hdev_obj;
345
346 DBC_REQUIRE(refs > 0);
347
348 if (hdev_obj) {
349 if (dev_obj->cod_mgr) {
350 cod_delete(dev_obj->cod_mgr);
351 dev_obj->cod_mgr = NULL;
352 }
353
354 if (dev_obj->hnode_mgr) {
355 node_delete_mgr(dev_obj->hnode_mgr);
356 dev_obj->hnode_mgr = NULL;
357 }
358
359 /* Free the io, channel, and message managers for this board: */
360 if (dev_obj->hio_mgr) {
361 io_destroy(dev_obj->hio_mgr);
362 dev_obj->hio_mgr = NULL;
363 }
364 if (dev_obj->hchnl_mgr) {
365 chnl_destroy(dev_obj->hchnl_mgr);
366 dev_obj->hchnl_mgr = NULL;
367 }
368 if (dev_obj->hmsg_mgr) {
369 msg_delete(dev_obj->hmsg_mgr);
370 dev_obj->hmsg_mgr = NULL;
371 }
372
373 if (dev_obj->hdeh_mgr) {
374 /* Uninitialize DEH module. */
375 bridge_deh_destroy(dev_obj->hdeh_mgr);
376 dev_obj->hdeh_mgr = NULL;
377 }
378 if (dev_obj->hcmm_mgr) {
379 cmm_destroy(dev_obj->hcmm_mgr, true);
380 dev_obj->hcmm_mgr = NULL;
381 }
382
383 if (dev_obj->dmm_mgr) {
384 dmm_destroy(dev_obj->dmm_mgr);
385 dev_obj->dmm_mgr = NULL;
386 }
387
388 /* Call the driver's bridge_dev_destroy() function: */
389 /* Require of DevDestroy */
390 if (dev_obj->hbridge_context) {
391 status = (*dev_obj->bridge_interface.pfn_dev_destroy)
392 (dev_obj->hbridge_context);
393 dev_obj->hbridge_context = NULL;
394 } else
395 status = -EPERM;
396 if (!status) {
397 /* Remove this DEV_Object from the global list: */
398 drv_remove_dev_object(dev_obj->hdrv_obj, dev_obj);
399 /* Free The library * LDR_FreeModule
400 * (dev_obj->module_obj); */
401 /* Free this dev object: */
402 kfree(dev_obj);
403 dev_obj = NULL;
404 }
405 } else {
406 status = -EFAULT;
407 }
408
409 return status;
410 }
411
412 /*
413 * ======== dev_get_chnl_mgr ========
414 * Purpose:
415 * Retrieve the handle to the channel manager handle created for this
416 * device.
417 */
418 int dev_get_chnl_mgr(struct dev_object *hdev_obj,
419 struct chnl_mgr **mgr)
420 {
421 int status = 0;
422 struct dev_object *dev_obj = hdev_obj;
423
424 DBC_REQUIRE(refs > 0);
425 DBC_REQUIRE(mgr != NULL);
426
427 if (hdev_obj) {
428 *mgr = dev_obj->hchnl_mgr;
429 } else {
430 *mgr = NULL;
431 status = -EFAULT;
432 }
433
434 DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL));
435 return status;
436 }
437
438 /*
439 * ======== dev_get_cmm_mgr ========
440 * Purpose:
441 * Retrieve the handle to the shared memory manager created for this
442 * device.
443 */
444 int dev_get_cmm_mgr(struct dev_object *hdev_obj,
445 struct cmm_object **mgr)
446 {
447 int status = 0;
448 struct dev_object *dev_obj = hdev_obj;
449
450 DBC_REQUIRE(refs > 0);
451 DBC_REQUIRE(mgr != NULL);
452
453 if (hdev_obj) {
454 *mgr = dev_obj->hcmm_mgr;
455 } else {
456 *mgr = NULL;
457 status = -EFAULT;
458 }
459
460 DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL));
461 return status;
462 }
463
464 /*
465 * ======== dev_get_dmm_mgr ========
466 * Purpose:
467 * Retrieve the handle to the dynamic memory manager created for this
468 * device.
469 */
470 int dev_get_dmm_mgr(struct dev_object *hdev_obj,
471 struct dmm_object **mgr)
472 {
473 int status = 0;
474 struct dev_object *dev_obj = hdev_obj;
475
476 DBC_REQUIRE(refs > 0);
477 DBC_REQUIRE(mgr != NULL);
478
479 if (hdev_obj) {
480 *mgr = dev_obj->dmm_mgr;
481 } else {
482 *mgr = NULL;
483 status = -EFAULT;
484 }
485
486 DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL));
487 return status;
488 }
489
490 /*
491 * ======== dev_get_cod_mgr ========
492 * Purpose:
493 * Retrieve the COD manager create for this device.
494 */
495 int dev_get_cod_mgr(struct dev_object *hdev_obj,
496 struct cod_manager **cod_mgr)
497 {
498 int status = 0;
499 struct dev_object *dev_obj = hdev_obj;
500
501 DBC_REQUIRE(refs > 0);
502 DBC_REQUIRE(cod_mgr != NULL);
503
504 if (hdev_obj) {
505 *cod_mgr = dev_obj->cod_mgr;
506 } else {
507 *cod_mgr = NULL;
508 status = -EFAULT;
509 }
510
511 DBC_ENSURE(!status || (cod_mgr != NULL && *cod_mgr == NULL));
512 return status;
513 }
514
515 /*
516 * ========= dev_get_deh_mgr ========
517 */
518 int dev_get_deh_mgr(struct dev_object *hdev_obj,
519 struct deh_mgr **deh_manager)
520 {
521 int status = 0;
522
523 DBC_REQUIRE(refs > 0);
524 DBC_REQUIRE(deh_manager != NULL);
525 DBC_REQUIRE(hdev_obj);
526 if (hdev_obj) {
527 *deh_manager = hdev_obj->hdeh_mgr;
528 } else {
529 *deh_manager = NULL;
530 status = -EFAULT;
531 }
532 return status;
533 }
534
535 /*
536 * ======== dev_get_dev_node ========
537 * Purpose:
538 * Retrieve the platform specific device ID for this device.
539 */
540 int dev_get_dev_node(struct dev_object *hdev_obj,
541 struct cfg_devnode **dev_nde)
542 {
543 int status = 0;
544 struct dev_object *dev_obj = hdev_obj;
545
546 DBC_REQUIRE(refs > 0);
547 DBC_REQUIRE(dev_nde != NULL);
548
549 if (hdev_obj) {
550 *dev_nde = dev_obj->dev_node_obj;
551 } else {
552 *dev_nde = NULL;
553 status = -EFAULT;
554 }
555
556 DBC_ENSURE(!status || (dev_nde != NULL && *dev_nde == NULL));
557 return status;
558 }
559
560 /*
561 * ======== dev_get_first ========
562 * Purpose:
563 * Retrieve the first Device Object handle from an internal linked list
564 * DEV_OBJECTs maintained by DEV.
565 */
566 struct dev_object *dev_get_first(void)
567 {
568 struct dev_object *dev_obj = NULL;
569
570 dev_obj = (struct dev_object *)drv_get_first_dev_object();
571
572 return dev_obj;
573 }
574
575 /*
576 * ======== dev_get_intf_fxns ========
577 * Purpose:
578 * Retrieve the Bridge interface function structure for the loaded driver.
579 * if_fxns != NULL.
580 */
581 int dev_get_intf_fxns(struct dev_object *hdev_obj,
582 struct bridge_drv_interface **if_fxns)
583 {
584 int status = 0;
585 struct dev_object *dev_obj = hdev_obj;
586
587 DBC_REQUIRE(refs > 0);
588 DBC_REQUIRE(if_fxns != NULL);
589
590 if (hdev_obj) {
591 *if_fxns = &dev_obj->bridge_interface;
592 } else {
593 *if_fxns = NULL;
594 status = -EFAULT;
595 }
596
597 DBC_ENSURE(!status || ((if_fxns != NULL) && (*if_fxns == NULL)));
598 return status;
599 }
600
601 /*
602 * ========= dev_get_io_mgr ========
603 */
604 int dev_get_io_mgr(struct dev_object *hdev_obj,
605 struct io_mgr **io_man)
606 {
607 int status = 0;
608
609 DBC_REQUIRE(refs > 0);
610 DBC_REQUIRE(io_man != NULL);
611 DBC_REQUIRE(hdev_obj);
612
613 if (hdev_obj) {
614 *io_man = hdev_obj->hio_mgr;
615 } else {
616 *io_man = NULL;
617 status = -EFAULT;
618 }
619
620 return status;
621 }
622
623 /*
624 * ======== dev_get_next ========
625 * Purpose:
626 * Retrieve the next Device Object handle from an internal linked list
627 * of DEV_OBJECTs maintained by DEV, after having previously called
628 * dev_get_first() and zero or more dev_get_next
629 */
630 struct dev_object *dev_get_next(struct dev_object *hdev_obj)
631 {
632 struct dev_object *next_dev_object = NULL;
633
634 if (hdev_obj) {
635 next_dev_object = (struct dev_object *)
636 drv_get_next_dev_object((u32) hdev_obj);
637 }
638
639 return next_dev_object;
640 }
641
642 /*
643 * ========= dev_get_msg_mgr ========
644 */
645 void dev_get_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr **msg_man)
646 {
647 DBC_REQUIRE(refs > 0);
648 DBC_REQUIRE(msg_man != NULL);
649 DBC_REQUIRE(hdev_obj);
650
651 *msg_man = hdev_obj->hmsg_mgr;
652 }
653
654 /*
655 * ======== dev_get_node_manager ========
656 * Purpose:
657 * Retrieve the Node Manager Handle
658 */
659 int dev_get_node_manager(struct dev_object *hdev_obj,
660 struct node_mgr **node_man)
661 {
662 int status = 0;
663 struct dev_object *dev_obj = hdev_obj;
664
665 DBC_REQUIRE(refs > 0);
666 DBC_REQUIRE(node_man != NULL);
667
668 if (hdev_obj) {
669 *node_man = dev_obj->hnode_mgr;
670 } else {
671 *node_man = NULL;
672 status = -EFAULT;
673 }
674
675 DBC_ENSURE(!status || (node_man != NULL && *node_man == NULL));
676 return status;
677 }
678
679 /*
680 * ======== dev_get_symbol ========
681 */
682 int dev_get_symbol(struct dev_object *hdev_obj,
683 const char *str_sym, u32 * pul_value)
684 {
685 int status = 0;
686 struct cod_manager *cod_mgr;
687
688 DBC_REQUIRE(refs > 0);
689 DBC_REQUIRE(str_sym != NULL && pul_value != NULL);
690
691 if (hdev_obj) {
692 status = dev_get_cod_mgr(hdev_obj, &cod_mgr);
693 if (cod_mgr)
694 status = cod_get_sym_value(cod_mgr, (char *)str_sym,
695 pul_value);
696 else
697 status = -EFAULT;
698 }
699
700 return status;
701 }
702
703 /*
704 * ======== dev_get_bridge_context ========
705 * Purpose:
706 * Retrieve the Bridge Context handle, as returned by the
707 * bridge_dev_create fxn.
708 */
709 int dev_get_bridge_context(struct dev_object *hdev_obj,
710 struct bridge_dev_context **phbridge_context)
711 {
712 int status = 0;
713 struct dev_object *dev_obj = hdev_obj;
714
715 DBC_REQUIRE(refs > 0);
716 DBC_REQUIRE(phbridge_context != NULL);
717
718 if (hdev_obj) {
719 *phbridge_context = dev_obj->hbridge_context;
720 } else {
721 *phbridge_context = NULL;
722 status = -EFAULT;
723 }
724
725 DBC_ENSURE(!status || ((phbridge_context != NULL) &&
726 (*phbridge_context == NULL)));
727 return status;
728 }
729
730 /*
731 * ======== dev_exit ========
732 * Purpose:
733 * Decrement reference count, and free resources when reference count is
734 * 0.
735 */
736 void dev_exit(void)
737 {
738 DBC_REQUIRE(refs > 0);
739
740 refs--;
741
742 if (refs == 0) {
743 cmm_exit();
744 dmm_exit();
745 }
746
747 DBC_ENSURE(refs >= 0);
748 }
749
750 /*
751 * ======== dev_init ========
752 * Purpose:
753 * Initialize DEV's private state, keeping a reference count on each call.
754 */
755 bool dev_init(void)
756 {
757 bool cmm_ret, dmm_ret, ret = true;
758
759 DBC_REQUIRE(refs >= 0);
760
761 if (refs == 0) {
762 cmm_ret = cmm_init();
763 dmm_ret = dmm_init();
764
765 ret = cmm_ret && dmm_ret;
766
767 if (!ret) {
768 if (cmm_ret)
769 cmm_exit();
770
771 if (dmm_ret)
772 dmm_exit();
773
774 }
775 }
776
777 if (ret)
778 refs++;
779
780 DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
781
782 return ret;
783 }
784
785 /*
786 * ======== dev_notify_clients ========
787 * Purpose:
788 * Notify all clients of this device of a change in device status.
789 */
790 int dev_notify_clients(struct dev_object *hdev_obj, u32 ret)
791 {
792 struct dev_object *dev_obj = hdev_obj;
793 struct list_head *curr;
794
795 /*
796 * FIXME: this code needs struct proc_object to have a list_head
797 * at the begining. If not, this can go horribly wrong.
798 */
799 list_for_each(curr, &dev_obj->proc_list)
800 proc_notify_clients((void *)curr, (u32) ret);
801
802 return 0;
803 }
804
805 /*
806 * ======== dev_remove_device ========
807 */
808 int dev_remove_device(struct cfg_devnode *dev_node_obj)
809 {
810 struct dev_object *hdev_obj; /* handle to device object */
811 int status = 0;
812 struct drv_data *drv_datap = dev_get_drvdata(bridge);
813
814 if (!drv_datap)
815 status = -ENODATA;
816
817 if (!dev_node_obj)
818 status = -EFAULT;
819
820 /* Retrieve the device object handle originaly stored with
821 * the dev_node: */
822 if (!status) {
823 /* check the device string and then store dev object */
824 if (!strcmp((char *)((struct drv_ext *)dev_node_obj)->sz_string,
825 "TIOMAP1510")) {
826 hdev_obj = drv_datap->dev_object;
827 /* Destroy the device object. */
828 status = dev_destroy_device(hdev_obj);
829 } else {
830 status = -EPERM;
831 }
832 }
833
834 if (status)
835 pr_err("%s: Failed, status 0x%x\n", __func__, status);
836
837 return status;
838 }
839
840 /*
841 * ======== dev_set_chnl_mgr ========
842 * Purpose:
843 * Set the channel manager for this device.
844 */
845 int dev_set_chnl_mgr(struct dev_object *hdev_obj,
846 struct chnl_mgr *hmgr)
847 {
848 int status = 0;
849 struct dev_object *dev_obj = hdev_obj;
850
851 DBC_REQUIRE(refs > 0);
852
853 if (hdev_obj)
854 dev_obj->hchnl_mgr = hmgr;
855 else
856 status = -EFAULT;
857
858 DBC_ENSURE(status || (dev_obj->hchnl_mgr == hmgr));
859 return status;
860 }
861
862 /*
863 * ======== dev_set_msg_mgr ========
864 * Purpose:
865 * Set the message manager for this device.
866 */
867 void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr)
868 {
869 DBC_REQUIRE(refs > 0);
870 DBC_REQUIRE(hdev_obj);
871
872 hdev_obj->hmsg_mgr = hmgr;
873 }
874
875 /*
876 * ======== dev_start_device ========
877 * Purpose:
878 * Initializes the new device with the BRIDGE environment.
879 */
880 int dev_start_device(struct cfg_devnode *dev_node_obj)
881 {
882 struct dev_object *hdev_obj = NULL; /* handle to 'Bridge Device */
883 /* Bridge driver filename */
884 char bridge_file_name[CFG_MAXSEARCHPATHLEN] = "UMA";
885 int status;
886 struct mgr_object *hmgr_obj = NULL;
887 struct drv_data *drv_datap = dev_get_drvdata(bridge);
888
889 DBC_REQUIRE(refs > 0);
890
891 /* Given all resources, create a device object. */
892 status = dev_create_device(&hdev_obj, bridge_file_name,
893 dev_node_obj);
894 if (!status) {
895 /* Store away the hdev_obj with the DEVNODE */
896 if (!drv_datap || !dev_node_obj) {
897 status = -EFAULT;
898 pr_err("%s: Failed, status 0x%x\n", __func__, status);
899 } else if (!(strcmp((char *)dev_node_obj, "TIOMAP1510"))) {
900 drv_datap->dev_object = (void *) hdev_obj;
901 }
902 if (!status) {
903 /* Create the Manager Object */
904 status = mgr_create(&hmgr_obj, dev_node_obj);
905 if (status && !(strcmp((char *)dev_node_obj,
906 "TIOMAP1510"))) {
907 /* Ensure the device extension is NULL */
908 drv_datap->dev_object = NULL;
909 }
910 }
911 if (status) {
912 /* Clean up */
913 dev_destroy_device(hdev_obj);
914 hdev_obj = NULL;
915 }
916 }
917
918 return status;
919 }
920
921 /*
922 * ======== fxn_not_implemented ========
923 * Purpose:
924 * Takes the place of a Bridge Null Function.
925 * Parameters:
926 * Multiple, optional.
927 * Returns:
928 * -ENOSYS: Always.
929 */
930 static int fxn_not_implemented(int arg, ...)
931 {
932 return -ENOSYS;
933 }
934
935 /*
936 * ======== init_cod_mgr ========
937 * Purpose:
938 * Create a COD manager for this device.
939 * Parameters:
940 * dev_obj: Pointer to device object created with
941 * dev_create_device()
942 * Returns:
943 * 0: Success.
944 * -EFAULT: Invalid hdev_obj.
945 * Requires:
946 * Should only be called once by dev_create_device() for a given DevObject.
947 * Ensures:
948 */
949 static int init_cod_mgr(struct dev_object *dev_obj)
950 {
951 int status = 0;
952 char *sz_dummy_file = "dummy";
953
954 DBC_REQUIRE(refs > 0);
955 DBC_REQUIRE(!dev_obj || (dev_obj->cod_mgr == NULL));
956
957 status = cod_create(&dev_obj->cod_mgr, sz_dummy_file, NULL);
958
959 return status;
960 }
961
962 /*
963 * ======== dev_insert_proc_object ========
964 * Purpose:
965 * Insert a ProcObject into the list maintained by DEV.
966 * Parameters:
967 * p_proc_object: Ptr to ProcObject to insert.
968 * dev_obj: Ptr to Dev Object where the list is.
969 * already_attached: Ptr to return the bool
970 * Returns:
971 * 0: If successful.
972 * Requires:
973 * List Exists
974 * hdev_obj is Valid handle
975 * DEV Initialized
976 * already_attached != NULL
977 * proc_obj != 0
978 * Ensures:
979 * 0 and List is not Empty.
980 */
981 int dev_insert_proc_object(struct dev_object *hdev_obj,
982 u32 proc_obj, bool *already_attached)
983 {
984 int status = 0;
985 struct dev_object *dev_obj = (struct dev_object *)hdev_obj;
986
987 DBC_REQUIRE(refs > 0);
988 DBC_REQUIRE(dev_obj);
989 DBC_REQUIRE(proc_obj != 0);
990 DBC_REQUIRE(already_attached != NULL);
991 if (!list_empty(&dev_obj->proc_list))
992 *already_attached = true;
993
994 /* Add DevObject to tail. */
995 /*
996 * FIXME: this code needs struct proc_object to have a list_head
997 * at the begining. If not, this can go horribly wrong.
998 */
999 list_add_tail((struct list_head *)proc_obj, &dev_obj->proc_list);
1000
1001 DBC_ENSURE(!status && !list_empty(&dev_obj->proc_list));
1002
1003 return status;
1004 }
1005
1006 /*
1007 * ======== dev_remove_proc_object ========
1008 * Purpose:
1009 * Search for and remove a Proc object from the given list maintained
1010 * by the DEV
1011 * Parameters:
1012 * p_proc_object: Ptr to ProcObject to insert.
1013 * dev_obj Ptr to Dev Object where the list is.
1014 * Returns:
1015 * 0: If successful.
1016 * Requires:
1017 * List exists and is not empty
1018 * proc_obj != 0
1019 * hdev_obj is a valid Dev handle.
1020 * Ensures:
1021 * Details:
1022 * List will be deleted when the DEV is destroyed.
1023 */
1024 int dev_remove_proc_object(struct dev_object *hdev_obj, u32 proc_obj)
1025 {
1026 int status = -EPERM;
1027 struct list_head *cur_elem;
1028 struct dev_object *dev_obj = (struct dev_object *)hdev_obj;
1029
1030 DBC_REQUIRE(dev_obj);
1031 DBC_REQUIRE(proc_obj != 0);
1032 DBC_REQUIRE(!list_empty(&dev_obj->proc_list));
1033
1034 /* Search list for dev_obj: */
1035 list_for_each(cur_elem, &dev_obj->proc_list) {
1036 if ((u32) cur_elem == proc_obj) {
1037 list_del(cur_elem);
1038 status = 0;
1039 break;
1040 }
1041 }
1042
1043 return status;
1044 }
1045
1046 int dev_get_dev_type(struct dev_object *device_obj, u8 *dev_type)
1047 {
1048 int status = 0;
1049 struct dev_object *dev_obj = (struct dev_object *)device_obj;
1050
1051 *dev_type = dev_obj->dev_type;
1052
1053 return status;
1054 }
1055
1056 /*
1057 * ======== store_interface_fxns ========
1058 * Purpose:
1059 * Copy the Bridge's interface functions into the device object,
1060 * ensuring that fxn_not_implemented() is set for:
1061 *
1062 * 1. All Bridge function pointers which are NULL; and
1063 * 2. All function slots in the struct dev_object structure which have no
1064 * corresponding slots in the the Bridge's interface, because the Bridge
1065 * is of an *older* version.
1066 * Parameters:
1067 * intf_fxns: Interface fxn Structure of the Bridge's Dev Object.
1068 * drv_fxns: Interface Fxns offered by the Bridge during DEV_Create().
1069 * Returns:
1070 * Requires:
1071 * Input pointers are valid.
1072 * Bridge driver is *not* written for a newer DSP API.
1073 * Ensures:
1074 * All function pointers in the dev object's fxn interface are not NULL.
1075 */
1076 static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
1077 struct bridge_drv_interface *intf_fxns)
1078 {
1079 u32 bridge_version;
1080
1081 /* Local helper macro: */
1082 #define STORE_FXN(cast, pfn) \
1083 (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \
1084 (cast)fxn_not_implemented))
1085
1086 DBC_REQUIRE(intf_fxns != NULL);
1087 DBC_REQUIRE(drv_fxns != NULL);
1088 DBC_REQUIRE(MAKEVERSION(drv_fxns->brd_api_major_version,
1089 drv_fxns->brd_api_minor_version) <= BRD_API_VERSION);
1090 bridge_version = MAKEVERSION(drv_fxns->brd_api_major_version,
1091 drv_fxns->brd_api_minor_version);
1092 intf_fxns->brd_api_major_version = drv_fxns->brd_api_major_version;
1093 intf_fxns->brd_api_minor_version = drv_fxns->brd_api_minor_version;
1094 /* Install functions up to DSP API version .80 (first alpha): */
1095 if (bridge_version > 0) {
1096 STORE_FXN(fxn_dev_create, pfn_dev_create);
1097 STORE_FXN(fxn_dev_destroy, pfn_dev_destroy);
1098 STORE_FXN(fxn_dev_ctrl, pfn_dev_cntrl);
1099 STORE_FXN(fxn_brd_monitor, pfn_brd_monitor);
1100 STORE_FXN(fxn_brd_start, pfn_brd_start);
1101 STORE_FXN(fxn_brd_stop, pfn_brd_stop);
1102 STORE_FXN(fxn_brd_status, pfn_brd_status);
1103 STORE_FXN(fxn_brd_read, pfn_brd_read);
1104 STORE_FXN(fxn_brd_write, pfn_brd_write);
1105 STORE_FXN(fxn_brd_setstate, pfn_brd_set_state);
1106 STORE_FXN(fxn_brd_memcopy, pfn_brd_mem_copy);
1107 STORE_FXN(fxn_brd_memwrite, pfn_brd_mem_write);
1108 STORE_FXN(fxn_brd_memmap, pfn_brd_mem_map);
1109 STORE_FXN(fxn_brd_memunmap, pfn_brd_mem_un_map);
1110 STORE_FXN(fxn_chnl_create, pfn_chnl_create);
1111 STORE_FXN(fxn_chnl_destroy, pfn_chnl_destroy);
1112 STORE_FXN(fxn_chnl_open, pfn_chnl_open);
1113 STORE_FXN(fxn_chnl_close, pfn_chnl_close);
1114 STORE_FXN(fxn_chnl_addioreq, pfn_chnl_add_io_req);
1115 STORE_FXN(fxn_chnl_getioc, pfn_chnl_get_ioc);
1116 STORE_FXN(fxn_chnl_cancelio, pfn_chnl_cancel_io);
1117 STORE_FXN(fxn_chnl_flushio, pfn_chnl_flush_io);
1118 STORE_FXN(fxn_chnl_getinfo, pfn_chnl_get_info);
1119 STORE_FXN(fxn_chnl_getmgrinfo, pfn_chnl_get_mgr_info);
1120 STORE_FXN(fxn_chnl_idle, pfn_chnl_idle);
1121 STORE_FXN(fxn_chnl_registernotify, pfn_chnl_register_notify);
1122 STORE_FXN(fxn_io_create, pfn_io_create);
1123 STORE_FXN(fxn_io_destroy, pfn_io_destroy);
1124 STORE_FXN(fxn_io_onloaded, pfn_io_on_loaded);
1125 STORE_FXN(fxn_io_getprocload, pfn_io_get_proc_load);
1126 STORE_FXN(fxn_msg_create, pfn_msg_create);
1127 STORE_FXN(fxn_msg_createqueue, pfn_msg_create_queue);
1128 STORE_FXN(fxn_msg_delete, pfn_msg_delete);
1129 STORE_FXN(fxn_msg_deletequeue, pfn_msg_delete_queue);
1130 STORE_FXN(fxn_msg_get, pfn_msg_get);
1131 STORE_FXN(fxn_msg_put, pfn_msg_put);
1132 STORE_FXN(fxn_msg_registernotify, pfn_msg_register_notify);
1133 STORE_FXN(fxn_msg_setqueueid, pfn_msg_set_queue_id);
1134 }
1135 /* Add code for any additional functions in newerBridge versions here */
1136 /* Ensure postcondition: */
1137 DBC_ENSURE(intf_fxns->pfn_dev_create != NULL);
1138 DBC_ENSURE(intf_fxns->pfn_dev_destroy != NULL);
1139 DBC_ENSURE(intf_fxns->pfn_dev_cntrl != NULL);
1140 DBC_ENSURE(intf_fxns->pfn_brd_monitor != NULL);
1141 DBC_ENSURE(intf_fxns->pfn_brd_start != NULL);
1142 DBC_ENSURE(intf_fxns->pfn_brd_stop != NULL);
1143 DBC_ENSURE(intf_fxns->pfn_brd_status != NULL);
1144 DBC_ENSURE(intf_fxns->pfn_brd_read != NULL);
1145 DBC_ENSURE(intf_fxns->pfn_brd_write != NULL);
1146 DBC_ENSURE(intf_fxns->pfn_chnl_create != NULL);
1147 DBC_ENSURE(intf_fxns->pfn_chnl_destroy != NULL);
1148 DBC_ENSURE(intf_fxns->pfn_chnl_open != NULL);
1149 DBC_ENSURE(intf_fxns->pfn_chnl_close != NULL);
1150 DBC_ENSURE(intf_fxns->pfn_chnl_add_io_req != NULL);
1151 DBC_ENSURE(intf_fxns->pfn_chnl_get_ioc != NULL);
1152 DBC_ENSURE(intf_fxns->pfn_chnl_cancel_io != NULL);
1153 DBC_ENSURE(intf_fxns->pfn_chnl_flush_io != NULL);
1154 DBC_ENSURE(intf_fxns->pfn_chnl_get_info != NULL);
1155 DBC_ENSURE(intf_fxns->pfn_chnl_get_mgr_info != NULL);
1156 DBC_ENSURE(intf_fxns->pfn_chnl_idle != NULL);
1157 DBC_ENSURE(intf_fxns->pfn_chnl_register_notify != NULL);
1158 DBC_ENSURE(intf_fxns->pfn_io_create != NULL);
1159 DBC_ENSURE(intf_fxns->pfn_io_destroy != NULL);
1160 DBC_ENSURE(intf_fxns->pfn_io_on_loaded != NULL);
1161 DBC_ENSURE(intf_fxns->pfn_io_get_proc_load != NULL);
1162 DBC_ENSURE(intf_fxns->pfn_msg_set_queue_id != NULL);
1163
1164 #undef STORE_FXN
1165 }
This page took 0.06448 seconds and 5 git commands to generate.