Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / 1394 / adapters / hci1394_buf.c
blobf2c1241cefec3d2af3dbfa8eec79040ee3095d46
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * hci1394_buf.c
31 * These routines handle IO mapped memory. They include routines to alloc and
32 * free IO mapped memory and a routine to get the adapters default dma
33 * attributes. These routines are meant to be called from the base context.
34 * They should not be called from an interrupt handler.
37 #include <sys/conf.h>
38 #include <sys/ddi.h>
39 #include <sys/modctl.h>
40 #include <sys/stat.h>
41 #include <sys/sunddi.h>
42 #include <sys/kmem.h>
44 #include <sys/1394/h1394.h>
45 #include <sys/1394/adapters/hci1394.h>
49 * hci1394_buffer_attr_get()
50 * returns (in dma_attr) the default DMA attributes for this adapter.
52 void
53 hci1394_buf_attr_get(ddi_dma_attr_t *dma_attr)
55 dma_attr->dma_attr_version = DMA_ATTR_V0;
56 dma_attr->dma_attr_addr_lo = (uint64_t)0x00000000;
57 dma_attr->dma_attr_addr_hi = (uint64_t)0xFFFFFFFF;
58 dma_attr->dma_attr_count_max = (uint64_t)0xFFFFFFFF;
59 dma_attr->dma_attr_align = 64;
60 dma_attr->dma_attr_burstsizes = 0x3FF;
61 dma_attr->dma_attr_minxfer = 1;
62 dma_attr->dma_attr_maxxfer = (uint64_t)0xFFFFFFFF;
63 dma_attr->dma_attr_seg = (uint64_t)0xFFFFFFFF;
64 dma_attr->dma_attr_sgllen = 0x7FFFFFFF;
65 dma_attr->dma_attr_granular = 4;
66 dma_attr->dma_attr_flags = 0;
68 #if defined(__i386) || defined(__amd64)
69 /* XXX - Not sure why x86 wants the dma_attr_seg to be 0x7FFF?? */
70 dma_attr->dma_attr_seg = (uint64_t)0x7FFF;
71 #endif
76 * hci1394_buf_alloc()
77 * Allocate an IO mapped buffer. drvinfo is passed in and contains generic
78 * driver info, like dip, instance, buf_attr, etc. Parms is passed in and
79 * contains the input parameters for alloc, ow much memory to alloc, how many
80 * cookies can we handle, and alignment requirements. info is returned with
81 * all the info about the mapped buffer. handle is returned. It should be
82 * used when calling hci1394_buf_free().
84 int
85 hci1394_buf_alloc(hci1394_drvinfo_t *drvinfo, hci1394_buf_parms_t *parms,
86 hci1394_buf_info_t *info, hci1394_buf_handle_t *handle)
88 ddi_dma_attr_t dma_attr;
89 hci1394_buf_t *buf;
90 int status;
93 ASSERT(drvinfo != NULL);
94 ASSERT(parms != NULL);
95 ASSERT(info != NULL);
96 ASSERT(handle != NULL);
98 /* alloc the space to keep track of the buffer */
99 buf = kmem_alloc(sizeof (hci1394_buf_t), KM_SLEEP);
101 /* setup the return parameter */
102 *handle = buf;
104 /* save away pointer to general info */
105 buf->bu_drvinfo = drvinfo;
107 /* Get the default DMA attributes and override sgllen and alignment */
109 _NOTE(SCHEME_PROTECTS_DATA("unique (on stack)", ddi_dma_attr_t))
110 hci1394_buf_attr_get(&dma_attr);
111 dma_attr.dma_attr_sgllen = parms->bp_max_cookies;
112 dma_attr.dma_attr_align = parms->bp_alignment;
114 status = ddi_dma_alloc_handle(drvinfo->di_dip, &dma_attr,
115 DDI_DMA_SLEEP, NULL, &buf->bu_dma_handle);
116 if (status != DDI_SUCCESS) {
117 kmem_free(buf, sizeof (hci1394_buf_t));
118 return (DDI_FAILURE);
121 status = ddi_dma_mem_alloc(buf->bu_dma_handle, parms->bp_length,
122 &drvinfo->di_buf_attr, DDI_DMA_STREAMING, DDI_DMA_SLEEP,
123 NULL, &info->bi_kaddr, &info->bi_real_length, &buf->bu_handle);
124 if (status != DDI_SUCCESS) {
125 ddi_dma_free_handle(&buf->bu_dma_handle);
126 kmem_free(buf, sizeof (hci1394_buf_t));
127 return (DDI_FAILURE);
130 status = ddi_dma_addr_bind_handle(buf->bu_dma_handle, NULL,
131 info->bi_kaddr, info->bi_real_length, DDI_DMA_RDWR |
132 DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, &info->bi_cookie,
133 &info->bi_cookie_count);
134 if (status != DDI_SUCCESS) {
135 ddi_dma_mem_free(&buf->bu_handle);
136 ddi_dma_free_handle(&buf->bu_dma_handle);
137 kmem_free(buf, sizeof (hci1394_buf_t));
138 return (DDI_FAILURE);
141 /* setup rest of buffer info returned to caller */
142 info->bi_handle = buf->bu_handle;
143 info->bi_dma_handle = buf->bu_dma_handle;
144 info->bi_length = parms->bp_length;
146 return (DDI_SUCCESS);
151 * hci1394_buf_free()
152 * Free IO mapped buffer. Notice that a pointer to the handle is used for
153 * the parameter. free() will set your handle to NULL before returning.
155 void
156 hci1394_buf_free(hci1394_buf_handle_t *handle)
158 hci1394_buf_t *buf;
160 ASSERT(handle != NULL);
162 buf = *handle;
163 (void) ddi_dma_unbind_handle(buf->bu_dma_handle);
164 ddi_dma_mem_free(&buf->bu_handle);
165 ddi_dma_free_handle(&buf->bu_dma_handle);
167 /* free the space to keep track of the buffer */
168 kmem_free(buf, sizeof (hci1394_buf_t));
170 /* set the handle to NULL to help catch bugs */
171 *handle = NULL;