/*
* 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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* The interface into the HAL from the services layer.
*/
static void hci1394_s1394if_shutdown(void *hal_private);
static int hci1394_s1394if_write_response(void *hal_private,
static int hci1394_s1394if_read_response(void *hal_private,
static int hci1394_s1394if_lock_response(void *hal_private,
static void hci1394_s1394if_response_complete(void *hal_private,
static int hci1394_s1394if_reset_bus(void *hal_private);
static int hci1394_s1394if_set_contender_bit(void *hal_private);
static int hci1394_s1394if_set_root_holdoff_bit(void *hal_private);
static int hci1394_s1394if_update_config_rom(void *hal_private,
static int hci1394_s1394if_phy_filter_set(void *hal_private,
static int hci1394_s1394if_phy_filter_clr(void *hal_private,
static int hci1394_s1394if_short_bus_reset(void *hal_private);
static int hci1394_s1394if_csr_read(void *hal_private,
static int hci1394_s1394if_csr_write(void *hal_private,
static void hci1394_s1394if_power_state_change(void *hal_private,
/* entry points into HAL from Services Layer */
H1394_EVTS_V1, /* hal_version */
0, /* reserved */
hci1394_s1394if_shutdown, /* shutdown */
hci1394_s1394if_phy, /* send_phy_config_pkt */
hci1394_s1394if_read, /* read */
hci1394_s1394if_read_response, /* read_response */
hci1394_s1394if_write, /* write */
hci1394_s1394if_write_response, /* write_response */
hci1394_s1394if_response_complete, /* response_complete */
hci1394_s1394if_lock, /* lock */
hci1394_s1394if_lock_response, /* lock_response */
hci1394_alloc_isoch_dma, /* allocate_isoch_dma */
hci1394_free_isoch_dma, /* free_isoch_dma */
hci1394_start_isoch_dma, /* start_isoch_dma */
hci1394_stop_isoch_dma, /* stop_isoch_dma */
hci1394_update_isoch_dma, /* update_isoch_dma */
hci1394_s1394if_update_config_rom, /* update_config_rom */
hci1394_s1394if_reset_bus, /* bus_reset */
hci1394_s1394if_short_bus_reset, /* short_bus_reset */
hci1394_s1394if_set_contender_bit, /* set_contender_bit */
hci1394_s1394if_set_root_holdoff_bit, /* set_root_holdoff_bit */
hci1394_s1394if_set_gap_count, /* set_gap_count */
hci1394_s1394if_csr_read, /* csr_read */
hci1394_s1394if_csr_write, /* csr_write */
hci1394_s1394if_csr_cswap32, /* csr_cswap32 */
hci1394_s1394if_phy_filter_set, /* phys_arreq_enable_set */
hci1394_s1394if_phy_filter_clr, /* phys_arreq_enable_clr */
hci1394_s1394if_power_state_change /* node_power_state_change */
};
/*
* hci1394_s1394if_shutdown()
* Shutdown the HAL. This is called when a critical error has been detected.
* This routine should shutdown the HAL so that it will no longer send or
* to try and keep the machine from crashing.
*/
static void
{
HCI1394_TNF_HAL_STACK, "");
HCI1394_TNF_HAL_STACK, "");
}
/*
* hci1394_s1394if_phy()
* write a phy packet out to the 1394 bus. A phy packet consists of one
* quadlet of data.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not in a bus reset or shutdown */
} else {
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
result);
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_write()
* Perform a 1394 write operation. This can be either a quadlet or block
* write.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not in a bus reset or shutdown */
} else {
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
result);
if (status != DDI_SUCCESS) {
"");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_read()
* Perform a 1394 read operation. This can be either a quadlet or block
* read.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not in a bus reset or shutdown */
} else {
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
result);
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_lock()
* Perform a 1394/1212 lock operation. This can be one of the following lock
* operations: (CMD1394_LOCK_MASK_SWAP, CMD1394_LOCK_COMPARE_SWAP
* CMD1394_LOCK_FETCH_ADD, CMD1394_LOCK_LITTLE_ADD, CMD1394_LOCK_BOUNDED_ADD
* CMD1394_LOCK_WRAP_ADD)
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not in a bus reset or shutdown */
} else {
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
result);
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_write_response()
* Send a response to a write request received off of the 1394 bus. This
* could have been with a quadlet or block write request.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not in a bus reset or shutdown */
} else {
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_read_response()
* Send a response to a read request received off of the 1394 bus. This
* could have been with a quadlet or block read request.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not in a bus reset or shutdown */
} else {
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_lock_response()
* Send a response to a lock request received off of the 1394 bus. This
* could have been one of the following lock operations:
* (CMD1394_LOCK_MASK_SWAP, CMD1394_LOCK_COMPARE_SWAP CMD1394_LOCK_FETCH_ADD,
* CMD1394_LOCK_LITTLE_ADD, CMD1394_LOCK_BOUNDED_ADD, CMD1394_LOCK_WRAP_ADD)
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not in a bus reset or shutdown */
} else {
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_response_complete()
* This notifies the HAL that the services layer and target driver are done
* with a command that was received off of the 1394 bus. This will usually
* be called after the response to the command has been command_complete'd.
* The HAL is free to re-use the command or free up the memory from this
* command after this call has returned. This should only be called for
* ARREQ's.
*/
static void
{
HCI1394_TNF_HAL_STACK, "");
HCI1394_TNF_HAL_STACK, "");
}
/*
* hci1394_s1394if_reset_bus()
* This routine resets the 1394 bus. It performs a "long" bus reset. It
* should work on all OpenHCI adapters.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not shutdown */
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_set_contender_bit()
* This routine sets up the PHY so that the selfid contender bit will be set
* on subsequent bus resets. This routine will fail when we have a 1394-1995
* PHY since this PHY does not have a SW controllable contender bit.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not shutdown */
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_set_root_holdoff_bit()
* This routine will set the root holdoff bit in the PHY. The Services Layer
* should send out a PHY configuration packet first to tell everyone which
* node to set the root holdoff bit on. If it is our root holdoff bit we
* are setting, the PHY will automatically set it unless we have an old
* (1394-1995) PHY. If we have a 1394-1995 PHY, the SL needs to call this
* routine after sending the PHY configuration packet. The SL also needs to
* call this if they want to perform a long bus reset and have the root
* holdoff bit set. We do this so that we do not have to do a read before
* the write. A PHY register write has less of a chance of failing.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not shutdown */
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_set_gap_count()
* This routine will set the gap count bit in the PHY. The Services Layer
* should send out a PHY configuration packet first to tell everyone what
* gap count to use. Our PHY will automatically set the gap count unless we
* have an old (1394-1995) PHY. If we have a 1394-1995 PHY, the SL needs to
* call this routine after sending the PHY configuration packet and before
* generating a bus reset. The SL also needs to call before the they call to
* perform a long bus reset. We do this so that we do not have to do a PHY
* read before the write. A PHY register write has less of a chance of
* failing.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not shutdown */
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_phy_filter_set()
* disabled by default. They can be enabled on a node by node basis. All
* physical accesses are disabled every bus reset so they must be re-enabled
* every bus reset (This is due to the fact the the node ids change every bus
* physically mapped memory over the 1394 bus. A bit = to 1 enables that
* node's physical accesses, a bit = to 0 does nothing (i.e. a bitwise or is
* performed). The LSB of the mask (bit 0), maps to node #0, bit #62, maps to
* node 62. The MSB (#63) is not used since the can only be 63 nodes
* (0 - 62) on the bus.
*
* hci1394_s1394if_phy_filter_clr() is used to disable access to physical
* memory. This is only required if the node had previously been enabled.
*
* generation is used to verify that we are have not gotten a bus reset since
* the mask was built.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not shutdown */
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_phy_filter_clr()
* All physical accesses are disabled every bus reset so they must be
* re-enabled every bus reset (This is due to the fact the the node ids
* change every bus reset). Only nodes which have been enabled and no longer
* need access to physical memory need to be disabled.
*
* physically mapped memory over the 1394 bus. A bit = to 1 disables that
* node's physical accesses, a bit = to 0 does nothing (i.e. a bitwise or is
* performed). The LSB of the mask (bit 0), maps to node #0, bit #62, maps to
* node 62. The MSB (#63) is not used since there can only be 63 nodes
* (0 - 62) on the bus.
*
* hci1394_s1394if_phy_filter_set() is used to enable access to physical
* memory.
*
* generation is used to verify that we are have not gotten a bus reset since
* the mask was build.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not shutdown */
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_short_bus_reset()
* This routine resets the 1394 bus. It performs a "short" bus reset. It
* will only work on adapters with a 1394A or later PHY. Calling this routine
* when we have a 1394-1995 PHY is an error.
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not shutdown */
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
if (status != DDI_SUCCESS) {
HCI1394_TNF_HAL_ERROR, "");
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_update_config_rom()
* This routine updates the configuration ROM. It copies "quadlet_count"
* 32-bit words from "local_buf" to the config ROM starting at the first
* location in config ROM. This routine is meant to update the entire config
* ROM and not meant for a partial update.
*/
static int
{
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not shutdown */
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* hci1394_s1394if_csr_read()
* CSR register read interface
* For more information on CSR registers, see
* IEEE 1212
* IEEE 1394-1995
* section 8.3.2
* IEEE P1394A Draft 3.0
* sections 10.32,10.33
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not shutdown */
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
switch (offset) {
case CSR_STATE_CLEAR:
break;
case CSR_STATE_SET:
/* Write Only Register */
break;
case CSR_NODE_IDS:
break;
case CSR_RESET_START:
/* Not supported */
break;
case CSR_SPLIT_TIMEOUT_HI:
break;
case CSR_SPLIT_TIMEOUT_LO:
break;
case CSR_CYCLE_TIME:
/* CYCLE_TIME is implemented in HW */
break;
case CSR_BUS_TIME:
/* BUS_TIME is implemented in the hci1394_ohci_* SW */
break;
case CSR_BUSY_TIMEOUT:
break;
case CSR_BUS_MANAGER_ID:
/* BUS_MANAGER_ID is implemented in HW */
break;
case CSR_BANDWIDTH_AVAILABLE:
/* BANDWIDTH_AVAILABLE is implemented in HW */
break;
/* CHANNELS_AVAILABLE_HI is implemented in HW */
break;
/* CHANNELS_AVAILABLE_LO is implemented in HW */
break;
default:
break;
}
if (status != DDI_SUCCESS) {
}
HCI1394_TNF_HAL_STACK, "");
return (status);
}
/*
* hci1394_s1394if_csr_write()
* CSR register write interface
* For more information on CSR registers, see
* IEEE 1212
* IEEE 1394-1995
* section 8.3.2
* IEEE P1394A Draft 3.0
* sections 10.32,10.33
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not shutdown */
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
switch (offset) {
case CSR_STATE_CLEAR:
break;
case CSR_STATE_SET:
break;
case CSR_NODE_IDS:
break;
case CSR_RESET_START:
/* Not supported */
break;
/*
* there is a race condition when updating the split timeout
* due to the nature of the interface. (i.e. having a separate
* hi an lo register)
*/
case CSR_SPLIT_TIMEOUT_HI:
/*
* update the pending list timeout value. The split timeout
* is stored in 1394 bus cycles and the timeout is specified in
* nS. Therefore, we need to convert the split timeout into nS.
*/
soft_state->csr)));
break;
case CSR_SPLIT_TIMEOUT_LO:
/*
* update the pending list timeout value. The split timeout
* is stored in 1394 bus cycles and the timeout is specified in
* nS. Therefore, we need to convert the split timeout into nS.
*/
soft_state->csr)));
break;
case CSR_CYCLE_TIME:
break;
case CSR_BUS_TIME:
break;
case CSR_BUSY_TIMEOUT:
break;
case CSR_BUS_MANAGER_ID:
break;
case CSR_BANDWIDTH_AVAILABLE:
break;
break;
break;
default:
break;
}
if (status != DDI_SUCCESS) {
}
HCI1394_TNF_HAL_STACK, "");
return (status);
}
/*
* hci1394_s1394if_csr_cswap32()
* CSR register cswap32 interface
* For more information on CSR registers, see
* IEEE 1212
* IEEE 1394-1995
* section 8.3.2
* IEEE P1394A Draft 3.0
* sections 10.32,10.33
*/
static int
{
int status;
HCI1394_TNF_HAL_STACK, "");
/* make sure we are not shutdown */
HCI1394_TNF_HAL_STACK, "");
return (DDI_FAILURE);
}
switch (offset) {
case CSR_STATE_CLEAR:
break;
case CSR_STATE_SET:
/* Invalid access, only write allowed */
break;
case CSR_NODE_IDS:
break;
case CSR_RESET_START:
break;
case CSR_SPLIT_TIMEOUT_HI:
break;
case CSR_SPLIT_TIMEOUT_LO:
break;
case CSR_CYCLE_TIME:
break;
case CSR_BUS_TIME:
break;
case CSR_BUSY_TIMEOUT:
break;
case CSR_BUS_MANAGER_ID:
/* BUS_MANAGER_ID is implemented in HW */
break;
case CSR_BANDWIDTH_AVAILABLE:
/* BANDWIDTH_AVAILABLE is implemented in HW */
break;
/* CHANNELS_AVAILABLE_HI is implemented in HW */
break;
/* CHANNELS_AVAILABLE_LO is implemented in HW */
break;
default:
break;
}
if (status != DDI_SUCCESS) {
}
HCI1394_TNF_HAL_STACK, "");
return (status);
}
/*
* hci1394_s1394if_power_state_change()
* Signals that a change in the bus topology has taken place which may affect
* power management.
*/
/*ARGSUSED*/
static void
{
/* not implemented */
}