1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate * All rights reserved.
25*7c478bd9Sstevel@tonic-gate */
26*7c478bd9Sstevel@tonic-gate
27*7c478bd9Sstevel@tonic-gate /*
28*7c478bd9Sstevel@tonic-gate * hci1394_vendor.c
29*7c478bd9Sstevel@tonic-gate * These routines provide initialization, cleanup, and general access to
30*7c478bd9Sstevel@tonic-gate * vendor specific features on the OpenHCI adapter.
31*7c478bd9Sstevel@tonic-gate */
32*7c478bd9Sstevel@tonic-gate
33*7c478bd9Sstevel@tonic-gate #include <sys/conf.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
37*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
38*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
39*7c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
40*7c478bd9Sstevel@tonic-gate
41*7c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h>
42*7c478bd9Sstevel@tonic-gate
43*7c478bd9Sstevel@tonic-gate
44*7c478bd9Sstevel@tonic-gate /*
45*7c478bd9Sstevel@tonic-gate * Macro which makes sure vendor register offset is not greater that 0x7FC and
46*7c478bd9Sstevel@tonic-gate * that it is quadlet aligned.
47*7c478bd9Sstevel@tonic-gate */
48*7c478bd9Sstevel@tonic-gate #define VENDOR_ALIGN_ADDR(addr) (addr & 0x7FC)
49*7c478bd9Sstevel@tonic-gate
50*7c478bd9Sstevel@tonic-gate
51*7c478bd9Sstevel@tonic-gate /*
52*7c478bd9Sstevel@tonic-gate * Patchable variable to have the driver set the GUID on a Sun RIO chip.
53*7c478bd9Sstevel@tonic-gate * Normally this will be done by the firmware, but for PPX cards and OBP images
54*7c478bd9Sstevel@tonic-gate * without 1394 support, we need to fo this. This is only used for RIO. Other
55*7c478bd9Sstevel@tonic-gate * vendor cards are not effected.
56*7c478bd9Sstevel@tonic-gate * 0 - don't set GUID (default)
57*7c478bd9Sstevel@tonic-gate * non zero - set GUID on RIO
58*7c478bd9Sstevel@tonic-gate */
59*7c478bd9Sstevel@tonic-gate int hci1394_set_rio_guid = 0;
60*7c478bd9Sstevel@tonic-gate
61*7c478bd9Sstevel@tonic-gate
62*7c478bd9Sstevel@tonic-gate static int hci1394_rio_init(hci1394_vendor_t *vendor);
63*7c478bd9Sstevel@tonic-gate static void hci1394_rio_guid_init(hci1394_vendor_t *vendor);
64*7c478bd9Sstevel@tonic-gate static int hci1394_rio_resume(hci1394_vendor_t *vendor);
65*7c478bd9Sstevel@tonic-gate
66*7c478bd9Sstevel@tonic-gate
67*7c478bd9Sstevel@tonic-gate /*
68*7c478bd9Sstevel@tonic-gate * hci1394_vendor_init()
69*7c478bd9Sstevel@tonic-gate * Initialize the Vendor Specific portions of the OpenHCI chipset. This is
70*7c478bd9Sstevel@tonic-gate * not required according to the OpenHCI spec, but may be needed for
71*7c478bd9Sstevel@tonic-gate * performance optimizations, etc. dip, accattrp, and vendor_info are inputs.
72*7c478bd9Sstevel@tonic-gate * num_reg_sets and vendor_handle are outputs. num_reg_sets is the number of
73*7c478bd9Sstevel@tonic-gate * registers sets (or mappings) that are present for this device. This will
74*7c478bd9Sstevel@tonic-gate * usually be 0 or 1. vendor_handle is an opaque handle used in rest of
75*7c478bd9Sstevel@tonic-gate * vendor routines.
76*7c478bd9Sstevel@tonic-gate */
77*7c478bd9Sstevel@tonic-gate int
hci1394_vendor_init(hci1394_drvinfo_t * drvinfo,hci1394_ohci_handle_t ohci,hci1394_vendor_info_t * vendor_info,hci1394_vendor_handle_t * vendor_handle)78*7c478bd9Sstevel@tonic-gate hci1394_vendor_init(hci1394_drvinfo_t *drvinfo, hci1394_ohci_handle_t ohci,
79*7c478bd9Sstevel@tonic-gate hci1394_vendor_info_t *vendor_info, hci1394_vendor_handle_t *vendor_handle)
80*7c478bd9Sstevel@tonic-gate {
81*7c478bd9Sstevel@tonic-gate int status;
82*7c478bd9Sstevel@tonic-gate hci1394_vendor_t *vendor;
83*7c478bd9Sstevel@tonic-gate
84*7c478bd9Sstevel@tonic-gate
85*7c478bd9Sstevel@tonic-gate ASSERT(drvinfo != NULL);
86*7c478bd9Sstevel@tonic-gate ASSERT(vendor_info != NULL);
87*7c478bd9Sstevel@tonic-gate ASSERT(vendor_handle != NULL);
88*7c478bd9Sstevel@tonic-gate
89*7c478bd9Sstevel@tonic-gate /*
90*7c478bd9Sstevel@tonic-gate * alloc the space to keep track of the vendor registers.
91*7c478bd9Sstevel@tonic-gate */
92*7c478bd9Sstevel@tonic-gate vendor = kmem_alloc(sizeof (hci1394_vendor_t), KM_SLEEP);
93*7c478bd9Sstevel@tonic-gate vendor->ve_info = *vendor_info;
94*7c478bd9Sstevel@tonic-gate vendor->ve_drvinfo = drvinfo;
95*7c478bd9Sstevel@tonic-gate vendor->ve_ohci = ohci;
96*7c478bd9Sstevel@tonic-gate
97*7c478bd9Sstevel@tonic-gate /* setup the vendor_handle return parameter */
98*7c478bd9Sstevel@tonic-gate *vendor_handle = vendor;
99*7c478bd9Sstevel@tonic-gate
100*7c478bd9Sstevel@tonic-gate /* call vendor specific initialization routine */
101*7c478bd9Sstevel@tonic-gate switch (vendor_info->vendor_id) {
102*7c478bd9Sstevel@tonic-gate
103*7c478bd9Sstevel@tonic-gate /* Sun Microsystems 1394 Device */
104*7c478bd9Sstevel@tonic-gate case VENDOR_VID_SUN_MICROSYSTEMS:
105*7c478bd9Sstevel@tonic-gate switch (vendor_info->device_id) {
106*7c478bd9Sstevel@tonic-gate
107*7c478bd9Sstevel@tonic-gate /* RIO base chip. Call the RIO specific init routine */
108*7c478bd9Sstevel@tonic-gate case VENDOR_DID_RIO_1394:
109*7c478bd9Sstevel@tonic-gate status = hci1394_rio_init(vendor);
110*7c478bd9Sstevel@tonic-gate if (status != DDI_SUCCESS) {
111*7c478bd9Sstevel@tonic-gate kmem_free(vendor,
112*7c478bd9Sstevel@tonic-gate sizeof (hci1394_vendor_t));
113*7c478bd9Sstevel@tonic-gate *vendor_handle = NULL;
114*7c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
115*7c478bd9Sstevel@tonic-gate }
116*7c478bd9Sstevel@tonic-gate break;
117*7c478bd9Sstevel@tonic-gate /* VENDOR_DID_RIO_1394 */
118*7c478bd9Sstevel@tonic-gate
119*7c478bd9Sstevel@tonic-gate /* unrecognized device - don't map any registers */
120*7c478bd9Sstevel@tonic-gate default:
121*7c478bd9Sstevel@tonic-gate vendor->ve_reg_count = 0;
122*7c478bd9Sstevel@tonic-gate break;
123*7c478bd9Sstevel@tonic-gate }
124*7c478bd9Sstevel@tonic-gate break;
125*7c478bd9Sstevel@tonic-gate /* VENDOR_VID_SUN_MICROSYSTEMS */
126*7c478bd9Sstevel@tonic-gate
127*7c478bd9Sstevel@tonic-gate /* unrecognized vendor - don't map any registers */
128*7c478bd9Sstevel@tonic-gate default:
129*7c478bd9Sstevel@tonic-gate vendor->ve_reg_count = 0;
130*7c478bd9Sstevel@tonic-gate break;
131*7c478bd9Sstevel@tonic-gate }
132*7c478bd9Sstevel@tonic-gate
133*7c478bd9Sstevel@tonic-gate vendor_info->vendor_reg_count = vendor->ve_reg_count;
134*7c478bd9Sstevel@tonic-gate
135*7c478bd9Sstevel@tonic-gate return (DDI_SUCCESS);
136*7c478bd9Sstevel@tonic-gate }
137*7c478bd9Sstevel@tonic-gate
138*7c478bd9Sstevel@tonic-gate
139*7c478bd9Sstevel@tonic-gate /*
140*7c478bd9Sstevel@tonic-gate * hci1394_vendor_fini()
141*7c478bd9Sstevel@tonic-gate * Cleanup after Vendor Specific init. This includes freeing any allocated
142*7c478bd9Sstevel@tonic-gate * kernel memory and freeing any mapped registers.
143*7c478bd9Sstevel@tonic-gate *
144*7c478bd9Sstevel@tonic-gate * NOTE: This routine must be called after a successful vendor_init even if the
145*7c478bd9Sstevel@tonic-gate * num_reg_sets = 0 during init. This routine is normally called during
146*7c478bd9Sstevel@tonic-gate * the detach process.
147*7c478bd9Sstevel@tonic-gate *
148*7c478bd9Sstevel@tonic-gate * NOTE: A pointer to the handle is used for the parameter. fini() will set
149*7c478bd9Sstevel@tonic-gate * your handle to NULL before returning.
150*7c478bd9Sstevel@tonic-gate */
151*7c478bd9Sstevel@tonic-gate void
hci1394_vendor_fini(hci1394_vendor_handle_t * vendor_handle)152*7c478bd9Sstevel@tonic-gate hci1394_vendor_fini(hci1394_vendor_handle_t *vendor_handle)
153*7c478bd9Sstevel@tonic-gate {
154*7c478bd9Sstevel@tonic-gate uint_t index;
155*7c478bd9Sstevel@tonic-gate
156*7c478bd9Sstevel@tonic-gate
157*7c478bd9Sstevel@tonic-gate ASSERT(vendor_handle != NULL);
158*7c478bd9Sstevel@tonic-gate
159*7c478bd9Sstevel@tonic-gate for (index = 0; index < (*vendor_handle)->ve_reg_count; index++) {
160*7c478bd9Sstevel@tonic-gate ddi_regs_map_free(&(*vendor_handle)->
161*7c478bd9Sstevel@tonic-gate ve_reg_array[index]->vr_reg_handle);
162*7c478bd9Sstevel@tonic-gate }
163*7c478bd9Sstevel@tonic-gate kmem_free(*vendor_handle, sizeof (hci1394_vendor_t));
164*7c478bd9Sstevel@tonic-gate
165*7c478bd9Sstevel@tonic-gate /* Set the vendor_handle to NULL to help catch bugs */
166*7c478bd9Sstevel@tonic-gate *vendor_handle = NULL;
167*7c478bd9Sstevel@tonic-gate }
168*7c478bd9Sstevel@tonic-gate
169*7c478bd9Sstevel@tonic-gate
170*7c478bd9Sstevel@tonic-gate /*
171*7c478bd9Sstevel@tonic-gate * hci1394_vendor_resume()
172*7c478bd9Sstevel@tonic-gate * Vendor Specific init for a power resume (DDI_RESUME). This includes
173*7c478bd9Sstevel@tonic-gate * re-setting up any vendor specific registers.
174*7c478bd9Sstevel@tonic-gate */
175*7c478bd9Sstevel@tonic-gate int
hci1394_vendor_resume(hci1394_vendor_handle_t vendor_handle)176*7c478bd9Sstevel@tonic-gate hci1394_vendor_resume(hci1394_vendor_handle_t vendor_handle)
177*7c478bd9Sstevel@tonic-gate {
178*7c478bd9Sstevel@tonic-gate int status;
179*7c478bd9Sstevel@tonic-gate hci1394_vendor_info_t *vendor_info;
180*7c478bd9Sstevel@tonic-gate
181*7c478bd9Sstevel@tonic-gate
182*7c478bd9Sstevel@tonic-gate ASSERT(vendor_handle != NULL);
183*7c478bd9Sstevel@tonic-gate
184*7c478bd9Sstevel@tonic-gate vendor_info = &vendor_handle->ve_info;
185*7c478bd9Sstevel@tonic-gate
186*7c478bd9Sstevel@tonic-gate /* call vendor specific initialization routine */
187*7c478bd9Sstevel@tonic-gate switch (vendor_info->vendor_id) {
188*7c478bd9Sstevel@tonic-gate
189*7c478bd9Sstevel@tonic-gate /* Sun Microsystems 1394 Device */
190*7c478bd9Sstevel@tonic-gate case VENDOR_VID_SUN_MICROSYSTEMS:
191*7c478bd9Sstevel@tonic-gate switch (vendor_info->device_id) {
192*7c478bd9Sstevel@tonic-gate
193*7c478bd9Sstevel@tonic-gate /* RIO base chip. Call the RIO specific resume routine */
194*7c478bd9Sstevel@tonic-gate case VENDOR_DID_RIO_1394:
195*7c478bd9Sstevel@tonic-gate status = hci1394_rio_resume(vendor_handle);
196*7c478bd9Sstevel@tonic-gate if (status != DDI_SUCCESS) {
197*7c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
198*7c478bd9Sstevel@tonic-gate }
199*7c478bd9Sstevel@tonic-gate break;
200*7c478bd9Sstevel@tonic-gate /* VENDOR_DID_RIO_1394 */
201*7c478bd9Sstevel@tonic-gate
202*7c478bd9Sstevel@tonic-gate /* unrecognized device - don't map any registers */
203*7c478bd9Sstevel@tonic-gate default:
204*7c478bd9Sstevel@tonic-gate break;
205*7c478bd9Sstevel@tonic-gate }
206*7c478bd9Sstevel@tonic-gate break;
207*7c478bd9Sstevel@tonic-gate /* VENDOR_VID_SUN_MICROSYSTEMS */
208*7c478bd9Sstevel@tonic-gate
209*7c478bd9Sstevel@tonic-gate /* unrecognized vendor - don't map any registers */
210*7c478bd9Sstevel@tonic-gate default:
211*7c478bd9Sstevel@tonic-gate break;
212*7c478bd9Sstevel@tonic-gate }
213*7c478bd9Sstevel@tonic-gate
214*7c478bd9Sstevel@tonic-gate return (DDI_SUCCESS);
215*7c478bd9Sstevel@tonic-gate }
216*7c478bd9Sstevel@tonic-gate
217*7c478bd9Sstevel@tonic-gate
218*7c478bd9Sstevel@tonic-gate /*
219*7c478bd9Sstevel@tonic-gate * hci1394_vendor_reg_write()
220*7c478bd9Sstevel@tonic-gate * Write vendor specific register. reg_set is the register set to write. The
221*7c478bd9Sstevel@tonic-gate * first register set would be reg_set = 0, the second reg_set = 1, etc.
222*7c478bd9Sstevel@tonic-gate * offset is the offset into the vendor specific register space. An offset of
223*7c478bd9Sstevel@tonic-gate * 0 would be the first vendor register for that register set. data is the
224*7c478bd9Sstevel@tonic-gate * data to write to the vendor register.
225*7c478bd9Sstevel@tonic-gate */
226*7c478bd9Sstevel@tonic-gate int
hci1394_vendor_reg_write(hci1394_vendor_handle_t vendor_handle,uint_t reg_set,uint_t offset,uint32_t data)227*7c478bd9Sstevel@tonic-gate hci1394_vendor_reg_write(hci1394_vendor_handle_t vendor_handle,
228*7c478bd9Sstevel@tonic-gate uint_t reg_set, uint_t offset, uint32_t data)
229*7c478bd9Sstevel@tonic-gate {
230*7c478bd9Sstevel@tonic-gate hci1394_vendor_reg_t *venreg;
231*7c478bd9Sstevel@tonic-gate uint32_t *regaddr;
232*7c478bd9Sstevel@tonic-gate
233*7c478bd9Sstevel@tonic-gate
234*7c478bd9Sstevel@tonic-gate ASSERT(vendor_handle != NULL);
235*7c478bd9Sstevel@tonic-gate
236*7c478bd9Sstevel@tonic-gate if (vendor_handle->ve_reg_count < (reg_set + 1)) {
237*7c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
238*7c478bd9Sstevel@tonic-gate }
239*7c478bd9Sstevel@tonic-gate
240*7c478bd9Sstevel@tonic-gate venreg = vendor_handle->ve_reg_array[reg_set];
241*7c478bd9Sstevel@tonic-gate regaddr = (uint32_t *)((uintptr_t)venreg->vr_reg_addr +
242*7c478bd9Sstevel@tonic-gate (uintptr_t)VENDOR_ALIGN_ADDR(offset));
243*7c478bd9Sstevel@tonic-gate
244*7c478bd9Sstevel@tonic-gate ddi_put32(venreg->vr_reg_handle, regaddr, data);
245*7c478bd9Sstevel@tonic-gate
246*7c478bd9Sstevel@tonic-gate return (DDI_SUCCESS);
247*7c478bd9Sstevel@tonic-gate }
248*7c478bd9Sstevel@tonic-gate
249*7c478bd9Sstevel@tonic-gate
250*7c478bd9Sstevel@tonic-gate /*
251*7c478bd9Sstevel@tonic-gate * hci1394_vendor_reg_read()
252*7c478bd9Sstevel@tonic-gate * Read vendor specific register. reg_set is the register set to write. The
253*7c478bd9Sstevel@tonic-gate * first register set would be reg_set = 0, the second reg_set = 1, etc.
254*7c478bd9Sstevel@tonic-gate * offset is the offset into the vendor specific register space. An offset
255*7c478bd9Sstevel@tonic-gate * of 0 would be the first vendor register for that register set. data is
256*7c478bd9Sstevel@tonic-gate * the address to put the data read.
257*7c478bd9Sstevel@tonic-gate */
258*7c478bd9Sstevel@tonic-gate int
hci1394_vendor_reg_read(hci1394_vendor_handle_t vendor_handle,uint_t reg_set,uint_t offset,uint32_t * data)259*7c478bd9Sstevel@tonic-gate hci1394_vendor_reg_read(hci1394_vendor_handle_t vendor_handle, uint_t reg_set,
260*7c478bd9Sstevel@tonic-gate uint_t offset, uint32_t *data)
261*7c478bd9Sstevel@tonic-gate {
262*7c478bd9Sstevel@tonic-gate hci1394_vendor_reg_t *venreg;
263*7c478bd9Sstevel@tonic-gate uint32_t *regaddr;
264*7c478bd9Sstevel@tonic-gate
265*7c478bd9Sstevel@tonic-gate
266*7c478bd9Sstevel@tonic-gate ASSERT(vendor_handle != NULL);
267*7c478bd9Sstevel@tonic-gate ASSERT(data != NULL);
268*7c478bd9Sstevel@tonic-gate
269*7c478bd9Sstevel@tonic-gate if (vendor_handle->ve_reg_count < (reg_set + 1)) {
270*7c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
271*7c478bd9Sstevel@tonic-gate }
272*7c478bd9Sstevel@tonic-gate
273*7c478bd9Sstevel@tonic-gate venreg = vendor_handle->ve_reg_array[reg_set];
274*7c478bd9Sstevel@tonic-gate regaddr = (uint32_t *)((uintptr_t)venreg->vr_reg_addr +
275*7c478bd9Sstevel@tonic-gate (uintptr_t)VENDOR_ALIGN_ADDR(offset));
276*7c478bd9Sstevel@tonic-gate
277*7c478bd9Sstevel@tonic-gate *data = ddi_get32(venreg->vr_reg_handle, regaddr);
278*7c478bd9Sstevel@tonic-gate
279*7c478bd9Sstevel@tonic-gate return (DDI_SUCCESS);
280*7c478bd9Sstevel@tonic-gate }
281*7c478bd9Sstevel@tonic-gate
282*7c478bd9Sstevel@tonic-gate /*
283*7c478bd9Sstevel@tonic-gate * hci1394_rio_init()
284*7c478bd9Sstevel@tonic-gate * Initialize SUNW RIO vendor specific registers.
285*7c478bd9Sstevel@tonic-gate */
286*7c478bd9Sstevel@tonic-gate static int
hci1394_rio_init(hci1394_vendor_t * vendor)287*7c478bd9Sstevel@tonic-gate hci1394_rio_init(hci1394_vendor_t *vendor)
288*7c478bd9Sstevel@tonic-gate {
289*7c478bd9Sstevel@tonic-gate int status;
290*7c478bd9Sstevel@tonic-gate
291*7c478bd9Sstevel@tonic-gate
292*7c478bd9Sstevel@tonic-gate ASSERT(vendor != NULL);
293*7c478bd9Sstevel@tonic-gate
294*7c478bd9Sstevel@tonic-gate vendor->ve_reg_count = 1;
295*7c478bd9Sstevel@tonic-gate vendor->ve_reg_array[0] = kmem_alloc(sizeof (hci1394_vendor_reg_t),
296*7c478bd9Sstevel@tonic-gate KM_SLEEP);
297*7c478bd9Sstevel@tonic-gate
298*7c478bd9Sstevel@tonic-gate status = ddi_regs_map_setup(vendor->ve_drvinfo->di_dip, RIOREG_REG_BASE,
299*7c478bd9Sstevel@tonic-gate &vendor->ve_reg_array[0]->vr_reg_addr, RIOREG_OFFSET, RIOREG_LENGTH,
300*7c478bd9Sstevel@tonic-gate &vendor->ve_drvinfo->di_reg_attr,
301*7c478bd9Sstevel@tonic-gate &vendor->ve_reg_array[0]->vr_reg_handle);
302*7c478bd9Sstevel@tonic-gate if (status != DDI_SUCCESS) {
303*7c478bd9Sstevel@tonic-gate vendor->ve_reg_count = 0;
304*7c478bd9Sstevel@tonic-gate kmem_free(vendor->ve_reg_array[0],
305*7c478bd9Sstevel@tonic-gate sizeof (hci1394_vendor_reg_t));
306*7c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
307*7c478bd9Sstevel@tonic-gate }
308*7c478bd9Sstevel@tonic-gate
309*7c478bd9Sstevel@tonic-gate /* Setup RIO Host Control Register */
310*7c478bd9Sstevel@tonic-gate status = hci1394_vendor_reg_write(vendor, 0, RIOREG_HOST_CONTROL,
311*7c478bd9Sstevel@tonic-gate RIOREG_HOST_CONTROL_SETTING);
312*7c478bd9Sstevel@tonic-gate if (status != DDI_SUCCESS) {
313*7c478bd9Sstevel@tonic-gate ddi_regs_map_free(&vendor->ve_reg_array[0]->vr_reg_handle);
314*7c478bd9Sstevel@tonic-gate vendor->ve_reg_count = 0;
315*7c478bd9Sstevel@tonic-gate kmem_free(vendor->ve_reg_array[0],
316*7c478bd9Sstevel@tonic-gate sizeof (hci1394_vendor_reg_t));
317*7c478bd9Sstevel@tonic-gate vendor->ve_reg_array[0] = NULL;
318*7c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
319*7c478bd9Sstevel@tonic-gate }
320*7c478bd9Sstevel@tonic-gate
321*7c478bd9Sstevel@tonic-gate /* Setup GUID on RIO without firmware support */
322*7c478bd9Sstevel@tonic-gate hci1394_rio_guid_init(vendor);
323*7c478bd9Sstevel@tonic-gate
324*7c478bd9Sstevel@tonic-gate return (DDI_SUCCESS);
325*7c478bd9Sstevel@tonic-gate }
326*7c478bd9Sstevel@tonic-gate
327*7c478bd9Sstevel@tonic-gate
328*7c478bd9Sstevel@tonic-gate /*
329*7c478bd9Sstevel@tonic-gate * hci1394_rio_resume()
330*7c478bd9Sstevel@tonic-gate * Re-initialize RIO. This routine should be called during a resume.
331*7c478bd9Sstevel@tonic-gate */
332*7c478bd9Sstevel@tonic-gate static int
hci1394_rio_resume(hci1394_vendor_t * vendor)333*7c478bd9Sstevel@tonic-gate hci1394_rio_resume(hci1394_vendor_t *vendor)
334*7c478bd9Sstevel@tonic-gate {
335*7c478bd9Sstevel@tonic-gate int status;
336*7c478bd9Sstevel@tonic-gate
337*7c478bd9Sstevel@tonic-gate
338*7c478bd9Sstevel@tonic-gate ASSERT(vendor != NULL);
339*7c478bd9Sstevel@tonic-gate
340*7c478bd9Sstevel@tonic-gate /* Setup RIO Host Control Register */
341*7c478bd9Sstevel@tonic-gate status = hci1394_vendor_reg_write(vendor, 0, RIOREG_HOST_CONTROL,
342*7c478bd9Sstevel@tonic-gate RIOREG_HOST_CONTROL_SETTING);
343*7c478bd9Sstevel@tonic-gate if (status != DDI_SUCCESS) {
344*7c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
345*7c478bd9Sstevel@tonic-gate }
346*7c478bd9Sstevel@tonic-gate
347*7c478bd9Sstevel@tonic-gate /* Setup GUID on RIO PPX */
348*7c478bd9Sstevel@tonic-gate hci1394_rio_guid_init(vendor);
349*7c478bd9Sstevel@tonic-gate
350*7c478bd9Sstevel@tonic-gate return (DDI_SUCCESS);
351*7c478bd9Sstevel@tonic-gate }
352*7c478bd9Sstevel@tonic-gate
353*7c478bd9Sstevel@tonic-gate
354*7c478bd9Sstevel@tonic-gate /*
355*7c478bd9Sstevel@tonic-gate * hci1394_rio_guid_init()
356*7c478bd9Sstevel@tonic-gate * Setup a GUID in the RIO. Normally firmware would do this for the
357*7c478bd9Sstevel@tonic-gate * motherboard version. This will not hurt a RIO on the motherboard since we
358*7c478bd9Sstevel@tonic-gate * won't be able to write the GUID. We should not get to this code anyway in
359*7c478bd9Sstevel@tonic-gate * production systems. Use a timestamp for the lower 40 bits of the GUID.
360*7c478bd9Sstevel@tonic-gate */
361*7c478bd9Sstevel@tonic-gate static void
hci1394_rio_guid_init(hci1394_vendor_t * vendor)362*7c478bd9Sstevel@tonic-gate hci1394_rio_guid_init(hci1394_vendor_t *vendor)
363*7c478bd9Sstevel@tonic-gate {
364*7c478bd9Sstevel@tonic-gate hrtime_t guid_timestamp;
365*7c478bd9Sstevel@tonic-gate
366*7c478bd9Sstevel@tonic-gate ASSERT(vendor != NULL);
367*7c478bd9Sstevel@tonic-gate
368*7c478bd9Sstevel@tonic-gate if (hci1394_set_rio_guid != 0) {
369*7c478bd9Sstevel@tonic-gate guid_timestamp = gethrtime();
370*7c478bd9Sstevel@tonic-gate
371*7c478bd9Sstevel@tonic-gate /* mask out the vendor field of the GUID */
372*7c478bd9Sstevel@tonic-gate guid_timestamp = guid_timestamp & RIOREG_GUID_MASK;
373*7c478bd9Sstevel@tonic-gate
374*7c478bd9Sstevel@tonic-gate /* fill in Sun Microsystems */
375*7c478bd9Sstevel@tonic-gate guid_timestamp = guid_timestamp | RIOREG_GUID_SUN_MICROSYSTEMS;
376*7c478bd9Sstevel@tonic-gate
377*7c478bd9Sstevel@tonic-gate /* write this to the GUID registers */
378*7c478bd9Sstevel@tonic-gate ddi_put32(vendor->ve_ohci->ohci_reg_handle,
379*7c478bd9Sstevel@tonic-gate &vendor->ve_ohci->ohci_regs->guid_hi,
380*7c478bd9Sstevel@tonic-gate (uint32_t)(guid_timestamp >> 32));
381*7c478bd9Sstevel@tonic-gate ddi_put32(vendor->ve_ohci->ohci_reg_handle,
382*7c478bd9Sstevel@tonic-gate &vendor->ve_ohci->ohci_regs->guid_lo,
383*7c478bd9Sstevel@tonic-gate (uint32_t)(guid_timestamp & 0xFFFFFFFF));
384*7c478bd9Sstevel@tonic-gate }
385*7c478bd9Sstevel@tonic-gate }
386