source: svn/trunk/newcon3bcm2_21bu/BSEAV/api/build/proxy/bapi_driver_ioctl.pm

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 10.7 KB
Line 
1#!/usr/bin/perl
2#############################################################################
3#
4#               Copyright (c) 2004-2008, Broadcom Corporation.
5#               All rights reserved.
6#               Confidential Property of Broadcom Corporation.
7#
8#  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
9#  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
10#  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
11#
12# $brcm_Workfile: bapi_driver_ioctl.pm $
13# $brcm_Revision: 7 $
14# $brcm_Date: 1/23/08 3:09p $
15#
16# File Description:
17#
18# Revision History:
19#
20# $brcm_Log: /BSEAV/api/build/proxy/bapi_driver_ioctl.pm $
21#
22# 7   1/23/08 3:09p mphillip
23# PR38923: Mosaic decode handles also require managing
24#
25# 6   11/21/07 3:43p gmohile
26# PR 36570 : fix array sizes
27#
28# 5   1/10/07 10:34a erickson
29# PR26351: bdecode_acquire_capture_buffer needs to have its bsurface_t
30# destroyed
31#
32# 4   3/10/06 4:26p vle
33# PR 20136: add pcmplay to the list of handles
34#
35# 3   11/2/05 11:24a vsilyaev
36# PR 17883: Don't shutdown SettopApi stack if signal is pending
37#
38# 2   9/12/05 12:35p mphillip
39# PR16870: Fix kernel-mode macrovision support
40#
41# 1   2/7/05 6:55p dlwin
42# Merge down for release 2005_REFSW_MERGETOMAIN:
43#
44# Irvine_BSEAVSW_Devel/15   12/2/04 4:45p vsilyaev
45# PR 13351: Added code to pass through NULL pointers as arguments.
46#
47# Irvine_BSEAVSW_Devel/14   8/31/04 1:36p erickson
48# PR11869: buser_input must also be a managed handle
49#
50# Irvine_BSEAVSW_Devel/13   8/12/04 9:28a erickson
51# PR11135: reworked bhandle_mgr autogen code to be data driven and close
52# down in correct order
53#
54# Irvine_BSEAVSW_Devel/12   7/23/04 2:41p erickson
55# PR11771: updated proxy layer for settop api changes
56#
57# Irvine_BSEAVSW_Devel/11   7/9/04 1:38p erickson
58# PR11771: rebuilt proxy layer for settop api dataflow redesign, and
59# handle all callbacks with new perl module
60#
61# Irvine_BSEAVSW_Devel/10   6/29/04 11:27a erickson
62# PR11135: handle overflow callback
63#
64# Irvine_BSEAVSW_Devel/9   6/24/04 2:37p erickson
65# PR11135: adapted proxy layer to bsettop_callback
66#
67# Irvine_BSEAVSW_Devel/8   6/24/04 10:24a erickson
68# PR11135: added "don't modify" headers
69#
70# Irvine_BSEAVSW_Devel/7   6/21/04 4:38p erickson
71# PR11135: use double curly braces to prevent stack overflow in the
72# switch statement
73#
74# Irvine_BSEAVSW_Devel/6   6/18/04 12:33p erickson
75# PR11135: destroy callbacks when closing
76#
77# Irvine_BSEAVSW_Devel/5   6/17/04 9:37a erickson
78# PR11135: recpump callback enabled
79#
80# Irvine_BSEAVSW_Devel/4   6/16/04 5:15p erickson
81# PR11135: added callback support
82#
83# Irvine_BSEAVSW_Devel/3   6/1/04 11:28a erickson
84# PR11135: added support for strings (const char *)
85#
86# Irvine_BSEAVSW_Devel/2   5/25/04 11:46a erickson
87# PR11135: playback must be managed
88#
89# Irvine_BSEAVSW_Devel/1   5/17/04 11:13a erickson
90# PR11135: added initial linux proxy impl
91#
92#############################################################################
93use strict;
94use bapi_callbacks;
95
96package bapi_driver_ioctl;
97
98# For managed handles, the open function must return a handle.
99# The close function must take only the handle as a parameter.
100# The order of this list determines the order in which handles will be autoclosed
101# by bhandle_mgr. It will close from the top down.
102my @managed_handles = (
103["btuner_tune_rf", "bstream_close", "stream"],
104["btuner_tune_linein", "bstream_close", "stream"],
105["bstream_open", "bstream_close", "stream"],
106["bstream_open_child", "bstream_close", "stream"],
107["btuner_open", "btuner_close", "tuner"],
108["bplaypump_open", "bplaypump_close", "playpump"],
109["brecpump_open", "brecpump_close", "recpump"],
110["bdecode_window_open", "bdecode_window_close", "window"],
111["bdecode_window_open_mosaic", "bdecode_window_close", "window"],
112["bdecode_window_clone", "bdecode_window_close", "window"],
113["bdecode_open", "bdecode_close", "decode"],
114["bdecode_open_mosaic", "bdecode_close", "decode"],
115["buser_input_open", "buser_input_close", "ui"],
116["bsurface_create", "bsurface_destroy", "surface"],
117["bdecode_acquire_capture_buffer", "bsurface_destroy", "surface"],
118["bgraphics_open", "bgraphics_close", "graphics"],
119["bdisplay_open", "bdisplay_close", "display"],
120["bpcm_play_open", "bpcm_play_close", "pcmplay"]
121);
122
123sub build_addhandle {
124        my $func = shift;
125        my $mh;
126        my $text = "";
127
128        for $mh (@managed_handles) {
129                if ($mh->[0] eq $func->{FUNCNAME}) {
130                        my $close_func = $mh->[1];
131                        $text .= "  bhandle_mgr_add(file->private_data, st.__retval, (settopapi_close_func)$close_func, \"$close_func\");\n";
132                        last;
133                }
134        }
135        return $text;
136}
137
138sub build_removehandle {
139        my $func = shift;
140        my $mh;
141        my $text = "";
142
143        for $mh (@managed_handles) {
144                if ($mh->[1] eq $func->{FUNCNAME}) {
145                        my $close_func = $mh->[1];
146                        my $handle = $mh->[2];
147                        $text .= "  bhandle_mgr_remove(file->private_data, st.$handle, \"$close_func\");\n";
148                        last;
149                }
150        }
151        return $text;
152}
153
154sub build_closelist
155{
156        my ($filename, @funcs) = @_;
157        my $mh;
158       
159        open FILE, ">$filename" || die "Cannot open $filename";
160
161        print FILE "/*********************************\n";
162        print FILE "*\n";
163        print FILE "* This file is autogenerated. Do not modify.\n";
164        print FILE "*\n";
165        print FILE "*********************************/\n";
166
167        print FILE "#include \"bhandle_mgr.h\"\n";
168        print FILE "#include \"bsettop.h\"\n";
169        print FILE "static settopapi_close_func g_closefuncs[] = {\n";
170        for $mh (@managed_handles) {
171                my $close_func = $mh->[1];
172                print FILE "  (settopapi_close_func) $close_func,\n";
173        }
174        print FILE "  0\n";
175        print FILE "};\n";
176        close FILE;
177}
178
179sub parse
180{
181        my ($filename, @funcs) = @_;
182        my $func;
183        open FILE, ">$filename" || die "Cannot open $filename";
184
185        print FILE "/*********************************\n";
186        print FILE "*\n";
187        print FILE "* This file is autogenerated. Do not modify.\n";
188        print FILE "*\n";
189        print FILE "*********************************/\n";
190
191        #
192        # This function only generates the case statements. The switch statement
193        # and the rest of the function context can be found in BSEAV/linux/driver/97038/bcmdriver.c.
194        #
195        for $func (@funcs) {
196                my $params = $func->{PARAMS};
197                my $param;
198
199                print FILE "case BSETTOP_IOCTL_$func->{FUNCNAME}:\n";
200                # Using double curly braces causes the stack to be allocated for
201                # each case statement instead of for the whole switch statement.
202                # This prevents stack overflow in the kernel. If this compiler trick stops
203                # working in the future, use a union or put each case statement in a function.
204                print FILE "  {{\n";
205
206                if (!$func->{NOSTRUCT}) {
207                        print FILE "  ioctl_settopapi_struct_$func->{FUNCNAME} st;\n";
208                        for $param (@$params) {
209                                if ($param->{ISREF}) {
210                                        if ($param->{ARRAYLENGTH}) {
211                                                if ($param->{ARRAYLENGTH} ne "__maxstringlength") {
212                                                        print FILE "  $param->{TYPE} $param->{NAME};\n";
213                                                }
214                                        }
215                                        else {
216                                                print FILE "  $param->{BASETYPE} $param->{NAME};\n";
217                                        }
218                                }
219                        }
220                        if ($func->{FUNCNAME} eq "bdisplay_set") {
221                                print FILE "  bmacrovision_tables mv_tables;\n";
222                        }
223                        print FILE "\n";
224
225                        print FILE "  rc = copy_from_user(&st, (void*)arg, sizeof(st));\n";
226                        print FILE "  if (rc) break;\n";
227                }
228
229                # This bracket is necessary in order to dynamically allocate arrays
230                # using values in st.
231                print FILE "  {\n";
232
233                for $param (@$params) {
234                        my $arraylength = $param->{ARRAYLENGTH};
235                        if ($arraylength && !($arraylength eq "__maxstringlength")) {
236                                $arraylength = "st." . $arraylength;
237                        }
238
239                        if ($param->{ISREF}) {
240                                if ($param->{ARRAYLENGTH}) {
241                                        if ($param->{ARRAYLENGTH} ne "__maxstringlength") {
242                                                print FILE "  $param->{BASETYPE} $param->{NAME}_array[$arraylength];\n";
243                                                print FILE "  $param->{NAME} = $param->{NAME}_array;\n";
244                                        }
245                                        else {
246                                                print FILE "  $param->{BASETYPE} $param->{NAME}\[$arraylength\];\n";
247                                        }
248                                }
249                                if ($param->{INPARAM}) {
250                                        if ($param->{ARRAYLENGTH}) {
251                                                print FILE "  rc = copy_from_user((void*)$param->{NAME}, st.$param->{NAME}, $arraylength*sizeof($param->{BASETYPE}));\n";
252                                                print FILE "  if (rc) break;\n";
253                                        }
254                                        else {
255                                                print FILE "  if (st.$param->{NAME}) {\n";
256                                                print FILE "  rc = copy_from_user((void*)&$param->{NAME}, st.$param->{NAME}, sizeof($param->{NAME}));\n";
257                                                print FILE "  if (rc) break;\n";
258                                                print FILE "  }\n";
259                                        }
260                                }
261                        }
262                }
263
264                if ($func->{FUNCNAME} eq "bdisplay_set") {
265                        print FILE "  if (st.settings && settings.macrovision_tables) {\n";
266                        print FILE "    rc = copy_from_user(&mv_tables, (void*)settings.macrovision_tables, sizeof(mv_tables));\n";
267                        print FILE "    if (rc) break;\n";
268                        print FILE "    settings.macrovision_tables = &mv_tables;\n";
269                        print FILE "  }\n";
270                }
271
272                # switch user-mode callback for a kernel-mode callback
273                my $callback_text = bapi_callbacks::build_kernel_callback($func);
274                if ($callback_text) {
275                        printf FILE $callback_text;
276                }
277
278                print FILE "\n  /* Make the function call */\n";
279                if ($func->{RETTYPE} =~ /\*$/) {
280                        print FILE "  $func->{RETTYPE} __retval = $func->{FUNCNAME}(";
281                }
282                elsif ($func->{RETTYPE} eq "void") {
283                        print FILE "  $func->{FUNCNAME}(";
284                }
285                else {
286                        print FILE "  st.__retval = $func->{FUNCNAME}(";
287                }
288                my $i;
289                for $param (@$params) {
290                        if ($param->{ISREF}) {
291                                if ($param->{ARRAYLENGTH}) {
292                                        print FILE "$param->{NAME}";
293                                }
294                                else {
295                                        print FILE "st.$param->{NAME} ? &$param->{NAME}:NULL";
296                                }
297                        }
298                        else {
299                                print FILE "st.$param->{NAME}";
300                        }
301                        if ($i++ != $#$params) {
302                                print FILE ",";
303                        }
304                }
305                print FILE ");\n";
306                if ($func->{RETTYPE} =~ /\*$/) {
307                        print FILE "  if (__retval) {\n";
308                        print FILE "    st.__retval = *__retval;\n";
309                        print FILE "  }\n";
310                        print FILE "  else {\n";
311                        print FILE "    rc = -EIO; break;\n";
312                        print FILE "  }\n";
313                }
314
315                #
316                # interface with the bhandle_mgr
317                #
318                my $addition = build_addhandle($func);
319                if ($addition) {
320                        print FILE $addition;
321                }
322                my $addition = build_removehandle($func);
323                if ($addition) {
324                        print FILE $addition;
325                }
326
327                if ($func->{RETTYPE} eq "void") {
328                        print FILE "  rc = 0;\n\n";
329                }
330                else {
331                        # Don't fail the ioctl if the settop api call failed. The
332                        # app will need to detect the error.
333                        print FILE "  rc = copy_to_user((void*)arg, &st, sizeof(st));\n";
334                        print FILE "  if (rc) {rc = -EFAULT; break;}\n";
335                }
336
337                for $param (@$params) {
338                        my $arraylength = $param->{ARRAYLENGTH};
339                        if ($arraylength && !($arraylength eq "__maxstringlength")) {
340                                $arraylength = "st." . $arraylength;
341                        }
342
343                        if ($param->{ISREF} && !$param->{INPARAM}) {
344                                print FILE "  if (st.$param->{NAME}) {\n";
345                                if ($param->{ARRAYLENGTH}) {
346                                        print FILE "    rc = copy_to_user(st.$param->{NAME}, $param->{NAME}, $arraylength*sizeof($param->{BASETYPE}));\n";
347                                }
348                                else {
349                                        print FILE "    rc = copy_to_user(st.$param->{NAME}, &$param->{NAME}, sizeof($param->{NAME}));\n";
350                                }
351                                print FILE "    if (rc) {rc = -EFAULT; break;}\n";
352                                print FILE "  }\n";
353                        }
354                }
355
356                print FILE "  }\n";
357                print FILE "  }}\n";
358                print FILE "  break;\n\n";
359        }
360        close FILE;
361}
362
3631;
364
Note: See TracBrowser for help on using the repository browser.