1/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above copyright
9 *       notice, this list of conditions and the following disclaimer in the
10 *       documentation and/or other materials provided with the distribution.
11 *     * Neither the name of Freescale Semiconductor nor the
12 *       names of its contributors may be used to endorse or promote products
13 *       derived from this software without specific prior written permission.
14 *
15 *
16 * ALTERNATIVELY, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") as published by the Free Software
18 * Foundation, either version 2 of that License or (at your option) any
19 * later version.
20 *
21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33
34/**************************************************************************//**
35 @File          error_ext.h
36
37 @Description   Error definitions.
38*//***************************************************************************/
39
40#ifndef __ERROR_EXT_H
41#define __ERROR_EXT_H
42
43#if defined(NCSW_FREEBSD)
44#include <sys/param.h>
45#include <sys/errno.h>
46#include <sys/pcpu.h>
47#endif
48
49#include "std_ext.h"
50#include "xx_ext.h"
51#include "core_ext.h"
52
53
54
55
56/**************************************************************************//**
57 @Group         gen_id  General Drivers Utilities
58
59 @Description   External routines.
60
61 @{
62*//***************************************************************************/
63
64/**************************************************************************//**
65 @Group         gen_error_id  Errors, Events and Debug
66
67 @Description   External routines.
68
69 @{
70*//***************************************************************************/
71
72/******************************************************************************
73The scheme below provides the bits description for error codes:
74
75 0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15
76|       Reserved (should be zero)      |              Module ID               |
77
78 16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31
79|                               Error Type                                    |
80******************************************************************************/
81
82#define ERROR_CODE(_err)            ((((uint32_t)_err) & 0x0000FFFF) | __ERR_MODULE__)
83
84#define GET_ERROR_TYPE(_errcode)    ((_errcode) & 0x0000FFFF)
85                                /**< Extract module code from error code (#t_Error) */
86
87#define GET_ERROR_MODULE(_errcode)  ((_errcode) & 0x00FF0000)
88                                /**< Extract error type (#e_ErrorType) from
89                                     error code (#t_Error) */
90
91
92/**************************************************************************//**
93 @Description    Error Type Enumeration
94*//***************************************************************************/
95typedef enum e_ErrorType    /*   Comments / Associated Message Strings                      */
96{                           /* ------------------------------------------------------------ */
97    E_OK = 0                /*   Never use "RETURN_ERROR" with E_OK; Use "return E_OK;"     */
98    ,E_WRITE_FAILED = EIO   /**< Write access failed on memory/device.                      */
99                            /*   String: none, or device name.                              */
100    ,E_NO_DEVICE = ENXIO    /**< The associated device is not initialized.                  */
101                            /*   String: none.                                              */
102    ,E_NOT_AVAILABLE = EAGAIN
103                            /**< Resource is unavailable.                                   */
104                            /*   String: none, unless the operation is not the main goal
105                                 of the function (in this case add resource description).   */
106    ,E_NO_MEMORY = ENOMEM   /**< External memory allocation failed.                         */
107                            /*   String: description of item for which allocation failed.   */
108    ,E_INVALID_ADDRESS = EFAULT
109                            /**< Invalid address.                                           */
110                            /*   String: description of the specific violation.             */
111    ,E_BUSY = EBUSY         /**< Resource or module is busy.                                */
112                            /*   String: none, unless the operation is not the main goal
113                                 of the function (in this case add resource description).   */
114    ,E_ALREADY_EXISTS = EEXIST
115                            /**< Requested resource or item already exists.                 */
116                            /*   Use when resource duplication or sharing are not allowed.
117                                 String: none, unless the operation is not the main goal
118                                 of the function (in this case add item description).       */
119    ,E_INVALID_OPERATION = ENODEV
120                            /**< The operation/command is invalid (unrecognized).           */
121                            /*   String: none.                                              */
122    ,E_INVALID_VALUE = EDOM /**< Invalid value.                                             */
123                            /*   Use for non-enumeration parameters, and
124                                 only when other error types are not suitable.
125                                 String: parameter description + "(should be <attribute>)",
126                                 e.g: "Maximum Rx buffer length (should be divisible by 8)",
127                                      "Channel number (should be even)".                    */
128    ,E_NOT_IN_RANGE = ERANGE/**< Parameter value is out of range.                           */
129                            /*   Don't use this error for enumeration parameters.
130                                 String: parameter description + "(should be %d-%d)",
131                                 e.g: "Number of pad characters (should be 0-15)".          */
132    ,E_NOT_SUPPORTED = ENOSYS
133                            /**< The function is not supported or not implemented.          */
134                            /*   String: none.                                              */
135    ,E_INVALID_STATE        /**< The operation is not allowed in current module state.      */
136                            /*   String: none.                                              */
137    ,E_INVALID_HANDLE       /**< Invalid handle of module or object.                        */
138                            /*   String: none, unless the function takes in more than one
139                                 handle (in this case add the handle description)           */
140    ,E_INVALID_ID           /**< Invalid module ID (usually enumeration or index).          */
141                            /*   String: none, unless the function takes in more than one
142                                 ID (in this case add the ID description)                   */
143    ,E_NULL_POINTER         /**< Unexpected NULL pointer.                                   */
144                            /*   String: pointer description.                               */
145    ,E_INVALID_SELECTION    /**< Invalid selection or mode.                                 */
146                            /*   Use for enumeration values, only when other error types
147                                 are not suitable.
148                                 String: parameter description.                             */
149    ,E_INVALID_COMM_MODE    /**< Invalid communication mode.                                */
150                            /*   String: none, unless the function takes in more than one
151                                 communication mode indications (in this case add
152                                 parameter description).                                    */
153    ,E_INVALID_MEMORY_TYPE  /**< Invalid memory type.                                       */
154                            /*   String: none, unless the function takes in more than one
155                                 memory types (in this case add memory description,
156                                 e.g: "Data memory", "Buffer descriptors memory").          */
157    ,E_INVALID_CLOCK        /**< Invalid clock.                                             */
158                            /*   String: none, unless the function takes in more than one
159                                 clocks (in this case add clock description,
160                                 e.g: "Rx clock", "Tx clock").                              */
161    ,E_CONFLICT             /**< Some setting conflicts with another setting.               */
162                            /*   String: description of the conflicting settings.           */
163    ,E_NOT_ALIGNED          /**< Non-aligned address.                                       */
164                            /*   String: parameter description + "(should be %d-bytes aligned)",
165                                 e.g: "Rx data buffer (should be 32-bytes aligned)".        */
166    ,E_NOT_FOUND            /**< Requested resource or item was not found.                  */
167                            /*   Use only when the resource/item is uniquely identified.
168                                 String: none, unless the operation is not the main goal
169                                 of the function (in this case add item description).       */
170    ,E_FULL                 /**< Resource is full.                                          */
171                            /*   String: none, unless the operation is not the main goal
172                                 of the function (in this case add resource description).   */
173    ,E_EMPTY                /**< Resource is empty.                                         */
174                            /*   String: none, unless the operation is not the main goal
175                                 of the function (in this case add resource description).   */
176    ,E_ALREADY_FREE         /**< Specified resource or item is already free or deleted.     */
177                            /*   String: none, unless the operation is not the main goal
178                                 of the function (in this case add item description).       */
179    ,E_READ_FAILED          /**< Read access failed on memory/device.                       */
180                            /*   String: none, or device name.                              */
181    ,E_INVALID_FRAME        /**< Invalid frame object (NULL handle or missing buffers).     */
182                            /*   String: none.                                              */
183    ,E_SEND_FAILED          /**< Send operation failed on device.                           */
184                            /*   String: none, or device name.                              */
185    ,E_RECEIVE_FAILED       /**< Receive operation failed on device.                        */
186                            /*   String: none, or device name.                              */
187    ,E_TIMEOUT/* = ETIMEDOUT*/  /**< The operation timed out.                                   */
188                            /*   String: none.                                              */
189
190    ,E_DUMMY_LAST           /* NEVER USED */
191
192} e_ErrorType;
193
194/**************************************************************************//**
195 @Description    Event Type Enumeration
196*//***************************************************************************/
197typedef enum e_Event        /*   Comments / Associated Flags and Message Strings            */
198{                           /* ------------------------------------------------------------ */
199    EV_NO_EVENT = 0         /**< No event; Never used.                                      */
200
201    ,EV_RX_DISCARD          /**< Received packet discarded (by the driver, and only for
202                                 complete packets);
203                                 Flags: error flags in case of error, zero otherwise.       */
204                            /*   String: reason for discard, e.g: "Error in frame",
205                                 "Disordered frame", "Incomplete frame", "No frame object". */
206    ,EV_RX_ERROR            /**< Receive error (by hardware/firmware);
207                                 Flags: usually status flags from the buffer descriptor.    */
208                            /*   String: none.                                              */
209    ,EV_TX_ERROR            /**< Transmit error (by hardware/firmware);
210                                 Flags: usually status flags from the buffer descriptor.    */
211                            /*   String: none.                                              */
212    ,EV_NO_BUFFERS          /**< System ran out of buffer objects;
213                                 Flags: zero.                                               */
214                            /*   String: none.                                              */
215    ,EV_NO_MB_FRAMES        /**< System ran out of multi-buffer frame objects;
216                                 Flags: zero.                                               */
217                            /*   String: none.                                              */
218    ,EV_NO_SB_FRAMES        /**< System ran out of single-buffer frame objects;
219                                 Flags: zero.                                               */
220                            /*   String: none.                                              */
221    ,EV_TX_QUEUE_FULL       /**< Transmit queue is full;
222                                 Flags: zero.                                               */
223                            /*   String: none.                                              */
224    ,EV_RX_QUEUE_FULL       /**< Receive queue is full;
225                                 Flags: zero.                                               */
226                            /*   String: none.                                              */
227    ,EV_INTR_QUEUE_FULL     /**< Interrupt queue overflow;
228                                 Flags: zero.                                               */
229                            /*   String: none.                                              */
230    ,EV_NO_DATA_BUFFER      /**< Data buffer allocation (from higher layer) failed;
231                                 Flags: zero.                                               */
232                            /*   String: none.                                              */
233    ,EV_OBJ_POOL_EMPTY      /**< Objects pool is empty;
234                                 Flags: zero.                                               */
235                            /*   String: object description (name).                         */
236    ,EV_BUS_ERROR           /**< Illegal access on bus;
237                                 Flags: the address (if available) or bus identifier        */
238                            /*   String: bus/address/module description.                    */
239    ,EV_PTP_TXTS_QUEUE_FULL /**< PTP Tx timestamps queue is full;
240                                 Flags: zero.                                               */
241                            /*   String: none.                                              */
242    ,EV_PTP_RXTS_QUEUE_FULL /**< PTP Rx timestamps queue is full;
243                                 Flags: zero.                                               */
244                            /*   String: none.                                              */
245    ,EV_DUMMY_LAST
246
247} e_Event;
248
249
250/**************************************************************************//**
251 @Collection    Debug Levels for Errors and Events
252
253                The level description refers to errors only.
254                For events, classification is done by the user.
255
256                The TRACE, INFO and WARNING levels are allowed only when using
257                the DBG macro, and are not allowed when using the error macros
258                (RETURN_ERROR or REPORT_ERROR).
259 @{
260*//***************************************************************************/
261#define REPORT_LEVEL_CRITICAL   1       /**< Crasher: Incorrect flow, NULL pointers/handles. */
262#define REPORT_LEVEL_MAJOR      2       /**< Cannot proceed: Invalid operation, parameters or
263                                             configuration. */
264#define REPORT_LEVEL_MINOR      3       /**< Recoverable problem: a repeating call with the same
265                                             parameters may be successful. */
266#define REPORT_LEVEL_WARNING    4       /**< Something is not exactly right, yet it is not an error. */
267#define REPORT_LEVEL_INFO       5       /**< Messages which may be of interest to user/programmer. */
268#define REPORT_LEVEL_TRACE      6       /**< Program flow messages. */
269
270#define EVENT_DISABLED          0xFF    /**< Disabled event (not reported at all) */
271
272/* @} */
273
274
275
276#define NO_MSG      ("")
277
278#ifndef DEBUG_GLOBAL_LEVEL
279#define DEBUG_GLOBAL_LEVEL  REPORT_LEVEL_WARNING
280#endif /* DEBUG_GLOBAL_LEVEL */
281
282#ifndef ERROR_GLOBAL_LEVEL
283#define ERROR_GLOBAL_LEVEL  DEBUG_GLOBAL_LEVEL
284#endif /* ERROR_GLOBAL_LEVEL */
285
286#ifndef EVENT_GLOBAL_LEVEL
287#define EVENT_GLOBAL_LEVEL  REPORT_LEVEL_MINOR
288#endif /* EVENT_GLOBAL_LEVEL */
289
290#ifdef EVENT_LOCAL_LEVEL
291#define EVENT_DYNAMIC_LEVEL EVENT_LOCAL_LEVEL
292#else
293#define EVENT_DYNAMIC_LEVEL EVENT_GLOBAL_LEVEL
294#endif /* EVENT_LOCAL_LEVEL */
295
296
297#ifndef DEBUG_DYNAMIC_LEVEL
298#define DEBUG_USING_STATIC_LEVEL
299
300#ifdef DEBUG_STATIC_LEVEL
301#define DEBUG_DYNAMIC_LEVEL DEBUG_STATIC_LEVEL
302#else
303#define DEBUG_DYNAMIC_LEVEL DEBUG_GLOBAL_LEVEL
304#endif /* DEBUG_STATIC_LEVEL */
305
306#else /* DEBUG_DYNAMIC_LEVEL */
307#ifdef DEBUG_STATIC_LEVEL
308#error "Please use either DEBUG_STATIC_LEVEL or DEBUG_DYNAMIC_LEVEL (not both)"
309#else
310int DEBUG_DYNAMIC_LEVEL = DEBUG_GLOBAL_LEVEL;
311#endif /* DEBUG_STATIC_LEVEL */
312#endif /* !DEBUG_DYNAMIC_LEVEL */
313
314
315#ifndef ERROR_DYNAMIC_LEVEL
316
317#ifdef ERROR_STATIC_LEVEL
318#define ERROR_DYNAMIC_LEVEL ERROR_STATIC_LEVEL
319#else
320#define ERROR_DYNAMIC_LEVEL ERROR_GLOBAL_LEVEL
321#endif /* ERROR_STATIC_LEVEL */
322
323#else /* ERROR_DYNAMIC_LEVEL */
324#ifdef ERROR_STATIC_LEVEL
325#error "Please use either ERROR_STATIC_LEVEL or ERROR_DYNAMIC_LEVEL (not both)"
326#else
327int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL;
328#endif /* ERROR_STATIC_LEVEL */
329#endif /* !ERROR_DYNAMIC_LEVEL */
330
331#define PRINT_FORMAT        "[CPU%02d, %s:%d %s]"
332#define PRINT_FMT_PARAMS    PCPU_GET(cpuid), __FILE__, __LINE__, __FUNCTION__
333
334#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
335/* No debug/error/event messages at all */
336#define DBG(_level, _vmsg)
337
338#define REPORT_ERROR(_level, _err, _vmsg)
339
340#define RETURN_ERROR(_level, _err, _vmsg) \
341        return ERROR_CODE(_err)
342
343#if (REPORT_EVENTS > 0)
344
345#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
346    do { \
347        if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
348            XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
349        } \
350    } while (0)
351
352#else
353
354#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
355
356#endif /* (REPORT_EVENTS > 0) */
357
358
359#else /* DEBUG_ERRORS > 0 */
360
361extern const char *dbgLevelStrings[];
362#if (REPORT_EVENTS > 0)
363extern const char *eventStrings[];
364#endif /* (REPORT_EVENTS > 0) */
365
366char * ErrTypeStrings (e_ErrorType err);
367
368
369#if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING))
370/* No need for DBG macro - debug level is higher anyway */
371#define DBG(_level, _vmsg)
372#else
373#define DBG(_level, _vmsg) \
374    do { \
375        if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \
376            XX_Print("> %s (%s) " PRINT_FORMAT ": ", \
377                     dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
378                     __STRING(__ERR_MODULE__), \
379                     PRINT_FMT_PARAMS); \
380            XX_Print _vmsg; \
381            XX_Print("\r\n"); \
382        } \
383    } while (0)
384#endif /* (defined(DEBUG_USING_STATIC_LEVEL) && (DEBUG_DYNAMIC_LEVEL < WARNING)) */
385
386
387#define REPORT_ERROR(_level, _err, _vmsg) \
388    do { \
389        if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \
390            XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \
391                     dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
392                     __STRING(__ERR_MODULE__), \
393                     PRINT_FMT_PARAMS, \
394                     ErrTypeStrings((e_ErrorType)GET_ERROR_TYPE(_err))); \
395            XX_Print _vmsg; \
396            XX_Print("\r\n"); \
397        } \
398    } while (0)
399
400
401#define RETURN_ERROR(_level, _err, _vmsg) \
402    do { \
403        REPORT_ERROR(_level, (_err), _vmsg); \
404        return ERROR_CODE(_err); \
405    } while (0)
406
407
408#if (REPORT_EVENTS > 0)
409
410#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
411    do { \
412        if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
413            XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \
414                     dbgLevelStrings[_ev##_LEVEL - 1], \
415                     __STRING(__ERR_MODULE__), \
416                     PRINT_FMT_PARAMS, \
417                     eventStrings[((_ev) - EV_NO_EVENT - 1)], \
418                     (uint16_t)(_flg)); \
419            XX_Print _vmsg; \
420            XX_Print("\r\n"); \
421            XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
422        } \
423    } while (0)
424
425#else /* not REPORT_EVENTS */
426
427#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
428
429#endif /* (REPORT_EVENTS > 0) */
430
431#endif /* (DEBUG_ERRORS > 0) */
432
433
434/**************************************************************************//**
435 @Function      ASSERT_COND
436
437 @Description   Assertion macro.
438
439 @Param[in]     _cond - The condition being checked, in positive form;
440                        Failure of the condition triggers the assert.
441*//***************************************************************************/
442#ifdef DISABLE_ASSERTIONS
443#define ASSERT_COND(_cond)
444#else
445#define ASSERT_COND(_cond) \
446    do { \
447        if (!(_cond)) { \
448            XX_Print("*** ASSERT_COND failed " PRINT_FORMAT "\r\n", \
449                    PRINT_FMT_PARAMS); \
450            XX_Exit(1); \
451        } \
452    } while (0)
453#endif /* DISABLE_ASSERTIONS */
454
455
456#ifdef DISABLE_INIT_PARAMETERS_CHECK
457
458#define CHECK_INIT_PARAMETERS(handle, f_check)
459#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval)
460
461#else
462
463#define CHECK_INIT_PARAMETERS(handle, f_check) \
464    do { \
465        t_Error err = f_check(handle); \
466        if (err != E_OK) { \
467            RETURN_ERROR(MAJOR, err, NO_MSG); \
468        } \
469    } while (0)
470
471#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) \
472    do { \
473        t_Error err = f_check(handle); \
474        if (err != E_OK) { \
475            REPORT_ERROR(MAJOR, err, NO_MSG); \
476            return (retval); \
477        } \
478    } while (0)
479
480#endif /* DISABLE_INIT_PARAMETERS_CHECK */
481
482#ifdef DISABLE_SANITY_CHECKS
483
484#define SANITY_CHECK_RETURN_ERROR(_cond, _err)
485#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval)
486#define SANITY_CHECK_RETURN(_cond, _err)
487#define SANITY_CHECK_EXIT(_cond, _err)
488
489#else /* DISABLE_SANITY_CHECKS */
490
491#define SANITY_CHECK_RETURN_ERROR(_cond, _err) \
492    do { \
493        if (!(_cond)) { \
494            RETURN_ERROR(CRITICAL, (_err), NO_MSG); \
495        } \
496    } while (0)
497
498#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) \
499    do { \
500        if (!(_cond)) { \
501            REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
502            return (retval); \
503        } \
504    } while (0)
505
506#define SANITY_CHECK_RETURN(_cond, _err) \
507    do { \
508        if (!(_cond)) { \
509            REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
510            return; \
511        } \
512    } while (0)
513
514#define SANITY_CHECK_EXIT(_cond, _err) \
515    do { \
516        if (!(_cond)) { \
517            REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
518            XX_Exit(1); \
519        } \
520    } while (0)
521
522#endif /* DISABLE_SANITY_CHECKS */
523
524/** @} */ /* end of Debug/error Utils group */
525
526/** @} */ /* end of General Utils group */
527
528#endif /* __ERROR_EXT_H */
529
530
531