1 /* from: Broadcom Id: cfe_api.c,v 1.18 2006/08/24 02:13:56 binh Exp $ */ 2 3 /*- 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 * Copyright 2000, 2001, 2002 7 * Broadcom Corporation. All rights reserved. 8 * 9 * This software is furnished under license and may be used and copied only 10 * in accordance with the following terms and conditions. Subject to these 11 * conditions, you may download, copy, install, use, modify and distribute 12 * modified or unmodified copies of this software in source and/or binary 13 * form. No title or ownership is transferred hereby. 14 * 15 * 1) Any source code used, modified or distributed must reproduce and 16 * retain this copyright notice and list of conditions as they appear in 17 * the source file. 18 * 19 * 2) No right is granted to use any trade name, trademark, or logo of 20 * Broadcom Corporation. The "Broadcom Corporation" name may not be 21 * used to endorse or promote products derived from this software 22 * without the prior written permission of Broadcom Corporation. 23 * 24 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED 25 * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 27 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE 28 * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE 29 * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 32 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 34 * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37 /* ********************************************************************* 38 * 39 * Broadcom Common Firmware Environment (CFE) 40 * 41 * Device Function stubs File: cfe_api.c 42 * 43 * This module contains device function stubs (small routines to 44 * call the standard "iocb" interface entry point to CFE). 45 * There should be one routine here per iocb function call. 46 * 47 * Authors: Mitch Lichtenberg, Chris Demetriou 48 * 49 ********************************************************************* */ 50 51 #include <sys/cdefs.h> 52 __FBSDID("$FreeBSD$"); 53 54 #include <dev/cfe/cfe_api.h> 55 #include <dev/cfe/cfe_api_int.h> 56 57 /* Cast from a native pointer to a cfe_xptr_t and back. */ 58 #define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n)) 59 #define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x)) 60 61 #ifdef CFE_API_IMPL_NAMESPACE 62 #define cfe_iocb_dispatch(a) __cfe_iocb_dispatch(a) 63 #endif 64 int cfe_iocb_dispatch(cfe_xiocb_t *xiocb); 65 66 #if defined(CFE_API_common) || defined(CFE_API_ALL) 67 /* 68 * Declare the dispatch function with args of "intptr_t". 69 * This makes sure whatever model we're compiling in 70 * puts the pointers in a single register. For example, 71 * combining -mlong64 and -mips1 or -mips2 would lead to 72 * trouble, since the handle and IOCB pointer will be 73 * passed in two registers each, and CFE expects one. 74 */ 75 76 static int (*cfe_dispfunc)(intptr_t handle, intptr_t xiocb) = 0; 77 static cfe_xuint_t cfe_handle = 0; 78 79 int 80 cfe_init(cfe_xuint_t handle, cfe_xuint_t ept) 81 { 82 cfe_dispfunc = NATIVE_FROM_XPTR(ept); 83 cfe_handle = handle; 84 return 0; 85 } 86 87 int 88 cfe_iocb_dispatch(cfe_xiocb_t *xiocb) 89 { 90 if (!cfe_dispfunc) return -1; 91 return (*cfe_dispfunc)((intptr_t)cfe_handle, (intptr_t)xiocb); 92 } 93 #endif /* CFE_API_common || CFE_API_ALL */ 94 95 #if defined(CFE_API_close) || defined(CFE_API_ALL) 96 int 97 cfe_close(int handle) 98 { 99 cfe_xiocb_t xiocb; 100 101 xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE; 102 xiocb.xiocb_status = 0; 103 xiocb.xiocb_handle = handle; 104 xiocb.xiocb_flags = 0; 105 xiocb.xiocb_psize = 0; 106 107 cfe_iocb_dispatch(&xiocb); 108 109 return xiocb.xiocb_status; 110 111 } 112 #endif /* CFE_API_close || CFE_API_ALL */ 113 114 #if defined(CFE_API_cpu_start) || defined(CFE_API_ALL) 115 int 116 cfe_cpu_start(int cpu, void (*fn)(void), long sp, long gp, long a1) 117 { 118 cfe_xiocb_t xiocb; 119 120 xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; 121 xiocb.xiocb_status = 0; 122 xiocb.xiocb_handle = 0; 123 xiocb.xiocb_flags = 0; 124 xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); 125 xiocb.plist.xiocb_cpuctl.cpu_number = cpu; 126 xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START; 127 xiocb.plist.xiocb_cpuctl.gp_val = gp; 128 xiocb.plist.xiocb_cpuctl.sp_val = sp; 129 xiocb.plist.xiocb_cpuctl.a1_val = a1; 130 xiocb.plist.xiocb_cpuctl.start_addr = (long)fn; 131 132 cfe_iocb_dispatch(&xiocb); 133 134 return xiocb.xiocb_status; 135 } 136 #endif /* CFE_API_cpu_start || CFE_API_ALL */ 137 138 #if defined(CFE_API_cpu_stop) || defined(CFE_API_ALL) 139 int 140 cfe_cpu_stop(int cpu) 141 { 142 cfe_xiocb_t xiocb; 143 144 xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; 145 xiocb.xiocb_status = 0; 146 xiocb.xiocb_handle = 0; 147 xiocb.xiocb_flags = 0; 148 xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); 149 xiocb.plist.xiocb_cpuctl.cpu_number = cpu; 150 xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP; 151 152 cfe_iocb_dispatch(&xiocb); 153 154 return xiocb.xiocb_status; 155 } 156 #endif /* CFE_API_cpu_stop || CFE_API_ALL */ 157 158 #if defined(CFE_API_enumenv) || defined(CFE_API_ALL) 159 int 160 cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen) 161 { 162 cfe_xiocb_t xiocb; 163 164 xiocb.xiocb_fcode = CFE_CMD_ENV_ENUM; 165 xiocb.xiocb_status = 0; 166 xiocb.xiocb_handle = 0; 167 xiocb.xiocb_flags = 0; 168 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 169 xiocb.plist.xiocb_envbuf.enum_idx = idx; 170 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 171 xiocb.plist.xiocb_envbuf.name_length = namelen; 172 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); 173 xiocb.plist.xiocb_envbuf.val_length = vallen; 174 175 cfe_iocb_dispatch(&xiocb); 176 177 return xiocb.xiocb_status; 178 } 179 #endif /* CFE_API_enumenv || CFE_API_ALL */ 180 181 #if defined(CFE_API_enumdev) || defined(CFE_API_ALL) 182 int 183 cfe_enumdev(int idx, char *name, int namelen) 184 { 185 cfe_xiocb_t xiocb; 186 187 xiocb.xiocb_fcode = CFE_CMD_DEV_ENUM; 188 xiocb.xiocb_status = 0; 189 xiocb.xiocb_handle = 0; 190 xiocb.xiocb_flags = 0; 191 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 192 xiocb.plist.xiocb_envbuf.enum_idx = idx; 193 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 194 xiocb.plist.xiocb_envbuf.name_length = namelen; 195 196 cfe_iocb_dispatch(&xiocb); 197 198 return xiocb.xiocb_status; 199 } 200 #endif /* CFE_API_enumdev || CFE_API_ALL */ 201 202 #if defined(CFE_API_enummem) || defined(CFE_API_ALL) 203 int 204 cfe_enummem(int idx, int flags, cfe_xuint_t *start, cfe_xuint_t *length, 205 cfe_xuint_t *type) 206 { 207 cfe_xiocb_t xiocb; 208 209 xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM; 210 xiocb.xiocb_status = 0; 211 xiocb.xiocb_handle = 0; 212 xiocb.xiocb_flags = flags; 213 xiocb.xiocb_psize = sizeof(xiocb_meminfo_t); 214 xiocb.plist.xiocb_meminfo.mi_idx = idx; 215 216 cfe_iocb_dispatch(&xiocb); 217 218 if (xiocb.xiocb_status < 0) 219 return xiocb.xiocb_status; 220 221 *start = xiocb.plist.xiocb_meminfo.mi_addr; 222 *length = xiocb.plist.xiocb_meminfo.mi_size; 223 *type = xiocb.plist.xiocb_meminfo.mi_type; 224 225 return 0; 226 } 227 #endif /* CFE_API_enummem || CFE_API_ALL */ 228 229 #if defined(CFE_API_exit) || defined(CFE_API_ALL) 230 int 231 cfe_exit(int warm, int status) 232 { 233 cfe_xiocb_t xiocb; 234 235 xiocb.xiocb_fcode = CFE_CMD_FW_RESTART; 236 xiocb.xiocb_status = 0; 237 xiocb.xiocb_handle = 0; 238 xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0; 239 xiocb.xiocb_psize = sizeof(xiocb_exitstat_t); 240 xiocb.plist.xiocb_exitstat.status = status; 241 242 cfe_iocb_dispatch(&xiocb); 243 244 return xiocb.xiocb_status; 245 } 246 #endif /* CFE_API_exit || CFE_API_ALL */ 247 248 #if defined(CFE_API_flushcache) || defined(CFE_API_ALL) 249 int 250 cfe_flushcache(int flg) 251 { 252 cfe_xiocb_t xiocb; 253 254 xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE; 255 xiocb.xiocb_status = 0; 256 xiocb.xiocb_handle = 0; 257 xiocb.xiocb_flags = flg; 258 xiocb.xiocb_psize = 0; 259 260 cfe_iocb_dispatch(&xiocb); 261 262 return xiocb.xiocb_status; 263 } 264 #endif /* CFE_API_flushcache || CFE_API_ALL */ 265 266 #if defined(CFE_API_getdevinfo) || defined(CFE_API_ALL) 267 int 268 cfe_getdevinfo(char *name) 269 { 270 cfe_xiocb_t xiocb; 271 272 xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO; 273 xiocb.xiocb_status = 0; 274 xiocb.xiocb_handle = 0; 275 xiocb.xiocb_flags = 0; 276 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 277 xiocb.plist.xiocb_buffer.buf_offset = 0; 278 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); 279 xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); 280 281 cfe_iocb_dispatch(&xiocb); 282 283 if (xiocb.xiocb_status < 0) 284 return xiocb.xiocb_status; 285 return xiocb.plist.xiocb_buffer.buf_devflags; 286 } 287 #endif /* CFE_API_getdevinfo || CFE_API_ALL */ 288 289 #if defined(CFE_API_getenv) || defined(CFE_API_ALL) 290 int 291 cfe_getenv(char *name, char *dest, int destlen) 292 { 293 cfe_xiocb_t xiocb; 294 295 *dest = 0; 296 297 xiocb.xiocb_fcode = CFE_CMD_ENV_GET; 298 xiocb.xiocb_status = 0; 299 xiocb.xiocb_handle = 0; 300 xiocb.xiocb_flags = 0; 301 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 302 xiocb.plist.xiocb_envbuf.enum_idx = 0; 303 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 304 xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); 305 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest); 306 xiocb.plist.xiocb_envbuf.val_length = destlen; 307 308 cfe_iocb_dispatch(&xiocb); 309 310 return xiocb.xiocb_status; 311 } 312 #endif /* CFE_API_getenv || CFE_API_ALL */ 313 314 #if defined(CFE_API_getfwinfo) || defined(CFE_API_ALL) 315 int 316 cfe_getfwinfo(cfe_fwinfo_t *info) 317 { 318 cfe_xiocb_t xiocb; 319 320 xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO; 321 xiocb.xiocb_status = 0; 322 xiocb.xiocb_handle = 0; 323 xiocb.xiocb_flags = 0; 324 xiocb.xiocb_psize = sizeof(xiocb_fwinfo_t); 325 326 cfe_iocb_dispatch(&xiocb); 327 328 if (xiocb.xiocb_status < 0) 329 return xiocb.xiocb_status; 330 331 info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version; 332 info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem; 333 info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags; 334 info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid; 335 info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va; 336 info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa; 337 info->fwi_bootarea_size = xiocb.plist.xiocb_fwinfo.fwi_bootarea_size; 338 #if 0 339 info->fwi_reserved1 = xiocb.plist.xiocb_fwinfo.fwi_reserved1; 340 info->fwi_reserved2 = xiocb.plist.xiocb_fwinfo.fwi_reserved2; 341 info->fwi_reserved3 = xiocb.plist.xiocb_fwinfo.fwi_reserved3; 342 #endif 343 344 return 0; 345 } 346 #endif /* CFE_API_getfwinfo || CFE_API_ALL */ 347 348 #if defined(CFE_API_getstdhandle) || defined(CFE_API_ALL) 349 int 350 cfe_getstdhandle(int flg) 351 { 352 cfe_xiocb_t xiocb; 353 354 xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE; 355 xiocb.xiocb_status = 0; 356 xiocb.xiocb_handle = 0; 357 xiocb.xiocb_flags = flg; 358 xiocb.xiocb_psize = 0; 359 360 cfe_iocb_dispatch(&xiocb); 361 362 if (xiocb.xiocb_status < 0) 363 return xiocb.xiocb_status; 364 return xiocb.xiocb_handle; 365 366 } 367 #endif /* CFE_API_getstdhandle || CFE_API_ALL */ 368 369 #if defined(CFE_API_getticks) || defined(CFE_API_ALL) 370 int64_t 371 #ifdef CFE_API_IMPL_NAMESPACE 372 __cfe_getticks(void) 373 #else 374 cfe_getticks(void) 375 #endif 376 { 377 cfe_xiocb_t xiocb; 378 379 xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME; 380 xiocb.xiocb_status = 0; 381 xiocb.xiocb_handle = 0; 382 xiocb.xiocb_flags = 0; 383 xiocb.xiocb_psize = sizeof(xiocb_time_t); 384 xiocb.plist.xiocb_time.ticks = 0; 385 386 cfe_iocb_dispatch(&xiocb); 387 388 return xiocb.plist.xiocb_time.ticks; 389 390 } 391 #endif /* CFE_API_getticks || CFE_API_ALL */ 392 393 #if defined(CFE_API_inpstat) || defined(CFE_API_ALL) 394 int 395 cfe_inpstat(int handle) 396 { 397 cfe_xiocb_t xiocb; 398 399 xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT; 400 xiocb.xiocb_status = 0; 401 xiocb.xiocb_handle = handle; 402 xiocb.xiocb_flags = 0; 403 xiocb.xiocb_psize = sizeof(xiocb_inpstat_t); 404 xiocb.plist.xiocb_inpstat.inp_status = 0; 405 406 cfe_iocb_dispatch(&xiocb); 407 408 if (xiocb.xiocb_status < 0) 409 return xiocb.xiocb_status; 410 return xiocb.plist.xiocb_inpstat.inp_status; 411 412 } 413 #endif /* CFE_API_inpstat || CFE_API_ALL */ 414 415 #if defined(CFE_API_ioctl) || defined(CFE_API_ALL) 416 int 417 cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, int length, 418 int *retlen, cfe_xuint_t offset) 419 { 420 cfe_xiocb_t xiocb; 421 422 xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL; 423 xiocb.xiocb_status = 0; 424 xiocb.xiocb_handle = handle; 425 xiocb.xiocb_flags = 0; 426 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 427 xiocb.plist.xiocb_buffer.buf_offset = offset; 428 xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum; 429 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 430 xiocb.plist.xiocb_buffer.buf_length = length; 431 432 cfe_iocb_dispatch(&xiocb); 433 434 if (retlen) 435 *retlen = xiocb.plist.xiocb_buffer.buf_retlen; 436 return xiocb.xiocb_status; 437 } 438 #endif /* CFE_API_ioctl || CFE_API_ALL */ 439 440 #if defined(CFE_API_open) || defined(CFE_API_ALL) 441 int 442 cfe_open(char *name) 443 { 444 cfe_xiocb_t xiocb; 445 446 xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN; 447 xiocb.xiocb_status = 0; 448 xiocb.xiocb_handle = 0; 449 xiocb.xiocb_flags = 0; 450 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 451 xiocb.plist.xiocb_buffer.buf_offset = 0; 452 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); 453 xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); 454 455 cfe_iocb_dispatch(&xiocb); 456 457 if (xiocb.xiocb_status < 0) 458 return xiocb.xiocb_status; 459 return xiocb.xiocb_handle; 460 } 461 #endif /* CFE_API_open || CFE_API_ALL */ 462 463 #if defined(CFE_API_read) || defined(CFE_API_ALL) 464 int 465 cfe_read(int handle, unsigned char *buffer, int length) 466 { 467 return cfe_readblk(handle, 0, buffer, length); 468 } 469 #endif /* CFE_API_read || CFE_API_ALL */ 470 471 #if defined(CFE_API_readblk) || defined(CFE_API_ALL) 472 int 473 cfe_readblk(int handle, cfe_xint_t offset, unsigned char *buffer, int length) 474 { 475 cfe_xiocb_t xiocb; 476 477 xiocb.xiocb_fcode = CFE_CMD_DEV_READ; 478 xiocb.xiocb_status = 0; 479 xiocb.xiocb_handle = handle; 480 xiocb.xiocb_flags = 0; 481 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 482 xiocb.plist.xiocb_buffer.buf_offset = offset; 483 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 484 xiocb.plist.xiocb_buffer.buf_length = length; 485 486 cfe_iocb_dispatch(&xiocb); 487 488 if (xiocb.xiocb_status < 0) 489 return xiocb.xiocb_status; 490 return xiocb.plist.xiocb_buffer.buf_retlen; 491 } 492 #endif /* CFE_API_readblk || CFE_API_ALL */ 493 494 #if defined(CFE_API_setenv) || defined(CFE_API_ALL) 495 int 496 cfe_setenv(char *name, char *val) 497 { 498 cfe_xiocb_t xiocb; 499 500 xiocb.xiocb_fcode = CFE_CMD_ENV_SET; 501 xiocb.xiocb_status = 0; 502 xiocb.xiocb_handle = 0; 503 xiocb.xiocb_flags = 0; 504 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 505 xiocb.plist.xiocb_envbuf.enum_idx = 0; 506 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 507 xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); 508 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); 509 xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val); 510 511 cfe_iocb_dispatch(&xiocb); 512 513 return xiocb.xiocb_status; 514 } 515 #endif /* CFE_API_setenv || CFE_API_ALL */ 516 517 #if (defined(CFE_API_strlen) || defined(CFE_API_ALL)) \ 518 && !defined(CFE_API_STRLEN_CUSTOM) 519 int 520 cfe_strlen(char *name) 521 { 522 int count = 0; 523 524 while (*name++) 525 count++; 526 527 return count; 528 } 529 #endif /* CFE_API_strlen || CFE_API_ALL */ 530 531 #if defined(CFE_API_write) || defined(CFE_API_ALL) 532 int 533 cfe_write(int handle, unsigned char *buffer, int length) 534 { 535 return cfe_writeblk(handle, 0, buffer, length); 536 } 537 #endif /* CFE_API_write || CFE_API_ALL */ 538 539 #if defined(CFE_API_writeblk) || defined(CFE_API_ALL) 540 int 541 cfe_writeblk(int handle, cfe_xint_t offset, unsigned char *buffer, int length) 542 { 543 cfe_xiocb_t xiocb; 544 545 xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE; 546 xiocb.xiocb_status = 0; 547 xiocb.xiocb_handle = handle; 548 xiocb.xiocb_flags = 0; 549 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 550 xiocb.plist.xiocb_buffer.buf_offset = offset; 551 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 552 xiocb.plist.xiocb_buffer.buf_length = length; 553 554 cfe_iocb_dispatch(&xiocb); 555 556 if (xiocb.xiocb_status < 0) 557 return xiocb.xiocb_status; 558 return xiocb.plist.xiocb_buffer.buf_retlen; 559 } 560 #endif /* CFE_API_writeblk || CFE_API_ALL */ 561