t1394.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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"
/*
* t1394.c
* 1394 Target Driver Interface
* This file contains all of the 1394 Software Framework routines called
* by target drivers
*/
#include <sys/tnf_probe.h>
static int s1394_allow_detach = 0;
/*
* Function: t1394_attach()
* Input(s): dip The dip given to the target driver
* in it's attach() routine
* version The version of the target driver -
* T1394_VERSION_V1
* flags The flags parameter is unused (for now)
*
* Output(s): attachinfo Used to pass info back to target,
* including bus generation, local
* node ID, dma attribute, etc.
* t1394_hdl The target "handle" to be used for
* all subsequent calls into the
* 1394 Software Framework
*
* Description: t1394_attach() registers the target (based on its dip) with
* the 1394 Software Framework. It returns the bus_generation,
* local_nodeID, iblock_cookie and other useful information to
* the target, as well as a handle (t1394_hdl) that will be used
* in all subsequent calls into this framework.
*/
/* ARGSUSED */
int
{
int hp_node = 0;
if (version != T1394_VERSION_V1) {
return (DDI_FAILURE);
}
return (DDI_FAILURE);
}
"hp-node");
/* Allocate space for s1394_target_t */
/* Copy in the params */
/* Place the target on the appropriate node */
if (hp_node != 0) {
/*
* on_node can be NULL if the node got unplugged
* while the target driver is in its attach routine.
*/
"on_node == NULL");
return (DDI_FAILURE);
}
}
/* Return the current generation */
/* Fill in hal node id */
/* Give the target driver the iblock_cookie */
/* Give the target driver the attributes */
DDI_PROP_DONTPASS, "unit-dir-offset", 0);
/* By default, disable all physical AR requests */
target->physical_arreq_enabled = 0;
/* Get dev_max_payload & current_max_payload */
/* Add into linked list */
} else {
}
/* Fill in services layer private info */
return (DDI_SUCCESS);
}
/*
* Function: t1394_detach()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* flags The flags parameter is unused (for now)
*
* Output(s): DDI_SUCCESS Target successfully detached
* DDI_FAILURE Target failed to detach
*
* Description: t1394_detach() unregisters the target from the 1394 Software
* Framework. t1394_detach() can fail if the target has any
* allocated commands that haven't been freed.
*/
/* ARGSUSED */
int
{
/* How many cmds has this target allocated? */
if (num_cmds != 0) {
return (DDI_FAILURE);
}
/*
* Remove from linked lists. Topology tree is already locked
* so that the node won't go away while we are looking at it.
*/
} else {
if (target->target_prev)
if (target->target_next)
}
/* Free memory */
return (DDI_SUCCESS);
}
/*
* Function: t1394_alloc_cmd()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* flags The flags parameter is described below
*
* Output(s): cmdp Pointer to the newly allocated command
*
* Description: t1394_alloc_cmd() allocates a command for use with the
* t1394_read(), t1394_write(), or t1394_lock() interfaces
* of the 1394 Software Framework. By default, t1394_alloc_cmd()
* may sleep while allocating memory for the command structure.
* If this is undesirable, the target may set the
* T1394_ALLOC_CMD_NOSLEEP bit in the flags parameter. Also,
* this call may fail because a target driver has already
* allocated MAX_NUMBER_ALLOC_CMDS commands.
*/
int
{
/* Find the HAL this target resides on */
/* How many cmds has this target allocated? */
if (num_cmds >= MAX_NUMBER_ALLOC_CMDS) {
"MAX_NUMBER_ALLOC_CMDS");
S1394_TNF_SL_ATREQ_STACK, "");
/* kstats - cmd alloc failures */
return (DDI_FAILURE);
}
/* Increment the number of cmds this target has allocated? */
S1394_TNF_SL_ATREQ_STACK, "");
/* kstats - cmd alloc failures */
return (DDI_FAILURE);
}
/* Get the Services Layer private area */
/* Initialize the command's blocking mutex */
/* Initialize the command's blocking condition variable */
return (DDI_SUCCESS);
}
/*
* Function: t1394_free_cmd()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* flags The flags parameter is unused (for now)
* cmdp Pointer to the command to be freed
*
* Output(s): DDI_SUCCESS Target successfully freed command
* DDI_FAILURE Target failed to free command
*
* Description: t1394_free_cmd() attempts to free a command that has previously
* been allocated by the target driver. It is possible for
* t1394_free_cmd() to fail because the command is currently
* in-use by the 1394 Software Framework.
*/
/* ARGSUSED */
int
{
/* Find the HAL this target resides on */
/* How many cmds has this target allocated? */
if (num_cmds == 0) {
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_FAILURE);
}
/* Get the Services Layer private area */
/* Check that command isn't in use */
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_FAILURE);
}
/* Decrement the number of cmds this target has allocated */
/* Destroy the command's blocking condition variable */
/* Destroy the command's blocking mutex */
/* Command pointer is set to NULL before returning */
/* kstats - number of cmd frees */
return (DDI_SUCCESS);
}
/*
* Function: t1394_read()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* cmd Pointer to the command to send
*
* Output(s): DDI_SUCCESS Target successful sent the command
* DDI_FAILURE Target failed to send command
*
* Description: t1394_read() attempts to send an asynchronous read request
* onto the 1394 bus.
*/
int
{
int ret;
int err;
/* Get the Services Layer private area */
/* Is this command currently in use? */
"");
return (DDI_FAILURE);
}
/* Set-up the destination of the command */
/* No status (default) */
/* Check for proper command type */
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_FAILURE);
}
/* Is this a blocking command on interrupt stack? */
"intr context");
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_FAILURE);
}
if (state != S1394_HAL_NORMAL) {
if (ret != CMD1394_CMDSUCCESS) {
return (DDI_FAILURE);
}
}
S1394_CMD_READ, &err);
/* Command has now been put onto the queue! */
if (ret != DDI_SUCCESS) {
/* Copy error code into result */
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_FAILURE);
}
/*
* If this command was sent during a bus reset,
* then put it onto the pending Q.
*/
if (state == S1394_HAL_RESET) {
/* Remove cmd from outstanding request Q */
/* Are we on the bus reset event stack? */
/* Blocking commands are not allowed */
msg, "CMD1394_BLOCKING in bus reset "
"context");
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_FAILURE);
}
}
/* Block (if necessary) */
goto block_on_asynch_cmd;
}
/* Send the command out */
if (ret != DDI_SUCCESS) {
if (err == CMD1394_ESTALE_GENERATION) {
/* Remove cmd from outstanding request Q */
/* Block (if necessary) */
goto block_on_asynch_cmd;
} else {
/* Remove cmd from outstanding request Q */
/* Copy error code into result */
"s1394_xfer_asynch_command()");
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_FAILURE);
}
} else {
/* Block (if necessary) */
goto block_on_asynch_cmd;
}
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_SUCCESS);
}
/*
* Function: t1394_write()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* cmd Pointer to the command to send
*
* Output(s): DDI_SUCCESS Target successful sent the command
* DDI_FAILURE Target failed to send command
*
* Description: t1394_write() attempts to send an asynchronous write request
* onto the 1394 bus.
*/
int
{
int ret;
int err;
/* Get the Services Layer private area */
/* Is this command currently in use? */
"");
return (DDI_FAILURE);
}
/* Set-up the destination of the command */
/* Is this an FA request? */
if (S1394_IS_CMD_FCP(s_priv) &&
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_FAILURE);
}
}
/* No status (default) */
/* Check for proper command type */
"");
return (DDI_FAILURE);
}
/* Is this a blocking command on interrupt stack? */
"context");
"");
return (DDI_FAILURE);
}
if (state != S1394_HAL_NORMAL) {
if (ret != CMD1394_CMDSUCCESS) {
return (DDI_FAILURE);
}
}
S1394_CMD_WRITE, &err);
/* Command has now been put onto the queue! */
if (ret != DDI_SUCCESS) {
/* Copy error code into result */
"");
return (DDI_FAILURE);
}
/*
* If this command was sent during a bus reset,
* then put it onto the pending Q.
*/
if (state == S1394_HAL_RESET) {
/* Remove cmd from outstanding request Q */
/* Are we on the bus reset event stack? */
/* Blocking commands are not allowed */
msg, "CMD1394_BLOCKING in bus reset cntxt");
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_FAILURE);
}
}
/* Block (if necessary) */
"");
return (DDI_SUCCESS);
}
/* Send the command out */
if (ret != DDI_SUCCESS) {
if (err == CMD1394_ESTALE_GENERATION) {
/* Remove cmd from outstanding request Q */
/* Block (if necessary) */
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_SUCCESS);
} else {
/* Remove cmd from outstanding request Q */
/* Copy error code into result */
"Failed in s1394_xfer_asynch_command()");
S1394_TNF_SL_ATREQ_STACK, "");
return (DDI_FAILURE);
}
} else {
/* Block (if necessary) */
"");
return (DDI_SUCCESS);
}
}
/*
* Function: t1394_lock()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* cmd Pointer to the command to send
*
* Output(s): DDI_SUCCESS Target successful sent the command
* DDI_FAILURE Target failed to send command
*
* Description: t1394_lock() attempts to send an asynchronous lock request
* onto the 1394 bus.
*/
int
{
int ret;
/* Get the Services Layer private area */
/* Is this command currently in use? */
"");
return (DDI_FAILURE);
}
/* Set-up the destination of the command */
if (state != S1394_HAL_NORMAL) {
if (ret != CMD1394_CMDSUCCESS) {
return (DDI_FAILURE);
}
}
/* Check for proper command type */
"t1394_lock()");
"");
return (DDI_FAILURE);
}
/* No status (default) */
/* Is this a blocking command on interrupt stack? */
"context");
"");
return (DDI_FAILURE);
}
} else { /* (cmd->cmd_type == CMD1394_ASYNCH_LOCK_64) */
}
/* Make sure num_retries is reasonable */
switch (lock_type) {
case CMD1394_LOCK_MASK_SWAP:
case CMD1394_LOCK_FETCH_ADD:
case CMD1394_LOCK_LITTLE_ADD:
case CMD1394_LOCK_BOUNDED_ADD:
case CMD1394_LOCK_WRAP_ADD:
break;
case CMD1394_LOCK_BIT_AND:
case CMD1394_LOCK_BIT_OR:
case CMD1394_LOCK_BIT_XOR:
case CMD1394_LOCK_INCREMENT:
case CMD1394_LOCK_DECREMENT:
case CMD1394_LOCK_ADD:
case CMD1394_LOCK_SUBTRACT:
case CMD1394_LOCK_THRESH_ADD:
case CMD1394_LOCK_CLIP_ADD:
break;
default:
ret = DDI_FAILURE;
break;
}
return (ret);
}
/*
* Function: t1394_alloc_addr()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* addr_allocp The structure used to specify the type,
* size, permissions, and callbacks
* (if any) for the requested block
* of 1394 address space
* flags The flags parameter is unused (for now)
*
* Output(s): result Used to pass more specific info back
* to target
*
* Description: t1394_alloc_addr() requests that part of the 1394 Address Space
* on the local node be set aside for this target driver, and
* associated with this address space should be some permissions
* and callbacks. If the request is unable to be fulfilled,
* t1394_alloc_addr() will return DDI_FAILURE and result will
* indicate the reason. T1394_EINVALID_PARAM indicates that the
* combination of flags given is invalid, and T1394_EALLOC_ADDR
* indicates that the requested type of address space is
* unavailable.
*/
/* ARGSUSED */
int
{
int err;
"");
/* Find the HAL this target resides on */
/* Get the bounds of the request */
/* Check combination of flags */
/*
* Reads are enabled, but target doesn't want to
* be notified and hasn't given backing store
*/
"Invalid flags "
"(RDs on, notify off, no backing store)");
S1394_TNF_SL_ARREQ_STACK, "");
/* kstats - addr alloc failures */
return (DDI_FAILURE);
} else {
}
}
/*
* Writes are enabled, but target doesn't want to
* be notified and hasn't given backing store
*/
"Invalid flags "
"(WRs on, notify off, no backing store)");
S1394_TNF_SL_ARREQ_STACK, "");
/* kstats - addr alloc failures */
return (DDI_FAILURE);
} else {
}
}
/*
* Locks are enabled, but target doesn't want to
* be notified and hasn't given backing store
*/
"Invalid flags "
"(LKs on, notify off, no backing store)");
S1394_TNF_SL_ARREQ_STACK, "");
/* kstats - addr alloc failures */
return (DDI_FAILURE);
} else {
}
}
/* If not T1394_ADDR_FIXED, then allocate a block */
if (err != DDI_SUCCESS) {
/* kstats - addr alloc failures */
} else {
*result = T1394_NOERROR;
}
S1394_TNF_SL_ARREQ_STACK, "");
return (err);
} else {
if (err != DDI_SUCCESS) {
/* kstats - addr alloc failures */
} else {
*result = T1394_NOERROR;
/* If physical, update the AR request counter */
}
}
S1394_TNF_SL_ARREQ_STACK, "");
return (err);
}
}
/*
* Function: t1394_free_addr()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* addr_hdl The address "handle" returned by the
* the t1394_alloc_addr() routine
* flags The flags parameter is unused (for now)
*
* Output(s): DDI_SUCCESS Target successfully freed memory
* DDI_FAILURE Target failed to free the memory block
*
* Description: t1394_free_addr() attempts to free up memory that has been
* allocated by the target using t1394_alloc_addr().
*/
/* ARGSUSED */
int
{
/* Find the HAL this target resides on */
S1394_TNF_SL_ARREQ_STACK, "");
return (DDI_FAILURE);
}
/* If physical, update the AR request counter */
}
/* kstats - number of addr frees */
return (DDI_SUCCESS);
}
/*
* Function: t1394_recv_request_done()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* resp Pointer to the command which the
* target received in it's callback
* flags The flags parameter is unused (for now)
*
* Output(s): DDI_SUCCESS Target successfully returned command
* to the 1394 Software Framework,
* and, if necessary, sent response
* DDI_FAILURE Target failed to return the command to
* the 1394 Software Framework
*
* Description: t1394_recv_request_done() takes the command that is given and
* determines whether that command requires a response to be
* sent on the 1394 bus. If it is necessary and it's response
* code (cmd_result) has been set appropriately, then a response
* will be sent. If no response is necessary (broadcast or
* posted write), then the command resources are reclaimed.
*/
/* ARGSUSED */
int
{
int ret;
S1394_TNF_SL_ARREQ_STACK, "");
/* Find the HAL this target resides on */
/* Get the Services Layer private area */
/* Get a pointer to the HAL private struct */
/* Is this an FA request? */
}
/* Is this a write request? */
/* Is this a posted write request? */
}
/* If broadcast or posted write cmd, don't send response */
/* kstats - Posted Write error */
}
/* Free the command - Pass it back to the HAL */
h_priv);
S1394_TNF_SL_ARREQ_STACK, "");
return (DDI_SUCCESS);
}
/* Verify valid response code */
switch (resp->cmd_result) {
case IEEE1394_RESP_COMPLETE:
/* Is the mblk_t too small? */
msgb_len = 0;
msg, "mblk_t is NULL in response");
S1394_TNF_SL_ARREQ_STACK, "");
/*
* Free the command - Pass it back
* to the HAL
*/
return (DDI_FAILURE);
}
msgb_len +=
break;
}
}
if (mblk_too_small == B_TRUE) {
msg, "mblk_t too small in response");
S1394_TNF_SL_ARREQ_STACK, "");
/*
* Free the command - Pass it back
* to the HAL
*/
return (DDI_FAILURE);
}
}
/* FALLTHROUGH */
case IEEE1394_RESP_DATA_ERROR:
case IEEE1394_RESP_TYPE_ERROR:
S1394_TNF_SL_ARREQ_STACK, "");
return (ret);
default:
"Invalid response code");
S1394_TNF_SL_ARREQ_STACK, "");
return (DDI_FAILURE);
}
}
/*
* Function: t1394_fcp_register_controller()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* evts The structure in which the target
* specifies its callback routines
*
* flags The flags parameter is unused (for now)
*
* Output(s): DDI_SUCCESS Successfully registered.
*
* DDI_FAILURE Not registered due to failure.
*
* Description: Used to register the target within the Framework as an FCP
* controller.
*/
/* ARGSUSED */
int
{
int result;
S1394_TNF_SL_FCP_STACK, "");
S1394_TNF_SL_FCP_STACK, "");
return (result);
}
/*
* Function: t1394_fcp_unregister_controller()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
*
* Output(s): DDI_SUCCESS Successfully unregistered.
*
* DDI_FAILURE Not unregistered due to failure.
*
* Description: Used to unregister the target within the Framework as an FCP
* controller.
*/
int
{
int result;
S1394_TNF_SL_FCP_STACK, "");
S1394_TNF_SL_FCP_STACK, "");
return (result);
}
/*
* Function: t1394_fcp_register_target()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* evts The structure in which the target
* specifies its callback routines
*
* flags The flags parameter is unused (for now)
*
* Output(s): DDI_SUCCESS Successfully registered.
*
* DDI_FAILURE Not registered due to failure.
*
* Description: Used to register the target within the Framework as an FCP
* target.
*/
/* ARGSUSED */
int
{
int result;
S1394_TNF_SL_FCP_STACK, "");
S1394_TNF_SL_FCP_STACK, "");
return (result);
}
/*
* Function: t1394_fcp_unregister_target()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
*
* Output(s): DDI_SUCCESS Successfully unregistered.
*
* DDI_FAILURE Not unregistered due to failure.
*
* Description: Used to unregister the target within the Framework as an FCP
* target.
*/
int
{
int result;
S1394_TNF_SL_FCP_STACK, "");
S1394_TNF_SL_FCP_STACK, "");
return (result);
}
/*
* Function: t1394_cmp_register()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* evts The structure in which the target
* specifies its callback routines
*
* Output(s): DDI_SUCCESS Successfully registered.
*
* DDI_FAILURE Not registered due to failure.
*
* Description: Used to register the target within the Framework as a CMP
* device.
*/
/* ARGSUSED */
int
{
int result;
return (result);
}
/*
* Function: t1394_cmp_unregister()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* evts The structure in which the target
* specifies its callback routines
*
* Output(s): DDI_SUCCESS Successfully registered.
*
* DDI_FAILURE Not registered due to failure.
*
* Description: Used to unregister the target within the Framework as a CMP
* device.
*/
int
{
int result;
"");
"");
return (result);
}
/*
* Function: t1394_cmp_read()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* reg Register type.
* valp Returned register value.
*
* Output(s): DDI_SUCCESS Successfully registered.
*
* DDI_FAILURE Not registered due to failure.
*
* Description: Used to read a CMP register value.
*/
int
{
int result;
return (result);
}
/*
* Function: t1394_cmp_cas()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* reg Register type.
* arg_val Compare argument.
* new_val New register value.
* old_valp Returned original register value.
*
* Output(s): DDI_SUCCESS Successfully registered.
*
* DDI_FAILURE Not registered due to failure.
*
* Description: Used to compare-swap a CMP register value.
*/
int
{
int result;
return (result);
}
/*
* Function: t1394_alloc_isoch_single()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* sii The structure used to set up the
* overall characteristics of the
* isochronous stream
* flags The flags parameter is unused (for now)
*
* Output(s): setup_args Contains the channel number that was
* allocated
* t1394_single_hdl This in the isoch "handle" used in
* t1394_free_isoch_single()
* result Used to pass more specific info back
* to target
*
* Description: t1394_alloc_isoch_single() is used to direct the 1394 Software
* Framework to allocate an isochronous channel and bandwidth
* from the Isochronous Resource Manager (IRM). If a bus reset
* occurs, the 1394 Software Framework attempts to reallocate the
* same resources, calling the rsrc_fail_target() callback if
* it is unsuccessful.
*/
/* ARGSUSED */
int
{
int ret;
int err;
S1394_TNF_SL_ISOCH_STACK, "");
/* Check for invalid channel_mask */
if (sii->si_channel_mask == 0) {
"Invalid channel mask");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Check for invalid bandwidth */
"Invalid bandwidth requirements");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Verify that rsrc_fail_target() callback is non-NULL */
"Invalid callback specified");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/*
* Allocate an Isoch CEC of type S1394_SINGLE
*/
/* Allocate the Isoch CEC structure */
/* Initialize the structure type */
/* Create the mutex and "in_callbacks" cv */
/* Initialize the Isoch CEC's member list */
/* Initialize the filters */
/* Insert Isoch CEC into the HAL's list */
/*
* Join the newly created Isoch CEC
*/
/* All events are NULL except rsrc_fail_target() */
if (ret != DDI_SUCCESS) {
"Unexpected error from t1394_join_isoch_cec()");
if (ret != DDI_SUCCESS) {
/* Unable to free the Isoch CEC */
"Unexpected error from t1394_free_isoch_cec()");
ASSERT(0);
}
/* Handle is nulled out before returning */
*t1394_single_hdl = NULL;
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/*
* Setup the isoch resources, etc.
*/
if (ret != DDI_SUCCESS) {
"Unexpected error from t1394_setup_isoch_cec()");
/* Leave the Isoch CEC */
if (ret != DDI_SUCCESS) {
/* Unable to leave the Isoch CEC */
"Unexpected error from t1394_leave_isoch_cec()");
ASSERT(0);
}
/* Free up the Isoch CEC */
if (ret != DDI_SUCCESS) {
/* Unable to free the Isoch CEC */
"Unexpected error from t1394_free_isoch_cec()");
ASSERT(0);
}
/* Handle is nulled out before returning */
*t1394_single_hdl = NULL;
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Return the setup_args - channel num and speed */
/* Update the handle */
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_SUCCESS);
}
/*
* Function: t1394_free_isoch_single()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* t1394_single_hdl The isoch "handle" return by
* t1394_alloc_isoch_single()
* flags The flags parameter is unused (for now)
*
* Output(s): None
*
* Description: t1394_free_isoch_single() frees the isochronous resources
* and the handle that were allocated during the call to
* t1394_alloc_isoch_single().
*/
/* ARGSUSED */
void
{
int ret;
S1394_TNF_SL_ISOCH_STACK, "");
/* Convert the handle to an Isoch CEC pointer */
/*
* Teardown the isoch resources, etc.
*/
if (ret != DDI_SUCCESS) {
/* Unable to teardown the Isoch CEC */
"Unexpected error from t1394_teardown_isoch_cec()");
ASSERT(0);
}
/*
* Leave the Isoch CEC
*/
if (ret != DDI_SUCCESS) {
/* Unable to leave the Isoch CEC */
"Unexpected error from t1394_leave_isoch_cec()");
ASSERT(0);
}
/*
* Free the Isoch CEC
*/
if (ret != DDI_SUCCESS) {
/* Unable to free the Isoch CEC */
"Unexpected error from t1394_free_isoch_cec()");
ASSERT(0);
}
/* Handle is nulled out before returning */
*t1394_single_hdl = NULL;
S1394_TNF_SL_ISOCH_STACK, "");
}
/*
* Function: t1394_alloc_isoch_cec()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* props The structure used to set up the
* overall characteristics of for
* the Isoch CEC.
* flags The flags parameter is unused (for now)
*
* Output(s): t1394_isoch_cec_hdl The Isoch CEC "handle" used in all
* subsequent isoch_cec() calls
*
* Description: t1394_alloc_isoch_cec() allocates and initializes an
* isochronous channel event coordinator (Isoch CEC) for use
* in managing and coordinating activity for an isoch channel
*/
/* ARGSUSED */
int
{
S1394_TNF_SL_ISOCH_STACK, "");
/* Check for invalid channel_mask */
if (props->cec_channel_mask == 0) {
"Invalid channel mask");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Test conditions specific to T1394_NO_IRM_ALLOC */
/* If T1394_NO_IRM_ALLOC, then only one bit should be set */
"Invalid channel mask");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* If T1394_NO_IRM_ALLOC, then speeds should be equal */
"Invalid speeds (min != max)");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
}
/* Check for invalid bandwidth */
"Invalid bandwidth requirements");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Allocate the Isoch CEC structure */
/* Initialize the structure type */
/* Create the mutex and "in_callbacks" cv */
/* Initialize the Isoch CEC's member list */
/* Initialize the filters */
/* Insert Isoch CEC into the HAL's list */
/* Update the handle and return */
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_SUCCESS);
}
/*
* Function: t1394_free_isoch_cec()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* flags The flags parameter is unused (for now)
* t1394_isoch_cec_hdl The Isoch CEC "handle" returned by
* t1394_alloc_isoch_cec()
*
* Output(s): DDI_SUCCESS Target successfully freed the Isoch CEC
* DDI_FAILURE Target failed to free the Isoch CEC
*
* Description: t1394_free_isoch_cec() attempts to free the Isoch CEC
* structure. It will fail (DDI_FAILURE) if there are any
* remaining members who have not yet left.
*/
/* ARGSUSED */
int
{
S1394_TNF_SL_ISOCH_STACK, "");
/* Convert the handle to an Isoch CEC pointer */
/* Lock the Isoch CEC member list */
/* Are we in any callbacks? */
if (CEC_IN_ANY_CALLBACKS(cec_curr)) {
/* Unlock the Isoch CEC member list */
"Not allowed to free Isoch CEC (in callbacks)");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Is "free" a legal state transition? */
/* Unlock the Isoch CEC member list */
"Not allowed to free Isoch CEC");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Remove Isoch CEC from HAL's list */
/* Destroy the Isoch CEC's mutex and cv */
/* Free up the memory for the Isoch CEC struct */
/* Update the handle and return */
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_SUCCESS);
}
/*
* Function: t1394_join_isoch_cec()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* t1394_isoch_cec_hdl The Isoch CEC "handle" returned by
* t1394_alloc_isoch_cec()
* flags The flags parameter is unused (for now)
* join_isoch_info This structure provides infomation
* about a target that wishes to join
* the given Isoch CEC. It gives
* max_speed, channel_mask, etc.
*
* Output(s): DDI_SUCCESS Target successfully joined the
* Isoch CEC
* DDI_FAILURE Target failed to join the Isoch CEC
*
* Description: t1394_join_isoch_cec() determines, based on the information
* given in the join_isoch_info structure, if the target may
* join the Isoch CEC. If it is determined that the target may
* join, the specified callback routines are stored away for
* later use in the coordination tasks.
*/
/* ARGSUSED */
int
{
S1394_TNF_SL_ISOCH_STACK, "");
/* Convert the handle to an Isoch CEC pointer */
/* Allocate a new Isoch CEC member structure */
/* Lock the Isoch CEC member list */
/* Are we in any callbacks? (Wait for them to finish) */
while (CEC_IN_ANY_CALLBACKS(cec_curr)) {
}
/* Is "join" a legal state transition? */
/* Unlock the Isoch CEC member list */
"Not allowed to join Isoch CEC");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Check the channel mask for consistency */
if (check_mask == 0) {
/* Unlock the Isoch CEC member list */
"Inconsistent channel mask specified");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Check for consistent speeds */
/* Unlock the Isoch CEC member list */
"Inconsistent speed specified");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
} else if (join_isoch_info->req_max_speed <
} else {
}
/* Check for no more than one talker */
/* Unlock the Isoch CEC member list */
"Multiple talkers specified");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Verify that all callbacks are non-NULL (for PEER_TO_PEER) */
/* Unlock the Isoch CEC member list */
"Invalid callbacks specified");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Copy the events information into the struct */
/* Insert new member into Isoch CEC's member list */
/* Update the channel mask filter */
/* Update the speed filter */
/* Update the talker pointer (if necessary) */
/*
* Now "leave" is a legal state transition
* and "free" is an illegal state transition
*/
/* Unlock the Isoch CEC member list */
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_SUCCESS);
}
/*
* Function: t1394_leave_isoch_cec()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* t1394_isoch_cec_hdl The Isoch CEC "handle" returned by
* t1394_alloc_isoch_cec()
* flags The flags parameter is unused (for now)
*
* Output(s): DDI_SUCCESS Target successfully left the
* Isoch CEC
* DDI_FAILURE Target failed to leave the Isoch CEC
*
* Description: t1394_leave_isoch_cec() is used by a target driver to remove
* itself from the Isoch CEC's member list. It is possible
* for this call to fail because the target is not found in
* the current member list, or because it is not an appropriate
* time for a target to leave.
*/
/* ARGSUSED */
int
{
S1394_TNF_SL_ISOCH_STACK, "");
/* Convert the handle to an Isoch CEC pointer */
/* Lock the Isoch CEC member list */
/* Are we in any callbacks? (Wait for them to finish) */
while (CEC_IN_ANY_CALLBACKS(cec_curr)) {
}
/* Is "leave" a legal state transition? */
/* Unlock the Isoch CEC member list */
"Not allowed to leave Isoch CEC");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Find the Target on the CEC's member list */
while (member_curr != NULL) {
if (member_curr->cec_mem_target ==
(s1394_target_t *)t1394_hdl) {
} else {
/* Keep track of channel mask and max speed info */
}
}
/* Target not found on this Isoch CEC */
/* Unlock the Isoch CEC member list */
"Target not found in Isoch CEC member list");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
} else {
/* This member's departure may change filter constraints */
}
/* Remove member from Isoch CEC's member list */
/* If we are removing the talker, then update the pointer */
/* Is the Isoch CEC's member list empty? */
/*
* Now "free" _might_ be a legal state transition
* if we aren't in setup or start phases and "leave"
* is definitely an illegal state transition
*/
}
/* Unlock the Isoch CEC member list */
/* Free the Isoch CEC member structure */
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_SUCCESS);
}
/*
* Function: t1394_setup_isoch_cec()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* t1394_isoch_cec_hdl The Isoch CEC "handle" returned by
* t1394_alloc_isoch_cec()
* flags The flags parameter is unused (for now)
*
* Output(s): result Used to pass more specific info back
* to target
*
* Description: t1394_setup_isoch_cec() directs the 1394 Software Framework
* to allocate isochronous resources and invoke the setup_target()
* callback for each member of the Isoch CEC. This call may
* fail because bandwidth was unavailable (T1394_ENO_BANDWIDTH),
* channels were unavailable (T1394_ENO_CHANNEL), or one of the
* member targets returned failure from its setup_target()
* callback.
*/
/* ARGSUSED */
int
{
int chnl_num;
int err;
int ret;
int j;
S1394_TNF_SL_ISOCH_STACK, "");
/* Convert the handle to an Isoch CEC pointer */
/* Lock the Isoch CEC member list */
/* Are we in any callbacks? */
if (CEC_IN_ANY_CALLBACKS(cec_curr)) {
/* Unlock the Isoch CEC member list */
"Not allowed to setup Isoch CEC (in callbacks)");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Is "setup" a legal state transition? */
/* Unlock the Isoch CEC member list */
"Not allowed to setup Isoch CEC");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* If T1394_NO_IRM_ALLOC is set then don't allocate... do callbacks */
goto setup_do_callbacks;
}
/* Allocate bandwidth and channels */
for (j = 0; j < S1394_ISOCH_ALLOC_RETRIES; j++) {
/*
* Get the current generation number - don't
* need the lock because we are read only here
*/
/* Compute how much bandwidth is needed */
/* Check that the generation has not changed - */
/* don't need the lock (read only) */
continue;
/* Unlock the Isoch CEC member list */
/* Try to allocate the bandwidth */
&err);
/* Lock the Isoch CEC member list */
/* If there was a bus reset, start over */
if (ret == DDI_FAILURE) {
if (err == CMD1394_EBUSRESET) {
continue; /* start over and try again */
} else {
/* Unlock the Isoch CEC member list */
msg, "Unable to allocate isoch bandwidth");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
}
/* Check that the generation has not changed - */
/* don't need the lock (read only) */
continue;
/*
* Allocate a channel
* From IEEE 1394-1995, Section 8.3.2.3.8: "Bits
* allocated in the CHANNELS_AVAILABLE_HI field of
* this register shall start at bit zero (channel
* number zero), and additional channel numbers shall
* be represented in a monotonically increasing sequence
* of bit numbers up to a maximum of bit 31 (channel
* number 31). Bits allocated in the CHANNELS_AVAILABLE_LO
* field of this register shall start at bit zero
* (channel number 32), and additional channel numbers
* shall be represented in a monotonically increasing
* sequence of bit numbers up to a maximum of bit 31
* (channel number 63).
*/
/* Unlock the Isoch CEC member list */
if (chnl_num < 32) {
&err);
} else {
&err);
}
/* Lock the Isoch CEC member list */
/* Did we get a channel? (or a bus reset) */
if ((ret == DDI_SUCCESS) ||
(err == CMD1394_EBUSRESET))
break;
}
}
/* If we've tried all the possible channels, then fail */
if (chnl_num == 0) {
/*
* If we successfully allocate bandwidth, and
* then fail getting a channel, we need to
* free up the bandwidth
*/
/* Check that the generation has not changed */
/* lock not needed here (read only) */
continue;
/* Unlock the Isoch CEC member list */
/* Try to free up the bandwidth */
generation, &err);
/* Lock the Isoch CEC member list */
if (ret == DDI_FAILURE) {
if (err == CMD1394_EBUSRESET) {
continue;
} else {
"Unable to free isoch bandwidth");
}
}
/* Unlock the Isoch CEC member list */
"Unable to allocate isoch channel");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* If we got a channel, we're done (else start over) */
if (ret == DDI_SUCCESS)
break;
else if (err == CMD1394_EBUSRESET)
continue;
}
/* Have we gotten too many bus resets? */
if (j == S1394_ISOCH_ALLOC_RETRIES) {
/* Unlock the Isoch CEC member list */
"Unable to allocate isoch channel");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Call all of the setup_target() callbacks */
/* Now we are going into the callbacks */
/* Unlock the Isoch CEC member list */
*result = 0;
while (member_curr != NULL) {
if (ret != DDI_SUCCESS)
*result = T1394_ETARGET;
}
}
/* Lock the Isoch CEC member list */
/* We are finished with the callbacks */
}
/*
* Now "start" and "teardown" are legal state transitions
* and "join", "free", and "setup" are illegal state transitions
*/
/* Unlock the Isoch CEC member list */
/* Return DDI_FAILURE if any targets failed setup */
if (*result != 0) {
"Target returned error in setup_target()");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_SUCCESS);
}
/*
* Function: t1394_start_isoch_cec()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* t1394_isoch_cec_hdl The Isoch CEC "handle" returned by
* t1394_alloc_isoch_cec()
* flags The flags parameter is unused (for now)
*
* Output(s): DDI_SUCCESS All start_target() callbacks returned
* successfully
* DDI_FAILURE One or more start_target() callbacks
* returned failure
*
* Description: t1394_start_isoch_cec() directs the 1394 Software Framework
* to invoke each of the start_target() callbacks, first for
* each listener, then for the talker.
*/
/* ARGSUSED */
int
{
int ret;
S1394_TNF_SL_ISOCH_STACK, "");
/* Convert the handle to an Isoch CEC pointer */
/* Lock the Isoch CEC member list */
/* Are we in any callbacks? */
if (CEC_IN_ANY_CALLBACKS(cec_curr)) {
/* Unlock the Isoch CEC member list */
"Not allowed to start Isoch CEC (in callbacks)");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Is "start" a legal state transition? */
/* Unlock the Isoch CEC member list */
"Not allowed to start Isoch CEC");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Now we are going into the callbacks */
/* Unlock the Isoch CEC member list */
/*
* Call all of the start_target() callbacks
* Start at the tail (listeners first) and
* go toward the head (talker last)
*/
while (member_curr != NULL) {
if (ret != DDI_SUCCESS)
}
}
/* Lock the Isoch CEC member list */
/* We are finished with the callbacks */
}
/*
* Now "stop" is a legal state transitions
* and "start" and "teardown" are illegal state transitions
*/
/* Unlock the Isoch CEC member list */
/* Return DDI_FAILURE if any targets failed start */
"Target returned error in start_target()");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_SUCCESS);
}
/*
* Function: t1394_stop_isoch_cec()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* t1394_isoch_cec_hdl The Isoch CEC "handle" returned by
* t1394_alloc_isoch_cec()
* flags The flags parameter is unused (for now)
*
* Output(s): DDI_SUCCESS Target successfully stopped the
* Isoch CEC
* DDI_FAILURE Target failed to stop the Isoch CEC
*
* Description: t1394_stop_isoch_cec() directs the 1394 Software Framework
* to invoke each of the stop_target() callbacks, first for
* the talker, then for each listener.
* (This call will fail if it is called at an
* inappropriate time, i.e. before the t1394_start_isoch_cec()
* call, etc.)
*/
/* ARGSUSED */
int
{
S1394_TNF_SL_ISOCH_STACK, "");
/* Convert the handle to an Isoch CEC pointer */
/* Lock the Isoch CEC member list */
/* Are we in any callbacks? */
if (CEC_IN_ANY_CALLBACKS(cec_curr)) {
/* Unlock the Isoch CEC member list */
"Not allowed to stop Isoch CEC (in callbacks)");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Is "stop" a legal state transition? */
/* Unlock the Isoch CEC member list */
"Not allowed to stop Isoch CEC");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Now we are going into the callbacks */
/* Unlock the Isoch CEC member list */
/*
* Call all of the stop_target() callbacks
* Start at the head (talker first) and
* go toward the tail (listeners last)
*/
while (member_curr != NULL) {
}
}
/* Lock the Isoch CEC member list */
/* We are finished with the callbacks */
}
/*
* Now "start" and "teardown" are legal state transitions
* and "stop" is an illegal state transitions
*/
/* Unlock the Isoch CEC member list */
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_SUCCESS);
}
/*
* Function: t1394_teardown_isoch_cec()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* t1394_isoch_cec_hdl The Isoch CEC "handle" returned by
* t1394_alloc_isoch_cec()
* flags The flags parameter is unused (for now)
*
* Output(s): DDI_SUCCESS Target successfully tore down the
* Isoch CEC
* DDI_FAILURE Target failed to tear down the
* Isoch CEC
*
* Description: t1394_teardown_isoch_cec() directs the 1394 Software Framework
* to free up any isochronous resources we might be holding and
* call all of the teardown_target() callbacks.
* (This call will fail if it is called at an
* inappropriate time, i.e. before the t1394_start_isoch_cec()
* call, before the t1394_stop_isoch_cec, etc.
*/
/* ARGSUSED */
int
{
int ret;
int err;
S1394_TNF_SL_ISOCH_STACK, "");
/* Convert the handle to an Isoch CEC pointer */
/* Lock the Isoch CEC member list */
/* Are we in any callbacks? */
if (CEC_IN_ANY_CALLBACKS(cec_curr)) {
/* Unlock the Isoch CEC member list */
"Not allowed to teardown Isoch CEC (in callbacks)");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Is "teardown" a legal state transition? */
/* Unlock the Isoch CEC member list */
"Not allowed to teardown Isoch CEC");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* If T1394_NO_IRM_ALLOC is set then don't free... do callbacks */
goto teardown_do_callbacks;
}
/* If nothing has been allocated or we failed to */
/* reallocate, then we are done... call the callbacks */
goto teardown_do_callbacks;
}
/*
* Get the current generation number - don't need the
* topology tree mutex here because it is read-only, and
* there is a race condition with or without it.
*/
/* Compute the amount bandwidth to free */
/* Check that the generation has not changed - */
/* don't need the lock (read only) */
goto teardown_do_callbacks;
/* Unlock the Isoch CEC member list */
/* Try to free up the bandwidth */
/* Lock the Isoch CEC member list */
if (ret == DDI_FAILURE) {
if (err == CMD1394_EBUSRESET) {
goto teardown_do_callbacks;
} else {
"Unable to free allocated bandwidth");
}
}
/* Free the allocated channel */
/* Unlock the Isoch CEC member list */
} else {
}
/* Lock the Isoch CEC member list */
if (ret == DDI_FAILURE) {
if (err == CMD1394_EBUSRESET) {
goto teardown_do_callbacks;
} else {
"Unable to free allocated bandwidth");
}
}
/* From here on reallocation is unnecessary */
cec_curr->realloc_chnl_num = 0;
cec_curr->realloc_bandwidth = 0;
/* Now we are going into the callbacks */
/* Unlock the Isoch CEC member list */
/* Call all of the teardown_target() callbacks */
while (member_curr != NULL) {
}
}
/* Lock the Isoch CEC member list */
/* We are finished with the callbacks */
}
/*
* Now "join" and "setup" are legal state transitions
* and "start" and "teardown" are illegal state transitions
*/
/* And if the member list is empty, then "free" is legal too */
}
/* Unlock the Isoch CEC member list */
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_SUCCESS);
}
/*
* Function: t1394_alloc_isoch_dma()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* idi This structure contains information
* for configuring the data flow for
* isochronous DMA
* flags The flags parameter is unused (for now)
*
* Output(s): t1394_idma_hdl The IDMA "handle" used in all
* subsequent isoch_dma() calls
* result Used to pass more specific info back
* to target
*
* Description: t1394_alloc_isoch_dma() allocates and initializes an
* isochronous DMA resource for transmitting or receiving
* isochronous data. If it fails, result may hold
* T1394_EIDMA_NO_RESRCS, indicating that no isoch DMA resource
* are available.
*/
/* ARGSUSED */
int
{
int ret;
S1394_TNF_SL_ISOCH_STACK, "");
/* Find the HAL this target resides on */
/* Sanity check dma options. If talk enabled, listen should be off */
"conflicting idma options; talker and listener");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Only one listen mode allowed */
"conflicting idma options; both listener modes set");
S1394_TNF_SL_ISOCH_STACK, "");
return (DDI_FAILURE);
}
/* Have HAL alloc a resource and compile ixl */
(void **)t1394_idma_hdl, result);
if (ret != DDI_SUCCESS) {
"HAL alloc_isoch_dma error, maybe IXL compilation");
if (*result == IXL1394_ENO_DMA_RESRCS) {
}
}
S1394_TNF_SL_ISOCH_STACK, "");
return (ret);
}
/*
* Function: t1394_free_isoch_dma()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* flags The flags parameter is unused (for now)
* t1394_idma_hdl The IDMA "handle" returned by
* t1394_alloc_isoch_dma()
*
* Output(s): None
*
* Description: t1394_free_isoch_dma() is used to free all DMA resources
* allocated for the isoch stream associated with t1394_idma_hdl.
*/
/* ARGSUSED */
void
{
S1394_TNF_SL_ISOCH_STACK, "");
/* Find the HAL this target resides on */
/* Tell HAL to release local isoch dma resources */
/* Null out isoch handle */
*t1394_idma_hdl = NULL;
S1394_TNF_SL_ISOCH_STACK, "");
}
/*
* Function: t1394_start_isoch_dma()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* t1394_idma_hdl The IDMA "handle" returned by
* t1394_alloc_isoch_dma()
* idma_ctrlinfo This structure contains control args
* used when starting isoch DMA for
* the allocated resource
* flags One flag defined - ID1394_START_ON_CYCLE
*
* Output(s): result Used to pass more specific info back
* to target
*
* Description: t1394_start_isoch_dma() is used to start DMA for the isoch
* stream associated with t1394_idma_hdl.
*/
/* ARGSUSED */
int
int *result)
{
int ret;
S1394_TNF_SL_ISOCH_STACK, "");
/* Find the HAL this target resides on */
S1394_TNF_SL_ISOCH_STACK, "");
return (ret);
}
/*
* Function: t1394_stop_isoch_dma()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* t1394_idma_hdl The IDMA "handle" returned by
* t1394_alloc_isoch_dma()
* flags The flags parameter is unused (for now)
*
* Output(s): None
*
* Description: t1394_stop_isoch_dma() is used to stop DMA for the isoch
* stream associated with t1394_idma_hdl.
*/
/* ARGSUSED */
void
{
int result;
S1394_TNF_SL_ISOCH_STACK, "");
/* Find the HAL this target resides on */
(void *)t1394_idma_hdl, &result);
S1394_TNF_SL_ISOCH_STACK, "");
}
/*
* Function: t1394_update_isoch_dma()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* t1394_idma_hdl The IDMA "handle" returned by
* t1394_alloc_isoch_dma()
* idma_updateinfo This structure contains ixl command args
* used when updating args in an
* existing list of ixl commands with
* args in a new list of ixl commands.
* flags The flags parameter is unused (for now)
*
* Output(s): result Used to pass more specific info back
* to target
*
* Description: t1394_update_isoch_dma() is used to alter an IXL program that
* has already been built (compiled) by t1394_alloc_isoch_dma().
*/
/* ARGSUSED */
int
int *result)
{
int ret;
S1394_TNF_SL_ISOCH_STACK, "");
/* Find the HAL this target resides on */
S1394_TNF_SL_ISOCH_STACK, "");
return (ret);
}
/*
* Function: t1394_initiate_bus_reset()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* flags The flags parameter is unused (for now)
*
* Output(s): None
*
* Description: t1394_initiate_bus_reset() determines whether the local
* device has a P1394A PHY and will support the arbitrated
* short bus reset. If not, it will initiate a normal bus reset.
*/
/* ARGSUSED */
void
{
int ret;
S1394_TNF_SL_BR_STACK, "");
/* Find the HAL this target resides on */
/* Reset the bus */
if (ret != DDI_SUCCESS) {
"Error initiating short bus reset");
}
} else {
if (ret != DDI_SUCCESS) {
"Error initiating bus reset");
}
}
S1394_TNF_SL_BR_STACK, "");
}
/*
* Function: t1394_get_topology_map()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* bus_generation The current generation
* tm_length The size of the tm_buffer given
* flags The flags parameter is unused (for now)
*
* Output(s): tm_buffer Filled in by the 1394 Software Framework
* with the contents of the local
* TOPOLOGY_MAP
*
* Description: t1394_get_topology_map() returns the 1394 TOPLOGY_MAP. See
* IEEE 1394-1995 Section 8.2.3.4.1 for format information. This
* call can fail if there is a generation mismatch or the
* tm_buffer is too small to hold the TOPOLOGY_MAP.
*/
/* ARGSUSED */
int
{
"");
/* Find the HAL this target resides on */
/* Lock the topology tree */
/* Check the bus_generation for the Topology Map */
/* Unlock the topology tree */
"Generation mismatch");
S1394_TNF_SL_CSR_STACK, "");
return (DDI_FAILURE);
}
/* Check that the buffer is big enough */
/* Unlock the topology tree */
"Buffer size too small");
S1394_TNF_SL_CSR_STACK, "");
return (DDI_FAILURE);
}
/* Do the copy */
/* Unlock the topology tree */
"");
return (DDI_SUCCESS);
}
/*
* Function: t1394_CRC16()
* Input(s): d The data to compute the CRC-16 for
* crc_length The length into the data to compute for
* flags The flags parameter is unused (for now)
*
* Output(s): CRC The CRC-16 computed for the length
* of data specified
*
* 1212, 1994 - 8.1.5.
*/
/* ARGSUSED */
{
return (ret);
}
/*
* Function: t1394_add_cfgrom_entry()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* cfgrom_entryinfo This structure holds the cfgrom key,
* buffer, and size
* flags The flags parameter is unused (for now)
*
* Output(s): t1394_cfgrom_hdl The ConfigROM "handle" used in
* t1394_rem_cfgrom_entry()
* result Used to pass more specific info back
* to target
*
* Description: t1394_add_cfgrom_entry() adds an entry to the local Config ROM,
* updating the directory entries as necessary. This call could
* fail because there is no room for the new entry in Config ROM
* (T1394_ECFGROM_FULL), the key is invalid (T1394_EINVALID_PARAM),
* or it was called in interrupt context (T1394_EINVALID_CONTEXT).
*/
/* ARGSUSED */
int
{
int ret;
/* Check for a valid size */
if (size == 0) {
"Invalid size of Config ROM buffer (== 0)");
return (DDI_FAILURE);
}
/* Check for a valid key type */
"Invalid key_type in Config ROM key");
return (DDI_FAILURE);
}
/* Find the HAL this target resides on */
/* Is this on the interrupt stack? */
return (DDI_FAILURE);
}
/* Lock the Config ROM buffer */
(void **)t1394_cfgrom_hdl, result);
if (ret != DDI_SUCCESS) {
if (*result == CMD1394_ERSRC_CONFLICT)
"Failed in s1394_add_cfgrom_entry()");
"stacktrace 1394 s1394", "");
return (ret);
}
/* Setup the timeout function */
} else {
}
return (ret);
}
/*
* Function: t1394_rem_cfgrom_entry()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* flags The flags parameter is unused (for now)
* t1394_cfgrom_hdl The ConfigROM "handle" returned by
* t1394_add_cfgrom_entry()
*
* Output(s): result Used to pass more specific info back
* to target
*
* Description: t1394_rem_cfgrom_entry() is used to remove a previously added
* Config ROM entry (indicated by t1394_cfgrom_hdl).
*/
/* ARGSUSED */
int
{
int ret;
/* Find the HAL this target resides on */
/* Is this on the interrupt stack? */
return (DDI_FAILURE);
}
/* Lock the Config ROM buffer */
result);
if (ret != DDI_SUCCESS) {
"Failed in s1394_remove_cfgrom_entry()");
"stacktrace 1394 s1394", "");
return (ret);
}
/* Setup the timeout function */
} else {
}
return (ret);
}
/*
* Function: t1394_get_targetinfo()
* Input(s): t1394_hdl The target "handle" returned by
* t1394_attach()
* bus_generation The current generation
* flags The flags parameter is unused (for now)
*
* Output(s): targetinfo Structure containing max_payload,
* max_speed, and target node ID.
*
* Description: t1394_get_targetinfo() is used to retrieve information specific
* to a target device. It will fail if the generation given
* does not match the current generation.
*/
/* ARGSUSED */
int
{
/* Find the HAL this target resides on */
/* Lock the topology tree */
/* Check the bus_generation */
/* Unlock the topology tree */
return (DDI_FAILURE);
}
/*
* If there is no node, report T1394_INVALID_NODEID for target_nodeID;
* current_max_speed and current_max_payload are undefined for this
* case.
*/
} else {
/* Get current_max_payload */
S1394_TNF_SL_STACK, "",
}
/* Unlock the topology tree */
return (DDI_SUCCESS);
}