17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM * CDDL HEADER START
37836SJohn.Forte@Sun.COM *
47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM *
87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM * and limitations under the License.
127836SJohn.Forte@Sun.COM *
137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM *
197836SJohn.Forte@Sun.COM * CDDL HEADER END
207836SJohn.Forte@Sun.COM */
217836SJohn.Forte@Sun.COM /*
227836SJohn.Forte@Sun.COM * Copyright 2000 by Cisco Systems, Inc. All rights reserved.
2312161SJack.Meng@Sun.COM * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
247836SJohn.Forte@Sun.COM *
257836SJohn.Forte@Sun.COM * iSCSI Software Initiator
267836SJohn.Forte@Sun.COM */
277836SJohn.Forte@Sun.COM
287836SJohn.Forte@Sun.COM /*
297836SJohn.Forte@Sun.COM * Framework interface routines for iSCSI
307836SJohn.Forte@Sun.COM */
319162SPeter.Dunlap@Sun.COM
329162SPeter.Dunlap@Sun.COM #include "iscsi.h" /* main header */
339162SPeter.Dunlap@Sun.COM #include <sys/iscsi_protocol.h> /* protocol structs */
347836SJohn.Forte@Sun.COM #include <sys/scsi/adapters/iscsi_if.h> /* ioctl interfaces */
357836SJohn.Forte@Sun.COM #include "iscsi_targetparam.h"
367836SJohn.Forte@Sun.COM #include "persistent.h"
377836SJohn.Forte@Sun.COM #include <sys/scsi/adapters/iscsi_door.h>
387836SJohn.Forte@Sun.COM #include <sys/dlpi.h>
397836SJohn.Forte@Sun.COM #include <sys/utsname.h>
407836SJohn.Forte@Sun.COM #include "isns_client.h"
417836SJohn.Forte@Sun.COM #include "isns_protocol.h"
428194SJack.Meng@Sun.COM #include <sys/bootprops.h>
439201SJack.Meng@Sun.COM #include <sys/types.h>
449201SJack.Meng@Sun.COM #include <sys/bootconf.h>
457836SJohn.Forte@Sun.COM
467836SJohn.Forte@Sun.COM #define ISCSI_NAME_VERSION "iSCSI Initiator v-1.55"
477836SJohn.Forte@Sun.COM
487836SJohn.Forte@Sun.COM #define MAX_GET_NAME_SIZE 1024
497836SJohn.Forte@Sun.COM #define MAX_NAME_PROP_SIZE 256
507836SJohn.Forte@Sun.COM #define UNDEFINED -1
5110156SZhang.Yi@Sun.COM #define ISCSI_DISC_DELAY 2 /* seconds */
527836SJohn.Forte@Sun.COM
537836SJohn.Forte@Sun.COM /*
547836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
557836SJohn.Forte@Sun.COM * | iscsi globals |
567836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
577836SJohn.Forte@Sun.COM */
587836SJohn.Forte@Sun.COM void *iscsi_state;
597836SJohn.Forte@Sun.COM kmutex_t iscsi_oid_mutex;
607836SJohn.Forte@Sun.COM uint32_t iscsi_oid;
617836SJohn.Forte@Sun.COM int iscsi_nop_delay = ISCSI_DEFAULT_NOP_DELAY;
627836SJohn.Forte@Sun.COM int iscsi_rx_window = ISCSI_DEFAULT_RX_WINDOW;
637836SJohn.Forte@Sun.COM int iscsi_rx_max_window = ISCSI_DEFAULT_RX_MAX_WINDOW;
649162SPeter.Dunlap@Sun.COM boolean_t iscsi_logging = B_FALSE;
657836SJohn.Forte@Sun.COM
668194SJack.Meng@Sun.COM extern ib_boot_prop_t *iscsiboot_prop;
679201SJack.Meng@Sun.COM extern int modrootloaded;
689201SJack.Meng@Sun.COM extern struct bootobj rootfs;
698194SJack.Meng@Sun.COM
707836SJohn.Forte@Sun.COM /*
717836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
727836SJohn.Forte@Sun.COM * | iscsi.c prototypes |
737836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
747836SJohn.Forte@Sun.COM */
757836SJohn.Forte@Sun.COM static int iscsi_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
767836SJohn.Forte@Sun.COM void *arg, void **result);
777836SJohn.Forte@Sun.COM static int iscsi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
787836SJohn.Forte@Sun.COM static int iscsi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
797836SJohn.Forte@Sun.COM
807836SJohn.Forte@Sun.COM /* scsi_tran prototypes */
817836SJohn.Forte@Sun.COM static int iscsi_tran_lun_init(dev_info_t *hba_dip, dev_info_t *lun_dip,
827836SJohn.Forte@Sun.COM scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
837836SJohn.Forte@Sun.COM static int iscsi_tran_lun_probe(struct scsi_device *sd, int (*callback) ());
847836SJohn.Forte@Sun.COM static struct scsi_pkt *iscsi_tran_init_pkt(struct scsi_address *ap,
857836SJohn.Forte@Sun.COM struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
867836SJohn.Forte@Sun.COM int tgtlen, int flags, int (*callback) (), caddr_t arg);
877836SJohn.Forte@Sun.COM static void iscsi_tran_lun_free(dev_info_t *hba_dip, dev_info_t *lun_dip,
887836SJohn.Forte@Sun.COM scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
897836SJohn.Forte@Sun.COM static int iscsi_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt);
907836SJohn.Forte@Sun.COM static int iscsi_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
917836SJohn.Forte@Sun.COM static int iscsi_tran_reset(struct scsi_address *ap, int level);
927836SJohn.Forte@Sun.COM static int iscsi_tran_getcap(struct scsi_address *ap, char *cap, int whom);
937836SJohn.Forte@Sun.COM static int iscsi_tran_setcap(struct scsi_address *ap, char *cap,
947836SJohn.Forte@Sun.COM int value, int whom);
957836SJohn.Forte@Sun.COM static void iscsi_tran_destroy_pkt(struct scsi_address *ap,
967836SJohn.Forte@Sun.COM struct scsi_pkt *pkt);
977836SJohn.Forte@Sun.COM static void iscsi_tran_dmafree(struct scsi_address *ap,
987836SJohn.Forte@Sun.COM struct scsi_pkt *pkt);
997836SJohn.Forte@Sun.COM static void iscsi_tran_sync_pkt(struct scsi_address *ap,
1007836SJohn.Forte@Sun.COM struct scsi_pkt *pkt);
1017836SJohn.Forte@Sun.COM static void iscsi_tran_sync_pkt(struct scsi_address *ap,
1027836SJohn.Forte@Sun.COM struct scsi_pkt *pkt);
1037836SJohn.Forte@Sun.COM static int iscsi_tran_reset_notify(struct scsi_address *ap, int flag,
1047836SJohn.Forte@Sun.COM void (*callback) (caddr_t), caddr_t arg);
1057836SJohn.Forte@Sun.COM static int iscsi_tran_bus_config(dev_info_t *parent, uint_t flags,
1067836SJohn.Forte@Sun.COM ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
1077836SJohn.Forte@Sun.COM static int iscsi_tran_bus_unconfig(dev_info_t *parent, uint_t flags,
1087836SJohn.Forte@Sun.COM ddi_bus_config_op_t op, void *arg);
1097836SJohn.Forte@Sun.COM static int iscsi_tran_get_name(struct scsi_device *sd, char *name, int len);
1107836SJohn.Forte@Sun.COM static int iscsi_tran_get_bus_addr(struct scsi_device *sd, char *name, int len);
1117836SJohn.Forte@Sun.COM
1127836SJohn.Forte@Sun.COM /* bus_ops prototypes */
1137836SJohn.Forte@Sun.COM /* LINTED E_STATIC_UNUSED */
1147836SJohn.Forte@Sun.COM static ddi_intrspec_t iscsi_get_intrspec(dev_info_t *dip, dev_info_t *rdip,
1157836SJohn.Forte@Sun.COM uint_t inumber);
1167836SJohn.Forte@Sun.COM /* LINTED E_STATIC_UNUSED */
1177836SJohn.Forte@Sun.COM static int iscsi_add_intrspec(dev_info_t *dip, dev_info_t *rdip,
1187836SJohn.Forte@Sun.COM ddi_intrspec_t intrspec, ddi_iblock_cookie_t *iblock_cookiep,
1197836SJohn.Forte@Sun.COM ddi_idevice_cookie_t *idevice_cookiep, uint_t (*int_handler)(caddr_t
1207836SJohn.Forte@Sun.COM int_handler_arg), caddr_t int_handler_arg, int kind);
1217836SJohn.Forte@Sun.COM /* LINTED E_STATIC_UNUSED */
1227836SJohn.Forte@Sun.COM static void iscsi_remove_intrspec(dev_info_t *dip, dev_info_t *rdip,
1237836SJohn.Forte@Sun.COM ddi_intrspec_t intrspec, ddi_iblock_cookie_t iblock_cookie);
1247836SJohn.Forte@Sun.COM /* LINTED E_STATIC_UNUSED */
1257836SJohn.Forte@Sun.COM static int iscsi_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop,
1267836SJohn.Forte@Sun.COM void *arg, void *result);
1277836SJohn.Forte@Sun.COM
1287836SJohn.Forte@Sun.COM /* cb_ops prototypes */
1297836SJohn.Forte@Sun.COM static int iscsi_open(dev_t *devp, int flags, int otyp, cred_t *credp);
1307836SJohn.Forte@Sun.COM static int iscsi_close(dev_t dev, int flag, int otyp, cred_t *credp);
1319201SJack.Meng@Sun.COM static int iscsi_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
1327836SJohn.Forte@Sun.COM cred_t *credp, int *rvalp);
1337836SJohn.Forte@Sun.COM
1347836SJohn.Forte@Sun.COM int iscsi_get_persisted_param(uchar_t *name,
1357836SJohn.Forte@Sun.COM iscsi_param_get_t *ipgp,
1367836SJohn.Forte@Sun.COM iscsi_login_params_t *params);
1377836SJohn.Forte@Sun.COM static void iscsi_override_target_default(iscsi_hba_t *ihp,
1387836SJohn.Forte@Sun.COM iscsi_param_get_t *ipg);
1397836SJohn.Forte@Sun.COM
1407836SJohn.Forte@Sun.COM /* scsi_tran helpers */
1417836SJohn.Forte@Sun.COM static int iscsi_virt_lun_init(dev_info_t *hba_dip, dev_info_t *lun_dip,
1427836SJohn.Forte@Sun.COM scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
1437836SJohn.Forte@Sun.COM static int iscsi_phys_lun_init(dev_info_t *hba_dip, dev_info_t *lun_dip,
1447836SJohn.Forte@Sun.COM scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
1457836SJohn.Forte@Sun.COM static int iscsi_i_commoncap(struct scsi_address *ap, char *cap,
1467836SJohn.Forte@Sun.COM int val, int lunonly, int doset);
1477836SJohn.Forte@Sun.COM static void iscsi_get_name_to_iqn(char *name, int name_max_len);
1487836SJohn.Forte@Sun.COM static void iscsi_get_name_from_iqn(char *name, int name_max_len);
1498194SJack.Meng@Sun.COM static boolean_t iscsi_cmp_boot_sess_oid(iscsi_hba_t *ihp, uint32_t oid);
1507836SJohn.Forte@Sun.COM
1519201SJack.Meng@Sun.COM /* iscsi initiator service helpers */
1529201SJack.Meng@Sun.COM static boolean_t iscsi_enter_service_zone(iscsi_hba_t *ihp, uint32_t status);
1539201SJack.Meng@Sun.COM static void iscsi_exit_service_zone(iscsi_hba_t *ihp, uint32_t status);
1549201SJack.Meng@Sun.COM static void iscsi_check_miniroot(iscsi_hba_t *ihp);
15510156SZhang.Yi@Sun.COM static void iscsi_get_tunable_default(iscsi_tunable_object_t *param);
15610156SZhang.Yi@Sun.COM static int iscsi_get_persisted_tunable_param(uchar_t *name,
15710156SZhang.Yi@Sun.COM iscsi_tunable_object_t *tpsg);
15810156SZhang.Yi@Sun.COM static void iscsi_set_default_tunable_params(iscsi_tunable_params_t *params);
1599201SJack.Meng@Sun.COM
1607836SJohn.Forte@Sun.COM /* struct helpers prototypes */
1617836SJohn.Forte@Sun.COM
1627836SJohn.Forte@Sun.COM /*
1637836SJohn.Forte@Sun.COM * At this point this driver doesn't need this structure because nothing
1647836SJohn.Forte@Sun.COM * is done during the open, close or ioctl. Code put in place because
1657836SJohn.Forte@Sun.COM * some admin related work might be done in the ioctl routine.
1667836SJohn.Forte@Sun.COM */
1677836SJohn.Forte@Sun.COM static struct cb_ops iscsi_cb_ops = {
1687836SJohn.Forte@Sun.COM iscsi_open, /* open */
1697836SJohn.Forte@Sun.COM iscsi_close, /* close */
1707836SJohn.Forte@Sun.COM nodev, /* strategy */
1717836SJohn.Forte@Sun.COM nodev, /* print */
1727836SJohn.Forte@Sun.COM nodev, /* dump */
1737836SJohn.Forte@Sun.COM nodev, /* read */
1747836SJohn.Forte@Sun.COM nodev, /* write */
1757836SJohn.Forte@Sun.COM iscsi_ioctl, /* ioctl */
1767836SJohn.Forte@Sun.COM nodev, /* devmap */
1777836SJohn.Forte@Sun.COM nodev, /* mmap */
1787836SJohn.Forte@Sun.COM nodev, /* segmap */
1797836SJohn.Forte@Sun.COM nochpoll, /* poll */
1807836SJohn.Forte@Sun.COM ddi_prop_op, /* prop_op */
1817836SJohn.Forte@Sun.COM NULL, /* streamtab */
1827836SJohn.Forte@Sun.COM D_NEW | D_MP | D_HOTPLUG, /* flags */
1837836SJohn.Forte@Sun.COM CB_REV, /* cb_rev */
1847836SJohn.Forte@Sun.COM nodev, /* aread */
1857836SJohn.Forte@Sun.COM nodev, /* awrite */
1867836SJohn.Forte@Sun.COM };
1877836SJohn.Forte@Sun.COM
1887836SJohn.Forte@Sun.COM static struct dev_ops iscsi_dev_ops = {
1897836SJohn.Forte@Sun.COM DEVO_REV, /* devo_rev */
1907836SJohn.Forte@Sun.COM 0, /* refcnt */
1917836SJohn.Forte@Sun.COM iscsi_getinfo, /* getinfo */
1927836SJohn.Forte@Sun.COM nulldev, /* identify */
1937836SJohn.Forte@Sun.COM nulldev, /* probe */
1947836SJohn.Forte@Sun.COM iscsi_attach, /* attach */
1957836SJohn.Forte@Sun.COM iscsi_detach, /* detach */
1967836SJohn.Forte@Sun.COM nodev, /* reset */
1977836SJohn.Forte@Sun.COM &iscsi_cb_ops, /* driver operations */
1987836SJohn.Forte@Sun.COM NULL, /* bus ops */
1997836SJohn.Forte@Sun.COM NULL, /* power management */
2008614SZhang.Yi@Sun.COM ddi_quiesce_not_needed, /* quiesce */
2017836SJohn.Forte@Sun.COM };
2027836SJohn.Forte@Sun.COM
2037836SJohn.Forte@Sun.COM static struct modldrv modldrv = {
2047836SJohn.Forte@Sun.COM &mod_driverops, /* drv_modops */
2057836SJohn.Forte@Sun.COM ISCSI_NAME_VERSION, /* drv_linkinfo */
2067836SJohn.Forte@Sun.COM &iscsi_dev_ops /* drv_dev_ops */
2077836SJohn.Forte@Sun.COM };
2087836SJohn.Forte@Sun.COM
2097836SJohn.Forte@Sun.COM static struct modlinkage modlinkage = {
2107836SJohn.Forte@Sun.COM MODREV_1, /* ml_rev */
2117836SJohn.Forte@Sun.COM &modldrv, /* ml_linkage[] */
2127836SJohn.Forte@Sun.COM NULL /* NULL termination */
2137836SJohn.Forte@Sun.COM };
2147836SJohn.Forte@Sun.COM
2157836SJohn.Forte@Sun.COM /*
2167836SJohn.Forte@Sun.COM * This structure is bogus. scsi_hba_attach_setup() requires, as in the kernel
2177836SJohn.Forte@Sun.COM * will panic if you don't pass this in to the routine, this information.
2187836SJohn.Forte@Sun.COM * Need to determine what the actual impact to the system is by providing
2197836SJohn.Forte@Sun.COM * this information if any. Since dma allocation is done in pkt_init it may
2207836SJohn.Forte@Sun.COM * not have any impact. These values are straight from the Writing Device
2217836SJohn.Forte@Sun.COM * Driver manual.
2227836SJohn.Forte@Sun.COM */
2237836SJohn.Forte@Sun.COM static ddi_dma_attr_t iscsi_dma_attr = {
2247836SJohn.Forte@Sun.COM DMA_ATTR_V0, /* ddi_dma_attr version */
2257836SJohn.Forte@Sun.COM 0, /* low address */
2267836SJohn.Forte@Sun.COM 0xffffffff, /* high address */
2277836SJohn.Forte@Sun.COM 0x00ffffff, /* counter upper bound */
2287836SJohn.Forte@Sun.COM 1, /* alignment requirements */
2297836SJohn.Forte@Sun.COM 0x3f, /* burst sizes */
2307836SJohn.Forte@Sun.COM 1, /* minimum DMA access */
2317836SJohn.Forte@Sun.COM 0xffffffff, /* maximum DMA access */
2327836SJohn.Forte@Sun.COM (1 << 24) - 1, /* segment boundary restrictions */
2337836SJohn.Forte@Sun.COM 1, /* scater/gather list length */
2347836SJohn.Forte@Sun.COM 512, /* device granularity */
2357836SJohn.Forte@Sun.COM 0 /* DMA flags */
2367836SJohn.Forte@Sun.COM };
2377836SJohn.Forte@Sun.COM
2387836SJohn.Forte@Sun.COM /*
2397836SJohn.Forte@Sun.COM * _init - General driver init entry
2407836SJohn.Forte@Sun.COM */
2417836SJohn.Forte@Sun.COM int
_init(void)2427836SJohn.Forte@Sun.COM _init(void)
2437836SJohn.Forte@Sun.COM {
2447836SJohn.Forte@Sun.COM int rval = 0;
2457836SJohn.Forte@Sun.COM
2467836SJohn.Forte@Sun.COM iscsi_net_init();
2477836SJohn.Forte@Sun.COM
2487836SJohn.Forte@Sun.COM mutex_init(&iscsi_oid_mutex, NULL, MUTEX_DRIVER, NULL);
2497836SJohn.Forte@Sun.COM iscsi_oid = ISCSI_INITIATOR_OID;
2507836SJohn.Forte@Sun.COM
2517836SJohn.Forte@Sun.COM /*
2527836SJohn.Forte@Sun.COM * Set up the soft state structures. If this driver is actually
2537836SJohn.Forte@Sun.COM * being attached to the system then we'll have at least one
2547836SJohn.Forte@Sun.COM * HBA/NIC used.
2557836SJohn.Forte@Sun.COM */
2567836SJohn.Forte@Sun.COM rval = ddi_soft_state_init(&iscsi_state,
2577836SJohn.Forte@Sun.COM sizeof (iscsi_hba_t), 1);
2587836SJohn.Forte@Sun.COM if (rval != 0) {
2597836SJohn.Forte@Sun.COM iscsi_net_fini();
2607836SJohn.Forte@Sun.COM goto init_done;
2617836SJohn.Forte@Sun.COM }
2627836SJohn.Forte@Sun.COM
2637836SJohn.Forte@Sun.COM rval = scsi_hba_init(&modlinkage);
2647836SJohn.Forte@Sun.COM if (rval != 0) {
2657836SJohn.Forte@Sun.COM ddi_soft_state_fini(&iscsi_state);
2667836SJohn.Forte@Sun.COM iscsi_net_fini();
2677836SJohn.Forte@Sun.COM goto init_done;
2687836SJohn.Forte@Sun.COM }
2697836SJohn.Forte@Sun.COM
2707836SJohn.Forte@Sun.COM rval = mod_install(&modlinkage);
2717836SJohn.Forte@Sun.COM if (rval != 0) {
2727836SJohn.Forte@Sun.COM ddi_soft_state_fini(&iscsi_state);
2737836SJohn.Forte@Sun.COM scsi_hba_fini(&modlinkage);
2747836SJohn.Forte@Sun.COM iscsi_net_fini();
2757836SJohn.Forte@Sun.COM goto init_done;
2767836SJohn.Forte@Sun.COM }
2777836SJohn.Forte@Sun.COM (void) iscsi_door_ini();
2787836SJohn.Forte@Sun.COM
2797836SJohn.Forte@Sun.COM init_done:
2807836SJohn.Forte@Sun.COM return (rval);
2817836SJohn.Forte@Sun.COM }
2827836SJohn.Forte@Sun.COM
2837836SJohn.Forte@Sun.COM /*
2847836SJohn.Forte@Sun.COM * _fini - General driver destructor entry
2857836SJohn.Forte@Sun.COM */
2867836SJohn.Forte@Sun.COM int
_fini(void)2877836SJohn.Forte@Sun.COM _fini(void)
2887836SJohn.Forte@Sun.COM {
2897836SJohn.Forte@Sun.COM int rval = 0;
2907836SJohn.Forte@Sun.COM
2917836SJohn.Forte@Sun.COM rval = mod_remove(&modlinkage);
2927836SJohn.Forte@Sun.COM if (rval == 0) {
2937836SJohn.Forte@Sun.COM scsi_hba_fini(&modlinkage);
2947836SJohn.Forte@Sun.COM ddi_soft_state_fini(&iscsi_state);
2957836SJohn.Forte@Sun.COM mutex_destroy(&iscsi_oid_mutex);
2967836SJohn.Forte@Sun.COM (void) iscsi_door_term();
2977836SJohn.Forte@Sun.COM iscsi_net_fini();
2987836SJohn.Forte@Sun.COM }
2997836SJohn.Forte@Sun.COM return (rval);
3007836SJohn.Forte@Sun.COM }
3017836SJohn.Forte@Sun.COM
3027836SJohn.Forte@Sun.COM /*
3037836SJohn.Forte@Sun.COM * _info - General driver info entry
3047836SJohn.Forte@Sun.COM */
3057836SJohn.Forte@Sun.COM int
_info(struct modinfo * mp)3067836SJohn.Forte@Sun.COM _info(struct modinfo *mp)
3077836SJohn.Forte@Sun.COM {
3087836SJohn.Forte@Sun.COM int rval = 0;
3097836SJohn.Forte@Sun.COM
3107836SJohn.Forte@Sun.COM rval = mod_info(&modlinkage, mp);
3117836SJohn.Forte@Sun.COM
3127836SJohn.Forte@Sun.COM return (rval);
3137836SJohn.Forte@Sun.COM }
3147836SJohn.Forte@Sun.COM
3157836SJohn.Forte@Sun.COM
3167836SJohn.Forte@Sun.COM /*
3177836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
3187836SJohn.Forte@Sun.COM * | Start of dev_ops routines |
3197836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
3207836SJohn.Forte@Sun.COM */
3217836SJohn.Forte@Sun.COM
3227836SJohn.Forte@Sun.COM /*
3237836SJohn.Forte@Sun.COM * iscsi_getinfo - returns general driver information
3247836SJohn.Forte@Sun.COM */
3257836SJohn.Forte@Sun.COM /* ARGSUSED */
3267836SJohn.Forte@Sun.COM static int
iscsi_getinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)3277836SJohn.Forte@Sun.COM iscsi_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
3287836SJohn.Forte@Sun.COM void *arg, void **result)
3297836SJohn.Forte@Sun.COM {
3307836SJohn.Forte@Sun.COM int rval = DDI_SUCCESS;
3317836SJohn.Forte@Sun.COM int instance = getminor((dev_t)arg);
3327836SJohn.Forte@Sun.COM iscsi_hba_t *ip;
3337836SJohn.Forte@Sun.COM
3347836SJohn.Forte@Sun.COM switch (infocmd) {
3357836SJohn.Forte@Sun.COM case DDI_INFO_DEVT2DEVINFO:
3367836SJohn.Forte@Sun.COM if ((ip = ddi_get_soft_state(iscsi_state, instance)) == NULL) {
3377836SJohn.Forte@Sun.COM return (DDI_FAILURE);
3387836SJohn.Forte@Sun.COM }
3397836SJohn.Forte@Sun.COM *result = ip->hba_dip;
3407836SJohn.Forte@Sun.COM if (ip->hba_dip == NULL)
3417836SJohn.Forte@Sun.COM rval = DDI_FAILURE;
3427836SJohn.Forte@Sun.COM else
3437836SJohn.Forte@Sun.COM rval = DDI_SUCCESS;
3447836SJohn.Forte@Sun.COM break;
3457836SJohn.Forte@Sun.COM
3467836SJohn.Forte@Sun.COM case DDI_INFO_DEVT2INSTANCE:
3477836SJohn.Forte@Sun.COM *result = (void *)(uintptr_t)instance;
3487836SJohn.Forte@Sun.COM rval = DDI_SUCCESS;
3497836SJohn.Forte@Sun.COM break;
3507836SJohn.Forte@Sun.COM
3517836SJohn.Forte@Sun.COM default:
3527836SJohn.Forte@Sun.COM rval = DDI_FAILURE;
3537836SJohn.Forte@Sun.COM break;
3547836SJohn.Forte@Sun.COM }
3557836SJohn.Forte@Sun.COM return (rval);
3567836SJohn.Forte@Sun.COM }
3577836SJohn.Forte@Sun.COM
3587836SJohn.Forte@Sun.COM
3597836SJohn.Forte@Sun.COM /*
3607836SJohn.Forte@Sun.COM * iscsi_attach -- Attach instance of an iSCSI HBA. We
3617836SJohn.Forte@Sun.COM * will attempt to create our HBA and register it with
3627836SJohn.Forte@Sun.COM * scsi_vhci. If it's not possible to create the HBA
3637836SJohn.Forte@Sun.COM * or register with vhci we will fail the attach.
3647836SJohn.Forte@Sun.COM */
3657836SJohn.Forte@Sun.COM static int
iscsi_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)3667836SJohn.Forte@Sun.COM iscsi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
3677836SJohn.Forte@Sun.COM {
3687836SJohn.Forte@Sun.COM int rval = DDI_SUCCESS;
3697836SJohn.Forte@Sun.COM int instance = ddi_get_instance(dip);
3707836SJohn.Forte@Sun.COM iscsi_hba_t *ihp = NULL;
3717836SJohn.Forte@Sun.COM scsi_hba_tran_t *tran = NULL;
3727836SJohn.Forte@Sun.COM char init_port_name[MAX_NAME_PROP_SIZE];
3737836SJohn.Forte@Sun.COM
3747836SJohn.Forte@Sun.COM switch (cmd) {
3757836SJohn.Forte@Sun.COM case DDI_ATTACH:
3767836SJohn.Forte@Sun.COM /* create iSCSH HBA devctl device node */
3777836SJohn.Forte@Sun.COM if (ddi_create_minor_node(dip, ISCSI_DEVCTL, S_IFCHR, 0,
3787836SJohn.Forte@Sun.COM DDI_PSEUDO, 0) == DDI_SUCCESS) {
3797836SJohn.Forte@Sun.COM
3807836SJohn.Forte@Sun.COM /* allocate HBA soft state */
3817836SJohn.Forte@Sun.COM if (ddi_soft_state_zalloc(iscsi_state, instance) !=
3827836SJohn.Forte@Sun.COM DDI_SUCCESS) {
3837836SJohn.Forte@Sun.COM ddi_remove_minor_node(dip, NULL);
3847836SJohn.Forte@Sun.COM rval = DDI_FAILURE;
3857836SJohn.Forte@Sun.COM break;
3867836SJohn.Forte@Sun.COM }
3877836SJohn.Forte@Sun.COM
3887836SJohn.Forte@Sun.COM /* get reference to soft state */
3897836SJohn.Forte@Sun.COM if ((ihp = (iscsi_hba_t *)ddi_get_soft_state(
3907836SJohn.Forte@Sun.COM iscsi_state, instance)) == NULL) {
3917836SJohn.Forte@Sun.COM ddi_remove_minor_node(dip, NULL);
3927836SJohn.Forte@Sun.COM ddi_soft_state_free(iscsi_state, instance);
3937836SJohn.Forte@Sun.COM rval = DDI_FAILURE;
3947836SJohn.Forte@Sun.COM break;
3957836SJohn.Forte@Sun.COM }
3967836SJohn.Forte@Sun.COM
3977836SJohn.Forte@Sun.COM /* init HBA mutex used to protect discovery events */
3987836SJohn.Forte@Sun.COM mutex_init(&ihp->hba_discovery_events_mutex, NULL,
3997836SJohn.Forte@Sun.COM MUTEX_DRIVER, NULL);
4007836SJohn.Forte@Sun.COM
4019162SPeter.Dunlap@Sun.COM /* Get LDI ident */
4029162SPeter.Dunlap@Sun.COM rval = ldi_ident_from_dip(dip, &ihp->hba_li);
4039162SPeter.Dunlap@Sun.COM ASSERT(rval == 0); /* Failure indicates invalid arg */
4049162SPeter.Dunlap@Sun.COM
4059201SJack.Meng@Sun.COM /* init HBA mutex used to protect service status */
4069201SJack.Meng@Sun.COM mutex_init(&ihp->hba_service_lock, NULL,
4079201SJack.Meng@Sun.COM MUTEX_DRIVER, NULL);
4089201SJack.Meng@Sun.COM cv_init(&ihp->hba_service_cv, NULL, CV_DRIVER, NULL);
4099201SJack.Meng@Sun.COM
4107836SJohn.Forte@Sun.COM /*
4117836SJohn.Forte@Sun.COM * init SendTargets semaphore that is used to allow
4127836SJohn.Forte@Sun.COM * only one operation at a time
4137836SJohn.Forte@Sun.COM */
4147836SJohn.Forte@Sun.COM sema_init(&ihp->hba_sendtgts_semaphore, 1, NULL,
4157836SJohn.Forte@Sun.COM SEMA_DRIVER, NULL);
4167836SJohn.Forte@Sun.COM
4177836SJohn.Forte@Sun.COM ihp->hba_sess_list = NULL;
4187836SJohn.Forte@Sun.COM rw_init(&ihp->hba_sess_list_rwlock, NULL,
4197836SJohn.Forte@Sun.COM RW_DRIVER, NULL);
4207836SJohn.Forte@Sun.COM
4217836SJohn.Forte@Sun.COM /* allocate scsi_hba_tran */
4227836SJohn.Forte@Sun.COM if ((tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP))
4237836SJohn.Forte@Sun.COM == NULL) {
4247836SJohn.Forte@Sun.COM ddi_remove_minor_node(dip, NULL);
4257836SJohn.Forte@Sun.COM goto iscsi_attach_failed2;
4267836SJohn.Forte@Sun.COM }
4277836SJohn.Forte@Sun.COM
4287836SJohn.Forte@Sun.COM /* soft state setup */
4297836SJohn.Forte@Sun.COM ihp->hba_sig = ISCSI_SIG_HBA;
4307836SJohn.Forte@Sun.COM ihp->hba_tran = tran;
4317836SJohn.Forte@Sun.COM ihp->hba_dip = dip;
4329712SJack.Meng@Sun.COM if (iscsiboot_prop == NULL) {
4339712SJack.Meng@Sun.COM ihp->hba_service_status =
4349712SJack.Meng@Sun.COM ISCSI_SERVICE_DISABLED;
43510185SJack.Meng@Sun.COM ihp->hba_service_status_overwrite = B_FALSE;
4369712SJack.Meng@Sun.COM } else {
4379712SJack.Meng@Sun.COM ihp->hba_service_status =
4389712SJack.Meng@Sun.COM ISCSI_SERVICE_ENABLED;
43910185SJack.Meng@Sun.COM ihp->hba_service_status_overwrite = B_TRUE;
4409712SJack.Meng@Sun.COM }
4419201SJack.Meng@Sun.COM ihp->hba_service_client_count = 0;
4427836SJohn.Forte@Sun.COM
4437836SJohn.Forte@Sun.COM mutex_enter(&iscsi_oid_mutex);
4447836SJohn.Forte@Sun.COM ihp->hba_oid = iscsi_oid++;
4457836SJohn.Forte@Sun.COM mutex_exit(&iscsi_oid_mutex);
4467836SJohn.Forte@Sun.COM
4477836SJohn.Forte@Sun.COM ihp->hba_name[0] = '\0';
4487836SJohn.Forte@Sun.COM ihp->hba_name_length = 0;
4497836SJohn.Forte@Sun.COM ihp->hba_alias_length = 0;
4507836SJohn.Forte@Sun.COM ihp->hba_alias[0] = '\0';
4517836SJohn.Forte@Sun.COM
4527836SJohn.Forte@Sun.COM iscsi_net->tweaks.rcvbuf = ddi_prop_get_int(
4537836SJohn.Forte@Sun.COM DDI_DEV_T_ANY, ihp->hba_dip, 0, "so-rcvbuf",
4547836SJohn.Forte@Sun.COM ISCSI_SOCKET_RCVBUF_SIZE);
4557836SJohn.Forte@Sun.COM
4567836SJohn.Forte@Sun.COM iscsi_net->tweaks.sndbuf = ddi_prop_get_int(
4577836SJohn.Forte@Sun.COM DDI_DEV_T_ANY, ihp->hba_dip, 0, "so-sndbuf",
4587836SJohn.Forte@Sun.COM ISCSI_SOCKET_SNDBUF_SIZE);
4597836SJohn.Forte@Sun.COM
4607836SJohn.Forte@Sun.COM iscsi_net->tweaks.nodelay = ddi_prop_get_int(
4617836SJohn.Forte@Sun.COM DDI_DEV_T_ANY, ihp->hba_dip, 0, "tcp-nodelay",
4627836SJohn.Forte@Sun.COM ISCSI_TCP_NODELAY_DEFAULT);
4637836SJohn.Forte@Sun.COM
4647836SJohn.Forte@Sun.COM iscsi_net->tweaks.conn_notify_threshold =
4657836SJohn.Forte@Sun.COM ddi_prop_get_int(DDI_DEV_T_ANY,
4667836SJohn.Forte@Sun.COM ihp->hba_dip, 0, "tcp-conn-notify-threshold",
4677836SJohn.Forte@Sun.COM ISCSI_TCP_CNOTIFY_THRESHOLD_DEFAULT);
4687836SJohn.Forte@Sun.COM
4697836SJohn.Forte@Sun.COM iscsi_net->tweaks.conn_abort_threshold =
4707836SJohn.Forte@Sun.COM ddi_prop_get_int(DDI_DEV_T_ANY, ihp->hba_dip,
4717836SJohn.Forte@Sun.COM 0, "tcp-conn-abort-threshold",
4727836SJohn.Forte@Sun.COM ISCSI_TCP_CABORT_THRESHOLD_DEFAULT);
4737836SJohn.Forte@Sun.COM
4747836SJohn.Forte@Sun.COM iscsi_net->tweaks.abort_threshold = ddi_prop_get_int(
4757836SJohn.Forte@Sun.COM DDI_DEV_T_ANY, ihp->hba_dip, 0,
4767836SJohn.Forte@Sun.COM "tcp-abort-threshold",
4777836SJohn.Forte@Sun.COM ISCSI_TCP_ABORT_THRESHOLD_DEFAULT);
4787836SJohn.Forte@Sun.COM
4797836SJohn.Forte@Sun.COM ihp->hba_config_storm_delay = ddi_prop_get_int(
4807836SJohn.Forte@Sun.COM DDI_DEV_T_ANY, ihp->hba_dip, 0,
4817836SJohn.Forte@Sun.COM "config-storm-delay",
4827836SJohn.Forte@Sun.COM ISCSI_CONFIG_STORM_DELAY_DEFAULT);
4837836SJohn.Forte@Sun.COM
4847836SJohn.Forte@Sun.COM (void) ddi_prop_update_int(DDI_DEV_T_NONE, ihp->hba_dip,
4857836SJohn.Forte@Sun.COM "so-rcvbuf", iscsi_net->tweaks.rcvbuf);
4867836SJohn.Forte@Sun.COM
4877836SJohn.Forte@Sun.COM (void) ddi_prop_update_int(DDI_DEV_T_NONE, ihp->hba_dip,
4887836SJohn.Forte@Sun.COM "so-sndbuf", iscsi_net->tweaks.sndbuf);
4897836SJohn.Forte@Sun.COM
4907836SJohn.Forte@Sun.COM (void) ddi_prop_update_int(DDI_DEV_T_NONE, ihp->hba_dip,
4917836SJohn.Forte@Sun.COM "tcp-nodelay", iscsi_net->tweaks.nodelay);
4927836SJohn.Forte@Sun.COM
4937836SJohn.Forte@Sun.COM (void) ddi_prop_update_int(DDI_DEV_T_NONE, ihp->hba_dip,
4947836SJohn.Forte@Sun.COM "tcp-conn-notify-threshold",
4957836SJohn.Forte@Sun.COM iscsi_net->tweaks.conn_notify_threshold);
4967836SJohn.Forte@Sun.COM
4977836SJohn.Forte@Sun.COM (void) ddi_prop_update_int(DDI_DEV_T_NONE, ihp->hba_dip,
4987836SJohn.Forte@Sun.COM "tcp-conn-abort-threshold",
4997836SJohn.Forte@Sun.COM iscsi_net->tweaks.conn_abort_threshold);
5007836SJohn.Forte@Sun.COM
5017836SJohn.Forte@Sun.COM (void) ddi_prop_update_int(DDI_DEV_T_NONE, ihp->hba_dip,
5027836SJohn.Forte@Sun.COM "tcp-abort-threshold",
5037836SJohn.Forte@Sun.COM iscsi_net->tweaks.abort_threshold);
5047836SJohn.Forte@Sun.COM
5057836SJohn.Forte@Sun.COM (void) ddi_prop_update_int(DDI_DEV_T_NONE, ihp->hba_dip,
5067836SJohn.Forte@Sun.COM "config-storm-delay",
5077836SJohn.Forte@Sun.COM ihp->hba_config_storm_delay);
5087836SJohn.Forte@Sun.COM
5097836SJohn.Forte@Sun.COM /* setup hba defaults */
5107836SJohn.Forte@Sun.COM iscsi_set_default_login_params(&ihp->hba_params);
51110156SZhang.Yi@Sun.COM iscsi_set_default_tunable_params(
51210156SZhang.Yi@Sun.COM &ihp->hba_tunable_params);
5137836SJohn.Forte@Sun.COM
5149429SJack.Meng@Sun.COM /* setup minimal initiator params */
5159429SJack.Meng@Sun.COM iscsid_set_default_initiator_node_settings(ihp, B_TRUE);
5169429SJack.Meng@Sun.COM
5177836SJohn.Forte@Sun.COM /* hba set up */
5187836SJohn.Forte@Sun.COM tran->tran_hba_private = ihp;
5197836SJohn.Forte@Sun.COM tran->tran_tgt_private = NULL;
5207836SJohn.Forte@Sun.COM tran->tran_tgt_init = iscsi_tran_lun_init;
5217836SJohn.Forte@Sun.COM tran->tran_tgt_probe = iscsi_tran_lun_probe;
5227836SJohn.Forte@Sun.COM tran->tran_tgt_free = iscsi_tran_lun_free;
5237836SJohn.Forte@Sun.COM tran->tran_start = iscsi_tran_start;
5247836SJohn.Forte@Sun.COM tran->tran_abort = iscsi_tran_abort;
5257836SJohn.Forte@Sun.COM tran->tran_reset = iscsi_tran_reset;
5267836SJohn.Forte@Sun.COM tran->tran_getcap = iscsi_tran_getcap;
5277836SJohn.Forte@Sun.COM tran->tran_setcap = iscsi_tran_setcap;
5287836SJohn.Forte@Sun.COM tran->tran_init_pkt = iscsi_tran_init_pkt;
5297836SJohn.Forte@Sun.COM tran->tran_destroy_pkt = iscsi_tran_destroy_pkt;
5307836SJohn.Forte@Sun.COM tran->tran_dmafree = iscsi_tran_dmafree;
5317836SJohn.Forte@Sun.COM tran->tran_sync_pkt = iscsi_tran_sync_pkt;
5327836SJohn.Forte@Sun.COM tran->tran_reset_notify = iscsi_tran_reset_notify;
5337836SJohn.Forte@Sun.COM tran->tran_bus_config = iscsi_tran_bus_config;
5347836SJohn.Forte@Sun.COM tran->tran_bus_unconfig = iscsi_tran_bus_unconfig;
5357836SJohn.Forte@Sun.COM
5367836SJohn.Forte@Sun.COM tran->tran_get_name = iscsi_tran_get_name;
5377836SJohn.Forte@Sun.COM tran->tran_get_bus_addr = iscsi_tran_get_bus_addr;
5387836SJohn.Forte@Sun.COM tran->tran_interconnect_type = INTERCONNECT_ISCSI;
5397836SJohn.Forte@Sun.COM
5407836SJohn.Forte@Sun.COM /* register scsi hba with scsa */
5417836SJohn.Forte@Sun.COM if (scsi_hba_attach_setup(dip, &iscsi_dma_attr,
5427836SJohn.Forte@Sun.COM tran, SCSI_HBA_TRAN_CLONE) != DDI_SUCCESS) {
5437836SJohn.Forte@Sun.COM goto iscsi_attach_failed1;
5447836SJohn.Forte@Sun.COM }
5457836SJohn.Forte@Sun.COM
5467836SJohn.Forte@Sun.COM /* register scsi hba with mdi (MPxIO/vhci) */
5477836SJohn.Forte@Sun.COM if (mdi_phci_register(MDI_HCI_CLASS_SCSI, dip, 0) !=
5487836SJohn.Forte@Sun.COM MDI_SUCCESS) {
5497836SJohn.Forte@Sun.COM ihp->hba_mpxio_enabled = B_FALSE;
5507836SJohn.Forte@Sun.COM } else {
5517836SJohn.Forte@Sun.COM ihp->hba_mpxio_enabled = B_TRUE;
5527836SJohn.Forte@Sun.COM }
5537836SJohn.Forte@Sun.COM
5547836SJohn.Forte@Sun.COM (void) iscsi_hba_kstat_init(ihp);
5557836SJohn.Forte@Sun.COM
5567836SJohn.Forte@Sun.COM /* Initialize targetparam list */
5577836SJohn.Forte@Sun.COM iscsi_targetparam_init();
5587836SJohn.Forte@Sun.COM
5597836SJohn.Forte@Sun.COM /* Initialize ISID */
5607836SJohn.Forte@Sun.COM ihp->hba_isid[0] = ISCSI_SUN_ISID_0;
5617836SJohn.Forte@Sun.COM ihp->hba_isid[1] = ISCSI_SUN_ISID_1;
5627836SJohn.Forte@Sun.COM ihp->hba_isid[2] = ISCSI_SUN_ISID_2;
5637836SJohn.Forte@Sun.COM ihp->hba_isid[3] = ISCSI_SUN_ISID_3;
5647836SJohn.Forte@Sun.COM ihp->hba_isid[4] = ISCSI_SUN_ISID_4;
5657836SJohn.Forte@Sun.COM ihp->hba_isid[5] = ISCSI_SUN_ISID_5;
5667836SJohn.Forte@Sun.COM
5677836SJohn.Forte@Sun.COM /* Setup iSNS transport services and client */
5687836SJohn.Forte@Sun.COM isns_client_init();
5697836SJohn.Forte@Sun.COM
5707836SJohn.Forte@Sun.COM /*
5719201SJack.Meng@Sun.COM * initialize persistent store,
5729201SJack.Meng@Sun.COM * or boot target info in case of iscsi boot
5737836SJohn.Forte@Sun.COM */
5749201SJack.Meng@Sun.COM ihp->hba_persistent_loaded = B_FALSE;
5759201SJack.Meng@Sun.COM if (iscsid_init(ihp) == B_FALSE) {
5767836SJohn.Forte@Sun.COM goto iscsi_attach_failed0;
5777836SJohn.Forte@Sun.COM }
5787836SJohn.Forte@Sun.COM
5797836SJohn.Forte@Sun.COM /* Setup init_port_name for MPAPI */
5807836SJohn.Forte@Sun.COM (void) snprintf(init_port_name, MAX_NAME_PROP_SIZE,
5817836SJohn.Forte@Sun.COM "%s,%02x%02x%02x%02x%02x%02x",
5827836SJohn.Forte@Sun.COM (char *)ihp->hba_name, ihp->hba_isid[0],
5837836SJohn.Forte@Sun.COM ihp->hba_isid[1], ihp->hba_isid[2],
5847836SJohn.Forte@Sun.COM ihp->hba_isid[3], ihp->hba_isid[4],
5857836SJohn.Forte@Sun.COM ihp->hba_isid[5]);
5867836SJohn.Forte@Sun.COM
5877836SJohn.Forte@Sun.COM if (ddi_prop_update_string(DDI_DEV_T_NONE, dip,
58810696SDavid.Hollister@Sun.COM SCSI_ADDR_PROP_INITIATOR_PORT, init_port_name) !=
5897836SJohn.Forte@Sun.COM DDI_PROP_SUCCESS) {
5907836SJohn.Forte@Sun.COM cmn_err(CE_WARN, "iscsi_attach: Creating "
59110696SDavid.Hollister@Sun.COM SCSI_ADDR_PROP_INITIATOR_PORT
59210696SDavid.Hollister@Sun.COM " property on iSCSI "
5937836SJohn.Forte@Sun.COM "HBA(%s) with dip(%d) Failed",
5947836SJohn.Forte@Sun.COM (char *)ihp->hba_name,
5957836SJohn.Forte@Sun.COM ddi_get_instance(dip));
5967836SJohn.Forte@Sun.COM }
5977836SJohn.Forte@Sun.COM
5987836SJohn.Forte@Sun.COM ddi_report_dev(dip);
5997836SJohn.Forte@Sun.COM } else {
6007836SJohn.Forte@Sun.COM rval = DDI_FAILURE;
6017836SJohn.Forte@Sun.COM }
6027836SJohn.Forte@Sun.COM break;
6037836SJohn.Forte@Sun.COM
6047836SJohn.Forte@Sun.COM iscsi_attach_failed0:
6057836SJohn.Forte@Sun.COM isns_client_cleanup();
6067836SJohn.Forte@Sun.COM if (ihp->stats.ks) {
6077836SJohn.Forte@Sun.COM (void) iscsi_hba_kstat_term(ihp);
6087836SJohn.Forte@Sun.COM }
6097836SJohn.Forte@Sun.COM if (ihp->hba_mpxio_enabled == B_TRUE) {
6107836SJohn.Forte@Sun.COM (void) mdi_phci_unregister(dip, 0);
6117836SJohn.Forte@Sun.COM }
6127836SJohn.Forte@Sun.COM (void) scsi_hba_detach(ihp->hba_dip);
6137836SJohn.Forte@Sun.COM iscsi_attach_failed1:
6147836SJohn.Forte@Sun.COM ddi_remove_minor_node(dip, NULL);
6157836SJohn.Forte@Sun.COM ddi_prop_remove_all(ihp->hba_dip);
6167836SJohn.Forte@Sun.COM scsi_hba_tran_free(tran);
6177836SJohn.Forte@Sun.COM iscsi_attach_failed2:
6189201SJack.Meng@Sun.COM cv_destroy(&ihp->hba_service_cv);
6199201SJack.Meng@Sun.COM mutex_destroy(&ihp->hba_service_lock);
6207836SJohn.Forte@Sun.COM mutex_destroy(&ihp->hba_discovery_events_mutex);
6217836SJohn.Forte@Sun.COM sema_destroy(&ihp->hba_sendtgts_semaphore);
6227836SJohn.Forte@Sun.COM rw_destroy(&ihp->hba_sess_list_rwlock);
6237836SJohn.Forte@Sun.COM ddi_soft_state_free(iscsi_state, instance);
6247836SJohn.Forte@Sun.COM rval = DDI_FAILURE;
6257836SJohn.Forte@Sun.COM break;
6267836SJohn.Forte@Sun.COM
6277836SJohn.Forte@Sun.COM case DDI_RESUME:
6287836SJohn.Forte@Sun.COM break;
6297836SJohn.Forte@Sun.COM
6307836SJohn.Forte@Sun.COM default:
6317836SJohn.Forte@Sun.COM rval = DDI_FAILURE;
6327836SJohn.Forte@Sun.COM }
6337836SJohn.Forte@Sun.COM
6347836SJohn.Forte@Sun.COM if (rval != DDI_SUCCESS) {
6357836SJohn.Forte@Sun.COM cmn_err(CE_WARN, "iscsi driver unable to attach "
6367836SJohn.Forte@Sun.COM "hba instance %d", instance);
6377836SJohn.Forte@Sun.COM }
6387836SJohn.Forte@Sun.COM
6397836SJohn.Forte@Sun.COM return (rval);
6407836SJohn.Forte@Sun.COM }
6417836SJohn.Forte@Sun.COM
6427836SJohn.Forte@Sun.COM /*
6437836SJohn.Forte@Sun.COM * iscsi_detach - called on unload of hba instance
6447836SJohn.Forte@Sun.COM */
6457836SJohn.Forte@Sun.COM static int
iscsi_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)6467836SJohn.Forte@Sun.COM iscsi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
6477836SJohn.Forte@Sun.COM {
6487836SJohn.Forte@Sun.COM int rval = DDI_SUCCESS;
6497836SJohn.Forte@Sun.COM scsi_hba_tran_t *tran = NULL;
6507836SJohn.Forte@Sun.COM iscsi_hba_t *ihp = NULL;
6517836SJohn.Forte@Sun.COM iscsi_hba_t *ihp_check = NULL;
6527836SJohn.Forte@Sun.COM int instance;
6537836SJohn.Forte@Sun.COM char *init_node_name;
6547836SJohn.Forte@Sun.COM
6557836SJohn.Forte@Sun.COM instance = ddi_get_instance(dip);
6567836SJohn.Forte@Sun.COM
6577836SJohn.Forte@Sun.COM switch (cmd) {
6587836SJohn.Forte@Sun.COM case DDI_DETACH:
6597836SJohn.Forte@Sun.COM if (!(tran = (scsi_hba_tran_t *)ddi_get_driver_private(dip))) {
6607836SJohn.Forte@Sun.COM rval = DDI_SUCCESS;
6617836SJohn.Forte@Sun.COM break;
6627836SJohn.Forte@Sun.COM }
6637836SJohn.Forte@Sun.COM
6647836SJohn.Forte@Sun.COM if ((ihp = (iscsi_hba_t *)tran->tran_hba_private) == NULL) {
6657836SJohn.Forte@Sun.COM rval = DDI_FAILURE;
6667836SJohn.Forte@Sun.COM break;
6677836SJohn.Forte@Sun.COM }
6687836SJohn.Forte@Sun.COM
6697836SJohn.Forte@Sun.COM /*
6707836SJohn.Forte@Sun.COM * Validate that what is stored by the DDI framework is still
6717836SJohn.Forte@Sun.COM * the same state structure referenced by the SCSI framework
6727836SJohn.Forte@Sun.COM */
6737836SJohn.Forte@Sun.COM ihp_check = ddi_get_soft_state(iscsi_state, instance);
6747836SJohn.Forte@Sun.COM if (ihp_check != ihp) {
6757836SJohn.Forte@Sun.COM rval = DDI_FAILURE;
6767836SJohn.Forte@Sun.COM break;
6777836SJohn.Forte@Sun.COM }
6787836SJohn.Forte@Sun.COM
6797836SJohn.Forte@Sun.COM /* If a session exists we can't safely detach */
6807836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
6817836SJohn.Forte@Sun.COM if (ihp->hba_sess_list != NULL) {
6827836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
6837836SJohn.Forte@Sun.COM rval = DDI_FAILURE;
6847836SJohn.Forte@Sun.COM break;
6857836SJohn.Forte@Sun.COM }
6867836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
6877836SJohn.Forte@Sun.COM
6887836SJohn.Forte@Sun.COM /* Disable all discovery services */
6897836SJohn.Forte@Sun.COM if (iscsid_disable_discovery(ihp,
6907836SJohn.Forte@Sun.COM ISCSI_ALL_DISCOVERY_METHODS) == B_FALSE) {
6917836SJohn.Forte@Sun.COM /* Disable failed. Fail detach */
6927836SJohn.Forte@Sun.COM rval = DDI_FAILURE;
6937836SJohn.Forte@Sun.COM break;
6947836SJohn.Forte@Sun.COM }
6957836SJohn.Forte@Sun.COM
6967836SJohn.Forte@Sun.COM /* Deregister from iSNS server(s). */
6977836SJohn.Forte@Sun.COM init_node_name = kmem_zalloc(ISCSI_MAX_NAME_LEN, KM_SLEEP);
6987836SJohn.Forte@Sun.COM if (persistent_initiator_name_get(init_node_name,
6997836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN) == B_TRUE) {
7007836SJohn.Forte@Sun.COM if (strlen(init_node_name) > 0) {
7017836SJohn.Forte@Sun.COM (void) isns_dereg(ihp->hba_isid,
7027836SJohn.Forte@Sun.COM (uint8_t *)init_node_name);
7037836SJohn.Forte@Sun.COM }
7047836SJohn.Forte@Sun.COM }
7057836SJohn.Forte@Sun.COM kmem_free(init_node_name, ISCSI_MAX_NAME_LEN);
7067836SJohn.Forte@Sun.COM init_node_name = NULL;
7077836SJohn.Forte@Sun.COM
7087836SJohn.Forte@Sun.COM /* Cleanup iSNS Client */
7097836SJohn.Forte@Sun.COM isns_client_cleanup();
7107836SJohn.Forte@Sun.COM
7117836SJohn.Forte@Sun.COM iscsi_targetparam_cleanup();
7127836SJohn.Forte@Sun.COM
7137836SJohn.Forte@Sun.COM /* Cleanup iscsid resources */
7147836SJohn.Forte@Sun.COM iscsid_fini();
7157836SJohn.Forte@Sun.COM
7167836SJohn.Forte@Sun.COM if (rval != DDI_SUCCESS) {
7177836SJohn.Forte@Sun.COM break;
7187836SJohn.Forte@Sun.COM }
7197836SJohn.Forte@Sun.COM /* kstat hba. destroy */
7207836SJohn.Forte@Sun.COM KSTAT_DEC_HBA_CNTR_SESS(ihp);
7217836SJohn.Forte@Sun.COM
7227836SJohn.Forte@Sun.COM if (ihp->hba_mpxio_enabled == B_TRUE) {
7237836SJohn.Forte@Sun.COM (void) mdi_phci_unregister(dip, 0);
7247836SJohn.Forte@Sun.COM }
7257836SJohn.Forte@Sun.COM ddi_remove_minor_node(dip, NULL);
7267836SJohn.Forte@Sun.COM
7277836SJohn.Forte@Sun.COM ddi_prop_remove_all(ihp->hba_dip);
7289162SPeter.Dunlap@Sun.COM
7299162SPeter.Dunlap@Sun.COM ldi_ident_release(ihp->hba_li);
7309162SPeter.Dunlap@Sun.COM
7319201SJack.Meng@Sun.COM cv_destroy(&ihp->hba_service_cv);
7329201SJack.Meng@Sun.COM mutex_destroy(&ihp->hba_service_lock);
7337836SJohn.Forte@Sun.COM mutex_destroy(&ihp->hba_discovery_events_mutex);
7347836SJohn.Forte@Sun.COM rw_destroy(&ihp->hba_sess_list_rwlock);
7357836SJohn.Forte@Sun.COM (void) iscsi_hba_kstat_term(ihp);
7367836SJohn.Forte@Sun.COM
7377836SJohn.Forte@Sun.COM (void) scsi_hba_detach(dip);
7387836SJohn.Forte@Sun.COM if (tran != NULL) {
7397836SJohn.Forte@Sun.COM scsi_hba_tran_free(tran);
7407836SJohn.Forte@Sun.COM }
7417836SJohn.Forte@Sun.COM ddi_soft_state_free(iscsi_state, instance);
7427836SJohn.Forte@Sun.COM break;
7437836SJohn.Forte@Sun.COM default:
7447836SJohn.Forte@Sun.COM break;
7457836SJohn.Forte@Sun.COM }
7467836SJohn.Forte@Sun.COM
7477836SJohn.Forte@Sun.COM if (rval != DDI_SUCCESS) {
7487836SJohn.Forte@Sun.COM cmn_err(CE_WARN, "iscsi driver unable to "
7497836SJohn.Forte@Sun.COM "detach hba instance %d", instance);
7507836SJohn.Forte@Sun.COM }
7517836SJohn.Forte@Sun.COM
7527836SJohn.Forte@Sun.COM return (rval);
7537836SJohn.Forte@Sun.COM }
7547836SJohn.Forte@Sun.COM
7557836SJohn.Forte@Sun.COM /*
7567836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
7577836SJohn.Forte@Sun.COM * | End of dev_ops routines |
7587836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
7597836SJohn.Forte@Sun.COM */
7607836SJohn.Forte@Sun.COM
7617836SJohn.Forte@Sun.COM /*
7627836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
7637836SJohn.Forte@Sun.COM * | scsi_tran(9E) routines |
7647836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
7657836SJohn.Forte@Sun.COM */
7667836SJohn.Forte@Sun.COM
7677836SJohn.Forte@Sun.COM /*
7687836SJohn.Forte@Sun.COM * iscsi_tran_lun_init - Find target device based on SCSI device
7697836SJohn.Forte@Sun.COM * Based on the information given (SCSI device, target dev_info) find
7707836SJohn.Forte@Sun.COM * the target iSCSI device and put a pointer to that information in
7717836SJohn.Forte@Sun.COM * the scsi_hba_tran_t structure.
7727836SJohn.Forte@Sun.COM */
7737836SJohn.Forte@Sun.COM static int
iscsi_tran_lun_init(dev_info_t * hba_dip,dev_info_t * lun_dip,scsi_hba_tran_t * hba_tran,struct scsi_device * sd)7747836SJohn.Forte@Sun.COM iscsi_tran_lun_init(dev_info_t *hba_dip, dev_info_t *lun_dip,
7757836SJohn.Forte@Sun.COM scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
7767836SJohn.Forte@Sun.COM {
7777836SJohn.Forte@Sun.COM int rval = 0;
7787836SJohn.Forte@Sun.COM int type = 0;
7797836SJohn.Forte@Sun.COM
7807836SJohn.Forte@Sun.COM ASSERT(hba_tran->tran_hba_private != NULL);
7817836SJohn.Forte@Sun.COM
7827836SJohn.Forte@Sun.COM /*
7837836SJohn.Forte@Sun.COM * Child node is getting initialized. Look at the mpxio component
7847836SJohn.Forte@Sun.COM * type on the child device to see if this device is mpxio managed
7857836SJohn.Forte@Sun.COM * or not.
7867836SJohn.Forte@Sun.COM */
7877836SJohn.Forte@Sun.COM type = mdi_get_component_type(lun_dip);
7887836SJohn.Forte@Sun.COM if (type != MDI_COMPONENT_CLIENT) {
7897836SJohn.Forte@Sun.COM rval = iscsi_phys_lun_init(hba_dip, lun_dip, hba_tran, sd);
7907836SJohn.Forte@Sun.COM } else {
7917836SJohn.Forte@Sun.COM rval = iscsi_virt_lun_init(hba_dip, lun_dip, hba_tran, sd);
7927836SJohn.Forte@Sun.COM }
7937836SJohn.Forte@Sun.COM
7947836SJohn.Forte@Sun.COM return (rval);
7957836SJohn.Forte@Sun.COM }
7967836SJohn.Forte@Sun.COM
7977836SJohn.Forte@Sun.COM /*
7987836SJohn.Forte@Sun.COM * iscsi_tran_lun_probe - This function didn't need to be implemented.
7997836SJohn.Forte@Sun.COM * We could have left NULL in the tran table. Since this isn't a
8007836SJohn.Forte@Sun.COM * performance path this seems safe. We are just wrappering the
8017836SJohn.Forte@Sun.COM * function so we can see the call go through if we have debugging
8027836SJohn.Forte@Sun.COM * enabled.
8037836SJohn.Forte@Sun.COM */
8047836SJohn.Forte@Sun.COM static int
iscsi_tran_lun_probe(struct scsi_device * sd,int (* callback)())8057836SJohn.Forte@Sun.COM iscsi_tran_lun_probe(struct scsi_device *sd, int (*callback) ())
8067836SJohn.Forte@Sun.COM {
8077836SJohn.Forte@Sun.COM int rval = 0;
8087836SJohn.Forte@Sun.COM
8097836SJohn.Forte@Sun.COM rval = scsi_hba_probe(sd, callback);
8107836SJohn.Forte@Sun.COM
8117836SJohn.Forte@Sun.COM return (rval);
8127836SJohn.Forte@Sun.COM }
8137836SJohn.Forte@Sun.COM
8147836SJohn.Forte@Sun.COM /*
8157836SJohn.Forte@Sun.COM * iscsi_init_pkt - Allocate SCSI packet and fill in required info.
8167836SJohn.Forte@Sun.COM */
8177836SJohn.Forte@Sun.COM /* ARGSUSED */
8187836SJohn.Forte@Sun.COM static struct scsi_pkt *
iscsi_tran_init_pkt(struct scsi_address * ap,struct scsi_pkt * pkt,struct buf * bp,int cmdlen,int statuslen,int tgtlen,int flags,int (* callback)(),caddr_t arg)8197836SJohn.Forte@Sun.COM iscsi_tran_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
8207836SJohn.Forte@Sun.COM struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags,
8217836SJohn.Forte@Sun.COM int (*callback) (), caddr_t arg)
8227836SJohn.Forte@Sun.COM {
8237836SJohn.Forte@Sun.COM iscsi_lun_t *ilp;
8247836SJohn.Forte@Sun.COM iscsi_cmd_t *icmdp;
8257836SJohn.Forte@Sun.COM
8267836SJohn.Forte@Sun.COM ASSERT(ap != NULL);
8277836SJohn.Forte@Sun.COM ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
8287836SJohn.Forte@Sun.COM
8297836SJohn.Forte@Sun.COM /*
8307836SJohn.Forte@Sun.COM * The software stack doesn't have DMA which means the iSCSI
8317836SJohn.Forte@Sun.COM * protocol layer will be doing a bcopy from bp to outgoing
8327836SJohn.Forte@Sun.COM * streams buffers. Make sure that the buffer is mapped in
8337836SJohn.Forte@Sun.COM * so that the copy won't panic the system.
8347836SJohn.Forte@Sun.COM */
8358267SJack.Meng@Sun.COM if (bp && (bp->b_bcount != 0) &&
8368267SJack.Meng@Sun.COM bp_mapin_common(bp, (callback == NULL_FUNC) ?
8377836SJohn.Forte@Sun.COM VM_NOSLEEP : VM_SLEEP) == NULL) {
8387836SJohn.Forte@Sun.COM return (NULL);
8397836SJohn.Forte@Sun.COM }
8407836SJohn.Forte@Sun.COM
8417836SJohn.Forte@Sun.COM ilp = (iscsi_lun_t *)ap->a_hba_tran->tran_tgt_private;
8427836SJohn.Forte@Sun.COM ASSERT(ilp != NULL);
8437836SJohn.Forte@Sun.COM
8447836SJohn.Forte@Sun.COM if (pkt == NULL) {
8457836SJohn.Forte@Sun.COM pkt = scsi_hba_pkt_alloc(ilp->lun_sess->sess_hba->hba_dip,
8467836SJohn.Forte@Sun.COM ap, cmdlen, statuslen, tgtlen, sizeof (iscsi_cmd_t),
8477836SJohn.Forte@Sun.COM callback, arg);
8487836SJohn.Forte@Sun.COM if (pkt == NULL) {
8497836SJohn.Forte@Sun.COM return (NULL);
8507836SJohn.Forte@Sun.COM }
8517836SJohn.Forte@Sun.COM icmdp = (iscsi_cmd_t *)pkt->pkt_ha_private;
8527836SJohn.Forte@Sun.COM icmdp->cmd_sig = ISCSI_SIG_CMD;
8537836SJohn.Forte@Sun.COM icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
8547836SJohn.Forte@Sun.COM icmdp->cmd_lun = ilp;
8557836SJohn.Forte@Sun.COM icmdp->cmd_type = ISCSI_CMD_TYPE_SCSI;
8567836SJohn.Forte@Sun.COM /* add the report lun addressing type on to the lun */
8577836SJohn.Forte@Sun.COM icmdp->cmd_un.scsi.lun = ilp->lun_addr_type << 14;
8587836SJohn.Forte@Sun.COM icmdp->cmd_un.scsi.lun = icmdp->cmd_un.scsi.lun |
8597836SJohn.Forte@Sun.COM ilp->lun_num;
8607836SJohn.Forte@Sun.COM icmdp->cmd_un.scsi.pkt = pkt;
8617836SJohn.Forte@Sun.COM icmdp->cmd_un.scsi.bp = bp;
8627836SJohn.Forte@Sun.COM icmdp->cmd_un.scsi.cmdlen = cmdlen;
8637836SJohn.Forte@Sun.COM icmdp->cmd_un.scsi.statuslen = statuslen;
8647836SJohn.Forte@Sun.COM icmdp->cmd_crc_error_seen = B_FALSE;
8658231SJack.Meng@Sun.COM icmdp->cmd_misc_flags = 0;
8668294SShengliang.Zhang@Sun.COM if (flags & PKT_XARQ) {
8678294SShengliang.Zhang@Sun.COM icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_XARQ;
8688294SShengliang.Zhang@Sun.COM }
8698294SShengliang.Zhang@Sun.COM
8709162SPeter.Dunlap@Sun.COM
8719162SPeter.Dunlap@Sun.COM idm_sm_audit_init(&icmdp->cmd_state_audit);
8729162SPeter.Dunlap@Sun.COM
8737836SJohn.Forte@Sun.COM mutex_init(&icmdp->cmd_mutex, NULL, MUTEX_DRIVER, NULL);
8747836SJohn.Forte@Sun.COM cv_init(&icmdp->cmd_completion, NULL, CV_DRIVER, NULL);
8757836SJohn.Forte@Sun.COM
8767836SJohn.Forte@Sun.COM pkt->pkt_address = *ap;
8777836SJohn.Forte@Sun.COM pkt->pkt_comp = (void (*)())NULL;
8787836SJohn.Forte@Sun.COM pkt->pkt_flags = 0;
8797836SJohn.Forte@Sun.COM pkt->pkt_time = 0;
8807836SJohn.Forte@Sun.COM pkt->pkt_resid = 0;
8817836SJohn.Forte@Sun.COM pkt->pkt_statistics = 0;
8827836SJohn.Forte@Sun.COM pkt->pkt_reason = 0;
8837836SJohn.Forte@Sun.COM }
8847836SJohn.Forte@Sun.COM return (pkt);
8857836SJohn.Forte@Sun.COM }
8867836SJohn.Forte@Sun.COM
8877836SJohn.Forte@Sun.COM /*
8887836SJohn.Forte@Sun.COM * iscsi_tran_lun_free - Free a SCSI LUN
8897836SJohn.Forte@Sun.COM */
8907836SJohn.Forte@Sun.COM static void
iscsi_tran_lun_free(dev_info_t * hba_dip,dev_info_t * lun_dip,scsi_hba_tran_t * hba_tran,struct scsi_device * sd)8917836SJohn.Forte@Sun.COM iscsi_tran_lun_free(dev_info_t *hba_dip, dev_info_t *lun_dip,
8927836SJohn.Forte@Sun.COM scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
8937836SJohn.Forte@Sun.COM {
8947836SJohn.Forte@Sun.COM iscsi_lun_t *ilp = NULL;
8957836SJohn.Forte@Sun.COM
8967836SJohn.Forte@Sun.COM ASSERT(hba_dip != NULL);
8977836SJohn.Forte@Sun.COM ASSERT(lun_dip != NULL);
8987836SJohn.Forte@Sun.COM ASSERT(hba_tran != NULL);
8997836SJohn.Forte@Sun.COM ASSERT(sd != NULL);
9007836SJohn.Forte@Sun.COM ilp = (iscsi_lun_t *)hba_tran->tran_tgt_private;
9017836SJohn.Forte@Sun.COM ASSERT(ilp != NULL);
9027836SJohn.Forte@Sun.COM
9037836SJohn.Forte@Sun.COM (void) mdi_prop_remove(ilp->lun_pip, NULL);
9047836SJohn.Forte@Sun.COM }
9057836SJohn.Forte@Sun.COM
9067836SJohn.Forte@Sun.COM /*
9077836SJohn.Forte@Sun.COM * iscsi_start -- Start a SCSI transaction based on the packet
9087836SJohn.Forte@Sun.COM * This will attempt to add the icmdp to the pending queue
9097836SJohn.Forte@Sun.COM * for the connection and kick the queue. If the enqueue
9107836SJohn.Forte@Sun.COM * fails that means the queue is full.
9117836SJohn.Forte@Sun.COM */
9127836SJohn.Forte@Sun.COM static int
iscsi_tran_start(struct scsi_address * ap,struct scsi_pkt * pkt)9137836SJohn.Forte@Sun.COM iscsi_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt)
9147836SJohn.Forte@Sun.COM {
9157836SJohn.Forte@Sun.COM iscsi_lun_t *ilp = NULL;
9167836SJohn.Forte@Sun.COM iscsi_sess_t *isp = NULL;
9177836SJohn.Forte@Sun.COM iscsi_cmd_t *icmdp = NULL;
9187836SJohn.Forte@Sun.COM uint_t flags;
9197836SJohn.Forte@Sun.COM
9207836SJohn.Forte@Sun.COM ASSERT(ap != NULL);
9217836SJohn.Forte@Sun.COM ASSERT(pkt != NULL);
9227836SJohn.Forte@Sun.COM ilp = (iscsi_lun_t *)ap->a_hba_tran->tran_tgt_private;
9237836SJohn.Forte@Sun.COM isp = (iscsi_sess_t *)ilp->lun_sess;
9247836SJohn.Forte@Sun.COM icmdp = (iscsi_cmd_t *)pkt->pkt_ha_private;
9257836SJohn.Forte@Sun.COM flags = pkt->pkt_flags;
9267836SJohn.Forte@Sun.COM ASSERT(ilp != NULL);
9277836SJohn.Forte@Sun.COM ASSERT(isp != NULL);
9287836SJohn.Forte@Sun.COM ASSERT(icmdp != NULL);
9297836SJohn.Forte@Sun.COM
9307836SJohn.Forte@Sun.COM /*
9317836SJohn.Forte@Sun.COM * If the session is in the FREE state then
9327836SJohn.Forte@Sun.COM * all connections are down and retries have
9337836SJohn.Forte@Sun.COM * been exhausted. Fail command with fatal error.
9347836SJohn.Forte@Sun.COM */
93512161SJack.Meng@Sun.COM rw_enter(&isp->sess_state_rwlock, RW_READER);
9367836SJohn.Forte@Sun.COM if (isp->sess_state == ISCSI_SESS_STATE_FREE) {
93712161SJack.Meng@Sun.COM rw_exit(&isp->sess_state_rwlock);
93812161SJack.Meng@Sun.COM return (TRAN_FATAL_ERROR);
93912161SJack.Meng@Sun.COM }
94012161SJack.Meng@Sun.COM
94112161SJack.Meng@Sun.COM /*
94212161SJack.Meng@Sun.COM * If we haven't received data from the target in the
94312161SJack.Meng@Sun.COM * max specified period something is wrong with the
94412161SJack.Meng@Sun.COM * transport. Fail IO with FATAL_ERROR.
94512161SJack.Meng@Sun.COM */
94612161SJack.Meng@Sun.COM if (isp->sess_rx_lbolt + SEC_TO_TICK(iscsi_rx_max_window) <
94712161SJack.Meng@Sun.COM ddi_get_lbolt()) {
94812161SJack.Meng@Sun.COM rw_exit(&isp->sess_state_rwlock);
9497836SJohn.Forte@Sun.COM return (TRAN_FATAL_ERROR);
9507836SJohn.Forte@Sun.COM }
9517836SJohn.Forte@Sun.COM
9527836SJohn.Forte@Sun.COM /*
9537836SJohn.Forte@Sun.COM * If the session is not in LOGGED_IN then we have
9547836SJohn.Forte@Sun.COM * no connections LOGGED_IN, but we haven't exhuasted
9557836SJohn.Forte@Sun.COM * our retries. Fail the command with busy so the
9567836SJohn.Forte@Sun.COM * caller might try again later. Once retries are
9577836SJohn.Forte@Sun.COM * exhausted the state machine will move us to FREE.
9587836SJohn.Forte@Sun.COM */
9597836SJohn.Forte@Sun.COM if (isp->sess_state != ISCSI_SESS_STATE_LOGGED_IN) {
96012161SJack.Meng@Sun.COM rw_exit(&isp->sess_state_rwlock);
9617836SJohn.Forte@Sun.COM return (TRAN_BUSY);
9627836SJohn.Forte@Sun.COM }
9637836SJohn.Forte@Sun.COM
9647836SJohn.Forte@Sun.COM /*
9657836SJohn.Forte@Sun.COM * If we haven't received data from the target in the
9667836SJohn.Forte@Sun.COM * specified period something is probably wrong with
9677836SJohn.Forte@Sun.COM * the transport. Just return back BUSY until either
9687836SJohn.Forte@Sun.COM * the problem is resolved of the transport fails.
9697836SJohn.Forte@Sun.COM */
9707836SJohn.Forte@Sun.COM if (isp->sess_rx_lbolt + SEC_TO_TICK(iscsi_rx_window) <
9717836SJohn.Forte@Sun.COM ddi_get_lbolt()) {
97212161SJack.Meng@Sun.COM rw_exit(&isp->sess_state_rwlock);
9737836SJohn.Forte@Sun.COM return (TRAN_BUSY);
9747836SJohn.Forte@Sun.COM }
9757836SJohn.Forte@Sun.COM
9767836SJohn.Forte@Sun.COM
9777836SJohn.Forte@Sun.COM /* reset cmd values in case upper level driver is retrying cmd */
9787836SJohn.Forte@Sun.COM icmdp->cmd_prev = icmdp->cmd_next = NULL;
9797836SJohn.Forte@Sun.COM icmdp->cmd_crc_error_seen = B_FALSE;
9807836SJohn.Forte@Sun.COM icmdp->cmd_lbolt_pending = icmdp->cmd_lbolt_active =
9817836SJohn.Forte@Sun.COM icmdp->cmd_lbolt_aborting = icmdp->cmd_lbolt_timeout =
9827836SJohn.Forte@Sun.COM (clock_t)NULL;
9837836SJohn.Forte@Sun.COM icmdp->cmd_itt = icmdp->cmd_ttt = 0;
9847836SJohn.Forte@Sun.COM icmdp->cmd_un.scsi.abort_icmdp = NULL;
9857836SJohn.Forte@Sun.COM
9867836SJohn.Forte@Sun.COM mutex_enter(&isp->sess_queue_pending.mutex);
9877836SJohn.Forte@Sun.COM iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
9887836SJohn.Forte@Sun.COM mutex_exit(&isp->sess_queue_pending.mutex);
98912161SJack.Meng@Sun.COM rw_exit(&isp->sess_state_rwlock);
9907836SJohn.Forte@Sun.COM
9917836SJohn.Forte@Sun.COM /*
9927836SJohn.Forte@Sun.COM * If this packet doesn't have FLAG_NOINTR set, it could have
9937836SJohn.Forte@Sun.COM * already run to completion (and the memory freed) at this
9947836SJohn.Forte@Sun.COM * point, so check our local copy of pkt_flags. Otherwise we
9957836SJohn.Forte@Sun.COM * have to wait for completion before returning to the caller.
9967836SJohn.Forte@Sun.COM */
9977836SJohn.Forte@Sun.COM if (flags & FLAG_NOINTR) {
9987836SJohn.Forte@Sun.COM mutex_enter(&icmdp->cmd_mutex);
9997836SJohn.Forte@Sun.COM while ((icmdp->cmd_state != ISCSI_CMD_STATE_COMPLETED) ||
10007836SJohn.Forte@Sun.COM (icmdp->cmd_un.scsi.r2t_icmdp != NULL) ||
10018447SBing.Zhao@Sun.COM (icmdp->cmd_un.scsi.abort_icmdp != NULL) ||
10028447SBing.Zhao@Sun.COM (icmdp->cmd_un.scsi.r2t_more == B_TRUE)) {
10037836SJohn.Forte@Sun.COM cv_wait(&icmdp->cmd_completion, &icmdp->cmd_mutex);
10047836SJohn.Forte@Sun.COM }
10057836SJohn.Forte@Sun.COM icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
10067836SJohn.Forte@Sun.COM mutex_exit(&icmdp->cmd_mutex);
10077836SJohn.Forte@Sun.COM }
10087836SJohn.Forte@Sun.COM
10097836SJohn.Forte@Sun.COM return (TRAN_ACCEPT);
10107836SJohn.Forte@Sun.COM }
10117836SJohn.Forte@Sun.COM
10127836SJohn.Forte@Sun.COM /*
10137836SJohn.Forte@Sun.COM * iscsi_tran_abort - Called when an upper level application
10147836SJohn.Forte@Sun.COM * or driver wants to kill a scsi_pkt that was already sent to
10157836SJohn.Forte@Sun.COM * this driver.
10167836SJohn.Forte@Sun.COM */
10177836SJohn.Forte@Sun.COM /* ARGSUSED */
10187836SJohn.Forte@Sun.COM static int
iscsi_tran_abort(struct scsi_address * ap,struct scsi_pkt * pkt)10197836SJohn.Forte@Sun.COM iscsi_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
10207836SJohn.Forte@Sun.COM {
10217836SJohn.Forte@Sun.COM return (0);
10227836SJohn.Forte@Sun.COM }
10237836SJohn.Forte@Sun.COM
10247836SJohn.Forte@Sun.COM /*
10257836SJohn.Forte@Sun.COM * iscsi_tran_reset - Reset target at either BUS, TARGET, or LUN
10267836SJohn.Forte@Sun.COM * level. This will require the issuing of a task management
10277836SJohn.Forte@Sun.COM * command down to the target/lun.
10287836SJohn.Forte@Sun.COM */
10297836SJohn.Forte@Sun.COM static int
iscsi_tran_reset(struct scsi_address * ap,int level)10307836SJohn.Forte@Sun.COM iscsi_tran_reset(struct scsi_address *ap, int level)
10317836SJohn.Forte@Sun.COM {
10327836SJohn.Forte@Sun.COM int rval = ISCSI_STATUS_INTERNAL_ERROR;
10337836SJohn.Forte@Sun.COM iscsi_sess_t *isp = NULL;
10347836SJohn.Forte@Sun.COM iscsi_lun_t *ilp = NULL;
10357836SJohn.Forte@Sun.COM
10367836SJohn.Forte@Sun.COM ilp = (iscsi_lun_t *)ap->a_hba_tran->tran_tgt_private;
10377836SJohn.Forte@Sun.COM ASSERT(ilp != NULL);
10387836SJohn.Forte@Sun.COM isp = ilp->lun_sess;
10397836SJohn.Forte@Sun.COM ASSERT(isp != NULL);
10407836SJohn.Forte@Sun.COM
10417836SJohn.Forte@Sun.COM switch (level) {
10427836SJohn.Forte@Sun.COM case RESET_LUN:
10437836SJohn.Forte@Sun.COM /* reset attempt will block until attempt is complete */
10447836SJohn.Forte@Sun.COM rval = iscsi_handle_reset(isp, level, ilp);
10457836SJohn.Forte@Sun.COM break;
10467836SJohn.Forte@Sun.COM case RESET_BUS:
10477836SJohn.Forte@Sun.COM /*
10487836SJohn.Forte@Sun.COM * What are we going to realy reset the ethernet
10497836SJohn.Forte@Sun.COM * network!? Just fall through to a target reset.
10507836SJohn.Forte@Sun.COM */
10517836SJohn.Forte@Sun.COM case RESET_TARGET:
10527836SJohn.Forte@Sun.COM /* reset attempt will block until attempt is complete */
10537836SJohn.Forte@Sun.COM rval = iscsi_handle_reset(isp, level, NULL);
10547836SJohn.Forte@Sun.COM break;
10557836SJohn.Forte@Sun.COM case RESET_ALL:
10567836SJohn.Forte@Sun.COM default:
10577836SJohn.Forte@Sun.COM break;
10587836SJohn.Forte@Sun.COM }
10597836SJohn.Forte@Sun.COM
10607836SJohn.Forte@Sun.COM return (ISCSI_SUCCESS(rval) ? 1 : 0);
10617836SJohn.Forte@Sun.COM }
10627836SJohn.Forte@Sun.COM
10637836SJohn.Forte@Sun.COM /*
10647836SJohn.Forte@Sun.COM * iscsi_tran_getcap - Get target/lun capabilities.
10657836SJohn.Forte@Sun.COM */
10667836SJohn.Forte@Sun.COM static int
iscsi_tran_getcap(struct scsi_address * ap,char * cap,int whom)10677836SJohn.Forte@Sun.COM iscsi_tran_getcap(struct scsi_address *ap, char *cap, int whom)
10687836SJohn.Forte@Sun.COM {
10697836SJohn.Forte@Sun.COM return (iscsi_i_commoncap(ap, cap, 0, whom, 0));
10707836SJohn.Forte@Sun.COM }
10717836SJohn.Forte@Sun.COM
10727836SJohn.Forte@Sun.COM
10737836SJohn.Forte@Sun.COM /*
10747836SJohn.Forte@Sun.COM * iscsi_tran_setcap - Set target/lun capabilities.
10757836SJohn.Forte@Sun.COM */
10767836SJohn.Forte@Sun.COM /* ARGSUSED */
10777836SJohn.Forte@Sun.COM static int
iscsi_tran_setcap(struct scsi_address * ap,char * cap,int value,int whom)10787836SJohn.Forte@Sun.COM iscsi_tran_setcap(struct scsi_address *ap, char *cap, int value, int whom)
10797836SJohn.Forte@Sun.COM {
10809780SBing.Zhao@Sun.COM return (iscsi_i_commoncap(ap, cap, value, whom, 1));
10817836SJohn.Forte@Sun.COM }
10827836SJohn.Forte@Sun.COM
10837836SJohn.Forte@Sun.COM
10847836SJohn.Forte@Sun.COM /*
10857836SJohn.Forte@Sun.COM * iscsi_tran_destroy_pkt - Clean up packet
10867836SJohn.Forte@Sun.COM */
10877836SJohn.Forte@Sun.COM static void
iscsi_tran_destroy_pkt(struct scsi_address * ap,struct scsi_pkt * pkt)10887836SJohn.Forte@Sun.COM iscsi_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
10897836SJohn.Forte@Sun.COM {
10907836SJohn.Forte@Sun.COM iscsi_cmd_t *icmdp;
10917836SJohn.Forte@Sun.COM
10927836SJohn.Forte@Sun.COM icmdp = (iscsi_cmd_t *)pkt->pkt_ha_private;
10937836SJohn.Forte@Sun.COM
10947836SJohn.Forte@Sun.COM ASSERT(icmdp != NULL);
10957836SJohn.Forte@Sun.COM ASSERT(icmdp->cmd_sig == ISCSI_SIG_CMD);
10967836SJohn.Forte@Sun.COM ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_FREE);
10977836SJohn.Forte@Sun.COM
10987836SJohn.Forte@Sun.COM mutex_destroy(&icmdp->cmd_mutex);
10997836SJohn.Forte@Sun.COM cv_destroy(&icmdp->cmd_completion);
11007836SJohn.Forte@Sun.COM scsi_hba_pkt_free(ap, pkt);
11017836SJohn.Forte@Sun.COM }
11027836SJohn.Forte@Sun.COM
11037836SJohn.Forte@Sun.COM /*
11047836SJohn.Forte@Sun.COM * iscsi_tran_dmafree - This is a software driver, NO DMA
11057836SJohn.Forte@Sun.COM */
11067836SJohn.Forte@Sun.COM /* ARGSUSED */
11077836SJohn.Forte@Sun.COM static void
iscsi_tran_dmafree(struct scsi_address * ap,struct scsi_pkt * pkt)11087836SJohn.Forte@Sun.COM iscsi_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
11097836SJohn.Forte@Sun.COM {
11107836SJohn.Forte@Sun.COM /*
11117836SJohn.Forte@Sun.COM * The iSCSI interface doesn't deal with DMA
11127836SJohn.Forte@Sun.COM */
11137836SJohn.Forte@Sun.COM }
11147836SJohn.Forte@Sun.COM
11157836SJohn.Forte@Sun.COM /*
11167836SJohn.Forte@Sun.COM * iscsi_tran_sync_pkt - This is a software driver, NO DMA
11177836SJohn.Forte@Sun.COM */
11187836SJohn.Forte@Sun.COM /* ARGSUSED */
11197836SJohn.Forte@Sun.COM static void
iscsi_tran_sync_pkt(struct scsi_address * ap,struct scsi_pkt * pkt)11207836SJohn.Forte@Sun.COM iscsi_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
11217836SJohn.Forte@Sun.COM {
11227836SJohn.Forte@Sun.COM /*
11237836SJohn.Forte@Sun.COM * The iSCSI interface doesn't deal with DMA
11247836SJohn.Forte@Sun.COM */
11257836SJohn.Forte@Sun.COM }
11267836SJohn.Forte@Sun.COM
11277836SJohn.Forte@Sun.COM /*
11287836SJohn.Forte@Sun.COM * iscsi_tran_reset_notify - We don't support BUS_RESET so there
11297836SJohn.Forte@Sun.COM * is no point in support callback.
11307836SJohn.Forte@Sun.COM */
11317836SJohn.Forte@Sun.COM /* ARGSUSED */
11327836SJohn.Forte@Sun.COM static int
iscsi_tran_reset_notify(struct scsi_address * ap,int flag,void (* callback)(caddr_t),caddr_t arg)11337836SJohn.Forte@Sun.COM iscsi_tran_reset_notify(struct scsi_address *ap, int flag,
11347836SJohn.Forte@Sun.COM void (*callback) (caddr_t), caddr_t arg)
11357836SJohn.Forte@Sun.COM {
11367836SJohn.Forte@Sun.COM
11377836SJohn.Forte@Sun.COM /*
11387836SJohn.Forte@Sun.COM * We never do BUS_RESETS so allowing this call
11397836SJohn.Forte@Sun.COM * back to register has no point?
11407836SJohn.Forte@Sun.COM */
11417836SJohn.Forte@Sun.COM return (DDI_SUCCESS);
11427836SJohn.Forte@Sun.COM }
11437836SJohn.Forte@Sun.COM
11447836SJohn.Forte@Sun.COM
11457836SJohn.Forte@Sun.COM /*
11467836SJohn.Forte@Sun.COM * iscsi_tran_bus_config - on demand device configuration
11477836SJohn.Forte@Sun.COM *
11487836SJohn.Forte@Sun.COM * iscsi_tran_bus_config is called by the NDI layer at the completion
11497836SJohn.Forte@Sun.COM * of a dev_node creation. There are two primary cases defined in this
11507836SJohn.Forte@Sun.COM * function. The first is BUS_CONFIG_ALL. In this case the NDI is trying
11517836SJohn.Forte@Sun.COM * to identify that targets/luns are available configured at that point
11527836SJohn.Forte@Sun.COM * in time. It is safe to just complete the process succcessfully. The
11537836SJohn.Forte@Sun.COM * second case is a new case that was defined in S10 for devfs. BUS_CONFIG_ONE
11547836SJohn.Forte@Sun.COM * this is to help driver the top down discovery instead of bottom up. If
11557836SJohn.Forte@Sun.COM * we receive a BUS_CONFIG_ONE we should check to see if the <addr> exists
11567836SJohn.Forte@Sun.COM * if so complete successfull processing. Otherwise we should call the
11577836SJohn.Forte@Sun.COM * deamon and see if we can plumb the <addr>. If it is possible to plumb the
11587836SJohn.Forte@Sun.COM * <addr> block until plumbing is complete. In both cases of being able to
11597836SJohn.Forte@Sun.COM * plumb <addr> or not continue with successfull processing.
11607836SJohn.Forte@Sun.COM */
11617836SJohn.Forte@Sun.COM static int
iscsi_tran_bus_config(dev_info_t * parent,uint_t flags,ddi_bus_config_op_t op,void * arg,dev_info_t ** childp)11627836SJohn.Forte@Sun.COM iscsi_tran_bus_config(dev_info_t *parent, uint_t flags,
11637836SJohn.Forte@Sun.COM ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
11647836SJohn.Forte@Sun.COM {
11657836SJohn.Forte@Sun.COM int rval = NDI_SUCCESS;
11667836SJohn.Forte@Sun.COM iscsi_hba_t *ihp = NULL;
11677836SJohn.Forte@Sun.COM int iflags = flags;
11687836SJohn.Forte@Sun.COM char *name = NULL;
11697836SJohn.Forte@Sun.COM char *ptr = NULL;
11709201SJack.Meng@Sun.COM boolean_t config_root = B_FALSE;
11717836SJohn.Forte@Sun.COM
11727836SJohn.Forte@Sun.COM /* get reference to soft state */
11737836SJohn.Forte@Sun.COM ihp = (iscsi_hba_t *)ddi_get_soft_state(iscsi_state,
11747836SJohn.Forte@Sun.COM ddi_get_instance(parent));
11757836SJohn.Forte@Sun.COM if (ihp == NULL) {
11767836SJohn.Forte@Sun.COM return (NDI_FAILURE);
11777836SJohn.Forte@Sun.COM }
11787836SJohn.Forte@Sun.COM
11799201SJack.Meng@Sun.COM iscsi_check_miniroot(ihp);
11809201SJack.Meng@Sun.COM if ((modrootloaded == 0) && (iscsiboot_prop != NULL)) {
11819201SJack.Meng@Sun.COM config_root = B_TRUE;
11829201SJack.Meng@Sun.COM }
11839201SJack.Meng@Sun.COM
11849201SJack.Meng@Sun.COM if (config_root == B_FALSE) {
11859201SJack.Meng@Sun.COM if (iscsi_client_request_service(ihp) == B_FALSE) {
11869201SJack.Meng@Sun.COM return (NDI_FAILURE);
11879201SJack.Meng@Sun.COM }
11889201SJack.Meng@Sun.COM }
11899201SJack.Meng@Sun.COM
11907836SJohn.Forte@Sun.COM /* lock so only one config operation occrs */
11917836SJohn.Forte@Sun.COM sema_p(&iscsid_config_semaphore);
11927836SJohn.Forte@Sun.COM
11937836SJohn.Forte@Sun.COM switch (op) {
11947836SJohn.Forte@Sun.COM case BUS_CONFIG_ONE:
11957836SJohn.Forte@Sun.COM /* parse target name out of name given */
11967836SJohn.Forte@Sun.COM if ((ptr = strchr((char *)arg, '@')) == NULL) {
11977836SJohn.Forte@Sun.COM rval = NDI_FAILURE;
11987836SJohn.Forte@Sun.COM break;
11997836SJohn.Forte@Sun.COM }
12007836SJohn.Forte@Sun.COM ptr++; /* move past '@' */
12017836SJohn.Forte@Sun.COM name = kmem_zalloc(MAX_GET_NAME_SIZE, KM_SLEEP);
12027836SJohn.Forte@Sun.COM (void) strncpy(name, ptr, MAX_GET_NAME_SIZE);
12037836SJohn.Forte@Sun.COM /* We need to strip the LUN */
12047836SJohn.Forte@Sun.COM if ((ptr = strchr(name, ',')) == NULL) {
12057836SJohn.Forte@Sun.COM rval = NDI_FAILURE;
12067836SJohn.Forte@Sun.COM kmem_free(name, MAX_GET_NAME_SIZE);
12077836SJohn.Forte@Sun.COM name = NULL;
12087836SJohn.Forte@Sun.COM break;
12097836SJohn.Forte@Sun.COM }
12107836SJohn.Forte@Sun.COM /* We also need to strip the 4 bytes of hex TPGT */
12117836SJohn.Forte@Sun.COM ptr -= 4;
12127836SJohn.Forte@Sun.COM if (ptr <= name) {
12137836SJohn.Forte@Sun.COM rval = NDI_FAILURE;
12147836SJohn.Forte@Sun.COM kmem_free(name, MAX_GET_NAME_SIZE);
12157836SJohn.Forte@Sun.COM name = NULL;
12167836SJohn.Forte@Sun.COM break;
12177836SJohn.Forte@Sun.COM }
12187836SJohn.Forte@Sun.COM *ptr = '\0'; /* NULL terminate */
12197836SJohn.Forte@Sun.COM
12207836SJohn.Forte@Sun.COM /* translate name back to original iSCSI name */
12217836SJohn.Forte@Sun.COM iscsi_get_name_to_iqn(name, MAX_GET_NAME_SIZE);
12227836SJohn.Forte@Sun.COM
12237836SJohn.Forte@Sun.COM /* configure target, skip 4 byte ISID */
12247836SJohn.Forte@Sun.COM iscsid_config_one(ihp, (name+4), B_TRUE);
12257836SJohn.Forte@Sun.COM
12267836SJohn.Forte@Sun.COM kmem_free(name, MAX_GET_NAME_SIZE);
12277836SJohn.Forte@Sun.COM name = NULL;
12287836SJohn.Forte@Sun.COM
12297836SJohn.Forte@Sun.COM /*
12307836SJohn.Forte@Sun.COM * DDI group instructed us to use this flag.
12317836SJohn.Forte@Sun.COM */
12327836SJohn.Forte@Sun.COM iflags |= NDI_MDI_FALLBACK;
12337836SJohn.Forte@Sun.COM break;
12347836SJohn.Forte@Sun.COM case BUS_CONFIG_DRIVER:
12357836SJohn.Forte@Sun.COM /* FALLTHRU */
12367836SJohn.Forte@Sun.COM case BUS_CONFIG_ALL:
12377836SJohn.Forte@Sun.COM iscsid_config_all(ihp, B_TRUE);
12387836SJohn.Forte@Sun.COM break;
12397836SJohn.Forte@Sun.COM default:
12407836SJohn.Forte@Sun.COM rval = NDI_FAILURE;
12417836SJohn.Forte@Sun.COM break;
12427836SJohn.Forte@Sun.COM }
12437836SJohn.Forte@Sun.COM
12447836SJohn.Forte@Sun.COM if (rval == NDI_SUCCESS) {
12457836SJohn.Forte@Sun.COM rval = ndi_busop_bus_config(parent, iflags,
12467836SJohn.Forte@Sun.COM op, arg, childp, 0);
12477836SJohn.Forte@Sun.COM }
12487836SJohn.Forte@Sun.COM sema_v(&iscsid_config_semaphore);
12497836SJohn.Forte@Sun.COM
12509201SJack.Meng@Sun.COM if (config_root == B_FALSE) {
12519201SJack.Meng@Sun.COM iscsi_client_release_service(ihp);
12529201SJack.Meng@Sun.COM }
12539201SJack.Meng@Sun.COM
12547836SJohn.Forte@Sun.COM return (rval);
12557836SJohn.Forte@Sun.COM }
12567836SJohn.Forte@Sun.COM
12577836SJohn.Forte@Sun.COM /*
12587836SJohn.Forte@Sun.COM * iscsi_tran_bus_unconfig - on demand device unconfiguration
12597836SJohn.Forte@Sun.COM *
12607836SJohn.Forte@Sun.COM * Called by the os framework under low resource situations.
12617836SJohn.Forte@Sun.COM * It will attempt to unload our minor nodes (logical units
12627836SJohn.Forte@Sun.COM * ndi/mdi nodes).
12637836SJohn.Forte@Sun.COM */
12647836SJohn.Forte@Sun.COM static int
iscsi_tran_bus_unconfig(dev_info_t * parent,uint_t flag,ddi_bus_config_op_t op,void * arg)12657836SJohn.Forte@Sun.COM iscsi_tran_bus_unconfig(dev_info_t *parent, uint_t flag,
12667836SJohn.Forte@Sun.COM ddi_bus_config_op_t op, void *arg)
12677836SJohn.Forte@Sun.COM {
12689201SJack.Meng@Sun.COM int rval = NDI_SUCCESS;
12699201SJack.Meng@Sun.COM iscsi_hba_t *ihp = NULL;
12709201SJack.Meng@Sun.COM
12719201SJack.Meng@Sun.COM /* get reference to soft state */
12729201SJack.Meng@Sun.COM ihp = (iscsi_hba_t *)ddi_get_soft_state(iscsi_state,
12739201SJack.Meng@Sun.COM ddi_get_instance(parent));
12749201SJack.Meng@Sun.COM if (ihp == NULL) {
12759201SJack.Meng@Sun.COM return (NDI_FAILURE);
12769201SJack.Meng@Sun.COM }
12779201SJack.Meng@Sun.COM
12789201SJack.Meng@Sun.COM if (iscsi_client_request_service(ihp) == B_FALSE) {
127911730SJack.Meng@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
128011730SJack.Meng@Sun.COM if (ihp->hba_sess_list != NULL) {
128111730SJack.Meng@Sun.COM rval = NDI_FAILURE;
128211730SJack.Meng@Sun.COM }
128311730SJack.Meng@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
128411730SJack.Meng@Sun.COM return (rval);
12859201SJack.Meng@Sun.COM }
12869201SJack.Meng@Sun.COM
12879201SJack.Meng@Sun.COM rval = ndi_busop_bus_unconfig(parent, flag, op, arg);
12889201SJack.Meng@Sun.COM
12899201SJack.Meng@Sun.COM iscsi_client_release_service(ihp);
12909201SJack.Meng@Sun.COM
12919201SJack.Meng@Sun.COM return (rval);
12927836SJohn.Forte@Sun.COM }
12937836SJohn.Forte@Sun.COM
12947836SJohn.Forte@Sun.COM
12957836SJohn.Forte@Sun.COM /*
12967836SJohn.Forte@Sun.COM * iscsi_tran_get_name - create private /devices name for LUN
12977836SJohn.Forte@Sun.COM *
12987836SJohn.Forte@Sun.COM * This creates the <addr> in /devices/iscsi/<driver>@<addr>
12997836SJohn.Forte@Sun.COM * path. For this <addr> we return the <session/target_name>,<lun num>
13007836SJohn.Forte@Sun.COM * Where <target_name> is an <iqn/eui/...> as defined by the iSCSI
13017836SJohn.Forte@Sun.COM * specification. We do modify the name slightly so that it still
13027836SJohn.Forte@Sun.COM * complies with the IEEE <addr> naming scheme. This means that we
13037836SJohn.Forte@Sun.COM * will substitute out the ':', '@', ... and other reserved characters
13047836SJohn.Forte@Sun.COM * defined in the IEEE definition with '%<hex value of special char>'
13057836SJohn.Forte@Sun.COM * This routine is indirectly called by iscsi_lun_create_xxx. These
13067836SJohn.Forte@Sun.COM * calling routines must prevent the session and lun lists from changing
13077836SJohn.Forte@Sun.COM * during this routine.
13087836SJohn.Forte@Sun.COM */
13097836SJohn.Forte@Sun.COM static int
iscsi_tran_get_name(struct scsi_device * sd,char * name,int len)13107836SJohn.Forte@Sun.COM iscsi_tran_get_name(struct scsi_device *sd, char *name, int len)
13117836SJohn.Forte@Sun.COM {
13127836SJohn.Forte@Sun.COM int target = 0;
13137836SJohn.Forte@Sun.COM int lun = 0;
13147836SJohn.Forte@Sun.COM iscsi_hba_t *ihp = NULL;
13157836SJohn.Forte@Sun.COM iscsi_sess_t *isp = NULL;
13167836SJohn.Forte@Sun.COM iscsi_lun_t *ilp = NULL;
13177836SJohn.Forte@Sun.COM dev_info_t *lun_dip = NULL;
13187836SJohn.Forte@Sun.COM
13197836SJohn.Forte@Sun.COM ASSERT(sd != NULL);
13207836SJohn.Forte@Sun.COM ASSERT(name != NULL);
13217836SJohn.Forte@Sun.COM lun_dip = sd->sd_dev;
13227836SJohn.Forte@Sun.COM ASSERT(lun_dip != NULL);
13237836SJohn.Forte@Sun.COM
13247836SJohn.Forte@Sun.COM /* get reference to soft state */
13257836SJohn.Forte@Sun.COM ihp = (iscsi_hba_t *)ddi_get_soft_state(iscsi_state,
13267836SJohn.Forte@Sun.COM ddi_get_instance(ddi_get_parent(lun_dip)));
13277836SJohn.Forte@Sun.COM if (ihp == NULL) {
13287836SJohn.Forte@Sun.COM name[0] = '\0';
13297836SJohn.Forte@Sun.COM return (0);
13307836SJohn.Forte@Sun.COM }
13317836SJohn.Forte@Sun.COM
13327836SJohn.Forte@Sun.COM /* Get the target num */
13337836SJohn.Forte@Sun.COM target = ddi_prop_get_int(DDI_DEV_T_ANY, sd->sd_dev,
13347836SJohn.Forte@Sun.COM DDI_PROP_DONTPASS, TARGET_PROP, 0);
13357836SJohn.Forte@Sun.COM
13367836SJohn.Forte@Sun.COM /* Get the target num */
13377836SJohn.Forte@Sun.COM lun = ddi_prop_get_int(DDI_DEV_T_ANY, sd->sd_dev,
13387836SJohn.Forte@Sun.COM DDI_PROP_DONTPASS, LUN_PROP, 0);
13397836SJohn.Forte@Sun.COM
13407836SJohn.Forte@Sun.COM /*
13417836SJohn.Forte@Sun.COM * Now we need to find our ilp by walking the lists
13427836SJohn.Forte@Sun.COM * off the ihp and isp.
13437836SJohn.Forte@Sun.COM */
13447836SJohn.Forte@Sun.COM /* See if we already created this session */
13457836SJohn.Forte@Sun.COM
13467836SJohn.Forte@Sun.COM /* Walk the HBA's session list */
13477836SJohn.Forte@Sun.COM for (isp = ihp->hba_sess_list; isp; isp = isp->sess_next) {
13487836SJohn.Forte@Sun.COM /* compare target name as the unique identifier */
13497836SJohn.Forte@Sun.COM if (target == isp->sess_oid) {
13507836SJohn.Forte@Sun.COM /* found match */
13517836SJohn.Forte@Sun.COM break;
13527836SJohn.Forte@Sun.COM }
13537836SJohn.Forte@Sun.COM }
13547836SJohn.Forte@Sun.COM
13557836SJohn.Forte@Sun.COM /* If we found matching session continue searching for tgt */
13567836SJohn.Forte@Sun.COM if (isp == NULL) {
13577836SJohn.Forte@Sun.COM /* sess not found */
13587836SJohn.Forte@Sun.COM name[0] = '\0';
13597836SJohn.Forte@Sun.COM return (0);
13607836SJohn.Forte@Sun.COM }
13617836SJohn.Forte@Sun.COM
13627836SJohn.Forte@Sun.COM /*
13637836SJohn.Forte@Sun.COM * Search for the matching iscsi lun structure. We don't
13647836SJohn.Forte@Sun.COM * need to hold the READER for the lun list at this point.
13657836SJohn.Forte@Sun.COM * because the tran_get_name is being called from the online
13667836SJohn.Forte@Sun.COM * function which is already holding a reader on the lun
13677836SJohn.Forte@Sun.COM * list.
13687836SJohn.Forte@Sun.COM */
13697836SJohn.Forte@Sun.COM for (ilp = isp->sess_lun_list; ilp; ilp = ilp->lun_next) {
13707836SJohn.Forte@Sun.COM if (lun == ilp->lun_num) {
13717836SJohn.Forte@Sun.COM /* found match */
13727836SJohn.Forte@Sun.COM break;
13737836SJohn.Forte@Sun.COM }
13747836SJohn.Forte@Sun.COM }
13757836SJohn.Forte@Sun.COM
13767836SJohn.Forte@Sun.COM if (ilp == NULL) {
13777836SJohn.Forte@Sun.COM /* tgt not found */
13787836SJohn.Forte@Sun.COM name[0] = '\0';
13797836SJohn.Forte@Sun.COM return (0);
13807836SJohn.Forte@Sun.COM }
13817836SJohn.Forte@Sun.COM
13827836SJohn.Forte@Sun.COM /* Ensure enough space for lun_addr is available */
13837836SJohn.Forte@Sun.COM ASSERT(ilp->lun_addr != NULL);
13847836SJohn.Forte@Sun.COM if ((strlen(ilp->lun_addr) + 1) > len) {
13857836SJohn.Forte@Sun.COM return (0);
13867836SJohn.Forte@Sun.COM }
13877836SJohn.Forte@Sun.COM
13887836SJohn.Forte@Sun.COM /* copy lun_addr name */
13897836SJohn.Forte@Sun.COM (void) strcpy(name, ilp->lun_addr);
13907836SJohn.Forte@Sun.COM
13917836SJohn.Forte@Sun.COM /*
13927836SJohn.Forte@Sun.COM * Based on IEEE-1275 we can't have any ':', ' ', '@', or '/'
13937836SJohn.Forte@Sun.COM * characters in our naming. So replace all those characters
13947836SJohn.Forte@Sun.COM * with '-'
13957836SJohn.Forte@Sun.COM */
13967836SJohn.Forte@Sun.COM iscsi_get_name_from_iqn(name, len);
13977836SJohn.Forte@Sun.COM
13987836SJohn.Forte@Sun.COM return (1);
13997836SJohn.Forte@Sun.COM }
14007836SJohn.Forte@Sun.COM
14017836SJohn.Forte@Sun.COM /*
14027836SJohn.Forte@Sun.COM * iscsi_tran_get_bus_addr - This returns a human readable string
14037836SJohn.Forte@Sun.COM * for the bus address. Examining most other drivers fcp, etc. They
14047836SJohn.Forte@Sun.COM * all just return the same string as tran_get_name. In our case
14057836SJohn.Forte@Sun.COM * our tran get name is already some what usable so leave alone.
14067836SJohn.Forte@Sun.COM */
14077836SJohn.Forte@Sun.COM static int
iscsi_tran_get_bus_addr(struct scsi_device * sd,char * name,int len)14087836SJohn.Forte@Sun.COM iscsi_tran_get_bus_addr(struct scsi_device *sd, char *name, int len)
14097836SJohn.Forte@Sun.COM {
14107836SJohn.Forte@Sun.COM return (iscsi_tran_get_name(sd, name, len));
14117836SJohn.Forte@Sun.COM }
14127836SJohn.Forte@Sun.COM
14137836SJohn.Forte@Sun.COM
14147836SJohn.Forte@Sun.COM /*
14157836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
14167836SJohn.Forte@Sun.COM * | End of scsi_tran routines |
14177836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
14187836SJohn.Forte@Sun.COM */
14197836SJohn.Forte@Sun.COM
14207836SJohn.Forte@Sun.COM /*
14217836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
14227836SJohn.Forte@Sun.COM * | Start of cb_ops routines |
14237836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
14247836SJohn.Forte@Sun.COM */
14257836SJohn.Forte@Sun.COM
14267836SJohn.Forte@Sun.COM /*
14277836SJohn.Forte@Sun.COM * iscsi_open - Driver should be made IOCTL MT safe. Otherwise
14287836SJohn.Forte@Sun.COM * this function needs updated.
14297836SJohn.Forte@Sun.COM */
14307836SJohn.Forte@Sun.COM /* ARGSUSED */
14317836SJohn.Forte@Sun.COM static int
iscsi_open(dev_t * devp,int flags,int otyp,cred_t * credp)14327836SJohn.Forte@Sun.COM iscsi_open(dev_t *devp, int flags, int otyp, cred_t *credp)
14337836SJohn.Forte@Sun.COM {
14347836SJohn.Forte@Sun.COM return (0);
14357836SJohn.Forte@Sun.COM }
14367836SJohn.Forte@Sun.COM
14377836SJohn.Forte@Sun.COM /*
14387836SJohn.Forte@Sun.COM * iscsi_close -
14397836SJohn.Forte@Sun.COM */
14407836SJohn.Forte@Sun.COM /* ARGSUSED */
14417836SJohn.Forte@Sun.COM static int
iscsi_close(dev_t dev,int flags,int otyp,cred_t * credp)14427836SJohn.Forte@Sun.COM iscsi_close(dev_t dev, int flags, int otyp, cred_t *credp)
14437836SJohn.Forte@Sun.COM {
14447836SJohn.Forte@Sun.COM return (0);
14457836SJohn.Forte@Sun.COM }
14467836SJohn.Forte@Sun.COM
14477836SJohn.Forte@Sun.COM /*
14487836SJohn.Forte@Sun.COM * iscsi_ioctl -
14497836SJohn.Forte@Sun.COM */
14507836SJohn.Forte@Sun.COM /* ARGSUSED */
14519201SJack.Meng@Sun.COM static int
iscsi_ioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)14527836SJohn.Forte@Sun.COM iscsi_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
14537836SJohn.Forte@Sun.COM cred_t *credp, int *rvalp)
14547836SJohn.Forte@Sun.COM {
14557836SJohn.Forte@Sun.COM int rtn = 0;
14567836SJohn.Forte@Sun.COM int instance = 0;
14577836SJohn.Forte@Sun.COM int list_space = 0;
14587836SJohn.Forte@Sun.COM int lun_sz = 0;
14597836SJohn.Forte@Sun.COM int did;
14608428SZhang.Yi@Sun.COM int retry;
14617836SJohn.Forte@Sun.COM iscsi_hba_t *ihp = NULL;
14627836SJohn.Forte@Sun.COM iscsi_sess_t *isp = NULL;
14637836SJohn.Forte@Sun.COM iscsi_conn_t *icp = NULL;
14647836SJohn.Forte@Sun.COM iscsi_login_params_t *params = NULL;
14657836SJohn.Forte@Sun.COM iscsi_login_params_t *tmpParams = NULL;
14667836SJohn.Forte@Sun.COM uchar_t *name = NULL;
14677836SJohn.Forte@Sun.COM dev_info_t *lun_dip = NULL;
14687836SJohn.Forte@Sun.COM
14697836SJohn.Forte@Sun.COM entry_t e;
14707836SJohn.Forte@Sun.COM iscsi_oid_t oid;
14717836SJohn.Forte@Sun.COM iscsi_property_t *ipp;
14727836SJohn.Forte@Sun.COM iscsi_static_property_t *ispp;
14737836SJohn.Forte@Sun.COM iscsi_param_get_t *ilg;
14747836SJohn.Forte@Sun.COM iscsi_param_set_t *ils;
14757836SJohn.Forte@Sun.COM iscsi_target_list_t idl, *idlp = NULL;
14767836SJohn.Forte@Sun.COM iscsi_addr_list_t ial, *ialp = NULL;
14777836SJohn.Forte@Sun.COM iscsi_chap_props_t *chap = NULL;
14787836SJohn.Forte@Sun.COM iscsi_radius_props_t *radius = NULL;
14797836SJohn.Forte@Sun.COM iscsi_auth_props_t *auth = NULL;
14807836SJohn.Forte@Sun.COM iscsi_lun_list_t *ll, *llp = NULL;
14817836SJohn.Forte@Sun.COM iscsi_lun_props_t *lun = NULL;
14827836SJohn.Forte@Sun.COM iscsi_lun_t *ilp = NULL;
14837836SJohn.Forte@Sun.COM iSCSIDiscoveryMethod_t method;
14847836SJohn.Forte@Sun.COM iSCSIDiscoveryProperties_t discovery_props;
14857836SJohn.Forte@Sun.COM iscsi_uscsi_t iu;
14867836SJohn.Forte@Sun.COM iscsi_uscsi_t iu_caller;
14877836SJohn.Forte@Sun.COM #ifdef _MULTI_DATAMODEL
14887836SJohn.Forte@Sun.COM /* For use when a 32 bit app makes a call into a 64 bit ioctl */
14897836SJohn.Forte@Sun.COM iscsi_uscsi32_t iu32_caller;
14907836SJohn.Forte@Sun.COM model_t model;
14917836SJohn.Forte@Sun.COM #endif /* _MULTI_DATAMODEL */
14927836SJohn.Forte@Sun.COM void *void_p;
14937836SJohn.Forte@Sun.COM iscsi_sendtgts_list_t *stl_hdr;
14947836SJohn.Forte@Sun.COM iscsi_sendtgts_list_t *istl;
14957836SJohn.Forte@Sun.COM int stl_sz;
14967836SJohn.Forte@Sun.COM iscsi_target_entry_t *target;
14977836SJohn.Forte@Sun.COM uint32_t old_oid;
14987836SJohn.Forte@Sun.COM uint32_t target_oid;
14997836SJohn.Forte@Sun.COM iscsi_targetparam_entry_t *curr_entry;
15007836SJohn.Forte@Sun.COM char *initiator_node_name;
15017836SJohn.Forte@Sun.COM char *initiator_node_alias;
15027836SJohn.Forte@Sun.COM isns_portal_group_list_t *pg_list = NULL;
15037836SJohn.Forte@Sun.COM isns_server_portal_group_list_t *server_pg_list_hdr = NULL;
15047836SJohn.Forte@Sun.COM isns_server_portal_group_list_t *server_pg_list = NULL;
15057836SJohn.Forte@Sun.COM int pg_list_sz, pg_sz_copy_out, server_pg_list_sz;
15067836SJohn.Forte@Sun.COM iscsi_config_sess_t *ics;
15077836SJohn.Forte@Sun.COM int size;
15087836SJohn.Forte@Sun.COM boolean_t rval;
15097836SJohn.Forte@Sun.COM char init_port_name[MAX_NAME_PROP_SIZE];
15107836SJohn.Forte@Sun.COM iscsi_sockaddr_t addr_dsc;
15118194SJack.Meng@Sun.COM iscsi_boot_property_t *bootProp;
15128294SShengliang.Zhang@Sun.COM boolean_t discovered = B_TRUE;
151310156SZhang.Yi@Sun.COM iscsi_tunable_object_t *tpsg;
151410156SZhang.Yi@Sun.COM iscsi_tunable_object_t *tpss;
151512161SJack.Meng@Sun.COM iscsi_reen_t *reenum;
15167836SJohn.Forte@Sun.COM
15177836SJohn.Forte@Sun.COM instance = getminor(dev);
15187836SJohn.Forte@Sun.COM ihp = (iscsi_hba_t *)ddi_get_soft_state(iscsi_state, instance);
15197836SJohn.Forte@Sun.COM if (ihp == NULL)
15207836SJohn.Forte@Sun.COM return (EFAULT);
15217836SJohn.Forte@Sun.COM
15229201SJack.Meng@Sun.COM iscsi_check_miniroot(ihp);
15239201SJack.Meng@Sun.COM if ((cmd != ISCSI_SMF_ONLINE) && (cmd != ISCSI_SMF_OFFLINE) &&
15249201SJack.Meng@Sun.COM (cmd != ISCSI_SMF_GET)) {
15259201SJack.Meng@Sun.COM /* other cmd needs to acquire the service */
15269201SJack.Meng@Sun.COM if (iscsi_client_request_service(ihp) == B_FALSE) {
15279201SJack.Meng@Sun.COM return (EFAULT);
15289201SJack.Meng@Sun.COM }
15299201SJack.Meng@Sun.COM }
15309201SJack.Meng@Sun.COM
15317836SJohn.Forte@Sun.COM switch (cmd) {
15327836SJohn.Forte@Sun.COM /*
15337836SJohn.Forte@Sun.COM * ISCSI_CREATE_OID - Create a Object IDentifier for a TargetName
15347836SJohn.Forte@Sun.COM */
15357836SJohn.Forte@Sun.COM case ISCSI_CREATE_OID:
15367836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &oid, sizeof (oid), mode)) {
15377836SJohn.Forte@Sun.COM rtn = EFAULT;
15387836SJohn.Forte@Sun.COM break;
15397836SJohn.Forte@Sun.COM }
15407836SJohn.Forte@Sun.COM if (oid.o_vers != ISCSI_INTERFACE_VERSION) {
15417836SJohn.Forte@Sun.COM rtn = EINVAL;
15427836SJohn.Forte@Sun.COM break;
15437836SJohn.Forte@Sun.COM }
15447836SJohn.Forte@Sun.COM
15457836SJohn.Forte@Sun.COM /* Set the target that this session is associated with */
15467836SJohn.Forte@Sun.COM oid.o_oid = iscsi_targetparam_get_oid(oid.o_name);
15477836SJohn.Forte@Sun.COM
15487836SJohn.Forte@Sun.COM if (ddi_copyout(&oid, (caddr_t)arg, sizeof (oid), mode)) {
15497836SJohn.Forte@Sun.COM rtn = EFAULT;
15507836SJohn.Forte@Sun.COM break;
15517836SJohn.Forte@Sun.COM }
15527836SJohn.Forte@Sun.COM break;
15537836SJohn.Forte@Sun.COM /*
15547836SJohn.Forte@Sun.COM * ISCSI_PARAM_GET - Get param for specified
15557836SJohn.Forte@Sun.COM * connection/session.
15567836SJohn.Forte@Sun.COM */
15577836SJohn.Forte@Sun.COM case ISCSI_PARAM_GET:
15587836SJohn.Forte@Sun.COM /* copyin user args */
15597836SJohn.Forte@Sun.COM ilg = (iscsi_param_get_t *)kmem_alloc(sizeof (*ilg), KM_SLEEP);
15607836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, ilg, sizeof (*ilg), mode)) {
15617836SJohn.Forte@Sun.COM rtn = EFAULT;
15627836SJohn.Forte@Sun.COM kmem_free(ilg, sizeof (*ilg));
15637836SJohn.Forte@Sun.COM break;
15647836SJohn.Forte@Sun.COM }
15657836SJohn.Forte@Sun.COM
15667836SJohn.Forte@Sun.COM if (ilg->g_vers != ISCSI_INTERFACE_VERSION) {
15677836SJohn.Forte@Sun.COM rtn = EINVAL;
15687836SJohn.Forte@Sun.COM kmem_free(ilg, sizeof (*ilg));
15697836SJohn.Forte@Sun.COM break;
15707836SJohn.Forte@Sun.COM }
15717836SJohn.Forte@Sun.COM
15727836SJohn.Forte@Sun.COM /* handle special case for Initiator name */
15737836SJohn.Forte@Sun.COM if (ilg->g_param == ISCSI_LOGIN_PARAM_INITIATOR_NAME) {
15747836SJohn.Forte@Sun.COM (void) strlcpy((char *)ilg->g_value.v_name,
15757836SJohn.Forte@Sun.COM (char *)ihp->hba_name, ISCSI_MAX_NAME_LEN);
15767836SJohn.Forte@Sun.COM } else if (ilg->g_param == ISCSI_LOGIN_PARAM_INITIATOR_ALIAS) {
15777836SJohn.Forte@Sun.COM if (ihp->hba_alias_length == 0) {
15787836SJohn.Forte@Sun.COM rtn = EINVAL;
15797836SJohn.Forte@Sun.COM } else {
15807836SJohn.Forte@Sun.COM (void) strlcpy((char *)ilg->g_value.v_name,
15817836SJohn.Forte@Sun.COM (char *)ihp->hba_alias, ISCSI_MAX_NAME_LEN);
15827836SJohn.Forte@Sun.COM }
15837836SJohn.Forte@Sun.COM } else {
15847836SJohn.Forte@Sun.COM /* To describe the validity of the requested param */
15857836SJohn.Forte@Sun.COM boolean_t valid_flag = B_TRUE;
15867836SJohn.Forte@Sun.COM
15877836SJohn.Forte@Sun.COM name = NULL;
15887836SJohn.Forte@Sun.COM
15897836SJohn.Forte@Sun.COM /*
15907836SJohn.Forte@Sun.COM * switch login based if looking for initiator
15917836SJohn.Forte@Sun.COM * params
15927836SJohn.Forte@Sun.COM */
15937836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
15947836SJohn.Forte@Sun.COM if (ilg->g_oid == ihp->hba_oid) {
15957836SJohn.Forte@Sun.COM /* initiator */
15967836SJohn.Forte@Sun.COM params = &ihp->hba_params;
15977836SJohn.Forte@Sun.COM name = ihp->hba_name;
15987836SJohn.Forte@Sun.COM if (iscsi_get_persisted_param(name,
15997836SJohn.Forte@Sun.COM ilg, params) != 0) {
16007836SJohn.Forte@Sun.COM valid_flag = B_FALSE;
16017836SJohn.Forte@Sun.COM }
16027836SJohn.Forte@Sun.COM } else {
16037836SJohn.Forte@Sun.COM /*
16047836SJohn.Forte@Sun.COM * If the oid does represent a session check
16057836SJohn.Forte@Sun.COM * to see if it is a target oid. If so,
16067836SJohn.Forte@Sun.COM * return the target's associated session.
16077836SJohn.Forte@Sun.COM */
16087836SJohn.Forte@Sun.COM rtn = iscsi_sess_get(ilg->g_oid, ihp, &isp);
16097836SJohn.Forte@Sun.COM if (rtn != 0) {
16107836SJohn.Forte@Sun.COM rtn = iscsi_sess_get_by_target(
16117836SJohn.Forte@Sun.COM ilg->g_oid, ihp, &isp);
16127836SJohn.Forte@Sun.COM }
16137836SJohn.Forte@Sun.COM
16147836SJohn.Forte@Sun.COM /*
16157836SJohn.Forte@Sun.COM * If rtn is zero then we have found an
16167836SJohn.Forte@Sun.COM * existing session. Use the session name to
16177836SJohn.Forte@Sun.COM * do param lookup. If rtn is non-zero then
16187836SJohn.Forte@Sun.COM * create a targetparam object and use its name
16197836SJohn.Forte@Sun.COM * for param lookup.
16207836SJohn.Forte@Sun.COM */
16217836SJohn.Forte@Sun.COM if (rtn == 0) {
16227836SJohn.Forte@Sun.COM name = isp->sess_name;
16237836SJohn.Forte@Sun.COM params = &isp->sess_params;
16247836SJohn.Forte@Sun.COM } else {
16257836SJohn.Forte@Sun.COM name =
16267836SJohn.Forte@Sun.COM iscsi_targetparam_get_name(
16277836SJohn.Forte@Sun.COM ilg->g_oid);
16287836SJohn.Forte@Sun.COM if (ilg->g_param_type ==
16297836SJohn.Forte@Sun.COM ISCSI_SESS_PARAM) {
16307836SJohn.Forte@Sun.COM tmpParams =
16317836SJohn.Forte@Sun.COM (iscsi_login_params_t *)
16327836SJohn.Forte@Sun.COM kmem_alloc(
16337836SJohn.Forte@Sun.COM sizeof (*tmpParams),
16347836SJohn.Forte@Sun.COM KM_SLEEP);
16357836SJohn.Forte@Sun.COM params = tmpParams;
16367836SJohn.Forte@Sun.COM }
16377836SJohn.Forte@Sun.COM rtn = 0;
16387836SJohn.Forte@Sun.COM }
16397836SJohn.Forte@Sun.COM
16407836SJohn.Forte@Sun.COM if (name == NULL) {
16417836SJohn.Forte@Sun.COM rw_exit(
16427836SJohn.Forte@Sun.COM &ihp->hba_sess_list_rwlock);
16437836SJohn.Forte@Sun.COM rtn = EFAULT;
16447836SJohn.Forte@Sun.COM kmem_free(ilg, sizeof (*ilg));
16457836SJohn.Forte@Sun.COM if (tmpParams != NULL)
16467836SJohn.Forte@Sun.COM kmem_free(tmpParams,
16477836SJohn.Forte@Sun.COM sizeof (*tmpParams));
16487836SJohn.Forte@Sun.COM
16497836SJohn.Forte@Sun.COM break;
16507836SJohn.Forte@Sun.COM }
16517836SJohn.Forte@Sun.COM
16527836SJohn.Forte@Sun.COM if (ilg->g_param_type == ISCSI_SESS_PARAM) {
16537836SJohn.Forte@Sun.COM /* session */
16547836SJohn.Forte@Sun.COM /*
16557836SJohn.Forte@Sun.COM * Update sess_params with the
16567836SJohn.Forte@Sun.COM * latest params from the
16577836SJohn.Forte@Sun.COM * persistent store.
16587836SJohn.Forte@Sun.COM */
16597836SJohn.Forte@Sun.COM if (iscsi_get_persisted_param(name,
16607836SJohn.Forte@Sun.COM ilg, params) != 0) {
16617836SJohn.Forte@Sun.COM /*
16627836SJohn.Forte@Sun.COM * If the parameter in
16637836SJohn.Forte@Sun.COM * question is not
16647836SJohn.Forte@Sun.COM * overriden, no effect
16657836SJohn.Forte@Sun.COM * on existing session
16667836SJohn.Forte@Sun.COM * parameters. However,
16677836SJohn.Forte@Sun.COM * the parameter is
16687836SJohn.Forte@Sun.COM * marked invalid
16697836SJohn.Forte@Sun.COM * (from the standpoint
16707836SJohn.Forte@Sun.COM * of whether it is
16717836SJohn.Forte@Sun.COM * overriden).
16727836SJohn.Forte@Sun.COM */
16737836SJohn.Forte@Sun.COM valid_flag = B_FALSE;
16747836SJohn.Forte@Sun.COM }
16757836SJohn.Forte@Sun.COM } else if (ilg->g_param_type ==
16767836SJohn.Forte@Sun.COM ISCSI_CONN_PARAM && isp != NULL) {
16777836SJohn.Forte@Sun.COM /* connection */
16787836SJohn.Forte@Sun.COM rw_enter(&isp->sess_conn_list_rwlock,
16797836SJohn.Forte@Sun.COM RW_READER);
16807836SJohn.Forte@Sun.COM /* Assuming 1 conn per sess. */
16817836SJohn.Forte@Sun.COM /*
16827836SJohn.Forte@Sun.COM * MC/S - Need to be modified to
16837836SJohn.Forte@Sun.COM * take g_conn_cid into account when
16847836SJohn.Forte@Sun.COM * we go multi-connection.
16857836SJohn.Forte@Sun.COM */
16867836SJohn.Forte@Sun.COM if ((isp->sess_conn_act != NULL) &&
16877836SJohn.Forte@Sun.COM (isp->sess_conn_act->conn_state ==
16887836SJohn.Forte@Sun.COM ISCSI_CONN_STATE_LOGGED_IN)) {
16897836SJohn.Forte@Sun.COM params = &(isp->
16907836SJohn.Forte@Sun.COM sess_conn_act->
16917836SJohn.Forte@Sun.COM conn_params);
16927836SJohn.Forte@Sun.COM } else {
16937836SJohn.Forte@Sun.COM valid_flag = B_FALSE;
16947836SJohn.Forte@Sun.COM }
16957836SJohn.Forte@Sun.COM rw_exit(&isp->sess_conn_list_rwlock);
16967836SJohn.Forte@Sun.COM }
16977836SJohn.Forte@Sun.COM }
16987836SJohn.Forte@Sun.COM
16997836SJohn.Forte@Sun.COM /* make sure we have params to get info from */
17007836SJohn.Forte@Sun.COM if (params) {
17017836SJohn.Forte@Sun.COM rtn = iscsi_get_param(params, valid_flag, ilg);
17027836SJohn.Forte@Sun.COM
17037836SJohn.Forte@Sun.COM /*
17047836SJohn.Forte@Sun.COM * for target parameters, check if any
17057836SJohn.Forte@Sun.COM * parameters were overridden at the initiator
17067836SJohn.Forte@Sun.COM * level. If so, then change the default value
17077836SJohn.Forte@Sun.COM * to the initiator's overridden value
17087836SJohn.Forte@Sun.COM */
17097836SJohn.Forte@Sun.COM if ((rtn == 0) &&
17107836SJohn.Forte@Sun.COM (ilg->g_oid != ihp->hba_oid)) {
17117836SJohn.Forte@Sun.COM iscsi_override_target_default(ihp,
17127836SJohn.Forte@Sun.COM ilg);
17137836SJohn.Forte@Sun.COM }
17147836SJohn.Forte@Sun.COM }
17157836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
17167836SJohn.Forte@Sun.COM }
17177836SJohn.Forte@Sun.COM
17187836SJohn.Forte@Sun.COM if (rtn == 0) {
17197836SJohn.Forte@Sun.COM rtn = ddi_copyout(ilg, (caddr_t)arg,
17207836SJohn.Forte@Sun.COM sizeof (iscsi_param_get_t), mode);
17217836SJohn.Forte@Sun.COM }
17227836SJohn.Forte@Sun.COM kmem_free(ilg, sizeof (*ilg));
17237836SJohn.Forte@Sun.COM if (tmpParams != NULL)
17247836SJohn.Forte@Sun.COM kmem_free(tmpParams, sizeof (*tmpParams));
17257836SJohn.Forte@Sun.COM break;
17267836SJohn.Forte@Sun.COM
17277836SJohn.Forte@Sun.COM /*
17287836SJohn.Forte@Sun.COM * ISCSI_INIT_NODE_NAME_SET - Change the initiator-node name for
17297836SJohn.Forte@Sun.COM * the specified connection/session.
17307836SJohn.Forte@Sun.COM */
17317836SJohn.Forte@Sun.COM case ISCSI_INIT_NODE_NAME_SET:
17327836SJohn.Forte@Sun.COM /* copyin user args */
17337836SJohn.Forte@Sun.COM ils = (iscsi_param_set_t *)kmem_alloc(sizeof (*ils), KM_SLEEP);
17347836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, ils, sizeof (*ils), mode)) {
17357836SJohn.Forte@Sun.COM rtn = EFAULT;
17367836SJohn.Forte@Sun.COM kmem_free(ils, sizeof (*ils));
17377836SJohn.Forte@Sun.COM break;
17387836SJohn.Forte@Sun.COM }
17397836SJohn.Forte@Sun.COM
17407836SJohn.Forte@Sun.COM if (ils->s_vers != ISCSI_INTERFACE_VERSION) {
17417836SJohn.Forte@Sun.COM rtn = EINVAL;
17427836SJohn.Forte@Sun.COM kmem_free(ils, sizeof (*ils));
17437836SJohn.Forte@Sun.COM break;
17447836SJohn.Forte@Sun.COM }
17457836SJohn.Forte@Sun.COM
17467836SJohn.Forte@Sun.COM /* saving off the old initiator-node name */
17477836SJohn.Forte@Sun.COM initiator_node_name = kmem_zalloc(ISCSI_MAX_NAME_LEN, KM_SLEEP);
17487836SJohn.Forte@Sun.COM rval = persistent_initiator_name_get(initiator_node_name,
17497836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN);
17507836SJohn.Forte@Sun.COM
17517836SJohn.Forte@Sun.COM rtn = iscsi_set_params(ils, ihp, B_TRUE);
17527836SJohn.Forte@Sun.COM kmem_free(ils, sizeof (*ils));
17537836SJohn.Forte@Sun.COM if (rtn != 0) {
17547836SJohn.Forte@Sun.COM kmem_free(initiator_node_name, ISCSI_MAX_NAME_LEN);
17559620SJack.Meng@Sun.COM initiator_node_name = NULL;
17569201SJack.Meng@Sun.COM break;
17577836SJohn.Forte@Sun.COM }
17587836SJohn.Forte@Sun.COM
17597836SJohn.Forte@Sun.COM (void) snprintf(init_port_name, MAX_NAME_PROP_SIZE,
17607836SJohn.Forte@Sun.COM "%s,%02x%02x%02x%02x%02x%02x",
17617836SJohn.Forte@Sun.COM (char *)ihp->hba_name, ihp->hba_isid[0],
17627836SJohn.Forte@Sun.COM ihp->hba_isid[1], ihp->hba_isid[2],
17637836SJohn.Forte@Sun.COM ihp->hba_isid[3], ihp->hba_isid[4],
17647836SJohn.Forte@Sun.COM ihp->hba_isid[5]);
17657836SJohn.Forte@Sun.COM
17667836SJohn.Forte@Sun.COM if (ddi_prop_update_string(DDI_DEV_T_NONE,
176710696SDavid.Hollister@Sun.COM ihp->hba_dip, SCSI_ADDR_PROP_INITIATOR_PORT,
17687836SJohn.Forte@Sun.COM init_port_name) != DDI_PROP_SUCCESS) {
17697836SJohn.Forte@Sun.COM cmn_err(CE_WARN, "iscsi_ioctl: Updating "
177010696SDavid.Hollister@Sun.COM SCSI_ADDR_PROP_INITIATOR_PORT " property on iSCSI "
17717836SJohn.Forte@Sun.COM "HBA(%s) with dip(%d) Failed",
17727836SJohn.Forte@Sun.COM (char *)ihp->hba_name,
17737836SJohn.Forte@Sun.COM ddi_get_instance(ihp->hba_dip));
17747836SJohn.Forte@Sun.COM }
17757836SJohn.Forte@Sun.COM
17767836SJohn.Forte@Sun.COM /*
17777836SJohn.Forte@Sun.COM * Deregister the old initiator-node name from the iSNS
17787836SJohn.Forte@Sun.COM * server
17797836SJohn.Forte@Sun.COM * Register the new initiator-node name with the iSNS server
17807836SJohn.Forte@Sun.COM */
17817836SJohn.Forte@Sun.COM method = persistent_disc_meth_get();
17827836SJohn.Forte@Sun.COM if (method & iSCSIDiscoveryMethodISNS) {
17837836SJohn.Forte@Sun.COM if (rval == B_TRUE) {
17847836SJohn.Forte@Sun.COM if (strlen(initiator_node_name) > 0) {
17857836SJohn.Forte@Sun.COM /*
17867836SJohn.Forte@Sun.COM * we will attempt to offline the targets.
17877836SJohn.Forte@Sun.COM * if logouts fail, we will still continue
17887836SJohn.Forte@Sun.COM */
17897836SJohn.Forte@Sun.COM #define STRING_INNO "initiator-node name - Offline "
17907836SJohn.Forte@Sun.COM #define STRING_FFOMD "failed for one or more devices"
17917836SJohn.Forte@Sun.COM if ((iscsid_del(
17927836SJohn.Forte@Sun.COM ihp, NULL, method, NULL))
17937836SJohn.Forte@Sun.COM != B_TRUE) {
17947836SJohn.Forte@Sun.COM cmn_err(CE_NOTE,
17957836SJohn.Forte@Sun.COM "Attempting to change "
17967836SJohn.Forte@Sun.COM STRING_INNO
17977836SJohn.Forte@Sun.COM STRING_FFOMD);
17987836SJohn.Forte@Sun.COM }
17997836SJohn.Forte@Sun.COM (void) isns_dereg(ihp->hba_isid,
18007836SJohn.Forte@Sun.COM (uint8_t *)initiator_node_name);
18017836SJohn.Forte@Sun.COM #undef STRING_INNO
18027836SJohn.Forte@Sun.COM #undef STRING_FFOMD
18037836SJohn.Forte@Sun.COM }
18047836SJohn.Forte@Sun.COM }
18057836SJohn.Forte@Sun.COM if (persistent_initiator_name_get(initiator_node_name,
18067836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN) != B_TRUE) {
18077836SJohn.Forte@Sun.COM kmem_free(initiator_node_name,
18087836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN);
18097836SJohn.Forte@Sun.COM initiator_node_name = NULL;
18107836SJohn.Forte@Sun.COM rtn = EIO;
18117836SJohn.Forte@Sun.COM break;
18127836SJohn.Forte@Sun.COM }
18137836SJohn.Forte@Sun.COM if (strlen(initiator_node_name) == 0) {
18147836SJohn.Forte@Sun.COM kmem_free(initiator_node_name,
18157836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN);
18167836SJohn.Forte@Sun.COM initiator_node_name = NULL;
18177836SJohn.Forte@Sun.COM rtn = EIO;
18187836SJohn.Forte@Sun.COM break;
18197836SJohn.Forte@Sun.COM }
18207836SJohn.Forte@Sun.COM
18217836SJohn.Forte@Sun.COM initiator_node_alias = kmem_zalloc(ISCSI_MAX_NAME_LEN,
18227836SJohn.Forte@Sun.COM KM_SLEEP);
18237836SJohn.Forte@Sun.COM if (persistent_alias_name_get(initiator_node_alias,
18247836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN) != B_TRUE) {
18257836SJohn.Forte@Sun.COM initiator_node_alias[0] = '\0';
18267836SJohn.Forte@Sun.COM }
18277836SJohn.Forte@Sun.COM
18287836SJohn.Forte@Sun.COM (void) isns_reg(ihp->hba_isid,
18297836SJohn.Forte@Sun.COM (uint8_t *)initiator_node_name,
18307836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN,
18317836SJohn.Forte@Sun.COM (uint8_t *)initiator_node_alias,
18327836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN,
18337836SJohn.Forte@Sun.COM ISNS_INITIATOR_NODE_TYPE,
18347836SJohn.Forte@Sun.COM isns_scn_callback);
18357836SJohn.Forte@Sun.COM iscsid_do_isns_query(ihp);
18367836SJohn.Forte@Sun.COM
18377836SJohn.Forte@Sun.COM kmem_free(initiator_node_alias, ISCSI_MAX_NAME_LEN);
18387836SJohn.Forte@Sun.COM initiator_node_alias = NULL;
18397836SJohn.Forte@Sun.COM }
18409620SJack.Meng@Sun.COM
18419620SJack.Meng@Sun.COM kmem_free(initiator_node_name, ISCSI_MAX_NAME_LEN);
18429620SJack.Meng@Sun.COM initiator_node_name = NULL;
18437836SJohn.Forte@Sun.COM break;
18447836SJohn.Forte@Sun.COM
18457836SJohn.Forte@Sun.COM /*
18467836SJohn.Forte@Sun.COM * ISCSI_PARAM_SET - Set param for specified connection/session.
18477836SJohn.Forte@Sun.COM */
18487836SJohn.Forte@Sun.COM case ISCSI_PARAM_SET:
18497836SJohn.Forte@Sun.COM /* copyin user args */
18507836SJohn.Forte@Sun.COM ils = (iscsi_param_set_t *)kmem_alloc(sizeof (*ils), KM_SLEEP);
18517836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, ils, sizeof (*ils), mode)) {
18527836SJohn.Forte@Sun.COM rtn = EFAULT;
18537836SJohn.Forte@Sun.COM kmem_free(ils, sizeof (*ils));
18547836SJohn.Forte@Sun.COM break;
18557836SJohn.Forte@Sun.COM }
18567836SJohn.Forte@Sun.COM
18577836SJohn.Forte@Sun.COM if (ils->s_vers != ISCSI_INTERFACE_VERSION) {
18587836SJohn.Forte@Sun.COM rtn = EINVAL;
18597836SJohn.Forte@Sun.COM kmem_free(ils, sizeof (*ils));
18607836SJohn.Forte@Sun.COM break;
18617836SJohn.Forte@Sun.COM }
18627836SJohn.Forte@Sun.COM rtn = iscsi_set_params(ils, ihp, B_TRUE);
18638194SJack.Meng@Sun.COM if (iscsiboot_prop) {
18648194SJack.Meng@Sun.COM if (iscsi_cmp_boot_sess_oid(ihp, ils->s_oid)) {
18658194SJack.Meng@Sun.COM /*
18668194SJack.Meng@Sun.COM * found active session for this object
18678194SJack.Meng@Sun.COM * or this is initiator's object
18688194SJack.Meng@Sun.COM * with mpxio enabled
18698194SJack.Meng@Sun.COM */
18708194SJack.Meng@Sun.COM if (!iscsi_reconfig_boot_sess(ihp)) {
18718194SJack.Meng@Sun.COM rtn = EINVAL;
18728194SJack.Meng@Sun.COM kmem_free(ils, sizeof (*ils));
18738194SJack.Meng@Sun.COM break;
18748194SJack.Meng@Sun.COM }
18758194SJack.Meng@Sun.COM }
18768194SJack.Meng@Sun.COM }
18777836SJohn.Forte@Sun.COM kmem_free(ils, sizeof (*ils));
18787836SJohn.Forte@Sun.COM break;
18797836SJohn.Forte@Sun.COM
18807836SJohn.Forte@Sun.COM /*
18817836SJohn.Forte@Sun.COM * ISCSI_TARGET_PARAM_CLEAR
18827836SJohn.Forte@Sun.COM * - remove custom parameter settings for a target.
18837836SJohn.Forte@Sun.COM */
18847836SJohn.Forte@Sun.COM case ISCSI_TARGET_PARAM_CLEAR:
18857836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &e, sizeof (e), mode)) {
18867836SJohn.Forte@Sun.COM rtn = EFAULT;
18877836SJohn.Forte@Sun.COM break;
18887836SJohn.Forte@Sun.COM } else if (e.e_vers != ISCSI_INTERFACE_VERSION) {
18897836SJohn.Forte@Sun.COM rtn = EINVAL;
18907836SJohn.Forte@Sun.COM break;
18917836SJohn.Forte@Sun.COM }
18927836SJohn.Forte@Sun.COM
18937836SJohn.Forte@Sun.COM if ((e.e_oid != ihp->hba_oid) &&
18947836SJohn.Forte@Sun.COM (e.e_oid != ISCSI_OID_NOTSET)) {
189510978SZhang.Yi@Sun.COM boolean_t rval1, rval2, rval3;
18967836SJohn.Forte@Sun.COM uchar_t *t_name;
18977836SJohn.Forte@Sun.COM iscsi_sess_t *t_isp;
189810978SZhang.Yi@Sun.COM boolean_t t_rtn = B_TRUE;
189910978SZhang.Yi@Sun.COM persistent_param_t t_param;
190010978SZhang.Yi@Sun.COM iscsi_config_sess_t t_ics;
190110978SZhang.Yi@Sun.COM persistent_tunable_param_t t_tpsg;
19027836SJohn.Forte@Sun.COM
19037836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
19047836SJohn.Forte@Sun.COM /*
19057836SJohn.Forte@Sun.COM * If the oid does represent a session check to see
19067836SJohn.Forte@Sun.COM * if it is a target oid. If so, return the target's
19077836SJohn.Forte@Sun.COM * associated session.
19087836SJohn.Forte@Sun.COM */
19097836SJohn.Forte@Sun.COM rtn = iscsi_sess_get(e.e_oid, ihp, &isp);
19107836SJohn.Forte@Sun.COM if (rtn != 0) {
19117836SJohn.Forte@Sun.COM rtn = iscsi_sess_get_by_target(e.e_oid, ihp,
19127836SJohn.Forte@Sun.COM &isp);
19137836SJohn.Forte@Sun.COM }
19147836SJohn.Forte@Sun.COM
19157836SJohn.Forte@Sun.COM /*
19167836SJohn.Forte@Sun.COM * If rtn is zero then we have found an
19177836SJohn.Forte@Sun.COM * existing session. Use the session name to
19187836SJohn.Forte@Sun.COM * do param lookup. If rtn is non-zero then
19197836SJohn.Forte@Sun.COM * create a targetparam object and use its name
19207836SJohn.Forte@Sun.COM * for param lookup.
19217836SJohn.Forte@Sun.COM */
19227836SJohn.Forte@Sun.COM if (rtn == 0) {
19237836SJohn.Forte@Sun.COM t_name = isp->sess_name;
19247836SJohn.Forte@Sun.COM } else {
19257836SJohn.Forte@Sun.COM t_name = iscsi_targetparam_get_name(e.e_oid);
19267836SJohn.Forte@Sun.COM rtn = 0;
19277836SJohn.Forte@Sun.COM }
19287836SJohn.Forte@Sun.COM
19297836SJohn.Forte@Sun.COM if (t_name == NULL) {
19307836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
19317836SJohn.Forte@Sun.COM rtn = EFAULT;
19327836SJohn.Forte@Sun.COM break;
19337836SJohn.Forte@Sun.COM }
19347836SJohn.Forte@Sun.COM
19357836SJohn.Forte@Sun.COM name = kmem_zalloc(ISCSI_MAX_NAME_LEN, KM_SLEEP);
19367836SJohn.Forte@Sun.COM (void) strncpy((char *)name, (char *)t_name,
19377836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN);
19387836SJohn.Forte@Sun.COM
193910978SZhang.Yi@Sun.COM t_ics.ics_in = 1;
194010978SZhang.Yi@Sun.COM rval1 = persistent_param_get((char *)name, &t_param);
194110978SZhang.Yi@Sun.COM rval2 = persistent_get_config_session((char *)name,
194210978SZhang.Yi@Sun.COM &t_ics);
194310978SZhang.Yi@Sun.COM rval3 = persistent_get_tunable_param((char *)name,
194410978SZhang.Yi@Sun.COM &t_tpsg);
194510978SZhang.Yi@Sun.COM
194610978SZhang.Yi@Sun.COM if ((rval1 == B_FALSE) && (rval2 == B_FALSE) &&
194710978SZhang.Yi@Sun.COM (rval3 == B_FALSE)) {
194810978SZhang.Yi@Sun.COM /* no any target parameters get */
194910978SZhang.Yi@Sun.COM kmem_free(name, ISCSI_MAX_NAME_LEN);
195010978SZhang.Yi@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
195110978SZhang.Yi@Sun.COM rtn = EIO;
195210978SZhang.Yi@Sun.COM break;
195310978SZhang.Yi@Sun.COM }
195410978SZhang.Yi@Sun.COM
19557836SJohn.Forte@Sun.COM if (persistent_param_clear((char *)name) == B_FALSE) {
19567836SJohn.Forte@Sun.COM kmem_free(name, ISCSI_MAX_NAME_LEN);
19577836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
19587836SJohn.Forte@Sun.COM rtn = EIO;
19597836SJohn.Forte@Sun.COM break;
19607836SJohn.Forte@Sun.COM }
19617836SJohn.Forte@Sun.COM
19627836SJohn.Forte@Sun.COM ics = kmem_zalloc(sizeof (*ics), KM_SLEEP);
19637836SJohn.Forte@Sun.COM ics->ics_ver = ISCSI_INTERFACE_VERSION;
19647836SJohn.Forte@Sun.COM ics->ics_oid = ISCSI_INITIATOR_OID;
19657836SJohn.Forte@Sun.COM ics->ics_in = 1;
19667836SJohn.Forte@Sun.COM
19677836SJohn.Forte@Sun.COM /*
19687836SJohn.Forte@Sun.COM * We may have multiple sessions with different
19697836SJohn.Forte@Sun.COM * tpgt values. So we need to loop through
19707836SJohn.Forte@Sun.COM * the sessions and update all sessions.
19717836SJohn.Forte@Sun.COM */
19727836SJohn.Forte@Sun.COM for (isp = ihp->hba_sess_list; isp;
19737836SJohn.Forte@Sun.COM isp = t_isp) {
19747836SJohn.Forte@Sun.COM t_isp = isp->sess_next;
19757836SJohn.Forte@Sun.COM
19767836SJohn.Forte@Sun.COM if (strncmp((char *)isp->sess_name,
19777836SJohn.Forte@Sun.COM (char *)name, ISCSI_MAX_NAME_LEN) == 0) {
19787836SJohn.Forte@Sun.COM /*
19797836SJohn.Forte@Sun.COM * When removing target-params we need
19807836SJohn.Forte@Sun.COM * slightly different actions depending
19817836SJohn.Forte@Sun.COM * on if the session should still exist.
19827836SJohn.Forte@Sun.COM * Get the initiator-node value for
19837836SJohn.Forte@Sun.COM * MS/T. If there is no initiator
19847836SJohn.Forte@Sun.COM * value then assume the default value
19857836SJohn.Forte@Sun.COM * of 1. If the initiator value is
19867836SJohn.Forte@Sun.COM * less than this ISID then we need to
19877836SJohn.Forte@Sun.COM * destroy the session. Otherwise
19887836SJohn.Forte@Sun.COM * update the session information and
19897836SJohn.Forte@Sun.COM * resync (N7 event).
19907836SJohn.Forte@Sun.COM */
19917836SJohn.Forte@Sun.COM rtn = iscsi_ioctl_get_config_sess(
19927836SJohn.Forte@Sun.COM ihp, ics);
19937836SJohn.Forte@Sun.COM if (((rtn != 0) &&
19947836SJohn.Forte@Sun.COM (isp->sess_isid[5] > 0)) ||
19957836SJohn.Forte@Sun.COM ((rtn == 0) &&
19967836SJohn.Forte@Sun.COM (ics->ics_out <=
19977836SJohn.Forte@Sun.COM isp->sess_isid[5]))) {
19987836SJohn.Forte@Sun.COM
19997836SJohn.Forte@Sun.COM /*
20007836SJohn.Forte@Sun.COM * This session should no
20017836SJohn.Forte@Sun.COM * longer exist. Remove
20027836SJohn.Forte@Sun.COM * session.
20037836SJohn.Forte@Sun.COM */
20047836SJohn.Forte@Sun.COM if (!ISCSI_SUCCESS(
20057836SJohn.Forte@Sun.COM iscsi_sess_destroy(isp))) {
200610978SZhang.Yi@Sun.COM t_rtn = B_FALSE;
200710978SZhang.Yi@Sun.COM continue;
20087836SJohn.Forte@Sun.COM }
20097836SJohn.Forte@Sun.COM isp = ihp->hba_sess_list;
20107836SJohn.Forte@Sun.COM } else {
201112161SJack.Meng@Sun.COM uint32_t event_count;
20127836SJohn.Forte@Sun.COM /*
20137836SJohn.Forte@Sun.COM * Reset the session
20147836SJohn.Forte@Sun.COM * parameters.
20157836SJohn.Forte@Sun.COM */
20167836SJohn.Forte@Sun.COM bcopy(&(isp->sess_hba->
20177836SJohn.Forte@Sun.COM hba_params),
20187836SJohn.Forte@Sun.COM &(isp->sess_params),
20197836SJohn.Forte@Sun.COM sizeof (isp->sess_params));
20208194SJack.Meng@Sun.COM if (iscsiboot_prop &&
20218194SJack.Meng@Sun.COM isp->sess_boot) {
20228194SJack.Meng@Sun.COM /*
20238194SJack.Meng@Sun.COM * reconfig boot
20248194SJack.Meng@Sun.COM * session later
20258194SJack.Meng@Sun.COM */
20268194SJack.Meng@Sun.COM continue;
20278194SJack.Meng@Sun.COM }
20287836SJohn.Forte@Sun.COM /*
20297836SJohn.Forte@Sun.COM * Notify the session that the
20307836SJohn.Forte@Sun.COM * login parameters have
20317836SJohn.Forte@Sun.COM * changed.
20327836SJohn.Forte@Sun.COM */
203312161SJack.Meng@Sun.COM event_count = atomic_inc_32_nv(
203412161SJack.Meng@Sun.COM &isp->
203512161SJack.Meng@Sun.COM sess_state_event_count);
203612161SJack.Meng@Sun.COM iscsi_sess_enter_state_zone(
203712161SJack.Meng@Sun.COM isp);
203812161SJack.Meng@Sun.COM
20397836SJohn.Forte@Sun.COM iscsi_sess_state_machine(isp,
204012161SJack.Meng@Sun.COM ISCSI_SESS_EVENT_N7,
204112161SJack.Meng@Sun.COM event_count);
204212161SJack.Meng@Sun.COM
204312161SJack.Meng@Sun.COM iscsi_sess_exit_state_zone(
204412161SJack.Meng@Sun.COM isp);
20457836SJohn.Forte@Sun.COM }
20467836SJohn.Forte@Sun.COM }
20477836SJohn.Forte@Sun.COM }
204810978SZhang.Yi@Sun.COM if (t_rtn == B_FALSE) {
204910978SZhang.Yi@Sun.COM boolean_t t_rval = B_TRUE;
205010978SZhang.Yi@Sun.COM /* Failure!, restore target's parameters */
205110978SZhang.Yi@Sun.COM if (rval1 == B_TRUE) {
205210978SZhang.Yi@Sun.COM rval1 = persistent_param_set(
205310978SZhang.Yi@Sun.COM (char *)name, &t_param);
205410978SZhang.Yi@Sun.COM if (rval1 == B_FALSE) {
205510978SZhang.Yi@Sun.COM t_rval = B_FALSE;
205610978SZhang.Yi@Sun.COM }
205710978SZhang.Yi@Sun.COM }
205810978SZhang.Yi@Sun.COM if (rval2 == B_TRUE) {
205910978SZhang.Yi@Sun.COM rval2 = persistent_set_config_session(
206010978SZhang.Yi@Sun.COM (char *)name, &t_ics);
206110978SZhang.Yi@Sun.COM if (rval2 == B_FALSE) {
206210978SZhang.Yi@Sun.COM t_rval = B_FALSE;
206310978SZhang.Yi@Sun.COM }
206410978SZhang.Yi@Sun.COM }
206510978SZhang.Yi@Sun.COM if (rval3 == B_TRUE) {
206610978SZhang.Yi@Sun.COM rval3 = persistent_set_tunable_param(
206710978SZhang.Yi@Sun.COM (char *)name, &t_tpsg);
206810978SZhang.Yi@Sun.COM if (rval3 == B_FALSE) {
206910978SZhang.Yi@Sun.COM t_rval = B_FALSE;
207010978SZhang.Yi@Sun.COM }
207110978SZhang.Yi@Sun.COM }
207210978SZhang.Yi@Sun.COM if (t_rval == B_FALSE) {
207310978SZhang.Yi@Sun.COM cmn_err(CE_WARN, "Failed to restore "
207410978SZhang.Yi@Sun.COM "target's parameters after remove "
207510978SZhang.Yi@Sun.COM "session related to target "
207610978SZhang.Yi@Sun.COM "parameters failure.");
207710978SZhang.Yi@Sun.COM }
207810978SZhang.Yi@Sun.COM rtn = EBUSY;
207910978SZhang.Yi@Sun.COM }
20807836SJohn.Forte@Sun.COM kmem_free(ics, sizeof (*ics));
20817836SJohn.Forte@Sun.COM kmem_free(name, ISCSI_MAX_NAME_LEN);
20827836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
20838194SJack.Meng@Sun.COM if (iscsiboot_prop) {
20848194SJack.Meng@Sun.COM if (iscsi_cmp_boot_sess_oid(ihp, e.e_oid)) {
20858194SJack.Meng@Sun.COM /*
20868194SJack.Meng@Sun.COM * found active session for this object
20878194SJack.Meng@Sun.COM * or this is initiator object
20888194SJack.Meng@Sun.COM * with mpxio enabled
20898194SJack.Meng@Sun.COM */
20908194SJack.Meng@Sun.COM if (!iscsi_reconfig_boot_sess(ihp)) {
20918194SJack.Meng@Sun.COM rtn = EINVAL;
20928194SJack.Meng@Sun.COM break;
20938194SJack.Meng@Sun.COM }
20948194SJack.Meng@Sun.COM }
20958194SJack.Meng@Sun.COM }
20967836SJohn.Forte@Sun.COM }
20977836SJohn.Forte@Sun.COM break;
20987836SJohn.Forte@Sun.COM
20997836SJohn.Forte@Sun.COM /*
21007836SJohn.Forte@Sun.COM * ISCSI_TARGET_OID_LIST_GET -
21017836SJohn.Forte@Sun.COM */
21027836SJohn.Forte@Sun.COM case ISCSI_TARGET_OID_LIST_GET:
21037836SJohn.Forte@Sun.COM /* copyin user args */
21047836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &idl,
21057836SJohn.Forte@Sun.COM sizeof (idl), mode)) {
21067836SJohn.Forte@Sun.COM rtn = EFAULT;
21077836SJohn.Forte@Sun.COM break;
21087836SJohn.Forte@Sun.COM }
21097836SJohn.Forte@Sun.COM
21107836SJohn.Forte@Sun.COM if (idl.tl_vers != ISCSI_INTERFACE_VERSION) {
21117836SJohn.Forte@Sun.COM rtn = EINVAL;
21127836SJohn.Forte@Sun.COM break;
21137836SJohn.Forte@Sun.COM }
21147836SJohn.Forte@Sun.COM
21157836SJohn.Forte@Sun.COM list_space = sizeof (iscsi_target_list_t);
21167836SJohn.Forte@Sun.COM if (idl.tl_in_cnt != 0)
21177836SJohn.Forte@Sun.COM list_space += (sizeof (uint32_t) *
21187836SJohn.Forte@Sun.COM (idl.tl_in_cnt - 1));
21197836SJohn.Forte@Sun.COM
21207836SJohn.Forte@Sun.COM idlp = kmem_zalloc(list_space, KM_SLEEP);
21217836SJohn.Forte@Sun.COM bcopy(&idl, idlp, sizeof (idl));
21227836SJohn.Forte@Sun.COM idlp->tl_out_cnt = 0;
21237836SJohn.Forte@Sun.COM
21247836SJohn.Forte@Sun.COM /*
21257836SJohn.Forte@Sun.COM * If target list type is ISCSI_TGT_OID_LIST and discovery
21267836SJohn.Forte@Sun.COM * has not been completed or in progress, poke the discovery
21277836SJohn.Forte@Sun.COM * methods so target information is returned
21287836SJohn.Forte@Sun.COM */
21297836SJohn.Forte@Sun.COM mutex_enter(&ihp->hba_discovery_events_mutex);
21307836SJohn.Forte@Sun.COM method = ihp->hba_discovery_events;
21317836SJohn.Forte@Sun.COM if ((idl.tl_tgt_list_type == ISCSI_TGT_OID_LIST) &&
21327836SJohn.Forte@Sun.COM (method != ISCSI_ALL_DISCOVERY_METHODS) &&
21337836SJohn.Forte@Sun.COM (ihp->hba_discovery_in_progress == B_FALSE)) {
21347836SJohn.Forte@Sun.COM ihp->hba_discovery_in_progress = B_TRUE;
21357836SJohn.Forte@Sun.COM mutex_exit(&ihp->hba_discovery_events_mutex);
21367836SJohn.Forte@Sun.COM iscsid_poke_discovery(ihp, iSCSIDiscoveryMethodUnknown);
21377836SJohn.Forte@Sun.COM mutex_enter(&ihp->hba_discovery_events_mutex);
21387836SJohn.Forte@Sun.COM ihp->hba_discovery_in_progress = B_FALSE;
21397836SJohn.Forte@Sun.COM }
21407836SJohn.Forte@Sun.COM mutex_exit(&ihp->hba_discovery_events_mutex);
21417836SJohn.Forte@Sun.COM
21427836SJohn.Forte@Sun.COM /*
21437836SJohn.Forte@Sun.COM * Return the correct list information based on the type
21447836SJohn.Forte@Sun.COM */
21457836SJohn.Forte@Sun.COM switch (idl.tl_tgt_list_type) {
21467836SJohn.Forte@Sun.COM /* ISCSI_TGT_PARAM_OID_LIST - iscsiadm list target-params */
21477836SJohn.Forte@Sun.COM case ISCSI_TGT_PARAM_OID_LIST:
21487836SJohn.Forte@Sun.COM /* get params from persistent store */
21497836SJohn.Forte@Sun.COM iscsi_targetparam_lock_list(RW_READER);
21507836SJohn.Forte@Sun.COM curr_entry = iscsi_targetparam_get_next_entry(NULL);
21517836SJohn.Forte@Sun.COM while (curr_entry != NULL) {
21527836SJohn.Forte@Sun.COM if (idlp->tl_out_cnt < idlp->tl_in_cnt) {
21537836SJohn.Forte@Sun.COM idlp->tl_oid_list[idlp->tl_out_cnt] =
21547836SJohn.Forte@Sun.COM curr_entry->target_oid;
21557836SJohn.Forte@Sun.COM }
21567836SJohn.Forte@Sun.COM idlp->tl_out_cnt++;
21577836SJohn.Forte@Sun.COM curr_entry = iscsi_targetparam_get_next_entry(
21587836SJohn.Forte@Sun.COM curr_entry);
21597836SJohn.Forte@Sun.COM }
21607836SJohn.Forte@Sun.COM iscsi_targetparam_unlock_list();
21617836SJohn.Forte@Sun.COM break;
21627836SJohn.Forte@Sun.COM
21637836SJohn.Forte@Sun.COM /* ISCSI_STATIC_TGT_OID_LIST - iscsiadm list static-config */
21647836SJohn.Forte@Sun.COM case ISCSI_STATIC_TGT_OID_LIST:
21657836SJohn.Forte@Sun.COM {
21667836SJohn.Forte@Sun.COM char *target_name = NULL;
21677836SJohn.Forte@Sun.COM void *v = NULL;
21687836SJohn.Forte@Sun.COM
21697836SJohn.Forte@Sun.COM /* get static-config from persistent store */
21707836SJohn.Forte@Sun.COM target_name = kmem_zalloc(ISCSI_MAX_NAME_LEN, KM_SLEEP);
21717836SJohn.Forte@Sun.COM persistent_static_addr_lock();
21727836SJohn.Forte@Sun.COM while (persistent_static_addr_next(&v,
21737836SJohn.Forte@Sun.COM (char *)target_name, &e) == B_TRUE) {
21747836SJohn.Forte@Sun.COM
21757836SJohn.Forte@Sun.COM if (idlp->tl_out_cnt < idlp->tl_in_cnt) {
21767836SJohn.Forte@Sun.COM idlp->tl_oid_list[idlp->tl_out_cnt] =
21777836SJohn.Forte@Sun.COM e.e_oid;
21787836SJohn.Forte@Sun.COM }
21797836SJohn.Forte@Sun.COM idlp->tl_out_cnt++;
21807836SJohn.Forte@Sun.COM
21817836SJohn.Forte@Sun.COM }
21827836SJohn.Forte@Sun.COM
21837836SJohn.Forte@Sun.COM persistent_static_addr_unlock();
21847836SJohn.Forte@Sun.COM kmem_free(target_name, ISCSI_MAX_NAME_LEN);
21857836SJohn.Forte@Sun.COM break;
21867836SJohn.Forte@Sun.COM }
21877836SJohn.Forte@Sun.COM
21887836SJohn.Forte@Sun.COM /* ISCSI_TGT_OID_LIST - iscsiadm list target */
21897836SJohn.Forte@Sun.COM case ISCSI_TGT_OID_LIST:
21907836SJohn.Forte@Sun.COM
21917836SJohn.Forte@Sun.COM /* get sessions from hba's session list */
21927836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
21937836SJohn.Forte@Sun.COM for (isp = ihp->hba_sess_list; isp;
21947836SJohn.Forte@Sun.COM isp = isp->sess_next) {
21957836SJohn.Forte@Sun.COM
21967836SJohn.Forte@Sun.COM if (((isp->sess_state !=
21977836SJohn.Forte@Sun.COM ISCSI_SESS_STATE_FREE) ||
21987836SJohn.Forte@Sun.COM (isp->sess_discovered_by !=
21997836SJohn.Forte@Sun.COM iSCSIDiscoveryMethodUnknown)) &&
22007836SJohn.Forte@Sun.COM (isp->sess_type ==
22017836SJohn.Forte@Sun.COM ISCSI_SESS_TYPE_NORMAL)) {
22027836SJohn.Forte@Sun.COM if (idlp->tl_out_cnt <
22037836SJohn.Forte@Sun.COM idlp->tl_in_cnt) {
22047836SJohn.Forte@Sun.COM idlp->tl_oid_list[
22057836SJohn.Forte@Sun.COM idlp->tl_out_cnt] =
22067836SJohn.Forte@Sun.COM isp->sess_oid;
22077836SJohn.Forte@Sun.COM }
22087836SJohn.Forte@Sun.COM idlp->tl_out_cnt++;
22097836SJohn.Forte@Sun.COM }
22107836SJohn.Forte@Sun.COM
22117836SJohn.Forte@Sun.COM }
22127836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
22137836SJohn.Forte@Sun.COM break;
22147836SJohn.Forte@Sun.COM
22157836SJohn.Forte@Sun.COM default:
22167836SJohn.Forte@Sun.COM ASSERT(FALSE);
22177836SJohn.Forte@Sun.COM }
22187836SJohn.Forte@Sun.COM
22197836SJohn.Forte@Sun.COM rtn = ddi_copyout(idlp, (caddr_t)arg, list_space, mode);
22207836SJohn.Forte@Sun.COM kmem_free(idlp, list_space);
22217836SJohn.Forte@Sun.COM break;
22227836SJohn.Forte@Sun.COM
22237836SJohn.Forte@Sun.COM /*
22247836SJohn.Forte@Sun.COM * ISCSI_TARGET_PROPS_GET -
22257836SJohn.Forte@Sun.COM */
22267836SJohn.Forte@Sun.COM case ISCSI_TARGET_PROPS_GET:
22277836SJohn.Forte@Sun.COM /* ---- fall through sense the code is almost the same ---- */
22287836SJohn.Forte@Sun.COM
22297836SJohn.Forte@Sun.COM /*
22307836SJohn.Forte@Sun.COM * ISCSI_TARGET_PROPS_SET -
22317836SJohn.Forte@Sun.COM */
22327836SJohn.Forte@Sun.COM case ISCSI_TARGET_PROPS_SET:
22337836SJohn.Forte@Sun.COM /* copyin user args */
22347836SJohn.Forte@Sun.COM ipp = (iscsi_property_t *)kmem_alloc(sizeof (*ipp),
22357836SJohn.Forte@Sun.COM KM_SLEEP);
22367836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, ipp, sizeof (*ipp), mode)) {
22377836SJohn.Forte@Sun.COM rtn = EFAULT;
22387836SJohn.Forte@Sun.COM kmem_free(ipp, sizeof (*ipp));
22397836SJohn.Forte@Sun.COM break;
22407836SJohn.Forte@Sun.COM }
22417836SJohn.Forte@Sun.COM
22427836SJohn.Forte@Sun.COM if (ipp->p_vers != ISCSI_INTERFACE_VERSION) {
22437836SJohn.Forte@Sun.COM rtn = EINVAL;
22447836SJohn.Forte@Sun.COM kmem_free(ipp, sizeof (*ipp));
22457836SJohn.Forte@Sun.COM break;
22467836SJohn.Forte@Sun.COM }
22477836SJohn.Forte@Sun.COM
22487836SJohn.Forte@Sun.COM rtn = iscsi_target_prop_mod(ihp, ipp, cmd);
22497836SJohn.Forte@Sun.COM if (rtn == 0)
22507836SJohn.Forte@Sun.COM rtn = ddi_copyout(ipp, (caddr_t)arg,
22517836SJohn.Forte@Sun.COM sizeof (*ipp), mode);
22527836SJohn.Forte@Sun.COM kmem_free(ipp, sizeof (*ipp));
22537836SJohn.Forte@Sun.COM break;
22547836SJohn.Forte@Sun.COM
22557836SJohn.Forte@Sun.COM /*
22567836SJohn.Forte@Sun.COM * ISCSI_TARGET_ADDRESS_GET -
22577836SJohn.Forte@Sun.COM */
22587836SJohn.Forte@Sun.COM case ISCSI_TARGET_ADDRESS_GET:
22597836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &ial, sizeof (ial), mode)) {
22607836SJohn.Forte@Sun.COM rtn = EFAULT;
22617836SJohn.Forte@Sun.COM break;
22627836SJohn.Forte@Sun.COM }
22637836SJohn.Forte@Sun.COM
22647836SJohn.Forte@Sun.COM if (ial.al_vers != ISCSI_INTERFACE_VERSION) {
22657836SJohn.Forte@Sun.COM rtn = EINVAL;
22667836SJohn.Forte@Sun.COM break;
22677836SJohn.Forte@Sun.COM }
22687836SJohn.Forte@Sun.COM
22697836SJohn.Forte@Sun.COM /*
22707836SJohn.Forte@Sun.COM * Find out how much space we need to malloc for the users
22717836SJohn.Forte@Sun.COM * request.
22727836SJohn.Forte@Sun.COM */
22737836SJohn.Forte@Sun.COM list_space = sizeof (iscsi_addr_list_t);
22747836SJohn.Forte@Sun.COM if (ial.al_in_cnt != 0) {
22757836SJohn.Forte@Sun.COM list_space += (sizeof (iscsi_addr_t) *
22767836SJohn.Forte@Sun.COM (ial.al_in_cnt - 1));
22777836SJohn.Forte@Sun.COM }
22787836SJohn.Forte@Sun.COM ialp = (iscsi_addr_list_t *)kmem_zalloc(list_space, KM_SLEEP);
22797836SJohn.Forte@Sun.COM
22807836SJohn.Forte@Sun.COM /* Copy in the header portion */
22817836SJohn.Forte@Sun.COM bcopy(&ial, ialp, sizeof (ial));
22827836SJohn.Forte@Sun.COM
22837836SJohn.Forte@Sun.COM /* session */
22847836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
22857836SJohn.Forte@Sun.COM rtn = iscsi_sess_get(ialp->al_oid, ihp, &isp);
22867836SJohn.Forte@Sun.COM if (rtn != 0) {
22877836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
22887836SJohn.Forte@Sun.COM rtn = EFAULT;
22897836SJohn.Forte@Sun.COM break;
22907836SJohn.Forte@Sun.COM }
22917836SJohn.Forte@Sun.COM
22927836SJohn.Forte@Sun.COM ialp->al_out_cnt = 0;
22937836SJohn.Forte@Sun.COM ialp->al_tpgt = isp->sess_tpgt_conf;
22947836SJohn.Forte@Sun.COM rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
22957836SJohn.Forte@Sun.COM for (icp = isp->sess_conn_list; icp; icp = icp->conn_next) {
22967836SJohn.Forte@Sun.COM if (icp->conn_state != ISCSI_CONN_STATE_LOGGED_IN) {
22977836SJohn.Forte@Sun.COM continue;
22987836SJohn.Forte@Sun.COM }
22997836SJohn.Forte@Sun.COM if (ialp->al_out_cnt < ialp->al_in_cnt) {
23007836SJohn.Forte@Sun.COM iscsi_addr_t *ap;
23017836SJohn.Forte@Sun.COM
23027836SJohn.Forte@Sun.COM ap = &ialp->al_addrs[ialp->al_out_cnt];
23037836SJohn.Forte@Sun.COM if (icp->conn_base_addr.sin.sa_family
23047836SJohn.Forte@Sun.COM == AF_INET) {
23057836SJohn.Forte@Sun.COM
23067836SJohn.Forte@Sun.COM struct sockaddr_in *addr_in =
23077836SJohn.Forte@Sun.COM (struct sockaddr_in *)&icp->
23087836SJohn.Forte@Sun.COM conn_base_addr.sin4;
23097836SJohn.Forte@Sun.COM ap->a_addr.i_insize =
23107836SJohn.Forte@Sun.COM sizeof (struct in_addr);
23117836SJohn.Forte@Sun.COM bcopy(&addr_in->sin_addr.s_addr,
23127836SJohn.Forte@Sun.COM &ap->a_addr.i_addr.in4.s_addr,
23137836SJohn.Forte@Sun.COM sizeof (struct in_addr));
23147836SJohn.Forte@Sun.COM ap->a_port = addr_in->sin_port;
23157836SJohn.Forte@Sun.COM
23167836SJohn.Forte@Sun.COM } else {
23177836SJohn.Forte@Sun.COM
23187836SJohn.Forte@Sun.COM struct sockaddr_in6 *addr_in6 =
23197836SJohn.Forte@Sun.COM (struct sockaddr_in6 *)&icp->
23207836SJohn.Forte@Sun.COM conn_base_addr.sin6;
23217836SJohn.Forte@Sun.COM ap->a_addr.i_insize =
23227836SJohn.Forte@Sun.COM sizeof (struct in6_addr);
23237836SJohn.Forte@Sun.COM bcopy(&addr_in6->sin6_addr.s6_addr,
23247836SJohn.Forte@Sun.COM &ap->a_addr.i_addr.in6.s6_addr,
23257836SJohn.Forte@Sun.COM sizeof (struct in6_addr));
23267836SJohn.Forte@Sun.COM ap->a_port = addr_in6->sin6_port;
23277836SJohn.Forte@Sun.COM
23287836SJohn.Forte@Sun.COM }
23297836SJohn.Forte@Sun.COM }
23307836SJohn.Forte@Sun.COM ialp->al_out_cnt++;
23317836SJohn.Forte@Sun.COM }
23327836SJohn.Forte@Sun.COM rw_exit(&isp->sess_conn_list_rwlock);
23337836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
23347836SJohn.Forte@Sun.COM
23357836SJohn.Forte@Sun.COM rtn = ddi_copyout(ialp, (caddr_t)arg, list_space, mode);
23367836SJohn.Forte@Sun.COM kmem_free(ialp, list_space);
23377836SJohn.Forte@Sun.COM break;
23387836SJohn.Forte@Sun.COM
23397836SJohn.Forte@Sun.COM /*
23407836SJohn.Forte@Sun.COM * ISCSI_CHAP_SET -
23417836SJohn.Forte@Sun.COM */
23427836SJohn.Forte@Sun.COM case ISCSI_CHAP_SET:
23437836SJohn.Forte@Sun.COM chap = (iscsi_chap_props_t *)kmem_zalloc(sizeof (*chap),
23447836SJohn.Forte@Sun.COM KM_SLEEP);
23457836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, chap, sizeof (*chap), mode)) {
23467836SJohn.Forte@Sun.COM rtn = EFAULT;
23477836SJohn.Forte@Sun.COM kmem_free(chap, sizeof (*chap));
23487836SJohn.Forte@Sun.COM break;
23497836SJohn.Forte@Sun.COM } else if (chap->c_vers != ISCSI_INTERFACE_VERSION) {
23507836SJohn.Forte@Sun.COM rtn = EINVAL;
23517836SJohn.Forte@Sun.COM kmem_free(chap, sizeof (*chap));
23527836SJohn.Forte@Sun.COM break;
23537836SJohn.Forte@Sun.COM }
23547836SJohn.Forte@Sun.COM
23557836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
23567836SJohn.Forte@Sun.COM if (chap->c_oid == ihp->hba_oid)
23577836SJohn.Forte@Sun.COM name = ihp->hba_name;
23587836SJohn.Forte@Sun.COM else {
23597836SJohn.Forte@Sun.COM rtn = iscsi_sess_get(chap->c_oid, ihp, &isp);
23607836SJohn.Forte@Sun.COM if (rtn != 0) {
23617836SJohn.Forte@Sun.COM rtn = iscsi_sess_get_by_target(
23627836SJohn.Forte@Sun.COM chap->c_oid, ihp, &isp);
23637836SJohn.Forte@Sun.COM }
23647836SJohn.Forte@Sun.COM
23657836SJohn.Forte@Sun.COM /*
23667836SJohn.Forte@Sun.COM * If rtn is zero then we have found an
23677836SJohn.Forte@Sun.COM * existing session. Use the session name to
23687836SJohn.Forte@Sun.COM * do param lookup. If rtn is non-zero then
23697836SJohn.Forte@Sun.COM * create a targetparam object and use its name
23707836SJohn.Forte@Sun.COM * for param lookup.
23717836SJohn.Forte@Sun.COM */
23727836SJohn.Forte@Sun.COM if (rtn == 0) {
23737836SJohn.Forte@Sun.COM name = isp->sess_name;
23747836SJohn.Forte@Sun.COM } else {
23757836SJohn.Forte@Sun.COM name =
23767836SJohn.Forte@Sun.COM iscsi_targetparam_get_name(chap->c_oid);
23777836SJohn.Forte@Sun.COM rtn = 0;
23787836SJohn.Forte@Sun.COM }
23797836SJohn.Forte@Sun.COM }
23807836SJohn.Forte@Sun.COM
23817836SJohn.Forte@Sun.COM if (name == NULL) {
23827836SJohn.Forte@Sun.COM rw_exit(
23837836SJohn.Forte@Sun.COM &ihp->hba_sess_list_rwlock);
23847836SJohn.Forte@Sun.COM rtn = EFAULT;
23857836SJohn.Forte@Sun.COM kmem_free(chap, sizeof (*chap));
23867836SJohn.Forte@Sun.COM break;
23877836SJohn.Forte@Sun.COM }
23887836SJohn.Forte@Sun.COM
23897836SJohn.Forte@Sun.COM if (persistent_chap_set((char *)name, chap) ==
23907836SJohn.Forte@Sun.COM B_FALSE) {
23917836SJohn.Forte@Sun.COM rtn = EIO;
23927836SJohn.Forte@Sun.COM }
23937836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
23947836SJohn.Forte@Sun.COM kmem_free(chap, sizeof (*chap));
23957836SJohn.Forte@Sun.COM break;
23967836SJohn.Forte@Sun.COM
23977836SJohn.Forte@Sun.COM /*
23987836SJohn.Forte@Sun.COM * ISCSI_CHAP_GET -
23997836SJohn.Forte@Sun.COM */
24007836SJohn.Forte@Sun.COM case ISCSI_CHAP_GET:
24017836SJohn.Forte@Sun.COM chap = (iscsi_chap_props_t *)kmem_zalloc(sizeof (*chap),
24027836SJohn.Forte@Sun.COM KM_SLEEP);
24037836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, chap, sizeof (*chap), mode)) {
24047836SJohn.Forte@Sun.COM kmem_free(chap, sizeof (*chap));
24057836SJohn.Forte@Sun.COM rtn = EFAULT;
24067836SJohn.Forte@Sun.COM break;
24077836SJohn.Forte@Sun.COM } else if (chap->c_vers != ISCSI_INTERFACE_VERSION) {
24087836SJohn.Forte@Sun.COM kmem_free(chap, sizeof (*chap));
24097836SJohn.Forte@Sun.COM rtn = EINVAL;
24107836SJohn.Forte@Sun.COM break;
24117836SJohn.Forte@Sun.COM }
24127836SJohn.Forte@Sun.COM
24137836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
24147836SJohn.Forte@Sun.COM if (chap->c_oid == ihp->hba_oid)
24157836SJohn.Forte@Sun.COM name = ihp->hba_name;
24167836SJohn.Forte@Sun.COM else {
24177836SJohn.Forte@Sun.COM rtn = iscsi_sess_get(chap->c_oid, ihp, &isp);
24187836SJohn.Forte@Sun.COM if (rtn != 0) {
24197836SJohn.Forte@Sun.COM rtn = iscsi_sess_get_by_target(
24207836SJohn.Forte@Sun.COM chap->c_oid, ihp, &isp);
24217836SJohn.Forte@Sun.COM }
24227836SJohn.Forte@Sun.COM
24237836SJohn.Forte@Sun.COM /*
24247836SJohn.Forte@Sun.COM * If rtn is zero then we have found an
24257836SJohn.Forte@Sun.COM * existing session. Use the session name to
24267836SJohn.Forte@Sun.COM * do param lookup. If rtn is non-zero then
24277836SJohn.Forte@Sun.COM * create a targetparam object and use its name
24287836SJohn.Forte@Sun.COM * for param lookup.
24297836SJohn.Forte@Sun.COM */
24307836SJohn.Forte@Sun.COM if (rtn == 0) {
24317836SJohn.Forte@Sun.COM name = isp->sess_name;
24327836SJohn.Forte@Sun.COM } else {
24337836SJohn.Forte@Sun.COM rtn = 0;
24347836SJohn.Forte@Sun.COM name =
24357836SJohn.Forte@Sun.COM iscsi_targetparam_get_name(chap->c_oid);
24367836SJohn.Forte@Sun.COM }
24377836SJohn.Forte@Sun.COM
24388389SJack.Meng@Sun.COM if (name == NULL) {
24398389SJack.Meng@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
24408389SJack.Meng@Sun.COM rtn = EFAULT;
24418389SJack.Meng@Sun.COM break;
24428389SJack.Meng@Sun.COM }
24437836SJohn.Forte@Sun.COM /*
24447836SJohn.Forte@Sun.COM * Initialize the target-side chap name to the
24457836SJohn.Forte@Sun.COM * session name if no chap settings have been
24467836SJohn.Forte@Sun.COM * saved for the current session.
24477836SJohn.Forte@Sun.COM */
24487836SJohn.Forte@Sun.COM if (persistent_chap_get((char *)name,
24497836SJohn.Forte@Sun.COM chap) == B_FALSE) {
24507836SJohn.Forte@Sun.COM int name_len = strlen((char *)name);
24517836SJohn.Forte@Sun.COM iscsi_chap_props_t *chap = NULL;
24527836SJohn.Forte@Sun.COM chap = (iscsi_chap_props_t *)kmem_zalloc
24537836SJohn.Forte@Sun.COM (sizeof (iscsi_chap_props_t), KM_SLEEP);
24547836SJohn.Forte@Sun.COM bcopy((char *)name, chap->c_user, name_len);
24557836SJohn.Forte@Sun.COM chap->c_user_len = name_len;
24567836SJohn.Forte@Sun.COM (void) (persistent_chap_set((char *)name,
24577836SJohn.Forte@Sun.COM chap));
24587836SJohn.Forte@Sun.COM kmem_free(chap, sizeof (*chap));
24597836SJohn.Forte@Sun.COM }
24607836SJohn.Forte@Sun.COM }
24617836SJohn.Forte@Sun.COM
24627836SJohn.Forte@Sun.COM if (name == NULL) {
24637836SJohn.Forte@Sun.COM rw_exit(
24647836SJohn.Forte@Sun.COM &ihp->hba_sess_list_rwlock);
24657836SJohn.Forte@Sun.COM rtn = EFAULT;
24667836SJohn.Forte@Sun.COM break;
24677836SJohn.Forte@Sun.COM }
24687836SJohn.Forte@Sun.COM
24697836SJohn.Forte@Sun.COM if (persistent_chap_get((char *)name, chap) == B_FALSE) {
24707836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
24717836SJohn.Forte@Sun.COM rtn = EIO;
24727836SJohn.Forte@Sun.COM break;
24737836SJohn.Forte@Sun.COM }
24747836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
24757836SJohn.Forte@Sun.COM
24767836SJohn.Forte@Sun.COM rtn = ddi_copyout(chap, (caddr_t)arg, sizeof (*chap), mode);
24777836SJohn.Forte@Sun.COM kmem_free(chap, sizeof (*chap));
24787836SJohn.Forte@Sun.COM break;
24797836SJohn.Forte@Sun.COM
24807836SJohn.Forte@Sun.COM /*
24817836SJohn.Forte@Sun.COM * ISCSI_CHAP_CLEAR -
24827836SJohn.Forte@Sun.COM */
24837836SJohn.Forte@Sun.COM case ISCSI_CHAP_CLEAR:
24847836SJohn.Forte@Sun.COM chap = (iscsi_chap_props_t *)kmem_zalloc(sizeof (*chap),
24857836SJohn.Forte@Sun.COM KM_SLEEP);
24867836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, chap, sizeof (*chap), mode)) {
24877836SJohn.Forte@Sun.COM rtn = EFAULT;
24887836SJohn.Forte@Sun.COM kmem_free(chap, sizeof (*chap));
24897836SJohn.Forte@Sun.COM break;
24907836SJohn.Forte@Sun.COM } else if (chap->c_vers != ISCSI_INTERFACE_VERSION) {
24917836SJohn.Forte@Sun.COM rtn = EINVAL;
24927836SJohn.Forte@Sun.COM kmem_free(chap, sizeof (*chap));
24937836SJohn.Forte@Sun.COM break;
24947836SJohn.Forte@Sun.COM }
24957836SJohn.Forte@Sun.COM
24967836SJohn.Forte@Sun.COM if (chap->c_oid == ihp->hba_oid) {
24977836SJohn.Forte@Sun.COM iscsi_sess_t *sessp;
24987836SJohn.Forte@Sun.COM
24997836SJohn.Forte@Sun.COM name = ihp->hba_name;
25007836SJohn.Forte@Sun.COM
25017836SJohn.Forte@Sun.COM if (persistent_chap_clear(
25027836SJohn.Forte@Sun.COM (char *)name) == B_FALSE) {
25037836SJohn.Forte@Sun.COM rtn = EIO;
25047836SJohn.Forte@Sun.COM }
25057836SJohn.Forte@Sun.COM
25067836SJohn.Forte@Sun.COM /*
25077836SJohn.Forte@Sun.COM * Loop through all sessions and memset their
25087836SJohn.Forte@Sun.COM * (initiator's) passwords
25097836SJohn.Forte@Sun.COM */
25107836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
25117836SJohn.Forte@Sun.COM for (sessp = ihp->hba_sess_list; sessp;
25127836SJohn.Forte@Sun.COM sessp = sessp->sess_next) {
25137836SJohn.Forte@Sun.COM (void) memset(sessp->sess_auth.password,
25147836SJohn.Forte@Sun.COM 0, iscsiAuthStringMaxLength);
25157836SJohn.Forte@Sun.COM sessp->sess_auth.password_length = 0;
25167836SJohn.Forte@Sun.COM }
25177836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
25187836SJohn.Forte@Sun.COM
25197836SJohn.Forte@Sun.COM } else {
25207836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
25217836SJohn.Forte@Sun.COM /*
25227836SJohn.Forte@Sun.COM * If the oid does represent a session check to see
25237836SJohn.Forte@Sun.COM * if it is a target oid. If so, return the target's
25247836SJohn.Forte@Sun.COM * associated session.
25257836SJohn.Forte@Sun.COM */
25267836SJohn.Forte@Sun.COM rtn = iscsi_sess_get(chap->c_oid, ihp, &isp);
25277836SJohn.Forte@Sun.COM if (rtn != 0) {
25287836SJohn.Forte@Sun.COM rtn = iscsi_sess_get_by_target(chap->c_oid,
25297836SJohn.Forte@Sun.COM ihp, &isp);
25307836SJohn.Forte@Sun.COM }
25317836SJohn.Forte@Sun.COM
25327836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
25337836SJohn.Forte@Sun.COM
25347836SJohn.Forte@Sun.COM /*
25357836SJohn.Forte@Sun.COM * If rtn is zero then we have found an
25367836SJohn.Forte@Sun.COM * existing session. Use the session name to
25377836SJohn.Forte@Sun.COM * do param lookup. If rtn is non-zero then
25387836SJohn.Forte@Sun.COM * create a targetparam object and use its name
25397836SJohn.Forte@Sun.COM * for param lookup.
25407836SJohn.Forte@Sun.COM */
25417836SJohn.Forte@Sun.COM if (rtn == 0) {
25427836SJohn.Forte@Sun.COM name = isp->sess_name;
25437836SJohn.Forte@Sun.COM } else {
25447836SJohn.Forte@Sun.COM name =
25457836SJohn.Forte@Sun.COM iscsi_targetparam_get_name(chap->c_oid);
25467836SJohn.Forte@Sun.COM rtn = 0;
25477836SJohn.Forte@Sun.COM }
25487836SJohn.Forte@Sun.COM
25497836SJohn.Forte@Sun.COM if (name == NULL) {
25507836SJohn.Forte@Sun.COM rtn = EFAULT;
25517836SJohn.Forte@Sun.COM break;
25527836SJohn.Forte@Sun.COM }
25537836SJohn.Forte@Sun.COM
25547836SJohn.Forte@Sun.COM if (persistent_chap_clear(
25557836SJohn.Forte@Sun.COM (char *)name) == B_FALSE) {
25567836SJohn.Forte@Sun.COM rtn = EIO;
25577836SJohn.Forte@Sun.COM }
25587836SJohn.Forte@Sun.COM
25597836SJohn.Forte@Sun.COM /*
25607836SJohn.Forte@Sun.COM * Clear out session chap password if we found a
25617836SJohn.Forte@Sun.COM * session above.
25627836SJohn.Forte@Sun.COM */
25637836SJohn.Forte@Sun.COM if (isp != NULL) {
25647836SJohn.Forte@Sun.COM (void) memset(isp->sess_auth.password_in,
25657836SJohn.Forte@Sun.COM 0, iscsiAuthStringMaxLength);
25667836SJohn.Forte@Sun.COM isp->sess_auth.password_length_in = 0;
25677836SJohn.Forte@Sun.COM }
25687836SJohn.Forte@Sun.COM
25697836SJohn.Forte@Sun.COM }
25707836SJohn.Forte@Sun.COM
25717836SJohn.Forte@Sun.COM kmem_free(chap, sizeof (*chap));
25727836SJohn.Forte@Sun.COM break;
25737836SJohn.Forte@Sun.COM
25747836SJohn.Forte@Sun.COM /*
25757836SJohn.Forte@Sun.COM * ISCSI_STATIC_GET -
25767836SJohn.Forte@Sun.COM */
25777836SJohn.Forte@Sun.COM case ISCSI_STATIC_GET:
25787836SJohn.Forte@Sun.COM ispp = (iscsi_static_property_t *)kmem_alloc(
25797836SJohn.Forte@Sun.COM sizeof (*ispp), KM_SLEEP);
25807836SJohn.Forte@Sun.COM
25817836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, ispp, sizeof (*ispp), mode)) {
25827836SJohn.Forte@Sun.COM rtn = EFAULT;
25837836SJohn.Forte@Sun.COM kmem_free(ispp, sizeof (*ispp));
25847836SJohn.Forte@Sun.COM break;
25857836SJohn.Forte@Sun.COM }
25867836SJohn.Forte@Sun.COM
25877836SJohn.Forte@Sun.COM if (ispp->p_vers != ISCSI_INTERFACE_VERSION) {
25887836SJohn.Forte@Sun.COM rtn = EINVAL;
25897836SJohn.Forte@Sun.COM kmem_free(ispp, sizeof (*ispp));
25907836SJohn.Forte@Sun.COM break;
25917836SJohn.Forte@Sun.COM }
25927836SJohn.Forte@Sun.COM
25937836SJohn.Forte@Sun.COM {
25947836SJohn.Forte@Sun.COM void *v = NULL;
25957836SJohn.Forte@Sun.COM boolean_t found = B_FALSE;
25967836SJohn.Forte@Sun.COM
25977836SJohn.Forte@Sun.COM persistent_static_addr_lock();
25987836SJohn.Forte@Sun.COM while (persistent_static_addr_next(&v,
25997836SJohn.Forte@Sun.COM (char *)ispp->p_name, &e) == B_TRUE) {
26007836SJohn.Forte@Sun.COM
26017836SJohn.Forte@Sun.COM if (ispp->p_oid == e.e_oid) {
26027836SJohn.Forte@Sun.COM /*
26037836SJohn.Forte@Sun.COM * In case there are multiple
26047836SJohn.Forte@Sun.COM * addresses associated with the
26057836SJohn.Forte@Sun.COM * given target OID, pick the first
26067836SJohn.Forte@Sun.COM * one.
26077836SJohn.Forte@Sun.COM */
26087836SJohn.Forte@Sun.COM iscsi_addr_t *ap;
26097836SJohn.Forte@Sun.COM
26107836SJohn.Forte@Sun.COM ap = &(ispp->p_addr_list.al_addrs[0]);
26117836SJohn.Forte@Sun.COM ap->a_port = e.e_port;
26127836SJohn.Forte@Sun.COM ap->a_addr.i_insize = e.e_insize;
26137836SJohn.Forte@Sun.COM bcopy(e.e_u.u_in6.s6_addr,
26147836SJohn.Forte@Sun.COM ap->a_addr.i_addr.in6.s6_addr,
26157836SJohn.Forte@Sun.COM e.e_insize);
26167836SJohn.Forte@Sun.COM ispp->p_name_len =
26177836SJohn.Forte@Sun.COM strlen((char *)ispp->p_name);
26187836SJohn.Forte@Sun.COM ispp->p_addr_list.al_tpgt = e.e_tpgt;
26197836SJohn.Forte@Sun.COM ispp->p_addr_list.al_out_cnt = 1;
26207836SJohn.Forte@Sun.COM
26217836SJohn.Forte@Sun.COM found = B_TRUE;
26227836SJohn.Forte@Sun.COM break;
26237836SJohn.Forte@Sun.COM }
26247836SJohn.Forte@Sun.COM }
26257836SJohn.Forte@Sun.COM persistent_static_addr_unlock();
26267836SJohn.Forte@Sun.COM
26277836SJohn.Forte@Sun.COM if (found == B_TRUE) {
26287836SJohn.Forte@Sun.COM rtn = ddi_copyout(ispp, (caddr_t)arg,
26297836SJohn.Forte@Sun.COM sizeof (*ispp), mode);
26307836SJohn.Forte@Sun.COM } else {
26317836SJohn.Forte@Sun.COM rtn = ENOENT;
26327836SJohn.Forte@Sun.COM }
26337836SJohn.Forte@Sun.COM }
26347836SJohn.Forte@Sun.COM kmem_free(ispp, sizeof (*ispp));
26357836SJohn.Forte@Sun.COM
26367836SJohn.Forte@Sun.COM break;
26377836SJohn.Forte@Sun.COM
26387836SJohn.Forte@Sun.COM /*
26397836SJohn.Forte@Sun.COM * ISCSI_STATIC_SET -
26407836SJohn.Forte@Sun.COM */
26417836SJohn.Forte@Sun.COM case ISCSI_STATIC_SET:
26427836SJohn.Forte@Sun.COM target = iscsi_ioctl_copyin((caddr_t)arg, mode,
26437836SJohn.Forte@Sun.COM sizeof (*target));
26447836SJohn.Forte@Sun.COM if (target == NULL) {
26457836SJohn.Forte@Sun.COM rtn = EFAULT;
26467836SJohn.Forte@Sun.COM break;
26477836SJohn.Forte@Sun.COM }
26487836SJohn.Forte@Sun.COM
264910774SZhang.Yi@Sun.COM if ((target->te_entry.e_vers != ISCSI_INTERFACE_VERSION) ||
265010774SZhang.Yi@Sun.COM (target->te_entry.e_insize == 0)) {
26517836SJohn.Forte@Sun.COM kmem_free(target, sizeof (*target));
26527836SJohn.Forte@Sun.COM rtn = EINVAL;
26537836SJohn.Forte@Sun.COM break;
26547836SJohn.Forte@Sun.COM }
26557836SJohn.Forte@Sun.COM
26567836SJohn.Forte@Sun.COM /* Check if the target's already been added */
26577836SJohn.Forte@Sun.COM {
26587836SJohn.Forte@Sun.COM boolean_t static_target_found = B_FALSE;
26597836SJohn.Forte@Sun.COM void *v = NULL;
26607836SJohn.Forte@Sun.COM
26617836SJohn.Forte@Sun.COM name = kmem_zalloc(ISCSI_MAX_NAME_LEN, KM_SLEEP);
26627836SJohn.Forte@Sun.COM persistent_static_addr_lock();
26637836SJohn.Forte@Sun.COM while (persistent_static_addr_next(&v, (char *)name,
26647836SJohn.Forte@Sun.COM &e) == B_TRUE) {
26657836SJohn.Forte@Sun.COM /*
26667836SJohn.Forte@Sun.COM * MC/S - Need to check IP address and port
26677836SJohn.Forte@Sun.COM * number as well when we support MC/S.
26687836SJohn.Forte@Sun.COM */
26697836SJohn.Forte@Sun.COM if ((strncmp((char *)name,
26707836SJohn.Forte@Sun.COM (char *)target->te_name,
26717836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN) == 0) &&
26727836SJohn.Forte@Sun.COM (target->te_entry.e_tpgt == e.e_tpgt) &&
26737836SJohn.Forte@Sun.COM (target->te_entry.e_insize == e.e_insize) &&
26747836SJohn.Forte@Sun.COM (bcmp(&target->te_entry.e_u, &e.e_u,
26757836SJohn.Forte@Sun.COM e.e_insize) == 0)) {
26767836SJohn.Forte@Sun.COM /*
26777836SJohn.Forte@Sun.COM * We don't allow MC/S for now but
26787836SJohn.Forte@Sun.COM * we do allow adding the same target
26797836SJohn.Forte@Sun.COM * with different TPGTs (hence,
26807836SJohn.Forte@Sun.COM * different sessions).
26817836SJohn.Forte@Sun.COM */
26827836SJohn.Forte@Sun.COM static_target_found = B_TRUE;
26837836SJohn.Forte@Sun.COM break;
26847836SJohn.Forte@Sun.COM }
26857836SJohn.Forte@Sun.COM }
26867836SJohn.Forte@Sun.COM persistent_static_addr_unlock();
26877836SJohn.Forte@Sun.COM kmem_free(name, ISCSI_MAX_NAME_LEN);
26887836SJohn.Forte@Sun.COM
26897836SJohn.Forte@Sun.COM if (static_target_found == B_TRUE) {
26907836SJohn.Forte@Sun.COM /* Duplicate entry */
26917836SJohn.Forte@Sun.COM kmem_free(target, sizeof (*target));
26927836SJohn.Forte@Sun.COM rtn = EEXIST;
26937836SJohn.Forte@Sun.COM break;
26947836SJohn.Forte@Sun.COM }
26957836SJohn.Forte@Sun.COM }
26967836SJohn.Forte@Sun.COM
26977836SJohn.Forte@Sun.COM if (target->te_entry.e_oid == ISCSI_OID_NOTSET) {
26987836SJohn.Forte@Sun.COM mutex_enter(&iscsi_oid_mutex);
26997836SJohn.Forte@Sun.COM target->te_entry.e_oid = iscsi_oid++;
27007836SJohn.Forte@Sun.COM mutex_exit(&iscsi_oid_mutex);
27017836SJohn.Forte@Sun.COM }
27027836SJohn.Forte@Sun.COM
27037836SJohn.Forte@Sun.COM persistent_static_addr_lock();
27047836SJohn.Forte@Sun.COM if (persistent_static_addr_set((char *)target->te_name,
27057836SJohn.Forte@Sun.COM &target->te_entry) == B_FALSE) {
27067836SJohn.Forte@Sun.COM persistent_static_addr_unlock();
27077836SJohn.Forte@Sun.COM kmem_free(target, sizeof (*target));
27087836SJohn.Forte@Sun.COM rtn = EIO;
27097836SJohn.Forte@Sun.COM break;
27107836SJohn.Forte@Sun.COM }
27117836SJohn.Forte@Sun.COM persistent_static_addr_unlock();
27127836SJohn.Forte@Sun.COM
27137836SJohn.Forte@Sun.COM /*
27147836SJohn.Forte@Sun.COM * If Static Targets discovery is enabled, then add
27157836SJohn.Forte@Sun.COM * target to discovery queue. Otherwise, just create
27167836SJohn.Forte@Sun.COM * the session for potential future use.
27177836SJohn.Forte@Sun.COM */
27187836SJohn.Forte@Sun.COM method = persistent_disc_meth_get();
27197836SJohn.Forte@Sun.COM if (method & iSCSIDiscoveryMethodStatic) {
27207836SJohn.Forte@Sun.COM iscsid_poke_discovery(ihp, iSCSIDiscoveryMethodStatic);
27217836SJohn.Forte@Sun.COM (void) iscsid_login_tgt(ihp, (char *)target->te_name,
27227836SJohn.Forte@Sun.COM iSCSIDiscoveryMethodStatic, NULL);
27237836SJohn.Forte@Sun.COM }
27247836SJohn.Forte@Sun.COM
27257836SJohn.Forte@Sun.COM rtn = iscsi_ioctl_copyout(target, sizeof (*target),
27267836SJohn.Forte@Sun.COM (caddr_t)arg, mode);
27277836SJohn.Forte@Sun.COM break;
27287836SJohn.Forte@Sun.COM
27297836SJohn.Forte@Sun.COM /*
27307836SJohn.Forte@Sun.COM * ISCSI_STATIC_CLEAR -
27317836SJohn.Forte@Sun.COM */
27327836SJohn.Forte@Sun.COM case ISCSI_STATIC_CLEAR:
27337836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &e, sizeof (e), mode)) {
27347836SJohn.Forte@Sun.COM rtn = EFAULT;
27357836SJohn.Forte@Sun.COM break;
273610864SZhang.Yi@Sun.COM } else if (e.e_vers != ISCSI_INTERFACE_VERSION) {
27377836SJohn.Forte@Sun.COM rtn = EINVAL;
27387836SJohn.Forte@Sun.COM break;
27397836SJohn.Forte@Sun.COM }
27407836SJohn.Forte@Sun.COM
27417836SJohn.Forte@Sun.COM {
27427836SJohn.Forte@Sun.COM boolean_t found = B_FALSE;
27437836SJohn.Forte@Sun.COM void *v = NULL;
27447836SJohn.Forte@Sun.COM entry_t tmp_e;
27457836SJohn.Forte@Sun.COM char *name = NULL;
27467836SJohn.Forte@Sun.COM
27477836SJohn.Forte@Sun.COM name = kmem_zalloc(ISCSI_MAX_NAME_LEN, KM_SLEEP);
27487836SJohn.Forte@Sun.COM
27497836SJohn.Forte@Sun.COM /* Find name for matching static_tgt oid */
27507836SJohn.Forte@Sun.COM persistent_static_addr_lock();
27517836SJohn.Forte@Sun.COM while (persistent_static_addr_next(&v,
27527836SJohn.Forte@Sun.COM (char *)name, &tmp_e) == B_TRUE) {
27537836SJohn.Forte@Sun.COM if (e.e_oid == tmp_e.e_oid) {
27547836SJohn.Forte@Sun.COM found = B_TRUE;
27557836SJohn.Forte@Sun.COM break;
27567836SJohn.Forte@Sun.COM }
27577836SJohn.Forte@Sun.COM }
27587836SJohn.Forte@Sun.COM
27597836SJohn.Forte@Sun.COM /* If static_tgt found logout and remove it */
27607836SJohn.Forte@Sun.COM if (found == B_TRUE) {
27617836SJohn.Forte@Sun.COM
27627836SJohn.Forte@Sun.COM iscsid_addr_to_sockaddr(tmp_e.e_insize,
27637836SJohn.Forte@Sun.COM &tmp_e.e_u, tmp_e.e_port, &addr_dsc.sin);
27647836SJohn.Forte@Sun.COM
276510156SZhang.Yi@Sun.COM persistent_static_addr_unlock();
276610156SZhang.Yi@Sun.COM
276710156SZhang.Yi@Sun.COM /*
276810156SZhang.Yi@Sun.COM * If discovery in progress, try few times
276910156SZhang.Yi@Sun.COM * before return busy
277010156SZhang.Yi@Sun.COM */
277110156SZhang.Yi@Sun.COM retry = 0;
277210156SZhang.Yi@Sun.COM mutex_enter(&ihp->hba_discovery_events_mutex);
277310156SZhang.Yi@Sun.COM while (ihp->hba_discovery_in_progress ==
277410156SZhang.Yi@Sun.COM B_TRUE) {
277510156SZhang.Yi@Sun.COM if (++retry == 5) {
277610156SZhang.Yi@Sun.COM rtn = EBUSY;
277710156SZhang.Yi@Sun.COM break;
277810156SZhang.Yi@Sun.COM }
277910156SZhang.Yi@Sun.COM mutex_exit(
278010156SZhang.Yi@Sun.COM &ihp->hba_discovery_events_mutex);
278110156SZhang.Yi@Sun.COM delay(SEC_TO_TICK(
278210156SZhang.Yi@Sun.COM ISCSI_DISC_DELAY));
278310156SZhang.Yi@Sun.COM mutex_enter(
278410156SZhang.Yi@Sun.COM &ihp->hba_discovery_events_mutex);
278510156SZhang.Yi@Sun.COM }
278610156SZhang.Yi@Sun.COM /* remove from persistent store */
278710156SZhang.Yi@Sun.COM if (rtn == 0 && persistent_static_addr_clear(
278810156SZhang.Yi@Sun.COM e.e_oid) == B_FALSE) {
278910156SZhang.Yi@Sun.COM rtn = EIO;
279010156SZhang.Yi@Sun.COM }
279110156SZhang.Yi@Sun.COM mutex_exit(&ihp->hba_discovery_events_mutex);
279210156SZhang.Yi@Sun.COM
279310156SZhang.Yi@Sun.COM if (rtn != 0) {
279410156SZhang.Yi@Sun.COM kmem_free(name, ISCSI_MAX_NAME_LEN);
279510156SZhang.Yi@Sun.COM break;
279610156SZhang.Yi@Sun.COM }
279710156SZhang.Yi@Sun.COM
27987836SJohn.Forte@Sun.COM /* Attempt to logout of target */
27997836SJohn.Forte@Sun.COM if (iscsid_del(ihp, (char *)name,
28007836SJohn.Forte@Sun.COM iSCSIDiscoveryMethodStatic, &addr_dsc.sin)
280110156SZhang.Yi@Sun.COM == B_FALSE) {
280210156SZhang.Yi@Sun.COM persistent_static_addr_lock();
280310156SZhang.Yi@Sun.COM
280410156SZhang.Yi@Sun.COM /*
280510156SZhang.Yi@Sun.COM * Restore static_tgt to
280610156SZhang.Yi@Sun.COM * persistent store
280710156SZhang.Yi@Sun.COM */
280810156SZhang.Yi@Sun.COM if (persistent_static_addr_set(
280910156SZhang.Yi@Sun.COM (char *)name,
2810*12790SZhang.Yi@Sun.COM &tmp_e) == B_FALSE) {
281110156SZhang.Yi@Sun.COM cmn_err(CE_WARN, "Failed to "
281210156SZhang.Yi@Sun.COM "restore static target "
281310156SZhang.Yi@Sun.COM "address after logout "
281410156SZhang.Yi@Sun.COM "target failure.");
281510156SZhang.Yi@Sun.COM }
28167836SJohn.Forte@Sun.COM persistent_static_addr_unlock();
281710156SZhang.Yi@Sun.COM rtn = EBUSY;
281810156SZhang.Yi@Sun.COM } else {
28197836SJohn.Forte@Sun.COM iscsid_poke_discovery(ihp,
28207836SJohn.Forte@Sun.COM iSCSIDiscoveryMethodStatic);
28217836SJohn.Forte@Sun.COM (void) iscsid_login_tgt(ihp,
28227836SJohn.Forte@Sun.COM (char *)name,
28237836SJohn.Forte@Sun.COM iSCSIDiscoveryMethodStatic,
28247836SJohn.Forte@Sun.COM NULL);
28257836SJohn.Forte@Sun.COM
28267836SJohn.Forte@Sun.COM }
28277836SJohn.Forte@Sun.COM } else {
28287836SJohn.Forte@Sun.COM persistent_static_addr_unlock();
28297836SJohn.Forte@Sun.COM rtn = EIO;
28307836SJohn.Forte@Sun.COM }
28317836SJohn.Forte@Sun.COM kmem_free(name, ISCSI_MAX_NAME_LEN);
28327836SJohn.Forte@Sun.COM }
28337836SJohn.Forte@Sun.COM break;
28347836SJohn.Forte@Sun.COM
28357836SJohn.Forte@Sun.COM /*
28367836SJohn.Forte@Sun.COM * ISCSI_ISNS_SERVER_ADDR_SET:
28377836SJohn.Forte@Sun.COM */
28387836SJohn.Forte@Sun.COM case ISCSI_ISNS_SERVER_ADDR_SET:
28397836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &e, sizeof (e), mode)) {
28407836SJohn.Forte@Sun.COM rtn = EFAULT;
28417836SJohn.Forte@Sun.COM break;
28427836SJohn.Forte@Sun.COM } else if (e.e_vers != ISCSI_INTERFACE_VERSION) {
28437836SJohn.Forte@Sun.COM rtn = EINVAL;
28447836SJohn.Forte@Sun.COM break;
28457836SJohn.Forte@Sun.COM }
28467836SJohn.Forte@Sun.COM
28477836SJohn.Forte@Sun.COM if (persistent_isns_addr_set(&e) == B_FALSE) {
28487836SJohn.Forte@Sun.COM rtn = EIO;
28497836SJohn.Forte@Sun.COM break;
28507836SJohn.Forte@Sun.COM }
28517836SJohn.Forte@Sun.COM
28527836SJohn.Forte@Sun.COM /*
28537836SJohn.Forte@Sun.COM * If iSNS server discovery is enabled, then kickoff
28547836SJohn.Forte@Sun.COM * discovery of the targets advertised by the recently
28557836SJohn.Forte@Sun.COM * added iSNS server address.
28567836SJohn.Forte@Sun.COM */
28577836SJohn.Forte@Sun.COM method = persistent_disc_meth_get();
28587836SJohn.Forte@Sun.COM if (method & iSCSIDiscoveryMethodISNS) {
28597836SJohn.Forte@Sun.COM initiator_node_name = kmem_zalloc(ISCSI_MAX_NAME_LEN,
28607836SJohn.Forte@Sun.COM KM_SLEEP);
28617836SJohn.Forte@Sun.COM if (persistent_initiator_name_get(initiator_node_name,
28627836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN) != B_TRUE) {
28637836SJohn.Forte@Sun.COM kmem_free(initiator_node_name,
28647836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN);
28657836SJohn.Forte@Sun.COM initiator_node_name = NULL;
28667836SJohn.Forte@Sun.COM rtn = EIO;
28677836SJohn.Forte@Sun.COM break;
28687836SJohn.Forte@Sun.COM }
28697836SJohn.Forte@Sun.COM if (strlen(initiator_node_name) == 0) {
28707836SJohn.Forte@Sun.COM kmem_free(initiator_node_name,
28717836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN);
28727836SJohn.Forte@Sun.COM initiator_node_name = NULL;
28737836SJohn.Forte@Sun.COM rtn = EIO;
28747836SJohn.Forte@Sun.COM break;
28757836SJohn.Forte@Sun.COM }
28767836SJohn.Forte@Sun.COM
28777836SJohn.Forte@Sun.COM initiator_node_alias = kmem_zalloc(ISCSI_MAX_NAME_LEN,
28787836SJohn.Forte@Sun.COM KM_SLEEP);
28797836SJohn.Forte@Sun.COM if (persistent_alias_name_get(initiator_node_alias,
28807836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN) != B_TRUE) {
28817836SJohn.Forte@Sun.COM initiator_node_alias[0] = '\0';
28827836SJohn.Forte@Sun.COM }
28837836SJohn.Forte@Sun.COM
28847836SJohn.Forte@Sun.COM /*
28857836SJohn.Forte@Sun.COM * Register this initiator node against this iSNS
28867836SJohn.Forte@Sun.COM * server.
28877836SJohn.Forte@Sun.COM */
28887836SJohn.Forte@Sun.COM (void) isns_reg_one_server(&e, ihp->hba_isid,
28897836SJohn.Forte@Sun.COM (uint8_t *)initiator_node_name,
28907836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN,
28917836SJohn.Forte@Sun.COM (uint8_t *)initiator_node_alias,
28927836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN,
28937836SJohn.Forte@Sun.COM ISNS_INITIATOR_NODE_TYPE,
28947836SJohn.Forte@Sun.COM isns_scn_callback);
28957836SJohn.Forte@Sun.COM
28967836SJohn.Forte@Sun.COM iscsid_do_isns_query_one_server(ihp, &e);
28977836SJohn.Forte@Sun.COM
28987836SJohn.Forte@Sun.COM iscsid_addr_to_sockaddr(e.e_insize,
28997836SJohn.Forte@Sun.COM &e.e_u, e.e_port, &addr_dsc.sin);
29007836SJohn.Forte@Sun.COM
29017836SJohn.Forte@Sun.COM (void) iscsid_login_tgt(ihp, NULL,
29027836SJohn.Forte@Sun.COM iSCSIDiscoveryMethodISNS,
29037836SJohn.Forte@Sun.COM &addr_dsc.sin);
29047836SJohn.Forte@Sun.COM
29057836SJohn.Forte@Sun.COM /* Done using the name and alias - free them. */
29067836SJohn.Forte@Sun.COM kmem_free(initiator_node_name, ISCSI_MAX_NAME_LEN);
29077836SJohn.Forte@Sun.COM initiator_node_name = NULL;
29087836SJohn.Forte@Sun.COM kmem_free(initiator_node_alias, ISCSI_MAX_NAME_LEN);
29097836SJohn.Forte@Sun.COM initiator_node_alias = NULL;
29107836SJohn.Forte@Sun.COM }
29117836SJohn.Forte@Sun.COM break;
29127836SJohn.Forte@Sun.COM
29137836SJohn.Forte@Sun.COM /*
29147836SJohn.Forte@Sun.COM * ISCSI_DISCOVERY_ADDR_SET:
29157836SJohn.Forte@Sun.COM */
29167836SJohn.Forte@Sun.COM case ISCSI_DISCOVERY_ADDR_SET:
29177836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &e, sizeof (e), mode)) {
29187836SJohn.Forte@Sun.COM rtn = EFAULT;
29197836SJohn.Forte@Sun.COM break;
29207836SJohn.Forte@Sun.COM } else if (e.e_vers != ISCSI_INTERFACE_VERSION) {
29217836SJohn.Forte@Sun.COM rtn = EINVAL;
29227836SJohn.Forte@Sun.COM break;
29237836SJohn.Forte@Sun.COM }
29247836SJohn.Forte@Sun.COM
29257836SJohn.Forte@Sun.COM if (e.e_oid == ISCSI_OID_NOTSET) {
29267836SJohn.Forte@Sun.COM mutex_enter(&iscsi_oid_mutex);
29277836SJohn.Forte@Sun.COM e.e_oid = iscsi_oid++;
29287836SJohn.Forte@Sun.COM mutex_exit(&iscsi_oid_mutex);
29297836SJohn.Forte@Sun.COM }
29307836SJohn.Forte@Sun.COM
29317836SJohn.Forte@Sun.COM if (persistent_disc_addr_set(&e) == B_FALSE) {
29327836SJohn.Forte@Sun.COM rtn = EIO;
29337836SJohn.Forte@Sun.COM break;
29347836SJohn.Forte@Sun.COM }
29357836SJohn.Forte@Sun.COM
29367836SJohn.Forte@Sun.COM /*
29377836SJohn.Forte@Sun.COM * If Send Targets discovery is enabled, then kickoff
29387836SJohn.Forte@Sun.COM * discovery of the targets advertised by the recently
29397836SJohn.Forte@Sun.COM * added discovery address.
29407836SJohn.Forte@Sun.COM */
29417836SJohn.Forte@Sun.COM method = persistent_disc_meth_get();
29427836SJohn.Forte@Sun.COM if (method & iSCSIDiscoveryMethodSendTargets) {
29437836SJohn.Forte@Sun.COM
29447836SJohn.Forte@Sun.COM iscsid_addr_to_sockaddr(e.e_insize,
29457836SJohn.Forte@Sun.COM &e.e_u, e.e_port, &addr_dsc.sin);
29467836SJohn.Forte@Sun.COM iscsid_do_sendtgts(&e);
29477836SJohn.Forte@Sun.COM (void) iscsid_login_tgt(ihp, NULL,
29487836SJohn.Forte@Sun.COM iSCSIDiscoveryMethodSendTargets,
29497836SJohn.Forte@Sun.COM &addr_dsc.sin);
29507836SJohn.Forte@Sun.COM
29517836SJohn.Forte@Sun.COM }
29527836SJohn.Forte@Sun.COM break;
29537836SJohn.Forte@Sun.COM
29547836SJohn.Forte@Sun.COM /*
29557836SJohn.Forte@Sun.COM * ISCSI_DISCOVERY_ADDR_LIST_GET
29567836SJohn.Forte@Sun.COM */
29577836SJohn.Forte@Sun.COM case ISCSI_DISCOVERY_ADDR_LIST_GET:
29587836SJohn.Forte@Sun.COM /* copyin user args */
29597836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &ial, sizeof (ial), mode)) {
29607836SJohn.Forte@Sun.COM rtn = EFAULT;
29617836SJohn.Forte@Sun.COM break;
29627836SJohn.Forte@Sun.COM }
29637836SJohn.Forte@Sun.COM
29647836SJohn.Forte@Sun.COM if (ial.al_vers != ISCSI_INTERFACE_VERSION) {
29657836SJohn.Forte@Sun.COM rtn = EINVAL;
29667836SJohn.Forte@Sun.COM break;
29677836SJohn.Forte@Sun.COM }
29687836SJohn.Forte@Sun.COM
29697836SJohn.Forte@Sun.COM list_space = sizeof (iscsi_addr_list_t);
29707836SJohn.Forte@Sun.COM if (ial.al_in_cnt != 0) {
29717836SJohn.Forte@Sun.COM list_space += (sizeof (iscsi_addr_t) *
29727836SJohn.Forte@Sun.COM (ial.al_in_cnt - 1));
29737836SJohn.Forte@Sun.COM }
29747836SJohn.Forte@Sun.COM
29757836SJohn.Forte@Sun.COM ialp = kmem_zalloc(list_space, KM_SLEEP);
29767836SJohn.Forte@Sun.COM bcopy(&ial, ialp, sizeof (iscsi_addr_list_t));
29777836SJohn.Forte@Sun.COM
29787836SJohn.Forte@Sun.COM void_p = NULL;
29797836SJohn.Forte@Sun.COM ialp->al_out_cnt = 0;
29807836SJohn.Forte@Sun.COM persistent_disc_addr_lock();
29817836SJohn.Forte@Sun.COM while (persistent_disc_addr_next(&void_p, &e) == B_TRUE) {
29827836SJohn.Forte@Sun.COM if (ialp->al_out_cnt < ialp->al_in_cnt) {
29837836SJohn.Forte@Sun.COM int i = ialp->al_out_cnt;
29847836SJohn.Forte@Sun.COM iscsi_addr_t *addr = &ialp->al_addrs[i];
29857836SJohn.Forte@Sun.COM
29867836SJohn.Forte@Sun.COM addr->a_port = e.e_port;
29877836SJohn.Forte@Sun.COM addr->a_addr.i_insize = e.e_insize;
29887836SJohn.Forte@Sun.COM addr->a_oid = e.e_oid;
29897836SJohn.Forte@Sun.COM
29907836SJohn.Forte@Sun.COM if (e.e_insize == sizeof (struct in_addr)) {
29917836SJohn.Forte@Sun.COM /* IPv4 */
29927836SJohn.Forte@Sun.COM addr->a_addr.i_addr.in4.s_addr =
29937836SJohn.Forte@Sun.COM e.e_u.u_in4.s_addr;
29947836SJohn.Forte@Sun.COM } else if (e.e_insize ==
29957836SJohn.Forte@Sun.COM sizeof (struct in6_addr)) {
29967836SJohn.Forte@Sun.COM /* IPv6 */
29977836SJohn.Forte@Sun.COM bcopy(e.e_u.u_in6.s6_addr,
29987836SJohn.Forte@Sun.COM addr->a_addr.i_addr.in6.s6_addr,
29997836SJohn.Forte@Sun.COM 16);
30007836SJohn.Forte@Sun.COM }
30017836SJohn.Forte@Sun.COM }
30027836SJohn.Forte@Sun.COM ialp->al_out_cnt++;
30037836SJohn.Forte@Sun.COM }
30047836SJohn.Forte@Sun.COM persistent_disc_addr_unlock();
30057836SJohn.Forte@Sun.COM
30067836SJohn.Forte@Sun.COM rtn = ddi_copyout(ialp, (caddr_t)arg, list_space, mode);
30077836SJohn.Forte@Sun.COM kmem_free(ialp, list_space);
30087836SJohn.Forte@Sun.COM break;
30097836SJohn.Forte@Sun.COM
30107836SJohn.Forte@Sun.COM /*
30117836SJohn.Forte@Sun.COM * ISCSI_ISNS_SERVER_ADDR_LIST_GET
30127836SJohn.Forte@Sun.COM */
30137836SJohn.Forte@Sun.COM case ISCSI_ISNS_SERVER_ADDR_LIST_GET:
30147836SJohn.Forte@Sun.COM /* copyin user args */
30157836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &ial, sizeof (ial), mode)) {
30167836SJohn.Forte@Sun.COM rtn = EFAULT;
30177836SJohn.Forte@Sun.COM break;
30187836SJohn.Forte@Sun.COM }
30197836SJohn.Forte@Sun.COM
30207836SJohn.Forte@Sun.COM if (ial.al_vers != ISCSI_INTERFACE_VERSION) {
30217836SJohn.Forte@Sun.COM rtn = EINVAL;
30227836SJohn.Forte@Sun.COM break;
30237836SJohn.Forte@Sun.COM }
30247836SJohn.Forte@Sun.COM
30257836SJohn.Forte@Sun.COM list_space = sizeof (iscsi_addr_list_t);
30267836SJohn.Forte@Sun.COM if (ial.al_in_cnt != 0) {
30277836SJohn.Forte@Sun.COM list_space += (sizeof (iscsi_addr_t) *
30287836SJohn.Forte@Sun.COM (ial.al_in_cnt - 1));
30297836SJohn.Forte@Sun.COM }
30307836SJohn.Forte@Sun.COM
30317836SJohn.Forte@Sun.COM ialp = kmem_zalloc(list_space, KM_SLEEP);
30327836SJohn.Forte@Sun.COM bcopy(&ial, ialp, sizeof (iscsi_addr_list_t));
30337836SJohn.Forte@Sun.COM
30347836SJohn.Forte@Sun.COM void_p = NULL;
30357836SJohn.Forte@Sun.COM ialp->al_out_cnt = 0;
30367836SJohn.Forte@Sun.COM persistent_isns_addr_lock();
30377836SJohn.Forte@Sun.COM while (persistent_isns_addr_next(&void_p, &e) == B_TRUE) {
30387836SJohn.Forte@Sun.COM if (ialp->al_out_cnt < ialp->al_in_cnt) {
30397836SJohn.Forte@Sun.COM int i = ialp->al_out_cnt;
30407836SJohn.Forte@Sun.COM iscsi_addr_t *addr = &ialp->al_addrs[i];
30417836SJohn.Forte@Sun.COM
30427836SJohn.Forte@Sun.COM addr->a_port = e.e_port;
30437836SJohn.Forte@Sun.COM addr->a_addr.i_insize = e.e_insize;
30447836SJohn.Forte@Sun.COM if (e.e_insize == sizeof (struct in_addr)) {
30457836SJohn.Forte@Sun.COM /* IPv4 */
30467836SJohn.Forte@Sun.COM addr->a_addr.i_addr.in4.s_addr =
30477836SJohn.Forte@Sun.COM e.e_u.u_in4.s_addr;
30487836SJohn.Forte@Sun.COM } else if (e.e_insize ==
30497836SJohn.Forte@Sun.COM sizeof (struct in6_addr)) {
30507836SJohn.Forte@Sun.COM /* IPv6 */
30517836SJohn.Forte@Sun.COM bcopy(e.e_u.u_in6.s6_addr,
30527836SJohn.Forte@Sun.COM addr->a_addr.i_addr.in6.s6_addr,
30537836SJohn.Forte@Sun.COM 16);
30547836SJohn.Forte@Sun.COM }
30557836SJohn.Forte@Sun.COM }
30567836SJohn.Forte@Sun.COM ialp->al_out_cnt++;
30577836SJohn.Forte@Sun.COM }
30587836SJohn.Forte@Sun.COM persistent_isns_addr_unlock();
30597836SJohn.Forte@Sun.COM
30607836SJohn.Forte@Sun.COM rtn = ddi_copyout(ialp, (caddr_t)arg, list_space, mode);
30617836SJohn.Forte@Sun.COM kmem_free(ialp, list_space);
30627836SJohn.Forte@Sun.COM break;
30637836SJohn.Forte@Sun.COM
30647836SJohn.Forte@Sun.COM /*
30657836SJohn.Forte@Sun.COM * ISCSI_DISCOVERY_ADDR_CLEAR:
30667836SJohn.Forte@Sun.COM */
30677836SJohn.Forte@Sun.COM case ISCSI_DISCOVERY_ADDR_CLEAR:
30687836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &e, sizeof (e), mode)) {
30697836SJohn.Forte@Sun.COM rtn = EFAULT;
30707836SJohn.Forte@Sun.COM break;
30717836SJohn.Forte@Sun.COM } else if (e.e_vers != ISCSI_INTERFACE_VERSION) {
30727836SJohn.Forte@Sun.COM rtn = EINVAL;
30737836SJohn.Forte@Sun.COM break;
30747836SJohn.Forte@Sun.COM }
30757836SJohn.Forte@Sun.COM
30767836SJohn.Forte@Sun.COM iscsid_addr_to_sockaddr(e.e_insize,
30777836SJohn.Forte@Sun.COM &e.e_u, e.e_port, &addr_dsc.sin);
30787836SJohn.Forte@Sun.COM
307910156SZhang.Yi@Sun.COM /* If discovery in progress, try few times before return busy */
308010156SZhang.Yi@Sun.COM retry = 0;
308110156SZhang.Yi@Sun.COM mutex_enter(&ihp->hba_discovery_events_mutex);
308210156SZhang.Yi@Sun.COM while (ihp->hba_discovery_in_progress == B_TRUE) {
308310156SZhang.Yi@Sun.COM if (++retry == 5) {
308410156SZhang.Yi@Sun.COM rtn = EBUSY;
308510156SZhang.Yi@Sun.COM break;
308610156SZhang.Yi@Sun.COM }
308710156SZhang.Yi@Sun.COM mutex_exit(&ihp->hba_discovery_events_mutex);
308810156SZhang.Yi@Sun.COM delay(SEC_TO_TICK(ISCSI_DISC_DELAY));
308910156SZhang.Yi@Sun.COM mutex_enter(&ihp->hba_discovery_events_mutex);
309010156SZhang.Yi@Sun.COM }
309110156SZhang.Yi@Sun.COM
309210156SZhang.Yi@Sun.COM /*
309310156SZhang.Yi@Sun.COM * Clear discovery address first, so that any bus config
309410156SZhang.Yi@Sun.COM * will ignore this discovery address
309510156SZhang.Yi@Sun.COM */
309610156SZhang.Yi@Sun.COM if (rtn == 0 && persistent_disc_addr_clear(&e) == B_FALSE) {
309710156SZhang.Yi@Sun.COM rtn = EIO;
309810156SZhang.Yi@Sun.COM }
309910156SZhang.Yi@Sun.COM mutex_exit(&ihp->hba_discovery_events_mutex);
310010156SZhang.Yi@Sun.COM
310110156SZhang.Yi@Sun.COM if (rtn != 0) {
310210156SZhang.Yi@Sun.COM break;
310310156SZhang.Yi@Sun.COM }
31047836SJohn.Forte@Sun.COM /* Attempt to logout of associated targets */
31057836SJohn.Forte@Sun.COM if (iscsid_del(ihp, NULL,
31067836SJohn.Forte@Sun.COM iSCSIDiscoveryMethodSendTargets, &addr_dsc.sin) ==
310710156SZhang.Yi@Sun.COM B_FALSE) {
310810156SZhang.Yi@Sun.COM /* Failure!, restore the discovery addr. */
310910156SZhang.Yi@Sun.COM if (persistent_disc_addr_set(&e) == B_FALSE) {
311010156SZhang.Yi@Sun.COM cmn_err(CE_WARN, "Failed to restore sendtgt "
311110156SZhang.Yi@Sun.COM "discovery address after logout associated "
311210156SZhang.Yi@Sun.COM "targets failures.");
31137836SJohn.Forte@Sun.COM }
31147836SJohn.Forte@Sun.COM rtn = EBUSY;
31157836SJohn.Forte@Sun.COM }
31167836SJohn.Forte@Sun.COM break;
31177836SJohn.Forte@Sun.COM
31187836SJohn.Forte@Sun.COM /*
31197836SJohn.Forte@Sun.COM * ISCSI_ISNS_SERVER_CLEAR:
31207836SJohn.Forte@Sun.COM */
31217836SJohn.Forte@Sun.COM case ISCSI_ISNS_SERVER_ADDR_CLEAR:
31227836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &e, sizeof (e), mode)) {
31237836SJohn.Forte@Sun.COM rtn = EFAULT;
31247836SJohn.Forte@Sun.COM break;
31257836SJohn.Forte@Sun.COM } else if (e.e_vers != ISCSI_INTERFACE_VERSION) {
31267836SJohn.Forte@Sun.COM rtn = EINVAL;
31277836SJohn.Forte@Sun.COM break;
31287836SJohn.Forte@Sun.COM }
31297836SJohn.Forte@Sun.COM
31307836SJohn.Forte@Sun.COM iscsid_addr_to_sockaddr(e.e_insize,
31317836SJohn.Forte@Sun.COM &e.e_u, e.e_port, &addr_dsc.sin);
31327836SJohn.Forte@Sun.COM
313310156SZhang.Yi@Sun.COM /* If discovery in progress, try few times before return busy */
313410156SZhang.Yi@Sun.COM retry = 0;
313510156SZhang.Yi@Sun.COM mutex_enter(&ihp->hba_discovery_events_mutex);
313610156SZhang.Yi@Sun.COM while (ihp->hba_discovery_in_progress == B_TRUE) {
313710156SZhang.Yi@Sun.COM if (++retry == 5) {
313810156SZhang.Yi@Sun.COM rtn = EBUSY;
313910156SZhang.Yi@Sun.COM break;
314010156SZhang.Yi@Sun.COM }
314110156SZhang.Yi@Sun.COM mutex_exit(&ihp->hba_discovery_events_mutex);
314210156SZhang.Yi@Sun.COM delay(SEC_TO_TICK(ISCSI_DISC_DELAY));
314310156SZhang.Yi@Sun.COM mutex_enter(&ihp->hba_discovery_events_mutex);
314410156SZhang.Yi@Sun.COM }
314510156SZhang.Yi@Sun.COM
314610156SZhang.Yi@Sun.COM /*
314710156SZhang.Yi@Sun.COM * Clear isns server address first, so that any bus config
314810156SZhang.Yi@Sun.COM * will ignore any target registerd on this isns server
314910156SZhang.Yi@Sun.COM */
315010156SZhang.Yi@Sun.COM if (rtn == 0 && persistent_isns_addr_clear(&e) == B_FALSE) {
315110156SZhang.Yi@Sun.COM rtn = EIO;
315210156SZhang.Yi@Sun.COM }
315310156SZhang.Yi@Sun.COM mutex_exit(&ihp->hba_discovery_events_mutex);
315410156SZhang.Yi@Sun.COM
315510156SZhang.Yi@Sun.COM if (rtn != 0) {
315610156SZhang.Yi@Sun.COM break;
315710156SZhang.Yi@Sun.COM }
315810156SZhang.Yi@Sun.COM
31597836SJohn.Forte@Sun.COM /* Attempt logout of associated targets */
31607836SJohn.Forte@Sun.COM if (iscsid_del(ihp, NULL, iSCSIDiscoveryMethodISNS,
316110156SZhang.Yi@Sun.COM &addr_dsc.sin) == B_FALSE) {
316210156SZhang.Yi@Sun.COM /* Failure!, restore the isns server addr. */
316310156SZhang.Yi@Sun.COM
316410156SZhang.Yi@Sun.COM if (persistent_isns_addr_set(&e) == B_FALSE) {
316510156SZhang.Yi@Sun.COM cmn_err(CE_WARN, "Failed to restore isns server"
316610156SZhang.Yi@Sun.COM " address after logout associated targets"
316710156SZhang.Yi@Sun.COM " failures.");
31687836SJohn.Forte@Sun.COM }
316910156SZhang.Yi@Sun.COM rtn = EBUSY;
317010156SZhang.Yi@Sun.COM } else {
31717836SJohn.Forte@Sun.COM method = persistent_disc_meth_get();
31727836SJohn.Forte@Sun.COM if (method & iSCSIDiscoveryMethodISNS) {
31737836SJohn.Forte@Sun.COM boolean_t is_last_isns_server_b =
31747836SJohn.Forte@Sun.COM B_FALSE;
31757836SJohn.Forte@Sun.COM int isns_server_count = 0;
31767836SJohn.Forte@Sun.COM void *void_p = NULL;
31777836SJohn.Forte@Sun.COM
31787836SJohn.Forte@Sun.COM /*
31797836SJohn.Forte@Sun.COM * Check if the last iSNS server's been
31807836SJohn.Forte@Sun.COM * removed.
31817836SJohn.Forte@Sun.COM */
31827836SJohn.Forte@Sun.COM {
31837836SJohn.Forte@Sun.COM entry_t tmp_e;
31847836SJohn.Forte@Sun.COM persistent_isns_addr_lock();
31857836SJohn.Forte@Sun.COM while (persistent_isns_addr_next(
31867836SJohn.Forte@Sun.COM &void_p, &tmp_e) == B_TRUE) {
31877836SJohn.Forte@Sun.COM isns_server_count++;
31887836SJohn.Forte@Sun.COM }
31897836SJohn.Forte@Sun.COM }
31907836SJohn.Forte@Sun.COM persistent_isns_addr_unlock();
31917836SJohn.Forte@Sun.COM if (isns_server_count == 0) {
31927836SJohn.Forte@Sun.COM is_last_isns_server_b = B_TRUE;
31937836SJohn.Forte@Sun.COM }
31947836SJohn.Forte@Sun.COM
31957836SJohn.Forte@Sun.COM /*
31967836SJohn.Forte@Sun.COM * Deregister this node from this iSNS
31977836SJohn.Forte@Sun.COM * server.
31987836SJohn.Forte@Sun.COM */
31997836SJohn.Forte@Sun.COM initiator_node_name = kmem_zalloc(
32007836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN, KM_SLEEP);
32017836SJohn.Forte@Sun.COM if (persistent_initiator_name_get(
32027836SJohn.Forte@Sun.COM initiator_node_name,
32037836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN) == B_TRUE) {
32047836SJohn.Forte@Sun.COM
32057836SJohn.Forte@Sun.COM if (strlen(initiator_node_name) > 0) {
32067836SJohn.Forte@Sun.COM (void) isns_dereg_one_server(
32077836SJohn.Forte@Sun.COM &e, (uint8_t *)
32087836SJohn.Forte@Sun.COM initiator_node_name,
32097836SJohn.Forte@Sun.COM is_last_isns_server_b);
32107836SJohn.Forte@Sun.COM }
32117836SJohn.Forte@Sun.COM }
32127836SJohn.Forte@Sun.COM kmem_free(initiator_node_name,
32137836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN);
32147836SJohn.Forte@Sun.COM initiator_node_name = NULL;
32157836SJohn.Forte@Sun.COM }
32167836SJohn.Forte@Sun.COM }
32177836SJohn.Forte@Sun.COM break;
32187836SJohn.Forte@Sun.COM
32197836SJohn.Forte@Sun.COM /*
32207836SJohn.Forte@Sun.COM * ISCSI_DISCOVERY_SET -
32217836SJohn.Forte@Sun.COM */
32227836SJohn.Forte@Sun.COM case ISCSI_DISCOVERY_SET:
32237836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &method, sizeof (method), mode)) {
32247836SJohn.Forte@Sun.COM rtn = EFAULT;
32257836SJohn.Forte@Sun.COM break;
32267836SJohn.Forte@Sun.COM }
32277836SJohn.Forte@Sun.COM
32287836SJohn.Forte@Sun.COM if (persistent_disc_meth_set(method) == B_FALSE) {
32297836SJohn.Forte@Sun.COM rtn = EIO;
32307836SJohn.Forte@Sun.COM } else {
32318265SBing.Zhao@Sun.COM (void) iscsid_enable_discovery(ihp, method, B_FALSE);
32327836SJohn.Forte@Sun.COM iscsid_poke_discovery(ihp, method);
32337836SJohn.Forte@Sun.COM (void) iscsid_login_tgt(ihp, NULL, method, NULL);
32347836SJohn.Forte@Sun.COM }
32357836SJohn.Forte@Sun.COM break;
32367836SJohn.Forte@Sun.COM
32377836SJohn.Forte@Sun.COM /*
32387836SJohn.Forte@Sun.COM * ISCSI_DISCOVERY_GET -
32397836SJohn.Forte@Sun.COM */
32407836SJohn.Forte@Sun.COM case ISCSI_DISCOVERY_GET:
32417836SJohn.Forte@Sun.COM method = persistent_disc_meth_get();
32427836SJohn.Forte@Sun.COM rtn = ddi_copyout(&method, (caddr_t)arg,
32437836SJohn.Forte@Sun.COM sizeof (method), mode);
32447836SJohn.Forte@Sun.COM break;
32457836SJohn.Forte@Sun.COM
32467836SJohn.Forte@Sun.COM /*
32477836SJohn.Forte@Sun.COM * ISCSI_DISCOVERY_CLEAR -
32487836SJohn.Forte@Sun.COM */
32497836SJohn.Forte@Sun.COM case ISCSI_DISCOVERY_CLEAR:
32507836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &method, sizeof (method), mode)) {
32517836SJohn.Forte@Sun.COM rtn = EFAULT;
32527836SJohn.Forte@Sun.COM break;
32537836SJohn.Forte@Sun.COM }
32547836SJohn.Forte@Sun.COM
32558428SZhang.Yi@Sun.COM /* If discovery in progress, try few times before return busy */
32568428SZhang.Yi@Sun.COM retry = 0;
32578428SZhang.Yi@Sun.COM mutex_enter(&ihp->hba_discovery_events_mutex);
32588428SZhang.Yi@Sun.COM while (ihp->hba_discovery_in_progress == B_TRUE) {
32598428SZhang.Yi@Sun.COM if (++retry == 5) {
32608428SZhang.Yi@Sun.COM rtn = EBUSY;
32618428SZhang.Yi@Sun.COM break;
32628428SZhang.Yi@Sun.COM }
32638428SZhang.Yi@Sun.COM mutex_exit(&ihp->hba_discovery_events_mutex);
326410156SZhang.Yi@Sun.COM delay(SEC_TO_TICK(ISCSI_DISC_DELAY));
32658428SZhang.Yi@Sun.COM mutex_enter(&ihp->hba_discovery_events_mutex);
32667836SJohn.Forte@Sun.COM }
32677836SJohn.Forte@Sun.COM
32687836SJohn.Forte@Sun.COM /*
32698428SZhang.Yi@Sun.COM * Clear discovery first, so that any bus config or
32708428SZhang.Yi@Sun.COM * discovery requests will ignore this discovery method
32717836SJohn.Forte@Sun.COM */
32728428SZhang.Yi@Sun.COM if (rtn == 0 && persistent_disc_meth_clear(method) == B_FALSE) {
32737836SJohn.Forte@Sun.COM rtn = EIO;
32748428SZhang.Yi@Sun.COM }
32758428SZhang.Yi@Sun.COM mutex_exit(&ihp->hba_discovery_events_mutex);
32768428SZhang.Yi@Sun.COM
32778428SZhang.Yi@Sun.COM if (rtn != 0) {
32787836SJohn.Forte@Sun.COM break;
32797836SJohn.Forte@Sun.COM }
32808428SZhang.Yi@Sun.COM
32818428SZhang.Yi@Sun.COM /* Attempt to logout from all associated targets */
32828428SZhang.Yi@Sun.COM if (iscsid_disable_discovery(ihp, method) == B_FALSE) {
32838428SZhang.Yi@Sun.COM /* Failure!, reset the discovery */
32848428SZhang.Yi@Sun.COM if (persistent_disc_meth_set(method) == B_FALSE) {
32858428SZhang.Yi@Sun.COM cmn_err(CE_WARN, "Failed to reset discovery "
32868428SZhang.Yi@Sun.COM "method after discovery disable failure.");
32878428SZhang.Yi@Sun.COM }
32888428SZhang.Yi@Sun.COM rtn = EBUSY;
32898428SZhang.Yi@Sun.COM }
32907836SJohn.Forte@Sun.COM break;
32917836SJohn.Forte@Sun.COM
32927836SJohn.Forte@Sun.COM /*
32937836SJohn.Forte@Sun.COM * ISCSI_DISCOVERY_PROPS -
32947836SJohn.Forte@Sun.COM */
32957836SJohn.Forte@Sun.COM case ISCSI_DISCOVERY_PROPS:
32967836SJohn.Forte@Sun.COM iscsid_props(&discovery_props);
32977836SJohn.Forte@Sun.COM if (ddi_copyout(&discovery_props, (caddr_t)arg,
32987836SJohn.Forte@Sun.COM sizeof (discovery_props), mode))
32997836SJohn.Forte@Sun.COM rtn = EFAULT;
33007836SJohn.Forte@Sun.COM break;
33017836SJohn.Forte@Sun.COM
33027836SJohn.Forte@Sun.COM /*
33037836SJohn.Forte@Sun.COM * ISCSI_LUN_OID_LIST --
33047836SJohn.Forte@Sun.COM */
33057836SJohn.Forte@Sun.COM case ISCSI_LUN_OID_LIST_GET:
33067836SJohn.Forte@Sun.COM ll = (iscsi_lun_list_t *)kmem_alloc(sizeof (*ll), KM_SLEEP);
33077836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, ll, sizeof (*ll), mode)) {
33087836SJohn.Forte@Sun.COM rtn = EFAULT;
33097836SJohn.Forte@Sun.COM kmem_free(ll, sizeof (*ll));
33107836SJohn.Forte@Sun.COM break;
33117836SJohn.Forte@Sun.COM }
33127836SJohn.Forte@Sun.COM
33137836SJohn.Forte@Sun.COM if (ll->ll_vers != ISCSI_INTERFACE_VERSION) {
33147836SJohn.Forte@Sun.COM rtn = EINVAL;
33157836SJohn.Forte@Sun.COM kmem_free(ll, sizeof (*ll));
33167836SJohn.Forte@Sun.COM break;
33177836SJohn.Forte@Sun.COM }
33187836SJohn.Forte@Sun.COM
33197836SJohn.Forte@Sun.COM /*
33207836SJohn.Forte@Sun.COM * Find out how much space the user has allocated in their
33217836SJohn.Forte@Sun.COM * structure. Match the same space for our structure.
33227836SJohn.Forte@Sun.COM */
33237836SJohn.Forte@Sun.COM lun_sz = sizeof (iscsi_lun_list_t);
33247836SJohn.Forte@Sun.COM if (ll->ll_in_cnt > 0) {
33257836SJohn.Forte@Sun.COM lun_sz += (ll->ll_in_cnt - 1) * sizeof (iscsi_if_lun_t);
33267836SJohn.Forte@Sun.COM }
33277836SJohn.Forte@Sun.COM
33287836SJohn.Forte@Sun.COM llp = kmem_zalloc(lun_sz, KM_SLEEP);
33297836SJohn.Forte@Sun.COM bcopy(ll, llp, sizeof (*ll));
33307836SJohn.Forte@Sun.COM kmem_free(ll, sizeof (*ll));
33317836SJohn.Forte@Sun.COM
33327836SJohn.Forte@Sun.COM /*
33337836SJohn.Forte@Sun.COM * Check to see if oid references a target-param oid. If so,
33347836SJohn.Forte@Sun.COM * find the associated session oid before getting lu list.
33357836SJohn.Forte@Sun.COM */
33367836SJohn.Forte@Sun.COM if (iscsi_targetparam_get_name(llp->ll_tgt_oid) != NULL) {
33377836SJohn.Forte@Sun.COM for (isp = ihp->hba_sess_list; isp;
33387836SJohn.Forte@Sun.COM isp = isp->sess_next) {
33397836SJohn.Forte@Sun.COM if (isp->sess_target_oid == llp->ll_tgt_oid) {
33407836SJohn.Forte@Sun.COM target_oid = isp->sess_oid;
33417836SJohn.Forte@Sun.COM break;
33427836SJohn.Forte@Sun.COM }
33437836SJohn.Forte@Sun.COM }
33447836SJohn.Forte@Sun.COM } else {
33457836SJohn.Forte@Sun.COM target_oid = llp->ll_tgt_oid;
33467836SJohn.Forte@Sun.COM }
33477836SJohn.Forte@Sun.COM
33487836SJohn.Forte@Sun.COM
33497836SJohn.Forte@Sun.COM /*
33507836SJohn.Forte@Sun.COM * Look at the LUNs attached to the specified target. If there
33517836SJohn.Forte@Sun.COM * is space in the user structure save that information locally.
33527836SJohn.Forte@Sun.COM * Always add up the count to the total. By always adding
33537836SJohn.Forte@Sun.COM * the count this code can be used if ll_in_cnt == 0 and
33547836SJohn.Forte@Sun.COM * the user just wishes to know the appropriate size to
33557836SJohn.Forte@Sun.COM * allocate.
33567836SJohn.Forte@Sun.COM */
33577836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
33587836SJohn.Forte@Sun.COM for (isp = ihp->hba_sess_list; isp; isp = isp->sess_next) {
33597836SJohn.Forte@Sun.COM if ((llp->ll_all_tgts == B_FALSE) &&
33607836SJohn.Forte@Sun.COM (isp->sess_oid != target_oid)) {
33617836SJohn.Forte@Sun.COM continue;
33627836SJohn.Forte@Sun.COM }
33637836SJohn.Forte@Sun.COM rw_enter(&isp->sess_lun_list_rwlock, RW_READER);
33647836SJohn.Forte@Sun.COM for (ilp = isp->sess_lun_list; ilp;
33657836SJohn.Forte@Sun.COM ilp = ilp->lun_next) {
33668531SBing.Zhao@Sun.COM if ((ilp->lun_state &
33678531SBing.Zhao@Sun.COM ISCSI_LUN_STATE_ONLINE) &&
33688531SBing.Zhao@Sun.COM !(ilp->lun_state &
33698531SBing.Zhao@Sun.COM ISCSI_LUN_STATE_INVALID)) {
33707836SJohn.Forte@Sun.COM if (llp->ll_out_cnt <
33717836SJohn.Forte@Sun.COM llp->ll_in_cnt) {
33727836SJohn.Forte@Sun.COM iscsi_if_lun_t *lp;
33737836SJohn.Forte@Sun.COM lp = &llp->ll_luns[
33747836SJohn.Forte@Sun.COM llp->ll_out_cnt];
33757836SJohn.Forte@Sun.COM
33767836SJohn.Forte@Sun.COM lp->l_tgt_oid =
33777836SJohn.Forte@Sun.COM isp->sess_oid;
33787836SJohn.Forte@Sun.COM lp->l_oid = ilp->lun_oid;
33797836SJohn.Forte@Sun.COM lp->l_num = ilp->lun_num;
33807836SJohn.Forte@Sun.COM }
33817836SJohn.Forte@Sun.COM llp->ll_out_cnt++;
33827836SJohn.Forte@Sun.COM }
33837836SJohn.Forte@Sun.COM }
33847836SJohn.Forte@Sun.COM rw_exit(&isp->sess_lun_list_rwlock);
33857836SJohn.Forte@Sun.COM }
33867836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
33877836SJohn.Forte@Sun.COM
33887836SJohn.Forte@Sun.COM if (ddi_copyout(llp, (caddr_t)arg, lun_sz, mode)) {
33897836SJohn.Forte@Sun.COM rtn = EFAULT;
33907836SJohn.Forte@Sun.COM }
33917836SJohn.Forte@Sun.COM
33927836SJohn.Forte@Sun.COM kmem_free(llp, lun_sz);
33937836SJohn.Forte@Sun.COM break;
33947836SJohn.Forte@Sun.COM
33957836SJohn.Forte@Sun.COM /*
33967836SJohn.Forte@Sun.COM * ISCSI_LUN_PROPS_GET --
33977836SJohn.Forte@Sun.COM */
33987836SJohn.Forte@Sun.COM case ISCSI_LUN_PROPS_GET:
33997836SJohn.Forte@Sun.COM lun = (iscsi_lun_props_t *)kmem_zalloc(sizeof (*lun), KM_SLEEP);
34007836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, lun, sizeof (*lun), mode)) {
34017836SJohn.Forte@Sun.COM rtn = EFAULT;
34027836SJohn.Forte@Sun.COM kmem_free(lun, sizeof (*lun));
34037836SJohn.Forte@Sun.COM break;
34047836SJohn.Forte@Sun.COM }
34057836SJohn.Forte@Sun.COM
34067836SJohn.Forte@Sun.COM if (lun->lp_vers != ISCSI_INTERFACE_VERSION) {
34077836SJohn.Forte@Sun.COM rtn = EINVAL;
34087836SJohn.Forte@Sun.COM kmem_free(lun, sizeof (*lun));
34097836SJohn.Forte@Sun.COM break;
34107836SJohn.Forte@Sun.COM }
34117836SJohn.Forte@Sun.COM
34127836SJohn.Forte@Sun.COM /*
34137836SJohn.Forte@Sun.COM * For the target specified, find the LUN specified and
34147836SJohn.Forte@Sun.COM * return its properties
34157836SJohn.Forte@Sun.COM */
34167836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
34177836SJohn.Forte@Sun.COM rtn = iscsi_sess_get(lun->lp_tgt_oid, ihp, &isp);
34187836SJohn.Forte@Sun.COM if (rtn != 0) {
34197836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
34207836SJohn.Forte@Sun.COM rtn = EFAULT;
34217836SJohn.Forte@Sun.COM kmem_free(lun, sizeof (*lun));
34227836SJohn.Forte@Sun.COM break;
34237836SJohn.Forte@Sun.COM }
34247836SJohn.Forte@Sun.COM rtn = EINVAL; /* Set bad rtn, correct only if found */
34257836SJohn.Forte@Sun.COM rw_enter(&isp->sess_lun_list_rwlock, RW_READER);
34267836SJohn.Forte@Sun.COM for (ilp = isp->sess_lun_list; ilp; ilp = ilp->lun_next) {
34277836SJohn.Forte@Sun.COM if (ilp->lun_oid == lun->lp_oid) {
34287836SJohn.Forte@Sun.COM lun->lp_num = ilp->lun_num;
34297836SJohn.Forte@Sun.COM lun->lp_status = LunValid;
34307836SJohn.Forte@Sun.COM lun->lp_time_online = ilp->lun_time_online;
34317836SJohn.Forte@Sun.COM
34327836SJohn.Forte@Sun.COM if (ilp->lun_pip != NULL) {
34337836SJohn.Forte@Sun.COM lun_dip = mdi_pi_get_client(
34347836SJohn.Forte@Sun.COM ilp->lun_pip);
34357836SJohn.Forte@Sun.COM } else {
34367836SJohn.Forte@Sun.COM lun_dip = ilp->lun_dip;
34377836SJohn.Forte@Sun.COM }
34387836SJohn.Forte@Sun.COM
34397836SJohn.Forte@Sun.COM if (lun_dip != NULL &&
34408446SZhang.Yi@Sun.COM ((i_ddi_devi_attached(lun_dip)) ||
34418446SZhang.Yi@Sun.COM (ddi_get_devstate(lun_dip) ==
34428446SZhang.Yi@Sun.COM DDI_DEVSTATE_UP))) {
34437836SJohn.Forte@Sun.COM (void) ddi_pathname(lun_dip,
34447836SJohn.Forte@Sun.COM lun->lp_pathname);
34457836SJohn.Forte@Sun.COM } else {
34467836SJohn.Forte@Sun.COM /*
34477836SJohn.Forte@Sun.COM * The LUN is not exported to the
34487836SJohn.Forte@Sun.COM * OS yet. It is in the process
34497836SJohn.Forte@Sun.COM * of being added.
34507836SJohn.Forte@Sun.COM */
34517836SJohn.Forte@Sun.COM lun->lp_status = LunDoesNotExist;
34527836SJohn.Forte@Sun.COM }
34537836SJohn.Forte@Sun.COM bcopy(ilp->lun_vid, lun->lp_vid,
34547836SJohn.Forte@Sun.COM sizeof (lun->lp_vid));
34557836SJohn.Forte@Sun.COM bcopy(ilp->lun_pid, lun->lp_pid,
34567836SJohn.Forte@Sun.COM sizeof (lun->lp_pid));
34577836SJohn.Forte@Sun.COM rtn = ddi_copyout(lun, (caddr_t)arg,
34587836SJohn.Forte@Sun.COM sizeof (*lun), mode);
34597836SJohn.Forte@Sun.COM if (rtn == -1) {
34607836SJohn.Forte@Sun.COM rtn = EFAULT;
34617836SJohn.Forte@Sun.COM }
34627836SJohn.Forte@Sun.COM break;
34637836SJohn.Forte@Sun.COM }
34647836SJohn.Forte@Sun.COM }
34657836SJohn.Forte@Sun.COM rw_exit(&isp->sess_lun_list_rwlock);
34667836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
34677836SJohn.Forte@Sun.COM
34687836SJohn.Forte@Sun.COM kmem_free(lun, sizeof (*lun));
34697836SJohn.Forte@Sun.COM break;
34707836SJohn.Forte@Sun.COM
34717836SJohn.Forte@Sun.COM /*
34727836SJohn.Forte@Sun.COM * ISCSI_CONN_OID_LIST_GET --
34737836SJohn.Forte@Sun.COM */
34747836SJohn.Forte@Sun.COM #define ISCSIIOCOLGC iscsi_ioctl_conn_oid_list_get_copyout
34757836SJohn.Forte@Sun.COM case ISCSI_CONN_OID_LIST_GET:
34767836SJohn.Forte@Sun.COM {
34777836SJohn.Forte@Sun.COM iscsi_conn_list_t *cl;
34787836SJohn.Forte@Sun.COM
34797836SJohn.Forte@Sun.COM /* Asuume the worst */
34807836SJohn.Forte@Sun.COM rtn = EFAULT;
34817836SJohn.Forte@Sun.COM
34827836SJohn.Forte@Sun.COM /* Copy the input argument into kernel world. */
34837836SJohn.Forte@Sun.COM cl = iscsi_ioctl_conn_oid_list_get_copyin(
34847836SJohn.Forte@Sun.COM (caddr_t)arg,
34857836SJohn.Forte@Sun.COM mode);
34867836SJohn.Forte@Sun.COM if (cl != NULL) {
34877836SJohn.Forte@Sun.COM if (iscsi_ioctl_conn_oid_list_get(ihp, cl) ==
34887836SJohn.Forte@Sun.COM B_TRUE) {
34897836SJohn.Forte@Sun.COM rtn =
34907836SJohn.Forte@Sun.COM ISCSIIOCOLGC(
34917836SJohn.Forte@Sun.COM cl, (caddr_t)arg, mode);
34927836SJohn.Forte@Sun.COM }
34937836SJohn.Forte@Sun.COM }
34947836SJohn.Forte@Sun.COM break;
34957836SJohn.Forte@Sun.COM }
34967836SJohn.Forte@Sun.COM #undef ISCSIIOCOLGC
34977836SJohn.Forte@Sun.COM /*
34987836SJohn.Forte@Sun.COM * ISCSI_CONN_OID_LIST_GET --
34997836SJohn.Forte@Sun.COM */
35007836SJohn.Forte@Sun.COM case ISCSI_CONN_PROPS_GET:
35017836SJohn.Forte@Sun.COM {
35027836SJohn.Forte@Sun.COM iscsi_conn_props_t *cp;
35037836SJohn.Forte@Sun.COM
35047836SJohn.Forte@Sun.COM /* Asuume the worst */
35057836SJohn.Forte@Sun.COM rtn = EFAULT;
35067836SJohn.Forte@Sun.COM
35077836SJohn.Forte@Sun.COM /* Copy the input argument into kernel world. */
35087836SJohn.Forte@Sun.COM cp = iscsi_ioctl_copyin(
35097836SJohn.Forte@Sun.COM (caddr_t)arg,
35107836SJohn.Forte@Sun.COM mode,
35117836SJohn.Forte@Sun.COM sizeof (iscsi_conn_props_t));
35127836SJohn.Forte@Sun.COM
35137836SJohn.Forte@Sun.COM if (cp != NULL) {
35147836SJohn.Forte@Sun.COM /* Get the propereties. */
35157836SJohn.Forte@Sun.COM if (iscsi_ioctl_conn_props_get(ihp, cp) ==
35167836SJohn.Forte@Sun.COM B_TRUE) {
35177836SJohn.Forte@Sun.COM rtn =
35187836SJohn.Forte@Sun.COM iscsi_ioctl_copyout(
35197836SJohn.Forte@Sun.COM cp,
35207836SJohn.Forte@Sun.COM sizeof (*cp),
35217836SJohn.Forte@Sun.COM (caddr_t)arg,
35227836SJohn.Forte@Sun.COM mode);
35238426SShengliang.Zhang@Sun.COM } else {
35248426SShengliang.Zhang@Sun.COM kmem_free(cp, sizeof (*cp));
35258426SShengliang.Zhang@Sun.COM cp = NULL;
35267836SJohn.Forte@Sun.COM }
35277836SJohn.Forte@Sun.COM }
35287836SJohn.Forte@Sun.COM break;
35297836SJohn.Forte@Sun.COM }
35307836SJohn.Forte@Sun.COM
35317836SJohn.Forte@Sun.COM /*
35327836SJohn.Forte@Sun.COM * ISCSI_RADIUS_GET -
35337836SJohn.Forte@Sun.COM */
35347836SJohn.Forte@Sun.COM case ISCSI_RADIUS_GET:
35357836SJohn.Forte@Sun.COM {
35367836SJohn.Forte@Sun.COM iscsi_nvfile_status_t status;
35377836SJohn.Forte@Sun.COM
35387836SJohn.Forte@Sun.COM radius = (iscsi_radius_props_t *)kmem_zalloc(sizeof (*radius),
35397836SJohn.Forte@Sun.COM KM_SLEEP);
35407836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, radius, sizeof (*radius), mode)) {
35417836SJohn.Forte@Sun.COM kmem_free(radius, sizeof (*radius));
35427836SJohn.Forte@Sun.COM rtn = EFAULT;
35437836SJohn.Forte@Sun.COM break;
35447836SJohn.Forte@Sun.COM } else if (radius->r_vers != ISCSI_INTERFACE_VERSION) {
35457836SJohn.Forte@Sun.COM kmem_free(radius, sizeof (*radius));
35467836SJohn.Forte@Sun.COM rtn = EINVAL;
35477836SJohn.Forte@Sun.COM break;
35487836SJohn.Forte@Sun.COM }
35497836SJohn.Forte@Sun.COM
35507836SJohn.Forte@Sun.COM old_oid = radius->r_oid;
35517836SJohn.Forte@Sun.COM
35527836SJohn.Forte@Sun.COM if (radius->r_oid == ihp->hba_oid) {
35537836SJohn.Forte@Sun.COM name = ihp->hba_name;
35547836SJohn.Forte@Sun.COM } else {
35557836SJohn.Forte@Sun.COM /*
35567836SJohn.Forte@Sun.COM * RADIUS configuration should be done on a per
35577836SJohn.Forte@Sun.COM * initiator basis.
35587836SJohn.Forte@Sun.COM */
35597836SJohn.Forte@Sun.COM kmem_free(radius, sizeof (*radius));
35607836SJohn.Forte@Sun.COM rtn = EINVAL;
35617836SJohn.Forte@Sun.COM break;
35627836SJohn.Forte@Sun.COM }
35637836SJohn.Forte@Sun.COM
35647836SJohn.Forte@Sun.COM status = persistent_radius_get(radius);
35657836SJohn.Forte@Sun.COM if (status == ISCSI_NVFILE_SUCCESS) {
35667836SJohn.Forte@Sun.COM /*
35677836SJohn.Forte@Sun.COM * Restore the value for overridden (and bogus) oid.
35687836SJohn.Forte@Sun.COM */
35697836SJohn.Forte@Sun.COM radius->r_oid = old_oid;
35707836SJohn.Forte@Sun.COM rtn = ddi_copyout(radius, (caddr_t)arg,
35717836SJohn.Forte@Sun.COM sizeof (*radius), mode);
35727836SJohn.Forte@Sun.COM } else if (status == ISCSI_NVFILE_NAMEVAL_NOT_FOUND) {
35737836SJohn.Forte@Sun.COM rtn = ENOENT;
35747836SJohn.Forte@Sun.COM } else {
35757836SJohn.Forte@Sun.COM rtn = EIO;
35767836SJohn.Forte@Sun.COM }
35777836SJohn.Forte@Sun.COM kmem_free(radius, sizeof (*radius));
35787836SJohn.Forte@Sun.COM break;
35797836SJohn.Forte@Sun.COM }
35807836SJohn.Forte@Sun.COM
35817836SJohn.Forte@Sun.COM /*
35827836SJohn.Forte@Sun.COM * ISCSI_RADIUS_SET -
35837836SJohn.Forte@Sun.COM */
35847836SJohn.Forte@Sun.COM case ISCSI_RADIUS_SET:
35857836SJohn.Forte@Sun.COM radius = (iscsi_radius_props_t *)kmem_zalloc(sizeof (*radius),
35867836SJohn.Forte@Sun.COM KM_SLEEP);
35877836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, radius, sizeof (*radius), mode)) {
35887836SJohn.Forte@Sun.COM rtn = EFAULT;
35897836SJohn.Forte@Sun.COM kmem_free(radius, sizeof (*radius));
35907836SJohn.Forte@Sun.COM break;
35917836SJohn.Forte@Sun.COM } else if (radius->r_vers != ISCSI_INTERFACE_VERSION) {
35927836SJohn.Forte@Sun.COM rtn = EINVAL;
35937836SJohn.Forte@Sun.COM kmem_free(radius, sizeof (*radius));
35947836SJohn.Forte@Sun.COM break;
35957836SJohn.Forte@Sun.COM }
35967836SJohn.Forte@Sun.COM
35977836SJohn.Forte@Sun.COM if (radius->r_oid == ihp->hba_oid) {
35987836SJohn.Forte@Sun.COM name = ihp->hba_name;
35997836SJohn.Forte@Sun.COM } else {
36007836SJohn.Forte@Sun.COM /*
36017836SJohn.Forte@Sun.COM * RADIUS configuration should be done on a per
36027836SJohn.Forte@Sun.COM * initiator basis.
36037836SJohn.Forte@Sun.COM */
36047836SJohn.Forte@Sun.COM kmem_free(radius, sizeof (*radius));
36057836SJohn.Forte@Sun.COM rtn = EINVAL;
36067836SJohn.Forte@Sun.COM break;
36077836SJohn.Forte@Sun.COM }
36087836SJohn.Forte@Sun.COM
36097836SJohn.Forte@Sun.COM if (persistent_radius_set(radius) == B_FALSE) {
36107836SJohn.Forte@Sun.COM rtn = EIO;
36117836SJohn.Forte@Sun.COM }
36127836SJohn.Forte@Sun.COM
36137836SJohn.Forte@Sun.COM kmem_free(radius, sizeof (*radius));
36147836SJohn.Forte@Sun.COM break;
36157836SJohn.Forte@Sun.COM
36167836SJohn.Forte@Sun.COM /*
36177836SJohn.Forte@Sun.COM * ISCSI_AUTH_GET -
36187836SJohn.Forte@Sun.COM */
36197836SJohn.Forte@Sun.COM case ISCSI_AUTH_GET:
36207836SJohn.Forte@Sun.COM auth = (iscsi_auth_props_t *)kmem_zalloc(sizeof (*auth),
36217836SJohn.Forte@Sun.COM KM_SLEEP);
36227836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, auth, sizeof (*auth), mode)) {
36237836SJohn.Forte@Sun.COM kmem_free(auth, sizeof (*auth));
36247836SJohn.Forte@Sun.COM rtn = EFAULT;
36257836SJohn.Forte@Sun.COM break;
36267836SJohn.Forte@Sun.COM } else if (auth->a_vers != ISCSI_INTERFACE_VERSION) {
36277836SJohn.Forte@Sun.COM kmem_free(auth, sizeof (*auth));
36287836SJohn.Forte@Sun.COM rtn = EINVAL;
36297836SJohn.Forte@Sun.COM break;
36307836SJohn.Forte@Sun.COM }
36317836SJohn.Forte@Sun.COM
36327836SJohn.Forte@Sun.COM old_oid = auth->a_oid;
36337836SJohn.Forte@Sun.COM
36347836SJohn.Forte@Sun.COM if (auth->a_oid == ihp->hba_oid) {
36357836SJohn.Forte@Sun.COM name = ihp->hba_name;
36367836SJohn.Forte@Sun.COM } else {
36377836SJohn.Forte@Sun.COM
36387836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
36397836SJohn.Forte@Sun.COM /*
36407836SJohn.Forte@Sun.COM * If the oid does represent a session check to see
36417836SJohn.Forte@Sun.COM * if it is a target oid. If so, return the target's
36427836SJohn.Forte@Sun.COM * associated session.
36437836SJohn.Forte@Sun.COM */
36447836SJohn.Forte@Sun.COM rtn = iscsi_sess_get(auth->a_oid, ihp, &isp);
36457836SJohn.Forte@Sun.COM if (rtn != 0) {
36467836SJohn.Forte@Sun.COM rtn = iscsi_sess_get_by_target(auth->a_oid,
36477836SJohn.Forte@Sun.COM ihp, &isp);
36487836SJohn.Forte@Sun.COM }
36497836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
36507836SJohn.Forte@Sun.COM
36517836SJohn.Forte@Sun.COM /*
36527836SJohn.Forte@Sun.COM * If rtn is zero then we have found an
36537836SJohn.Forte@Sun.COM * existing session. Use the session name to
36547836SJohn.Forte@Sun.COM * do param lookup. If rtn is non-zero then
36557836SJohn.Forte@Sun.COM * create a targetparam object and use its name
36567836SJohn.Forte@Sun.COM * for param lookup.
36577836SJohn.Forte@Sun.COM */
36587836SJohn.Forte@Sun.COM if (rtn == 0) {
36597836SJohn.Forte@Sun.COM name = isp->sess_name;
36607836SJohn.Forte@Sun.COM } else {
36617836SJohn.Forte@Sun.COM name =
36627836SJohn.Forte@Sun.COM iscsi_targetparam_get_name(auth->a_oid);
36637836SJohn.Forte@Sun.COM }
36647836SJohn.Forte@Sun.COM }
36657836SJohn.Forte@Sun.COM
36667836SJohn.Forte@Sun.COM if (name == NULL) {
36677836SJohn.Forte@Sun.COM rtn = EFAULT;
36687836SJohn.Forte@Sun.COM break;
36697836SJohn.Forte@Sun.COM }
36707836SJohn.Forte@Sun.COM
36717836SJohn.Forte@Sun.COM if (persistent_auth_get((char *)name, auth) == B_TRUE) {
36727836SJohn.Forte@Sun.COM /*
36737836SJohn.Forte@Sun.COM * Restore the value for overridden (and bogus) oid.
36747836SJohn.Forte@Sun.COM */
36757836SJohn.Forte@Sun.COM auth->a_oid = old_oid;
36767836SJohn.Forte@Sun.COM rtn = ddi_copyout(auth, (caddr_t)arg,
36777836SJohn.Forte@Sun.COM sizeof (*auth), mode);
36787836SJohn.Forte@Sun.COM } else {
36797836SJohn.Forte@Sun.COM rtn = EIO;
36807836SJohn.Forte@Sun.COM }
36817836SJohn.Forte@Sun.COM
36827836SJohn.Forte@Sun.COM kmem_free(auth, sizeof (*auth));
36837836SJohn.Forte@Sun.COM break;
36847836SJohn.Forte@Sun.COM
36857836SJohn.Forte@Sun.COM /*
36867836SJohn.Forte@Sun.COM * ISCSI_AUTH_SET -
36877836SJohn.Forte@Sun.COM */
36887836SJohn.Forte@Sun.COM case ISCSI_AUTH_SET:
36897836SJohn.Forte@Sun.COM auth = (iscsi_auth_props_t *)kmem_zalloc(sizeof (*auth),
36907836SJohn.Forte@Sun.COM KM_SLEEP);
36917836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, auth, sizeof (*auth), mode)) {
36927836SJohn.Forte@Sun.COM kmem_free(auth, sizeof (*auth));
36937836SJohn.Forte@Sun.COM rtn = EFAULT;
36947836SJohn.Forte@Sun.COM break;
36957836SJohn.Forte@Sun.COM } else if (auth->a_vers != ISCSI_INTERFACE_VERSION) {
36967836SJohn.Forte@Sun.COM kmem_free(auth, sizeof (*auth));
36977836SJohn.Forte@Sun.COM rtn = EINVAL;
36987836SJohn.Forte@Sun.COM break;
36997836SJohn.Forte@Sun.COM }
37007836SJohn.Forte@Sun.COM
37017836SJohn.Forte@Sun.COM if (auth->a_oid == ihp->hba_oid) {
37027836SJohn.Forte@Sun.COM name = ihp->hba_name;
37037836SJohn.Forte@Sun.COM } else {
37047836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
37057836SJohn.Forte@Sun.COM /*
37067836SJohn.Forte@Sun.COM * If the oid does represent a session check to see
37077836SJohn.Forte@Sun.COM * if it is a target oid. If so, return the target's
37087836SJohn.Forte@Sun.COM * associated session.
37097836SJohn.Forte@Sun.COM */
37107836SJohn.Forte@Sun.COM rtn = iscsi_sess_get(auth->a_oid, ihp, &isp);
37117836SJohn.Forte@Sun.COM if (rtn != 0) {
37127836SJohn.Forte@Sun.COM rtn = iscsi_sess_get_by_target(auth->a_oid,
37137836SJohn.Forte@Sun.COM ihp, &isp);
37147836SJohn.Forte@Sun.COM }
37157836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
37167836SJohn.Forte@Sun.COM
37177836SJohn.Forte@Sun.COM /*
37187836SJohn.Forte@Sun.COM * If rtn is zero then we have found an
37197836SJohn.Forte@Sun.COM * existing session. Use the session name to
37207836SJohn.Forte@Sun.COM * do param lookup. If rtn is non-zero then
37217836SJohn.Forte@Sun.COM * create a targetparam object and use its name
37227836SJohn.Forte@Sun.COM * for param lookup.
37237836SJohn.Forte@Sun.COM */
37247836SJohn.Forte@Sun.COM if (rtn == 0) {
37257836SJohn.Forte@Sun.COM name = isp->sess_name;
37267836SJohn.Forte@Sun.COM } else {
37277836SJohn.Forte@Sun.COM name =
37287836SJohn.Forte@Sun.COM iscsi_targetparam_get_name(auth->a_oid);
37297836SJohn.Forte@Sun.COM rtn = 0;
37307836SJohn.Forte@Sun.COM }
37317836SJohn.Forte@Sun.COM }
37327836SJohn.Forte@Sun.COM
37338389SJack.Meng@Sun.COM if (name == NULL) {
37348389SJack.Meng@Sun.COM rtn = EFAULT;
37358389SJack.Meng@Sun.COM } else if (persistent_auth_set((char *)name, auth)
37368389SJack.Meng@Sun.COM == B_FALSE) {
37377836SJohn.Forte@Sun.COM rtn = EIO;
37387836SJohn.Forte@Sun.COM }
37397836SJohn.Forte@Sun.COM
37407836SJohn.Forte@Sun.COM kmem_free(auth, sizeof (*auth));
37417836SJohn.Forte@Sun.COM break;
37427836SJohn.Forte@Sun.COM
37437836SJohn.Forte@Sun.COM /*
37447836SJohn.Forte@Sun.COM * ISCSI_AUTH_CLEAR -
37457836SJohn.Forte@Sun.COM */
37467836SJohn.Forte@Sun.COM case ISCSI_AUTH_CLEAR:
37477836SJohn.Forte@Sun.COM auth = (iscsi_auth_props_t *)kmem_alloc(sizeof (*auth),
37487836SJohn.Forte@Sun.COM KM_SLEEP);
37497836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, auth, sizeof (*auth), mode)) {
37507836SJohn.Forte@Sun.COM kmem_free(auth, sizeof (*auth));
37517836SJohn.Forte@Sun.COM rtn = EFAULT;
37527836SJohn.Forte@Sun.COM break;
37537836SJohn.Forte@Sun.COM } else if (auth->a_vers != ISCSI_INTERFACE_VERSION) {
37547836SJohn.Forte@Sun.COM kmem_free(auth, sizeof (*auth));
37557836SJohn.Forte@Sun.COM rtn = EINVAL;
37567836SJohn.Forte@Sun.COM break;
37577836SJohn.Forte@Sun.COM }
37587836SJohn.Forte@Sun.COM
37597836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
37607836SJohn.Forte@Sun.COM /*
37617836SJohn.Forte@Sun.COM * If the oid does represent a session check to see
37627836SJohn.Forte@Sun.COM * if it is a target oid. If so, return the target's
37637836SJohn.Forte@Sun.COM * associated session.
37647836SJohn.Forte@Sun.COM */
37657836SJohn.Forte@Sun.COM rtn = iscsi_sess_get(auth->a_oid, ihp, &isp);
37667836SJohn.Forte@Sun.COM if (rtn != 0) {
37677836SJohn.Forte@Sun.COM rtn = iscsi_sess_get_by_target(auth->a_oid, ihp, &isp);
37687836SJohn.Forte@Sun.COM }
37697836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
37707836SJohn.Forte@Sun.COM
37717836SJohn.Forte@Sun.COM /*
37727836SJohn.Forte@Sun.COM * If rtn is zero then we have found an
37737836SJohn.Forte@Sun.COM * existing session. Use the session name to
37747836SJohn.Forte@Sun.COM * do param lookup. If rtn is non-zero then
37757836SJohn.Forte@Sun.COM * create a targetparam object and use its name
37767836SJohn.Forte@Sun.COM * for param lookup.
37777836SJohn.Forte@Sun.COM */
37787836SJohn.Forte@Sun.COM if (rtn == 0) {
37797836SJohn.Forte@Sun.COM name = isp->sess_name;
37807836SJohn.Forte@Sun.COM } else {
37817836SJohn.Forte@Sun.COM name =
37827836SJohn.Forte@Sun.COM iscsi_targetparam_get_name(auth->a_oid);
37837836SJohn.Forte@Sun.COM rtn = 0;
37848294SShengliang.Zhang@Sun.COM discovered = B_FALSE;
37857836SJohn.Forte@Sun.COM }
37867836SJohn.Forte@Sun.COM
37877836SJohn.Forte@Sun.COM if (name == NULL) {
37887836SJohn.Forte@Sun.COM rtn = EFAULT;
37897836SJohn.Forte@Sun.COM break;
37907836SJohn.Forte@Sun.COM }
37917836SJohn.Forte@Sun.COM
37927836SJohn.Forte@Sun.COM if (persistent_auth_clear((char *)name) == B_FALSE) {
37937836SJohn.Forte@Sun.COM rtn = EIO;
37947836SJohn.Forte@Sun.COM }
37958294SShengliang.Zhang@Sun.COM
37968294SShengliang.Zhang@Sun.COM /*
37978294SShengliang.Zhang@Sun.COM * ISCSI_TARGET_PARAM_CLEAR, ISCSI_CHAP_CLEAR and
37988294SShengliang.Zhang@Sun.COM * ISCSI_AUTH_CLEAR ioctl are called sequentially to remove
37998294SShengliang.Zhang@Sun.COM * target parameters. Here, the target that is not discovered
38008294SShengliang.Zhang@Sun.COM * by initiator should be removed from the iscsi_targets list
38018294SShengliang.Zhang@Sun.COM * residing in the memory.
38028294SShengliang.Zhang@Sun.COM */
38038294SShengliang.Zhang@Sun.COM if (discovered == B_FALSE) {
38048294SShengliang.Zhang@Sun.COM (void) iscsi_targetparam_remove_target(auth->a_oid);
38058294SShengliang.Zhang@Sun.COM }
38068294SShengliang.Zhang@Sun.COM
38077836SJohn.Forte@Sun.COM kmem_free(auth, sizeof (*auth));
38087836SJohn.Forte@Sun.COM break;
38097836SJohn.Forte@Sun.COM
38107836SJohn.Forte@Sun.COM /*
38117836SJohn.Forte@Sun.COM * ISCSI_DB_DUMP -
38127836SJohn.Forte@Sun.COM */
38137836SJohn.Forte@Sun.COM case ISCSI_DB_DUMP:
38147836SJohn.Forte@Sun.COM persistent_dump_data();
38157836SJohn.Forte@Sun.COM break;
38167836SJohn.Forte@Sun.COM
38177836SJohn.Forte@Sun.COM case ISCSI_USCSI:
38187836SJohn.Forte@Sun.COM
38197836SJohn.Forte@Sun.COM #ifdef _MULTI_DATAMODEL
38207836SJohn.Forte@Sun.COM model = ddi_model_convert_from(mode & FMODELS);
38217836SJohn.Forte@Sun.COM switch (model) {
38227836SJohn.Forte@Sun.COM case DDI_MODEL_ILP32:
38237836SJohn.Forte@Sun.COM
38247836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &iu32_caller,
38257836SJohn.Forte@Sun.COM sizeof (iscsi_uscsi32_t), mode)) {
38267836SJohn.Forte@Sun.COM rtn = EFAULT;
38277836SJohn.Forte@Sun.COM break;
38287836SJohn.Forte@Sun.COM }
38297836SJohn.Forte@Sun.COM
38307836SJohn.Forte@Sun.COM /* perform conversion from 32 -> 64 */
38317836SJohn.Forte@Sun.COM iu_caller.iu_vers = iu32_caller.iu_vers;
38327836SJohn.Forte@Sun.COM iu_caller.iu_oid = iu32_caller.iu_oid;
38337836SJohn.Forte@Sun.COM iu_caller.iu_tpgt = iu32_caller.iu_tpgt;
38347836SJohn.Forte@Sun.COM iu_caller.iu_len = iu32_caller.iu_len;
38357836SJohn.Forte@Sun.COM iu_caller.iu_lun = iu32_caller.iu_lun;
38367836SJohn.Forte@Sun.COM uscsi_cmd32touscsi_cmd((&iu32_caller.iu_ucmd),
38377836SJohn.Forte@Sun.COM (&iu_caller.iu_ucmd));
38387836SJohn.Forte@Sun.COM
38397836SJohn.Forte@Sun.COM break;
38407836SJohn.Forte@Sun.COM case DDI_MODEL_NONE:
38417836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &iu_caller,
38427836SJohn.Forte@Sun.COM sizeof (iscsi_uscsi_t), mode)) {
38437836SJohn.Forte@Sun.COM rtn = EFAULT;
38447836SJohn.Forte@Sun.COM break;
38457836SJohn.Forte@Sun.COM }
38467836SJohn.Forte@Sun.COM break;
38477836SJohn.Forte@Sun.COM default:
38487836SJohn.Forte@Sun.COM ASSERT(FALSE);
38497836SJohn.Forte@Sun.COM rtn = EINVAL;
38507836SJohn.Forte@Sun.COM break;
38517836SJohn.Forte@Sun.COM }
38527836SJohn.Forte@Sun.COM #endif /* _MULTI_DATAMODEL */
38537836SJohn.Forte@Sun.COM
38547836SJohn.Forte@Sun.COM /* If failures earlier break */
38557836SJohn.Forte@Sun.COM if (rtn != 0) {
38567836SJohn.Forte@Sun.COM break;
38577836SJohn.Forte@Sun.COM }
38587836SJohn.Forte@Sun.COM
38597836SJohn.Forte@Sun.COM /* copy from caller to internel cmd */
38607836SJohn.Forte@Sun.COM bcopy(&iu_caller, &iu, sizeof (iu));
38617836SJohn.Forte@Sun.COM
38627836SJohn.Forte@Sun.COM if (iu.iu_vers != ISCSI_INTERFACE_VERSION) {
38637836SJohn.Forte@Sun.COM rtn = EINVAL;
38647836SJohn.Forte@Sun.COM break;
38657836SJohn.Forte@Sun.COM }
38667836SJohn.Forte@Sun.COM /*
38677836SJohn.Forte@Sun.COM * Check to see if oid references a target-param oid. If so,
38687836SJohn.Forte@Sun.COM * find the associated session oid before getting lu list.
38697836SJohn.Forte@Sun.COM */
38707836SJohn.Forte@Sun.COM if (iscsi_targetparam_get_name(iu.iu_oid) != NULL) {
38717836SJohn.Forte@Sun.COM for (isp = ihp->hba_sess_list; isp; isp =
38727836SJohn.Forte@Sun.COM isp->sess_next) {
38737836SJohn.Forte@Sun.COM if (isp->sess_target_oid == iu.iu_oid) {
38747836SJohn.Forte@Sun.COM target_oid = isp->sess_oid;
38757836SJohn.Forte@Sun.COM break;
38767836SJohn.Forte@Sun.COM }
38777836SJohn.Forte@Sun.COM }
38787836SJohn.Forte@Sun.COM } else {
38797836SJohn.Forte@Sun.COM target_oid = iu.iu_oid;
38807836SJohn.Forte@Sun.COM }
38817836SJohn.Forte@Sun.COM
38827836SJohn.Forte@Sun.COM /* make sure we have a matching session for this command */
38837836SJohn.Forte@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
38847836SJohn.Forte@Sun.COM rtn = iscsi_sess_get(target_oid, ihp, &isp);
38857836SJohn.Forte@Sun.COM if (rtn != 0) {
38867836SJohn.Forte@Sun.COM rtn = iscsi_sess_get_by_target(target_oid, ihp,
38877836SJohn.Forte@Sun.COM &isp);
38887836SJohn.Forte@Sun.COM if (rtn != 0) {
38897836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
38907836SJohn.Forte@Sun.COM rtn = EFAULT;
38917836SJohn.Forte@Sun.COM break;
38927836SJohn.Forte@Sun.COM }
38937836SJohn.Forte@Sun.COM }
38947836SJohn.Forte@Sun.COM /*
38957836SJohn.Forte@Sun.COM * If a caller buffer is present allocate duplicate
38967836SJohn.Forte@Sun.COM * kernel space and copyin caller memory.
38977836SJohn.Forte@Sun.COM */
38987836SJohn.Forte@Sun.COM if (iu.iu_ucmd.uscsi_buflen > 0) {
38997836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_bufaddr = (caddr_t)kmem_alloc(
39007836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_buflen, KM_SLEEP);
39017836SJohn.Forte@Sun.COM if (ddi_copyin(iu_caller.iu_ucmd.uscsi_bufaddr,
39027836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_bufaddr,
39037836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_buflen, mode)) {
39047836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
39057836SJohn.Forte@Sun.COM rtn = EFAULT;
39067836SJohn.Forte@Sun.COM break;
39077836SJohn.Forte@Sun.COM }
39087836SJohn.Forte@Sun.COM }
39097836SJohn.Forte@Sun.COM
39107836SJohn.Forte@Sun.COM /*
39117836SJohn.Forte@Sun.COM * If a caller cdb is present allocate duplicate
39127836SJohn.Forte@Sun.COM * kernel space and copyin caller memory.
39137836SJohn.Forte@Sun.COM */
39147836SJohn.Forte@Sun.COM if (iu.iu_ucmd.uscsi_cdblen > 0) {
39157836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_cdb = (caddr_t)kmem_alloc(
39167836SJohn.Forte@Sun.COM iu_caller.iu_ucmd.uscsi_cdblen, KM_SLEEP);
39177836SJohn.Forte@Sun.COM if (ddi_copyin(iu_caller.iu_ucmd.uscsi_cdb,
39187836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_cdb,
39197836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_cdblen, mode)) {
39207836SJohn.Forte@Sun.COM if (iu.iu_ucmd.uscsi_buflen > 0) {
39217836SJohn.Forte@Sun.COM kmem_free(iu.iu_ucmd.uscsi_bufaddr,
39227836SJohn.Forte@Sun.COM iu_caller.iu_ucmd.uscsi_buflen);
39237836SJohn.Forte@Sun.COM }
39247836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
39257836SJohn.Forte@Sun.COM rtn = EFAULT;
39267836SJohn.Forte@Sun.COM break;
39277836SJohn.Forte@Sun.COM }
39287836SJohn.Forte@Sun.COM }
39297836SJohn.Forte@Sun.COM
39307836SJohn.Forte@Sun.COM /*
39317836SJohn.Forte@Sun.COM * If a caller request sense is present allocate
39327836SJohn.Forte@Sun.COM * duplicate kernel space. No need to copyin.
39337836SJohn.Forte@Sun.COM */
39347836SJohn.Forte@Sun.COM if (iu.iu_ucmd.uscsi_rqlen > 0) {
39357836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_rqbuf = (caddr_t)kmem_alloc(
39367836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_rqlen, KM_SLEEP);
39377836SJohn.Forte@Sun.COM }
39387836SJohn.Forte@Sun.COM
39397836SJohn.Forte@Sun.COM /* issue passthru to io path handler */
39407836SJohn.Forte@Sun.COM rtn = iscsi_handle_passthru(isp, iu.iu_lun, &iu.iu_ucmd);
39417836SJohn.Forte@Sun.COM if (rtn != 0) {
39427836SJohn.Forte@Sun.COM rtn = EFAULT;
39437836SJohn.Forte@Sun.COM }
39447836SJohn.Forte@Sun.COM
39457836SJohn.Forte@Sun.COM /*
39467836SJohn.Forte@Sun.COM * If the caller had a buf we need to do a copyout
39477836SJohn.Forte@Sun.COM * and free the kernel memory
39487836SJohn.Forte@Sun.COM */
39497836SJohn.Forte@Sun.COM if (iu.iu_ucmd.uscsi_buflen > 0) {
39507836SJohn.Forte@Sun.COM if (ddi_copyout(iu.iu_ucmd.uscsi_bufaddr,
39517836SJohn.Forte@Sun.COM iu_caller.iu_ucmd.uscsi_bufaddr,
39527836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_buflen, mode) != 0) {
39537836SJohn.Forte@Sun.COM rtn = EFAULT;
39547836SJohn.Forte@Sun.COM }
39557836SJohn.Forte@Sun.COM kmem_free(iu.iu_ucmd.uscsi_bufaddr,
39567836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_buflen);
39577836SJohn.Forte@Sun.COM }
39587836SJohn.Forte@Sun.COM
39597836SJohn.Forte@Sun.COM /* We need to free kernel cdb, no need to copyout */
39607836SJohn.Forte@Sun.COM if (iu.iu_ucmd.uscsi_cdblen > 0) {
39617836SJohn.Forte@Sun.COM kmem_free(iu.iu_ucmd.uscsi_cdb,
39627836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_cdblen);
39637836SJohn.Forte@Sun.COM }
39647836SJohn.Forte@Sun.COM
39657836SJohn.Forte@Sun.COM /*
39667836SJohn.Forte@Sun.COM * If the caller had a request sense we need to
39677836SJohn.Forte@Sun.COM * do a copyout and free the kernel memory
39687836SJohn.Forte@Sun.COM */
39697836SJohn.Forte@Sun.COM if (iu.iu_ucmd.uscsi_rqlen > 0) {
39707836SJohn.Forte@Sun.COM if (ddi_copyout(iu.iu_ucmd.uscsi_rqbuf,
39717836SJohn.Forte@Sun.COM iu_caller.iu_ucmd.uscsi_rqbuf,
397211271SMilos.Muzik@Sun.COM iu.iu_ucmd.uscsi_rqlen - iu.iu_ucmd.uscsi_rqresid,
397311271SMilos.Muzik@Sun.COM mode) != 0) {
39747836SJohn.Forte@Sun.COM rtn = EFAULT;
39757836SJohn.Forte@Sun.COM }
39767836SJohn.Forte@Sun.COM kmem_free(iu.iu_ucmd.uscsi_rqbuf,
39777836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_rqlen);
39787836SJohn.Forte@Sun.COM }
39797836SJohn.Forte@Sun.COM
39807836SJohn.Forte@Sun.COM #ifdef _MULTI_DATAMODEL
398111271SMilos.Muzik@Sun.COM switch (model = ddi_model_convert_from(mode & FMODELS)) {
398211271SMilos.Muzik@Sun.COM case DDI_MODEL_ILP32:
398311271SMilos.Muzik@Sun.COM if (iu.iu_ucmd.uscsi_status != 0) {
39847836SJohn.Forte@Sun.COM iu32_caller.iu_ucmd.uscsi_status =
39857836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_status;
398611271SMilos.Muzik@Sun.COM iu32_caller.iu_ucmd.uscsi_rqresid =
398711271SMilos.Muzik@Sun.COM iu.iu_ucmd.uscsi_rqresid;
398811271SMilos.Muzik@Sun.COM }
398911271SMilos.Muzik@Sun.COM iu32_caller.iu_ucmd.uscsi_resid =
399011271SMilos.Muzik@Sun.COM iu.iu_ucmd.uscsi_resid;
399111271SMilos.Muzik@Sun.COM if (ddi_copyout((void *)&iu32_caller, (caddr_t)arg,
399211271SMilos.Muzik@Sun.COM sizeof (iscsi_uscsi32_t), mode) != 0) {
399311271SMilos.Muzik@Sun.COM rtn = EFAULT;
399411271SMilos.Muzik@Sun.COM }
399511271SMilos.Muzik@Sun.COM break;
399611271SMilos.Muzik@Sun.COM case DDI_MODEL_NONE:
399711271SMilos.Muzik@Sun.COM if (iu.iu_ucmd.uscsi_status != 0) {
39987836SJohn.Forte@Sun.COM iu_caller.iu_ucmd.uscsi_status =
39997836SJohn.Forte@Sun.COM iu.iu_ucmd.uscsi_status;
400011271SMilos.Muzik@Sun.COM iu_caller.iu_ucmd.uscsi_rqresid =
400111271SMilos.Muzik@Sun.COM iu.iu_ucmd.uscsi_rqresid;
40027836SJohn.Forte@Sun.COM }
400311271SMilos.Muzik@Sun.COM iu_caller.iu_ucmd.uscsi_resid = iu.iu_ucmd.uscsi_resid;
400411271SMilos.Muzik@Sun.COM if (ddi_copyout((void *)&iu_caller, (caddr_t)arg,
400511271SMilos.Muzik@Sun.COM sizeof (iscsi_uscsi_t), mode) != 0) {
400611271SMilos.Muzik@Sun.COM rtn = EFAULT;
400711271SMilos.Muzik@Sun.COM }
400811271SMilos.Muzik@Sun.COM break;
400911271SMilos.Muzik@Sun.COM default:
401011271SMilos.Muzik@Sun.COM ASSERT(FALSE);
40117836SJohn.Forte@Sun.COM }
40127836SJohn.Forte@Sun.COM #endif /* _MULTI_DATAMODEL */
40137836SJohn.Forte@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
40147836SJohn.Forte@Sun.COM break;
40157836SJohn.Forte@Sun.COM
40169201SJack.Meng@Sun.COM case ISCSI_SMF_ONLINE:
40177836SJohn.Forte@Sun.COM if (ddi_copyin((caddr_t)arg, &did, sizeof (int), mode) != 0) {
40187836SJohn.Forte@Sun.COM rtn = EFAULT;
40199201SJack.Meng@Sun.COM break;
40209201SJack.Meng@Sun.COM }
40219201SJack.Meng@Sun.COM /* just a theoretical case */
40229201SJack.Meng@Sun.COM if (ihp->hba_persistent_loaded == B_FALSE) {
40239201SJack.Meng@Sun.COM rtn = EFAULT;
40249201SJack.Meng@Sun.COM break;
40259201SJack.Meng@Sun.COM }
40269201SJack.Meng@Sun.COM
402710185SJack.Meng@Sun.COM /* doesn't need to overwrite the status anymore */
402810185SJack.Meng@Sun.COM mutex_enter(&ihp->hba_service_lock);
402910185SJack.Meng@Sun.COM if (ihp->hba_service_status_overwrite == B_TRUE) {
403010185SJack.Meng@Sun.COM ihp->hba_service_status = ISCSI_SERVICE_DISABLED;
403110185SJack.Meng@Sun.COM ihp->hba_service_status_overwrite = B_FALSE;
403210185SJack.Meng@Sun.COM }
403310185SJack.Meng@Sun.COM mutex_exit(&ihp->hba_service_lock);
403410185SJack.Meng@Sun.COM
40359201SJack.Meng@Sun.COM if (iscsi_enter_service_zone(ihp, ISCSI_SERVICE_ENABLED) ==
40369201SJack.Meng@Sun.COM B_FALSE) {
40379201SJack.Meng@Sun.COM break;
40389201SJack.Meng@Sun.COM }
40399201SJack.Meng@Sun.COM
40409201SJack.Meng@Sun.COM rval = iscsi_door_bind(did);
40419201SJack.Meng@Sun.COM if (rval == B_TRUE) {
40429201SJack.Meng@Sun.COM rval = iscsid_start(ihp);
40439201SJack.Meng@Sun.COM if (rval == B_FALSE) {
40449201SJack.Meng@Sun.COM iscsi_door_unbind();
40459201SJack.Meng@Sun.COM }
40469201SJack.Meng@Sun.COM }
40479201SJack.Meng@Sun.COM
40489201SJack.Meng@Sun.COM if (rval == B_TRUE) {
40499201SJack.Meng@Sun.COM iscsi_exit_service_zone(ihp, ISCSI_SERVICE_ENABLED);
40509201SJack.Meng@Sun.COM } else {
40519201SJack.Meng@Sun.COM iscsi_exit_service_zone(ihp, ISCSI_SERVICE_DISABLED);
40527836SJohn.Forte@Sun.COM rtn = EFAULT;
40537836SJohn.Forte@Sun.COM }
40549201SJack.Meng@Sun.COM
40559201SJack.Meng@Sun.COM break;
40569201SJack.Meng@Sun.COM
40579201SJack.Meng@Sun.COM case ISCSI_SMF_OFFLINE:
40589201SJack.Meng@Sun.COM if (iscsi_enter_service_zone(ihp, ISCSI_SERVICE_DISABLED)
40599201SJack.Meng@Sun.COM == B_FALSE) {
40609201SJack.Meng@Sun.COM break;
40619201SJack.Meng@Sun.COM }
40629201SJack.Meng@Sun.COM
40639201SJack.Meng@Sun.COM rval = iscsid_stop(ihp);
406411730SJack.Meng@Sun.COM iscsi_door_unbind();
406511730SJack.Meng@Sun.COM
406611730SJack.Meng@Sun.COM iscsi_exit_service_zone(ihp, ISCSI_SERVICE_DISABLED);
406711730SJack.Meng@Sun.COM
406811730SJack.Meng@Sun.COM if (ddi_copyout((void *)&rval, (caddr_t)arg,
406911730SJack.Meng@Sun.COM sizeof (boolean_t), mode) != 0) {
40709201SJack.Meng@Sun.COM rtn = EFAULT;
40719201SJack.Meng@Sun.COM }
407211730SJack.Meng@Sun.COM
40739201SJack.Meng@Sun.COM break;
40749201SJack.Meng@Sun.COM
40759201SJack.Meng@Sun.COM case ISCSI_SMF_GET:
40769201SJack.Meng@Sun.COM mutex_enter(&ihp->hba_service_lock);
40779201SJack.Meng@Sun.COM while (ihp->hba_service_status ==
40789201SJack.Meng@Sun.COM ISCSI_SERVICE_TRANSITION) {
40799201SJack.Meng@Sun.COM cv_wait(&ihp->hba_service_cv,
40809201SJack.Meng@Sun.COM &ihp->hba_service_lock);
40819201SJack.Meng@Sun.COM }
40829201SJack.Meng@Sun.COM if (ddi_copyout((void *)&ihp->hba_service_status,
40839201SJack.Meng@Sun.COM (caddr_t)arg, sizeof (boolean_t), mode) != 0) {
40849201SJack.Meng@Sun.COM rtn = EFAULT;
40859201SJack.Meng@Sun.COM }
40869201SJack.Meng@Sun.COM mutex_exit(&ihp->hba_service_lock);
40877836SJohn.Forte@Sun.COM break;
40887836SJohn.Forte@Sun.COM
40897836SJohn.Forte@Sun.COM case ISCSI_DISCOVERY_EVENTS:
40907836SJohn.Forte@Sun.COM /*
40917836SJohn.Forte@Sun.COM * If discovery has not been completed and not in progress,
40927836SJohn.Forte@Sun.COM * poke the discovery methods
40937836SJohn.Forte@Sun.COM */
40947836SJohn.Forte@Sun.COM mutex_enter(&ihp->hba_discovery_events_mutex);
40957836SJohn.Forte@Sun.COM method = ihp->hba_discovery_events;
40967836SJohn.Forte@Sun.COM if ((method != ISCSI_ALL_DISCOVERY_METHODS) &&
40977836SJohn.Forte@Sun.COM (ihp->hba_discovery_in_progress == B_FALSE)) {
40987836SJohn.Forte@Sun.COM ihp->hba_discovery_in_progress = B_TRUE;
40997836SJohn.Forte@Sun.COM mutex_exit(&ihp->hba_discovery_events_mutex);
41007836SJohn.Forte@Sun.COM iscsid_poke_discovery(ihp, iSCSIDiscoveryMethodUnknown);
41017836SJohn.Forte@Sun.COM mutex_enter(&ihp->hba_discovery_events_mutex);
41027836SJohn.Forte@Sun.COM ihp->hba_discovery_in_progress = B_FALSE;
41037836SJohn.Forte@Sun.COM method = ihp->hba_discovery_events;
41047836SJohn.Forte@Sun.COM }
41057836SJohn.Forte@Sun.COM mutex_exit(&ihp->hba_discovery_events_mutex);
41067836SJohn.Forte@Sun.COM
41077836SJohn.Forte@Sun.COM if (ddi_copyout((void *)&method, (caddr_t)arg,
41087836SJohn.Forte@Sun.COM sizeof (method), mode) != 0)
41097836SJohn.Forte@Sun.COM rtn = EFAULT;
41107836SJohn.Forte@Sun.COM break;
41117836SJohn.Forte@Sun.COM
41127836SJohn.Forte@Sun.COM /*
41137836SJohn.Forte@Sun.COM * ISCSI_SENDTGTS_GET --
41147836SJohn.Forte@Sun.COM */
41157836SJohn.Forte@Sun.COM case ISCSI_SENDTGTS_GET:
41167836SJohn.Forte@Sun.COM stl_hdr = iscsi_ioctl_copyin((caddr_t)arg, mode,
41177836SJohn.Forte@Sun.COM sizeof (*stl_hdr));
41187836SJohn.Forte@Sun.COM if (stl_hdr == NULL) {
41197836SJohn.Forte@Sun.COM rtn = EFAULT;
41207836SJohn.Forte@Sun.COM break;
41217836SJohn.Forte@Sun.COM }
41227836SJohn.Forte@Sun.COM
41237836SJohn.Forte@Sun.COM if (stl_hdr->stl_entry.e_vers != ISCSI_INTERFACE_VERSION) {
41247836SJohn.Forte@Sun.COM rtn = EINVAL;
41257836SJohn.Forte@Sun.COM kmem_free(stl_hdr, sizeof (*stl_hdr));
41267836SJohn.Forte@Sun.COM break;
41277836SJohn.Forte@Sun.COM }
41287836SJohn.Forte@Sun.COM
41297836SJohn.Forte@Sun.COM /* calculate how much memory user allocated for SendTgts */
41307836SJohn.Forte@Sun.COM stl_sz = sizeof (*stl_hdr);
41317836SJohn.Forte@Sun.COM if (stl_hdr->stl_in_cnt > 0) {
41327836SJohn.Forte@Sun.COM stl_sz += ((stl_hdr->stl_in_cnt - 1) *
41337836SJohn.Forte@Sun.COM sizeof (iscsi_sendtgts_entry_t));
41347836SJohn.Forte@Sun.COM }
41357836SJohn.Forte@Sun.COM
41367836SJohn.Forte@Sun.COM /* allocate local SendTgts list of the same size */
41377836SJohn.Forte@Sun.COM istl = kmem_zalloc(stl_sz, KM_SLEEP);
41387836SJohn.Forte@Sun.COM bcopy(stl_hdr, istl, sizeof (*stl_hdr));
41397836SJohn.Forte@Sun.COM kmem_free(stl_hdr, sizeof (*stl_hdr));
41407836SJohn.Forte@Sun.COM
41417836SJohn.Forte@Sun.COM /* lock interface so only one SendTargets operation occurs */
41427836SJohn.Forte@Sun.COM sema_p(&ihp->hba_sendtgts_semaphore);
41437836SJohn.Forte@Sun.COM
41447836SJohn.Forte@Sun.COM rtn = iscsi_ioctl_sendtgts_get(ihp, istl);
41457836SJohn.Forte@Sun.COM
41467836SJohn.Forte@Sun.COM if (rtn == 0) {
41477836SJohn.Forte@Sun.COM rtn = iscsi_ioctl_copyout(istl, stl_sz,
41487836SJohn.Forte@Sun.COM (caddr_t)arg, mode);
41497836SJohn.Forte@Sun.COM }
41507836SJohn.Forte@Sun.COM
41517836SJohn.Forte@Sun.COM /* release lock to allow another SendTargets discovery */
41527836SJohn.Forte@Sun.COM sema_v(&ihp->hba_sendtgts_semaphore);
41537836SJohn.Forte@Sun.COM
41547836SJohn.Forte@Sun.COM break;
41557836SJohn.Forte@Sun.COM
41567836SJohn.Forte@Sun.COM /*
41577836SJohn.Forte@Sun.COM * ISCSI_ISNS_SERVER_GET --
41587836SJohn.Forte@Sun.COM */
41597836SJohn.Forte@Sun.COM case ISCSI_ISNS_SERVER_GET:
41607836SJohn.Forte@Sun.COM server_pg_list_hdr = iscsi_ioctl_copyin((caddr_t)arg, mode,
41617836SJohn.Forte@Sun.COM sizeof (*server_pg_list_hdr));
41627836SJohn.Forte@Sun.COM if (server_pg_list_hdr == NULL) {
41637836SJohn.Forte@Sun.COM rtn = EFAULT;
41647836SJohn.Forte@Sun.COM break;
41657836SJohn.Forte@Sun.COM }
41667836SJohn.Forte@Sun.COM
41677836SJohn.Forte@Sun.COM /* If iSNS discovery mode is not set, return with zero entry */
41687836SJohn.Forte@Sun.COM method = persistent_disc_meth_get();
41697836SJohn.Forte@Sun.COM if ((method & iSCSIDiscoveryMethodISNS) == 0) {
41708426SShengliang.Zhang@Sun.COM kmem_free(server_pg_list_hdr,
41718426SShengliang.Zhang@Sun.COM sizeof (*server_pg_list_hdr));
41728426SShengliang.Zhang@Sun.COM server_pg_list_hdr = NULL;
41737836SJohn.Forte@Sun.COM rtn = EACCES;
41747836SJohn.Forte@Sun.COM break;
41757836SJohn.Forte@Sun.COM }
41767836SJohn.Forte@Sun.COM
41777836SJohn.Forte@Sun.COM initiator_node_name = kmem_zalloc(ISCSI_MAX_NAME_LEN, KM_SLEEP);
41787836SJohn.Forte@Sun.COM if (persistent_initiator_name_get(initiator_node_name,
41797836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN) != B_TRUE) {
41807836SJohn.Forte@Sun.COM kmem_free(initiator_node_name, ISCSI_MAX_NAME_LEN);
41817836SJohn.Forte@Sun.COM initiator_node_name = NULL;
41827836SJohn.Forte@Sun.COM kmem_free(server_pg_list_hdr,
41837836SJohn.Forte@Sun.COM sizeof (*server_pg_list_hdr));
41848426SShengliang.Zhang@Sun.COM server_pg_list_hdr = NULL;
41857836SJohn.Forte@Sun.COM rtn = EIO;
41867836SJohn.Forte@Sun.COM break;
41877836SJohn.Forte@Sun.COM }
41887836SJohn.Forte@Sun.COM if (strlen(initiator_node_name) == 0) {
41897836SJohn.Forte@Sun.COM kmem_free(initiator_node_name, ISCSI_MAX_NAME_LEN);
41907836SJohn.Forte@Sun.COM initiator_node_name = NULL;
41917836SJohn.Forte@Sun.COM kmem_free(server_pg_list_hdr,
41927836SJohn.Forte@Sun.COM sizeof (*server_pg_list_hdr));
41938426SShengliang.Zhang@Sun.COM server_pg_list_hdr = NULL;
41947836SJohn.Forte@Sun.COM rtn = EIO;
41957836SJohn.Forte@Sun.COM break;
41967836SJohn.Forte@Sun.COM }
41977836SJohn.Forte@Sun.COM
41987836SJohn.Forte@Sun.COM initiator_node_alias = kmem_zalloc(
41997836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN, KM_SLEEP);
42007836SJohn.Forte@Sun.COM if (persistent_alias_name_get(initiator_node_alias,
42017836SJohn.Forte@Sun.COM ISCSI_MAX_NAME_LEN) != B_TRUE) {
42027836SJohn.Forte@Sun.COM initiator_node_alias[0] = '\0';
42037836SJohn.Forte@Sun.COM }
42047836SJohn.Forte@Sun.COM rtn = isns_query_one_server(&(server_pg_list_hdr->addr),
42057836SJohn.Forte@Sun.COM ihp->hba_isid,
42067836SJohn.Forte@Sun.COM (uint8_t *)initiator_node_name,
42077836SJohn.Forte@Sun.COM (uint8_t *)initiator_node_alias,
42087836SJohn.Forte@Sun.COM ISNS_INITIATOR_NODE_TYPE,
42097836SJohn.Forte@Sun.COM &pg_list);
42107836SJohn.Forte@Sun.COM if (rtn != isns_ok || pg_list == NULL) {
42117836SJohn.Forte@Sun.COM kmem_free(initiator_node_name, ISCSI_MAX_NAME_LEN);
42127836SJohn.Forte@Sun.COM initiator_node_name = NULL;
42137836SJohn.Forte@Sun.COM kmem_free(initiator_node_alias, ISCSI_MAX_NAME_LEN);
42147836SJohn.Forte@Sun.COM initiator_node_alias = NULL;
42157836SJohn.Forte@Sun.COM kmem_free(server_pg_list_hdr,
42167836SJohn.Forte@Sun.COM sizeof (*server_pg_list_hdr));
42177836SJohn.Forte@Sun.COM server_pg_list_hdr = NULL;
42187836SJohn.Forte@Sun.COM rtn = EIO;
42197836SJohn.Forte@Sun.COM break;
42207836SJohn.Forte@Sun.COM }
42217836SJohn.Forte@Sun.COM
42227836SJohn.Forte@Sun.COM /*
42237836SJohn.Forte@Sun.COM * pg_list_sz is the size of the pg_list returned from the
42247836SJohn.Forte@Sun.COM * isns_query_all
42257836SJohn.Forte@Sun.COM *
42267836SJohn.Forte@Sun.COM * pg_sz_copy_out is the size of the pg_list we are going to
42277836SJohn.Forte@Sun.COM * return back to the caller
42287836SJohn.Forte@Sun.COM *
42297836SJohn.Forte@Sun.COM * server_pg_list_sz is total amount of data we are returning
42307836SJohn.Forte@Sun.COM * back to the caller
42317836SJohn.Forte@Sun.COM */
42327836SJohn.Forte@Sun.COM pg_list->pg_in_cnt =
42337836SJohn.Forte@Sun.COM server_pg_list_hdr->addr_port_list.pg_in_cnt;
42347836SJohn.Forte@Sun.COM pg_list_sz = sizeof (isns_portal_group_list_t);
42357836SJohn.Forte@Sun.COM if (pg_list->pg_out_cnt > 0) {
42367836SJohn.Forte@Sun.COM pg_list_sz += (pg_list->pg_out_cnt - 1) *
42377836SJohn.Forte@Sun.COM sizeof (isns_portal_group_t);
42387836SJohn.Forte@Sun.COM }
42397836SJohn.Forte@Sun.COM /*
42407836SJohn.Forte@Sun.COM * check if caller passed in a buffer with enough space
42417836SJohn.Forte@Sun.COM * if there isn't enough space, fill the caller's buffer with
42427836SJohn.Forte@Sun.COM * as much information as possible.
42437836SJohn.Forte@Sun.COM *
42447836SJohn.Forte@Sun.COM * if pg_out_cnt > pg_in_cnt, pg_out_cnt will be returned with
42457836SJohn.Forte@Sun.COM * the total number of targets found
42467836SJohn.Forte@Sun.COM *
42477836SJohn.Forte@Sun.COM * if pg_out_cnt < pg_in_cnt, pg_out_cnt will be the number
42487836SJohn.Forte@Sun.COM * of targets returned
42497836SJohn.Forte@Sun.COM */
42507836SJohn.Forte@Sun.COM if (pg_list->pg_in_cnt < pg_list->pg_out_cnt) {
42517836SJohn.Forte@Sun.COM pg_sz_copy_out = sizeof (isns_portal_group_list_t);
42527836SJohn.Forte@Sun.COM if (pg_list->pg_in_cnt > 0) {
42537836SJohn.Forte@Sun.COM pg_sz_copy_out += (pg_list->pg_in_cnt - 1) *
42547836SJohn.Forte@Sun.COM sizeof (isns_portal_group_t);
42557836SJohn.Forte@Sun.COM }
42567836SJohn.Forte@Sun.COM server_pg_list_sz =
42577836SJohn.Forte@Sun.COM sizeof (isns_server_portal_group_list_t);
42587836SJohn.Forte@Sun.COM if (pg_list->pg_in_cnt > 0) {
42597836SJohn.Forte@Sun.COM server_pg_list_sz += (pg_list->pg_in_cnt - 1) *
42607836SJohn.Forte@Sun.COM sizeof (isns_portal_group_t);
42617836SJohn.Forte@Sun.COM }
42627836SJohn.Forte@Sun.COM } else {
42637836SJohn.Forte@Sun.COM pg_sz_copy_out = pg_list_sz;
42647836SJohn.Forte@Sun.COM server_pg_list_sz =
42657836SJohn.Forte@Sun.COM sizeof (isns_server_portal_group_list_t);
42667836SJohn.Forte@Sun.COM if (pg_list->pg_out_cnt > 0) {
42677836SJohn.Forte@Sun.COM server_pg_list_sz += (pg_list->pg_out_cnt - 1) *
42687836SJohn.Forte@Sun.COM sizeof (isns_portal_group_t);
42697836SJohn.Forte@Sun.COM }
42707836SJohn.Forte@Sun.COM }
42717836SJohn.Forte@Sun.COM
42727836SJohn.Forte@Sun.COM server_pg_list = (isns_server_portal_group_list_t *)kmem_zalloc(
42737836SJohn.Forte@Sun.COM server_pg_list_sz, KM_SLEEP);
42747836SJohn.Forte@Sun.COM
42757836SJohn.Forte@Sun.COM bcopy(&(server_pg_list_hdr->addr), &(server_pg_list->addr),
42767836SJohn.Forte@Sun.COM sizeof (server_pg_list->addr));
42777836SJohn.Forte@Sun.COM bcopy(pg_list, &server_pg_list->addr_port_list, pg_sz_copy_out);
42787836SJohn.Forte@Sun.COM
42797836SJohn.Forte@Sun.COM if (ddi_copyout(server_pg_list, (caddr_t)arg, server_pg_list_sz,
42807836SJohn.Forte@Sun.COM mode) != 0) {
42817836SJohn.Forte@Sun.COM rtn = EFAULT;
42827836SJohn.Forte@Sun.COM }
42837836SJohn.Forte@Sun.COM DTRACE_PROBE1(iscsi_ioctl_iscsi_isns_server_get_pg_sz,
42847836SJohn.Forte@Sun.COM int, pg_list_sz);
42858426SShengliang.Zhang@Sun.COM kmem_free(initiator_node_name, ISCSI_MAX_NAME_LEN);
42868426SShengliang.Zhang@Sun.COM initiator_node_name = NULL;
42878426SShengliang.Zhang@Sun.COM kmem_free(initiator_node_alias, ISCSI_MAX_NAME_LEN);
42888426SShengliang.Zhang@Sun.COM initiator_node_alias = NULL;
42897836SJohn.Forte@Sun.COM kmem_free(pg_list, pg_list_sz);
42908426SShengliang.Zhang@Sun.COM pg_list = NULL;
42917836SJohn.Forte@Sun.COM kmem_free(server_pg_list, server_pg_list_sz);
42928426SShengliang.Zhang@Sun.COM server_pg_list = NULL;
42937836SJohn.Forte@Sun.COM kmem_free(server_pg_list_hdr, sizeof (*server_pg_list_hdr));
42948426SShengliang.Zhang@Sun.COM server_pg_list_hdr = NULL;
42957836SJohn.Forte@Sun.COM break;
42967836SJohn.Forte@Sun.COM
42977836SJohn.Forte@Sun.COM /*
42987836SJohn.Forte@Sun.COM * ISCSI_GET_CONFIG_SESSIONS --
42997836SJohn.Forte@Sun.COM */
43007836SJohn.Forte@Sun.COM case ISCSI_GET_CONFIG_SESSIONS:
43017836SJohn.Forte@Sun.COM /* FALLTHRU */
43027836SJohn.Forte@Sun.COM
43037836SJohn.Forte@Sun.COM case ISCSI_SET_CONFIG_SESSIONS:
43047836SJohn.Forte@Sun.COM size = sizeof (*ics);
43057836SJohn.Forte@Sun.COM ics = iscsi_ioctl_copyin((caddr_t)arg, mode, size);
43067836SJohn.Forte@Sun.COM if (ics == NULL) {
43077836SJohn.Forte@Sun.COM rtn = EFAULT;
43087836SJohn.Forte@Sun.COM break;
43097836SJohn.Forte@Sun.COM }
43107836SJohn.Forte@Sun.COM
43117836SJohn.Forte@Sun.COM /* verify version infomration */
43127836SJohn.Forte@Sun.COM if (ics->ics_ver != ISCSI_INTERFACE_VERSION) {
43137836SJohn.Forte@Sun.COM rtn = EINVAL;
43147836SJohn.Forte@Sun.COM kmem_free(ics, size);
43158426SShengliang.Zhang@Sun.COM ics = NULL;
43167836SJohn.Forte@Sun.COM break;
43177836SJohn.Forte@Sun.COM }
43187836SJohn.Forte@Sun.COM
43197836SJohn.Forte@Sun.COM /* Check to see if we need to copy in more memory */
43207836SJohn.Forte@Sun.COM if (ics->ics_in > 1) {
43217836SJohn.Forte@Sun.COM /* record correct size */
43227836SJohn.Forte@Sun.COM size = ISCSI_SESSION_CONFIG_SIZE(ics->ics_in);
43237836SJohn.Forte@Sun.COM /* free old buffer */
43247836SJohn.Forte@Sun.COM kmem_free(ics, sizeof (*ics));
43257836SJohn.Forte@Sun.COM
43267836SJohn.Forte@Sun.COM /* copy in complete buffer size */
43277836SJohn.Forte@Sun.COM ics = iscsi_ioctl_copyin((caddr_t)arg, mode, size);
43287836SJohn.Forte@Sun.COM if (ics == NULL) {
43297836SJohn.Forte@Sun.COM rtn = EFAULT;
43307836SJohn.Forte@Sun.COM break;
43317836SJohn.Forte@Sun.COM }
43327836SJohn.Forte@Sun.COM }
43337836SJohn.Forte@Sun.COM
43347836SJohn.Forte@Sun.COM /* switch action based on get or set */
43357836SJohn.Forte@Sun.COM if (cmd == ISCSI_GET_CONFIG_SESSIONS) {
43367836SJohn.Forte@Sun.COM /* get */
43377836SJohn.Forte@Sun.COM rtn = iscsi_ioctl_get_config_sess(ihp, ics);
43387836SJohn.Forte@Sun.COM if (rtn == 0) {
43397836SJohn.Forte@Sun.COM /* copyout data for gets */
43407836SJohn.Forte@Sun.COM rtn = iscsi_ioctl_copyout(ics, size,
43417836SJohn.Forte@Sun.COM (caddr_t)arg, mode);
43428426SShengliang.Zhang@Sun.COM } else {
43438426SShengliang.Zhang@Sun.COM kmem_free(ics, size);
43448426SShengliang.Zhang@Sun.COM ics = NULL;
43457836SJohn.Forte@Sun.COM }
43467836SJohn.Forte@Sun.COM } else {
43477836SJohn.Forte@Sun.COM /* set */
43487836SJohn.Forte@Sun.COM rtn = iscsi_ioctl_set_config_sess(ihp, ics);
43498194SJack.Meng@Sun.COM if (iscsiboot_prop) {
43508194SJack.Meng@Sun.COM if (iscsi_cmp_boot_sess_oid(ihp,
43518194SJack.Meng@Sun.COM ics->ics_oid)) {
43528194SJack.Meng@Sun.COM /*
43538194SJack.Meng@Sun.COM * found active session for this object
43548194SJack.Meng@Sun.COM * or this is initiator object
43558194SJack.Meng@Sun.COM * with mpxio enabled
43568194SJack.Meng@Sun.COM */
43578194SJack.Meng@Sun.COM if (!iscsi_reconfig_boot_sess(ihp)) {
43588426SShengliang.Zhang@Sun.COM kmem_free(ics, size);
43598426SShengliang.Zhang@Sun.COM ics = NULL;
43608194SJack.Meng@Sun.COM rtn = EINVAL;
43618194SJack.Meng@Sun.COM break;
43628194SJack.Meng@Sun.COM }
43638194SJack.Meng@Sun.COM }
43648194SJack.Meng@Sun.COM }
43658426SShengliang.Zhang@Sun.COM kmem_free(ics, size);
43668426SShengliang.Zhang@Sun.COM ics = NULL;
43677836SJohn.Forte@Sun.COM }
43687836SJohn.Forte@Sun.COM break;
43697836SJohn.Forte@Sun.COM
43708194SJack.Meng@Sun.COM case ISCSI_IS_ACTIVE:
43718194SJack.Meng@Sun.COM /*
43728194SJack.Meng@Sun.COM * dhcpagent calls here to check if there are
43738194SJack.Meng@Sun.COM * active iSCSI sessions
43748194SJack.Meng@Sun.COM */
43758194SJack.Meng@Sun.COM instance = 0;
43768194SJack.Meng@Sun.COM if (iscsiboot_prop) {
43778194SJack.Meng@Sun.COM instance = 1;
43788194SJack.Meng@Sun.COM }
43798194SJack.Meng@Sun.COM if (!instance) {
43808194SJack.Meng@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock,
43818194SJack.Meng@Sun.COM RW_READER);
43828194SJack.Meng@Sun.COM for (isp = ihp->hba_sess_list; isp;
43838194SJack.Meng@Sun.COM isp = isp->sess_next) {
43848194SJack.Meng@Sun.COM if ((isp->sess_state ==
43858194SJack.Meng@Sun.COM ISCSI_SESS_STATE_LOGGED_IN) &&
43868194SJack.Meng@Sun.COM (isp->sess_lun_list !=
43878194SJack.Meng@Sun.COM NULL)) {
43888194SJack.Meng@Sun.COM instance = 1;
43898194SJack.Meng@Sun.COM break;
43908194SJack.Meng@Sun.COM }
43918194SJack.Meng@Sun.COM }
43928194SJack.Meng@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
43938194SJack.Meng@Sun.COM }
43948194SJack.Meng@Sun.COM size = sizeof (instance);
43958194SJack.Meng@Sun.COM if (ddi_copyout(&instance, (caddr_t)arg, size,
43968194SJack.Meng@Sun.COM mode) != 0) {
43978194SJack.Meng@Sun.COM rtn = EFAULT;
43988194SJack.Meng@Sun.COM }
43998194SJack.Meng@Sun.COM break;
44008194SJack.Meng@Sun.COM
44018194SJack.Meng@Sun.COM case ISCSI_BOOTPROP_GET:
44028194SJack.Meng@Sun.COM size = sizeof (*bootProp);
44038194SJack.Meng@Sun.COM bootProp = iscsi_ioctl_copyin((caddr_t)arg, mode, size);
44048194SJack.Meng@Sun.COM if (bootProp == NULL) {
44058194SJack.Meng@Sun.COM rtn = EFAULT;
44068194SJack.Meng@Sun.COM break;
44078194SJack.Meng@Sun.COM }
44088194SJack.Meng@Sun.COM bootProp->hba_mpxio_enabled =
44098194SJack.Meng@Sun.COM iscsi_chk_bootlun_mpxio(ihp);
44108194SJack.Meng@Sun.COM if (iscsiboot_prop == NULL) {
44118194SJack.Meng@Sun.COM bootProp->iscsiboot = 0;
44128194SJack.Meng@Sun.COM rtn = iscsi_ioctl_copyout(bootProp, size,
44138194SJack.Meng@Sun.COM (caddr_t)arg, mode);
44148194SJack.Meng@Sun.COM break;
44158194SJack.Meng@Sun.COM } else {
44168194SJack.Meng@Sun.COM bootProp->iscsiboot = 1;
44178194SJack.Meng@Sun.COM }
44188194SJack.Meng@Sun.COM
44198194SJack.Meng@Sun.COM if (iscsiboot_prop->boot_init.ini_name != NULL) {
44208194SJack.Meng@Sun.COM (void) strncpy((char *)bootProp->ini_name.n_name,
44218194SJack.Meng@Sun.COM (char *)iscsiboot_prop->boot_init.ini_name,
44228194SJack.Meng@Sun.COM ISCSI_MAX_NAME_LEN);
44238194SJack.Meng@Sun.COM }
44248194SJack.Meng@Sun.COM if (iscsiboot_prop->boot_init.ini_chap_name != NULL) {
44258194SJack.Meng@Sun.COM bootProp->auth.a_auth_method = authMethodCHAP;
44268194SJack.Meng@Sun.COM (void) strncpy((char *)bootProp->ini_chap.c_user,
44278194SJack.Meng@Sun.COM (char *)iscsiboot_prop->boot_init.ini_chap_name,
44288194SJack.Meng@Sun.COM ISCSI_MAX_NAME_LEN);
44298194SJack.Meng@Sun.COM (void) strncpy((char *)bootProp->ini_chap.c_secret,
44308194SJack.Meng@Sun.COM (char *)iscsiboot_prop->boot_init.ini_chap_sec,
44318194SJack.Meng@Sun.COM ISCSI_CHAP_SECRET_LEN);
44328194SJack.Meng@Sun.COM if (iscsiboot_prop->boot_tgt.tgt_chap_name !=
44338194SJack.Meng@Sun.COM NULL) {
44348194SJack.Meng@Sun.COM bootProp->auth.a_bi_auth = B_TRUE;
44358194SJack.Meng@Sun.COM } else {
44368194SJack.Meng@Sun.COM bootProp->auth.a_bi_auth = B_FALSE;
44378194SJack.Meng@Sun.COM }
44388194SJack.Meng@Sun.COM }
44398194SJack.Meng@Sun.COM if (iscsiboot_prop->boot_tgt.tgt_name != NULL) {
44408194SJack.Meng@Sun.COM (void) strncpy((char *)bootProp->tgt_name.n_name,
44418194SJack.Meng@Sun.COM (char *)iscsiboot_prop->boot_tgt.tgt_name,
44428194SJack.Meng@Sun.COM ISCSI_MAX_NAME_LEN);
44438194SJack.Meng@Sun.COM }
44448194SJack.Meng@Sun.COM if (iscsiboot_prop->boot_tgt.tgt_chap_name != NULL) {
44458194SJack.Meng@Sun.COM (void) strncpy((char *)bootProp->tgt_chap.c_user,
44468194SJack.Meng@Sun.COM (char *)iscsiboot_prop->boot_tgt.tgt_chap_name,
44478194SJack.Meng@Sun.COM ISCSI_MAX_NAME_LEN);
44488194SJack.Meng@Sun.COM (void) strncpy((char *)bootProp->tgt_chap.c_secret,
44498194SJack.Meng@Sun.COM (char *)iscsiboot_prop->boot_tgt.tgt_chap_sec,
44508194SJack.Meng@Sun.COM ISCSI_CHAP_SECRET_LEN);
44518194SJack.Meng@Sun.COM }
44528194SJack.Meng@Sun.COM
44538194SJack.Meng@Sun.COM rtn = iscsi_ioctl_copyout(bootProp, size, (caddr_t)arg, mode);
44548194SJack.Meng@Sun.COM break;
44558194SJack.Meng@Sun.COM
445612161SJack.Meng@Sun.COM case ISCSI_TARGET_REENUM:
445712161SJack.Meng@Sun.COM size = sizeof (iscsi_reen_t);
445812161SJack.Meng@Sun.COM reenum = (iscsi_reen_t *)kmem_alloc(size, KM_SLEEP);
445912161SJack.Meng@Sun.COM
446012161SJack.Meng@Sun.COM if (ddi_copyin((caddr_t)arg, reenum, size, mode) != 0) {
446112161SJack.Meng@Sun.COM rtn = EFAULT;
446212161SJack.Meng@Sun.COM kmem_free(reenum, size);
446312161SJack.Meng@Sun.COM break;
446412161SJack.Meng@Sun.COM }
446512161SJack.Meng@Sun.COM if (reenum->re_ver != ISCSI_INTERFACE_VERSION) {
446612161SJack.Meng@Sun.COM rtn = EINVAL;
446712161SJack.Meng@Sun.COM kmem_free(reenum, size);
446812161SJack.Meng@Sun.COM break;
446912161SJack.Meng@Sun.COM }
447012161SJack.Meng@Sun.COM rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
447112161SJack.Meng@Sun.COM rtn = iscsi_sess_get(reenum->re_oid, ihp, &isp);
447212161SJack.Meng@Sun.COM if (rtn != 0) {
447312161SJack.Meng@Sun.COM rtn = iscsi_sess_get_by_target(
447412161SJack.Meng@Sun.COM reenum->re_oid, ihp, &isp);
447512161SJack.Meng@Sun.COM }
447612161SJack.Meng@Sun.COM
447712161SJack.Meng@Sun.COM if (rtn != 0) {
447812161SJack.Meng@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
447912161SJack.Meng@Sun.COM kmem_free(reenum, size);
448012161SJack.Meng@Sun.COM break;
448112161SJack.Meng@Sun.COM }
448212161SJack.Meng@Sun.COM kmem_free(reenum, size);
448312161SJack.Meng@Sun.COM if (isp->sess_type == ISCSI_SESS_TYPE_NORMAL) {
448412161SJack.Meng@Sun.COM rw_enter(&isp->sess_state_rwlock, RW_READER);
448512161SJack.Meng@Sun.COM if ((isp->sess_state ==
448612161SJack.Meng@Sun.COM ISCSI_SESS_STATE_LOGGED_IN) &&
448712161SJack.Meng@Sun.COM (iscsi_sess_enum_request(isp, B_TRUE,
448812161SJack.Meng@Sun.COM isp->sess_state_event_count)
448912161SJack.Meng@Sun.COM == ISCSI_SESS_ENUM_SUBMITTED)) {
449012161SJack.Meng@Sun.COM (void) iscsi_sess_enum_query(isp);
449112161SJack.Meng@Sun.COM }
449212161SJack.Meng@Sun.COM rw_exit(&isp->sess_state_rwlock);
449312161SJack.Meng@Sun.COM }
449412161SJack.Meng@Sun.COM rw_exit(&ihp->hba_sess_list_rwlock);
449512161SJack.Meng@Sun.COM break;
449612161SJack.Meng@Sun.COM
449710156SZhang.Yi@Sun.COM case ISCSI_TUNABLE_PARAM_SET:
449810156SZhang.Yi@Sun.COM tpss = (iscsi_tunable_object_t *)kmem_alloc(sizeof (*tpss),
449910156SZhang.Yi@Sun.COM KM_SLEEP);
450010156SZhang.Yi@Sun.COM if (ddi_copyin((caddr_t)arg, tpss, sizeof (*tpss), mode)) {
450110156SZhang.Yi@Sun.COM rtn = EFAULT;
450210156SZhang.Yi@Sun.COM kmem_free(tpss, sizeof (*tpss));
450310156SZhang.Yi@Sun.COM break;
450410156SZhang.Yi@Sun.COM }
450510156SZhang.Yi@Sun.COM rtn = iscsi_ioctl_set_tunable_param(ihp, tpss);
450610156SZhang.Yi@Sun.COM kmem_free(tpss, sizeof (*tpss));
450710156SZhang.Yi@Sun.COM break;
450810156SZhang.Yi@Sun.COM
450910156SZhang.Yi@Sun.COM case ISCSI_TUNABLE_PARAM_GET:
451010156SZhang.Yi@Sun.COM tpsg = (iscsi_tunable_object_t *)kmem_alloc(sizeof (*tpsg),
451110156SZhang.Yi@Sun.COM KM_SLEEP);
451210156SZhang.Yi@Sun.COM if (ddi_copyin((caddr_t)arg, tpsg, sizeof (*tpsg), mode)) {
451310156SZhang.Yi@Sun.COM rtn = EFAULT;
451410156SZhang.Yi@Sun.COM kmem_free(tpsg, sizeof (*tpsg));
451510156SZhang.Yi@Sun.COM break;
451610156SZhang.Yi@Sun.COM }
451710156SZhang.Yi@Sun.COM if (tpsg->t_oid == ihp->hba_oid) {
451810156SZhang.Yi@Sun.COM /* initiator */
451910156SZhang.Yi@Sun.COM name = ihp->hba_name;
452010156SZhang.Yi@Sun.COM if (iscsi_get_persisted_tunable_param((uchar_t *)name,
452110156SZhang.Yi@Sun.COM tpsg) == 1) {
452210156SZhang.Yi@Sun.COM /*
452310156SZhang.Yi@Sun.COM * no persisted tunable parameters found
452410156SZhang.Yi@Sun.COM * for iscsi initiator, use default tunable
452510156SZhang.Yi@Sun.COM * params for initiator node.
452610156SZhang.Yi@Sun.COM */
452710156SZhang.Yi@Sun.COM iscsi_get_tunable_default(tpsg);
452810156SZhang.Yi@Sun.COM }
452910156SZhang.Yi@Sun.COM } else {
453010156SZhang.Yi@Sun.COM /* check whether it is a target oid */
453110156SZhang.Yi@Sun.COM name = iscsi_targetparam_get_name(tpsg->t_oid);
453210156SZhang.Yi@Sun.COM if (name == NULL) {
453310156SZhang.Yi@Sun.COM /* invalid node name */
453410156SZhang.Yi@Sun.COM rtn = EINVAL;
453510156SZhang.Yi@Sun.COM kmem_free(tpsg, sizeof (*tpsg));
453610156SZhang.Yi@Sun.COM break;
453710156SZhang.Yi@Sun.COM }
453810156SZhang.Yi@Sun.COM if (iscsi_get_persisted_tunable_param((uchar_t *)name,
453910156SZhang.Yi@Sun.COM tpsg) == 1) {
454010156SZhang.Yi@Sun.COM /*
454110156SZhang.Yi@Sun.COM * no persisted tunable parameters found for
454210156SZhang.Yi@Sun.COM * iscsi target, use initiator's configure.
454310156SZhang.Yi@Sun.COM */
454410156SZhang.Yi@Sun.COM if (iscsi_get_persisted_tunable_param(
454510156SZhang.Yi@Sun.COM (uchar_t *)ihp->hba_name, tpsg) == -1) {
454610156SZhang.Yi@Sun.COM /*
454710156SZhang.Yi@Sun.COM * No initiator tunable parameters set
454810156SZhang.Yi@Sun.COM * use default value for target
454910156SZhang.Yi@Sun.COM */
455010156SZhang.Yi@Sun.COM iscsi_get_tunable_default(tpsg);
455110156SZhang.Yi@Sun.COM }
455210156SZhang.Yi@Sun.COM }
455310156SZhang.Yi@Sun.COM }
455410156SZhang.Yi@Sun.COM
455510156SZhang.Yi@Sun.COM if (ddi_copyout(tpsg, (caddr_t)arg,
455610156SZhang.Yi@Sun.COM sizeof (iscsi_tunable_object_t), mode) != 0) {
455710156SZhang.Yi@Sun.COM rtn = EFAULT;
455810156SZhang.Yi@Sun.COM }
455910156SZhang.Yi@Sun.COM kmem_free(tpsg, sizeof (*tpsg));
456010156SZhang.Yi@Sun.COM break;
456110156SZhang.Yi@Sun.COM
45627836SJohn.Forte@Sun.COM default:
45637836SJohn.Forte@Sun.COM rtn = ENOTTY;
45647836SJohn.Forte@Sun.COM cmn_err(CE_NOTE, "unrecognized ioctl 0x%x", cmd);
45657836SJohn.Forte@Sun.COM } /* end of ioctl type switch/cases */
45667836SJohn.Forte@Sun.COM
45679201SJack.Meng@Sun.COM if ((cmd != ISCSI_SMF_ONLINE) && (cmd != ISCSI_SMF_OFFLINE) &&
45689201SJack.Meng@Sun.COM (cmd != ISCSI_SMF_GET)) {
45699201SJack.Meng@Sun.COM /* other cmds need to release the service */
45709201SJack.Meng@Sun.COM iscsi_client_release_service(ihp);
45719201SJack.Meng@Sun.COM }
45729201SJack.Meng@Sun.COM
45737836SJohn.Forte@Sun.COM return (rtn);
45747836SJohn.Forte@Sun.COM }
45757836SJohn.Forte@Sun.COM
45767836SJohn.Forte@Sun.COM /*
45777836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
45787836SJohn.Forte@Sun.COM * | End of cb_ops routines |
45797836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
45807836SJohn.Forte@Sun.COM */
45817836SJohn.Forte@Sun.COM
45827836SJohn.Forte@Sun.COM
45837836SJohn.Forte@Sun.COM /*
45847836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
45857836SJohn.Forte@Sun.COM * | Common scsi_tran support routines |
45867836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
45877836SJohn.Forte@Sun.COM */
45887836SJohn.Forte@Sun.COM
45897836SJohn.Forte@Sun.COM /*
45907836SJohn.Forte@Sun.COM * iscsi_i_commoncap -- SCSA host adapter get/set capability routines.
45917836SJohn.Forte@Sun.COM *
45927836SJohn.Forte@Sun.COM * Need to determine if any of these can be determined through the iSCSI
45937836SJohn.Forte@Sun.COM * protocol. For now just return error on most.
45947836SJohn.Forte@Sun.COM */
45957836SJohn.Forte@Sun.COM /* ARGSUSED */
45967836SJohn.Forte@Sun.COM static int
iscsi_i_commoncap(struct scsi_address * ap,char * cap,int val,int tgtonly,int doset)45977836SJohn.Forte@Sun.COM iscsi_i_commoncap(struct scsi_address *ap, char *cap, int val,
45987836SJohn.Forte@Sun.COM int tgtonly, int doset)
45997836SJohn.Forte@Sun.COM {
46007836SJohn.Forte@Sun.COM int rtn;
46017836SJohn.Forte@Sun.COM int cidx;
46027836SJohn.Forte@Sun.COM iscsi_lun_t *ilp;
46037836SJohn.Forte@Sun.COM
46047836SJohn.Forte@Sun.COM ASSERT((ap)->a_hba_tran->tran_hba_private != NULL);
46057836SJohn.Forte@Sun.COM ilp = (iscsi_lun_t *)((ap)->a_hba_tran->tran_tgt_private);
46067836SJohn.Forte@Sun.COM ASSERT(ilp != NULL);
46077836SJohn.Forte@Sun.COM
46087836SJohn.Forte@Sun.COM if (cap == (char *)0) {
46097836SJohn.Forte@Sun.COM return (FALSE);
46107836SJohn.Forte@Sun.COM }
46117836SJohn.Forte@Sun.COM
46127836SJohn.Forte@Sun.COM cidx = scsi_hba_lookup_capstr(cap);
46137836SJohn.Forte@Sun.COM if (cidx == -1) {
46147836SJohn.Forte@Sun.COM return (cidx);
46157836SJohn.Forte@Sun.COM }
46167836SJohn.Forte@Sun.COM
46177836SJohn.Forte@Sun.COM /*
46187836SJohn.Forte@Sun.COM * Process setcap request.
46197836SJohn.Forte@Sun.COM */
46207836SJohn.Forte@Sun.COM if (doset) {
46217836SJohn.Forte@Sun.COM /*
46227836SJohn.Forte@Sun.COM * At present, we can only set binary (0/1) values
46237836SJohn.Forte@Sun.COM */
46247836SJohn.Forte@Sun.COM switch (cidx) {
46257836SJohn.Forte@Sun.COM case SCSI_CAP_LUN_RESET:
46267836SJohn.Forte@Sun.COM if (val) {
46277836SJohn.Forte@Sun.COM ilp->lun_cap |= ISCSI_LUN_CAP_RESET;
46287836SJohn.Forte@Sun.COM } else {
46297836SJohn.Forte@Sun.COM ilp->lun_cap &= ~ISCSI_LUN_CAP_RESET;
46307836SJohn.Forte@Sun.COM }
46317836SJohn.Forte@Sun.COM rtn = TRUE;
46327836SJohn.Forte@Sun.COM break;
46337836SJohn.Forte@Sun.COM default:
46347836SJohn.Forte@Sun.COM /*
46357836SJohn.Forte@Sun.COM * None of these are settable via
46367836SJohn.Forte@Sun.COM * the capability interface.
46377836SJohn.Forte@Sun.COM */
46387836SJohn.Forte@Sun.COM rtn = FALSE;
46397836SJohn.Forte@Sun.COM break;
46407836SJohn.Forte@Sun.COM }
46417836SJohn.Forte@Sun.COM
46427836SJohn.Forte@Sun.COM /*
46437836SJohn.Forte@Sun.COM * Process getcap request.
46447836SJohn.Forte@Sun.COM */
46457836SJohn.Forte@Sun.COM } else {
46467836SJohn.Forte@Sun.COM switch (cidx) {
46477836SJohn.Forte@Sun.COM case SCSI_CAP_DMA_MAX:
46487836SJohn.Forte@Sun.COM /* no DMA, Psuedo value */
46497836SJohn.Forte@Sun.COM rtn = INT32_MAX;
46507836SJohn.Forte@Sun.COM break;
46517836SJohn.Forte@Sun.COM case SCSI_CAP_INITIATOR_ID:
46527836SJohn.Forte@Sun.COM rtn = 7;
46537836SJohn.Forte@Sun.COM break;
46547836SJohn.Forte@Sun.COM case SCSI_CAP_ARQ:
46557836SJohn.Forte@Sun.COM case SCSI_CAP_RESET_NOTIFICATION:
46567836SJohn.Forte@Sun.COM case SCSI_CAP_TAGGED_QING:
46577836SJohn.Forte@Sun.COM rtn = TRUE;
46587836SJohn.Forte@Sun.COM break;
46597836SJohn.Forte@Sun.COM case SCSI_CAP_SCSI_VERSION:
46607836SJohn.Forte@Sun.COM rtn = SCSI_VERSION_3;
46617836SJohn.Forte@Sun.COM break;
46627836SJohn.Forte@Sun.COM case SCSI_CAP_INTERCONNECT_TYPE:
46637836SJohn.Forte@Sun.COM rtn = INTERCONNECT_FABRIC;
46647836SJohn.Forte@Sun.COM break;
46657836SJohn.Forte@Sun.COM case SCSI_CAP_LUN_RESET:
46667836SJohn.Forte@Sun.COM rtn = ((ilp->lun_cap & ISCSI_LUN_CAP_RESET) != 0) ?
46677836SJohn.Forte@Sun.COM TRUE : FALSE;
46687836SJohn.Forte@Sun.COM break;
46697836SJohn.Forte@Sun.COM case SCSI_CAP_CDB_LEN:
46707836SJohn.Forte@Sun.COM /*
46717836SJohn.Forte@Sun.COM * iSCSI RFC 3720 defines a default 16 byte
46727836SJohn.Forte@Sun.COM * CDB as part of the Basic Header Segment
46737836SJohn.Forte@Sun.COM * (BHS) (10.2.1) and allows for an Additional
46747836SJohn.Forte@Sun.COM * Header Segment (AHS) Length of 255 * 4
46757836SJohn.Forte@Sun.COM * (10.2.1.5). The AHS length can be used
46767836SJohn.Forte@Sun.COM * for different purposes two of which are
46777836SJohn.Forte@Sun.COM * Extended CDB ADS (10.2.2.3) and Bidirectional
46787836SJohn.Forte@Sun.COM * Expected Read-Data Length AHS (10.2.2.4).
46797836SJohn.Forte@Sun.COM * The largest header of these consumes is
46807836SJohn.Forte@Sun.COM * 32 bytes. So the total Max CDB Length is
46817836SJohn.Forte@Sun.COM * 16 + ((255 * 4 ) - 32) = 1004.
46827836SJohn.Forte@Sun.COM */
46837836SJohn.Forte@Sun.COM rtn = 1004;
46847836SJohn.Forte@Sun.COM break;
46857836SJohn.Forte@Sun.COM default:
46867836SJohn.Forte@Sun.COM rtn = UNDEFINED;
46877836SJohn.Forte@Sun.COM break;
46887836SJohn.Forte@Sun.COM }
46897836SJohn.Forte@Sun.COM }
46907836SJohn.Forte@Sun.COM return (rtn);
46917836SJohn.Forte@Sun.COM }
46927836SJohn.Forte@Sun.COM
46937836SJohn.Forte@Sun.COM /*
46947836SJohn.Forte@Sun.COM * iscsi_virt_lun_init - attempts to complete a mdi/scsi_vhci binding
46957836SJohn.Forte@Sun.COM *
46967836SJohn.Forte@Sun.COM * This routine is used to associate the tran_tgt_private to our ilp
46977836SJohn.Forte@Sun.COM * structure. This function is indirectly called from our
46987836SJohn.Forte@Sun.COM * iscsi_lun_create_xxx routines. These routines must prevent
46997836SJohn.Forte@Sun.COM * the session and lun lists from changing during this call.
47007836SJohn.Forte@Sun.COM */
47017836SJohn.Forte@Sun.COM /* ARGSUSED */
47027836SJohn.Forte@Sun.COM static int
iscsi_virt_lun_init(dev_info_t * hba_dip,dev_info_t * lun_dip,scsi_hba_tran_t * hba_tran,struct scsi_device * sd)47037836SJohn.Forte@Sun.COM iscsi_virt_lun_init(dev_info_t *hba_dip, dev_info_t *lun_dip,
47047836SJohn.Forte@Sun.COM scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
47057836SJohn.Forte@Sun.COM {
47067836SJohn.Forte@Sun.COM iscsi_lun_t *ilp = NULL;
47077836SJohn.Forte@Sun.COM iscsi_lun_t *ilp_check = NULL;
47087836SJohn.Forte@Sun.COM iscsi_sess_t *isp = NULL;
47097836SJohn.Forte@Sun.COM char *lun_guid = NULL;
47107836SJohn.Forte@Sun.COM mdi_pathinfo_t *pip = NULL;
47117836SJohn.Forte@Sun.COM iscsi_hba_t *ihp = (iscsi_hba_t *)hba_tran->tran_hba_private;
47127836SJohn.Forte@Sun.COM char target_port_name[MAX_NAME_PROP_SIZE];
47137836SJohn.Forte@Sun.COM
47147836SJohn.Forte@Sun.COM /*
47157836SJohn.Forte@Sun.COM * Here's a nice little piece of undocumented stuff.
47167836SJohn.Forte@Sun.COM */
47177836SJohn.Forte@Sun.COM if ((pip = (mdi_pathinfo_t *)sd->sd_private) == NULL) {
47187836SJohn.Forte@Sun.COM /*
47197836SJohn.Forte@Sun.COM * Very bad news if this occurs. Somehow SCSI_vhci has
47207836SJohn.Forte@Sun.COM * lost the pathinfo node for this target.
47217836SJohn.Forte@Sun.COM */
47227836SJohn.Forte@Sun.COM return (DDI_NOT_WELL_FORMED);
47237836SJohn.Forte@Sun.COM }
47247836SJohn.Forte@Sun.COM
47257836SJohn.Forte@Sun.COM ilp = (iscsi_lun_t *)mdi_pi_get_phci_private(pip);
47267836SJohn.Forte@Sun.COM
47277836SJohn.Forte@Sun.COM /*
47287836SJohn.Forte@Sun.COM * +----------------------------------------------------+
47297836SJohn.Forte@Sun.COM * | Looking to find the target device via the property |
47307836SJohn.Forte@Sun.COM * | is not required since the driver can easily get |
47317836SJohn.Forte@Sun.COM * | this information from the mdi_phci_get_private() |
47327836SJohn.Forte@Sun.COM * | call above. This is just a consistency check |
47337836SJohn.Forte@Sun.COM * | which can be removed. |
47347836SJohn.Forte@Sun.COM */
47357836SJohn.Forte@Sun.COM if (mdi_prop_lookup_string(pip, MDI_GUID, &lun_guid) !=
47367836SJohn.Forte@Sun.COM DDI_PROP_SUCCESS) {
47377836SJohn.Forte@Sun.COM return (DDI_NOT_WELL_FORMED);
47387836SJohn.Forte@Sun.COM }
47397836SJohn.Forte@Sun.COM
47407836SJohn.Forte@Sun.COM for (isp = ihp->hba_sess_list; isp; isp = isp->sess_next) {
47417836SJohn.Forte@Sun.COM
47427836SJohn.Forte@Sun.COM /* If this isn't the matching session continue */
47437836SJohn.Forte@Sun.COM if (ilp->lun_sess != isp) {
47447836SJohn.Forte@Sun.COM continue;
47457836SJohn.Forte@Sun.COM }
47467836SJohn.Forte@Sun.COM
47477836SJohn.Forte@Sun.COM /*
47487836SJohn.Forte@Sun.COM * We are already holding the lun list rwlock
47497836SJohn.Forte@Sun.COM * for this thread on the callers side of mdi_pi_online
47507836SJohn.Forte@Sun.COM * or ndi_devi_online. Which lead to this functions
47517836SJohn.Forte@Sun.COM * call.
47527836SJohn.Forte@Sun.COM */
47537836SJohn.Forte@Sun.COM for (ilp_check = isp->sess_lun_list; ilp_check;
47547836SJohn.Forte@Sun.COM ilp_check = ilp_check->lun_next) {
47557836SJohn.Forte@Sun.COM
47567836SJohn.Forte@Sun.COM /*
47577836SJohn.Forte@Sun.COM * If this is the matching LUN and contains
47587836SJohn.Forte@Sun.COM * the same LUN GUID then break we found our
47597836SJohn.Forte@Sun.COM * match.
47607836SJohn.Forte@Sun.COM */
47617836SJohn.Forte@Sun.COM if ((ilp == ilp_check) &&
47627836SJohn.Forte@Sun.COM (strcmp(lun_guid, ilp_check->lun_guid) == 0)) {
47637836SJohn.Forte@Sun.COM break;
47647836SJohn.Forte@Sun.COM }
47657836SJohn.Forte@Sun.COM }
47667836SJohn.Forte@Sun.COM if (ilp_check != NULL) {
47677836SJohn.Forte@Sun.COM break;
47687836SJohn.Forte@Sun.COM }
47697836SJohn.Forte@Sun.COM }
47707836SJohn.Forte@Sun.COM
47717836SJohn.Forte@Sun.COM /*
47727836SJohn.Forte@Sun.COM * Free resource that's no longer required.
47737836SJohn.Forte@Sun.COM */
47747836SJohn.Forte@Sun.COM if (lun_guid != NULL)
47757836SJohn.Forte@Sun.COM (void) mdi_prop_free(lun_guid);
47767836SJohn.Forte@Sun.COM
47777836SJohn.Forte@Sun.COM if (ilp_check == NULL) {
47787836SJohn.Forte@Sun.COM /*
47797836SJohn.Forte@Sun.COM * Failed to find iSCSI LUN in HBA chain based
47807836SJohn.Forte@Sun.COM * on the GUID that was stored as a property on
47817836SJohn.Forte@Sun.COM * the pathinfo node.
47827836SJohn.Forte@Sun.COM */
47837836SJohn.Forte@Sun.COM return (DDI_NOT_WELL_FORMED);
47847836SJohn.Forte@Sun.COM }
47857836SJohn.Forte@Sun.COM
47867836SJohn.Forte@Sun.COM if (ilp != ilp_check) {
47877836SJohn.Forte@Sun.COM /*
47887836SJohn.Forte@Sun.COM * The iSCSI target that we found on the HBA link is
47897836SJohn.Forte@Sun.COM * different than the iSCSI target that was stored as
47907836SJohn.Forte@Sun.COM * private data on the pathinfo node.
47917836SJohn.Forte@Sun.COM */
47927836SJohn.Forte@Sun.COM return (DDI_NOT_WELL_FORMED);
47937836SJohn.Forte@Sun.COM }
47947836SJohn.Forte@Sun.COM /*
47957836SJohn.Forte@Sun.COM * | End of consistency check |
47967836SJohn.Forte@Sun.COM * +----------------------------------------------------+
47977836SJohn.Forte@Sun.COM */
47987836SJohn.Forte@Sun.COM
47997836SJohn.Forte@Sun.COM hba_tran->tran_tgt_private = ilp;
48007836SJohn.Forte@Sun.COM
48017836SJohn.Forte@Sun.COM target_port_name[0] = '\0';
48027836SJohn.Forte@Sun.COM if (ilp->lun_sess->sess_tpgt_conf == ISCSI_DEFAULT_TPGT) {
48037836SJohn.Forte@Sun.COM (void) snprintf(target_port_name, MAX_NAME_PROP_SIZE,
48047836SJohn.Forte@Sun.COM "%02x%02x%02x%02x%02x%02x,%s",
48057836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[0], ilp->lun_sess->sess_isid[1],
48067836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[2], ilp->lun_sess->sess_isid[3],
48077836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[4], ilp->lun_sess->sess_isid[5],
48087836SJohn.Forte@Sun.COM ilp->lun_sess->sess_name);
48097836SJohn.Forte@Sun.COM } else {
48107836SJohn.Forte@Sun.COM (void) snprintf(target_port_name, MAX_NAME_PROP_SIZE,
48117836SJohn.Forte@Sun.COM "%02x%02x%02x%02x%02x%02x,%s,%d",
48127836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[0], ilp->lun_sess->sess_isid[1],
48137836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[2], ilp->lun_sess->sess_isid[3],
48147836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[4], ilp->lun_sess->sess_isid[5],
48157836SJohn.Forte@Sun.COM ilp->lun_sess->sess_name, ilp->lun_sess->sess_tpgt_conf);
48167836SJohn.Forte@Sun.COM }
48177836SJohn.Forte@Sun.COM
481810696SDavid.Hollister@Sun.COM if (mdi_prop_update_string(pip,
481910696SDavid.Hollister@Sun.COM SCSI_ADDR_PROP_TARGET_PORT, target_port_name) != DDI_PROP_SUCCESS) {
482010696SDavid.Hollister@Sun.COM cmn_err(CE_WARN, "iscsi_virt_lun_init: Creating '"
482110696SDavid.Hollister@Sun.COM SCSI_ADDR_PROP_TARGET_PORT "' property on Path(%p) "
482210696SDavid.Hollister@Sun.COM "for Target(%s), Lun(%d) Failed",
48237836SJohn.Forte@Sun.COM (void *)pip, ilp->lun_sess->sess_name, ilp->lun_num);
48247836SJohn.Forte@Sun.COM }
48257836SJohn.Forte@Sun.COM
48267836SJohn.Forte@Sun.COM return (DDI_SUCCESS);
48277836SJohn.Forte@Sun.COM }
48287836SJohn.Forte@Sun.COM
48297836SJohn.Forte@Sun.COM /*
48307836SJohn.Forte@Sun.COM * iscsi_phys_lun_init - attempts to complete a ndi binding
48317836SJohn.Forte@Sun.COM *
48327836SJohn.Forte@Sun.COM * This routine is used to associate the tran_tgt_private to our
48337836SJohn.Forte@Sun.COM * ilp structure. This function is indirectly called from our
48347836SJohn.Forte@Sun.COM * iscsi_lun_create_xxx routines. These routines must prevent
48357836SJohn.Forte@Sun.COM * the session and lun lists from changing during this call.
48367836SJohn.Forte@Sun.COM */
48377836SJohn.Forte@Sun.COM static int
iscsi_phys_lun_init(dev_info_t * hba_dip,dev_info_t * lun_dip,scsi_hba_tran_t * hba_tran,struct scsi_device * sd)48387836SJohn.Forte@Sun.COM iscsi_phys_lun_init(dev_info_t *hba_dip, dev_info_t *lun_dip,
48397836SJohn.Forte@Sun.COM scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
48407836SJohn.Forte@Sun.COM {
48417836SJohn.Forte@Sun.COM int rtn = DDI_SUCCESS;
48427836SJohn.Forte@Sun.COM iscsi_hba_t *ihp = NULL;
48437836SJohn.Forte@Sun.COM iscsi_sess_t *isp = NULL;
48447836SJohn.Forte@Sun.COM iscsi_lun_t *ilp = NULL;
48457836SJohn.Forte@Sun.COM char target_port_name[MAX_NAME_PROP_SIZE];
48467836SJohn.Forte@Sun.COM int *words = NULL;
48477836SJohn.Forte@Sun.COM uint_t nwords = 0;
48487836SJohn.Forte@Sun.COM
48497836SJohn.Forte@Sun.COM ASSERT(hba_dip);
48507836SJohn.Forte@Sun.COM ASSERT(lun_dip);
48517836SJohn.Forte@Sun.COM ASSERT(hba_tran);
48527836SJohn.Forte@Sun.COM ASSERT(sd);
48537836SJohn.Forte@Sun.COM ihp = (iscsi_hba_t *)hba_tran->tran_hba_private;
48547836SJohn.Forte@Sun.COM ASSERT(ihp);
48557836SJohn.Forte@Sun.COM
48567836SJohn.Forte@Sun.COM if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, lun_dip,
48577836SJohn.Forte@Sun.COM DDI_PROP_DONTPASS, LUN_PROP, &words, &nwords) != DDI_PROP_SUCCESS) {
48587836SJohn.Forte@Sun.COM cmn_err(CE_WARN, "iscsi_phys_lun_init: Returning DDI_FAILURE:"
48597836SJohn.Forte@Sun.COM "lun for %s (instance %d)", ddi_get_name(lun_dip),
48607836SJohn.Forte@Sun.COM ddi_get_instance(lun_dip));
48617836SJohn.Forte@Sun.COM return (DDI_FAILURE);
48627836SJohn.Forte@Sun.COM }
48637836SJohn.Forte@Sun.COM
48647836SJohn.Forte@Sun.COM if (nwords == 0) {
48657836SJohn.Forte@Sun.COM ddi_prop_free(words);
48667836SJohn.Forte@Sun.COM return (DDI_FAILURE);
48677836SJohn.Forte@Sun.COM }
48687836SJohn.Forte@Sun.COM
48697836SJohn.Forte@Sun.COM ASSERT(words != NULL);
48707836SJohn.Forte@Sun.COM
48717836SJohn.Forte@Sun.COM /* See if we already created this session */
48727836SJohn.Forte@Sun.COM
48737836SJohn.Forte@Sun.COM /* Walk the HBA's session list */
48747836SJohn.Forte@Sun.COM for (isp = ihp->hba_sess_list; isp; isp = isp->sess_next) {
48757836SJohn.Forte@Sun.COM /* compare target name as the unique identifier */
48767836SJohn.Forte@Sun.COM if (sd->sd_address.a_target == isp->sess_oid) {
48777836SJohn.Forte@Sun.COM /* found match */
48787836SJohn.Forte@Sun.COM break;
48797836SJohn.Forte@Sun.COM }
48807836SJohn.Forte@Sun.COM }
48817836SJohn.Forte@Sun.COM
48827836SJohn.Forte@Sun.COM /* If we found matching session continue searching for tgt */
48837836SJohn.Forte@Sun.COM if (isp != NULL) {
48847836SJohn.Forte@Sun.COM /*
48857836SJohn.Forte@Sun.COM * Search for the matching iscsi lun structure. We don't
48867836SJohn.Forte@Sun.COM * need to hold the READER for the lun list at this point.
48877836SJohn.Forte@Sun.COM * because the tran_get_name is being called from the online
48887836SJohn.Forte@Sun.COM * function which is already holding a reader on the lun
48897836SJohn.Forte@Sun.COM * list.
48907836SJohn.Forte@Sun.COM */
48917836SJohn.Forte@Sun.COM for (ilp = isp->sess_lun_list; ilp; ilp = ilp->lun_next) {
48927836SJohn.Forte@Sun.COM if (*words == ilp->lun_num) {
48937836SJohn.Forte@Sun.COM /* found match */
48947836SJohn.Forte@Sun.COM break;
48957836SJohn.Forte@Sun.COM }
48967836SJohn.Forte@Sun.COM }
48977836SJohn.Forte@Sun.COM
48987836SJohn.Forte@Sun.COM if (ilp != NULL) {
48997836SJohn.Forte@Sun.COM /*
49007836SJohn.Forte@Sun.COM * tgt found path it to the tran_lun_private
49017836SJohn.Forte@Sun.COM * this is used later for fast access on
49027836SJohn.Forte@Sun.COM * init_pkt and start
49037836SJohn.Forte@Sun.COM */
49047836SJohn.Forte@Sun.COM hba_tran->tran_tgt_private = ilp;
49057836SJohn.Forte@Sun.COM } else {
49067836SJohn.Forte@Sun.COM /* tgt not found */
49077836SJohn.Forte@Sun.COM ddi_prop_free(words);
49087836SJohn.Forte@Sun.COM return (DDI_FAILURE);
49097836SJohn.Forte@Sun.COM }
49107836SJohn.Forte@Sun.COM } else {
49117836SJohn.Forte@Sun.COM /* sess not found */
49127836SJohn.Forte@Sun.COM ddi_prop_free(words);
49137836SJohn.Forte@Sun.COM return (DDI_FAILURE);
49147836SJohn.Forte@Sun.COM }
49157836SJohn.Forte@Sun.COM ddi_prop_free(words);
49167836SJohn.Forte@Sun.COM
49177836SJohn.Forte@Sun.COM target_port_name[0] = '\0';
49187836SJohn.Forte@Sun.COM if (ilp->lun_sess->sess_tpgt_conf == ISCSI_DEFAULT_TPGT) {
49197836SJohn.Forte@Sun.COM (void) snprintf(target_port_name, MAX_NAME_PROP_SIZE,
49207836SJohn.Forte@Sun.COM "%02x%02x%02x%02x%02x%02x,%s",
49217836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[0], ilp->lun_sess->sess_isid[1],
49227836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[2], ilp->lun_sess->sess_isid[3],
49237836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[4], ilp->lun_sess->sess_isid[5],
49247836SJohn.Forte@Sun.COM ilp->lun_sess->sess_name);
49257836SJohn.Forte@Sun.COM } else {
49267836SJohn.Forte@Sun.COM (void) snprintf(target_port_name, MAX_NAME_PROP_SIZE,
49277836SJohn.Forte@Sun.COM "%02x%02x%02x%02x%02x%02x,%s,%d",
49287836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[0], ilp->lun_sess->sess_isid[1],
49297836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[2], ilp->lun_sess->sess_isid[3],
49307836SJohn.Forte@Sun.COM ilp->lun_sess->sess_isid[4], ilp->lun_sess->sess_isid[5],
49317836SJohn.Forte@Sun.COM ilp->lun_sess->sess_name, ilp->lun_sess->sess_tpgt_conf);
49327836SJohn.Forte@Sun.COM }
49337836SJohn.Forte@Sun.COM
49347836SJohn.Forte@Sun.COM if (ddi_prop_update_string(DDI_DEV_T_NONE, lun_dip,
493510696SDavid.Hollister@Sun.COM SCSI_ADDR_PROP_TARGET_PORT, target_port_name) != DDI_PROP_SUCCESS) {
493610696SDavid.Hollister@Sun.COM cmn_err(CE_WARN, "iscsi_phys_lun_init: Creating '"
493710696SDavid.Hollister@Sun.COM SCSI_ADDR_PROP_TARGET_PORT "' property on Target(%s), "
493810696SDavid.Hollister@Sun.COM "Lun(%d) Failed", ilp->lun_sess->sess_name, ilp->lun_num);
49397836SJohn.Forte@Sun.COM }
49407836SJohn.Forte@Sun.COM
49417836SJohn.Forte@Sun.COM return (rtn);
49427836SJohn.Forte@Sun.COM }
49437836SJohn.Forte@Sun.COM
49447836SJohn.Forte@Sun.COM /*
49457836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
49467836SJohn.Forte@Sun.COM * | End of scsi_tran support routines |
49477836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
49487836SJohn.Forte@Sun.COM */
49497836SJohn.Forte@Sun.COM
49507836SJohn.Forte@Sun.COM /*
49517836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
49527836SJohn.Forte@Sun.COM * | Begin of struct utility routines |
49537836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
49547836SJohn.Forte@Sun.COM */
49557836SJohn.Forte@Sun.COM
49567836SJohn.Forte@Sun.COM
49577836SJohn.Forte@Sun.COM /*
49587836SJohn.Forte@Sun.COM * iscsi_set_default_login_params - This function sets the
49597836SJohn.Forte@Sun.COM * driver default login params. This is using during the
49607836SJohn.Forte@Sun.COM * creation of our iSCSI HBA structure initialization by
49617836SJohn.Forte@Sun.COM * could be used at other times to reset back to the defaults.
49627836SJohn.Forte@Sun.COM */
49637836SJohn.Forte@Sun.COM void
iscsi_set_default_login_params(iscsi_login_params_t * params)49647836SJohn.Forte@Sun.COM iscsi_set_default_login_params(iscsi_login_params_t *params)
49657836SJohn.Forte@Sun.COM {
49667836SJohn.Forte@Sun.COM params->immediate_data = ISCSI_DEFAULT_IMMEDIATE_DATA;
49677836SJohn.Forte@Sun.COM params->initial_r2t = ISCSI_DEFAULT_INITIALR2T;
49687836SJohn.Forte@Sun.COM params->first_burst_length = ISCSI_DEFAULT_FIRST_BURST_LENGTH;
49697836SJohn.Forte@Sun.COM params->max_burst_length = ISCSI_DEFAULT_MAX_BURST_LENGTH;
49707836SJohn.Forte@Sun.COM params->data_pdu_in_order = ISCSI_DEFAULT_DATA_PDU_IN_ORDER;
49717836SJohn.Forte@Sun.COM params->data_sequence_in_order = ISCSI_DEFAULT_DATA_SEQUENCE_IN_ORDER;
49727836SJohn.Forte@Sun.COM params->default_time_to_wait = ISCSI_DEFAULT_TIME_TO_WAIT;
49737836SJohn.Forte@Sun.COM params->default_time_to_retain = ISCSI_DEFAULT_TIME_TO_RETAIN;
49747836SJohn.Forte@Sun.COM params->header_digest = ISCSI_DEFAULT_HEADER_DIGEST;
49757836SJohn.Forte@Sun.COM params->data_digest = ISCSI_DEFAULT_DATA_DIGEST;
49767836SJohn.Forte@Sun.COM params->max_recv_data_seg_len = ISCSI_DEFAULT_MAX_RECV_SEG_LEN;
49777836SJohn.Forte@Sun.COM params->max_xmit_data_seg_len = ISCSI_DEFAULT_MAX_XMIT_SEG_LEN;
49787836SJohn.Forte@Sun.COM params->max_connections = ISCSI_DEFAULT_MAX_CONNECTIONS;
49797836SJohn.Forte@Sun.COM params->max_outstanding_r2t = ISCSI_DEFAULT_MAX_OUT_R2T;
49807836SJohn.Forte@Sun.COM params->error_recovery_level = ISCSI_DEFAULT_ERROR_RECOVERY_LEVEL;
49817836SJohn.Forte@Sun.COM params->ifmarker = ISCSI_DEFAULT_IFMARKER;
49827836SJohn.Forte@Sun.COM params->ofmarker = ISCSI_DEFAULT_OFMARKER;
49837836SJohn.Forte@Sun.COM }
49847836SJohn.Forte@Sun.COM
498510156SZhang.Yi@Sun.COM /* Helper function to sets the driver default tunable parameters */
498610156SZhang.Yi@Sun.COM static void
iscsi_set_default_tunable_params(iscsi_tunable_params_t * params)498710156SZhang.Yi@Sun.COM iscsi_set_default_tunable_params(iscsi_tunable_params_t *params)
498810156SZhang.Yi@Sun.COM {
498910156SZhang.Yi@Sun.COM params->recv_login_rsp_timeout = ISCSI_DEFAULT_RX_TIMEOUT_VALUE;
499010156SZhang.Yi@Sun.COM params->conn_login_max = ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX;
499110156SZhang.Yi@Sun.COM params->polling_login_delay = ISCSI_DEFAULT_LOGIN_POLLING_DELAY;
499210156SZhang.Yi@Sun.COM }
49937836SJohn.Forte@Sun.COM
49947836SJohn.Forte@Sun.COM /*
49957836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
49967836SJohn.Forte@Sun.COM * | End of struct utility routines |
49977836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
49987836SJohn.Forte@Sun.COM */
49997836SJohn.Forte@Sun.COM
50007836SJohn.Forte@Sun.COM /*
50017836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
50027836SJohn.Forte@Sun.COM * | Begin of ioctl utility routines |
50037836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
50047836SJohn.Forte@Sun.COM */
50057836SJohn.Forte@Sun.COM
50067836SJohn.Forte@Sun.COM /*
50077836SJohn.Forte@Sun.COM * iscsi_get_param - This function is a helper to ISCSI_GET_PARAM
50087836SJohn.Forte@Sun.COM * IOCTL
50097836SJohn.Forte@Sun.COM */
50107836SJohn.Forte@Sun.COM int
iscsi_get_param(iscsi_login_params_t * params,boolean_t valid_flag,iscsi_param_get_t * ipgp)50117836SJohn.Forte@Sun.COM iscsi_get_param(iscsi_login_params_t *params, boolean_t valid_flag,
50127836SJohn.Forte@Sun.COM iscsi_param_get_t *ipgp) {
50137836SJohn.Forte@Sun.COM int rtn = 0;
50147836SJohn.Forte@Sun.COM
50157836SJohn.Forte@Sun.COM /* ---- Default to settable, possibly changed later ---- */
50167836SJohn.Forte@Sun.COM ipgp->g_value.v_valid = valid_flag;
50177836SJohn.Forte@Sun.COM ipgp->g_value.v_settable = B_TRUE;
50187836SJohn.Forte@Sun.COM
50197836SJohn.Forte@Sun.COM switch (ipgp->g_param) {
50207836SJohn.Forte@Sun.COM /*
50217836SJohn.Forte@Sun.COM * Boolean parameters
50227836SJohn.Forte@Sun.COM */
50237836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER:
50247836SJohn.Forte@Sun.COM ipgp->g_value.v_bool.b_current =
50257836SJohn.Forte@Sun.COM params->data_sequence_in_order;
50267836SJohn.Forte@Sun.COM ipgp->g_value.v_bool.b_default =
50277836SJohn.Forte@Sun.COM ISCSI_DEFAULT_DATA_SEQUENCE_IN_ORDER;
50287836SJohn.Forte@Sun.COM break;
50297836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_IMMEDIATE_DATA:
50307836SJohn.Forte@Sun.COM ipgp->g_value.v_bool.b_current =
50317836SJohn.Forte@Sun.COM params->immediate_data;
50327836SJohn.Forte@Sun.COM ipgp->g_value.v_bool.b_default =
50337836SJohn.Forte@Sun.COM ISCSI_DEFAULT_IMMEDIATE_DATA;
50347836SJohn.Forte@Sun.COM break;
50357836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_INITIAL_R2T:
50367836SJohn.Forte@Sun.COM ipgp->g_value.v_bool.b_current =
50377836SJohn.Forte@Sun.COM params->initial_r2t;
50387836SJohn.Forte@Sun.COM ipgp->g_value.v_bool.b_default =
50397836SJohn.Forte@Sun.COM ISCSI_DEFAULT_IMMEDIATE_DATA;
50407836SJohn.Forte@Sun.COM break;
50417836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER:
50427836SJohn.Forte@Sun.COM ipgp->g_value.v_bool.b_current =
50437836SJohn.Forte@Sun.COM params->data_pdu_in_order;
50447836SJohn.Forte@Sun.COM ipgp->g_value.v_bool.b_default =
50457836SJohn.Forte@Sun.COM ISCSI_DEFAULT_DATA_PDU_IN_ORDER;
50467836SJohn.Forte@Sun.COM break;
50477836SJohn.Forte@Sun.COM
50487836SJohn.Forte@Sun.COM /*
50497836SJohn.Forte@Sun.COM * Integer parameters
50507836SJohn.Forte@Sun.COM */
50517836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_HEADER_DIGEST:
50527836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_current = params->header_digest;
50537836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_default = ISCSI_DEFAULT_HEADER_DIGEST;
50547836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_min = 0;
50557836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_max = ISCSI_MAX_HEADER_DIGEST;
50567836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_incr = 1;
50577836SJohn.Forte@Sun.COM break;
50587836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_DATA_DIGEST:
50597836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_current = params->data_digest;
50607836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_default = ISCSI_DEFAULT_DATA_DIGEST;
50617836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_min = 0;
50627836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_max = ISCSI_MAX_DATA_DIGEST;
50637836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_incr = 1;
50647836SJohn.Forte@Sun.COM break;
50657836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN:
50667836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_current =
50677836SJohn.Forte@Sun.COM params->default_time_to_retain;
50687836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_default =
50697836SJohn.Forte@Sun.COM ISCSI_DEFAULT_TIME_TO_RETAIN;
50707836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_min = 0;
50717836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_max = ISCSI_MAX_TIME2RETAIN;
50727836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_incr = 1;
50737836SJohn.Forte@Sun.COM break;
50747836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT:
50757836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_current =
50767836SJohn.Forte@Sun.COM params->default_time_to_wait;
50777836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_default =
50787836SJohn.Forte@Sun.COM ISCSI_DEFAULT_TIME_TO_WAIT;
50797836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_min = 0;
50807836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_max = ISCSI_MAX_TIME2WAIT;
50817836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_incr = 1;
50827836SJohn.Forte@Sun.COM break;
50837836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL:
50847836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_current =
50857836SJohn.Forte@Sun.COM params->error_recovery_level;
50867836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_default =
50877836SJohn.Forte@Sun.COM ISCSI_DEFAULT_ERROR_RECOVERY_LEVEL;
50887836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_min = 0;
50897836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_max = ISCSI_MAX_ERROR_RECOVERY_LEVEL;
50907836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_incr = 1;
50917836SJohn.Forte@Sun.COM ipgp->g_value.v_settable = B_FALSE;
50927836SJohn.Forte@Sun.COM break;
50937836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH:
50947836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_current =
50957836SJohn.Forte@Sun.COM params->first_burst_length;
50967836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_default =
50977836SJohn.Forte@Sun.COM ISCSI_DEFAULT_FIRST_BURST_LENGTH;
50987836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_min = 512;
50997836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_max = ISCSI_MAX_FIRST_BURST_LENGTH;
51007836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_incr = 1;
51017836SJohn.Forte@Sun.COM break;
51027836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH:
51037836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_current =
51047836SJohn.Forte@Sun.COM params->max_burst_length;
51057836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_default =
51067836SJohn.Forte@Sun.COM ISCSI_DEFAULT_MAX_BURST_LENGTH;
51077836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_min = 512;
51087836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_max = ISCSI_MAX_BURST_LENGTH;
51097836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_incr = 1;
51107836SJohn.Forte@Sun.COM break;
51117836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_MAX_CONNECTIONS:
51127836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_current =
51137836SJohn.Forte@Sun.COM params->max_connections;
51147836SJohn.Forte@Sun.COM ipgp->g_value.v_settable = B_FALSE;
51157836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_default =
51167836SJohn.Forte@Sun.COM ISCSI_DEFAULT_MAX_CONNECTIONS;
51177836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_min = 1;
51187836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_max = ISCSI_MAX_CONNECTIONS;
51197836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_incr = 1;
51207836SJohn.Forte@Sun.COM break;
51217836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_OUTSTANDING_R2T:
51227836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_current =
51237836SJohn.Forte@Sun.COM params->max_outstanding_r2t;
51247836SJohn.Forte@Sun.COM ipgp->g_value.v_settable = B_FALSE;
51257836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_default =
51267836SJohn.Forte@Sun.COM ISCSI_DEFAULT_MAX_OUT_R2T;
51277836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_min = 1;
51287836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_max = ISCSI_MAX_OUTSTANDING_R2T;
51297836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_incr = 1;
51307836SJohn.Forte@Sun.COM break;
51317836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH:
51327836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_current =
51337836SJohn.Forte@Sun.COM params->max_recv_data_seg_len;
51347836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_default =
51357836SJohn.Forte@Sun.COM ISCSI_DEFAULT_MAX_RECV_SEG_LEN;
51367836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_min = 512;
51377836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_max =
51387836SJohn.Forte@Sun.COM ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH;
51397836SJohn.Forte@Sun.COM ipgp->g_value.v_integer.i_incr = 1;
51407836SJohn.Forte@Sun.COM break;
51417836SJohn.Forte@Sun.COM default:
51427836SJohn.Forte@Sun.COM rtn = EINVAL;
51437836SJohn.Forte@Sun.COM }
51447836SJohn.Forte@Sun.COM
51457836SJohn.Forte@Sun.COM return (rtn);
51467836SJohn.Forte@Sun.COM }
51477836SJohn.Forte@Sun.COM
51487836SJohn.Forte@Sun.COM /*
51497836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
51507836SJohn.Forte@Sun.COM * | End of ioctl utility routines |
51517836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+
51527836SJohn.Forte@Sun.COM */
51537836SJohn.Forte@Sun.COM
51547836SJohn.Forte@Sun.COM /*
51557836SJohn.Forte@Sun.COM * iscsi_get_name_from_iqn - Translates a normal iqn/eui into a
51567836SJohn.Forte@Sun.COM * IEEE safe address. IEEE addresses have a number of characters
51577836SJohn.Forte@Sun.COM * set aside as reserved.
51587836SJohn.Forte@Sun.COM */
51597836SJohn.Forte@Sun.COM static void
iscsi_get_name_from_iqn(char * name,int name_max_len)51607836SJohn.Forte@Sun.COM iscsi_get_name_from_iqn(char *name, int name_max_len)
51617836SJohn.Forte@Sun.COM {
51627836SJohn.Forte@Sun.COM char *tmp = NULL;
51637836SJohn.Forte@Sun.COM char *oldch = NULL;
51647836SJohn.Forte@Sun.COM char *newch = NULL;
51657836SJohn.Forte@Sun.COM
51667836SJohn.Forte@Sun.COM tmp = kmem_zalloc(MAX_GET_NAME_SIZE, KM_SLEEP);
51677836SJohn.Forte@Sun.COM
51687836SJohn.Forte@Sun.COM for (oldch = &name[0], newch = &tmp[0]; *oldch != '\0';
51697836SJohn.Forte@Sun.COM oldch++, newch++) {
51707836SJohn.Forte@Sun.COM switch (*oldch) {
51717836SJohn.Forte@Sun.COM case ':':
51727836SJohn.Forte@Sun.COM *newch++ = '%';
51737836SJohn.Forte@Sun.COM *newch++ = '3';
51747836SJohn.Forte@Sun.COM *newch = 'A';
51757836SJohn.Forte@Sun.COM break;
51767836SJohn.Forte@Sun.COM case ' ':
51777836SJohn.Forte@Sun.COM *newch++ = '%';
51787836SJohn.Forte@Sun.COM *newch++ = '2';
51797836SJohn.Forte@Sun.COM *newch = '0';
51807836SJohn.Forte@Sun.COM break;
51817836SJohn.Forte@Sun.COM case '@':
51827836SJohn.Forte@Sun.COM *newch++ = '%';
51837836SJohn.Forte@Sun.COM *newch++ = '4';
51847836SJohn.Forte@Sun.COM *newch = '0';
51857836SJohn.Forte@Sun.COM break;
51867836SJohn.Forte@Sun.COM case '/':
51877836SJohn.Forte@Sun.COM *newch++ = '%';
51887836SJohn.Forte@Sun.COM *newch++ = '2';
51897836SJohn.Forte@Sun.COM *newch = 'F';
51907836SJohn.Forte@Sun.COM break;
51917836SJohn.Forte@Sun.COM default:
51927836SJohn.Forte@Sun.COM *newch = *oldch;
51937836SJohn.Forte@Sun.COM }
51947836SJohn.Forte@Sun.COM }
51957836SJohn.Forte@Sun.COM (void) strncpy(name, tmp, name_max_len);
51967836SJohn.Forte@Sun.COM kmem_free(tmp, MAX_GET_NAME_SIZE);
51977836SJohn.Forte@Sun.COM }
51987836SJohn.Forte@Sun.COM
51997836SJohn.Forte@Sun.COM /*
52007836SJohn.Forte@Sun.COM * iscsi_get_name_to_iqn - Converts IEEE safe address back
52017836SJohn.Forte@Sun.COM * into a iscsi iqn/eui.
52027836SJohn.Forte@Sun.COM */
52037836SJohn.Forte@Sun.COM static void
iscsi_get_name_to_iqn(char * name,int name_max_len)52047836SJohn.Forte@Sun.COM iscsi_get_name_to_iqn(char *name, int name_max_len)
52057836SJohn.Forte@Sun.COM {
52067836SJohn.Forte@Sun.COM char *tmp = NULL;
52077836SJohn.Forte@Sun.COM char *oldch = NULL;
52087836SJohn.Forte@Sun.COM char *newch = NULL;
52097836SJohn.Forte@Sun.COM
52107836SJohn.Forte@Sun.COM tmp = kmem_zalloc(MAX_GET_NAME_SIZE, KM_SLEEP);
52117836SJohn.Forte@Sun.COM
52127836SJohn.Forte@Sun.COM for (oldch = &name[0], newch = &tmp[0]; *oldch != '\0';
52137836SJohn.Forte@Sun.COM oldch++, newch++) {
52147836SJohn.Forte@Sun.COM if (*oldch == '%') {
52157836SJohn.Forte@Sun.COM switch (*(oldch+1)) {
52167836SJohn.Forte@Sun.COM case '2':
52177836SJohn.Forte@Sun.COM if (*(oldch+2) == '0') {
52187836SJohn.Forte@Sun.COM *newch = ' ';
52197836SJohn.Forte@Sun.COM oldch += 2;
52207836SJohn.Forte@Sun.COM } else if (*(oldch+2) == 'F') {
52217836SJohn.Forte@Sun.COM *newch = '/';
52227836SJohn.Forte@Sun.COM oldch += 2;
52237836SJohn.Forte@Sun.COM } else {
52247836SJohn.Forte@Sun.COM *newch = *oldch;
52257836SJohn.Forte@Sun.COM }
52267836SJohn.Forte@Sun.COM break;
52277836SJohn.Forte@Sun.COM case '3':
52287836SJohn.Forte@Sun.COM if (*(oldch+2) == 'A') {
52297836SJohn.Forte@Sun.COM *newch = ':';
52307836SJohn.Forte@Sun.COM oldch += 2;
52317836SJohn.Forte@Sun.COM } else {
52327836SJohn.Forte@Sun.COM *newch = *oldch;
52337836SJohn.Forte@Sun.COM }
52347836SJohn.Forte@Sun.COM break;
52357836SJohn.Forte@Sun.COM case '4':
52367836SJohn.Forte@Sun.COM if (*(oldch+2) == '0') {
52377836SJohn.Forte@Sun.COM *newch = '@';
52387836SJohn.Forte@Sun.COM oldch += 2;
52397836SJohn.Forte@Sun.COM } else {
52407836SJohn.Forte@Sun.COM *newch = *oldch;
52417836SJohn.Forte@Sun.COM }
52427836SJohn.Forte@Sun.COM break;
52437836SJohn.Forte@Sun.COM default:
52447836SJohn.Forte@Sun.COM *newch = *oldch;
52457836SJohn.Forte@Sun.COM }
52467836SJohn.Forte@Sun.COM } else {
52477836SJohn.Forte@Sun.COM *newch = *oldch;
52487836SJohn.Forte@Sun.COM }
52497836SJohn.Forte@Sun.COM }
52507836SJohn.Forte@Sun.COM (void) strncpy(name, tmp, name_max_len);
52517836SJohn.Forte@Sun.COM kmem_free(tmp, MAX_GET_NAME_SIZE);
52527836SJohn.Forte@Sun.COM }
52537836SJohn.Forte@Sun.COM
52547836SJohn.Forte@Sun.COM /*
52557836SJohn.Forte@Sun.COM * iscsi_get_persisted_param * - a helper to ISCSI_GET_PARAM ioctl
52567836SJohn.Forte@Sun.COM *
52577836SJohn.Forte@Sun.COM * On return 0 means persisted parameter found
52587836SJohn.Forte@Sun.COM */
52597836SJohn.Forte@Sun.COM int
iscsi_get_persisted_param(uchar_t * name,iscsi_param_get_t * ipgp,iscsi_login_params_t * params)52607836SJohn.Forte@Sun.COM iscsi_get_persisted_param(uchar_t *name, iscsi_param_get_t *ipgp,
52617836SJohn.Forte@Sun.COM iscsi_login_params_t *params)
52627836SJohn.Forte@Sun.COM {
52637836SJohn.Forte@Sun.COM int rtn = 1;
52647836SJohn.Forte@Sun.COM persistent_param_t *pparam;
52657836SJohn.Forte@Sun.COM
52667836SJohn.Forte@Sun.COM if (name == NULL || strlen((char *)name) == 0) {
52677836SJohn.Forte@Sun.COM return (rtn);
52687836SJohn.Forte@Sun.COM }
52697836SJohn.Forte@Sun.COM
52707836SJohn.Forte@Sun.COM pparam = (persistent_param_t *)kmem_zalloc(sizeof (*pparam), KM_SLEEP);
52717836SJohn.Forte@Sun.COM
52727836SJohn.Forte@Sun.COM if (persistent_param_get((char *)name, pparam) == B_TRUE) {
52737836SJohn.Forte@Sun.COM if (pparam->p_bitmap & (1 << ipgp->g_param)) {
52747836SJohn.Forte@Sun.COM /* Found configured parameter. */
52757836SJohn.Forte@Sun.COM bcopy(&pparam->p_params, params, sizeof (*params));
52767836SJohn.Forte@Sun.COM rtn = 0;
52777836SJohn.Forte@Sun.COM }
52787836SJohn.Forte@Sun.COM }
52797836SJohn.Forte@Sun.COM
52807836SJohn.Forte@Sun.COM kmem_free(pparam, sizeof (*pparam));
52817836SJohn.Forte@Sun.COM
52827836SJohn.Forte@Sun.COM return (rtn);
52837836SJohn.Forte@Sun.COM }
52847836SJohn.Forte@Sun.COM
52857836SJohn.Forte@Sun.COM /*
52867836SJohn.Forte@Sun.COM * iscsi_override_target_default - helper function set the target's default
52877836SJohn.Forte@Sun.COM * login parameter if there is a configured initiator parameter.
52887836SJohn.Forte@Sun.COM *
52897836SJohn.Forte@Sun.COM */
52907836SJohn.Forte@Sun.COM static void
iscsi_override_target_default(iscsi_hba_t * ihp,iscsi_param_get_t * ipg)52917836SJohn.Forte@Sun.COM iscsi_override_target_default(iscsi_hba_t *ihp, iscsi_param_get_t *ipg)
52927836SJohn.Forte@Sun.COM {
52937836SJohn.Forte@Sun.COM persistent_param_t *pp;
52947836SJohn.Forte@Sun.COM iscsi_login_params_t *params;
52957836SJohn.Forte@Sun.COM
52967836SJohn.Forte@Sun.COM pp = (persistent_param_t *)kmem_zalloc(sizeof (*pp), KM_SLEEP);
52977836SJohn.Forte@Sun.COM if (persistent_param_get((char *)ihp->hba_name, pp) == B_TRUE) {
52987836SJohn.Forte@Sun.COM if (pp->p_bitmap & (1 << ipg->g_param)) {
52997836SJohn.Forte@Sun.COM params = &pp->p_params;
53007836SJohn.Forte@Sun.COM switch (ipg->g_param) {
53017836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER:
53027836SJohn.Forte@Sun.COM ipg->g_value.v_bool.b_default =
53037836SJohn.Forte@Sun.COM params->data_sequence_in_order;
53047836SJohn.Forte@Sun.COM break;
53057836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_IMMEDIATE_DATA:
53067836SJohn.Forte@Sun.COM ipg->g_value.v_bool.b_default =
53077836SJohn.Forte@Sun.COM params->immediate_data;
53087836SJohn.Forte@Sun.COM break;
53097836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_INITIAL_R2T:
53107836SJohn.Forte@Sun.COM ipg->g_value.v_bool.b_default =
53117836SJohn.Forte@Sun.COM params->initial_r2t;
53127836SJohn.Forte@Sun.COM break;
53137836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER:
53147836SJohn.Forte@Sun.COM ipg->g_value.v_bool.b_default =
53157836SJohn.Forte@Sun.COM params->data_pdu_in_order;
53167836SJohn.Forte@Sun.COM break;
53177836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_HEADER_DIGEST:
53187836SJohn.Forte@Sun.COM ipg->g_value.v_integer.i_default =
53197836SJohn.Forte@Sun.COM params->header_digest;
53207836SJohn.Forte@Sun.COM break;
53217836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_DATA_DIGEST:
53227836SJohn.Forte@Sun.COM ipg->g_value.v_integer.i_default =
53237836SJohn.Forte@Sun.COM params->data_digest;
53247836SJohn.Forte@Sun.COM break;
53257836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN:
53267836SJohn.Forte@Sun.COM ipg->g_value.v_integer.i_default =
53277836SJohn.Forte@Sun.COM params->default_time_to_retain;
53287836SJohn.Forte@Sun.COM break;
53297836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT:
53307836SJohn.Forte@Sun.COM ipg->g_value.v_integer.i_default =
53317836SJohn.Forte@Sun.COM params->default_time_to_wait;
53327836SJohn.Forte@Sun.COM break;
53337836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL:
53347836SJohn.Forte@Sun.COM ipg->g_value.v_integer.i_default =
53357836SJohn.Forte@Sun.COM params->error_recovery_level;
53367836SJohn.Forte@Sun.COM break;
53377836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH:
53387836SJohn.Forte@Sun.COM ipg->g_value.v_integer.i_default =
53397836SJohn.Forte@Sun.COM params->first_burst_length;
53407836SJohn.Forte@Sun.COM break;
53417836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH:
53427836SJohn.Forte@Sun.COM ipg->g_value.v_integer.i_default =
53437836SJohn.Forte@Sun.COM params->max_burst_length;
53447836SJohn.Forte@Sun.COM break;
53457836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_MAX_CONNECTIONS:
53467836SJohn.Forte@Sun.COM ipg->g_value.v_integer.i_default =
53477836SJohn.Forte@Sun.COM params->max_connections;
53487836SJohn.Forte@Sun.COM break;
53497836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_OUTSTANDING_R2T:
53507836SJohn.Forte@Sun.COM ipg->g_value.v_integer.i_default =
53517836SJohn.Forte@Sun.COM params->max_outstanding_r2t;
53527836SJohn.Forte@Sun.COM break;
53537836SJohn.Forte@Sun.COM case ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH:
53547836SJohn.Forte@Sun.COM ipg->g_value.v_integer.i_default =
53557836SJohn.Forte@Sun.COM params->max_xmit_data_seg_len;
53567836SJohn.Forte@Sun.COM break;
53577836SJohn.Forte@Sun.COM default:
53587836SJohn.Forte@Sun.COM break;
53597836SJohn.Forte@Sun.COM }
53607836SJohn.Forte@Sun.COM }
53617836SJohn.Forte@Sun.COM }
53627836SJohn.Forte@Sun.COM kmem_free(pp, sizeof (*pp));
53637836SJohn.Forte@Sun.COM }
53648194SJack.Meng@Sun.COM
53658194SJack.Meng@Sun.COM static boolean_t
iscsi_cmp_boot_sess_oid(iscsi_hba_t * ihp,uint32_t oid)53668194SJack.Meng@Sun.COM iscsi_cmp_boot_sess_oid(iscsi_hba_t *ihp, uint32_t oid)
53678194SJack.Meng@Sun.COM {
53688194SJack.Meng@Sun.COM iscsi_sess_t *isp = NULL;
53698194SJack.Meng@Sun.COM
53708194SJack.Meng@Sun.COM if (iscsi_chk_bootlun_mpxio(ihp)) {
53718194SJack.Meng@Sun.COM for (isp = ihp->hba_sess_list; isp; isp = isp->sess_next) {
53728194SJack.Meng@Sun.COM if ((isp->sess_oid == oid) && isp->sess_boot) {
53738194SJack.Meng@Sun.COM /* oid is session object */
53748194SJack.Meng@Sun.COM break;
53758194SJack.Meng@Sun.COM }
53768194SJack.Meng@Sun.COM if ((isp->sess_target_oid == oid) && isp->sess_boot) {
53778194SJack.Meng@Sun.COM /*
53788194SJack.Meng@Sun.COM * oid is target object while
53798194SJack.Meng@Sun.COM * this session is boot session
53808194SJack.Meng@Sun.COM */
53818194SJack.Meng@Sun.COM break;
53828194SJack.Meng@Sun.COM }
53838194SJack.Meng@Sun.COM }
53848194SJack.Meng@Sun.COM if (oid == ihp->hba_oid) {
53858194SJack.Meng@Sun.COM /* oid is initiator object id */
53868194SJack.Meng@Sun.COM return (B_TRUE);
53878194SJack.Meng@Sun.COM } else if ((isp != NULL) && (isp->sess_boot)) {
53888194SJack.Meng@Sun.COM /* oid is boot session object id */
53898194SJack.Meng@Sun.COM return (B_TRUE);
53908194SJack.Meng@Sun.COM }
53918194SJack.Meng@Sun.COM }
53928194SJack.Meng@Sun.COM return (B_FALSE);
53938194SJack.Meng@Sun.COM }
53949201SJack.Meng@Sun.COM
53959201SJack.Meng@Sun.COM /*
53969201SJack.Meng@Sun.COM * iscsi_client_request_service - request the iSCSI service
53979201SJack.Meng@Sun.COM * returns true if the service is enabled and increases the count
53989201SJack.Meng@Sun.COM * returns false if the service is disabled
53999201SJack.Meng@Sun.COM * blocks until the service status is either enabled or disabled
54009201SJack.Meng@Sun.COM */
54019201SJack.Meng@Sun.COM boolean_t
iscsi_client_request_service(iscsi_hba_t * ihp)54029201SJack.Meng@Sun.COM iscsi_client_request_service(iscsi_hba_t *ihp) {
54039201SJack.Meng@Sun.COM boolean_t rval = B_TRUE;
54049201SJack.Meng@Sun.COM
54059201SJack.Meng@Sun.COM mutex_enter(&ihp->hba_service_lock);
54069201SJack.Meng@Sun.COM while ((ihp->hba_service_status == ISCSI_SERVICE_TRANSITION) ||
54079201SJack.Meng@Sun.COM (ihp->hba_service_client_count == UINT_MAX)) {
54089201SJack.Meng@Sun.COM cv_wait(&ihp->hba_service_cv, &ihp->hba_service_lock);
54099201SJack.Meng@Sun.COM }
54109201SJack.Meng@Sun.COM if (ihp->hba_service_status == ISCSI_SERVICE_ENABLED) {
54119201SJack.Meng@Sun.COM ihp->hba_service_client_count++;
54129201SJack.Meng@Sun.COM } else {
54139201SJack.Meng@Sun.COM rval = B_FALSE;
54149201SJack.Meng@Sun.COM }
54159201SJack.Meng@Sun.COM mutex_exit(&ihp->hba_service_lock);
54169201SJack.Meng@Sun.COM
54179201SJack.Meng@Sun.COM return (rval);
54189201SJack.Meng@Sun.COM }
54199201SJack.Meng@Sun.COM
54209201SJack.Meng@Sun.COM /*
54219201SJack.Meng@Sun.COM * iscsi_client_release_service - decrease the count and wake up
54229201SJack.Meng@Sun.COM * blocking threads if the count reaches zero
54239201SJack.Meng@Sun.COM */
54249201SJack.Meng@Sun.COM void
iscsi_client_release_service(iscsi_hba_t * ihp)54259201SJack.Meng@Sun.COM iscsi_client_release_service(iscsi_hba_t *ihp) {
54269201SJack.Meng@Sun.COM mutex_enter(&ihp->hba_service_lock);
54279201SJack.Meng@Sun.COM ASSERT(ihp->hba_service_client_count > 0);
54289201SJack.Meng@Sun.COM ihp->hba_service_client_count--;
54299201SJack.Meng@Sun.COM if (ihp->hba_service_client_count == 0) {
54309201SJack.Meng@Sun.COM cv_broadcast(&ihp->hba_service_cv);
54319201SJack.Meng@Sun.COM }
54329201SJack.Meng@Sun.COM mutex_exit(&ihp->hba_service_lock);
54339201SJack.Meng@Sun.COM }
54349201SJack.Meng@Sun.COM
54359201SJack.Meng@Sun.COM /*
54369201SJack.Meng@Sun.COM * iscsi_enter_service_zone - enter the service zone, should be called
54379201SJack.Meng@Sun.COM * before doing any modifications to the service status
54389201SJack.Meng@Sun.COM * return TRUE if the zone is entered
54399201SJack.Meng@Sun.COM * FALSE if no need to enter the zone
54409201SJack.Meng@Sun.COM */
54419201SJack.Meng@Sun.COM static boolean_t
iscsi_enter_service_zone(iscsi_hba_t * ihp,uint32_t status)54429201SJack.Meng@Sun.COM iscsi_enter_service_zone(iscsi_hba_t *ihp, uint32_t status) {
54439201SJack.Meng@Sun.COM if ((status != ISCSI_SERVICE_ENABLED) &&
54449201SJack.Meng@Sun.COM (status != ISCSI_SERVICE_DISABLED)) {
54459201SJack.Meng@Sun.COM return (B_FALSE);
54469201SJack.Meng@Sun.COM }
54479201SJack.Meng@Sun.COM
54489201SJack.Meng@Sun.COM mutex_enter(&ihp->hba_service_lock);
54499201SJack.Meng@Sun.COM while (ihp->hba_service_status == ISCSI_SERVICE_TRANSITION) {
54509201SJack.Meng@Sun.COM cv_wait(&ihp->hba_service_cv, &ihp->hba_service_lock);
54519201SJack.Meng@Sun.COM }
54529201SJack.Meng@Sun.COM if (ihp->hba_service_status == status) {
54539201SJack.Meng@Sun.COM mutex_exit(&ihp->hba_service_lock);
54549201SJack.Meng@Sun.COM return (B_FALSE);
54559201SJack.Meng@Sun.COM }
54569201SJack.Meng@Sun.COM ihp->hba_service_status = ISCSI_SERVICE_TRANSITION;
54579201SJack.Meng@Sun.COM while (ihp->hba_service_client_count > 0) {
54589201SJack.Meng@Sun.COM cv_wait(&ihp->hba_service_cv, &ihp->hba_service_lock);
54599201SJack.Meng@Sun.COM }
54609201SJack.Meng@Sun.COM mutex_exit(&ihp->hba_service_lock);
54619201SJack.Meng@Sun.COM return (B_TRUE);
54629201SJack.Meng@Sun.COM }
54639201SJack.Meng@Sun.COM
54649201SJack.Meng@Sun.COM /*
54659201SJack.Meng@Sun.COM * iscsi_exit_service_zone - exits the service zone and wakes up waiters
54669201SJack.Meng@Sun.COM */
54679201SJack.Meng@Sun.COM static void
iscsi_exit_service_zone(iscsi_hba_t * ihp,uint32_t status)54689201SJack.Meng@Sun.COM iscsi_exit_service_zone(iscsi_hba_t *ihp, uint32_t status) {
54699201SJack.Meng@Sun.COM if ((status != ISCSI_SERVICE_ENABLED) &&
54709201SJack.Meng@Sun.COM (status != ISCSI_SERVICE_DISABLED)) {
54719201SJack.Meng@Sun.COM return;
54729201SJack.Meng@Sun.COM }
54739201SJack.Meng@Sun.COM
54749201SJack.Meng@Sun.COM mutex_enter(&ihp->hba_service_lock);
54759201SJack.Meng@Sun.COM ASSERT(ihp->hba_service_status == ISCSI_SERVICE_TRANSITION);
54769201SJack.Meng@Sun.COM ihp->hba_service_status = status;
54779201SJack.Meng@Sun.COM cv_broadcast(&ihp->hba_service_cv);
54789201SJack.Meng@Sun.COM mutex_exit(&ihp->hba_service_lock);
54799201SJack.Meng@Sun.COM }
54809201SJack.Meng@Sun.COM
54819201SJack.Meng@Sun.COM static void
iscsi_check_miniroot(iscsi_hba_t * ihp)54829201SJack.Meng@Sun.COM iscsi_check_miniroot(iscsi_hba_t *ihp) {
54839201SJack.Meng@Sun.COM if (strncmp(rootfs.bo_name, "/ramdisk", 8) == 0) {
54849201SJack.Meng@Sun.COM /*
54859201SJack.Meng@Sun.COM * in miniroot we don't have the persistent store
54869201SJack.Meng@Sun.COM * so just to need to ensure an enabled status
54879201SJack.Meng@Sun.COM */
54889201SJack.Meng@Sun.COM ihp->hba_service_status = ISCSI_SERVICE_ENABLED;
54899201SJack.Meng@Sun.COM }
54909201SJack.Meng@Sun.COM }
549110156SZhang.Yi@Sun.COM
549210156SZhang.Yi@Sun.COM static void
iscsi_get_tunable_default(iscsi_tunable_object_t * param)549310156SZhang.Yi@Sun.COM iscsi_get_tunable_default(iscsi_tunable_object_t *param) {
549410156SZhang.Yi@Sun.COM int param_id = 0;
549510156SZhang.Yi@Sun.COM
549610156SZhang.Yi@Sun.COM param_id = 1 << (param->t_param - 1);
549710156SZhang.Yi@Sun.COM param->t_set = B_FALSE;
549810156SZhang.Yi@Sun.COM switch (param_id) {
549910156SZhang.Yi@Sun.COM case ISCSI_TUNABLE_PARAM_RX_TIMEOUT_VALUE:
550010156SZhang.Yi@Sun.COM param->t_value.v_integer = ISCSI_DEFAULT_RX_TIMEOUT_VALUE;
550110156SZhang.Yi@Sun.COM break;
550210156SZhang.Yi@Sun.COM case ISCSI_TUNABLE_PARAM_LOGIN_POLLING_DELAY:
550310156SZhang.Yi@Sun.COM param->t_value.v_integer = ISCSI_DEFAULT_LOGIN_POLLING_DELAY;
550410156SZhang.Yi@Sun.COM break;
550510156SZhang.Yi@Sun.COM case ISCSI_TUNABLE_PARAM_CONN_LOGIN_MAX:
550610156SZhang.Yi@Sun.COM param->t_value.v_integer = ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX;
550710156SZhang.Yi@Sun.COM break;
550810156SZhang.Yi@Sun.COM default:
550910156SZhang.Yi@Sun.COM break;
551010156SZhang.Yi@Sun.COM }
551110156SZhang.Yi@Sun.COM }
551210156SZhang.Yi@Sun.COM
551310156SZhang.Yi@Sun.COM /*
551410156SZhang.Yi@Sun.COM * iscsi_get_persisted_tunable_param * - a helper to ISCSI_TUNABLE_PARAM_GET
551510156SZhang.Yi@Sun.COM * ioctl
551610156SZhang.Yi@Sun.COM * return:
551710156SZhang.Yi@Sun.COM * 0 persisted tunable parameter found
551810156SZhang.Yi@Sun.COM * 1 persisted tunable parameter not found
551910156SZhang.Yi@Sun.COM */
552010156SZhang.Yi@Sun.COM static int
iscsi_get_persisted_tunable_param(uchar_t * name,iscsi_tunable_object_t * tpsg)552110156SZhang.Yi@Sun.COM iscsi_get_persisted_tunable_param(uchar_t *name, iscsi_tunable_object_t *tpsg)
552210156SZhang.Yi@Sun.COM {
552310156SZhang.Yi@Sun.COM int rtn = 1;
552410156SZhang.Yi@Sun.COM int param_id = 0;
552510156SZhang.Yi@Sun.COM persistent_tunable_param_t *pparam;
552610156SZhang.Yi@Sun.COM
552710156SZhang.Yi@Sun.COM if ((name == NULL) || strlen((char *)name) == 0) {
552810156SZhang.Yi@Sun.COM return (rtn);
552910156SZhang.Yi@Sun.COM }
553010156SZhang.Yi@Sun.COM
553110156SZhang.Yi@Sun.COM tpsg->t_set = B_FALSE;
553210156SZhang.Yi@Sun.COM pparam = (persistent_tunable_param_t *)kmem_zalloc(sizeof (*pparam),
553310156SZhang.Yi@Sun.COM KM_SLEEP);
553410156SZhang.Yi@Sun.COM if (persistent_get_tunable_param((char *)name, pparam) == B_TRUE) {
553510156SZhang.Yi@Sun.COM if (pparam->p_bitmap & (1 << (tpsg->t_param - 1))) {
553610156SZhang.Yi@Sun.COM tpsg->t_set = B_TRUE;
553710156SZhang.Yi@Sun.COM param_id = 1 << (tpsg->t_param - 1);
553810156SZhang.Yi@Sun.COM switch (param_id) {
553910156SZhang.Yi@Sun.COM case ISCSI_TUNABLE_PARAM_RX_TIMEOUT_VALUE:
554010156SZhang.Yi@Sun.COM tpsg->t_value.v_integer =
554110156SZhang.Yi@Sun.COM pparam->p_params.recv_login_rsp_timeout;
554210156SZhang.Yi@Sun.COM break;
554310156SZhang.Yi@Sun.COM case ISCSI_TUNABLE_PARAM_LOGIN_POLLING_DELAY:
554410156SZhang.Yi@Sun.COM tpsg->t_value.v_integer =
554510156SZhang.Yi@Sun.COM pparam->p_params.polling_login_delay;
554610156SZhang.Yi@Sun.COM break;
554710156SZhang.Yi@Sun.COM case ISCSI_TUNABLE_PARAM_CONN_LOGIN_MAX:
554810156SZhang.Yi@Sun.COM tpsg->t_value.v_integer =
554910156SZhang.Yi@Sun.COM pparam->p_params.conn_login_max;
555010156SZhang.Yi@Sun.COM break;
555110156SZhang.Yi@Sun.COM default:
555210156SZhang.Yi@Sun.COM break;
555310156SZhang.Yi@Sun.COM }
555410156SZhang.Yi@Sun.COM rtn = 0;
555510156SZhang.Yi@Sun.COM }
555610156SZhang.Yi@Sun.COM }
555710156SZhang.Yi@Sun.COM
555810156SZhang.Yi@Sun.COM kmem_free(pparam, sizeof (*pparam));
555910156SZhang.Yi@Sun.COM
556010156SZhang.Yi@Sun.COM return (rtn);
556110156SZhang.Yi@Sun.COM }
5562