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 */
41typedef 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
51typedef 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
63gcmd_t *
64ghd_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
98void
99ghd_gcmd_free(gcmd_t *gcmdp)
100{
101	kmem_free(gcmdp, ((gw_t *)gcmdp)->glen);
102}
103