xref: /illumos-gate/usr/src/uts/intel/io/dktp/hba/ghd/ghd_gcmd.c (revision a0955b86cd77e22e80846428a5065e871b6d8eb8)
1 /*
2  * CDDL HEADER START
3  *
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.
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 /*
23  * Copyright 1999 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include "ghd.h"
30 
31 /*
32  * Round up all allocations so that we can guarantee
33  * long-long alignment.  This is the same alignment
34  * provided by kmem_alloc().
35  */
36 #define	ROUNDUP(x)	(((x) + 0x07) & ~0x07)
37 
38 /*
39  * Private wrapper for gcmd_t
40  */
41 typedef struct gw_gcmd_and_length {
42 	gcmd_t	gcmd;		/* this must be first */
43 	int	glen;		/* length includes HBA private area */
44 }gw_t;
45 
46 /*
47  * round up the size so the HBA private area is on a 8 byte boundary
48  */
49 #define	GW_PADDED_LENGTH	ROUNDUP(sizeof (gw_t))
50 
51 typedef struct gcmd_padded_wrapper {
52 	union {
53 		gw_t	gw;
54 		char	gw_pad[GW_PADDED_LENGTH];
55 
56 	} gwrap;
57 } gwrap_t;
58 
59 /*
60  * Allocate a gcmd_t wrapper and HBA private area
61  */
62 
63 gcmd_t *
64 ghd_gcmd_alloc(gtgt_t	*gtgtp,
65 		int	ccblen,
66 		int	sleep)
67 {
68 	gwrap_t	*gwp;
69 	gcmd_t	*gcmdp;
70 	int	 gwrap_len;
71 
72 	ccblen = ROUNDUP(ccblen);
73 	gwrap_len = sizeof (gwrap_t) + ccblen;
74 	gwp = kmem_zalloc(gwrap_len, (sleep ? KM_SLEEP : KM_NOSLEEP));
75 	if (gwp == NULL) {
76 		ASSERT(sleep == FALSE);
77 		return (NULL);
78 	}
79 
80 	/* save the total length for the free function */
81 	gwp->gwrap.gw.glen = gwrap_len;
82 
83 	/*
84 	 * save the ptr to HBA private area and initialize all
85 	 * the gcmd_t members and save
86 	 */
87 	gcmdp = &gwp->gwrap.gw.gcmd;
88 	GHD_GCMD_INIT(gcmdp, (void *)(gwp + 1), gtgtp);
89 	return (gcmdp);
90 }
91 
92 
93 
94 /*
95  * Free the gcmd_t wrapper and HBA private area
96  */
97 
98 void
99 ghd_gcmd_free(gcmd_t *gcmdp)
100 {
101 	kmem_free(gcmdp, ((gw_t *)gcmdp)->glen);
102 }
103