/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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
*/
/*
*/
#include <sys/byteorder.h>
#include <sys/mac_client.h>
/*
* leadville header files
*/
/*
* fcoe header files
*/
/*
* fcoei header files
*/
#include <fcoei.h>
/*
* forward declaration of stack functions
*/
static uint32_t fcoei_xch_check(
static int fcoei_ioctl(
static void fcoei_watchdog(void *arg);
static void fcoei_trigger_fp_attach(void *arg);
/*
* Driver identificaton stuff
*/
0,
};
0,
NULL,
};
};
&modldrv,
};
/*
* Driver's global variables
*/
int fcoei_use_ext_log = 0;
/*
* Common loadable module entry points _init, _fini, _info
*/
int
_init(void)
{
int ret;
if (ret != DDI_SUCCESS) {
return (ret);
}
if (ret != 0) {
return (ret);
}
/*
* Let FCTL initialize devo_bus_ops
*/
return (ret);
}
int
_fini(void)
{
int ret;
if (ret != 0) {
return (ret);
}
return (ret);
}
int
{
}
/*
* Autoconfiguration entry points: attach, detach, getinfo
*/
static int
{
int ret;
int fcoe_ret;
int instance;
switch (cmd) {
case DDI_ATTACH:
if (ret != DDI_SUCCESS) {
return (ret);
}
/*
* Get the soft state, and do basic initialization with dip
*/
if (fcoe_ret != FCOE_SUCCESS) {
"%x", fcoe_ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
case DDI_RESUME:
return (DDI_SUCCESS);
default:
return (DDI_FAILURE);
}
}
static int
{
int fcoe_ret;
int instance;
return (DDI_FAILURE);
}
switch (cmd) {
case DDI_DETACH:
return (DDI_FAILURE);
}
return (DDI_FAILURE);
}
if (fcoe_ret != FCOE_SUCCESS) {
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
case DDI_SUSPEND:
return (DDI_SUCCESS);
default:
return (DDI_FAILURE);
}
}
/*
* Device access entry points: open, close, ioctl
*/
static int
{
return (EINVAL);
}
return (EPERM);
}
/*
* First of all, get related soft state
*/
return (ENXIO);
}
/*
* We don't support concurrent open
*/
return (EBUSY);
}
return (0);
}
static int
{
return (EINVAL);
}
/*
* First of all, get related soft state
*/
return (ENXIO);
}
/*
* If it's not open, we can exit
*/
return (ENODEV);
}
return (0);
}
static int
{
int ret = 0;
return (EPERM);
}
/*
* Get related soft state
*/
if (!ss) {
return (ENXIO);
}
/*
* Process ioctl
*/
switch (cmd) {
default:
}
/*
* Set return value
*/
return (ret);
}
/*
* fcoei_attach_init
* init related stuff of the soft state
*
* Input:
* ss = the soft state that will be processed
*
* Return:
* if it succeeded or not
*
* Comment:
* N/A
*/
static int
{
int ret;
/*
* Register fcoei to FCOE as its client
*/
if (ret == -1) {
return (DDI_FAILURE);
} else {
}
/*
* It's fcoe's responsiblity to initialize eport's all elements,
* so we needn't do eport initialization
*/
goto fail_register_client;
} else {
}
/*
* Now it's time to register fca_tran to FCTL
* Remember fc_local_port is transparent to FCA (fcoei)
*/
/*
* scsi_tran_hba_setup could need these stuff
*/
/*
* Initialize vectors
*/
/*
* fc_fca_attach only sets driver's private, it has nothing to with
* common port object between fcoei and leadville.
* After this attach, fp_attach will be triggered, and it will call
* fca_bind_port to let fcoei to know about common port object.
*/
goto fail_fca_attach;
}
/*
* It's time to do ss initialization
*/
if (ret != DDI_SUCCESS) {
goto fail_minor_node;
}
/*
* ss->ss_eport has been initialized
*/
"fcoei_sol_oxid_hash", FCOEI_SOL_HASH_SIZE,
"fcoei_unsol_rxid_hash", FCOEI_UNSOL_HASH_SIZE,
taskq_name[31] = 0;
ss->ss_link_speed = 0;
ss->ss_port_event_counter = 0;
ss->ss_sol_cnt1 = 0;
ss->ss_sol_cnt2 = 0;
ss->ss_unsol_cnt1 = 0;
ss->ss_unsol_cnt2 = 0;
ss->ss_ioctl_flags = 0;
/*
* Fill out RNID Management Information
*/
/*
* Start our watchdog
*/
delay(50);
}
/*
* Report the device to the system
*/
return (DDI_SUCCESS);
return (DDI_FAILURE);
}
/*
* fcoei_detach_uninit
* uninit related stuff of the soft state
*
* Input:
* ss = the soft state that will be processed
*
* Return:
* if it succeeded or not
*
* Comment:
* N/A
*/
int
{
/*
* Stop watchdog first
*/
}
/*
* Destroy the taskq
*/
/*
* Release all allocated resources
*/
/*
* Release itself
*/
return (FCOE_SUCCESS);
}
/*
* fcoei_watchdog
* Perform periodic checking and routine tasks
*
* Input:
* arg = the soft state that will be processed
*
* Return:
* N/A
*
* Comment:
* N/A
*/
static void
{
/*
* For debugging
*/
/*
* If nobody reqeusts to terminate the watchdog, we will work forever
*/
/*
* We handle all asynchronous events serially
*/
/*
* To avoid to check timing too freqently, we check
* if we need skip timing stuff.
*/
goto end_timing;
} else {
}
/*
* It's time to do timeout checking of solicited exchanges
*/
if (ss->ss_sol_cnt2 == 0) {
} else {
}
} else {
if (ss->ss_sol_cnt1 == 0) {
} else {
}
}
/*
* It's time to do timeout checking of unsolicited exchange
*/
if (ss->ss_unsol_cnt2 == 0) {
} else {
}
} else {
if (ss->ss_unsol_cnt1 == 0) {
} else {
}
}
/*
* Check if there are exchanges which are ready to complete
*/
/*
* Wait for next cycle
*/
goto skip_wait;
}
}
/*
* Do clear work before exit
*/
/*
* Watchdog has stopped
*/
}
static void
{
case AE_EVENT_SOL_FRAME:
break;
case AE_EVENT_UNSOL_FRAME:
break;
case AE_EVENT_PORT:
/* FALLTHROUGH */
case AE_EVENT_RESET:
break;
case AE_EVENT_EXCHANGE:
/* FALLTHROUGH */
default:
break;
}
}
}
}
/*
* fcoei_process_events
* Process the events one by one
*
* Input:
* ss = the soft state that will be processed
*
* Return:
* N/A
*
* Comment:
* N/A
*/
static void
{
/*
* It's the only place to delete node from ss_event_list, so we needn't
* hold mutex to check if the list is empty.
*/
case AE_EVENT_SOL_FRAME:
break;
case AE_EVENT_UNSOL_FRAME:
break;
case AE_EVENT_EXCHANGE:
break;
case AE_EVENT_PORT:
break;
case AE_EVENT_RESET:
break;
default:
}
}
}
/*
* fcoei_handle_tmout_xch_list
* Complete every exchange in the timed-out xch list of the soft state
*
* Input:
* ss = the soft state that need be handled
*
* Return:
* N/A
*
* Comment:
* When mod_hash_walk is in progress, we can't change the hashtable.
* This is post-walk handling of exchange timing
*/
void
{
}
}
/*
* fcoei_xch_check
* Check if the exchange timed out or link is down
*
* Input:
* key = rxid of the unsolicited exchange
* val = the unsolicited exchange
* arg = the soft state
*
* Return:
* MH_WALK_CONTINUE = continue to walk
*
* Comment:
* We need send ABTS for timed-out for solicited exchange
* If it's solicited FLOGI, we need set SS_FLAG_FLOGI_FAILED
* If the link is down, we think it has timed out too.
*/
/* ARGSUSED */
static uint32_t
{
/*
* It's solicited exchange
*/
if (LA_ELS_FLOGI == ((ls_code_t *)(void *)
/*
* It's solicited FLOGI
*/
}
}
}
return (MH_WALK_CONTINUE);
}
/*
* fcoei_init_ifm
* initialize fcoei_frame
*
* Input:
* frm = the frame that ifm need link to
* xch = the exchange that ifm need link to
*
* Return:
* N/A
*
* Comment:
* For solicited frames, it's called after FC frame header initialization
* For unsolicited frames, it's called just after the frame enters fcoei
*/
void
{
}
/*
* fcoei_trigger_fp_attach
* Trigger fp_attach for this fcoei port
*
* Input:
* arg = the soft state that fp will attach
*
* Return:
* N/A
*
* Comment:
* N/A
*/
static void
{
return;
}
/*
*/
(void) ndi_devi_free(child);
return;
}
/*
* If it's physical HBA, fp.conf will register the property.
* fcoei is one software HBA, so we need register it manually
*/
"port", 0) != DDI_PROP_SUCCESS) {
(void) ndi_devi_free(child);
return;
}
/*
* It will call fp_attach eventually
*/
if (rval != NDI_SUCCESS) {
} else {
}
}
/*
* fcoei_abts_exchange
* Send ABTS to abort solicited exchange
*
* Input:
* xch = the exchange that will be aborted
*
* Return:
* N/A
*
* Comment:
* ABTS frame uses the same oxid as the exchange
*/
static void
{
/*
* BLS_ABTS doesn't contain any other payload except FCFH
*/
return;
}
}
/*
* fcoei_complete_xch
* Complete the exchange
*
* Input:
* xch = the exchange that will be completed
* frm = newly-allocated frame that has not been submitted
* pkt_state = LV fpkt state
* pkt_reason = LV fpkt reason
*
* Return:
* N/A
*
* Comment:
* N/A
*/
void
{
if (pkt_state != FC_PKT_SUCCESS) {
}
/*
* It's newly-allocated frame , which we haven't sent out
*/
}
/*
* If xch is in hash table, we need remove it
*/
} else {
}
} else {
}
}