6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 #include <sys/types.h>
29 #include <sys/param.h>
30 #include <sys/modctl.h>
31 #include <sys/sysmacros.h>
32 #include <sys/kmem.h>
33 #include <sys/cmn_err.h>
34 #include <sys/ddi.h>
35 #include <sys/sunddi.h>
36 #include <sys/spl.h>
37 #include <sys/time.h>
38 #include <sys/varargs.h>
39 #include <ipp/ipp.h>
40 #include <ipp/ipp_impl.h>
41 #include <ipp/ipgpc/ipgpc.h>
42
43 /*
44 * Debug switch.
45 */
46
47 #if defined(DEBUG)
1361 */
1362 LOCK_ACTION(ap, RW_READER);
1363 if (ap->ippa_state != IPP_ASTATE_AVAILABLE) {
1364 UNLOCK_ACTION(ap);
1365 rele_action(ap);
1366 return (EPROTO);
1367 }
1368
1369 /*
1370 * Increment the action's packet count to note that
1371 * it's being used.
1372 *
1373 * NOTE: We only have a read lock, so we need to use
1374 * atomic_add_32(). The read lock is still
1375 * important though as it is crucial to block
1376 * out a destroy operation between the action
1377 * state being checked and the packet count
1378 * being incremented.
1379 */
1380
1381 atomic_add_32(&(ap->ippa_packets), 1);
1382
1383 imp = ap->ippa_mod;
1384 ASSERT(imp != NULL);
1385 UNLOCK_ACTION(ap);
1386
1387 ippo = imp->ippm_ops;
1388 ASSERT(ippo != NULL);
1389
1390 /*
1391 * If there's a log, grab the next entry and fill it
1392 * in.
1393 */
1394
1395 if (pp->ippp_log != NULL &&
1396 pp->ippp_log_windex <= pp->ippp_log_limit) {
1397 lp = &(pp->ippp_log[pp->ippp_log_windex++]);
1398 lp->ippl_aid = aid;
1399 (void) strcpy(lp->ippl_name, cp->ippc_name);
1400 gethrestime(&lp->ippl_begin);
1401 } else {
1403 }
1404
1405 /*
1406 * Invoke the action.
1407 */
1408
1409 rc = ippo->ippo_action_invoke(aid, pp);
1410
1411 /*
1412 * Also log the time that the action finished
1413 * processing.
1414 */
1415
1416 if (lp != NULL)
1417 gethrestime(&lp->ippl_end);
1418
1419 /*
1420 * Decrement the packet count.
1421 */
1422
1423 atomic_add_32(&(ap->ippa_packets), -1);
1424
1425 /*
1426 * If the class' action id is the same now as it was
1427 * before then clearly no 'next action' has been set.
1428 * This is a protocol error.
1429 */
1430
1431 if (cp->ippc_aid == aid) {
1432 DBG1(DBG_PACKET,
1433 "action '%s' did not set next action\n",
1434 ap->ippa_name);
1435 rele_action(ap);
1436 return (EPROTO);
1437 }
1438
1439 /*
1440 * The action did not complete successfully. Terminate
1441 * packet processing.
1442 */
1443
2362
2363 /*
2364 * If the modul has 'destruct pending' set then it means it is either
2365 * still in the cache (i.e not allocated) or in the process of
2366 * being set up by alloc_mod().
2367 */
2368
2369 LOCK_MOD(imp, RW_READER);
2370 if (imp->ippm_destruct_pending) {
2371 UNLOCK_MOD(imp);
2372 rw_exit(ipp_mod_byid_lock);
2373 return (NULL);
2374 }
2375 UNLOCK_MOD(imp);
2376
2377 /*
2378 * Increment the hold count to prevent the structure from being
2379 * freed.
2380 */
2381
2382 atomic_add_32(&(imp->ippm_hold_count), 1);
2383 rw_exit(ipp_mod_byid_lock);
2384
2385 return (imp);
2386 }
2387 #undef __FN__
2388
2389 #define __FN__ "rele_mod"
2390 static void
2391 rele_mod(
2392 ipp_mod_t *imp)
2393 {
2394 /*
2395 * This call means we're done with the pointer so we can drop the
2396 * hold count.
2397 */
2398
2399 ASSERT(imp->ippm_hold_count != 0);
2400 atomic_add_32(&(imp->ippm_hold_count), -1);
2401
2402 /*
2403 * If the structure has 'destruct pending' set then we tried to free
2404 * it but couldn't, so do it now.
2405 */
2406
2407 LOCK_MOD(imp, RW_READER);
2408 if (imp->ippm_destruct_pending && imp->ippm_hold_count == 0) {
2409 UNLOCK_MOD(imp);
2410 kmem_cache_free(ipp_mod_cache, imp);
2411 return;
2412 }
2413
2414 UNLOCK_MOD(imp);
2415 }
2416 #undef __FN__
2417
2418 #define __FN__ "get_mid"
2419 static ipp_mod_id_t
2420 get_mid(
3054
3055 /*
3056 * If the action has 'destruct pending' set then it means it is either
3057 * still in the cache (i.e not allocated) or in the process of
3058 * being set up by alloc_action().
3059 */
3060
3061 LOCK_ACTION(ap, RW_READER);
3062 if (ap->ippa_destruct_pending) {
3063 UNLOCK_ACTION(ap);
3064 rw_exit(ipp_action_byid_lock);
3065 return (NULL);
3066 }
3067 UNLOCK_ACTION(ap);
3068
3069 /*
3070 * Increment the hold count to prevent the structure from being
3071 * freed.
3072 */
3073
3074 atomic_add_32(&(ap->ippa_hold_count), 1);
3075 rw_exit(ipp_action_byid_lock);
3076
3077 return (ap);
3078 }
3079 #undef __FN__
3080
3081 #define __FN__ "rele_action"
3082 static void
3083 rele_action(
3084 ipp_action_t *ap)
3085 {
3086 /*
3087 * This call means we're done with the pointer so we can drop the
3088 * hold count.
3089 */
3090
3091 ASSERT(ap->ippa_hold_count != 0);
3092 atomic_add_32(&(ap->ippa_hold_count), -1);
3093
3094 /*
3095 * If the structure has 'destruct pending' set then we tried to free
3096 * it but couldn't, so do it now.
3097 */
3098
3099 LOCK_ACTION(ap, RW_READER);
3100 if (ap->ippa_destruct_pending && ap->ippa_hold_count == 0) {
3101 UNLOCK_ACTION(ap);
3102 kmem_cache_free(ipp_action_cache, ap);
3103 return;
3104 }
3105 UNLOCK_ACTION(ap);
3106 }
3107 #undef __FN__
3108
3109 #define __FN__ "get_aid"
3110 static ipp_action_id_t
3111 get_aid(
3112 void)
|
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <sys/param.h>
28 #include <sys/modctl.h>
29 #include <sys/sysmacros.h>
30 #include <sys/kmem.h>
31 #include <sys/cmn_err.h>
32 #include <sys/ddi.h>
33 #include <sys/sunddi.h>
34 #include <sys/spl.h>
35 #include <sys/time.h>
36 #include <sys/varargs.h>
37 #include <ipp/ipp.h>
38 #include <ipp/ipp_impl.h>
39 #include <ipp/ipgpc/ipgpc.h>
40
41 /*
42 * Debug switch.
43 */
44
45 #if defined(DEBUG)
1359 */
1360 LOCK_ACTION(ap, RW_READER);
1361 if (ap->ippa_state != IPP_ASTATE_AVAILABLE) {
1362 UNLOCK_ACTION(ap);
1363 rele_action(ap);
1364 return (EPROTO);
1365 }
1366
1367 /*
1368 * Increment the action's packet count to note that
1369 * it's being used.
1370 *
1371 * NOTE: We only have a read lock, so we need to use
1372 * atomic_add_32(). The read lock is still
1373 * important though as it is crucial to block
1374 * out a destroy operation between the action
1375 * state being checked and the packet count
1376 * being incremented.
1377 */
1378
1379 atomic_inc_32(&(ap->ippa_packets));
1380
1381 imp = ap->ippa_mod;
1382 ASSERT(imp != NULL);
1383 UNLOCK_ACTION(ap);
1384
1385 ippo = imp->ippm_ops;
1386 ASSERT(ippo != NULL);
1387
1388 /*
1389 * If there's a log, grab the next entry and fill it
1390 * in.
1391 */
1392
1393 if (pp->ippp_log != NULL &&
1394 pp->ippp_log_windex <= pp->ippp_log_limit) {
1395 lp = &(pp->ippp_log[pp->ippp_log_windex++]);
1396 lp->ippl_aid = aid;
1397 (void) strcpy(lp->ippl_name, cp->ippc_name);
1398 gethrestime(&lp->ippl_begin);
1399 } else {
1401 }
1402
1403 /*
1404 * Invoke the action.
1405 */
1406
1407 rc = ippo->ippo_action_invoke(aid, pp);
1408
1409 /*
1410 * Also log the time that the action finished
1411 * processing.
1412 */
1413
1414 if (lp != NULL)
1415 gethrestime(&lp->ippl_end);
1416
1417 /*
1418 * Decrement the packet count.
1419 */
1420
1421 atomic_dec_32(&(ap->ippa_packets));
1422
1423 /*
1424 * If the class' action id is the same now as it was
1425 * before then clearly no 'next action' has been set.
1426 * This is a protocol error.
1427 */
1428
1429 if (cp->ippc_aid == aid) {
1430 DBG1(DBG_PACKET,
1431 "action '%s' did not set next action\n",
1432 ap->ippa_name);
1433 rele_action(ap);
1434 return (EPROTO);
1435 }
1436
1437 /*
1438 * The action did not complete successfully. Terminate
1439 * packet processing.
1440 */
1441
2360
2361 /*
2362 * If the modul has 'destruct pending' set then it means it is either
2363 * still in the cache (i.e not allocated) or in the process of
2364 * being set up by alloc_mod().
2365 */
2366
2367 LOCK_MOD(imp, RW_READER);
2368 if (imp->ippm_destruct_pending) {
2369 UNLOCK_MOD(imp);
2370 rw_exit(ipp_mod_byid_lock);
2371 return (NULL);
2372 }
2373 UNLOCK_MOD(imp);
2374
2375 /*
2376 * Increment the hold count to prevent the structure from being
2377 * freed.
2378 */
2379
2380 atomic_inc_32(&(imp->ippm_hold_count));
2381 rw_exit(ipp_mod_byid_lock);
2382
2383 return (imp);
2384 }
2385 #undef __FN__
2386
2387 #define __FN__ "rele_mod"
2388 static void
2389 rele_mod(
2390 ipp_mod_t *imp)
2391 {
2392 /*
2393 * This call means we're done with the pointer so we can drop the
2394 * hold count.
2395 */
2396
2397 ASSERT(imp->ippm_hold_count != 0);
2398 atomic_dec_32(&(imp->ippm_hold_count));
2399
2400 /*
2401 * If the structure has 'destruct pending' set then we tried to free
2402 * it but couldn't, so do it now.
2403 */
2404
2405 LOCK_MOD(imp, RW_READER);
2406 if (imp->ippm_destruct_pending && imp->ippm_hold_count == 0) {
2407 UNLOCK_MOD(imp);
2408 kmem_cache_free(ipp_mod_cache, imp);
2409 return;
2410 }
2411
2412 UNLOCK_MOD(imp);
2413 }
2414 #undef __FN__
2415
2416 #define __FN__ "get_mid"
2417 static ipp_mod_id_t
2418 get_mid(
3052
3053 /*
3054 * If the action has 'destruct pending' set then it means it is either
3055 * still in the cache (i.e not allocated) or in the process of
3056 * being set up by alloc_action().
3057 */
3058
3059 LOCK_ACTION(ap, RW_READER);
3060 if (ap->ippa_destruct_pending) {
3061 UNLOCK_ACTION(ap);
3062 rw_exit(ipp_action_byid_lock);
3063 return (NULL);
3064 }
3065 UNLOCK_ACTION(ap);
3066
3067 /*
3068 * Increment the hold count to prevent the structure from being
3069 * freed.
3070 */
3071
3072 atomic_inc_32(&(ap->ippa_hold_count));
3073 rw_exit(ipp_action_byid_lock);
3074
3075 return (ap);
3076 }
3077 #undef __FN__
3078
3079 #define __FN__ "rele_action"
3080 static void
3081 rele_action(
3082 ipp_action_t *ap)
3083 {
3084 /*
3085 * This call means we're done with the pointer so we can drop the
3086 * hold count.
3087 */
3088
3089 ASSERT(ap->ippa_hold_count != 0);
3090 atomic_dec_32(&(ap->ippa_hold_count));
3091
3092 /*
3093 * If the structure has 'destruct pending' set then we tried to free
3094 * it but couldn't, so do it now.
3095 */
3096
3097 LOCK_ACTION(ap, RW_READER);
3098 if (ap->ippa_destruct_pending && ap->ippa_hold_count == 0) {
3099 UNLOCK_ACTION(ap);
3100 kmem_cache_free(ipp_action_cache, ap);
3101 return;
3102 }
3103 UNLOCK_ACTION(ap);
3104 }
3105 #undef __FN__
3106
3107 #define __FN__ "get_aid"
3108 static ipp_action_id_t
3109 get_aid(
3110 void)
|