diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/lib/sun_fc/common/TgtFCHBAPort.cc | 10 | ||||
-rw-r--r-- | usr/src/uts/common/dtrace/sdt_subr.c | 9 | ||||
-rw-r--r-- | usr/src/uts/common/io/comstar/port/fct/discovery.c | 50 | ||||
-rw-r--r-- | usr/src/uts/common/io/comstar/port/fct/fct.c | 232 | ||||
-rw-r--r-- | usr/src/uts/common/io/comstar/port/fct/fct_impl.h | 15 | ||||
-rw-r--r-- | usr/src/uts/common/io/comstar/port/qlt/qlt.c | 59 | ||||
-rw-r--r-- | usr/src/uts/common/sys/fct.h | 24 | ||||
-rw-r--r-- | usr/src/uts/common/sys/fct_defines.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/sys/fctio.h | 3 |
9 files changed, 380 insertions, 23 deletions
diff --git a/usr/src/lib/sun_fc/common/TgtFCHBAPort.cc b/usr/src/lib/sun_fc/common/TgtFCHBAPort.cc index 511df32308..44c086d765 100644 --- a/usr/src/lib/sun_fc/common/TgtFCHBAPort.cc +++ b/usr/src/lib/sun_fc/common/TgtFCHBAPort.cc @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -401,6 +401,7 @@ void TgtFCHBAPort::sendRLS(uint64_t destWWN, fctio_t fctio; // fc_hba_adapter_port_stats_t fc_port_stat; uint64_t en_portWWN; + uint64_t DestPortID; // Validate the arguments if (pRspBuffer == NULL || @@ -417,13 +418,14 @@ void TgtFCHBAPort::sendRLS(uint64_t destWWN, /* The destWWN is either the adapter port or a discovered port. */ memset(&fctio, 0, sizeof (fctio)); - fctio.fctio_cmd = FCTIO_GET_ADAPTER_PORT_STATS; + fctio.fctio_cmd = FCTIO_GET_LINK_STATUS; fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_portWWN; fctio.fctio_ilen = (uint32_t)(sizeof (en_portWWN)); if (portWWN != destWWN) { attrs = getDiscoveredAttributes(destWWN, tmp); - fctio.fctio_abuf = (uint64_t)(uintptr_t)&attrs.PortFcId; - fctio.fctio_alen = (uint32_t)(sizeof (attrs.PortFcId)); + DestPortID = (uint64_t)attrs.PortFcId; + fctio.fctio_abuf = (uint64_t)(uintptr_t)&DestPortID; + fctio.fctio_alen = (uint32_t)(sizeof (DestPortID)); } fctio.fctio_xfer = FCTIO_XFER_READ; fctio.fctio_flags = 0; diff --git a/usr/src/uts/common/dtrace/sdt_subr.c b/usr/src/uts/common/dtrace/sdt_subr.c index 62e6cf52b4..a89403ea75 100644 --- a/usr/src/uts/common/dtrace/sdt_subr.c +++ b/usr/src/uts/common/dtrace/sdt_subr.c @@ -1085,6 +1085,15 @@ sdt_argdesc_t sdt_args[] = { "fc_port_info_t *" }, { "fc", "xfer-done", 4, 4, "stmf_data_buf_t *", "fc_xferinfo_t *" }, + { "fc", "rscn-receive", 0, 0, "fct_i_local_port_t *", + "conninfo_t *" }, + { "fc", "rscn-receive", 1, 1, "int", "int"}, + { "fc", "abts-receive", 0, 0, "fct_cmd_t *", + "conninfo_t *" }, + { "fc", "abts-receive", 1, 1, "fct_i_local_port_t *", + "fc_port_info_t *" }, + { "fc", "abts-receive", 2, 2, "fct_i_remote_port_t *", + "fc_port_info_t *" }, { NULL } diff --git a/usr/src/uts/common/io/comstar/port/fct/discovery.c b/usr/src/uts/common/io/comstar/port/fct/discovery.c index 13ad485bfc..96a80c2558 100644 --- a/usr/src/uts/common/io/comstar/port/fct/discovery.c +++ b/usr/src/uts/common/io/comstar/port/fct/discovery.c @@ -2671,6 +2671,52 @@ fct_gspn_cb(fct_i_cmd_t *icmd) rw_exit(&iport->iport_lock); } +void +fct_rls_cb(fct_i_cmd_t *icmd) +{ + fct_els_t *els = ICMD_TO_ELS(icmd); + uint8_t *resp; + fct_rls_cb_data_t *rls_cb_data = NULL; + fct_port_link_status_t *rls_resp; + fct_i_local_port_t *iport = ICMD_TO_IPORT(icmd); + + rls_cb_data = icmd->icmd_cb_private; + + if (!FCT_IS_ELS_ACC(icmd)) { + stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_rls_cb: " + "solicited RLS is not accepted - icmd/%p", icmd); + if (rls_cb_data) { + rls_cb_data->fct_els_res = FCT_FAILURE; + sema_v(&iport->iport_rls_sema); + } + return; + } + + if (!rls_cb_data) { + sema_v(&iport->iport_rls_sema); + return; + } + + resp = els->els_resp_payload; + + rls_cb_data = icmd->icmd_cb_private; + + /* Get the response and store it somewhere */ + rls_resp = (fct_port_link_status_t *)rls_cb_data->fct_link_status; + rls_resp->LinkFailureCount = BE_32(*((uint32_t *)(resp + 4))); + rls_resp->LossOfSyncCount = BE_32(*((uint32_t *)(resp + 8))); + rls_resp->LossOfSignalsCount = BE_32(*((uint32_t *)(resp + 12))); + rls_resp->PrimitiveSeqProtocolErrorCount = + BE_32(*((uint32_t *)(resp + 16))); + rls_resp->InvalidTransmissionWordCount = + BE_32(*((uint32_t *)(resp + 20))); + rls_resp->InvalidCRCCount = BE_32(*((uint32_t *)(resp + 24))); + + rls_cb_data->fct_els_res = FCT_SUCCESS; + sema_v(&iport->iport_rls_sema); + icmd->icmd_cb_private = NULL; +} + /* * For lookup functions, we move locking up one level */ @@ -2758,6 +2804,10 @@ fct_rscn_verify(fct_i_local_port_t *iport, uint8_t *rscn_req_payload, page_format = 0x03 & page_buf[0]; page_portid = fct_netbuf_to_value(page_buf + 1, 3); + DTRACE_FC_2(rscn__receive, + fct_i_local_port_t, iport, + int, page_portid); + rw_enter(&iport->iport_lock, RW_READER); if (!page_format) { irp = fct_portid_to_portptr(iport, page_portid); diff --git a/usr/src/uts/common/io/comstar/port/fct/fct.c b/usr/src/uts/common/io/comstar/port/fct/fct.c index fb0e2fbd1d..7c1166837d 100644 --- a/usr/src/uts/common/io/comstar/port/fct/fct.c +++ b/usr/src/uts/common/io/comstar/port/fct/fct.c @@ -53,6 +53,7 @@ static int fct_close(dev_t dev, int flag, int otype, cred_t *credp); static int fct_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, int *rval); static int fct_fctiocmd(intptr_t data, int mode); +void fct_init_kstats(fct_i_local_port_t *iport); static dev_info_t *fct_dip; static struct cb_ops fct_cb_ops = { @@ -91,6 +92,7 @@ static struct dev_ops fct_ops = { }; #define FCT_NAME "COMSTAR FCT" +#define FCT_MODULE_NAME "fct" extern struct mod_ops mod_driverops; static struct modldrv modldrv = { @@ -633,29 +635,111 @@ int fct_get_port_stats(uint8_t *port_wwn, fc_tgt_hba_adapter_port_stats_t *port_stats, uint32_t *error_detail) { + int ret; fct_i_local_port_t *iport = fct_get_iport_per_wwn(port_wwn); + fct_port_link_status_t stat; + uint32_t buf_size = sizeof (fc_tgt_hba_adapter_port_stats_t); if (!iport) return (ENXIO); port_stats->version = FCT_HBA_ADAPTER_PORT_STATS_VERSION; + + if (iport->iport_port->port_info == NULL) { + *error_detail = FCTIO_FAILURE; + return (EIO); + } + ret = iport->iport_port->port_info(FC_TGT_PORT_RLS, + iport->iport_port, NULL, (uint8_t *)&stat, &buf_size); + if (ret != STMF_SUCCESS) { + *error_detail = FCTIO_FAILURE; + return (EIO); + } + + port_stats->SecondsSinceLastReset = 0; + port_stats->TxFrames = 0; + port_stats->TxWords = 0; + port_stats->RxFrames = 0; + port_stats->RxWords = 0; + port_stats->LIPCount = 0; + port_stats->NOSCount = 0; + port_stats->ErrorFrames = 0; + port_stats->DumpedFrames = 0; + port_stats->LinkFailureCount = stat.LinkFailureCount; + port_stats->LossOfSyncCount = stat.LossOfSyncCount; + port_stats->LossOfSignalCount = stat.LossOfSignalsCount; + port_stats->PrimitiveSeqProtocolErrCount = + stat.PrimitiveSeqProtocolErrorCount; + port_stats->InvalidTxWordCount = + stat.InvalidTransmissionWordCount; + port_stats->InvalidCRCCount = stat.InvalidCRCCount; + + return (ret); +} + +int +fct_get_link_status(uint8_t *port_wwn, uint64_t *dest_id, + fct_port_link_status_t *link_status, uint32_t *error_detail) +{ + fct_i_local_port_t *iport = fct_get_iport_per_wwn(port_wwn); + fct_i_remote_port_t *irp = NULL; + uint32_t buf_size = sizeof (fct_port_link_status_t); + stmf_status_t ret = 0; + int i; + fct_cmd_t *cmd = NULL; + + if (!iport) { + *error_detail = FCTIO_BADWWN; + return (ENXIO); + } + /* - * port_stats->SecondsSinceLastReset = ; - * port_stats->TxFrames = ; - * port_stats->TxWords = ; - * port_stats->RxFrames = ; - * port_stats->RxWords = ; - * port_stats->LIPCount = ; - * port_stats->NOSCount = ; - * port_stats->ErrorFrames = ; - * port_stats->DumpedFrames = ; - * port_stats->LinkFailureCount = ; - * port_stats->LossOfSyncCount = ; - * port_stats->LossOfSignalCount = ; - * port_stats->PrimitiveSeqProtocol = ; - * port_stats->InvalidTxWordCount = ; - * port_stats->InvalidCRCCount = ; + * If what we are requesting is zero or same as local port, + * then we use port_info() */ - return (0); + if (dest_id == NULL || *dest_id == iport->iport_link_info.portid) { + if (iport->iport_port->port_info == NULL) { + *error_detail = FCTIO_FAILURE; + return (EIO); + } + ret = iport->iport_port->port_info(FC_TGT_PORT_RLS, + iport->iport_port, NULL, + (uint8_t *)link_status, &buf_size); + if (ret == STMF_SUCCESS) { + return (0); + } else { + *error_detail = FCTIO_FAILURE; + return (EIO); + } + } + + /* + * For remote port, we will send RLS + */ + for (i = 0; i < rportid_table_size; i++) { + irp = iport->iport_rp_tb[i]; + while (irp) { + if (irp->irp_rp->rp_id == *dest_id && + irp->irp_flags & IRP_PLOGI_DONE) { + goto SEND_RLS_ELS; + } + irp = irp->irp_next; + } + } + return (ENXIO); + +SEND_RLS_ELS: + cmd = fct_create_solels(iport->iport_port, + irp->irp_rp, 0, ELS_OP_RLS, + 0, fct_rls_cb); + if (!cmd) + return (ENOMEM); + iport->iport_rls_cb_data.fct_link_status = link_status; + CMD_TO_ICMD(cmd)->icmd_cb_private = &iport->iport_rls_cb_data; + fct_post_to_solcmd_queue(iport->iport_port, cmd); + sema_p(&iport->iport_rls_sema); + if (iport->iport_rls_cb_data.fct_els_res != FCT_SUCCESS) + ret = EIO; + return (ret); } static int @@ -788,6 +872,19 @@ fct_fctiocmd(intptr_t data, int mode) mutex_exit(&fct_global_mutex); break; } + case FCTIO_GET_LINK_STATUS: { + uint8_t *port_wwn = (uint8_t *)ibuf; + fct_port_link_status_t *link_status = + (fct_port_link_status_t *)obuf; + uint64_t *dest_id = abuf; + + mutex_enter(&fct_global_mutex); + ret = fct_get_link_status(port_wwn, dest_id, link_status, + &fctio->fctio_errno); + mutex_exit(&fct_global_mutex); + break; + } + default: break; } @@ -1018,6 +1115,7 @@ fct_register_local_port(fct_local_port_t *port) mutex_init(&iport->iport_worker_lock, NULL, MUTEX_DRIVER, NULL); cv_init(&iport->iport_worker_cv, NULL, CV_DRIVER, NULL); rw_init(&iport->iport_lock, NULL, RW_DRIVER, NULL); + sema_init(&iport->iport_rls_sema, 0, NULL, SEMA_DRIVER, NULL); /* Remote port mgmt */ iport->iport_rp_slots = (fct_i_remote_port_t **)kmem_zalloc( @@ -1088,6 +1186,8 @@ fct_register_local_port(fct_local_port_t *port) fct_iport_list = iport; mutex_exit(&fct_global_mutex); + fct_init_kstats(iport); + fct_log_local_port_event(port, ESC_SUNFC_PORT_ATTACH); return (FCT_SUCCESS); @@ -1169,6 +1269,7 @@ fct_deregister_local_port(fct_local_port_t *port) sizeof (fct_i_remote_port_t *)); rw_destroy(&iport->iport_lock); cv_destroy(&iport->iport_worker_cv); + sema_destroy(&iport->iport_rls_sema); mutex_destroy(&iport->iport_worker_lock); ddi_taskq_destroy(iport->iport_worker_taskq); if (iport->iport_rp_tb) { @@ -1176,6 +1277,10 @@ fct_deregister_local_port(fct_local_port_t *port) sizeof (fct_i_remote_port_t *)); } + if (iport->iport_kstat_portstat) { + kstat_delete(iport->iport_kstat_portstat); + } + fct_log_local_port_event(port, ESC_SUNFC_PORT_DETACH); return (FCT_SUCCESS); @@ -2275,6 +2380,16 @@ fct_create_solels(fct_local_port_t *port, fct_remote_port_t *rp, int implicit, kmem_zalloc(els->els_req_size, KM_SLEEP); p[7] = FC_SCR_FULL_REGISTRATION; break; + case ELS_OP_RLS: + els->els_resp_alloc_size = els->els_resp_size = 28; + els->els_resp_payload = (uint8_t *) + kmem_zalloc(els->els_resp_size, KM_SLEEP); + els->els_req_alloc_size = els->els_req_size = 8; + p = els->els_req_payload = (uint8_t *) + kmem_zalloc(els->els_req_size, KM_SLEEP); + ptid = PORT_TO_IPORT(port)->iport_link_info.portid; + fct_value_to_netbuf(ptid, els->els_req_payload + 5, 3); + break; default: ASSERT(0); @@ -2737,6 +2852,12 @@ fct_handle_rcvd_abts(fct_cmd_t *cmd) fct_queue_cmd_for_termination(cmd, FCT_NOT_LOGGED_IN); return; } + + DTRACE_FC_3(abts__receive, + fct_cmd_t, cmd, + fct_local_port_t, port, + fct_i_remote_port_t, irp); + cmd->cmd_rp = irp->irp_rp; /* @@ -3339,3 +3460,82 @@ fct_wwn_to_str(char *to_ptr, const uint8_t *from_ptr) from_ptr[0], from_ptr[1], from_ptr[2], from_ptr[3], from_ptr[4], from_ptr[5], from_ptr[6], from_ptr[7]); } + +static int +fct_update_stats(kstat_t *ks, int rw) +{ + fct_i_local_port_t *iport; + fct_port_stat_t *port_kstat; + fct_port_link_status_t stat; + uint32_t buf_size = sizeof (stat); + int ret; + + if (rw == KSTAT_WRITE) + return (EACCES); + + iport = (fct_i_local_port_t *)ks->ks_private; + port_kstat = (fct_port_stat_t *)ks->ks_data; + + if (iport->iport_port->port_info == NULL) { + return (EIO); + } + ret = iport->iport_port->port_info(FC_TGT_PORT_RLS, + iport->iport_port, NULL, (uint8_t *)&stat, &buf_size); + if (ret != STMF_SUCCESS) { + return (EIO); + } + + port_kstat->link_failure_cnt.value.ui32 = + stat.LinkFailureCount; + port_kstat->loss_of_sync_cnt.value.ui32 = + stat.LossOfSyncCount; + port_kstat->loss_of_signals_cnt.value.ui32 = + stat.LossOfSignalsCount; + port_kstat->prim_seq_protocol_err_cnt.value.ui32 = + stat.PrimitiveSeqProtocolErrorCount; + port_kstat->invalid_tx_word_cnt.value.ui32 = + stat.InvalidTransmissionWordCount; + port_kstat->invalid_crc_cnt.value.ui32 = + stat.InvalidCRCCount; + + return (0); +} + +void +fct_init_kstats(fct_i_local_port_t *iport) +{ + kstat_t *ks; + fct_port_stat_t *port_kstat; + char name[256]; + + if (iport->iport_alias) + (void) sprintf(name, "iport_%s", iport->iport_alias); + else + (void) sprintf(name, "iport_%"PRIxPTR"", (uintptr_t)iport); + ks = kstat_create(FCT_MODULE_NAME, 0, name, "rawdata", + KSTAT_TYPE_NAMED, sizeof (fct_port_stat_t) / sizeof (kstat_named_t), + 0); + + if (ks == NULL) { + return; + } + port_kstat = (fct_port_stat_t *)ks->ks_data; + + iport->iport_kstat_portstat = ks; + kstat_named_init(&port_kstat->link_failure_cnt, + "Link_failure_cnt", KSTAT_DATA_UINT32); + kstat_named_init(&port_kstat->loss_of_sync_cnt, + "Loss_of_sync_cnt", KSTAT_DATA_UINT32); + kstat_named_init(&port_kstat->loss_of_signals_cnt, + "Loss_of_signals_cnt", KSTAT_DATA_UINT32); + kstat_named_init(&port_kstat->prim_seq_protocol_err_cnt, + "Prim_seq_protocol_err_cnt", KSTAT_DATA_UINT32); + kstat_named_init(&port_kstat->invalid_tx_word_cnt, + "Invalid_tx_word_cnt", KSTAT_DATA_UINT32); + kstat_named_init(&port_kstat->invalid_crc_cnt, + "Invalid_crc_cnt", KSTAT_DATA_UINT32); + ks->ks_update = fct_update_stats; + ks->ks_private = (void *)iport; + kstat_install(ks); + +} diff --git a/usr/src/uts/common/io/comstar/port/fct/fct_impl.h b/usr/src/uts/common/io/comstar/port/fct/fct_impl.h index c1eab8bb2e..483b027cb2 100644 --- a/usr/src/uts/common/io/comstar/port/fct/fct_impl.h +++ b/usr/src/uts/common/io/comstar/port/fct/fct_impl.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _FCT_IMPL_H @@ -154,6 +154,14 @@ typedef struct fct_i_remote_port { } fct_i_remote_port_t; /* + * structure used for fct_rls_cb() callback private data + */ +typedef struct fct_rls_cb_data { + struct fct_port_link_status *fct_link_status; + fct_status_t fct_els_res; +} fct_rls_cb_data_t; + +/* * irp flags */ #define IRP_PLOGI_DONE 0x0001 @@ -266,7 +274,9 @@ typedef struct fct_i_local_port { /* rpwe = remote port with pending els(es) */ fct_i_remote_port_t *iport_rpwe_head; fct_i_remote_port_t *iport_rpwe_tail; - + kstat_t *iport_kstat_portstat; + ksema_t iport_rls_sema; + fct_rls_cb_data_t iport_rls_cb_data; } fct_i_local_port_t; #define IPORT_FLOGI_DONE(iport) PORT_FLOGI_DONE(&(iport)->iport_link_info) @@ -423,6 +433,7 @@ void fct_gsnn_cb(fct_i_cmd_t *icmd); void fct_gcs_cb(fct_i_cmd_t *icmd); void fct_gft_cb(fct_i_cmd_t *icmd); void fct_gspn_cb(fct_i_cmd_t *icmd); +void fct_rls_cb(fct_i_cmd_t *icmd); disc_action_t fct_process_link_init(fct_i_local_port_t *iport); #ifdef __cplusplus diff --git a/usr/src/uts/common/io/comstar/port/qlt/qlt.c b/usr/src/uts/common/io/comstar/port/qlt/qlt.c index 17b8dcb1df..f171cce5b3 100644 --- a/usr/src/uts/common/io/comstar/port/qlt/qlt.c +++ b/usr/src/uts/common/io/comstar/port/qlt/qlt.c @@ -888,6 +888,64 @@ qlt_populate_hba_fru_details(struct fct_local_port *port, FCHBA_MODEL_DESCRIPTION_LEN, "%s", qlt->nvram->model_name); } +/* ARGSUSED */ +fct_status_t +qlt_info(uint32_t cmd, fct_local_port_t *port, + void *arg, uint8_t *buf, uint32_t *bufsizep) +{ + qlt_state_t *qlt = (qlt_state_t *)port->port_fca_private; + mbox_cmd_t *mcp; + fct_status_t ret = FCT_SUCCESS; + uint8_t *p; + fct_port_link_status_t *link_status; + + switch (cmd) { + case FC_TGT_PORT_RLS: + if ((*bufsizep) < sizeof (fct_port_link_status_t)) { + ret = FCT_FAILURE; + break; + } + /* send mailbox command to get link status */ + mcp = qlt_alloc_mailbox_command(qlt, 156); + if (mcp == NULL) { + ret = FCT_ALLOC_FAILURE; + break; + } + + /* GET LINK STATUS count */ + mcp->to_fw[0] = 0x6d; + mcp->to_fw[8] = 156/4; + mcp->to_fw_mask |= BIT_1 | BIT_8; + mcp->from_fw_mask |= BIT_1 | BIT_2; + + ret = qlt_mailbox_command(qlt, mcp); + if (ret != QLT_SUCCESS) { + qlt_free_mailbox_command(qlt, mcp); + break; + } + qlt_dmem_dma_sync(mcp->dbuf, DDI_DMA_SYNC_FORCPU); + + p = mcp->dbuf->db_sglist[0].seg_addr; + link_status = (fct_port_link_status_t *)buf; + link_status->LinkFailureCount = LE_32(*((uint32_t *)p)); + link_status->LossOfSyncCount = LE_32(*((uint32_t *)(p + 4))); + link_status->LossOfSignalsCount = LE_32(*((uint32_t *)(p + 8))); + link_status->PrimitiveSeqProtocolErrorCount = + LE_32(*((uint32_t *)(p + 12))); + link_status->InvalidTransmissionWordCount = + LE_32(*((uint32_t *)(p + 16))); + link_status->InvalidCRCCount = + LE_32(*((uint32_t *)(p + 20))); + + qlt_free_mailbox_command(qlt, mcp); + break; + default: + ret = FCT_FAILURE; + break; + } + return (ret); +} + fct_status_t qlt_port_start(caddr_t arg) { @@ -940,6 +998,7 @@ qlt_port_start(caddr_t arg) port->port_ctl = qlt_ctl; port->port_flogi_xchg = qlt_do_flogi; port->port_populate_hba_details = qlt_populate_hba_fru_details; + port->port_info = qlt_info; if (fct_register_local_port(port) != FCT_SUCCESS) { goto qlt_pstart_fail_2_5; diff --git a/usr/src/uts/common/sys/fct.h b/usr/src/uts/common/sys/fct.h index 43940a90d2..09ec2c8c0f 100644 --- a/usr/src/uts/common/sys/fct.h +++ b/usr/src/uts/common/sys/fct.h @@ -158,6 +158,9 @@ typedef struct fct_rcvd_abts { #define FCHBA_DRIVER_NAME_LEN 256 #define FCHBA_SYMB_NAME_LEN 255 +#define FC_TGT_PORT_INFO_CMD (((uint32_t)'I') << 24) +#define FC_TGT_PORT_RLS FC_TGT_PORT_INFO_CMD + 0x1 + typedef struct fct_port_attrs { char manufacturer[FCHBA_MANUFACTURER_LEN]; char serial_number[FCHBA_SERIAL_NUMBER_LEN]; @@ -174,6 +177,15 @@ typedef struct fct_port_attrs { uint32_t max_frame_size; } fct_port_attrs_t; +typedef struct fct_port_link_status { + uint32_t LinkFailureCount; + uint32_t LossOfSyncCount; + uint32_t LossOfSignalsCount; + uint32_t PrimitiveSeqProtocolErrorCount; + uint32_t InvalidTransmissionWordCount; + uint32_t InvalidCRCCount; +} fct_port_link_status_t; + typedef struct fct_dbuf_store { void *fds_fct_private; void *fds_fca_private; @@ -232,6 +244,9 @@ typedef struct fct_local_port { struct fct_flogi_xchg *fx); void (*port_populate_hba_details)( struct fct_local_port *port, struct fct_port_attrs *port_attrs); + fct_status_t (*port_info)(uint32_t cmd, + struct fct_local_port *port, void *arg, uint8_t *buf, + uint32_t *bufsizep); } fct_local_port_t; /* @@ -277,6 +292,15 @@ typedef struct fct_link_info { uint8_t port_rpwwn[8]; } fct_link_info_t; +typedef struct fct_port_stat { + kstat_named_t link_failure_cnt; + kstat_named_t loss_of_sync_cnt; + kstat_named_t loss_of_signals_cnt; + kstat_named_t prim_seq_protocol_err_cnt; + kstat_named_t invalid_tx_word_cnt; + kstat_named_t invalid_crc_cnt; +} fct_port_stat_t; + /* * port topology */ diff --git a/usr/src/uts/common/sys/fct_defines.h b/usr/src/uts/common/sys/fct_defines.h index cd4f8324c5..79db9f1293 100644 --- a/usr/src/uts/common/sys/fct_defines.h +++ b/usr/src/uts/common/sys/fct_defines.h @@ -71,6 +71,7 @@ typedef stmf_status_t fct_status_t; #define ELS_OP_FLOGI 0x04 #define ELS_OP_LOGO 0x05 #define ELS_OP_ABTX 0x06 +#define ELS_OP_RLS 0x0f #define ELS_OP_ECHO 0x10 #define ELS_OP_REC 0x13 #define ELS_OP_SRR 0x14 diff --git a/usr/src/uts/common/sys/fctio.h b/usr/src/uts/common/sys/fctio.h index 875d632b6c..698914941b 100644 --- a/usr/src/uts/common/sys/fctio.h +++ b/usr/src/uts/common/sys/fctio.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _FCTIO_H @@ -38,6 +38,7 @@ extern "C" { #define FCTIO_GET_DISCOVERED_PORT_ATTRIBUTES (FCTIO_SUB_CMD + 0x04) #define FCTIO_GET_PORT_ATTRIBUTES (FCTIO_SUB_CMD + 0x05) #define FCTIO_GET_ADAPTER_PORT_STATS (FCTIO_SUB_CMD + 0x06) +#define FCTIO_GET_LINK_STATUS (FCTIO_SUB_CMD + 0x07) /* * fcio_xfer definitions |