1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  IOCB dispatcher		    	File: cfe_vendor_xreq.c
5    *
6    *  This routine is the main API dispatch for CFE.  User API
7    *  calls, via the ROM entry point, get dispatched to routines
8    *  in this module.
9    *
10    *  This version of cfe_xreq is used for vendor extensions to
11    *  CFE.
12    *
13    *  This module looks similar to cfe_iocb_dispatch - it is different
14    *  in that the data structure used, cfe_xiocb_t, uses fixed
15    *  size field members (specifically, all 64-bits) no matter how
16    *  the firmware is compiled.  This ensures a consistent API
17    *  interface on any implementation.  When you call CFE
18    *  from another program, the entry vector comes here first.
19    *
20    *  Should the normal cfe_iocb interface change, this one should
21    *  be kept the same for backward compatibility reasons.
22    *
23    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
24    *
25    *********************************************************************
26    *
27    *  Copyright 2000,2001,2002,2003
28    *  Broadcom Corporation. All rights reserved.
29    *
30    *  This software is furnished under license and may be used and
31    *  copied only in accordance with the following terms and
32    *  conditions.  Subject to these conditions, you may download,
33    *  copy, install, use, modify and distribute modified or unmodified
34    *  copies of this software in source and/or binary form.  No title
35    *  or ownership is transferred hereby.
36    *
37    *  1) Any source code used, modified or distributed must reproduce
38    *     and retain this copyright notice and list of conditions
39    *     as they appear in the source file.
40    *
41    *  2) No right is granted to use any trade name, trademark, or
42    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
43    *     name may not be used to endorse or promote products derived
44    *     from this software without the prior written permission of
45    *     Broadcom Corporation.
46    *
47    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
48    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
49    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
50    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
51    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
52    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
53    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
54    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
55    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
56    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
57    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
58    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
59    *     THE POSSIBILITY OF SUCH DAMAGE.
60    ********************************************************************* */
61
62
63#include "lib_types.h"
64#include "lib_malloc.h"
65#include "lib_queue.h"
66#include "lib_printf.h"
67#include "lib_string.h"
68#include "cfe_iocb.h"
69#include "cfe_vendor_iocb.h"
70#include "cfe_xiocb.h"
71#include "cfe_vendor_xiocb.h"
72#include "cfe_error.h"
73#include "cfe_device.h"
74#include "cfe_timer.h"
75#include "cfe_mem.h"
76#include "env_subr.h"
77#include "cfe.h"
78
79
80/*  *********************************************************************
81    *  Constants
82    ********************************************************************* */
83
84/* enum values for various plist types */
85
86#define PLBUF	1		/* iocb_buffer_t */
87
88/*  *********************************************************************
89    *  Structures
90    ********************************************************************* */
91
92struct cfe_vendor_xcmd_dispatch_s {
93    int xplistsize;
94    int iplistsize;
95    int plisttype;
96};
97
98
99/*  *********************************************************************
100    *  Command conversion table
101    *  This table contains useful information for converting
102    *  iocbs to xiocbs.
103    ********************************************************************* */
104
105const static struct cfe_vendor_xcmd_dispatch_s
106   cfe_vendor_xcmd_dispatch_table[CFE_CMD_VENDOR_MAX-CFE_CMD_VENDOR_USE] = {
107    {sizeof(xiocb_buffer_t), sizeof(iocb_buffer_t), PLBUF},	/* 0 : CFE_CMD_VENDOR_SAMPLE */
108};
109
110
111/*  *********************************************************************
112    *  Externs
113    ********************************************************************* */
114
115extern int cfe_vendor_iocb_dispatch(cfe_vendor_iocb_t *iocb);
116extern cfe_int_t cfe_vendor_doxreq(cfe_vendor_xiocb_t *xiocb);
117
118/*  *********************************************************************
119    *  cfe_vendor_doxreq(xiocb)
120    *
121    *  Process an xiocb request.  This routine converts an xiocb
122    *  into an iocb, calls the IOCB dispatcher, converts the results
123    *  back into the xiocb, and returns.
124    *
125    *  Input parameters:
126    *  	   xiocb - pointer to user xiocb
127    *
128    *  Return value:
129    *  	   command status, <0 if error occured
130    ********************************************************************* */
131
132cfe_int_t cfe_vendor_doxreq(cfe_vendor_xiocb_t *xiocb)
133{
134    const struct cfe_vendor_xcmd_dispatch_s *disp;
135    cfe_vendor_iocb_t iiocb;
136    cfe_int_t res;
137
138    /*
139     * Check for commands codes out of range
140     */
141
142    if ((xiocb->xiocb_fcode < CFE_CMD_VENDOR_USE) ||
143	(xiocb->xiocb_fcode >= CFE_CMD_VENDOR_MAX)) {
144	xiocb->xiocb_status = CFE_ERR_INV_COMMAND;
145	return xiocb->xiocb_status;
146	}
147
148    /*
149     * Check for command codes in range but invalid
150     */
151
152    disp = &cfe_vendor_xcmd_dispatch_table[xiocb->xiocb_fcode - CFE_CMD_VENDOR_USE];
153
154    if (disp->xplistsize < 0) {
155	xiocb->xiocb_status = CFE_ERR_INV_COMMAND;
156	return xiocb->xiocb_status;
157	}
158
159    /*
160     * Check for invalid parameter list size
161     */
162
163    if (disp->xplistsize != xiocb->xiocb_psize) {
164	xiocb->xiocb_status = CFE_ERR_INV_PARAM;
165	return xiocb->xiocb_status;
166	}
167
168    /*
169     * Okay, copy parameters into the internal IOCB.
170     * First, the fixed header.
171     */
172
173    iiocb.iocb_fcode = (unsigned int) xiocb->xiocb_fcode;
174    iiocb.iocb_status = (int) xiocb->xiocb_status;
175    iiocb.iocb_handle = (int) xiocb->xiocb_handle;
176    iiocb.iocb_flags = (unsigned int) xiocb->xiocb_flags;
177    iiocb.iocb_psize = (unsigned int) disp->iplistsize;
178
179    /*
180     * Now the parameter list
181     */
182
183    switch (disp->plisttype) {
184	case PLBUF:
185	    iiocb.plist.iocb_buffer.buf_offset = (cfe_offset_t) xiocb->plist.xiocb_buffer.buf_offset;
186	    iiocb.plist.iocb_buffer.buf_ptr = (unsigned char *) (uintptr_t) xiocb->plist.xiocb_buffer.buf_ptr;
187	    iiocb.plist.iocb_buffer.buf_length = (unsigned int) xiocb->plist.xiocb_buffer.buf_length;
188	    iiocb.plist.iocb_buffer.buf_retlen = (unsigned int) xiocb->plist.xiocb_buffer.buf_retlen;
189	    iiocb.plist.iocb_buffer.buf_ioctlcmd = (unsigned int) xiocb->plist.xiocb_buffer.buf_ioctlcmd;
190	    break;
191	}
192
193    /*
194     * Do the internal function dispatch
195     */
196
197    res = (cfe_int_t) cfe_vendor_iocb_dispatch(&iiocb);
198
199    /*
200     * Now convert the parameter list members back
201     */
202
203    switch (disp->plisttype) {
204	case PLBUF:
205	    xiocb->plist.xiocb_buffer.buf_offset = (cfe_uint_t) iiocb.plist.iocb_buffer.buf_offset;
206	    xiocb->plist.xiocb_buffer.buf_ptr = (cfe_xptr_t) (uintptr_t) iiocb.plist.iocb_buffer.buf_ptr;
207	    xiocb->plist.xiocb_buffer.buf_length = (cfe_uint_t) iiocb.plist.iocb_buffer.buf_length;
208	    xiocb->plist.xiocb_buffer.buf_retlen = (cfe_uint_t) iiocb.plist.iocb_buffer.buf_retlen;
209	    xiocb->plist.xiocb_buffer.buf_ioctlcmd = (cfe_uint_t) iiocb.plist.iocb_buffer.buf_ioctlcmd;
210	    break;
211	}
212
213    /*
214     * And the fixed header
215     */
216
217    xiocb->xiocb_status = (cfe_int_t) iiocb.iocb_status;
218    xiocb->xiocb_handle = (cfe_int_t) iiocb.iocb_handle;
219    xiocb->xiocb_flags = (cfe_uint_t) iiocb.iocb_flags;
220
221    return xiocb->xiocb_status;
222}
223