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