/*
* 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
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* iSCSI logical unit interfaces
*/
#include "iscsi.h"
#include <sys/bootprops.h>
/* tpgt bytes in string form */
/* logical unit number bytes in string form */
/*
* Addition addr size of size of ',' + max str form of tpgt (2 bytes) +
* ',' + max str form of logical unit number (4 bytes).
*/
/* internal interfaces */
extern dev_info_t *scsi_vhci_dip;
extern ib_boot_prop_t *iscsiboot_prop;
/*
* +--------------------------------------------------------------------+
* | External Connection Interfaces |
* +--------------------------------------------------------------------+
*/
/*
* iscsi_lun_create - This function will create a lun mapping.
* logic specific to MPxIO vs. NDI node creation is switched
* out to a helper function.
*/
{
/*
* Check whether it has already existed in the list.
*/
/*
* The logic unit has already existed in the list,
* return with success.
*/
return (ISCSI_STATUS_SUCCESS);
}
}
ADDR_EXT_SIZE + 1),
/* allocate space for lun struct */
/* initialize common LU information */
/* store GUID if valid one exists */
} else {
ilp->lun_guid_size = 0;
}
/*
* We need to add the lun to our lists now because during the
* lun creation we will get called back into multiple times
* depending on the createion type. These callbacks will
* occur via our tran_init_lun, tran_get_name, tran_get_bus_addr,
* tran_init_pkt, tran_start.
*/
} else {
}
/* Attempt to create a scsi_vhci binding if GUID is available */
}
if (!ISCSI_SUCCESS(rtn)) {
/* unable to bind under scsi_vhci, failback to ndi */
}
/*
* If NOT successful we need to remove the lun from the
* session and free any related resources.
*/
if (!ISCSI_SUCCESS(rtn)) {
/* if head, set head to our next */
} else {
/* if not head, set prev lun's next to our next */
break;
}
}
}
ADDR_EXT_SIZE + 1));
}
} else {
/* Check whether this is the required LUN for iscsi boot */
/*
* During iscsi boot, the boot lun has been
* online, we should set the "online flag".
*/
}
}
}
return (rtn);
}
/*
* iscsi_lun_destroy - offline and remove lun
*
* This interface is called when a name service change has
* occured and the storage is no longer available to this
* initiator. This function will offline and free the
* solaris node resources. Then it will free all iscsi lun
* resources.
*
* This function can fail with ISCSI_STATUS_BUSY if the
* logical unit is in use. The user should unmount or
* close the device and perform the nameservice operation
* again if this occurs.
*/
{
/* attempt to offline and free solaris node */
/* If we successfully unplumbed the lun remove it from our lists */
if (ISCSI_SUCCESS(status)) {
/* target first item in list */
} else {
/*
* search session list for ilp pointing
* to lun being removed. Then
* update that luns next pointer.
*/
break;
}
}
} else {
/* couldn't find session */
}
}
/* release its memory */
ADDR_EXT_SIZE + 1));
}
}
return (status);
}
/*
* +--------------------------------------------------------------------+
* | External Logical Unit Interfaces |
* +--------------------------------------------------------------------+
*/
/*
* iscsi_lun_virt_create - Creates solaris logical unit via MDI
*/
static iscsi_status_t
struct scsi_inquiry *inq)
{
int ncompatible = 0;
int circ = 0;
/*
* Generate compatible property
*/
/* if nodename can't be determined then print a message and skip it */
return (ISCSI_STATUS_INTERNAL_ERROR);
}
/*
*
*/
0, &pip);
if (mdi_rtn == MDI_SUCCESS) {
"property for %s lun %d (MDI_GUID)",
goto virt_create_done;
}
"property for %s lun %d (TARGET_PROP)",
goto virt_create_done;
}
"property for %s lun %d (LUN_PROP)",
goto virt_create_done;
}
compatible, ncompatible) !=
"property for %s lun %d (COMPATIBLE)",
goto virt_create_done;
}
if (mdi_rtn == MDI_NOT_SUPPORTED) {
goto virt_create_done;
}
(void) mdi_pi_free(pip, 0);
} else {
}
}
return (rtn);
}
/*
* iscsi_lun_phys_create - creates solaris logical unit via NDI
*/
static iscsi_status_t
{
int ncompatible = 0;
int circ = 0;
/* get the 'scsi-binding-set' property */
&scsi_binding_set) != DDI_PROP_SUCCESS) {
}
/* generate compatible property */
if (scsi_binding_set)
/* if nodename can't be determined then print a message and skip it */
return (ISCSI_STATUS_INTERNAL_ERROR);
}
/* if lun alloc success, set props */
if (ndi_rtn == NDI_SUCCESS) {
"property for %s lun %d (TARGET_PROP)",
goto phys_create_done;
}
"property for %s lun %d (LUN_PROP)",
goto phys_create_done;
}
!= DDI_PROP_SUCCESS) {
"property for %s lun %d (COMPATIBLE)",
goto phys_create_done;
}
/* If props were setup ok, online the lun */
if (ndi_rtn == NDI_SUCCESS) {
/* Try to online the new node */
}
/* If success set rtn flag, else unwire alloc'd lun */
if (ndi_rtn == NDI_SUCCESS) {
/*
* Assign the instance number for the dev_link
* generator. This will ensure the link name is
* unique and persistent across reboots.
*/
(void) ndi_prop_update_string(DDI_DEV_T_NONE,
} else {
(void) ndi_devi_free(lun_dip);
}
}
return (rtn);
}
/*
* iscsi_lun_online - _di_online logical unit
*
* This is called after a path has recovered it will cause
*/
void
{
int circ = 0;
int rval = 0;
if (rval == MDI_SUCCESS) {
}
if (rval == NDI_SUCCESS) {
}
}
/* Check whether this is the required LUN for iscsi boot */
if (iscsiboot_prop != NULL &&
/*
* During iscsi boot, the boot lun has been
* online, we should set the "online flag".
*/
}
}
}
/*
* If the LUN has been online and it is a disk,
* send out a system event.
*/
DDI_SUCCESS) {
return;
}
} else {
}
DDI_SUCCESS) {
return;
}
}
}
/*
* iscsi_lun_offline - attempt _di_offline [and optional _di_free]
*
* This function is called via two paths. When a transport
* path has failed it will be called to offline the logical
* unit. When nameservice access has been removed it will
* be called to both offline and free the logical unit.
* (This operates soley on the solaris node states.
* iscsi_lun_destroy() should be called when attempting
* to free all iscsi lun resources.)
*
* This function can fail with ISCSI_STATUS_BUSY if the
* logical unit is in use. The user should unmount or
* close the device and perform the nameservice operation
* again if this occurs.
*
* If we fail to offline a LUN that we don't want to destroy,
* we will mark it with invalid state. If this LUN still
* exists on the target, we can have another chance to online
* it again when we do the LUN enumeration.
*/
{
int circ = 0;
int rval;
/*
* Since we carry the logical units parent
* lock across the offline call it will not
* issue devfs_clean() and may fail with a
* devi_ref count > 0.
*/
} else {
}
/*
* Make sure node is attached otherwise
* it won't have related cache nodes to
* clean up. i_ddi_devi_attached is
* similiar to i_ddi_node_state(cdip) >=
* DS_ATTACHED. We should clean up only
* when lun_free is set.
*/
if (i_ddi_devi_attached(cdip)) {
/* Get parent dip */
/* Get full devname */
/* Release lock before devfs_clean() */
/* Clean cache */
}
}
}
/* Attempt to offline the logical units */
} else {
}
if (rval == MDI_SUCCESS) {
}
} else {
}
}
} else {
} else {
}
if (rval != NDI_SUCCESS) {
}
} else {
}
}
DDI_SUCCESS) {
return (status);
}
DDI_SUCCESS) {
return (status);
}
}
}
return (status);
}