/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1999-2000 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* These routines provide initialization, cleanup, and general access to
* vendor specific features on the OpenHCI adapter.
*/
/*
* Macro which makes sure vendor register offset is not greater that 0x7FC and
* that it is quadlet aligned.
*/
/*
* Patchable variable to have the driver set the GUID on a Sun RIO chip.
* Normally this will be done by the firmware, but for PPX cards and OBP images
* without 1394 support, we need to fo this. This is only used for RIO. Other
* vendor cards are not effected.
* 0 - don't set GUID (default)
* non zero - set GUID on RIO
*/
int hci1394_set_rio_guid = 0;
/*
* hci1394_vendor_init()
* Initialize the Vendor Specific portions of the OpenHCI chipset. This is
* not required according to the OpenHCI spec, but may be needed for
* performance optimizations, etc. dip, accattrp, and vendor_info are inputs.
* num_reg_sets and vendor_handle are outputs. num_reg_sets is the number of
* registers sets (or mappings) that are present for this device. This will
* usually be 0 or 1. vendor_handle is an opaque handle used in rest of
* vendor routines.
*/
int
{
int status;
/*
* alloc the space to keep track of the vendor registers.
*/
/* setup the vendor_handle return parameter */
*vendor_handle = vendor;
/* call vendor specific initialization routine */
switch (vendor_info->vendor_id) {
/* Sun Microsystems 1394 Device */
switch (vendor_info->device_id) {
/* RIO base chip. Call the RIO specific init routine */
case VENDOR_DID_RIO_1394:
if (status != DDI_SUCCESS) {
sizeof (hci1394_vendor_t));
*vendor_handle = NULL;
errmsg, "hci1394_rio_init() failed");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
break;
/* VENDOR_DID_RIO_1394 */
/* unrecognized device - don't map any registers */
default:
vendor->ve_reg_count = 0;
break;
}
break;
/* VENDOR_VID_SUN_MICROSYSTEMS */
/* unrecognized vendor - don't map any registers */
default:
vendor->ve_reg_count = 0;
break;
}
return (DDI_SUCCESS);
}
/*
* hci1394_vendor_fini()
* Cleanup after Vendor Specific init. This includes freeing any allocated
* kernel memory and freeing any mapped registers.
*
* NOTE: This routine must be called after a successful vendor_init even if the
* num_reg_sets = 0 during init. This routine is normally called during
* the detach process.
*
* NOTE: A pointer to the handle is used for the parameter. fini() will set
* your handle to NULL before returning.
*/
void
{
}
/* Set the vendor_handle to NULL to help catch bugs */
*vendor_handle = NULL;
}
/*
* hci1394_vendor_resume()
* Vendor Specific init for a power resume (DDI_RESUME). This includes
* re-setting up any vendor specific registers.
*/
int
{
int status;
"");
/* call vendor specific initialization routine */
switch (vendor_info->vendor_id) {
/* Sun Microsystems 1394 Device */
switch (vendor_info->device_id) {
/* RIO base chip. Call the RIO specific resume routine */
case VENDOR_DID_RIO_1394:
if (status != DDI_SUCCESS) {
errmsg, "hci1394_rio_resume() failed");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
break;
/* VENDOR_DID_RIO_1394 */
/* unrecognized device - don't map any registers */
default:
break;
}
break;
/* VENDOR_VID_SUN_MICROSYSTEMS */
/* unrecognized vendor - don't map any registers */
default:
break;
}
"");
return (DDI_SUCCESS);
}
/*
* hci1394_vendor_reg_write()
* Write vendor specific register. reg_set is the register set to write. The
* first register set would be reg_set = 0, the second reg_set = 1, etc.
* offset is the offset into the vendor specific register space. An offset of
* 0 would be the first vendor register for that register set. data is the
* data to write to the vendor register.
*/
int
{
HCI1394_TNF_HAL_STACK, "");
"reg_set not present");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_vendor_reg_read()
* Read vendor specific register. reg_set is the register set to write. The
* first register set would be reg_set = 0, the second reg_set = 1, etc.
* offset is the offset into the vendor specific register space. An offset
* of 0 would be the first vendor register for that register set. data is
* the address to put the data read.
*/
int
{
HCI1394_TNF_HAL_STACK, "");
"reg_set not present");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_rio_init()
* Initialize SUNW RIO vendor specific registers.
*/
static int
{
int status;
KM_SLEEP);
if (status != DDI_SUCCESS) {
vendor->ve_reg_count = 0;
sizeof (hci1394_vendor_reg_t));
"");
"");
return (DDI_FAILURE);
}
/* Setup RIO Host Control Register */
if (status != DDI_SUCCESS) {
vendor->ve_reg_count = 0;
sizeof (hci1394_vendor_reg_t));
"");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
/* Setup GUID on RIO without firmware support */
return (DDI_SUCCESS);
}
/*
* hci1394_rio_resume()
* Re-initialize RIO. This routine should be called during a resume.
*/
static int
{
int status;
/* Setup RIO Host Control Register */
if (status != DDI_SUCCESS) {
"");
"");
return (DDI_FAILURE);
}
/* Setup GUID on RIO PPX */
return (DDI_SUCCESS);
}
/*
* hci1394_rio_guid_init()
* Setup a GUID in the RIO. Normally firmware would do this for the
* motherboard version. This will not hurt a RIO on the motherboard since we
* won't be able to write the GUID. We should not get to this code anyway in
* production systems. Use a timestamp for the lower 40 bits of the GUID.
*/
static void
{
"");
if (hci1394_set_rio_guid != 0) {
guid_timestamp = gethrtime();
/* mask out the vendor field of the GUID */
/* fill in Sun Microsystems */
/* write this to the GUID registers */
}
"");
}