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 /*
22*12571SViswanathan.Kannappan@Sun.COM * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
237836SJohn.Forte@Sun.COM */
247836SJohn.Forte@Sun.COM
257836SJohn.Forte@Sun.COM #include <sys/conf.h>
267836SJohn.Forte@Sun.COM #include <sys/file.h>
277836SJohn.Forte@Sun.COM #include <sys/ddi.h>
287836SJohn.Forte@Sun.COM #include <sys/sunddi.h>
297836SJohn.Forte@Sun.COM #include <sys/modctl.h>
307836SJohn.Forte@Sun.COM #include <sys/scsi/scsi.h>
317836SJohn.Forte@Sun.COM #include <sys/scsi/impl/scsi_reset_notify.h>
327836SJohn.Forte@Sun.COM #include <sys/disp.h>
337836SJohn.Forte@Sun.COM #include <sys/byteorder.h>
347836SJohn.Forte@Sun.COM #include <sys/atomic.h>
357836SJohn.Forte@Sun.COM
36*12571SViswanathan.Kannappan@Sun.COM #include <sys/stmf.h>
37*12571SViswanathan.Kannappan@Sun.COM #include <sys/lpif.h>
38*12571SViswanathan.Kannappan@Sun.COM #include <sys/portif.h>
39*12571SViswanathan.Kannappan@Sun.COM #include <sys/stmf_ioctl.h>
40*12571SViswanathan.Kannappan@Sun.COM
417836SJohn.Forte@Sun.COM #include "stmf_impl.h"
427836SJohn.Forte@Sun.COM #include "lun_map.h"
437836SJohn.Forte@Sun.COM #include "stmf_state.h"
447836SJohn.Forte@Sun.COM
457836SJohn.Forte@Sun.COM void stmf_update_sessions_per_ve(stmf_view_entry_t *ve,
467836SJohn.Forte@Sun.COM stmf_lu_t *lu, int action);
477836SJohn.Forte@Sun.COM void stmf_add_lus_to_session_per_vemap(stmf_i_local_port_t *ilport,
487836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss, stmf_lun_map_t *vemap);
497836SJohn.Forte@Sun.COM stmf_id_data_t *stmf_lookup_group_for_host(uint8_t *ident, uint16_t ident_size);
507836SJohn.Forte@Sun.COM stmf_status_t stmf_add_ent_to_map(stmf_lun_map_t *sm, void *ent, uint8_t *lun);
517836SJohn.Forte@Sun.COM stmf_status_t stmf_remove_ent_from_map(stmf_lun_map_t *sm, uint8_t *lun);
527836SJohn.Forte@Sun.COM uint16_t stmf_get_next_free_lun(stmf_lun_map_t *sm, uint8_t *lun);
537836SJohn.Forte@Sun.COM stmf_status_t stmf_add_tg(uint8_t *tg_name, uint16_t tg_name_size,
547836SJohn.Forte@Sun.COM int allow_special, uint32_t *err_detail);
557836SJohn.Forte@Sun.COM stmf_status_t stmf_add_hg(uint8_t *hg_name, uint16_t hg_name_size,
567836SJohn.Forte@Sun.COM int allow_special, uint32_t *err_detail);
577836SJohn.Forte@Sun.COM stmf_i_local_port_t *stmf_targetident_to_ilport(uint8_t *target_ident,
587836SJohn.Forte@Sun.COM uint16_t ident_size);
597836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *stmf_lookup_session_for_hostident(
607836SJohn.Forte@Sun.COM stmf_i_local_port_t *ilport, uint8_t *host_ident,
617836SJohn.Forte@Sun.COM uint16_t ident_size);
627836SJohn.Forte@Sun.COM stmf_i_lu_t *stmf_luident_to_ilu(uint8_t *lu_ident);
637836SJohn.Forte@Sun.COM stmf_lun_map_t *stmf_get_ve_map_per_ids(stmf_id_data_t *tgid,
647836SJohn.Forte@Sun.COM stmf_id_data_t *hgid);
657836SJohn.Forte@Sun.COM stmf_lun_map_t *stmf_duplicate_ve_map(stmf_lun_map_t *src);
667836SJohn.Forte@Sun.COM int stmf_merge_ve_map(stmf_lun_map_t *src, stmf_lun_map_t *dst,
677836SJohn.Forte@Sun.COM stmf_lun_map_t **pp_ret_map, stmf_merge_flags_t mf);
687836SJohn.Forte@Sun.COM void stmf_destroy_ve_map(stmf_lun_map_t *dst);
697836SJohn.Forte@Sun.COM void stmf_free_id(stmf_id_data_t *id);
707836SJohn.Forte@Sun.COM
717836SJohn.Forte@Sun.COM
727836SJohn.Forte@Sun.COM /*
737836SJohn.Forte@Sun.COM * Init the view
747836SJohn.Forte@Sun.COM */
757836SJohn.Forte@Sun.COM void
stmf_view_init()767836SJohn.Forte@Sun.COM stmf_view_init()
777836SJohn.Forte@Sun.COM {
787836SJohn.Forte@Sun.COM uint8_t grpname_forall = '*';
797836SJohn.Forte@Sun.COM (void) stmf_add_hg(&grpname_forall, 1, 1, NULL);
807836SJohn.Forte@Sun.COM (void) stmf_add_tg(&grpname_forall, 1, 1, NULL);
817836SJohn.Forte@Sun.COM }
827836SJohn.Forte@Sun.COM
837836SJohn.Forte@Sun.COM /*
847836SJohn.Forte@Sun.COM * Clear config database here
857836SJohn.Forte@Sun.COM */
867836SJohn.Forte@Sun.COM void
stmf_view_clear_config()877836SJohn.Forte@Sun.COM stmf_view_clear_config()
887836SJohn.Forte@Sun.COM {
897836SJohn.Forte@Sun.COM stmf_id_data_t *idgrp, *idgrp_next, *idmemb, *idmemb_next;
907836SJohn.Forte@Sun.COM stmf_ver_tg_t *vtg, *vtg_next;
917836SJohn.Forte@Sun.COM stmf_ver_hg_t *vhg, *vhg_next;
927836SJohn.Forte@Sun.COM stmf_view_entry_t *ve, *ve_next;
937836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu;
947836SJohn.Forte@Sun.COM stmf_id_list_t *idlist;
957836SJohn.Forte@Sun.COM stmf_i_local_port_t *ilport;
967836SJohn.Forte@Sun.COM
977836SJohn.Forte@Sun.COM for (vtg = stmf_state.stmf_ver_tg_head; vtg; vtg = vtg_next) {
987836SJohn.Forte@Sun.COM for (vhg = vtg->vert_verh_list; vhg; vhg = vhg_next) {
997836SJohn.Forte@Sun.COM if (vhg->verh_ve_map.lm_nentries) {
1007836SJohn.Forte@Sun.COM kmem_free(vhg->verh_ve_map.lm_plus,
1017836SJohn.Forte@Sun.COM vhg->verh_ve_map.lm_nentries *
1027836SJohn.Forte@Sun.COM sizeof (void *));
1037836SJohn.Forte@Sun.COM }
1047836SJohn.Forte@Sun.COM vhg_next = vhg->verh_next;
1057836SJohn.Forte@Sun.COM kmem_free(vhg, sizeof (stmf_ver_hg_t));
1067836SJohn.Forte@Sun.COM }
1077836SJohn.Forte@Sun.COM vtg_next = vtg->vert_next;
1087836SJohn.Forte@Sun.COM kmem_free(vtg, sizeof (stmf_ver_tg_t));
1097836SJohn.Forte@Sun.COM }
1107836SJohn.Forte@Sun.COM stmf_state.stmf_ver_tg_head = NULL;
1117836SJohn.Forte@Sun.COM
1127836SJohn.Forte@Sun.COM if (stmf_state.stmf_luid_list.id_count) {
1137836SJohn.Forte@Sun.COM /* clear the views for lus */
1147836SJohn.Forte@Sun.COM for (idmemb = stmf_state.stmf_luid_list.idl_head;
1157836SJohn.Forte@Sun.COM idmemb; idmemb = idmemb_next) {
1167836SJohn.Forte@Sun.COM for (ve = (stmf_view_entry_t *)idmemb->id_impl_specific;
1177836SJohn.Forte@Sun.COM ve; ve = ve_next) {
1187836SJohn.Forte@Sun.COM ve_next = ve->ve_next;
1197836SJohn.Forte@Sun.COM ve->ve_hg->id_refcnt--;
1207836SJohn.Forte@Sun.COM ve->ve_tg->id_refcnt--;
1217836SJohn.Forte@Sun.COM kmem_free(ve, sizeof (stmf_view_entry_t));
1227836SJohn.Forte@Sun.COM }
1237836SJohn.Forte@Sun.COM if (idmemb->id_pt_to_object) {
1247836SJohn.Forte@Sun.COM ilu = (stmf_i_lu_t *)(idmemb->id_pt_to_object);
1257836SJohn.Forte@Sun.COM ilu->ilu_luid = NULL;
1267836SJohn.Forte@Sun.COM }
1277836SJohn.Forte@Sun.COM idmemb_next = idmemb->id_next;
1287836SJohn.Forte@Sun.COM stmf_free_id(idmemb);
1297836SJohn.Forte@Sun.COM }
1307836SJohn.Forte@Sun.COM stmf_state.stmf_luid_list.id_count = 0;
1317836SJohn.Forte@Sun.COM stmf_state.stmf_luid_list.idl_head =
1327836SJohn.Forte@Sun.COM stmf_state.stmf_luid_list.idl_tail = NULL;
1337836SJohn.Forte@Sun.COM }
1347836SJohn.Forte@Sun.COM
1357836SJohn.Forte@Sun.COM if (stmf_state.stmf_hg_list.id_count) {
1367836SJohn.Forte@Sun.COM /* free all the host group */
1377836SJohn.Forte@Sun.COM for (idgrp = stmf_state.stmf_hg_list.idl_head;
1387836SJohn.Forte@Sun.COM idgrp; idgrp = idgrp_next) {
1397836SJohn.Forte@Sun.COM idlist = (stmf_id_list_t *)(idgrp->id_impl_specific);
1407836SJohn.Forte@Sun.COM if (idlist->id_count) {
1417836SJohn.Forte@Sun.COM for (idmemb = idlist->idl_head; idmemb;
1427836SJohn.Forte@Sun.COM idmemb = idmemb_next) {
1437836SJohn.Forte@Sun.COM idmemb_next = idmemb->id_next;
1447836SJohn.Forte@Sun.COM stmf_free_id(idmemb);
1457836SJohn.Forte@Sun.COM }
1467836SJohn.Forte@Sun.COM }
1477836SJohn.Forte@Sun.COM idgrp_next = idgrp->id_next;
1487836SJohn.Forte@Sun.COM stmf_free_id(idgrp);
1497836SJohn.Forte@Sun.COM }
1507836SJohn.Forte@Sun.COM stmf_state.stmf_hg_list.id_count = 0;
1517836SJohn.Forte@Sun.COM stmf_state.stmf_hg_list.idl_head =
1527836SJohn.Forte@Sun.COM stmf_state.stmf_hg_list.idl_tail = NULL;
1537836SJohn.Forte@Sun.COM }
1547836SJohn.Forte@Sun.COM if (stmf_state.stmf_tg_list.id_count) {
1557836SJohn.Forte@Sun.COM /* free all the target group */
1567836SJohn.Forte@Sun.COM for (idgrp = stmf_state.stmf_tg_list.idl_head;
1577836SJohn.Forte@Sun.COM idgrp; idgrp = idgrp_next) {
1587836SJohn.Forte@Sun.COM idlist = (stmf_id_list_t *)(idgrp->id_impl_specific);
1597836SJohn.Forte@Sun.COM if (idlist->id_count) {
1607836SJohn.Forte@Sun.COM for (idmemb = idlist->idl_head; idmemb;
1617836SJohn.Forte@Sun.COM idmemb = idmemb_next) {
1627836SJohn.Forte@Sun.COM idmemb_next = idmemb->id_next;
1637836SJohn.Forte@Sun.COM stmf_free_id(idmemb);
1647836SJohn.Forte@Sun.COM }
1657836SJohn.Forte@Sun.COM }
1667836SJohn.Forte@Sun.COM idgrp_next = idgrp->id_next;
1677836SJohn.Forte@Sun.COM stmf_free_id(idgrp);
1687836SJohn.Forte@Sun.COM }
1697836SJohn.Forte@Sun.COM stmf_state.stmf_tg_list.id_count = 0;
1707836SJohn.Forte@Sun.COM stmf_state.stmf_tg_list.idl_head =
1717836SJohn.Forte@Sun.COM stmf_state.stmf_tg_list.idl_tail = NULL;
1727836SJohn.Forte@Sun.COM }
1737836SJohn.Forte@Sun.COM
1747836SJohn.Forte@Sun.COM for (ilport = stmf_state.stmf_ilportlist; ilport;
1757836SJohn.Forte@Sun.COM ilport = ilport->ilport_next) {
1767836SJohn.Forte@Sun.COM ilport->ilport_tg = NULL;
1777836SJohn.Forte@Sun.COM }
1787836SJohn.Forte@Sun.COM }
1797836SJohn.Forte@Sun.COM
1807836SJohn.Forte@Sun.COM /*
1817836SJohn.Forte@Sun.COM * Create luns map for session based on the view
1827836SJohn.Forte@Sun.COM */
1837836SJohn.Forte@Sun.COM stmf_status_t
stmf_session_create_lun_map(stmf_i_local_port_t * ilport,stmf_i_scsi_session_t * iss)1847836SJohn.Forte@Sun.COM stmf_session_create_lun_map(stmf_i_local_port_t *ilport,
1857836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss)
1867836SJohn.Forte@Sun.COM {
1877836SJohn.Forte@Sun.COM stmf_id_data_t *tg;
1887836SJohn.Forte@Sun.COM stmf_id_data_t *hg;
1897836SJohn.Forte@Sun.COM stmf_ver_tg_t *vertg;
1907836SJohn.Forte@Sun.COM char *phg_data, *ptg_data;
1917836SJohn.Forte@Sun.COM stmf_ver_hg_t *verhg;
1927836SJohn.Forte@Sun.COM stmf_lun_map_t *ve_map;
1937836SJohn.Forte@Sun.COM
19411978STim.Szeto@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
19511978STim.Szeto@Sun.COM
1967836SJohn.Forte@Sun.COM tg = ilport->ilport_tg;
1977836SJohn.Forte@Sun.COM hg = stmf_lookup_group_for_host(iss->iss_ss->ss_rport_id->ident,
1987836SJohn.Forte@Sun.COM iss->iss_ss->ss_rport_id->ident_length);
1997836SJohn.Forte@Sun.COM iss->iss_hg = hg;
2007836SJohn.Forte@Sun.COM
2017836SJohn.Forte@Sun.COM /*
2027836SJohn.Forte@Sun.COM * get the view entry map,
2037836SJohn.Forte@Sun.COM * take all host/target group into consideration
2047836SJohn.Forte@Sun.COM */
2057836SJohn.Forte@Sun.COM ve_map = stmf_duplicate_ve_map(0);
2067836SJohn.Forte@Sun.COM for (vertg = stmf_state.stmf_ver_tg_head; vertg != NULL;
2077836SJohn.Forte@Sun.COM vertg = vertg->vert_next) {
2087836SJohn.Forte@Sun.COM ptg_data = (char *)vertg->vert_tg_ref->id_data;
2097836SJohn.Forte@Sun.COM if ((ptg_data[0] != '*') && (!tg ||
2107836SJohn.Forte@Sun.COM ((tg->id_data[0] != '*') &&
2117836SJohn.Forte@Sun.COM (vertg->vert_tg_ref != tg)))) {
2127836SJohn.Forte@Sun.COM continue;
2137836SJohn.Forte@Sun.COM }
2147836SJohn.Forte@Sun.COM for (verhg = vertg->vert_verh_list; verhg != NULL;
2157836SJohn.Forte@Sun.COM verhg = verhg->verh_next) {
2167836SJohn.Forte@Sun.COM phg_data = (char *)verhg->verh_hg_ref->id_data;
2177836SJohn.Forte@Sun.COM if ((phg_data[0] != '*') && (!hg ||
2187836SJohn.Forte@Sun.COM ((hg->id_data[0] != '*') &&
2197836SJohn.Forte@Sun.COM (verhg->verh_hg_ref != hg)))) {
2207836SJohn.Forte@Sun.COM continue;
2217836SJohn.Forte@Sun.COM }
2227836SJohn.Forte@Sun.COM (void) stmf_merge_ve_map(&verhg->verh_ve_map, ve_map,
2237836SJohn.Forte@Sun.COM &ve_map, 0);
2247836SJohn.Forte@Sun.COM }
2257836SJohn.Forte@Sun.COM }
2267836SJohn.Forte@Sun.COM
2277836SJohn.Forte@Sun.COM
2287836SJohn.Forte@Sun.COM if (ve_map->lm_nluns) {
2297836SJohn.Forte@Sun.COM stmf_add_lus_to_session_per_vemap(ilport, iss, ve_map);
2307836SJohn.Forte@Sun.COM }
2317836SJohn.Forte@Sun.COM /* not configured, cannot access any luns for now */
2327836SJohn.Forte@Sun.COM
2337836SJohn.Forte@Sun.COM stmf_destroy_ve_map(ve_map);
2347836SJohn.Forte@Sun.COM
2357836SJohn.Forte@Sun.COM return (STMF_SUCCESS);
2367836SJohn.Forte@Sun.COM }
2377836SJohn.Forte@Sun.COM
2387836SJohn.Forte@Sun.COM /*
2397836SJohn.Forte@Sun.COM * destroy lun map for session
2407836SJohn.Forte@Sun.COM */
2417836SJohn.Forte@Sun.COM /* ARGSUSED */
2427836SJohn.Forte@Sun.COM stmf_status_t
stmf_session_destroy_lun_map(stmf_i_local_port_t * ilport,stmf_i_scsi_session_t * iss)2437836SJohn.Forte@Sun.COM stmf_session_destroy_lun_map(stmf_i_local_port_t *ilport,
2447836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss)
2457836SJohn.Forte@Sun.COM {
2467836SJohn.Forte@Sun.COM stmf_lun_map_t *sm;
2477836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu;
2487836SJohn.Forte@Sun.COM uint16_t n;
2497836SJohn.Forte@Sun.COM stmf_lun_map_ent_t *ent;
2507836SJohn.Forte@Sun.COM
25111978STim.Szeto@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
2527836SJohn.Forte@Sun.COM /*
2537836SJohn.Forte@Sun.COM * to avoid conflict with updating session's map,
2547836SJohn.Forte@Sun.COM * which only grab stmf_lock
2557836SJohn.Forte@Sun.COM */
2567836SJohn.Forte@Sun.COM sm = iss->iss_sm;
2577836SJohn.Forte@Sun.COM iss->iss_sm = NULL;
2587836SJohn.Forte@Sun.COM iss->iss_hg = NULL;
2597836SJohn.Forte@Sun.COM if (sm->lm_nentries) {
2607836SJohn.Forte@Sun.COM for (n = 0; n < sm->lm_nentries; n++) {
2617836SJohn.Forte@Sun.COM if ((ent = (stmf_lun_map_ent_t *)sm->lm_plus[n])
2627836SJohn.Forte@Sun.COM != NULL) {
2637836SJohn.Forte@Sun.COM if (ent->ent_itl_datap) {
2647836SJohn.Forte@Sun.COM stmf_do_itl_dereg(ent->ent_lu,
2657836SJohn.Forte@Sun.COM ent->ent_itl_datap,
2667836SJohn.Forte@Sun.COM STMF_ITL_REASON_IT_NEXUS_LOSS);
2677836SJohn.Forte@Sun.COM }
2687836SJohn.Forte@Sun.COM ilu = (stmf_i_lu_t *)
2697836SJohn.Forte@Sun.COM ent->ent_lu->lu_stmf_private;
2707836SJohn.Forte@Sun.COM atomic_add_32(&ilu->ilu_ref_cnt, -1);
2717836SJohn.Forte@Sun.COM kmem_free(sm->lm_plus[n],
2727836SJohn.Forte@Sun.COM sizeof (stmf_lun_map_ent_t));
2737836SJohn.Forte@Sun.COM }
2747836SJohn.Forte@Sun.COM }
2757836SJohn.Forte@Sun.COM kmem_free(sm->lm_plus,
2767836SJohn.Forte@Sun.COM sizeof (stmf_lun_map_ent_t *) * sm->lm_nentries);
2777836SJohn.Forte@Sun.COM }
2787836SJohn.Forte@Sun.COM
2797836SJohn.Forte@Sun.COM kmem_free(sm, sizeof (*sm));
2807836SJohn.Forte@Sun.COM return (STMF_SUCCESS);
2817836SJohn.Forte@Sun.COM }
2827836SJohn.Forte@Sun.COM
2837836SJohn.Forte@Sun.COM /*
2847836SJohn.Forte@Sun.COM * Expects the session lock to be held.
2857836SJohn.Forte@Sun.COM */
2867836SJohn.Forte@Sun.COM stmf_xfer_data_t *
stmf_session_prepare_report_lun_data(stmf_lun_map_t * sm)2877836SJohn.Forte@Sun.COM stmf_session_prepare_report_lun_data(stmf_lun_map_t *sm)
2887836SJohn.Forte@Sun.COM {
2897836SJohn.Forte@Sun.COM stmf_xfer_data_t *xd;
2907836SJohn.Forte@Sun.COM uint16_t nluns, ent;
2917836SJohn.Forte@Sun.COM uint32_t alloc_size, data_size;
2927836SJohn.Forte@Sun.COM int i;
2937836SJohn.Forte@Sun.COM
2947836SJohn.Forte@Sun.COM nluns = sm->lm_nluns;
2957836SJohn.Forte@Sun.COM
2967836SJohn.Forte@Sun.COM data_size = 8 + (((uint32_t)nluns) << 3);
2977836SJohn.Forte@Sun.COM if (nluns == 0) {
2987836SJohn.Forte@Sun.COM data_size += 8;
2997836SJohn.Forte@Sun.COM }
3007836SJohn.Forte@Sun.COM alloc_size = data_size + sizeof (stmf_xfer_data_t) - 4;
3017836SJohn.Forte@Sun.COM
3027836SJohn.Forte@Sun.COM xd = (stmf_xfer_data_t *)kmem_zalloc(alloc_size, KM_NOSLEEP);
3037836SJohn.Forte@Sun.COM
3047836SJohn.Forte@Sun.COM if (xd == NULL)
3057836SJohn.Forte@Sun.COM return (NULL);
3067836SJohn.Forte@Sun.COM
3077836SJohn.Forte@Sun.COM xd->alloc_size = alloc_size;
3087836SJohn.Forte@Sun.COM xd->size_left = data_size;
3097836SJohn.Forte@Sun.COM
3107836SJohn.Forte@Sun.COM *((uint32_t *)xd->buf) = BE_32(data_size - 8);
3117836SJohn.Forte@Sun.COM if (nluns == 0) {
3127836SJohn.Forte@Sun.COM return (xd);
3137836SJohn.Forte@Sun.COM }
3147836SJohn.Forte@Sun.COM
3157836SJohn.Forte@Sun.COM ent = 0;
3167836SJohn.Forte@Sun.COM
3177836SJohn.Forte@Sun.COM for (i = 0; ((i < sm->lm_nentries) && (ent < nluns)); i++) {
3187836SJohn.Forte@Sun.COM if (sm->lm_plus[i] == NULL)
3197836SJohn.Forte@Sun.COM continue;
3207836SJohn.Forte@Sun.COM /* Fill in the entry */
3217836SJohn.Forte@Sun.COM xd->buf[8 + (ent << 3) + 1] = (uchar_t)i;
3227836SJohn.Forte@Sun.COM xd->buf[8 + (ent << 3) + 0] = ((uchar_t)(i >> 8));
3237836SJohn.Forte@Sun.COM ent++;
3247836SJohn.Forte@Sun.COM }
3257836SJohn.Forte@Sun.COM
3267836SJohn.Forte@Sun.COM ASSERT(ent == nluns);
3277836SJohn.Forte@Sun.COM
3287836SJohn.Forte@Sun.COM return (xd);
3297836SJohn.Forte@Sun.COM }
3307836SJohn.Forte@Sun.COM
3317836SJohn.Forte@Sun.COM /*
3327836SJohn.Forte@Sun.COM * Add a lu to active sessions based on LUN inventory.
3337836SJohn.Forte@Sun.COM * Only invoked when the lu is onlined
3347836SJohn.Forte@Sun.COM */
3357836SJohn.Forte@Sun.COM void
stmf_add_lu_to_active_sessions(stmf_lu_t * lu)3367836SJohn.Forte@Sun.COM stmf_add_lu_to_active_sessions(stmf_lu_t *lu)
3377836SJohn.Forte@Sun.COM {
3387836SJohn.Forte@Sun.COM stmf_id_data_t *luid;
3397836SJohn.Forte@Sun.COM stmf_view_entry_t *ve;
3407836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu;
3417836SJohn.Forte@Sun.COM
3427836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
3437836SJohn.Forte@Sun.COM ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
3447836SJohn.Forte@Sun.COM ASSERT(ilu->ilu_state == STMF_STATE_ONLINE);
3457836SJohn.Forte@Sun.COM
3467836SJohn.Forte@Sun.COM luid = ((stmf_i_lu_t *)lu->lu_stmf_private)->ilu_luid;
3477836SJohn.Forte@Sun.COM
3487836SJohn.Forte@Sun.COM if (!luid) {
3497836SJohn.Forte@Sun.COM /* we did not configure view for this lun, so just return */
3507836SJohn.Forte@Sun.COM return;
3517836SJohn.Forte@Sun.COM }
3527836SJohn.Forte@Sun.COM
3537836SJohn.Forte@Sun.COM for (ve = (stmf_view_entry_t *)luid->id_impl_specific;
3547836SJohn.Forte@Sun.COM ve; ve = ve->ve_next) {
3557836SJohn.Forte@Sun.COM stmf_update_sessions_per_ve(ve, lu, 1);
3567836SJohn.Forte@Sun.COM }
3577836SJohn.Forte@Sun.COM }
3587836SJohn.Forte@Sun.COM /*
3597836SJohn.Forte@Sun.COM * Unmap a lun from all sessions
3607836SJohn.Forte@Sun.COM */
3617836SJohn.Forte@Sun.COM void
stmf_session_lu_unmapall(stmf_lu_t * lu)3627836SJohn.Forte@Sun.COM stmf_session_lu_unmapall(stmf_lu_t *lu)
3637836SJohn.Forte@Sun.COM {
3647836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu;
3657836SJohn.Forte@Sun.COM stmf_id_data_t *luid;
3667836SJohn.Forte@Sun.COM stmf_view_entry_t *ve;
3677836SJohn.Forte@Sun.COM
3687836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
3697836SJohn.Forte@Sun.COM
3707836SJohn.Forte@Sun.COM ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
3717836SJohn.Forte@Sun.COM
3727836SJohn.Forte@Sun.COM if (ilu->ilu_ref_cnt == 0)
3737836SJohn.Forte@Sun.COM return;
3747836SJohn.Forte@Sun.COM
3757836SJohn.Forte@Sun.COM luid = ((stmf_i_lu_t *)lu->lu_stmf_private)->ilu_luid;
3767836SJohn.Forte@Sun.COM if (!luid) {
3777836SJohn.Forte@Sun.COM /*
3787836SJohn.Forte@Sun.COM * we did not configure view for this lun, this should be
3797836SJohn.Forte@Sun.COM * an error
3807836SJohn.Forte@Sun.COM */
3817836SJohn.Forte@Sun.COM return;
3827836SJohn.Forte@Sun.COM }
3837836SJohn.Forte@Sun.COM
3847836SJohn.Forte@Sun.COM for (ve = (stmf_view_entry_t *)luid->id_impl_specific;
3857836SJohn.Forte@Sun.COM ve; ve = ve->ve_next) {
3867836SJohn.Forte@Sun.COM stmf_update_sessions_per_ve(ve, lu, 0);
3877836SJohn.Forte@Sun.COM if (ilu->ilu_ref_cnt == 0)
3887836SJohn.Forte@Sun.COM break;
3897836SJohn.Forte@Sun.COM }
3907836SJohn.Forte@Sun.COM }
3917836SJohn.Forte@Sun.COM /*
3927836SJohn.Forte@Sun.COM * add lu to a session, stmf_lock is already held
3937836SJohn.Forte@Sun.COM */
3947836SJohn.Forte@Sun.COM stmf_status_t
stmf_add_lu_to_session(stmf_i_local_port_t * ilport,stmf_i_scsi_session_t * iss,stmf_lu_t * lu,uint8_t * lu_nbr)3957836SJohn.Forte@Sun.COM stmf_add_lu_to_session(stmf_i_local_port_t *ilport,
3967836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss,
3977836SJohn.Forte@Sun.COM stmf_lu_t *lu,
3987836SJohn.Forte@Sun.COM uint8_t *lu_nbr)
3997836SJohn.Forte@Sun.COM {
4007836SJohn.Forte@Sun.COM stmf_lun_map_t *sm = iss->iss_sm;
4017836SJohn.Forte@Sun.COM stmf_status_t ret;
4027836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
4037836SJohn.Forte@Sun.COM stmf_lun_map_ent_t *lun_map_ent;
4047836SJohn.Forte@Sun.COM uint32_t new_flags = 0;
4057836SJohn.Forte@Sun.COM uint16_t luNbr =
4067836SJohn.Forte@Sun.COM ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
4077836SJohn.Forte@Sun.COM
4087836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
4097836SJohn.Forte@Sun.COM ASSERT(!stmf_get_ent_from_map(sm, luNbr));
4107836SJohn.Forte@Sun.COM
4117836SJohn.Forte@Sun.COM if ((sm->lm_nluns == 0) &&
4127836SJohn.Forte@Sun.COM ((iss->iss_flags & ISS_BEING_CREATED) == 0)) {
4137836SJohn.Forte@Sun.COM new_flags = ISS_GOT_INITIAL_LUNS;
4147836SJohn.Forte@Sun.COM atomic_or_32(&ilport->ilport_flags, ILPORT_SS_GOT_INITIAL_LUNS);
4157836SJohn.Forte@Sun.COM stmf_state.stmf_process_initial_luns = 1;
4167836SJohn.Forte@Sun.COM }
4177836SJohn.Forte@Sun.COM
4187836SJohn.Forte@Sun.COM lun_map_ent = (stmf_lun_map_ent_t *)
4197836SJohn.Forte@Sun.COM kmem_zalloc(sizeof (stmf_lun_map_ent_t), KM_SLEEP);
4207836SJohn.Forte@Sun.COM lun_map_ent->ent_lu = lu;
4217836SJohn.Forte@Sun.COM ret = stmf_add_ent_to_map(sm, (void *)lun_map_ent, lu_nbr);
4227836SJohn.Forte@Sun.COM ASSERT(ret == STMF_SUCCESS);
4237836SJohn.Forte@Sun.COM atomic_add_32(&ilu->ilu_ref_cnt, 1);
42410725SJohn.Forte@Sun.COM /*
42510725SJohn.Forte@Sun.COM * do not set lun inventory flag for standby port
42610725SJohn.Forte@Sun.COM * as this would be handled from peer
42710725SJohn.Forte@Sun.COM */
42810725SJohn.Forte@Sun.COM if (ilport->ilport_standby == 0) {
42910725SJohn.Forte@Sun.COM new_flags |= ISS_LUN_INVENTORY_CHANGED;
43010725SJohn.Forte@Sun.COM }
4317836SJohn.Forte@Sun.COM atomic_or_32(&iss->iss_flags, new_flags);
4327836SJohn.Forte@Sun.COM return (STMF_SUCCESS);
4337836SJohn.Forte@Sun.COM }
4347836SJohn.Forte@Sun.COM
4357836SJohn.Forte@Sun.COM /*
4367836SJohn.Forte@Sun.COM * remvoe lu from a session, stmf_lock is already held
4377836SJohn.Forte@Sun.COM */
4387836SJohn.Forte@Sun.COM /* ARGSUSED */
4397836SJohn.Forte@Sun.COM stmf_status_t
stmf_remove_lu_from_session(stmf_i_local_port_t * ilport,stmf_i_scsi_session_t * iss,stmf_lu_t * lu,uint8_t * lu_nbr)4407836SJohn.Forte@Sun.COM stmf_remove_lu_from_session(stmf_i_local_port_t *ilport,
4417836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss,
4427836SJohn.Forte@Sun.COM stmf_lu_t *lu,
4437836SJohn.Forte@Sun.COM uint8_t *lu_nbr)
4447836SJohn.Forte@Sun.COM {
4457836SJohn.Forte@Sun.COM stmf_status_t ret;
4467836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu;
4477836SJohn.Forte@Sun.COM stmf_lun_map_t *sm = iss->iss_sm;
4487836SJohn.Forte@Sun.COM stmf_lun_map_ent_t *lun_map_ent;
4497836SJohn.Forte@Sun.COM uint16_t luNbr =
4507836SJohn.Forte@Sun.COM ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
4517836SJohn.Forte@Sun.COM
4527836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
4537836SJohn.Forte@Sun.COM lun_map_ent = stmf_get_ent_from_map(sm, luNbr);
4547836SJohn.Forte@Sun.COM ASSERT(lun_map_ent && lun_map_ent->ent_lu == lu);
4557836SJohn.Forte@Sun.COM
4567836SJohn.Forte@Sun.COM ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
4577836SJohn.Forte@Sun.COM
4587836SJohn.Forte@Sun.COM ret = stmf_remove_ent_from_map(sm, lu_nbr);
4597836SJohn.Forte@Sun.COM ASSERT(ret == STMF_SUCCESS);
4607836SJohn.Forte@Sun.COM atomic_add_32(&ilu->ilu_ref_cnt, -1);
4617836SJohn.Forte@Sun.COM iss->iss_flags |= ISS_LUN_INVENTORY_CHANGED;
4627836SJohn.Forte@Sun.COM if (lun_map_ent->ent_itl_datap) {
4637836SJohn.Forte@Sun.COM stmf_do_itl_dereg(lu, lun_map_ent->ent_itl_datap,
4649884STim.Szeto@Sun.COM STMF_ITL_REASON_USER_REQUEST);
4657836SJohn.Forte@Sun.COM }
4667836SJohn.Forte@Sun.COM kmem_free((void *)lun_map_ent, sizeof (stmf_lun_map_ent_t));
4677836SJohn.Forte@Sun.COM return (STMF_SUCCESS);
4687836SJohn.Forte@Sun.COM }
4697836SJohn.Forte@Sun.COM
4707836SJohn.Forte@Sun.COM /*
4717836SJohn.Forte@Sun.COM * add or remove lu from all related sessions based on view entry,
4727836SJohn.Forte@Sun.COM * action is 0 for delete, 1 for add
4737836SJohn.Forte@Sun.COM */
4747836SJohn.Forte@Sun.COM void
stmf_update_sessions_per_ve(stmf_view_entry_t * ve,stmf_lu_t * lu,int action)4757836SJohn.Forte@Sun.COM stmf_update_sessions_per_ve(stmf_view_entry_t *ve,
4767836SJohn.Forte@Sun.COM stmf_lu_t *lu, int action)
4777836SJohn.Forte@Sun.COM {
4787836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu_tmp;
4797836SJohn.Forte@Sun.COM stmf_lu_t *lu_to_add;
4807836SJohn.Forte@Sun.COM stmf_i_local_port_t *ilport;
4817836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss;
4827836SJohn.Forte@Sun.COM stmf_id_list_t *hostlist;
4837836SJohn.Forte@Sun.COM stmf_id_list_t *targetlist;
4847836SJohn.Forte@Sun.COM int all_hg = 0, all_tg = 0;
4857836SJohn.Forte@Sun.COM
4867836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
4877836SJohn.Forte@Sun.COM
4887836SJohn.Forte@Sun.COM if (!lu) {
4897836SJohn.Forte@Sun.COM ilu_tmp = (stmf_i_lu_t *)ve->ve_luid->id_pt_to_object;
4907836SJohn.Forte@Sun.COM if (!ilu_tmp)
4917836SJohn.Forte@Sun.COM return;
4927836SJohn.Forte@Sun.COM lu_to_add = ilu_tmp->ilu_lu;
4937836SJohn.Forte@Sun.COM } else {
4947836SJohn.Forte@Sun.COM lu_to_add = lu;
4957836SJohn.Forte@Sun.COM ilu_tmp = (stmf_i_lu_t *)lu->lu_stmf_private;
4967836SJohn.Forte@Sun.COM }
4977836SJohn.Forte@Sun.COM
4987836SJohn.Forte@Sun.COM if (ve->ve_hg->id_data[0] == '*')
4997836SJohn.Forte@Sun.COM all_hg = 1;
5007836SJohn.Forte@Sun.COM if (ve->ve_tg->id_data[0] == '*')
5017836SJohn.Forte@Sun.COM all_tg = 1;
5027836SJohn.Forte@Sun.COM hostlist = (stmf_id_list_t *)ve->ve_hg->id_impl_specific;
5037836SJohn.Forte@Sun.COM targetlist = (stmf_id_list_t *)ve->ve_tg->id_impl_specific;
5047836SJohn.Forte@Sun.COM
5057836SJohn.Forte@Sun.COM if ((!all_hg && !hostlist->idl_head) ||
5067836SJohn.Forte@Sun.COM (!all_tg && !targetlist->idl_head))
5077836SJohn.Forte@Sun.COM /* No sessions to be updated */
5087836SJohn.Forte@Sun.COM return;
5097836SJohn.Forte@Sun.COM
5107836SJohn.Forte@Sun.COM for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
5117836SJohn.Forte@Sun.COM ilport = ilport->ilport_next) {
5127836SJohn.Forte@Sun.COM if (!all_tg && ilport->ilport_tg != ve->ve_tg)
5137836SJohn.Forte@Sun.COM continue;
5147836SJohn.Forte@Sun.COM /* This ilport belongs to the target group */
5157836SJohn.Forte@Sun.COM rw_enter(&ilport->ilport_lock, RW_WRITER);
5167836SJohn.Forte@Sun.COM for (iss = ilport->ilport_ss_list; iss != NULL;
5177836SJohn.Forte@Sun.COM iss = iss->iss_next) {
5187836SJohn.Forte@Sun.COM if (!all_hg && iss->iss_hg != ve->ve_hg)
5197836SJohn.Forte@Sun.COM continue;
5207836SJohn.Forte@Sun.COM /* This host belongs to the host group */
5217836SJohn.Forte@Sun.COM if (action == 0) { /* to remove */
5227836SJohn.Forte@Sun.COM (void) stmf_remove_lu_from_session(ilport, iss,
5237836SJohn.Forte@Sun.COM lu_to_add, ve->ve_lun);
5247836SJohn.Forte@Sun.COM if (ilu_tmp->ilu_ref_cnt == 0) {
5257836SJohn.Forte@Sun.COM rw_exit(&ilport->ilport_lock);
5267836SJohn.Forte@Sun.COM return;
5277836SJohn.Forte@Sun.COM }
5287836SJohn.Forte@Sun.COM } else {
5297836SJohn.Forte@Sun.COM (void) stmf_add_lu_to_session(ilport, iss,
5307836SJohn.Forte@Sun.COM lu_to_add, ve->ve_lun);
5317836SJohn.Forte@Sun.COM }
5327836SJohn.Forte@Sun.COM }
5337836SJohn.Forte@Sun.COM rw_exit(&ilport->ilport_lock);
5347836SJohn.Forte@Sun.COM }
5357836SJohn.Forte@Sun.COM }
5367836SJohn.Forte@Sun.COM
5377836SJohn.Forte@Sun.COM /*
5387836SJohn.Forte@Sun.COM * add luns in view entry map to a session,
5397836SJohn.Forte@Sun.COM * and stmf_lock is already held
5407836SJohn.Forte@Sun.COM */
5417836SJohn.Forte@Sun.COM void
stmf_add_lus_to_session_per_vemap(stmf_i_local_port_t * ilport,stmf_i_scsi_session_t * iss,stmf_lun_map_t * vemap)5427836SJohn.Forte@Sun.COM stmf_add_lus_to_session_per_vemap(stmf_i_local_port_t *ilport,
5437836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss,
5447836SJohn.Forte@Sun.COM stmf_lun_map_t *vemap)
5457836SJohn.Forte@Sun.COM {
5467836SJohn.Forte@Sun.COM stmf_lu_t *lu;
5477836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu;
5487836SJohn.Forte@Sun.COM stmf_view_entry_t *ve;
5497836SJohn.Forte@Sun.COM uint32_t i;
5507836SJohn.Forte@Sun.COM
5517836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
5527836SJohn.Forte@Sun.COM
5537836SJohn.Forte@Sun.COM for (i = 0; i < vemap->lm_nentries; i++) {
5547836SJohn.Forte@Sun.COM ve = (stmf_view_entry_t *)vemap->lm_plus[i];
5557836SJohn.Forte@Sun.COM if (!ve)
5567836SJohn.Forte@Sun.COM continue;
5577836SJohn.Forte@Sun.COM ilu = (stmf_i_lu_t *)ve->ve_luid->id_pt_to_object;
5587836SJohn.Forte@Sun.COM if (ilu && ilu->ilu_state == STMF_STATE_ONLINE) {
5597836SJohn.Forte@Sun.COM lu = ilu->ilu_lu;
5607836SJohn.Forte@Sun.COM (void) stmf_add_lu_to_session(ilport, iss, lu,
5617836SJohn.Forte@Sun.COM ve->ve_lun);
5627836SJohn.Forte@Sun.COM }
5637836SJohn.Forte@Sun.COM }
5647836SJohn.Forte@Sun.COM }
5657836SJohn.Forte@Sun.COM /* remove luns in view entry map from a session */
5667836SJohn.Forte@Sun.COM void
stmf_remove_lus_from_session_per_vemap(stmf_i_local_port_t * ilport,stmf_i_scsi_session_t * iss,stmf_lun_map_t * vemap)5677836SJohn.Forte@Sun.COM stmf_remove_lus_from_session_per_vemap(stmf_i_local_port_t *ilport,
5687836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss,
5697836SJohn.Forte@Sun.COM stmf_lun_map_t *vemap)
5707836SJohn.Forte@Sun.COM {
5717836SJohn.Forte@Sun.COM stmf_lu_t *lu;
5727836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu;
5737836SJohn.Forte@Sun.COM stmf_view_entry_t *ve;
5747836SJohn.Forte@Sun.COM uint32_t i;
5757836SJohn.Forte@Sun.COM
5767836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
5777836SJohn.Forte@Sun.COM
5787836SJohn.Forte@Sun.COM for (i = 0; i < vemap->lm_nentries; i++) {
5797836SJohn.Forte@Sun.COM ve = (stmf_view_entry_t *)vemap->lm_plus[i];
5807836SJohn.Forte@Sun.COM if (!ve)
5817836SJohn.Forte@Sun.COM continue;
5827836SJohn.Forte@Sun.COM ilu = (stmf_i_lu_t *)ve->ve_luid->id_pt_to_object;
5837836SJohn.Forte@Sun.COM if (ilu && ilu->ilu_state == STMF_STATE_ONLINE) {
5847836SJohn.Forte@Sun.COM lu = ilu->ilu_lu;
5857836SJohn.Forte@Sun.COM (void) stmf_remove_lu_from_session(ilport, iss, lu,
5867836SJohn.Forte@Sun.COM ve->ve_lun);
5877836SJohn.Forte@Sun.COM }
5887836SJohn.Forte@Sun.COM }
5897836SJohn.Forte@Sun.COM }
5907836SJohn.Forte@Sun.COM
5917836SJohn.Forte@Sun.COM stmf_id_data_t *
stmf_alloc_id(uint16_t id_size,uint16_t type,uint8_t * id_data,uint32_t additional_size)5927836SJohn.Forte@Sun.COM stmf_alloc_id(uint16_t id_size, uint16_t type, uint8_t *id_data,
5937836SJohn.Forte@Sun.COM uint32_t additional_size)
5947836SJohn.Forte@Sun.COM {
5957836SJohn.Forte@Sun.COM stmf_id_data_t *id;
5967836SJohn.Forte@Sun.COM int struct_size, total_size, real_id_size;
5977836SJohn.Forte@Sun.COM
5987836SJohn.Forte@Sun.COM real_id_size = ((uint32_t)id_size + 7) & (~7);
5997836SJohn.Forte@Sun.COM struct_size = (sizeof (*id) + 7) & (~7);
6007836SJohn.Forte@Sun.COM total_size = ((additional_size + 7) & (~7)) + struct_size +
6017836SJohn.Forte@Sun.COM real_id_size;
6027836SJohn.Forte@Sun.COM id = (stmf_id_data_t *)kmem_zalloc(total_size, KM_SLEEP);
6037836SJohn.Forte@Sun.COM id->id_type = type;
6047836SJohn.Forte@Sun.COM id->id_data_size = id_size;
6057836SJohn.Forte@Sun.COM id->id_data = ((uint8_t *)id) + struct_size;
6067836SJohn.Forte@Sun.COM id->id_total_alloc_size = total_size;
6077836SJohn.Forte@Sun.COM if (additional_size) {
6087836SJohn.Forte@Sun.COM id->id_impl_specific = ((uint8_t *)id) + struct_size +
6097836SJohn.Forte@Sun.COM real_id_size;
6107836SJohn.Forte@Sun.COM }
6117836SJohn.Forte@Sun.COM bcopy(id_data, id->id_data, id_size);
6127836SJohn.Forte@Sun.COM
6137836SJohn.Forte@Sun.COM return (id);
6147836SJohn.Forte@Sun.COM }
6157836SJohn.Forte@Sun.COM
6167836SJohn.Forte@Sun.COM void
stmf_free_id(stmf_id_data_t * id)6177836SJohn.Forte@Sun.COM stmf_free_id(stmf_id_data_t *id)
6187836SJohn.Forte@Sun.COM {
6197836SJohn.Forte@Sun.COM kmem_free(id, id->id_total_alloc_size);
6207836SJohn.Forte@Sun.COM }
6217836SJohn.Forte@Sun.COM
6227836SJohn.Forte@Sun.COM
6237836SJohn.Forte@Sun.COM stmf_id_data_t *
stmf_lookup_id(stmf_id_list_t * idlist,uint16_t id_size,uint8_t * data)6247836SJohn.Forte@Sun.COM stmf_lookup_id(stmf_id_list_t *idlist, uint16_t id_size, uint8_t *data)
6257836SJohn.Forte@Sun.COM {
6267836SJohn.Forte@Sun.COM stmf_id_data_t *id;
6277836SJohn.Forte@Sun.COM
6287836SJohn.Forte@Sun.COM for (id = idlist->idl_head; id != NULL; id = id->id_next) {
6297836SJohn.Forte@Sun.COM if ((id->id_data_size == id_size) &&
6307836SJohn.Forte@Sun.COM (bcmp(id->id_data, data, id_size) == 0)) {
6317836SJohn.Forte@Sun.COM return (id);
6327836SJohn.Forte@Sun.COM }
6337836SJohn.Forte@Sun.COM }
6347836SJohn.Forte@Sun.COM
6357836SJohn.Forte@Sun.COM return (NULL);
6367836SJohn.Forte@Sun.COM }
6377836SJohn.Forte@Sun.COM /* Return the target group which a target belong to */
6387836SJohn.Forte@Sun.COM stmf_id_data_t *
stmf_lookup_group_for_target(uint8_t * ident,uint16_t ident_size)6397836SJohn.Forte@Sun.COM stmf_lookup_group_for_target(uint8_t *ident, uint16_t ident_size)
6407836SJohn.Forte@Sun.COM {
6417836SJohn.Forte@Sun.COM stmf_id_data_t *tgid;
6427836SJohn.Forte@Sun.COM stmf_id_data_t *target;
6437836SJohn.Forte@Sun.COM
6447836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
6457836SJohn.Forte@Sun.COM
6467836SJohn.Forte@Sun.COM for (tgid = stmf_state.stmf_tg_list.idl_head; tgid;
6477836SJohn.Forte@Sun.COM tgid = tgid->id_next) {
6487836SJohn.Forte@Sun.COM target = stmf_lookup_id(
6497836SJohn.Forte@Sun.COM (stmf_id_list_t *)tgid->id_impl_specific,
6507836SJohn.Forte@Sun.COM ident_size, ident);
6517836SJohn.Forte@Sun.COM if (target)
6527836SJohn.Forte@Sun.COM return (tgid);
6537836SJohn.Forte@Sun.COM }
6547836SJohn.Forte@Sun.COM return (NULL);
6557836SJohn.Forte@Sun.COM }
6567836SJohn.Forte@Sun.COM /* Return the host group which a host belong to */
6577836SJohn.Forte@Sun.COM stmf_id_data_t *
stmf_lookup_group_for_host(uint8_t * ident,uint16_t ident_size)6587836SJohn.Forte@Sun.COM stmf_lookup_group_for_host(uint8_t *ident, uint16_t ident_size)
6597836SJohn.Forte@Sun.COM {
6607836SJohn.Forte@Sun.COM stmf_id_data_t *hgid;
6617836SJohn.Forte@Sun.COM stmf_id_data_t *host;
6627836SJohn.Forte@Sun.COM
6637836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
6647836SJohn.Forte@Sun.COM
6657836SJohn.Forte@Sun.COM for (hgid = stmf_state.stmf_hg_list.idl_head; hgid;
6667836SJohn.Forte@Sun.COM hgid = hgid->id_next) {
6677836SJohn.Forte@Sun.COM host = stmf_lookup_id(
6687836SJohn.Forte@Sun.COM (stmf_id_list_t *)hgid->id_impl_specific,
6697836SJohn.Forte@Sun.COM ident_size, ident);
6707836SJohn.Forte@Sun.COM if (host)
6717836SJohn.Forte@Sun.COM return (hgid);
6727836SJohn.Forte@Sun.COM }
6737836SJohn.Forte@Sun.COM return (NULL);
6747836SJohn.Forte@Sun.COM }
6757836SJohn.Forte@Sun.COM
6767836SJohn.Forte@Sun.COM void
stmf_append_id(stmf_id_list_t * idlist,stmf_id_data_t * id)6777836SJohn.Forte@Sun.COM stmf_append_id(stmf_id_list_t *idlist, stmf_id_data_t *id)
6787836SJohn.Forte@Sun.COM {
6797836SJohn.Forte@Sun.COM id->id_next = NULL;
6807836SJohn.Forte@Sun.COM
6817836SJohn.Forte@Sun.COM if ((id->id_prev = idlist->idl_tail) == NULL) {
6827836SJohn.Forte@Sun.COM idlist->idl_head = idlist->idl_tail = id;
6837836SJohn.Forte@Sun.COM } else {
6847836SJohn.Forte@Sun.COM idlist->idl_tail->id_next = id;
6857836SJohn.Forte@Sun.COM idlist->idl_tail = id;
6867836SJohn.Forte@Sun.COM }
6877836SJohn.Forte@Sun.COM atomic_add_32(&idlist->id_count, 1);
6887836SJohn.Forte@Sun.COM }
6897836SJohn.Forte@Sun.COM
6907836SJohn.Forte@Sun.COM void
stmf_remove_id(stmf_id_list_t * idlist,stmf_id_data_t * id)6917836SJohn.Forte@Sun.COM stmf_remove_id(stmf_id_list_t *idlist, stmf_id_data_t *id)
6927836SJohn.Forte@Sun.COM {
6937836SJohn.Forte@Sun.COM if (id->id_next) {
6947836SJohn.Forte@Sun.COM id->id_next->id_prev = id->id_prev;
6957836SJohn.Forte@Sun.COM } else {
6967836SJohn.Forte@Sun.COM idlist->idl_tail = id->id_prev;
6977836SJohn.Forte@Sun.COM }
6987836SJohn.Forte@Sun.COM
6997836SJohn.Forte@Sun.COM if (id->id_prev) {
7007836SJohn.Forte@Sun.COM id->id_prev->id_next = id->id_next;
7017836SJohn.Forte@Sun.COM } else {
7027836SJohn.Forte@Sun.COM idlist->idl_head = id->id_next;
7037836SJohn.Forte@Sun.COM }
7047836SJohn.Forte@Sun.COM atomic_add_32(&idlist->id_count, -1);
7057836SJohn.Forte@Sun.COM }
7067836SJohn.Forte@Sun.COM
7077836SJohn.Forte@Sun.COM
7087836SJohn.Forte@Sun.COM /*
7097836SJohn.Forte@Sun.COM * The refcnts of objects in a view entry are updated when then entry
7107836SJohn.Forte@Sun.COM * is successfully added. ve_map is just another representation of the
7117836SJohn.Forte@Sun.COM * view enrtries in a LU. Duplicating or merging a ve map does not
7127836SJohn.Forte@Sun.COM * affect any refcnts.
7137836SJohn.Forte@Sun.COM */
7147836SJohn.Forte@Sun.COM stmf_lun_map_t *
stmf_duplicate_ve_map(stmf_lun_map_t * src)7157836SJohn.Forte@Sun.COM stmf_duplicate_ve_map(stmf_lun_map_t *src)
7167836SJohn.Forte@Sun.COM {
7177836SJohn.Forte@Sun.COM stmf_lun_map_t *dst;
7187836SJohn.Forte@Sun.COM int i;
7197836SJohn.Forte@Sun.COM
7207836SJohn.Forte@Sun.COM dst = (stmf_lun_map_t *)kmem_zalloc(sizeof (*dst), KM_SLEEP);
7217836SJohn.Forte@Sun.COM
7227836SJohn.Forte@Sun.COM if (src == NULL)
7237836SJohn.Forte@Sun.COM return (dst);
7247836SJohn.Forte@Sun.COM
7257836SJohn.Forte@Sun.COM if (src->lm_nentries) {
7267836SJohn.Forte@Sun.COM dst->lm_plus = kmem_zalloc(dst->lm_nentries *
7277836SJohn.Forte@Sun.COM sizeof (void *), KM_SLEEP);
7287836SJohn.Forte@Sun.COM for (i = 0; i < dst->lm_nentries; i++) {
7297836SJohn.Forte@Sun.COM dst->lm_plus[i] = src->lm_plus[i];
7307836SJohn.Forte@Sun.COM }
7317836SJohn.Forte@Sun.COM }
7327836SJohn.Forte@Sun.COM
7337836SJohn.Forte@Sun.COM return (dst);
7347836SJohn.Forte@Sun.COM }
7357836SJohn.Forte@Sun.COM
7367836SJohn.Forte@Sun.COM void
stmf_destroy_ve_map(stmf_lun_map_t * dst)7377836SJohn.Forte@Sun.COM stmf_destroy_ve_map(stmf_lun_map_t *dst)
7387836SJohn.Forte@Sun.COM {
7397836SJohn.Forte@Sun.COM if (dst->lm_nentries) {
7407836SJohn.Forte@Sun.COM kmem_free(dst->lm_plus, dst->lm_nentries * sizeof (void *));
7417836SJohn.Forte@Sun.COM }
7427836SJohn.Forte@Sun.COM kmem_free(dst, sizeof (*dst));
7437836SJohn.Forte@Sun.COM }
7447836SJohn.Forte@Sun.COM
7457836SJohn.Forte@Sun.COM int
stmf_merge_ve_map(stmf_lun_map_t * src,stmf_lun_map_t * dst,stmf_lun_map_t ** pp_ret_map,stmf_merge_flags_t mf)7467836SJohn.Forte@Sun.COM stmf_merge_ve_map(stmf_lun_map_t *src, stmf_lun_map_t *dst,
7477836SJohn.Forte@Sun.COM stmf_lun_map_t **pp_ret_map, stmf_merge_flags_t mf)
7487836SJohn.Forte@Sun.COM {
7497836SJohn.Forte@Sun.COM int i;
7507836SJohn.Forte@Sun.COM int nentries;
7517836SJohn.Forte@Sun.COM int to_create_space = 0;
7527836SJohn.Forte@Sun.COM
7537836SJohn.Forte@Sun.COM if (dst == NULL) {
7547836SJohn.Forte@Sun.COM *pp_ret_map = stmf_duplicate_ve_map(src);
7557836SJohn.Forte@Sun.COM return (1);
7567836SJohn.Forte@Sun.COM }
7577836SJohn.Forte@Sun.COM
7587836SJohn.Forte@Sun.COM if (src == NULL || src->lm_nluns == 0) {
7597836SJohn.Forte@Sun.COM if (mf & MERGE_FLAG_RETURN_NEW_MAP)
7607836SJohn.Forte@Sun.COM *pp_ret_map = stmf_duplicate_ve_map(dst);
7617836SJohn.Forte@Sun.COM else
7627836SJohn.Forte@Sun.COM *pp_ret_map = dst;
7637836SJohn.Forte@Sun.COM return (1);
7647836SJohn.Forte@Sun.COM }
7657836SJohn.Forte@Sun.COM
7667836SJohn.Forte@Sun.COM if (mf & MERGE_FLAG_RETURN_NEW_MAP) {
7677836SJohn.Forte@Sun.COM *pp_ret_map = stmf_duplicate_ve_map(NULL);
7687836SJohn.Forte@Sun.COM nentries = max(dst->lm_nentries, src->lm_nentries);
7697836SJohn.Forte@Sun.COM to_create_space = 1;
7707836SJohn.Forte@Sun.COM } else {
7717836SJohn.Forte@Sun.COM *pp_ret_map = dst;
7727836SJohn.Forte@Sun.COM /* If there is not enough space in dst map */
7737836SJohn.Forte@Sun.COM if (dst->lm_nentries < src->lm_nentries) {
7747836SJohn.Forte@Sun.COM nentries = src->lm_nentries;
7757836SJohn.Forte@Sun.COM to_create_space = 1;
7767836SJohn.Forte@Sun.COM }
7777836SJohn.Forte@Sun.COM }
7787836SJohn.Forte@Sun.COM if (to_create_space) {
7797836SJohn.Forte@Sun.COM void **p;
7807836SJohn.Forte@Sun.COM p = (void **)kmem_zalloc(nentries * sizeof (void *), KM_SLEEP);
7817836SJohn.Forte@Sun.COM if (dst->lm_nentries) {
7827836SJohn.Forte@Sun.COM bcopy(dst->lm_plus, p,
7837836SJohn.Forte@Sun.COM dst->lm_nentries * sizeof (void *));
7847836SJohn.Forte@Sun.COM }
7857836SJohn.Forte@Sun.COM if (mf & (MERGE_FLAG_RETURN_NEW_MAP == 0))
7867836SJohn.Forte@Sun.COM kmem_free(dst->lm_plus,
7877836SJohn.Forte@Sun.COM dst->lm_nentries * sizeof (void *));
7887836SJohn.Forte@Sun.COM (*pp_ret_map)->lm_plus = p;
7897836SJohn.Forte@Sun.COM (*pp_ret_map)->lm_nentries = nentries;
7907836SJohn.Forte@Sun.COM }
7917836SJohn.Forte@Sun.COM
7927836SJohn.Forte@Sun.COM for (i = 0; i < src->lm_nentries; i++) {
7937836SJohn.Forte@Sun.COM if (src->lm_plus[i] == NULL)
7947836SJohn.Forte@Sun.COM continue;
7957836SJohn.Forte@Sun.COM if (dst->lm_plus[i] != NULL) {
7967836SJohn.Forte@Sun.COM if (mf & MERGE_FLAG_NO_DUPLICATE) {
7977836SJohn.Forte@Sun.COM if (mf & MERGE_FLAG_RETURN_NEW_MAP) {
7987836SJohn.Forte@Sun.COM stmf_destroy_ve_map(*pp_ret_map);
7997836SJohn.Forte@Sun.COM *pp_ret_map = NULL;
8007836SJohn.Forte@Sun.COM }
8017836SJohn.Forte@Sun.COM return (0);
8027836SJohn.Forte@Sun.COM }
8037836SJohn.Forte@Sun.COM } else {
8047836SJohn.Forte@Sun.COM dst->lm_plus[i] = src->lm_plus[i];
8057836SJohn.Forte@Sun.COM dst->lm_nluns++;
8067836SJohn.Forte@Sun.COM }
8077836SJohn.Forte@Sun.COM }
8087836SJohn.Forte@Sun.COM
8097836SJohn.Forte@Sun.COM return (1);
8107836SJohn.Forte@Sun.COM }
8117836SJohn.Forte@Sun.COM
8127836SJohn.Forte@Sun.COM /*
8137836SJohn.Forte@Sun.COM * add host group, id_impl_specific point to a list of hosts,
8147836SJohn.Forte@Sun.COM * on return, if error happened, err_detail may be assigned if
8157836SJohn.Forte@Sun.COM * the pointer is not NULL
8167836SJohn.Forte@Sun.COM */
8177836SJohn.Forte@Sun.COM stmf_status_t
stmf_add_hg(uint8_t * hg_name,uint16_t hg_name_size,int allow_special,uint32_t * err_detail)8187836SJohn.Forte@Sun.COM stmf_add_hg(uint8_t *hg_name, uint16_t hg_name_size,
8197836SJohn.Forte@Sun.COM int allow_special, uint32_t *err_detail)
8207836SJohn.Forte@Sun.COM {
8217836SJohn.Forte@Sun.COM stmf_id_data_t *id;
8227836SJohn.Forte@Sun.COM
8237836SJohn.Forte@Sun.COM if (!allow_special) {
8247836SJohn.Forte@Sun.COM if (hg_name[0] == '*')
8257836SJohn.Forte@Sun.COM return (STMF_INVALID_ARG);
8267836SJohn.Forte@Sun.COM }
8277836SJohn.Forte@Sun.COM
8287836SJohn.Forte@Sun.COM if (stmf_lookup_id(&stmf_state.stmf_hg_list,
8297836SJohn.Forte@Sun.COM hg_name_size, (uint8_t *)hg_name)) {
8307836SJohn.Forte@Sun.COM if (err_detail)
8317836SJohn.Forte@Sun.COM *err_detail = STMF_IOCERR_HG_EXISTS;
8327836SJohn.Forte@Sun.COM return (STMF_ALREADY);
8337836SJohn.Forte@Sun.COM }
8347836SJohn.Forte@Sun.COM id = stmf_alloc_id(hg_name_size, STMF_ID_TYPE_HOST_GROUP,
8357836SJohn.Forte@Sun.COM (uint8_t *)hg_name, sizeof (stmf_id_list_t));
8367836SJohn.Forte@Sun.COM stmf_append_id(&stmf_state.stmf_hg_list, id);
8377836SJohn.Forte@Sun.COM
8387836SJohn.Forte@Sun.COM return (STMF_SUCCESS);
8397836SJohn.Forte@Sun.COM }
8407836SJohn.Forte@Sun.COM
8417836SJohn.Forte@Sun.COM /* add target group */
8427836SJohn.Forte@Sun.COM stmf_status_t
stmf_add_tg(uint8_t * tg_name,uint16_t tg_name_size,int allow_special,uint32_t * err_detail)8437836SJohn.Forte@Sun.COM stmf_add_tg(uint8_t *tg_name, uint16_t tg_name_size,
8447836SJohn.Forte@Sun.COM int allow_special, uint32_t *err_detail)
8457836SJohn.Forte@Sun.COM {
8467836SJohn.Forte@Sun.COM stmf_id_data_t *id;
8477836SJohn.Forte@Sun.COM
8487836SJohn.Forte@Sun.COM if (!allow_special) {
8497836SJohn.Forte@Sun.COM if (tg_name[0] == '*')
8507836SJohn.Forte@Sun.COM return (STMF_INVALID_ARG);
8517836SJohn.Forte@Sun.COM }
8527836SJohn.Forte@Sun.COM
8537836SJohn.Forte@Sun.COM
8547836SJohn.Forte@Sun.COM if (stmf_lookup_id(&stmf_state.stmf_tg_list, tg_name_size,
8557836SJohn.Forte@Sun.COM (uint8_t *)tg_name)) {
8567836SJohn.Forte@Sun.COM if (err_detail)
8577836SJohn.Forte@Sun.COM *err_detail = STMF_IOCERR_TG_EXISTS;
8587836SJohn.Forte@Sun.COM return (STMF_ALREADY);
8597836SJohn.Forte@Sun.COM }
8607836SJohn.Forte@Sun.COM id = stmf_alloc_id(tg_name_size, STMF_ID_TYPE_TARGET_GROUP,
8617836SJohn.Forte@Sun.COM (uint8_t *)tg_name, sizeof (stmf_id_list_t));
8627836SJohn.Forte@Sun.COM stmf_append_id(&stmf_state.stmf_tg_list, id);
8637836SJohn.Forte@Sun.COM
8647836SJohn.Forte@Sun.COM return (STMF_SUCCESS);
8657836SJohn.Forte@Sun.COM }
8667836SJohn.Forte@Sun.COM
8677836SJohn.Forte@Sun.COM /*
8687836SJohn.Forte@Sun.COM * insert view entry into list for a luid, if ve->ve_id is 0xffffffff,
8697836SJohn.Forte@Sun.COM * pick up a smallest available veid for it, and return the veid in ve->ve_id.
8707836SJohn.Forte@Sun.COM * The view entries list is sorted based on veid.
8717836SJohn.Forte@Sun.COM */
8727836SJohn.Forte@Sun.COM stmf_status_t
stmf_add_ve_to_luid(stmf_id_data_t * luid,stmf_view_entry_t * ve)8737836SJohn.Forte@Sun.COM stmf_add_ve_to_luid(stmf_id_data_t *luid, stmf_view_entry_t *ve)
8747836SJohn.Forte@Sun.COM {
8757836SJohn.Forte@Sun.COM stmf_view_entry_t *ve_tmp = NULL;
8767836SJohn.Forte@Sun.COM stmf_view_entry_t *ve_prev = NULL;
8777836SJohn.Forte@Sun.COM
8787836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
8797836SJohn.Forte@Sun.COM
8807836SJohn.Forte@Sun.COM ve_tmp = (stmf_view_entry_t *)luid->id_impl_specific;
8817836SJohn.Forte@Sun.COM
8827836SJohn.Forte@Sun.COM if (ve->ve_id != 0xffffffff) {
8837836SJohn.Forte@Sun.COM for (; ve_tmp; ve_tmp = ve_tmp->ve_next) {
8847836SJohn.Forte@Sun.COM if (ve_tmp->ve_id > ve->ve_id) {
8857836SJohn.Forte@Sun.COM break;
8867836SJohn.Forte@Sun.COM } else if (ve_tmp->ve_id == ve->ve_id) {
8877836SJohn.Forte@Sun.COM return (STMF_ALREADY);
8887836SJohn.Forte@Sun.COM }
8897836SJohn.Forte@Sun.COM ve_prev = ve_tmp;
8907836SJohn.Forte@Sun.COM }
8917836SJohn.Forte@Sun.COM } else {
8927836SJohn.Forte@Sun.COM uint32_t veid = 0;
8937836SJohn.Forte@Sun.COM /* search the smallest available veid */
8947836SJohn.Forte@Sun.COM for (; ve_tmp; ve_tmp = ve_tmp->ve_next) {
8957836SJohn.Forte@Sun.COM ASSERT(ve_tmp->ve_id >= veid);
8967836SJohn.Forte@Sun.COM if (ve_tmp->ve_id != veid)
8977836SJohn.Forte@Sun.COM break;
8987836SJohn.Forte@Sun.COM veid++;
8997836SJohn.Forte@Sun.COM if (veid == 0xffffffff)
9007836SJohn.Forte@Sun.COM return (STMF_NOT_SUPPORTED);
9017836SJohn.Forte@Sun.COM ve_prev = ve_tmp;
9027836SJohn.Forte@Sun.COM }
9037836SJohn.Forte@Sun.COM ve->ve_id = veid;
9047836SJohn.Forte@Sun.COM }
9057836SJohn.Forte@Sun.COM
9067836SJohn.Forte@Sun.COM /* insert before ve_tmp if it exist */
9077836SJohn.Forte@Sun.COM ve->ve_next = ve_tmp;
9087836SJohn.Forte@Sun.COM ve->ve_prev = ve_prev;
9097836SJohn.Forte@Sun.COM if (ve_tmp) {
9107836SJohn.Forte@Sun.COM ve_tmp->ve_prev = ve;
9117836SJohn.Forte@Sun.COM }
9127836SJohn.Forte@Sun.COM if (ve_prev) {
9137836SJohn.Forte@Sun.COM ve_prev->ve_next = ve;
9147836SJohn.Forte@Sun.COM } else {
9157836SJohn.Forte@Sun.COM luid->id_impl_specific = (void *)ve;
9167836SJohn.Forte@Sun.COM }
9177836SJohn.Forte@Sun.COM return (STMF_SUCCESS);
9187836SJohn.Forte@Sun.COM }
9197836SJohn.Forte@Sun.COM
9207836SJohn.Forte@Sun.COM /* stmf_lock is already held, err_detail may be assigned if error happens */
9217836SJohn.Forte@Sun.COM stmf_status_t
stmf_add_view_entry(stmf_id_data_t * hg,stmf_id_data_t * tg,uint8_t * lu_guid,uint32_t * ve_id,uint8_t * lun,stmf_view_entry_t ** conflicting,uint32_t * err_detail)9227836SJohn.Forte@Sun.COM stmf_add_view_entry(stmf_id_data_t *hg, stmf_id_data_t *tg,
9237836SJohn.Forte@Sun.COM uint8_t *lu_guid, uint32_t *ve_id, uint8_t *lun,
9247836SJohn.Forte@Sun.COM stmf_view_entry_t **conflicting, uint32_t *err_detail)
9257836SJohn.Forte@Sun.COM {
9267836SJohn.Forte@Sun.COM stmf_id_data_t *luid;
9277836SJohn.Forte@Sun.COM stmf_view_entry_t *ve;
9287836SJohn.Forte@Sun.COM char *phg, *ptg;
9297836SJohn.Forte@Sun.COM stmf_lun_map_t *ve_map = NULL;
9307836SJohn.Forte@Sun.COM stmf_ver_hg_t *verhg = NULL, *verhg_ex = NULL;
9317836SJohn.Forte@Sun.COM stmf_ver_tg_t *vertg = NULL, *vertg_ex = NULL;
9327836SJohn.Forte@Sun.COM char luid_new;
9337836SJohn.Forte@Sun.COM uint16_t lun_num;
9347836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu;
9357836SJohn.Forte@Sun.COM stmf_status_t ret;
9367836SJohn.Forte@Sun.COM
9377836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
9387836SJohn.Forte@Sun.COM
9397836SJohn.Forte@Sun.COM lun_num = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
9407836SJohn.Forte@Sun.COM
9417836SJohn.Forte@Sun.COM luid = stmf_lookup_id(&stmf_state.stmf_luid_list, 16, lu_guid);
9427836SJohn.Forte@Sun.COM if (luid == NULL) {
9437836SJohn.Forte@Sun.COM luid = stmf_alloc_id(16, STMF_ID_TYPE_LU_GUID, lu_guid, 0);
9447836SJohn.Forte@Sun.COM ilu = stmf_luident_to_ilu(lu_guid);
9457836SJohn.Forte@Sun.COM if (ilu) {
9467836SJohn.Forte@Sun.COM ilu->ilu_luid = luid;
9477836SJohn.Forte@Sun.COM luid->id_pt_to_object = (void *)ilu;
9487836SJohn.Forte@Sun.COM }
9497836SJohn.Forte@Sun.COM luid_new = 1;
9507836SJohn.Forte@Sun.COM } else {
9517836SJohn.Forte@Sun.COM luid_new = 0;
9527836SJohn.Forte@Sun.COM ilu = (stmf_i_lu_t *)luid->id_pt_to_object;
9537836SJohn.Forte@Sun.COM }
9547836SJohn.Forte@Sun.COM
9557836SJohn.Forte@Sun.COM /* The view entry won't be added if there is any confilict */
9567836SJohn.Forte@Sun.COM phg = (char *)hg->id_data; ptg = (char *)tg->id_data;
9577836SJohn.Forte@Sun.COM for (ve = (stmf_view_entry_t *)luid->id_impl_specific; ve != NULL;
9587836SJohn.Forte@Sun.COM ve = ve->ve_next) {
9597836SJohn.Forte@Sun.COM if (((phg[0] == '*') || (ve->ve_hg->id_data[0] == '*') ||
9607836SJohn.Forte@Sun.COM (hg == ve->ve_hg)) && ((ptg[0] == '*') ||
9617836SJohn.Forte@Sun.COM (ve->ve_tg->id_data[0] == '*') || (tg == ve->ve_tg))) {
9627836SJohn.Forte@Sun.COM *conflicting = ve;
9637836SJohn.Forte@Sun.COM *err_detail = STMF_IOCERR_VIEW_ENTRY_CONFLICT;
9647836SJohn.Forte@Sun.COM ret = STMF_ALREADY;
9657836SJohn.Forte@Sun.COM goto add_ve_err_ret;
9667836SJohn.Forte@Sun.COM }
9677836SJohn.Forte@Sun.COM }
9687836SJohn.Forte@Sun.COM
9697836SJohn.Forte@Sun.COM ve_map = stmf_duplicate_ve_map(0);
9707836SJohn.Forte@Sun.COM for (vertg = stmf_state.stmf_ver_tg_head; vertg != NULL;
9717836SJohn.Forte@Sun.COM vertg = vertg->vert_next) {
9727836SJohn.Forte@Sun.COM ptg = (char *)vertg->vert_tg_ref->id_data;
9737836SJohn.Forte@Sun.COM if ((ptg[0] != '*') && (tg->id_data[0] != '*') &&
9747836SJohn.Forte@Sun.COM (vertg->vert_tg_ref != tg)) {
9757836SJohn.Forte@Sun.COM continue;
9767836SJohn.Forte@Sun.COM }
9777836SJohn.Forte@Sun.COM if (vertg->vert_tg_ref == tg)
9787836SJohn.Forte@Sun.COM vertg_ex = vertg;
9797836SJohn.Forte@Sun.COM for (verhg = vertg->vert_verh_list; verhg != NULL;
9807836SJohn.Forte@Sun.COM verhg = verhg->verh_next) {
9817836SJohn.Forte@Sun.COM phg = (char *)verhg->verh_hg_ref->id_data;
9827836SJohn.Forte@Sun.COM if ((phg[0] != '*') && (hg->id_data[0] != '*') &&
9837836SJohn.Forte@Sun.COM (verhg->verh_hg_ref != hg)) {
9847836SJohn.Forte@Sun.COM continue;
9857836SJohn.Forte@Sun.COM }
9867836SJohn.Forte@Sun.COM if ((vertg_ex == vertg) && (verhg->verh_hg_ref == hg))
9877836SJohn.Forte@Sun.COM verhg_ex = verhg;
9887836SJohn.Forte@Sun.COM (void) stmf_merge_ve_map(&verhg->verh_ve_map, ve_map,
9897836SJohn.Forte@Sun.COM &ve_map, 0);
9907836SJohn.Forte@Sun.COM }
9917836SJohn.Forte@Sun.COM }
9927836SJohn.Forte@Sun.COM
9937836SJohn.Forte@Sun.COM if (lun[2] == 0xFF) {
9947836SJohn.Forte@Sun.COM /* Pick a LUN number */
9957836SJohn.Forte@Sun.COM lun_num = stmf_get_next_free_lun(ve_map, lun);
9967836SJohn.Forte@Sun.COM if (lun_num > 0x3FFF) {
9977836SJohn.Forte@Sun.COM stmf_destroy_ve_map(ve_map);
9987836SJohn.Forte@Sun.COM ret = STMF_NOT_SUPPORTED;
9997836SJohn.Forte@Sun.COM goto add_ve_err_ret;
10007836SJohn.Forte@Sun.COM }
10017836SJohn.Forte@Sun.COM } else {
10027836SJohn.Forte@Sun.COM if ((*conflicting = stmf_get_ent_from_map(ve_map, lun_num))
10037836SJohn.Forte@Sun.COM != NULL) {
10047836SJohn.Forte@Sun.COM stmf_destroy_ve_map(ve_map);
10057836SJohn.Forte@Sun.COM *err_detail = STMF_IOCERR_LU_NUMBER_IN_USE;
10067836SJohn.Forte@Sun.COM ret = STMF_LUN_TAKEN;
10077836SJohn.Forte@Sun.COM goto add_ve_err_ret;
10087836SJohn.Forte@Sun.COM }
10097836SJohn.Forte@Sun.COM }
10107836SJohn.Forte@Sun.COM stmf_destroy_ve_map(ve_map);
10117836SJohn.Forte@Sun.COM
10127836SJohn.Forte@Sun.COM /* All is well, do the actual addition now */
10137836SJohn.Forte@Sun.COM ve = (stmf_view_entry_t *)kmem_zalloc(sizeof (*ve), KM_SLEEP);
10147836SJohn.Forte@Sun.COM ve->ve_id = *ve_id;
10157836SJohn.Forte@Sun.COM ve->ve_lun[0] = lun[0];
10167836SJohn.Forte@Sun.COM ve->ve_lun[1] = lun[1];
10177836SJohn.Forte@Sun.COM
10187836SJohn.Forte@Sun.COM if ((ret = stmf_add_ve_to_luid(luid, ve)) != STMF_SUCCESS) {
10197836SJohn.Forte@Sun.COM kmem_free(ve, sizeof (stmf_view_entry_t));
10207836SJohn.Forte@Sun.COM goto add_ve_err_ret;
10217836SJohn.Forte@Sun.COM }
10227836SJohn.Forte@Sun.COM ve->ve_hg = hg; hg->id_refcnt++;
10237836SJohn.Forte@Sun.COM ve->ve_tg = tg; tg->id_refcnt++;
10247836SJohn.Forte@Sun.COM ve->ve_luid = luid; luid->id_refcnt++;
10257836SJohn.Forte@Sun.COM
10267836SJohn.Forte@Sun.COM *ve_id = ve->ve_id;
10277836SJohn.Forte@Sun.COM
10287836SJohn.Forte@Sun.COM if (luid_new) {
10297836SJohn.Forte@Sun.COM stmf_append_id(&stmf_state.stmf_luid_list, luid);
10307836SJohn.Forte@Sun.COM }
10317836SJohn.Forte@Sun.COM
10327836SJohn.Forte@Sun.COM if (vertg_ex == NULL) {
10337836SJohn.Forte@Sun.COM vertg_ex = (stmf_ver_tg_t *)kmem_zalloc(sizeof (stmf_ver_tg_t),
10347836SJohn.Forte@Sun.COM KM_SLEEP);
10357836SJohn.Forte@Sun.COM vertg_ex->vert_next = stmf_state.stmf_ver_tg_head;
10367836SJohn.Forte@Sun.COM stmf_state.stmf_ver_tg_head = vertg_ex;
10377836SJohn.Forte@Sun.COM vertg_ex->vert_tg_ref = tg;
10387836SJohn.Forte@Sun.COM verhg_ex = vertg_ex->vert_verh_list =
10397836SJohn.Forte@Sun.COM (stmf_ver_hg_t *)kmem_zalloc(sizeof (stmf_ver_hg_t),
10407836SJohn.Forte@Sun.COM KM_SLEEP);
10417836SJohn.Forte@Sun.COM verhg_ex->verh_hg_ref = hg;
10427836SJohn.Forte@Sun.COM }
10437836SJohn.Forte@Sun.COM if (verhg_ex == NULL) {
10447836SJohn.Forte@Sun.COM verhg_ex = (stmf_ver_hg_t *)kmem_zalloc(sizeof (stmf_ver_hg_t),
10457836SJohn.Forte@Sun.COM KM_SLEEP);
10467836SJohn.Forte@Sun.COM verhg_ex->verh_next = vertg_ex->vert_verh_list;
10477836SJohn.Forte@Sun.COM vertg_ex->vert_verh_list = verhg_ex;
10487836SJohn.Forte@Sun.COM verhg_ex->verh_hg_ref = hg;
10497836SJohn.Forte@Sun.COM }
10507836SJohn.Forte@Sun.COM ret = stmf_add_ent_to_map(&verhg_ex->verh_ve_map, ve, ve->ve_lun);
10517836SJohn.Forte@Sun.COM ASSERT(ret == STMF_SUCCESS);
10527836SJohn.Forte@Sun.COM
10537836SJohn.Forte@Sun.COM /* we need to update the affected session */
10547836SJohn.Forte@Sun.COM if (stmf_state.stmf_service_running) {
10557836SJohn.Forte@Sun.COM if (ilu && ilu->ilu_state == STMF_STATE_ONLINE)
10567836SJohn.Forte@Sun.COM stmf_update_sessions_per_ve(ve, ilu->ilu_lu, 1);
10577836SJohn.Forte@Sun.COM }
10587836SJohn.Forte@Sun.COM
10597836SJohn.Forte@Sun.COM return (STMF_SUCCESS);
10607836SJohn.Forte@Sun.COM add_ve_err_ret:
10617836SJohn.Forte@Sun.COM if (luid_new) {
10627836SJohn.Forte@Sun.COM if (ilu)
10637836SJohn.Forte@Sun.COM ilu->ilu_luid = NULL;
10647836SJohn.Forte@Sun.COM stmf_free_id(luid);
10657836SJohn.Forte@Sun.COM }
10667836SJohn.Forte@Sun.COM return (ret);
10677836SJohn.Forte@Sun.COM }
10687836SJohn.Forte@Sun.COM
10697836SJohn.Forte@Sun.COM stmf_status_t
stmf_add_ent_to_map(stmf_lun_map_t * lm,void * ent,uint8_t * lun)10707836SJohn.Forte@Sun.COM stmf_add_ent_to_map(stmf_lun_map_t *lm, void *ent, uint8_t *lun)
10717836SJohn.Forte@Sun.COM {
10727836SJohn.Forte@Sun.COM uint16_t n;
10737836SJohn.Forte@Sun.COM if (((lun[0] & 0xc0) >> 6) != 0)
10747836SJohn.Forte@Sun.COM return (STMF_FAILURE);
10757836SJohn.Forte@Sun.COM
10767836SJohn.Forte@Sun.COM n = (uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8);
10777836SJohn.Forte@Sun.COM try_again_to_add:
10787836SJohn.Forte@Sun.COM if (lm->lm_nentries && (n < lm->lm_nentries)) {
10797836SJohn.Forte@Sun.COM if (lm->lm_plus[n] == NULL) {
10807836SJohn.Forte@Sun.COM lm->lm_plus[n] = ent;
10817836SJohn.Forte@Sun.COM lm->lm_nluns++;
10827836SJohn.Forte@Sun.COM return (STMF_SUCCESS);
10837836SJohn.Forte@Sun.COM } else {
10847836SJohn.Forte@Sun.COM return (STMF_LUN_TAKEN);
10857836SJohn.Forte@Sun.COM }
10867836SJohn.Forte@Sun.COM } else {
10877836SJohn.Forte@Sun.COM void **pplu;
10887836SJohn.Forte@Sun.COM uint16_t m = n + 1;
10897836SJohn.Forte@Sun.COM m = ((m + 7) & ~7) & 0x7FFF;
10907836SJohn.Forte@Sun.COM pplu = (void **)kmem_zalloc(m * sizeof (void *), KM_SLEEP);
10917836SJohn.Forte@Sun.COM bcopy(lm->lm_plus, pplu,
10927836SJohn.Forte@Sun.COM lm->lm_nentries * sizeof (void *));
10937836SJohn.Forte@Sun.COM kmem_free(lm->lm_plus, lm->lm_nentries * sizeof (void *));
10947836SJohn.Forte@Sun.COM lm->lm_plus = pplu;
10957836SJohn.Forte@Sun.COM lm->lm_nentries = m;
10967836SJohn.Forte@Sun.COM goto try_again_to_add;
10977836SJohn.Forte@Sun.COM }
10987836SJohn.Forte@Sun.COM }
10997836SJohn.Forte@Sun.COM
11007836SJohn.Forte@Sun.COM
11017836SJohn.Forte@Sun.COM stmf_status_t
stmf_remove_ent_from_map(stmf_lun_map_t * lm,uint8_t * lun)11027836SJohn.Forte@Sun.COM stmf_remove_ent_from_map(stmf_lun_map_t *lm, uint8_t *lun)
11037836SJohn.Forte@Sun.COM {
11047836SJohn.Forte@Sun.COM uint16_t n, i;
11057836SJohn.Forte@Sun.COM uint8_t lutype = (lun[0] & 0xc0) >> 6;
11067836SJohn.Forte@Sun.COM if (lutype != 0)
11077836SJohn.Forte@Sun.COM return (STMF_FAILURE);
11087836SJohn.Forte@Sun.COM
11097836SJohn.Forte@Sun.COM n = (uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8);
11107836SJohn.Forte@Sun.COM
11117836SJohn.Forte@Sun.COM if (n >= lm->lm_nentries)
11127836SJohn.Forte@Sun.COM return (STMF_NOT_FOUND);
11137836SJohn.Forte@Sun.COM if (lm->lm_plus[n] == NULL)
11147836SJohn.Forte@Sun.COM return (STMF_NOT_FOUND);
11157836SJohn.Forte@Sun.COM
11167836SJohn.Forte@Sun.COM lm->lm_plus[n] = NULL;
11177836SJohn.Forte@Sun.COM lm->lm_nluns--;
11187836SJohn.Forte@Sun.COM
11197836SJohn.Forte@Sun.COM for (i = 0; i < lm->lm_nentries; i++) {
11207836SJohn.Forte@Sun.COM if (lm->lm_plus[lm->lm_nentries - 1 - i] != NULL)
11217836SJohn.Forte@Sun.COM break;
11227836SJohn.Forte@Sun.COM }
11237836SJohn.Forte@Sun.COM i &= ~15;
11247836SJohn.Forte@Sun.COM if (i >= 16) {
11257836SJohn.Forte@Sun.COM void **pplu;
11267836SJohn.Forte@Sun.COM uint16_t m;
11277836SJohn.Forte@Sun.COM m = lm->lm_nentries - i;
11287836SJohn.Forte@Sun.COM pplu = (void **)kmem_zalloc(m * sizeof (void *), KM_SLEEP);
11297836SJohn.Forte@Sun.COM bcopy(lm->lm_plus, pplu, m * sizeof (void *));
11307836SJohn.Forte@Sun.COM kmem_free(lm->lm_plus, lm->lm_nentries * sizeof (void *));
11317836SJohn.Forte@Sun.COM lm->lm_plus = pplu;
11327836SJohn.Forte@Sun.COM lm->lm_nentries = m;
11337836SJohn.Forte@Sun.COM }
11347836SJohn.Forte@Sun.COM
11357836SJohn.Forte@Sun.COM return (STMF_SUCCESS);
11367836SJohn.Forte@Sun.COM }
11377836SJohn.Forte@Sun.COM
11387836SJohn.Forte@Sun.COM uint16_t
stmf_get_next_free_lun(stmf_lun_map_t * sm,uint8_t * lun)11397836SJohn.Forte@Sun.COM stmf_get_next_free_lun(stmf_lun_map_t *sm, uint8_t *lun)
11407836SJohn.Forte@Sun.COM {
11417836SJohn.Forte@Sun.COM uint16_t luNbr;
11427836SJohn.Forte@Sun.COM
11437836SJohn.Forte@Sun.COM
11447836SJohn.Forte@Sun.COM if (sm->lm_nluns < 0x4000) {
11457836SJohn.Forte@Sun.COM for (luNbr = 0; luNbr < sm->lm_nentries; luNbr++) {
11467836SJohn.Forte@Sun.COM if (sm->lm_plus[luNbr] == NULL)
11477836SJohn.Forte@Sun.COM break;
11487836SJohn.Forte@Sun.COM }
11497836SJohn.Forte@Sun.COM } else {
11507836SJohn.Forte@Sun.COM return (0xFFFF);
11517836SJohn.Forte@Sun.COM }
11527836SJohn.Forte@Sun.COM if (lun) {
11537836SJohn.Forte@Sun.COM bzero(lun, 8);
11547836SJohn.Forte@Sun.COM lun[1] = luNbr & 0xff;
11557836SJohn.Forte@Sun.COM lun[0] = (luNbr >> 8) & 0xff;
11567836SJohn.Forte@Sun.COM }
11577836SJohn.Forte@Sun.COM
11587836SJohn.Forte@Sun.COM return (luNbr);
11597836SJohn.Forte@Sun.COM }
11607836SJohn.Forte@Sun.COM
11617836SJohn.Forte@Sun.COM void *
stmf_get_ent_from_map(stmf_lun_map_t * sm,uint16_t lun_num)11627836SJohn.Forte@Sun.COM stmf_get_ent_from_map(stmf_lun_map_t *sm, uint16_t lun_num)
11637836SJohn.Forte@Sun.COM {
11647836SJohn.Forte@Sun.COM if ((lun_num & 0xC000) == 0) {
11657836SJohn.Forte@Sun.COM if (sm->lm_nentries > lun_num)
11667836SJohn.Forte@Sun.COM return (sm->lm_plus[lun_num & 0x3FFF]);
11677836SJohn.Forte@Sun.COM else
11687836SJohn.Forte@Sun.COM return (NULL);
11697836SJohn.Forte@Sun.COM }
11707836SJohn.Forte@Sun.COM
11717836SJohn.Forte@Sun.COM return (NULL);
11727836SJohn.Forte@Sun.COM }
11737836SJohn.Forte@Sun.COM
11747836SJohn.Forte@Sun.COM int
stmf_add_ve(uint8_t * hgname,uint16_t hgname_size,uint8_t * tgname,uint16_t tgname_size,uint8_t * lu_guid,uint32_t * ve_id,uint8_t * luNbr,uint32_t * err_detail)11757836SJohn.Forte@Sun.COM stmf_add_ve(uint8_t *hgname, uint16_t hgname_size,
11767836SJohn.Forte@Sun.COM uint8_t *tgname, uint16_t tgname_size,
11777836SJohn.Forte@Sun.COM uint8_t *lu_guid, uint32_t *ve_id,
11787836SJohn.Forte@Sun.COM uint8_t *luNbr, uint32_t *err_detail)
11797836SJohn.Forte@Sun.COM {
11807836SJohn.Forte@Sun.COM stmf_id_data_t *hg;
11817836SJohn.Forte@Sun.COM stmf_id_data_t *tg;
11827836SJohn.Forte@Sun.COM stmf_view_entry_t *conflictve;
11837836SJohn.Forte@Sun.COM stmf_status_t ret;
11847836SJohn.Forte@Sun.COM
11857836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
11867836SJohn.Forte@Sun.COM
11877836SJohn.Forte@Sun.COM hg = stmf_lookup_id(&stmf_state.stmf_hg_list, hgname_size,
11887836SJohn.Forte@Sun.COM (uint8_t *)hgname);
11897836SJohn.Forte@Sun.COM if (!hg) {
11907836SJohn.Forte@Sun.COM *err_detail = STMF_IOCERR_INVALID_HG;
11917836SJohn.Forte@Sun.COM return (ENOENT); /* could not find group */
11927836SJohn.Forte@Sun.COM }
11937836SJohn.Forte@Sun.COM tg = stmf_lookup_id(&stmf_state.stmf_tg_list, tgname_size,
11947836SJohn.Forte@Sun.COM (uint8_t *)tgname);
11957836SJohn.Forte@Sun.COM if (!tg) {
11967836SJohn.Forte@Sun.COM *err_detail = STMF_IOCERR_INVALID_TG;
11977836SJohn.Forte@Sun.COM return (ENOENT); /* could not find group */
11987836SJohn.Forte@Sun.COM }
11997836SJohn.Forte@Sun.COM ret = stmf_add_view_entry(hg, tg, lu_guid, ve_id, luNbr,
12007836SJohn.Forte@Sun.COM &conflictve, err_detail);
12017836SJohn.Forte@Sun.COM
12027836SJohn.Forte@Sun.COM if (ret == STMF_ALREADY) {
12037836SJohn.Forte@Sun.COM return (EALREADY);
12047836SJohn.Forte@Sun.COM } else if (ret == STMF_LUN_TAKEN) {
12057836SJohn.Forte@Sun.COM return (EEXIST);
12067836SJohn.Forte@Sun.COM } else if (ret == STMF_NOT_SUPPORTED) {
12077836SJohn.Forte@Sun.COM return (E2BIG);
12087836SJohn.Forte@Sun.COM } else if (ret != STMF_SUCCESS) {
12097836SJohn.Forte@Sun.COM return (EINVAL);
12107836SJohn.Forte@Sun.COM }
12117836SJohn.Forte@Sun.COM return (0);
12127836SJohn.Forte@Sun.COM }
12137836SJohn.Forte@Sun.COM
12147836SJohn.Forte@Sun.COM int
stmf_remove_ve_by_id(uint8_t * guid,uint32_t veid,uint32_t * err_detail)12157836SJohn.Forte@Sun.COM stmf_remove_ve_by_id(uint8_t *guid, uint32_t veid, uint32_t *err_detail)
12167836SJohn.Forte@Sun.COM {
12177836SJohn.Forte@Sun.COM stmf_id_data_t *luid;
12187836SJohn.Forte@Sun.COM stmf_view_entry_t *ve;
12197836SJohn.Forte@Sun.COM stmf_ver_tg_t *vtg;
12207836SJohn.Forte@Sun.COM stmf_ver_hg_t *vhg;
12217836SJohn.Forte@Sun.COM stmf_ver_tg_t *prev_vtg = NULL;
12227836SJohn.Forte@Sun.COM stmf_ver_hg_t *prev_vhg = NULL;
12237836SJohn.Forte@Sun.COM int found = 0;
12247836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu;
12257836SJohn.Forte@Sun.COM
12267836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
12277836SJohn.Forte@Sun.COM luid = stmf_lookup_id(&stmf_state.stmf_luid_list, 16, guid);
12287836SJohn.Forte@Sun.COM if (luid == NULL) {
12297836SJohn.Forte@Sun.COM *err_detail = STMF_IOCERR_INVALID_LU_ID;
12307836SJohn.Forte@Sun.COM return (ENODEV);
12317836SJohn.Forte@Sun.COM }
12327836SJohn.Forte@Sun.COM ilu = (stmf_i_lu_t *)luid->id_pt_to_object;
12337836SJohn.Forte@Sun.COM
12347836SJohn.Forte@Sun.COM for (ve = (stmf_view_entry_t *)luid->id_impl_specific;
12357836SJohn.Forte@Sun.COM ve; ve = ve->ve_next) {
12367836SJohn.Forte@Sun.COM if (ve->ve_id == veid) {
12377836SJohn.Forte@Sun.COM break;
12387836SJohn.Forte@Sun.COM }
12397836SJohn.Forte@Sun.COM }
12407836SJohn.Forte@Sun.COM if (!ve) {
12417836SJohn.Forte@Sun.COM *err_detail = STMF_IOCERR_INVALID_VE_ID;
12427836SJohn.Forte@Sun.COM return (ENODEV);
12437836SJohn.Forte@Sun.COM }
12447836SJohn.Forte@Sun.COM /* remove the ve */
12457836SJohn.Forte@Sun.COM if (ve->ve_next)
12467836SJohn.Forte@Sun.COM ve->ve_next->ve_prev = ve->ve_prev;
12477836SJohn.Forte@Sun.COM if (ve->ve_prev)
12487836SJohn.Forte@Sun.COM ve->ve_prev->ve_next = ve->ve_next;
12497836SJohn.Forte@Sun.COM else {
12507836SJohn.Forte@Sun.COM luid->id_impl_specific = (void *)ve->ve_next;
12517836SJohn.Forte@Sun.COM if (!luid->id_impl_specific) {
12527836SJohn.Forte@Sun.COM /* don't have any view entries related to this lu */
12537836SJohn.Forte@Sun.COM stmf_remove_id(&stmf_state.stmf_luid_list, luid);
12547836SJohn.Forte@Sun.COM if (ilu)
12557836SJohn.Forte@Sun.COM ilu->ilu_luid = NULL;
12567836SJohn.Forte@Sun.COM stmf_free_id(luid);
12577836SJohn.Forte@Sun.COM }
12587836SJohn.Forte@Sun.COM }
12597836SJohn.Forte@Sun.COM
12607836SJohn.Forte@Sun.COM /* we need to update ver_hg->verh_ve_map */
12617836SJohn.Forte@Sun.COM for (vtg = stmf_state.stmf_ver_tg_head; vtg; vtg = vtg->vert_next) {
12627836SJohn.Forte@Sun.COM if (vtg->vert_tg_ref == ve->ve_tg) {
12637836SJohn.Forte@Sun.COM found = 1;
12647836SJohn.Forte@Sun.COM break;
12657836SJohn.Forte@Sun.COM }
12667836SJohn.Forte@Sun.COM prev_vtg = vtg;
12677836SJohn.Forte@Sun.COM }
12687836SJohn.Forte@Sun.COM ASSERT(found);
12697836SJohn.Forte@Sun.COM found = 0;
12707836SJohn.Forte@Sun.COM for (vhg = vtg->vert_verh_list; vhg; vhg = vhg->verh_next) {
12717836SJohn.Forte@Sun.COM if (vhg->verh_hg_ref == ve->ve_hg) {
12727836SJohn.Forte@Sun.COM found = 1;
12737836SJohn.Forte@Sun.COM break;
12747836SJohn.Forte@Sun.COM }
12757836SJohn.Forte@Sun.COM prev_vhg = vhg;
12767836SJohn.Forte@Sun.COM }
12777836SJohn.Forte@Sun.COM ASSERT(found);
12787836SJohn.Forte@Sun.COM
12797836SJohn.Forte@Sun.COM (void) stmf_remove_ent_from_map(&vhg->verh_ve_map, ve->ve_lun);
12807836SJohn.Forte@Sun.COM
12817836SJohn.Forte@Sun.COM /* free verhg if it don't have any ve entries related */
12827836SJohn.Forte@Sun.COM if (!vhg->verh_ve_map.lm_nluns) {
12837836SJohn.Forte@Sun.COM /* we don't have any view entry related */
12847836SJohn.Forte@Sun.COM if (prev_vhg)
12857836SJohn.Forte@Sun.COM prev_vhg->verh_next = vhg->verh_next;
12867836SJohn.Forte@Sun.COM else
12877836SJohn.Forte@Sun.COM vtg->vert_verh_list = vhg->verh_next;
12887836SJohn.Forte@Sun.COM
12897836SJohn.Forte@Sun.COM /* Free entries in case the map still has memory */
12907836SJohn.Forte@Sun.COM if (vhg->verh_ve_map.lm_nentries) {
12917836SJohn.Forte@Sun.COM kmem_free(vhg->verh_ve_map.lm_plus,
12927836SJohn.Forte@Sun.COM vhg->verh_ve_map.lm_nentries *
12937836SJohn.Forte@Sun.COM sizeof (void *));
12947836SJohn.Forte@Sun.COM }
12957836SJohn.Forte@Sun.COM kmem_free(vhg, sizeof (stmf_ver_hg_t));
12967836SJohn.Forte@Sun.COM if (!vtg->vert_verh_list) {
12977836SJohn.Forte@Sun.COM /* we don't have any ve related */
12987836SJohn.Forte@Sun.COM if (prev_vtg)
12997836SJohn.Forte@Sun.COM prev_vtg->vert_next = vtg->vert_next;
13007836SJohn.Forte@Sun.COM else
13017836SJohn.Forte@Sun.COM stmf_state.stmf_ver_tg_head = vtg->vert_next;
13027836SJohn.Forte@Sun.COM kmem_free(vtg, sizeof (stmf_ver_tg_t));
13037836SJohn.Forte@Sun.COM }
13047836SJohn.Forte@Sun.COM }
13057836SJohn.Forte@Sun.COM
13067836SJohn.Forte@Sun.COM if (stmf_state.stmf_service_running && ilu &&
13077836SJohn.Forte@Sun.COM ilu->ilu_state == STMF_STATE_ONLINE) {
13087836SJohn.Forte@Sun.COM stmf_update_sessions_per_ve(ve, ilu->ilu_lu, 0);
13097836SJohn.Forte@Sun.COM }
13107836SJohn.Forte@Sun.COM
13117836SJohn.Forte@Sun.COM ve->ve_hg->id_refcnt--;
13127836SJohn.Forte@Sun.COM ve->ve_tg->id_refcnt--;
13137836SJohn.Forte@Sun.COM
13147836SJohn.Forte@Sun.COM kmem_free(ve, sizeof (stmf_view_entry_t));
13157836SJohn.Forte@Sun.COM return (0);
13167836SJohn.Forte@Sun.COM }
13177836SJohn.Forte@Sun.COM
13187836SJohn.Forte@Sun.COM int
stmf_add_group(uint8_t * grpname,uint16_t grpname_size,stmf_id_type_t group_type,uint32_t * err_detail)13197836SJohn.Forte@Sun.COM stmf_add_group(uint8_t *grpname, uint16_t grpname_size,
13207836SJohn.Forte@Sun.COM stmf_id_type_t group_type, uint32_t *err_detail)
13217836SJohn.Forte@Sun.COM {
13227836SJohn.Forte@Sun.COM stmf_status_t status;
13237836SJohn.Forte@Sun.COM
13247836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
13257836SJohn.Forte@Sun.COM
13267836SJohn.Forte@Sun.COM if (group_type == STMF_ID_TYPE_HOST_GROUP)
13277836SJohn.Forte@Sun.COM status = stmf_add_hg(grpname, grpname_size, 0, err_detail);
13287836SJohn.Forte@Sun.COM else if (group_type == STMF_ID_TYPE_TARGET_GROUP)
13297836SJohn.Forte@Sun.COM status = stmf_add_tg(grpname, grpname_size, 0, err_detail);
13307836SJohn.Forte@Sun.COM else {
13317836SJohn.Forte@Sun.COM return (EINVAL);
13327836SJohn.Forte@Sun.COM }
13337836SJohn.Forte@Sun.COM switch (status) {
13347836SJohn.Forte@Sun.COM case STMF_SUCCESS:
13357836SJohn.Forte@Sun.COM return (0);
13367836SJohn.Forte@Sun.COM case STMF_INVALID_ARG:
13377836SJohn.Forte@Sun.COM return (EINVAL);
13387836SJohn.Forte@Sun.COM case STMF_ALREADY:
13397836SJohn.Forte@Sun.COM return (EEXIST);
13407836SJohn.Forte@Sun.COM default:
13417836SJohn.Forte@Sun.COM return (EIO);
13427836SJohn.Forte@Sun.COM }
13437836SJohn.Forte@Sun.COM }
13447836SJohn.Forte@Sun.COM
13457836SJohn.Forte@Sun.COM /*
13467836SJohn.Forte@Sun.COM * Group can only be removed only when it does not have
13477836SJohn.Forte@Sun.COM * any view entry related
13487836SJohn.Forte@Sun.COM */
13497836SJohn.Forte@Sun.COM int
stmf_remove_group(uint8_t * grpname,uint16_t grpname_size,stmf_id_type_t group_type,uint32_t * err_detail)13507836SJohn.Forte@Sun.COM stmf_remove_group(uint8_t *grpname, uint16_t grpname_size,
13517836SJohn.Forte@Sun.COM stmf_id_type_t group_type, uint32_t *err_detail)
13527836SJohn.Forte@Sun.COM {
13537836SJohn.Forte@Sun.COM stmf_id_data_t *id;
13547836SJohn.Forte@Sun.COM stmf_id_data_t *idmemb;
13557836SJohn.Forte@Sun.COM stmf_id_list_t *grp_memblist;
13567836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss;
13577836SJohn.Forte@Sun.COM stmf_i_local_port_t *ilport;
13587836SJohn.Forte@Sun.COM
13597836SJohn.Forte@Sun.COM if (grpname[0] == '*')
13607836SJohn.Forte@Sun.COM return (EINVAL);
13617836SJohn.Forte@Sun.COM
13627836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
13637836SJohn.Forte@Sun.COM
13647836SJohn.Forte@Sun.COM if (group_type == STMF_ID_TYPE_HOST_GROUP)
13657836SJohn.Forte@Sun.COM id = stmf_lookup_id(&stmf_state.stmf_hg_list,
13667836SJohn.Forte@Sun.COM grpname_size, grpname);
13677836SJohn.Forte@Sun.COM else if (group_type == STMF_ID_TYPE_TARGET_GROUP)
13687836SJohn.Forte@Sun.COM id = stmf_lookup_id(&stmf_state.stmf_tg_list,
13697836SJohn.Forte@Sun.COM grpname_size, grpname);
13707836SJohn.Forte@Sun.COM if (!id) {
13717836SJohn.Forte@Sun.COM *err_detail = (group_type == STMF_ID_TYPE_HOST_GROUP)?
13727836SJohn.Forte@Sun.COM STMF_IOCERR_INVALID_HG:STMF_IOCERR_INVALID_TG;
13737836SJohn.Forte@Sun.COM return (ENODEV); /* no such grp */
13747836SJohn.Forte@Sun.COM }
13757836SJohn.Forte@Sun.COM if (id->id_refcnt) {
13767836SJohn.Forte@Sun.COM /* fail, still have viewentry related to it */
13777836SJohn.Forte@Sun.COM *err_detail = (group_type == STMF_ID_TYPE_HOST_GROUP)?
13787836SJohn.Forte@Sun.COM STMF_IOCERR_HG_IN_USE:STMF_IOCERR_TG_IN_USE;
13797836SJohn.Forte@Sun.COM return (EBUSY);
13807836SJohn.Forte@Sun.COM }
13817836SJohn.Forte@Sun.COM grp_memblist = (stmf_id_list_t *)id->id_impl_specific;
13827836SJohn.Forte@Sun.COM while ((idmemb = grp_memblist->idl_head) != NULL) {
13837836SJohn.Forte@Sun.COM stmf_remove_id(grp_memblist, idmemb);
13847836SJohn.Forte@Sun.COM stmf_free_id(idmemb);
13857836SJohn.Forte@Sun.COM }
13867836SJohn.Forte@Sun.COM
13877836SJohn.Forte@Sun.COM ASSERT(!grp_memblist->id_count);
13887836SJohn.Forte@Sun.COM if (id->id_type == STMF_ID_TYPE_TARGET_GROUP) {
13897836SJohn.Forte@Sun.COM for (ilport = stmf_state.stmf_ilportlist; ilport;
13907836SJohn.Forte@Sun.COM ilport = ilport->ilport_next) {
13917836SJohn.Forte@Sun.COM if (ilport->ilport_tg == (void *)id) {
13927836SJohn.Forte@Sun.COM ilport->ilport_tg = NULL;
13937836SJohn.Forte@Sun.COM }
13947836SJohn.Forte@Sun.COM }
13957836SJohn.Forte@Sun.COM stmf_remove_id(&stmf_state.stmf_tg_list, id);
13967836SJohn.Forte@Sun.COM } else {
13977836SJohn.Forte@Sun.COM for (ilport = stmf_state.stmf_ilportlist; ilport;
13987836SJohn.Forte@Sun.COM ilport = ilport->ilport_next) {
13997836SJohn.Forte@Sun.COM for (iss = ilport->ilport_ss_list; iss;
14007836SJohn.Forte@Sun.COM iss = iss->iss_next) {
14017836SJohn.Forte@Sun.COM if (iss->iss_hg == (void *)id)
14027836SJohn.Forte@Sun.COM iss->iss_hg = NULL;
14037836SJohn.Forte@Sun.COM }
14047836SJohn.Forte@Sun.COM }
14057836SJohn.Forte@Sun.COM stmf_remove_id(&stmf_state.stmf_hg_list, id);
14067836SJohn.Forte@Sun.COM }
14077836SJohn.Forte@Sun.COM stmf_free_id(id);
14087836SJohn.Forte@Sun.COM return (0);
14097836SJohn.Forte@Sun.COM
14107836SJohn.Forte@Sun.COM }
14117836SJohn.Forte@Sun.COM
14127836SJohn.Forte@Sun.COM int
stmf_add_group_member(uint8_t * grpname,uint16_t grpname_size,uint8_t * entry_ident,uint16_t entry_size,stmf_id_type_t entry_type,uint32_t * err_detail)14137836SJohn.Forte@Sun.COM stmf_add_group_member(uint8_t *grpname, uint16_t grpname_size,
14147836SJohn.Forte@Sun.COM uint8_t *entry_ident, uint16_t entry_size,
14157836SJohn.Forte@Sun.COM stmf_id_type_t entry_type, uint32_t *err_detail)
14167836SJohn.Forte@Sun.COM {
14177836SJohn.Forte@Sun.COM stmf_id_data_t *id_grp, *id_alltgt;
14187836SJohn.Forte@Sun.COM stmf_id_data_t *id_member;
14197836SJohn.Forte@Sun.COM stmf_id_data_t *id_grp_tmp;
14207836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss;
14217836SJohn.Forte@Sun.COM stmf_i_local_port_t *ilport;
14227836SJohn.Forte@Sun.COM stmf_lun_map_t *vemap, *vemap_alltgt;
14237836SJohn.Forte@Sun.COM uint8_t grpname_forall = '*';
14247836SJohn.Forte@Sun.COM
14257836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
14267836SJohn.Forte@Sun.COM ASSERT(grpname[0] != '*');
14277836SJohn.Forte@Sun.COM
14287836SJohn.Forte@Sun.COM if (entry_type == STMF_ID_TYPE_HOST) {
14297836SJohn.Forte@Sun.COM id_grp = stmf_lookup_id(&stmf_state.stmf_hg_list,
14307836SJohn.Forte@Sun.COM grpname_size, grpname);
14317836SJohn.Forte@Sun.COM id_grp_tmp = stmf_lookup_group_for_host(entry_ident,
14327836SJohn.Forte@Sun.COM entry_size);
14337836SJohn.Forte@Sun.COM } else {
14347836SJohn.Forte@Sun.COM id_grp = stmf_lookup_id(&stmf_state.stmf_tg_list,
14357836SJohn.Forte@Sun.COM grpname_size, grpname);
14367836SJohn.Forte@Sun.COM id_grp_tmp = stmf_lookup_group_for_target(entry_ident,
14377836SJohn.Forte@Sun.COM entry_size);
14387836SJohn.Forte@Sun.COM }
14397836SJohn.Forte@Sun.COM if (id_grp == NULL) {
14407836SJohn.Forte@Sun.COM *err_detail = (entry_type == STMF_ID_TYPE_HOST)?
14417836SJohn.Forte@Sun.COM STMF_IOCERR_INVALID_HG:STMF_IOCERR_INVALID_TG;
14427836SJohn.Forte@Sun.COM return (ENODEV); /* not found */
14437836SJohn.Forte@Sun.COM }
14447836SJohn.Forte@Sun.COM
14457836SJohn.Forte@Sun.COM /* Check whether this member already bound to a group */
14467836SJohn.Forte@Sun.COM if (id_grp_tmp) {
14477836SJohn.Forte@Sun.COM if (id_grp_tmp != id_grp) {
14487836SJohn.Forte@Sun.COM *err_detail = (entry_type == STMF_ID_TYPE_HOST)?
14497836SJohn.Forte@Sun.COM STMF_IOCERR_HG_ENTRY_EXISTS:
14507836SJohn.Forte@Sun.COM STMF_IOCERR_TG_ENTRY_EXISTS;
14517836SJohn.Forte@Sun.COM return (EEXIST); /* already added into another grp */
14527836SJohn.Forte@Sun.COM }
14537836SJohn.Forte@Sun.COM else
14547836SJohn.Forte@Sun.COM return (0);
14557836SJohn.Forte@Sun.COM }
145611108STim.Szeto@Sun.COM
145711108STim.Szeto@Sun.COM /* verify target is offline */
145811108STim.Szeto@Sun.COM if (entry_type == STMF_ID_TYPE_TARGET) {
145911108STim.Szeto@Sun.COM ilport = stmf_targetident_to_ilport(entry_ident, entry_size);
146011108STim.Szeto@Sun.COM if (ilport && ilport->ilport_state != STMF_STATE_OFFLINE) {
146111108STim.Szeto@Sun.COM *err_detail = STMF_IOCERR_TG_NEED_TG_OFFLINE;
146211108STim.Szeto@Sun.COM return (EBUSY);
146311108STim.Szeto@Sun.COM }
146411108STim.Szeto@Sun.COM }
146511108STim.Szeto@Sun.COM
14667836SJohn.Forte@Sun.COM id_member = stmf_alloc_id(entry_size, entry_type,
14677836SJohn.Forte@Sun.COM entry_ident, 0);
14687836SJohn.Forte@Sun.COM stmf_append_id((stmf_id_list_t *)id_grp->id_impl_specific, id_member);
14697836SJohn.Forte@Sun.COM
14707836SJohn.Forte@Sun.COM if (entry_type == STMF_ID_TYPE_TARGET) {
14717836SJohn.Forte@Sun.COM ilport = stmf_targetident_to_ilport(entry_ident, entry_size);
14727836SJohn.Forte@Sun.COM if (ilport)
14737836SJohn.Forte@Sun.COM ilport->ilport_tg = (void *)id_grp;
14747836SJohn.Forte@Sun.COM return (0);
14757836SJohn.Forte@Sun.COM }
14767836SJohn.Forte@Sun.COM /* For host group member, update the session if needed */
14777836SJohn.Forte@Sun.COM if (!stmf_state.stmf_service_running)
14787836SJohn.Forte@Sun.COM return (0);
14797836SJohn.Forte@Sun.COM /* Need to consider all target group + this host group */
14807836SJohn.Forte@Sun.COM id_alltgt = stmf_lookup_id(&stmf_state.stmf_tg_list,
14817836SJohn.Forte@Sun.COM 1, &grpname_forall);
14827836SJohn.Forte@Sun.COM vemap_alltgt = stmf_get_ve_map_per_ids(id_alltgt, id_grp);
14837836SJohn.Forte@Sun.COM
14847836SJohn.Forte@Sun.COM /* check whether there are sessions may be affected */
14857836SJohn.Forte@Sun.COM for (ilport = stmf_state.stmf_ilportlist; ilport;
14867836SJohn.Forte@Sun.COM ilport = ilport->ilport_next) {
14877836SJohn.Forte@Sun.COM if (ilport->ilport_state != STMF_STATE_ONLINE)
14887836SJohn.Forte@Sun.COM continue;
14897836SJohn.Forte@Sun.COM iss = stmf_lookup_session_for_hostident(ilport,
14907836SJohn.Forte@Sun.COM entry_ident, entry_size);
14917836SJohn.Forte@Sun.COM if (iss) {
14927836SJohn.Forte@Sun.COM stmf_id_data_t *tgid;
14937836SJohn.Forte@Sun.COM iss->iss_hg = (void *)id_grp;
14947836SJohn.Forte@Sun.COM tgid = ilport->ilport_tg;
14957836SJohn.Forte@Sun.COM if (tgid) {
14967836SJohn.Forte@Sun.COM vemap = stmf_get_ve_map_per_ids(tgid, id_grp);
14977836SJohn.Forte@Sun.COM if (vemap)
14987836SJohn.Forte@Sun.COM stmf_add_lus_to_session_per_vemap(
14997836SJohn.Forte@Sun.COM ilport, iss, vemap);
15007836SJohn.Forte@Sun.COM }
15017836SJohn.Forte@Sun.COM if (vemap_alltgt)
15027836SJohn.Forte@Sun.COM stmf_add_lus_to_session_per_vemap(ilport,
15037836SJohn.Forte@Sun.COM iss, vemap_alltgt);
15047836SJohn.Forte@Sun.COM }
15057836SJohn.Forte@Sun.COM }
15067836SJohn.Forte@Sun.COM
15077836SJohn.Forte@Sun.COM return (0);
15087836SJohn.Forte@Sun.COM }
15097836SJohn.Forte@Sun.COM
15107836SJohn.Forte@Sun.COM int
stmf_remove_group_member(uint8_t * grpname,uint16_t grpname_size,uint8_t * entry_ident,uint16_t entry_size,stmf_id_type_t entry_type,uint32_t * err_detail)15117836SJohn.Forte@Sun.COM stmf_remove_group_member(uint8_t *grpname, uint16_t grpname_size,
15127836SJohn.Forte@Sun.COM uint8_t *entry_ident, uint16_t entry_size,
15137836SJohn.Forte@Sun.COM stmf_id_type_t entry_type, uint32_t *err_detail)
15147836SJohn.Forte@Sun.COM {
15157836SJohn.Forte@Sun.COM stmf_id_data_t *id_grp, *id_alltgt;
15167836SJohn.Forte@Sun.COM stmf_id_data_t *id_member;
15177836SJohn.Forte@Sun.COM stmf_lun_map_t *vemap, *vemap_alltgt;
15187836SJohn.Forte@Sun.COM uint8_t grpname_forall = '*';
15197836SJohn.Forte@Sun.COM stmf_i_local_port_t *ilport;
15207836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss;
15217836SJohn.Forte@Sun.COM
15227836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
15237836SJohn.Forte@Sun.COM ASSERT(grpname[0] != '*');
15247836SJohn.Forte@Sun.COM
15257836SJohn.Forte@Sun.COM if (entry_type == STMF_ID_TYPE_HOST) {
15267836SJohn.Forte@Sun.COM id_grp = stmf_lookup_id(&stmf_state.stmf_hg_list,
15277836SJohn.Forte@Sun.COM grpname_size, grpname);
15287836SJohn.Forte@Sun.COM } else {
15297836SJohn.Forte@Sun.COM id_grp = stmf_lookup_id(&stmf_state.stmf_tg_list,
15307836SJohn.Forte@Sun.COM grpname_size, grpname);
15317836SJohn.Forte@Sun.COM }
15327836SJohn.Forte@Sun.COM if (id_grp == NULL) {
15337836SJohn.Forte@Sun.COM *err_detail = (entry_type == STMF_ID_TYPE_HOST)?
15347836SJohn.Forte@Sun.COM STMF_IOCERR_INVALID_HG:STMF_IOCERR_INVALID_TG;
15357836SJohn.Forte@Sun.COM return (ENODEV); /* no such group */
15367836SJohn.Forte@Sun.COM }
15377836SJohn.Forte@Sun.COM id_member = stmf_lookup_id((stmf_id_list_t *)id_grp->id_impl_specific,
15387836SJohn.Forte@Sun.COM entry_size, entry_ident);
15397836SJohn.Forte@Sun.COM if (!id_member) {
15407836SJohn.Forte@Sun.COM *err_detail = (entry_type == STMF_ID_TYPE_HOST)?
15417836SJohn.Forte@Sun.COM STMF_IOCERR_INVALID_HG_ENTRY:STMF_IOCERR_INVALID_TG_ENTRY;
15427836SJohn.Forte@Sun.COM return (ENODEV); /* no such member */
15437836SJohn.Forte@Sun.COM }
15449884STim.Szeto@Sun.COM /* verify target is offline */
15459884STim.Szeto@Sun.COM if (entry_type == STMF_ID_TYPE_TARGET) {
15469884STim.Szeto@Sun.COM ilport = stmf_targetident_to_ilport(entry_ident, entry_size);
15479884STim.Szeto@Sun.COM if (ilport && ilport->ilport_state != STMF_STATE_OFFLINE) {
15489884STim.Szeto@Sun.COM *err_detail = STMF_IOCERR_TG_NEED_TG_OFFLINE;
15499884STim.Szeto@Sun.COM return (EBUSY);
15509884STim.Szeto@Sun.COM }
15519884STim.Szeto@Sun.COM }
15529884STim.Szeto@Sun.COM
15537836SJohn.Forte@Sun.COM stmf_remove_id((stmf_id_list_t *)id_grp->id_impl_specific, id_member);
15547836SJohn.Forte@Sun.COM stmf_free_id(id_member);
15557836SJohn.Forte@Sun.COM
15567836SJohn.Forte@Sun.COM if (entry_type == STMF_ID_TYPE_TARGET) {
15577836SJohn.Forte@Sun.COM ilport = stmf_targetident_to_ilport(entry_ident, entry_size);
15587836SJohn.Forte@Sun.COM if (ilport)
15597836SJohn.Forte@Sun.COM ilport->ilport_tg = NULL;
15607836SJohn.Forte@Sun.COM return (0);
15617836SJohn.Forte@Sun.COM }
15627836SJohn.Forte@Sun.COM /* For host group member, update the session */
15637836SJohn.Forte@Sun.COM if (!stmf_state.stmf_service_running)
15647836SJohn.Forte@Sun.COM return (0);
15657836SJohn.Forte@Sun.COM
15667836SJohn.Forte@Sun.COM /* Need to consider all target group + this host group */
15677836SJohn.Forte@Sun.COM id_alltgt = stmf_lookup_id(&stmf_state.stmf_tg_list,
15687836SJohn.Forte@Sun.COM 1, &grpname_forall);
15697836SJohn.Forte@Sun.COM vemap_alltgt = stmf_get_ve_map_per_ids(id_alltgt, id_grp);
15707836SJohn.Forte@Sun.COM
15717836SJohn.Forte@Sun.COM /* check if there are session related, if so, update it */
15727836SJohn.Forte@Sun.COM for (ilport = stmf_state.stmf_ilportlist; ilport;
15737836SJohn.Forte@Sun.COM ilport = ilport->ilport_next) {
15747836SJohn.Forte@Sun.COM if (ilport->ilport_state != STMF_STATE_ONLINE)
15757836SJohn.Forte@Sun.COM continue;
15767836SJohn.Forte@Sun.COM iss = stmf_lookup_session_for_hostident(ilport,
15777836SJohn.Forte@Sun.COM entry_ident, entry_size);
15787836SJohn.Forte@Sun.COM if (iss) {
15797836SJohn.Forte@Sun.COM stmf_id_data_t *tgid;
15807836SJohn.Forte@Sun.COM iss->iss_hg = NULL;
15817836SJohn.Forte@Sun.COM tgid = ilport->ilport_tg;
15827836SJohn.Forte@Sun.COM if (tgid) {
15837836SJohn.Forte@Sun.COM vemap = stmf_get_ve_map_per_ids(tgid, id_grp);
15847836SJohn.Forte@Sun.COM if (vemap)
15857836SJohn.Forte@Sun.COM stmf_remove_lus_from_session_per_vemap(
15867836SJohn.Forte@Sun.COM ilport, iss, vemap);
15877836SJohn.Forte@Sun.COM }
15887836SJohn.Forte@Sun.COM if (vemap_alltgt)
15897836SJohn.Forte@Sun.COM stmf_remove_lus_from_session_per_vemap(ilport,
15907836SJohn.Forte@Sun.COM iss, vemap_alltgt);
15917836SJohn.Forte@Sun.COM }
15927836SJohn.Forte@Sun.COM }
15937836SJohn.Forte@Sun.COM
15947836SJohn.Forte@Sun.COM return (0);
15957836SJohn.Forte@Sun.COM }
15967836SJohn.Forte@Sun.COM
15977836SJohn.Forte@Sun.COM /* Assert stmf_lock is already held */
15987836SJohn.Forte@Sun.COM stmf_i_local_port_t *
stmf_targetident_to_ilport(uint8_t * target_ident,uint16_t ident_size)15997836SJohn.Forte@Sun.COM stmf_targetident_to_ilport(uint8_t *target_ident, uint16_t ident_size)
16007836SJohn.Forte@Sun.COM {
16017836SJohn.Forte@Sun.COM stmf_i_local_port_t *ilport;
16027836SJohn.Forte@Sun.COM uint8_t *id;
16037836SJohn.Forte@Sun.COM
16047836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
16057836SJohn.Forte@Sun.COM
16067836SJohn.Forte@Sun.COM for (ilport = stmf_state.stmf_ilportlist; ilport;
16077836SJohn.Forte@Sun.COM ilport = ilport->ilport_next) {
16087836SJohn.Forte@Sun.COM id = (uint8_t *)ilport->ilport_lport->lport_id;
16097836SJohn.Forte@Sun.COM if ((id[3] == ident_size) &&
16107836SJohn.Forte@Sun.COM bcmp(id + 4, target_ident, ident_size) == 0) {
16117836SJohn.Forte@Sun.COM return (ilport);
16127836SJohn.Forte@Sun.COM }
16137836SJohn.Forte@Sun.COM }
16147836SJohn.Forte@Sun.COM return (NULL);
16157836SJohn.Forte@Sun.COM }
16167836SJohn.Forte@Sun.COM
16177836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *
stmf_lookup_session_for_hostident(stmf_i_local_port_t * ilport,uint8_t * host_ident,uint16_t ident_size)16187836SJohn.Forte@Sun.COM stmf_lookup_session_for_hostident(stmf_i_local_port_t *ilport,
16197836SJohn.Forte@Sun.COM uint8_t *host_ident, uint16_t ident_size)
16207836SJohn.Forte@Sun.COM {
16217836SJohn.Forte@Sun.COM stmf_i_scsi_session_t *iss;
16227836SJohn.Forte@Sun.COM uint8_t *id;
16237836SJohn.Forte@Sun.COM
16247836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
16257836SJohn.Forte@Sun.COM
16267836SJohn.Forte@Sun.COM for (iss = ilport->ilport_ss_list; iss; iss = iss->iss_next) {
16277836SJohn.Forte@Sun.COM id = (uint8_t *)iss->iss_ss->ss_rport_id;
16287836SJohn.Forte@Sun.COM if ((id[3] == ident_size) &&
16297836SJohn.Forte@Sun.COM bcmp(id + 4, host_ident, ident_size) == 0) {
16307836SJohn.Forte@Sun.COM return (iss);
16317836SJohn.Forte@Sun.COM }
16327836SJohn.Forte@Sun.COM }
16337836SJohn.Forte@Sun.COM return (NULL);
16347836SJohn.Forte@Sun.COM }
16357836SJohn.Forte@Sun.COM
16367836SJohn.Forte@Sun.COM stmf_i_lu_t *
stmf_luident_to_ilu(uint8_t * lu_ident)16377836SJohn.Forte@Sun.COM stmf_luident_to_ilu(uint8_t *lu_ident)
16387836SJohn.Forte@Sun.COM {
16397836SJohn.Forte@Sun.COM stmf_i_lu_t *ilu;
16407836SJohn.Forte@Sun.COM
16417836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
16427836SJohn.Forte@Sun.COM
16437836SJohn.Forte@Sun.COM for (ilu = stmf_state.stmf_ilulist; ilu; ilu = ilu->ilu_next) {
16447836SJohn.Forte@Sun.COM if (bcmp(&ilu->ilu_lu->lu_id->ident[0], lu_ident, 16) == 0)
16457836SJohn.Forte@Sun.COM return (ilu);
16467836SJohn.Forte@Sun.COM }
16477836SJohn.Forte@Sun.COM
16487836SJohn.Forte@Sun.COM return (NULL);
16497836SJohn.Forte@Sun.COM }
16507836SJohn.Forte@Sun.COM
16517836SJohn.Forte@Sun.COM /*
16527836SJohn.Forte@Sun.COM * Assert stmf_lock is already held,
16537836SJohn.Forte@Sun.COM * Just get the view map for the specific target group and host group
16547836SJohn.Forte@Sun.COM * tgid and hgid can not be NULL
16557836SJohn.Forte@Sun.COM */
16567836SJohn.Forte@Sun.COM stmf_lun_map_t *
stmf_get_ve_map_per_ids(stmf_id_data_t * tgid,stmf_id_data_t * hgid)16577836SJohn.Forte@Sun.COM stmf_get_ve_map_per_ids(stmf_id_data_t *tgid, stmf_id_data_t *hgid)
16587836SJohn.Forte@Sun.COM {
16597836SJohn.Forte@Sun.COM int found = 0;
16607836SJohn.Forte@Sun.COM stmf_ver_tg_t *vertg;
16617836SJohn.Forte@Sun.COM stmf_ver_hg_t *verhg;
16627836SJohn.Forte@Sun.COM
16637836SJohn.Forte@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
16647836SJohn.Forte@Sun.COM
16657836SJohn.Forte@Sun.COM for (vertg = stmf_state.stmf_ver_tg_head;
16667836SJohn.Forte@Sun.COM vertg; vertg = vertg->vert_next) {
16677836SJohn.Forte@Sun.COM if (vertg->vert_tg_ref == tgid) {
16687836SJohn.Forte@Sun.COM found = 1;
16697836SJohn.Forte@Sun.COM break;
16707836SJohn.Forte@Sun.COM }
16717836SJohn.Forte@Sun.COM }
16727836SJohn.Forte@Sun.COM if (!found)
16737836SJohn.Forte@Sun.COM return (NULL);
16747836SJohn.Forte@Sun.COM
16757836SJohn.Forte@Sun.COM for (verhg = vertg->vert_verh_list; verhg; verhg = verhg->verh_next) {
16767836SJohn.Forte@Sun.COM if (verhg->verh_hg_ref == hgid) {
16777836SJohn.Forte@Sun.COM return (&verhg->verh_ve_map);
16787836SJohn.Forte@Sun.COM }
16797836SJohn.Forte@Sun.COM }
16807836SJohn.Forte@Sun.COM return (NULL);
16817836SJohn.Forte@Sun.COM }
168210691STim.Szeto@Sun.COM
168310691STim.Szeto@Sun.COM stmf_status_t
stmf_validate_lun_view_entry(stmf_id_data_t * hg,stmf_id_data_t * tg,uint8_t * lun,uint32_t * err_detail)168410691STim.Szeto@Sun.COM stmf_validate_lun_view_entry(stmf_id_data_t *hg, stmf_id_data_t *tg,
168510691STim.Szeto@Sun.COM uint8_t *lun, uint32_t *err_detail)
168610691STim.Szeto@Sun.COM {
168710691STim.Szeto@Sun.COM char *phg, *ptg;
168810691STim.Szeto@Sun.COM stmf_lun_map_t *ve_map = NULL;
168910691STim.Szeto@Sun.COM stmf_ver_hg_t *verhg = NULL;
169010691STim.Szeto@Sun.COM stmf_ver_tg_t *vertg = NULL;
169110691STim.Szeto@Sun.COM uint16_t lun_num;
169210691STim.Szeto@Sun.COM stmf_status_t ret = STMF_SUCCESS;
169310691STim.Szeto@Sun.COM
169410691STim.Szeto@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
169510691STim.Szeto@Sun.COM
169610691STim.Szeto@Sun.COM ve_map = stmf_duplicate_ve_map(0);
169710691STim.Szeto@Sun.COM for (vertg = stmf_state.stmf_ver_tg_head; vertg != NULL;
169810691STim.Szeto@Sun.COM vertg = vertg->vert_next) {
169910691STim.Szeto@Sun.COM ptg = (char *)vertg->vert_tg_ref->id_data;
170010691STim.Szeto@Sun.COM if ((ptg[0] != '*') && (tg->id_data[0] != '*') &&
170110691STim.Szeto@Sun.COM (vertg->vert_tg_ref != tg)) {
170210691STim.Szeto@Sun.COM continue;
170310691STim.Szeto@Sun.COM }
170410691STim.Szeto@Sun.COM for (verhg = vertg->vert_verh_list; verhg != NULL;
170510691STim.Szeto@Sun.COM verhg = verhg->verh_next) {
170610691STim.Szeto@Sun.COM phg = (char *)verhg->verh_hg_ref->id_data;
170710691STim.Szeto@Sun.COM if ((phg[0] != '*') && (hg->id_data[0] != '*') &&
170810691STim.Szeto@Sun.COM (verhg->verh_hg_ref != hg)) {
170910691STim.Szeto@Sun.COM continue;
171010691STim.Szeto@Sun.COM }
171110691STim.Szeto@Sun.COM (void) stmf_merge_ve_map(&verhg->verh_ve_map, ve_map,
171210691STim.Szeto@Sun.COM &ve_map, 0);
171310691STim.Szeto@Sun.COM }
171410691STim.Szeto@Sun.COM }
171510691STim.Szeto@Sun.COM
171610691STim.Szeto@Sun.COM ret = STMF_SUCCESS;
171710691STim.Szeto@Sun.COM /* Return an available lun number */
171810691STim.Szeto@Sun.COM if (lun[2] == 0xFF) {
171910691STim.Szeto@Sun.COM /* Pick a LUN number */
172010691STim.Szeto@Sun.COM lun_num = stmf_get_next_free_lun(ve_map, lun);
172110691STim.Szeto@Sun.COM if (lun_num > 0x3FFF)
172210691STim.Szeto@Sun.COM ret = STMF_NOT_SUPPORTED;
172310691STim.Szeto@Sun.COM } else {
172410691STim.Szeto@Sun.COM lun_num = (uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8);
172510691STim.Szeto@Sun.COM if (stmf_get_ent_from_map(ve_map, lun_num) != NULL) {
172610691STim.Szeto@Sun.COM *err_detail = STMF_IOCERR_LU_NUMBER_IN_USE;
172710691STim.Szeto@Sun.COM ret = STMF_LUN_TAKEN;
172810691STim.Szeto@Sun.COM }
172910691STim.Szeto@Sun.COM }
173010691STim.Szeto@Sun.COM stmf_destroy_ve_map(ve_map);
173110691STim.Szeto@Sun.COM
173210691STim.Szeto@Sun.COM return (ret);
173310691STim.Szeto@Sun.COM }
173410691STim.Szeto@Sun.COM
173510691STim.Szeto@Sun.COM int
stmf_validate_lun_ve(uint8_t * hgname,uint16_t hgname_size,uint8_t * tgname,uint16_t tgname_size,uint8_t * luNbr,uint32_t * err_detail)173610691STim.Szeto@Sun.COM stmf_validate_lun_ve(uint8_t *hgname, uint16_t hgname_size,
173710691STim.Szeto@Sun.COM uint8_t *tgname, uint16_t tgname_size,
173810691STim.Szeto@Sun.COM uint8_t *luNbr, uint32_t *err_detail)
173910691STim.Szeto@Sun.COM {
174010691STim.Szeto@Sun.COM stmf_id_data_t *hg;
174110691STim.Szeto@Sun.COM stmf_id_data_t *tg;
174210691STim.Szeto@Sun.COM stmf_status_t ret;
174310691STim.Szeto@Sun.COM
174410691STim.Szeto@Sun.COM ASSERT(mutex_owned(&stmf_state.stmf_lock));
174510691STim.Szeto@Sun.COM
174610691STim.Szeto@Sun.COM hg = stmf_lookup_id(&stmf_state.stmf_hg_list, hgname_size,
174710691STim.Szeto@Sun.COM (uint8_t *)hgname);
174810691STim.Szeto@Sun.COM if (!hg) {
174910691STim.Szeto@Sun.COM *err_detail = STMF_IOCERR_INVALID_HG;
175010691STim.Szeto@Sun.COM return (ENOENT); /* could not find group */
175110691STim.Szeto@Sun.COM }
175210691STim.Szeto@Sun.COM tg = stmf_lookup_id(&stmf_state.stmf_tg_list, tgname_size,
175310691STim.Szeto@Sun.COM (uint8_t *)tgname);
175410691STim.Szeto@Sun.COM if (!tg) {
175510691STim.Szeto@Sun.COM *err_detail = STMF_IOCERR_INVALID_TG;
175610691STim.Szeto@Sun.COM return (ENOENT); /* could not find group */
175710691STim.Szeto@Sun.COM }
175810691STim.Szeto@Sun.COM ret = stmf_validate_lun_view_entry(hg, tg, luNbr, err_detail);
175910691STim.Szeto@Sun.COM
176010691STim.Szeto@Sun.COM if (ret == STMF_LUN_TAKEN) {
176110691STim.Szeto@Sun.COM return (EEXIST);
176210691STim.Szeto@Sun.COM } else if (ret == STMF_NOT_SUPPORTED) {
176310691STim.Szeto@Sun.COM return (E2BIG);
176410691STim.Szeto@Sun.COM } else if (ret != STMF_SUCCESS) {
176510691STim.Szeto@Sun.COM return (EINVAL);
176610691STim.Szeto@Sun.COM }
176710691STim.Szeto@Sun.COM return (0);
176810691STim.Szeto@Sun.COM }
1769