4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
31 #include <sys/usb/clients/usbser/usbser_rseq.h>
34 #include <sys/debug.h>
36 #include <sys/sunddi.h>
37 /*LINTED E_STATIC_UNUSED*/
38 static long rseq_random() __unused
;
39 #define random rseq_random
49 rseq_do_common(rseq_t
*rseq
, int num
, uintptr_t arg
, int flags
, int fail_err
,
56 for (i
= 0; i
< num
; i
++) {
59 if (s
->s_func
== NULL
) {
62 s
->s_rval
= (i
!= fail_num
) ? s
->s_func(arg
) : fail_err
;
63 rval
= (s
->s_cb
) ? (s
->s_cb(rseq
, i
, arg
)) : RSEQ_OK
;
65 if (rval
== RSEQ_UNDO
) {
66 (void) rseq_undo(rseq
, i
, arg
, flags
);
68 } else if (rval
== RSEQ_ABORT
) {
71 ASSERT(rval
== RSEQ_OK
);
79 rseq_undo_common(rseq_t
*rseq
, int num
, uintptr_t arg
, int flags
, int fail_err
,
86 for (i
= num
- 1; i
>= 0; i
--) {
89 if (s
->s_func
== NULL
) {
92 s
->s_rval
= (i
!= fail_num
) ? s
->s_func(arg
) : fail_err
;
93 rval
= (s
->s_cb
) ? (s
->s_cb(rseq
, i
, arg
)) : RSEQ_OK
;
95 if (rval
== RSEQ_ABORT
) {
98 ASSERT(rval
== RSEQ_OK
);
105 rseq_do(rseq_t
*rseq
, int num
, uintptr_t arg
, int flags
)
107 return (rseq_do_common(rseq
, num
, arg
, flags
, 0, -1));
112 rseq_undo(rseq_t
*rseq
, int num
, uintptr_t arg
, int flags
)
114 return (rseq_undo_common(rseq
, num
, arg
, flags
, 0, -1));
122 rseq_debug(rseq_t
*rseq
, int num
, uintptr_t arg
, int flags
, int scenario
,
123 uintptr_t sarg1
, uintptr_t sarg2
,
124 int (*func
)(rseq_t
*, int, uintptr_t, int, int, uintptr_t))
126 int rnd
, rval
= RSEQ_OK
, i
;
129 case RSEQ_DBG_FAIL_ONE
:
130 rval
= func(rseq
, num
, arg
, flags
, sarg1
, sarg2
);
132 case RSEQ_DBG_FAIL_ONE_RANDOM
:
133 rnd
= random() % num
;
134 rval
= func(rseq
, num
, arg
, flags
, sarg1
, rnd
);
136 case RSEQ_DBG_FAIL_ONEBYONE
:
137 for (i
= 0; i
< num
; i
++) {
138 rval
= func(rseq
, num
, arg
, flags
, sarg1
, i
);
140 * when aborted, the undo path is not executed, so we
141 * can't continue without the risk of resource leakage.
143 if (rval
== RSEQ_ABORT
) {
149 ASSERT(!"rseq_debug: incorrect debug scenario");
157 rseq_do_debug(rseq_t
*rseq
, int num
, uintptr_t arg
, int flags
, int scenario
,
158 uintptr_t sarg1
, uintptr_t sarg2
)
160 return (rseq_debug(rseq
, num
, arg
, flags
, scenario
, sarg1
, sarg2
,
166 rseq_undo_debug(rseq_t
*rseq
, int num
, uintptr_t arg
, int flags
, int scenario
,
167 uintptr_t sarg1
, uintptr_t sarg2
)
169 return (rseq_debug(rseq
, num
, arg
, flags
, scenario
, sarg1
, sarg2
,
173 #endif /* __lock_lint */
181 return (ddi_get_lbolt());