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
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]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
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.
39 #include <sys/modctl.h>
41 #include <sys/sunddi.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.
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;
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().
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
;
93 ASSERT(drvinfo
!= NULL
);
94 ASSERT(parms
!= 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 */
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
);
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.
156 hci1394_buf_free(hci1394_buf_handle_t
*handle
)
160 ASSERT(handle
!= NULL
);
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 */