/*
* 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 track the tlabel usage for a 1394 adapter.
*/
/*
* hci1394_tlabel_init()
* Initialize the tlabel structures. These structures will be protected
* by a mutex at the iblock_cookie passed in. Bad tlabels will be usable
* when > reclaim_time_nS has gone by. init() returns a handle to be used
* for the rest of the tlabel functions.
*/
void
{
/* alloc space for tlabel data */
/* setup handle which is returned from this function */
*tlabel_handle = tstruct;
/*
* Initialize tlabel structure. We start with max node set to the
* maxiumum node we could have so that we make sure the arrays are
* initialized correctly in hci1394_tlabel_reset().
*/
/*
* The mutex must be initialized before tlabel_reset()
* is called. This is because tlabel_reset is also
* used in normal tlabel processing (i.e. not just during
* initialization)
*/
}
/*
* hci1394_tlabel_fini()
* Frees up the space allocated in init(). Notice that a pointer to the
* handle is used for the parameter. fini() will set your handle to NULL
* before returning.
*/
void
{
/* set handle to null. This helps catch bugs. */
*tlabel_handle = NULL;
}
/*
* hci1394_tlabel_alloc()
* alloc a tlabel based on the node id. If alloc fails, we are out of
* tlabels for that node. See comments before set_reclaim_time() on when
* bad tlabel's are free to be used again.
*/
int
{
HCI1394_TNF_HAL_STACK, "");
/* copy destination into tlabel_info */
/* figure out what node we are going to */
/*
* Keep track of if we have sent out a broadcast request and what the
* maximum # node we have sent to for reset processing optimization
*/
if (node_number == IEEE1394_BROADCAST_NODEID) {
}
/* setup copies so we don't take up so much space :-) */
/*
* If there are any bad tlabels, see if the last bad tlabel recorded for
* this nodeid is now good to use. If so, add all bad tlabels for that
* node id back into the free list
*
* NOTE: This assumes that bad tlabels are infrequent.
*/
if (bad != 0) {
/* add the bad tlabels back into the free list */
/* clear the bad list */
bad = 0;
}
}
/*
* Find a free tlabel. This will break out of the loop once it finds a
* tlabel. There are a total of TLABEL_RANGE tlabels. The alloc
* rotates the check so that we don't always use the same tlabel. It
* stores the last tlabel used in last.
*/
/* if the next tlabel to check is free */
/* we are using this tlabel */
/* take it out of the free list */
/*
* increment the last count so we start checking on the
* next tlabel next alloc(). Note the rollover at
* TLABEL_RANGE since we only have TLABEL_RANGE tlabels.
*/
(last)++;
if (last >= TLABEL_RANGE) {
last = 0;
}
/* Copy the copies back */
/* unlock the tlabel structure */
HCI1394_TNF_HAL_STACK, "");
return (DDI_SUCCESS);
}
/*
* This tlabel is not free, lets go to the next one. Note the
* rollover at TLABEL_RANGE since we only have TLABEL_RANGE
* tlabels.
*/
(last)++;
if (last >= TLABEL_RANGE) {
last = 0;
}
}
/* Copy the copies back */
return (DDI_FAILURE);
}
/*
* hci1394_tlabel_free()
* free the previously alloc()'d tlabel. Once a tlabel has been free'd, it
* can be used again when alloc() is called.
*/
void
{
/* figure out what node and tlabel we are using */
/*
* Put the tlabel back in the free list and NULL out the (void *) in the
* lookup structure. You wouldn't expect to have to null out the lookup
* structure, but we know first hand that bad HW will send invalid
* tlabels which could really mess things up if you didn't :-)
*/
}
/*
* hci1394_tlabel_register()
* Register an opaque command with an alloc()'d tlabel. Each nodeID has it's
* own tlabel list.
*/
void
{
HCI1394_TNF_HAL_STACK, "");
/* figure out what node and tlabel we are using */
/* enter the (void *) into the lookup table */
HCI1394_TNF_HAL_STACK, "");
}
/*
* hci1394_tlabel_lookup()
* returns (in cmd) the opaque command which was registered with the
* specified tlabel from alloc(). If a tlabel was not registered, cmd ='s
* NULL.
*/
void
{
HCI1394_TNF_HAL_STACK, "");
/* figure out what node and tlabel we are using */
/*
* fetch the (void *) from the lookup table. The case where the pointer
* equals NULL will be handled by the layer above.
*/
HCI1394_TNF_HAL_STACK, "");
}
/*
* hci1394_tlabel_bad()
* Register the specified tlabel as bad. tlabel_lookup() will no longer
* return a registered opaque command and this tlabel will not be returned
* from alloc() until > reclaim_time has passed. See set_reclaim_time() for
* more info.
*/
void
{
/* figure out what node and tlabel we are using */
/*
* Put the tlabel in the bad list and NULL out the (void *) in the
* lookup structure. We may see this tlabel shortly if the device is
* late in responding. We want to make sure to drop the message if we
* do. Set the bad timestamp to the current time plus the reclaim time.
* This is the "new" time when all of the bad tlabels for this node will
* be free'd.
*/
}
/*
* hci1394_tlabel_reset()
* resets the tlabel tracking structures to an initial state where no
* tlabels are outstanding and all tlabels are registered as good. This
* routine should be called every bus reset.
*/
void
{
int index;
int index2;
HCI1394_TNF_HAL_STACK, "");
/* Bus reset optimization. handle broadcast writes separately */
(uint64_t)0xFFFFFFFFFFFFFFFF;
(uint64_t)0;
(hrtime_t)0;
}
}
/*
* Mark all tlabels as free. No bad tlabels. Start the first tlabel
* alloc at 0. Cleanout the lookup table. An optimization to only do
* this up to the max node we have seen on the bus has been added.
*/
}
}
tlabel_handle->tb_max_node = 0;
}
/*
* hci1394_tlabel_set_reclaim_time()
* This function should be called if a change to the reclaim_time is
* required after the initial call to init(). It is not necessary to call
* this function if the reclaim time never changes.
*
* Currently, bad tlabels are reclaimed in tlabel_alloc().
* It looks like the following for a given node:
*
* if bad tlabels exist
* if ((current time + reclaim time) >= last bad tlabel time)
* free all bad tlabels.
*/
void
{
HCI1394_TNF_HAL_STACK, "");
/*
* We do not need to lock the tlabel structure in this because we are
* doing a single write to reclaim_time. If this changes in the future,
* we may need to add calls to lock() and unlock().
*/
HCI1394_TNF_HAL_STACK, "");
}