srpt_stp.c revision 191c289b86668766245f78ec1f87557319bc46a1
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * CDDL HEADER START
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * The contents of this file are subject to the terms of the
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Common Development and Distribution License (the "License").
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * You may not use this file except in compliance with the License.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * See the License for the specific language governing permissions
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * and limitations under the License.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * When distributing Covered Code, include this CDDL HEADER in each
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * If applicable, add the following below this CDDL HEADER, with the
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * fields enclosed by brackets "[]" replaced with your own identifying
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * information: Portions Copyright [yyyy] [name of copyright owner]
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * CDDL HEADER END
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Use is subject to license terms.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * SCSI Target Port I/F for Solaris SCSI RDMA Protocol Target (SRP)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * port provider module for the COMSTAR framework.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * STMF LPort Interface Prototypes
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstatic stmf_status_t srpt_stp_xfer_data(struct scsi_task *task,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstmf_status_t srpt_stp_send_status(struct scsi_task *task,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstatic void srpt_stp_task_free(struct scsi_task *task);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstatic stmf_status_t srpt_stp_abort(struct stmf_local_port *lport,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstatic void srpt_stp_task_poll(struct scsi_task *task);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstatic void srpt_stp_ctl(struct stmf_local_port *lport,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck struct stmf_local_port *lport, void *arg, uint8_t *buf,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstatic void srpt_stp_event_handler(struct stmf_local_port *lport,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstatic void srpt_format_login_rsp(srp_login_req_t *req,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstatic void srpt_format_login_rej(srp_login_req_t *req,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstatic scsi_devid_desc_t *srpt_stp_alloc_scsi_devid_desc(uint64_t guid);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstatic void srpt_stp_free_scsi_devid_desc(scsi_devid_desc_t *sdd);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * srpt_stp_start_srp() - Start SRP service
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Enable the SRP service for the specified SCSI Target Port.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck SRPT_DPRINTF_L1("stp_start_srp, NULL SCSI target port");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck SRPT_DPRINTF_L1("stp_start_srp, SCSI target port NULL"
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck " IOC pointer");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck SRPT_DPRINTF_L2("stp_start_srp, register SRP service for"
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck " svc_id (%016llx)", (u_longlong_t)tgt->tp_ibt_svc_id);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck SRPT_DPRINTF_L1("stp_start_srp, SRP service creation err (%d)",
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Bind the service associated with the SCSI target port to
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * each active port of the I/O Controller.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck for (port = 0; port < ioc->ioc_attr.hca_nports; port++) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Calculate the new I/O Controller profile and either update the
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * profile if previously registered or register it with the IB
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Device Management Agent.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck SRPT_DPRINTF_L3("start_srp, update I/O Controller profile (%016llx)",
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck srpt_ctxt->sc_ibdma_ops.ibdma_update(ioc->ioc_ibdma_hdl,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * srpt_stp_stop_srp() - Stop SRP service.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Disable the SRP service on the specified SCSI Target Port.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck " specified");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck SRPT_DPRINTF_L2("stp_stop_srp, bad Target, IOC NULL");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Update the I/O Controller profile to remove the SRP service
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * for this SCSI target port.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck " unregister IOC profile");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Unbind the SRP service associated with the SCSI target port
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * from all of the I/O Controller physical ports.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck SRPT_DPRINTF_L2("stp_stop_srp, unbind and de-register service"
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck status = ibt_deregister_service(srpt_ctxt->sc_ibt_hdl,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * SRP service is now off-line for this SCSI Target Port.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * We force a disconnect (i.e. SRP Target Logout) for any
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * active SRP logins.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * wait for all sessions to terminate before returning
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck cv_wait(&tgt->tp_sess_complete, &tgt->tp_sess_list_lock);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * srpt_stp_alloc_port() - Allocate SCSI Target Port
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck SRPT_DPRINTF_L1("stp_alloc_port, NULL I/O Controller");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck SRPT_DPRINTF_L3("stp_alloc_port, allocate STMF local port");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck lport = stmf_alloc(STMF_STRUCT_STMF_LOCAL_PORT, sizeof (*tgt), 0);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck mutex_init(&tgt->tp_ch_list_lock, NULL, MUTEX_DRIVER, NULL);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck cv_init(&tgt->tp_offline_complete, NULL, CV_DRIVER, NULL);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck list_create(&tgt->tp_ch_list, sizeof (srpt_channel_t),
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck mutex_init(&tgt->tp_sess_list_lock, NULL, MUTEX_DRIVER, NULL);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck cv_init(&tgt->tp_sess_complete, NULL, CV_DRIVER, NULL);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck list_create(&tgt->tp_sess_list, sizeof (srpt_session_t),
return (tgt);
goto retry_registration;
return (NULL);
return (STMF_SUCCESS);
return (status);
goto retry_deregistration;
return (status);
static stmf_status_t
return (STMF_FAILURE);
base_offset = 0;
desc++;
xferred_len = 0;
return (STMF_FAILURE);
while (xfer_len > 0) {
return (STMF_SUCCESS);
return (STMF_BUSY);
return (STMF_FAILURE);
desc_offset = 0;
desc++;
return (STMF_SUCCESS);
return (status);
if (resid != 0) {
if (sense_length != 0) {
status);
return (status);
(void *)task,
return (STMF_FAILURE);
status);
return (STMF_FAILURE);
return (STMF_SUCCESS);
(void *)task);
static stmf_status_t
(void *)iu);
return (status);
(void *)task);
switch (cmd) {
case STMF_CMD_LPORT_ONLINE:
* creation/destruction transitional state and the will
&cstatus);
case STMF_CMD_LPORT_OFFLINE:
cmd);
static stmf_status_t
return (STMF_SUCCESS);
static scsi_devid_desc_t *
return (sdd);
sizeof (srpt_session_t), 0);
return (NULL);
return (NULL);
return (ss);
goto reject_login;
SRP_PORT_ID_LEN) != 0) {
goto reject_login;
goto reject_login;
goto reject_login;
goto reject_login;
SRP_PORT_ID_LEN) == 0) &&
SRP_PORT_ID_LEN) == 0)) {
goto reject_login;
goto reject_login;
goto reject_login;
goto reject_login;
goto reject_login;
return (ch);
return (NULL);